diff --git a/OSCADSharp/OSCADSharp.UnitTests/Solids/CylinderTests.cs b/OSCADSharp/OSCADSharp.UnitTests/Solids/CylinderTests.cs index 5e441f5..fd9b5ea 100644 --- a/OSCADSharp/OSCADSharp.UnitTests/Solids/CylinderTests.cs +++ b/OSCADSharp/OSCADSharp.UnitTests/Solids/CylinderTests.cs @@ -1,4 +1,5 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; +using OSCADSharp.Scripting; using OSCADSharp.Solids; using System; using System.Collections.Generic; @@ -86,5 +87,97 @@ 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.Name))); + Assert.IsTrue(script.Contains(String.Format("r2 = {0}", radius2.Name))); + } + + [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.Name))); + Assert.IsTrue(script.Contains(String.Format("d2 = {0}", d2.Name))); + } + + [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.Name))); + Assert.IsFalse(script.Contains(String.Format("d = {0}", diameter.Name))); + + obj.Bind("Diameter", diameter); + + script = obj.ToString(); + + Assert.AreEqual(Convert.ToDouble(diameter.Value), obj.Diameter); + Assert.IsTrue(script.Contains(String.Format("d = {0}", diameter.Name))); + Assert.IsFalse(script.Contains(String.Format("r = {0}", radius.Name))); + } + + [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")); + } } } diff --git a/OSCADSharp/OSCADSharp/Bindings/Bindings.cs b/OSCADSharp/OSCADSharp/Bindings/Bindings.cs index 62ac29f..92f75a0 100644 --- a/OSCADSharp/OSCADSharp/Bindings/Bindings.cs +++ b/OSCADSharp/OSCADSharp/Bindings/Bindings.cs @@ -98,7 +98,7 @@ namespace OSCADSharp.Bindings { if (!this.hasMapping(propertyName)) { - throw new KeyNotFoundException(String.Format("No bindable property matching the name {0} was found")); + throw new KeyNotFoundException(String.Format("No bindable property matching the name {0} was found", propertyName)); } //Assign mapping r -> radius -> variable diff --git a/OSCADSharp/OSCADSharp/Solids/Cube.cs b/OSCADSharp/OSCADSharp/Solids/Cube.cs index 57cf5a7..f9fd5f1 100644 --- a/OSCADSharp/OSCADSharp/Solids/Cube.cs +++ b/OSCADSharp/OSCADSharp/Solids/Cube.cs @@ -173,12 +173,15 @@ namespace OSCADSharp.Solids vec.Bind(property, variable); } - - if(property.ToLower() == "center") + 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 } diff --git a/OSCADSharp/OSCADSharp/Solids/Cylinder.cs b/OSCADSharp/OSCADSharp/Solids/Cylinder.cs index a70fc47..db68537 100644 --- a/OSCADSharp/OSCADSharp/Solids/Cylinder.cs +++ b/OSCADSharp/OSCADSharp/Solids/Cylinder.cs @@ -5,15 +5,19 @@ using System.Text; using System.Threading.Tasks; using OSCADSharp.Spatial; using OSCADSharp.Scripting; +using OSCADSharp.Bindings; namespace OSCADSharp.Solids { /// /// A Cylinder geometry /// - public class Cylinder : OSCADObject + public class Cylinder : OSCADObject, IBindable { #region Attributes + private bool center = false; + private BindableBoolean centerBinding = new BindableBoolean("center"); + /// /// Height of the cylinder or cone /// @@ -76,7 +80,15 @@ namespace OSCADSharp.Solids /// false: (default), z ranges from 0 to h /// true: z ranges from -h/2 to +h/2 /// - public bool Center { get; set; } = false; + public bool Center + { + get { return this.center; } + set + { + this.center = value; + this.centerBinding.InnerValue = this.center.ToString().ToLower(); + } + } /// /// Minimum angle (in degrees) of each cylinder fragment. @@ -126,11 +138,12 @@ namespace OSCADSharp.Solids /// Script for this object public override string ToString() { - var sb = new StatementBuilder(); + var sb = new StatementBuilder(this.bindings); sb.Append("cylinder("); - sb.AppendValuePairIfExists("center", this.Center.ToString().ToLower()); - sb.AppendValuePairIfExists("r1", this.Radius1, true); - sb.AppendValuePairIfExists("r2", this.Radius2, true); + sb.AppendValuePairIfExists("center", this.centerBinding.IsBound ? this.centerBinding.ToString() : this.center.ToString().ToLower()); + + appendDiameterAndRadius(sb); + sb.AppendValuePairIfExists("h", this.Height, true); sb.AppendValuePairIfExists("$fn", this.Resolution, true); sb.AppendValuePairIfExists("$fa", this.MinimumAngle, true); @@ -140,6 +153,33 @@ namespace OSCADSharp.Solids return sb.ToString(); } + 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); + } + } + /// /// Gets a copy of this object that is a new instance /// @@ -196,6 +236,37 @@ namespace OSCADSharp.Solids new Vector3(this.Radius, this.Radius, this.Height / 2)); } } + + private Bindings.Bindings bindings = new Bindings.Bindings(new Dictionary() + { + {"radius", "r" }, + {"radius1", "r1" }, + {"radius2", "r2" }, + {"diameter", "d" }, + {"diameter1", "d1" }, + {"diameter2", "d2" }, + {"resolution", "$fn" }, + {"minimumangle", "$fa" }, + {"minimumcircumferentiallength", "$fs" } + }); + /// + /// Binds a a variable to a property on this object + /// + /// A string specifying the property such as "Diameter" or "Radius" + /// The variable to bind the to. This variable will appear in script output in lieu of the + /// literal value of the property + public 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(this, property, variable); + } + } #endregion } }