diff --git a/ExampleFiles/Components/LocalAxes.gh b/ExampleFiles/Components/LocalAxes.gh new file mode 100644 index 000000000..85df7bc60 Binary files /dev/null and b/ExampleFiles/Components/LocalAxes.gh differ diff --git a/GsaGH/Components/0_Model/GetGeometry.cs b/GsaGH/Components/0_Model/GetGeometry.cs index f82ed2fce..f6e041991 100644 --- a/GsaGH/Components/0_Model/GetGeometry.cs +++ b/GsaGH/Components/0_Model/GetGeometry.cs @@ -19,6 +19,7 @@ using OasysUnits.Serialization.JsonNet; using OasysUnits.Units; using Rhino.Geometry; +using System.Collections.ObjectModel; namespace GsaGH.Components { @@ -90,8 +91,9 @@ public class SolveResults internal ConcurrentBag Mem2ds { get; set; } internal ConcurrentBag Mem3ds { get; set; } } + SolveResults Compute( - ConcurrentDictionary allnDict, + ConcurrentDictionary allnDict, ConcurrentDictionary axDict, ConcurrentDictionary nDict, ConcurrentDictionary eDict, @@ -100,7 +102,8 @@ SolveResults Compute( ConcurrentDictionary pDict, ConcurrentDictionary p3Dict, ConcurrentDictionary amDict, - ConcurrentDictionary modDict + ConcurrentDictionary modDict, + ConcurrentDictionary> localAxesDict ) { SolveResults results = new SolveResults(); @@ -121,7 +124,7 @@ ConcurrentDictionary modDict { // create elements Tuple, ConcurrentBag, ConcurrentBag> elementTuple - = Util.Gsa.FromGSA.GetElements(eDict, allnDict, sDict, pDict, p3Dict, amDict, modDict, LengthUnit); + = Util.Gsa.FromGSA.GetElements(eDict, allnDict, sDict, pDict, p3Dict, amDict, modDict, localAxesDict, LengthUnit); results.Elem1ds = elementTuple.Item1; results.Elem2ds = elementTuple.Item2; @@ -132,7 +135,7 @@ Tuple, ConcurrentBag, Concurrent { // create members Tuple, ConcurrentBag, ConcurrentBag> memberTuple - = Util.Gsa.FromGSA.GetMembers(mDict, allnDict, LengthUnit, sDict, pDict, p3Dict, this); + = Util.Gsa.FromGSA.GetMembers(mDict, allnDict, LengthUnit, sDict, pDict, p3Dict, localAxesDict, this); results.Mem1ds = memberTuple.Item1; results.Mem2ds = memberTuple.Item2; @@ -293,8 +296,13 @@ protected override void SolveInstance(IGH_DataAccess data) ConcurrentDictionary amDict = new ConcurrentDictionary(model.AnalysisMaterials()); ConcurrentDictionary modDict = new ConcurrentDictionary(model.SectionModifiers()); + // populate local axes dictionary + ConcurrentDictionary> localAxesDict = new ConcurrentDictionary>(); + foreach(int id in eDict.Keys) + localAxesDict.TryAdd(id, model.ElementDirectionCosine(id)); + tsk = Task.Run(() => Compute(nDict, axDict, out_nDict, - eDict, mDict, sDict, pDict, p3Dict, amDict, modDict), CancelToken); + eDict, mDict, sDict, pDict, p3Dict, amDict, modDict, localAxesDict), CancelToken); } // Add a null task even if data collection fails. This keeps the // list size in sync with the iterations @@ -345,8 +353,13 @@ protected override void SolveInstance(IGH_DataAccess data) ConcurrentDictionary amDict = new ConcurrentDictionary(model.AnalysisMaterials()); ConcurrentDictionary modDict = new ConcurrentDictionary(model.SectionModifiers()); + // populate local axes dictionary + ConcurrentDictionary> localAxesDict = new ConcurrentDictionary>(); + foreach (int id in eDict.Keys) + localAxesDict.TryAdd(id, model.ElementDirectionCosine(id)); + results = Compute(nDict, axDict, out_nDict, - eDict, mDict, sDict, pDict, p3Dict, amDict, modDict); + eDict, mDict, sDict, pDict, p3Dict, amDict, modDict, localAxesDict); } else return; } @@ -603,7 +616,7 @@ public override void DrawViewportWires(IGH_PreviewArgs args) public List SpacerDescriptions; public bool IsInitialised; - + private LengthUnit LengthUnit = DefaultUnits.LengthUnitGeometry; public override void CreateAttributes() @@ -614,7 +627,7 @@ public override void CreateAttributes() m_attributes = new OasysGH.UI.DropDownComponentAttributes(this, SetSelected, DropDownItems, SelectedItems, SpacerDescriptions); } - public void InitialiseDropdowns() + public void InitialiseDropdowns() { this.SpacerDescriptions = new List(new string[] { diff --git a/GsaGH/Components/2_Geometry/EditElement1d.cs b/GsaGH/Components/2_Geometry/EditElement1d.cs index bafc6ca97..d66423d49 100644 --- a/GsaGH/Components/2_Geometry/EditElement1d.cs +++ b/GsaGH/Components/2_Geometry/EditElement1d.cs @@ -63,7 +63,7 @@ protected override void RegisterInputParams(GH_InputParamManager pManager) pManager.AddParameter(new GsaBool6Parameter(), "End release", "⭲", "Set Release (Bool6) at End of Element", GH_ParamAccess.item); pManager.AddAngleParameter("Orientation Angle", "⭮A", "Set Element Orientation Angle", GH_ParamAccess.item); - pManager.AddGenericParameter("Orientation Node", "⭮N", "Set Element Orientation Node", GH_ParamAccess.item); + pManager.AddParameter(new GsaNodeParameter(), "Orientation Node", "⭮N", "Set Element Orientation Node", GH_ParamAccess.item); pManager.AddTextParameter("Name", "Na", "Set Element Name", GH_ParamAccess.item); pManager.AddColourParameter("Colour", "Co", "Set Element Colour", GH_ParamAccess.item); diff --git a/GsaGH/Components/2_Geometry/EditMember1d.cs b/GsaGH/Components/2_Geometry/EditMember1d.cs index 329ab3b13..3c0440604 100644 --- a/GsaGH/Components/2_Geometry/EditMember1d.cs +++ b/GsaGH/Components/2_Geometry/EditMember1d.cs @@ -68,7 +68,7 @@ protected override void RegisterInputParams(GH_InputParamManager pManager) pManager.AddParameter(new GsaBool6Parameter(), "Start release", "⭰", "Set Release (Bool6) at Start of Member", GH_ParamAccess.item); pManager.AddParameter(new GsaBool6Parameter(), "End release", "⭲", "Set Release (Bool6) at End of Member", GH_ParamAccess.item); pManager.AddAngleParameter("Orientation Angle", "⭮A", "Set Member Orientation Angle", GH_ParamAccess.item); - pManager.AddGenericParameter("Orientation Node", "⭮N", "Set Member Orientation Node", GH_ParamAccess.item); + pManager.AddParameter(new GsaNodeParameter(), "Orientation Node", "⭮N", "Set Member Orientation Node", GH_ParamAccess.item); pManager.AddNumberParameter("Mesh Size in model units", "Ms", "Set Member Mesh Size", GH_ParamAccess.item); pManager.AddBooleanParameter("Mesh With Others", "M/o", "Mesh with others?", GH_ParamAccess.item); pManager.AddParameter(new GsaBucklingLengthFactorsParameter(), "Set " + GsaBucklingLengthFactorsGoo.Name, GsaBucklingLengthFactorsGoo.NickName, GsaBucklingLengthFactorsGoo.Description, GH_ParamAccess.item); diff --git a/GsaGH/Components/2_Geometry/ElemFromMem.cs b/GsaGH/Components/2_Geometry/ElemFromMem.cs index 82c870cb9..d72e2e7f2 100644 --- a/GsaGH/Components/2_Geometry/ElemFromMem.cs +++ b/GsaGH/Components/2_Geometry/ElemFromMem.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Linq; using Grasshopper.Kernel; using Grasshopper.Kernel.Types; @@ -184,6 +185,13 @@ protected override void SolveInstance(IGH_DataAccess DA) // extract nodes from model ConcurrentBag nodes = Util.Gsa.FromGSA.GetNodes(new ConcurrentDictionary(gsa.Nodes()), LengthUnit); + ConcurrentDictionary elementDict = new ConcurrentDictionary(gsa.Elements()); + + // populate local axes dictionary + ConcurrentDictionary> localAxesDict = new ConcurrentDictionary>(); + foreach (int id in elementDict.Keys) + localAxesDict.TryAdd(id, gsa.ElementDirectionCosine(id)); + // extract elements from model Tuple, ConcurrentBag, ConcurrentBag> elementTuple = Util.Gsa.FromGSA.GetElements( @@ -194,6 +202,7 @@ Tuple, ConcurrentBag, Concurrent new ConcurrentDictionary(gsa.Prop3Ds()), new ConcurrentDictionary(gsa.AnalysisMaterials()), new ConcurrentDictionary(gsa.SectionModifiers()), + localAxesDict, LengthUnit); // post process materials (as they currently have a bug when running parallel!) @@ -363,7 +372,7 @@ public override void UpdateUIFromSelectedItems() this.LengthUnit = (LengthUnit)UnitsHelper.Parse(typeof(LengthUnit), this.SelectedItems[0]); base.UpdateUIFromSelectedItems(); } - + public override void VariableParameterMaintenance() { string unitAbbreviation = Length.GetAbbreviation(this.LengthUnit); diff --git a/GsaGH/Components/2_Geometry/LocalAxis.cs b/GsaGH/Components/2_Geometry/LocalAxes.cs similarity index 65% rename from GsaGH/Components/2_Geometry/LocalAxis.cs rename to GsaGH/Components/2_Geometry/LocalAxes.cs index 0e21fb909..aed0c33db 100644 --- a/GsaGH/Components/2_Geometry/LocalAxis.cs +++ b/GsaGH/Components/2_Geometry/LocalAxes.cs @@ -1,9 +1,15 @@ using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Collections.ObjectModel; using Grasshopper.Kernel; using Grasshopper.Kernel.Types; +using GsaAPI; using GsaGH.Parameters; +using GsaGH.Util.Gsa.ToGSA; using OasysGH; using OasysGH.Components; +using OasysUnits.Units; using Rhino.Geometry; namespace GsaGH.Components @@ -11,7 +17,7 @@ namespace GsaGH.Components /// /// Component to edit a Node /// - public class LocalAxis : GH_OasysComponent, IGH_PreviewObject + public class LocalAxes : GH_OasysComponent, IGH_PreviewObject { #region Name and Ribbon Layout public override Guid ComponentGuid => new Guid("4a322b8e-031a-4c90-b8df-b32d162a3274"); @@ -19,7 +25,7 @@ public class LocalAxis : GH_OasysComponent, IGH_PreviewObject public override OasysPluginInfo PluginInfo => GsaGH.PluginInfo.Instance; protected override System.Drawing.Bitmap Icon => GsaGH.Properties.Resources.LocalAxes; - public LocalAxis() : base("Local Axis", + public LocalAxes() : base("Local Axis", "Axis", "Get Element1D or Member1D local axes", Ribbon.CategoryName.Name(), @@ -50,7 +56,7 @@ protected override void SolveInstance(IGH_DataAccess DA) GsaElement1d elem = null; Point3d midPt = new Point3d(); double size = 0; - Tuple axes; + GsaLocalAxes axes; if (gh_typ.Value is GsaMember1dGoo) { gh_typ.CastTo(ref mem); @@ -60,6 +66,14 @@ protected override void SolveInstance(IGH_DataAccess DA) return; } axes = mem.LocalAxes; + if (axes == null) + { + GsaModel model = new GsaModel(); + model.Model = Util.Gsa.ToGSA.Assemble.AssembleModel(model, new List(), new List(), new List(), new List(), new List() { mem }, new List(), new List(), new List(), new List(), new List(), new List(), new List(), new List(), new List(), LengthUnit.Meter); + + axes = new GsaLocalAxes(model.Model.MemberDirectionCosine(1)); + AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Members´s local axes might deviate from the local axes in the assembled GSA model."); + } midPt = mem.PolyCurve.PointAtNormalizedLength(0.5); size = mem.PolyCurve.GetLength() * 0.05; } @@ -72,6 +86,14 @@ protected override void SolveInstance(IGH_DataAccess DA) return; } axes = elem.LocalAxes; + if (axes == null) + { + GsaModel model = new GsaModel(); + model.Model = Util.Gsa.ToGSA.Assemble.AssembleModel(model, new List(), new List() { elem }, new List(), new List(), new List(), new List(), new List(), new List(), new List(), new List(), new List(), new List(), new List(), new List(), LengthUnit.Meter); + + axes = new GsaLocalAxes(model.Model.ElementDirectionCosine(1)); + AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Element´s local axes might deviate from the local axes in the assembled GSA model."); + } midPt = elem.Line.PointAtNormalizedLength(0.5); size = elem.Line.GetLength() * 0.05; } @@ -80,15 +102,12 @@ protected override void SolveInstance(IGH_DataAccess DA) AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Unable to convert input to Element1D or Member1D"); return; } - - Vector3d x = axes.Item1; - Vector3d y = axes.Item2; - Vector3d z = axes.Item3; - + Vector3d x = axes.X; + Vector3d y = axes.Y; + Vector3d z = axes.Z; DA.SetData(0, x); DA.SetData(1, y); DA.SetData(2, z); - previewXaxis = new Line(midPt, x, size); previewYaxis = new Line(midPt, y, size); previewZaxis = new Line(midPt, z, size); diff --git a/GsaGH/Helpers/Export/_GsaExport.cs b/GsaGH/Helpers/Export/_GsaExport.cs index 79387fdf3..1ff5d2ab8 100644 --- a/GsaGH/Helpers/Export/_GsaExport.cs +++ b/GsaGH/Helpers/Export/_GsaExport.cs @@ -52,6 +52,11 @@ public static GsaModel MergeModel(GsaModel mainModel, GsaModel appendModel) ConcurrentDictionary amDict = new ConcurrentDictionary(model.AnalysisMaterials()); ConcurrentDictionary modDict = new ConcurrentDictionary(model.SectionModifiers()); + // populate local axes dictionary + ConcurrentDictionary> localAxesDict = new ConcurrentDictionary>(); + foreach (int id in eDict.Keys) + localAxesDict.TryAdd(id, model.ElementDirectionCosine(id)); + // get nodes ConcurrentBag goonodes = Util.Gsa.FromGSA.GetNodes(nDict, LengthUnit.Meter); // convert from Goo-type @@ -61,7 +66,7 @@ public static GsaModel MergeModel(GsaModel mainModel, GsaModel appendModel) // get elements Tuple, ConcurrentBag, ConcurrentBag> elementTuple - = Util.Gsa.FromGSA.GetElements(eDict, nDict, sDict, pDict, p3Dict, amDict, modDict, LengthUnit.Meter); + = Util.Gsa.FromGSA.GetElements(eDict, nDict, sDict, pDict, p3Dict, amDict, modDict, localAxesDict, LengthUnit.Meter); // convert from Goo-type List elem1ds = elementTuple.Item1.Select(n => n.Value).ToList(); // change all members in List's ID to 0; @@ -79,7 +84,7 @@ Tuple, ConcurrentBag, Concurrent // get members Tuple, ConcurrentBag, ConcurrentBag> memberTuple - = Util.Gsa.FromGSA.GetMembers(mDict, nDict, LengthUnit.Meter, sDict, pDict, p3Dict); + = Util.Gsa.FromGSA.GetMembers(mDict, nDict, LengthUnit.Meter, sDict, pDict, p3Dict, localAxesDict); // convert from Goo-type List mem1ds = memberTuple.Item1.Select(n => n.Value).ToList(); // change all members in List's ID to 0; diff --git a/GsaGH/Helpers/_Display.cs b/GsaGH/Helpers/_Display.cs index 202918653..e39e821e3 100644 --- a/GsaGH/Helpers/_Display.cs +++ b/GsaGH/Helpers/_Display.cs @@ -9,40 +9,9 @@ namespace GsaGH.UI /// /// Colour class holding the main colours used in colour scheme. /// Make calls to this class to be able to easy update colours. - /// /// public class Display { - public static Tuple GetLocalPlane(PolyCurve crv, double t, double orientationAngle) - { - crv.PerpendicularFrameAt(t, out Plane pln); - pln.Rotate(orientationAngle, pln.Normal); - - double absAngleToZ = Vector3d.VectorAngle(pln.Normal, Vector3d.ZAxis); - absAngleToZ %= Math.PI; - - Vector3d outX = pln.ZAxis; - Vector3d outY; - if (absAngleToZ < 0.25 * Math.PI || absAngleToZ > 0.75 * Math.PI) - { - outY = new Vector3d(outX); - double angle; - if (outX.Z > 0) - angle = -0.5 * Math.PI; - else - angle = 0.5 * Math.PI; - - if (!outY.Rotate(angle, pln.XAxis)) - throw new Exception(); - } - else - { - outY = pln.YAxis; - } - Vector3d outZ = Vector3d.CrossProduct(outX, outY); - return new Tuple(outX, outY, outZ); - } - public static void Preview1D(PolyCurve crv, double angle_radian, GsaBool6 start, GsaBool6 end, ref List greenLines20, ref List redLines10) { diff --git a/GsaGH/Helpers/_GsaImport.cs b/GsaGH/Helpers/_GsaImport.cs index d568a2529..57b1606d9 100644 --- a/GsaGH/Helpers/_GsaImport.cs +++ b/GsaGH/Helpers/_GsaImport.cs @@ -156,7 +156,7 @@ public static Plane AxisToPlane(Axis axis, LengthUnit unit) public static Tuple, ConcurrentBag, ConcurrentBag> GetElements(ConcurrentDictionary eDict, ConcurrentDictionary nDict, ConcurrentDictionary sDict, ConcurrentDictionary pDict, ConcurrentDictionary p3Dict, - ConcurrentDictionary mDict, ConcurrentDictionary modDict, LengthUnit unit) + ConcurrentDictionary mDict, ConcurrentDictionary modDict, ConcurrentDictionary> localAxesDict, LengthUnit unit) { // Create lists for Rhino lines and meshes ConcurrentBag elem1ds = new ConcurrentBag(); @@ -217,7 +217,7 @@ public static Tuple, ConcurrentBag 0) elem1ds = new ConcurrentBag(elem1dDict.AsParallel(). Select(item => new GsaElement1dGoo( - ConvertToElement1D(item.Value, item.Key, nDict, sDict, mDict, modDict, unit)))); + ConvertToElement1D(item.Value, item.Key, nDict, sDict, mDict, modDict, localAxesDict, unit)))); if (elem2dDict.Count > 0) elem2ds = ConvertToElement2Ds(elem2dDict, nDict, pDict, mDict, unit); @@ -241,7 +241,7 @@ public static Tuple, ConcurrentBag public static GsaElement1d ConvertToElement1D(Element element, int ID, ConcurrentDictionary nodes, ConcurrentDictionary sections, - ConcurrentDictionary materials, ConcurrentDictionary sectionModifiers, LengthUnit unit) + ConcurrentDictionary materials, ConcurrentDictionary sectionModifiers, ConcurrentDictionary> localAxes, LengthUnit unit) { // get element's topology ReadOnlyCollection topo = element.Topology; @@ -292,7 +292,12 @@ public static GsaElement1d ConvertToElement1D(Element element, } // create GH GsaElement1d - return new GsaElement1d(element, ln, ID, section, orient); + GsaElement1d element1d = new GsaElement1d(element, ln, ID, section, orient); + + // set local axes + element1d.LocalAxes = new GsaLocalAxes(localAxes[ID]); + + return element1d; } return null; } @@ -799,7 +804,7 @@ public static Member DuplicateMember(Member mem) /// public static Tuple, ConcurrentBag, ConcurrentBag> GetMembers(ConcurrentDictionary mDict, ConcurrentDictionary nDict, LengthUnit unit, - ConcurrentDictionary sDict, ConcurrentDictionary pDict, ConcurrentDictionary p3Dict, GH_Component owner = null) + ConcurrentDictionary sDict, ConcurrentDictionary pDict, ConcurrentDictionary p3Dict, ConcurrentDictionary> localAxesDict, GH_Component owner = null) { // Create lists for Rhino lines and meshes ConcurrentBag mem1ds = new ConcurrentBag(); @@ -1000,6 +1005,9 @@ public static Tuple, ConcurrentBag GsaMember1d mem1d = new GsaMember1d(mem, unit, key, topopts.ToList(), topoType.ToList(), section, orient); mem1d.MeshSize = new Length(mem.MeshSize, LengthUnit.Meter).As(unit); + // set local axes + mem1d.LocalAxes = new GsaLocalAxes(localAxesDict[key]); + // add member to output list mem1ds.Add(new GsaMember1dGoo(mem1d)); } diff --git a/GsaGH/Helpers/_RhinoConversions.cs b/GsaGH/Helpers/_RhinoConversions.cs index c6552f0ea..92a8dcb4c 100644 --- a/GsaGH/Helpers/_RhinoConversions.cs +++ b/GsaGH/Helpers/_RhinoConversions.cs @@ -12,6 +12,7 @@ using OasysUnits.Units; using OasysGH.Units; using OasysGH.Units.Helpers; +using System.Collections.ObjectModel; namespace GsaGH.Util.GH { @@ -816,16 +817,24 @@ public static Mesh ConvertBrepToMesh(Brep brep, List curves, List elementDict = new ConcurrentDictionary(model.Elements()); + + // populate local axes dictionary + ConcurrentDictionary> localAxesDict = new ConcurrentDictionary>(); + foreach (int id in elementDict.Keys) + localAxesDict.TryAdd(id, model.ElementDirectionCosine(id)); + // extract elements from model Tuple, ConcurrentBag, ConcurrentBag> elementTuple = Util.Gsa.FromGSA.GetElements( - new ConcurrentDictionary(model.Elements()), + elementDict, new ConcurrentDictionary(model.Nodes()), new ConcurrentDictionary(model.Sections()), new ConcurrentDictionary(model.Prop2Ds()), new ConcurrentDictionary(model.Prop3Ds()), new ConcurrentDictionary(model.AnalysisMaterials()), new ConcurrentDictionary(model.SectionModifiers()), + localAxesDict, unit); List elem2dgoo = elementTuple.Item2.OrderBy(item => item.Value.Ids).ToList(); diff --git a/GsaGH/Parameters/2_Geometry/GsaElement1d.cs b/GsaGH/Parameters/2_Geometry/GsaElement1d.cs index e0d3148f7..cb79a2c46 100644 --- a/GsaGH/Parameters/2_Geometry/GsaElement1d.cs +++ b/GsaGH/Parameters/2_Geometry/GsaElement1d.cs @@ -29,6 +29,7 @@ public class GsaElement1d private GsaBool6 _rel2; private GsaSection _section = new GsaSection(); private GsaNode _orientationNode; + private GsaLocalAxes _localAxes = null; private Line previewSX1; private Line previewSX2; @@ -250,13 +251,15 @@ public ElementType Type this._element.Type = value; } } - internal Tuple LocalAxes + internal GsaLocalAxes LocalAxes { get { - PolyCurve crv = new PolyCurve(); - crv.Append(this._line); - return UI.Display.GetLocalPlane(crv, crv.GetLength() / 2, this._element.OrientationAngle * Math.PI / 180.0); + return _localAxes; + } + set + { + this._localAxes = value; } } #endregion @@ -298,6 +301,7 @@ public GsaElement1d Duplicate(bool cloneApiElement = false) GsaElement1d dup = new GsaElement1d(); dup._id = this._id; dup._element = this._element; + dup._localAxes = this._localAxes; if (cloneApiElement) dup.CloneApiObject(); dup._line = (LineCurve)this._line.DuplicateShallow(); @@ -401,5 +405,33 @@ internal void UpdatePreview() previewPointEnd = this._line.PointAtEnd; } #endregion + + #region transformation methods + public GsaElement1d Transform(Transform xform) + { + GsaElement1d elem = this.Duplicate(true); + elem.Id = 0; + elem.LocalAxes = null; + + LineCurve xLn = elem.Line; + xLn.Transform(xform); + elem.Line = xLn; + + return elem; + } + + public GsaElement1d Morph(SpaceMorph xmorph) + { + GsaElement1d elem = this.Duplicate(true); + elem.Id = 0; + elem.LocalAxes = null; + + LineCurve xLn = this.Line; + xmorph.Morph(xLn); + elem.Line = xLn; + + return elem; + } + #endregion } } diff --git a/GsaGH/Parameters/2_Geometry/GsaElement1dGoo.cs b/GsaGH/Parameters/2_Geometry/GsaElement1dGoo.cs index 2e1a79a56..8f482ab42 100644 --- a/GsaGH/Parameters/2_Geometry/GsaElement1dGoo.cs +++ b/GsaGH/Parameters/2_Geometry/GsaElement1dGoo.cs @@ -1,6 +1,5 @@ using Grasshopper.Kernel; using Grasshopper.Kernel.Types; -using GsaAPI; using OasysGH; using Rhino.Geometry; using OasysGH.Parameters; @@ -114,35 +113,6 @@ public override bool CastFrom(object source) } #endregion - #region transformation methods - public override IGH_GeometricGoo Transform(Transform xform) - { - if (Value == null) { return null; } - if (Value.Line == null) { return null; } - - GsaElement1d elem = Value.Duplicate(true); - elem.Id = 0; - LineCurve xLn = elem.Line; - xLn.Transform(xform); - elem.Line = xLn; - - return new GsaElement1dGoo(elem); - } - - public override IGH_GeometricGoo Morph(SpaceMorph xmorph) - { - if (Value == null) { return null; } - if (Value.Line == null) { return null; } - - GsaElement1d elem = Value.Duplicate(true); - LineCurve xLn = Value.Line; - xmorph.Morph(xLn); - elem.Line = xLn; - - return new GsaElement1dGoo(elem); - } - #endregion - #region drawing methods public override void DrawViewportMeshes(GH_PreviewMeshArgs args) { @@ -198,5 +168,17 @@ public override void DrawViewportWires(GH_PreviewWireArgs args) } } #endregion + + #region transformation methods + public override IGH_GeometricGoo Transform(Transform xform) + { + return new GsaElement1dGoo(Value.Transform(xform)); + } + + public override IGH_GeometricGoo Morph(SpaceMorph xmorph) + { + return new GsaElement1dGoo(Value.Morph(xmorph)); + } + #endregion } } diff --git a/GsaGH/Parameters/2_Geometry/GsaElement2d.cs b/GsaGH/Parameters/2_Geometry/GsaElement2d.cs index deee16281..0fd51a16b 100644 --- a/GsaGH/Parameters/2_Geometry/GsaElement2d.cs +++ b/GsaGH/Parameters/2_Geometry/GsaElement2d.cs @@ -8,7 +8,6 @@ using OasysUnits; using OasysUnits.Units; using Rhino.Geometry; -using Grasshopper.Kernel.Types; namespace GsaGH.Parameters { diff --git a/GsaGH/Parameters/2_Geometry/GsaLocalAxes.cs b/GsaGH/Parameters/2_Geometry/GsaLocalAxes.cs new file mode 100644 index 000000000..78c7f2fa9 --- /dev/null +++ b/GsaGH/Parameters/2_Geometry/GsaLocalAxes.cs @@ -0,0 +1,26 @@ +using Rhino.Geometry; +using System.Collections.ObjectModel; + +namespace GsaGH.Parameters +{ + public class GsaLocalAxes + { + public Vector3d X { get; } + public Vector3d Y { get; } + public Vector3d Z { get; } + + public GsaLocalAxes(Vector3d x, Vector3d y, Vector3d z) + { + this.X = x; + this.Y = y; + this.Z = z; + } + + public GsaLocalAxes(ReadOnlyCollection collection) + { + this.X = new Vector3d(collection[0], collection[1], collection[2]); + this.Y = new Vector3d(collection[3], collection[4], collection[5]); + this.Z = new Vector3d(collection[6], collection[7], collection[8]); + } + } +} diff --git a/GsaGH/Parameters/2_Geometry/GsaMember1d.cs b/GsaGH/Parameters/2_Geometry/GsaMember1d.cs index b0bf29dd1..ccf0be67e 100644 --- a/GsaGH/Parameters/2_Geometry/GsaMember1d.cs +++ b/GsaGH/Parameters/2_Geometry/GsaMember1d.cs @@ -25,6 +25,7 @@ public class GsaMember1d private GsaBool6 _rel1; private GsaBool6 _rel2; private GsaNode _orientationNode; + private GsaLocalAxes _localAxes = null; private Line previewSX1; private Line previewSX2; @@ -65,7 +66,17 @@ public class GsaMember1d public GsaSection Section { get; set; } = new GsaSection(); public List Topology => this._topo; public List TopologyType => this._topoType; - internal Tuple LocalAxes => UI.Display.GetLocalPlane(this._crv, this._crv.GetLength() / 2.0, this.OrientationAngle.Radians); + internal GsaLocalAxes LocalAxes + { + get + { + return _localAxes; + } + set + { + this._localAxes = value; + } + } public PolyCurve PolyCurve { get @@ -322,6 +333,7 @@ public GsaMember1d Duplicate(bool cloneApiMember = false) dup.Id = this.Id; dup.MeshSize = this.MeshSize; dup.ApiMember = this.ApiMember; + dup._localAxes = this._localAxes; if (cloneApiMember) dup.CloneApiObject(); dup._crv = (PolyCurve)this._crv.DuplicateShallow(); @@ -342,6 +354,7 @@ public GsaMember1d Transform(Transform xform) { GsaMember1d dup = this.Duplicate(true); dup.Id = 0; + dup.LocalAxes = null; List pts = this._topo.ToList(); Point3dList xpts = new Point3dList(pts); @@ -362,6 +375,7 @@ public GsaMember1d Morph(SpaceMorph xmorph) { GsaMember1d dup = this.Duplicate(true); dup.Id = 0; + dup.LocalAxes = null; List pts = this._topo.ToList(); for (int i = 0; i < pts.Count; i++) diff --git a/GsaGH/Parameters/2_Geometry/GsaMember1dGoo.cs b/GsaGH/Parameters/2_Geometry/GsaMember1dGoo.cs index 7e32ea9cf..da9c051a7 100644 --- a/GsaGH/Parameters/2_Geometry/GsaMember1dGoo.cs +++ b/GsaGH/Parameters/2_Geometry/GsaMember1dGoo.cs @@ -149,7 +149,6 @@ public override IGH_GeometricGoo Morph(SpaceMorph xmorph) { return new GsaMember1dGoo(Value.Morph(xmorph)); } - #endregion #region drawing methods diff --git a/GsaGHTests/Helper/_DisplayTest.cs b/GsaGHTests/Helper/_DisplayTest.cs deleted file mode 100644 index c95b38726..000000000 --- a/GsaGHTests/Helper/_DisplayTest.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System; -using GsaGH.UI; -using Rhino.Geometry; -using Xunit; - -namespace GsaGHTests.Helpers -{ - [Collection("GrasshopperFixture collection")] - public class _DisplayTest - { - [Theory] - [InlineData(0, 0, 1, 0, 0, 0, 1, 0, 1, 0)] - [InlineData(0, 0, 1, Math.PI / 2.0, 0, 0, 1, -1, 0, 0)] - [InlineData(0, 0, 1, Math.PI, 0, 0, 1, 0, -1, 0)] - [InlineData(0, 0, 1, Math.PI * 3 / 2.0, 0, 0, 1, 1, 0, 0)] - [InlineData(0, 0, 1, 2 * Math.PI, 0, 0, 1, 0, 1, 0)] - [InlineData(0, 0, 1, 5 * Math.PI / 2.0, 0, 0, 1, -1, 0, 0)] - [InlineData(0, 0, -1, 0, 0, 0, -1, 0, 1, 0)] - [InlineData(0, 0, -1, Math.PI / 2.0, 0, 0, -1, 1, 0, 0)] - [InlineData(0, 0, -1, Math.PI, 0, 0, -1, 0, -1, 0)] - [InlineData(0, 1, 0, 0, 0, 1, 0, 0, 0, 1)] - [InlineData(0, 1, 0, Math.PI / 2.0, 0, 1, 0, 1, 0, 0)] - [InlineData(0, 1, 0, Math.PI, 0, 1, 0, 0, 0, -1)] - [InlineData(0, 1, 0, Math.PI * 3 / 2.0, 0, 1, 0, -1, 0, 0)] - [InlineData(0, 1, 0, 2 * Math.PI, 0, 1, 0, 0, 0, 1)] - [InlineData(0, 1, 0, 5 * Math.PI / 2.0, 0, 1, 0, 1, 0, 0)] - [InlineData(0, -1, 0, 0, 0, -1, 0, 0, 0, 1)] - [InlineData(0, -1, 0, Math.PI / 2.0, 0, -1, 0, -1, 0, 0)] - [InlineData(0, -1, 0, Math.PI, 0, -1, 0, 0, 0, -1)] - [InlineData(1, 0, 0, 0, 1, 0, 0, 0, 0, 1)] - [InlineData(1, 0, 0, Math.PI / 2.0, 1, 0, 0, 0, -1, 0)] - [InlineData(1, 0, 0, Math.PI, 1, 0, 0, 0, 0, -1)] - [InlineData(-1, 0, 0, 0, -1, 0, 0, 0, 0, 1)] - [InlineData(-1, 0, 0, Math.PI / 2.0, -1, 0, 0, 0, 1, 0)] - [InlineData(-1, 0, 0, Math.PI, -1, 0, 0, 0, 0, -1)] - public void GetLocalPlaneTest(double dx, double dy, double dz, double angle, double expextedLocalX1, double expextedLocalY1, double expextedLocalZ1, double expextedLocalX2, double expextedLocalY2, double expextedLocalZ2) - { - // Arrange - Random random = new Random(); - double x = random.NextDouble(); - double y = random.NextDouble(); - double z = random.NextDouble(); - Point3d start = new Point3d(x, y, z); - Point3d end = new Point3d(x + dx, y + dy, z + dz); - Line line = new Line(start, end); - PolyCurve curve = new PolyCurve(); - curve.Append(line); - - double t = curve.GetLength() / 2.0; - - // Act - Tuple localAxis = Display.GetLocalPlane(curve, t, angle); - - // Assert - Vector3d expectedLocalX = new Vector3d(expextedLocalX1, expextedLocalY1, expextedLocalZ1); - Vector3d expectedLocalY = new Vector3d(expextedLocalX2, expextedLocalY2, expextedLocalZ2); - Vector3d expectedLocalZ = Vector3d.CrossProduct(expectedLocalX, expectedLocalY); - - int precision = 10; - - Assert.Equal(expectedLocalX.X, localAxis.Item1.X, precision); - Assert.Equal(expectedLocalX.Y, localAxis.Item1.Y, precision); - Assert.Equal(expectedLocalX.Z, localAxis.Item1.Z, precision); - Assert.Equal(expectedLocalY.X, localAxis.Item2.X, precision); - Assert.Equal(expectedLocalY.Y, localAxis.Item2.Y, precision); - Assert.Equal(expectedLocalY.Z, localAxis.Item2.Z, precision); - Assert.Equal(expectedLocalZ.X, localAxis.Item3.X, precision); - Assert.Equal(expectedLocalZ.Y, localAxis.Item3.Y, precision); - Assert.Equal(expectedLocalZ.Z, localAxis.Item3.Z, precision); - } - } -} diff --git a/IntegrationTests/Components/CreateGridPlane.cs b/IntegrationTests/Components/CreateGridPlaneTests.cs similarity index 91% rename from IntegrationTests/Components/CreateGridPlane.cs rename to IntegrationTests/Components/CreateGridPlaneTests.cs index 67cc21983..e7c896170 100644 --- a/IntegrationTests/Components/CreateGridPlane.cs +++ b/IntegrationTests/Components/CreateGridPlaneTests.cs @@ -29,8 +29,6 @@ public void GridPlaneSurfaceTest() GH_Document doc = Document(); GH_Component comp = Helper.FindComponent(doc, "gps"); Assert.NotNull(comp); - // Todo fix: referencing GsaGH directly causes tests to fail - // Not only this one but tests that otherwise work GsaGridPlaneSurfaceGoo output = (GsaGridPlaneSurfaceGoo)ComponentTestHelper.GetOutput(comp); GsaGridPlaneSurface gps = output.Value; Assert.Equal(42, gps.GridPlaneId); diff --git a/IntegrationTests/Components/LocalAxesTests.cs b/IntegrationTests/Components/LocalAxesTests.cs new file mode 100644 index 000000000..7625d5b47 --- /dev/null +++ b/IntegrationTests/Components/LocalAxesTests.cs @@ -0,0 +1,83 @@ +using System; +using System.IO; +using System.Reflection; +using Grasshopper.Kernel; +using Grasshopper.Kernel.Types; +using Xunit; + +namespace IntegrationTests.Components +{ + [Collection("GrasshopperFixture collection")] + public class LocalAxesTests + { + public static GH_Document Document() + { + Type thisClass = MethodBase.GetCurrentMethod().DeclaringType; + string fileName = thisClass.Name + ".gh"; + fileName = fileName.Replace(thisClass.Namespace, string.Empty).Replace("Tests", string.Empty); + + string solutiondir = Directory.GetParent(Directory.GetCurrentDirectory()).Parent.Parent.Parent.Parent.FullName; + string path = Path.Combine(new string[] { solutiondir, "ExampleFiles", "Components" }); + + return Helper.CreateDocument(Path.Combine(path, fileName)); + } + + [Fact] + public void LocalAxesTest() + { + GH_Document doc = Document(); + + IGH_Param paramX1 = Helper.FindParameter(doc, "X1"); + IGH_Param paramY1 = Helper.FindParameter(doc, "Y1"); + IGH_Param paramZ1 = Helper.FindParameter(doc, "Z1"); + IGH_Param paramX2 = Helper.FindParameter(doc, "X2"); + IGH_Param paramY2 = Helper.FindParameter(doc, "Y2"); + IGH_Param paramZ2 = Helper.FindParameter(doc, "Z2"); + for (int i = 0; i < 20; i++) + { + GH_Vector outputX1 = (GH_Vector)paramX1.VolatileData.get_Branch(0)[i]; + GH_Vector outputY1 = (GH_Vector)paramY1.VolatileData.get_Branch(0)[i]; + GH_Vector outputZ1 = (GH_Vector)paramZ1.VolatileData.get_Branch(0)[i]; + GH_Vector outputX2 = (GH_Vector)paramX2.VolatileData.get_Branch(0)[i]; + GH_Vector outputY2 = (GH_Vector)paramY2.VolatileData.get_Branch(0)[i]; + GH_Vector outputZ2 = (GH_Vector)paramZ2.VolatileData.get_Branch(0)[i]; + + Assert.Equal(outputX1.Value.X, outputX2.Value.X, 6); + Assert.Equal(outputX1.Value.Y, outputX2.Value.Y, 6); + Assert.Equal(outputX1.Value.Z, outputX2.Value.Z, 6); + Assert.Equal(outputY1.Value.X, outputY2.Value.X, 6); + Assert.Equal(outputY1.Value.Y, outputY2.Value.Y, 6); + Assert.Equal(outputY1.Value.Z, outputY2.Value.Z, 6); + Assert.Equal(outputZ1.Value.X, outputZ2.Value.X, 6); + Assert.Equal(outputZ1.Value.Y, outputZ2.Value.Y, 6); + Assert.Equal(outputZ1.Value.Z, outputZ2.Value.Z, 6); + } + + IGH_Param paramX3 = Helper.FindParameter(doc, "X3"); + IGH_Param paramY3 = Helper.FindParameter(doc, "Y3"); + IGH_Param paramZ3 = Helper.FindParameter(doc, "Z3"); + IGH_Param paramX4 = Helper.FindParameter(doc, "X4"); + IGH_Param paramY4 = Helper.FindParameter(doc, "Y4"); + IGH_Param paramZ4 = Helper.FindParameter(doc, "Z4"); + for (int i = 0; i < 20; i++) + { + GH_Vector outputX3 = (GH_Vector)paramX3.VolatileData.get_Branch(0)[i]; + GH_Vector outputY3 = (GH_Vector)paramY3.VolatileData.get_Branch(0)[i]; + GH_Vector outputZ3 = (GH_Vector)paramZ3.VolatileData.get_Branch(0)[i]; + GH_Vector outputX4 = (GH_Vector)paramX4.VolatileData.get_Branch(0)[i]; + GH_Vector outputY4 = (GH_Vector)paramY4.VolatileData.get_Branch(0)[i]; + GH_Vector outputZ4 = (GH_Vector)paramZ4.VolatileData.get_Branch(0)[i]; + + Assert.Equal(outputX3.Value.X, outputX4.Value.X, 6); + Assert.Equal(outputX3.Value.Y, outputX4.Value.Y, 6); + Assert.Equal(outputX3.Value.Z, outputX4.Value.Z, 6); + Assert.Equal(outputY3.Value.X, outputY4.Value.X, 6); + Assert.Equal(outputY3.Value.Y, outputY4.Value.Y, 6); + Assert.Equal(outputY3.Value.Z, outputY4.Value.Z, 6); + Assert.Equal(outputZ3.Value.X, outputZ4.Value.X, 6); + Assert.Equal(outputZ3.Value.Y, outputZ4.Value.Y, 6); + Assert.Equal(outputZ3.Value.Z, outputZ4.Value.Z, 6); + } + } + } +} diff --git a/build-test-deploy.yml b/build-test-deploy.yml index 4a50c1cc6..78e003163 100644 --- a/build-test-deploy.yml +++ b/build-test-deploy.yml @@ -66,6 +66,12 @@ steps: summaryFileLocation: '$(System.DefaultWorkingDirectory)/results/gsagh/**/coverage.cobertura.xml' pathToSources: '$(System.DefaultWorkingDirectory)' +- task: PublishCodeCoverageResults@1 + inputs: + codeCoverageTool: 'cobertura' + summaryFileLocation: '$(System.DefaultWorkingDirectory)/results/integration/**/coverage.cobertura.xml' + pathToSources: '$(System.DefaultWorkingDirectory)' + - powershell: | $coverage_file_gsagh = (Resolve-Path $(System.DefaultWorkingDirectory)/results/gsagh/*/coverage.cobertura.xml).Path echo $coverage_file_gsagh