Revit SDK 介绍:RebarFreeForm

前言

这个例子介绍了如何做自由造型的钢筋,并且可以自动更新。

内容

最终运行的效果如下:
在这里插入图片描述
不过这个工程也是年久失修,可以编译通过,但无法正常运行,需要做些修改。自带的addin文件里没有添加共享参数的命令,需要把它加进来。最终结果如下:

<?xml version="1.0" encoding="utf-8"?>
<RevitAddIns>
  <AddIn Type="Command">
    <Assembly>RebarFreeForm.dll</Assembly>
    <ClientId>9d871749-6401-419f-ba8f-99a44c03adf5</ClientId>
    <FullClassName>Revit.SDK.Samples.RebarFreeForm.CS.Command</FullClassName>
    <Text>Rebar Free Form</Text>
    <Description>External command to create a Rebar FreeForm element and external application to implement the custom server used to regenerate the rebar geometry based on constraints</Description>
    <VisibilityMode>AlwaysVisible</VisibilityMode>
	<LanguageType>Unknown</LanguageType>
	<VendorId>ADSK</VendorId>
  </AddIn>
  <AddIn Type="Command">
    <Assembly>RebarFreeForm.dll</Assembly>
    <ClientId>9d871749-6401-419f-ba8f-11a44c03adf5</ClientId>
    <FullClassName>Revit.SDK.Samples.RebarFreeForm.CS.AddSharedParams</FullClassName>
    <Text>Add Shared Params</Text>
    <Description>Add Shared Parameters.</Description>
    <VisibilityMode>AlwaysVisible</VisibilityMode>
	<LanguageType>Unknown</LanguageType>
	<VendorId>ADSK</VendorId>
  </AddIn>
  <AddIn Type="Application">
    <Name>RebarFreeForm</Name>
    <Assembly>RebarFreeForm.dll</Assembly>
    <ClientId>a6ea850e-a041-48bb-85f5-8ce21b2ba972</ClientId>
    <FullClassName>Revit.SDK.Samples.RebarFreeForm.CS.Application</FullClassName>
	<VendorId>ADSK</VendorId>
	<VendorDescription>Autodesk, www.autodesk.com</VendorDescription>
  </AddIn>
</RevitAddIns>

入口

这个插件的核心逻辑在它的 Application 里面:

  1. 需要一个 Updater,CurveElementRegenUpdater
  2. 需要一个 ExternalService, RebarUpdateServer
namespace Revit.SDK.Samples.RebarFreeForm.CS
{
    [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
    [Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
    public class Application : IExternalApplication
    {

      RebarUpdateServer m_server = new RebarUpdateServer();
      public Result OnShutdown(UIControlledApplication application)
      {
         return Result.Succeeded;
      }
      public Result OnStartup(UIControlledApplication application)
      {
         // Register CurveElement updater with revit to trigger regen in rebar for selected lines
         CurveElementRegenUpdater updater = new CurveElementRegenUpdater(application.ActiveAddInId);
         UpdaterRegistry.RegisterUpdater(updater);
         ElementClassFilter modelLineFilter = new ElementClassFilter(typeof(CurveElement));
         UpdaterRegistry.AddTrigger(updater.GetUpdaterId(), modelLineFilter, Element.GetChangeTypeAny());
         
         //Register the RebarUpdateServer
         ExternalService service = ExternalServiceRegistry.GetService(m_server.GetServiceId());
         if (service != null)
         {
            service.AddServer(m_server);
            return Result.Succeeded;
         }
         return Result.Succeeded;
      }
   }
}

从 Updater 到 ExternalService

// 在 CurveElementRegenUpdater 中改变 rebar 的共享参数,来让 RebarUpdateServer 有机会执行
foreach(Element elem in elemBars)
{
   Rebar bar = elem as Rebar;
   if (modifiedIds.Contains(id))// if id of line is in the rebar, then trigger regen
   {
      var param = bar.LookupParameter(AddSharedParams.m_paramName);
      param.Set(param.AsInteger() == 0? 1: 0);// just flip the value to register a change that will trigger the regeneration of that rebar on commit.
   }
}

RebarUpdateServer

从测试的结果看,这个 RebarUpdateServer 可能也是年久失修,如果选择创建多个钢筋,也被堆在了一起,或者没考虑过我测试的这种情况。
Revit API:IRebarUpdateServer 更新自定义造型钢筋的接口
如何将数据传入 RebarUpdateServer

  1. RebarUpdateServer 设定 CustomHandle
  2. 在插件的命令中为这些handle添加关联数据

RebarUpdateServer 设定 CustomHandle

public bool GetCustomHandles(RebarHandlesData data)
{
   data.AddCustomHandle((int)BarHandle.FirstHandle);
   data.AddCustomHandle((int)BarHandle.SecondHandle);
   data.AddCustomHandle((int)BarHandle.ThirdHandle);
   data.SetStartHandle((int)BarHandle.StartHandle);
   data.SetEndHandle((int)BarHandle.EndHandle);
   return true;
}
public bool GetHandlesPosition(RebarHandlePositionData data)
{
   if (data.GetNumberOfBars() <= 0)
      return false;
         
   IList<Curve> firstBar = data.GetBarGeometry(0);
   data.SetPosition((int)BarHandle.FirstHandle, firstBar[0].Evaluate(0.5, true));
   data.SetPosition((int)BarHandle.SecondHandle, firstBar[0].Evaluate(0.3, true));
   data.SetPosition((int)BarHandle.ThirdHandle, firstBar[0].Evaluate(0.7, true));
   data.SetPosition((int)BarHandle.StartHandle, firstBar[0].Evaluate(0, true));
   data.SetPosition((int)BarHandle.EndHandle, firstBar[0].Evaluate(1, true));
   return true;
}

public bool GetCustomHandleName(RebarHandleNameData handleNameData)
{
   switch (handleNameData.GetCustomHandleTag())
   {
      case (int)BarHandle.FirstHandle:
         handleNameData.SetCustomHandleName("First Handle");
         break;
      case (int)BarHandle.SecondHandle:
         handleNameData.SetCustomHandleName("Second Handle");
         break;
      case (int)BarHandle.ThirdHandle:
         handleNameData.SetCustomHandleName("Third Handle");
         break;
      default:
         return false;
   }
   return true;
}

在插件的命令中为这些handle添加关联数据

foreach (RebarConstrainedHandle handle in handles)
{
   if (handle.GetHandleType() == RebarHandleType.StartOfBar || handle.GetHandleType() == RebarHandleType.EndOfBar)
      continue;

   Reference reference = sel.PickObject(ObjectType.Face, "Select face for " + handle.GetHandleName());
   if (reference == null)
      continue;
   List<Reference> refs = new List<Reference>();
   refs.Add(reference);
   RebarConstraint constraint = RebarConstraint.Create(handle, refs, true, 0.0);
   rManager.SetPreferredConstraintForHandle(handle, constraint);
}

其它

这个例子应该还有些 bug,但使用的 API 基本就是这些了,如果有相似的需求,可以以此为基础去进行改造。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

极客BIM工作室

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

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

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

打赏作者

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

抵扣说明:

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

余额充值