sketchucation logo sketchucation
    • Login
    ℹ️ GoFundMe | Our friend Gus Robatto needs some help in a challenging time Learn More

    Interrogating each group to find Cylinders & Cubes

    Scheduled Pinned Locked Moved Developers' Forum
    8 Posts 4 Posters 635 Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • N Offline
      nkclarke
      last edited by

      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

      1 Reply Last reply Reply Quote 0
      • TIGT Offline
        TIG Moderator
        last edited by

        @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.
        Thanks

        If you have groups then you can of course give them names like group.name='cuboid' and group.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' edges

        
        faces.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' face

        circle=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... πŸ€“

        TIG

        1 Reply Last reply Reply Quote 0
        • N Offline
          nkclarke
          last edited by

          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.

          1 Reply Last reply Reply Quote 0
          • N Offline
            nkclarke
            last edited by

            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?

            1 Reply Last reply Reply Quote 0
            • TIGT Offline
              TIG Moderator
              last edited by

              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...

              TIG

              1 Reply Last reply Reply Quote 0
              • P Offline
                peterjohnson84
                last edited by

                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

                1 Reply Last reply Reply Quote 0
                • thomthomT Offline
                  thomthom
                  last edited by

                  @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]

                  Thomas Thomassen β€” SketchUp Monkey & Coding addict
                  List of my plugins and link to the CookieWare fund

                  1 Reply Last reply Reply Quote 0
                  • P Offline
                    peterjohnson84
                    last edited by

                    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.

                    1 Reply Last reply Reply Quote 0
                    • 1 / 1
                    • First post
                      Last post
                    Buy SketchPlus
                    Buy SUbD
                    Buy WrapR
                    Buy eBook
                    Buy Modelur
                    Buy Vertex Tools
                    Buy SketchCuisine
                    Buy FormFonts

                    Advertisement