前言
这个例子介绍如果从分割表面中,获取内部Tile(或者Panel)的族里面的几何实体的面的面积。
内容
本例子的逻辑相对来说比较简单,主要是对 DividedSurface 和 Element 的API接口要熟悉。
核心逻辑
- 设置单个面板Panel的面积上限和下限
- 获取所有分割表面
- 如果用户已经选择了分割表面,就使用当前选择
- 如果用户没有选择,就过滤出文件中的所有分割表面
- 对于每一个分割表面
- 查询获取它内部的 Panel Family Instance:
ds.GetTileFamilyInstance(gn, 0);
- 遍历 Family Instance 的几何,得到所有的面
- 遍历输出面的面积到日志文件
- 记录最后一个面的面积(估计是因为是sample,代码写的比较随意)
- 根据Family Instance 最后一个面的面积,统计是符合要求、高于上限、低于下限
- 查询获取它内部的 Panel Family Instance:
设置单个面板Panel的面积上限和下限
下图为启动界面:
获取所有分割表面
用于获取特定类型 Element 的模板方法
protected List<T> GetElements<T>() where T : Element
{
List<T> returns = new List<T>();
FilteredElementCollector collector = new FilteredElementCollector(m_uiDoc.Document);
ICollection<Element> founds = collector.OfClass(typeof(T)).ToElements();
foreach (Element elem in founds)
{
returns.Add(elem as T);
}
return returns;
}
获取分割表面的逻辑:
private void GetDividedSurfaces(){
// 获取所有的分割表面
if (m_uiDoc.Selection.GetElementIds().Count == 0){
m_dividedSurfaceList = GetElements<DividedSurface>();
return;
}
// 后去用户选择的分割表面
foreach (ElementId elementId in m_uiDoc.Selection.GetElementIds()){
Element element = m_uiDoc.Document.GetElement(elementId);
DividedSurface ds = element as DividedSurface;
if (ds != null){
m_dividedSurfaceList.Add(ds);
}
}
}
对于每一个分割表面
获取每一个分割表面中 Tile(或者Panel)的逻辑框架:
for (int u = 0; u < ds.NumberOfUGridlines; u++){
for (int v = 0; v < ds.NumberOfVGridlines; v++){
GridNode gn = new GridNode(u, v);
if (false == ds.IsSeedNode(gn)){
continue;
}
FamilyInstance familyinstance = ds.GetTileFamilyInstance(gn, 0);
if (familyinstance != null){
// 获取族实例的面积
double panelArea = GetAreaOfTileInstance(familyinstance);
}
}
}
遍历获取族几何体面积的核心逻辑:
private double GetAreaOfTileInstance(FamilyInstance familyinstance)
{
double panelArea = 0d;
// 获取族实例的几何
Autodesk.Revit.DB.Options opt = m_uiApp.Application.Create.NewGeometryOptions();
opt.ComputeReferences = true;
Autodesk.Revit.DB.GeometryElement geomElem = familyinstance.get_Geometry(opt);
// 遍历几何
IEnumerator<GeometryObject> Objects = geomElem.GetEnumerator();
while (Objects.MoveNext()){
GeometryObject geomObject1 = Objects.Current;
// 获取实体,只支持族实例本身就是solid,或者是GeometryInstance,且其中包含 solid
Solid solid = null;
if (geomObject1 is Solid){
solid = (Solid)geomObject1;
if (null == solid){continue;}
}
else if (geomObject1 is GeometryInstance){
GeometryInstance geomInst = geomObject1 as GeometryInstance;
IEnumerator<GeometryObject> Objects1 = geomInst.SymbolGeometry.GetEnumerator();
while (Objects1.MoveNext()){
Object geomObj = Objects1.Current;
solid = geomObj as Solid;
if (solid != null) break;
}
}
// 如果 solid 里没有 face,则跳过(未检查solid本身为null
if (null == solid.Faces || 0 == solid.Faces.Size){ continue; }
// 遍历输出面的面积到日志文件
// 记录最后一个面的面积(估计是因为是sample,代码写的比较随意)
foreach (Face face in solid.Faces) {
panelArea = face.Area;
m_writeFile.WriteLine(familyinstance.Id.IntegerValue + " : " + panelArea);
}
}
return panelArea;
}