/***************************************************/ // Apply pressure load to the elements laying within tolerance from the pressure area. private void ApplyLoad(PressureLoad load) { foreach (Element e in this._mesh.Elements) { // Check if the element is 2D. Element2D el = e as Element2D; if (el == null) { continue; } // Check if the element is adjoining to the pressure area (if all its vertices lie within tolerance) - if yes then apply the load. Point3d elC = el.GetCentroid(); foreach (Brep s in load.Surfaces) { bool broken = false; foreach (Point3d v in el.GetVertices()) { if (v.DistanceTo(s.ClosestPoint(v)) > this._tolerance) { broken = true; break; } } if (!broken) { el.AddPressure(load.LoadValue * 1); } } } }
/***************************************************/ // Apply infill load to the adjoining elements. private void ApplyLoad(InfillLoad load) { foreach (Element e in this._mesh.Elements) { // Check if the element is 2D. Element2D el = e as Element2D; if (el == null) { continue; } Point3d elC = el.GetCentroid(); Vector3d elN = el.GetNormal(); foreach (Infill i in load.Infills) { // Check if the element is adjoining to the infill (if all its vertices lie within tolerance). bool broken = false; foreach (Point3d v in el.GetVertices()) { if (v.DistanceTo(i.Volume.ClosestPoint(v)) > this._tolerance) { broken = true; break; } } // If the element is adjoining to the infill, apply the load based on location of the element and load function of the infill. if (!broken) { // Flip normal of the element if it points outside the infill. Point3d cpt = Point3d.Add(elC, elN * this._tolerance); if (!i.Volume.IsPointInside(cpt, Rhino.RhinoMath.SqrtEpsilon, true)) { el.FlipNormal(); } // Check if the element is not surrounded by the infill from both sides - if it is then do nothing (no hydrostatic pressure). else { cpt = Point3d.Add(elC, -elN * this._tolerance); if (i.Volume.IsPointInside(cpt, Rhino.RhinoMath.SqrtEpsilon, true)) { continue; } } // Apply the load based on location of the element and load function of the infill. string g = load.InfillDensity.ToString(GuanacoUtil.Invariant); string x = (i.MaxZ - elC.Z).ToString(GuanacoUtil.Invariant); string z = (i.MaxZ - i.MinZ).ToString(GuanacoUtil.Invariant); string f = load.LoadFunction.Replace("g", g).Replace("x", x).Replace("z", z); double p = GuanacoUtil.Evaluate(f); el.AddPressure(-p); } } } }
/***************************************************/ // Create the preview of panels. public static void AddPanelPreview(this Rhino.Display.CustomDisplay display, Model model, IEnumerable <int> ids, out HashSet <int> nodeIds, double graphicFactor, double elementFactor, double textFactor, double forceFactor, bool showComponentNumbers, bool showElementNumbers, bool showLCS, bool showLoads, bool showLoadValues, bool showEdges, bool showThk = false, Grasshopper.GUI.Gradient.GH_Gradient gradient = null, string panelResultType = "None", bool showResultValues = false) { nodeIds = new HashSet <int>(); if (model.Panels.Count == 0) { return; } // Take all results out first to determine min & max, otherwise could be done inside the loop. Dictionary <int, double> panelTopResults = new Dictionary <int, double>(); Dictionary <int, double> panelBottomResults = new Dictionary <int, double>(); double panelMax = 0; double panelMin = 0; if (panelResultType != "None") { Dictionary <int, double[]> panelResults = model.Mesh.GetElementResults(panelResultType); foreach (KeyValuePair <int, double[]> elResult in panelResults) { int id = elResult.Key; double[] results = elResult.Value; int halfResultCount = results.Length / 2; panelTopResults.Add(id, results.Skip(halfResultCount).Average()); panelBottomResults.Add(id, results.Take(halfResultCount).Average()); } panelMax = Math.Max(panelTopResults.Values.Max(), panelBottomResults.Values.Max()); panelMin = Math.Min(panelTopResults.Values.Min(), panelBottomResults.Values.Min()); } ids = ids.Count() == 0 ? Enumerable.Range(0, model.Panels.Count) : ids.Select(i => i - 1); foreach (int i in ids) { Panel panel = model.Panels[i]; if (showComponentNumbers) { Vector3d fOffset = panel.LCS.ZAxis * 0.002; if (showThk) { fOffset += panel.LCS.ZAxis * 0.5 * panel.Thickness; } Plane fp = new Plane(panel.LCS.Origin + fOffset, panel.LCS.ZAxis); Plane bp = new Plane(panel.LCS.Origin - fOffset, -panel.LCS.ZAxis); Rhino.Display.Text3d ft = new Rhino.Display.Text3d("Panel " + panel.CCXId(), fp, elementFactor * 0.6 * textFactor); Rhino.Display.Text3d bt = new Rhino.Display.Text3d("Panel " + panel.CCXId(), bp, elementFactor * 0.6 * textFactor); ft.Bold = true; bt.Bold = true; display.AddText(ft, Color.DarkRed); display.AddText(bt, Color.DarkRed); } foreach (Element element in panel.Elements) { Element2D e = element as Element2D; int eId = e.Id.AsInteger; foreach (Node n in e.Nodes.Take(e.PrimaryNodeCount)) { nodeIds.Add(n.Id.AsInteger); } Color bottomColor; Color topColor; if (panelResultType == "None") { bottomColor = topColor = Color.Aqua; } else { bottomColor = gradient.ColourAt((panelBottomResults[eId] - panelMin) / (panelMax - panelMin)); topColor = gradient.ColourAt((panelTopResults[eId] - panelMin) / (panelMax - panelMin)); } Point3d centroid = e.GetCentroid(); Vector3d normal = e.GetNormal(); Vector3d minOffset = normal * 0.001; Vector3d offset = showThk ? normal * 0.5 * panel.Thickness : minOffset; List <Point3d> front = new List <Point3d>(); List <Point3d> back = new List <Point3d>(); foreach (Point3d v in e.GetVertices()) { front.Add(v + offset); back.Add(v - offset); } display.AddPolygon(front, topColor, Color.Black, true, showEdges); display.AddPolygon(back, bottomColor, Color.Black, true, showEdges); if (showThk) { front.Add(front[0]); back.Add(back[0]); for (int j = 0; j < front.Count - 1; j++) { List <Point3d> fv = front.GetRange(j, 2); List <Point3d> bv = back.GetRange(j, 2); bv.Reverse(); fv.AddRange(bv); display.AddPolygon(fv, Color.Aqua, Color.Black, true, true); } } Plane tp = new Plane(panel.LCS); tp.Origin = centroid + offset + minOffset; tp.XAxis *= -1; tp.ZAxis *= -1; Plane bp = new Plane(panel.LCS); bp.Origin = centroid - offset - minOffset; if (showResultValues && panelTopResults.Count != 0) { Rhino.Display.Text3d t1 = new Rhino.Display.Text3d(panelTopResults[eId].ToString("G2"), tp, elementFactor * 0.4 * textFactor); t1.Bold = true; display.AddText(t1, Color.Black); Rhino.Display.Text3d t2 = new Rhino.Display.Text3d(panelBottomResults[eId].ToString("G2"), bp, elementFactor * 0.4 * textFactor); t2.Bold = true; display.AddText(t2, Color.Black); } if (showLCS) { display.AddVector(centroid, e.Orientation[0] * elementFactor * graphicFactor, Color.Red); display.AddVector(centroid, e.Orientation[1] * elementFactor * graphicFactor, Color.Green); display.AddVector(centroid, normal * elementFactor * graphicFactor, Color.Blue); } if (showLoads && e.Pressure != 0) { Vector3d pv = normal * e.Pressure / forceFactor * elementFactor * 5 * graphicFactor; List <Point3d> pressurePoints = new List <Point3d>(); foreach (Point3d pt in e.PopulateWithPoints()) { if (e.Pressure > 0) { display.AddVector(pt - pv - offset, pv); } else { display.AddVector(pt - pv + offset, pv); } } if (showLoadValues) { Plane p; if (e.Pressure > 0) { p = new Plane(e.GetCentroid() - pv * 1.1 - offset, Vector3d.XAxis, Vector3d.ZAxis); } else { p = new Plane(e.GetCentroid() - pv * 1.1 + offset, Vector3d.XAxis, Vector3d.ZAxis); } Rhino.Display.Text3d t = new Rhino.Display.Text3d(e.Pressure.ToString("G2"), p, elementFactor * 0.4 * textFactor); t.Bold = true; display.AddText(t, Color.Magenta); } } if (showElementNumbers) { Rhino.Display.Text3d tt = new Rhino.Display.Text3d(e.CCXId(), tp, elementFactor * 0.4 * textFactor); Rhino.Display.Text3d bt = new Rhino.Display.Text3d(e.CCXId(), bp, elementFactor * 0.4 * textFactor); tt.Bold = true; bt.Bold = true; display.AddText(tt, Color.Black); display.AddText(bt, Color.Black); } } } }