代码之家  ›  专栏  ›  技术社区  ›  George Profenza

从Cinema4d到Blender的3D动画

  •  1
  • George Profenza  · 技术社区  · 14 年前

    我需要 将网格动画从Cinema4d导入到Blender中 .

    我试着用collada来做。collada 1.3进口商似乎没有 做任何事,collada 1.4导入程序似乎可以工作,但动画没有得到 导入搅拌机。

    读后 this post :

    问题解决了!

    万一有人进来找我 为了得到答案,我通过 电子邮件和他亲切地解释说 .dae文件存在问题 从c4d错误导出。

    希望Otomo不介意我引用 他的电子邮件,我只是不想要其他的 人们浪费我在这上面的时间 一个愚蠢的问题。

    在文本编辑器中打开.dae,然后 变化:

    数据 数据

    对此:

    数据 数据

    两种情况下的fps也必须相同 C4D和搅拌机。

    我试过了,但有个错误:

    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进口商? 有修改导入程序的提示吗?

    注: 搅拌机2.5A2 导入collada动画,但坐标系不同,并非所有动画都能通过。例如,当我将一个框从0,0,0设置为100100100时, 在X,Y,Z上旋转它,在X,Y,Z上缩放它,在搅拌机中我得到:在1轴上平移(X在电影院4d中最初是Y),旋转很好,缩放被忽略。

    1 回复  |  直到 11 年前
        1
  •  0
  •   George Profenza    14 年前

    我最后写了一个剧本。

    我几乎找不到可用的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密钥(位置、旋转、规模)。 点级动画转换为多个形状关键点。 变形标记动画可以很好地保存。