Stop automatic rename of objects script.py



  • Hi There,

    yes there might be some or more users what do like the automatic rename, but on the other hand there are still users that like it to have the structure clean instead.
    Do you know if there is already a script done by someone what deletes every text starting from .1, .2, .3 and so on to clean it up a bit or does anybody know how to script this?

    Thank you very much for your help!

    Best Regards,
    Peter and Michael



  • To change the name of all the scene objects, you have to iterate over all the objects. You can do that recursively or non-recursively.

    For the given object, you can simply check if the name has a "." and get the substring before that dot.

    # get name
    name = op.GetName()
    
    # find last ".""
    pos = name.rfind(".")
    if pos != -1:
        
        # get substring
        name = name[0:pos]
         
        print(name)
        op.SetName(name)
        c4d.EventAdd()
    

    But this will change the name of all objects that have a "." in the name. A more advanced version of this would check if the part right of "." is actually a number.



  • Hi @peXel, thanks for reaching out us.

    With regard to your request, following-up with the suggestion from @PluginStudent (kudos dude) I warmly recommend to read BaseList2D and GeListNode to get familiar with the concepts needed to properly traverse the scene and manage the information found belonging to the encountered objects.

    If there are no further questions, please remember to set the Thread to Solved.

    Best, R!



  • Hi There,

    Sorry I was off for a while (...)
    Thanks @PluginStudent for this, but it does not solve the problem sadly.
    It does just rename one object. What I am looking for is to rename all objects at all, no matter if .1 .2 .3 or what else .xxx
    Just to get things more clean again. I am not a programmer, so I can't do any real scripting sadly

    Thank you very much

    Best,
    Peter



  • Hi Peter, see if the code below can temporary solve your issue.

    import c4d
    
    def Rename (op):
        # check for op being valid
        if op is None:
            return
        
        # get the name
        name = op.GetName()
        
        # find last ".""
        pos = name.rfind(".")
        if pos != -1:
            # get substring
            name = name[0:pos]
        
        # remove the additional "."
        name = name.replace(".", "_")
        
        # set the name
        op.SetName(name)
    
        # iterate over the child
        if op.GetDown() is not None:
            Rename(op.GetDown())
            
        # iterate over the sibling
        if op.GetNext() is not None:
            Rename(op.GetNext())
    
    # Main function
    def main():
        # retrieve the first item in the Object Manager and pass it to Rename
        Rename(doc.GetFirstObject())
        
        # notify Cinema 
        c4d.EventAdd()
    
    # Execute main()
    if __name__=='__main__':
        main()
    

    The code above is just a draft example on how you can get it done but it should be on you to adapt it to your specific needs. Using a code without any grain of salt can be dangerous and error prone and it should also be noted that we're here to support rather than to provide solution.

    I again iterate the suggestion to have a look to BaseList2D and GeListNode to get familiar with the concepts needed to properly traverse the scene and manage the information found belonging to the encountered objects and also, in your case, to Python tutorials for beginners.

    Finally, if no further help is needed, remember to mark the thread as "SOLVED".

    Best, R



  • Hi,

    I know that regular expressions are a somewhat sensitive topic and can be overwhelming for beginners. But since the string shuffling shown here will produce produce false positives (e.g. "foo.bar"), I feel this is more than a question of "this is bad style and could lead to problems" and therefor should not be encouraged. Here is a regex you should use instead:

    import re
    
    # The regex to strip numeric affixes.
    RE_STRIP_NUMERIC_AFFIX = re.compile("(^\\S+)(\\.)(\\d+$)")
    
    # A little function that uses the regex.
    def strip_numeric_affix(item):
        """
        """
        match = RE_STRIP_NUMERIC_AFFIX.match(item)
        return match.group(1) if match else item
    
    # -- Test our regex ---------------------------------------------------------
    
    data = [
        # Valid candidates
        "foo.324",
        "foo_bar.1",
        "foo.bar.1",
        # Invalid candidates
        ".1",
        "foo.bar",
        "foo_bar.1 bar"
    ]
    
    for item in data:
        print "original: ", item
        print "stripped: ", strip_numeric_affix(item), "\n"
    
    original:  foo.324
    stripped:  foo 
    
    original:  foo_bar.1
    stripped:  foo_bar 
    
    original:  foo.bar.1
    stripped:  foo.bar 
    
    original:  .1
    stripped:  .1 
    
    original:  foo.bar
    stripped:  foo.bar 
    
    original:  foo_bar.1 bar
    stripped:  foo_bar.1 bar 
    [Finished in 0.1s]
    

    Cheers,
    zipit



  • Speaking of regular expressions, I find it often useful to utilize the "raw" notation for strings to avoid double-escape character sequences, which can add another layer of confusion:

    RE_STRIP_NUMERIC_AFFIX = re.compile(r"(^\S+)(\.)(\d+$)")



  • @Cairyn

    Noooooo, you have to make them as cryptic as possible ;) Jokes aside, you are absolutely right, this is adviseable.

    Cheers,
    zipit



  • PERFECT! Thank you very much. It's really a great helper. Back to good old times :-)

    Best,
    Peter


Log in to reply