From 3076f9d8ab0d62629ecddfb9d66dff4dc08d46cd Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 3 Mar 2013 11:39:03 +0900 Subject: [PATCH] Convert prints to operator messages for blender 2.5+ Not everyone has ready access to the output of python scripts, so this should be more friendly, especially for new users who aren't aware they need to have an armature selected. --- blender-2.56/iqm_export.py | 86 +++++++++++++++++++++--------------- blender-2.57/iqm_export.py | 86 +++++++++++++++++++++--------------- blender-2.58/iqm_export.py | 90 ++++++++++++++++++++++---------------- blender-2.59/iqm_export.py | 90 ++++++++++++++++++++++---------------- blender-2.62/iqm_export.py | 90 ++++++++++++++++++++++---------------- blender-2.63/iqm_export.py | 90 ++++++++++++++++++++++---------------- 6 files changed, 310 insertions(+), 222 deletions(-) diff --git a/blender-2.56/iqm_export.py b/blender-2.56/iqm_export.py index f2d0580..54a80e6 100644 --- a/blender-2.56/iqm_export.py +++ b/blender-2.56/iqm_export.py @@ -58,6 +58,22 @@ MAXVCACHE = 32 +def IQMerror(operator, message): + operator.report({'ERROR'}, message) + return {'CANCELLED'} + +def IQMdebug(operator, message): + operator.report({'DEBUG'}, message) + return {'CANCELLED'} + +def IQMwarning(operator, message): + operator.report({'WARNING'}, message) + return None + +def IQMinfo(operator, message): + operator.report({'INFO'}, message) + return None + class Vertex: def __init__(self, index, coord, normal, uv, weights): self.index = index @@ -113,7 +129,8 @@ def __eq__(self, v): class Mesh: - def __init__(self, name, material, verts): + def __init__(self, operator, name, material, verts): + self.operator = operator self.name = name self.material = material self.verts = [ None for v in verts ] @@ -211,10 +228,10 @@ def optimize(self): besttri = i bestscore = score - print('%s: %d verts optimized to %d/%d loads for %d entry LRU cache' % (self.name, len(self.verts), vertloads, len(vertschedule), MAXVCACHE)) - #print('%s: %d verts scheduled to %d' % (self.name, len(self.verts), len(vertschedule))) + IQMdebug(self.operator, '%s: %d verts optimized to %d/%d loads for %d entry LRU cache' % (self.name, len(self.verts), vertloads, len(vertschedule), MAXVCACHE)) + #IQMdebug(self.operator, '%s: %d verts scheduled to %d' % (self.name, len(self.verts), len(vertschedule))) self.verts = vertschedule - # print('%s: %d tris scheduled to %d' % (self.name, len(self.tris), len(trischedule))) + # IQMdebug(self.operator, '%s: %d tris scheduled to %d' % (self.name, len(self.tris), len(trischedule))) self.tris = trischedule def calcNeighbors(self): @@ -413,13 +430,14 @@ def boundsData(self, bones, meshes): invbase.append(bone.matrix.copy().invert()) data = b'' for i, frame in enumerate(self.frames): - print('Calculating bounding box for %s:%d' % (self.name, i)) + IQMdebug(self.operator, 'Calculating bounding box for %s:%d' % (self.name, i)) data += self.frameBoundsData(bones, meshes, frame, invbase) return data class IQMFile: - def __init__(self): + def __init__(self, operator): + self.operator = operator self.textoffsets = {} self.textdata = b'' self.meshes = [] @@ -479,7 +497,7 @@ def calcFrameSize(self): for joint in self.joints: if self.anims: self.posedata.append(joint.poseData(self)) - print('Exporting %d frames of size %d' % (self.numframes, self.framesize)) + IQMdebug(self.operator, 'Exporting %d frames of size %d' % (self.numframes, self.framesize)) def writeVerts(self, file, offset): if self.numverts <= 0: @@ -626,7 +644,7 @@ def findArmature(context): return armature -def derigifyBones(context, armature, scale): +def derigifyBones(operator, context, armature, scale): data = armature.data orgbones = {} @@ -683,11 +701,11 @@ def derigifyBones(context, armature, scale): bonematrix[3][2] *= scale bones[bone.name] = Bone(bname, bone.name, index, bname in defparent and bones.get(defbones[defparent[bname]].name), bonematrix) worklist.extend(defchildren[bname]) - print('De-rigified %d bones' % len(worklist)) + IQMdebug(operator, 'De-rigified %d bones' % len(worklist)) return bones -def collectBones(context, armature, scale): +def collectBones(operator, context, armature, scale): data = armature.data bones = {} worldmatrix = armature.matrix_world @@ -702,16 +720,16 @@ def collectBones(context, armature, scale): for child in bone.children: if child not in worklist: worklist.append(child) - print('Collected %d bones' % len(worklist)) + IQMdebug(operator, 'Collected %d bones' % len(worklist)) return bones -def collectAnim(context, armature, scale, bones, action, startframe = None, endframe = None): +def collectAnim(operator, context, armature, scale, bones, action, startframe = None, endframe = None): if not startframe or not endframe: startframe, endframe = action.frame_range startframe = int(startframe) endframe = int(endframe) - print('Exporting action "%s" frames %d-%d' % (action.name, startframe, endframe)) + IQMdebug(operator, 'Exporting action "%s" frames %d-%d' % (action.name, startframe, endframe)) scene = context.scene worldmatrix = armature.matrix_world armature.animation_data.action = action @@ -743,7 +761,7 @@ def collectAnim(context, armature, scale, bones, action, startframe = None, endf return outdata -def collectAnims(context, armature, scale, bones, animspecs): +def collectAnims(operator, context, armature, scale, bones, animspecs): actions = bpy.data.actions animspecs = [ spec.strip() for spec in animspecs.split(',') ] anims = [] @@ -754,7 +772,7 @@ def collectAnims(context, armature, scale, bones, animspecs): animspec = [ arg.strip() for arg in animspec.split(':') ] animname = animspec[0] if animname not in actions: - print('Action "%s" not found in current armature' % animname) + IQMwarning(operator, 'Action "%s" not found in current armature' % animname) continue try: startframe = int(animspec[1]) @@ -772,14 +790,14 @@ def collectAnims(context, armature, scale, bones, animspecs): flags = int(animspec[4]) except: flags = 0 - framedata = collectAnim(context, armature, scale, bones, actions[animname], startframe, endframe) + framedata = collectAnim(operator, context, armature, scale, bones, actions[animname], startframe, endframe) anims.append(Animation(animname, framedata, fps, flags)) armature.animation_data.action = oldaction scene.frame_set(oldframe) return anims -def collectMeshes(context, bones, scale, matfun, useskel = True, filetype = 'IQM'): +def collectMeshes(operator, context, bones, scale, matfun, useskel = True, filetype = 'IQM'): vertwarn = [] objs = context.selected_objects #context.scene.objects meshes = [] @@ -807,7 +825,7 @@ def collectMeshes(context, bones, scale, matfun, useskel = True, filetype = 'IQM mesh = materials[obj.name, matindex, material] except: matprefix = (data.materials and data.materials[matindex].name) or '' - mesh = Mesh(obj.name, matfun(matprefix, material), data.vertices) + mesh = Mesh(operator, obj.name, matfun(matprefix, material), data.vertices) meshes.append(mesh) materials[obj.name, matindex, material] = mesh @@ -839,7 +857,7 @@ def collectMeshes(context, bones, scale, matfun, useskel = True, filetype = 'IQM except: if (groups[g.group].name, mesh.name) not in vertwarn: vertwarn.append((groups[g.group].name, mesh.name)) - print('Vertex depends on non-existent bone: %s in mesh: %s' % (groups[g.group].name, mesh.name)) + IQMwarning(operator, 'Vertex depends on non-existent bone: %s in mesh: %s' % (groups[g.group].name, mesh.name)) if not face.use_smooth: vertindex = len(verts) @@ -877,7 +895,7 @@ def collectMeshes(context, bones, scale, matfun, useskel = True, filetype = 'IQM if filetype == 'IQM': mesh.calcTangents() mesh.calcNeighbors() - print('%s %s: generated %d triangles' % (mesh.name, mesh.material, len(mesh.tris))) + IQMdebug(operator, '%s %s: generated %d triangles' % (mesh.name, mesh.material, len(mesh.tris))) return meshes @@ -933,39 +951,37 @@ def exportIQE(file, meshes, bones, anims): file.write('\n') -def exportIQM(context, filename, usemesh = True, useskel = True, usebbox = True, scale = 1.0, animspecs = None, matfun = (lambda prefix, image: image), derigify = False): +def exportIQM(operator, context, filename, usemesh = True, useskel = True, usebbox = True, scale = 1.0, animspecs = None, matfun = (lambda prefix, image: image), derigify = False): armature = findArmature(context) if useskel and not armature: - print('No armature selected') - return + return IQMerror('No armature selected') if filename.lower().endswith('.iqm'): filetype = 'IQM' elif filename.lower().endswith('.iqe'): filetype = 'IQE' else: - print('Unknown file type: %s' % filename) - return + return IQMerror('Unknown file type: %s' % filename) if useskel: if derigify: - bones = derigifyBones(context, armature, scale) + bones = derigifyBones(operator, context, armature, scale) else: - bones = collectBones(context, armature, scale) + bones = collectBones(operator, context, armature, scale) else: bones = {} bonelist = sorted(bones.values(), key = lambda bone: bone.index) if usemesh: - meshes = collectMeshes(context, bones, scale, matfun, useskel, filetype) + meshes = collectMeshes(operator, context, bones, scale, matfun, useskel, filetype) else: meshes = [] if useskel and animspecs: - anims = collectAnims(context, armature, scale, bonelist, animspecs) + anims = collectAnims(operator, context, armature, scale, bonelist, animspecs) else: anims = [] if filetype == 'IQM': - iqm = IQMFile() + iqm = IQMFile(operator) iqm.addMeshes(meshes) iqm.addJoints(bonelist) iqm.addAnims(anims) @@ -978,16 +994,16 @@ def exportIQM(context, filename, usemesh = True, useskel = True, usebbox = True, else: file = open(filename, 'w') except: - print ('Failed writing to %s' % (filename)) - return + return IQMerror(operator, 'Failed writing to %s' % (filename)) if filetype == 'IQM': iqm.export(file, usebbox) elif filetype == 'IQE': exportIQE(file, meshes, bonelist, anims) file.close() - print('Saved %s file to %s' % (filetype, filename)) + IQMinfo(operator, 'Saved %s file to %s' % (filetype, filename)) else: - print('No %s file was generated' % (filetype)) + return IQMerror(operator, 'No %s file was generated' % (filetype)) + return {'FINISHED'} class ExportIQM(bpy.types.Operator, ExportHelper): @@ -1009,7 +1025,7 @@ def execute(self, context): matfun = lambda prefix, image: prefix + os.path.splitext(image)[0] else: matfun = lambda prefix, image: image - exportIQM(context, self.properties.filepath, self.properties.usemesh, self.properties.useskel, self.properties.usebbox, self.properties.usescale, self.properties.animspec, matfun, self.properties.derigify) + exportIQM(operator, context, self.properties.filepath, self.properties.usemesh, self.properties.useskel, self.properties.usebbox, self.properties.usescale, self.properties.animspec, matfun, self.properties.derigify) return {'FINISHED'} def check(self, context): diff --git a/blender-2.57/iqm_export.py b/blender-2.57/iqm_export.py index da4ab1d..954a0f6 100644 --- a/blender-2.57/iqm_export.py +++ b/blender-2.57/iqm_export.py @@ -51,6 +51,22 @@ MAXVCACHE = 32 +def IQMerror(operator, message): + operator.report({'ERROR'}, message) + return {'CANCELLED'} + +def IQMdebug(operator, message): + operator.report({'DEBUG'}, message) + return {'CANCELLED'} + +def IQMwarning(operator, message): + operator.report({'WARNING'}, message) + return None + +def IQMinfo(operator, message): + operator.report({'INFO'}, message) + return None + class Vertex: def __init__(self, index, coord, normal, uv, weights): self.index = index @@ -106,7 +122,8 @@ def __eq__(self, v): class Mesh: - def __init__(self, name, material, verts): + def __init__(self, operator, name, material, verts): + self.operator = operator self.name = name self.material = material self.verts = [ None for v in verts ] @@ -205,10 +222,10 @@ def optimize(self): besttri = i bestscore = score - print('%s: %d verts optimized to %d/%d loads for %d entry LRU cache' % (self.name, len(self.verts), vertloads, len(vertschedule), MAXVCACHE)) - #print('%s: %d verts scheduled to %d' % (self.name, len(self.verts), len(vertschedule))) + IQMdebug(self.operator, '%s: %d verts optimized to %d/%d loads for %d entry LRU cache' % (self.name, len(self.verts), vertloads, len(vertschedule), MAXVCACHE)) + #IQMdebug(self.operator, '%s: %d verts scheduled to %d' % (self.name, len(self.verts), len(vertschedule))) self.verts = vertschedule - # print('%s: %d tris scheduled to %d' % (self.name, len(self.tris), len(trischedule))) + # IQMdebug(self.operator, '%s: %d tris scheduled to %d' % (self.name, len(self.tris), len(trischedule))) self.tris = trischedule def calcNeighbors(self): @@ -408,13 +425,14 @@ def boundsData(self, bones, meshes): invbase.append(bone.matrix.inverted()) data = b'' for i, frame in enumerate(self.frames): - print('Calculating bounding box for %s:%d' % (self.name, i)) + IQMdebug(self.operator, 'Calculating bounding box for %s:%d' % (self.name, i)) data += self.frameBoundsData(bones, meshes, frame, invbase) return data class IQMFile: - def __init__(self): + def __init__(self, operator): + self.operator = operator self.textoffsets = {} self.textdata = b'' self.meshes = [] @@ -474,7 +492,7 @@ def calcFrameSize(self): for joint in self.joints: if self.anims: self.posedata.append(joint.poseData(self)) - print('Exporting %d frames of size %d' % (self.numframes, self.framesize)) + IQMdebug(self.operator, 'Exporting %d frames of size %d' % (self.numframes, self.framesize)) def writeVerts(self, file, offset): if self.numverts <= 0: @@ -621,7 +639,7 @@ def findArmature(context): return armature -def derigifyBones(context, armature, scale): +def derigifyBones(operator, context, armature, scale): data = armature.data orgbones = {} @@ -678,11 +696,11 @@ def derigifyBones(context, armature, scale): bonematrix[3][2] *= scale bones[bone.name] = Bone(bname, bone.name, index, bname in defparent and bones.get(defbones[defparent[bname]].name), bonematrix) worklist.extend(defchildren[bname]) - print('De-rigified %d bones' % len(worklist)) + IQMdebug(operator, 'De-rigified %d bones' % len(worklist)) return bones -def collectBones(context, armature, scale): +def collectBones(operator, context, armature, scale): data = armature.data bones = {} worldmatrix = armature.matrix_world @@ -697,16 +715,16 @@ def collectBones(context, armature, scale): for child in bone.children: if child not in worklist: worklist.append(child) - print('Collected %d bones' % len(worklist)) + IQMdebug(operator, 'Collected %d bones' % len(worklist)) return bones -def collectAnim(context, armature, scale, bones, action, startframe = None, endframe = None): +def collectAnim(operator, context, armature, scale, bones, action, startframe = None, endframe = None): if not startframe or not endframe: startframe, endframe = action.frame_range startframe = int(startframe) endframe = int(endframe) - print('Exporting action "%s" frames %d-%d' % (action.name, startframe, endframe)) + IQMdebug(operator, 'Exporting action "%s" frames %d-%d' % (action.name, startframe, endframe)) scene = context.scene worldmatrix = armature.matrix_world armature.animation_data.action = action @@ -739,7 +757,7 @@ def collectAnim(context, armature, scale, bones, action, startframe = None, endf return outdata -def collectAnims(context, armature, scale, bones, animspecs): +def collectAnims(operator, context, armature, scale, bones, animspecs): actions = bpy.data.actions animspecs = [ spec.strip() for spec in animspecs.split(',') ] anims = [] @@ -750,7 +768,7 @@ def collectAnims(context, armature, scale, bones, animspecs): animspec = [ arg.strip() for arg in animspec.split(':') ] animname = animspec[0] if animname not in actions: - print('Action "%s" not found in current armature' % animname) + IQMwarning(operator, 'Action "%s" not found in current armature' % animname) continue try: startframe = int(animspec[1]) @@ -768,14 +786,14 @@ def collectAnims(context, armature, scale, bones, animspecs): flags = int(animspec[4]) except: flags = 0 - framedata = collectAnim(context, armature, scale, bones, actions[animname], startframe, endframe) + framedata = collectAnim(operator, context, armature, scale, bones, actions[animname], startframe, endframe) anims.append(Animation(animname, framedata, fps, flags)) armature.animation_data.action = oldaction scene.frame_set(oldframe) return anims -def collectMeshes(context, bones, scale, matfun, useskel = True, filetype = 'IQM'): +def collectMeshes(operator, context, bones, scale, matfun, useskel = True, filetype = 'IQM'): vertwarn = [] objs = context.selected_objects #context.scene.objects meshes = [] @@ -803,7 +821,7 @@ def collectMeshes(context, bones, scale, matfun, useskel = True, filetype = 'IQM mesh = materials[obj.name, matindex, material] except: matprefix = (data.materials and data.materials[matindex].name) or '' - mesh = Mesh(obj.name, matfun(matprefix, material), data.vertices) + mesh = Mesh(operator, obj.name, matfun(matprefix, material), data.vertices) meshes.append(mesh) materials[obj.name, matindex, material] = mesh @@ -836,7 +854,7 @@ def collectMeshes(context, bones, scale, matfun, useskel = True, filetype = 'IQM except: if (groups[g.group].name, mesh.name) not in vertwarn: vertwarn.append((groups[g.group].name, mesh.name)) - print('Vertex depends on non-existent bone: %s in mesh: %s' % (groups[g.group].name, mesh.name)) + IQMwarning(operator, 'Vertex depends on non-existent bone: %s in mesh: %s' % (groups[g.group].name, mesh.name)) if not face.use_smooth: vertindex = len(verts) @@ -874,7 +892,7 @@ def collectMeshes(context, bones, scale, matfun, useskel = True, filetype = 'IQM if filetype == 'IQM': mesh.calcTangents() mesh.calcNeighbors() - print('%s %s: generated %d triangles' % (mesh.name, mesh.material, len(mesh.tris))) + IQMdebug(operator, '%s %s: generated %d triangles' % (mesh.name, mesh.material, len(mesh.tris))) return meshes @@ -931,39 +949,37 @@ def exportIQE(file, meshes, bones, anims): file.write('\n') -def exportIQM(context, filename, usemesh = True, useskel = True, usebbox = True, scale = 1.0, animspecs = None, matfun = (lambda prefix, image: image), derigify = False): +def exportIQM(operator, context, filename, usemesh = True, useskel = True, usebbox = True, scale = 1.0, animspecs = None, matfun = (lambda prefix, image: image), derigify = False): armature = findArmature(context) if useskel and not armature: - print('No armature selected') - return + return IQMerror('No armature selected') if filename.lower().endswith('.iqm'): filetype = 'IQM' elif filename.lower().endswith('.iqe'): filetype = 'IQE' else: - print('Unknown file type: %s' % filename) - return + return IQMerror('Unknown file type: %s' % filename) if useskel: if derigify: - bones = derigifyBones(context, armature, scale) + bones = derigifyBones(operator, context, armature, scale) else: - bones = collectBones(context, armature, scale) + bones = collectBones(operator, context, armature, scale) else: bones = {} bonelist = sorted(bones.values(), key = lambda bone: bone.index) if usemesh: - meshes = collectMeshes(context, bones, scale, matfun, useskel, filetype) + meshes = collectMeshes(operator, context, bones, scale, matfun, useskel, filetype) else: meshes = [] if useskel and animspecs: - anims = collectAnims(context, armature, scale, bonelist, animspecs) + anims = collectAnims(operator, context, armature, scale, bonelist, animspecs) else: anims = [] if filetype == 'IQM': - iqm = IQMFile() + iqm = IQMFile(operator) iqm.addMeshes(meshes) iqm.addJoints(bonelist) iqm.addAnims(anims) @@ -976,16 +992,16 @@ def exportIQM(context, filename, usemesh = True, useskel = True, usebbox = True, else: file = open(filename, 'w') except: - print ('Failed writing to %s' % (filename)) - return + return IQMerror(operator, 'Failed writing to %s' % (filename)) if filetype == 'IQM': iqm.export(file, usebbox) elif filetype == 'IQE': exportIQE(file, meshes, bonelist, anims) file.close() - print('Saved %s file to %s' % (filetype, filename)) + IQMinfo(operator, 'Saved %s file to %s' % (filetype, filename)) else: - print('No %s file was generated' % (filetype)) + return IQMerror(operator, 'No %s file was generated' % (filetype)) + return {'FINISHED'} class ExportIQM(bpy.types.Operator, ExportHelper): @@ -1007,7 +1023,7 @@ def execute(self, context): matfun = lambda prefix, image: prefix + os.path.splitext(image)[0] else: matfun = lambda prefix, image: image - exportIQM(context, self.properties.filepath, self.properties.usemesh, self.properties.useskel, self.properties.usebbox, self.properties.usescale, self.properties.animspec, matfun, self.properties.derigify) + exportIQM(operator, context, self.properties.filepath, self.properties.usemesh, self.properties.useskel, self.properties.usebbox, self.properties.usescale, self.properties.animspec, matfun, self.properties.derigify) return {'FINISHED'} def check(self, context): diff --git a/blender-2.58/iqm_export.py b/blender-2.58/iqm_export.py index 8134b44..bde5622 100644 --- a/blender-2.58/iqm_export.py +++ b/blender-2.58/iqm_export.py @@ -51,6 +51,22 @@ MAXVCACHE = 32 +def IQMerror(operator, message): + operator.report({'ERROR'}, message) + return {'CANCELLED'} + +def IQMdebug(operator, message): + operator.report({'DEBUG'}, message) + return {'CANCELLED'} + +def IQMwarning(operator, message): + operator.report({'WARNING'}, message) + return None + +def IQMinfo(operator, message): + operator.report({'INFO'}, message) + return None + class Vertex: def __init__(self, index, coord, normal, uv, weights, color): self.index = index @@ -107,7 +123,8 @@ def __eq__(self, v): class Mesh: - def __init__(self, name, material, verts): + def __init__(self, operator, name, material, verts): + self.operator = operator self.name = name self.material = material self.verts = [ None for v in verts ] @@ -206,10 +223,10 @@ def optimize(self): besttri = i bestscore = score - print('%s: %d verts optimized to %d/%d loads for %d entry LRU cache' % (self.name, len(self.verts), vertloads, len(vertschedule), MAXVCACHE)) - #print('%s: %d verts scheduled to %d' % (self.name, len(self.verts), len(vertschedule))) + IQMdebug(self.operator, '%s: %d verts optimized to %d/%d loads for %d entry LRU cache' % (self.name, len(self.verts), vertloads, len(vertschedule), MAXVCACHE)) + #IQMdebug(self.operator, '%s: %d verts scheduled to %d' % (self.name, len(self.verts), len(vertschedule))) self.verts = vertschedule - # print('%s: %d tris scheduled to %d' % (self.name, len(self.tris), len(trischedule))) + # IQMdebug(self.operator, '%s: %d tris scheduled to %d' % (self.name, len(self.tris), len(trischedule))) self.tris = trischedule def calcNeighbors(self): @@ -409,13 +426,14 @@ def boundsData(self, bones, meshes): invbase.append(bone.matrix.inverted()) data = b'' for i, frame in enumerate(self.frames): - print('Calculating bounding box for %s:%d' % (self.name, i)) + IQMdebug(self.operator, 'Calculating bounding box for %s:%d' % (self.name, i)) data += self.frameBoundsData(bones, meshes, frame, invbase) return data class IQMFile: - def __init__(self): + def __init__(self, operator): + self.operator = operator self.textoffsets = {} self.textdata = b'' self.meshes = [] @@ -475,7 +493,7 @@ def calcFrameSize(self): for joint in self.joints: if self.anims: self.posedata.append(joint.poseData(self)) - print('Exporting %d frames of size %d' % (self.numframes, self.framesize)) + IQMdebug(self.operator, 'Exporting %d frames of size %d' % (self.numframes, self.framesize)) def writeVerts(self, file, offset): if self.numverts <= 0: @@ -638,7 +656,7 @@ def findArmature(context): return armature -def derigifyBones(context, armature, scale): +def derigifyBones(operator, context, armature, scale): data = armature.data orgbones = {} @@ -695,11 +713,11 @@ def derigifyBones(context, armature, scale): bonematrix[3][2] *= scale bones[bone.name] = Bone(bname, bone.name, index, bname in defparent and bones.get(defbones[defparent[bname]].name), bonematrix) worklist.extend(defchildren[bname]) - print('De-rigified %d bones' % len(worklist)) + IQMdebug(operator, 'De-rigified %d bones' % len(worklist)) return bones -def collectBones(context, armature, scale): +def collectBones(operator, context, armature, scale): data = armature.data bones = {} worldmatrix = armature.matrix_world @@ -714,16 +732,16 @@ def collectBones(context, armature, scale): for child in bone.children: if child not in worklist: worklist.append(child) - print('Collected %d bones' % len(worklist)) + IQMdebug(operator, 'Collected %d bones' % len(worklist)) return bones -def collectAnim(context, armature, scale, bones, action, startframe = None, endframe = None): +def collectAnim(operator, context, armature, scale, bones, action, startframe = None, endframe = None): if not startframe or not endframe: startframe, endframe = action.frame_range startframe = int(startframe) endframe = int(endframe) - print('Exporting action "%s" frames %d-%d' % (action.name, startframe, endframe)) + IQMdebug(operator, 'Exporting action "%s" frames %d-%d' % (action.name, startframe, endframe)) scene = context.scene worldmatrix = armature.matrix_world armature.animation_data.action = action @@ -756,9 +774,9 @@ def collectAnim(context, armature, scale, bones, action, startframe = None, endf return outdata -def collectAnims(context, armature, scale, bones, animspecs): +def collectAnims(operator, context, armature, scale, bones, animspecs): if not armature.animation_data: - print('Armature has no animation data') + IQMwarning(operator, 'Armature has no animation data') return [] actions = bpy.data.actions animspecs = [ spec.strip() for spec in animspecs.split(',') ] @@ -770,7 +788,7 @@ def collectAnims(context, armature, scale, bones, animspecs): animspec = [ arg.strip() for arg in animspec.split(':') ] animname = animspec[0] if animname not in actions: - print('Action "%s" not found in current armature' % animname) + IQMwarning(operator, 'Action "%s" not found in current armature' % animname) continue try: startframe = int(animspec[1]) @@ -788,14 +806,14 @@ def collectAnims(context, armature, scale, bones, animspecs): flags = int(animspec[4]) except: flags = 0 - framedata = collectAnim(context, armature, scale, bones, actions[animname], startframe, endframe) + framedata = collectAnim(operator, context, armature, scale, bones, actions[animname], startframe, endframe) anims.append(Animation(animname, framedata, fps, flags)) armature.animation_data.action = oldaction scene.frame_set(oldframe) return anims -def collectMeshes(context, bones, scale, matfun, useskel = True, usecol = False, filetype = 'IQM'): +def collectMeshes(operator, context, bones, scale, matfun, useskel = True, usecol = False, filetype = 'IQM'): vertwarn = [] objs = context.selected_objects #context.scene.objects meshes = [] @@ -825,7 +843,7 @@ def collectMeshes(context, bones, scale, matfun, useskel = True, usecol = False, mesh = materials[obj.name, matindex, material] except: matprefix = (data.materials and data.materials[matindex].name) or '' - mesh = Mesh(obj.name, matfun(matprefix, material), data.vertices) + mesh = Mesh(operator, obj.name, matfun(matprefix, material), data.vertices) meshes.append(mesh) materials[obj.name, matindex, material] = mesh @@ -871,7 +889,7 @@ def collectMeshes(context, bones, scale, matfun, useskel = True, usecol = False, except: if (groups[g.group].name, mesh.name) not in vertwarn: vertwarn.append((groups[g.group].name, mesh.name)) - print('Vertex depends on non-existent bone: %s in mesh: %s' % (groups[g.group].name, mesh.name)) + IQMwarning(operator, 'Vertex depends on non-existent bone: %s in mesh: %s' % (groups[g.group].name, mesh.name)) if not face.use_smooth: vertindex = len(verts) @@ -909,7 +927,7 @@ def collectMeshes(context, bones, scale, matfun, useskel = True, usecol = False, if filetype == 'IQM': mesh.calcTangents() mesh.calcNeighbors() - print('%s %s: generated %d triangles' % (mesh.name, mesh.material, len(mesh.tris))) + IQMdebug(operator, '%s %s: generated %d triangles' % (mesh.name, mesh.material, len(mesh.tris))) return meshes @@ -971,40 +989,37 @@ def exportIQE(file, meshes, bones, anims): file.write('\n') - -def exportIQM(context, filename, usemesh = True, useskel = True, usebbox = True, usecol = False, scale = 1.0, animspecs = None, matfun = (lambda prefix, image: image), derigify = False): +def exportIQM(operator, context, filename, usemesh = True, useskel = True, usebbox = True, usecol = False, scale = 1.0, animspecs = None, matfun = (lambda prefix, image: image), derigify = False): armature = findArmature(context) if useskel and not armature: - print('No armature selected') - return + return IQMerror(operator, 'No armature selected') if filename.lower().endswith('.iqm'): filetype = 'IQM' elif filename.lower().endswith('.iqe'): filetype = 'IQE' else: - print('Unknown file type: %s' % filename) - return + return IQMerror(operator, 'Unknown file type: %s' % filename) if useskel: if derigify: - bones = derigifyBones(context, armature, scale) + bones = derigifyBones(operator, context, armature, scale) else: - bones = collectBones(context, armature, scale) + bones = collectBones(operator, context, armature, scale) else: bones = {} bonelist = sorted(bones.values(), key = lambda bone: bone.index) if usemesh: - meshes = collectMeshes(context, bones, scale, matfun, useskel, usecol, filetype) + meshes = collectMeshes(operator, context, bones, scale, matfun, useskel, usecol, filetype) else: meshes = [] if useskel and animspecs: - anims = collectAnims(context, armature, scale, bonelist, animspecs) + anims = collectAnims(operator, context, armature, scale, bonelist, animspecs) else: anims = [] if filetype == 'IQM': - iqm = IQMFile() + iqm = IQMFile(operator) iqm.addMeshes(meshes) iqm.addJoints(bonelist) iqm.addAnims(anims) @@ -1017,16 +1032,16 @@ def exportIQM(context, filename, usemesh = True, useskel = True, usebbox = True, else: file = open(filename, 'w') except: - print ('Failed writing to %s' % (filename)) - return + return IQMerror(operator, 'Failed writing to %s' % (filename)) if filetype == 'IQM': iqm.export(file, usebbox) elif filetype == 'IQE': exportIQE(file, meshes, bonelist, anims) file.close() - print('Saved %s file to %s' % (filetype, filename)) + IQMinfo(operator, 'Saved %s file to %s' % (filetype, filename)) else: - print('No %s file was generated' % (filetype)) + return IQMerror(operator, 'No %s file was generated' % (filetype)) + return {'FINISHED'} class ExportIQM(bpy.types.Operator, ExportHelper): @@ -1049,8 +1064,7 @@ def execute(self, context): matfun = lambda prefix, image: prefix + os.path.splitext(image)[0] else: matfun = lambda prefix, image: image - exportIQM(context, self.properties.filepath, self.properties.usemesh, self.properties.useskel, self.properties.usebbox, self.properties.usecol, self.properties.usescale, self.properties.animspec, matfun, self.properties.derigify) - return {'FINISHED'} + return exportIQM(self, context, self.properties.filepath, self.properties.usemesh, self.properties.useskel, self.properties.usebbox, self.properties.usecol, self.properties.usescale, self.properties.animspec, matfun, self.properties.derigify) def check(self, context): filepath = bpy.path.ensure_ext(self.filepath, '.iqm') diff --git a/blender-2.59/iqm_export.py b/blender-2.59/iqm_export.py index 321b883..f53cf8c 100644 --- a/blender-2.59/iqm_export.py +++ b/blender-2.59/iqm_export.py @@ -51,6 +51,22 @@ MAXVCACHE = 32 +def IQMerror(operator, message): + operator.report({'ERROR'}, message) + return {'CANCELLED'} + +def IQMdebug(operator, message): + operator.report({'DEBUG'}, message) + return {'CANCELLED'} + +def IQMwarning(operator, message): + operator.report({'WARNING'}, message) + return None + +def IQMinfo(operator, message): + operator.report({'INFO'}, message) + return None + class Vertex: def __init__(self, index, coord, normal, uv, weights, color): self.index = index @@ -107,7 +123,8 @@ def __eq__(self, v): class Mesh: - def __init__(self, name, material, verts): + def __init__(self, operator, name, material, verts): + self.operator = operator self.name = name self.material = material self.verts = [ None for v in verts ] @@ -206,10 +223,10 @@ def optimize(self): besttri = i bestscore = score - print('%s: %d verts optimized to %d/%d loads for %d entry LRU cache' % (self.name, len(self.verts), vertloads, len(vertschedule), MAXVCACHE)) - #print('%s: %d verts scheduled to %d' % (self.name, len(self.verts), len(vertschedule))) + IQMdebug(self.operator, '%s: %d verts optimized to %d/%d loads for %d entry LRU cache' % (self.name, len(self.verts), vertloads, len(vertschedule), MAXVCACHE)) + #IQMdebug(self.operator, '%s: %d verts scheduled to %d' % (self.name, len(self.verts), len(vertschedule))) self.verts = vertschedule - # print('%s: %d tris scheduled to %d' % (self.name, len(self.tris), len(trischedule))) + # IQMdebug(self.operator, '%s: %d tris scheduled to %d' % (self.name, len(self.tris), len(trischedule))) self.tris = trischedule def calcNeighbors(self): @@ -409,13 +426,14 @@ def boundsData(self, bones, meshes): invbase.append(bone.matrix.inverted()) data = b'' for i, frame in enumerate(self.frames): - print('Calculating bounding box for %s:%d' % (self.name, i)) + IQMdebug(self.operator, 'Calculating bounding box for %s:%d' % (self.name, i)) data += self.frameBoundsData(bones, meshes, frame, invbase) return data class IQMFile: - def __init__(self): + def __init__(self, operator): + self.operator = operator self.textoffsets = {} self.textdata = b'' self.meshes = [] @@ -475,7 +493,7 @@ def calcFrameSize(self): for joint in self.joints: if self.anims: self.posedata.append(joint.poseData(self)) - print('Exporting %d frames of size %d' % (self.numframes, self.framesize)) + IQMdebug(self.operator, 'Exporting %d frames of size %d' % (self.numframes, self.framesize)) def writeVerts(self, file, offset): if self.numverts <= 0: @@ -638,7 +656,7 @@ def findArmature(context): return armature -def derigifyBones(context, armature, scale): +def derigifyBones(operator, context, armature, scale): data = armature.data orgbones = {} @@ -695,11 +713,11 @@ def derigifyBones(context, armature, scale): bonematrix[3][2] *= scale bones[bone.name] = Bone(bname, bone.name, index, bname in defparent and bones.get(defbones[defparent[bname]].name), bonematrix) worklist.extend(defchildren[bname]) - print('De-rigified %d bones' % len(worklist)) + IQMdebug(operator, 'De-rigified %d bones' % len(worklist)) return bones -def collectBones(context, armature, scale): +def collectBones(operator, context, armature, scale): data = armature.data bones = {} worldmatrix = armature.matrix_world @@ -714,16 +732,16 @@ def collectBones(context, armature, scale): for child in bone.children: if child not in worklist: worklist.append(child) - print('Collected %d bones' % len(worklist)) + IQMdebug(operator, 'Collected %d bones' % len(worklist)) return bones -def collectAnim(context, armature, scale, bones, action, startframe = None, endframe = None): +def collectAnim(operator, context, armature, scale, bones, action, startframe = None, endframe = None): if not startframe or not endframe: startframe, endframe = action.frame_range startframe = int(startframe) endframe = int(endframe) - print('Exporting action "%s" frames %d-%d' % (action.name, startframe, endframe)) + IQMdebug(operator, 'Exporting action "%s" frames %d-%d' % (action.name, startframe, endframe)) scene = context.scene worldmatrix = armature.matrix_world armature.animation_data.action = action @@ -756,9 +774,9 @@ def collectAnim(context, armature, scale, bones, action, startframe = None, endf return outdata -def collectAnims(context, armature, scale, bones, animspecs): +def collectAnims(operator, context, armature, scale, bones, animspecs): if not armature.animation_data: - print('Armature has no animation data') + IQMwarning(operator, 'Armature has no animation data') return [] actions = bpy.data.actions animspecs = [ spec.strip() for spec in animspecs.split(',') ] @@ -770,7 +788,7 @@ def collectAnims(context, armature, scale, bones, animspecs): animspec = [ arg.strip() for arg in animspec.split(':') ] animname = animspec[0] if animname not in actions: - print('Action "%s" not found in current armature' % animname) + IQMwarning(operator, 'Action "%s" not found in current armature' % animname) continue try: startframe = int(animspec[1]) @@ -788,14 +806,14 @@ def collectAnims(context, armature, scale, bones, animspecs): flags = int(animspec[4]) except: flags = 0 - framedata = collectAnim(context, armature, scale, bones, actions[animname], startframe, endframe) + framedata = collectAnim(operator, context, armature, scale, bones, actions[animname], startframe, endframe) anims.append(Animation(animname, framedata, fps, flags)) armature.animation_data.action = oldaction scene.frame_set(oldframe) return anims -def collectMeshes(context, bones, scale, matfun, useskel = True, usecol = False, filetype = 'IQM'): +def collectMeshes(operator, context, bones, scale, matfun, useskel = True, usecol = False, filetype = 'IQM'): vertwarn = [] objs = context.selected_objects #context.scene.objects meshes = [] @@ -839,7 +857,7 @@ def collectMeshes(context, bones, scale, matfun, useskel = True, usecol = False, mesh = materials[obj.name, matindex, material] except: matprefix = (data.materials and data.materials[matindex].name) or '' - mesh = Mesh(obj.name, matfun(matprefix, material), data.vertices) + mesh = Mesh(operator, obj.name, matfun(matprefix, material), data.vertices) meshes.append(mesh) materials[obj.name, matindex, material] = mesh @@ -899,7 +917,7 @@ def collectMeshes(context, bones, scale, matfun, useskel = True, usecol = False, except: if (groups[g.group].name, mesh.name) not in vertwarn: vertwarn.append((groups[g.group].name, mesh.name)) - print('Vertex depends on non-existent bone: %s in mesh: %s' % (groups[g.group].name, mesh.name)) + IQMwarning(operator, 'Vertex depends on non-existent bone: %s in mesh: %s' % (groups[g.group].name, mesh.name)) if not face.use_smooth: vertindex = len(verts) @@ -937,7 +955,7 @@ def collectMeshes(context, bones, scale, matfun, useskel = True, usecol = False, if filetype == 'IQM': mesh.calcTangents() mesh.calcNeighbors() - print('%s %s: generated %d triangles' % (mesh.name, mesh.material, len(mesh.tris))) + IQMdebug(operator, '%s %s: generated %d triangles' % (mesh.name, mesh.material, len(mesh.tris))) return meshes @@ -999,40 +1017,37 @@ def exportIQE(file, meshes, bones, anims): file.write('\n') - -def exportIQM(context, filename, usemesh = True, useskel = True, usebbox = True, usecol = False, scale = 1.0, animspecs = None, matfun = (lambda prefix, image: image), derigify = False): +def exportIQM(operator, context, filename, usemesh = True, useskel = True, usebbox = True, usecol = False, scale = 1.0, animspecs = None, matfun = (lambda prefix, image: image), derigify = False): armature = findArmature(context) if useskel and not armature: - print('No armature selected') - return + return IQMerror(operator, 'No armature selected') if filename.lower().endswith('.iqm'): filetype = 'IQM' elif filename.lower().endswith('.iqe'): filetype = 'IQE' else: - print('Unknown file type: %s' % filename) - return + return IQMerror(operator, 'Unknown file type: %s' % filename) if useskel: if derigify: - bones = derigifyBones(context, armature, scale) + bones = derigifyBones(operator, context, armature, scale) else: - bones = collectBones(context, armature, scale) + bones = collectBones(operator, context, armature, scale) else: bones = {} bonelist = sorted(bones.values(), key = lambda bone: bone.index) if usemesh: - meshes = collectMeshes(context, bones, scale, matfun, useskel, usecol, filetype) + meshes = collectMeshes(operator, context, bones, scale, matfun, useskel, usecol, filetype) else: meshes = [] if useskel and animspecs: - anims = collectAnims(context, armature, scale, bonelist, animspecs) + anims = collectAnims(operator, context, armature, scale, bonelist, animspecs) else: anims = [] if filetype == 'IQM': - iqm = IQMFile() + iqm = IQMFile(operator) iqm.addMeshes(meshes) iqm.addJoints(bonelist) iqm.addAnims(anims) @@ -1045,16 +1060,16 @@ def exportIQM(context, filename, usemesh = True, useskel = True, usebbox = True, else: file = open(filename, 'w') except: - print ('Failed writing to %s' % (filename)) - return + return IQMerror(operator, 'Failed writing to %s' % (filename)) if filetype == 'IQM': iqm.export(file, usebbox) elif filetype == 'IQE': exportIQE(file, meshes, bonelist, anims) file.close() - print('Saved %s file to %s' % (filetype, filename)) + IQMinfo(operator, 'Saved %s file to %s' % (filetype, filename)) else: - print('No %s file was generated' % (filetype)) + return IQMerror(operator, 'No %s file was generated' % (filetype)) + return {'FINISHED'} class ExportIQM(bpy.types.Operator, ExportHelper): @@ -1079,8 +1094,7 @@ def execute(self, context): matfun = lambda prefix, image: prefix else: matfun = lambda prefix, image: image - exportIQM(context, self.properties.filepath, self.properties.usemesh, self.properties.useskel, self.properties.usebbox, self.properties.usecol, self.properties.usescale, self.properties.animspec, matfun, self.properties.derigify) - return {'FINISHED'} + return exportIQM(self, context, self.properties.filepath, self.properties.usemesh, self.properties.useskel, self.properties.usebbox, self.properties.usecol, self.properties.usescale, self.properties.animspec, matfun, self.properties.derigify) def check(self, context): filepath = bpy.path.ensure_ext(self.filepath, '.iqm') diff --git a/blender-2.62/iqm_export.py b/blender-2.62/iqm_export.py index d4568ae..7b14396 100644 --- a/blender-2.62/iqm_export.py +++ b/blender-2.62/iqm_export.py @@ -51,6 +51,22 @@ MAXVCACHE = 32 +def IQMerror(operator, message): + operator.report({'ERROR'}, message) + return {'CANCELLED'} + +def IQMdebug(operator, message): + operator.report({'DEBUG'}, message) + return {'CANCELLED'} + +def IQMwarning(operator, message): + operator.report({'WARNING'}, message) + return None + +def IQMinfo(operator, message): + operator.report({'INFO'}, message) + return None + class Vertex: def __init__(self, index, coord, normal, uv, weights, color): self.index = index @@ -107,7 +123,8 @@ def __eq__(self, v): class Mesh: - def __init__(self, name, material, verts): + def __init__(self, operator, name, material, verts): + self.operator = operator self.name = name self.material = material self.verts = [ None for v in verts ] @@ -206,10 +223,10 @@ def optimize(self): besttri = i bestscore = score - print('%s: %d verts optimized to %d/%d loads for %d entry LRU cache' % (self.name, len(self.verts), vertloads, len(vertschedule), MAXVCACHE)) - #print('%s: %d verts scheduled to %d' % (self.name, len(self.verts), len(vertschedule))) + IQMdebug(self.operator, '%s: %d verts optimized to %d/%d loads for %d entry LRU cache' % (self.name, len(self.verts), vertloads, len(vertschedule), MAXVCACHE)) + #IQMdebug(self.operator, '%s: %d verts scheduled to %d' % (self.name, len(self.verts), len(vertschedule))) self.verts = vertschedule - # print('%s: %d tris scheduled to %d' % (self.name, len(self.tris), len(trischedule))) + # IQMdebug(self.operator, '%s: %d tris scheduled to %d' % (self.name, len(self.tris), len(trischedule))) self.tris = trischedule def calcNeighbors(self): @@ -409,13 +426,14 @@ def boundsData(self, bones, meshes): invbase.append(bone.matrix.inverted()) data = b'' for i, frame in enumerate(self.frames): - print('Calculating bounding box for %s:%d' % (self.name, i)) + IQMdebug(self.operator, 'Calculating bounding box for %s:%d' % (self.name, i)) data += self.frameBoundsData(bones, meshes, frame, invbase) return data class IQMFile: - def __init__(self): + def __init__(self, operator): + self.operator = operator self.textoffsets = {} self.textdata = b'' self.meshes = [] @@ -475,7 +493,7 @@ def calcFrameSize(self): for joint in self.joints: if self.anims: self.posedata.append(joint.poseData(self)) - print('Exporting %d frames of size %d' % (self.numframes, self.framesize)) + IQMdebug(self.operator, 'Exporting %d frames of size %d' % (self.numframes, self.framesize)) def writeVerts(self, file, offset): if self.numverts <= 0: @@ -638,7 +656,7 @@ def findArmature(context): return armature -def derigifyBones(context, armature, scale): +def derigifyBones(operator, context, armature, scale): data = armature.data orgbones = {} @@ -693,11 +711,11 @@ def derigifyBones(context, armature, scale): bonematrix.translation *= scale bones[bone.name] = Bone(bname, bone.name, index, bname in defparent and bones.get(defbones[defparent[bname]].name), bonematrix) worklist.extend(defchildren[bname]) - print('De-rigified %d bones' % len(worklist)) + IQMdebug(operator, 'De-rigified %d bones' % len(worklist)) return bones -def collectBones(context, armature, scale): +def collectBones(operator, context, armature, scale): data = armature.data bones = {} worldmatrix = armature.matrix_world @@ -710,16 +728,16 @@ def collectBones(context, armature, scale): for child in bone.children: if child not in worklist: worklist.append(child) - print('Collected %d bones' % len(worklist)) + IQMdebug(operator, 'Collected %d bones' % len(worklist)) return bones -def collectAnim(context, armature, scale, bones, action, startframe = None, endframe = None): +def collectAnim(operator, context, armature, scale, bones, action, startframe = None, endframe = None): if not startframe or not endframe: startframe, endframe = action.frame_range startframe = int(startframe) endframe = int(endframe) - print('Exporting action "%s" frames %d-%d' % (action.name, startframe, endframe)) + IQMdebug(operator, 'Exporting action "%s" frames %d-%d' % (action.name, startframe, endframe)) scene = context.scene worldmatrix = armature.matrix_world armature.animation_data.action = action @@ -750,9 +768,9 @@ def collectAnim(context, armature, scale, bones, action, startframe = None, endf return outdata -def collectAnims(context, armature, scale, bones, animspecs): +def collectAnims(operator, context, armature, scale, bones, animspecs): if not armature.animation_data: - print('Armature has no animation data') + IQMwarning(operator, 'Armature has no animation data') return [] actions = bpy.data.actions animspecs = [ spec.strip() for spec in animspecs.split(',') ] @@ -764,7 +782,7 @@ def collectAnims(context, armature, scale, bones, animspecs): animspec = [ arg.strip() for arg in animspec.split(':') ] animname = animspec[0] if animname not in actions: - print('Action "%s" not found in current armature' % animname) + IQMwarning(operator, 'Action "%s" not found in current armature' % animname) continue try: startframe = int(animspec[1]) @@ -782,14 +800,14 @@ def collectAnims(context, armature, scale, bones, animspecs): flags = int(animspec[4]) except: flags = 0 - framedata = collectAnim(context, armature, scale, bones, actions[animname], startframe, endframe) + framedata = collectAnim(operator, context, armature, scale, bones, actions[animname], startframe, endframe) anims.append(Animation(animname, framedata, fps, flags)) armature.animation_data.action = oldaction scene.frame_set(oldframe) return anims -def collectMeshes(context, bones, scale, matfun, useskel = True, usecol = False, filetype = 'IQM'): +def collectMeshes(operator, context, bones, scale, matfun, useskel = True, usecol = False, filetype = 'IQM'): vertwarn = [] objs = context.selected_objects #context.scene.objects meshes = [] @@ -833,7 +851,7 @@ def collectMeshes(context, bones, scale, matfun, useskel = True, usecol = False, mesh = materials[obj.name, matindex, material] except: matprefix = (data.materials and data.materials[matindex].name) or '' - mesh = Mesh(obj.name, matfun(matprefix, material), data.vertices) + mesh = Mesh(operator, obj.name, matfun(matprefix, material), data.vertices) meshes.append(mesh) materials[obj.name, matindex, material] = mesh @@ -893,7 +911,7 @@ def collectMeshes(context, bones, scale, matfun, useskel = True, usecol = False, except: if (groups[g.group].name, mesh.name) not in vertwarn: vertwarn.append((groups[g.group].name, mesh.name)) - print('Vertex depends on non-existent bone: %s in mesh: %s' % (groups[g.group].name, mesh.name)) + IQMwarning(operator, 'Vertex depends on non-existent bone: %s in mesh: %s' % (groups[g.group].name, mesh.name)) if not face.use_smooth: vertindex = len(verts) @@ -931,7 +949,7 @@ def collectMeshes(context, bones, scale, matfun, useskel = True, usecol = False, if filetype == 'IQM': mesh.calcTangents() mesh.calcNeighbors() - print('%s %s: generated %d triangles' % (mesh.name, mesh.material, len(mesh.tris))) + IQMdebug(operator, '%s %s: generated %d triangles' % (mesh.name, mesh.material, len(mesh.tris))) return meshes @@ -993,40 +1011,37 @@ def exportIQE(file, meshes, bones, anims): file.write('\n') - -def exportIQM(context, filename, usemesh = True, useskel = True, usebbox = True, usecol = False, scale = 1.0, animspecs = None, matfun = (lambda prefix, image: image), derigify = False): +def exportIQM(operator, context, filename, usemesh = True, useskel = True, usebbox = True, usecol = False, scale = 1.0, animspecs = None, matfun = (lambda prefix, image: image), derigify = False): armature = findArmature(context) if useskel and not armature: - print('No armature selected') - return + return IQMerror(operator, 'No armature selected') if filename.lower().endswith('.iqm'): filetype = 'IQM' elif filename.lower().endswith('.iqe'): filetype = 'IQE' else: - print('Unknown file type: %s' % filename) - return + return IQMerror(operator, 'Unknown file type: %s' % filename) if useskel: if derigify: - bones = derigifyBones(context, armature, scale) + bones = derigifyBones(operator, context, armature, scale) else: - bones = collectBones(context, armature, scale) + bones = collectBones(operator, context, armature, scale) else: bones = {} bonelist = sorted(bones.values(), key = lambda bone: bone.index) if usemesh: - meshes = collectMeshes(context, bones, scale, matfun, useskel, usecol, filetype) + meshes = collectMeshes(operator, context, bones, scale, matfun, useskel, usecol, filetype) else: meshes = [] if useskel and animspecs: - anims = collectAnims(context, armature, scale, bonelist, animspecs) + anims = collectAnims(operator, context, armature, scale, bonelist, animspecs) else: anims = [] if filetype == 'IQM': - iqm = IQMFile() + iqm = IQMFile(operator) iqm.addMeshes(meshes) iqm.addJoints(bonelist) iqm.addAnims(anims) @@ -1039,16 +1054,16 @@ def exportIQM(context, filename, usemesh = True, useskel = True, usebbox = True, else: file = open(filename, 'w') except: - print ('Failed writing to %s' % (filename)) - return + return IQMerror(operator, 'Failed writing to %s' % (filename)) if filetype == 'IQM': iqm.export(file, usebbox) elif filetype == 'IQE': exportIQE(file, meshes, bonelist, anims) file.close() - print('Saved %s file to %s' % (filetype, filename)) + IQMinfo(operator, 'Saved %s file to %s' % (filetype, filename)) else: - print('No %s file was generated' % (filetype)) + return IQMerror(operator, 'No %s file was generated' % (filetype)) + return {'FINISHED'} class ExportIQM(bpy.types.Operator, ExportHelper): @@ -1073,8 +1088,7 @@ def execute(self, context): matfun = lambda prefix, image: prefix else: matfun = lambda prefix, image: image - exportIQM(context, self.properties.filepath, self.properties.usemesh, self.properties.useskel, self.properties.usebbox, self.properties.usecol, self.properties.usescale, self.properties.animspec, matfun, self.properties.derigify) - return {'FINISHED'} + return exportIQM(self, context, self.properties.filepath, self.properties.usemesh, self.properties.useskel, self.properties.usebbox, self.properties.usecol, self.properties.usescale, self.properties.animspec, matfun, self.properties.derigify) def check(self, context): filepath = bpy.path.ensure_ext(self.filepath, '.iqm') diff --git a/blender-2.63/iqm_export.py b/blender-2.63/iqm_export.py index 76e8058..ba9da6d 100644 --- a/blender-2.63/iqm_export.py +++ b/blender-2.63/iqm_export.py @@ -50,6 +50,22 @@ MAXVCACHE = 32 +def IQMerror(operator, message): + operator.report({'ERROR'}, message) + return {'CANCELLED'} + +def IQMdebug(operator, message): + operator.report({'DEBUG'}, message) + return {'CANCELLED'} + +def IQMwarning(operator, message): + operator.report({'WARNING'}, message) + return None + +def IQMinfo(operator, message): + operator.report({'INFO'}, message) + return None + class Vertex: def __init__(self, index, coord, normal, uv, weights, color): self.index = index @@ -106,7 +122,8 @@ def __eq__(self, v): class Mesh: - def __init__(self, name, material, verts): + def __init__(self, operator, name, material, verts): + self.operator = operator self.name = name self.material = material self.verts = [ None for v in verts ] @@ -205,10 +222,10 @@ def optimize(self): besttri = i bestscore = score - print('%s: %d verts optimized to %d/%d loads for %d entry LRU cache' % (self.name, len(self.verts), vertloads, len(vertschedule), MAXVCACHE)) - #print('%s: %d verts scheduled to %d' % (self.name, len(self.verts), len(vertschedule))) + IQMdebug(self.operator, '%s: %d verts optimized to %d/%d loads for %d entry LRU cache' % (self.name, len(self.verts), vertloads, len(vertschedule), MAXVCACHE)) + #IQMdebug(self.operator, '%s: %d verts scheduled to %d' % (self.name, len(self.verts), len(vertschedule))) self.verts = vertschedule - # print('%s: %d tris scheduled to %d' % (self.name, len(self.tris), len(trischedule))) + # IQMdebug(self.operator, '%s: %d tris scheduled to %d' % (self.name, len(self.tris), len(trischedule))) self.tris = trischedule def calcNeighbors(self): @@ -408,13 +425,14 @@ def boundsData(self, bones, meshes): invbase.append(bone.matrix.inverted()) data = b'' for i, frame in enumerate(self.frames): - print('Calculating bounding box for %s:%d' % (self.name, i)) + IQMdebug(self.operator, 'Calculating bounding box for %s:%d' % (self.name, i)) data += self.frameBoundsData(bones, meshes, frame, invbase) return data class IQMFile: - def __init__(self): + def __init__(self, operator): + self.operator = operator self.textoffsets = {} self.textdata = b'' self.meshes = [] @@ -474,7 +492,7 @@ def calcFrameSize(self): for joint in self.joints: if self.anims: self.posedata.append(joint.poseData(self)) - print('Exporting %d frames of size %d' % (self.numframes, self.framesize)) + IQMdebug(self.operator, 'Exporting %d frames of size %d' % (self.numframes, self.framesize)) def writeVerts(self, file, offset): if self.numverts <= 0: @@ -637,7 +655,7 @@ def findArmature(context): return armature -def derigifyBones(context, armature, scale): +def derigifyBones(operator, context, armature, scale): data = armature.data orgbones = {} @@ -692,11 +710,11 @@ def derigifyBones(context, armature, scale): bonematrix.translation *= scale bones[bone.name] = Bone(bname, bone.name, index, bname in defparent and bones.get(defbones[defparent[bname]].name), bonematrix) worklist.extend(defchildren[bname]) - print('De-rigified %d bones' % len(worklist)) + IQMdebug(operator, 'De-rigified %d bones' % len(worklist)) return bones -def collectBones(context, armature, scale): +def collectBones(operator, context, armature, scale): data = armature.data bones = {} worldmatrix = armature.matrix_world @@ -709,16 +727,16 @@ def collectBones(context, armature, scale): for child in bone.children: if child not in worklist: worklist.append(child) - print('Collected %d bones' % len(worklist)) + IQMdebug(operator, 'Collected %d bones' % len(worklist)) return bones -def collectAnim(context, armature, scale, bones, action, startframe = None, endframe = None): +def collectAnim(operator, context, armature, scale, bones, action, startframe = None, endframe = None): if not startframe or not endframe: startframe, endframe = action.frame_range startframe = int(startframe) endframe = int(endframe) - print('Exporting action "%s" frames %d-%d' % (action.name, startframe, endframe)) + IQMdebug(operator, 'Exporting action "%s" frames %d-%d' % (action.name, startframe, endframe)) scene = context.scene worldmatrix = armature.matrix_world armature.animation_data.action = action @@ -749,9 +767,9 @@ def collectAnim(context, armature, scale, bones, action, startframe = None, endf return outdata -def collectAnims(context, armature, scale, bones, animspecs): +def collectAnims(operator, context, armature, scale, bones, animspecs): if not armature.animation_data: - print('Armature has no animation data') + IQMwarning(operator, 'Armature has no animation data') return [] actions = bpy.data.actions animspecs = [ spec.strip() for spec in animspecs.split(',') ] @@ -763,7 +781,7 @@ def collectAnims(context, armature, scale, bones, animspecs): animspec = [ arg.strip() for arg in animspec.split(':') ] animname = animspec[0] if animname not in actions: - print('Action "%s" not found in current armature' % animname) + IQMwarning(operator, 'Action "%s" not found in current armature' % animname) continue try: startframe = int(animspec[1]) @@ -781,14 +799,14 @@ def collectAnims(context, armature, scale, bones, animspecs): flags = int(animspec[4]) except: flags = 0 - framedata = collectAnim(context, armature, scale, bones, actions[animname], startframe, endframe) + framedata = collectAnim(operator, context, armature, scale, bones, actions[animname], startframe, endframe) anims.append(Animation(animname, framedata, fps, flags)) armature.animation_data.action = oldaction scene.frame_set(oldframe) return anims -def collectMeshes(context, bones, scale, matfun, useskel = True, usecol = False, filetype = 'IQM'): +def collectMeshes(operator, context, bones, scale, matfun, useskel = True, usecol = False, filetype = 'IQM'): vertwarn = [] objs = context.selected_objects #context.scene.objects meshes = [] @@ -834,7 +852,7 @@ def collectMeshes(context, bones, scale, matfun, useskel = True, usecol = False, mesh = materials[obj.name, matindex, material] except: matprefix = (data.materials and data.materials[matindex].name) or '' - mesh = Mesh(obj.name, matfun(matprefix, material), data.vertices) + mesh = Mesh(operator, obj.name, matfun(matprefix, material), data.vertices) meshes.append(mesh) materials[obj.name, matindex, material] = mesh @@ -894,7 +912,7 @@ def collectMeshes(context, bones, scale, matfun, useskel = True, usecol = False, except: if (groups[g.group].name, mesh.name) not in vertwarn: vertwarn.append((groups[g.group].name, mesh.name)) - print('Vertex depends on non-existent bone: %s in mesh: %s' % (groups[g.group].name, mesh.name)) + IQMwarning(operator, 'Vertex depends on non-existent bone: %s in mesh: %s' % (groups[g.group].name, mesh.name)) if not face.use_smooth: vertindex = len(verts) @@ -932,7 +950,7 @@ def collectMeshes(context, bones, scale, matfun, useskel = True, usecol = False, if filetype == 'IQM': mesh.calcTangents() mesh.calcNeighbors() - print('%s %s: generated %d triangles' % (mesh.name, mesh.material, len(mesh.tris))) + IQMdebug(operator, '%s %s: generated %d triangles' % (mesh.name, mesh.material, len(mesh.tris))) return meshes @@ -994,40 +1012,37 @@ def exportIQE(file, meshes, bones, anims): file.write('\n') - -def exportIQM(context, filename, usemesh = True, useskel = True, usebbox = True, usecol = False, scale = 1.0, animspecs = None, matfun = (lambda prefix, image: image), derigify = False): +def exportIQM(operator, context, filename, usemesh = True, useskel = True, usebbox = True, usecol = False, scale = 1.0, animspecs = None, matfun = (lambda prefix, image: image), derigify = False): armature = findArmature(context) if useskel and not armature: - print('No armature selected') - return + return IQMerror(operator, 'No armature selected') if filename.lower().endswith('.iqm'): filetype = 'IQM' elif filename.lower().endswith('.iqe'): filetype = 'IQE' else: - print('Unknown file type: %s' % filename) - return + return IQMerror(operator, 'Unknown file type: %s' % filename) if useskel: if derigify: - bones = derigifyBones(context, armature, scale) + bones = derigifyBones(operator, context, armature, scale) else: - bones = collectBones(context, armature, scale) + bones = collectBones(operator, context, armature, scale) else: bones = {} bonelist = sorted(bones.values(), key = lambda bone: bone.index) if usemesh: - meshes = collectMeshes(context, bones, scale, matfun, useskel, usecol, filetype) + meshes = collectMeshes(operator, context, bones, scale, matfun, useskel, usecol, filetype) else: meshes = [] if useskel and animspecs: - anims = collectAnims(context, armature, scale, bonelist, animspecs) + anims = collectAnims(operator, context, armature, scale, bonelist, animspecs) else: anims = [] if filetype == 'IQM': - iqm = IQMFile() + iqm = IQMFile(operator) iqm.addMeshes(meshes) iqm.addJoints(bonelist) iqm.addAnims(anims) @@ -1040,16 +1055,16 @@ def exportIQM(context, filename, usemesh = True, useskel = True, usebbox = True, else: file = open(filename, 'w') except: - print ('Failed writing to %s' % (filename)) - return + return IQMerror(operator, 'Failed writing to %s' % (filename)) if filetype == 'IQM': iqm.export(file, usebbox) elif filetype == 'IQE': exportIQE(file, meshes, bonelist, anims) file.close() - print('Saved %s file to %s' % (filetype, filename)) + IQMinfo(operator, 'Saved %s file to %s' % (filetype, filename)) else: - print('No %s file was generated' % (filetype)) + return IQMerror(operator, 'No %s file was generated' % (filetype)) + return {'FINISHED'} class ExportIQM(bpy.types.Operator, ExportHelper): @@ -1074,8 +1089,7 @@ def execute(self, context): matfun = lambda prefix, image: prefix else: matfun = lambda prefix, image: image - exportIQM(context, self.properties.filepath, self.properties.usemesh, self.properties.useskel, self.properties.usebbox, self.properties.usecol, self.properties.usescale, self.properties.animspec, matfun, self.properties.derigify) - return {'FINISHED'} + return exportIQM(self, context, self.properties.filepath, self.properties.usemesh, self.properties.useskel, self.properties.usebbox, self.properties.usecol, self.properties.usescale, self.properties.animspec, matfun, self.properties.derigify) def check(self, context): filepath = bpy.path.ensure_ext(self.filepath, '.iqm')