Wall Modifier IUpdater

Wall Modifier IUpdater

ryansC5XHQ
Contributor Contributor
1,644 Views
9 Replies
Message 1 of 10

Wall Modifier IUpdater

ryansC5XHQ
Contributor
Contributor

I keep getting an error. Any advice? I'm just trying to place a door in the wall based on a parameter selection.

 

public class Modify_Wall_Modeling : IUpdater
{
static AddInId m_appid;
static UpdaterId m_updaterId;

public Modify_Wall_Modeling(AddInId id)
{
m_appid = id;
m_updaterId = new UpdaterId(m_appid, new Guid("D1B8E39B-FE1E-4C99-949E-93B11B34A0CC"));
}

public void Execute(UpdaterData data)
{
#region updaterUI
Document doc = data.GetDocument();
//Autodesk.Revit.DB.View view = doc.ActiveView as Autodesk.Revit.DB.View;
//PhaseStandardTools phaseStandardTools = new PhaseStandardTools();
//CreateRoofSlab create_roof_slab = new CreateRoofSlab();
//RibbonPanelClass ribbon_panel_class = new RibbonPanelClass();
BuildingComponentClass bcc = new BuildingComponentClass();
BuildingComponentToolsClass bctc = new BuildingComponentToolsClass();

//FilteredElementCollector wall_collector = new FilteredElementCollector(doc,doc.ActiveView.Id).OfClass(typeof(Wall));

foreach (ElementId id in data.GetModifiedElementIds())
{
try
{

Wall wall = doc.GetElement(id) as Wall;

bcc.Wall_Modeling(wall, doc);

}
catch
{
continue;
}
}

#endregion
}

public string GetAdditionalInformation()
{
return "Wall Model Modify";
}

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

public UpdaterId GetUpdaterId()
{
return m_updaterId;
}

public string GetUpdaterName()
{
return "Modify Wall Updater";
}

}

 

 

ryansC5XHQ_0-1601928423718.png

 

0 Likes
Accepted solutions (1)
1,645 Views
9 Replies
Replies (9)
Message 2 of 10

RPTHOMAS108
Mentor
Mentor

You know with that kind of message it is somewhere in the Execute method. So you'll have to go a bit deeper than what you have shown for items such as BuildingComponentClass.

 

I don't know that you can 100% of the time avoid this message. Interactions with document changes due to other updaters and the failure handling process is never simple. How do you allow for what someone else has done and the changes they want to make with their updater?

 

0 Likes
Message 3 of 10

ryansC5XHQ
Contributor
Contributor

IUpdater trigger is set to Element.ChangetypeAny(). I just wonder if inserting a door through the wall IUpdater is triggering another execute method before the first execute method is finished.  If that is the case, then I'm simply stumped?  I'm kind of glad to hear that I am not the only one dealing with this.

0 Likes
Message 4 of 10

jeremytammik
Autodesk
Autodesk
Accepted solution

Possibly, your Execute method is performing an action that re-triggers your updater, thus entering an infinite loop.

 

You could introduce a boolean variable in your Execute method to prevent it from starting such a recursive sequence.

 

You can use the Idling event to reset your variable back again once the transaction has been committed and Revit has settled down again.

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes
Message 5 of 10

ryansC5XHQ
Contributor
Contributor

Jeremy,

You are spot on, and that was what I was afraid of.  Very humble for your opinion.

 

blessings,

Ryan S.

0 Likes
Message 6 of 10

ryansC5XHQ
Contributor
Contributor

Jeremy,

 

The boolean will stop the possible recursive sequence, but I lose my door that is created. Any suggestions?

 

 

Regards,

Ryan S

0 Likes
Message 7 of 10

jeremytammik
Autodesk
Autodesk

That means that some step is cancelling the door creation step.

 

Check your return values from the Execute method. Oops; it is void.

   

Actually, the proper way to avoid a rersive call is to set the right level of change priority:

 

https://www.revitapidocs.com/2020/494c6daa-617d-1bc2-b3a8-c4b817240b93.htm

 

Identifies the nature of the change the Updater will be performing. Used to identify order of execution of updaters. Called once during registration of the updater.
 
Depending on the change priority, the updater will be executed sooner or later, and that will affect what updaters (including itself, maybe) may come after it has been executed.
 
In most cases, you would want to set the change priority so that an updaters trigger is not fired by the changes made by the updater Execute.
  


Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes
Message 8 of 10

ryansC5XHQ
Contributor
Contributor

I'm all ears......

 

Here is my method that returns a familyinstance.

 

 

public FamilyInstance create_door_in_wall(Wall wall, string doortype_name, Document doc)
{

ElementId level_id = wall.LevelId;

Level level = doc.GetElement(level_id) as Level;

Parameter p_wall_length = wall.get_Parameter(BuiltInParameter.CURVE_ELEM_LENGTH);

double wall_length = p_wall_length.AsDouble();

 

LocationCurve lc = wall.Location as LocationCurve;

Curve curve = lc.Curve as Curve;

Line line = curve as Line;

double end_point = curve.GetEndParameter(0);

double centerpoint_double = end_point + (wall_length / 2);

 

XYZ centerpoint = curve.Evaluate(centerpoint_double, false);

 

FamilySymbol fs = new FilteredElementCollector(doc).OfClass(typeof(FamilySymbol)).First(q => q.Name == doortype_name) as FamilySymbol;

FamilyInstance fi = doc.Create.NewFamilyInstance(centerpoint, fs, wall, level, StructuralType.NonStructural);

 

wall.LookupParameter("Create Door").Set(0);

}

0 Likes
Message 9 of 10

ryansC5XHQ
Contributor
Contributor

Jeremy,

 

I was able to work out the bool for the IUpdater.  I IUpdater works perfectly inside a group and a door is created. 

Just a side note-I was able to verify the potential loop in the IUpdater when inside a group, but no loop present outside of a group edit mode. Stumped! lol

 

ryansC5XHQ_1-1602070376172.png

 

 

If I select a wall to outside of a group, I get the IUpdater error,see picture below.

 

ryansC5XHQ_0-1602070240343.png

 

Any clues?

 

0 Likes
Message 10 of 10

ryansC5XHQ
Contributor
Contributor

Jeremy,

 I found a solution. I simply raise an ExternalEvent (from inside the IUpdater) in the event-specific parameters are checked. If the wall is inside a group the IUpdater will do the trick!

0 Likes