Divide Parts at Levels

On the AUGI Revit API wish list it was mentioned that it would be nice to be able to divide parts at levels.

Wish granted!

divideparts


public void CreatePartAndDivideAtLevels()
{
    Document doc = this.ActiveUIDocument.Document;
    UIDocument uidoc = new UIDocument(doc);
    ElementId id = uidoc.Selection.PickObject(ObjectType.Element).ElementId;
    IList<ElementId> ids = new List<ElementId>();
    ids.Add(id);

    using (Transaction t = new Transaction(doc,"Create Part"))
    {
        t.Start();
        // Create parts from the selected element
        // There is "CreateParts" but no "CreatePart", so needed to use a list containing the one element
        PartUtils.CreateParts(doc,ids);
        t.Commit();
    }

    // Get the newly created parts
    ICollection<ElementId> partsList = PartUtils.GetAssociatedParts(doc,id,false,false);

    // Get all levels
    ICollection<ElementId> levels = new FilteredElementCollector(doc).OfClass(typeof(Level)).OfCategory(BuiltInCategory.OST_Levels).ToElementIds();

    // Create a list of curves which needs to be used in DivideParts but for this example
    // the divide is being done by levels so the curve list will be empty
    IList<Curve> curveList = new List<Curve>();

    // Get the host object corresponding to the selected element
    // HostObject is the parent class for walls, roof, floors, etc.
    HostObject hostObj = doc.GetElement(id) as HostObject;

    // Get the reference of one of the major faces of the selected element
    // Will be used to create a sketch plane
    Reference r = HostObjectUtils.GetSideFaces(hostObj, ShellLayerType.Exterior).First();

    using (Transaction t = new Transaction(doc,"Divide Part at Levels"))
    {
        t.Start();
        SketchPlane sketchPlane = doc.Create.NewSketchPlane(r);
        // Divide the parts
        PartUtils.DivideParts(doc, partsList, levels, curveList, sketchPlane.Id);
        t.Commit();
    }

    // Set the view's "Parts Visibility" parameter so that parts are shown
    Parameter p = doc.ActiveView.get_Parameter(BuiltInParameter.VIEW_PARTS_VISIBILITY);
    using (Transaction t = new Transaction(doc,"Set View Parameter"))
    {
        t.Start();
        p.Set(0); // 0 = Show Parts, 1 = Show Original, 2 = Show Both
        t.Commit();
    }            
}