/***************************************************/ // Convert Guanaco mesh to Rhino mesh. public static Rhino.Geometry.Mesh GetRhinoMesh(Mesh mesh, out List <LineCurve> barElements) { barElements = new List <LineCurve>(); Rhino.Geometry.Mesh rhinoMesh = new Rhino.Geometry.Mesh(); foreach (Node node in mesh.Nodes) { rhinoMesh.Vertices.Add(node.Location); } foreach (Element element in mesh.Elements) { if (element is Element2D) { Element2D e = element as Element2D; int[] nodeIds = e.Nodes.Take(e.PrimaryNodeCount).Select(n => n.Id.AsInteger).ToArray(); if (nodeIds.Length == 4) { rhinoMesh.Faces.AddFace(nodeIds[0], nodeIds[1], nodeIds[2], nodeIds[3]); } else if (nodeIds.Length == 3) { rhinoMesh.Faces.AddFace(nodeIds[0], nodeIds[1], nodeIds[2]); } } else if (element is Element1D) { Element1D e = element as Element1D; barElements.Add(new LineCurve(rhinoMesh.Vertices[e.Nodes.First().Id.AsInteger], rhinoMesh.Vertices[e.Nodes.Last().Id.AsInteger])); } } return(rhinoMesh); }
// Clone to a target mesh. public override GuanacoObject Clone(Mesh targetMesh, bool newID = false) { Element1D e = this.Clone(newID) as Element1D; if (targetMesh != null) { targetMesh.AddElement(e, this._id.AsInteger); e._nodes = this._nodes.Select(n => targetMesh.Nodes[n.Id.AsInteger]).ToList(); } return(e); }
/***************************************************/ //Clone. public override GuanacoObject Clone(bool newID = false) { Element1D e = this.ShallowClone(newID) as Element1D; e._nodes = this._nodes.Select(n => n.Clone(newID) as Node).ToList(); e._results = new Dictionary <string, double[]>(this._results); foreach (string r in this._results.Keys) { e._results[r] = this._results[r].ToArray(); } e._parentCollection = null; e._id = null; return(e); }
/***************************************************/ // Read results for 1D elements from the output file. public static void Read1DElementForces(Model model, int step = 0, double totalTime = 1.0) { if (model.Bars.Count == 0) { return; } int el1DCount = model.Bars.Select(b => b.Elements.Count()).Sum(); string[] resLines = File.ReadAllLines(model.GetModelFilePath(GuanacoUtil.FileType.dat)); bool stepFound = false; int lineNo = -1; double time = 0; int stepCount = 1; for (int i = 0; i < resLines.Length; i++) { string line = resLines[i]; if (line.TrimStart(' ').StartsWith("statistics")) { string[] splt = line.Split(GuanacoUtil.Space, StringSplitOptions.RemoveEmptyEntries); time = double.Parse(splt[splt.Length - 1], GuanacoUtil.FloatNum); lineNo = i + 4; if (stepCount == step) { stepFound = true; break; } stepCount++; i += el1DCount * 2 * 20 - 1; } } if (!stepFound && time != totalTime) { throw new Exception("Oooops, the iteration did not converge!"); } foreach (Bar bar in model.Bars) { Plane LCS = new Plane(bar.LCS); LCS.Rotate(bar.Rotation, LCS.ZAxis); Transform t = Transform.PlaneToPlane(Plane.WorldXY, LCS); foreach (Element element in bar.Elements) { Element1D e = element as Element1D; foreach (string s in Enum.GetNames(typeof(SectionForces1D)).Skip(1)) { if (!e.Results.ContainsKey(s)) { e.AddResult(s, new double[2]); } } double multiplier = 1; for (int j = 0; j < 2; j++) { double[] force = resLines[lineNo].Split(GuanacoUtil.Space, StringSplitOptions.RemoveEmptyEntries).Select(x => double.Parse(x, GuanacoUtil.FloatNum)).Take(3).ToArray(); Vector3d forceV = new Vector3d(force[0], force[1], force[2]) * multiplier; forceV.Transform(t); e.Results["Fx"][j] = forceV.X; e.Results["Fy"][j] = forceV.Y; e.Results["Fz"][j] = forceV.Z; lineNo += 8; double[] moment = resLines[lineNo].Split(GuanacoUtil.Space, StringSplitOptions.RemoveEmptyEntries).Select(x => double.Parse(x, GuanacoUtil.FloatNum)).ToArray(); Vector3d momentV = new Vector3d(moment[0], moment[1], moment[2]) * multiplier; momentV.Transform(t); e.Results["Mxx"][j] = momentV[0]; e.Results["Myy"][j] = momentV[1]; e.Results["Mzz"][j] = momentV[2]; lineNo += 12; multiplier *= -1; } } } }
/***************************************************/ // Calculate the display factors dependent on the size of the model and its elements. public static double[] sizeFactors(this Model model) { BoundingBox bBox = new BoundingBox(model.Mesh.Nodes.Select(x => x.Location)); double forceFactor = 0; double elementFactor = bBox.Diagonal.Length; foreach (Panel panel in model.Panels) { foreach (Element element in panel.Elements) { Element2D e = element as Element2D; List <Point3d> eVertices = e.GetVertices().ToList(); if (e.PrimaryNodeCount == 3) { for (int i = 0; i < 3; i++) { double edgeL = eVertices[i].DistanceTo(eVertices[(i + 1) % 3]); if (edgeL <= elementFactor) { elementFactor = edgeL; } } } else { for (int i = 0; i < 2; i++) { double diagL = eVertices[i].DistanceTo(eVertices[i + 2]); if (diagL <= elementFactor) { elementFactor = diagL; } } } if (e.Pressure != 0 && Math.Abs(e.Pressure) >= forceFactor) { forceFactor = Math.Abs(e.Pressure); } } } foreach (Bar bar in model.Bars) { foreach (Element element in bar.Elements) { Element1D e = element as Element1D; Point3d[] eVertices = e.GetVertices().ToArray(); double l = eVertices[0].DistanceTo(eVertices[1]); if (l <= elementFactor) { elementFactor = l; } } } foreach (Node n in model.Mesh.Nodes) { if (n.ForceLoad.Length != 0 && Math.Abs(n.ForceLoad.Length) >= forceFactor) { forceFactor = Math.Abs(n.ForceLoad.Length); } } elementFactor *= 0.3; return(new double[] { elementFactor, forceFactor }); }
/***************************************************/ // Create the preview of bars. public static void AddBarPreview(this Rhino.Display.CustomDisplay display, Model model, IEnumerable <int> ids, out HashSet <int> nodeIds, double graphicFactor, double elementFactor, double textFactor, bool showComponentNumbers, bool showElementNumbers, bool showLCS, bool showThk = false, string barResultType = "None", bool showResultValues = false) { nodeIds = new HashSet <int>(); if (model.Bars.Count == 0) { return; } // Take all results out first to determine min & max, otherwise could be done inside the loop. Dictionary <int, double[]> barResults = new Dictionary <int, double[]>(); double BFactor = 0; if (barResultType != "None") { barResults = model.Mesh.GetElementResults(barResultType); double barExtreme = barResults.Values.Select(r => Math.Max(Math.Abs(r[0]), Math.Abs(r[1]))).Max(); BFactor = elementFactor / barExtreme * 10; } ids = ids.Count() == 0 ? Enumerable.Range(0, model.Bars.Count) : ids.Select(i => i - 1); foreach (int i in ids) { Bar bar = model.Bars[i]; Plane locLCS = new Plane(bar.LCS); locLCS.Rotate(bar.Rotation, locLCS.ZAxis); locLCS.Translate(locLCS.XAxis * bar.Offset.X); locLCS.Translate(locLCS.YAxis * bar.Offset.Y); Vector3d hOffset = locLCS.XAxis * (bar.Profile.GetHeight() * 0.5); if (showThk) { hOffset *= 2; } Plane tp = new Plane(locLCS.Origin, bar.LCS.YAxis, Vector3d.ZAxis); tp.Translate(hOffset); Curve[] profileCurves = bar.Profile.ToRhinoProfile(); if (showComponentNumbers) { Rhino.Display.Text3d t = new Rhino.Display.Text3d("Bar " + bar.CCXId(), tp, elementFactor * 0.6 * textFactor); t.Bold = true; display.AddText(t, Color.DarkRed); } foreach (Element element in bar.Elements) { Element1D e = element as Element1D; int eId = e.Id.AsInteger; nodeIds.Add(e.Nodes.First().Id.AsInteger); nodeIds.Add(e.Nodes.Last().Id.AsInteger); Point3d[] endPts = e.GetVertices().ToArray(); Point3d c = (endPts[0] + endPts[1]) * 0.5; display.AddLine(new Line(endPts[0], endPts[1]), Color.Aqua); if (showThk) { Plane eP = new Plane(locLCS); List <Point3d> elementVertices = e.GetVertices().ToList(); eP.Translate(elementVertices[0] - bar.LCS.Origin); Transform ptp = Transform.PlaneToPlane(Plane.WorldXY, eP); // Use DisplayPipeline to get surface preview! Now a temporary solution given. foreach (Curve pc in profileCurves) { Curve opc = pc.DuplicateCurve(); opc.Transform(ptp); display.AddCurve(opc); opc.Translate(elementVertices[1] - elementVertices[0]); display.AddCurve(opc); } } if (barResultType != "None") { Vector3d graphDir; switch (barResultType) { case "Myy": graphDir = locLCS.XAxis; break; case "Mxx": graphDir = locLCS.YAxis; break; default: string barResDir = barResultType.ToString().Substring(1, 1); graphDir = barResDir == "y" ? locLCS.YAxis : locLCS.XAxis; break; } graphDir *= BFactor * graphicFactor; Point3d[] cPts = new Point3d[] { endPts[0], endPts[1], endPts[1] + graphDir * barResults[eId][1], endPts[0] + graphDir * barResults[eId][0] }; display.AddPolygon(cPts, Color.CornflowerBlue, Color.Black, true, true); if (showResultValues && barResults.Count != 0) { Plane tp1 = new Plane(tp); tp1.Translate(endPts[0] - tp1.Origin + graphDir * barResults[eId][0]); Rhino.Display.Text3d t1 = new Rhino.Display.Text3d(barResults[eId][0].ToString("G2"), tp1, elementFactor * 0.4 * textFactor); t1.Bold = true; display.AddText(t1, Color.Black); Plane tp2 = new Plane(tp); tp2.Translate(endPts[1] - tp2.Origin + graphDir * barResults[eId][1]); Rhino.Display.Text3d t2 = new Rhino.Display.Text3d(barResults[eId][1].ToString("G2"), tp2, elementFactor * 0.4 * textFactor); t2.Bold = true; display.AddText(t2, Color.Black); } } if (showLCS) { display.AddVector(c, locLCS.XAxis * elementFactor * graphicFactor, Color.Red); display.AddVector(c, locLCS.YAxis * elementFactor * graphicFactor, Color.Green); display.AddVector(c, locLCS.ZAxis * elementFactor * graphicFactor, Color.Blue); } if (showElementNumbers) { Plane etp = new Plane(tp); etp.Translate(c - bar.LCS.Origin); Rhino.Display.Text3d t = new Rhino.Display.Text3d(e.CCXId(), etp, elementFactor * 0.4 * textFactor); t.Bold = true; display.AddText(t, Color.Black); } } } }
/***************************************************/ // Read mesh file and convert it to Guanaco mesh format. public static void ReadMesh(Model model, bool reducedIntegration) { // Create empty mesh, initiate local variables. int barCounter = 0; int panelCounter = 0; bool nodeLines, elementLines, componentLines; nodeLines = elementLines = componentLines = false; string[] itemSep = new string[] { "," }; // Read the mesh file. string line; int elementOrder = -1; int elementDimension = -1; List <int> elementList = new List <int>(); Dictionary <int, int> elementPairs = new Dictionary <int, int>(); System.IO.StreamReader file = new System.IO.StreamReader(model.GetModelFilePath() + "_Mesh.inp"); while ((line = file.ReadLine()) != null) { if (line.StartsWith("*NODE") && !line.StartsWith("*NODE ")) { nodeLines = true; continue; } else if (nodeLines && line.StartsWith("*")) { nodeLines = false; } // Create Guanaco node based on the given line of input file. else if (nodeLines) { string[] nodeInfo = line.Replace("\n", "").Split(itemSep, StringSplitOptions.None); double x = Double.Parse(nodeInfo[1], GuanacoUtil.FloatNum); double y = Double.Parse(nodeInfo[2], GuanacoUtil.FloatNum); double z = Double.Parse(nodeInfo[3], GuanacoUtil.FloatNum); model.Mesh.AddNode(new Node(x, y, z)); } if (line.StartsWith("*ELEMENT, type=")) { elementLines = true; string elementShape = line.Replace(" ", "").Substring(14).Split(',')[0]; switch (elementShape) { case "T3D2": elementOrder = 1; elementDimension = 1; break; case "T3D3": elementOrder = 2; elementDimension = 1; break; case "CPS3": case "CPS4": elementOrder = 1; elementDimension = 2; break; case "CPS6": case "CPS8": elementOrder = 2; elementDimension = 2; break; default: throw new Exception("Incorrect element type! Check if all elements in the .inp file are supported by Guanaco."); } } else if (elementLines && line.StartsWith("*")) { elementLines = false; } // Create Guanaco element based on the given line of input file. else if (elementLines) { string[] elInfo = line.Replace("\n", "").Split(itemSep, StringSplitOptions.None); List <Node> elementNodes = new List <Node>(); for (int i = 1; i < elInfo.Length; i++) { int id = int.Parse(elInfo[i]) - 1; elementNodes.Add(model.Mesh.Nodes[id]); } Element el; if (elementDimension == 1) { // Add element. el = new Element1D(elementNodes, elementOrder, reducedIntegration); model.Mesh.AddElement(el as Element1D); // Set primary nodes of an element. elementNodes[0].Primary = true; elementNodes.Last().Primary = true; } else if (elementDimension == 2) { // Add element. el = new Element2D(elementNodes, elementOrder, reducedIntegration); model.Mesh.AddElement(el as Element2D); // Set primary nodes of an element. for (int i = 0; i < (el as Element2D).PrimaryNodeCount; i++) { elementNodes[i].Primary = true; } } else { throw new Exception("Unsupported element found!"); } elementPairs.Add(int.Parse(elInfo[0]), el.Id.AsInteger); } if (componentLines && !Char.IsDigit(line[0])) { if (elementDimension == 1) { model.Bars[barCounter].AssignElements(elementList.Select(e => model.Mesh.Elements[e]).ToList()); barCounter++; } else if (elementDimension == 2) { model.Panels[panelCounter].AssignElements(elementList.Select(e => model.Mesh.Elements[e]).ToList()); panelCounter++; } elementList = new List <int>(); } if (line.StartsWith("*ELSET,")) { componentLines = true; if (line.Contains("PhysicalLine")) { elementDimension = 1; } else if (line.Contains("PhysicalSurface")) { elementDimension = 2; } else { throw new Exception("Gmsh physical entity type not known."); } } else if (componentLines && line.StartsWith("*")) { componentLines = false; } // Assign the mesh elements to relevant components. else if (componentLines) { string[] sa = line.Replace("\n", "").Split(itemSep, StringSplitOptions.RemoveEmptyEntries); foreach (string s in sa) { int id; if (Int32.TryParse(s, out id)) { elementList.Add(elementPairs[id]); } } } } if (elementList.Count > 0) { if (elementDimension == 1) { model.Bars[barCounter].AssignElements(elementList.Select(e => model.Mesh.Elements[e]).ToList()); } else if (elementDimension == 2) { model.Panels[panelCounter].AssignElements(elementList.Select(e => model.Mesh.Elements[e]).ToList()); } } file.Close(); }