Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    TextureTag Hangs On To Deleted Material?

    Scheduled Pinned Locked Moved PYTHON Development
    6 Posts 0 Posters 547 Views
    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.
    • H Offline
      Helper
      last edited by

      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

      1 Reply Last reply Reply Quote 0
      • H Offline
        Helper
        last edited by

        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

        1 Reply Last reply Reply Quote 0
        • H Offline
          Helper
          last edited by

          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.

          1 Reply Last reply Reply Quote 0
          • H Offline
            Helper
            last edited by

            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

            1 Reply Last reply Reply Quote 0
            • H Offline
              Helper
              last edited by

              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.

              1 Reply Last reply Reply Quote 0
              • H Offline
                Helper
                last edited by

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

                OK. Thanks.

                -ScottA

                1 Reply Last reply Reply Quote 0
                • First post
                  Last post