Even with a translucent material the component is still selectable. Completely hiding the component during the operation works but of course is pointless because you can’t see anything.
#DISCLAIMER: Includes a bunch of ugly test code.
def draw(view)
draw_preview(view)
@mouse_ip.draw(view) if @mouse_ip.display?
end
def draw_preview(view)
points = picked_points
#puts points.count
if points.size == 1 # && @mouse_ip.valid?
face = @mouse_ip.face
if face
box_points = face.vertices.map { |v| v.position }
else
center = points[0]
box_points =
[
center + [0, 10, -10],
center + [0, 10, 10],
center + [0, -10, 10],
center + [0, -10, -10]
]
end
view.drawing_color = Sketchup::Color.new(0, 0, 255, 50)
view.draw(GL_POLYGON, box_points)
if @mouse_ip && @last_position != @mouse_ip.position
tr = @face ? Geom::Transformation.new(@mouse_ip.position, @face.normal) : Geom::Transformation.new(@mouse_ip.position)
@inst.transformation = tr if @inst
@last_position = @mouse_ip.position
end
end
return unless points.size == 2
view.set_color_from_line(*points)
view.line_width = 1
view.line_stipple = ''
view.draw(GL_LINES, points)
end
Ah, well, that confused me because SketchUp also has opening objects.
(These are the virtual openings cut by cutting components.)
They are exposed to the C API, but not yet the Ruby API.
Your example suffers from the same debilitating ailment. The reason the component ‘zooms in’ is because the end of the component is picked, and the component is repositioned at that point. The pick helper is selecting a point on the component rather than the face underneath it. In contrast the native insert component, and move tool, both somehow ignore the component being moved. It’s like it’s invisible to the pick helper.
OK I finally got it working. I had to use a timer or the component wouldn’t be drawn until the mouse stopped moving. This was due to hiding the component so the input point wouldn’t pick a point on the component. This is the best solution I can come up with at this point. It’s still not as smooth as moving without hiding the component, because of all the extra work, and it seems like a bit of a hack. I’d welcome another solution (other than hiding) to exclude a particular component from the pick.
Just my note:
The onMouseMove called every time when the mouse changing its position pixel by pixel (when x, y is different than the previous)
So this piece of code happening within milliseconds reading from top to bottom repeatedly and “telling” to the sytem to hide-un-hide-hide-un-hide… all the time.
Until you are not mowing the mouse then the last “command” is un-hide.
I don’t see much point using like this.
Pick a new point where the component will be moved to.
The new point should not be on the component being moved.
a. Because the component can be between the mouse and the object under it the component needs to be hidden, otherwise the object below the component can’t be picked, and the input point will be on top of the component.
After the input point is chosen, the component needs to be moved to the new location, and shown.
a. Important! The goal is move, and show the component at it’s new position after every mouse move, just like the insert component tool when selecting a component from the component browser.
I understand that hiding and unhiding on every mouse move is not optimal, that is why I’m trying to find another way to exclude the component from the pick, and allow the object under it to be picked.
See here for why that is a problem. The video shows both the insert component and the custom tool.
Well my advice for this issue, would be (since you have a reference to the instance,) … would be to remove this instance from the pick paths under consideration.
The PickHelper#path_at docs have an erroneous example of iterating the picklist. Ie, the highest index is pickhelper.count-1, so a better example is…
ph = view.pick_helper
ph.do_pick(x, y)
# Iterate all pick-routes:
for pick_path_index in 0..ph.count-1
puts ph.path_at(pick_path_index)
end
* Note that we could also use 0...ph.count and the last value would not be included in the Range object.
Okay? So let us say that your moving instance is referenced as inst …
pickpaths = {}
ph = view.pick_helper
ph.do_pick(x, y)
# Iterate all pick-routes:
for index in 0..ph.count-1
pickpath = ph.path_at(index)
pickpaths[index]= pickpath unless pickpath.include?(inst)
end
if !pickpaths.empty?
# iterate looking for a face
path = pickpaths.find {|index,path| path.last.is_a?(Sketchup::Face) }
if path # nil if not found
index = pickpaths.key(path)
end
end
So if successful, index is now the index into the PickHelper object’s picklist
and path is the actually path array whose leaf is the found face.
Yes you could just use 1 iterator loop to find the first path whose leaf is a face,
and doesn’t includes the instance.
Also FYI, PickHelper#test_point is touted as the fastest way to test points under the cursor.
The problem is that the face under the instance is not in the pick path because the instance is covering it up. Moving the instance out of the way before doing the pick is working though.