Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python 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
    • Recent
    • Tags
    • Users
    • Login

    Auto load folder of images to material [SOLVED]

    Scheduled Pinned Locked Moved PYTHON Development
    5 Posts 0 Posters 563 Views
    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.
    • H Offline
      Helper
      last edited by

      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 os

      def 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 desktop

      mat = 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 material

      if __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. 
      
      1 Reply Last reply Reply Quote 0
      • H Offline
        Helper
        last edited by

        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
        Martin

          
        import 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()  
          
          
          
        
        1 Reply Last reply Reply Quote 0
        • H Offline
          Helper
          last edited by

          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

          1 Reply Last reply Reply Quote 0
          • H Offline
            Helper
            last edited by

            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

            1 Reply Last reply Reply Quote 0
            • H Offline
              Helper
              last edited by

              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()

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