/// <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; })); }
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))); }
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); }
public void SetTestData() { p1 = new StructuralAxis() { Origin = new SpecklePoint(5, 6, 7) }; p2 = new StructuralAxis() { Origin = new SpecklePoint(8, 9, 10) }; }
/// <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()); }
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; }
/// <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); }
/// <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); }
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); }
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); }
/// <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); } }
/// <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); }
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)); }
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)); }
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); }
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>()); } }