コード例 #1
0
ファイル: _panda_cdhelper.py プロジェクト: Shogo-Hayakawa/wrs
def gen_polygons_cdnp(pdnp, name='cdnp_polygons', radius=.01):
    """
    :param trimeshmodel:
    :param name:
    :param radius: TODO
    :return:
    author: weiwei
    date: 20210204
    """
    collision_node = CollisionNode(name)
    # counter = 0
    for geom in pdnp.findAllMatches('**/+GeomNode'):
        geom_node = geom.node()
        for g in range(geom_node.getNumGeoms()):
            geom = geom_node.getGeom(g).decompose()
            vdata = geom.getVertexData()
            vreader = GeomVertexReader(vdata, 'vertex')
            for p in range(geom.getNumPrimitives()):
                prim = geom.getPrimitive(p)
                for p2 in range(prim.getNumPrimitives()):
                    s = prim.getPrimitiveStart(p2)
                    e = prim.getPrimitiveEnd(p2)
                    v = []
                    for vi in range(s, e):
                        vreader.setRow(prim.getVertex(vi))
                        # TODO expand radius by moving along normal directions
                        v.append(vreader.getData3f())
                    col_poly = CollisionPolygon(*v)
                    collision_node.addSolid(col_poly)
                    # print("polygon ", counter)
                    # counter += 1
    return collision_node
コード例 #2
0
ファイル: wezupath.py プロジェクト: janEntikan/syndactyly
    def make_nav_graph(self, mesh, edge_neighbors_only=True, draw_graph=False):
        '''Creates a navigation graph from a 3D mesh,
        A node is created for each triangle in the mesh,
        nodes are connected either by shared edges (edge_neighbors_only=True),
        or by shared vertex (edge_neighbors_only=False).
        '''
        _get_center=self._get_center
        _get_neighbors=self._get_neighbors
        _distance=self._distance
        _round_vec3_to_tuple=self._round_vec3_to_tuple

        #make a list of the triangles
        #get the id of each vert in each triangle and
        #get the position of each vert
        triangles=[]
        vert_dict=defaultdict(set)
        #only works ok with one geom so flatten the mesh befor comming here
        geom=self.find_first_geom(mesh)
        vdata = geom.getVertexData()
        vertex = GeomVertexReader(vdata, 'vertex')
        for prim in geom.getPrimitives():
            num_primitives=prim.getNumPrimitives()
            for p in range(num_primitives):
                #print ('primitive {} of {}'.format(p, num_primitives))
                s = prim.getPrimitiveStart(p)
                e = prim.getPrimitiveEnd(p)
                triangle={'vertex_id':[], 'vertex_pos':[]}
                for i in range(s, e):
                    vi = prim.getVertex(i)
                    vertex.setRow(vi)
                    v =[round(i, 4) for i in vertex.getData3f() ]
                    vertex_id=tuple([round(i*4.0)/4.0 for i in v])
                    triangle['vertex_pos'].append(v)
                    triangle['vertex_id'].append(vertex_id)
                    vert_dict[vertex_id].add(len(triangles))#len(self.triangles) is the triangle id
                triangles.append(triangle)

        #get centers and neighbors
        for i, triangle in enumerate(triangles):
            #print ('triangle ', i ,' of ', len(self.triangles) )
            triangle['center']=_get_center(triangle['vertex_pos'])
            triangle['neighbors']=_get_neighbors(triangle['vertex_id'], vert_dict, i, edge_neighbors_only)
        #construct the dict
        edges={}
        cost={}
        positions={}
        for i, triangle in enumerate(triangles):
            #print ('neighbor ', i)
            edges[i]=triangle['neighbors']
            cost[i]={}
            start=triangle['center']
            positions[i]=start
            for neighbor in triangle['neighbors']:
                cost[i][neighbor]=_distance(start, triangles[neighbor]['center'])
        lookup={_round_vec3_to_tuple(value):key for (key, value) in positions.items()}
        self.graph= {'neighbors':edges, 'cost':cost, 'pos':positions, 'lookup':lookup}
        if draw_graph:
            self.draw_connections()
コード例 #3
0
 def getTriangleAsPoints(self, ind, vreader=None):
     if vreader is None:
         vreader = GeomVertexReader(self.vdata, 'vertex')
     pts = []
     for vi in self.getTriangleVertexIndices(ind):
         vreader.setRow(vi)
         pt = vreader.getData3f()
         pts.append(Point3(*pt))
     return Triangle.TriangleTuple(pts[0], pts[1], pts[2])
コード例 #4
0
 def getTriangleAsPoints(self, ind, vreader=None):
     if vreader is None:
         vreader = GeomVertexReader(self.vdata, 'vertex')
     pts = []
     for vi in self.getTriangleVertexIndices(ind):
         vreader.setRow(vi)
         pt = vreader.getData3f()
         pts.append(Point3(*pt))
     return Triangle.TriangleTuple(pts[0], pts[1], pts[2])
コード例 #5
0
def processPrimitive(prim, vdata, mesh):
    vertex = GeomVertexReader(vdata, 'vertex')

    prim = prim.decompose()

    for p in range(prim.getNumPrimitives()):
        s = prim.getPrimitiveStart(p)
        e = prim.getPrimitiveEnd(p)
        vertices = []
        for i in range(s, e):
            vi = prim.getVertex(i)
            vertices.append(vi)
            vertex.setRow(vi)
            v = vertex.getData3f()
            print("prim %s has vertex %s: %s" % (p, vi, repr(v)))
        mesh.add_face(f=vertices)
コード例 #6
0
def get3DTrianglesFromModel(model):
    
    # Calculate the net transformation
    transform = model.getNetTransform()
    transformMat = transform.getMat()
    
    # Get geometry data from GeomNode instances inside the model
    geomNodes = model.findAllMatches('**/+GeomNode')
    
    triangles = []
    for nodePath in geomNodes:
        geomNode = nodePath.node()
        
        for n in range(geomNode.getNumGeoms()):
            geom = geomNode.getGeom(n)
            vdata = geom.getVertexData()
            
            for k in range(geom.getNumPrimitives()):
                prim = geom.getPrimitive(k)
                vertex = GeomVertexReader(vdata, 'vertex')
                assert isinstance(prim, (GeomTristrips, GeomTriangles))
                
                # Decompose into triangles
                prim = prim.decompose()
                for p in range(prim.getNumPrimitives()):
                    s = prim.getPrimitiveStart(p)
                    e = prim.getPrimitiveEnd(p)
                    
                    triPts = []
                    for i in range(s, e):
                        vi = prim.getVertex(i)
                        vertex.setRow(vi)
                        v = vertex.getData3f()
                        
                        # Apply transformation
                        v = transformMat.xformPoint(v)
                        
                        triPts.append([v.x, v.y, v.z])

                    triangles.append(triPts)
            
    triangles = np.array(triangles)
            
    return triangles
コード例 #7
0
ファイル: main.py プロジェクト: antoineMoPa/open_space_drive
        def processPrimitive(prim, vdata):
            vertex = GeomVertexReader(vdata, 'vertex')
            prim = prim.decompose()

            for p in range(prim.getNumPrimitives()):
                s = prim.getPrimitiveStart(p)
                e = prim.getPrimitiveEnd(p)
                last = None

                roadBuilder.addPrim()

                for i in range(s, e):
                    vi = prim.getVertex(i)
                    vertex.setRow(vi)
                    v = vertex.getData3()
                    if last is not None:
                        self.road_segments.append([last, v])
                        roadBuilder.addSegment(last, v)
                    last = v
コード例 #8
0
    def completeTunnelPath(self):
        self.geomNode.addGeom(self.geom)

        if self.triStrips.getNumPrimitives() == 0:
            return

        floorMesh = CollisionFloorMesh()
        vertexReader = GeomVertexReader(self.vertexData, 'vertex')

        print "Original prims:", self.triStrips.getNumPrimitives()

        p = 0
        for i in range(self.triStrips.getNumPrimitives()):
            v0 = self.triStrips.getPrimitiveStart(i)
            ve = self.triStrips.getPrimitiveEnd(i)
            j = v0 + 4

            # add the bottom triangles
            vertexReader.setRow(self.triStrips.getVertex(j))
            floorMesh.addVertex(Point3(vertexReader.getData3f()))
            vertexReader.setRow(self.triStrips.getVertex(j + 1))
            floorMesh.addVertex(Point3(vertexReader.getData3f()))
            vertexReader.setRow(self.triStrips.getVertex(j + 2))
            floorMesh.addVertex(Point3(vertexReader.getData3f()))
            floorMesh.addTriangle(p, p + 1, p + 2)

            vertexReader.setRow(self.triStrips.getVertex(j + 3))
            floorMesh.addVertex(Point3(vertexReader.getData3f()))
            floorMesh.addTriangle(p + 1, p + 3, p + 2)

            p += 4

        # this adds every triangle, but is not appropriate for a closed path


#         tris = self.triStrips.decompose()
#         print "Decomposed prims:",tris.getNumPrimitives()
#         p = 0
#         for i in range(tris.getNumPrimitives()):
#             v0 = tris.getPrimitiveStart(i)
#             ve = tris.getPrimitiveEnd(i)
#             if v0 < ve:
#                 vertexReader.setRow(tris.getVertex(v0))
#                 floorMesh.addVertex(Point3(vertexReader.getData3f()))
#                 vertexReader.setRow(tris.getVertex(v0+1))
#                 floorMesh.addVertex(Point3(vertexReader.getData3f()))
#                 vertexReader.setRow(tris.getVertex(v0+2))
#                 floorMesh.addVertex(Point3(vertexReader.getData3f()))
#                 floorMesh.addTriangle(p, p+1, p+2)
#                 p += 3

        self.floorCollNode.addSolid(floorMesh)
コード例 #9
0
    def completeQuadPath(self):
        self.geomNode.addGeom(self.geom)

        if self.triStrips.getNumPrimitives() == 0:
            return

        floorMesh = CollisionFloorMesh()
        vertexReader = GeomVertexReader(self.vertexData, 'vertex')
        tris = self.triStrips.decompose()
        print "Decomposed prims:", tris.getNumPrimitives()
        p = 0
        for i in range(tris.getNumPrimitives()):
            v0 = tris.getPrimitiveStart(i)
            ve = tris.getPrimitiveEnd(i)
            if v0 < ve:
                vertexReader.setRow(tris.getVertex(v0))
                floorMesh.addVertex(Point3(vertexReader.getData3f()))
                vertexReader.setRow(tris.getVertex(v0 + 1))
                floorMesh.addVertex(Point3(vertexReader.getData3f()))
                vertexReader.setRow(tris.getVertex(v0 + 2))
                floorMesh.addVertex(Point3(vertexReader.getData3f()))
                floorMesh.addTriangle(p, p + 1, p + 2)
                p += 3

        self.floorCollNode.addSolid(floorMesh)
コード例 #10
0
    def completeTunnelPath(self):
        self.geomNode.addGeom(self.geom)
        
        if self.triStrips.getNumPrimitives() == 0:
            return
        
        floorMesh = CollisionFloorMesh()
        vertexReader = GeomVertexReader(self.vertexData, 'vertex') 
        
        print "Original prims:",self.triStrips.getNumPrimitives()
        
        p = 0
        for i in range(self.triStrips.getNumPrimitives()):
            v0 = self.triStrips.getPrimitiveStart(i)
            ve = self.triStrips.getPrimitiveEnd(i)
            j = v0 + 4
            
            # add the bottom triangles
            vertexReader.setRow(self.triStrips.getVertex(j))
            floorMesh.addVertex(Point3(vertexReader.getData3f()))
            vertexReader.setRow(self.triStrips.getVertex(j+1))
            floorMesh.addVertex(Point3(vertexReader.getData3f()))
            vertexReader.setRow(self.triStrips.getVertex(j+2))
            floorMesh.addVertex(Point3(vertexReader.getData3f()))
            floorMesh.addTriangle(p, p+1, p+2)
            
            vertexReader.setRow(self.triStrips.getVertex(j+3))
            floorMesh.addVertex(Point3(vertexReader.getData3f()))
            floorMesh.addTriangle(p+1, p+3, p+2)

            p += 4
        
        # this adds every triangle, but is not appropriate for a closed path
#         tris = self.triStrips.decompose()
#         print "Decomposed prims:",tris.getNumPrimitives()
#         p = 0
#         for i in range(tris.getNumPrimitives()):
#             v0 = tris.getPrimitiveStart(i)
#             ve = tris.getPrimitiveEnd(i)
#             if v0 < ve:
#                 vertexReader.setRow(tris.getVertex(v0))
#                 floorMesh.addVertex(Point3(vertexReader.getData3f()))
#                 vertexReader.setRow(tris.getVertex(v0+1))
#                 floorMesh.addVertex(Point3(vertexReader.getData3f()))
#                 vertexReader.setRow(tris.getVertex(v0+2))
#                 floorMesh.addVertex(Point3(vertexReader.getData3f()))
#                 floorMesh.addTriangle(p, p+1, p+2)
#                 p += 3
        
        self.floorCollNode.addSolid(floorMesh)
コード例 #11
0
def rebuildGeomNodesToColPolys(incomingNode,
                               relativeTo=None,
                               filter=lambda n: True):
    ''' 
    Converts GeomNodes into CollisionPolys in a straight 1-to-1 conversion 

    Returns a new NodePath containing the CollisionNodes 
    
    If the geometry is at all complex, running the result of this through colTree
    should improve performance.
    
    '''
    parent = NodePath('cGeomConversionParent')
    for c in incomingNode.findAllMatches('**/+GeomNode'):
        if not filter(c): continue
        if relativeTo:
            xform = c.getMat(relativeTo).xformPoint
        else:
            xform = (c.getMat(incomingNode) *
                     (incomingNode.getMat())).xformPoint
        geomNode = c.node()
        for g in range(geomNode.getNumGeoms()):
            geom = geomNode.getGeom(g).decompose()
            vdata = geom.getVertexData()
            vreader = GeomVertexReader(vdata, 'vertex')
            cChild = CollisionNode("")
            for p in range(geom.getNumPrimitives()):
                prim = geom.getPrimitive(p)
                for p2 in range(prim.getNumPrimitives()):
                    s = prim.getPrimitiveStart(p2)
                    e = prim.getPrimitiveEnd(p2)
                    if e - s > 2:
                        v = []
                        for vi in range(s, e):
                            vreader.setRow(prim.getVertex(vi))
                            v.append(Point3(xform(vreader.getData3f())))
                        colPoly = CollisionPolygon(*v)
                        cChild.addSolid(colPoly)
            n = parent.attachNewNode(cChild)
    return parent
コード例 #12
0
    def completePath(self):
        self.geomNode.addGeom(self.geom)

        if self.triStrips.getNumPrimitives() == 0:
            return

        floorMesh = CollisionFloorMesh()

        tris = self.triStrips.decompose()
        p = 0
        vertexReader = GeomVertexReader(self.vertexData, "vertex")
        for i in range(tris.getNumPrimitives()):
            v0 = tris.getPrimitiveStart(i)
            ve = tris.getPrimitiveEnd(i)
            if v0 < ve:
                vertexReader.setRow(tris.getVertex(v0))
                floorMesh.addVertex(Point3(vertexReader.getData3f()))
                vertexReader.setRow(tris.getVertex(v0 + 1))
                floorMesh.addVertex(Point3(vertexReader.getData3f()))
                vertexReader.setRow(tris.getVertex(v0 + 2))
                floorMesh.addVertex(Point3(vertexReader.getData3f()))
                floorMesh.addTriangle(p, p + 1, p + 2)
                p += 3

        self.floorCollNode.addSolid(floorMesh)
コード例 #13
0
def rebuildGeomNodesToColPolys (incomingNode,relativeTo=None): 
    ''' 
    Converts GeomNodes into CollisionPolys in a straight 1-to-1 conversion 

    Returns a new NodePath containing the CollisionNodes 
    ''' 
    
    parent = NodePath('cGeomConversionParent') 
    for c in incomingNode.findAllMatches('**/+GeomNode'): 
        if relativeTo:
            xform=c.getMat(relativeTo).xformPoint
        else:
            xform=(c.getMat(incomingNode)*(incomingNode.getMat())).xformPoint
        gni = 0 
        geomNode = c.node() 
        for g in range(geomNode.getNumGeoms()): 
            geom = geomNode.getGeom(g).decompose() 
            vdata = geom.getVertexData() 
            vreader = GeomVertexReader(vdata, 'vertex') 
            cChild = CollisionNode('cGeom-%s-gni%i' % (c.getName(), gni)) 
            
            gni += 1 
            for p in range(geom.getNumPrimitives()): 
                prim = geom.getPrimitive(p) 
                for p2 in range(prim.getNumPrimitives()): 
                    s = prim.getPrimitiveStart(p2) 
                    e = prim.getPrimitiveEnd(p2) 
                    v = [] 
                    for vi in range (s, e): 
                        vreader.setRow(prim.getVertex(vi)) 
                        v.append (xform(vreader.getData3f())) 
                    colPoly = CollisionPolygon(*v) 
                    cChild.addSolid(colPoly) 

            n=parent.attachNewNode (cChild) 
            #n.show()
            
    return parent 
コード例 #14
0
def getSurfaceAreaFromGeom(geom, transform=None):
    
    totalArea = 0.0
    for k in range(geom.getNumPrimitives()):
        prim = geom.getPrimitive(k)
        vdata = geom.getVertexData()
        vertex = GeomVertexReader(vdata, 'vertex')
        assert isinstance(prim, (GeomTristrips, GeomTriangles))
         
        # Decompose into triangles
        prim = prim.decompose()
        for p in range(prim.getNumPrimitives()):
            s = prim.getPrimitiveStart(p)
            e = prim.getPrimitiveEnd(p)
             
            triPts = []
            for i in range(s, e):
                vi = prim.getVertex(i)
                vertex.setRow(vi)
                v = vertex.getData3f()
                
                # Apply transformation
                if transform is not None:
                    v = transform.xformPoint(v)
                
                triPts.append([v.x, v.y, v.z])
            triPts = np.array(triPts)

            # calculate the semi-perimeter and area
            a = np.linalg.norm(triPts[0] - triPts[1], 2)
            b = np.linalg.norm(triPts[1] - triPts[2], 2)
            c = np.linalg.norm(triPts[2] - triPts[0], 2)
            s = (a + b + c) / 2
            area = (s*(s-a)*(s-b)*(s-c)) ** 0.5
            totalArea += area

    return totalArea
コード例 #15
0
def rebuildGeomNodesToColPolys (incomingNode,relativeTo=None,filter=lambda n:True): 
    ''' 
    Converts GeomNodes into CollisionPolys in a straight 1-to-1 conversion 

    Returns a new NodePath containing the CollisionNodes 
    
    If the geometry is at all complex, running the result of this through colTree
    should improve performance.
    
    '''
    parent = NodePath('cGeomConversionParent') 
    for c in incomingNode.findAllMatches('**/+GeomNode'): 
        if not filter(c): continue
        if relativeTo:
            xform=c.getMat(relativeTo).xformPoint
        else:
            xform=(c.getMat(incomingNode)*(incomingNode.getMat())).xformPoint
        geomNode = c.node() 
        for g in range(geomNode.getNumGeoms()): 
            geom = geomNode.getGeom(g).decompose() 
            vdata = geom.getVertexData() 
            vreader = GeomVertexReader(vdata, 'vertex') 
            cChild = CollisionNode("") 
            for p in range(geom.getNumPrimitives()): 
                prim = geom.getPrimitive(p) 
                for p2 in range(prim.getNumPrimitives()): 
                    s = prim.getPrimitiveStart(p2) 
                    e = prim.getPrimitiveEnd(p2) 
                    if e-s>2:
                        v = []
                        for vi in range (s, e): 
                            vreader.setRow(prim.getVertex(vi)) 
                            v.append(Point3(xform(vreader.getData3f())) )
                        colPoly = CollisionPolygon(*v) 
                        cChild.addSolid(colPoly) 
            n=parent.attachNewNode(cChild)   
    return parent 
コード例 #16
0
ファイル: main.py プロジェクト: C0MPU73R/Panda3D-Astron
def drawBody(nodePath,
             vdata,
             pos,
             vecList,
             radius=1,
             keepDrawing=True,
             numVertices=8):

    circleGeom = Geom(vdata)

    vertWriter = GeomVertexWriter(vdata, "vertex")
    colorWriter = GeomVertexWriter(vdata, "color")
    normalWriter = GeomVertexWriter(vdata, "normal")
    drawReWriter = GeomVertexRewriter(vdata, "drawFlag")
    texReWriter = GeomVertexRewriter(vdata, "texcoord")

    startRow = vdata.getNumRows()
    vertWriter.setRow(startRow)
    colorWriter.setRow(startRow)
    normalWriter.setRow(startRow)

    sCoord = 0

    if (startRow != 0):
        texReWriter.setRow(startRow - numVertices)
        sCoord = texReWriter.getData2f().getX() + 1

        drawReWriter.setRow(startRow - numVertices)
        if (drawReWriter.getData1f() == False):
            sCoord -= 1

    drawReWriter.setRow(startRow)
    texReWriter.setRow(startRow)

    angleSlice = 2 * math.pi / numVertices
    currAngle = 0

    #axisAdj=LMatrix4.rotateMat(45, axis)*LMatrix4.scaleMat(radius)*LMatrix4.translateMat(pos)

    perp1 = vecList[1]
    perp2 = vecList[2]

    # vertex information is written here
    for i in range(numVertices):
        adjCircle = pos + \
            (perp1 * math.cos(currAngle) + perp2 * math.sin(currAngle)) * \
            radius
        normal = perp1 * math.cos(currAngle) + perp2 * math.sin(currAngle)
        normalWriter.addData3f(normal)
        vertWriter.addData3f(adjCircle)
        texReWriter.addData2f(sCoord, (i + 0.001) / (numVertices - 1))
        colorWriter.addData4f(0.5, 0.5, 0.5, 1)
        drawReWriter.addData1f(keepDrawing)
        currAngle += angleSlice

    if startRow == 0:
        return

    drawReader = GeomVertexReader(vdata, "drawFlag")
    drawReader.setRow(startRow - numVertices)

    # we cant draw quads directly so we use Tristrips
    if drawReader.getData1i() != 0:
        lines = GeomTristrips(Geom.UHStatic)
        half = int(numVertices * 0.5)
        for i in range(numVertices):
            lines.addVertex(i + startRow)
            if i < half:
                lines.addVertex(i + startRow - half)
            else:
                lines.addVertex(i + startRow - half - numVertices)

        lines.addVertex(startRow)
        lines.addVertex(startRow - half)
        lines.closePrimitive()
        lines.decompose()
        circleGeom.addPrimitive(lines)

        circleGeomNode = GeomNode("Debug")
        circleGeomNode.addGeom(circleGeom)

        # I accidentally made the front-face face inwards. Make reverse makes the tree render properly and
        # should cause any surprises to any poor programmer that tries to use
        # this code
        circleGeomNode.setAttrib(CullFaceAttrib.makeReverse(), 1)
        global numPrimitives
        numPrimitives += numVertices * 2

        nodePath.attachNewNode(circleGeomNode)
コード例 #17
0
def getColorAttributesFromVertexData(geom, transform=None):
    
    colorsTotalAreas = dict()
    for k in range(geom.getNumPrimitives()):
        prim = geom.getPrimitive(k)
        vdata = geom.getVertexData()
        assert isinstance(prim, (GeomTristrips, GeomTriangles))
        
        # Check if color is defined for vertex
        isColorDefined = False        
        for i, geomVertexCol in enumerate(vdata.getFormat().getColumns()):
            if geomVertexCol.getContents() == GeomEnums.CColor:
                isColorDefined = True
                break
        assert isColorDefined
        
        vertex = GeomVertexReader(vdata, 'vertex')
        vertexColor = GeomVertexReader(vdata, 'color')
                
        # Decompose into triangles
        prim = prim.decompose()
        for p in range(prim.getNumPrimitives()):
            s = prim.getPrimitiveStart(p)
            e = prim.getPrimitiveEnd(p)
            
            color = None
            triPts = []
            for i in range(s, e):
                vi = prim.getVertex(i)
                vertex.setRow(vi)
                vertexColor.setRow(vi)
                v = vertex.getData3f()
                
                # NOTE: all vertex of the same polygon (triangles) should have the same color,
                #       so only grab it once.
                if color is None:
                    color = vertexColor.getData4f()
                    color = (color[0], color[1], color[2], color[3])
            
                triPts.append([v.x, v.y, v.z])
            triPts = np.array(triPts)
                
            # Apply transformation
            if transform is not None:
                v = transform.xformPoint(v)
            
            # calculate the semi-perimeter and area
            a = np.linalg.norm(triPts[0] - triPts[1], 2)
            b = np.linalg.norm(triPts[1] - triPts[2], 2)
            c = np.linalg.norm(triPts[2] - triPts[0], 2)
            s = (a + b + c) / 2
            area = (s*(s-a)*(s-b)*(s-c)) ** 0.5
            
            if color in colorsTotalAreas:
                colorsTotalAreas[color] += area
            else:
                colorsTotalAreas[color] = area
    
    areas = []        
    rgbColors = []
    transparencies = []
    for color, area in colorsTotalAreas.iteritems():
        areas.append(area)
        rgbColors.append(list(color[:3]))
        
        # Check transparency
        isTransparent = color[3] < 1.0
        transparencies.append(isTransparent)
            
    return areas, rgbColors, transparencies
コード例 #18
0
def processModel(path):
    scene = loadModel(path)
    if scene.isEmpty():
        print("Error converting `{0}`!".format(path))
        return

    fPath = Filename.fromOsSpecific(path)
    outputPath = Filename.toOsSpecific(
        Filename("bam2smd/" + fPath.getDirname() + "/" +
                 fPath.getBasenameWoExtension() + "/"))
    if not os.path.exists(outputPath):
        os.makedirs(outputPath)

    isCharacter = not scene.find("**/+Character").isEmpty()
    isAnimation = not scene.find("**/+AnimBundleNode").isEmpty()

    if not isAnimation:
        if isCharacter:
            nodes = Skeleton(scene.findAllMatches("**/+Character"))
        else:
            nodes = Skeleton(None)

        names = {}

        for geomNp in scene.findAllMatches("**/+GeomNode"):
            smd = "version 1\n"

            smd += str(nodes)

            smd += "skeleton\n"
            smd += "time 0\n"
            if isCharacter:
                boneIds = sorted(nodes.bones.keys())
                for iBone in range(len(boneIds)):
                    boneId = boneIds[iBone]
                    bone = nodes.bones[boneId]
                    if isinstance(bone, CharacterJoint):
                        boneTform = bone.getTransformState()
                        pos = boneTform.getPos()
                        boneMat = boneTform.getMat().getUpper3()
                        #boneMat.transposeInPlace()
                        rot = mat3NormalizedToEulO(boneMat)
                    else:
                        pos = Vec3()
                        rot = Vec3()
                    smd += boneFrameString(boneId, pos, rot)
            else:
                smd += "0  0 0 0  0 0 0\n"
            smd += "end\n"

            smd += "triangles\n"
            for geom in geomNp.node().getGeoms():
                geom = geom.decompose()
                vdata = geom.getVertexData()
                blendTable = vdata.getTransformBlendTable()
                for prim in geom.getPrimitives():
                    numTris = prim.getNumPrimitives()
                    for nTri in range(numTris):
                        start = prim.getPrimitiveStart(nTri)
                        end = prim.getPrimitiveEnd(nTri)

                        smd += "no_material\n"

                        for primVert in range(start, end):
                            vertIdx = prim.getVertex(primVert)

                            reader = GeomVertexReader(vdata)

                            reader.setColumn(InternalName.getVertex())
                            reader.setRow(vertIdx)
                            pos = reader.getData3f()

                            uv = Vec2(0, 0)
                            if vdata.hasColumn(InternalName.getTexcoord()):
                                reader.setColumn(InternalName.getTexcoord())
                                reader.setRow(vertIdx)
                                uv = reader.getData2f()

                            norm = Vec3.forward()
                            if vdata.hasColumn(InternalName.getNormal()):
                                reader.setColumn(InternalName.getNormal())
                                reader.setRow(vertIdx)
                                norm = reader.getData3f()

                            smd += "0  {0:.6f} {1:.6f} {2:.6f}  {3:.6f} {4:.6f} {5:.6f}  {6:.6f} {7:.6f}  ".format(
                                pos[0], pos[1], pos[2], norm[0], norm[1],
                                norm[2], uv[0], uv[1])
                            if (isCharacter and blendTable
                                    and vdata.getNumArrays() > 1
                                    and vdata.getArray(1).hasColumn(
                                        InternalName.getTransformBlend())):
                                reader.setColumn(
                                    1,
                                    vdata.getArray(
                                        1).getArrayFormat().getColumn(
                                            InternalName.getTransformBlend()))
                                reader.setRow(vertIdx)
                                nBlend = reader.getData1i()
                                blend = blendTable.getBlend(nBlend)
                                numTransforms = blend.getNumTransforms()
                                smd += "{0} ".format(numTransforms)
                                for nTransform in range(numTransforms):
                                    transform = blend.getTransform(nTransform)
                                    if isinstance(transform,
                                                  JointVertexTransform):
                                        boneId = nodes.getBoneId(
                                            transform.getJoint())
                                        smd += "{0} {1:.6f} ".format(
                                            boneId,
                                            blend.getWeight(nTransform))
                            else:
                                smd += "1 0 1.0"
                            smd += "\n"
            smd += "end\n"

            smdFile = geomNp.getName()
            if len(smdFile) == 0:
                smdFile = getUnknownName()
            elif names.get(smdFile, 0) > 0:
                smdFile = smdFile + "_{0}".format(names[smdFile])
                names[smdFile] += 1
            else:
                names[smdFile] = 1
            smdFile += ".smd"

            outFile = open(outputPath + "\\" + smdFile, "w")
            outFile.write(smd)
            outFile.flush()
            outFile.close()
    else:
        bundles = scene.findAllMatches("**/+AnimBundleNode")
        bundle = bundles[0].node().getBundle()
        nodes = Skeleton(bundles)

        smd = "version 1\n"

        smd += str(nodes)

        smd += "skeleton\n"
        numFrames = bundle.getNumFrames()
        boneIds = sorted(nodes.bones.keys())
        for iFrame in range(numFrames):
            smd += "time {0}\n".format(iFrame)
            for iBone in range(len(boneIds)):
                bone = nodes.getBone(boneIds[iBone])
                if isinstance(bone, AnimChannelACMatrixSwitchType):
                    boneFrameMat = Mat4()
                    bone.getValueNoScaleShear(iFrame, boneFrameMat)
                    boneFrameTransform = TransformState.makeMat(boneFrameMat)
                    pos = boneFrameTransform.getPos()
                    rotMat = boneFrameMat.getUpper3()
                    #rotMat.transposeInPlace()
                    rot = mat3NormalizedToEulO(rotMat)
                    smd += boneFrameString(boneIds[iBone], pos, rot)

        smd += "end\n"

        smdFile = fPath.getBasenameWoExtension() + ".smd"
        outFile = open(outputPath + "\\" + smdFile, "w")
        outFile.write(smd)
        outFile.flush()
        outFile.close()
コード例 #19
0
	def createModelClone(self,modelFilename):

		newVisualCar = loader.loadModel(modelFilename)
		geomNodeCollection = newVisualCar.findAllMatches('**/+GeomNode')

		simpleTris=[]

		self.unmodifiedVertexData=[]

		for nodePath in geomNodeCollection:
			geomNode = nodePath.node()
			for i in range(geomNode.getNumGeoms()):

				geom = geomNode.getGeom(i)

				vdata = geom.getVertexData()
				vertex = GeomVertexReader(vdata, 'vertex')
				while not vertex.isAtEnd():
					v=vertex.getData3f()
					vertexModelX,vertexModelY,vertexModelZ=v
					self.unmodifiedVertexData.append([vertexModelX,vertexModelY,vertexModelZ])

				for primitiveIndex in range(geom.getNumPrimitives()):
					prim=geom.getPrimitive(primitiveIndex)
					prim=prim.decompose()
					for p in range(prim.getNumPrimitives()):
						s = prim.getPrimitiveStart(p)
						e = prim.getPrimitiveEnd(p)
						singleTriData=[]
						for i in range(s, e):
							vertex.setRow(prim.getVertex(s)) 
							vi = prim.getVertex(i)
							singleTriData.append(vi)
						simpleTris.append(singleTriData)

		simpleVertices=self.unmodifiedVertexData

		format=GeomVertexFormat.getV3()

		vdata=GeomVertexData('shadow', format, Geom.UHDynamic)
		self.pandaVertexData=vdata
		vertex=GeomVertexWriter(vdata, 'vertex')
		for vertexIndex in range(len(simpleVertices)):
			simpleVertex=simpleVertices[vertexIndex]
			vertex.addData3f(0,0,0)

		tris=GeomTriangles(Geom.UHStatic)
		for index in range(len(simpleTris)):
			simpleTri=simpleTris[index]
			tris.addVertex(simpleTri[0])
			tris.addVertex(simpleTri[1])
			tris.addVertex(simpleTri[2])
			tris.closePrimitive()

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

		snode=GeomNode('shadow')
		snode.addGeom(shadow)

		self.snode=snode
コード例 #20
0
    def __init__(self, entity, mesh=None, center=(0,0,0)):
        super().__init__()
        center = Vec3(center)
        if mesh == None and entity.model:
            mesh = entity.model
            # print('''auto generating mesh collider from entity's mesh''')

        self.node_path = entity.attachNewNode(CollisionNode('CollisionNode'))
        self.collision_polygons = []

        if isinstance(mesh, Mesh):
            if mesh.triangles:
                triangles = mesh.triangles
                if not isinstance(mesh.triangles[0], tuple):
                    triangles = [triangles[i:i + 3] for i in range(0, len(triangles), 3)] # group into groups of three

                for tri in triangles:
                    if len(tri) == 3:
                        poly = CollisionPolygon(
                            Vec3(mesh.vertices[tri[2]]),
                            Vec3(mesh.vertices[tri[1]]),
                            Vec3(mesh.vertices[tri[0]]),
                            )
                        self.collision_polygons.append(poly)
                    elif len(tri) == 4:
                        poly = CollisionPolygon(
                            Vec3(mesh.vertices[tri[3]]),
                            Vec3(mesh.vertices[tri[2]]),
                            Vec3(mesh.vertices[tri[1]]),
                            Vec3(mesh.vertices[tri[0]]))
                        self.collision_polygons.append(poly)


            elif mesh.mode == 'triangle': # no triangle list, so take 3 and 3 vertices
                for i in range(0, len(mesh.vertices), 3):
                    poly = CollisionPolygon(
                        Vec3(mesh.vertices[i+2]),
                        Vec3(mesh.vertices[i+1]),
                        Vec3(mesh.vertices[i]),
                        )
                    self.collision_polygons.append(poly)


            else:
                print('error: mesh collider does not support', mesh.mode, 'mode')
                return None


        elif isinstance(mesh, NodePath):
            from panda3d.core import GeomVertexReader
            verts = []
            geomNodeCollection = mesh.findAllMatches('**/+GeomNode')
            for nodePath in geomNodeCollection:
                geomNode = nodePath.node()
                for i in range(geomNode.getNumGeoms()):
                    geom = geomNode.getGeom(i)
                    vdata = geom.getVertexData()
                    for i in range(geom.getNumPrimitives()):
                        prim = geom.getPrimitive(i)
                        vertex_reader = GeomVertexReader(vdata, 'vertex')
                        prim = prim.decompose()

                        for p in range(prim.getNumPrimitives()):
                            s = prim.getPrimitiveStart(p)
                            e = prim.getPrimitiveEnd(p)
                            for i in range(s, e):
                                vi = prim.getVertex(i)
                                vertex_reader.setRow(vi)
                                verts.append(vertex_reader.getData3())

            for i in range(0, len(verts)-3, 3):
                p = CollisionPolygon(Vec3(verts[i+2]), Vec3(verts[i+1]), Vec3(verts[i]))
                self.collision_polygons.append(p)


        node = self.node_path.node()
        for poly in self.collision_polygons:
            node.addSolid(poly)
        self.visible = False
コード例 #21
0
    def movePmTo(self, dest_index):
        geom = self.geomPath.node().modifyGeom(0)
        vertdata = geom.modifyVertexData()
        prim = geom.modifyPrimitive(0)
        indexdata = prim.modifyVertices()
        
        indexrewriter = GeomVertexRewriter(indexdata)
        indexrewriter.setColumn(0)
        nextTriangleIndex = indexdata.getNumRows()
        
        vertwriter = GeomVertexWriter(vertdata, 'vertex')
        numverts = vertdata.getNumRows()
        vertwriter.setRow(numverts)
        normalwriter = GeomVertexWriter(vertdata, 'normal')
        normalwriter.setRow(numverts)
        uvwriter = GeomVertexWriter(vertdata, 'texcoord')
        uvwriter.setRow(numverts)
        
        while self.pm_index < dest_index:
            for op_index in range(len(self.pm_refinements[self.pm_index])):
                vals = self.pm_refinements[self.pm_index][op_index]
                op = vals[0]
                if op == PM_OP.TRIANGLE_ADDITION:
                    indexrewriter.setRow(nextTriangleIndex)
                    nextTriangleIndex += 3
                    indexrewriter.addData1i(vals[1])
                    indexrewriter.addData1i(vals[2])
                    indexrewriter.addData1i(vals[3])
                elif op == PM_OP.INDEX_UPDATE:
                    #TODO: ugly workaround for p3d 1.7 bug, change to below for 1.8
                    indexreader = GeomVertexReader(indexdata)
                    indexreader.setColumn(0)
                    indexreader.setRow(vals[1])
                    oldval = indexreader.getData1i()
                    del indexreader
                    
                    #indexrewriter.setRow(vals[1])
                    #oldval = indexrewriter.getData1i()
                    
                    indexrewriter.setRow(vals[1])
                    indexrewriter.setData1i(vals[2])
                    self.pm_refinements[self.pm_index][op_index] = (op, vals[1], oldval)
                elif op == PM_OP.VERTEX_ADDITION:
                    numverts += 1
                    vertwriter.addData3f(vals[1], vals[2], vals[3])
                    normalwriter.addData3f(vals[4], vals[5], vals[6])
                    uvwriter.addData2f(vals[7], vals[8])
                
            self.pm_index += 1

        while self.pm_index > dest_index:
            self.pm_index -= 1
            for op_index in range(len(self.pm_refinements[self.pm_index])):
                vals = self.pm_refinements[self.pm_index][op_index]
                op = vals[0]
                if op == PM_OP.TRIANGLE_ADDITION:
                    nextTriangleIndex -= 3
                elif op == PM_OP.INDEX_UPDATE:
                    #TODO: ugly workaround for p3d 1.7 bug, change to below for 1.8
                    indexreader = GeomVertexReader(indexdata)
                    indexreader.setColumn(0)
                    indexreader.setRow(vals[1])
                    oldval = indexreader.getData1i()
                    del indexreader
                    
                    #indexrewriter.setRow(vals[1])
                    #oldval = indexrewriter.getData1i()
                    
                    indexrewriter.setRow(vals[1])
                    indexrewriter.setData1i(vals[2])
                    self.pm_refinements[self.pm_index][op_index] = (op, vals[1], oldval)
                elif op == PM_OP.VERTEX_ADDITION:
                    numverts -= 1

        if nextTriangleIndex < indexdata.getNumRows():
            indexdata.setNumRows(nextTriangleIndex)
        if numverts < vertdata.getNumRows():
            vertdata.setNumRows(numverts)
コード例 #22
0
ファイル: main.py プロジェクト: AdrianF98/Toontown-2-Revised
def drawBody(nodePath, vdata, pos, vecList, radius=1, keepDrawing=True, numVertices=8):

    circleGeom = Geom(vdata)

    vertWriter = GeomVertexWriter(vdata, "vertex")
    colorWriter = GeomVertexWriter(vdata, "color")
    normalWriter = GeomVertexWriter(vdata, "normal")
    drawReWriter = GeomVertexRewriter(vdata, "drawFlag")
    texReWriter = GeomVertexRewriter(vdata, "texcoord")

    startRow = vdata.getNumRows()
    vertWriter.setRow(startRow)
    colorWriter.setRow(startRow)
    normalWriter.setRow(startRow)

    sCoord = 0

    if (startRow != 0):
        texReWriter.setRow(startRow - numVertices)
        sCoord = texReWriter.getData2f().getX() + 1

        drawReWriter.setRow(startRow - numVertices)
        if(drawReWriter.getData1f() == False):
            sCoord -= 1

    drawReWriter.setRow(startRow)
    texReWriter.setRow(startRow)

    angleSlice = 2 * math.pi / numVertices
    currAngle = 0

    #axisAdj=LMatrix4.rotateMat(45, axis)*LMatrix4.scaleMat(radius)*LMatrix4.translateMat(pos)

    perp1 = vecList[1]
    perp2 = vecList[2]

    # vertex information is written here
    for i in range(numVertices):
        adjCircle = pos + \
            (perp1 * math.cos(currAngle) + perp2 * math.sin(currAngle)) * \
            radius
        normal = perp1 * math.cos(currAngle) + perp2 * math.sin(currAngle)
        normalWriter.addData3f(normal)
        vertWriter.addData3f(adjCircle)
        texReWriter.addData2f(sCoord, (i + 0.001) / (numVertices - 1))
        colorWriter.addData4f(0.5, 0.5, 0.5, 1)
        drawReWriter.addData1f(keepDrawing)
        currAngle += angleSlice

    drawReader = GeomVertexReader(vdata, "drawFlag")
    drawReader.setRow(startRow - numVertices)

    # we cant draw quads directly so we use Tristrips
    if (startRow != 0) & (drawReader.getData1f() != False):
        lines = GeomTristrips(Geom.UHStatic)
        half = int(numVertices * 0.5)
        for i in range(numVertices):
            lines.addVertex(i + startRow)
            if i < half:
                lines.addVertex(i + startRow - half)
            else:
                lines.addVertex(i + startRow - half - numVertices)

        lines.addVertex(startRow)
        lines.addVertex(startRow - half)
        lines.closePrimitive()
        lines.decompose()
        circleGeom.addPrimitive(lines)

        circleGeomNode = GeomNode("Debug")
        circleGeomNode.addGeom(circleGeom)

        # I accidentally made the front-face face inwards. Make reverse makes the tree render properly and
        # should cause any surprises to any poor programmer that tries to use
        # this code
        circleGeomNode.setAttrib(CullFaceAttrib.makeReverse(), 1)
        global numPrimitives
        numPrimitives += numVertices * 2

        nodePath.attachNewNode(circleGeomNode)
コード例 #23
0
    def __init__(self, entity, mesh=None, center=(0,0,0)):
        super().__init__()
        center = Vec3(center)
        if mesh == None and entity.model:
            mesh = entity.model
            # print('''auto generating mesh collider from entity's mesh''')

        # from ursina import Mesh     # this part is obsolete if I use the old obj loading
        # if not isinstance(mesh, Mesh):
        #     from ursina import mesh_importer
        #     mesh = eval(mesh_importer.obj_to_ursinamesh(name=mesh.name, save_to_file=False))
        #     flipped_verts = [v*Vec3(-1,1,1) for v in mesh.vertices] # have to flip it on x axis for some reason
        #     mesh.vertices = flipped_verts
        self.node_path = entity.attachNewNode(CollisionNode('CollisionNode'))
        self.node = self.node_path.node()
        self.collision_polygons = list()

        if isinstance(mesh, Mesh):
            if mesh.triangles:
                for tri in mesh.triangles:
                    if len(tri) == 3:
                        poly = CollisionPolygon(
                            Vec3(mesh.vertices[tri[2]]),
                            Vec3(mesh.vertices[tri[1]]),
                            Vec3(mesh.vertices[tri[0]]),
                            )
                        self.collision_polygons.append(poly)
                    elif len(tri) == 4:
                        poly = CollisionPolygon(
                            Vec3(mesh.vertices[tri[2]]),
                            Vec3(mesh.vertices[tri[1]]),
                            Vec3(mesh.vertices[tri[0]]))
                        self.collision_polygons.append(poly)
                        poly = CollisionPolygon(
                            Vec3(mesh.vertices[tri[0]]),
                            Vec3(mesh.vertices[tri[3]]),
                            Vec3(mesh.vertices[tri[2]]))
                        self.collision_polygons.append(poly)

            elif mesh.mode == 'triangle':
                for i in range(0, len(mesh.vertices), 3):
                    poly = CollisionPolygon(
                        Vec3(mesh.vertices[i+2]),
                        Vec3(mesh.vertices[i+1]),
                        Vec3(mesh.vertices[i]),
                        )
                    self.collision_polygons.append(poly)


            else:
                print('error: mesh collider does not support', mesh.mode, 'mode')
                return None


        elif isinstance(mesh, NodePath):
            from panda3d.core import GeomVertexReader
            verts = []
            geomNodeCollection = mesh.findAllMatches('**/+GeomNode')
            for nodePath in geomNodeCollection:
                geomNode = nodePath.node()
                for i in range(geomNode.getNumGeoms()):
                    geom = geomNode.getGeom(i)
                    vdata = geom.getVertexData()
                    for i in range(geom.getNumPrimitives()):
                        prim = geom.getPrimitive(i)
                        vertex_reader = GeomVertexReader(vdata, 'vertex')
                        prim = prim.decompose()

                        for p in range(prim.getNumPrimitives()):
                            s = prim.getPrimitiveStart(p)
                            e = prim.getPrimitiveEnd(p)
                            for i in range(s, e):
                                vi = prim.getVertex(i)
                                vertex_reader.setRow(vi)
                                verts.append(vertex_reader.getData3())

            for i in range(0, len(verts)-3, 3):
                p = CollisionPolygon(Vec3(verts[i+2]), Vec3(verts[i+1]), Vec3(verts[i]))
                self.collision_polygons.append(p)


        for poly in self.collision_polygons:
            self.node.addSolid(poly)
        self.visible = False
コード例 #24
0
    def createModelClone(self, modelFilename):

        newVisualCar = loader.loadModel(modelFilename)
        geomNodeCollection = newVisualCar.findAllMatches('**/+GeomNode')

        simpleTris = []

        self.unmodifiedVertexData = []

        for nodePath in geomNodeCollection:
            geomNode = nodePath.node()
            for i in range(geomNode.getNumGeoms()):

                geom = geomNode.getGeom(i)

                vdata = geom.getVertexData()
                vertex = GeomVertexReader(vdata, 'vertex')
                while not vertex.isAtEnd():
                    v = vertex.getData3f()
                    vertexModelX, vertexModelY, vertexModelZ = v
                    self.unmodifiedVertexData.append(
                        [vertexModelX, vertexModelY, vertexModelZ])

                for primitiveIndex in range(geom.getNumPrimitives()):
                    prim = geom.getPrimitive(primitiveIndex)
                    prim = prim.decompose()
                    for p in range(prim.getNumPrimitives()):
                        s = prim.getPrimitiveStart(p)
                        e = prim.getPrimitiveEnd(p)
                        singleTriData = []
                        for i in range(s, e):
                            vertex.setRow(prim.getVertex(s))
                            vi = prim.getVertex(i)
                            singleTriData.append(vi)
                        simpleTris.append(singleTriData)

        simpleVertices = self.unmodifiedVertexData

        format = GeomVertexFormat.getV3()

        vdata = GeomVertexData('shadow', format, Geom.UHDynamic)
        self.pandaVertexData = vdata
        vertex = GeomVertexWriter(vdata, 'vertex')
        for vertexIndex in range(len(simpleVertices)):
            simpleVertex = simpleVertices[vertexIndex]
            vertex.addData3f(0, 0, 0)

        tris = GeomTriangles(Geom.UHStatic)
        for index in range(len(simpleTris)):
            simpleTri = simpleTris[index]
            tris.addVertex(simpleTri[0])
            tris.addVertex(simpleTri[1])
            tris.addVertex(simpleTri[2])
            tris.closePrimitive()

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

        snode = GeomNode('shadow')
        snode.addGeom(shadow)

        self.snode = snode
コード例 #25
0
    def movePmTo(self, dest_index):
        geom = self.geomPath.node().modifyGeom(0)
        vertdata = geom.modifyVertexData()
        prim = geom.modifyPrimitive(0)
        indexdata = prim.modifyVertices()

        indexrewriter = GeomVertexRewriter(indexdata)
        indexrewriter.setColumn(0)
        nextTriangleIndex = indexdata.getNumRows()

        vertwriter = GeomVertexWriter(vertdata, 'vertex')
        numverts = vertdata.getNumRows()
        vertwriter.setRow(numverts)
        normalwriter = GeomVertexWriter(vertdata, 'normal')
        normalwriter.setRow(numverts)
        uvwriter = GeomVertexWriter(vertdata, 'texcoord')
        uvwriter.setRow(numverts)

        while self.pm_index < dest_index:
            for op_index in range(len(self.pm_refinements[self.pm_index])):
                vals = self.pm_refinements[self.pm_index][op_index]
                op = vals[0]
                if op == PM_OP.TRIANGLE_ADDITION:
                    indexrewriter.setRow(nextTriangleIndex)
                    nextTriangleIndex += 3
                    indexrewriter.addData1i(vals[1])
                    indexrewriter.addData1i(vals[2])
                    indexrewriter.addData1i(vals[3])
                elif op == PM_OP.INDEX_UPDATE:
                    #TODO: ugly workaround for p3d 1.7 bug, change to below for 1.8
                    indexreader = GeomVertexReader(indexdata)
                    indexreader.setColumn(0)
                    indexreader.setRow(vals[1])
                    oldval = indexreader.getData1i()
                    del indexreader

                    #indexrewriter.setRow(vals[1])
                    #oldval = indexrewriter.getData1i()

                    indexrewriter.setRow(vals[1])
                    indexrewriter.setData1i(vals[2])
                    self.pm_refinements[self.pm_index][op_index] = (op,
                                                                    vals[1],
                                                                    oldval)
                elif op == PM_OP.VERTEX_ADDITION:
                    numverts += 1
                    vertwriter.addData3f(vals[1], vals[2], vals[3])
                    normalwriter.addData3f(vals[4], vals[5], vals[6])
                    uvwriter.addData2f(vals[7], vals[8])

            self.pm_index += 1

        while self.pm_index > dest_index:
            self.pm_index -= 1
            for op_index in range(len(self.pm_refinements[self.pm_index])):
                vals = self.pm_refinements[self.pm_index][op_index]
                op = vals[0]
                if op == PM_OP.TRIANGLE_ADDITION:
                    nextTriangleIndex -= 3
                elif op == PM_OP.INDEX_UPDATE:
                    #TODO: ugly workaround for p3d 1.7 bug, change to below for 1.8
                    indexreader = GeomVertexReader(indexdata)
                    indexreader.setColumn(0)
                    indexreader.setRow(vals[1])
                    oldval = indexreader.getData1i()
                    del indexreader

                    #indexrewriter.setRow(vals[1])
                    #oldval = indexrewriter.getData1i()

                    indexrewriter.setRow(vals[1])
                    indexrewriter.setData1i(vals[2])
                    self.pm_refinements[self.pm_index][op_index] = (op,
                                                                    vals[1],
                                                                    oldval)
                elif op == PM_OP.VERTEX_ADDITION:
                    numverts -= 1

        if nextTriangleIndex < indexdata.getNumRows():
            indexdata.setNumRows(nextTriangleIndex)
        if numverts < vertdata.getNumRows():
            vertdata.setNumRows(numverts)