前言
PlaceFamilyInstanceByFace 这个例子从 SDK 文档中看到是 2009 版就提供的,估计可能是当时增加了对基于面的族实例放置的 API 支持,所以就写了一个例子。
内容
这个例子写的不太好,里面有 hard code 的内容,它对要用的基于面的点族和线族的名称直接做了限制,然后又没有提供对应的族文件。
// FamilyInstanceCreator::CheckFamilySymbol
case BasedType.Point:
defaultSymbolName = "Point-based";
break;
case BasedType.Line:
defaultSymbolName = "Line-based";
break;
以 Revit 小房子模型为例,需要做些修改,才能正常运行这个插件。
对于 Point-based 族,复制 P-D-66N28T8,并且改名:
对于 Line-based,则自己做一个族,使用 基于线的公制常规模型.rft
族模板。
运行效果,Point-based:
核心逻辑:
public bool CreatePointFamilyInstance(Autodesk.Revit.DB.XYZ locationP, Autodesk.Revit.DB.XYZ directionP, int faceIndex
, int familySymbolIndex)
{
Face face = m_faceList[faceIndex];
if (!m_familySymbolList[familySymbolIndex].IsActive)
m_familySymbolList[familySymbolIndex].Activate();
FamilyInstance instance = m_revitDoc.Document.Create.NewFamilyInstance(face, locationP, directionP, m_familySymbolList[familySymbolIndex]);
List<ElementId> instanceId = new List<ElementId>();
instanceId.Add(instance.Id);
m_revitDoc.Selection.SetElementIds(instanceId);
return true;
}
运行效果,Line-based:
核心逻辑:
public bool CreateLineFamilyInstance(Autodesk.Revit.DB.XYZ startP, Autodesk.Revit.DB.XYZ endP, int faceIndex, int familySymbolIndex)
{
Face face = m_faceList[faceIndex];
Autodesk.Revit.DB.XYZ projectedStartP = Project(face.Triangulate().Vertices as List<XYZ>, startP);
Autodesk.Revit.DB.XYZ projectedEndP = Project(face.Triangulate().Vertices as List<XYZ>, endP);
if (projectedStartP.IsAlmostEqualTo(projectedEndP))
{
return false;
}
Line line = Line.CreateBound(projectedStartP, projectedEndP);
if (!m_familySymbolList[familySymbolIndex].IsActive)
m_familySymbolList[familySymbolIndex].Activate();
FamilyInstance instance = m_revitDoc.Document.Create.NewFamilyInstance(face, line, m_familySymbolList[familySymbolIndex]);
List<ElementId> instanceId = new List<ElementId>();
instanceId.Add(instance.Id);
m_revitDoc.Selection.SetElementIds(instanceId);
return true;
}
这里用都是 NewFamilyInstance
,但它有很多个接受不同参数的重载。详见:Revit API: 创建族实例 FamilyInstance