【Revit二次开发】几何

几何


几何

在Autodesk. Revit, DB命名空间里包含了- -些几何图形相关的类型,它们在API中用
于几何图形的表示和处理。从基类继承的情况分,API提供了三大种几何类型来描述和存
储几何信息:
●几何基元类:包括所有从GeometryObject派生出来的子类。
●几何辅助类:包括一些从APIObject派生出来的几何相关的子类和一些值类型。
●几何集合类:包括一些实现了lEnumerable或者lEnumerator 接口的几何相关的
类型。

在Revit二次开发中,几何是非常重要的一部分,因为在Revit中,所有的构件都是由几何形状组成的。Revit中的几何可以分为以下几种类型:

点(Point):代表三维空间中的一个点,可以用X、Y、Z坐标表示。
线(Line):由两个点组成的直线段。
平面(PlanarFace):由三个或以上的点组成的平面。
多边形(Polygon):由三个或以上的点组成的封闭形状。
三角形(Triangle):由三个点组成的三角形。
矩形(Rectangle):由四个点组成的矩形。
圆形(Circle):由一个中心点和半径组成的圆形。
在Revit二次开发中,我们可以使用以下几种方式来获取构件的几何信息:

获取构件的几何信息对象(GeometryObject),可以通过GeometryInstance对象获取。
获取构件的几何信息(Geometry),可以通过Element对象的Geometry属性获取。
获取构件的几何图形(Solid),可以通过Element对象的GetSolidGeometry方法获取。
例如,以下代码可以获取某一构件的几何信息:

Element element = ... // 获取某一构件
GeometryElement geometry = element.Geometry; // 获取构件的几何信息

获取到几何信息后,我们可以使用以下方法来获取具体的几何形状:

获取点(Point):通过Point对象的Coordinates属性获取。
获取线(Line):通过Curve对象的GetEndPoint和GetStartPoint方法获取。
获取平面(PlanarFace):通过PlanarFace对象的Vertices属性获取。
获取多边形(Polygon):通过Polygon对象的Vertices属性获取。
获取三角形(Triangle):通过Triangle对象的Vertices属性获取。
获取矩形(Rectangle):通过Rectangle对象的Vertices属性获取。
获取圆形(Circle):通过Circle对象的Center属性和Radius属性获取。
例如,以下代码可以获取某一构件的所有点:

GeometryElement geometry = ... // 获取某一构件的几何信息
foreach (GeometryObject geoObj in geometry)
{
    Point point = geoObj as Point;
    if (point != null)
    {
        XYZ coordinates = point.Coordinates; // 获取点的坐标
        // 处理点的坐标
    }
}

需要注意的是,几何信息中的坐标是以Revit内部的坐标系表示的,需要进行转换才能与其他外部坐标系进行对比。

例子

Revit二次开发中常用的几何计算方法如下:

获取两点之间的距离:
可以通过XYZ对象的DistanceTo方法获取两个点之间的距离。

XYZ point1 = ... // 获取第一个点的坐标
XYZ point2 = ... // 获取第二个点的坐标
double distance = point1.DistanceTo(point2); // 获取两个点之间的距离

获取两线之间的夹角:
可以通过两条线段的方向向量计算出它们之间的夹角。

Line line1 = ... // 获取第一条线段
Line line2 = ... // 获取第二条线段

double angle = line1.Direction.AngleTo(line2.Direction); // 获取两条线段之间的夹角

获取平面内两线的交点:
可以通过Plane对象的Intersect方法获取平面内两条线段的交点。

Plane plane = ... // 获取平面
Line line1 = ... // 获取第一条线段
Line line2 = ... // 获取第二条线段
XYZ intersection = plane.Intersect(line1, line2); // 获取两条线段在平面上的交点

获取平面内点到直线的距离:
可以通过Plane对象的Project方法将点投影到直线上,然后计算投影点与原点之间的距离。

Plane plane = ... // 获取平面
Line line = ... // 获取直线
XYZ point = ... // 获取点
XYZ projection = plane.Project(point, line.Direction); // 将点投影到直线上
double distance = projection.DistanceTo(point); // 计算投影点与原点之间的距离

获取平面内点到线段的距离:
可以先将点投影到直线上,然后判断投影点是否在线段上,最后计算投影点与原点之间的距离。

Plane plane = ... // 获取平面
Line line = ... // 获取直线
XYZ point = ... // 获取点
XYZ projection = plane.Project(point, line.Direction); // 将点投影到直线上
if (projection.IsOnLine(line)) // 判断投影点是否在线段上
{
    double distance = projection.DistanceTo(point); // 计算投影点与原点之间的距离
}

计算平面内点是否在多边形内:
可以通过Polygon对象的Contains方法判断一个点是否在多边形内。

Plane plane = ... // 获取平面
Polygon polygon = ... // 获取多边形
XYZ point = ... // 获取点
bool isInPolygon = polygon.Contains(point); // 判断点是否在多边形内
	public Autodesk.Revit.UI.Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
    {
        try
        {
            UIDocument uidoc = commandData.Application.ActiveUIDocument;
            Document doc = uidoc.Document;

            Selection selection = uidoc.Selection;
            string msg = string.Empty;
            //选择墙
            ISelectionFilter wallFilter = new WallSelectionFilter(doc);
            Reference eleRef = selection.PickObject(ObjectType.Element, wallFilter);
            if (null == eleRef || ElementId.InvalidElementId == eleRef.ElementId)
            {
                return Result.Cancelled;
            }
            //获取墙的信息
            Element element = doc.GetElement(eleRef);
            Wall wall = element as Wall;
            if (wall == null)
                return Result.Failed;
            //structuralUsage枚举
            Enum structuralUsage = wall.StructuralUsage;
            List<double> areas = GetArea(wall);
            double volumn = GetVolumn(wall);
            int i = 0;
            foreach (double area in areas)
            {
                i++;
                msg += " 面" + i + " :" + area + "平方米 ";
            }
            msg = "是否为结构:" + structuralUsage.ToString() + " ElementId:" + element.Id + " 体积:" + volumn + "立方米" + msg;
            TaskDialog.Show(this.GetType().Name, msg);

            return Result.Succeeded;
        }
        catch (Exception ex)
        {
            message = ex.Message;
            return Result.Failed;
        }
    }

    /// <summary>
    /// 获取几何元素的面积
    /// </summary>
    /// <param name="element"></param>
    /// <returns>平方米</returns>
    public static List<double> GetArea(Element element)
    {
        List<double> area = new List<double>();
        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)
                {
                    double v = UnitUtils.ConvertFromInternalUnits(face.Area, UnitTypeId.SquareMeters);
                    area.Add(v);
                }
            }
        }
        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, UnitTypeId.CubicMeters);
        return volumn;
    }


}
public class WallSelectionFilter : ISelectionFilter
{
    Document m_doc = null;

    /// <summary>
    /// Constructor the filter and initialize the document.
    /// </summary>
    /// <param name="doc">The document.</param>
    public WallSelectionFilter(Document doc)
    {
        m_doc = doc;
    }
    /// <summary>
    /// Allow all the element to be selected
    /// </summary>
    /// <param name="element">A candidate element in selection operation.</param>
    /// <returns>Return true to allow the user to select this candidate element.</returns>
    public bool AllowElement(Element elem)
    {
        return elem is Wall;
    }
    /// <summary>
    /// Allow planar face reference to be selected
    /// </summary>
    /// <param name="refer">A candidate reference in selection operation.</param>
    /// <param name="point">The 3D position of the mouse on the candidate reference.</param>
    /// <returns>Return true for planar face reference. Return false for non planar face reference.</returns>
    public bool AllowReference(Reference reference, XYZ position)
    {
        return false;  //设置为不允许
    }
  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Revit 二次开发中,获取族实例几何信息的方法可以分为两种:使用 Revit API 提供的方法和使用 Geometry API 提供的方法。 首先,使用 Revit API 提供的方法可以通过以下代码获取族实例的几何信息: ```csharp // 获取当前文档 Document doc = uidoc.Document; // 获取选中的族实例 ElementId elementId = uidoc.Selection.GetElementIds().FirstOrDefault(); FamilyInstance familyInstance = doc.GetElement(elementId) as FamilyInstance; // 获取族实例的几何信息 GeometryElement geometryElement = familyInstance.get_Geometry(new Options()); foreach (GeometryObject geometryObject in geometryElement) { if (geometryObject is Solid solid) { // 获取实体的顶点信息 foreach (Face face in solid.Faces) { Mesh mesh = face.Triangulate(); foreach (XYZ vertex in mesh.Vertices) { // 获取顶点坐标 double x = vertex.X; double y = vertex.Y; double z = vertex.Z; } } } } ``` 其次,使用 Geometry API 提供的方法可以通过以下代码获取族实例的几何信息: ```csharp // 获取当前文档 Document doc = uidoc.Document; // 获取选中的族实例 ElementId elementId = uidoc.Selection.GetElementIds().FirstOrDefault(); FamilyInstance familyInstance = doc.GetElement(elementId) as FamilyInstance; // 获取族实例的几何信息 GeometryElement geometryElement = familyInstance.Symbol.Geometry; foreach (GeometryObject geometryObject in geometryElement) { if (geometryObject is Solid solid) { // 获取实体的顶点信息 foreach (Face face in solid.Faces) { Mesh mesh = face.Triangulate(); foreach (XYZ vertex in mesh.Vertices) { // 获取顶点坐标 double x = vertex.X; double y = vertex.Y; double z = vertex.Z; } } } } ``` 无论是哪种方法,都可以获取到族实例的几何信息。使用 Revit API 提供的方法可以更方便地获取当前文档和选中的族实例,而使用 Geometry API 提供的方法则可以直接从族类型中获取几何信息,避免了需要实例化后再获取几何信息的步骤。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

孤影墨客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值