private void AppendCouplingInformation(StringBuilder sb, IGS_StructuralElement se, Dictionary <int, List <GH_GeometricGoo <GH_CouplingStruc> > > map) { if (se.Id > 0) { List <GH_GeometricGoo <GH_CouplingStruc> > involvedCouplings; if (map.TryGetValue(se.Id, out involvedCouplings)) { if (se is GS_StructuralLine) { AppendCouplingInformation_L(sb, involvedCouplings); } else if (se is GS_StructuralPoint) { AppendCouplingInformation_P(sb, involvedCouplings); } } } }
protected override void SolveInstance(IGH_DataAccess da) { bool initSystem = da.GetData <bool>(1); bool mesh = da.GetData <bool>(2); double hmin = da.GetData <double>(3); double tolg = da.GetData <double>(4); int idBorder = da.GetData <int>(5); int gdiv = da.GetData <int>(6); string ctrl = da.GetData <string>(7); string text = da.GetData <string>(8); var structural_elements_pre = new List <IGS_StructuralElement>(); List <GH_GeometricGoo <GH_CouplingStruc> > coupling_information = new List <GH_GeometricGoo <GH_CouplingStruc> >(); var axis_elements = new List <IGH_Axis>(); foreach (var it in da.GetDataList <IGH_Goo>(0)) { if (it is IGS_StructuralElement) { structural_elements_pre.Add(it as IGS_StructuralElement); } else if (it is IGH_Axis) { axis_elements.Add(it as IGH_Axis); } else if (it is GH_GeometricGoo <GH_CouplingStruc> ) { coupling_information.Add(it as GH_GeometricGoo <GH_CouplingStruc>); } else { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Data conversion failed from " + it.TypeName + " to IGS_StructuralElement."); } } // merge Structural Points at same Location according tolg and adjust references in coupling-like elements to point to new merged structural points var structural_elements_merged = new List <IGS_StructuralElement>(); var set_references_back_A = new List <(GH_GeometricGoo <GH_CouplingStruc>, GS_StructuralPoint)>(); var set_references_back_B = new List <(GH_GeometricGoo <GH_CouplingStruc>, GS_StructuralPoint)>(); mergeStructuralPoints(coupling_information, structural_elements_pre, tolg, structural_elements_merged, set_references_back_A, set_references_back_B); // setup data for id distribution and pre-processing var structural_elements = new List <IGS_StructuralElement>(); int id = idBorder; SortedSet <int> idSetPoint = new SortedSet <int>(); SortedSet <int> idSetLine = new SortedSet <int>(); // assign auto generated IDs temporarily (just for couplings) and write "Id=0" back at end of this method List <IGS_StructuralElement> write_id_back_to_zero = new List <IGS_StructuralElement>(); //id=assignIDs(id, idSet, structural_elements, write_id_back_to_zero); id = addUnknownElementsFromCouplings(id, idSetPoint, idSetLine, structural_elements, coupling_information, write_id_back_to_zero); addStructuralElements(idSetPoint, idSetLine, structural_elements, structural_elements_merged); // build hashmap for couplings: for one id (key), you get a list of couplings in which this structural element is involved Dictionary <int, List <GH_GeometricGoo <GH_CouplingStruc> > > couplingMapPoint = buildCouplingMap(coupling_information, false); Dictionary <int, List <GH_GeometricGoo <GH_CouplingStruc> > > couplingMapLine = buildCouplingMap(coupling_information, true); // pre-process axis elements and perform check for structural lines if they lie on axis var gaxDefinitions = new StringBuilder(); var axisAdded = getAxisDefinitions(axis_elements, gaxDefinitions); var slnReferences = calcSlnReferences(structural_elements, axisAdded, tolg, write_id_back_to_zero, ref id); // init boundingbox _boundingBox = new BoundingBox(); if (structural_elements.Count > 0) { IGS_StructuralElement se = structural_elements[0]; if (se is GS_StructuralPoint) { _boundingBox = (se as GS_StructuralPoint).Boundingbox; } else if (se is GS_StructuralLine) { _boundingBox = (se as GS_StructuralLine).Boundingbox; } else if (se is GS_StructuralArea) { _boundingBox = (se as GS_StructuralArea).Boundingbox; } } // write teddy var sb = new StringBuilder(); sb.AppendLine("+PROG SOFIMSHC"); sb.AppendLine("HEAD"); sb.AppendLine("PAGE UNII 0"); // export always in SOFiSTiK database units if (initSystem) { sb.AppendLine("SYST 3D GDIR NEGZ GDIV " + gdiv); } //sb.AppendLine("SYST 3D GDIR NEGZ GDIV -1000"); else { sb.AppendLine("SYST REST"); } sb.AppendFormat("CTRL TOLG {0:F6}\n", tolg); if (mesh) { sb.AppendLine("CTRL MESH 1"); sb.AppendFormat("CTRL HMIN {0}\n", hmin != 0.0 ? string.Format("{0:F4}", hmin) : "-"); } // add control string if (!string.IsNullOrEmpty(ctrl)) { sb.Append(ctrl); } sb.AppendLine(); // write axis elements sb.Append(gaxDefinitions.ToString()); // write structural elements foreach (var se in structural_elements) { // write structural points if (se is GS_StructuralPoint) { var spt = se as GS_StructuralPoint; Point3d p = spt.Value.Location; _boundingBox.Union(spt.Boundingbox); string id_string = se.Id > 0 ? se.Id.ToString() : "-"; sb.AppendFormat("SPT {0} X {1:F8} {2:F8} {3:F8}", id_string, p.X, p.Y, p.Z); if (spt.DirectionLocalX.Length > 1.0E-8) { sb.AppendFormat(" SX {0:F6} {1:F6} {2:F6}", spt.DirectionLocalX.X, spt.DirectionLocalX.Y, spt.DirectionLocalX.Z); } if (spt.DirectionLocalZ.Length > 1.0E-8) { sb.AppendFormat(" NX {0:F6} {1:F6} {2:F6}", spt.DirectionLocalZ.X, spt.DirectionLocalZ.Y, spt.DirectionLocalZ.Z); } if (string.IsNullOrWhiteSpace(spt.FixLiteral) == false) { sb.AppendFormat(" FIX {0}", spt.FixLiteral); } if (string.IsNullOrWhiteSpace(spt.UserText) == false) { sb.AppendFormat(" {0}", spt.UserText); } sb.AppendLine(); AppendCouplingInformation(sb, se, couplingMapPoint); } // write structural lines else if (se is GS_StructuralLine) { var sln = se as GS_StructuralLine; _boundingBox.Union(sln.Boundingbox); string id_string = se.Id > 0 ? se.Id.ToString() : "-"; string id_group = sln.GroupId > 0 ? sln.GroupId.ToString() : "-"; string id_section = "-"; if (sln.SectionIdStart > 0) { if (sln.SectionIdEnd == 0 || sln.SectionIdEnd == sln.SectionIdStart) { id_section = sln.SectionIdStart.ToString(); } else { id_section = string.Format("\"{0}.{1}\"", sln.SectionIdStart, sln.SectionIdEnd); } } sb.AppendFormat("SLN {0} GRP {1} SNO {2}", id_string, id_group, id_section); if (sln.DirectionLocalZ.Length > 1.0E-8) { sb.AppendFormat(" DRX {0:F6} {1:F6} {2:F6}", sln.DirectionLocalZ.X, sln.DirectionLocalZ.Y, sln.DirectionLocalZ.Z); } else { sb.AppendFormat(" DRX {0:F6} {1:F6} {2:F6}", 0, 0, -1); } if (string.IsNullOrWhiteSpace(sln.FixLiteral) == false) { sb.AppendFormat(" FIX {0}", sln.FixLiteral); } sb.AppendFormat(" STYP {0}", sln.ElementType); if (Math.Abs(sln.ElementSize) > 1.0E-8) { sb.AppendFormat(" SDIV {0}", sln.ElementSize); } if (string.IsNullOrWhiteSpace(sln.UserText) == false) { sb.AppendFormat(" {0}", sln.UserText); } if (slnReferences.TryGetValue(sln.Id, out var refs)) { sb.AppendFormat(" REF '" + refs.Item1 + "' NPA " + refs.Item2 + " NPE " + refs.Item3); sb.AppendLine(); } else { sb.AppendLine(); AppendCurveGeometry(sb, sln.Value); } AppendCouplingInformation(sb, se, couplingMapLine); } // write structural areas else if (se is GS_StructuralArea) { var sar = se as GS_StructuralArea; var brep = sar.Value; _boundingBox.Union(sar.Boundingbox); string id_string = se.Id > 0 ? se.Id.ToString() : "-"; string grp_string = sar.GroupId > 0 ? sar.GroupId.ToString() : "-"; string thk_string = sar.Thickness.ToString("F6"); // some preparations brep.CullUnusedSurfaces(); brep.CullUnusedFaces(); brep.CullUnusedEdges(); // loop over all faces within the brep foreach (var fc in brep.Faces) { // checks and preparations fc.ShrinkFace(BrepFace.ShrinkDisableSide.ShrinkAllSides); if (fc.IsClosed(0) || fc.IsClosed(1)) { this.AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "A given Surface is closed in one direction.\nSuch surfaces cannot be handled by SOFiMSHC and need to be split."); } // write SAR header sb.AppendLine(); sb.AppendFormat("SAR {0} GRP {1} T {2}", id_string, grp_string, thk_string); id_string = string.Empty; // set only the 1st time if (sar.MaterialId > 0) { sb.AppendFormat(" MNO {0}", sar.MaterialId.ToString()); } if (sar.ReinforcementId > 0) { sb.AppendFormat(" MRF {0}", sar.ReinforcementId.ToString()); } if (sar.DirectionLocalX.Length > 1.0E-8) { sb.AppendFormat(" DRX {0:F6} {1:F6} {2:F6}", sar.DirectionLocalX.X, sar.DirectionLocalX.Y, sar.DirectionLocalX.Z); } if (!sar.Alignment.Equals("CENT")) { sb.AppendFormat(" QREF {0}", sar.Alignment); } if (!sar.MeshOptions.Equals("AUTO")) { sb.AppendFormat(" MCTL {0}", sar.MeshOptions); } if (Math.Abs(sar.ElementSize) > 1.0E-8) { sb.AppendFormat(" H1 {0}", sar.ElementSize); } if (string.IsNullOrWhiteSpace(sar.UserText) == false) { sb.AppendFormat(" {0}", sar.UserText); } sb.AppendLine(); // outer boundary AppendSurfaceBoundary(sb, fc); // write geometry if (fc.IsPlanar() == false) { AppendSurfaceGeometry(sb, fc.ToNurbsSurface()); } } } else { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Unsupported type encountered: " + se.TypeName); } } sb.AppendLine(); // add additional text if (!string.IsNullOrEmpty(text)) { sb.Append(text); } sb.AppendLine(); sb.AppendLine("END"); foreach (IGS_StructuralElement se in write_id_back_to_zero) { se.Id = 0; } foreach (var tp in set_references_back_A) { tp.Item1.Value.Reference_A = tp.Item2; } foreach (var tp in set_references_back_B) { tp.Item1.Value.Reference_B = tp.Item2; } da.SetData(0, sb.ToString()); }