Revit API Forum
Welcome to Autodesk’s Revit API Forums. Share your knowledge, ask questions, and explore popular Revit API topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Room area won't trigger updater

17 REPLIES 17
SOLVED
Reply
Message 1 of 18
AGGilliam
661 Views, 17 Replies

Room area won't trigger updater

I have an updater that will detect when rooms have been added or deleted to keep track of the counts, because the default count can't be used in formulas. I just tried adding a trigger for the room area so that when rooms are removed they are fully deleted so the user doesn't have to filter the schedule and delete it from there. The updater is triggered when I change the area with a room bounding line but, if I remove the room, the updater won't trigger even though the area changes to zero. Any thoughts on why that wouldn't work or how I might delete the rooms another way?

Tags (2)
Labels (1)
17 REPLIES 17
Message 2 of 18
RPTHOMAS108
in reply to: AGGilliam

Are you using GetChangeTypeParameter? Not sure why that wouldn't work if the value was changing but the code example may help with that. There have been issues with other types of parameter not triggering in the past but in those cases they didn't trigger at all.

 

 

Message 3 of 18
AGGilliam
in reply to: RPTHOMAS108

Here's the code for the trigger, I don't think I did anything weird other than put three changetypes in there. I originally just had two (addition and deletion) but after adding the parameter they still seem to trigger. I tried looking for another parameter to use, but the only one I could think of would have been location and I couldn't figure out what the id would be for that.

 

internal void AddTrigger()
        {
            UpdaterRegistry.AddTrigger(updaterid, new ElementCategoryFilter(BuiltInCategory.OST_Rooms),
                ChangeType.ConcatenateChangeTypes(Element.GetChangeTypeElementAddition(), ChangeType.ConcatenateChangeTypes(Element.GetChangeTypeElementDeletion(), Element.GetChangeTypeParameter(new ElementId(BuiltInParameter.ROOM_AREA)))));
        }

 

Message 4 of 18

Hi AGilliam, I ran into this problem before, try changing the ElementCategoryFilter by an ElementCassFilter of a type SpatialElement : new ElementClassFilter(typeof(SpatialElement)).

your code will look like this.

internal void AddTrigger()
        {
            UpdaterRegistry.AddTrigger(updaterid,new ElementClassFilter(typeof(SpatialElement)),
                ChangeType.ConcatenateChangeTypes(Element.GetChangeTypeElementAddition(), ChangeType.ConcatenateChangeTypes(Element.GetChangeTypeElementDeletion(), Element.GetChangeTypeParameter(new ElementId(BuiltInParameter.ROOM_AREA)))));
        }
;
Message 5 of 18

Just tested this and I got the same results, it triggers when I change the area by adding a room bounding line but not when the room is removed.
Message 6 of 18

You should Adding the trigger three different times instead of concatenating the changeType.

internal void AddTrigger()
        {
            UpdaterRegistry.AddTrigger(updaterid,new ElementClassFilter(typeof(SpatialElement)),Element.GetChangeTypeElementAddition());
            UpdaterRegistry.AddTrigger(updaterid,new ElementClassFilter(typeof(SpatialElement)),Element.GetChangeTypeElementDeletion());
            UpdaterRegistry.AddTrigger(updaterid,new ElementClassFilter(typeof(SpatialElement)),Element.GetChangeTypeParameter(new ElementId(BuiltInParameter.ROOM_AREA)));
        }

 

Message 7 of 18

I split them into separate statements like you suggested, but it's still functioning the same as before.
Message 8 of 18
AGGilliam
in reply to: AGGilliam

I just remembered that GetChangeTypeAny exists so I decided to test that out and it's triggering when the room gets removed like I originally expected, but I still have no idea what's actually triggering it if the change in area didn't work. I don't like the idea of the updater triggering for every change though, so I'm open to other ideas.

Message 9 of 18
RPTHOMAS108
in reply to: AGGilliam

Remarks section for Element.GetChangeTypeParameter in RevitAPI.chm:

"...Note: This change type will not trigger on newly created or deleted elements."

 

So I would try again adding the separate triggers (Added/Removed/Parameter Changed) with the category filter for Rooms. You could use the class filter with SpatialElement but that then also includes changes to Areas & Spaces. You can't use Room class with ElementClassFilter because the Room class isn't in 'Revit's native object model'.

 

If you simplify it to those three triggers and it still doesn't work then create a minimum reproducible case. Since Autodesk has never confirmed you shouldn't be using a category filter for this (that should not be the case).

 

In the RevitAPI.chm the UpdaterRegistry.AddTrigger method overloads that takes a Filter actually note under the remarks section:

"This method only works with CategoryFilter and ParameterFilter."

 

Which is odd since this Wall updater example uses an ElementClassFilter.

 

Message 10 of 18
AGGilliam
in reply to: RPTHOMAS108

What does the ChangeType have to do with the filter? Both filters seem to work just fine as the updater is triggered in all of the other expected scenarios, and the room is neither newly created or deleted just removed (perhaps unplaced is a more appropriate term?). The parameter ChangeType works, just not in this specific scenario for some reason even though that parameter is being changed in both instances. Unless Revit considers an unplaced room deleted?
Message 11 of 18
RPTHOMAS108
in reply to: AGGilliam

The first time you've mentioned 'unplaced' is just now.

 

Would suggest then you create a minimum reproducible case with only the GetChangeTypeParameter. The filter is still required in the AddTrigger method regardless.

 

The Area for rooms parameter is kind of an odd one since when unplaced it will display 'Not Enclosed' in the UI, in RevitLookup it notes 0. So I still assume a change from +ve to 0 should be picked up as a parameter change.

 

 

Message 12 of 18
AGGilliam
in reply to: RPTHOMAS108

You're right, I've been saying removed up until this point, but unplaced is what I meant. Sorry if that wasn't clear. Just to re-iterate my original intent, I'm trying to fully delete rooms that have been removed/unplaced so I need to detect that change with the updater. I've pasted a portion of my code below:

 

class RegRoomTracker : IExternalApplication
    {
        RoomTracker updater = null;

        public Result OnStartup(UIControlledApplication uiapp)
        {
            AddInId addinId = uiapp.ActiveAddInId;
            updater = new RoomTracker(addinId);
            updater.RegisterUpdater();
            updater.AddTrigger();
            return Result.Succeeded;
        }

        public Result OnShutdown(UIControlledApplication uiapp)
        {
            UpdaterRegistry.UnregisterUpdater(updater.GetUpdaterId());
            return Result.Succeeded;
        }
    }

    class RoomTracker : IUpdater
    {
        private UpdaterId updaterid;

        internal RoomTracker(AddInId addinId)
        {
            updaterid = new UpdaterId(addinId, new Guid("5CCFA69E-03F3-46D6-875D-5BB6FEF59190"));
        }

        internal void RegisterUpdater()
        {
            if (!UpdaterRegistry.IsUpdaterRegistered(updaterid))
                UpdaterRegistry.RegisterUpdater(this, true);
        }

        internal void AddTrigger()
        {
            
            UpdaterRegistry.AddTrigger(updaterid, new ElementCategoryFilter(BuiltInCategory.OST_Rooms), Element.GetChangeTypeElementAddition());
            UpdaterRegistry.AddTrigger(updaterid, new ElementCategoryFilter(BuiltInCategory.OST_Rooms), Element.GetChangeTypeElementDeletion());
            UpdaterRegistry.AddTrigger(updaterid, new ElementCategoryFilter(BuiltInCategory.OST_Rooms), Element.GetChangeTypeParameter(new ElementId(BuiltInParameter.ROOM_AREA)));
            //UpdaterRegistry.AddTrigger(updaterid, new ElementClassFilter(typeof(SpatialElement)), Element.GetChangeTypeParameter(new ElementId(BuiltInParameter.ROOM_LEVEL_ID)));
            //UpdaterRegistry.AddTrigger(updaterid, new ElementClassFilter(typeof(SpatialElement)), Element.GetChangeTypeAny());
        }

        #region IUpdater Members
        public void Execute(UpdaterData data)
        {
            Document doc = data.GetDocument();
            List<ElementId> added = data.GetAddedElementIds().ToList();
            List<ElementId> deleted = data.GetDeletedElementIds().ToList();
            List<ElementId> modified = data.GetModifiedElementIds().ToList();


            // Delete removed rooms
            foreach (ElementId id in modified)
            {
                Room rm = doc.GetElement(id) as Room;
                if (rm.Area == 0)
                    doc.Delete(id);
            }
 }

        public UpdaterId GetUpdaterId()
        {
            return updaterid;
        }

        public ChangePriority GetChangePriority()
        {
            return ChangePriority.Annotations;
        }

        public string GetUpdaterName()
        {
            return "SchemaUpdater";
        }

        public string GetAdditionalInformation()
        {
            return "";
        }
    }

 

Message 13 of 18
RPTHOMAS108
in reply to: AGGilliam

Your code seems to work ok for me when I drag the room outside it's boundary to unplace it.

 

What Revit version are you using?

Message 14 of 18
AGGilliam
in reply to: RPTHOMAS108

Is that how you usually do it? I've been selecting the room and pressing delete, I'll try that and see what happens. I'm using Revit 2022.
Message 15 of 18
AGGilliam
in reply to: RPTHOMAS108

After all that headache, that was the issue. I never knew dragging a room out of its boundaries would remove it so I've always just deleted it, which also throws up a warning. Anyway, thanks for the help!
Message 16 of 18
RPTHOMAS108
in reply to: AGGilliam

Yes a placed room needs a boundary so you unplace it by dragging it out or deleting part of the boundary.

 

Architects sometimes have a number of unplaced rooms populated with parameters defined in their project template which they then copy into the relevant room areas.

 

Rooms are kind of odd they don't follow type/instance relationship but if you delete their physical representation in the UI they still exist in the colour scheme and schedule etc. (they can be scheduled and deleted in UI). Probably Revit keeps hold of them to maintain the room data they hold.

 

It probably would have solved a lot of headaches if they just followed the type/instance dynamic i.e. things common for a type of room defined in the type and other things such as area in the instance of that type.

Message 17 of 18
AGGilliam
in reply to: RPTHOMAS108

That makes sense. Thanks for the explanation, I was curious why that functionality existed. We really only use rooms to label storage units with the room name, so it doesn't make sense for us to keep them around if they're unplaced.
Message 18 of 18
tamas.deri
in reply to: RPTHOMAS108

Are there any further info on this? By our experience it is possible to use multiple type of ElementFilters for the trigger, but also had serious issues because some of our more specific triggers caused irrecoverable model corruption. Since then we only use the officially allowed category and parameter filters, and never had such model crashes. It would be really good to know what is the official explanation for having such note.

@jeremy_tammik?

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Rail Community