C4D octane materials to redshift.
-
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()
-
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. -
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()
-
Unfortunately this script doesn't include Specular and Displacement channels conversion.