/// <summary> /// Constructor used to populate from a dictionary mapping element ids /// to a list of child elements. /// </summary> public CmdInspectElectricalForm2( MapParentToChildren map, ElementId electricalEquipmentCategoryId, IList <Element> electricalEquipment) { _electricalEquipmentCategoryId = electricalEquipmentCategoryId; _comparer = new ElectricalElementComparer(electricalEquipmentCategoryId); InitializeComponent(); tv.BeginUpdate(); PopulateFromMapParentToChildren(tv.Nodes, ElementId.InvalidElementId, map); tv.EndUpdate(); listBox1.SelectedIndex = 0; }
void PopulateFromMapParentToChildren( TreeNodeCollection tnc, ElementId parentId, MapParentToChildren map) { if (map.ContainsKey(parentId)) { List <Element> children = map[parentId]; children.Sort(_comparer); string key, text; bool isEquipment; // isCircuit foreach (Element e in children) { if (!_done.ContainsKey(e.Id)) { _done[e.Id] = 1; //isCircuit = e is ElectricalSystem; isEquipment = e.Category.Id.Equals(_electricalEquipmentCategoryId); key = Util.ElementDescriptionAndId(e); //text = ( isEquipment || isCircuit ) ? e.Name : Util.BrowserDescription( e ); text = ElectricalElementText(e, _electricalEquipmentCategoryId); TreeNode tn = tnc.Add(key, text); CmdInspectElectricalForm.AddLoadNodes(tn, e); if (map.ContainsKey(e.Id)) { // // highlight circuit e.g. electrical system node that has // electrical equipment connected to it; also avoid setting // it to bold multiple times over: // if (isEquipment) { TreeNode p = tn.Parent; listBox1.Items.Add(new PanelTreeNodeHelper(e, tn)); if (null != p && (null == p.NodeFont || !p.NodeFont.Bold)) { p.NodeFont = new System.Drawing.Font(this.Font, FontStyle.Bold); } } PopulateFromMapParentToChildren(tn.Nodes, e.Id, map); } } } } }
static void PopulateChildren( MapParentToChildren mapParentToChildren, Element parent ) { Connector c2 = null; ElementId id = parent.Id; FamilyInstance fi = parent as FamilyInstance; ElectricalSystem eq = parent as ElectricalSystem; Debug.Assert( null != fi || null != eq, "expected element to be family instance or electrical system" ); ConnectorSet connectors = (null == eq) ? fi.MEPModel.ConnectorManager.Connectors : eq.ConnectorManager.Connectors; foreach( Connector c in connectors ) { Debug.Assert( c.Owner.Id.Equals( id ), "expected connector owner to be this element" ); //if( c.IsConnected ) // only valid for PhysicalConn //MEPSystem mepSystem = c.MEPSystem; // null for electrical connector //if( null == mepSystem ) // || !mepSystem.Id.IntegerValue.Equals( m_system.Id.IntegerValue ) //{ // continue; //} //c2 = GetConnectedConnector( c ); ConnectorSet refs = c.AllRefs; Debug.Assert( 1 == refs.Size, "expected one single connected connector" ); foreach( Connector tmp in refs ) { c2 = tmp; } if( null != c2 ) { Element e = c2.Owner; Debug.Assert( null != e, "expected valid connector owner" ); Debug.Assert( e is FamilyInstance || e is ElectricalSystem, "expected electrical connector owner to be family instance or electrical equipment" ); mapParentToChildren.Add( id, e ); } } }
public Result Execute( ExternalCommandData commandData, ref String message, ElementSet elements) { try { // // dictionary defining tree view info displayed in modeless // dialogue mapping parent node to all its circuit elements: // null --> root panels // panel --> systems // system --> circuit elements, panels, ... // MapParentToChildren mapParentToChildren = new MapParentToChildren(); ElementId electricalEquipmentCategoryId = ElementId.InvalidElementId; List <Element> equipment; { // // run the analysis in its own scope, so the wait cursor // disappears before we display the modeless dialogue: // WaitCursor waitCursor = new WaitCursor(); UIApplication app = commandData.Application; Document doc = app.ActiveUIDocument.Document; ElementId nullId = ElementId.InvalidElementId; // // retrieve electrical equipment instances: // equipment = Util.GetElectricalEquipment(doc); int n = equipment.Count; Debug.WriteLine(string.Format("Retrieved {0} electrical equipment instance{1}{2}", n, Util.PluralSuffix(n), Util.DotOrColon(n))); Dictionary <string, FamilyInstance> mapPanel = new Dictionary <string, FamilyInstance>(); foreach (FamilyInstance e in equipment) { // // ensure that every panel shows up in the list, // even if it does not have children: // mapParentToChildren.Add(e.Id, null); mapPanel[e.Name] = e; MEPModel mepModel = e.MEPModel; ElectricalSystemSet systems2 = mepModel.ElectricalSystems; string panelAndSystem = string.Empty; if (null == systems2) { panelAndSystem = CmdElectricalSystemBrowser.Unassigned; // this is a root node } else { Debug.Assert(1 == systems2.Size, "expected equipment to belong to one single panel and system"); foreach (ElectricalSystem system in systems2) { if (0 < panelAndSystem.Length) { panelAndSystem += ", "; } panelAndSystem += system.PanelName + ":" + system.Name + ":" + system.Id.IntegerValue.ToString(); } } Debug.WriteLine(" " + Util.ElementDescriptionAndId(e) + " " + panelAndSystem); } // // retrieve electrical systems: // these are also returned by Util.GetCircuitElements(), by the way, // since they have the parameters RBS_ELEC_CIRCUIT_PANEL_PARAM and // RBS_ELEC_CIRCUIT_NUMBER that we use to identify those. // FilteredElementCollector c = new FilteredElementCollector(doc); IList <Element> systems = c.OfClass(typeof(ElectricalSystem)).ToElements(); n = systems.Count; Debug.WriteLine(string.Format("Retrieved {0} electrical system{1}{2}", n, Util.PluralSuffix(n), Util.DotOrColon(n))); foreach (ElectricalSystem system in systems) { string panelName = system.PanelName; if (0 == panelName.Length) { panelName = CmdElectricalSystemBrowser.Unassigned; // will not appear in tree } else { // // todo: is there a more direct way to identify // what panel a system belongs to? this seems error // prone ... what if a panel name occurs multiple times? // how do we identify which one to use? // FamilyInstance panel = mapPanel[panelName]; mapParentToChildren.Add(panel.Id, system); } string panelAndSystem = panelName + ":" + system.Name + ":" + system.Id.IntegerValue.ToString(); Debug.WriteLine(" " + Util.ElementDescriptionAndId(system) + " " + panelAndSystem); Debug.Assert(system.ConnectorManager.Owner.Id.Equals(system.Id), "expected electrical system's connector manager owner to be system itself"); } // // now we have the equipment and systems, // we can build the non-leaf levels of the tree: // foreach (FamilyInstance e in equipment) { MEPModel mepModel = e.MEPModel; ElectricalSystemSet systems2 = mepModel.ElectricalSystems; if (null == systems2) { mapParentToChildren.Add(nullId, e); // root node } else { Debug.Assert(1 == systems2.Size, "expected equipment to belong to one single panel and system"); foreach (ElectricalSystem system in systems2) { mapParentToChildren.Add(system.Id, e); } } } // // list all circuit elements: // BuiltInParameter bipPanel = BuiltInParameter.RBS_ELEC_CIRCUIT_PANEL_PARAM; BuiltInParameter bipCircuit = BuiltInParameter.RBS_ELEC_CIRCUIT_NUMBER; IList <Element> circuitElements = Util.GetCircuitElements(doc); n = circuitElements.Count; Debug.WriteLine(string.Format("Retrieved {0} circuit element{1}...", n, Util.PluralSuffix(n))); n = 0; foreach (Element e in circuitElements) { if (e is ElectricalSystem) { ++n; } else { string circuitName = e.get_Parameter(bipCircuit).AsString(); string panelName = e.get_Parameter(bipPanel).AsString(); string key = panelName + ":" + circuitName; string panelAndSystem = string.Empty; FamilyInstance inst = e as FamilyInstance; Debug.Assert(null != inst, "expected all circuit elements to be family instances"); MEPModel mepModel = inst.MEPModel; ElectricalSystemSet systems2 = mepModel.ElectricalSystems; Debug.Assert(null != systems2, "expected circuit element to belong to an electrical system"); // this fails in "2341_MEP - 2009 Central.rvt", says martin: // // a circuit element can belong to several systems ... imagine // a piece of telephone equipment which hooks up to a phone line // and also requires power ... so i removed this assertion: // //Debug.Assert( 1 == systems2.Size, "expected circuit element to belong to one single system" ); foreach (ElectricalSystem system in systems2) { if (0 < panelAndSystem.Length) { panelAndSystem += ", "; } panelAndSystem += system.PanelName + ":" + system.Name + ":" + system.Id.IntegerValue.ToString(); Debug.Assert(system.PanelName == panelName, "expected same panel name in parameter and electrical system"); // this fails in "2341_MEP - 2009 Central.rvt", says martin: //Debug.Assert( system.Name == circuitName, "expected same name in circuit parameter and system" ); mapParentToChildren.Add(system.Id, e); } Debug.WriteLine(string.Format(" {0} panel:circuit {1}", Util.ElementDescriptionAndId(e), panelAndSystem)); } } Debug.WriteLine(string.Format("{0} circuit element{1} were the electrical systems.", n, Util.PluralSuffix(n))); // // get the electrical equipment category id: // Categories categories = doc.Settings.Categories; electricalEquipmentCategoryId = categories.get_Item(BuiltInCategory.OST_ElectricalEquipment).Id; } // // we have assembled the entire required tree view structure, so let us display it: // CmdInspectElectricalForm2 dialog = new CmdInspectElectricalForm2(mapParentToChildren, electricalEquipmentCategoryId, equipment); dialog.Show(); return(Result.Succeeded); } catch (Exception ex) { message = ex.Message; return(Result.Failed); } }
public Result Execute( ExternalCommandData commandData, ref String message, ElementSet elements ) { UIApplication app = commandData.Application; Document doc = app.ActiveUIDocument.Document; // // retrieve electrical equipment: // List<Element> equipment = Util.GetElectricalEquipment( doc ); int n = equipment.Count; Debug.WriteLine( string.Format( "Retrieved {0} electrical equipment instance{1}{2}", n, Util.PluralSuffix( n ), Util.DotOrColon( n ) ) ); // // determine which equipment has parents; // the remaining ones are root nodes: // Dictionary<ElementId, ElementId> equipmentParents = new Dictionary<ElementId, ElementId>(); foreach( FamilyInstance fi in equipment ) { foreach( Connector c in fi.MEPModel.ConnectorManager.Connectors ) { ConnectorSet refs = c.AllRefs; foreach( Connector c2 in refs ) { Debug.Assert( null != c2.Owner, "expected valid connector owner" ); Debug.Assert( c2.Owner is ElectricalSystem, "expected panel element to be electrical system" ); ElectricalSystem eq = c2.Owner as ElectricalSystem; foreach( Element e2 in eq.Elements ) { Debug.Assert( e2 is FamilyInstance, "expected electrical system element to be family instance" ); if( !e2.Id.Equals( fi.Id ) ) { if( equipment.Exists( delegate( Element e ) { return e.Id.Equals( e2.Id ); } ) ) { equipmentParents[e2.Id] = eq.Id; } } } } } } //n = equipment.RemoveAll( delegate( Element e ) { return subequipment.Exists( delegate( Element e2 ) { return e2.Id.Equals( e.Id ); } ); } ); // // populate parent to children mapping: // ElementId nullId = ElementId.InvalidElementId; MapParentToChildren mapParentToChildren = new MapParentToChildren(); foreach( FamilyInstance fi in equipment ) { //ElementId parentId = equipmentParents.ContainsKey( fi.Id ) ? equipmentParents[fi.Id] : nullId; //mapParentToChildren.Add( parentId, fi ); // // handle root nodes; // non-roots are handled below a children: // if( !equipmentParents.ContainsKey( fi.Id ) ) { mapParentToChildren.Add( nullId, fi ); } foreach( Connector c in fi.MEPModel.ConnectorManager.Connectors ) { ConnectorSet refs = c.AllRefs; foreach( Connector c2 in refs ) { Debug.Assert( null != c2.Owner, "expected valid connector owner" ); Debug.Assert( c2.Owner is ElectricalSystem, "expected panel element to be electrical system" ); ElectricalSystem eq = c2.Owner as ElectricalSystem; mapParentToChildren.Add( fi.Id, eq ); foreach( Element e2 in eq.Elements ) { Debug.Assert( e2 is FamilyInstance, "expected electrical system element to be family instance" ); if( !e2.Id.Equals( fi.Id ) ) { mapParentToChildren.Add( eq.Id, e2 ); } } } } } #region Test code #if TEST_CODE // // retrieve electrical systems: // List<Element> systems = new List<Element>(); doc.get_Elements( typeof( ElectricalSystem ), systems ); n = systems.Count; Debug.WriteLine( string.Format( "Retrieved {0} electrical system{1}{2}", n, Util.PluralSuffix( n ), Util.DotOrColon( n ) ) );