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

    The layer material ID is the same as the node material ID.

    General Talk
    r21 python
    4
    8
    1.3k
    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.
    • X
      x_nerve
      last edited by x_nerve

      Hi:
      I'm a beginner in Python, and I've had a problem for a long time, because the material ID is the same, and some of the functionality doesn't work. When can the ID be updated?

      1 Reply Last reply Reply Quote 0
      • ferdinandF
        ferdinand
        last edited by

        Hi,

        I am not quite sure what you are talking about. I never dabbled with the new node based materials in Python, but I somehow doubt that they have the same ID as Cinema's standard material (which would be c4d.Mmaterial), as Cinema otherwise would not be able to distinguish between these two. What are you referring to with "(material) ID"?

        Also noteworthy is that the node based materials require a special interface to do anything useful. Afaik, this interface has not been exposed to Python yet, so you won't really be able to do anything meaningful, unless you find an unofficial way to modify such a material.

        Cheers,
        zipit

        MAXON SDK Specialist
        developers.maxon.net

        1 Reply Last reply Reply Quote 0
        • X
          x_nerve
          last edited by x_nerve

          Thank you for your reply. I know that the third party renderer has opened the Python interface. Sorry to interrupt. Thanks again for your reply.The screenshot is as follows:

          Material_picture.jpg

          1 Reply Last reply Reply Quote 0
          • ferdinandF
            ferdinand
            last edited by

            Hm,

            that is weird, 5703 is the ID Mmaterial. As you can see here, while both Material and NodeMaterial inherit from BaseMaterial, NodeMaterial does not inherit from Material. So this is either some sort of dummy Mmaterial node for the old material editor, or this has to do with the fact, that NodeMaterial has not been exposed to Python yet.

            If you are really hellbent on determining if a Mmaterial node is actually a node material or not, you could look at their description, as they are obviously not the same. But be aware that materials can have dynamically generated elements in their description. So just comparing the lengths or looking for a specific length is probably a very unreliable method. You probably want to look for the presence of a certain parameter/attribute.

            import c4d
            
            def main():
                """
                """
                # Get the first material.
                material = doc.GetFirstMaterial()
                if not isinstance(material, c4d.BaseMaterial):
                    raise ValueError("No material found.")
            
                # Loop over all materials.
                while material:
                    # Get the description of the current material.
                    description = material.GetDescription(0)
                    # The number of elements in that description.
                    parameter_count = len(list(description))
                    print material, parameter_count
                    material = material.GetNext()
            
            if __name__ == "__main__":
                main()
            

            Which will print for some node and some true Mmaterial materials something like this:

            <c4d.Material object called 'Mat/Mat' with ID 5703 at 0x00000178FA08FEF0> 267
            <c4d.Material object called 'Mat/Mat' with ID 5703 at 0x00000178FA08F690> 267
            <c4d.Material object called 'Node/Mat' with ID 5703 at 0x00000178FA08F0B0> 278
            <c4d.Material object called 'Node/Mat' with ID 5703 at 0x00000178FA08FEF0> 278
            <c4d.Material object called 'Mat/Mat' with ID 5703 at 0x00000178FA08F690> 267
            

            Cheers,
            zipit

            MAXON SDK Specialist
            developers.maxon.net

            1 Reply Last reply Reply Quote 0
            • X
              x_nerve
              last edited by x_nerve

              Thank you for your patience, but I really want to implement the following function: automatically create the material ball and sky objects to reduce the workload.But the standard material and node material have the same ID, which is difficult to implement in a normal way.Thank you again for your patient reply.

              Here is the Arnold renderer script code:

              import c4d
              
              def main():
                  #Select active objects.
                  objects = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_CHILDREN)
                  if not objects :
                     raise ValueError("No objects selected.")
              
                  doc.StartUndo()
                  
                  for obj in objects:
                      
                      #Collect texture tags.
                      Tags = obj.GetTags()
                      TextureTag = [TagList for TagList in Tags if TagList.GetRealType() == 5616]
              
                      #Delet blank texture tag.
                      if TextureTag != 0:
                          for Blank in TextureTag:
                              if Blank[c4d.TEXTURETAG_MATERIAL] == None:
                                  doc.AddUndo(c4d.UNDOTYPE_CHANGE,Blank)
                                  Blank.Remove()
              
                      #Add an arnold texture ball and texture tag to each active object.
                      arnold = c4d.BaseMaterial(1033991)
                      Tag = c4d.BaseTag(5616)
                      Tag[c4d.TEXTURETAG_MATERIAL] = arnold
                      doc.InsertMaterial(arnold)
                      obj.InsertTag(Tag)
              
                  #Create the arnold sky object.
                  Sky = c4d.BaseObject(1034624)
                  doc.InsertObject(Sky)
                  
                  doc.EndUndo()
                  c4d.EventAdd()
              
              if __name__ == "__main__":
                  main()
              
              1 Reply Last reply Reply Quote 0
              • ferdinandF
                ferdinand
                last edited by

                Hi,

                as I said: The node space has not been exposed to Python yet. You cannot create, modify or even just access NodeMaterial materials in Python. So would either have to use C++ or just another material system.

                Cheers,
                zipit

                MAXON SDK Specialist
                developers.maxon.net

                1 Reply Last reply Reply Quote 0
                • M
                  m_adam
                  last edited by m_adam

                  Hi in C++ there is the BaseList2D.IsNodeBased method to check if a BaseList2D contains nodes and more interesting there is the NodeMaterial class that represents a Nodal Material, unfortunately, both are not available in Python.
                  Note also that any type of material can be evaluated to a NodeMaterial and this will add the MaterialData the ability to use NodeGraph.

                  So I confirm the only reliable way in Python to know if a material is a NodeBased one is to check the description.

                  If you want to explicitly create a NodeBaseMaterial the only way for you do to do so is via CallCommand with

                  c4d.CallCommand(202541) # New Node Material
                  

                  Cheers,
                  Maxime.

                  EDIT: BaseList2D.IsNodeBased was added to Python in R24.

                  MAXON SDK Specialist

                  Development Blog, MAXON Registered Developer

                  1 Reply Last reply Reply Quote 0
                  • indexofrefractionI
                    indexofrefraction
                    last edited by indexofrefraction

                    I also just ran into this...
                    < R24 you dont have BaseList2D.IsNodeBased, but as a small hack you can do:

                    def isNodeMaterial(op):
                      return True if op.GetType == c4d.Mmaterial and '[Node]' in op.GetBubbleHelp() else False
                    
                    1 Reply Last reply Reply Quote 1
                    • First post
                      Last post