How to put mouse click points into a array?

I have try to study the official example code and put “n” points into a array.
unfortunately,it can’t work.this is the code

  def activate
    @mouse_ip = Sketchup::InputPoint.new
    @picked_first_ip = Sketchup::InputPoint.new
    update_ui
  end
  def draw(view) 
    @mouse_ip.draw(view) if @mouse_ip.display?
    update_ui
  end  
  def onMouseMove(flags, x, y, view)
    picked_first_ip = Sketchup::InputPoint.new
    @mouse_ip = Sketchup::InputPoint.new
    @mouse_ip.pick(view, x, y) 
    view.tooltip = @mouse_ip.tooltip if @mouse_ip.valid? 
    view.invalidate 
    update_ui
    if picked_first_point?
      @mouse_ip.pick(view, x, y, @picked_first_ip)          
    else
      @mouse_ip.pick(view, x, y)
    end
      view.tooltip = @mouse_ip.tooltip if @mouse_ip.valid?
      view.invalidate
  end
      
  def onLButtonDown(flags, x, y, view)
    @mouse_down = Geom::Point3d.new(x, y)
    @pick_first_ip = mouse_down
    if picked_first_point? 
      reset_tool
    else
      @picked_first_ip.copy!(@mouse_ip)
    end
  end      
  def reset_tool
    @picked_first_ip.clear
    update_ui
  end
      
  def update_ui
    if picked_first_point?
      Sketchup.status_text = 'select the first point'
    else
      Sketchup.status_text = 'select the second point'
    end
  end
  
  def picked_points
    points = []
    points << @picked_first_ip.position if picked_first_point?
    points << @mouse_ip.position if @mouse_ip.valid?
    ip1   = points[0]
    ip2   = points[1]        
    if points.size == 2 #there “2” maybe 3 or 7……N
      UI.messagebox(ip1)
      UI.messagebox(ip2)
    else
      
    end
  end

Maybe I have got wrong understand the method of pick.
someone can help me thanks!

Let me send you a sample that can help you so much.

require 'sketchup.rb'
module MajidMahmoudi
  module ClickFinder
    class Click
      def init()
        @input = Sketchup::InputPoint.new
        @input_help = Sketchup::InputPoint.new
        @pt = []
        @mp = @input.position.to_a
        @st = 0
      end

      def activate
        init()
      end # activate

      def deactivate(view)
        @st = 0
        @pt = []
        view.invalidate
      end

      def suspend(view)
        view.invalidate
      end

      def resume(view)
        view.invalidate
      end

      def onMouseMove(flags, x, y, view)
        if @st != 0
          if @input_help.valid?
            @input.pick(view, x, y, @input_help)
          else
            @input.pick(view, x, y)
          end
          @mp = @input.position.to_a
          Sketchup.status_text= "Select First Rail Pole Position"
          @input.pick(view, x, y)
        end
        view.invalidate
      end

      def draw (view)
        @input.draw view
        if @input.valid? && @st > 0
          view.set_color_from_line @pt[@st - 1], @mp
          view.line_width = 3
          view.draw_polyline @pt[@st - 1], @mp
          view.drawing_color= "yellow"
          for i in 1...@st
            view.drawing_color= "green"
            view.draw_polyline @pt[i - 1], @pt[i]
          end
        end
      end

      def onLButtonDown(flags, x, y, view)
        if @pt[@st] != @mp
          if @input_help.valid?
            @input.pick(view, x, y, @input_help)
          else
            @input.pick(view, x, y)
          end
          @input_help.copy!(@input)
          @pt[@st] = @input.position.to_a
          @mp = @input.position.to_a
          @st += 1
          view.invalidate
        end
      end
    end # class Click

    unless file_loaded?(__FILE__)
      UI.menu("Plugins").add_item("Click") {
      Sketchup.active_model.select_tool(Click.new)
      }
      file_loaded(__FILE__)
     end
  end
end

All clicked points are in @pt. The last point is in @mp.

Can you post a complete snippet please? You are missing the class definition at the top.

And I don’t see any place where you are calling picked_points.

Can you elaborate on what isn’t working for you. (What are you doing, what are you expecting and what are you observing?)

You code has several errors…
Firstly it should be inside a class so a Tool gets made…
Next you have a mix of @xxx and xxx variables - these are not the same…
So when you

picked_first_ip = ...

Is not the same reference as

@picked_first_ip

or

picked_first_point?

You are making your code more convoluted and hard to debug…
Later

@pick_first_ip = mouse_down

is used but mouse_down is undefined ? BUT @mouse_down is set up !
A @xxx variable is shared across methods but your

if picked_first_point? 

is limited to its own method so is always nil !
Try using @picked_first_point
There is not final ? in the variable’s name…

The method picked_points() is never called in your code.

I’m afraid you code is perhaps beyond redemption, without a major rewrite…
This is NOT a major audit - just some issues that jumped out…

1 Like

It’s a hobbyhorse of mine, but I don’t think the difference between local variables, global variables, method arguments, and @ variables is properly taught most places.

Globals should be the exclusive province of the language and core functions, never created by any user script. There is no way to protect against collisions between use of the same named global across unrelated contexts. Such clashes cause errors that are extremely hard to debug.

@variables are widely misused, IMO. They are meant to preserve an object’s memory of its “state”. That is, what it needs to remember so as to respond correctly to subsequent function calls. They are essential to handle callbacks from the GUI, since Ruby gives up control between such calls; other sorts of memory of what callbacks came before is lost unless retained in @ variables. They aren’t meant as a way to pass data “around the side” when one function calls another on the same object! When code is written so that values are passed via @ instead of explicit parameters it becomes impossible for any other object to safely call that function. Said another way, the object has a contract with itself (that required data is in an @) but gives no such promise to anything else. But even in a single object, the practice makes it hard to be sure what the function relies on without studying the entire code body. Oh, this function uses @foo I wonder when and why it was last assigned?

Misuse of @ is especially common in code that is actually function-oriented not object-oriented. Code snippets posted here on the forum often use @ variables for everything, even going so far as to pass them as parameters to a function on the same object or to use them as temporaries not needed outside or after the current function (for which local, non-@ is the right kind).

Architectural not “Artitectural”

1 Like