Mesh selections#

Helpers for building, saving and replaying triangle selections on a pyvcad.SurfaceMesh without opening a window. A selection file records the triangle IDs together with a fingerprint of the mesh they belong to, so it can refuse to load onto changed geometry, and the recipe that made it, so a point or ray seed can be rerun after a deliberate remesh. Use select_mesh_patch() (see Interactive (GUI)) to pick a selection by hand. See the Select triangle-mesh patches guide for a walkthrough.

pyvcad_rendering.resolve_selection_mesh(source, voxel_size=None)[source]#

Return a SurfaceMesh from an existing mesh or an OpenVCAD tree.

Tree resolution always requires an explicit voxel size. The resulting triangle IDs are tied to that exact resolved mesh and must not be reused after changing the resolution.

Parameters:
  • source (SurfaceMesh | Node) – A mesh to use as is, or a tree to mesh.

  • voxel_size (float, optional) – Meshing voxel size in mm. Required for a Node, and must be None for a SurfaceMesh.

Returns:

The mesh that triangle IDs refer to.

Return type:

SurfaceMesh

Raises:
  • ValueError – If voxel_size is missing for a Node or given for a SurfaceMesh.

  • TypeError – If source is neither type.

pyvcad_rendering.mesh_selection_recipe(method, triangle_id=None, vertex_id=None, point=None, ray_origin=None, ray_direction=None, max_angle_degrees=None, radius=None, blocked_edges=None, triangle_regions=None, boundary_edges=None)[source]#

Build a validated, JSON-serializable selection recipe.

A point or ray seed is geometrically replayable after deliberate remeshing. A triangle-ID seed is exact but is only safe while the mesh fingerprint remains unchanged.

Parameters:
  • method (str) – “manual”, “linked”, “linked_by_face_angle”, “linked_constrained”, “enclosed_region” or “geodesic_radius”. A “manual” recipe takes no other arguments.

  • triangle_id (int, optional) – Seed triangle. Not valid for “geodesic_radius”.

  • vertex_id (int, optional) – Seed vertex. Only valid for “geodesic_radius”.

  • point (Vec3 | sequence, optional) – Seed point; the nearest triangle or vertex is used.

  • ray_origin (Vec3 | sequence, optional) – Ray seed origin. Requires ray_direction.

  • ray_direction (Vec3 | sequence, optional) – Ray seed direction; the first hit is used.

  • max_angle_degrees (float, optional) – Face-angle limit in [0, 180]. Required for “linked_by_face_angle”, optional for “linked_constrained”.

  • radius (float, optional) – Geodesic radius in mm. Required for “geodesic_radius”.

  • blocked_edges (list[tuple[int, int]], optional) – Mesh edges growth cannot cross, for “linked_constrained”.

  • triangle_regions (list[int], optional) – Per-triangle labels; unequal labels stop growth, for “linked_constrained”.

  • boundary_edges (list[tuple[int, int]], optional) – Closed loop of at least three edges. Required for “enclosed_region”.

Exactly one seed (triangle_id, vertex_id, point, or the ray pair) is required for every method except “manual”.

Returns:

The recipe, ready for apply_mesh_selection_recipe() or save_mesh_selection().

Return type:

dict

Raises:

ValueError – If the method is unknown or the seed and parameters do not fit it.

pyvcad_rendering.apply_mesh_selection_recipe(mesh, recipe)[source]#

Run a selection recipe on a resolved SurfaceMesh.

Parameters:
Returns:

The selected triangles.

Return type:

MeshSelection

Raises:
  • ValueError – If the recipe is invalid or “manual”.

  • RuntimeError – If a ray seed misses the mesh.

pyvcad_rendering.save_mesh_selection(selection, path, recipe=None, voxel_size=None)[source]#

Write a versioned triangle-ID selection file with source safety metadata.

The JSON file stores the triangle IDs, the source mesh fingerprint and counts, and the recipe, so load_mesh_selection() can refuse a changed mesh and replay_mesh_selection() can rerun a point or ray seed on it.

Parameters:
  • selection (MeshSelection) – The selection to save. Its source mesh must be unchanged.

  • path (str | Path) – Output file. Parent directories are created.

  • recipe (dict, optional) – The recipe that made the selection. Defaults to a “manual” recipe.

  • voxel_size (float, optional) – The voxel size the source tree was meshed at, recorded for reference.

Raises:
  • TypeError – If selection is not a MeshSelection.

  • RuntimeError – If the selection’s source mesh has changed.

pyvcad_rendering.load_mesh_selection(path, source, voxel_size=None)[source]#

Load exact triangle IDs, rejecting any source fingerprint mismatch.

Parameters:
  • path (str | Path) – A file written by save_mesh_selection().

  • source (SurfaceMesh | Node) – The mesh, or the tree to mesh, that the selection was made on.

  • voxel_size (float, optional) – Meshing voxel size in mm. Required for a Node.

Returns:

The saved triangles on the resolved mesh.

Return type:

MeshSelection

Raises:

RuntimeError – If the resolved mesh’s fingerprint differs from the saved one.

pyvcad_rendering.replay_mesh_selection(path, source, voxel_size=None)[source]#

Replay a saved point/ray recipe on intentionally changed or remeshed geometry.

Exact IDs are returned when the fingerprint still matches. Manual selections and triangle-ID recipes cannot be replayed when it differs because they contain no geometry-stable seed.

Parameters:
  • path (str | Path) – A file written by save_mesh_selection().

  • source (SurfaceMesh | Node) – The current mesh, or the tree to mesh.

  • voxel_size (float, optional) – Meshing voxel size in mm. Required for a Node.

Returns:

The saved triangles, or the recipe rerun on the changed mesh.

Return type:

MeshSelection

Raises:

RuntimeError – If the mesh changed and the recipe has no point or ray seed, or uses a topology-specific method (“linked_constrained” or “enclosed_region”).

pyvcad_rendering.SELECTION_FILE_FORMAT: str = 'openvcad-mesh-selection'#

Value of the format field in a saved mesh-selection JSON file.

pyvcad_rendering.SELECTION_FILE_VERSION: int = 1#

Version of the mesh-selection file format written by save_mesh_selection().