Solved Copy Material with Current State to Object

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)

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

Thanks, zipit, much appreciated. :)

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.

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

Got it. Thanks, again, zipit for you answer. :)