Script not waiting after importing


#1

I’m trying to do stuff to objects after they are imported but the script keeps going before I can pick a point, very frustrating. I have 2 questions, first one is out of curiosity.

  1. Was it an oversight that the developers of the Ruby script language forget to add an insert point parameter to the insert method, that is bizarre.

  2. That being said, main question, how do you get the script to wait for the mouseclicks (to insert) then continue with the rest of the script ?

Here is the peared down script:

require 'sketchup.rb’
UI.menu (“PlugIns”).add_item(“Import 3DS test”){
model=Sketchup.active_model
result = UI.messagebox “Import 3DS ?” ,MB_OKCANCEL
if result == 1

result2 = UI.messagebox “Do it” ,MB_OKCANCEL
if result2 == 1
model.import “c:/temp3/new.3ds”, true
end #result2

UI.messagebox “I should not appear yet until a point is picked ?” ,MB_OKCANCEL
end #result
}

Thanks for reading.


#2

Model.import can do with some improvements. It’s not entirely consistent across importers. Some import the model at ORIGIN, some activate the Place Component tool.

As you have noticed, it’s often more useful to developers to simply get a definition loaded in the model instead of having the instance automatically placed in the model. IMO model.import should work like model.definitions.load.

For importers that activate the Place Component tool I’d use an observer to detect when the instance is placed. (Taking into account that the user might cancel (could be a bit tricky.).

(btw, code is a lot easier to read if you wrap it up as Preformatted Text )


#3

I have posted here before, I forget how to get the code in that format, sorry.
I never used any of the observer class methods so I will have to learn how they work, I will look into that, but you are saying that that should make the script wait for a user input ?


#4

No need for an observer…
Do something like this to break the placement prompt, whilst leaving the newly imported component in the definitions list, then you find it and put an instance of it at the origin…

defnsIN=model.definitions.to_a
model.import(path_to_file)
Sketchup.send_action("selectSelectionTool:")
defnsOUT=model.definitions.to_a
defn=nil
unless defnsIN==defnsOUT
  defn=defnsOUT[-1]
end
model.entities.add_instance(defn, Geom::Transformation.new(ORIGIN)) if defn

#5

The Ruby scripting language was not developed for SketchUp specifically. It was developed in Japan. Ruby’s development and maintenance is totally separate from SketchUp development.

SketchUp embeds the Ruby interpreter and adds libraries called an API, so that SketchUp models and application functions can be accessed from scripts.

It is more general that this.

Your main issue is that you are writing sequential code. This is code that operates in a linear fashion.

In order to accommodate the user of an application, you need to write event-driven code.

This kind of code is broken up into methods that get called by the application engine (known as “callback methods”,) in response to an event initiated by the user.
In SketchUp there are two ways. One is called an observer, that “observes” events and responds to them.
Events such as a mouse click, … or the placing of a component. The opening of a model, the saving of a model, the deleting of an model entity, and many others. (See the observer classes in the API documentation.)

The other is a Tool class instance that also has callback methods for mouse clicks and key presses. See the Examples extension from the Extension Warehouse by the SketchUp Team.