### Install potpourri3d from source with Suitesparse Source: https://github.com/nmwsharp/potpourri3d/blob/master/README.md Installs the potpourri3d Python library from source, enabling the use of Suitesparse linear solvers. This requires cmake and a C++ compiler, and is recommended for improved performance and robustness. The `--no-binary` flag ensures that it attempts to compile locally. ```bash python -m pip install potpourri3d --no-binary potpourri3d ``` -------------------------------- ### Install potpourri3d via pip Source: https://github.com/nmwsharp/potpourri3d/blob/master/README.md Installs the potpourri3d Python library using pip. This command typically installs precompiled binaries for common system configurations. ```bash pip install potpourri3d ``` -------------------------------- ### Get Tangent Frames on Mesh using Vector Heat (Python) Source: https://github.com/nmwsharp/potpourri3d/blob/master/README.md Retrieves tangent frames (basisX, basisY, basisN) at each vertex of a mesh, which are essential for defining and manipulating tangent data within the vector heat solver. The mesh must be pre-initialized. ```Python import potpourri3d as pp3d V, F = # a Nx3 numpy array of points and Mx3 array of triangle face indices solver = pp3d.MeshVectorHeatSolver(V,F) # Get the tangent frames which are used by the solver to define tangent data # at each vertex basisX, basisY, basisN = solver.get_tangent_frames() ``` -------------------------------- ### Polygon Mesh Heat Solver for Distance and Transport (Python) Source: https://github.com/nmwsharp/potpourri3d/blob/master/README.md Utilizes the heat method to compute unsigned geodesic distance, signed distance, and vector quantities on polygon meshes. The PolygonMeshHeatSolver allows for efficient computation after an initial setup, supporting various mesh types including mixed-degree ones. It can extend scalar values, get tangent frames, transport vectors, and compute signed distances to curves. ```python import potpourri3d as pp3d import numpy as np V, polygons = # your polygon mesh solver = pp3d.PolygonMeshHeatSolver(V, F) # Compute unsigned geodesic distance to vertices 12 and 17 dist = solver.compute_distance([12, 17]) # Extend the value `0.` from vertex 12 and `1.` from vertex 17. ext = solver.extend_scalar([12, 17], [0.,1.]) # Get the tangent frames which are used by the solver to define tangent data # at each vertex basisX, basisY, basisN = solver.get_tangent_frames() # Parallel transport a vector along the surface # (and map it to a vector in 3D) sourceV = 22 ext = solver.transport_tangent_vector(sourceV, [6., 6.]) ext3D = ext[:,0,np.newaxis] * basisX + ext[:,1,np.newaxis] * basisY # Compute signed distance to the oriented curve(s) denoted by a vertex sequence. curves = [ [9, 10, 12, 13, 51, 48], [79, 93, 12, 30, 78, 18, 92], [90, 84, 19, 91, 82, 81, 83] ] signed_dist = solver.compute_signed_distance(curves) ``` -------------------------------- ### Trace Geodesic Path on Mesh Surface (Python) Source: https://github.com/nmwsharp/potpourri3d/blob/master/README.md Traces a geodesic path along a mesh surface starting from a given vertex and direction. It uses the GeodesicTracer class, which can precompute data for repeated traces, making it efficient. The output is a polyline represented by an Nx3 array of points. ```python import potpourri3d as pp3d import numpy as np V, F = # your mesh tracer = pp3d.GeodesicTracer(V,F) # shares precomputation for repeated traces trace_pts = tracer.trace_geodesic_from_vertex(22, np.array((0.3, 0.5, 0.4))) # trace_pts is a Vx3 numpy array of points forming the path ``` -------------------------------- ### PointCloudHeatSolver - Initialization and Core Methods Source: https://github.com/nmwsharp/potpourri3d/blob/master/README.md Demonstrates the initialization of the PointCloudHeatSolver and common methods for computing distances, interpolations, and tangent frames. ```APIDOC ## PointCloudHeatSolver ### Description Initializes a solver instance for performing heat diffusion based computations on a point cloud. ### Method `__init__` ### Endpoint N/A (Class Constructor) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **P** (numpy.ndarray) - Required - A Nx3 real numpy array of points. - **t_coef** (float) - Optional - Sets the time used for short-time heat flow. Defaults to 1.0. Larger values increase stability but smooth the solution. ### Request Example ```python import potpourri3d as pp3d import numpy as np P = np.random.rand(100, 3) # Example point cloud solver = pp3d.PointCloudHeatSolver(P, t_coef=1.0) ``` ### Response #### Success Response (200) N/A (Constructor does not return a response in the traditional sense; it creates an object) #### Response Example None ``` ```APIDOC ## PointCloudHeatSolver.compute_distance ### Description Computes the geodesic distance from a source point to all other points in the cloud. ### Method `compute_distance` ### Endpoint N/A (Class Method) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **p_ind** (int) - Required - The index of the source point. ### Request Example ```python dists = solver.compute_distance(4) ``` ### Response #### Success Response (200) - **dists** (numpy.ndarray) - A numpy array containing the geodesic distance from the source point to each point in the cloud. #### Response Example ```json { "distances": [0.0, 0.1, 0.5, ...] } ``` ``` ```APIDOC ## PointCloudHeatSolver.extend_scalar ### Description Interpolates scalar values defined at specific points to the entire point cloud based on nearest geodesic neighbors. ### Method `extend_scalar` ### Endpoint N/A (Class Method) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **p_inds** (list of int) - Required - A list of indices of the source points where values are defined. - **values** (list of float) - Required - A list of scalar values, one for each source point. ### Request Example ```python values = solver.extend_scalar([12, 17], [0., 1.]) ``` ### Response #### Success Response (200) - **values** (numpy.ndarray) - A numpy array containing the interpolated scalar values for each point in the cloud. #### Response Example ```json { "interpolated_values": [0.0, 0.2, 0.8, ...] } ``` ``` ```APIDOC ## PointCloudHeatSolver.get_tangent_frames ### Description Retrieves the tangent frames (basis vectors X, Y, and normal N) at each point in the cloud, used for defining tangent data. ### Method `get_tangent_frames` ### Endpoint N/A (Class Method) ### Parameters None ### Request Example ```python basisX, basisY, basisN = solver.get_tangent_frames() ``` ### Response #### Success Response (200) - **basisX** (numpy.ndarray) - An Nx3 array of basis X vectors. - **basisY** (numpy.ndarray) - An Nx3 array of basis Y vectors. - **basisN** (numpy.ndarray) - An Nx3 array of normal vectors. #### Response Example ```json { "basisX": [[1.0, 0.0, 0.0], ...], "basisY": [[0.0, 1.0, 0.0], ...], "basisN": [[0.0, 0.0, 1.0], ...] } ``` ``` -------------------------------- ### PointCloudHeatSolver Initialization and Usage in Python Source: https://github.com/nmwsharp/potpourri3d/blob/master/README.md Demonstrates initializing the PointCloudHeatSolver with a point cloud, computing geodesic distances, extending scalar values, retrieving tangent frames, transporting tangent vectors, computing logarithmic maps, and calculating signed distances to curves. Requires the potpourri3d library and numpy. ```python import potpourri3d as pp3d import numpy as np # Assume P is a Nx3 numpy array of points P = np.random.rand(100, 3) # Initialize the solver solver = pp3d.PointCloudHeatSolver(P) # Compute the geodesic distance to point 4 dists = solver.compute_distance(4) # Extend scalar values (e.g., 0. at point 12, 1. at point 17) ext = solver.extend_scalar([12, 17], [0.,1.]) # Get tangent frames (basisX, basisY, basisN) basisX, basisY, basisN = solver.get_tangent_frames() # Transport a tangent vector (e.g., [6., 6.] at source point 22) sourceP = 22 ext_vec = solver.transport_tangent_vector(sourceP, [6., 6.]) ext3D = ext_vec[:,0,np.newaxis] * basisX + ext_vec[:,1,np.newaxis] * basisY # Compute the logarithmic map centered at source point 22 logmap = solver.compute_log_map(sourceP) # Compute signed distance to specified curves curves = [ [9, 10, 12, 13, 51, 48], [79, 93, 12, 30, 78, 18, 92], [90, 84, 19, 91, 82, 81, 83] ] signed_dist = solver.compute_signed_distance(curves, basisN) ``` -------------------------------- ### Input / Output Source: https://github.com/nmwsharp/potpourri3d/blob/master/README.md Provides functions for reading and writing various 3D mesh and point cloud file formats. ```APIDOC ## GET read_mesh ### Description Reads a mesh from a file. ### Method GET ### Endpoint /read_mesh ### Parameters #### Query Parameters - **filename** (string) - Required - The path to the file to read. ### Response #### Success Response (200) - **V** (numpy.ndarray) - Nx3 array of vertices. - **F** (numpy.ndarray) - Mx3 or Mx4 array of face indices. ## GET read_polygon_mesh ### Description Reads a polygon mesh from a file. ### Method GET ### Endpoint /read_polygon_mesh ### Parameters #### Query Parameters - **filename** (string) - Required - The path to the file to read. ### Response #### Success Response (200) - **V** (numpy.ndarray) - Nx3 array of vertices. - **polygons** (list) - List of faces, where each face is a list of vertex indices. ## POST write_mesh ### Description Writes a mesh to a file, optionally with UV coordinates. ### Method POST ### Endpoint /write_mesh ### Parameters #### Request Body - **V** (numpy.ndarray) - Required - Nx3 array of vertices. - **F** (numpy.ndarray) - Required - Mx3 or Mx4 array of face indices. - **filename** (string) - Required - The path to write the file to. - **UV_coords** (numpy.ndarray) - Optional - Ux2 array of UV coordinates. - **UV_type** (string) - Optional - Type of UV coordinates ('per-vertex', 'per-face', or 'per-corner'). ### Response #### Success Response (200) - (No specific response body documented, typically indicates success) ## GET read_point_cloud ### Description Reads a point cloud from a file, ignoring face information. ### Method GET ### Endpoint /read_point_cloud ### Parameters #### Query Parameters - **filename** (string) - Required - The path to the file to read. ### Response #### Success Response (200) - **V** (numpy.ndarray) - Nx3 array of vertices. ## POST write_point_cloud ### Description Writes a point cloud to a file. ### Method POST ### Endpoint /write_point_cloud ### Parameters #### Request Body - **V** (numpy.ndarray) - Required - Nx3 array of vertices. - **filename** (string) - Required - The path to write the file to. ### Response #### Success Response (200) - (No specific response body documented, typically indicates success) ``` -------------------------------- ### CMake: Configure Potpourri3D Python Bindings Source: https://github.com/nmwsharp/potpourri3d/blob/master/CMakeLists.txt This CMake script sets up the build environment for Potpourri3D's Python bindings. It includes setting the minimum CMake version, defining the project, recursively adding pybind11 and geometry-central dependencies, configuring Eigen location, and creating a Python module target linked against geometry-central. ```cmake cmake_minimum_required(VERSION 3.5.0) project(potpourri3d_bindings) # Recurse in to pybind set(PYBIND11_NEWPYTHON ON) add_subdirectory(deps/pybind11) # set location of eigen for geometry-central set(GC_EIGEN_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/deps/eigen" CACHE PATH "my path") # geometry-central set(CMAKE_POSITION_INDEPENDENT_CODE ON) add_subdirectory(deps/geometry-central) pybind11_add_module(potpourri3d_bindings src/cpp/core.cpp src/cpp/io.cpp src/cpp/heat_helpers.cpp src/cpp/mesh.cpp src/cpp/point_cloud.cpp ) include_directories(potpourri3d_bindings ${CMAKE_CURRENT_SOURCE_DIR}/src/cpp) target_link_libraries(potpourri3d_bindings PRIVATE geometry-central) install(TARGETS potpourri3d_bindings LIBRARY DESTINATION .) ``` -------------------------------- ### Initialize EdgeFlipGeodesicSolver in Python Source: https://github.com/nmwsharp/potpourri3d/blob/master/README.md Initializes the `EdgeFlipGeodesicSolver` class, which is designed for computing geodesic paths and loops on triangle meshes. The constructor requires the mesh's vertex (V) and face (F) data. This solver is efficient for repeated geodesic computations on the same mesh as it precomputes necessary structures. ```python import potpourri3d as pp3d V = # Nx3 real numpy array of vertices F = # Mx3 integer numpy array of faces (0-based indices, manifold, oriented triangle mesh) path_solver = pp3d.EdgeFlipGeodesicSolver(V, F) ``` -------------------------------- ### Initialize MeshVectorHeatSolver in Python Source: https://github.com/nmwsharp/potpourri3d/blob/master/README.md Initializes the `MeshVectorHeatSolver` class, which is used for various surface analysis tasks including computing logarithmic maps and extending scalar values. It requires vertex and face data of the mesh. Optional parameters control the time coefficient for heat flow and the use of intrinsic Delaunay triangulation for robustness. ```python import potpourri3d as pp3d V = # Nx3 numpy array of vertices F = # Mx3 numpy array of faces # Basic initialization solver = pp3d.MeshVectorHeatSolver(V, F) # Initialization with custom parameters t_coef_value = 1.0 use_intrinsic = True solver_custom = pp3d.MeshVectorHeatSolver(V, F, t_coef=t_coef_value, useIntrinsicDelaunay=use_intrinsic) ``` -------------------------------- ### Compute Signed Distance with Heat Method (Python) Source: https://github.com/nmwsharp/potpourri3d/blob/master/README.md Computes signed distances on a mesh using the signed heat method, which is robust to holes and noise. This section demonstrates how to initialize the solver and specify curves using barycentric coordinates for calculations. ```python import potpourri3d as pp3d # Assume V and F are defined numpy arrays for vertices and faces # V, F = # your mesh solver = pp3d.MeshSignedHeatSolver(V, F) # Specify a curve as a sequence of barycentric points curves = [ [ (61, [0.3, 0.3]), # face (7, []), # vertex (16, [0.3, 0.3, 0.4]), # face (11, [0.4]), # edge (71, []), # vertex (20, [0.3, 0.3, 0.4]), # face (13, []), # vertex (58, []) # vertex ] ] # To perform a calculation, you would typically call a method on the solver, # for example: signed_distance = solver.compute_signed_distance(curves) # The exact method signature depends on the library's implementation. ``` -------------------------------- ### Mesh Basic Utilities Source: https://github.com/nmwsharp/potpourri3d/blob/master/README.md Provides fundamental mesh operations such as calculating face and vertex areas, computing the cotangent Laplacian matrix, extracting mesh edges, and performing contouring with the marching triangles algorithm. ```APIDOC ## Mesh Basic Utilities ### Description Provides fundamental mesh operations such as calculating face and vertex areas, computing the cotangent Laplacian matrix, extracting mesh edges, and performing contouring with the marching triangles algorithm. ### Functions - `face_areas(V, F)`: Computes a real numpy array of face areas for a triangular mesh. - `vertex_areas(V, F)`: Computes a real numpy array of vertex areas for a triangular mesh. - `cotan_laplacian(V, F, denom_eps=0.)`: Computes the cotan-Laplace matrix as a sparse csr scipy matrix. - `edges(V, F)`: Returns the Ex2 integer-valued matrix representing the edges of the mesh. ### Marching Triangles - `MarchingTrianglesSolver(V, F)`: Constructs a solver instance for contouring scalar functions on triangle meshes using the marching triangles algorithm. - `marching_triangles(u, isoval=0.)`: Performs the marching triangles algorithm on a scalar function `u` with a given isovalue. - `marching_triangles(V, F, u, isoval=0.)`: A one-off function to perform the marching triangles algorithm. ### Barycentric Points Barycentric points are used for input and output. They are specified as 2-tuples of the form `(element_index, barycentric_coordinates)`: - Vertices: `(vertex_index, )` - Edges: `(edge_index, [t])` where `t` is in `[0,1]`. - Faces: `(face_index, [tA, tB])` where `tA`, `tB` are barycentric coordinates. `tC` is inferred if not provided. ``` -------------------------------- ### PointCloudHeatSolver - Vector and Logarithmic Map Operations Source: https://github.com/nmwsharp/potpourri3d/blob/master/README.md Details methods for parallel transporting tangent vectors and computing the logarithmic map on the point cloud. ```APIDOC ## PointCloudHeatSolver.transport_tangent_vector ### Description Parallel transports a single 2D tangent vector from a source point across the surface. ### Method `transport_tangent_vector` ### Endpoint N/A (Class Method) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **p_ind** (int) - Required - The index of the source point. - **vector** (numpy.ndarray) - Required - A 2D tangent vector to transport. ### Request Example ```python sourceP = 22 tangent_vector = np.array([6., 6.]) ext = solver.transport_tangent_vector(sourceP, tangent_vector) ``` ### Response #### Success Response (200) - **ext** (numpy.ndarray) - A numpy array representing the transported 2D tangent vector. #### Response Example ```json { "transported_vector": [5.8, 6.2] } ``` ``` ```APIDOC ## PointCloudHeatSolver.transport_tangent_vectors ### Description Parallel transports multiple 2D tangent vectors across the surface, mapping each to its nearest geodesic neighbor's source point. ### Method `transport_tangent_vectors` ### Endpoint N/A (Class Method) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **p_inds** (list of int) - Required - A list of indices of the source points. - **vectors** (list of numpy.ndarray) - Required - A list of 2D tangent vectors, one for each source point. ### Request Example ```python source_points = [22, 30] tangent_vectors = [np.array([6., 6.]), np.array([-2., 3.])] ext = solver.transport_tangent_vectors(source_points, tangent_vectors) ``` ### Response #### Success Response (200) - **ext** (numpy.ndarray) - A numpy array of transported 2D tangent vectors. #### Response Example ```json { "transported_vectors": [[5.8, 6.2], [-2.1, 3.5]] } ``` ``` ```APIDOC ## PointCloudHeatSolver.compute_log_map ### Description Computes the logarithmic map centered at a specified source point on the point cloud. ### Method `compute_log_map` ### Endpoint N/A (Class Method) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **p_ind** (int) - Required - The index of the source point. ### Request Example ```python logmap = solver.compute_log_map(22) ``` ### Response #### Success Response (200) - **logmap** (numpy.ndarray) - A numpy array containing the logarithmic map values for each point relative to the source point. #### Response Example ```json { "logarithmic_map": [0.0, 0.1, 0.5, ...] } ``` ``` -------------------------------- ### EdgeFlipGeodesicSolver Class Source: https://github.com/nmwsharp/potpourri3d/blob/master/README.md Computes geodesic paths on surfaces using an iterative edge-flipping strategy. ```APIDOC ## EdgeFlipGeodesicSolver ### Description Computes geodesic paths on surfaces using an iterative edge-flipping strategy. This approach is useful for finding the path itself, potentially a non-shortest geodesic. ### Methods #### `__init__(V, F)` Constructs an instance of the `EdgeFlipGeodesicSolver` class. - **V** (numpy.ndarray) - Nx3 real numpy array of vertices. - **F** (numpy.ndarray) - Mx3 integer numpy array of faces, with 0-based vertex indices (must form a manifold, oriented triangle mesh). #### `find_geodesic_path(v_start, v_end, max_iterations=None, max_relative_length_decrease=None)` Computes a geodesic path from a start vertex to an end vertex. - **v_start** (int) - Index of the starting vertex. - **v_end** (int) - Index of the ending vertex. - **max_iterations** (int, optional) - Maximum number of shortening iterations. Defaults to no limit. - **max_relative_length_decrease** (float, optional) - Limits the maximum relative decrease in path length. E.g., 0.5 means the resulting path is at least 0.5 times the initial length. Defaults to no limit. Returns: - numpy.ndarray: An Nx3 numpy array of positions defining the path as a polyline along the surface. #### `find_geodesic_path_poly(v_list, max_iterations=None, max_relative_length_decrease=None)` Computes a geodesic path through a sequence of vertices. - **v_list** (list) - A list of vertex indices representing the path sequence `[v_start, v_a, v_b, ..., v_end]`. - **max_iterations** (int, optional) - Maximum number of shortening iterations. Defaults to no limit. - **max_relative_length_decrease** (float, optional) - Limits the maximum relative decrease in path length. Defaults to no limit. Returns: - numpy.ndarray: An Nx3 numpy array of positions defining the path as a polyline along the surface. #### `find_geodesic_loop(v_list, max_iterations=None, max_relative_length_decrease=None)` Computes a closed geodesic loop connecting the first vertex in `v_list` back to itself. - **v_list** (list) - A list of vertex indices defining the initial loop sequence. - **max_iterations** (int, optional) - Maximum number of shortening iterations. Defaults to no limit. - **max_relative_length_decrease** (float, optional) - Limits the maximum relative decrease in path length. Defaults to no limit. Returns: - numpy.ndarray: An Nx3 numpy array of positions defining the loop as a polyline along the surface. ### Example Usage ```python import potpourri3d as pp3d import numpy as np # Assume V and F are defined numpy arrays for vertices and faces # V = np.random.rand(100, 3) # F = np.random.randint(0, 100, size=(150, 3)) path_solver = pp3d.EdgeFlipGeodesicSolver(V, F) path_pts = path_solver.find_geodesic_path(v_start=14, v_end=22) # path_pts is a Vx3 numpy array of points forming the path ``` ``` -------------------------------- ### Mesh Geodesic Tracing Source: https://github.com/nmwsharp/potpourri3d/blob/master/README.md Routines to trace geodesic paths along the surface of a mesh given an initial point and direction or length. The path is returned as a polyline. ```APIDOC ## GeodesicTracer Class ### Description Constructs an instance of the tracer class for geodesic path tracing on a mesh. ### Method `GeodesicTracer(V, F)` ### Parameters #### Path Parameters - **V** (Nx3 numpy array) - Vertex array of the mesh. - **F** (Mx3 numpy array) - Face array of the mesh (0-based vertex indices). ### Request Example ```python import potpourri3d as pp3d import numpy as np V, F = # your mesh tracer = pp3d.GeodesicTracer(V, F) ``` ## trace_geodesic_from_vertex ### Description Traces a geodesic path starting from a specified vertex in a given direction. ### Method `trace_geodesic_from_vertex(start_vert, direction_xyz, max_iterations=None)` ### Parameters #### Path Parameters - **start_vert** (int) - The index of the starting vertex. - **direction_xyz** (length-3 numpy array) - A vector specifying the initial direction and distance to trace. - **max_iterations** (int, optional) - Maximum number of faces/edges to trace through. Defaults to no limit. ### Response #### Success Response (200) - **trace_pts** (Nx3 numpy array) - An array of points forming the geodesic path as a polyline. ### Response Example ```python trace_pts = tracer.trace_geodesic_from_vertex(22, np.array((0.3, 0.5, 0.4))) ``` ## trace_geodesic_from_face ### Description Traces a geodesic path starting from a point within a specified face in a given direction. ### Method `trace_geodesic_from_face(start_face, bary_coords, direction_xyz, max_iterations=None)` ### Parameters #### Path Parameters - **start_face** (int) - The index of the starting face. - **bary_coords** (length-3 numpy array) - Barycentric coordinates specifying the starting point within the face. - **direction_xyz** (length-3 numpy array) - A vector specifying the initial direction and distance to trace. - **max_iterations** (int, optional) - Maximum number of faces/edges to trace through. Defaults to no limit. ### Response #### Success Response (200) - **trace_pts** (Nx3 numpy array) - An array of points forming the geodesic path as a polyline. ### Response Example ```python # Assuming tracer is already initialized # trace_pts = tracer.trace_geodesic_from_face(start_face, bary_coords, direction_xyz) ``` ``` -------------------------------- ### MeshVectorHeatSolver Class Source: https://github.com/nmwsharp/potpourri3d/blob/master/README.md Provides functionalities for solving the vector heat method on meshes, including computing logarithmic maps and interpolating tangent data. ```APIDOC ## MeshVectorHeatSolver ### Description Solves the vector heat method on meshes. Used for computing logarithmic maps, interpolating tangent data, and more. ### Methods #### `__init__(V, F, t_coef=1.0, useIntrinsicDelaunay=True)` Constructs an instance of the `MeshVectorHeatSolver` class. - **V** (numpy.ndarray) - Nx3 real numpy array of vertices. - **F** (numpy.ndarray) - Mx3 integer numpy array of faces, with 0-based vertex indices (triangle meshes only, should be manifold). - **t_coef** (float) - Time coefficient for short-time heat flow. Defaults to 1.0. Larger values increase stability but also smoothing. - **useIntrinsicDelaunay** (bool) - If true, uses intrinsic triangulation internally for improved robustness. Defaults to True. #### `extend_scalar(v_inds, values)` Nearest-geodesic-neighbor interpolates scalar values defined at vertices. - **v_inds** (list) - List of source vertex indices. - **values** (list) - List of scalar values, one for each source vertex. #### `get_tangent_frames()` Retrieves the coordinate frames (basis-X, basis-Y, normal) used for tangent data at each vertex. Returns: - tuple: A tuple containing three Nx3 numpy arrays: basis-X, basis-Y, and normal axes. #### `get_connection_laplacian()` Retrieves the connection Laplacian used internally as a sparse matrix. Returns: - scipy.sparse.csr_matrix: The VxV connection Laplacian matrix. #### `transport_tangent_vector(v_ind, vector)` Parallel transports a single 2D tangent vector across the surface from a source vertex. - **v_ind** (int) - Index of the source vertex. - **vector** (numpy.ndarray) - A 2D tangent vector to transport. #### `transport_tangent_vectors(v_inds, vectors)` Parallel transports a collection of 2D tangent vectors across the surface. - **v_inds** (list) - List of source vertex indices. - **vectors** (list) - List of 2D tangent vectors, one for each source vertex. #### `compute_log_map(v_ind, strategy='AffineLocal')` Computes the logarithmic map centered at the given source vertex. - **v_ind** (int) - Index of the source vertex. - **strategy** (str) - The strategy to use for computation. Options: `'VectorHeat'`, `'AffineLocal'`, `'AffineAdaptive'`. Defaults to `'AffineLocal'`. ### Example Usage ```python import potpourri3d as pp3d import numpy as np # Assume V and F are defined numpy arrays for vertices and faces # V = np.random.rand(100, 3) # F = np.random.randint(0, 100, size=(150, 3)) solver = pp3d.MeshVectorHeatSolver(V, F) logmap = solver.compute_log_map(v_ind=0) ``` ``` -------------------------------- ### Find Geodesic Path using EdgeFlipGeodesicSolver in Python Source: https://github.com/nmwsharp/potpourri3d/blob/master/README.md Computes a geodesic path between two specified vertices on a 3D mesh using the `EdgeFlipGeodesicSolver`. This solver utilizes edge flips to iteratively shorten a path until it becomes geodesic. It requires the mesh's vertex and face data for initialization. The output is a NumPy array of points defining the geodesic polyline. ```python import potpourri3d as pp3d V, F = # your mesh path_solver = pp3d.EdgeFlipGeodesicSolver(V, F) # shares precomputation for repeated solves v_start_index = 14 v_end_index = 22 path_pts = path_solver.find_geodesic_path(v_start=v_start_index, v_end=v_end_index) # path_pts is a Vx3 numpy array of points forming the path ``` -------------------------------- ### Compute Geodesic Distance with Heat Method (Python) Source: https://github.com/nmwsharp/potpourri3d/blob/master/README.md Computes geodesic distances on a mesh using the heat method. It offers both stateful solvers for repeated computations and one-off functions for single calculations. The accuracy may be affected by mesh coarseness. ```python import potpourri3d as pp3d # Assume V and F are defined numpy arrays for vertices and faces # V = np.array([...]) # F = np.array([...]) # Stateful solves (faster for multiple computations) solver = pp3d.MeshHeatMethodDistanceSolver(V, F) dist_single = solver.compute_distance(7) # Distance from vertex 7 dist_multi = solver.compute_distance_multisource([1, 2, 3]) # Distance from vertices 1, 2, or 3 # One-off versions dist_single_oneoff = pp3d.compute_distance(V, F, 7) dist_multi_oneoff = pp3d.compute_distance_multisource(V, F, [1, 3, 4]) ``` -------------------------------- ### Mesh Signed Distance Solver Source: https://github.com/nmwsharp/potpourri3d/blob/master/README.md Calculates signed distances on meshes using the signed heat method, providing robustness against holes and noise. This solver is also stateful for efficiency when performing multiple computations. ```APIDOC ## Mesh Signed Distance Solver ### Description Calculates signed distances on meshes using the signed heat method, providing robustness against holes and noise. This solver is also stateful for efficiency when performing multiple computations. ### Constructor - `MeshSignedHeatSolver(V, F)` - `V` (numpy.ndarray): Nx3 array of vertices. - `F` (numpy.ndarray): Mx3 array of faces with 0-based vertex indices. ### Methods - `compute_signed_distance(curves)`: Computes the signed distance from a set of curves. - `curves` (list of lists): A list where each inner list contains barycentric points defining a curve. Each barycentric point is a tuple `(element_index, [barycentric_coordinates])`. - Returns: numpy.ndarray of signed distances. ### Notes Requires a mesh represented by vertices `V` and faces `F`. The input `curves` define the zero level set for the signed distance computation. ``` -------------------------------- ### Mesh Heat Method Distance Solver Source: https://github.com/nmwsharp/potpourri3d/blob/master/README.md Calculates geodesic distances on surfaces using the heat method. This solver is optimized for scenarios where multiple distance computations are needed from the same mesh. ```APIDOC ## Mesh Heat Method Distance Solver ### Description Calculates geodesic distances on surfaces using the heat method. This solver is optimized for scenarios where multiple distance computations are needed from the same mesh. ### Constructor - `MeshHeatMethodDistanceSolver(V, F, t_coef=1., use_robust=True)` - `V` (numpy.ndarray): Nx3 array of vertices. - `F` (numpy.ndarray): Mx3 array of faces with 0-based vertex indices. - `t_coef` (float): Time coefficient for short-time heat flow. Defaults to 1.0. - `use_robust` (bool): Whether to use intrinsic triangulations for robustness. Defaults to True. ### Methods - `compute_distance(v_ind)`: Computes the geodesic distance from a single source vertex. - `v_ind` (int): The zero-based index of the source vertex. - Returns: numpy.ndarray of distances. - `compute_distance_multisource(v_ind_list)`: Computes the geodesic distance from the nearest of a collection of source vertices. - `v_ind_list` (list of int): A list of zero-based indices of the source vertices. - Returns: numpy.ndarray of distances. ### One-off Functions - `compute_distance(V, F, v_ind)`: Computes geodesic distance from a single source vertex (one-off). - `V` (numpy.ndarray): Nx3 array of vertices. - `F` (numpy.ndarray): Mx3 array of faces. - `v_ind` (int): Zero-based index of the source vertex. - Returns: numpy.ndarray of distances. - `compute_distance_multisource(V, F, v_ind_list)`: Computes geodesic distance from multiple source vertices (one-off). - `V` (numpy.ndarray): Nx3 array of vertices. - `F` (numpy.ndarray): Mx3 array of faces. - `v_ind_list` (list of int): List of zero-based indices of the source vertices. - Returns: numpy.ndarray of distances. ### Notes For coarse meshes, results may be inaccurate. Consider using a finer mesh or internal refinement for improved accuracy. ``` -------------------------------- ### Compute Local Triangulation of Point Cloud - Python Source: https://github.com/nmwsharp/potpourri3d/blob/master/README.md Constructs a local triangulation for a given point cloud. The `get_local_triangulation` method returns a numpy array representing triangles around each vertex. It uses a degeneracy heuristic by default. The output is an integer numpy array of shape `[V, M, 3]` where `V` is the number of vertices and `M` is the maximum number of neighbors for any local triangulation. ```python import numpy as np # Assuming 'P' is a numpy array of point cloud vertices # P = np.random.rand(100, 3) # Example point cloud # Initialize local triangulation local_triangulation_computer = PointCloudLocalTriangulation(P, with_degeneracy_heuristic=True) # Get the local triangulation # Returns a [V, M, 3] integer numpy array # Each [i,:,:] holds the local triangles about vertex i # M is the max number of neighbors in any local triangulation # For vertices with fewer neighbors, the trailing rows hold -1 local_triangles = local_triangulation_computer.get_local_triangulation() print(f"Shape of local triangulation: {local_triangles.shape}") ``` -------------------------------- ### Marching Triangles Contour Extraction (Python) Source: https://github.com/nmwsharp/potpourri3d/blob/master/README.md Implements the marching triangles algorithm for contouring scalar functions defined on triangle meshes. It provides both a stateful solver and a one-off function. The output consists of lists of barycentric points representing curve components. ```python import potpourri3d as pp3d # Assume V and F are defined numpy arrays for vertices and faces # V = np.array([...]) # F = np.array([...]) # u = np.array([...]) # Scalar function values on vertices # Stateful solver triangles_solver = pp3d.MarchingTrianglesSolver(V, F) contours_stateful = triangles_solver.marching_triangles(u, isoval=0.) # One-off function contours_oneoff = pp3d.marching_triangles(V, F, u, isoval=0.) ``` -------------------------------- ### Read Mesh File Source: https://github.com/nmwsharp/potpourri3d/blob/master/README.md Reads a mesh from a specified file. It returns vertex and face data as NumPy arrays. The file format is inferred from the filename extension and supports formats compatible with geometry-central. ```python V, F = read_mesh(filename) ``` -------------------------------- ### Write Point Cloud File Source: https://github.com/nmwsharp/potpourri3d/blob/master/README.md Writes point cloud data (vertices) to a specified file. This function writes a mesh file with no face entries. The file format is inferred from the filename extension. ```python write_point_cloud(V, filename) ``` -------------------------------- ### Read Point Cloud File Source: https://github.com/nmwsharp/potpourri3d/blob/master/README.md Reads point cloud data from a specified file. It returns vertex data as a NumPy array. This function effectively reads a mesh file and ignores face information. The file format is inferred from the filename extension. ```python V = read_point_cloud(filename) ``` -------------------------------- ### Compute Logarithmic Map using MeshVectorHeatSolver in Python Source: https://github.com/nmwsharp/potpourri3d/blob/master/README.md Computes the logarithmic map centered at a specified source vertex on a 3D mesh. This method is part of the vector heat method for surface analysis. It requires a mesh represented by vertices (V) and faces (F). The `MeshVectorHeatSolver` class is used for this computation. ```python import potpourri3d as pp3d V, F = # your mesh solver = pp3d.MeshVectorHeatSolver(V, F) logmap = solver.compute_log_map(source_vertex_index) # logmap contains the computed logarithmic map data ``` -------------------------------- ### Write Mesh File Source: https://github.com/nmwsharp/potpourri3d/blob/master/README.md Writes mesh data (vertices, faces, and optionally UV coordinates) to a specified file. The file format is inferred from the filename extension and supports formats compatible with geometry-central. Note that UV indices are not preserved. ```python write_mesh(V, F, filename, UV_coords=None, UV_type=None) ``` -------------------------------- ### Transport Tangent Vector on Mesh using Vector Heat (Python) Source: https://github.com/nmwsharp/potpourri3d/blob/master/README.md Performs parallel transport of a tangent vector along the surface of a mesh and maps it to a 3D vector. This operation is part of the vector heat method and requires the mesh and tangent frames to be initialized. ```Python import potpourri3d as pp3d import numpy as np V, F = # a Nx3 numpy array of points and Mx3 array of triangle face indices solver = pp3d.MeshVectorHeatSolver(V,F) # Parallel transport a vector along the surface # (and map it to a vector in 3D) sourceV = 22 ext = solver.transport_tangent_vector(sourceV, [6., 6.]) ext3D = ext[:,0,np.newaxis] * basisX + ext[:,1,np.newaxis] * basisY ``` -------------------------------- ### Read Polygon Mesh File Source: https://github.com/nmwsharp/potpourri3d/blob/master/README.md Reads a polygon mesh from a specified file. It returns vertex data as a NumPy array and face data as a nested list of integers. The file format is inferred from the filename extension. ```python V, polygons = read_polygon_mesh(filename) ``` -------------------------------- ### Extend Scalar Field on Mesh using Vector Heat (Python) Source: https://github.com/nmwsharp/potpourri3d/blob/master/README.md Extends scalar values across a mesh surface using the vector heat method. This is useful for interpolation and defining boundary conditions. It requires a pre-existing mesh. ```Python import potpourri3d as pp3d import numpy as np # = Stateful solves V, F = # a Nx3 numpy array of points and Mx3 array of triangle face indices solver = pp3d.MeshVectorHeatSolver(V,F) # Extend the value `0.` from vertex 12 and `1.` from vertex 17. Any vertex # geodesically closer to 12. will take the value 0., and vice versa # (plus some slight smoothing) ext = solver.extend_scalar([12, 17], [0.,1.]) ```