Removed all support for bindings **Massive shift in direction**. They have been removed to clear the path for supporting more robust time-saving functionality, such as compound objects like premade containers and better support for 2d-to-3d image scanning support (bindings are much more difficult to support for the advanced features). Bindings may be added back in if an eventual advanced post-processing system is implemented along with a more structured syntax for file creation (or translation to another language).

This commit is contained in:
Michael Smith 2016-10-27 21:32:58 -07:00
parent df7096f614
commit 3697647e4a
37 changed files with 447 additions and 2578 deletions

View File

@ -1,6 +1,5 @@

using OSCADSharp.DataBinding;
using OSCADSharp.Solids;
using OSCADSharp.Solids;
using OSCADSharp.Solids.Compound;
using OSCADSharp.Solids.Imported;
using OSCADSharp.Spatial;
using OSCADSharp.Utility;
@ -38,13 +37,11 @@ namespace OSCADSharp.ConsoleTests
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);
OSCADObject flatInnerPortion = new Cylinder(Inches.Quarter, Inches.Eigth, true) { Resolution = 30 };
OSCADObject shaft = new Cylinder(Inches.Eigth, Inches.Half, true) { Resolution = 30 };
flatInnerPortion = flatInnerPortion.Translate(0, 0, shaft.Bounds().ZMax);
OSCADObject pegShaft = new Cylinder(Inches.Quarter, Inches.Half - Inches.Eigth, true)
OSCADObject pegShaft = new Cylinder(Inches.Quarter, Inches.Half - Inches.Eigth, true) { Resolution = 30 }
.Translate(0, 0, -Inches.Eigth);
OSCADObject bottomBall = new Sphere(Inches.Quarter* 1.1)
.Translate(0, 0, pegShaft.Bounds().ZMin);
@ -55,17 +52,372 @@ namespace OSCADSharp.ConsoleTests
obj.ToFile("peg");
}
private static void makeLaserStand()
{
OSCADObject center = new Cube(Inches.One, Inches.Half, Inches.One*1.2, true);
OSCADObject outerColumn = new Cylinder(Inches.One, Inches.One, true).Resize(Inches.One * 1.5, Inches.Half * 1.5, Inches.One);
var bnds = outerColumn.Bounds();
OSCADObject bottom = new Cylinder(Inches.One, Inches.One, true)
.Resize(Inches.One * 2, Inches.Half * 2, Inches.One)
.Translate(0, 0, 0);
var obj = (outerColumn) + bottom;
bnds = obj.Bounds();
var cap = makeStandCap();
obj = obj + cap.Translate(0, 0, bnds.ZMax - Inches.Sixteenth);
obj.ToFile("laserStand2").Open();
}
private static OSCADObject makeStandCap()
{
OSCADObject center = new Cube(Inches.One - Inches.Sixteenth, Inches.Half - Inches.Sixteenth, Inches.Quarter, true);
OSCADObject outerColumn = new Cylinder(Inches.One, Inches.One, true).Resize(Inches.One * 1.5, Inches.Half * 1.5, Inches.One);
var bnds = center.Bounds();
OSCADObject top = new Cylinder(Inches.One, Inches.One, true)
.Resize(Inches.One * 2.25, Inches.Half * 2.25, Inches.Quarter);
OSCADObject cutout = new Cylinder(Inches.One, Inches.One, true)
.Resize(Inches.One * 2.1, Inches.Half * 2.1, Inches.Quarter);
top = top - cutout.Translate(0, 0, Inches.Quarter/2);
OSCADObject brim = top.Clone();
var obj = center + top.Translate(0, 0, bnds.Height / 2 + Inches.Sixteenth / 2);
return obj;
}
private static void makeCardClip()
{
var leftSide = new Cube(Inches.Sixteenth, Inches.Half, Inches.Half, true)
.Rotate(0, -3, 0).Translate(Inches.Sixteenth, 0, Inches.Half / 2);
var rightSide = leftSide.Clone().Mirror(1, 0, 0);
var bottom = new Cube(Inches.Quarter*.85, Inches.Half, Inches.Sixteenth, true);
var obj = leftSide + rightSide + bottom;
//obj = new Sphere() { Radius = .25, Resolution = 30 }.Translate(0, 0, -1).Minkowski(obj);
//90 degree joint
obj = obj.Translate(0, 0, Inches.Eigth) +
obj.Clone().Rotate(0, 180, 0).Translate(0, 0, 0)
+ new Cube(Inches.Quarter * .85, Inches.Half, Inches.Quarter * .85, true);
obj = obj.Rotate(90, 0, 0);
obj.ToFile("clip-180");
}
public static void makeBadge()
{
var img = ImportedImage.FromFile("badge-1.png", new ImageImportOptions()
{
HeightMapping = ImageImportOptions.HeightMappingMode.Vertical
});
img.Resize(Inches.One * 2.4, Inches.One * 2.75, Inches.Eigth).ToFile("badge");
}
public static void makeLoop()
{
double outerDiam = Inches.Quarter+ Inches.Sixteenth;
double height = Inches.Eigth + Inches.Sixteenth;
double holeSize = Inches.Quarter;
double paddingSize = Inches.Sixteenth;
var outer = new Cylinder(holeSize + paddingSize, height, true) { Resolution = 50 };
var inner = new Cylinder(holeSize, height*2, true) { Resolution = 50 };
var bounds = outer.Bounds();
var bottomDisk = new Cylinder(outerDiam + Inches.Eigth, Inches.Sixteenth / 2, true) { Resolution = 50 }.Translate(0, 0, bounds.ZMin - Inches.Sixteenth / 4);
var whole = ((outer + bottomDisk) - inner);
whole.ToFile("loop");
var topDisk = new Cylinder(outerDiam + Inches.Eigth, Inches.Sixteenth / 2, true) - new Cylinder(holeSize + Inches.Sixteenth, Inches.Half, true) { Resolution = 50 };
topDisk.ToFile("topLoop");
}
public static void makeHolder()
{
double innerSize = (Inches.One * 4);
var cutout = new Cube(Inches.One * 10, Inches.Half, Inches.Half, true).Translate(0, innerSize/2, 0);
cutout = cutout + cutout.Rotate(0, 0, 90) + cutout.Rotate(0, 0, 180) + cutout.Rotate(0, 0, 270);
OSCADObject innerCyl = new Cylinder(innerSize, Inches.Eigth + Inches.Sixteenth, true) {
Resolution = 60
};
var outerCyl = new Cylinder(innerSize + Inches.Eigth, Inches.Quarter + Inches.Sixteenth, true) {
Resolution = 60
};
innerCyl = innerCyl.Translate(0, 0, outerCyl.Bounds().ZMax - (Inches.Eigth + Inches.Sixteenth)/2 + .1);
var whole = (outerCyl - innerCyl) - cutout;
whole.ToFile("coasterHolder-square").Open();
}
public static void makeDisk()
{
double glassGap = Inches.Eigth;
double outer = (Inches.One * 3) + glassGap*2;
double holeSize = (Inches.One - Inches.Sixteenth);
double thickness = Inches.Quarter;
var outerCylinder = new Cylinder(outer, thickness, true) { Resolution = 100 };
var innerCutout = new Cylinder(outer - glassGap, thickness, true) { Resolution = 100 }.Translate(0, 0, thickness - Inches.Sixteenth);
var hole = new Cylinder(holeSize, thickness * 2, true) { Resolution = 100 };
var whole = (outerCylinder - innerCutout) - hole;
whole.ToFile("candleDisk").Open();
}
public static void makePaddle()
{
double holeSize = Inches.One + Inches.Eigth;
double holeHeight = Inches.One;
double shaftSize = holeSize + Inches.Quarter;
double totalLength = Inches.One * 8;
double totalWidth = Inches.One * 5;
var blade = new Sphere() { Resolution = 80 }.Resize(totalLength, totalWidth, Inches.One*2);
var copy = blade.Clone().Translate(0, 0, -Inches.One).Scale(1.4, 1.4, 1.1);
blade = blade - copy;
//var gap = new Cube(Inches.One, Inches.One * 8, Inches.One*8, true).Translate(blade.Bounds().XMin, 0, 0);
//blade = blade - gap;
OSCADObject shaft = new Cylinder(shaftSize, totalLength / 4, true) { Resolution = 80 }.Rotate(0, 90, 0);
var hole = new Cylinder(holeSize, holeHeight * 2, true) { Resolution = 80 }.Rotate(0, 90, 0).Translate(shaft.Bounds().XMin, 0, 0);
blade = blade - hole.Translate(blade.Bounds().XMin + Inches.Half, 0, +Inches.Quarter);
shaft = shaft - hole;
shaft = shaft.Translate(blade.Bounds().XMin + Inches.Half, 0, +Inches.Quarter);
var gapCloser = new Sphere(shaftSize) { Resolution = 80 }.Translate(shaft.Bounds().XMax, 0, +Inches.Quarter);
var whole = (blade + shaft + gapCloser).Rotate(180, 0, 0);
whole.ToFile("paddle").Open();
}
public static void makepaddleHandle()
{
double holeSize = Inches.One + Inches.Eigth;
double holeHeight = Inches.One;
double shaftSize = holeSize + Inches.Quarter;
double totalLength = Inches.One * 8;
double totalWidth = Inches.One * 5;
var blade = new Sphere() { Resolution = 80 }.Resize(totalLength, totalWidth, Inches.One * 2);
var copy = blade.Clone().Translate(0, 0, -Inches.One).Scale(1.4, 1.4, 1.1);
blade = blade - copy;
//var gap = new Cube(Inches.One, Inches.One * 8, Inches.One*8, true).Translate(blade.Bounds().XMin, 0, 0);
//blade = blade - gap;
OSCADObject shaft = new Cylinder(shaftSize, totalLength / 4, true) { Resolution = 80 }.Rotate(0, 90, 0);
var hole = new Cylinder(holeSize, holeHeight * 2, true) { Resolution = 80 }.Rotate(0, 90, 0).Translate(shaft.Bounds().XMin, 0, 0);
blade = blade - hole.Translate(blade.Bounds().XMin + Inches.Half, 0, +Inches.Quarter);
shaft = shaft - hole;
shaft = shaft.Translate(blade.Bounds().XMin + Inches.Half, 0, +Inches.Quarter);
var top = new Cylinder(shaftSize, Inches.One * 3, true) { Resolution = 80 }.Rotate(90, 0, 0).Translate(shaft.Bounds().XMax, 0, shaft.Bounds().ZMax - shaftSize/2);
var gapCloserLeft = new Sphere(shaftSize) { Resolution = 80 }.Translate(top.Bounds().XMax - shaftSize/2, top.Bounds().YMax, +Inches.Quarter);
var gapCloserRight = gapCloserLeft.Mirror(0, 1, 0);
var whole = shaft + top + gapCloserLeft + gapCloserRight;
whole.ToFile("paddleHandle").Open();
}
public static void makeGreatSword()
{
double referenceWidth = Inches.Eigth;
double overallLength = Inches.One*1.5;
var tang = new Cylinder(referenceWidth, overallLength, true) { Resolution = 6 }.Scale(.5, 2, 1);
var pommel = new Sphere(referenceWidth * 1.2){ Resolution = 11 }.Translate(0, 0, -Inches.Half - Inches.Eigth).Color("Gold");
var hilt = new Cylinder(referenceWidth, Inches.Half * .75, true) { Resolution = 10 }
.Rotate(90, 0, 0)
.Translate(0, 0, -Inches.Quarter).Color("Gold");
var hiltRight = new Sphere(referenceWidth * 1.1) { Resolution = 8 }
.Scale(1, 1, 1.2).Color("Gold")
.Translate(0, hilt.Bounds().YMin, hilt.Position().Z);
var hiltLeft = hiltRight.Clone().Mirror(0, 1, 0);
var hiltCenter = new Cylinder(referenceWidth * .9, Inches.Half * .8, true) { Resolution = 8 }
.Translate(0, 0, -Inches.Quarter - Inches.Quarter*.75).Color("Gold");
hilt = hilt + hiltLeft + hiltRight + hiltCenter;
var blade = tang.Translate(0, 0, Inches.Half);
var tip = new Cylinder(referenceWidth, Inches.Quarter, true) { Resolution = 6, Diameter2 = .1 }.Scale(.5, 2, 1).Translate(0, 0, blade.Bounds().ZMax + Inches.Eigth);
blade = blade + tip;
blade = blade.Color("Silver");
var whole = (blade + pommel + hilt).Scale(.5, .5, .5);
whole.ToFile("greatsword").Open();
}
public static void makeACBrackets()
{
double width = Inches.One * 6.5;
double height = Inches.One;
double depth = Inches.One;
double thickness = Inches.Quarter;
var mainBox = new Cube(width, depth, height, true);
var cutout = mainBox.Clone().Scale(1.1, 1, 1).Translate(0, thickness, thickness);
var hole = new Cylinder(Inches.Eigth, Inches.One * 2, true) { Resolution = 30 }.Rotate(90, 0, 0);
var whole = mainBox - cutout - hole.Translate(0, 0, Inches.Quarter) -
hole.Clone().Translate(-Inches.One * 2, 0, Inches.Quarter) - hole.Clone().Translate(+Inches.One * 2, 0, Inches.Quarter);
whole.ToFile("acBracket");
}
public static void makeDiceHolder()
{
double chamberDiameter = Inches.One;
var singleChamberCenter = new Cylinder(chamberDiameter, Inches.Half + Inches.Eigth, true) { Resolution = 6 };
var singleChamber = new Cylinder(chamberDiameter + Inches.Eigth, Inches.Half + Inches.Eigth, true) { Resolution = 6 } - singleChamberCenter.Scale(1, 1, 2);
singleChamber = singleChamber.Rotate(0, 0, 30);
var bottom = singleChamber;
for (int angle = 60; angle < 420; angle+=60)
{
bottom += singleChamber.Clone().Translate(chamberDiameter - Inches.Sixteenth, 0, 0).Rotate(0, 0, angle);
}
var hexSection = bottom.Clone();
var outerCylCenter = new Cylinder(chamberDiameter * 2.9, Inches.Half, true) { Resolution = 90 }.Translate(0, 0, Inches.Eigth);
var outerCyl = (new Cylinder(chamberDiameter * 2.9 + Inches.Eigth, Inches.Half, true) { Resolution = 90 } - outerCylCenter).Translate(0, 0, bottom.Bounds().ZMin + Inches.Half);
bottom += outerCyl;
var lidCenter = new Cylinder(chamberDiameter * 2.9 + Inches.Eigth + Inches.Sixteenth*.5, Inches.One, true) { Resolution = 90 }.Translate(0, 0, Inches.Eigth);
var lid = (new Cylinder(chamberDiameter * 2.9 + Inches.Quarter + Inches.Sixteenth * .5, Inches.One, true) { Resolution = 90 } - lidCenter).Translate(0, 0, bottom.Bounds().ZMin + Inches.Half);
var top = lid.Clone().Mirror(0, 0, 1).Rotate(0, 180, 0);
//OSCADObject dragon = ImportedImage.FromFile("dragonInsignia.png", new ImageImportOptions() {
// UseGrayScale = true,
// HeightMapping = ImageImportOptions.HeightMappingMode.None,
// SimplificationAmount = 100
//});
//var topBounds = top.Bounds();
//dragon = dragon.Scale(.1, .1, Inches.Quarter).Translate(-topBounds.Length/2 + Inches.Sixteenth, -topBounds.Width/2 + Inches.Sixteenth, topBounds.ZMin - Inches.Eigth);
var whole = top;//bottom;// /*bottom + */ top - dragon;
whole.ToFile("diceHolder_cap").Open();
}
public static void makeSideTwoByFourBracket()
{
double wallThickness = Inches.Eigth;
double innerWidth = Inches.One * 4 + Inches.Sixteenth;
double innerHeight = Inches.One * 2 + Inches.Sixteenth;
double innerDepth = Inches.Half + Inches.Sixteenth;
OSCADObject twoByfourHolder = new Box()
{
Size = new Vector3(innerWidth + wallThickness * 2, innerHeight + wallThickness * 2, innerDepth + wallThickness),
Center = true,
WallThickness = wallThickness
};
var whole = twoByfourHolder.Rotate(90, 0, 90) +
twoByfourHolder.Clone().Rotate(90, 0, 90).Rotate(0, 90, 0).Translate(innerHeight/2 - wallThickness*2 + Inches.Sixteenth*.5, 0, -innerHeight/2 - innerDepth/2 - wallThickness + Inches.Sixteenth);
whole = whole.Rotate(0, -90, 0);
whole.ToFile("twobyFourSideBracket");
}
public static void makeCenterTwoByFourBracket()
{
double wallThickness = Inches.Eigth;
double innerWidth = Inches.One * 4 + Inches.Sixteenth;
double innerHeight = Inches.One * 2 + Inches.Sixteenth;
double innerDepth = Inches.Half + Inches.Sixteenth;
OSCADObject twoByfourHolder = new Box()
{
Size = new Vector3(innerWidth + wallThickness * 2, innerHeight + wallThickness * 2, innerDepth + wallThickness),
Center = true,
WallThickness = wallThickness
};
var whole = twoByfourHolder.Rotate(180, 0, 0).Rotate(0, 0, 90);
var left = twoByfourHolder.Clone().Rotate(0, 0, 90).Rotate(0, 90, 0)
.Translate(innerDepth - wallThickness*2, 0, whole.Bounds().ZMax + innerHeight / 2);
var right = left.Mirror(1, 0, 0);
whole = whole + left + right;
// .Rotate(90, 0, 90) +
// twoByfourHolder.Clone().Rotate(90, 0, 90).Rotate(0, 90, 0).Translate(innerHeight / 2 - wallThickness * 2 + Inches.Sixteenth * .5, 0, -innerHeight / 2 - innerDepth / 2 - wallThickness + Inches.Sixteenth);
//whole = whole.Rotate(0, -90, 0);
whole.ToFile("twobyFourCenterBracket");
}
static void Main(string[] args)
{
var img = ImportedImage.FromFile("sample.png").Scale(1, 1, Inches.Quarter + Inches.Eigth);
var imgPos = img.Position();
var _base = new Cylinder(img.Bounds().Width + Inches.Quarter, Inches.Quarter) { Resolution = 100 };
//makeCenterTwoByFourBracket();
//makeSideTwoByFourBracket();
makeDiceHolder();
//makeACBrackets();
makeGreatSword();
makepaddleHandle();
makePaddle();
//makeDisk();
//makeHolder();
//makeLoop();
//makeBadge();
//makeCardClip();
//makeLaserStand();
//makeStandCap();
var rim = _base.Clone().Scale(1, 1, 1.25) - _base.Clone().Scale(.9, .9, 3.5).Translate(0, 0, -Inches.Eigth);
var coaster = img + _base.Translate(imgPos.X, imgPos.Y, 0) + rim.Translate(imgPos.X, imgPos.Y, Inches.Quarter); ;
var tubeMe = new Tube()
{
Diameter1 = Inches.One,
Diameter2 = Inches.Half,
Height = Inches.One,
Bottom = false,
Resolution = 100,
//Center = true,
WallThickness = Inches.Sixteenth
};
tubeMe.ToFile("tubeTest");
//var boxMe = new Box() {
// Size = new Vector3(10, 10, 10),
// WallThickness = .5
//};
//boxMe.ToFile("boxtest");
//var img = ImportedImage.FromFile("twixCrop_small.png", new ImageImportOptions()
//{
// HeightMapping = ImageImportOptions.HeightMappingMode.Vertical,
// UseGrayScale = false,
// SimplificationAmount = 25
//});
//img.ToFile("twixCrop");
//var img = ImportedImage.FromFile("vermont-nc.png").Scale(1, 1, Inches.Quarter + Inches.Eigth);
//var imgPos = img.Position();z
//var _base = new Cylinder(img.Bounds().Width + Inches.Quarter, Inches.Quarter) { Resolution = 100 };
//var rim = _base.Clone().Scale(1, 1, 1.25) - _base.Clone().Scale(.9, .9, 3.5).Translate(0, 0, -Inches.Eigth);
//var coaster = img + _base.Translate(imgPos.X, imgPos.Y, 0) + rim.Translate(imgPos.X, imgPos.Y, Inches.Quarter); ;
coaster.ToFile("seaImg").Open();
//coaster.ToFile("seaImg").Open();
//makePeg();

View File

@ -1,7 +1,6 @@
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Linq;
using OSCADSharp.DataBinding;
using OSCADSharp.Solids;
namespace OSCADSharp.UnitTests
@ -54,14 +53,5 @@ namespace OSCADSharp.UnitTests
Assert.AreEqual(0, childrenThatAreDiffs);
}
[TestMethod]
[ExpectedException(typeof(NotSupportedException))]
public void Difference_NoBindableProperties()
{
var diff = new Cube() - new Sphere();
diff.Bind("SomeProperty", new Variable("test", 5));
}
}
}

View File

@ -1,6 +1,5 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using OSCADSharp.DataBinding;
using OSCADSharp.IO;
using OSCADSharp.Solids;
using OSCADSharp.Utility;
@ -155,23 +154,6 @@ namespace OSCADSharp.UnitTests
Assert.AreEqual(OutputSettings.OSCADSharpHeader, output[0]);
}
[TestMethod]
public void OSCADObject_ToFileIncludesGlobalVariablesDefinedInSettings()
{
var cube = new Cube();
string[] output = null;
Variables.Global.Add("$fn", 100);
var mock = new Mock<IFileWriter>();
mock.Setup(_wrtr => _wrtr.WriteAllLines(It.IsAny<string>(), It.IsAny<string[]>()))
.Callback<string, string[]>((path, contents) => { output = contents; });
Dependencies.SetFileWriter(mock.Object);
cube.ToFile("myFile");
Assert.AreEqual("$fn = 100;\r\n", output[1]);
}
}
}

View File

@ -56,11 +56,9 @@
</Otherwise>
</Choose>
<ItemGroup>
<Compile Include="Scripting\VariableTests.cs" />
<Compile Include="SettingsTests.cs" />
<Compile Include="Solids\CubeTests.cs" />
<Compile Include="Solids\CylinderTests.cs" />
<Compile Include="Transforms\ColorTests.cs" />
<Compile Include="Transforms\HullTests.cs" />
<Compile Include="InterpolationTests.cs" />
<Compile Include="Transforms\MirrorTests.cs" />
@ -73,7 +71,6 @@
<Compile Include="Booleans\IntersectionTests.cs" />
<Compile Include="Transforms\MinkowskiTests.cs" />
<Compile Include="Transforms\ResizeTests.cs" />
<Compile Include="Transforms\RotateTests.cs" />
<Compile Include="Transforms\ScaleTests.cs" />
<Compile Include="Transforms\TranslateTests.cs" />
</ItemGroup>

View File

@ -1,32 +0,0 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OSCADSharp.DataBinding;
using OSCADSharp.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OSCADSharp.UnitTests.Scripting
{
[TestClass]
public class VariableTests
{
[TestMethod]
public void Variables_CreatingVariableWithTrueForGlobalAddsGlobals()
{
var myVariable = new Variable("overallWidth", Inches.ToMillimeters(3.5), true);
Assert.AreEqual(Variables.Global.Get("overallWidth"), myVariable);
}
[TestMethod]
public void Variables_ComputingAVariableValueResultsInACompoundVariable()
{
var compound = new Variable("x", 5) / 12;
string type = compound.GetType().ToString();
Assert.AreEqual("OSCADSharp.DataBinding.Variable+CompoundVariable", type);
}
}
}

View File

@ -1,6 +1,5 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using OSCADSharp.DataBinding;
using OSCADSharp.IO;
using OSCADSharp.Solids;
using OSCADSharp.Utility;
@ -15,23 +14,6 @@ namespace OSCADSharp.UnitTests
[TestClass]
public class SettingsTests
{
[TestMethod]
public void Settings_NullVariablesDoNothing()
{
var cube = new Cube();
Variables.Global["thing"] = null;
string[] output = null;
var mock = new Mock<IFileWriter>();
mock.Setup(_wrtr => _wrtr.WriteAllLines(It.IsAny<string>(), It.IsAny<string[]>()))
.Callback<string, string[]>((path, contents) => { output = contents; });
Dependencies.SetFileWriter(mock.Object);
cube.ToFile("myFile");
Assert.AreEqual("", output[1]);
}
[TestMethod]
[ExpectedException(typeof(InvalidOperationException))]
public void Settings_NullOpenSCADPathThrowsError()

View File

@ -4,7 +4,6 @@ using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OSCADSharp.Utility;
using OSCADSharp.Spatial;
using OSCADSharp.DataBinding;
using OSCADSharp.Solids;
namespace OSCADSharp.UnitTests
@ -107,94 +106,6 @@ namespace OSCADSharp.UnitTests
Assert.AreEqual(new Vector3(-2.5, -2.5, -10), obj.Bounds().BottomLeft);
}
[TestMethod]
public void Cube_Size_XYZBindingsAppearInOutput()
{
Variable xValue = new Variable("xVal", 10.125);
Variable yValue = new Variable("yVal", 15.5);
Variable zValue = new Variable("zVal", 25);
var obj = new Cube();
obj.Bind("Size.X", xValue);
obj.Bind("Size.Y", yValue);
obj.Bind("Size.Z", zValue);
string script = obj.ToString();
Assert.AreEqual(Convert.ToDouble(xValue.Value), obj.Size.X);
Assert.AreEqual(Convert.ToDouble(yValue.Value), obj.Size.Y);
Assert.AreEqual(Convert.ToDouble(zValue.Value), obj.Size.Z);
Assert.IsTrue(script.Contains("size = [xVal, yVal, zVal]"));
}
[TestMethod]
public void Cube_Size_LengthWidthHeightindingsAppearInOutput()
{
Variable xValue = new Variable("xVal", 10.125);
Variable yValue = new Variable("yVal", 15.5);
Variable zValue = new Variable("zVal", 25);
var obj = new Cube();
obj.Bind("Length", xValue);
obj.Bind("Width", yValue);
obj.Bind("Height", zValue);
string script = obj.ToString();
Assert.AreEqual(Convert.ToDouble(xValue.Value), obj.Size.X);
Assert.AreEqual(Convert.ToDouble(yValue.Value), obj.Size.Y);
Assert.AreEqual(Convert.ToDouble(zValue.Value), obj.Size.Z);
Assert.IsTrue(script.Contains("size = [xVal, yVal, zVal]"));
}
[TestMethod]
public void Cube_CenterBindingAppearsInOutput()
{
Variable centerVal = new Variable("isCentered", true);
var obj = new Cube();
obj.Bind("Center", centerVal);
string script = obj.ToString();
Assert.AreEqual(centerVal.Value, obj.Center);
Assert.IsTrue(script.Contains("center = isCentered"));
}
[TestMethod]
public void Cube_ConstructorBindingsAppearInOutput()
{
var length = new Variable("deckBoxLength", Inches.Sixteenth * 32);
var width = new Variable("deckBoxWidth", Inches.Sixteenth * 32);
var height = new Variable("deckboxHeight", Inches.ToMillimeters(2.5));
var centered = new Variable("isCentered", true);
var cube = new Cube(length, width, height, centered);
string script = cube.ToString();
Assert.IsTrue(script.Contains("size = [deckBoxLength, deckBoxWidth, deckboxHeight]"));
Assert.IsTrue(script.Contains("center = isCentered"));
}
[TestMethod]
public void Cube_CloneHasSameBindings()
{
var cubeHeight = new Variable("myHeight", 35);
var cubeXTranslation = new Variable("xOffset", 50);
OSCADObject cube = new Cube(15, 5, 15);
cube.Bind("Height", cubeHeight);
cube = cube.Translate(cubeXTranslation, 0, 0);
var clone = cube.Clone();
string script = clone.ToString();
Assert.IsTrue(script.Contains("translate(v = [xOffset"));
Assert.IsTrue(script.Contains("size = [15, 5, myHeight]"));
}
[TestMethod]
public void Cube_LengthWidthHeightAppearsInScriptOutput()
{

View File

@ -1,5 +1,4 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OSCADSharp.DataBinding;
using OSCADSharp.Solids;
using OSCADSharp.Spatial;
using OSCADSharp.Utility;
@ -89,157 +88,5 @@ namespace OSCADSharp.UnitTests
Assert.IsTrue(script.Contains("$fa"));
Assert.IsTrue(script.Contains("$fs"));
}
[TestMethod]
public void Cylinder_CenterBindingAppearsInOutput()
{
Variable centerVal = new Variable("isCentered", true);
var obj = new Cylinder();
obj.Bind("Center", centerVal);
string script = obj.ToString();
Assert.AreEqual(centerVal.Value, obj.Center);
Assert.IsTrue(script.Contains("center = isCentered"));
}
[TestMethod]
public void Cylinder_R1R2BindingTest()
{
Variable radius1 = new Variable("radius1", 5);
Variable radius2 = new Variable("radius2", 25);
var obj = new Cylinder();
obj.Bind("Radius1", radius1);
obj.Bind("Radius2", radius2);
string script = obj.ToString();
Assert.AreEqual(Convert.ToDouble(radius1.Value), obj.Radius1);
Assert.AreEqual(Convert.ToDouble(radius2.Value), obj.Radius2);
Assert.IsTrue(script.Contains(String.Format("r1 = {0}", radius1.Text)));
Assert.IsTrue(script.Contains(String.Format("r2 = {0}", radius2.Text)));
}
[TestMethod]
public void Cylinder_D1RDBindingTest()
{
Variable d1 = new Variable("diameter2", 5);
Variable d2 = new Variable("diameter2", 25);
var obj = new Cylinder();
obj.Bind("Diameter1", d1);
obj.Bind("Diameter2", d2);
string script = obj.ToString();
Assert.AreEqual(Convert.ToDouble(d1.Value), obj.Diameter1);
Assert.AreEqual(Convert.ToDouble(d2.Value), obj.Diameter2);
Assert.IsTrue(script.Contains(String.Format("d1 = {0}", d1.Text)));
Assert.IsTrue(script.Contains(String.Format("d2 = {0}", d2.Text)));
}
[TestMethod]
public void Cylinder_DiameterAndRadiusBindingsAreMutuallyExclusive()
{
Variable diameter = new Variable("diameter", 15.5);
Variable radius = new Variable("radius", 45);
var obj = new Cylinder();
obj.Bind("Radius", radius);
string script = obj.ToString();
Assert.AreEqual(Convert.ToDouble(radius.Value), obj.Radius);
Assert.IsTrue(script.Contains(String.Format("r = {0}", radius.Text)));
Assert.IsFalse(script.Contains(String.Format("d = {0}", diameter.Text)));
obj.Bind("Diameter", diameter);
script = obj.ToString();
Assert.AreEqual(Convert.ToDouble(diameter.Value), obj.Diameter);
Assert.IsTrue(script.Contains(String.Format("d = {0}", diameter.Text)));
Assert.IsFalse(script.Contains(String.Format("r = {0}", radius.Text)));
}
[TestMethod]
public void Cylinder_BindingsResolutionAngleAndFragmentSizeTest()
{
var resolution = new Variable("resolution", 30);
var angle = new Variable("angle", 5);
var circLength = new Variable("circLength", 10);
var cylinder = new Cylinder();
cylinder.Bind("Resolution", resolution);
cylinder.Bind("MinimumAngle", angle);
cylinder.Bind("MinimumCircumferentialLength", circLength);
string script = cylinder.ToString();
Assert.IsTrue(script.Contains("$fn = resolution"));
Assert.IsTrue(script.Contains("$fa = angle"));
Assert.IsTrue(script.Contains("$fs = circLength"));
}
[TestMethod]
public void Cylinder_CanCreatePreBoundCylinderWithConstructor()
{
var diam = new Variable("mainColumn", Inches.Half);
var height = new Variable("overallHeight", Inches.Quarter);
var cyl = new Cylinder(diam, diam, height);
Assert.AreEqual(diam.Value, cyl.Diameter);
Assert.AreEqual(height.Value, cyl.Height);
string script = cyl.ToString();
Assert.IsTrue(script.Contains("d1 = mainColumn"));
Assert.IsTrue(script.Contains("d2 = mainColumn"));
Assert.IsTrue(script.Contains("h = overallHeight"));
}
[TestMethod]
public void Cylinder_CloningCylinderClonesBindings()
{
var diam = new Variable("mainColumn", Inches.Half);
var height = new Variable("overallHeight", Inches.Quarter);
var center = new Variable("isCentered", true);
var color = new Variable("myColor", "Blue");
var rotation = new Variable("myRot", new Vector3(90, 90, -90));
OSCADObject cyl = new Cylinder(diam, diam, height, center);
cyl = cyl.Rotate(rotation).Color(color);
var clone = cyl.Clone();
string script = clone.ToString();
Assert.IsTrue(script.Contains("color(myColor"));
Assert.IsTrue(script.Contains("rotate(myRot)"));
Assert.IsTrue(script.Contains("center = isCentered"));
Assert.IsTrue(script.Contains("d1 = mainColumn"));
Assert.IsTrue(script.Contains("d2 = mainColumn"));
Assert.IsTrue(script.Contains("h = overallHeight"));
}
[TestMethod]
public void Cylinder_NegationOnConstructorVariablesProvidesExpectedOutput()
{
Variable wheelThickness = new Variable("wheelThickness", Inches.Eigth + Inches.Sixteenth);
Variable wheelDiameter = new Variable("wheelDiameter", Inches.ToMillimeters(1.5));
Variable wheelHoleDiameter = new Variable("wheelHoleDiameter", Inches.Quarter);
OSCADObject cyl = new Cylinder(wheelHoleDiameter - 1, wheelHoleDiameter - 1, wheelThickness + 2)
.Translate(0, -wheelDiameter / 2 + wheelHoleDiameter / 2, 0);
string script = cyl.ToString();
Assert.IsTrue(script.Contains("translate(v = [0, -wheelDiameter / 2 + wheelHoleDiameter / 2, 0])"));
Assert.IsTrue(script.Contains("cylinder(center = false, d1 = wheelHoleDiameter - 1, d2 = wheelHoleDiameter - 1, h = wheelThickness + 2);"));
}
}
}

View File

@ -2,7 +2,6 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OSCADSharp.Utility;
using OSCADSharp.Spatial;
using OSCADSharp.DataBinding;
using OSCADSharp.Solids;
namespace OSCADSharp.UnitTests
@ -117,90 +116,6 @@ namespace OSCADSharp.UnitTests
Assert.IsTrue(script.Contains("$fn"));
Assert.IsTrue(script.Contains("$fa"));
Assert.IsTrue(script.Contains("$fs"));
}
[TestMethod]
public void Sphere_RadiusVariableBoundAppearsInOutput()
{
string variableName = "mySphereRadius";
double radius = 15;
Variables.Global.Add(variableName, radius);
var sphere = new Sphere();
sphere.Bind("Radius", Variables.Global["mySphereRadius"]);
Assert.IsTrue(sphere.Radius == radius);
string script = sphere.ToString();
Assert.IsTrue(script.Contains("r = mySphereRadius"));
}
[TestMethod]
public void Sphere_BindingDiameterSetsDiameterInOutput()
{
string variableName = "diam";
double diam = 20;
Variables.Global.Add(variableName, diam);
var sphere = new Sphere();
sphere.Bind("Diameter", Variables.Global["diam"]);
Assert.IsTrue(sphere.Diameter == diam);
string script = sphere.ToString();
Assert.IsTrue(script.Contains("d = diam"));
}
[TestMethod]
public void Sphere_ResolutionAngleAndFragmentSizeTest()
{
var resolution = new Variable("resolution", 30);
var angle = new Variable("angle", 5);
var fragSize = new Variable("fragSize", 10);
var sphere = new Sphere();
sphere.Bind("Resolution", resolution);
sphere.Bind("MinimumAngle", angle);
sphere.Bind("MinimumFragmentSize", fragSize);
string script = sphere.ToString();
Assert.IsTrue(script.Contains("$fn = resolution"));
Assert.IsTrue(script.Contains("$fa = angle"));
Assert.IsTrue(script.Contains("$fs = fragSize"));
}
[TestMethod]
public void Sphere_CanCreateSphereWithBindingsFromConstructor()
{
var diam = new Variable("width", Inches.One);
var resolution = new Variable("rez", 100);
var sphere = new Sphere(diam, resolution);
Assert.AreEqual(diam.Value, sphere.Diameter);
Assert.AreEqual(resolution.Value, sphere.Resolution);
string script = sphere.ToString();
Assert.IsTrue(script.Contains("d = width"));
Assert.IsTrue(script.Contains("$fn = rez"));
}
[TestMethod]
public void Sphere_BindingsAreClonedWithObject()
{
var diam = new Variable("width", Inches.One);
var resolution = new Variable("rez", 100);
var scale = new Variable("theScale", new Vector3(1, 2, 3));
var sphere = new Sphere(diam, resolution).Scale(scale);
var clone = sphere.Clone();
string script = clone.ToString();
Assert.IsTrue(script.Contains("d = width"));
Assert.IsTrue(script.Contains("$fn = rez"));
Assert.IsTrue(script.Contains("scale(v = theScale)"));
}
}
}
}

View File

@ -1,5 +1,4 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OSCADSharp.DataBinding;
using OSCADSharp.Solids;
using OSCADSharp.Spatial;
using System;
@ -27,96 +26,5 @@ namespace OSCADSharp.UnitTests
{
var obj = new Text3D("BBBB", 16).Bounds();
}
[TestMethod]
public void Text_TextAndSizeBindingAffectsOutput()
{
var text = new Variable("txt", "yo");
var size = new Variable("txtSize", 34);
var obj = new Text3D();
obj.Bind("Text", text);
obj.Bind("Size", size);
string script = obj.ToString();
Assert.AreEqual(text.Value, obj.Text);
Assert.IsTrue(size.Value.ToString() == obj.Size.ToString());
Assert.IsTrue(script.Contains(String.Format("text(\"{0}\"", text.Text)));
Assert.IsTrue(script.Contains(String.Format("size = {0}", size.Text)));
}
[TestMethod]
public void Text_FontSpacingBindingAffectsOutput()
{
var font = new Variable("font", "wingdings");
var spacing = new Variable("spacing", 34);
var obj = new Text3D();
obj.Bind("font", font);
obj.Bind("SpacinG", spacing);
string script = obj.ToString();
Assert.AreEqual(font.Value, obj.Font);
Assert.IsTrue(spacing.Value.ToString() == obj.Spacing.ToString());
Assert.IsTrue(script.Contains(String.Format("font = {0}", font.Text)));
Assert.IsTrue(script.Contains(String.Format("spacing = {0}", spacing.Text)));
}
[TestMethod]
public void Text_TextDirectionLanguageBindingAffectsOutput()
{
var direction = new Variable("direction", "ltr");
var language = new Variable("language", "en");
var obj = new Text3D();
obj.Bind("textdirection", direction);
obj.Bind("language", language);
string script = obj.ToString();
Assert.AreEqual(direction.Value, obj.TextDirection);
Assert.AreEqual(language.Value, obj.Language);
Assert.IsTrue(script.Contains(String.Format("direction = {0}", direction.Text)));
Assert.IsTrue(script.Contains(String.Format("language = {0}", language.Text)));
}
[TestMethod]
public void Text_BindingConstructorAffectsOutput()
{
var text = new Variable("txt", "Greetings, Earthlings");
var size = new Variable("txtSize", 82);
var txt = new Text3D(text, size);
string script = txt.ToString();
Assert.IsTrue(script.Contains(String.Format("text(\"{0}\"", text.Text)));
Assert.IsTrue(script.Contains(String.Format("size = {0}", size.Text)));
}
[TestMethod]
public void Test_ClonedObjectHasBindings()
{
var text = new Variable("txt", "Greetings, Earthlings");
var size = new Variable("txtSize", 82);
var mirrorNormal = new Variable("xMirror", new Vector3(1, 0, 0));
var zResize = new Variable("zSize", 30);
var txt = new Text3D(text, size)
.Mirror(mirrorNormal).Resize(15, 15, zResize);
var clone = txt.Clone();
string script = clone.ToString();
Assert.IsTrue(script.Contains(String.Format("text(\"{0}\"", text.Text)));
Assert.IsTrue(script.Contains(String.Format("size = {0}", size.Text)));
Assert.IsTrue(script.Contains(String.Format("mirror(xMirror)", size.Text)));
Assert.IsTrue(script.Contains(String.Format("resize([15, 15, zSize])", size.Text)));
}
}
}

View File

@ -1,45 +0,0 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OSCADSharp.DataBinding;
using OSCADSharp.Solids;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OSCADSharp.UnitTests.Transforms
{
[TestClass]
public class ColorTests
{
[TestMethod]
public void Color_BoundFieldsAppearInOutput()
{
Variable colorVar = new Variable("myFavoriteColor", "blue");
Variable cubeOpacity = new Variable("cubeOpacity", .6);
var obj = new Cube().Color("Red", .5);
obj.Bind("color", colorVar);
obj.Bind("opacity", cubeOpacity);
string script = obj.ToString();
Assert.IsTrue(script.Contains("myFavoriteColor"));
Assert.IsTrue(script.Contains("cubeOpacity"));
}
[TestMethod]
public void Color_CanBindWithColorOverload()
{
Variable colorVar = new Variable("myFavoriteColor", "blue");
Variable cubeOpacity = new Variable("cubeOpacity", .6);
var obj = new Cube().Color(colorVar, cubeOpacity);
string script = obj.ToString();
Assert.IsTrue(script.Contains("myFavoriteColor"));
Assert.IsTrue(script.Contains("cubeOpacity"));
}
}
}

View File

@ -1,5 +1,4 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OSCADSharp.DataBinding;
using OSCADSharp.Solids;
using OSCADSharp.Spatial;
using System;
@ -60,36 +59,6 @@ namespace OSCADSharp.UnitTests
var cube = new Cube(5, 10, 20);
var pos = cube.Mirror(1, 1, 0).Bounds();
}
[TestMethod]
public void Mirror_CanBindNormal()
{
var cube = new Cube(5, 20, 15).Mirror(1, 0, 0);
cube.Bind("normal", new Variable("myVar", new Vector3(1, 0, 0)));
string script = cube.ToString();
Assert.IsTrue(script.Contains("mirror(myVar)"));
}
[TestMethod]
public void Mirror_CanBindNormalWithParameter()
{
var cube = new Cube(5, 20, 15).Mirror(new Variable("myVar", new Vector3(1, 0, 0)));
string script = cube.ToString();
Assert.IsTrue(script.Contains("mirror(myVar)"));
}
[TestMethod]
public void Mirror_VariablesForXandZ()
{
var x = new Variable("xComp", 0);
var z = new Variable("zComp", 1);
var cube = new Cube().Mirror(x, 0, z);
string script = cube.ToString();
Assert.IsTrue(script.Contains("mirror([xComp, 0, zComp])"));
}
}
}
}

View File

@ -1,5 +1,4 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OSCADSharp.DataBinding;
using OSCADSharp.Solids;
using OSCADSharp.Spatial;
using System;
@ -31,31 +30,5 @@ namespace OSCADSharp.UnitTests.Transforms
Assert.AreEqual(new Vector3(5, 5, 5), bounds.TopRight);
Assert.AreEqual(new Vector3(0, 0, 0), bounds.BottomLeft);
}
[TestMethod]
public void Resize_SizeBindingwithVectorAppearsInOutput()
{
var resizedCube = new Cube().Resize(5, 5, 10);
var sizeVar = new Variable("mySize", new Vector3(20, 30, 20));
resizedCube.Bind("size", sizeVar);
string script = resizedCube.ToString();
Assert.IsTrue(script.Contains("resize(mySize)"));
}
[TestMethod]
public void Resize_ParameterizedSizeBindingAppearsInOutput()
{
var xAmount = new Variable("xAmt", 15);
var resizedCube = new Cube().Resize(xAmount, 5, 10);
string script = resizedCube.ToString();
Assert.IsTrue(script.Contains("resize([xAmt, 5, 10])"));
}
}
}

View File

@ -1,52 +0,0 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OSCADSharp.DataBinding;
using OSCADSharp.Solids;
using OSCADSharp.Spatial;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OSCADSharp.UnitTests.Transforms
{
[TestClass]
public class RotateTests
{
[TestMethod]
public void Rotate_CanBindAngle()
{
var cyl = new Cylinder().Rotate(0, 90, 0);
var rotVar = new Variable("myRot", new Vector3(120, 90, 30));
cyl.Bind("angle", rotVar);
string script = cyl.ToString();
Assert.IsTrue(script.Contains("rotate(myRot)"));
}
[TestMethod]
public void Rotate_CanBindAngleWithParameters()
{
var xAngle = new Variable("xAngle", 30);
var yAngle = new Variable("yAngle", -20);
var cyl = new Cylinder().Rotate(xAngle, yAngle, 120);
string script = cyl.ToString();
Assert.IsTrue(script.Contains("rotate([xAngle, yAngle, 120])"));
}
[TestMethod]
public void Rotate_CanMultiplyAVectorVariableInline()
{
var rotation = new Variable("cubeRot", 15);
var cube = new Cube(20, 20, 80, true).Rotate(rotation * 1.5, 30, 30);
string script = cube.ToString();
Assert.IsTrue(script.Contains("rotate([cubeRot * 1.5, 30, 30])"));
}
}
}

View File

@ -1,5 +1,4 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OSCADSharp.DataBinding;
using OSCADSharp.Solids;
using OSCADSharp.Spatial;
using System;
@ -36,30 +35,5 @@ namespace OSCADSharp.UnitTests.Transforms
Assert.AreEqual(bounds.YMin, 0);
Assert.AreEqual(bounds.ZMin, 0);
}
[TestMethod]
public void Scale_CanBindScaleValue()
{
var cube = new Cube().Scale(2, 2, 2);
var scaleVar = new Variable("scaleVar", new Vector3(5, 1, 2));
cube.Bind("scale", scaleVar);
string script = cube.ToString();
Assert.IsTrue(script.Contains("v = scaleVar"));
}
[TestMethod]
public void Scale_CanBindParameterizedScaleValue()
{
var x = new Variable("xS", 3);
var y = new Variable("yS", 4);
var z = new Variable("zS", 3);
var cube = new Cube().Scale(x, y, z);
string script = cube.ToString();
Assert.IsTrue(script.Contains("v = [xS, yS, zS]"));
}
}
}

View File

@ -1,5 +1,4 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OSCADSharp.DataBinding;
using OSCADSharp.Solids;
using OSCADSharp.Spatial;
using OSCADSharp.Utility;
@ -25,44 +24,5 @@ namespace OSCADSharp.UnitTests.Transforms
Assert.AreEqual(boundsAfter.TopRight, boundsBefore.TopRight + new Vector3(5, 2, 3));
Assert.AreEqual(boundsAfter.BottomLeft, boundsBefore.BottomLeft + new Vector3(5, 2, 3));
}
[TestMethod]
public void Translate_CanBindVector()
{
var cube = new Cube().Translate(10, 0, 0);
var vec = new Variable("vec", new Vector3(0, 20, 30));
cube.Bind("vector", vec);
string script = cube.ToString();
Assert.IsTrue(script.Contains("v = vec"));
}
[TestMethod]
public void Translate_CanBindVectorsByParameters()
{
var y = new Variable("yAmt", -35);
var z = new Variable("zAmt", 40);
var cube = new Cube().Translate(-5, y, z);
string script = cube.ToString();
Assert.IsTrue(script.Contains("v = [-5, yAmt, zAmt]"));
}
[TestMethod]
public void Translate_AddingTwoVariablesYieldsInlineOperation()
{
var cylinDiameter = new Variable("cylinDiam", Inches.One);
var wallThickness = new Variable("wallThickness", Inches.Eigth);
var cylin = new Cylinder(cylinDiameter, cylinDiameter);
cylin.Height = 15;
var obj = cylin.Translate(cylinDiameter + wallThickness, 0, 0);
string script = obj.ToString();
Assert.IsTrue(script.Contains("v = [cylinDiam + wallThickness, 0, 0]"));
}
}
}

View File

@ -1,57 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OSCADSharp.DataBinding
{
internal class BindableBoolean : IBindable
{
internal string InnerValue
{
get;
set;
}
private Bindings bindings = new Bindings(new Dictionary<string, string>()
{
{ "innervalue", "innervalue" }
});
/// <summary>
/// Creates a bindable boolean, which is more or less a
/// proxy for bindings on boolean fields
/// </summary>
/// <param name="propertyName">Name of the property in the containing class for binding.
/// This will be used as a synonym</param>
internal BindableBoolean(string propertyName)
{
this.boundProperty = propertyName;
this.bindings.Synonym("innervalue", propertyName);
}
private readonly string boundProperty = null;
internal bool IsBound { get; set; } = false;
public void Bind(string property, Variable variable)
{
this.IsBound = true;
var stringifiedVar = new Variable(variable.Text, variable.Value.ToString().ToLower());
this.bindings.Add<BindableBoolean>(this, property, stringifiedVar);
}
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;
}
}
}

View File

@ -1,70 +0,0 @@
using OSCADSharp.Spatial;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OSCADSharp.DataBinding
{
internal class BindableVector : Vector3, IBindable
{
private Bindings bindings = new Bindings(new Dictionary<string, string>()
{
{ "x", "x" },
{ "y", "y" },
{ "z", "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);
}
internal BindableVector(double x = 0, double y = 0, double z = 0, Dictionary<string, string> synonyms = null)
{
this.X = x;
this.Y = y;
this.Z = z;
this.setSynonyms(synonyms);
}
private void setSynonyms(Dictionary<string, string> synonyms)
{
if (synonyms == null)
return;
foreach (KeyValuePair<string, string> item in synonyms)
{
this.bindings.Synonym(item.Value, item.Key);
}
}
public void Bind(string property, Variable variable)
{
this.bindings.Add<BindableVector>(this, property, variable);
}
public override string ToString()
{
string x = this.bindings.Contains("x") ? this.bindings.Get("x").BoundVariable.Text : this.X.ToString();
string y = this.bindings.Contains("y") ? this.bindings.Get("y").BoundVariable.Text : this.Y.ToString();
string z = this.bindings.Contains("z") ? this.bindings.Get("z").BoundVariable.Text : this.Z.ToString();
return String.Format("[{0}, {1}, {2}]", x, y, z);
}
internal new BindableVector Clone()
{
var clone = new BindableVector(base.Clone());
clone.bindings = this.bindings.Clone();
return clone;
}
}
}

View File

@ -1,14 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OSCADSharp.DataBinding
{
internal class Binding
{
public string OpenSCADFieldName { get; set; }
public Variable BoundVariable { get; set; }
}
}

View File

@ -1,143 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace OSCADSharp.DataBinding
{
internal class Bindings
{
#region Fields
private Dictionary<string, Binding> bindings = new Dictionary<string, Binding>();
private readonly Dictionary<string, string> propertyNametoOpenSCADFieldMappings = new Dictionary<string, string>();
private Dictionary<string, string> synonyms = new Dictionary<string, string>();
#endregion
#region Constructors
internal Bindings()
{
this.propertyNametoOpenSCADFieldMappings = new Dictionary<string, string>();
}
internal Bindings(Dictionary<string, string> mappings)
{
this.propertyNametoOpenSCADFieldMappings = mappings;
}
#endregion
#region Private Methods
private void setProperty<T>(T instance, string property, Variable variable)
{
PropertyInfo[] properties;
properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
for (int i = properties.Length - 1; i >= 0; i--)
{
var prop = properties[i];
string lProperty = property.ToLower();
if (this.hasMatchingSynonym(lProperty))
lProperty = this.synonyms[lProperty];
if (prop.Name.ToLower() == lProperty)
{
prop.SetValue(instance, variable.Value);
}
}
}
/// <summary>
/// Returns true if this set of bindings can map the specified property to an OpenSCAD field
/// </summary>
/// <param name="propertyName"></param>
/// <returns></returns>
private bool hasMapping(string propertyName)
{
return this.propertyNametoOpenSCADFieldMappings.ContainsKey(propertyName.ToLower())
|| this.hasMatchingSynonym(propertyName.ToLower());
}
/// <summary>
/// Returns the corresponding OpenSCAD output field name for
/// a given property name
/// </summary>
/// <param name="propertyName"></param>
/// <returns></returns>
private string propertyToOpenSCADField(string propertyName)
{
string lpropertyName = propertyName.ToLower();
if (this.hasMatchingSynonym(lpropertyName))
{
return this.synonymToOpenScadField(lpropertyName);
}
return this.propertyNametoOpenSCADFieldMappings[lpropertyName];
}
private void add(Binding binding)
{
bindings[binding.OpenSCADFieldName] = binding;
}
private bool hasMatchingSynonym(string synonymName)
{
return this.synonyms.ContainsKey(synonymName);
}
private string synonymToOpenScadField(string synonymName)
{
return this.propertyToOpenSCADField(this.synonyms[synonymName]);
}
#endregion
#region Internal API
internal void Add<T>(T instance, string propertyName, Variable variable)
{
if (!this.hasMapping(propertyName))
{
throw new KeyNotFoundException(String.Format("No bindable property matching the name {0} was found", propertyName));
}
//Assign mapping r -> radius -> variable
var binding = new Binding()
{
OpenSCADFieldName = this.propertyToOpenSCADField(propertyName),
BoundVariable = variable
};
//Set value of property to variable value
this.setProperty<T>(instance, propertyName, variable);
this.add(binding);
}
internal bool Contains(string openScadFieldName)
{
return bindings.ContainsKey(openScadFieldName);
}
internal Binding Get(string propertyName)
{
if (this.hasMatchingSynonym(propertyName))
return this.bindings[this.synonyms[propertyName]];
return bindings[propertyName];
}
internal void Synonym(string propertyName, string alternateName)
{
this.synonyms[alternateName] = propertyName;
}
internal Bindings Clone()
{
var clone = new Bindings(this.propertyNametoOpenSCADFieldMappings);
clone.synonyms = this.synonyms;
clone.bindings = this.bindings;
return clone;
}
#endregion
}
}

View File

@ -1,21 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OSCADSharp.DataBinding
{
/// <summary>
/// An object whose properties can be bound to variables
/// </summary>
internal interface IBindable
{
/// <summary>
/// Binds a variable to property of this object
/// </summary>
/// <param name="property"></param>
/// <param name="variable"></param>
void Bind(string property, Variable variable);
}
}

View File

@ -1,309 +0,0 @@
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.DataBinding
{
/// <summary>
/// A value for setting object properties in script output to
/// a specific variable
/// </summary>
public class Variable
{
/// <summary>
/// Creates a new Variable with the specified text/value
/// </summary>
/// <param name="text">Text of the variable. This is the text that will appear in script output for this variable</param>
/// <param name="value">The variable's value</param>
/// <param name="addGlobal">A flag indicating whether to add this variable to Variables.Global</param>
public Variable(string text, object value, bool addGlobal = false)
{
this.Text = text;
this.Value = value;
if (addGlobal)
{
Variables.Global.Add(this);
}
}
/// <summary>
/// Text of the variable
/// </summary>
public string Text { get; set; }
/// <summary>
/// Value of the variable.
///
/// Must be compatible with the data type being assigned to.
/// </summary>
public object Value { get; set; }
/// <summary>
/// Gets this variable as a text = value string
/// </summary>
/// <returns></returns>
public override string ToString()
{
return string.Format("{0} = {1}", this.Text, this.Value.ToString());
}
#region Operators
private static Variable applyMixedOperatorLeft(string oprtor, Variable left, object right, Func<object, object, object> calcMethod)
{
if (VariableCalculator.IsNumeric(right))
{
return new CompoundVariable(String.Format("{0} {1} {2}", left.Text, oprtor, right.ToString()),
calcMethod(left.Value, right));
}
throw new NotSupportedException(String.Format("Cannot use {0} operator on a variable with an object of type {1}",
oprtor, typeof(object).ToString()));
}
private static Variable applyMixedOperatorRight(string oprtor, object left, Variable right, Func<object, object, object> calcMethod)
{
if (VariableCalculator.IsNumeric(left))
{
return new CompoundVariable(String.Format("{0} {1} {2}", left.ToString(), oprtor, right.Text),
calcMethod(left, right.Value));
}
throw new NotSupportedException(String.Format("Cannot use {0} operator on a variable with an object of type {1}",
oprtor, typeof(object).ToString()));
}
/// <summary>
/// Adds two variables together
/// </summary>
/// <param name="left"></param>
/// <param name="right"></param>
/// <returns></returns>
public static Variable operator +(Variable left, Variable right)
{
return new CompoundVariable(String.Format("{0} + {1}", left.Text, right.Text), VariableCalculator.Add(left.Value, right.Value));
}
/// <summary>
/// Adds a value to a variable
/// </summary>
/// <param name="left"></param>
/// <param name="right"></param>
/// <returns></returns>
public static Variable operator +(Variable left, object right)
{
return applyMixedOperatorLeft("+", left, right, VariableCalculator.Add);
}
/// <summary>
/// Adds a value to a variable
/// </summary>
/// <param name="left"></param>
/// <param name="right"></param>
/// <returns></returns>
public static Variable operator +(object left, Variable right)
{
return applyMixedOperatorRight("+", left, right, VariableCalculator.Add);
}
/// <summary>
/// Subtracts two variables
/// </summary>
/// <param name="left"></param>
/// <param name="right"></param>
/// <returns></returns>
public static Variable operator -(Variable left, Variable right)
{
return new CompoundVariable(String.Format("{0} - {1}", left.Text, right.Text), VariableCalculator.Subtract(left.Value, right.Value));
}
/// <summary>
/// Numerical negation on a variable
/// </summary>
/// <param name="right"></param>
/// <returns></returns>
public static Variable operator -(Variable right)
{
object value = null;
if (VariableCalculator.IsNumeric(right.Value))
{
value = -Convert.ToDouble(right.Value);
}
else if(VariableCalculator.IsVector(right.Value))
{
value = ((Vector3)right.Value).Negate();
}
return new CompoundVariable(String.Format("-{0}", right.Text), value);
}
/// <summary>
/// Subtracts a value from a variable
/// </summary>
/// <param name="left"></param>
/// <param name="right"></param>
/// <returns></returns>
public static Variable operator -(Variable left, object right)
{
return applyMixedOperatorLeft("-", left, right, VariableCalculator.Subtract);
}
/// <summary>
/// Subtracts a value from a variable
/// </summary>
/// <param name="left"></param>
/// <param name="right"></param>
/// <returns></returns>
public static Variable operator -(object left, Variable right)
{
return applyMixedOperatorRight("-", left, right, VariableCalculator.Subtract);
}
/// <summary>
/// Multiplies two variables
/// </summary>
/// <param name="left"></param>
/// <param name="right"></param>
/// <returns></returns>
public static Variable operator *(Variable left, Variable right)
{
return new CompoundVariable(String.Format("{0} * {1}", left.Text, right.Text), VariableCalculator.Multiply(left.Value, right.Value));
}
/// <summary>
/// Multiplies a variable by a value
/// </summary>
/// <param name="left"></param>
/// <param name="right"></param>
/// <returns></returns>
public static Variable operator *(Variable left, object right)
{
return applyMixedOperatorLeft("*", left, right, VariableCalculator.Multiply);
}
/// <summary>
/// Multiplies a variable by a value
/// </summary>
/// <param name="left"></param>
/// <param name="right"></param>
/// <returns></returns>
public static Variable operator *(object left, Variable right)
{
return applyMixedOperatorRight("*", left, right, VariableCalculator.Multiply);
}
/// <summary>
/// Divides two variables
/// </summary>
/// <param name="left"></param>
/// <param name="right"></param>
/// <returns></returns>
public static Variable operator /(Variable left, Variable right)
{
return new CompoundVariable(String.Format("{0} / {1}", left.Text, right.Text), VariableCalculator.Divide(left.Value, right.Value));
}
/// <summary>
/// Divides a variable by a value
/// </summary>
/// <param name="left"></param>
/// <param name="right"></param>
/// <returns></returns>
public static Variable operator /(Variable left, object right)
{
return applyMixedOperatorLeft("/", left, right, VariableCalculator.Divide);
}
/// <summary>
/// Divides a variable by a value
/// </summary>
/// <param name="left"></param>
/// <param name="right"></param>
/// <returns></returns>
public static Variable operator /(object left, Variable right)
{
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
}
}

View File

@ -1,116 +0,0 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OSCADSharp.DataBinding
{
/// <summary>
/// A collection of names/values for variables
/// </summary>
public sealed class Variables
{
/// <summary>
/// Global variables that can be assigned for output at the
/// top of OpenSCAD scripts
/// </summary>
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
/// </summary>
/// <param name="name"></param>
/// <param name="value"></param>
public void Add(string name, object value)
{
this.variables[name] = new Variable(name, value);
}
/// <summary>
/// Adds a variable to the collection
/// </summary>
/// <param name="variable"></param>
public void Add(Variable variable)
{
this.variables[variable.Text] = variable;
}
/// <summary>
/// Removes a variable from the collection
/// </summary>
/// <param name="name"></param>
public Variable Remove(string name)
{
Variable value;
this.variables.TryRemove(name, out value);
return value;
}
/// <summary>
/// Gets a variable by name
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public Variable Get(string name)
{
return this.variables[name];
}
/// <summary>
/// Assigns or gets a variable's value
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public Variable this[string name] // long is a 64-bit integer
{
get
{
if (variables.ContainsKey(name))
{
return variables[name];
}
else
{
return null;
}
}
set
{
variables[name] = value;
}
}
/// <summary>
/// This class is intended for use in other externally-exposed classes,
/// as such its constructor is not public.
/// </summary>
internal Variables()
{
}
/// <summary>
/// Gets the string representation for all variables
/// </summary>
/// <returns></returns>
public override string ToString()
{
StringBuilder sb = new StringBuilder();
foreach (var kvp in this.variables)
{
if(kvp.Value == null || String.IsNullOrEmpty(kvp.Value.ToString()) || String.IsNullOrEmpty(kvp.Key))
{
continue;
}
sb.Append(kvp.Value.ToString());
sb.Append(";");
sb.Append(Environment.NewLine);
}
return sb.ToString();
}
}
}

View File

@ -1,5 +1,4 @@
using OSCADSharp.DataBinding;
using OSCADSharp.Spatial;
using OSCADSharp.Spatial;
using OSCADSharp.Utility;
using System;
using System.Collections.Generic;
@ -21,7 +20,7 @@ namespace OSCADSharp
/// 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();
internal Vector3 Normal { get; set; } = new Vector3();
/// <summary>
/// Creates an object that's mirrored on a plane
@ -30,25 +29,12 @@ namespace OSCADSharp
/// <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);
this.Normal = 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 normal = this.Normal.ToString();
string mirrorCommand = String.Format("mirror({0})", normal);
var formatter = new SingleBlockFormatter(mirrorCommand, this.obj.ToString());
@ -59,8 +45,7 @@ namespace OSCADSharp
{
return new MirroredObject(this.obj.Clone(), this.Normal)
{
Name = this.Name,
bindings = this.bindings.Clone()
Name = this.Name
};
}
@ -108,23 +93,6 @@ namespace OSCADSharp
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

View File

@ -1,5 +1,4 @@
using OSCADSharp.DataBinding;
using OSCADSharp.Spatial;
using OSCADSharp.Spatial;
using OSCADSharp.Utility;
using System;
using System.Collections.Generic;
@ -98,12 +97,7 @@ namespace OSCADSharp
}
return new Bounds(newBottomLeft, newTopRight);
}
public override void Bind(string property, Variable variable)
{
throw new NotSupportedException("This object has no bindable properties.");
}
}
}
#endregion

View File

@ -1,5 +1,4 @@
using OSCADSharp.DataBinding;
using OSCADSharp.Spatial;
using OSCADSharp.Spatial;
using OSCADSharp.Utility;
using System;
using System.Collections.Generic;
@ -32,36 +31,19 @@ namespace OSCADSharp
{
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;
if (!this.ColorName.StartsWith("["))
{
colorName = this.bindings.Contains("color") ? this.bindings.Get("color").BoundVariable.Text :
"\"" + this.ColorName + "\"";
colorName = "\"" + this.ColorName + "\"";
}
else {
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();
colorName = this.ColorName;
}
string opacity = this.Opacity.ToString();
string colorCommand = String.Format("color({0}, {1})", colorName, opacity);
var formatter = new SingleBlockFormatter(colorCommand, this.obj.ToString());
@ -72,8 +54,7 @@ namespace OSCADSharp
{
return new ColoredObject(this.obj.Clone(), this.ColorName, this.Opacity)
{
Name = this.Name,
bindings = this.bindings.Clone()
Name = this.Name
};
}
@ -86,16 +67,7 @@ namespace OSCADSharp
{
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
@ -109,6 +81,10 @@ namespace OSCADSharp
/// Size of the object in terms of X/Y/Z
/// </summary>
internal Vector3 Size { get; set; }
internal ResizedObject(OSCADObject obj) : base(obj)
{
}
/// <summary>
/// Creates a resized object
@ -117,30 +93,12 @@ namespace OSCADSharp
/// <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)
{
Size = size;
}
public override string ToString()
{
string size = this.bindings.Contains("size") ? this.bindings.Get("size").BoundVariable.Text : this.Size.ToString();
string size = this.Size.ToString();
string resizeCommand = String.Format("resize({0})", size);
var formatter = new SingleBlockFormatter(resizeCommand, this.obj.ToString());
@ -149,13 +107,11 @@ namespace OSCADSharp
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()
Size = this.Size.Clone()
};
}
@ -176,25 +132,6 @@ namespace OSCADSharp
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
@ -207,7 +144,7 @@ namespace OSCADSharp
/// <summary>
/// The angle to rotate, in terms of X/Y/Z euler angles
/// </summary>
internal Vector3 Angle { get; set; } = new BindableVector();
internal Vector3 Angle { get; set; } = new Vector3();
/// <summary>
/// Creates an object with rotation applied
@ -216,26 +153,12 @@ namespace OSCADSharp
/// <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);
this.Angle = angle;
}
public override string ToString()
{
string angle = this.bindings.Contains("angle") ? this.bindings.Get("angle").BoundVariable.Text : this.Angle.ToString();
string angle = this.Angle.ToString();
string rotateCommand = String.Format("rotate({0})", angle.ToString());
var formatter = new SingleBlockFormatter(rotateCommand, this.obj.ToString());
@ -246,8 +169,7 @@ namespace OSCADSharp
{
return new RotatedObject(this.obj.Clone(), this.Angle)
{
Name = this.Name,
bindings = this.bindings.Clone()
Name = this.Name
};
}
@ -262,24 +184,6 @@ namespace OSCADSharp
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
@ -293,7 +197,7 @@ namespace OSCADSharp
/// <summary>
/// The scale factor to be applied
/// </summary>
internal Vector3 ScaleFactor { get; set; } = new BindableVector(1, 1, 1);
internal Vector3 ScaleFactor { get; set; } = new Vector3(1, 1, 1);
/// <summary>
/// Creates a scaled object
@ -302,26 +206,12 @@ namespace OSCADSharp
/// <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);
this.ScaleFactor = scale;
}
public override string ToString()
{
string scale = this.bindings.Contains("scalefactor") ? this.bindings.Get("scalefactor").BoundVariable.Text : this.ScaleFactor.ToString();
string scale = this.ScaleFactor.ToString();
string scaleCommand = String.Format("scale(v = {0})", scale);
var formatter = new SingleBlockFormatter(scaleCommand, this.obj.ToString());
@ -332,8 +222,7 @@ namespace OSCADSharp
{
return new ScaledObject(this.obj.Clone(), this.ScaleFactor)
{
Name = this.Name,
bindings = this.bindings.Clone()
Name = this.Name
};
}
@ -347,24 +236,6 @@ namespace OSCADSharp
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);
}
}
}
@ -385,30 +256,16 @@ namespace OSCADSharp
/// <param name="vector">Amount to translate by</param>
internal TranslatedObject(OSCADObject obj, Vector3 vector) : base(obj)
{
this.Vector = new BindableVector(vector);
this.Vector = 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 translation = this.Vector.ToString();
string translateCommmand = String.Format("translate(v = {0})", translation);
var formatter = new SingleBlockFormatter(translateCommmand, this.obj.ToString());
@ -417,13 +274,10 @@ namespace OSCADSharp
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()
Vector = this.Vector.Clone()
};
return clone;
@ -439,24 +293,6 @@ namespace OSCADSharp
var oldBounds = obj.Bounds();
return new Bounds(oldBounds.BottomLeft + this.Vector, oldBounds.TopRight + this.Vector);
}
private Bindings bindings = new Bindings(new Dictionary<string, string>() {
{ "vector", "vector" }
});
public override void Bind(string property, Variable variable)
{
var bindableVec = this.Vector as BindableVector;
if (bindableVec != null && property == "x" || property == "y" || property == "z")
{
bindableVec.Bind(property, variable);
}
else
{
this.bindings.Add<TranslatedObject>(this, property, variable);
}
}
}
#endregion
}

View File

@ -1,5 +1,4 @@
using OSCADSharp.DataBinding;
using OSCADSharp.IO;
using OSCADSharp.IO;
using OSCADSharp.Spatial;
using OSCADSharp.Utility;
using System;
@ -17,7 +16,7 @@ namespace OSCADSharp
/// Represents any Object or collection of objects that becomes am
/// an OpenSCAD script when converted to a string.
/// </summary>
public abstract partial class OSCADObject : IBindable
public abstract partial class OSCADObject
{
#region Attributes
private readonly int id = Ids.Get();
@ -47,17 +46,6 @@ namespace OSCADSharp
{
return new ColoredObject(this, colorName, opacity);
}
/// <summary>
/// Applies Color and/or Opacity to this object with variable bindings
/// </summary>
/// <param name="colorName">Color name variable to apply</param>
/// <param name="opacity">(optional)Opacity variable</param>
/// <returns>A colored object</returns>
public OSCADObject Color(Variable colorName, Variable opacity = null)
{
return new ColoredObject(this, colorName, opacity);
}
#endregion
#region Mirror
@ -71,16 +59,6 @@ namespace OSCADSharp
{
return new MirroredObject(this, normal);
}
/// <summary>
/// Mirrors the object on a plane represented in a variable
/// </summary>
/// <param name="normal">Variable for the normal vector of the plane</param>
/// <returns>A mirrored object</returns>
public OSCADObject Mirror(Variable normal)
{
return new MirroredObject(this, normal);
}
/// <summary>
/// Mirrors the object about a plane, as specified by the normal
@ -94,90 +72,7 @@ namespace OSCADSharp
{
return this.Mirror(new Vector3(x, y, z));
}
/// <summary>
/// Mirrors an object about a plane with variables for some components of the normal
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <returns>A mirrored object</returns>
public OSCADObject Mirror(Variable x, Variable y, Variable z)
{
return new MirroredObject(this, new Vector3(), x, y, z);
}
/// <summary>
/// Mirrors an object about a plane with variables for some components of the normal
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <returns>A mirrored object</returns>
public OSCADObject Mirror(Variable x, double y, double z)
{
return new MirroredObject(this, new Vector3(0, y, z), x, null, null);
}
/// <summary>
/// Mirrors an object about a plane with variables for some components of the normal
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <returns>A mirrored object</returns>
public OSCADObject Mirror(double x, Variable y, double z)
{
return new MirroredObject(this, new Vector3(x, 0, z), null, y, null);
}
/// <summary>
/// Mirrors an object about a plane with variables for some components of the normal
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <returns>A mirrored object</returns>
public OSCADObject Mirror(double x, double y, Variable z)
{
return new MirroredObject(this, new Vector3(x, y, 0), null, null, z);
}
/// <summary>
/// Mirrors an object about a plane with variables for some components of the normal
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <returns>A mirrored object</returns>
public OSCADObject Mirror(Variable x, Variable y, double z)
{
return new MirroredObject(this, new Vector3(0, 0, z), x, y, null);
}
/// <summary>
/// Mirrors an object about a plane with variables for some components of the normal
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <returns>A mirrored object</returns>
public OSCADObject Mirror(double x, Variable y, Variable z)
{
return new MirroredObject(this, new Vector3(x, 0, 0), null, y, z);
}
/// <summary>
/// Mirrors an object about a plane with variables for some components of the normal
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <returns>A mirrored object</returns>
public OSCADObject Mirror(Variable x, double y, Variable z)
{
return new MirroredObject(this, new Vector3(0, y, 0), x, null, z);
}
#endregion
#region Resize
@ -190,17 +85,7 @@ namespace OSCADSharp
{
return new ResizedObject(this, newsize);
}
/// <summary>
/// Resizes to a specified set of X/Y/Z dimensions using a variable
/// </summary>
/// <param name="newsize">The X/Y/Z dimensions</param>
/// <returns>A resized object</returns>
public OSCADObject Resize(Variable newsize)
{
return new ResizedObject(this, newsize);
}
/// <summary>
/// Resizes to a specified set of X/Y/Z dimensions
/// </summary>
@ -212,90 +97,6 @@ namespace OSCADSharp
{
return this.Resize(new Vector3(x, y, z));
}
/// <summary>
/// Resizes to a specified set of X/Y/Z dimensions using one or more variables
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <returns>A resized object</returns>
public OSCADObject Resize(Variable x, Variable y, Variable z)
{
return new ResizedObject(this, new Vector3(), x, y, z);
}
/// <summary>
/// Resizes to a specified set of X/Y/Z dimensions using one or more variables
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <returns>A resized object</returns>
public OSCADObject Resize(Variable x, double y, double z)
{
return new ResizedObject(this, new Vector3(0, y, z), x, null, null);
}
/// <summary>
/// Resizes to a specified set of X/Y/Z dimensions using one or more variables
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <returns>A resized object</returns>
public OSCADObject Resize(double x, Variable y, double z)
{
return new ResizedObject(this, new Vector3(x, 0, z), null, y, null);
}
/// <summary>
/// Resizes to a specified set of X/Y/Z dimensions using one or more variables
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <returns>A resized object</returns>
public OSCADObject Resize(double x, double y, Variable z)
{
return new ResizedObject(this, new Vector3(x, y, 0), null, null, z);
}
/// <summary>
/// Resizes to a specified set of X/Y/Z dimensions using one or more variables
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <returns>A resized object</returns>
public OSCADObject Resize(Variable x, double y, Variable z)
{
return new ResizedObject(this, new Vector3(0, y, 0), x, null, z);
}
/// <summary>
/// Resizes to a specified set of X/Y/Z dimensions using one or more variables
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <returns>A resized object</returns>
public OSCADObject Resize(double x, Variable y, Variable z)
{
return new ResizedObject(this, new Vector3(x, 0, 0), null, y, z);
}
/// <summary>
/// Resizes to a specified set of X/Y/Z dimensions using one or more variables
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <returns>A resized object</returns>
public OSCADObject Resize(Variable x, Variable y, double z)
{
return new ResizedObject(this, new Vector3(0, 0, z), x, y, null);
}
#endregion
#region Rotate
@ -307,17 +108,7 @@ namespace OSCADSharp
public OSCADObject Rotate(Vector3 angle)
{
return new RotatedObject(this, angle);
}
/// <summary>
/// Rotates about a specified X/Y/Z euler angle variable
/// </summary>
/// <param name="angle">The angle(s) to rotate</param>
/// <returns>A rotated object</returns>
public OSCADObject Rotate(Variable angle)
{
return new RotatedObject(this, angle);
}
}
/// <summary>
/// Rotates about a specified X/Y/Z euler angle
@ -329,91 +120,7 @@ namespace OSCADSharp
public OSCADObject Rotate(double x, double y, double z)
{
return this.Rotate(new Vector3(x, y, z));
}
/// <summary>
/// Rotates about a specified X/Y/Z euler variables
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <returns>A rotated object</returns>
public OSCADObject Rotate(Variable x, Variable y, Variable z)
{
return new RotatedObject(this, new Vector3(), x, y, z);
}
/// <summary>
/// Rotates about a specified X/Y/Z euler with one or more variables
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <returns>A rotated object</returns>
public OSCADObject Rotate(Variable x, double y, double z)
{
return new RotatedObject(this, new Vector3(0, y, z), x, null, null);
}
/// <summary>
/// Rotates about a specified X/Y/Z euler with one or more variables
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <returns>A rotated object</returns>
public OSCADObject Rotate(double x, Variable y, double z)
{
return new RotatedObject(this, new Vector3(x, 0, z), null, y, null);
}
/// <summary>
/// Rotates about a specified X/Y/Z euler with one or more variables
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <returns>A rotated object</returns>
public OSCADObject Rotate(double x, double y, Variable z)
{
return new RotatedObject(this, new Vector3(x, y, 0), null, null, z);
}
/// <summary>
/// Rotates about a specified X/Y/Z euler with one or more variables
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <returns>A rotated object</returns>
public OSCADObject Rotate(Variable x, double y, Variable z)
{
return new RotatedObject(this, new Vector3(0, y, 0), x, null, z);
}
/// <summary>
/// Rotates about a specified X/Y/Z euler with one or more variables
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <returns>A rotated object</returns>
public OSCADObject Rotate(double x, Variable y, Variable z)
{
return new RotatedObject(this, new Vector3(x, 0, 0), null, y, z);
}
/// <summary>
/// Rotates about a specified X/Y/Z euler with one or more variables
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <returns>A rotated object</returns>
public OSCADObject Rotate(Variable x, Variable y, double z)
{
return new RotatedObject(this, new Vector3(0, 0, z), x, y, null);
}
}
#endregion
#region Scale
@ -427,16 +134,6 @@ namespace OSCADSharp
return new ScaledObject(this, scale);
}
/// <summary>
/// Rescales an object by an X/Y/Z scale factor variable
/// </summary>
/// <param name="scale">The scale to apply. For example 1, 2, 1 would yield 2x scale on the Y axis</param>
/// <returns>A scaled object</returns>
public OSCADObject Scale(Variable scale)
{
return new ScaledObject(this, scale);
}
/// <summary>
/// Rescales an object by an X/Y/Z scale factor
/// </summary>
@ -448,90 +145,6 @@ namespace OSCADSharp
{
return this.Scale(new Vector3(x, y, z));
}
/// <summary>
/// Rescales an object by an X/Y/Z scale factor variables
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <returns>A scaled object</returns>
public OSCADObject Scale(Variable x, Variable y, Variable z)
{
return new ScaledObject(this, new Vector3(), x, y, z);
}
/// <summary>
/// Rescales an object by one or more X/Y/Z scale factor variables
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <returns>A scaled object</returns>
public OSCADObject Scale(Variable x, double y, double z)
{
return new ScaledObject(this, new Vector3(0, y, z), x, null, null);
}
/// <summary>
/// Rescales an object by one or more X/Y/Z scale factor variables
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <returns>A scaled object</returns>
public OSCADObject Scale(double x, Variable y, double z)
{
return new ScaledObject(this, new Vector3(x, 0, z), null, y, null);
}
/// <summary>
/// Rescales an object by one or more X/Y/Z scale factor variables
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <returns>A scaled object</returns>
public OSCADObject Scale(double x, double y, Variable z)
{
return new ScaledObject(this, new Vector3(x, y, 0), null, null, z);
}
/// <summary>
/// Rescales an object by one or more X/Y/Z scale factor variables
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <returns>A scaled object</returns>
public OSCADObject Scale(Variable x, double y, Variable z)
{
return new ScaledObject(this, new Vector3(0, y, 0), x, null, z);
}
/// <summary>
/// Rescales an object by one or more X/Y/Z scale factor variables
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <returns>A scaled object</returns>
public OSCADObject Scale(double x, Variable y, Variable z)
{
return new ScaledObject(this, new Vector3(x, 0, 0), null, y, z);
}
/// <summary>
/// Rescales an object by one or more X/Y/Z scale factor variables
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <returns>A scaled object</returns>
public OSCADObject Scale(Variable x, Variable y, double z)
{
return new ScaledObject(this, new Vector3(0, 0, z), x, y, null);
}
#endregion
#region Translate
@ -544,17 +157,7 @@ namespace OSCADSharp
{
return new TranslatedObject(this, translation);
}
/// <summary>
/// Translates an object by the specified amount with a variable
/// </summary>
/// <param name="translation">The vector upon which to translate (move object(s))</param>
/// <returns>A translated object</returns>
public OSCADObject Translate(Variable translation)
{
return new TranslatedObject(this, translation);
}
/// <summary>
/// Translates an object by the specified amount
/// </summary>
@ -565,91 +168,7 @@ namespace OSCADSharp
public OSCADObject Translate(double x, double y, double z)
{
return this.Translate(new Vector3(x, y, z));
}
/// <summary>
/// Translates an object by the specified amount with one or more variables
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <returns>A translated object</returns>
public OSCADObject Translate(Variable x, Variable y, Variable z)
{
return new TranslatedObject(this, new Vector3(), x, y, z);
}
/// <summary>
/// Translates an object by the specified amount with one or more variables
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <returns>A translated object</returns>
public OSCADObject Translate(Variable x, double y, double z)
{
return new TranslatedObject(this, new Vector3(0, y, z), x, null, null);
}
/// <summary>
/// Translates an object by the specified amount with one or more variables
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <returns>A translated object</returns>
public OSCADObject Translate(double x, Variable y, double z)
{
return new TranslatedObject(this, new Vector3(x, 0, z), null, y, null);
}
/// <summary>
/// Translates an object by the specified amount with one or more variables
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <returns>A translated object</returns>
public OSCADObject Translate(double x, double y, Variable z)
{
return new TranslatedObject(this, new Vector3(x, y, 0), null, null, z);
}
/// <summary>
/// Translates an object by the specified amount with one or more variables
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <returns>A translated object</returns>
public OSCADObject Translate(Variable x, double y, Variable z)
{
return new TranslatedObject(this, new Vector3(0, y, 0), x, null, z);
}
/// <summary>
/// Translates an object by the specified amount with one or more variables
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <returns>A translated object</returns>
public OSCADObject Translate(double x, Variable y, Variable z)
{
return new TranslatedObject(this, new Vector3(x, 0, 0), null, y, z);
}
/// <summary>
/// Translates an object by the specified amount with one or more variables
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <returns>A translated object</returns>
public OSCADObject Translate(Variable x, Variable y, double z)
{
return new TranslatedObject(this, new Vector3(0, 0, z), x, y, null);
}
}
#endregion
#region Minkowski/Hull
@ -766,17 +285,7 @@ namespace OSCADSharp
/// The parent of this object in its OSCADObject tree
/// </summary>
internal OSCADObject Parent { get; set; }
/// <summary>
/// If the variable is not null, binds it to the property specified
/// </summary>
/// <param name="property"></param>
/// <param name="variable"></param>
internal void BindIfVariableNotNull(string property, Variable variable)
{
if (variable != null)
this.Bind(property, variable);
}
/// <summary>
/// Internal collection of children for this object
@ -843,20 +352,11 @@ namespace OSCADSharp
Dependencies.FileWriter.WriteAllLines(path, new string[]
{
OutputSettings.OSCADSharpHeader,
Variables.Global.ToString(),
this.ToString()
});
return Dependencies.FileInvokerFactory(path);
}
/// <summary>
/// Binds a a variable to a property on this object
/// </summary>
/// <param name="property">A string specifying the property such as "Diameter" or "Radius"</param>
/// <param name="variable">The variable to bind the to. This variable will appear in script output in lieu of the
/// literal value of the property</param>
public abstract void Bind(string property, Variable variable);
}
#endregion
#region Operators

View File

@ -43,7 +43,6 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="DataBinding\BindableBoolean.cs" />
<Compile Include="OSCADObject.AbstractTransforms.cs" />
<Compile Include="OSCADObject.BaseTransform.cs" />
<Compile Include="OSCADObject.BasicTransforms.cs" />
@ -64,14 +63,9 @@
<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" />
@ -82,7 +76,6 @@
<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" />

View File

@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OSCADSharp.DataBinding;
using OSCADSharp.Spatial;
namespace OSCADSharp.Solids.Compound
@ -88,16 +87,6 @@ namespace OSCADSharp.Solids.Compound
return box.ToString();
}
/// <summary>
/// Binds a a variable to a property on this object
/// </summary>
/// <param name="property">A string specifying the property such as "Diameter" or "Radius"</param>
/// <param name="variable">The variable to bind the to. This variable will appear in script output in lieu of the
/// literal value of the property</param>
public override void Bind(string property, Variable variable)
{
throw new NotImplementedException();
}
/// <summary>
/// Returns the approximate boundaries of this OpenSCAD object

View File

@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OSCADSharp.DataBinding;
using OSCADSharp.Spatial;
namespace OSCADSharp.Solids.Compound
@ -151,16 +150,6 @@ namespace OSCADSharp.Solids.Compound
return cyl.ToString();
}
/// <summary>
/// Binds a a variable to a property on this object
/// </summary>
/// <param name="property">A string specifying the property such as "Diameter" or "Radius"</param>
/// <param name="variable">The variable to bind the to. This variable will appear in script output in lieu of the
/// literal value of the property</param>
public override void Bind(string property, Variable variable)
{
throw new NotImplementedException();
}
/// <summary>
/// Returns the approximate boundaries of this OpenSCAD object

View File

@ -1,5 +1,4 @@
using OSCADSharp.DataBinding;
using OSCADSharp.Spatial;
using OSCADSharp.Spatial;
using System;
using System.Collections.Generic;
using System.Linq;
@ -14,33 +13,18 @@ namespace OSCADSharp.Solids
public class Cube : OSCADObject
{
#region Attributes
private Vector3 size = new BindableVector(1, 1, 1, sizeSynonyms);
private bool center = false;
private BindableBoolean centerBinding = new BindableBoolean("center");
/// <summary>
/// The Size of the cube in terms of X/Y/Z units
/// </summary>
public Vector3 Size
{
get { return this.size; }
set { this.size = new BindableVector(value, sizeSynonyms); }
}
public Vector3 Size { get; set; } = new Vector3(1, 1, 1);
/// <summary>
/// If True, the center of the cube will be at 0, 0, 0
///
/// If False (default) one corner will be centered at 0,0, 0, with the cube extending into the positive octant (positive X/Y/Z)
/// </summary>
public bool Center
{
get { return this.center; }
set
{
this.center = value;
this.centerBinding.InnerValue = this.center.ToString().ToLower();
}
}
public bool Center { get; set; } = false;
#endregion
#region Constructors
@ -58,7 +42,7 @@ namespace OSCADSharp.Solids
/// <param name="center">Indicates whether the cube should be centered on the origin</param>
public Cube(Vector3 size = null, bool center = false)
{
this.Size = new BindableVector(size, sizeSynonyms) ?? new BindableVector(1, 1, 1, sizeSynonyms);
this.Size = size ?? new Vector3(1, 1, 1);
this.Center = center;
}
@ -77,21 +61,6 @@ namespace OSCADSharp.Solids
this.Center = center;
}
/// <summary>
/// Creates a new Cube object with variable bindings
/// </summary>
/// <param name="length">Size on the X axis</param>
/// <param name="width">Size on the Y axis</param>
/// <param name="height">Size on the Z axis</param>
/// <param name="center">Indicates whether the cube should be centered on the origin</param>
public Cube(Variable length = null, Variable width = null, Variable height = null, Variable center = null)
{
this.BindIfVariableNotNull("length", length);
this.BindIfVariableNotNull("width", width);
this.BindIfVariableNotNull("height", height);
this.BindIfVariableNotNull("center", center);
}
#endregion
#region Overrides
@ -101,10 +70,7 @@ namespace OSCADSharp.Solids
/// <returns>Script for this object</returns>
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(),
Environment.NewLine); ;
return String.Format("cube(size = {0}, center = {1}); {2}", this.Size.ToString(), this.Center.ToString().ToLower(), Environment.NewLine);
}
/// <summary>
@ -113,16 +79,11 @@ namespace OSCADSharp.Solids
/// <returns></returns>
public override OSCADObject Clone()
{
var size = this.size as BindableVector;
var center = this.centerBinding.Clone();
var clone = new Cube()
{
Name = this.Name,
size = size.Clone(),
center = this.Center,
centerBinding = center,
bindings = this.bindings.Clone()
Size = this.Size.Clone(),
Center = this.Center,
};
return clone;
@ -164,46 +125,6 @@ namespace OSCADSharp.Solids
new Vector3(this.Size.X / 2, this.Size.Y / 2, this.Size.Z / 2));
}
}
private Bindings bindings = new Bindings();
private static readonly Dictionary<string, string> sizeSynonyms = new Dictionary<string, string>()
{
{"size.x", "x" },
{"size.y", "y" },
{"size.z", "z" },
{"length", "x" },
{"width", "y" },
{"height", "z" }
};
/// <summary>
/// Binds a a variable to a property on this object
/// </summary>
/// <param name="property">A string specifying the property such as "Diameter" or "Radius"</param>
/// <param name="variable">The variable to bind the to. This variable will appear in script output in lieu of the
/// literal value of the property</param>
public override void Bind(string property, Variable variable)
{
if (sizeSynonyms.ContainsKey(property.ToLower()))
{
BindableVector vec;
if (this.size is BindableVector)
vec = this.Size as BindableVector;
else
vec = new BindableVector(this.size);
vec.Bind(property, variable);
}
else if (property.ToLower() == "center")
{
this.centerBinding.Bind(property, variable);
this.center = Convert.ToBoolean(variable.Value);
}
else
{
throw new KeyNotFoundException(String.Format("No bindable property matching the name {0} was found", property));
}
}
#endregion
}
}

View File

@ -1,5 +1,4 @@
using OSCADSharp.DataBinding;
using OSCADSharp.Spatial;
using OSCADSharp.Spatial;
using OSCADSharp.Utility;
using System;
using System.Collections.Generic;
@ -15,9 +14,6 @@ namespace OSCADSharp.Solids
public class Cylinder : OSCADObject
{
#region Attributes
private bool center = false;
private BindableBoolean centerBinding = new BindableBoolean("center");
/// <summary>
/// Height of the cylinder or cone
/// </summary>
@ -80,15 +76,7 @@ namespace OSCADSharp.Solids
/// false: (default), z ranges from 0 to h
/// true: z ranges from -h/2 to +h/2
/// </summary>
public bool Center
{
get { return this.center; }
set
{
this.center = value;
this.centerBinding.InnerValue = this.center.ToString().ToLower();
}
}
public bool Center { get; set; } = false;
/// <summary>
/// Minimum angle (in degrees) of each cylinder fragment.
@ -129,28 +117,6 @@ namespace OSCADSharp.Solids
this.Height = height;
this.Center = center;
}
/// <summary>
/// Creates a cylinder with one or more pre-bound variables
/// </summary>
/// <param name="diameter1"></param>
/// <param name="diameter2"></param>
/// <param name="height"></param>
/// <param name="center"></param>
/// <param name="resolution"></param>
/// <param name="minimumangle"></param>
/// <param name="minimumcircumferentiallength"></param>
public Cylinder(Variable diameter1 = null, Variable diameter2 = null, Variable height = null,
Variable center = null, Variable resolution = null, Variable minimumangle = null, Variable minimumcircumferentiallength = null)
{
this.BindIfVariableNotNull("diameter1", diameter1);
this.BindIfVariableNotNull("diameter2", diameter2);
this.BindIfVariableNotNull("height", height);
this.BindIfVariableNotNull("center", center);
this.BindIfVariableNotNull("resolution", resolution);
this.BindIfVariableNotNull("minimumangle", minimumangle);
this.BindIfVariableNotNull("minimumcircumferentiallength", minimumcircumferentiallength);
}
#endregion
#region Overrides
@ -160,9 +126,9 @@ namespace OSCADSharp.Solids
/// <returns>Script for this object</returns>
public override string ToString()
{
var sb = new StatementBuilder(this.bindings);
var sb = new StatementBuilder();
sb.Append("cylinder(");
sb.AppendValuePairIfExists("center", this.centerBinding.IsBound ? this.centerBinding.ToString() : this.center.ToString().ToLower());
sb.AppendValuePairIfExists("center", this.Center.ToString().ToLower());
appendDiameterAndRadius(sb);
@ -177,29 +143,8 @@ namespace OSCADSharp.Solids
private void appendDiameterAndRadius(StatementBuilder sb)
{
if (bindings.Contains("d"))
{
sb.AppendValuePairIfExists("d", this.Diameter, true);
}
else if (bindings.Contains("r"))
{
sb.AppendValuePairIfExists("r", this.Radius, true);
}
else if (bindings.Contains("d1") || bindings.Contains("d2"))
{
sb.AppendValuePairIfExists("d1", this.Diameter1, true);
sb.AppendValuePairIfExists("d2", this.Diameter2, true);
}
else if (bindings.Contains("r1") || bindings.Contains("r2"))
{
sb.AppendValuePairIfExists("r1", this.Radius1, true);
sb.AppendValuePairIfExists("r2", this.Radius2, true);
}
else
{
sb.AppendValuePairIfExists("r1", this.Radius1, true);
sb.AppendValuePairIfExists("r2", this.Radius2, true);
}
}
/// <summary>
@ -218,8 +163,6 @@ namespace OSCADSharp.Solids
MinimumAngle = this.MinimumAngle,
MinimumCircumferentialLength = this.MinimumCircumferentialLength,
Center = this.Center,
centerBinding = this.centerBinding,
bindings = this.bindings.Clone()
};
}
@ -260,39 +203,6 @@ namespace OSCADSharp.Solids
new Vector3(this.Radius, this.Radius, this.Height / 2));
}
}
private Bindings bindings = new Bindings(new Dictionary<string, string>()
{
{"radius", "r" },
{"radius1", "r1" },
{"radius2", "r2" },
{"diameter", "d" },
{"diameter1", "d1" },
{"diameter2", "d2" },
{"height", "h" },
{"resolution", "$fn" },
{"minimumangle", "$fa" },
{"minimumcircumferentiallength", "$fs" }
});
/// <summary>
/// Binds a a variable to a property on this object
/// </summary>
/// <param name="property">A string specifying the property such as "Diameter" or "Radius"</param>
/// <param name="variable">The variable to bind the to. This variable will appear in script output in lieu of the
/// literal value of the property</param>
public override void Bind(string property, Variable variable)
{
if (property.ToLower() == "center")
{
this.centerBinding.Bind(property, variable);
this.center = Convert.ToBoolean(variable.Value);
}
else
{
this.bindings.Add<Cylinder>(this, property, variable);
}
}
#endregion
}
}

View File

@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OSCADSharp.DataBinding;
using OSCADSharp.Spatial;
using System.Drawing;
using OSCADSharp.Utility.Images;
@ -54,16 +53,6 @@ namespace OSCADSharp.Solids.Imported
#endregion
#region OSCADObject Overrides
/// <summary>
/// Imported images have no bindable properties
/// </summary>
/// <param name="property"></param>
/// <param name="variable"></param>
public override void Bind(string property, Variable variable)
{
throw new NotSupportedException("Imported images have no bindable properties");
}
/// <summary>
/// Returns the approximate boundaries of this OpenSCAD object
/// </summary>

View File

@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OSCADSharp.DataBinding;
using OSCADSharp.Spatial;
using System.IO;
@ -56,16 +55,6 @@ namespace OSCADSharp.Solids.Imported
#endregion
#region OSCADObject Overrides
/// <summary>
/// Binds the specified property to a variable
/// </summary>
/// <param name="property"></param>
/// <param name="variable"></param>
public override void Bind(string property, Variable variable)
{
//No bindable properties on an imported model
}
/// <summary>
/// Returns the approximate boundaries of this OpenSCAD object
/// </summary>

View File

@ -6,7 +6,6 @@ using System.Threading.Tasks;
using System.Collections.Concurrent;
using System.Reflection;
using OSCADSharp.Spatial;
using OSCADSharp.DataBinding;
using OSCADSharp.Utility;
namespace OSCADSharp.Solids
@ -65,22 +64,7 @@ namespace OSCADSharp.Solids
public Sphere(double diameter)
{
this.Diameter = diameter;
}
/// <summary>
/// Creates a sphere with one more more pre-bound properties
/// </summary>
/// <param name="diameter"></param>
/// <param name="resolution"></param>
/// <param name="minimumAngle"></param>
/// <param name="minimumFragmentSize"></param>
public Sphere(Variable diameter = null, Variable resolution = null, Variable minimumAngle = null, Variable minimumFragmentSize = null)
{
this.BindIfVariableNotNull("diameter", diameter);
this.BindIfVariableNotNull("resolution", resolution);
this.BindIfVariableNotNull("minimumangle", minimumAngle);
this.BindIfVariableNotNull("minimumfragmentsize", minimumFragmentSize);
}
}
#endregion
#region Overrides
@ -90,18 +74,9 @@ namespace OSCADSharp.Solids
/// <returns>Script for this object</returns>
public override string ToString()
{
StatementBuilder sb = new StatementBuilder(this.bindings);
StatementBuilder sb = new StatementBuilder();
sb.Append("sphere(");
if (this.bindings.Contains("d"))
{
sb.AppendValuePairIfExists("d", this.Diameter);
}
else
{
sb.AppendValuePairIfExists("r", this.Radius);
}
sb.AppendValuePairIfExists("r", this.Radius);
sb.AppendValuePairIfExists("$fn", this.Resolution, true);
sb.AppendValuePairIfExists("$fa", this.MinimumAngle, true);
sb.AppendValuePairIfExists("$fs", this.MinimumFragmentSize, true);
@ -123,8 +98,7 @@ namespace OSCADSharp.Solids
Resolution = this.Resolution,
MinimumAngle = this.MinimumAngle,
MinimumFragmentSize = this.MinimumFragmentSize,
Radius = this.Radius,
bindings = this.bindings.Clone()
Radius = this.Radius
};
}
@ -147,26 +121,6 @@ namespace OSCADSharp.Solids
return new Bounds(new Vector3(-this.Radius, -this.Radius, -this.Radius),
new Vector3(this.Radius, this.Radius, this.Radius));
}
private Bindings bindings = new Bindings(new Dictionary<string, string>()
{
{ "radius", "r" },
{ "minimumangle", "$fa" },
{ "minimumfragmentsize", "$fs" },
{ "resolution", "$fn" },
{ "diameter", "d" }
});
/// <summary>
/// Binds a a variable to a property on this object
/// </summary>
/// <param name="property">A string specifying the property such as "Diameter" or "Radius"</param>
/// <param name="variable">The variable to bind the to. This variable will appear in script output in lieu of the
/// literal value of the property</param>
public override void Bind(string property, Variable variable)
{
this.bindings.Add<Sphere>(this, property, variable);
}
#endregion
}
}

View File

@ -1,5 +1,4 @@
using OSCADSharp.DataBinding;
using OSCADSharp.Spatial;
using OSCADSharp.Spatial;
using OSCADSharp.Utility;
using System;
using System.Collections.Generic;
@ -69,26 +68,6 @@ namespace OSCADSharp.Solids
this.Text = text;
this.Size = size;
}
/// <summary>
/// Creates a 3d text object with pre-bound variables
/// </summary>
/// <param name="text"></param>
/// <param name="size"></param>
/// <param name="font"></param>
/// <param name="spacing"></param>
/// <param name="language"></param>
/// <param name="textdirection"></param>
public Text3D(Variable text = null, Variable size = null, Variable font = null,
Variable spacing = null, Variable language = null, Variable textdirection = null)
{
this.BindIfVariableNotNull("text", text);
this.BindIfVariableNotNull("size", size);
this.BindIfVariableNotNull("font", font);
this.BindIfVariableNotNull("spacing", spacing);
this.BindIfVariableNotNull("language", language);
this.BindIfVariableNotNull("textdirection", textdirection);
}
#endregion
#region Overrides
@ -106,8 +85,7 @@ namespace OSCADSharp.Solids
Font = this.Font,
Spacing = this.Spacing,
TextDirection = this.TextDirection,
Language = this.Language,
bindings = this.bindings.Clone()
Language = this.Language
};
}
@ -117,18 +95,10 @@ namespace OSCADSharp.Solids
/// <returns>Script for this object</returns>
public override string ToString()
{
StatementBuilder sb = new StatementBuilder(this.bindings);
StatementBuilder sb = new StatementBuilder();
sb.Append("text(");
sb.Append("\"");
if (this.bindings.Contains("text"))
{
sb.Append(this.bindings.Get("text").BoundVariable.Text);
}
else
{
sb.Append(this.Text);
}
sb.Append(this.Text);
sb.Append("\"");
sb.AppendValuePairIfExists("size", this.Size?.ToString(), true);
@ -168,28 +138,7 @@ namespace OSCADSharp.Solids
public override Bounds Bounds()
{
throw new NotSupportedException("Bounds are not supported for objects using Text3D");
}
private Bindings bindings = new Bindings(new Dictionary<string, string>()
{
{ "text", "text" },
{ "size", "size" },
{ "font", "font" },
{ "spacing", "spacing" },
{ "textdirection", "direction" },
{ "language", "language" }
});
/// <summary>
/// Binds a a variable to a property on this object
/// </summary>
/// <param name="property">A string specifying the property such as "Diameter" or "Radius"</param>
/// <param name="variable">The variable to bind the to. This variable will appear in script output in lieu of the
/// literal value of the property</param>
public override void Bind(string property, Variable variable)
{
this.bindings.Add<Text3D>(this, property, variable);
}
}
#endregion
}
}

View File

@ -1,5 +1,4 @@
using OSCADSharp.DataBinding;
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -14,12 +13,6 @@ namespace OSCADSharp.Utility
internal class StatementBuilder
{
private StringBuilder SB { get; set; } = new StringBuilder();
private readonly Bindings bindings = null;
internal StatementBuilder(Bindings bindings)
{
this.bindings = bindings;
}
/// <summary>
/// Special append method for conditionally adding value-pairs
@ -27,10 +20,8 @@ namespace OSCADSharp.Utility
/// <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>
internal void AppendValuePairIfExists(string name, object value, bool prefixWithComma = false)
public void AppendValuePairIfExists(string name, object value, bool prefixWithComma = false)
{
bool useBinding = this.shouldUseBinding(name);
if (!String.IsNullOrEmpty(value?.ToString()))
{
if (prefixWithComma)
@ -40,32 +31,28 @@ namespace OSCADSharp.Utility
SB.Append(name);
SB.Append(" = ");
if (useBinding)
{
SB.Append(this.bindings.Get(name).BoundVariable.Text);
}
else
{
SB.Append(value);
}
SB.Append(value);
}
}
private bool shouldUseBinding(string name)
{
return this.bindings != null && this.bindings.Contains(name);
}
/// <summary>
/// Pass-through for StringBuilder.Append
/// </summary>
/// <param name="text"></param>
internal void Append(string text)
public 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>