pyvista.PolyDataFilters.collision

pyvista.PolyDataFilters.collision#

PolyDataFilters.collision(
other_mesh,
contact_mode=0,
box_tolerance=0.001,
cell_tolerance=0.0,
n_cells_per_node=2,
generate_scalars: bool = False,
progress_bar: bool = False,
)[source]#

Perform collision determination between two polyhedral surfaces.

If collision_mode is set to all contacts, the output will be lines of contact. If collision_mode is first contact or half contacts then the Contacts output will be vertices.

Warning

Currently only triangles are processed. Use PolyDataFilters.triangulate() to convert any strips or polygons to triangles. Otherwise, the mesh will be converted for you within this method.

Parameters:
other_meshpyvista.DataSet

Other mesh to test collision with. If the other mesh is not a surface, its external surface will be extracted and triangulated.

contact_modeint, default: 0

Contact mode. One of the following:

  • 0 - All contacts. Find all the contacting cell pairs with two points per collision

  • 1 - First contact. Quickly find the first contact point.

  • 2 - Half contacts. Find all the contacting cell pairs with one point per collision.

box_tolerancefloat, default: 0.001

Oriented bounding box (OBB) tree tolerance in world coordinates.

cell_tolerancefloat, default: 0.0

Cell tolerance (squared value).

n_cells_per_nodeint, default: 2

Number of cells in each OBB.

generate_scalarsbool, default: False

Flag to visualize the contact cells. If True, the contacting cells will be colored from red through blue, with collisions first determined colored red. This array is stored as "collision_rgba".

Note

This will remove any other cell arrays in the mesh.

progress_barbool, default: False

Display a progress bar to indicate progress.

Returns:
pyvista.PolyData

Mesh containing collisions in the field_data attribute named "ContactCells". Array only exists when there are collisions.

int

Number of collisions.

Notes

Due to the nature of the vtk.vtkCollisionDetectionFilter, repeated uses of this method will be slower that using the vtk.vtkCollisionDetectionFilter directly. The first update of the filter creates two instances of vtkOBBTree, which can be subsequently updated by modifying the transform or matrix of the input meshes.

This method assumes no transform and is easier to use for single collision tests, but it is recommended to use a combination of pyvista and vtk for rapidly computing repeated collisions. See the Collision Detection Example

Examples

Compute the collision between a sphere and the back faces of a cube and output the cell indices of the first 10 collisions.

>>> import numpy as np
>>> import pyvista as pv
>>> mesh_a = pv.Sphere(radius=0.5)
>>> mesh_b = pv.Cube((0.5, 0.5, 0.5)).extract_cells([0, 2, 4])
>>> collision, ncol = mesh_a.collision(mesh_b, cell_tolerance=1)
>>> collision['ContactCells'][:10]
pyvista_ndarray([464,   0,   0,  29,  29,  27,  27,  28,  28,  23])

Plot the collisions by creating a collision mask with the "ContactCells" field data. Cells with a collision are colored red.

>>> scalars = np.zeros(collision.n_cells, dtype=bool)
>>> scalars[collision.field_data['ContactCells']] = True
>>> pl = pv.Plotter()
>>> _ = pl.add_mesh(
...     collision,
...     scalars=scalars,
...     show_scalar_bar=False,
...     cmap='bwr',
... )
>>> _ = pl.add_mesh(
...     mesh_b,
...     color='lightblue',
...     line_width=5,
...     opacity=0.7,
...     show_edges=True,
... )
>>> pl.show()
../../../_images/pyvista-PolyDataFilters-collision-1_00_00.png

Alternatively, simply plot the collisions using the default 'collision_rgba' array after enabling generate_scalars.

>>> collision, ncol = mesh_a.collision(
...     mesh_b, cell_tolerance=1, generate_scalars=True
... )
>>> collision.plot()
../../../_images/pyvista-PolyDataFilters-collision-1_01_00.png

See Collision for more examples using this filter.