# PickHelper.window\_pick bug inside a group/component

**URL:** <https://forums.sketchup.com/t/pickhelper-window-pick-bug-inside-a-group-component/121327>\
**Category:** Ruby API\
**Created:** [April 8, 2020, 3:14pm UTC](https://forums.sketchup.com/t/pickhelper-window-pick-bug-inside-a-group-component/121327 "2020-04-08T15:14:22Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![voquochai](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/voquochai/32/63877_2.png) [@voquochai](https://forums.sketchup.com/u/voquochai)\
**Post date:** [April 8, 2020, 3:14pm UTC](https://forums.sketchup.com/t/pickhelper-window-pick-bug-inside-a-group-component/121327/1 "2020-04-08T15:14:22Z")

</div>

Hi, I am trying to write a selection tool and when using the window\_pick method, there was a problem.  
The [PickHelper.window\_pick](https://ruby.sketchup.com/Sketchup/PickHelper.html#window_pick-instance_method) method works well outside the model but when I use it inside an object it works wrong. I’m using it the wrong way?  
Check out the code below in the onLButtonUp method.  
Thanks

```ruby
class SelectTool
  def initialize(*_args)
    @model = Sketchup.active_model
    @selection = Sketchup.active_model.selection
    @ip_mouse = Sketchup::InputPoint.new
  end

  def activate
    reset
  end

  def deactivate(view)
    view.invalidate
  end

  def reset; end

  def onCancel(reason, _view)
    if reason == 0
      @model.close_active if @model.active_path
    end
  end

  def onMouseMove(_flags, x, y, view)
    @mouse = [x, y]
    onSetCursor
    set_statusbar
    view.invalidate
  end

  def onLButtonDown(_flags, x, y, _view)
    @click_times = 1
    @drag = true
    @mouse_down = [x, y]
  end

  def dragging?
    @drag && @mouse_down && @mouse.distance(@mouse_down) > 10
  end

  def onLButtonUp(_flags, x, y, view)
    ph = view.pick_helper
    ph.do_pick(x, y)
    @best_entity = ph.best_picked

    if dragging?
      pick_type = if @mouse.x > @mouse_down.x
                    Sketchup::PickHelper::PICK_INSIDE
                  else
                    Sketchup::PickHelper::PICK_CROSSING
                  end

      num_picked = ph.window_pick(@mouse_down, @mouse, pick_type)
      if num_picked > 0
        @selection.clear
        @selection.add(ph.all_picked)
      end
    else
      @selection.clear
      @selection.add(@best_entity) if @best_entity
    end

    @drag = false
    @mouse_down = nil

    view.invalidate
  end

  def onLButtonDoubleClick(_flags, x, y, view)
    @click_times += 1
    p "onLButtonDoubleClick: @click_times = #{@click_times}"

    ph = view.pick_helper
    ph.do_pick(x, y)
    @best_entity = ph.best_picked

    if object?(@best_entity)
      active_path = @model.active_path || []
      unless @best_entity.locked?
        @model.active_path = active_path + [@best_entity]
      end
    elsif @best_entity
      if geometry?(@best_entity)
        # select connected
        if @best_entity.is_a?(Sketchup::Edge)
          @selection.add(@best_entity.faces)
        else
          # Face
          @selection.add(@best_entity.edges)
        end

        @selection.add(@best_entity.all_connected) if @click_times > 2
      else
        # API cant edit Dimension and Text
        # Sketchup.send_action('selectSelectionTool:')
      end
    elsif @model.active_path
      @model.close_active 
    end
  end

  def object?(entity)
    return unless entity

    entity.is_a?(Sketchup::Group) ||
      entity.is_a?(Sketchup::ComponentInstance)
  end 
  
  def geometry?(entity)
    return unless entity

    entity.is_a?(Sketchup::Edge) ||
      entity.is_a?(Sketchup::Face)
  end

  def onSetCursor
    # UI.set_cursor(@cursor)
  end

  def set_statusbar
    status_text = 'Select objects. Shift to extend select. Drag mouse to select multiple.'
    Sketchup.set_status_text(status_text)
  end

  def draw(view)
    if dragging?
      rect = [
        @mouse_down,
        [@mouse_down.x, @mouse.y],
        @mouse,
        [@mouse.x, @mouse_down.y]
      ]

      inside = @mouse.x > @mouse_down.x

      view.line_width = 1
      view.line_stipple = inside ? '' : '_'
      view.drawing_color = 'black'
      view.draw2d(GL_LINE_LOOP, rect)
    end
  end
end

Sketchup.active_model.select_tool(SelectTool.new)

```

---

<div class="post-metadata">

**Author:** ![DanRathbun](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/danrathbun/32/500_2.png) [@DanRathbun](https://forums.sketchup.com/u/DanRathbun)\
**Post date:** [April 8, 2020, 11:11pm UTC](https://forums.sketchup.com/t/pickhelper-window-pick-bug-inside-a-group-component/121327/2 "2020-04-08T23:11:34Z")

</div>

Yes I see it acts weird. Does ThomThom’s PickHelper Guide help ?

> **[PickHelper — A Visual Guide](http://www.thomthom.net/thoughts/2013/01/pickhelper-a-visual-guide/)**
>
> I’ve put together a visual guide to the PickHelper class in SketchUp’s Ruby API. When I first tried to use the PickHelper class I was confused over what the different methods did, and f…

---

<div class="post-metadata">

**Author:** ![voquochai](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/voquochai/32/63877_2.png) [@voquochai](https://forums.sketchup.com/u/voquochai)\
**Post date:** [April 9, 2020, 1:01am UTC](https://forums.sketchup.com/t/pickhelper-window-pick-bug-inside-a-group-component/121327/3 "2020-04-09T01:01:57Z")

</div>

The window\_pick method has been added since 2016’s SketchUp, Thom Thom’s document has not added this method yet.  
The boundingbox\_pick method has the same problem.

---

<div class="post-metadata">

**Author:** ![DanRathbun](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/danrathbun/32/500_2.png) [@DanRathbun](https://forums.sketchup.com/u/DanRathbun)\
**Post date:** [April 9, 2020, 10:55am UTC](https://forums.sketchup.com/t/pickhelper-window-pick-bug-inside-a-group-component/121327/4 "2020-04-09T10:55:38Z")

</div>

Okay I got it picking from the active entities …

… but it can’t tell the difference from a crossing and an inside pick.

> **EDIT** : Actually that was **my** error. I had messed with the **`if`** statement just after the **`if dragging?`** statement and I’ve since fixed that.
> 
> **BUT** : The problems now seem to be that the window pick will **ONLY** return **one** pick path for any primitive entities even though more than 1 are window selected and **OFTEN only** during a crossing select. (Ie, occasionally an inside window select will also grab a random primitive edge or face.) It doesn’t matter how many groups or component instances are also selected (along with the primitives,) the window pick only returns a single pick path for one of the primitives (seemly chosen at random) in the selection along with the pick paths for groups and/or component instances.

Also … we don’t need to do `ph.do_pick(x,y)` with a window pick pattern so I moved that down into the `else` (not dragging) clause.

```ruby
class SelectTool
  def initialize(*_args)
    @model = Sketchup.active_model
    @selection = Sketchup.active_model.selection
    @ip_mouse = Sketchup::InputPoint.new
  end

  def activate
    reset
  end

  def deactivate(view)
    view.invalidate
  end

  def reset
    @drag = false
  end

  def onCancel(reason, _view)
    if reason == 0
      if @model.active_path
        @model.close_active
      else
        reset()
      end
    end
  end

  def onMouseMove(_flags, x, y, view)
    @mouse = [x, y]
    onSetCursor
    set_statusbar
    view.invalidate
  end

  def onLButtonDown(_flags, x, y, _view)
    @click_times = 1
    @drag = true
    @mouse_down = [x, y, 0]
  end

  def dragging?
    @drag && @mouse_down && @mouse.distance(@mouse_down) > 10
  end

  def onLButtonUp(_flags, x, y, view)
    ph = view.pick_helper

    if dragging?
      if x > @mouse_down.x
        pick_type = Sketchup::PickHelper::PICK_INSIDE
      else
        pick_type = Sketchup::PickHelper::PICK_CROSSING
      end

      #num_picked = ph.window_pick(@mouse_down, @mouse, pick_type)
      num_picked = ph.window_pick(@mouse_down, [x,y,0], pick_type)
      if num_picked > 0
        puts "Number picked: #{num_picked}"
        picked = []
        context = @model.active_entities
        ph.count.times { |pick_path_index|
          path = ph.path_at(pick_path_index)
          found = path.find { |ent| context == ent.parent.entities }
          picked << found if found
        }
        picked.uniq!
        puts "Picked: "<<picked.inspect
        @selection.clear
        @selection.add(picked)
      else
        UI.beep
      end

      @drag = false

    else
      # Moved these 2 statements inside the else:
      ph.do_pick(x, y)
      @best_entity = ph.best_picked
      #
      @selection.clear
      @selection.add(@best_entity) if @best_entity
    end

    @mouse_down = nil

    view.invalidate
  end

  def onLButtonDoubleClick(_flags, x, y, view)
    @click_times += 1
    p "onLButtonDoubleClick: @click_times = #{@click_times}"

    ph = view.pick_helper
    ph.do_pick(x, y)
    @best_entity = ph.best_picked

    if object?(@best_entity)
      active_path = @model.active_path || []
      unless @best_entity.locked?
        @model.active_path = active_path + [@best_entity]
      end
    elsif @best_entity
      if geometry?(@best_entity)
        # select connected
        if @best_entity.is_a?(Sketchup::Edge)
          @selection.add(@best_entity.faces)
        else
          # Face
          @selection.add(@best_entity.edges)
        end

        @selection.add(@best_entity.all_connected) if @click_times > 2
      else
        # API cant edit Dimension and Text
        # Sketchup.send_action('selectSelectionTool:')
      end
    elsif @model.active_path
      @model.close_active 
    end
  end

  def object?(entity)
    return unless entity

    entity.is_a?(Sketchup::Group) ||
      entity.is_a?(Sketchup::ComponentInstance)
  end 
  
  def geometry?(entity)
    return unless entity

    entity.is_a?(Sketchup::Edge) ||
      entity.is_a?(Sketchup::Face)
  end

  def onSetCursor
    # UI.set_cursor(@cursor)
  end

  def set_statusbar
    status_text = 'Select objects. Shift to extend select. Drag mouse to select multiple.'
    Sketchup.set_status_text(status_text)
  end

  def draw(view)
    if dragging?
      rect = [
        @mouse_down,
        [@mouse_down.x, @mouse.y],
        @mouse,
        [@mouse.x, @mouse_down.y]
      ]

      inside = @mouse.x > @mouse_down.x

      view.line_width = 1
      view.line_stipple = inside ? '' : '_'
      view.drawing_color = 'black'
      view.draw2d(GL_LINE_LOOP, rect)
    end
  end
end

```

---

<div class="post-metadata">

**Author:** ![DanRathbun](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/danrathbun/32/500_2.png) [@DanRathbun](https://forums.sketchup.com/u/DanRathbun)\
**Post date:** [April 12, 2020, 8:46am UTC](https://forums.sketchup.com/t/pickhelper-window-pick-bug-inside-a-group-component/121327/5 "2020-04-12T08:46:38Z")

</div>

> <https://github.com/SketchUp/api-issue-tracker/issues/459>
>
> \### SketchUp Ruby API Issue
> 
> \*\*\[\`Sketchup::PickHelper\`\](https://ruby.sketchup.…com/Sketchup/PickHelper.html) \[\`window\_pick\`\](https://ruby.sketchup.com/Sketchup/PickHelper.html#window\_pick-instance\_method) and \[\`boundingbox\_pick\`\](https://ruby.sketchup.com/Sketchup/PickHelper.html#boundingbox\_pick-instance\_method) are not correct in nested contexts\*\*.
> 
> \[Window \](https://ruby.sketchup.com/Sketchup/PickHelper.html#window\_pick-instance\_method)and \[BoundingBox \](https://ruby.sketchup.com/Sketchup/PickHelper.html#boundingbox\_pick-instance\_method)picks work correctly at the top level of the model, but not when within an editing context.
> 
> When in a nested context, the \[\`#all\_picked()\`\](https://ruby.sketchup.com/Sketchup/PickHelper.html#all\_picked-instance\_method) method's return array does \*\*not\*\* contain entities from the \*\*active entities\*\*, as the documentation seems to indicate (yet also is a bit confusing.)
> 
> When in a nested context, the \[\`#element\_at()\`\](https://ruby.sketchup.com/Sketchup/PickHelper.html#element\_at-instance\_method) method does \*\*not\*\* return an entity within the \*\*active entities\*\*, as the documentation states.
> 
> Because of this, a tool needs to iterate the pick paths and then iterate each path comparing the entity's parent's entities against the active entities to get the correct picked items from the active context. Ie ...
> \`\`\`ruby
> picked = \[\]
> context = @model.active\_entities
> ph.count.times { |pick\_path\_index|
> path = ph.path\_at(pick\_path\_index)
> found = path.find { |ent| context == ent.parent.entities }
> picked \<\< found if found
> }
> \`\`\`
> (\_Full test tool posted below.\_)
> 
> Also ... the main problem seems to be that the window pick will ONLY return one pick path for any primitive entities even though more than 1 are window selected and OFTEN only during a crossing select. (Ie, occasionally an inside window select will also grab a random primitive edge or face.) It doesn’t matter how many groups or component instances are also selected (along with the primitives,) the window pick only returns a single pick path for one of the primitives (seemly chosen at random) in the selection along with the pick paths for groups and/or component instances.
> 
> \----
> 
> \_REF FORUM TOPIC:\_ https://forums.sketchup.com/t/pickhelper-window-pick-bug-inside-a-group-component/121327
> 
> \----
> 
> Test tool from the referenced forum topic. Test by window selecting a combination of groups, instances and \*\*multiple\*\* primitives at the top level of the model, and then in nested contexts.
> 
> \`\`\`ruby
> class SelectTool
> def initialize(\*\_args)
> @model = Sketchup.active\_model
> @selection = Sketchup.active\_model.selection
> @ip\_mouse = Sketchup::InputPoint.new
> end
> 
> def activate
> reset
> end
> 
> def deactivate(view)
> view.invalidate
> end
> 
> def reset
> @drag = false
> end
> 
> def onCancel(reason, \_view)
> if reason == 0
> if @model.active\_path
> @model.close\_active
> else
> reset()
> end
> end
> end
> 
> def onMouseMove(\_flags, x, y, view)
> @mouse = \[x, y\]
> onSetCursor
> set\_statusbar
> view.invalidate
> end
> 
> def onLButtonDown(\_flags, x, y, \_view)
> @click\_times = 1
> @drag = true
> @mouse\_down = \[x, y, 0\]
> end
> 
> def dragging?
> @drag && @mouse\_down && @mouse.distance(@mouse\_down) \> 10
> end
> 
> def onLButtonUp(\_flags, x, y, view)
> ph = view.pick\_helper
> 
> if dragging?
> if x \> @mouse\_down.x
> pick\_type = Sketchup::PickHelper::PICK\_INSIDE
> else
> pick\_type = Sketchup::PickHelper::PICK\_CROSSING
> end
> 
> #num\_picked = ph.window\_pick(@mouse\_down, @mouse, pick\_type)
> num\_picked = ph.window\_pick(@mouse\_down, \[x,y,0\], pick\_type)
> if num\_picked \> 0
> puts "Number picked: #{num\_picked}"
> picked = \[\]
> context = @model.active\_entities
> ph.count.times { |pick\_path\_index|
> path = ph.path\_at(pick\_path\_index)
> found = path.find { |ent| context == ent.parent.entities }
> picked \<\< found if found
> }
> picked.uniq!
> puts "Picked: "\<\<picked.inspect
> @selection.clear
> @selection.add(picked)
> else
> UI.beep
> end
> 
> @drag = false
> 
> else
> # Moved these 2 statements inside the else:
> ph.do\_pick(x, y)
> @best\_entity = ph.best\_picked
> #
> @selection.clear
> @selection.add(@best\_entity) if @best\_entity
> end
> 
> @mouse\_down = nil
> 
> view.invalidate
> end
> 
> def onLButtonDoubleClick(\_flags, x, y, view)
> @click\_times += 1
> p "onLButtonDoubleClick: @click\_times = #{@click\_times}"
> 
> ph = view.pick\_helper
> ph.do\_pick(x, y)
> @best\_entity = ph.best\_picked
> 
> if object?(@best\_entity)
> active\_path = @model.active\_path || \[\]
> unless @best\_entity.locked?
> @model.active\_path = active\_path + \[@best\_entity\]
> end
> elsif @best\_entity
> if geometry?(@best\_entity)
> # select connected
> if @best\_entity.is\_a?(Sketchup::Edge)
> @selection.add(@best\_entity.faces)
> else
> # Face
> @selection.add(@best\_entity.edges)
> end
> 
> @selection.add(@best\_entity.all\_connected) if @click\_times \> 2
> else
> # API cant edit Dimension and Text
> # Sketchup.send\_action('selectSelectionTool:')
> end
> elsif @model.active\_path
> @model.close\_active 
> end
> end
> 
> def object?(entity)
> return unless entity
> 
> entity.is\_a?(Sketchup::Group) ||
> entity.is\_a?(Sketchup::ComponentInstance)
> end 
>   
> def geometry?(entity)
> return unless entity
> 
> entity.is\_a?(Sketchup::Edge) ||
> entity.is\_a?(Sketchup::Face)
> end
> 
> def onSetCursor
> # UI.set\_cursor(@cursor)
> end
> 
> def set\_statusbar
> status\_text = 'Select objects. Shift to extend select. Drag mouse to select multiple.'
> Sketchup.set\_status\_text(status\_text)
> end
> 
> def draw(view)
> if dragging?
> rect = \[
> @mouse\_down,
> \[@mouse\_down.x, @mouse.y\],
> @mouse,
> \[@mouse.x, @mouse\_down.y\]
> \]
> 
> inside = @mouse.x \> @mouse\_down.x
> 
> view.line\_width = 1
> view.line\_stipple = inside ? '' : '\_'
> view.drawing\_color = 'black'
> view.draw2d(GL\_LINE\_LOOP, rect)
> end
> end
> end
> \`\`\`
> 
> :?:

---

<div class="post-metadata">

**Author:** ![bobecka](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/bobecka/32/189469_2.png) [@bobecka](https://forums.sketchup.com/u/bobecka)\
**Post date:** [July 10, 2025, 9:02pm UTC](https://forums.sketchup.com/t/pickhelper-window-pick-bug-inside-a-group-component/121327/6 "2025-07-10T21:02:39Z")

</div>

5 years have passed and nothing has changed. No one has a way to select elements from active\_entities using a rectangle???

---

<div class="post-metadata">

**Author:** ![DanRathbun](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/danrathbun/32/500_2.png) [@DanRathbun](https://forums.sketchup.com/u/DanRathbun)\
**Post date:** [July 10, 2025, 9:07pm UTC](https://forums.sketchup.com/t/pickhelper-window-pick-bug-inside-a-group-component/121327/7 "2025-07-10T21:07:53Z")

</div>

True. @CraigTrickett this is an example of the API team not correcting existing bugs, in favor of supporting new features. (Likely because marketing thinks new features will drive more sales.)

---

<div class="post-metadata">

**Author:** ![CraigTrickett](https://avatars.discourse-cdn.com/v4/letter/c/c77e96/32.png) [@CraigTrickett](https://forums.sketchup.com/u/CraigTrickett)\
**Post date:** [July 14, 2025, 1:21pm UTC](https://forums.sketchup.com/t/pickhelper-window-pick-bug-inside-a-group-component/121327/8 "2025-07-14T13:21:37Z")

</div>

Hi @DanRathbun, thank you for bringing this to my attention.  
I can certainly ask the team about this particular issue and try to come back to you.

In regards to bugs vs new features, I would highlight that a number of bugs have actually been fixed as well as new features added. Sadly, its usually easier for people to see which bug’s haven’t been fixed but that will always be the case. 5 years is a long time for any bug to go unfixed and I’m not trying to make excuses for that.

Let me see what I can find out.

Kind regards,

Craig

---

<div class="post-metadata">

**Author:** ![DanRathbun](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/danrathbun/32/500_2.png) [@DanRathbun](https://forums.sketchup.com/u/DanRathbun)\
**Post date:** [July 14, 2025, 4:53pm UTC](https://forums.sketchup.com/t/pickhelper-window-pick-bug-inside-a-group-component/121327/9 "2025-07-14T16:53:10Z")

</div>

> [@CraigTrickett](#):
>
> In regards to bugs vs new features, I would highlight that a number of bugs have actually been fixed as well as new features added.

Sometimes we cannot help but voice our frustrations. It is not lost on us how much emphasis goes into new features. That said, this was once a new API feature, that apparently was not 100% finished.

> [@CraigTrickett](#):
>
> 5 years is a long time for any bug to go unfixed and I’m not trying to make excuses for that.

There are “bug” issues older, up to 8 years old:

- [Issues (labeled “bug”) · SketchUp/api-issue-tracker](https://github.com/SketchUp/api-issue-tracker/issues?q=is%3Aopen%20is%3Aissue%20label%3ASketchUp%20sort%3Acreated-asc%20label%3A%22Ruby%20API%22%20label%3Abug)

---

<div class="post-metadata">

**Author:** ![JackyM](https://avatars.discourse-cdn.com/v4/letter/j/d07c76/32.png) [@JackyM](https://forums.sketchup.com/u/JackyM)\
**Post date:** [August 29, 2025, 3:57pm UTC](https://forums.sketchup.com/t/pickhelper-window-pick-bug-inside-a-group-component/121327/10 "2025-08-29T15:57:56Z")

</div>


