有人碰到一个比较头疼的问题,就是试了好多种Document.Create.NewFamilyInstance的重载,都无法把想要的东西在墙上创建出来。
下图就是他想要创建的墙上的灯具:
我们手工放置的时候,可以发现它是放在墙的某个面上的,所以,基本可以排除其他NewFamilyInstance的重载函数,而只锁定下面的几个:
NewFamilyInstance(Reference, Line position, FamilySymbol)
NewFamilyInstance(Reference, XYZ location, XYZ referenceDirection, FamilySymbol)
NewFamilyInstance(Face, Line position, FamilySymbol)
NewFamilyInstance(Face, XYZ location, XYZ referenceDirection, FamilySymbol)
而该实例是放置在一个点的位置,所以我们决定使用这个方法:
NewFamilyInstance(Reference, XYZ location, XYZ referenceDirection, FamilySymbol)
观察该方法的几个参数,第一个Reference,应该就是面的引用,第二个是放置点的位置,第三个是旋转方向,第四个就是族类型了。
那么如何获得面的引用?
RevitAPI有一个类叫HostObjectUtils,提供了几个方法可以方便的获得宿主元素的面,比如GetSideFaces就是专门用来获取墙的侧面的。
var reference = HostObjectUtils.GetSideFaces(wall, ShellLayerType.Interior).First();
ShellLayerType用来指明是内墙还是外墙,.First()用来获取第一个引用,一般一面墙只有一个侧面嘛。
接下来就简单了,整个代码如下:
FamilySymbol familySymbol = GetFamilySymbol("Switch board");
ElementId elementId = new ElementId(308696);
Wall wall = RevitDoc.GetElement(elementId) as Wall;
var reference = HostObjectUtils.GetSideFaces(wall, ShellLayerType.Interior).First();
if (wall != null)
{
var instance = RevitDoc.Create.NewFamilyInstance(reference,
new XYZ(13.3997604933275,-1.35161192601243,9.0571329707487),
new XYZ(0,0,0),
familySymbol);
if (instance == null)
TaskDialog.Show("ERROR", "Instance is null!");
}
这里我们不需要旋转实例,所以referenceDirection直接设为(0,0,0)了。
然而新的问题出现,API创建的和手工创建的并不是完全一样的,
手工创建的如下图:
API创建的是这样的:
很显然,手工创建的Elevaion是可以编辑的,而API创建的是无法编辑的!
那怎么办?
经过仔细观察,我们发现,API创建的实例还有另外一个属性和手工创建的不一样,那就是Schedule Level,或者叫“明细表标高”,API创建出来的值是空的。
所以,我们只要修改到和手工创建一样就可以啦。
Parameter parameter = instance.get_Parameter(
BuiltInParameter.INSTANCE_SCHEDULE_ONLY_LEVEL_PARAM);
if (parameter != null)
{
parameter.Set(new ElementId(311));
}