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.boundsand 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.
groupis just another variable - you need to make a it reference the group you want.For instance, if you want
groupto 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.
Hello! It looks like you're interested in this conversation, but you don't have an account yet.
Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.
With your input, this post could be even better π
Register LoginAdvertisement