TextureTag Hangs On To Deleted Material?



  • On 11/06/2016 at 12:40, xxxxxxxx wrote:

    Hi,
    Is there a way to check if a texture tag is pointing to a deleted material?
    If you delete the material. The texture tag still thinks it's there for some strange reason.

    I did find a way to do it in Evil Mad Scientist mode. 😈
    But is there an "official" way to do this?

    #When deleting the material. The tag does not automatically update it's container to reflect that!! Why!!??  
    #This example checks if the texture tag has a material assigned to it by looking at the icon's coordinates  
    #If the icon values are not 0 & 0. Then there is no material assigned to the texture tag  
      
    import c4d  
    def main() :  
        
      texTag = op.GetTag(c4d.Ttexture)  
      
      #Get the icon on the tag to see if it's coords are used to display the X icon(no material)  
      icon = texTag.GetIcon()  
      iconX = icon['x']  
      iconY = icon['y']      
      #print iconX, "  ", iconY  
        
      #1010 is the id in the texture tag's container that links to it's material(if any)  
      #But it does not reset itself to None if the user deletes the material! why??   
      #This code resets the tag's material container entry to be None. And sets the name value to "None"  
      bc = texTag.GetData()  
      if iconX != 0 and iconY != 0:   
          bc[1010] = None  
          mat = texTag.GetMaterial() #<--Technically this should be null. But the tag hangs on to the deleted material's name!!!  
          mat.SetName("None")  
      
      #Prints the material's name if there is a material assigned to the texture tag  
      #Or None. If the material was deleted  
      print texTag.GetMaterial().GetName()  
            
      c4d.EventAdd()  
      
    if __name__=='__main__':  
      main()
    

    -ScottA



  • On 11/06/2016 at 13:08, xxxxxxxx wrote:

    D'oh. Never mind.
    I think I found the official way that most people use:
      print texTag[c4d.TEXTURETAG_MATERIAL]

    This does not change the tag's container. So it's still pointing to the deleted material.
    But that doesn't really matter. And it is a simple way to check for a None material scenario. And that's all I really needed.

    Plus. I found a better way to check the texture tag's material link entry
    This one does return None if the material is deleted.

    import c4d  
    def main() :  
        
      ttag = op.GetTag(c4d.Ttexture)      
      bc = ttag.GetData()          
      link = bc.GetMaterialLink(1010, doc)      
      print link  
        
      c4d.EventAdd()  
      
    if __name__=='__main__':  
      main()
    

    -ScottA



  • On 13/06/2016 at 04:50, xxxxxxxx wrote:

    Hi Scott,

    while you seem to have found a solution yourself, I'd still like to take the chance to discuss some things in your first code snippet:

    First of all, I think, you have a valid point here. TextureTag.GetMaterial() indeed does not behave the way I had expected it in this situation. Actually you are being returned the Material that's still existing in the Undo Buffer. Your code then renames it, you can check this by simply deleting a material, then call your script and undo the deletion. We will still need to discuss this behavior internally.

    Then you try to change the link in the TextureTag's BaseContainer to None. The thing is, you aren't changing anything. With texTag.GetData() you retrieve a copy of the tag's BaseContainer. So changing anything in this BaseContainer won't do anything, until you either write the container back into the tag or (more preferable) use GetDataInstance() instead. By this you get a reference to the tag's actual BaseContainer and can change it directly (and GetDataInstance() is quicker, as no data needs to be copied).

    Lastly there are a bunch of None checks missing. I know, this probably just some experimental code, just mentioning it, in case somebody is copying code from this thread.



  • On 13/06/2016 at 07:34, xxxxxxxx wrote:

    Thanks for the feedback Andreas.
    I know my first example is pretty crazy. It was just a wild hack to force it to do my bidding until I found a better solution.

    I was pretty surprised at how GetMaterial() hangs onto the deleted material too.
    That seems wrong to me. But the person who wrote it might have some reason for it to be that way.

    -ScottA



  • On 13/06/2016 at 07:57, xxxxxxxx wrote:

    The point is in C++ GetMaterial() has a ignoredocs parameter, which determines how the material link will be evaluated. In Python this was always set true, so the link always gets evaluated over document barriers. In the upcoming fix, the function will have an optional ignoredocs parameter as well. It will default to true though (in contrast to C++), to keep compatibility with old code.



  • On 13/06/2016 at 08:12, xxxxxxxx wrote:

    OK. Thanks.

    -ScottA


Log in to reply