# Examples from pyvista.DataObjectFilters.cell_validator
# ======================================================

# Load a mesh with invalid cells.
import numpy as np
import pyvista as pv
from pyvista import examples
mesh = examples.download_cow()

# Validate the cells and show the included arrays.
validated = mesh.cell_validator()
validated.array_names

# There are many arrays, but most are empty. Show unique scalar values.
validity_state = validated.cell_data['validity_state']
np.unique(validity_state)

# The `0` cells are valid, and the cells with value `16` (that is, hex `0x10`) have a
# non-convex state. We confirm this by printing the `'non_convex'` array, which shows there
# are three invalid cells.
validated.field_data['non_convex']

# Check the status of cells explicitly using `CellStatus`. For checking
# if is a cell is valid, use equality `==`.
validity_state[0] == pv.CellStatus.VALID

validity_state[1013] == pv.CellStatus.VALID

# Equality can also be used for checking specific status bits, but will only be `True` if
# the cell has exactly one status bit set.
validity_state[1013] == pv.CellStatus.NON_CONVEX

# In general, checking the status with bit operators should be preferred.
(
    validity_state[1013] & pv.CellStatus.NON_CONVEX
) == pv.CellStatus.NON_CONVEX

# We can also show all invalid cells. This matches the non-convex ids, which confirms
# these are the only invalid cells.
validated.field_data['invalid']

# Plot the cell states using `color_labels()`. Orient the
# camera to show the underside of the cow where two of the invalid cells are located.
colored, color_map = validated.color_labels(
    scalars='validity_state', return_dict=True
)
pl = pv.Plotter()
_ = pl.add_mesh(colored)
_ = pl.add_legend(color_map)
pl.view_xz()
pl.camera.zoom(2.5)
pl.show()

# Extract the invalid cells and plot them along with the original mesh as wireframe for
# context. Orient the camera to focus on the cow's left eye where the third invalid cell is
# located.
invalid_cells = mesh.extract_cells(validated['invalid'])

pl = pv.Plotter()
_ = pl.add_mesh(mesh, style='wireframe', color='light gray')
_ = pl.add_mesh(invalid_cells, color='lime')
pl.camera_position = pv.CameraPosition(
    position=(5.1, 1.8, -4.9),
    focal_point=(4.7, 1.8, 0.38),
    viewup=(0.0, 1.0, 0.0),
)
pl.show()

# ----------------------------------------------------------------------
# Generated by sphinx-examples-as-code https://github.com/pyvista/sphinx-examples-as-code
