2010-11-25 326 views

回答

9

剛剛爲Cinema4D寫了另一個python腳本。

你可以找到disturb media blogwiki的細節。

DeltaInc Bot

Dodecahedrons

僅供參考,我在這裏列出源太:

''' 
author : "George Profenza" 
url : ("disturb", "disturbmedia.com/blog","My blog, http://tomaterial.blogspot.com") 

Export meshes the three.js 3D Engine by mr.doob's et al. 

More details on the engine here: 
https://github.com/mrdoob/three.js 

Currently supports UVs. If the model doesn't display correctly 
you might need to reverse some normals/do some cleanup. 
Also, if you use Selection Tags and basic ColorMaterials, 
the colours will be picked up as face colors. Call autoColor() on the 
model you use for this. 
The mesh transformations(position, rotation, scale) are saved 
and you can get them using: getPosition(), getRotation() and getScale() 
each returning a THREE.Vector3 

In short 
var myGeom = new myC4DGeom(); 
var myModel = new THREE.Mesh(myGeom, new THREE.MeshFaceMaterial()); 
//set transforms 
model.position = myGeom.getPosition() 
model.rotation = myGeom.getRotation() 
model.scale = myGeom.getScale() 
//set selection tags colours 
myGeom.autoColor() 

More details on this exporter and more js examples here: 
https://github.com/orgicus/three.js 

Have fun! 

This script requires Cinema 4D R11.5 minimum and the Py4D Plugin: 
http://www.py4d.com/get-py4d/ 
''' 

import c4d 
from c4d import documents,UVWTag,storage 
from c4d.utils import * 
from c4d import symbols as sy, plugins, utils, bitmaps, gui 
import math 
import re 

# utils 
clean = lambda varStr: re.sub('\W|^(?=\d)','_', varStr) 
# from Active State's Python recipies: http://code.activestate.com/recipes/266466-html-colors-tofrom-rgb-tuples/ 
def RGBToHTMLColor(rgb_tuple): 
    return '0x%02x%02x%02x' % rgb_tuple 
def Export(): 
    if not op: return 
    if op.GetType() != 5100: 
      print 'Selected Object is not an editable mesh' 
      return 
    unit = 0.001#for scale 
    fps = doc.GetFps() 
    bd = doc.GetRenderBaseDraw() 
    scr = bd.GetFrameScreen() 
    rd = doc.GetActiveRenderData() 
    name = op.GetName() 
    classname = clean(name) 

    c4dPath = c4d.storage.GeGetC4DPath(sy.C4D_PATH_LIBRARY) 
    jsFile = open(c4dPath+'/scripts/Three.js','r') 
    js = jsFile.read() 
    htmlFile = open(c4dPath+'/scripts/template.html','r') 
    html = htmlFile.read() 
    html = html.replace('%s',classname) 
    code = 'var %s = function() {\n\n\tvar scope = this;\n\n\tTHREE.Geometry.call(this);\n\n' % classname 

    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) 
     SendModelingCommand(command = MCOMMAND_REVERSENORMALS, list = [op], mode = MODIFY_ALL, bc = c4d.BaseContainer(), doc = doc) 

     verts = op.GetPointAll() 
     for v in verts: 
      code += '\tv(%.6f, %.6f, %.6f);\n' % (v.x, -v.y, v.z) 
     code += '\n' 
     ncount = 0 
     uvcount = 0 
     faces = op.GetAllPolygons() 
     normals = op.CreatePhongNormals() 
     ndirection = 1 
     hasUV = False 
     for tag in op.GetTags(): 
      if tag.GetName() == "UVW": 
       uvw = tag 
       hasUV = True 
     for f in faces: 
      if(f.d == f.c): 
       if(normals): 
        code += '\tf3(%d, %d, %d, %.6f, %.6f, %.6f);\n' % (f.a, f.b, f.c, normals[ncount].x*ndirection, normals[ncount].y*ndirection, normals[ncount].z*ndirection) 
       else: 
        code += '\tf3(%d, %d, %d);\n' % (f.a, f.b, f.c) 
      else: 
       if(normals): 
        code += '\tf4(%d, %d, %d, %d, %.6f, %.6f, %.6f);\n' % (f.a, f.b, f.c, f.d, normals[ncount].x*ndirection, normals[ncount].y*ndirection, normals[ncount].z*ndirection) 
       else: 
        code += '\tf4(%d, %d, %d, %d);\n' % (f.a, f.b, f.c, f.d) 
      if hasUV: 
       uv = uvw.Get(uvcount); 
       # 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)+')],' 
       if len(uv) == 4: 
        code += '\tuv(%.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f);\n' % (uv[0].x, uv[0].y, uv[1].x, uv[1].y, uv[2].x, uv[2].y, uv[3].x, uv[3].y) 
       else: 
        code += '\tuv(%.6f, %.6f, %.6f, %.6f, %.6f, %.6f);\n' % (uv[0].x, uv[0].y, uv[1].x, uv[1].y, uv[2].x, uv[2].y) 
       ncount += 1 
       uvcount += 1 

     #selection color 
     code +='\n\tscope.colors = {};\n' 
     code +='\tscope.selections = {};\n' 
     selName = '' 
     for tag in op.GetTags(): 
      if(tag.GetType() == 5616): #texture tag 
       material = tag.GetMaterial() 
       color = material[sy.MATERIAL_COLOR_COLOR] 
       tag.SetBit(c4d.BIT_ACTIVE) 
       selName = clean(tag[sy.TEXTURETAG_RESTRICTION]) 
       if len(selName) == 0: print "*** WARNING! *** Missing selection name for material: " + material.GetName() 
       code += '\tscope.colors["'+selName+'"] = '+str(RGBToHTMLColor((color.x*255,color.y*255,color.z*255)))+';\n' 
      if tag.GetType() == 5673: #selection tag 
       # print 'selection: ' + tag.GetName() 
       sel = tag.GetSelection() 
       selName = clean(tag.GetName()) 
       ids = sel.GetAll(op.GetPointCount()) 
       indices = [i for i, e in enumerate(ids) if e != 0] 
       code += '\tscope.selections["'+selName+'"] = '+str(indices)+';\n' 

     code += '\n\tscope.autoColor = function(){\n' 
     code += '\t\tfor(var s in this.selections){\n' 
     code += '\t\t\tfor(var i = 0 ; i < this.selections[s].length; i++) this.faces[this.selections[s][i]].material = [ new THREE.MeshColorFillMaterial(this.colors[s],1) ];\n' 
     code += '\t\t}\n\t}\n' 

     # model position, rotation, scale    rotation x,y,z = H,P,B => three.js x,y,z is P,H,B => y,x,z 
     p = op.GetPos() 
     r = op.GetRot() 
     s = op.GetScale() 
     code += '\n\tscope.getPosition = function(){\treturn new THREE.Vector3'+str((p.x,p.y,p.z))+';\t}\n' 
     code += '\n\tscope.getRotation = function(){\treturn new THREE.Vector3'+str((r.y,r.x,r.z))+';\t}\n' 
     code += '\n\tscope.getScale = function(){\treturn new THREE.Vector3'+str((s.x,s.y,s.z))+';\t}\n' 

     code += '\n' 
     code += '\tfunction v(x, y, z) {\n\n' 
     code += '\t\tscope.vertices.push(new THREE.Vertex(new THREE.Vector3(x, y, z)));\n\n' 
     code += '\t}\n\n' 
     code += '\tfunction f3(a, b, c, nx, ny, nz) {\n\n' 
     code += '\t\tscope.faces.push(new THREE.Face3(a, b, c, nx && ny && nz ? new THREE.Vector3(nx, ny, nz) : null));\n\n' 
     code += '\t}\n\n' 
     code += '\tfunction f4(a, b, c, d, nx, ny, nz) {\n\n' 
     code += '\t\tscope.faces.push(new THREE.Face4(a, b, c, d, nx && ny && nz ? new THREE.Vector3(nx, ny, nz) : null));\n\n' 
     code += '\t}\n\n' 
     code += '\tfunction uv(u1, v1, u2, v2, u3, v3, u4, v4) {\n\n' 
     code += '\t\tvar uv = [];\n' 
     code += '\t\tuv.push(new THREE.UV(u1, v1));\n' 
     code += '\t\tuv.push(new THREE.UV(u2, v2));\n' 
     code += '\t\tuv.push(new THREE.UV(u3, v3));\n' 
     code += '\t\tif (u4 && v4) uv.push(new THREE.UV(u4, v4));\n' 
     code += '\t\tscope.uvs.push(uv);\n' 
     code += '\t}\n\n' 
     code += '}\n\n' 
     code += '%s.prototype = new THREE.Geometry();\n' % classname 
     code += '%s.prototype.constructor = %s;' % (classname, classname) 

     SendModelingCommand(command = MCOMMAND_REVERSENORMALS, list = [op], mode = MODIFY_ALL, bc = c4d.BaseContainer(), doc = doc) 

     return code 

    code = GetMesh(code) 
    docPath = doc.GetDocumentPath() 
    jspath = docPath+'/'+classname+'.js' 
    htmlpath = docPath+'/'+classname+'.html' 
    file = open(jspath,'w') 
    file.write(code) 
    file.close() 
    file = open(htmlpath,'w') 
    file.write(html) 
    file.close() 
    file = open(docPath+'/Three.js','w') 
    file.write(js) 
    file.close() 
    print 'Export Complete!' 

Export() 

而且,增加了 '超薄' 出口到repository應該產生較小的.js文件 爲模型

+0

我可以爲Cinema 4D R13 +將3D模型導出爲Three.js嗎?我無法看到Py4D的這個版本。任何幫助?謝謝。 – vnpnlz 2013-04-04 08:28:44

2

Alirght,要試試這裏:

此插件不適用於C4D R12。由於Maxon吸收了Py4D,他們選擇將符號對象吸收到c4d對象中。我分出你的code並探索了一下,試圖解決11.5的Py4D和R12之間的微小差異。

無論如何,這裏是您提出的plugin cafe post,我對這些問題進行了更多評論。再次感謝您爲真棒鋪平道路!

+0

嗨,這是相當不錯的東西!不幸的是,自從冬天以後,我沒有時間更新我的代碼。 three.js移動得非常快。我會找一些時間來更新我的分支和出口商(因爲他們不再適合最新的three.js主要回購版)謝謝! – 2011-04-07 19:02:35

1

如果您收到對象屬性錯誤,則需要在three.js導出器腳本(c4d13 +)中將GetPos調用與GetAbsPos進行交換。