Source code for paraview.detail.python_selector

"""This module is used by vtkPythonSelector to perform query-based
selections. It relies on the python-calculator (vtkPythonCalculator),
specifically, the Python code used by that class, to compute a mask array from
the query expression. Once the mask array is obtained, this module will
mark those elements as requested.
"""
from __future__ import absolute_import, print_function

try:
    import numpy as np
except ImportError:
    raise RuntimeError("'numpy' module is not found. numpy is needed for " \
                       "this functionality to work. Please install numpy and try again.")

import re
import vtkmodules.numpy_interface.dataset_adapter as dsa
import vtkmodules.numpy_interface.algorithms as algos
from vtkmodules.vtkCommonDataModel import vtkDataObject
from vtkmodules.util import vtkConstants
from . import calculator

# import wrapping module for `vtkPythonSelector`
from paraview.modules import vtkPVVTKExtensionsExtractionPython

import sys

if sys.hexversion < 0x03000000:
    import itertools

    izip = itertools.izip
else:
    izip = zip


def _create_id_array(dataobject, attributeType):
    """Returns a VTKArray or VTKCompositeDataArray for the ids"""
    if not dataobject:
        raise RuntimeError("dataobject cannot be None")
    if dataobject.IsA("vtkCompositeDataSet"):
        ids = []
        for ds in dataobject:
            ids.append(_create_id_array(ds, attributeType))
        return dsa.VTKCompositeDataArray(ids)
    else:
        numElems = dataobject.GetNumberOfElements(attributeType)
        return dsa.VTKArray(np.arange(numElems)) if numElems > 0 else dsa.NoneArray


[docs]def maskarray_is_valid(maskArray): """Validates that the maskArray is either a VTKArray, VTKCompositeDataArray, ndarray or a NoneArray other returns false.""" return maskArray is dsa.NoneArray or \ isinstance(maskArray, dsa.VTKArray) or \ isinstance(maskArray, dsa.VTKCompositeDataArray) or \ isinstance(maskArray, np.ndarray)
[docs]def execute(inputDO, selectionNode, insidednessArrayName, outputDO): field_type = selectionNode.GetFieldType() if field_type == selectionNode.CELL: attributeType = vtkDataObject.CELL elif field_type == selectionNode.POINT: attributeType = vtkDataObject.POINT elif field_type == selectionNode.ROW: attributeType = vtkDataObject.ROW else: raise RuntimeError("Unsupported field attributeType %r" % field_type) # Evaluate expression on the inputDO. # This is equivalent to executing the Python Calculator on the input dataset # to produce a mask array. inputs = [] inputs.append(dsa.WrapDataObject(inputDO)) query = selectionNode.GetQueryString() # Get a dictionary for arrays in the dataset attributes. We pass that # as the variables in the eval namespace for calculator.compute(). elocals = calculator.get_arrays(inputs[0].GetAttributes(attributeType)) if ("id" not in elocals) and re.search(r'\bid\b', query): # Add "id" array if the query string refers to id. # This is a temporary fix. We should look into # accelerating id-based selections in the future. elocals["id"] = _create_id_array(inputs[0], attributeType) try: maskArray = calculator.compute(inputs, query, ns=elocals) except: from sys import stderr print("Error: Failed to evaluate Expression '%s'. " \ "The following exception stack should provide additional developer " \ "specific information. This typically implies a malformed " \ "expression. Verify that the expression is valid.\n" % query, file=stderr) raise if not maskarray_is_valid(maskArray): raise RuntimeError( "Expression '%s' did not produce a valid mask array. The value " \ "produced is of the type '%s'. This typically implies a malformed " \ "expression. Verify that the expression is valid." % \ (query, type(maskArray))) # Preserve topology. Just add the mask array as vtkSignedCharArray to the # output. # Note: we must force the data type to VTK_SIGNED_CHAR or the array will # be ignored by the freeze selection operation from paraview.vtk.util import numpy_support output = dsa.WrapDataObject(outputDO) if maskArray is not dsa.NoneArray: if isinstance(maskArray, dsa.VTKCompositeDataArray): for ds, array in izip(output, maskArray.Arrays): if array is not dsa.NoneArray: insidedness = numpy_support.numpy_to_vtk(array, deep=1, array_type=vtkConstants.VTK_SIGNED_CHAR) insidedness.SetName(insidednessArrayName) ds.GetAttributes(attributeType).VTKObject.AddArray(insidedness) else: insidedness = numpy_support.numpy_to_vtk(maskArray, deep=1, array_type=vtkConstants.VTK_SIGNED_CHAR) insidedness.SetName(insidednessArrayName) output.GetAttributes(attributeType).VTKObject.AddArray(insidedness)