/// <summary> /// Method to write ITEM-CODE and ITEM-DESCRIPTION entries to enable import of the PCF file into the Plant 3D "PLANTPCFTOISO" command. /// </summary> /// <param name="element">The current element being written.</param> /// <returns>StringBuilder containing the entries.</returns> public static StringBuilder Plant3DIsoWriter(Element element, Document doc) { //If an element has EXISTING in it's PCF_ELEM_SPEC the writing of ITEM-CODE will be skipped, making Plant 3D ISO treat it as existing. pdef elemSpec = new plst().PCF_ELEM_SPEC; Parameter pm = element.get_Parameter(elemSpec.Guid); if (string.Equals(pm.AsString(), "EXISTING")) { return(new StringBuilder()); } //Write ITEM-CODE et al StringBuilder sb = new StringBuilder(); pdef matId = new plst().PCF_MAT_ID; pdef matDescr = new plst().PCF_MAT_DESCR; int itemCode = element.get_Parameter(matId.Guid).AsInteger(); string itemDescr = element.get_Parameter(matDescr.Guid).AsString(); string key = MepUtils.GetElementPipingSystemType(element, doc).Abbreviation; sb.AppendLine(" ITEM-CODE " + key + "-" + itemCode); sb.AppendLine(" ITEM-DESCRIPTION " + itemDescr); return(sb); }
private Connector DetectUnconnectedConnector(Document doc, Connector knownCon) { var allCons = MepUtils.GetALLConnectorsInDocument(doc); return(allCons.Where(c => c.Equalz(knownCon, 0.00328) && c.Owner.Id.IntegerValue != knownCon.Owner.Id.IntegerValue).FirstOrDefault()); }
//Choose one and traverse in both directions finding other supports on same pipe //Continue conditions: // 1. Element is Pipe -> add to brokenPipesList, continue // a. AND PipingSystemAbbreviation remains unchanged // b. AND PCF_ELEM_SPEC remains unchanged // 2. Element is PipeAccessory and is one of the Support family instances -> add to supports on pipe //Break conditions: // 1. Element is PipeFitting -> Break // 2. Element is PipeAccessory and NOT an instance of a Support family -> Break // 3. Element is Pipe AND PipingSystemAbbreviation changes -> Break // 4. Element is Pipe AND PCF_ELEM_SPEC changes -> Break // 5. Free end -> Break public void Traverse(Document doc) { //Get connectors from the Seed Element Cons cons = MepUtils.GetConnectors(SeedElement); //Assign the connectors from the support to the two directions Connector firstSideCon = cons.Primary; Connector secondSideCon = cons.Secondary; #region SpecFinder //The spec of the support can be different from the pipe's //It is decided that the spec of the pipe is decisive //This means spec must be determined before loop starts //ATTENTION: If pipes on both sides have different spec -> no traversal needed -> the support is placed at a natural boundary Connector refFirstCon = null; Connector refSecondCon = null; if (firstSideCon.IsConnected) { var refFirstCons = MepUtils.GetAllConnectorsFromConnectorSet(firstSideCon.AllRefs); refFirstCon = refFirstCons.Where(x => x.Owner.IsType <Pipe>()).FirstOrDefault(); } else { refFirstCon = DetectUnconnectedConnector(doc, firstSideCon); } if (secondSideCon.IsConnected) { var refSecondCons = MepUtils.GetAllConnectorsFromConnectorSet(secondSideCon.AllRefs); refSecondCon = refSecondCons.Where(x => x.Owner.IsType <Pipe>()).FirstOrDefault(); } else { refSecondCon = DetectUnconnectedConnector(doc, secondSideCon); } string firstSpec = ""; string secondSpec = ""; string spec = ""; if (refFirstCon != null) { Element el = refFirstCon.Owner; firstSpec = el.get_Parameter(new plst().PCF_ELEM_SPEC.Guid).AsString(); } if (refSecondCon != null) { Element el = refSecondCon.Owner; secondSpec = el.get_Parameter(new plst().PCF_ELEM_SPEC.Guid).AsString(); } if (firstSpec.IsNullOrEmpty() && secondSpec.IsNullOrEmpty()) { return; //<- Both empty } if (!firstSpec.IsNullOrEmpty() && secondSpec.IsNullOrEmpty()) { spec = firstSpec; //<- First not empty, but second } else if (firstSpec.IsNullOrEmpty() && !secondSpec.IsNullOrEmpty()) { spec = secondSpec; //<- Second not empty, but first } else { if (firstSpec == secondSpec) { spec = firstSpec; } else { return; //<- Different specs -> support is at natural boundary } } #endregion //Loop controller bool Continue = true; //Side controller bool firstSideDone = false; //Loop variables Connector start = null; //Initialize first loop start = firstSideCon; //Loop guard int i = 0; while (Continue) { //Loop guard, if too many iterations something is wrong i++; if (i > 10000) { throw new Exception("Traverse loop in BrokenPipes has reached 10000 iterations -> something is wrong! \n" + "Do you really have 10000 pipe pieces?"); } //Using a seed connector, "start", get the next element //If "start" does not yield a connector to continue on -> stop this side //Determine if next element is eligible for continue //If yes, add element to collections, get next connector //If not, continue next side if side not already done Connector refCon; if (start.IsConnected) { var refCons = MepUtils.GetAllConnectorsFromConnectorSet(start.AllRefs); //<- DOES ALLREFS RETURN NULL IF EMPTY??? refCon = refCons.Where(x => x.Owner.IsType <Pipe>() || x.Owner.IsType <FamilyInstance>()).FirstOrDefault(); } else { refCon = DetectUnconnectedConnector(doc, start); } //Break condition 5: Free end if (refCon == null) //Dead end { if (firstSideDone == false) { //Dead end -> first side done -> continue second side firstSideDone = true; start = secondSideCon; continue; } else { Continue = false; break; } //Dead end -> both sides done -> end traversal loop } Element elementToConsider = refCon.Owner; //Determine if the element is a support bool isSupport = elementToConsider.ComponentClass1(doc) == "Pipe Support"; //Continuation 1a string elementSysAbr = elementToConsider.get_Parameter(BuiltInParameter.RBS_DUCT_PIPE_SYSTEM_ABBREVIATION_PARAM).AsString(); if (CurSysAbr != elementSysAbr) { if (firstSideDone == false) { //Dead end -> first side done -> continue second side firstSideDone = true; start = secondSideCon; continue; } else { Continue = false; break; } //Dead end -> both sides done -> end traversal } //Continuation 1b string elementSpec = elementToConsider.get_Parameter(new plst().PCF_ELEM_SPEC.Guid).AsString(); if (spec != elementSpec && !isSupport) //The spec can be different for another support on the pipe, so it must accept those { if (firstSideDone == false) { //Dead end -> first side done -> continue second side firstSideDone = true; start = secondSideCon; continue; } else { Continue = false; break; } //Dead end -> both sides done -> end traversal } switch (elementToConsider) { //Remove from pipeList, add to brokenPipesList, continue case Pipe pipe: BrokenPipes.Add(elementToConsider); start = (from Connector c in pipe.ConnectorManager.Connectors //Find next seed connector where c.Id != refCon.Id && (int)c.ConnectorType == 1 select c).FirstOrDefault(); break; case FamilyInstance fi: //Break condition 1: Element is a fitting if (elementToConsider.Category.Id.IntegerValue == (int)BuiltInCategory.OST_PipeFitting) { if (firstSideDone == false) { //Dead end -> first side done -> continue second side firstSideDone = true; start = secondSideCon; continue; } else { Continue = false; break; } //Dead end -> both sides done -> end traversal } //Break condition 2: Element is a PipeAccessory and NOT a support if (elementToConsider.Category.Id.IntegerValue == (int)BuiltInCategory.OST_PipeAccessory && !isSupport) { if (firstSideDone == false) { //Dead end -> first side done -> continue second side firstSideDone = true; start = secondSideCon; continue; } else { Continue = false; break; } //Dead end -> both sides done -> end traversal } //If execution reaches this part, then the element is a support and is eligible for consideration SupportsOnPipe.Add(elementToConsider); //Find next seed connector Cons supportCons = MepUtils.GetConnectors(elementToConsider); if (refCon.GetMEPConnectorInfo().IsPrimary) { start = supportCons.Secondary; } else { start = supportCons.Primary; } break; default: break; } } }
public static void SetWallThicknessPipes(HashSet <Element> elements) { //Wallthicknes for pipes are hardcoded until further notice //Values are from 10216-2 - Seamless steel tubes for pressure purposes //TODO: Implement a way to read values from excel Dictionary <int, string> pipeWallThk = new Dictionary <int, string> { [10] = "1.8 mm", [15] = "2 mm", [20] = "2.3 mm", [25] = "2.6 mm", [32] = "2.6 mm", [40] = "2.6 mm", [50] = "2.9 mm", [65] = "2.9 mm", [80] = "3.2 mm", [100] = "3.6 mm", [125] = "4 mm", [150] = "4.5 mm", [200] = "6.3 mm", [250] = "6.3 mm", [300] = "7.1 mm", [350] = "8 mm", [400] = "8.8 mm", [450] = "10 mm", [500] = "11 mm", [600] = "12.5 mm" }; pdef wallThkDef = new plst().PCF_ELEM_CII_WALLTHK; pdef elemType = new plst().PCF_ELEM_TYPE; foreach (Element element in elements) { //See if the parameter already has value and skip element if it has if (!string.IsNullOrEmpty(element.get_Parameter(wallThkDef.Guid).AsString())) { continue; } if (element.get_Parameter(elemType.Guid).AsString().Equals("SUPPORT")) { continue; } //Retrieve the correct wallthickness from dictionary and set it on the element Parameter wallThkParameter = element.get_Parameter(wallThkDef.Guid); //Get connector set for the pipes ConnectorSet connectorSet = MepUtils.GetConnectorManager(element).Connectors; Connector c1 = null; if (element is Pipe) { //Filter out non-end types of connectors c1 = (from Connector connector in connectorSet where connector.ConnectorType.ToString().Equals("End") select connector).FirstOrDefault(); } if (element is FamilyInstance) { c1 = (from Connector connector in connectorSet where connector.GetMEPConnectorInfo().IsPrimary select connector).FirstOrDefault(); Connector c2 = (from Connector connector in connectorSet where connector.GetMEPConnectorInfo().IsSecondary select connector).FirstOrDefault(); if (c2 != null) { if (c1.Radius > c2.Radius) { c1 = c2; } } } string data = string.Empty; string source = Conversion.PipeSizeToMm(c1.Radius); int dia = Convert.ToInt32(source); pipeWallThk.TryGetValue(dia, out data); wallThkParameter.Set(data); } }