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

    Arrange component names

    Scheduled Pinned Locked Moved Developers' Forum
    13 Posts 5 Posters 776 Views 5 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.
    • S Offline
      slbaumgartner
      last edited by

      @tt_su said:

      Why do you need to rename all the other components to place a new component?

      I'd bet that the numeric prefix has external ordering significance (like number 053 has some relation to 054) so the existing higher numbered parts have to be pushed up when a new one is inserted into the list.

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

        @tt_su said:

        The order is in no guarantied order. It doesn't change when definitions are modified.

        Ok, thanks.

        @tt_su said:

        I'm afraid it's a bit unclear to me.
        Are you trying to rename all definitions?

        Not exactly, I'm trying to insert a new component in the middle of a name-sorted list, while keeping the numbering sequence.

        @tt_su said:

        What is the expected result?

        List of components where the first 3 characters of the component name determine the component's position in the list.

        @tt_su said:

        Why do you need to rename all the other components to place a new component?

        I want to place a component in position 52 in the list, so I name it "052 - ...", but there already is a component which name starts with "052" so I need all existing component names to increase their 'index' by 1.

        Further:

        I'm working on a wooden house frame and I need a way to get the components exported in a certain order. I have numbered the 'parts' in order of 'appearance'.

        • e.g. the part you need first would be "001 - Bottom plate part - 45x95x6000". Where the "001" is the 'index' for the part and the rest is a description of it.

        So, If I at some point realise that I need to insert another piece of timber, I would create a new component. But I need to place it in a certain position in the components list (which is sorted by name). If part number 052 would be a wall stud of a certain dimension and I needed to insert a new stud of another dimension next to it I want the part to be number 051 or 053 - doesn't really matter which as long as they are close.

        If the component count at that point is 200, I'd need to increase the 'index' number for all components 053-200 by one.

        Is this any clearer?

        //S.

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

          @slbaumgartner said:

          I'd bet that the numeric prefix has external ordering significance (like number 053 has some relation to 054) so the existing higher numbered parts have to be pushed up when a new one is inserted into the list.

          Exactly : )

          //S.

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

            The core issue here is to realize that there is a difference between the ordering in which items are stored in a Ruby container as they are added (which may be seemingly random - e.g. in a hash - or may be based on some optimization of the internal structure) vs the order in which they are presented by some UI or processed by code. If the order matters for the latter purposes, you should create an Array using #to_a and then sort the Array using whatever ordering rule you like.

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

              @siim11s said:

              @slbaumgartner said:

              I'd bet that the numeric prefix has external ordering significance (like number 053 has some relation to 054) so the existing higher numbered parts have to be pushed up when a new one is inserted into the list.

              Exactly : )

              Here is some code for you to test. It seems to do what I understand you want.

              mod = Sketchup.active_model
              ent = mod.active_entities
              sel = mod.selection
              cds = mod.definitions.reject{|cd|cd.group?||cd.image?}
              prefix=('%03d' % cds.length)
              new=sel.first;new_name=prefix+' - '+new.definition.name
              inp=UI.inputbox(["New Name;"],[new_name],"Rename #{new.definition.name}")
              if inp
               prefix,name=inp[0].split(' - ')
               cds.each{|cd|
                if cd.name.index(' - ')
                 p,n=cd.name.split(' - ')
                 if p.to_i >= prefix.to_i
                  cd.name=p.next+' - '+n
                 end
                end
               }
               new.definition.name=inp[0]
              end
              
              

              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
                siim11s
                last edited by

                @sdmitch said:

                Here is some code for you to test. It seems to do what I understand you want.

                Yes.. almost. Not quite the way I imagined it though.
                It also seems to add "#1" at the end of some(?!) of the changed names.

                I'd prefer it wasn't dependent on the " - " in the name, rather that the first 3 characters are numbers. And I'd like to be able to sort through the whole list of numbered components in the model.. looking for consistency errors and correct them if needed. But I'll try to understand it better. Thanks!

                @slbaumgartner said:

                The core issue here is to realize that there is a difference between the ordering in which items are stored in a Ruby container as they are added (which may be seemingly random - e.g. in a hash - or may be based on some optimization of the internal structure) vs the order in which they are presented by some UI or processed by code. If the order matters for the latter purposes, you should create an Array using #to_a and then sort the Array using whatever ordering rule you like.

                Yes, that's where I first got stuck. I have a few Ideas I can try now, thanks for the help so far.

                //S.

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

                  @siim11s said:

                  Yes.. almost. Not quite the way I imagined it though.
                  It also seems to add "#1" at the end of some(?!) of the changed names.

                  I'd prefer it wasn't dependent on the " - " in the name, rather that the first 3 characters are numbers. And I'd like to be able to sort through the whole list of numbered components in the model.. looking for consistency errors and correct them if needed. But I'll try to understand it better. Thanks!

                  The "#1" usually only occurs when you give the same name to two definitions which is why I don't name the selected component until the end.

                  Using the " - " seemed to be the safest option given your naming sample.

                  cdn = mod.definitions.map{|cd| cd.name}.sort
                  

                  will give you a sorted array of the definition names.

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

                  http://sdmitch.blogspot.com/

                  1 Reply Last reply Reply Quote 0
                  • M Offline
                    MSP_Greg
                    last edited by

                    Try the following (based on SDMitch's code)

                    
                    mod = Sketchup.active_model
                    ent = mod.active_entities
                    sel = mod.selection
                    cds = mod.definitions.reject{|cd|cd.group?||cd.image?}
                    prefix=('%03d' % cds.length)
                    new=sel.first;new_name=prefix+' - '+new.definition.name
                    inp=UI.inputbox(["New Name;"],[new_name],"Rename #{new.definition.name}")
                    reInc = /^(\d{3})(.+)/
                    if (reInc.match(inp[0]))
                      new.definition.name = inp[0]
                      iPre = $1.to_i
                      iCD = 0
                      cds.each { |cd|
                        if (reInc.match(cd))
                          iCD = $1.to_i + 1
                          cd.name = "%03d#{$2}" %iCD if iCD > iPre
                        end
                      }
                    end
                    
                    

                    As long as the cd name begins with three numbers...

                    Note - no testing for prefixes greater than 999, and no testing for duplicate names after the increment.

                    Greg

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

                      @msp_greg said:

                      Try the following (based on SDMitch's code)

                      
                      > mod = Sketchup.active_model
                      > ent = mod.active_entities
                      > sel = mod.selection
                      > cds = mod.definitions.reject{|cd|cd.group?||cd.image?}
                      > prefix=('%03d' % cds.length)
                      > new=sel.first;new_name=prefix+' - '+new.definition.name
                      > inp=UI.inputbox(["New Name;"],[new_name],"Rename #{new.definition.name}")
                      > reInc = /^(\d{3})(.+)/
                      > if (reInc.match(inp[0]))
                      >   new.definition.name = inp[0]
                      >   iPre = $1.to_i
                      >   iCD = 0
                      >   cds.each { |cd|
                      >     if (reInc.match(cd))
                      >       iCD = $1.to_i + 1
                      >       cd.name = "%03d#{$2}" %iCD if iCD > iPre
                      >     end
                      >   }
                      > end
                      > 
                      

                      As long as the cd name begins with three numbers...

                      Note - no testing for prefixes greater than 999, and no testing for duplicate names after the increment.

                      Greg

                      Greg,

                      Tried your code and found two problems.

                      1. if(reInc.match(cd)) needs to be if(reInc.match(cd.name))

                      2. the prefix of the new name entered gets incremented as well. the new.definition.name = inp[0] statement needs to be the last thing done in the if (reInc.match(inp[0])) section.

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

                      http://sdmitch.blogspot.com/

                      1 Reply Last reply Reply Quote 0
                      • M Offline
                        MSP_Greg
                        last edited by

                        siim11s,

                        The previous code I posted didn't allow for name collisions. Below code should allow for it. Also added a few comments...

                        
                        # reInc checks for match of three digits at beginning of string,
                        # loads digits into $1, rest of name into $2
                        reInc = /^(\d{3})(.+)/
                        
                        if (reInc.match(inp[0]))
                          # sort reverse so name colisions won't occur
                          cds.sort! { |a,b| b.name <=> a.name }
                        
                          # initialize loop variables
                          iPre = $1.to_i
                          iCD = 0
                        
                          cds.each { |cd|
                            if (reInc.match(cd.name))
                              iCD = $1.to_i + 1
                              # since we're reverse sorted, break when we reach low numbers
                              break if iCD <= iPre
                              cd.name = "%03d#{$2}" %iCD
                            end
                          }
                          new.definition.name = inp[0]
                        end
                        
                        # for testing, use below to resort & output new names
                        cds.sort! { |a,b| a.name <=> b.name }
                        cds.each { |cd| puts cd.name }
                        
                        

                        Greg

                        1 Reply Last reply Reply Quote 0
                        • M Offline
                          MSP_Greg
                          last edited by

                          SDMitch (Mitch?),

                          @sdmitch said:

                          Tried your code and found two problems.

                          1. if(reInc.match(cd)) needs to be if(reInc.match(cd.name))

                          Thanks for the catches. I edited & corrected the second post. I tested mine with a string array, not an array of cd's. Hence, no name prop.

                          @sdmitch said:

                          1. the prefix of the new name entered gets incremented as well.

                          That's why you had the new cd name assign at the end of the loop. That's why I shouldn't change code after I've tested it...

                          Thanks,

                          Greg

                          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