Mesh - mesh of triangles

../../_images/mesh-mesh.png
class Mesh(points=None, faces=None, tracks=None, groups=None, options=None)[source]

set of triangles, used to represent volumes or surfaces. As volumes are represented by their exterior surface, the same datastructure represent bothvolumes and faces.

Note

a Mesh instance can contain non-connex geometries (like many separated parts, called islands), or even non-manifold meshing. In the purpose of part design, the madcad functions may need more regular caracteristics so checking methods exists and it is up the the user to ensure the meshes do provide them when calling the demanding functions.

points

typedlist of vec3 for points

faces

typedlist of uvec3 for faces, the triplet is (a,b,c) such that cross(b-a, c-a) is the normal oriented to the exterior.

tracks

typedlist of integers giving the group each face belong to

groups

custom information for each group

options

custom informations for the entire mesh

__add__(other)[source]

return a new mesh concatenating the faces and points of both meshes

__iadd__(other)[source]

append the faces and points of the other mesh

own(**kwargs) Self

Return a copy of the current mesh, which attributes are referencing the original data or duplicates if demanded

Example

>>> b = a.own(points=True, faces=False)
>>> b.points is a.points
False
>>> b.faces is a.faces
True
option(**kwargs) self

Update the internal options with the given dictionary and the keywords arguments. This is only a shortcut to set options in a method style.

transform(trans) Self

Apply the transform to the points of the mesh, returning the new transformed mesh

mergeclose(limit=None) dict

Merge points below the specified distance, or below the precision return a dictionary of points remapping {src index: dst index}

O(n) implementation thanks to hashing

mergepoints(merges) self[source]

merge points with the merge dictionnary {src index: dst index} merged points are not removed from the buffer.

mergegroups(defs=None, merges=None) self

Merge the groups according to the merge dictionary The new groups associated can be specified with defs The former unused groups are not removed from the buffer and the new ones are appended

If merges is not provided, all groups are merged, and defs is the data associated to the only group after the merge

strippoints() list[source]

remove points that are used by no faces, return the reindex list. if used is provided, these points will be removed without usage verification

return a table of the reindex made

stripgroups() list

Remove groups that are used by no faces. return the reindex list.

finish() self
Finish and clean the mesh
note that this operation can cost as much as other transformation operation job done
  • mergeclose
  • strippoints
  • stripgroups
  • check
check()[source]

raise if the internal data is inconsistent

isvalid()

Return true if the internal data is consistent (all indices referes to actual points and groups)

issurface()[source]

return True if the mesh is a well defined surface (an edge has 2 connected triangles at maximum, with consistent normals) such meshes are usually called ‘manifold’

isenvelope()[source]

return True if the surfaces are a closed envelope (the outline is empty)

pointnear(point: dvec3) int

Return the nearest point the the given location

pointat(point: dvec3, neigh=1e-13) int

Return the index of the first point at the given location, or None

groupnear(point) int[source]

return group id if the face the closest to the given point

facenear(point) int[source]

return the index of the closest triangle to the given point

group(quals) Self[source]

extract a part of the mesh corresponding to the designated groups.

Groups can be be given in either the following ways:
  • a set of group indices

    This can be useful to combine with other functions. However it can be difficult for a user script to keep track of which index correspond to which created group

  • an iterable of group qualifiers

    This is the best way to designate groups, and is meant to be used in combination with self.qual(). This mode selects every group having all the input qualifiers

Example

>>> # create a mesh with only the given groups
>>> mesh.group({1, 3, 8, 9})
<Mesh ...>
>>> # create a mesh with all the groups having the following qualifiers
>>> mesh.group(['extrusion', 'arc'])
<Mesh ...>
replace(mesh, groups=None) self[source]

replace the given groups by the given mesh. If groups is not specified, it will take the matching groups (with same index) in the current mesh

qualify(*quals, select=None, replace=False) self

Set a new qualifier for the given groups

Parameters:
  • quals – the qualifiers to enable for the selected mesh groups
  • select (iterable) – if specified, only the groups having all those qualifiers will be added the new qualifiers
  • replace (bool) – if True, the qualifiers in select will be removed

Example

>>> pool = meshb.qualify('part-a') + meshb.qualify('part-b')
>>> set(meshb.faces) == set(pool.group('part-b').faces)
True
>>> chamfer(mesh, ...).qualify('my-group', select='chamfer', replace=True)
>>> mesh.group('my-group')
<Mesh ...>
qualified_indices(quals)

Yield the faces indices when their associated group are matching the requirements

qualified_groups(quals)

Yield the groups indices when they are matching the requirements

maxnum() float

Maximum numeric value of the mesh, use this to get an hint on its size or to evaluate the numeric precision

precision(propag=3) float

Numeric coordinate precision of operations on this mesh, allowed by the floating point precision

surface() float[source]

total surface of triangles

volume() float[source]

return the volume enclosed by the mesh if composed of envelopes (else it has no meaning)

barycenter() dvec3[source]

surface barycenter of the mesh

barycenter_points() dvec3

Barycenter of points used

box() Box

Return the extreme coordinates of the mesh (vec3, vec3)

usepointat(point, neigh=1e-13) int

Return the index of the first point in the mesh at the location. If none is found, insert it and return the index

facepoints(f) tuple[source]

shorthand to get the points of a face (index is an int or a triplet)

facenormal(f) dvec3[source]

normal for a face

facenormals() [vec3][source]

list normals for each face

edgenormals() {uvec2: vec3}[source]

dict of normals for each UNORIENTED edge

vertexnormals() [vec3][source]

list of normals for each point

tangents() {int: vec3}[source]

tangents to outline points

edges() set[source]

set of UNORIENTED edges present in the mesh

edges_oriented() set[source]

iterator of ORIENTED edges, directly retreived of each face

outlines() Web[source]

return a Web of ORIENTED edges

outlines_oriented() set[source]

return a set of the ORIENTED edges delimiting the surfaces of the mesh

outlines_unoriented() set[source]

return a set of the UNORIENTED edges delimiting the surfaces of the mesh this method is robust to face orientation aberations

groupoutlines() Web[source]

return a Web of ORIENTED edges indexing groups.

On a frontier between multiple groups, there is as many edges as groups, each associated to a group.

frontiers(*args) Web[source]

return a Web of UNORIENTED edges that split the given groups appart.

The arguments are groups indices or lists of group qualifiers (as set in qualify()). If there is one only argument it is considered as as list of arguments.

  • if no argument is given, then return the frontiers between every groups
  • to include the groups edges that are on the group border but not at the frontier with an other group, add None to the group set

Example

>>> m = Mesh([...], [uvec3(0,1,2), uvec3(2,1,3)], [0, 1], [...])
>>> m.frontiers(0,1).edges
[uvec2(1,2)]
>>> # equivalent to
>>> m.frontiers({0,1}).edges
[uvec2(1,2)]
>>> m.frontiers(0,None)
[uvec2(0,1), uvec2(0,2)]
splitgroups(edges=None)[source]

split the mesh groups into connectivity separated groups. the points shared by multiple groups will be duplicated if edges is provided, only the given edges at group frontier will be splitted

return a list of tracks for points

split(edges) Self[source]

split the mesh around the given edges. The points in common with two or more designated edges will be dupliated once or more, and the face indices will be reassigned so that faces each side of the given edges will own a duplicate of that point each.

islands(conn=None) [Mesh][source]

return the unconnected parts of the mesh as several meshes

flip() Self[source]

flip all faces, getting the normals opposite

orient(dir=None, conn=None) Self[source]

flip the necessary faces to make the normals consistent, ensuring the continuity of the out side.

Argument dir tries to make the result deterministic:

  • if given, the outermost point in this direction will be considered pointing outside
  • if not given, the farthest point to the barycenter will be considered pointing outside

note that if the mesh contains multiple islands, that direction must make sense for each single island