Auto load folder of images to material [SOLVED]
-
On 29/05/2015 at 12:24, xxxxxxxx wrote:
Hi everyone!
I don't know python at all but I'm trying to figure out how to automate part of a process for a job I'm working on.
My goal is to load images from the "tex" folder into the color channel of the material on my object, keyframe it, move to the next image, then next frame, keyframe, etc., until all images in that folder have a keyframe on the same material. I've been doing it by hand for this job for folders with 160 images and making mistakes, and now the job requires me to do that for folders much larger! ARgh!
I know you can use the animate function on a material to pull a folder of images but it doesn't import the image path nor does it create an actual keyframe which I need for my project to work correctly.
I've been pulling python code from various places and trying to toy around and get something to work but I just lack the knowledge and experience. Had I more time I could maybe flesh it out but as I don't have a ton of time I am turning to you
I found this code that loads an image from the desk top. It seems to work but I can't seem to change the path to, say, the tex folder in my job....but on top of that I need it to do more.
import c4d
import osdef main() :
fn = c4d.storage.GeGetC4DPath(c4d.C4D_PATH_DESKTOP) #Gets the desktop path
pathToTexture = os.path.join(fn,'01.jpg') #Gets the specific texture image on your desktopmat = doc.GetActiveMaterial() #Assign the active material a variable
shdr_texture = c4d.BaseList2D(c4d.Xbitmap) #Create a bitmap shader in memory
shdr_texture[c4d.BITMAPSHADER_FILENAME] = pathToTexture #Assign the path to the texture image to your shader
mat[c4d.MATERIAL_COLOR_SHADER]= shdr_texture #Assign the shader to the color channel in memory only
mat.InsertShader(shdr_texture) #Insert the shader into the color channel
mat.Update(True, True) #Re-calculate the thumbnails of the materialif __name__=='__main__':
main()I've also pulled some other code that might get the job done but I am not sure how to implement it.
imageList = os.listdir(folder) # get folder contents frame = document.GetFrame() # determin the current frame offset = 0 # define frame offset frameOffset = frame+offset # calculate the offset material[c4d.imageSlot] = imagelist[frameOffset] # set image in material Any help would be greatly appreciated.
-
On 29/05/2015 at 17:20, xxxxxxxx wrote:
Hi and welcome ibycus!
this code should answer your question.
If something is nonspecific or you have other questions feel free to ask.Best wishes
Martinimport c4d, os from c4d import gui, bitmaps def main() : #_________________________________________________ #assuming your scene was saved before abspath= doc.GetDocumentPath()+"/"+"tex" imageList = os.listdir(abspath) if imageList == []: return #_________________________________________________ #validate pictures fast #just check the extensions #ensure that there is no hidden .DS_Store etc ext = (".jpg", ".png", ".gif") #and so on for f in imageList: if not any(f.endswith(e) for e in ext) : imageList.remove(f) if imageList == []: return #_________________________________________________ #validate pictures slow #initialize every picture with c4d #""for i in imageList: #""orig = bitmaps.BaseBitmap() #""if orig.InitWith(abspath+"/"+i)[0] != c4d.IMAGERESULT_OK: #""imageList.remove(i) #""if imageList == []: #""return #_________________________________________________ #validate material and shader mat = doc.GetActiveMaterial() if not mat: return shader = mat[c4d.MATERIAL_COLOR_SHADER] if not shader: shader = c4d.BaseList2D(c4d.Xbitmap) shader[c4d.BITMAPSHADER_FILENAME] = imageList[0] mat[c4d.MATERIAL_COLOR_SHADER] = shader mat.InsertShader(shader) if shader.GetType() != c4d.Xbitmap: print "No valid bitmapshader in the slot! Please remove the current shader." return #_________________________________________________ #validate animation track and curve tracks = shader.GetCTracks() track = [] if tracks != []: #if there is any track for tr in tracks: if tr.GetDescriptionID()[0].id == c4d.BITMAPSHADER_FILENAME and tr.GetObject() == shader :#check if there already exists a filetrack at the shader track = tr curve = track.GetCurve() if not track: #if not build it descid = c4d.DescID(c4d.DescLevel(c4d.BITMAPSHADER_FILENAME,c4d.DTYPE_FILENAME)) track = c4d.CTrack(shader,descid) shader.InsertTrackSorted(track) curve = track.GetCurve() else: #if there is no track at all, build a file track descid = c4d.DescID(c4d.DescLevel(c4d.BITMAPSHADER_FILENAME,c4d.DTYPE_FILENAME)) track = c4d.CTrack(shader,descid) shader.InsertTrackSorted(track) curve = track.GetCurve() #_________________________________________________ #store current time and ensure the document takes long enough lenList = len(imageList) intime = doc.GetTime() fps = doc.GetFps() inframe = intime.GetFrame(fps) maxtime = doc.GetMaxTime().GetFrame(fps) if maxtime < lenList: newtime =c4d.BaseTime(float(lenList)/fps) doc.SetMaxTime(newtime) doc.SetLoopMaxTime(newtime) #_________________________________________________ #for every item in imagelist set a key to the shaders curve for i in xrange(lenList) : frame = i keyTime = c4d.BaseTime(frame,fps) #set up the basetime object addPicture = curve.AddKey(keyTime) #try to add a key to the curve if addPicture: shader[c4d.BITMAPSHADER_FILENAME] =imageList[i] #assign the image to the shader keyPicture = addPicture["key"] #grab the key variable from the key dict keyPicture.SetGeData(curve, imageList[i]) #assign imagedata to the key track.FillKey(doc, shader, keyPicture) #fill the key on track #_________________________________________________ #go to the stored frame and animate everything at this frame to update the scene doc.SetTime(intime) doc.ExecutePasses(None, True, False, False, 0) c4d.EventAdd() if __name__=='__main__': main()
-
On 01/06/2015 at 07:55, xxxxxxxx wrote:
Holy Moly!
Thanks a lot! That was a little more involved than I thought it would be. Thanks so much for taking the time to look at this and leaving notes so I can see whats going.
You have set up a "fast load" and a "slow load", the slow load is disabled. What exactly is the difference between the two? I couldn't get the slow load to do anything for me.
Also, it seems to be loading the image list in a random order. Is there anyway to force is to load alphabetically?
Thanks again,
Ashly
-
On 01/06/2015 at 11:40, xxxxxxxx wrote:
Hi Ashly,
you´re welcome!
Here everything works as expected.
You might use some python sort routine to sort your list alphabetically.sorted(imageList, key=str.lower)
The slow load is way overdone, it initializes every bitmap in c4d.
The fast load just checks if file endings match the types you defined in the extension list.
They both should do the same with your imageList, if the extension list is well defined.
But with the slow load you´ll be absolutely sure that c4d can handle your files.
(There might be cases where your file has e.g. a .tif ending but is no picture at all.)
Furthermore you can manipulate the bitmaps in c4d.Hope this helps!
Best wishes
Martin -
On 02/06/2015 at 09:13, xxxxxxxx wrote:
Thanks Martin!
You are a gentlemen and a scholar.
I ended up getting it to work with
imageList.sort()