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
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    C4D octane materials to redshift.

    Cinema 4D SDK
    python project tool
    3
    4
    2.5k
    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.
    • M
      m0d.design
      last edited by

      I am fairly new to python here and am trying to make a script to convert octane materials to redshift in C4D. I am however currently unsuccessful. I am using cinema 4D 2023.2.0 and the most recent release of redshift. For octane i am using 2022.1-R7. Any help would be really appreciated. Not sure if its just my IDs are wrong and the ones i'm getting aren't right or maybe the code is wrong too.

      Current console output with script

      Traceback (most recent call last):
        File "scriptmanager", line 93, in <module>
        File "scriptmanager", line 85, in main
        File "scriptmanager", line 53, in convert_octane_to_redshift
      BaseException: could not allocate 'c4d.BaseMaterial (ID 1036219)' instance
      

      Current version of the script

      import c4d
      from c4d import documents
      from c4d import utils
      from c4d import bitmaps
      
      ID_OCTANE_MATERIAL = 1029501
      ID_OCTANE_IMAGE_TEXTURE = 1029508
      ID_OCTANE_COLORCORRECTION = 1029512
      ID_OCTANE_INVERT_TEXTURE = 1029514
      ID_OCTANE_MULTIPLY_TEXTURE = 1029516
      ID_OCTANE_MIXTEXTURE = 1029505
      mainLayerId = 526336
      
      ID_REDSHIFT_MATERIAL = 1036219
      ID_REDSHIFT_IMAGE = 1039749
      ID_REDSHIFT_COLOR_SPLITTER = 1040084
      
      def GetTexture(doc, oct_mat, channel):
          if not oct_mat.IsInstanceOf(ID_OCTANE_MATERIAL):
              return None
      
          image_name = None
          image_shader = oct_mat[channel]
          if image_shader:
              shader_type = image_shader.GetType()
      
              if shader_type == ID_OCTANE_MULTIPLY_TEXTURE:
                  image_shader = image_shader[c4d.MULTIPLY_TEXTURE1]
                  if image_shader:
                      shader_type = image_shader.GetType()
      
              if shader_type == ID_OCTANE_MIXTEXTURE:
                  image_shader = image_shader[c4d.MIXTEX_TEXTURE1_LNK]
                  if image_shader:
                      shader_type = image_shader.GetType()
      
              if shader_type == ID_OCTANE_COLORCORRECTION:
                  image_shader = image_shader[c4d.COLORCOR_TEXTURE_LNK]
                  if image_shader:
                      shader_type = image_shader.GetType()
      
              if shader_type == ID_OCTANE_INVERT_TEXTURE:
                  image_shader = image_shader[c4d.INVERT_TEXTURE]
                  if image_shader:
                      shader_type = image_shader.GetType()
      
              if shader_type == ID_OCTANE_IMAGE_TEXTURE:
                  image_name = image_shader[c4d.IMAGETEXTURE_FILE]
                  print(image_name)
          return image_name
      
      def convert_octane_to_redshift(doc, octane_material):
          redshift_material = c4d.BaseMaterial(ID_REDSHIFT_MATERIAL)
          if not redshift_material:
              raise BaseException("could not allocate 'c4d.BaseMaterial (ID 1036219)' instance")
      
          redshift_material.SetName(octane_material.GetName())
          doc.InsertMaterial(redshift_material)
      
          diff_file = GetTexture(doc, octane_material, c4d.OCT_MATERIAL_DIFFUSE_LINK)
          if diff_file:
              diff_bitmap = bitmaps.BaseBitmap()
              diff_bitmap.InitWith(diff_file)
              diff_image = utils.BitmapToRSBitmap(diff_bitmap)
              if diff_image:
                  diff_shader = c4d.BaseShader(ID_REDSHIFT_IMAGE)
                  diff_shader[c4d.REDSHIFT_SHADER_IMAGE] = diff_image
                  redshift_material[c4d.REDSHIFT_SHADER_MATERIAL_DIFFUSE_COLOR] = diff_shader
                  redshift_material.InsertShader(diff_shader)
      
                  color_splitter = c4d.BaseShader(ID_REDSHIFT_COLOR_SPLITTER)
                  color_splitter[c4d.REDSHIFT_SHADER_COLOR_SPLITTER_INPUT] = diff_shader
                  redshift_material[c4d.REDSHIFT_SHADER_MATERIAL_OPACITY_COLOR] = color_splitter
                  redshift_material.InsertShader(color_splitter)
      
          return redshift_material
      
      def main():
          doc = documents.GetActiveDocument()
          selected_materials = doc.GetActiveMaterials()
      
          for mat in selected_materials:
              if mat.IsInstanceOf(ID_OCTANE_MATERIAL):
                  doc.StartUndo()
                  new_rs_mat = convert_octane_to_redshift(doc, mat)
                  doc.AddUndo(c4d.UNDOTYPE_NEW, new_rs_mat)
                  doc.AddUndo(c4d.UNDOTYPE_DELETE, mat)
                  doc.RemoveMaterial(mat)
                  doc.EndUndo()
                  c4d.EventAdd()
      
      if __name__ == '__main__':
          main()
      
      
      1 Reply Last reply Reply Quote 0
      • M
        m_adam
        last edited by

        Hi @m0d-design out of curiosity is this coming from chat GPT?

        There is multiple thing wrong in your code, first of all we can't help you with the octane API, so to retrieve the data from an octane material please contact otoy directly. To create a redshift material you can find an example in Create a RS Standard Material with a Texture node connected to the Color and also wired up to a color splitter that it is connected to the opacity..

        Cheers,
        Maxime.

        MAXON SDK Specialist

        Development Blog, MAXON Registered Developer

        1 Reply Last reply Reply Quote 0
        • M
          m0d.design
          last edited by

          It is, ive been hand holding gpt while it structures it. Of course its out of date though unfortunately. It struggles the most with redshift scripts, for some reason it doesn't properly know how to create a material. I did some digging and found that post you shared before posting here to try and use it. However im not skilled enough yet in python or in the knowledge of the plugins to that extent to structure it myself. GPT and I did manage to make a working conversion script for octane to C4D native materials though with some lengthy troubleshooting. Don't know if this would help with the current topic at hand at all. But either way I appreciate the reply.

          import c4d
          from c4d import documents
          
          ID_OCTANE_MATERIAL = 1029501
          ID_OCTANE_IMAGE_TEXTURE = 1029508
          ID_OCTANE_COLORCORRECTION = 1029512
          ID_OCTANE_INVERT_TEXTURE = 1029514
          ID_OCTANE_MULTIPLY_TEXTURE = 1029516
          ID_OCTANE_MIXTEXTURE = 1029505
          mainLayerId = 526336
          
          
          def CheckSelection(doc, mats):
              oct_mats = []
              if mats:
                  count = len(mats)
                  for i in range(count):
                      if mats[i].GetType() == ID_OCTANE_MATERIAL:
                          oct_mats.append(mats[i])
              return oct_mats
          
          def GetTexture(doc, oct_mat, channel):
              image_name = None
              image_shader = oct_mat[channel]
              if image_shader:
                  shader_type = image_shader.GetType()
          
                  if shader_type == ID_OCTANE_MULTIPLY_TEXTURE:
                      image_shader = image_shader[c4d.MULTIPLY_TEXTURE1]
                      if image_shader:
                          shader_type = image_shader.GetType()
          
                  if shader_type == ID_OCTANE_MIXTEXTURE:
                      image_shader = image_shader[c4d.MIXTEX_TEXTURE1_LNK]
                      if image_shader:
                          shader_type = image_shader.GetType()
          
                  if shader_type == ID_OCTANE_COLORCORRECTION:
                      image_shader = image_shader[c4d.COLORCOR_TEXTURE_LNK]
                      if image_shader:
                          shader_type = image_shader.GetType()
          
                  if shader_type == ID_OCTANE_INVERT_TEXTURE:
                      image_shader = image_shader[c4d.INVERT_TEXTURE]
                      if image_shader:
                          shader_type = image_shader.GetType()
          
                  if shader_type == ID_OCTANE_IMAGE_TEXTURE:
                      image_name = image_shader[c4d.IMAGETEXTURE_FILE]
                      print(image_name)
              return image_name
          
          def ReAssign(doc, oct_mat, c4d_mat):
              obj_link = oct_mat[c4d.ID_MATERIALASSIGNMENTS]
              link_count = obj_link.GetObjectCount()
              for i in range(link_count):
                  tex_tag = obj_link.ObjectFromIndex(doc, i)
                  doc.AddUndo(c4d.UNDOTYPE_CHANGE, tex_tag)
                  tex_tag[c4d.TEXTURETAG_MATERIAL] = c4d_mat
                  tex_tag.Message(c4d.MSG_CHANGE)
          
          def RebuildMats(doc, oct_mats):
              c4d_mats = []
              count = len(oct_mats)
              for i in range(count):
                  oct_mat = oct_mats[i]
                  c4d_mat = c4d.BaseMaterial(c4d.Mmaterial)
                  name = oct_mat[c4d.ID_BASELIST_NAME]
                  c4d_mat[c4d.ID_BASELIST_NAME] = name
          
                  diff_file = GetTexture(doc, oct_mat, c4d.OCT_MATERIAL_DIFFUSE_LINK)
                  if diff_file:
                      diff_shader = c4d.BaseShader(c4d.Xbitmap)
                      diff_shader[c4d.BITMAPSHADER_FILENAME] = diff_file
                      c4d_mat[c4d.MATERIAL_COLOR_SHADER] = diff_shader
                      c4d_mat.InsertShader(diff_shader)
          
                  opac_file = GetTexture(doc, oct_mat, c4d.OCT_MATERIAL_OPACITY_LINK)
                  if opac_file:
                      opac_shader = c4d.BaseShader(c4d.Xbitmap)
                      opac_shader[c4d.BITMAPSHADER_FILENAME] = opac_file
                      c4d_mat[c4d.MATERIAL_ALPHA_SHADER] = opac_shader
                      c4d_mat.InsertShader(opac_shader)
                      c4d_mat[c4d.MATERIAL_USE_ALPHA] = True
          
          
                  normal_file = GetTexture(doc, oct_mat, c4d.OCT_MATERIAL_NORMAL_LINK)
                  if normal_file:
                      normal_shader = c4d.BaseShader(c4d.Xbitmap)
                      normal_shader[c4d.BITMAPSHADER_FILENAME] = normal_file
                      c4d_mat[c4d.MATERIAL_NORMAL_SHADER] = normal_shader
                      c4d_mat.InsertShader(normal_shader)
                      c4d_mat[c4d.MATERIAL_USE_NORMAL] = True
          
                  bump_file = GetTexture(doc, oct_mat, c4d.OCT_MATERIAL_BUMP_LINK)
                  if bump_file:
                      bump_shader = c4d.BaseShader(c4d.Xbitmap)
                      bump_shader[c4d.BITMAPSHADER_FILENAME] = bump_file
                      c4d_mat[c4d.MATERIAL_BUMP_SHADER] = bump_shader
                      c4d_mat.InsertShader(bump_shader)
                      c4d_mat[c4d.MATERIAL_USE_BUMP] = True
          
                  rough_file = GetTexture(doc, oct_mat, c4d.OCT_MATERIAL_ROUGHNESS_LINK)
                  if rough_file:
                      rough_shader = c4d.BaseShader(c4d.Xbitmap)
                      rough_shader[c4d.BITMAPSHADER_FILENAME] = rough_file
                      c4d_mat[c4d.MATERIAL_USE_REFLECTION] = True
                      c4d_mat[mainLayerId + c4d.REFLECTION_LAYER_MAIN_DISTRIBUTION] = 2
                      c4d_mat[mainLayerId + c4d.REFLECTION_LAYER_MAIN_SHADER_ROUGHNESS] = rough_shader
                      c4d_mat.InsertShader(rough_shader)
          
                  ReAssign(doc, oct_mat, c4d_mat)
          
                  c4d_mats.append(c4d_mat)
                  doc.InsertMaterial(c4d_mat)
                  doc.AddUndo(c4d.UNDOTYPE_NEW, c4d_mat)
          
              return
          
          
          def main():
              my_doc = documents.GetActiveDocument()
              my_mats = my_doc.GetActiveMaterials()
              my_oct_mats = CheckSelection(my_doc, my_mats)
          
              if my_oct_mats:
                  doc.StartUndo()
                  RebuildMats(my_doc, my_oct_mats)
                  doc.EndUndo()
                  c4d.EventAdd()
          
          
          if __name__ == '__main__':
              main()
          
          
          1 Reply Last reply Reply Quote 0
          • S
            Smolak
            last edited by

            Unfortunately this script doesn't include Specular and Displacement channels conversion.

            Architectural Visualizations - www.archviz-4d.studio

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