datastructures¤
Mesh data structures for quad meshes, coarse layouts and pseudo-quads, with the strip grammar, smoothing and colouring that act on them.
Classes¤
Mesh
¤
-
Reference
datastructures
Classes
Mesh Methods:load_from_json
Methods:¤
__from_data__
classmethod
¤
Decode a mesh, repairing digit-string strip and polyedge keys back into ints.
boundaries
¤
Collect the mesh boundaries as lists of vertices.
Returns:
-
boundaries(list) –List of boundaries as lists of vertex keys.
boundary_kinks
¤
is_boundary_vertex_kink
¤
Return whether there is a kink at a boundary vertex according to a threshold angle.
Parameters:
-
vkey(Key) –The boundary vertex key.
-
threshold_angle(float) –Threshold angle in rad.
Returns:
-
bool–True if vertex is on the boundary and has an angle larger than the threshold angle. False otherwise.
load_from_json
classmethod
¤
Construct a mesh from what save_to_json wrote; the class comes from the file.
Digit-string strip keys are turned back into ints.
Parameters:
-
filepath(str) – -
default(optional, default:None) –Returned when the file does not exist, instead of raising. For a caller resuming from a cache that may not have been written yet.
Returns:
-
Mesh–Of whatever class the file names.
Raises:
-
TypeError–From
Data.from_json, if the file holds a mesh that is not an instance ofcls.
save_to_json
¤
QuadMesh
¤
-
Reference
datastructures
Classes
CoarseQuadMesh Methods:densification
Methods:¤
add_strip
¤
add_strip(
polyedge: list[int],
open_strip: bool = True,
project: Callable[[list[float]], list[float]] | None = None,
) -> tuple[int, dict[int, tuple[int, int]]]
Add a strip along polyedge. (new strip key, {old vertex: pair}).
See compas_singular.datastructures.mesh_quad.grammar.add_strip.
add_strips
¤
add_strips(
polyedges: list[list[int]],
open_strip: bool = True,
project: Callable[[list[float]], list[float]] | None = None,
) -> list[int]
Add a strip along each polyedge. The new strip keys.
open_strip and project as in add_strip.
collect_polyedge
¤
collect_polyedge(
u0: int,
v0: int,
both_sides: bool = True,
oriented: bool = False,
strict: bool = False,
) -> list[int]
Collect all the edges in the polyedge of the input edge.
Parameters:
-
u0(int) –The identifier of the edge start.
-
v0(int) –The identifier of the edge end.
-
both_sides(bool, default:True) –Whether to walk in both directions from the seed halfedge. Default is True. With False the walk stops at the first extremity, which is what a directional tracer wants.
-
oriented(bool, default:False) –Whether to return the polyedge in the direction of the seed halfedge. Default is False, which returns the reversed polyedge whenever the walk reaches an extremity on the first side, i.e. the seed direction is lost.
-
strict(bool, default:False) –Passed to
vertex_opposite_vertex. Default is False.
Returns:
-
polyedge(list) –The list of the vertices in polyedge.
collect_polyedges
¤
Collect the polyedges accross four-valent vertices between boundaries and/or singularities and store it in the mesh data attributes.
Parameters:
-
strict(bool, default:False) –Passed to
vertex_opposite_vertex. Default is False.
Returns:
-
polyedges(list) –List of quad polyedges as list of vertices.
collect_strip
¤
Returns all the edges in the strip of the input edge; a non-quad face ends it like the boundary.
Parameters:
-
u0(int) –The identifier of the edge start.
-
v0(int) –The identifier of the edge end.
-
both_sides(bool, default:True) –Whether to walk in both directions from the seed halfedge. Default is True. With False the walk stops at the first extremity.
Returns:
-
strip(list) –The list of the edges in strip.
collect_strips
¤
Collect the strip data and store it in the mesh data attributes.
Returns:
-
strips(dict) –The strip data.
delete_strip
¤
Delete the strip skey, welding its sides. {old vertex: the vertex it merged into}.
See compas_singular.datastructures.mesh_quad.grammar.delete_strip.
edge_strip
¤
Return the strip of an edge.
Parameters:
-
edge(tuple) –An edge as two vertex keys.
Returns:
-
strip–The strip of the edge.
face_opposite_edge
¤
Returns the opposite edge in the quad face, or None on a boundary or a non-quad face.
Parameters:
Returns:
-
tuple or None–The opposite edge
(w, x). None if (u, v) is a boundary halfedge, i.e. has no face, or if its face is not a quad.
face_strips
¤
Return the two strips of a face.
Parameters:
-
fkey(hashable) –
Returns:
-
list–The two strips of the face.
is_polyedge_closed
¤
Output whether a polyedge is closed.
Parameters:
-
pkey(hashable) –A strip key.
Returns:
-
bool–True if the polyedge is closed. False otherwise.
is_strip_closed
¤
Output whether a strip is closed.
Parameters:
-
skey(hashable) –A strip key.
Returns:
-
bool–True if the strip is closed. False otherwise.
is_strip_face
¤
Whether a strip can cross this face: it has four sides.
is_vertex_singular
¤
polyedge_edges
¤
Return the edges of a polyedge.
Parameters:
-
pkey(hashable) –A polyedge key.
Returns:
-
list–The edges of the polyedge, as pairs of vertex keys.
polyedge_graph
¤
Compute the vertices and edges of the graph representing the polyedge connectivity, where each graph vertex is a mesh polyedge and each graph edge a non-compas_singular mesh vertex representing the crossing of two polyedges. Polyedges connected by their extremities, which are singularities, do not count as overlapping.
Parameters:
-
legacy(bool, default:True) –Use the historical implementation, about half of whose edges are self-loops. Default is True;
Falsegives one edge per crossing.
Returns:
-
tuple–A tuple of two objects, the dictionary of mesh polyedge indices pointing to their centroid coordinates, and the list of edges between graph vertices.
polyedge_length
¤
Return the length of a polyedge.
Parameters:
-
pkey(hashable) –A polyedge key.
Returns:
-
float–The sum of the lengths of the edges of the polyedge.
polyedge_midpoint
¤
Return the point at mid-length of a polyedge.
Parameters:
-
pkey(hashable) –A polyedge key.
Returns:
-
Point–The midpoint.
polyedge_vertices
¤
Return the vertices of a polyedge.
Parameters:
-
pkey(hashable) –A polyedge key.
Returns:
-
list–The vertices of the polyedge.
polyline
¤
Return the coordinates of the vertices of a polyedge.
Parameters:
-
pkey(hashable) –A polyedge key.
Returns:
-
list–The polyline as a list of XYZ points.
polylines
¤
singularities
¤
Returns all the singularity indices in the quad mesh.
Returns:
-
list–The list of vertex indices that are quad mesh singularities.
singularity_polyedge_decomposition
¤
singularity_polyedges
¤
Collect the polyedges connected to singularities.
Returns:
-
list–The polyedges connected to singularities.
singularity_polyline_decomposition
¤
Return the polylines forming a quad patch decomposition of the mesh.
Returns:
-
list–The polylines connected to singularities.
singularity_polylines
¤
Return the polylines connected to singularities.
Returns:
-
list–The polylines connected to singularities.
strip_edge_midpoint_polyline
¤
Return the strip polyline connecting edge midpoints.
Parameters:
-
skey(hashable) –A strip key.
Returns:
-
list–The edge midpoint polyline.
strip_edges
¤
Return the edges of a strip.
Parameters:
-
skey(hashable) –A strip key.
Returns:
-
list–The edges of the strip.
strip_face_centroid_polyline
¤
Return the strip polyline connecting face centroids.
Parameters:
-
skey(hashable) –A strip key.
Returns:
-
list–The face centroid polyline.
strip_faces
¤
Return the faces of a strip.
Parameters:
-
skey(hashable) –A strip key.
Returns:
-
list–The faces of the strip.
strip_graph
¤
Compute the vertices and edges of the graph representing the strip connectivity, where each graph vertex is a mesh strip and each graph edge a mesh face representing the crossing of two strips. Potentially includes loop edges (u, u) or multiple arallel edges (u, v) and/or (v, u).
Returns:
-
tuple–A tuple of two objects, the dictionary of mesh strip keys pointing to graph vertex coordinates, and the list of edges between graph vertices.
strip_side_polyedges
¤
Return the two side polyedges of a strip.
Parameters:
-
skey(hashable) –A strip key.
Returns:
-
tuple–The pair of polyedges on the side of the strip.
strip_side_polylines
¤
Return the two side polylines of a strip.
Parameters:
-
skey(hashable) –A strip key.
Returns:
-
tuple–The pair of polylines on the side of the strip.
substitute_vertex_in_strips
¤
substitute_vertex_in_strips(
old_vkey: int, new_vkey: int, strips: list[int] | None = None
) -> None
Substitute a vertex by another one.
Parameters:
-
old_vkey(hashable) –The old vertex key.
-
new_vkey(hashable) –The new vertex key.
-
strips(list, default:None) –List of specific strip keys. Per default None, i.e. all.
vertex_opposite_vertex
¤
Returns the opposite vertex to u accross vertex v.
Parameters:
-
u(hashable) –A vertex key.
-
v(hashable) –A vertex key.
-
strict(bool, default:False) –Decide the crossing on edges rather than vertices. Default is False, the historical behaviour; switching it changes decompositions.
Returns:
-
(hashable, None)–The opposite vertex. None if v is a singularity or if (u, v) leads outwards.
CoarseQuadMesh
¤
Attributes¤
__data__
property
¤
Everything but the derived dense meshes this layout last produced.
Methods:¤
coarse_edge_dense_edges
¤
Return the child edges, or polyedge, in the dense quad mesh from a parent edge in the coarse quad mesh.
densification
¤
densification(
boundary_curvature: bool = True,
skeleton_curvature: bool = True,
overwrite_edges_to_curves: dict[tuple[int, int], list[list[float]]] | None = None,
field: Any = None,
) -> QuadMesh
Generate a denser quad mesh from the coarse quad mesh and its strip densities.
Parameters:
-
boundary_curvature(bool, default:True) –Use the shape
edges_to_curveshas stored for edges on the layout's own boundary, instead of chording them. Defaults to True. Ignored -- treated as True -- whenoverwrite_edges_to_curvesis given. -
skeleton_curvature(bool, default:True) –Same, for the edges that are NOT on the boundary -- the interior edges a skeleton or field decomposition traced as separatrices. Defaults to True. Ignored -- treated as True -- when
overwrite_edges_to_curvesis given. -
overwrite_edges_to_curves(dict, default:None) –A dictionary with edges (u, v) pointing to a curve for densification, overriding whatever
edges_to_curveshas stored -- for every edge, regardless ofboundary_curvature/skeleton_curvature. The curves are lists of XYZ points. -
field(optional, default:None) –A
CrossFieldto steer patch interiors; boundaries stay fixed. Any layout on the same walls works, including a skeleton one.
Returns:
-
QuadMesh–The dense mesh, also stored on this one --
get_quad_mesh().
edges_to_curves
¤
from_quad_mesh
classmethod
¤
from_quad_mesh(
quad_mesh: QuadMesh,
collect_strips: bool = True,
collect_polyedges: bool = True,
attribute_density: bool = True,
strict: bool = False,
) -> "CoarseQuadMesh"
Build coarse quad mesh from quad mesh with density and child-parent element data.
Parameters:
-
quad_mesh(QuadMesh) –A quad mesh.
-
attribute_density(bool, default:True) –Keep density data of dense quad mesh and inherit it as aatribute.
-
strict(bool, default:False) –Passed to
QuadMesh.singularity_polyedge_decomposition. Default is False. Setting it to True changes the resulting coarse layout.
Returns:
-
coarse_quad_mesh(CoarseQuadMesh) –A coarse quad mesh with density data.
get_strip_densities
¤
get_strip_density
¤
Get the density of a strip.
Parameters:
-
skey(hashable) –A strip key.
Returns:
-
int–The strip density.
set_edges_to_curves
¤
set_mesh_density_face_target
¤
set_mesh_density_face_target(nb_faces: int) -> None
Set equal strip densities based on a target number of faces.
Parameters:
-
nb_faces(int) –The target number of faces.
set_shape_polylines
¤
Remember the polylines the edges take their shape from. None clears them.
set_strip_density
¤
Set the densty of one strip.
Parameters:
-
skey(hashable) –A strip key.
-
d(int) –A density parameter.
set_strip_density_func
¤
Set the strip densities based on a function.
Parameters:
-
skey(hashable) –A strip key.
set_strip_density_target
¤
Set the strip densities based on a target length and the average length of the strip edges.
Parameters:
-
skey(hashable) –A strip key.
-
t(float) –A target length.
set_strips_density
¤
set_strips_density_func
¤
Set the strip densities based on a function.
Parameters:
-
skeys((list, None), default:None) –The keys of strips to set density. If is None, all strips are considered.
set_strips_density_target
¤
PseudoQuadMesh
¤
Methods:¤
collect_strip
¤
collect_strips
¤
face_opposite_edge
¤
face_strips
¤
Return the two strips of a face.
Parameters:
-
fkey(hashable) –
Returns:
-
list–The two strips of the face.
is_strip_closed
¤
Output whether a strip is closed.
Parameters:
-
skey(hashable) –A strip key.
Returns:
-
bool–True if the strip is closed. False otherwise.
is_strip_face
¤
A quad, or a triangle registered as a pseudo-quad in face_pole.
is_vertex_singular
¤
singularity_polyedges
¤
Collect the polyedges connected to singularities.
Returns:
-
list–The polyedges connected to singularities.
CoarsePseudoQuadMesh
¤
Methods:¤
densification
¤
densification(
boundary_curvature: bool = True,
skeleton_curvature: bool = True,
overwrite_edges_to_curves: dict[tuple[int, int], list[list[float]]] | None = None,
field: Any = None,
) -> "QuadMesh"
Generate a denser quad mesh from the coarse quad mesh and its strip densities.
Parameters:
-
boundary_curvature(bool, default:True) –Use the stored
edges_to_curvesshape for edges on the layout's own boundary. Defaults to True. Ignored -- treated as True -- whenoverwrite_edges_to_curvesis given. -
skeleton_curvature(bool, default:True) –Same, for the interior edges. Defaults to True. Ignored -- treated as True -- when
overwrite_edges_to_curvesis given. -
overwrite_edges_to_curves(dict, default:None) –A dictionary with edges (u, v) pointing to a curve for densification, overriding whatever
edges_to_curveshas stored -- for every edge. The curves are lists of XYZ points. -
field(optional, default:None) –A
CrossField(fromFieldDecomposition.get_field()orCrossField.from_boundary(...)). With it, each patch INTERIOR is integrated from the field instead of blended from its own four sides -- which is the only way a guide curve reaches a patch it forced no topology in. The layout does not have to have come from that field: a skeleton layout and a field solved on the same walls work together. Boundaries stay fixed either way, so the result still welds into a mesh whose strips can be collected and edited.
Returns:
-
QuadMesh–The dense mesh, also stored on this one --
get_quad_mesh().
densify
¤
densify(
pattern_overwrite: "str | dict[int, str] | None" = None,
boundary_curvature: bool = True,
skeleton_curvature: bool = True,
overwrite_edges_to_curves: dict[tuple[int, int], list[list[float]]] | None = None,
field: Any = None,
) -> "QuadMesh"
Build one dense patch per coarse face from the pattern's template and weld them together.
Parameters:
-
pattern_overwrite(str or dict, default:None) –A key of
PATTERNSfor every face, or a dict of face to key. -
boundary_curvature(bool, default:True) –Use the stored
edges_to_curvesshape for edges on the layout's own boundary. Defaults to True. Ignored -- treated as True -- whenoverwrite_edges_to_curvesis given. -
skeleton_curvature(bool, default:True) –Same, for the interior edges. Defaults to True. Ignored -- treated as True -- when
overwrite_edges_to_curvesis given. -
overwrite_edges_to_curves(dict, default:None) –Overrides whatever
edges_to_curveshas stored, for every edge. -
field(optional, default:None) –
Returns:
-
QuadMesh–
from_coarse_polylines
classmethod
¤
from_coarse_polylines(
polylines: list[list[list[float]]],
poles: list[list[float]] | None = None,
holes: list[list[float]] | None = None,
precision: int | None = None,
tol: float | None = None,
collect_strips: bool = True,
) -> "CoarsePseudoQuadMesh"
A coarse quad layout from a drawn network with one polyline per coarse edge.
Validates rather than repairs; triangular patches become pseudo-quads.
Parameters:
-
polylines(list[list[[x, y, z]]]) –One polyline per coarse edge. A straight edge is two points.
-
poles(list[[x, y, z]], default:None) –Preferred pole positions. A triangular patch is a pseudo-quad with or without one; a position given here decides which corner collapses.
-
holes(list[[x, y, z]], default:None) –One point inside each hole of the domain. A hole is a bounded cycle of the network and is otherwise indistinguishable from a patch, so without this it is filled.
-
precision(int, default:None) –Decimals the endpoints are welded at. Default is COMPAS's own, 3.
-
tol(float, default:None) –Distance below which a point is ON a curve, for the validity checks. Defaults to the weld resolution.
-
collect_strips(bool, default:True) –Collect strip data before returning, as
CoarseQuadMesh.from_quad_meshdoes.
Returns:
-
CoarsePseudoQuadMesh–Carrying the drawn shape of every edge -- see
CoarseQuadMesh.edges_to_curves.
Raises:
-
ValueError–On a network that is not a clean planar arrangement of triangular and quadrilateral patches.
quad_mesh
¤
quad_mesh(
boundary_curvature: bool = True,
skeleton_curvature: bool = True,
overwrite_edges_to_curves: dict[tuple[int, int], list[list[float]]] | None = None,
field: Any = None,
pattern_overwrite: "str | dict[int, str] | None" = None,
) -> "QuadMesh"
Generate a dense quad mesh from this layout in a chosen pattern.
'diagonal' and 'fan' first raise densities to equal and even values per patch.
Parameters:
-
boundary_curvature(bool, default:True) –Use the shape
edges_to_curveshas stored for edges on the layout's own boundary, instead of chording them. Defaults to True. Ignored -- treated as True -- whenoverwrite_edges_to_curvesis given. Seedensify. -
skeleton_curvature(bool, default:True) –Same, for the edges that are NOT on the boundary -- the interior edges a skeleton or field decomposition traced as separatrices. Defaults to True. Ignored -- treated as True -- when
overwrite_edges_to_curvesis given. -
overwrite_edges_to_curves(dict, default:None) –Coarse edges
(u, v)pointing to a curve to densify them along, each curve a list of XYZ points, overriding whateveredges_to_curveshas stored -- for every edge, regardless ofboundary_curvature/skeleton_curvature. -
field(optional, default:None) –A
CrossField. Only valid with theorthopattern -- seedensification. -
pattern_overwrite(str or dict, default:None) –One of
compas_singular...patterns.PATTERNS:'ortho'(the plain grid),'diagonal'(the grid with both patch diagonals cut through it) or'fan'(four polar fans meeting at the centre).
Returns:
-
QuadMesh–The dense mesh, also stored on this one --
get_quad_mesh().
Skeleton
¤
Skeleton class for the generation of the topological skeleton or medial axis from a Delaunay mesh.
References
- Harry Blum. 1967. A transformation for extracting new descriptors of shape. Models for Perception of Speech and Visual Forms, pages 362--380. Available at http://pageperso.lif.univ-mrs.fr/~edouard.thiel/rech/1967-blum.pdf.
- Punam K. Saha, Gunilla Borgefors, and Gabriella Sanniti di Baja. 2016. A survey on skeletonization algorithms and their applications. Pattern Recognition Letters, volume 76, pages 3--12. Available at https://www.sciencedirect.com/science/article/abs/pii/S0167865515001233.
-
Reference
datastructures
Classes
Skeleton Methods:from_mesh
Methods:¤
branches
¤
Get the branch polylines of the topological skeleton as polylines connecting singular points.
Returns:
-
list–List of polylines as tuples of XYZ-coordinates.
lines
¤
Get the lines forming the topological skeleton, i.e. the lines connecting the circumcentres of adjacent faces.
Returns:
-
list–List of lines as tuples of pairs XYZ-coordinates.
real_neighbors
¤
BoundaryLoop
¤
A closed domain wall, arc-length parametrised, stored doubled so an arc across the seam is a slice.
Parameters:
-
points(list[[x, y, z]]) –The loop, closed. A repeated closing point is dropped: the loop is stored open and closed by the doubling, so keeping it would put a zero-length segment in the middle of every arc that crosses the seam.
Strip grammar¤
add_strip
¤
add_strip(
mesh: QuadMesh,
polyedge: list[int],
open_strip: bool = True,
project: Callable[[list[float]], list[float]] | None = None,
) -> tuple[int, dict[int, tuple[int, int]]]
Add a strip along polyedge, opened by open_added_strip by default.
The polyedge is consumed. It may run along a wall, and pass a vertex twice (a self-crossing strip).
Parameters:
-
mesh(QuadMesh) –A quad mesh.
attributes['strips']must be non-empty --update_strip_datadoesmax(...) + 1and raises on an empty dict. -
polyedge(list[int]) –Vertex keys in order, each joined to the next by an edge. Either closed, or with both ends on the boundary or at a pole (see
pole_ends). -
open_strip(bool, default:True) –Give the new strip its width with
open_added_strip. DefaultTrue.Falseis topology only: both copies of each vertex stay on top of the vertex they replace. -
project(callable, default:None) –project(xyz) -> xyzfor the new pair at a BOUNDARY vertex, e.g. back onto a curved wall. Without it they stay on the chord across the vertex. Ignored whenopen_stripisFalse.
Returns:
-
tuple[int, dict]–The new strip key, and
{old vertex: (left copy, right copy)}. The left and right polyedges are the values of that map read in polyedge order; the pairs in it are exactly the vertices an opener has to separate. A pole end maps to(pole, pole). A vertex passed twice is split twice: the second pass splits the first pass's copies, which then key its pairs although they are no longer in the mesh.
Raises:
-
ValueError–With
open_strip, when a face next to the strip is left folded or without area. The mesh is left edited: work on a copy.
Notes
An end at an existing pole is not copied: the strip ends there in a new
pseudo-quad, as in thesis Fig. 5.15. See pole_ends.
add_strips
¤
add_strips(
mesh: QuadMesh,
polyedges: list[list[int]],
open_strip: bool = True,
project: Callable[[list[float]], list[float]] | None = None,
) -> list[int]
Add a strip along each polyedge in order, re-deriving the remaining polyedges after each insertion.
Parameters:
-
mesh(QuadMesh) –A quad mesh, with
attributes['strips']already collected. -
polyedges(list[list[int]]) –Polyedges, each a list of vertex keys.
-
open_strip(bool, default:True) –Open each new strip by
open_added_strip. DefaultTrue. -
project(callable, default:None) –Passed on to
open_added_strip.
Returns:
-
list–The new strip keys, in the order the strips were added.
split_strip
¤
split_strip(
mesh: QuadMesh,
skey: int,
n: int = 2,
open_strip: bool = True,
project: Callable[[list[float]], list[float]] | None = None,
) -> list[int]
Refine a strip into n strips. open_strip/project as in add_strip.
Returns:
-
list–The existing strip key, followed by the
n - 1new ones.
split_strips
¤
open_added_strip
¤
open_added_strip(
mesh: QuadMesh,
old_to_new: dict[int, tuple[int, int]],
sides: dict[int, tuple[list[int], list[int]] | None],
on_boundary: Iterable[int] = (),
project: Callable[[list[float]], list[float]] | None = None,
) -> int
Give a new strip its width: place each new pair at thirds of the span across the old vertex.
Only the new pairs move; boundary pairs go through project. Returns the number repositioned.
Parameters:
-
mesh(QuadMesh) –The mesh after a topology-only
add_strip. -
old_to_new(dict) –{old vertex: (copy, copy)}, the second return value ofadd_strip. -
sides(dict) –polyedge_sidesof the polyedge, measured BEFOREadd_strip. -
on_boundary(iterable, default:()) –Old vertices that were on the boundary.
-
project(callable, default:None) –project(xyz) -> xyzapplied to the new pair at a boundary vertex.
Returns:
-
int–The number of pairs actually repositioned. Planar (xy): z is set to 0.
strip_polyedge_update
¤
strip_polyedge_update(
mesh: QuadMesh,
polyedge: list[int],
vertex_modifications: dict[int, tuple[int, int]],
) -> list[int]
Rewrite polyedge in terms of the vertices an insertion left behind.
Parameters:
-
mesh(QuadMesh) –A quad mesh.
-
polyedge(list[int]) –A polyedge, as a list of the OLD vertex keys.
-
vertex_modifications(dict) –Old vertex keys pointing to the new ones that replaced them -- the second return value of
add_strip.
Returns:
-
list–The shortest path that visits the replacements in the original order.
is_polyedge_valid_for_strip_addition
¤
polyedge_sides
¤
polyedge_sides(
mesh: QuadMesh, polyedge: list[int]
) -> dict[int, tuple[list[int], list[int]] | None]
{vertex: (left neighbours, right neighbours)} across the polyedge, in XY.
delete_strip
¤
Delete the strip skey, welding the faces either side together.
Consumed strips go with it and face_pole is repointed; vertices move.
Parameters:
-
mesh(QuadMesh) –A quad mesh.
-
skey(hashable) –A strip key.
Returns:
-
dict–{old vertex: the vertex it was merged into}. Empty if there was no such strip.
delete_strips
¤
Delete several strips.
Strip keys are re-checked as the deletions go, because deleting one strip can
delete others with it -- see collateral_strip_deletions.
collateral_strip_deletions
¤
The strips that deleting skeys would delete as well. Mutates nothing.
total_boundary_deletions
¤
The boundaries that deleting skeys would collapse. Mutates nothing.
strips_to_split_to_prevent_boundary_collapse
¤
strips_to_split_to_prevent_boundary_collapse(
mesh: QuadMesh, skeys: list[int]
) -> dict[int, int] | None
What to split before deleting skeys so every boundary keeps three edges (thesis 5.3.2). Mutates nothing.
Returns:
-
dict or None–Noneif the collapse cannot be prevented,{}if nothing is at risk, else{skey: n}to refine first. Do not conflateNoneand{}.
Pole grammar¤
split_quad_in_pseudo_quads
¤
merge_pseudo_quads_in_quad
¤
Shape grammar¤
add_opening
¤
Add an opening to a mesh face.
Parameters:
-
mesh(Mesh) –A mesh.
-
fkey(hashable) –A face key.
Returns:
-
list–List of new vertex keys around the opening oriented towards the outside.
add_handle
¤
Add a handle between two quad mesh faces.
Parameters:
-
mesh(QuadMesh) –A quad mesh.
-
fkey_1(hashable) –A face key.
-
fkey_2(hashable) –A face key.
Returns:
-
list–List of new face keys around the opening
Smoothing¤
constrained_smoothing
¤
constrained_smoothing(
mesh: Mesh,
kmax: int = 100,
damping: float = 0.5,
constraints: dict[int, Constraint] | None = None,
algorithm: str | Sequence[str] = "centroid",
fixed: Sequence[int] | None = None,
symmetric: bool | None = None,
) -> None
Smooth a mesh in place, moving each constrained vertex back onto its constraint after every iteration.
Parameters:
-
mesh(Mesh) –A mesh to smooth, modified in place.
-
kmax(int, default:100) –Number of iterations for smoothing, per algorithm. Default is
100. -
damping(float, default:0.5) –Damping value for smoothing between 0 and 1. Default is
0.5. -
constraints(dict[int, Constraint], default:None) –Dictionary of constraints as vertex keys pointing to COMPAS geometry (points, polylines, curves or surfaces). Empty by default. See
closest_point_on_constraintfor the accepted geometry. -
algorithm(('centroid', 'area', 'centerofmass'), default:'centroid') –Smoothing algorithm to apply. Classic centroid by default. A sequence of algorithms, such as
['area', 'centroid'], runs each in turn forkmaxiterations, in the order given. -
fixed(sequence[int], default:None) –Vertices that the smoothing algorithm must not move at all. Default is None.
-
symmetric(bool, default:None) –Keep a mesh made by
expand_symmetricallyexactly symmetric by averaging each vertex over itsattributes['orbits']every iteration.None(default) means: when the mesh has orbits.
Returns:
-
None–The mesh is modified in place.
Raises:
-
ValueError–If an algorithm is not recognised.
boundary_constrained_smoothing
¤
boundary_constrained_smoothing(
mesh: Mesh,
curves: Sequence[Constraint] | None = None,
kmax: int = 100,
damping: float = 0.5,
algorithm: str | Sequence[str] = "centroid",
corner_angle: float = pi / 6,
fix_corners: bool = True,
constraints: dict[int, Constraint] | None = None,
) -> dict[int, Constraint]
Smooth a mesh with its boundary vertices sliding along the boundary and corners fixed.
Parameters:
-
mesh(Mesh) –A mesh to smooth, modified in place.
-
curves(sequence, default:None) –The boundary geometry to snap the boundary vertices to, as COMPAS polylines or curves. Default is None, in which case the mesh boundary polylines are used.
-
kmax(int, default:100) –Number of iterations for smoothing, per algorithm. Default is
100. -
damping(float, default:0.5) –Damping value for smoothing between 0 and 1. Default is
0.5. -
algorithm(('centroid', 'area', 'centerofmass'), default:'centroid') –Smoothing algorithm to apply, or several to run in turn. Classic centroid by default. See
constrained_smoothing. -
corner_angle(float, default:pi / 6) –Threshold deviation angle for a boundary kink, in radians. Default is
pi / 6(30 degrees). -
fix_corners(bool, default:True) –If True, pin the boundary vertices at a kink to their current position. Default is True.
-
constraints(dict[int, Constraint], default:None) –Additional constraints, as vertex keys pointing to COMPAS geometry, applied on top of the automated ones. Default is None.
Returns:
-
dict[int, Constraint]–The constraints that were applied, as vertex keys pointing to point, polyline or curve objects. The mesh itself is modified in place.
- Tutorial Smoothing and quality Smoothing functions
boundary_smoothing
¤
boundary_smoothing(
mesh: Mesh,
curves: Sequence[Constraint] | None = None,
kmax: int = 100,
damping: float = 0.5,
algorithm: str | Sequence[str] = "area",
corner_angle: float = pi / 6,
fix_corners: bool = True,
) -> dict[int, Constraint]
Smooth only the boundary of a mesh, sliding its vertices along the boundary.
Unlike boundary_constrained_smoothing, every interior vertex is fixed: the
boundary vertices are redistributed along the boundary and nothing else moves.
Parameters:
-
mesh(Mesh) –A mesh to smooth, modified in place.
-
curves(sequence, default:None) –The boundary geometry to slide the boundary vertices along, as COMPAS polylines or curves. Default is None, in which case the mesh boundary polylines are used.
-
kmax(int, default:100) –Number of iterations for smoothing, per algorithm. Default is
100. -
damping(float, default:0.5) –Damping value for smoothing between 0 and 1. Default is
0.5. -
algorithm(('area', 'centroid', 'centerofmass'), default:'area') –Smoothing algorithm to apply, or several to run in turn. Area by default. See
constrained_smoothing. -
corner_angle(float, default:pi / 6) –Threshold deviation angle for a boundary kink, in radians. Default is
pi / 6(30 degrees). -
fix_corners(bool, default:True) –If True, pin the boundary vertices at a kink to their current position. Default is True.
Returns:
region_smoothing
¤
region_smoothing(
mesh: Mesh,
vertices: Sequence[int] | dict[int, float],
kmax: int = 50,
damping: float = 0.5,
blend: int = 3,
constraints: dict[int, Constraint] | None = None,
) -> dict[int, float]
Area-weighted smoothing of one region, with damping tapered to zero over blend rings.
Everything outside the region is fixed; the taper avoids a crease at its edge.
Parameters:
-
mesh(Mesh) –A mesh to smooth, modified in place.
-
vertices(sequence[int] | dict[int, float]) –The region to smooth, either as the vertex keys of its core -- which are then tapered over
blendrings -- or as a ready-made dictionary of vertex keys pointing to damping weights between 0 and 1, in which caseblendis ignored. A vertex that is absent, or whose weight is not positive, is fixed. -
kmax(int, default:50) –Number of iterations for smoothing. Default is
50, fewer than the whole-mesh functions, since a region is small and needs fewer to settle. -
damping(float, default:0.5) –Damping value for smoothing between 0 and 1, scaled per vertex by its weight. Default is
0.5. -
blend(int, default:3) –Rings of vertices outside the core over which the damping falls to zero. Default is
3. Ignored ifverticesis a dictionary of weights. -
constraints(dict[int, Constraint], default:None) –Dictionary of constraints as vertex keys pointing to COMPAS geometry, applied to the vertices of the region after every iteration. Constraints on vertices outside the region are ignored, since those vertices do not move. Default is None, in which case
automated_boundary_constraintsis used: a region touching the boundary then slides along it instead of being dragged inward. Seeclosest_point_on_constraintfor the accepted geometry.
Returns:
-
dict[int, float]–The damping weights that were applied, as vertex keys pointing to a weight between 0 and 1. The mesh itself is modified in place.
- Tutorial Smoothing and quality Smoothing functions
relaxation
¤
relaxation(
mesh: Mesh,
fixed: str | Sequence[int] = "corners",
constraints: dict[int, Constraint] | None = None,
q_factor: float = 100.0,
) -> None
Force-density relaxation of a mesh with compas_fd, boundary edges q_factor times stiffer.
Parameters:
-
mesh(Mesh) –A mesh to relax, modified in place.
-
fixed(('corners', 'boundary'), default:'corners') –The vertices that do not move:
'corners'(default) for the boundary vertices at a kink,'boundary'for every boundary vertex, or the vertex keys themselves. -
constraints(dict[int, Constraint], default:None) –Dictionary of constraints as vertex keys pointing to geometry the vertex must stay on. A point pins the vertex there, like a fixed vertex. A polyline or a sequence of points, a compas Vector, Frame, Line, Plane, Circle, NurbsCurve or NurbsSurface, or a
compas_fdConstraint lets it slide along. Constraints on fixed vertices are ignored. Default is None. -
q_factor(float, default:100.0) –How much larger the force density of a boundary edge is than that of an interior edge. Default is
100.
Returns:
-
None–The mesh is modified in place.
Raises:
-
ValueError–If
fixedis an unrecognised string. -
TypeError–If a constraint cannot be turned into a
compas_fdconstraint. -
ImportError–If
compas_fdis not installed.
- Tutorial Smoothing and quality Smoothing functions
automated_boundary_constraints
¤
automated_boundary_constraints(
mesh: Mesh,
curves: Sequence[Constraint] | None = None,
corner_angle: float = pi / 6,
fix_corners: bool = True,
) -> dict[int, Constraint]
Constrain every boundary vertex to the boundary curve it belongs to, pinning kinks.
Parameters:
-
mesh(Mesh) –The mesh to constrain.
-
curves(sequence, default:None) –The boundary geometry to snap the boundary vertices to, as COMPAS polylines or curves. Each run of boundary vertices between two corners is matched to the curve it is closest to. Default is None, in which case the mesh boundary polylines are used.
-
corner_angle(float, default:pi / 6) –Threshold deviation angle for a boundary kink, in radians. Default is
pi / 6(30 degrees). -
fix_corners(bool, default:True) –If True, pin the boundary vertices at a kink to their current position. Default is True.
Returns:
closest_point_on_constraint
¤
closest_point_on_constraint(
constraint: Constraint, xyz: list[float], discretisation: int = 128
) -> list[float] | None
Project a point onto a constraint object, using COMPAS geometry only.
Parameters:
-
constraint(None | Point | [float, float, float] | Polyline | sequence[point] | Curve | Any) –The geometry to project onto:
None-- no constraint, None is returned;- a
compas.geometry.Pointor a bare[x, y, z]-- the point itself, i.e. a pin; - a
compas.geometry.Polylineor any sequence of points -- the closest point on that polyline, viacompas.geometry.closest_point_on_polyline; - any other
compas.geometry.Curve-- acompas.geometry.Line, acompas.geometry.Circle, a curve fromcompas_rhino'scurve_to_compasor fromcompas_occ-- the closest point on the curve, from its ownclosest_point. See_closest_point_on_curvefor the curves that have none and fall back on theirto_polylinediscretisation; - any other object with a working
closest_pointmethod (acompas_singular.editing.GuideCurve, a Rhino or OCC surface, ...) -- the result of that method; - anything else with a
to_polyline-- the closest point on that discretisation.
-
xyz([float, float, float]) –The coordinates of the point to project.
-
discretisation(int, default:128) –Number of segments used to discretise a curve that has no analytical closest point. Default is
128.
Returns:
-
list[float] | None–The XYZ coordinates of the closest point on the constraint, or None if the constraint is None.
Raises:
-
TypeError–If the closest point on the constraint cannot be computed.
mesh_boundary_loops
¤
mesh_boundary_polylines
¤
mesh_boundary_corners
¤
Collect the boundary vertices of a mesh that sit on a kink.
The kink is measured as the deviation from straight between the two boundary edges at the vertex: zero along a straight boundary, pi / 2 at a square corner.
Parameters:
-
mesh(Mesh) –A mesh.
-
corner_angle(float, default:pi / 6) –Threshold deviation angle, in radians. Default is
pi / 6(30 degrees).
Returns:
automated_smoothing_surface_constraints
¤
automated_smoothing_surface_constraints(
mesh: Mesh,
surface: Any,
borders: Sequence[Any],
kinks: Sequence[list[float]] | None = None,
) -> dict[int, Any]
Constrain every vertex to a surface, each boundary vertex to its nearest border, and kinks to points.
Parameters:
-
mesh(Mesh) –The mesh to constrain.
-
surface(Any) –The surface, as anything with a
closest_pointmethod. -
borders(sequence) –The border curves of the surface, as polylines or curves.
-
kinks(sequence[[float, float, float]], default:None) –The points along the borders where the tangent jumps.
Returns:
-
dict–Vertex keys pointing to the surface, a border curve or a
compas.geometry.Point.
automated_smoothing_constraints
¤
automated_smoothing_constraints(
mesh: Mesh,
points: Sequence[list[float]] | None = None,
curves: Sequence[Any] | None = None,
surface: Any | None = None,
) -> dict[int, Any]
Constrain the vertices of a mesh to pins, boundary curves and a surface; pins win.
Parameters:
-
mesh(Mesh) –The mesh to constrain.
-
points(sequence[[float, float, float]], default:None) –Each pins the mesh vertex nearest to it, anywhere in the mesh.
-
curves(sequence, default:None) –Curves for the boundary vertices, as polylines or curves.
-
surface(Any, default:None) –A surface -- or a mesh -- for every vertex, as anything with a
closest_pointmethod.
Returns:
-
dict–Vertex keys pointing to a point, curve or surface.
surface_constrained_smoothing
¤
surface_constrained_smoothing(
mesh: Mesh,
surface: Any,
borders: Sequence[Any],
kmax: int = 100,
damping: float = 0.5,
algorithm: str = "centroid",
) -> dict[int, Any]
Smooth a mesh on a surface, re-projecting boundary vertices onto the nearest border every iteration.
Parameters:
-
mesh(Mesh) –A mesh to smooth, modified in place.
-
surface(Any) –The surface, as anything with a
closest_pointmethod. -
borders(sequence) –The border curves of the surface, as polylines or curves.
-
kmax(int, default:100) –Number of iterations for smoothing. Default is
100. -
damping(float, default:0.5) –Damping value for smoothing between 0 and 1. Default is
0.5. -
algorithm(('centroid', 'area', 'centerofmass'), default:'centroid') –Type of smoothing algorithm to apply. Classic centroid by default.
Returns:
-
dict–The constraints that were applied. The mesh itself is modified in place.
Coarse edge curves¤
coarse_edges_to_curves
¤
coarse_edges_to_curves(
coarse: "CoarseQuadMesh | CoarsePseudoQuadMesh",
loops: "list[list[list[float]]] | tuple[list[list[float]], ...]" = (),
polylines: "list[list[list[float]]] | tuple[list[list[float]], ...]" = (),
wall_tol: float | None = None,
precision: int | None = None,
) -> tuple[dict[tuple[int, int], list[list[float]]], dict[str, int]]
({(u, v): polyline}, tally): the shape of every coarse edge, for densification(edges_to_curves=...).
The mapping is complete for every edge, as densification requires.
Parameters:
-
coarse(CoarseQuadMesh or CoarsePseudoQuadMesh) –The layout to densify. Read only.
-
loops(list[list[[x, y, z]]], default:()) –The domain walls, outer first, each closed. Sample them from the Rhino curves at whatever resolution the final mesh should follow -- these points ARE the boundary from here on, so an arc handed over as two points is a chord.
-
polylines(list[list[[x, y, z]]], default:()) –The decomposition's branches, as baked on
Skeleton::Polylines. Matched by the geometric key of their two ends. -
wall_tol(float, default:None) –How far from a wall a boundary corner may sit and still be taken as on it. Defaults to a quarter of the mean coarse edge length, which is generous on purpose: a corner placed by the background triangulation lies on a CHORD of the wall, so on a tightly curved boundary it is a sagitta off it -- 0.03 for a 0.5 background on a 1-unit radius -- and the branch is already gated on the edge being topologically on the layout boundary and on
_arc_is_one_edge. -
precision(int, default:None) –Decimals for the geometric key of the traced branch. The default is COMPAS's own (3), which is far coarser than the single-precision error a Rhino mesh round trip introduces and so is safe.
Returns:
snap_corners_to_walls
¤
snap_corners_to_walls(
coarse: "CoarseQuadMesh | CoarsePseudoQuadMesh",
loops: "list[list[list[float]]] | tuple[list[list[float]], ...]" = (),
wall_tol: float | None = None,
) -> tuple[int, float]
Move the layout's boundary corners onto the nearest wall, within wall_tol. (moved, worst).
Mutates coarse; call it before coarse_edges_to_curves.
Parameters:
-
coarse(CoarseQuadMesh or CoarsePseudoQuadMesh) –The layout. Modified in place.
-
loops(list[list[[x, y, z]]], default:()) –The domain walls, outer first, each closed -- the same ones handed to
coarse_edges_to_curves. -
wall_tol(float, default:None) –Largest move allowed. Defaults to a quarter of the mean coarse edge length, matching
coarse_edges_to_curves.
Returns:
mean_edge_length
¤
mean_edge_length(coarse: 'CoarseQuadMesh | CoarsePseudoQuadMesh') -> float
Average coarse edge length, the scale every tolerance here is relative to.
Coarse mesh from polylines¤
split_at_corners
¤
split_at_corners(
points: list[list[float]], angle: float = CORNER_ANGLE
) -> list[list[list[float]]]
split_at_junctions
¤
split_at_junctions(
polylines: list[list[list[float]]],
tol: float | None = None,
precision: int | None = None,
points: "list[list[float]] | tuple[list[float], ...]" = (),
) -> tuple[list[list[list[float]]], list[int]]
Split every polyline wherever another ends on it or crosses it. (pieces, origin).
Turns a drawing into a network weld_network accepts; dangling ends are left for it to refuse.
Parameters:
-
polylines(list[list[[x, y, z]]]) – -
tol(float, default:None) –How close an end must be to another curve to be ON it. Defaults to the weld resolution, the same distance
check_networkrefuses a T-junction at -- so what this splits is exactly what that would refuse. -
precision(int, default:None) –Decimals of the weld, used only to derive the default
tol. -
points(list[[x, y, z]], default:()) –Extra points to cut at. Any polyline passing within
tolof one is split there, exactly as if a curve had ended on it. For a caller that knows where a corner is without having a curve that ends there -- a corner on a wall, marked by a piece of wall that is not itself an edge.
Returns:
weld_network
¤
weld_network(
polylines: list[list[list[float]]], precision: int | None = None
) -> tuple[list[list[float]], list[tuple[int, int, list[list[float]]]]]
(vertices, edges) from a drawn network. One polyline is one coarse edge.
Parameters:
-
polylines(list[list[[x, y, z]]]) –One polyline per coarse edge. A straight edge is two points; a curved one is however many the CAD session sampled it at.
-
precision(int, default:None) –Decimals the endpoints are welded at. The default is COMPAS's own, 3, which is the resolution
Mesh.from_polylinesmatches endpoints at and the one a Rhino mesh round trip already rounds to.
Returns:
-
tuple[list[[x, y, z]], list[int, int, list[[x, y, z]]]]–The corners, and one
(start, end, points)per edge withpointsrunningstart->end. Corner indices are positional, so handingverticesstraight tofrom_vertices_and_facesgives mesh keys that are these same indices.
Raises:
-
ValueError–On a polyline that is not an edge, or a second polyline between two corners that already have one.
check_network
¤
check_network(
vertices: list[list[float]],
edges: list[tuple[int, int, list[list[float]]]],
tol: float,
) -> None
Raise unless the drawn network is a clean planar arrangement.
Checks T-junctions, crossings, dangling curves and loose pieces, most specific first.
Parameters:
-
vertices(list) –As returned by
weld_network. -
edges(list) –As returned by
weld_network. -
tol(float) –Distance below which a point is ON a curve. The weld resolution is the right scale -- two points nearer than that are already one corner.
Raises:
faces_from_network
¤
faces_from_network(
vertices: list[list[float]],
edges: list[tuple[int, int, list[list[float]]]],
holes: list[list[float]] | None = None,
) -> list[list[int]]
The domain's patches as counter-clockwise rings of corner indices, by planar face walk.
The unbounded face (by the full point ring's signed area) and holes are dropped.
Parameters:
-
vertices(list) –As returned by
weld_network. -
edges(list) –As returned by
weld_network. -
holes(list[[x, y, z]], default:None) –One point inside each hole of the domain.
Returns:
check_faces
¤
check_faces(
faces: list[list[int]], vertices: list[list[float]], sides: tuple[int, ...] = (3, 4)
) -> None
Raise unless every recovered patch has an allowed number of sides (triangles become poles).
Colouring¤
mesh_vertex_2_coloring
¤
Try to color the vertices of a mesh with two colors only without adjacent vertices with the same color.
Parameters:
-
mesh(Mesh) –A mesh.
Returns:
-
(dict, None)–A dictionary with vertex keys pointing to colors, if two-colorable. None if not two-colorable.
mesh_vertex_n_coloring
¤
Color the vertices of a mesh with a minimum number of colors without adjacent vertices with the same color.
Parameters:
-
mesh(Mesh) –A mesh.
Returns:
-
dict–A dictionary with vertex keys pointing to colors.
mesh_face_2_coloring
¤
Try to color the faces of a mesh with two colors only without adjacent faces with the same color.
Parameters:
-
mesh(Mesh) –A mesh.
Returns:
-
(dict, None)–A dictionary with face keys pointing to colors, if two-colorable. None if not two-colorable.
mesh_face_n_coloring
¤
Color the faces of a mesh with a minimum number of colors without adjacent faces with the same color.
Parameters:
-
mesh(Mesh) –A mesh.
Returns:
-
dict–A dictionary with face keys pointing to colors.
quad_mesh_strip_2_coloring
¤
Try to color the strips of a quad mesh with two colors only without overlapping strips with the same color.
Parameters:
-
quad_mesh(QuadMesh) –A quad mesh.
Returns:
-
(dict, None)–A dictionary with strip keys pointing to colors, if two-colorable. None if not two-colorable.
quad_mesh_strip_n_coloring
¤
Color the strips of a quad mesh with a minimum number of colors without overlapping strips with the same color.
Parameters:
-
quad_mesh(QuadMesh) –A quad mesh.
Returns:
-
dict–A dictionary with strip keys pointing to colors.
quad_mesh_polyedge_2_coloring
¤
quad_mesh_polyedge_2_coloring(
quad_mesh: QuadMesh, edge_output: bool = False
) -> dict[Any, int] | None
Try to color the polyedges of a quad mesh with two colors only without overlapping polyedges with the same color. Polyedges connected by their extremities, which are singularities, do not count as overlapping.
Parameters:
-
quad_mesh(QuadMesh) –A quad mesh.
-
edge_output(bool, default:False) –Optional to output coloring per edge keys instead of polyedge key.
Returns:
-
(dict, None)–A dictionary with polyedge keys pointing to colors, if two-colorable. If edge_output, edge keys pointing to colors. None if not two-colorable.
quad_mesh_polyedge_n_coloring
¤
Color the polyedges of a quad mesh with a minimum number of colors without overlapping polyedges with the same color. Polyedges connected by their extremities, which are singularities, do not count as overlapping.
Parameters:
-
quad_mesh(QuadMesh) –A quad mesh.
-
edge_output(bool, default:False) –Optional to output coloring per edge keys instead of polyedge key.
Returns:
-
dict–A dictionary with polyedge keys pointing to colors. If edge_output, edge keys pointing to colors.
dense_quad_mesh_polyedge_2_coloring
¤
Morphing¤
fold
¤
fold(
quad_mesh: QuadMesh,
vkey_to_group: dict[int, int],
func0: Callable[[QuadMesh, int], list[float]],
func1: Callable[[QuadMesh, int], list[float]],
) -> dict[int, list[float]]
fold_vertex_group
¤
Operations¤
mesh_move_by
¤
mesh_move_vertices_by
¤
Move mesh vertices by different vectors.
Parameters:
-
mesh(Mesh) –A mesh.
-
key_to_vector(dict) –A dictionary of vertex keys pointing to vectors.
mesh_move_vertex_to
¤
Move a mesh vertex to a point.
Parameters:
-
mesh(Mesh) –A mesh.
-
point(list) –An XYZ point.
-
vkey(hashable) –A vertex key.
is_face_degenerate
¤
Whether a triangle is flat (collinear or repeated corners), by a scale-relative height test.
Parameters:
-
a(list) –The three corners, as
[x, y, z]. -
b(list) –The three corners, as
[x, y, z]. -
c(list) –The three corners, as
[x, y, z]. -
tol(float, default:FLATNESS) –Relative height below which the triangle counts as flat.
Returns:
-
bool–
trimesh_face_circle
¤
Circumcircle of a triangular face, in closed form so the centre is bit-reproducible.
Parameters:
-
mesh(Mesh) –A mesh.
-
fkey(hashable) –A face key.
Returns:
-
tuple or None–(center, radius, normal)-- centre first, which is the ordering compas_singular relies on -- or None if the face is not a triangle.
Raises:
-
ValueError–If the triangle is flat. A flat triangle has no circumcircle, and the closed form below divides by its doubled squared area.
boundary_triangulationdeletes flat faces before any caller here gets to walk them, so reaching this means one was built some other way.
mesh_weld
¤
Weld vertices within a precision into a new mesh, dropping faces that collapse below three vertices.
Parameters:
-
mesh(Mesh) –A mesh.
-
precision(int, default:None) –Decimals of the geometric key used to match vertices. Defaults to the COMPAS tolerance precision.
-
cls(type, default:None) –The class of the resulting mesh. Defaults to the class of
mesh.
Returns:
-
Mesh–A new welded mesh.
meshes_join
¤
meshes_join_and_weld
¤
meshes_join_and_weld(
meshes: list[Mesh], precision: int | None = None, cls: type | None = None
) -> Any
Join and weld meshes within a precision distance, returning a new mesh.
Parameters:
-
meshes(list) –A list of meshes.
-
precision(int, default:None) –Decimals of the geometric key used to match vertices. Defaults to the COMPAS tolerance precision.
-
cls(type, default:None) –The class of the resulting mesh. Defaults to the class of the first mesh.
Returns:
-
Mesh–A new joined and welded mesh.