Shifted some non-basic transforms to AbstractTransforms and some base classes to BaseTransfroms.

This commit is contained in:
Michael L Smith 2016-03-19 21:59:32 -07:00
parent 5c0faaf469
commit f630bb0f23
8 changed files with 297 additions and 309 deletions

View File

@ -1,18 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OSCADSharp
{
/// <summary>
/// Creates an object that's the convex hull of child objects
/// </summary>
internal class HulledObject : MultiStatementObject
{
internal HulledObject(IEnumerable<OSCADObject> children) : base("hull()", children)
{
}
}
}

View File

@ -1,30 +0,0 @@
using OSCADSharp.Spatial;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OSCADSharp
{
/// <summary>
/// Creates an object that's the minkowski sum of child objects
/// </summary>
internal class MinkowskiedObject : MultiStatementObject
{
internal MinkowskiedObject(IEnumerable<OSCADObject> children) : base("minkowski()", children)
{
}
public override Vector3 Position()
{
throw new NotSupportedException("Position is not supported on Minkowskied objects.");
}
public override Bounds Bounds()
{
throw new NotSupportedException("Bounds is not supported on Minkowskied objects.");
}
}
}

View File

@ -1,126 +0,0 @@
using OSCADSharp.DataBinding;
using OSCADSharp.Spatial;
using OSCADSharp.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OSCADSharp
{
/// <summary>
/// An object that's mirrored on a plane
/// </summary>
internal class MirroredObject : SingleStatementObject
{
/// <summary>
/// The normal vector of a plane intersecting the origin of the object,
/// through which to mirror it.
/// </summary>
internal Vector3 Normal { get; set; } = new BindableVector();
/// <summary>
/// Creates an object that's mirrored on a plane
/// </summary>
/// <param name="obj">The object(s) to be mirrored</param>
/// <param name="normal">The normal vector of the plane on the object's origin to mirror upon</param>
internal MirroredObject(OSCADObject obj, Vector3 normal) : base(obj)
{
this.Normal = new BindableVector(normal);
}
internal MirroredObject(OSCADObject obj, Variable normal) : base(obj)
{
this.Bind("normal", normal);
}
internal MirroredObject(OSCADObject obj, Vector3 normal, Variable x, Variable y, Variable z) : base(obj)
{
this.Normal = new BindableVector(normal);
this.BindIfVariableNotNull("x", x);
this.BindIfVariableNotNull("y", y);
this.BindIfVariableNotNull("z", z);
}
public override string ToString()
{
string normal = this.bindings.Contains("normal") ? this.bindings.Get("normal").BoundVariable.Text : this.Normal.ToString();
string mirrorCommand = String.Format("mirror({0})", normal);
var formatter = new SingleBlockFormatter(mirrorCommand, this.obj.ToString());
return formatter.ToString();
}
public override OSCADObject Clone()
{
return new MirroredObject(this.obj.Clone(), this.Normal)
{
Name = this.Name,
bindings = this.bindings.Clone()
};
}
// TODO: This will yield incorrect positions if mirroring on multiple axes
// fix mirrored positions for multiple-axis mirroring
public override Vector3 Position()
{
if (this.isMoreThanOneAxis())
{
throw new NotSupportedException("Getting the position of an object that's been mirrored on more than one axis is not currently supported.");
}
var pos = obj.Position();
double x = this.Normal.X != 0 ? pos.X * -1 : pos.X;
double y = this.Normal.Y != 0 ? pos.Y * -1 : pos.Y;
double z = this.Normal.Z != 0 ? pos.Z * -1 : pos.Z;
return new Vector3(x, y, z);
}
private bool isMoreThanOneAxis()
{
return (this.Normal.X != 0 && (this.Normal.Y != 0 || this.Normal.Z != 0)) ||
(this.Normal.Y != 0 && (this.Normal.X != 0 || this.Normal.Z != 0));
}
// TODO: As with Position, will yield incorrect positions if mirroring on multiple axes
// fix mirrored positions for multiple-axis mirroring
public override Bounds Bounds()
{
if (this.isMoreThanOneAxis())
{
throw new NotSupportedException("Getting the position of an object that's been mirrored on more than one axis is not currently supported.");
}
var oldBounds = this.obj.Bounds();
var newBottomLeft = new Vector3(this.Normal.X != 0 ? oldBounds.BottomLeft.X * -1 : oldBounds.BottomLeft.X,
this.Normal.Y != 0 ? oldBounds.BottomLeft.Y * -1 : oldBounds.BottomLeft.Y,
this.Normal.Z != 0 ? oldBounds.BottomLeft.Z * -1 : oldBounds.BottomLeft.Z);
var newTopRight = new Vector3(this.Normal.X != 0 ? oldBounds.TopRight.X * -1 : oldBounds.TopRight.X,
this.Normal.Y != 0 ? oldBounds.TopRight.Y * -1 : oldBounds.TopRight.Y,
this.Normal.Z != 0 ? oldBounds.TopRight.Z * -1 : oldBounds.TopRight.Z);
return new Bounds(newBottomLeft, newTopRight);
}
private Bindings bindings = new Bindings(new Dictionary<string, string>() {
{"normal", "normal"}
});
public override void Bind(string property, Variable variable)
{
var bindableVec = this.Normal as BindableVector;
if (bindableVec != null && property == "x" || property == "y" || property == "z")
{
bindableVec.Bind(property, variable);
}
else
{
this.bindings.Add<MirroredObject>(this, property, variable);
}
}
}
}

View File

@ -1,106 +0,0 @@
using OSCADSharp.DataBinding;
using OSCADSharp.Spatial;
using OSCADSharp.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OSCADSharp
{
/// <summary>
/// A statement that has multiple child nodes, whose ToString output
/// is more or less just an aggregate of the children
/// </summary>
internal class MultiStatementObject : OSCADObject
{
private string outerStatement;
internal MultiStatementObject(string outerStatement, IEnumerable<OSCADObject> children)
{
this.outerStatement = outerStatement;
this.m_children = children.ToList();
foreach (var child in children)
{
child.Parent = this;
}
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
foreach (var child in this.m_children)
{
sb.Append(child.ToString());
}
var formatter = new SingleBlockFormatter(this.outerStatement, sb.ToString());
return formatter.ToString();
}
public override OSCADObject Clone()
{
List<OSCADObject> childClones = new List<OSCADObject>();
foreach (var child in this.m_children)
{
childClones.Add(child.Clone());
}
return new MultiStatementObject(this.outerStatement, childClones)
{
Name = this.Name
};
}
public override Vector3 Position()
{
var positions = this.m_children.Select(child => child.Position());
return Vector3.Average(positions.ToArray());
}
public override Bounds Bounds()
{
var newBottomLeft = new Vector3();
var newTopRight = new Vector3();
foreach (var child in this.m_children)
{
var bounds = child.Bounds();
if (bounds.XMin < newBottomLeft.X)
{
newBottomLeft.X = bounds.XMin;
}
if (bounds.YMin < newBottomLeft.Y)
{
newBottomLeft.Y = bounds.YMin;
}
if (bounds.ZMin < newBottomLeft.Z)
{
newBottomLeft.Z = bounds.ZMin;
}
if (bounds.XMax > newTopRight.X)
{
newTopRight.X = bounds.XMax;
}
if (bounds.YMax> newTopRight.Y)
{
newTopRight.Y = bounds.YMax;
}
if (bounds.ZMax > newTopRight.Z)
{
newTopRight.Z = bounds.ZMax;
}
}
return new Bounds(newBottomLeft, newTopRight);
}
public override void Bind(string property, Variable variable)
{
throw new NotSupportedException("This object has no bindable properties.");
}
}
}

View File

@ -0,0 +1,167 @@
using OSCADSharp.DataBinding;
using OSCADSharp.Spatial;
using OSCADSharp.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OSCADSharp
{
public abstract partial class OSCADObject
{
#region MirroredObject
/// <summary>
/// An object that's mirrored on a plane
/// </summary>
internal class MirroredObject : SingleStatementObject
{
/// <summary>
/// The normal vector of a plane intersecting the origin of the object,
/// through which to mirror it.
/// </summary>
internal Vector3 Normal { get; set; } = new BindableVector();
/// <summary>
/// Creates an object that's mirrored on a plane
/// </summary>
/// <param name="obj">The object(s) to be mirrored</param>
/// <param name="normal">The normal vector of the plane on the object's origin to mirror upon</param>
internal MirroredObject(OSCADObject obj, Vector3 normal) : base(obj)
{
this.Normal = new BindableVector(normal);
}
internal MirroredObject(OSCADObject obj, Variable normal) : base(obj)
{
this.Bind("normal", normal);
}
internal MirroredObject(OSCADObject obj, Vector3 normal, Variable x, Variable y, Variable z) : base(obj)
{
this.Normal = new BindableVector(normal);
this.BindIfVariableNotNull("x", x);
this.BindIfVariableNotNull("y", y);
this.BindIfVariableNotNull("z", z);
}
public override string ToString()
{
string normal = this.bindings.Contains("normal") ? this.bindings.Get("normal").BoundVariable.Text : this.Normal.ToString();
string mirrorCommand = String.Format("mirror({0})", normal);
var formatter = new SingleBlockFormatter(mirrorCommand, this.obj.ToString());
return formatter.ToString();
}
public override OSCADObject Clone()
{
return new MirroredObject(this.obj.Clone(), this.Normal)
{
Name = this.Name,
bindings = this.bindings.Clone()
};
}
// TODO: This will yield incorrect positions if mirroring on multiple axes
// fix mirrored positions for multiple-axis mirroring
public override Vector3 Position()
{
if (this.isMoreThanOneAxis())
{
throw new NotSupportedException("Getting the position of an object that's been mirrored on more than one axis is not currently supported.");
}
var pos = obj.Position();
double x = this.Normal.X != 0 ? pos.X * -1 : pos.X;
double y = this.Normal.Y != 0 ? pos.Y * -1 : pos.Y;
double z = this.Normal.Z != 0 ? pos.Z * -1 : pos.Z;
return new Vector3(x, y, z);
}
private bool isMoreThanOneAxis()
{
return (this.Normal.X != 0 && (this.Normal.Y != 0 || this.Normal.Z != 0)) ||
(this.Normal.Y != 0 && (this.Normal.X != 0 || this.Normal.Z != 0));
}
// TODO: As with Position, will yield incorrect positions if mirroring on multiple axes
// fix mirrored positions for multiple-axis mirroring
public override Bounds Bounds()
{
if (this.isMoreThanOneAxis())
{
throw new NotSupportedException("Getting the position of an object that's been mirrored on more than one axis is not currently supported.");
}
var oldBounds = this.obj.Bounds();
var newBottomLeft = new Vector3(this.Normal.X != 0 ? oldBounds.BottomLeft.X * -1 : oldBounds.BottomLeft.X,
this.Normal.Y != 0 ? oldBounds.BottomLeft.Y * -1 : oldBounds.BottomLeft.Y,
this.Normal.Z != 0 ? oldBounds.BottomLeft.Z * -1 : oldBounds.BottomLeft.Z);
var newTopRight = new Vector3(this.Normal.X != 0 ? oldBounds.TopRight.X * -1 : oldBounds.TopRight.X,
this.Normal.Y != 0 ? oldBounds.TopRight.Y * -1 : oldBounds.TopRight.Y,
this.Normal.Z != 0 ? oldBounds.TopRight.Z * -1 : oldBounds.TopRight.Z);
return new Bounds(newBottomLeft, newTopRight);
}
private Bindings bindings = new Bindings(new Dictionary<string, string>() {
{"normal", "normal"}
});
public override void Bind(string property, Variable variable)
{
var bindableVec = this.Normal as BindableVector;
if (bindableVec != null && property == "x" || property == "y" || property == "z")
{
bindableVec.Bind(property, variable);
}
else
{
this.bindings.Add<MirroredObject>(this, property, variable);
}
}
}
#endregion
#region HulledObject
/// <summary>
/// Creates an object that's the convex hull of child objects
/// </summary>
internal class HulledObject : MultiStatementObject
{
internal HulledObject(IEnumerable<OSCADObject> children) : base("hull()", children)
{
}
}
#endregion
#region MinkowskiedObject
/// <summary>
/// Creates an object that's the minkowski sum of child objects
/// </summary>
internal class MinkowskiedObject : MultiStatementObject
{
internal MinkowskiedObject(IEnumerable<OSCADObject> children) : base("minkowski()", children)
{
}
public override Vector3 Position()
{
throw new NotSupportedException("Position is not supported on Minkowskied objects.");
}
public override Bounds Bounds()
{
throw new NotSupportedException("Bounds is not supported on Minkowskied objects.");
}
}
#endregion
}
}

View File

@ -0,0 +1,128 @@
using OSCADSharp.DataBinding;
using OSCADSharp.Spatial;
using OSCADSharp.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OSCADSharp
{
public abstract partial class OSCADObject
{
#region MultiStatement
/// <summary>
/// A statement that has multiple child nodes, whose ToString output
/// is more or less just an aggregate of the children
/// </summary>
internal class MultiStatementObject : OSCADObject
{
private string outerStatement;
internal MultiStatementObject(string outerStatement, IEnumerable<OSCADObject> children)
{
this.outerStatement = outerStatement;
this.m_children = children.ToList();
foreach (var child in children)
{
child.Parent = this;
}
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
foreach (var child in this.m_children)
{
sb.Append(child.ToString());
}
var formatter = new SingleBlockFormatter(this.outerStatement, sb.ToString());
return formatter.ToString();
}
public override OSCADObject Clone()
{
List<OSCADObject> childClones = new List<OSCADObject>();
foreach (var child in this.m_children)
{
childClones.Add(child.Clone());
}
return new MultiStatementObject(this.outerStatement, childClones)
{
Name = this.Name
};
}
public override Vector3 Position()
{
var positions = this.m_children.Select(child => child.Position());
return Vector3.Average(positions.ToArray());
}
public override Bounds Bounds()
{
var newBottomLeft = new Vector3();
var newTopRight = new Vector3();
foreach (var child in this.m_children)
{
var bounds = child.Bounds();
if (bounds.XMin < newBottomLeft.X)
{
newBottomLeft.X = bounds.XMin;
}
if (bounds.YMin < newBottomLeft.Y)
{
newBottomLeft.Y = bounds.YMin;
}
if (bounds.ZMin < newBottomLeft.Z)
{
newBottomLeft.Z = bounds.ZMin;
}
if (bounds.XMax > newTopRight.X)
{
newTopRight.X = bounds.XMax;
}
if (bounds.YMax > newTopRight.Y)
{
newTopRight.Y = bounds.YMax;
}
if (bounds.ZMax > newTopRight.Z)
{
newTopRight.Z = bounds.ZMax;
}
}
return new Bounds(newBottomLeft, newTopRight);
}
public override void Bind(string property, Variable variable)
{
throw new NotSupportedException("This object has no bindable properties.");
}
}
#endregion
#region SingleStatementObject
/// <summary>
/// A statement with just one nested child node
/// </summary>
internal abstract class SingleStatementObject : OSCADObject
{
protected OSCADObject obj { get; set; }
protected SingleStatementObject(OSCADObject obj)
{
this.obj = obj;
this.m_children.Add(obj);
obj.Parent = this;
}
}
#endregion
}
}

View File

@ -45,6 +45,8 @@
<Compile Include="DataBinding\BindableBoolean.cs" />
<Compile Include="DataBinding\VariableCalculator.cs" />
<Compile Include="DataBinding\CompoundVariable.cs" />
<Compile Include="OSCADObject.AbstractTransforms.cs" />
<Compile Include="OSCADObject.BaseTransform.cs" />
<Compile Include="OSCADObject.BasicTransforms.cs" />
<Compile Include="OSCADObject.Booleans.cs" />
<Compile Include="Utility\Dependencies.cs" />
@ -56,7 +58,6 @@
<Compile Include="DataBinding\Binding.cs" />
<Compile Include="DataBinding\Bindings.cs" />
<Compile Include="DataBinding\IBindable.cs" />
<Compile Include="SingleStatementObject.cs" />
<Compile Include="Utility\StatementBuilder.cs" />
<Compile Include="DataBinding\Variable.cs" />
<Compile Include="IO\OutputSettings.cs" />
@ -64,17 +65,13 @@
<Compile Include="DataBinding\BindableVector.cs" />
<Compile Include="Spatial\Bounds.cs" />
<Compile Include="Spatial\Matrix.cs" />
<Compile Include="HulledObject.cs" />
<Compile Include="Utility\SingleBlockFormatter.cs" />
<Compile Include="MultiStatementObject.cs" />
<Compile Include="OSCADObject.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Solids\Cube.cs" />
<Compile Include="Solids\Cylinder.cs" />
<Compile Include="Solids\Sphere.cs" />
<Compile Include="Solids\Text3D.cs" />
<Compile Include="MinkowskiedObject.cs" />
<Compile Include="MirroredObject.cs" />
<Compile Include="Spatial\Vector3.cs" />
<Compile Include="DataBinding\Variables.cs" />
</ItemGroup>

View File

@ -1,24 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OSCADSharp
{
/// <summary>
/// A statement with just one nested child node
/// </summary>
internal abstract class SingleStatementObject : OSCADObject
{
protected OSCADObject obj { get; set; }
protected SingleStatementObject(OSCADObject obj)
{
this.obj = obj;
this.m_children.Add(obj);
obj.Parent = this;
}
}
}