def _writeVertices(self, file): vtype = self.material.getVertexType() if vtype == iMaterials.EVT_STANDARD: svtype = 'standard' elif vtype == iMaterials.EVT_2TCOORDS: svtype = '2tcoords' elif vtype == iMaterials.EVT_TANGENTS: svtype = 'tangents' file.write(' <vertices type="%s" vertexCount="%d">\n' % (svtype, len(self.vertices))) meshName = self.bMesh.name tverts = len(self.vertices) vcount = 0 mcount = 100 bnum = self.bufNumber if tverts > 10000: mcount = 1000 for vert in self.vertices: if iGUI.exportCancelled(): return self._writeVertex(file, vert, vtype) vcount += 1 if (vcount % mcount) == 0: iGUI.updateStatus('Exporting Mesh: %s, buf: %d writing vertices(%d of %d)' % (meshName, bnum, vcount, tverts)) file.write(' </vertices>\n')
def _writeFaces(self, file): file.write(' <indices indexCount="%d">\n' % (len(self.faces)*3)) line = ' ' iCount = 0 meshName = self.bMesh.name tfaces = len(self.faces) fcount = 0 bnum = self.bufNumber for face in self.faces: if iGUI.exportCancelled(): return line += (' %d %d %d' % (face[2], face[1], face[0])) iCount += 1 if iCount == 12: line += '\n' file.write(line) line = ' ' iCount = 0 fcount += 1 if (fcount % 100) == 0: iGUI.updateStatus('Exporting Mesh: %s, buf: %d writing faces(%d of %d)' % (meshName, bnum, fcount, tfaces)) if iCount > 0: line += '\n' file.write(line) file.write(' </indices>\n')
def _savePackedTexture(self, bImage): if bImage in self.copiedImages: return # # can't use bpy.data.image here because it _doesn't_ support 32 # bit images, so the alpha channel would be lost for input # images that have one. this way is also much faster... # filename = self.getImageFileName("", bImage, 1) if filename == None: return iGUI.updateStatus("Saving Packed Texture " + filename + "...") self.copiedImages.append(bImage) if self.gTexExtension != ".???": iTGAWriter.writeTGA(bImage, filename, True) else: saveName = bImage.getFilename() bImage.setFilename(filename) bImage.save() bImage.setFilename(saveName)
def _copyExternalImage(self, bImage): if bImage in self.copiedImages: return self.copiedImages.append(bImage) filename = self.getImageFileName("", bImage, 1) if filename == None: return ofilename = bImage.getFilename() iGUI.updateStatus("Copying external image " + ofilename + "...") shutil.copy2(ofilename, filename)
def _convertMesh(self, iname, oname): iGUI.updateStatus("Creating Binary Mesh: " + oname) meshcvt = iGUI.gMeshCvtPath directory = Blender.sys.dirname(meshcvt) cmdline = meshcvt + " -v " + self.gIrrlichtVersion + ' -i "' + iname + '" -o "' + oname cmdline += '" -a "' + iUtils.filterPath(self.gBaseDir) + '"' print(cmdline) try: subprocess.call(cmdline, shell=True, cwd=directory) except: self.gFatalError = "Error Converting To Binary Mesh. Check imeshcvt setup."
def _writeMorphTarget(self, file, idx): block = self.bKeyBlocks[idx] # # first, count the number of vertices we'll be writing # vidx = 0 for vert in self.vertices: if iGUI.exportCancelled(): return bvert = vert.pos[0] pos = vert.pos[idx] if (bvert.x != pos.x) or (bvert.y != pos.y) or (bvert.z != pos.z): vidx += 1 file.write(' <morph-target name="%s" vertexCount="%d">\n' % (block.name,vidx)) meshName = self.bMesh.name tverts = len(self.vertices) vcount = 0 mcount = 100 bnum = self.bufNumber if tverts > 10000: mcount = 1000 vidx = 0 for vert in self.vertices: if iGUI.exportCancelled(): return bvert = vert.pos[0] pos = vert.pos[idx] if (bvert.x != pos.x) or (bvert.y != pos.y) or (bvert.z != pos.z): spos = '%d %.6f %.6f %.6f ' % (vidx, pos.x, pos.z, pos.y) file.write(' ' + spos + '\n') vidx += 1 vcount += 1 if (vcount % mcount) == 0: iGUI.updateStatus('Exporting Mesh: %s, buf: %d writing vertices(%d of %d)' % (meshName, bnum, vcount, tverts)) file.write(' </morph-target>\n')
def doExport(self): self.gFatalError = None self.gImageInfo = {} iGUI.updateStatus("Exporting...") start = time.clock() # exit edit mode if necessary editMode = Blender.Window.EditMode() if editMode: Blender.Window.EditMode(0) # # use this to track exported mesh data. multiple mesh objects may # reference the same mesh data. irrb only export's a single copy # self.gExportedMeshes = [] self.gExportedMeshesLC = [] self.gMeshNameConflicts = [] # # export objects from the current scene # self.gScene = Blender.Scene.GetCurrent() self.gSceneLayers = self.gScene.getLayers() self.gActions = Blender.Armature.NLA.GetActions() # # initialize .irr scene file if requested # logName = "" if self.gCreateScene: try: if not self.gSceneDir.endswith(Blender.sys.sep): self.gSceneDir += Blender.sys.sep self.gSceneFileName = self.gSceneDir + self.gScene.getName() + ".irr" self.sfile = open(self.gSceneFileName, "w") self.iScene = iScene.Scene(self) self.iScene.writeSceneHeader(self.sfile, self.gScene, self.gExportPhysics) except IOError, (errno, strerror): self.sfile = None self.gSceneFileName = None
def createBuffers(self): if self.debug: debug('Restrict Display: ' + str(self.bObject.restrictDisplay)) debug('Restrict Render: ' + str(self.bObject.restrictRender)) lnames = '' for name in self.uvLayerNames: if len(lnames): lnames += ', ' lnames += name debug('UV Layers (%d): %s' % (len(self.uvLayerNames), lnames)) mname = 'None' if self.uvMatName != None: mname = self.uvMatName debug('Primary UV Layer: ' + mname) psystems = self.bObject.getParticleSystems() pnames = '' for psys in psystems: if len(pnames): pnames += ', ' pnames += psys.getName() debug('Particle Systems (%d): %s' % (len(psystems), pnames)) val = 'False' if (self.bMesh.mode & Blender.Mesh.Modes['TWOSIDED']): val = 'True' debug('Double Sided: ' + val) if self.bMesh.vertexColors: val = 'True' else: val = 'False' debug('Mesh VertexColors: ' + val) # # dump shape keys # if self.bKey: debug('Mesh Key: True') debug('Mesh Key Blocks Count: %d' % len(self.bKeyBlocks)) i = 1 for block in self.bKeyBlocks: debug(' Block %d, Name: %s, Length: %d' % (i,block.name, len(block.data))) i += 1 debug('Mesh Key IPO: %s' % str(self.bKey.ipo)) else: debug('Mesh Key: None') # # dump ipo's # ipos = self.bObject.ipo if ipos: debug('Mesh ipo: %s' % str(ipos)) else: debug('Mesh ipo: None') # # dump modifiers # mods = self.bObject.modifiers if mods: debug('Modifiers:') for mod in mods: stype = self._getModType(mod) debug(' Name: %s, Type: %s' % (mod.name,stype)) else: debug('Modifiers: None') # # dump armatures # if len(self.armatures) > 0: debug('Armatures:') for arm in self.armatures: debug(' Name: %s, Bone Count: %d' % (arm.name,len(arm.bones))) else: debug('Armatures: None') # # dump actions # ''' act = self.bObject.action print 'bObject.action', act, type(act) if act != None: print ' Action Name', act.name strips = self.bObject.actionStrips print 'bObject.actionstrips', strips, type(strips) if strips != None: print ' ActionStrips size: ', len(strips) print ' ActionStrips __len__: ', strips.__len__() ''' # # dump physics # OB_OCCLUDER = 0x40000 OB_SENSOR = 0x80000 pflags = [] rbFlags = self.bObject.rbFlags showMass = False if not (rbFlags & 0x10000): # shhhh :) pflags.append('NO COLLISION') else: if rbFlags & Blender.Object.RBFlags['ACTOR']: pflags.append('ACTOR') if rbFlags & Blender.Object.RBFlags['PROP']: pflags.append('PROP') if rbFlags & Blender.Object.RBFlags['DYNAMIC']: showMass = True pflags.append('DYNAMIC') if rbFlags & Blender.Object.RBFlags['GHOST']: pflags.append('GHOST') if rbFlags & Blender.Object.RBFlags['RIGIDBODY']: showMass = True pflags.append('RIGIDBODY') if rbFlags & Blender.Object.RBFlags['COLLISION_RESPONSE']: pflags.append('RESPONSE') if rbFlags & Blender.Object.RBFlags['BOUNDS']: pflags.append('BOUNDS') if rbFlags & Blender.Object.RBFlags['CHILD']: pflags.append('COMPOUND') if rbFlags & OB_OCCLUDER: pflags.append('OCCLUDER') if rbFlags & OB_SENSOR: pflags.append('SENSOR') debug('rbflags:' + ('%x' % rbFlags)) debug('pflags: ' + str(pflags)) debug('isSoftBody: ' + str(self.bObject.isSB())) if rbFlags & Blender.Object.RBFlags['BOUNDS']: ShapeType = self.bObject.rbShapeBoundType if ShapeType == 0: sShapeType = 'box' elif ShapeType == 1: sShapeType = 'sphere' elif ShapeType == 2: sShapeType = 'cylinder' elif ShapeType == 3: sShapeType = 'cone' elif ShapeType == 4: sShapeType = 'trimesh' elif ShapeType == 5: sShapeType = 'convexhull' debug('bound shape: ' + sShapeType); if showMass: debug('mass: %.2f' % self.bObject.rbMass) debug('radius: %.2f' % self.bObject.rbRadius) # # dump constraints # constraints = self.bObject.constraints for constraint in constraints: if constraint.type == Blender.Constraint.Type['RIGIDBODYJOINT']: rbcType =constraint[Blender.Constraint.Settings['CONSTR_RB_TYPE']] #rbcType isn't matching these constants... #print(Blender.Constraint.Settings['CONSTR_RB_FLAG']) #print(Blender.Constraint.Settings['CONSTR_RB_HINGE']) #print(Blender.Constraint.Settings['CONSTR_RB_BALL']) #print(Blender.Constraint.Settings['CONSTR_RB_GENERIC6DOF']) # from DNA_constraint_types.h CONSTRAINT_RB_BALL = 1 CONSTRAINT_RB_HINGE = 2 CONSTRAINT_RB_CONETWIST = 4 CONSTRAINT_RB_VEHICLE = 11 CONSTRAINT_RB_GENERIC6DOF = 12 srbcType = '6dof' if rbcType == CONSTRAINT_RB_BALL: srbcType = 'Hinge' elif rbcType == CONSTRAINT_RB_HINGE: srbcType = 'Ball' pivot = (constraint[Blender.Constraint.Settings['CONSTR_RB_PIVX']], constraint[Blender.Constraint.Settings['CONSTR_RB_PIVY']], constraint[Blender.Constraint.Settings['CONSTR_RB_PIVZ']]) axisrot = (constraint[Blender.Constraint.Settings['CONSTR_RB_AXX']], constraint[Blender.Constraint.Settings['CONSTR_RB_AXY']], constraint[Blender.Constraint.Settings['CONSTR_RB_AXZ']]) debug('rb const: %s' % constraint.name) debug(' type: %d %s' % (rbcType, srbcType)) debug(' pivot: %s' % str(pivot)) debug(' rot: %s' % str(axisrot)) # # Loop through faces and create a new meshBuffer for each unique # material used. Also add face/vertex info into the meshBuffer. # result = True faces = self.bMesh.faces # # the face attributes will be extracted from the uvMatName uvlayer # if (self.uvMatName != None) and (self.uvMatName != self.activeUVLayer): self.bMesh.activeUVLayer = self.uvMatName fcount = 0 tfaces = len(faces) mcount = 100 tangents = self.bMesh.getTangents() for face in faces: if iGUI.exportCancelled(): break; fcount += 1 if (fcount % mcount) == 0: iGUI.updateStatus('Analyzing Mesh Faces: %s, (%d of %d)' % (self.bMesh.name, fcount, tfaces)) # Get the Blender "Procedural" Material for this face. Will be used # for vertex color if a UV texture isn't assigned. Will also be used # in the material name. try: bMaterial = self.bMesh.materials[face.mat] except: bMaterial = None matType = 0 # UV Material (game engine)? if self.hasFaceUV and (face.mode & iUtils.B_MESH_FACEMODE_TEX): matType = 1 # # UV/game materials allow options (two-sided, lighting, # alpha etc.) per face. This is why we include these # settings in the material name - differing options will # create seperate mesh buffers.. # stwosided = '0' # mesh "Double Sided" if ((self.bMesh.mode & iUtils.B_MESH_MODE_TWOSIDED) or (face.mode & iUtils.B_MESH_FACEMODE_TWOSIDE)): stwosided = '1' # face "light" slighting = '0' if (face.mode & iUtils.B_MESH_FACEMODE_LIGHT): slighting = '1' # face "alpha" salpha = '0' if (face.transp & iUtils.B_MESH_FACETRANSPMODE_ALPHA): salpha = '1' # face uvlayer image names faceImageName = self._getFaceImageNames(face) # face blender material index if bMaterial == None: sBlenderMat = '00' else: sBlenderMat = '%02d' % face.mat matName = ('uvmat:' + faceImageName + sBlenderMat + stwosided + slighting + salpha) # Blender Material elif bMaterial != None: matType = 2 matName = 'blender:' + bMaterial.getName() + (':%02d' % face.mat) # Unassigned Material else: matType = 3 matName = 'unassigned' if matName in self.materials: meshBuffer = self.materials[matName] else: # create the material and mesh buffer if matType == 1: # uv material material = iMaterials.UVMaterial(self, self.bObject,matName, self.exporter,face,bMaterial) elif matType == 2: # blender material material = iMaterials.BlenderMaterial(self.bObject,matName, self.exporter,bMaterial) else: # unassigned / default material material = iMaterials.DefaultMaterial(self.bObject,matName, self.exporter,bMaterial) # create the meshbuffer and update the material dict & mesh # buffer list meshBuffer = iMeshBuffer.MeshBuffer(self.bMesh, material, self.uvMatName,len(self.meshBuffers)) self.materials[matName] = meshBuffer self.meshBuffers.append(meshBuffer) meshBuffer.addFace(face, tangents[face.index], self.bKeyBlocks) iGUI.updateStatus('Analyzing Mesh Faces: %s, Done.' % (self.bMesh.name)) if self.debug: debug('\n[Buffers]') debug('Count: %d' % len(self.materials)) for key,val in self.materials.iteritems(): debug(' ' + key + ' : ' + val.getMaterialType()) # # restore the active uv layer if necessary # if self.activeUVLayer != self.bMesh.activeUVLayer: self.bMesh.activeUVLayer = self.activeUVLayer return result
def _exportMesh(self, bObject): # get Mesh meshData = bObject.getData(False, True) oName = bObject.getName() debug("\n[Mesh - ob:%s, me:%s]" % (oName, meshData.name)) self.gMeshFileName = self.gMeshDir + meshData.name + ".irrmesh" binaryMeshFileName = "" if self.gBinary: binaryMeshFileName = self.gMeshDir + meshData.name + ".irrbmesh" iGUI.updateStatus("Exporting Mesh: " + meshData.name + ", Object: " + oName) alreadyExported = self._hasMeshBeenExported(meshData.name) if len(meshData.verts) == 0: msg = "ignoring mesh: %s, no vertices" % meshData.name addWarning(msg) return # # write scene node data to scene (.irr) file # meshFileName = self.gMeshFileName if self.sfile != None: meshFileName = iUtils.relpath(self.gMeshFileName, self.gBaseDir) sceneMeshFileName = meshFileName if self.gBinary: fname, fext = Blender.sys.splitext(meshFileName) sceneMeshFileName = fname + ".irrbmesh" self.iScene.writeMeshObject(self.sfile, sceneMeshFileName, bObject, self.gObjectLevel, self.gExportPhysics) # # have we already exported this mesh data block? # if alreadyExported: return self._addToMeshExportedList(meshData.name) try: file = open(self.gMeshFileName, "w") except: pass irrMesh = iMesh.Mesh(bObject, self, True) if irrMesh.createBuffers() == True: if iGUI.exportCancelled(): file.close() return irrMesh.write(file) if iGUI.exportCancelled(): file.close() return self.gVertCount += irrMesh.getVertexCount() self.gFaceCount += irrMesh.getFaceCount() # write image(s) if any for k, v in irrMesh.getMaterials().iteritems(): if iGUI.exportCancelled(): file.close() return if v.getMaterialType() == "UVMaterial": mat = v.getMaterial() images = mat.getImages() for image in images: self._saveImage(image) file.close() file = None if self.gBinary: self._convertMesh(self.gMeshFileName, binaryMeshFileName)