import Blender
from Blender import NMesh
from Blender import Image
from array import array
import string
import os,sys
from Blender.Draw import *
from Blender.BGL import *
try:
import gzip
GZIPOK = 1
except ImportError:
print "Gzip module not supported!"
GZIPOK = 0
def getTabs(tabCount):
# returns tabCount tab characters as a string
tabs = ""
for i in range(0, tabCount):
tabs = tabs + "\t"
return tabs
def numToFloatXML(theFloat):
# returns the number as an XML string
return "<float>" + str(theFloat) + "</float>"
def numToIntXML(theInt):
return "<int>" + str(theInt) + "</int>"
def vertToArrayChunkXML(vert, tabCount, firstIndex):
# converts a vertex to xml
tabs = getTabs(tabCount)
xml = array('c')
xml.fromstring(tabs + "<void index=\"" + str(firstIndex) + "\">\n")
xml.fromstring(tabs + "\t" + numToFloatXML(vert[0]) + "\n")
xml.fromstring(tabs + "</void>\n")
xml.fromstring(tabs + "<void index=\"" + str(firstIndex + 1) + "\">\n")
xml.fromstring(tabs + "\t" + numToFloatXML(vert[1]) + "\n")
xml.fromstring(tabs + "</void>\n")
xml.fromstring(tabs + "<void index=\"" + str(firstIndex + 2) + "\">\n")
xml.fromstring(tabs + "\t" + numToFloatXML(vert[2]) + "\n")
xml.fromstring(tabs + "</void>\n")
return xml
def coordToUVCoordXML(coord, tabCount, firstIndex):
# converts a vertex to xml
tabs = getTabs(tabCount)
xml = array('c')
xml.fromstring(tabs + "<void index=\"" + str(firstIndex) + "\">\n")
xml.fromstring(tabs + "\t" + numToFloatXML(coord[0]) + "\n")
xml.fromstring(tabs + "</void>\n")
xml.fromstring(tabs + "<void index=\"" + str(firstIndex + 1) + "\">\n")
xml.fromstring(tabs + "\t" + numToFloatXML(coord[1]) + "\n")
xml.fromstring(tabs + "</void>\n")
return xml
def triangleToArrayChunkXML(vert1, vert2, vert3, tabCount, firstIndex):
# converts three vertices to xml
xml = array('c')
xml.extend(vertToArrayChunkXML(vert1, tabCount, firstIndex))
xml.extend(vertToArrayChunkXML(vert2, tabCount, firstIndex + 3))
xml.extend(vertToArrayChunkXML(vert3, tabCount, firstIndex + 6))
return xml
def triangleToUVCoordXML(coord1, coord2, coord3, tabCount, firstIndex):
# converts three vertices to xml
xml = array('c')
xml.extend(coordToUVCoordXML(coord1, tabCount, firstIndex))
xml.extend(coordToUVCoordXML(coord2, tabCount, firstIndex + 2))
xml.extend(coordToUVCoordXML(coord3, tabCount, firstIndex + 4))
return xml
def facesToTriangleArrayXML(faces, materialIndex, tabCount):
# converts a list of faces to an array
# returns it in xml format
index = 0
tabs = getTabs(tabCount)
xml = array('c')
xmlBody = array('c')
for face in faces:
if (face.mat == materialIndex) and (len(face) > 2) :
# if there are three of more verices, and
# if it has the correct material index
xmlBody.extend(triangleToArrayChunkXML(face[0], face[1], face[2], tabCount + 3, index))
index = index + 9
if len(face) > 3 :
# if there are 4 vertices.
# this breaks quadrilaterals into triangles
xmlBody.extend(triangleToArrayChunkXML(face[0], face[2], face[3], tabCount + 3, index))
index = index + 9
xml.fromstring(tabs + "<object class=\"javax.media.j3d.TriangleArray\">\n")
xml.fromstring(tabs + "\t" + numToIntXML(index) + "\n")
xml.fromstring(tabs + "\t<object class=\"javax.media.j3d.GeometryArray\" field=\"COORDINATES\"></object>\n")
xml.fromstring(tabs + "\t<void property=\"coordinates\">\n")
xml.fromstring(tabs + "\t\t" + numToIntXML(0) + "\n")
xml.fromstring(tabs + "\t\t<array class=\"float\" length=\"" + str(index) + "\">\n")
xml.extend(xmlBody)
xml.fromstring(tabs + "\t\t</array>\n")
xml.fromstring(tabs + "\t</void>\n")
xml.fromstring(tabs + "</object>\n")
return xml
def facesToArrayXML(faces, materialIndex, tabCount):
# converts a list of faces to an array
# returns it in xml format
index = 0
tabs = getTabs(tabCount)
xml = array('c')
xmlBody = array('c')
for face in faces:
if (face.mat == materialIndex) and (len(face) > 2) :
# if there are three of more verices, and
# if it has the correct material index
xmlBody.extend(triangleToArrayChunkXML(face[0], face[1], face[2], tabCount + 1, index))
index = index + 9
if len(face) > 3 :
# if there are 4 vertices.
# this breaks quadrilaterals into triangles
xmlBody.extend(triangleToArrayChunkXML(face[0], face[2], face[3], tabCount + 1, index))
index = index + 9
xml.fromstring(tabs + "<array class=\"float\" length=\"" + str(index) + "\">\n")
xml.extend(xmlBody)
xml.fromstring(tabs + "</array>\n")
return xml
# gas
def facesUVToArrayXML(faces, materialIndex, tabCount):
# converts a list of faces to an array
# returns it in xml format
index = 0
tabs = getTabs(tabCount)
xml = array('c')
xmlBody = array('c')
for face in faces:
if (face.mat == materialIndex) and (len(face) > 2) and (len(face.uv) > 2):
# UV coordinates
xmlBody.extend(triangleToUVCoordXML(face.uv[0], face.uv[1], face.uv[2], tabCount + 1, index))
index = index + 6
if len(face) > 3 :
# if there are 4 vertices.
# this breaks quadrilaterals into triangles
xmlBody.extend(triangleToUVCoordXML(face.uv[0], face.uv[2], face.uv[3], tabCount + 1, index))
index = index + 6
xml.fromstring(tabs + "<array class=\"float\" length=\"" + str(index) + "\">\n")
xml.extend(xmlBody)
xml.fromstring(tabs + "</array>\n")
return xml
def meshComponentToTriangleStripArrayXML(mesh, materialIndex, tabCount):
xml = prepareMeshComponentToTriangleStripArrayXML(mesh, materialIndex, tabCount)
xml = actualMeshToComponentTriangleStripArrayXML(mesh, materialIndex, tabCount)
return xml
def actualMeshToComponentTriangleStripArrayXML(mesh, materialIndex, tabCount):
name = mesh.name
xml = array('c')
xml.fromstring(tabs + "<object idref=\""+ name + "-ga" + str(materialIndex) + "\"></object>\n")
return xml
def prepareMeshComponentToTriangleStripArrayXML(mesh, materialIndex, tabCount):
# creates a TriangleStripArray from the faces in the mesh
# with the materialIndex specified
tabs = getTabs(tabCount)
xml = array('c')
faces = mesh.faces
name = mesh.name
# initialise the GeometryInfo doover
xml.fromstring(tabs + "<void class=\"com.sun.j3d.utils.geometry.GeometryInfo\" id=\""+ name + "-gi" + str(materialIndex) + "\">\n")
xml.fromstring(tabs + "\t<object class=\"com.sun.j3d.utils.geometry.GeometryInfo\" field=\"TRIANGLE_ARRAY\"></object>\n")
xml.fromstring(tabs + "\t<void property=\"coordinates\">\n")
xml.extend(facesToArrayXML(faces, materialIndex, tabCount + 2))
xml.fromstring(tabs + "\t</void>\n")
if (mesh.hasFaceUV()) :
xml.fromstring(tabs + "\t<void property=\"textureCoordinates2\">\n")
xml.extend(facesUVToArrayXML(faces, materialIndex, tabCount + 2))
xml.fromstring(tabs + "\t</void>\n")
xml.fromstring(tabs + "</void>\n")
# do the Normal Generation
xml.fromstring(tabs + "<void class=\"com.sun.j3d.utils.geometry.NormalGenerator\">\n")
xml.fromstring(tabs + "\t<void property=\"creaseAngle\">\n")
xml.fromstring(tabs + "\t\t<object class=\"java.lang.Math\" field=\"PI\"></object>\n")
xml.fromstring(tabs + "\t</void>\n")
xml.fromstring(tabs + "\t<void method=\"generateNormals\">\n")
xml.fromstring(tabs + "\t\t<object idref=\""+ name + "-gi" + str(materialIndex) + "\"></object>\n")
xml.fromstring(tabs + "\t</void>\n")
xml.fromstring(tabs + "</void>\n")
# do the Stripification
xml.fromstring(tabs + "<void class=\"com.sun.j3d.utils.geometry.Stripifier\">\n")
xml.fromstring(tabs + "\t<void method=\"stripify\">\n")
xml.fromstring(tabs + "\t\t<object idref=\""+ name + "-gi" + str(materialIndex) + "\"></object>\n")
xml.fromstring(tabs + "\t</void>\n")
xml.fromstring(tabs + "</void>\n")
# return the TriangleStripArray
xml.fromstring(tabs + "<void idref=\""+ name + "-gi" + str(materialIndex) + "\">\n")
xml.fromstring(tabs + "\t<void property=\"geometryArray\" id=\""+ name + "-ga" + str(materialIndex) + "\"></void>\n")
xml.fromstring(tabs + "</void>\n")
return xml
def meshComponentToShape3DXML(mesh, materialIndex, tabCount):
# creates a Shape3D from all the faces in the mesh with the
# materialIndex specified
tabs = getTabs(tabCount)
xml = array('c')
#materials = Blender.Object.GetSelected()[0].getData().materials
materials = mesh.materials
name = mesh.name
faces = mesh.faces
xml.extend(prepareMeshComponentToTriangleStripArrayXML(mesh, materialIndex, tabCount))
xml.fromstring(tabs + "<object class=\"javax.media.j3d.Shape3D\">\n")
if (mesh.hasFaceUV()) :
tex = str(faces[0].image.getName())
# this is for removing .00x from reloaded texture names....
if (tex.find(".0") != -1) :
#print "debug "+tex
#print "debug "+str(tex.rfind(".0"))
tex = tex[0:tex.rfind(".0")]
# --------------------------------------------------------
xml.fromstring(tabs + "\t<void property=\"userData\">\n")
xml.fromstring(tabs + "\t\t<string>"+tex+"</string>\n")
print("texture found :"+tex)
xml.fromstring(tabs + "\t</void>\n")
xml.fromstring(tabs + "\t<void property=\"geometry\">\n")
xml.fromstring(tabs + "\t\t<object idref=\""+ name + "-ga" + str(materialIndex) + "\"></object>\n")
xml.fromstring(tabs + "\t</void>\n")
xml.fromstring(tabs + "\t<void property=\"appearance\">\n")
xml.extend(materialToAppearanceXML(materials[materialIndex], tabCount + 2))
xml.fromstring(tabs + "\t</void>\n")
xml.fromstring(tabs + "</object>\n")
return xml
def meshToShape3DXMLList(mesh, tabCount):
# creates a set of Shape3D objects (in XML) stored in a list
# crea la lista dei materiali
tabs = getTabs(tabCount)
theList = []
#materials = Blender.Object.GetSelected()[0].getData().materials
materials = mesh.materials
for materialIndex in range(0, len(materials)):
theList.append(meshComponentToShape3DXML(mesh, materialIndex, tabCount))
return theList
def colourToColor3fXML(r, g, b, tabCount):
# turns the rgb values into a Color3f object in XML form
tabs = getTabs(tabCount)
xml = array('c')
xml.fromstring(tabs + "<object class=\"javax.vecmath.Color3f\">\n")
xml.fromstring(tabs + "\t" + numToFloatXML(r) + "\n")
xml.fromstring(tabs + "\t" + numToFloatXML(g) + "\n")
xml.fromstring(tabs + "\t" + numToFloatXML(b) + "\n")
xml.fromstring(tabs + "</object>\n")
return xml
def materialToMaterialXML(material, tabCount):
# converts a blender material into a java material object
# in xml form
tabs = getTabs(tabCount)
xml = array('c')
xml.fromstring(tabs + "<object class=\"javax.media.j3d.Material\">\n")
#ambient colour
xml.extend(colourToColor3fXML( material.R * material.amb,
material.G * material.amb,
material.B * material.amb,
tabCount + 1
))
#emissive colour
xml.extend(colourToColor3fXML( material.emit, material.emit, material.emit, tabCount + 1))
#diffuse colour
xml.extend(colourToColor3fXML( material.R,
material.G,
material.B,
tabCount + 1
))
xml.extend(colourToColor3fXML( material.specR,
material.specG,
material.specB,
tabCount + 1
))
xml.fromstring(tabs + "\t" + numToFloatXML(material.spec * 64) + "\n")
xml.fromstring(tabs + "</object>\n")
return xml
def materialToAppearanceXML(material, tabCount):
# converts the material into a java Appearance object
tabs = getTabs(tabCount)
xml = array('c')
xml.fromstring(tabs + "<object class=\"javax.media.j3d.Appearance\">\n")
xml.fromstring(tabs + "\t<void property=\"material\">\n")
xml.extend(materialToMaterialXML(material, tabCount + 2))
xml.fromstring(tabs + "\t</void>\n")
xml.fromstring(tabs + "</object>\n")
return xml
def outputXML(xml, filename):
# outputs the xml to the file
outXML = array('c', "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<java version=\"1.4.1_01\" class=\"java.beans.XMLDecoder\">\n")
outXML.extend(xml)
outXML.fromstring("</java>")
if (gzipmode.val):
gzfile = gzip.open(filename+".gz", "w")
gzfile.write(outXML)
#gzfile.flush()
gzfile.close()
else :
openfile = open(filename, "wb")
outXML.tofile(openfile)
openfile.flush()
openfile.close()
print "wrote " + filename
# gui stuff....
DEFAULT_OUT_DIR = "D:\\Source\\Java3d\\compose3D\\Models\\Codici"
outdir = Create('')
gzipmode = Create(0)
# event constants
exportevt = 1
outevt = 2
gzipmodeevt = 3
def gui():
global gzipmode
global outdir
glClearColor(0.5,0.5,0.5, 0.0)
glClear(GL_COLOR_BUFFER_BIT)
glRasterPos2i(40, 70)
Text("Export selected meshes (ESC to exit) ")
Button("Start export!", exportevt, 40, 40, 150, 19)
glColor3f(1,1,1)
outdir = String("Output Dir: ",outevt,40,110,400,19,DEFAULT_OUT_DIR,220)
print outdir.val
gzipmode = Toggle("gzip output format", gzipmodeevt,40, 130, 130, 19, gzipmode.val)
#print gzipmode.val
def event(evt, val):
if (evt == ESCKEY and not val): Exit()
def bevent(evt):
if (evt == exportevt): StartExport()
Register(gui, event, bevent)
def StartExport():
# let's create the path if it doesn't exist
if (not os.path.exists(outdir.val)):
print outdir.val
os.mkdir(outdir.val)
print " directory "+outdir.val+" created"
objList = Blender.Object.GetSelected()
for obj in objList :
mesh = obj.getData()
print mesh
moo = meshToShape3DXMLList(mesh, 1)
for i in range(0, len(moo)):
if (mesh.hasFaceUV()) :
outputXML(moo[i],os.path.join(outdir.val, mesh.materials[i].name + ".00" +str(i)+".textured."+ mesh.name + ".Shape3D.xml") )
else:
outputXML(moo[i],os.path.join(outdir.val, mesh.materials[i].name + ".00" +str(i)+"."+ mesh.name + ".Shape3D.xml"))
print("done")
|