mirror of
https://github.com/eliasstepanik/OSCADSharpDotnet7.git
synced 2026-01-11 21:48:34 +00:00
Merge pull request #4 from Exolun/Refactor/BindingRefactor
Refactor/binding refactor
This commit is contained in:
commit
b4feff07ec
1
.gitignore
vendored
1
.gitignore
vendored
@ -210,3 +210,4 @@ FakesAssemblies/
|
||||
GeneratedArtifacts/
|
||||
_Pvt_Extensions/
|
||||
ModelManifest.xml
|
||||
OSCADSharp/NDependOut/
|
||||
|
||||
@ -1,29 +1,82 @@
|
||||
|
||||
using OSCADSharp.DataBinding;
|
||||
using OSCADSharp.Solids;
|
||||
using OSCADSharp.Spatial;
|
||||
using OSCADSharp.Utility;
|
||||
|
||||
namespace OSCADSharp.ConsoleTests
|
||||
{
|
||||
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)
|
||||
{
|
||||
var diam = new Variable("mainColumn", Inches.Half);
|
||||
var height = new Variable("overallHeight", Inches.Quarter);
|
||||
Variables.Global.Add(diam);
|
||||
Variables.Global.Add(height);
|
||||
makePeg();
|
||||
|
||||
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 pos = cyl.Position();
|
||||
var cyl1 = new Cylinder(1, 100, true).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 axisHelper = cyl1.Union(cyl2, cyl3).Color("Red");
|
||||
//var cyl = new Cylinder(diam, diam, height);
|
||||
|
||||
//var topCorner = new Sphere().Translate(obj.Bounds().TopRight);
|
||||
//var botCorner = new Sphere().Translate(obj.Bounds().BottomLeft);
|
||||
|
||||
(cyl + axisHelper).ToFile("test.scad").Open();
|
||||
|
||||
//var pos = cyl.Position();
|
||||
//var cyl1 = new Cylinder(1, 100, true).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 axisHelper = cyl1.Union(cyl2, cyl3).Color("Red");
|
||||
|
||||
////var topCorner = new Sphere().Translate(obj.Bounds().TopRight);
|
||||
////var botCorner = new Sphere().Translate(obj.Bounds().BottomLeft);
|
||||
|
||||
//(cyl + axisHelper).ToFile("test.scad").Open();
|
||||
|
||||
//Console.ReadKey();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using System.Linq;
|
||||
using OSCADSharp.DataBinding;
|
||||
using OSCADSharp.Solids;
|
||||
|
||||
namespace OSCADSharp.UnitTests
|
||||
{
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using OSCADSharp.Solids;
|
||||
|
||||
namespace OSCADSharp.UnitTests
|
||||
{
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using OSCADSharp.Solids;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using OSCADSharp.Solids;
|
||||
using OSCADSharp.Spatial;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using OSCADSharp.Files;
|
||||
using OSCADSharp.Scripting;
|
||||
using OSCADSharp.DataBinding;
|
||||
using OSCADSharp.IO;
|
||||
using OSCADSharp.Solids;
|
||||
using OSCADSharp.Utility;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
@ -80,7 +82,7 @@ namespace OSCADSharp.UnitTests
|
||||
.Translate(0, 5, 10).Rotate(0, 90, 0)
|
||||
.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);
|
||||
|
||||
Assert.AreEqual(ids.Count, ids.Distinct().Count());
|
||||
@ -147,11 +149,11 @@ namespace OSCADSharp.UnitTests
|
||||
var mock = new Mock<IFileWriter>();
|
||||
mock.Setup(_wrtr => _wrtr.WriteAllLines(It.IsAny<string>(), It.IsAny<string[]>()))
|
||||
.Callback<string, string[]>((path, contents) => { output = contents; });
|
||||
Dependencies.FileWriter = mock.Object;
|
||||
Dependencies.SetFileWriter(mock.Object);
|
||||
|
||||
cube.ToFile("myFile");
|
||||
|
||||
Assert.AreEqual(Settings.OSCADSharpHeader, output[0]);
|
||||
Assert.AreEqual(OutputSettings.OSCADSharpHeader, output[0]);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
@ -164,7 +166,7 @@ namespace OSCADSharp.UnitTests
|
||||
var mock = new Mock<IFileWriter>();
|
||||
mock.Setup(_wrtr => _wrtr.WriteAllLines(It.IsAny<string>(), It.IsAny<string[]>()))
|
||||
.Callback<string, string[]>((path, contents) => { output = contents; });
|
||||
Dependencies.FileWriter = mock.Object;
|
||||
Dependencies.SetFileWriter(mock.Object);
|
||||
|
||||
cube.ToFile("myFile");
|
||||
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using OSCADSharp.DataBinding;
|
||||
using OSCADSharp.Utility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@ -24,7 +26,7 @@ namespace OSCADSharp.UnitTests.Scripting
|
||||
var compound = new Variable("x", 5) / 12;
|
||||
|
||||
string type = compound.GetType().ToString();
|
||||
Assert.AreEqual("OSCADSharp.Scripting.CompoundVariable", type);
|
||||
Assert.AreEqual("OSCADSharp.DataBinding.Variable+CompoundVariable", type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using OSCADSharp.Files;
|
||||
using OSCADSharp.Scripting;
|
||||
using OSCADSharp.DataBinding;
|
||||
using OSCADSharp.IO;
|
||||
using OSCADSharp.Solids;
|
||||
using OSCADSharp.Utility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@ -23,7 +25,7 @@ namespace OSCADSharp.UnitTests
|
||||
var mock = new Mock<IFileWriter>();
|
||||
mock.Setup(_wrtr => _wrtr.WriteAllLines(It.IsAny<string>(), It.IsAny<string[]>()))
|
||||
.Callback<string, string[]>((path, contents) => { output = contents; });
|
||||
Dependencies.FileWriter = mock.Object;
|
||||
Dependencies.SetFileWriter(mock.Object);
|
||||
|
||||
cube.ToFile("myFile");
|
||||
|
||||
@ -34,14 +36,14 @@ namespace OSCADSharp.UnitTests
|
||||
[ExpectedException(typeof(InvalidOperationException))]
|
||||
public void Settings_NullOpenSCADPathThrowsError()
|
||||
{
|
||||
Settings.OpenSCADPath = null;
|
||||
OutputSettings.OpenSCADPath = null;
|
||||
|
||||
var cube = new Cube();
|
||||
|
||||
var mock = new Mock<IFileWriter>();
|
||||
mock.Setup(_wrtr => _wrtr.WriteAllLines(It.IsAny<string>(), It.IsAny<string[]>()))
|
||||
.Callback<string, string[]>((path, contents) => { });
|
||||
Dependencies.FileWriter = mock.Object;
|
||||
Dependencies.SetFileWriter(mock.Object);
|
||||
|
||||
cube.ToFile("test").Open();
|
||||
}
|
||||
|
||||
@ -2,7 +2,10 @@
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using OSCADSharp.Scripting;
|
||||
using OSCADSharp.Utility;
|
||||
using OSCADSharp.Spatial;
|
||||
using OSCADSharp.DataBinding;
|
||||
using OSCADSharp.Solids;
|
||||
|
||||
namespace OSCADSharp.UnitTests
|
||||
{
|
||||
@ -191,5 +194,15 @@ namespace OSCADSharp.UnitTests
|
||||
Assert.IsTrue(script.Contains("translate(v = [xOffset"));
|
||||
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]"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using OSCADSharp.Scripting;
|
||||
using OSCADSharp.DataBinding;
|
||||
using OSCADSharp.Solids;
|
||||
using OSCADSharp.Spatial;
|
||||
using OSCADSharp.Utility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
using System;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using OSCADSharp.Scripting;
|
||||
using OSCADSharp.Utility;
|
||||
using OSCADSharp.Spatial;
|
||||
using OSCADSharp.DataBinding;
|
||||
using OSCADSharp.Solids;
|
||||
|
||||
namespace OSCADSharp.UnitTests
|
||||
{
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using OSCADSharp.Scripting;
|
||||
using OSCADSharp.DataBinding;
|
||||
using OSCADSharp.Solids;
|
||||
using OSCADSharp.Spatial;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using OSCADSharp.Scripting;
|
||||
using OSCADSharp.DataBinding;
|
||||
using OSCADSharp.Solids;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using OSCADSharp.Solids;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using OSCADSharp.Solids;
|
||||
|
||||
namespace OSCADSharp.UnitTests
|
||||
{
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using OSCADSharp.Scripting;
|
||||
using OSCADSharp.DataBinding;
|
||||
using OSCADSharp.Solids;
|
||||
using OSCADSharp.Spatial;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using OSCADSharp.Scripting;
|
||||
using OSCADSharp.DataBinding;
|
||||
using OSCADSharp.Solids;
|
||||
using OSCADSharp.Spatial;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using OSCADSharp.Scripting;
|
||||
using OSCADSharp.DataBinding;
|
||||
using OSCADSharp.Solids;
|
||||
using OSCADSharp.Spatial;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using OSCADSharp.Scripting;
|
||||
using OSCADSharp.DataBinding;
|
||||
using OSCADSharp.Solids;
|
||||
using OSCADSharp.Spatial;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using OSCADSharp.Scripting;
|
||||
using OSCADSharp.DataBinding;
|
||||
using OSCADSharp.Solids;
|
||||
using OSCADSharp.Spatial;
|
||||
using OSCADSharp.Utility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
8101
OSCADSharp/OSCADSharp.ndproj
Normal file
8101
OSCADSharp/OSCADSharp.ndproj
Normal file
File diff suppressed because it is too large
Load Diff
@ -12,6 +12,7 @@ EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C831DC9A-396A-43F9-AAC6-410A88485356}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
..\LICENSE.txt = ..\LICENSE.txt
|
||||
OSCADSharp\OSCADSharp.nuspec = OSCADSharp\OSCADSharp.nuspec
|
||||
..\README.md = ..\README.md
|
||||
EndProjectSection
|
||||
EndProject
|
||||
|
||||
@ -3,13 +3,12 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using OSCADSharp.Scripting;
|
||||
|
||||
namespace OSCADSharp.Bindings
|
||||
namespace OSCADSharp.DataBinding
|
||||
{
|
||||
internal class BindableBoolean : IBindable
|
||||
{
|
||||
public string InnerValue
|
||||
internal string InnerValue
|
||||
{
|
||||
get;
|
||||
set;
|
||||
@ -32,9 +31,9 @@ namespace OSCADSharp.Bindings
|
||||
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)
|
||||
{
|
||||
this.IsBound = true;
|
||||
@ -42,17 +41,17 @@ namespace OSCADSharp.Bindings
|
||||
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);
|
||||
clone.bindings = this.bindings;
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return this.bindings.Get(this.boundProperty).BoundVariable.Text;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,11 +1,11 @@
|
||||
using System;
|
||||
using OSCADSharp.Spatial;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using OSCADSharp.Scripting;
|
||||
|
||||
namespace OSCADSharp.Bindings
|
||||
namespace OSCADSharp.DataBinding
|
||||
{
|
||||
internal class BindableVector : Vector3, IBindable
|
||||
{
|
||||
@ -16,11 +16,16 @@ namespace OSCADSharp.Bindings
|
||||
{ "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.Y = y;
|
||||
@ -54,7 +59,7 @@ namespace OSCADSharp.Bindings
|
||||
return String.Format("[{0}, {1}, {2}]", x, y, z);
|
||||
}
|
||||
|
||||
public new BindableVector Clone()
|
||||
internal new BindableVector Clone()
|
||||
{
|
||||
var clone = new BindableVector(base.Clone());
|
||||
clone.bindings = this.bindings.Clone();
|
||||
@ -1,11 +1,10 @@
|
||||
using OSCADSharp.Scripting;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OSCADSharp.Bindings
|
||||
namespace OSCADSharp.DataBinding
|
||||
{
|
||||
internal class Binding
|
||||
{
|
||||
@ -1,28 +1,27 @@
|
||||
using OSCADSharp.Scripting;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OSCADSharp.Bindings
|
||||
namespace OSCADSharp.DataBinding
|
||||
{
|
||||
internal class Bindings
|
||||
{
|
||||
#region Fields
|
||||
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>();
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
public Bindings()
|
||||
internal Bindings()
|
||||
{
|
||||
this.propertyNametoOpenSCADFieldMappings = new Dictionary<string, string>();
|
||||
}
|
||||
|
||||
public Bindings(Dictionary<string, string> mappings)
|
||||
internal Bindings(Dictionary<string, string> mappings)
|
||||
{
|
||||
this.propertyNametoOpenSCADFieldMappings = mappings;
|
||||
}
|
||||
@ -1,16 +1,15 @@
|
||||
using OSCADSharp.Scripting;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OSCADSharp
|
||||
namespace OSCADSharp.DataBinding
|
||||
{
|
||||
/// <summary>
|
||||
/// An object whose properties can be bound to variables
|
||||
/// </summary>
|
||||
public interface IBindable
|
||||
internal interface IBindable
|
||||
{
|
||||
/// <summary>
|
||||
/// Binds a variable to property of this object
|
||||
@ -1,11 +1,12 @@
|
||||
using OSCADSharp.Scripting;
|
||||
using OSCADSharp.Spatial;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OSCADSharp
|
||||
namespace OSCADSharp.DataBinding
|
||||
{
|
||||
/// <summary>
|
||||
/// A value for setting object properties in script output to
|
||||
@ -229,5 +230,80 @@ namespace OSCADSharp
|
||||
return applyMixedOperatorRight("/", left, right, VariableCalculator.Divide);
|
||||
}
|
||||
#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
|
||||
}
|
||||
}
|
||||
@ -5,7 +5,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OSCADSharp
|
||||
namespace OSCADSharp.DataBinding
|
||||
{
|
||||
/// <summary>
|
||||
/// A collection of names/values for variables
|
||||
@ -16,8 +16,8 @@ namespace OSCADSharp
|
||||
/// Global variables that can be assigned for output at the
|
||||
/// top of OpenSCAD scripts
|
||||
/// </summary>
|
||||
public static Variables Global = new Variables();
|
||||
private ConcurrentDictionary<string, Variable> variables = new ConcurrentDictionary<string, Variable>();
|
||||
public static Variables Global { get; set; } = new Variables();
|
||||
private readonly ConcurrentDictionary<string, Variable> variables = new ConcurrentDictionary<string, Variable>();
|
||||
|
||||
/// <summary>
|
||||
/// Adds a variable to the collection
|
||||
@ -1,16 +1,17 @@
|
||||
using System;
|
||||
using OSCADSharp.Utility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OSCADSharp.Files
|
||||
namespace OSCADSharp.IO
|
||||
{
|
||||
internal class DefaultFileInvoker : IFileInvoker
|
||||
{
|
||||
private string filePath;
|
||||
public DefaultFileInvoker(string filePath)
|
||||
private readonly string filePath;
|
||||
internal DefaultFileInvoker(string filePath)
|
||||
{
|
||||
this.filePath = filePath;
|
||||
}
|
||||
@ -19,7 +20,7 @@ namespace OSCADSharp.Files
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -31,7 +32,7 @@ namespace OSCADSharp.Files
|
||||
{
|
||||
try
|
||||
{
|
||||
Process.Start(Settings.OpenSCADPath, String.Format("{0}", this.filePath));
|
||||
Process.Start(OutputSettings.OpenSCADPath, String.Format("{0}", this.filePath));
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
@ -5,7 +5,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OSCADSharp.Files
|
||||
namespace OSCADSharp.IO
|
||||
{
|
||||
internal class DefaultFileWriter : IFileWriter
|
||||
{
|
||||
@ -4,7 +4,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OSCADSharp
|
||||
namespace OSCADSharp.IO
|
||||
{
|
||||
/// <summary>
|
||||
/// Invokes OpenSCAD actions on output files
|
||||
@ -4,7 +4,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OSCADSharp
|
||||
namespace OSCADSharp.IO
|
||||
{
|
||||
/// <summary>
|
||||
/// A class that takes text and writes to file
|
||||
52
OSCADSharp/OSCADSharp/IO/OutputSettings.cs
Normal file
52
OSCADSharp/OSCADSharp/IO/OutputSettings.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
167
OSCADSharp/OSCADSharp/OSCADObject.AbstractTransforms.cs
Normal file
167
OSCADSharp/OSCADSharp/OSCADObject.AbstractTransforms.cs
Normal 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
|
||||
}
|
||||
}
|
||||
128
OSCADSharp/OSCADSharp/OSCADObject.BaseTransform.cs
Normal file
128
OSCADSharp/OSCADSharp/OSCADObject.BaseTransform.cs
Normal 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
|
||||
}
|
||||
}
|
||||
453
OSCADSharp/OSCADSharp/OSCADObject.BasicTransforms.cs
Normal file
453
OSCADSharp/OSCADSharp/OSCADObject.BasicTransforms.cs
Normal 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
|
||||
}
|
||||
}
|
||||
80
OSCADSharp/OSCADSharp/OSCADObject.Booleans.cs
Normal file
80
OSCADSharp/OSCADSharp/OSCADObject.Booleans.cs
Normal 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
|
||||
}
|
||||
}
|
||||
@ -1,9 +1,7 @@
|
||||
using OSCADSharp.Bindings;
|
||||
using OSCADSharp.Booleans;
|
||||
using OSCADSharp.Files;
|
||||
using OSCADSharp.Scripting;
|
||||
using OSCADSharp.DataBinding;
|
||||
using OSCADSharp.IO;
|
||||
using OSCADSharp.Spatial;
|
||||
using OSCADSharp.Transforms;
|
||||
using OSCADSharp.Utility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
@ -11,22 +9,24 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
[assembly: CLSCompliant(true)]
|
||||
|
||||
namespace OSCADSharp
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents any Object or collection of objects that becomes am
|
||||
/// an OpenSCAD script when converted to a string.
|
||||
/// </summary>
|
||||
public abstract class OSCADObject : IBindable
|
||||
public abstract partial class OSCADObject : IBindable
|
||||
{
|
||||
#region Attributes
|
||||
private uint id = Ids.Get();
|
||||
private readonly int id = Ids.Get();
|
||||
|
||||
/// <summary>
|
||||
/// The unique Id of the object
|
||||
/// these values auto-increment
|
||||
/// </summary>
|
||||
public uint Id { get { return this.id; } }
|
||||
public int Id { get { return this.id; } }
|
||||
|
||||
/// <summary>
|
||||
/// Name of this OSCADObject
|
||||
@ -685,7 +685,7 @@ namespace OSCADSharp
|
||||
/// <returns></returns>
|
||||
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>
|
||||
@ -696,7 +696,7 @@ namespace OSCADSharp
|
||||
/// <returns></returns>
|
||||
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>
|
||||
@ -708,7 +708,7 @@ namespace OSCADSharp
|
||||
/// <returns></returns>
|
||||
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)
|
||||
@ -781,7 +781,7 @@ namespace OSCADSharp
|
||||
/// <summary>
|
||||
/// Internal collection of children for this object
|
||||
/// </summary>
|
||||
protected List<OSCADObject> children = new List<OSCADObject>();
|
||||
protected List<OSCADObject> m_children { get; set; } = new List<OSCADObject>();
|
||||
|
||||
/// <summary>
|
||||
/// Returns all chidren of this OSCADObject
|
||||
@ -792,12 +792,12 @@ namespace OSCADSharp
|
||||
{
|
||||
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)
|
||||
// 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>();
|
||||
OSCADObject child = null;
|
||||
|
||||
@ -806,7 +806,7 @@ namespace OSCADSharp
|
||||
child = toTraverse.Pop();
|
||||
allChildren.Add(child);
|
||||
|
||||
foreach (var subChild in child.children)
|
||||
foreach (var subChild in child.m_children)
|
||||
{
|
||||
toTraverse.Push(subChild);
|
||||
}
|
||||
@ -842,7 +842,7 @@ namespace OSCADSharp
|
||||
|
||||
Dependencies.FileWriter.WriteAllLines(path, new string[]
|
||||
{
|
||||
Settings.OSCADSharpHeader,
|
||||
OutputSettings.OSCADSharpHeader,
|
||||
Variables.Global.ToString(),
|
||||
this.ToString()
|
||||
});
|
||||
@ -868,19 +868,19 @@ namespace OSCADSharp
|
||||
/// <returns></returns>
|
||||
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;
|
||||
}
|
||||
else if(right.GetType() == typeof(Union))
|
||||
else if(right.GetType() == typeof(UnionedObject))
|
||||
{
|
||||
right.children.Add(left);
|
||||
right.m_children.Add(left);
|
||||
return right;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new Union(new OSCADObject[] {left, right });
|
||||
return new UnionedObject(new OSCADObject[] {left, right });
|
||||
}
|
||||
}
|
||||
|
||||
@ -892,19 +892,19 @@ namespace OSCADSharp
|
||||
/// <returns></returns>
|
||||
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;
|
||||
}
|
||||
else if (right.GetType() == typeof(Difference))
|
||||
else if (right.GetType() == typeof(DifferencedObject))
|
||||
{
|
||||
right.children.Add(left);
|
||||
right.m_children.Add(left);
|
||||
return right;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new Difference(new OSCADObject[] {left, right });
|
||||
return new DifferencedObject(new OSCADObject[] {left, right });
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
@ -42,53 +42,38 @@
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Internal\Bindings\BindableBoolean.cs" />
|
||||
<Compile Include="Internal\Scripting\VariableCalculator.cs" />
|
||||
<Compile Include="Internal\Scripting\CompoundVariable.cs" />
|
||||
<Compile Include="Public\Settings\Dependencies.cs" />
|
||||
<Compile Include="Internal\Files\DefaultFileInvoker.cs" />
|
||||
<Compile Include="Internal\Files\DefaultFileWriter.cs" />
|
||||
<Compile Include="Public\Files\IFileInvoker.cs" />
|
||||
<Compile Include="Public\Files\IFileWriter.cs" />
|
||||
<Compile Include="Internal\Settings\Ids.cs" />
|
||||
<Compile Include="Internal\Settings\OpenSCADPathFinder.cs" />
|
||||
<Compile Include="Internal\Bindings\Binding.cs" />
|
||||
<Compile Include="Internal\Bindings\Bindings.cs" />
|
||||
<Compile Include="Internal\Bindings\IBindable.cs" />
|
||||
<Compile Include="Internal\Scripting\SingleStatementObject.cs" />
|
||||
<Compile Include="Internal\Scripting\StatementBuilder.cs" />
|
||||
<Compile Include="Public\Scripting\Variable.cs" />
|
||||
<Compile Include="Public\Settings\Settings.cs" />
|
||||
<Compile Include="Public\Inches.cs" />
|
||||
<Compile Include="Internal\Bindings\BindableVector.cs" />
|
||||
<Compile Include="Public\Spatial\Bounds.cs" />
|
||||
<Compile Include="Internal\Spatial\Matrix.cs" />
|
||||
<Compile Include="Internal\Transforms\HulledObject.cs" />
|
||||
<Compile Include="Internal\Transforms\LinearExtrudedObject.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="DataBinding\BindableBoolean.cs" />
|
||||
<Compile Include="OSCADObject.AbstractTransforms.cs" />
|
||||
<Compile Include="OSCADObject.BaseTransform.cs" />
|
||||
<Compile Include="OSCADObject.BasicTransforms.cs" />
|
||||
<Compile Include="OSCADObject.Booleans.cs" />
|
||||
<Compile Include="Utility\Dependencies.cs" />
|
||||
<Compile Include="IO\DefaultFileInvoker.cs" />
|
||||
<Compile Include="IO\DefaultFileWriter.cs" />
|
||||
<Compile Include="IO\IFileInvoker.cs" />
|
||||
<Compile Include="IO\IFileWriter.cs" />
|
||||
<Compile Include="Utility\Ids.cs" />
|
||||
<Compile Include="DataBinding\Binding.cs" />
|
||||
<Compile Include="DataBinding\Bindings.cs" />
|
||||
<Compile Include="DataBinding\IBindable.cs" />
|
||||
<Compile Include="Utility\StatementBuilder.cs" />
|
||||
<Compile Include="DataBinding\Variable.cs" />
|
||||
<Compile Include="IO\OutputSettings.cs" />
|
||||
<Compile Include="Utility\Inches.cs" />
|
||||
<Compile Include="DataBinding\BindableVector.cs" />
|
||||
<Compile Include="Spatial\Bounds.cs" />
|
||||
<Compile Include="Spatial\Matrix.cs" />
|
||||
<Compile Include="Utility\SingleBlockFormatter.cs" />
|
||||
<Compile Include="OSCADObject.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Public\Solids\Cube.cs" />
|
||||
<Compile Include="Public\Solids\Cylinder.cs" />
|
||||
<Compile Include="Public\Solids\Sphere.cs" />
|
||||
<Compile Include="Public\Solids\Text3D.cs" />
|
||||
<Compile Include="Internal\Transforms\ColoredObject.cs" />
|
||||
<Compile Include="Internal\Transforms\MinkowskiedObject.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" />
|
||||
<Compile Include="Solids\Cube.cs" />
|
||||
<Compile Include="Solids\Cylinder.cs" />
|
||||
<Compile Include="Solids\Sphere.cs" />
|
||||
<Compile Include="Solids\Text3D.cs" />
|
||||
<Compile Include="Spatial\Vector3.cs" />
|
||||
<Compile Include="DataBinding\Variables.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- 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.
|
||||
|
||||
@ -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); };
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
@ -1,13 +1,12 @@
|
||||
using System;
|
||||
using OSCADSharp.DataBinding;
|
||||
using OSCADSharp.Spatial;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using OSCADSharp.Spatial;
|
||||
using OSCADSharp.Bindings;
|
||||
using OSCADSharp.Scripting;
|
||||
|
||||
namespace OSCADSharp
|
||||
namespace OSCADSharp.Solids
|
||||
{
|
||||
/// <summary>
|
||||
/// A Cube geometry
|
||||
@ -103,8 +102,8 @@ namespace OSCADSharp
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("cube(size = {0}, center = {1}); {2}",
|
||||
this.Size.ToString(),
|
||||
this.centerBinding.IsBound ? this.centerBinding.ToString() : this.center.ToString().ToLower(),
|
||||
this.Size.ToString(),
|
||||
this.centerBinding.IsBound ? this.centerBinding.ToString() : this.center.ToString().ToLower(),
|
||||
Environment.NewLine); ;
|
||||
}
|
||||
|
||||
@ -137,7 +136,7 @@ namespace OSCADSharp
|
||||
public override 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);
|
||||
}
|
||||
@ -155,18 +154,18 @@ namespace OSCADSharp
|
||||
/// <returns></returns>
|
||||
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));
|
||||
}
|
||||
else
|
||||
{
|
||||
return new Bounds(new Vector3(-this.Size.X / 2, -this.Size.Y / 2, -this.Size.Z / 2),
|
||||
return new Bounds(new Vector3(-this.Size.X / 2, -this.Size.Y / 2, -this.Size.Z / 2),
|
||||
new Vector3(this.Size.X / 2, this.Size.Y / 2, this.Size.Z / 2));
|
||||
}
|
||||
}
|
||||
|
||||
private Bindings.Bindings bindings = new Bindings.Bindings();
|
||||
private Bindings bindings = new Bindings();
|
||||
private static readonly Dictionary<string, string> sizeSynonyms = new Dictionary<string, string>()
|
||||
{
|
||||
{"size.x", "x" },
|
||||
@ -195,7 +194,7 @@ namespace OSCADSharp
|
||||
|
||||
vec.Bind(property, variable);
|
||||
}
|
||||
else if(property.ToLower() == "center")
|
||||
else if (property.ToLower() == "center")
|
||||
{
|
||||
this.centerBinding.Bind(property, variable);
|
||||
this.center = Convert.ToBoolean(variable.Value);
|
||||
@ -1,13 +1,13 @@
|
||||
using System;
|
||||
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;
|
||||
using OSCADSharp.Spatial;
|
||||
using OSCADSharp.Scripting;
|
||||
using OSCADSharp.Bindings;
|
||||
|
||||
namespace OSCADSharp
|
||||
namespace OSCADSharp.Solids
|
||||
{
|
||||
/// <summary>
|
||||
/// 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" },
|
||||
{"radius1", "r1" },
|
||||
@ -3,13 +3,13 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using OSCADSharp.Spatial;
|
||||
using OSCADSharp.Scripting;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Reflection;
|
||||
using OSCADSharp.Bindings;
|
||||
using OSCADSharp.Spatial;
|
||||
using OSCADSharp.DataBinding;
|
||||
using OSCADSharp.Utility;
|
||||
|
||||
namespace OSCADSharp
|
||||
namespace OSCADSharp.Solids
|
||||
{
|
||||
/// <summary>
|
||||
/// A Sphere geometry
|
||||
@ -25,11 +25,12 @@ namespace OSCADSharp
|
||||
/// <summary>
|
||||
/// This is the diameter of the sphere
|
||||
/// </summary>
|
||||
public double Diameter {
|
||||
public double Diameter
|
||||
{
|
||||
get { return this.Radius * 2; }
|
||||
set { this.Radius = value / 2; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Minimum angle (in degrees) of each cylinder fragment.
|
||||
/// ($fa in OpenSCAD)
|
||||
@ -143,11 +144,11 @@ namespace OSCADSharp
|
||||
/// <returns></returns>
|
||||
public override Bounds Bounds()
|
||||
{
|
||||
return new Bounds(new Vector3(-this.Radius, -this.Radius, -this.Radius),
|
||||
return new Bounds(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" },
|
||||
{ "minimumangle", "$fa" },
|
||||
@ -1,13 +1,13 @@
|
||||
using OSCADSharp.Scripting;
|
||||
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;
|
||||
using OSCADSharp.Spatial;
|
||||
using OSCADSharp.Bindings;
|
||||
|
||||
namespace OSCADSharp
|
||||
namespace OSCADSharp.Solids
|
||||
{
|
||||
/// <summary>
|
||||
/// 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");
|
||||
}
|
||||
|
||||
private Bindings.Bindings bindings = new Bindings.Bindings(new Dictionary<string, string>()
|
||||
private Bindings bindings = new Bindings(new Dictionary<string, string>()
|
||||
{
|
||||
{ "text", "text" },
|
||||
{ "size", "size" },
|
||||
@ -1,10 +1,11 @@
|
||||
using System;
|
||||
using OSCADSharp.Spatial;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OSCADSharp
|
||||
namespace OSCADSharp.Spatial
|
||||
{
|
||||
/// <summary>
|
||||
/// A set of boundaries
|
||||
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using OSCADSharp.Spatial;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@ -13,7 +14,7 @@ namespace OSCADSharp.Spatial
|
||||
internal class Matrix
|
||||
{
|
||||
#region Fields/Properties
|
||||
private double[] values;
|
||||
private readonly double[] values;
|
||||
|
||||
internal int ColumnCount { get; private set; }
|
||||
internal int RowCount { get; private set; }
|
||||
@ -78,13 +79,14 @@ namespace OSCADSharp.Spatial
|
||||
return piOver180 * degrees;
|
||||
}
|
||||
|
||||
private static readonly Matrix identity = new Matrix(new double[] {
|
||||
1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
0, 0, 0, 1
|
||||
}, 4, 4);
|
||||
internal static Matrix Identity { get { return identity; } }
|
||||
internal static Matrix Identity()
|
||||
{
|
||||
return new Matrix(new double[] {
|
||||
1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
0, 0, 0, 1}, 4, 4); ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a transformation matrix for performing rotations on the X-Axis
|
||||
@ -95,7 +97,7 @@ namespace OSCADSharp.Spatial
|
||||
internal static Matrix XRotation(double angle)
|
||||
{
|
||||
if (angle == 0)
|
||||
return Identity;
|
||||
return Identity();
|
||||
|
||||
double radAngle = toRadians(angle);
|
||||
double[] rotationArr = new double[] {
|
||||
@ -117,7 +119,7 @@ namespace OSCADSharp.Spatial
|
||||
internal static Matrix YRotation(double angle)
|
||||
{
|
||||
if (angle == 0)
|
||||
return Identity;
|
||||
return Identity();
|
||||
|
||||
double radAngle = toRadians(angle);
|
||||
double[] rotationArr = new double[] {
|
||||
@ -139,7 +141,7 @@ namespace OSCADSharp.Spatial
|
||||
internal static Matrix ZRotation(double angle)
|
||||
{
|
||||
if (angle == 0)
|
||||
return Identity;
|
||||
return Identity();
|
||||
|
||||
double radAngle = toRadians(angle);
|
||||
double[] rotationArr = new double[] {
|
||||
@ -1,11 +1,10 @@
|
||||
using OSCADSharp.Spatial;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OSCADSharp
|
||||
namespace OSCADSharp.Spatial
|
||||
{
|
||||
/// <summary>
|
||||
/// A Three-Dimensional vector
|
||||
45
OSCADSharp/OSCADSharp/Utility/Dependencies.cs
Normal file
45
OSCADSharp/OSCADSharp/Utility/Dependencies.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4,21 +4,21 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OSCADSharp
|
||||
namespace OSCADSharp.Utility
|
||||
{
|
||||
/// <summary>
|
||||
/// Responsible for creating identifiers for objects
|
||||
/// </summary>
|
||||
internal static class Ids
|
||||
{
|
||||
private static uint globalId = 0;
|
||||
private static object idLockObject = new object();
|
||||
private static int globalId = 0;
|
||||
private readonly static object idLockObject = new object();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a unique auto-incrementing integer id
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal static uint Get()
|
||||
internal static int Get()
|
||||
{
|
||||
lock (idLockObject)
|
||||
{
|
||||
@ -4,37 +4,37 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OSCADSharp
|
||||
namespace OSCADSharp.Utility
|
||||
{
|
||||
/// <summary>
|
||||
/// Constants and conversions for units for us imperial-minded folks.
|
||||
/// </summary>
|
||||
public class Inches
|
||||
public static class Inches
|
||||
{
|
||||
/// <summary>
|
||||
/// One imperial inch
|
||||
/// </summary>
|
||||
public const double One = 25.4;
|
||||
public static double One { get; private set; } = 25.4;
|
||||
|
||||
/// <summary>
|
||||
/// Half of an imperial inch
|
||||
/// </summary>
|
||||
public const double Half = One / 2;
|
||||
public static double Half { get; private set; } = One / 2;
|
||||
|
||||
/// <summary>
|
||||
/// Quarter of an imperial inch
|
||||
/// </summary>
|
||||
public const double Quarter = Half / 2;
|
||||
public static double Quarter { get; private set; } = Half / 2;
|
||||
|
||||
/// <summary>
|
||||
/// Eigth of an imperial inch
|
||||
/// </summary>
|
||||
public const double Eigth = Quarter / 2;
|
||||
public static double Eigth { get; private set; } = Quarter / 2;
|
||||
|
||||
/// <summary>
|
||||
/// Sixteenth of an imperial inch
|
||||
/// </summary>
|
||||
public const double Sixteenth = Eigth / 2;
|
||||
public static double Sixteenth { get; private set; } = Eigth / 2;
|
||||
|
||||
/// <summary>
|
||||
/// Converts inches to millimeters
|
||||
@ -5,7 +5,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OSCADSharp.Scripting
|
||||
namespace OSCADSharp.Utility
|
||||
{
|
||||
/// <summary>
|
||||
/// A class that creates blocks of curly-braced script with the
|
||||
@ -13,9 +13,9 @@ namespace OSCADSharp.Scripting
|
||||
/// </summary>
|
||||
internal class SingleBlockFormatter
|
||||
{
|
||||
private string outerCode;
|
||||
private string innerCode;
|
||||
private string indentationAmount = " ";
|
||||
private readonly string outerCode;
|
||||
private readonly string innerCode;
|
||||
private readonly string indentationAmount = " ";
|
||||
|
||||
internal SingleBlockFormatter(string outerCode, string innerCode)
|
||||
{
|
||||
@ -1,10 +1,11 @@
|
||||
using System;
|
||||
using OSCADSharp.DataBinding;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OSCADSharp.Scripting
|
||||
namespace OSCADSharp.Utility
|
||||
{
|
||||
/// <summary>
|
||||
/// Extends the capabilities of StringBuilder with domain-specific behavior
|
||||
@ -13,25 +14,20 @@ namespace OSCADSharp.Scripting
|
||||
internal class StatementBuilder
|
||||
{
|
||||
private StringBuilder SB { get; set; } = new StringBuilder();
|
||||
private Bindings.Bindings bindings = null;
|
||||
|
||||
internal StatementBuilder()
|
||||
{
|
||||
}
|
||||
|
||||
internal StatementBuilder(Bindings.Bindings bindings)
|
||||
private readonly Bindings bindings = null;
|
||||
|
||||
internal StatementBuilder(Bindings bindings)
|
||||
{
|
||||
this.bindings = bindings;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Special append method for conditionally adding value-pairs
|
||||
/// </summary>
|
||||
/// <param name="name">The Name of the value-pair</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>
|
||||
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);
|
||||
|
||||
@ -45,7 +41,7 @@ namespace OSCADSharp.Scripting
|
||||
SB.Append(name);
|
||||
SB.Append(" = ");
|
||||
|
||||
if(useBinding)
|
||||
if (useBinding)
|
||||
{
|
||||
SB.Append(this.bindings.Get(name).BoundVariable.Text);
|
||||
}
|
||||
@ -65,20 +61,11 @@ namespace OSCADSharp.Scripting
|
||||
/// Pass-through for StringBuilder.Append
|
||||
/// </summary>
|
||||
/// <param name="text"></param>
|
||||
public void Append(string text)
|
||||
internal void Append(string text)
|
||||
{
|
||||
SB.Append(text);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pass-through for StringBuilder.AppendLine
|
||||
/// </summary>
|
||||
/// <param name="text"></param>
|
||||
public void AppendLine(string text)
|
||||
{
|
||||
SB.AppendLine(text);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets this builder's full string
|
||||
/// </summary>
|
||||
Loading…
x
Reference in New Issue
Block a user