def mesh_to_nodepath(mesh, boundsInfo): scene_members = pcore.getSceneMembers(mesh) rootNode = p3d.NodePath("rootnode") rotatePath = rootNode.attachNewNode("rotater") matrix = numpy.identity(4) if mesh.assetInfo.upaxis == collada.asset.UP_AXIS.X_UP: r = collada.scene.RotateTransform(0, 1, 0, 90) matrix = r.matrix elif mesh.assetInfo.upaxis == collada.asset.UP_AXIS.Y_UP: r = collada.scene.RotateTransform(1, 0, 0, 90) matrix = r.matrix rotatePath.setMat(p3d.Mat4(*matrix.T.flatten().tolist())) modelNode = p3d.ModelNode("colladanode") modelNode.setPreserveTransform(p3d.ModelNode.PTNet) modelPath = rotatePath.attachNewNode(modelNode) for geom, renderstate, mat4 in scene_members: node = p3d.GeomNode("primitive") node.addGeom(geom) if renderstate is not None: # FIXME: disabled transparency attrib because of progressive transparency bug renderstate = renderstate.removeAttrib(p3d.ColorScaleAttrib) node.setGeomState(0, renderstate) geomPath = modelPath.attachNewNode(node) geomPath.setMat(mat4) newroot = centerAndScale(rotatePath, boundsInfo) newroot.flattenStrong() return modelPath
def getBam(mesh, filename): scene_members = pandacore.getSceneMembers(mesh) rotateNode = GeomNode("rotater") rotatePath = NodePath(rotateNode) matrix = numpy.identity(4) if mesh.assetInfo.upaxis == collada.asset.UP_AXIS.X_UP: r = collada.scene.RotateTransform(0,1,0,90) matrix = r.matrix elif mesh.assetInfo.upaxis == collada.asset.UP_AXIS.Y_UP: r = collada.scene.RotateTransform(1,0,0,90) matrix = r.matrix rotatePath.setMat(Mat4(*matrix.T.flatten().tolist())) for geom, renderstate, mat4 in scene_members: node = GeomNode("primitive") node.addGeom(geom) if renderstate is not None: node.setGeomState(0, renderstate) geomPath = rotatePath.attachNewNode(node) geomPath.setMat(mat4) rotatePath.flattenStrong() wrappedNode = pandacore.centerAndScale(rotatePath) model_name = filename.replace('/', '_') wrappedNode.setName(model_name) bam_temp = tempfile.mktemp(suffix = model_name + '.bam') wrappedNode.writeBamFile(bam_temp) bam_f = open(bam_temp, 'rb') bam_data = bam_f.read() bam_f.close() os.remove(bam_temp) return bam_data
def getBam(mesh, filename): scene_members = pandacore.getSceneMembers(mesh) rotateNode = GeomNode("rotater") rotatePath = NodePath(rotateNode) matrix = numpy.identity(4) if mesh.assetInfo.upaxis == collada.asset.UP_AXIS.X_UP: r = collada.scene.RotateTransform(0,1,0,90) matrix = r.matrix elif mesh.assetInfo.upaxis == collada.asset.UP_AXIS.Y_UP: r = collada.scene.RotateTransform(1,0,0,90) matrix = r.matrix rotatePath.setMat(Mat4(*matrix.T.flatten().tolist())) for geom, renderstate, mat4 in scene_members: node = GeomNode("primitive") node.addGeom(geom) if renderstate is not None: node.setGeomState(0, renderstate) geomPath = rotatePath.attachNewNode(node) geomPath.setMat(mat4) rotatePath.flattenStrong() wrappedNode = pandacore.centerAndScale(rotatePath) model_name = filename.replace('/', '_') wrappedNode.setName(model_name) bam_temp = tempfile.mktemp(suffix = model_name + '.bam') wrappedNode.writeBamFile(bam_temp) bam_f = open(bam_temp, 'rb') bam_data = bam_f.read() bam_f.close() os.remove(bam_temp) return bam_data
def __init__(self, mesh_path, progressive_texture_path): resolutions = [] f = tarfile.open(progressive_texture_path) for resolution_name in f.getnames(): toset = { 'size': resolution_name[:-4], 'contents': f.extractfile(resolution_name).read() } texpnm = PNMImage() texpnm.read(StringStream(toset['contents']), 'something.jpg') newtex = Texture() newtex.load(texpnm) toset['texture'] = newtex resolutions.append(toset) self.resolutions = resolutions def aux_loader(fname): return resolutions[0]['contents'] mesh = collada.Collada(mesh_path, aux_file_loader=aux_loader) scene_members = getSceneMembers(mesh) base = ShowBase() rotateNode = GeomNode("rotater") rotatePath = render.attachNewNode(rotateNode) matrix = numpy.identity(4) if mesh.assetInfo.upaxis == collada.asset.UP_AXIS.X_UP: r = collada.scene.RotateTransform(0, 1, 0, 90) matrix = r.matrix elif mesh.assetInfo.upaxis == collada.asset.UP_AXIS.Y_UP: r = collada.scene.RotateTransform(1, 0, 0, 90) matrix = r.matrix rotatePath.setMat(Mat4(*matrix.T.flatten().tolist())) geom, renderstate, mat4 = scene_members[0] node = GeomNode("primitive") node.addGeom(geom) if renderstate is not None: node.setGeomState(0, renderstate) self.geomPath = rotatePath.attachNewNode(node) self.geomPath.setMat(mat4) wrappedNode = ensureCameraAt(self.geomPath, base.camera) base.disableMouse() attachLights(render) render.setShaderAuto() render.setTransparency(TransparencyAttrib.MDual, 1) base.render.analyze() KeyboardMovement() MouseDrag(wrappedNode) MouseScaleZoom(wrappedNode) MouseCamera() num_resolutions = len(resolutions) - 1 self.slider = DirectSlider(range=(0, num_resolutions), value=0, pageSize=1, command=self.sliderMoved, pos=(0, 0, -.9), scale=1) for key, val in uiArgs.iteritems(): self.slider.thumb[key] = val self.triText = OnscreenText(text="", pos=(-1, 0.85), scale=0.15, fg=(1, 0.5, 0.5, 1), align=TextNode.ALeft, mayChange=1) base.run()
def load_into_bamfile(meshdata, subfiles, model): """Uses pycollada and panda3d to load meshdata and subfiles and write out to a bam file on disk""" if os.path.isfile(model.bam_file): print 'returning cached bam file' return model.bam_file mesh = load_mesh(meshdata, subfiles) model_name = model.model_json['full_path'].replace('/', '_') if model.model_type == 'progressive' and model.model_subtype == 'full': progressive_stream = model.model_json['metadata']['types'][ 'progressive'].get('progressive_stream') if progressive_stream is not None: print 'LOADING PROGRESSIVE STREAM' data = model.prog_data try: mesh = add_back_pm.add_back_pm(mesh, StringIO(data), 100) print '-----' print 'SUCCESSFULLY ADDED BACK PM' print '-----' except: f = open(model.bam_file, 'w') f.close() raise print 'loading into bamfile', model_name, mesh scene_members = pandacore.getSceneMembers(mesh) print 'got scene members', model_name, mesh rotateNode = GeomNode("rotater") rotatePath = NodePath(rotateNode) matrix = numpy.identity(4) if mesh.assetInfo.upaxis == collada.asset.UP_AXIS.X_UP: r = collada.scene.RotateTransform(0, 1, 0, 90) matrix = r.matrix elif mesh.assetInfo.upaxis == collada.asset.UP_AXIS.Y_UP: r = collada.scene.RotateTransform(1, 0, 0, 90) matrix = r.matrix rotatePath.setMat(Mat4(*matrix.T.flatten().tolist())) for geom, renderstate, mat4 in scene_members: node = GeomNode("primitive") node.addGeom(geom) if renderstate is not None: node.setGeomState(0, renderstate) geomPath = rotatePath.attachNewNode(node) geomPath.setMat(mat4) print 'created np', model_name, mesh if model.model_type != 'optimized_unflattened' and model.model_type != 'progressive': print 'ABOUT TO FLATTEN' rotatePath.flattenStrong() print 'DONE FLATTENING' print 'flattened', model_name, mesh wrappedNode = pandacore.centerAndScale(rotatePath) wrappedNode.setName(model_name) wrappedNode.writeBamFile(model.bam_file) print 'saved', model_name, mesh wrappedNode = None return model.bam_file
def __init__(self, models): ShowBase.ShowBase.__init__(self) self.models = models unique_meshes = set(m.mesh for m in models) mesh2nodepath = {} for mesh in unique_meshes: scene_members = pcore.getSceneMembers(mesh) rotateNode = p3d.GeomNode("rotater") rotatePath = p3d.NodePath(rotateNode) matrix = numpy.identity(4) if mesh.assetInfo.upaxis == collada.asset.UP_AXIS.X_UP: r = collada.scene.RotateTransform(0, 1, 0, 90) matrix = r.matrix elif mesh.assetInfo.upaxis == collada.asset.UP_AXIS.Y_UP: r = collada.scene.RotateTransform(1, 0, 0, 90) matrix = r.matrix rotatePath.setMat(p3d.Mat4(*matrix.T.flatten().tolist())) rbc = p3d.RigidBodyCombiner('combiner') rbcPath = rotatePath.attachNewNode(rbc) for geom, renderstate, mat4 in scene_members: node = p3d.GeomNode("primitive") node.addGeom(geom) if renderstate is not None: node.setGeomState(0, renderstate) geomPath = rbcPath.attachNewNode(node) geomPath.setMat(mat4) rbc.collect() mesh2nodepath[mesh] = centerAndScale( rotatePath, print_bounds.getBoundsInfo(mesh)) scenepath = render.attachNewNode("scene") for model in self.models: np = mesh2nodepath[model.mesh] instance = scenepath.attachNewNode("model") np.instanceTo(instance) instance.setPos(model.x, model.y, model.z) instance.setScale(model.scale, model.scale, model.scale) q = p3d.Quat() q.setI(model.orient_x) q.setJ(model.orient_y) q.setK(model.orient_z) q.setR(model.orient_w) instance.setQuat(q) base.camLens.setFar(sys.maxint) base.camLens.setNear(8.0) pcore.attachLights(render) render.setShaderAuto() render.setTransparency(p3d.TransparencyAttrib.MDual, 1) render.setAntialias(p3d.AntialiasAttrib.MAuto) controls.KeyboardMovement() controls.ButtonUtils(scenepath) controls.MouseDrag(scenepath) controls.MouseCamera() controls.MouseScaleZoom(scenepath)
def load_into_bamfile(meshdata, subfiles, model): """Uses pycollada and panda3d to load meshdata and subfiles and write out to a bam file on disk""" if os.path.isfile(model.bam_file): print 'returning cached bam file' return model.bam_file mesh = load_mesh(meshdata, subfiles) model_name = model.model_json['full_path'].replace('/', '_') if model.model_type == 'progressive' and model.model_subtype == 'full': progressive_stream = model.model_json['metadata']['types']['progressive'].get('progressive_stream') if progressive_stream is not None: print 'LOADING PROGRESSIVE STREAM' data = model.prog_data try: mesh = add_back_pm.add_back_pm(mesh, StringIO(data), 100) print '-----' print 'SUCCESSFULLY ADDED BACK PM' print '-----' except: f = open(model.bam_file, 'w') f.close() raise print 'loading into bamfile', model_name, mesh scene_members = pandacore.getSceneMembers(mesh) print 'got scene members', model_name, mesh rotateNode = GeomNode("rotater") rotatePath = NodePath(rotateNode) matrix = numpy.identity(4) if mesh.assetInfo.upaxis == collada.asset.UP_AXIS.X_UP: r = collada.scene.RotateTransform(0,1,0,90) matrix = r.matrix elif mesh.assetInfo.upaxis == collada.asset.UP_AXIS.Y_UP: r = collada.scene.RotateTransform(1,0,0,90) matrix = r.matrix rotatePath.setMat(Mat4(*matrix.T.flatten().tolist())) for geom, renderstate, mat4 in scene_members: node = GeomNode("primitive") node.addGeom(geom) if renderstate is not None: node.setGeomState(0, renderstate) geomPath = rotatePath.attachNewNode(node) geomPath.setMat(mat4) print 'created np', model_name, mesh if model.model_type != 'optimized_unflattened' and model.model_type != 'progressive': print 'ABOUT TO FLATTEN' rotatePath.flattenStrong() print 'DONE FLATTENING' print 'flattened', model_name, mesh wrappedNode = pandacore.centerAndScale(rotatePath) wrappedNode.setName(model_name) wrappedNode.writeBamFile(model.bam_file) print 'saved', model_name, mesh wrappedNode = None return model.bam_file
def __init__(self, models): ShowBase.ShowBase.__init__(self) self.models = models unique_meshes = set(m.mesh for m in models) mesh2nodepath = {} for mesh in unique_meshes: scene_members = pcore.getSceneMembers(mesh) rotateNode = p3d.GeomNode("rotater") rotatePath = p3d.NodePath(rotateNode) matrix = numpy.identity(4) if mesh.assetInfo.upaxis == collada.asset.UP_AXIS.X_UP: r = collada.scene.RotateTransform(0,1,0,90) matrix = r.matrix elif mesh.assetInfo.upaxis == collada.asset.UP_AXIS.Y_UP: r = collada.scene.RotateTransform(1,0,0,90) matrix = r.matrix rotatePath.setMat(p3d.Mat4(*matrix.T.flatten().tolist())) rbc = p3d.RigidBodyCombiner('combiner') rbcPath = rotatePath.attachNewNode(rbc) for geom, renderstate, mat4 in scene_members: node = p3d.GeomNode("primitive") node.addGeom(geom) if renderstate is not None: node.setGeomState(0, renderstate) geomPath = rbcPath.attachNewNode(node) geomPath.setMat(mat4) rbc.collect() mesh2nodepath[mesh] = centerAndScale(rotatePath, print_bounds.getBoundsInfo(mesh)) scenepath = render.attachNewNode("scene") for model in self.models: np = mesh2nodepath[model.mesh] instance = scenepath.attachNewNode("model") np.instanceTo(instance) instance.setPos(model.x, model.y, model.z) instance.setScale(model.scale, model.scale, model.scale) q = p3d.Quat() q.setI(model.orient_x) q.setJ(model.orient_y) q.setK(model.orient_z) q.setR(model.orient_w) instance.setQuat(q) base.camLens.setFar(sys.maxint) base.camLens.setNear(8.0) pcore.attachLights(render) render.setShaderAuto() render.setTransparency(p3d.TransparencyAttrib.MDual, 1) render.setAntialias(p3d.AntialiasAttrib.MAuto) controls.KeyboardMovement() controls.ButtonUtils(scenepath) controls.MouseDrag(scenepath) controls.MouseCamera() controls.MouseScaleZoom(scenepath)
def __init__(self, mesh_path, progressive_texture_path): resolutions = [] f = tarfile.open(progressive_texture_path) for resolution_name in f.getnames(): toset = {'size': resolution_name[:-4], 'contents': f.extractfile(resolution_name).read()} texpnm = PNMImage() texpnm.read(StringStream(toset['contents']), 'something.jpg') newtex = Texture() newtex.load(texpnm) toset['texture'] = newtex resolutions.append(toset) self.resolutions = resolutions def aux_loader(fname): return resolutions[0]['contents'] mesh = collada.Collada(mesh_path, aux_file_loader=aux_loader) scene_members = getSceneMembers(mesh) base = ShowBase() rotateNode = GeomNode("rotater") rotatePath = render.attachNewNode(rotateNode) matrix = numpy.identity(4) if mesh.assetInfo.upaxis == collada.asset.UP_AXIS.X_UP: r = collada.scene.RotateTransform(0,1,0,90) matrix = r.matrix elif mesh.assetInfo.upaxis == collada.asset.UP_AXIS.Y_UP: r = collada.scene.RotateTransform(1,0,0,90) matrix = r.matrix rotatePath.setMat(Mat4(*matrix.T.flatten().tolist())) geom, renderstate, mat4 = scene_members[0] node = GeomNode("primitive") node.addGeom(geom) if renderstate is not None: node.setGeomState(0, renderstate) self.geomPath = rotatePath.attachNewNode(node) self.geomPath.setMat(mat4) wrappedNode = ensureCameraAt(self.geomPath, base.camera) base.disableMouse() attachLights(render) render.setShaderAuto() render.setTransparency(TransparencyAttrib.MDual, 1) base.render.analyze() KeyboardMovement() MouseDrag(wrappedNode) MouseScaleZoom(wrappedNode) MouseCamera() num_resolutions = len(resolutions) - 1 self.slider = DirectSlider(range=(0, num_resolutions), value=0, pageSize=1, command=self.sliderMoved, pos=(0, 0, -.9), scale=1) for key, val in uiArgs.iteritems(): self.slider.thumb[key] = val self.triText = OnscreenText(text="", pos=(-1,0.85), scale = 0.15, fg=(1, 0.5, 0.5, 1), align=TextNode.ALeft, mayChange=1) base.run()
def getPmPerceptualError(mesh, pm_filebuf, mipmap_tarfilebuf): perceptualdiff = which('perceptualdiff') if perceptualdiff is None: raise Exception("perceptualdiff exectuable not found on path") pm_chunks = [] if pm_filebuf is not None: data = pm_filebuf.read(PM_CHUNK_SIZE) refinements_read = 0 num_refinements = None while len(data) > 0: (refinements_read, num_refinements, pm_refinements, data_left) = pdae_utils.readPDAEPartial(data, refinements_read, num_refinements) pm_chunks.append(pm_refinements) data = data_left + pm_filebuf.read(PM_CHUNK_SIZE) tar = tarfile.TarFile(fileobj=mipmap_tarfilebuf) texsizes = [] largest_tarinfo = (0, None) for tarinfo in tar: tarinfo.xsize = int(tarinfo.name.split('x')[0]) if tarinfo.xsize > largest_tarinfo[0]: largest_tarinfo = (tarinfo.xsize, tarinfo) if tarinfo.xsize >= 128: texsizes.append(tarinfo) if len(texsizes) == 0: texsizes.append(largest_tarinfo[1]) texsizes = sorted(texsizes, key=lambda t: t.xsize) texims = [] first_image_data = None for tarinfo in texsizes: f = tar.extractfile(tarinfo) texdata = f.read() if first_image_data is None: first_image_data = texdata texpnm = PNMImage() texpnm.read(StringStream(texdata), 'something.jpg') newtex = Texture() newtex.load(texpnm) texims.append(newtex) mesh.images[0].setData(first_image_data) scene_members = getSceneMembers(mesh) # turn off panda3d printing to stdout nout = MultiplexStream() Notify.ptr().setOstreamPtr(nout, 0) nout.addFile(Filename(os.devnull)) base = ShowBase() rotateNode = GeomNode("rotater") rotatePath = base.render.attachNewNode(rotateNode) matrix = numpy.identity(4) if mesh.assetInfo.upaxis == collada.asset.UP_AXIS.X_UP: r = collada.scene.RotateTransform(0, 1, 0, 90) matrix = r.matrix elif mesh.assetInfo.upaxis == collada.asset.UP_AXIS.Y_UP: r = collada.scene.RotateTransform(1, 0, 0, 90) matrix = r.matrix rotatePath.setMat(Mat4(*matrix.T.flatten().tolist())) geom, renderstate, mat4 = scene_members[0] node = GeomNode("primitive") node.addGeom(geom) if renderstate is not None: node.setGeomState(0, renderstate) geomPath = rotatePath.attachNewNode(node) geomPath.setMat(mat4) wrappedNode = ensureCameraAt(geomPath, base.camera) base.disableMouse() attachLights(base.render) base.render.setShaderAuto() base.render.setTransparency(TransparencyAttrib.MNone) base.render.setColorScaleOff(9999) controls.KeyboardMovement() controls.MouseDrag(wrappedNode) controls.MouseScaleZoom(wrappedNode) controls.ButtonUtils(wrappedNode) controls.MouseCamera() error_data = [] try: tempdir = tempfile.mkdtemp(prefix='meshtool-print-pm-perceptual-error') triangleCounts = [] hprs = [(0, 0, 0), (0, 90, 0), (0, 180, 0), (0, 270, 0), (90, 0, 0), (-90, 0, 0)] for texim in texims: np = base.render.find("**/rotater/collada") np.setTextureOff(1) np.setTexture(texim, 1) for angle, hpr in enumerate(hprs): wrappedNode.setHpr(*hpr) takeScreenshot(tempdir, base, geomPath, texim, angle) triangleCounts.append(getNumTriangles(geomPath)) for pm_chunk in pm_chunks: pdae_panda.add_refinements(geomPath, pm_chunk) for texim in texims: np = base.render.find("**/rotater/collada") np.setTextureOff(1) np.setTexture(texim, 1) for angle, hpr in enumerate(hprs): wrappedNode.setHpr(*hpr) takeScreenshot(tempdir, base, geomPath, texim, angle) triangleCounts.append(getNumTriangles(geomPath)) full_tris = triangleCounts[-1] full_tex = texims[-1] for numtris in triangleCounts: for texim in texims: pixel_diff = 0 for angle, hpr in enumerate(hprs): curFile = '%d_%d_%d_%d.png' % (numtris, texim.getXSize(), texim.getYSize(), angle) curFile = os.path.join(tempdir, curFile) fullFile = '%d_%d_%d_%d.png' % (full_tris, full_tex.getXSize(), full_tex.getYSize(), angle) fullFile = os.path.join(tempdir, fullFile) try: output = subprocess.check_output([ perceptualdiff, '-threshold', '1', fullFile, curFile ]) except subprocess.CalledProcessError as ex: output = ex.output output = output.strip() if len(output) > 0: pixel_diff = max(pixel_diff, int(output.split('\n')[1].split()[0])) error_data.append({ 'triangles': numtris, 'width': texim.getXSize(), 'height': texim.getYSize(), 'pixel_error': pixel_diff }) finally: shutil.rmtree(tempdir, ignore_errors=True) return error_data
def getPmPerceptualError(mesh, pm_filebuf, mipmap_tarfilebuf): perceptualdiff = which('perceptualdiff') if perceptualdiff is None: raise Exception("perceptualdiff exectuable not found on path") pm_chunks = [] if pm_filebuf is not None: data = pm_filebuf.read(PM_CHUNK_SIZE) refinements_read = 0 num_refinements = None while len(data) > 0: (refinements_read, num_refinements, pm_refinements, data_left) = pdae_utils.readPDAEPartial(data, refinements_read, num_refinements) pm_chunks.append(pm_refinements) data = data_left + pm_filebuf.read(PM_CHUNK_SIZE) tar = tarfile.TarFile(fileobj=mipmap_tarfilebuf) texsizes = [] largest_tarinfo = (0, None) for tarinfo in tar: tarinfo.xsize = int(tarinfo.name.split('x')[0]) if tarinfo.xsize > largest_tarinfo[0]: largest_tarinfo = (tarinfo.xsize, tarinfo) if tarinfo.xsize >= 128: texsizes.append(tarinfo) if len(texsizes) == 0: texsizes.append(largest_tarinfo[1]) texsizes = sorted(texsizes, key=lambda t: t.xsize) texims = [] first_image_data = None for tarinfo in texsizes: f = tar.extractfile(tarinfo) texdata = f.read() if first_image_data is None: first_image_data = texdata texpnm = PNMImage() texpnm.read(StringStream(texdata), 'something.jpg') newtex = Texture() newtex.load(texpnm) texims.append(newtex) mesh.images[0].setData(first_image_data) scene_members = getSceneMembers(mesh) # turn off panda3d printing to stdout nout = MultiplexStream() Notify.ptr().setOstreamPtr(nout, 0) nout.addFile(Filename(os.devnull)) base = ShowBase() rotateNode = GeomNode("rotater") rotatePath = base.render.attachNewNode(rotateNode) matrix = numpy.identity(4) if mesh.assetInfo.upaxis == collada.asset.UP_AXIS.X_UP: r = collada.scene.RotateTransform(0,1,0,90) matrix = r.matrix elif mesh.assetInfo.upaxis == collada.asset.UP_AXIS.Y_UP: r = collada.scene.RotateTransform(1,0,0,90) matrix = r.matrix rotatePath.setMat(Mat4(*matrix.T.flatten().tolist())) geom, renderstate, mat4 = scene_members[0] node = GeomNode("primitive") node.addGeom(geom) if renderstate is not None: node.setGeomState(0, renderstate) geomPath = rotatePath.attachNewNode(node) geomPath.setMat(mat4) wrappedNode = ensureCameraAt(geomPath, base.camera) base.disableMouse() attachLights(base.render) base.render.setShaderAuto() base.render.setTransparency(TransparencyAttrib.MNone) base.render.setColorScaleOff(9999) controls.KeyboardMovement() controls.MouseDrag(wrappedNode) controls.MouseScaleZoom(wrappedNode) controls.ButtonUtils(wrappedNode) controls.MouseCamera() error_data = [] try: tempdir = tempfile.mkdtemp(prefix='meshtool-print-pm-perceptual-error') triangleCounts = [] hprs = [(0, 0, 0), (0, 90, 0), (0, 180, 0), (0, 270, 0), (90, 0, 0), (-90, 0, 0)] for texim in texims: np = base.render.find("**/rotater/collada") np.setTextureOff(1) np.setTexture(texim, 1) for angle, hpr in enumerate(hprs): wrappedNode.setHpr(*hpr) takeScreenshot(tempdir, base, geomPath, texim, angle) triangleCounts.append(getNumTriangles(geomPath)) for pm_chunk in pm_chunks: pdae_panda.add_refinements(geomPath, pm_chunk) for texim in texims: np = base.render.find("**/rotater/collada") np.setTextureOff(1) np.setTexture(texim, 1) for angle, hpr in enumerate(hprs): wrappedNode.setHpr(*hpr) takeScreenshot(tempdir, base, geomPath, texim, angle) triangleCounts.append(getNumTriangles(geomPath)) full_tris = triangleCounts[-1] full_tex = texims[-1] for numtris in triangleCounts: for texim in texims: pixel_diff = 0 for angle, hpr in enumerate(hprs): curFile = '%d_%d_%d_%d.png' % (numtris, texim.getXSize(), texim.getYSize(), angle) curFile = os.path.join(tempdir, curFile) fullFile = '%d_%d_%d_%d.png' % (full_tris, full_tex.getXSize(), full_tex.getYSize(), angle) fullFile = os.path.join(tempdir, fullFile) try: output = subprocess.check_output([perceptualdiff, '-threshold', '1', fullFile, curFile]) except subprocess.CalledProcessError as ex: output = ex.output output = output.strip() if len(output) > 0: pixel_diff = max(pixel_diff, int(output.split('\n')[1].split()[0])) error_data.append({'triangles': numtris, 'width': texim.getXSize(), 'height': texim.getYSize(), 'pixel_error': pixel_diff}) finally: shutil.rmtree(tempdir, ignore_errors=True) return error_data