123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- '''
- 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
- code +='\n\tthis.computeCentroids();\n\tthis.computeNormals(true);\n'
- #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.MeshBasicMaterial({color:this.colors[s]})];\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()
|