Skip to main content

A Python library for common tasks on 3D point clouds and meshes

Project description

Point Cloud Utils Logo

A Python library for common tasks on 3D point clouds and meshes


build workflow

Point Cloud Utils (pcu) is a utility library providing the following functionality for 3D processing point clouds and triangle meshes. See the Examples section for documentation on how to use these:

  • Utility functions for reading and writing many common mesh formats (PLY, STL, OFF, OBJ, 3DS, VRML 2.0, X3D, COLLADA). If it can be imported into MeshLab, we can read it!
  • A series of algorithms for generating point samples on meshes:
  • Utilities for downsampling point clouds:
    • To satisfy a blue noise distribution
    • On a voxel grid
  • Closest points between a point cloud and a mesh
  • Normal estimation from point clouds and triangle meshes
  • Fast k-nearest-neighbor search between point clouds (based on nanoflann).
  • Hausdorff distances between point-clouds.
  • Chamfer distances between point-clouds.
  • Approximate Wasserstein distances between point-clouds using the Sinkhorn method.
  • Compute signed distances between a point cloud and a mesh using Fast Winding Numbers
  • Compute closest points on a mesh to a point cloud
  • Deduplicating point clouds and mesh vertices
  • Mesh smoothing
  • Making a mesh watertight (based on the Watertight Manifold algorithm)

Installation

pip install point-cloud-utils

Examples

List of examples

Loading meshes and point clouds

Point-Cloud-Utils supports reading many common mesh formats (PLY, STL, OFF, OBJ, 3DS, VRML 2.0, X3D, COLLADA). If it can be imported into MeshLab, we can read it! The type of file is inferred from its file extension.

If you only need a few attributes of a point cloud or mesh, the quickest way to load a mesh is using one of the read_mesh_* utility functions

import point_cloud_utils as pcu

# Load vertices and faces for a mesh
v, f = pcu.load_mesh_vf("path/to/mesh")

# Load vertices and per-vertex normals
v, n = pcu.load_mesh_vn("path/to/mesh")

# Load vertices, per-vertex normals, and per-vertex-colors
v, n, c = pcu.load_mesh_vnc("path/to/mesh")

# Load vertices, faces, and per-vertex normals
v, f, n = pcu.load_mesh_vfn("path/to/mesh")

# Load vertices, faces, per-vertex normals, and per-vertex colors
v, f, n, c = pcu.load_mesh_vfnc("path/to/mesh")

For meshes and point clouds with more complex attributes, use load_triangle_mesh which returns a TriangleMesh object.

import point_cloud_utils as pcu

# mesh is a lightweight TriangleMesh container object holding mesh vertices, faces, and their attributes.
# Any attributes which aren't loaded (because they aren't present in the file) are set to None.
# The data in TriangleMesh is layed out as follows (run help(pcu.TriangleMesh) for more details):
# TriangleMesh:
#   vertex_data:
#       positions: [V, 3]-shaped numpy array of per-vertex positions
#       normals: [V, 3]-shaped numpy array of per-vertex normals (or None)
#       texcoords: [V, 2]-shaped numpy array of per-vertex uv coordinates (or None)
#       tex_ids: [V,]-shaped numpy array of integer indices into TriangleMesh.textures indicating which texture to
#                use at this vertex (or None)
#       colors: [V, 4]-shaped numpy array of per-vertex RBGA colors in [0.0, 1.0] (or None)
#       radius: [V,]-shaped numpy array of per-vertex curvature radii (or None)
#       quality: [V,]-shaped numpy array of per-vertex quality measures (or None)
#       flags: [V,]-shaped numpy array of 32-bit integer flags per vertex (or None)
#   face_data:
#       vertex_ids: [F, 3]-shaped numpy array of integer face indices into TrianglMesh.vertex_data.positions
#       normals: [F, 3]-shaped numpy array of per-face normals (or None)
#       colors: [F, 4]-shaped numpy array of per-face RBGA colors in [0.0, 1.0] (or None)
#       quality: [F,]-shaped numpy array of per-face quality measures (or None)
#       flags: [F,]-shaped numpy array of 32-bit integer flags per face (or None)
#
#       wedge_colors: [F, 3, 4]-shaped numpy array of per-wedge RBGA colors in [0.0, 1.0] (or None)
#       wedge_normals: [F, 3, 3]-shaped numpy array of per-wedge normals (or None)
#       wedge_texcoords: [F, 3, 2]-shaped numpy array of per-wedge] uv coordinates (or None)
#       wedge_tex_ids: [F, 3]-shaped numpy array of integer indices into TriangleMesh.textures indicating which
#                      texture to use at this wedge (or None)
#   textures: A list of paths to texture image files for this mesh
#   normal_maps: A list of paths to texture image files for this mesh
mesh = pcu.load_triangle_mesh("path/to/mesh")

# You can also load a mesh directly using the TriangleMesh class
mesh = pcu.TriangleMesh("path/to/mesh")

For meshes and point clouds with more complex attributes, use save_triangle_mesh which accepts a whole host of named arguments which control the attributes to save.

# save_triangle_mesh accepts a path to save to (The type of mesh  saved is determined by the file extesion),
# an array of mesh vertices of shape [V, 3], and optional arguments specifying faces, per-mesh attributes,
# per-face attributes and per-wedge attributes:
#   filename    : Path to the mesh to save. The type of file will be determined from the file extension.
#   v           : [V, 3]-shaped numpy array of per-vertex positions
#   f           : [F, 3]-shaped numpy array of integer face indices into TrianglMesh.vertex_data.positions (or None)
#   vn          : [V, 3]-shaped numpy array of per-vertex normals (or None)
#   vt          : [V, 2]-shaped numpy array of per-vertex uv coordinates (or None)
#   vc          : [V, 4]-shaped numpy array of per-vertex RBGA colors in [0.0, 1.0] (or None)
#   vq          : [V,]-shaped numpy array of per-vertex quality measures (or None)
#   vr          : [V,]-shaped numpy array of per-vertex curvature radii (or None)
#   vti         : [V,]-shaped numpy array of integer indices into TriangleMesh.textures indicating which texture to
#                 use at this vertex (or None)
#   vflags      : [V,]-shaped numpy array of 32-bit integer flags per vertex (or None)
#   fn          : [F, 3]-shaped numpy array of per-face normals (or None)
#   fc          : [F, 4]-shaped numpy array of per-face RBGA colors in [0.0, 1.0] (or None)
#   fq          : [F,]-shaped numpy array of per-face quality measures (or None)
#   fflags      : [F,]-shaped numpy array of 32-bit integer flags per face (or None)
#   wc          : [F, 3, 4]-shaped numpy array of per-wedge RBGA colors in [0.0, 1.0] (or None)
#   wn          : [F, 3, 3]-shaped numpy array of per-wedge normals (or None)
#   wt          : [F, 3, 2]-shaped numpy array of per-wedge] uv coordinates (or None)
#   wti         : [F, 3]-shaped numpy array of integer indices into TriangleMesh.textures indicating which
#   textures    : A list of paths to texture image files for this mesh
#   normal_maps : A list of paths to texture image files for this mesh
pcu.save_triangle_mesh("path/to/mesh", v=v, f=f, vn=vertex_normals, vc=vertex_colors, fn=face_normals)

# You can also directly save a pcu.TrianglMesh object
mesh.save("path/to/mesh")

Saving meshes and point clouds

Point-Cloud-Utils supports writing many common mesh formats (PLY, STL, OFF, OBJ, 3DS, VRML 2.0, X3D, COLLADA). If it can be imported into MeshLab, we can read it! The type of file is inferred from its file extension.

If you only need to write few attributes of a point cloud or mesh, the quickest way to use the save_mesh_* functions

import point_cloud_utils as pcu

# Assume v, f, n, c are numpy arrays
# where
#   v are the mesh vertices of shape [V, 3]
#   f are the mesh face indices into v of shape [F, 3]
#   n are the mesh per-vertex normals of shape [V, 3]
#   c are the mesh per-vertex colors of shape [V, 4]

# Save mesh vertices and faces
pcu.save_mesh_vf("path/to/mesh", v, f)

# Save mesh vertices and per-vertex normals
v, n = pcu.save_mesh_vn("path/to/mesh", v, n)

# Save mesh vertices, per-vertex normals, and per-vertex-colors
v, n, c = pcu.save_mesh_vnc("path/to/mesh", v, n, c)

# Save mesh vertices, faces, and per-vertex normals
v, f, n = pcu.save_mesh_vfn("path/to/mesh", v, f, n)

# Save vertices, faces, per-vertex normals, and per-vertex colors
v, f, n, c = pcu.save_mesh_vfnc("path/to/mesh", v, f, n, c)

Generating blue-noise samples on a mesh with Poisson-disk sampling

Generate 10000 samples on a mesh with poisson disk samples

import point_cloud_utils as pcu
import numpy as np

# v is a nv by 3 NumPy array of vertices
# f is an nf by 3 NumPy array of face indexes into v
# n is a nv by 3 NumPy array of vertex normals
v, f, n = pcu.load_mesh_vfn("my_model.ply")

# Generate 10000 samples on a mesh with poisson disk samples
# f_i are the face indices of each sample and bc are barycentric coordinates of the sample within a face
f_i, bc = pcu.sample_mesh_poisson_disk(v, f, n, 10000)

# Use the face indices and barycentric coordinate to compute sample positions and normals
v_poisson = pcu.interpolate_barycentric_coords(f, fi, bc, v)
n_poisson = pcu.interpolate_barycentric_coords(f, fi, bc, n)

Generate blue noise samples on a mesh separated by approximately 0.01 times the bounding box diagonal

import point_cloud_utils as pcu
import numpy as np
# v is a nv by 3 NumPy array of vertices
# f is an nf by 3 NumPy array of face indexes into v
# n is a nv by 3 NumPy array of vertex normals
v, f, n = pcu.load_mesh_vfn("my_model.ply")


# Generate samples on a mesh with poisson disk samples seperated by approximately 0.01 times
# the length of the bounding box diagonal
bbox = np.max(v, axis=0) - np.min(v, axis=0)
bbox_diag = np.linalg.norm(bbox)

# f_i are the face indices of each sample and bc are barycentric coordinates of the sample within a face
f_i, bc = pcu.sample_mesh_poisson_disk(v, f, n, 10000)

# Use the face indices and barycentric coordinate to compute sample positions and normals
v_sampled = pcu.interpolate_barycentric_coords(f, fi, bc, v)
n_sampled = pcu.interpolate_barycentric_coords(f, fi, bc, n)

Generate random samples on a mesh

import point_cloud_utils as pcu
import numpy as np

# v is a nv by 3 NumPy array of vertices
# f is an nf by 3 NumPy array of face indexes into v
# n is a nv by 3 NumPy array of vertex normals
v, f, n = pcu.load_mesh_vfn("my_model.ply")

# Generate random samples on the mesh (v, f, n)
# f_idx are the face indices of each sample and bc are barycentric coordinates of the sample within a face
f_idx, bc = pcu.sample_mesh_random(v, f, num_samples=v.shape[0] * 40)

# Use the face indices and barycentric coordinate to compute sample positions and normals
v_sampled = pcu.interpolate_barycentric_coords(f, fi, bc, v)
n_sampled = pcu.interpolate_barycentric_coords(f, fi, bc, n)

Downsample a point cloud to have a blue noise distribution

import point_cloud_utils as pcu
import numpy as np

# v is a nv by 3 NumPy array of vertices
# n is a nv by 3 NumPy array of vertex normals
v, n = pcu.load_mesh_vn("my_model.ply")

# Downsample a point cloud by approximately 50% so that the sampled points approximately
# follow a blue noise distribution
# idx is an array of integer indices into v indicating which samples to keep
idx = pcu.downsample_point_cloud_poisson_disk(v, num_samples=int(0.5*v.shape[0]))

# Use the indices to get the sample positions and normals
v_sampled = v[idx]
n_sampled = n[idx]

Downsample a point cloud on a voxel grid

Simple downsampling within the bounding box of a point cloud

import point_cloud_utils as pcu
import numpy as np

# v is a nv by 3 NumPy array of vertices
# n is a nv by 3 NumPy array of vertex normals
# n is a nv by 4 NumPy array of vertex colors
v, n, c = pcu.load_mesh_vnc("my_model.ply")

# We'll use a voxel grid with 128 voxels per axis
num_voxels_per_axis = 128

# Size of the axis aligned bounding box of the point cloud
bbox_size = v.max(0) - v.min(0)

# The size per-axis of a single voxel
sizeof_voxel = bbox_size / num_voxels_per_axis

# Downsample a point cloud on a voxel grid so there is at most one point per voxel.
# Multiple points, normals, and colors within a voxel cell are averaged together.
v_sampled, n_sampled, c_sampled = pcu.downsample_point_cloud_voxel_grid(sizeof_voxel, v, n, c)

Specifying the location of the voxel grid in space (e.g. to only consider points wihtin a sub-region of the point cloud)

import point_cloud_utils as pcu
import numpy as np

# v is a nv by 3 NumPy array of vertices
# n is a nv by 3 NumPy array of vertex normals
# n is a nv by 4 NumPy array of vertex colors
v, n, c = pcu.load_mesh_vnc("my_model.ply")

# We'll use a voxel grid with 128 voxels per axis
num_voxels_per_axis = 128

# Size of the axis aligned bounding box of the point cloud
bbox_size = v.max(0) - v.min(0)

# Let's say we only want to consider points in the top right corner of the bounding box
domain_min = v.min(0) + bbox_size / 2.0
domain_max = v.min(0) + bbox_size

# The size per-axis of a single voxel
sizeof_voxel = bbox_size / num_voxels_per_axis

# Downsample a point cloud on a voxel grid so there is at most one point per voxel.
# Multiple points, normals, and colors within a voxel cell are averaged together.
# min_bound and max_bound specify a bounding box in which we will downsample points
v_sampled, n_sampled, c_sampled = pcu.downsample_point_cloud_voxel_grid(sizeof_voxel, v, n, c,
                                                                        min_bound=domain_min, max_bound=domain_max)

Discarding voxels with too few points

import point_cloud_utils as pcu
import numpy as np

# v is a nv by 3 NumPy array of vertices
# n is a nv by 3 NumPy array of vertex normals
# n is a nv by 4 NumPy array of vertex colors
v, n, c = pcu.load_mesh_vnc("my_model.ply")

# We'll use a voxel grid with 128 voxels per axis
num_voxels_per_axis = 128

# Size of the axis aligned bounding box of the point cloud
bbox_size = v.max(0) - v.min(0)

# The size per-axis of a single voxel
sizeof_voxel = bbox_size / num_voxels_per_axis

# We will throw away points within voxel cells containing fewer than 3 points
min_points_per_voxel = 3

# Downsample a point cloud on a voxel grid so there is at most one point per voxel.
# Multiple points, normals, and colors within a voxel cell are averaged together.
v_sampled, n_sampled, c_sampled = pcu.downsample_point_cloud_voxel_grid(sizeof_voxel, v, n, c,
                                                                        min_points_per_voxel=min_points_per_voxel)

Compute closest points on a mesh

import point_cloud_utils as pcu

# v is a nv by 3 NumPy array of vertices
v, f = pcu.load_mesh_vf("my_model.ply")

# Generate 1000 random query points. We will find the closest point on the mesh for each of these
p = np.random.rand(1000, 3)

# For each query point, find the closest point on the mesh.
# Here:
#  - d is an array of closest distances for each query point with shape (1000,)
#  - fi is an array of closest face indices for each point with shape (1000,)
#  - bc is an array of barycentric coordinates within each face (shape (1000, 3)
#    of the closest point for each query point
d, fi, bc = pcu.closest_points_on_mesh(p, v, f)

# Convert barycentric coordinates to 3D positions
closest_points = pcu.interpolate_barycentric_coords(f, fi, bc, v)

Estimating normals from a point cloud

import point_cloud_utils as pcu

# v is a nv by 3 NumPy array of vertices
v = pcu.load_mesh_v("my_model.ply")

# Estimate a normal at each point (row of v) using its 16 nearest neighbors
n = pcu.estimate_point_cloud_normals_knn(v, 16)

# Estimate a normal at each point (row of v) using its neighbors within a 0.1-radius ball
n = pcu.estimate_point_cloud_normals_ball(v, 0.1)

Approximate Wasserstein (Sinkhorn) distance between two point clouds

import point_cloud_utils as pcu
import numpy as np

# a and b are arrays where each row contains a point
# Note that the point sets can have different sizes (e.g [100, 3], [111, 3])
a = np.random.rand(100, 3)
b = np.random.rand(100, 3)

# M is a 100x100 array where each entry  (i, j) is the squared distance between point a[i, :] and b[j, :]
M = pcu.pairwise_distances(a, b)

# w_a and w_b are masses assigned to each point. In this case each point is weighted equally.
w_a = np.ones(a.shape[0])
w_b = np.ones(b.shape[0])

# P is the transport matrix between a and b, eps is a regularization parameter, smaller epsilons lead to
# better approximation of the true Wasserstein distance at the expense of slower convergence
P = pcu.sinkhorn(w_a, w_b, M, eps=1e-3)

# To get the distance as a number just compute the frobenius inner product <M, P>
sinkhorn_dist = (M*P).sum()

Chamfer distance between two point clouds

import point_cloud_utils as pcu
import numpy as np

# a and b are arrays where each row contains a point
# Note that the point sets can have different sizes (e.g [100, 3], [111, 3])
a = np.random.rand(100, 3)
b = np.random.rand(100, 3)

chamfer_dist = pcu.chamfer_distance(a, b)

Hausdorff distance between two point clouds

import point_cloud_utils as pcu
import numpy as np

# Generate two random point sets
a = np.random.rand(1000, 3)
b = np.random.rand(500, 3)

# Compute one-sided squared Hausdorff distances
hausdorff_a_to_b = pcu.one_sided_hausdorff_distance(a, b)
hausdorff_b_to_a = pcu.one_sided_hausdorff_distance(b, a)

# Take a max of the one sided squared  distances to get the two sided Hausdorff distance
hausdorff_dist = pcu.hausdorff_distance(a, b)

# Find the index pairs of the two points with maximum shortest distancce
hausdorff_b_to_a, idx_b, idx_a = pcu.one_sided_hausdorff_distance(b, a, return_index=True)
assert np.abs(np.sum((a[idx_a] - b[idx_b])**2) - hausdorff_b_to_a) < 1e-5, "These values should be almost equal"

# Find the index pairs of the two points with maximum shortest distancce
hausdorff_dist, idx_b, idx_a = pcu.hausdorff_distance(b, a, return_index=True)
assert np.abs(np.sum((a[idx_a] - b[idx_b])**2) - hausdorff_dist) < 1e-5, "These values should be almost equal"

K-nearest-neighbors between two point clouds

import point_cloud_utils as pcu
import numpy as np

# Generate two random point sets
a = np.random.rand(1000, 3)
b = np.random.rand(500, 3)

# dists_a_to_b is of shape (a.shape[0],) and contains the shortest squared distance
# between each point in a and the points in b
# corrs_a_to_b is of shape (a.shape[0],) and contains the index into b of the
# closest point for each point in a
dists_a_to_b, corrs_a_to_b = pcu.shortest_distance_pairs(a, b)

Generating point samples in the square and cube with Lloyd relaxation

import point_cloud_utils as pcu

# v is a nv by 3 NumPy array of vertices
# f is an nf by 3 NumPy array of face indexes into v
v, f = pcu.load_mesh_vf("my_model.ply")

# Generate 1000 points on the mesh with Lloyd's algorithm
samples = pcu.sample_mesh_lloyd(v, f, 1000)

# Generate 100 points on the unit square with Lloyd's algorithm
samples_2d = pcu.lloyd_2d(100)

# Generate 100 points on the unit cube with Lloyd's algorithm
samples_3d = pcu.lloyd_3d(100)

Compute shortest signed distances to a triangle mesh with fast winding numbers

import point_cloud_utils as pcu

# v is a nv by 3 NumPy array of vertices
# f is an nf by 3 NumPy array of face indexes into v
v, f = pcu.load_mesh_vf("my_model.ply")

# Generate 1000 points in the volume around the mesh. We'll compute the signed distance to the
# mesh at each of these points
pts = np.random.rand(1000, 3) * (v.max(0) - v.min(0)) + v.min(0)

# Compute the sdf, the index of the closest face in the mesh, and the barycentric coordinates of
# closest point on the mesh, for each point in pts
sdfs, face_ids, barycentric_coords = pcu.signed_distance_to_mesh(pts, v, f)

Deduplicating Point Clouds and Meshes

Point Clouds:

import point_cloud_utils as pcu

# p is a (n, 3)-shaped array of points (one per row)
# p is a (n, 3)-shaped array of normals at each point
p, n = pcu.load_mesh_vn("my_pcloud.ply")

# Treat any points closer than 1e-7 apart as the same point
# idx_i is an array of indices such that p_dedup = p[idx_i]
# idx_j is an array of indices such that p = p_dedup[idx_j]
p_dedup, idx_i, idx_j  = deduplicate_point_cloud(p, 1e-7)

# Use idx_i to deduplicate the normals
n_dedup = n[idx_i]

Meshes:

# v is a (nv, 3)-shaped NumPy array of vertices
# f is an (nf, 3)-shaped NumPy array of face indexes into v
# c is a (nv, 4)-shaped numpy array of per-vertex colors
v, f, c = pcu.load_mesh_vfc("my_model.ply")

# Treat any points closer than 1e-7 apart as the same point
# idx_i is an array of indices such that v_dedup = v[idx_i]
# idx_j is an array of indices such that v = v_dedup[idx_j]
v_dedup, f_dedup, idx_i, idx_j = pcu.deduplicate_mesh_vertices(v, f, 1e-7)

# Use idx_i to deduplicate the colors
c_dedup = c[idx_i]

Smoothing a Mesh

import point_cloud_utils as pcu

# v is a nv by 3 NumPy array of vertices
# f is an nf by 3 NumPy array of face indexes into v
v, f = pcu.load_mesh_vf("my_model.ply")

num_iters = 3  # Number of smoothing iterations
use_cotan_weights = True  # Whether to use cotangent weighted laplacian

# vsmooth contains the vertices of the smoothed mesh (the new mesh has the same face indices f)
vsmooth = pcu.laplacian_smooth_mesh(v, f, num_iters, use_cotan_weights=use_cotan_weights)

Making a Mesh Watertight

import point_cloud_utils as pcu

# v is a nv by 3 NumPy array of vertices
# f is an nf by 3 NumPy array of face indexes into v
v, f = pcu.load_mesh_vf("my_model.ply")

# Optional resolution parameter (default is 20_000).
# See https://github.com/hjwdzh/Manifold for details
resolution = 20_000  
v_watertight, f_watertight = pcu.make_mesh_watertight(v, f, resolution=resolution)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

point-cloud-utils-0.23.0.tar.gz (31.0 kB view details)

Uploaded Source

Built Distributions

point_cloud_utils-0.23.0-cp310-cp310-win_amd64.whl (4.3 MB view details)

Uploaded CPython 3.10 Windows x86-64

point_cloud_utils-0.23.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (7.0 MB view details)

Uploaded CPython 3.10 manylinux: glibc 2.17+ x86-64

point_cloud_utils-0.23.0-cp310-cp310-macosx_10_9_x86_64.whl (5.9 MB view details)

Uploaded CPython 3.10 macOS 10.9+ x86-64

point_cloud_utils-0.23.0-cp39-cp39-win_amd64.whl (4.3 MB view details)

Uploaded CPython 3.9 Windows x86-64

point_cloud_utils-0.23.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (7.0 MB view details)

Uploaded CPython 3.9 manylinux: glibc 2.17+ x86-64

point_cloud_utils-0.23.0-cp39-cp39-macosx_10_9_x86_64.whl (5.9 MB view details)

Uploaded CPython 3.9 macOS 10.9+ x86-64

point_cloud_utils-0.23.0-cp38-cp38-win_amd64.whl (4.3 MB view details)

Uploaded CPython 3.8 Windows x86-64

point_cloud_utils-0.23.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (7.0 MB view details)

Uploaded CPython 3.8 manylinux: glibc 2.17+ x86-64

point_cloud_utils-0.23.0-cp38-cp38-macosx_10_9_x86_64.whl (5.9 MB view details)

Uploaded CPython 3.8 macOS 10.9+ x86-64

point_cloud_utils-0.23.0-cp37-cp37m-win_amd64.whl (4.3 MB view details)

Uploaded CPython 3.7m Windows x86-64

point_cloud_utils-0.23.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (7.0 MB view details)

Uploaded CPython 3.7m manylinux: glibc 2.17+ x86-64

point_cloud_utils-0.23.0-cp37-cp37m-macosx_10_9_x86_64.whl (5.9 MB view details)

Uploaded CPython 3.7m macOS 10.9+ x86-64

point_cloud_utils-0.23.0-cp36-cp36m-win_amd64.whl (4.3 MB view details)

Uploaded CPython 3.6m Windows x86-64

point_cloud_utils-0.23.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (7.0 MB view details)

Uploaded CPython 3.6m manylinux: glibc 2.17+ x86-64

point_cloud_utils-0.23.0-cp36-cp36m-macosx_10_9_x86_64.whl (5.9 MB view details)

Uploaded CPython 3.6m macOS 10.9+ x86-64

File details

Details for the file point-cloud-utils-0.23.0.tar.gz.

File metadata

  • Download URL: point-cloud-utils-0.23.0.tar.gz
  • Upload date:
  • Size: 31.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.0 CPython/3.9.12

File hashes

Hashes for point-cloud-utils-0.23.0.tar.gz
Algorithm Hash digest
SHA256 5ddce4ebdb7adb1f54d743357fb5960bf80b1b1d5c129e7793781988927bc59b
MD5 7da0f295ab006ffac5b597dc3513194e
BLAKE2b-256 b7711dad7f9812e3d41bf7a141aab4f3989ea15d374e531b1e0fceba7563caaa

See more details on using hashes here.

File details

Details for the file point_cloud_utils-0.23.0-cp310-cp310-win_amd64.whl.

File metadata

File hashes

Hashes for point_cloud_utils-0.23.0-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 c8cad81230426abd663ebf8f89a0638ef8acb40e11e2587ec64691e356173d8e
MD5 934a1ae64782668cf4a0e92eae18b6c0
BLAKE2b-256 e2902fd7785a8a5306b4a31f4e79e6645f1a04baefae7466b89bca7754234904

See more details on using hashes here.

File details

Details for the file point_cloud_utils-0.23.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for point_cloud_utils-0.23.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 51416742dedddd30c18987be413c29b064d9bd717af27f30f7d540365945db81
MD5 936db2198a7b0555fd8bd3bf20637d5c
BLAKE2b-256 d8a9375d9e20e73e7e81e7e56cfa40f2c55a49b9a59c2e95f77571458e118f8c

See more details on using hashes here.

File details

Details for the file point_cloud_utils-0.23.0-cp310-cp310-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for point_cloud_utils-0.23.0-cp310-cp310-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 06b9c19eba520d2c2ac76f52048e526bc4afc5d27b954439effecb09bdae1a06
MD5 bc21c6a465d1ce17b957c10411318f17
BLAKE2b-256 25b4bbb84295f03736fb2121122a1f2786af4398aed7d51a494887c93a5d0dde

See more details on using hashes here.

File details

Details for the file point_cloud_utils-0.23.0-cp39-cp39-win_amd64.whl.

File metadata

File hashes

Hashes for point_cloud_utils-0.23.0-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 86d6ba83e7be74f043f0b7ce48fcd35eea80677f46adf10743d7ed13980143eb
MD5 e5382ce7db317c8679c37212f2a54b86
BLAKE2b-256 38d87b2144e50b42fea21e805d72f8983892742a13ccc4196e972e6482c77bb7

See more details on using hashes here.

File details

Details for the file point_cloud_utils-0.23.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for point_cloud_utils-0.23.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 270248751a9cbeaf3b776421f5643bc8cd6cde4f56967a53881bda95fc05a501
MD5 35a14d11b1c925c1dc9f23187b551d67
BLAKE2b-256 6eea9963edbcbfe1369813d2813ff4fa5f8894e3a0b6602194e4653577469dd3

See more details on using hashes here.

File details

Details for the file point_cloud_utils-0.23.0-cp39-cp39-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for point_cloud_utils-0.23.0-cp39-cp39-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 1655da3edffd44566b0860c26b96954976c3614182a9ca0c3df2c7c5a2140c47
MD5 bc3b3eaf50e5650bb762caa9b13169e6
BLAKE2b-256 d0e0c0e45d07f893f1f13c5e88aba1998c437ac9135073a6a0cb2f9dfc36a383

See more details on using hashes here.

File details

Details for the file point_cloud_utils-0.23.0-cp38-cp38-win_amd64.whl.

File metadata

File hashes

Hashes for point_cloud_utils-0.23.0-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 31fc1b3592f39c7569898db72528d523d6d2475f2c99a2e3769d65b7a73b505b
MD5 8faf9c0830dd8b6ed7ac6c8658d4c07e
BLAKE2b-256 aa4e1488510258c90b2fd1e1f3016a2c052c4e91e1ccb498c80ffb7004a2b44f

See more details on using hashes here.

File details

Details for the file point_cloud_utils-0.23.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for point_cloud_utils-0.23.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 07906820270bc6c723d03f7f26cb3e02dd5b251d5c91f5cc0467afd825c9cb51
MD5 673ac2eb8e313fe1e2c34cf2aa1af841
BLAKE2b-256 95411d98386dda6a36fabc0d1106bec19cd06e0f397931a9a60595f2d6c5c3f1

See more details on using hashes here.

File details

Details for the file point_cloud_utils-0.23.0-cp38-cp38-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for point_cloud_utils-0.23.0-cp38-cp38-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 15d759505f82d64bbdca421b4015df52f82beadbb6c76ef97b574199436da006
MD5 b9d8697f003abd3546d285cc44abc4e7
BLAKE2b-256 6e9dd84f9e5b982b292f80facf8ec86466339f063f78091857c87925e93e47c1

See more details on using hashes here.

File details

Details for the file point_cloud_utils-0.23.0-cp37-cp37m-win_amd64.whl.

File metadata

File hashes

Hashes for point_cloud_utils-0.23.0-cp37-cp37m-win_amd64.whl
Algorithm Hash digest
SHA256 9003c67d19041fe532a3d97eef19aef69d69c56c6195da9339807e77c817f805
MD5 254606de9388be7098b59067e954a13b
BLAKE2b-256 dbb289b2a9c22bb28f1998f807b971900ce4265c6dba9c402070148d72709506

See more details on using hashes here.

File details

Details for the file point_cloud_utils-0.23.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for point_cloud_utils-0.23.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 a7182e10c5c89899f6d115ca55b9fed6f520f9ca43558e59a2629a31bdb76ef0
MD5 00153d82b4e6320a0974f8998cbdf2d4
BLAKE2b-256 9b4288c86bc5d6940b331b24736ec0167d1af6cfae1638a1bcabfa558c9ce49f

See more details on using hashes here.

File details

Details for the file point_cloud_utils-0.23.0-cp37-cp37m-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for point_cloud_utils-0.23.0-cp37-cp37m-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 55a9d571ce026f908ac264ec0eac53baff819a21aed522cb61343d2a1e0715e3
MD5 473f33537da9b38610263032e96b4118
BLAKE2b-256 da6a959a2b65f172013c82dc664ab313110691d83a2b7a99a70ac8ff327de901

See more details on using hashes here.

File details

Details for the file point_cloud_utils-0.23.0-cp36-cp36m-win_amd64.whl.

File metadata

File hashes

Hashes for point_cloud_utils-0.23.0-cp36-cp36m-win_amd64.whl
Algorithm Hash digest
SHA256 c2b425992a56108f78f0577a4fb4d2aa2b322b6e4ee50e1f78a082ed6190e9b5
MD5 c0ce766168aa9eb5eea15924944137ac
BLAKE2b-256 ceb250dfab9554ffbb17e80b32d45f75663ec5cdb01cf9891632e148a6ea3c93

See more details on using hashes here.

File details

Details for the file point_cloud_utils-0.23.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for point_cloud_utils-0.23.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 21e0c5abf63c30c6d7752609236763e119a8f2b3fb64b38c9839698c4eb93754
MD5 400a7ef2a188224e3513a7846534fd01
BLAKE2b-256 ce34d9c54e44ceb2f73a5f69f611bc998ed43b7e326eed07c64d927b8c1fb99a

See more details on using hashes here.

File details

Details for the file point_cloud_utils-0.23.0-cp36-cp36m-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for point_cloud_utils-0.23.0-cp36-cp36m-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 e98777b06136cf557bd495a932e9ecc6d0ecb2d21c8dd08304347938a716a7c6
MD5 bf1d9d86afde8f8e23acd1eef7c23e45
BLAKE2b-256 701f0153a55b6899217cf693a33937f235db5b139b4b5e1b8888eeae9d952112

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page