//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;
            }));
        }
        //These methods are structured slightly differently as currently an axis is a special case - it's not directly part of the structural schema
        //and only called as part of ToNative calls for other higher-level types which create axes as necessary

        public static string ToNative(this GsaAxis gsaAxis)
        {
            var keyword = GsaRecord.GetKeyword <GsaAxis>();

            if (gsaAxis.Gwa(out var gwaLines, false))
            {
                //axes currently never have an application ID
                Initialiser.AppResources.Cache.Upsert(keyword, gsaAxis.Index.Value, gwaLines.First(), gsaAxis.StreamId, "", GsaRecord.GetGwaSetCommandType <GsaAxis>());
            }
            return("");
        }
        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);
        }
        private static bool Add1dLoadsWithoutAppId(string keyword, string axisKeyword, string entityKeyword, string loadCaseKeyword, IEnumerable <GsaLoadBeamUdl> gsaLoads, ref List <Structural1DLoad> structural1DLoads)
        {
            var gsaGroups = gsaLoads.GroupBy(gl => gl.LoadCaseIndex).Select(g => g.OfType <GsaLoadBeamUdl>().ToList()).ToList();

            foreach (var gsaGroup in gsaGroups)
            {
                //This is the group which might have axes, so if this is true, then they need to be transformed
                var transformedGsaLoads  = new List <StructuralVectorSix>();
                var uniqueLoadings       = new List <StructuralVectorSix>();
                var uniqueToLoadingsList = new Dictionary <int, List <int> >();

                var glByIndex = gsaGroup.Where(gl => gl.Index.HasValue).ToDictionary(gl => gl.Index.Value, gl => gl);

                foreach (var gl in gsaGroup)
                {
                    if (!gl.Index.HasValue || gl.Index == 0)
                    {
                        continue;
                    }

                    var loading = Helper.GsaLoadToLoading(gl.LoadDirection, gl.Load.Value);
                    if (gl.AxisRefType == LoadBeamAxisRefType.Reference && gl.AxisIndex.HasValue && gl.AxisIndex.Value > 0)
                    {
                        var axisGwa = Initialiser.AppResources.Cache.GetGwa(axisKeyword, gl.AxisIndex.Value);
                        if (axisGwa != null && axisGwa.Count() > 0 && string.IsNullOrEmpty(axisGwa.First()))
                        {
                            return(false);
                        }
                        var gsaAxis = new GsaAxis();
                        gsaAxis.FromGwa(axisGwa.First());
                        var loadAxis = (StructuralAxis)gsaAxis.ToSpeckle();
                        //Converts from loads on an axis to their global equivalent
                        loading.TransformOntoAxis(loadAxis);
                    }

                    int uniqueLoadingIndex;
                    if (loading != null)
                    {
                        var matching = uniqueLoadings.Where(k => k.Value.SequenceEqual(loading.Value));
                        if (matching.Count() > 0)
                        {
                            uniqueLoadingIndex = uniqueLoadings.IndexOf(matching.First());
                        }
                        else
                        {
                            uniqueLoadingIndex = uniqueLoadings.Count();
                            uniqueLoadings.Add(loading);
                        }
                        if (!uniqueToLoadingsList.ContainsKey(uniqueLoadingIndex))
                        {
                            uniqueToLoadingsList.Add(uniqueLoadingIndex, new List <int>());
                        }
                        uniqueToLoadingsList[uniqueLoadingIndex].Add(gl.Index.Value);
                    }
                }

                foreach (var ul in uniqueToLoadingsList.Keys)
                {
                    var entityIndices = uniqueToLoadingsList[ul].SelectMany(ei => glByIndex[ei].Entities).Distinct().OrderBy(n => n).ToList();
                    var elementRefs   = entityIndices.Select(ei => Initialiser.AppResources.Cache.GetApplicationId(entityKeyword, ei)).Where(aid => !string.IsNullOrEmpty(aid)).ToList();
                    var loadCaseRef   = (gsaGroup.First().LoadCaseIndex.HasValue) ? Initialiser.AppResources.Cache.GetApplicationId(loadCaseKeyword, gsaGroup.First().LoadCaseIndex.Value) : null;
                    var load          = new Structural1DLoad()
                    {
                        ApplicationId = SpeckleStructuralGSA.Helper.FormatApplicationId(keyword, uniqueToLoadingsList[ul]),
                        Name          = gsaGroup.First().Name,
                        ElementRefs   = elementRefs,
                        LoadCaseRef   = loadCaseRef,
                        Loading       = uniqueLoadings[ul]
                    };
                    structural1DLoads.Add(load);
                }
            }

            return(true);
        }
Пример #5
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("");
        }