private bool IsRuleSetToRangeNone(RoutingPreferenceManager routingPreferenceManager, RoutingPreferenceRuleGroupType groupType, int index) { if (routingPreferenceManager.GetNumberOfRules(groupType) == 0) { return(false); } RoutingPreferenceRule rule = routingPreferenceManager.GetRule(groupType, index); if (rule.NumberOfCriteria == 0) { return(false); } PrimarySizeCriterion psc = rule.GetCriterion(0) as PrimarySizeCriterion; if (psc.IsEqual(PrimarySizeCriterion.None())) { return(true); } else { return(false); } }
/// <summary> /// Check to see if the routing preferences specify a preferred junction type but do not have any /// rules with valid fittings for that type (e.g, "Tee" is the preferred junction type, but only "Tap" fittings /// are specified in junction rules.) /// </summary> /// <param name="routingPreferenceManager"></param> /// <returns></returns> private bool IsPreferredJunctionTypeValid(RoutingPreferenceManager routingPreferenceManager) { PreferredJunctionType preferredJunctionType = routingPreferenceManager.PreferredJunctionType; if (routingPreferenceManager.GetNumberOfRules(RoutingPreferenceRuleGroupType.Junctions) == 0) { return(false); } bool teeDefined = false; bool tapDefined = false; for (int index = 0; index != routingPreferenceManager.GetNumberOfRules(RoutingPreferenceRuleGroupType.Junctions); ++index) { RoutingPreferenceRule rule = routingPreferenceManager.GetRule(RoutingPreferenceRuleGroupType.Junctions, index); if (rule.MEPPartId == ElementId.InvalidElementId) { continue; } FamilySymbol familySymbol = this.m_document.GetElement(rule.MEPPartId) as FamilySymbol; Parameter paramPartType = familySymbol.Family.get_Parameter(BuiltInParameter.FAMILY_CONTENT_PART_TYPE); if (paramPartType == null) { throw new Exception("Null partType parameter."); } PartType partType = (PartType)paramPartType.AsInteger(); if ((partType == PartType.Tee)) { teeDefined = true; } else if ( (partType == PartType.TapAdjustable) || (partType == PartType.TapPerpendicular) || (partType == PartType.SpudPerpendicular) || (partType == PartType.SpudAdjustable) ) { tapDefined = true; } } if ((preferredJunctionType == PreferredJunctionType.Tap) && !tapDefined) { return(false); } if ((preferredJunctionType == PreferredJunctionType.Tee) && !teeDefined) { return(false); } return(true); }
/// <summary> /// Checks to see if any segments in the routing preference manager have sizes that cannot be fitted with fittings defined in a rule group type, such as "Elbow." /// For example, if a segment rule defines a segment be used from sizes 2" to 12", and there are three elbows rules defined to be used from ranges /// 2"-4", 4"-7", and 9"-14", this method will return warning information specifying the sizes (8", 8.5", etc...) not covered by elbow fittings. /// </summary> private XElement GetSegmentRangeNotCoveredWarning(RoutingPreferenceManager routingPreferenceManager, RoutingPreferenceRuleGroupType groupType) { for (int index = 0; index != routingPreferenceManager.GetNumberOfRules(RoutingPreferenceRuleGroupType.Segments); ++index) { RoutingPreferenceRule rule = routingPreferenceManager.GetRule(RoutingPreferenceRuleGroupType.Segments, index); if (rule.MEPPartId == ElementId.InvalidElementId) { continue; } if (rule.NumberOfCriteria == 0) //double check all/none { continue; } PrimarySizeCriterion psc = rule.GetCriterion(0) as PrimarySizeCriterion; PipeSegment segment = m_document.GetElement(rule.MEPPartId) as PipeSegment; List <double> sizesNotCovered = new List <double>(); bool isCovered = CheckSegmentForValidCoverage(routingPreferenceManager, psc.MinimumSize, psc.MaximumSize, rule.MEPPartId, groupType, sizesNotCovered); if (!isCovered) { XElement xSegmentNotCovered = new XElement(XName.Get("SegmentRangeNotCovered")); xSegmentNotCovered.Add(new XAttribute(XName.Get("name"), segment.Name)); StringBuilder sBuilder = new StringBuilder(); foreach (double size in sizesNotCovered) { double roundedSize = Convert.ConvertValueDocumentUnits(size, m_document); sBuilder.Append(roundedSize.ToString() + " "); } sBuilder.Remove(sBuilder.Length - 1, 1); xSegmentNotCovered.Add(new XAttribute(XName.Get("sizes"), sBuilder.ToString())); xSegmentNotCovered.Add(new XAttribute(XName.Get("unit"), m_document.GetUnits().GetFormatOptions(UnitType.UT_PipeSize).DisplayUnits.ToString())); xSegmentNotCovered.Add(new XAttribute(XName.Get("groupType"), groupType.ToString())); return(xSegmentNotCovered); } } return(null); }
/// <summary> /// Get all segments from a the currently selected pipe type, get each size from each segment, /// collect, sort, and return. /// </summary> public static List <double> GetAvailableSegmentSizes(RoutingPreferenceManager routingPreferenceManager, Autodesk.Revit.DB.Document document) { System.Collections.Generic.HashSet <double> sizes = new HashSet <double>(); int segmentCount = routingPreferenceManager.GetNumberOfRules(RoutingPreferenceRuleGroupType.Segments); for (int index = 0; index != segmentCount; ++index) { RoutingPreferenceRule segmentRule = routingPreferenceManager.GetRule(RoutingPreferenceRuleGroupType.Segments, index); Segment segment = document.GetElement(segmentRule.MEPPartId) as Segment; foreach (MEPSize size in segment.GetSizes()) { sizes.Add(size.NominalDiameter); } } List <double> sizesSorted = sizes.ToList(); sizesSorted.Sort(); return(sizesSorted); }
/// <summary> /// Create Xml from a RoutingPreferenceRule /// </summary> /// <param name="rule"></param> /// <param name="groupType"></param> /// <returns></returns> private XElement createXmlFromRoutingPreferenceRule(RoutingPreferenceRule rule, RoutingPreferenceRuleGroupType groupType) { XElement xRoutingPreferenceRule = new XElement(XName.Get("RoutingPreferenceRule")); xRoutingPreferenceRule.Add(new XAttribute(XName.Get("description"), rule.Description)); xRoutingPreferenceRule.Add(new XAttribute(XName.Get("ruleGroup"), groupType.ToString())); if (rule.NumberOfCriteria >= 1) { PrimarySizeCriterion psc = rule.GetCriterion(0) as PrimarySizeCriterion; if (psc.IsEqual(PrimarySizeCriterion.All())) { xRoutingPreferenceRule.Add(new XAttribute(XName.Get("minimumSize"), "All")); } else if (psc.IsEqual(PrimarySizeCriterion.None())) { xRoutingPreferenceRule.Add(new XAttribute(XName.Get("minimumSize"), "None")); } else //Only specify "maximumSize" if not specifying "All" or "None" for minimum size, just like in the UI. { xRoutingPreferenceRule.Add(new XAttribute(XName.Get("minimumSize"), (Convert.ConvertValueDocumentUnits(psc.MinimumSize, m_document)).ToString())); xRoutingPreferenceRule.Add(new XAttribute(XName.Get("maximumSize"), (Convert.ConvertValueDocumentUnits(psc.MaximumSize, m_document)).ToString())); } } else { xRoutingPreferenceRule.Add(new XAttribute(XName.Get("minimumSize"), "All")); } if (groupType == RoutingPreferenceRuleGroupType.Segments) { xRoutingPreferenceRule.Add(new XAttribute(XName.Get("partName"), GetSegmentNameById(rule.MEPPartId))); } else { xRoutingPreferenceRule.Add(new XAttribute(XName.Get("partName"), GetFittingNameById(rule.MEPPartId))); } return(xRoutingPreferenceRule); }
/// <summary> /// Populate a routing preference manager from Xml /// </summary> /// <param name="routingPreferenceManagerXElement"></param> private void ParseRoutingPreferenceManagerFromXML(XElement routingPreferenceManagerXElement) { XAttribute xaPipeTypeName = routingPreferenceManagerXElement.Attribute(XName.Get("pipeTypeName")); XAttribute xaPreferredJunctionType = routingPreferenceManagerXElement.Attribute(XName.Get("preferredJunctionType")); PreferredJunctionType preferredJunctionType; bool r1 = Enum.TryParse <PreferredJunctionType>(xaPreferredJunctionType.Value, out preferredJunctionType); if (!r1) { throw new RoutingPreferenceDataException("Invalid Preferred Junction Type in: " + routingPreferenceManagerXElement.ToString()); } ElementId pipeTypeId = GetPipeTypeByName(xaPipeTypeName.Value); if (pipeTypeId == ElementId.InvalidElementId) { throw new RoutingPreferenceDataException("Could not find pipe type element in: " + routingPreferenceManagerXElement.ToString()); } PipeType pipeType = m_document.GetElement(pipeTypeId) as PipeType; RoutingPreferenceManager routingPreferenceManager = pipeType.RoutingPreferenceManager; routingPreferenceManager.PreferredJunctionType = preferredJunctionType; foreach (XNode xRule in routingPreferenceManagerXElement.Nodes()) { if (xRule is XElement) { RoutingPreferenceRuleGroupType groupType; RoutingPreferenceRule rule = ParseRoutingPreferenceRuleFromXML(xRule as XElement, out groupType); routingPreferenceManager.AddRule(groupType, rule); } } }
void SelectAndPlaceTakeOffFitting( Document doc ) { ElementId mainDuctId = ElementId.InvalidElementId; // Get DuctType - we need this for its // RoutingPreferenceManager. This is how we assign // our tap object to be used. This is the settings // for the duct object we attach our tap to. Duct duct = doc.GetElement( mainDuctId ) as Duct; DuctType ductType = duct.DuctType; RoutingPreferenceManager routePrefManager = ductType.RoutingPreferenceManager; // Set Junction Prefernce to Tap. routePrefManager.PreferredJunctionType = PreferredJunctionType.Tap; // For simplicity sake, I remove all previous rules // for taps so I can just add what I want here. // This will probably vary. int initRuleCount = routePrefManager.GetNumberOfRules( RoutingPreferenceRuleGroupType.Junctions ); for( int i = 0; i != initRuleCount; ++i ) { routePrefManager.RemoveRule( RoutingPreferenceRuleGroupType.Junctions, 0 ); } // Get FamilySymbol for Tap I want to use. FamilySymbol tapSym = null; doc.LoadFamilySymbol( "C:/FamilyLocation/MyTap.rfa", "MyTap", out tapSym ); // Symbol needs to be activated before use. if( ( !tapSym.IsActive ) && ( tapSym != null ) ) { tapSym.Activate(); doc.Regenerate(); } // Create Rule that utilizes the Tap. Use the argument // MEPPartId = ElementId for the desired FamilySymbol. RoutingPreferenceRule newRule = new RoutingPreferenceRule( tapSym.Id, "MyTap" ); routePrefManager.AddRule( RoutingPreferenceRuleGroupType.Junctions, newRule ); // To create a solid tap, we need to use the Revit // doc.Create.NewTakeoffFitting routine. For this, // we need a connector. If we don't have one, we // just create a temporary object with a connector // where we want it. Connector tmpConn = CreateTemporaryConnectorForTap(); // Create our tap. FamilyInstance tapInst = doc.Create.NewTakeoffFitting( tmpConn, duct ); }
/// <summary> /// Create a RoutingPreferenceRule from Xml /// </summary> /// <param name="ruleXElement"></param> /// <param name="groupType"></param> /// <returns></returns> private RoutingPreferenceRule ParseRoutingPreferenceRuleFromXML(XElement ruleXElement, out RoutingPreferenceRuleGroupType groupType) { XAttribute xaDescription = null; XAttribute xaPartName = null; XAttribute xaMinSize = null; XAttribute xaMaxSize = null; XAttribute xaGroup = null; xaDescription = ruleXElement.Attribute(XName.Get("description")); xaPartName = ruleXElement.Attribute(XName.Get("partName")); xaGroup = ruleXElement.Attribute(XName.Get("ruleGroup")); xaMinSize = ruleXElement.Attribute(XName.Get("minimumSize")); ElementId partId; bool r3 = Enum.TryParse <RoutingPreferenceRuleGroupType>(xaGroup.Value, out groupType); if (!r3) { throw new RoutingPreferenceDataException("Could not parse rule group type: " + xaGroup.Value); } string description = xaDescription.Value; if (groupType == RoutingPreferenceRuleGroupType.Segments) { partId = GetSegmentByName(xaPartName.Value); } else { partId = GetFittingByName(xaPartName.Value); } if (partId == ElementId.InvalidElementId) { throw new RoutingPreferenceDataException("Could not find MEP Part: " + xaPartName.Value + ". Is this the correct family name, and is the correct family loaded?"); } RoutingPreferenceRule rule = new RoutingPreferenceRule(partId, description); PrimarySizeCriterion sizeCriterion; if (string.Compare(xaMinSize.Value, "All", true) == 0) //If "All" or "None" are specified, set min and max values to documented "Max" values. { sizeCriterion = PrimarySizeCriterion.All(); } else if (string.Compare(xaMinSize.Value, "None", true) == 0) { sizeCriterion = PrimarySizeCriterion.None(); } else // "maximumSize" attribute is only needed if not specifying "All" or "None." { try { xaMaxSize = ruleXElement.Attribute(XName.Get("maximumSize")); } catch (System.Exception) { throw new RoutingPreferenceDataException("Cannot get maximumSize attribute in: " + ruleXElement.ToString()); } double min, max; bool r1 = double.TryParse(xaMinSize.Value, out min); bool r2 = double.TryParse(xaMaxSize.Value, out max); if (!r1 || !r2) { throw new RoutingPreferenceDataException("Could not parse size values: " + xaMinSize.Value + ", " + xaMaxSize.Value); } if (min > max) { throw new RoutingPreferenceDataException("Invalid size range."); } min = Convert.ConvertValueToFeet(min, m_document); max = Convert.ConvertValueToFeet(max, m_document); sizeCriterion = new PrimarySizeCriterion(min, max); } rule.AddCriterion(sizeCriterion); return(rule); }
void SelectAndPlaceTakeOffFitting(Document doc) { ElementId mainDuctId = ElementId.InvalidElementId; // Get DuctType - we need this for its // RoutingPreferenceManager. This is how we assign // our tap object to be used. This is the settings // for the duct object we attach our tap to. Duct duct = doc.GetElement(mainDuctId) as Duct; DuctType ductType = duct.DuctType; RoutingPreferenceManager routePrefManager = ductType.RoutingPreferenceManager; // Set Junction Prefernce to Tap. routePrefManager.PreferredJunctionType = PreferredJunctionType.Tap; // For simplicity sake, I remove all previous rules // for taps so I can just add what I want here. // This will probably vary. int initRuleCount = routePrefManager.GetNumberOfRules( RoutingPreferenceRuleGroupType.Junctions); for (int i = 0; i != initRuleCount; ++i) { routePrefManager.RemoveRule( RoutingPreferenceRuleGroupType.Junctions, 0); } // Get FamilySymbol for Tap I want to use. FamilySymbol tapSym = null; doc.LoadFamilySymbol("C:/FamilyLocation/MyTap.rfa", "MyTap", out tapSym); // Symbol needs to be activated before use. if ((!tapSym.IsActive) && (tapSym != null)) { tapSym.Activate(); doc.Regenerate(); } // Create Rule that utilizes the Tap. Use the argument // MEPPartId = ElementId for the desired FamilySymbol. RoutingPreferenceRule newRule = new RoutingPreferenceRule(tapSym.Id, "MyTap"); routePrefManager.AddRule( RoutingPreferenceRuleGroupType.Junctions, newRule); // To create a solid tap, we need to use the Revit // doc.Create.NewTakeoffFitting routine. For this, // we need a connector. If we don't have one, we // just create a temporary object with a connector // where we want it. Connector tmpConn = CreateTemporaryConnectorForTap(); // Create our tap. FamilyInstance tapInst = doc.Create.NewTakeoffFitting(tmpConn, duct); }
/// <summary> /// 检测系统中是否有默认连接项,无则进行添加 /// </summary> /// <param name="src"></param> /// <param name="type"></param> protected FamilySymbol Judge_LoadDefaultFitting(MEPCurve src, MEPCurveConnectTypeENUM type) { FamilySymbol fs = null; switch (type) { case MEPCurveConnectTypeENUM.Elbow: //弯头 fs = src.GetDefaultFittingSymbol(RoutingPreferenceRuleGroupType.Elbows); break; case MEPCurveConnectTypeENUM.Tee: //三通 fs = src.GetDefaultFittingSymbol(RoutingPreferenceRuleGroupType.Junctions); break; case MEPCurveConnectTypeENUM.Cross: //四通 fs = src.GetDefaultFittingSymbol(RoutingPreferenceRuleGroupType.Crosses); break; case MEPCurveConnectTypeENUM.Transition: //过渡件 fs = src.GetDefaultFittingSymbol(RoutingPreferenceRuleGroupType.Transitions); break; case MEPCurveConnectTypeENUM.TakeOff: //侧接 fs = src.GetDefaultTakeoffFittingSymbol(); break; default: fs = null; break; } if (fs != null) { return(fs); } if (this.IsOnlyUseRevitDefault) { return(null); } var familyName = this.GetDefaultFittingName(src, type); if (familyName == null) { return(null); } fs = FamilyLoadUtils.FindFamilySymbol_SubTransaction(src.Document, familyName, null); if (fs == null) { return(null); } if (src is Pipe || src is Duct) { RoutingPreferenceManager rpm = src.GetMEPCurveType().RoutingPreferenceManager; var rule = new RoutingPreferenceRule(fs.Id, ""); rule.AddCriterion(PrimarySizeCriterion.All()); switch (type) { case MEPCurveConnectTypeENUM.Elbow: //弯头 rpm.AddRule(RoutingPreferenceRuleGroupType.Elbows, rule); break; case MEPCurveConnectTypeENUM.Tee: //三通 rpm.AddRule(RoutingPreferenceRuleGroupType.Junctions, rule); break; case MEPCurveConnectTypeENUM.Cross: //四通 rpm.AddRule(RoutingPreferenceRuleGroupType.Crosses, rule); break; case MEPCurveConnectTypeENUM.Transition: //过渡件 rpm.AddRule(RoutingPreferenceRuleGroupType.Transitions, rule); break; case MEPCurveConnectTypeENUM.TakeOff: //侧接 rpm.AddRule(RoutingPreferenceRuleGroupType.Junctions, rule); break; default: break; } } else if (src is Conduit) { Parameter param = null; switch (type) { case MEPCurveConnectTypeENUM.Elbow: //弯头 param = (src.Document.GetElement(src.GetTypeId())).GetParameters("弯头").FirstOrDefault(); break; case MEPCurveConnectTypeENUM.Tee: //三通 param = (src.Document.GetElement(src.GetTypeId())).GetParameters("T 形三通").FirstOrDefault(); break; case MEPCurveConnectTypeENUM.Cross: //四通 param = (src.Document.GetElement(src.GetTypeId())).GetParameters("交叉线").FirstOrDefault(); break; case MEPCurveConnectTypeENUM.Transition: //过渡件 param = (src.Document.GetElement(src.GetTypeId())).GetParameters("过渡件").FirstOrDefault(); break; default: break; } if (param != null) { param.Set(fs.Id); } } else if (src is CableTray) { Parameter param = null; var t = new FilteredElementCollector(src.Document).OfClass(typeof(CableTrayType)).FirstOrDefault(p => p.GetParameters("族名称").First().AsString() == "带配件的电缆桥架"); switch (type) { case MEPCurveConnectTypeENUM.Elbow: //弯头 param = t.GetParameters("水平弯头").FirstOrDefault(); break; case MEPCurveConnectTypeENUM.Tee: //三通 param = t.GetParameters("T 形三通").FirstOrDefault(); break; case MEPCurveConnectTypeENUM.Cross: //四通 param = t.GetParameters("交叉线").FirstOrDefault(); break; case MEPCurveConnectTypeENUM.Transition: //过渡件 param = t.GetParameters("过渡件").FirstOrDefault(); break; default: break; } if (param != null) { param.Set(fs.Id); } } return(fs); }