Keyframing the source file on an ImageTexture shader
-
I have this Octane material with a ImageTexture shader.
I can programmatically set the source file on the shader.
I want to be able to Keyframe this source file.
Here's what I got so far:def changeTexture(shader, item, chosen, curTime) : doc = shader.GetDocument() doc.AddUndo(c4d.UNDOTYPE_CHANGE, shader) filepath = f'{item}_{chosen}.png' # Assign the new value print(f'Applying texture: {filepath}') print (shader[c4d.IMAGETEXTURE_FILE]) shader[c4d.IMAGETEXTURE_FILE] = filepath shader.Message(c4d.MSG_UPDATE) print(shader[c4d.IMAGETEXTURE_FILE]) track = shader.FindCTrack(c4d.IMAGETEXTURE_FILE) if not track: track = c4d.CTrack(shader, c4d.IMAGETEXTURE_FILE) shader.InsertTrackSorted(track) print(track) curve = track.GetCurve() result = curve.FindKey(curTime) if result is None: result = curve.AddKey(curTime) print(result) track.FillKey(doc, shader, result['key']) c4d.EventAdd()
This runs without bugs. The files do get changed but they're not keyframed. The first time I run this, the file keyframe indicator does show up orange. But not the subsequent times.
-
hi,
Your code is running fine with our regular bitmap shader and a standard material.
As you are using Octane i cannot check what is going on. What looks to be the issue is the DescID you are using to find the track or to create it
track = shader.FindCTrack(c4d.IMAGETEXTURE_FILE)
. You can learn a bit more about DescIDs in our c++ manual. DescID allow you to define the Type for a parameter. you are creating the Track without using the right type, which could be the issue.Below a code that is working as expected.
Cheers,
Manuelfrom typing import Optional import c4d doc: c4d.documents.BaseDocument # The active document op: Optional[c4d.BaseObject] # The active object, None if unselected def ChangeTexture(shader, item, chosen, curTime) : doc = shader.GetDocument() doc.AddUndo(c4d.UNDOTYPE_CHANGE, shader) filepath = f'{item}_{chosen}.png' # Assign the new value print(f'Applying texture: {filepath}') print (shader[c4d.BITMAPSHADER_FILENAME]) shader[c4d.BITMAPSHADER_FILENAME] = filepath shader.Message(c4d.MSG_UPDATE) print(shader[c4d.BITMAPSHADER_FILENAME]) track = shader.FindCTrack(c4d.BITMAPSHADER_FILENAME) if not track: track = c4d.CTrack(shader, c4d.BITMAPSHADER_FILENAME) shader.InsertTrackSorted(track) print(track) curve = track.GetCurve() result = curve.FindKey(curTime) if result is None: result = curve.AddKey(curTime) print(result) track.FillKey(doc, shader, result['key']) c4d.EventAdd() def main() -> None: # Creates a Standard C4D Material mat = c4d.Material() if mat is None: raise RuntimeError("Failed to create a new default material.") # Creates a bitmap shader sha = c4d.BaseList2D(c4d.Xbitmap) if sha is None: raise RuntimeError("Failed to create a bitmap shader.") # Defines the path of the bitmap shader sha[c4d.BITMAPSHADER_FILENAME] = "FileName" # Defines the material color shader to new created one. mat[c4d.MATERIAL_COLOR_SHADER] = sha # Inserts the shader into the material mat.InsertShader(sha) # Inserts a material in the active doc doc.InsertMaterial(mat) ChangeTexture(sha, 1, 2, doc.GetTime()) ChangeTexture(sha, 1, 4, doc.GetTime() + c4d.BaseTime(1)) # Pushes an update event to Cinema 4D c4d.EventAdd() """ def state(): # Defines the state of the command in a menu. Similar to CommandData.GetState. return c4d.CMD_ENABLED """ if __name__ == '__main__': main()
-
Hi,
A simple addition on CTrack and DescId as I was also faced to this a time ago. You can consult the @ferdinand's explanations and exemples on CTrack to the following post :
Cheers,
Christophe