感叹一下,学编程有些概念刚接触真的挺抽象,碰到这种情况只能先把方法用起来,后面再回头总结归纳下。
下面是《AUTODESK REVIT二次开发基础教程》这本书中列出的的部分重要继承于Element的子类,完整的继承类要查阅RevitAPI.dll,刚看时很懵,完全搞不懂它们之间的关系,刚学不用死记硬背,记住 元素Element、族Family、族类型ElementType、族实例Instance。
一 元素Element
一句话总结就是相当于C#中的Object。Object会提供一些如ToString(),Equals()之类的共通方法。Element也同理,会提供诸如Category(类别)、Geometry(几何)、Location(定位)、Parameters(参数)、Id等共通属性或参数。
二 族、元素类型、实例
上面提到父类Element提供共通的属性和方法。而族Family在继承Element的基础上演化出自己独有的属性和方法,元素类型ElementType你可以理解而同族同个属性不同的数值差异。(其实这样理解不完全正确,两种族可能除了名字外它们的可能在属性和方法没什么差别,这主要决定于Revit要不要实现这个族的特殊属性,有时只取个名字简单区分一下,目前没想到更简练的语言总结。)
以防火门和防爆门举例子,防火门具有防火等级的属性,但它不需要防爆门的防爆属性,防爆门具有抗爆的属性,能承受多大的冲击波是它的区别于防火门的属性。于是我们就衍生出防火门和防爆门两种族Family,(同上,Revit不一定会实现防爆和防火两个属性,可能只是取个名字区分下。)
继续以防火门为例,防火门可能有各种不同的尺寸,于是衍生不不同尺寸的元素类型(ElementType)ElementType。
实例Instance可以理解为C#中的实例化概念。
下图ElementType(元素类型)衍生出FamilySymbol (族类型)和WallType(墙类型)及更多,实例(Instance)可以衍生出FamilyInstance(族实例)和Wall(墙实例)及更多。
我刚学这块的时候也是一脸懵逼,为啥要分这么多种。区分这么多种主要是Revit中的族主要分为可载入(FamilySymbol)和不可载入族(如WallType和FloorType),我理解为不可载入族中有一些特殊的方法和属性,比较重要,所以单独独立出来。
实例也是同理,分为FamilyInstanc,Wall,Floor等。
以下图为例,红框为族,绿框为族衍生出来的族类型,而橙框是Element的一项属性 Category (类别),这个属性主要是将族分类,方便后续查找。我们知道我们要找的元素Element是什么类别,就可以更快的找到它。比如想找一个柱子,先通过 Category (类别)过滤出来。
三 继承于元素Element的其他类
标高Level、轴网Grid、房间Room这些类也是继承于Element,区别于族没有元素类型的概念。
四 点Point、线Curve
1.点和线是看不到的,用它来创建元素,比如基于点的用XYZ,基于线的用Curve的子类Line或Arc。
2.点XYZ,
①创建点为new XYZ(X,Y,Z)
3.线Curve子类有Line和Arc
①Line创建:Line.Create(xyz1,xyz2)
②Arc创建:Arc.Create()
4.点(Point)和线(Curve)不是继承于Element,而是GeometryObject,同理还有面(Face),立体图形(Solid)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Events;
using Autodesk.Revit.UI.Selection;
namespace Selection
{
[Transaction(TransactionMode.Manual)]
public class ElementTest : IExternalCommand
{
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
//UIApplication表示一个活动的Revit@会话,提供了对UI定制、事件以及活动文档的访问。
UIApplication uIApplication = commandData.Application;
//Application类表示一个Revit应用,提供对文档、选项以及其他应用范围的数据的访问和设置。
Application app = uIApplication.Application;
//主要包含了跟UI相关的文档信息和操作,比如Active View和ShowElement
UIDocument uIDocument = uIApplication.ActiveUIDocument;
//用与存储Revit的元素、管理视图和数据
Document doc = uIDocument.Document;
//获取元素实例的三种方式
//通过id获取
Wall wall = doc.GetElement(new ElementId(520531)) as Wall;
TaskDialog.Show("element", wall.Name);
//通过PickObject获取
Reference reference = uIDocument.Selection.PickObject(ObjectType.Edge);
FamilyInstance familyInstance = doc.GetElement(reference) as FamilyInstance;
TaskDialog.Show("element", familyInstance.Name);
//通过过滤器获取
//获取族类型
FamilyInstance door = doc.GetElement(new ElementId(542477)) as FamilyInstance;
FamilySymbol familySymbol = door.Symbol;
//通过族类型获取族
Family family=familySymbol.Family;
TaskDialog.Show("族类型和族",familySymbol.Name.ToString()+family.Name.ToString());
//可以通过族获取族下面的所有族类型
Family family1 = familyInstance.Symbol.Family;
ISet<ElementId> eleids = family1.GetFamilySymbolIds();
StringBuilder stringBuilder = new StringBuilder();
foreach(ElementId eleid in eleids)
{
FamilySymbol familySymbol1=doc.GetElement(eleid) as FamilySymbol;
stringBuilder.AppendLine(familySymbol1.Name.ToString());
}
TaskDialog.Show("族类型", stringBuilder.ToString());
//获取点
XYZ point=(door.Location as LocationPoint).Point;
TaskDialog.Show("定位", point.ToString());
//获取线
Line line=(wall.Location as LocationCurve).Curve as Line;
XYZ xyzstart= line.GetEndPoint(0);
XYZ xyzend = line.GetEndPoint(1);
XYZ orgin = line.Origin;
TaskDialog.Show("定位", xyzstart.ToString());
TaskDialog.Show("定位", xyzend.ToString());
TaskDialog.Show("定位", orgin.ToString());
return Result.Succeeded;
}
}
}