diff --git a/OSCADSharp/OSCADSharp/HulledObject.cs b/OSCADSharp/OSCADSharp/HulledObject.cs
deleted file mode 100644
index f91335a..0000000
--- a/OSCADSharp/OSCADSharp/HulledObject.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace OSCADSharp
-{
- ///
- /// Creates an object that's the convex hull of child objects
- ///
- internal class HulledObject : MultiStatementObject
- {
- internal HulledObject(IEnumerable children) : base("hull()", children)
- {
- }
- }
-}
diff --git a/OSCADSharp/OSCADSharp/MinkowskiedObject.cs b/OSCADSharp/OSCADSharp/MinkowskiedObject.cs
deleted file mode 100644
index 61d13cb..0000000
--- a/OSCADSharp/OSCADSharp/MinkowskiedObject.cs
+++ /dev/null
@@ -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
-{
- ///
- /// Creates an object that's the minkowski sum of child objects
- ///
- internal class MinkowskiedObject : MultiStatementObject
- {
-
- internal MinkowskiedObject(IEnumerable 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.");
- }
- }
-}
diff --git a/OSCADSharp/OSCADSharp/MirroredObject.cs b/OSCADSharp/OSCADSharp/MirroredObject.cs
deleted file mode 100644
index f1a037c..0000000
--- a/OSCADSharp/OSCADSharp/MirroredObject.cs
+++ /dev/null
@@ -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
-{
- ///
- /// An object that's mirrored on a plane
- ///
- internal class MirroredObject : SingleStatementObject
- {
- ///
- /// The normal vector of a plane intersecting the origin of the object,
- /// through which to mirror it.
- ///
- internal Vector3 Normal { get; set; } = new BindableVector();
-
- ///
- /// Creates an object that's mirrored on a plane
- ///
- /// The object(s) to be mirrored
- /// The normal vector of the plane on the object's origin to mirror upon
- 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() {
- {"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(this, property, variable);
- }
- }
- }
-}
diff --git a/OSCADSharp/OSCADSharp/MultiStatementObject.cs b/OSCADSharp/OSCADSharp/MultiStatementObject.cs
deleted file mode 100644
index af5eff3..0000000
--- a/OSCADSharp/OSCADSharp/MultiStatementObject.cs
+++ /dev/null
@@ -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
-{
-
- ///
- /// A statement that has multiple child nodes, whose ToString output
- /// is more or less just an aggregate of the children
- ///
- internal class MultiStatementObject : OSCADObject
- {
- private string outerStatement;
-
- internal MultiStatementObject(string outerStatement, IEnumerable 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 childClones = new List();
- 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.");
- }
- }
-}
diff --git a/OSCADSharp/OSCADSharp/OSCADObject.AbstractTransforms.cs b/OSCADSharp/OSCADSharp/OSCADObject.AbstractTransforms.cs
new file mode 100644
index 0000000..0bc197c
--- /dev/null
+++ b/OSCADSharp/OSCADSharp/OSCADObject.AbstractTransforms.cs
@@ -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
+ ///
+ /// An object that's mirrored on a plane
+ ///
+ internal class MirroredObject : SingleStatementObject
+ {
+ ///
+ /// The normal vector of a plane intersecting the origin of the object,
+ /// through which to mirror it.
+ ///
+ internal Vector3 Normal { get; set; } = new BindableVector();
+
+ ///
+ /// Creates an object that's mirrored on a plane
+ ///
+ /// The object(s) to be mirrored
+ /// The normal vector of the plane on the object's origin to mirror upon
+ 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() {
+ {"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(this, property, variable);
+ }
+ }
+ }
+
+ #endregion
+
+ #region HulledObject
+ ///
+ /// Creates an object that's the convex hull of child objects
+ ///
+ internal class HulledObject : MultiStatementObject
+ {
+ internal HulledObject(IEnumerable children) : base("hull()", children)
+ {
+ }
+ }
+ #endregion
+
+ #region MinkowskiedObject
+ ///
+ /// Creates an object that's the minkowski sum of child objects
+ ///
+ internal class MinkowskiedObject : MultiStatementObject
+ {
+
+ internal MinkowskiedObject(IEnumerable 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
+ }
+}
diff --git a/OSCADSharp/OSCADSharp/OSCADObject.BaseTransform.cs b/OSCADSharp/OSCADSharp/OSCADObject.BaseTransform.cs
new file mode 100644
index 0000000..0b96d62
--- /dev/null
+++ b/OSCADSharp/OSCADSharp/OSCADObject.BaseTransform.cs
@@ -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
+ ///
+ /// A statement that has multiple child nodes, whose ToString output
+ /// is more or less just an aggregate of the children
+ ///
+ internal class MultiStatementObject : OSCADObject
+ {
+ private string outerStatement;
+
+ internal MultiStatementObject(string outerStatement, IEnumerable 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 childClones = new List();
+ 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
+ ///
+ /// A statement with just one nested child node
+ ///
+ 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
+ }
+}
diff --git a/OSCADSharp/OSCADSharp/OSCADSharp.csproj b/OSCADSharp/OSCADSharp/OSCADSharp.csproj
index 1079d67..c4bf323 100644
--- a/OSCADSharp/OSCADSharp/OSCADSharp.csproj
+++ b/OSCADSharp/OSCADSharp/OSCADSharp.csproj
@@ -45,6 +45,8 @@
+
+
@@ -56,7 +58,6 @@
-
@@ -64,17 +65,13 @@
-
-
-
-
diff --git a/OSCADSharp/OSCADSharp/SingleStatementObject.cs b/OSCADSharp/OSCADSharp/SingleStatementObject.cs
deleted file mode 100644
index bd6aa56..0000000
--- a/OSCADSharp/OSCADSharp/SingleStatementObject.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace OSCADSharp
-{
- ///
- /// A statement with just one nested child node
- ///
- 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;
- }
- }
-}