Have created object be placed with the cursor


#1

I create a model using the following code. The points in vertArr come from a c++ file.
It usually creates the group at the origin. I figured out how to create it somewhere other than the origin. I want to create the object and then have it be placed with the mouse click. The same way when a 3d model is loaded into a model. It loads and then it floats with the cursor until the user clicks where they want it to go. How can I do this with the api?

for counter in 0..array_length


          pts = []

          # Get the next 3 points in vertArr
          p1 = vertArr[i]
          p2 = vertArr[i + 1]
          p3 = vertArr[i + 2]
          
          # increment 'i' for the next 3 points
          i = i + 3

          # push the points into the 'pts' array to use to add the face
          pts.push(p1, p2, p3)

          # add the face to the group with the 'pts' array
          face = group.entities.add_face pts

#2

For user interaction (with the cursor) you need to create a tool. A tool is a class that implements methods to listen when SketchUp reports an input event. You then need to use an InputPoint to get a 3d coordinate that corresponds to the (x,y) cursor position. Take a look at the linetool.rb example.

For the start, better let the user click and then insert the group at that position.

If you want the group to move with the mousemove, you have to wrap it properly in an operation (including abort) so you won’t flood the undo stack with an item on every mousemove.

If your tool becomes more complex, it is best to think of them as finite state automatons, and draw the concept first with arrows on paper so you can be sure you won’t reach any not defined, inconsistent state (variable values that don’t match and cause errors).


#3
Sketchup.active_model.select_tool MouseTool.new
mouse = MouseTool.new

I create a new tool this way .
Then i initialize it

def initialize
	@x_coord = 0
	@y_coord = 0
end

In my tool class, I use onLButtonDown

def onLButtonDown(flags, x, y, view)
	@x_coord = x
        @y_coord = y
end

Then in my method I use

x_point = mouse.instance_variable_get(:@x_coord) 
y_point = mouse.instance_variable_get(:@y_coord)

To get the point. But it just returns the initialized values of 0.
How do I put in a “pause” to wait for the user to click?


#4

The MouseTool instance that mouse holds is not used by SketchUp as tool. It’s a new, second instance!
You wanted to do:

model = Sketchup.active_model # Do this no more than once and at the very beginning where it is decided on which model your plugin acts.
# ...
mouse = MouseTool.new
model.select_tool(mouse)

In Ruby, instance variables are by default private. Although Ruby has inspection methods that allow to hack anything, it’s nicer if you define a public getter method:

attr_reader :x_coord # Automatically creates a getter method for this instance variable.

#5

Thanks. I moved my create geometry method into my tool class and it works.


#6

I’m still confused though with the operation part.

The start_operation method is used to notify Edit > Undo that a new operation (which can be undone) is starting.

How does this help with attaching my group to the move with the mouse?


#7

To be more clear. I can select where I want to place my object, but its not attached to my mouse as it moves.


#8

No. Start_operation tells the undo system that you are starting a sequence of steps that you would like the user to be able to undo. You need a corresponding commit_operation at the end of the sequence. start_operation has nothing whatever to do with capturing mouse movements. For those you need to implement the Tool#onMouseMove method in your Tool class and do whatever you need to track movement in that method.