#BILTNA2018 Wish 3 Granted: Level remap to allow safe level deletion

The problem

If you delete a level in Revit, it deletes all objects on that level – no warning is given.

There should be a safe way of finding objects that are assigned to that level and reassigning them to a different level.

Perhaps Revit could automatically assign them to the level below?

Its a real problem if you create too many levels at the beginning of a project, you cant then delete some as you’ll lose information.

The solution – an API command to remap elements so they no longer reference the selected level
public void levelRemap()
{
    Document doc = this.ActiveUIDocument.Document;
    UIDocument uidoc = this.ActiveUIDocument;
    Level level = doc.GetElement(uidoc.Selection.PickObject(ObjectType.Element, "Select level")) as Level;
    
    Level levelBelow = new FilteredElementCollector(doc)
        .OfClass(typeof(Level))
        .Cast<Level>()
        .OrderBy(q => q.Elevation)
        .Where(q => q.Elevation <= level.Elevation)
        .FirstOrDefault();
    
    if (levelBelow == null)
    {
        TaskDialog.Show("Error", "No level below " + level.Elevation);
        return;
    }
    
    List<string> paramsToAdjust = new List<string> { "Base Offset", "Sill Height", "Top Offset"};
    
    List<Element> elements = new FilteredElementCollector(doc).WherePasses(new ElementLevelFilter(level.Id)).ToList();
    using (Transaction t = new Transaction(doc, "Level Remap"))
    {
        t.Start();
        foreach (Element e in elements)
        {
            foreach (Parameter p in e.Parameters)
            {
                if (p.StorageType != StorageType.ElementId || p.IsReadOnly)
                    continue;
                if (p.AsElementId() != level.Id)
                    continue;
                
                double elevationDiff = level.Elevation - levelBelow.Elevation;
                
                p.Set(levelBelow.Id);
                
                foreach (string paramName in paramsToAdjust)
                {
                    Parameter pToAdjust = e.LookupParameter(paramName);
                    if (pToAdjust != null && !pToAdjust.IsReadOnly)
                        pToAdjust.Set(pToAdjust.AsDouble() + elevationDiff);
                }
            }
        }
        t.Commit();
    }
}
Advertisements

4 thoughts on “#BILTNA2018 Wish 3 Granted: Level remap to allow safe level deletion

  1. Great Harry. I have develop something similar years ago for my company. Our app display a list
    of elements attached to each level and a list of levels to choose one and change the elements. There are some special cases for certains categories that require more code to make it work I all.

  2. Hi Harry, Just testing this out on the advanced sample project and a few errors pop up. In addition it seems that floors at the selected level are getting deleted

    • I added “Height Offset From Level” to the paramsToAdjust list. I’m starting to see how this works. There’d be an issue with elements associated to two levels ie top and bottom. Columns for axample have a bottom level and a top level. Walls can be attached to a top level. How would you adjust the script to account for this?

      • Hi Alexis – You are right that some additional work would be needed to take this proof-of-concept to the next level (pun intended!). For example, the Top Offset should only be set if the Top Level (for columns) or Top Constraint (for walls) is set.

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 )

Google+ photo

You are commenting using your Google+ 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 )

Connecting to %s