sketchucation logo sketchucation
    • Login
    ℹ️ Licensed Extensions | FredoBatch, ElevationProfile, FredoSketch, LayOps, MatSim and Pic2Shape will require license from Sept 1st More Info

    Recursive print_group_tree() help

    Scheduled Pinned Locked Moved Developers' Forum
    12 Posts 3 Posters 483 Views 3 Watching
    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.
    • honoluludesktopH Offline
      honoluludesktop
      last edited by

      Tom, didn't know that a method can call itself. Boy I've got a lot to learn. What happens to the variables? Guess they are they recreated each time the method is called.

      1 Reply Last reply Reply Quote 0
      • D Offline
        draftomatic
        last edited by

        @thomthom said:

        1. You're getting a tree of the entities in a model - would it not be better to start with model.entities instead of scanning model.definitions for instances with parent that is model?

        Seems wasteful to iterate all of the entities when all I want is the Group tree. There will normally be less Definitions/Groups than Entities, no?

        @unknownuser said:

        1. Your code makes the assumption that all instances has instances, this might not be the case.

        What if I purge the model before I run this code?

        @model.definitions.purge_unused
        

        @unknownuser said:

        1. You can not assume groups are all unique - group definitions often has group instances. At least from what I observe from the models at our office and the warehouse.

        I'm using this routine to make all Groups unique before I run this code:

        
            @model.definitions.each { |d|
              if (d.group?())
                d.instances.each { |i|
                  i.make_unique
                }
              end
            }
        
        
        1 Reply Last reply Reply Quote 0
        • thomthomT Offline
          thomthom
          last edited by

          @draftomatic said:

          Seems wasteful to iterate all of the entities when all I want is the Group tree. There will normally be less Definitions/Groups than Entities, no?

          Yes, but you iterate the entities of the groups, so you're only skipping a few entities at the root. In most models I've seen, the root contains mostly groups or components, so there would be little to gain. You could be feeding your recursive method entities collections, starting with model. entities. You'd then have less code.

          @draftomatic said:

          What if I purge the model before I run this code?

          You could, but it's only an extra check to verify there is instances. And maybe some users don't want their model purged without their knowing.

          @honoluludesktop said:

          Tom, didn't know that a method can call itself. Boy I've got a lot to learn. What happens to the variables? Guess they are they recreated each time the method is called.

          method variables are local to each calling of the method, yes.
          Beware of recursive methods though, if you call it too many time you end up with stack overflow - which will crash SU. Very easy to do if you iterate entities with recursive methods.

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

          1 Reply Last reply Reply Quote 0
          • D Offline
            draftomatic
            last edited by

            Thanks thomthom... is this better?

              def print_group_tree()
                @model.entities.each { |e|
                  if (e.is_a?(Sketchup;;Group))
                      puts e.name
                      recurse_group(e)
                  end
                }
              end
              
              def recurse_group(group)
                group.entities.each { |e|
                  next unless e.is_a?(Sketchup;;Group)
                  puts e.name
                  recurse_group(e)
                }
              end
            
            1 Reply Last reply Reply Quote 0
            • thomthomT Offline
              thomthom
              last edited by

              Yes - though, is this just a framework of what it will do? As it is now it looks like it prints out the names in a pretty flat list...

              I mean, the code traverses the model tree, but from the code I don't see any reason to do a tree traversal. A flat traversal of model.definitions would be the same?

              What is the more abstract purpose of outputting the group names?

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

              1 Reply Last reply Reply Quote 0
              • D Offline
                draftomatic
                last edited by

                @thomthom said:

                I mean, the code traverses the model tree, but from the code I don't see any reason to do a tree traversal. A flat traversal of model.definitions would be the same?

                I'm writing an XML exporter that exports the Group tree along with the rest of the model... XML = tree.

                Obviously my real code is doing more than just printing names. But it's top-secret! πŸ˜ƒ

                1 Reply Last reply Reply Quote 0
                • D Offline
                  draftomatic
                  last edited by

                  @honoluludesktop said:

                  Tom, didn't know that a method can call itself. Boy I've got a lot to learn. What happens to the variables? Guess they are they recreated each time the method is called.

                  Look up "Recursion" =). Each call has its own scope.

                  http://en.wikipedia.org/wiki/Recursion_(computer_science)

                  One of the best examples is computing the Fibonacci sequence.

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

                    Righti'o!

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

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

                      Recursing works generally for digging down the model tree with groups and components, but if you use it to process edges and faces - like traversing connected geometry, then you will run into stack overflow.

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

                      1 Reply Last reply Reply Quote 0
                      • honoluludesktopH Offline
                        honoluludesktop
                        last edited by

                        tt, This recursive stuff really works! Below drills down into component instances. Now, on to add groups.

                        def get_ci(ci_array)
                          entities = Sketchup.active_model.entities
                          entities.each do |ent|
                            if ent.is_a? Sketchup;;ComponentInstance
                              ci_array.push ent
                            end
                          end
                          return ci_array
                        end
                        
                        def explode_ci_array(ci_array)
                          ci_sub_array=[]
                          ci_array.each do |ci|
                            if ci.is_a? Sketchup;;ComponentInstance
                              ci_sub_array=ci.explode
                            end
                          end
                          return ci_sub_array
                        end
                        
                        ci_array=[]
                        found = false
                        while found == false
                          ci_array=get_ci(ci_array)
                          ci_array=explode_ci_array(ci_array)
                          if ci_array[0] == nil
                            found = true
                          end
                        end
                        
                        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