Revit二次开发入门:第五章几何
本章内容
1.什么是几何
几何数据就是代表一个构件的几何模型。
在Autodesk.Revit.DB命名空间里包含了一些几何图形相关的类型,他们在API中用于几何图形的标识和处理。
从基类基础的情况分,API提供了三大种几何类型来描述和存储几何信息,分别是:
- 几何基元类:包括所有从GeometryObject派生出来的子类
- 几何辅助类:包括一些从APIObject派生出来的几何相关的子类和一些值类型。
- 几何集合类:包括一些实现了IEnumerable或者IEnumerator接口的几何相关的类型
2.属性参数
OPtions决定具体返回的具体值
- GeoElement geoElem=elem.get_Geometry(geoOptions);
- Options类,用于指定返回几何数据的特征
- 返回的几何对信息的详细程度:设置ComputerReferences属性为true或false
- 设置返回的几何信息的详细程度:设置DetailLeve(粗略、中等、详细等)
- 返回哪个视图的几何信息:设置View属性
- 两种创建Option对象的方法:
- Application.Creation.NewGeometryOptions()
- Options的构造函数New Options()
3.几何对象与关系
几何对象:
- Geometry返回GeometryElement对象
- GeometryElement.Objects返回GeometryObhectArray,包含:
- Autodesk.Revit.DB.GeometryElement
- Autodesk.Revit.DB.GeometryInstance-包含标准族实例几何信息
- Autodesk.Revit.DB.Solid-三维实体
- Autodesk.Revit.DB.Edge-棱边
- Autodesk.Revit.DB.Face-表面
- Autodesk.Revit.DB.Mesh-网格
- Autodesk.Revit.DB.Point-点
- GeometryElement.Objects返回GeometryObhectArray,包含:
4.几何基元类
几何基元类在API中描述图形表示,由基类GeometryObject派生,主要有如下的类型:
-
Profile-轮廓 与 Point/XYZ点
- Point三维空间的点
- XYZ代表了具体的位置坐标
- 可自由进行创建等
- Profile-轮廓:可以来生成形状的单条线、一串连接起来的线或闭合的环。
- Point三维空间的点
-
Face-三维空间的实体面
- Face多样性
- Face的周围边-EdgeCurve
- 三角化后得到Mesh
- 面积、法向量计算等
- 不能直接构造一个对象
-
Edge-边
- 隶属于面
- 每个Edge隶属两个面
- 可转换成集合曲线Curve
- 只能从Face里面取,不能直接New
-
Curve-线
- 几何运算对象
- 显得多样性
- 可自由创建
- Line line=new Line();
-
Point-点
-
GeometryElement-几何元素:一个元素的几何表示,标好了所有的几何信息
-
GeomtryInstance-几何实例:一个类型图元的实例,可以取得与该实例相关的类型图元的几何信息。
-
Mesh-网格/Mesh Triangle三角网格
- 网格(Mesh):三角化网格用于描述三维面的形状
- 三角形片
- 顶点坐标
- 每个三角形的三个顶点
-
Solid-实体
- 可以得到构成Solid的Face
- Solid的边-Edge
- Edge可以转换成Curve
- 表面积、体积
-
几何元素(GeometryElement)与集合实例(GeometryInstance)的获取方法
Element.Geometry该属性用户获取实体对象的几何数据
Geometry Element.Geometry[Options options]{get;}
Options opt=new Options(); opt.DetailLevel = ViewDetailLevel.Fine; opt.ComputeReferences = true; opt.IncludeNonVisibleObjects = true; GeometryElement geometry = elem.get_geometry(opt); IEnumerator<GeometryObject> gIter = geometry.GetEnumerator(); gIter.Reset(); while (gIter.MoveNext()) { TaskDialog.Show("几何信息", "几何类型:" + gIter.Current.GetType().Name); }
5.几何辅助类
API有一些辅助类来帮助表示某些元素的几何信息,比如视图的裁剪是由BoundingBoxXYZ对象来定义的。
- BoundingBoxXYZ:三维的长方体
- Transform:仿射空间的一个变换
- Reference:Revit模型中的一个几何对象的稳定引用,一般用以创建元素,比如尺寸标注等。
- Plane:几何平面对象
- Options:解析几何的用户参数选择
- XYZ三维空间的坐标
- UV:二维空间的坐标
- BoundingBoxUV:二维的长方形,平行于坐标轴
6.几何集合类
API提供了下面一些几何类用来存储或者遍历稽核数据,所有这些类的方法和属性是类似的。
- 线:CurveArray,CurrveArrayIterator
- 边:EdgeArray,EdgeArrayIterator,EdgeArrayArray,EdgeArrayArrayIterator
- 面:FaceArray,FaceArrayIterator
- 引用:ReferenceArray,RegerenceArrIterator
- Double值:DoubleArray,DoubleArrayIterator
7.几何运算与工具集
- 面与面相交、投影
- 面线相交、投影
- 面与Solid相交
- Solid与Solid的布尔运算
Intersect | Curve | Face | Solid |
---|---|---|---|
Curve | √ | √ | √ |
Face | √ | √ | √ |
Solid | √ | √ | √ |
Project | XYZ | Curve | Face | Solid |
---|---|---|---|---|
XYZ | / | √ | √ | √ |
Curve | √ | √ | √ | √ |
Face | √ | √ | √ | √ |
Solid | √ | √ | √ | √ |
-
几何数据创建(注:不是Element!)
-
布尔运算
-
BooleanOperationUtils:
- Union
- defference
- Intersect
8.实例练习1:几何计算
- 从一个元素中得到实体
- 从实体得到面,计算面积与体积
- Solid,Face,Mesh,Triangle之间的关系
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using System.Collections.Generic;
using System.Linq;
namespace SolidPractise {
[TransactionAttribute(TransactionMode.Manual)]
[RegenerationAttribute(RegenerationOption.Manual)]
public class SolidTest : IExternalCommand {
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) {
UIDocument uiDoc = commandData.Application.ActiveUIDocument;
Document doc = uiDoc.Document;
ICollection<ElementId> ids = uiDoc.Selection.GetElementIds();
Element selElem = uiDoc.Document.GetElement(ids.First());
GeometryElement ge = selElem.get_Geometry(new Options());
double area = 0;
double volume = 0;
int triangleCount = 0;
foreach (GeometryObject o in ge) {
if (o is Solid) {
Solid sd = o as Solid;
foreach (Face face in sd.Faces) {
area += face.Area * 0.3048 * 0.3048;//这里计算了所有的面,所以和特性中显示的不一致。
Mesh mesh = face.Triangulate(0.5);
triangleCount += mesh.NumTriangles;
}
volume += sd.Volume * 0.3048 * 0.3048 * 0.3048;
}
}
TaskDialog.Show("计算", "面积总和为:" + area.ToString() + "平方米\n" +
"体积为:" + volume.ToString("0.000") + "立方米\n" +
"三角网格数为:" + triangleCount.ToString());
return Result.Succeeded;
}
}
}
9.实例练习2:交点立柱
- 计算轴线间的交点
- 在交点处放置柱子
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Structure;
using Autodesk.Revit.UI;
using System.Collections.Generic;
using System.Linq;
namespace GridPractise {
[TransactionAttribute(TransactionMode.Manual)]
[RegenerationAttribute(RegenerationOption.Manual)]
public class GridTest : IExternalCommand {
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) {
UIDocument uiDoc = commandData.Application.ActiveUIDocument;
Document doc = uiDoc.Document;
FilteredElementCollector coll = new FilteredElementCollector(doc);
ElementClassFilter gridFilter = new ElementClassFilter(typeof(Grid));
List<Element> grid = coll.WherePasses(gridFilter).ToElements().ToList();
List<Line> gridLines = new List<Line>();
List<XYZ> intXyzs = new List<XYZ>();
foreach (Grid g in grid) {
gridLines.Add(g.Curve as Line);
}
foreach (Line line1 in gridLines) {
foreach (Line line2 in gridLines) {
XYZ normal1 = line1.Direction;
XYZ normal2 = line2.Direction;
if (normal1.IsAlmostEqualTo(normal2)) {
continue;
}
SetComparisonResult intRst = line1.Intersect(line2, out IntersectionResultArray results);
if (intRst == SetComparisonResult.Overlap && results.Size == 1) {
XYZ tp = results.get_Item(0).XYZPoint;
if (intXyzs.Where(m => m.IsAlmostEqualTo(tp)).Count() == 0) {
intXyzs.Add(tp);
}
}
}
}
Level level = doc.GetElement(new ElementId(311)) as Level;
FamilySymbol familySymbol = doc.GetElement(new ElementId(338370)) as FamilySymbol;
using (Transaction tr = new Transaction(doc)) {
tr.Start("Clomn");
if (!familySymbol.IsActive) {
familySymbol.Activate();
}
foreach (XYZ xyz in intXyzs) {
FamilyInstance familyInstance =
doc.Create.NewFamilyInstance(xyz, familySymbol, level, StructuralType.NonStructural);
}
tr.Commit();
}
return Result.Succeeded;
}
}
}