AutoJoinElements

I just heard that there is an issue with the Document.AutoJoinElements method.
This gave rise to a discussion which raises some interesting points and is worth sharing.

For those of you not familiar with this method, here is the brief description from the Revit API help file:

<

p style=”color:darkblue”>AutoJoinElements forces the elements in the Revit document to automatically join to their neighbours where appropriate.
Use this method to force elements in the document to automatically join to their neighbours.
Note that when a transaction is committed there is an automatic call to automatically join elements.

That sounds pretty clear, doesn’t it?
Unfortunately, it doesn’t quite work that way, at least not at the moment.

Automatic AutoJoinElements Broken

As stated in the help file, all elements requiring joining are automatically joined every time a transaction is committed.
This obviously includes the transaction that is automatically managed by the Revit API framework for a command using the automatic transaction mode.

You may want to call auto-join manually at some point as well, though only in manual regeneration mode, for instance if you need to query the auto-joined geometry for something else.
For example, if you create two walls that will eventually be auto-joined, and want to examine the corner formed by them right away because you want to create something else there.
In order to get the updated and joined geometry and the final resulting corner point, you will need to regenerate and auto-join.

The Regeneration.Automatic mode applies to auto-joining as well.
In any mode though, you should not need to call auto-join (nor regenerate) manually if you do not need to read updated geometry.
The end of the transaction will always perform both no matter what the regeneration mode is.

Unfortunately, right now, you do need to make the explicit call to AutoJoinElements, because the automatic mechanism is not kicking in.
Furthermore, calling AutoJoinElements in automatic regeneration mode will throw an exception, so you cannot do that.
An application that needs this functionality currently has to use manual regeneration.

If I run the Revit API introduction external command Lab2_0_CreateLittleHouse, which creates a little house consisting of four walls with a door and some windows, a floor, a roof, and a room, the end result after the command terminates looks like this:

Little house with unjoined walls

The walls have not been joined at the corners, so somehow the automatic call to AutoJoinElements has not been performed.

This command is using automatic transaction mode and the manual regeneration option.

Adding a call to doc.AutoJoinElements immediately before returning Result.Succeeded fixes the problem:

Little house with joined walls

Questions and Answers on AutoJoinElements

As mentioned above, we had an interesting and fruitful internal discussion in the course of clarifying the intended behaviour of this mechanism:

[Q] I would like some usage tips or comments that help me understand the behaviour of AutoJoinElemens.
Here is what I am doing:
I draw four rectangular walls.
I notice that the wall corners are not automatically shrink wrapped.
If I add an explicit call to AutoJoinElements, they are.
When is the right timing for this?
Right before or after a new element is added?
Does AutoJoinElements only affect one element at a time?

[A] It can be used to affect one single element at a time, and it is also effective for multiple elements.
That’s what I would do here: draw all the new walls, call AutoJoinElements once at the end, and then you should be able to do things like creating rooms for the circuits formed by these walls.

You may also need to regenerate first by calling doc.Regenerate, and then auto-join.
Sometimes, you may even need to regenerate again afterwards as well.

[Q] Thank you, it works now.
So it looks like auto-join is also updating the graphics in this case.
I thought the regeneration would do that.
Your comment about calling the regeneration twice makes more sense now.

[A] Generally, you should not need to regenerate twice, but sometimes it is needed.

Yes, auto-join updates the model.
It updates it in a different way than regeneration.
Technically, auto-join could actually be part of regeneration, but there are performance reasons for them to be two separate methods.

Obviously, you need a transaction to be able to regenerate and auto-join.
The end of the transaction (commit) will do call these for you too, but you can do it yourself (in manual mode) if you need to.

[Q] Another question: how can I partially auto-join, e.g. join certain specific walls but not others?

[A] Auto joining is not for joining walls on demand – it is a step that will eventually be always performed and it will join everything that needs to be joined, according to certain rules.
So it does not matter if you only auto-join two walls in your loop.
At the end you will have to commit your transaction, and during the committing procedure all walls that should be joined will be joined automatically.

[Q] Aha, thank you for the clarification.
I thought this feature is to control join and disjoin behaviour, and that is not the case.

So this means that we only need to call auto-join once when the shrink wrap information is needed.

Regarding the automatically joining, I am using TransactionMode.Automatic and RegenerationOption.Automatic, and the walls are not joined after my command has terminated.
I need to add the call to AutoJoinElements for them to be joined.

[A] As explained above, that is a temporary situation.
The Regeneration.Automatic mode normally applies to auto-joining as well.
You should not need to call auto-join manually in any mode if you do not need to query the updated geometry.
The end of the transaction will always perform both no matter what the regeneration mode is.

Right now you do need to make the explicit call to AutoJoinElements, because the automatic mechanism is not kicking in.
Furthermore, you cannot make that call in automatic regeneration mode due to it throwing an exception, so an application that needs this functionality currently has to use manual regeneration.

Very many thanks to Mikako Harada, Scott Conover and Arnošt Löbel for this useful information, and sorry for the temporary bad news for application developers relying on the automatic mechanism.


Comments

11 responses to “AutoJoinElements”

  1. pnavarra Avatar
    pnavarra

    Hi Jeremy,
    Iv’e got problems when I create a PulldownButtonData.
    It is grayed out…do you know why.
    When I create separated PushButtons, it works….
    Cheers!

  2. Dear Pierre,
    No, I have never encountered this problem. Here are some sample code snippets excerpted from the Revit API introduction Lab6_2_Ribbon application that work for me:
    // prepare data for creating stackable buttons
    PushButtonData pbd1 = new PushButtonData( name1 + ” 2″, text1, addInPath, cmd1 );
    PushButtonData pbd2 = new PushButtonData( name2, text2, addInPath, cmd2 );
    PulldownButtonData pbd3 = new PulldownButtonData( name3, text3 );
    // add stackable buttons
    IList ribbonItems = panel.AddStackedItems( pbd1, pbd2, pbd3 );
    // add two push buttons as sub-items of the Lab 1 commands
    PulldownButton pb3 = ribbonItems[2] as PulldownButton;
    pbd = new PushButtonData( name1, text1, addInPath, cmd1 );
    PushButton pb3_1 = pb3.AddPushButton( pbd );
    pbd = new PushButtonData( name2, text2, addInPath, cmd2 );
    PushButton pb3_2 = pb3.AddPushButton( pbd );
    Cheers, Jeremy.

  3. Konstantin Avatar
    Konstantin

    Jeremy,
    Is there a way to prevent members from auto-joining? I have an issue where I have structural framing with tiny offsets (intentionally introduced for connections). During automatic import via code all that geometry gets messed up becuase Revit readjusts member centerlines as it sees fit.

  4. Dear sir,
    How can i connect two pipe programmatically?
    Thanks & Regards,
    Nitin

  5. Dear Konstantin,
    Revit 2012 offers the possibility to allow and disallow wall end joins (cf. What’s New in the help file), but I do not believe there is any API access to this for other elements.
    Cheers, Jeremy.

  6. Dear Nitin,
    You can look at
    http://thebuildingcoder.typepad.com/blog/2011/04/use-of-newtakeofffitting-on-a-pipe.html
    That presents a simple solution.
    Apparently, there are a large number of potential complications, as our frequent correspondent Kailash Kute has pointed out. He explains a number of issues that he ran into and how to resolve some of them in his comments on
    http://thebuildingcoder.typepad.com/blog/2011/02/create-a-pipe-cap.html
    Cheers, Jeremy.

  7. Dear sir,
    I m using AutoJoinElements() with pipes and couplings but it is not connecting them.
    What can be the problem?
    Thanks & Regards,
    -Nitin

  8. Dear Nitin,
    I do not believe that AutoJoinElements will do anything to connect your pipes and couplings.
    To achieve that, you can either connect them yourself manually by querying and using methods on their respective connector manager objects, or use the dedicated methods to insert fittings which will automatically connect the elements as well:
    http://thebuildingcoder.typepad.com/blog/2010/05/cable-tray-orientation-and-fittings.html
    http://thebuildingcoder.typepad.com/blog/2011/02/use-of-newtakeofffitting-on-a-duct.html
    http://thebuildingcoder.typepad.com/blog/2011/02/create-a-pipe-cap.html
    http://thebuildingcoder.typepad.com/blog/2011/04/use-of-newtakeofffitting-on-a-pipe.html
    Cheers, Jeremy.

  9. Hi Jeremy,
    When I creating wall or other component in working my project by revit, my revit slowly progress (about 30 second ~ few minute.
    Please help me in my picture at
    http://dotuanhanh.blogspot.com/2014/04/revit-model-performance-optimization.html
    Regards,

  10. Dear Augi,
    I will happily advise you on Revit API programming issues.
    For product usage and performance issues, I would suggest talking with product support.
    Good luck.
    Cheers, Jeremy.

  11. Yes Sir,
    Thank you so much.

Leave a Reply to Augi DomeoCancel reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading