public static string ToNative(this StructuralLoadCase loadCase)
        {
            if (string.IsNullOrEmpty(loadCase.ApplicationId))
            {
                return("");
            }
            return(Helper.ToNativeTryCatch(loadCase, () =>
            {
                var keyword = GsaRecord.GetKeyword <GsaLoadCase>();
                var index = Initialiser.AppResources.Cache.ResolveIndex(keyword, loadCase.ApplicationId);
                var streamId = Initialiser.AppResources.Cache.LookupStream(loadCase.ApplicationId);
                var gsaLoad = new GsaLoadCase()
                {
                    ApplicationId = loadCase.ApplicationId,
                    Index = index,
                    StreamId = streamId,
                    Title = loadCase.Name,
                    CaseType = loadCase.CaseType
                };

                if (gsaLoad.Gwa(out var gwaLines, false))
                {
                    Initialiser.AppResources.Cache.Upsert(keyword, index, gwaLines.First(), streamId, loadCase.ApplicationId, GsaRecord.GetGwaSetCommandType <GsaLoadCase>());
                }
                //TO DO: add to error messages shown on UI
                return "";
            }
Ejemplo n.º 2
0
        public static string ToNative(this Structural1DPropertyExplicit prop)
        {
            if (string.IsNullOrEmpty(prop.ApplicationId))
            {
                return("");
            }

            return(Helper.ToNativeTryCatch(prop, () =>
            {
                var gsaSectionDict = new Dictionary <MaterialType, Func <Structural1DPropertyExplicit, int, GsaSection> >
                {
                    { MaterialType.Concrete, ToGsaSectionConcrete },
                    { MaterialType.Steel, ToGsaSectionSteel },
                    { MaterialType.Generic, ToGsaSectionGeneric }
                };

                var keyword = GsaRecord.GetKeyword <GsaSection>();
                var streamId = Initialiser.AppResources.Cache.LookupStream(prop.ApplicationId);
                var index = Initialiser.AppResources.Cache.ResolveIndex(keyword, prop.ApplicationId);

                var materialIndex = 0;
                var materialType = MaterialType.Generic;

                var materialSteelKeyword = typeof(GSAMaterialSteel).GetGSAKeyword();
                var materialConcKeyword = typeof(GSAMaterialConcrete).GetGSAKeyword();

                var res = Initialiser.AppResources.Cache.LookupIndex(materialSteelKeyword, prop.MaterialRef);
                if (res.HasValue)
                {
                    materialIndex = res.Value;
                    materialType = MaterialType.Steel;
                }
                else
                {
                    res = Initialiser.AppResources.Cache.LookupIndex(materialConcKeyword, prop.MaterialRef);
                    if (res.HasValue)
                    {
                        materialIndex = res.Value;
                        materialType = MaterialType.Concrete;
                    }
                    else
                    {
                        //For generic, set index to 1 as a default
                        materialIndex = 1;
                    }
                }

                var gsaSection = gsaSectionDict[materialType](prop, materialIndex);
                gsaSection.Index = index;
                gsaSection.ApplicationId = prop.ApplicationId;
                gsaSection.Name = prop.Name;

                if (gsaSection.Gwa(out var gwaLines, false))
                {
                    Initialiser.AppResources.Cache.Upsert(keyword, index, gwaLines.First(), streamId, prop.ApplicationId, GsaRecord.GetGwaSetCommandType <GsaSection>());
                }

                return "";
            }));
        public static string ToNative(this Structural0DSpring spring)
        {
            if (string.IsNullOrEmpty(spring.ApplicationId) || spring.Value == null || string.IsNullOrEmpty(spring.PropertyRef))
            {
                return("");
            }

            return(Helper.ToNativeTryCatch(spring, () =>
            {
                var propIndex = Initialiser.AppResources.Cache.LookupIndex(GsaRecord.GetKeyword <GsaPropSpr>(), spring.PropertyRef);
                if (propIndex == null)
                {
                    //TO DO : add error message
                    return "";
                }

                var keyword = GsaRecord.GetKeyword <GsaNode>();
                var streamId = Initialiser.AppResources.Cache.LookupStream(spring.ApplicationId);
                var index = Initialiser.AppResources.Proxy.NodeAt(spring.Value[0], spring.Value[1], spring.Value[2], Initialiser.AppResources.Settings.CoincidentNodeAllowance);

                var existingGwa = Initialiser.AppResources.Cache.GetGwa(keyword, index);
                GsaNode gsaNode;
                if (existingGwa == null || existingGwa.Count() == 0 || string.IsNullOrEmpty(existingGwa.First()))
                {
                    gsaNode = new GsaNode()
                    {
                        Index = index,
                        ApplicationId = spring.ApplicationId,
                        Name = spring.Name,
                        StreamId = streamId,
                        X = spring.Value[0],
                        Y = spring.Value[1],
                        Z = spring.Value[2],
                        SpringPropertyIndex = propIndex
                    };
                }
                else
                {
                    gsaNode = new GsaNode();
                    if (!gsaNode.FromGwa(existingGwa.First()))
                    {
                        //TO DO: add error mesage
                        return "";
                    }
                    gsaNode.SpringPropertyIndex = propIndex;
                }

                //Yes, the Axis member of the Speckle StructuralSpringProperty object is not used

                if (gsaNode.Gwa(out var gwaLines, false))
                {
                    Initialiser.AppResources.Cache.Upsert(keyword, gsaNode.Index.Value, gwaLines.First(), streamId, gsaNode.ApplicationId, GsaRecord.GetGwaSetCommandType <GsaNode>());
                }

                return "";
            }
Ejemplo n.º 4
0
        public static string ToNative(this StructuralStorey storey)
        {
            if (string.IsNullOrEmpty(storey.ApplicationId) && Helper.IsZeroAxis(storey.Axis))
            {
                return("");
            }

            return(Helper.ToNativeTryCatch(storey, () =>
            {
                var keyword = GsaRecord.GetKeyword <GsaGridPlane>();
                var index = Initialiser.AppResources.Cache.ResolveIndex(keyword, storey.ApplicationId);
                var streamId = Initialiser.AppResources.Cache.LookupStream(storey.ApplicationId);

                var gsaPlane = new GsaGridPlane()
                {
                    Index = index,
                    ApplicationId = storey.ApplicationId,
                    StreamId = streamId,
                    Name = storey.Name,
                    Elevation = storey.Elevation,
                    Type = GridPlaneType.Storey,
                };

                gsaPlane.StoreyToleranceAboveAuto = (!storey.ToleranceAbove.HasValue || storey.ToleranceAbove.Value == 0);
                if (storey.ToleranceBelow.HasValue && storey.ToleranceBelow.Value != 0)
                {
                    gsaPlane.StoreyToleranceBelow = storey.ToleranceBelow;
                }
                gsaPlane.StoreyToleranceBelowAuto = (!storey.ToleranceBelow.HasValue || storey.ToleranceBelow.Value == 0);
                if (!gsaPlane.StoreyToleranceAboveAuto)
                {
                    gsaPlane.StoreyToleranceAbove = storey.ToleranceAbove;
                }

                if (storey.ValidNonZero())
                {
                    gsaPlane.AxisRefType = GridPlaneAxisRefType.Reference;
                    //Create new axis on the fly here
                    var gsaAxis = StructuralAxisToNative.ToNativeSchema(storey.Axis);
                    StructuralAxisToNative.ToNative(gsaAxis);

                    gsaPlane.AxisIndex = gsaAxis.Index;
                }
                else
                {
                    gsaPlane.AxisRefType = GridPlaneAxisRefType.Global;
                }

                if (gsaPlane.Gwa(out var gsaPlaneGwaLines, true))
                {
                    Initialiser.AppResources.Cache.Upsert(keyword, index, gsaPlaneGwaLines.First(), streamId, storey.ApplicationId, GsaRecord.GetGwaSetCommandType <GsaLoadCase>());
                }

                return "";
            }));
        public static string ToNative(this Structural1DLoad load)
        {
            if (string.IsNullOrEmpty(load.ApplicationId) && !Helper.IsValidLoading(load.Loading))
            {
                return("");
            }

            return(Helper.ToNativeTryCatch(load, () =>
            {
                //Note: only LOAD_BEAM_UDL is supported at this stage
                var keyword = GsaRecord.GetKeyword <GsaLoadBeam>();
                var gwaSetCommandType = GsaRecord.GetGwaSetCommandType <GsaLoadBeam>();
                var streamId = Initialiser.AppResources.Cache.LookupStream(load.ApplicationId);

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

                var entityKeyword = (Initialiser.AppResources.Settings.TargetLayer == GSATargetLayer.Design) ? GsaRecord.GetKeyword <GsaMemb>() : GsaRecord.GetKeyword <GsaEl>();
                var entityIndices = (load.ElementRefs == null) ? null : Initialiser.AppResources.Cache.LookupIndices(entityKeyword, load.ElementRefs).Where(i => i.HasValue).Select(i => i.Value).ToList();

                var loadingDict = Helper.ExplodeLoading(load.Loading);
                foreach (var k in loadingDict.Keys)
                {
                    var applicationId = string.Join("_", load.ApplicationId, k.ToString());
                    var index = Initialiser.AppResources.Cache.ResolveIndex(keyword, applicationId);
                    var gsaLoad = new GsaLoadBeamUdl()
                    {
                        Index = index,
                        ApplicationId = applicationId,
                        StreamId = streamId,
                        Name = load.Name,
                        LoadDirection = k,
                        Load = loadingDict[k],
                        Projected = false,
                        AxisRefType = LoadBeamAxisRefType.Global,
                        LoadCaseIndex = loadCaseIndex,
                        Entities = entityIndices
                    };

                    if (gsaLoad.Gwa(out var gwa, false))
                    {
                        foreach (var gwaLine in gwa)
                        {
                            Initialiser.AppResources.Cache.Upsert(keyword, index, gwaLine, streamId, applicationId, gwaSetCommandType);
                        }
                    }
                }
Ejemplo n.º 6
0
        public static string ToNative(this StructuralSpringProperty prop)
        {
            if (string.IsNullOrEmpty(prop.ApplicationId) || prop.SpringType == StructuralSpringPropertyType.NotSet)
            {
                return("");
            }

            return(Helper.ToNativeTryCatch(prop, () =>
            {
                var keyword = GsaRecord.GetKeyword <GsaPropSpr>();
                var streamId = Initialiser.AppResources.Cache.LookupStream(prop.ApplicationId);
                var index = Initialiser.AppResources.Cache.ResolveIndex(keyword, prop.ApplicationId);

                var existingGwa = Initialiser.AppResources.Cache.GetGwa(keyword, index);
                var gsaPropSpr = new GsaPropSpr()
                {
                    Index = index,
                    ApplicationId = prop.ApplicationId,
                    StreamId = streamId,
                    Name = prop.Name,
                    PropertyType = prop.SpringType,
                    DampingRatio = prop.DampingRatio
                };

                if (prop.Stiffness != null && prop.Stiffness.Value != null && prop.Stiffness.Value.Count() > 0)
                {
                    gsaPropSpr.Stiffnesses = new Dictionary <AxisDirection6, double>();
                    for (int i = 0; i < prop.Stiffness.Value.Count(); i++)
                    {
                        if (prop.Stiffness.Value[i] > 0)
                        {
                            gsaPropSpr.Stiffnesses.Add(Helper.AxisDirs[i], prop.Stiffness.Value[i]);
                        }
                    }
                }

                //Yes, the Axis member of the Speckle StructuralSpringProperty object is not used

                if (gsaPropSpr.Gwa(out var gwaLines, false))
                {
                    Initialiser.AppResources.Cache.Upsert(keyword, gsaPropSpr.Index.Value, gwaLines.First(), streamId, gsaPropSpr.ApplicationId, GsaRecord.GetGwaSetCommandType <GsaNode>());
                }

                return "";
            }
Ejemplo n.º 7
0
        public static string ToNative(this Structural0DLoad load)
        {
            if (string.IsNullOrEmpty(load.ApplicationId) && !Helper.IsValidLoading(load.Loading))
            {
                return("");
            }

            return(Helper.ToNativeTryCatch(load, () =>
            {
                var keyword = GsaRecord.GetKeyword <GsaLoadNode>();
                var nodeKeyword = GsaRecord.GetKeyword <GsaNode>();
                var loadCaseKeyword = GsaRecord.GetKeyword <GsaLoadCase>();

                var nodeIndices = (load.NodeRefs == null) ? null : Initialiser.AppResources.Cache.LookupIndices(nodeKeyword, load.NodeRefs).Where(x => x.HasValue).Select(x => x.Value).OrderBy(i => i).ToList();
                var loadCaseIndex = Initialiser.AppResources.Cache.ResolveIndex(loadCaseKeyword, load.LoadCaseRef);
                var streamId = Initialiser.AppResources.Cache.LookupStream(load.ApplicationId);
                var gwaSetCommandType = GsaRecord.GetGwaSetCommandType <GsaLoadNode>();

                var gwaList = new List <string>();
                var loadingDict = Helper.ExplodeLoading(load.Loading);
                foreach (var k in loadingDict.Keys)
                {
                    var applicationId = string.Join("_", load.ApplicationId, k.ToString());
                    var index = Initialiser.AppResources.Cache.ResolveIndex(keyword, applicationId);
                    var gsaLoad = new GsaLoadNode()
                    {
                        Index = index,
                        ApplicationId = applicationId,
                        StreamId = streamId,
                        Name = load.Name,
                        LoadDirection = k,
                        Value = loadingDict[k],
                        GlobalAxis = true,
                        NodeIndices = nodeIndices,
                        LoadCaseIndex = loadCaseIndex
                    };
                    if (gsaLoad.Gwa(out var gwa, false))
                    {
                        Initialiser.AppResources.Cache.Upsert(keyword, index, gwa.First(), streamId, applicationId, gwaSetCommandType);
                    }
                }
Ejemplo n.º 8
0
        public static string ToNative(this StructuralNode node)
        {
            if (string.IsNullOrEmpty(node.ApplicationId) || node.Value == null || node.Value.Count < 3)
            {
                return("");
            }

            return(Helper.ToNativeTryCatch(node, () =>
            {
                var keyword = GsaRecord.GetKeyword <GsaNode>();
                var massKeyword = GsaRecord.GetKeyword <GsaPropMass>();

                var index = Initialiser.AppResources.Proxy.NodeAt(node.Value[0], node.Value[1], node.Value[2], Initialiser.AppResources.Settings.CoincidentNodeAllowance);
                var streamId = Initialiser.AppResources.Cache.LookupStream(node.ApplicationId);

                var existingGwa = Initialiser.AppResources.Cache.GetGwa(keyword, index);
                GsaNode gsaNode;
                if (existingGwa == null || existingGwa.Count() == 0 || string.IsNullOrEmpty(existingGwa.First()))
                {
                    gsaNode = new GsaNode()
                    {
                        Index = index,
                        ApplicationId = node.ApplicationId,
                        Name = node.Name,
                        StreamId = streamId,
                        X = node.Value[0],
                        Y = node.Value[1],
                        Z = node.Value[2],
                    };
                }
                else
                {
                    gsaNode = new GsaNode();
                    if (!gsaNode.FromGwa(existingGwa.First()))
                    {
                        //TO DO: add error mesage
                        return "";
                    }
                }

                if (node.Mass.HasValue && node.Mass.Value > 0)
                {
                    int?massIndex = null;
                    GsaPropMass gsaPropMass = null;

                    //Assume the PROP_MASS has the same Application ID as this node
                    //Check if the existing mass with the App ID still has the mass required by this StructuralNode
                    massIndex = Initialiser.AppResources.Cache.LookupIndex(massKeyword, node.ApplicationId);
                    if (massIndex.HasValue)
                    {
                        var massGwa = Initialiser.AppResources.Cache.GetGwa(massKeyword, massIndex.Value);
                        if (massGwa != null && massGwa.Count() > 0 && !string.IsNullOrEmpty(massGwa.First()))
                        {
                            gsaPropMass = new GsaPropMass();
                            gsaPropMass.FromGwa(massGwa.First());

                            if (Math.Abs(gsaPropMass.Mass - node.Mass.Value) > massEpsilon)
                            {
                                gsaPropMass.Mass = node.Mass.Value;
                            }
                        }
                    }

                    if (gsaPropMass == null)
                    {
                        gsaPropMass = new GsaPropMass()
                        {
                            ApplicationId = gsaNode.ApplicationId,
                            StreamId = streamId,
                            Index = Initialiser.AppResources.Cache.ResolveIndex(massKeyword, gsaNode.ApplicationId),
                            Mass = node.Mass.Value
                        };
                        if (!string.IsNullOrEmpty(node.Name))
                        {
                            gsaPropMass.Name = "Mass for " + node.Name;
                        }
                    }
                    if (gsaPropMass.Gwa(out var massGwaLines, false))
                    {
                        Initialiser.AppResources.Cache.Upsert(massKeyword, gsaPropMass.Index.Value, massGwaLines.First(), streamId, gsaPropMass.ApplicationId, GsaRecord.GetGwaSetCommandType <GsaPropMass>());
                    }
                }
Ejemplo n.º 9
0
        public static string ToNative(this StructuralLoadPlane loadPlane)
        {
            if (string.IsNullOrEmpty(loadPlane.ApplicationId))
            {
                return("");
            }

            return(Helper.ToNativeTryCatch(loadPlane, () =>
            {
                var keyword = GsaRecord.GetKeyword <GsaGridSurface>();
                var storeyKeyword = GsaRecord.GetKeyword <GsaGridPlane>();
                var streamId = Initialiser.AppResources.Cache.LookupStream(loadPlane.ApplicationId);

                var index = Initialiser.AppResources.Cache.ResolveIndex(keyword, loadPlane.ApplicationId);
                var gsaGridSurface = new GsaGridSurface()
                {
                    ApplicationId = loadPlane.ApplicationId,
                    StreamId = streamId,
                    Index = index,
                    Name = loadPlane.Name,
                    Tolerance = loadPlane.Tolerance,
                    Angle = loadPlane.SpanAngle,

                    Type = (loadPlane.ElementDimension.HasValue && loadPlane.ElementDimension.Value == 1)
            ? GridSurfaceElementsType.OneD
            : (loadPlane.ElementDimension.HasValue && loadPlane.ElementDimension.Value == 2)
              ? GridSurfaceElementsType.TwoD
              : GridSurfaceElementsType.NotSet,

                    Span = (loadPlane.Span.HasValue && loadPlane.Span.Value == 1)
            ? GridSurfaceSpan.One
            : (loadPlane.Span.HasValue && loadPlane.Span.Value == 2)
              ? GridSurfaceSpan.Two
              : GridSurfaceSpan.NotSet,

                    //There is no support for entity references in the structural schema, so leave entities blank, which is equal to "all"

                    //There is no support for this argument in the Structural schema, and was even omitted from the GWA
                    //in the previous version of the ToNative code
                    Expansion = GridExpansion.PlaneCorner
                };

                if (!string.IsNullOrEmpty(loadPlane.StoreyRef))
                {
                    var gridPlaneIndex = Initialiser.AppResources.Cache.LookupIndex(storeyKeyword, loadPlane.StoreyRef);

                    if (gridPlaneIndex.ValidNonZero())
                    {
                        gsaGridSurface.PlaneRefType = GridPlaneAxisRefType.Reference;
                        gsaGridSurface.PlaneIndex = gridPlaneIndex;
                    }
                }
                else if (loadPlane.Axis.ValidNonZero())
                {
                    gsaGridSurface.PlaneRefType = GridPlaneAxisRefType.Reference;

                    //Create axis
                    //Create new axis on the fly here
                    var gsaAxis = StructuralAxisToNative.ToNativeSchema(loadPlane.Axis);
                    StructuralAxisToNative.ToNative(gsaAxis);

                    //Create plane - the key here is that it's not a storey, but a general, type of grid plane,
                    //which is why the ToNative() method for SpeckleStorey shouldn't be used as it only creates storey-type GSA grid plane
                    var gsaPlaneKeyword = GsaRecord.GetKeyword <GsaGridPlane>();
                    var planeIndex = Initialiser.AppResources.Cache.ResolveIndex(gsaPlaneKeyword);

                    var gsaPlane = new GsaGridPlane()
                    {
                        Index = planeIndex,
                        Name = loadPlane.Name,
                        Type = GridPlaneType.General,
                        AxisRefType = GridPlaneAxisRefType.Reference,
                        AxisIndex = gsaAxis.Index
                    };
                    if (gsaPlane.Gwa(out var gsaPlaneGwas, true))
                    {
                        Initialiser.AppResources.Cache.Upsert(gsaPlaneKeyword, planeIndex, gsaPlaneGwas.First(), streamId, "", GsaRecord.GetGwaSetCommandType <GsaGridPlane>());
                    }
                    gsaGridSurface.PlaneIndex = planeIndex;
                }
        public static string ToNative(this StructuralAssembly assembly)
        {
            if (string.IsNullOrEmpty(assembly.ApplicationId) || assembly.Value == null || assembly.Value.Count < 6)
            {
                return("");
            }

            return(Helper.ToNativeTryCatch(assembly, () =>
            {
                //Need to convert rounding expressed as an epsilon (e.g. 0.001) to a number of decimal places for use in Math.Round calls
                var epsilon = SpeckleStructuralClasses.Helper.PointComparisonEpsilon.ToString();
                var numDecPlaces = epsilon.IndexOf('1') - epsilon.IndexOf('.');

                var keyword = GsaRecord.GetKeyword <GsaAssembly>();
                var index = Initialiser.AppResources.Cache.ResolveIndex(keyword, assembly.ApplicationId);
                var streamId = Initialiser.AppResources.Cache.LookupStream(assembly.ApplicationId);

                var topo1Pt = CoordsToPoint(assembly.Value.Take(3));
                var topo2Pt = CoordsToPoint(assembly.Value.Skip(3).Take(3));
                var orientPt = (assembly.OrientationPoint.Value == null) ? new Point3D(0, 0, 0) : CoordsToPoint(assembly.OrientationPoint.Value);

                var topo1Index = Initialiser.AppResources.Proxy.NodeAt(topo1Pt.X, topo1Pt.Y, topo1Pt.Z, Initialiser.AppResources.Settings.CoincidentNodeAllowance);
                var topo2Index = Initialiser.AppResources.Proxy.NodeAt(topo2Pt.X, topo2Pt.Y, topo2Pt.Z, Initialiser.AppResources.Settings.CoincidentNodeAllowance);
                var orientPtIndex = Initialiser.AppResources.Proxy.NodeAt(orientPt.X, orientPt.Y, orientPt.Z, Initialiser.AppResources.Settings.CoincidentNodeAllowance);

                var entityKeyword = (Initialiser.AppResources.Settings.TargetLayer == GSATargetLayer.Design) ? GsaRecord.GetKeyword <GsaMemb>() : GsaRecord.GetKeyword <GsaEl>();
                var entityIndices = Initialiser.AppResources.Cache.LookupIndices(entityKeyword, assembly.ElementRefs).Where(i => i.HasValue).Select(i => i.Value).ToList();

                var gsaAssembly = new GsaAssembly()
                {
                    Index = index,
                    ApplicationId = assembly.ApplicationId,
                    StreamId = streamId,
                    Name = assembly.Name,
                    Topo1 = topo1Index,
                    Topo2 = topo2Index,
                    OrientNode = orientPtIndex,
                    CurveType = CurveType.Lagrange,
                    SizeY = assembly.Width ?? 0,
                    SizeZ = 0,
                    Type = (Initialiser.AppResources.Settings.TargetLayer == GSATargetLayer.Design) ? GSAEntity.MEMBER : GSAEntity.ELEMENT,
                    Entities = entityIndices
                };

                if (assembly.NumPoints.HasValue && assembly.NumPoints.Value > 0)
                {
                    gsaAssembly.PointDefn = PointDefinition.Points;
                    gsaAssembly.NumberOfPoints = assembly.NumPoints.Value;
                }
                else if (assembly.PointDistances != null && assembly.PointDistances.Count() > 0)
                {
                    gsaAssembly.PointDefn = PointDefinition.Explicit;
                    var distances = assembly.PointDistances.Select(pd => Math.Round(pd, numDecPlaces)).Distinct().OrderBy(n => n).ToList();
                    gsaAssembly.ExplicitPositions.AddRange(distances);
                }
                else if (assembly.StoreyRefs != null && assembly.StoreyRefs.Count() > 0)
                {
                    gsaAssembly.PointDefn = PointDefinition.Storey;
                    gsaAssembly.StoreyIndices = Initialiser.AppResources.Cache.LookupIndices(GsaRecord.GetKeyword <GsaGridPlane>(), assembly.StoreyRefs).Where(i => i.HasValue).Select(i => i.Value).ToList();
                    //Not verifying at the moment that the grid planes are indeed storeys
                }
                else
                {
                    gsaAssembly.PointDefn = PointDefinition.Points;
                    gsaAssembly.NumberOfPoints = 10;
                }

                if (gsaAssembly.Gwa(out var gwaLines, false))
                {
                    //axes currently never have a stream nor an application ID
                    Initialiser.AppResources.Cache.Upsert(keyword, gsaAssembly.Index.Value, gwaLines.First(), streamId, assembly.ApplicationId, GsaRecord.GetGwaSetCommandType <GsaAssembly>());
                }

                return "";
            }));
        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>());
                        }
                    }