七、revit中元素的获取方法

  • 信息的获取
    1.得到信息的载体
    2.读取信息

7.1得到信息的载体

  • 在revit中信息的载体用element这个类来表示
  • Element元素:ElementType(元素类型)、Family(族)、FamilyInstance(族实例)、HostObject(宿主对象)、其他
  • ElementType(元素类型)包括:FamilySymbol(族类型)、WallType(墙类型)
  • FamilyInstance(族实例)包括:Window(窗)、Column(柱)、Beam(梁),族实例都是由标准族和可载入族生成
  • HostObject(宿主对象)包括:Wall(墙)、Floor(楼板)、MEPcurve,宿主对象都是由系统族生成

7.2获取元素

1.直接选取

using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GetInformation
{
    [Transaction(TransactionMode.ReadOnly)] //事件
    public class Information : IExternalCommand  //实现接口

    {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            //通过commandData获取UIDocument
            UIDocument uidoc = commandData.Application.ActiveUIDocument;
            //通过uidoc获取revit当前文档
            Document doc = uidoc.Document;
            //在revit当前文档下,进行选择元素的操作
            var reference = uidoc.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element);
            //获取直接选择的这个元素
            var element = doc.GetElement(reference.ElementId);
            //对所选择的元素进行类型转换(或者可以理解成指定获取元素的类别,比如:墙、楼板、屋顶等等)
            var wall = element as Wall;
            return Result.Succeeded;
        }
    }
}

但是在revit中运行的时候,如果没有选择元素,那么revit会抛出一个OperationCanceledExecption(用户取消了选择操作)异常。为了消除这个异常,可以修改代码如下:

using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GetInformation
{
    [Transaction(TransactionMode.ReadOnly)] //事件
    public class Information : IExternalCommand  //实现接口

    {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            //通过commandData获取UIDocument
            UIDocument uidoc = commandData.Application.ActiveUIDocument;
            //通过uidoc获取revit当前文档
            Document doc = uidoc.Document;
            try
            {
                //在revit当前文档下,进行选择元素的操作
                var reference = uidoc.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element);
                //获取直接选择的这个元素
                var element = doc.GetElement(reference.ElementId);
                //对所选择的元素进行类型转换(或者可以理解成指定获取元素的类别,比如:墙、楼板、屋顶等等)
                var wall = element as Wall;
            }
            catch (Autodesk.Revit.Exceptions.OperationCanceledException e) //注意,这里的OperationCanceledException一定要选用revit下的,而不能用system自带的
            {

            }                       
            return Result.Succeeded;
        }
    }
}

但是这里又出现一个新的问题,用户在选择的时候,不一定是专业人员,选的不一定是墙这种类型,按照上面的代码虽然指定了获取元素的类别为wall,但是在revit中实际操作的时候,选择别的东西比如植物或者屋顶,也不会任何异常。那如何,才能解决这个问题呢。其实可以让用户在实际操作的时候只能选择wall其他东西选不中,这样就解决了这个问题。

选择这个功能主要是通过PickObject方法来实现的,我们F12查看其定义,其有多个重载,这代表方法名一样,参数定义不一样。

PickObject有四个函数名一样的方法,但是它们的参数定义不一样

public Reference PickObject(ObjectType objectType);
public Reference PickObject(ObjectType objectType, string statusPrompt);//string statusPrompt就是一句提示语,提示怎么样操作,选择什么东西
public Reference PickObject(ObjectType objectType, ISelectionFilter selectionFilter);//ISelectionFilter接口实际上就是 一个选择过滤器,我们可以通过这个接口来定制选择条件
public Reference PickObject(ObjectType objectType, ISelectionFilter selectionFilter, string statusPrompt);//
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GetInformation
{
    [Transaction(TransactionMode.ReadOnly)] //事件
    public class Information : IExternalCommand  //实现接口

    {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            //通过commandData获取UIDocument
            UIDocument uidoc = commandData.Application.ActiveUIDocument;
            //通过uidoc获取revit当前文档
            Document doc = uidoc.Document;
            try
            {
                //新建一个wallFilter对象(或者叫实例化WallSelectionFilter类)
                var wallFilter = new WallSelectionFilter();
                //在revit当前文档下,进行选择元素的操作
                var reference = uidoc.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element,wallFilter);
                //获取直接选择的这个元素
                var element = doc.GetElement(reference.ElementId);
                //对所选择的元素进行类型转换(或者可以理解成指定获取元素的类别,比如:墙、楼板、屋顶等等)
                var wall = element as Wall;                
            }
            catch (Autodesk.Revit.Exceptions.OperationCanceledException e) //注意,这里的OperationCanceledException一定要选用revit下的,而不能用system自带的
            {

            }                       
            return Result.Succeeded;
        }
        public class WallSelectionFilter : ISelectionFilter  //新建一个WallSelectionFilter类,实现ISelectionFilter接口
        {
            public bool AllowElement(Element elem)  //方法:允许什么样的元素
            {
                //通过指定元素的category来,确定哪些元素被选择
                if (elem.Category.Id.IntegerValue == (int)BuiltInCategory.OST_Walls) //如果他的ID对应的整型数值等于revit中墙的内置枚举类型参数的数值(这里需要强制转换为int类型)
                {
                    return true;
                }
                else return false;
            }

            public bool AllowReference(Reference reference, XYZ position)  //方法:是否允许引用
            {
                return false;  //设置为不允许
            }
        }
    }
}

2.通过ID获取

这里可以有三种方法获取ID

  • 第一种:通过调试代码来获取
    对代码加上断点-点击调试-附加到进程-选择revit-设置成自动托管模式并确认-打开revit外部工具-运行我们载入的程序-界面会自动跳转到vs2019的代码调试界面,并且到打的断点的这个位置停下来-摁下F10逐过程的运行-不断的下一步-到选择的是否会自动切换到revit界面-鼠标选择中你想要的墙体,选择完毕后又会自动切换到vs2019代码界面-这个时候把鼠标移动至ElementId-就会显现出你选中墙体的ID值,这里显示为428745。
    这样在已知要获取的元素墙的ID为428745的条件下,如何通过代码在revit中直接选取到这面墙呢?
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GetInformation
{
    [Transaction(TransactionMode.ReadOnly)] //事件
    public class Information : IExternalCommand  //实现接口

    {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            //通过commandData获取UIDocument
            UIDocument uidoc = commandData.Application.ActiveUIDocument;
            //通过uidoc获取revit当前文档
            Document doc = uidoc.Document;
            try
            {
                //新建一个wallFilter对象(或者叫实例化WallSelectionFilter类)
                var wallFilter = new WallSelectionFilter();
                //将元素ID为428745的元素添加到选择集里面
                uidoc.Selection.SetElementIds(new List<ElementId> { new ElementId(428745) });               
            }
            catch (Autodesk.Revit.Exceptions.OperationCanceledException e) //注意,这里的OperationCanceledException一定要选用revit下的,而不能用system自带的
            {

            }                       
            return Result.Succeeded;
        }
        public class WallSelectionFilter : ISelectionFilter  //新建一个WallSelectionFilter类,实现ISelectionFilter接口
        {
            public bool AllowElement(Element elem)  //方法:允许什么样的元素
            {
                //通过指定元素的category来,确定哪些元素被选择
                if (elem.Category.Id.IntegerValue == (int)BuiltInCategory.OST_Walls) //如果他的ID对应的整型数值等于revit中墙的内置枚举类型参数的数值(这里需要强制转换为int类型)
                {
                    return true;
                }
                else return false;
            }

            public bool AllowReference(Reference reference, XYZ position)  //方法:是否允许引用
            {
                return false;  //设置为不允许
            }
        }
    }
}
  • 第二种:可以在revit中使用其自带的功能-先选择墙-然后点击管理-点击选择项的ID,就会出现其ID值
  • 第三种:使用revitlookup插件查询-点击revitlookup-点击snoop current selection-查看ID