Accessing a removed entity


I want to get a reference to removed entities in the Sketchup::EntitiesObserver

I need the persistent ID and layer name for the deleted entity to be precise (not necessarily a reference as there might be no such thing). I will then remove those from various maps that I am keeping on the C++ side…

currenly I have the following in the Sketchup::EntitiesObserver:

  def onElementRemoved(entities, entity_id)
    puts "onElementRemoved start"
    model = Sketchup.active_model
    puts "active model acquired: #{model}"
    entity = model.find_entity_by_id(entity_id) 
    puts "entities acquired: #{entity}"
    if entity.is_a?(Sketchup::Face) || entity.is_a?(Sketchup::Group)
      puts "entity is either a face or a group"
      MyExt.onElementRemoved(entities, entity.persistent_id,
    puts "onElementRemoved end"
  • I execute these operations with the outputs:
  1. select and move a face:

face entity ref: #Sketchup::Face:0x000002829041e550

  1. select and move same face again: (same pointer)

face entity ref: #Sketchup::Face:0x000002829041e550

  1. delete the face: (no pointer)

onElementRemoved start
active model acquired: #Sketchup::Model:0x0000028286a713a8
entities acquired:
onElementRemoved end

  1. undo delete:

onTransactionUndo: #Sketchup::Model:0x0000028286a713a8

  1. select and move the face: (new pointer)

face entity ref: #Sketchup::Face:0x00000282900d8918

My assumption is that the face entity pointer is dereferenced on delete and a new pointer is created after undo. Is there an undo log (or any other mechanism) to get the persistent ID and layer name for the deleted entity so I can remove those from other necessary places in my extension if the user deletes an entity?

Thanks in advance :slight_smile:

There is a ModelObserver#onPidChanged() callback that might help.

The reference passed into erase callbacks points at a special class called “DeletedEntity” and you cannot call property methods like #layer or #persistent_id on theses references (as the actual object has already been deleted.)

The only workaround is to cache the property information ahead of time (such as when an entity is created or at some interesting milestone.)

Generally, with the Ruby API, the original authors and even maintainers that came later just do not (or did not) understand the value in observers that give impending notification to events that are about to happen.

We (the coders) had arguments with them like 12 years ago on this subject. I remember clearly an obstinate response like … “Events are handled after the fact and this is why the callbacks all begin with an ‘on…’ prefix. You cannot have an event before it happens”.

This “discussion” and requests for various “onBefore…” or “pre…” observer callbacks predated the public API Issue tracker. We did get a few pre-event callbacks dealing with model and component saving in the abstract ModelObserver class. (This was in the v8 days.)

We are still waiting for better pre-event callbacks for EntityObserver and / or the EntitiesObserver collection observer.

Nothing much was happening with this request, so one of the developers recently filed an request issue in the public issue tracker as a reminder. (I say recent, but it will be 2 years in December since he filed this issue.)

I would suggest you look through the other open issues regarding SketchUp observers …

Are you using the Ruby object itself as a key in your maps? When entities are going through the undo/redo system the Ruby wrapper ends up being recreated. However, the entityID should remain the same. So can you use the entityID as a key in your system?

We see the value, but the problem is of a technical nature. Allowing extensions to trigger in the midst of operations cause all sorts of problems with object life-time. It’s been a major source of crashes and instability. If there was a way to enforce read-only access that could be an option for “pre” events, but that’s not a trivial thing either.

1 Like


I am using the persistent IDs as keys, the prints were more so to confirm that I have no longer access to the object.

I think I can add a new map with this and the values could be a tuple of layer name and pid, (and when the entity id is removed this could trigger a series of functions) but,

it would require me to cache everything at the beginning of each session. Thanks for the suggestion, this is now what I will do…

yes, this would have been great :slight_smile:

Can you elaborate on how this info is used in your extension? You are using it in the UI?

We use it to remove the entities/geometries from the last exported file without the need to export the entire model again :slight_smile:

Remove from where?

this would be a file the user had already exported from sketchup. and if they make changes to the original model (ofc if the toggle is ON) we override the exported geometry.