Pick_helper exclude component

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

Because the component is transformed in real time as the mouse moves.

We don’t really have the whole story.
You mention “the component” and “the opening” and show an image with a door component.

I didn’t see anything being transformed in realtime in the previous post.

It seems weird to do it in a “preview” method.

In my example DragTool I used #move! to prevent undo entries for each transform as the mouse moves.

1 Like

That looks like what I need. I’ll try your sample move tool in the morning.

The opening mentioned is the barn door component that I’m placing.

I just started with this custom tool and modified it. Very quick and dirty test code at this point.

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.

1 Like

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 got it working using your example DragTool, and hiding the component during the pick.

def onMouseMove(flags, x, y, view)
  @inst.hidden = true
  draw_hidden = Sketchup.active_model.rendering_options["DrawHidden"]
  Sketchup.active_model.rendering_options["DrawHidden"] = false if draw_hidden
  @ip = view.inputpoint(x, y)
  @ip.pick(view, x, y)
  point = @ip.position
  @inst.move!(Geom::Transformation.translation(point))
  @inst.hidden = false
  Sketchup.active_model.rendering_options["DrawHidden"] = true if draw_hidden
  view.tooltip = @ip.tooltip if @ip.valid?
  view.invalidate
end

I now have an issue that nothing is updated until I stop moving the mouse.

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.

Any ideas @eneroth3, or @thomthom

def onMouseMove(flags, x, y, view)
  UI.stop_timer(@timer) if @timer
  @timer = UI.start_timer(0.001, false) do
    @inst.hidden = true
    draw_hidden = Sketchup.active_model.rendering_options["DrawHidden"]
    Sketchup.active_model.rendering_options["DrawHidden"] = false if draw_hidden
    @ip = view.inputpoint(x, y)
    point = @ip.position
    @inst.move!(Geom::Transformation.translation(point))
    @inst.hidden = false
    Sketchup.active_model.rendering_options["DrawHidden"] = true if draw_hidden
    view.tooltip = @ip.tooltip if @ip.valid?
  end
  view.invalidate
end

Just my note:
image
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.

So everytime the mouse moves I want to:

  1. Pick a new point where the component will be moved to.
  2. 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.
  3. 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.

:bulb: It just occurred to me that I could move the component out of the way instead of hiding it. Much, much better!

    def onMouseMove(flags, x, y, view)
      @inst.move!(Geom::Transformation.translation(Geom::Point3d.new(0, 0, 100_000)))
      @ip = view.inputpoint(x, y)
      point = @ip.position
      @inst.move!(Geom::Transformation.translation(point))
      view.tooltip = @ip.tooltip if @ip.valid?
      view.invalidate
    end

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.

1 Like

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.

There should be multiple pickpaths. You’re saying there is only 1 ?
If so, I’d log a bug report.

Here’s a feature request for this in the issue tracker.

2 Likes

That is exactly the problem.

Good call. I didn’t remember participating in that issue report.
(There are far too many issues open !)

And @Neil_Burkholder there is a kindred spirit who logged this report (2 years ago) …

1 Like

Thanks everybody for your help. It’s been some very tedious hours. Thankfully it’s looking more hopeful now :slight_smile:

2 Likes

Want to log a feature request for input points to be able to exclude things?