Run SandBox Add Detail Tool from Script

How can I run the native Add Detail tool from within a script/the console?

I can identify its name as ‘AddDetailTool’ by using:
Sketchup.active_model.tools.pop_tool

And it’s ID as 50400 by using
Sketchup.active_model.tools.active_tool_id

But how do I now run it on a selection of faces?
I thought one could use push_tool, but if I select the faces and run:
Sketchup.active_model.tools.push_tool(50400)

The console returns True but nothing happens.

The goal is to run it on all the faces within a selection of different groups.

P.S: The ID for this tool seems to change everytime I run push_tool. Am I missing something?

Add multiple images

Sketchup.html#send_action-class_method
E.g:

Sketchup.send_action("selectPushPullTool:")

However…

… is not possible with the Push/Pull tool.

Sorry if I wasn’t being clear.

I’m not trying to use the “Push/Pull Tool”
I’m trying to use the SandBox “Add Detail” Tool.

The push_tool method is used to “activate” a tool, as described here:

and here:

Yea. Okay. My example just to show how to activate the built in tool.
The SandBox is delivered as a custom tool, I don’t know a method to select it from Ruby. But I’m almost certain that you can not pass a parameters or objects to it… (nor to built in tool)

The built in tools are programmed to be controlled interactive by the GUI, not by Ruby code. The Ruby API provides primitive operations from which you can usually accomplish the same result from your code though it requires a pretty good understanding of the API.

Command IDs are only valid for a session. They are not persistent between sessions.
Also the nature of context menu commands is that their IDs are only valid whilst the context menu is displayed. Afterward the IDs are recycled and might be different the next time a context menu is “built”.

Try this (which would only work for English distro) …

module Richersims
  module SomePlugin

    AddDetailCmd = nil
    ObjectSpace.each_object(UI::Command) {|o|
      break AddDetailCmd = o if o.menu_text == "Add Detail"
    }
    
    def add_detail
      Sketchup.active_model.select_tool(AddDetailCmd)
    end

  end
end

ADD: If the Sandbox Tools extension is not loaded, then the add_detail method above would active the SelectionTool.

Thanks for the help.
I tried your code but the same occurs.
The tool is activated (I can tell because the selection tool deactivates and the name of the tool appears when I use pop_tool) but no actual addition of detail occurs.

Well I do not know much about the Sandbox Tools as they are encrypted and not open source.

Perhaps it only adds “detail” to objects that the extension creates ? (Extensions know what they create by attaching attribute dictionaries. So perhaps use one of the attribute inspector extensions to do some snooping ?)

We cannot say why as we do not have your test model or code and don’t know what you really are trying to do.

The test model is a single selected triangle.

The code I placed directly into the console is as follows:

AddDetailCmd = nil
ObjectSpace.each_object(UI::Command) {|o|
  break AddDetailCmd = o if o.menu_text == "Add Detail"
}
Sketchup.active_model.select_tool(AddDetailCmd)

The console simply returns Sketchup::Model:0x0000000de68b30 instead of splitting the triangle into 4 smaller ones.

The API documentation for the Sketchup::Model#select_tool method indicates that it simply returns the model object although activating the tool argument, … so this part of your observation is expected.

I tested out the tool, was I did get this helper warning …

image

In practice you need two triangular faces as the tool’s cursor does not activate until you are over the shared edge of 2 triangular faces. EDIT: OH no, it WILL split 1 triangular face into 3 triangular faces.


… and after further testing, … I don’t know why now (as it worked yesterday,) but most of the UI::Command objects for the Sandbox extension are “hidden”. (I suspect some of the API reflection methods may be “tweaked” to be silent about them as this is a proprietary extension.)

Anyway I was able to get this to work …

AddDetailCmd = nil
ObjectSpace.each_object(UI::Toolbar) {|tb|
  if tb.name == "Sandbox"
    tb.each do |cmd|
      next if cmd == "|"
      if cmd.menu_text == "Add Detail"
        break AddDetailCmd = cmd
      end
    end
    break
  end
}

But you cannot select the command from the Ruby Console because the console window has focus.
So I added a context menu item …

UI.add_context_menu_handler {|menu| menu.add_item(AddDetailCmd) }

… and it works. It is a bit quirky though. I had to right-click on one of the axis and choose the menu item, and then hover over a shared edge for a couple of faces to get the “Add Detail” cursor.

Anyway … back to what was said earlier, … I have to agree that attempting to use this for automated code is likely not to be useful. You cannot pass a point to the tool’s command proc.

You will be better off coding your own triangular face splitter method.

1 Like

Thank you so much for your help Dan.
The code you provided does work but I agree that using the context menu item defeats the purpose.
I will attempt to create my own tool and will report back if I am successful.

FYI, It is faster for manual use, to assign a shortcut to “Tools > Sandbox > Add Details”.
(I just tried it after assigning F9 as the shortcut. Works well.)