主题:操作电源电路。

摘要:此示例显示如何操作电源电路。

项目文件:

Command.cs

它包含从接口IExternalCommand继承和实现Execute方法的类Command

CircuitOperationData.cs

存储操作电路信息的数据类。

CircuitOperationForm.cs

它包含对话框,提供操作电路的选项。

ElectricalSystemItem.cs

该类用于在电路选择对话框中显示电气系统。一个电气系统项包含一个电气系统的名称和id 

EditCircuitForm.cs

它包含对话框,提供编辑电路的选项。 

SelectCircuitForm.cs

它包含一个对话框,允许用户选择要操作的电路。 

Enum.cs

此文件包含两个枚举。

-操作枚举列出了操作电路的选项。

-EditOption枚举列出了编辑电路的选项。

描述:

此示例提供以下功能。

-让用户使用选定的元素创建电源电路。这些元素应在同一电压定义和相同极数的未使用电气连接器中。

-让用户编辑电源电路。

-让用户向电路添加元素。这些元素应在同一电压定义和相同极数的未使用电气连接器中。

-让用户从电路中移除元素。

-让用户为电路选择面板。

-如果电路有面板,则让用户从电路中断开面板。

说明:

打开或新建一个Revit项目,并确保放置了所需的电气元素。示例项目文件PowerCircuit.rvt在示例文件夹中可用。然后执行命令。

1.创建电源电路

a. 选择在当前项目中具有未使用电气连接器的相同电压定义和相同极数的元素。

b. 执行命令。

c. 单击按钮

预期结果:使用选定的元素创建电源电路并进行突出显示。

注意:1.当前在API中没有很好的方法来检查连接器是否具有相同的电压定义或极数,因此示例会跳过验证此信息并仅在创建失败时提供消息。用户必须清楚选择的元素的电压和极数是否匹配。2.在此示例中,不允许使用全部是照明设备的元素创建电源电路。

2.编辑电源电路。

a. 选择属于一个或多个电路的电源电路或元素。

b. 执行命令。

c. 单击按钮

d. 如果所选元素属于多个电源电路,请从其电路中选择要编辑的电路在“选择电路”对话框中。如果没有,则转到下一步。

e. 在“编辑电路”对话框中选择编辑电路的选项。

-单击按钮以将元素添加到电路。然后选择具有与其他电路元素相同的未使用电气连接器的元素。出于与步骤1中注释相同的原因,示例跳过验证电压和极数,并在创建失败时提供消息。

预期结果:所选元素已添加到电路并突出显示电路。

-单击按钮以从电路中删除元素。然后选择要删除的元素。

预期结果:所选元素已从电路中移除并突出显示电路。

-单击按钮以为电路选择面板。与步骤3相同。

3.为电路选择面板。

a. 选择属于一个或多个电路的电源电路或元素。

b. 执行命令。

c. 单击按钮以为电路选择面板。

d. 如果所选元素属于多个电源电路,请从其电路中选择要编辑的电路在“选择电路”对话框中。如果没有,则转到下一步。

e. 选择一个面板以将其分配给电路。面板必须分配到与其他电路元素相同电压定义的分配系统。此外,面板必须具有与其他电路元素相同的极数。出于与步骤1中注释相同的原因,示例跳过验证电压和极数,并在创建失败时提供消息。

预期结果:所选面板分配给电路并突出显示电路。

4.从电路断开面板。

a. 选择属于一个或多个电路的电源电路或元素。

b. 执行命令。

c. 单击按钮以从电路中断开面板。

d. 如果所选元素属于多个电源电路,请从其电路中选择要编辑的电路在“选择电路”对话框中。如果没有,则转到下一步。

预期结果:电路的面板已从电路中移除并突出显示电路。

完整的源代码请加入QQ群649037449,在群文件中下载RevitSDK.exe,解压后在文件夹中搜索本文中应用程序名称即可获得完整源码

CircuitOperationData.cs

//
// (C) Copyright 2003-2019 by Autodesk, Inc.
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted,
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to
// restrictions set forth in FAR 52.227-19 (Commercial Computer
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
// (Rights in Technical Data and Computer Software), as applicable.
//

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;

using Autodesk.Revit;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB.Electrical;
using Autodesk.Revit.UI.Selection;

namespace Revit.SDK.Samples.PowerCircuit.CS
{
/// <summary>
/// Data class which stores the information of electrical circuit operation
/// </summary>
public class CircuitOperationData
{
#region Fields

/// <summary>
/// Active document of Revit
/// </summary>
UIDocument m_revitDoc;

/// <summary>
/// Selection of active document
/// </summary>
Selection m_selection;

/// <summary>
/// Operation on selected elements
/// </summary>
private Operation m_operation;

/// <summary>
/// Option of editing circuit
/// </summary>
private EditOption m_editOption;

/// <summary>
/// Whether new circuit can be created with selected elements
/// </summary>
private bool m_canCreateCircuit;

/// <summary>
/// Whether there is a circuit in selected elements
/// </summary>
private bool m_hasCircuit;

/// <summary>
/// Whether the circuit in selected elements has panel
/// </summary>
private bool m_hasPanel;

/// <summary>
/// All electrical systems contain selected element
/// </summary>
private ElectricalSystemSet m_electricalSystemSet;

/// <summary>
/// All electrical system items which will be displayed in circuit selecting form
/// </summary>
private List<ElectricalSystemItem> m_electricalSystemItems;

/// <summary>
/// The electrical system chosen to operate
/// </summary>
private ElectricalSystem m_selectedElectricalSystem;

#endregion

#region Properties
/// <summary>
/// Operation type
/// </summary>
public Operation Operation
{
get
{
return m_operation;
}

set
{
m_operation = value;
}
}

/// <summary>
/// Get the information whether new circuit can be created
/// </summary>
public bool CanCreateCircuit
{
get
{
return m_canCreateCircuit;
}
}

/// <summary>
/// Get the value of whether there are circuits in selected elements
/// </summary>
public bool HasCircuit
{
get
{
return m_hasCircuit;
}
}

/// <summary>
/// Get the information whether the circuit in selected elements has panel
/// </summary>
public bool HasPanel
{
get
{
return m_hasPanel;
}
}

/// <summary>
/// Edit options
/// </summary>
public EditOption EditOption
{
get
{
return m_editOption;
}
set
{
m_editOption = value;
}
}

/// <summary>
/// All electrical system items which will be displayed in circuit selecting form
/// </summary>
public ReadOnlyCollection<ElectricalSystemItem> ElectricalSystemItems
{
get
{
foreach (ElectricalSystem es in m_electricalSystemSet)
{
ElectricalSystemItem esi = new ElectricalSystemItem(es);
m_electricalSystemItems.Add(esi);
}

return new ReadOnlyCollection<ElectricalSystemItem>(m_electricalSystemItems);
}
}

/// <summary>
/// Number of electrical systems contain selected elements
/// </summary>
public int ElectricalSystemCount
{
get
{
return m_electricalSystemSet.Size;
}
}
#endregion

#region Methods
/// <summary>
/// Constructor
/// </summary>
/// <param name="commandData">Revit's external commandData</param>
public CircuitOperationData(ExternalCommandData commandData)
{
m_revitDoc = commandData.Application.ActiveUIDocument;
m_selection = m_revitDoc.Selection;

m_electricalSystemSet = new ElectricalSystemSet();
m_electricalSystemItems = new List<ElectricalSystemItem>();

CollectConnectorInfo();
CollectCircuitInfo();
}

/// <summary>
/// Verify if all selected elements have unused connectors
/// </summary>
private void CollectConnectorInfo()
{
m_canCreateCircuit = true;
// Flag to check if all selected elements are lighting devices
bool allLightingDevices = true;

foreach (ElementId elementId in m_selection.GetElementIds())
{
Element element = m_revitDoc.Document.GetElement(elementId);
FamilyInstance fi = element as FamilyInstance;
if (null == fi)
{
m_canCreateCircuit = false;
return;
}

if (!String.Equals(fi.Category.Name, "Lighting Devices"))
{
allLightingDevices = false;
}

// Verify if the family instance has usable connectors
if (!VerifyUnusedConnectors(fi))
{
m_canCreateCircuit = false;
return;
}
}

if (allLightingDevices)
{
m_canCreateCircuit = false;
}
}

/// <summary>
/// Verify if the family instance has usable connectors
/// </summary>
/// <param name="fi">The family instance to be verified</param>
/// <returns>True if the family instance has usable connecotors,
/// otherwise false</returns>
static private bool VerifyUnusedConnectors(FamilyInstance fi)
{
bool hasUnusedElectricalConnector = false;
try
{
MEPModel mepModel = fi.MEPModel;
if (null == mepModel)
{
return hasUnusedElectricalConnector;
}

ConnectorManager cm = mepModel.ConnectorManager;
ConnectorSet unusedConnectors = cm.UnusedConnectors;
if (null == unusedConnectors || unusedConnectors.IsEmpty)
{
return hasUnusedElectricalConnector;
}

foreach (Connector connector in unusedConnectors)
{
if (connector.Domain == Domain.DomainElectrical)
{
hasUnusedElectricalConnector = true;
break;
}
}
}
catch (Exception)
{
return hasUnusedElectricalConnector;
}

return hasUnusedElectricalConnector;
}

/// <summary>
/// Get common circuits contain all selected elements
/// </summary>
private void CollectCircuitInfo()
{
//bool isElectricalSystem = false;

bool bInitilzedElectricalSystemSet = false;

//
// Get common circuits of selected elements
//
ElectricalSystem tempElectricalSystem = null;
foreach (ElementId elementId in m_selection.GetElementIds())
{
Element element = m_revitDoc.Document.GetElement(elementId);
FamilyInstance fi = element as FamilyInstance;
MEPModel mepModel;
ElectricalSystemSet ess;

if (fi != null && (mepModel = fi.MEPModel) != null)
{
//
// If the element is a family instance and its MEP model is not null,
// retrieve its circuits
// Then compare the circuits with circuits of other selected elements
// to get the common ones
//

// Get all electrical systems
ess = mepModel.ElectricalSystems;
if (null == ess)
{
m_hasCircuit = false;
m_hasPanel = false;
return;
}

// Remove systems which are not power circuits
foreach (ElectricalSystem es in ess)
{
if (es.SystemType != ElectricalSystemType.PowerCircuit)
{
ess.Erase(es);
}
}

if (ess.IsEmpty)
{
m_hasCircuit = false;
m_hasPanel = false;
return;
}

// If m_electricalSystemSet is not set before, set it
// otherwise compare the circuits with circuits of other selected elements
// to get the common ones
if (!bInitilzedElectricalSystemSet)
{
m_electricalSystemSet = ess;
bInitilzedElectricalSystemSet = true;
continue;
}
else
{
foreach (ElectricalSystem es in m_electricalSystemSet)
{
if (!ess.Contains(es))
{
m_electricalSystemSet.Erase(es);
}
}

if (m_electricalSystemSet.IsEmpty)
{
m_hasCircuit = false;
m_hasPanel = false;
return;
}
}
}
else if ((tempElectricalSystem = element as ElectricalSystem) != null)
{
//
// If the element is an electrical system, verify if it is a power circuit
// If not, compare with circuits of other selected elements
// to get the common ones
//
//verify if it is a power circuit
if (tempElectricalSystem.SystemType != ElectricalSystemType.PowerCircuit)
{
m_hasCircuit = false;
m_hasPanel = false;
return;
}

// If m_electricalSystemSet is not set before, set it
// otherwise compare with circuits of other selected elements
// to get the common ones
if (!bInitilzedElectricalSystemSet)
{
m_electricalSystemSet.Insert(tempElectricalSystem);
bInitilzedElectricalSystemSet = true;
continue;
}

if (!m_electricalSystemSet.Contains(tempElectricalSystem))
{
m_hasCircuit = false;
m_hasPanel = false;
return;
}

m_electricalSystemSet.Clear();
m_electricalSystemSet.Insert(tempElectricalSystem);
}
else
{
m_hasCircuit = false;
m_hasPanel = false;
return;
}
}

// Verify if there is any common power circuit
if (!m_electricalSystemSet.IsEmpty)
{
m_hasCircuit = true;
if (m_electricalSystemSet.Size == 1)
{
foreach (ElectricalSystem es in m_electricalSystemSet)
{
m_selectedElectricalSystem = es;
break;
}
}

foreach (ElectricalSystem es in m_electricalSystemSet)
{
if (!String.IsNullOrEmpty(es.PanelName))
{
m_hasPanel = true;
break;
}
}
}
}

/// <summary>
/// Dispatch operations
/// </summary>
public void Operate()
{
Transaction transaction = new Transaction(m_revitDoc.Document, m_operation.ToString());
transaction.Start();
switch (m_operation)
{
case Operation.CreateCircuit:
CreatePowerCircuit();
break;
case Operation.EditCircuit:
EditCircuit();
break;
case Operation.SelectPanel:
SelectPanel();
break;
case Operation.DisconnectPanel:
DisconnectPanel();
break;
default:
break;
}
transaction.Commit();

// Select the modified circuit
if (m_operation != Operation.CreateCircuit)
{
SelectCurrentCircuit();
}
}

/// <summary>
/// Create a power circuit with selected elements
/// </summary>
public void CreatePowerCircuit()
{
List<ElementId> selectionElementId = new List<ElementId>();
ElementSet elements = new ElementSet();
foreach (ElementId elementId in m_selection.GetElementIds())
{
elements.Insert(m_revitDoc.Document.GetElement(elementId));
}

foreach (Element e in elements)
{
selectionElementId.Add(e.Id);
}

try
{
// Creation
ElectricalSystem es = ElectricalSystem.Create(m_revitDoc.Document, selectionElementId, ElectricalSystemType.PowerCircuit);

// Select the newly created power system
m_selection.GetElementIds().Clear();
m_selection.GetElementIds().Add(es.Id);
}
catch (Exception)
{
ShowErrorMessage("FailedToCreateCircuit");
}
}

/// <summary>
/// Dispatch operations of editing circuit
/// </summary>
public void EditCircuit()
{
switch (m_editOption)
{
case EditOption.Add:
AddElementToCircuit();
break;
case EditOption.Remove:
RemoveElementFromCircuit();
break;
case EditOption.SelectPanel:
SelectPanel();
break;
default:
break;
}

}

/// <summary>
/// Add an element to circuit
/// </summary>
public void AddElementToCircuit()
{
// Clear selection before selecting the panel
m_selection.GetElementIds().Clear();
// Interact with UI to select a panel
if (m_revitDoc.Selection.PickObject(ObjectType.Element) == null)
{
return;
}

//
// Verify if the selected element can be added to the circuit
//

// Get selected element
Element selectedElement = null;
foreach (ElementId elementId in m_selection.GetElementIds())
{
Element element = m_revitDoc.Document.GetElement(elementId);
selectedElement = element;
}

// Get the MEP model of selected element
MEPModel mepModel = null;
FamilyInstance fi = selectedElement as FamilyInstance;
if (null == fi || null == (mepModel = fi.MEPModel))
{
ShowErrorMessage("SelectElectricalComponent");
return;
}

// Verify if the element has usable connector
if (!VerifyUnusedConnectors(fi))
{
ShowErrorMessage("NoUsableConnector");
return;
}

if (IsElementBelongsToCircuit(mepModel, m_selectedElectricalSystem))
{
ShowErrorMessage("ElementInCircuit");
return;
}

try
{
ElementSet es = new ElementSet();
foreach (ElementId elementId in m_selection.GetElementIds())
{
es.Insert(m_revitDoc.Document.GetElement(elementId));
}
if (!m_selectedElectricalSystem.AddToCircuit(es))
{
ShowErrorMessage("FailedToAddElement");
return;
}
}
catch (Exception)
{
ShowErrorMessage("FailedToAddElement");
}
}

/// <summary>
/// Remove an element from selected circuit
/// </summary>
public void RemoveElementFromCircuit()
{
// Clear selection before selecting the panel
m_selection.GetElementIds().Clear();
// Interact with UI to select a panel
if (m_revitDoc.Selection.PickObject(ObjectType.Element) == null)
{
return;
}

// Get the selected element
Element selectedElement = null;
foreach (ElementId elementId in m_revitDoc.Selection.GetElementIds())
{
Element element = m_revitDoc.Document.GetElement(elementId);
selectedElement = element;
}

// Get the MEP model of selected element
MEPModel mepModel = null;
FamilyInstance fi = selectedElement as FamilyInstance;
if (null == fi || null == (mepModel = fi.MEPModel))
{
ShowErrorMessage("SelectElectricalComponent");
return;
}

// Check whether the selected element belongs to the circuit
if (!IsElementBelongsToCircuit(mepModel, m_selectedElectricalSystem))
{
ShowErrorMessage("ElementNotInCircuit");
return;
}

try
{
// Remove the selected element from circuit
ElementSet es = new ElementSet();
foreach (ElementId elementId in m_revitDoc.Selection.GetElementIds())
{
es.Insert(m_revitDoc.Document.GetElement(elementId));
}
m_selectedElectricalSystem.RemoveFromCircuit(es);
}
catch (Exception)
{
ShowErrorMessage("FailedToRemoveElement");
}
}

static private bool IsElementBelongsToCircuit(MEPModel mepModel,
ElectricalSystem selectedElectricalSystem)
{
ElectricalSystemSet ess = mepModel.ElectricalSystems;
if (null == ess || !ess.Contains(selectedElectricalSystem))
{
return false;
}

return true;
}

/// <summary>
/// Select a panel for selected circuit
/// </summary>
public void SelectPanel()
{
// Clear selection before selecting the panel
m_selection.GetElementIds().Clear();

// Interact with UI to select a panel
if (m_revitDoc.Selection.PickObject(ObjectType.Element) == null)
{
return;
}

try
{
FamilyInstance fi;
foreach (ElementId elementId in m_selection.GetElementIds())
{
Element element = m_revitDoc.Document.GetElement(elementId);
fi = element as FamilyInstance;
if (fi != null)
{
m_selectedElectricalSystem.SelectPanel(fi);
}
}
}
catch (Exception)
{
ShowErrorMessage("FailedToSelectPanel");
}
}

/// <summary>
/// Disconnect panel for selected circuit
/// </summary>
public void DisconnectPanel()
{
try
{
m_selectedElectricalSystem.DisconnectPanel();
}
catch (Exception)
{
ShowErrorMessage("FailedToDisconnectPanel");
}
}

/// <summary>
/// Get selected index from circuit selecting form and locate expected circuit
/// </summary>
/// <param name="index">Index of selected item in circuit selecting form</param>
public void SelectCircuit(int index)
{
// Locate ElectricalSystemItem by index
ElectricalSystemItem esi = m_electricalSystemItems[index] as ElectricalSystemItem;
Autodesk.Revit.DB.ElementId ei = esi.Id;

// Locate expected electrical system
m_selectedElectricalSystem = m_revitDoc.Document.GetElement(ei) as ElectricalSystem;
// Select the electrical system
SelectCurrentCircuit();
}

/// <summary>
/// Select created/modified/selected electrical system
/// </summary>
public void SelectCurrentCircuit()
{
m_selection.GetElementIds().Clear();
m_selection.GetElementIds().Add(m_selectedElectricalSystem.Id);
}

/// <summary>
/// Get selected index from circuit selecting form and show the circuit in the center of
/// screen by moving the view.
/// </summary>
/// <param name="index">Index of selected item in circuit selecting form</param>
public void ShowCircuit(int index)
{
ElectricalSystemItem esi = m_electricalSystemItems[index] as ElectricalSystemItem;
Autodesk.Revit.DB.ElementId ei = esi.Id;
m_revitDoc.ShowElements(ei);
}

/// <summary>
/// Show message box with specified string
/// </summary>
/// <param name="message">specified string to show</param>
static private void ShowErrorMessage(String message)
{
TaskDialog.Show(Properties.Resources.ResourceManager.GetString("OperationFailed"), Properties.Resources.ResourceManager.GetString(message), TaskDialogCommonButtons.Ok);
}
#endregion
}
}

完整的源代码请加入QQ群649037449,在群文件中下载RevitSDK.exe,解压后在文件夹中搜索本文中应用程序名称即可获得完整源码

ElectricalSystemItem.cs

//
// (C) Copyright 2003-2019 by Autodesk, Inc.
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted,
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to
// restrictions set forth in FAR 52.227-19 (Commercial Computer
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
// (Rights in Technical Data and Computer Software), as applicable.
//
using System;
using System.Collections.Generic;
using System.Text;
using Autodesk.Revit;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Electrical;
namespace Revit.SDK.Samples.PowerCircuit.CS
{
    /// <summary>
    /// An electrical system item contains the name and id of an electrical system. 
    /// The class is used for displaying electrical systems in circuit selecting form.
    /// </summary>
    public class ElectricalSystemItem
    {
        /// <summary>
        /// Name of an electrical system
        /// </summary>
        private String m_name;
        /// <summary>
        /// Id of an electrical system
        /// </summary>
        private Autodesk.Revit.DB.ElementId m_id;
        /// <summary>
        /// Id of an electrical system
        /// </summary>
        public Autodesk.Revit.DB.ElementId Id
        {
            get
            {
                return m_id;
            }
        }
        /// <summary>
        /// Name of an electrical system
        /// </summary>
        public String Name
        {
            get
            {
                return m_name;
            }
        }
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="es"></param>
        public ElectricalSystemItem(ElectricalSystem es)
        {
            m_name = es.Name;
            m_id = es.Id;
        }
    };
}