¿Cómo exportar un modelo 3D a partir de Cinema4d a three.js?
-
28-09-2019 - |
Pregunta
Si tengo una malla de modelado en Cine 4D , ¿cómo puedo exportarlo para la three.js 3D JS motor?
Además, sería útil para la exportación de material colores polígono selecciones .
Solución
Sólo escribió otro script en Python para Cinema4d para esto.
Se puede encontrar más información sobre el rel Blog medios molestar y wiki .
A modo de referencia, estoy lista la fuente aquí también:
'''
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()
Además, añadió exportadores delgados 'a la repositorio que debe producir más pequeños archivos .js para los modelos
Otros consejos
Otra opción es la exportación como Collada / DAE o OBJ y el uso COLLADALoader o OBJLoader .
Alirght, va a tratar esta aquí:
Este plugin no funciona con C4d R12. Desde Maxon absorbido Py4D, hicieron una elección para absorber el objeto símbolos en el objeto C4d. Me bifurcada su código y hurgó un poco para tratar de solucionar las diferencias minutos entre de 11,5 Py4D y R12.
De todas formas, aquí está el plugin de café después usted hizo cuando le comenté un poco más con respecto a los temas. Gracias de nuevo por allanando el camino para genialidad!
Si se produce un error atributo de objeto, es necesario intercambiar la llamada GetPos
con GetAbsPos
en el guión exportador three.js
(c4d13 +).