From 0e47d85f426cf8d600ca37319b5713269cf25375 Mon Sep 17 00:00:00 2001 From: Michael L Smith Date: Mon, 22 Feb 2016 19:22:04 -0800 Subject: [PATCH 1/9] + Added StatementBuilder for use in places where we'll be doing a lot more conditional output construction. --- OSCADSharp/OSCADSharp/OSCADSharp.csproj | 1 + .../OSCADSharp/Scripting/StatementBuilder.cs | 64 +++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 OSCADSharp/OSCADSharp/Scripting/StatementBuilder.cs diff --git a/OSCADSharp/OSCADSharp/OSCADSharp.csproj b/OSCADSharp/OSCADSharp/OSCADSharp.csproj index 23a88dd..6a7f166 100644 --- a/OSCADSharp/OSCADSharp/OSCADSharp.csproj +++ b/OSCADSharp/OSCADSharp/OSCADSharp.csproj @@ -43,6 +43,7 @@ + diff --git a/OSCADSharp/OSCADSharp/Scripting/StatementBuilder.cs b/OSCADSharp/OSCADSharp/Scripting/StatementBuilder.cs new file mode 100644 index 0000000..3498a90 --- /dev/null +++ b/OSCADSharp/OSCADSharp/Scripting/StatementBuilder.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OSCADSharp.Scripting +{ + /// + /// Extends the capabilities of StringBuilder with domain-specific behavior + /// + internal class StatementBuilder + { + private StringBuilder SB { get; set; } = new StringBuilder(); + + /// + /// Special append method for conditionally adding value-pairs + /// + /// The Name of the value-pair + /// The value - if null this method does nothing + /// (optional) Flag indicating whether a comma should be added before the value-pair + public void AppendValuePairIfExists(string name, object value, bool prefixWithComma = false) + { + if (!String.IsNullOrEmpty(value?.ToString())) + { + if (prefixWithComma) + { + SB.Append(", "); + } + + SB.Append(name); + SB.Append("="); + SB.Append(value); + } + } + + /// + /// Pass-through for StringBuilder.Append + /// + /// + public void Append(string text) + { + SB.Append(text); + } + + /// + /// Pass-through for StringBuilder.AppendLine + /// + /// + public void AppendLine(string text) + { + SB.AppendLine(text); + } + + /// + /// Gets this builder's full string + /// + /// + public override string ToString() + { + return SB.ToString(); + } + } +} From ddb0a319c9d4da487cc1b7f2a733ce9ef7a0b9b7 Mon Sep 17 00:00:00 2001 From: Michael L Smith Date: Mon, 22 Feb 2016 20:12:04 -0800 Subject: [PATCH 2/9] + Refactored Text3D to use StatementBuilder --- OSCADSharp/OSCADSharp.ConsoleTests/Program.cs | 9 ++++----- OSCADSharp/OSCADSharp/Solids/Text3D.cs | 16 ++++++++-------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/OSCADSharp/OSCADSharp.ConsoleTests/Program.cs b/OSCADSharp/OSCADSharp.ConsoleTests/Program.cs index 19291b8..14dea4f 100644 --- a/OSCADSharp/OSCADSharp.ConsoleTests/Program.cs +++ b/OSCADSharp/OSCADSharp.ConsoleTests/Program.cs @@ -14,8 +14,7 @@ namespace OSCADSharp.ConsoleTests static void Main(string[] args) { - var obj = new Cube(5, 5, 20) - .Translate(30, 0, 0).Rotate(0, 90, 0).Resize(2, 2, 2); + var obj = new Text3D("Whaat is thissss?"); var pos = obj.Position(); var cyl1 = new Cylinder(1, 100, true).Translate(pos); @@ -23,10 +22,10 @@ namespace OSCADSharp.ConsoleTests var cyl3 = new Cylinder(1, 100, true).Rotate(90, 0, 0).Translate(pos); var axisHelper = cyl1.Union(cyl2, cyl3).Color("Red"); - var topCorner = new Sphere().Translate(obj.Bounds().TopRight); - var botCorner = new Sphere().Translate(obj.Bounds().BottomLeft); + //var topCorner = new Sphere().Translate(obj.Bounds().TopRight); + //var botCorner = new Sphere().Translate(obj.Bounds().BottomLeft); - (obj + topCorner + botCorner + axisHelper).ToFile("test.scad"); + (obj + axisHelper).ToFile("test.scad"); //Console.ReadKey(); } diff --git a/OSCADSharp/OSCADSharp/Solids/Text3D.cs b/OSCADSharp/OSCADSharp/Solids/Text3D.cs index 888da34..a41a9dc 100644 --- a/OSCADSharp/OSCADSharp/Solids/Text3D.cs +++ b/OSCADSharp/OSCADSharp/Solids/Text3D.cs @@ -107,22 +107,22 @@ namespace OSCADSharp.Solids /// Script for this object public override string ToString() { - StringBuilder sb = new StringBuilder(); + StatementBuilder sb = new StatementBuilder(); sb.Append("text("); sb.Append("\""); sb.Append(this.Text); sb.Append("\""); - appendIfValueNotNullOrEmpty("size", this.Size?.ToString(), sb); + sb.AppendValuePairIfExists("size", this.Size?.ToString(), true); // Text is always centered in OSCADSharp to ensure correctness of // position interpolation - appendIfValueNotNullOrEmpty("halign", "\"center\"", sb); - appendIfValueNotNullOrEmpty("valign", "\"center\"", sb); + sb.AppendValuePairIfExists("halign", "\"center\"", true); + sb.AppendValuePairIfExists("valign", "\"center\"", true); - appendIfValueNotNullOrEmpty("font", this.Font, sb); - appendIfValueNotNullOrEmpty("spacing", this.Spacing?.ToString(), sb); - appendIfValueNotNullOrEmpty("direction", this.TextDirection?.ToString(), sb); - appendIfValueNotNullOrEmpty("language", this.Language?.ToString(), sb); + sb.AppendValuePairIfExists("font", this.Font, true); + sb.AppendValuePairIfExists("spacing", this.Spacing?.ToString(), true); + sb.AppendValuePairIfExists("direction", this.TextDirection?.ToString(), true); + sb.AppendValuePairIfExists("language", this.Language?.ToString(), true); sb.Append(");"); sb.Append(Environment.NewLine); From 3a7875ee510c72cf90144d5a53ff4c47d2356029 Mon Sep 17 00:00:00 2001 From: Michael L Smith Date: Mon, 22 Feb 2016 20:36:15 -0800 Subject: [PATCH 3/9] + Reworked Cylinder so that if $f* values are omitted, they don't appear in output. --- .../Solids/CylinderTests.cs | 29 +++++++++++++++++++ .../OSCADSharp/Scripting/StatementBuilder.cs | 2 +- OSCADSharp/OSCADSharp/Solids/Cylinder.cs | 22 ++++++++++---- OSCADSharp/OSCADSharp/Solids/Text3D.cs | 1 + 4 files changed, 47 insertions(+), 7 deletions(-) diff --git a/OSCADSharp/OSCADSharp.UnitTests/Solids/CylinderTests.cs b/OSCADSharp/OSCADSharp.UnitTests/Solids/CylinderTests.cs index b1acbce..5e441f5 100644 --- a/OSCADSharp/OSCADSharp.UnitTests/Solids/CylinderTests.cs +++ b/OSCADSharp/OSCADSharp.UnitTests/Solids/CylinderTests.cs @@ -57,5 +57,34 @@ namespace OSCADSharp.UnitTests Assert.AreEqual(new Vector3(2.5, 2.5, 10), obj.Bounds().TopRight); Assert.AreEqual(new Vector3(-2.5, -2.5, -10), obj.Bounds().BottomLeft); } + + [TestMethod] + public void Cylinder_ScriptOutputDoesNotContainResolutionValuesIfNotSpecified() + { + var cylinder = new Cylinder(); + + string script = cylinder.ToString(); + + Assert.IsTrue(!script.Contains("$fn")); + Assert.IsTrue(!script.Contains("$fa")); + Assert.IsTrue(!script.Contains("$fs")); + } + + [TestMethod] + public void Cylinder_ScriptOutpuHasResolutionValuesIfSpecified() + { + var cylinder = new Cylinder() + { + Resolution = 40, + MinimumAngle = 5, + MinimumCircumferentialLength = 2 + }; + + string script = cylinder.ToString(); + + Assert.IsTrue(script.Contains("$fn")); + Assert.IsTrue(script.Contains("$fa")); + Assert.IsTrue(script.Contains("$fs")); + } } } diff --git a/OSCADSharp/OSCADSharp/Scripting/StatementBuilder.cs b/OSCADSharp/OSCADSharp/Scripting/StatementBuilder.cs index 3498a90..30171ad 100644 --- a/OSCADSharp/OSCADSharp/Scripting/StatementBuilder.cs +++ b/OSCADSharp/OSCADSharp/Scripting/StatementBuilder.cs @@ -29,7 +29,7 @@ namespace OSCADSharp.Scripting } SB.Append(name); - SB.Append("="); + SB.Append(" = "); SB.Append(value); } } diff --git a/OSCADSharp/OSCADSharp/Solids/Cylinder.cs b/OSCADSharp/OSCADSharp/Solids/Cylinder.cs index 5fe08b8..a70fc47 100644 --- a/OSCADSharp/OSCADSharp/Solids/Cylinder.cs +++ b/OSCADSharp/OSCADSharp/Solids/Cylinder.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using OSCADSharp.Spatial; +using OSCADSharp.Scripting; namespace OSCADSharp.Solids { @@ -81,19 +82,19 @@ namespace OSCADSharp.Solids /// Minimum angle (in degrees) of each cylinder fragment. /// ($fa in OpenSCAD) /// - public int MinimumAngle { get; set; } = 12; + public int? MinimumAngle { get; set; } /// /// Minimum circumferential length of each fragment. /// ($fs in OpenSCAD) /// - public int MinimumCircumferentialLength { get; set; } = 2; + public int? MinimumCircumferentialLength { get; set; } /// /// Number of fragments in 360 degrees. Values of 3 or more override MinimumAngle and MinimumCircumferentialLength /// ($fn in OpenSCAD) /// - public int Resolution { get; set; } = 0; + public int? Resolution { get; set; } #endregion #region Constructors @@ -125,9 +126,18 @@ namespace OSCADSharp.Solids /// Script for this object public override string ToString() { - return String.Format("cylinder($fn = {0}, $fa = {1}, $fs = {2}, h = {3}, r1 = {4}, r2 = {5}, center = {6}); {7}", - Resolution.ToString(), MinimumAngle.ToString(), MinimumCircumferentialLength.ToString(), - Height.ToString(), Radius1.ToString(), Radius2.ToString(), Center.ToString().ToLower(), Environment.NewLine); + var sb = new StatementBuilder(); + sb.Append("cylinder("); + sb.AppendValuePairIfExists("center", this.Center.ToString().ToLower()); + sb.AppendValuePairIfExists("r1", this.Radius1, true); + sb.AppendValuePairIfExists("r2", this.Radius2, true); + sb.AppendValuePairIfExists("h", this.Height, true); + sb.AppendValuePairIfExists("$fn", this.Resolution, true); + sb.AppendValuePairIfExists("$fa", this.MinimumAngle, true); + sb.AppendValuePairIfExists("$fs", this.MinimumCircumferentialLength, true); + sb.Append(");"); + sb.Append(Environment.NewLine); + return sb.ToString(); } /// diff --git a/OSCADSharp/OSCADSharp/Solids/Text3D.cs b/OSCADSharp/OSCADSharp/Solids/Text3D.cs index a41a9dc..40045cd 100644 --- a/OSCADSharp/OSCADSharp/Solids/Text3D.cs +++ b/OSCADSharp/OSCADSharp/Solids/Text3D.cs @@ -145,6 +145,7 @@ namespace OSCADSharp.Solids /// /// Returns the approximate boundaries of this OpenSCAD object + /// /// public override Bounds Bounds() { From a4613ea79dc7789b1c19313e9f47ef6bc68690ab Mon Sep 17 00:00:00 2001 From: Michael L Smith Date: Tue, 23 Feb 2016 17:47:36 -0800 Subject: [PATCH 4/9] + Reworked Sphere to use StatementBuilder as well to conditionally output $f* values --- OSCADSharp/OSCADSharp.ConsoleTests/Program.cs | 2 +- .../Solids/SphereTests.cs | 29 +++++++++++++++++++ OSCADSharp/OSCADSharp/Solids/Sphere.cs | 20 +++++++++---- 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/OSCADSharp/OSCADSharp.ConsoleTests/Program.cs b/OSCADSharp/OSCADSharp.ConsoleTests/Program.cs index 14dea4f..b6a77fa 100644 --- a/OSCADSharp/OSCADSharp.ConsoleTests/Program.cs +++ b/OSCADSharp/OSCADSharp.ConsoleTests/Program.cs @@ -14,7 +14,7 @@ namespace OSCADSharp.ConsoleTests static void Main(string[] args) { - var obj = new Text3D("Whaat is thissss?"); + var obj = new Sphere(30); var pos = obj.Position(); var cyl1 = new Cylinder(1, 100, true).Translate(pos); diff --git a/OSCADSharp/OSCADSharp.UnitTests/Solids/SphereTests.cs b/OSCADSharp/OSCADSharp.UnitTests/Solids/SphereTests.cs index 2cc55d3..e0c5509 100644 --- a/OSCADSharp/OSCADSharp.UnitTests/Solids/SphereTests.cs +++ b/OSCADSharp/OSCADSharp.UnitTests/Solids/SphereTests.cs @@ -86,5 +86,34 @@ namespace OSCADSharp.UnitTests Assert.AreEqual(new Vector3(15, 15, 15), obj.Bounds().TopRight); Assert.AreEqual(new Vector3(-15, -15, -15), obj.Bounds().BottomLeft); } + + [TestMethod] + public void Sphere_ScriptOutputDoesNotContainResolutionValuesIfNotSpecified() + { + var sphere = new Sphere(); + + string script = sphere.ToString(); + + Assert.IsTrue(!script.Contains("$fn")); + Assert.IsTrue(!script.Contains("$fa")); + Assert.IsTrue(!script.Contains("$fs")); + } + + [TestMethod] + public void Sphere_ScriptOutpuHasResolutionValuesIfSpecified() + { + var sphere = new Sphere() + { + Resolution = 40, + MinimumAngle = 5, + MinimumFragmentSize = 2 + }; + + string script = sphere.ToString(); + + Assert.IsTrue(script.Contains("$fn")); + Assert.IsTrue(script.Contains("$fa")); + Assert.IsTrue(script.Contains("$fs")); + } } } diff --git a/OSCADSharp/OSCADSharp/Solids/Sphere.cs b/OSCADSharp/OSCADSharp/Solids/Sphere.cs index 766decb..20d2d56 100644 --- a/OSCADSharp/OSCADSharp/Solids/Sphere.cs +++ b/OSCADSharp/OSCADSharp/Solids/Sphere.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using OSCADSharp.Spatial; +using OSCADSharp.Scripting; namespace OSCADSharp.Solids { @@ -30,19 +31,19 @@ namespace OSCADSharp.Solids /// Minimum angle (in degrees) of each cylinder fragment. /// ($fa in OpenSCAD) /// - public int MinimumAngle { get; set; } = 12; + public int? MinimumAngle { get; set; } /// /// Fragment size in mm /// ($fs in OpenSCAD) /// - public int MinimumFragmentSize { get; set; } = 2; + public int? MinimumFragmentSize { get; set; } /// /// Number of fragments in 360 degrees. Values of 3 or more override MinimumAngle and MinimumCircumferentialLength /// ($fn in OpenSCAD) /// - public int Resolution { get; set; } = 0; + public int? Resolution { get; set; } #endregion #region Constructors @@ -70,9 +71,16 @@ namespace OSCADSharp.Solids /// Script for this object public override string ToString() { - return String.Format("sphere($fn = {0}, $fa = {1}, $fs = {2}, r = {3});{4}", - this.Resolution.ToString(), this.MinimumAngle.ToString(), - this.MinimumFragmentSize.ToString(), this.Radius.ToString(), Environment.NewLine); + StatementBuilder sb = new StatementBuilder(); + sb.Append("sphere("); + sb.AppendValuePairIfExists("r", this.Radius); + sb.AppendValuePairIfExists("$fn", this.Resolution, true); + sb.AppendValuePairIfExists("$fa", this.MinimumAngle, true); + sb.AppendValuePairIfExists("$fs", this.MinimumFragmentSize, true); + sb.Append(");"); + sb.Append(Environment.NewLine); + + return sb.ToString(); } /// From 85064599399228bcbaff043dceb4b6476eb156e2 Mon Sep 17 00:00:00 2001 From: Michael L Smith Date: Tue, 23 Feb 2016 18:02:24 -0800 Subject: [PATCH 5/9] + Added internal Parent reference / made assignments to it when operations occur --- OSCADSharp/OSCADSharp/OSCADObject.cs | 5 +++++ OSCADSharp/OSCADSharp/Scripting/MultiBlockStatementObject.cs | 4 ++++ OSCADSharp/OSCADSharp/Transforms/ColoredObject.cs | 1 + OSCADSharp/OSCADSharp/Transforms/LinearExtrudedObject.cs | 1 + OSCADSharp/OSCADSharp/Transforms/MirroredObject.cs | 1 + OSCADSharp/OSCADSharp/Transforms/ResizedObject.cs | 1 + OSCADSharp/OSCADSharp/Transforms/RotatedObject.cs | 1 + OSCADSharp/OSCADSharp/Transforms/ScaledObject.cs | 1 + OSCADSharp/OSCADSharp/Transforms/TranslatedObject.cs | 1 + 9 files changed, 16 insertions(+) diff --git a/OSCADSharp/OSCADSharp/OSCADObject.cs b/OSCADSharp/OSCADSharp/OSCADObject.cs index 3a41ad7..5201a46 100644 --- a/OSCADSharp/OSCADSharp/OSCADObject.cs +++ b/OSCADSharp/OSCADSharp/OSCADObject.cs @@ -262,6 +262,11 @@ namespace OSCADSharp return this.ToString() == other.ToString(); } + /// + /// The parent of this object in its OSCADObject tree + /// + internal OSCADObject Parent { get; set; } + /// /// Internal collection of children for this object /// diff --git a/OSCADSharp/OSCADSharp/Scripting/MultiBlockStatementObject.cs b/OSCADSharp/OSCADSharp/Scripting/MultiBlockStatementObject.cs index f1a8c7c..8faa9d7 100644 --- a/OSCADSharp/OSCADSharp/Scripting/MultiBlockStatementObject.cs +++ b/OSCADSharp/OSCADSharp/Scripting/MultiBlockStatementObject.cs @@ -20,6 +20,10 @@ namespace OSCADSharp.Scripting { this.outerStatement = outerStatement; this.children = children.ToList(); + foreach (var child in children) + { + child.Parent = this; + } } public override string ToString() diff --git a/OSCADSharp/OSCADSharp/Transforms/ColoredObject.cs b/OSCADSharp/OSCADSharp/Transforms/ColoredObject.cs index 1d57142..9f02c14 100644 --- a/OSCADSharp/OSCADSharp/Transforms/ColoredObject.cs +++ b/OSCADSharp/OSCADSharp/Transforms/ColoredObject.cs @@ -33,6 +33,7 @@ namespace OSCADSharp.Transforms this.Opacity = opacity; this.children.Add(obj); + obj.Parent = this; } public override string ToString() diff --git a/OSCADSharp/OSCADSharp/Transforms/LinearExtrudedObject.cs b/OSCADSharp/OSCADSharp/Transforms/LinearExtrudedObject.cs index 0467bb6..0f6900c 100644 --- a/OSCADSharp/OSCADSharp/Transforms/LinearExtrudedObject.cs +++ b/OSCADSharp/OSCADSharp/Transforms/LinearExtrudedObject.cs @@ -35,6 +35,7 @@ namespace OSCADSharp.Transforms this.Height = height; this.children.Add(obj); + obj.Parent = this; } public override OSCADObject Clone() diff --git a/OSCADSharp/OSCADSharp/Transforms/MirroredObject.cs b/OSCADSharp/OSCADSharp/Transforms/MirroredObject.cs index 68796d2..7cad6ca 100644 --- a/OSCADSharp/OSCADSharp/Transforms/MirroredObject.cs +++ b/OSCADSharp/OSCADSharp/Transforms/MirroredObject.cs @@ -32,6 +32,7 @@ namespace OSCADSharp.Transforms this.Normal = normal; this.children.Add(obj); + obj.Parent = this; } public override string ToString() diff --git a/OSCADSharp/OSCADSharp/Transforms/ResizedObject.cs b/OSCADSharp/OSCADSharp/Transforms/ResizedObject.cs index 6cb5b03..f8eff1a 100644 --- a/OSCADSharp/OSCADSharp/Transforms/ResizedObject.cs +++ b/OSCADSharp/OSCADSharp/Transforms/ResizedObject.cs @@ -30,6 +30,7 @@ namespace OSCADSharp.Transforms this.Size = size; this.children.Add(obj); + obj.Parent = this; } public override string ToString() diff --git a/OSCADSharp/OSCADSharp/Transforms/RotatedObject.cs b/OSCADSharp/OSCADSharp/Transforms/RotatedObject.cs index 460123d..616b78f 100644 --- a/OSCADSharp/OSCADSharp/Transforms/RotatedObject.cs +++ b/OSCADSharp/OSCADSharp/Transforms/RotatedObject.cs @@ -30,6 +30,7 @@ namespace OSCADSharp.Transforms this.Angle = angle; this.children.Add(obj); + obj.Parent = this; } public override string ToString() diff --git a/OSCADSharp/OSCADSharp/Transforms/ScaledObject.cs b/OSCADSharp/OSCADSharp/Transforms/ScaledObject.cs index 5bcee35..e4d230e 100644 --- a/OSCADSharp/OSCADSharp/Transforms/ScaledObject.cs +++ b/OSCADSharp/OSCADSharp/Transforms/ScaledObject.cs @@ -30,6 +30,7 @@ namespace OSCADSharp.Transforms this.ScaleFactor = scale; this.children.Add(obj); + obj.Parent = this; } public override string ToString() diff --git a/OSCADSharp/OSCADSharp/Transforms/TranslatedObject.cs b/OSCADSharp/OSCADSharp/Transforms/TranslatedObject.cs index a1cd635..b8445f3 100644 --- a/OSCADSharp/OSCADSharp/Transforms/TranslatedObject.cs +++ b/OSCADSharp/OSCADSharp/Transforms/TranslatedObject.cs @@ -27,6 +27,7 @@ namespace OSCADSharp.Transforms this.Vector = vector; this.children.Add(obj); + obj.Parent = this; } public override string ToString() From 4532e7b20d41a4e6c17ef9a0dfaa1f172c21b90f Mon Sep 17 00:00:00 2001 From: Michael L Smith Date: Tue, 23 Feb 2016 19:14:50 -0800 Subject: [PATCH 6/9] Added Variables class, Settings class, settings/header output in OSCADObject.ToFile --- OSCADSharp/OSCADSharp.ConsoleTests/Program.cs | 1 + OSCADSharp/OSCADSharp/OSCADObject.cs | 7 +- OSCADSharp/OSCADSharp/OSCADSharp.csproj | 2 + OSCADSharp/OSCADSharp/Scripting/Variables.cs | 67 +++++++++++++++++++ OSCADSharp/OSCADSharp/Settings.cs | 27 ++++++++ 5 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 OSCADSharp/OSCADSharp/Scripting/Variables.cs create mode 100644 OSCADSharp/OSCADSharp/Settings.cs diff --git a/OSCADSharp/OSCADSharp.ConsoleTests/Program.cs b/OSCADSharp/OSCADSharp.ConsoleTests/Program.cs index b6a77fa..c1b74b7 100644 --- a/OSCADSharp/OSCADSharp.ConsoleTests/Program.cs +++ b/OSCADSharp/OSCADSharp.ConsoleTests/Program.cs @@ -14,6 +14,7 @@ namespace OSCADSharp.ConsoleTests static void Main(string[] args) { + Settings.Globals["$fn"] = 100; var obj = new Sphere(30); var pos = obj.Position(); diff --git a/OSCADSharp/OSCADSharp/OSCADObject.cs b/OSCADSharp/OSCADSharp/OSCADObject.cs index 5201a46..67d2ab6 100644 --- a/OSCADSharp/OSCADSharp/OSCADObject.cs +++ b/OSCADSharp/OSCADSharp/OSCADObject.cs @@ -329,7 +329,12 @@ namespace OSCADSharp path += ".scad"; } - File.WriteAllLines(path, new string[] { this.ToString() }); + File.WriteAllLines(path, new string[] + { + Settings.OSCADSharpHeader, + Settings.Globals.ToString(), + this.ToString() + }); } #endregion diff --git a/OSCADSharp/OSCADSharp/OSCADSharp.csproj b/OSCADSharp/OSCADSharp/OSCADSharp.csproj index 6a7f166..ae770d1 100644 --- a/OSCADSharp/OSCADSharp/OSCADSharp.csproj +++ b/OSCADSharp/OSCADSharp/OSCADSharp.csproj @@ -44,6 +44,7 @@ + @@ -68,6 +69,7 @@ + diff --git a/OSCADSharp/OSCADSharp/Scripting/Variables.cs b/OSCADSharp/OSCADSharp/Scripting/Variables.cs new file mode 100644 index 0000000..1a47561 --- /dev/null +++ b/OSCADSharp/OSCADSharp/Scripting/Variables.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OSCADSharp.Scripting +{ + /// + /// A collection of names/values for variables + /// + public sealed class Variables + { + private Dictionary variables = new Dictionary(); + + /// + /// Assigns or gets a variable's value + /// + /// + /// + public object this[string name] // long is a 64-bit integer + { + get + { + if (variables.ContainsKey(name)) + { + return variables[name]; + } + else + { + return null; + } + } + set + { + variables[name] = value; + } + } + + /// + /// This class is intended for use in other externally-exposed classes, + /// as such its constructor is not public. + /// + internal Variables() + { + } + + /// + /// Gets the string representation for all variables + /// + /// + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + foreach (var kvp in this.variables) + { + sb.Append(kvp.Key); + sb.Append(" = "); + sb.Append(kvp.Value); + sb.Append(";"); + sb.Append(Environment.NewLine); + } + + return sb.ToString(); + } + } +} diff --git a/OSCADSharp/OSCADSharp/Settings.cs b/OSCADSharp/OSCADSharp/Settings.cs new file mode 100644 index 0000000..3886f99 --- /dev/null +++ b/OSCADSharp/OSCADSharp/Settings.cs @@ -0,0 +1,27 @@ +using OSCADSharp.Scripting; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OSCADSharp +{ + /// + /// Settings for OpenSCAD scripts + /// + public static class Settings + { + /// + /// Code-gen header + /// + public static readonly string OSCADSharpHeader = String.Format("/*Code Generated using OSCADSharp on {0}. {1}{2}For more information, please visit https://github.com/Exolun/OSCADSharp */{3}", + DateTime.Now.ToString(), Environment.NewLine, Environment.NewLine, Environment.NewLine); + + /// + /// Global variables that can be assigned for output at the + /// top of OpenSCAD scripts + /// + public static Variables Globals = new Variables(); + } +} From 7e5160d701fae81298ba75e9d44d09db07432109 Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Tue, 23 Feb 2016 21:59:17 -0800 Subject: [PATCH 7/9] Extracted IFileWriter for OSCADObject.ToFile Included default implementation for IFileWriter and replaceable reference in Settings.cs --- OSCADSharp/OSCADSharp/OSCADObject.cs | 4 ++-- OSCADSharp/OSCADSharp/OSCADSharp.csproj | 2 ++ .../OSCADSharp/Scripting/DefaultFileWriter.cs | 17 +++++++++++++++ .../OSCADSharp/Scripting/IFileWriter.cs | 21 +++++++++++++++++++ OSCADSharp/OSCADSharp/Settings.cs | 5 +++++ 5 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 OSCADSharp/OSCADSharp/Scripting/DefaultFileWriter.cs create mode 100644 OSCADSharp/OSCADSharp/Scripting/IFileWriter.cs diff --git a/OSCADSharp/OSCADSharp/OSCADObject.cs b/OSCADSharp/OSCADSharp/OSCADObject.cs index 67d2ab6..3e8b537 100644 --- a/OSCADSharp/OSCADSharp/OSCADObject.cs +++ b/OSCADSharp/OSCADSharp/OSCADObject.cs @@ -328,8 +328,8 @@ namespace OSCADSharp { path += ".scad"; } - - File.WriteAllLines(path, new string[] + + Settings.FileWriter.WriteAllLines(path, new string[] { Settings.OSCADSharpHeader, Settings.Globals.ToString(), diff --git a/OSCADSharp/OSCADSharp/OSCADSharp.csproj b/OSCADSharp/OSCADSharp/OSCADSharp.csproj index ae770d1..1b7c5b0 100644 --- a/OSCADSharp/OSCADSharp/OSCADSharp.csproj +++ b/OSCADSharp/OSCADSharp/OSCADSharp.csproj @@ -42,6 +42,8 @@ + + diff --git a/OSCADSharp/OSCADSharp/Scripting/DefaultFileWriter.cs b/OSCADSharp/OSCADSharp/Scripting/DefaultFileWriter.cs new file mode 100644 index 0000000..05ae2e4 --- /dev/null +++ b/OSCADSharp/OSCADSharp/Scripting/DefaultFileWriter.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OSCADSharp.Scripting +{ + internal class DefaultFileWriter : IFileWriter + { + public void WriteAllLines(string path, string[] contents) + { + File.WriteAllLines(path, contents); + } + } +} diff --git a/OSCADSharp/OSCADSharp/Scripting/IFileWriter.cs b/OSCADSharp/OSCADSharp/Scripting/IFileWriter.cs new file mode 100644 index 0000000..afdbb46 --- /dev/null +++ b/OSCADSharp/OSCADSharp/Scripting/IFileWriter.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OSCADSharp.Scripting +{ + /// + /// A class that takes text and writes to file + /// + public interface IFileWriter + { + /// + /// Writes lines of text to a file at the path specified + /// + /// + /// + void WriteAllLines(string path, string[] contents); + } +} diff --git a/OSCADSharp/OSCADSharp/Settings.cs b/OSCADSharp/OSCADSharp/Settings.cs index 3886f99..d6b183f 100644 --- a/OSCADSharp/OSCADSharp/Settings.cs +++ b/OSCADSharp/OSCADSharp/Settings.cs @@ -23,5 +23,10 @@ namespace OSCADSharp /// top of OpenSCAD scripts /// public static Variables Globals = new Variables(); + + /// + /// Used to write scripts to file + /// + public static IFileWriter FileWriter = new DefaultFileWriter(); } } From 05e73130b61f04b2fcef4d7d569503af09955145 Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Tue, 23 Feb 2016 22:00:56 -0800 Subject: [PATCH 8/9] Added Moq to UnitTests project via NuGet --- .../OSCADSharp.UnitTests/OSCADSharp.UnitTests.csproj | 7 +++++++ OSCADSharp/OSCADSharp.UnitTests/packages.config | 4 ++++ 2 files changed, 11 insertions(+) create mode 100644 OSCADSharp/OSCADSharp.UnitTests/packages.config diff --git a/OSCADSharp/OSCADSharp.UnitTests/OSCADSharp.UnitTests.csproj b/OSCADSharp/OSCADSharp.UnitTests/OSCADSharp.UnitTests.csproj index a1e5ecc..83c374d 100644 --- a/OSCADSharp/OSCADSharp.UnitTests/OSCADSharp.UnitTests.csproj +++ b/OSCADSharp/OSCADSharp.UnitTests/OSCADSharp.UnitTests.csproj @@ -35,6 +35,10 @@ 4 + + ..\packages\Moq.4.2.1510.2205\lib\net40\Moq.dll + True + @@ -75,6 +79,9 @@ OSCADSharp + + + diff --git a/OSCADSharp/OSCADSharp.UnitTests/packages.config b/OSCADSharp/OSCADSharp.UnitTests/packages.config new file mode 100644 index 0000000..f8429b5 --- /dev/null +++ b/OSCADSharp/OSCADSharp.UnitTests/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file From 0237d9f35b23d4f1bba2511a39f2913d02c38f8e Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Wed, 24 Feb 2016 00:53:41 -0800 Subject: [PATCH 9/9] Mocked some FileWriters for settings output tests. --- .../OSCADSharp.UnitTests/OSCADObjectTests.cs | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/OSCADSharp/OSCADSharp.UnitTests/OSCADObjectTests.cs b/OSCADSharp/OSCADSharp.UnitTests/OSCADObjectTests.cs index e64a2a8..de5cb5f 100644 --- a/OSCADSharp/OSCADSharp.UnitTests/OSCADObjectTests.cs +++ b/OSCADSharp/OSCADSharp.UnitTests/OSCADObjectTests.cs @@ -1,4 +1,6 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; +using OSCADSharp.Scripting; using OSCADSharp.Solids; using System; using System.Collections.Concurrent; @@ -135,6 +137,39 @@ namespace OSCADSharp.UnitTests Assert.AreEqual("Text", children[0].Name); Assert.AreEqual("Union", children[1].Name); } + + [TestMethod] + public void OSCADObject_ToFileIncludesOSCADSharpGeneratedHeader() + { + var cube = new Cube(); + string[] output = null; + + var mock = new Mock(); + mock.Setup(_wrtr => _wrtr.WriteAllLines(It.IsAny(), It.IsAny())) + .Callback((path, contents) => { output = contents; }); + Settings.FileWriter = mock.Object; + + cube.ToFile("myFile"); + + Assert.AreEqual(Settings.OSCADSharpHeader, output[0]); + } + + [TestMethod] + public void OSCADObject_ToFileIncludesGlobalVariablesDefinedInSettings() + { + var cube = new Cube(); + string[] output = null; + Settings.Globals["$fn"] = 100; + + var mock = new Mock(); + mock.Setup(_wrtr => _wrtr.WriteAllLines(It.IsAny(), It.IsAny())) + .Callback((path, contents) => { output = contents; }); + Settings.FileWriter = mock.Object; + + cube.ToFile("myFile"); + + Assert.AreEqual("$fn = 100;\r\n", output[1]); + } } }