API的方式创建一个立方体族,然后创建两个实例参数长度和宽度
、创建了X方向和Y方向的两个尺寸标志,然后把两个尺寸标注关联到参数
总结API做族的步骤:
- 创建族
- 创建参数
- 创建尺寸标注
- 尺寸标注和参数关联
private void CreateEx()
{
var path = @"C:\ProgramData\Autodesk\RVT 2020\Family Templates\Chinese\公制常规模型.rft";
var savePath = @"D:\Revit族\revit-family\" + DateTime.Now.Ticks.ToString() + ".rfa";
var famDoc = _uiapp.Application.NewFamilyDocument(path);
var manager = famDoc.FamilyManager;
var trans = new Transaction(famDoc, "createex");
trans.Start();
//创建参数
var lengthParameter = manager.AddParameter("长度", BuiltInParameterGroup.PG_GEOMETRY, ParameterType.Length, true);
var widthParameter = manager.AddParameter("宽度", BuiltInParameterGroup.PG_GEOMETRY, ParameterType.Length, true);
var width = 100d;
var center = XYZ.Zero;
var p1 = center + XYZ.BasisY * width - XYZ.BasisX * width;
var p2 = p1 + XYZ.BasisX * 2 * width;
var p3 = p2 - XYZ.BasisY * 2 * width;
var p4 = p3 - XYZ.BasisX * 2 * width;
var array = new CurveArray();
var line1 = Line.CreateBound(p1, p2);
var line2 = Line.CreateBound(p2, p3);
var line3 = Line.CreateBound(p3, p4);
var line4 = Line.CreateBound(p4, p1);
array.Append(line1);
array.Append(line2);
array.Append(line3);
array.Append(line4);
var profile = new CurveArrArray();
profile.Append(array);
var plane = Plane.CreateByNormalAndOrigin(XYZ.BasisZ, XYZ.Zero);
var sk = SketchPlane.Create(famDoc, plane);
var extrusion = famDoc.FamilyCreate.NewExtrusion(true, profile, sk, 200);
var view = new FilteredElementCollector(famDoc).OfClass(typeof(View)).WhereElementIsNotElementType()
.Cast<View>().FirstOrDefault(x => x.Name.Contains("参照标高"));
famDoc.Regenerate();
var opt = new Options()
{
ComputeReferences = true
};
var geometry = extrusion.get_Geometry(opt);
var ref1 = default(Reference);
var ref11 = default(Reference);
var ref2 = default(Reference);
var ref22 = default(Reference);
foreach (var geo in geometry)
{
var solid = geo as Solid;
if (solid != null && solid.Faces.Size > 0 && solid.Volume > 0)
{
foreach (var face in solid.Faces)
{
var pf = face as PlanarFace;
if (pf != null && pf.FaceNormal.IsAlmostEqualTo(XYZ.BasisX))
{
ref1 = pf.Reference;
}
else if (pf != null && pf.FaceNormal.IsAlmostEqualTo(XYZ.BasisX.Negate()))
{
ref11 = pf.Reference;
}
else if (pf != null && pf.FaceNormal.IsAlmostEqualTo(XYZ.BasisY))
{
ref2 = pf.Reference;
}
else if (pf != null && pf.FaceNormal.IsAlmostEqualTo(XYZ.BasisY.Negate()))
{
ref22 = pf.Reference;
}
}
}
}
//创建尺寸标注
if (ref1 != null && ref11 != null)
{
var refArray = new ReferenceArray();
refArray.Append(ref1);
refArray.Append(ref11);
var widthDim = famDoc.FamilyCreate.NewDimension(view, line1, refArray);
//参数和尺寸标注做关联
widthDim.FamilyLabel = widthParameter;
}
if (ref2 != null && ref22 != null)
{
var refArray = new ReferenceArray();
refArray.Append(ref2);
refArray.Append(ref22);
var lengthDim = famDoc.FamilyCreate.NewDimension(view, line2, refArray);
//参数和尺寸标注做关联
lengthDim.FamilyLabel = lengthParameter;
}
trans.Commit();
trans.Dispose();
famDoc.SaveAs(savePath);
}
API做族的时候有一个比较难受的地方是拿对应的Refenence,创建拉伸之前的Profile中的直线的Reference是空的,只能先创建轮廓,然后创建拉伸,然后再从拉伸中提取几何信息,拿到面的Refence,然后还要指定中间的那个尺寸线,才可以创建尺寸标注。这波操作下来,我觉得是挺傻的,不知道API为为啥要这么设计,但是二次开发也没办法,只能这么用。