Example #1
0
	def draw(self):
		self.clearMesh()
		#print "vertices : %s" % (self.vertices)
		
		for p in self.vertices:
			self.vWriter.addData3f(p[0], p[1], p[2])
			self.cWriter.addData4f(self.color)
			
		lines = GeomLinestrips (Geom.UHStatic)
		for line in self.lines:
			lines.addVertices(line[0], line[1])
			lines.closePrimitive()
		self.geom.addPrimitive (lines)
Example #2
0
def makeSelectRect():
    ctup = (1, 1, 1, 1)
    fmt = GeomVertexFormat.getV3c4()
    vertexData = GeomVertexData('points', fmt, Geom.UHDynamic)

    points = (  #makes nice for Tristrips
        (0, 0, 0),
        (0, 0, 1),
        (1, 0, 0),
        (1, 0, 1),
    )

    verts = GeomVertexWriter(vertexData, 'vertex')
    color = GeomVertexWriter(vertexData, 'color')

    for point in points:
        verts.addData3f(*point)
        color.addData4f(*ctup)

    boxLines = GeomLinestrips(Geom.UHDynamic)
    boxLines.addVertices(0, 1, 3, 2)
    boxLines.addVertex(0)
    boxLines.closePrimitive()

    boxTris = GeomTristrips(Geom.UHDynamic)
    boxTris.addConsecutiveVertices(0, 3)
    boxTris.closePrimitive()

    box = Geom(vertexData)
    box.addPrimitive(boxLines)
    #box.addPrimitive(boxTris)

    return box
Example #3
0
    def _get_primitive() -> GeomLines:
        """Generate GeomLines primitive for bounding box lines."""
        primitive = GeomLinestrips(Geom.UHStatic)
        # 0, 1, 2, 3, 4, 5, 6, 7 - bounding box grey vertices

        # Bounding box
        for i in [0, 4]:
            for j in [0, 1, 2, 3, 0]:
                primitive.addVertex(i + j)
            primitive.closePrimitive()
        for i in range(4):
            primitive.addVertices(i, i + 4)
            primitive.closePrimitive()

        return primitive
Example #4
0
def makeSelectRect():
    ctup = (1,1,1,1)
    fmt = GeomVertexFormat.getV3c4()
    vertexData = GeomVertexData('points', fmt, Geom.UHDynamic)

    points = ( #makes nice for Tristrips
        (0,0,0),
        (0,0,1),
        (1,0,0),
        (1,0,1),
    )

    verts = GeomVertexWriter(vertexData, 'vertex')
    color = GeomVertexWriter(vertexData, 'color')

    for point in points:
        verts.addData3f(*point)
        color.addData4f(*ctup)

    boxLines = GeomLinestrips(Geom.UHDynamic)
    boxLines.addVertices(0,1,3,2)
    boxLines.addVertex(0)
    boxLines.closePrimitive()

    boxTris = GeomTristrips(Geom.UHDynamic)
    boxTris.addConsecutiveVertices(0,3)
    boxTris.closePrimitive()

    box = Geom(vertexData)
    box.addPrimitive(boxLines)
    #box.addPrimitive(boxTris)

    return box
Example #5
0
    def _create_geom(self):
        color = ConfigVariableColor('grid-color', DEFAULT_GRID_COLOR)

        radius = floor(self.size / (2 * self.spacing))
        diameter = (2 * radius + 1)
        start = -radius * self.spacing

        vertex_format = GeomVertexFormat.get_v3c4()
        vertex_data = GeomVertexData('grid', vertex_format, Geom.UH_static)
        vertex_data.set_num_rows(diameter * 4)
        vertex_writer = GeomVertexWriter(vertex_data, 'vertex')
        color_writer = GeomVertexWriter(vertex_data, 'color')

        for i, j in product(range(diameter), repeat=2):
            vertex_writer.add_data3f(start + i * self.spacing,
                                     start + j * self.spacing, 0.0)
            alpha = GRID_ALPHA - GRID_ALPHA * (
                Vector(i - radius, j - radius).norm() / radius)
            color_writer.add_data4f(color[0], color[1], color[2], alpha)

        primitive = GeomLinestrips(Geom.UH_static)
        for vertex in vertex_indexes(diameter):
            primitive.add_vertex(vertex)
        primitive.close_primitive()
        self.geom = Geom(vertex_data)
        self.geom.add_primitive(primitive)
Example #6
0
File: ui.py Project: tgbugs/desc
def makeGrid(rng = 1000, spacing = 10): #FIXME make this scale based on zoom???
    ctup = (.3,.3,.3,1)
    xs = range(-rng,rng+1,spacing)
    ys = xs

    fmt = GeomVertexFormat.getV3c4() #3 component vertex, w/ 4 comp color
    #fmt = GeomVertexFormat.getV3() #3 component vertex, w/ 4 comp color
    vertexData = GeomVertexData('points', fmt, Geom.UHStatic)

    verts = GeomVertexWriter(vertexData, 'vertex')
    color = GeomVertexWriter(vertexData, 'color')


    for i,d in enumerate(xs):
        switch1 = (-1) ** i * rng
        switch2 = (-1) ** i * -rng
        #print(d,switch1,0)
        verts.addData3f(d, switch1, 0)
        verts.addData3f(d, switch2, 0)
        color.addData4f(*ctup)
        color.addData4f(*ctup)

    for i,d in enumerate(ys):
        switch1 = (-1) ** i * rng
        switch2 = (-1) ** i * -rng
        verts.addData3f(switch1, d, 0)
        verts.addData3f(switch2, d, 0)
        color.addData4f(*ctup)
        color.addData4f(*ctup)

    gridLines = GeomLinestrips(Geom.UHStatic)
    gridLines.addConsecutiveVertices(0, vertexData.getNumRows())
    gridLines.closePrimitive()

    grid = Geom(vertexData)
    grid.addPrimitive(gridLines)
    return grid
Example #7
0
    def draw(self):
        self.clearMesh()
        #print "vertices : %s" % (self.vertices)

        for p in self.vertices:
            self.vWriter.addData3f(p[0], p[1], p[2])
            self.cWriter.addData4f(self.color)

        lines = GeomLinestrips(Geom.UHStatic)
        for line in self.lines:
            lines.addVertices(line[0], line[1])
            lines.closePrimitive()
        self.geom.addPrimitive(lines)
Example #8
0
def createCircle(color_vec4=Vec4(1., 1., 1., 1.), with_hole=False, num_of_verts=10, radius=1.):
    # Own Geometry
    format = GeomVertexFormat.getV3c4()
    vdata = GeomVertexData("colored_circle", format, Geom.UHStatic)
    vdata.setNumRows(4)

    vertexPosWriter = GeomVertexWriter(vdata, "vertex")

    # generates circles in x-y plane
    circle_points = math_utils.get_circle_vertices(num_of_verts=num_of_verts, radius=radius)

    for p in circle_points:
        vertexPosWriter.addData3f(p[0], p[1], p[2])

    # let's also add color to each vertex
    colorWriter = GeomVertexWriter(vdata, "color")

    for i in range(num_of_verts):
        colorWriter.addData4f(color_vec4)

    # make primitives and assign vertices to them (primitives and primitive
    # groups can be made independently from vdata, and are later assigned
    # to vdata)
    line = GeomLinestrips(Geom.UHStatic)

    line.add_consecutive_vertices(0, num_of_verts)

    if with_hole != True:
        line.add_vertex(0)  # connect it up at the end

    line.closePrimitive()  # the 1st primitive is finished

    # make a Geom object to hold the primitives
    geom = Geom(vdata)
    geom.addPrimitive(line)

    geom_node = GeomNode("colored_circle_node")
    geom_node.addGeom(geom)

    return geom_node
Example #9
0
 def primitives_lines(self, vdata):
     vertex = GeomVertexWriter(vdata, 'vertex')
     color = GeomVertexWriter(vdata, 'color')
     n = len(self.points)
     # Points
     for p in self.points:
         vertex.addData3f(p.x, p.y, p.z)
         color.addData4f(0.2, 0.2, 0.2, 0.0)
     # Triangles
     for a, b, c in self.vertices:
         lines = GeomLinestrips(Geom.UHStatic)
         lines.addVertices(a, b, c, a)
         lines.closePrimitive()
         yield lines
Example #10
0
    def _get_primitive_linestrips(line_count: int) -> GeomPrimitive:
        """Generate GeomLinestrips primitive for build plate grid.

        Parameters
        ----------
        line_count : int
            Line count for the generated GeomLinestrips primitive.

        Returns
        -------
        GeomLinestrips
            Generated primitive.
        """
        primitive = GeomLinestrips(Geom.UHStatic)

        for i in range(line_count):
            primitive.addVertices(2 * i, 2 * i + 1)
            primitive.closePrimitive()

        return primitive
Example #11
0
 def addLine(self, points):
     """
 Adds a line to class GeomNode from a pair of points
 """
     #Creates objects needed to draw a geometry on the HUD
     #The vertex data which will define the rendered geometry
     vertex_data = GeomVertexData("graph", GeomVertexFormat.getV3(),
                                  Geom.UHStatic)
     #The object that writes vertexes the vertex data
     writer = GeomVertexWriter(vertex_data, "vertex")
     for point in points:
         writer.add_data3f(point[0], 0, point[1])
     #Defines that this geometry represents a polyline
     primitive = GeomLinestrips(Geom.UHStatic)
     #Tells geometry how many verticies will be added(?)
     primitive.add_consecutive_vertices(0, 2)
     primitive.close_primitive()
     geometry = Geom(vertex_data)
     geometry.add_primitive(primitive)
     #Draws a graph on the HUD
     self.geom_node.add_geom(geometry)
Example #12
0
	def line (self, start, end):
		# since we're doing line segments, just vertices in our geom
		format = GeomVertexFormat.getV3()
	   
		# build our data structure and get a handle to the vertex column
		vdata = GeomVertexData ('', format, Geom.UHStatic)
		vertices = GeomVertexWriter (vdata, 'vertex')
		   
		# build a linestrip vertex buffer
		lines = GeomLinestrips (Geom.UHStatic)
	   
		vertices.addData3f (start[0], start[1], start[2])
		vertices.addData3f (end[0], end[1], end[2])
	   
		lines.addVertices (0, 1)
		
		lines.closePrimitive()
	   
		geom = Geom (vdata)
		geom.addPrimitive (lines)
		# Add our primitive to the geomnode
		#self.gnode.addGeom (geom)
		return geom
Example #13
0
def makeGrid(rng=1000, spacing=10):  #FIXME make this scale based on zoom???
    ctup = (.3, .3, .3, 1)
    xs = range(-rng, rng + 1, spacing)
    ys = xs

    fmt = GeomVertexFormat.getV3c4()  #3 component vertex, w/ 4 comp color
    #fmt = GeomVertexFormat.getV3() #3 component vertex, w/ 4 comp color
    vertexData = GeomVertexData('points', fmt, Geom.UHStatic)

    verts = GeomVertexWriter(vertexData, 'vertex')
    color = GeomVertexWriter(vertexData, 'color')

    for i, d in enumerate(xs):
        switch1 = (-1)**i * rng
        switch2 = (-1)**i * -rng
        #print(d,switch1,0)
        verts.addData3f(d, switch1, 0)
        verts.addData3f(d, switch2, 0)
        color.addData4f(*ctup)
        color.addData4f(*ctup)

    for i, d in enumerate(ys):
        switch1 = (-1)**i * rng
        switch2 = (-1)**i * -rng
        verts.addData3f(switch1, d, 0)
        verts.addData3f(switch2, d, 0)
        color.addData4f(*ctup)
        color.addData4f(*ctup)

    gridLines = GeomLinestrips(Geom.UHStatic)
    gridLines.addConsecutiveVertices(0, vertexData.getNumRows())
    gridLines.closePrimitive()

    grid = Geom(vertexData)
    grid.addPrimitive(gridLines)
    return grid
Example #14
0
    def generate(
            self
    ):  # call this after setting some of the variables to update it
        if not self.vertices:
            return

        if hasattr(self, 'geomNode'):
            self.geomNode.removeAllGeoms()

        static_mode = Geom.UHStatic if self.static else Geom.UHDynamic

        formats = {
            (0, 0, 0): GeomVertexFormat.getV3(),
            (1, 0, 0): GeomVertexFormat.getV3c4(),
            (0, 1, 0): GeomVertexFormat.getV3t2(),
            (0, 0, 1): GeomVertexFormat.getV3n3(),
            (1, 0, 1): GeomVertexFormat.getV3n3c4(),
            (1, 1, 0): GeomVertexFormat.getV3c4t2(),
            (0, 1, 1): GeomVertexFormat.getV3n3t2(),
            (1, 1, 1): GeomVertexFormat.getV3n3c4t2(),
        }

        vertex_format = formats[(bool(self.colors), bool(self.uvs),
                                 bool(self.normals))]
        vdata = GeomVertexData('name', vertex_format, static_mode)
        vdata.setNumRows(len(self.vertices))  # for speed

        vertexwriter = GeomVertexWriter(vdata, 'vertex')
        for v in self.vertices:
            vertexwriter.addData3f((v[0], v[2], v[1]))  # swap y and z

        if self.colors:
            colorwriter = GeomVertexWriter(vdata, 'color')
            for c in self.colors:
                colorwriter.addData4f(c)

        if self.uvs:
            uvwriter = GeomVertexWriter(vdata, 'texcoord')
            for uv in self.uvs:
                uvwriter.addData2f(uv[0], uv[1])

        if self.normals != None:
            normalwriter = GeomVertexWriter(vdata, 'normal')
            for norm in self.normals:
                normalwriter.addData3f((norm[0], norm[2], norm[1]))

        modes = {
            'triangle': GeomTriangles(static_mode),
            'tristrip': GeomTristrips(static_mode),
            'ngon': GeomTrifans(static_mode),
            'line': GeomLines(static_mode),
            'lines': GeomLinestrips(static_mode),
            'point': GeomPoints(static_mode),
        }
        if self.mode == 'line' and len(self.vertices) % 2 > 0:
            if len(self.vertices) == 1:
                self.mode = point
            print(
                'warning: number of vertices must be even for line mode, ignoring last vert'
            )
            self.vertices = self.vertices[:len(self.vertices) - 1]

        prim = modes[self.mode]

        if self._triangles:
            if isinstance(self._triangles[0], int):
                for t in self._triangles:
                    prim.addVertex(t)

            elif len(
                    self._triangles[0]
            ) >= 3:  # if tris are tuples like this: ((0,1,2), (1,2,3))
                for t in self._triangles:
                    if len(t) == 3:
                        for e in t:
                            prim.addVertex(e)
                    elif len(t) == 4:  # turn quad into tris
                        prim.addVertex(t[0])
                        prim.addVertex(t[1])
                        prim.addVertex(t[2])
                        prim.addVertex(t[2])
                        prim.addVertex(t[3])
                        prim.addVertex(t[0])

        else:
            prim.addConsecutiveVertices(0, len(self.vertices))

        prim.close_primitive()

        geom = Geom(vdata)
        geom.addPrimitive(prim)

        self.geomNode = GeomNode('mesh')
        self.geomNode.addGeom(geom)
        self.attachNewNode(self.geomNode)
        # print('finished')

        self.recipe = f'''Mesh(
Example #15
0
    def regenerateGeometry(self):
        #
        # Generate vertex data
        #

        numVerts = len(self.vertices)

        vdata = GeomVertexData("SolidFace", getFaceFormat(), GeomEnums.UHStatic)
        vdata.uncleanSetNumRows(len(self.vertices))

        vwriter = GeomVertexWriter(vdata, InternalName.getVertex())
        twriter = GeomVertexWriter(vdata, InternalName.getTexcoord())
        nwriter = GeomVertexWriter(vdata, InternalName.getNormal())
        tanwriter = GeomVertexWriter(vdata, InternalName.getTangent())
        bwriter = GeomVertexWriter(vdata, InternalName.getBinormal())

        for i in range(len(self.vertices)):
            vert = self.vertices[i]
            vwriter.setData3f(vert.pos)
            twriter.setData2f(vert.uv)
            nwriter.setData3f(self.plane.getNormal())
            tanwriter.setData3f(self.material.tangent)
            bwriter.setData3f(self.material.binormal)

        #
        # Generate indices
        #

        # Triangles in 3D view
        prim3D = GeomTriangles(GeomEnums.UHStatic)
        prim3D.reserveNumVertices((numVerts - 2) * 3)
        for i in range(1, numVerts - 1):
            prim3D.addVertices(i + 1, i, 0)
            prim3D.closePrimitive()

        # Line loop in 2D view.. using line strips
        prim2D = GeomLinestrips(GeomEnums.UHStatic)
        prim2D.reserveNumVertices(numVerts + 1)
        for i in range(numVerts):
            prim2D.addVertex(i)
        # Close off the line strip with the first vertex.. creating a line loop
        prim2D.addVertex(0)
        prim2D.closePrimitive()

        #
        # Generate mesh objects
        #

        geom3D = SolidFaceGeom(vdata)
        geom3D.setDrawMask(VIEWPORT_3D_MASK)
        geom3D.setPlaneCulled(True)
        geom3D.setPlane(self.plane)
        geom3D.addPrimitive(prim3D)
        self.index3D = self.solid.addFaceGeom(geom3D, self.state3D)

        geom3DLines = SolidFaceGeom(vdata)
        geom3DLines.addPrimitive(prim2D)
        geom3DLines.setDrawMask(VIEWPORT_3D_MASK)
        geom3DLines.setDraw(False)
        self.index3DLines = self.solid.addFaceGeom(geom3DLines, self.state3DLines)

        geom2D = SolidFaceGeom(vdata)
        geom2D.addPrimitive(prim2D)
        geom2D.setDrawMask(VIEWPORT_2D_MASK)
        self.index2D = self.solid.addFaceGeom(geom2D, self.state2D)

        self.geom3D = geom3D
        self.geom3DLines = geom3DLines
        self.geom2D = geom2D

        self.vdata = vdata

        self.hasGeometry = True
Example #16
0
File: ui.py Project: tgbugs/desc
def makeAxis(): #FIXME make this scale based on zoom???
    """
    x y z
    r g b
    """
    colors = (
        (1,0,0,1),
        (0,1,0,1),
        (0,0,1,1),

        (1,0,0,1),
        (0,1,0,1),
        (0,0,1,1),
    )
    points = (
        (0,0,0),
        (0,0,0),
        (0,0,0),
        (1,0,0),
        (0,1,0),
        (0,0,1),
    )

    fmt = GeomVertexFormat.getV3c4() #3 component vertex, w/ 4 comp color
    #fmt = GeomVertexFormat.getV3() #3 component vertex, w/ 4 comp color
    vertexData = GeomVertexData('points', fmt, Geom.UHStatic)

    verts = GeomVertexWriter(vertexData, 'vertex')
    color = GeomVertexWriter(vertexData, 'color')


    for p,c in zip(points,colors):
        verts.addData3f(*p)
        color.addData4f(*c)

    axisX = GeomLinestrips(Geom.UHStatic)
    axisX.addVertices(0,3)
    axisX.closePrimitive()

    axisY = GeomLinestrips(Geom.UHStatic)
    axisY.addVertices(1,4)
    axisY.closePrimitive()

    axisZ = GeomLinestrips(Geom.UHStatic)
    axisZ.addVertices(2,5)
    axisZ.closePrimitive()

    axis = Geom(vertexData)
    axis.addPrimitive(axisX)
    axis.addPrimitive(axisY)
    axis.addPrimitive(axisZ)
    return axis
Example #17
0
def makeAxis():  #FIXME make this scale based on zoom???
    """
    x y z
    r g b
    """
    colors = (
        (1, 0, 0, 1),
        (0, 1, 0, 1),
        (0, 0, 1, 1),
        (1, 0, 0, 1),
        (0, 1, 0, 1),
        (0, 0, 1, 1),
    )
    points = (
        (0, 0, 0),
        (0, 0, 0),
        (0, 0, 0),
        (1, 0, 0),
        (0, 1, 0),
        (0, 0, 1),
    )

    fmt = GeomVertexFormat.getV3c4()  #3 component vertex, w/ 4 comp color
    #fmt = GeomVertexFormat.getV3() #3 component vertex, w/ 4 comp color
    vertexData = GeomVertexData('points', fmt, Geom.UHStatic)

    verts = GeomVertexWriter(vertexData, 'vertex')
    color = GeomVertexWriter(vertexData, 'color')

    for p, c in zip(points, colors):
        verts.addData3f(*p)
        color.addData4f(*c)

    axisX = GeomLinestrips(Geom.UHStatic)
    axisX.addVertices(0, 3)
    axisX.closePrimitive()

    axisY = GeomLinestrips(Geom.UHStatic)
    axisY.addVertices(1, 4)
    axisY.closePrimitive()

    axisZ = GeomLinestrips(Geom.UHStatic)
    axisZ.addVertices(2, 5)
    axisZ.closePrimitive()

    axis = Geom(vertexData)
    axis.addPrimitive(axisX)
    axis.addPrimitive(axisY)
    axis.addPrimitive(axisZ)
    return axis
Example #18
0
def create_GeomNode_Simple_Polygon_with_Hole_LineStrips(symbol_geometries):
    color_vec4 = Vec4(1., 1., 1., 1.)

    outerpolygon_contour_points = 0.1 * symbol_geometries[0][0]
    inner_hole_contour_points = 0.1 * symbol_geometries[0][1]

    # outerpolygon_contour_points = (
    #     np.array([[0, 1], [-1, 0], [0, -1], [1, 0]], dtype=np.float64))

    # inner_hole_contour_points = (
    #     0.5 * np.array([[0, 1], [-1, 0], [0, -1], [1, 0]], dtype=np.float64))


    from panda3d.core import Triangulator, LPoint2d
    
    # tr = Triangulator()

    # for vertex in outerpolygon_contour_points: 
    #     vi = tr.addVertex(vertex[0], vertex[1])
    #     tr.addPolygonVertex(vi)

    # tr.beginHole()
    # for vertex in inner_hole_contour_points:
    #     vi = tr.addVertex(vertex[0], vertex[1])
    #     tr.addHoleVertex(vi)

    # tr.triangulate()
    
    # vertices = tr.getVertices()

    # indices = []
    # num_triangles = tr.getNumTriangles()
    # for i in range(num_triangles):
    #     indices.append([tr.getTriangleV0(i), tr.getTriangleV1(i), tr.getTriangleV2(i)])

    # Own Geometry

    # format = GeomVertexFormat.getV3c4t2()
    format = GeomVertexFormat.getV3c4()
    vdata = GeomVertexData("colored_polygon", format, Geom.UHStatic)
    vdata.setNumRows(4)

    # let's also add color to each vertex
    colorWriter = GeomVertexWriter(vdata, "color")
    vertexPosWriter = GeomVertexWriter(vdata, "vertex")

    for v in outerpolygon_contour_points: 
        vertexPosWriter.addData3f(v[0], 0, v[1])
        colorWriter.addData4f(color_vec4)
    
    for v in inner_hole_contour_points: 
        vertexPosWriter.addData3f(v[0], 0, v[1])
        colorWriter.addData4f(color_vec4)

    # make primitives and assign vertices to them (primitives and primitive
    # groups can be made independently from vdata, and are later assigned
    # to vdata)
    # tris = GeomTriangles(Geom.UHStatic) 

    tris = GeomLinestrips(Geom.UHStatic)

    # for index_triple in indices: 
    #     tris.addVertices(index_triple[0], index_triple[1], index_triple[2])
    tris.add_consecutive_vertices(0, len(outerpolygon_contour_points))
    tris.closePrimitive()

    tris.add_consecutive_vertices(len(outerpolygon_contour_points), len(inner_hole_contour_points))
    tris.closePrimitive()

    # make a Geom object to hold the primitives
    polygonGeom = Geom(vdata)  # vdata contains the vertex position/color/... buffers
    polygonGeom.addPrimitive(tris)  # tris contains the index buffer

    # now put quadGeom in a GeomNode. You can now position your geometry
    # in the scene graph.
    polygonGeomNode = GeomNode("colored_polygon_node")
    polygonGeomNode.addGeom(polygonGeom)

    return polygonGeomNode
Example #19
0
    def generate(
            self
    ):  # call this after setting some of the variables to update it
        if hasattr(self, 'geomNode'):
            self.geomNode.removeAllGeoms()

        static_mode = Geom.UHStatic if self.static else Geom.UHDynamic

        formats = {
            (0, 0, 0): GeomVertexFormat.getV3(),
            (1, 0, 0): GeomVertexFormat.getV3c4(),
            (0, 1, 0): GeomVertexFormat.getV3t2(),
            (0, 0, 1): GeomVertexFormat.getV3n3(),
            (1, 0, 1): GeomVertexFormat.getV3n3c4(),
            (1, 1, 0): GeomVertexFormat.getV3c4t2(),
            (0, 1, 1): GeomVertexFormat.getV3n3t2(),
            (1, 1, 1): GeomVertexFormat.getV3n3c4t2(),
        }

        vertex_format = formats[(bool(self.colors), bool(self.uvs),
                                 bool(self.normals))]
        vdata = GeomVertexData('name', vertex_format, static_mode)
        vdata.setNumRows(len(self.vertices))  # for speed

        vertexwriter = GeomVertexWriter(vdata, 'vertex')
        for v in self.vertices:
            vertexwriter.addData3f((v[0], v[2], v[1]))  # swap y and z

        if self.colors:
            colorwriter = GeomVertexWriter(vdata, 'color')
            for c in self.colors:
                colorwriter.addData4f(c)

        if self.uvs:
            uvwriter = GeomVertexWriter(vdata, 'texcoord')
            for uv in self.uvs:
                uvwriter.addData2f(uv[0], uv[1])

        if self.normals != None:
            normalwriter = GeomVertexWriter(vdata, 'normal')
            for norm in self.normals:
                normalwriter.addData3f((norm[0], norm[2], norm[1]))

        modes = {
            'triangle': GeomTriangles(static_mode),
            'tristrip': GeomTristrips(static_mode),
            'ngon': GeomTrifans(static_mode),
            'line': GeomLinestrips(static_mode),
            'point': GeomPoints(static_mode),
        }

        if self.mode != 'line' or not self._triangles:
            prim = modes[self.mode]

            if self._triangles:
                if isinstance(self._triangles[0], int):
                    for t in self._triangles:
                        prim.addVertex(t)

                elif len(
                        self._triangles[0]
                ) >= 3:  # if tris are tuples like this: ((0,1,2), (1,2,3))
                    for t in self._triangles:
                        if len(t) == 3:
                            for e in t:
                                prim.addVertex(e)
                        elif len(t) == 4:  # turn quad into tris
                            prim.addVertex(t[0])
                            prim.addVertex(t[1])
                            prim.addVertex(t[2])
                            prim.addVertex(t[2])
                            prim.addVertex(t[3])
                            prim.addVertex(t[0])

            else:
                prim.addConsecutiveVertices(0, len(self.vertices))

            prim.close_primitive()
            geom = Geom(vdata)
            geom.addPrimitive(prim)

        else:  # line with segments defnined in triangles
            for line in self._triangles:
                prim = modes[self.mode]
                for e in line:
                    prim.addVertex(e)
                prim.close_primitive()
                geom = Geom(vdata)
                geom.addPrimitive(prim)

        self.geomNode = GeomNode('mesh')
        self.geomNode.addGeom(geom)
        self.attachNewNode(self.geomNode)

        # if self.normals:
        #     self.normals = [tuple(e) for e in self.normals]
        self.recipe = dedent(f'''
            Mesh(
                vertices={[tuple(e) for e in self.vertices]},
                triangles={self._triangles},
                colors={[tuple(e) for e in self.colors]},
                uvs={self.uvs},
                normals={[tuple(e) for e in self.normals]},
                static={self.static},
                mode="{self.mode}",
                thickness={self.thickness}
            )
        ''')