sketchucation logo sketchucation
    • Login
    โ„น๏ธ Licensed Extensions | FredoBatch, ElevationProfile, FredoSketch, LayOps, MatSim and Pic2Shape will require license from Sept 1st More Info

    Ruby Group Swap

    Scheduled Pinned Locked Moved Developers' Forum
    12 Posts 3 Posters 1.6k 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.
    • TIGT Offline
      TIG Moderator
      last edited by

      Something like this:

      gnames=['TubeLeft', 'TubeRight'. 'Widget']
      cnames=['TubeLeft4', 'TubeRight4', 'MyBanana']
      ### or whatever arrays of group/component-definition names you want to swap from/to...
      ### We'll assume that we have previously imported the group[s] in a SKP, and
      ### you already have the replacement component-definition[s] loaded into the model definitions list...
      model=Sketchup.active_model
      defns=model.definitions
      gnames.each_with_index{|gname, index| ### 'index' lets us find the matching 'cname'
        defns.to_a.each.collect{|d|
          d if d.group? && d.instances[0].name==gname ### collect matching group[s] definitions
        }.each{|g| ### in case more than one match !
          cname=cnames[index] ### note use of 'index'
          cdefn=defns[cnames[index]]
          g.instances.each{|i| i.definition=cdefn } if cdef ### i.e. we skip this IF no match !
        }
      }
      
      

      This processes the names in the two Arrays.
      So it swaps all groups named 'TubeLeft' with a component-definition named 'TubeLeft4' etc...
      IF they exist...

      TIG

      1 Reply Last reply Reply Quote 0
      • S Offline
        Skastafari
        last edited by

        I really like your idea. Keeping a list of group names and a corresponding list of component names will make managing my models really easy. I was trying to implement your method, and mostly failing. My template is set up with components already loaded, and the groups import with my geometry. I keep getting Error: #<LocalJumpError: no block given> and (eval):2536:in `each_with_index' I am still trying to figure out what I did wrong. If anything jumps out, let me know. The only thing I found was a period instead of a comma on gnames=[] I do really appreciate your time on this. I will continue working on it until I can get it running. I am thinking I better start making sure my origins match up on my groups and corresponding components. Thanks again TIG.

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

          Try this alternative:

          gnames=['TubeLeft', 'TubeRight', 'Widget']
          cnames=['TubeLeft4', 'TubeRight4', 'MyBanana']
          ### or whatever arrays of group/component-definition names you want to swap from/to...
          ### We'll assume that we have previously imported the group[s] in a SKP, and
          ### you already have the replacement component-definition[s] loaded into the model definitions list...
              model = Sketchup.active_model
              defns = model.definitions
              gnames.each_with_index{|gname, index| ### 'index' lets us find the matching 'cname'
                defns.to_a.each.select{|d|
                  d.group? && d.instances[0].name == gname ### collect matching group[s] definitions
                }.each{|g| ### in case more than one match !
                  cname = cnames[index] ### note use of 'index'
                  cdefn = defns[cnames[index]]
                  g.instances.each{|i| i.definition=cdefn } if cdef ### i.e. we skip this IF no match !
                }
              }
          
          

          Sorry... but this is untested... but I just don't have time to test these fully right now... ๐Ÿ˜ž
          If there's an error in the RC look at he line it indicates...

          TIG

          1 Reply Last reply Reply Quote 0
          • sdmitchS Offline
            sdmitch
            last edited by

            @skastafari said:

            I really like your idea. Keeping a list of group names and a corresponding list of component names will make managing my models really easy. I was trying to implement your method, and mostly failing. My template is set up with components already loaded, and the groups import with my geometry. I keep getting Error: #<LocalJumpError: no block given> and (eval):2536:in `each_with_index' I am still trying to figure out what I did wrong. If anything jumps out, let me know. The only thing I found was a period instead of a comma on gnames=[] I do really appreciate your time on this. I will continue working on it until I can get it running. I am thinking I better start making sure my origins match up on my groups and corresponding components. Thanks again TIG.

            In addition to the period instead of a comma in the gnames array, the last line with 'if cdef' should be 'if cdefn'. But even with those corrections, it still fails for me with the following error 'undefined method definition=' for #<Sketchup::Group:0xc9c7710>'. Despite the API showing a 'group.definition' option, that also causes the error 'undefined method definition' for #Sketchup::Group:0xc9c7710.

            My solution deletes the group and places the component using the group's transformation.

             mod = Sketchup.active_model
             ent = mod.active_entities
             sel = mod.selection
             gnames=['TubeLeft', 'TubeRight', 'Widget']
             cnames=['Bench', 'Couch', 'Nancy']
             mod.start_operation 'GroupSwap'
             ent.grep(Sketchup;;Group).each{|g| 
              ndx=gnames.index(g.name)
              if ndx
               c=mod.definitions[cnames[ndx]]; 
               if c
                gt=g.transformation;
                g.erase!
                ent.add_instance(c,gt)
               else
                puts "#{cnames[ndx]} not found"
               end
              end
             }
             mod.commit_operation
            
            

            BeforeG2C before.jpg
            AfterG2C after.jpg

            Nothing is worthless, it can always be used as a bad example.

            http://sdmitch.blogspot.com/

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

              The '.' v ',' in the initial ' gnames' array was a stupid typo. ๐Ÿ˜ณ
              Also swap the typo:
              ... i.definition=cdefn } if cdef ### i.e. >>> ... i.definition=cdefn } if cdef**n** ### i.e.

              Otherwise it ought to work [but, as yet untested... typed from memory ๐Ÿ˜ฎ ]

              TIG

              1 Reply Last reply Reply Quote 0
              • sdmitchS Offline
                sdmitch
                last edited by

                TIG, I'm sure it will work as soon as Skastafari and I upgrade to 2015.

                Nothing is worthless, it can always be used as a bad example.

                http://sdmitch.blogspot.com/

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

                  You can mimic resetting a group's definition in earlier versions using alternatives - try this...

                      gnames=['TubeLeft', 'TubeRight', 'Widget']
                      cnames=['TubeLeft4', 'TubeRight4', 'MyBanana']
                      ### or whatever arrays of group/component-definition names you want to swap from/to...
                      ### We'll assume that we have previously imported the group[s] in a SKP, and
                      ### you already have the replacement component-definition[s] loaded into the model definitions list...
                          model = Sketchup.active_model
                          defns = model.definitions
                          gnames.each_with_index{|gname, index| ### 'index' lets us find the matching 'cname'
                            defns.to_a.each.select{|d|
                              d.group? && d.instances[0].name == gname ### collect matching group[s] definitions
                            }.each{|g| ### in case more than one match !
                              cname = cnames[index] ### note use of 'index'
                              cdefn = defns[cnames[index]]
                              g.instances.each{|i|
                                i.parent.entities.add_instance(cdefn, i.transformation) ### place compo over group
                                i.erase! ### remove original group
                              } if cdefn ### i.e. we skip this IF no match !
                            }
                          }
                  
                  

                  TIG

                  1 Reply Last reply Reply Quote 0
                  • S Offline
                    Skastafari
                    last edited by

                    I was able to get some desirable results using most of sdmitch's code. Perhaps I am against some issues with my older license of Pro 8 that I was just not aware of (ruby 2.0 differences?) I am also having some new unforeseen issues with the origin points on my imported geometry. For some reason all imported groups are sharing the same origin. So it has become rather frustrating processing my models when all my components end up at what appears to be a global origin point for all imported groups (Using Fluid importer). I do think it is necessary to grab the transform from the group to apply to the component for proper placement of the component during the swap. Right now the only thing I can come up with to solve my problem would be to just first run another script that explodes each group, and then regroups it with the same name. Is there any easier way to reset a group's (transform) origin?

                    I really appreciate the ideas and feedback here, You guys have saved me from hours and hours of trial and error frustration already. The day to day grind of manually swapping out hundreds of groups with components is about as pleasurable as getting my teeth pulled. Thanks again, these ideas so far are more than I could have hoped for.

                    1 Reply Last reply Reply Quote 0
                    • sdmitchS Offline
                      sdmitch
                      last edited by

                      @skastafari said:

                      I was able to get some desirable results using most of sdmitch's code. Perhaps I am against some issues with my older license of Pro 8 that I was just not aware of (ruby 2.0 differences?) I am also having some new unforeseen issues with the origin points on my imported geometry. For some reason all imported groups are sharing the same origin. So it has become rather frustrating processing my models when all my components end up at what appears to be a global origin point for all imported groups (Using Fluid importer). I do think it is necessary to grab the transform from the group to apply to the component for proper placement of the component during the swap. Right now the only thing I can come up with to solve my problem would be to just first run another script that explodes each group, and then regroups it with the same name. Is there any easier way to reset a group's (transform) origin?

                      I really appreciate the ideas and feedback here, You guys have saved me from hours and hours of trial and error frustration already. The day to day grind of manually swapping out hundreds of groups with components is about as pleasurable as getting my teeth pulled. Thanks again, these ideas so far are more than I could have hoped for.

                      Here is a link that should help with the "misplaced" origins.

                      http://sketchucation.com/forums/viewtopic.php?t=30508

                      Nothing is worthless, it can always be used as a bad example.

                      http://sdmitch.blogspot.com/

                      1 Reply Last reply Reply Quote 0
                      • S Offline
                        Skastafari
                        last edited by

                        I have plugged away at the imported origin problem some more, I found that exploding imported groups is undesirable as it leaves behind unwanted vertices on your non-grouped objects when you regroup. I messed around writing an explode/regroup routine (it was buggy) and then I found a similar thread where TIG had an elegant less buggy explode/regroup solution using an array. it was something like...
                        sel = mod.selection groupArray=(sel[0].explode.find_all{|e|e if e.respond_to?(:bounds)}).uniq Sketchup.active_model.entities.add_group(groupArray)

                        That fixed the origin points, but I found that I cannot explode to get a new origin as it ruins ungrouped geometry in my model. I found that exploding is unnecessary and is only really a limitation of using SketchUp's interface, as there is no option to add a single group object inside another group. You would need to select at least 1 other object since the only options available in SU are "edit group", "make component", or "explode". With ruby I can just use add_group and I have a single group inside a group. Easy enough for me even with my limited ruby experience. Now I just need a way to get the name of each group add it to a new group with the same name. I need help with syntax for this.

                        The only potential problem I can see with this ide to reset origin is that perhaps SU won't like having a group inside a group of the same name. If it defaults to something like group_1 or something I can just update my "gname" to reflect that, hopefully that is the case.

                        I will check out that thread link sdmitch, thanks for your help.

                        1 Reply Last reply Reply Quote 0
                        • S Offline
                          Skastafari
                          last edited by

                          If anyone is interested, I finally solved my imported group's origin problem fairly simply with this...

                          ga = entities.grep(Sketchup::Group) ga.each { |e| n=e.name; e.model.entities.add_group(e); e.parent.instances[0].name=n}

                          Basically it just takes all the groups after import, adds them into a new group and names the new group the same name. This resets the origin, and allows the swap code to work properly.

                          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