Пример #1
0
def renderVerts(verts, idx):

    from meshtool.filters.panda_filters.pandacore import getVertexData, attachLights, ensureCameraAt
    from meshtool.filters.panda_filters.pandacontrols import KeyboardMovement, MouseDrag, MouseScaleZoom
    from panda3d.core import GeomTriangles, Geom, GeomNode
    from direct.showbase.ShowBase import ShowBase

    vdata, indexdata = getVertexData(verts, idx)
    gprim = GeomTriangles(Geom.UHStatic)
    gprim.setIndexType(Geom.NTUint32)
    gprim.setVertices(indexdata)
    gprim.closePrimitive()
    pgeom = Geom(vdata)
    pgeom.addPrimitive(gprim)
    node = GeomNode("primitive")
    node.addGeom(pgeom)
    p3dApp = ShowBase()
    #attachLights(render)
    geomPath = render.attachNewNode(node)
    geomPath.setRenderModeWireframe()
    ensureCameraAt(geomPath, base.camera)
    KeyboardMovement()
    #render.setShaderAuto()
    p3dApp.run()
Пример #2
0
def renderVerts(verts, idx):
    
    from meshtool.filters.panda_filters.pandacore import getVertexData, attachLights, ensureCameraAt
    from meshtool.filters.panda_filters.pandacontrols import KeyboardMovement, MouseDrag, MouseScaleZoom
    from panda3d.core import GeomTriangles, Geom, GeomNode
    from direct.showbase.ShowBase import ShowBase
    
    vdata, indexdata = getVertexData(verts, idx)
    gprim = GeomTriangles(Geom.UHStatic)
    gprim.setIndexType(Geom.NTUint32)
    gprim.setVertices(indexdata)
    gprim.closePrimitive()
    pgeom = Geom(vdata)
    pgeom.addPrimitive(gprim)
    node = GeomNode("primitive")
    node.addGeom(pgeom)
    p3dApp = ShowBase()
    #attachLights(render)
    geomPath = render.attachNewNode(node)
    geomPath.setRenderModeWireframe()
    ensureCameraAt(geomPath, base.camera)
    KeyboardMovement()
    #render.setShaderAuto()
    p3dApp.run()
Пример #3
0
def renderCharts(facegraph, verts, vert_indices, lineset=None):
    
    from meshtool.filters.panda_filters.pandacore import getVertexData, attachLights, ensureCameraAt
    from meshtool.filters.panda_filters.pandacontrols import KeyboardMovement, MouseDrag, MouseScaleZoom, ButtonUtils
    from panda3d.core import GeomTriangles, Geom, GeomNode, GeomVertexFormat, GeomVertexData, GeomVertexWriter, LineSegs
    from direct.showbase.ShowBase import ShowBase
       
    vformat = GeomVertexFormat.getV3c4()
    vdata=GeomVertexData('tris', vformat, Geom.UHDynamic)

    vertex=GeomVertexWriter(vdata, 'vertex')
    color=GeomVertexWriter(vdata, 'color')
    
    colors = gen_color3(len(facegraph))
    numtris = 0
    for chart, data in facegraph.nodes_iter(data=True):
        curcolor = next(colors)
        for tri in data['tris']:
            triv = verts[vert_indices[tri]]
            vertex.addData3f(triv[0][0], triv[0][1], triv[0][2])
            vertex.addData3f(triv[1][0], triv[1][1], triv[1][2])
            vertex.addData3f(triv[2][0], triv[2][1], triv[2][2])
            color.addData4f(curcolor[0],curcolor[1], curcolor[2], 1)
            color.addData4f(curcolor[0],curcolor[1], curcolor[2], 1)
            color.addData4f(curcolor[0],curcolor[1], curcolor[2], 1)
            numtris += 1

    tris=GeomTriangles(Geom.UHDynamic)
    tris.addConsecutiveVertices(0, 3*numtris)
    tris.closePrimitive()
        
    linenodes = []
    if lineset:
        for lines in lineset:
            ls = LineSegs()
            ls.setThickness(4)
            curcolor = next(colors)
            ls.setColor(curcolor[0]/256.0, curcolor[1]/256.0, curcolor[2]/256.0, 1)
    
            tuples = False
            for blah in lines:
                if isinstance(blah, tuple):
                    tuples = True
                break
            if tuples:
                for i, j in lines:
                    frompt = verts[i]
                    topt = verts[j]
                    ls.moveTo(frompt[0], frompt[1], frompt[2])
                    ls.drawTo(topt[0], topt[1], topt[2])
            else:
                for i in range(len(lines)-1):
                    frompt = verts[lines[i]]
                    topt = verts[lines[i+1]]
                    ls.moveTo(frompt[0], frompt[1], frompt[2])
                    ls.drawTo(topt[0], topt[1], topt[2])
            
            linenodes.append(ls.create())
        

    pgeom = Geom(vdata)
    pgeom.addPrimitive(tris)

    node = GeomNode("primitive")
    node.addGeom(pgeom)

    p3dApp = ShowBase()
    #attachLights(render)
    geomPath = render.attachNewNode(node)

    for linenode in linenodes:
        geomPath.attachNewNode(linenode)
    
    #geomPath.setRenderModeWireframe()
    
    ensureCameraAt(geomPath, base.cam)
    
    boundingSphere = geomPath.getBounds()
    base.cam.setPos(boundingSphere.getCenter() + boundingSphere.getRadius())

    base.cam.lookAt(boundingSphere.getCenter())
    
    KeyboardMovement()
    ButtonUtils(geomPath)
    MouseDrag(geomPath)
    MouseScaleZoom(geomPath)
    #render.setShaderAuto()
    p3dApp.run()
Пример #4
0
    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()
Пример #5
0
def visualize(centers, corners, edges):
    from meshtool.filters.panda_filters.pandacore import getVertexData, attachLights, ensureCameraAt
    from meshtool.filters.panda_filters.pandacontrols import KeyboardMovement, MouseDrag, MouseScaleZoom, MouseCamera
    from panda3d.core import GeomPoints, GeomTriangles, Geom, GeomNode, GeomVertexFormat, GeomVertexData, GeomVertexWriter, LineSegs, VBase3
    from direct.showbase.ShowBase import ShowBase

    format = GeomVertexFormat.getV3c4()
    vdata = GeomVertexData('pts', format, Geom.UHDynamic)
    vertex = GeomVertexWriter(vdata, 'vertex')
    color = GeomVertexWriter(vdata, 'color')

    vertex_index = 0
    center_vertex_indices = {}
    corner_vertex_indices = {}
    for key, center in centers.iteritems():
        vertex.addData3f(center.x * X_SCALE, center.y * Y_SCALE,
                         center.elevation * Z_SCALE)
        curcolor = hex2rgb(COLORS[center.biome])
        color.addData4f(curcolor[0], curcolor[1], curcolor[2], 1)
        center_vertex_indices[key] = vertex_index
        vertex_index += 1

        for corner in center.corners:
            vertex.addData3f(corner.x * X_SCALE, corner.y * Y_SCALE,
                             corner.elevation * Z_SCALE)
            color.addData4f(curcolor[0], curcolor[1], curcolor[2], 1)
            corner_vertex_indices[corner.id] = vertex_index
            vertex_index += 1

    tris = GeomTriangles(Geom.UHDynamic)

    for edge in edges.itervalues():
        corner0 = edge.corner0
        corner1 = edge.corner1
        center0 = edge.center0
        center1 = edge.center1
        if corner0 is None or corner1 is None:
            continue

        tris.addVertices(corner_vertex_indices[corner1.id],
                         corner_vertex_indices[corner0.id],
                         center_vertex_indices[center0.id])

        tris.addVertices(center_vertex_indices[center1.id],
                         corner_vertex_indices[corner0.id],
                         corner_vertex_indices[corner1.id])

    tris.closePrimitive()

    pgeom = Geom(vdata)
    pgeom.addPrimitive(tris)

    node = GeomNode("primitive")
    node.addGeom(pgeom)

    p3dApp = ShowBase()
    attachLights(render)
    geomPath = render.attachNewNode(node)
    #geomPath.setRenderModeThickness(6.0)

    #geomPath.setRenderModeWireframe()

    ensureCameraAt(geomPath, base.cam)

    boundingSphere = geomPath.getBounds()
    base.cam.setPos(boundingSphere.getCenter() + boundingSphere.getRadius())

    base.cam.lookAt(boundingSphere.getCenter())

    geomPath.setScale(VBase3(50, 50, 50))

    KeyboardMovement()
    #MouseDrag(geomPath)
    MouseCamera()
    MouseScaleZoom(geomPath)
    #render.setShaderAuto()
    p3dApp.run()
Пример #6
0
def visualize(centers, corners, edges):
    from meshtool.filters.panda_filters.pandacore import getVertexData, attachLights, ensureCameraAt
    from meshtool.filters.panda_filters.pandacontrols import KeyboardMovement, MouseDrag, MouseScaleZoom, MouseCamera
    from panda3d.core import GeomPoints, GeomTriangles, Geom, GeomNode, GeomVertexFormat, GeomVertexData, GeomVertexWriter, LineSegs, VBase3
    from direct.showbase.ShowBase import ShowBase
    
    format = GeomVertexFormat.getV3c4()
    vdata = GeomVertexData('pts', format, Geom.UHDynamic)
    vertex = GeomVertexWriter(vdata, 'vertex')
    color = GeomVertexWriter(vdata, 'color')
    
    vertex_index = 0
    center_vertex_indices = {}
    corner_vertex_indices = {}
    for key, center in centers.iteritems():
        vertex.addData3f(center.x * X_SCALE, center.y * Y_SCALE, center.elevation * Z_SCALE)
        curcolor = hex2rgb(COLORS[center.biome])
        color.addData4f(curcolor[0], curcolor[1], curcolor[2], 1)
        center_vertex_indices[key] = vertex_index
        vertex_index += 1
        
        for corner in center.corners:
            vertex.addData3f(corner.x * X_SCALE, corner.y * Y_SCALE, corner.elevation * Z_SCALE)
            color.addData4f(curcolor[0], curcolor[1], curcolor[2], 1)
            corner_vertex_indices[corner.id] = vertex_index
            vertex_index += 1
    
    tris = GeomTriangles(Geom.UHDynamic)
    
    for edge in edges.itervalues():
        corner0 = edge.corner0
        corner1 = edge.corner1
        center0 = edge.center0
        center1 = edge.center1
        if corner0 is None or corner1 is None:
            continue
        
        tris.addVertices(corner_vertex_indices[corner1.id],
                         corner_vertex_indices[corner0.id],
                         center_vertex_indices[center0.id])
        
        tris.addVertices(center_vertex_indices[center1.id],
                         corner_vertex_indices[corner0.id],
                         corner_vertex_indices[corner1.id])
        
    
    tris.closePrimitive()

    pgeom = Geom(vdata)
    pgeom.addPrimitive(tris)

    node = GeomNode("primitive")
    node.addGeom(pgeom)

    p3dApp = ShowBase()
    attachLights(render)
    geomPath = render.attachNewNode(node)
    #geomPath.setRenderModeThickness(6.0)
    
    #geomPath.setRenderModeWireframe()
    
    ensureCameraAt(geomPath, base.cam)
    
    boundingSphere = geomPath.getBounds()
    base.cam.setPos(boundingSphere.getCenter() + boundingSphere.getRadius())

    base.cam.lookAt(boundingSphere.getCenter())
    
    geomPath.setScale(VBase3(50,50,50))
    
    KeyboardMovement()
    #MouseDrag(geomPath)
    MouseCamera()
    MouseScaleZoom(geomPath)
    #render.setShaderAuto()
    p3dApp.run()
Пример #7
0
def renderCharts(facegraph, verts, vert_indices, lineset=None):

    from meshtool.filters.panda_filters.pandacore import getVertexData, attachLights, ensureCameraAt
    from meshtool.filters.panda_filters.pandacontrols import KeyboardMovement, MouseDrag, MouseScaleZoom, ButtonUtils
    from panda3d.core import GeomTriangles, Geom, GeomNode, GeomVertexFormat, GeomVertexData, GeomVertexWriter, LineSegs
    from direct.showbase.ShowBase import ShowBase

    vformat = GeomVertexFormat.getV3c4()
    vdata = GeomVertexData('tris', vformat, Geom.UHDynamic)

    vertex = GeomVertexWriter(vdata, 'vertex')
    color = GeomVertexWriter(vdata, 'color')

    colors = gen_color3(len(facegraph))
    numtris = 0
    for chart, data in facegraph.nodes_iter(data=True):
        curcolor = next(colors)
        for tri in data['tris']:
            triv = verts[vert_indices[tri]]
            vertex.addData3f(triv[0][0], triv[0][1], triv[0][2])
            vertex.addData3f(triv[1][0], triv[1][1], triv[1][2])
            vertex.addData3f(triv[2][0], triv[2][1], triv[2][2])
            color.addData4f(curcolor[0], curcolor[1], curcolor[2], 1)
            color.addData4f(curcolor[0], curcolor[1], curcolor[2], 1)
            color.addData4f(curcolor[0], curcolor[1], curcolor[2], 1)
            numtris += 1

    tris = GeomTriangles(Geom.UHDynamic)
    tris.addConsecutiveVertices(0, 3 * numtris)
    tris.closePrimitive()

    linenodes = []
    if lineset:
        for lines in lineset:
            ls = LineSegs()
            ls.setThickness(4)
            curcolor = next(colors)
            ls.setColor(curcolor[0] / 256.0, curcolor[1] / 256.0,
                        curcolor[2] / 256.0, 1)

            tuples = False
            for blah in lines:
                if isinstance(blah, tuple):
                    tuples = True
                break
            if tuples:
                for i, j in lines:
                    frompt = verts[i]
                    topt = verts[j]
                    ls.moveTo(frompt[0], frompt[1], frompt[2])
                    ls.drawTo(topt[0], topt[1], topt[2])
            else:
                for i in range(len(lines) - 1):
                    frompt = verts[lines[i]]
                    topt = verts[lines[i + 1]]
                    ls.moveTo(frompt[0], frompt[1], frompt[2])
                    ls.drawTo(topt[0], topt[1], topt[2])

            linenodes.append(ls.create())

    pgeom = Geom(vdata)
    pgeom.addPrimitive(tris)

    node = GeomNode("primitive")
    node.addGeom(pgeom)

    p3dApp = ShowBase()
    #attachLights(render)
    geomPath = render.attachNewNode(node)

    for linenode in linenodes:
        geomPath.attachNewNode(linenode)

    #geomPath.setRenderModeWireframe()

    ensureCameraAt(geomPath, base.cam)

    boundingSphere = geomPath.getBounds()
    base.cam.setPos(boundingSphere.getCenter() + boundingSphere.getRadius())

    base.cam.lookAt(boundingSphere.getCenter())

    KeyboardMovement()
    ButtonUtils(geomPath)
    MouseDrag(geomPath)
    MouseScaleZoom(geomPath)
    #render.setShaderAuto()
    p3dApp.run()
    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()
Пример #9
0
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