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 public Result Execute2( ExternalCommandData commandData, ref String message, ElementSet elements, bool populateFullHierarchy) { try { WaitCursor waitCursor = new WaitCursor(); UIApplication app = commandData.Application; Document doc = app.ActiveUIDocument.Document; // // display electrical equipment instance data, // i.e. equipment_name:system_name, and convert it to // a map from key = panel:circuit --> 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))); Dictionary <string, List <Element> > mapPanelAndSystemToEquipment = new Dictionary <string, List <Element> >(); foreach (FamilyInstance elecEqip in equipment) { ListEquipment(elecEqip, mapPanelAndSystemToEquipment); } // // determine mapping from panel to circuit == electrical system: // Dictionary <string, ElectricalSystemSet> mapPanelToSystems = new Dictionary <string, ElectricalSystemSet>(); IList <Element> systems = Util.GetElectricalSystems(doc); n = systems.Count; Debug.WriteLine(string.Format("Retrieved {0} electrical system{1}.", n, Util.PluralSuffix(n))); // // all circuits which are fed from the same family instance have // the same panel name, so you can retrieve all of these circuits. // // todo: there is an issue here if there are several different panels // with the same name! they will get merged in the tree view, // but they should stay separate. possible workaround: add the // element id to keep them separate, and then remove it again // when displaying in tree view. // foreach (ElectricalSystem system in systems) { string panelName = system.PanelName; Debug.WriteLine(" system " + system.Name + ": panel " + panelName + " load classifications " + system.LoadClassifications); if (!mapPanelToSystems.ContainsKey(panelName)) { mapPanelToSystems.Add(panelName, new ElectricalSystemSet()); } mapPanelToSystems[panelName].Insert(system); } n = mapPanelToSystems.Count; //Debug.WriteLine( string.Format( "Mapping from the {0} panel{1} to systems, system name :circuit name(connectors/unused connectors):", n, Util.PluralSuffix( n ) ) ); Debug.WriteLine(string.Format("Mapping from the {0} panel{1} to electrical systems == circuits:", n, Util.PluralSuffix(n))); List <string> keys = new List <string>(mapPanelToSystems.Keys); keys.Sort(); string s; foreach (string panelName in keys) { s = string.Empty; foreach (ElectricalSystem system in mapPanelToSystems[panelName]) { ConnectorManager cmgr = system.ConnectorManager; // the connector manager does not include any logical connectors // in the Revit 2009 fcs and wu1 API, only physical ones: //Debug.Assert( 0 == cmgr.Connectors.Size, // "electrical connector count is always zero" ); Debug.Assert(cmgr.UnusedConnectors.Size <= cmgr.Connectors.Size, "unused connectors is a subset of connectors"); Debug.Assert(system.Name.Equals(system.CircuitNumber), "ElectricalSystem Name and CircuitNumber properties are always identical"); //s += ( 0 < s.Length ? ", " : ": " ) + system.Name; s += (0 < s.Length ? ", " : ": ") + system.Name // + ":" + system.CircuitNumber + "(" + cmgr.Connectors.Size.ToString() + "/" + cmgr.UnusedConnectors.Size.ToString() + ")"; } Debug.WriteLine(" " + panelName + s); } /* * Debug.WriteLine( "Mapping from panels to systems to connected elements:" ); * foreach( string panelName in keys ) * { * Debug.WriteLine( " panel " + panelName + ":" ); * foreach( ElectricalSystem system in mapPanelToSystems[panelName] ) * { * ConnectorManager cmgr = system.ConnectorManager; * n = cmgr.Connectors.Size; * Debug.WriteLine( string.Format( " system {0} has {1} connector{2}{3}", system.Name, n, Util.PluralSuffix( n ), Util.DotOrColon( n ) ) ); * foreach( Connector connector in system.ConnectorManager.Connectors ) * { * Element owner = connector.Owner; * Debug.WriteLine( string.Format( " owner {0} {1}, domain {2}", owner.Name, owner.Id.IntegerValue, connector.Domain ) ); * } * } * } */ // // list all circuit elements: // // this captures all elements in circuits H-2: 2, 4, 6 etc, // but not the element T2 in H-2:1,3,5, because it has no circuit number, // just a panel number. // 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}{2}", n, Util.PluralSuffix(n), Util.DotOrColon(n))); Dictionary <string, List <Element> > mapPanelAndCircuitToElements = new Dictionary <string, List <Element> >(); foreach (Element e in circuitElements) { string circuitName = e.get_Parameter(bipCircuit).AsString(); // // do not map an electrical system to itself: // if (!(e is ElectricalSystem && e.Name.Equals(circuitName))) { string panelName = e.get_Parameter(bipPanel).AsString(); string key = panelName + ":" + circuitName; Debug.WriteLine(string.Format(" {0} <{1} {2}> panel:circuit {3}", e.GetType().Name, e.Name, e.Id.IntegerValue, key)); if (!mapPanelAndCircuitToElements.ContainsKey(key)) { mapPanelAndCircuitToElements.Add(key, new List <Element>()); } mapPanelAndCircuitToElements[key].Add(e); } } n = mapPanelAndCircuitToElements.Count; Debug.WriteLine(string.Format("Mapped circuit elements to {0} panel:circuit{1}{2}", n, Util.PluralSuffix(n), Util.DotOrColon(n))); keys.Clear(); keys.AddRange(mapPanelAndCircuitToElements.Keys); keys.Sort(new PanelCircuitComparer()); foreach (string panelAndCircuit in keys) { List <string> a = new List <string>(mapPanelAndCircuitToElements[panelAndCircuit].Count); foreach (Element e in mapPanelAndCircuitToElements[panelAndCircuit]) { FamilyInstance inst = e as FamilyInstance; a.Add((null == inst ? e.Category.Name : inst.Symbol.Family.Name) + " " + e.Name); } a.Sort(); s = string.Join(", ", a.ToArray()); Debug.WriteLine(" " + panelAndCircuit + ": " + s); } #region Aborted attempt to use RBS_ELEC_CIRCUIT_PANEL_PARAM #if USE_RBS_ELEC_CIRCUIT_PANEL_PARAM // // list all panel elements: // // selecting all elements with a BuiltInParameter.RBS_ELEC_CIRCUIT_NUMBER // captures all elements in circuits H-2: 2, 4, 6 etc, but not the element // T2 in H-2:1,3,5, because it has no circuit number, just a panel number. // // so grab everything with a panel number instead. // // all this added to the selection was lots of wires, so forget it again. // BuiltInParameter bipCircuit = BuiltInParameter.RBS_ELEC_CIRCUIT_NUMBER; BuiltInParameter bipPanel = BuiltInParameter.RBS_ELEC_CIRCUIT_PANEL_PARAM; List <Element> circuitElements = new List <Element>(); Util.GetElementsWithParameter(circuitElements, bipPanel, app); n = circuitElements.Count; Debug.WriteLine(string.Format("Retrieved {0} circuit element{1}{2}", n, Util.PluralSuffix(n), Util.DotOrColon(n))); Dictionary <string, List <Element> > mapCircuitToElements = new Dictionary <string, List <Element> >(); foreach (Element e in circuitElements) { string panelName = e.get_Parameter(bipPanel).AsString(); Parameter p = e.get_Parameter(bipCircuit); if (null == p) { Debug.WriteLine(string.Format(" {0} <{1} {2}> panel:circuit {3}:null", e.GetType().Name, e.Name, e.Id.IntegerValue, panelName)); } else { string circuitName = p.AsString(); // // do not map an electrical system to itself: // if (!(e is ElectricalSystem && e.Name.Equals(circuitName))) { string key = panelName + ":" + circuitName; Debug.WriteLine(string.Format(" {0} <{1} {2}> panel:circuit {3}", e.GetType().Name, e.Name, e.Id.IntegerValue, key)); if (!mapCircuitToElements.ContainsKey(key)) { mapCircuitToElements.Add(key, new List <Element>()); } mapCircuitToElements[key].Add(e); } } } n = mapCircuitToElements.Count; Debug.WriteLine(string.Format("Mapped circuit elements to {0} panel:circuit{1}{2}", n, Util.PluralSuffix(n), Util.DotOrColon(n))); keys.Clear(); keys.AddRange(mapCircuitToElements.Keys); keys.Sort(new PanelCircuitComparer()); foreach (string circuitName in keys) { List <string> a = new List <string>(mapCircuitToElements[circuitName].Count); foreach (Element e in mapCircuitToElements[circuitName]) { FamilyInstance inst = e as FamilyInstance; a.Add((null == inst ? e.Category.Name : inst.Symbol.Family.Name) + " " + e.Name); } a.Sort(); s = string.Join(", ", a.ToArray()); Debug.WriteLine(" " + circuitName + ": " + s); } #endif // USE_RBS_ELEC_CIRCUIT_PANEL_PARAM #endregion // Aborted attempt to use RBS_ELEC_CIRCUIT_PANEL_PARAM // // merge the two trees of equipment and circuit elements // to reproduce the content of the system browser ... the // hardest part of this is setting up the PanelSystemComparer // to generate the same sort order as the system browser: // //n = mapPanelAndSystemToEquipment.Count + mapPanelAndCircuitToElements.Count; //Dictionary<string, List<Element>> mapSystemBrowser = new Dictionary<string, List<Element>>( n ); Dictionary <string, List <Element> > mapSystemBrowser = new Dictionary <string, List <Element> >(mapPanelAndCircuitToElements); foreach (KeyValuePair <string, List <Element> > pair in mapPanelAndSystemToEquipment) { mapSystemBrowser[pair.Key] = pair.Value; } n = mapSystemBrowser.Count; Debug.WriteLine(string.Format("Mapped equipment + circuit elements to {0} panel:system{1}{2}", n, Util.PluralSuffix(n), Util.DotOrColon(n))); keys.Clear(); keys.AddRange(mapSystemBrowser.Keys); keys.Sort(new PanelSystemComparer()); foreach (string panelAndSystem in keys) { List <string> a = new List <string>(mapSystemBrowser[panelAndSystem].Count); foreach (Element e in mapSystemBrowser[panelAndSystem]) { a.Add(Util.BrowserDescription(e)); } a.Sort(); s = string.Join(", ", a.ToArray()); Debug.WriteLine(string.Format(" {0}({1}): ", panelAndSystem, a.Count) + s); } // // get the electrical equipment category id: // Categories categories = doc.Settings.Categories; ElementId electricalEquipmentCategoryId = categories.get_Item(BuiltInCategory.OST_ElectricalEquipment).Id; // // we have assembled the required information and structured it // sufficiently for the tree view, so now let us go ahead and display it: // CmdInspectElectricalForm dialog = new CmdInspectElectricalForm(mapSystemBrowser, electricalEquipmentCategoryId, populateFullHierarchy); dialog.Show(); return(Result.Succeeded); } catch (Exception ex) { message = ex.Message; return(Result.Failed); } }