Jump to content

Sign in to follow this  
Myosis

Removing empty selection tags

Recommended Posts

Good, you found the solution already. Don't forget to create a startUndo/EndUndo bracket around the whole code.

Share this post


Link to post
Share on other sites

  • Topic Author
  • I'm now trying the same for texture tags
    I would like to remove them if there are no longer bound to an active selection tag.

    So I'm running along each tag looking for [c4d.TEXTURETAG_RESTRICTION]
    And if it contains the name of any active selection tag [c4d.ID_BASELIST_NAME]

    Code here:

    import c4d
    
    def iter_hierarchy(op):
    
        for tag in op.GetTags():
    
            t = op.GetFirstTag()
            
            while t:
                if t.GetType() == c4d.Tpolygonselection:
                    tagselection  =  t.GetBaseSelect()
                    name = t[c4d.ID_BASELIST_NAME]
                    print name
                          
                    if tag.CheckType(c4d.Ttexture):
                        texname = tag[c4d.TEXTURETAG_RESTRICTION]
                        if not name in texname:
                            doc.AddUndo(c4d.UNDOTYPE_DELETE, tag)
                            tag.Remove()
                        
                t = t.GetNext()
                print 'run new tag'
                
        for child in op.GetChildren():
            iter_hierarchy(child)
    
    def main():
    
        for op in doc.GetObjects():
            iter_hierarchy(op)
    
        c4d.EventAdd()
    
    main()

    If anyone can see the flaw, it would be the final piece to the puzzle for me!

    My guess is that I'm doing something wrong in the texture tag restriction ?


     

    Share this post


    Link to post
    Share on other sites
    46 minutes ago, Myosis said:

    If anyone can see the flaw, it would be the final piece to the puzzle for me!

    I'm not sure what you want to achieve? You are nesting two loops over the same tag set?

    If there are no selection tags at all, your check will never come to pass because it is nested inside the test for the selection tag.

    If you have two or more selection tags, the inner test will always become true and always remove the texture tag, because there is always ONE polygon selection for which the condition is true (you loop over all of them - essentially, you ask the system to remove the texture tag if not ALL the polygon selections that are there describe this texture tag's selection).

    You test the name of the selection tag against the texture tag's selection with an "in" condition instead of "=="? That means "Polygon" fits "Polygon Tag", as "in" checks for partial strings.

    And what is about auto-selections like C1, R2 or the likes?

     

    If your intent is just to remove texture tags with no selection assigned, your test would be something like "if texname is None or texname == "":" so it just checks whether this field is empty. You wouldn't even need a loop over the selection tags.

    Looping the selection tags just ensures that the used selection string actually matches with one selection, is that what you want? Texture tags that have no selection (and therefore apply to the whole object) would be removed too, then.

     

    Just trying to get your actual condition...

     

    Share this post


    Link to post
    Share on other sites
  • Topic Author
  • Once I cleared all empty selection tags, I'm left with 1 selection tag on each model, but I'm also I'm left with a bunch of texture tags.

    I want to remove all texture tags that are no longer referring to existing selection tags.
    But most of the texture tags still have a name in their selection "c4d.TEXTURETAG_RESTRICTION" (but that selection tag no longer exist). So I don't think I can use None in this case.
    My thought was to compare the names of each tag and remove if is doesn't match 

     

    If I change the if not to, just if the scripts works reversed, I now remove all texture tags that are referring to existing selection tags. Hence the reason I tried if not, or else: but they both don't seem to be the solution.

     

    I hope I was able to explain myself clearly😓

    Share this post


    Link to post
    Share on other sites
    1 hour ago, Myosis said:

    Once I cleared all empty selection tags, I'm left with 1 selection tag on each model, but I'm also I'm left with a bunch of texture tags.

     

    I see. Okay, your general logic is flawed - go through a simple example with 2 sel tags and 2 mat tags manually and you will see why it's deleting everything.

     

    Here is a working version:
     

    import c4d
    from c4d import gui
    
    def iter_hierarchy(op):
    
        # outer loop over the texture(!) tags
        for texturetag in op.GetTags():
            if texturetag.CheckType(c4d.Ttexture):
                texturename = texturetag[c4d.TEXTURETAG_RESTRICTION]
                # this name must be referred to by some selection,
                # otherwise apparently the selection tag has been
                # removed and the texture has no effect
    
                found = False # Default: No such selection
                # check all selections whether texturename is
                # referenced. If yes, we remember that find.
                for selectiontag in op.GetTags(): # get the newest tag list
                    if selectiontag.CheckType(c4d.Tpolygonselection):
                        refname = selectiontag[c4d.ID_BASELIST_NAME]
                        if refname == texturename:
                            found = True
                            print "Reference ", refname, " has been found!"
                            break
                            
                if not found:
                    print "Texture tag ", texturetag.GetName(), " is not referenced!"
                    doc.AddUndo(c4d.UNDOTYPE_DELETE, texturetag)
                    texturetag.Remove()
                            
        for child in op.GetChildren():
            iter_hierarchy(child)
    
    
    def main():
        doc.StartUndo()
    
        for op in doc.GetObjects():
            iter_hierarchy(op)
        doc.EndUndo()
    
        c4d.EventAdd()
    
    # Execute main()
    if __name__=='__main__':
        main()
    

    Note that I swapped the nesting of the loops.

    First, I go through the tag list and look for all texture tags.

    Then, for each such tag, I go through the list of tags again, and search for all selection tags.

    If I find any one selection tag that is mentioned in the texture tag, I remember that in the variable "found".

    After the loop ends, found is either False (when no selection tag has been found that is referenced in the texture), in which case I delete the texture tag.

    Or found is True, in which case there IS a selection tag, so I don't need to do anything.

     

    The main difference between your version and mine is that your version deletes immediately in the innermost loop, which does not work as the condition goes over ALL the selection tags. In my version, I delay the deletion decision until I have the aggregate information assembled.

     

    Also, I added the StartUndo and EndUndo bracket.

     

    Share this post


    Link to post
    Share on other sites
  • Topic Author
  • @Cairyn

     

    Spent some time comparing the two and learned a bunch. I can see that I was pretty far-off.
    For some reason I thought I had to look at them individually. Your code makes a lot more sense, and works like a charm!

     

    I cannot thank you enough for helping me out with this, so I might give your patreon a try 😉
    Thank you🙏
     

    Share this post


    Link to post
    Share on other sites

    Join the conversation

    You can post now and register later. If you have an account, sign in now to post with your account.

    Guest
    Reply to this topic...

    ×   Pasted as rich text.   Paste as plain text instead

      Only 75 emoji are allowed.

    ×   Your link has been automatically embedded.   Display as a link instead

    ×   Your previous content has been restored.   Clear editor

    ×   You cannot paste images directly. Upload or insert images from URL.

    Sign in to follow this  

    • Recently Browsing   0 members

      No registered users viewing this page.

    ×
    ×
    • Create New...