2010-06-02 128 views
1

我需要從Cinema4D導入網格動畫到Blender從cinema4d到攪拌機的3d動畫

我想這樣做使用Collada.The Collada的1.3進口商似乎沒有 做任何事情,爲Collada 1.4進口商似乎工作,但動畫沒有得到 導入攪拌機。

閱讀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.

我試過了,但我得到一個錯誤:

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' 

有沒有人碰到這個問題?我在哪裏可以找到新的Collada導入器? 有關修改導入程序的任何提示?

注意: Blender 2.5a2導入collada動畫,但座標系是不同的,並不是所有的動畫都通過它。例如,當我從0,0,0到100,100,100, 對一個盒子進行動畫處理時,在x,y,z上旋轉它並在x,y,z上將它縮放到Blender中:I軸上的平移(原本是y在電影院4d),旋轉很好,比例被忽略。

回答

0

我最終編寫了一個腳本。

我幾乎找不到可用的C.O.F.F.E.E.文檔如此繼續並安裝py4D

該文檔非常好,論壇上的支持是驚人的。

下面是當前腳本:

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

它支持的IPO鍵(位置,旋轉,縮放)。 點級動畫被轉換爲多個形狀鍵。 變形標記動畫保存得很好。