Observer for recognize object moved

Hy, I’am build a sketchup extension for a simulation of better router position. It’s a University project.
I need an observer to recognize when a user moves the object. With this I used if I remove the object the observer answers me but if I move it gives me no results … Help me please!

#this is my Observer    	
class Observer < Sketchup::EntityObserver
    		def onEraseEntity(entity)
            	puts("EntityObserver::onEraseEntity: #{entity.to_s}, is deleted? #{entity.deleted?}")
       	 	end  
       	 	def onChangeEntity(entity)
            	puts("EntityObserver::onChangeEntity: #{entity.to_s} #{entity.entityID}")
        	end		
	end

#this is the code that add Observer
def self.create_Ap(x,y,z,x_min,y_min)
	  model = Sketchup.active_model
	  model.start_operation('Create Ap', true)
	  group = model.active_entities.add_group
	  entities = group.entities
	  points = [
	    Geom::Point3d.new(x+x_min,   y+y_min,   z.m),
	    Geom::Point3d.new((x+(0.15.m)+x_min), y+y_min,   z.m),
	    Geom::Point3d.new((x+(0.15.m)+x_min), (y+(0.1.m)+y_min), z.m),
	    Geom::Point3d.new(x+x_min,(y+(0.1.m))+y_min, z.m)
	  ]
	  face = entities.add_face(points)
	  face.pushpull(-0.02.m)
	  face.material = "Black"
	  face.back_material = "Black"
	  face.set_attribute "testdictionary", "test", 1
	  if $node == nil
	  	$node = Array.new
	  end
	  $node.push(face)
	  face.add_observer(Observer.new)
	  model.commit_operation
	end

Please read this on how to post code.

Please use proper Ruby 2 space indentation.

Also, do not use $ global variables ! (Use module or class variables instead.) See:

1 Like

Thanks. You know how solve my Observer problem?

Now that it is readable I’ll look at it. May take a bit of time. (Still on 1st cup of coffee. :coffee: )

2 Likes

Can you elaborate what the problem is? I ran the observer and didn’t see anything unexpected with it.

Also it’s quite hard to understand your code. Using 2 space indentation would help as we wouldn’t need to scroll sideways (or scroll away vertically from where we are just to get to the horizontal scroll bar). Using paranthesis around arguments makes it much easier to see what words are arguments to what method call. Lastly global variables should be avoided as they may clash with global variables defined by other plugins. You can wrap your code in a module and use a class variable instead.

2 Likes

It works for me. onChangeEntity() fires if you double-click into the group and move one of the BLACK face’s vertices with the MoveTool, or move the entire face with the PushPullTool.

Were you wanting to fire the observer if the user moved the entire group instance ?
If so, you’ll need to attach the observer to the group reference also.

1 Like

I simply attached the observer myself to a selected entity from the console rather than figuring in out what the long method did and make up values for its arguments. I think you found the problem!

1 Like

Yes I had to cleanup the code, module wrap it, add default arguments and add a menuitem:

module Author; end
module Author::SomePluginRenameMe

  extend self

  @@loaded ||= false

  #this is my Observer    	
  class Observer < Sketchup::EntityObserver
    def onEraseEntity(entity)
      puts("EntityObserver::onEraseEntity: #{entity.to_s}"<<
        ", is deleted? #{entity.deleted?}")
    end
    def onChangeEntity(entity)
      puts("EntityObserver::onChangeEntity: "<<
        "#{entity.to_s} #{entity.entityID}")
    end		
  end

  # This is the code that add Observer
  def create_Ap(
    x = 0,
    y = 0,
    z = 0,
    x_min = 1.m,
    y_min = 1.m
  )
    #
    model = Sketchup.active_model
    model.start_operation('Create Ap', true)
      #
      group = model.active_entities.add_group
      entities = group.entities
      points = [
        Geom::Point3d.new( x+x_min, y+y_min, z.m),
        Geom::Point3d.new( (x+(0.15.m)+x_min), y+y_min, z.m),
        Geom::Point3d.new( (x+(0.15.m)+x_min), (y+(0.1.m)+y_min), z.m),
        Geom::Point3d.new( x+x_min, (y+(0.1.m))+y_min, z.m)
      ]
      face = entities.add_face(points)
      face.pushpull(-0.02.m)
      face.material = "Black"
      face.back_material = "Black"
      face.set_attribute( "testdictionary", "test", 1 )
      if @node == nil
        @node = Array.new
      end
      @node.push(face)
      face.add_observer(Observer.new)
      group.add_observer(Observer.new)
      #
    model.commit_operation
    #
  end

  unless @@loaded # RUN ONCE CODE
    UI.menu('Plugins').add_item(
      Module.nesting[0].name.split('::').last
    ) { create_Ap() } # using default arguments
    @@loaded = true
  end

end
1 Like

However, @d.trepiccione93, I would not create a new observer instance for every model object.
Instead I’d create only one per model, and reuse it for all the model’s object (if possible.)
But, I never use model level observers for more than one model. (That can “cross wires” and lead to problems and confuse the code.)

1 Like

Thank you so much. I will modify the code taking into account all the advice you gave me.
Since we find ourselves, since these solids that I add to the model represent routers, if I wanted to import premade models instead of creating those ugly solids?

This question makes no sense in English.

Please begin a new topic (and explain better) …


… or perhaps look in the Extensions category.

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.