lacecore

class lacecore.Mesh(v, f, copy_v=False, copy_f=False, face_groups=None)

A triangular or quad mesh. Vertices and faces are represented using NumPy arrays. Instances are read-only, at least for now. This class is optimized for cloud computation.

Parameters:
  • v (np.ndarray) – A kx3 array of vertices. It will be marked read-only.

  • f (np.ndarray) – A kx3 or kx4 array of vertex indices which make up the faces. It will be marked read-only.

  • copy_v (bool) – When True, the input vertices will be copied before they are marked read-only.

  • copy_f (bool) – When True, the input faces will be copied before they are marked read-only.

apex(along)

Find the most extreme vertex in the direction provided.

Parameters:

along (np.arraylike) – A (3,) direction of interest.

Returns:

A copy of the point in self.v which lies furthest

in the direction of interest.

Return type:

np.ndarray

property bounding_box

A bounding box around the vertices.

Returns:

The bounding box.

Return type:

polliwog.Box

face_normals(normalize=True)

Compute surface normals of each face. The direction of the normal follows conventional counter-clockwise winding and the right-hand rule.

Parameters:

normalize (bool) – When True, return unit-length normals.

Returns:

Face normals as (k, 3).

Return type:

np.ndarray

faces_flipped()

Flip the orientation of the faces.

Returns:

A mesh with transformed faces.

Return type:

lacecore.Mesh

faces_triangulated()

Triangulate the mesh’s quad faces to triangles. Raise an error if the mesh is already triangulated.

Returns:

A mesh with transformed vertices.

Return type:

lacecore.Mesh

flipped(dim, preserve_vertex_centroid=False)

Flip about the given axis.

Parameters:
  • dim (int) – The axis to flip around: 0 for x, 1 for y, 2 for z.

  • preserve_vertex_centroid (bool) – When True, translate after flipping to preserve the original vertex centroid.

Returns:

A mesh with transformed vertices.

Return type:

lacecore.Mesh

property is_quad

True if a triangular mesh.

Returns:

True if a triangular mesh.

Return type:

bool

property is_tri

True if a triangular mesh.

Returns:

True if a triangular mesh.

Return type:

bool

keeping_vertices_above(dim, point)

Select vertices which, when projected to the given axis, lie further along that axis than the projection of the given point.

Return a new mesh, without mutating the callee.

Parameters:
  • dim (int) – The axis of interest: 0 for x, 1 for y, 2 for z.

  • point (np.arraylike) – The point of interest.

Returns:

A submesh containing the selection.

Return type:

lacecore.Mesh

keeping_vertices_at_or_above(dim, point)

Select vertices which, when projected to the given axis, are either coincident with the projection of the given point, or lie further along the axis.

Return a new mesh, without mutating the callee.

Parameters:
  • dim (int) – The axis of interest: 0 for x, 1 for y, 2 for z.

  • point (np.arraylike) – The point of interest.

Returns:

A submesh containing the selection.

Return type:

lacecore.Mesh

keeping_vertices_at_or_below(dim, point)

Select vertices which, when projected to the given axis, are either coincident with the projection of the given point, or lie before it.

Return a new mesh, without mutating the callee.

Parameters:
  • dim (int) – The axis of interest: 0 for x, 1 for y, 2 for z.

  • point (np.arraylike) – The point of interest.

Returns:

A submesh containing the selection.

Return type:

lacecore.Mesh

keeping_vertices_behind_plane(plane)

Select the vertices which are behind the given plane.

Return a new mesh, without mutating the callee.

Parameters:

plane (polliwog.Plane) – The plane of interest.

Returns:

A submesh containing the selection.

Return type:

lacecore.Mesh

keeping_vertices_below(dim, point)

Select vertices which, when projected to the given axis, lie before the projection of the given point.

Return a new mesh, without mutating the callee.

Parameters:
  • dim (int) – The axis of interest: 0 for x, 1 for y, 2 for z.

  • point (np.arraylike) – The point of interest.

Returns:

A submesh containing the selection.

Return type:

lacecore.Mesh

keeping_vertices_in_front_of_plane(plane)

Select the vertices which are in front of the given plane.

Return a new mesh, without mutating the callee.

Parameters:

plane (polliwog.Plane) – The plane of interest.

Returns:

A submesh containing the selection.

Return type:

lacecore.Mesh

keeping_vertices_on_or_behind_plane(plane)

Select the vertices which are either on or behind the given plane.

Return a new mesh, without mutating the callee.

Parameters:

plane (polliwog.Plane) – The plane of interest.

Returns:

A submesh containing the selection.

Return type:

lacecore.Mesh

keeping_vertices_on_or_in_front_of_plane(plane)

Select the vertices which are either on or in front of the given plane.

Return a new mesh, without mutating the callee.

Parameters:

plane (polliwog.Plane) – The plane of interest.

Returns:

A submesh containing the selection.

Return type:

lacecore.Mesh

non_uniformly_scaled(x_factor, y_factor, z_factor)

Scale along each axis by the given factors.

Parameters:
  • x_factor (flot) – The scale factor along the x axis.

  • y_factor (flot) – The scale factor along the y axis.

  • z_factor (flot) – The scale factor along the z axis.

Returns:

A mesh with transformed vertices.

Return type:

lacecore.Mesh

property num_f

The number of faces.

Returns:

The number of faces.

Return type:

int

property num_v

The number of vertices.

Returns:

The number of vertices.

Return type:

int

picking_face_groups(*group_names)

Select faces which belong to the given face groups.

Parameters:

group_names (list) – The face groups to keep.

Returns:

A submesh containing the selection.

Return type:

lacecore.Mesh

picking_faces(indices_or_boolean_mask)

Select only the given faces.

Return a new mesh, without mutating the callee.

Parameters:

indices_or_boolean_mask (np.arraylike) – Either a list of vertex indices, or a boolean mask the same length as the vertex array.

Returns:

A submesh containing the selection.

Return type:

lacecore.Mesh

picking_vertices(indices_or_boolean_mask)

Select only the given vertices.

Return a new mesh, without mutating the callee.

Parameters:

indices_or_boolean_mask (np.arraylike) – Either a list of vertex indices, or a boolean mask the same length as the vertex array.

Returns:

A submesh containing the selection.

Return type:

lacecore.Mesh

reoriented(up, look)

Reorient using up and look.

Returns:

A mesh with transformed vertices.

Return type:

lacecore.Mesh

rotated(rotation)

Rotate by the given 3x3 rotation matrix or a Rodrigues vector.

Returns:

A mesh with transformed vertices.

Return type:

lacecore.Mesh

select()

Begin a chained selection operation. After invoking .select(), apply selection criteria, then invoke .end() to create a submesh.

Include .union() in the chain to combine multiple sets of selection criteria into a single submesh.

Does not mutate the callee.

Returns:

The selection operation.

Return type:

lacecore.Selection

Example

>>> centroid = np.average(mesh.v, axis=0)
>>> upper_right_quadrant = (
    mesh.select()
    .vertices_above(centroid, dim=0)
    .vertices_above(centroid, dim=1)
    .end()
)
>>> upper_half_plus_right_half = (
    mesh.select()
    .vertices_above(centroid, dim=0)
    .union()
    .vertices_above(centroid, dim=1)
    .end()
)
sliced_by_plane(*planes, only_for_selection=None)

Slice the triangles, keeping the portion in front of the given plane.

  • Faces partially in front of the plane are sliced.

  • Faces fully in front of the plane are kept as is.

  • Faces fully behind the plane are culled.

Return a new mesh, without mutating the callee.

Parameters:
  • plane (polliwog.Plane) – The plane of interest.

  • only_for_selection (function) – A function which receives a lacecore.Selection and should invoke selection methods on it.

Returns:

The sliced mesh.

Return type:

lacecore.Mesh

transform()

Begin a composite transform operation. After invoking .transform(), apply transformations, then invoke .end() to create a mesh with transformed vertices.

Does not mutate the callee.

Returns:

The transform operation.

Return type:

lacecore.Transform

Example

>>> transformed = (
    mesh.transform()
    .translate(3.0 * vg.basis.x)
    .uniform_scale(3.0)
    .end()
)
translated(translation)

Translate by the vector provided.

Parameters:

vector (np.arraylike) – A 3x1 vector.

Returns:

A mesh with transformed vertices.

Return type:

lacecore.Mesh

uniformly_scaled(factor)

Scale by the given factor.

Parameters:

factor (float) – The scale factor.

Returns:

A mesh with transformed vertices.

Return type:

lacecore.Mesh

units_converted(from_units, to_units)

Convert the mesh from one set of units to another.

Support the length units from Ounce: https://github.com/lace/ounce/blob/master/ounce/core.py#L26

Returns:

A mesh with transformed vertices.

Return type:

lacecore.Mesh

property vertex_centroid

The centroid or geometric average of the vertices.

write_obj(filename)

Save a mesh’s faces, vertices, and face groups to a Wavefront OBJ file.

Parameters:

filename (str) – The file to write. If it exists, it will be overwritten.

Selection operations

class lacecore.Selection(target, union_with=[])

Encapsulate a chained submesh selection operation.

Invoke .end() to apply the selection operation and create a submesh. By default, orphaned vertices are pruned. However you can keep them by invoking .end(prune_orphan_vertices=True).

Include .union() in the chain to combine more than one set of selection criteria into a single submesh.

Parameters:
  • target (lacecore.Mesh) – The mesh on which to operate.

  • union_with (lacecore.Selection) – The operation with which the new instance should combine itself. Normally this is reserved for internal use.

end(prune_orphan_vertices=True, ret_indices_of_original_faces_and_vertices=False)

Apply the selection to construct a submesh.

Parameters:
  • prune_orphan_vertices (bool) – When True, remove vertices which are referenced only by faces which are being removed.

  • ret_indices_of_original_faces_and_vertices – When True, also return the indices of the original faces and vertices.

Returns:

Either the submesh as an instance of lacecore.Mesh, or a tuple

(submesh, indices_of_original_faces, indices_of_original_vertices). The index arrays contain the new indices of the original vertices, and -1 for each removed face and vertex.

Return type:

object

generate_masks(prune_orphan_vertices=True)

Apply the selection to generate vertex and face masks.

Parameters:

prune_orphan_vertices (bool) – When True, remove vertices which are referenced only by faces which are being removed.

Returns:

(face_mask, vertex_mask). The index arrays contain the new

indices of the original vertices, and -1 for each removed face and vertex.

Return type:

tuple

pick_face_groups(*group_names)

Select faces which belong to the given face groups.

Parameters:

group_names (list) – The face groups to keep.

Returns:

self

pick_faces(indices_or_boolean_mask)

Select only the given faces.

Parameters:

indices_or_boolean_mask (np.arraylike) – Either a list of face indices, or a boolean mask the same length as the face array.

Returns:

self

pick_vertices(indices_or_boolean_mask)

Select only the given vertices.

Parameters:

indices_or_boolean_mask (np.arraylike) – Either a list of vertex indices, or a boolean mask the same length as the vertex array.

Returns:

self

pick_vertices_of_face_groups(*group_names)

Select vertices which belong to any of the given face groups.

Parameters:

group_names (list) – The face groups to keep.

Returns:

self

union()

Chain on a new selection object. This works like a boolean “or” to combine two sets of submesh operations.

Parameters:

indices_or_boolean_mask (np.arraylike) – Either a list of face indices, or a boolean mask the same length as the face array.

Returns:

The new selection operation, which will

combine itself with self.

Return type:

lacecore.Selection

Example

>>> upper_half_plus_right_half = (
    mesh.select()
    .vertices_above(centroid, dim=0)
    .union()
    .vertices_above(centroid, dim=1)
    .end()
)
vertices_above(dim, point)

Select vertices which, when projected to the given axis, lie further along that axis than the projection of the given point.

Parameters:
  • dim (int) – The axis of interest: 0 for x, 1 for y, 2 for z.

  • point (np.arraylike) – The point of interest.

Returns:

self

vertices_at_or_above(dim, point)

Select vertices which, when projected to the given axis, are either coincident with the projection of the given point, or lie further along the axis.

Parameters:
  • dim (int) – The axis of interest: 0 for x, 1 for y, 2 for z.

  • point (np.arraylike) – The point of interest.

Returns:

self

vertices_at_or_below(dim, point)

Select vertices which, when projected to the given axis, are either coincident with the projection of the given point, or lie before it.

Parameters:
  • dim (int) – The axis of interest: 0 for x, 1 for y, 2 for z.

  • point (np.arraylike) – The point of interest.

Returns:

self

vertices_behind_plane(plane)

Select the vertices which are behind the given plane.

Parameters:

plane (polliwog.Plane) – The plane of interest.

Returns:

self

vertices_below(dim, point)

Select vertices which, when projected to the given axis, lie before the projection of the given point.

Parameters:
  • dim (int) – The axis of interest: 0 for x, 1 for y, 2 for z.

  • point (np.arraylike) – The point of interest.

Returns:

self

vertices_in_front_of_plane(plane)

Select the vertices which are in front of the given plane.

Parameters:

plane (polliwog.Plane) – The plane of interest.

Returns:

self

vertices_on_or_behind_plane(plane)

Select the vertices which are either on or behind the given plane.

Parameters:

plane (polliwog.Plane) – The plane of interest.

Returns:

self

vertices_on_or_in_front_of_plane(plane)

Select the vertices which are either on or in front of the given plane.

Parameters:

plane (polliwog.Plane) – The plane of interest.

Returns:

self

Groups

class lacecore.GroupMap(num_elements, group_names, masks, copy_masks=False)

An immutable map of groups of elements, which are allowed to overlap. These can be used for face or vertex groups, as in the Wavefront OBJ standard.

Parameters:
  • num_elements (int) – The total number of elements. This determines the length of the masks.

  • group_names (list) – The names of the groups.

  • masks (np.array) – A boolean array with a row containing a boolean mask for each group.

__getitem__(group_name)

Get the read-only mask for the requested group.

Parameters:

group_name (string) – The desired group.

Returns:

A read-only boolean array with length equal to self.num_elements.

Return type:

np.array

__iter__()

Iterate over the groups.

Returns:

An iterator over the groups.

Return type:

list_iterator

__len__()

Get the number of groups.

Returns:

The number of groups.

Return type:

int

defragment(group_order=None)

Reorder the faces to keep groups together.

Overlapping groups are not supported.

Parameters:

group_order (list) – The desired order of the groups. The default is to order by the first face in which the group appears.

Returns:

The new order of the faces, suitable for passing to lacecore.reindex_faces().

Return type:

np.ndarray

classmethod from_dict(group_data, num_elements)

Create a group map from a dictionary of elements. The keys are the group names and the values are lists of element indices.

Parameters:
  • group_data (dict) – The group data.

  • num_elements (int) – The total number of elements.

group_names_for_element_mask(element_mask)

Translate an element mask to a list of group names.

Parameters:

element_mask (np.array) – An element mask (e.g. a return value from mask_for_element()).

Returns:

The group membership represented by the element mask.

Return type:

list

keys()

Get the names of all the groups.

Returns:

A list of the group names.

Return type:

list

mask_for_element(element)

Get the read-only group mask for the requested element.

Parameters:

element (int) – The desired element.

Returns:

A read-only boolean array corresponding to the

group names in self.keys().

Return type:

np.array

reindexed(f_new_to_old)

Given a mapping from new face indices to old face indices, construct a group map which preserves the original groups but references the new set of indices. When reindexing a mesh, invoke this function on the old group map to construct a new group map which preserves the original segments wherever possible.

Parameters:

f_new_to_old (np.ndarray) – The old face index corresponding to each of the new faces.

Returns:

A new group map suitable for use with the new faces.

Return type:

GroupMap

union(*group_names)

Construct the union of the requested groups and return it as a writable mask.

Parameters:

group_names (list) – The requested groups.

Returns:

A boolean mask with length equal to self.num_elements.

Return type:

np.array

Tesselated shapes

Functions for creating meshes for tesselated 3D shapes.

lacecore.shapes.cube(origin, size)

Tesselate an axis-aligned cube. One vertex is origin. The diametrically opposite vertex is size units along +x, +y, and +z.

Parameters:
  • origin (np.ndarray) – A 3D point vector containing the point on the prism with the minimum x, y, and z coords.

  • size (float) – The length, width, and height of the cube, which should be positive.

Returns:

A Mesh instance containing the cube.

Return type:

lacecore.Mesh

lacecore.shapes.rectangular_prism(origin, size)

Tesselate an axis-aligned rectangular prism. One vertex is origin. The diametrically opposite vertex is origin + size.

Parameters:
  • origin (np.ndarray) – A 3D point vector containing the point on the prism with the minimum x, y, and z coords.

  • size (np.ndarray) – A 3D vector specifying the prism’s length, width, and height, which should be positive.

Returns:

A Mesh instance containing the rectangular prism.

Return type:

lacecore.Mesh

lacecore.shapes.triangular_prism(p1, p2, p3, height)

Tesselate a triangular prism whose base is the triangle p1, p2, p3. If the vertices are oriented in a counterclockwise direction, the prism extends from behind them.

Parameters:
  • p1 (np.ndarray) – A 3D point on the base of the prism.

  • p2 (np.ndarray) – A 3D point on the base of the prism.

  • p3 (np.ndarray) – A 3D point on the base of the prism.

  • height (float) – The height of the prism, which should be positive.

Returns:

A Mesh instance containing the triangular prism.

Return type:

lacecore.Mesh

Indices and tables