public Mesh GenerateStressMeshv2(double lim0, double lim1) { Mesh mesh = new Mesh(); Grasshopper.GUI.Gradient.GH_Gradient grad = StaticFunctions.GetStandardGradient(lim0, lim1); double max = vonMises.Max(); for (int i = 0; i < NumberOfElements; i++) { int A = mesh.Vertices.Add(uMesh.Vertices[uMesh.Faces[i].A]); int B = mesh.Vertices.Add(uMesh.Vertices[uMesh.Faces[i].B]); int C = mesh.Vertices.Add(uMesh.Vertices[uMesh.Faces[i].C]); double normVal = vonMises[i] / max; if (max == 0) { normVal = 0; } System.Drawing.Color color = grad.ColourAt(normVal); mesh.VertexColors.Add(color.R, color.G, color.B); mesh.VertexColors.Add(color.R, color.G, color.B); mesh.VertexColors.Add(color.R, color.G, color.B); mesh.Faces.AddFace(new MeshFace(A, B, C)); } return(mesh); }
public Mesh GenereateDeformedMesh(double t) { Mesh mesh = new Mesh(); List <Vector3D> dispVecs = new List <Vector3D>(); foreach (Node node in nodes) { Vector3D dispVec = new Vector3D(a[node.dofX], a[node.dofY], a[node.dofZ]); dispVec = dispVec * t; dispVecs.Add(dispVec); mesh.Vertices.Add(node.x + dispVec.X, node.y + dispVec.Y, node.z + dispVec.Z); } double max = dispVecs.Max(x => x.Length); Grasshopper.GUI.Gradient.GH_Gradient grad = StaticFunctions.GetStandardGradient(); foreach (Vector3D vec in dispVecs) { double normVal = vec.Length / max; System.Drawing.Color color = grad.ColourAt(normVal); mesh.VertexColors.Add(color.R, color.G, color.B); } foreach (ShellElement elem in this.elements) { MeshFace face = new MeshFace(elem.Nodes[0].Id, elem.Nodes[1].Id, elem.Nodes[2].Id); mesh.Faces.AddFace(face); } return(mesh); }
public static Color GetColourGradient(int charge, int max) { Grasshopper.GUI.Gradient.GH_Gradient gradient = new Grasshopper.GUI.Gradient.GH_Gradient(); gradient.AddGrip(max, Color.FromArgb(234, 28, 0)); //Red gradient.AddGrip(max * 0.75, Color.FromArgb(234, 126, 0)); //Orange gradient.AddGrip(max * 0.50, Color.FromArgb(254, 244, 84)); //Gelb gradient.AddGrip(max * 0.25, Color.FromArgb(173, 203, 179)); //babyblau gradient.AddGrip(0, Color.FromArgb(75, 107, 169)); //blau return(gradient.ColourAt(charge)); }
public void DrawViewportWires(GH_PreviewWireArgs args) { int numDiv = 40; Grasshopper.GUI.Gradient.GH_Gradient gH_Gradient = new Grasshopper.GUI.Gradient.GH_Gradient(); gH_Gradient.AddGrip(0, m_colour1); gH_Gradient.AddGrip(1, m_colour2); for (int i = 0; i < numDiv + 1; i++) { double t = (double)i / numDiv; Color col = gH_Gradient.ColourAt(t); int thk = (int)Math.Abs(((m_size2 - m_size1) * t + m_size1)); Line ln = new Line(Value.PointAt((double)i / (numDiv - 1)), Value.PointAt((double)(i + 1) / (numDiv - 1))); args.Pipeline.DrawLine(ln, col, thk); } }
public Mesh GenerateStressMeshv1(double lim0, double lim1) { Mesh mesh = new Mesh(); mesh.CopyFrom(uMesh); Grasshopper.GUI.Gradient.GH_Gradient grad = StaticFunctions.GetStandardGradient(lim0, lim1); double[] meanVals = new double[NumberOfElements]; for (int i = 0; i < nodes.Count; i++) { int index = mesh.TopologyVertices.TopologyVertexIndex(i); int[] connectedFaces = mesh.TopologyVertices.ConnectedFaces(index); double sum = 0; for (int j = 0; j < connectedFaces.Length; j++) { sum += vonMises[connectedFaces[j]]; } double mean = sum / connectedFaces.Length; meanVals[i] = mean; } double max = meanVals.Max(); for (int i = 0; i < nodes.Count; i++) { double normVal = meanVals[i] / max; if (max == 0) { normVal = 0; } System.Drawing.Color color = grad.ColourAt(normVal); mesh.VertexColors.Add(color.R, color.G, color.B); } return(mesh); }
protected override void SolveInstance(IGH_DataAccess DA) { // Model to work on GsaModel in_Model = new GsaModel(); // Get Model GH_ObjectWrapper gh_typ = new GH_ObjectWrapper(); if (DA.GetData(0, ref gh_typ)) { #region Inputs if (gh_typ.Value is GsaModelGoo) { gh_typ.CastTo(ref in_Model); if (gsaModel != null) { if (in_Model.GUID != gsaModel.GUID) { gsaModel = in_Model; getresults = true; } } else { gsaModel = in_Model; } } else { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Error converting input to GSA Model"); return; } // Get analysis case GH_Integer gh_aCase = new GH_Integer(); DA.GetData(1, ref gh_aCase); GH_Convert.ToInt32(gh_aCase, out int tempanalCase, GH_Conversion.Both); // Get element filter list GH_String gh_elList = new GH_String(); DA.GetData(2, ref gh_elList); GH_Convert.ToString(gh_elList, out string tempelemList, GH_Conversion.Both); // Get colours List <Grasshopper.Kernel.Types.GH_Colour> gh_Colours = new List <Grasshopper.Kernel.Types.GH_Colour>(); List <System.Drawing.Color> colors = new List <System.Drawing.Color>(); if (DA.GetDataList(3, gh_Colours)) { for (int i = 0; i < gh_Colours.Count; i++) { System.Drawing.Color color = new System.Drawing.Color(); GH_Convert.ToColor(gh_Colours[i], out color, GH_Conversion.Both); colors.Add(color); } } Grasshopper.GUI.Gradient.GH_Gradient gH_Gradient = UI.Colour.Stress_Gradient(colors); #endregion #region get results? // check if we must get results or just update display if (analCase == 0 || analCase != tempanalCase) { analCase = tempanalCase; getresults = true; } if (elemList == "" || elemList != tempelemList) { elemList = tempelemList; getresults = true; } #endregion #region Create results output if (getresults) { #region Get results from GSA // ### Get results ### //Get analysis case from model AnalysisCaseResult analysisCaseResult = null; gsaModel.Model.Results().TryGetValue(analCase, out analysisCaseResult); if (analysisCaseResult == null) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "No results exist for Analysis Case " + analCase + " in file"); return; } IReadOnlyDictionary <int, Element3DResult> globalResults = analysisCaseResult.Element3DResults(elemList); #endregion // ### Loop through results ### // clear existing result lists xyz_out = new DataTree <Vector3d>(); xxyyzz_out = new DataTree <Vector3d>(); // maximum and minimum result values for colouring later dmax_x = 0; dmax_y = 0; dmax_z = 0; dmax_xx = 0; dmax_yy = 0; dmax_zz = 0; dmax_xyz = 0; dmax_xxyyzz = 0; dmin_x = 0; dmin_y = 0; dmin_z = 0; dmin_xx = 0; dmin_yy = 0; dmin_zz = 0; dmin_xyz = 0; dmin_xxyyzz = 0; keys = new List <int>(); double unitfactorxyz = 1; double unitfactorxxyyzz = 1; foreach (int key in globalResults.Keys) { keys.Add(key); // lists for results Element3DResult elementResults; if (globalResults.TryGetValue(key, out elementResults)) { List <Vector3d> xyz = new List <Vector3d>(); List <Vector3d> xxyyzz = new List <Vector3d>(); switch (_mode) { case FoldMode.Displacement: unitfactorxyz = 0.001; List <Double3> trans_vals = elementResults.Displacement.ToList(); foreach (Double3 val in trans_vals) { Vector3d valxyz = new Vector3d { X = val.X / unitfactorxyz, Y = val.Y / unitfactorxyz, Z = val.Z / unitfactorxyz }; xyz.Add(valxyz); } break; case FoldMode.Stress: unitfactorxxyyzz = 1000000; List <Tensor3> stress_vals = elementResults.Stress.ToList(); foreach (Tensor3 val in stress_vals) { Vector3d valxxyyzz = new Vector3d { X = val.XX / unitfactorxxyyzz, Y = val.YY / unitfactorxxyyzz, Z = val.ZZ / unitfactorxxyyzz }; Vector3d valxyyzzx = new Vector3d { X = val.XY / unitfactorxxyyzz, Y = val.YZ / unitfactorxxyyzz, Z = val.ZX / unitfactorxxyyzz }; xyz.Add(valxxyyzz); xxyyzz.Add(valxyyzzx); } break; } // update max and min values dmax_x = Math.Max(xyz.Max(val => val.X), dmax_x); dmax_y = Math.Max(xyz.Max(val => val.Y), dmax_y); dmax_z = Math.Max(xyz.Max(val => val.Z), dmax_z); dmax_xyz = Math.Max( xyz.Max(val => Math.Sqrt( Math.Pow(val.X, 2) + Math.Pow(val.Y, 2) + Math.Pow(val.Z, 2))), dmax_xyz); dmin_x = Math.Min(xyz.Min(val => val.X), dmin_x); dmin_y = Math.Min(xyz.Min(val => val.Y), dmin_y); dmin_z = Math.Min(xyz.Min(val => val.Z), dmin_z); if (_mode == FoldMode.Stress) { dmax_xx = Math.Max(xxyyzz.Max(val => val.X), dmax_xx); dmax_yy = Math.Max(xxyyzz.Max(val => val.Y), dmax_yy); dmax_zz = Math.Max(xxyyzz.Max(val => val.Z), dmax_zz); dmin_xx = Math.Min(xxyyzz.Min(val => val.X), dmin_xx); dmin_yy = Math.Min(xxyyzz.Min(val => val.Y), dmin_yy); dmin_zz = Math.Min(xxyyzz.Min(val => val.Z), dmin_zz); } // add vector lists to main lists xyz_out.AddRange(xyz, new GH_Path(key - 1)); xxyyzz_out.AddRange(xxyyzz, new GH_Path(key - 1)); } } getresults = false; } #endregion #region Result mesh values // ### Coloured Result Meshes ### // round max and min to reasonable numbers double dmax = 0; double dmin = 0; switch (_disp) { case (DisplayValue.X): dmax = dmax_x; dmin = dmin_x; break; case (DisplayValue.Y): dmax = dmax_y; dmin = dmin_y; break; case (DisplayValue.Z): dmax = dmax_z; dmin = dmin_z; break; case (DisplayValue.resXYZ): dmax = dmax_xyz; dmin = dmin_xyz; break; case (DisplayValue.XX): dmax = dmax_xx; dmin = dmin_xx; break; case (DisplayValue.YY): dmax = dmax_yy; dmin = dmin_yy; break; case (DisplayValue.ZZ): dmax = dmax_zz; dmin = dmin_zz; break; case (DisplayValue.resXXYYZZ): dmax = dmax_xxyyzz; dmin = dmin_xxyyzz; break; } List <double> rounded = Util.Gsa.ResultHelper.SmartRounder(dmax, dmin); dmax = rounded[0]; dmin = rounded[1]; #region create mesh // create mesh // get elements and nodes from model elemList = string.Join(" ", keys.ToList()); IReadOnlyDictionary <int, Element> elems = gsaModel.Model.Elements(elemList); IReadOnlyDictionary <int, Node> nodes = gsaModel.Model.Nodes(); List <int> elemID = new List <int>(); List <int> parentMember = new List <int>(); List <ResultMesh> resultMeshes = new List <ResultMesh>(); List <Mesh> meshes = new List <Mesh>(); // loop through elements foreach (int key in elems.Keys) { elems.TryGetValue(key, out Element element); Mesh tempmesh = GhSA.Util.Gsa.FromGSA.ConvertElement3D(element, nodes); if (tempmesh == null) { continue; } List <Vector3d> transformation = null; // add mesh colour List <double> vals = new List <double>(); GH_Path path = new GH_Path(key - 1); List <Vector3d> tempXYZ = xyz_out.Branch(path); List <Vector3d> tempXXYYZZ = xxyyzz_out.Branch(path); switch (_disp) { case (DisplayValue.X): vals = tempXYZ.ConvertAll(val => val.X); transformation = new List <Vector3d>(); for (int i = 0; i < vals.Count; i++) { transformation.Add(new Vector3d(vals[i] * Value / 1000, 0, 0)); } break; case (DisplayValue.Y): vals = tempXYZ.ConvertAll(val => val.Y); transformation = new List <Vector3d>(); for (int i = 0; i < vals.Count; i++) { transformation.Add(new Vector3d(0, vals[i] * Value / 1000, 0)); } break; case (DisplayValue.Z): vals = tempXYZ.ConvertAll(val => val.Z); transformation = new List <Vector3d>(); for (int i = 0; i < vals.Count; i++) { transformation.Add(new Vector3d(0, 0, vals[i] * Value / 1000)); } break; case (DisplayValue.resXYZ): vals = tempXYZ.ConvertAll(val => ( Math.Sqrt( Math.Pow(val.X, 2) + Math.Pow(val.Y, 2) + Math.Pow(val.Z, 2)))); transformation = tempXYZ.ConvertAll(vec => Vector3d.Multiply(Value / 1000, vec)); break; case (DisplayValue.XX): vals = tempXXYYZZ.ConvertAll(val => val.X); break; case (DisplayValue.YY): vals = tempXXYYZZ.ConvertAll(val => val.Y); break; case (DisplayValue.ZZ): vals = tempXXYYZZ.ConvertAll(val => val.Z); break; case (DisplayValue.resXXYYZZ): vals = tempXXYYZZ.ConvertAll(val => ( Math.Sqrt( Math.Pow(val.X, 2) + Math.Pow(val.Y, 2) + Math.Pow(val.Z, 2)))); break; } for (int i = 1; i < vals.Count; i++) // start at i=1 as the first index is the centre point in GsaAPI output { //normalised value between -1 and 1 double tnorm = 2 * (vals[i] - dmin) / (dmax - dmin) - 1; System.Drawing.Color col = (double.IsNaN(tnorm)) ? System.Drawing.Color.Transparent : gH_Gradient.ColourAt(tnorm); tempmesh.VertexColors.Add(col); if (transformation != null) { Point3f def = tempmesh.Vertices[i - 1]; def.Transform(Transform.Translation(transformation[i])); tempmesh.Vertices[i - 1] = def; } } ResultMesh resultMesh = new ResultMesh(tempmesh, vals); meshes.Add(tempmesh); resultMeshes.Add(resultMesh); #endregion elemID.Add(key); parentMember.Add(element.ParentMember.Member); } #endregion #region Legend // ### Legend ### // loop through number of grip points in gradient to create legend //Find Colour and Values for legend output List <double> ts = new List <double>(); List <System.Drawing.Color> cs = new List <System.Drawing.Color>(); for (int i = 0; i < gH_Gradient.GripCount; i++) { double t = dmin + (dmax - dmin) / ((double)gH_Gradient.GripCount - 1) * (double)i; double scl = Math.Pow(10, Math.Floor(Math.Log10(Math.Abs(t))) + 1); scl = Math.Max(scl, 1); t = scl * Math.Round(t / scl, 3); ts.Add(t); System.Drawing.Color gradientcolour = gH_Gradient.ColourAt(2 * (double)i / ((double)gH_Gradient.GripCount - 1) - 1); cs.Add(gradientcolour); } #endregion // set outputs int outind = 0; DA.SetDataTree(outind++, xyz_out); if (_mode == FoldMode.Stress) { DA.SetDataTree(outind++, xxyyzz_out); } DA.SetDataList(outind++, resultMeshes); DA.SetDataList(outind++, cs); DA.SetDataList(outind++, ts); } }
protected override void SolveInstance(IGH_DataAccess DA) { // Model to work on GsaModel in_Model = new GsaModel(); // Get Model GH_ObjectWrapper gh_typ = new GH_ObjectWrapper(); if (DA.GetData(0, ref gh_typ)) { #region Inputs if (gh_typ.Value is GsaModelGoo) { gh_typ.CastTo(ref in_Model); if (gsaModel != null) { if (in_Model.GUID != gsaModel.GUID) { gsaModel = in_Model; getresults = true; } } else { gsaModel = in_Model; } } else { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Error converting input to GSA Model"); return; } // Get analysis case GH_Integer gh_aCase = new GH_Integer(); DA.GetData(1, ref gh_aCase); GH_Convert.ToInt32(gh_aCase, out int tempanalCase, GH_Conversion.Both); // Get node filter list GH_String gh_noList = new GH_String(); DA.GetData(2, ref gh_noList); GH_Convert.ToString(gh_noList, out string tempnodeList, GH_Conversion.Both); // Get colours List <Grasshopper.Kernel.Types.GH_Colour> gh_Colours = new List <Grasshopper.Kernel.Types.GH_Colour>(); List <System.Drawing.Color> colors = new List <System.Drawing.Color>(); if (DA.GetDataList(3, gh_Colours)) { for (int i = 0; i < gh_Colours.Count; i++) { System.Drawing.Color color = new System.Drawing.Color(); GH_Convert.ToColor(gh_Colours[i], out color, GH_Conversion.Both); colors.Add(color); } } Grasshopper.GUI.Gradient.GH_Gradient gH_Gradient = UI.Colour.Stress_Gradient(colors); // Get scalar GH_Number gh_Scale = new GH_Number(); DA.GetData(4, ref gh_Scale); double scale = 1; GH_Convert.ToDouble(gh_Scale, out scale, GH_Conversion.Both); #endregion #region get results? // check if we must get results or just update display if (analCase == 0 || analCase != tempanalCase) { analCase = tempanalCase; getresults = true; } if (nodeList == "" || nodeList != tempnodeList) { nodeList = tempnodeList; getresults = true; } #endregion if (getresults) { #region Get results from GSA // ### Get results ### //Get analysis case from model AnalysisCaseResult analysisCaseResult = null; gsaModel.Model.Results().TryGetValue(analCase, out analysisCaseResult); if (analysisCaseResult == null) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "No results exist for Analysis Case " + analCase + " in file"); return; } IReadOnlyDictionary <int, NodeResult> results = analysisCaseResult.NodeResults(nodeList); IReadOnlyDictionary <int, Node> nodes = gsaModel.Model.Nodes(nodeList); #endregion #region Create results output // ### Loop through results ### // clear any existing lists of vectors to output results in: xyz = new List <Vector3d>(); xxyyzz = new List <Vector3d>(); // maximum and minimum result values for colouring later dmax_x = 0; dmax_y = 0; dmax_z = 0; dmax_xx = 0; dmax_yy = 0; dmax_zz = 0; dmax_xyz = 0; dmax_xxyyzz = 0; dmin_x = 0; dmin_y = 0; dmin_z = 0; dmin_xx = 0; dmin_yy = 0; dmin_zz = 0; dmin_xyz = 0; dmin_xxyyzz = 0; double unitfactorxyz = 1; double unitfactorxxyyzz = 1; // if reaction type, then we reuse the nodeList to filter support nodes from the rest if (_mode == FoldMode.Reaction) { nodeList = ""; } foreach (var key in results.Keys) { NodeResult result; Double6 values = null; if (_mode == FoldMode.Reaction) { bool isSupport = false; Node node = new Node(); nodes.TryGetValue(key, out node); NodalRestraint rest = node.Restraint; if (rest.X || rest.Y || rest.Z || rest.XX || rest.YY || rest.ZZ) { isSupport = true; } if (!isSupport) { continue; } else { if (nodeList == "") { nodeList = key.ToString(); } else { nodeList += " " + key; } } } results.TryGetValue(key, out result); switch (_mode) { case (FoldMode.Displacement): values = result.Displacement; unitfactorxyz = 0.001; unitfactorxxyyzz = 1; break; case (FoldMode.Reaction): values = result.Reaction; unitfactorxyz = 1000; unitfactorxxyyzz = 1000; break; case (FoldMode.SpringForce): values = result.SpringForce; unitfactorxyz = 1000; unitfactorxxyyzz = 1000; break; case (FoldMode.Constraint): values = result.Constraint; break; } // update max and min values if (values.X / unitfactorxyz > dmax_x) { dmax_x = values.X / unitfactorxyz; } if (values.Y / unitfactorxyz > dmax_y) { dmax_y = values.Y / unitfactorxyz; } if (values.Z / unitfactorxyz > dmax_z) { dmax_z = values.Z / unitfactorxyz; } if (Math.Sqrt(Math.Pow(values.X, 2) + Math.Pow(values.Y, 2) + Math.Pow(values.Z, 2)) / unitfactorxyz > dmax_xyz) { dmax_xyz = Math.Sqrt(Math.Pow(values.X, 2) + Math.Pow(values.Y, 2) + Math.Pow(values.Z, 2)) / unitfactorxyz; } if (values.XX / unitfactorxxyyzz > dmax_xx) { dmax_xx = values.XX / unitfactorxxyyzz; } if (values.YY / unitfactorxxyyzz > dmax_yy) { dmax_yy = values.YY / unitfactorxxyyzz; } if (values.ZZ / unitfactorxxyyzz > dmax_zz) { dmax_zz = values.ZZ / unitfactorxxyyzz; } if (Math.Sqrt(Math.Pow(values.XX, 2) + Math.Pow(values.YY, 2) + Math.Pow(values.ZZ, 2)) / unitfactorxxyyzz > dmax_xxyyzz) { dmax_xxyyzz = Math.Sqrt(Math.Pow(values.XX, 2) + Math.Pow(values.YY, 2) + Math.Pow(values.ZZ, 2)) / unitfactorxxyyzz; } if (values.X / unitfactorxyz < dmin_x) { dmin_x = values.X / unitfactorxyz; } if (values.Y / unitfactorxyz < dmin_y) { dmin_y = values.Y / unitfactorxyz; } if (values.Z / unitfactorxyz < dmin_z) { dmin_z = values.Z / unitfactorxyz; } if (Math.Sqrt(Math.Pow(values.X, 2) + Math.Pow(values.Y, 2) + Math.Pow(values.Z, 2)) / unitfactorxyz < dmin_xyz) { dmin_xyz = Math.Sqrt(Math.Pow(values.X, 2) + Math.Pow(values.Y, 2) + Math.Pow(values.Z, 2)) / unitfactorxyz; } if (values.XX / unitfactorxxyyzz < dmin_xx) { dmin_xx = values.XX / unitfactorxxyyzz; } if (values.YY / unitfactorxxyyzz < dmin_yy) { dmin_yy = values.YY / unitfactorxxyyzz; } if (values.ZZ / unitfactorxxyyzz < dmin_zz) { dmin_zz = values.ZZ / unitfactorxxyyzz; } if (Math.Sqrt(Math.Pow(values.XX, 2) + Math.Pow(values.YY, 2) + Math.Pow(values.ZZ, 2)) / unitfactorxxyyzz < dmin_xxyyzz) { dmin_xxyyzz = Math.Sqrt(Math.Pow(values.XX, 2) + Math.Pow(values.YY, 2) + Math.Pow(values.ZZ, 2)) / unitfactorxxyyzz; } // add the values to the vector lists xyz.Add(new Vector3d(values.X / unitfactorxyz, values.Y / unitfactorxyz, values.Z / unitfactorxyz)); xxyyzz.Add(new Vector3d(values.XX / unitfactorxxyyzz, values.YY / unitfactorxxyyzz, values.ZZ / unitfactorxxyyzz)); } #endregion getresults = false; } #region Result point values // ### Coloured Result Points ### // Get nodes for point location and restraint check in case of reaction force IReadOnlyDictionary <int, Node> nDict = gsaModel.Model.Nodes(nodeList); List <GsaNodeGoo> gsanodes = Util.Gsa.FromGSA.GetNodes(nDict, gsaModel.Model); //Find Colour and Values for legend output List <double> ts = new List <double>(); List <System.Drawing.Color> cs = new List <System.Drawing.Color>(); // round max and min to reasonable numbers double dmax = 0; double dmin = 0; switch (_disp) { case (DisplayValue.X): dmax = dmax_x; dmin = dmin_x; break; case (DisplayValue.Y): dmax = dmax_y; dmin = dmin_y; break; case (DisplayValue.Z): dmax = dmax_z; dmin = dmin_z; break; case (DisplayValue.resXYZ): dmax = dmax_xyz; dmin = dmin_xyz; break; case (DisplayValue.XX): dmax = dmax_xx; dmin = dmin_xx; break; case (DisplayValue.YY): dmax = dmax_yy; dmin = dmin_yy; break; case (DisplayValue.ZZ): dmax = dmax_zz; dmin = dmin_zz; break; case (DisplayValue.resXXYYZZ): dmax = dmax_xxyyzz; dmin = dmin_xxyyzz; break; } List <double> rounded = Util.Gsa.ResultHelper.SmartRounder(dmax, dmin); dmax = rounded[0]; dmin = rounded[1]; // Loop through nodes and set result colour into ResultPoint format List <ResultPoint> pts = new List <ResultPoint>(); List <System.Drawing.Color> col = new List <System.Drawing.Color>(); for (int i = 0; i < gsanodes.Count; i++) { if (gsanodes[i].Value != null) { if (!(dmin == 0 & dmax == 0)) { double t = 0; Vector3d translation = new Vector3d(0, 0, 0); // pick the right value to display switch (_disp) { case (DisplayValue.X): t = xyz[i].X; translation.X = t * Value / 1000; break; case (DisplayValue.Y): t = xyz[i].Y; translation.Y = t * Value / 1000; break; case (DisplayValue.Z): t = xyz[i].Z; translation.Z = t * Value / 1000; break; case (DisplayValue.resXYZ): t = Math.Sqrt(Math.Pow(xyz[i].X, 2) + Math.Pow(xyz[i].Y, 2) + Math.Pow(xyz[i].Z, 2)); translation.X = xyz[i].X * Value / 1000; translation.Y = xyz[i].Y * Value / 1000; translation.Z = xyz[i].Z * Value / 1000; break; case (DisplayValue.XX): t = xxyyzz[i].X; break; case (DisplayValue.YY): t = xxyyzz[i].Y; break; case (DisplayValue.ZZ): t = xxyyzz[i].Z; break; case (DisplayValue.resXXYYZZ): t = Math.Sqrt(Math.Pow(xxyyzz[i].X, 2) + Math.Pow(xxyyzz[i].Y, 2) + Math.Pow(xxyyzz[i].Z, 2)); break; } //normalised value between -1 and 1 double tnorm = 2 * (t - dmin) / (dmax - dmin) - 1; // get colour for that normalised value System.Drawing.Color valcol = gH_Gradient.ColourAt(tnorm); // set the size of the point for ResultPoint class. Size is calculated from 0-base, so not a normalised value between extremes float size = (t >= 0 && dmax != 0) ? Math.Max(2, (float)(t / dmax * scale)) : Math.Max(2, (float)(Math.Abs(t) / Math.Abs(dmin) * scale)); // create deflection point Point3d def = new Point3d(gsanodes[i].Value.Point); def.Transform(Transform.Translation(translation)); // add our special resultpoint to the list of points pts.Add(new ResultPoint(def, t, valcol, size)); // add the colour to the colours list col.Add(valcol); } } } #endregion #region Legend // ### Legend ### // loop through number of grip points in gradient to create legend for (int i = 0; i < gH_Gradient.GripCount; i++) { double t = dmin + (dmax - dmin) / ((double)gH_Gradient.GripCount - 1) * (double)i; double scl = Math.Pow(10, Math.Floor(Math.Log10(Math.Abs(t))) + 1); scl = Math.Max(scl, 1); t = scl * Math.Round(t / scl, 3); ts.Add(t); System.Drawing.Color gradientcolour = gH_Gradient.ColourAt(2 * (double)i / ((double)gH_Gradient.GripCount - 1) - 1); cs.Add(gradientcolour); } #endregion // set outputs DA.SetDataList(0, xyz); DA.SetDataList(1, xxyyzz); DA.SetDataList(2, pts); DA.SetDataList(3, col); DA.SetDataList(4, cs); DA.SetDataList(5, ts); } }
/***************************************************/ // Create the preview of nodes. public static void AddNodePreview(this Rhino.Display.CustomDisplay display, Model model, IEnumerable <int> ids, double graphicFactor, double elementFactor, double textFactor, double forceFactor, bool showNodes, bool showNodeNumbers, bool showLoads, bool showLoadValues, Grasshopper.GUI.Gradient.GH_Gradient gradient = null, string nodeResultType = "None", bool showResultValues = false) { if (model.Mesh == null || model.Mesh.Nodes.Count == 0) { return; } List <double> nodeResults = new List <double>(); double nodeMax = 0; double nodeMin = 0; if (nodeResultType != "None") { nodeResults = model.Mesh.GetNodeDisplacement(nodeResultType); nodeMax = nodeResults.Max(); nodeMin = nodeResults.Min(); } foreach (int i in ids) { Node n = model.Mesh.Nodes[i]; if (!n.Primary) { continue; } if (showNodes) { if (nodeResults.Count > 0) { display.AddPoint(n.Location, gradient.ColourAt((nodeResults[i] - nodeMin) / (nodeMax - nodeMin)), Rhino.Display.PointStyle.Simple, Math.Max(1, Convert.ToInt32(5 * elementFactor * graphicFactor))); } else { display.AddPoint(n.Location, Color.DarkRed, Rhino.Display.PointStyle.Simple, Math.Max(1, Convert.ToInt32(5 * elementFactor * graphicFactor))); } } if (showResultValues && nodeResults.Count > 0) { Plane p = new Plane(n.Location + Vector3d.ZAxis * elementFactor, Vector3d.XAxis, Vector3d.ZAxis); Rhino.Display.Text3d t = new Rhino.Display.Text3d(nodeResults[i].ToString("G2"), p, elementFactor * 0.4 * textFactor); t.Bold = true; display.AddText(t, Color.Black); } if (showLoads && n.ForceLoad.Length != 0) { Vector3d dLoad = n.ForceLoad / forceFactor * elementFactor * 5 * graphicFactor; display.AddVector(n.Location - dLoad, dLoad); if (showLoadValues) { Plane p = new Plane(n.Location - dLoad * 1.1, Vector3d.XAxis, Vector3d.ZAxis); Rhino.Display.Text3d t = new Rhino.Display.Text3d(n.ForceLoad.Length.ToString("G2"), p, elementFactor * 0.4 * textFactor); t.Bold = true; display.AddText(t, Color.Magenta); } } if (showLoads && n.MomentLoad.Length != 0) { Vector3d mLoad = n.MomentLoad; Vector3d axis = new Vector3d(mLoad.X, mLoad.Y, mLoad.Z); Plane ap = new Plane(n.Location, axis); Arc mArc = new Arc(new Circle(ap, 2.5 * elementFactor * graphicFactor), Math.PI * 1.5); display.AddArc(mArc); display.AddVector(mArc.EndPoint, mArc.TangentAt(Math.PI * 1.5)); if (showLoadValues) { Plane p = new Plane(n.Location - n.MomentLoad / forceFactor * elementFactor * 5 * graphicFactor * 1.1, Vector3d.XAxis, Vector3d.ZAxis); Rhino.Display.Text3d t = new Rhino.Display.Text3d(n.MomentLoad.Length.ToString("G2"), p, elementFactor * 0.4 * textFactor); t.Bold = true; display.AddText(t, Color.Magenta); } } if (showNodeNumbers) { Plane p = new Plane(n.Location, Vector3d.XAxis, Vector3d.ZAxis); Rhino.Display.Text3d t = new Rhino.Display.Text3d(n.CCXId(), p, elementFactor * 0.4 * textFactor); t.Bold = true; display.AddText(t, Color.Purple); } } }
/***************************************************/ // 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); } } } }
protected override void SolveInstance(IGH_DataAccess DA) { // Model to work on GsaModel in_Model = new GsaModel(); // Get Model GH_ObjectWrapper gh_typ = new GH_ObjectWrapper(); if (DA.GetData(0, ref gh_typ)) { #region Inputs if (gh_typ.Value is GsaModelGoo) { gh_typ.CastTo(ref in_Model); if (gsaModel != null) { if (in_Model.GUID != gsaModel.GUID) { gsaModel = in_Model; getresults = true; } } else { gsaModel = in_Model; } } else { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Error converting input to GSA Model"); return; } // Get analysis case GH_Integer gh_aCase = new GH_Integer(); DA.GetData(1, ref gh_aCase); GH_Convert.ToInt32(gh_aCase, out int tempanalCase, GH_Conversion.Both); // Get element filter list GH_String gh_elList = new GH_String(); DA.GetData(2, ref gh_elList); GH_Convert.ToString(gh_elList, out string tempelemList, GH_Conversion.Both); // Get number of divisions GH_Integer gh_Div = new GH_Integer(); DA.GetData(3, ref gh_Div); GH_Convert.ToInt32(gh_Div, out int temppositionsCount, GH_Conversion.Both); // Get colours List <Grasshopper.Kernel.Types.GH_Colour> gh_Colours = new List <Grasshopper.Kernel.Types.GH_Colour>(); List <System.Drawing.Color> colors = new List <System.Drawing.Color>(); if (DA.GetDataList(4, gh_Colours)) { for (int i = 0; i < gh_Colours.Count; i++) { System.Drawing.Color color = new System.Drawing.Color(); GH_Convert.ToColor(gh_Colours[i], out color, GH_Conversion.Both); colors.Add(color); } } Grasshopper.GUI.Gradient.GH_Gradient gH_Gradient = UI.Colour.Stress_Gradient(colors); // Get scalar GH_Number gh_Scale = new GH_Number(); DA.GetData(5, ref gh_Scale); double scale = 1; GH_Convert.ToDouble(gh_Scale, out scale, GH_Conversion.Both); #endregion #region get results? // check if we must get results or just update display if (analCase == 0 || analCase != tempanalCase) { analCase = tempanalCase; getresults = true; } if (elemList == "" || elemList != tempelemList) { elemList = tempelemList; getresults = true; } if (positionsCount == 0 || positionsCount != temppositionsCount) { positionsCount = temppositionsCount; getresults = true; } #endregion #region Create results output if (getresults) { #region Get results from GSA // ### Get results ### //Get analysis case from model AnalysisCaseResult analysisCaseResult = null; gsaModel.Model.Results().TryGetValue(analCase, out analysisCaseResult); if (analysisCaseResult == null) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "No results exist for Analysis Case " + analCase + " in file"); return; } IReadOnlyDictionary <int, Element1DResult> globalResults = analysisCaseResult.Element1DResults(elemList, positionsCount); IReadOnlyDictionary <int, Element> elems = gsaModel.Model.Elements(elemList); IReadOnlyDictionary <int, Node> nodes = gsaModel.Model.Nodes(); #endregion // ### Loop through results ### // clear existing result lists xyz_out = new DataTree <Vector3d>(); xxyyzz_out = new DataTree <Vector3d>(); segmentlines = new DataTree <Line>(); List <int> elemID = new List <int>(); List <int> parentMember = new List <int>(); // maximum and minimum result values for colouring later dmax_x = 0; dmax_y = 0; dmax_z = 0; dmax_xx = 0; dmax_yy = 0; dmax_zz = 0; dmax_xyz = 0; dmax_xxyyzz = 0; dmin_x = 0; dmin_y = 0; dmin_z = 0; dmin_xx = 0; dmin_yy = 0; dmin_zz = 0; dmin_xyz = 0; dmin_xxyyzz = 0; double unitfactorxyz = 1; double unitfactorxxyyzz = 1; foreach (int key in globalResults.Keys) { // lists for results Element1DResult elementResults; globalResults.TryGetValue(key, out elementResults); List <Double6> values = new List <Double6>(); List <Vector3d> xyz = new List <Vector3d>(); List <Vector3d> xxyyzz = new List <Vector3d>(); // list for element geometry and info Element element = new Element(); elems.TryGetValue(key, out element); Node start = new Node(); nodes.TryGetValue(element.Topology[0], out start); Node end = new Node(); nodes.TryGetValue(element.Topology[1], out end); Line ln = new Line( new Point3d(start.Position.X, start.Position.Y, start.Position.Z), new Point3d(end.Position.X, end.Position.Y, end.Position.Z)); elemID.Add(key); parentMember.Add(element.ParentMember.Member); // set the result type dependent on user selection in dropdown switch (_mode) { case (FoldMode.Displacement): values = elementResults.Displacement.ToList(); unitfactorxyz = 0.001; unitfactorxxyyzz = 1; break; case (FoldMode.Force): values = elementResults.Force.ToList(); unitfactorxyz = 1000; unitfactorxxyyzz = 1000; break; } // prepare the line segments int segments = Math.Max(1, values.Count - 1); // number of segment lines is 1 less than number of points int segment = 0; // counter for segments List <Line> segmentedlines = new List <Line>(); // loop through the results foreach (Double6 result in values) { // update max and min values if (result.X / unitfactorxyz > dmax_x) { dmax_x = result.X / unitfactorxyz; } if (result.Y / unitfactorxyz > dmax_y) { dmax_y = result.Y / unitfactorxyz; } if (result.Z / unitfactorxyz > dmax_z) { dmax_z = result.Z / unitfactorxyz; } if (Math.Sqrt(Math.Pow(result.X, 2) + Math.Pow(result.Y, 2) + Math.Pow(result.Z, 2)) / unitfactorxyz > dmax_xyz) { dmax_xyz = Math.Sqrt(Math.Pow(result.X, 2) + Math.Pow(result.Y, 2) + Math.Pow(result.Z, 2)) / unitfactorxyz; } if (result.XX / unitfactorxxyyzz > dmax_xx) { dmax_xx = result.XX / unitfactorxxyyzz; } if (result.YY / unitfactorxxyyzz > dmax_yy) { dmax_yy = result.YY / unitfactorxxyyzz; } if (result.ZZ / unitfactorxxyyzz > dmax_zz) { dmax_zz = result.ZZ / unitfactorxxyyzz; } if (Math.Sqrt(Math.Pow(result.XX, 2) + Math.Pow(result.YY, 2) + Math.Pow(result.ZZ, 2)) / unitfactorxxyyzz > dmax_xxyyzz) { dmax_xxyyzz = Math.Sqrt(Math.Pow(result.XX, 2) + Math.Pow(result.YY, 2) + Math.Pow(result.ZZ, 2)) / unitfactorxxyyzz; } if (result.X / unitfactorxyz < dmin_x) { dmin_x = result.X / unitfactorxyz; } if (result.Y / unitfactorxyz < dmin_y) { dmin_y = result.Y / unitfactorxyz; } if (result.Z / unitfactorxyz < dmin_z) { dmin_z = result.Z / unitfactorxyz; } if (Math.Sqrt(Math.Pow(result.X, 2) + Math.Pow(result.Y, 2) + Math.Pow(result.Z, 2)) / unitfactorxyz < dmin_xyz) { dmin_xyz = Math.Sqrt(Math.Pow(result.X, 2) + Math.Pow(result.Y, 2) + Math.Pow(result.Z, 2)) / unitfactorxyz; } if (result.XX / unitfactorxxyyzz < dmin_xx) { dmin_xx = result.XX / unitfactorxxyyzz; } if (result.YY / unitfactorxxyyzz < dmin_yy) { dmin_yy = result.YY / unitfactorxxyyzz; } if (result.ZZ / unitfactorxxyyzz < dmin_zz) { dmin_zz = result.ZZ / unitfactorxxyyzz; } if (Math.Sqrt(Math.Pow(result.XX, 2) + Math.Pow(result.YY, 2) + Math.Pow(result.ZZ, 2)) / unitfactorxxyyzz < dmin_xxyyzz) { dmin_xxyyzz = Math.Sqrt(Math.Pow(result.XX, 2) + Math.Pow(result.YY, 2) + Math.Pow(result.ZZ, 2)) / unitfactorxxyyzz; } // add the values to the vector lists xyz.Add(new Vector3d(result.X / unitfactorxyz, result.Y / unitfactorxyz, result.Z / unitfactorxyz)); xxyyzz.Add(new Vector3d(result.XX / unitfactorxxyyzz, result.YY / unitfactorxxyyzz, result.ZZ / unitfactorxxyyzz)); // create ResultLines if (segment < segments) { Line segmentline = new Line( ln.PointAt((double)segment / segments), ln.PointAt((double)(segment + 1) / segments) ); segment++; segmentedlines.Add(segmentline); } } // add the vector list to the out tree xyz_out.AddRange(xyz, new GH_Path(key - 1)); xxyyzz_out.AddRange(xxyyzz, new GH_Path(key - 1)); segmentlines.AddRange(segmentedlines, new GH_Path(key - 1)); } getresults = false; } #endregion #region Result line values // ### Coloured Result Lines ### // round max and min to reasonable numbers double dmax = 0; double dmin = 0; switch (_disp) { case (DisplayValue.X): dmax = dmax_x; dmin = dmin_x; break; case (DisplayValue.Y): dmax = dmax_y; dmin = dmin_y; break; case (DisplayValue.Z): dmax = dmax_z; dmin = dmin_z; break; case (DisplayValue.resXYZ): dmax = dmax_xyz; dmin = dmin_xyz; break; case (DisplayValue.XX): dmax = dmax_xx; dmin = dmin_xx; break; case (DisplayValue.YY): dmax = dmax_yy; dmin = dmin_yy; break; case (DisplayValue.ZZ): dmax = dmax_zz; dmin = dmin_zz; break; case (DisplayValue.resXXYYZZ): dmax = dmax_xxyyzz; dmin = dmin_xxyyzz; break; } List <double> rounded = Util.Gsa.ResultHelper.SmartRounder(dmax, dmin); dmax = rounded[0]; dmin = rounded[1]; // Loop through segmented lines and set result colour into ResultLine format DataTree <ResultLine> lines_out = new DataTree <ResultLine>(); DataTree <System.Drawing.Color> col_out = new DataTree <System.Drawing.Color>(); foreach (GH_Path path in segmentlines.Paths) { List <ResultLine> lns = new List <ResultLine>(); List <System.Drawing.Color> col = new List <System.Drawing.Color>(); List <Line> segmentedlines = segmentlines.Branch(path); for (int j = 0; j < segmentedlines.Count; j++) { if (!(dmin == 0 & dmax == 0)) { Vector3d startTranslation = new Vector3d(0, 0, 0); Vector3d endTranslation = new Vector3d(0, 0, 0); double t1 = 0; double t2 = 0; // pick the right value to display switch (_disp) { case (DisplayValue.X): t1 = xyz_out[path, j].X; t2 = xyz_out[path, j + 1].X; startTranslation.X = t1 * Value / 1000; endTranslation.X = t2 * Value / 1000; break; case (DisplayValue.Y): t1 = xyz_out[path, j].Y; t2 = xyz_out[path, j + 1].Y; startTranslation.Y = t1 * Value / 1000; endTranslation.Y = t2 * Value / 1000; break; case (DisplayValue.Z): t1 = xyz_out[path, j].Z; t2 = xyz_out[path, j + 1].Z; startTranslation.Z = t1 * Value / 1000; endTranslation.Z = t2 * Value / 1000; break; case (DisplayValue.resXYZ): t1 = Math.Sqrt(Math.Pow(xyz_out[path, j].X, 2) + Math.Pow(xyz_out[path, j].Y, 2) + Math.Pow(xyz_out[path, j].Z, 2)); t2 = Math.Sqrt(Math.Pow(xyz_out[path, j + 1].X, 2) + Math.Pow(xyz_out[path, j + 1].Y, 2) + Math.Pow(xyz_out[path, j + 1].Z, 2)); startTranslation.X = xyz_out[path, j].X * Value / 1000; endTranslation.X = xyz_out[path, j + 1].X * Value / 1000; startTranslation.Y = xyz_out[path, j].Y * Value / 1000; endTranslation.Y = xyz_out[path, j + 1].Y * Value / 1000; startTranslation.Z = xyz_out[path, j].Z * Value / 1000; endTranslation.Z = xyz_out[path, j + 1].Z * Value / 1000; break; case (DisplayValue.XX): t1 = xxyyzz_out[path, j].X; t2 = xxyyzz_out[path, j + 1].X; break; case (DisplayValue.YY): t1 = xxyyzz_out[path, j].Y; t2 = xxyyzz_out[path, j + 1].Y; break; case (DisplayValue.ZZ): t1 = xxyyzz_out[path, j].Z; t2 = xxyyzz_out[path, j + 1].Z; break; case (DisplayValue.resXXYYZZ): t1 = Math.Sqrt(Math.Pow(xxyyzz_out[path, j].X, 2) + Math.Pow(xxyyzz_out[path, j].Y, 2) + Math.Pow(xxyyzz_out[path, j].Z, 2)); t2 = Math.Sqrt(Math.Pow(xxyyzz_out[path, j + 1].X, 2) + Math.Pow(xxyyzz_out[path, j + 1].Y, 2) + Math.Pow(xxyyzz_out[path, j + 1].Z, 2)); break; } Point3d start = new Point3d(segmentedlines[j].PointAt(0)); start.Transform(Transform.Translation(startTranslation)); Point3d end = new Point3d(segmentedlines[j].PointAt(1)); end.Transform(Transform.Translation(endTranslation)); Line segmentline = new Line(start, end); //normalised value between -1 and 1 double tnorm1 = 2 * (t1 - dmin) / (dmax - dmin) - 1; double tnorm2 = 2 * (t2 - dmin) / (dmax - dmin) - 1; // get colour for that normalised value System.Drawing.Color valcol1 = double.IsNaN(tnorm1) ? System.Drawing.Color.Black : gH_Gradient.ColourAt(tnorm1); System.Drawing.Color valcol2 = double.IsNaN(tnorm2) ? System.Drawing.Color.Black : gH_Gradient.ColourAt(tnorm2); // set the size of the line ends for ResultLine class. Size is calculated from 0-base, so not a normalised value between extremes float size1 = (t1 >= 0 && dmax != 0) ? Math.Max(2, (float)(t1 / dmax * scale)) : Math.Max(2, (float)(Math.Abs(t1) / Math.Abs(dmin) * scale)); if (double.IsNaN(size1)) { size1 = 1; } float size2 = (t2 >= 0 && dmax != 0) ? Math.Max(2, (float)(t2 / dmax * scale)) : Math.Max(2, (float)(Math.Abs(t2) / Math.Abs(dmin) * scale)); if (double.IsNaN(size2)) { size2 = 1; } // add our special resultline to the list of lines lns.Add(new ResultLine(segmentline, t1, t2, valcol1, valcol2, size1, size2)); // add the colour to the colours list col.Add(valcol1); if (j == segmentedlines.Count - 1) { col.Add(valcol2); } } } lines_out.AddRange(lns, path); col_out.AddRange(col, path); } #endregion #region Legend // ### Legend ### // loop through number of grip points in gradient to create legend //Find Colour and Values for legend output List <double> ts = new List <double>(); List <System.Drawing.Color> cs = new List <System.Drawing.Color>(); for (int i = 0; i < gH_Gradient.GripCount; i++) { double t = dmin + (dmax - dmin) / ((double)gH_Gradient.GripCount - 1) * (double)i; double scl = Math.Pow(10, Math.Floor(Math.Log10(Math.Abs(t))) + 1); scl = Math.Max(scl, 1); t = scl * Math.Round(t / scl, 3); ts.Add(t); System.Drawing.Color gradientcolour = gH_Gradient.ColourAt(2 * (double)i / ((double)gH_Gradient.GripCount - 1) - 1); cs.Add(gradientcolour); } #endregion // set outputs DA.SetDataTree(0, xyz_out); DA.SetDataTree(1, xxyyzz_out); DA.SetDataTree(2, lines_out); DA.SetDataTree(3, col_out); DA.SetDataList(4, cs); DA.SetDataList(5, ts); } }