Revit API: Dimension 尺寸标注

前言

本文介绍 Revit API 的尺寸标注。

内容

在 Revit API 中,尺寸标注相关的有三个类:DimensionAngularDimensionSpotDimension
后两者是 Dimension 的子类。
Revit API: Dimension 尺寸标注_第1张图片
对应到 UI:
Revit API: Dimension 尺寸标注_第2张图片

创建标注

Revit 中创建标注的地方并不统一。分别在 Autodesk.Revit.Creation.ItemFactoryBaseAutodesk.Revit.Creation.FamilyItemFactoryAutodesk.Revit.Creation.Document中。其中,后两者继承自第一个类。

Autodesk.Revit.Creation.ItemFactoryBase, 创建对齐标注和线型标注,Alignment 是约束:

namespace Autodesk.Revit.Creation
{
     
    public class ItemFactoryBase : APIObject
    {
     
        public Dimension NewAlignment(View view, Reference reference1, Reference reference2);
        public Dimension NewDimension(View view, Line line, ReferenceArray references, DB.DimensionType dimensionType);
        public Dimension NewDimension(View view, Line line, ReferenceArray references);
    }
}

在实际使用中,Revit 文件和 Revit 族文件使用上稍有差异。
Revit 文件:

Dimension newDimension = doc.Create.NewDimension(doc.ActiveView, newLine2, referenceArray);

Revit 族文件,实际对应的是 FamilyItemFactory 里面的方法:

dim = m_document.FamilyCreate.NewDimension(view, line, refArray);

如下所示,在族文件里,除了对齐标注和线型标注,可以做角度、半径、直径、弧长的尺寸标注。从另一个角度可以说明,在 Revit 文件中,可能不能创建这些类型的尺寸标注,需要自己去验证一下。

namespace Autodesk.Revit.Creation
{
     
    public class FamilyItemFactory : ItemFactoryBase
    {
     
        public Dimension NewAngularDimension(View view, Arc arc, Reference firstRef, Reference secondRef);
        public Dimension NewAngularDimension(View view, Arc arc, Reference firstRef, Reference secondRef, DB.DimensionType dimensionType);
        public Dimension NewArcLengthDimension(View view, Arc arc, Reference arcRef, Reference firstRef, Reference secondRef);
        public Dimension NewArcLengthDimension(View view, Arc arc, Reference arcRef, Reference firstRef, Reference secondRef, DB.DimensionType dimensionType);
        public Dimension NewDiameterDimension(View view, Reference arcRef, DB.XYZ origin);
        public Dimension NewLinearDimension(View view, Line line, ReferenceArray references);
        public Dimension NewLinearDimension(View view, Line line, ReferenceArray references, DB.DimensionType dimensionType);
        public Dimension NewRadialDimension(View view, Reference arcRef, DB.XYZ origin);
        public Dimension NewRadialDimension(View view, Reference arcRef, DB.XYZ origin, DB.DimensionType dimensionType);
    }
}

创建高程点标注:

namespace Autodesk.Revit.Creation
{
     
    public class Document : ItemFactoryBase
    {
     
        public SpotDimension NewSpotCoordinate(View view, Reference reference, DB.XYZ origin, DB.XYZ bend, DB.XYZ end, DB.XYZ refPt, bool hasLeader);
        public SpotDimension NewSpotElevation(View view, Reference reference, DB.XYZ origin, DB.XYZ bend, DB.XYZ end, DB.XYZ refPt, bool hasLeader);
    }
}

创建的过程是类似的,以 NewDimension 为例:
Revit API 开发(3):用两个点创建一个标注

线性标注的例子

Revit API: Dimension 尺寸标注_第3张图片
逻辑:

  1. 用户选中墙(这个例子仅仅支持墙的方向在平面视图中从左往右,其它方向自行修改代码)
  2. 检测墙的几何图形,找到端点的两个面(通过法线来判断)
  3. 从一个面计算得到坐标在 UV(0,0) 的点,然后投影到另一个面
  4. 把这两个点都平移一段距离(吐槽 line.CreateOffset 健壮性太差)
  5. 创建线性标注,doc.Create.NewDimension(uiDoc.ActiveView, line, referenceArray)

完整代码:

class CreateDimensionCommand : IExternalCommand
{
     
    public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
    {
     
        UIDocument uiDoc = commandData.Application.ActiveUIDocument;
        Document doc = uiDoc.Document;

        Face face1 = null;
        Face face2 = null;
        Reference reference = uiDoc.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element);
        Element elem = doc.GetElement(reference.ElementId);
        Options options = new Options();
        options.View = uiDoc.ActiveView;
        options.ComputeReferences = true;
        GeometryElement geometryElement = elem.get_Geometry(options);
        foreach (GeometryObject gObj in geometryElement)
        {
     
            Solid solid = gObj as Solid;
            foreach (Face face in solid.Faces)
            {
     
                XYZ normal = face.ComputeNormal(new UV(0, 0));
                if (Math.Abs(normal.X) > 0.1)
                {
     
                    if (normal.X > 0.1)
                    {
     
                        face1 = face;
                    }
                    else
                    {
     
                        face2 = face;
                    }
                }
            }
        }

        if (face1 != null && face2 != null)
        {
     
            Transaction tran = new Transaction(doc, "Create Dimension");
            tran.Start();
            XYZ p1 = face1.Evaluate(new UV(0, 0));
            XYZ p2 = face2.Project(p1).XYZPoint;
            p1 = new XYZ(p1.X, p1.Y + 10.0, p1.Z);
            p2 = new XYZ(p2.X, p2.Y + 10.0, p2.Z);
            Line line = Line.CreateBound(p1, p2);

            ReferenceArray referenceArray = new ReferenceArray();
            referenceArray.Append(face1.Reference);
            referenceArray.Append(face2.Reference);
            doc.Create.NewDimension(uiDoc.ActiveView, line, referenceArray);
            tran.Commit();
        }

        return Result.Succeeded;
    }
}

高程点的例子

Revit API: Dimension 尺寸标注_第4张图片
逻辑:

  1. 用户选中墙(这个例子仅仅支持墙的方向在平面视图中从左往右,其它方向自行修改代码)
  2. 检测墙的几何图形,找到顶面(通过法线来判断)
  3. 从一个面计算得到坐标在 UV(0,20) 的点作为 origin(注意和你选的面有关,不一定是这个点作为起点)
  4. 计算几个转角点 bend,终点 end,以及 refPt,这个点似乎没有什么作用
  5. 设置是否需要箭头
  6. 创建线性标注,doc.Create.NewSpotElevation(uiDoc.ActiveView, topFaceRef, origin, bend, end, refPt, hasLeader)
class CreateSpotDimensionCommand : 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(Autodesk.Revit.UI.Selection.ObjectType.Element);
        Face upFace = null;
        Element elem = doc.GetElement(reference.ElementId);
        Options options = new Options();
        options.View = uiDoc.ActiveView;
        options.ComputeReferences = true;
        GeometryElement geometryElement = elem.get_Geometry(options);
        foreach (GeometryObject gObj in geometryElement)
        {
     
            Solid solid = gObj as Solid;
            foreach (Face face in solid.Faces)
            {
     
                XYZ normal = face.ComputeNormal(new UV(0, 0));
                if (normal.Z > 0.1)
                {
     
                    upFace = face;
                }
            }
        }

        if (upFace != null)
        {
     
            Reference topFaceRef = upFace.Reference;
            Transaction tran = new Transaction(doc, "Create Dimension");
            tran.Start();
            XYZ origin = upFace.Evaluate(new UV(0, 20));
            XYZ bend = new XYZ(origin.X + 10.0, origin.Y, origin.Z + 10.0);
            XYZ end = new XYZ(bend.X + 10.0, bend.Y, bend.Z);
            XYZ refPt = origin;
            bool hasLeader = true;

            doc.Create.NewSpotElevation(uiDoc.ActiveView, topFaceRef, origin, bend, end, refPt, hasLeader);
            tran.Commit();
        }

        return Result.Succeeded;
    }
}

你可能感兴趣的:(Revit,API)