From AutoLisp to Ruby
-
@deanby7 said:
Hi
Having written many AutoLisp routines over the years, I've recently turned my hand to Sketchup Ruby. I must admit to finding it a bit more difficult to grasp the object orientated computing than I imagined. Maybe it's my age! Hopefully, slowly but surely I'll get the hang of it, with the help from you guys in this forum.
I was hoping to find some "recipes" for achieving tasks, but my search on the Internet has not been successful. If anyone knows of such useful code snippets, I would grateful.
Example:- get the user to pick one or two points on screen and store these as variables. In Lisp, this one maybe two lines of code but looking at line.rb as an example this looks to be very complicated for a ruby newbie! Could anyone assist with the basics?
I have other questions, but I won't bombard the forum all at once!! : )
Any help with the above would be most appreciated.The bare minimum required in Sketchup Ruby.
class Pick_Two def initialize @ipt = Sketchup;;InputPoint.new @pts = [] end def onLButtonDown(flags,x,y,view) @ipt.pick view,x,y @pts << @ipt.position if @pts.length==2 UI.messagebox "Point1=#{@pts[0]}\nPoint2=#{@pts[1]}" @pts=[] end end end Sketchup.active_model.select_tool Pick_Two.new
-
expanding on Sam's example, if you want something more flexible...
module SaM # namespace it so it doesn't clash class Pick_Points def initialize(n) @ipt = Sketchup;;InputPoint.new @@pts = [] @count = n @tally = 0 end def onLButtonDown(flags,x,y,view) @ipt.pick view,x,y @@pts << @ipt.position.to_a p @tally += 1 if @@pts.length == @count p 'done' Sketchup.active_model.select_tool(nil) end end end end
and run it from your code with..
n = 5 # any number Sketchup.active_model.select_tool SaM;;Pick_Points.new(n)
then retrieve it's values with...
SaM;;Pick_Points.class_variable_get(;@@pts)
john
-
Many thanks to both of you
-
I think I am not understanding something as I'm getting an error....
Error: #<NoMethodError: private method `class_variable_get' called for SaM::Pick_Points:Class>This is my test code.....
require('sketchup.rb')
def pick
n = 2
Sketchup.active_model.select_tool SaM::Pick_Points.new(n)
SaM::Pick_Points.class_variable_get(:@@pts)
puts @@pts[0]
puts @@pts[1]end
module SaM # namespace it so it doesn't clash
class Pick_Points
def initialize(n)
@ipt = Sketchup::InputPoint.new
@@pts = []
@count = n
@tally = 0
end
def onLButtonDown(flags,x,y,view)@ipt.pick view,x,y @@pts << @ipt.position.to_a p @tally += 1 if @@pts.length == @count p 'done' Sketchup.active_model.select_tool(nil) end
end
end
endif (not file_loaded?("dbpick.rb"))
UI.menu("Plugins").add_item("dbpick") { pick }
end
file_loaded("dbpick.rb") -
Is the code to have the pick points snapping to geometry and inferencing involve a lot more code?
-
you have a few things going wrong there and it's easier for me to add some note to one that works...
the main one is you need to get your own copy of the class variable and ruby doesn't wait when you call the tool, so you have to...
this one adds a timer, and adds your method into the same namespace as the class...
module BbN # namespace it so it doesn't clash extend self # avoid common names for methods def bd_pick n = 5 # call the tool Sketchup.active_model.select_tool BbN;;Pick_Points.new(n) # get it's id tool_id = Sketchup.active_model.tools.active_tool_id #create a timer and use the id to know if it's finnished wait_for_tool = UI.start_timer(1.0, true) do if Sketchup.active_model.tools.active_tool_id == tool_id else # this is the 'pop' back, we retrieve the values from the @@var result = (BbN;;Pick_Points.class_variable_get(;@@pts)) # I prefer p over puts as it shows a usable array p result[0] p result[1] # clean up UI.stop_timer(wait_for_tool) end end end class Pick_Points def initialize(n) @ipt = Sketchup;;InputPoint.new @@pts = [] @count = n @tally = 0 end def onLButtonDown(flags,x,y,view) @ipt.pick view,x,y @@pts << @ipt.position.to_a p @tally += 1 if @@pts.length == @count p 'done' Sketchup.active_model.select_tool(nil) end end end # add menu , toolbar or shortcut key cmd unless file_loaded?("dbpick.rb") cmd = UI;;Command.new(BbN;;bd_pick) UI.menu("Plugins").add_item("dbpick") {cmd} end end
also, use code blocks in the forum, it's in the toolbar...
john
-
Sorry John
With the above code I'm getting......Error Loading File dbpick.rb
Unrecognized command idI'm running Version 8 Sketchup.
Dean -
Dean - why don't you study linetool.rb
It comes with sketchup 8 and is in your plugins folder.linetool.rb gives a pretty good example of what is possible. It is missing a few features that you might want such as setting up a tool bar.
-
@deanby7 said:
...I'm running Version 8 Sketchup
Sketchup.active_model.tools.active_tool_id
has been around since v6?try it in Ruby Console after a tool change, does it fail there?
but, I agree with Garry on linetool.rb, I made a few tools based on it...
john
-
The menu item does not appear in the plugin drop down, but the script is obviously running because the ruby console is repeating an error message! I never thought picking two points on the screen could be so difficult!!
-
Sam's was the basic that you should get working first...
mine was an elaboration to show passing the the pts to something else...
have a look at the query tool in the examples folder as well...
john
-
I now have the two pick points working from sdmitch's code. I will study the linetool.rb script to fathom getting the cursor to snap to geometry! Something tells me this will be easy task!
-
@deanby7 said:
I'm running Version 8 Sketchup.
... which runs Ruby v1.8.6-p287 on PC, and v1.8.5-p0 on OSX.
@deanby7 said:
I'm getting an error....
Error: #<NoMethodError: private method
class_variable_get' called for SaM::Pick_Points:Class>`For some reason Ruby 1.8 had made
class_variable_get()
andclass_variable_set()
to be private methods.In SketchUp v14+ using Ruby 2.0+, they were changed to be public methods.
Advertisement