Cloud vertices, What is it ?

Notecloud_vertices automatically falls back to its model-only version when wxPython is unavailable. You can also import the model explicitly: from wolfhece.PyVertex._model import cloud_vertices. See the Model/GUI architecture tutorial for details.

Basics

Cloud vertices is a synonym for point cloud. It is a group of points in a 3D space.

It can be initialized from:

  • a list of vertices

  • a numpy array (shape (N, 3))

  • an Excel file

  • a CSV file (with/without header)

  • a Shape file (point type)

  • a DXF file (MTEXT or INSERT)

Each point can have associated values.

Storage

cloud_vertices supports two internal storage backends represented by StorageMode:

  • StorageMode.DICT (legacy): rows are stored as myvertices[id] = {'vertex': wolfvertex, ...}

  • StorageMode.NUMPY: coordinates are stored in compact NumPy arrays for large clouds

By default, init_from_nparray(array) uses an automatic switch:

  • if len(array) < 100_000: keep dict backend

  • if len(array) >= 100_000: switch to numpy backend

You can switch explicitly with:

  • cloud.switch_storage_mode(StorageMode.NUMPY)

  • cloud.switch_storage_mode(StorageMode.DICT)

Strings ('numpy', 'dict') are still accepted for backward compatibility.

The current mode is available via cloud.storage_mode (an enum value).

Important compatibility note: reading cloud.myvertices always gives a dict view; if the cloud is in NumPy mode, it is materialized back to dict.

Properties

The cloud has a cloudproperties attribute that contains some properties (mainly for visualization in OpenGL).

KD-tree

A KD-tree is a data structure that allows for efficient nearest neighbor searches in a multi-dimensional space. It is particularly useful for spatial queries, such as finding the closest points in a point cloud.

Each instance of cloud_vertices has a KD-tree associated with it. The KD-tree is built using the vertices of the point cloud, and it allows for fast nearest neighbor searches.

[ ]:

from wolfhece import __version__ assert __version__ > '2.2.9', f'Bad version of wolfhece: {__version__} <= 2.2.9' from wolfhece.PyVertex import cloud_vertices, wolfvertex from wolfhece.PyVertex._model import StorageMode import numpy as np

Create a new cloud_vertices instance

[2]:
vertices = np.array([[0, 0, 0], [1, 1, 1], [2, 2, 2], [3, 3, 3], [4, 4, 4]])

cloud = cloud_vertices()

cloud.init_from_nparray(vertices)

Storage modes and automatic switch

The next example uses a very small threshold (10 points) only for demonstration. In production, the default threshold is 100_000 points.

[ ]:
# Demo only: lower the threshold to trigger the auto-switch quickly
cloud_auto = cloud_vertices()
cloud_auto.AUTO_NUMPY_SWITCH_THRESHOLD = 10

small = np.arange(27, dtype=np.float64).reshape(9, 3)
big = np.arange(30, dtype=np.float64).reshape(10, 3)

cloud_auto.init_from_nparray(small)
print('mode for 9 points:', cloud_auto.storage_mode)

cloud_auto.init_from_nparray(big)
print('mode for 10 points:', cloud_auto.storage_mode)

# Explicit switch with enum
cloud_auto.switch_storage_mode(StorageMode.DICT)
print('mode after explicit switch:', cloud_auto.storage_mode)

# Backward-compatible strings still work
cloud_auto.switch_storage_mode('numpy')
print('mode after string switch:', cloud_auto.storage_mode)
[3]:
# number of vertices
print(cloud.nbvertices)

# Header information
print(cloud.has_values)
print(cloud.header)
5
False
[]

Plot by matplotlib

[4]:
cloud.plot_matplotlib()
[4]:
(<Figure size 640x480 with 1 Axes>, <Axes: >)
../_images/tutorials_cloudpoints_8_1.png

Get coordinates of the vertices

[4]:
xyz = cloud.xyz # -> np.ndarray with shape (n,3)

print(xyz)
[[0. 0. 0.]
 [1. 1. 1.]
 [2. 2. 2.]
 [3. 3. 3.]
 [4. 4. 4.]]

Add a value

[5]:
new_val = np.array([1, 2, 3, 4, 5])

cloud.add_values_by_id_list('test', new_val)

print(cloud.header)
['vertex', 'test']

Get coordinates but value as z

[6]:
xyz_val = cloud.get_xyz('test')

print(xyz_val)
[[0. 0. 1.]
 [1. 1. 2.]
 [2. 2. 3.]
 [3. 3. 4.]
 [4. 4. 5.]]

Find the nearest vertex

[7]:
nb = 1
dist, vert, assoc_dict = cloud.find_nearest([[.5, .5, 0.]], nb= nb)

# If the number of neighbors is 1, the output is a single list of vertices and distances
# If the number of neighbors is greater than 1, the output is a list of lists of vertices and distances

print('distance:', dist)
print('vertex:', vert.x, vert.y, vert.z)
print('key:', assoc_dict)
distance: 0.7071067811865476
vertex: 0.0 0.0 0.0
key: {'vertex': <wolfhece.PyVertex.wolfvertex object at 0x000002B1087DA4A0>, 'test': np.int64(1)}

Find the nearest vertices

nb = 2

[8]:
nb = 2
dist, vert, assoc_dict = cloud.find_nearest(np.asarray([[.5, .5, 0.]]), nb= nb)

# If the number of neighbors is 1, the output is a single list of vertices and distances
# If the number of neighbors is greater than 1, the output is a list of lists of vertices and distances

print('number of neighbors:', len(dist))

for i in range(nb):
    print('distance:', dist[i])
    print('vertex:', vert[i].x, vert[i].y, vert[i].z)
    print('key:', assoc_dict[i])

number of neighbors: 2
distance: 0.7071067811865476
vertex: 0.0 0.0 0.0
key: {'vertex': <wolfhece.PyVertex.wolfvertex object at 0x000002B1087DA4A0>, 'test': np.int64(1)}
distance: 1.224744871391589
vertex: 1.0 1.0 1.0
key: {'vertex': <wolfhece.PyVertex.wolfvertex object at 0x000002B128E67DF0>, 'test': np.int64(2)}

Find the nearest vertex for multiple points

[9]:
nb = 2
xyz1 = [.5, 1., 0.]
xyz2 = [.5, 2., 1.]
dist, vert, assoc_dict = cloud.find_nearest([xyz1, xyz2], nb= nb)

# If the number of neighbors is 1, the output is a single list of vertices and distances
# If the number of neighbors is greater than 1, the output is a list of lists of vertices and distances

if nb ==1:
    for i_vert in range(2):
        print('distance:', dist[i_vert])
        print('vertex:', vert[i_vert].x, vert[i_vert].y, vert[i_vert].z)
        print('key:', assoc_dict[i_vert])
else:
    for i_vert in range(2):
        for i in range(nb):
            dist_list = dist[i_vert]
            vert_list = vert[i_vert]
            assoc_dict_list = assoc_dict[i_vert]

            print('distance:', dist_list[i])
            print('vertex:', vert_list[i].x, vert_list[i].y, vert_list[i].z)
            print('key:', assoc_dict_list[i])
distance: 1.118033988749895
vertex: 1.0 1.0 1.0
key: {'vertex': <wolfhece.PyVertex.wolfvertex object at 0x000002B128E67DF0>, 'test': np.int64(2)}
distance: 1.118033988749895
vertex: 0.0 0.0 0.0
key: {'vertex': <wolfhece.PyVertex.wolfvertex object at 0x000002B1087DA4A0>, 'test': np.int64(1)}
distance: 1.118033988749895
vertex: 1.0 1.0 1.0
key: {'vertex': <wolfhece.PyVertex.wolfvertex object at 0x000002B128E67DF0>, 'test': np.int64(2)}
distance: 1.8027756377319946
vertex: 2.0 2.0 2.0
key: {'vertex': <wolfhece.PyVertex.wolfvertex object at 0x000002B128E66350>, 'test': np.int64(3)}

Performance guidelines (quick recap)

Use StorageMode.DICT when:

  • the cloud is small (typically below 100_000 points),

  • you often mutate individual rows or access myvertices directly.

Use StorageMode.NUMPY when:

  • the cloud is large (100_000+ points),

  • you mostly run bulk operations (get_xyz, find_minmax, nearest-neighbor queries).

Practical tips:

  • Keep numpy_backend=None to use the automatic threshold-based switch.

  • Prefer switch_storage_mode(StorageMode.NUMPY) or switch_storage_mode(StorageMode.DICT) for explicit control.

  • Strings ('numpy', 'dict') remain supported for backward compatibility.

  • Reading myvertices always returns a dict view and may materialize data from NumPy mode for compatibility.