示例#1
0
def make_axes():
    """Make an axes geometry.

    Returns:
        Geom -- p3d geometry
    """
    vformat = GeomVertexFormat.get_v3c4()
    vdata = GeomVertexData('vdata', vformat, Geom.UHStatic)
    vdata.uncleanSetNumRows(6)

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

    for x, y, z in np.eye(3):
        vertex.addData3(0, 0, 0)
        color.addData4(x, y, z, 1)
        vertex.addData3(x, y, z)
        color.addData4(x, y, z, 1)

    prim = GeomLines(Geom.UHStatic)
    prim.addNextVertices(6)

    geom = Geom(vdata)
    geom.addPrimitive(prim)
    return geom
示例#2
0
def make_node_from_mesh(points: np.ndarray,
                        faces: np.ndarray,
                        normals: np.ndarray,
                        rgba: np.ndarray = np.asarray([1, 1, 1, 1])):
    vertex_normal_format = GeomVertexFormat.get_v3n3c4()

    v_data = GeomVertexData('sphere', vertex_normal_format, Geom.UHStatic)
    num_rows = np.max([points.shape[0], faces.shape[0]])
    v_data.setNumRows(int(num_rows))

    vertex_data = GeomVertexWriter(v_data, 'vertex')
    normal_data = GeomVertexWriter(v_data, 'normal')
    color_data = GeomVertexWriter(v_data, 'color')

    for point, normal in zip(points, normals):
        vertex_data.addData3(point[0], point[1], point[2])
        normal_data.addData3(normal[0], normal[1], normal[2])
        color_data.addData4(rgba[0], rgba[1], rgba[2], rgba[3])
    geom = Geom(v_data)
    for face in faces:
        tri = GeomTriangles(Geom.UHStatic)
        p_1 = points[face[0], :]
        p_2 = points[face[1], :]
        p_3 = points[face[2], :]
        norm = normals[face[0], :]
        if np.dot(np.cross(p_2 - p_1, p_3 - p_2), norm) < 0:
            tri.add_vertices(face[2], face[1], face[0])
        else:
            tri.add_vertices(face[0], face[1], face[2])
        geom.addPrimitive(tri)

    node = GeomNode('gnode')
    node.addGeom(geom)
    return node
示例#3
0
    def create_model(self):
        vdata = GeomVertexData('name', Diagram.gformat, Geom.UHStatic)
        vdata.setNumRows(len(self.values)*2)

        vertex = GeomVertexWriter(vdata, 'vertex')
        color = GeomVertexWriter(vdata, 'color')
        prim = GeomTristrips(Geom.UHStatic)

        i = 0
        for x, z in self.values:
            vertex.addData3(0, x, 0)
            color.addData4(0, 0, 1, 1)
            prim.addVertex(i)

            vertex.addData3(0, x, z/100)
            color.addData4(0, 0, 1, 1)
            prim.addVertex(i+1)

            i += 2

        prim.closePrimitive()

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

        node = GeomNode('gnode')
        node.addGeom(diagram_geom)

        node.setTag('entity_type', self.__class__.__name__)
        node.setTag('entity_id', self.entity_id)

        model_parent = self.parent.geom[0]
        parent_scale = model_parent.getScale()

        nodePath = render.attachNewNode(node)
        nodePath.reparentTo(model_parent)
        nodePath.set_two_sided(True)
        nodePath.setLightOff()

        node_parent = self.parent.start.geom[0]



        L = self.parent.longitude()
        h = 1
        nodePath.setScale(h / parent_scale[2], 1 / parent_scale[1], 1 / parent_scale[0])

        nodePath.wrtReparentTo(node_parent)
        """
        model = app.base.loader.loadModel("data/geom/plate")
        model.set_two_sided(True)
        model.setTag('entity_type', self.__class__.__name__)
        model.setTag('entity_id', self.entity_id)
        self.geom = [model]"""

        self.update_model()
示例#4
0
class VChunkGeom:
    def __init__(self, voxel_unit_size):

        self.voxel_unit_size = voxel_unit_size
        self.triangles = GeomTriangles(Geom.UHStatic)

        self.format = GeomVertexFormat.getV3n3c4()
        self.v_data = GeomVertexData('square', self.format, Geom.UHStatic)

        self.vertex = GeomVertexWriter(self.v_data, 'vertex')
        self.normal = GeomVertexWriter(self.v_data, 'normal')
        self.color = GeomVertexWriter(self.v_data, 'color')

    def add_face(self, face, cube_x, cube_y, cube_z, color: LVector4):

        start_index = self.vertex.getWriteRow()

        vector = LVector3(cube_x * self.voxel_unit_size.x,
                          cube_y * self.voxel_unit_size.z,
                          cube_z * self.voxel_unit_size.y)

        for offset in face.offsets:

            scaled_offset = LVector3(self.voxel_unit_size.x * offset[0],
                                     self.voxel_unit_size.z * offset[1],
                                     self.voxel_unit_size.y * offset[2])

            self.vertex.addData3(vector + scaled_offset)
            self.normal.addData3(face.normal)
            self.color.addData4(color)

        self.add_triangles(start_index)

    def add_triangles(self, start_index):
        self.triangles.addVertices(start_index, start_index + 1,
                                   start_index + 2)
        self.triangles.closePrimitive()
        self.triangles.addVertices(start_index, start_index + 2,
                                   start_index + 3)
        self.triangles.closePrimitive()

    def get_geom(self):
        geom = Geom(self.v_data)
        geom.addPrimitive(self.triangles)

        return geom
示例#5
0
class Boundary(VisibleObject):
    ignore_light = True
    default_shown = True
    def __init__(self, name, points = [], color = None):
        VisibleObject.__init__(self, name)
        self.visible = True
        if color is None:
            color = bodyClasses.get_orbit_color('boundary')
        self.color = color
        self.points = points

    def check_settings(self):
        self.set_shown(settings.show_boundaries)

    def set_points_list(self, points):
        self.points = points

    def create_instance(self):
        self.vertexData = GeomVertexData('vertexData', GeomVertexFormat.getV3c4(), Geom.UHStatic)
        self.vertexWriter = GeomVertexWriter(self.vertexData, 'vertex')
        self.colorwriter = GeomVertexWriter(self.vertexData, 'color')
        for point in self.points:
            position = point.project(0, self.context.observer.camera_global_pos, self.context.observer.infinity)
            self.vertexWriter.addData3f(*position)
            self.colorwriter.addData4(srgb_to_linear(self.color))
        self.lines = GeomLines(Geom.UHStatic)
        index = 0
        for i in range(len(self.points)-1):
            self.lines.addVertex(index)
            self.lines.addVertex(index+1)
            self.lines.closePrimitive()
            index += 1
        self.geom = Geom(self.vertexData)
        self.geom.addPrimitive(self.lines)
        self.node = GeomNode("boundary")
        self.node.addGeom(self.geom)
        self.instance = NodePath(self.node)
        self.instance.setRenderModeThickness(settings.boundary_thickness)
        self.instance.reparentTo(self.context.annotation)
        self.instance.setBin('background', settings.boundaries_depth)
        self.instance.set_depth_write(False)
示例#6
0
    def _write_geom_data_colors(
        cls,
        geom_data: GeomVertexData,
        layer_vertex_count: int,
        color: Tuple[float, float, float, float] = _COLOR_DEFAULT,
    ):
        """Write color data into the provided GeomVertexData.

        Parameters
        ----------
        geom_data : GeomVertexData
            GeomVertexData to write color data into.
        layer_vertex_count : int
            Total vertex count in layer.
        color : Tuple[float, float, float, float]
            Target vertex color.
        """
        writer_color = GeomVertexWriter(geom_data, "color")

        for _ in range(layer_vertex_count):
            writer_color.addData4(color)
示例#7
0
    def __init__(self, vertices, normals, colours, tetrahedra):
        super().__init__()
        self.n_vertices = len(vertices)
        self.n_tetrahedra = len(tetrahedra)

        self.data = GeomVertexData(repr(self), format4, Geom.UHDynamic)
        self.data.setNumRows(self.n_vertices)
        self.prim = GeomLinesAdjacency(Geom.UHDynamic)

        vertex_writer = GeomVertexWriter(self.data, "vertex")
        normal_writer = GeomVertexWriter(self.data, "normal")
        colour_writer = GeomVertexWriter(self.data, "colour")

        for vertex in vertices:
            vertex_writer.addData4(*vertex)

        for normal in normals:
            normal_writer.addData4(*normal)

        for colour in colours:
            colour_writer.addData4(*colour)

        for tetra in tetrahedra:
            self.prim.addVertices(*tetra)
            self.prim.closePrimitive()

        self.geom = Geom(self.data)
        self.geom.addPrimitive(self.prim)
        self.node = GeomNode(repr(self))
        self.node.addGeom(self.geom)
示例#8
0
    def _get_geom_vertex_data(cls, size: LVector3d,
                              name: str) -> GeomVertexData:
        """Generate GeomVertexData for the bounding box.

        Parameters
        ----------
        size : LVector3d
            Bounding box size.
        name : str
            Name for generated GeomVertexData.

        Returns
        -------
        GeomVertexData
            Bounding box GeomVertexData.
        """
        geom_data = GeomVertexData(name, cls._GEOM_VERTEX_FORMAT,
                                   Geom.UHStatic)
        geom_data.setNumRows(8)  # 8 cube vertices

        writer_color = GeomVertexWriter(geom_data, "color")
        writer_vertex = GeomVertexWriter(geom_data, "vertex")

        # VERTEX COLORS
        for i in range(8):
            writer_color.addData4(cls._COLOR_BOUNDING_BOX_DEFAULT)

        # VERTEX COORDS

        # Bounding box
        writer_vertex.addData3d(0, 0, 0)
        writer_vertex.addData3d(size.x, 0, 0)
        writer_vertex.addData3d(size.x, 0, size.z)
        writer_vertex.addData3d(0, 0, size.z)
        writer_vertex.addData3d(0, size.y, 0)
        writer_vertex.addData3d(size.x, size.y, 0)
        writer_vertex.addData3d(size.x, size.y, size.z)
        writer_vertex.addData3d(0, size.y, size.z)

        return geom_data
示例#9
0
def make_cloud_node(pts, col=LColorf(1.0, 0.0, 0.0, 1.0)):
    ptCloudData = GeomVertexData("PointCloudData", GeomVertexFormat.getV3c4(),
                                 GeomEnums.UH_static)
    vertexWriter = GeomVertexWriter(ptCloudData, Thread.getCurrentThread())
    vertexWriter.setColumn("vertex")
    colorWriter = GeomVertexWriter(ptCloudData, Thread.getCurrentThread())
    colorWriter.setColumn("color")

    for (x, y, z) in pts:
        vertexWriter.addData3(x, y, z)
        colorWriter.addData4(col)

    geomPts = GeomPoints(GeomEnums.UH_static)
    geomPts.addConsecutiveVertices(0, len(pts))
    geomPts.closePrimitive()

    geom = Geom(ptCloudData)
    geom.addPrimitive(geomPts)

    node = GeomNode("PointCloudNode")
    node.addGeom(geom, RenderState.makeEmpty())
    return node
示例#10
0
    def __init__(self, data, timescale, scale, record, dark_matter,
                 no_ordinary_matter):
        self.data = data
        self.scale = scale
        self.timescale = timescale
        self.dark_matter = dark_matter
        self.no_ordinary_matter = no_ordinary_matter

        self.n_particles = self.data.shape[1]
        ShowBase.__init__(self)
        vdata = GeomVertexData('galaxies', GeomVertexFormat.get_v3c4(),
                               Geom.UHStatic)
        vdata.setNumRows(self.n_particles)
        self.vertex = GeomVertexWriter(vdata, 'vertex')
        color = GeomVertexWriter(vdata, 'color')
        for i in range(self.n_particles):
            if (self.data[0][i].dark_matter and
                    not self.dark_matter) or (not self.data[0][i].dark_matter
                                              and self.no_ordinary_matter):
                continue
            pos = self.data[0][i].pos / self.scale
            self.vertex.addData3(*pos)
            color.addData4(1, 1, 1, 1)
        prim = GeomPoints(Geom.UHStatic)
        prim.add_consecutive_vertices(0, self.n_particles - 1)
        geom = Geom(vdata)
        geom.addPrimitive(prim)
        node = GeomNode('gnode')
        node.addGeom(geom)
        nodePath = self.render.attach_new_node(node)
        nodePath.setRenderModeThickness(2)
        self.disableMouse()
        self.useTrackball()
        self.trackball.node().set_pos(0, 100, 0)
        self.trackball.node().set_hpr(90, 0, 90)
        self.setBackgroundColor(0, 0, 0)
        self.taskMgr.add(self.update_task, "VertexUpdateTask")
        self.record(record)
示例#11
0
def make_patch_node(pts, col=LColorf(0.0, 1.0, 0.0, 1.0)):
    splinePatchData = GeomVertexData("SplinePatchData",
                                     GeomVertexFormat.getV3c4(),
                                     GeomEnums.UH_static)
    vertexWriter = GeomVertexWriter(splinePatchData, Thread.getCurrentThread())
    vertexWriter.setColumn("vertex")
    colorWriter = GeomVertexWriter(splinePatchData, Thread.getCurrentThread())
    colorWriter.setColumn("color")

    for (x, y, z) in pts:
        vertexWriter.addData3(x, y, z)
        colorWriter.addData4(col)

    geomLines = GeomLines(GeomEnums.UH_static)
    geomLines.addConsecutiveVertices(0, len(pts))
    geomLines.addVertex(0)
    geomLines.closePrimitive()

    geom = Geom(splinePatchData)
    geom.addPrimitive(geomLines)

    node = GeomNode("SplinePatchNode")
    node.addGeom(geom, RenderState.makeEmpty())
    return node
示例#12
0
    def _get_geom_data_grid_y(
        cls,
        build_plate_size: LVector2d,
        grid_spacing: float = _GRID_SPACING,
        name: str = "",
    ) -> GeomVertexData:
        """Generate GeomVertexData for build plate grid in Y axis.

        Parameters
        ----------
        build_plate_size : LVector2d
            Build plate size.
        grid_spacing : float
            Grid spacing; distance between successive grid lines.
        name : str
            Generated GeomVertexData name.
        """
        geom_data = GeomVertexData(name, cls._GEOM_VERTEX_FORMAT_GRID,
                                   Geom.UHStatic)
        geom_data.setNumRows(int(math.ceil(build_plate_size.y / grid_spacing)))

        writer_vertex = GeomVertexWriter(geom_data, "vertex")
        writer_color = GeomVertexWriter(geom_data, "color")

        current_y = grid_spacing
        while current_y < build_plate_size.y:
            writer_vertex.addData3d(LVecBase3d(0, current_y, 0))
            writer_vertex.addData3d(
                LVecBase3d(build_plate_size.x, current_y, 0))

            for _ in range(2):
                writer_color.addData4(cls._GRID_COLOR)

            current_y += grid_spacing

        return geom_data
示例#13
0
    def gen_geom(self, mesh_json):
        # Create vertex format
        geom_array = GeomVertexArrayFormat()
        geom_array.add_column("vertex", 3, Geom.NTFloat32, Geom.CPoint)
        has_normals = False
        has_texcoords = False
        has_weights = False
        if "normals" in mesh_json:
            geom_array.add_column("normal", 3, Geom.NTFloat32, Geom.CNormal)
            has_normals = True
        if "texcoords" in mesh_json:
            geom_array.add_column("texcoord", 3, Geom.NTFloat32,
                                  Geom.CTexcoord)
            has_texcoords = True
        if "weights" in mesh_json:
            geom_array.add_column("joint", 4, Geom.NTUint8, Geom.CIndex)
            geom_array.add_column("weight", 4, Geom.NTFloat32, Geom.COther)
            has_weights = True
        geom_format = GeomVertexFormat()
        geom_format.add_array(geom_array)
        geom_format = GeomVertexFormat.register_format(geom_format)

        # Set up vertex data
        vdata = GeomVertexData(
            str(random.randint(0, 255)) + "_vdata", geom_format, Geom.UHStatic)
        vcount = len(mesh_json["vertices"]) // 3
        vdata.setNumRows(vcount)
        vertex = GeomVertexWriter(vdata, "vertex")

        for i in range(vcount):
            vertex.addData3(mesh_json["vertices"][3 * i],
                            mesh_json["vertices"][3 * i + 1],
                            mesh_json["vertices"][3 * i + 2])
        if has_normals:
            normal = GeomVertexWriter(vdata, "normal")
            for i in range(vcount):
                normal.addData3(mesh_json["normals"][3 * i],
                                mesh_json["normals"][3 * i + 1],
                                mesh_json["normals"][3 * i + 2])
        if has_texcoords:
            texcoord = GeomVertexWriter(vdata, "texcoord")
            for i in range(vcount):
                texcoord.addData2(mesh_json["texcoords"][2 * i],
                                  mesh_json["texcoords"][2 * i + 1])
        if has_weights:
            joint = GeomVertexWriter(vdata, "joint")
            weight = GeomVertexWriter(vdata, "weight")
            for i in range(vcount):
                joint_count = len(mesh_json["joints"][i])
                joint.addData4(
                    0 if joint_count < 1 else mesh_json["joints"][i][0],
                    0 if joint_count < 2 else mesh_json["joints"][i][1],
                    0 if joint_count < 3 else mesh_json["joints"][i][2],
                    0 if joint_count < 4 else mesh_json["joints"][i][3])
                weight.addData4(
                    0 if joint_count < 1 else mesh_json["weights"][i][0],
                    0 if joint_count < 2 else mesh_json["weights"][i][1],
                    0 if joint_count < 3 else mesh_json["weights"][i][2],
                    0 if joint_count < 4 else mesh_json["weights"][i][3])

        # Create primitive
        prim = GeomTriangles(Geom.UHStatic)
        for i in range(vcount // 3):
            prim.addVertices(3 * i, 3 * i + 1, 3 * i + 2)
        geom = Geom(vdata)
        geom.add_primitive(prim)

        # Load texture
        tex = None
        if "texture" in mesh_json:
            tex = Loader(EComponent.base).loadTexture(
                (Path("resources") / mesh_json["texture"]).absolute())
            tex.setMagfilter(SamplerState.FT_nearest)
            tex.setMinfilter(SamplerState.FT_nearest)

        # Create new geometry node
        geom_node = GeomNode(str(random.randint(0, 255)) + "_node")
        if tex is None:
            geom_node.addGeom(geom)
        else:
            attrib = TextureAttrib.make(tex)
            state = RenderState.make(attrib)
            geom_node.addGeom(geom, state)
        if EComponent.panda_root_node is not None:
            self.geom_path = EComponent.panda_root_node.attach_new_node(
                geom_node)
            self.geom_path.set_shader_input("object_id", self.object_id)

        # Set shader
        if has_weights and self.geom_path is not None:
            self.geom_path.setTag("shader type", "skinned")
            bone_mats = PTA_LMatrix4f()
            for _ in range(100):
                bone_mats.push_back(helper.np_mat4_to_panda(np.identity(4)))
            self.geom_path.set_shader_input(f"boneMats", bone_mats)

            # Disable culling
            self.geom_path.node().setBounds(OmniBoundingVolume())
            self.geom_path.node().setFinal(True)
示例#14
0
class Asterism(VisibleObject):
    def __init__(self, name):
        VisibleObject.__init__(self, name)
        self.visible = True
        self.color = bodyClasses.get_orbit_color('constellation')
        self.position = LPoint3d(0, 0, 0)
        self.segments = []
        self.position = None

    def check_settings(self):
        self.set_shown(settings.show_asterisms)

    def set_segments_list(self, segments):
        self.segments = segments
        ra_sin = 0
        ra_cos = 0
        decl = 0
        if len(self.segments) > 0 and len(self.segments[0]) > 0:
            for star in self.segments[0]:
                asc = star.orbit.get_right_asc()
                ra_sin += sin(asc)
                ra_cos += cos(asc)
                decl += star.orbit.get_declination()
            ra = atan2(ra_sin, ra_cos)
            decl /= len(self.segments[0])
            self.position = InfinitePosition(right_asc=ra, right_asc_unit=units.Rad, declination=decl, declination_unit=units.Rad)

    def create_instance(self):
        self.vertexData = GeomVertexData('vertexData', GeomVertexFormat.getV3c4(), Geom.UHStatic)
        self.vertexWriter = GeomVertexWriter(self.vertexData, 'vertex')
        self.colorwriter = GeomVertexWriter(self.vertexData, 'color')
        #TODO: Ugly hack to calculate star position from the sun...
        old_cam_pos = self.context.observer.camera_global_pos
        self.context.observer.camera_global_pos = LPoint3d()
        center = LPoint3d()
        for segment in self.segments:
            if len(segment) < 2: continue
            for star in segment:
                #TODO: Temporary workaround to have star pos
                star.update(0, 0)
                star.update_obs(self.context.observer)
                position, distance, scale_factor = self.calc_scene_params(star.rel_position, star._position, star.distance_to_obs, star.vector_to_obs)
                self.vertexWriter.addData3f(*position)
                self.colorwriter.addData4(srgb_to_linear(self.color))
        self.context.observer.camera_global_pos = old_cam_pos
        self.lines = GeomLines(Geom.UHStatic)
        index = 0
        for segment in self.segments:
            if len(segment) < 2: continue
            for i in range(len(segment)-1):
                self.lines.addVertex(index)
                self.lines.addVertex(index+1)
                self.lines.closePrimitive()
                index += 1
            index += 1
        self.geom = Geom(self.vertexData)
        self.geom.addPrimitive(self.lines)
        self.node = GeomNode("asterism")
        self.node.addGeom(self.geom)
        self.instance = NodePath(self.node)
        self.instance.setRenderModeThickness(settings.asterism_thickness)
        self.instance.reparentTo(self.context.annotation)
        self.instance.setBin('background', settings.asterisms_depth)
        self.instance.set_depth_write(False)
示例#15
0
class Grid(VisibleObject):
    ignore_light = True
    default_shown = False
    def __init__(self, name, orientation, color):
        VisibleObject.__init__(self, name)
        self.visible = True
        self.nbOfPoints = 360
        self.nbOfRings = 17
        self.nbOfSectors = 24
        self.points_to_remove = (self.nbOfPoints // (self.nbOfRings + 1)) // 2
        self.orientation = orientation
        self.color = color
        self.settings_attr = 'show_' + name.lower() + '_grid'

    def check_settings(self):
        show = getattr(settings, self.settings_attr)
        if show is not None:
            self.set_shown(show)

    def create_instance(self):
        self.vertexData = GeomVertexData('vertexData', GeomVertexFormat.getV3c4(), Geom.UHStatic)
        self.vertexWriter = GeomVertexWriter(self.vertexData, 'vertex')
        self.colorwriter = GeomVertexWriter(self.vertexData, 'color')
        for r in range(1, self.nbOfRings + 1):
            for i in range(self.nbOfPoints):
                angle = 2 * pi / self.nbOfPoints * i
                x = cos(angle) * sin( pi * r / (self.nbOfRings + 1) )
                y = sin(angle) * sin( pi * r / (self.nbOfRings + 1) )
                z = sin( -pi / 2 + pi * r / (self.nbOfRings + 1) )

                self.vertexWriter.addData3f((self.context.observer.infinity * x, self.context.observer.infinity * y, self.context.observer.infinity * z))
                if r == self.nbOfRings / 2 + 1:
                    self.colorwriter.addData4(srgb_to_linear((self.color.x * 1.5, 0, 0, 1)))
                else:
                    self.colorwriter.addData4(srgb_to_linear(self.color))
        for s in range(self.nbOfSectors):
            for i in range(self.points_to_remove, self.nbOfPoints // 2 - self.points_to_remove + 1):
                angle = 2 * pi / self.nbOfPoints * i
                x = cos(2*pi * s / self.nbOfSectors) * sin(angle)
                y = sin(2*pi * s / self.nbOfSectors) * sin(angle)
                z = cos(angle)

                self.vertexWriter.addData3f((self.context.observer.infinity * x , self.context.observer.infinity * y, self.context.observer.infinity * z))
                if s == 0:
                    self.colorwriter.addData4(srgb_to_linear((self.color.x * 1.5, 0, 0, 1)))
                else:
                    self.colorwriter.addData4(srgb_to_linear(self.color))
        self.lines = GeomLines(Geom.UHStatic)
        index = 0
        for r in range(self.nbOfRings):
            for i in range(self.nbOfPoints-1):
                self.lines.addVertex(index)
                self.lines.addVertex(index+1)
                self.lines.closePrimitive()
                index += 1
            self.lines.addVertex(index)
            self.lines.addVertex(index - self.nbOfPoints + 1)
            self.lines.closePrimitive()
            index += 1
        for r in range(self.nbOfSectors):
            for i in range(self.nbOfPoints // 2 - self.points_to_remove * 2):
                self.lines.addVertex(index)
                self.lines.addVertex(index+1)
                self.lines.closePrimitive()
                index += 1
            index += 1
        self.geom = Geom(self.vertexData)
        self.geom.addPrimitive(self.lines)
        self.node = GeomNode("grid")
        self.node.addGeom(self.geom)
        self.instance = NodePath(self.node)
        self.instance.setRenderModeThickness(settings.grid_thickness)
        self.instance.reparentTo(self.context.annotation)
        self.instance.setQuat(LQuaternion(*self.orientation))

    def set_orientation(self, orientation):
        self.orientation = orientation
        if self.instance:
            self.instance.setQuat(LQuaternion(*self.orientation))