2010-06-02 31 views
1

Je dois importer une animation de maillage de Cinema4D dans Blender.animation 3D de cinema4d à blender

J'ai essayé de le faire en utilisant l'importateur Collada.The Collada 1.3 ne semble pas quoi que ce soit, l'importateur Collada 1.4 semble fonctionner, mais l'animation ne se importé dans Blender.

Après avoir lu this post:

Problem solved!

In case anyone comes in here looking for the answer, I spoke to Otomo via email and he kindly explained that the problem lies in the .dae file being exported incorrectly from C4D.

I hope Otomo doesn't mind me quoting his email, I just don't want other people to waste the time I did on such a stupid problem.

Open up the .dae in a text editor and change:

data data

to this:

data data

The fps must also be the same in both c4d and blender.

J'ai essayé, mais je reçois une erreur:

FEEDBACK: Illusoft Collada 1.4 Plugin v0.3.162 started 
The minor version of the file you are using is newer then the plug-in, so errors may occur. 
image not found: None 
Traceback (most recent call last): 
    File "/Applications/blender/blender.app/Contents/MacOS/.blender/scripts/bpymodules/colladaImEx/cstartup.py", line 681, in ButtonEvent 
    onlyMainScene, applyModifiers) 
    File "/Applications/blender/blender.app/Contents/MacOS/.blender/scripts/bpymodules/colladaImEx/translator.py", line 120, in __init__ 
    self.__Import(fileName) 
    File "/Applications/blender/blender.app/Contents/MacOS/.blender/scripts/bpymodules/colladaImEx/translator.py", line 127, in __Import 
    documentTranslator.Import(fileName) 
    File "/Applications/blender/blender.app/Contents/MacOS/.blender/scripts/bpymodules/colladaImEx/translator.py", line 333, in Import 
    self.sceneGraph.LoadFromCollada(self.colladaDocument.visualScenesLibrary.items, self.colladaDocument.scene) 
    File "/Applications/blender/blender.app/Contents/MacOS/.blender/scripts/bpymodules/colladaImEx/translator.py", line 550, in LoadFromCollada 
    ob = sceneNode.ObjectFromDae(daeNode) 
    File "/Applications/blender/blender.app/Contents/MacOS/.blender/scripts/bpymodules/colladaImEx/translator.py", line 2079, in ObjectFromDae 
    a.LoadFromDae(daeAnimation, daeNode, newObject) 
    File "/Applications/blender/blender.app/Contents/MacOS/.blender/scripts/bpymodules/colladaImEx/translator.py", line 1254, in LoadFromDae 
    interpolationsSource = daeAnimation.GetSource(interpolations.source) 
AttributeError: 'NoneType' object has no attribute 'source' 

Quelqu'un at-il rencontré ce problème? Où puis-je trouver un nouvel importateur Collada? Des indices sur la modification de l'importateur?

Remarque: Blender 2.5a2 importe des animations collada, mais le système de coordonnées est différent et toutes les animations ne le traversent pas. Par exemple, lorsque j'anime une boîte de 0,0,0 à 100,100,100, la fait pivoter sur x, y, z et la redimensionne sur x, y, z, dans Blender I get: translation sur 1 axe (x qui est à l'origine y dans le cinéma 4d), la rotation est bonne, l'échelle est ignorée.

Répondre

0

J'ai fini par écrire un script.

J'ai trouvé à peine C.O.F.F.E.E. documentation donc allé de l'avant et installé py4D.

La documentation est assez bonne et le support sur le forum est incroyable.

Voici le script actuel:

import c4d 
from c4d import documents,UVWTag 
from c4d.utils import Deg 
from c4d import symbols as sy, plugins, utils, bitmaps, gui 
import math 


def BlenderExport(): 
    if not op: return 
    if op.GetType() != 5100: 
     print 'Selected Object is not an editable mesh' 
     return 
    unit = 0.001#for scale 
    foffset = 1#for frames 
    bd = doc.GetRenderBaseDraw() 
    scr = bd.GetFrameScreen() 
    rd = doc.GetActiveRenderData() 
    sizeX = int(rd[sy.RDATA_XRES_VIRTUAL]) 
    sizeY = int(rd[sy.RDATA_YRES_VIRTUAL]) 
    name = op.GetName() 
    fps = doc.GetFps() 
    sFrame= doc.GetMinTime().GetFrame(fps) 
    eFrame= doc.GetMaxTime().GetFrame(fps) 
    code = 'import Blender\nfrom Blender import *\nimport bpy\nfrom Blender.Mathutils import *\n\nscn = bpy.data.scenes.active\ncontext=scn.getRenderingContext()\ncontext.fps = '+str(fps)+'\ncontext.sFrame = '+str(sFrame)+'\ncontext.eFrame = '+str(eFrame)+'\ncontext.sizeX = '+str(sizeX)+'\ncontext.sizeY = ' + str(sizeY) + '\n' 

    def GetMesh(code): 
     # goto 0 
     doc.SetTime(c4d.BaseTime(0, fps)) 
     c4d.DrawViews(c4d.DA_ONLY_ACTIVE_VIEW|c4d.DA_NO_THREAD|c4d.DA_NO_REDUCTION|c4d.DA_STATICBREAK) 
     c4d.GeSyncMessage(c4d.EVMSG_TIMECHANGED) 
     doc.SetTime(doc.GetTime()) 
     c4d.EventAdd(c4d.EVENT_ANIMATE) 

     code  += 'editmode = Window.EditMode()\nif editmode:\tWindow.EditMode(0)\n' 
     coords4D = op.GetPointAll() 
     coords  = 'coords = [' 
     uvw  = 0 
     uvs  = 'uvs = [' 
     for tag in op.GetTags(): 
      if tag.GetName() == "UVW": 
       uvw = tag 
     for c in coords4D: 
      coords += '['+str(c.x*unit)+','+str(c.z*unit)+','+str(c.y*unit)+'],' 
     coords  = coords.rpartition(',')[0] + ']\n' 
     faces4D = op.GetAllPolygons() 
     fcount  = 0 
     faces  = 'faces = [' 
     for f in faces4D: 
      faces += '['+str(f)+'],' 
      uv = uvw.Get(fcount); 
      uvs += '[Vector('+str(uv[0].x)+','+str(1.0-uv[0].y)+'),Vector('+str(uv[1].x)+','+str(1.0-uv[1].y)+'),Vector('+str(uv[2].x)+','+str(1.0-uv[2].y)+')],' 
      fcount += 1 

     faces  = faces.rpartition(',')[0] + ']\n' 
     uvs  = uvs.rpartition(',')[0] + ']\n' 

     code  = code + coords + faces + uvs 
     code  += "c4dmesh = bpy.data.meshes.new('"+name+"_mesh')\nc4dmesh.verts.extend(coords)\nc4dmesh.faces.extend(faces)\n\nob = scn.objects.new(c4dmesh,'"+name+"_obj')\nc4dmesh.flipNormals()\n\nif editmode:\tWindow.EditMode(1)\n\n" 
     code  += "c4dmesh.quadToTriangle()\nc4dmesh.addUVLayer('c4duv')\n" 
     code  += "for f in range(0,"+str(fcount)+"):\n\tc4dmesh.faces[f].uv = uvs[f]\n" 

     return code 

    def GetIPOKeys(code): 
     # store properties for tracks 
     tracks = op.GetCTracks() 
     # 0,1,2 = Position, 3,4,5 = Scale, 6,7,8 = Rotation, 9 = PLA 
     # props = [[lx,f],[ly,f],[lz,f],[sx,f],[sy,f],[sz,f],[rx,f],[ry,f],[rz,f]] 
     try: 
      props = [] 
      trackIDs = [3,4,5,6,7,8,0,2,1] 
      propVals = ['LocX','LocZ','LocY','SizeX','SizeY','SizeZ','RotZ','RotX','RotY'] 
      propIPOs = ['Ipo.OB_LOCX','Ipo.OB_LOCZ','Ipo.OB_LOCY','Ipo.OB_SCALEX','Ipo.OB_SCALEY','Ipo.OB_SCALEY','Ipo.OB_ROTZ','Ipo.OB_ROTX','Ipo.OB_ROTY'] 
      for t in range(0,9): 
       props.append([[],[]]) 
       curve = tracks[t].GetCurve() 
       keyCount = curve.GetKeyCount() 
       for k in range(0,keyCount): 
         key = curve.GetKey(k) 
         props[t][0].append(key.GetValue()) 
         props[t][1].append(key.GetTime().GetFrame(fps)) 
      # find the max key 
      maxProp = max(enumerate(props), key = lambda tup: len(tup[1]))[1][1] 
      maxKeys = len(maxProp) 
      # loop through tracks and keys 
      for key in range(0,maxKeys): 
       code += "Blender.Set('curframe',"+str(maxProp[key])+")\n" 
       for track in trackIDs: 
        if(key < len(props[track][0])): 
         code += "ob."+propVals[track] + " = " + str(props[track][0][key]) + '\n' 
         code += 'key = ob.insertIpoKey(' + propIPOs[track] + ')\n' 
     except: 
      pass 
     return code 
    #  mesh/morph animation -> mesh always has the same number of verts 
    def GetShapeKeys(code): 
     track = 0; 
     tracks = op.GetCTracks() 
     for t in tracks: 
      if(t.GetName() == 'PLA'): track = t 
     # track = op.GetCTracks()[9]  
     if track != 0: 
      curve = track.GetCurve() 
      keyCount = curve.GetKeyCount() 
      verts = [] 
      frames = [] 
      vertsNum = op.GetPointCount() 
      ctime = doc.GetTime() 

      for k in range(1,keyCount): 
       key = curve.GetKey(k) 
       frames.append(key.GetTime().GetFrame(fps)) 
       c4d.StatusSetBar(100*(k/keyCount)) 
       doc.SetTime(key.GetTime()) 
       c4d.DrawViews(c4d.DA_ONLY_ACTIVE_VIEW|c4d.DA_NO_THREAD|c4d.DA_NO_REDUCTION|c4d.DA_STATICBREAK) 
       c4dvecs = op.GetPointAll(); 
       blendvecs = [] 
       for v in c4dvecs: 
        blendvecs.append([v.x*unit,v.z*unit,v.y*unit]) 
       verts.append(blendvecs) 
       c4d.GeSyncMessage(c4d.EVMSG_TIMECHANGED) 
      doc.SetTime(ctime) 
      c4d.EventAdd(c4d.EVENT_ANIMATE) 
      c4d.StatusClear() 

      code += '\n\n# shape keys\nverts = ' + str(verts) + '\n' 
      code += "if(ob.activeShape == 0):\n\tob.insertShapeKey()\n\n" 
      for f in range(0,len(frames)): 
       kNum = str(f+1) 
       code += "if editmode: Window.EditMode(0)\n" 
       code += "for v in range(0,"+str(vertsNum)+"):\n\tc4dmesh.verts[v].co.x = verts["+str(f)+"][v][0]\n\tc4dmesh.verts[v].co.y = verts["+str(f)+"][v][1]\n\tc4dmesh.verts[v].co.z = verts["+str(f)+"][v][2]\n" 
       code += "c4dmesh.calcNormals()\n" 
       code += "ob.insertShapeKey()\n" 
       code += "if editmode: Window.EditMode(1)\n" 
       code += "shapeKey = ob.getData().getKey()\n" 
       code += "newIpo = Ipo.New('Key','newIpo')\n" 
       code += "if(shapeKey.ipo == None): shapeKey.ipo = newIpo\n" 
       code += "if(shapeKey.ipo['Key "+kNum+"'] == None): shapeKey.ipo.addCurve('Key "+kNum+"')\n" 
       if(f == 0): code += "shapeKey.ipo['Key "+kNum+"'].append(BezTriple.New(1.0,0.0,0.0))\n" 
       if(f > 0): code += "shapeKey.ipo['Key "+kNum+"'].append(BezTriple.New("+str(float(frames[f-1]))+",0.0,0.0))\n" 
       code += "shapeKey.ipo['Key "+kNum+"'].append(BezTriple.New("+str(float(frames[f]))+",1.0,0.0))\n" 
     else: 
      #no PLA tracks, look for morph tag 
      vertsNum = op.GetPointCount() 
      for tag in op.GetTags(): 
       if tag.GetType() == 1019633: 
        # print tag[sy.MORPHTAG_MORPHS] 
        ''' 
        work around 
        1. store first key for each track curve 
        2. set the first key value to 1 for the 1st track and 0 for the others 
        3. store the mesh vertices -> track name verts = [] 
        4. after all track verts are stored, restore the original values 
        5. write the the curve keys for blender shape keys 
        ''' 
        code += "if(ob.activeShape == 0):\n\tob.insertShapeKey()\n\n" 
        tc = 0 
        tcs = str(tc+1) 
        for track in tag.GetCTracks(): 
         curve = track.GetCurve() 
         value = curve.GetKey(0).GetValue() 
         curve.GetKey(0).SetValue(curve,1.0) 
         print track.GetName() 
         doc.SetTime(c4d.BaseTime(0, fps)) 
         c4d.DrawViews(c4d.DA_ONLY_ACTIVE_VIEW|c4d.DA_NO_THREAD|c4d.DA_NO_REDUCTION|c4d.DA_STATICBREAK) 
         c4dvecs = op.GetPointAll(); 
         blendverts = [] 
         for v in c4dvecs: 
          blendverts.append([v.x*unit,v.z*unit,v.y*unit]) 
         code += "Key"+tcs+"verts = " + str(blendverts)+"\n" 
         code += "if editmode: Window.EditMode(0)\n" 
         code += "for v in range(0,"+str(vertsNum)+"):\n\tc4dmesh.verts[v].co.x = Key"+tcs+"verts[v][0]\n\tc4dmesh.verts[v].co.y = Key"+tcs+"verts[v][1]\n\tc4dmesh.verts[v].co.z = Key"+tcs+"verts[v][2]\n" 
         code += "c4dmesh.calcNormals()\n" 
         code += "ob.insertShapeKey()\n" 
         code += "if editmode: Window.EditMode(1)\n" 
         code += "shapeKey = ob.getData().getKey()\n" 
         code += "newIpo = Ipo.New('Key','newIpo')\n" 
         code += "if(shapeKey.ipo == None): shapeKey.ipo = newIpo\n" 
         code += "if(shapeKey.ipo['Key "+tcs+"'] == None): shapeKey.ipo.addCurve('Key "+tcs+"')\n" 
         print op.GetPointAll() 
         c4d.GeSyncMessage(c4d.EVMSG_TIMECHANGED) 
         curve.GetKey(0).SetValue(curve,value) 
         keyCount = curve.GetKeyCount() 
         for k in range(0,keyCount): 
          key = curve.GetKey(k) 
          value = key.GetValue() 
          frame = key.GetTime().GetFrame(fps) 
          code += "shapeKey.ipo['Key "+tcs+"'].append(BezTriple.New("+str(float(frame))+","+str(value)+",0.0))\n" 
         tc += 1 
         tcs = str(tc+1) 

        c4d.EventAdd(c4d.EVENT_ANIMATE) 
     return code 

    def GetCamera(code): 
     bd = doc.GetRenderBaseDraw() 
     cp = bd.GetSceneCamera(doc) 
     if cp is None: cp = bd.GetEditorCamera() 
     fov = Deg(cp[sy.CAMERAOBJECT_FOV]) 
     pos = cp.GetPos() 
     rot = cp.GetRot() 
     code += "\nc4dCam = Camera.New('persp','c4d_"+cp.GetName()+"')\nc4dCam.drawPassepartout = True\nc4dCam.alpha = 0.5\nc4dCam.drawLimits = 1\nc4dCam.dofDist = 100.0\n" 
     code += "c4dCam.angle = "+str(fov)+"\nc4dCamLens = c4dCam.lens\nc4dCam.lens = c4dCamLens\nWindow.RedrawAll()\nc4dCamObj = scn.objects.new(c4dCam)\n" 
     code += "c4dCamObj.setLocation("+str([pos.x,pos.z,pos.y])+")\n" 
     code += "c4dCamObj.setEuler("+str([rot.x+(math.pi*.5),rot.y,rot.z])+")\n" 
     code += "scn.setCurrentCamera(c4dCamObj)\n" 
     return code 

    code = GetMesh(code) 
    code = GetIPOKeys(code) 
    code = GetShapeKeys(code) 
    code = GetCamera(code) 

    file = open(doc.GetDocumentPath()+'/'+op.GetName()+'_export.py','w') 
    file.write(code) 
    file.close() 


BlenderExport() 

Il prend en charge les touches (ipo position, rotation, échelle). L'animation de niveau point est convertie en plusieurs clés de forme. L'animation Morph Tag se conserve bien.