public StringBuilder Export(string pipeLineAbbreviation, HashSet <Element> elements, Document document) { Document doc = document; string key = pipeLineAbbreviation; //The list of fittings, sorted by TYPE then SKEY IList <Element> fittingsList = elements. OrderBy(e => e.get_Parameter(new plst().PCF_ELEM_TYPE.Guid).AsString()). ThenBy(e => e.get_Parameter(new plst().PCF_ELEM_SKEY.Guid).AsString()).ToList(); StringBuilder sbFittings = new StringBuilder(); foreach (Element element in fittingsList) { //If the Element Type field is empty -> ignore the component if (string.IsNullOrEmpty(element.get_Parameter(new plst().PCF_ELEM_TYPE.Guid).AsString())) { continue; } sbFittings.AppendLine(element.get_Parameter(new plst().PCF_ELEM_TYPE.Guid).AsString()); sbFittings.AppendLine(" COMPONENT-IDENTIFIER " + element.get_Parameter(new plst().PCF_ELEM_COMPID.Guid).AsInteger()); //Write Plant3DIso entries if turned on if (iv.ExportToPlant3DIso) { sbFittings.Append(Composer.Plant3DIsoWriter(element, doc)); } //Cast the elements gathered by the collector to FamilyInstances FamilyInstance familyInstance = (FamilyInstance)element; Options options = new Options(); //MEPModel of the elements is accessed MEPModel mepmodel = familyInstance.MEPModel; //Get connector set for the element ConnectorSet connectorSet = mepmodel.ConnectorManager.Connectors; //Switch to different element type configurations switch (element.get_Parameter(new plst().PCF_ELEM_TYPE.Guid).AsString()) { case ("ELBOW"): Connector primaryConnector = null; Connector secondaryConnector = null; //Process endpoints of the component foreach (Connector connector in connectorSet) { if (connector.GetMEPConnectorInfo().IsPrimary) { primaryConnector = connector; } if (connector.GetMEPConnectorInfo().IsSecondary) { secondaryConnector = connector; } } sbFittings.Append(EndWriter.WriteEP1(element, primaryConnector)); sbFittings.Append(EndWriter.WriteEP2(element, secondaryConnector)); sbFittings.Append(EndWriter.WriteCP(familyInstance)); sbFittings.Append(" ANGLE "); sbFittings.Append((Conversion.RadianToDegree(element.LookupParameter("Angle").AsDouble()) * 100).ToString("0")); sbFittings.AppendLine(); break; case ("TEE"): //Sort connectors to primary, secondary and none primaryConnector = null; secondaryConnector = null; Connector tertiaryConnector = null; foreach (Connector connector in connectorSet) { #region Debug //Debug //sbFittings.Append(connector.GetMEPConnectorInfo().IsPrimary); //sbFittings.Append(connector.GetMEPConnectorInfo().IsSecondary); //sbFittings.Append((connector.GetMEPConnectorInfo().IsPrimary == false) & (connector.GetMEPConnectorInfo().IsSecondary == false)); //sbFittings.AppendLine(); #endregion if (connector.GetMEPConnectorInfo().IsPrimary) { primaryConnector = connector; } if (connector.GetMEPConnectorInfo().IsSecondary) { secondaryConnector = connector; } if ((connector.GetMEPConnectorInfo().IsPrimary == false) && (connector.GetMEPConnectorInfo().IsSecondary == false)) { tertiaryConnector = connector; } } //Process endpoints of the component sbFittings.Append(EndWriter.WriteEP1(element, primaryConnector)); sbFittings.Append(EndWriter.WriteEP2(element, secondaryConnector)); sbFittings.Append(EndWriter.WriteCP(familyInstance)); sbFittings.Append(EndWriter.WriteBP1(element, tertiaryConnector)); break; case ("REDUCER-CONCENTRIC"): //Process endpoints of the component primaryConnector = null; secondaryConnector = null; //Process endpoints of the component foreach (Connector connector in connectorSet) { if (connector.GetMEPConnectorInfo().IsPrimary) { primaryConnector = connector; } if (connector.GetMEPConnectorInfo().IsSecondary) { secondaryConnector = connector; } } sbFittings.Append(EndWriter.WriteEP1(element, primaryConnector)); sbFittings.Append(EndWriter.WriteEP2(element, secondaryConnector)); break; case ("REDUCER-ECCENTRIC"): goto case ("REDUCER-CONCENTRIC"); case ("FLANGE"): primaryConnector = null; secondaryConnector = null; tertiaryConnector = null; foreach (Connector connector in connectorSet) { if (connector.GetMEPConnectorInfo().IsPrimary) { primaryConnector = connector; } if (connector.GetMEPConnectorInfo().IsSecondary) { secondaryConnector = connector; } } //Process endpoints of the component //Secondary goes first because it is the weld neck point and the primary second because it is the flanged end //(dunno if it is significant); sbFittings.Append(EndWriter.WriteEP1(element, secondaryConnector)); sbFittings.Append(EndWriter.WriteEP2(element, primaryConnector)); break; case ("FLANGE-BLIND"): primaryConnector = null; foreach (Connector connector in connectorSet) { primaryConnector = connector; } //Connector information extraction sbFittings.Append(EndWriter.WriteEP1(element, primaryConnector)); XYZ endPointOriginFlangeBlind = primaryConnector.Origin; double connectorSizeFlangeBlind = primaryConnector.Radius; //Analyses the geometry to obtain a point opposite the main connector. //Extraction of the direction of the connector and reversing it XYZ reverseConnectorVector = -primaryConnector.CoordinateSystem.BasisZ; Line detectorLine = Line.CreateUnbound(endPointOriginFlangeBlind, reverseConnectorVector); //Begin geometry analysis GeometryElement geometryElement = familyInstance.get_Geometry(options); //Prepare resulting point XYZ endPointAnalyzed = null; foreach (GeometryObject geometry in geometryElement) { GeometryInstance instance = geometry as GeometryInstance; if (null != instance) { foreach (GeometryObject instObj in instance.GetInstanceGeometry()) { Solid solid = instObj as Solid; if (null == solid || 0 == solid.Faces.Size || 0 == solid.Edges.Size) { continue; } // Get the faces foreach (Face face in solid.Faces) { IntersectionResultArray results = null; XYZ intersection = null; SetComparisonResult result = face.Intersect(detectorLine, out results); if (result == SetComparisonResult.Overlap) { intersection = results.get_Item(0).XYZPoint; if (intersection.IsAlmostEqualTo(endPointOriginFlangeBlind) == false) { endPointAnalyzed = intersection; } } } } } } sbFittings.Append(EndWriter.WriteEP2(element, endPointAnalyzed, connectorSizeFlangeBlind)); break; case ("CAP"): goto case ("FLANGE-BLIND"); case ("OLET"): primaryConnector = null; secondaryConnector = null; foreach (Connector connector in connectorSet) { if (connector.GetMEPConnectorInfo().IsPrimary) { primaryConnector = connector; } if (connector.GetMEPConnectorInfo().IsSecondary) { secondaryConnector = connector; } } XYZ endPointOriginOletPrimary = primaryConnector.Origin; XYZ endPointOriginOletSecondary = secondaryConnector.Origin; //get reference elements ConnectorSet refConnectors = primaryConnector.AllRefs; Element refElement = null; foreach (Connector c in refConnectors) { refElement = c.Owner; } Pipe refPipe = (Pipe)refElement; //Get connector set for the pipes ConnectorSet refConnectorSet = refPipe.ConnectorManager.Connectors; //Filter out non-end types of connectors IEnumerable <Connector> connectorEnd = from Connector connector in refConnectorSet where connector.ConnectorType.ToString() == "End" select connector; //Following code is ported from my python solution in Dynamo. //The olet geometry is analyzed with congruent rectangles to find the connection point on the pipe even for angled olets. XYZ B = endPointOriginOletPrimary; XYZ D = endPointOriginOletSecondary; XYZ pipeEnd1 = connectorEnd.First().Origin; XYZ pipeEnd2 = connectorEnd.Last().Origin; XYZ BDvector = D - B; XYZ ABvector = pipeEnd1 - pipeEnd2; double angle = Conversion.RadianToDegree(ABvector.AngleTo(BDvector)); if (angle > 90) { ABvector = -ABvector; angle = Conversion.RadianToDegree(ABvector.AngleTo(BDvector)); } Line refsLine = Line.CreateBound(pipeEnd1, pipeEnd2); XYZ C = refsLine.Project(B).XYZPoint; double L3 = B.DistanceTo(C); XYZ E = refsLine.Project(D).XYZPoint; double L4 = D.DistanceTo(E); double ratio = L4 / L3; double L1 = E.DistanceTo(C); double L5 = L1 / (ratio - 1); XYZ A; if (angle < 89) { XYZ ECvector = C - E; ECvector = ECvector.Normalize(); double L = L1 + L5; ECvector = ECvector.Multiply(L); A = E.Add(ECvector); #region Debug //Debug //Place family instance at points to debug the alorithm //StructuralType strType = (StructuralType)4; //FamilySymbol familySymbol = null; //FilteredElementCollector collector = new FilteredElementCollector(doc); //IEnumerable<Element> collection = collector.OfClass(typeof(FamilySymbol)).ToElements(); //FamilySymbol marker = null; //foreach (Element e in collection) //{ // familySymbol = e as FamilySymbol; // if (null != familySymbol.Category) // { // if ("Structural Columns" == familySymbol.Category.Name) // { // break; // } // } //} //if (null != familySymbol) //{ // foreach (Element e in collection) // { // familySymbol = e as FamilySymbol; // if (familySymbol.FamilyName == "Marker") // { // marker = familySymbol; // Transaction trans = new Transaction(doc, "Place point markers"); // trans.Start(); // doc.Create.NewFamilyInstance(A, marker, strType); // doc.Create.NewFamilyInstance(B, marker, strType); // doc.Create.NewFamilyInstance(C, marker, strType); // doc.Create.NewFamilyInstance(D, marker, strType); // doc.Create.NewFamilyInstance(E, marker, strType); // trans.Commit(); // } // } //} #endregion } else { A = E; } angle = Math.Round(angle * 100); sbFittings.Append(EndWriter.WriteCP(A)); sbFittings.Append(EndWriter.WriteBP1(element, secondaryConnector)); sbFittings.Append(" ANGLE "); sbFittings.Append(Conversion.AngleToPCF(angle)); sbFittings.AppendLine(); break; } Composer elemParameterComposer = new Composer(); sbFittings.Append(elemParameterComposer.ElemParameterWriter(element)); #region CII export if (iv.ExportToCII) { sbFittings.Append(Composer.CIIWriter(doc, key)); } #endregion sbFittings.Append(" UNIQUE-COMPONENT-IDENTIFIER "); sbFittings.Append(element.UniqueId); sbFittings.AppendLine(); } //// Clear the output file //File.WriteAllBytes(InputVars.OutputDirectoryFilePath + "Fittings.pcf", new byte[0]); //// Write to output file //using (StreamWriter w = File.AppendText(InputVars.OutputDirectoryFilePath + "Fittings.pcf")) //{ // w.Write(sbFittings); // w.Close(); //} return(sbFittings); }
public StringBuilder Export(string pipeLineAbbreviation, HashSet <Element> elements, Document document) { Document doc = document; string key = pipeLineAbbreviation; //The list of fittings, sorted by TYPE then SKEY IList <Element> fittingsList = elements. OrderBy(e => e.get_Parameter(new plst().PCF_ELEM_TYPE.Guid).AsString()). ThenBy(e => e.get_Parameter(new plst().PCF_ELEM_SKEY.Guid).AsString()).ToList(); StringBuilder sbFittings = new StringBuilder(); foreach (Element element in fittingsList) { sbFittings.AppendLine(element.get_Parameter(new plst().PCF_ELEM_TYPE.Guid).AsString()); sbFittings.AppendLine(" COMPONENT-IDENTIFIER " + element.get_Parameter(new plst().PCF_ELEM_COMPID.Guid).AsString()); if (element.get_Parameter(new plst().PCF_ELEM_SPEC.Guid).AsString() == "EXISTING-INCLUDE") { sbFittings.AppendLine(" STATUS DOTTED-UNDIMENSIONED"); sbFittings.AppendLine(" MATERIAL-LIST EXCLUDE"); } //Write Plant3DIso entries if turned on if (iv.ExportToIsogen) { sbFittings.Append(Composer.Plant3DIsoWriter(element, doc)); } //Cast the elements gathered by the collector to FamilyInstances FamilyInstance familyInstance = (FamilyInstance)element; Options options = new Options(); //Gather connectors of the element var cons = mp.GetConnectors(element); //Switch to different element type configurations switch (element.get_Parameter(new plst().PCF_ELEM_TYPE.Guid).AsString()) { case ("ELBOW"): sbFittings.Append(EndWriter.WriteEP1(element, cons.Primary)); sbFittings.Append(EndWriter.WriteEP2(element, cons.Secondary)); sbFittings.Append(EndWriter.WriteCP(familyInstance)); sbFittings.Append(" ANGLE "); Parameter par = element.LookupParameter("Angle"); if (par == null) { par = element.LookupParameter("angle"); } if (par == null) { throw new Exception($"Angle parameter on elbow {element.Id.IntegerValue} does not exist or is named differently!"); } sbFittings.Append((Conversion.RadianToDegree(par.AsDouble()) * 100).ToString("0")); sbFittings.AppendLine(); break; //case ("BEND"): // sbFittings.Append(EndWriter.WriteEP1(element, cons.Primary)); // sbFittings.Append(EndWriter.WriteEP2(element, cons.Secondary)); // sbFittings.Append(EndWriter.WriteCP(familyInstance)); // break; case ("TEE"): //Process endpoints of the component sbFittings.Append(EndWriter.WriteEP1(element, cons.Primary)); sbFittings.Append(EndWriter.WriteEP2(element, cons.Secondary)); sbFittings.Append(EndWriter.WriteCP(familyInstance)); sbFittings.Append(EndWriter.WriteBP1(element, cons.Tertiary)); break; case ("REDUCER-CONCENTRIC"): sbFittings.Append(EndWriter.WriteEP1(element, cons.Primary)); sbFittings.Append(EndWriter.WriteEP2(element, cons.Secondary)); break; case ("REDUCER-ECCENTRIC"): goto case ("REDUCER-CONCENTRIC"); case ("COUPLING"): goto case ("REDUCER-CONCENTRIC"); case ("FLANGE"): //Process endpoints of the component //Secondary goes first because it is the weld neck point and the primary second because it is the flanged end //(dunno if it is significant); It is not, it should be specified the type of end, BW, PL, FL etc. to work correctly. sbFittings.Append(EndWriter.WriteEP1(element, cons.Secondary)); sbFittings.Append(EndWriter.WriteEP2(element, cons.Primary)); break; case ("FLANGE-BLIND"): sbFittings.Append(EndWriter.WriteEP1(element, cons.Primary)); XYZ endPointOriginFlangeBlind = cons.Primary.Origin; double connectorSizeFlangeBlind = cons.Primary.Radius; //Analyses the geometry to obtain a point opposite the main connector. //Extraction of the direction of the connector and reversing it XYZ reverseConnectorVector = -cons.Primary.CoordinateSystem.BasisZ; Line detectorLine = Line.CreateBound(endPointOriginFlangeBlind, endPointOriginFlangeBlind + reverseConnectorVector * 10); //Begin geometry analysis GeometryElement geometryElement = familyInstance.get_Geometry(options); //Prepare resulting point XYZ endPointAnalyzed = null; foreach (GeometryObject geometry in geometryElement) { if (geometry is GeometryInstance instance) { foreach (GeometryObject instObj in instance.GetInstanceGeometry()) { Solid solid = instObj as Solid; if (null == solid || 0 == solid.Faces.Size || 0 == solid.Edges.Size) { continue; } // Get the faces foreach (Face face in solid.Faces) { IntersectionResultArray results = null; XYZ intersection = null; SetComparisonResult result = face.Intersect(detectorLine, out results); if (result == SetComparisonResult.Overlap) { intersection = results.get_Item(0).XYZPoint; if (intersection.IsAlmostEqualTo(endPointOriginFlangeBlind) == false) { endPointAnalyzed = intersection; } } } } } } sbFittings.Append(EndWriter.WriteEP2(element, endPointAnalyzed, connectorSizeFlangeBlind)); break; case ("CAP"): goto case ("FLANGE-BLIND"); case ("OLET"): XYZ endPointOriginOletPrimary = cons.Primary.Origin; XYZ endPointOriginOletSecondary = cons.Secondary.Origin; //get reference elements Pipe refPipe = null; var refCons = mp.GetAllConnectorsFromConnectorSet(cons.Primary.AllRefs); Connector refCon = refCons.Where(x => x.Owner.IsType <Pipe>()).FirstOrDefault(); if (refCon == null) { //Find the target pipe var filter = new ElementClassFilter(typeof(Pipe)); var view3D = Shared.Filter.Get3DView(doc); var refIntersect = new ReferenceIntersector(filter, FindReferenceTarget.Element, view3D); ReferenceWithContext rwc = refIntersect.FindNearest(cons.Primary.Origin, cons.Primary.CoordinateSystem.BasisZ); var refId = rwc.GetReference().ElementId; refPipe = (Pipe)doc.GetElement(refId); if (refPipe == null) { throw new Exception($"Olet {element.Id.IntegerValue} cannot find a reference Pipe!"); } } else { refPipe = (Pipe)refCon.Owner; } Cons refPipeCons = mp.GetConnectors(refPipe); //Following code is ported from my python solution in Dynamo. //The olet geometry is analyzed with congruent rectangles to find the connection point on the pipe even for angled olets. XYZ B = endPointOriginOletPrimary; XYZ D = endPointOriginOletSecondary; XYZ pipeEnd1 = refPipeCons.Primary.Origin; XYZ pipeEnd2 = refPipeCons.Secondary.Origin; XYZ BDvector = D - B; XYZ ABvector = pipeEnd1 - pipeEnd2; double angle = Conversion.RadianToDegree(ABvector.AngleTo(BDvector)); if (angle > 90) { ABvector = -ABvector; angle = Conversion.RadianToDegree(ABvector.AngleTo(BDvector)); } Line refsLine = Line.CreateBound(pipeEnd1, pipeEnd2); XYZ C = refsLine.Project(B).XYZPoint; double L3 = B.DistanceTo(C); XYZ E = refsLine.Project(D).XYZPoint; double L4 = D.DistanceTo(E); double ratio = L4 / L3; double L1 = E.DistanceTo(C); double L5 = L1 / (ratio - 1); XYZ A; if (angle < 89) { XYZ ECvector = C - E; ECvector = ECvector.Normalize(); double L = L1 + L5; ECvector = ECvector.Multiply(L); A = E.Add(ECvector); #region Debug //Debug //Place family instance at points to debug the alorithm //StructuralType strType = (StructuralType)4; //FamilySymbol familySymbol = null; //FilteredElementCollector collector = new FilteredElementCollector(doc); //IEnumerable<Element> collection = collector.OfClass(typeof(FamilySymbol)).ToElements(); //FamilySymbol marker = null; //foreach (Element e in collection) //{ // familySymbol = e as FamilySymbol; // if (null != familySymbol.Category) // { // if ("Structural Columns" == familySymbol.Category.Name) // { // break; // } // } //} //if (null != familySymbol) //{ // foreach (Element e in collection) // { // familySymbol = e as FamilySymbol; // if (familySymbol.FamilyName == "Marker") // { // marker = familySymbol; // Transaction trans = new Transaction(doc, "Place point markers"); // trans.Start(); // doc.Create.NewFamilyInstance(A, marker, strType); // doc.Create.NewFamilyInstance(B, marker, strType); // doc.Create.NewFamilyInstance(C, marker, strType); // doc.Create.NewFamilyInstance(D, marker, strType); // doc.Create.NewFamilyInstance(E, marker, strType); // trans.Commit(); // } // } //} #endregion } else { A = E; } angle = Math.Round(angle * 100); sbFittings.Append(EndWriter.WriteCP(A)); sbFittings.Append(EndWriter.WriteBP1(element, cons.Secondary)); sbFittings.Append(" ANGLE "); sbFittings.Append(Conversion.AngleToPCF(angle)); sbFittings.AppendLine(); break; } Composer elemParameterComposer = new Composer(); sbFittings.Append(elemParameterComposer.ElemParameterWriter(element)); #region CII export if (iv.ExportToCII) { sbFittings.Append(Composer.CIIWriter(doc, key)); } #endregion sbFittings.Append(" UNIQUE-COMPONENT-IDENTIFIER "); sbFittings.Append(element.UniqueId); sbFittings.AppendLine(); } //// Clear the output file //File.WriteAllBytes(InputVars.OutputDirectoryFilePath + "Fittings.pcf", new byte[0]); //// Write to output file //using (StreamWriter w = File.AppendText(InputVars.OutputDirectoryFilePath + "Fittings.pcf")) //{ // w.Write(sbFittings); // w.Close(); //} return(sbFittings); }
public StringBuilder Export(string pipeLineAbbreviation, HashSet <Element> elements, Document document) { Document doc = document; string key = pipeLineAbbreviation; plst pList = new plst(); //paramList = new plst(); //The list of fittings, sorted by TYPE then SKEY IList <Element> accessoriesList = elements. OrderBy(e => e.get_Parameter(pList.PCF_ELEM_TYPE.Guid).AsString()). ThenBy(e => e.get_Parameter(pList.PCF_ELEM_SKEY.Guid).AsString()).ToList(); StringBuilder sbAccessories = new StringBuilder(); //This is a workaround to try to determine what element caused an exception Element element = null; try { foreach (Element Element in accessoriesList) { //This is a workaround to try to determine what element caused an exception element = Element; //If the Element Type field is empty -> ignore the component if (string.IsNullOrEmpty(element.get_Parameter(pList.PCF_ELEM_TYPE.Guid).AsString())) { continue; } sbAccessories.AppendLine(element.get_Parameter(new plst().PCF_ELEM_TYPE.Guid).AsString()); sbAccessories.AppendLine(" COMPONENT-IDENTIFIER " + element.get_Parameter(new plst().PCF_ELEM_COMPID.Guid).AsInteger()); //Write Plant3DIso entries if turned on if (InputVars.ExportToPlant3DIso) { sbAccessories.Append(Composer.Plant3DIsoWriter(element, doc)); } //Cast the elements gathered by the collector to FamilyInstances FamilyInstance familyInstance = (FamilyInstance)element; Options options = new Options(); //MEPModel of the elements is accessed MEPModel mepmodel = familyInstance.MEPModel; //Get connector set for the element ConnectorSet connectorSet = mepmodel.ConnectorManager.Connectors; //Switch to different element type configurations switch (element.get_Parameter(pList.PCF_ELEM_TYPE.Guid).AsString()) { case ("FILTER"): //Process endpoints of the component Connector primaryConnector = null; Connector secondaryConnector = null; foreach (Connector connector in connectorSet) { if (connector.GetMEPConnectorInfo().IsPrimary) { primaryConnector = connector; } if (connector.GetMEPConnectorInfo().IsSecondary) { secondaryConnector = connector; } } //Process endpoints of the component sbAccessories.Append(EndWriter.WriteEP1(element, primaryConnector)); sbAccessories.Append(EndWriter.WriteEP2(element, secondaryConnector)); break; case ("INSTRUMENT"): //Process endpoints of the component primaryConnector = null; secondaryConnector = null; foreach (Connector connector in connectorSet) { if (connector.GetMEPConnectorInfo().IsPrimary) { primaryConnector = connector; } if (connector.GetMEPConnectorInfo().IsSecondary) { secondaryConnector = connector; } } //Process endpoints of the component sbAccessories.Append(EndWriter.WriteEP1(element, primaryConnector)); sbAccessories.Append(EndWriter.WriteEP2(element, secondaryConnector)); sbAccessories.Append(EndWriter.WriteCP(familyInstance)); break; case ("VALVE"): goto case ("INSTRUMENT"); case ("VALVE-ANGLE"): //Process endpoints of the component primaryConnector = null; secondaryConnector = null; foreach (Connector connector in connectorSet) { if (connector.GetMEPConnectorInfo().IsPrimary) { primaryConnector = connector; } if (connector.GetMEPConnectorInfo().IsSecondary) { secondaryConnector = connector; } } //Process endpoints of the component sbAccessories.Append(EndWriter.WriteEP1(element, primaryConnector)); sbAccessories.Append(EndWriter.WriteEP2(element, secondaryConnector)); //The centre point is obtained by creating an unbound line from primary connector and projecting the secondary point on the line. XYZ reverseConnectorVector = -primaryConnector.CoordinateSystem.BasisZ; Line primaryLine = Line.CreateUnbound(primaryConnector.Origin, reverseConnectorVector); XYZ centrePoint = primaryLine.Project(secondaryConnector.Origin).XYZPoint; sbAccessories.Append(EndWriter.WriteCP(centrePoint)); break; case ("INSTRUMENT-DIAL"): ////Process endpoints of the component //primaryConnector = null; //foreach (Connector connector in connectorSet) primaryConnector = connector; ////Process endpoints of the component //sbAccessories.Append(EndWriter.WriteEP1(element, primaryConnector)); ////The co-ords point is obtained by creating an unbound line from primary connector and taking an arbitrary point a long the line. //reverseConnectorVector = -primaryConnector.CoordinateSystem.BasisZ.Multiply(0.656167979); //XYZ coOrdsPoint = primaryConnector.Origin; //Transform pointTranslation; //pointTranslation = Transform.CreateTranslation(reverseConnectorVector); //coOrdsPoint = pointTranslation.OfPoint(coOrdsPoint); primaryConnector = null; foreach (Connector connector in connectorSet) { primaryConnector = connector; } //Connector information extraction sbAccessories.Append(EndWriter.WriteEP1(element, primaryConnector)); XYZ primConOrigin = primaryConnector.Origin; //Analyses the geometry to obtain a point opposite the main connector. //Extraction of the direction of the connector and reversing it reverseConnectorVector = -primaryConnector.CoordinateSystem.BasisZ; Line detectorLine = Line.CreateUnbound(primConOrigin, reverseConnectorVector); //Begin geometry analysis GeometryElement geometryElement = familyInstance.get_Geometry(options); //Prepare resulting point XYZ endPointAnalyzed = null; foreach (GeometryObject geometry in geometryElement) { GeometryInstance instance = geometry as GeometryInstance; if (null == instance) { continue; } foreach (GeometryObject instObj in instance.GetInstanceGeometry()) { Solid solid = instObj as Solid; if (null == solid || 0 == solid.Faces.Size || 0 == solid.Edges.Size) { continue; } foreach (Face face in solid.Faces) { IntersectionResultArray results = null; XYZ intersection = null; SetComparisonResult result = face.Intersect(detectorLine, out results); if (result != SetComparisonResult.Overlap) { continue; } intersection = results.get_Item(0).XYZPoint; if (intersection.IsAlmostEqualTo(primConOrigin) == false) { endPointAnalyzed = intersection; } } } } sbAccessories.Append(EndWriter.WriteCO(endPointAnalyzed)); break; case "SUPPORT": primaryConnector = (from Connector c in connectorSet where c.GetMEPConnectorInfo().IsPrimary select c).FirstOrDefault(); sbAccessories.Append(EndWriter.WriteCO(familyInstance, primaryConnector)); break; case "INSTRUMENT-3WAY": //Sort connectors to primary, secondary and none primaryConnector = null; secondaryConnector = null; Connector tertiaryConnector = null; foreach (Connector connector in connectorSet) { if (connector.GetMEPConnectorInfo().IsPrimary) { primaryConnector = connector; } if (connector.GetMEPConnectorInfo().IsSecondary) { secondaryConnector = connector; } if ((connector.GetMEPConnectorInfo().IsPrimary == false) && (connector.GetMEPConnectorInfo().IsSecondary == false)) { tertiaryConnector = connector; } } //Process endpoints of the component sbAccessories.Append(EndWriter.WriteEP1(element, primaryConnector)); sbAccessories.Append(EndWriter.WriteEP2(element, secondaryConnector)); sbAccessories.Append(EndWriter.WriteEP3(element, tertiaryConnector)); sbAccessories.Append(EndWriter.WriteCP(familyInstance)); break; } Composer elemParameterComposer = new Composer(); sbAccessories.Append(elemParameterComposer.ElemParameterWriter(element)); #region CII export if (InputVars.ExportToCII && !string.Equals(element.get_Parameter(pList.PCF_ELEM_TYPE.Guid).AsString(), "SUPPORT")) { sbAccessories.Append(Composer.CIIWriter(doc, key)); } #endregion sbAccessories.Append(" UNIQUE-COMPONENT-IDENTIFIER "); sbAccessories.Append(element.UniqueId); sbAccessories.AppendLine(); //Process tap entries of the element if any //Diameter Limit nullifies the tapsWriter output if the tap diameter is less than the limit so it doesn't get exported if (string.IsNullOrEmpty(element.LookupParameter("PCF_ELEM_TAP1").AsString()) == false) { TapsWriter tapsWriter = new TapsWriter(element, "PCF_ELEM_TAP1", doc); sbAccessories.Append(tapsWriter.tapsWriter); } if (string.IsNullOrEmpty(element.LookupParameter("PCF_ELEM_TAP2").AsString()) == false) { TapsWriter tapsWriter = new TapsWriter(element, "PCF_ELEM_TAP2", doc); sbAccessories.Append(tapsWriter.tapsWriter); } if (string.IsNullOrEmpty(element.LookupParameter("PCF_ELEM_TAP3").AsString()) == false) { TapsWriter tapsWriter = new TapsWriter(element, "PCF_ELEM_TAP3", doc); sbAccessories.Append(tapsWriter.tapsWriter); } } } catch (Exception e) { throw new Exception("Element " + element.Id.IntegerValue.ToString() + " caused an exception: " + e.Message); } //// Clear the output file //System.IO.File.WriteAllBytes(InputVars.OutputDirectoryFilePath + "Accessories.pcf", new byte[0]); //// Write to output file //using (StreamWriter w = File.AppendText(InputVars.OutputDirectoryFilePath + "Accessories.pcf")) //{ // w.Write(sbAccessories); // w.Close(); //} return(sbAccessories); }
public StringBuilder Export(string pipeLineAbbreviation, HashSet <Element> elements, Document document) { Document doc = document; string key = pipeLineAbbreviation; plst pList = new plst(); //paramList = new plst(); //The list of fittings, sorted by TYPE then SKEY IList <Element> accessoriesList = elements. OrderBy(e => e.get_Parameter(pList.PCF_ELEM_TYPE.Guid).AsString()). ThenBy(e => e.get_Parameter(pList.PCF_ELEM_SKEY.Guid).AsString()).ToList(); StringBuilder sbAccessories = new StringBuilder(); //This is a workaround to try to determine what element caused an exception Element element = null; try { foreach (Element Element in accessoriesList) { //This is a workaround to try to determine what element caused an exception element = Element; sbAccessories.AppendLine(element.get_Parameter(new plst().PCF_ELEM_TYPE.Guid).AsString()); sbAccessories.AppendLine(" COMPONENT-IDENTIFIER " + element.get_Parameter(new plst().PCF_ELEM_COMPID.Guid).AsString()); if (element.get_Parameter(new plst().PCF_ELEM_SPEC.Guid).AsString() == "EXISTING-INCLUDE") { sbAccessories.AppendLine(" STATUS DOTTED-UNDIMENSIONED"); sbAccessories.AppendLine(" MATERIAL-LIST EXCLUDE"); } //Write Plant3DIso entries if turned on if (InputVars.ExportToIsogen) { sbAccessories.Append(Composer.Plant3DIsoWriter(element, doc)); } //Cast the elements gathered by the collector to FamilyInstances FamilyInstance familyInstance = (FamilyInstance)element; Options options = new Options(); //Gather connectors of the element var cons = mp.GetConnectors(element); //Switch to different element type configurations switch (element.get_Parameter(pList.PCF_ELEM_TYPE.Guid).AsString()) { case ("FILTER"): //Process endpoints of the component sbAccessories.Append(EndWriter.WriteEP1(element, cons.Primary)); sbAccessories.Append(EndWriter.WriteEP2(element, cons.Secondary)); sbAccessories.Append(pdw.ParameterValue("TAG", new[] { "TAG 1", "TAG 2", "TAG 3" }, element)); break; case ("INSTRUMENT"): //Process endpoints of the component sbAccessories.Append(EndWriter.WriteEP1(element, cons.Primary)); sbAccessories.Append(EndWriter.WriteEP2(element, cons.Secondary)); sbAccessories.Append(EndWriter.WriteCP(familyInstance)); sbAccessories.Append(pdw.ParameterValue("TAG", new[] { "TAG 1", "TAG 2", "TAG 3" }, element)); break; case ("VALVE"): goto case ("INSTRUMENT"); case ("VALVE-ANGLE"): //Process endpoints of the component sbAccessories.Append(EndWriter.WriteEP1(element, cons.Primary)); sbAccessories.Append(EndWriter.WriteEP2(element, cons.Secondary)); //The centre point is obtained by creating an bound line from primary connector and projecting the secondary point on the line. XYZ reverseConnectorVector = -cons.Primary.CoordinateSystem.BasisZ; Line primaryLine = Line.CreateBound(cons.Primary.Origin, cons.Primary.Origin + reverseConnectorVector * 10); XYZ centrePoint = primaryLine.Project(cons.Secondary.Origin).XYZPoint; sbAccessories.Append(EndWriter.WriteCP(centrePoint)); sbAccessories.Append(pdw.ParameterValue("TAG", new[] { "TAG 1", "TAG 2", "TAG 3" }, element)); break; case ("INSTRUMENT-DIAL"): //Connector information extraction sbAccessories.Append(EndWriter.WriteEP1(element, cons.Primary)); XYZ primConOrigin = cons.Primary.Origin; //Analyses the geometry to obtain a point opposite the main connector. //Extraction of the direction of the connector and reversing it reverseConnectorVector = -cons.Primary.CoordinateSystem.BasisZ; Line detectorLine = Line.CreateBound(primConOrigin, primConOrigin + reverseConnectorVector * 10); //Begin geometry analysis GeometryElement geometryElement = familyInstance.get_Geometry(options); //Prepare resulting point XYZ endPointAnalyzed = null; foreach (GeometryObject geometry in geometryElement) { GeometryInstance instance = geometry as GeometryInstance; if (null == instance) { continue; } foreach (GeometryObject instObj in instance.GetInstanceGeometry()) { Solid solid = instObj as Solid; if (null == solid || 0 == solid.Faces.Size || 0 == solid.Edges.Size) { continue; } foreach (Face face in solid.Faces) { IntersectionResultArray results = null; XYZ intersection = null; try { SetComparisonResult result = face.Intersect(detectorLine, out results); if (result != SetComparisonResult.Overlap) { continue; } intersection = results.get_Item(0).XYZPoint; if (intersection.IsAlmostEqualTo(primConOrigin) == false) { endPointAnalyzed = intersection; } } catch (Exception) { continue; } } } } //If the point is still null after geometry intersection, it means the analysis failed //Create an artificial point if (endPointAnalyzed == null) { endPointAnalyzed = cons.Primary.Origin + reverseConnectorVector * 2; } sbAccessories.Append(EndWriter.WriteCO(endPointAnalyzed)); sbAccessories.Append(pdw.ParameterValue("TAG", new[] { "TAG 1", "TAG 2", "TAG 3" }, element)); break; case "SUPPORT": sbAccessories.Append(EndWriter.WriteCO(familyInstance, cons.Primary)); sbAccessories.Append(pdw.ParameterValue("TAG", new[] { "TAG 1", "TAG 2", "TAG 3" }, element)); break; case "FLOOR-SYMBOL": sbAccessories.Append(EndWriter.WriteCO(familyInstance)); break; case "INSTRUMENT-3WAY": //Process endpoints of the component sbAccessories.Append(EndWriter.WriteEP1(element, cons.Primary)); sbAccessories.Append(EndWriter.WriteEP2(element, cons.Secondary)); sbAccessories.Append(EndWriter.WriteEP3(element, cons.Tertiary)); sbAccessories.Append(EndWriter.WriteCP(familyInstance)); break; } Composer elemParameterComposer = new Composer(); sbAccessories.Append(elemParameterComposer.ElemParameterWriter(element)); #region CII export if (InputVars.ExportToCII && !string.Equals(element.get_Parameter(pList.PCF_ELEM_TYPE.Guid).AsString(), "SUPPORT")) { sbAccessories.Append(Composer.CIIWriter(doc, key)); } #endregion sbAccessories.Append(" UNIQUE-COMPONENT-IDENTIFIER "); sbAccessories.Append(element.UniqueId); sbAccessories.AppendLine(); //Process tap entries of the element if any //Diameter Limit nullifies the tapsWriter output if the tap diameter is less than the limit so it doesn't get exported if (string.IsNullOrEmpty(element.LookupParameter("PCF_ELEM_TAP1").AsString()) == false) { TapsWriter tapsWriter = new TapsWriter(element, "PCF_ELEM_TAP1", doc); sbAccessories.Append(tapsWriter.tapsWriter); } if (string.IsNullOrEmpty(element.LookupParameter("PCF_ELEM_TAP2").AsString()) == false) { TapsWriter tapsWriter = new TapsWriter(element, "PCF_ELEM_TAP2", doc); sbAccessories.Append(tapsWriter.tapsWriter); } if (string.IsNullOrEmpty(element.LookupParameter("PCF_ELEM_TAP3").AsString()) == false) { TapsWriter tapsWriter = new TapsWriter(element, "PCF_ELEM_TAP3", doc); sbAccessories.Append(tapsWriter.tapsWriter); } } } catch (Exception e) { throw new Exception("Element " + element.Id.IntegerValue.ToString() + " caused an exception: " + e.Message); } //// Clear the output file //System.IO.File.WriteAllBytes(InputVars.OutputDirectoryFilePath + "Accessories.pcf", new byte[0]); //// Write to output file //using (StreamWriter w = File.AppendText(InputVars.OutputDirectoryFilePath + "Accessories.pcf")) //{ // w.Write(sbAccessories); // w.Close(); //} return(sbAccessories); }