Following up this suggestion from Julien, here’s a look at how to create a massing family with geometry built from the mesh of a toposurface.
public void topoToMass()
{
Document doc = this.ActiveUIDocument.Document;
UIDocument uidoc = this.ActiveUIDocument;
Application app = this.Application;
TopographySurface topo = doc.GetElement(uidoc.Selection.PickObject(ObjectType.Element)) as TopographySurface;
Mesh mesh = topo.get_Geometry(new Options()).First(q => q is Mesh) as Mesh;
Document famDoc = app.NewFamilyDocument(@"C:\ProgramData\Autodesk\RAC 2014\Family Templates\English_I\Conceptual Mass\Mass.rft");
using (Transaction t = new Transaction(famDoc,"Create massing surfaces"))
{
t.Start();
for (int i = 0; i < mesh.NumTriangles; i++)
{
MeshTriangle mt = mesh.get_Triangle(i);
makeForm(famDoc, mt.get_Vertex(0), mt.get_Vertex(1), mt.get_Vertex(2));
if (i > 0 && i % 100 == 0)
{
TaskDialog td = new TaskDialog("Form Counter");
td.CommonButtons = TaskDialogCommonButtons.Yes|TaskDialogCommonButtons.No;
td.MainInstruction = i + " out of " + mesh.NumTriangles + " triangles processed. Do you want to continue?";
if (td.Show() == TaskDialogResult.No)
break;
}
}
t.Commit();
}
famDoc.LoadFamily(doc);
}
private Form makeForm(Document doc, XYZ pt1, XYZ pt2, XYZ pt3)
{
Form form = null;
XYZ u = pt2.Subtract(pt1);
XYZ v = pt3.Subtract(pt1);
double area = u.CrossProduct(v).GetLength()/2;
if (area < 10)
return null;
ReferenceArray ra = new ReferenceArray();
ra.Append(MakeCuveByPoints(doc, pt1, pt2).GeometryCurve.Reference);
ra.Append(MakeCuveByPoints(doc, pt2, pt3).GeometryCurve.Reference);
ra.Append(MakeCuveByPoints(doc, pt3, pt1).GeometryCurve.Reference);
form = doc.FamilyCreate.NewFormByCap(true, ra);
return form;
}
private CurveByPoints MakeCuveByPoints(Document doc, XYZ ptA, XYZ ptB)
{
ReferencePointArray rpa = new ReferencePointArray();
rpa.Append(doc.FamilyCreate.NewReferencePoint(ptA));
rpa.Append(doc.FamilyCreate.NewReferencePoint(ptB));
return doc.FamilyCreate.NewCurveByPoints(rpa);
}