Revit SDK 介绍:FreeFormElement

前言

这个例子介绍了 Revit 的自由造型能力,内容包含创建拉伸、进行布尔操作等。

内容

创建一个内建体量,以及用模型线绘制一个轮廓。选择体量和轮廓,程序会用轮廓做一个拉伸,这个拉伸的高度比体量高。然后对两个体量进行布尔减操作,将结果作为常规模型族载入到当前文件,并放到对应位置。
在这里插入图片描述

代码逻辑

主要逻辑在 CreateNegativeBlock,文件:Revit 2021 SDK\Samples\FreeFormElement\CS\FreeFormElementUtils.cs

从线的引用里获取线的几何图形

几点需要注意的:

  1. 通过 Reference 可以从文档获取 Elementdoc.GetElement(reference)
  2. 对获得的 Curve 按首尾相接进行排序
        public static IList<Curve> GetContiguousCurvesFromSelectedCurveElements(Document doc, IList<Reference> boundaries)
        {
            List<Curve> curves = new List<Curve>();

            // Build a list of curves from the curve elements
            foreach (Reference reference in boundaries)
            {
                CurveElement curveElement = doc.GetElement(reference) as CurveElement;
                curves.Add(curveElement.GeometryCurve.Clone());
            }

            // Walk through each curve (after the first) to match up the curves in order
            for (int i = 0; i < curves.Count; i++)
            {
                Curve curve = curves[i];
                XYZ endPoint = curve.GetEndPoint(1);

                // find curve with start point = end point
                for (int j = i + 1; j < curves.Count; j++)
                {
                    // Is there a match end->start, if so this is the next curve
                    if (curves[j].GetEndPoint(0).IsAlmostEqualTo(endPoint, 1e-05))
                    {
                        Curve tmpCurve = curves[i + 1];
                        curves[i + 1] = curves[j];
                        curves[j] = tmpCurve;
                        continue;
                    }
                    // Is there a match end->end, if so, reverse the next curve
                    else if (curves[j].GetEndPoint(1).IsAlmostEqualTo(endPoint, 1e-05))
                    {
                        Curve tmpCurve = curves[i + 1];
                        curves[i + 1] = CreateReversedCurve(curves[j]);
                        curves[j] = tmpCurve;
                        continue;
                    }
                }
            }

            return curves;
        }

创建闭合线圈

  1. CurveLoop 的创建需要首尾相连的线
  2. GeometryCreationUtilities.CreateExtrusionGeometry 的参数是 List<CurveLoop>
CurveLoop loop = null;
try
{
   loop = CurveLoop.Create(curves);
}
catch (Autodesk.Revit.Exceptions.ArgumentException)
{
   // Curves are not contiguous
   return FailureCondition.CurvesNotContigous;
}
List<CurveLoop> loops = new List<CurveLoop>();
loops.Add(loop);

创建自由造型几何形体

// 1. 确定拉伸的高度,确保比体量高1.
// Get elevation of loop
double elevation = curves[0].GetEndPoint(0).Z;
// Get height for extrusion
BoundingBoxXYZ bbox = targetElement.get_BoundingBox(null);
double height = bbox.Max.Z - elevation;
height += 1;

// 2. 创建一个拉伸体
Solid block = GeometryCreationUtilities.CreateExtrusionGeometry(loops, XYZ.BasisZ, height);

// 3. 用选中的体量作为减体量,源码中考虑多个solid,这里省略了。
IList<Solid> fromElement = GetTargetSolids(targetElement);
Solid toSubtract = fromElement[0];

// 4. 进行布尔操作
try
{
    BooleanOperationsUtils.ExecuteBooleanOperationModifyingOriginalSolid(block, toSubtract, BooleanOperationsType.Difference);
}
catch (Autodesk.Revit.Exceptions.InvalidOperationException)
{
   return FailureCondition.NoIntersection;
}

用计算结果创建族

// Create family
Document familyDoc = app.NewFamilyDocument(familyTemplate);
// Create freeform element
using (Transaction t = new Transaction(familyDoc, "Add element"))
{
   t.Start();
   RevitFreeFormElement element = Autodesk.Revit.DB.FreeFormElement.Create(familyDoc, block);
   t.Commit();
}

FreeFormElement 的接口:

namespace Autodesk.Revit.DB
{
    public class FreeFormElement : GenericForm
    {
        public static FreeFormElement Create(Document document, Solid geometry);
        public bool CanOffsetFace(Face face);
        public void SetFaceOffset(Face face, double offset);
        public void UpdateSolidGeometry(Solid newGeometry);
    }
}

FreeFormElement 的继承层次:
在这里插入图片描述

载入族

Family family = familyDoc.LoadFamily(doc, familyLoadOptions);

放置族

// 1. 用 FamilySymbolFilter 找到对应的 FamilySymbol
FilteredElementCollector collector = new FilteredElementCollector(doc);
collector.WherePasses(new FamilySymbolFilter(family.Id));
FamilySymbol fs = collector.FirstElement() as FamilySymbol;

//2. 放置族到对应的位置,底面和输入轮廓重合
using (Transaction t2 = new Transaction(doc, "Place instance"))
{
   t2.Start();
   if (!fs.IsActive)
      fs.Activate();
   doc.Create.NewFamilyInstance(XYZ.Zero, fs, Autodesk.Revit.DB.Structure.StructuralType.NonStructural);
   t2.Commit();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

极客BIM工作室

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

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

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

打赏作者

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

抵扣说明:

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

余额充值