Merge pull request #4 from Exolun/Refactor/BindingRefactor

Refactor/binding refactor
This commit is contained in:
Michael Smith 2016-03-23 21:26:16 -07:00
commit b4feff07ec
72 changed files with 9417 additions and 1352 deletions

1
.gitignore vendored
View File

@ -210,3 +210,4 @@ FakesAssemblies/
GeneratedArtifacts/ GeneratedArtifacts/
_Pvt_Extensions/ _Pvt_Extensions/
ModelManifest.xml ModelManifest.xml
OSCADSharp/NDependOut/

View File

@ -1,28 +1,81 @@
 
using OSCADSharp.DataBinding;
using OSCADSharp.Solids;
using OSCADSharp.Spatial;
using OSCADSharp.Utility;
namespace OSCADSharp.ConsoleTests namespace OSCADSharp.ConsoleTests
{ {
class Program class Program
{ {
private static OSCADObject getEndCover(OSCADObject outer)
{
var bounds = outer.Bounds();
var endCover = new Cube(Inches.Sixteenth, bounds.Width, bounds.Height, true);
var choppedOut = endCover.Clone().Scale(2, (bounds.Width-Inches.Quarter)/ bounds.Width, (bounds.Height - Inches.Half) / bounds.Height);
choppedOut = choppedOut.Translate(0, Inches.Quarter, 0);
return endCover - choppedOut;
}
private static void makeBracket()
{
OSCADObject cube = new Cube(new Vector3(Inches.ToMillimeters(2.75), Inches.One, Inches.ToMillimeters(1.25)), true);
var outside = cube.Clone();
((Cube)outside).Size.X += Inches.Sixteenth;
((Cube)outside).Size.Z += Inches.Sixteenth;
cube = cube.Scale(2, 1, 1).Translate(0, Inches.Sixteenth, 0);
var obj = outside - cube;
var bounds = obj.Bounds();
obj = obj + getEndCover(outside).Translate(bounds.XMax, 0, 0);
obj = obj + getEndCover(outside).Translate(-bounds.XMax, 0, 0);
obj.ToFile("leftBracket").Open();
}
private static void makePeg()
{
Variables.Global.Add("$fn", 30);
OSCADObject flatInnerPortion = new Cylinder(Inches.Quarter, Inches.Eigth, true);
OSCADObject shaft = new Cylinder(Inches.Eigth, Inches.Half, true);
flatInnerPortion = flatInnerPortion.Translate(0, 0, shaft.Bounds().ZMax);
OSCADObject pegShaft = new Cylinder(Inches.Quarter, Inches.Half - Inches.Eigth, true)
.Translate(0, 0, -Inches.Eigth);
OSCADObject bottomBall = new Sphere(Inches.Quarter* 1.1)
.Translate(0, 0, pegShaft.Bounds().ZMin);
var obj = flatInnerPortion + shaft + pegShaft + bottomBall;
obj = obj.Rotate(0, 180, 0).Translate(0, 0, obj.Bounds().ZMax);
obj.ToFile("peg");
}
static void Main(string[] args) static void Main(string[] args)
{ {
var diam = new Variable("mainColumn", Inches.Half); makePeg();
var height = new Variable("overallHeight", Inches.Quarter);
Variables.Global.Add(diam);
Variables.Global.Add(height);
var cyl = new Cylinder(diam, diam, height); //var diam = new Variable("mainColumn", Inches.Half);
//var height = new Variable("overallHeight", Inches.Quarter);
//Variables.Global.Add(diam);
//Variables.Global.Add(height);
//var cyl = new Cylinder(diam, diam, height);
var pos = cyl.Position(); //var pos = cyl.Position();
var cyl1 = new Cylinder(1, 100, true).Translate(pos); //var cyl1 = new Cylinder(1, 100, true).Translate(pos);
var cyl2 = new Cylinder(1, 100, true).Rotate(0, 90, 0).Translate(pos); //var cyl2 = new Cylinder(1, 100, true).Rotate(0, 90, 0).Translate(pos);
var cyl3 = new Cylinder(1, 100, true).Rotate(90, 0, 0).Translate(pos); //var cyl3 = new Cylinder(1, 100, true).Rotate(90, 0, 0).Translate(pos);
var axisHelper = cyl1.Union(cyl2, cyl3).Color("Red"); //var axisHelper = cyl1.Union(cyl2, cyl3).Color("Red");
//var topCorner = new Sphere().Translate(obj.Bounds().TopRight); ////var topCorner = new Sphere().Translate(obj.Bounds().TopRight);
//var botCorner = new Sphere().Translate(obj.Bounds().BottomLeft); ////var botCorner = new Sphere().Translate(obj.Bounds().BottomLeft);
(cyl + axisHelper).ToFile("test.scad").Open(); //(cyl + axisHelper).ToFile("test.scad").Open();
//Console.ReadKey(); //Console.ReadKey();
} }

View File

@ -1,6 +1,8 @@
using System; using System;
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Linq; using System.Linq;
using OSCADSharp.DataBinding;
using OSCADSharp.Solids;
namespace OSCADSharp.UnitTests namespace OSCADSharp.UnitTests
{ {

View File

@ -1,5 +1,6 @@
using System; using System;
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using OSCADSharp.Solids;
namespace OSCADSharp.UnitTests namespace OSCADSharp.UnitTests
{ {

View File

@ -1,4 +1,5 @@
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using OSCADSharp.Solids;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;

View File

@ -1,4 +1,6 @@
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using OSCADSharp.Solids;
using OSCADSharp.Spatial;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;

View File

@ -1,7 +1,9 @@
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq; using Moq;
using OSCADSharp.Files; using OSCADSharp.DataBinding;
using OSCADSharp.Scripting; using OSCADSharp.IO;
using OSCADSharp.Solids;
using OSCADSharp.Utility;
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
@ -80,7 +82,7 @@ namespace OSCADSharp.UnitTests
.Translate(0, 5, 10).Rotate(0, 90, 0) .Translate(0, 5, 10).Rotate(0, 90, 0)
.Translate(0, 0, 10).Scale(1, 1, 2); .Translate(0, 0, 10).Scale(1, 1, 2);
List<uint> ids = obj.Children().Select(child => child.Id).ToList(); List<int> ids = obj.Children().Select(child => child.Id).ToList();
ids.Add(obj.Id); ids.Add(obj.Id);
Assert.AreEqual(ids.Count, ids.Distinct().Count()); Assert.AreEqual(ids.Count, ids.Distinct().Count());
@ -147,11 +149,11 @@ namespace OSCADSharp.UnitTests
var mock = new Mock<IFileWriter>(); var mock = new Mock<IFileWriter>();
mock.Setup(_wrtr => _wrtr.WriteAllLines(It.IsAny<string>(), It.IsAny<string[]>())) mock.Setup(_wrtr => _wrtr.WriteAllLines(It.IsAny<string>(), It.IsAny<string[]>()))
.Callback<string, string[]>((path, contents) => { output = contents; }); .Callback<string, string[]>((path, contents) => { output = contents; });
Dependencies.FileWriter = mock.Object; Dependencies.SetFileWriter(mock.Object);
cube.ToFile("myFile"); cube.ToFile("myFile");
Assert.AreEqual(Settings.OSCADSharpHeader, output[0]); Assert.AreEqual(OutputSettings.OSCADSharpHeader, output[0]);
} }
[TestMethod] [TestMethod]
@ -164,7 +166,7 @@ namespace OSCADSharp.UnitTests
var mock = new Mock<IFileWriter>(); var mock = new Mock<IFileWriter>();
mock.Setup(_wrtr => _wrtr.WriteAllLines(It.IsAny<string>(), It.IsAny<string[]>())) mock.Setup(_wrtr => _wrtr.WriteAllLines(It.IsAny<string>(), It.IsAny<string[]>()))
.Callback<string, string[]>((path, contents) => { output = contents; }); .Callback<string, string[]>((path, contents) => { output = contents; });
Dependencies.FileWriter = mock.Object; Dependencies.SetFileWriter(mock.Object);
cube.ToFile("myFile"); cube.ToFile("myFile");

View File

@ -1,4 +1,6 @@
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using OSCADSharp.DataBinding;
using OSCADSharp.Utility;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -24,7 +26,7 @@ namespace OSCADSharp.UnitTests.Scripting
var compound = new Variable("x", 5) / 12; var compound = new Variable("x", 5) / 12;
string type = compound.GetType().ToString(); string type = compound.GetType().ToString();
Assert.AreEqual("OSCADSharp.Scripting.CompoundVariable", type); Assert.AreEqual("OSCADSharp.DataBinding.Variable+CompoundVariable", type);
} }
} }
} }

View File

@ -1,7 +1,9 @@
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq; using Moq;
using OSCADSharp.Files; using OSCADSharp.DataBinding;
using OSCADSharp.Scripting; using OSCADSharp.IO;
using OSCADSharp.Solids;
using OSCADSharp.Utility;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -23,7 +25,7 @@ namespace OSCADSharp.UnitTests
var mock = new Mock<IFileWriter>(); var mock = new Mock<IFileWriter>();
mock.Setup(_wrtr => _wrtr.WriteAllLines(It.IsAny<string>(), It.IsAny<string[]>())) mock.Setup(_wrtr => _wrtr.WriteAllLines(It.IsAny<string>(), It.IsAny<string[]>()))
.Callback<string, string[]>((path, contents) => { output = contents; }); .Callback<string, string[]>((path, contents) => { output = contents; });
Dependencies.FileWriter = mock.Object; Dependencies.SetFileWriter(mock.Object);
cube.ToFile("myFile"); cube.ToFile("myFile");
@ -34,14 +36,14 @@ namespace OSCADSharp.UnitTests
[ExpectedException(typeof(InvalidOperationException))] [ExpectedException(typeof(InvalidOperationException))]
public void Settings_NullOpenSCADPathThrowsError() public void Settings_NullOpenSCADPathThrowsError()
{ {
Settings.OpenSCADPath = null; OutputSettings.OpenSCADPath = null;
var cube = new Cube(); var cube = new Cube();
var mock = new Mock<IFileWriter>(); var mock = new Mock<IFileWriter>();
mock.Setup(_wrtr => _wrtr.WriteAllLines(It.IsAny<string>(), It.IsAny<string[]>())) mock.Setup(_wrtr => _wrtr.WriteAllLines(It.IsAny<string>(), It.IsAny<string[]>()))
.Callback<string, string[]>((path, contents) => { }); .Callback<string, string[]>((path, contents) => { });
Dependencies.FileWriter = mock.Object; Dependencies.SetFileWriter(mock.Object);
cube.ToFile("test").Open(); cube.ToFile("test").Open();
} }

View File

@ -2,7 +2,10 @@
using System.Text; using System.Text;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using OSCADSharp.Scripting; using OSCADSharp.Utility;
using OSCADSharp.Spatial;
using OSCADSharp.DataBinding;
using OSCADSharp.Solids;
namespace OSCADSharp.UnitTests namespace OSCADSharp.UnitTests
{ {
@ -191,5 +194,15 @@ namespace OSCADSharp.UnitTests
Assert.IsTrue(script.Contains("translate(v = [xOffset")); Assert.IsTrue(script.Contains("translate(v = [xOffset"));
Assert.IsTrue(script.Contains("size = [15, 5, myHeight]")); Assert.IsTrue(script.Contains("size = [15, 5, myHeight]"));
} }
[TestMethod]
public void Cube_LengthWidthHeightAppearsInScriptOutput()
{
var cube = new Cube(15, 5, 12);
string script = cube.ToString();
Assert.IsTrue(script.Contains("size = [15, 5, 12]"));
}
} }
} }

View File

@ -1,5 +1,8 @@
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using OSCADSharp.Scripting; using OSCADSharp.DataBinding;
using OSCADSharp.Solids;
using OSCADSharp.Spatial;
using OSCADSharp.Utility;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;

View File

@ -1,6 +1,9 @@
using System; using System;
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using OSCADSharp.Scripting; using OSCADSharp.Utility;
using OSCADSharp.Spatial;
using OSCADSharp.DataBinding;
using OSCADSharp.Solids;
namespace OSCADSharp.UnitTests namespace OSCADSharp.UnitTests
{ {

View File

@ -1,5 +1,7 @@
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using OSCADSharp.Scripting; using OSCADSharp.DataBinding;
using OSCADSharp.Solids;
using OSCADSharp.Spatial;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;

View File

@ -1,5 +1,6 @@
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using OSCADSharp.Scripting; using OSCADSharp.DataBinding;
using OSCADSharp.Solids;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;

View File

@ -1,4 +1,5 @@
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using OSCADSharp.Solids;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;

View File

@ -1,5 +1,6 @@
using System; using System;
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using OSCADSharp.Solids;
namespace OSCADSharp.UnitTests namespace OSCADSharp.UnitTests
{ {

View File

@ -1,5 +1,7 @@
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using OSCADSharp.Scripting; using OSCADSharp.DataBinding;
using OSCADSharp.Solids;
using OSCADSharp.Spatial;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;

View File

@ -1,5 +1,7 @@
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using OSCADSharp.Scripting; using OSCADSharp.DataBinding;
using OSCADSharp.Solids;
using OSCADSharp.Spatial;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;

View File

@ -1,5 +1,7 @@
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using OSCADSharp.Scripting; using OSCADSharp.DataBinding;
using OSCADSharp.Solids;
using OSCADSharp.Spatial;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;

View File

@ -1,5 +1,7 @@
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using OSCADSharp.Scripting; using OSCADSharp.DataBinding;
using OSCADSharp.Solids;
using OSCADSharp.Spatial;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;

View File

@ -1,5 +1,8 @@
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using OSCADSharp.Scripting; using OSCADSharp.DataBinding;
using OSCADSharp.Solids;
using OSCADSharp.Spatial;
using OSCADSharp.Utility;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;

8101
OSCADSharp/OSCADSharp.ndproj Normal file

File diff suppressed because it is too large Load Diff

View File

@ -12,6 +12,7 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C831DC9A-396A-43F9-AAC6-410A88485356}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C831DC9A-396A-43F9-AAC6-410A88485356}"
ProjectSection(SolutionItems) = preProject ProjectSection(SolutionItems) = preProject
..\LICENSE.txt = ..\LICENSE.txt ..\LICENSE.txt = ..\LICENSE.txt
OSCADSharp\OSCADSharp.nuspec = OSCADSharp\OSCADSharp.nuspec
..\README.md = ..\README.md ..\README.md = ..\README.md
EndProjectSection EndProjectSection
EndProject EndProject

View File

@ -3,13 +3,12 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using OSCADSharp.Scripting;
namespace OSCADSharp.Bindings namespace OSCADSharp.DataBinding
{ {
internal class BindableBoolean : IBindable internal class BindableBoolean : IBindable
{ {
public string InnerValue internal string InnerValue
{ {
get; get;
set; set;
@ -32,9 +31,9 @@ namespace OSCADSharp.Bindings
this.bindings.Synonym("innervalue", propertyName); this.bindings.Synonym("innervalue", propertyName);
} }
private string boundProperty = null; private readonly string boundProperty = null;
public bool IsBound { get; set; } = false; internal bool IsBound { get; set; } = false;
public void Bind(string property, Variable variable) public void Bind(string property, Variable variable)
{ {
this.IsBound = true; this.IsBound = true;
@ -42,17 +41,17 @@ namespace OSCADSharp.Bindings
this.bindings.Add<BindableBoolean>(this, property, stringifiedVar); this.bindings.Add<BindableBoolean>(this, property, stringifiedVar);
} }
public BindableBoolean Clone() public override string ToString()
{
return this.bindings.Get(this.boundProperty).BoundVariable.Text;
}
internal BindableBoolean Clone()
{ {
var clone = new BindableBoolean(this.boundProperty); var clone = new BindableBoolean(this.boundProperty);
clone.bindings = this.bindings; clone.bindings = this.bindings;
return clone; return clone;
} }
public override string ToString()
{
return this.bindings.Get(this.boundProperty).BoundVariable.Text;
}
} }
} }

View File

@ -1,11 +1,11 @@
using System; using OSCADSharp.Spatial;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using OSCADSharp.Scripting;
namespace OSCADSharp.Bindings namespace OSCADSharp.DataBinding
{ {
internal class BindableVector : Vector3, IBindable internal class BindableVector : Vector3, IBindable
{ {
@ -16,11 +16,16 @@ namespace OSCADSharp.Bindings
{ "z", "z" } { "z", "z" }
}); });
public BindableVector(Vector3 vector, Dictionary<string, string> synonyms = null) : this(vector.X, vector.Y, vector.Z) internal BindableVector(Vector3 vector, Dictionary<string, string> synonyms = null) : this(vector.X, vector.Y, vector.Z)
{ {
this.X = vector.X;
this.Y = vector.Y;
this.Z = vector.Z;
this.setSynonyms(synonyms);
} }
public BindableVector(double x = 0, double y = 0, double z = 0, Dictionary<string, string> synonyms = null) internal BindableVector(double x = 0, double y = 0, double z = 0, Dictionary<string, string> synonyms = null)
{ {
this.X = x; this.X = x;
this.Y = y; this.Y = y;
@ -54,7 +59,7 @@ namespace OSCADSharp.Bindings
return String.Format("[{0}, {1}, {2}]", x, y, z); return String.Format("[{0}, {1}, {2}]", x, y, z);
} }
public new BindableVector Clone() internal new BindableVector Clone()
{ {
var clone = new BindableVector(base.Clone()); var clone = new BindableVector(base.Clone());
clone.bindings = this.bindings.Clone(); clone.bindings = this.bindings.Clone();

View File

@ -1,11 +1,10 @@
using OSCADSharp.Scripting; using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace OSCADSharp.Bindings namespace OSCADSharp.DataBinding
{ {
internal class Binding internal class Binding
{ {

View File

@ -1,28 +1,27 @@
using OSCADSharp.Scripting; using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace OSCADSharp.Bindings namespace OSCADSharp.DataBinding
{ {
internal class Bindings internal class Bindings
{ {
#region Fields #region Fields
private Dictionary<string, Binding> bindings = new Dictionary<string, Binding>(); private Dictionary<string, Binding> bindings = new Dictionary<string, Binding>();
private Dictionary<string, string> propertyNametoOpenSCADFieldMappings = new Dictionary<string, string>(); private readonly Dictionary<string, string> propertyNametoOpenSCADFieldMappings = new Dictionary<string, string>();
private Dictionary<string, string> synonyms = new Dictionary<string, string>(); private Dictionary<string, string> synonyms = new Dictionary<string, string>();
#endregion #endregion
#region Constructors #region Constructors
public Bindings() internal Bindings()
{ {
this.propertyNametoOpenSCADFieldMappings = new Dictionary<string, string>(); this.propertyNametoOpenSCADFieldMappings = new Dictionary<string, string>();
} }
public Bindings(Dictionary<string, string> mappings) internal Bindings(Dictionary<string, string> mappings)
{ {
this.propertyNametoOpenSCADFieldMappings = mappings; this.propertyNametoOpenSCADFieldMappings = mappings;
} }

View File

@ -1,16 +1,15 @@
using OSCADSharp.Scripting; using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace OSCADSharp namespace OSCADSharp.DataBinding
{ {
/// <summary> /// <summary>
/// An object whose properties can be bound to variables /// An object whose properties can be bound to variables
/// </summary> /// </summary>
public interface IBindable internal interface IBindable
{ {
/// <summary> /// <summary>
/// Binds a variable to property of this object /// Binds a variable to property of this object

View File

@ -1,11 +1,12 @@
using OSCADSharp.Scripting; using OSCADSharp.Spatial;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Linq.Expressions;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace OSCADSharp namespace OSCADSharp.DataBinding
{ {
/// <summary> /// <summary>
/// A value for setting object properties in script output to /// A value for setting object properties in script output to
@ -229,5 +230,80 @@ namespace OSCADSharp
return applyMixedOperatorRight("/", left, right, VariableCalculator.Divide); return applyMixedOperatorRight("/", left, right, VariableCalculator.Divide);
} }
#endregion #endregion
#region CompoundVariable
private class CompoundVariable : Variable
{
internal CompoundVariable(string name, object value) : base(name, value, false)
{
}
}
#endregion
#region VariableCalculator
private static class VariableCalculator
{
internal static bool IsNumeric(object value)
{
return value is int || value is double || value is float || value is decimal;
}
internal static bool IsVector(object value)
{
return value is Vector3 || value is BindableVector;
}
private static object computeExpression(BinaryExpression expr, object left, object right)
{
object result = null;
if (IsNumeric(left) && IsNumeric(right))
result = Expression.Lambda<Func<double>>(expr).Compile()();
if (IsVector(left) || IsVector(right))
result = Expression.Lambda<Func<Vector3>>(expr).Compile()();
return result;
}
private static BinaryExpression makeExpression(Func<ConstantExpression, ConstantExpression, BinaryExpression> methodToUse,
object left, object right)
{
if (IsNumeric(left))
left = Convert.ToDouble(left);
if (IsNumeric(right))
right = Convert.ToDouble(right);
var leftExpr = Expression.Constant(left, left.GetType());
var rightExpr = Expression.Constant(right, right.GetType());
BinaryExpression expr = methodToUse(leftExpr, rightExpr);
return expr;
}
internal static object Add(object left, object right)
{
BinaryExpression expr = makeExpression(Expression.Add, left, right);
return computeExpression(expr, left, right);
}
internal static object Subtract(object left, object right)
{
BinaryExpression expr = makeExpression(Expression.Subtract, left, right);
return computeExpression(expr, left, right);
}
internal static object Multiply(object left, object right)
{
BinaryExpression expr = makeExpression(Expression.Multiply, left, right);
return computeExpression(expr, left, right);
}
internal static object Divide(object left, object right)
{
BinaryExpression expr = makeExpression(Expression.Divide, left, right);
return computeExpression(expr, left, right);
}
}
#endregion
} }
} }

View File

@ -5,7 +5,7 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace OSCADSharp namespace OSCADSharp.DataBinding
{ {
/// <summary> /// <summary>
/// A collection of names/values for variables /// A collection of names/values for variables
@ -16,8 +16,8 @@ namespace OSCADSharp
/// Global variables that can be assigned for output at the /// Global variables that can be assigned for output at the
/// top of OpenSCAD scripts /// top of OpenSCAD scripts
/// </summary> /// </summary>
public static Variables Global = new Variables(); public static Variables Global { get; set; } = new Variables();
private ConcurrentDictionary<string, Variable> variables = new ConcurrentDictionary<string, Variable>(); private readonly ConcurrentDictionary<string, Variable> variables = new ConcurrentDictionary<string, Variable>();
/// <summary> /// <summary>
/// Adds a variable to the collection /// Adds a variable to the collection

View File

@ -1,16 +1,17 @@
using System; using OSCADSharp.Utility;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace OSCADSharp.Files namespace OSCADSharp.IO
{ {
internal class DefaultFileInvoker : IFileInvoker internal class DefaultFileInvoker : IFileInvoker
{ {
private string filePath; private readonly string filePath;
public DefaultFileInvoker(string filePath) internal DefaultFileInvoker(string filePath)
{ {
this.filePath = filePath; this.filePath = filePath;
} }
@ -19,7 +20,7 @@ namespace OSCADSharp.Files
{ {
try try
{ {
Process.Start(Settings.OpenSCADPath, String.Format("-o {0} {1}", outputFile, this.filePath)); Process.Start(OutputSettings.OpenSCADPath, String.Format("-o {0} {1}", outputFile, this.filePath));
} }
catch (InvalidOperationException) catch (InvalidOperationException)
{ {
@ -31,7 +32,7 @@ namespace OSCADSharp.Files
{ {
try try
{ {
Process.Start(Settings.OpenSCADPath, String.Format("{0}", this.filePath)); Process.Start(OutputSettings.OpenSCADPath, String.Format("{0}", this.filePath));
} }
catch (InvalidOperationException) catch (InvalidOperationException)
{ {

View File

@ -5,7 +5,7 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace OSCADSharp.Files namespace OSCADSharp.IO
{ {
internal class DefaultFileWriter : IFileWriter internal class DefaultFileWriter : IFileWriter
{ {

View File

@ -4,7 +4,7 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace OSCADSharp namespace OSCADSharp.IO
{ {
/// <summary> /// <summary>
/// Invokes OpenSCAD actions on output files /// Invokes OpenSCAD actions on output files

View File

@ -4,7 +4,7 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace OSCADSharp namespace OSCADSharp.IO
{ {
/// <summary> /// <summary>
/// A class that takes text and writes to file /// A class that takes text and writes to file

View File

@ -0,0 +1,52 @@
using OSCADSharp.Utility;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OSCADSharp.IO
{
/// <summary>
/// Settings for OpenSCAD scripts
/// </summary>
public static class OutputSettings
{
/// <summary>
/// Code-gen header
/// </summary>
public static string OSCADSharpHeader { get; private set; } = String.Format("/*Code Generated using OSCADSharp on {0}. {1}{2}For more information, please visit https://github.com/Exolun/OSCADSharp */{3}",
DateTime.Now.ToString(), Environment.NewLine, Environment.NewLine, Environment.NewLine);
/// <summary>
/// Path to the OpenSCAD executable for file invocation
/// (Default value is set the default install directory on Windows)
/// </summary>
public static string OpenSCADPath { get; set; } = new OpenSCADPathFinder().GetPath();
/// <summary>
/// Known where the default installation locations for OpenSCAD
/// are, and finds the right path for the current environment
/// </summary>
private class OpenSCADPathFinder
{
private readonly string[] possibleFilePaths = new string[]
{
@"C:\Program Files (x86)\OpenSCAD\openscad.exe",
@"C:\Program Files\OpenSCAD\openscad.exe"
};
internal string GetPath()
{
foreach (string path in possibleFilePaths)
{
if (File.Exists(path))
return path;
}
return null;
}
}
}
}

View File

@ -1,34 +0,0 @@
using OSCADSharp.Scripting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OSCADSharp.Spatial;
namespace OSCADSharp.Booleans
{
/// <summary>
/// Subtracts the 2nd (and all further) child nodes from the first one (logical and not).
/// </summary>
internal class Difference : MultiStatementObject
{
/// <summary>
/// Creates a subtraction of child nodes
/// </summary>
/// <param name="children"></param>
public Difference(IEnumerable<OSCADObject> children) : base("difference()", children)
{
}
public override Vector3 Position()
{
return children[0].Position();
}
public override Bounds Bounds()
{
return children[0].Bounds();
}
}
}

View File

@ -1,34 +0,0 @@
using OSCADSharp.Scripting;
using OSCADSharp.Spatial;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OSCADSharp.Booleans
{
/// <summary>
/// Creates the intersection of all child nodes
/// </summary>
internal class Intersection : MultiStatementObject
{
/// <summary>
/// Creates the intersection of all child nodes
/// </summary>
/// <param name="children"></param>
public Intersection(IEnumerable<OSCADObject> children) : base("intersection()", children)
{
}
public override Vector3 Position()
{
throw new NotSupportedException("Position is not supported on Intersected objects.");
}
public override Bounds Bounds()
{
throw new NotSupportedException("Bounds is not supported on Intersected objects.");
}
}
}

View File

@ -1,23 +0,0 @@
using OSCADSharp.Scripting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OSCADSharp.Booleans
{
/// <summary>
/// A union of child nodes. This is the sum of all children (logical or).
/// </summary>
internal class Union : MultiStatementObject
{
/// <summary>
/// Create a union that is the combination of all children
/// </summary>
/// <param name="children">OSCADObjects to combine</param>
internal Union(IEnumerable<OSCADObject> children) : base("union()", children)
{
}
}
}

View File

@ -1,15 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OSCADSharp.Scripting
{
internal class CompoundVariable : Variable
{
public CompoundVariable(string name, object value) : base(name, value, false)
{
}
}
}

View File

@ -1,104 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OSCADSharp.Spatial;
namespace OSCADSharp.Scripting
{
/// <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.children = children.ToList();
foreach (var child in children)
{
child.Parent = this;
}
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
foreach (var child in this.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.children)
{
childClones.Add(child.Clone());
}
return new MultiStatementObject(this.outerStatement, childClones)
{
Name = this.Name
};
}
public override Vector3 Position()
{
var positions = this.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.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

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

View File

@ -1,73 +0,0 @@
using OSCADSharp.Bindings;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
namespace OSCADSharp
{
internal static class VariableCalculator
{
internal static bool IsNumeric(object value)
{
return value is int || value is double || value is float || value is decimal;
}
internal static bool IsVector(object value)
{
return value is Vector3 || value is BindableVector;
}
private static object computeExpression(BinaryExpression expr, object left, object right)
{
object result = null;
if (IsNumeric(left) && IsNumeric(right))
result = Expression.Lambda<Func<double>>(expr).Compile()();
if (IsVector(left) || IsVector(right))
result = Expression.Lambda<Func<Vector3>>(expr).Compile()();
return result;
}
private static BinaryExpression makeExpression(Func<ConstantExpression, ConstantExpression, BinaryExpression> methodToUse,
object left, object right)
{
if (IsNumeric(left))
left = Convert.ToDouble(left);
if (IsNumeric(right))
right = Convert.ToDouble(right);
var leftExpr = Expression.Constant(left, left.GetType());
var rightExpr = Expression.Constant(right, right.GetType());
BinaryExpression expr = methodToUse(leftExpr, rightExpr);
return expr;
}
internal static object Add(object left, object right)
{
BinaryExpression expr = makeExpression(Expression.Add, left, right);
return computeExpression(expr, left, right);
}
internal static object Subtract(object left, object right)
{
BinaryExpression expr = makeExpression(Expression.Subtract, left, right);
return computeExpression(expr, left, right);
}
internal static object Multiply(object left, object right)
{
BinaryExpression expr = makeExpression(Expression.Multiply, left, right);
return computeExpression(expr, left, right);
}
internal static object Divide(object left, object right)
{
BinaryExpression expr = makeExpression(Expression.Divide, left, right);
return computeExpression(expr, left, right);
}
}
}

View File

@ -1,34 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OSCADSharp
{
/// <summary>
/// Known where the default installation locations for OpenSCAD
/// are, and finds the right path for the current environment
/// </summary>
internal class OpenSCADPathFinder
{
private string[] possibleFilePaths = new string[]
{
@"C:\Program Files (x86)\OpenSCAD\openscad.exe",
@"C:\Program Files\OpenSCAD\openscad.exe"
};
internal string GetPath()
{
foreach (string path in possibleFilePaths)
{
if (File.Exists(path))
return path;
}
return null;
}
}
}

View File

@ -1,86 +0,0 @@
using OSCADSharp.Scripting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OSCADSharp.Spatial;
namespace OSCADSharp.Transforms
{
/// <summary>
/// An object that has color and/or opacity applied to it
/// </summary>
internal class ColoredObject : SingleStatementObject
{
#region Attributes
internal string ColorName { get; set; } = "Yellow";
internal double Opacity { get; set; } = 1.0;
#endregion
/// <summary>
/// Creates a colorized object
/// </summary>
/// <param name="obj">The object(s) to which color will be applied</param>
/// <param name="color">The string-wise name of the color to be applied</param>
/// <param name="opacity">Opacity from 0.0 to 1.0 </param>
internal ColoredObject(OSCADObject obj, string color = "Yellow", double opacity = 1.0) : base(obj)
{
this.ColorName = color;
this.Opacity = opacity;
}
/// <summary>
/// Creates a colorized object with predefined bindings
/// </summary>
/// <param name="obj">The object(s) to which color will be applied</param>
/// <param name="colorName"></param>
/// <param name="opacity"></param>
internal ColoredObject(OSCADObject obj, Variable colorName, Variable opacity) : base(obj)
{
this.Bind("color", colorName);
this.BindIfVariableNotNull("opacity", opacity);
}
public override string ToString()
{
string colorName = this.bindings.Contains("color") ? this.bindings.Get("color").BoundVariable.Text :
"\""+this.ColorName+"\"";
string opacity = this.bindings.Contains("opacity") ? this.bindings.Get("opacity").BoundVariable.Text
: this.Opacity.ToString();
string colorCommand = String.Format("color({0}, {1})", colorName, opacity);
var formatter = new SingleBlockFormatter(colorCommand, this.obj.ToString());
return formatter.ToString();
}
public override OSCADObject Clone()
{
return new ColoredObject(this.obj.Clone(), this.ColorName, this.Opacity)
{
Name = this.Name,
bindings = this.bindings.Clone()
};
}
public override Vector3 Position()
{
return this.obj.Position();
}
public override Bounds Bounds()
{
return this.obj.Bounds();
}
private Bindings.Bindings bindings = new Bindings.Bindings(new Dictionary<string, string>() {
{"color", "color" },
{"opacity", "opacity" }
});
public override void Bind(string property, Variable variable)
{
this.bindings.Add<ColoredObject>(this, property, variable);
}
}
}

View File

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

View File

@ -1,66 +0,0 @@
using OSCADSharp.Scripting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OSCADSharp.Spatial;
namespace OSCADSharp.Transforms
{
/// <summary>
/// Linear Extrusion is a modeling operation that takes a 2D polygon as input and extends it in the third dimension. This way a 3D shape is created.
///
/// This is a limited subset of the capabilities
/// </summary>
internal class LinearExtrudedObject : SingleStatementObject
{
/// <summary>
/// Height to extrude to
/// </summary>
public double Height { get; set; } = 1.0;
//TODO: Possibly implement everything else?
//linear_extrude(height = fanwidth, center = true, convexity = 10, twist = -fanrot, slices = 20, scale = 1.0) {...}
/// <summary>
/// An object that will be extruded from 2d to 3d
/// </summary>
/// <param name="obj"></param>
/// <param name="height"></param>
public LinearExtrudedObject(OSCADObject obj, double height) : base(obj)
{
this.Height = height;
}
public override OSCADObject Clone()
{
return new LinearExtrudedObject(this.obj.Clone(), this.Height)
{
Name = this.Name
};
}
public override string ToString()
{
string extrudeCommand = String.Format("linear_extrude(height = {0})", this.Height.ToString());
var formatter = new SingleBlockFormatter(extrudeCommand, this.obj.ToString());
return formatter.ToString();
}
public override Vector3 Position()
{
throw new NotSupportedException();
}
public override Bounds Bounds()
{
throw new NotImplementedException();
}
public override void Bind(string property, Variable variable)
{
throw new NotImplementedException();
}
}
}

View File

@ -1,31 +0,0 @@
using OSCADSharp.Scripting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OSCADSharp.Spatial;
namespace OSCADSharp.Transforms
{
/// <summary>
/// Creates an object that's the minkowski sum of child objects
/// </summary>
internal class MinkowskiedObject : MultiStatementObject
{
public 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.Bindings;
using OSCADSharp.Scripting;
using OSCADSharp.Spatial;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OSCADSharp.Transforms
{
/// <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 bindings = new Bindings.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,107 +0,0 @@
using OSCADSharp.Scripting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OSCADSharp.Spatial;
using OSCADSharp.Bindings;
namespace OSCADSharp.Transforms
{
/// <summary>
/// An object that's been resized to a specified set of X/Y/Z dimensions
/// </summary>
internal class ResizedObject : SingleStatementObject
{
/// <summary>
/// Size of the object in terms of X/Y/Z
/// </summary>
internal Vector3 Size { get; set; }
/// <summary>
/// Creates a resized object
/// </summary>
/// <param name="obj">The object(s) to be resized</param>
/// <param name="size">The size to resize to, in terms of x/y/z dimensions</param>
internal ResizedObject(OSCADObject obj, Vector3 size) : base(obj)
{
Size = new BindableVector(size);
}
internal ResizedObject(OSCADObject obj, Variable size) : base(obj)
{
this.Bind("size", size);
}
internal ResizedObject(OSCADObject obj, Vector3 size, Variable x, Variable y, Variable z) : base(obj)
{
this.Size = new BindableVector(size);
this.BindIfVariableNotNull("x", x);
this.BindIfVariableNotNull("y", y);
this.BindIfVariableNotNull("z", z);
}
internal ResizedObject(OSCADObject obj) : base(obj)
{
}
public override string ToString()
{
string size = this.bindings.Contains("size") ? this.bindings.Get("size").BoundVariable.Text : this.Size.ToString();
string resizeCommand = String.Format("resize({0})", size);
var formatter = new SingleBlockFormatter(resizeCommand, this.obj.ToString());
return formatter.ToString();
}
public override OSCADObject Clone()
{
var bndSize = this.Size as BindableVector;
return new ResizedObject(this.obj.Clone())
{
Name = this.Name,
bindings = this.bindings.Clone(),
Size = bndSize != null ? bndSize.Clone() : this.Size.Clone()
};
}
public override Vector3 Position()
{
var bounds = this.Bounds();
return Vector3.Average(bounds.BottomLeft, bounds.TopRight);
}
public override Bounds Bounds()
{
var oldBounds = obj.Bounds();
double xScaleFactor = this.Size.X > 0 ? this.Size.X / Math.Abs(oldBounds.XMax - oldBounds.XMin) : 1;
double yScaleFactor = this.Size.Y > 0 ? this.Size.Y / Math.Abs(oldBounds.YMax - oldBounds.YMin) : 1;
double zScaleFactor = this.Size.Z > 0 ? this.Size.Z / Math.Abs(oldBounds.ZMax - oldBounds.ZMin) : 1;
Vector3 scaleMultiplier = new Vector3(xScaleFactor, yScaleFactor, zScaleFactor);
return new Bounds(oldBounds.BottomLeft * scaleMultiplier, oldBounds.TopRight * scaleMultiplier);
}
private Bindings.Bindings bindings = new Bindings.Bindings(new Dictionary<string, string>() {
{ "size", "size" }
});
public override void Bind(string property, Variable variable)
{
var bindableVec = this.Size as BindableVector;
if(bindableVec != null && property == "x" || property == "y" || property == "z")
{
bindableVec.Bind(property, variable);
}
else
{
this.bindings.Add<ResizedObject>(this, property, variable);
}
}
}
}

View File

@ -1,93 +0,0 @@
using OSCADSharp.Bindings;
using OSCADSharp.Scripting;
using OSCADSharp.Spatial;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OSCADSharp.Transforms
{
/// <summary>
/// An object with rotation applied
/// </summary>
internal class RotatedObject : SingleStatementObject
{
/// <summary>
/// The angle to rotate, in terms of X/Y/Z euler angles
/// </summary>
internal Vector3 Angle { get; set; } = new BindableVector();
/// <summary>
/// Creates an object with rotation applied
/// </summary>
/// <param name="obj">The object being rotated</param>
/// <param name="angle">The angle to rotate</param>
internal RotatedObject(OSCADObject obj, Vector3 angle) : base(obj)
{
this.Angle = new BindableVector(angle);
}
internal RotatedObject(OSCADObject obj, Variable normal) : base(obj)
{
this.Bind("angle", normal);
}
internal RotatedObject(OSCADObject obj, Vector3 angle, Variable x, Variable y, Variable z) : base(obj)
{
this.Angle = new BindableVector(angle);
this.BindIfVariableNotNull("x", x);
this.BindIfVariableNotNull("y", y);
this.BindIfVariableNotNull("z", z);
}
public override string ToString()
{
string angle = this.bindings.Contains("angle") ? this.bindings.Get("angle").BoundVariable.Text : this.Angle.ToString();
string rotateCommand = String.Format("rotate({0})", angle.ToString());
var formatter = new SingleBlockFormatter(rotateCommand, this.obj.ToString());
return formatter.ToString();
}
public override OSCADObject Clone()
{
return new RotatedObject(this.obj.Clone(), this.Angle)
{
Name = this.Name,
bindings = this.bindings.Clone()
};
}
public override Vector3 Position()
{
return Matrix.GetRotatedPoint(this.obj.Position(), this.Angle.X, this.Angle.Y, this.Angle.Z);
}
public override Bounds Bounds()
{
var oldBounds = obj.Bounds();
return new Bounds(Matrix.GetRotatedPoint(oldBounds.BottomLeft, this.Angle.X, this.Angle.Y, this.Angle.Z),
Matrix.GetRotatedPoint(oldBounds.TopRight, this.Angle.X, this.Angle.Y, this.Angle.Z));
}
private Bindings.Bindings bindings = new Bindings.Bindings(new Dictionary<string, string>() {
{ "angle", "angle" }
});
public override void Bind(string property, Variable variable)
{
var bindableVec = this.Angle as BindableVector;
if (bindableVec != null && property == "x" || property == "y" || property == "z")
{
bindableVec.Bind(property, variable);
}
else
{
this.bindings.Add<RotatedObject>(this, property, variable);
}
}
}
}

View File

@ -1,93 +0,0 @@
using OSCADSharp.Scripting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OSCADSharp.Spatial;
using OSCADSharp.Bindings;
namespace OSCADSharp.Transforms
{
/// <summary>
/// An object that's been rescaled
/// </summary>
internal class ScaledObject : SingleStatementObject
{
/// <summary>
/// The scale factor to be applied
/// </summary>
internal Vector3 ScaleFactor { get; set; } = new BindableVector(1, 1, 1);
/// <summary>
/// Creates a scaled object
/// </summary>
/// <param name="obj">Object(s) to be scaled</param>
/// <param name="scale">Scale factor in x/y/z components</param>
internal ScaledObject(OSCADObject obj, Vector3 scale) : base(obj)
{
this.ScaleFactor = new BindableVector(scale);
}
internal ScaledObject(OSCADObject obj, Variable normal) : base(obj)
{
this.Bind("scalefactor", normal);
}
internal ScaledObject(OSCADObject obj, Vector3 scale, Variable x, Variable y, Variable z) : base(obj)
{
this.ScaleFactor = new BindableVector(scale);
this.BindIfVariableNotNull("x", x);
this.BindIfVariableNotNull("y", y);
this.BindIfVariableNotNull("z", z);
}
public override string ToString()
{
string scale = this.bindings.Contains("scalefactor") ? this.bindings.Get("scalefactor").BoundVariable.Text : this.ScaleFactor.ToString();
string scaleCommand = String.Format("scale(v = {0})", scale);
var formatter = new SingleBlockFormatter(scaleCommand, this.obj.ToString());
return formatter.ToString();
}
public override OSCADObject Clone()
{
return new ScaledObject(this.obj.Clone(), this.ScaleFactor)
{
Name = this.Name,
bindings = this.bindings.Clone()
};
}
public override Vector3 Position()
{
return obj.Position() * this.ScaleFactor;
}
public override Bounds Bounds()
{
var oldBounds = obj.Bounds();
return new Bounds(oldBounds.BottomLeft * this.ScaleFactor, oldBounds.TopRight * this.ScaleFactor);
}
private Bindings.Bindings bindings = new Bindings.Bindings(new Dictionary<string, string>() {
{ "scalefactor", "scalefactor" }
});
public override void Bind(string property, Variable variable)
{
var bindableVec = this.ScaleFactor as BindableVector;
property = property == "scale" ? "scalefactor" : property;
if (bindableVec != null && property == "x" || property == "y" || property == "z")
{
bindableVec.Bind(property, variable);
}
else
{
this.bindings.Add<ScaledObject>(this, property, variable);
}
}
}
}

View File

@ -1,98 +0,0 @@
using OSCADSharp.Scripting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OSCADSharp.Spatial;
using OSCADSharp.Bindings;
namespace OSCADSharp.Transforms
{
/// <summary>
/// An object or objects that have been moved along the specified vector
/// </summary>
internal class TranslatedObject : SingleStatementObject
{
internal Vector3 Vector { get; set; }
/// <summary>
/// Creates a translated object
/// </summary>
/// <param name="obj">Object(s) to translate</param>
/// <param name="vector">Amount to translate by</param>
internal TranslatedObject(OSCADObject obj, Vector3 vector) : base(obj)
{
this.Vector = new BindableVector(vector);
}
internal TranslatedObject(OSCADObject obj, Variable normal) : base(obj)
{
this.Bind("vector", normal);
}
internal TranslatedObject(OSCADObject obj, Vector3 vector, Variable x, Variable y, Variable z) : base(obj)
{
this.Vector = new BindableVector(vector);
this.BindIfVariableNotNull("x", x);
this.BindIfVariableNotNull("y", y);
this.BindIfVariableNotNull("z", z);
}
internal TranslatedObject(OSCADObject obj) : base(obj)
{
}
public override string ToString()
{
string translation = this.bindings.Contains("vector") ? this.bindings.Get("vector").BoundVariable.Text : this.Vector.ToString();
string translateCommmand = String.Format("translate(v = {0})", translation);
var formatter = new SingleBlockFormatter(translateCommmand, this.obj.ToString());
return formatter.ToString();
}
public override OSCADObject Clone()
{
var bindableVec = this.Vector as BindableVector;
var clone = new TranslatedObject(this.obj.Clone())
{
Name = this.Name,
bindings = this.bindings.Clone(),
Vector = bindableVec != null ? bindableVec.Clone() : this.Vector.Clone()
};
return clone;
}
public override Vector3 Position()
{
return this.obj.Position() + this.Vector;
}
public override Bounds Bounds()
{
var oldBounds = obj.Bounds();
return new Bounds(oldBounds.BottomLeft + this.Vector, oldBounds.TopRight + this.Vector);
}
private Bindings.Bindings bindings = new Bindings.Bindings(new Dictionary<string, string>() {
{ "vector", "vector" }
});
public override void Bind(string property, Variable variable)
{
var bindableVec = this.Vector as BindableVector;
if (bindableVec != null && property == "x" || property == "y" || property == "z")
{
bindableVec.Bind(property, variable);
}
else
{
this.bindings.Add<TranslatedObject>(this, property, variable);
}
}
}
}

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>
private 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.BindIfVariableNotNull("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>
private 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>
private 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 readonly 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

@ -0,0 +1,453 @@
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 ColoredObject
/// <summary>
/// An OSCADObject that has color and/or opacity applied to it
/// </summary>
private class ColoredObject : SingleStatementObject
{
#region Attributes
internal string ColorName { get; set; } = "Yellow";
internal double Opacity { get; set; } = 1.0;
#endregion
/// <summary>
/// Creates a colorized object
/// </summary>
/// <param name="obj">The object(s) to which color will be applied</param>
/// <param name="color">The string-wise name of the color to be applied</param>
/// <param name="opacity">Opacity from 0.0 to 1.0 </param>
internal ColoredObject(OSCADObject obj, string color = "Yellow", double opacity = 1.0) : base(obj)
{
this.ColorName = color;
this.Opacity = opacity;
}
/// <summary>
/// Creates a colorized object with predefined bindings
/// </summary>
/// <param name="obj">The object(s) to which color will be applied</param>
/// <param name="colorName"></param>
/// <param name="opacity"></param>
internal ColoredObject(OSCADObject obj, Variable colorName, Variable opacity) : base(obj)
{
this.BindIfVariableNotNull("color", colorName);
this.BindIfVariableNotNull("opacity", opacity);
}
public override string ToString()
{
string colorName = this.bindings.Contains("color") ? this.bindings.Get("color").BoundVariable.Text :
"\"" + this.ColorName + "\"";
string opacity = this.bindings.Contains("opacity") ? this.bindings.Get("opacity").BoundVariable.Text
: this.Opacity.ToString();
string colorCommand = String.Format("color({0}, {1})", colorName, opacity);
var formatter = new SingleBlockFormatter(colorCommand, this.obj.ToString());
return formatter.ToString();
}
public override OSCADObject Clone()
{
return new ColoredObject(this.obj.Clone(), this.ColorName, this.Opacity)
{
Name = this.Name,
bindings = this.bindings.Clone()
};
}
public override Vector3 Position()
{
return this.obj.Position();
}
public override Bounds Bounds()
{
return this.obj.Bounds();
}
private Bindings bindings = new Bindings(new Dictionary<string, string>() {
{"color", "color" },
{"opacity", "opacity" }
});
public override void Bind(string property, Variable variable)
{
this.bindings.Add<ColoredObject>(this, property, variable);
}
}
#endregion
#region ResizedObject
/// <summary>
/// An OSCADObject that's been resized to a specified set of X/Y/Z dimensions
/// </summary>
private class ResizedObject : SingleStatementObject
{
/// <summary>
/// Size of the object in terms of X/Y/Z
/// </summary>
internal Vector3 Size { get; set; }
/// <summary>
/// Creates a resized object
/// </summary>
/// <param name="obj">The object(s) to be resized</param>
/// <param name="size">The size to resize to, in terms of x/y/z dimensions</param>
internal ResizedObject(OSCADObject obj, Vector3 size) : base(obj)
{
Size = new BindableVector(size);
}
internal ResizedObject(OSCADObject obj, Variable size) : base(obj)
{
this.BindIfVariableNotNull("size", size);
}
internal ResizedObject(OSCADObject obj, Vector3 size, Variable x, Variable y, Variable z) : base(obj)
{
this.Size = new BindableVector(size);
this.BindIfVariableNotNull("x", x);
this.BindIfVariableNotNull("y", y);
this.BindIfVariableNotNull("z", z);
}
internal ResizedObject(OSCADObject obj) : base(obj)
{
}
public override string ToString()
{
string size = this.bindings.Contains("size") ? this.bindings.Get("size").BoundVariable.Text : this.Size.ToString();
string resizeCommand = String.Format("resize({0})", size);
var formatter = new SingleBlockFormatter(resizeCommand, this.obj.ToString());
return formatter.ToString();
}
public override OSCADObject Clone()
{
var bndSize = this.Size as BindableVector;
return new ResizedObject(this.obj.Clone())
{
Name = this.Name,
bindings = this.bindings.Clone(),
Size = bndSize != null ? bndSize.Clone() : this.Size.Clone()
};
}
public override Vector3 Position()
{
var bounds = this.Bounds();
return Vector3.Average(bounds.BottomLeft, bounds.TopRight);
}
public override Bounds Bounds()
{
var oldBounds = obj.Bounds();
double xScaleFactor = this.Size.X > 0 ? this.Size.X / Math.Abs(oldBounds.XMax - oldBounds.XMin) : 1;
double yScaleFactor = this.Size.Y > 0 ? this.Size.Y / Math.Abs(oldBounds.YMax - oldBounds.YMin) : 1;
double zScaleFactor = this.Size.Z > 0 ? this.Size.Z / Math.Abs(oldBounds.ZMax - oldBounds.ZMin) : 1;
Vector3 scaleMultiplier = new Vector3(xScaleFactor, yScaleFactor, zScaleFactor);
return new Bounds(oldBounds.BottomLeft * scaleMultiplier, oldBounds.TopRight * scaleMultiplier);
}
private Bindings bindings = new Bindings(new Dictionary<string, string>() {
{ "size", "size" }
});
public override void Bind(string property, Variable variable)
{
var bindableVec = this.Size as BindableVector;
if (bindableVec != null && property == "x" || property == "y" || property == "z")
{
bindableVec.Bind(property, variable);
}
else
{
this.bindings.Add<ResizedObject>(this, property, variable);
}
}
}
#endregion
#region RotatedObject
/// <summary>
/// An OSCADObject with rotation applied
/// </summary>
private class RotatedObject : SingleStatementObject
{
/// <summary>
/// The angle to rotate, in terms of X/Y/Z euler angles
/// </summary>
internal Vector3 Angle { get; set; } = new BindableVector();
/// <summary>
/// Creates an object with rotation applied
/// </summary>
/// <param name="obj">The object being rotated</param>
/// <param name="angle">The angle to rotate</param>
internal RotatedObject(OSCADObject obj, Vector3 angle) : base(obj)
{
this.Angle = new BindableVector(angle);
}
internal RotatedObject(OSCADObject obj, Variable normal) : base(obj)
{
this.BindIfVariableNotNull("angle", normal);
}
internal RotatedObject(OSCADObject obj, Vector3 angle, Variable x, Variable y, Variable z) : base(obj)
{
this.Angle = new BindableVector(angle);
this.BindIfVariableNotNull("x", x);
this.BindIfVariableNotNull("y", y);
this.BindIfVariableNotNull("z", z);
}
public override string ToString()
{
string angle = this.bindings.Contains("angle") ? this.bindings.Get("angle").BoundVariable.Text : this.Angle.ToString();
string rotateCommand = String.Format("rotate({0})", angle.ToString());
var formatter = new SingleBlockFormatter(rotateCommand, this.obj.ToString());
return formatter.ToString();
}
public override OSCADObject Clone()
{
return new RotatedObject(this.obj.Clone(), this.Angle)
{
Name = this.Name,
bindings = this.bindings.Clone()
};
}
public override Vector3 Position()
{
return Matrix.GetRotatedPoint(this.obj.Position(), this.Angle.X, this.Angle.Y, this.Angle.Z);
}
public override Bounds Bounds()
{
var oldBounds = obj.Bounds();
return new Bounds(Matrix.GetRotatedPoint(oldBounds.BottomLeft, this.Angle.X, this.Angle.Y, this.Angle.Z),
Matrix.GetRotatedPoint(oldBounds.TopRight, this.Angle.X, this.Angle.Y, this.Angle.Z));
}
private Bindings bindings = new Bindings(new Dictionary<string, string>() {
{ "angle", "angle" }
});
public override void Bind(string property, Variable variable)
{
var bindableVec = this.Angle as BindableVector;
if (bindableVec != null && property == "x" || property == "y" || property == "z")
{
bindableVec.Bind(property, variable);
}
else
{
this.bindings.Add<RotatedObject>(this, property, variable);
}
}
}
#endregion
#region ScaledObject
/// <summary>
/// An object that's been rescaled
/// </summary>
private class ScaledObject : SingleStatementObject
{
/// <summary>
/// The scale factor to be applied
/// </summary>
internal Vector3 ScaleFactor { get; set; } = new BindableVector(1, 1, 1);
/// <summary>
/// Creates a scaled object
/// </summary>
/// <param name="obj">Object(s) to be scaled</param>
/// <param name="scale">Scale factor in x/y/z components</param>
internal ScaledObject(OSCADObject obj, Vector3 scale) : base(obj)
{
this.ScaleFactor = new BindableVector(scale);
}
internal ScaledObject(OSCADObject obj, Variable normal) : base(obj)
{
this.BindIfVariableNotNull("scalefactor", normal);
}
internal ScaledObject(OSCADObject obj, Vector3 scale, Variable x, Variable y, Variable z) : base(obj)
{
this.ScaleFactor = new BindableVector(scale);
this.BindIfVariableNotNull("x", x);
this.BindIfVariableNotNull("y", y);
this.BindIfVariableNotNull("z", z);
}
public override string ToString()
{
string scale = this.bindings.Contains("scalefactor") ? this.bindings.Get("scalefactor").BoundVariable.Text : this.ScaleFactor.ToString();
string scaleCommand = String.Format("scale(v = {0})", scale);
var formatter = new SingleBlockFormatter(scaleCommand, this.obj.ToString());
return formatter.ToString();
}
public override OSCADObject Clone()
{
return new ScaledObject(this.obj.Clone(), this.ScaleFactor)
{
Name = this.Name,
bindings = this.bindings.Clone()
};
}
public override Vector3 Position()
{
return obj.Position() * this.ScaleFactor;
}
public override Bounds Bounds()
{
var oldBounds = obj.Bounds();
return new Bounds(oldBounds.BottomLeft * this.ScaleFactor, oldBounds.TopRight * this.ScaleFactor);
}
private Bindings bindings = new Bindings(new Dictionary<string, string>() {
{ "scalefactor", "scalefactor" }
});
public override void Bind(string property, Variable variable)
{
var bindableVec = this.ScaleFactor as BindableVector;
property = property == "scale" ? "scalefactor" : property;
if (bindableVec != null && property == "x" || property == "y" || property == "z")
{
bindableVec.Bind(property, variable);
}
else
{
this.bindings.Add<ScaledObject>(this, property, variable);
}
}
}
#endregion
#region TranslatedObject
/// <summary>
/// An OSCADObject or objects that have been moved along the specified vector
/// </summary>
private class TranslatedObject : SingleStatementObject
{
internal Vector3 Vector { get; set; }
/// <summary>
/// Creates a translated object
/// </summary>
/// <param name="obj">Object(s) to translate</param>
/// <param name="vector">Amount to translate by</param>
internal TranslatedObject(OSCADObject obj, Vector3 vector) : base(obj)
{
this.Vector = new BindableVector(vector);
}
internal TranslatedObject(OSCADObject obj, Variable normal) : base(obj)
{
this.BindIfVariableNotNull("vector", normal);
}
internal TranslatedObject(OSCADObject obj, Vector3 vector, Variable x, Variable y, Variable z) : base(obj)
{
this.Vector = new BindableVector(vector);
this.BindIfVariableNotNull("x", x);
this.BindIfVariableNotNull("y", y);
this.BindIfVariableNotNull("z", z);
}
internal TranslatedObject(OSCADObject obj) : base(obj)
{
}
public override string ToString()
{
string translation = this.bindings.Contains("vector") ? this.bindings.Get("vector").BoundVariable.Text : this.Vector.ToString();
string translateCommmand = String.Format("translate(v = {0})", translation);
var formatter = new SingleBlockFormatter(translateCommmand, this.obj.ToString());
return formatter.ToString();
}
public override OSCADObject Clone()
{
var bindableVec = this.Vector as BindableVector;
var clone = new TranslatedObject(this.obj.Clone())
{
Name = this.Name,
bindings = this.bindings.Clone(),
Vector = bindableVec != null ? bindableVec.Clone() : this.Vector.Clone()
};
return clone;
}
public override Vector3 Position()
{
return this.obj.Position() + this.Vector;
}
public override Bounds Bounds()
{
var oldBounds = obj.Bounds();
return new Bounds(oldBounds.BottomLeft + this.Vector, oldBounds.TopRight + this.Vector);
}
private Bindings bindings = new Bindings(new Dictionary<string, string>() {
{ "vector", "vector" }
});
public override void Bind(string property, Variable variable)
{
var bindableVec = this.Vector as BindableVector;
if (bindableVec != null && property == "x" || property == "y" || property == "z")
{
bindableVec.Bind(property, variable);
}
else
{
this.bindings.Add<TranslatedObject>(this, property, variable);
}
}
}
#endregion
}
}

View File

@ -0,0 +1,80 @@
using OSCADSharp.Spatial;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OSCADSharp
{
public abstract partial class OSCADObject
{
#region Difference
/// <summary>
/// Subtracts the 2nd (and all further) child nodes from the first one (logical and not).
/// </summary>
private class DifferencedObject : MultiStatementObject
{
/// <summary>
/// Creates a subtraction of child nodes
/// </summary>
/// <param name="children"></param>
internal DifferencedObject(IEnumerable<OSCADObject> children) : base("difference()", children)
{
}
public override Vector3 Position()
{
return m_children[0].Position();
}
public override Bounds Bounds()
{
return m_children[0].Bounds();
}
}
#endregion
#region Intersection
/// <summary>
/// Creates the intersection of all child nodes
/// </summary>
private class IntersectedObject : MultiStatementObject
{
/// <summary>
/// Creates the intersection of all child nodes
/// </summary>
/// <param name="children"></param>
internal IntersectedObject(IEnumerable<OSCADObject> children) : base("intersection()", children)
{
}
public override Vector3 Position()
{
throw new NotSupportedException("Position is not supported on Intersected objects.");
}
public override Bounds Bounds()
{
throw new NotSupportedException("Bounds is not supported on Intersected objects.");
}
}
#endregion
#region Union
/// <summary>
/// A union of child nodes. This is the sum of all children (logical or).
/// </summary>
private class UnionedObject : MultiStatementObject
{
/// <summary>
/// Create a union that is the combination of all children
/// </summary>
/// <param name="children">OSCADObjects to combine</param>
internal UnionedObject(IEnumerable<OSCADObject> children) : base("union()", children)
{
}
}
#endregion
}
}

View File

@ -1,9 +1,7 @@
using OSCADSharp.Bindings; using OSCADSharp.DataBinding;
using OSCADSharp.Booleans; using OSCADSharp.IO;
using OSCADSharp.Files;
using OSCADSharp.Scripting;
using OSCADSharp.Spatial; using OSCADSharp.Spatial;
using OSCADSharp.Transforms; using OSCADSharp.Utility;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
@ -11,22 +9,24 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
[assembly: CLSCompliant(true)]
namespace OSCADSharp namespace OSCADSharp
{ {
/// <summary> /// <summary>
/// Represents any Object or collection of objects that becomes am /// Represents any Object or collection of objects that becomes am
/// an OpenSCAD script when converted to a string. /// an OpenSCAD script when converted to a string.
/// </summary> /// </summary>
public abstract class OSCADObject : IBindable public abstract partial class OSCADObject : IBindable
{ {
#region Attributes #region Attributes
private uint id = Ids.Get(); private readonly int id = Ids.Get();
/// <summary> /// <summary>
/// The unique Id of the object /// The unique Id of the object
/// these values auto-increment /// these values auto-increment
/// </summary> /// </summary>
public uint Id { get { return this.id; } } public int Id { get { return this.id; } }
/// <summary> /// <summary>
/// Name of this OSCADObject /// Name of this OSCADObject
@ -685,7 +685,7 @@ namespace OSCADSharp
/// <returns></returns> /// <returns></returns>
public OSCADObject Union(params OSCADObject[] objects) public OSCADObject Union(params OSCADObject[] objects)
{ {
return doBlockStatement("Union", objects, (children) => { return new Union(children); }); return doBlockStatement("Union", objects, (children) => { return new UnionedObject(children); });
} }
/// <summary> /// <summary>
@ -696,7 +696,7 @@ namespace OSCADSharp
/// <returns></returns> /// <returns></returns>
public OSCADObject Difference(params OSCADObject[] objects) public OSCADObject Difference(params OSCADObject[] objects)
{ {
return doBlockStatement("Difference", objects, (children) => { return new Difference(children); }); return doBlockStatement("Difference", objects, (children) => { return new DifferencedObject(children); });
} }
/// <summary> /// <summary>
@ -708,7 +708,7 @@ namespace OSCADSharp
/// <returns></returns> /// <returns></returns>
public OSCADObject Intersection(params OSCADObject[] objects) public OSCADObject Intersection(params OSCADObject[] objects)
{ {
return doBlockStatement("Intersection", objects, (children) => { return new Intersection(children); }); return doBlockStatement("Intersection", objects, (children) => { return new IntersectedObject(children); });
} }
private OSCADObject doBlockStatement(string name, OSCADObject[] objects, Func<IEnumerable<OSCADObject>, OSCADObject> factory) private OSCADObject doBlockStatement(string name, OSCADObject[] objects, Func<IEnumerable<OSCADObject>, OSCADObject> factory)
@ -781,7 +781,7 @@ namespace OSCADSharp
/// <summary> /// <summary>
/// Internal collection of children for this object /// Internal collection of children for this object
/// </summary> /// </summary>
protected List<OSCADObject> children = new List<OSCADObject>(); protected List<OSCADObject> m_children { get; set; } = new List<OSCADObject>();
/// <summary> /// <summary>
/// Returns all chidren of this OSCADObject /// Returns all chidren of this OSCADObject
@ -792,12 +792,12 @@ namespace OSCADSharp
{ {
if(recursive == false) if(recursive == false)
{ {
return new List<OSCADObject>(this.children); return new List<OSCADObject>(this.m_children);
} }
// Initial children are reversed here because for objects with multiple children (such as boolean operations) // Initial children are reversed here because for objects with multiple children (such as boolean operations)
// the natural collection order would yield opposite the expected order in a stack (first child would be the last popped) // the natural collection order would yield opposite the expected order in a stack (first child would be the last popped)
Stack<OSCADObject> toTraverse = new Stack<OSCADObject>(this.children.Reverse<OSCADObject>()); Stack<OSCADObject> toTraverse = new Stack<OSCADObject>(this.m_children.Reverse<OSCADObject>());
List<OSCADObject> allChildren = new List<OSCADObject>(); List<OSCADObject> allChildren = new List<OSCADObject>();
OSCADObject child = null; OSCADObject child = null;
@ -806,7 +806,7 @@ namespace OSCADSharp
child = toTraverse.Pop(); child = toTraverse.Pop();
allChildren.Add(child); allChildren.Add(child);
foreach (var subChild in child.children) foreach (var subChild in child.m_children)
{ {
toTraverse.Push(subChild); toTraverse.Push(subChild);
} }
@ -842,7 +842,7 @@ namespace OSCADSharp
Dependencies.FileWriter.WriteAllLines(path, new string[] Dependencies.FileWriter.WriteAllLines(path, new string[]
{ {
Settings.OSCADSharpHeader, OutputSettings.OSCADSharpHeader,
Variables.Global.ToString(), Variables.Global.ToString(),
this.ToString() this.ToString()
}); });
@ -868,19 +868,19 @@ namespace OSCADSharp
/// <returns></returns> /// <returns></returns>
public static OSCADObject operator +(OSCADObject left, OSCADObject right) public static OSCADObject operator +(OSCADObject left, OSCADObject right)
{ {
if(left.GetType() == typeof(Union)) if(left.GetType() == typeof(UnionedObject))
{ {
left.children.Add(right); left.m_children.Add(right);
return left; return left;
} }
else if(right.GetType() == typeof(Union)) else if(right.GetType() == typeof(UnionedObject))
{ {
right.children.Add(left); right.m_children.Add(left);
return right; return right;
} }
else else
{ {
return new Union(new OSCADObject[] {left, right }); return new UnionedObject(new OSCADObject[] {left, right });
} }
} }
@ -892,19 +892,19 @@ namespace OSCADSharp
/// <returns></returns> /// <returns></returns>
public static OSCADObject operator -(OSCADObject left, OSCADObject right) public static OSCADObject operator -(OSCADObject left, OSCADObject right)
{ {
if (left.GetType() == typeof(Difference)) if (left.GetType() == typeof(DifferencedObject))
{ {
left.children.Add(right); left.m_children.Add(right);
return left; return left;
} }
else if (right.GetType() == typeof(Difference)) else if (right.GetType() == typeof(DifferencedObject))
{ {
right.children.Add(left); right.m_children.Add(left);
return right; return right;
} }
else else
{ {
return new Difference(new OSCADObject[] {left, right }); return new DifferencedObject(new OSCADObject[] {left, right });
} }
} }
#endregion #endregion

View File

@ -42,53 +42,38 @@
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Internal\Bindings\BindableBoolean.cs" /> <Compile Include="DataBinding\BindableBoolean.cs" />
<Compile Include="Internal\Scripting\VariableCalculator.cs" /> <Compile Include="OSCADObject.AbstractTransforms.cs" />
<Compile Include="Internal\Scripting\CompoundVariable.cs" /> <Compile Include="OSCADObject.BaseTransform.cs" />
<Compile Include="Public\Settings\Dependencies.cs" /> <Compile Include="OSCADObject.BasicTransforms.cs" />
<Compile Include="Internal\Files\DefaultFileInvoker.cs" /> <Compile Include="OSCADObject.Booleans.cs" />
<Compile Include="Internal\Files\DefaultFileWriter.cs" /> <Compile Include="Utility\Dependencies.cs" />
<Compile Include="Public\Files\IFileInvoker.cs" /> <Compile Include="IO\DefaultFileInvoker.cs" />
<Compile Include="Public\Files\IFileWriter.cs" /> <Compile Include="IO\DefaultFileWriter.cs" />
<Compile Include="Internal\Settings\Ids.cs" /> <Compile Include="IO\IFileInvoker.cs" />
<Compile Include="Internal\Settings\OpenSCADPathFinder.cs" /> <Compile Include="IO\IFileWriter.cs" />
<Compile Include="Internal\Bindings\Binding.cs" /> <Compile Include="Utility\Ids.cs" />
<Compile Include="Internal\Bindings\Bindings.cs" /> <Compile Include="DataBinding\Binding.cs" />
<Compile Include="Internal\Bindings\IBindable.cs" /> <Compile Include="DataBinding\Bindings.cs" />
<Compile Include="Internal\Scripting\SingleStatementObject.cs" /> <Compile Include="DataBinding\IBindable.cs" />
<Compile Include="Internal\Scripting\StatementBuilder.cs" /> <Compile Include="Utility\StatementBuilder.cs" />
<Compile Include="Public\Scripting\Variable.cs" /> <Compile Include="DataBinding\Variable.cs" />
<Compile Include="Public\Settings\Settings.cs" /> <Compile Include="IO\OutputSettings.cs" />
<Compile Include="Public\Inches.cs" /> <Compile Include="Utility\Inches.cs" />
<Compile Include="Internal\Bindings\BindableVector.cs" /> <Compile Include="DataBinding\BindableVector.cs" />
<Compile Include="Public\Spatial\Bounds.cs" /> <Compile Include="Spatial\Bounds.cs" />
<Compile Include="Internal\Spatial\Matrix.cs" /> <Compile Include="Spatial\Matrix.cs" />
<Compile Include="Internal\Transforms\HulledObject.cs" /> <Compile Include="Utility\SingleBlockFormatter.cs" />
<Compile Include="Internal\Transforms\LinearExtrudedObject.cs" /> <Compile Include="OSCADObject.cs" />
<Compile Include="Internal\Scripting\SingleBlockFormatter.cs" />
<Compile Include="Internal\Scripting\MultiStatementObject.cs" />
<Compile Include="Internal\Booleans\Difference.cs" />
<Compile Include="Internal\Booleans\Intersection.cs" />
<Compile Include="Internal\Booleans\Union.cs" />
<Compile Include="Public\OSCADObject.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Public\Solids\Cube.cs" /> <Compile Include="Solids\Cube.cs" />
<Compile Include="Public\Solids\Cylinder.cs" /> <Compile Include="Solids\Cylinder.cs" />
<Compile Include="Public\Solids\Sphere.cs" /> <Compile Include="Solids\Sphere.cs" />
<Compile Include="Public\Solids\Text3D.cs" /> <Compile Include="Solids\Text3D.cs" />
<Compile Include="Internal\Transforms\ColoredObject.cs" /> <Compile Include="Spatial\Vector3.cs" />
<Compile Include="Internal\Transforms\MinkowskiedObject.cs" /> <Compile Include="DataBinding\Variables.cs" />
<Compile Include="Internal\Transforms\MirroredObject.cs" />
<Compile Include="Internal\Transforms\ResizedObject.cs" />
<Compile Include="Internal\Transforms\RotatedObject.cs" />
<Compile Include="Internal\Transforms\ScaledObject.cs" />
<Compile Include="Internal\Transforms\TranslatedObject.cs" />
<Compile Include="Public\Spatial\Vector3.cs" />
<Compile Include="Public\Scripting\Variables.cs" />
</ItemGroup>
<ItemGroup>
<None Include="OSCADSharp.nuspec" />
</ItemGroup> </ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.

View File

@ -1,25 +0,0 @@
using OSCADSharp.Files;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OSCADSharp
{
/// <summary>
/// Contains definitions for external APIs used by OSCADSharp
/// </summary>
public static class Dependencies
{
/// <summary>
/// Used to write scripts to file
/// </summary>
public static IFileWriter FileWriter = new DefaultFileWriter();
/// <summary>
/// Factory method to provide the class used to perform actions on output scripts
/// </summary>
public static Func<string, IFileInvoker> FileInvokerFactory = (path) => { return new DefaultFileInvoker(path); };
}
}

View File

@ -1,29 +0,0 @@
using OSCADSharp.Files;
using OSCADSharp.Scripting;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OSCADSharp
{
/// <summary>
/// Settings for OpenSCAD scripts
/// </summary>
public static class Settings
{
/// <summary>
/// Code-gen header
/// </summary>
public static readonly string OSCADSharpHeader = String.Format("/*Code Generated using OSCADSharp on {0}. {1}{2}For more information, please visit https://github.com/Exolun/OSCADSharp */{3}",
DateTime.Now.ToString(), Environment.NewLine, Environment.NewLine, Environment.NewLine);
/// <summary>
/// Path to the OpenSCAD executable for file invocation
/// (Default value is set the default install directory on Windows)
/// </summary>
public static string OpenSCADPath = new OpenSCADPathFinder().GetPath();
}
}

View File

@ -1,13 +1,12 @@
using System; using OSCADSharp.DataBinding;
using OSCADSharp.Spatial;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using OSCADSharp.Spatial;
using OSCADSharp.Bindings;
using OSCADSharp.Scripting;
namespace OSCADSharp namespace OSCADSharp.Solids
{ {
/// <summary> /// <summary>
/// A Cube geometry /// A Cube geometry
@ -137,7 +136,7 @@ namespace OSCADSharp
public override Vector3 Position() public override Vector3 Position()
{ {
Vector3 position; Vector3 position;
if(this.Center == false) if (this.Center == false)
{ {
position = new Vector3(this.Size.X / 2, this.Size.Y / 2, this.Size.Z / 2); position = new Vector3(this.Size.X / 2, this.Size.Y / 2, this.Size.Z / 2);
} }
@ -155,7 +154,7 @@ namespace OSCADSharp
/// <returns></returns> /// <returns></returns>
public override Bounds Bounds() public override Bounds Bounds()
{ {
if(Center == false) if (Center == false)
{ {
return new Bounds(new Vector3(), new Vector3(this.Size.X, this.Size.Y, this.Size.Z)); return new Bounds(new Vector3(), new Vector3(this.Size.X, this.Size.Y, this.Size.Z));
} }
@ -166,7 +165,7 @@ namespace OSCADSharp
} }
} }
private Bindings.Bindings bindings = new Bindings.Bindings(); private Bindings bindings = new Bindings();
private static readonly Dictionary<string, string> sizeSynonyms = new Dictionary<string, string>() private static readonly Dictionary<string, string> sizeSynonyms = new Dictionary<string, string>()
{ {
{"size.x", "x" }, {"size.x", "x" },
@ -195,7 +194,7 @@ namespace OSCADSharp
vec.Bind(property, variable); vec.Bind(property, variable);
} }
else if(property.ToLower() == "center") else if (property.ToLower() == "center")
{ {
this.centerBinding.Bind(property, variable); this.centerBinding.Bind(property, variable);
this.center = Convert.ToBoolean(variable.Value); this.center = Convert.ToBoolean(variable.Value);

View File

@ -1,13 +1,13 @@
using System; using OSCADSharp.DataBinding;
using OSCADSharp.Spatial;
using OSCADSharp.Utility;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using OSCADSharp.Spatial;
using OSCADSharp.Scripting;
using OSCADSharp.Bindings;
namespace OSCADSharp namespace OSCADSharp.Solids
{ {
/// <summary> /// <summary>
/// A Cylinder geometry /// A Cylinder geometry
@ -261,7 +261,7 @@ namespace OSCADSharp
} }
} }
private Bindings.Bindings bindings = new Bindings.Bindings(new Dictionary<string, string>() private Bindings bindings = new Bindings(new Dictionary<string, string>()
{ {
{"radius", "r" }, {"radius", "r" },
{"radius1", "r1" }, {"radius1", "r1" },

View File

@ -3,13 +3,13 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using OSCADSharp.Spatial;
using OSCADSharp.Scripting;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Reflection; using System.Reflection;
using OSCADSharp.Bindings; using OSCADSharp.Spatial;
using OSCADSharp.DataBinding;
using OSCADSharp.Utility;
namespace OSCADSharp namespace OSCADSharp.Solids
{ {
/// <summary> /// <summary>
/// A Sphere geometry /// A Sphere geometry
@ -25,7 +25,8 @@ namespace OSCADSharp
/// <summary> /// <summary>
/// This is the diameter of the sphere /// This is the diameter of the sphere
/// </summary> /// </summary>
public double Diameter { public double Diameter
{
get { return this.Radius * 2; } get { return this.Radius * 2; }
set { this.Radius = value / 2; } set { this.Radius = value / 2; }
} }
@ -147,7 +148,7 @@ namespace OSCADSharp
new Vector3(this.Radius, this.Radius, this.Radius)); new Vector3(this.Radius, this.Radius, this.Radius));
} }
private Bindings.Bindings bindings = new Bindings.Bindings(new Dictionary<string, string>() private Bindings bindings = new Bindings(new Dictionary<string, string>()
{ {
{ "radius", "r" }, { "radius", "r" },
{ "minimumangle", "$fa" }, { "minimumangle", "$fa" },

View File

@ -1,13 +1,13 @@
using OSCADSharp.Scripting; using OSCADSharp.DataBinding;
using OSCADSharp.Spatial;
using OSCADSharp.Utility;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using OSCADSharp.Spatial;
using OSCADSharp.Bindings;
namespace OSCADSharp namespace OSCADSharp.Solids
{ {
/// <summary> /// <summary>
/// Create text using fonts installed on the local system or provided as separate font file. /// Create text using fonts installed on the local system or provided as separate font file.
@ -170,7 +170,7 @@ namespace OSCADSharp
throw new NotSupportedException("Bounds are not supported for objects using Text3D"); throw new NotSupportedException("Bounds are not supported for objects using Text3D");
} }
private Bindings.Bindings bindings = new Bindings.Bindings(new Dictionary<string, string>() private Bindings bindings = new Bindings(new Dictionary<string, string>()
{ {
{ "text", "text" }, { "text", "text" },
{ "size", "size" }, { "size", "size" },

View File

@ -1,10 +1,11 @@
using System; using OSCADSharp.Spatial;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace OSCADSharp namespace OSCADSharp.Spatial
{ {
/// <summary> /// <summary>
/// A set of boundaries /// A set of boundaries

View File

@ -1,4 +1,5 @@
using System; using OSCADSharp.Spatial;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
@ -13,7 +14,7 @@ namespace OSCADSharp.Spatial
internal class Matrix internal class Matrix
{ {
#region Fields/Properties #region Fields/Properties
private double[] values; private readonly double[] values;
internal int ColumnCount { get; private set; } internal int ColumnCount { get; private set; }
internal int RowCount { get; private set; } internal int RowCount { get; private set; }
@ -78,13 +79,14 @@ namespace OSCADSharp.Spatial
return piOver180 * degrees; return piOver180 * degrees;
} }
private static readonly Matrix identity = new Matrix(new double[] { internal static Matrix Identity()
1, 0, 0, 0, {
0, 1, 0, 0, return new Matrix(new double[] {
0, 0, 1, 0, 1, 0, 0, 0,
0, 0, 0, 1 0, 1, 0, 0,
}, 4, 4); 0, 0, 1, 0,
internal static Matrix Identity { get { return identity; } } 0, 0, 0, 1}, 4, 4); ;
}
/// <summary> /// <summary>
/// Gets a transformation matrix for performing rotations on the X-Axis /// Gets a transformation matrix for performing rotations on the X-Axis
@ -95,7 +97,7 @@ namespace OSCADSharp.Spatial
internal static Matrix XRotation(double angle) internal static Matrix XRotation(double angle)
{ {
if (angle == 0) if (angle == 0)
return Identity; return Identity();
double radAngle = toRadians(angle); double radAngle = toRadians(angle);
double[] rotationArr = new double[] { double[] rotationArr = new double[] {
@ -117,7 +119,7 @@ namespace OSCADSharp.Spatial
internal static Matrix YRotation(double angle) internal static Matrix YRotation(double angle)
{ {
if (angle == 0) if (angle == 0)
return Identity; return Identity();
double radAngle = toRadians(angle); double radAngle = toRadians(angle);
double[] rotationArr = new double[] { double[] rotationArr = new double[] {
@ -139,7 +141,7 @@ namespace OSCADSharp.Spatial
internal static Matrix ZRotation(double angle) internal static Matrix ZRotation(double angle)
{ {
if (angle == 0) if (angle == 0)
return Identity; return Identity();
double radAngle = toRadians(angle); double radAngle = toRadians(angle);
double[] rotationArr = new double[] { double[] rotationArr = new double[] {

View File

@ -1,11 +1,10 @@
using OSCADSharp.Spatial; using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace OSCADSharp namespace OSCADSharp.Spatial
{ {
/// <summary> /// <summary>
/// A Three-Dimensional vector /// A Three-Dimensional vector

View File

@ -0,0 +1,45 @@
using OSCADSharp.IO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OSCADSharp.Utility
{
/// <summary>
/// Contains definitions for external APIs used by OSCADSharp
/// </summary>
public static class Dependencies
{
/// <summary>
/// Used to write scripts to file
/// </summary>
public static IFileWriter FileWriter { get; private set; } = new DefaultFileWriter();
/// <summary>
/// Sets the filewriter for OSCADSharp to use
/// </summary>
/// <param name="writer"></param>
public static void SetFileWriter(IFileWriter writer)
{
FileWriter = writer;
}
/// <summary>
/// Factory method to provide the class used to perform actions on output scripts
/// </summary>
public static Func<string, IFileInvoker> FileInvokerFactory { get; private set; } = (path) => { return new DefaultFileInvoker(path); };
/// <summary>
/// Sets the factory method OSCADSharp will use to get
/// file invoker objects
/// </summary>
/// <param name="invokerFactoryMethod"></param>
public static void SetFileInvokerFactory(Func<string, IFileInvoker> invokerFactoryMethod)
{
FileInvokerFactory = invokerFactoryMethod;
}
}
}

View File

@ -4,21 +4,21 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace OSCADSharp namespace OSCADSharp.Utility
{ {
/// <summary> /// <summary>
/// Responsible for creating identifiers for objects /// Responsible for creating identifiers for objects
/// </summary> /// </summary>
internal static class Ids internal static class Ids
{ {
private static uint globalId = 0; private static int globalId = 0;
private static object idLockObject = new object(); private readonly static object idLockObject = new object();
/// <summary> /// <summary>
/// Gets a unique auto-incrementing integer id /// Gets a unique auto-incrementing integer id
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
internal static uint Get() internal static int Get()
{ {
lock (idLockObject) lock (idLockObject)
{ {

View File

@ -4,37 +4,37 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace OSCADSharp namespace OSCADSharp.Utility
{ {
/// <summary> /// <summary>
/// Constants and conversions for units for us imperial-minded folks. /// Constants and conversions for units for us imperial-minded folks.
/// </summary> /// </summary>
public class Inches public static class Inches
{ {
/// <summary> /// <summary>
/// One imperial inch /// One imperial inch
/// </summary> /// </summary>
public const double One = 25.4; public static double One { get; private set; } = 25.4;
/// <summary> /// <summary>
/// Half of an imperial inch /// Half of an imperial inch
/// </summary> /// </summary>
public const double Half = One / 2; public static double Half { get; private set; } = One / 2;
/// <summary> /// <summary>
/// Quarter of an imperial inch /// Quarter of an imperial inch
/// </summary> /// </summary>
public const double Quarter = Half / 2; public static double Quarter { get; private set; } = Half / 2;
/// <summary> /// <summary>
/// Eigth of an imperial inch /// Eigth of an imperial inch
/// </summary> /// </summary>
public const double Eigth = Quarter / 2; public static double Eigth { get; private set; } = Quarter / 2;
/// <summary> /// <summary>
/// Sixteenth of an imperial inch /// Sixteenth of an imperial inch
/// </summary> /// </summary>
public const double Sixteenth = Eigth / 2; public static double Sixteenth { get; private set; } = Eigth / 2;
/// <summary> /// <summary>
/// Converts inches to millimeters /// Converts inches to millimeters

View File

@ -5,7 +5,7 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace OSCADSharp.Scripting namespace OSCADSharp.Utility
{ {
/// <summary> /// <summary>
/// A class that creates blocks of curly-braced script with the /// A class that creates blocks of curly-braced script with the
@ -13,9 +13,9 @@ namespace OSCADSharp.Scripting
/// </summary> /// </summary>
internal class SingleBlockFormatter internal class SingleBlockFormatter
{ {
private string outerCode; private readonly string outerCode;
private string innerCode; private readonly string innerCode;
private string indentationAmount = " "; private readonly string indentationAmount = " ";
internal SingleBlockFormatter(string outerCode, string innerCode) internal SingleBlockFormatter(string outerCode, string innerCode)
{ {

View File

@ -1,10 +1,11 @@
using System; using OSCADSharp.DataBinding;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace OSCADSharp.Scripting namespace OSCADSharp.Utility
{ {
/// <summary> /// <summary>
/// Extends the capabilities of StringBuilder with domain-specific behavior /// Extends the capabilities of StringBuilder with domain-specific behavior
@ -13,25 +14,20 @@ namespace OSCADSharp.Scripting
internal class StatementBuilder internal class StatementBuilder
{ {
private StringBuilder SB { get; set; } = new StringBuilder(); private StringBuilder SB { get; set; } = new StringBuilder();
private Bindings.Bindings bindings = null; private readonly Bindings bindings = null;
internal StatementBuilder() internal StatementBuilder(Bindings bindings)
{
}
internal StatementBuilder(Bindings.Bindings bindings)
{ {
this.bindings = bindings; this.bindings = bindings;
} }
/// <summary> /// <summary>
/// Special append method for conditionally adding value-pairs /// Special append method for conditionally adding value-pairs
/// </summary> /// </summary>
/// <param name="name">The Name of the value-pair</param> /// <param name="name">The Name of the value-pair</param>
/// <param name="value">The value - if null this method does nothing</param> /// <param name="value">The value - if null this method does nothing</param>
/// <param name="prefixWithComma">(optional) Flag indicating whether a comma should be added before the value-pair</param> /// <param name="prefixWithComma">(optional) Flag indicating whether a comma should be added before the value-pair</param>
public void AppendValuePairIfExists(string name, object value, bool prefixWithComma = false) internal void AppendValuePairIfExists(string name, object value, bool prefixWithComma = false)
{ {
bool useBinding = this.shouldUseBinding(name); bool useBinding = this.shouldUseBinding(name);
@ -45,7 +41,7 @@ namespace OSCADSharp.Scripting
SB.Append(name); SB.Append(name);
SB.Append(" = "); SB.Append(" = ");
if(useBinding) if (useBinding)
{ {
SB.Append(this.bindings.Get(name).BoundVariable.Text); SB.Append(this.bindings.Get(name).BoundVariable.Text);
} }
@ -65,20 +61,11 @@ namespace OSCADSharp.Scripting
/// Pass-through for StringBuilder.Append /// Pass-through for StringBuilder.Append
/// </summary> /// </summary>
/// <param name="text"></param> /// <param name="text"></param>
public void Append(string text) internal void Append(string text)
{ {
SB.Append(text); SB.Append(text);
} }
/// <summary>
/// Pass-through for StringBuilder.AppendLine
/// </summary>
/// <param name="text"></param>
public void AppendLine(string text)
{
SB.AppendLine(text);
}
/// <summary> /// <summary>
/// Gets this builder's full string /// Gets this builder's full string
/// </summary> /// </summary>