前言
这个例子介绍了如何做自由造型的钢筋,并且可以自动更新。
内容
最终运行的效果如下: 不过这个工程也是年久失修,可以编译通过,但无法正常运行,需要做些修改。自带的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 里面:
- 需要一个 Updater,
CurveElementRegenUpdater - 需要一个 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)
{
CurveElementRegenUpdater updater = new CurveElementRegenUpdater(application.ActiveAddInId);
UpdaterRegistry.RegisterUpdater(updater);
ElementClassFilter modelLineFilter = new ElementClassFilter(typeof(CurveElement));
UpdaterRegistry.AddTrigger(updater.GetUpdaterId(), modelLineFilter, Element.GetChangeTypeAny());
ExternalService service = ExternalServiceRegistry.GetService(m_server.GetServiceId());
if (service != null)
{
service.AddServer(m_server);
return Result.Succeeded;
}
return Result.Succeeded;
}
}
}
从 Updater 到 ExternalService
foreach(Element elem in elemBars)
{
Rebar bar = elem as Rebar;
if (modifiedIds.Contains(id))
{
var param = bar.LookupParameter(AddSharedParams.m_paramName);
param.Set(param.AsInteger() == 0? 1: 0);
}
}
RebarUpdateServer
从测试的结果看,这个 RebarUpdateServer 可能也是年久失修,如果选择创建多个钢筋,也被堆在了一起,或者没考虑过我测试的这种情况。 Revit API:IRebarUpdateServer 更新自定义造型钢筋的接口 如何将数据传入 RebarUpdateServer ?
RebarUpdateServer 设定 CustomHandle- 在插件的命令中为这些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 基本就是这些了,如果有相似的需求,可以以此为基础去进行改造。
|