Get UniqueId of deleted element within dynamic updater? (with feature request)

Get UniqueId of deleted element within dynamic updater? (with feature request)

Anonymous
Not applicable
7,131 Views
30 Replies
Message 1 of 31

Get UniqueId of deleted element within dynamic updater? (with feature request)

Anonymous
Not applicable

Hello all,

 

does anyone know of a supported (work sharing safe) way to obtain the UniqueId of a deleted element within a custom dynamic updater's Execute() method?

 

You get a list of ElementIds which is nice, but the elements can not be retrieved using Document.GetElement(), presumably because they have already been deleted from the document before the updater is called. The only way I know to obtain the UniqueId is directly from the Element, which I don't have. I need to match the deleted elements against a list of UniqueId strings that I have stored previously. I'll settle for unsupported hacks if need be at this stage, but I want to play nice with work sharing if possible.

 

UniqueIds are great for most things, but seem to be completely useless in this situation.

 

Any ideas?

 

Feature request: Failing a solution to the above, it would be nice if a pair of methods could be added to the DB.Document class that would allow directly converting ElementIds to UniqueId strings and vice versa (and would behave nicely for deleted elements within the updater call).

 

Call them something like:

  • GetElementIdFromUniqueId(ElementId id)
  • GetUniqueIdFromElementId(String uid)

Alternatively, providing a list of UniqueIds along with the ElementIds to the UpdaterData object would be handy.

Accepted solutions (1)
7,132 Views
30 Replies
Replies (30)
Message 2 of 31

jeremytammik
Autodesk
Autodesk
Accepted solution

Dear Scott,

 

Nope, sorry, I am not aware of any way to achieve this very understandable goal.

 

Please make a note of the ADN case number 10292440 [Accessing deleted elements] and wish list item CF-2162 [API: DocumentChanging or ElementsDeleting event before element is deleted] that have been raised asking for something similar.

 

I added your request to the wish list item.

 

Arnošt reacted to it a little while ago, asking me, "What exactly the customer wants to do about the deleted elements? What kind of information does she need about them?" and adding that it is extremely unlikely we will create an pre-deletion event, but we may provide some extra information about the elements that got deleted in the last transaction.

 

Any business case you can make and additional information you can provide to underline the importance of this wish and explain to Arnošt what he would like to know will help make it a reality.

 

Thank you!

 

Cheers,

 

Jeremy



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

Message 3 of 31

Anonymous
Not applicable

Thanks for the confirmation Jeremy.

 

I'll shed a bit of light on why I need this functionality and also waffle on a bit about my current project and what I am using the Revit API to achieve.

 

The company I work for manufactures panelised structural roof and wall systems for the construction industry. Part of the service we offer is to take the design documents provided for a building and prepare a full set of manufacturing shop details and on-site assembly instructions specific to our products. This is currently all done manually in 2D AutoCAD with the manufacturing data interpreted and entered manually into our manufacturing systems. It is very labor intensive and prone to error. In terms of complexity and functionality required, it is similar to, but more difficult than structural steelwork detailing.

 

I have the task of developing a suite of add-in applications that take a building modeled in Revit and slice up the walls and roofs into customised product components according to our manufacturing and design parameters. I then must automatically prepare the shop drawings and export the manufacturing data for all components of the building. There are typically many thousands of such components and all have to comply with very complex and context-sensitive panelisation constraints and component selections. The built-in Revit functionality such as curtain walls and component parts could handle some of the work, but there are significant short-falls and show stoppers with each method and so I have needed to re-invent the wheel for many things while leveraging standard Revit functionality in unusual ways as much as possible. I'm over one hundred thousand lines of code into this at this point and there is much further to go.

 

Now within all that mess I need to maintain hierarchies of dependant Revit Elements. This is all pretty straight forward except for the issue of deleted elements. If a user deletes a parent element, I want to detect this in the updater and also remove its children and when a child element is deleted I want to either roll-back the change or re-instate a new element in its place. Because I am using UniqueIds exclusively for storage and tracking and only ever deal with ElementIds for live processing I am unable to determine exactly what relationships (if any) a deleted element has and then act accordingly.

 

In earlier versions of my application it wasn't a strong requirement to support work-sharing so I got around this problem by using a dedicated element dependency tree stored as a singleton DataStorageElement which simply contained the integer values of the ElementIds. Although not ideal and a little clunky to work with, it works fine and has gotten me this far. But now that I need work-sharing it needs to be replaced.

 

I could use the unsupported method to extract the ElementId directly from a UniqueId ( int.Parse(uid.Substring(uid.Length - 8, 8), NumberStyles.HexNumber) ) but again work-sharing will break it.

 

Storing the ElementIds natively into the Entities or as an element parameter won't work either as although they will stay synchonised while work-sharing, they will be set to InvalidElementId before I can read them.

 

The only thing I can see working is to periodically sweep through all elements in the model using idling events looking for orphans and missing children, not very efficient and with the complexity levels these models will be operating at it would be quite laggy.

 

As I see it, providing a list of ElementIds for deleted elements is pointless because anyone following the guideline of only storing UniqueIds can't do anything with them. Replacing the deleted ElementId collection within the UpdaterData object with the equivalent UniqueId strings makes much more sense. I just want to know whether the deleted Element is one that I'm interested in, providing the UniqueId will solve that nicely and increase the usefulness of the API for work-sharing.

 

I think I'll have to ditch the work-sharing support again until something changes.

0 Likes
Message 4 of 31

arnostlobel
Alumni
Alumni
I am sorry it took me so long to respond. Thank you, Scott, for your detailed explanation of your workflow. I asked Jeremy not too long ago to find out what was it users wanted to know about deleted elements (besides their Ids). I asked because I believe there could be something done about it. We could actually give some extra data along the element Ids. When an element is removed from a model, it is not actually deleted yet. It is put on the undo stack in case the deletion should be undone later. So, the removed element sort of still lives on, but it is not in a valid state anymore, because it is detached from the rest of the model. Operations on it should be avoided (even for us, internal developers, I mean). There are situations at which we do examine such elements, but it is always when gathering data we know for sure can still be accessed. So, that is why I asked. There is data that could be useful to have, I suppose, even for the API developer. That's is why I wanted to have a list, eventually, of extra info a typical API developer would like to have access to for deleted elements. With such a list I could check which ones of the data are safe to access and wrap it in some sort of a deleted-element-info class and have it available in those document events and possibly updaters too.

It looks like you, Scott, would be fairly happy if we provide just unique elements Ids along with the regular Ids. Is that correct? Or is there anything else you (or anyone else on this thread) would like to have?

Thank you
Arnošt Löbel
0 Likes
Message 5 of 31

jeremytammik
Autodesk
Autodesk

Dear Arnošt,

 

Some things besides unique id that developers have asked for in the past is the element category and type.

 

The parameter values would also be handy, if they can be conserved.

 

Basically, information that can be used to identify an element, e.g. (i) to know what it is, in order to decide whether to ignore it or not, and (ii) to identify a corresponding data record in an external database.

 

Thank you!

 

Cheers,

 

Jeremy



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

0 Likes
Message 6 of 31

Anonymous
Not applicable

Thanks Arnošt for taking interest in this. The UniqueId alone would be perfect for me, but as Jeremey has said, others have different needs so any and all info that can be provided will make a world of difference.

0 Likes
Message 7 of 31

arnostlobel
Alumni
Alumni
Thank you both.
Ideally, we get more of real-world scenarios. It is sometimes too easy to over-anticipate users' need, which turns developing of such features too costly.

I am afraid we will not be able to allow accessing parameters on deleted elements. Even though some parameters may be safe to get, generally there are not, and most of them would cause problems. Some identification should be possible, however. Maybe categories could be accessed.

Thank you
Arnošt Löbel
0 Likes
Message 8 of 31

Anonymous
Not applicable

I'll add a quick +1 on wanting access to the UniqueId of the element on deletion.  

 

Not having access to it requires my whole application to rely on the ElementId (despite its shortcomings) rather than using the UniqueId of the element.

 

I can also see the value of having access to the category & type, although that not a requirement for me personally.

0 Likes
Message 9 of 31

Anonymous
Not applicable
I would also like to add my +1 vote to accessing the UniqueId upon deletion.
0 Likes
Message 10 of 31

Luis_Salazar
Participant
Participant

Hi Arnost, I need to add my wish. I also need to access to the Element Type of the element being deleted. It would be the big difference if we have that information.

 

In hsbcad we had to do a lot of things to check deleted elements because of not having enough information.

0 Likes
Message 11 of 31

Anonymous
Not applicable
If there is a small number of types you are interested in. Why not create an updater specific to each type? You can then infer the type based on which updater was triggered.
0 Likes
Message 12 of 31

Anonymous
Not applicable

Hi all,

 

Since Arnošt wanted to know what info users need from deleted elements, I thought about pitching in. We add some information to elements in form of extensible storage and would be great if we could get it from deleted elements.

 

Cheers,

Doinas Muresan

0 Likes
Message 13 of 31

jeremytammik
Autodesk
Autodesk

Dear Doinas,

 

Thank you for chipping in.

 

I added your request to the wish list item CF-2162 [API: DocumentChanging or ElementsDeleting event before element is deleted -- 10292440] to make the development team aware of its importance and prompted them for some kind of statement on what the chances are of getting access to this information.

 

Best regard,

 

Jeremy



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

Message 14 of 31

Ryan
Enthusiast
Enthusiast

Another +1 on the uniqueId with deleted elements.

 

I'm doing the same thing as Scott with the api,  on a slightly smaller scale in terms of production. But, I have found keeping track of element relationships outside of Revit to be faster then requesting though Revit. I like the idea of logging with UniqueId's.

 

 

0 Likes
Message 15 of 31

jeremytammik
Autodesk
Autodesk

Dear Ryan,

 

Have you checked whether that API wish has been logged and collected lots of votes on the Revit Idea Station?

 

http://forums.autodesk.com/t5/revit-ideas/idb-p/302/label-name/api/tab/most-recent

 

If not, would you like to add it, and ask all your friends to vote for it?

 

Thank you!

 

Cheers,

 

Jeremy



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

Message 16 of 31

Ryan
Enthusiast
Enthusiast

Thanks Jeremy!

 

Didn't know about his part of the forum. 

 

Just after i posted from not finding anything on my initial search, i came across this Request: Provide more information about deleted element: Ideally a read-only copy.

 

I cant figure out how to delete my post, so i posted this link in the idea as well. Please vote!

 

Thanks!

 

0 Likes
Message 17 of 31

Troy_Gates
Advocate
Advocate

Just thinking out-loud, but could you not intercept the Delete command, create your own code for selecting the items to be deleted, store the elementids and then delete the elements with the API?

 

In essence, create your own Delete command to track the elements being deleted.

 

UIApplication uiapp = new UIApplication(this.Application);
			
RevitCommandId commandId = RevitCommandId.LookupCommandId("ID_BUTTON_DELETE");
			
try
{
	AddInCommandBinding importBinding = uiapp.CreateAddInCommandBinding(commandId);
	importBinding.Executed += new EventHandler<Autodesk.Revit.UI.Events.ExecutedEventArgs>(trackAndDeleteElements);
}
catch
{
}

 

Based on Harry Mattison's code for intercepting the Import CAD command: https://boostyourbim.wordpress.com/2013/01/14/how-to-override-commands-in-the-revit-ui-if-you-really...

Message 18 of 31

jeremytammik
Autodesk
Autodesk

Sounds like a brilliant idea to me... congratulations, Troy!



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

0 Likes
Message 19 of 31

Ryan
Enthusiast
Enthusiast

Thanks Troy,

 

That does sound like a great idea!

 

I would have to catch the undo command as well, since that does send  deleted element id's.

 

Then we get into multi undo's in one instance, which the journal file is telling me is a separate undo command.

 

Also, The redo command and multi redo command would have to be captured as well, since they both could return Deleted elements.

 

I haven't thought much about this yet, but i'm unsure how to approach  undo/redo transactions... 

 

 

  Jrn.Command "Internal" , "Simulate Multi-Undo , ID_SIMULATE_MULTIUNDO"

 

Jrn.Command "Ribbon" , "Undo the last action , ID_BUTTON_UNDO"

0 Likes
Message 20 of 31

Ryan
Enthusiast
Enthusiast

After some trial and error, then finally a search, Jeremy has already pointed out "I can see only two commands cannot have binding: Undo and Redo commands."

 

0 Likes