From 5afc0ed51792c3c1df480d19b2073093ccbfa6fe Mon Sep 17 00:00:00 2001 From: Michael L Smith Date: Sat, 5 Mar 2016 22:09:11 -0800 Subject: [PATCH] Added variable operators + one test so far --- .../Transforms/TranslateTests.cs | 15 ++++ OSCADSharp/OSCADSharp/OSCADSharp.csproj | 1 + OSCADSharp/OSCADSharp/Scripting/Variable.cs | 48 +++++++++++- .../Scripting/VariableCalculator.cs | 73 +++++++++++++++++++ OSCADSharp/OSCADSharp/Spatial/Vector3.cs | 22 ++++++ 5 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 OSCADSharp/OSCADSharp/Scripting/VariableCalculator.cs diff --git a/OSCADSharp/OSCADSharp.UnitTests/Transforms/TranslateTests.cs b/OSCADSharp/OSCADSharp.UnitTests/Transforms/TranslateTests.cs index e763866..e1442ec 100644 --- a/OSCADSharp/OSCADSharp.UnitTests/Transforms/TranslateTests.cs +++ b/OSCADSharp/OSCADSharp.UnitTests/Transforms/TranslateTests.cs @@ -47,5 +47,20 @@ namespace OSCADSharp.UnitTests.Transforms 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]")); + } } } diff --git a/OSCADSharp/OSCADSharp/OSCADSharp.csproj b/OSCADSharp/OSCADSharp/OSCADSharp.csproj index 4619df6..2d14881 100644 --- a/OSCADSharp/OSCADSharp/OSCADSharp.csproj +++ b/OSCADSharp/OSCADSharp/OSCADSharp.csproj @@ -43,6 +43,7 @@ + diff --git a/OSCADSharp/OSCADSharp/Scripting/Variable.cs b/OSCADSharp/OSCADSharp/Scripting/Variable.cs index 1420b33..dd2100d 100644 --- a/OSCADSharp/OSCADSharp/Scripting/Variable.cs +++ b/OSCADSharp/OSCADSharp/Scripting/Variable.cs @@ -42,6 +42,52 @@ namespace OSCADSharp.Scripting public override string ToString() { return string.Format("{0} = {1}", this.Name, this.Value.ToString()); - } + } + + #region Operators + /// + /// Adds two variables together + /// + /// + /// + /// + public static Variable operator +(Variable left, Variable right) + { + return new Variable(String.Format("{0} + {1}", left.Name, right.Name), VariableCalculator.Add(left.Value, right.Value)); + } + + /// + /// Subtracts two variables + /// + /// + /// + /// + public static Variable operator -(Variable left, Variable right) + { + return new Variable(String.Format("{0} - {1}", left.Name, right.Name), VariableCalculator.Subtract(left.Value, right.Value)); + } + + /// + /// Multiplies two variables + /// + /// + /// + /// + public static Variable operator *(Variable left, Variable right) + { + return new Variable(String.Format("{0} * {1}", left.Name, right.Name), VariableCalculator.Multiply(left.Value, right.Value)); + } + + /// + /// Divides two variables + /// + /// + /// + /// + public static Variable operator /(Variable left, Variable right) + { + return new Variable(String.Format("{0} / {1}", left.Name, right.Name), VariableCalculator.Divide(left.Value, right.Value)); + } + #endregion } } diff --git a/OSCADSharp/OSCADSharp/Scripting/VariableCalculator.cs b/OSCADSharp/OSCADSharp/Scripting/VariableCalculator.cs new file mode 100644 index 0000000..0dc40b6 --- /dev/null +++ b/OSCADSharp/OSCADSharp/Scripting/VariableCalculator.cs @@ -0,0 +1,73 @@ +using OSCADSharp.Bindings; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Threading.Tasks; + +namespace OSCADSharp.Scripting +{ + internal static class VariableCalculator + { + private static bool isNumeric(object value) + { + return value is int || value is double || value is float || value is decimal; + } + + private 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>(expr).Compile()(); + if (isVector(left) || isVector(right)) + result = Expression.Lambda>(expr).Compile()(); + + return result; + } + + private static BinaryExpression makeExpression(Func 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); + } + } +} diff --git a/OSCADSharp/OSCADSharp/Spatial/Vector3.cs b/OSCADSharp/OSCADSharp/Spatial/Vector3.cs index 3c4d3bf..f510029 100644 --- a/OSCADSharp/OSCADSharp/Spatial/Vector3.cs +++ b/OSCADSharp/OSCADSharp/Spatial/Vector3.cs @@ -212,6 +212,28 @@ namespace OSCADSharp { return new Vector3(left * right.X, left * right.Y, left * right.Z); } + + /// + /// Divides a vector by a double + /// + /// + /// + /// + public static Vector3 operator /(Vector3 left, double right) + { + return new Vector3(left.X / right, left.Y / right, left.Z / right); + } + + /// + /// Divides a vector by a double + /// + /// + /// + /// + public static Vector3 operator /(double left, Vector3 right) + { + return new Vector3(left / right.X, left / right.Y, left / right.Z); + } #endregion internal Matrix ToMatrix()