SurfaceMesh¶
Tutorial¶
For a walk-through of kaolin.rep.SurfaceMesh features,
see working_with_meshes.ipynb.
API¶
- class kaolin.rep.SurfaceMesh(vertices, faces, normals=None, uvs=None, face_uvs_idx=None, face_normals_idx=None, material_assignments=None, materials=None, vertex_normals=None, face_normals=None, face_uvs=None, face_vertices=None, strict_checks=True, unset_attributes_return_none=True, allow_auto_compute=True)¶
This container class manages data attributes (pytorch tensors) of a homogeneous surface mesh (i.e. with all faces of an equal number of vertices, such as triangle mesh), or a batch of meshes following three
Batchingstrategies.SurfaceMeshallows converting between these batching strategies, and automatically computes some attributes (such as face normals) on access (see supported attributes). This data type does not extend to volumetric tetrahedral meshes at this time and has limited support for materials.Overview
To construct a
SurfaceMeshobject, passverticesandfaces(can be 0-length) tensors and any other supported attributes; batching strategy will be automatically determined from the inputs:vertices = torch.rand((B, V, 3), dtype=torch.float32, device=device) faces = torch.randint(0, V - 1, (F, 3), dtype=torch.long) mesh = SurfaceMesh(faces, vertices)
To load a
SurfaceMeshobject:from kaolin.io import obj, usd mesh = obj.load_mesh(path) mesh2 = usd.load_mesh(path2)
Examine mesh properties:
>>> print(mesh) # Note auto-computable attributes SurfaceMesh object with batching strategy NONE vertices: [42, 3] (torch.float32)[cpu] faces: [80, 3] (torch.int64)[cpu] face_vertices: if possible, computed on access from: (faces, vertices) face_normals: if possible, computed on access from: (normals, face_normals_idx) or (vertices, faces) vertex_normals: if possible, computed on access from: (faces, face_normals) face_uvs: if possible, computed on access from: (uvs, face_uvs_idx) >>> mesh.face_normals # Causes attribute to be computed >>> print(mesh.describe_attribute("face_normals")) face_normals: [80, 3, 3] (torch.float32)[cpu]
To get a sense for what tensors the mesh can contain for different batching strategies see table below, or run:
>>> print(SurfaceMesh.attribute_info_string(SurfaceMesh.Batching.FIXED)) Expected SurfaceMesh contents for batching strategy FIXED faces: (torch.IntTensor) of shape ['F', 'FSz'] face_normals_idx: (torch.IntTensor) of shape ['B', 'F', 'FSz'] face_uvs_idx: (torch.IntTensor) of shape ['B', 'F', 'FSz'] material_assignments: (torch.IntTensor) of shape ['B', 'F'] vertices: (torch.FloatTensor) of shape ['B', 'V', 3] face_vertices: (torch.FloatTensor) of shape ['B', 'F', 'FSz', 3] normals: (torch.FloatTensor) of shape ['B', 'VN', 3] face_normals: (torch.FloatTensor) of shape ['B', 'F', 'FSz', 3] vertex_normals: (torch.FloatTensor) of shape ['B', 'V', 3] uvs: (torch.FloatTensor) of shape ['B', 'U', 2] face_uvs: (torch.FloatTensor) of shape ['B', 'F', 'FSz', 2] materials: non-tensor attribute
Note
This class is using python logging, so set up logging to get diagnostics:
import logging import sys logging.basicConfig(level=logging.INFO, stream=sys.stdout)
Supported Attributes:
SurfaceMeshsupports the following attributes, which can be provided to the constructor or set on the object. See supported batching strategies.Attribute
Batching.NONEBatching.FIXEDBatching.LISTComputable?
vertices
V x 3
B x V x 3
[V_i x 3]
N
face_vertices
F x FSz x 3
B x F x FSz x 3
[F_i x FSz_i x 3]
Y
normals
VN x 3
B x VN x 3
[VN_i x 3]
N
face_normals
F x FSz x 3
B x F x FSz x 3
[F_i x FSz_i x 3]
Y
vertex_normals
V x 3
B x V x 3
[V_i x 3]
Y
uvs
U x 2
B x U x 2
[U_i x 2]
N
face_uvs
F x FSz x 2
B x F x FSz x 2
[F_i x FSz_i x 2]
Y
faces
F x FSz
F x FSz
[F_i x FSize]
N
face_normals_idx
F x FSz
B x F x FSz
[F_i x FSz]
N
face_uvs_idx
F x FSz
B x F x FSz
[F_i x FSz]
N
material_assignments
F
B x F
[F_i]
N
materials (non-tensor)
list
list of lists
list of lists
N
Legend: B - batch size, V - number of vertices, VN - number of vertex normals, U - number of UV coordinates, F - number of faces, FSz - number of vertices per face, {?}_i - count for the ith mesh, […] - list of tensors of shapes.
Note
SurfaceMeshwill not sanity check consistency of manually set attributes.- __init__(vertices, faces, normals=None, uvs=None, face_uvs_idx=None, face_normals_idx=None, material_assignments=None, materials=None, vertex_normals=None, face_normals=None, face_uvs=None, face_vertices=None, strict_checks=True, unset_attributes_return_none=True, allow_auto_compute=True)¶
Initializes the object, while automatically detecting the batching strategy (see above for expected tensor dimensions). The
verticesandfacestensors are required, but the number of faces/vertices can be 0. Any or all of the other attributes can be also provided or set later. See table above for expected tensor dimensions for different batching strategies.- Parameters
vertices (Union[torch.FloatTensor, list]) – xyz locations of vertices.
faces (Union[torch.LongTensor, list]) – indices into
verticesarray for each vertex of each face; this is the only fixed topology item forBatching.FIXED.face_vertices (Optional[Union[torch.FloatTensor, list]]) – xyz locations for each vertex of each face; can be set directly or is auto-computable by indexing
verticeswithfaces.normals (Optional[Union[torch.FloatTensor, list]]) – xyz normal values, indexed by
face_normals_idx.face_normals (Optional[Union[torch.FloatTensor, list]]) – xyz normal values for each face; can be set directly or is auto-computable by 1) indexing
normalswithface_normals_idx, or (if either is missing and mesh is triangular) by 2) using vertex locations.vertex_normals (Optional[Union[torch.FloatTensor, list]]) – xyz normal values, corresponding to vertices; can be set directly or is auto-computable by averaging
face_normalsof faces incident to a vertex.uvs (Optional[Union[torch.FloatTensor, list]]) – uv texture coordinates, indexed by
face_uvs_idx.face_uvs (Optional[Union[torch.FloatTensor, list]]) – uv coordinate values for each vertex of each face; can be set directly or is auto-computable by indexing
uvswithface_uvs_idx.face_normals_idx (Optional[Union[torch.LongTensor, list]]) – indices into
normalsfor each vertex in each face.face_uvs_idx (Optional[Union[torch.LongTensor, list]]) – indices into
uvsfor each vertex of each face.material_assignments (Optional[Union[torch.Tensor, list]]) – indices into
materialslist for each face.materials (Optional[list]) – raw materials as output by the io reader.
strict_checks (bool) – if
True, will raise exception if any tensors passed to the construcor have unexpected shapes (see shapes matrix above); note that checks are less strict forBatching.LISTbatching (default:True).unset_attributes_return_none (bool) – if set to
Falseexception will be raised when accessing attributes that are not set (or cannot be computed), ifTruewill simply returnNone(default:True).allow_auto_compute (bool) – whether to allow auto-computation of attributes on mesh attribute access; see supported attributes (default:
True).
Supported Batching Strategies
SurfaceMeshcan be instantiated with any of the following batching strategies, and supports conversions between batching strategies. Current batching strategy of ameshobject can be read frommesh.batchingor by runningprint(mesh).For example:
mesh = kaolin.io.obj.load_mesh(path) print(mesh) mesh.to_batched() print(mesh)
- class Batching(value)¶
Batching strategies supported by the
SurfaceMesh.- Batching.FIXED = 'FIXED'¶
a batch of meshes with fixed topology (i.e. same faces array)
- Batching.LIST = 'LIST'¶
a list of meshes of any topologies
- Batching.NONE = 'NONE'¶
a single unbatched mesh
- classmethod attribute_info_string(batching)¶
Outputs information about expected mesh contents and tensor sizes, given a batching strategy. Only includes tensor and material attributes.
- Parameters
batching (SurfaceMesh.Batching) – batching strategy
- Returns
multi-line string of attributes and their shapes
- Return type
(str)
- check_sanity()¶
Checks that tensor attribute sizes are consistent for the current batching strategy. Will log any inconsistencies.
- Returns
true if sane, false if not
- Return type
(bool)
- set_batching(batching, skip_errors=False)¶
Converts a mesh to a different batching strategy. Modifies the mesh in place and returns self.
- All conversions are supported, except the following:
to NONE from FIXED or LIST batch with more than one mesh
to FIXED from LIST batch where fixed topology items are different
- Parameters
batching (SurfaceMesh.Batching) – desirable batching strategy.
skip_errors – if true, will simply unset attributes that cannot be converted (useful if e.g. vertices are of fixed topology, but meshes have variable number of normals that cannot be stacked)
- Returns
(self)
- to_batched()¶
Convenience shorthand to convert unbatched mesh to FIXED topology batched mesh. Modifies the mesh in place and returns self.
- Returns
(self)
- getattr_batched(attr, batching)¶
Same as getattr or mesh.attr, but converts the attribute value to desired batching strategy before returning.
- All conversions are supported, except the following:
to NONE from FIXED or LIST batch with more than one mesh
to FIXED from LIST batch where fixed topology items are different
- Parameters
attr (str) – attribute name
batching (SurfaceMesh.Batching) – desirable batching strategy.
- Returns
attribute value
- classmethod cat(meshes, fixed_topology=True, skip_errors=False)¶
Concatenates meshes or batches of meshes to create a FIXED (if fixed_topology) or LIST batched mesh. Only attributes present in all the meshes will be preserved.
- Parameters
meshes (Sequence[SurfaceMesh]) – meshes to concatenate; any batching is supported
fixed_topology (bool) – if to create a FIXED batched mesh (input must comply to assumptions)
skip_errors (bool) – if True, will not fail if some of the attributes fail to convert to target batching
- Returns
new mesh
- Return type
- static convert_attribute_batching(val, from_batching, to_batching, is_tensor=True, fixed_topology=False, batch_size=None)¶
Converts tensors between different
SurfaceMesh.Batchingstrategies. The input value is expected to respect the providedfrom_batching. Will fail if conversion cannot be done- Approximate summary of conversions for tensor values:
NONE->LIST: return[val]NONE->FIXED: returnval.unsqueeze(0)unless fixed_topologyLIST->NONE: returnval[0], fails if list longer than 1LIST->FIXED: returntorch.stack(val)(orval[0]if fixed_topology)FIXED->NONE: returnval.squeeze(0)unless fixed_topology, fails if list longer than 1FIXED->LIST: return[val[i, ...] for i ...](or[val for i ...]if fixed_topology)
Non-tensor values are stored as lists for
FIXEDandLISTbatching.Note
This method is only useful for converting batching of custom attributes and is not needed if only working with attributes natively supported by the
SurfaceMesh.- Parameters
val (Union[Tensor, list]) – value to convert, must be consistent with
from_batchingfrom_batching (Batching) – batching type to convert from
to_batching (Batching) – batching type to convert to
is_tensor (bool) – if the converted value is a tensor attribute (and not e.g. unstructured value to store in lists)
fixed_topology (bool) – if the attribute should be the same across items in a
FIXEDbatchingbatch_size (Optional[int]) – desirable batch size; must be consistent with
val(will be guessed in most cases, but when convertingfixed_topologyitems to e.g.LISTbatching, this value is needed)
Attribute Access
By default,
SurfaceMeshwill attempt to auto-compute missing attributes on access. These attributes will be cached, unless their ancestors haverequires_grad == True. This behavior of themeshobject can be changed at construction time (allow_auto_compute=False) or by settingmesh.allow_auto_computelater. In addition to this convenience API, explicit methods for attribute access are also supported.For example, using convenience API:
# Caching is enabled by default mesh = kaolin.io.obj.load_mesh(path, with_normals=False) print(mesh) print(mesh.has_attribute('face_normals')) # False fnorm = mesh.face_normals # Auto-computed print(mesh.has_attribute('face_normals')) # True (cached) # Caching is disabled when gradients need to flow mesh = kaolin.io.obj.load_mesh(path, with_normals=False) mesh.vertices.requires_grad = True # causes caching to be off print(mesh.has_attribute('face_normals')) # False fnorm = mesh.face_normals # Auto-computed print(mesh.has_attribute('face_normals')) # False (caching disabled)
For example, using explicit API:
mesh = kaolin.io.obj.load_mesh(path, with_normals=False) print(mesh.has_attribute('face_normals')) # False fnorm = mesh.get_or_compute_attribute('face_normals', should_cache=False) print(mesh.has_attribute('face_normals')) # False
- get_attributes(only_tensors=False)¶
Returns names of all attributes that are currently set.
- Parameters
only_tensors – if true, will only include tensor attributes
- Returns
list of string names
- Return type
(list)
- has_attribute(attr)¶
Checks if a given attribute is present without trying to compute it, if not.
- has_or_can_compute_attribute(attr)¶
Returns true if this attribute is set or has all the requirements to be computed. Note that actual computation may still fail at run time.
- probably_can_compute_attribute(attr)¶
Checks that the attributes required for computing attribute exist and returns true if the attribute is likely to be computable (not that it is not possible to determine this for sure without actually computing the attribute, as there could be runtime errors that occur during computation).
- Parameters
attr (str) – attribute name to check
- Returns
(bool) True if likely to be computable
- get_attribute(attr)¶
Gets attribute without any auto-computation magic. If attribute is not set will either return
Noneifmesh.unset_attributes_return_noneor raise an exception.- Parameters
attr (str) – attribute name, see attributes
- Returns
attribute value
- Raises
AttributeError – if attribute nate is not supported, or if attribute is not set and
not mesh.unset_attributes_return_none
- get_or_compute_attribute(attr, should_cache=None)¶
Gets or computes an attribute, while allowing explicit control of caching of the computed value. If attribute is not set and cannot be computed will either return
Noneifmesh.unset_attributes_return_noneor raise an exception.- Parameters
attr (str) – attribute name, see attributes
should_cache (Optional[bool]) – if
True, will cache attribute if it was computed; ifFalse, will not cache; by default will decide if to cache based onrequires_gradof variables used in computation (will not cache if any hasrequires_grad is True).
- Returns
attribute value
Inspecting and Copying Meshes
To make it easier to work with,
SurfaceMeshsupports detailed print statements, as well aslen(),copy(),deepcopy()and can be converted to a dictionary.Supported operations:
import copy mesh_copy = copy.copy(mesh) mesh_copy = copy.deepcopy(mesh) batch_size = len(mesh) # Print default attributes print(mesh) # Print more detailed attributes print(mesh.to_string(detailed=True, print_stats=True)) # Print specific attribute print(mesh.describe_attribute('vertices'))
- to_string(print_stats=False, detailed=False)¶
Returns information about tensor attributes currently contained in the mesh as a multi-line string.
- describe_attribute(attr, print_stats=False, detailed=False)¶
Outputs an informative string about an attribute; the same method used for all attributes in
to_string.- Args:
print_stats (bool): if to print statistics about values in each tensor detailed (bool): if to include additional information about each tensor
- Returns
multi-line string with attribute information
- Return type
(str)
- as_dict(only_tensors=False)¶
Returns currently set items as a dictionary. Does not auto-compute any items, but returns raw values.
Tensor Operations
Convenience operations for device and type conversions of some or all member tensors.
- cuda(device=None, attributes=None)¶
Calls cuda on all or only on select tensor attributes, returns a copy of self.
- Parameters
device – device to set
attributes (list of str) – if set, will only call cuda() on select attributes
- Returns
(SurfaceMesh) shallow copy, with the exception of attributes that were converted
- cpu(attributes=None)¶
Calls cpu() on all or only on select tensor attributes, returns a copy of self.
- Parameters
attributes (list of str) – if set, will only call cpu() on select attributes
- Returns
(SurfaceMesh) shallow copy, with the exception of attributes that were converted
- to(device, attributes=None)¶
Converts all or select tensor attributes to provided device; returns copy of self.
- Parameters
device (str, torch.device) – device to call torch tensors’
tomethod withattributes (list of str) – if set, will only convert select attributes
- Returns
(SurfaceMesh) shallow copy, with the exception of attributes that were converted
- float_tensors_to(float_dtype)¶
Converts all floating point tensors to the provided type; returns shallow copy.
- Parameters
float_dtype – torch dtype such as torch.float16, torch.float32
- Returns
(SurfaceMesh) shallow copy, with the exception of attributes that were converted
- detach(attributes=None)¶
Detaches all or select attributes in a shallow copy of self.
- Parameters
attributes (list of str) – if set, will only call cuda on select attributes
- Returns
(SurfaceMesh) shallow copy, with the exception of attributes that were converted
Other
- static assert_supported(attr)¶