#RTCEUR Wish 3 continued & discussed – automatic revision clouds

In the previous post I showed how the API can create a revision and cloud for elements selected by the user. Now, what if you wanted the revisioning to be done automatically every time the user makes a change, addition, or deletion?

It works nicely when the table is moved or a new, wall is created that does not join with other walls.

But what happens when a window is moved or a wall that joins to other walls is created? Too many elements are included in the revision cloud – not good! This is because when the user modifies an element hosted by the wall, Revit makes changes to both the hosted element (such as the door) and also the wall that hosts the door. The same issue comes up when a new wall joins with existing walls – they all are changed. GetModifiedElementIds does not let us differentiate between the element that the user changed and the elements that Revit changed because of the user change.

It might be possible to get the selected element using the Idling event, store its element id, and then in the updater only create the revision cloud around this element if it was modified.

Automatically creating a revision cloud around an element’s former location after it has been deleted is even harder. GetDeletedElementIds gives the ids of the deleted elements, but because they are deleted they no longer have a bounding box or location that you can get to define the curves of the revision cloud. To do this you would need to store the id and bounding box coordinates of every element in the model, and then retrieve that data after the element is deleted. If smoke starts coming out of your computer from doing this, don’t say I didn’t warn you.

public class AutoRevisionCloudUpdater : IUpdater
{
    static AddInId m_appId;
    static UpdaterId m_updaterId;
    public AutoRevisionCloudUpdater(AddInId id)
    {
        m_appId = id;
        m_updaterId = new UpdaterId(m_appId, new Guid("1BF2F6A2-4C06-42d4-97C1-D1B4EB593EFF"));
    }
    public void Execute(UpdaterData data)
    {
        Document doc = data.GetDocument();
        
        // create list of all modified and created elements
        List<ElementId> ids = data.GetModifiedElementIds().ToList();
        ids.AddRange(data.GetAddedElementIds().ToList());
        
        foreach (ElementId id in ids)
        {        
            makeRevCloud(doc, id);
        }
    }
    public string GetAdditionalInformation(){return "Auto Revision Cloud";}
    public ChangePriority GetChangePriority(){return ChangePriority.FloorsRoofsStructuralWalls;}
    public UpdaterId GetUpdaterId(){return m_updaterId;}
    public string GetUpdaterName(){return "Auto Revision Cloud";}
    
    private void makeRevCloud(Document doc, ElementId id)
    {
        Element e = doc.GetElement(id);
            
        // create new revision
        Revision rev = Revision.Create(doc);
        rev.RevisionDate = DateTime.Now.ToLongDateString();
        rev.Description = id.IntegerValue.ToString();
        
        // use bounding box of element and offset to create curves for revision cloud
        BoundingBoxXYZ bbox = e.get_BoundingBox(doc.ActiveView);
        List<Curve> curves = new List<Curve>();
        double offset = 2;
        XYZ pt1 = bbox.Min.Subtract(XYZ.BasisX.Multiply(offset)).Subtract(XYZ.BasisY.Multiply(offset));
        XYZ pt2 = new XYZ(bbox.Min.X - offset, bbox.Max.Y + offset, 0);
        XYZ pt3 = bbox.Max.Add(XYZ.BasisX.Multiply(offset)).Add(XYZ.BasisY.Multiply(offset));;
        XYZ pt4 = new XYZ(bbox.Max.X + offset, bbox.Min.Y - offset, 0);
        curves.Add(Line.CreateBound(pt1, pt2));
        curves.Add(Line.CreateBound(pt2, pt3));
        curves.Add(Line.CreateBound(pt3, pt4));
        curves.Add(Line.CreateBound(pt4, pt1));
        
        // create revision cloud
        RevisionCloud cloud = RevisionCloud.Create(doc, doc.ActiveView, rev.Id, curves);
    }
}

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

    AutoRevisionCloudUpdater updater = new AutoRevisionCloudUpdater(this.Application.ActiveAddInId);
    UpdaterRegistry.RegisterUpdater(updater);
    UpdaterRegistry.AddTrigger(updater.GetUpdaterId(), new ElementClassFilter(typeof(FamilyInstance)), Element.GetChangeTypeGeometry());
    UpdaterRegistry.AddTrigger(updater.GetUpdaterId(), new ElementClassFilter(typeof(FamilyInstance)), Element.GetChangeTypeElementAddition());
    UpdaterRegistry.AddTrigger(updater.GetUpdaterId(), new ElementClassFilter(typeof(Wall)), Element.GetChangeTypeGeometry());
    UpdaterRegistry.AddTrigger(updater.GetUpdaterId(), new ElementClassFilter(typeof(Wall)), Element.GetChangeTypeElementAddition());
}
Advertisements

3 thoughts on “#RTCEUR Wish 3 continued & discussed – automatic revision clouds

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