I want to write a ruby script : rotate an object
-
I want a ruby script that selects all entities on a specific layer, the rotates it on the axis origin after prompting for the specific angle.
Are there any samples of ruby scripts that can do anything like this that I can work from?
I appreciate any help.
-
Manual:
Switch to layer in question.
Hide all other layers.
Select All (CTRL+A)
Choose the RotateTool
Pick the origin
enter the angle in the VCB
Then if that all works the way you wish... write a ruby method that does the same thing.
-
I just had a small but satisfying breakthrough reverse-engineering some established ruby scripts to get the functionality I wanted.
I might just be able to finish this script I have in mind after all...
-
I have this simple ruby script to rotate a selection of entities around the red axis by 45 degrees by pressing the up key:
class Rotationtest # perform rotate def rotate(angle) tr = Geom;;Transformation.rotation([0,0,0],[1,0,0],angle.degrees) Sketchup.active_model.active_entities.transform_entities(tr,Sketchup.active_model.selection) end # process upkey def onKeyDown(key, repeat, flags, view) case key when VK_UP then rotate(45) end end end # class Rotationtest if(not $rotatoiontest_menu_loaded) UI.menu("Plugins").add_item("ROTATION TEST") { Sketchup.active_model.select_tool Rotationtest.new } end $rotatoiontest_menu_loaded = true
I want to replace the "press up key to rotate 45 degrees" function with an input prompt for a specific rotation angle when I select the plugin function from the menu.
How should I go about that?
-
I appreciate the response. I'll see what I can't do from here on. (This plugin I'm working on will be a huge time saver if I can get it to work.)
-
Adam
You need to learn how to write all code within your own module namespace.
Then make a plugin sub-module within that.
And inside that sub-module, write a proper event driven
Tool
class, that will be used by the plugin.Read the API on the Tool class. It MUST have an
activate
callback method.Also your tool should test for
model.selection.empty?
and if it is empty, beep or display aUI.messagebox("Nothing Selected!")
, then activate the SelectTool, viaSketchup.send_action("selectSelectionTool:")
You also may need to pass an array of things to Entities.transform_entities, as the 2nd argument.
so useSketchup.active_model.selection.to_a
(instead of passing the reference to the selection collection itself.)Instead of an input box.. tools can use the VCB (aka Measurements entry bar.)
def onUserText(text, view) @angle = text.to_f rotate(@angle) end
Once you get it working... wrap the "action" in a
begin
..rescue
block with an undo operation.
see: [ Code ] wrapping operationsAnd don't forget to use the [Code Snippets] Index (it's a "Sticky Topic" at the top of this forum!)
-
Do not use
$var
global variables. There is no good reason for your code to ever execute outside your namespace.Your file should be set up similar to this:
require('sketchup.rb') module Lauder module RotateSelection VERSION = '1.0.0' AUTHOR = 'A.J. Lauder' class RotaterTool # your tool callbacks HERE end # RotaterTool @@thisfile = 'AJLauder;'<<File.basename(__FILE__) unless file_loaded?(@@thisfile) UI.menu("Plugins").add_item("ROTATION TEST") { Sketchup.active_model.select_tool( RotaterTool.new ) } file_loaded(@@thisfile) end # unless end # RotateSelection end # Lauder
In Ruby
class
...end
andmodule
...end
mean "open for modification (and create if not yet defined)." This means a module or class definition can span any number of files.So everyone of your plugins will be defined within your OWN unique toplevel module. Every time Ruby reads another one of your files, it will reopen
module Lauder
and add the any new sub-module or class definitions inside your namespace.P.S.: I used
Lauder
as an example. YOU can choose any unique namespace you wish. -
Here is the inputbox section on SketchUp API
http://www.sketchup.com/intl/en/developer/docs/ourdoc/ui#inputboxHere is an example...
#---------------------------- #Set Rotation #---------------------------- def initialize() @angle = 0 results = inputbox(["Enter Rotation;"], @angle, "Set Rotation") return if !results @angle = results[0] end #def def rotate(@angle) tr = Geom;;Transformation.rotation([0,0,0],[1,0,0],@angle.degrees) #<-- add @angle value from inputbox Sketchup.active_model.active_entities.transform_entities(tr,Sketchup.active_model.selection) end #def def onLButtonDown(flags,x,y,view) rotate(@angle) end #def
The above code is not tested so I might have done something wrong...Cheers!
-
Thank you for this information.
Mind you, I'm in no particular hurry to have this plugin up and running; I have a lot of modeling to finish first.
However, I desire the eventual script to do the following functions:
-Prompt for a specific rotation angle.
-Set the axes on specific lines in a model-specific group that can be manually moved and oriented around the model.
-Select all entities on certain model-specific layers.
-Then rotate the selection on the origin of the new axes position. -
Hi, I was working on adding selected component on layer created with inputbox result and thought you might want to take a look at it.
@@sel = Sketchup.active_model.selection[0] ; @@sel.name results = inputbox(["Enter Layer Name;"], [@@sel.name], "Set;; LAYER") return if !results layers.add results[0] layer = Sketchup.active_model.layers.add results[0] @@sel.layer = results[0]
I want to learn if instead of having a text inputbox you can also have a dropdown menu list with existing layers on it so you can select from there aswell.
If anyone know how to do that let me know thanks!
Cheers!
-
@unknownuser said:
I want to learn if instead of having a text inputbox you can also have a dropdown menu list with existing layers on it so you can select from there aswell.
Yes I have done that.. it is one one my files (somewhere)
just guessing it's similar to this:
def choose_layer(active=false) model = Sketchup.active_model layset = model.layers deflay =( active ? model.active_layer.name ; layset.first.name ) laylist = layset.map(){|l| l.name }.join('|') results = inputbox(["Layer ;...... "], [deflay], [laylist], " Choose Layer") results ? layset[results.first] ; nil end #
Advertisement