Can the Ruby API monitor the user's actions drawn by the drawing tool?

Can the Ruby API monitor the user’s actions in drawing faces with the drawing tool? Each time the user draws a surface get the coordinate information of that surface.

I found the relevant code, but I don’t know how to control MyEntitiesObserver to run or stop. I would appreciate any advice, thanks!

class MyEntitiesObserver < Sketchup::EntitiesObserver
  def onElementAdded(entities, entity)
    puts "onElementAdded: #{entity}"
    if entity.typename == "Face" 
      p entity.persistent_id
    end
  end
end

# Attach the observer
Sketchup.active_model.entities.add_observer(MyEntitiesObserver.new)

See the example here
Entities #remove_observer-instance_method


By the way:
entity.typename == "Face" comparison is slow, use entity.is_a?(Sketchup::Face) instead.

1 Like

You will likely also need to attach a ToolsObserver to the model’s toolstack watching for the change to the Line tool.

To do that, you need a ModelObserver that also watches for changes to the active edit path, so you can watch the active_entities.

To do that you need an AppObserver that watches the application for when models are created or opened.

AppObserver sees model load or create —> attaches new hybrid ModelObserver —> attaches itself to it’s Tools collection —> which will start watching the active_entities when the Line Tool is in use.


This example uses the extension submodule as the AppObserver object, since there is only one application and only one AppObserver will ever be needed. (Ie, … we do not ever need an instance of a class object for an AppObserver object.)

Here is an example ... (to view - click to expand) ...
# encoding: UTF-8
#
# Example extension module as an observer.

module Example # <<---<<< change to YOUR UNIQUE namespace module
  module SomeExtension # <<---<<< change to desired name

    extend self # ... self refers to the submodule here

    # A hybrid observer that watches the model, the toolstack and when
    # the Line tool is active also the watches the active entities.
    class MyHybridObserver

      # NOTE: Outside instance methods, self refers to the class.
      # Inside instances methods, self refers to the instance when
      # the methods are actually executed.

      # SketchUp's observer queue will hold the reference to this observer.
      def initialize(model)
        @model = model
        @watching = nil
        # Attach itself to the model object:
        @model.add_observer(self)
        # Attach itself to the model's toolstack:
        @model.tools.add_observer(self)
        #
        ### ... attach this observer or other observers,
        ###      to the model's collections here ...
        #
      end

      def onActivePathChanged(model)
        if @watching
          # Only watch the active entities context:
          @watching.remove_observer(self)
          @watching = model.active_entities
          @watching.add_observer(self)
        end
        #
      end

      def onActiveToolChanged(tools, tool_name, tool_id)
        case tool_id
        when 21020 # Sketch (Edge/Line) tool
          @watching = @model.active_entities
          @watching.add_observer(self)
        when 10508, 10509, 10520, 10523, 10525 # Camera tools
          # Don't change @watching, just return:
          return
        else # some other tool
          if @watching
            @watching.remove_observer(self)
            @watching = false
          end
        end
      end

      def onElementAdded(entities, entity)
        if entity.is_a?(Sketchup::Face)
          # Do something with: entity.vertices
        end
      end

    end # observer class


    ### APPOBSERVER CALLBACKS
    #

    def expectsStartupModelNotifications
      true
    end

    def onNewModel(model)
      # Create a model specific spy that attaches itself to the model:
      MyHybridObserver.new(model)
    end

    def onOpenModel(model)
      # Create a model specific spy that attaches itself to the model:
      MyHybridObserver.new(model)
    end

    ### RUN ONCE AT STARTUP
    #
    if !defined?(@loaded)
      #
      ### define GUI objects here ...
      #

      # Attach this submodule as an AppObserver to SketchUp:
      ::Sketchup.add_observer(self)

      # Mark this submodule as loaded:
      @loaded = true
    end

  end # extension submodule
end # namespace module

… or download the whole file … face_watcher.rb (2.7 KB)

Thank you for your guidance and advice

Thanks for providing the relevant commands and ideas