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

    Creating a material and applying to BaseObject within Python Generator

    Cinema 4D SDK
    python
    2
    2
    1.2k
    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.
    • jenandesignJ
      jenandesign
      last edited by s_bach

      Hello, I did a search and couldn't find much to do with materials.

      My c4d version is R19

      I am creating a bunch of BaseObjects inside a Python Generator and trying to shade them in various ways- which requires me to create a new material for each BaseObject.

      I am successfully creating the Material instance (I think) by storing a new c4d.Material() into a new variable. However, when I run MakeTag(c4d.Ttexture) on the BaseObject and set the c4d.TEXTURETAG_MATERIAL parameter to my newly created material, it does not appear to take.

      Here is my code. It uses some modata from a linked matrix object to generate a series of discs / rings.

      import c4d
      from c4d.modules import mograph as mo
      #Welcome to the world of Python
      
      def main():
          link = op[c4d.ID_USERDATA,1]
          size = op[c4d.ID_USERDATA,2]
          roff = op[c4d.ID_USERDATA,3]
          
          md = mo.GeGetMoData(link)
          if md is None: return False
          
          null = c4d.BaseObject(c4d.Onull)
          
          cnt = md.GetCount()
          marr = md.GetArray(c4d.MODATA_MATRIX)
          carr = md.GetArray(c4d.MODATA_COLOR)
          for i in reversed(xrange(0, cnt)):
              
              mat = c4d.Material()
              mat.SetChannelState(c4d.CHANNEL_COLOR, True)
              mat[c4d.MATERIAL_COLOR_COLOR] = carr[i]
              
              disc1 = c4d.BaseObject(c4d.Odisc)
              disc1[c4d.PRIM_DISC_ORAD] = carr[i][0] * size
              disc1[c4d.PRIM_AXIS] = 4
              disc1.SetMg(marr[i])
              disc1.InsertUnder(null)
              
              disc2 = c4d.BaseObject(c4d.Odisc)
              disc2[c4d.PRIM_DISC_IRAD] = carr[i][0] * size
              disc2[c4d.PRIM_DISC_ORAD] = carr[i][0] * size * 1.2
              disc2[c4d.PRIM_AXIS] = 4
              moff = marr[i]
              moff.off = moff.off + (roff * carr[i][0])
              disc2.SetMg(marr[i])
              ttag =  disc2.MakeTag(c4d.Ttexture)
              ttag[c4d.TEXTURETAG_MATERIAL] = mat
              disc2.InsertUnder(null)
          
          return null
      

      Any ideas or suggestions are greatly appreciated! Thank you!

      1 Reply Last reply Reply Quote 0
      • S
        s_bach
        last edited by

        Hello,

        you cannot create a Material in the main() function of a Python Generator object.

        The main() function of the Python Generator object defines a cache of "virtual" BaseObjects which will appear in the scene.

        Materials cannot be created this way. A material must be inserted into the BaseDocument. This must only happen from the main thread, typically in reaction to some user interaction.

        One way of doing this would be to add a user data button to your Generator. Then your user could simply press that button to create the needed materials. Pressing the button can be detected by implementing the message() function.

        This could look like this:

        def main():
        
            # search for material
            mat = doc.SearchMaterial("Generator Material")
        
            if mat is None:
                return None
        
            # create object
            cube = c4d.BaseObject(c4d.Ocube)
            
            # apply material
            ttag =  cube.MakeTag(c4d.Ttexture)
            ttag[c4d.TEXTURETAG_MATERIAL] = mat
        
            return cube
        
        def message(id, data):
            if id == c4d.MSG_DESCRIPTION_COMMAND:
                buttonId = data['id']
        
                # check button ID
                if buttonId[1].id == 1:
                    
                    # create material and insert it into the host document
                    c4d.StopAllThreads()
        
                    material = c4d.Material()
                    material.SetName("Generator Material")
                    material[c4d.MATERIAL_COLOR_COLOR] = c4d.Vector(1,0,0)
        
                    doc.InsertMaterial(material, None)
        
                    c4d.EventAdd()
        

        Also, please use the Q&A system.

        best wishes,
        Sebastian

        MAXON SDK Specialist

        Development Blog, MAXON Registered Developer

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