Beispiel #1
0
        /// <summary>
        /// Maps a flat array of coordinates from a local coordinate system to the global Cartesian coordinate system.
        /// </summary>
        /// <param name="values">Flat array of coordinates</param>
        /// <param name="axis">Local coordinate system</param>
        /// <returns>Transformed array of coordinates</returns>
        public static double[] MapPointsLocal2Global(double[] values, StructuralAxis axis)
        {
            var newVals = new List <double>();

            for (var i = 0; i < values.Length; i += 3)
            {
                var coor = values.Skip(i).Take(3).ToList();

                double x = 0;
                double y = 0;
                double z = 0;

                x += axis.Xdir.Value[0] * coor[0];
                y += axis.Xdir.Value[1] * coor[0];
                z += axis.Xdir.Value[2] * coor[0];

                x += axis.Ydir.Value[0] * coor[1];
                y += axis.Ydir.Value[1] * coor[1];
                z += axis.Ydir.Value[2] * coor[1];

                x += axis.Normal.Value[0] * coor[2];
                y += axis.Normal.Value[1] * coor[2];
                z += axis.Normal.Value[2] * coor[2];

                newVals.Add(x);
                newVals.Add(y);
                newVals.Add(z);
            }

            return(newVals.ToArray());
        }
        public void TestCoordinateMappings()
        {
            //< axis vector multiplier, global point , expected local point relative to axis >
            var globalExpected = new List <Tuple <double, SpecklePoint, SpecklePoint> >()
            {
                { new Tuple <double, SpecklePoint, SpecklePoint>(1, new SpecklePoint(3, 4, 5), new SpecklePoint(0, 0, 0)) },
                { new Tuple <double, SpecklePoint, SpecklePoint>(1, new SpecklePoint(3, 4, 6), new SpecklePoint(0, 0, 1)) },
                { new Tuple <double, SpecklePoint, SpecklePoint>(2, new SpecklePoint(3, 4 + (2 * Math.Sqrt(8)), 5), new SpecklePoint(2, 2, 0)) }
            };

            foreach (var tuple in globalExpected)
            {
                var axisFactor    = tuple.Item1;
                var pt            = tuple.Item2;
                var expectedPoint = tuple.Item3;

                var xdir = new StructuralVectorThree(1, 1, 0);
                xdir.Normalise();
                xdir.Scale(axisFactor);
                var ydir = new StructuralVectorThree(-1, 1, 0);
                ydir.Normalise();
                ydir.Scale(axisFactor);

                var axis = new StructuralAxis(xdir, ydir)
                {
                    Origin = new SpecklePoint(3, 4, 5)
                };

                var localCoords = pt.Value.MapGlobal2Local(axis);
                Assert.AreEqual(expectedPoint.Value[0], localCoords[0]);
                Assert.AreEqual(expectedPoint.Value[1], localCoords[1]);
                Assert.AreEqual(expectedPoint.Value[2], localCoords[2]);
            }
        }
        //NOTE: *unlike* most other ToSpeckle methods, this one does not find, and then convert, all instances of a GSA entity type;
        //this method does convert the exact object passed into a corresponding Speckle object
        public static SpeckleObject ToSpeckle(this GsaAxis gsaAxis)
        {
            return(Helper.ToSpeckleTryCatch(gsaAxis.Keyword, gsaAxis.Index ?? 0, () =>
            {
                var vX = new Vector3D(gsaAxis.XDirX.Value, gsaAxis.XDirY.Value, gsaAxis.XDirZ.Value);
                var vXY = new Vector3D(gsaAxis.XYDirX.Value, gsaAxis.XYDirY.Value, gsaAxis.XYDirZ.Value);
                var normal = vX.CrossProduct(vXY);
                var vY = normal.CrossProduct(vX);

                var axisX = new StructuralVectorThree(vX.X, vX.Y, vX.Z);
                var axisY = new StructuralVectorThree(vY.X, vY.Y, vY.Z);
                var axisNormal = new StructuralVectorThree(normal.X, normal.Y, normal.Z);
                //The x axis is assumed to be the , but the XY vector is not necessarily
                var speckleAxis = new StructuralAxis(axisX, axisY, axisNormal, gsaAxis.ApplicationId)
                {
                    Name = gsaAxis.Name
                };

                if (gsaAxis.OriginX > 0 || gsaAxis.OriginY > 0 || gsaAxis.OriginZ > 0)
                {
                    speckleAxis.Origin = new SpecklePoint(gsaAxis.OriginX, gsaAxis.OriginY, gsaAxis.OriginZ);
                }

                return speckleAxis;
            }));
        }
Beispiel #4
0
        public static bool IsZeroAxis(StructuralAxis axis)
        {
            var bp         = axis.basePlane;
            var zeroVector = new double[3] {
                0, 0, 0
            };

            return((bp.Xdir == null && bp.Ydir == null) ||
                   (bp.Xdir.Value.SequenceEqual(zeroVector) && bp.Ydir.Value.SequenceEqual(zeroVector)));
        }
Beispiel #5
0
        private static double AxisElevation(StructuralAxis axis, double[] polylineCoords)
        {
            // Calculate elevation
            var elevation = (polylineCoords[0] * axis.Normal.Value[0] +
                             polylineCoords[1] * axis.Normal.Value[1] +
                             polylineCoords[2] * axis.Normal.Value[2]) /
                            Math.Sqrt(Math.Pow(axis.Normal.Value[0], 2) + Math.Pow(axis.Normal.Value[1], 2) + Math.Pow(axis.Normal.Value[2], 2));

            return(elevation);
        }
Beispiel #6
0
 public void SetTestData()
 {
     p1 = new StructuralAxis()
     {
         Origin = new SpecklePoint(5, 6, 7)
     };
     p2 = new StructuralAxis()
     {
         Origin = new SpecklePoint(8, 9, 10)
     };
 }
Beispiel #7
0
        /// <summary>
        /// Maps a flat array of coordinates from the global Cartesian coordinate system to a local coordinate system.
        /// </summary>
        /// <param name="values">Flat array of coordinates</param>
        /// <param name="axis">Local coordinate system</param>
        /// <returns>Transformed array of coordinates</returns>
        public static double[] MapPointsGlobal2Local(IEnumerable <double> values, StructuralAxis axis)
        {
            var newVals = new List <double>();

            for (var i = 0; i < values.Count(); i += 3)
            {
                var coor       = values.Skip(i).Take(3).ToList();
                var translated = coor.MapGlobal2Local(axis);
                newVals.AddRange(translated);
            }

            return(newVals.ToArray());
        }
Beispiel #8
0
        public static void SetAxis(StructuralAxis axis, out int index, out string gwa, string name = "")
        {
            var gwaAxisName = name ?? "";

            index = 0;
            gwa   = "";
            double[] globalOrigin = { 0, 0, 0 };
            double[] globalXdir   = { 1, 0, 0 };
            double[] globalYdir   = { 0, 1, 0 };
            double[] globalZdir   = { 0, 0, 1 };

            if (axis == null || (axis.Xdir == null && axis.Ydir == null) ||
                (
                    axis.Xdir.Value.SequenceEqual(globalXdir) &&
                    axis.Ydir.Value.SequenceEqual(globalYdir) &&
                    axis.Normal.Value.SequenceEqual(globalZdir)))
            {
                return;
            }
            var res = Initialiser.Cache.ResolveIndex("AXIS.1");

            var originCoords = (axis.Origin == null || axis.Origin.Value == null) ? new List <double> {
                0, 0, 0
            } : axis.Origin.Value;

            var ls = new List <string>
            {
                "SET",
                "AXIS.1",
                res.ToString(),
                gwaAxisName,
                "CART",

                originCoords[0].ToString(),
                originCoords[1].ToString(),
                originCoords[2].ToString(),

                axis.Xdir.Value[0].ToString(),
                axis.Xdir.Value[1].ToString(),
                axis.Xdir.Value[2].ToString(),

                axis.Ydir.Value[0].ToString(),
                axis.Ydir.Value[1].ToString(),
                axis.Ydir.Value[2].ToString()
            };

            gwa = string.Join("\t", ls);

            index = res;
        }
Beispiel #9
0
        /// <summary>
        /// Calculates the local axis of a 1D entity.
        /// </summary>
        /// <param name="coor">Entity coordinates</param>
        /// <param name="zAxis">Z axis of the 1D entity</param>
        /// <returns>Axis</returns>
        public static StructuralAxis LocalAxisEntity1D(double[] coor, StructuralVectorThree zAxis)
        {
            var axisX = new Vector3D(coor[3] - coor[0], coor[4] - coor[1], coor[5] - coor[2]);
            var axisZ = new Vector3D(zAxis.Value[0], zAxis.Value[1], zAxis.Value[2]);
            var axisY = Vector3D.CrossProduct(axisZ, axisX);

            var axis = new StructuralAxis(
                new StructuralVectorThree(new double[] { axisX.X, axisX.Y, axisX.Z }),
                new StructuralVectorThree(new double[] { axisY.X, axisY.Y, axisY.Z }),
                new StructuralVectorThree(new double[] { axisZ.X, axisZ.Y, axisZ.Z })
                );

            axis.Normalize();
            return(axis);
        }
Beispiel #10
0
        /// <summary>
        /// Calculates rotation angle of 2D entity to align with axis
        /// </summary>
        /// <param name="coor">Entity coordinates</param>
        /// <param name="axis">Axis of entity</param>
        /// <returns>Rotation angle</returns>
        public static double Get2DAngle(double[] coor, StructuralAxis axis)
        {
            var axisX = new Vector3D(axis.Xdir.Value[0], axis.Xdir.Value[1], axis.Xdir.Value[2]);
            var axisY = new Vector3D(axis.Ydir.Value[0], axis.Ydir.Value[1], axis.Ydir.Value[2]);
            var axisZ = new Vector3D(axis.Normal.Value[0], axis.Normal.Value[1], axis.Normal.Value[2]);

            Vector3D x0;
            Vector3D z0;

            var nodes = new List <Vector3D>();

            for (var i = 0; i < coor.Length; i += 3)
            {
                nodes.Add(new Vector3D(coor[i], coor[i + 1], coor[i + 2]));
            }

            // Get 0 angle axis in GLOBAL coordinates
            x0 = Vector3D.Subtract(nodes[1], nodes[0]);
            x0.Normalize();
            z0 = Vector3D.CrossProduct(x0, Vector3D.Subtract(nodes[2], nodes[0]));
            z0.Normalize();

            x0 = new Vector3D(1, 0, 0);
            x0 = Vector3D.Subtract(x0, Vector3D.Multiply(Vector3D.DotProduct(x0, z0), z0));

            if (x0.Length == 0)
            {
                x0 = new Vector3D(0, z0.X > 0 ? -1 : 1, 0);
            }

            x0.Normalize();

            // Find angle
            var angle = Math.Acos(Vector3D.DotProduct(x0, axisX) / (x0.Length * axisX.Length)).ToDegrees();

            if (double.IsNaN(angle))
            {
                return(0);
            }

            var signVector = Vector3D.CrossProduct(x0, axisX);
            var sign       = Vector3D.DotProduct(signVector, axisZ);

            return(sign >= 0 ? angle : -angle);
        }
Beispiel #11
0
        public static void SetAxis(StructuralAxis axis, int Index, out string gwa, string name = "")
        {
            var gwaAxisName = name ?? "";

            gwa = "";
            double[] globalOrigin = { 0, 0, 0 };
            double[] globalXdir   = { 1, 0, 0 };
            double[] globalYdir   = { 0, 1, 0 };
            double[] globalZdir   = { 0, 0, 1 };

            if (axis == null ||
                (
                    axis.Xdir.Value.SequenceEqual(globalXdir) &&
                    axis.Ydir.Value.SequenceEqual(globalYdir) &&
                    axis.Normal.Value.SequenceEqual(globalZdir)))
            {
                return;
            }

            var ls = new List <string>
            {
                "SET",
                "AXIS.1",
                Index.ToString(),
                gwaAxisName,
                "CART",

                axis.Origin.Value[0].ToString(),
                axis.Origin.Value[1].ToString(),
                axis.Origin.Value[2].ToString(),

                axis.Xdir.Value[0].ToString(),
                axis.Xdir.Value[1].ToString(),
                axis.Xdir.Value[2].ToString(),

                axis.Ydir.Value[0].ToString(),
                axis.Ydir.Value[1].ToString(),
                axis.Ydir.Value[2].ToString()
            };

            gwa = string.Join("\t", ls);
        }
Beispiel #12
0
        public static void SetAxis(StructuralAxis axis, out int index, out string gwa, string name = "")
        {
            var gwaAxisName = name ?? "";

            index = 0;
            gwa   = "";

            if (axis == null ||
                (axis.Xdir.Value.SequenceEqual(new double[] { 1, 0, 0 }) &&
                 axis.Ydir.Value.SequenceEqual(new double[] { 0, 1, 0 }) &&
                 axis.Normal.Value.SequenceEqual(new double[] { 0, 0, 1 })))
            {
                return;
            }
            var res = Initialiser.Cache.ResolveIndex("AXIS.1");

            var ls = new List <string>
            {
                "SET",
                "AXIS.1",
                res.ToString(),
                gwaAxisName,
                "CART",

                "0",
                "0",
                "0",

                axis.Xdir.Value[0].ToString(),
                axis.Xdir.Value[1].ToString(),
                axis.Xdir.Value[2].ToString(),

                axis.Ydir.Value[0].ToString(),
                axis.Ydir.Value[1].ToString(),
                axis.Ydir.Value[2].ToString()
            };

            gwa = string.Join("\t", ls);

            index = res;
        }
        public static GsaAxis ToNativeSchema(this StructuralAxis axis)
        {
            var keyword = GsaRecord.GetKeyword <GsaAxis>();
            var index   = Initialiser.AppResources.Cache.ResolveIndex(keyword);
            var origin  = (Valid(axis.Origin)) ? axis.Origin : new SpecklePoint(0, 0, 0);
            var gsaAxis = new GsaAxis()
            {
                Index   = index,
                Name    = axis.Name,
                OriginX = origin.Value[0],
                OriginY = origin.Value[1],
                OriginZ = origin.Value[2],
                XDirX   = axis.Xdir.Value[0],
                XDirY   = axis.Xdir.Value[1],
                XDirZ   = axis.Xdir.Value[2],
                XYDirX  = axis.Ydir.Value[0],
                XYDirY  = axis.Ydir.Value[1],
                XYDirZ  = axis.Ydir.Value[2]
            };

            return(gsaAxis);
        }
Beispiel #14
0
        /// <summary>
        /// Calculates rotation angle of 1D entity to align with axis.
        /// </summary>
        /// <param name="axis">Axis of entity</param>
        /// <returns>Rotation angle</returns>
        public static double Get1DAngle(StructuralAxis axis)
        {
            var axisX = new Vector3D(axis.Xdir.Value[0], axis.Xdir.Value[1], axis.Xdir.Value[2]);
            var axisY = new Vector3D(axis.Ydir.Value[0], axis.Ydir.Value[1], axis.Ydir.Value[2]);
            var axisZ = new Vector3D(axis.Normal.Value[0], axis.Normal.Value[1], axis.Normal.Value[2]);

            if (axisX.X == 0 && axisX.Y == 0)
            {
                // Column
                var Yglobal = new Vector3D(0, 1, 0);

                var angle = Math.Acos(Vector3D.DotProduct(Yglobal, axisY) / (Yglobal.Length * axisY.Length)).ToDegrees();
                if (double.IsNaN(angle))
                {
                    return(0);
                }

                var signVector = Vector3D.CrossProduct(Yglobal, axisY);
                var sign       = Vector3D.DotProduct(signVector, axisX);

                return(sign >= 0 ? angle : -angle);
            }
            else
            {
                var Zglobal = new Vector3D(0, 0, 1);
                var Y0      = Vector3D.CrossProduct(Zglobal, axisX);
                var angle   = Math.Acos(Vector3D.DotProduct(Y0, axisY) / (Y0.Length * axisY.Length)).ToDegrees();
                if (double.IsNaN(angle))
                {
                    angle = 0;
                }

                var signVector = Vector3D.CrossProduct(Y0, axisY);
                var sign       = Vector3D.DotProduct(signVector, axisX);

                return(sign >= 0 ? angle : 360 - angle);
            }
        }
Beispiel #15
0
        /// <summary>
        /// Maps a flat array of coordinates from a local coordinate system to the global Cartesian coordinate system.
        /// </summary>
        /// <param name="values">Flat array of coordinates</param>
        /// <param name="axis">Local coordinate system</param>
        /// <returns>Transformed array of coordinates</returns>
        public static double[] MapPointsLocal2Global(IEnumerable <double> values, StructuralAxis axis)
        {
            var newVals = new List <double>();

            for (var i = 0; i < values.Count(); i += 3)
            {
                var coor = values.Skip(i).Take(3).ToList();

                double x = 0;
                double y = 0;
                double z = 0;

                x += axis.Xdir.Value[0] * coor[0];
                y += axis.Xdir.Value[1] * coor[0];
                z += axis.Xdir.Value[2] * coor[0];

                x += axis.Ydir.Value[0] * coor[1];
                y += axis.Ydir.Value[1] * coor[1];
                z += axis.Ydir.Value[2] * coor[1];

                x += axis.Normal.Value[0] * coor[2];
                y += axis.Normal.Value[1] * coor[2];
                z += axis.Normal.Value[2] * coor[2];

                if (axis.Origin != null && axis.Origin.Value != null && axis.Origin.Value.Count == 3)
                {
                    x += axis.Origin.Value[0];
                    y += axis.Origin.Value[1];
                    z += axis.Origin.Value[2];
                }
                newVals.Add(x);
                newVals.Add(y);
                newVals.Add(z);
            }

            return(newVals.ToArray());
        }
        protected List <string> SetAxisPlaneGWACommands(StructuralAxis axis, string planeName, out int gridPlaneIndex, double?elevation = null,
                                                        double?elevationAbove = null, double?elevationBelow = null, GridPlaneType gridPlaneType = GridPlaneType.General, string sid = null)
        {
            var gridPlaneKeyword = "GRID_PLANE.4";

            gridPlaneIndex = Initialiser.Cache.ResolveIndex(gridPlaneKeyword);

            var ls = new List <string>();

            var gwaCommands = new List <string>();

            Helper.SetAxis(axis, out var planeAxisIndex, out var planeAxisGwa, planeName);
            if (planeAxisGwa.Length > 0)
            {
                gwaCommands.Add(planeAxisGwa);
            }

            var planeType = gridPlaneType.ToString().ToUpper();

            ls.Clear();

            ls.AddRange(new[] {
                "SET",
                gridPlaneKeyword + ((sid == null) ? "" : ":" + sid),
                gridPlaneIndex.ToString(),
                (string.IsNullOrEmpty(planeName)) ? " " : planeName,
                planeType,                        // Type
                planeAxisIndex.ToString(),
                (elevation ?? 0).ToString(),      // Elevation
                (elevationBelow ?? 0).ToString(), // tolerance below
                (elevationAbove ?? 0).ToString()
            });

            gwaCommands.Add(string.Join("\t", ls));

            return(gwaCommands);
        }
Beispiel #17
0
        public string SetGWACommand()
        {
            if (this.Value == null)
            {
                return("");
            }

            var destType = typeof(GSABridgeAlignment);

            var alignment = this.Value as StructuralBridgeAlignment;

            if (alignment.ApplicationId == null)
            {
                return("");
            }

            var keyword = destType.GetGSAKeyword();

            var gridSurfaceIndex = Initialiser.AppResources.Cache.ResolveIndex("GRID_SURFACE.1");
            var gridPlaneIndex   = Initialiser.AppResources.Cache.ResolveIndex("GRID_PLANE.4");

            var index = Initialiser.AppResources.Cache.ResolveIndex(keyword, alignment.ApplicationId);

            var sid = Helper.GenerateSID(alignment);

            var gwaCommands = new List <string>();

            var ls = new List <string>();

            int axisIndex = 1;

            if (alignment.Plane != null)
            {
                var axis = new StructuralAxis()
                {
                    Xdir = alignment.Plane.Xdir, Ydir = alignment.Plane.Ydir, Origin = alignment.Plane.Origin
                };
                axis.Normal = alignment.Plane.Normal ?? CrossProduct(alignment.Plane.Xdir, alignment.Plane.Ydir);

                Helper.SetAxis(axis, out axisIndex, out var axisGwa, alignment.Name);
                if (axisGwa.Length > 0)
                {
                    gwaCommands.Add(axisGwa);
                }
            }

            ls.Clear();
            ls.AddRange(new[] {
                "SET",
                "GRID_PLANE.4",
                gridPlaneIndex.ToString(),
                alignment.Name == null || alignment.Name == "" ? " " : alignment.Name,
                "GENERAL", // Type
                axisIndex.ToString(),
                "0",       // Elevation assumed to be at local z=0 (i.e. dictated by the origin)
                "0",       // Elevation above
                "0"
            });            // Elevation below

            gwaCommands.Add(string.Join(Initialiser.AppResources.Proxy.GwaDelimiter.ToString(), ls));

            ls.Clear();
            ls.AddRange(new[] {
                "SET",
                "GRID_SURFACE.1",
                gridSurfaceIndex.ToString(),
                alignment.Name == null || alignment.Name == "" ? " " : alignment.Name,
                gridPlaneIndex.ToString(),
                "2",    // Dimension of elements to target
                "all",  // List of elements to target
                "0.01", // Tolerance
                "ONE",  // Span option
                "0"
            });         // Span angle
            gwaCommands.Add(string.Join(Initialiser.AppResources.Proxy.GwaDelimiter.ToString(), ls));


            ls.Clear();
            ls.AddRange(new []
            {
                "SET",
                keyword + ":" + sid,
                index.ToString(),
                string.IsNullOrEmpty(alignment.Name) ? "" : alignment.Name,
                "1", //Grid surface
                (alignment.Nodes == null ? 0 : alignment.Nodes.Count()).ToString(),
            });

            if (alignment.Nodes != null)
            {
                foreach (var node in alignment.Nodes)
                {
                    ls.Add(node.Chainage.ToString());
                    if (node.Curvature == StructuralBridgeCurvature.Straight)
                    {
                        ls.Add("0");
                    }
                    else
                    {
                        ls.Add(((1d / node.Radius) * ((node.Curvature == StructuralBridgeCurvature.RightCurve) ? 1 : -1)).ToString());
                    }
                }
                gwaCommands.Add(string.Join(Initialiser.AppResources.Proxy.GwaDelimiter.ToString(), ls));
            }

            return(string.Join("\n", gwaCommands));
        }
Beispiel #18
0
        public static double[] MapGlobal2Local(this IEnumerable <double> globalCoords, StructuralAxis axis)
        {
            var coords = globalCoords.ToArray();

            if (axis == null)
            {
                return(coords);
            }
            var cartesianDifference = (axis.Origin == null || axis.Origin.Value == null || axis.Origin.Value.Count != 3)
        ? coords
        : new double[] { coords[0] - axis.Origin.Value[0], coords[1] - axis.Origin.Value[1], coords[2] - axis.Origin.Value[2] };

            var A = Matrix <double> .Build.DenseOfArray(new double[, ] {
                { axis.Xdir.Value[0], axis.Xdir.Value[1], axis.Xdir.Value[2] },
                { axis.Ydir.Value[0], axis.Ydir.Value[1], axis.Ydir.Value[2] },
                { axis.Normal.Value[0], axis.Normal.Value[1], axis.Normal.Value[2] }
            });

            A = A.Transpose();
            var b = Vector <double> .Build.Dense(cartesianDifference);

            var coefficients = A.Solve(b);

            return(coefficients.Select(c => Math.Round(c, 10)).ToArray());
        }
 public static bool ValidNonZero(this StructuralAxis axis)
 {
     return(axis != null && axis.Xdir != null && axis.Ydir != null && axis.Xdir.Value.Any(v => v != 0) && axis.Ydir.Value.Any(v => v != 0));
 }
Beispiel #20
0
        public static string ToNative(this Structural2DLoadPanel loadPanel)
        {
            if (string.IsNullOrEmpty(loadPanel.ApplicationId))
            {
                return("");
            }
            if (loadPanel.Loading == null || loadPanel.Loading.Value == null || loadPanel.Loading.Value.All(v => v == 0))
            {
                Initialiser.AppResources.Messenger.CacheMessage(MessageIntent.Display, MessageLevel.Error, "Structural2DLoadPanel with no loading", loadPanel.ApplicationId);
                return("");
            }

            var keyword           = GsaRecord.GetKeyword <GsaLoadGridArea>();
            var gwaSetCommandType = GsaRecord.GetGwaSetCommandType <GsaLoadGridArea>();
            var streamId          = Initialiser.AppResources.Cache.LookupStream(loadPanel.ApplicationId);

            var loadCaseKeyword = GsaRecord.GetKeyword <GsaLoadCase>();
            var loadCaseIndex   = Initialiser.AppResources.Cache.ResolveIndex(loadCaseKeyword, loadPanel.LoadCaseRef);

            var loadingDict      = ExplodeLoading(loadPanel.Loading);
            var originalPolyline = loadPanel.Value.ToArray();

            //There are two possible axes at play here:
            //1.  one associated with the grid surface (referred by LoadPlaneRef) applied to the coordinates of the polyline
            //2.  one associated with the loading - i.e. applied to the load
            //Note: only the first is supported here

            //When retrieving the axis (to use in transforming the polyline etc), there are two routes here:
            //1.  referencing a load plane (grid surface)
            //2.  not referencing a load plane, in which case a grid surface and axis needs to be created

            var gridSurfaceKeyword = GsaRecord.GetKeyword <GsaGridSurface>();
            var gridPlaneKeyword   = GsaRecord.GetKeyword <GsaGridPlane>();
            var axisKeyword        = GsaRecord.GetKeyword <GsaAxis>();

            StructuralAxis axis             = null;
            int            gridSurfaceIndex = 0;

            if (string.IsNullOrEmpty(loadPanel.LoadPlaneRef))
            {
                //If there is no load plane (corresponding to GRID_SURFACE in GSA terms) specified, then at minimum a GRID_SURFACE still needs
                //to be created but it doesn't need to refer to a GRID_PLANE because that load plane can just have "GLOBAL" set for its plane.

                //HOWEVER, the approach taken here - which could be reviewed - is to create one anyway, whose X and y axes are based on the polyline
                //so that an elevation value can be set in the GRID_PLANE

                //Create axis based on the polyline
                try
                {
                    axis      = SpeckleStructuralGSA.Helper.Parse2DAxis(originalPolyline);
                    axis.Name = loadPanel.Name;
                    var gsaAxis = StructuralAxisToNative.ToNativeSchema(axis);
                    gsaAxis.StreamId = streamId;
                    StructuralAxisToNative.ToNative(gsaAxis);

                    var gridPlaneIndex = Initialiser.AppResources.Cache.ResolveIndex(gridPlaneKeyword);
                    var gsaGridPlane   = new GsaGridPlane()
                    {
                        Index       = gridPlaneIndex,
                        Name        = loadPanel.Name,
                        StreamId    = streamId,
                        AxisRefType = GridPlaneAxisRefType.Reference,
                        AxisIndex   = gsaAxis.Index,
                        Elevation   = AxisElevation(axis, originalPolyline),
                        Type        = GridPlaneType.General,
                        StoreyToleranceAboveAuto = true,
                        StoreyToleranceBelowAuto = true
                    };
                    if (gsaGridPlane.Gwa(out var gsaGridPlaneGwas, false))
                    {
                        Initialiser.AppResources.Cache.Upsert(gridPlaneKeyword, gridPlaneIndex, gsaGridPlaneGwas.First(), streamId, "", GsaRecord.GetGwaSetCommandType <GsaGridPlane>());
                    }

                    gridSurfaceIndex = Initialiser.AppResources.Cache.ResolveIndex(gridSurfaceKeyword);
                    var gsaGridSurface = new GsaGridSurface()
                    {
                        Index        = gridSurfaceIndex,
                        PlaneRefType = GridPlaneAxisRefType.Reference,
                        StreamId     = streamId,
                        PlaneIndex   = gridPlaneIndex,
                        Name         = loadPanel.Name,
                        AllIndices   = true,
                        Type         = GridSurfaceElementsType.TwoD,
                        Span         = GridSurfaceSpan.One,
                        Angle        = 0,
                        Tolerance    = 0.01,
                        Expansion    = GridExpansion.PlaneCorner
                    };
                    if (gsaGridSurface.Gwa(out var gsaGridSurfaceGwas, false))
                    {
                        Initialiser.AppResources.Cache.Upsert(gridSurfaceKeyword, gridSurfaceIndex, gsaGridSurfaceGwas.First(), streamId, "", GsaRecord.GetGwaSetCommandType <GsaGridSurface>());
                    }
                }
                catch
                {
                    Initialiser.AppResources.Messenger.CacheMessage(MessageIntent.Display, MessageLevel.Error, "Generating axis from coordinates for 2D load panel", loadPanel.ApplicationId);
                }
            }
            else
            {
                //Get axis from load plane using LoadPlaneRef
                //Within this option, there are two routes to retrieve the axis:
                //1.  the StructuralLoadPlane has its own axis (because AxisRefs aren't offered yet in the Structural classes)
                //2.  the StructuralLoadPlane references a StructuralStorey, which has an axis

                gridSurfaceIndex = Initialiser.AppResources.Cache.ResolveIndex(gridSurfaceKeyword, loadPanel.LoadPlaneRef);
                var gsaGridSurfaceGwa = Initialiser.AppResources.Cache.GetGwa(gridSurfaceKeyword, gridSurfaceIndex).First();

                var gsaGridSurface = new GsaGridSurface();
                if (gsaGridSurface.FromGwa(gsaGridSurfaceGwa))
                {
                    if (gsaGridSurface.PlaneRefType == GridPlaneAxisRefType.Reference && gsaGridSurface.PlaneIndex.ValidNonZero())
                    {
                        var gsaGridPlaneGwa = Initialiser.AppResources.Cache.GetGwa(gridPlaneKeyword, gsaGridSurface.PlaneIndex.Value).First();

                        var gsaGridPlane = new GsaGridPlane();
                        if (gsaGridPlane.FromGwa(gsaGridPlaneGwa))
                        {
                            if (gsaGridPlane.AxisRefType == GridPlaneAxisRefType.Reference && gsaGridPlane.AxisIndex.ValidNonZero())
                            {
                                var axisIndex = gsaGridPlane.AxisIndex.Value;

                                var gsaAxisGwa = Initialiser.AppResources.Cache.GetGwa(axisKeyword, axisIndex).First();
                                var gsaAxis    = new GsaAxis();
                                if (gsaAxis.FromGwa(gsaAxisGwa))
                                {
                                    axis = (StructuralAxis)gsaAxis.ToSpeckle();
                                }
                                else
                                {
                                    Initialiser.AppResources.Messenger.CacheMessage(MessageIntent.Display, MessageLevel.Error, "Unable to parse AXIS GWA", loadPanel.ApplicationId);
                                }
                            }
                            else
                            {
                                Initialiser.AppResources.Messenger.CacheMessage(MessageIntent.Display, MessageLevel.Error, "Invalid AXIS reference", loadPanel.ApplicationId);
                            }
                        }
                        else
                        {
                            Initialiser.AppResources.Messenger.CacheMessage(MessageIntent.Display, MessageLevel.Error, "Unable to parse GRID_PLANE GWA", loadPanel.ApplicationId);
                        }
                    }
                    else
                    {
                        Initialiser.AppResources.Messenger.CacheMessage(MessageIntent.Display, MessageLevel.Error, "Invalid GRID_PLANE reference", loadPanel.ApplicationId);
                    }
                }
                else
                {
                    Initialiser.AppResources.Messenger.CacheMessage(MessageIntent.Display, MessageLevel.Error, "Unable to parse GRID_SURFACE GWA", loadPanel.ApplicationId);
                }
            }

            // Transform polygon coordinates to the relevant axis
            // keep in mind that the 2D load panel inherits from SpecklePolyline
            var polyline = SpeckleStructuralGSA.Helper.MapPointsGlobal2Local(originalPolyline, axis);

            foreach (var k in loadingDict.Keys)
            {
                var applicationId = string.Join("_", loadPanel.ApplicationId, k.ToString());
                var index         = Initialiser.AppResources.Cache.ResolveIndex(keyword, applicationId);

                var gsaLoadPanel = new GsaLoadGridArea()
                {
                    Index            = index,
                    ApplicationId    = applicationId,
                    StreamId         = streamId,
                    Name             = loadPanel.Name,
                    Value            = loadingDict[k],
                    GridSurfaceIndex = gridSurfaceIndex,
                    LoadDirection    = k,
                    LoadCaseIndex    = loadCaseIndex,
                    //No support yet for an axis separate to the grid surface's, on which the loading is applied
                    AxisRefType = AxisRefType.Global,
                    //No support yet for whole-plane 2D load panels - all assumed to be based on polyline/polygon
                    Area      = LoadAreaOption.Polygon,
                    Polygon   = PolylineCoordsToGwaPolygon(polyline),
                    Projected = false
                };
                if (gsaLoadPanel.Gwa(out var gsaLoadPanelGwas, false))
                {
                    Initialiser.AppResources.Cache.Upsert(keyword, index, gsaLoadPanelGwas.First(), streamId, applicationId, GsaRecord.GetGwaSetCommandType <GsaLoadGridArea>());
                }
            }

            return("");
        }
        public static List <SpeckleObject> ToSpeckle(this BoundaryConditions myRestraint)
        {
            var points = new List <XYZ>();

            var restraintType = myRestraint.GetBoundaryConditionsType();

            if (restraintType == BoundaryConditionsType.Point)
            {
                var point = myRestraint.Point;
                points.Add(point);
            }
            else if (restraintType == BoundaryConditionsType.Line)
            {
                var curve = myRestraint.GetCurve();
                points.Add(curve.GetEndPoint(0));
                points.Add(curve.GetEndPoint(1));
            }
            else if (restraintType == BoundaryConditionsType.Area)
            {
                var loops = myRestraint.GetLoops();
                foreach (var loop in loops)
                {
                    foreach (var curve in loop)
                    {
                        points.Add(curve.GetEndPoint(0));
                        points.Add(curve.GetEndPoint(1));
                    }
                }
                points = points.Distinct().ToList();
            }

            var coordinateSystem = myRestraint.GetDegreesOfFreedomCoordinateSystem();
            var axis             = new StructuralAxis(
                new StructuralVectorThree(new double[] { coordinateSystem.BasisX.X, coordinateSystem.BasisX.Y, coordinateSystem.BasisX.Z }),
                new StructuralVectorThree(new double[] { coordinateSystem.BasisY.X, coordinateSystem.BasisY.Y, coordinateSystem.BasisY.Z }),
                new StructuralVectorThree(new double[] { coordinateSystem.BasisZ.X, coordinateSystem.BasisZ.Y, coordinateSystem.BasisZ.Z })
                );

            var restraint = new StructuralVectorBoolSix(new bool[6]);
            var stiffness = new StructuralVectorSix(new double[6]);

            var listOfParams = new BuiltInParameter[] {
                BuiltInParameter.BOUNDARY_DIRECTION_X,
                BuiltInParameter.BOUNDARY_DIRECTION_Y,
                BuiltInParameter.BOUNDARY_DIRECTION_Z,
                BuiltInParameter.BOUNDARY_DIRECTION_ROT_X,
                BuiltInParameter.BOUNDARY_DIRECTION_ROT_Y,
                BuiltInParameter.BOUNDARY_DIRECTION_ROT_Z
            };

            var listOfSpringParams = new BuiltInParameter[] {
                BuiltInParameter.BOUNDARY_RESTRAINT_X,
                BuiltInParameter.BOUNDARY_RESTRAINT_Y,
                BuiltInParameter.BOUNDARY_RESTRAINT_Z,
                BuiltInParameter.BOUNDARY_RESTRAINT_ROT_X,
                BuiltInParameter.BOUNDARY_RESTRAINT_ROT_Y,
                BuiltInParameter.BOUNDARY_RESTRAINT_ROT_Z,
            };

            for (var i = 0; i < 6; i++)
            {
                switch (myRestraint.get_Parameter(listOfParams[i]).AsInteger())
                {
                case 0:
                    restraint.Value[i] = true;
                    break;

                case 1:
                    restraint.Value[i] = false;
                    break;

                case 2:
                    stiffness.Value[i] = myRestraint.get_Parameter(listOfSpringParams[i]).AsDouble();
                    break;
                }
            }
            restraint.GenerateHash();
            stiffness.GenerateHash();

            var myNodes = new List <SpeckleObject>();

            foreach (var point in points)
            {
                var myPoint = (SpeckleCoreGeometryClasses.SpecklePoint)SpeckleCore.Converter.Serialise(point);
                var myNode  = new StructuralNode();
                myNode.basePoint = myPoint;
                myNode.Axis      = axis;
                myNode.Restraint = restraint;
                myNode.Stiffness = stiffness;
                myNodes.Add(myNode);
            }

            return(myNodes);
        }
Beispiel #22
0
        public static SpeckleObject ToSpeckle(this GSA0DLoad dummyObject)
        {
            var newLines = ToSpeckleBase <GSA0DLoad>();

            var loads = new List <GSA0DLoad>();

            var nodes = Initialiser.GSASenderObjects[typeof(GSANode)].Cast <GSANode>().ToList();


            foreach (var p in newLines.Values)
            {
                var loadSubList = new List <GSA0DLoad>();

                // Placeholder load object to get list of nodes and load values
                // Need to transform to axis so one load definition may be transformed to many
                var initLoad = new GSA0DLoad()
                {
                    GWACommand = p
                };
                initLoad.ParseGWACommand(nodes);

                // Raise node flag to make sure it gets sent
                foreach (var n in nodes.Where(n => initLoad.Value.NodeRefs.Contains(n.Value.ApplicationId)))
                {
                    n.ForceSend = true;
                }

                // Create load for each node applied
                foreach (string nRef in initLoad.Value.NodeRefs)
                {
                    var load = new GSA0DLoad
                    {
                        GWACommand    = initLoad.GWACommand,
                        SubGWACommand = new List <string>(initLoad.SubGWACommand)
                    };
                    load.Value.Name        = initLoad.Value.Name;
                    load.Value.LoadCaseRef = initLoad.Value.LoadCaseRef;

                    // Transform load to defined axis
                    var            node      = nodes.Where(n => (n.Value.ApplicationId == nRef)).First();
                    string         gwaRecord = null;
                    StructuralAxis loadAxis  = HelperClass.Parse0DAxis(initLoad.Axis, Initialiser.Interface, out gwaRecord, node.Value.Value.ToArray());
                    load.Value.Loading = initLoad.Value.Loading;
                    load.Value.Loading.TransformOntoAxis(loadAxis);

                    // If the loading already exists, add node ref to list
                    var match = loadSubList.Count() > 0 ? loadSubList.Where(l => (l.Value.Loading.Value as List <double>).SequenceEqual(load.Value.Loading.Value as List <double>)).First() : null;
                    if (match != null)
                    {
                        match.Value.NodeRefs.Add(nRef);
                        if (gwaRecord != null)
                        {
                            match.SubGWACommand.Add(gwaRecord);
                        }
                    }
                    else
                    {
                        load.Value.NodeRefs = new List <string>()
                        {
                            nRef
                        };
                        if (gwaRecord != null)
                        {
                            load.SubGWACommand.Add(gwaRecord);
                        }
                        loadSubList.Add(load);
                    }
                }

                loads.AddRange(loadSubList);
            }

            Initialiser.GSASenderObjects[typeof(GSA0DLoad)].AddRange(loads);

            return((loads.Count() > 0) ? new SpeckleObject() : new SpeckleNull());
        }
        public string SetGWACommand()
        {
            if (this.Value == null)
            {
                return("");
            }

            var load = this.Value as Structural1DLoadLine;

            if (load.ApplicationId == null)
            {
                return("");
            }

            var keyword = typeof(GSAGridLineLoad).GetGSAKeyword();

            //There are no GSA types for these yet, so use empty strings for the type names

            var loadCaseKeyword = typeof(GSALoadCase).GetGSAKeyword();

            var indexResult = Initialiser.AppResources.Cache.LookupIndex(loadCaseKeyword, load.LoadCaseRef);
            var loadCaseRef = indexResult ?? Initialiser.AppResources.Cache.ResolveIndex(loadCaseKeyword, load.LoadCaseRef);

            if (indexResult == null && load.ApplicationId != null)
            {
                if (load.LoadCaseRef == null)
                {
                    Helper.SafeDisplay("Blank load case references found for these Application IDs:", load.ApplicationId);
                }
                else
                {
                    Helper.SafeDisplay("Load case references not found:", load.ApplicationId + " referencing " + load.LoadCaseRef);
                }
            }

            StructuralAxis axis        = null;
            var            ls          = new List <string>();
            var            gwaCommands = new List <string>();
            int            gridSurfaceIndex;

            double elevation = 0;

            if (string.IsNullOrEmpty(load.LoadPlaneRef))
            {
                axis = (load.Value == null)
          ? new StructuralAxis(new StructuralVectorThree(1, 0, 0), new StructuralVectorThree(0, 1, 0))
          : Helper.Parse1DAxis(load.Value.ToArray());

                Helper.SetAxis(axis, out int planeAxisIndex, out string planeAxisGwa, load.Name);
                if (planeAxisGwa.Length > 0)
                {
                    gwaCommands.Add(planeAxisGwa);
                }

                if (load.Value != null)
                {
                    // Calculate elevation
                    elevation = (load.Value[0] * axis.Normal.Value[0] +
                                 load.Value[1] * axis.Normal.Value[1] +
                                 load.Value[2] * axis.Normal.Value[2]) /
                                Math.Sqrt(axis.Normal.Value[0] * axis.Normal.Value[0] +
                                          axis.Normal.Value[1] * axis.Normal.Value[1] +
                                          axis.Normal.Value[2] * axis.Normal.Value[2]);
                }


                gridSurfaceIndex = Initialiser.AppResources.Cache.ResolveIndex("GRID_SURFACE.1");
                var gridPlaneIndex = Initialiser.AppResources.Cache.ResolveIndex("GRID_PLANE.4");

                ls.Clear();
                ls.AddRange(new[] {
                    "SET",
                    "GRID_PLANE.4",
                    gridPlaneIndex.ToString(),
                    load.Name == null || load.Name == "" ? " " : load.Name,
                    "GENERAL", // Type
                    planeAxisIndex.ToString(),
                    elevation.ToString(),
                    "0", // Elevation above
                    "0"
                });      // Elevation below
                gwaCommands.Add(string.Join(Initialiser.AppResources.Proxy.GwaDelimiter.ToString(), ls));

                ls.Clear();
                ls.AddRange(new[] { "SET",
                                    "GRID_SURFACE.1",
                                    gridSurfaceIndex.ToString(),
                                    load.Name == null || load.Name == "" ? " " : load.Name,
                                    gridPlaneIndex.ToString(),
                                    "1",          // Dimension of elements to target
                                    "all",        // List of elements to target
                                    "0.01",       // Tolerance
                                    "TWO_SIMPLE", // Span option
                                    "0" });       // Span angle
                gwaCommands.Add(string.Join(Initialiser.AppResources.Proxy.GwaDelimiter.ToString(), ls));
            }
            else //LoadPlaneRef is not empty/null
            {
                try
                {
                    gridSurfaceIndex = Initialiser.AppResources.Cache.LookupIndex("GRID_SURFACE.1", load.LoadPlaneRef).Value;
                }
                catch
                {
                    gridSurfaceIndex = Initialiser.AppResources.Cache.ResolveIndex("GRID_SURFACE.1", load.LoadPlaneRef);
                }

                var loadPlanesDict = Initialiser.AppResources.Cache.GetIndicesSpeckleObjects(typeof(StructuralLoadPlane).Name);
                if (loadPlanesDict.ContainsKey(gridSurfaceIndex) && loadPlanesDict[gridSurfaceIndex] != null)
                {
                    var loadPlane = ((StructuralLoadPlane)loadPlanesDict[gridSurfaceIndex]);
                    if (loadPlane.Axis != null)
                    {
                        axis = loadPlane.Axis;
                    }
                    else
                    {
                        try
                        {
                            var storeyIndex = Initialiser.AppResources.Cache.LookupIndex("GRID_PLANE.4", loadPlane.StoreyRef).Value;
                            var storeysDict = Initialiser.AppResources.Cache.GetIndicesSpeckleObjects(typeof(StructuralStorey).Name);
                            if (storeysDict.ContainsKey(storeyIndex) && storeysDict[storeyIndex] != null)
                            {
                                var storey = ((StructuralStorey)storeysDict[storeyIndex]);
                                if (storey.Axis != null)
                                {
                                    axis = storey.Axis;
                                }
                            }
                        }
                        catch { }

                        if (axis == null)
                        {
                            axis = new StructuralAxis(new StructuralVectorThree(1, 0, 0), new StructuralVectorThree(0, 1, 0));
                        }
                    }
                }
            }

            // Transform coordinate to new axis
            var transformed = Helper.MapPointsGlobal2Local(load.Value.ToArray(), axis);

            var direction = new string[3] {
                "X", "Y", "Z"
            };

            for (var i = 0; i < Math.Min(direction.Count(), load.Loading.Value.Count()); i++)
            {
                if (load.Loading.Value[i] == 0)
                {
                    continue;
                }

                var subLs = new List <string>();
                for (var j = 0; j < transformed.Count(); j += 3)
                {
                    subLs.Add("(" + transformed[j].ToString() + "," + transformed[j + 1].ToString() + ")");
                }

                ls.Clear();

                var index = Initialiser.AppResources.Cache.ResolveIndex(typeof(GSAGridLineLoad).GetGSAKeyword());

                var sid = Helper.GenerateSID(load);
                ls.AddRange(new[] {
                    "SET_AT",
                    index.ToString(),
                    keyword + (string.IsNullOrEmpty(sid) ? "" : ":" + sid),
                    load.Name == null || load.Name == "" ? " " : load.Name + (load.Name.All(char.IsDigit) ? " " : ""),
                    gridSurfaceIndex.ToString(),
                    "POLYGON",
                    string.Join(" ", subLs),
                    loadCaseRef.ToString(),
                    "GLOBAL",
                    "NO",
                    direction[i],
                    load.Loading.Value[i].ToString(),
                    load.LoadingEnd == null ? load.Loading.Value[i].ToString() : load.LoadingEnd.Value[i].ToString()
                });

                gwaCommands.Add(string.Join(Initialiser.AppResources.Proxy.GwaDelimiter.ToString(), ls));
            }

            return(string.Join("\n", gwaCommands));
        }
        public static SpeckleObject ToSpeckle(this GSA2DLoad dummyObject)
        {
            var newLines = ToSpeckleBase <GSA2DLoad>();

            var loads    = new List <GSA2DLoad>();
            var elements = (Initialiser.Settings.TargetLayer == GSATargetLayer.Analysis) ? Initialiser.GSASenderObjects[typeof(GSA2DElement)].Cast <GSA2DElement>().ToList() : new List <GSA2DElement>();
            var members  = (Initialiser.Settings.TargetLayer == GSATargetLayer.Design) ? Initialiser.GSASenderObjects[typeof(GSA2DMember)].Cast <GSA2DMember>().ToList() : new List <GSA2DMember>();

            foreach (var p in newLines.Values)
            {
                var loadSubList = new List <GSA2DLoad>();

                // Placeholder load object to get list of elements and load values
                // Need to transform to axis so one load definition may be transformed to many
                var initLoad = new GSA2DLoad()
                {
                    GWACommand = p
                };
                initLoad.ParseGWACommand(elements, members);

                if (Initialiser.Settings.TargetLayer == GSATargetLayer.Analysis)
                {
                    // Create load for each element applied
                    foreach (string nRef in initLoad.Value.ElementRefs)
                    {
                        var load = new GSA2DLoad
                        {
                            GWACommand    = initLoad.GWACommand,
                            SubGWACommand = new List <string>(initLoad.SubGWACommand)
                        };
                        load.Value.Name        = initLoad.Value.Name;
                        load.Value.LoadCaseRef = initLoad.Value.LoadCaseRef;

                        // Transform load to defined axis
                        var            elem     = elements.Where(e => e.Value.ApplicationId == nRef).First();
                        StructuralAxis loadAxis = HelperClass.Parse2DAxis(elem.Value.Vertices.ToArray(), 0, load.Axis != 0); // Assumes if not global, local
                        load.Value.Loading = initLoad.Value.Loading;

                        // Perform projection
                        if (load.Projected)
                        {
                            load.Value.Loading.Value[0] = 0;
                            load.Value.Loading.Value[1] = 0;
                        }
                        load.Value.Loading.TransformOntoAxis(loadAxis);

                        // If the loading already exists, add element ref to list
                        var match = loadSubList.Count() > 0 ? loadSubList.Where(l => l.Value.Loading.Equals(load.Value.Loading)).First() : null;
                        if (match != null)
                        {
                            match.Value.ElementRefs.Add(nRef);
                        }
                        else
                        {
                            load.Value.ElementRefs = new List <string>()
                            {
                                nRef
                            };
                            loadSubList.Add(load);
                        }
                    }
                }
                else if (Initialiser.Settings.TargetLayer == GSATargetLayer.Design)
                {
                    // Create load for each element applied
                    foreach (string nRef in initLoad.Value.ElementRefs)
                    {
                        var load = new GSA2DLoad
                        {
                            GWACommand    = initLoad.GWACommand,
                            SubGWACommand = new List <string>(initLoad.SubGWACommand),
                        };
                        load.Value.Name        = initLoad.Value.Name;
                        load.Value.LoadCaseRef = initLoad.Value.LoadCaseRef;

                        // Transform load to defined axis
                        var            memb     = members.Where(e => e.Value.ApplicationId == nRef).First();
                        StructuralAxis loadAxis = HelperClass.Parse2DAxis(memb.Value.Vertices.ToArray(), 0, load.Axis != 0); // Assumes if not global, local
                        load.Value.Loading = initLoad.Value.Loading;
                        load.Value.Loading.TransformOntoAxis(loadAxis);

                        // Perform projection
                        if (load.Projected)
                        {
                            load.Value.Loading.Value[0] = 0;
                            load.Value.Loading.Value[1] = 0;
                        }
                        load.Value.Loading.TransformOntoAxis(loadAxis);

                        // If the loading already exists, add element ref to list
                        var match = loadSubList.Count() > 0 ? loadSubList.Where(l => (l.Value.Loading.Value as List <double>).SequenceEqual(load.Value.Loading.Value as List <double>)).First() : null;
                        if (match != null)
                        {
                            match.Value.ElementRefs.Add(nRef);
                        }
                        else
                        {
                            load.Value.ElementRefs = new List <string>()
                            {
                                nRef
                            };
                            loadSubList.Add(load);
                        }
                    }
                }

                loads.AddRange(loadSubList);
            }

            Initialiser.GSASenderObjects[typeof(GSA2DLoad)].AddRange(loads);

            return((loads.Count() > 0) ? new SpeckleObject() : new SpeckleNull());
        }
    public int Group; // Keep for load targetting

    public void ParseGWACommand(List<GSANode> nodes, List<GSA2DProperty> props)
    {
      // MEMB.8 | num | name | colour | type (2D) | exposure | prop | group | topology | node | angle | mesh_size | is_intersector | analysis_type | fire | time[4] | dummy | off_auto_internal | off_z | reinforcement2d |

      if (this.GWACommand == null)
        return;

      var obj = new Structural2DElementMesh();

      var pieces = this.GWACommand.ListSplit(Initialiser.AppResources.Proxy.GwaDelimiter);

      var counter = 1; // Skip identifier
      this.GSAId = Convert.ToInt32(pieces[counter++]);
      obj.ApplicationId = Helper.GetApplicationId(this.GetGSAKeyword(), this.GSAId);
      obj.Name = pieces[counter++].Trim(new char[] { '"' }); // name
      var color = pieces[counter++].ParseGSAColor(); // colour

      var type = pieces[counter++];
      obj.ElementType = (type == "SLAB") ? Structural2DElementType.Slab : (type == "WALL") ? Structural2DElementType.Wall : Structural2DElementType.Generic;

      counter++; // exposure - fire property

      var propertyGSAId = Convert.ToInt32(pieces[counter++]);

      obj.PropertyRef = Helper.GetApplicationId(typeof(GSA2DProperty).GetGSAKeyword(), propertyGSAId);
      this.Group = Convert.ToInt32(pieces[counter++]); // Keep group for load targetting

      // topology
      var coordinates = new List<double>();
      var nodeRefsFull = pieces[counter++];

      //Remove the specification of internal nodes
      var nodeRefsWithoutInternalNodes = Regex.Replace(nodeRefsFull, @"P\([0-9]*(.*?)\)", "");
      nodeRefsWithoutInternalNodes = Regex.Replace(nodeRefsWithoutInternalNodes, @"L\([0-9]*(.*?)\)", "");
      nodeRefsWithoutInternalNodes = Regex.Replace(nodeRefsWithoutInternalNodes, @"V\([0-9]*(.*?)\)", "");

      var nodeRefs = nodeRefsWithoutInternalNodes.Trim().ListSplit(" ");
      for (var i = 0; i < nodeRefs.Length; i++)
      {
        var node = nodes.Where(n => n.GSAId.ToString() == nodeRefs[i]).FirstOrDefault();
        if (node == null)
        {
          //TO DO: review how this is possible and prevent it
          continue;
        }

        coordinates.AddRange(node.Value.Value);
        this.SubGWACommand.Add(node.GWACommand);
      }

      var temp = new Structural2DElementMesh(
          coordinates.Essential(),
          color.HexToArgbColor(),
          obj.ElementType, obj.PropertyRef,
          null,
          null);


      obj.Vertices = temp.Vertices;
      obj.Faces = temp.Faces;
      obj.Colors = temp.Colors;

      var numFaces = 0;
      for (var i = 0; i < obj.Faces.Count(); i++)
      {
        numFaces++;
        i += obj.Faces[i] + 3;
      }

      counter++; // Orientation node

      var prop = props.Where(p => p.Value.ApplicationId == obj.PropertyRef).FirstOrDefault();
      StructuralAxis axis = null;
      try
      {
        axis = Helper.Parse2DAxis(coordinates.ToArray(),
            Convert.ToDouble(pieces[counter++]),
            prop == null ? false : (prop as GSA2DProperty).IsAxisLocal);
      }
      catch
      {
        Initialiser.AppResources.Messenger.CacheMessage(MessageIntent.Display, MessageLevel.Error, "Generating axis from coordinates for 2D member", obj.ApplicationId);
      }

      if (axis != null)
      {
        obj.Axis = Enumerable.Repeat(axis, numFaces).ToList();
        if (prop != null)
        {
          this.SubGWACommand.Add(prop.GWACommand);
        }
      }

      //Since this is a GSA-specific property, only set if not default
      var meshSize = Convert.ToDouble(pieces[counter++]);
      if (meshSize > 0)
      {
        obj.GSAMeshSize = meshSize; // mesh_size
      }

      counter++; // intersector
      counter++; // analysis type

      counter = counter+=6; // skip fire bits to get to dummy status
      //Since this is a GSA-specific property, only set if true;
      var dummy = (pieces[counter++] == "DUMMY");
      if (dummy)
      {
        obj.GSADummy = dummy;
      }

      Initialiser.AppResources.Proxy.GetGSATotal2DElementOffset(propertyGSAId, Convert.ToDouble(pieces[counter++]), out var offset, out var offsetRec);
      this.SubGWACommand.Add(offsetRec);

      obj.Offset = Enumerable.Repeat(offset, numFaces).ToList();

      // skip remaining commands

      if (!obj.Properties.ContainsKey("structural"))
      {
        obj.Properties.Add("structural", new Dictionary<string, object>());
      }
      ((Dictionary<string, object>)obj.Properties["structural"]).Add("NativeId", this.GSAId.ToString());

      this.Value = obj;
    }
        public static SpeckleObject ToSpeckle(this GSA1DLoadDesignLayer dummyObject)
        {
            var newLines = ToSpeckleBase <GSA1DLoadDesignLayer>();

            var loads = new List <GSA1DLoadDesignLayer>();
            //var members = Initialiser.GSASenderObjects.Get<GSA1DMember)].Cast<GSA1DMember>().ToList();
            var members = Initialiser.GSASenderObjects.Get <GSA1DMember>();

            foreach (var p in newLines.Values)
            {
                var loadSubList = new List <GSA1DLoadDesignLayer>();

                // Placeholder load object to get list of elements and load values
                // Need to transform to axis so one load definition may be transformed to many
                var initLoad = new GSA1DLoadDesignLayer()
                {
                    GWACommand = p
                };
                initLoad.ParseGWACommand(members);

                // Create load for each element applied
                foreach (string nRef in initLoad.Value.ElementRefs)
                {
                    var load = new GSA1DLoadDesignLayer
                    {
                        GWACommand    = initLoad.GWACommand,
                        SubGWACommand = new List <string>(initLoad.SubGWACommand)
                    };
                    load.Value.Name        = initLoad.Value.Name;
                    load.Value.LoadCaseRef = initLoad.Value.LoadCaseRef;

                    // Transform load to defined axis
                    var            memb     = members.Where(e => e.Value.ApplicationId == nRef).First();
                    StructuralAxis loadAxis = load.Axis == 0 ? new StructuralAxis(
                        new StructuralVectorThree(new double[] { 1, 0, 0 }),
                        new StructuralVectorThree(new double[] { 0, 1, 0 }),
                        new StructuralVectorThree(new double[] { 0, 0, 1 })) :
                                              Helper.LocalAxisEntity1D(memb.Value.Value.ToArray(), memb.Value.ZAxis); // Assumes if not global, local
                    load.Value.Loading = initLoad.Value.Loading;
                    load.Value.Loading.TransformOntoAxis(loadAxis);

                    // Perform projection
                    if (load.Projected)
                    {
                        var loadDirection = new Vector3D(
                            load.Value.Loading.Value[0],
                            load.Value.Loading.Value[1],
                            load.Value.Loading.Value[2]);

                        if (loadDirection.Length > 0)
                        {
                            var axisX  = new Vector3D(memb.Value[5] - memb.Value[0], memb.Value[4] - memb.Value[1], memb.Value[3] - memb.Value[2]);
                            var angle  = Vector3D.AngleBetween(loadDirection, axisX);
                            var factor = Math.Sin(angle);
                            load.Value.Loading.Value[0] *= factor;
                            load.Value.Loading.Value[1] *= factor;
                            load.Value.Loading.Value[2] *= factor;
                        }
                    }

                    // If the loading already exists, add element ref to list
                    var match = loadSubList.Count() > 0 ? loadSubList.Where(l => l.Value.Loading.Equals(load.Value.Loading)).First() : null;
                    if (match != null)
                    {
                        match.Value.ElementRefs.Add(nRef);
                    }
                    else
                    {
                        load.Value.ElementRefs = new List <string>()
                        {
                            nRef
                        };
                        loadSubList.Add(load);
                    }
                }

                loads.AddRange(loadSubList);
            }

            Initialiser.GSASenderObjects.AddRange(loads);

            return((loads.Count() > 0) ? new SpeckleObject() : new SpeckleNull());
        }
        public static string ToNative(this Structural2DLoadPanel loadPanel)
        {
            if (string.IsNullOrEmpty(loadPanel.ApplicationId))
            {
                return("");
            }

            return(Helper.ToNativeTryCatch(loadPanel, () =>
            {
                if (loadPanel.Loading == null || loadPanel.Loading.Value == null || loadPanel.Loading.Value.All(v => v == 0))
                {
                    Initialiser.AppResources.Messenger.Message(MessageIntent.Display, MessageLevel.Error, "Structural2DLoadPanel with no loading", loadPanel.ApplicationId);
                    return "";
                }

                var keyword = GsaRecord.GetKeyword <GsaLoadGridArea>();
                var gwaSetCommandType = GsaRecord.GetGwaSetCommandType <GsaLoadGridArea>();
                var streamId = Initialiser.AppResources.Cache.LookupStream(loadPanel.ApplicationId);

                var loadCaseKeyword = GsaRecord.GetKeyword <GsaLoadCase>();
                var loadCaseIndex = Initialiser.AppResources.Cache.ResolveIndex(loadCaseKeyword, loadPanel.LoadCaseRef);

                var loadingDict = ExplodeLoading(loadPanel.Loading);
                var originalPolyline = loadPanel.Value.ToArray();

                //There are two possible axes at play here:
                //1.  one associated with the grid surface (referred by LoadPlaneRef) applied to the coordinates of the polyline
                //2.  one associated with the loading - i.e. applied to the load
                //Note: only the first is supported here

                //When retrieving the axis (to use in transforming the polyline etc), there are two routes here:
                //1.  referencing a load plane (grid surface)
                //2.  not referencing a load plane, in which case a grid surface and axis needs to be created

                var gridSurfaceKeyword = GsaRecord.GetKeyword <GsaGridSurface>();
                var gridPlaneKeyword = GsaRecord.GetKeyword <GsaGridPlane>();
                var axisKeyword = GsaRecord.GetKeyword <GsaAxis>();

                StructuralAxis axis = null;
                int gridSurfaceIndex = 0;
                if (string.IsNullOrEmpty(loadPanel.LoadPlaneRef))
                {
                    //If there is no load plane (corresponding to GRID_SURFACE in GSA terms) specified, then at minimum a GRID_SURFACE still needs
                    //to be created but it doesn't need to refer to a GRID_PLANE because that load plane can just have "GLOBAL" set for its plane.

                    //HOWEVER, the approach taken here - which could be reviewed - is to create one anyway, whose X and y axes are based on the polyline
                    //so that an elevation value can be set in the GRID_PLANE

                    //Create axis based on the polyline
                    try
                    {
                        axis = SpeckleStructuralGSA.Helper.Parse2DAxis(originalPolyline);
                        axis.Name = loadPanel.Name;
                        var gsaAxis = StructuralAxisToNative.ToNativeSchema(axis);
                        gsaAxis.StreamId = streamId;
                        StructuralAxisToNative.ToNative(gsaAxis);

                        var gridPlaneIndex = Initialiser.AppResources.Cache.ResolveIndex(gridPlaneKeyword);
                        var gsaGridPlane = new GsaGridPlane()
                        {
                            Index = gridPlaneIndex,
                            Name = loadPanel.Name,
                            StreamId = streamId,
                            AxisRefType = GridPlaneAxisRefType.Reference,
                            AxisIndex = gsaAxis.Index,
                            Elevation = AxisElevation(axis, originalPolyline),
                            Type = GridPlaneType.General,
                            StoreyToleranceAboveAuto = true,
                            StoreyToleranceBelowAuto = true
                        };
                        if (gsaGridPlane.Gwa(out var gsaGridPlaneGwas, false))
                        {
                            Initialiser.AppResources.Cache.Upsert(gridPlaneKeyword, gridPlaneIndex, gsaGridPlaneGwas.First(), streamId, "", GsaRecord.GetGwaSetCommandType <GsaGridPlane>());
                        }

                        gridSurfaceIndex = Initialiser.AppResources.Cache.ResolveIndex(gridSurfaceKeyword);
                        var gsaGridSurface = new GsaGridSurface()
                        {
                            Index = gridSurfaceIndex,
                            PlaneRefType = GridPlaneAxisRefType.Reference,
                            StreamId = streamId,
                            PlaneIndex = gridPlaneIndex,
                            Name = loadPanel.Name,
                            //Not setting indices should cause the code to assume "all"
                            Type = GridSurfaceElementsType.TwoD,
                            Span = GridSurfaceSpan.One,
                            Angle = 0,
                            Tolerance = 0.01,
                            Expansion = GridExpansion.PlaneCorner
                        };
                        if (gsaGridSurface.Gwa(out var gsaGridSurfaceGwas, false))
                        {
                            Initialiser.AppResources.Cache.Upsert(gridSurfaceKeyword, gridSurfaceIndex, gsaGridSurfaceGwas.First(), streamId, "", GsaRecord.GetGwaSetCommandType <GsaGridSurface>());
                        }
                    }