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
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
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()
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
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)
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)
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)
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
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
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)
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
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
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)
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)
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))