Ejemplo n.º 1
0
    def __new__(cls, array: Union[Iterable, vtkAbstractArray], dataset=None,
                association=FieldAssociation.NONE):
        """Allocate the array."""
        if isinstance(array, Iterable):
            obj = np.asarray(array).view(cls)
        elif isinstance(array, vtkAbstractArray):
            obj = convert_array(array).view(cls)
            obj.VTKObject = array

        obj.association = association
        obj.dataset = vtkWeakReference()
        if isinstance(dataset, VTKObjectWrapper):
            obj.dataset.Set(dataset.VTKObject)
        else:
            obj.dataset.Set(dataset)
        return obj
Ejemplo n.º 2
0
    def __new__(cls,
                array: Union[Iterable, _vtk.vtkAbstractArray],
                dataset=None,
                association=FieldAssociation.NONE):
        """Allocate the array."""
        if isinstance(array, Iterable):
            obj = np.asarray(array).view(cls)
        elif isinstance(array, _vtk.vtkAbstractArray):
            obj = convert_array(array).view(cls)
            obj.VTKObject = array
        else:
            raise TypeError(
                f'pyvista_ndarray got an invalid type {type(array)}.  '
                'Expected an Iterable or vtk.vtkAbstractArray')

        obj.association = association
        obj.dataset = _vtk.vtkWeakReference()
        if isinstance(dataset, _vtk.VTKObjectWrapper):
            obj.dataset.Set(dataset.VTKObject)
        else:
            obj.dataset.Set(dataset)
        return obj
Ejemplo n.º 3
0
    def _prepare_array(self, data: Union[Sequence[Number], Number, np.ndarray],
                       name: str, deep_copy: bool) -> _vtk.vtkDataSet:
        """Prepare an array to be added to this dataset."""
        if data is None:
            raise TypeError('``data`` cannot be None.')
        if isinstance(data, Iterable):
            data = pyvista_ndarray(data)

        if self.association == FieldAssociation.POINT:
            array_len = self.dataset.GetNumberOfPoints()
        elif self.association == FieldAssociation.CELL:
            array_len = self.dataset.GetNumberOfCells()
        else:
            array_len = data.shape[0] if isinstance(data, np.ndarray) else 1

        # Fixup input array length for scalar input
        if not isinstance(data, np.ndarray) or np.ndim(data) == 0:
            tmparray = np.empty(array_len)
            tmparray.fill(data)
            data = tmparray
        if data.shape[0] != array_len:
            raise ValueError(
                f'data length of ({data.shape[0]}) != required length ({array_len})'
            )

        if data.dtype == np.bool_:
            self.dataset.association_bitarray_names[self.association.name].add(
                name)
            data = data.view(np.uint8)

        shape = data.shape
        if data.ndim == 3:
            # Array of matrices. We need to make sure the order in
            # memory is right.  If row major (C/C++),
            # transpose. VTK wants column major (Fortran order). The deep
            # copy later will make sure that the array is contiguous.
            # If column order but not contiguous, transpose so that the
            # deep copy below does not happen.
            size = data.dtype.itemsize
            if ((data.strides[1] / size == 3 and data.strides[2] / size == 1)
                    or
                (data.strides[1] / size == 1 and data.strides[2] / size == 3
                 and not data.flags.contiguous)):
                data = data.transpose(0, 2, 1)

        # If array is not contiguous, make a deep copy that is contiguous
        if not data.flags.contiguous:
            data = np.ascontiguousarray(data)

        # Flatten array of matrices to array of vectors
        if len(shape) == 3:
            data = data.reshape(shape[0], shape[1] * shape[2])

        # Swap bytes from big to little endian.
        if data.dtype.byteorder == '>':
            data = data.byteswap(inplace=True)

        # this handles the case when an input array is directly added to the
        # output. We want to make sure that the array added to the output is not
        # referring to the input dataset.
        copy = pyvista_ndarray(data)

        return helpers.convert_array(copy, name, deep=deep_copy)
Ejemplo n.º 4
0
    def append(self,
               narray: Union[Sequence[Number], Number, np.ndarray],
               name: str,
               deep_copy=False,
               active_vectors=True,
               active_scalars=True) -> None:
        """Add an array to this object.

        Parameters
        ----------
        narray : array_like, scalar value
            A pyvista_ndarray, numpy.ndarray, list, tuple or scalar value.

        name : str
            Name of the array to add.

        deep_copy : bool
            When True makes a full copy of the array.

        active_vectors : bool
            If True, make this the active vector array.

        active_scalars : bool:
            If True, make this the active scalar array.
        """
        if narray is None:
            raise TypeError('narray cannot be None.')
        if isinstance(narray, Iterable):
            narray = pyvista_ndarray(narray)

        if self.association == FieldAssociation.POINT:
            array_len = self.dataset.GetNumberOfPoints()
        elif self.association == FieldAssociation.CELL:
            array_len = self.dataset.GetNumberOfCells()
        else:
            array_len = narray.shape[0] if isinstance(narray,
                                                      np.ndarray) else 1

        # Fixup input array length for scalar input:
        if not isinstance(narray, np.ndarray) or np.ndim(narray) == 0:
            tmparray = np.empty(array_len)
            tmparray.fill(narray)
            narray = tmparray

        if narray.shape[0] != array_len:
            raise ValueError(
                f'narray length of ({narray.shape[0]}) != required length ({array_len})'
            )

        if narray.dtype == np.bool_:
            self.dataset.association_bitarray_names[self.association].add(name)
            narray = narray.view(np.uint8)

        shape = narray.shape
        if len(shape) == 3:
            # Array of matrices. We need to make sure the order  in memory is right.
            # If column order (c order), transpose. VTK wants row order (fortran
            # order). The deep copy later will make sure that the array is contiguous.
            # If row order but not contiguous, transpose so that the deep copy below
            # does not happen.
            size = narray.dtype.itemsize
            if (narray.strides[1] / size == 3 and narray.strides[2] / size == 1) or \
                (narray.strides[1] / size == 1 and narray.strides[2] / size == 3 and \
                 not narray.flags.contiguous):
                narray = narray.transpose(0, 2, 1)

        # If array is not contiguous, make a deep copy that is contiguous
        if not narray.flags.contiguous:
            narray = np.ascontiguousarray(narray)

        # Flatten array of matrices to array of vectors
        if len(shape) == 3:
            narray = narray.reshape(shape[0], shape[1] * shape[2])

        # Swap bytes from big to little endian.
        if narray.dtype.byteorder == '>':
            narray = narray.byteswap(inplace=True)

        # this handles the case when an input array is directly appended on the
        # output. We want to make sure that the array added to the output is not
        # referring to the input dataset.
        copy = pyvista_ndarray(narray)

        vtk_arr = helpers.convert_array(copy, name, deep=deep_copy)
        self.VTKObject.AddArray(vtk_arr)
        try:
            if active_scalars or self.active_scalars is None:
                self.active_scalars = name  # type: ignore
            if active_vectors or self.active_vectors is None:
                # verify this is actually vector data
                if len(shape) == 2 and shape[1] == 3:
                    self.active_vectors = name  # type: ignore
        except TypeError:
            pass
        self.VTKObject.Modified()