对于几何模型,revit提供一些相关的api来描述和存储几何模型信息,比如说三维实体(Solid)、表面(Face)、棱边(Edge)、格网(Mesh)等,它们都有对应的类来描述这些信息,并且这些类都继承自GeometryObject类。接下来用两个例子介绍如果获取几何模型的信息。
1、获取墙的面积、体积、格网信息。
[Transaction(TransactionMode.Manual)]
public class Geometry : IExternalCommand
{
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
UIDocument uiDoc = commandData.Application.ActiveUIDocument;
Document doc = uiDoc.Document;
//计算墙的面积
Reference reference = uiDoc.Selection.PickObject(ObjectType.Element, "选择墙");
if (reference == null)
return Result.Cancelled;
Wall wall = doc.GetElement(reference) as Wall;
if (wall == null)
return Result.Failed;
double area = GetArea(wall);
double volumn = GetVolumn(wall);
int triangleCount = GetTriangleCount(wall,0.5);
TaskDialog.Show("revit", $"{wall.Name}墙面积为:{area}平方米,体积为{volumn}立方米");
return Result.Succeeded;
}
}
/// <summary>
/// 获取几何元素的面积
/// </summary>
/// <param name="element"></param>
/// <returns>平方米</returns>
public static double GetArea(Element element)
{
double area = 0;
GeometryElement geometryElement = element.get_Geometry(new Options());
foreach (GeometryObject geometryObject in geometryElement)
{
if (geometryObject is Solid)
{
Solid solid = geometryObject as Solid;
foreach (Face face in solid.Faces)
{
area += face.Area;
}
}
}
area = UnitUtils.ConvertFromInternalUnits(area, DisplayUnitType.DUT_SQUARE_METERS);
return area;
}
/// <summary>
/// 获取几何元素的体积
/// </summary>
/// <param name="element"></param>
/// <returns>立方米</returns>
public static double GetVolumn(Element element)
{
double volumn = 0;
GeometryElement geometryElement = element.get_Geometry(new Options());
foreach (GeometryObject geometryObject in geometryElement)
{
if (geometryObject is Solid)
{
Solid solid = geometryObject as Solid;
volumn += solid.Volume;
}
}
volumn = UnitUtils.ConvertFromInternalUnits(volumn, DisplayUnitType.DUT_CUBIC_METERS);
return volumn;
}
/// <summary>
/// 获取几何元素三角网格数量
/// </summary>
/// <param name="element"></param>
/// <param name="levelOfDetail"></param>
/// <returns></returns>
public static int GetTriangleCount(Element element, double levelOfDetail)
{
int triangleCount = 0;
GeometryElement geometryElement = element.get_Geometry(new Options());
foreach (GeometryObject geometryObject in geometryElement)
{
if (geometryObject is Solid)
{
Solid solid = geometryObject as Solid;
foreach (Face face in solid.Faces)
{
Mesh mesh = face.Triangulate(levelOfDetail);
triangleCount += mesh.NumTriangles;
}
}
}
return triangleCount;
}
结果:
2、计算两模型线相交点,并在相交点处插入立柱
[Transaction(TransactionMode.Manual)]
public class Geometry2 : IExternalCommand
{
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
UIDocument uiDoc = commandData.Application.ActiveUIDocument;
Document doc = uiDoc.Document;
//计算墙的面积
Reference reference1 = uiDoc.Selection.PickObject(ObjectType.Element, "选择第一条模型线");
if (reference1 == null)
return Result.Cancelled;
Reference reference2 = uiDoc.Selection.PickObject(ObjectType.Element, "选择第二条模型线");
if (reference2 == null)
return Result.Cancelled;
ModelCurve modelCurve1 = doc.GetElement(reference1) as ModelCurve;
ModelCurve modelCurve2 = doc.GetElement(reference2) as ModelCurve;
List<XYZ> points = GetIntersectionPoint(modelCurve1.GeometryCurve, modelCurve2.GeometryCurve);
using(Transaction trans = new Transaction(doc,"创建立柱"))
{
trans.Start();
FamilySymbol familySymbol = GetFamilySymbol(doc, "457 x 475mm");
if (!familySymbol.IsActive)
familySymbol.Activate();
foreach (XYZ point in points)
{
FamilyInstance familyInstance = doc.Create.NewFamilyInstance(point, familySymbol, GetLevel(doc, "标高 1"), StructuralType.NonStructural);
}
trans.Commit();
}
return Result.Succeeded;
}
}
/// <summary>
/// 获取两条曲线的交点
/// </summary>
/// <param name="curve1"></param>
/// <param name="curve2"></param>
/// <returns></returns>
public static List<XYZ> GetIntersectionPoint(Curve curve1, Curve curve2)
{
List<XYZ> intersectionPoints = new List<XYZ>();
IntersectionResultArray resultArray = new IntersectionResultArray();
SetComparisonResult result = curve1.Intersect(curve2, out resultArray);
if(result == SetComparisonResult.Overlap)//相交但是不重合
{
foreach(IntersectionResult intersectionResult in resultArray)
{
intersectionPoints.Add(intersectionResult.XYZPoint);
}
}
return intersectionPoints;
}
/// <summary>
/// 获取指定名称的族类型
/// </summary>
/// <param name="doc"></param>
/// <param name="familySymbolName"></param>
/// <returns></returns>
public static FamilySymbol GetFamilySymbol(Document doc, string familySymbolName)
{
FilteredElementCollector collector = new FilteredElementCollector(doc);
collector = collector.OfClass(typeof(FamilySymbol));
var query = from element in collector
where element.Name == familySymbolName
select element;
List<Element> elements = query.ToList();
if (elements.Count < 1)
return null;
return elements[0] as FamilySymbol;
}
/// <summary>
/// 获取指定名称的标高
/// </summary>
/// <param name="doc"></param>
/// <param name="levelName">标高名称</param>
/// <returns></returns>
public static Level GetLevel(Document doc, string levelName)
{
FilteredElementCollector collector = new FilteredElementCollector(doc);
collector = collector.OfClass(typeof(Level));
var query = from element in collector
where element.Name == levelName
select element;
List<Element> elements = query.ToList();
if (elements.Count < 1)
return null;
return elements[0] as Level;
}
结果:
我是一个安静的路人,如果有什么不懂的地方,可以私信我,我们共同探讨,一起进步!