public override void SolveInstance(IGH_DataAccess DA, out string msg, out GH_RuntimeMessageLevel level) { msg = ""; level = GH_RuntimeMessageLevel.Blank; OnComponentLoaded(); // Input var inGH = new GH_RFEM(); var inGH2 = new List <GH_RFEM>(); var iMember = new RFMember(); var iCroSecs = new List <RFCroSec>(); // Output var oExtrussion = new List <Brep>(); // Register input parameters if (!DA.GetData(0, ref inGH)) { return; } iMember = (RFMember)inGH.Value; if (!DA.GetDataList(1, inGH2)) { return; } foreach (var cs in inGH2) { iCroSecs.Add((RFCroSec)cs.Value); } oExtrussion = Component_ExtrudeMembers.ExtrudeMembersToBrep(iMember, iCroSecs, length_segment, out msg); if (msg != "") { level = GH_RuntimeMessageLevel.Warning; return; } // Assign output DA.SetDataList(0, oExtrussion); }
public override void SolveInstance(IGH_DataAccess DA, out string msg, out GH_RuntimeMessageLevel level) { msg = ""; level = GH_RuntimeMessageLevel.Blank; OnComponentLoaded(); // Input var inGH = new GH_RFEM(); var inGH2 = new List <GH_RFEM>(); var iMember = new RFMember(); var iCroSecs = new List <RFCroSec>(); // Output var oExtrussion = new List <Mesh>(); // Register input parameters if (!DA.GetData(0, ref inGH)) { return; } iMember = (RFMember)inGH.Value; if (!DA.GetDataList(1, inGH2)) { return; } foreach (var cs in inGH2) { iCroSecs.Add((RFCroSec)cs.Value); } // Check input var cs_indeces = iCroSecs.Select(x => x.No); if (iMember.EndCrossSectionNo == 0) // In case of tension members, etc. { iMember.EndCrossSectionNo = iMember.StartCrossSectionNo; } if (!(cs_indeces.Contains(iMember.StartCrossSectionNo)) || (!(cs_indeces.Contains(iMember.EndCrossSectionNo)))) { level = GH_RuntimeMessageLevel.Warning; msg = $"Provide cross sections for member No {iMember.No}."; return; } // Get base geometry var crosecs1 = iCroSecs.Where(x => x.No == iMember.StartCrossSectionNo).ToList()[0].Shape; var crosecs2 = iCroSecs.Where(x => x.No == iMember.EndCrossSectionNo).ToList()[0].Shape; var baseline = iMember.BaseLine.ToCurve(); // Check geometry if ((crosecs1.Sum(x => x.SpanCount) != crosecs2.Sum(x => x.SpanCount)) || (crosecs1.Count != crosecs2.Count)) { level = GH_RuntimeMessageLevel.Warning; msg = $"Provide similar cross sections for member No {iMember.No}."; return; } // Generate tween curves - still on the origin! List <Curve> segments; int nCroSecsInter = Math.Max((int)(baseline.GetLength() / length_segment), 2); var loft_crvs = Component_ExtrudeMembers.GenerateCroSecs(baseline, crosecs1, crosecs2, nCroSecsInter, 0.001, 0.001, out segments); // Orient cross sections loft_crvs = Component_ExtrudeMembers.OrientCroSecs(loft_crvs, segments, nCroSecsInter, iMember.Frames[0], crosecs1.Count); // Extrude members for (int i = 0; i < loft_crvs.Count; i++) { for (int j = 0; j < loft_crvs[i].Count; j++) { var beam_mesh = new Mesh(); // for each of the curves that make one cross section for (int k = 0; k < loft_crvs[i][j].Count; k++) { var exploded_segments = new List <Curve>(); if (loft_crvs[i][j][k].SpanCount > 1) { // exploded_segments = loft_crvs[i][j][k].DuplicateSegments().ToList(); var crv = loft_crvs[i][j][k].ToNurbsCurve(); // Get spilt parameters var split_t = new List <double>(); for (int n = 0; n < crv.SpanCount; n++) { split_t.Add(crv.SpanDomain(n).T0); //split_t.Add(crv.SpanDomain(n).T1); } split_t.Add(crv.SpanDomain(crv.SpanCount - 1).T1); //split_t = split_t.Distinct().ToList(); exploded_segments = crv.Split(split_t).ToList(); } else { exploded_segments.Add(loft_crvs[i][j][k]); } //var real_segments = (exploded_segments.Where(x => x.GetLength()>0.001)).ToList(); var real_segments = exploded_segments; var counter_nodes = loft_crvs[i][j][k].IsClosed ? real_segments.Count * nFaces : real_segments.Count * nFaces + 1; for (int n = 0; n < real_segments.Count; n++) { var domain = real_segments[n].Domain; for (int m = 0; m < nFaces; m++) { // Add vertex if (!(real_segments[n].IsClosed & m == nFaces - 1 & n == real_segments.Count - 1)) // for closed section shapes ignore last point { var t = (double)m / (double)nFaces * (domain.T1 - domain.T0) + domain.T0; var pt = real_segments[n].PointAt(t); beam_mesh.Vertices.Add(pt.X, pt.Y, pt.Z); } // Add mesh face if ((m + n) > 0 & k > 0) { int a = (m - 1) + n * nFaces + counter_nodes * (k - 1); int b = ((m) + n * nFaces) % counter_nodes + counter_nodes * (k - 1); // get first node in the section if it is closed int c = ((m) + n * nFaces) % counter_nodes + counter_nodes * (k); int d = (m - 1) + n * nFaces + counter_nodes * (k); beam_mesh.Faces.AddFace(new MeshFace(a, b, c, d)); } } } // Add last face if (k > 0) { int a1 = (nFaces * real_segments.Count - 1) + counter_nodes * (k - 1); int b1 = (nFaces * real_segments.Count) % counter_nodes + counter_nodes * (k - 1); int c1 = (nFaces * real_segments.Count) % counter_nodes + counter_nodes * (k); int d1 = (nFaces * real_segments.Count - 1) % counter_nodes + counter_nodes * (k); beam_mesh.Faces.AddFace(new MeshFace(a1, b1, c1, d1)); } } oExtrussion.Add(beam_mesh); } } // Assign output DA.SetDataList(0, oExtrussion); }
public override void SolveInstance(IGH_DataAccess DA, out string msg, out GH_RuntimeMessageLevel level) { msg = ""; level = GH_RuntimeMessageLevel.Blank; OnComponentLoaded(); // Input var inGH = new GH_RFEM(); var inGH2 = new List <GH_RFEM>(); var iMember = new RFMember(); var iCroSecs = new List <RFCroSec>(); // Output var oExtrussion = new List <Brep>(); // Register input parameters if (!DA.GetData(0, ref inGH)) { return; } iMember = (RFMember)inGH.Value; if (!DA.GetDataList(1, inGH2)) { return; } foreach (var cs in inGH2) { iCroSecs.Add((RFCroSec)cs.Value); } // Check input var cs_indeces = iCroSecs.Select(x => x.No); if (iMember.EndCrossSectionNo == 0) // In case of tension members, etc. { iMember.EndCrossSectionNo = iMember.StartCrossSectionNo; } if (!(cs_indeces.Contains(iMember.StartCrossSectionNo)) || (!(cs_indeces.Contains(iMember.EndCrossSectionNo)))) { level = GH_RuntimeMessageLevel.Warning; msg = $"Provide cross sections for member No {iMember.No}."; return; } // Get base geometry var crosecs1 = iCroSecs.Where(x => x.No == iMember.StartCrossSectionNo).ToList()[0].Shape; var crosecs2 = iCroSecs.Where(x => x.No == iMember.EndCrossSectionNo).ToList()[0].Shape; var baseline = iMember.BaseLine.ToCurve(); // Check geometry if ((crosecs1.Sum(x => x.SpanCount) != crosecs2.Sum(x => x.SpanCount)) || (crosecs1.Count != crosecs2.Count)) { level = GH_RuntimeMessageLevel.Warning; msg = $"Provide similar cross sections for member No {iMember.No}."; return; } // Generate tween curves - still on the origin! List <Curve> segments; int nCroSecsInter; length_segment = Math.Max(length_segment, 0.05); // Check minimum vlaue if (baseline.Degree <= 1) { nCroSecsInter = 2; } else { nCroSecsInter = Math.Max((int)(baseline.GetLength() / length_segment), 2); } var loft_crvs = Component_ExtrudeMembers.GenerateCroSecs(baseline, crosecs1, crosecs2, nCroSecsInter, 0.001, 0.001, out segments); // Orient cross sections loft_crvs = Component_ExtrudeMembers.OrientCroSecs(loft_crvs, segments, nCroSecsInter, iMember.Frames[0], crosecs1.Count); // Extrude members for (int i = 0; i < segments.Count; i++) { for (int j = 0; j < crosecs1.Count; j++) { oExtrussion.AddRange(Brep.CreateFromLoft(loft_crvs[i][j], Point3d.Unset, Point3d.Unset, LoftType.Normal, false)); } } // Assign output DA.SetDataList(0, oExtrussion); }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object can be used to retrieve data from input parameters and /// to store data in output parameters.</param> protected override void SolveInstance(IGH_DataAccess DA, EvaluationUnit unit) { // RFEM variables var modelName = ""; IModel model = null; IModelData data = null; //Additional variables var dicMat = new Dictionary <int, Material>(); var dicMass = new Dictionary <int, List <double> >(); var dicVol = new Dictionary <int, List <double> >(); var dicGeo = new Dictionary <int, List <Brep> >(); // Input var msg = ""; var msgs = new List <string>(); var run = false; DA.GetData(0, ref run); if (run) { if (!DA.GetData(1, ref modelName)) { Component_GetData.ConnectRFEM(ref model, ref data); } else { Component_GetData.ConnectRFEM(modelName, ref model, ref data); } _materials.Clear(); _massTree.Clear(); _volumeTree.Clear(); _brepTree.Clear(); try { // Get Surfaces var sfcs = Component_GetData.GetRFSurfaces(data.GetSurfaces().ToList(), data); foreach (var sfc in sfcs) { // Add material to dictionary if (!dicMat.ContainsKey(sfc.MaterialNo)) { dicMat.Add(sfc.MaterialNo, data.GetMaterial(sfc.MaterialNo, ItemAt.AtNo).GetData()); dicMass.Add(sfc.MaterialNo, new List <double>()); dicVol.Add(sfc.MaterialNo, new List <double>()); dicGeo.Add(sfc.MaterialNo, new List <Brep>()); } // Add mass to output list dicVol[sfc.MaterialNo].Add(sfc.Area * sfc.Thickness); dicMass[sfc.MaterialNo].Add(sfc.Area * sfc.Thickness * dicMat[sfc.MaterialNo].SpecificWeight / 10.0); // Add Geometry to output list dicGeo[sfc.MaterialNo].Add(sfc.ToBrep()); } // Get Members var members = Component_GetData.GetRFMembers(data.GetMembers().ToList(), data); var crosecs = Component_GetData.GetRFCroSecs(data.GetCrossSections().ToList(), model, ref msgs); var cs_indeces = crosecs.Select(x => x.No).ToList(); foreach (var member in members) { var mat_index = crosecs.Where(x => x.No == member.StartCrossSectionNo).ToList()[0].MatNo; // Add material to dictionary if (!dicMat.ContainsKey(mat_index)) { dicMat.Add(mat_index, data.GetMaterial(mat_index, ItemAt.AtNo).GetData()); dicMass.Add(mat_index, new List <double>()); dicVol.Add(mat_index, new List <double>()); dicGeo.Add(mat_index, new List <Brep>()); } // Add mass to output list if (member.EndCrossSectionNo == 0) // In case of tension members, etc. { member.EndCrossSectionNo = member.StartCrossSectionNo; } if (!(cs_indeces.Contains(member.StartCrossSectionNo)) || (!(cs_indeces.Contains(member.EndCrossSectionNo)))) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, $"Provide cross sections for member No {member.No}."); continue; } var startCroSec = crosecs[cs_indeces.IndexOf(member.StartCrossSectionNo)]; var endCroSec = crosecs[cs_indeces.IndexOf(member.EndCrossSectionNo)]; var volume = (startCroSec.A + endCroSec.A) / 2 * member.Length; dicVol[mat_index].Add(volume); dicMass[mat_index].Add(member.Weight); // Add Geometry to output list var memberShape = Component_ExtrudeMembers.ExtrudeMembersToBrep(member, crosecs, member.Length / 8.0, out msg); if (memberShape == null) { dicGeo[mat_index].Add(null); } else { dicGeo[mat_index].Add(memberShape[0]); } } // Prepare Output var matSorted = dicMat.Values.OrderBy(x => x.No).ToList(); _materials = matSorted.Select(x => x.Description).ToList(); for (int i = 0; i < matSorted.Count; i++) { var path = new GH_Path(i); _volumeTree.EnsurePath(path); _volumeTree.Branch(path).AddRange(dicVol[matSorted[i].No]); _massTree.EnsurePath(path); _massTree.Branch(path).AddRange(dicMass[matSorted[i].No]); _brepTree.EnsurePath(path); _brepTree.Branch(path).AddRange(dicGeo[matSorted[i].No]); } } catch (Exception ex) { Component_GetData.DisconnectRFEM(ref model, ref data); _materials.Clear(); _massTree.Clear(); _volumeTree.Clear(); _brepTree.Clear(); throw ex; } Component_GetData.DisconnectRFEM(ref model, ref data); if (msgs.Count > 0) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, String.Join(System.Environment.NewLine, msg.ToArray())); } if (msg != "") { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, msg); } } DA.SetDataList(0, _materials); DA.SetDataTree(1, _brepTree); DA.SetDataTree(2, _massTree); DA.SetDataTree(3, _volumeTree); }