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