Interrogating each group to find Cylinders & Cubes
-
I'm new to script writing but I'm trying to write a Ruby script to complete a task I've been given at work. I have a skp file containing only separate groups (several hundred). Each group consists of EITHER a CYLINDER or a CUBOID. I'm trying to come up with a script that examines each group in turn and can judge whether the shape is a cylinder or a cuboid. If the shape turns out to be a cylinder, I need to extract the co-ordinates of the face centre, the diameter of the circle and the length of the cylinder. If the group meets the criteria of a cuboid, I need the co-ords of the lower corner/vertex and the dimensions of the cuboid.
Also, I need to be able to export the above information into a text file.
Any tips or help would be gratefully appreciated. Or, a view on the achievability of what I'm trying to do would also be useful.
Thanks
-
@nkclarke said:
I'm new to script writing but I'm trying to write a Ruby script to complete a task I've been given at work. I have a skp file containing only separate groups (several hundred). Each group consists of EITHER a CYLINDER or a CUBOID. I'm trying to come up with a script that examines each group in turn and can judge whether the shape is a cylinder or a cuboid. If the shape turns out to be a cylinder, I need to extract the co-ordinates of the face centre, the diameter of the circle and the length of the cylinder. If the group meets the criteria of a cuboid, I need the co-ords of the lower corner/vertex and the dimensions of the cuboid.
Also, I need to be able to export the above information into a text file.
Any tips or help would be gratefully appreciated. Or, a view on the achievability of what I'm trying to do would also be useful.
ThanksIf you have groups then you can of course give them names like
group.name='cuboid'
andgroup.name='cylinder'
- then NO tests are needed just compare the names !!!If that simple trick won't do...
To see if a 'face' belongs to a cuboid test it for number of edges and connected faces...face=nil group.entities.each{|e| if e.class==Sketchup;;Face face=e break end } not_cuboid=false not_cuboid=true if face.edges.length!=4 faces=[]; face.all_connected.each{|e|faces << e if e.class==Sketchup;;Face} not_cuboid=true if faces.length!=6 faces.each{|f| if f.edges.length!=4 not_cuboid=true break end }
'face' is a cuboid 'if not not_cuboid'
This doesn't trap a cylinder made with 4 sided circles which would look 'cuboid' too...
If the cylinder is truly made from a 'circle' then you can test further for 'curve' and 'smooth' edgesfaces.each{|f| f.edges.each{|e| if e.curve and e.curve.class==Sketchup;;ArcCurve end if e.smooth? not_cuboid=true break end } break if not_cuboid }
It also doesn't trap for non-right-angled corner cuboids... to check for that
faces.each{|f| verts=f.vertices vertsp=verts+verts[0]+verts[1] (verts.length).each{|i| veca=vertsp[i+1].vector_to(vertsp[i]) vecb=vertsp[i+1].vector_to(vertsp[i+2]) ang=veca.angle_between(vecb) if ang!=90.degrees not_cuboid=true break end } }
...
If it's a cuboid then get
bb=group.bounds
and then
x=bb.min.x y=bb.min.y z=bb.min.z
If it's a cylinder find the 'circle' facecircle=nil len=nil group.entities.each{|e| if e.class==Sketchup;;Edge if e.curve and e.curve.class==ArcCurve circle=e len=e.length break end end } center=circle.center diameter=circle.radius*2 height=nil group.entities.each{|e| if e.class==Sketchup;;Edge if not e.curve height=e break end end }
You now have center, diameter and height for the cylinder...
-
Thank you so much for that. You went to a lot of trouble for me and I appreciate it. I think it'll take me some time to get my head around it but for me it's a good introduction to Ruby.
-
Once I've been able to extract all of the data I need during my interrogation of all the groups, is it possible to export these variables into a separate text file? Or does the Ruby environment within SketchUp prefer the user to stay within SketchUp?
-
It's easy enough to export data to a file.
Find ComponentReporter++.rb for an example...
Export and Import are relatively straightforward, it how you manipulate the data before/afterwards that's more tricky... -
I am also working on this problem and though I follow the logic behind the code you wrote - I am struggling to implement it.
How do you get sketchup to recognise the group.(...) method? i.e. stop it returning the error:
undefined local variable or method `group' for JF::WebConsole:Module
when I type:
face=nil group.entities.each{|e| if e.class==Sketchup;;Face face=e break end } not_cuboid=false not_cuboid=true if face.edges.length!=4 faces=[]; face.all_connected.each{|e|faces << e if e.class==Sketchup;;Face} not_cuboid=true if faces.length!=6 faces.each{|f| if f.edges.length!=4 not_cuboid=true break end }
Its as if sketchup doesn't know what group I'm referring to - doesn't know what 'group' even is. After searching I have noticed some talk about 'active_entities' and suspect the answer may be invlved with this somehow.
Apologies if this sounds like nonsense - I think I'm missing something big, but can't work out what it is.
Cheers, Pete
-
@peterjohnson84 said:
Its as if sketchup doesn't know what group I'm referring to
Because it doesn't.
group
is just another variable - you need to make a it reference the group you want.For instance, if you want
group
to reference the selected object:
group = Sketchup.active_model.selection[0]
-
That's the badger! Though as is the way with these things, it seems so simple once I know the solution.
Thankyou very much anyway...that has helped me a great deal.
Advertisement