Class Definition: polymesh.Mesh

drafting: polymesh.Mesh

A triangle mesh in millimetres.

polymesh.Mesh holds a surface made of flat triangles: the points of its vertices, the triangles as indices into them, and optionally a colour for each vertex or each triangle. It is what polymesh.read makes of an STL, OBJ or PLY file, what its method write saves to one, and what solid.polyhedron builds a solid from. A mesh from elsewhere, such as the faces and vertices isosurface returns, becomes one through the constructor.

A mesh is measured by area, volume and bbox, moved by translate, rotate, mirror and scale as a solid.Shape is, and cut with a plane into regions by section.

 
 ## A tetrahedron, its triangles turned outwards
 V = [0, 0, 0; 10, 0, 0; 0, 10, 0; 0, 0, 10];
 F = [1, 3, 2; 1, 2, 4; 2, 3, 4; 3, 1, 4];
 C = [1, 0, 0; 0, 1, 0; 0, 0, 1; 1, 1, 0];
 M = polymesh.Mesh (V, F, 'FaceColour', C);
 volume (M)
 ⇒ 166.67

The class is a value class. Every operation returns a new mesh and leaves its operand unchanged. The vertices and triangles are set when the mesh is made; the colours can be set at any time.

See also: polymesh.read, polymesh.Mesh.write, solid.polyhedron

Source Code: polymesh.Mesh

The polymesh.Mesh class contains the following properties:

The vertices as an N-by-3 matrix of x, y and z in millimetres.

The triangles as a K-by-3 matrix of indices into the rows of Vertices, one row for each triangle. The order of its corners turns the triangle: seen from the side its normal points to, they run anticlockwise.

An N-by-3 matrix of red, green and blue from 0 to 1, a row for each vertex, or empty for none.

A K-by-3 matrix of red, green and blue from 0 to 1, a row for each triangle, or empty for none.

The polymesh.Mesh class offers the following public methods:

polymesh.Mesh: M = polymesh.Mesh ()

polymesh.Mesh: M = polymesh.Mesh (V, F)

polymesh.Mesh: M = polymesh.Mesh (S)

polymesh.Mesh: M = polymesh.Mesh (…, name, value)

M = polymesh.Mesh () returns the empty mesh, which has no vertices and no triangles.

M = polymesh.Mesh (V, F) makes the mesh of the points V, an N-by-3 matrix, and the triangles F, a K-by-3 matrix of indices into the rows of V.

M = polymesh.Mesh (S) takes them from a struct with the fields vertices and faces, the form patch, isosurface and reducepatch use.

NameValue
'VertexColour'an N-by-3 matrix of red, green and blue from 0 to 1, a row for each vertex
'FaceColour'a K-by-3 matrix of red, green and blue from 0 to 1, a row for each triangle

A vertex that no triangle uses is kept, and so is a triangle two of whose corners are one vertex.

polymesh.Mesh: R = section (M, U)

polymesh.Mesh: R = section (M, U, 'Tolerance', T)

polymesh.Mesh: [R, OPEN] = section (…)

R = section (M, U) cuts the mesh M with the plane of the geom.UCS U, and returns the cut as solid.Shape.section returns the cut of a solid: a 1-by-N cell array of geom.Region objects in U, one for each separate piece, largest first, each an outline with the holes in it, or the empty cell (1, 0) when the cut has no area. A face of the mesh lying in the plane is part of the cut.

The cut of a mesh is a polygon, and the regions are made of straight segments, exact for the mesh: a round hole in a mesh is a polygon of its facets. The triangles may be turned either way, inwards or outwards, which many files get wrong; outlines and holes are told apart by how they nest. geom.Region.fit turns the polygon back into lines, arcs and splines within a tolerance, so that a faceted bore is a circle again.

R = section (M, U, 'Tolerance', T) heals a mesh with gaps: where the cut through it breaks off, ends closer than T are joined, nearest first, and points of the cut closer than T are taken as one. The default T is a millionth of the size of the mesh, which joins nothing but rounding.

[R, OPEN] = section (…) returns in OPEN what could not be made into regions, as a cell array of N-by-2 polylines in the coordinates of U: chains that still break off, where the mesh has a hole wider than T, and loops that cross themselves or one another, where the mesh does. A closed loop repeats its first point at its end.

 
 ## A slice half way up a part, healed where it was saved with gaps
 M = polymesh.read ('part.stl');
 [R, OPEN] = section (M, geom.UCS ([0, 0, 1], [0, 0, 12]), ...
                      'Tolerance', 0.01);

See also: solid.Shape.section, geom.Region, geom.Region.fit

polymesh.Mesh: write (M, FILE)

polymesh.Mesh: write (M, FILE, 'Encoding', E)

write (M, FILE) writes the mesh M to FILE, in the format the extension of FILE names, .stl, .obj, .ply or .3mf in any case, with its colours where the format holds them.

  • An STL file is binary: each triangle its normal, computed from its corners, and its corners as 32-bit floats, about seven significant figures. It holds no colours.
  • An OBJ file is text, each coordinate in the fewest digits that read back as the same number. A vertex’s colour follows its coordinates. Face colours are materials, one for each distinct colour, in a library beside FILE with its name and the extension .mtl, which replaces any file of that name.
  • A PLY file is binary, little-endian, its coordinates 64-bit floats. Colours are the properties red, green and blue of its vertices and of its faces, as uchar from 0 to 255.
  • A 3MF file is the archive slicers take, in millimetres: one object named after FILE, each coordinate in the fewest digits that read back as the same number, and the colours of the triangles as base materials. It holds no vertex colours. The empty mesh cannot be written to it.

write (M, FILE, 'Encoding', E) writes a PLY file as text, each coordinate in the fewest digits that read back as the same number, when E is 'ascii', or binary when it is 'binary', the default; no other format takes it.

So OBJ, PLY and 3MF keep every coordinate exactly, and STL keeps a few microns on a part tens of millimetres across. polymesh.read reads all four back.

See also: polymesh.read

polymesh.Mesh: show (M)

polymesh.Mesh: V = show (M)

show (M) shows the mesh in a model.Viewer kept for its variable and titled with its name, which opens the first time and redraws in place after, the camera where it was; a mesh given as an expression rather than a variable shares one viewer with the rest. The mesh is shaded facet by facet in its faces’ colours where it has them, else in its vertices’, else in grey. In the viewer C turns to its other colourings and E draws its triangle edges or hides them.

V = show (M) also returns the viewer, a model.Viewer, whose pick returns points clicked on the mesh and pickucs a coordinate system.

The viewer is built with the package when Open CASCADE and X11 are found, and needs a display to run. It runs on Linux.

See also: model.Viewer, solid.Shape.show

polymesh.Mesh: M = translate (M, V)

V is a 3-element vector in millimetres.

See also: polymesh.Mesh.rotate, polymesh.Mesh.mirror, polymesh.Mesh.scale

polymesh.Mesh: M = rotate (M, ANGLE, AXIS)

polymesh.Mesh: M = rotate (M, ANGLE, AXIS, P)

ANGLE is in degrees and turns the mesh anticlockwise when seen from the tip of AXIS looking back, the right-hand rule. AXIS is a nonzero 3-element direction, and P a point on the axis, the origin by default.

See also: polymesh.Mesh.translate, polymesh.Mesh.mirror, polymesh.Mesh.scale

polymesh.Mesh: M = mirror (M, N)

polymesh.Mesh: M = mirror (M, N, P)

The plane passes through the point P, the origin by default, with the nonzero 3-element normal N. The corners of every triangle are taken in the other order, so a triangle turned outwards stays turned outwards.

See also: polymesh.Mesh.translate, polymesh.Mesh.rotate, polymesh.Mesh.scale

polymesh.Mesh: M = scale (M, F)

polymesh.Mesh: M = scale (M, F, P)

Every length is multiplied by the positive factor F, so the volume grows by its cube. P, the origin by default, is the point that stays where it is.

See also: polymesh.Mesh.translate, polymesh.Mesh.rotate, polymesh.Mesh.mirror

polymesh.Mesh: A = area (M)

The area is the sum of the areas of the triangles. The empty mesh has area zero.

See also: polymesh.Mesh.volume

polymesh.Mesh: V = volume (M)

The mesh must be closed, as isclosed tells; an open mesh encloses nothing and is an error. The volume is the same whichever way the triangles are turned, as long as they all agree. The empty mesh has volume zero.

See also: polymesh.Mesh.isclosed, polymesh.Mesh.area

polymesh.Mesh: B = bbox (M)

polymesh.Mesh: [B, L] = bbox (M)

B is the 1-by-6 vector [xmin, ymin, zmin, xmax, ymax, zmax] in millimetres, and L the 1-by-3 vector of the lengths along each axis. Only the vertices of triangles count. The empty mesh has no extent and returns an empty B and L.

See also: solid.Shape.bbox

polymesh.Mesh: TF = isclosed (M)

A mesh is closed when every edge is shared by exactly two triangles turned opposite ways, so that the triangles agree on which side is out. Edges are told by their vertices, not by their points: two vertices at the same point are not joined. The empty mesh is closed.

See also: polymesh.Mesh.volume, solid.polyhedron

polymesh.Mesh: TF = isempty (M)

polymesh.Mesh: N = numvertices (M)

See also: polymesh.Mesh.numfaces

polymesh.Mesh: N = numfaces (M)

See also: polymesh.Mesh.numvertices