Revit 2014 API is going to Blow Your Faces Out!

public void explodeMe()
{
    UIDocument uidoc = this.ActiveUIDocument;
    Document doc = uidoc.Document;

    // Create filter for all walls and roofs (RoofBase is the base class for the ExtrusionRoof & FootprintRoof classes
    ElementClassFilter wallFilter = new ElementClassFilter(typeof(Wall),false);
    ElementClassFilter roofFilter = new ElementClassFilter(typeof(RoofBase),false);
    LogicalOrFilter orFilter = new LogicalOrFilter(wallFilter, roofFilter);

    // explode each element 25 feet from its real location
    double displacementDistance = 25;

    using (Transaction t = new Transaction(doc, "Explode"))
    {
        t.Start();
        foreach (Element e in new FilteredElementCollector(doc).WherePasses(orFilter))
        {
            IList<ElementId> idsToDisplace = new List<ElementId>();
            idsToDisplace.Add(e.Id);

            // explode will offset each element in the direction normal to one of its "major" faces (top face for roof, side face for wall)
            Face face = null;
            HostObject hostObj = e as HostObject;
            if (hostObj is Wall)
            {
                Wall w = hostObj as Wall;

                // only explode the exterior walls
                if (!w.WallType.Name.Contains("Exterior"))
                    continue;

                face = hostObj.GetGeometryObjectFromReference(HostObjectUtils.GetSideFaces(hostObj, ShellLayerType.Exterior).First()) as Face;
            }
            else if (hostObj is RoofBase)
                face = hostObj.GetGeometryObjectFromReference(HostObjectUtils.GetTopFaces(hostObj).First()) as Face;
            // Find the face normal at the center of the face
            BoundingBoxUV bbox = face.GetBoundingBox();
            // center of the face in the UV of the face
            UV center = new UV((bbox.Max.U - bbox.Min.U)/2 + bbox.Min.U, (bbox.Max.V - bbox.Min.V)/2 + bbox.Min.V);
            XYZ faceNormal = face.ComputeNormal(center);

            // inserts are not automatically exploded with their hosts, so find them here and add them to the list
            foreach (FamilyInstance fi in new FilteredElementCollector(doc).OfClass(typeof(FamilyInstance)).Cast<FamilyInstance>().Where(f => f.Host != null && f.Host.Id == hostObj.Id))
            {
                idsToDisplace.Add(fi.Id);
            }

            DisplacementElement displacementElement = DisplacementElement.Create(doc, idsToDisplace, faceNormal.Multiply(displacementDistance), doc.ActiveView, null);

            // Create a Displacement Path annotation connecting the displaced element with its true location
            Options options = new Options();
            options.ComputeReferences = true;
            Reference edgeRef = null;
            // get a reference to any edge in the displaced element
            foreach (GeometryObject gobj in hostObj.get_Geometry(options))
            {
                if (gobj is Solid)
                {
                    Solid solid = gobj as Solid;
                    Edge edge = solid.Faces.get_Item(0).EdgeLoops.get_Item(0).get_Item(0);
                    edgeRef = edge.Reference;
                    break;
                }
            }
            ElementId pathId = DisplacementPath.Create(doc, displacementElement, edgeRef, 0.5);
        }
        t.Commit();
    }
}
Advertisements

One thought on “Revit 2014 API is going to Blow Your Faces Out!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s