Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware 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

    Copy Material with Current State to Object

    Cinema 4D SDK
    python
    3
    5
    762
    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.
    • SwinnS
      Swinn
      last edited by Manuel

      Is there a way to copy the material associated with the texture tag when I use Current State to Object? Is there a line I can add to my code? I need the new geometry to have its own material that is separate from the original object's material. Thanks.

      # Current State to Object
              return_value = c4d.utils.SendModelingCommand(
                              command = c4d.MCOMMAND_CURRENTSTATETOOBJECT,
                              list = [doc.SearchObject("S" + str (item))],
                              mode = c4d.MODELINGCOMMANDMODE_ALL,
                              bc = settings,
                              doc = doc)
      
      1 Reply Last reply Reply Quote 0
      • ferdinandF
        ferdinand
        last edited by ferdinand

        Hi,

        at least I am not aware of any functionality of CSO in this regard. I also do not think that Cinema has such a function at all (but I might be wrong about this). You will have to clone your materials manually and relink them. Something like the following:

        import c4d
        
        def clone_and_relink_materials(node):
            """Clones all unique materials assigned to an object and sets the links to the the cloned materials in the respective material tags.
        
            Args:
                node (``c4d.BaseObject``): The object to clone the materials for.
            
            Returns:
                tuple[bool, list[c4d.BaseMaterial]]: If the cloning has been successful and the cloned materials.
            """
            # Get out if node is not a BaseObject.
            if not isinstance(node, c4d.BaseObject):
                return False, []
        
            # A hashmap for the materials and the document the node is attached to.
            clones = {}
            doc = node.GetDocument()
            # Go over all tags of the object.
            for tag in node.GetTags():
                # Step over non-material tags and material tags that do not have a
                # material.
                if not tag.CheckType(c4d.Ttexture):
                    continue
                elif tag[c4d.TEXTURETAG_MATERIAL] is None:
                    continue
        
                # Get the material and hash it, so that we can keep track of which
                # material has been cloned and which not (in case there are multiple
                # material tags referencing the same material).
                material = tag[c4d.TEXTURETAG_MATERIAL]
                nid = material.FindUniqueID(c4d.MAXON_CREATOR_ID)
                # This a newly encountered material (in this object)
                if nid not in clones:
                    # Clone the material, change its name and insert it into the
                    # document.
                    clone = material.GetClone(c4d.COPYFLAGS_NONE)
                    clone.SetName(clone.GetName() + "_clone")
                    doc.InsertMaterial(clone)
                    clones[nid] = clone
                # Get the cloned material for the material referenced in the
                # material tag and set the reference in the material tag to the
                # clone.
                tag[c4d.TEXTURETAG_MATERIAL] = clones[nid]
                tag.Message(c4d.MSG_UPDATE)
            return True, clones.values()
                
        def main():
            success, materials = clone_and_relink_materials(op)
            print "success:", success
            print "cloned materials:", materials
            c4d.EventAdd()
        
        if __name__=='__main__':
            main()
        

        Note that this solution is not material-tag agnostic, i.e. will not work in any environment that does not rely on Ttexture tags to assign materials to an object.

        Cheers,
        zipit

        MAXON SDK Specialist
        developers.maxon.net

        1 Reply Last reply Reply Quote 1
        • SwinnS
          Swinn
          last edited by

          Thanks, zipit, much appreciated. 🙂

          1 Reply Last reply Reply Quote 0
          • ManuelM
            Manuel
            last edited by

            Hello,

            For your next threads, please help us keeping things organised and clean. I know it's not your priority but it really simplify our work here.

            • Q&A New Functionality.
            • How to Post Questions especially the tagging part.

            I've added the tags and marked this thread as a question so when you considered it as solved, please change the state 🙂

            Nothing more to add, thanks @zipit for you answer 🙂

            Cheers,
            Manuel

            MAXON SDK Specialist

            MAXON Registered Developer

            1 Reply Last reply Reply Quote 0
            • SwinnS
              Swinn
              last edited by

              Got it. Thanks, again, zipit for you answer. 🙂

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