def pandageom_from_vfnf(vertices, face_normals, triangles, name='auto'): """ :param vertices: nx3 nparray, each row is vertex :param face_normals: nx3 nparray, each row is the normal of a face :param triangles: nx3 nparray, each row is three idx to the vertices :param name: :return: a geom model that is ready to be used to define a nodepath author: weiwei date: 20160613, 20210109 """ # expand vertices to let each triangle refer to a different vert+normal # vertices and normals vertformat = GeomVertexFormat.getV3n3() vertexdata = GeomVertexData(name, vertformat, Geom.UHStatic) vertids = triangles.flatten() multiplied_verticies = np.empty((len(vertids), 3), dtype=np.float32) multiplied_verticies[:] = vertices[vertids] vertex_normals = np.repeat(face_normals.astype(np.float32), repeats=3, axis=0) npstr = np.hstack((multiplied_verticies, vertex_normals)).tobytes() vertexdata.modifyArrayHandle(0).setData(npstr) # triangles primitive = GeomTriangles(Geom.UHStatic) primitive.setIndexType(GeomEnums.NTUint32) multiplied_triangles = np.arange(len(vertids), dtype=np.uint32).reshape(-1, 3) primitive.modifyVertices(-1).modifyHandle().setData( multiplied_triangles.tobytes()) # make geom geom = Geom(vertexdata) geom.addPrimitive(primitive) return geom
def pandageom_from_points(vertices, rgba_list=None, name=''): """ pack the vertices into a panda3d point cloud geom :param vertices: :param rgba_list: a list with a single 1x4 nparray or with len(vertices) 1x4 nparray :param name: :return: author: weiwei date: 20170328, 20210116 """ if rgba_list is None: # default vertex_rgbas = np.array([[0, 0, 0, 255]] * len(vertices), dtype=np.uint8) elif type(rgba_list) is not list: raise Exception('rgba\_list must be a list!') elif len(rgba_list) == 1: vertex_rgbas = np.tile((np.array(rgba_list[0]) * 255).astype(np.uint8), (len(vertices), 1)) elif len(rgba_list) == len(vertices): vertex_rgbas = (np.array(rgba_list) * 255).astype(np.uint8) else: raise ValueError( 'rgba_list must be a list of one or len(vertices) 1x4 nparray!') vertformat = GeomVertexFormat() arrayformat = GeomVertexArrayFormat() arrayformat.addColumn(InternalName.getVertex(), 3, GeomEnums.NTFloat32, GeomEnums.CPoint) vertformat.addArray(arrayformat) arrayformat = GeomVertexArrayFormat() arrayformat.addColumn(InternalName.getColor(), 4, GeomEnums.NTUint8, GeomEnums.CColor) vertformat.addArray(arrayformat) vertformat = GeomVertexFormat.registerFormat(vertformat) vertexdata = GeomVertexData(name, vertformat, Geom.UHStatic) vertexdata.modifyArrayHandle(0).copyDataFrom( np.ascontiguousarray(vertices, dtype=np.float32)) vertexdata.modifyArrayHandle(1).copyDataFrom(vertex_rgbas) primitive = GeomPoints(Geom.UHStatic) primitive.setIndexType(GeomEnums.NTUint32) primitive.modifyVertices(-1).modifyHandle().copyDataFrom( np.arange(len(vertices), dtype=np.uint32)) geom = Geom(vertexdata) geom.addPrimitive(primitive) return geom
def pandageom_from_points(vertices, rgba=None, name=''): """ pack the vertices into a panda3d point cloud geom :param vertices: :param rgba: rgba color for each vertex, can be list or nparray (rgb is also acceptable) :param name: :return: author: weiwei date: 20170328, 20210116, 20220721 """ if rgba is None: # default vertex_rgbas = np.asarray([[0, 0, 0, 255]] * len(vertices), dtype=np.uint8) if isinstance(rgba, list): rgba = np.array(rgba) if not isinstance(rgba, np.array): raise ValueError('rgba must be a list or an nparray!') if len(rgba) == 1: vertex_rgbas = np.tile((rgba * 255).astype(np.uint8), (len(vertices), 1)) elif len(rgba) == len(vertices): vertex_rgbas = (rgba * 255).astype(np.uint8) n_color_bit = rgba.shape[1] vertformat = GeomVertexFormat() arrayformat = GeomVertexArrayFormat() arrayformat.addColumn(InternalName.getVertex(), 3, GeomEnums.NTFloat32, GeomEnums.CPoint) vertformat.addArray(arrayformat) arrayformat = GeomVertexArrayFormat() arrayformat.addColumn(InternalName.getColor(), n_color_bit, GeomEnums.NTUint8, GeomEnums.CColor) vertformat.addArray(arrayformat) vertformat = GeomVertexFormat.registerFormat(vertformat) vertexdata = GeomVertexData(name, vertformat, Geom.UHStatic) vertexdata.modifyArrayHandle(0).copyDataFrom( np.ascontiguousarray(vertices, dtype=np.float32)) vertexdata.modifyArrayHandle(1).copyDataFrom(vertex_rgbas) primitive = GeomPoints(Geom.UHStatic) primitive.setIndexType(GeomEnums.NTUint32) primitive.modifyVertices(-1).modifyHandle().copyDataFrom( np.arange(len(vertices), dtype=np.uint32)) geom = Geom(vertexdata) geom.addPrimitive(primitive) return geom
def pandageom_from_vvnf(vertices, vertex_normals, triangles, name=''): """ use environment.collisionmodel instead, vvnf = vertices, vertex normals, faces pack the vertices, vertice normals and triangles into a panda3d geom :param vertices: nx3 nparray, each row is a vertex :param vertex_normals: nx3 nparray, each row is the normal of a vertex :param triangles: nx3 nparray, each row is three idx to the vertices :param name: :return: author: weiwei date: 20171219, 20210901 """ vertformat = GeomVertexFormat.getV3n3() vertexdata = GeomVertexData(name, vertformat, Geom.UHStatic) vertexdata.modifyArrayHandle(0).setData( np.hstack((vertices, vertex_normals)).astype(np.float32).tobytes()) primitive = GeomTriangles(Geom.UHStatic) primitive.setIndexType(GeomEnums.NTUint32) primitive.modifyVertices(-1).modifyHandle().setData( triangles.astype(np.uint32).tobytes()) # make geom geom = Geom(vertexdata) geom.addPrimitive(primitive) return geom
def create_geometry_from_mesh(mesh): # Define the individual array formats for vertex attributes. vertex_position_format = GeomVertexArrayFormat("vertex", 3, Geom.NT_float32, Geom.C_point) vertex_normal_format = GeomVertexArrayFormat("normal", 3, Geom.NT_float32, Geom.C_normal) vertex_color_format = GeomVertexArrayFormat("color", 4, Geom.NT_uint8, Geom.C_color) # Define the vertex data format with positions and colors. vertex_format = GeomVertexFormat() vertex_format.addArray(vertex_position_format) vertex_format.addArray(vertex_normal_format) vertex_format.addArray(vertex_color_format) vertex_format = GeomVertexFormat.registerFormat(vertex_format) # Populate the vertex position and color arrays. vertex_data = GeomVertexData("mesh_vertices", vertex_format, Geom.UH_static) vertex_data.modifyArrayHandle(0).copyDataFrom( np.array(mesh.positions, dtype=np.float32)) vertex_data.modifyArrayHandle(1).copyDataFrom( np.array(mesh.normals, dtype=np.float32)) vertex_data.modifyArrayHandle(2).copyDataFrom( np.array(mesh.colors, dtype=np.uint8)) # Populate the triangle indices. triangles = GeomTriangles(Geom.UH_static) triangles.setIndexType(Geom.NT_uint32) triangles.modifyVertices().modifyHandle().copyDataFrom( np.array(mesh.triangles, dtype=np.uint32)) geometry = Geom(vertex_data) geometry.add_primitive(triangles) return geometry