utils package

Submodules

utils.blenderutils module

utils.blenderutils.bmesh_copy_from_object(obj, transform: bool = True, triangulate: bool = True, apply_modifiers: bool = False) BMesh

Returns a transformed, triangulated copy of the mesh

utils.blenderutils.enlarge_to_fit(surrounding_object, internal_object, rnd: ~random.Random = <random.Random object>, padding: float = 0.01)

Enlarge surrounding_object until internal_object lies entirely inside it.

utils.blenderutils.first_vert_pos_along_axis(obj, axis)

Return the position of the first vertex when sorting all verts along axis

utils.blenderutils.get_random_face(bm: BMesh, rng: Random) BMFace

Deterministic method of getting a random face.

This should work even if the face and vertex indices have changed before. Parameters: - bm (bmesh): - rng (Instance of random.Random()): Random number generator to (re-)use to get consistent behavior

Returns: A face selected from bmesh.faces. If bmesh verts and face positions are the same

and rng is in the same state, this should always be the same face.

utils.blenderutils.get_random_vert(bm: BMesh, rng: Random) BMVert

Deterministic method of getting a random vertex

This should work even if the face and vertex indices have changed before. Parameters: - bm (bmesh): - rng (Instance of random.Random()): Random number generator to (re-)use to get consistent behavior

Returns: A vertex selected from bmesh.verts. If bmesh verts and face positions are the

same and rng is in the same state, this should always be the same vertex.

utils.blenderutils.img_type_to_extension(img_type)

This attempts to return an image file extension for a blender image type. Note that only common types are supported at the moment, feel free to add more. See also: https://docs.blender.org/api/current/bpy_types_enum_items/image_type_items.html

utils.blenderutils.perturb_direction(direction: ~mathutils.Vector, min_alpha: float = 0.0, max_alpha: float = 360.0, rnd: ~random.Random = <random.Random object>) Vector

Perturbates a direction by applying a rotation over a random axis

Note: This function is not entirely fair, some directions might be chosen a bit

more often than others, due to the way the axis is chosen. However, for our purposes, it should be fine.

Parameters:
  • direction – starting force direction that has to be perturbed.

  • min_alpha – Minimum angle to perturb the direction in degrees.

  • max_alpha – Maximum angle to perturb the direction in degrees.

  • rnd – Random number generator to use

Returns:

Rotated direction

Return type:

direction

utils.blenderutils.push_outside(pushed_obj, static_obj, offset: float = 0.01, rnd: ~random.Random = <random.Random object>)

Move pushed_obj until it no longer intersects with static_obj.

utils.blenderutils.random_point_within_bounds(bm, rng: Random) Vector

Select a random position within the bmesh’s bounds

Parameters:
  • bm (-) – Bmesh

  • rng (-) – Random number generator to (re-)use to get consistent behavior

Returns:

a random position within the axis aligned bounding box of bm

Return type:

  • mathutils.Vector

utils.blenderutils.random_pos_in_vicinity(obj: ~bpy.types.Object, min_dist_from_surface: float = 0.025, max_dist_from_surface: float = 0.25, rnd: ~random.Random = <class 'random.Random'>)

Get random position close to the given object’s surface

The object may be concave. A bit of ray-tracing will be done to ensure that the position is not inside the object.

Parameters:
  • obj – bpy.types.object with mesh content!

  • min_dist_from_surface

Returns:

The random position

Return type:

mathutils.Vector

utils.blenderutils.resort_mesh(bm) BMesh

Sort mesh vertices by their positions. Makes up for non-deterministic methods.

Some functions in blender seem to be non-deterministic, likely due to parallelization. This results in our mesh vertices and faces not necessarily being in the same order each run. This function seeks to correct this, by re-creating the mesh with sorted vertices and faces.

utils.blenderutils.rotate_towards(obj: ~bpy.types.Object, target_pos: ~mathutils.Vector, forward_vec=<mathutils.Vector object>, roll_ang: float = 0)

Make the object point its forward_vec at target pos

utils.blenderutils.select_surface_path(surface_bm: ~bmesh.types.BMesh, start_node_id: int | None = None, direction: ~typing.Tuple[float, float, float] | None = None, path_length: float = 0.1, rnd: ~random.Random = <random.Random object>) List[int]

Select connected nodes along a surface.

When selecting the next node, this function always looks at previously selected nodes and tries to select the new node along the same direction. This makes the path face roughly into a single direction.

Parameters:
  • surface_bm (Bmesh) – The mesh topology

  • start_node_id (int) – The ID of the node for which neighbors are to be found. If None, a random node will be selected. Only nodes where the normal faces upwards will be considered in this case.

  • direction (tuple of 3 floats) – Direction in which the path should (roughly) go, starting at the node startNodeID. If None, a random direction will be selected.

  • path_length (float) – The algorithm will stop selecting more nodes as soon as the path is longer than pathLength. This means that it’s possible that pathLength is exceeded.

  • rnd – Random number generator to (re-)use to get consistent behavior

Returns: list of int: IDs of the vertices that form the path

utils.blenderutils.unselect_all() None

Unselect all objects in the scene.

utils.dict_utils module

utils.sofautils module

utils.sofautils.buffer_shared()

Check if two objects share the same buffer, meaning that they point to the same block of memory. An TypeError exception will be raised if either of the objects does not provide a buffer.

utils.sofautils.check_valid_displacement(displacement, low_thresh=0.0, high_thresh=nan)

Analyzes the provided displacement and tells if the displacement is associated with (1) a stable deformation (i.e., lower than high_thresh), (2) a significant deformation (i.e., higher than low_thresh).

Parameters:
  • displacement (array_like) – Nx3 array with x,y,z displacements of N points.

  • low_thresh (float) – value below which the displacement is considered negligible (default 0.0).

  • high_thresh (float) – value above which the displacement is associated to unstable deformation (default NaN).

Returns:

  • is_stable = False if there is at least one displacement whose norm is >= high_thresh or there is at least one displacement with NaN value

  • is_moving = False if there is at least one displacement whose norm is <= low_thresh

Return type:

is_stable, is_moving

utils.sofautils.convert2rigid(positions, quaternions=[0, 0, 0, 1])

Converts an Nx3 list of coordinates, that describe 3D coordinates of a SOFA object templated as Vec3d template into the corresponding Nx7 (position+quaternion) format, needed for SOFA Rigid template. Orientation (as quaternion) associated to each point can also be provided. If a single quaternion is provided, the same value is associated to all the points.

Parameters:
  • (list) (quaternions) – N x 3 list of coordinates.

  • (list) – 1 x 7 or N x 7 list of quaternions associated to the points.

Returns:

N x 7 list of coordinates concatenated with the corresponding quaternion, for compatibility with Rigid template.

Return type:

list

utils.sofautils.get_bbox(position)

Gets the bounding box of the object defined by the given vertices.

Parameters:

position (list) – List with the coordinates of N points (position field of Sofa MechanicalObject).

Returns:

xmin, xmax, ymin, ymax, zmin, zmax – min and max coordinates of the object bounding box.

Return type:

floats

utils.sofautils.get_distance_np(array1, array2)

For each point in array2, returns the Euclidean distance with its closest point in array1 and the index of such closest point.

Parameters:
  • (ndarray) (array2) – N1 x M array with the points.

  • (ndarray) – N2 x M array with the points.

Returns:

  • dist – N2 x 1 Euclidean distance of each point of array2 with the closest point in array1. dist contains the same result as: np.nanmin( distance.cdist( array1, array2 ), axis=1 )

  • indexes – N2 x 1 Indices of closest point in array1

utils.sofautils.get_indices_in_roi(positions: list, center: ndarray | None = None, radius: float | None = 0.01, bbox: list | None = None) list

Get the indices of the points falling within the specified bounding box.

Parameters:
  • positions – N x 3 list of points coordinates.

  • center

  • radius

bbox: [xmin, ymin, zmin, xmax, ymax, zmax] extremes of the bounding box.

Returns: indices: List of indices of points enclosed in the bbox.

utils.sofautils.sofa2vtk(state, topology)

Converts a sofa object to a vtkPolyData.

Parameters:
  • () (state) – SOFA mechanical object

  • (?) (topology) – SOFA object containing information about triangles (either topology or a loader)

utils.sofautils.sofa2vtu(state, vtk_mesh)

Converts a sofa object to a vtkUnstructuredGrid.

Parameters:
  • () (state) – SOFA mechanical object

  • (?) (topology) – SOFA object containing information about triangles (either topology or a loader)

utils.vtkutils module

class utils.vtkutils.ErrorObserver

Bases: object

Class that can catch vtk errors.

To use, instanciate and use vtk’s “.AddObserver()” methods. Then, after running the vtk filter, use ErrorObserver.ErrorOccured to check if something went wrong. In this case, ErrorObserver.ErrorMessage() can be used to retrieve the error message.

utils.vtkutils.apply_transform(mesh: vtkDataSet, vtk_transform: vtkTransform) vtkDataSet

Applies the given transform to the input mesh and returns the result.

Parameters:

mesh – The input vtkDataSet object.

Returns:

Transformed vtkDataSet.

utils.vtkutils.buffer_shared()

Check if two objects share the same buffer, meaning that they point to the same block of memory. An TypeError exception will be raised if either of the objects does not provide a buffer.

utils.vtkutils.calc_array_stats(arr: vtkDataArray) tuple

Given a vtkDataArray with N components per tuple, this function calculates the length of each tuple and then the min, max and mean over all of these lengths.

Parameters:

arr – A vtkDataArray with…

Returns:

minimum, maximum, mean

utils.vtkutils.calc_center_transform(mesh: vtkDataSet) vtkTransform

Calculates a transform that would center mesh’s bounding box around the origin.

Parameters:

mesh – Mesh for which to caculate the center

Returns:

The transform that would translate ‘mesh’ so that its bounding box is centered around the origin.

Return type:

vtkTransform

utils.vtkutils.calc_displacement(mesh_initial: vtkDataSet, mesh_deformed: vtkDataSet, mesh_initial_indices: list | None = None) vtkFloatArray

Given an initial and deformed mesh, computes the displacement for each point from the initial mesh to the deformed mesh.

Important: The function assumes that the ith point in mesh_initial corresponds to the ith point in the deformed mesh (and that the meshes have the same number of points).

Parameters:
  • mesh_initial – The starting vtkDataSet object.

  • mesh_deformed – The corresponding deformed vtkDataSet object.

  • mesh_initial_indices – For each point of mesh_deformed, the index of the corresponding point in mesh_initial. If None, mesh_initial and mesh_deformed must have the same number of points.

Returns:

Displacement array.

utils.vtkutils.calc_geodesic_distance(mesh: vtkDataSet, node_id: int) vtkDoubleArray

Computes the geodesic distance of each point in the input mesh with respect to the point with index node_id.

Parameters:
  • mesh – The vtkDataSet object.

  • node_id – The ID of the node for which neighbors are to be found.

Returns:

A vtkDoubleArray named “geodesic_distance” containing the geodesic distance of each point in the mesh to the point node_id.

utils.vtkutils.calc_mean_position(mesh: vtkDataSet) float

Computes the centroid of the input object.

Parameters:

mesh – A vtkDataSet object.

Returns:

3D coordinates of the object centroid.

utils.vtkutils.calc_mesh_size(mesh: ~vtkmodules.vtkCommonDataModel.vtkDataSet) -> (<class 'float'>, <class 'float'>, <class 'float'>)

Calculate the dimensions of the mesh’s bounding box by evaluating xmax-xmin etc.

Parameters:

mesh – A vtkDataSet object.

Returns:

The dimensions of the bounding box of the mesh.

Return type:

size_x, size_y, size_z

utils.vtkutils.calc_surface_area(mesh: vtkDataSet) float

Computes the surface area of the input mesh and adds it to the mesh as a single entry field data float array “surfaceArea”.

The surface area is computed by summing up the areas of all the triangular elements of the mesh, done by vtk internally.

Parameters:

mesh – A vtkDataSet object.

Returns:

The computed surface area.

utils.vtkutils.calc_volume(mesh: vtkUnstructuredGrid) float

Computes the volume of the input mesh using the vtkIntegrateAttributes filter.

The volume is computed by summing up the volumes of all 3D elements of the mesh.

Parameters:

mesh – A vtkDataSet object, restricted to data types with volumetric cells because otherwise the filter will compute the surface area or line length unsolicited.

Returns:

The computed volume.

utils.vtkutils.copy_arrays(input_geometry: vtkDataSet, source: vtkDataSet, copy_point_data: bool = True, copy_cell_data: bool = True) vtkDataSet

Copy arrays from source onto input_geometry.

Note: This performs a shallow copy only. Note: If an array with the same name already exists, this will be overwritten.

Returns:

‘input_geometry’, but with the arrays from ‘source’.

utils.vtkutils.create_random_rigid_transform(max_rotation: float, max_translation: float, rot_center: tuple | None = None, rnd: Random | None = None) vtkTransform

Creates a random rigid transformation parametrized on the provided input values.

Optionally, a rotation center point can be given. Also optionally, a (seeded) random number generator can be given.

Parameters:
  • max_rotation – Maximum rotation angle allowed, in degrees.

  • max_translation – Maximum random translation along each axis.

  • rot_center – 3D coordinates of the position around which the rotation will be created.

  • rnd – Instance of random.Random() that will be used to sample all random values (for deterministic output).

Returns:

vtkTransform

utils.vtkutils.extract_surface(mesh: vtkDataSet) vtkPolyData

Given an input mesh, extracts its outer surface. Converts an input unstructured grid into a polydata object. Be careful since PolyData objects cannot contain 3D elements, thus all tetrahedra will be lost with this operation. vtkGeometryFilter is used because it is faster and delegates to vtkDataSetSurfaceFilter if it cannot handle a mesh (see issue #83). Replaces vtkutils.unstructuredGridToPolyData().

Parameters:

mesh – The vtkDataSet where we want to retain the external surface only.

Returns:

The input grid converted into a polydata.

Return type:

A vtkDataSet with surface elements only

utils.vtkutils.find_corresponding_indices(mesh: vtkDataSet, points: ndarray) list

For each point in the points array, returns the index of the closest point in the input mesh.

Parameters:
  • mesh1 – The input vtkDataSet.

  • points – Nx3 array of points.

Returns:

A list of int with the ids of mesh vertices closest to each point.

utils.vtkutils.generate_point_normals(mesh: vtkPolyData) vtkPolyData

Generates point normals for the input mesh.

Parameters:
  • mesh – A vtkPolyData object. Please be aware that the input must be a polydata in order

  • normals. (to calculate point) –

Returns:

The same vtkPolyData provided as input, with the additional “Normals” array.

utils.vtkutils.get_connected_vertices(mesh: vtkDataSet, node_id: int) list

Find the neighbor vertices of the node node_id in the provided mesh.

Parameters:
  • mesh – The vtkDataSet object.

  • node_id – The ID of the node for which neighbors are to be found.

Returns:

The IDs of the vertices that are neighbors of node_id.

utils.vtkutils.has_tetra(mesh: vtkDataSet) bool

Checks if input mesh has tetrahedral elements.

Parameters:

mesh – a vtkDataSet object.

Returns:

True if the provided object contains tetrahedral elements, False otherwise.

utils.vtkutils.make_single_float_array(value: float, name: str = 'array') vtkFloatArray

Converts a float into a vtkFloatArray.

Parameters:
  • value – Value associated to the array.

  • name – Name that will be associated to the created vtk array.

Returns:

A vtkFloatArray filled with the specified value and with the specified name.

utils.vtkutils.polyDataToUnstructuredGrid(pd: vtkPolyData) vtkUnstructuredGrid

Converts an input polydata into an unstructured grid.

Parameters:

pd – The input polydata

Returns:

The input polydata converted into an unstructured grid.

utils.vtkutils.remap_arrays(input_geometry: vtkDataSet, source: vtkDataSet, sharpness: float = 1000.0) vtkDataSet

Remap arrays from source onto input_geometry.

Returns:

A dataset of the same type as ‘input_geometry’, but with the arrays from ‘source’ interpolated onto it.

utils.vtkutils.transform_from_str(s: str) vtkTransform

Converts the input string into a vtkMatrix.

Parameters:
  • s – A string containing exactly 16 values, separated by spaces (as output by

  • transform_to_str)

Returns:

A vtkTransform where the matrix has been constructed from the given 16 values.

utils.vtkutils.transform_to_str(tf: vtkTransform) str

Converts the input vtkTransform into a string.

Parameters:

tf – The input vtkTransform.

Returns:

String version of the input transform.

utils.vtkutils.vtk2numpy(mesh: vtkDataSet) ndarray

Converts the points in a vtkDataSet into a numpy array.

Parameters:

mesh – A vtkDataSet object.

Returns:

Numpy array with the coordinates of the mesh points.

Module contents