init
This commit is contained in:
@@ -0,0 +1,315 @@
|
||||
r"""
|
||||
Currently, this package is experimental and may change in the future.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
import sys
|
||||
import importlib.util
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from importlib.abc import MetaPathFinder
|
||||
from importlib.machinery import ExtensionFileLoader
|
||||
|
||||
LOADING_STACK = []
|
||||
LIB_EXTS = [".pyd", ".so"]
|
||||
|
||||
def find_lib_path(paths, vtk_module_name):
|
||||
for ext in LIB_EXTS:
|
||||
for base_path in paths:
|
||||
# vtk-wheel => vtkCommonCore.cpython-310-darwin.so
|
||||
# paraview => vtkCommonCore.so
|
||||
# Caution: vtkIOXML vs vtkIOXMLParser
|
||||
for f in Path(base_path).glob(f"{vtk_module_name}[.-]*"):
|
||||
resolved_file = f.resolve()
|
||||
if resolved_file.is_file() and ext in resolved_file.suffixes:
|
||||
return str(resolved_file)
|
||||
|
||||
|
||||
class VTKMetaHook(MetaPathFinder):
|
||||
"""Attach a custom loaded for vtk native library loading to defer loading of pure python dependencies"""
|
||||
def find_spec(self, fullname, path, target=None):
|
||||
if fullname.startswith("vtkmodules.vtk"):
|
||||
vtk_module_name = fullname.split(".")[1]
|
||||
module_path = find_lib_path(path, vtk_module_name)
|
||||
if module_path is None:
|
||||
return None
|
||||
|
||||
LOADING_STACK.append(fullname)
|
||||
return importlib.util.spec_from_file_location(fullname, module_path, loader=VTKLoader(fullname, module_path))
|
||||
|
||||
return None
|
||||
|
||||
|
||||
class VTKLoader(ExtensionFileLoader):
|
||||
"""Flush any pending dependency load once initialize() phase is done"""
|
||||
def exec_module(self, module):
|
||||
super().exec_module(module)
|
||||
|
||||
# Process pending dependencies only if the module match the first load request
|
||||
if len(LOADING_STACK) and LOADING_STACK[0] == module.__name__:
|
||||
LOADING_STACK.clear()
|
||||
on_vtk_module_init_completed()
|
||||
|
||||
|
||||
|
||||
# Register our hook for vtk library loader
|
||||
sys.meta_path.insert(0, VTKMetaHook())
|
||||
|
||||
|
||||
def _windows_dll_path():
|
||||
import os
|
||||
_vtk_python_path = './vtkmodules'
|
||||
_vtk_dll_path = 'bin'
|
||||
# Compute the DLL path based on the location of the file and traversing up
|
||||
# the installation prefix to append the DLL path.
|
||||
_vtk_dll_directory = os.path.dirname(os.path.abspath(__file__))
|
||||
# Loop while we have components to remove.
|
||||
while _vtk_python_path not in ('', '.', '/'):
|
||||
# Strip a directory away.
|
||||
_vtk_python_path = os.path.dirname(_vtk_python_path)
|
||||
_vtk_dll_directory = os.path.dirname(_vtk_dll_directory)
|
||||
_vtk_dll_directory = os.path.join(_vtk_dll_directory, _vtk_dll_path)
|
||||
if os.path.exists(_vtk_dll_directory):
|
||||
# We never remove this path; it is required for VTK to work and there's
|
||||
# no scope where we can easily remove the directory again.
|
||||
_ = os.add_dll_directory(_vtk_dll_directory)
|
||||
|
||||
# Build tree support.
|
||||
try:
|
||||
from . import _build_paths
|
||||
|
||||
# Add any paths needed for the build tree.
|
||||
for path in _build_paths.paths:
|
||||
if os.path.exists(path):
|
||||
_ = os.add_dll_directory(path)
|
||||
except ImportError:
|
||||
# Relocatable install tree (or non-Windows).
|
||||
pass
|
||||
|
||||
|
||||
# CPython 3.8 added behaviors which modified the DLL search path on Windows to
|
||||
# only search "blessed" paths. When importing SMTK, ensure that SMTK's DLLs are
|
||||
# in this set of "blessed" paths.
|
||||
if sys.version_info >= (3, 8) and sys.platform == 'win32':
|
||||
_windows_dll_path()
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# this little trick is for static builds of VTK. In such builds, if
|
||||
# the user imports this Python package in a non-statically linked Python
|
||||
# interpreter i.e. not of the of the VTK-python executables, then we import the
|
||||
# static components importer module.
|
||||
def _load_vtkmodules_static():
|
||||
if 'vtkmodules_vtkCommonCore' not in sys.builtin_module_names:
|
||||
import _vtkmodules_static
|
||||
|
||||
#_load_vtkmodules_static()
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# list the contents
|
||||
__all__ = [
|
||||
'vtkCommonCore',
|
||||
'vtkWebCore',
|
||||
'vtkCommonMath',
|
||||
'vtkCommonTransforms',
|
||||
'vtkCommonDataModel',
|
||||
'vtkCommonExecutionModel',
|
||||
'vtkIOCore',
|
||||
'vtkImagingCore',
|
||||
'vtkIOImage',
|
||||
'vtkIOXMLParser',
|
||||
'vtkIOXML',
|
||||
'vtkCommonMisc',
|
||||
'vtkFiltersCore',
|
||||
'vtkRenderingCore',
|
||||
'vtkRenderingContext2D',
|
||||
'vtkRenderingFreeType',
|
||||
'vtkRenderingSceneGraph',
|
||||
'vtkRenderingVtkJS',
|
||||
'vtkIOExport',
|
||||
'vtkWebGLExporter',
|
||||
'vtkInteractionStyle',
|
||||
'vtkFiltersGeneral',
|
||||
'vtkFiltersSources',
|
||||
'vtkInteractionWidgets',
|
||||
'vtkViewsCore',
|
||||
'vtkViewsInfovis',
|
||||
'vtkCommonComputationalGeometry',
|
||||
'vtkCommonSystem',
|
||||
'vtkFiltersCellGrid',
|
||||
'vtkIOCellGrid',
|
||||
'vtkIOLegacy',
|
||||
'vtkDomainsChemistry',
|
||||
'vtkRenderingHyperTreeGrid',
|
||||
'vtkRenderingUI',
|
||||
'vtkRenderingOpenGL2',
|
||||
'vtkRenderingContextOpenGL2',
|
||||
'vtkRenderingVolume',
|
||||
'vtkImagingMath',
|
||||
'vtkRenderingVolumeOpenGL2',
|
||||
'vtkViewsContext2D',
|
||||
'vtkSerializationManager',
|
||||
'vtkTestingSerialization',
|
||||
'vtkImagingColor',
|
||||
'vtkTestingRendering',
|
||||
'vtkRenderingVolumeAMR',
|
||||
'vtkPythonContext2D',
|
||||
'vtkParallelCore',
|
||||
'vtkRenderingParallel',
|
||||
'vtkRenderingVRModels',
|
||||
'vtkRenderingVR',
|
||||
'vtkRenderingMatplotlib',
|
||||
'vtkRenderingLabel',
|
||||
'vtkRenderingLOD',
|
||||
'vtkRenderingLICOpenGL2',
|
||||
'vtkRenderingImage',
|
||||
'vtkChartsCore',
|
||||
'vtkRenderingGridAxes',
|
||||
'vtkRenderingExternal',
|
||||
'vtkRenderingCellGrid',
|
||||
'vtkIOXdmf2',
|
||||
'vtkIOVeraOut',
|
||||
'vtkIOVPIC',
|
||||
'vtkIOTecplotTable',
|
||||
'vtkIOTRUCHAS',
|
||||
'vtkIOSegY',
|
||||
'vtkIOParallelXML',
|
||||
'vtkIOLSDyna',
|
||||
'vtkIOParallelLSDyna',
|
||||
'vtkIOExodus',
|
||||
'vtkIOParallelExodus',
|
||||
'vtkIOPLY',
|
||||
'vtkIOPIO',
|
||||
'vtkIOMovie',
|
||||
'vtkIOOggTheora',
|
||||
'vtkIOOMF',
|
||||
'vtkIONetCDF',
|
||||
'vtkIOMotionFX',
|
||||
'vtkIOGeometry',
|
||||
'vtkIOParallel',
|
||||
'vtkIOMINC',
|
||||
'vtkIOLANLX3D',
|
||||
'vtkIOImport',
|
||||
'vtkIOIOSS',
|
||||
'vtkIOHDF',
|
||||
'vtkIOH5part',
|
||||
'vtkIOH5Rage',
|
||||
'vtkIOGeoJSON',
|
||||
'vtkIOFLUENTCFF',
|
||||
'vtkIOVideo',
|
||||
'vtkIOFDS',
|
||||
'vtkIOInfovis',
|
||||
'vtkIOExportPDF',
|
||||
'vtkRenderingGL2PSOpenGL2',
|
||||
'vtkIOExportGL2PS',
|
||||
'vtkIOEngys',
|
||||
'vtkIOEnSight',
|
||||
'vtkIOERF',
|
||||
'vtkIOCityGML',
|
||||
'vtkIOChemistry',
|
||||
'vtkIOCesium3DTiles',
|
||||
'vtkIOCONVERGECFD',
|
||||
'vtkIOCGNSReader',
|
||||
'vtkIOAvmesh',
|
||||
'vtkIOAsynchronous',
|
||||
'vtkIOAMR',
|
||||
'vtkInteractionImage',
|
||||
'vtkInfovisLayout',
|
||||
'vtkImagingStencil',
|
||||
'vtkImagingStatistics',
|
||||
'vtkImagingGeneral',
|
||||
'vtkImagingOpenGL2',
|
||||
'vtkImagingMorphological',
|
||||
'vtkImagingFourier',
|
||||
'vtkIOSQL',
|
||||
'vtkRenderingAnnotation',
|
||||
'vtkImagingHybrid',
|
||||
'vtkGeovisCore',
|
||||
'vtkFiltersTopology',
|
||||
'vtkFiltersTensor',
|
||||
'vtkFiltersSelection',
|
||||
'vtkFiltersSMP',
|
||||
'vtkFiltersPython',
|
||||
'vtkFiltersProgrammable',
|
||||
'vtkFiltersModeling',
|
||||
'vtkFiltersPoints',
|
||||
'vtkFiltersStatistics',
|
||||
'vtkFiltersParallelStatistics',
|
||||
'vtkFiltersImaging',
|
||||
'vtkFiltersExtraction',
|
||||
'vtkFiltersGeometry',
|
||||
'vtkFiltersHybrid',
|
||||
'vtkFiltersHyperTree',
|
||||
'vtkFiltersTexture',
|
||||
'vtkFiltersParallel',
|
||||
'vtkFiltersParallelImaging',
|
||||
'vtkFiltersParallelDIY2',
|
||||
'vtkFiltersTemporal',
|
||||
'vtkFiltersGeometryPreview',
|
||||
'vtkFiltersGeneric',
|
||||
'vtkFiltersFlowPaths',
|
||||
'vtkFiltersAMR',
|
||||
'vtkDomainsChemistryOpenGL2',
|
||||
'vtkCommonPython',
|
||||
'vtkCommonColor',
|
||||
'vtkImagingSources',
|
||||
'vtkInfovisCore',
|
||||
'vtkAcceleratorsVTKmCore',
|
||||
'vtkAcceleratorsVTKmDataModel',
|
||||
'vtkAcceleratorsVTKmFilters',
|
||||
'vtkFiltersVerdict',
|
||||
'vtkFiltersReduction',
|
||||
'all',
|
||||
'gtk',
|
||||
'numpy_interface',
|
||||
'qt',
|
||||
'test',
|
||||
'tk',
|
||||
'util',
|
||||
'wx',
|
||||
|
||||
]
|
||||
#------------------------------------------------------------------------------
|
||||
# get the version
|
||||
__version__ = "9.5.2"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# describe import dependencies to properly define Python @override
|
||||
MODULE_MAPPER = {
|
||||
"vtkCommonDataModel": [
|
||||
"vtkmodules.util.data_model",
|
||||
],
|
||||
"vtkCommonExecutionModel": [
|
||||
"vtkmodules.util.execution_model",
|
||||
],
|
||||
}
|
||||
LOADED_MODULES = set()
|
||||
PENDING_LOADED_MODULES = set()
|
||||
|
||||
def register_vtk_module_dependencies(vtk_module_name, *import_names):
|
||||
"""Method to call for registering external override on vtkmodule load"""
|
||||
MODULE_MAPPER.setdefault(vtk_module_name, []).extend(import_names)
|
||||
|
||||
# If already loaded let's make sure we import it now
|
||||
if vtk_module_name in LOADED_MODULES:
|
||||
for import_name in import_names:
|
||||
importlib.import_module(import_name)
|
||||
|
||||
|
||||
def on_vtk_module_init(module_name):
|
||||
"""Automatically called by vtkmodule when they are loaded"""
|
||||
if module_name in LOADED_MODULES:
|
||||
return
|
||||
|
||||
PENDING_LOADED_MODULES.add(module_name)
|
||||
|
||||
|
||||
def on_vtk_module_init_completed():
|
||||
pending = list(PENDING_LOADED_MODULES)
|
||||
PENDING_LOADED_MODULES.clear()
|
||||
|
||||
for module_name in pending:
|
||||
LOADED_MODULES.add(module_name)
|
||||
for import_name in MODULE_MAPPER.get(module_name, []):
|
||||
importlib.import_module(import_name)
|
||||
@@ -0,0 +1,167 @@
|
||||
""" This module loads the entire VTK library into its namespace. It
|
||||
also allows one to use specific packages inside the vtk directory.."""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
# --------------------------------------
|
||||
from .vtkCommonCore import *
|
||||
from .vtkWebCore import *
|
||||
from .vtkCommonMath import *
|
||||
from .vtkCommonTransforms import *
|
||||
from .vtkCommonDataModel import *
|
||||
from .vtkCommonExecutionModel import *
|
||||
from .vtkIOCore import *
|
||||
from .vtkImagingCore import *
|
||||
from .vtkIOImage import *
|
||||
from .vtkIOXMLParser import *
|
||||
from .vtkIOXML import *
|
||||
from .vtkCommonMisc import *
|
||||
from .vtkFiltersCore import *
|
||||
from .vtkRenderingCore import *
|
||||
from .vtkRenderingContext2D import *
|
||||
from .vtkRenderingFreeType import *
|
||||
from .vtkRenderingSceneGraph import *
|
||||
from .vtkRenderingVtkJS import *
|
||||
from .vtkIOExport import *
|
||||
from .vtkWebGLExporter import *
|
||||
from .vtkInteractionStyle import *
|
||||
from .vtkFiltersGeneral import *
|
||||
from .vtkFiltersSources import *
|
||||
from .vtkInteractionWidgets import *
|
||||
from .vtkViewsCore import *
|
||||
from .vtkViewsInfovis import *
|
||||
from .vtkCommonComputationalGeometry import *
|
||||
from .vtkCommonSystem import *
|
||||
from .vtkFiltersCellGrid import *
|
||||
from .vtkIOCellGrid import *
|
||||
from .vtkIOLegacy import *
|
||||
from .vtkDomainsChemistry import *
|
||||
from .vtkRenderingHyperTreeGrid import *
|
||||
from .vtkRenderingUI import *
|
||||
from .vtkRenderingOpenGL2 import *
|
||||
from .vtkRenderingContextOpenGL2 import *
|
||||
from .vtkRenderingVolume import *
|
||||
from .vtkImagingMath import *
|
||||
from .vtkRenderingVolumeOpenGL2 import *
|
||||
from .vtkViewsContext2D import *
|
||||
from .vtkSerializationManager import *
|
||||
from .vtkTestingSerialization import *
|
||||
from .vtkImagingColor import *
|
||||
from .vtkTestingRendering import *
|
||||
from .vtkRenderingVolumeAMR import *
|
||||
from .vtkPythonContext2D import *
|
||||
from .vtkParallelCore import *
|
||||
from .vtkRenderingParallel import *
|
||||
from .vtkRenderingVRModels import *
|
||||
from .vtkRenderingVR import *
|
||||
from .vtkRenderingMatplotlib import *
|
||||
from .vtkRenderingLabel import *
|
||||
from .vtkRenderingLOD import *
|
||||
from .vtkRenderingLICOpenGL2 import *
|
||||
from .vtkRenderingImage import *
|
||||
from .vtkChartsCore import *
|
||||
from .vtkRenderingGridAxes import *
|
||||
from .vtkRenderingExternal import *
|
||||
from .vtkRenderingCellGrid import *
|
||||
from .vtkIOXdmf2 import *
|
||||
from .vtkIOVeraOut import *
|
||||
from .vtkIOVPIC import *
|
||||
from .vtkIOTecplotTable import *
|
||||
from .vtkIOTRUCHAS import *
|
||||
from .vtkIOSegY import *
|
||||
from .vtkIOParallelXML import *
|
||||
from .vtkIOLSDyna import *
|
||||
from .vtkIOParallelLSDyna import *
|
||||
from .vtkIOExodus import *
|
||||
from .vtkIOParallelExodus import *
|
||||
from .vtkIOPLY import *
|
||||
from .vtkIOPIO import *
|
||||
from .vtkIOMovie import *
|
||||
from .vtkIOOggTheora import *
|
||||
from .vtkIOOMF import *
|
||||
from .vtkIONetCDF import *
|
||||
from .vtkIOMotionFX import *
|
||||
from .vtkIOGeometry import *
|
||||
from .vtkIOParallel import *
|
||||
from .vtkIOMINC import *
|
||||
from .vtkIOLANLX3D import *
|
||||
from .vtkIOImport import *
|
||||
from .vtkIOIOSS import *
|
||||
from .vtkIOHDF import *
|
||||
from .vtkIOH5part import *
|
||||
from .vtkIOH5Rage import *
|
||||
from .vtkIOGeoJSON import *
|
||||
from .vtkIOFLUENTCFF import *
|
||||
from .vtkIOVideo import *
|
||||
from .vtkIOFDS import *
|
||||
from .vtkIOInfovis import *
|
||||
from .vtkIOExportPDF import *
|
||||
from .vtkRenderingGL2PSOpenGL2 import *
|
||||
from .vtkIOExportGL2PS import *
|
||||
from .vtkIOEngys import *
|
||||
from .vtkIOEnSight import *
|
||||
from .vtkIOERF import *
|
||||
from .vtkIOCityGML import *
|
||||
from .vtkIOChemistry import *
|
||||
from .vtkIOCesium3DTiles import *
|
||||
from .vtkIOCONVERGECFD import *
|
||||
from .vtkIOCGNSReader import *
|
||||
from .vtkIOAvmesh import *
|
||||
from .vtkIOAsynchronous import *
|
||||
from .vtkIOAMR import *
|
||||
from .vtkInteractionImage import *
|
||||
from .vtkInfovisLayout import *
|
||||
from .vtkImagingStencil import *
|
||||
from .vtkImagingStatistics import *
|
||||
from .vtkImagingGeneral import *
|
||||
from .vtkImagingOpenGL2 import *
|
||||
from .vtkImagingMorphological import *
|
||||
from .vtkImagingFourier import *
|
||||
from .vtkIOSQL import *
|
||||
from .vtkRenderingAnnotation import *
|
||||
from .vtkImagingHybrid import *
|
||||
from .vtkGeovisCore import *
|
||||
from .vtkFiltersTopology import *
|
||||
from .vtkFiltersTensor import *
|
||||
from .vtkFiltersSelection import *
|
||||
from .vtkFiltersSMP import *
|
||||
from .vtkFiltersPython import *
|
||||
from .vtkFiltersProgrammable import *
|
||||
from .vtkFiltersModeling import *
|
||||
from .vtkFiltersPoints import *
|
||||
from .vtkFiltersStatistics import *
|
||||
from .vtkFiltersParallelStatistics import *
|
||||
from .vtkFiltersImaging import *
|
||||
from .vtkFiltersExtraction import *
|
||||
from .vtkFiltersGeometry import *
|
||||
from .vtkFiltersHybrid import *
|
||||
from .vtkFiltersHyperTree import *
|
||||
from .vtkFiltersTexture import *
|
||||
from .vtkFiltersParallel import *
|
||||
from .vtkFiltersParallelImaging import *
|
||||
from .vtkFiltersParallelDIY2 import *
|
||||
from .vtkFiltersTemporal import *
|
||||
from .vtkFiltersGeometryPreview import *
|
||||
from .vtkFiltersGeneric import *
|
||||
from .vtkFiltersFlowPaths import *
|
||||
from .vtkFiltersAMR import *
|
||||
from .vtkDomainsChemistryOpenGL2 import *
|
||||
from .vtkCommonPython import *
|
||||
from .vtkCommonColor import *
|
||||
from .vtkImagingSources import *
|
||||
from .vtkInfovisCore import *
|
||||
from .vtkAcceleratorsVTKmCore import *
|
||||
from .vtkAcceleratorsVTKmDataModel import *
|
||||
from .vtkAcceleratorsVTKmFilters import *
|
||||
from .vtkFiltersVerdict import *
|
||||
from .vtkFiltersReduction import *
|
||||
|
||||
|
||||
# useful macro for getting type names
|
||||
from .util.vtkConstants import vtkImageScalarTypeNameMacro
|
||||
|
||||
# import convenience decorators
|
||||
from .util.misc import calldata_type
|
||||
|
||||
# import the vtkVariant helpers
|
||||
from .util.vtkVariant import *
|
||||
@@ -0,0 +1,662 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
This program will generate .pyi files for all the VTK modules
|
||||
in the "vtkmodules" package (or whichever package you specify).
|
||||
These files are used for type checking and autocompletion in
|
||||
some Python IDEs.
|
||||
|
||||
The VTK modules must be in Python's path when you run this script.
|
||||
Options are as follows:
|
||||
|
||||
-p PACKAGE The package to generate .pyi files for [vtkmodules]
|
||||
-o OUTPUT The output directory [default is the package directory]
|
||||
-e EXT The file suffix [.pyi]
|
||||
-i IMPORTER The static module importer (for static builds only)
|
||||
-h HELP
|
||||
|
||||
With no arguments, the script runs with the defaults (the .pyi files
|
||||
are put inside the existing vtkmodules package). This is equivalent
|
||||
to the following:
|
||||
|
||||
python -m vtkmodules.generate_pyi -p vtkmodules
|
||||
|
||||
To put the pyi files somewhere else, perhaps with a different suffix:
|
||||
|
||||
python -m vtkmodules.generate_pyi -o /path/to/vtkmodules -e .pyi
|
||||
|
||||
To generate pyi files for just one or two modules:
|
||||
|
||||
python -m vtkmodules.generate_pyi -p vtkmodules vtkCommonCore vtkCommonDataModel
|
||||
|
||||
To generate pyi files for your own modules in your own package:
|
||||
|
||||
python -m vtkmodules.generate_pyi -p mypackage mymodule [mymodule2 ...]
|
||||
|
||||
"""
|
||||
|
||||
from vtkmodules.vtkCommonCore import vtkObjectBase, vtkSOADataArrayTemplate
|
||||
from keyword import iskeyword
|
||||
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
import ast
|
||||
import argparse
|
||||
import builtins
|
||||
import inspect
|
||||
import importlib.util
|
||||
|
||||
# ==== Cancel any module overrides ====
|
||||
|
||||
import vtkmodules
|
||||
|
||||
vtkmodules.MODULE_MAPPER = {}
|
||||
|
||||
# ==== For type inspection ====
|
||||
|
||||
# list expected non-vtk type names
|
||||
types = set()
|
||||
for m,o in builtins.__dict__.items():
|
||||
if isinstance(o, type):
|
||||
types.add(m)
|
||||
for m in ['Any', 'Buffer', 'Callback', 'None', 'Pointer', 'Template', 'Union']:
|
||||
types.add(m)
|
||||
|
||||
# basic type checking methods
|
||||
ismethod = inspect.isroutine
|
||||
isclass = inspect.isclass
|
||||
|
||||
# VTK methods have a special type
|
||||
vtkmethod = type(vtkObjectBase.IsA)
|
||||
template = type(vtkSOADataArrayTemplate)
|
||||
|
||||
def isvtkmethod(m):
|
||||
"""Check for VTK's custom method descriptor"""
|
||||
return (type(m) == vtkmethod)
|
||||
|
||||
def isnamespace(m):
|
||||
"""Check for namespaces within a module"""
|
||||
# until vtkmodules.vtkCommonCore.namespace is directly accessible
|
||||
return (str(type(m)) == "<class 'vtkmodules.vtkCommonCore.namespace'>")
|
||||
|
||||
def isenum(m):
|
||||
"""Check for enums (currently derived from int)"""
|
||||
return (isclass(m) and issubclass(m, int))
|
||||
|
||||
def typename(o):
|
||||
"""Generate a typename that can be used for annotation."""
|
||||
if o is None:
|
||||
return "None"
|
||||
elif type(o) == template:
|
||||
return "Template"
|
||||
else:
|
||||
return type(o).__name__
|
||||
|
||||
def typename_forward(o):
|
||||
"""Generate a typename, or if necessary, a forward reference."""
|
||||
name = typename(o)
|
||||
if name not in types:
|
||||
# do forward reference by adding quotes
|
||||
name = '\'' + name + '\''
|
||||
return name
|
||||
|
||||
|
||||
# ==== For the topological sort ====
|
||||
|
||||
class Graph:
|
||||
"""A graph for topological sorting."""
|
||||
def __init__(self):
|
||||
self.nodes = {}
|
||||
def __getitem__(self, name):
|
||||
return self.nodes[name]
|
||||
def __setitem__(self, name, node):
|
||||
self.nodes[name] = node
|
||||
|
||||
class Node:
|
||||
"""A node for the graph."""
|
||||
def __init__(self, o, d):
|
||||
self.obj = o
|
||||
self.deps = d
|
||||
|
||||
def build_graph(d):
|
||||
"""Build a graph from a module's dictionary."""
|
||||
graph = Graph()
|
||||
items = sorted(d.items())
|
||||
for m,o in items:
|
||||
if isclass(o):
|
||||
if m == o.__name__:
|
||||
# a class definition
|
||||
bases = [b.__name__ for b in o.__bases__]
|
||||
graph[m] = Node(o, bases)
|
||||
else:
|
||||
# a class alias
|
||||
graph[m] = Node(o, [o.__name__])
|
||||
elif ismethod(o):
|
||||
graph[m] = Node(o, [])
|
||||
else:
|
||||
graph[m] = Node(o, [typename(o)])
|
||||
return graph
|
||||
|
||||
def sorted_graph_helper(graph, m, visited, items):
|
||||
"""Helper for topological sorting."""
|
||||
visited.add(m)
|
||||
try:
|
||||
node = graph[m]
|
||||
except KeyError:
|
||||
return
|
||||
for dep in node.deps:
|
||||
if dep not in visited:
|
||||
sorted_graph_helper(graph, dep, visited, items)
|
||||
items.append((m, node.obj))
|
||||
|
||||
def sorted_graph(graph):
|
||||
"""Sort a graph and return the sorted items."""
|
||||
items = []
|
||||
visited = set()
|
||||
for m in graph.nodes:
|
||||
if m not in visited:
|
||||
sorted_graph_helper(graph, m, visited, items)
|
||||
return items
|
||||
|
||||
def topologically_sorted_items(d):
|
||||
"""Return the items from a module's dictionary, topologically sorted."""
|
||||
return sorted_graph(build_graph(d))
|
||||
|
||||
|
||||
# ==== For parsing docstrings ====
|
||||
|
||||
# regular expressions for parsing
|
||||
string = re.compile(r"""("([^\\"]|\\.)*"|'([^\\']|\\.)*')""")
|
||||
identifier = re.compile(r"""([A-Za-z_]([A-Za-z0-9_]|[.][A-Za-z_])*)""")
|
||||
indent = re.compile(r"[ \t]+(?=\S)")
|
||||
has_self = re.compile(r"[(]self[,)]")
|
||||
|
||||
# important characters for rapidly parsing code
|
||||
keychar = re.compile(r"[\'\"{}\[\]()\n]")
|
||||
|
||||
def parse_error(message, text, begin, pos):
|
||||
"""Print a parse error, syntax or otherwise.
|
||||
"""
|
||||
end = text.find('\n', pos)
|
||||
if end == -1:
|
||||
end = len(text)
|
||||
sys.stderr.write("Error: " + message + ":\n")
|
||||
sys.stderr.write(text[begin:end] + "\n");
|
||||
sys.stderr.write('-' * (pos - begin) + "^\n")
|
||||
|
||||
def annotation_text(a, text, is_return):
|
||||
"""Return the new text to be used for an annotation.
|
||||
"""
|
||||
if isinstance(a, ast.Name):
|
||||
name = a.id
|
||||
if name not in types:
|
||||
# quote the type, in case it isn't yet defined
|
||||
text = '\'' + name + '\''
|
||||
elif isinstance(a, (ast.Tuple, ast.List)):
|
||||
size = len(a.elts)
|
||||
e = a.elts[0]
|
||||
offset = a.col_offset
|
||||
old_name = text[e.col_offset - offset:e.end_col_offset - offset]
|
||||
name = annotation_text(e, old_name, is_return)
|
||||
|
||||
if is_return:
|
||||
# use concrete types for return values
|
||||
if isinstance(a, ast.Tuple):
|
||||
text = 'Tuple[' + ', '.join([name]*size) + ']'
|
||||
else:
|
||||
text = 'List[' + name + ']'
|
||||
else:
|
||||
# use generic sequence types for args
|
||||
if isinstance(a, ast.Tuple):
|
||||
text = 'Sequence[' + name + ']'
|
||||
else:
|
||||
text = 'MutableSequence[' + name + ']'
|
||||
|
||||
return text
|
||||
|
||||
def fix_annotations(signature):
|
||||
"""Fix the annotations in a method definition.
|
||||
The signature must be a single-line function def, no decorators.
|
||||
"""
|
||||
# get the FunctionDef object from the parse tree
|
||||
definition = ast.parse(signature).body[0]
|
||||
annotations = [arg.annotation for arg in definition.args.args]
|
||||
return_i = len(annotations) # index of annotation for return
|
||||
annotations.append(definition.returns)
|
||||
|
||||
# create a list of changes to apply to the annotations
|
||||
changes = []
|
||||
for i,a in enumerate(annotations):
|
||||
if a is not None:
|
||||
old_text = signature[a.col_offset:a.end_col_offset]
|
||||
text = annotation_text(a, old_text, (i == return_i))
|
||||
if text != old_text:
|
||||
changes.append((a.col_offset, a.end_col_offset, text))
|
||||
|
||||
# apply changes to generate a new signature
|
||||
if changes:
|
||||
newsig = ""
|
||||
lastpos = 0
|
||||
for begin,end,text in changes:
|
||||
newsig += signature[lastpos:begin]
|
||||
newsig += text
|
||||
lastpos = end
|
||||
newsig += signature[lastpos:]
|
||||
signature = newsig
|
||||
|
||||
return signature
|
||||
|
||||
def push_signature(o, l, signature):
|
||||
"""Process a method signature and add it to the list.
|
||||
"""
|
||||
# eliminate newlines and indents
|
||||
signature = re.sub(r"\s+", " ", signature)
|
||||
# no space after opening delimiter or ':' or '='
|
||||
signature = re.sub(r"([({\[:=]) ", "\\1", signature)
|
||||
|
||||
if signature.startswith('C++:'):
|
||||
# the C++ method signatures are unused
|
||||
pass
|
||||
elif signature.startswith(o.__name__ + "("):
|
||||
# make it into a python method definition
|
||||
signature = "def " + signature + ': ...'
|
||||
if sys.hexversion >= 0x3080000:
|
||||
# XXX(Python 3.8) uses ast features from 3.8
|
||||
signature = fix_annotations(signature)
|
||||
if signature not in l:
|
||||
l.append(signature)
|
||||
|
||||
def get_signatures(o):
|
||||
"""Return a list of method signatures found in the docstring.
|
||||
"""
|
||||
doc = o.__doc__
|
||||
signatures = [] # output method signatures
|
||||
if doc is None:
|
||||
return signatures
|
||||
|
||||
# variables used for parsing the docstrings
|
||||
begin = 0 # beginning of current signature
|
||||
pos = 0 # current position in docstring
|
||||
delim_stack = [] # keep track of bracket depth
|
||||
|
||||
# loop through docstring using longest strides possible
|
||||
# (this will go line-by-line or until first ( ) { } [ ] " ')
|
||||
while pos < len(doc):
|
||||
# look for the next "character of interest" in docstring
|
||||
match = keychar.search(doc, pos)
|
||||
# did we find a match before the end of docstring?
|
||||
if match:
|
||||
# get new position
|
||||
pos,end = match.span()
|
||||
# take different action, depending on char
|
||||
c = match.group()
|
||||
if c in '\"\'':
|
||||
# skip over a string literal
|
||||
m = string.match(doc, pos)
|
||||
if m:
|
||||
pos,end = m.span()
|
||||
else:
|
||||
parse_error("Unterminated string", doc, begin, pos)
|
||||
break
|
||||
elif c in '{[(':
|
||||
# descend into a bracketed expression (push stack)
|
||||
delim_stack.append({'{':'}','[':']','(':')'}[c])
|
||||
elif c in '}])':
|
||||
# ascend out of a bracketed expression (pop stack)
|
||||
if not delim_stack or c != delim_stack.pop():
|
||||
parse_error("Unmatched bracket", doc, begin, pos)
|
||||
break
|
||||
elif c == '\n' and not (delim_stack or indent.match(doc, end)):
|
||||
# a newline not followed by an indent marks end of signature,
|
||||
# except for within brackets
|
||||
signature = doc[begin:pos].strip()
|
||||
if signature:
|
||||
push_signature(o, signatures, signature)
|
||||
begin = end
|
||||
else:
|
||||
# blank line means no more signatures in docstring
|
||||
break
|
||||
else:
|
||||
# reached the end of the docstring
|
||||
end = len(doc)
|
||||
if not delim_stack:
|
||||
signature = doc[begin:pos].strip()
|
||||
if signature:
|
||||
push_signature(o, signatures, signature)
|
||||
else:
|
||||
parse_error("Unmatched bracket", doc, begin, pos)
|
||||
break
|
||||
|
||||
# advance position within docstring and return to head of loop
|
||||
pos = end
|
||||
|
||||
return signatures
|
||||
|
||||
def get_constructors(c):
|
||||
"""Get constructors from the class documentation.
|
||||
"""
|
||||
constructors = []
|
||||
name = c.__name__
|
||||
doc = c.__doc__
|
||||
|
||||
if not doc or not doc.startswith(name + "("):
|
||||
return constructors
|
||||
signatures = get_signatures(c)
|
||||
for signature in signatures:
|
||||
if signature.startswith("def " + name + "("):
|
||||
signature = re.sub("-> \'?" + name + "\'?", "-> None", signature)
|
||||
if signature.startswith("def " + name + "()"):
|
||||
constructors.append(re.sub(name + r"\(", "__init__(self", signature, count=1))
|
||||
else:
|
||||
constructors.append(re.sub(name + r"\(", "__init__(self, ", signature, count=1))
|
||||
return constructors
|
||||
|
||||
def handle_static(o, signature):
|
||||
"""If method has no "self", add @static decorator."""
|
||||
if isvtkmethod(o) and not has_self.search(signature):
|
||||
return "@staticmethod\n" + signature
|
||||
else:
|
||||
return signature
|
||||
|
||||
def add_indent(s, indent):
|
||||
"""Add the given indent before every line in the string.
|
||||
"""
|
||||
return indent + re.sub(r"\n(?=([^\n]))", "\n" + indent, s)
|
||||
|
||||
def namespace_pyi(c, mod):
|
||||
"""Fake a namespace by creating a dummy class.
|
||||
"""
|
||||
base = "namespace"
|
||||
if mod.__name__ != 'vtkmodules.vtkCommonCore':
|
||||
base = 'vtkmodules.vtkCommonCore.' + base
|
||||
out = "class " + c.__name__ + "(" + base + "):\n"
|
||||
count = 0
|
||||
|
||||
# do all nested classes (these will be enum types)
|
||||
items = topologically_sorted_items(c.__dict__)
|
||||
others = []
|
||||
for m,o in items:
|
||||
if isenum(o) and m == o.__name__:
|
||||
out += add_indent(class_pyi(o), " ")
|
||||
count += 1
|
||||
else:
|
||||
others.append((m, o))
|
||||
|
||||
# do all constants
|
||||
items = others
|
||||
others = []
|
||||
for m,o in items:
|
||||
if not m.startswith("__") and not ismethod(o) and not isclass(o):
|
||||
out += " " + m + ":" + typename_forward(o) + "\n"
|
||||
count += 1
|
||||
else:
|
||||
others.append((m,o))
|
||||
|
||||
if count == 0:
|
||||
out = out[0:-1] + " ...\n"
|
||||
|
||||
return out
|
||||
|
||||
def class_pyi(c):
|
||||
"""Generate all the method stubs for a class.
|
||||
"""
|
||||
bases = []
|
||||
for b in c.__bases__:
|
||||
if b.__module__ in (c.__module__, 'builtins'):
|
||||
bases.append(b.__name__)
|
||||
else:
|
||||
bases.append(b.__module__ + "." + b.__name__)
|
||||
|
||||
out = "class " + c.__name__ + "(" + ", ".join(bases) + "):\n"
|
||||
count = 0
|
||||
|
||||
# do all nested classes (these are usually enum types)
|
||||
items = topologically_sorted_items(c.__dict__)
|
||||
others = []
|
||||
for m,o in items:
|
||||
if isclass(o) and m == o.__name__:
|
||||
out += add_indent(class_pyi(o), " ")
|
||||
count += 1
|
||||
else:
|
||||
others.append((m, o))
|
||||
|
||||
# do all constants
|
||||
items = others
|
||||
others = []
|
||||
for m,o in items:
|
||||
if not m.startswith("__") and not ismethod(o) and not isclass(o) and not iskeyword(m):
|
||||
out += " " + m + ":" + typename_forward(o) + "\n"
|
||||
count += 1
|
||||
else:
|
||||
others.append((m,o))
|
||||
|
||||
# do the __init__ methods
|
||||
constructors = get_constructors(c)
|
||||
if len(constructors) == 0:
|
||||
if hasattr(c, "__init__") and issubclass(c, vtkObjectBase):
|
||||
out += " def __init__(self, **properties:Any) -> None: ...\n"
|
||||
count += 1
|
||||
else:
|
||||
count += 1
|
||||
if len(constructors) == 1:
|
||||
out += add_indent(constructors[0], " ") + "\n"
|
||||
else:
|
||||
for overload in constructors:
|
||||
out += add_indent("@overload\n" + overload, " ") + "\n"
|
||||
|
||||
# do the methods
|
||||
items = others
|
||||
others = []
|
||||
for m,o in items:
|
||||
if ismethod(o):
|
||||
signatures = get_signatures(o)
|
||||
if len(signatures) == 0:
|
||||
continue
|
||||
count += 1
|
||||
if len(signatures) == 1:
|
||||
signature = handle_static(o, signatures[0])
|
||||
out += add_indent(signature, " ") + "\n"
|
||||
continue
|
||||
for overload in signatures:
|
||||
signature = handle_static(o, overload)
|
||||
out += add_indent("@overload\n" + signature, " ") + "\n"
|
||||
else:
|
||||
others.append((m, o))
|
||||
|
||||
if count == 0:
|
||||
out = out[0:-1] + " ...\n"
|
||||
|
||||
return out
|
||||
|
||||
def module_pyi(mod, output):
|
||||
"""Generate the contents of a .pyi file for a VTK module.
|
||||
"""
|
||||
# needed stuff from typing module
|
||||
output.write("from typing import overload, Any, Callable, TypeVar, Union\n")
|
||||
output.write("from typing import Tuple, List, Sequence, MutableSequence\n")
|
||||
output.write("\n")
|
||||
output.write("Callback = Union[Callable[..., None], None]\n")
|
||||
output.write("Buffer = TypeVar('Buffer')\n")
|
||||
output.write("Pointer = TypeVar('Pointer')\n")
|
||||
output.write("Template = TypeVar('Template')\n")
|
||||
output.write("\n")
|
||||
|
||||
if mod.__name__ == 'vtkmodules.vtkCommonCore':
|
||||
# dummy superclass for namespaces
|
||||
output.write("class namespace: pass\n")
|
||||
output.write("\n")
|
||||
|
||||
# all the modules this module depends on
|
||||
depends = set(['vtkmodules.vtkCommonCore'])
|
||||
for m,o in mod.__dict__.items():
|
||||
if isclass(o) and m == o.__name__:
|
||||
for base in o.__bases__:
|
||||
depends.add(base.__module__)
|
||||
depends.discard(mod.__name__)
|
||||
depends.discard("builtins")
|
||||
for depend in sorted(depends):
|
||||
output.write("import " + depend + "\n")
|
||||
if depends:
|
||||
output.write("\n")
|
||||
|
||||
# sort the dict according to dependency
|
||||
items = topologically_sorted_items(mod.__dict__)
|
||||
|
||||
# do all namespaces
|
||||
others = []
|
||||
for m,o in items:
|
||||
if isnamespace(o) and m == o.__name__:
|
||||
output.write(namespace_pyi(o, mod))
|
||||
output.write("\n")
|
||||
else:
|
||||
others.append((m, o))
|
||||
|
||||
# do all enum types
|
||||
items = others
|
||||
others = []
|
||||
for m,o in items:
|
||||
if isenum(o) and m == o.__name__:
|
||||
output.write(class_pyi(o))
|
||||
output.write("\n")
|
||||
else:
|
||||
others.append((m, o))
|
||||
|
||||
# do all enum aliases
|
||||
items = others
|
||||
others = []
|
||||
for m,o in items:
|
||||
if isenum(o) and m != o.__name__:
|
||||
output.write(m + " = " + o.__name__ + "\n")
|
||||
else:
|
||||
others.append((m, o))
|
||||
|
||||
# do all constants
|
||||
items = others
|
||||
others = []
|
||||
for m,o in items:
|
||||
if not m.startswith("__") and not ismethod(o) and not isclass(o):
|
||||
output.write(m + ":" + typename_forward(o) + "\n")
|
||||
else:
|
||||
others.append((m,o))
|
||||
if len(items) > len(others):
|
||||
output.write("\n")
|
||||
|
||||
# do all classes
|
||||
items = others
|
||||
others = []
|
||||
for m,o in items:
|
||||
if isclass(o) and m == o.__name__:
|
||||
output.write(class_pyi(o))
|
||||
output.write("\n")
|
||||
else:
|
||||
others.append((m, o))
|
||||
|
||||
# do all class aliases
|
||||
items = others
|
||||
others = []
|
||||
for m,o in items:
|
||||
if isclass(o) and m != o.__name__:
|
||||
output.write(m + " = " + o.__name__ + "\n")
|
||||
else:
|
||||
others.append((m, o))
|
||||
|
||||
def main(argv=sys.argv):
|
||||
# for error messages etcetera
|
||||
progname = os.path.basename(argv[0])
|
||||
|
||||
# parse the program arguments
|
||||
parser = argparse.ArgumentParser(
|
||||
prog=argv[0],
|
||||
usage="python " + progname + " [-p package] [-o output_dir]",
|
||||
description="A .pyi generator for the VTK python wrappers.")
|
||||
parser.add_argument('-p', '--package', type=str, default="vtkmodules",
|
||||
help="Package name [vtkmodules].")
|
||||
parser.add_argument('-i', '--importer', type=str,
|
||||
help="Static module importer [].")
|
||||
parser.add_argument('-o', '--output', type=str,
|
||||
help="Output directory [package directory].")
|
||||
parser.add_argument('-e', '--ext', type=str, default=".pyi",
|
||||
help="Output file suffix [.pyi].")
|
||||
parser.add_argument('--test', action='count', default=0,
|
||||
help="Test .pyi files instead of creating them.")
|
||||
parser.add_argument('modules', type=str, nargs='*',
|
||||
help="Modules to process [all].")
|
||||
args = parser.parse_args(argv[1:])
|
||||
|
||||
# for convenience
|
||||
packagename = args.package
|
||||
modules = args.modules
|
||||
basedir = args.output
|
||||
ext = args.ext
|
||||
|
||||
# if static module importer is needed, it must be handled first
|
||||
if args.importer:
|
||||
if len(modules) == 0:
|
||||
sys.stderr.write(progname + ": when using '-i', all modules " +
|
||||
"in the package must be listed on the command line.\n")
|
||||
return 1
|
||||
# check that the modules aren't already present as builtins
|
||||
# (we replace '.' separators with underscores for static importers)
|
||||
module_exemplar = (packagename + '.' + modules[0]).replace('.', '_')
|
||||
if module_exemplar not in sys.builtin_module_names:
|
||||
importlib.import_module(args.importer)
|
||||
|
||||
# get information about the package
|
||||
if basedir is None or len(modules) == 0:
|
||||
mod = importlib.import_module(packagename)
|
||||
if basedir is None:
|
||||
filename = getattr(mod, '__file__', None)
|
||||
if filename is None or os.path.basename(filename) != '__init__.py':
|
||||
sys.stderr.write(progname + ": " + packagename + " has no __init__.py\n")
|
||||
return 1
|
||||
basedir = os.path.dirname(filename)
|
||||
if len(modules) == 0:
|
||||
for modname in mod.__all__:
|
||||
# only generate .pyi files for the extension modules in __all__
|
||||
try:
|
||||
spec = importlib.util.find_spec(packagename + "." + modname)
|
||||
except ValueError:
|
||||
spec = None
|
||||
if not errflag:
|
||||
errflag = True
|
||||
sys.stderr.write(progname + ": couldn't get loader for " + modname + "\n")
|
||||
if spec is None:
|
||||
continue
|
||||
if not isinstance(spec.loader, importlib.machinery.ExtensionFileLoader):
|
||||
continue
|
||||
# the module is definitely an extension module
|
||||
modules.append(modname)
|
||||
|
||||
# Give all PATH environment variable entries to add_dll_directory on Windows
|
||||
# This enable third-party libraries like OpenXR loader's DLL to be found easily.
|
||||
if os.name == "nt":
|
||||
for p in os.environ.get("PATH").split(';'):
|
||||
try:
|
||||
os.add_dll_directory(p)
|
||||
except Exception as e:
|
||||
print(f"Warning: Failed to add {p} as DLL search directory: ${e}")
|
||||
|
||||
# iterate through the modules in the package
|
||||
errflag = False
|
||||
for modname in modules:
|
||||
pyifile = os.path.join(basedir, modname + ext)
|
||||
if args.test:
|
||||
# test the syntax of the .pyi file
|
||||
flags = ast.PyCF_TYPE_COMMENTS if sys.hexversion >= 0x3080000 else 0
|
||||
with open(pyifile, 'r') as f:
|
||||
compile(f.read(), pyifile, 'exec', flags)
|
||||
else:
|
||||
# generate the .pyi file for the module
|
||||
mod = importlib.import_module(packagename + "." + modname)
|
||||
with open(pyifile, "w") as f:
|
||||
module_pyi(mod, f)
|
||||
|
||||
# add 'py.typed' to the package
|
||||
with open(os.path.join(basedir, 'py.typed'), 'w') as f:
|
||||
pass
|
||||
|
||||
if __name__ == '__main__':
|
||||
result = main(sys.argv)
|
||||
if result is not None:
|
||||
sys.exit(result)
|
||||
@@ -0,0 +1,545 @@
|
||||
"""
|
||||
Description:
|
||||
|
||||
This provides a VTK widget for pyGtk. This embeds a vtkRenderWindow
|
||||
inside a GTK widget. This is based on GtkVTKRenderWindow.py.
|
||||
|
||||
The extensions here allow the use of gtkglext rather than gtkgl and
|
||||
pygtk-2 rather than pygtk-0. It requires pygtk-2.0.0 or later.
|
||||
|
||||
There is a working example at the bottom.
|
||||
|
||||
Credits:
|
||||
|
||||
John Hunter <jdhunter@ace.bsd.uchicago.edu> developed and tested
|
||||
this code based on VTK's GtkVTKRenderWindow.py and extended it to
|
||||
work with pygtk-2.0.0.
|
||||
|
||||
License:
|
||||
|
||||
VTK license.
|
||||
|
||||
"""
|
||||
|
||||
import math, sys
|
||||
import pygtk
|
||||
pygtk.require('2.0')
|
||||
import gtk
|
||||
import gtk.gtkgl
|
||||
from gtk import gdk
|
||||
from vtkmodules.vtkRenderingCore import vtkActor, vtkCellPicker, vtkProperty, vtkRenderWindow
|
||||
|
||||
|
||||
class GtkGLExtVTKRenderWindowBase(gtk.gtkgl.DrawingArea):
|
||||
|
||||
""" A base class that enables one to embed a vtkRenderWindow into
|
||||
a pyGTK widget. This class embeds the RenderWindow correctly.
|
||||
Provided are some empty methods that can be overloaded to provide
|
||||
a user defined interaction behaviour. The event handling
|
||||
functions have names that are somewhat similar to the ones in the
|
||||
vtkInteractorStyle class included with VTK. """
|
||||
|
||||
def __init__(self, *args):
|
||||
gtk.gtkgl.DrawingArea.__init__(self)
|
||||
self.set_double_buffered(gtk.FALSE)
|
||||
|
||||
self._RenderWindow = vtkRenderWindow()
|
||||
# private attributes
|
||||
self.__Created = 0
|
||||
|
||||
# used by the LOD actors
|
||||
self._DesiredUpdateRate = 15
|
||||
self._StillUpdateRate = 0.0001
|
||||
|
||||
self.ConnectSignals()
|
||||
|
||||
# need this to be able to handle key_press events.
|
||||
self.set_flags(gtk.CAN_FOCUS)
|
||||
# default size
|
||||
self.set_size_request(300, 300)
|
||||
|
||||
def ConnectSignals(self):
|
||||
self.connect("realize", self.OnRealize)
|
||||
self.connect("expose_event", self.OnExpose)
|
||||
self.connect("configure_event", self.OnConfigure)
|
||||
self.connect("button_press_event", self.OnButtonDown)
|
||||
self.connect("button_release_event", self.OnButtonUp)
|
||||
self.connect("motion_notify_event", self.OnMouseMove)
|
||||
self.connect("enter_notify_event", self.OnEnter)
|
||||
self.connect("leave_notify_event", self.OnLeave)
|
||||
self.connect("key_press_event", self.OnKeyPress)
|
||||
self.connect("delete_event", self.OnDestroy)
|
||||
self.add_events(gdk.EXPOSURE_MASK|
|
||||
gdk.BUTTON_PRESS_MASK |
|
||||
gdk.BUTTON_RELEASE_MASK |
|
||||
gdk.KEY_PRESS_MASK |
|
||||
gdk.POINTER_MOTION_MASK |
|
||||
gdk.POINTER_MOTION_HINT_MASK |
|
||||
gdk.ENTER_NOTIFY_MASK |
|
||||
gdk.LEAVE_NOTIFY_MASK)
|
||||
|
||||
def GetRenderWindow(self):
|
||||
return self._RenderWindow
|
||||
|
||||
def GetRenderer(self):
|
||||
self._RenderWindow.GetRenderers().InitTraversal()
|
||||
return self._RenderWindow.GetRenderers().GetNextItem()
|
||||
|
||||
def SetDesiredUpdateRate(self, rate):
|
||||
"""Mirrors the method with the same name in
|
||||
vtkRenderWindowInteractor."""
|
||||
self._DesiredUpdateRate = rate
|
||||
|
||||
def GetDesiredUpdateRate(self):
|
||||
"""Mirrors the method with the same name in
|
||||
vtkRenderWindowInteractor."""
|
||||
return self._DesiredUpdateRate
|
||||
|
||||
def SetStillUpdateRate(self, rate):
|
||||
"""Mirrors the method with the same name in
|
||||
vtkRenderWindowInteractor."""
|
||||
self._StillUpdateRate = rate
|
||||
|
||||
def GetStillUpdateRate(self):
|
||||
"""Mirrors the method with the same name in
|
||||
vtkRenderWindowInteractor."""
|
||||
return self._StillUpdateRate
|
||||
|
||||
def Render(self):
|
||||
if self.__Created:
|
||||
self._RenderWindow.Render()
|
||||
|
||||
def OnRealize(self, *args):
|
||||
if self.__Created == 0:
|
||||
# you can't get the xid without the window being realized.
|
||||
self.realize()
|
||||
if sys.platform=='win32':
|
||||
win_id = str(self.widget.window.handle)
|
||||
else:
|
||||
win_id = str(self.widget.window.xid)
|
||||
self._RenderWindow.SetWindowInfo(win_id)
|
||||
self.__Created = 1
|
||||
return gtk.TRUE
|
||||
|
||||
def Created(self):
|
||||
return self.__Created
|
||||
|
||||
def OnConfigure(self, widget, event):
|
||||
self.widget=widget
|
||||
self._RenderWindow.SetSize(event.width, event.height)
|
||||
self.Render()
|
||||
return gtk.TRUE
|
||||
|
||||
def OnExpose(self, *args):
|
||||
self.Render()
|
||||
return gtk.TRUE
|
||||
|
||||
def OnDestroy(self, *args):
|
||||
self.hide()
|
||||
del self._RenderWindow
|
||||
self.destroy()
|
||||
return gtk.TRUE
|
||||
|
||||
def OnButtonDown(self, wid, event):
|
||||
"""Mouse button pressed."""
|
||||
self._RenderWindow.SetDesiredUpdateRate(self._DesiredUpdateRate)
|
||||
return gtk.TRUE
|
||||
|
||||
def OnButtonUp(self, wid, event):
|
||||
"""Mouse button released."""
|
||||
self._RenderWindow.SetDesiredUpdateRate(self._StillUpdateRate)
|
||||
return gtk.TRUE
|
||||
|
||||
def OnMouseMove(self, wid, event):
|
||||
"""Mouse has moved."""
|
||||
return gtk.TRUE
|
||||
|
||||
def OnEnter(self, wid, event):
|
||||
"""Entering the vtkRenderWindow."""
|
||||
return gtk.TRUE
|
||||
|
||||
def OnLeave(self, wid, event):
|
||||
"""Leaving the vtkRenderWindow."""
|
||||
return gtk.TRUE
|
||||
|
||||
def OnKeyPress(self, wid, event):
|
||||
"""Key pressed."""
|
||||
return gtk.TRUE
|
||||
|
||||
def OnKeyRelease(self, wid, event):
|
||||
"Key released."
|
||||
return gtk.TRUE
|
||||
|
||||
|
||||
class GtkGLExtVTKRenderWindow(GtkGLExtVTKRenderWindowBase):
|
||||
|
||||
""" An example of a fully functional GtkGLExtVTKRenderWindow that
|
||||
is based on the vtkRenderWidget.py provided with the VTK
|
||||
sources."""
|
||||
|
||||
def __init__(self, *args):
|
||||
GtkGLExtVTKRenderWindowBase.__init__(self)
|
||||
|
||||
self._CurrentRenderer = None
|
||||
self._CurrentCamera = None
|
||||
self._CurrentZoom = 1.0
|
||||
self._CurrentLight = None
|
||||
|
||||
self._ViewportCenterX = 0
|
||||
self._ViewportCenterY = 0
|
||||
|
||||
self._Picker = vtkCellPicker()
|
||||
self._PickedAssembly = None
|
||||
self._PickedProperty = vtkProperty()
|
||||
self._PickedProperty.SetColor(1, 0, 0)
|
||||
self._PrePickedProperty = None
|
||||
|
||||
self._OldFocus = None
|
||||
|
||||
# these record the previous mouse position
|
||||
self._LastX = 0
|
||||
self._LastY = 0
|
||||
|
||||
def OnButtonDown(self, wid, event):
|
||||
self._RenderWindow.SetDesiredUpdateRate(self._DesiredUpdateRate)
|
||||
return self.StartMotion(wid, event)
|
||||
return gtk.TRUE
|
||||
|
||||
def OnButtonUp(self, wid, event):
|
||||
self._RenderWindow.SetDesiredUpdateRate(self._StillUpdateRate)
|
||||
return self.EndMotion(wid, event)
|
||||
return gtk.TRUE
|
||||
|
||||
def OnMouseMove(self, wid, event=None):
|
||||
if ((event.state & gdk.BUTTON1_MASK) == gdk.BUTTON1_MASK):
|
||||
if ((event.state & gdk.SHIFT_MASK) == gdk.SHIFT_MASK):
|
||||
m = self.get_pointer()
|
||||
self.Pan(m[0], m[1])
|
||||
else:
|
||||
m = self.get_pointer()
|
||||
self.Rotate(m[0], m[1])
|
||||
elif ((event.state & gdk.BUTTON2_MASK) == gdk.BUTTON2_MASK):
|
||||
m = self.get_pointer()
|
||||
self.Pan(m[0], m[1])
|
||||
elif ((event.state & gdk.BUTTON3_MASK) == gdk.BUTTON3_MASK):
|
||||
m = self.get_pointer()
|
||||
self.Zoom(m[0], m[1])
|
||||
else:
|
||||
return gtk.FALSE
|
||||
|
||||
return gtk.TRUE
|
||||
|
||||
def OnEnter(self, wid, event=None):
|
||||
# a render hack because grab_focus blanks the renderwin
|
||||
self.grab_focus()
|
||||
w = self.get_pointer()
|
||||
self.UpdateRenderer(w[0], w[1])
|
||||
return gtk.TRUE
|
||||
|
||||
def OnKeyPress(self, wid, event=None):
|
||||
#if (event.keyval == gdk.keyval_from_name("q") or
|
||||
# event.keyval == gdk.keyval_from_name("Q")):
|
||||
# gtk.mainquit()
|
||||
|
||||
if (event.keyval == gdk.keyval_from_name('r') or
|
||||
event.keyval == gdk.keyval_from_name('R')):
|
||||
self.Reset()
|
||||
return gtk.TRUE
|
||||
elif (event.keyval == gdk.keyval_from_name('w') or
|
||||
event.keyval == gdk.keyval_from_name('W')):
|
||||
self.Wireframe()
|
||||
return gtk.TRUE
|
||||
elif (event.keyval == gdk.keyval_from_name('s') or
|
||||
event.keyval == gdk.keyval_from_name('S')):
|
||||
self.Surface()
|
||||
return gtk.TRUE
|
||||
elif (event.keyval == gdk.keyval_from_name('p') or
|
||||
event.keyval == gdk.keyval_from_name('P')):
|
||||
m = self.get_pointer()
|
||||
self.PickActor(m[0], m[1])
|
||||
return gtk.TRUE
|
||||
else:
|
||||
return gtk.FALSE
|
||||
|
||||
def GetZoomFactor(self):
|
||||
return self._CurrentZoom
|
||||
|
||||
def SetZoomFactor(self, zf):
|
||||
self._CurrentZoom = zf
|
||||
|
||||
def GetPicker(self):
|
||||
return self._Picker
|
||||
|
||||
def Render(self):
|
||||
if (self._CurrentLight):
|
||||
light = self._CurrentLight
|
||||
light.SetPosition(self._CurrentCamera.GetPosition())
|
||||
light.SetFocalPoint(self._CurrentCamera.GetFocalPoint())
|
||||
|
||||
GtkGLExtVTKRenderWindowBase.Render(self)
|
||||
|
||||
|
||||
def UpdateRenderer(self,x,y):
|
||||
"""
|
||||
UpdateRenderer will identify the renderer under the mouse and set
|
||||
up _CurrentRenderer, _CurrentCamera, and _CurrentLight.
|
||||
"""
|
||||
windowX,windowY = self.widget.window.get_size()
|
||||
|
||||
renderers = self._RenderWindow.GetRenderers()
|
||||
numRenderers = renderers.GetNumberOfItems()
|
||||
|
||||
self._CurrentRenderer = None
|
||||
renderers.InitTraversal()
|
||||
for i in range(0,numRenderers):
|
||||
renderer = renderers.GetNextItem()
|
||||
vx,vy = (0,0)
|
||||
if (windowX > 1):
|
||||
vx = float(x)/(windowX-1)
|
||||
if (windowY > 1):
|
||||
vy = (windowY-float(y)-1)/(windowY-1)
|
||||
(vpxmin,vpymin,vpxmax,vpymax) = renderer.GetViewport()
|
||||
|
||||
if (vx >= vpxmin and vx <= vpxmax and
|
||||
vy >= vpymin and vy <= vpymax):
|
||||
self._CurrentRenderer = renderer
|
||||
self._ViewportCenterX = float(windowX)*(vpxmax-vpxmin)/2.0\
|
||||
+vpxmin
|
||||
self._ViewportCenterY = float(windowY)*(vpymax-vpymin)/2.0\
|
||||
+vpymin
|
||||
self._CurrentCamera = self._CurrentRenderer.GetActiveCamera()
|
||||
lights = self._CurrentRenderer.GetLights()
|
||||
lights.InitTraversal()
|
||||
self._CurrentLight = lights.GetNextItem()
|
||||
break
|
||||
|
||||
self._LastX = x
|
||||
self._LastY = y
|
||||
|
||||
def GetCurrentRenderer(self):
|
||||
if self._CurrentRenderer is None:
|
||||
renderers = self._RenderWindow.GetRenderers()
|
||||
numRenderers = renderers.GetNumberOfItems()
|
||||
|
||||
renderers.InitTraversal()
|
||||
for i in range(0,numRenderers):
|
||||
renderer = renderers.GetNextItem()
|
||||
break
|
||||
self._CurrentRenderer = renderer
|
||||
return self._CurrentRenderer
|
||||
|
||||
def GetCurrentCamera(self):
|
||||
if self._CurrentCamera is None:
|
||||
renderer = self.GetCurrentRenderer()
|
||||
self._CurrentCamera = renderer.GetActiveCamera()
|
||||
return self._CurrentCamera
|
||||
|
||||
def StartMotion(self, wid, event=None):
|
||||
x = event.x
|
||||
y = event.y
|
||||
self.UpdateRenderer(x,y)
|
||||
return gtk.TRUE
|
||||
|
||||
def EndMotion(self, wid, event=None):
|
||||
if self._CurrentRenderer:
|
||||
self.Render()
|
||||
return gtk.TRUE
|
||||
|
||||
def Rotate(self,x,y):
|
||||
if self._CurrentRenderer:
|
||||
|
||||
self._CurrentCamera.Azimuth(self._LastX - x)
|
||||
self._CurrentCamera.Elevation(y - self._LastY)
|
||||
self._CurrentCamera.OrthogonalizeViewUp()
|
||||
|
||||
self._LastX = x
|
||||
self._LastY = y
|
||||
|
||||
self._CurrentRenderer.ResetCameraClippingRange()
|
||||
self.Render()
|
||||
|
||||
def Pan(self,x,y):
|
||||
if self._CurrentRenderer:
|
||||
|
||||
renderer = self._CurrentRenderer
|
||||
camera = self._CurrentCamera
|
||||
(pPoint0,pPoint1,pPoint2) = camera.GetPosition()
|
||||
(fPoint0,fPoint1,fPoint2) = camera.GetFocalPoint()
|
||||
|
||||
if (camera.GetParallelProjection()):
|
||||
renderer.SetWorldPoint(fPoint0,fPoint1,fPoint2,1.0)
|
||||
renderer.WorldToDisplay()
|
||||
fx,fy,fz = renderer.GetDisplayPoint()
|
||||
renderer.SetDisplayPoint(fx-x+self._LastX,
|
||||
fy+y-self._LastY,
|
||||
fz)
|
||||
renderer.DisplayToWorld()
|
||||
fx,fy,fz,fw = renderer.GetWorldPoint()
|
||||
camera.SetFocalPoint(fx,fy,fz)
|
||||
|
||||
renderer.SetWorldPoint(pPoint0,pPoint1,pPoint2,1.0)
|
||||
renderer.WorldToDisplay()
|
||||
fx,fy,fz = renderer.GetDisplayPoint()
|
||||
renderer.SetDisplayPoint(fx-x+self._LastX,
|
||||
fy+y-self._LastY,
|
||||
fz)
|
||||
renderer.DisplayToWorld()
|
||||
fx,fy,fz,fw = renderer.GetWorldPoint()
|
||||
camera.SetPosition(fx,fy,fz)
|
||||
|
||||
else:
|
||||
(fPoint0,fPoint1,fPoint2) = camera.GetFocalPoint()
|
||||
# Specify a point location in world coordinates
|
||||
renderer.SetWorldPoint(fPoint0,fPoint1,fPoint2,1.0)
|
||||
renderer.WorldToDisplay()
|
||||
# Convert world point coordinates to display coordinates
|
||||
dPoint = renderer.GetDisplayPoint()
|
||||
focalDepth = dPoint[2]
|
||||
|
||||
aPoint0 = self._ViewportCenterX + (x - self._LastX)
|
||||
aPoint1 = self._ViewportCenterY - (y - self._LastY)
|
||||
|
||||
renderer.SetDisplayPoint(aPoint0,aPoint1,focalDepth)
|
||||
renderer.DisplayToWorld()
|
||||
|
||||
(rPoint0,rPoint1,rPoint2,rPoint3) = renderer.GetWorldPoint()
|
||||
if (rPoint3 != 0.0):
|
||||
rPoint0 = rPoint0/rPoint3
|
||||
rPoint1 = rPoint1/rPoint3
|
||||
rPoint2 = rPoint2/rPoint3
|
||||
|
||||
camera.SetFocalPoint((fPoint0 - rPoint0) + fPoint0,
|
||||
(fPoint1 - rPoint1) + fPoint1,
|
||||
(fPoint2 - rPoint2) + fPoint2)
|
||||
|
||||
camera.SetPosition((fPoint0 - rPoint0) + pPoint0,
|
||||
(fPoint1 - rPoint1) + pPoint1,
|
||||
(fPoint2 - rPoint2) + pPoint2)
|
||||
|
||||
self._LastX = x
|
||||
self._LastY = y
|
||||
|
||||
self.Render()
|
||||
|
||||
def Zoom(self,x,y):
|
||||
if self._CurrentRenderer:
|
||||
|
||||
renderer = self._CurrentRenderer
|
||||
camera = self._CurrentCamera
|
||||
|
||||
zoomFactor = math.pow(1.02,(0.5*(self._LastY - y)))
|
||||
self._CurrentZoom = self._CurrentZoom * zoomFactor
|
||||
|
||||
if camera.GetParallelProjection():
|
||||
parallelScale = camera.GetParallelScale()/zoomFactor
|
||||
camera.SetParallelScale(parallelScale)
|
||||
else:
|
||||
camera.Dolly(zoomFactor)
|
||||
renderer.ResetCameraClippingRange()
|
||||
|
||||
self._LastX = x
|
||||
self._LastY = y
|
||||
|
||||
self.Render()
|
||||
|
||||
def Reset(self):
|
||||
if self._CurrentRenderer:
|
||||
self._CurrentRenderer.ResetCamera()
|
||||
|
||||
self.Render()
|
||||
|
||||
def Wireframe(self):
|
||||
actors = self._CurrentRenderer.GetActors()
|
||||
numActors = actors.GetNumberOfItems()
|
||||
actors.InitTraversal()
|
||||
for i in range(0,numActors):
|
||||
actor = actors.GetNextItem()
|
||||
actor.GetProperty().SetRepresentationToWireframe()
|
||||
|
||||
self.Render()
|
||||
|
||||
def Surface(self):
|
||||
actors = self._CurrentRenderer.GetActors()
|
||||
numActors = actors.GetNumberOfItems()
|
||||
actors.InitTraversal()
|
||||
for i in range(0,numActors):
|
||||
actor = actors.GetNextItem()
|
||||
actor.GetProperty().SetRepresentationToSurface()
|
||||
|
||||
self.Render()
|
||||
|
||||
def PickActor(self,x,y):
|
||||
if self._CurrentRenderer:
|
||||
|
||||
renderer = self._CurrentRenderer
|
||||
picker = self._Picker
|
||||
|
||||
windowX,windowY = self.widget.window.get_size()
|
||||
picker.Pick(x,(windowY - y - 1),0.0,renderer)
|
||||
assembly = picker.GetAssembly()
|
||||
|
||||
if (self._PickedAssembly != None and
|
||||
self._PrePickedProperty != None):
|
||||
self._PickedAssembly.SetProperty(self._PrePickedProperty)
|
||||
# release hold of the property
|
||||
self._PrePickedProperty.UnRegister(self._PrePickedProperty)
|
||||
self._PrePickedProperty = None
|
||||
|
||||
if (assembly != None):
|
||||
self._PickedAssembly = assembly
|
||||
self._PrePickedProperty = self._PickedAssembly.GetProperty()
|
||||
# hold onto the property
|
||||
self._PrePickedProperty.Register(self._PrePickedProperty)
|
||||
self._PickedAssembly.SetProperty(self._PickedProperty)
|
||||
|
||||
self.Render()
|
||||
|
||||
|
||||
def main():
|
||||
from vtkmodules.vtkFiltersSources import vtkConeSource
|
||||
from vtkmodules.vtkRenderingCore import vtkActor, vtkPolyDataMapper, vtkRenderer
|
||||
# load implementations for rendering and interaction factory classes
|
||||
import vtkmodules.vtkRenderingOpenGL2
|
||||
import vtkmodules.vtkInteractionStyle
|
||||
|
||||
# The main window
|
||||
window = gtk.Window()
|
||||
window.set_title("A GtkGLExtVTKRenderWindow Demo!")
|
||||
window.connect("destroy", gtk.mainquit)
|
||||
window.connect("delete_event", gtk.mainquit)
|
||||
window.set_border_width(10)
|
||||
|
||||
vtkgtk = GtkGLExtVTKRenderWindow()
|
||||
vtkgtk.show()
|
||||
|
||||
vbox = gtk.VBox(spacing=3)
|
||||
vbox.show()
|
||||
vbox.pack_start(vtkgtk)
|
||||
|
||||
button = gtk.Button('My Button')
|
||||
button.show()
|
||||
vbox.pack_start(button)
|
||||
window.add(vbox)
|
||||
|
||||
window.set_size_request(400, 400)
|
||||
|
||||
# The VTK stuff.
|
||||
cone = vtkConeSource()
|
||||
cone.SetResolution(80)
|
||||
coneMapper = vtkPolyDataMapper()
|
||||
coneMapper.SetInputConnection(cone.GetOutputPort())
|
||||
#coneActor = vtkLODActor()
|
||||
coneActor = vtkActor()
|
||||
coneActor.SetMapper(coneMapper)
|
||||
coneActor.GetProperty().SetColor(0.5, 0.5, 1.0)
|
||||
ren = vtkRenderer()
|
||||
vtkgtk.GetRenderWindow().AddRenderer(ren)
|
||||
ren.AddActor(coneActor)
|
||||
|
||||
# show the main window and start event processing.
|
||||
window.show()
|
||||
gtk.mainloop()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
+311
@@ -0,0 +1,311 @@
|
||||
"""
|
||||
Description:
|
||||
|
||||
Provides a pyGtk vtkRenderWindowInteractor widget. This embeds a
|
||||
vtkRenderWindow inside a GTK widget and uses the
|
||||
vtkGenericRenderWindowInteractor for the event handling. This is
|
||||
similar to GtkVTKRenderWindowInteractor.py.
|
||||
|
||||
The extensions here allow the use of gtkglext rather than gtkgl and
|
||||
pygtk-2 rather than pygtk-0. It requires pygtk-2.0.0 or later.
|
||||
|
||||
There is a working example at the bottom.
|
||||
|
||||
Credits:
|
||||
|
||||
John Hunter <jdhunter@ace.bsd.uchicago.edu> developed and tested
|
||||
this code based on VTK's GtkVTKRenderWindow.py and extended it to
|
||||
work with pygtk-2.0.0.
|
||||
|
||||
License:
|
||||
|
||||
VTK license.
|
||||
|
||||
"""
|
||||
|
||||
import sys
|
||||
import pygtk
|
||||
pygtk.require('2.0')
|
||||
import gtk
|
||||
from gtk import gdk
|
||||
import gtk.gtkgl
|
||||
from vtkmodules.vtkRenderingCore import vtkRenderWindow
|
||||
from vtkmodules.vtkRenderingUI import vtkGenericRenderWindowInteractor
|
||||
|
||||
class GtkGLExtVTKRenderWindowInteractor(gtk.gtkgl.DrawingArea):
|
||||
|
||||
""" Embeds a vtkRenderWindow into a pyGTK widget and uses
|
||||
vtkGenericRenderWindowInteractor for the event handling. This
|
||||
class embeds the RenderWindow correctly. A __getattr__ hook is
|
||||
provided that makes the class behave like a
|
||||
vtkGenericRenderWindowInteractor."""
|
||||
|
||||
def __init__(self, *args):
|
||||
gtk.gtkgl.DrawingArea.__init__(self)
|
||||
|
||||
self.set_double_buffered(gtk.FALSE)
|
||||
|
||||
self._RenderWindow = vtkRenderWindow()
|
||||
|
||||
# private attributes
|
||||
self.__Created = 0
|
||||
self._ActiveButton = 0
|
||||
|
||||
self._Iren = vtkGenericRenderWindowInteractor()
|
||||
self._Iren.SetRenderWindow(self._RenderWindow)
|
||||
self._Iren.GetInteractorStyle().SetCurrentStyleToTrackballCamera()
|
||||
self._Iren.AddObserver('CreateTimerEvent', self.CreateTimer)
|
||||
self._Iren.AddObserver('DestroyTimerEvent', self.DestroyTimer)
|
||||
self.ConnectSignals()
|
||||
|
||||
# need this to be able to handle key_press events.
|
||||
self.set_flags(gtk.CAN_FOCUS)
|
||||
|
||||
def set_size_request(self, w, h):
|
||||
gtk.gtkgl.DrawingArea.set_size_request(self, w, h)
|
||||
self._RenderWindow.SetSize(w, h)
|
||||
self._Iren.SetSize(w, h)
|
||||
self._Iren.ConfigureEvent()
|
||||
|
||||
def ConnectSignals(self):
|
||||
self.connect("realize", self.OnRealize)
|
||||
self.connect("expose_event", self.OnExpose)
|
||||
self.connect("configure_event", self.OnConfigure)
|
||||
self.connect("button_press_event", self.OnButtonDown)
|
||||
self.connect("button_release_event", self.OnButtonUp)
|
||||
self.connect("motion_notify_event", self.OnMouseMove)
|
||||
self.connect("enter_notify_event", self.OnEnter)
|
||||
self.connect("leave_notify_event", self.OnLeave)
|
||||
self.connect("key_press_event", self.OnKeyPress)
|
||||
self.connect("delete_event", self.OnDestroy)
|
||||
self.add_events(gdk.EXPOSURE_MASK| gdk.BUTTON_PRESS_MASK |
|
||||
gdk.BUTTON_RELEASE_MASK |
|
||||
gdk.KEY_PRESS_MASK |
|
||||
gdk.POINTER_MOTION_MASK |
|
||||
gdk.POINTER_MOTION_HINT_MASK |
|
||||
gdk.ENTER_NOTIFY_MASK | gdk.LEAVE_NOTIFY_MASK)
|
||||
|
||||
def __getattr__(self, attr):
|
||||
"""Makes the object behave like a
|
||||
vtkGenericRenderWindowInteractor"""
|
||||
if attr == '__vtk__':
|
||||
return lambda t=self._Iren: t
|
||||
elif hasattr(self._Iren, attr):
|
||||
return getattr(self._Iren, attr)
|
||||
else:
|
||||
raise AttributeError(self.__class__.__name__ +
|
||||
" has no attribute named " + attr)
|
||||
|
||||
def CreateTimer(self, obj, event):
|
||||
gtk.timeout_add(10, self._Iren.TimerEvent)
|
||||
|
||||
def DestroyTimer(self, obj, event):
|
||||
"""The timer is a one shot timer so will expire automatically."""
|
||||
return 1
|
||||
|
||||
def GetRenderWindow(self):
|
||||
return self._RenderWindow
|
||||
|
||||
def Render(self):
|
||||
if self.__Created:
|
||||
self._RenderWindow.Render()
|
||||
|
||||
def OnRealize(self, *args):
|
||||
if self.__Created == 0:
|
||||
# you can't get the xid without the window being realized.
|
||||
self.realize()
|
||||
if sys.platform=='win32':
|
||||
win_id = str(self.widget.window.handle)
|
||||
else:
|
||||
win_id = str(self.widget.window.xid)
|
||||
|
||||
self._RenderWindow.SetWindowInfo(win_id)
|
||||
#self._Iren.Initialize()
|
||||
self.__Created = 1
|
||||
return gtk.TRUE
|
||||
|
||||
def OnConfigure(self, widget, event):
|
||||
self.widget=widget
|
||||
self._Iren.SetSize(event.width, event.height)
|
||||
self._Iren.ConfigureEvent()
|
||||
self.Render()
|
||||
return gtk.TRUE
|
||||
|
||||
def OnExpose(self, *args):
|
||||
self.Render()
|
||||
return gtk.TRUE
|
||||
|
||||
def OnDestroy(self, event=None):
|
||||
self.hide()
|
||||
del self._RenderWindow
|
||||
self.destroy()
|
||||
return gtk.TRUE
|
||||
|
||||
def _GetCtrlShift(self, event):
|
||||
ctrl, shift = 0, 0
|
||||
if ((event.state & gdk.CONTROL_MASK) == gdk.CONTROL_MASK):
|
||||
ctrl = 1
|
||||
if ((event.state & gdk.SHIFT_MASK) == gdk.SHIFT_MASK):
|
||||
shift = 1
|
||||
return ctrl, shift
|
||||
|
||||
def OnButtonDown(self, wid, event):
|
||||
"""Mouse button pressed."""
|
||||
m = self.get_pointer()
|
||||
ctrl, shift = self._GetCtrlShift(event)
|
||||
self._Iren.SetEventInformationFlipY(m[0], m[1], ctrl, shift,
|
||||
chr(0), 0, None)
|
||||
button = event.button
|
||||
if button == 3:
|
||||
self._Iren.RightButtonPressEvent()
|
||||
return gtk.TRUE
|
||||
elif button == 1:
|
||||
self._Iren.LeftButtonPressEvent()
|
||||
return gtk.TRUE
|
||||
elif button == 2:
|
||||
self._Iren.MiddleButtonPressEvent()
|
||||
return gtk.TRUE
|
||||
else:
|
||||
return gtk.FALSE
|
||||
|
||||
def OnButtonUp(self, wid, event):
|
||||
"""Mouse button released."""
|
||||
m = self.get_pointer()
|
||||
ctrl, shift = self._GetCtrlShift(event)
|
||||
self._Iren.SetEventInformationFlipY(m[0], m[1], ctrl, shift,
|
||||
chr(0), 0, None)
|
||||
button = event.button
|
||||
if button == 3:
|
||||
self._Iren.RightButtonReleaseEvent()
|
||||
return gtk.TRUE
|
||||
elif button == 1:
|
||||
self._Iren.LeftButtonReleaseEvent()
|
||||
return gtk.TRUE
|
||||
elif button == 2:
|
||||
self._Iren.MiddleButtonReleaseEvent()
|
||||
return gtk.TRUE
|
||||
|
||||
return gtk.FALSE
|
||||
|
||||
def OnMouseMove(self, wid, event):
|
||||
"""Mouse has moved."""
|
||||
m = self.get_pointer()
|
||||
ctrl, shift = self._GetCtrlShift(event)
|
||||
self._Iren.SetEventInformationFlipY(m[0], m[1], ctrl, shift,
|
||||
chr(0), 0, None)
|
||||
self._Iren.MouseMoveEvent()
|
||||
return gtk.TRUE
|
||||
|
||||
def OnEnter(self, wid, event):
|
||||
"""Entering the vtkRenderWindow."""
|
||||
self.grab_focus()
|
||||
m = self.get_pointer()
|
||||
ctrl, shift = self._GetCtrlShift(event)
|
||||
self._Iren.SetEventInformationFlipY(m[0], m[1], ctrl, shift,
|
||||
chr(0), 0, None)
|
||||
self._Iren.EnterEvent()
|
||||
return gtk.TRUE
|
||||
|
||||
def OnLeave(self, wid, event):
|
||||
"""Leaving the vtkRenderWindow."""
|
||||
m = self.get_pointer()
|
||||
ctrl, shift = self._GetCtrlShift(event)
|
||||
self._Iren.SetEventInformationFlipY(m[0], m[1], ctrl, shift,
|
||||
chr(0), 0, None)
|
||||
self._Iren.LeaveEvent()
|
||||
return gtk.TRUE
|
||||
|
||||
def OnKeyPress(self, wid, event):
|
||||
"""Key pressed."""
|
||||
m = self.get_pointer()
|
||||
ctrl, shift = self._GetCtrlShift(event)
|
||||
keycode, keysym = event.keyval, event.string
|
||||
key = chr(0)
|
||||
if keycode < 256:
|
||||
key = chr(keycode)
|
||||
self._Iren.SetEventInformationFlipY(m[0], m[1], ctrl, shift,
|
||||
key, 0, keysym)
|
||||
self._Iren.KeyPressEvent()
|
||||
self._Iren.CharEvent()
|
||||
return gtk.TRUE
|
||||
|
||||
def OnKeyRelease(self, wid, event):
|
||||
"Key released."
|
||||
m = self.get_pointer()
|
||||
ctrl, shift = self._GetCtrlShift(event)
|
||||
keycode, keysym = event.keyval, event.string
|
||||
key = chr(0)
|
||||
if keycode < 256:
|
||||
key = chr(keycode)
|
||||
self._Iren.SetEventInformationFlipY(m[0], m[1], ctrl, shift,
|
||||
key, 0, keysym)
|
||||
self._Iren.KeyReleaseEvent()
|
||||
return gtk.TRUE
|
||||
|
||||
def Initialize(self):
|
||||
if self.__Created:
|
||||
self._Iren.Initialize()
|
||||
|
||||
def SetPicker(self, picker):
|
||||
self._Iren.SetPicker(picker)
|
||||
|
||||
def GetPicker(self, picker):
|
||||
return self._Iren.GetPicker()
|
||||
|
||||
|
||||
def main():
|
||||
from vtkmodules.vtkFiltersSources import vtkConeSource
|
||||
from vtkmodules.vtkRenderingCore import vtkActor, vtkPolyDataMapper, vtkRenderer
|
||||
# load implementations for rendering and interaction factory classes
|
||||
import vtkmodules.vtkRenderingOpenGL2
|
||||
import vtkmodules.vtkInteractionStyle
|
||||
|
||||
# The main window
|
||||
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
|
||||
window.set_title("A GtkVTKRenderWindow Demo!")
|
||||
window.connect("destroy", gtk.mainquit)
|
||||
window.connect("delete_event", gtk.mainquit)
|
||||
window.set_border_width(10)
|
||||
|
||||
# A VBox into which widgets are packed.
|
||||
vbox = gtk.VBox(spacing=3)
|
||||
window.add(vbox)
|
||||
vbox.show()
|
||||
|
||||
# The GtkVTKRenderWindow
|
||||
gvtk = GtkGLExtVTKRenderWindowInteractor()
|
||||
#gvtk.SetDesiredUpdateRate(1000)
|
||||
gvtk.set_size_request(400, 400)
|
||||
vbox.pack_start(gvtk)
|
||||
gvtk.show()
|
||||
gvtk.Initialize()
|
||||
gvtk.Start()
|
||||
# prevents 'q' from exiting the app.
|
||||
gvtk.AddObserver("ExitEvent", lambda o,e,x=None: x)
|
||||
|
||||
# The VTK stuff.
|
||||
cone = vtkConeSource()
|
||||
cone.SetResolution(80)
|
||||
coneMapper = vtkPolyDataMapper()
|
||||
coneMapper.SetInputConnection(cone.GetOutputPort())
|
||||
#coneActor = vtkLODActor()
|
||||
coneActor = vtkActor()
|
||||
coneActor.SetMapper(coneMapper)
|
||||
coneActor.GetProperty().SetColor(0.5, 0.5, 1.0)
|
||||
ren = vtkRenderer()
|
||||
gvtk.GetRenderWindow().AddRenderer(ren)
|
||||
ren.AddActor(coneActor)
|
||||
|
||||
# A simple quit button
|
||||
quit = gtk.Button("Quit!")
|
||||
quit.connect("clicked", gtk.mainquit)
|
||||
vbox.pack_start(quit)
|
||||
quit.show()
|
||||
|
||||
# show the main window and start event processing.
|
||||
window.show()
|
||||
gtk.mainloop()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,535 @@
|
||||
"""
|
||||
Description:
|
||||
|
||||
Provides a simple VTK widget for pyGtk. This embeds a
|
||||
vtkRenderWindow inside a GTK widget. This is based on
|
||||
vtkTkRenderWidget.py. The GtkVTKRenderWindowBase class provides the
|
||||
abstraction necessary for someone to use their own interaction
|
||||
behaviour. The method names are similar to those in
|
||||
vtkInteractorStyle.h.
|
||||
|
||||
The class uses the gtkgl.GtkGLArea widget (gtkglarea). This avoids
|
||||
a lot of problems with flicker.
|
||||
|
||||
There is a working example at the bottom.
|
||||
|
||||
Credits:
|
||||
|
||||
Thanks to Dave Reed for testing the code under various platforms and
|
||||
for his suggestion to use the GtkGLArea widget to avoid flicker
|
||||
related issues.
|
||||
|
||||
Created by Prabhu Ramachandran, March 2001.
|
||||
|
||||
Using GtkGLArea, March, 2002.
|
||||
|
||||
Bugs:
|
||||
|
||||
(*) There is a focus related problem. Tkinter has a focus object
|
||||
that handles focus events. I don't know of an equivalent object
|
||||
under GTK. So, when an 'enter_notify_event' is received on the
|
||||
GtkVTKRenderWindow I grab the focus but I don't know what to do when
|
||||
I get a 'leave_notify_event'.
|
||||
|
||||
(*) Will not work under Win32 because it uses the XID of a window in
|
||||
OnRealize. Suggestions to fix this will be appreciated.
|
||||
|
||||
"""
|
||||
|
||||
import gtk, GDK, gtkgl
|
||||
from vtkmodules.vtkRenderingCore import vtkCellPicker, vtkProperty, vtkRenderWindow
|
||||
import math
|
||||
|
||||
|
||||
class GtkVTKRenderWindowBase(gtkgl.GtkGLArea):
|
||||
|
||||
""" A base class that enables one to embed a vtkRenderWindow into
|
||||
a pyGTK widget. This class embeds the RenderWindow correctly.
|
||||
Provided are some empty methods that can be overloaded to provide
|
||||
a user defined interaction behaviour. The event handling
|
||||
functions have names that are somewhat similar to the ones in the
|
||||
vtkInteractorStyle class included with VTK. """
|
||||
|
||||
def __init__(self, *args):
|
||||
l = list(args)
|
||||
attr = (gtkgl.RGBA, gtkgl.DOUBLEBUFFER)
|
||||
l.insert(0, self)
|
||||
l.insert(1, attr)
|
||||
apply(gtkgl.GtkGLArea.__init__, l)
|
||||
self._RenderWindow = vtkRenderWindow()
|
||||
|
||||
# private attributes
|
||||
self.__Created = 0
|
||||
|
||||
# used by the LOD actors
|
||||
self._DesiredUpdateRate = 15
|
||||
self._StillUpdateRate = 0.0001
|
||||
|
||||
self.ConnectSignals()
|
||||
|
||||
# need this to be able to handle key_press events.
|
||||
self.set_flags(gtk.CAN_FOCUS)
|
||||
# default size
|
||||
self.set_usize(300, 300)
|
||||
|
||||
def ConnectSignals(self):
|
||||
self.connect("realize", self.OnRealize)
|
||||
self.connect("expose_event", self.OnExpose)
|
||||
self.connect("configure_event", self.OnConfigure)
|
||||
self.connect("button_press_event", self.OnButtonDown)
|
||||
self.connect("button_release_event", self.OnButtonUp)
|
||||
self.connect("motion_notify_event", self.OnMouseMove)
|
||||
self.connect("enter_notify_event", self.OnEnter)
|
||||
self.connect("leave_notify_event", self.OnLeave)
|
||||
self.connect("key_press_event", self.OnKeyPress)
|
||||
self.connect("delete_event", self.OnDestroy)
|
||||
self.add_events(GDK.EXPOSURE_MASK| GDK.BUTTON_PRESS_MASK |
|
||||
GDK.BUTTON_RELEASE_MASK |
|
||||
GDK.KEY_PRESS_MASK |
|
||||
GDK.POINTER_MOTION_MASK |
|
||||
GDK.POINTER_MOTION_HINT_MASK |
|
||||
GDK.ENTER_NOTIFY_MASK | GDK.LEAVE_NOTIFY_MASK)
|
||||
|
||||
def GetRenderWindow(self):
|
||||
return self._RenderWindow
|
||||
|
||||
def GetRenderer(self):
|
||||
self._RenderWindow.GetRenderers().InitTraversal()
|
||||
return self._RenderWindow.GetRenderers().GetNextItem()
|
||||
|
||||
def SetDesiredUpdateRate(self, rate):
|
||||
"""Mirrors the method with the same name in
|
||||
vtkRenderWindowInteractor."""
|
||||
self._DesiredUpdateRate = rate
|
||||
|
||||
def GetDesiredUpdateRate(self):
|
||||
"""Mirrors the method with the same name in
|
||||
vtkRenderWindowInteractor."""
|
||||
return self._DesiredUpdateRate
|
||||
|
||||
def SetStillUpdateRate(self, rate):
|
||||
"""Mirrors the method with the same name in
|
||||
vtkRenderWindowInteractor."""
|
||||
self._StillUpdateRate = rate
|
||||
|
||||
def GetStillUpdateRate(self):
|
||||
"""Mirrors the method with the same name in
|
||||
vtkRenderWindowInteractor."""
|
||||
return self._StillUpdateRate
|
||||
|
||||
def Render(self):
|
||||
if self.__Created:
|
||||
self._RenderWindow.Render()
|
||||
|
||||
def OnRealize(self, *args):
|
||||
if self.__Created == 0:
|
||||
# you can't get the xid without the window being realized.
|
||||
self.realize()
|
||||
win_id = str(self.get_window().xid)
|
||||
self._RenderWindow.SetWindowInfo(win_id)
|
||||
self.__Created = 1
|
||||
return gtk.TRUE
|
||||
|
||||
def OnConfigure(self, wid, event=None):
|
||||
sz = self._RenderWindow.GetSize()
|
||||
if (event.width != sz[0]) or (event.height != sz[1]):
|
||||
self._RenderWindow.SetSize(event.width, event.height)
|
||||
return gtk.TRUE
|
||||
|
||||
def OnExpose(self, *args):
|
||||
self.Render()
|
||||
return gtk.TRUE
|
||||
|
||||
def OnDestroy(self, event=None):
|
||||
self.hide()
|
||||
del self._RenderWindow
|
||||
self.destroy()
|
||||
return gtk.TRUE
|
||||
|
||||
def OnButtonDown(self, wid, event):
|
||||
"""Mouse button pressed."""
|
||||
self._RenderWindow.SetDesiredUpdateRate(self._DesiredUpdateRate)
|
||||
return gtk.TRUE
|
||||
|
||||
def OnButtonUp(self, wid, event):
|
||||
"""Mouse button released."""
|
||||
self._RenderWindow.SetDesiredUpdateRate(self._StillUpdateRate)
|
||||
return gtk.TRUE
|
||||
|
||||
def OnMouseMove(self, wid, event):
|
||||
"""Mouse has moved."""
|
||||
return gtk.TRUE
|
||||
|
||||
def OnEnter(self, wid, event):
|
||||
"""Entering the vtkRenderWindow."""
|
||||
return gtk.TRUE
|
||||
|
||||
def OnLeave(self, wid, event):
|
||||
"""Leaving the vtkRenderWindow."""
|
||||
return gtk.TRUE
|
||||
|
||||
def OnKeyPress(self, wid, event):
|
||||
"""Key pressed."""
|
||||
return gtk.TRUE
|
||||
|
||||
def OnKeyRelease(self, wid, event):
|
||||
"Key released."
|
||||
return gtk.TRUE
|
||||
|
||||
|
||||
class GtkVTKRenderWindow(GtkVTKRenderWindowBase):
|
||||
|
||||
""" An example of a fully functional GtkVTKRenderWindow that is
|
||||
based on the vtkRenderWidget.py provided with the VTK sources."""
|
||||
|
||||
def __init__(self, *args):
|
||||
l = list(args)
|
||||
l.insert(0, self)
|
||||
apply(GtkVTKRenderWindowBase.__init__, l)
|
||||
|
||||
self._CurrentRenderer = None
|
||||
self._CurrentCamera = None
|
||||
self._CurrentZoom = 1.0
|
||||
self._CurrentLight = None
|
||||
|
||||
self._ViewportCenterX = 0
|
||||
self._ViewportCenterY = 0
|
||||
|
||||
self._Picker = vtkCellPicker()
|
||||
self._PickedAssembly = None
|
||||
self._PickedProperty = vtkProperty()
|
||||
self._PickedProperty.SetColor(1, 0, 0)
|
||||
self._PrePickedProperty = None
|
||||
|
||||
self._OldFocus = None
|
||||
|
||||
# these record the previous mouse position
|
||||
self._LastX = 0
|
||||
self._LastY = 0
|
||||
|
||||
def OnButtonDown(self, wid, event):
|
||||
self._RenderWindow.SetDesiredUpdateRate(self._DesiredUpdateRate)
|
||||
return self.StartMotion(wid, event)
|
||||
|
||||
def OnButtonUp(self, wid, event):
|
||||
self._RenderWindow.SetDesiredUpdateRate(self._StillUpdateRate)
|
||||
return self.EndMotion(wid, event)
|
||||
|
||||
def OnMouseMove(self, wid, event=None):
|
||||
if ((event.state & GDK.BUTTON1_MASK) == GDK.BUTTON1_MASK):
|
||||
if ((event.state & GDK.SHIFT_MASK) == GDK.SHIFT_MASK):
|
||||
m = self.get_pointer()
|
||||
self.Pan(m[0], m[1])
|
||||
return gtk.TRUE
|
||||
else:
|
||||
m = self.get_pointer()
|
||||
self.Rotate(m[0], m[1])
|
||||
return gtk.TRUE
|
||||
elif ((event.state & GDK.BUTTON2_MASK) == GDK.BUTTON2_MASK):
|
||||
m = self.get_pointer()
|
||||
self.Pan(m[0], m[1])
|
||||
return gtk.TRUE
|
||||
elif ((event.state & GDK.BUTTON3_MASK) == GDK.BUTTON3_MASK):
|
||||
m = self.get_pointer()
|
||||
self.Zoom(m[0], m[1])
|
||||
return gtk.TRUE
|
||||
else:
|
||||
return gtk.FALSE
|
||||
|
||||
def OnEnter(self, wid, event=None):
|
||||
self.grab_focus()
|
||||
w = self.get_pointer()
|
||||
self.UpdateRenderer(w[0], w[1])
|
||||
return gtk.TRUE
|
||||
|
||||
def OnLeave(self, wid, event):
|
||||
return gtk.TRUE
|
||||
|
||||
def OnKeyPress(self, wid, event=None):
|
||||
if (event.keyval == GDK.r) or (event.keyval == GDK.R):
|
||||
self.Reset()
|
||||
return gtk.TRUE
|
||||
elif (event.keyval == GDK.w) or (event.keyval == GDK.W):
|
||||
self.Wireframe()
|
||||
return gtk.TRUE
|
||||
elif (event.keyval == GDK.s) or (event.keyval == GDK.S):
|
||||
self.Surface()
|
||||
return gtk.TRUE
|
||||
elif (event.keyval == GDK.p) or (event.keyval == GDK.P):
|
||||
m = self.get_pointer()
|
||||
self.PickActor(m[0], m[1])
|
||||
return gtk.TRUE
|
||||
else:
|
||||
return gtk.FALSE
|
||||
|
||||
def GetZoomFactor(self):
|
||||
return self._CurrentZoom
|
||||
|
||||
def SetZoomFactor(self, zf):
|
||||
self._CurrentZoom = zf
|
||||
|
||||
def GetPicker(self):
|
||||
return self._Picker
|
||||
|
||||
def Render(self):
|
||||
if (self._CurrentLight):
|
||||
light = self._CurrentLight
|
||||
light.SetPosition(self._CurrentCamera.GetPosition())
|
||||
light.SetFocalPoint(self._CurrentCamera.GetFocalPoint())
|
||||
|
||||
GtkVTKRenderWindowBase.Render(self)
|
||||
|
||||
def UpdateRenderer(self,x,y):
|
||||
"""
|
||||
UpdateRenderer will identify the renderer under the mouse and set
|
||||
up _CurrentRenderer, _CurrentCamera, and _CurrentLight.
|
||||
"""
|
||||
windowX = self.get_window().width
|
||||
windowY = self.get_window().height
|
||||
|
||||
renderers = self._RenderWindow.GetRenderers()
|
||||
numRenderers = renderers.GetNumberOfItems()
|
||||
|
||||
self._CurrentRenderer = None
|
||||
renderers.InitTraversal()
|
||||
for i in range(0,numRenderers):
|
||||
renderer = renderers.GetNextItem()
|
||||
vx,vy = (0,0)
|
||||
if (windowX > 1):
|
||||
vx = float(x)/(windowX-1)
|
||||
if (windowY > 1):
|
||||
vy = (windowY-float(y)-1)/(windowY-1)
|
||||
(vpxmin,vpymin,vpxmax,vpymax) = renderer.GetViewport()
|
||||
|
||||
if (vx >= vpxmin and vx <= vpxmax and
|
||||
vy >= vpymin and vy <= vpymax):
|
||||
self._CurrentRenderer = renderer
|
||||
self._ViewportCenterX = float(windowX)*(vpxmax-vpxmin)/2.0\
|
||||
+vpxmin
|
||||
self._ViewportCenterY = float(windowY)*(vpymax-vpymin)/2.0\
|
||||
+vpymin
|
||||
self._CurrentCamera = self._CurrentRenderer.GetActiveCamera()
|
||||
lights = self._CurrentRenderer.GetLights()
|
||||
lights.InitTraversal()
|
||||
self._CurrentLight = lights.GetNextItem()
|
||||
break
|
||||
|
||||
self._LastX = x
|
||||
self._LastY = y
|
||||
|
||||
def GetCurrentRenderer(self):
|
||||
return self._CurrentRenderer
|
||||
|
||||
def StartMotion(self, wid, event=None):
|
||||
x = event.x
|
||||
y = event.y
|
||||
self.UpdateRenderer(x,y)
|
||||
return gtk.TRUE
|
||||
|
||||
def EndMotion(self, wid, event=None):
|
||||
if self._CurrentRenderer:
|
||||
self.Render()
|
||||
return gtk.TRUE
|
||||
|
||||
def Rotate(self,x,y):
|
||||
if self._CurrentRenderer:
|
||||
|
||||
self._CurrentCamera.Azimuth(self._LastX - x)
|
||||
self._CurrentCamera.Elevation(y - self._LastY)
|
||||
self._CurrentCamera.OrthogonalizeViewUp()
|
||||
|
||||
self._LastX = x
|
||||
self._LastY = y
|
||||
|
||||
self._CurrentRenderer.ResetCameraClippingRange()
|
||||
self.Render()
|
||||
|
||||
def Pan(self,x,y):
|
||||
if self._CurrentRenderer:
|
||||
|
||||
renderer = self._CurrentRenderer
|
||||
camera = self._CurrentCamera
|
||||
(pPoint0,pPoint1,pPoint2) = camera.GetPosition()
|
||||
(fPoint0,fPoint1,fPoint2) = camera.GetFocalPoint()
|
||||
|
||||
if (camera.GetParallelProjection()):
|
||||
renderer.SetWorldPoint(fPoint0,fPoint1,fPoint2,1.0)
|
||||
renderer.WorldToDisplay()
|
||||
fx,fy,fz = renderer.GetDisplayPoint()
|
||||
renderer.SetDisplayPoint(fx-x+self._LastX,
|
||||
fy+y-self._LastY,
|
||||
fz)
|
||||
renderer.DisplayToWorld()
|
||||
fx,fy,fz,fw = renderer.GetWorldPoint()
|
||||
camera.SetFocalPoint(fx,fy,fz)
|
||||
|
||||
renderer.SetWorldPoint(pPoint0,pPoint1,pPoint2,1.0)
|
||||
renderer.WorldToDisplay()
|
||||
fx,fy,fz = renderer.GetDisplayPoint()
|
||||
renderer.SetDisplayPoint(fx-x+self._LastX,
|
||||
fy+y-self._LastY,
|
||||
fz)
|
||||
renderer.DisplayToWorld()
|
||||
fx,fy,fz,fw = renderer.GetWorldPoint()
|
||||
camera.SetPosition(fx,fy,fz)
|
||||
|
||||
else:
|
||||
(fPoint0,fPoint1,fPoint2) = camera.GetFocalPoint()
|
||||
# Specify a point location in world coordinates
|
||||
renderer.SetWorldPoint(fPoint0,fPoint1,fPoint2,1.0)
|
||||
renderer.WorldToDisplay()
|
||||
# Convert world point coordinates to display coordinates
|
||||
dPoint = renderer.GetDisplayPoint()
|
||||
focalDepth = dPoint[2]
|
||||
|
||||
aPoint0 = self._ViewportCenterX + (x - self._LastX)
|
||||
aPoint1 = self._ViewportCenterY - (y - self._LastY)
|
||||
|
||||
renderer.SetDisplayPoint(aPoint0,aPoint1,focalDepth)
|
||||
renderer.DisplayToWorld()
|
||||
|
||||
(rPoint0,rPoint1,rPoint2,rPoint3) = renderer.GetWorldPoint()
|
||||
if (rPoint3 != 0.0):
|
||||
rPoint0 = rPoint0/rPoint3
|
||||
rPoint1 = rPoint1/rPoint3
|
||||
rPoint2 = rPoint2/rPoint3
|
||||
|
||||
camera.SetFocalPoint((fPoint0 - rPoint0) + fPoint0,
|
||||
(fPoint1 - rPoint1) + fPoint1,
|
||||
(fPoint2 - rPoint2) + fPoint2)
|
||||
|
||||
camera.SetPosition((fPoint0 - rPoint0) + pPoint0,
|
||||
(fPoint1 - rPoint1) + pPoint1,
|
||||
(fPoint2 - rPoint2) + pPoint2)
|
||||
|
||||
self._LastX = x
|
||||
self._LastY = y
|
||||
|
||||
self.Render()
|
||||
|
||||
def Zoom(self,x,y):
|
||||
if self._CurrentRenderer:
|
||||
|
||||
renderer = self._CurrentRenderer
|
||||
camera = self._CurrentCamera
|
||||
|
||||
zoomFactor = math.pow(1.02,(0.5*(self._LastY - y)))
|
||||
self._CurrentZoom = self._CurrentZoom * zoomFactor
|
||||
|
||||
if camera.GetParallelProjection():
|
||||
parallelScale = camera.GetParallelScale()/zoomFactor
|
||||
camera.SetParallelScale(parallelScale)
|
||||
else:
|
||||
camera.Dolly(zoomFactor)
|
||||
renderer.ResetCameraClippingRange()
|
||||
|
||||
self._LastX = x
|
||||
self._LastY = y
|
||||
|
||||
self.Render()
|
||||
|
||||
def Reset(self):
|
||||
if self._CurrentRenderer:
|
||||
self._CurrentRenderer.ResetCamera()
|
||||
|
||||
self.Render()
|
||||
|
||||
def Wireframe(self):
|
||||
actors = self._CurrentRenderer.GetActors()
|
||||
numActors = actors.GetNumberOfItems()
|
||||
actors.InitTraversal()
|
||||
for i in range(0,numActors):
|
||||
actor = actors.GetNextItem()
|
||||
actor.GetProperty().SetRepresentationToWireframe()
|
||||
|
||||
self.Render()
|
||||
|
||||
def Surface(self):
|
||||
actors = self._CurrentRenderer.GetActors()
|
||||
numActors = actors.GetNumberOfItems()
|
||||
actors.InitTraversal()
|
||||
for i in range(0,numActors):
|
||||
actor = actors.GetNextItem()
|
||||
actor.GetProperty().SetRepresentationToSurface()
|
||||
|
||||
self.Render()
|
||||
|
||||
def PickActor(self,x,y):
|
||||
if self._CurrentRenderer:
|
||||
|
||||
renderer = self._CurrentRenderer
|
||||
picker = self._Picker
|
||||
|
||||
windowY = self.get_window().height
|
||||
picker.Pick(x,(windowY - y - 1),0.0,renderer)
|
||||
assembly = picker.GetAssembly()
|
||||
|
||||
if (self._PickedAssembly != None and
|
||||
self._PrePickedProperty != None):
|
||||
self._PickedAssembly.SetProperty(self._PrePickedProperty)
|
||||
# release hold of the property
|
||||
self._PrePickedProperty.UnRegister(self._PrePickedProperty)
|
||||
self._PrePickedProperty = None
|
||||
|
||||
if (assembly != None):
|
||||
self._PickedAssembly = assembly
|
||||
self._PrePickedProperty = self._PickedAssembly.GetProperty()
|
||||
# hold onto the property
|
||||
self._PrePickedProperty.Register(self._PrePickedProperty)
|
||||
self._PickedAssembly.SetProperty(self._PickedProperty)
|
||||
|
||||
self.Render()
|
||||
|
||||
|
||||
def main():
|
||||
from vtkmodules.vtkFiltersSources import vtkConeSource
|
||||
from vtkmodules.vtkRenderingCore import vtkActor, vtkPolyDataMapper, vtkRenderer
|
||||
# load implementations for rendering and interaction factory classes
|
||||
import vtkmodules.vtkRenderingOpenGL2
|
||||
import vtkmodules.vtkInteractionStyle
|
||||
|
||||
# The main window
|
||||
window = gtk.GtkWindow(gtk.WINDOW_TOPLEVEL)
|
||||
window.set_title("A GtkVTKRenderWindow Demo!")
|
||||
window.connect("destroy", gtk.mainquit)
|
||||
window.connect("delete_event", gtk.mainquit)
|
||||
window.set_border_width(10)
|
||||
|
||||
# A VBox into which widgets are packed.
|
||||
vbox = gtk.GtkVBox(spacing=3)
|
||||
window.add(vbox)
|
||||
vbox.show()
|
||||
|
||||
# The GtkVTKRenderWindow
|
||||
gvtk = GtkVTKRenderWindow()
|
||||
#gvtk.SetDesiredUpdateRate(1000)
|
||||
gvtk.set_usize(400, 400)
|
||||
vbox.pack_start(gvtk)
|
||||
gvtk.show()
|
||||
|
||||
# The VTK stuff.
|
||||
cone = vtkConeSource()
|
||||
cone.SetResolution(80)
|
||||
coneMapper = vtkPolyDataMapper()
|
||||
coneMapper.SetInputConnection(cone.GetOutputPort())
|
||||
#coneActor = vtkLODActor()
|
||||
coneActor = vtkActor()
|
||||
coneActor.SetMapper(coneMapper)
|
||||
coneActor.GetProperty().SetColor(0.5, 0.5, 1.0)
|
||||
ren = vtkRenderer()
|
||||
gvtk.GetRenderWindow().AddRenderer(ren)
|
||||
ren.AddActor(coneActor)
|
||||
|
||||
# A simple quit button
|
||||
quit = gtk.GtkButton("Quit!")
|
||||
quit.connect("clicked", gtk.mainquit)
|
||||
vbox.pack_start(quit)
|
||||
quit.show()
|
||||
|
||||
# show the main window and start event processing.
|
||||
window.show()
|
||||
gtk.mainloop()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,303 @@
|
||||
"""
|
||||
Description:
|
||||
|
||||
Provides a pyGtk vtkRenderWindowInteractor widget. This embeds a
|
||||
vtkRenderWindow inside a GTK widget and uses the
|
||||
vtkGenericRenderWindowInteractor for the event handling. This is
|
||||
based on vtkTkRenderWindow.py.
|
||||
|
||||
The class uses the gtkgl.GtkGLArea widget (gtkglarea). This avoids
|
||||
a lot of problems with flicker.
|
||||
|
||||
There is a working example at the bottom.
|
||||
|
||||
Created by Prabhu Ramachandran, April 2002.
|
||||
|
||||
Bugs:
|
||||
|
||||
(*) There is a focus related problem. Tkinter has a focus object
|
||||
that handles focus events. I don't know of an equivalent object
|
||||
under GTK. So, when an 'enter_notify_event' is received on the
|
||||
GtkVTKRenderWindow I grab the focus but I don't know what to do when
|
||||
I get a 'leave_notify_event'.
|
||||
|
||||
(*) Will not work under Win32 because it uses the XID of a window in
|
||||
OnRealize. Suggestions to fix this will be appreciated.
|
||||
|
||||
"""
|
||||
|
||||
import gtk, GDK, gtkgl
|
||||
from vtkmodules.vtkRenderingUI import vtkGenericRenderWindowInteractor
|
||||
import math
|
||||
|
||||
|
||||
class GtkVTKRenderWindowInteractor(gtkgl.GtkGLArea):
|
||||
|
||||
""" Embeds a vtkRenderWindow into a pyGTK widget and uses
|
||||
vtkGenericRenderWindowInteractor for the event handling. This
|
||||
class embeds the RenderWindow correctly. A __getattr__ hook is
|
||||
provided that makes the class behave like a
|
||||
vtkGenericRenderWindowInteractor."""
|
||||
|
||||
def __init__(self, *args):
|
||||
l = list(args)
|
||||
attr = (gtkgl.RGBA, gtkgl.DOUBLEBUFFER)
|
||||
l.insert(0, self)
|
||||
l.insert(1, attr)
|
||||
apply(gtkgl.GtkGLArea.__init__, l)
|
||||
self._RenderWindow = vtkRenderWindow()
|
||||
|
||||
# private attributes
|
||||
self.__Created = 0
|
||||
self._ActiveButton = 0
|
||||
|
||||
self._Iren = vtkGenericRenderWindowInteractor()
|
||||
self._Iren.SetRenderWindow(self._RenderWindow)
|
||||
|
||||
self._Iren.AddObserver('CreateTimerEvent', self.CreateTimer)
|
||||
self._Iren.AddObserver('DestroyTimerEvent', self.DestroyTimer)
|
||||
self.ConnectSignals()
|
||||
|
||||
# need this to be able to handle key_press events.
|
||||
self.set_flags(gtk.CAN_FOCUS)
|
||||
# default size
|
||||
self.set_usize(300, 300)
|
||||
|
||||
def set_usize(self, w, h):
|
||||
gtkgl.GtkGLArea.set_usize(self, w, h)
|
||||
self._RenderWindow.SetSize(w, h)
|
||||
self._Iren.SetSize(w, h)
|
||||
self._Iren.ConfigureEvent()
|
||||
|
||||
def ConnectSignals(self):
|
||||
self.connect("realize", self.OnRealize)
|
||||
self.connect("expose_event", self.OnExpose)
|
||||
self.connect("configure_event", self.OnConfigure)
|
||||
self.connect("button_press_event", self.OnButtonDown)
|
||||
self.connect("button_release_event", self.OnButtonUp)
|
||||
self.connect("motion_notify_event", self.OnMouseMove)
|
||||
self.connect("enter_notify_event", self.OnEnter)
|
||||
self.connect("leave_notify_event", self.OnLeave)
|
||||
self.connect("key_press_event", self.OnKeyPress)
|
||||
self.connect("delete_event", self.OnDestroy)
|
||||
self.add_events(GDK.EXPOSURE_MASK| GDK.BUTTON_PRESS_MASK |
|
||||
GDK.BUTTON_RELEASE_MASK |
|
||||
GDK.KEY_PRESS_MASK |
|
||||
GDK.POINTER_MOTION_MASK |
|
||||
GDK.POINTER_MOTION_HINT_MASK |
|
||||
GDK.ENTER_NOTIFY_MASK | GDK.LEAVE_NOTIFY_MASK)
|
||||
|
||||
def __getattr__(self, attr):
|
||||
"""Makes the object behave like a
|
||||
vtkGenericRenderWindowInteractor"""
|
||||
if attr == '__vtk__':
|
||||
return lambda t=self._Iren: t
|
||||
elif hasattr(self._Iren, attr):
|
||||
return getattr(self._Iren, attr)
|
||||
else:
|
||||
raise AttributeError(self.__class__.__name__ +
|
||||
" has no attribute named " + attr)
|
||||
|
||||
def CreateTimer(self, obj, event):
|
||||
gtk.timeout_add(10, self._Iren.TimerEvent)
|
||||
|
||||
def DestroyTimer(self, obj, event):
|
||||
"""The timer is a one shot timer so will expire automatically."""
|
||||
return 1
|
||||
|
||||
def GetRenderWindow(self):
|
||||
return self._RenderWindow
|
||||
|
||||
def Render(self):
|
||||
if self.__Created:
|
||||
self._RenderWindow.Render()
|
||||
|
||||
def OnRealize(self, *args):
|
||||
if self.__Created == 0:
|
||||
# you can't get the xid without the window being realized.
|
||||
self.realize()
|
||||
win_id = str(self.get_window().xid)
|
||||
self._RenderWindow.SetWindowInfo(win_id)
|
||||
self._Iren.Initialize()
|
||||
self.__Created = 1
|
||||
return gtk.TRUE
|
||||
|
||||
def OnConfigure(self, wid, event=None):
|
||||
sz = self._RenderWindow.GetSize()
|
||||
if (event.width != sz[0]) or (event.height != sz[1]):
|
||||
self._Iren.SetSize(event.width, event.height)
|
||||
self._Iren.ConfigureEvent()
|
||||
return gtk.TRUE
|
||||
|
||||
def OnExpose(self, *args):
|
||||
self.Render()
|
||||
return gtk.TRUE
|
||||
|
||||
def OnDestroy(self, event=None):
|
||||
self.hide()
|
||||
del self._RenderWindow
|
||||
self.destroy()
|
||||
return gtk.TRUE
|
||||
|
||||
def _GetCtrlShift(self, event):
|
||||
ctrl, shift = 0, 0
|
||||
if ((event.state & GDK.CONTROL_MASK) == GDK.CONTROL_MASK):
|
||||
ctrl = 1
|
||||
if ((event.state & GDK.SHIFT_MASK) == GDK.SHIFT_MASK):
|
||||
shift = 1
|
||||
return ctrl, shift
|
||||
|
||||
def OnButtonDown(self, wid, event):
|
||||
"""Mouse button pressed."""
|
||||
m = self.get_pointer()
|
||||
ctrl, shift = self._GetCtrlShift(event)
|
||||
self._Iren.SetEventInformationFlipY(m[0], m[1], ctrl, shift,
|
||||
chr(0), 0, None)
|
||||
button = event.button
|
||||
if button == 3:
|
||||
self._Iren.RightButtonPressEvent()
|
||||
return gtk.TRUE
|
||||
elif button == 1:
|
||||
self._Iren.LeftButtonPressEvent()
|
||||
return gtk.TRUE
|
||||
elif button == 2:
|
||||
self._Iren.MiddleButtonPressEvent()
|
||||
return gtk.TRUE
|
||||
else:
|
||||
return gtk.FALSE
|
||||
|
||||
def OnButtonUp(self, wid, event):
|
||||
"""Mouse button released."""
|
||||
m = self.get_pointer()
|
||||
ctrl, shift = self._GetCtrlShift(event)
|
||||
self._Iren.SetEventInformationFlipY(m[0], m[1], ctrl, shift,
|
||||
chr(0), 0, None)
|
||||
button = event.button
|
||||
if button == 3:
|
||||
self._Iren.RightButtonReleaseEvent()
|
||||
return gtk.TRUE
|
||||
elif button == 1:
|
||||
self._Iren.LeftButtonReleaseEvent()
|
||||
return gtk.TRUE
|
||||
elif button == 2:
|
||||
self._Iren.MiddleButtonReleaseEvent()
|
||||
return gtk.TRUE
|
||||
|
||||
return gtk.FALSE
|
||||
|
||||
def OnMouseMove(self, wid, event):
|
||||
"""Mouse has moved."""
|
||||
m = self.get_pointer()
|
||||
ctrl, shift = self._GetCtrlShift(event)
|
||||
self._Iren.SetEventInformationFlipY(m[0], m[1], ctrl, shift,
|
||||
chr(0), 0, None)
|
||||
self._Iren.MouseMoveEvent()
|
||||
return gtk.TRUE
|
||||
|
||||
def OnEnter(self, wid, event):
|
||||
"""Entering the vtkRenderWindow."""
|
||||
self.grab_focus()
|
||||
m = self.get_pointer()
|
||||
ctrl, shift = self._GetCtrlShift(event)
|
||||
self._Iren.SetEventInformationFlipY(m[0], m[1], ctrl, shift,
|
||||
chr(0), 0, None)
|
||||
self._Iren.EnterEvent()
|
||||
return gtk.TRUE
|
||||
|
||||
def OnLeave(self, wid, event):
|
||||
"""Leaving the vtkRenderWindow."""
|
||||
m = self.get_pointer()
|
||||
ctrl, shift = self._GetCtrlShift(event)
|
||||
self._Iren.SetEventInformationFlipY(m[0], m[1], ctrl, shift,
|
||||
chr(0), 0, None)
|
||||
self._Iren.LeaveEvent()
|
||||
return gtk.TRUE
|
||||
|
||||
def OnKeyPress(self, wid, event):
|
||||
"""Key pressed."""
|
||||
m = self.get_pointer()
|
||||
ctrl, shift = self._GetCtrlShift(event)
|
||||
keycode, keysym = event.keyval, event.string
|
||||
key = chr(0)
|
||||
if keycode < 256:
|
||||
key = chr(keycode)
|
||||
self._Iren.SetEventInformationFlipY(m[0], m[1], ctrl, shift,
|
||||
key, 0, keysym)
|
||||
self._Iren.KeyPressEvent()
|
||||
self._Iren.CharEvent()
|
||||
return gtk.TRUE
|
||||
|
||||
def OnKeyRelease(self, wid, event):
|
||||
"Key released."
|
||||
m = self.get_pointer()
|
||||
ctrl, shift = self._GetCtrlShift(event)
|
||||
keycode, keysym = event.keyval, event.string
|
||||
key = chr(0)
|
||||
if keycode < 256:
|
||||
key = chr(keycode)
|
||||
self._Iren.SetEventInformationFlipY(m[0], m[1], ctrl, shift,
|
||||
key, 0, keysym)
|
||||
self._Iren.KeyReleaseEvent()
|
||||
return gtk.TRUE
|
||||
|
||||
def Initialize(self):
|
||||
if self.__Created:
|
||||
self._Iren.Initialize()
|
||||
|
||||
|
||||
def main():
|
||||
from vtkmodules.vtkFiltersSources import vtkConeSource
|
||||
from vtkmodules.vtkRenderingCore import vtkActor, vtkPolyDataMapper, vtkRenderer
|
||||
# load implementations for rendering and interaction factory classes
|
||||
import vtkmodules.vtkRenderingOpenGL2
|
||||
import vtkmodules.vtkInteractionStyle
|
||||
|
||||
# The main window
|
||||
window = gtk.GtkWindow(gtk.WINDOW_TOPLEVEL)
|
||||
window.set_title("A GtkVTKRenderWindow Demo!")
|
||||
window.connect("destroy", gtk.mainquit)
|
||||
window.connect("delete_event", gtk.mainquit)
|
||||
window.set_border_width(10)
|
||||
|
||||
# A VBox into which widgets are packed.
|
||||
vbox = gtk.GtkVBox(spacing=3)
|
||||
window.add(vbox)
|
||||
vbox.show()
|
||||
|
||||
# The GtkVTKRenderWindow
|
||||
gvtk = GtkVTKRenderWindowInteractor()
|
||||
#gvtk.SetDesiredUpdateRate(1000)
|
||||
gvtk.set_usize(400, 400)
|
||||
vbox.pack_start(gvtk)
|
||||
gvtk.show()
|
||||
gvtk.Initialize()
|
||||
gvtk.Start()
|
||||
# prevents 'q' from exiting the app.
|
||||
gvtk.AddObserver("ExitEvent", lambda o,e,x=None: x)
|
||||
|
||||
# The VTK stuff.
|
||||
cone = vtkConeSource()
|
||||
cone.SetResolution(80)
|
||||
coneMapper = vtkPolyDataMapper()
|
||||
coneMapper.SetInputConnection(cone.GetOutputPort())
|
||||
#coneActor = vtkLODActor()
|
||||
coneActor = vtkActor()
|
||||
coneActor.SetMapper(coneMapper)
|
||||
coneActor.GetProperty().SetColor(0.5, 0.5, 1.0)
|
||||
ren = vtkRenderer()
|
||||
gvtk.GetRenderWindow().AddRenderer(ren)
|
||||
ren.AddActor(coneActor)
|
||||
|
||||
# A simple quit button
|
||||
quit = gtk.GtkButton("Quit!")
|
||||
quit.connect("clicked", gtk.mainquit)
|
||||
vbox.pack_start(quit)
|
||||
quit.show()
|
||||
|
||||
# show the main window and start event processing.
|
||||
window.show()
|
||||
gtk.mainloop()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,4 @@
|
||||
"""pyGTK widgets for VTK."""
|
||||
|
||||
__all__ = ['GtkVTKRenderWindow', 'GtkVTKRenderWindowInteractor',
|
||||
'GtkGLExtVTKRenderWindow', 'GtkGLExtVTKRenderWindowInteractor']
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,3 @@
|
||||
"""Utility modules for the VTK-Python wrappers."""
|
||||
|
||||
__all__ = ['algorithms', 'dataset_adapter']
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,598 @@
|
||||
from __future__ import absolute_import
|
||||
from . import dataset_adapter as dsa
|
||||
import numpy
|
||||
from vtkmodules.util import numpy_support
|
||||
from vtkmodules.vtkCommonDataModel import vtkImageData
|
||||
from vtkmodules.vtkFiltersCore import vtkCellDataToPointData, vtkPolyDataNormals
|
||||
from vtkmodules.vtkFiltersGeneral import vtkCellDerivatives
|
||||
from vtkmodules.vtkFiltersVerdict import vtkCellSizeFilter, vtkCellQuality, vtkMatrixMathFilter
|
||||
|
||||
def _cell_derivatives (narray, dataset, attribute_type, filter):
|
||||
if not dataset :
|
||||
raise RuntimeError('Need a dataset to compute _cell_derivatives.')
|
||||
|
||||
# Reshape n dimensional vector to n by 1 matrix
|
||||
if len(narray.shape) == 1 :
|
||||
narray = narray.reshape((narray.shape[0], 1))
|
||||
|
||||
ncomp = narray.shape[1]
|
||||
if attribute_type == 'scalars' and ncomp != 1 :
|
||||
raise RuntimeError('This function expects scalars. ' +
|
||||
'Input shape ' + str(narray.shape))
|
||||
if attribute_type == 'vectors' and ncomp != 3 :
|
||||
raise RuntimeError('This function expects vectors. ' +
|
||||
'Input shape ' + str(narray.shape))
|
||||
|
||||
# numpy_to_vtk converts only contiguous arrays
|
||||
if not narray.flags.contiguous : narray = narray.copy()
|
||||
varray = numpy_support.numpy_to_vtk(narray)
|
||||
|
||||
if attribute_type == 'scalars': varray.SetName('scalars')
|
||||
else : varray.SetName('vectors')
|
||||
|
||||
# create a dataset with only our array but the same geometry/topology
|
||||
ds = dataset.NewInstance()
|
||||
ds.UnRegister(None)
|
||||
ds.CopyStructure(dataset.VTKObject)
|
||||
|
||||
if dsa.ArrayAssociation.FIELD == narray.Association :
|
||||
raise RuntimeError('Unknown data association. Data should be associated with points or cells.')
|
||||
|
||||
if dsa.ArrayAssociation.POINT == narray.Association :
|
||||
# Work on point data
|
||||
if narray.shape[0] != dataset.GetNumberOfPoints() :
|
||||
raise RuntimeError('The number of points does not match the number of tuples in the array')
|
||||
if attribute_type == 'scalars': ds.GetPointData().SetScalars(varray)
|
||||
else : ds.GetPointData().SetVectors(varray)
|
||||
elif dsa.ArrayAssociation.CELL == narray.Association :
|
||||
# Work on cell data
|
||||
if narray.shape[0] != dataset.GetNumberOfCells() :
|
||||
raise RuntimeError('The number of does not match the number of tuples in the array')
|
||||
|
||||
# Since vtkCellDerivatives only works with point data, we need to convert
|
||||
# the cell data to point data first.
|
||||
|
||||
ds2 = dataset.NewInstance()
|
||||
ds2.UnRegister(None)
|
||||
ds2.CopyStructure(dataset.VTKObject)
|
||||
|
||||
if attribute_type == 'scalars' : ds2.GetCellData().SetScalars(varray)
|
||||
else : ds2.GetCellData().SetVectors(varray)
|
||||
|
||||
c2p = vtkCellDataToPointData()
|
||||
c2p.SetInputData(ds2)
|
||||
c2p.Update()
|
||||
|
||||
# Set the output to the ds dataset
|
||||
if attribute_type == 'scalars':
|
||||
ds.GetPointData().SetScalars(c2p.GetOutput().GetPointData().GetScalars())
|
||||
else:
|
||||
ds.GetPointData().SetVectors(c2p.GetOutput().GetPointData().GetVectors())
|
||||
|
||||
filter.SetInputData(ds)
|
||||
|
||||
if dsa.ArrayAssociation.POINT == narray.Association :
|
||||
# Since the data is associated with cell and the query is on points
|
||||
# we have to convert to point data before returning
|
||||
c2p = vtkCellDataToPointData()
|
||||
c2p.SetInputConnection(filter.GetOutputPort())
|
||||
c2p.Update()
|
||||
return c2p.GetOutput().GetPointData()
|
||||
elif dsa.ArrayAssociation.CELL == narray.Association :
|
||||
filter.Update()
|
||||
return filter.GetOutput().GetCellData()
|
||||
else :
|
||||
# We shall never reach here
|
||||
raise RuntimeError('Unknown data association. Data should be associated with points or cells.')
|
||||
|
||||
def _cell_quality (dataset, quality) :
|
||||
if not dataset : raise RuntimeError('Need a dataset to compute _cell_quality')
|
||||
|
||||
# create a dataset with only our array but the same geometry/topology
|
||||
ds = dataset.NewInstance()
|
||||
ds.UnRegister(None)
|
||||
ds.CopyStructure(dataset.VTKObject)
|
||||
|
||||
filter = vtkCellQuality()
|
||||
filter.SetInputData(ds)
|
||||
|
||||
if "area" == quality : filter.SetQualityMeasureToArea()
|
||||
elif "aspect" == quality : filter.SetQualityMeasureToAspectRatio()
|
||||
elif "aspect_gamma" == quality : filter.SetQualityMeasureToAspectGamma()
|
||||
elif "condition" == quality : filter.SetQualityMeasureToCondition()
|
||||
elif "diagonal" == quality : filter.SetQualityMeasureToDiagonal()
|
||||
elif "jacobian" == quality : filter.SetQualityMeasureToJacobian()
|
||||
elif "max_angle" == quality : filter.SetQualityMeasureToMaxAngle()
|
||||
elif "shear" == quality : filter.SetQualityMeasureToShear()
|
||||
elif "skew" == quality : filter.SetQualityMeasureToSkew()
|
||||
elif "min_angle" == quality : filter.SetQualityMeasureToMinAngle()
|
||||
elif "volume" == quality : filter.SetQualityMeasureToVolume()
|
||||
else : raise RuntimeError('Unknown cell quality ['+quality+'].')
|
||||
|
||||
filter.Update()
|
||||
|
||||
varray = filter.GetOutput().GetCellData().GetArray("CellQuality")
|
||||
ans = dsa.vtkDataArrayToVTKArray(varray, dataset)
|
||||
|
||||
# The association information has been lost over the vtk filter
|
||||
# we must reconstruct it otherwise lower pipeline will be broken.
|
||||
ans.Association = dsa.ArrayAssociation.CELL
|
||||
|
||||
return ans
|
||||
|
||||
def _matrix_math_filter (narray, operation) :
|
||||
if operation not in ['Determinant', 'Inverse', 'Eigenvalue', 'Eigenvector'] :
|
||||
raise RuntimeError('Unknown quality measure ['+operation+']'+
|
||||
' Supported are [Determinant, Inverse, Eigenvalue, Eigenvector]')
|
||||
|
||||
if narray.ndim != 3 :
|
||||
raise RuntimeError(operation+' only works for an array of matrices(3D array).'+
|
||||
' Input shape ' + str(narray.shape))
|
||||
elif narray.shape[1] != narray.shape[2] :
|
||||
raise RuntimeError(operation+' requires an array of 2D square matrices.' +
|
||||
' Input shape ' + str(narray.shape))
|
||||
|
||||
# numpy_to_vtk converts only contiguous arrays
|
||||
if not narray.flags.contiguous : narray = narray.copy()
|
||||
|
||||
# Reshape is necessary because numpy_support.numpy_to_vtk only works with 2D or
|
||||
# less arrays.
|
||||
nrows = narray.shape[0]
|
||||
ncols = narray.shape[1] * narray.shape[2]
|
||||
narray = narray.reshape(nrows, ncols)
|
||||
|
||||
ds = vtkImageData()
|
||||
ds.SetDimensions(nrows, 1, 1)
|
||||
|
||||
varray = numpy_support.numpy_to_vtk(narray)
|
||||
varray.SetName('tensors')
|
||||
ds.GetPointData().SetTensors(varray)
|
||||
|
||||
filter = vtkMatrixMathFilter()
|
||||
|
||||
if operation == 'Determinant' : filter.SetOperationToDeterminant()
|
||||
elif operation == 'Inverse' : filter.SetOperationToInverse()
|
||||
elif operation == 'Eigenvalue' : filter.SetOperationToEigenvalue()
|
||||
elif operation == 'Eigenvector' : filter.SetOperationToEigenvector()
|
||||
|
||||
filter.SetInputData(ds)
|
||||
filter.Update()
|
||||
|
||||
varray = filter.GetOutput().GetPointData().GetArray(operation)
|
||||
|
||||
ans = dsa.vtkDataArrayToVTKArray(varray)
|
||||
|
||||
# The association information has been lost over the vtk filter
|
||||
# we must reconstruct it otherwise lower pipeline will be broken.
|
||||
ans.Association = narray.Association
|
||||
ans.DataSet = narray.DataSet
|
||||
|
||||
return ans
|
||||
|
||||
# Python interfaces
|
||||
def abs (narray) :
|
||||
"Returns the absolute values of an array of scalars/vectors/tensors."
|
||||
return numpy.abs(narray)
|
||||
|
||||
def all (narray, axis=None):
|
||||
"Returns the min value of an array of scalars/vectors/tensors."
|
||||
if narray is dsa.NoneArray:
|
||||
return dsa.NoneArray
|
||||
ans = numpy.all(numpy.array(narray), axis)
|
||||
return ans
|
||||
|
||||
def area (dataset) :
|
||||
"Returns the surface area of each cell in a mesh."
|
||||
return _cell_quality(dataset, "area")
|
||||
|
||||
def aspect (dataset) :
|
||||
"Returns the aspect ratio of each cell in a mesh."
|
||||
return _cell_quality(dataset, "aspect")
|
||||
|
||||
def aspect_gamma (dataset) :
|
||||
"Returns the aspect ratio gamma of each cell in a mesh."
|
||||
return _cell_quality(dataset, "aspect_gamma")
|
||||
|
||||
def condition (dataset) :
|
||||
"Returns the condition number of each cell in a mesh."
|
||||
return _cell_quality(dataset, "condition")
|
||||
|
||||
def cross (x, y) :
|
||||
"Return the cross product for two 3D vectors from two arrays of 3D vectors."
|
||||
if x is dsa.NoneArray or y is dsa.NoneArray:
|
||||
return dsa.NoneArray
|
||||
|
||||
if x.ndim != y.ndim or x.shape != y.shape:
|
||||
raise RuntimeError('Both operands must have same dimension and shape.' +
|
||||
' Input shapes ' + str(x.shape) + ' and ' + str(y.shape))
|
||||
|
||||
if x.ndim != 1 and x.ndim != 2 :
|
||||
raise RuntimeError('Cross only works for 3D vectors or an array of 3D vectors.' +
|
||||
' Input shapes ' + str(x.shape) + ' and ' + str(y.shape))
|
||||
|
||||
if x.ndim == 1 and x.shape[0] != 3 :
|
||||
raise RuntimeError('Cross only works for 3D vectors.' +
|
||||
' Input shapes ' + str(x.shape) + ' and ' + str(y.shape))
|
||||
|
||||
if x.ndim == 2 and x.shape[1] != 3 :
|
||||
raise RuntimeError('Cross only works for an array of 3D vectors.' +
|
||||
'Input shapes ' + str(x.shape) + ' and ' + str(y.shape))
|
||||
|
||||
return numpy.cross(x, y)
|
||||
|
||||
def curl (narray, dataset=None):
|
||||
"Returns the curl of an array of 3D vectors."
|
||||
if not dataset : dataset = narray.DataSet
|
||||
if not dataset : raise RuntimeError('Need a dataset to compute curl.')
|
||||
|
||||
if narray.ndim != 2 or narray.shape[1] != 3 :
|
||||
raise RuntimeError('Curl only works with an array of 3D vectors.' +
|
||||
'Input shape ' + str(narray.shape))
|
||||
|
||||
cd = vtkCellDerivatives()
|
||||
cd.SetVectorModeToComputeVorticity()
|
||||
|
||||
res = _cell_derivatives(narray, dataset, 'vectors', cd)
|
||||
|
||||
retVal = res.GetVectors()
|
||||
retVal.SetName("vorticity")
|
||||
|
||||
ans = dsa.vtkDataArrayToVTKArray(retVal, dataset)
|
||||
|
||||
# The association information has been lost over the vtk filter
|
||||
# we must reconstruct it otherwise lower pipeline will be broken.
|
||||
ans.Association = narray.Association
|
||||
|
||||
return ans
|
||||
|
||||
def divergence (narray, dataset=None):
|
||||
"Returns the divergence of an array of 3D vectors."
|
||||
if not dataset : dataset = narray.DataSet
|
||||
if not dataset : raise RuntimeError('Need a dataset to compute divergence')
|
||||
|
||||
if narray.ndim != 2 or narray.shape[1] != 3 :
|
||||
raise RuntimeError('Divergence only works with an array of 3D vectors.' +
|
||||
' Input shape ' + str(narray.shape))
|
||||
|
||||
g = gradient(narray, dataset)
|
||||
g = g.reshape(g.shape[0], 3, 3)
|
||||
|
||||
a = dsa.VTKArray\
|
||||
(numpy.add.reduce(g.diagonal(axis1=1, axis2=2), 1), dataset=g.DataSet)
|
||||
try:
|
||||
a.Association = g.Association
|
||||
except AttributeError: pass
|
||||
return a
|
||||
|
||||
|
||||
def det (narray) :
|
||||
"Returns the determinant of an array of 2D square matrices."
|
||||
return _matrix_math_filter(narray, "Determinant")
|
||||
|
||||
def determinant (narray) :
|
||||
"Returns the determinant of an array of 2D square matrices."
|
||||
return det(narray)
|
||||
|
||||
def diagonal (dataset) :
|
||||
"Returns the diagonal length of each cell in a dataset."
|
||||
return _cell_quality(dataset, "diagonal")
|
||||
|
||||
def dot (a1, a2):
|
||||
"Returns the dot product of two scalars/vectors of two array of scalars/vectors."
|
||||
if a1 is dsa.NoneArray or a2 is dsa.NoneArray:
|
||||
return dsa.NoneArray
|
||||
|
||||
if a1.shape[1] != a2.shape[1] :
|
||||
raise RuntimeError('Dot product only works with vectors of same dimension.' +
|
||||
' Input shapes ' + str(a1.shape) + ' and ' + str(a2.shape))
|
||||
m = a1*a2
|
||||
va = dsa.VTKArray(numpy.add.reduce(m, 1))
|
||||
if hasattr(m, "Association"):
|
||||
va.Association = m.Association
|
||||
if a1.DataSet == a2.DataSet : va.DataSet = a1.DataSet
|
||||
return va
|
||||
|
||||
def eigenvalue (narray) :
|
||||
"Returns the eigenvalue of an array of 2D square matrices."
|
||||
return _matrix_math_filter(narray, "Eigenvalue")
|
||||
|
||||
def eigenvector (narray) :
|
||||
"Returns the eigenvector of an array of 2D square matrices."
|
||||
return _matrix_math_filter(narray, "Eigenvector")
|
||||
|
||||
def gradient(narray, dataset=None):
|
||||
"Returns the gradient of an array of scalars/vectors."
|
||||
if not dataset: dataset = narray.DataSet
|
||||
if not dataset: raise RuntimeError('Need a dataset to compute gradient')
|
||||
|
||||
try:
|
||||
ncomp = narray.shape[1]
|
||||
except IndexError:
|
||||
ncomp = 1
|
||||
if ncomp != 1 and ncomp != 3:
|
||||
raise RuntimeError('Gradient only works with scalars (1 component) and vectors (3 component)' +
|
||||
' Input shape ' + str(narray.shape))
|
||||
|
||||
cd = vtkCellDerivatives()
|
||||
if ncomp == 1 : attribute_type = 'scalars'
|
||||
else : attribute_type = 'vectors'
|
||||
|
||||
res = _cell_derivatives(narray, dataset, attribute_type, cd)
|
||||
|
||||
if ncomp == 1 : retVal = res.GetVectors()
|
||||
else : retVal = res.GetTensors()
|
||||
|
||||
try:
|
||||
if narray.GetName() : retVal.SetName("gradient of " + narray.GetName())
|
||||
else : retVal.SetName("gradient")
|
||||
except AttributeError : retVal.SetName("gradient")
|
||||
|
||||
ans = dsa.vtkDataArrayToVTKArray(retVal, dataset)
|
||||
|
||||
# The association information has been lost over the vtk filter
|
||||
# we must reconstruct it otherwise lower pipeline will be broken.
|
||||
ans.Association = narray.Association
|
||||
|
||||
return ans
|
||||
|
||||
def inv (narray) :
|
||||
"Returns the inverse an array of 2D square matrices."
|
||||
return _matrix_math_filter(narray, "Inverse")
|
||||
|
||||
def inverse (narray) :
|
||||
"Returns the inverse of an array of 2D square matrices."
|
||||
return inv(narray)
|
||||
|
||||
def jacobian (dataset) :
|
||||
"Returns the jacobian of an array of 2D square matrices."
|
||||
return _cell_quality(dataset, "jacobian")
|
||||
|
||||
def laplacian (narray, dataset=None) :
|
||||
"Returns the jacobian of an array of scalars."
|
||||
if not dataset : dataset = narray.DataSet
|
||||
if not dataset : raise RuntimeError('Need a dataset to compute laplacian')
|
||||
ans = gradient(narray, dataset)
|
||||
return divergence(ans)
|
||||
|
||||
def ln (narray) :
|
||||
"Returns the natural logarithm of an array of scalars/vectors/tensors."
|
||||
return numpy.log(narray)
|
||||
|
||||
def log (narray) :
|
||||
"Returns the natural logarithm of an array of scalars/vectors/tensors."
|
||||
return ln(narray)
|
||||
|
||||
def log10 (narray) :
|
||||
"Returns the base 10 logarithm of an array of scalars/vectors/tensors."
|
||||
return numpy.log10(narray)
|
||||
|
||||
def max (narray, axis=None):
|
||||
"Returns the maximum value of an array of scalars/vectors/tensors."
|
||||
if narray is dsa.NoneArray:
|
||||
return dsa.NoneArray
|
||||
ans = numpy.max(narray, axis)
|
||||
# if len(ans.shape) == 2 and ans.shape[0] == 3 and ans.shape[1] == 3: ans.reshape(9)
|
||||
return ans
|
||||
|
||||
def max_angle (dataset) :
|
||||
"Returns the maximum angle of each cell in a dataset."
|
||||
return _cell_quality(dataset, "max_angle")
|
||||
|
||||
def mag (a) :
|
||||
"Returns the magnigude of an array of scalars/vectors."
|
||||
return numpy.sqrt(dot(a, a))
|
||||
|
||||
def matmul (a, b) :
|
||||
"Return the product of the inputs. Inputs can be vectors/tensors."
|
||||
ashape = a.shape
|
||||
if (len(ashape) == 3 and (ashape[1] != 3 or ashape[2] not in [1, 3])) \
|
||||
or (len(ashape) == 2 and ashape[1] != 3) \
|
||||
or (len(ashape) != 2 and len(ashape) != 3):
|
||||
return dsa.NoneArray
|
||||
|
||||
bshape = b.shape
|
||||
if (len(bshape) == 3 and (bshape[1] != 3 or bshape[2] not in [1, 3])) \
|
||||
or (len(bshape) == 2 and bshape[1] != 3) \
|
||||
or (len(bshape) != 2 and len(bshape) != 3):
|
||||
return dsa.NoneArray
|
||||
|
||||
aindices = "...j"
|
||||
if len(ashape) == 3:
|
||||
aindices = "...ij"
|
||||
|
||||
bindices = "...j"
|
||||
if len(bshape) == 3:
|
||||
bindices = "...jk"
|
||||
|
||||
indices = aindices + ',' + bindices
|
||||
ans = numpy.einsum(indices, a, b)
|
||||
return ans
|
||||
|
||||
def mean (narray, axis=None) :
|
||||
"Returns the mean value of an array of scalars/vectors/tensors."
|
||||
if narray is dsa.NoneArray:
|
||||
return dsa.NoneArray
|
||||
ans = numpy.mean(numpy.array(narray), axis)
|
||||
# if len(ans.shape) == 2 and ans.shape[0] == 3 and ans.shape[1] == 3: ans.reshape(9)
|
||||
return ans
|
||||
|
||||
def min (narray, axis=None):
|
||||
"Returns the min value of an array of scalars/vectors/tensors."
|
||||
if narray is dsa.NoneArray:
|
||||
return dsa.NoneArray
|
||||
ans = numpy.min(narray, axis)
|
||||
# if len(ans.shape) == 2 and ans.shape[0] == 3 and ans.shape[1] == 3: ans.reshape(9)
|
||||
return ans
|
||||
|
||||
def min_angle (dataset) :
|
||||
"Returns the minimum angle of each cell in a dataset."
|
||||
return _cell_quality(dataset, "min_angle")
|
||||
|
||||
def norm (a) :
|
||||
"Returns the normalized values of an array of scalars/vectors."
|
||||
return a/mag(a).reshape((a.shape[0], 1))
|
||||
|
||||
def shear (dataset) :
|
||||
"Returns the shear of each cell in a dataset."
|
||||
return _cell_quality(dataset, "shear")
|
||||
|
||||
def skew (dataset) :
|
||||
"Returns the skew of each cell in a dataset."
|
||||
return _cell_quality(dataset, "skew")
|
||||
|
||||
def strain (narray, dataset=None) :
|
||||
"Returns the strain of an array of 3D vectors."
|
||||
if not dataset : dataset = narray.DataSet
|
||||
if not dataset : raise RuntimeError('Need a dataset to compute strain')
|
||||
|
||||
if 2 != narray.ndim or 3 != narray.shape[1] :
|
||||
raise RuntimeError('strain only works with an array of 3D vectors' +
|
||||
'Input shape ' + str(narray.shape))
|
||||
|
||||
cd = vtkCellDerivatives()
|
||||
cd.SetTensorModeToComputeStrain()
|
||||
|
||||
res = _cell_derivatives(narray, dataset, 'vectors', cd)
|
||||
|
||||
retVal = res.GetTensors()
|
||||
retVal.SetName("strain")
|
||||
|
||||
ans = dsa.vtkDataArrayToVTKArray(retVal, dataset)
|
||||
|
||||
# The association information has been lost over the vtk filter
|
||||
# we must reconstruct it otherwise lower pipeline will be broken.
|
||||
ans.Association = narray.Association
|
||||
|
||||
return ans
|
||||
|
||||
def sum (narray, axis=None):
|
||||
"Returns the min value of an array of scalars/vectors/tensors."
|
||||
if narray is dsa.NoneArray:
|
||||
return dsa.NoneArray
|
||||
return numpy.sum(narray, axis)
|
||||
|
||||
def surface_normal (dataset) :
|
||||
"Returns the surface normal of each cell in a dataset."
|
||||
if not dataset : raise RuntimeError('Need a dataset to compute surface_normal')
|
||||
|
||||
ds = dataset.NewInstance()
|
||||
ds.UnRegister(None)
|
||||
ds.CopyStructure(dataset.VTKObject)
|
||||
|
||||
filter = vtkPolyDataNormals()
|
||||
filter.SetInputData(ds)
|
||||
filter.ComputeCellNormalsOn()
|
||||
filter.ComputePointNormalsOff()
|
||||
|
||||
filter.SetFeatureAngle(180)
|
||||
filter.SplittingOff()
|
||||
filter.ConsistencyOff()
|
||||
filter.AutoOrientNormalsOff()
|
||||
filter.FlipNormalsOff()
|
||||
filter.NonManifoldTraversalOff()
|
||||
filter.Update()
|
||||
|
||||
varray = filter.GetOutput().GetCellData().GetNormals()
|
||||
ans = dsa.vtkDataArrayToVTKArray(varray, dataset)
|
||||
|
||||
# The association information has been lost over the vtk filter
|
||||
# we must reconstruct it otherwise lower pipeline will be broken.
|
||||
ans.Association = dsa.ArrayAssociation.CELL
|
||||
|
||||
return ans
|
||||
|
||||
def trace (narray) :
|
||||
"Returns the trace of an array of 2D square matrices."
|
||||
ax1 = 0
|
||||
ax2 = 1
|
||||
if narray.ndim > 2 :
|
||||
ax1 = 1
|
||||
ax2 = 2
|
||||
return numpy.trace(narray, axis1=ax1, axis2=ax2)
|
||||
|
||||
def var (narray, axis=None) :
|
||||
"Returns the mean value of an array of scalars/vectors/tensors."
|
||||
if narray is dsa.NoneArray:
|
||||
return dsa.NoneArray
|
||||
return numpy.var(narray, axis)
|
||||
|
||||
def volume (dataset) :
|
||||
"Returns the volume of each cell in a dataset."
|
||||
#def _cell_quality (dataset, quality) :
|
||||
if not dataset : raise RuntimeError('Need a dataset to compute volume')
|
||||
|
||||
# create a dataset with only our array but the same geometry/topology
|
||||
ds = dataset.NewInstance()
|
||||
ds.UnRegister(None)
|
||||
ds.CopyStructure(dataset.VTKObject)
|
||||
|
||||
filter = vtkCellSizeFilter()
|
||||
filter.SetInputData(ds)
|
||||
filter.ComputeVertexCountOff()
|
||||
filter.ComputeLengthOff()
|
||||
filter.ComputeAreaOff()
|
||||
filter.Update()
|
||||
|
||||
varray = filter.GetOutput().GetCellData().GetArray("Volume")
|
||||
varray.SetName("CellQuality")
|
||||
ans = dsa.vtkDataArrayToVTKArray(varray, dataset)
|
||||
|
||||
# The association information has been lost over the vtk filter
|
||||
# we must reconstruct it otherwise lower pipeline will be broken.
|
||||
ans.Association = dsa.ArrayAssociation.CELL
|
||||
|
||||
return ans
|
||||
|
||||
def vorticity(narray, dataset=None):
|
||||
"Returns the vorticity/curl of an array of 3D vectors."
|
||||
return curl(narray, dataset)
|
||||
|
||||
def vertex_normal (dataset) :
|
||||
"Returns the vertex normal of each point in a dataset."
|
||||
if not dataset : raise RuntimeError('Need a dataset to compute vertex_normal')
|
||||
|
||||
ds = dataset.NewInstance()
|
||||
ds.UnRegister(None)
|
||||
ds.CopyStructure(dataset.VTKObject)
|
||||
|
||||
filter = vtkPolyDataNormals()
|
||||
filter.SetInputData(ds)
|
||||
filter.ComputeCellNormalsOff()
|
||||
filter.ComputePointNormalsOn()
|
||||
|
||||
filter.SetFeatureAngle(180)
|
||||
filter.SplittingOff()
|
||||
filter.ConsistencyOff()
|
||||
filter.AutoOrientNormalsOff()
|
||||
filter.FlipNormalsOff()
|
||||
filter.NonManifoldTraversalOff()
|
||||
filter.Update()
|
||||
|
||||
varray = filter.GetOutput().GetPointData().GetNormals()
|
||||
ans = dsa.vtkDataArrayToVTKArray(varray, dataset)
|
||||
|
||||
# The association information has been lost over the vtk filter
|
||||
# we must reconstruct it otherwise lower pipeline will be broken.
|
||||
ans.Association = dsa.ArrayAssociation.POINT
|
||||
|
||||
return ans
|
||||
|
||||
def make_vector(ax, ay, az=None):
|
||||
if ax is dsa.NoneArray or ay is dsa.NoneArray or ay is dsa.NoneArray:
|
||||
return dsa.NoneArray
|
||||
|
||||
if len(ax.shape) != 1 or len(ay.shape) != 1 or (az is not None and len(az.shape) != 1):
|
||||
raise ValueError("Can only merge 1D arrays")
|
||||
|
||||
if az is None:
|
||||
az = numpy.zeros(ax.shape)
|
||||
v = numpy.vstack([ax, ay, az]).transpose().view(dsa.VTKArray)
|
||||
# Copy defaults from first array. The user can always
|
||||
# overwrite this
|
||||
try:
|
||||
v.DataSet = ax.DataSet
|
||||
except AttributeError: pass
|
||||
try:
|
||||
v.Association = ax.Association
|
||||
except AttributeError: pass
|
||||
return v
|
||||
@@ -0,0 +1,803 @@
|
||||
# coding=utf-8
|
||||
"""
|
||||
A simple VTK widget for PyQt or PySide.
|
||||
See http://www.trolltech.com for Qt documentation,
|
||||
http://www.riverbankcomputing.co.uk for PyQt, and
|
||||
http://pyside.github.io for PySide.
|
||||
|
||||
This class is based on the vtkGenericRenderWindowInteractor and is
|
||||
therefore fairly powerful. It should also play nicely with the
|
||||
vtk3DWidget code.
|
||||
|
||||
Created by Prabhu Ramachandran, May 2002
|
||||
Based on David Gobbi's QVTKRenderWidget.py
|
||||
|
||||
Changes by Gerard Vermeulen Feb. 2003
|
||||
Win32 support.
|
||||
|
||||
Changes by Gerard Vermeulen, May 2003
|
||||
Bug fixes and better integration with the Qt framework.
|
||||
|
||||
Changes by Phil Thompson, Nov. 2006
|
||||
Ported to PyQt v4.
|
||||
Added support for wheel events.
|
||||
|
||||
Changes by Phil Thompson, Oct. 2007
|
||||
Bug fixes.
|
||||
|
||||
Changes by Phil Thompson, Mar. 2008
|
||||
Added cursor support.
|
||||
|
||||
Changes by Rodrigo Mologni, Sep. 2013 (Credit to Daniele Esposti)
|
||||
Bug fix to PySide: Converts PyCObject to void pointer.
|
||||
|
||||
Changes by Greg Schussman, Aug. 2014
|
||||
The keyPressEvent function now passes keysym instead of None.
|
||||
|
||||
Changes by Alex Tsui, Apr. 2015
|
||||
Port from PyQt4 to PyQt5.
|
||||
|
||||
Changes by Fabian Wenzel, Jan. 2016
|
||||
Support for Python3
|
||||
|
||||
Changes by Tobias Hänel, Sep. 2018
|
||||
Support for PySide2
|
||||
|
||||
Changes by Ruben de Bruin, Aug. 2019
|
||||
Fixes to the keyPressEvent function
|
||||
|
||||
Changes by Chen Jintao, Aug. 2021
|
||||
Support for PySide6
|
||||
|
||||
Changes by Eric Larson and Guillaume Favelier, Apr. 2022
|
||||
Support for PyQt6
|
||||
"""
|
||||
|
||||
# Check whether a specific PyQt implementation was chosen
|
||||
try:
|
||||
import vtkmodules.qt
|
||||
PyQtImpl = vtkmodules.qt.PyQtImpl
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
# Check whether a specific QVTKRenderWindowInteractor base
|
||||
# class was chosen, can be set to "QGLWidget" in
|
||||
# PyQt implementation version lower than Qt6,
|
||||
# or "QOpenGLWidget" in Pyside6 and PyQt6
|
||||
QVTKRWIBase = "QWidget"
|
||||
try:
|
||||
import vtkmodules.qt
|
||||
QVTKRWIBase = vtkmodules.qt.QVTKRWIBase
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
from vtkmodules.vtkRenderingCore import vtkRenderWindow
|
||||
from vtkmodules.vtkRenderingUI import vtkGenericRenderWindowInteractor
|
||||
|
||||
if PyQtImpl is None:
|
||||
# Autodetect the PyQt implementation to use
|
||||
try:
|
||||
import PySide6.QtCore
|
||||
PyQtImpl = "PySide6"
|
||||
except ImportError:
|
||||
try:
|
||||
import PyQt6.QtCore
|
||||
PyQtImpl = "PyQt6"
|
||||
except ImportError:
|
||||
try:
|
||||
import PyQt5.QtCore
|
||||
PyQtImpl = "PyQt5"
|
||||
except ImportError:
|
||||
try:
|
||||
import PySide2.QtCore
|
||||
PyQtImpl = "PySide2"
|
||||
except ImportError:
|
||||
try:
|
||||
import PyQt4.QtCore
|
||||
PyQtImpl = "PyQt4"
|
||||
except ImportError:
|
||||
try:
|
||||
import PySide.QtCore
|
||||
PyQtImpl = "PySide"
|
||||
except ImportError:
|
||||
raise ImportError("Cannot load either PyQt or PySide")
|
||||
|
||||
# Check the compatibility of PyQtImpl and QVTKRWIBase
|
||||
if QVTKRWIBase != "QWidget":
|
||||
if PyQtImpl in ["PySide6", "PyQt6"] and QVTKRWIBase == "QOpenGLWidget":
|
||||
pass # compatible
|
||||
elif PyQtImpl in ["PyQt5", "PySide2","PyQt4", "PySide"] and QVTKRWIBase == "QGLWidget":
|
||||
pass # compatible
|
||||
else:
|
||||
raise ImportError("Cannot load " + QVTKRWIBase + " from " + PyQtImpl)
|
||||
|
||||
if PyQtImpl == "PySide6":
|
||||
if QVTKRWIBase == "QOpenGLWidget":
|
||||
from PySide6.QtOpenGLWidgets import QOpenGLWidget
|
||||
from PySide6.QtWidgets import QWidget
|
||||
from PySide6.QtWidgets import QSizePolicy
|
||||
from PySide6.QtWidgets import QApplication
|
||||
from PySide6.QtWidgets import QMainWindow
|
||||
from PySide6.QtGui import QCursor
|
||||
from PySide6.QtCore import Qt
|
||||
from PySide6.QtCore import QTimer
|
||||
from PySide6.QtCore import QObject
|
||||
from PySide6.QtCore import QSize
|
||||
from PySide6.QtCore import QEvent
|
||||
elif PyQtImpl == "PyQt6":
|
||||
if QVTKRWIBase == "QOpenGLWidget":
|
||||
from PyQt6.QtOpenGLWidgets import QOpenGLWidget
|
||||
from PyQt6.QtWidgets import QWidget
|
||||
from PyQt6.QtWidgets import QSizePolicy
|
||||
from PyQt6.QtWidgets import QApplication
|
||||
from PyQt6.QtWidgets import QMainWindow
|
||||
from PyQt6.QtGui import QCursor
|
||||
from PyQt6.QtCore import Qt
|
||||
from PyQt6.QtCore import QTimer
|
||||
from PyQt6.QtCore import QObject
|
||||
from PyQt6.QtCore import QSize
|
||||
from PyQt6.QtCore import QEvent
|
||||
elif PyQtImpl == "PyQt5":
|
||||
if QVTKRWIBase == "QGLWidget":
|
||||
from PyQt5.QtOpenGL import QGLWidget
|
||||
from PyQt5.QtWidgets import QWidget
|
||||
from PyQt5.QtWidgets import QSizePolicy
|
||||
from PyQt5.QtWidgets import QApplication
|
||||
from PyQt5.QtWidgets import QMainWindow
|
||||
from PyQt5.QtGui import QCursor
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtCore import QTimer
|
||||
from PyQt5.QtCore import QObject
|
||||
from PyQt5.QtCore import QSize
|
||||
from PyQt5.QtCore import QEvent
|
||||
elif PyQtImpl == "PySide2":
|
||||
if QVTKRWIBase == "QGLWidget":
|
||||
from PySide2.QtOpenGL import QGLWidget
|
||||
from PySide2.QtWidgets import QWidget
|
||||
from PySide2.QtWidgets import QSizePolicy
|
||||
from PySide2.QtWidgets import QApplication
|
||||
from PySide2.QtWidgets import QMainWindow
|
||||
from PySide2.QtGui import QCursor
|
||||
from PySide2.QtCore import Qt
|
||||
from PySide2.QtCore import QTimer
|
||||
from PySide2.QtCore import QObject
|
||||
from PySide2.QtCore import QSize
|
||||
from PySide2.QtCore import QEvent
|
||||
elif PyQtImpl == "PyQt4":
|
||||
if QVTKRWIBase == "QGLWidget":
|
||||
from PyQt4.QtOpenGL import QGLWidget
|
||||
from PyQt4.QtGui import QWidget
|
||||
from PyQt4.QtGui import QSizePolicy
|
||||
from PyQt4.QtGui import QApplication
|
||||
from PyQt4.QtGui import QMainWindow
|
||||
from PyQt4.QtCore import Qt
|
||||
from PyQt4.QtCore import QTimer
|
||||
from PyQt4.QtCore import QObject
|
||||
from PyQt4.QtCore import QSize
|
||||
from PyQt4.QtCore import QEvent
|
||||
elif PyQtImpl == "PySide":
|
||||
if QVTKRWIBase == "QGLWidget":
|
||||
from PySide.QtOpenGL import QGLWidget
|
||||
from PySide.QtGui import QWidget
|
||||
from PySide.QtGui import QSizePolicy
|
||||
from PySide.QtGui import QApplication
|
||||
from PySide.QtGui import QMainWindow
|
||||
from PySide.QtCore import Qt
|
||||
from PySide.QtCore import QTimer
|
||||
from PySide.QtCore import QObject
|
||||
from PySide.QtCore import QSize
|
||||
from PySide.QtCore import QEvent
|
||||
else:
|
||||
raise ImportError("Unknown PyQt implementation " + repr(PyQtImpl))
|
||||
|
||||
# Define types for base class, based on string
|
||||
if QVTKRWIBase == "QWidget":
|
||||
QVTKRWIBaseClass = QWidget
|
||||
elif QVTKRWIBase == "QGLWidget":
|
||||
QVTKRWIBaseClass = QGLWidget
|
||||
elif QVTKRWIBase == "QOpenGLWidget":
|
||||
QVTKRWIBaseClass = QOpenGLWidget
|
||||
else:
|
||||
raise ImportError("Unknown base class for QVTKRenderWindowInteractor " + QVTKRWIBase)
|
||||
|
||||
if PyQtImpl == 'PyQt6':
|
||||
CursorShape = Qt.CursorShape
|
||||
WidgetAttribute = Qt.WidgetAttribute
|
||||
FocusPolicy = Qt.FocusPolicy
|
||||
ConnectionType = Qt.ConnectionType
|
||||
Key = Qt.Key
|
||||
SizePolicy = QSizePolicy.Policy
|
||||
EventType = QEvent.Type
|
||||
try:
|
||||
MouseButton = Qt.MouseButton
|
||||
WindowType = Qt.WindowType
|
||||
KeyboardModifier = Qt.KeyboardModifier
|
||||
except AttributeError:
|
||||
# Fallback solution for PyQt6 versions < 6.1.0
|
||||
MouseButton = Qt.MouseButtons
|
||||
WindowType = Qt.WindowFlags
|
||||
KeyboardModifier = Qt.KeyboardModifiers
|
||||
else:
|
||||
CursorShape = MouseButton = WindowType = WidgetAttribute = \
|
||||
KeyboardModifier = FocusPolicy = ConnectionType = Key = Qt
|
||||
SizePolicy = QSizePolicy
|
||||
EventType = QEvent
|
||||
|
||||
if PyQtImpl in ('PyQt4', 'PySide'):
|
||||
MiddleButton = MouseButton.MidButton
|
||||
else:
|
||||
MiddleButton = MouseButton.MiddleButton
|
||||
|
||||
|
||||
def _get_event_pos(ev):
|
||||
try: # Qt6+
|
||||
return ev.position().x(), ev.position().y()
|
||||
except AttributeError: # Qt5
|
||||
return ev.x(), ev.y()
|
||||
|
||||
|
||||
class QVTKRenderWindowInteractor(QVTKRWIBaseClass):
|
||||
|
||||
""" A QVTKRenderWindowInteractor for Python and Qt. Uses a
|
||||
vtkGenericRenderWindowInteractor to handle the interactions. Use
|
||||
GetRenderWindow() to get the vtkRenderWindow. Create with the
|
||||
keyword stereo=1 in order to generate a stereo-capable window.
|
||||
|
||||
The user interface is summarized in vtkInteractorStyle.h:
|
||||
|
||||
- Keypress j / Keypress t: toggle between joystick (position
|
||||
sensitive) and trackball (motion sensitive) styles. In joystick
|
||||
style, motion occurs continuously as long as a mouse button is
|
||||
pressed. In trackball style, motion occurs when the mouse button
|
||||
is pressed and the mouse pointer moves.
|
||||
|
||||
- Keypress c / Keypress o: toggle between camera and object
|
||||
(actor) modes. In camera mode, mouse events affect the camera
|
||||
position and focal point. In object mode, mouse events affect
|
||||
the actor that is under the mouse pointer.
|
||||
|
||||
- Button 1: rotate the camera around its focal point (if camera
|
||||
mode) or rotate the actor around its origin (if actor mode). The
|
||||
rotation is in the direction defined from the center of the
|
||||
renderer's viewport towards the mouse position. In joystick mode,
|
||||
the magnitude of the rotation is determined by the distance the
|
||||
mouse is from the center of the render window.
|
||||
|
||||
- Button 2: pan the camera (if camera mode) or translate the actor
|
||||
(if object mode). In joystick mode, the direction of pan or
|
||||
translation is from the center of the viewport towards the mouse
|
||||
position. In trackball mode, the direction of motion is the
|
||||
direction the mouse moves. (Note: with 2-button mice, pan is
|
||||
defined as <Shift>-Button 1.)
|
||||
|
||||
- Button 3: zoom the camera (if camera mode) or scale the actor
|
||||
(if object mode). Zoom in/increase scale if the mouse position is
|
||||
in the top half of the viewport; zoom out/decrease scale if the
|
||||
mouse position is in the bottom half. In joystick mode, the amount
|
||||
of zoom is controlled by the distance of the mouse pointer from
|
||||
the horizontal centerline of the window.
|
||||
|
||||
- Keypress 3: toggle the render window into and out of stereo
|
||||
mode. By default, red-blue stereo pairs are created. Some systems
|
||||
support Crystal Eyes LCD stereo glasses; you have to invoke
|
||||
SetStereoTypeToCrystalEyes() on the rendering window. Note: to
|
||||
use stereo you also need to pass a stereo=1 keyword argument to
|
||||
the constructor.
|
||||
|
||||
- Keypress e: exit the application.
|
||||
|
||||
- Keypress f: fly to the picked point
|
||||
|
||||
- Keypress p: perform a pick operation. The render window interactor
|
||||
has an internal instance of vtkCellPicker that it uses to pick.
|
||||
|
||||
- Keypress r: reset the camera view along the current view
|
||||
direction. Centers the actors and moves the camera so that all actors
|
||||
are visible.
|
||||
|
||||
- Keypress s: modify the representation of all actors so that they
|
||||
are surfaces.
|
||||
|
||||
- Keypress u: invoke the user-defined function. Typically, this
|
||||
keypress will bring up an interactor that you can type commands in.
|
||||
|
||||
- Keypress w: modify the representation of all actors so that they
|
||||
are wireframe.
|
||||
"""
|
||||
|
||||
# Map between VTK and Qt cursors.
|
||||
_CURSOR_MAP = {
|
||||
0: CursorShape.ArrowCursor, # VTK_CURSOR_DEFAULT
|
||||
1: CursorShape.ArrowCursor, # VTK_CURSOR_ARROW
|
||||
2: CursorShape.SizeBDiagCursor, # VTK_CURSOR_SIZENE
|
||||
3: CursorShape.SizeFDiagCursor, # VTK_CURSOR_SIZENWSE
|
||||
4: CursorShape.SizeBDiagCursor, # VTK_CURSOR_SIZESW
|
||||
5: CursorShape.SizeFDiagCursor, # VTK_CURSOR_SIZESE
|
||||
6: CursorShape.SizeVerCursor, # VTK_CURSOR_SIZENS
|
||||
7: CursorShape.SizeHorCursor, # VTK_CURSOR_SIZEWE
|
||||
8: CursorShape.SizeAllCursor, # VTK_CURSOR_SIZEALL
|
||||
9: CursorShape.PointingHandCursor, # VTK_CURSOR_HAND
|
||||
10: CursorShape.CrossCursor, # VTK_CURSOR_CROSSHAIR
|
||||
}
|
||||
|
||||
def __init__(self, parent=None, **kw):
|
||||
# the current button
|
||||
self._ActiveButton = MouseButton.NoButton
|
||||
|
||||
# private attributes
|
||||
self.__saveX = 0
|
||||
self.__saveY = 0
|
||||
self.__saveModifiers = KeyboardModifier.NoModifier
|
||||
self.__saveButtons = MouseButton.NoButton
|
||||
self.__wheelDelta = 0
|
||||
|
||||
# do special handling of some keywords:
|
||||
# stereo, rw
|
||||
|
||||
try:
|
||||
stereo = bool(kw['stereo'])
|
||||
except KeyError:
|
||||
stereo = False
|
||||
|
||||
try:
|
||||
rw = kw['rw']
|
||||
except KeyError:
|
||||
rw = None
|
||||
|
||||
# create base qt-level widget
|
||||
if QVTKRWIBase == "QWidget":
|
||||
if "wflags" in kw:
|
||||
wflags = kw['wflags']
|
||||
else:
|
||||
wflags = WindowType.Widget # what Qt.WindowFlags() returns (0)
|
||||
QWidget.__init__(self, parent, wflags | WindowType.MSWindowsOwnDC)
|
||||
elif QVTKRWIBase == "QGLWidget":
|
||||
QGLWidget.__init__(self, parent)
|
||||
elif QVTKRWIBase == "QOpenGLWidget":
|
||||
QOpenGLWidget.__init__(self, parent)
|
||||
|
||||
if rw: # user-supplied render window
|
||||
self._RenderWindow = rw
|
||||
else:
|
||||
self._RenderWindow = vtkRenderWindow()
|
||||
|
||||
WId = self.winId()
|
||||
|
||||
if type(WId).__name__ == 'PyCapsule':
|
||||
from ctypes import pythonapi, c_void_p, py_object, c_char_p
|
||||
|
||||
pythonapi.PyCapsule_GetName.restype = c_char_p
|
||||
pythonapi.PyCapsule_GetName.argtypes = [py_object]
|
||||
|
||||
name = pythonapi.PyCapsule_GetName(WId)
|
||||
|
||||
pythonapi.PyCapsule_GetPointer.restype = c_void_p
|
||||
pythonapi.PyCapsule_GetPointer.argtypes = [py_object, c_char_p]
|
||||
|
||||
WId = pythonapi.PyCapsule_GetPointer(WId, name)
|
||||
|
||||
self._RenderWindow.SetWindowInfo(str(int(WId)))
|
||||
|
||||
if stereo: # stereo mode
|
||||
self._RenderWindow.StereoCapableWindowOn()
|
||||
self._RenderWindow.SetStereoTypeToCrystalEyes()
|
||||
|
||||
try:
|
||||
self._Iren = kw['iren']
|
||||
except KeyError:
|
||||
self._Iren = vtkGenericRenderWindowInteractor()
|
||||
self._Iren.SetRenderWindow(self._RenderWindow)
|
||||
|
||||
# do all the necessary qt setup
|
||||
self.setAttribute(WidgetAttribute.WA_OpaquePaintEvent)
|
||||
self.setAttribute(WidgetAttribute.WA_PaintOnScreen)
|
||||
self.setMouseTracking(True) # get all mouse events
|
||||
self.setFocusPolicy(FocusPolicy.WheelFocus)
|
||||
self.setSizePolicy(QSizePolicy(SizePolicy.Expanding, SizePolicy.Expanding))
|
||||
|
||||
self._Timer = QTimer(self)
|
||||
self._Timer.timeout.connect(self.TimerEvent)
|
||||
|
||||
self._Iren.AddObserver('CreateTimerEvent', self.CreateTimer)
|
||||
self._Iren.AddObserver('DestroyTimerEvent', self.DestroyTimer)
|
||||
self._Iren.GetRenderWindow().AddObserver('CursorChangedEvent',
|
||||
self.CursorChangedEvent)
|
||||
|
||||
# If we've a parent, it does not close the child when closed.
|
||||
# Connect the parent's destroyed signal to this widget's close
|
||||
# slot for proper cleanup of VTK objects.
|
||||
if self.parent():
|
||||
self.parent().destroyed.connect(self.close, ConnectionType.DirectConnection)
|
||||
|
||||
def __getattr__(self, attr):
|
||||
"""Makes the object behave like a vtkGenericRenderWindowInteractor"""
|
||||
if attr == '__vtk__':
|
||||
return lambda t=self._Iren: t
|
||||
elif hasattr(self._Iren, attr):
|
||||
return getattr(self._Iren, attr)
|
||||
else:
|
||||
raise AttributeError(self.__class__.__name__ +
|
||||
" has no attribute named " + attr)
|
||||
|
||||
def Finalize(self):
|
||||
'''
|
||||
Call internal cleanup method on VTK objects
|
||||
'''
|
||||
self._RenderWindow.Finalize()
|
||||
|
||||
def CreateTimer(self, obj, evt):
|
||||
self._Timer.start(10)
|
||||
|
||||
def DestroyTimer(self, obj, evt):
|
||||
self._Timer.stop()
|
||||
return 1
|
||||
|
||||
def TimerEvent(self):
|
||||
self._Iren.TimerEvent()
|
||||
|
||||
def CursorChangedEvent(self, obj, evt):
|
||||
"""Called when the CursorChangedEvent fires on the render window."""
|
||||
# This indirection is needed since when the event fires, the current
|
||||
# cursor is not yet set so we defer this by which time the current
|
||||
# cursor should have been set.
|
||||
QTimer.singleShot(0, self.ShowCursor)
|
||||
|
||||
def HideCursor(self):
|
||||
"""Hides the cursor."""
|
||||
self.setCursor(CursorShape.BlankCursor)
|
||||
|
||||
def ShowCursor(self):
|
||||
"""Shows the cursor."""
|
||||
vtk_cursor = self._Iren.GetRenderWindow().GetCurrentCursor()
|
||||
qt_cursor = self._CURSOR_MAP.get(vtk_cursor, CursorShape.ArrowCursor)
|
||||
self.setCursor(qt_cursor)
|
||||
|
||||
def closeEvent(self, evt):
|
||||
self.Finalize()
|
||||
|
||||
def sizeHint(self):
|
||||
return QSize(400, 400)
|
||||
|
||||
def paintEngine(self):
|
||||
return None
|
||||
|
||||
def paintEvent(self, ev):
|
||||
self._Iren.Render()
|
||||
|
||||
def resizeEvent(self, ev):
|
||||
scale = self._getPixelRatio()
|
||||
w = int(round(scale*self.width()))
|
||||
h = int(round(scale*self.height()))
|
||||
self._RenderWindow.SetDPI(int(round(72*scale)))
|
||||
vtkRenderWindow.SetSize(self._RenderWindow, w, h)
|
||||
self._Iren.SetSize(w, h)
|
||||
self._Iren.ConfigureEvent()
|
||||
self.update()
|
||||
|
||||
def _GetKeyCharAndKeySym(self, ev):
|
||||
""" Convert a Qt key into a char and a vtk keysym.
|
||||
|
||||
This is essentially copied from the c++ implementation in
|
||||
GUISupport/Qt/QVTKInteractorAdapter.cxx.
|
||||
"""
|
||||
# if there is a char, convert its ASCII code to a VTK keysym
|
||||
try:
|
||||
keyChar = ev.text()[0]
|
||||
keySym = _keysyms_for_ascii[ord(keyChar)]
|
||||
except IndexError:
|
||||
keyChar = '\0'
|
||||
keySym = None
|
||||
|
||||
# next, try converting Qt key code to a VTK keysym
|
||||
if keySym is None:
|
||||
try:
|
||||
keySym = _keysyms[ev.key()]
|
||||
except KeyError:
|
||||
keySym = None
|
||||
|
||||
# use "None" as a fallback
|
||||
if keySym is None:
|
||||
keySym = "None"
|
||||
|
||||
return keyChar, keySym
|
||||
|
||||
def _GetCtrlShift(self, ev):
|
||||
ctrl = shift = False
|
||||
|
||||
if hasattr(ev, 'modifiers'):
|
||||
if ev.modifiers() & KeyboardModifier.ShiftModifier:
|
||||
shift = True
|
||||
if ev.modifiers() & KeyboardModifier.ControlModifier:
|
||||
ctrl = True
|
||||
else:
|
||||
if self.__saveModifiers & KeyboardModifier.ShiftModifier:
|
||||
shift = True
|
||||
if self.__saveModifiers & KeyboardModifier.ControlModifier:
|
||||
ctrl = True
|
||||
|
||||
return ctrl, shift
|
||||
|
||||
@staticmethod
|
||||
def _getPixelRatio():
|
||||
if PyQtImpl in ["PyQt5", "PySide2", "PySide6", "PyQt6"]:
|
||||
# Source: https://stackoverflow.com/a/40053864/3388962
|
||||
pos = QCursor.pos()
|
||||
for screen in QApplication.screens():
|
||||
rect = screen.geometry()
|
||||
if rect.contains(pos):
|
||||
return screen.devicePixelRatio()
|
||||
# Should never happen, but try to find a good fallback.
|
||||
return QApplication.instance().devicePixelRatio()
|
||||
else:
|
||||
# Qt4 seems not to provide any cross-platform means to get the
|
||||
# pixel ratio.
|
||||
return 1.
|
||||
|
||||
def _setEventInformation(self, x, y, ctrl, shift,
|
||||
key, repeat=0, keysum=None):
|
||||
scale = self._getPixelRatio()
|
||||
self._Iren.SetEventInformation(int(round(x*scale)),
|
||||
int(round((self.height()-y-1)*scale)),
|
||||
ctrl, shift, key, repeat, keysum)
|
||||
|
||||
def enterEvent(self, ev):
|
||||
ctrl, shift = self._GetCtrlShift(ev)
|
||||
self._setEventInformation(self.__saveX, self.__saveY,
|
||||
ctrl, shift, chr(0), 0, None)
|
||||
self._Iren.EnterEvent()
|
||||
|
||||
def leaveEvent(self, ev):
|
||||
ctrl, shift = self._GetCtrlShift(ev)
|
||||
self._setEventInformation(self.__saveX, self.__saveY,
|
||||
ctrl, shift, chr(0), 0, None)
|
||||
self._Iren.LeaveEvent()
|
||||
|
||||
def mousePressEvent(self, ev):
|
||||
ctrl, shift = self._GetCtrlShift(ev)
|
||||
repeat = 0
|
||||
if ev.type() == EventType.MouseButtonDblClick:
|
||||
repeat = 1
|
||||
x, y = _get_event_pos(ev)
|
||||
self._setEventInformation(x, y,
|
||||
ctrl, shift, chr(0), repeat, None)
|
||||
|
||||
self._ActiveButton = ev.button()
|
||||
|
||||
if self._ActiveButton == MouseButton.LeftButton:
|
||||
self._Iren.LeftButtonPressEvent()
|
||||
elif self._ActiveButton == MouseButton.RightButton:
|
||||
self._Iren.RightButtonPressEvent()
|
||||
elif self._ActiveButton == MiddleButton:
|
||||
self._Iren.MiddleButtonPressEvent()
|
||||
|
||||
def mouseReleaseEvent(self, ev):
|
||||
ctrl, shift = self._GetCtrlShift(ev)
|
||||
x, y = _get_event_pos(ev)
|
||||
self._setEventInformation(x, y,
|
||||
ctrl, shift, chr(0), 0, None)
|
||||
|
||||
if self._ActiveButton == MouseButton.LeftButton:
|
||||
self._Iren.LeftButtonReleaseEvent()
|
||||
elif self._ActiveButton == MouseButton.RightButton:
|
||||
self._Iren.RightButtonReleaseEvent()
|
||||
elif self._ActiveButton == MiddleButton:
|
||||
self._Iren.MiddleButtonReleaseEvent()
|
||||
|
||||
def mouseMoveEvent(self, ev):
|
||||
self.__saveModifiers = ev.modifiers()
|
||||
self.__saveButtons = ev.buttons()
|
||||
x, y = _get_event_pos(ev)
|
||||
self.__saveX = x
|
||||
self.__saveY = y
|
||||
|
||||
ctrl, shift = self._GetCtrlShift(ev)
|
||||
self._setEventInformation(x, y,
|
||||
ctrl, shift, chr(0), 0, None)
|
||||
self._Iren.MouseMoveEvent()
|
||||
|
||||
def keyPressEvent(self, ev):
|
||||
key, keySym = self._GetKeyCharAndKeySym(ev)
|
||||
ctrl, shift = self._GetCtrlShift(ev)
|
||||
self._setEventInformation(self.__saveX, self.__saveY,
|
||||
ctrl, shift, key, 0, keySym)
|
||||
self._Iren.KeyPressEvent()
|
||||
self._Iren.CharEvent()
|
||||
|
||||
def keyReleaseEvent(self, ev):
|
||||
key, keySym = self._GetKeyCharAndKeySym(ev)
|
||||
ctrl, shift = self._GetCtrlShift(ev)
|
||||
self._setEventInformation(self.__saveX, self.__saveY,
|
||||
ctrl, shift, key, 0, keySym)
|
||||
self._Iren.KeyReleaseEvent()
|
||||
|
||||
def wheelEvent(self, ev):
|
||||
if hasattr(ev, 'delta'):
|
||||
self.__wheelDelta += ev.delta()
|
||||
else:
|
||||
self.__wheelDelta += ev.angleDelta().y()
|
||||
|
||||
if self.__wheelDelta >= 120:
|
||||
self._Iren.MouseWheelForwardEvent()
|
||||
self.__wheelDelta = 0
|
||||
elif self.__wheelDelta <= -120:
|
||||
self._Iren.MouseWheelBackwardEvent()
|
||||
self.__wheelDelta = 0
|
||||
|
||||
def GetRenderWindow(self):
|
||||
return self._RenderWindow
|
||||
|
||||
def Render(self):
|
||||
self.update()
|
||||
|
||||
|
||||
def QVTKRenderWidgetConeExample():
|
||||
"""A simple example that uses the QVTKRenderWindowInteractor class."""
|
||||
|
||||
from vtkmodules.vtkFiltersSources import vtkConeSource
|
||||
from vtkmodules.vtkRenderingCore import vtkActor, vtkPolyDataMapper, vtkRenderer
|
||||
# load implementations for rendering and interaction factory classes
|
||||
import vtkmodules.vtkRenderingOpenGL2
|
||||
import vtkmodules.vtkInteractionStyle
|
||||
|
||||
# every QT app needs an app
|
||||
app = QApplication(['QVTKRenderWindowInteractor'])
|
||||
|
||||
window = QMainWindow()
|
||||
|
||||
# create the widget
|
||||
widget = QVTKRenderWindowInteractor(window)
|
||||
window.setCentralWidget(widget)
|
||||
# if you don't want the 'q' key to exit comment this.
|
||||
widget.AddObserver("ExitEvent", lambda o, e, a=app: a.quit())
|
||||
|
||||
ren = vtkRenderer()
|
||||
widget.GetRenderWindow().AddRenderer(ren)
|
||||
|
||||
cone = vtkConeSource()
|
||||
cone.SetResolution(8)
|
||||
|
||||
coneMapper = vtkPolyDataMapper()
|
||||
coneMapper.SetInputConnection(cone.GetOutputPort())
|
||||
|
||||
coneActor = vtkActor()
|
||||
coneActor.SetMapper(coneMapper)
|
||||
|
||||
ren.AddActor(coneActor)
|
||||
|
||||
# show the widget
|
||||
window.show()
|
||||
|
||||
widget.Initialize()
|
||||
widget.Start()
|
||||
|
||||
# start event processing
|
||||
# Source: https://doc.qt.io/qtforpython/porting_from2.html
|
||||
# 'exec_' is deprecated and will be removed in the future.
|
||||
# Use 'exec' instead.
|
||||
try:
|
||||
app.exec()
|
||||
except AttributeError:
|
||||
app.exec_()
|
||||
|
||||
|
||||
_keysyms_for_ascii = (
|
||||
None, None, None, None, None, None, None, None,
|
||||
None, "Tab", None, None, None, None, None, None,
|
||||
None, None, None, None, None, None, None, None,
|
||||
None, None, None, None, None, None, None, None,
|
||||
"space", "exclam", "quotedbl", "numbersign",
|
||||
"dollar", "percent", "ampersand", "quoteright",
|
||||
"parenleft", "parenright", "asterisk", "plus",
|
||||
"comma", "minus", "period", "slash",
|
||||
"0", "1", "2", "3", "4", "5", "6", "7",
|
||||
"8", "9", "colon", "semicolon", "less", "equal", "greater", "question",
|
||||
"at", "A", "B", "C", "D", "E", "F", "G",
|
||||
"H", "I", "J", "K", "L", "M", "N", "O",
|
||||
"P", "Q", "R", "S", "T", "U", "V", "W",
|
||||
"X", "Y", "Z", "bracketleft",
|
||||
"backslash", "bracketright", "asciicircum", "underscore",
|
||||
"quoteleft", "a", "b", "c", "d", "e", "f", "g",
|
||||
"h", "i", "j", "k", "l", "m", "n", "o",
|
||||
"p", "q", "r", "s", "t", "u", "v", "w",
|
||||
"x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", "Delete",
|
||||
)
|
||||
|
||||
_keysyms = {
|
||||
Key.Key_Backspace: 'BackSpace',
|
||||
Key.Key_Tab: 'Tab',
|
||||
Key.Key_Backtab: 'Tab',
|
||||
# Key.Key_Clear : 'Clear',
|
||||
Key.Key_Return: 'Return',
|
||||
Key.Key_Enter: 'Return',
|
||||
Key.Key_Shift: 'Shift_L',
|
||||
Key.Key_Control: 'Control_L',
|
||||
Key.Key_Alt: 'Alt_L',
|
||||
Key.Key_Pause: 'Pause',
|
||||
Key.Key_CapsLock: 'Caps_Lock',
|
||||
Key.Key_Escape: 'Escape',
|
||||
Key.Key_Space: 'space',
|
||||
# Key.Key_Prior : 'Prior',
|
||||
# Key.Key_Next : 'Next',
|
||||
Key.Key_End: 'End',
|
||||
Key.Key_Home: 'Home',
|
||||
Key.Key_Left: 'Left',
|
||||
Key.Key_Up: 'Up',
|
||||
Key.Key_Right: 'Right',
|
||||
Key.Key_Down: 'Down',
|
||||
Key.Key_SysReq: 'Snapshot',
|
||||
Key.Key_Insert: 'Insert',
|
||||
Key.Key_Delete: 'Delete',
|
||||
Key.Key_Help: 'Help',
|
||||
Key.Key_0: '0',
|
||||
Key.Key_1: '1',
|
||||
Key.Key_2: '2',
|
||||
Key.Key_3: '3',
|
||||
Key.Key_4: '4',
|
||||
Key.Key_5: '5',
|
||||
Key.Key_6: '6',
|
||||
Key.Key_7: '7',
|
||||
Key.Key_8: '8',
|
||||
Key.Key_9: '9',
|
||||
Key.Key_A: 'a',
|
||||
Key.Key_B: 'b',
|
||||
Key.Key_C: 'c',
|
||||
Key.Key_D: 'd',
|
||||
Key.Key_E: 'e',
|
||||
Key.Key_F: 'f',
|
||||
Key.Key_G: 'g',
|
||||
Key.Key_H: 'h',
|
||||
Key.Key_I: 'i',
|
||||
Key.Key_J: 'j',
|
||||
Key.Key_K: 'k',
|
||||
Key.Key_L: 'l',
|
||||
Key.Key_M: 'm',
|
||||
Key.Key_N: 'n',
|
||||
Key.Key_O: 'o',
|
||||
Key.Key_P: 'p',
|
||||
Key.Key_Q: 'q',
|
||||
Key.Key_R: 'r',
|
||||
Key.Key_S: 's',
|
||||
Key.Key_T: 't',
|
||||
Key.Key_U: 'u',
|
||||
Key.Key_V: 'v',
|
||||
Key.Key_W: 'w',
|
||||
Key.Key_X: 'x',
|
||||
Key.Key_Y: 'y',
|
||||
Key.Key_Z: 'z',
|
||||
Key.Key_Asterisk: 'asterisk',
|
||||
Key.Key_Plus: 'plus',
|
||||
Key.Key_Minus: 'minus',
|
||||
Key.Key_Period: 'period',
|
||||
Key.Key_Slash: 'slash',
|
||||
Key.Key_F1: 'F1',
|
||||
Key.Key_F2: 'F2',
|
||||
Key.Key_F3: 'F3',
|
||||
Key.Key_F4: 'F4',
|
||||
Key.Key_F5: 'F5',
|
||||
Key.Key_F6: 'F6',
|
||||
Key.Key_F7: 'F7',
|
||||
Key.Key_F8: 'F8',
|
||||
Key.Key_F9: 'F9',
|
||||
Key.Key_F10: 'F10',
|
||||
Key.Key_F11: 'F11',
|
||||
Key.Key_F12: 'F12',
|
||||
Key.Key_F13: 'F13',
|
||||
Key.Key_F14: 'F14',
|
||||
Key.Key_F15: 'F15',
|
||||
Key.Key_F16: 'F16',
|
||||
Key.Key_F17: 'F17',
|
||||
Key.Key_F18: 'F18',
|
||||
Key.Key_F19: 'F19',
|
||||
Key.Key_F20: 'F20',
|
||||
Key.Key_F21: 'F21',
|
||||
Key.Key_F22: 'F22',
|
||||
Key.Key_F23: 'F23',
|
||||
Key.Key_F24: 'F24',
|
||||
Key.Key_NumLock: 'Num_Lock',
|
||||
Key.Key_ScrollLock: 'Scroll_Lock',
|
||||
}
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(PyQtImpl)
|
||||
QVTKRenderWidgetConeExample()
|
||||
@@ -0,0 +1,47 @@
|
||||
"""Qt module for VTK/Python.
|
||||
|
||||
Example usage:
|
||||
|
||||
import sys
|
||||
import PyQt5
|
||||
from PyQt5.QtWidgets import QApplication
|
||||
from vtkmodules.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
|
||||
|
||||
app = QApplication(sys.argv)
|
||||
|
||||
widget = QVTKRenderWindowInteractor()
|
||||
widget.Initialize()
|
||||
widget.Start()
|
||||
|
||||
renwin = widget.GetRenderWindow()
|
||||
|
||||
For more information, see QVTKRenderWidgetConeExample() in the file
|
||||
QVTKRenderWindowInteractor.py.
|
||||
"""
|
||||
|
||||
import importlib
|
||||
import sys
|
||||
|
||||
# PyQtImpl can be set by the user
|
||||
PyQtImpl = None
|
||||
|
||||
# Has an implementation has been imported yet?
|
||||
for impl in ["PySide6", "PyQt6", "PyQt5", "PySide2", "PyQt4", "PySide"]:
|
||||
if impl in sys.modules:
|
||||
# Sometimes an attempted import can be crufty (e.g., unclean
|
||||
# uninstalls of PyQt5), so let's try to import the actual functionality
|
||||
try:
|
||||
importlib.import_module(impl + '.QtCore')
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
PyQtImpl = impl
|
||||
break
|
||||
|
||||
# QVTKRWIBase, base class for QVTKRenderWindowInteractor,
|
||||
# can be altered by the user to "QGLWidget" or "QOpenGLWidget"
|
||||
# in case of rendering errors (e.g. depth check problems,
|
||||
# readGLBuffer warnings...)
|
||||
QVTKRWIBase = "QWidget"
|
||||
|
||||
__all__ = ['QVTKRenderWindowInteractor']
|
||||
@@ -0,0 +1,96 @@
|
||||
from vtkmodules.util import vtkMethodParser
|
||||
|
||||
|
||||
class Tester:
|
||||
def __init__(self, debug=0):
|
||||
self.setDebug(debug)
|
||||
self.parser = vtkMethodParser.VtkDirMethodParser()
|
||||
self.obj = None
|
||||
|
||||
def setDebug(self, val):
|
||||
"""Sets debug value of the vtkMethodParser. 1 is verbose and
|
||||
0 is not. 0 is default."""
|
||||
vtkMethodParser.DEBUG = val
|
||||
|
||||
def testParse(self, obj):
|
||||
""" Testing if the object is parseable."""
|
||||
self.parser.parse_methods(obj)
|
||||
self.obj = obj
|
||||
|
||||
def testGetSet(self, obj, excluded_methods=[]):
|
||||
""" Testing Get/Set methods."""
|
||||
if obj != self.obj:
|
||||
self.testParse(obj)
|
||||
methods = self.parser.get_set_methods()
|
||||
toggle = [x[:-2] for x in self.parser.toggle_methods()]
|
||||
methods.extend(toggle)
|
||||
for method in methods:
|
||||
if method in excluded_methods:
|
||||
continue
|
||||
setm = "Set%s"%method
|
||||
getm = "Get%s"%method
|
||||
val = eval("obj.%s()"%getm)
|
||||
try:
|
||||
eval("obj.%s"%setm)(*val)
|
||||
except TypeError:
|
||||
eval("obj.%s"%setm)(*(val,))
|
||||
|
||||
val1 = eval("obj.%s()"%getm)
|
||||
|
||||
if val1 != val:
|
||||
name = obj.GetClassName()
|
||||
msg = "Failed test for %(name)s.Get/Set%(method)s\n"\
|
||||
"Before Set, value = %(val)s; "\
|
||||
"After Set, value = %(val1)s"%locals()
|
||||
raise AssertionError(msg)
|
||||
|
||||
def testBoolean(self, obj, excluded_methods=[]):
|
||||
""" Testing boolean (On/Off) methods."""
|
||||
if obj != self.obj:
|
||||
self.testParse(obj)
|
||||
methods = self.parser.toggle_methods()
|
||||
for method1 in methods:
|
||||
method = method1[:-2]
|
||||
|
||||
if method in excluded_methods:
|
||||
continue
|
||||
|
||||
getm = "Get%s"%method
|
||||
|
||||
orig_val = eval("obj.%s()"%getm)
|
||||
|
||||
# Turn on
|
||||
eval("obj.%sOn()"%method)
|
||||
val = eval("obj.%s()"%getm)
|
||||
|
||||
if val != 1:
|
||||
name = obj.GetClassName()
|
||||
msg = "Failed test for %(name)s.%(method)sOn\n"\
|
||||
"Result not equal to 1 "%locals()
|
||||
raise AssertionError(msg)
|
||||
|
||||
# Turn on
|
||||
eval("obj.%sOff()"%method)
|
||||
val = eval("obj.%s()"%getm)
|
||||
|
||||
if val != 0:
|
||||
name = obj.GetClassName()
|
||||
msg = "Failed test for %(name)s.%(method)sOff\n"\
|
||||
"Result not equal to 0 "%locals()
|
||||
raise AssertionError(msg)
|
||||
|
||||
# set the value back to the original value.
|
||||
eval("obj.Set%s(orig_val)"%method)
|
||||
|
||||
|
||||
def test(self, obj):
|
||||
"""Test the given vtk object."""
|
||||
|
||||
# first try parsing the object.
|
||||
self.testParse(obj)
|
||||
|
||||
# test the get/set methods
|
||||
self.testGetSet(obj)
|
||||
|
||||
# test the boolean methods
|
||||
self.testBoolean(obj)
|
||||
@@ -0,0 +1,53 @@
|
||||
from vtkmodules.vtkCommonCore import vtkCommand
|
||||
|
||||
|
||||
class vtkErrorObserver(object):
|
||||
def __init__(self):
|
||||
self.CallDataType = 'string0'
|
||||
self.reset()
|
||||
|
||||
def __call__(self, caller, event, data):
|
||||
if event == 'ErrorEvent':
|
||||
self._error_message = data
|
||||
elif event == 'WarningEvent':
|
||||
self._warning_message = data
|
||||
|
||||
def _check(self, seen, actual, expect, what):
|
||||
if seen:
|
||||
if actual.find(expect) == -1:
|
||||
msg = 'ERROR: %s message does not contain "%s" got \n"%s"' \
|
||||
% (what, expect, self.error_message)
|
||||
raise RuntimeError(msg)
|
||||
else:
|
||||
what = what.lower()
|
||||
msg = 'ERROR: Failed to catch any %s. ' \
|
||||
'Expected the %s message to contain "%s"' \
|
||||
% (what, what, expect)
|
||||
raise RuntimeError(msg)
|
||||
self.reset()
|
||||
|
||||
def check_error(self, expect):
|
||||
self._check(self.saw_error, self.error_message, expect, 'Error')
|
||||
|
||||
def check_warning(self, expect):
|
||||
self._check(self.saw_warning, self.warning_message, expect, 'Warning')
|
||||
|
||||
def reset(self):
|
||||
self._error_message = None
|
||||
self._warning_message = None
|
||||
|
||||
@property
|
||||
def saw_error(self):
|
||||
return self._error_message is not None
|
||||
|
||||
@property
|
||||
def error_message(self):
|
||||
return self._error_message
|
||||
|
||||
@property
|
||||
def saw_warning(self):
|
||||
return self._warning_message is not None
|
||||
|
||||
@property
|
||||
def warning_message(self):
|
||||
return self._warning_message
|
||||
@@ -0,0 +1,603 @@
|
||||
""" This module attempts to make it easy to create VTK-Python
|
||||
unittests. The module uses unittest for the test interface. For more
|
||||
documentation on what unittests are and how to use them, please read
|
||||
these:
|
||||
|
||||
http://www.python.org/doc/current/lib/module-unittest.html
|
||||
|
||||
http://www.diveintopython.org/roman_divein.html
|
||||
|
||||
|
||||
This VTK-Python test module supports image based tests with multiple
|
||||
images per test suite and multiple images per individual test as well.
|
||||
It also prints information appropriate for CDash
|
||||
(http://open.kitware.com/).
|
||||
|
||||
This module defines several useful classes and functions to make
|
||||
writing tests easy. The most important of these are:
|
||||
|
||||
class vtkTest:
|
||||
Subclass this for your tests. It also has a few useful internal
|
||||
functions that can be used to do some simple blackbox testing.
|
||||
|
||||
compareImage(renwin, img_fname, threshold=0.05):
|
||||
Compares renwin with image and generates image if it does not
|
||||
exist. The threshold determines how closely the images must match.
|
||||
The function also handles multiple images and finds the best
|
||||
matching image.
|
||||
|
||||
compareImageWithSavedImage(src_img, img_fname, threshold=0.05):
|
||||
Compares given source image (in the form of a vtkImageData) with
|
||||
saved image and generates the image if it does not exist. The
|
||||
threshold determines how closely the images must match. The
|
||||
function also handles multiple images and finds the best matching
|
||||
image.
|
||||
|
||||
getAbsImagePath(img_basename):
|
||||
Returns the full path to the image given the basic image name.
|
||||
|
||||
main(cases):
|
||||
Does the testing given a list of tuples containing test classes and
|
||||
the starting string of the functions used for testing.
|
||||
|
||||
interact():
|
||||
Interacts with the user if necessary. The behavior of this is
|
||||
rather trivial and works best when using Tkinter. It does not do
|
||||
anything by default and stops to interact with the user when given
|
||||
the appropriate command line arguments.
|
||||
|
||||
isInteractive():
|
||||
If interact() is not good enough, use this to find if the mode is
|
||||
interactive or not and do whatever is necessary to generate an
|
||||
interactive view.
|
||||
|
||||
Examples:
|
||||
|
||||
The best way to learn on how to use this module is to look at a few
|
||||
examples. The end of this file contains a trivial example. Please
|
||||
also look at the following examples:
|
||||
|
||||
Rendering/Testing/Python/TestTkRenderWidget.py,
|
||||
Rendering/Testing/Python/TestTkRenderWindowInteractor.py
|
||||
|
||||
Created: September, 2002
|
||||
|
||||
Prabhu Ramachandran <prabhu@aero.iitb.ac.in>
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
import sys, os, time
|
||||
import os.path
|
||||
import unittest, getopt
|
||||
from vtkmodules.vtkCommonCore import vtkCommand, vtkDebugLeaks, reference
|
||||
from vtkmodules.vtkCommonSystem import vtkTimerLog
|
||||
from vtkmodules.vtkIOImage import vtkPNGWriter
|
||||
from vtkmodules.vtkRenderingCore import vtkWindowToImageFilter
|
||||
from vtkmodules.vtkTestingRendering import vtkTesting
|
||||
from . import BlackBox
|
||||
|
||||
# location of the VTK data files. Set via command line args or
|
||||
# environment variable.
|
||||
VTK_DATA_ROOT = ""
|
||||
|
||||
# a list of paths to specific input data files
|
||||
VTK_DATA_PATHS = []
|
||||
|
||||
# location of the VTK baseline images. Set via command line args or
|
||||
# environment variable.
|
||||
VTK_BASELINE_ROOT = ""
|
||||
|
||||
# location of the VTK difference images for failed tests. Set via
|
||||
# command line args or environment variable.
|
||||
VTK_TEMP_DIR = ""
|
||||
|
||||
# a list of paths to validated output files
|
||||
VTK_BASELINE_PATHS = []
|
||||
|
||||
# Verbosity of the test messages (used by unittest)
|
||||
_VERBOSE = 0
|
||||
|
||||
# Determines if it is necessary to interact with the user. If zero
|
||||
# don't interact if 1 interact. Set via command line args
|
||||
_INTERACT = 0
|
||||
|
||||
# This will be set to 1 when the image test will not be performed.
|
||||
# This option is used internally by the script and set via command
|
||||
# line arguments.
|
||||
_NO_IMAGE = 0
|
||||
|
||||
def skip():
|
||||
'''Cause the test to be skipped due to insufficient requirements.'''
|
||||
sys.exit(125)
|
||||
|
||||
|
||||
class vtkTest(unittest.TestCase):
|
||||
"""A simple default VTK test class that defines a few useful
|
||||
blackbox tests that can be readily used. Derive your test cases
|
||||
from this class and use the following if you'd like to.
|
||||
|
||||
Note: Unittest instantiates this class (or your subclass) each
|
||||
time it tests a method. So if you do not want that to happen when
|
||||
generating VTK pipelines you should create the pipeline in the
|
||||
class definition as done below for _blackbox.
|
||||
"""
|
||||
|
||||
_blackbox = BlackBox.Tester(debug=0)
|
||||
|
||||
# Due to what seems to be a bug in python some objects leak.
|
||||
# Avoid the exit-with-error in vtkDebugLeaks.
|
||||
dl = vtkDebugLeaks()
|
||||
dl.SetExitError(0)
|
||||
dl = None
|
||||
|
||||
def _testParse(self, obj):
|
||||
"""Does a blackbox test by attempting to parse the class for
|
||||
its various methods using vtkMethodParser. This is a useful
|
||||
test because it gets all the methods of the vtkObject, parses
|
||||
them and sorts them into different classes of objects."""
|
||||
self._blackbox.testParse(obj)
|
||||
|
||||
def _testGetSet(self, obj, excluded_methods=[]):
|
||||
"""Checks the Get/Set method pairs by setting the value using
|
||||
the current state and making sure that it equals the value it
|
||||
was originally. This effectively calls _testParse
|
||||
internally. """
|
||||
self._blackbox.testGetSet(obj, excluded_methods)
|
||||
|
||||
def _testBoolean(self, obj, excluded_methods=[]):
|
||||
"""Checks the Boolean methods by setting the value on and off
|
||||
and making sure that the GetMethod returns the set value.
|
||||
This effectively calls _testParse internally. """
|
||||
self._blackbox.testBoolean(obj, excluded_methods)
|
||||
|
||||
def pathToData(self, filename):
|
||||
"""Given a filename with no path (i.e., no leading directories
|
||||
prepended), return the full path to a file as specified on the
|
||||
command line with a '-D' option.
|
||||
|
||||
As an example, if a test is run with "-D /path/to/grid.vtu"
|
||||
then calling
|
||||
|
||||
self.pathToData('grid.vtu')
|
||||
|
||||
in your test will return "/path/to/grid.vtu". This is
|
||||
useful in combination with ExternalData, where data may be
|
||||
staged by CTest to a user-configured directory at build time.
|
||||
|
||||
In order for this method to work, you must specify
|
||||
the JUST_VALID option for your test in CMake.
|
||||
"""
|
||||
global VTK_DATA_PATHS
|
||||
if not filename:
|
||||
return VTK_DATA_PATHS
|
||||
for path in VTK_DATA_PATHS:
|
||||
if filename == os.path.split(path)[-1]:
|
||||
return path
|
||||
return filename
|
||||
|
||||
def pathToValidatedOutput(self, filename):
|
||||
"""Given a filename with no path (i.e., no leading directories
|
||||
prepended), return the full path to a file as specified on the
|
||||
command line with a '-V' option.
|
||||
|
||||
As an example, if a test is run with
|
||||
"-V /path/to/validImage.png" then calling
|
||||
|
||||
self.pathToData('validImage.png')
|
||||
|
||||
in your test will return "/path/to/validImage.png". This is
|
||||
useful in combination with ExternalData, where data may be
|
||||
staged by CTest to a user-configured directory at build time.
|
||||
|
||||
In order for this method to work, you must specify
|
||||
the JUST_VALID option for your test in CMake.
|
||||
"""
|
||||
global VTK_BASELINE_PATHS
|
||||
if not filename:
|
||||
return VTK_BASELINE_PATHS
|
||||
for path in VTK_BASELINE_PATHS:
|
||||
if filename == os.path.split(path)[-1]:
|
||||
return path
|
||||
return filename
|
||||
|
||||
def prepareTestImage(self, interactor, **kwargs):
|
||||
import time
|
||||
startTime = time.time()
|
||||
events = []
|
||||
|
||||
def onKeyPress(caller, eventId):
|
||||
print('key is "' + caller.GetKeySym() + '"')
|
||||
events.append((time.time() - startTime, eventId, caller.GetKeySym()))
|
||||
|
||||
def onButton(caller, eventId):
|
||||
events.append((time.time() - startTime, eventId))
|
||||
|
||||
def onMovement(caller, eventId):
|
||||
events.append((time.time() - startTime, eventId, caller.GetEventPosition()))
|
||||
|
||||
interactor.AddObserver(vtkCommand.KeyPressEvent, onKeyPress)
|
||||
interactor.AddObserver(vtkCommand.LeftButtonPressEvent, onButton)
|
||||
interactor.AddObserver(vtkCommand.LeftButtonReleaseEvent, onButton)
|
||||
interactor.AddObserver(vtkCommand.MouseMoveEvent, onMovement)
|
||||
interactor.Start()
|
||||
rw = interactor.GetRenderWindow()
|
||||
baseline = 'baselineFilename'
|
||||
if 'filename' in kwargs:
|
||||
# Render an image and save it to the given filename
|
||||
w2if = vtkWindowToImageFilter()
|
||||
w2if.ReadFrontBufferOff()
|
||||
w2if.SetInput(rw)
|
||||
w2if.Update()
|
||||
baselineWithPath = kwargs['filename']
|
||||
baseline = os.path.split(baselineWithPath)[-1]
|
||||
pngw = vtkPNGWriter()
|
||||
pngw.SetFileName(baselineWithPath)
|
||||
pngw.SetInputConnection(w2if.GetOutputPort())
|
||||
try:
|
||||
pngw.Write()
|
||||
except RuntimeError:
|
||||
w2if.ReadFrontBufferOn()
|
||||
pngw.Write()
|
||||
rsz = rw.GetSize()
|
||||
rrc = rw.GetRenderers()
|
||||
rrs = [rrc.GetItemAsObject(i) for i in range(rrc.GetNumberOfItems())]
|
||||
eye = [0,0,1]
|
||||
aim = [0,0,0]
|
||||
up = [0,1,0]
|
||||
if len(rrs) > 0:
|
||||
cam = rrs[0].GetActiveCamera()
|
||||
eye = cam.GetPosition()
|
||||
aim = cam.GetFocalPoint()
|
||||
up = cam.GetViewUp()
|
||||
print("""
|
||||
Replace prepareTestImage() in your script with the following to make a test:
|
||||
|
||||
camera.SetPosition({eye[0]}, {eye[1]}, {eye[2]})
|
||||
camera.SetFocalPoint({aim[0]}, {aim[1]}, {aim[2]})
|
||||
camera.SetViewUp({up[0]}, {up[1]}, {up[2]})
|
||||
renwin.SetSize({rsz[0]}, {rsz[1]})
|
||||
self.assertImageMatch(renwin, '{baseline}')
|
||||
|
||||
Be sure that "renwin" and "camera" are valid variables (or rename them in the
|
||||
snippet above) referencing the vtkRenderWindow and vtkCamera, respectively.
|
||||
""".format(eye=eye, aim=aim, up=up, rsz=rsz, baseline=baseline))
|
||||
return events
|
||||
|
||||
def assertImageMatch(self, renwin, baseline, **kwargs):
|
||||
"""Throw an error if a rendering in the render window does not match the baseline image.
|
||||
|
||||
This method accepts a threshold keyword argument (with a default of 0.15)
|
||||
that specifies how different a baseline may be before causing a failure.
|
||||
"""
|
||||
absoluteBaseline = baseline
|
||||
try:
|
||||
open(absoluteBaseline, 'r')
|
||||
except:
|
||||
absoluteBaseline = getAbsImagePath(baseline)
|
||||
compareImage(renwin, absoluteBaseline, **kwargs)
|
||||
|
||||
def interact():
|
||||
"""Interacts with the user if necessary. """
|
||||
global _INTERACT
|
||||
if _INTERACT:
|
||||
input("\nPress Enter/Return to continue with the testing. --> ")
|
||||
|
||||
def isInteractive():
|
||||
"""Returns if the currently chosen mode is interactive or not
|
||||
based on command line options."""
|
||||
return _INTERACT
|
||||
|
||||
def getAbsImagePath(img_basename):
|
||||
"""Returns the full path to the image given the basic image
|
||||
name."""
|
||||
for path in VTK_BASELINE_PATHS:
|
||||
if os.path.basename(path) == img_basename:
|
||||
return path
|
||||
return os.path.join(VTK_BASELINE_ROOT, img_basename)
|
||||
|
||||
def _getTempImagePath(img_fname):
|
||||
x = os.path.join(VTK_TEMP_DIR, os.path.split(img_fname)[1])
|
||||
return os.path.abspath(x)
|
||||
|
||||
|
||||
def _GetController():
|
||||
try:
|
||||
from vtkmodules.vtkParallelMPI import vtkMPIController
|
||||
controller = vtkMPIController();
|
||||
|
||||
# If MPI was not initialized, we do not want to use MPI
|
||||
if not controller.GetCommunicator():
|
||||
return None
|
||||
return controller
|
||||
except:
|
||||
pass
|
||||
return None
|
||||
|
||||
def compareImageWithSavedImage(src_img, img_fname, threshold=0.05):
|
||||
"""Compares a source image (src_img, which is a vtkImageData) with
|
||||
the saved image file whose name is given in the second argument.
|
||||
If the image file does not exist the image is generated and
|
||||
stored. If not the source image is compared to that of the
|
||||
figure. This function also handles multiple images and finds the
|
||||
best matching image.
|
||||
"""
|
||||
global _NO_IMAGE, VTK_TEMP_DIR
|
||||
if _NO_IMAGE:
|
||||
return
|
||||
|
||||
# create the testing class to do the work
|
||||
rtTester = vtkTesting()
|
||||
|
||||
# Set the controller if possible
|
||||
try:
|
||||
rtTester.SetController(_GetController())
|
||||
except:
|
||||
pass
|
||||
|
||||
# Add temp directory to the arguments
|
||||
if len(VTK_TEMP_DIR) != 0:
|
||||
rtTester.AddArgument("-T")
|
||||
rtTester.AddArgument(VTK_TEMP_DIR)
|
||||
# Add image file name to the arguments
|
||||
rtTester.AddArgument("-V")
|
||||
rtTester.AddArgument(img_fname)
|
||||
|
||||
output_string = reference("")
|
||||
result = rtTester.RegressionTest(src_img, threshold, output_string)
|
||||
|
||||
# If the test failed, raise an exception
|
||||
if result == vtkTesting.FAILED:
|
||||
raise RuntimeError(output_string.get())
|
||||
# If the test passed, print the output
|
||||
else:
|
||||
print(output_string.get())
|
||||
|
||||
def compareImage(renwin, img_fname, threshold=0.05):
|
||||
"""Compares renwin's (a vtkRenderWindow) contents with the image
|
||||
file whose name is given in the second argument. If the image
|
||||
file does not exist the image is generated and stored. If not the
|
||||
image in the render window is compared to that of the figure.
|
||||
This function also handles multiple images and finds the best
|
||||
matching image. """
|
||||
|
||||
global _NO_IMAGE
|
||||
if _NO_IMAGE:
|
||||
return
|
||||
|
||||
w2if = vtkWindowToImageFilter()
|
||||
w2if.ReadFrontBufferOff()
|
||||
w2if.SetInput(renwin)
|
||||
w2if.Update()
|
||||
try:
|
||||
compareImageWithSavedImage(w2if, img_fname, threshold)
|
||||
except RuntimeError:
|
||||
w2if.ReadFrontBufferOn()
|
||||
compareImageWithSavedImage(w2if, img_fname, threshold)
|
||||
return
|
||||
|
||||
def main(cases):
|
||||
""" Pass a list of tuples containing test classes and the starting
|
||||
string of the functions used for testing.
|
||||
|
||||
Example:
|
||||
|
||||
main ([(vtkTestClass, 'test'), (vtkTestClass1, 'test')])
|
||||
"""
|
||||
|
||||
processCmdLine()
|
||||
|
||||
timer = vtkTimerLog()
|
||||
s_time = timer.GetCPUTime()
|
||||
s_wall_time = time.time()
|
||||
|
||||
# run the tests
|
||||
result = test(cases)
|
||||
|
||||
tot_time = timer.GetCPUTime() - s_time
|
||||
tot_wall_time = float(time.time() - s_wall_time)
|
||||
|
||||
# output measurements for CDash
|
||||
print("<DartMeasurement name=\"WallTime\" type=\"numeric/double\"> "
|
||||
" %f </DartMeasurement>"%tot_wall_time)
|
||||
print("<DartMeasurement name=\"CPUTime\" type=\"numeric/double\"> "
|
||||
" %f </DartMeasurement>"%tot_time)
|
||||
|
||||
# Delete these to eliminate debug leaks warnings.
|
||||
del cases, timer
|
||||
|
||||
if result.wasSuccessful():
|
||||
sys.exit(0)
|
||||
else:
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def test(cases):
|
||||
""" Pass a list of tuples containing test classes and the
|
||||
functions used for testing.
|
||||
|
||||
It returns a unittest._TextTestResult object.
|
||||
|
||||
Example:
|
||||
|
||||
test = test_suite([(vtkTestClass, 'test'),
|
||||
(vtkTestClass1, 'test')])
|
||||
"""
|
||||
# Make the test suites from the arguments.
|
||||
suites = []
|
||||
loader = unittest.TestLoader()
|
||||
# the "name" is ignored (it was always just 'test')
|
||||
for test,name in cases:
|
||||
suites.append(loader.loadTestsFromTestCase(test))
|
||||
test_suite = unittest.TestSuite(suites)
|
||||
|
||||
# Now run the tests.
|
||||
runner = unittest.TextTestRunner(verbosity=_VERBOSE)
|
||||
result = runner.run(test_suite)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def usage():
|
||||
msg="""Usage:\nTestScript.py [options]\nWhere options are:\n
|
||||
|
||||
-D /path/to/VTKData
|
||||
--data-dir /path/to/VTKData
|
||||
|
||||
Directory containing VTK Data use for tests. If this option
|
||||
is not set via the command line the environment variable
|
||||
VTK_DATA_ROOT is used. If the environment variable is not
|
||||
set the value defaults to '../../../../../VTKData'.
|
||||
|
||||
-B /path/to/valid/image_dir/
|
||||
--baseline-root /path/to/valid/image_dir/
|
||||
|
||||
This is a path to the directory containing the valid images
|
||||
for comparison. If this option is not set via the command
|
||||
line the environment variable VTK_BASELINE_ROOT is used. If
|
||||
the environment variable is not set the value defaults to
|
||||
the same value set for -D (--data-dir).
|
||||
|
||||
-T /path/to/valid/temporary_dir/
|
||||
--temp-dir /path/to/valid/temporary_dir/
|
||||
|
||||
This is a path to the directory where the image differences
|
||||
are written. If this option is not set via the command line
|
||||
the environment variable VTK_TEMP_DIR is used. If the
|
||||
environment variable is not set the value defaults to
|
||||
'../../../../Testing/Temporary'.
|
||||
|
||||
-V /path/to/validated/output.png
|
||||
--validated-output /path/to/valid/output.png
|
||||
|
||||
This is a path to a file (usually but not always an image)
|
||||
which is compared to data generated by the test.
|
||||
|
||||
-v level
|
||||
--verbose level
|
||||
|
||||
Sets the verbosity of the test runner. Valid values are 0,
|
||||
1, and 2 in increasing order of verbosity.
|
||||
|
||||
-I
|
||||
--interact
|
||||
|
||||
Interacts with the user when chosen. If this is not chosen
|
||||
the test will run and exit as soon as it is finished. When
|
||||
enabled, the behavior of this is rather trivial and works
|
||||
best when the test uses Tkinter.
|
||||
|
||||
-n
|
||||
--no-image
|
||||
|
||||
Does not do any image comparisons. This is useful if you
|
||||
want to run the test and not worry about test images or
|
||||
image failures etc.
|
||||
|
||||
-h
|
||||
--help
|
||||
|
||||
Prints this message.
|
||||
|
||||
"""
|
||||
return msg
|
||||
|
||||
|
||||
def parseCmdLine():
|
||||
arguments = sys.argv[1:]
|
||||
|
||||
options = "B:D:T:V:v:hnI"
|
||||
long_options = ['baseline-root=', 'data-dir=', 'temp-dir=',
|
||||
'validated-output=', 'verbose=', 'help',
|
||||
'no-image', 'interact']
|
||||
|
||||
try:
|
||||
# getopt expects options to be first
|
||||
first = 0
|
||||
for i, arg in enumerate(arguments):
|
||||
if arg.startswith('-'):
|
||||
first = i
|
||||
break
|
||||
opts, args = getopt.getopt(arguments[first:], options, long_options)
|
||||
except getopt.error as msg:
|
||||
print(usage())
|
||||
print('-'*70)
|
||||
print(msg)
|
||||
sys.exit (1)
|
||||
|
||||
return opts, args
|
||||
|
||||
|
||||
def processCmdLine():
|
||||
opts, args = parseCmdLine()
|
||||
|
||||
global VTK_DATA_ROOT, VTK_BASELINE_ROOT, VTK_TEMP_DIR, VTK_BASELINE_PATHS
|
||||
global _VERBOSE, _NO_IMAGE, _INTERACT
|
||||
|
||||
# setup defaults
|
||||
try:
|
||||
VTK_DATA_ROOT = os.environ['VTK_DATA_ROOT']
|
||||
except KeyError:
|
||||
VTK_DATA_ROOT = os.path.normpath("../../../../../VTKData")
|
||||
|
||||
try:
|
||||
VTK_BASELINE_ROOT = os.environ['VTK_BASELINE_ROOT']
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
try:
|
||||
VTK_TEMP_DIR = os.environ['VTK_TEMP_DIR']
|
||||
except KeyError:
|
||||
VTK_TEMP_DIR = os.path.normpath("../../../../Testing/Temporary")
|
||||
|
||||
for o, a in opts:
|
||||
if o in ('-D', '--data-dir'):
|
||||
oa = os.path.abspath(a)
|
||||
if os.path.isfile(oa):
|
||||
VTK_DATA_PATHS.append(oa)
|
||||
else:
|
||||
VTK_DATA_ROOT = oa
|
||||
if o in ('-B', '--baseline-root'):
|
||||
VTK_BASELINE_ROOT = os.path.abspath(a)
|
||||
if o in ('-T', '--temp-dir'):
|
||||
VTK_TEMP_DIR = os.path.abspath(a)
|
||||
if o in ('-V', '--validated-output'):
|
||||
VTK_BASELINE_PATHS.append(os.path.abspath(a))
|
||||
if o in ('-n', '--no-image'):
|
||||
_NO_IMAGE = 1
|
||||
if o in ('-I', '--interact'):
|
||||
_INTERACT = 1
|
||||
if o in ('-v', '--verbose'):
|
||||
try:
|
||||
_VERBOSE = int(a)
|
||||
except:
|
||||
msg="Verbosity should be an integer. 0, 1, 2 are valid."
|
||||
print(msg)
|
||||
sys.exit(1)
|
||||
if o in ('-h', '--help'):
|
||||
print(usage())
|
||||
sys.exit()
|
||||
|
||||
if not VTK_BASELINE_ROOT: # default value.
|
||||
VTK_BASELINE_ROOT = VTK_DATA_ROOT
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
######################################################################
|
||||
# A Trivial test case to illustrate how this module works.
|
||||
class SampleTest(vtkTest):
|
||||
from vtkmodules.vtkRenderingCore import vtkActor
|
||||
obj = vtkActor()
|
||||
def testParse(self):
|
||||
"Test if class is parseable"
|
||||
self._testParse(self.obj)
|
||||
|
||||
def testGetSet(self):
|
||||
"Testing Get/Set methods"
|
||||
self._testGetSet(self.obj)
|
||||
|
||||
def testBoolean(self):
|
||||
"Testing Boolean methods"
|
||||
self._testBoolean(self.obj)
|
||||
|
||||
# Test with the above trivial sample test.
|
||||
main( [ (SampleTest, 'test') ] )
|
||||
@@ -0,0 +1,4 @@
|
||||
"""Modules used for testing VTK-Python wrappers and writing tests for
|
||||
VTK using Python."""
|
||||
|
||||
__all__ = ['Testing', 'BlackBox', 'ErrorObserver', 'rtImageTest']
|
||||
@@ -0,0 +1,140 @@
|
||||
#!/usr/bin/env python
|
||||
# This is the script that runs Python regression test scripts.
|
||||
# The test script to be run must be the first argument.
|
||||
|
||||
from vtkmodules.vtkCommonCore import vtkMath
|
||||
from vtkmodules.vtkTestingRendering import vtkTesting
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
import traceback
|
||||
|
||||
def _GetController():
|
||||
try:
|
||||
from vtkmodules.vtkParallelMPI import vtkMPIController
|
||||
controller = vtkMPIController();
|
||||
|
||||
# If MPI was not initialized, we do not want to use MPI
|
||||
if not controller.GetCommunicator():
|
||||
return None
|
||||
return controller
|
||||
except:
|
||||
pass
|
||||
return None
|
||||
|
||||
def main(test_script):
|
||||
"""Run a regression test, and compare the contents of the window against
|
||||
against a valid image. This will use arguments from sys.argv to set the
|
||||
testing options via the vtkTesting class, run the test script, and then
|
||||
call vtkTesting.RegressionTest() to validate the image. The return
|
||||
value will the one provided by vtkTesting.RegressionTest().
|
||||
"""
|
||||
|
||||
# find the first argument that's an option
|
||||
opt1 = 1
|
||||
while opt1 < len(sys.argv) and not sys.argv[opt1].startswith('-'):
|
||||
opt1 += 1
|
||||
|
||||
# get the "-A" option, which isn't handled by vtkTester
|
||||
for i in range(opt1, len(sys.argv)):
|
||||
if sys.argv[i] == '-A' and i < len(sys.argv) - 1:
|
||||
sys.path.append(sys.argv[i + 1])
|
||||
|
||||
# create the testing class to do the work
|
||||
rtTester = vtkTesting()
|
||||
|
||||
try:
|
||||
rtTester.SetController(_GetController())
|
||||
except:
|
||||
pass
|
||||
|
||||
for arg in sys.argv[opt1:]:
|
||||
rtTester.AddArgument(arg)
|
||||
|
||||
# if test is not interactive, make a mock interactor with a
|
||||
# disabled Start method
|
||||
if rtTester.IsInteractiveModeSpecified() == 0:
|
||||
from vtkmodules.vtkRenderingCore import vtkRenderWindowInteractor
|
||||
import vtkmodules.vtkRenderingUI
|
||||
irenType = type(vtkRenderWindowInteractor())
|
||||
class vtkTestingInteractor(irenType):
|
||||
def Start(self):
|
||||
pass
|
||||
irenType.override(vtkTestingInteractor)
|
||||
|
||||
# seed the random number generator
|
||||
vtkMath.RandomSeed(6)
|
||||
|
||||
# read the test script
|
||||
with open(test_script) as test_file:
|
||||
test_code = test_file.read()
|
||||
|
||||
# inject the test script's directory into sys.path
|
||||
test_script_dir = os.path.abspath(os.path.dirname(test_script))
|
||||
sys.path.insert(0, test_script_dir)
|
||||
|
||||
# we provide an initial set of variables for the test script
|
||||
test_script_vars = { "__name__" : "__main__" }
|
||||
|
||||
try:
|
||||
# run the test and capture all of its global variables
|
||||
exec(compile(test_code, test_script, 'exec'), test_script_vars)
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
return vtkTesting.FAILED
|
||||
finally:
|
||||
# undo the change to the path
|
||||
sys.path.remove(test_script_dir)
|
||||
|
||||
# undo the vtkRenderWindowInteractor override
|
||||
if rtTester.IsInteractiveModeSpecified() == 0:
|
||||
irenType.override(None)
|
||||
|
||||
# if script has "if __name__ == '__main__':", then we assume that
|
||||
# it would have raised an exception or called exit(1) if it failed.
|
||||
if re.search('^if *__name__ *== *[\'\"]__main__[\'\"]', test_code, flags=re.MULTILINE):
|
||||
return vtkTesting.PASSED
|
||||
|
||||
# if script didn't set "threshold", use default value
|
||||
try:
|
||||
threshold = test_script_vars["threshold"]
|
||||
except KeyError:
|
||||
# Used to be 0.15. Changed to 0.05 for new SSIM method.
|
||||
threshold = 0.05
|
||||
|
||||
# we require a valid regression image
|
||||
if rtTester.IsValidImageSpecified():
|
||||
# look for a renderWindow ImageWindow or ImageViewer
|
||||
# first check for some common names
|
||||
if "iren" in test_script_vars:
|
||||
iren = test_script_vars["iren"]
|
||||
rtTester.SetRenderWindow(iren.GetRenderWindow())
|
||||
iren.GetRenderWindow().Render()
|
||||
elif "renWin" in test_script_vars:
|
||||
renWin = test_script_vars["renWin"]
|
||||
rtTester.SetRenderWindow(renWin)
|
||||
elif "viewer" in test_script_vars:
|
||||
viewer = test_script_vars["viewer"]
|
||||
rtTester.SetRenderWindow(viewer.GetRenderWindow())
|
||||
viewer.Render()
|
||||
elif "imgWin" in test_script_vars:
|
||||
imgWin = test_script_vars["imgWin"]
|
||||
rtTester.SetRenderWindow(imgWin)
|
||||
imgWin.Render()
|
||||
else:
|
||||
sys.stderr.write("Test driver rtImageTest.py says \"no iren, renWin, viewer, or imgWin\": %s\n" % test_script)
|
||||
return vtkTesting.FAILED
|
||||
|
||||
return rtTester.RegressionTest(threshold)
|
||||
|
||||
return vtkTesting.FAILED
|
||||
|
||||
if __name__ == '__main__':
|
||||
# We don't parse the arguments (vtkTesting does that), but we need
|
||||
# to extract the name of the test script to run.
|
||||
if len(sys.argv) < 2 or sys.argv[1].startswith('-'):
|
||||
print("Usage %s <test script> [<addition arguments>]" % argv[0])
|
||||
sys.exit(1)
|
||||
|
||||
if main(sys.argv[1]) == vtkTesting.FAILED:
|
||||
sys.exit(1)
|
||||
@@ -0,0 +1,4 @@
|
||||
"""Tkinter widgets for VTK."""
|
||||
|
||||
__all__ = ['vtkTkRenderWidget', 'vtkTkImageViewerWidget',
|
||||
'vtkTkRenderWindowInteractor', 'vtkTkPhotoImage']
|
||||
@@ -0,0 +1,101 @@
|
||||
import sys, os
|
||||
import vtkmodules
|
||||
from vtkmodules.vtkCommonCore import vtkVersion
|
||||
|
||||
def vtkLoadPythonTkWidgets(interp):
|
||||
"""vtkLoadPythonTkWidgets(interp) -- load vtk-tk widget extensions
|
||||
|
||||
This is a mess of mixed python and tcl code that searches for the
|
||||
shared object file that contains the python-vtk-tk widgets. Both
|
||||
the python path and the tcl path are searched.
|
||||
"""
|
||||
modname = 'vtkRenderingTk'
|
||||
VTK_VERSIONED_INSTALL = "ON"
|
||||
VTK_CUSTOM_LIBRARY_VERSION = "9.5"
|
||||
if VTK_VERSIONED_INSTALL in ("0", "OFF", "NO", "FALSE", "N"):
|
||||
name = modname
|
||||
elif VTK_CUSTOM_LIBRARY_VERSION:
|
||||
name = '%s-%s' % (modname,VTK_CUSTOM_LIBRARY_VERSION)
|
||||
else:
|
||||
X = vtkVersion.GetVTKMajorVersion()
|
||||
Y = vtkVersion.GetVTKMinorVersion()
|
||||
name = '%s-%d.%d' % (modname,X,Y)
|
||||
pkgname = modname.lower().capitalize()
|
||||
|
||||
# find out if the module is already loaded
|
||||
loadedpkgs = interp.call('info', 'loaded')
|
||||
found = False
|
||||
try:
|
||||
# check for result returned as a string
|
||||
found = (loadedpkgs.find(pkgname) >= 0)
|
||||
except AttributeError:
|
||||
# check for result returned as nested tuples
|
||||
for pkgtuple in loadedpkgs:
|
||||
found |= (pkgname in pkgtuple)
|
||||
if found:
|
||||
return
|
||||
|
||||
# create the platform-dependent file name
|
||||
prefix = ''
|
||||
if sys.platform == 'cygwin':
|
||||
prefix = 'cyg'
|
||||
elif os.name == 'posix':
|
||||
prefix = 'lib'
|
||||
extension = interp.call('info', 'sharedlibextension')
|
||||
filename = prefix+name+extension
|
||||
|
||||
# create an list of paths to search
|
||||
vtkmodules_dir = os.path.dirname(vtkmodules.__file__)
|
||||
pathlist = [vtkmodules_dir]
|
||||
|
||||
# a likely relative path for linux
|
||||
if sys.platform == 'linux':
|
||||
package_dir = os.path.dirname(vtkmodules_dir)
|
||||
python_dir = os.path.dirname(package_dir)
|
||||
if os.path.basename(python_dir).startswith('python'):
|
||||
lib_dir = os.path.dirname(python_dir)
|
||||
if os.path.basename(lib_dir).startswith('lib'):
|
||||
pathlist.append(lib_dir)
|
||||
|
||||
# add tcl paths, ensure that {} is handled properly
|
||||
try:
|
||||
auto_paths = interp.getvar('auto_path').split()
|
||||
except AttributeError:
|
||||
auto_paths = interp.getvar('auto_path')
|
||||
for path in auto_paths:
|
||||
prev = str(pathlist[-1])
|
||||
try:
|
||||
# try block needed when one uses Gordon McMillan's Python
|
||||
# Installer.
|
||||
if len(prev) > 0 and prev[0] == '{' and prev[-1] != '}':
|
||||
pathlist[-1] = prev+' '+path
|
||||
else:
|
||||
pathlist.append(path)
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
# a common installation path
|
||||
if os.name == 'posix':
|
||||
pathlist.append('/usr/local/lib')
|
||||
|
||||
# attempt to load
|
||||
for path in pathlist:
|
||||
try:
|
||||
# If the path object is not str, it means that it is a
|
||||
# Tkinter path object.
|
||||
if not isinstance(path, str):
|
||||
path = path.string
|
||||
# try block needed when one uses Gordon McMillan's Python
|
||||
# Installer.
|
||||
if len(path) > 0 and path[0] == '{' and path[-1] == '}':
|
||||
path = path[1:-1]
|
||||
fullpath = os.path.join(path, filename)
|
||||
except AttributeError:
|
||||
pass
|
||||
if ' ' in fullpath:
|
||||
fullpath = '{'+fullpath+'}'
|
||||
if interp.eval('catch {load '+fullpath+' '+pkgname+'}') == '0':
|
||||
return
|
||||
|
||||
# re-generate the error
|
||||
interp.call('load', filename, pkgname)
|
||||
@@ -0,0 +1,366 @@
|
||||
"""
|
||||
A vtkTkImageViewerWidget for python, which is based on the
|
||||
vtkTkImageWindowWidget.
|
||||
|
||||
Specify double=1 to get a double-buffered window.
|
||||
|
||||
Created by David Gobbi, Nov 1999
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
import math, os, sys
|
||||
from vtkmodules.vtkCommonExecutionModel import vtkStreamingDemandDrivenPipeline
|
||||
from vtkmodules.vtkInteractionImage import vtkImageViewer
|
||||
from vtkmodules.vtkRenderingCore import vtkActor2D, vtkTextMapper
|
||||
|
||||
import tkinter
|
||||
|
||||
from .vtkLoadPythonTkWidgets import vtkLoadPythonTkWidgets
|
||||
|
||||
class vtkTkImageViewerWidget(tkinter.Widget):
|
||||
"""
|
||||
A vtkTkImageViewerWidget for Python.
|
||||
|
||||
Use GetImageViewer() to get the vtkImageViewer.
|
||||
|
||||
Create with the keyword double=1 in order to generate a
|
||||
double-buffered viewer.
|
||||
|
||||
Create with the keyword focus_on_enter=1 to enable
|
||||
focus-follows-mouse. The default is for a click-to-focus mode.
|
||||
"""
|
||||
def __init__(self, master, cnf={}, **kw):
|
||||
"""
|
||||
Constructor.
|
||||
|
||||
Keyword arguments:
|
||||
|
||||
iv -- Use passed image viewer instead of creating a new one.
|
||||
|
||||
double -- If True, generate a double-buffered viewer.
|
||||
Defaults to False.
|
||||
|
||||
focus_on_enter -- If True, use a focus-follows-mouse mode.
|
||||
Defaults to False where the widget will use a click-to-focus
|
||||
mode.
|
||||
"""
|
||||
# load the necessary extensions into tk
|
||||
vtkLoadPythonTkWidgets(master.tk)
|
||||
|
||||
try: # use specified vtkImageViewer
|
||||
imageViewer = kw['iv']
|
||||
except KeyError: # or create one if none specified
|
||||
imageViewer = vtkImageViewer()
|
||||
|
||||
doubleBuffer = 0
|
||||
try:
|
||||
if kw['double']:
|
||||
doubleBuffer = 1
|
||||
del kw['double']
|
||||
except:
|
||||
pass
|
||||
|
||||
# check if focus should follow mouse
|
||||
if kw.get('focus_on_enter'):
|
||||
self._FocusOnEnter = 1
|
||||
del kw['focus_on_enter']
|
||||
else:
|
||||
self._FocusOnEnter = 0
|
||||
|
||||
kw['iv'] = imageViewer.GetAddressAsString("vtkImageViewer")
|
||||
tkinter.Widget.__init__(self, master, 'vtkTkImageViewerWidget',
|
||||
cnf, kw)
|
||||
if doubleBuffer:
|
||||
imageViewer.GetRenderWindow().DoubleBufferOn()
|
||||
|
||||
self.BindTkImageViewer()
|
||||
|
||||
def __getattr__(self,attr):
|
||||
# because the tk part of vtkTkImageViewerWidget must have
|
||||
# the only remaining reference to the ImageViewer when
|
||||
# it is destroyed, we can't actually store the ImageViewer
|
||||
# as an attribute but instead have to get it from the tk-side
|
||||
if attr == '_ImageViewer':
|
||||
addr = self.tk.call(self._w, 'GetImageViewer')[5:]
|
||||
return vtkImageViewer('_%s_vtkImageViewer_p' % addr)
|
||||
raise AttributeError(self.__class__.__name__ +
|
||||
" has no attribute named " + attr)
|
||||
|
||||
def GetImageViewer(self):
|
||||
return self._ImageViewer
|
||||
|
||||
def Render(self):
|
||||
self._ImageViewer.Render()
|
||||
|
||||
def BindTkImageViewer(self):
|
||||
imager = self._ImageViewer.GetRenderer()
|
||||
|
||||
# stuff for window level text.
|
||||
mapper = vtkTextMapper()
|
||||
mapper.SetInput("none")
|
||||
t_prop = mapper.GetTextProperty()
|
||||
t_prop.SetFontFamilyToTimes()
|
||||
t_prop.SetFontSize(18)
|
||||
t_prop.BoldOn()
|
||||
t_prop.ShadowOn()
|
||||
|
||||
self._LevelMapper = mapper
|
||||
|
||||
actor = vtkActor2D()
|
||||
actor.SetMapper(mapper)
|
||||
actor.SetLayerNumber(1)
|
||||
actor.GetPositionCoordinate().SetValue(4,22)
|
||||
actor.GetProperty().SetColor(1,1,0.5)
|
||||
actor.SetVisibility(0)
|
||||
imager.AddViewProp(actor)
|
||||
|
||||
self._LevelActor = actor
|
||||
|
||||
mapper = vtkTextMapper()
|
||||
mapper.SetInput("none")
|
||||
t_prop = mapper.GetTextProperty()
|
||||
t_prop.SetFontFamilyToTimes()
|
||||
t_prop.SetFontSize(18)
|
||||
t_prop.BoldOn()
|
||||
t_prop.ShadowOn()
|
||||
|
||||
self._WindowMapper = mapper
|
||||
|
||||
actor = vtkActor2D()
|
||||
actor.SetMapper(mapper)
|
||||
actor.SetLayerNumber(1)
|
||||
actor.GetPositionCoordinate().SetValue(4,4)
|
||||
actor.GetProperty().SetColor(1,1,0.5)
|
||||
actor.SetVisibility(0)
|
||||
imager.AddViewProp(actor)
|
||||
|
||||
self._WindowActor = actor
|
||||
|
||||
self._LastX = 0
|
||||
self._LastY = 0
|
||||
self._OldFocus = 0
|
||||
self._InExpose = 0
|
||||
|
||||
# bindings
|
||||
# window level
|
||||
self.bind("<ButtonPress-1>",
|
||||
lambda e,s=self: s.StartWindowLevelInteraction(e.x,e.y))
|
||||
self.bind("<B1-Motion>",
|
||||
lambda e,s=self: s.UpdateWindowLevelInteraction(e.x,e.y))
|
||||
self.bind("<ButtonRelease-1>",
|
||||
lambda e,s=self: s.EndWindowLevelInteraction())
|
||||
|
||||
# Get the value
|
||||
self.bind("<ButtonPress-3>",
|
||||
lambda e,s=self: s.StartQueryInteraction(e.x,e.y))
|
||||
self.bind("<B3-Motion>",
|
||||
lambda e,s=self: s.UpdateQueryInteraction(e.x,e.y))
|
||||
self.bind("<ButtonRelease-3>",
|
||||
lambda e,s=self: s.EndQueryInteraction())
|
||||
|
||||
self.bind("<Expose>",
|
||||
lambda e,s=self: s.ExposeTkImageViewer())
|
||||
self.bind("<Enter>",
|
||||
lambda e,s=self: s.EnterTkViewer())
|
||||
self.bind("<Leave>",
|
||||
lambda e,s=self: s.LeaveTkViewer())
|
||||
self.bind("<KeyPress-e>",
|
||||
lambda e,s=self: s.quit())
|
||||
self.bind("<KeyPress-r>",
|
||||
lambda e,s=self: s.ResetTkImageViewer())
|
||||
|
||||
def _GrabFocus(self):
|
||||
self._OldFocus=self.focus_get()
|
||||
self.focus()
|
||||
|
||||
def EnterTkViewer(self):
|
||||
if self._FocusOnEnter:
|
||||
self._GrabFocus()
|
||||
|
||||
def LeaveTkViewer(self):
|
||||
if self._FocusOnEnter and (self._OldFocus != None):
|
||||
self._OldFocus.focus()
|
||||
|
||||
def ExposeTkImageViewer(self):
|
||||
if (self._InExpose == 0):
|
||||
self._InExpose = 1
|
||||
if (not self._ImageViewer.GetRenderWindow().
|
||||
IsA('vtkCocoaRenderWindow')):
|
||||
self.update()
|
||||
self._ImageViewer.Render()
|
||||
self._InExpose = 0
|
||||
|
||||
def StartWindowLevelInteraction(self,x,y):
|
||||
if not self._FocusOnEnter:
|
||||
self._GrabFocus()
|
||||
viewer = self._ImageViewer
|
||||
self._LastX = x
|
||||
self._LastY = y
|
||||
self._Window = float(viewer.GetColorWindow())
|
||||
self._Level = float(viewer.GetColorLevel())
|
||||
|
||||
# make the window level text visible
|
||||
self._LevelActor.SetVisibility(1)
|
||||
self._WindowActor.SetVisibility(1)
|
||||
|
||||
self.UpdateWindowLevelInteraction(x,y)
|
||||
|
||||
def EndWindowLevelInteraction(self):
|
||||
# make the window level text invisible
|
||||
self._LevelActor.SetVisibility(0)
|
||||
self._WindowActor.SetVisibility(0)
|
||||
self.Render()
|
||||
|
||||
def UpdateWindowLevelInteraction(self,x,y):
|
||||
# compute normalized delta
|
||||
dx = 4.0*(x - self._LastX)/self.winfo_width()*self._Window
|
||||
dy = 4.0*(self._LastY - y)/self.winfo_height()*self._Level
|
||||
|
||||
# abs so that direction does not flip
|
||||
if (self._Window < 0.0):
|
||||
dx = -dx
|
||||
if (self._Level < 0.0):
|
||||
dy = -dy
|
||||
|
||||
# compute new window level
|
||||
window = self._Window + dx
|
||||
if (window < 0.0):
|
||||
level = self._Level + dy
|
||||
else:
|
||||
level = self._Level - dy
|
||||
|
||||
viewer = self._ImageViewer
|
||||
viewer.SetColorWindow(window)
|
||||
viewer.SetColorLevel(level)
|
||||
|
||||
self._WindowMapper.SetInput("Window: %g" % window)
|
||||
self._LevelMapper.SetInput("Level: %g" % level)
|
||||
|
||||
self.Render()
|
||||
|
||||
|
||||
def ResetTkImageViewer(self):
|
||||
# Reset: Set window level to show all values
|
||||
viewer = self._ImageViewer
|
||||
input = viewer.GetInput()
|
||||
if (input == None):
|
||||
return
|
||||
|
||||
# Get the extent in viewer
|
||||
z = viewer.GetZSlice()
|
||||
|
||||
input.UpdateInformation()
|
||||
info = input.GetOutputInformation(0)
|
||||
ext = info.Get(vtkStreamingDemandDrivenPipeline.WHOLE_EXTENT())
|
||||
ext[4] = z
|
||||
ext[5] = z
|
||||
input.Update(0, 1, 0, ext)
|
||||
|
||||
(low,high) = input.GetScalarRange()
|
||||
|
||||
viewer.SetColorWindow(high - low)
|
||||
viewer.SetColorLevel((high + low) * 0.5)
|
||||
|
||||
self.Render()
|
||||
|
||||
def StartQueryInteraction(self,x,y):
|
||||
if not self._FocusOnEnter:
|
||||
self._GrabFocus()
|
||||
# Query PixleValue stuff
|
||||
self._WindowActor.SetVisibility(1)
|
||||
self.UpdateQueryInteraction(x,y)
|
||||
|
||||
def EndQueryInteraction(self):
|
||||
self._WindowActor.SetVisibility(0)
|
||||
self.Render()
|
||||
|
||||
def UpdateQueryInteraction(self,x,y):
|
||||
viewer = self._ImageViewer
|
||||
input = viewer.GetInput()
|
||||
z = viewer.GetZSlice()
|
||||
|
||||
# y is flipped upside down
|
||||
y = self.winfo_height() - y
|
||||
|
||||
# make sure point is in the extent of the image.
|
||||
(xMin,xMax,yMin,yMax,zMin,zMax) = input.GetExtent()
|
||||
if (x < xMin or x > xMax or y < yMin or \
|
||||
y > yMax or z < zMin or z > zMax):
|
||||
return
|
||||
|
||||
numComps = input.GetNumberOfScalarComponents()
|
||||
text = ""
|
||||
for i in xrange(numComps):
|
||||
val = input.GetScalarComponentAsDouble(x,y,z,i)
|
||||
text = "%s %.1f" % (text,val)
|
||||
|
||||
self._WindowMapper.SetInput("(%d, %d): %s" % (x,y,text))
|
||||
|
||||
self.Render()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# an example of how to use this widget
|
||||
if __name__ == "__main__":
|
||||
from vtkmodules.vtkImagingSources import vtkImageCanvasSource2D
|
||||
# load implementations for rendering and interaction factory classes
|
||||
import vtkmodules.vtkRenderingOpenGL2
|
||||
import vtkmodules.vtkInteractionStyle
|
||||
|
||||
canvas = vtkImageCanvasSource2D()
|
||||
canvas.SetNumberOfScalarComponents(3)
|
||||
canvas.SetScalarType(3)
|
||||
canvas.SetExtent(0,511,0,511,0,0)
|
||||
canvas.SetDrawColor(100,100,0)
|
||||
canvas.FillBox(0,511,0,511)
|
||||
canvas.SetDrawColor(200,0,200)
|
||||
canvas.FillBox(32,511,100,500)
|
||||
canvas.SetDrawColor(100,0,0)
|
||||
canvas.FillTube(550,20,30,400,5)
|
||||
canvas.SetDrawColor(255,255,255)
|
||||
canvas.DrawSegment3D(10,20,0,90,510,0)
|
||||
canvas.SetDrawColor(200,50,50)
|
||||
canvas.DrawSegment3D(510,90,0,10,20,0)
|
||||
|
||||
# Check segment clipping
|
||||
canvas.SetDrawColor(0,200,0)
|
||||
canvas.DrawSegment(-10,30,30,-10)
|
||||
canvas.DrawSegment(-10,481,30,521)
|
||||
canvas.DrawSegment(481,-10,521,30)
|
||||
canvas.DrawSegment(481,521,521,481)
|
||||
|
||||
# Check Filling a triangle
|
||||
canvas.SetDrawColor(20,200,200)
|
||||
canvas.FillTriangle(-100,100,190,150,40,300)
|
||||
|
||||
# Check drawing a circle
|
||||
canvas.SetDrawColor(250,250,10)
|
||||
canvas.DrawCircle(350,350,200.0)
|
||||
|
||||
# Check drawing a point
|
||||
canvas.SetDrawColor(250,250,250)
|
||||
canvas.DrawPoint(350,350)
|
||||
canvas.DrawPoint(350,550)
|
||||
|
||||
# Test filling functionality
|
||||
canvas.SetDrawColor(55,0,0)
|
||||
canvas.DrawCircle(450,350,80.0)
|
||||
canvas.SetDrawColor(100,255,100)
|
||||
canvas.FillPixel(450,350)
|
||||
|
||||
# Create the GUI: two renderer widgets and a quit button
|
||||
|
||||
frame = tkinter.Frame()
|
||||
|
||||
widget = vtkTkImageViewerWidget(frame,width=512,height=512,double=1)
|
||||
viewer = widget.GetImageViewer()
|
||||
viewer.SetInputConnection(canvas.GetOutputPort())
|
||||
viewer.SetColorWindow(256)
|
||||
viewer.SetColorLevel(127.5)
|
||||
|
||||
button = tkinter.Button(frame,text="Quit",command=frame.quit)
|
||||
|
||||
widget.pack(side='top',padx=3,pady=3,fill='both',expand='t')
|
||||
frame.pack(fill='both',expand='t')
|
||||
button.pack(fill='x')
|
||||
|
||||
frame.mainloop()
|
||||
@@ -0,0 +1,28 @@
|
||||
"""
|
||||
A subclass of tkinter.PhotoImage that connects a
|
||||
vtkImageData to a photo widget.
|
||||
|
||||
Created by Daniel Blezek, August 2002
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
import sys
|
||||
|
||||
import tkinter
|
||||
|
||||
from .vtkLoadPythonTkWidgets import vtkLoadPythonTkWidgets
|
||||
|
||||
class vtkTkPhotoImage ( tkinter.PhotoImage ):
|
||||
"""
|
||||
A subclass of PhotoImage with helper functions
|
||||
for displaying vtkImageData
|
||||
"""
|
||||
def __init__ ( self, **kw ):
|
||||
# Caller the superclass
|
||||
tkinter.PhotoImage.__init__ ( self, kw )
|
||||
vtkLoadPythonTkWidgets ( self.tk )
|
||||
|
||||
def PutImageSlice ( self, image, z, orientation='transverse', window=256, level=128 ):
|
||||
t = str ( image.__this__ )
|
||||
s = 'vtkImageDataToTkPhoto %s %s %d %s %d %d' % ( t, self.name, z, orientation, window, level )
|
||||
self.tk.eval ( s )
|
||||
@@ -0,0 +1,474 @@
|
||||
"""
|
||||
A simple vtkTkRenderWidget for tkinter.
|
||||
|
||||
Created by David Gobbi, April 1999
|
||||
|
||||
May ??, 1999 - Modifications performed by Heather Drury,
|
||||
to rewrite _pan to match method in TkInteractor.tcl
|
||||
May 11, 1999 - Major rewrite by David Gobbi to make the
|
||||
interactor bindings identical to the TkInteractor.tcl
|
||||
bindings.
|
||||
July 14, 1999 - Added modification by Ken Martin for VTK 2.4, to
|
||||
use vtk widgets instead of Togl.
|
||||
Aug 29, 1999 - Renamed file to vtkRenderWidget.py
|
||||
Nov 14, 1999 - Added support for keyword 'rw'
|
||||
Mar 23, 2000 - Extensive but backwards compatible changes,
|
||||
improved documentation
|
||||
|
||||
A few important notes:
|
||||
|
||||
This class is meant to be used as a base-class widget for
|
||||
doing VTK rendering in Python.
|
||||
|
||||
In VTK (and C++) there is a very important distinction between
|
||||
public ivars (attributes in pythonspeak), protected ivars, and
|
||||
private ivars. When you write a python class that you want
|
||||
to 'look and feel' like a VTK class, you should follow these rules.
|
||||
|
||||
1) Attributes should never be public. Attributes should always be
|
||||
either protected (prefixed with a single underscore) or private
|
||||
(prefixed with a double underscore). You can provide access to
|
||||
attributes through public Set/Get methods (same as VTK).
|
||||
|
||||
2) Use a single underscore to denote a protected attribute, e.g.
|
||||
self._RenderWindow is protected (can be accessed from this
|
||||
class or a derived class).
|
||||
|
||||
3) Use a double underscore to denote a private attribute, e.g.
|
||||
self.__InExpose cannot be accessed outside of this class.
|
||||
|
||||
All attributes should be 'declared' in the __init__() function
|
||||
i.e. set to some initial value. Don't forget that 'None' means
|
||||
'NULL' - the python/vtk wrappers guarantee their equivalence.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
import math, os, sys
|
||||
from vtkmodules.vtkRenderingCore import vtkCellPicker, vtkProperty, vtkRenderWindow
|
||||
|
||||
import tkinter
|
||||
|
||||
from .vtkLoadPythonTkWidgets import vtkLoadPythonTkWidgets
|
||||
|
||||
class vtkTkRenderWidget(tkinter.Widget):
|
||||
"""
|
||||
A vtkTkRenderWidget for Python.
|
||||
|
||||
Use GetRenderWindow() to get the vtkRenderWindow.
|
||||
|
||||
Create with the keyword stereo=1 in order to generate a
|
||||
stereo-capable window.
|
||||
|
||||
Create with the keyword focus_on_enter=1 to enable
|
||||
focus-follows-mouse. The default is for a click-to-focus mode.
|
||||
"""
|
||||
def __init__(self, master, cnf={}, **kw):
|
||||
"""
|
||||
Constructor.
|
||||
|
||||
Keyword arguments:
|
||||
|
||||
rw -- Use passed render window instead of creating a new one.
|
||||
|
||||
stereo -- If True, generate a stereo-capable window.
|
||||
Defaults to False.
|
||||
|
||||
focus_on_enter -- If True, use a focus-follows-mouse mode.
|
||||
Defaults to False where the widget will use a click-to-focus
|
||||
mode.
|
||||
"""
|
||||
# load the necessary extensions into tk
|
||||
vtkLoadPythonTkWidgets(master.tk)
|
||||
|
||||
try: # check to see if a render window was specified
|
||||
renderWindow = kw['rw']
|
||||
except KeyError:
|
||||
renderWindow = vtkRenderWindow()
|
||||
|
||||
try: # was a stereo rendering context requested?
|
||||
if kw['stereo']:
|
||||
renderWindow.StereoCapableWindowOn()
|
||||
del kw['stereo']
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
# check if focus should follow mouse
|
||||
if kw.get('focus_on_enter'):
|
||||
self._FocusOnEnter = 1
|
||||
del kw['focus_on_enter']
|
||||
else:
|
||||
self._FocusOnEnter = 0
|
||||
|
||||
kw['rw'] = renderWindow.GetAddressAsString("vtkRenderWindow")
|
||||
tkinter.Widget.__init__(self, master, 'vtkTkRenderWidget', cnf, kw)
|
||||
|
||||
self._CurrentRenderer = None
|
||||
self._CurrentCamera = None
|
||||
self._CurrentZoom = 1.0
|
||||
self._CurrentLight = None
|
||||
|
||||
self._ViewportCenterX = 0
|
||||
self._ViewportCenterY = 0
|
||||
|
||||
self._Picker = vtkCellPicker()
|
||||
self._PickedAssembly = None
|
||||
self._PickedProperty = vtkProperty()
|
||||
self._PickedProperty.SetColor(1,0,0)
|
||||
self._PrePickedProperty = None
|
||||
|
||||
self._OldFocus = None
|
||||
|
||||
# used by the LOD actors
|
||||
self._DesiredUpdateRate = 15
|
||||
self._StillUpdateRate = 0.0001
|
||||
|
||||
# these record the previous mouse position
|
||||
self._LastX = 0
|
||||
self._LastY = 0
|
||||
|
||||
# private attributes
|
||||
self.__InExpose = 0
|
||||
|
||||
# create the Tk bindings
|
||||
self.BindTkRenderWidget()
|
||||
|
||||
def __getattr__(self,attr):
|
||||
# because the tk part of vtkTkRenderWidget must have
|
||||
# the only remaining reference to the RenderWindow when
|
||||
# it is destroyed, we can't actually store the RenderWindow
|
||||
# as an attribute but instead have to get it from the tk-side
|
||||
if attr == '_RenderWindow':
|
||||
return self.GetRenderWindow()
|
||||
raise AttributeError(self.__class__.__name__ +
|
||||
" has no attribute named " + attr)
|
||||
|
||||
def BindTkRenderWidget(self):
|
||||
"""
|
||||
Bind some default actions.
|
||||
"""
|
||||
self.bind("<ButtonPress>",
|
||||
lambda e,s=self: s.StartMotion(e.x,e.y))
|
||||
self.bind("<ButtonRelease>",
|
||||
lambda e,s=self: s.EndMotion(e.x,e.y))
|
||||
self.bind("<B1-Motion>",
|
||||
lambda e,s=self: s.Rotate(e.x,e.y))
|
||||
self.bind("<B2-Motion>",
|
||||
lambda e,s=self: s.Pan(e.x,e.y))
|
||||
self.bind("<B3-Motion>",
|
||||
lambda e,s=self: s.Zoom(e.x,e.y))
|
||||
self.bind("<Shift-B1-Motion>",
|
||||
lambda e,s=self: s.Pan(e.x,e.y))
|
||||
self.bind("<KeyPress-r>",
|
||||
lambda e,s=self: s.Reset(e.x,e.y))
|
||||
self.bind("<KeyPress-u>",
|
||||
lambda e,s=self: s.deiconify())
|
||||
self.bind("<KeyPress-w>",
|
||||
lambda e,s=self: s.Wireframe())
|
||||
self.bind("<KeyPress-s>",
|
||||
lambda e,s=self: s.Surface())
|
||||
self.bind("<KeyPress-p>",
|
||||
lambda e,s=self: s.PickActor(e.x,e.y))
|
||||
if self._FocusOnEnter:
|
||||
self.bind("<Enter>",
|
||||
lambda e,s=self: s.Enter(e.x,e.y))
|
||||
self.bind("<Leave>",
|
||||
lambda e,s=self: s.Leave(e.x,e.y))
|
||||
else:
|
||||
self.bind("<ButtonPress>",
|
||||
lambda e,s=self: s.Enter(e.x,e.y))
|
||||
self.bind("<Expose>",
|
||||
lambda e,s=self: s.Expose())
|
||||
|
||||
def GetZoomFactor(self):
|
||||
return self._CurrentZoom
|
||||
|
||||
def SetDesiredUpdateRate(self, rate):
|
||||
"""Mirrors the method with the same name in
|
||||
vtkRenderWindowInteractor."""
|
||||
self._DesiredUpdateRate = rate
|
||||
|
||||
def GetDesiredUpdateRate(self):
|
||||
"""Mirrors the method with the same name in
|
||||
vtkRenderWindowInteractor."""
|
||||
return self._DesiredUpdateRate
|
||||
|
||||
def SetStillUpdateRate(self, rate):
|
||||
"""Mirrors the method with the same name in
|
||||
vtkRenderWindowInteractor."""
|
||||
self._StillUpdateRate = rate
|
||||
|
||||
def GetStillUpdateRate(self):
|
||||
"""Mirrors the method with the same name in
|
||||
vtkRenderWindowInteractor."""
|
||||
return self._StillUpdateRate
|
||||
|
||||
def GetRenderWindow(self):
|
||||
addr = self.tk.call(self._w, 'GetRenderWindow')[5:]
|
||||
return vtkRenderWindow('_%s_vtkRenderWindow_p' % addr)
|
||||
|
||||
def GetPicker(self):
|
||||
return self._Picker
|
||||
|
||||
def Expose(self):
|
||||
if (not self.__InExpose):
|
||||
self.__InExpose = 1
|
||||
if (not self._RenderWindow.IsA('vtkCocoaRenderWindow')):
|
||||
self.update()
|
||||
self._RenderWindow.Render()
|
||||
self.__InExpose = 0
|
||||
|
||||
def Render(self):
|
||||
if (self._CurrentLight):
|
||||
light = self._CurrentLight
|
||||
light.SetPosition(self._CurrentCamera.GetPosition())
|
||||
light.SetFocalPoint(self._CurrentCamera.GetFocalPoint())
|
||||
|
||||
self._RenderWindow.Render()
|
||||
|
||||
def UpdateRenderer(self,x,y):
|
||||
"""
|
||||
UpdateRenderer will identify the renderer under the mouse and set
|
||||
up _CurrentRenderer, _CurrentCamera, and _CurrentLight.
|
||||
"""
|
||||
windowX = self.winfo_width()
|
||||
windowY = self.winfo_height()
|
||||
|
||||
renderers = self._RenderWindow.GetRenderers()
|
||||
numRenderers = renderers.GetNumberOfItems()
|
||||
|
||||
self._CurrentRenderer = None
|
||||
renderers.InitTraversal()
|
||||
for i in range(0,numRenderers):
|
||||
renderer = renderers.GetNextItem()
|
||||
vx,vy = (0,0)
|
||||
if (windowX > 1):
|
||||
vx = float(x)/(windowX-1)
|
||||
if (windowY > 1):
|
||||
vy = (windowY-float(y)-1)/(windowY-1)
|
||||
(vpxmin,vpymin,vpxmax,vpymax) = renderer.GetViewport()
|
||||
|
||||
if (vx >= vpxmin and vx <= vpxmax and
|
||||
vy >= vpymin and vy <= vpymax):
|
||||
self._CurrentRenderer = renderer
|
||||
self._ViewportCenterX = float(windowX)*(vpxmax-vpxmin)/2.0\
|
||||
+vpxmin
|
||||
self._ViewportCenterY = float(windowY)*(vpymax-vpymin)/2.0\
|
||||
+vpymin
|
||||
self._CurrentCamera = self._CurrentRenderer.GetActiveCamera()
|
||||
lights = self._CurrentRenderer.GetLights()
|
||||
lights.InitTraversal()
|
||||
self._CurrentLight = lights.GetNextItem()
|
||||
break
|
||||
|
||||
self._LastX = x
|
||||
self._LastY = y
|
||||
|
||||
def GetCurrentRenderer(self):
|
||||
return self._CurrentRenderer
|
||||
|
||||
def Enter(self,x,y):
|
||||
self._OldFocus=self.focus_get()
|
||||
self.focus()
|
||||
self.StartMotion(x, y)
|
||||
|
||||
def Leave(self,x,y):
|
||||
if (self._OldFocus != None):
|
||||
self._OldFocus.focus()
|
||||
|
||||
def StartMotion(self,x,y):
|
||||
self.GetRenderWindow().SetDesiredUpdateRate(self._DesiredUpdateRate)
|
||||
self.UpdateRenderer(x,y)
|
||||
|
||||
def EndMotion(self,x,y):
|
||||
self.GetRenderWindow().SetDesiredUpdateRate(self._StillUpdateRate)
|
||||
if self._CurrentRenderer:
|
||||
self.Render()
|
||||
|
||||
def Rotate(self,x,y):
|
||||
if self._CurrentRenderer:
|
||||
|
||||
self._CurrentCamera.Azimuth(self._LastX - x)
|
||||
self._CurrentCamera.Elevation(y - self._LastY)
|
||||
self._CurrentCamera.OrthogonalizeViewUp()
|
||||
|
||||
self._LastX = x
|
||||
self._LastY = y
|
||||
|
||||
self._CurrentRenderer.ResetCameraClippingRange()
|
||||
self.Render()
|
||||
|
||||
def Pan(self,x,y):
|
||||
if self._CurrentRenderer:
|
||||
|
||||
renderer = self._CurrentRenderer
|
||||
camera = self._CurrentCamera
|
||||
(pPoint0,pPoint1,pPoint2) = camera.GetPosition()
|
||||
(fPoint0,fPoint1,fPoint2) = camera.GetFocalPoint()
|
||||
|
||||
if (camera.GetParallelProjection()):
|
||||
renderer.SetWorldPoint(fPoint0,fPoint1,fPoint2,1.0)
|
||||
renderer.WorldToDisplay()
|
||||
fx,fy,fz = renderer.GetDisplayPoint()
|
||||
renderer.SetDisplayPoint(fx-x+self._LastX,
|
||||
fy+y-self._LastY,
|
||||
fz)
|
||||
renderer.DisplayToWorld()
|
||||
fx,fy,fz,fw = renderer.GetWorldPoint()
|
||||
camera.SetFocalPoint(fx,fy,fz)
|
||||
|
||||
renderer.SetWorldPoint(pPoint0,pPoint1,pPoint2,1.0)
|
||||
renderer.WorldToDisplay()
|
||||
fx,fy,fz = renderer.GetDisplayPoint()
|
||||
renderer.SetDisplayPoint(fx-x+self._LastX,
|
||||
fy+y-self._LastY,
|
||||
fz)
|
||||
renderer.DisplayToWorld()
|
||||
fx,fy,fz,fw = renderer.GetWorldPoint()
|
||||
camera.SetPosition(fx,fy,fz)
|
||||
|
||||
else:
|
||||
(fPoint0,fPoint1,fPoint2) = camera.GetFocalPoint()
|
||||
# Specify a point location in world coordinates
|
||||
renderer.SetWorldPoint(fPoint0,fPoint1,fPoint2,1.0)
|
||||
renderer.WorldToDisplay()
|
||||
# Convert world point coordinates to display coordinates
|
||||
dPoint = renderer.GetDisplayPoint()
|
||||
focalDepth = dPoint[2]
|
||||
|
||||
aPoint0 = self._ViewportCenterX + (x - self._LastX)
|
||||
aPoint1 = self._ViewportCenterY - (y - self._LastY)
|
||||
|
||||
renderer.SetDisplayPoint(aPoint0,aPoint1,focalDepth)
|
||||
renderer.DisplayToWorld()
|
||||
|
||||
(rPoint0,rPoint1,rPoint2,rPoint3) = renderer.GetWorldPoint()
|
||||
if (rPoint3 != 0.0):
|
||||
rPoint0 = rPoint0/rPoint3
|
||||
rPoint1 = rPoint1/rPoint3
|
||||
rPoint2 = rPoint2/rPoint3
|
||||
|
||||
camera.SetFocalPoint((fPoint0 - rPoint0) + fPoint0,
|
||||
(fPoint1 - rPoint1) + fPoint1,
|
||||
(fPoint2 - rPoint2) + fPoint2)
|
||||
|
||||
camera.SetPosition((fPoint0 - rPoint0) + pPoint0,
|
||||
(fPoint1 - rPoint1) + pPoint1,
|
||||
(fPoint2 - rPoint2) + pPoint2)
|
||||
|
||||
self._LastX = x
|
||||
self._LastY = y
|
||||
|
||||
self.Render()
|
||||
|
||||
def Zoom(self,x,y):
|
||||
if self._CurrentRenderer:
|
||||
|
||||
renderer = self._CurrentRenderer
|
||||
camera = self._CurrentCamera
|
||||
|
||||
zoomFactor = math.pow(1.02,(0.5*(self._LastY - y)))
|
||||
self._CurrentZoom = self._CurrentZoom * zoomFactor
|
||||
|
||||
if camera.GetParallelProjection():
|
||||
parallelScale = camera.GetParallelScale()/zoomFactor
|
||||
camera.SetParallelScale(parallelScale)
|
||||
else:
|
||||
camera.Dolly(zoomFactor)
|
||||
renderer.ResetCameraClippingRange()
|
||||
|
||||
self._LastX = x
|
||||
self._LastY = y
|
||||
|
||||
self.Render()
|
||||
|
||||
def Reset(self,x,y):
|
||||
if self._CurrentRenderer:
|
||||
self._CurrentRenderer.ResetCamera()
|
||||
|
||||
self.Render()
|
||||
|
||||
def Wireframe(self):
|
||||
actors = self._CurrentRenderer.GetActors()
|
||||
numActors = actors.GetNumberOfItems()
|
||||
actors.InitTraversal()
|
||||
for i in range(0,numActors):
|
||||
actor = actors.GetNextItem()
|
||||
actor.GetProperty().SetRepresentationToWireframe()
|
||||
|
||||
self.Render()
|
||||
|
||||
def Surface(self):
|
||||
actors = self._CurrentRenderer.GetActors()
|
||||
numActors = actors.GetNumberOfItems()
|
||||
actors.InitTraversal()
|
||||
for i in range(0,numActors):
|
||||
actor = actors.GetNextItem()
|
||||
actor.GetProperty().SetRepresentationToSurface()
|
||||
|
||||
self.Render()
|
||||
|
||||
def PickActor(self,x,y):
|
||||
if self._CurrentRenderer:
|
||||
|
||||
renderer = self._CurrentRenderer
|
||||
picker = self._Picker
|
||||
|
||||
windowY = self.winfo_height()
|
||||
picker.Pick(x,(windowY - y - 1),0.0,renderer)
|
||||
assembly = picker.GetAssembly()
|
||||
|
||||
if (self._PickedAssembly != None and
|
||||
self._PrePickedProperty != None):
|
||||
self._PickedAssembly.SetProperty(self._PrePickedProperty)
|
||||
# release hold of the property
|
||||
self._PrePickedProperty.UnRegister(self._PrePickedProperty)
|
||||
self._PrePickedProperty = None
|
||||
|
||||
if (assembly != None):
|
||||
self._PickedAssembly = assembly
|
||||
self._PrePickedProperty = self._PickedAssembly.GetProperty()
|
||||
# hold onto the property
|
||||
self._PrePickedProperty.Register(self._PrePickedProperty)
|
||||
self._PickedAssembly.SetProperty(self._PickedProperty)
|
||||
|
||||
self.Render()
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
def vtkRenderWidgetConeExample():
|
||||
"""Like it says, just a simple example
|
||||
"""
|
||||
|
||||
from vtkmodules.vtkFiltersSources import vtkConeSource
|
||||
from vtkmodules.vtkRenderingCore import vtkActor, vtkPolyDataMapper, vtkRenderer
|
||||
# load implementations for rendering and interaction factory classes
|
||||
import vtkmodules.vtkRenderingOpenGL2
|
||||
import vtkmodules.vtkInteractionStyle
|
||||
|
||||
# create root window
|
||||
root = tkinter.Tk()
|
||||
|
||||
# create vtkTkRenderWidget
|
||||
pane = vtkTkRenderWidget(root,width=300,height=300)
|
||||
|
||||
ren = vtkRenderer()
|
||||
pane.GetRenderWindow().AddRenderer(ren)
|
||||
|
||||
cone = vtkConeSource()
|
||||
cone.SetResolution(8)
|
||||
|
||||
coneMapper = vtkPolyDataMapper()
|
||||
coneMapper.SetInputConnection(cone.GetOutputPort())
|
||||
|
||||
coneActor = vtkActor()
|
||||
coneActor.SetMapper(coneMapper)
|
||||
|
||||
ren.AddActor(coneActor)
|
||||
|
||||
# pack the pane into the tk root
|
||||
pane.pack()
|
||||
|
||||
# start the tk mainloop
|
||||
root.mainloop()
|
||||
|
||||
if __name__ == "__main__":
|
||||
vtkRenderWidgetConeExample()
|
||||
@@ -0,0 +1,411 @@
|
||||
"""
|
||||
|
||||
A fully functional VTK widget for tkinter that uses
|
||||
vtkGenericRenderWindowInteractor. The widget is called
|
||||
vtkTkRenderWindowInteractor. The initialization part of this code is
|
||||
similar to that of the vtkTkRenderWidget.
|
||||
|
||||
Created by Prabhu Ramachandran, April 2002
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
import math, os, sys
|
||||
from vtkmodules.vtkRenderingCore import vtkRenderWindow
|
||||
from vtkmodules.vtkRenderingUI import vtkGenericRenderWindowInteractor
|
||||
|
||||
import tkinter
|
||||
|
||||
from .vtkLoadPythonTkWidgets import vtkLoadPythonTkWidgets
|
||||
|
||||
class vtkTkRenderWindowInteractor(tkinter.Widget):
|
||||
""" A vtkTkRenderWidndowInteractor for Python.
|
||||
|
||||
Use GetRenderWindow() to get the vtkRenderWindow.
|
||||
|
||||
Create with the keyword stereo=1 in order to generate a
|
||||
stereo-capable window.
|
||||
|
||||
Create with the keyword focus_on_enter=1 to enable
|
||||
focus-follows-mouse. The default is for a click-to-focus mode.
|
||||
|
||||
__getattr__ is used to make the widget also behave like a
|
||||
vtkGenericRenderWindowInteractor.
|
||||
"""
|
||||
def __init__(self, master, cnf={}, **kw):
|
||||
"""
|
||||
Constructor.
|
||||
|
||||
Keyword arguments:
|
||||
|
||||
rw -- Use passed render window instead of creating a new one.
|
||||
|
||||
stereo -- If True, generate a stereo-capable window.
|
||||
Defaults to False.
|
||||
|
||||
focus_on_enter -- If True, use a focus-follows-mouse mode.
|
||||
Defaults to False where the widget will use a click-to-focus
|
||||
mode.
|
||||
"""
|
||||
# load the necessary extensions into tk
|
||||
vtkLoadPythonTkWidgets(master.tk)
|
||||
|
||||
try: # check to see if a render window was specified
|
||||
renderWindow = kw['rw']
|
||||
except KeyError:
|
||||
renderWindow = vtkRenderWindow()
|
||||
|
||||
try: # was a stereo rendering context requested?
|
||||
if kw['stereo']:
|
||||
renderWindow.StereoCapableWindowOn()
|
||||
del kw['stereo']
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
# check if focus should follow mouse
|
||||
if kw.get('focus_on_enter'):
|
||||
self._FocusOnEnter = 1
|
||||
del kw['focus_on_enter']
|
||||
else:
|
||||
self._FocusOnEnter = 0
|
||||
|
||||
kw['rw'] = renderWindow.GetAddressAsString("vtkRenderWindow")
|
||||
tkinter.Widget.__init__(self, master, 'vtkTkRenderWidget', cnf, kw)
|
||||
|
||||
self._Iren = vtkGenericRenderWindowInteractor()
|
||||
self._Iren.SetRenderWindow(self._RenderWindow)
|
||||
|
||||
self._Iren.AddObserver('CreateTimerEvent', self.CreateTimer)
|
||||
self._Iren.AddObserver('DestroyTimerEvent', self.DestroyTimer)
|
||||
|
||||
self._OldFocus = None
|
||||
|
||||
# private attributes
|
||||
self.__InExpose = 0
|
||||
|
||||
# create the Tk bindings
|
||||
self.BindEvents()
|
||||
#self.tk_focusFollowsMouse()
|
||||
|
||||
def __getattr__(self, attr):
|
||||
# because the tk part of vtkTkRenderWidget must have
|
||||
# the only remaining reference to the RenderWindow when
|
||||
# it is destroyed, we can't actually store the RenderWindow
|
||||
# as an attribute but instead have to get it from the tk-side
|
||||
if attr == '__vtk__':
|
||||
return lambda t=self._Iren: t
|
||||
elif attr == '_RenderWindow':
|
||||
return self.GetRenderWindow()
|
||||
elif hasattr(self._Iren, attr):
|
||||
return getattr(self._Iren, attr)
|
||||
else:
|
||||
raise AttributeError(self.__class__.__name__ +
|
||||
" has no attribute named " + attr)
|
||||
|
||||
def BindEvents(self):
|
||||
""" Bind all the events. """
|
||||
self.bind("<Motion>",
|
||||
lambda e, s=self: s.MouseMoveEvent(e, 0, 0))
|
||||
self.bind("<Control-Motion>",
|
||||
lambda e, s=self: s.MouseMoveEvent(e, 1, 0))
|
||||
self.bind("<Shift-Motion>",
|
||||
lambda e, s=self: s.MouseMoveEvent(e, 1, 1))
|
||||
self.bind("<Control-Shift-Motion>",
|
||||
lambda e, s=self: s.MouseMoveEvent(e, 0, 1))
|
||||
|
||||
# Left Button
|
||||
self.bind("<ButtonPress-1>",
|
||||
lambda e, s=self: s.LeftButtonPressEvent(e, 0, 0))
|
||||
self.bind("<Control-ButtonPress-1>",
|
||||
lambda e, s=self: s.LeftButtonPressEvent(e, 1, 0))
|
||||
self.bind("<Shift-ButtonPress-1>",
|
||||
lambda e, s=self: s.LeftButtonPressEvent(e, 0, 1))
|
||||
self.bind("<Control-Shift-ButtonPress-1>",
|
||||
lambda e, s=self: s.LeftButtonPressEvent(e, 1, 1))
|
||||
self.bind("<ButtonRelease-1>",
|
||||
lambda e, s=self: s.LeftButtonReleaseEvent(e, 0, 0))
|
||||
self.bind("<Control-ButtonRelease-1>",
|
||||
lambda e, s=self: s.LeftButtonReleaseEvent(e, 1, 0))
|
||||
self.bind("<Shift-ButtonRelease-1>",
|
||||
lambda e, s=self: s.LeftButtonReleaseEvent(e, 0, 1))
|
||||
self.bind("<Control-Shift-ButtonRelease-1>",
|
||||
lambda e, s=self: s.LeftButtonReleaseEvent(e, 1, 1))
|
||||
|
||||
# Middle Button
|
||||
self.bind("<ButtonPress-2>",
|
||||
lambda e, s=self: s.MiddleButtonPressEvent(e, 0, 0))
|
||||
self.bind("<Control-ButtonPress-2>",
|
||||
lambda e, s=self: s.MiddleButtonPressEvent(e, 1, 0))
|
||||
self.bind("<Shift-ButtonPress-2>",
|
||||
lambda e, s=self: s.MiddleButtonPressEvent(e, 0, 1))
|
||||
self.bind("<Control-Shift-ButtonPress-2>",
|
||||
lambda e, s=self: s.MiddleButtonPressEvent(e, 1, 1))
|
||||
self.bind("<ButtonRelease-2>",
|
||||
lambda e, s=self: s.MiddleButtonReleaseEvent(e, 0, 0))
|
||||
self.bind("<Control-ButtonRelease-2>",
|
||||
lambda e, s=self: s.MiddleButtonReleaseEvent(e, 1, 0))
|
||||
self.bind("<Shift-ButtonRelease-2>",
|
||||
lambda e, s=self: s.MiddleButtonReleaseEvent(e, 0, 1))
|
||||
self.bind("<Control-Shift-ButtonRelease-2>",
|
||||
lambda e, s=self: s.MiddleButtonReleaseEvent(e, 1, 1))
|
||||
|
||||
# Right Button
|
||||
self.bind("<ButtonPress-3>",
|
||||
lambda e, s=self: s.RightButtonPressEvent(e, 0, 0))
|
||||
self.bind("<Control-ButtonPress-3>",
|
||||
lambda e, s=self: s.RightButtonPressEvent(e, 1, 0))
|
||||
self.bind("<Shift-ButtonPress-3>",
|
||||
lambda e, s=self: s.RightButtonPressEvent(e, 0, 1))
|
||||
self.bind("<Control-Shift-ButtonPress-3>",
|
||||
lambda e, s=self: s.RightButtonPressEvent(e, 1, 1))
|
||||
self.bind("<ButtonRelease-3>",
|
||||
lambda e, s=self: s.RightButtonReleaseEvent(e, 0, 0))
|
||||
self.bind("<Control-ButtonRelease-3>",
|
||||
lambda e, s=self: s.RightButtonReleaseEvent(e, 1, 0))
|
||||
self.bind("<Shift-ButtonRelease-3>",
|
||||
lambda e, s=self: s.RightButtonReleaseEvent(e, 0, 1))
|
||||
self.bind("<Control-Shift-ButtonRelease-3>",
|
||||
lambda e, s=self: s.RightButtonReleaseEvent(e, 1, 1))
|
||||
|
||||
if sys.platform == 'win32':
|
||||
self.bind("<MouseWheel>",
|
||||
lambda e, s=self: s.MouseWheelEvent(e, 0, 0))
|
||||
self.bind("<Control-MouseWheel>",
|
||||
lambda e, s=self: s.MouseWheelEvent(e, 1, 0))
|
||||
self.bind("<Shift-MouseWheel>",
|
||||
lambda e, s=self: s.MouseWheelEvent(e, 0, 1))
|
||||
self.bind("<Control-Shift-MouseWheel>",
|
||||
lambda e, s=self: s.MouseWheelEvent(e, 1, 1))
|
||||
else:
|
||||
# Mouse wheel forward event
|
||||
self.bind("<ButtonPress-4>",
|
||||
lambda e, s=self: s.MouseWheelForwardEvent(e, 0, 0))
|
||||
self.bind("<Control-ButtonPress-4>",
|
||||
lambda e, s=self: s.MouseWheelForwardEvent(e, 1, 0))
|
||||
self.bind("<Shift-ButtonPress-4>",
|
||||
lambda e, s=self: s.MouseWheelForwardEvent(e, 0, 1))
|
||||
self.bind("<Control-Shift-ButtonPress-4>",
|
||||
lambda e, s=self: s.MouseWheelForwardEvent(e, 1, 1))
|
||||
|
||||
# Mouse wheel backward event
|
||||
self.bind("<ButtonPress-5>",
|
||||
lambda e, s=self: s.MouseWheelBackwardEvent(e, 0, 0))
|
||||
self.bind("<Control-ButtonPress-5>",
|
||||
lambda e, s=self: s.MouseWheelBackwardEvent(e, 1, 0))
|
||||
self.bind("<Shift-ButtonPress-5>",
|
||||
lambda e, s=self: s.MouseWheelBackwardEvent(e, 0, 1))
|
||||
self.bind("<Control-Shift-ButtonPress-5>",
|
||||
lambda e, s=self: s.MouseWheelBackwardEvent(e, 1, 1))
|
||||
|
||||
# Key related events
|
||||
self.bind("<KeyPress>",
|
||||
lambda e, s=self: s.KeyPressEvent(e, 0, 0))
|
||||
self.bind("<Control-KeyPress>",
|
||||
lambda e, s=self: s.KeyPressEvent(e, 1, 0))
|
||||
self.bind("<Shift-KeyPress>",
|
||||
lambda e, s=self: s.KeyPressEvent(e, 0, 1))
|
||||
self.bind("<Control-Shift-KeyPress>",
|
||||
lambda e, s=self: s.KeyPressEvent(e, 1, 1))
|
||||
|
||||
self.bind("<KeyRelease>",
|
||||
lambda e, s=self: s.KeyReleaseEvent(e, 0, 0))
|
||||
self.bind("<Control-KeyRelease>",
|
||||
lambda e, s=self: s.KeyReleaseEvent(e, 1, 0))
|
||||
self.bind("<Shift-KeyRelease>",
|
||||
lambda e, s=self: s.KeyReleaseEvent(e, 0, 1))
|
||||
self.bind("<Control-Shift-KeyRelease>",
|
||||
lambda e, s=self: s.KeyReleaseEvent(e, 1, 1))
|
||||
|
||||
self.bind("<Enter>",
|
||||
lambda e, s=self: s.EnterEvent(e, 0, 0))
|
||||
self.bind("<Control-Enter>",
|
||||
lambda e, s=self: s.EnterEvent(e, 1, 0))
|
||||
self.bind("<Shift-Enter>",
|
||||
lambda e, s=self: s.EnterEvent(e, 0, 1))
|
||||
self.bind("<Control-Shift-Enter>",
|
||||
lambda e, s=self: s.EnterEvent(e, 1, 1))
|
||||
self.bind("<Leave>",
|
||||
lambda e, s=self: s.LeaveEvent(e, 0, 0))
|
||||
self.bind("<Control-Leave>",
|
||||
lambda e, s=self: s.LeaveEvent(e, 1, 0))
|
||||
self.bind("<Shift-Leave>",
|
||||
lambda e, s=self: s.LeaveEvent(e, 0, 1))
|
||||
self.bind("<Control-Shift-Leave>",
|
||||
lambda e, s=self: s.LeaveEvent(e, 1, 1))
|
||||
|
||||
self.bind("<Configure>", self.ConfigureEvent)
|
||||
self.bind("<Expose>",lambda e,s=self: s.ExposeEvent())
|
||||
|
||||
def CreateTimer(self, obj, evt):
|
||||
self.after(10, self._Iren.TimerEvent)
|
||||
|
||||
def DestroyTimer(self, obj, event):
|
||||
"""The timer is a one shot timer so will expire automatically."""
|
||||
return 1
|
||||
|
||||
def _GrabFocus(self, enter=0):
|
||||
self._OldFocus=self.focus_get()
|
||||
self.focus()
|
||||
|
||||
def MouseMoveEvent(self, event, ctrl, shift):
|
||||
self._Iren.SetEventInformationFlipY(event.x, event.y, ctrl,
|
||||
shift, chr(0), 0, None)
|
||||
self._Iren.MouseMoveEvent()
|
||||
|
||||
def LeftButtonPressEvent(self, event, ctrl, shift):
|
||||
self._Iren.SetEventInformationFlipY(event.x, event.y, ctrl,
|
||||
shift, chr(0), 0, None)
|
||||
self._Iren.LeftButtonPressEvent()
|
||||
if not self._FocusOnEnter:
|
||||
self._GrabFocus()
|
||||
|
||||
def LeftButtonReleaseEvent(self, event, ctrl, shift):
|
||||
self._Iren.SetEventInformationFlipY(event.x, event.y, ctrl,
|
||||
shift, chr(0), 0, None)
|
||||
self._Iren.LeftButtonReleaseEvent()
|
||||
|
||||
def MiddleButtonPressEvent(self, event, ctrl, shift):
|
||||
self._Iren.SetEventInformationFlipY(event.x, event.y, ctrl,
|
||||
shift, chr(0), 0, None)
|
||||
self._Iren.MiddleButtonPressEvent()
|
||||
if not self._FocusOnEnter:
|
||||
self._GrabFocus()
|
||||
|
||||
def MiddleButtonReleaseEvent(self, event, ctrl, shift):
|
||||
self._Iren.SetEventInformationFlipY(event.x, event.y, ctrl,
|
||||
shift, chr(0), 0, None)
|
||||
self._Iren.MiddleButtonReleaseEvent()
|
||||
|
||||
def RightButtonPressEvent(self, event, ctrl, shift):
|
||||
self._Iren.SetEventInformationFlipY(event.x, event.y, ctrl,
|
||||
shift, chr(0), 0, None)
|
||||
self._Iren.RightButtonPressEvent()
|
||||
if not self._FocusOnEnter:
|
||||
self._GrabFocus()
|
||||
|
||||
def RightButtonReleaseEvent(self, event, ctrl, shift):
|
||||
self._Iren.SetEventInformationFlipY(event.x, event.y, ctrl,
|
||||
shift, chr(0), 0, None)
|
||||
self._Iren.RightButtonReleaseEvent()
|
||||
|
||||
def MouseWheelEvent(self, event, ctrl, shift):
|
||||
self._Iren.SetEventInformationFlipY(event.x, event.y, ctrl,
|
||||
shift, chr(0), 0, None)
|
||||
if event.delta > 0:
|
||||
self._Iren.MouseWheelForwardEvent()
|
||||
else:
|
||||
self._Iren.MouseWheelBackwardEvent()
|
||||
|
||||
def MouseWheelForwardEvent(self, event, ctrl, shift):
|
||||
self._Iren.SetEventInformationFlipY(event.x, event.y, ctrl,
|
||||
shift, chr(0), 0, None)
|
||||
self._Iren.MouseWheelForwardEvent()
|
||||
|
||||
def MouseWheelBackwardEvent(self, event, ctrl, shift):
|
||||
self._Iren.SetEventInformationFlipY(event.x, event.y, ctrl,
|
||||
shift, chr(0), 0, None)
|
||||
self._Iren.MouseWheelBackwardEvent()
|
||||
|
||||
def KeyPressEvent(self, event, ctrl, shift):
|
||||
key = chr(0)
|
||||
if event.keysym_num < 128:
|
||||
key = chr(event.keysym_num)
|
||||
self._Iren.SetEventInformationFlipY(event.x, event.y, ctrl,
|
||||
shift, key, 0, event.keysym)
|
||||
self._Iren.KeyPressEvent()
|
||||
self._Iren.CharEvent()
|
||||
|
||||
def KeyReleaseEvent(self, event, ctrl, shift):
|
||||
key = chr(0)
|
||||
if event.keysym_num < 128:
|
||||
key = chr(event.keysym_num)
|
||||
self._Iren.SetEventInformationFlipY(event.x, event.y, ctrl,
|
||||
shift, key, 0, event.keysym)
|
||||
self._Iren.KeyReleaseEvent()
|
||||
|
||||
def ConfigureEvent(self, event):
|
||||
oldwidth, oldheight = self._Iren.GetSize()
|
||||
self._Iren.SetSize(event.width, event.height)
|
||||
self._Iren.ConfigureEvent()
|
||||
# check whether if the window has expanded vs shrunk
|
||||
if event.width <= oldwidth and event.height <= oldheight:
|
||||
# there will be no ExposeEvent if the window didn't grow,
|
||||
# so post a render to occur after any event processing
|
||||
self.after(0, self.Render)
|
||||
|
||||
def EnterEvent(self, event, ctrl, shift):
|
||||
if self._FocusOnEnter:
|
||||
self._GrabFocus()
|
||||
self._Iren.SetEventInformationFlipY(event.x, event.y, ctrl, shift,
|
||||
chr(0), 0, None)
|
||||
self._Iren.EnterEvent()
|
||||
|
||||
def LeaveEvent(self, event, ctrl, shift):
|
||||
if self._FocusOnEnter and (self._OldFocus != None):
|
||||
self._OldFocus.focus()
|
||||
self._Iren.SetEventInformationFlipY(event.x, event.y, ctrl, shift,
|
||||
chr(0), 0, None)
|
||||
self._Iren.LeaveEvent()
|
||||
|
||||
def ExposeEvent(self):
|
||||
if (not self.__InExpose):
|
||||
self.__InExpose = 1
|
||||
if (not self._RenderWindow.IsA('vtkCocoaRenderWindow')):
|
||||
self.update()
|
||||
self._RenderWindow.Render()
|
||||
self.__InExpose = 0
|
||||
|
||||
def GetRenderWindow(self):
|
||||
addr = self.tk.call(self._w, 'GetRenderWindow')[5:]
|
||||
return vtkRenderWindow('_%s_vtkRenderWindow_p' % addr)
|
||||
|
||||
def Render(self):
|
||||
self._RenderWindow.Render()
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
def vtkRenderWindowInteractorConeExample():
|
||||
"""Like it says, just a simple example
|
||||
"""
|
||||
|
||||
from vtkmodules.vtkFiltersSources import vtkConeSource
|
||||
from vtkmodules.vtkRenderingCore import vtkActor, vtkPolyDataMapper, vtkRenderer
|
||||
# load implementations for rendering and interaction factory classes
|
||||
import vtkmodules.vtkRenderingOpenGL2
|
||||
import vtkmodules.vtkInteractionStyle
|
||||
|
||||
# create root window
|
||||
root = tkinter.Tk()
|
||||
|
||||
# create vtkTkRenderWidget
|
||||
pane = vtkTkRenderWindowInteractor(root, width=300, height=300)
|
||||
pane.Initialize()
|
||||
|
||||
def quit(obj=root):
|
||||
obj.quit()
|
||||
|
||||
pane.AddObserver("ExitEvent", lambda o,e,q=quit: q())
|
||||
|
||||
ren = vtkRenderer()
|
||||
pane.GetRenderWindow().AddRenderer(ren)
|
||||
|
||||
cone = vtkConeSource()
|
||||
cone.SetResolution(8)
|
||||
|
||||
coneMapper = vtkPolyDataMapper()
|
||||
coneMapper.SetInputConnection(cone.GetOutputPort())
|
||||
|
||||
coneActor = vtkActor()
|
||||
coneActor.SetMapper(coneMapper)
|
||||
|
||||
ren.AddActor(coneActor)
|
||||
|
||||
# pack the pane into the tk root
|
||||
pane.pack(fill='both', expand=1)
|
||||
pane.Start()
|
||||
|
||||
# start the tk mainloop
|
||||
root.mainloop()
|
||||
|
||||
if __name__ == "__main__":
|
||||
vtkRenderWindowInteractorConeExample()
|
||||
@@ -0,0 +1,5 @@
|
||||
"""Utility modules for the VTK-Python wrappers."""
|
||||
|
||||
__all__ = ['colors', 'misc', 'vtkConstants', 'vtkImageExportToArray',
|
||||
'vtkImageImportFromArray', 'vtkMethodParser', 'vtkVariant',
|
||||
'numpy_support', 'pickle_support']
|
||||
@@ -0,0 +1,216 @@
|
||||
# This module defines many standard colors that should be useful.
|
||||
# These colors should be exactly the same as the ones defined in
|
||||
# vtkNamedColors.h.
|
||||
|
||||
# Whites
|
||||
antique_white = (0.9804, 0.9216, 0.8431)
|
||||
azure = (0.9412, 1.0000, 1.0000)
|
||||
bisque = (1.0000, 0.8941, 0.7686)
|
||||
blanched_almond = (1.0000, 0.9216, 0.8039)
|
||||
cornsilk = (1.0000, 0.9725, 0.8627)
|
||||
eggshell = (0.9900, 0.9000, 0.7900)
|
||||
floral_white = (1.0000, 0.9804, 0.9412)
|
||||
gainsboro = (0.8627, 0.8627, 0.8627)
|
||||
ghost_white = (0.9725, 0.9725, 1.0000)
|
||||
honeydew = (0.9412, 1.0000, 0.9412)
|
||||
ivory = (1.0000, 1.0000, 0.9412)
|
||||
lavender = (0.9020, 0.9020, 0.9804)
|
||||
lavender_blush = (1.0000, 0.9412, 0.9608)
|
||||
lemon_chiffon = (1.0000, 0.9804, 0.8039)
|
||||
linen = (0.9804, 0.9412, 0.9020)
|
||||
mint_cream = (0.9608, 1.0000, 0.9804)
|
||||
misty_rose = (1.0000, 0.8941, 0.8824)
|
||||
moccasin = (1.0000, 0.8941, 0.7098)
|
||||
navajo_white = (1.0000, 0.8706, 0.6784)
|
||||
old_lace = (0.9922, 0.9608, 0.9020)
|
||||
papaya_whip = (1.0000, 0.9373, 0.8353)
|
||||
peach_puff = (1.0000, 0.8549, 0.7255)
|
||||
seashell = (1.0000, 0.9608, 0.9333)
|
||||
snow = (1.0000, 0.9804, 0.9804)
|
||||
thistle = (0.8471, 0.7490, 0.8471)
|
||||
titanium_white = (0.9900, 1.0000, 0.9400)
|
||||
wheat = (0.9608, 0.8706, 0.7020)
|
||||
white = (1.0000, 1.0000, 1.0000)
|
||||
white_smoke = (0.9608, 0.9608, 0.9608)
|
||||
zinc_white = (0.9900, 0.9700, 1.0000)
|
||||
|
||||
# Greys
|
||||
cold_grey = (0.5000, 0.5400, 0.5300)
|
||||
dim_grey = (0.4118, 0.4118, 0.4118)
|
||||
grey = (0.7529, 0.7529, 0.7529)
|
||||
light_grey = (0.8275, 0.8275, 0.8275)
|
||||
slate_grey = (0.4392, 0.5020, 0.5647)
|
||||
slate_grey_dark = (0.1843, 0.3098, 0.3098)
|
||||
slate_grey_light = (0.4667, 0.5333, 0.6000)
|
||||
warm_grey = (0.5000, 0.5000, 0.4100)
|
||||
|
||||
# Blacks
|
||||
black = (0.0000, 0.0000, 0.0000)
|
||||
ivory_black = (0.1600, 0.1400, 0.1300)
|
||||
lamp_black = (0.1800, 0.2800, 0.2300)
|
||||
|
||||
# Reds
|
||||
alizarin_crimson = (0.8900, 0.1500, 0.2100)
|
||||
brick = (0.6100, 0.4000, 0.1200)
|
||||
cadmium_red_deep = (0.8900, 0.0900, 0.0500)
|
||||
coral = (1.0000, 0.4980, 0.3137)
|
||||
coral_light = (0.9412, 0.5020, 0.5020)
|
||||
deep_pink = (1.0000, 0.0784, 0.5765)
|
||||
english_red = (0.8300, 0.2400, 0.1000)
|
||||
firebrick = (0.6980, 0.1333, 0.1333)
|
||||
geranium_lake = (0.8900, 0.0700, 0.1900)
|
||||
hot_pink = (1.0000, 0.4118, 0.7059)
|
||||
indian_red = (0.6900, 0.0900, 0.1200)
|
||||
light_salmon = (1.0000, 0.6275, 0.4784)
|
||||
madder_lake_deep = (0.8900, 0.1800, 0.1900)
|
||||
maroon = (0.6902, 0.1882, 0.3765)
|
||||
pink = (1.0000, 0.7529, 0.7961)
|
||||
pink_light = (1.0000, 0.7137, 0.7569)
|
||||
raspberry = (0.5300, 0.1500, 0.3400)
|
||||
red = (1.0000, 0.0000, 0.0000)
|
||||
rose_madder = (0.8900, 0.2100, 0.2200)
|
||||
salmon = (0.9804, 0.5020, 0.4471)
|
||||
tomato = (1.0000, 0.3882, 0.2784)
|
||||
venetian_red = (0.8300, 0.1000, 0.1200)
|
||||
|
||||
# Browns
|
||||
beige = (0.6400, 0.5800, 0.5000)
|
||||
brown = (0.5000, 0.1647, 0.1647)
|
||||
brown_madder = (0.8600, 0.1600, 0.1600)
|
||||
brown_ochre = (0.5300, 0.2600, 0.1200)
|
||||
burlywood = (0.8706, 0.7216, 0.5294)
|
||||
burnt_sienna = (0.5400, 0.2100, 0.0600)
|
||||
burnt_umber = (0.5400, 0.2000, 0.1400)
|
||||
chocolate = (0.8235, 0.4118, 0.1176)
|
||||
deep_ochre = (0.4500, 0.2400, 0.1000)
|
||||
flesh = (1.0000, 0.4900, 0.2500)
|
||||
flesh_ochre = (1.0000, 0.3400, 0.1300)
|
||||
gold_ochre = (0.7800, 0.4700, 0.1500)
|
||||
greenish_umber = (1.0000, 0.2400, 0.0500)
|
||||
khaki = (0.9412, 0.9020, 0.5490)
|
||||
khaki_dark = (0.7412, 0.7176, 0.4196)
|
||||
light_beige = (0.9608, 0.9608, 0.8627)
|
||||
peru = (0.8039, 0.5216, 0.2471)
|
||||
rosy_brown = (0.7373, 0.5608, 0.5608)
|
||||
raw_sienna = (0.7800, 0.3800, 0.0800)
|
||||
raw_umber = (0.4500, 0.2900, 0.0700)
|
||||
sepia = (0.3700, 0.1500, 0.0700)
|
||||
sienna = (0.6275, 0.3216, 0.1765)
|
||||
saddle_brown = (0.5451, 0.2706, 0.0745)
|
||||
sandy_brown = (0.9569, 0.6431, 0.3765)
|
||||
tan = (0.8235, 0.7059, 0.5490)
|
||||
van_dyke_brown = (0.3700, 0.1500, 0.0200)
|
||||
|
||||
# Oranges
|
||||
cadmium_orange = (1.0000, 0.3800, 0.0100)
|
||||
cadmium_red_light = (1.0000, 0.0100, 0.0500)
|
||||
carrot = (0.9300, 0.5700, 0.1300)
|
||||
dark_orange = (1.0000, 0.5490, 0.0000)
|
||||
mars_orange = (0.5900, 0.2700, 0.0800)
|
||||
mars_yellow = (0.8900, 0.4400, 0.1000)
|
||||
orange = (1.0000, 0.5000, 0.0000)
|
||||
orange_red = (1.0000, 0.2706, 0.0000)
|
||||
yellow_ochre = (0.8900, 0.5100, 0.0900)
|
||||
|
||||
# Yellows
|
||||
aureoline_yellow = (1.0000, 0.6600, 0.1400)
|
||||
banana = (0.8900, 0.8100, 0.3400)
|
||||
cadmium_lemon = (1.0000, 0.8900, 0.0100)
|
||||
cadmium_yellow = (1.0000, 0.6000, 0.0700)
|
||||
cadmium_yellow_light = (1.0000, 0.6900, 0.0600)
|
||||
gold = (1.0000, 0.8431, 0.0000)
|
||||
goldenrod = (0.8549, 0.6471, 0.1255)
|
||||
goldenrod_dark = (0.7216, 0.5255, 0.0431)
|
||||
goldenrod_light = (0.9804, 0.9804, 0.8235)
|
||||
goldenrod_pale = (0.9333, 0.9098, 0.6667)
|
||||
light_goldenrod = (0.9333, 0.8667, 0.5098)
|
||||
melon = (0.8900, 0.6600, 0.4100)
|
||||
naples_yellow_deep = (1.0000, 0.6600, 0.0700)
|
||||
yellow = (1.0000, 1.0000, 0.0000)
|
||||
yellow_light = (1.0000, 1.0000, 0.8784)
|
||||
|
||||
# Greens
|
||||
chartreuse = (0.4980, 1.0000, 0.0000)
|
||||
chrome_oxide_green = (0.4000, 0.5000, 0.0800)
|
||||
cinnabar_green = (0.3800, 0.7000, 0.1600)
|
||||
cobalt_green = (0.2400, 0.5700, 0.2500)
|
||||
emerald_green = (0.0000, 0.7900, 0.3400)
|
||||
forest_green = (0.1333, 0.5451, 0.1333)
|
||||
green = (0.0000, 1.0000, 0.0000)
|
||||
green_dark = (0.0000, 0.3922, 0.0000)
|
||||
green_pale = (0.5961, 0.9843, 0.5961)
|
||||
green_yellow = (0.6784, 1.0000, 0.1843)
|
||||
lawn_green = (0.4863, 0.9882, 0.0000)
|
||||
lime_green = (0.1961, 0.8039, 0.1961)
|
||||
mint = (0.7400, 0.9900, 0.7900)
|
||||
olive = (0.2300, 0.3700, 0.1700)
|
||||
olive_drab = (0.4196, 0.5569, 0.1373)
|
||||
olive_green_dark = (0.3333, 0.4196, 0.1843)
|
||||
permanent_green = (0.0400, 0.7900, 0.1700)
|
||||
sap_green = (0.1900, 0.5000, 0.0800)
|
||||
sea_green = (0.1804, 0.5451, 0.3412)
|
||||
sea_green_dark = (0.5608, 0.7373, 0.5608)
|
||||
sea_green_medium = (0.2353, 0.7020, 0.4431)
|
||||
sea_green_light = (0.1255, 0.6980, 0.6667)
|
||||
spring_green = (0.0000, 1.0000, 0.4980)
|
||||
spring_green_medium = (0.0000, 0.9804, 0.6039)
|
||||
terre_verte = (0.2200, 0.3700, 0.0600)
|
||||
viridian_light = (0.4300, 1.0000, 0.4400)
|
||||
yellow_green = (0.6039, 0.8039, 0.1961)
|
||||
|
||||
# Cyans
|
||||
aquamarine = (0.4980, 1.0000, 0.8314)
|
||||
aquamarine_medium = (0.4000, 0.8039, 0.6667)
|
||||
cyan = (0.0000, 1.0000, 1.0000)
|
||||
cyan_white = (0.8784, 1.0000, 1.0000)
|
||||
turquoise = (0.2510, 0.8784, 0.8157)
|
||||
turquoise_dark = (0.0000, 0.8078, 0.8196)
|
||||
turquoise_medium = (0.2824, 0.8196, 0.8000)
|
||||
turquoise_pale = (0.6863, 0.9333, 0.9333)
|
||||
|
||||
# Blues
|
||||
alice_blue = (0.9412, 0.9725, 1.0000)
|
||||
blue = (0.0000, 0.0000, 1.0000)
|
||||
blue_light = (0.6784, 0.8471, 0.9020)
|
||||
blue_medium = (0.0000, 0.0000, 0.8039)
|
||||
cadet = (0.3725, 0.6196, 0.6275)
|
||||
cobalt = (0.2400, 0.3500, 0.6700)
|
||||
cornflower = (0.3922, 0.5843, 0.9294)
|
||||
cerulean = (0.0200, 0.7200, 0.8000)
|
||||
dodger_blue = (0.1176, 0.5647, 1.0000)
|
||||
indigo = (0.0300, 0.1800, 0.3300)
|
||||
manganese_blue = (0.0100, 0.6600, 0.6200)
|
||||
midnight_blue = (0.0980, 0.0980, 0.4392)
|
||||
navy = (0.0000, 0.0000, 0.5020)
|
||||
peacock = (0.2000, 0.6300, 0.7900)
|
||||
powder_blue = (0.6902, 0.8784, 0.9020)
|
||||
royal_blue = (0.2549, 0.4118, 0.8824)
|
||||
slate_blue = (0.4157, 0.3529, 0.8039)
|
||||
slate_blue_dark = (0.2824, 0.2392, 0.5451)
|
||||
slate_blue_light = (0.5176, 0.4392, 1.0000)
|
||||
slate_blue_medium = (0.4824, 0.4078, 0.9333)
|
||||
sky_blue = (0.5294, 0.8078, 0.9216)
|
||||
sky_blue_deep = (0.0000, 0.7490, 1.0000)
|
||||
sky_blue_light = (0.5294, 0.8078, 0.9804)
|
||||
steel_blue = (0.2745, 0.5098, 0.7059)
|
||||
steel_blue_light = (0.6902, 0.7686, 0.8706)
|
||||
turquoise_blue = (0.0000, 0.7800, 0.5500)
|
||||
ultramarine = (0.0700, 0.0400, 0.5600)
|
||||
|
||||
# Magentas
|
||||
blue_violet = (0.5412, 0.1686, 0.8863)
|
||||
cobalt_violet_deep = (0.5700, 0.1300, 0.6200)
|
||||
magenta = (1.0000, 0.0000, 1.0000)
|
||||
orchid = (0.8549, 0.4392, 0.8392)
|
||||
orchid_dark = (0.6000, 0.1961, 0.8000)
|
||||
orchid_medium = (0.7294, 0.3333, 0.8275)
|
||||
permanent_red_violet = (0.8600, 0.1500, 0.2700)
|
||||
plum = (0.8667, 0.6275, 0.8667)
|
||||
purple = (0.6275, 0.1255, 0.9412)
|
||||
purple_medium = (0.5765, 0.4392, 0.8588)
|
||||
ultramarine_violet = (0.3600, 0.1400, 0.4300)
|
||||
violet = (0.5600, 0.3700, 0.6000)
|
||||
violet_dark = (0.5804, 0.0000, 0.8275)
|
||||
violet_red = (0.8157, 0.1255, 0.5647)
|
||||
violet_red_medium = (0.7804, 0.0824, 0.5216)
|
||||
violet_red_pale = (0.8588, 0.4392, 0.5765)
|
||||
@@ -0,0 +1,861 @@
|
||||
"""This module provides classes that allow numpy style access
|
||||
to VTK datasets. See examples at bottom.
|
||||
"""
|
||||
|
||||
from contextlib import suppress
|
||||
from vtkmodules.vtkCommonCore import vtkPoints, vtkAbstractArray, vtkDataArray
|
||||
from vtkmodules.vtkCommonDataModel import (
|
||||
vtkCellArray,
|
||||
vtkDataObject,
|
||||
vtkFieldData,
|
||||
vtkDataSetAttributes,
|
||||
vtkPointData,
|
||||
vtkCellData,
|
||||
vtkDataObject,
|
||||
vtkImageData,
|
||||
vtkMultiBlockDataSet,
|
||||
vtkPolyData,
|
||||
vtkStructuredGrid,
|
||||
vtkRectilinearGrid,
|
||||
vtkUnstructuredGrid,
|
||||
vtkOverlappingAMR,
|
||||
vtkPartitionedDataSet,
|
||||
vtkPartitionedDataSetCollection,
|
||||
)
|
||||
|
||||
import weakref
|
||||
|
||||
NUMPY_AVAILABLE = False
|
||||
|
||||
with suppress(ImportError):
|
||||
import numpy
|
||||
from vtkmodules.numpy_interface import dataset_adapter as dsa
|
||||
|
||||
NUMPY_AVAILABLE = True
|
||||
|
||||
|
||||
class FieldDataBase(object):
|
||||
def __init__(self):
|
||||
self.association = None
|
||||
self.dataset = None
|
||||
|
||||
def __getitem__(self, idx):
|
||||
"""Implements the [] operator. Accepts an array name or index."""
|
||||
return self.get_array(idx)
|
||||
|
||||
def __setitem__(self, name, value):
|
||||
"""Implements the [] operator. Accepts an array name or index."""
|
||||
return self.set_array(name, value)
|
||||
|
||||
def get_array(self, idx):
|
||||
"Given an index or name, returns a VTKArray."
|
||||
if isinstance(idx, int) and idx >= self.GetNumberOfArrays():
|
||||
raise IndexError("array index out of range")
|
||||
vtkarray = super().GetArray(idx)
|
||||
|
||||
if not NUMPY_AVAILABLE:
|
||||
return vtkarray if vtkarray else self.GetAbstractArray(idx)
|
||||
|
||||
if not vtkarray:
|
||||
vtkarray = self.GetAbstractArray(idx)
|
||||
if vtkarray:
|
||||
return vtkarray
|
||||
return dsa.NoneArray
|
||||
array = dsa.vtkDataArrayToVTKArray(vtkarray, self.dataset)
|
||||
array.Association = self.association
|
||||
return array
|
||||
|
||||
def __contains__(self, aname):
|
||||
"""Returns true if the container contains arrays
|
||||
with the given name, false otherwise"""
|
||||
return self.HasArray(aname)
|
||||
|
||||
def keys(self):
|
||||
"""Returns the names of the arrays as a list."""
|
||||
kys = []
|
||||
narrays = self.GetNumberOfArrays()
|
||||
for i in range(narrays):
|
||||
name = self.GetAbstractArray(i).GetName()
|
||||
if name:
|
||||
kys.append(name)
|
||||
return tuple(kys)
|
||||
|
||||
def values(self):
|
||||
"""Returns the arrays as a tuple."""
|
||||
vals = []
|
||||
narrays = self.GetNumberOfArrays()
|
||||
for i in range(narrays):
|
||||
a = self.get_array(i)
|
||||
if a.GetName():
|
||||
vals.append(a)
|
||||
return tuple(vals)
|
||||
|
||||
def items(self):
|
||||
"""Returns a tuple of pairs (name, array)"""
|
||||
pairs = []
|
||||
narrays = self.GetNumberOfArrays()
|
||||
for i in range(narrays):
|
||||
arr = self.get_array(i)
|
||||
name = arr.GetName()
|
||||
if name:
|
||||
pairs.append((name, arr))
|
||||
return tuple(pairs)
|
||||
|
||||
def set_array(self, name, narray):
|
||||
"""Appends a new array to the dataset attributes."""
|
||||
if not NUMPY_AVAILABLE:
|
||||
if isinstance(narray, vtkAbstractArray):
|
||||
narray.SetName(name)
|
||||
self.AddArray(narray)
|
||||
return
|
||||
|
||||
if narray is dsa.NoneArray:
|
||||
# if NoneArray, nothing to do.
|
||||
return
|
||||
|
||||
if self.association == vtkDataObject.POINT:
|
||||
arrLength = self.dataset.GetNumberOfPoints()
|
||||
elif self.association == vtkDataObject.CELL:
|
||||
arrLength = self.dataset.GetNumberOfCells()
|
||||
elif (
|
||||
self.association == vtkDataObject.ROW
|
||||
and self.dataset.GetNumberOfColumns() > 0
|
||||
):
|
||||
arrLength = self.dataset.GetNumberOfRows()
|
||||
else:
|
||||
if not isinstance(narray, numpy.ndarray):
|
||||
arrLength = 1
|
||||
else:
|
||||
arrLength = narray.shape[0]
|
||||
|
||||
# Fixup input array length:
|
||||
if (
|
||||
not isinstance(narray, numpy.ndarray) or numpy.ndim(narray) == 0
|
||||
): # Scalar input
|
||||
dtype = narray.dtype if isinstance(narray, numpy.ndarray) else type(narray)
|
||||
tmparray = numpy.empty(arrLength, dtype=dtype)
|
||||
tmparray.fill(narray)
|
||||
narray = tmparray
|
||||
elif narray.shape[0] != arrLength: # Vector input
|
||||
components = 1
|
||||
for l in narray.shape:
|
||||
components *= l
|
||||
tmparray = numpy.empty((arrLength, components), dtype=narray.dtype)
|
||||
tmparray[:] = narray.flatten()
|
||||
narray = tmparray
|
||||
|
||||
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 = numpy.ascontiguousarray(narray)
|
||||
|
||||
# Flatten array of matrices to array of vectors
|
||||
if len(shape) == 3:
|
||||
narray = narray.reshape(shape[0], shape[1] * shape[2])
|
||||
|
||||
# this handle 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 = dsa.VTKArray(narray)
|
||||
try:
|
||||
copy.VTKObject = narray.VTKObject
|
||||
except AttributeError:
|
||||
pass
|
||||
arr = dsa.numpyTovtkDataArray(copy, name)
|
||||
self.AddArray(arr)
|
||||
|
||||
def __eq__(self, other: object) -> bool:
|
||||
"""Test dict-like equivalency."""
|
||||
# here we check if other is the same class or a subclass of self.
|
||||
if not isinstance(other, type(self)):
|
||||
return False
|
||||
|
||||
if self is other:
|
||||
return True
|
||||
|
||||
"""
|
||||
If numpy is not available, only check for identity without comparing contents of the data arrays
|
||||
"""
|
||||
if not NUMPY_AVAILABLE:
|
||||
return False
|
||||
|
||||
if set(self.keys()) != set(other.keys()):
|
||||
return False
|
||||
|
||||
# verify the value of the arrays
|
||||
for key, value in other.items():
|
||||
if not numpy.array_equal(value, self[key]):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self.keys())
|
||||
|
||||
def __len__(self):
|
||||
return self.GetNumberOfArrays()
|
||||
|
||||
@vtkFieldData.override
|
||||
class FieldData(FieldDataBase, vtkFieldData):
|
||||
pass
|
||||
|
||||
|
||||
class DataSetAttributesBase(FieldDataBase):
|
||||
pass
|
||||
|
||||
|
||||
@vtkDataSetAttributes.override
|
||||
class DataSetAttributes(DataSetAttributesBase, vtkDataSetAttributes):
|
||||
def __eq__(self, other: object) -> bool:
|
||||
"""Test dict-like equivalency."""
|
||||
if not super().__eq__(other):
|
||||
return False
|
||||
|
||||
for attr in [
|
||||
"GetScalars",
|
||||
"GetVectors",
|
||||
"GetNormals",
|
||||
"GetTangents",
|
||||
"GetTCoords",
|
||||
"GetTensors",
|
||||
"GetGlobalIds",
|
||||
"GetPedigreeIds",
|
||||
"GetRationalWeights",
|
||||
"GetHigherOrderDegrees",
|
||||
"GetProcessIds",
|
||||
]:
|
||||
self_attr = getattr(self, attr)()
|
||||
other_attr = getattr(other, attr)()
|
||||
if self_attr and other_attr:
|
||||
if self_attr.GetName() != other_attr.GetName():
|
||||
return False
|
||||
elif self_attr != other_attr:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
@vtkPointData.override
|
||||
class PointData(DataSetAttributesBase, vtkPointData):
|
||||
pass
|
||||
|
||||
|
||||
@vtkCellData.override
|
||||
class CellData(DataSetAttributesBase, vtkCellData):
|
||||
pass
|
||||
|
||||
|
||||
class CompositeDataSetAttributesIterator(object):
|
||||
def __init__(self, cdsa):
|
||||
self._cdsa = cdsa
|
||||
if cdsa:
|
||||
self._itr = iter(cdsa.keys())
|
||||
else:
|
||||
self._itr = None
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def __next__(self):
|
||||
if not self._cdsa:
|
||||
raise StopIteration
|
||||
|
||||
name = next(self._itr)
|
||||
return self._cdsa[name]
|
||||
|
||||
def next(self):
|
||||
return self.__next__()
|
||||
|
||||
|
||||
class CompositeDataSetAttributes(object):
|
||||
"""This is a python friendly wrapper for vtkDataSetAttributes for composite
|
||||
datasets. Since composite datasets themselves don't have attribute data, but
|
||||
the attribute data is associated with the leaf nodes in the composite
|
||||
dataset, this class simulates a DataSetAttributes interface by taking a
|
||||
union of DataSetAttributes associated with all leaf nodes."""
|
||||
|
||||
def __init__(self, dataset, association):
|
||||
self.DataSet = dataset
|
||||
self.Association = association
|
||||
self.ArrayNames = []
|
||||
self.Arrays = {}
|
||||
|
||||
# build the set of arrays available in the composite dataset. Since
|
||||
# composite datasets can have partial arrays, we need to iterate over
|
||||
# all non-null blocks in the dataset.
|
||||
self.__determine_arraynames()
|
||||
|
||||
def __determine_arraynames(self):
|
||||
array_set = set()
|
||||
array_list = []
|
||||
for dataset in self.DataSet:
|
||||
dsa = dataset.GetAttributesAsFieldData(self.Association)
|
||||
for array_name in dsa.keys():
|
||||
if array_name not in array_set:
|
||||
array_set.add(array_name)
|
||||
array_list.append(array_name)
|
||||
self.ArrayNames = array_list
|
||||
|
||||
def modified(self):
|
||||
"""Rescans the contained dataset to update the
|
||||
internal list of arrays."""
|
||||
self.__determine_arraynames()
|
||||
|
||||
def __contains__(self, aname):
|
||||
"""Returns true if the container contains arrays
|
||||
with the given name, false otherwise"""
|
||||
return aname in self.ArrayNames
|
||||
|
||||
def keys(self):
|
||||
"""Returns the names of the arrays as a tuple."""
|
||||
return tuple(self.ArrayNames)
|
||||
|
||||
def values(self):
|
||||
"""Returns all the arrays as a tuple."""
|
||||
arrays = []
|
||||
for array in self:
|
||||
arrays.append(array)
|
||||
return tuple(arrays)
|
||||
|
||||
def items(self):
|
||||
"""Returns (name, array) pairs as a tuple."""
|
||||
items = []
|
||||
for name in self.keys():
|
||||
items.append((name, self[name]))
|
||||
return tuple(items)
|
||||
|
||||
def __getitem__(self, idx):
|
||||
"""Implements the [] operator. Accepts an array name."""
|
||||
return self.get_array(idx)
|
||||
|
||||
def __setitem__(self, name, narray):
|
||||
"""Implements the [] operator. Accepts an array name."""
|
||||
return self.set_array(name, narray)
|
||||
|
||||
def set_array(self, name, narray):
|
||||
"""Appends a new array to the composite dataset attributes."""
|
||||
if not NUMPY_AVAILABLE:
|
||||
# don't know how to handle composite dataset attribute when numpy not around
|
||||
raise NotImplementedError("Only available with numpy")
|
||||
|
||||
if narray is dsa.NoneArray:
|
||||
# if NoneArray, nothing to do.
|
||||
return
|
||||
|
||||
added = False
|
||||
if not isinstance(narray, dsa.VTKCompositeDataArray): # Scalar input
|
||||
for ds in self.DataSet:
|
||||
ds.GetAttributesAsFieldData(self.Association).set_array(name, narray)
|
||||
added = True
|
||||
if added:
|
||||
self.ArrayNames.append(name)
|
||||
# don't add the narray since it's a scalar. GetArray() will create a
|
||||
# VTKCompositeArray on-demand.
|
||||
else:
|
||||
for ds, array in zip(self.DataSet, narray.Arrays):
|
||||
if array is not None:
|
||||
ds.GetAttributesAsFieldData(self.Association).set_array(name, array)
|
||||
added = True
|
||||
if added:
|
||||
self.ArrayNames.append(name)
|
||||
self.Arrays[name] = weakref.ref(narray)
|
||||
|
||||
def get_array(self, idx):
|
||||
"""Given a name, returns a VTKCompositeArray."""
|
||||
arrayname = idx
|
||||
|
||||
if not NUMPY_AVAILABLE:
|
||||
# don't know how to handle composite dataset attribute when numpy not around
|
||||
raise NotImplementedError("Only available with numpy")
|
||||
|
||||
if arrayname not in self.ArrayNames:
|
||||
return dsa.NoneArray
|
||||
if arrayname not in self.Arrays or self.Arrays[arrayname]() is None:
|
||||
array = dsa.VTKCompositeDataArray(
|
||||
dataset=self.DataSet, name=arrayname, association=self.Association
|
||||
)
|
||||
self.Arrays[arrayname] = weakref.ref(array)
|
||||
else:
|
||||
array = self.Arrays[arrayname]()
|
||||
return array
|
||||
|
||||
def __iter__(self):
|
||||
"""Iterators on keys"""
|
||||
return iter(self.ArrayNames)
|
||||
|
||||
def __len__(self):
|
||||
return len(self.ArrayNames)
|
||||
|
||||
# class DataSet(DataObjectBase):
|
||||
class DataSet(object):
|
||||
def __init__(self, **kwargs) -> None:
|
||||
self._numpy_attrs = []
|
||||
|
||||
@property
|
||||
def point_data(self):
|
||||
pd = super().GetPointData()
|
||||
pd.dataset = self
|
||||
pd.association = self.POINT
|
||||
return pd
|
||||
|
||||
@property
|
||||
def cell_data(self):
|
||||
cd = super().GetCellData()
|
||||
cd.dataset = self
|
||||
cd.association = self.CELL
|
||||
return cd
|
||||
|
||||
@property
|
||||
def field_data(self):
|
||||
fd = super().GetFieldData()
|
||||
if fd:
|
||||
fd.dataset = self
|
||||
fd.association = self.FIELD
|
||||
return fd
|
||||
|
||||
def __eq__(self, other: object) -> bool:
|
||||
"""Test equivalency between data objects."""
|
||||
if not isinstance(self, type(other)):
|
||||
return False
|
||||
|
||||
if self is other:
|
||||
return True
|
||||
|
||||
"""
|
||||
If numpy is not available, only check for identity without comparing contents of the data arrays
|
||||
"""
|
||||
if not NUMPY_AVAILABLE:
|
||||
return False
|
||||
|
||||
for attr in self._numpy_attrs:
|
||||
if hasattr(self, attr):
|
||||
if not numpy.array_equal(getattr(self, attr), getattr(other, attr)):
|
||||
return False
|
||||
|
||||
for attr in ["field_data", "point_data", "cell_data"]:
|
||||
if getattr(self, attr) != getattr(other, attr):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def convert_to_unstructured_grid(self):
|
||||
from vtkmodules.vtkFiltersCore import vtkExtractCells
|
||||
|
||||
ecells = vtkExtractCells()
|
||||
ecells.SetInputData(self)
|
||||
ecells.ExtractAllCellsOn()
|
||||
ecells.Update()
|
||||
return ecells.GetOutput()
|
||||
|
||||
|
||||
class PointSet(DataSet):
|
||||
def __init__(self, **kwargs) -> None:
|
||||
DataSet.__init__(self, **kwargs)
|
||||
self._numpy_attrs.append("points")
|
||||
|
||||
@property
|
||||
def points(self):
|
||||
pts = self.GetPoints()
|
||||
|
||||
if not NUMPY_AVAILABLE:
|
||||
return pts
|
||||
|
||||
if not pts or not pts.GetData():
|
||||
return None
|
||||
return dsa.vtkDataArrayToVTKArray(pts.GetData())
|
||||
|
||||
@points.setter
|
||||
def points(self, points):
|
||||
if isinstance(points, vtkPoints):
|
||||
self.SetPoints(points)
|
||||
return
|
||||
|
||||
if not NUMPY_AVAILABLE:
|
||||
raise ValueError("Expect vtkPoints")
|
||||
|
||||
pts = dsa.numpyTovtkDataArray(points, "points")
|
||||
vtkpts = vtkPoints()
|
||||
vtkpts.SetData(pts)
|
||||
self.SetPoints(vtkpts)
|
||||
|
||||
|
||||
@vtkUnstructuredGrid.override
|
||||
class UnstructuredGrid(PointSet, vtkUnstructuredGrid):
|
||||
def __init__(self, **kwargs):
|
||||
PointSet.__init__(self, **kwargs)
|
||||
vtkUnstructuredGrid.__init__(self, **kwargs)
|
||||
|
||||
@property
|
||||
def cells(self):
|
||||
ca = self.GetCells()
|
||||
conn_vtk = ca.GetConnectivityArray()
|
||||
offsets_vtk = ca.GetOffsetsArray()
|
||||
ct_vtk = self.GetCellTypesArray()
|
||||
|
||||
if not NUMPY_AVAILABLE:
|
||||
return {
|
||||
"connectivity": conn_vtk,
|
||||
"offsets": offsets_vtk,
|
||||
"cell_types": ct_vtk,
|
||||
}
|
||||
|
||||
conn = dsa.vtkDataArrayToVTKArray(conn_vtk)
|
||||
offsets = dsa.vtkDataArrayToVTKArray(offsets_vtk)
|
||||
ct = dsa.vtkDataArrayToVTKArray(ct_vtk)
|
||||
return {"connectivity": conn, "offsets": offsets, "cell_types": ct}
|
||||
|
||||
@cells.setter
|
||||
def cells(self, cells):
|
||||
ca = vtkCellArray()
|
||||
|
||||
if not NUMPY_AVAILABLE:
|
||||
ca.SetData(cells["offsets"], cells["connectivity"])
|
||||
self.SetCells(cells["cell_types"], ca)
|
||||
return
|
||||
|
||||
conn_vtk = dsa.numpyTovtkDataArray(cells["connectivity"])
|
||||
offsets_vtk = dsa.numpyTovtkDataArray(cells["offsets"])
|
||||
cell_types_vtk = dsa.numpyTovtkDataArray(cells["cell_types"])
|
||||
ca.SetData(offsets_vtk, conn_vtk)
|
||||
self.SetCells(cell_types_vtk, ca)
|
||||
|
||||
|
||||
@vtkImageData.override
|
||||
class ImageData(DataSet, vtkImageData):
|
||||
def __init__(self, **kwargs):
|
||||
DataSet.__init__(self, **kwargs)
|
||||
vtkImageData.__init__(self, **kwargs)
|
||||
|
||||
|
||||
@vtkPolyData.override
|
||||
class PolyData(PointSet, vtkPolyData):
|
||||
def __init__(self, **kwargs) -> None:
|
||||
PointSet.__init__(self, **kwargs)
|
||||
vtkPolyData.__init__(self, **kwargs)
|
||||
self._numpy_attrs.extend(["verts", "lines", "strips", "polys"])
|
||||
|
||||
@property
|
||||
def verts_arrays(self):
|
||||
ca = self.GetVerts()
|
||||
conn_vtk = ca.GetConnectivityArray()
|
||||
offsets_vtk = ca.GetOffsetsArray()
|
||||
|
||||
if not NUMPY_AVAILABLE:
|
||||
return {
|
||||
"connectivity": conn_vtk,
|
||||
"offsets": offsets_vtk,
|
||||
}
|
||||
|
||||
conn = dsa.vtkDataArrayToVTKArray(conn_vtk)
|
||||
offsets = dsa.vtkDataArrayToVTKArray(offsets_vtk)
|
||||
return {"connectivity": conn, "offsets": offsets}
|
||||
|
||||
@property
|
||||
def lines_arrays(self):
|
||||
ca = self.GetLines()
|
||||
conn_vtk = ca.GetConnectivityArray()
|
||||
offsets_vtk = ca.GetOffsetsArray()
|
||||
|
||||
if not NUMPY_AVAILABLE:
|
||||
return {
|
||||
"connectivity": conn_vtk,
|
||||
"offsets": offsets_vtk,
|
||||
}
|
||||
|
||||
conn = dsa.vtkDataArrayToVTKArray(conn_vtk)
|
||||
offsets = dsa.vtkDataArrayToVTKArray(offsets_vtk)
|
||||
return {"connectivity": conn, "offsets": offsets}
|
||||
|
||||
@property
|
||||
def strips_arrays(self):
|
||||
ca = self.GetStrips()
|
||||
conn_vtk = ca.GetConnectivityArray()
|
||||
offsets_vtk = ca.GetOffsetsArray()
|
||||
|
||||
if not NUMPY_AVAILABLE:
|
||||
return {
|
||||
"connectivity": conn_vtk,
|
||||
"offsets": offsets_vtk,
|
||||
}
|
||||
|
||||
conn = dsa.vtkDataArrayToVTKArray(conn_vtk)
|
||||
offsets = dsa.vtkDataArrayToVTKArray(offsets_vtk)
|
||||
return {"connectivity": conn, "offsets": offsets}
|
||||
|
||||
@property
|
||||
def polys_arrays(self):
|
||||
ca = self.GetPolys()
|
||||
conn_vtk = ca.GetConnectivityArray()
|
||||
offsets_vtk = ca.GetOffsetsArray()
|
||||
|
||||
if not NUMPY_AVAILABLE:
|
||||
return {
|
||||
"connectivity": conn_vtk,
|
||||
"offsets": offsets_vtk,
|
||||
}
|
||||
|
||||
conn = dsa.vtkDataArrayToVTKArray(conn_vtk)
|
||||
offsets = dsa.vtkDataArrayToVTKArray(offsets_vtk)
|
||||
return {"connectivity": conn, "offsets": offsets}
|
||||
|
||||
|
||||
@vtkRectilinearGrid.override
|
||||
class RectilinearGrid(DataSet, vtkRectilinearGrid):
|
||||
def __init__(self, **kwargs) -> None:
|
||||
DataSet.__init__(self, **kwargs)
|
||||
vtkRectilinearGrid.__init__(self, **kwargs)
|
||||
self._numpy_attrs.extend(["x_coordinates", "y_coordinates", "z_coordinates"])
|
||||
|
||||
@property
|
||||
def x_coordinates(self):
|
||||
pts = self.GetXCoordinates()
|
||||
|
||||
if not NUMPY_AVAILABLE:
|
||||
return pts
|
||||
|
||||
if not pts:
|
||||
return None
|
||||
return dsa.vtkDataArrayToVTKArray(pts)
|
||||
|
||||
@x_coordinates.setter
|
||||
def x_coordinates(self, points):
|
||||
if isinstance(points, vtkDataArray):
|
||||
self.SetXCoordinates(points)
|
||||
return
|
||||
|
||||
if not NUMPY_AVAILABLE:
|
||||
raise ValueError("Expect vtkDataArray")
|
||||
|
||||
pts = dsa.numpyTovtkDataArray(points, "x_coords")
|
||||
self.SetXCoordinates(pts)
|
||||
|
||||
@property
|
||||
def y_coordinates(self):
|
||||
pts = self.GetYCoordinates()
|
||||
|
||||
if not NUMPY_AVAILABLE:
|
||||
return pts
|
||||
|
||||
if not pts:
|
||||
return None
|
||||
return dsa.vtkDataArrayToVTKArray(pts)
|
||||
|
||||
@y_coordinates.setter
|
||||
def y_coordinates(self, points):
|
||||
if isinstance(points, vtkDataArray):
|
||||
self.SetYCoordinates(points)
|
||||
return
|
||||
|
||||
if not NUMPY_AVAILABLE:
|
||||
raise ValueError("Expect vtkDataArray")
|
||||
|
||||
pts = dsa.numpyTovtkDataArray(points, "y_coords")
|
||||
self.SetYCoordinates(pts)
|
||||
|
||||
@property
|
||||
def z_coordinates(self):
|
||||
pts = self.GetZCoordinates()
|
||||
|
||||
if not NUMPY_AVAILABLE:
|
||||
return pts
|
||||
|
||||
if not pts:
|
||||
return None
|
||||
return dsa.vtkDataArrayToVTKArray(pts)
|
||||
|
||||
@z_coordinates.setter
|
||||
def z_coordinates(self, points):
|
||||
if isinstance(points, vtkDataArray):
|
||||
self.SetZCoordinates(points)
|
||||
return
|
||||
|
||||
if not NUMPY_AVAILABLE:
|
||||
raise ValueError("Expect vtkDataArray")
|
||||
|
||||
pts = dsa.numpyTovtkDataArray(points, "z_coords")
|
||||
self.SetZCoordinates(pts)
|
||||
|
||||
|
||||
class CompositeDataIterator(object):
|
||||
"""Wrapper for a vtkCompositeDataIterator class to satisfy
|
||||
the python iterator protocol. This iterator iterates
|
||||
over non-empty leaf nodes. To iterate over empty or
|
||||
non-leaf nodes, use the vtkCompositeDataIterator directly.
|
||||
"""
|
||||
|
||||
def __init__(self, cds):
|
||||
self.Iterator = cds.NewIterator()
|
||||
if self.Iterator:
|
||||
self.Iterator.UnRegister(None)
|
||||
self.Iterator.GoToFirstItem()
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def __next__(self):
|
||||
if not self.Iterator:
|
||||
raise StopIteration
|
||||
|
||||
if self.Iterator.IsDoneWithTraversal():
|
||||
raise StopIteration
|
||||
retVal = self.Iterator.GetCurrentDataObject()
|
||||
self.Iterator.GoToNextItem()
|
||||
return retVal
|
||||
|
||||
def next(self):
|
||||
return self.__next__()
|
||||
|
||||
def __getattr__(self, name):
|
||||
"""Returns attributes from the vtkCompositeDataIterator."""
|
||||
return getattr(self.Iterator, name)
|
||||
|
||||
|
||||
class CompositeDataSetBase(object):
|
||||
"""A wrapper for vtkCompositeData and subclasses that makes it easier
|
||||
to access Point/Cell/Field data as VTKCompositeDataArrays. It also
|
||||
provides a Python type iterator."""
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self._PointData = None
|
||||
self._CellData = None
|
||||
self._FieldData = None
|
||||
self._Points = None
|
||||
|
||||
def __iter__(self):
|
||||
"Creates an iterator for the contained datasets."
|
||||
return CompositeDataIterator(self)
|
||||
|
||||
def get_attributes(self, type):
|
||||
"""Returns the attributes specified by the type as a
|
||||
CompositeDataSetAttributes instance."""
|
||||
return CompositeDataSetAttributes(self, type)
|
||||
|
||||
@property
|
||||
def point_data(self):
|
||||
"Returns the point data as a DataSetAttributes instance."
|
||||
if self._PointData is None or self._PointData() is None:
|
||||
pdata = self.get_attributes(vtkDataObject.POINT)
|
||||
self._PointData = weakref.ref(pdata)
|
||||
return self._PointData()
|
||||
|
||||
@property
|
||||
def cell_data(self):
|
||||
"Returns the cell data as a DataSetAttributes instance."
|
||||
if self._CellData is None or self._CellData() is None:
|
||||
cdata = self.get_attributes(vtkDataObject.CELL)
|
||||
self._CellData = weakref.ref(cdata)
|
||||
return self._CellData()
|
||||
|
||||
@property
|
||||
def field_data(self):
|
||||
"Returns the field data as a DataSetAttributes instance."
|
||||
if self._FieldData is None or self._FieldData() is None:
|
||||
fdata = self.get_attributes(vtkDataObject.FIELD)
|
||||
self._FieldData = weakref.ref(fdata)
|
||||
return self._FieldData()
|
||||
|
||||
@property
|
||||
def points(self):
|
||||
"Returns the points as a VTKCompositeDataArray instance."
|
||||
if not NUMPY_AVAILABLE:
|
||||
# don't know how to handle composite dataset when numpy not around
|
||||
raise NotImplementedError("Only available with numpy")
|
||||
|
||||
if self._Points is None or self._Points() is None:
|
||||
pts = []
|
||||
for ds in self:
|
||||
try:
|
||||
_pts = ds.Points
|
||||
except AttributeError:
|
||||
_pts = None
|
||||
|
||||
if _pts is None:
|
||||
pts.append(dsa.NoneArray)
|
||||
else:
|
||||
pts.append(_pts)
|
||||
if len(pts) == 0 or all([a is dsa.NoneArray for a in pts]):
|
||||
cpts = dsa.NoneArray
|
||||
else:
|
||||
cpts = dsa.VTKCompositeDataArray(pts, dataset=self)
|
||||
self._Points = weakref.ref(cpts)
|
||||
return self._Points()
|
||||
|
||||
|
||||
@vtkPartitionedDataSet.override
|
||||
class PartitionedDataSet(CompositeDataSetBase, vtkPartitionedDataSet):
|
||||
def append(self, dataset):
|
||||
self.SetPartition(self.GetNumberOfPartitions(), dataset)
|
||||
|
||||
@vtkPartitionedDataSetCollection.override
|
||||
class PartitionedDataSetCollection(CompositeDataSetBase, vtkPartitionedDataSetCollection):
|
||||
def append(self, dataset):
|
||||
self.SetPartitionedDataSet(self.GetNumberOfPartitionedDataSets(), dataset)
|
||||
|
||||
@vtkOverlappingAMR.override
|
||||
class OverlappingAMR(CompositeDataSetBase, vtkOverlappingAMR):
|
||||
pass
|
||||
|
||||
@vtkMultiBlockDataSet.override
|
||||
class MultiBlockDataSet(CompositeDataSetBase, vtkMultiBlockDataSet):
|
||||
pass
|
||||
|
||||
@vtkStructuredGrid.override
|
||||
class StructuredGrid(PointSet, vtkStructuredGrid):
|
||||
def __init__(self, **kwargs):
|
||||
PointSet.__init__(self, **kwargs)
|
||||
vtkStructuredGrid.__init__(self, **kwargs)
|
||||
|
||||
@property
|
||||
def x_coordinates(self):
|
||||
if not NUMPY_AVAILABLE:
|
||||
raise NotImplementedError("Only available with numpy")
|
||||
|
||||
dims = [0,0,0]
|
||||
self.GetDimensions(dims)
|
||||
return self.points[:, 0].reshape(dims, order="F")
|
||||
|
||||
@property
|
||||
def y_coordinates(self):
|
||||
if not NUMPY_AVAILABLE:
|
||||
raise NotImplementedError("Only available with numpy")
|
||||
|
||||
dims = [0,0,0]
|
||||
self.GetDimensions(dims)
|
||||
return self.points[:, 1].reshape(dims, order="F")
|
||||
|
||||
@property
|
||||
def z_coordinates(self):
|
||||
if not NUMPY_AVAILABLE:
|
||||
raise NotImplementedError("Only available with numpy")
|
||||
dims = [0,0,0]
|
||||
self.GetDimensions(dims)
|
||||
return self.points[:, 2].reshape(dims, order="F")
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Handle pickle registration
|
||||
# -----------------------------------------------------------------------------
|
||||
with suppress(ImportError):
|
||||
import copyreg
|
||||
from vtkmodules.util.pickle_support import serialize_VTK_data_object
|
||||
|
||||
copyreg.pickle(PolyData, serialize_VTK_data_object)
|
||||
copyreg.pickle(UnstructuredGrid, serialize_VTK_data_object)
|
||||
copyreg.pickle(ImageData, serialize_VTK_data_object)
|
||||
copyreg.pickle(PartitionedDataSet, serialize_VTK_data_object)
|
||||
copyreg.pickle(StructuredGrid, serialize_VTK_data_object)
|
||||
@@ -0,0 +1,268 @@
|
||||
"""Utility classes to help with the simpler Python interface
|
||||
for connecting and executing pipelines."""
|
||||
|
||||
__all__ = ['select_ports', 'Pipeline', 'Output']
|
||||
|
||||
def _call(first, last, inp=None, port=0):
|
||||
"""Set the input of the first filter, update the pipeline
|
||||
and return the output."""
|
||||
if inp and not first.GetNumberOfInputPorts():
|
||||
raise ValueError(f"{first.GetClassName()} does not have input ports yet an input was passed to the pipeline.")
|
||||
in_cons = []
|
||||
if first.GetNumberOfInputPorts():
|
||||
n_cons = first.GetNumberOfInputConnections(port)
|
||||
for i in range(n_cons):
|
||||
op = first.GetInputConnection(port, i)
|
||||
if op and op.GetProducer():
|
||||
op.GetProducer().Register(None)
|
||||
in_cons.append(op)
|
||||
from vtkmodules.vtkCommonExecutionModel import vtkAlgorithm
|
||||
from vtkmodules.vtkCommonExecutionModel import vtkTrivialProducer
|
||||
from collections.abc import Sequence
|
||||
if isinstance(inp, Sequence):
|
||||
if first.GetInputPortInformation(port).Has(
|
||||
vtkAlgorithm.INPUT_IS_REPEATABLE()):
|
||||
first.RemoveAllInputConnections(port)
|
||||
for aInp in inp:
|
||||
tp = vtkTrivialProducer()
|
||||
tp.SetOutput(aInp)
|
||||
first.AddInputConnection(port, tp.GetOutputPort());
|
||||
else:
|
||||
tp = vtkTrivialProducer()
|
||||
tp.SetOutput(inp)
|
||||
first.SetInputConnection(port, tp.GetOutputPort());
|
||||
|
||||
output = last.update().output
|
||||
|
||||
if first.GetNumberOfInputPorts():
|
||||
first.RemoveAllInputConnections(port)
|
||||
for op in in_cons:
|
||||
first.AddInputConnection(port, op)
|
||||
if op and op.GetProducer():
|
||||
op.GetProducer().UnRegister(None)
|
||||
|
||||
output_copy = []
|
||||
if type(output) is not tuple:
|
||||
output = (output,)
|
||||
for opt in output:
|
||||
copy = opt.NewInstance()
|
||||
copy.ShallowCopy(opt)
|
||||
output_copy.append(copy)
|
||||
if len(output_copy) == 1:
|
||||
return output_copy[0]
|
||||
else:
|
||||
return tuple(output_copy)
|
||||
|
||||
|
||||
class select_ports(object):
|
||||
"""Helper class for selecting input and output ports when
|
||||
connecting pipeline objects with the >> operator.
|
||||
Example uses:
|
||||
# Connect a source to the second input of a filter.
|
||||
source >> select_ports(1, filter)
|
||||
# Connect the second output of a source to a filter.
|
||||
select_ports(source, 1) >> filter
|
||||
# Combination of both: Connect source to second
|
||||
# input of the filter, then connect the second
|
||||
# output of that filter to another one.
|
||||
source >>> select_ports(1, filter, 1) >> filter2
|
||||
"""
|
||||
def __init__(self, *args):
|
||||
"""This constructor takes 2 or 3 arguments.
|
||||
The possibilities are:
|
||||
select_ports(input_port, algorithm)
|
||||
select_ports(algorithm, output_port)
|
||||
select_ports(input_port, algorithm, output_port)
|
||||
"""
|
||||
nargs = len(args)
|
||||
if nargs < 2 or nargs > 3:
|
||||
raise ValueError("Expecting 2 or 3 arguments")
|
||||
|
||||
self.input_port = None
|
||||
self.output_port = None
|
||||
before_alg = True
|
||||
for arg in args:
|
||||
if hasattr(arg, "IsA") and arg.IsA("vtkAlgorithm"):
|
||||
self.algorithm = arg
|
||||
before_alg = False
|
||||
else:
|
||||
if before_alg:
|
||||
self.input_port = arg
|
||||
else:
|
||||
self.output_port = arg
|
||||
if not self.input_port:
|
||||
self.input_port = 0
|
||||
if not self.output_port:
|
||||
self.output_port = 0
|
||||
|
||||
def SetInputConnection(self, inp):
|
||||
"Forwards to underlying algorithm and port."
|
||||
self.algorithm.SetInputConnection(self.input_port, inp)
|
||||
|
||||
def AddInputConnection(self, inp):
|
||||
"Forwards to underlying algorithm and port."
|
||||
self.algorithm.AddInputConnection(self.input_port, inp)
|
||||
|
||||
def GetOutputPort(self):
|
||||
"Returns the output port of the underlying algorithm."
|
||||
return self.algorithm.GetOutputPort(self.output_port)
|
||||
|
||||
def GetInputPortInformation(self, port):
|
||||
return self.algorithm.GetInputPortInformation(self.input_port)
|
||||
|
||||
def update(self):
|
||||
"""Execute the algorithm and return the output from the selected
|
||||
output port."""
|
||||
return self.algorithm.update()
|
||||
|
||||
def __rshift__(self, rhs):
|
||||
"Creates a pipeline between the underlying port and an algorithm."
|
||||
return Pipeline(self, rhs)
|
||||
|
||||
def __rrshift__(self, lhs):
|
||||
"""Creates a pipeline between the underlying port and an algorithm.
|
||||
This is to handle sequence >> select_ports where the port can
|
||||
accept multiple connections."""
|
||||
from collections.abc import Sequence
|
||||
if lhs is None or (isinstance(lhs, Sequence) and len(lhs == 0)):
|
||||
self.algorithm.RemoveAllInputConnections(self.input_port)
|
||||
return self
|
||||
return Pipeline(lhs, self)
|
||||
|
||||
def __call__(self, inp=None):
|
||||
"""Executes the underlying algorithm by passing input data to
|
||||
the selected input port. Returns a single output or a tuple
|
||||
if there are multiple outputs."""
|
||||
return _call(self.algorithm, self.algorithm, inp, self.input_port)
|
||||
|
||||
class Pipeline(object):
|
||||
"""Pipeline objects are created when 2 or more algorithms are
|
||||
connected with the >> operator. They store the first and last
|
||||
algorithms in the pipeline and enable connecting more algorithms
|
||||
and executing the pipeline. One should not have to create Pipeline
|
||||
objects directly. They are created by the use of the >> operator."""
|
||||
|
||||
PIPELINE = 0
|
||||
ALGORITHM = 1
|
||||
DATA = 2
|
||||
UNKNOWN = 3
|
||||
|
||||
def __init__(self, lhs, rhs):
|
||||
"""Create a pipeline object that connects two objects of the
|
||||
following type: data object, pipeline object, algorithm object."""
|
||||
left_type = self._determine_type(lhs)
|
||||
right_type = self._determine_type(rhs)
|
||||
if right_type == Pipeline.ALGORITHM:
|
||||
rhs_alg = rhs
|
||||
elif right_type == Pipeline.PIPELINE:
|
||||
rhs_alg = rhs.first
|
||||
else:
|
||||
raise TypeError(
|
||||
f"unsupported operand type(s) for >>: {type(lhs).__name__} and {type(rhs).__name__}")
|
||||
|
||||
from collections.abc import Sequence
|
||||
if isinstance(lhs, Sequence):
|
||||
for inp in lhs:
|
||||
self._connect(inp, rhs, rhs_alg, "AddInputConnection")
|
||||
else:
|
||||
self._connect(lhs, rhs, rhs_alg, "SetInputConnection")
|
||||
|
||||
def _connect(self, lhs, rhs, rhs_alg, connect_method):
|
||||
from vtkmodules.vtkCommonExecutionModel import vtkAlgorithm
|
||||
inInfo = rhs_alg.GetInputPortInformation(0)
|
||||
if inInfo.Has(vtkAlgorithm.INPUT_IS_REPEATABLE()):
|
||||
connect_method = 'AddInputConnection'
|
||||
|
||||
left_type = self._determine_type(lhs)
|
||||
right_type = self._determine_type(rhs)
|
||||
if left_type == Pipeline.UNKNOWN:
|
||||
raise TypeError(
|
||||
f"unsupported operand type(s) for >>: {type(lhs).__name__} and {type(rhs).__name__}")
|
||||
if right_type == Pipeline.ALGORITHM:
|
||||
if left_type == Pipeline.ALGORITHM:
|
||||
getattr(rhs_alg, connect_method)(lhs.GetOutputPort())
|
||||
self.first = lhs
|
||||
self.last = rhs
|
||||
elif left_type == Pipeline.PIPELINE:
|
||||
getattr(rhs_alg, connect_method)(lhs.last.GetOutputPort())
|
||||
self.first = lhs.first
|
||||
self.last = rhs
|
||||
elif left_type == Pipeline.DATA:
|
||||
from vtkmodules.vtkCommonExecutionModel import vtkTrivialProducer
|
||||
source = vtkTrivialProducer()
|
||||
source.SetOutput(lhs)
|
||||
getattr(rhs_alg, connect_method)(source.GetOutputPort())
|
||||
self.first = source
|
||||
self.last = rhs
|
||||
elif right_type == Pipeline.PIPELINE:
|
||||
if left_type == Pipeline.ALGORITHM:
|
||||
self.first = lhs
|
||||
self.last = rhs.last
|
||||
getattr(rhs_alg, connect_method)(lhs.GetOutputPort())
|
||||
elif left_type == Pipeline.PIPELINE:
|
||||
getattr(rhs_alg, connect_method)(lhs.last.GetOutputPort())
|
||||
self.first = lhs.first
|
||||
self.last = rhs.last
|
||||
elif left_type == Pipeline.DATA:
|
||||
from vtkmodules.vtkCommonExecutionModel import vtkTrivialProducer
|
||||
source = vtkTrivialProducer()
|
||||
source.SetOutput(lhs)
|
||||
getattr(rhs_alg, connect_method)(source.GetOutputPort())
|
||||
self.first = source
|
||||
self.last = rhs.last
|
||||
|
||||
def _determine_type(self, arg):
|
||||
if type(arg) is Pipeline:
|
||||
return Pipeline.PIPELINE
|
||||
if hasattr(arg, "SetInputConnection"):
|
||||
return Pipeline.ALGORITHM
|
||||
if hasattr(arg, "IsA") and arg.IsA("vtkDataObject"):
|
||||
return Pipeline.DATA
|
||||
return Pipeline.UNKNOWN
|
||||
|
||||
def update(self, **kwargs):
|
||||
"""Update the pipeline and return the last algorithm's
|
||||
output."""
|
||||
return self.last.update()
|
||||
|
||||
def __call__(self, inp=None):
|
||||
"""Sets the input of the first filter, update the pipeline
|
||||
and returns the output. A single data object or a tuple
|
||||
of data objects (when there are multiple outputs) are
|
||||
returned."""
|
||||
return _call(self.first, self.last, inp)
|
||||
|
||||
def __rshift__(self, rhs):
|
||||
"""Used to connect two pipeline items. The left side can
|
||||
be a data object, an algorithm or a pipeline. The right
|
||||
side can be an algorithm or a pipeline."""
|
||||
return Pipeline(self, rhs)
|
||||
|
||||
def __rrshift__(self, lhs):
|
||||
"""Creates a pipeline between a sequence input and a pipeline."""
|
||||
from collections.abc import Sequence
|
||||
if lhs is None or (isinstance(lhs, Sequence) and len(lhs) == 0):
|
||||
self.first.RemoveAllInputConnections(0)
|
||||
return self
|
||||
return Pipeline(lhs, self)
|
||||
|
||||
class Output(object):
|
||||
"""Helper object to represent the output of an algorithms as
|
||||
returned by the update() method. Implements the output property
|
||||
enabling calling update().output."""
|
||||
def __init__(self, algorithm, **kwargs):
|
||||
self.algorithm = algorithm
|
||||
self.algorithm.Update()
|
||||
|
||||
@property
|
||||
def output(self):
|
||||
"""Returns a single data object or a tuple of data objects
|
||||
if there are multiple outputs."""
|
||||
if self.algorithm.GetNumberOfOutputPorts() == 1:
|
||||
return self.algorithm.GetOutputDataObject(0)
|
||||
else:
|
||||
outputs = []
|
||||
nOutputs = self.algorithm.GetNumberOfOutputPorts()
|
||||
for i in range(nOutputs):
|
||||
outputs.append(self.algorithm.GetOutputDataObject(i))
|
||||
return tuple(outputs)
|
||||
@@ -0,0 +1,29 @@
|
||||
"""
|
||||
Utility module to make it easier to create new keys.
|
||||
"""
|
||||
from vtkmodules.vtkCommonCore import vtkInformationDataObjectKey as DataaObjectKey
|
||||
from vtkmodules.vtkCommonCore import vtkInformationDoubleKey as DoubleKey
|
||||
from vtkmodules.vtkCommonCore import vtkInformationDoubleVectorKey as DoubleVectorKey
|
||||
from vtkmodules.vtkCommonCore import vtkInformationIdTypeKey as IdTypeKey
|
||||
from vtkmodules.vtkCommonCore import vtkInformationInformationKey as InformationKey
|
||||
from vtkmodules.vtkCommonCore import vtkInformationInformationVectorKey as InformationVectorKey
|
||||
from vtkmodules.vtkCommonCore import vtkInformationIntegerKey as IntegerKey
|
||||
from vtkmodules.vtkCommonCore import vtkInformationIntegerVectorKey as IntegerVectorKey
|
||||
from vtkmodules.vtkCommonCore import vtkInformationKeyVectorKey as KeyVectorKey
|
||||
from vtkmodules.vtkCommonCore import vtkInformationObjectBaseKey as ObjectBaseKey
|
||||
from vtkmodules.vtkCommonCore import vtkInformationObjectBaseVectorKey as ObjectBaseVectorKey
|
||||
from vtkmodules.vtkCommonCore import vtkInformationRequestKey as RequestKey
|
||||
from vtkmodules.vtkCommonCore import vtkInformationStringKey as StringKey
|
||||
from vtkmodules.vtkCommonCore import vtkInformationStringVectorKey as StringVectorKey
|
||||
from vtkmodules.vtkCommonCore import vtkInformationUnsignedLongKey as UnsignedLongKey
|
||||
from vtkmodules.vtkCommonCore import vtkInformationVariantKey as VariantKey
|
||||
from vtkmodules.vtkCommonCore import vtkInformationVariantVectorKey as VariantVectorKey
|
||||
from vtkmodules.vtkCommonExecutionModel import vtkInformationDataObjectMetaDataKey as DataObjectMetaDataKey
|
||||
from vtkmodules.vtkCommonExecutionModel import vtkInformationExecutivePortKey as ExecutivePortKey
|
||||
from vtkmodules.vtkCommonExecutionModel import vtkInformationExecutivePortVectorKey as ExecutivePortVectorKey
|
||||
from vtkmodules.vtkCommonExecutionModel import vtkInformationIntegerRequestKey as IntegerRequestKey
|
||||
|
||||
def MakeKey(key_type, name, location, *args):
|
||||
"""Given a key type, make a new key of given name
|
||||
and location."""
|
||||
return key_type.MakeKey(name, location, *args)
|
||||
@@ -0,0 +1,133 @@
|
||||
"""Miscellaneous functions and classes that don't fit into specific
|
||||
categories."""
|
||||
|
||||
import sys, os
|
||||
from functools import wraps
|
||||
import warnings
|
||||
|
||||
def deprecated(version, message):
|
||||
"""
|
||||
Decorator to mark functions as deprecated.
|
||||
When the decorated function is called, a DeprecationWarning is issued with the provided message.
|
||||
|
||||
Example
|
||||
-------
|
||||
>>> @deprecated(version=1.2, message="Use 'new_function' instead.")
|
||||
... def old_function():
|
||||
... pass
|
||||
|
||||
>>> old_function()
|
||||
DeprecationWarning: Function 'old_function' is deprecated since 1.2. Use 'new_function' instead.
|
||||
|
||||
Note you can filter warning messages, see: https://docs.python.org/3/library/warnings.html#describing-warning-filters
|
||||
"""
|
||||
def decorator(func):
|
||||
warn = f"Function '{func.__name__}' is deprecated since version {version}. " + message
|
||||
@wraps(func)
|
||||
def wrapped(*args, **kwargs):
|
||||
warnings.warn(warn, DeprecationWarning)
|
||||
return func(*args, **kwargs)
|
||||
return wrapped
|
||||
return decorator
|
||||
|
||||
def calldata_type(type):
|
||||
"""set_call_data_type(type) -- convenience decorator to easily set the CallDataType attribute
|
||||
for python function used as observer callback.
|
||||
For example:
|
||||
|
||||
import vtkmodules.util.calldata_type
|
||||
import vtkmodules.util.vtkConstants
|
||||
import vtkmodules.vtkCommonCore import vtkCommand, vtkLookupTable
|
||||
|
||||
@calldata_type(vtkConstants.VTK_STRING)
|
||||
def onError(caller, event, calldata):
|
||||
print("caller: %s - event: %s - msg: %s" % (caller.GetClassName(), event, calldata))
|
||||
|
||||
lt = vtkLookupTable()
|
||||
lt.AddObserver(vtkCommand.ErrorEvent, onError)
|
||||
lt.SetTableRange(2,1)
|
||||
"""
|
||||
from vtkmodules import vtkCommonCore
|
||||
supported_call_data_types = ['string0', vtkCommonCore.VTK_STRING,
|
||||
vtkCommonCore.VTK_OBJECT, vtkCommonCore.VTK_INT,
|
||||
vtkCommonCore.VTK_LONG, vtkCommonCore.VTK_DOUBLE, vtkCommonCore.VTK_FLOAT]
|
||||
|
||||
if type not in supported_call_data_types:
|
||||
raise TypeError("'%s' is not a supported VTK call data type. Supported types are: %s" % (type, supported_call_data_types))
|
||||
|
||||
def wrap(f):
|
||||
f.CallDataType = type
|
||||
return f
|
||||
|
||||
return wrap
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# the following functions are for the vtk regression testing and examples
|
||||
|
||||
def vtkGetDataRoot():
|
||||
"""vtkGetDataRoot() -- return vtk example data directory"""
|
||||
dataRoot = None
|
||||
for i, argv in enumerate(sys.argv):
|
||||
if argv == '-D' and i+1 < len(sys.argv):
|
||||
dataRoot = sys.argv[i+1]
|
||||
|
||||
if dataRoot is None:
|
||||
dataRoot = os.environ.get('VTK_DATA_ROOT', '../../../../VTKData')
|
||||
|
||||
return dataRoot
|
||||
|
||||
def vtkGetTempDir():
|
||||
"""vtkGetTempDir() -- return vtk testing temp dir"""
|
||||
tempDir = None
|
||||
for i, argv in enumerate(sys.argv):
|
||||
if argv == '-T' and i+1 < len(sys.argv):
|
||||
tempDir = sys.argv[i+1]
|
||||
|
||||
if tempDir is None:
|
||||
tempDir = '.'
|
||||
|
||||
return tempDir
|
||||
|
||||
def vtkRegressionTestImage(renWin):
|
||||
"""vtkRegressionTestImage(renWin) -- produce regression image for window
|
||||
|
||||
This function writes out a regression .png file for a vtkWindow.
|
||||
Does anyone involved in testing care to elaborate?
|
||||
"""
|
||||
from vtkmodules.vtkRenderingCore import vtkWindowToImageFilter
|
||||
from vtkmodules.vtkIOImage import vtkPNGReader
|
||||
from vtkmodules.vtkImagingCore import vtkImageDifference
|
||||
|
||||
fname = None
|
||||
for i, argv in enumerate(sys.argv):
|
||||
if argv == '-V' and i+1 < len(sys.argv):
|
||||
fname = os.path.join(vtkGetDataRoot(), sys.argv[i+1])
|
||||
|
||||
if fname is None:
|
||||
return 2
|
||||
|
||||
else:
|
||||
rt_w2if = vtkWindowToImageFilter()
|
||||
rt_w2if.SetInput(renWin)
|
||||
|
||||
if not os.path.isfile(fname):
|
||||
rt_pngw = vtkPNGWriter()
|
||||
rt_pngw.SetFileName(fname)
|
||||
rt_pngw.SetInputConnection(rt_w2if.GetOutputPort())
|
||||
rt_pngw.Write()
|
||||
rt_pngw = None
|
||||
|
||||
rt_png = vtkPNGReader()
|
||||
rt_png.SetFileName(fname)
|
||||
|
||||
rt_id = vtkImageDifference()
|
||||
rt_id.SetInputConnection(rt_w2if.GetOutputPort())
|
||||
rt_id.SetImageConnection(rt_png.GetOutputPort())
|
||||
rt_id.Update()
|
||||
|
||||
if rt_id.GetThresholdedError() <= 10:
|
||||
return 1
|
||||
else:
|
||||
sys.stderr.write('Failed image test: %f\n'
|
||||
% rt_id.GetThresholdedError())
|
||||
return 0
|
||||
@@ -0,0 +1,252 @@
|
||||
"""This module adds support to easily import and export NumPy
|
||||
(http://numpy.scipy.org) arrays into/out of VTK arrays. The code is
|
||||
loosely based on TVTK (https://svn.enthought.com/enthought/wiki/TVTK).
|
||||
|
||||
This code depends on an addition to the VTK data arrays made by Berk
|
||||
Geveci to make it support Python's buffer protocol (on Feb. 15, 2008).
|
||||
|
||||
The main functionality of this module is provided by the two functions:
|
||||
numpy_to_vtk,
|
||||
vtk_to_numpy.
|
||||
|
||||
|
||||
Caveats:
|
||||
--------
|
||||
|
||||
- Bit arrays in general do not have a numpy equivalent and are not
|
||||
supported. Char arrays are also not easy to handle and might not
|
||||
work as you expect. Patches welcome.
|
||||
|
||||
- You need to make sure you hold a reference to a Numpy array you want
|
||||
to import into VTK. If not you'll get a segfault (in the best case).
|
||||
The same holds in reverse when you convert a VTK array to a numpy
|
||||
array -- don't delete the VTK array.
|
||||
|
||||
|
||||
Created by Prabhu Ramachandran in Feb. 2008.
|
||||
"""
|
||||
|
||||
from . import vtkConstants
|
||||
from vtkmodules.vtkCommonCore import vtkDataArray, vtkIdTypeArray, vtkLongArray
|
||||
import numpy
|
||||
|
||||
# Useful constants for VTK arrays.
|
||||
VTK_ID_TYPE_SIZE = vtkIdTypeArray().GetDataTypeSize()
|
||||
if VTK_ID_TYPE_SIZE == 4:
|
||||
ID_TYPE_CODE = numpy.int32
|
||||
elif VTK_ID_TYPE_SIZE == 8:
|
||||
ID_TYPE_CODE = numpy.int64
|
||||
|
||||
VTK_LONG_TYPE_SIZE = vtkLongArray().GetDataTypeSize()
|
||||
if VTK_LONG_TYPE_SIZE == 4:
|
||||
LONG_TYPE_CODE = numpy.int32
|
||||
ULONG_TYPE_CODE = numpy.uint32
|
||||
elif VTK_LONG_TYPE_SIZE == 8:
|
||||
LONG_TYPE_CODE = numpy.int64
|
||||
ULONG_TYPE_CODE = numpy.uint64
|
||||
|
||||
|
||||
def get_vtk_array_type(numpy_array_type):
|
||||
"""Returns a VTK typecode given a numpy array."""
|
||||
# This is a Mapping from numpy array types to VTK array types.
|
||||
_np_vtk = {numpy.uint8:vtkConstants.VTK_UNSIGNED_CHAR,
|
||||
numpy.uint16:vtkConstants.VTK_UNSIGNED_SHORT,
|
||||
numpy.uint32:vtkConstants.VTK_UNSIGNED_INT,
|
||||
numpy.uint64:vtkConstants.VTK_UNSIGNED_LONG_LONG,
|
||||
numpy.int8:vtkConstants.VTK_SIGNED_CHAR,
|
||||
numpy.int16:vtkConstants.VTK_SHORT,
|
||||
numpy.int32:vtkConstants.VTK_INT,
|
||||
numpy.int64:vtkConstants.VTK_LONG_LONG,
|
||||
numpy.float32:vtkConstants.VTK_FLOAT,
|
||||
numpy.float64:vtkConstants.VTK_DOUBLE,
|
||||
numpy.complex64:vtkConstants.VTK_FLOAT,
|
||||
numpy.complex128:vtkConstants.VTK_DOUBLE}
|
||||
for key, vtk_type in _np_vtk.items():
|
||||
if numpy_array_type == key or \
|
||||
numpy.issubdtype(numpy_array_type, key) or \
|
||||
numpy_array_type == numpy.dtype(key):
|
||||
return vtk_type
|
||||
raise TypeError(
|
||||
'Could not find a suitable VTK type for %s' % (str(numpy_array_type)))
|
||||
|
||||
def get_vtk_to_numpy_typemap():
|
||||
"""Returns the VTK array type to numpy array type mapping."""
|
||||
_vtk_np = {vtkConstants.VTK_BIT:numpy.uint8,
|
||||
vtkConstants.VTK_CHAR:numpy.int8,
|
||||
vtkConstants.VTK_SIGNED_CHAR:numpy.int8,
|
||||
vtkConstants.VTK_UNSIGNED_CHAR:numpy.uint8,
|
||||
vtkConstants.VTK_SHORT:numpy.int16,
|
||||
vtkConstants.VTK_UNSIGNED_SHORT:numpy.uint16,
|
||||
vtkConstants.VTK_INT:numpy.int32,
|
||||
vtkConstants.VTK_UNSIGNED_INT:numpy.uint32,
|
||||
vtkConstants.VTK_LONG:LONG_TYPE_CODE,
|
||||
vtkConstants.VTK_LONG_LONG:numpy.int64,
|
||||
vtkConstants.VTK_UNSIGNED_LONG:ULONG_TYPE_CODE,
|
||||
vtkConstants.VTK_UNSIGNED_LONG_LONG:numpy.uint64,
|
||||
vtkConstants.VTK_ID_TYPE:ID_TYPE_CODE,
|
||||
vtkConstants.VTK_FLOAT:numpy.float32,
|
||||
vtkConstants.VTK_DOUBLE:numpy.float64}
|
||||
return _vtk_np
|
||||
|
||||
|
||||
def get_numpy_array_type(vtk_array_type):
|
||||
"""Returns a numpy array typecode given a VTK array type."""
|
||||
return get_vtk_to_numpy_typemap()[vtk_array_type]
|
||||
|
||||
|
||||
def create_vtk_array(vtk_arr_type):
|
||||
"""Internal function used to create a VTK data array from another
|
||||
VTK array given the VTK array type.
|
||||
"""
|
||||
return vtkDataArray.CreateDataArray(vtk_arr_type)
|
||||
|
||||
|
||||
def numpy_to_vtk(num_array, deep=0, array_type=None):
|
||||
"""Converts a real numpy Array to a VTK array object.
|
||||
|
||||
This function only works for real arrays.
|
||||
Complex arrays are NOT handled. It also works for multi-component
|
||||
arrays. However, only 1, and 2 dimensional arrays are supported.
|
||||
This function is very efficient, so large arrays should not be a
|
||||
problem.
|
||||
|
||||
If the second argument is set to 1, the array is deep-copied from
|
||||
from numpy. This is not as efficient as the default behavior
|
||||
(shallow copy) and uses more memory but detaches the two arrays
|
||||
such that the numpy array can be released.
|
||||
|
||||
WARNING: You must maintain a reference to the passed numpy array, if
|
||||
the numpy data is gc'd and VTK will point to garbage which will in
|
||||
the best case give you a segfault.
|
||||
|
||||
Parameters:
|
||||
|
||||
num_array
|
||||
a 1D or 2D, real numpy array.
|
||||
|
||||
"""
|
||||
|
||||
z = numpy.asarray(num_array)
|
||||
if not z.flags.contiguous:
|
||||
z = numpy.ascontiguousarray(z)
|
||||
|
||||
shape = z.shape
|
||||
assert z.flags.contiguous, 'Only contiguous arrays are supported.'
|
||||
assert len(shape) < 3, \
|
||||
"Only arrays of dimensionality 2 or lower are allowed!"
|
||||
assert not numpy.issubdtype(z.dtype, numpy.dtype(complex).type), \
|
||||
"Complex numpy arrays cannot be converted to vtk arrays."\
|
||||
"Use real() or imag() to get a component of the array before"\
|
||||
" passing it to vtk."
|
||||
|
||||
# First create an array of the right type by using the typecode.
|
||||
if array_type:
|
||||
vtk_typecode = array_type
|
||||
else:
|
||||
vtk_typecode = get_vtk_array_type(z.dtype)
|
||||
result_array = create_vtk_array(vtk_typecode)
|
||||
|
||||
# Fixup shape in case its empty or scalar.
|
||||
try:
|
||||
testVar = shape[0]
|
||||
except:
|
||||
shape = (0,)
|
||||
|
||||
# Find the shape and set number of components.
|
||||
if len(shape) == 1:
|
||||
result_array.SetNumberOfComponents(1)
|
||||
else:
|
||||
result_array.SetNumberOfComponents(shape[1])
|
||||
|
||||
# We don't need to call result_array.SetNumberOfTuples(shape[0])
|
||||
# because we will use result_array.SetVoidPointer
|
||||
# which takes care of setting the NumberOfTuples
|
||||
# Calling SetNumberOfTuples will result in a memory allocation
|
||||
# that will be deleted on SetVoidPointer.
|
||||
|
||||
# Ravel the array appropriately.
|
||||
arr_dtype = get_numpy_array_type(vtk_typecode)
|
||||
if numpy.issubdtype(z.dtype, arr_dtype) or \
|
||||
z.dtype == numpy.dtype(arr_dtype):
|
||||
z_flat = numpy.ravel(z)
|
||||
else:
|
||||
z_flat = numpy.ravel(z).astype(arr_dtype)
|
||||
# z_flat is now a standalone object with no references from the caller.
|
||||
# As such, it will drop out of this scope and cause memory issues if we
|
||||
# do not deep copy its data.
|
||||
deep = 1
|
||||
|
||||
# Point the VTK array to the numpy data. The last argument (1)
|
||||
# tells the array not to deallocate.
|
||||
result_array.SetVoidArray(z_flat, len(z_flat), 1)
|
||||
if deep:
|
||||
copy = result_array.NewInstance()
|
||||
copy.DeepCopy(result_array)
|
||||
result_array = copy
|
||||
else:
|
||||
result_array._numpy_reference = z
|
||||
return result_array
|
||||
|
||||
def numpy_to_vtkIdTypeArray(num_array, deep=0):
|
||||
isize = vtkIdTypeArray().GetDataTypeSize()
|
||||
dtype = num_array.dtype
|
||||
if isize == 4:
|
||||
if dtype != numpy.int32:
|
||||
raise ValueError(
|
||||
'Expecting a numpy.int32 array, got %s instead.' % (str(dtype)))
|
||||
else:
|
||||
if dtype != numpy.int64:
|
||||
raise ValueError(
|
||||
'Expecting a numpy.int64 array, got %s instead.' % (str(dtype)))
|
||||
|
||||
return numpy_to_vtk(num_array, deep, vtkConstants.VTK_ID_TYPE)
|
||||
|
||||
def vtk_to_numpy(vtk_array):
|
||||
"""Converts a VTK data array to a numpy array.
|
||||
|
||||
Given a subclass of vtkDataArray, this function returns an
|
||||
appropriate numpy array containing the same data -- it actually
|
||||
points to the same data.
|
||||
|
||||
Parameters
|
||||
|
||||
vtk_array
|
||||
The VTK data array to be converted.
|
||||
|
||||
"""
|
||||
typ = vtk_array.GetDataType()
|
||||
assert typ in get_vtk_to_numpy_typemap().keys(), \
|
||||
"Unsupported array type %s"%typ
|
||||
|
||||
shape = vtk_array.GetNumberOfTuples(), \
|
||||
vtk_array.GetNumberOfComponents()
|
||||
|
||||
# Get the data via the buffer interface
|
||||
dtype = get_numpy_array_type(typ)
|
||||
try:
|
||||
if typ != vtkConstants.VTK_BIT:
|
||||
result = numpy.frombuffer(vtk_array, dtype=dtype)
|
||||
else:
|
||||
result = numpy.unpackbits(vtk_array, count=shape[0])
|
||||
except ValueError:
|
||||
# http://mail.scipy.org/pipermail/numpy-tickets/2011-August/005859.html
|
||||
# numpy 1.5.1 (and maybe earlier) has a bug where if frombuffer is
|
||||
# called with an empty buffer, it throws ValueError exception. This
|
||||
# handles that issue.
|
||||
if shape[0] == 0:
|
||||
# create an empty array with the given shape.
|
||||
result = numpy.empty(shape, dtype=dtype)
|
||||
else:
|
||||
raise
|
||||
if shape[1] == 1:
|
||||
shape = (shape[0], )
|
||||
try:
|
||||
result.shape = shape
|
||||
except ValueError:
|
||||
if shape[0] == 0:
|
||||
# Refer to https://github.com/numpy/numpy/issues/2536 .
|
||||
# For empty array, reshape fails. Create the empty array explicitly
|
||||
# if that happens.
|
||||
result = numpy.empty(shape, dtype=dtype)
|
||||
else: raise
|
||||
return result
|
||||
@@ -0,0 +1,108 @@
|
||||
"""This module generates support for pickling vtkDataObjects from python.
|
||||
It needs to be imported specifically in order to work:
|
||||
|
||||
>>> import vtkmodules.util.pickle_support
|
||||
|
||||
Once imported however, the pickling of data objects is very straightforward. Here is an
|
||||
example using poly data:
|
||||
|
||||
>>> sphereSrc = vtkSphereSource()
|
||||
>>> sphereSrc.Update()
|
||||
>>> pickled = pickle.dumps(sphereSrc.GetOutput())
|
||||
>>> unpickled = pickle.loads(pickled)
|
||||
>>> print(unpickled)
|
||||
*description of sphere data set*
|
||||
|
||||
The underlying serialization of the vtkDatObjects is based on the marshaling capabilities
|
||||
found in vtkCommunicator. Importing this module adds entries for the most common data
|
||||
objects in the global dispatch table used by pickle. NumPy is required as well since the
|
||||
-serialized data object gets pickled as a numpy array.
|
||||
"""
|
||||
|
||||
try:
|
||||
import copyreg, pickle, numpy
|
||||
except ImportError:
|
||||
raise ImportError("This module depends on the pickle, copyreg, and numpy modules.\
|
||||
Please make sure that it is installed properly.")
|
||||
|
||||
from ..vtkParallelCore import vtkCommunicator
|
||||
from ..vtkCommonCore import vtkCharArray
|
||||
from .. import vtkCommonDataModel
|
||||
|
||||
def unserialize_VTK_data_object(state):
|
||||
"""Takes a state dictionary with entries:
|
||||
- Type : a string with the class name for the data object
|
||||
- Serialized : a numpy array with the serialized data object
|
||||
|
||||
and transforms it into a data object.
|
||||
"""
|
||||
|
||||
if ("Type" not in state.keys()) or ("Serialized" not in state.keys()):
|
||||
raise RuntimeError("State dictionary passed to unpickle does not have Type and/or\
|
||||
Serialized keys.")
|
||||
|
||||
new_data_object = None
|
||||
DataSetClass = None
|
||||
try:
|
||||
DataSetClass = getattr(vtkCommonDataModel, state["Type"])
|
||||
except:
|
||||
raise TypeError("Could not find type " + type_string + " in vtkCommonDataModel module")
|
||||
serialized_data = state["Serialized"]
|
||||
new_data_object = DataSetClass()
|
||||
char_array = vtkCharArray()
|
||||
char_array.SetVoidArray(serialized_data, memoryview(serialized_data).nbytes, 1)
|
||||
if vtkCommunicator.UnMarshalDataObject(char_array, new_data_object) == 0:
|
||||
raise RuntimeError("Marshaling data object failed")
|
||||
return new_data_object
|
||||
|
||||
def serialize_VTK_data_object(data_object):
|
||||
"""Returns a tuple with a reference to the unpickling function and a state dictionary
|
||||
with entries:
|
||||
- Type : a string with the class name for the data object
|
||||
- Serialized : a numpy array with the serialized data object
|
||||
|
||||
This is exactly the state dictionary that unserialize_VTK_data_object expects.
|
||||
"""
|
||||
|
||||
if not data_object.IsA("vtkDataObject"):
|
||||
raise TypeError("Object passed to pickling should be a vtkDataObject")
|
||||
data_object_type = data_object.GetClassName()
|
||||
char_array = vtkCharArray()
|
||||
if vtkCommunicator.MarshalDataObject(data_object, char_array) == 0:
|
||||
raise RuntimeError("UnMarshaling data object failed")
|
||||
return unserialize_VTK_data_object, (
|
||||
{ "Type" : data_object_type,
|
||||
"Serialized" : numpy.frombuffer(char_array, numpy.int8, char_array.GetNumberOfValues()) },)
|
||||
|
||||
|
||||
# Fill in global dispatch table for most vtkDataObject types
|
||||
copyreg.pickle(vtkCommonDataModel.vtkDataSet, serialize_VTK_data_object)
|
||||
|
||||
copyreg.pickle(vtkCommonDataModel.vtkPolyData, serialize_VTK_data_object)
|
||||
copyreg.pickle(vtkCommonDataModel.vtkUnstructuredGrid, serialize_VTK_data_object)
|
||||
|
||||
copyreg.pickle(vtkCommonDataModel.vtkImageData, serialize_VTK_data_object)
|
||||
copyreg.pickle(vtkCommonDataModel.vtkRectilinearGrid, serialize_VTK_data_object)
|
||||
copyreg.pickle(vtkCommonDataModel.vtkStructuredGrid, serialize_VTK_data_object)
|
||||
copyreg.pickle(vtkCommonDataModel.vtkExplicitStructuredGrid, serialize_VTK_data_object)
|
||||
copyreg.pickle(vtkCommonDataModel.vtkStructuredPoints, serialize_VTK_data_object)
|
||||
|
||||
copyreg.pickle(vtkCommonDataModel.vtkUniformGridAMR, serialize_VTK_data_object)
|
||||
copyreg.pickle(vtkCommonDataModel.vtkOverlappingAMR, serialize_VTK_data_object)
|
||||
copyreg.pickle(vtkCommonDataModel.vtkHierarchicalBoxDataSet, serialize_VTK_data_object) # VTK_DEPRECATED_IN_9_5_0
|
||||
copyreg.pickle(vtkCommonDataModel.vtkNonOverlappingAMR, serialize_VTK_data_object)
|
||||
|
||||
copyreg.pickle(vtkCommonDataModel.vtkTable, serialize_VTK_data_object)
|
||||
|
||||
copyreg.pickle(vtkCommonDataModel.vtkTree, serialize_VTK_data_object)
|
||||
|
||||
copyreg.pickle(vtkCommonDataModel.vtkCompositeDataSet, serialize_VTK_data_object)
|
||||
copyreg.pickle(vtkCommonDataModel.vtkDataObjectTree, serialize_VTK_data_object)
|
||||
copyreg.pickle(vtkCommonDataModel.vtkMultiBlockDataSet, serialize_VTK_data_object)
|
||||
copyreg.pickle(vtkCommonDataModel.vtkPartitionedDataSet, serialize_VTK_data_object)
|
||||
copyreg.pickle(vtkCommonDataModel.vtkPartitionedDataSetCollection, serialize_VTK_data_object)
|
||||
copyreg.pickle(vtkCommonDataModel.vtkMultiPieceDataSet, serialize_VTK_data_object)
|
||||
|
||||
copyreg.pickle(vtkCommonDataModel.vtkDirectedGraph, serialize_VTK_data_object)
|
||||
copyreg.pickle(vtkCommonDataModel.vtkUndirectedGraph, serialize_VTK_data_object)
|
||||
copyreg.pickle(vtkCommonDataModel.vtkMolecule, serialize_VTK_data_object)
|
||||
@@ -0,0 +1,220 @@
|
||||
from vtkmodules.vtkCommonCore import vtkInformation
|
||||
from vtkmodules.vtkCommonDataModel import vtkDataObject
|
||||
from vtkmodules.vtkCommonExecutionModel import vtkAlgorithm
|
||||
from vtkmodules.vtkCommonExecutionModel import vtkDemandDrivenPipeline
|
||||
from vtkmodules.vtkCommonExecutionModel import vtkStreamingDemandDrivenPipeline
|
||||
from vtkmodules.vtkFiltersPython import vtkPythonAlgorithm
|
||||
|
||||
class VTKAlgorithm(object):
|
||||
"""This is a superclass which can be derived to implement
|
||||
Python classes that work with vtkPythonAlgorithm. It implements
|
||||
Initialize(), ProcessRequest(), FillInputPortInformation() and
|
||||
FillOutputPortInformation().
|
||||
|
||||
Initialize() sets the input and output ports based on data
|
||||
members.
|
||||
|
||||
ProcessRequest() calls RequestXXX() methods to implement
|
||||
various pipeline passes.
|
||||
|
||||
FillInputPortInformation() and FillOutputPortInformation() set
|
||||
the input and output types based on data members.
|
||||
"""
|
||||
|
||||
def __init__(self, nInputPorts=1, inputType='vtkDataSet',
|
||||
nOutputPorts=1, outputType='vtkPolyData'):
|
||||
"""Sets up default NumberOfInputPorts, NumberOfOutputPorts,
|
||||
InputType and OutputType that are used by various initialization
|
||||
methods."""
|
||||
|
||||
self.NumberOfInputPorts = nInputPorts
|
||||
self.NumberOfOutputPorts = nOutputPorts
|
||||
self.InputType = inputType
|
||||
self.OutputType = outputType
|
||||
|
||||
def Initialize(self, vtkself):
|
||||
"""Sets up number of input and output ports based on
|
||||
NumberOfInputPorts and NumberOfOutputPorts."""
|
||||
|
||||
vtkself.SetNumberOfInputPorts(self.NumberOfInputPorts)
|
||||
vtkself.SetNumberOfOutputPorts(self.NumberOfOutputPorts)
|
||||
|
||||
def GetInputData(self, inInfo, i, j):
|
||||
"""Convenience method that returns an input data object
|
||||
given a vector of information objects and two indices."""
|
||||
|
||||
return inInfo[i].GetInformationObject(j).Get(vtkDataObject.DATA_OBJECT())
|
||||
|
||||
def GetOutputData(self, outInfo, i):
|
||||
"""Convenience method that returns an output data object
|
||||
given an information object and an index."""
|
||||
return outInfo.GetInformationObject(i).Get(vtkDataObject.DATA_OBJECT())
|
||||
|
||||
def RequestDataObject(self, vtkself, request, inInfo, outInfo):
|
||||
"""Overwritten by subclass to manage data object creation.
|
||||
There is not need to overwrite this class if the output can
|
||||
be created based on the OutputType data member."""
|
||||
return 1
|
||||
|
||||
def RequestInformation(self, vtkself, request, inInfo, outInfo):
|
||||
"""Overwritten by subclass to provide meta-data to downstream
|
||||
pipeline."""
|
||||
return 1
|
||||
|
||||
def RequestUpdateExtent(self, vtkself, request, inInfo, outInfo):
|
||||
"""Overwritten by subclass to modify data request going
|
||||
to upstream pipeline."""
|
||||
return 1
|
||||
|
||||
def RequestData(self, vtkself, request, inInfo, outInfo):
|
||||
"""Overwritten by subclass to execute the algorithm."""
|
||||
raise NotImplementedError('RequestData must be implemented')
|
||||
|
||||
def ProcessRequest(self, vtkself, request, inInfo, outInfo):
|
||||
"""Splits a request to RequestXXX() methods."""
|
||||
if request.Has(vtkDemandDrivenPipeline.REQUEST_DATA_OBJECT()):
|
||||
return self.RequestDataObject(vtkself, request, inInfo, outInfo)
|
||||
elif request.Has(vtkDemandDrivenPipeline.REQUEST_INFORMATION()):
|
||||
return self.RequestInformation(vtkself, request, inInfo, outInfo)
|
||||
elif request.Has(vtkStreamingDemandDrivenPipeline.REQUEST_UPDATE_EXTENT()):
|
||||
return self.RequestUpdateExtent(vtkself, request, inInfo, outInfo)
|
||||
elif request.Has(vtkDemandDrivenPipeline.REQUEST_DATA()):
|
||||
return self.RequestData(vtkself, request, inInfo, outInfo)
|
||||
|
||||
return 1
|
||||
|
||||
def FillInputPortInformation(self, vtkself, port, info):
|
||||
"""Sets the required input type to InputType."""
|
||||
info.Set(vtkAlgorithm.INPUT_REQUIRED_DATA_TYPE(), self.InputType)
|
||||
return 1
|
||||
|
||||
def FillOutputPortInformation(self, vtkself, port, info):
|
||||
"""Sets the default output type to OutputType."""
|
||||
info.Set(vtkDataObject.DATA_TYPE_NAME(), self.OutputType)
|
||||
return 1
|
||||
|
||||
class VTKPythonAlgorithmBase(vtkPythonAlgorithm):
|
||||
"""This is a superclass which can be derived to implement
|
||||
Python classes that act as VTK algorithms in a VTK pipeline.
|
||||
It implements ProcessRequest(), FillInputPortInformation() and
|
||||
FillOutputPortInformation().
|
||||
|
||||
ProcessRequest() calls RequestXXX() methods to implement
|
||||
various pipeline passes.
|
||||
|
||||
FillInputPortInformation() and FillOutputPortInformation() set
|
||||
the input and output types based on data members.
|
||||
|
||||
Common use is something like this:
|
||||
|
||||
class HDF5Source(VTKPythonAlgorithmBase):
|
||||
def __init__(self):
|
||||
VTKPythonAlgorithmBase.__init__(self,
|
||||
nInputPorts=0,
|
||||
nOutputPorts=1, outputType='vtkImageData')
|
||||
|
||||
def RequestInformation(self, request, inInfo, outInfo):
|
||||
f = h5py.File("foo.h5", 'r')
|
||||
dims = f['RTData'].shape[::-1]
|
||||
info = outInfo.GetInformationObject(0)
|
||||
info.Set(vtkmodules.vtkCommonExecutionModel.vtkStreamingDemandDrivenPipeline.WHOLE_EXTENT(),
|
||||
(0, dims[0]-1, 0, dims[1]-1, 0, dims[2]-1), 6)
|
||||
return 1
|
||||
|
||||
def RequestData(self, request, inInfo, outInfo):
|
||||
f = h5py.File("foo.h5", 'r')
|
||||
data = f['RTData'][:]
|
||||
output = dsa.WrapDataObject(vtkmodules.vtkCommonDataModel.vtkImageData.GetData(outInfo))
|
||||
output.SetDimensions(data.shape)
|
||||
output.PointData.append(data.flatten(), 'RTData')
|
||||
output.PointData.SetActiveScalars('RTData')
|
||||
return 1
|
||||
|
||||
alg = HDF5Source()
|
||||
|
||||
cf = vtkmodules.vtkFiltersCore.vtkContourFilter()
|
||||
cf.SetInputConnection(alg.GetOutputPort())
|
||||
cf.Update()
|
||||
"""
|
||||
|
||||
class InternalAlgorithm(object):
|
||||
"Internal class. Do not use."
|
||||
def Initialize(self, vtkself):
|
||||
pass
|
||||
|
||||
def FillInputPortInformation(self, vtkself, port, info):
|
||||
return vtkself.FillInputPortInformation(port, info)
|
||||
|
||||
def FillOutputPortInformation(self, vtkself, port, info):
|
||||
return vtkself.FillOutputPortInformation(port, info)
|
||||
|
||||
def ProcessRequest(self, vtkself, request, inInfo, outInfo):
|
||||
return vtkself.ProcessRequest(request, inInfo, outInfo)
|
||||
|
||||
def __init__(self, nInputPorts=1, inputType='vtkDataSet',
|
||||
nOutputPorts=1, outputType='vtkPolyData'):
|
||||
"""Sets up default NumberOfInputPorts, NumberOfOutputPorts,
|
||||
InputType and OutputType that are used by various methods.
|
||||
Make sure to call this method from any subclass' __init__"""
|
||||
|
||||
self.SetPythonObject(VTKPythonAlgorithmBase.InternalAlgorithm())
|
||||
|
||||
self.SetNumberOfInputPorts(nInputPorts)
|
||||
self.SetNumberOfOutputPorts(nOutputPorts)
|
||||
|
||||
self.InputType = inputType
|
||||
self.OutputType = outputType
|
||||
|
||||
def GetInputData(self, inInfo, i, j):
|
||||
"""Convenience method that returns an input data object
|
||||
given a vector of information objects and two indices."""
|
||||
|
||||
return inInfo[i].GetInformationObject(j).Get(vtkDataObject.DATA_OBJECT())
|
||||
|
||||
def GetOutputData(self, outInfo, i):
|
||||
"""Convenience method that returns an output data object
|
||||
given an information object and an index."""
|
||||
return outInfo.GetInformationObject(i).Get(vtkDataObject.DATA_OBJECT())
|
||||
|
||||
def FillInputPortInformation(self, port, info):
|
||||
"""Sets the required input type to InputType."""
|
||||
info.Set(vtkAlgorithm.INPUT_REQUIRED_DATA_TYPE(), self.InputType)
|
||||
return 1
|
||||
|
||||
def FillOutputPortInformation(self, port, info):
|
||||
"""Sets the default output type to OutputType."""
|
||||
info.Set(vtkDataObject.DATA_TYPE_NAME(), self.OutputType)
|
||||
return 1
|
||||
|
||||
def ProcessRequest(self, request, inInfo, outInfo):
|
||||
"""Splits a request to RequestXXX() methods."""
|
||||
if request.Has(vtkDemandDrivenPipeline.REQUEST_DATA_OBJECT()):
|
||||
return self.RequestDataObject(request, inInfo, outInfo)
|
||||
elif request.Has(vtkDemandDrivenPipeline.REQUEST_INFORMATION()):
|
||||
return self.RequestInformation(request, inInfo, outInfo)
|
||||
elif request.Has(vtkStreamingDemandDrivenPipeline.REQUEST_UPDATE_EXTENT()):
|
||||
return self.RequestUpdateExtent(request, inInfo, outInfo)
|
||||
elif request.Has(vtkDemandDrivenPipeline.REQUEST_DATA()):
|
||||
return self.RequestData(request, inInfo, outInfo)
|
||||
|
||||
return 1
|
||||
|
||||
def RequestDataObject(self, request, inInfo, outInfo):
|
||||
"""Overwritten by subclass to manage data object creation.
|
||||
There is not need to overwrite this class if the output can
|
||||
be created based on the OutputType data member."""
|
||||
return 1
|
||||
|
||||
def RequestInformation(self, request, inInfo, outInfo):
|
||||
"""Overwritten by subclass to provide meta-data to downstream
|
||||
pipeline."""
|
||||
return 1
|
||||
|
||||
def RequestUpdateExtent(self, request, inInfo, outInfo):
|
||||
"""Overwritten by subclass to modify data request going
|
||||
to upstream pipeline."""
|
||||
return 1
|
||||
|
||||
def RequestData(self, request, inInfo, outInfo):
|
||||
"""Overwritten by subclass to execute the algorithm."""
|
||||
raise NotImplementedError('RequestData must be implemented')
|
||||
@@ -0,0 +1,201 @@
|
||||
"""
|
||||
This file is obsolete.
|
||||
All the constants are part of the base vtk module.
|
||||
"""
|
||||
|
||||
# Some constants used throughout code
|
||||
|
||||
_VTK_FLOAT_MAX = 1.0e+38
|
||||
_VTK_INT_MAX = 2147483647 # 2^31 - 1
|
||||
|
||||
# These types are returned by GetDataType to indicate pixel type.
|
||||
VTK_VOID = 0
|
||||
VTK_BIT = 1
|
||||
VTK_CHAR = 2
|
||||
VTK_SIGNED_CHAR =15
|
||||
VTK_UNSIGNED_CHAR = 3
|
||||
VTK_SHORT = 4
|
||||
VTK_UNSIGNED_SHORT = 5
|
||||
VTK_INT = 6
|
||||
VTK_UNSIGNED_INT = 7
|
||||
VTK_LONG = 8
|
||||
VTK_UNSIGNED_LONG = 9
|
||||
VTK_FLOAT =10
|
||||
VTK_DOUBLE =11
|
||||
VTK_ID_TYPE =12
|
||||
|
||||
# These types are not currently supported by GetDataType, but are
|
||||
# for completeness.
|
||||
VTK_STRING =13
|
||||
VTK_OPAQUE =14
|
||||
|
||||
VTK_LONG_LONG =16
|
||||
VTK_UNSIGNED_LONG_LONG =17
|
||||
|
||||
# These types are required by vtkVariant and vtkVariantArray
|
||||
VTK_VARIANT =20
|
||||
VTK_OBJECT =21
|
||||
|
||||
# Some constant required for correct template performance
|
||||
VTK_BIT_MIN = 0
|
||||
VTK_BIT_MAX = 1
|
||||
VTK_CHAR_MIN = -128
|
||||
VTK_CHAR_MAX = 127
|
||||
VTK_UNSIGNED_CHAR_MIN = 0
|
||||
VTK_UNSIGNED_CHAR_MAX = 255
|
||||
VTK_SHORT_MIN = -32768
|
||||
VTK_SHORT_MAX = 32767
|
||||
VTK_UNSIGNED_SHORT_MIN = 0
|
||||
VTK_UNSIGNED_SHORT_MAX = 65535
|
||||
VTK_INT_MIN = (-_VTK_INT_MAX-1)
|
||||
VTK_INT_MAX = _VTK_INT_MAX
|
||||
#VTK_UNSIGNED_INT_MIN = 0
|
||||
#VTK_UNSIGNED_INT_MAX = 4294967295
|
||||
VTK_LONG_MIN = (-VTK_INT_MAX-1)
|
||||
VTK_LONG_MAX = VTK_INT_MAX
|
||||
#VTK_UNSIGNED_LONG_MIN = 0
|
||||
#VTK_UNSIGNED_LONG_MAX = 4294967295
|
||||
VTK_FLOAT_MIN = -_VTK_FLOAT_MAX
|
||||
VTK_FLOAT_MAX = _VTK_FLOAT_MAX
|
||||
VTK_DOUBLE_MIN = -1.0e+99
|
||||
VTK_DOUBLE_MAX = 1.0e+99
|
||||
|
||||
# These types are returned to distinguish dataset types
|
||||
VTK_POLY_DATA = 0
|
||||
VTK_STRUCTURED_POINTS = 1
|
||||
VTK_STRUCTURED_GRID = 2
|
||||
VTK_RECTILINEAR_GRID = 3
|
||||
VTK_UNSTRUCTURED_GRID = 4
|
||||
VTK_PIECEWISE_FUNCTION = 5
|
||||
VTK_IMAGE_DATA = 6
|
||||
VTK_DATA_OBJECT = 7
|
||||
VTK_DATA_SET = 8
|
||||
VTK_POINT_SET = 9
|
||||
VTK_UNIFORM_GRID = 10
|
||||
VTK_COMPOSITE_DATA_SET = 11
|
||||
VTK_MULTIGROUP_DATA_SET = 12 # OBSOLETE VTK_DEPRECATED_IN_9_5_0
|
||||
VTK_MULTIBLOCK_DATA_SET = 13
|
||||
VTK_HIERARCHICAL_DATA_SET = 14 # OBSOLETE VTK_DEPRECATED_IN_9_5_0
|
||||
VTK_HIERARCHICAL_BOX_DATA_SET = 15 # OBSOLETE VTK_DEPRECATED_IN_9_5_0
|
||||
VTK_GENERIC_DATA_SET = 16
|
||||
VTK_HYPER_OCTREE = 17 # OBSOLETE VTK_DEPRECATED_IN_9_5_0
|
||||
VTK_TEMPORAL_DATA_SET = 18 # OBSOLETE VTK_DEPRECATED_IN_9_5_0
|
||||
VTK_TABLE = 19
|
||||
VTK_GRAPH = 20
|
||||
VTK_TREE = 21
|
||||
VTK_SELECTION = 22
|
||||
|
||||
# These types define error codes for vtk functions
|
||||
VTK_OK = 1
|
||||
VTK_ERROR = 2
|
||||
|
||||
# These types define different text properties
|
||||
VTK_ARIAL = 0
|
||||
VTK_COURIER = 1
|
||||
VTK_TIMES = 2
|
||||
VTK_UNKNOWN_FONT = 3
|
||||
|
||||
VTK_TEXT_LEFT = 0
|
||||
VTK_TEXT_CENTERED = 1
|
||||
VTK_TEXT_RIGHT = 2
|
||||
|
||||
VTK_TEXT_BOTTOM = 0
|
||||
VTK_TEXT_TOP = 2
|
||||
|
||||
VTK_TEXT_GLOBAL_ANTIALIASING_SOME = 0
|
||||
VTK_TEXT_GLOBAL_ANTIALIASING_NONE = 1
|
||||
VTK_TEXT_GLOBAL_ANTIALIASING_ALL = 2
|
||||
|
||||
VTK_LUMINANCE = 1
|
||||
VTK_LUMINANCE_ALPHA = 2
|
||||
VTK_RGB = 3
|
||||
VTK_RGBA = 4
|
||||
|
||||
VTK_COLOR_MODE_DEFAULT = 0
|
||||
VTK_COLOR_MODE_MAP_SCALARS = 1
|
||||
|
||||
# Constants for InterpolationType
|
||||
VTK_NEAREST_INTERPOLATION = 0
|
||||
VTK_LINEAR_INTERPOLATION = 1
|
||||
|
||||
# For volume rendering
|
||||
VTK_MAX_VRCOMP = 4
|
||||
|
||||
# These types define the 17 linear VTK Cell Types
|
||||
# See Filtering/vtkCellType.h
|
||||
|
||||
# Linear cells
|
||||
VTK_EMPTY_CELL = 0
|
||||
VTK_VERTEX = 1
|
||||
VTK_POLY_VERTEX = 2
|
||||
VTK_LINE = 3
|
||||
VTK_POLY_LINE = 4
|
||||
VTK_TRIANGLE = 5
|
||||
VTK_TRIANGLE_STRIP = 6
|
||||
VTK_POLYGON = 7
|
||||
VTK_PIXEL = 8
|
||||
VTK_QUAD = 9
|
||||
VTK_TETRA = 10
|
||||
VTK_VOXEL = 11
|
||||
VTK_HEXAHEDRON = 12
|
||||
VTK_WEDGE = 13
|
||||
VTK_PYRAMID = 14
|
||||
VTK_PENTAGONAL_PRISM = 15
|
||||
VTK_HEXAGONAL_PRISM = 16
|
||||
|
||||
# Quadratic, isoparametric cells
|
||||
VTK_QUADRATIC_EDGE = 21
|
||||
VTK_QUADRATIC_TRIANGLE = 22
|
||||
VTK_QUADRATIC_QUAD = 23
|
||||
VTK_QUADRATIC_TETRA = 24
|
||||
VTK_QUADRATIC_HEXAHEDRON = 25
|
||||
VTK_QUADRATIC_WEDGE = 26
|
||||
VTK_QUADRATIC_PYRAMID = 27
|
||||
VTK_BIQUADRATIC_QUAD = 28
|
||||
VTK_TRIQUADRATIC_HEXAHEDRON = 29
|
||||
VTK_QUADRATIC_LINEAR_QUAD = 30
|
||||
VTK_QUADRATIC_LINEAR_WEDGE = 31
|
||||
VTK_BIQUADRATIC_QUADRATIC_WEDGE = 32
|
||||
VTK_BIQUADRATIC_QUADRATIC_HEXAHEDRON = 33
|
||||
|
||||
# Special class of cells formed by convex group of points
|
||||
VTK_CONVEX_POINT_SET = 41
|
||||
|
||||
# Higher order cells in parametric form
|
||||
VTK_PARAMETRIC_CURVE = 51
|
||||
VTK_PARAMETRIC_SURFACE = 52
|
||||
VTK_PARAMETRIC_TRI_SURFACE = 53
|
||||
VTK_PARAMETRIC_QUAD_SURFACE = 54
|
||||
VTK_PARAMETRIC_TETRA_REGION = 55
|
||||
VTK_PARAMETRIC_HEX_REGION = 56
|
||||
|
||||
# Higher order cells
|
||||
VTK_HIGHER_ORDER_EDGE = 60
|
||||
VTK_HIGHER_ORDER_TRIANGLE = 61
|
||||
VTK_HIGHER_ORDER_QUAD = 62
|
||||
VTK_HIGHER_ORDER_POLYGON = 63
|
||||
VTK_HIGHER_ORDER_TETRAHEDRON = 64
|
||||
VTK_HIGHER_ORDER_WEDGE = 65
|
||||
VTK_HIGHER_ORDER_PYRAMID = 66
|
||||
VTK_HIGHER_ORDER_HEXAHEDRON = 67
|
||||
|
||||
# A macro to get the name of a type
|
||||
__vtkTypeNameDict = {VTK_VOID:"void",
|
||||
VTK_DOUBLE:"double",
|
||||
VTK_FLOAT:"float",
|
||||
VTK_LONG:"long",
|
||||
VTK_UNSIGNED_LONG:"unsigned long",
|
||||
VTK_INT:"int",
|
||||
VTK_UNSIGNED_INT:"unsigned int",
|
||||
VTK_SHORT:"short",
|
||||
VTK_UNSIGNED_SHORT:"unsigned short",
|
||||
VTK_CHAR:"char",
|
||||
VTK_UNSIGNED_CHAR:"unsigned char",
|
||||
VTK_SIGNED_CHAR:"signed char",
|
||||
VTK_LONG_LONG:"long long",
|
||||
VTK_UNSIGNED_LONG_LONG:"unsigned long long",
|
||||
VTK_ID_TYPE:"vtkIdType",
|
||||
VTK_BIT:"bit"}
|
||||
|
||||
def vtkImageScalarTypeNameMacro(type):
|
||||
return __vtkTypeNameDict[type]
|
||||
@@ -0,0 +1,116 @@
|
||||
"""
|
||||
vtkImageExportToArray - a NumPy front-end to vtkImageExport
|
||||
|
||||
This class converts a VTK image to a numpy array. The output
|
||||
array will always have 3 dimensions (or 4, if the image had
|
||||
multiple scalar components).
|
||||
|
||||
To use this class, you must have numpy installed (http://numpy.scipy.org)
|
||||
|
||||
Methods
|
||||
|
||||
SetInputConnection(vtkAlgorithmOutput) -- connect to VTK image pipeline
|
||||
SetInputData(vtkImageData) -- set an vtkImageData to export
|
||||
GetArray() -- execute pipeline and return a numpy array
|
||||
|
||||
Methods from vtkImageExport
|
||||
|
||||
GetDataExtent()
|
||||
GetDataSpacing()
|
||||
GetDataOrigin()
|
||||
"""
|
||||
|
||||
import numpy
|
||||
import numpy.core.umath as umath
|
||||
|
||||
from vtkmodules.vtkIOImage import vtkImageExport
|
||||
from vtkmodules.vtkCommonExecutionModel import vtkStreamingDemandDrivenPipeline
|
||||
from vtkmodules.vtkCommonCore import VTK_SIGNED_CHAR
|
||||
from vtkmodules.vtkCommonCore import VTK_UNSIGNED_CHAR
|
||||
from vtkmodules.vtkCommonCore import VTK_SHORT
|
||||
from vtkmodules.vtkCommonCore import VTK_UNSIGNED_SHORT
|
||||
from vtkmodules.vtkCommonCore import VTK_INT
|
||||
from vtkmodules.vtkCommonCore import VTK_UNSIGNED_INT
|
||||
from vtkmodules.vtkCommonCore import VTK_LONG
|
||||
from vtkmodules.vtkCommonCore import VTK_UNSIGNED_LONG
|
||||
from vtkmodules.vtkCommonCore import VTK_FLOAT
|
||||
from vtkmodules.vtkCommonCore import VTK_DOUBLE
|
||||
|
||||
|
||||
class vtkImageExportToArray:
|
||||
def __init__(self):
|
||||
self.__export = vtkImageExport()
|
||||
self.__ConvertUnsignedShortToInt = False
|
||||
|
||||
# type dictionary
|
||||
|
||||
__typeDict = { VTK_SIGNED_CHAR:'b',
|
||||
VTK_UNSIGNED_CHAR:'B',
|
||||
VTK_SHORT:'h',
|
||||
VTK_UNSIGNED_SHORT:'H',
|
||||
VTK_INT:'i',
|
||||
VTK_UNSIGNED_INT:'I',
|
||||
VTK_FLOAT:'f',
|
||||
VTK_DOUBLE:'d'}
|
||||
|
||||
__sizeDict = { VTK_SIGNED_CHAR:1,
|
||||
VTK_UNSIGNED_CHAR:1,
|
||||
VTK_SHORT:2,
|
||||
VTK_UNSIGNED_SHORT:2,
|
||||
VTK_INT:4,
|
||||
VTK_UNSIGNED_INT:4,
|
||||
VTK_FLOAT:4,
|
||||
VTK_DOUBLE:8 }
|
||||
|
||||
# convert unsigned shorts to ints, to avoid sign problems
|
||||
def SetConvertUnsignedShortToInt(self,yesno):
|
||||
self.__ConvertUnsignedShortToInt = yesno
|
||||
|
||||
def GetConvertUnsignedShortToInt(self):
|
||||
return self.__ConvertUnsignedShortToInt
|
||||
|
||||
def ConvertUnsignedShortToIntOn(self):
|
||||
self.__ConvertUnsignedShortToInt = True
|
||||
|
||||
def ConvertUnsignedShortToIntOff(self):
|
||||
self.__ConvertUnsignedShortToInt = False
|
||||
|
||||
# set the input
|
||||
def SetInputConnection(self,input):
|
||||
return self.__export.SetInputConnection(input)
|
||||
|
||||
def SetInputData(self,input):
|
||||
return self.__export.SetInputData(input)
|
||||
|
||||
def GetInput(self):
|
||||
return self.__export.GetInput()
|
||||
|
||||
def GetArray(self):
|
||||
self.__export.Update()
|
||||
input = self.__export.GetInput()
|
||||
extent = input.GetExtent()
|
||||
type = input.GetScalarType()
|
||||
numComponents = input.GetNumberOfScalarComponents()
|
||||
dim = (extent[5]-extent[4]+1,
|
||||
extent[3]-extent[2]+1,
|
||||
extent[1]-extent[0]+1)
|
||||
if (numComponents > 1):
|
||||
dim = dim + (numComponents,)
|
||||
|
||||
imArray = numpy.zeros(dim, self.__typeDict[type])
|
||||
self.__export.Export(imArray)
|
||||
|
||||
# convert unsigned short to int to avoid sign issues
|
||||
if (type == VTK_UNSIGNED_SHORT and self.__ConvertUnsignedShortToInt):
|
||||
imArray = umath.bitwise_and(imArray.astype('i'),0xffff)
|
||||
|
||||
return imArray
|
||||
|
||||
def GetDataExtent(self):
|
||||
return self.__export.GetDataExtent()
|
||||
|
||||
def GetDataSpacing(self):
|
||||
return self.__export.GetDataSpacing()
|
||||
|
||||
def GetDataOrigin(self):
|
||||
return self.__export.GetDataOrigin()
|
||||
@@ -0,0 +1,148 @@
|
||||
"""
|
||||
vtkImageImportFromArray: a NumPy front-end to vtkImageImport
|
||||
|
||||
Load a python array into a vtk image.
|
||||
To use this class, you must have NumPy installed (http://numpy.scipy.org/)
|
||||
|
||||
Methods:
|
||||
|
||||
SetArray() -- set the numpy array to load
|
||||
Update() -- generate the output
|
||||
GetOutput() -- get the image as vtkImageData
|
||||
GetOutputPort() -- connect to VTK pipeline
|
||||
|
||||
Methods from vtkImageImport:
|
||||
(if you don't set these, sensible defaults will be used)
|
||||
|
||||
SetDataExtent()
|
||||
SetDataSpacing()
|
||||
SetDataOrigin()
|
||||
"""
|
||||
|
||||
from vtkmodules.vtkIOImage import vtkImageImport
|
||||
from vtkmodules.vtkCommonCore import VTK_SIGNED_CHAR
|
||||
from vtkmodules.vtkCommonCore import VTK_UNSIGNED_CHAR
|
||||
from vtkmodules.vtkCommonCore import VTK_SHORT
|
||||
from vtkmodules.vtkCommonCore import VTK_UNSIGNED_SHORT
|
||||
from vtkmodules.vtkCommonCore import VTK_INT
|
||||
from vtkmodules.vtkCommonCore import VTK_UNSIGNED_INT
|
||||
from vtkmodules.vtkCommonCore import VTK_LONG
|
||||
from vtkmodules.vtkCommonCore import VTK_UNSIGNED_LONG
|
||||
from vtkmodules.vtkCommonCore import VTK_FLOAT
|
||||
from vtkmodules.vtkCommonCore import VTK_DOUBLE
|
||||
|
||||
class vtkImageImportFromArray:
|
||||
def __init__(self):
|
||||
self.__import = vtkImageImport()
|
||||
self.__ConvertIntToUnsignedShort = False
|
||||
self.__Array = None
|
||||
|
||||
# type dictionary: note that python doesn't support
|
||||
# unsigned integers properly!
|
||||
__typeDict = {'b':VTK_SIGNED_CHAR, # int8
|
||||
'B':VTK_UNSIGNED_CHAR, # uint8
|
||||
'h':VTK_SHORT, # int16
|
||||
'H':VTK_UNSIGNED_SHORT, # uint16
|
||||
'i':VTK_INT, # int32
|
||||
'I':VTK_UNSIGNED_INT, # uint32
|
||||
'f':VTK_FLOAT, # float32
|
||||
'd':VTK_DOUBLE, # float64
|
||||
'F':VTK_FLOAT, # float32
|
||||
'D':VTK_DOUBLE, # float64
|
||||
}
|
||||
|
||||
__sizeDict = { VTK_SIGNED_CHAR:1,
|
||||
VTK_UNSIGNED_CHAR:1,
|
||||
VTK_SHORT:2,
|
||||
VTK_UNSIGNED_SHORT:2,
|
||||
VTK_INT:4,
|
||||
VTK_UNSIGNED_INT:4,
|
||||
VTK_FLOAT:4,
|
||||
VTK_DOUBLE:8 }
|
||||
|
||||
# convert 'Int32' to 'unsigned short'
|
||||
def SetConvertIntToUnsignedShort(self,yesno):
|
||||
self.__ConvertIntToUnsignedShort = yesno
|
||||
|
||||
def GetConvertIntToUnsignedShort(self):
|
||||
return self.__ConvertIntToUnsignedShort
|
||||
|
||||
def ConvertIntToUnsignedShortOn(self):
|
||||
self.__ConvertIntToUnsignedShort = True
|
||||
|
||||
def ConvertIntToUnsignedShortOff(self):
|
||||
self.__ConvertIntToUnsignedShort = False
|
||||
|
||||
def Update(self):
|
||||
self.__import.Update()
|
||||
|
||||
# get the output
|
||||
def GetOutputPort(self):
|
||||
return self.__import.GetOutputPort()
|
||||
|
||||
# get the output
|
||||
def GetOutput(self):
|
||||
return self.__import.GetOutput()
|
||||
|
||||
# import an array
|
||||
def SetArray(self,imArray):
|
||||
self.__Array = imArray
|
||||
numComponents = 1
|
||||
dim = imArray.shape
|
||||
if len(dim) == 0:
|
||||
dim = (1,1,1)
|
||||
elif len(dim) == 1:
|
||||
dim = (1, 1, dim[0])
|
||||
elif len(dim) == 2:
|
||||
dim = (1, dim[0], dim[1])
|
||||
elif len(dim) == 4:
|
||||
numComponents = dim[3]
|
||||
dim = (dim[0],dim[1],dim[2])
|
||||
|
||||
typecode = imArray.dtype.char
|
||||
|
||||
ar_type = self.__typeDict[typecode]
|
||||
|
||||
complexComponents = 1
|
||||
if (typecode == 'F' or typecode == 'D'):
|
||||
numComponents = numComponents * 2
|
||||
complexComponents = 2
|
||||
|
||||
if (self.__ConvertIntToUnsignedShort and typecode == 'i'):
|
||||
imArray = imArray.astype('h')
|
||||
ar_type = VTK_UNSIGNED_SHORT
|
||||
|
||||
size = len(imArray.flat)*self.__sizeDict[ar_type]*complexComponents
|
||||
self.__import.CopyImportVoidPointer(imArray, size)
|
||||
self.__import.SetDataScalarType(ar_type)
|
||||
self.__import.SetNumberOfScalarComponents(numComponents)
|
||||
extent = self.__import.GetDataExtent()
|
||||
self.__import.SetDataExtent(extent[0],extent[0]+dim[2]-1,
|
||||
extent[2],extent[2]+dim[1]-1,
|
||||
extent[4],extent[4]+dim[0]-1)
|
||||
self.__import.SetWholeExtent(extent[0],extent[0]+dim[2]-1,
|
||||
extent[2],extent[2]+dim[1]-1,
|
||||
extent[4],extent[4]+dim[0]-1)
|
||||
|
||||
def GetArray(self):
|
||||
return self.__Array
|
||||
|
||||
# a whole bunch of methods copied from vtkImageImport
|
||||
|
||||
def SetDataExtent(self,extent):
|
||||
self.__import.SetDataExtent(extent)
|
||||
|
||||
def GetDataExtent(self):
|
||||
return self.__import.GetDataExtent()
|
||||
|
||||
def SetDataSpacing(self,spacing):
|
||||
self.__import.SetDataSpacing(spacing)
|
||||
|
||||
def GetDataSpacing(self):
|
||||
return self.__import.GetDataSpacing()
|
||||
|
||||
def SetDataOrigin(self,origin):
|
||||
self.__import.SetDataOrigin(origin)
|
||||
|
||||
def GetDataOrigin(self):
|
||||
return self.__import.GetDataOrigin()
|
||||
@@ -0,0 +1,226 @@
|
||||
"""
|
||||
This python module provides functionality to parse the methods of a
|
||||
VTK object.
|
||||
|
||||
Created by Prabhu Ramachandran. Committed in Apr, 2002.
|
||||
|
||||
"""
|
||||
|
||||
import string, re, sys
|
||||
import types
|
||||
|
||||
# set this to 1 if you want to see debugging messages - very useful if
|
||||
# you have problems
|
||||
DEBUG=0
|
||||
|
||||
def debug(msg):
|
||||
if DEBUG:
|
||||
print(msg)
|
||||
|
||||
class VtkDirMethodParser:
|
||||
"""Parses the methods from dir(vtk_obj)."""
|
||||
|
||||
def initialize_methods(self, vtk_obj):
|
||||
debug("VtkDirMethodParser:: initialize_methods()")
|
||||
|
||||
self.methods = dir(vtk_obj)[:]
|
||||
# stores the <blah>On methods
|
||||
self.toggle_meths = []
|
||||
# stores the Set<blah>To<blah> methods
|
||||
self.state_meths = []
|
||||
# stores the methods that have a Get<blah> and Set<blah>
|
||||
# only the <blah> is stored
|
||||
self.get_set_meths = []
|
||||
# pure get methods
|
||||
self.get_meths = []
|
||||
self.state_patn = re.compile("To[A-Z0-9]")
|
||||
|
||||
def parse_methods(self, vtk_obj):
|
||||
debug("VtkDirMethodParser:: parse_methods()")
|
||||
self.initialize_methods(vtk_obj)
|
||||
debug("VtkDirMethodParser:: parse_methods() - initialized methods")
|
||||
|
||||
for method in self.methods[:]:
|
||||
# finding all the methods that set the state.
|
||||
if method[:3].find("Set") >= 0 and \
|
||||
self.state_patn.search(method) is not None:
|
||||
try:
|
||||
eval("vtk_obj.Get%s" % method[3:])
|
||||
except AttributeError:
|
||||
self.state_meths.append(method)
|
||||
self.methods.remove(method)
|
||||
# finding all the On/Off toggle methods
|
||||
elif method[-2:].find("On") >= 0:
|
||||
try:
|
||||
self.methods.index("%sOff" % method[:-2])
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
self.toggle_meths.append(method)
|
||||
self.methods.remove(method)
|
||||
self.methods.remove("%sOff" % method[:-2])
|
||||
# finding the Get/Set methods.
|
||||
elif method[:3].find("Get") == 0:
|
||||
set_m = "Set" + method[3:]
|
||||
try:
|
||||
self.methods.index(set_m)
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
self.get_set_meths.append(method[3:])
|
||||
self.methods.remove(method)
|
||||
self.methods.remove(set_m)
|
||||
|
||||
self.clean_up_methods(vtk_obj)
|
||||
|
||||
def clean_up_methods(self, vtk_obj):
|
||||
self.clean_get_set(vtk_obj)
|
||||
self.clean_state_methods(vtk_obj)
|
||||
self.clean_get_methods(vtk_obj)
|
||||
|
||||
def clean_get_set(self, vtk_obj):
|
||||
debug("VtkDirMethodParser:: clean_get_set()")
|
||||
# cleaning up the Get/Set methods by removing the toggle funcs.
|
||||
for method in self.toggle_meths:
|
||||
try:
|
||||
self.get_set_meths.remove(method[:-2])
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
# cleaning them up by removing any methods that are responsible for
|
||||
# other vtkObjects
|
||||
for method in self.get_set_meths[:]:
|
||||
try:
|
||||
eval("vtk_obj.Get%s().GetClassName()" % method)
|
||||
except (TypeError, AttributeError):
|
||||
pass
|
||||
else:
|
||||
self.get_set_meths.remove(method)
|
||||
continue
|
||||
try:
|
||||
val = eval("vtk_obj.Get%s()" % method)
|
||||
except (TypeError, AttributeError):
|
||||
self.get_set_meths.remove(method)
|
||||
else:
|
||||
if val is None:
|
||||
self.get_set_meths.remove(method)
|
||||
|
||||
def clean_state_methods(self, vtk_obj):
|
||||
debug("VtkDirMethodParser:: clean_state_methods()")
|
||||
# Getting the remaining pure GetMethods
|
||||
for method in self.methods[:]:
|
||||
if method[:3].find("Get") == 0:
|
||||
self.get_meths.append(method)
|
||||
self.methods.remove(method)
|
||||
|
||||
# Grouping similar state methods
|
||||
if len(self.state_meths) != 0:
|
||||
tmp = self.state_meths[:]
|
||||
self.state_meths = []
|
||||
state_group = [tmp[0]]
|
||||
end = self.state_patn.search(tmp[0]).start()
|
||||
# stores the method type common to all similar methods
|
||||
m = tmp[0][3:end]
|
||||
for i in range(1, len(tmp)):
|
||||
if tmp[i].find(m) >= 0:
|
||||
state_group.append(tmp[i])
|
||||
else:
|
||||
self.state_meths.append(state_group)
|
||||
state_group = [tmp[i]]
|
||||
end = self.state_patn.search(tmp[i]).start()
|
||||
m = tmp[i][3:end]
|
||||
try: # remove the corresponding set method in get_set
|
||||
val = self.get_set_meths.index(m)
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
del self.get_set_meths[val]
|
||||
#self.get_meths.append("Get" + m)
|
||||
clamp_m = "Get" + m + "MinValue"
|
||||
try: # remove the GetNameMax/MinValue in get_meths
|
||||
val = self.get_meths.index(clamp_m)
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
del self.get_meths[val]
|
||||
val = self.get_meths.index("Get" + m + "MaxValue")
|
||||
del self.get_meths[val]
|
||||
|
||||
if len(state_group) > 0:
|
||||
self.state_meths.append(state_group)
|
||||
|
||||
def clean_get_methods(self, vtk_obj):
|
||||
debug("VtkDirMethodParser:: clean_get_methods()")
|
||||
for method in self.get_meths[:]:
|
||||
debug(method)
|
||||
try:
|
||||
res = eval("vtk_obj.%s()" % method)
|
||||
except (TypeError, AttributeError):
|
||||
self.get_meths.remove(method)
|
||||
continue
|
||||
else:
|
||||
try:
|
||||
eval("vtk_obj.%s().GetClassName()" % method)
|
||||
except AttributeError:
|
||||
pass
|
||||
else:
|
||||
self.get_meths.remove(method)
|
||||
continue
|
||||
if method[-8:].find("MaxValue") > -1:
|
||||
self.get_meths.remove(method)
|
||||
elif method[-8:].find("MinValue") > -1:
|
||||
self.get_meths.remove(method)
|
||||
|
||||
self.get_meths.sort()
|
||||
|
||||
def toggle_methods(self):
|
||||
return self.toggle_meths
|
||||
|
||||
def state_methods(self):
|
||||
return self.state_meths
|
||||
|
||||
def get_set_methods(self):
|
||||
return self.get_set_meths
|
||||
|
||||
def get_methods(self):
|
||||
return self.get_meths
|
||||
|
||||
|
||||
class VtkPrintMethodParser:
|
||||
"""This class finds the methods for a given vtkObject. It uses
|
||||
the output from vtkObject->Print() (or in Python str(vtkObject))
|
||||
and output from the VtkDirMethodParser to obtain the methods."""
|
||||
|
||||
def parse_methods(self, vtk_obj):
|
||||
"""Parse for the methods."""
|
||||
debug("VtkPrintMethodParser:: parse_methods()")
|
||||
self._initialize_methods(vtk_obj)
|
||||
|
||||
def _get_str_obj(self, vtk_obj):
|
||||
debug("VtkPrintMethodParser:: _get_str_obj()")
|
||||
self.methods = str(vtk_obj)
|
||||
self.methods = self.methods.split("\n")
|
||||
del self.methods[0]
|
||||
|
||||
def _initialize_methods(self, vtk_obj):
|
||||
"""Do the basic parsing and setting up"""
|
||||
debug("VtkPrintMethodParser:: _initialize_methods()")
|
||||
dir_p = VtkDirMethodParser()
|
||||
dir_p.parse_methods(vtk_obj)
|
||||
|
||||
self.toggle_meths = dir_p.toggle_methods()
|
||||
self.state_meths = dir_p.state_methods()
|
||||
self.get_set_meths = dir_p.get_set_methods()
|
||||
self.get_meths = dir_p.get_methods()
|
||||
|
||||
def toggle_methods(self):
|
||||
return self.toggle_meths
|
||||
|
||||
def state_methods(self):
|
||||
return self.state_meths
|
||||
|
||||
def get_set_methods(self):
|
||||
return self.get_set_meths
|
||||
|
||||
def get_methods(self):
|
||||
return self.get_meths
|
||||
@@ -0,0 +1,205 @@
|
||||
"""
|
||||
Utility functions to mimic the template support functions for vtkVariant
|
||||
"""
|
||||
|
||||
from vtkmodules import vtkCommonCore
|
||||
import sys
|
||||
|
||||
_variant_type_map = {
|
||||
'void' : vtkCommonCore.VTK_VOID,
|
||||
'char' : vtkCommonCore.VTK_CHAR,
|
||||
'unsigned char' : vtkCommonCore.VTK_UNSIGNED_CHAR,
|
||||
'signed char' : vtkCommonCore.VTK_SIGNED_CHAR,
|
||||
'short' : vtkCommonCore.VTK_SHORT,
|
||||
'unsigned short' : vtkCommonCore.VTK_UNSIGNED_SHORT,
|
||||
'int' : vtkCommonCore.VTK_INT,
|
||||
'unsigned int' : vtkCommonCore.VTK_UNSIGNED_INT,
|
||||
'long' : vtkCommonCore.VTK_LONG,
|
||||
'unsigned long' : vtkCommonCore.VTK_UNSIGNED_LONG,
|
||||
'long long' : vtkCommonCore.VTK_LONG_LONG,
|
||||
'unsigned long long' : vtkCommonCore.VTK_UNSIGNED_LONG_LONG,
|
||||
'float' : vtkCommonCore.VTK_FLOAT,
|
||||
'double' : vtkCommonCore.VTK_DOUBLE,
|
||||
'string' : vtkCommonCore.VTK_STRING,
|
||||
'vtkObjectBase' : vtkCommonCore.VTK_OBJECT,
|
||||
'vtkObject' : vtkCommonCore.VTK_OBJECT,
|
||||
}
|
||||
|
||||
_variant_method_map = {
|
||||
vtkCommonCore.VTK_VOID : '',
|
||||
vtkCommonCore.VTK_CHAR : 'ToChar',
|
||||
vtkCommonCore.VTK_UNSIGNED_CHAR : 'ToUnsignedChar',
|
||||
vtkCommonCore.VTK_SIGNED_CHAR : 'ToSignedChar',
|
||||
vtkCommonCore.VTK_SHORT : 'ToShort',
|
||||
vtkCommonCore.VTK_UNSIGNED_SHORT : 'ToUnsignedShort',
|
||||
vtkCommonCore.VTK_INT : 'ToInt',
|
||||
vtkCommonCore.VTK_UNSIGNED_INT : 'ToUnsignedInt',
|
||||
vtkCommonCore.VTK_LONG : 'ToLong',
|
||||
vtkCommonCore.VTK_UNSIGNED_LONG : 'ToUnsignedLong',
|
||||
vtkCommonCore.VTK_LONG_LONG : 'ToLongLong',
|
||||
vtkCommonCore.VTK_UNSIGNED_LONG_LONG : 'ToUnsignedLongLong',
|
||||
vtkCommonCore.VTK_FLOAT : 'ToFloat',
|
||||
vtkCommonCore.VTK_DOUBLE : 'ToDouble',
|
||||
vtkCommonCore.VTK_STRING : 'ToString',
|
||||
vtkCommonCore.VTK_OBJECT : 'ToVTKObject',
|
||||
}
|
||||
|
||||
_variant_check_map = {
|
||||
vtkCommonCore.VTK_VOID : 'IsValid',
|
||||
vtkCommonCore.VTK_CHAR : 'IsChar',
|
||||
vtkCommonCore.VTK_UNSIGNED_CHAR : 'IsUnsignedChar',
|
||||
vtkCommonCore.VTK_SIGNED_CHAR : 'IsSignedChar',
|
||||
vtkCommonCore.VTK_SHORT : 'IsShort',
|
||||
vtkCommonCore.VTK_UNSIGNED_SHORT : 'IsUnsignedShort',
|
||||
vtkCommonCore.VTK_INT : 'IsInt',
|
||||
vtkCommonCore.VTK_UNSIGNED_INT : 'IsUnsignedInt',
|
||||
vtkCommonCore.VTK_LONG : 'IsLong',
|
||||
vtkCommonCore.VTK_UNSIGNED_LONG : 'IsUnsignedLong',
|
||||
vtkCommonCore.VTK_LONG_LONG : 'IsLongLong',
|
||||
vtkCommonCore.VTK_UNSIGNED_LONG_LONG : 'IsUnsignedLongLong',
|
||||
vtkCommonCore.VTK_FLOAT : 'IsFloat',
|
||||
vtkCommonCore.VTK_DOUBLE : 'IsDouble',
|
||||
vtkCommonCore.VTK_STRING : 'IsString',
|
||||
vtkCommonCore.VTK_OBJECT : 'IsVTKObject',
|
||||
}
|
||||
|
||||
|
||||
def vtkVariantCreate(v, t):
|
||||
"""
|
||||
Create a vtkVariant of the specified type, where the type is in the
|
||||
following format: 'int', 'unsigned int', etc. for numeric types,
|
||||
and 'string' for strings. You can also use an
|
||||
integer VTK type constant for the type.
|
||||
"""
|
||||
if not issubclass(type(t), int):
|
||||
t = _variant_type_map[t]
|
||||
|
||||
return vtkCommonCore.vtkVariant(v, t)
|
||||
|
||||
|
||||
def vtkVariantExtract(v, t=None):
|
||||
"""
|
||||
Extract the specified value type from the vtkVariant, where the type is
|
||||
in the following format: 'int', 'unsigned int', etc. for numeric types,
|
||||
and 'string' for strings. You can also use an
|
||||
integer VTK type constant for the type. Set the type to 'None" to
|
||||
extract the value in its native type.
|
||||
"""
|
||||
v = vtkCommonCore.vtkVariant(v)
|
||||
|
||||
if t == None:
|
||||
t = v.GetType()
|
||||
elif not issubclass(type(t), int):
|
||||
t = _variant_type_map[t]
|
||||
|
||||
if getattr(v, _variant_check_map[t])():
|
||||
return getattr(v, _variant_method_map[t])()
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def vtkVariantCast(v, t):
|
||||
"""
|
||||
Cast the vtkVariant to the specified value type, where the type is
|
||||
in the following format: 'int', 'unsigned int', etc. for numeric types,
|
||||
and 'string' for strings. You can also use an
|
||||
integer VTK type constant for the type.
|
||||
"""
|
||||
if not issubclass(type(t), int):
|
||||
t = _variant_type_map[t]
|
||||
|
||||
v = vtkCommonCore.vtkVariant(v, t)
|
||||
|
||||
if v.IsValid():
|
||||
return getattr(v, _variant_method_map[t])()
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def vtkVariantStrictWeakOrder(s1, s2):
|
||||
"""
|
||||
Compare variants by type first, and then by value.
|
||||
"""
|
||||
s1 = vtkCommonCore.vtkVariant(s1)
|
||||
s2 = vtkCommonCore.vtkVariant(s2)
|
||||
|
||||
t1 = s1.GetType()
|
||||
t2 = s2.GetType()
|
||||
|
||||
# check based on type
|
||||
if t1 != t2:
|
||||
return t1 < t2
|
||||
|
||||
v1 = s1.IsValid()
|
||||
v2 = s2.IsValid()
|
||||
|
||||
# check based on validity
|
||||
if (not v1) or (not v2):
|
||||
return v1 < v2
|
||||
|
||||
# extract and compare the values
|
||||
r1 = getattr(s1, _variant_method_map[t1])()
|
||||
r2 = getattr(s2, _variant_method_map[t2])()
|
||||
|
||||
# compare vtk objects by classname, then address
|
||||
if t1 == vtkCommonCore.VTK_OBJECT:
|
||||
c1 = r1.GetClassName()
|
||||
c2 = r2.GetClassName()
|
||||
if c1 != c2:
|
||||
return c1 < c2
|
||||
else:
|
||||
return r1.__this__ < r2.__this__
|
||||
|
||||
return r1 < r2
|
||||
|
||||
|
||||
class vtkVariantStrictWeakOrderKey:
|
||||
"""A key method (class, actually) for use with sort()"""
|
||||
def __init__(self, obj, *args):
|
||||
self.obj = obj
|
||||
def __lt__(self, other):
|
||||
return vtkVariantStrictWeakOrder(self.obj, other)
|
||||
|
||||
|
||||
def vtkVariantStrictEquality(s1, s2):
|
||||
"""
|
||||
Check two variants for strict equality of type and value.
|
||||
"""
|
||||
s1 = vtkCommonCore.vtkVariant(s1)
|
||||
s2 = vtkCommonCore.vtkVariant(s2)
|
||||
|
||||
t1 = s1.GetType()
|
||||
t2 = s2.GetType()
|
||||
|
||||
# check based on type
|
||||
if t1 != t2:
|
||||
return False
|
||||
|
||||
v1 = s1.IsValid()
|
||||
v2 = s2.IsValid()
|
||||
|
||||
# check based on validity
|
||||
if (not v1) and (not v2):
|
||||
return True
|
||||
elif v1 != v2:
|
||||
return False
|
||||
|
||||
# extract and compare the values
|
||||
r1 = getattr(s1, _variant_method_map[t1])()
|
||||
r2 = getattr(s2, _variant_method_map[t2])()
|
||||
|
||||
return (r1 == r2)
|
||||
|
||||
|
||||
def vtkVariantLessThan(s1, s2):
|
||||
"""
|
||||
Return true if s1 < s2.
|
||||
"""
|
||||
return (vtkCommonCore.vtkVariant(s1) < vtkCommonCore.vtkVariant(s2))
|
||||
|
||||
|
||||
def vtkVariantEqual(s1, s2):
|
||||
"""
|
||||
Return true if s1 == s2.
|
||||
"""
|
||||
return (vtkCommonCore.vtkVariant(s1) == vtkCommonCore.vtkVariant(s2))
|
||||
@@ -0,0 +1,397 @@
|
||||
import cftime
|
||||
import logging
|
||||
import numpy as np
|
||||
from os.path import basename, splitext, exists
|
||||
import xarray as xr
|
||||
from vtkmodules.vtkCommonCore import (
|
||||
vtkVariant,
|
||||
)
|
||||
from vtkmodules.vtkCommonDataModel import (
|
||||
vtkDataObject
|
||||
)
|
||||
from vtkmodules.vtkCommonExecutionModel import (
|
||||
vtkAlgorithm,
|
||||
vtkStreamingDemandDrivenPipeline
|
||||
)
|
||||
from vtkmodules.vtkIONetCDF import vtkNetCDFCFReader, vtkXArrayAccessor
|
||||
from vtkmodules.util import numpy_support
|
||||
from vtkmodules.util.vtkAlgorithm import VTKPythonAlgorithmBase
|
||||
|
||||
@xr.register_dataset_accessor("vtk")
|
||||
class VtkAccessor:
|
||||
def __init__(self, dsxr):
|
||||
self._dsxr = dsxr
|
||||
|
||||
def create_reader(self):
|
||||
'''
|
||||
Returns a vtkXArrayCFReader that reads data from the XArray
|
||||
(using zero-copy when possible). At the moment, data is copied
|
||||
for coordinates (because they are converted to double in the reader)
|
||||
and for certain data that is subset either in XArray or in VTK.
|
||||
Lazy loading in XArray is respected, that is data is accessed only when
|
||||
it is needed.
|
||||
Time is passed to VTK either as an int64 for datetime64 or timedelta64,
|
||||
or as a double (using cftime.toordinal) for cftime.
|
||||
'''
|
||||
reader = vtkXArrayCFReader()
|
||||
reader.SetXArray(self._dsxr)
|
||||
return reader
|
||||
|
||||
|
||||
class vtkXArrayCFReader(VTKPythonAlgorithmBase):
|
||||
'''Reads data from a file using the XArray readers and then connects
|
||||
the XArray data to the vtkNetCDFCFREader (using zero-copy when
|
||||
possible). At the moment, data is copied for coordinates (because
|
||||
they are converted to double in the reader) and for certain data
|
||||
that is subset either in XArray or in VTK. Lazy loading in XArray
|
||||
is respected, that is data is accessed only when it is needed.
|
||||
Time is passed to VTK either as an int64 for datetime64 or
|
||||
timedelta64, or as a double (using cftime.toordinal) for cftime.
|
||||
'''
|
||||
|
||||
_FORWARD_GET = {
|
||||
"GetAccessor",
|
||||
"GetAllDimensions",
|
||||
|
||||
"GetNumberOfVariableArrays",
|
||||
"GetAllVariableArrayNames",
|
||||
"GetVariableArrayName",
|
||||
"GetVariableArrayStatus",
|
||||
|
||||
"GetTimeDimensionName",
|
||||
"GetLatitudeDimensionName",
|
||||
"GetLongitudeDimensionName",
|
||||
"GetVerticalDimensionName",
|
||||
|
||||
"GetOutput",
|
||||
"GetOutputType",
|
||||
"GetSphericalCoordinates",
|
||||
|
||||
"GetReplaceFillValueWithNan",
|
||||
|
||||
"GetVariableDimensions",
|
||||
"GetVerticalBias",
|
||||
"GetVerticalScale",
|
||||
"PrintSelf",
|
||||
}
|
||||
_FORWARD_SET = {
|
||||
"SetDimensions",
|
||||
|
||||
"SetTimeDimensionName",
|
||||
"SetLatitudeDimensionName",
|
||||
"SetLongitudeDimensionName",
|
||||
"SetVerticalDimensionName",
|
||||
|
||||
|
||||
"SetSphericalCoordinates",
|
||||
"SphericalCoordinatesOn",
|
||||
"SphericalCoordinatesOff",
|
||||
|
||||
"SetReplaceFillValueWithNan",
|
||||
"ReplaceFillValueWithNanOn",
|
||||
"ReplaceFillValueWithNanOff",
|
||||
|
||||
"SetOutputType",
|
||||
"SetOutputTypeToAutomatic",
|
||||
"SetOutputTypeToImage",
|
||||
"SetOutputTypeToRectilinear",
|
||||
"SetOutputTypeToStructured",
|
||||
"SetOutputTypeToUnstructured",
|
||||
|
||||
"SetVariableArrayStatus",
|
||||
"SetVerticalBias",
|
||||
"SetVerticalScale",
|
||||
"UpdateMetaData",
|
||||
}
|
||||
|
||||
def __init__(self):
|
||||
VTKPythonAlgorithmBase.__init__(
|
||||
self, nInputPorts=0, nOutputPorts=1, outputType="vtkDataObject"
|
||||
)
|
||||
self._log = logging.getLogger("vtkXArrayCFReader")
|
||||
self._filename = None
|
||||
self._timesteps = None
|
||||
self._timeindex = None
|
||||
self._node = None
|
||||
self._dsxr = None
|
||||
self._reader = vtkNetCDFCFReader()
|
||||
self._ndarray_cftime_toordinal = np.frompyfunc(vtkXArrayCFReader._cftime_toordinal, 1, 1)
|
||||
# reference to contiguous arrays so that they are not dealocated
|
||||
self._arrays = {}
|
||||
|
||||
|
||||
def __getattr__(self, name):
|
||||
in_set = name in self._FORWARD_SET
|
||||
in_get = name in self._FORWARD_GET
|
||||
if in_set or in_get:
|
||||
if in_set:
|
||||
self.Modified()
|
||||
return getattr(self._reader, name)
|
||||
else:
|
||||
raise AttributeError()
|
||||
|
||||
def SetFileName(self, name):
|
||||
"""Specify filename for the file to read."""
|
||||
if self._filename != name:
|
||||
self._filename = name
|
||||
self.Modified()
|
||||
|
||||
def GetFileName(self):
|
||||
return self._filename
|
||||
|
||||
def CanReadFile(self, filepath):
|
||||
ext = splitext(filepath)[1]
|
||||
filename = basename(filepath)
|
||||
correct_name = False
|
||||
if ext == '.nc' or ext == '.grib' or ext == '.h5':
|
||||
correct_name = True
|
||||
else:
|
||||
if ext == '' and filename == '.zgroup':
|
||||
correct_name = True
|
||||
if correct_name and exists(filepath):
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
|
||||
def SetNode(self, node):
|
||||
if self._node != node:
|
||||
self._node = node
|
||||
self.Modified()
|
||||
|
||||
def GetNode(self):
|
||||
return self._node
|
||||
|
||||
def SetXArray(self, dsxr):
|
||||
self._dsxr = dsxr
|
||||
self._update_accessor()
|
||||
self.Modified()
|
||||
|
||||
def GetXArray(self):
|
||||
return self._dsxr
|
||||
|
||||
def RequestDataObject(self, request, inInfo, outInfo):
|
||||
self._log.debug(f"DataObject ======================================================================")
|
||||
if not self._dsxr:
|
||||
if self._node:
|
||||
tree = xr.open_datatree(self._filename)
|
||||
self._dsxr = tree[self._node].to_dataset()
|
||||
else:
|
||||
self._dsxr = xr.open_dataset(self._filename, decode_timedelta=True)
|
||||
self._update_accessor()
|
||||
self._reader.UpdateDataObject()
|
||||
roi = self._reader.GetOutputInformation(0)
|
||||
if roi.Has(vtkDataObject.DATA_OBJECT()):
|
||||
rdata = roi.Get(vtkDataObject.DATA_OBJECT())
|
||||
else:
|
||||
self._log.error("vtkNetCDFCFReader did not create the dataset")
|
||||
rdata = None
|
||||
oi = outInfo.GetInformationObject(0)
|
||||
oi.Set(vtkDataObject.DATA_OBJECT(), rdata)
|
||||
return 1
|
||||
|
||||
def RequestInformation(self, request, inInfo, outInfo):
|
||||
self._log.debug(f"Information ======================================================================")
|
||||
oi = outInfo.GetInformationObject(0)
|
||||
self._reader.UpdateInformation()
|
||||
roi = self._reader.GetOutputInformation(0)
|
||||
if roi.Has(vtkStreamingDemandDrivenPipeline.TIME_STEPS()):
|
||||
self._timesteps = roi.Get(vtkStreamingDemandDrivenPipeline.TIME_STEPS())
|
||||
oi.Set(vtkStreamingDemandDrivenPipeline.TIME_STEPS(), self._timesteps, len(self._timesteps))
|
||||
oi.Set(vtkStreamingDemandDrivenPipeline.TIME_RANGE(), [self._timesteps[0], self._timesteps[-1]], 2)
|
||||
self._timesteps = np.asarray(self._timesteps)
|
||||
if roi.Has(vtkStreamingDemandDrivenPipeline.WHOLE_EXTENT()):
|
||||
ext = roi.Get(vtkStreamingDemandDrivenPipeline.WHOLE_EXTENT())
|
||||
self._log.debug("Whole extent: {}".format(ext))
|
||||
oi.Set(vtkStreamingDemandDrivenPipeline.WHOLE_EXTENT(), ext, 6)
|
||||
if roi.Has(vtkAlgorithm.CAN_HANDLE_PIECE_REQUEST()):
|
||||
oi.Set(vtkAlgorithm.CAN_HANDLE_PIECE_REQUEST(), 1)
|
||||
if roi.Has(vtkAlgorithm.CAN_PRODUCE_SUB_EXTENT()):
|
||||
oi.Set(vtkAlgorithm.CAN_PRODUCE_SUB_EXTENT(), 1)
|
||||
return 1
|
||||
|
||||
def RequestUpdateExtent(self, request, inInfo, outInfo):
|
||||
self._log.debug(f"UpdateExtent ======================================================================")
|
||||
oi = outInfo.GetInformationObject(0)
|
||||
if oi.Has(vtkStreamingDemandDrivenPipeline.UPDATE_TIME_STEP()):
|
||||
utime = oi.Get(vtkStreamingDemandDrivenPipeline.UPDATE_TIME_STEP())
|
||||
timeindex = (np.abs(self._timesteps - utime)).argmin()
|
||||
if timeindex != self._timeindex:
|
||||
self._log.debug(f"Time index = {timeindex}")
|
||||
self._timeindex = timeindex
|
||||
self.Modified()
|
||||
if oi.Has(vtkStreamingDemandDrivenPipeline.UPDATE_EXTENT()):
|
||||
ext = [0, 0, 0, 0, 0, 0]
|
||||
oi.Get(vtkStreamingDemandDrivenPipeline.UPDATE_EXTENT(), ext)
|
||||
self._log.debug("Update extent: {}".format(ext))
|
||||
roi = self._reader.GetOutputInformation(0)
|
||||
roi.Set(vtkStreamingDemandDrivenPipeline.UPDATE_EXTENT(), ext, 6)
|
||||
self._reader.PropagateUpdateExtent()
|
||||
return 1
|
||||
|
||||
|
||||
def RequestData(self, request, inInfo, outInfo):
|
||||
self._log.debug(f"Data ======================================================================")
|
||||
if self._timeindex:
|
||||
dsxr = self._dsxr.isel({self.GetTimeDimensionName() : self._timeindex})
|
||||
else:
|
||||
# no time, so no aditional selection is needed
|
||||
dsxr = self._dsxr
|
||||
accessor = self._reader.GetAccessor()
|
||||
self._set_data_vars(accessor, dsxr)
|
||||
self._reader.Update()
|
||||
# self._reader's data is already set for this's data so no ShallowCopy is needed
|
||||
return 1
|
||||
|
||||
@staticmethod
|
||||
def _get_nc_type(numpy_array_type):
|
||||
"""Returns a nc_type given a numpy array."""
|
||||
NC_BYTE = 1 # 1 byte integer
|
||||
NC_CHAR = 2 # iso/ascii character
|
||||
NC_SHORT = 3 # 2 byte integer
|
||||
NC_INT = 4 # 4 byte integer
|
||||
NC_LONG = NC_INT
|
||||
NC_FLOAT = 5
|
||||
NC_DOUBLE = 6
|
||||
NC_UBYTE = 7
|
||||
NC_USHORT = 8
|
||||
NC_UINT = 9
|
||||
NC_INT64 = 10 # 8 bypte integer
|
||||
NC_UINT64 = 11
|
||||
NC_STRING = 12
|
||||
_np_nc = {
|
||||
np.uint8: NC_UBYTE,
|
||||
np.uint16: NC_USHORT,
|
||||
np.uint32: NC_UINT,
|
||||
np.uint64: NC_UINT64,
|
||||
np.int8: NC_BYTE,
|
||||
np.int16: NC_SHORT,
|
||||
np.int32: NC_INT,
|
||||
np.int64: NC_INT64,
|
||||
np.float32: NC_FLOAT,
|
||||
np.float64: NC_DOUBLE,
|
||||
np.datetime64: NC_INT64,
|
||||
np.timedelta64: NC_INT64,
|
||||
np.str_: NC_STRING,
|
||||
np.bytes_: NC_CHAR,
|
||||
}
|
||||
for key, nc_type in _np_nc.items():
|
||||
if (
|
||||
numpy_array_type == key
|
||||
or np.issubdtype(numpy_array_type, key)
|
||||
or numpy_array_type == np.dtype(key)
|
||||
):
|
||||
return nc_type
|
||||
raise TypeError(
|
||||
"Could not find a suitable NetCDF type for %s" % (str(numpy_array_type))
|
||||
)
|
||||
|
||||
def _update_accessor(self):
|
||||
accessor, timename = self._get_accessor()
|
||||
self._reader.SetAccessor(accessor)
|
||||
if timename:
|
||||
self._reader.SetTimeDimensionName(timename)
|
||||
|
||||
def _get_accessor(self):
|
||||
acclog = logging.getLogger("_get_accessor_")
|
||||
acclog.setLevel(logging.WARNING)
|
||||
accessor = vtkXArrayAccessor()
|
||||
time_name = None
|
||||
time_names = []
|
||||
# Set Dim and DimLen
|
||||
dimNameToIndex = {k: i for i, k in enumerate(self._dsxr.sizes.keys())}
|
||||
accessor.SetDim(list(self._dsxr.sizes.keys()))
|
||||
accessor.SetDimLen(list(self._dsxr.sizes.values()))
|
||||
|
||||
# Set Var
|
||||
varList = list(self._dsxr.data_vars.keys()) + list(self._dsxr.coords.keys())
|
||||
varNameToIndex = {k: i for i, k in enumerate(varList)}
|
||||
is_coord = [0] * len(self._dsxr.data_vars)
|
||||
is_coord = is_coord + [1] * len(self._dsxr.coords)
|
||||
coords_bounds = self._get_coords_bounds()
|
||||
accessor.SetVar(varList, is_coord)
|
||||
for i, v in enumerate(varList):
|
||||
# data_vars are set after array selection and time selection to
|
||||
# take advantage of xarray lazy loading
|
||||
# https://docs.xarray.dev/en/latest/internals/internal-design.html
|
||||
if is_coord[i] or v in coords_bounds:
|
||||
# if there is subsetting in xarray, self._dsxr[v].values is
|
||||
# not contiguous. If the array is not contiguous, a contiguous
|
||||
# copy is created otherwise the contiguous array is simply returned
|
||||
v_data = np.ascontiguousarray(self._dsxr[v].values)
|
||||
if (
|
||||
v_data.dtype.type == np.datetime64
|
||||
or v_data.dtype.type == np.timedelta64
|
||||
):
|
||||
un = np.datetime_data(v_data.dtype)
|
||||
# unit = ns and 1 base unit
|
||||
if un[0] == "ns" and un[1] == 1:
|
||||
time_names.append(v)
|
||||
if v_data.dtype.char == "O":
|
||||
# object array, assume cftime
|
||||
# copy cftime array to a doubles array
|
||||
self._arrays[v] = self._ndarray_cftime_toordinal(v_data).astype(np.float64)
|
||||
time_names.append(v)
|
||||
v_data = self._arrays[v]
|
||||
else:
|
||||
self._arrays[v] = v_data
|
||||
acclog.debug(f"{v=} {v_data.shape=} {v_data.dtype} {self._dsxr[v].dims=}")
|
||||
acclog.debug(f"address:{hex(v_data.ctypes.data)}")
|
||||
accessor.SetVarValue(i, v_data)
|
||||
accessor.SetVarType(i, vtkXArrayCFReader._get_nc_type(v_data.dtype))
|
||||
else:
|
||||
accessor.SetVarType(i, vtkXArrayCFReader._get_nc_type(self._dsxr[v].variable.dtype))
|
||||
accessor.SetVarDims(i, [dimNameToIndex[name] for name in self._dsxr[v].dims])
|
||||
accessor.SetVarCoords(
|
||||
i, [varNameToIndex[name] for name in self._dsxr[v].coords]
|
||||
)
|
||||
|
||||
acclog.debug("Attributes:")
|
||||
for item in self._dsxr[v].attrs.items():
|
||||
acclog.debug(
|
||||
"name: {} value: {} type: {}".format(
|
||||
item[0], item[1], type(item[1])
|
||||
)
|
||||
)
|
||||
if np.issubdtype(type(item[1]), np.integer):
|
||||
accessor.SetAtt(i, item[0], vtkVariant(int(item[1])))
|
||||
elif np.issubdtype(type(item[1]), np.floating):
|
||||
accessor.SetAtt(i, item[0], vtkVariant(float(item[1])))
|
||||
elif isinstance(item[1], np.ndarray):
|
||||
accessor.SetAtt(
|
||||
i, item[0], vtkVariant(numpy_support.numpy_to_vtk(item[1]))
|
||||
)
|
||||
else:
|
||||
accessor.SetAtt(i, item[0], vtkVariant(item[1]))
|
||||
if len(time_names) >= 1:
|
||||
for name in time_names:
|
||||
if accessor.IsCOARDSCoordinate(name):
|
||||
time_name = name
|
||||
break
|
||||
return accessor, time_name
|
||||
|
||||
def _set_data_vars(self, accessor, dsxr):
|
||||
# data_vars are listed first in the list of data_vars,coords so we don't
|
||||
# need to add coords to the list, and still get the corect indexes
|
||||
varList = list(dsxr.data_vars.keys())
|
||||
for i, v in enumerate(varList):
|
||||
if self._reader.GetVariableArrayStatus(v):
|
||||
v_data = np.ascontiguousarray(dsxr[v].values)
|
||||
accessor.SetVarValue(i, v_data)
|
||||
self._arrays[v] = v_data
|
||||
|
||||
def _get_coords_bounds(self):
|
||||
'''
|
||||
Special data_vars associated coords
|
||||
'''
|
||||
b=set()
|
||||
for coord in list(self._dsxr.coords):
|
||||
bounds_attr = 'bounds'
|
||||
if bounds_attr in self._dsxr[coord].attrs:
|
||||
b.add(self._dsxr[coord].attrs[bounds_attr])
|
||||
return b
|
||||
|
||||
|
||||
@staticmethod
|
||||
def _cftime_toordinal(o):
|
||||
return o.toordinal(fractional=True)
|
||||
@@ -0,0 +1,251 @@
|
||||
from typing import overload, Any, Callable, TypeVar, Union
|
||||
from typing import Tuple, List, Sequence, MutableSequence
|
||||
|
||||
Callback = Union[Callable[..., None], None]
|
||||
Buffer = TypeVar('Buffer')
|
||||
Pointer = TypeVar('Pointer')
|
||||
Template = TypeVar('Template')
|
||||
|
||||
import vtkmodules.vtkCommonCore
|
||||
import vtkmodules.vtkCommonExecutionModel
|
||||
|
||||
class vtkAMRBaseParticlesReader(vtkmodules.vtkCommonExecutionModel.vtkMultiBlockDataSetAlgorithm):
|
||||
controller:'getset_descriptor'
|
||||
file_name:'getset_descriptor'
|
||||
filter_location:'getset_descriptor'
|
||||
frequency:'getset_descriptor'
|
||||
max_location:'getset_descriptor'
|
||||
min_location:'getset_descriptor'
|
||||
number_of_particle_arrays:'getset_descriptor'
|
||||
particle_data_array_selection:'getset_descriptor'
|
||||
total_number_of_particles:'getset_descriptor'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def FilterLocationOff(self) -> None: ...
|
||||
def FilterLocationOn(self) -> None: ...
|
||||
def GetController(self) -> 'vtkMultiProcessController': ...
|
||||
def GetFileName(self) -> str: ...
|
||||
def GetFilterLocation(self) -> int: ...
|
||||
def GetFrequency(self) -> int: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def GetNumberOfParticleArrays(self) -> int: ...
|
||||
def GetParticleArrayName(self, index:int) -> str: ...
|
||||
def GetParticleArrayStatus(self, name:str) -> int: ...
|
||||
def GetParticleDataArraySelection(self) -> 'vtkDataArraySelection': ...
|
||||
def GetTotalNumberOfParticles(self) -> int: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkAMRBaseParticlesReader': ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkAMRBaseParticlesReader': ...
|
||||
def SetController(self, __a:'vtkMultiProcessController') -> None: ...
|
||||
def SetFileName(self, fileName:str) -> None: ...
|
||||
def SetFilterLocation(self, _arg:int) -> None: ...
|
||||
def SetFrequency(self, _arg:int) -> None: ...
|
||||
def SetMaxLocation(self, maxx:float, maxy:float, maxz:float) -> None: ...
|
||||
def SetMinLocation(self, minx:float, miny:float, minz:float) -> None: ...
|
||||
def SetParticleArrayStatus(self, name:str, status:int) -> None: ...
|
||||
|
||||
class vtkAMRBaseReader(vtkmodules.vtkCommonExecutionModel.vtkOverlappingAMRAlgorithm):
|
||||
cell_data_array_selection:'getset_descriptor'
|
||||
controller:'getset_descriptor'
|
||||
enable_caching:'getset_descriptor'
|
||||
file_name:'getset_descriptor'
|
||||
max_level:'getset_descriptor'
|
||||
number_of_blocks:'getset_descriptor'
|
||||
number_of_cell_arrays:'getset_descriptor'
|
||||
number_of_levels:'getset_descriptor'
|
||||
number_of_point_arrays:'getset_descriptor'
|
||||
point_data_array_selection:'getset_descriptor'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def EnableCachingOff(self) -> None: ...
|
||||
def EnableCachingOn(self) -> None: ...
|
||||
def GetCellArrayName(self, index:int) -> str: ...
|
||||
def GetCellArrayStatus(self, name:str) -> int: ...
|
||||
def GetCellDataArraySelection(self) -> 'vtkDataArraySelection': ...
|
||||
def GetController(self) -> 'vtkMultiProcessController': ...
|
||||
def GetEnableCaching(self) -> int: ...
|
||||
def GetFileName(self) -> str: ...
|
||||
def GetNumberOfBlocks(self) -> int: ...
|
||||
def GetNumberOfCellArrays(self) -> int: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def GetNumberOfLevels(self) -> int: ...
|
||||
def GetNumberOfPointArrays(self) -> int: ...
|
||||
def GetPointArrayName(self, index:int) -> str: ...
|
||||
def GetPointArrayStatus(self, name:str) -> int: ...
|
||||
def GetPointDataArraySelection(self) -> 'vtkDataArraySelection': ...
|
||||
def Initialize(self) -> None: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
def IsCachingEnabled(self) -> bool: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkAMRBaseReader': ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkAMRBaseReader': ...
|
||||
def SetCellArrayStatus(self, name:str, status:int) -> None: ...
|
||||
def SetController(self, __a:'vtkMultiProcessController') -> None: ...
|
||||
def SetEnableCaching(self, _arg:int) -> None: ...
|
||||
def SetFileName(self, fileName:str) -> None: ...
|
||||
def SetMaxLevel(self, _arg:int) -> None: ...
|
||||
def SetPointArrayStatus(self, name:str, status:int) -> None: ...
|
||||
|
||||
class vtkAMRDataSetCache(vtkmodules.vtkCommonCore.vtkObject):
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def GetAMRBlock(self, compositeIdx:int) -> 'vtkUniformGrid': ...
|
||||
def GetAMRBlockCellData(self, compositeIdx:int, dataName:str) -> 'vtkDataArray': ...
|
||||
def GetAMRBlockPointData(self, compositeIdx:int, dataName:str) -> 'vtkDataArray': ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def HasAMRBlock(self, compositeIdx:int) -> bool: ...
|
||||
def HasAMRBlockCellData(self, compositeIdx:int, name:str) -> bool: ...
|
||||
def HasAMRBlockPointData(self, compositeIdx:int, name:str) -> bool: ...
|
||||
def InsertAMRBlock(self, compositeIdx:int, amrGrid:'vtkUniformGrid') -> None: ...
|
||||
def InsertAMRBlockCellData(self, compositeIdx:int, dataArray:'vtkDataArray') -> None: ...
|
||||
def InsertAMRBlockPointData(self, compositeIdx:int, dataArray:'vtkDataArray') -> None: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkAMRDataSetCache': ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkAMRDataSetCache': ...
|
||||
|
||||
class vtkAMREnzoParticlesReader(vtkAMRBaseParticlesReader):
|
||||
particle_type:'getset_descriptor'
|
||||
total_number_of_particles:'getset_descriptor'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def GetParticleType(self) -> int: ...
|
||||
def GetTotalNumberOfParticles(self) -> int: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkAMREnzoParticlesReader': ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkAMREnzoParticlesReader': ...
|
||||
def SetParticleType(self, _arg:int) -> None: ...
|
||||
|
||||
class vtkAMREnzoReader(vtkAMRBaseReader):
|
||||
convert_to_cgs:'getset_descriptor'
|
||||
file_name:'getset_descriptor'
|
||||
number_of_blocks:'getset_descriptor'
|
||||
number_of_levels:'getset_descriptor'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def ConvertToCGSOff(self) -> None: ...
|
||||
def ConvertToCGSOn(self) -> None: ...
|
||||
def GetConvertToCGS(self) -> int: ...
|
||||
def GetNumberOfBlocks(self) -> int: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def GetNumberOfLevels(self) -> int: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkAMREnzoReader': ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkAMREnzoReader': ...
|
||||
def SetConvertToCGS(self, _arg:int) -> None: ...
|
||||
def SetFileName(self, fileName:str) -> None: ...
|
||||
|
||||
class vtkAMRFlashParticlesReader(vtkAMRBaseParticlesReader):
|
||||
total_number_of_particles:'getset_descriptor'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def GetTotalNumberOfParticles(self) -> int: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkAMRFlashParticlesReader': ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkAMRFlashParticlesReader': ...
|
||||
|
||||
class vtkAMRFlashReader(vtkAMRBaseReader):
|
||||
file_name:'getset_descriptor'
|
||||
number_of_blocks:'getset_descriptor'
|
||||
number_of_levels:'getset_descriptor'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def GetNumberOfBlocks(self) -> int: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def GetNumberOfLevels(self) -> int: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkAMRFlashReader': ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkAMRFlashReader': ...
|
||||
def SetFileName(self, fileName:str) -> None: ...
|
||||
|
||||
class vtkAMRVelodyneReader(vtkAMRBaseReader):
|
||||
file_name:'getset_descriptor'
|
||||
number_of_blocks:'getset_descriptor'
|
||||
number_of_levels:'getset_descriptor'
|
||||
output:'getset_descriptor'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def GetNumberOfBlocks(self) -> int: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def GetNumberOfLevels(self) -> int: ...
|
||||
def GetOutput(self) -> 'vtkOverlappingAMR': ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkAMRVelodyneReader': ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkAMRVelodyneReader': ...
|
||||
def SetFileName(self, fileName:str) -> None: ...
|
||||
|
||||
class vtkAMReXGridReader(vtkAMRBaseReader):
|
||||
file_name:'getset_descriptor'
|
||||
number_of_blocks:'getset_descriptor'
|
||||
number_of_levels:'getset_descriptor'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def GetNumberOfBlocks(self) -> int: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def GetNumberOfLevels(self) -> int: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkAMReXGridReader': ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkAMReXGridReader': ...
|
||||
def SetFileName(self, fileName:str) -> None: ...
|
||||
|
||||
class vtkAMReXParticlesReader(vtkmodules.vtkCommonExecutionModel.vtkMultiBlockDataSetAlgorithm):
|
||||
controller:'getset_descriptor'
|
||||
particle_type:'getset_descriptor'
|
||||
plot_file_name:'getset_descriptor'
|
||||
point_data_array_selection:'getset_descriptor'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
@staticmethod
|
||||
def CanReadFile(fname:str, particlesType:str=...) -> int: ...
|
||||
def GetController(self) -> 'vtkMultiProcessController': ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def GetParticleType(self) -> str: ...
|
||||
def GetPlotFileName(self) -> str: ...
|
||||
def GetPointDataArraySelection(self) -> 'vtkDataArraySelection': ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkAMReXParticlesReader': ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkAMReXParticlesReader': ...
|
||||
def SetController(self, controller:'vtkMultiProcessController') -> None: ...
|
||||
def SetParticleType(self, str:str) -> None: ...
|
||||
def SetPlotFileName(self, fname:str) -> None: ...
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
from typing import overload, Any, Callable, TypeVar, Union
|
||||
from typing import Tuple, List, Sequence, MutableSequence
|
||||
|
||||
Callback = Union[Callable[..., None], None]
|
||||
Buffer = TypeVar('Buffer')
|
||||
Pointer = TypeVar('Pointer')
|
||||
Template = TypeVar('Template')
|
||||
|
||||
import vtkmodules.vtkCommonCore
|
||||
import vtkmodules.vtkCommonExecutionModel
|
||||
|
||||
class vtkAvmeshReader(vtkmodules.vtkCommonExecutionModel.vtkPartitionedDataSetCollectionAlgorithm):
|
||||
build_connectivity_iteratively:'getset_descriptor'
|
||||
file_name:'getset_descriptor'
|
||||
surface_only:'getset_descriptor'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def BuildConnectivityIterativelyOff(self) -> None: ...
|
||||
def BuildConnectivityIterativelyOn(self) -> None: ...
|
||||
def CanReadFile(self, filename:str) -> int: ...
|
||||
def GetBuildConnectivityIteratively(self) -> bool: ...
|
||||
def GetFileName(self) -> str: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def GetSurfaceOnly(self) -> bool: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkAvmeshReader': ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkAvmeshReader': ...
|
||||
def SetBuildConnectivityIteratively(self, _arg:bool) -> None: ...
|
||||
def SetFileName(self, arg:str) -> None: ...
|
||||
def SetSurfaceOnly(self, _arg:bool) -> None: ...
|
||||
def SurfaceOnlyOff(self) -> None: ...
|
||||
def SurfaceOnlyOn(self) -> None: ...
|
||||
|
||||
@@ -0,0 +1,716 @@
|
||||
from typing import overload, Any, Callable, TypeVar, Union
|
||||
from typing import Tuple, List, Sequence, MutableSequence
|
||||
|
||||
Callback = Union[Callable[..., None], None]
|
||||
Buffer = TypeVar('Buffer')
|
||||
Pointer = TypeVar('Pointer')
|
||||
Template = TypeVar('Template')
|
||||
|
||||
import vtkmodules.vtkCommonCore
|
||||
import vtkmodules.vtkCommonExecutionModel
|
||||
|
||||
VTK_ASCII:int
|
||||
VTK_BINARY:int
|
||||
|
||||
class vtkTextCodec(vtkmodules.vtkCommonCore.vtkObject):
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def CanHandle(self, NameString:str) -> bool: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def Name(self) -> str: ...
|
||||
def NewInstance(self) -> 'vtkTextCodec': ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkTextCodec': ...
|
||||
|
||||
class vtkASCIITextCodec(vtkTextCodec):
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def CanHandle(self, NameString:str) -> bool: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def Name(self) -> str: ...
|
||||
def NewInstance(self) -> 'vtkASCIITextCodec': ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkASCIITextCodec': ...
|
||||
|
||||
class vtkWriter(vtkmodules.vtkCommonExecutionModel.vtkAlgorithm):
|
||||
input:'getset_descriptor'
|
||||
input_data:'getset_descriptor'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def EncodeString(self, resname:str, name:str, doublePercent:bool) -> None: ...
|
||||
@overload
|
||||
def GetInput(self) -> 'vtkDataObject': ...
|
||||
@overload
|
||||
def GetInput(self, port:int) -> 'vtkDataObject': ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkWriter': ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkWriter': ...
|
||||
@overload
|
||||
def SetInputData(self, input:'vtkDataObject') -> None: ...
|
||||
@overload
|
||||
def SetInputData(self, index:int, input:'vtkDataObject') -> None: ...
|
||||
def Write(self) -> int: ...
|
||||
|
||||
class vtkAbstractParticleWriter(vtkWriter):
|
||||
collective_io:'getset_descriptor'
|
||||
file_name:'getset_descriptor'
|
||||
time_step:'getset_descriptor'
|
||||
time_value:'getset_descriptor'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def CloseFile(self) -> None: ...
|
||||
def GetCollectiveIO(self) -> int: ...
|
||||
def GetFileName(self) -> str: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def GetTimeStep(self) -> int: ...
|
||||
def GetTimeValue(self) -> float: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkAbstractParticleWriter': ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkAbstractParticleWriter': ...
|
||||
def SetCollectiveIO(self, _arg:int) -> None: ...
|
||||
def SetFileName(self, _arg:str) -> None: ...
|
||||
def SetTimeStep(self, _arg:int) -> None: ...
|
||||
def SetTimeValue(self, _arg:float) -> None: ...
|
||||
def SetWriteModeToCollective(self) -> None: ...
|
||||
def SetWriteModeToIndependent(self) -> None: ...
|
||||
|
||||
class vtkAbstractPolyDataReader(vtkmodules.vtkCommonExecutionModel.vtkPolyDataAlgorithm):
|
||||
file_name:'getset_descriptor'
|
||||
stream:'getset_descriptor'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def GetFileName(self) -> str: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def GetStream(self) -> 'vtkResourceStream': ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkAbstractPolyDataReader': ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkAbstractPolyDataReader': ...
|
||||
def SetFileName(self, _arg:str) -> None: ...
|
||||
def SetStream(self, _arg:'vtkResourceStream') -> None: ...
|
||||
|
||||
class vtkArrayDataReader(vtkmodules.vtkCommonExecutionModel.vtkArrayDataAlgorithm):
|
||||
file_name:'getset_descriptor'
|
||||
input_string:'getset_descriptor'
|
||||
read_from_input_string:'getset_descriptor'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def GetFileName(self) -> str: ...
|
||||
def GetInputString(self) -> str: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def GetReadFromInputString(self) -> bool: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkArrayDataReader': ...
|
||||
@staticmethod
|
||||
def Read(str:str) -> 'vtkArrayData': ...
|
||||
def ReadFromInputStringOff(self) -> None: ...
|
||||
def ReadFromInputStringOn(self) -> None: ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkArrayDataReader': ...
|
||||
def SetFileName(self, _arg:str) -> None: ...
|
||||
def SetInputString(self, string:str) -> None: ...
|
||||
def SetReadFromInputString(self, _arg:bool) -> None: ...
|
||||
|
||||
class vtkArrayDataWriter(vtkWriter):
|
||||
binary:'getset_descriptor'
|
||||
file_name:'getset_descriptor'
|
||||
output_string:'getset_descriptor'
|
||||
write_to_output_string:'getset_descriptor'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def BinaryOff(self) -> None: ...
|
||||
def BinaryOn(self) -> None: ...
|
||||
def GetBinary(self) -> int: ...
|
||||
def GetFileName(self) -> str: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def GetOutputString(self) -> str: ...
|
||||
def GetWriteToOutputString(self) -> bool: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkArrayDataWriter': ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkArrayDataWriter': ...
|
||||
def SetBinary(self, _arg:int) -> None: ...
|
||||
def SetFileName(self, _arg:str) -> None: ...
|
||||
def SetWriteToOutputString(self, _arg:bool) -> None: ...
|
||||
@overload
|
||||
def Write(self) -> int: ...
|
||||
@overload
|
||||
def Write(self, FileName:str, WriteBinary:bool=False) -> bool: ...
|
||||
@overload
|
||||
@staticmethod
|
||||
def Write(array:'vtkArrayData', file_name:str, WriteBinary:bool=False) -> bool: ...
|
||||
@overload
|
||||
def Write(self, WriteBinary:bool) -> str: ...
|
||||
@overload
|
||||
@staticmethod
|
||||
def Write(array:'vtkArrayData', WriteBinary:bool=False) -> str: ...
|
||||
def WriteToOutputStringOff(self) -> None: ...
|
||||
def WriteToOutputStringOn(self) -> None: ...
|
||||
|
||||
class vtkArrayReader(vtkmodules.vtkCommonExecutionModel.vtkArrayDataAlgorithm):
|
||||
file_name:'getset_descriptor'
|
||||
input_string:'getset_descriptor'
|
||||
read_from_input_string:'getset_descriptor'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def GetFileName(self) -> str: ...
|
||||
def GetInputString(self) -> str: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def GetReadFromInputString(self) -> bool: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkArrayReader': ...
|
||||
@staticmethod
|
||||
def Read(str:str) -> 'vtkArray': ...
|
||||
def ReadFromInputStringOff(self) -> None: ...
|
||||
def ReadFromInputStringOn(self) -> None: ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkArrayReader': ...
|
||||
def SetFileName(self, _arg:str) -> None: ...
|
||||
def SetInputString(self, string:str) -> None: ...
|
||||
def SetReadFromInputString(self, _arg:bool) -> None: ...
|
||||
|
||||
class vtkArrayWriter(vtkWriter):
|
||||
binary:'getset_descriptor'
|
||||
file_name:'getset_descriptor'
|
||||
output_string:'getset_descriptor'
|
||||
write_to_output_string:'getset_descriptor'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def BinaryOff(self) -> None: ...
|
||||
def BinaryOn(self) -> None: ...
|
||||
def GetBinary(self) -> int: ...
|
||||
def GetFileName(self) -> str: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def GetOutputString(self) -> str: ...
|
||||
def GetWriteToOutputString(self) -> bool: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkArrayWriter': ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkArrayWriter': ...
|
||||
def SetBinary(self, _arg:int) -> None: ...
|
||||
def SetFileName(self, _arg:str) -> None: ...
|
||||
def SetWriteToOutputString(self, _arg:bool) -> None: ...
|
||||
@overload
|
||||
def Write(self) -> int: ...
|
||||
@overload
|
||||
def Write(self, FileName:str, WriteBinary:bool=False) -> bool: ...
|
||||
@overload
|
||||
@staticmethod
|
||||
def Write(array:'vtkArray', file_name:str, WriteBinary:bool=False) -> bool: ...
|
||||
@overload
|
||||
def Write(self, WriteBinary:bool) -> str: ...
|
||||
@overload
|
||||
@staticmethod
|
||||
def Write(array:'vtkArray', WriteBinary:bool=False) -> str: ...
|
||||
def WriteToOutputStringOff(self) -> None: ...
|
||||
def WriteToOutputStringOn(self) -> None: ...
|
||||
|
||||
class vtkInputStream(vtkmodules.vtkCommonCore.vtkObject):
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def EndReading(self) -> None: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkInputStream': ...
|
||||
def Read(self, data:Pointer, length:int) -> int: ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkInputStream': ...
|
||||
def Seek(self, offset:int) -> int: ...
|
||||
def StartReading(self) -> None: ...
|
||||
|
||||
class vtkBase64InputStream(vtkInputStream):
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def EndReading(self) -> None: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkBase64InputStream': ...
|
||||
def Read(self, data:Pointer, length:int) -> int: ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkBase64InputStream': ...
|
||||
def Seek(self, offset:int) -> int: ...
|
||||
def StartReading(self) -> None: ...
|
||||
|
||||
class vtkOutputStream(vtkmodules.vtkCommonCore.vtkObject):
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def EndWriting(self) -> int: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkOutputStream': ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkOutputStream': ...
|
||||
def StartWriting(self) -> int: ...
|
||||
def Write(self, data:Pointer, length:int) -> int: ...
|
||||
|
||||
class vtkBase64OutputStream(vtkOutputStream):
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def EndWriting(self) -> int: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkBase64OutputStream': ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkBase64OutputStream': ...
|
||||
def StartWriting(self) -> int: ...
|
||||
def Write(self, data:Pointer, length:int) -> int: ...
|
||||
|
||||
class vtkBase64Utilities(vtkmodules.vtkCommonCore.vtkObject):
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
@staticmethod
|
||||
def DecodeSafely(input:Sequence[int], inputLen:int, output:MutableSequence[int], outputLen:int) -> int: ...
|
||||
@staticmethod
|
||||
def DecodeTriplet(i0:int, i1:int, i2:int, i3:int, o0:MutableSequence[int], o1:MutableSequence[int], o2:MutableSequence[int]) -> int: ...
|
||||
@staticmethod
|
||||
def Encode(input:Sequence[int], length:int, output:MutableSequence[int], mark_end:int=0) -> int: ...
|
||||
@staticmethod
|
||||
def EncodePair(i0:int, i1:int, o0:MutableSequence[int], o1:MutableSequence[int], o2:MutableSequence[int], o3:MutableSequence[int]) -> None: ...
|
||||
@staticmethod
|
||||
def EncodeSingle(i0:int, o0:MutableSequence[int], o1:MutableSequence[int], o2:MutableSequence[int], o3:MutableSequence[int]) -> None: ...
|
||||
@staticmethod
|
||||
def EncodeTriplet(i0:int, i1:int, i2:int, o0:MutableSequence[int], o1:MutableSequence[int], o2:MutableSequence[int], o3:MutableSequence[int]) -> None: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkBase64Utilities': ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkBase64Utilities': ...
|
||||
|
||||
class vtkDataCompressor(vtkmodules.vtkCommonCore.vtkObject):
|
||||
compression_level:'getset_descriptor'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
@overload
|
||||
def Compress(self, uncompressedData:Sequence[int], uncompressedSize:int, compressedData:MutableSequence[int], compressionSpace:int) -> int: ...
|
||||
@overload
|
||||
def Compress(self, uncompressedData:Sequence[int], uncompressedSize:int) -> 'vtkUnsignedCharArray': ...
|
||||
def GetCompressionLevel(self) -> int: ...
|
||||
def GetMaximumCompressionSpace(self, size:int) -> int: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkDataCompressor': ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkDataCompressor': ...
|
||||
def SetCompressionLevel(self, compressionLevel:int) -> None: ...
|
||||
@overload
|
||||
def Uncompress(self, compressedData:Sequence[int], compressedSize:int, uncompressedData:MutableSequence[int], uncompressedSize:int) -> int: ...
|
||||
@overload
|
||||
def Uncompress(self, compressedData:Sequence[int], compressedSize:int, uncompressedSize:int) -> 'vtkUnsignedCharArray': ...
|
||||
|
||||
class vtkDelimitedTextWriter(vtkWriter):
|
||||
field_delimiter:'getset_descriptor'
|
||||
file_name:'getset_descriptor'
|
||||
string_delimiter:'getset_descriptor'
|
||||
use_string_delimiter:'getset_descriptor'
|
||||
write_to_output_string:'getset_descriptor'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def GetFieldDelimiter(self) -> str: ...
|
||||
def GetFileName(self) -> str: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def GetString(self, string:str) -> str: ...
|
||||
def GetStringDelimiter(self) -> str: ...
|
||||
def GetUseStringDelimiter(self) -> bool: ...
|
||||
def GetWriteToOutputString(self) -> bool: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkDelimitedTextWriter': ...
|
||||
def RegisterAndGetOutputString(self) -> str: ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkDelimitedTextWriter': ...
|
||||
def SetFieldDelimiter(self, _arg:str) -> None: ...
|
||||
def SetFileName(self, _arg:str) -> None: ...
|
||||
def SetStringDelimiter(self, _arg:str) -> None: ...
|
||||
def SetUseStringDelimiter(self, _arg:bool) -> None: ...
|
||||
def SetWriteToOutputString(self, _arg:bool) -> None: ...
|
||||
def WriteToOutputStringOff(self) -> None: ...
|
||||
def WriteToOutputStringOn(self) -> None: ...
|
||||
|
||||
class vtkResourceStream(vtkmodules.vtkCommonCore.vtkObject):
|
||||
class SeekDirection(int):
|
||||
Begin:'SeekDirection'
|
||||
Current:'SeekDirection'
|
||||
End:'SeekDirection'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def EndOfStream(self) -> bool: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkResourceStream': ...
|
||||
def Read(self, buffer:Pointer, bytes:int) -> int: ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkResourceStream': ...
|
||||
def Seek(self, pos:int, dir:'SeekDirection') -> int: ...
|
||||
def SupportSeek(self) -> bool: ...
|
||||
def Tell(self) -> int: ...
|
||||
|
||||
class vtkFileResourceStream(vtkResourceStream):
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def EndOfStream(self) -> bool: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkFileResourceStream': ...
|
||||
def Open(self, path:str) -> bool: ...
|
||||
def Read(self, buffer:Pointer, bytes:int) -> int: ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkFileResourceStream': ...
|
||||
def Tell(self) -> int: ...
|
||||
|
||||
class vtkGlobFileNames(vtkmodules.vtkCommonCore.vtkObject):
|
||||
directory:'getset_descriptor'
|
||||
file_names:'getset_descriptor'
|
||||
recurse:'getset_descriptor'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def AddFileNames(self, pattern:str) -> int: ...
|
||||
def GetDirectory(self) -> str: ...
|
||||
def GetFileNames(self) -> 'vtkStringArray': ...
|
||||
def GetNthFileName(self, index:int) -> str: ...
|
||||
def GetNumberOfFileNames(self) -> int: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def GetRecurse(self) -> int: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkGlobFileNames': ...
|
||||
def RecurseOff(self) -> None: ...
|
||||
def RecurseOn(self) -> None: ...
|
||||
def Reset(self) -> None: ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkGlobFileNames': ...
|
||||
def SetDirectory(self, _arg:str) -> None: ...
|
||||
def SetRecurse(self, _arg:int) -> None: ...
|
||||
|
||||
class vtkJavaScriptDataWriter(vtkWriter):
|
||||
file_name:'getset_descriptor'
|
||||
include_field_names:'getset_descriptor'
|
||||
variable_name:'getset_descriptor'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def GetFileName(self) -> str: ...
|
||||
def GetIncludeFieldNames(self) -> bool: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def GetVariableName(self) -> str: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkJavaScriptDataWriter': ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkJavaScriptDataWriter': ...
|
||||
def SetFileName(self, _arg:str) -> None: ...
|
||||
def SetIncludeFieldNames(self, _arg:bool) -> None: ...
|
||||
def SetVariableName(self, _arg:str) -> None: ...
|
||||
|
||||
class vtkLZ4DataCompressor(vtkDataCompressor):
|
||||
acceleration_level:'getset_descriptor'
|
||||
compression_level:'getset_descriptor'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def GetAccelerationLevel(self) -> int: ...
|
||||
def GetAccelerationLevelMaxValue(self) -> int: ...
|
||||
def GetAccelerationLevelMinValue(self) -> int: ...
|
||||
def GetCompressionLevel(self) -> int: ...
|
||||
def GetMaximumCompressionSpace(self, size:int) -> int: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkLZ4DataCompressor': ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkLZ4DataCompressor': ...
|
||||
def SetAccelerationLevel(self, _arg:int) -> None: ...
|
||||
def SetCompressionLevel(self, compressionLevel:int) -> None: ...
|
||||
|
||||
class vtkLZMADataCompressor(vtkDataCompressor):
|
||||
compression_level:'getset_descriptor'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def GetCompressionLevel(self) -> int: ...
|
||||
def GetMaximumCompressionSpace(self, size:int) -> int: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkLZMADataCompressor': ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkLZMADataCompressor': ...
|
||||
def SetCompressionLevel(self, compressionLevel:int) -> None: ...
|
||||
|
||||
class vtkMemoryResourceStream(vtkResourceStream):
|
||||
buffer:'getset_descriptor'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def EndOfStream(self) -> bool: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkMemoryResourceStream': ...
|
||||
def OwnsBuffer(self) -> bool: ...
|
||||
def Read(self, buffer:Pointer, bytes:int) -> int: ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkMemoryResourceStream': ...
|
||||
def SetBuffer(self, buffer:Pointer, size:int, copy:bool=False) -> None: ...
|
||||
def Tell(self) -> int: ...
|
||||
|
||||
class vtkSortFileNames(vtkmodules.vtkCommonCore.vtkObject):
|
||||
file_names:'getset_descriptor'
|
||||
grouping:'getset_descriptor'
|
||||
ignore_case:'getset_descriptor'
|
||||
input_file_names:'getset_descriptor'
|
||||
numeric_sort:'getset_descriptor'
|
||||
skip_directories:'getset_descriptor'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def GetFileNames(self) -> 'vtkStringArray': ...
|
||||
def GetGrouping(self) -> int: ...
|
||||
def GetIgnoreCase(self) -> int: ...
|
||||
def GetInputFileNames(self) -> 'vtkStringArray': ...
|
||||
def GetNthGroup(self, i:int) -> 'vtkStringArray': ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def GetNumberOfGroups(self) -> int: ...
|
||||
def GetNumericSort(self) -> int: ...
|
||||
def GetSkipDirectories(self) -> int: ...
|
||||
def GroupingOff(self) -> None: ...
|
||||
def GroupingOn(self) -> None: ...
|
||||
def IgnoreCaseOff(self) -> None: ...
|
||||
def IgnoreCaseOn(self) -> None: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkSortFileNames': ...
|
||||
def NumericSortOff(self) -> None: ...
|
||||
def NumericSortOn(self) -> None: ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkSortFileNames': ...
|
||||
def SetGrouping(self, _arg:int) -> None: ...
|
||||
def SetIgnoreCase(self, _arg:int) -> None: ...
|
||||
def SetInputFileNames(self, input:'vtkStringArray') -> None: ...
|
||||
def SetNumericSort(self, _arg:int) -> None: ...
|
||||
def SetSkipDirectories(self, _arg:int) -> None: ...
|
||||
def SkipDirectoriesOff(self) -> None: ...
|
||||
def SkipDirectoriesOn(self) -> None: ...
|
||||
def Update(self) -> None: ...
|
||||
|
||||
class vtkTextCodecFactory(vtkmodules.vtkCommonCore.vtkObject):
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
@staticmethod
|
||||
def CodecForName(CodecName:str) -> 'vtkTextCodec': ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
@staticmethod
|
||||
def Initialize() -> None: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkTextCodecFactory': ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkTextCodecFactory': ...
|
||||
@staticmethod
|
||||
def UnRegisterAllCreateCallbacks() -> None: ...
|
||||
|
||||
class vtkURI(vtkmodules.vtkCommonCore.vtkObject):
|
||||
authority:'getset_descriptor'
|
||||
fragment:'getset_descriptor'
|
||||
path:'getset_descriptor'
|
||||
query:'getset_descriptor'
|
||||
scheme:'getset_descriptor'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
@overload
|
||||
@staticmethod
|
||||
def Clone(other:'vtkURI') -> 'vtkURI': ...
|
||||
@overload
|
||||
def Clone(self) -> 'vtkURI': ...
|
||||
def GetAuthority(self) -> 'vtkURIComponent': ...
|
||||
def GetFragment(self) -> 'vtkURIComponent': ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def GetPath(self) -> 'vtkURIComponent': ...
|
||||
def GetQuery(self) -> 'vtkURIComponent': ...
|
||||
def GetScheme(self) -> 'vtkURIComponent': ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
def IsAbsolute(self) -> bool: ...
|
||||
def IsEmpty(self) -> bool: ...
|
||||
def IsFull(self) -> bool: ...
|
||||
def IsReference(self) -> bool: ...
|
||||
def IsRelative(self) -> bool: ...
|
||||
def IsSameDocRef(self) -> bool: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkURI': ...
|
||||
@overload
|
||||
@staticmethod
|
||||
def Parse(uri:str) -> 'vtkURI': ...
|
||||
@overload
|
||||
@staticmethod
|
||||
def Parse(uri:str, size:int) -> 'vtkURI': ...
|
||||
@overload
|
||||
@staticmethod
|
||||
def PercentDecode(str:str) -> str: ...
|
||||
@overload
|
||||
@staticmethod
|
||||
def PercentDecode(str:str, size:int) -> str: ...
|
||||
@overload
|
||||
@staticmethod
|
||||
def PercentEncode(str:str) -> str: ...
|
||||
@overload
|
||||
@staticmethod
|
||||
def PercentEncode(str:str, size:int) -> str: ...
|
||||
@staticmethod
|
||||
def Resolve(baseURI:'vtkURI', uri:'vtkURI') -> 'vtkURI': ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkURI': ...
|
||||
def ToString(self) -> str: ...
|
||||
|
||||
class vtkURIComponent(object):
|
||||
value:'getset_descriptor'
|
||||
@overload
|
||||
def __init__(self) -> None: ...
|
||||
@overload
|
||||
def __init__(self, str:str) -> None: ...
|
||||
@overload
|
||||
def __init__(self, __a:'vtkURIComponent') -> None: ...
|
||||
def GetValue(self) -> str: ...
|
||||
def IsDefined(self) -> bool: ...
|
||||
|
||||
class vtkURILoader(vtkmodules.vtkCommonCore.vtkObject):
|
||||
base_uri:'getset_descriptor'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def GetBaseURI(self) -> 'vtkURI': ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def HasBaseURI(self) -> bool: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
@overload
|
||||
def Load(self, uri:str) -> 'vtkResourceStream': ...
|
||||
@overload
|
||||
def Load(self, uri:str, size:int) -> 'vtkResourceStream': ...
|
||||
@overload
|
||||
def Load(self, uri:'vtkURI') -> 'vtkResourceStream': ...
|
||||
def LoadResolved(self, uri:'vtkURI') -> 'vtkResourceStream': ...
|
||||
def NewInstance(self) -> 'vtkURILoader': ...
|
||||
def Resolve(self, uri:'vtkURI') -> 'vtkURI': ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkURILoader': ...
|
||||
def SetBaseDirectory(self, dirpath:str) -> bool: ...
|
||||
def SetBaseFileName(self, filepath:str) -> bool: ...
|
||||
@overload
|
||||
def SetBaseURI(self, uri:str) -> bool: ...
|
||||
@overload
|
||||
def SetBaseURI(self, uri:'vtkURI') -> bool: ...
|
||||
|
||||
class vtkUTF16TextCodec(vtkTextCodec):
|
||||
big_endian:'getset_descriptor'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def CanHandle(self, NameString:str) -> bool: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def Name(self) -> str: ...
|
||||
def NewInstance(self) -> 'vtkUTF16TextCodec': ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkUTF16TextCodec': ...
|
||||
def SetBigEndian(self, __a:bool) -> None: ...
|
||||
|
||||
class vtkUTF8TextCodec(vtkTextCodec):
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def Name(self) -> str: ...
|
||||
def NewInstance(self) -> 'vtkUTF8TextCodec': ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkUTF8TextCodec': ...
|
||||
|
||||
class vtkZLibDataCompressor(vtkDataCompressor):
|
||||
compression_level:'getset_descriptor'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def GetCompressionLevel(self) -> int: ...
|
||||
def GetMaximumCompressionSpace(self, size:int) -> int: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkZLibDataCompressor': ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkZLibDataCompressor': ...
|
||||
def SetCompressionLevel(self, compressionLevel:int) -> None: ...
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
from typing import overload, Any, Callable, TypeVar, Union
|
||||
from typing import Tuple, List, Sequence, MutableSequence
|
||||
|
||||
Callback = Union[Callable[..., None], None]
|
||||
Buffer = TypeVar('Buffer')
|
||||
Pointer = TypeVar('Pointer')
|
||||
Template = TypeVar('Template')
|
||||
|
||||
import vtkmodules.vtkCommonCore
|
||||
import vtkmodules.vtkCommonExecutionModel
|
||||
|
||||
class vtkERFReader(vtkmodules.vtkCommonExecutionModel.vtkPartitionedDataSetCollectionAlgorithm):
|
||||
blocks_selection:'getset_descriptor'
|
||||
file_name:'getset_descriptor'
|
||||
stage:'getset_descriptor'
|
||||
stages_selection:'getset_descriptor'
|
||||
variables_selection:'getset_descriptor'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def EnableAllBlocks(self) -> None: ...
|
||||
def EnableAllVariables(self) -> None: ...
|
||||
def GetBlocksSelection(self) -> 'vtkDataArraySelection': ...
|
||||
def GetFileName(self) -> str: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def GetStage(self) -> str: ...
|
||||
def GetStagesSelection(self) -> 'vtkDataArraySelection': ...
|
||||
def GetVariablesSelection(self) -> 'vtkDataArraySelection': ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkERFReader': ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkERFReader': ...
|
||||
def SetBlocksStatus(self, name:str, status:int) -> None: ...
|
||||
def SetFileName(self, _arg:str) -> None: ...
|
||||
def SetStagesStatus(self, name:str, status:int) -> None: ...
|
||||
def SetVariablesStatus(self, name:str, status:int) -> None: ...
|
||||
|
||||
class vtkHDF5Helper(object): ...
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
from typing import overload, Any, Callable, TypeVar, Union
|
||||
from typing import Tuple, List, Sequence, MutableSequence
|
||||
|
||||
Callback = Union[Callable[..., None], None]
|
||||
Buffer = TypeVar('Buffer')
|
||||
Pointer = TypeVar('Pointer')
|
||||
Template = TypeVar('Template')
|
||||
|
||||
import vtkmodules.vtkCommonCore
|
||||
import vtkmodules.vtkCommonExecutionModel
|
||||
|
||||
class vtkBTSReader(vtkmodules.vtkCommonExecutionModel.vtkPartitionedDataSetAlgorithm):
|
||||
file_name:'getset_descriptor'
|
||||
registration_name:'getset_descriptor'
|
||||
stream:'getset_descriptor'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def GetFileName(self) -> str: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def GetRegistrationName(self) -> str: ...
|
||||
def GetStream(self) -> 'vtkResourceStream': ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkBTSReader': ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkBTSReader': ...
|
||||
def SetFileName(self, _arg:str) -> None: ...
|
||||
def SetStream(self, stream:'vtkResourceStream') -> None: ...
|
||||
|
||||
@@ -0,0 +1,849 @@
|
||||
from typing import overload, Any, Callable, TypeVar, Union
|
||||
from typing import Tuple, List, Sequence, MutableSequence
|
||||
|
||||
Callback = Union[Callable[..., None], None]
|
||||
Buffer = TypeVar('Buffer')
|
||||
Pointer = TypeVar('Pointer')
|
||||
Template = TypeVar('Template')
|
||||
|
||||
import vtkmodules.vtkCommonCore
|
||||
import vtkmodules.vtkCommonDataModel
|
||||
import vtkmodules.vtkCommonExecutionModel
|
||||
import vtkmodules.vtkIOCore
|
||||
import vtkmodules.vtkIOXMLParser
|
||||
|
||||
class vtkCPExodusIIElementBlock(vtkmodules.vtkCommonDataModel.vtkUnstructuredGridBase):
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkCPExodusIIElementBlock': ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkCPExodusIIElementBlock': ...
|
||||
|
||||
class vtkCPExodusIIElementBlockImpl(vtkmodules.vtkCommonCore.vtkObject):
|
||||
max_cell_size:'getset_descriptor'
|
||||
number_of_cells:'getset_descriptor'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def Allocate(self, numCells:int, extSize:int=1000) -> None: ...
|
||||
def GetCellPoints(self, cellId:int, ptIds:'vtkIdList') -> None: ...
|
||||
def GetCellType(self, cellId:int) -> int: ...
|
||||
def GetFaceStream(self, cellId:int, ptIds:'vtkIdList') -> None: ...
|
||||
def GetIdsOfCellsOfType(self, type:int, array:'vtkIdTypeArray') -> None: ...
|
||||
def GetMaxCellSize(self) -> int: ...
|
||||
def GetNumberOfCells(self) -> int: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def GetPointCells(self, ptId:int, cellIds:'vtkIdList') -> None: ...
|
||||
def GetPolyhedronFaces(self, cellId:int, faces:'vtkCellArray') -> None: ...
|
||||
@overload
|
||||
def InsertNextCell(self, type:int, ptIds:'vtkIdList') -> int: ...
|
||||
@overload
|
||||
def InsertNextCell(self, type:int, npts:int, ptIds:Sequence[int]) -> int: ...
|
||||
@overload
|
||||
def InsertNextCell(self, type:int, npts:int, ptIds:Sequence[int], faces:'vtkCellArray') -> int: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
def IsHomogeneous(self) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkCPExodusIIElementBlockImpl': ...
|
||||
def ReplaceCell(self, cellId:int, npts:int, pts:Sequence[int]) -> None: ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkCPExodusIIElementBlockImpl': ...
|
||||
def SetExodusConnectivityArray(self, elements:MutableSequence[int], type:str, numElements:int, nodesPerElement:int) -> bool: ...
|
||||
|
||||
class vtkCPExodusIIInSituReader(vtkmodules.vtkCommonExecutionModel.vtkMultiBlockDataSetAlgorithm):
|
||||
current_time_step:'getset_descriptor'
|
||||
file_name:'getset_descriptor'
|
||||
time_step_range:'getset_descriptor'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def GetCurrentTimeStep(self) -> int: ...
|
||||
def GetFileName(self) -> str: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def GetTimeStepRange(self) -> Tuple[int, int]: ...
|
||||
def GetTimeStepValue(self, step:int) -> float: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkCPExodusIIInSituReader': ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkCPExodusIIInSituReader': ...
|
||||
def SetCurrentTimeStep(self, _arg:int) -> None: ...
|
||||
def SetFileName(self, _arg:str) -> None: ...
|
||||
|
||||
class vtkExodusIICache(vtkmodules.vtkCommonCore.vtkObject):
|
||||
cache_capacity:'getset_descriptor'
|
||||
space_left:'getset_descriptor'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def Clear(self) -> None: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def GetSpaceLeft(self) -> float: ...
|
||||
def Insert(self, key:'vtkExodusIICacheKey', value:'vtkDataArray') -> None: ...
|
||||
@overload
|
||||
def Invalidate(self, key:'vtkExodusIICacheKey') -> int: ...
|
||||
@overload
|
||||
def Invalidate(self, key:'vtkExodusIICacheKey', pattern:'vtkExodusIICacheKey') -> int: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkExodusIICache': ...
|
||||
def ReduceToSize(self, newSize:float) -> int: ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkExodusIICache': ...
|
||||
def SetCacheCapacity(self, sizeInMiB:float) -> None: ...
|
||||
|
||||
class vtkExodusIICacheEntry(object):
|
||||
value:'getset_descriptor'
|
||||
@overload
|
||||
def __init__(self) -> None: ...
|
||||
@overload
|
||||
def __init__(self, arr:'vtkDataArray') -> None: ...
|
||||
@overload
|
||||
def __init__(self, other:'vtkExodusIICacheEntry') -> None: ...
|
||||
def GetValue(self) -> 'vtkDataArray': ...
|
||||
|
||||
class vtkExodusIICacheKey(object):
|
||||
@overload
|
||||
def __init__(self) -> None: ...
|
||||
@overload
|
||||
def __init__(self, time:int, objType:int, objId:int, arrId:int) -> None: ...
|
||||
@overload
|
||||
def __init__(self, src:'vtkExodusIICacheKey') -> None: ...
|
||||
def match(self, other:'vtkExodusIICacheKey', pattern:'vtkExodusIICacheKey') -> bool: ...
|
||||
|
||||
class vtkExodusIIReader(vtkmodules.vtkCommonExecutionModel.vtkMultiBlockDataSetAlgorithm):
|
||||
class ObjectType(int): ...
|
||||
ASSEMBLY:'ObjectType'
|
||||
EDGE_BLOCK:'ObjectType'
|
||||
EDGE_BLOCK_ATTRIB:'ObjectType'
|
||||
EDGE_BLOCK_CONN:'ObjectType'
|
||||
EDGE_ID:'ObjectType'
|
||||
EDGE_MAP:'ObjectType'
|
||||
EDGE_SET:'ObjectType'
|
||||
EDGE_SET_CONN:'ObjectType'
|
||||
ELEMENT_ID:'ObjectType'
|
||||
ELEM_BLOCK:'ObjectType'
|
||||
ELEM_BLOCK_ATTRIB:'ObjectType'
|
||||
ELEM_BLOCK_EDGE_CONN:'ObjectType'
|
||||
ELEM_BLOCK_ELEM_CONN:'ObjectType'
|
||||
ELEM_BLOCK_FACE_CONN:'ObjectType'
|
||||
ELEM_BLOCK_TEMPORAL:'ObjectType'
|
||||
ELEM_MAP:'ObjectType'
|
||||
ELEM_SET:'ObjectType'
|
||||
ELEM_SET_CONN:'ObjectType'
|
||||
ENTITY_COUNTS:'ObjectType'
|
||||
FACE_BLOCK:'ObjectType'
|
||||
FACE_BLOCK_ATTRIB:'ObjectType'
|
||||
FACE_BLOCK_CONN:'ObjectType'
|
||||
FACE_ID:'ObjectType'
|
||||
FACE_MAP:'ObjectType'
|
||||
FACE_SET:'ObjectType'
|
||||
FACE_SET_CONN:'ObjectType'
|
||||
GLOBAL:'ObjectType'
|
||||
GLOBAL_CONN:'ObjectType'
|
||||
GLOBAL_ELEMENT_ID:'ObjectType'
|
||||
GLOBAL_NODE_ID:'ObjectType'
|
||||
GLOBAL_TEMPORAL:'ObjectType'
|
||||
HIERARCHY:'ObjectType'
|
||||
ID_NOT_FOUND:int
|
||||
IMPLICIT_ELEMENT_ID:'ObjectType'
|
||||
IMPLICIT_NODE_ID:'ObjectType'
|
||||
INFO_RECORDS:'ObjectType'
|
||||
MATERIAL:'ObjectType'
|
||||
NODAL:'ObjectType'
|
||||
NODAL_COORDS:'ObjectType'
|
||||
NODAL_SQUEEZEMAP:'ObjectType'
|
||||
NODAL_TEMPORAL:'ObjectType'
|
||||
NODE_ID:'ObjectType'
|
||||
NODE_MAP:'ObjectType'
|
||||
NODE_SET:'ObjectType'
|
||||
NODE_SET_CONN:'ObjectType'
|
||||
OBJECT_ID:'ObjectType'
|
||||
PART:'ObjectType'
|
||||
QA_RECORDS:'ObjectType'
|
||||
SEARCH_TYPE_ELEMENT:int
|
||||
SEARCH_TYPE_ELEMENT_THEN_NODE:int
|
||||
SEARCH_TYPE_NODE:int
|
||||
SEARCH_TYPE_NODE_THEN_ELEMENT:int
|
||||
SIDE_SET:'ObjectType'
|
||||
SIDE_SET_CONN:'ObjectType'
|
||||
all_array_status:'getset_descriptor'
|
||||
animate_mode_shapes:'getset_descriptor'
|
||||
apply_displacements:'getset_descriptor'
|
||||
assembly_array_status:'getset_descriptor'
|
||||
cache_size:'getset_descriptor'
|
||||
dimensionality:'getset_descriptor'
|
||||
displacement_magnitude:'getset_descriptor'
|
||||
display_type:'getset_descriptor'
|
||||
file_id:'getset_descriptor'
|
||||
file_name:'getset_descriptor'
|
||||
generate_file_id_array:'getset_descriptor'
|
||||
generate_global_element_id_array:'getset_descriptor'
|
||||
generate_global_node_id_array:'getset_descriptor'
|
||||
generate_implicit_element_id_array:'getset_descriptor'
|
||||
generate_implicit_node_id_array:'getset_descriptor'
|
||||
generate_object_id_cell_array:'getset_descriptor'
|
||||
global_edge_id_array_name:'getset_descriptor'
|
||||
global_element_id_array_name:'getset_descriptor'
|
||||
global_face_id_array_name:'getset_descriptor'
|
||||
global_node_id_array_name:'getset_descriptor'
|
||||
has_mode_shapes:'getset_descriptor'
|
||||
hierarchy_array_status:'getset_descriptor'
|
||||
ignore_file_time:'getset_descriptor'
|
||||
implicit_edge_id_array_name:'getset_descriptor'
|
||||
implicit_element_id_array_name:'getset_descriptor'
|
||||
implicit_face_id_array_name:'getset_descriptor'
|
||||
implicit_node_id_array_name:'getset_descriptor'
|
||||
m_time:'getset_descriptor'
|
||||
material_array_status:'getset_descriptor'
|
||||
max_name_length:'getset_descriptor'
|
||||
metadata_m_time:'getset_descriptor'
|
||||
mode_shape:'getset_descriptor'
|
||||
mode_shape_time:'getset_descriptor'
|
||||
mode_shapes_range:'getset_descriptor'
|
||||
number_of_assembly_arrays:'getset_descriptor'
|
||||
number_of_edge_block_arrays:'getset_descriptor'
|
||||
number_of_edge_map_arrays:'getset_descriptor'
|
||||
number_of_edge_result_arrays:'getset_descriptor'
|
||||
number_of_edge_set_arrays:'getset_descriptor'
|
||||
number_of_edge_set_result_arrays:'getset_descriptor'
|
||||
number_of_edges_in_file:'getset_descriptor'
|
||||
number_of_element_block_arrays:'getset_descriptor'
|
||||
number_of_element_map_arrays:'getset_descriptor'
|
||||
number_of_element_result_arrays:'getset_descriptor'
|
||||
number_of_element_set_arrays:'getset_descriptor'
|
||||
number_of_element_set_result_arrays:'getset_descriptor'
|
||||
number_of_elements_in_file:'getset_descriptor'
|
||||
number_of_face_block_arrays:'getset_descriptor'
|
||||
number_of_face_map_arrays:'getset_descriptor'
|
||||
number_of_face_result_arrays:'getset_descriptor'
|
||||
number_of_face_set_arrays:'getset_descriptor'
|
||||
number_of_face_set_result_arrays:'getset_descriptor'
|
||||
number_of_faces_in_file:'getset_descriptor'
|
||||
number_of_global_result_arrays:'getset_descriptor'
|
||||
number_of_hierarchy_arrays:'getset_descriptor'
|
||||
number_of_material_arrays:'getset_descriptor'
|
||||
number_of_node_map_arrays:'getset_descriptor'
|
||||
number_of_node_set_arrays:'getset_descriptor'
|
||||
number_of_node_set_result_arrays:'getset_descriptor'
|
||||
number_of_nodes:'getset_descriptor'
|
||||
number_of_nodes_in_file:'getset_descriptor'
|
||||
number_of_part_arrays:'getset_descriptor'
|
||||
number_of_point_result_arrays:'getset_descriptor'
|
||||
number_of_side_set_arrays:'getset_descriptor'
|
||||
number_of_side_set_result_arrays:'getset_descriptor'
|
||||
object_array_status:'getset_descriptor'
|
||||
object_attribute_status:'getset_descriptor'
|
||||
object_id_array_name:'getset_descriptor'
|
||||
object_name:'getset_descriptor'
|
||||
object_status:'getset_descriptor'
|
||||
part_array_status:'getset_descriptor'
|
||||
pedigree_edge_id_array_name:'getset_descriptor'
|
||||
pedigree_element_id_array_name:'getset_descriptor'
|
||||
pedigree_face_id_array_name:'getset_descriptor'
|
||||
pedigree_node_id_array_name:'getset_descriptor'
|
||||
side_set_source_element_id_array_name:'getset_descriptor'
|
||||
side_set_source_element_side_array_name:'getset_descriptor'
|
||||
sil:'getset_descriptor'
|
||||
sil_update_stamp:'getset_descriptor'
|
||||
squeeze_points:'getset_descriptor'
|
||||
time_step:'getset_descriptor'
|
||||
time_step_range:'getset_descriptor'
|
||||
title:'getset_descriptor'
|
||||
total_number_of_edges:'getset_descriptor'
|
||||
total_number_of_elements:'getset_descriptor'
|
||||
total_number_of_faces:'getset_descriptor'
|
||||
total_number_of_nodes:'getset_descriptor'
|
||||
use_legacy_block_names:'getset_descriptor'
|
||||
xml_file_name:'getset_descriptor'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def AnimateModeShapesOff(self) -> None: ...
|
||||
def AnimateModeShapesOn(self) -> None: ...
|
||||
def ApplyDisplacementsOff(self) -> None: ...
|
||||
def ApplyDisplacementsOn(self) -> None: ...
|
||||
def CanReadFile(self, fname:str) -> int: ...
|
||||
def Dump(self) -> None: ...
|
||||
@staticmethod
|
||||
def GLOBAL_TEMPORAL_VARIABLE() -> 'vtkInformationIntegerKey': ...
|
||||
@staticmethod
|
||||
def GLOBAL_VARIABLE() -> 'vtkInformationIntegerKey': ...
|
||||
def GenerateFileIdArrayOff(self) -> None: ...
|
||||
def GenerateFileIdArrayOn(self) -> None: ...
|
||||
def GenerateGlobalElementIdArrayOff(self) -> None: ...
|
||||
def GenerateGlobalElementIdArrayOn(self) -> None: ...
|
||||
def GenerateGlobalNodeIdArrayOff(self) -> None: ...
|
||||
def GenerateGlobalNodeIdArrayOn(self) -> None: ...
|
||||
def GenerateImplicitElementIdArrayOff(self) -> None: ...
|
||||
def GenerateImplicitElementIdArrayOn(self) -> None: ...
|
||||
def GenerateImplicitNodeIdArrayOff(self) -> None: ...
|
||||
def GenerateImplicitNodeIdArrayOn(self) -> None: ...
|
||||
def GenerateObjectIdCellArrayOff(self) -> None: ...
|
||||
def GenerateObjectIdCellArrayOn(self) -> None: ...
|
||||
def GetAnimateModeShapes(self) -> int: ...
|
||||
def GetApplyDisplacements(self) -> int: ...
|
||||
def GetAssemblyArrayID(self, name:str) -> int: ...
|
||||
def GetAssemblyArrayName(self, arrayIdx:int) -> str: ...
|
||||
@overload
|
||||
def GetAssemblyArrayStatus(self, index:int) -> int: ...
|
||||
@overload
|
||||
def GetAssemblyArrayStatus(self, __a:str) -> int: ...
|
||||
def GetCacheSize(self) -> float: ...
|
||||
def GetDimensionality(self) -> int: ...
|
||||
def GetDisplacementMagnitude(self) -> float: ...
|
||||
def GetDisplayType(self) -> int: ...
|
||||
def GetEdgeBlockArrayName(self, index:int) -> str: ...
|
||||
def GetEdgeBlockArrayStatus(self, name:str) -> int: ...
|
||||
def GetEdgeMapArrayName(self, index:int) -> str: ...
|
||||
def GetEdgeMapArrayStatus(self, name:str) -> int: ...
|
||||
def GetEdgeResultArrayName(self, index:int) -> str: ...
|
||||
def GetEdgeResultArrayStatus(self, name:str) -> int: ...
|
||||
def GetEdgeSetArrayName(self, index:int) -> str: ...
|
||||
def GetEdgeSetArrayStatus(self, name:str) -> int: ...
|
||||
def GetEdgeSetResultArrayName(self, index:int) -> str: ...
|
||||
def GetEdgeSetResultArrayStatus(self, name:str) -> int: ...
|
||||
def GetElementBlockArrayName(self, index:int) -> str: ...
|
||||
def GetElementBlockArrayStatus(self, name:str) -> int: ...
|
||||
def GetElementMapArrayName(self, index:int) -> str: ...
|
||||
def GetElementMapArrayStatus(self, name:str) -> int: ...
|
||||
def GetElementResultArrayName(self, index:int) -> str: ...
|
||||
def GetElementResultArrayStatus(self, name:str) -> int: ...
|
||||
def GetElementSetArrayName(self, index:int) -> str: ...
|
||||
def GetElementSetArrayStatus(self, name:str) -> int: ...
|
||||
def GetElementSetResultArrayName(self, index:int) -> str: ...
|
||||
def GetElementSetResultArrayStatus(self, name:str) -> int: ...
|
||||
def GetFaceBlockArrayName(self, index:int) -> str: ...
|
||||
def GetFaceBlockArrayStatus(self, name:str) -> int: ...
|
||||
def GetFaceMapArrayName(self, index:int) -> str: ...
|
||||
def GetFaceMapArrayStatus(self, name:str) -> int: ...
|
||||
def GetFaceResultArrayName(self, index:int) -> str: ...
|
||||
def GetFaceResultArrayStatus(self, name:str) -> int: ...
|
||||
def GetFaceSetArrayName(self, index:int) -> str: ...
|
||||
def GetFaceSetArrayStatus(self, name:str) -> int: ...
|
||||
def GetFaceSetResultArrayName(self, index:int) -> str: ...
|
||||
def GetFaceSetResultArrayStatus(self, name:str) -> int: ...
|
||||
def GetFileId(self) -> int: ...
|
||||
def GetFileName(self) -> str: ...
|
||||
def GetGenerateFileIdArray(self) -> int: ...
|
||||
def GetGenerateGlobalElementIdArray(self) -> int: ...
|
||||
def GetGenerateGlobalNodeIdArray(self) -> int: ...
|
||||
def GetGenerateImplicitElementIdArray(self) -> int: ...
|
||||
def GetGenerateImplicitNodeIdArray(self) -> int: ...
|
||||
def GetGenerateObjectIdCellArray(self) -> int: ...
|
||||
@overload
|
||||
@staticmethod
|
||||
def GetGlobalEdgeID(data:'vtkDataSet', localID:int) -> int: ...
|
||||
@overload
|
||||
@staticmethod
|
||||
def GetGlobalEdgeID(data:'vtkDataSet', localID:int, searchType:int) -> int: ...
|
||||
@staticmethod
|
||||
def GetGlobalEdgeIdArrayName() -> str: ...
|
||||
@overload
|
||||
@staticmethod
|
||||
def GetGlobalElementID(data:'vtkDataSet', localID:int) -> int: ...
|
||||
@overload
|
||||
@staticmethod
|
||||
def GetGlobalElementID(data:'vtkDataSet', localID:int, searchType:int) -> int: ...
|
||||
@staticmethod
|
||||
def GetGlobalElementIdArrayName() -> str: ...
|
||||
@overload
|
||||
@staticmethod
|
||||
def GetGlobalFaceID(data:'vtkDataSet', localID:int) -> int: ...
|
||||
@overload
|
||||
@staticmethod
|
||||
def GetGlobalFaceID(data:'vtkDataSet', localID:int, searchType:int) -> int: ...
|
||||
@staticmethod
|
||||
def GetGlobalFaceIdArrayName() -> str: ...
|
||||
@overload
|
||||
@staticmethod
|
||||
def GetGlobalNodeID(data:'vtkDataSet', localID:int) -> int: ...
|
||||
@overload
|
||||
@staticmethod
|
||||
def GetGlobalNodeID(data:'vtkDataSet', localID:int, searchType:int) -> int: ...
|
||||
@staticmethod
|
||||
def GetGlobalNodeIdArrayName() -> str: ...
|
||||
def GetGlobalResultArrayName(self, index:int) -> str: ...
|
||||
def GetGlobalResultArrayStatus(self, name:str) -> int: ...
|
||||
def GetHasModeShapes(self) -> int: ...
|
||||
def GetHierarchyArrayName(self, arrayIdx:int) -> str: ...
|
||||
@overload
|
||||
def GetHierarchyArrayStatus(self, index:int) -> int: ...
|
||||
@overload
|
||||
def GetHierarchyArrayStatus(self, __a:str) -> int: ...
|
||||
def GetIgnoreFileTime(self) -> bool: ...
|
||||
@staticmethod
|
||||
def GetImplicitEdgeIdArrayName() -> str: ...
|
||||
@staticmethod
|
||||
def GetImplicitElementIdArrayName() -> str: ...
|
||||
@staticmethod
|
||||
def GetImplicitFaceIdArrayName() -> str: ...
|
||||
@staticmethod
|
||||
def GetImplicitNodeIdArrayName() -> str: ...
|
||||
def GetMTime(self) -> int: ...
|
||||
def GetMaterialArrayID(self, name:str) -> int: ...
|
||||
def GetMaterialArrayName(self, arrayIdx:int) -> str: ...
|
||||
@overload
|
||||
def GetMaterialArrayStatus(self, index:int) -> int: ...
|
||||
@overload
|
||||
def GetMaterialArrayStatus(self, __a:str) -> int: ...
|
||||
def GetMaxNameLength(self) -> int: ...
|
||||
def GetMetadataMTime(self) -> int: ...
|
||||
def GetModeShapeTime(self) -> float: ...
|
||||
def GetModeShapesRange(self) -> Tuple[int, int]: ...
|
||||
def GetNodeMapArrayName(self, index:int) -> str: ...
|
||||
def GetNodeMapArrayStatus(self, name:str) -> int: ...
|
||||
def GetNodeSetArrayName(self, index:int) -> str: ...
|
||||
def GetNodeSetArrayStatus(self, name:str) -> int: ...
|
||||
def GetNodeSetResultArrayName(self, index:int) -> str: ...
|
||||
def GetNodeSetResultArrayStatus(self, name:str) -> int: ...
|
||||
def GetNumberOfAssemblyArrays(self) -> int: ...
|
||||
def GetNumberOfEdgeBlockArrays(self) -> int: ...
|
||||
def GetNumberOfEdgeMapArrays(self) -> int: ...
|
||||
def GetNumberOfEdgeResultArrays(self) -> int: ...
|
||||
def GetNumberOfEdgeSetArrays(self) -> int: ...
|
||||
def GetNumberOfEdgeSetResultArrays(self) -> int: ...
|
||||
def GetNumberOfEdgesInFile(self) -> int: ...
|
||||
def GetNumberOfElementBlockArrays(self) -> int: ...
|
||||
def GetNumberOfElementMapArrays(self) -> int: ...
|
||||
def GetNumberOfElementResultArrays(self) -> int: ...
|
||||
def GetNumberOfElementSetArrays(self) -> int: ...
|
||||
def GetNumberOfElementSetResultArrays(self) -> int: ...
|
||||
def GetNumberOfElementsInFile(self) -> int: ...
|
||||
def GetNumberOfEntriesInObject(self, objectType:int, objectIndex:int) -> int: ...
|
||||
def GetNumberOfFaceBlockArrays(self) -> int: ...
|
||||
def GetNumberOfFaceMapArrays(self) -> int: ...
|
||||
def GetNumberOfFaceResultArrays(self) -> int: ...
|
||||
def GetNumberOfFaceSetArrays(self) -> int: ...
|
||||
def GetNumberOfFaceSetResultArrays(self) -> int: ...
|
||||
def GetNumberOfFacesInFile(self) -> int: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def GetNumberOfGlobalResultArrays(self) -> int: ...
|
||||
def GetNumberOfHierarchyArrays(self) -> int: ...
|
||||
def GetNumberOfMaterialArrays(self) -> int: ...
|
||||
def GetNumberOfNodeMapArrays(self) -> int: ...
|
||||
def GetNumberOfNodeSetArrays(self) -> int: ...
|
||||
def GetNumberOfNodeSetResultArrays(self) -> int: ...
|
||||
def GetNumberOfNodes(self) -> int: ...
|
||||
def GetNumberOfNodesInFile(self) -> int: ...
|
||||
def GetNumberOfObjectArrayComponents(self, objectType:int, arrayIndex:int) -> int: ...
|
||||
def GetNumberOfObjectArrays(self, objectType:int) -> int: ...
|
||||
def GetNumberOfObjectAttributes(self, objectType:int, objectIndex:int) -> int: ...
|
||||
def GetNumberOfObjects(self, objectType:int) -> int: ...
|
||||
def GetNumberOfPartArrays(self) -> int: ...
|
||||
def GetNumberOfPointResultArrays(self) -> int: ...
|
||||
def GetNumberOfSideSetArrays(self) -> int: ...
|
||||
def GetNumberOfSideSetResultArrays(self) -> int: ...
|
||||
def GetNumberOfTimeSteps(self) -> int: ...
|
||||
def GetObjectArrayIndex(self, objectType:int, arrayName:str) -> int: ...
|
||||
def GetObjectArrayName(self, objectType:int, arrayIndex:int) -> str: ...
|
||||
@overload
|
||||
def GetObjectArrayStatus(self, objectType:int, arrayIndex:int) -> int: ...
|
||||
@overload
|
||||
def GetObjectArrayStatus(self, objectType:int, arrayName:str) -> int: ...
|
||||
def GetObjectAttributeIndex(self, objectType:int, objectIndex:int, attribName:str) -> int: ...
|
||||
def GetObjectAttributeName(self, objectType:int, objectIndex:int, attribIndex:int) -> str: ...
|
||||
@overload
|
||||
def GetObjectAttributeStatus(self, objectType:int, objectIndex:int, attribIndex:int) -> int: ...
|
||||
@overload
|
||||
def GetObjectAttributeStatus(self, objectType:int, objectIndex:int, attribName:str) -> int: ...
|
||||
def GetObjectId(self, objectType:int, objectIndex:int) -> int: ...
|
||||
@staticmethod
|
||||
def GetObjectIdArrayName() -> str: ...
|
||||
@overload
|
||||
def GetObjectIndex(self, objectType:int, objectName:str) -> int: ...
|
||||
@overload
|
||||
def GetObjectIndex(self, objectType:int, id:int) -> int: ...
|
||||
@overload
|
||||
def GetObjectName(self, objectType:int, objectIndex:int) -> str: ...
|
||||
@overload
|
||||
def GetObjectName(self) -> str: ...
|
||||
@overload
|
||||
def GetObjectStatus(self, objectType:int, objectIndex:int) -> int: ...
|
||||
@overload
|
||||
def GetObjectStatus(self, objectType:int, objectName:str) -> int: ...
|
||||
def GetObjectTypeFromName(self, name:str) -> int: ...
|
||||
def GetObjectTypeName(self, __a:int) -> str: ...
|
||||
def GetPartArrayID(self, name:str) -> int: ...
|
||||
def GetPartArrayName(self, arrayIdx:int) -> str: ...
|
||||
@overload
|
||||
def GetPartArrayStatus(self, index:int) -> int: ...
|
||||
@overload
|
||||
def GetPartArrayStatus(self, __a:str) -> int: ...
|
||||
def GetPartBlockInfo(self, arrayIdx:int) -> str: ...
|
||||
@staticmethod
|
||||
def GetPedigreeEdgeIdArrayName() -> str: ...
|
||||
@staticmethod
|
||||
def GetPedigreeElementIdArrayName() -> str: ...
|
||||
@staticmethod
|
||||
def GetPedigreeFaceIdArrayName() -> str: ...
|
||||
@staticmethod
|
||||
def GetPedigreeNodeIdArrayName() -> str: ...
|
||||
def GetPointResultArrayName(self, index:int) -> str: ...
|
||||
def GetPointResultArrayStatus(self, name:str) -> int: ...
|
||||
def GetSIL(self) -> 'vtkGraph': ...
|
||||
def GetSILUpdateStamp(self) -> int: ...
|
||||
def GetSideSetArrayName(self, index:int) -> str: ...
|
||||
def GetSideSetArrayStatus(self, name:str) -> int: ...
|
||||
def GetSideSetResultArrayName(self, index:int) -> str: ...
|
||||
def GetSideSetResultArrayStatus(self, name:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetSideSetSourceElementIdArrayName() -> str: ...
|
||||
@staticmethod
|
||||
def GetSideSetSourceElementSideArrayName() -> str: ...
|
||||
def GetSqueezePoints(self) -> bool: ...
|
||||
def GetTimeSeriesData(self, ID:int, vName:str, vType:str, result:'vtkFloatArray') -> int: ...
|
||||
def GetTimeStep(self) -> int: ...
|
||||
def GetTimeStepRange(self) -> Tuple[int, int]: ...
|
||||
def GetTitle(self) -> str: ...
|
||||
def GetTotalNumberOfEdges(self) -> int: ...
|
||||
def GetTotalNumberOfElements(self) -> int: ...
|
||||
def GetTotalNumberOfFaces(self) -> int: ...
|
||||
def GetTotalNumberOfNodes(self) -> int: ...
|
||||
def GetUseLegacyBlockNames(self) -> bool: ...
|
||||
def GetVariableID(self, type:str, name:str) -> int: ...
|
||||
def GetXMLFileName(self) -> str: ...
|
||||
def HasModeShapesOff(self) -> None: ...
|
||||
def HasModeShapesOn(self) -> None: ...
|
||||
def IgnoreFileTimeOff(self) -> None: ...
|
||||
def IgnoreFileTimeOn(self) -> None: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def IsValidVariable(self, type:str, name:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkExodusIIReader': ...
|
||||
def Reset(self) -> None: ...
|
||||
def ResetCache(self) -> None: ...
|
||||
def ResetSettings(self) -> None: ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkExodusIIReader': ...
|
||||
def SetAllArrayStatus(self, otype:int, status:int) -> None: ...
|
||||
def SetAnimateModeShapes(self, flag:int) -> None: ...
|
||||
def SetApplyDisplacements(self, d:int) -> None: ...
|
||||
@overload
|
||||
def SetAssemblyArrayStatus(self, index:int, flag:int) -> None: ...
|
||||
@overload
|
||||
def SetAssemblyArrayStatus(self, __a:str, flag:int) -> None: ...
|
||||
def SetCacheSize(self, CacheSize:float) -> None: ...
|
||||
def SetDisplacementMagnitude(self, s:float) -> None: ...
|
||||
def SetDisplayType(self, type:int) -> None: ...
|
||||
def SetEdgeBlockArrayStatus(self, name:str, flag:int) -> None: ...
|
||||
def SetEdgeMapArrayStatus(self, name:str, flag:int) -> None: ...
|
||||
def SetEdgeResultArrayStatus(self, name:str, flag:int) -> None: ...
|
||||
def SetEdgeSetArrayStatus(self, name:str, flag:int) -> None: ...
|
||||
def SetEdgeSetResultArrayStatus(self, name:str, flag:int) -> None: ...
|
||||
def SetElementBlockArrayStatus(self, name:str, flag:int) -> None: ...
|
||||
def SetElementMapArrayStatus(self, name:str, flag:int) -> None: ...
|
||||
def SetElementResultArrayStatus(self, name:str, flag:int) -> None: ...
|
||||
def SetElementSetArrayStatus(self, name:str, flag:int) -> None: ...
|
||||
def SetElementSetResultArrayStatus(self, name:str, flag:int) -> None: ...
|
||||
def SetFaceBlockArrayStatus(self, name:str, flag:int) -> None: ...
|
||||
def SetFaceMapArrayStatus(self, name:str, flag:int) -> None: ...
|
||||
def SetFaceResultArrayStatus(self, name:str, flag:int) -> None: ...
|
||||
def SetFaceSetArrayStatus(self, name:str, flag:int) -> None: ...
|
||||
def SetFaceSetResultArrayStatus(self, name:str, flag:int) -> None: ...
|
||||
def SetFileId(self, f:int) -> None: ...
|
||||
def SetFileName(self, fname:str) -> None: ...
|
||||
def SetGenerateFileIdArray(self, f:int) -> None: ...
|
||||
def SetGenerateGlobalElementIdArray(self, g:int) -> None: ...
|
||||
def SetGenerateGlobalNodeIdArray(self, g:int) -> None: ...
|
||||
def SetGenerateImplicitElementIdArray(self, g:int) -> None: ...
|
||||
def SetGenerateImplicitNodeIdArray(self, g:int) -> None: ...
|
||||
def SetGenerateObjectIdCellArray(self, g:int) -> None: ...
|
||||
def SetGlobalResultArrayStatus(self, name:str, flag:int) -> None: ...
|
||||
def SetHasModeShapes(self, ms:int) -> None: ...
|
||||
@overload
|
||||
def SetHierarchyArrayStatus(self, index:int, flag:int) -> None: ...
|
||||
@overload
|
||||
def SetHierarchyArrayStatus(self, __a:str, flag:int) -> None: ...
|
||||
def SetIgnoreFileTime(self, flag:bool) -> None: ...
|
||||
@overload
|
||||
def SetMaterialArrayStatus(self, index:int, flag:int) -> None: ...
|
||||
@overload
|
||||
def SetMaterialArrayStatus(self, __a:str, flag:int) -> None: ...
|
||||
def SetModeShape(self, val:int) -> None: ...
|
||||
def SetModeShapeTime(self, phase:float) -> None: ...
|
||||
def SetNodeMapArrayStatus(self, name:str, flag:int) -> None: ...
|
||||
def SetNodeSetArrayStatus(self, name:str, flag:int) -> None: ...
|
||||
def SetNodeSetResultArrayStatus(self, name:str, flag:int) -> None: ...
|
||||
@overload
|
||||
def SetObjectArrayStatus(self, objectType:int, arrayIndex:int, status:int) -> None: ...
|
||||
@overload
|
||||
def SetObjectArrayStatus(self, objectType:int, arrayName:str, status:int) -> None: ...
|
||||
@overload
|
||||
def SetObjectAttributeStatus(self, objectType:int, objectIndex:int, attribIndex:int, status:int) -> None: ...
|
||||
@overload
|
||||
def SetObjectAttributeStatus(self, objectType:int, objectIndex:int, attribName:str, status:int) -> None: ...
|
||||
@overload
|
||||
def SetObjectStatus(self, objectType:int, objectIndex:int, status:int) -> None: ...
|
||||
@overload
|
||||
def SetObjectStatus(self, objectType:int, objectName:str, status:int) -> None: ...
|
||||
@overload
|
||||
def SetPartArrayStatus(self, index:int, flag:int) -> None: ...
|
||||
@overload
|
||||
def SetPartArrayStatus(self, __a:str, flag:int) -> None: ...
|
||||
def SetPointResultArrayStatus(self, name:str, flag:int) -> None: ...
|
||||
def SetSideSetArrayStatus(self, name:str, flag:int) -> None: ...
|
||||
def SetSideSetResultArrayStatus(self, name:str, flag:int) -> None: ...
|
||||
def SetSqueezePoints(self, sp:bool) -> None: ...
|
||||
def SetTimeStep(self, _arg:int) -> None: ...
|
||||
def SetUseLegacyBlockNames(self, _arg:bool) -> None: ...
|
||||
def SetXMLFileName(self, fname:str) -> None: ...
|
||||
def UseLegacyBlockNamesOff(self) -> None: ...
|
||||
def UseLegacyBlockNamesOn(self) -> None: ...
|
||||
|
||||
class vtkExodusIIReaderParser(vtkmodules.vtkIOXMLParser.vtkXMLParser):
|
||||
sil:'getset_descriptor'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def GetBlockName(self, id:int) -> str: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def GetSIL(self) -> 'vtkMutableDirectedGraph': ...
|
||||
def Go(self, filename:str) -> None: ...
|
||||
def HasInformationAboutBlock(self, id:int) -> bool: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkExodusIIReaderParser': ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkExodusIIReaderParser': ...
|
||||
|
||||
class vtkExodusIIWriter(vtkmodules.vtkIOCore.vtkWriter):
|
||||
block_id_array_name:'getset_descriptor'
|
||||
file_name:'getset_descriptor'
|
||||
ghost_level:'getset_descriptor'
|
||||
ignore_meta_data_warning:'getset_descriptor'
|
||||
model_metadata:'getset_descriptor'
|
||||
store_doubles:'getset_descriptor'
|
||||
write_all_time_steps:'getset_descriptor'
|
||||
write_out_block_id_array:'getset_descriptor'
|
||||
write_out_global_element_id_array:'getset_descriptor'
|
||||
write_out_global_node_id_array:'getset_descriptor'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def GetBlockIdArrayName(self) -> str: ...
|
||||
def GetFileName(self) -> str: ...
|
||||
def GetGhostLevel(self) -> int: ...
|
||||
def GetIgnoreMetaDataWarning(self) -> bool: ...
|
||||
def GetModelMetadata(self) -> 'vtkModelMetadata': ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def GetStoreDoubles(self) -> int: ...
|
||||
def GetWriteAllTimeSteps(self) -> int: ...
|
||||
def GetWriteOutBlockIdArray(self) -> int: ...
|
||||
def GetWriteOutGlobalElementIdArray(self) -> int: ...
|
||||
def GetWriteOutGlobalNodeIdArray(self) -> int: ...
|
||||
def IgnoreMetaDataWarningOff(self) -> None: ...
|
||||
def IgnoreMetaDataWarningOn(self) -> None: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkExodusIIWriter': ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkExodusIIWriter': ...
|
||||
def SetBlockIdArrayName(self, _arg:str) -> None: ...
|
||||
def SetFileName(self, _arg:str) -> None: ...
|
||||
def SetGhostLevel(self, _arg:int) -> None: ...
|
||||
def SetIgnoreMetaDataWarning(self, _arg:bool) -> None: ...
|
||||
def SetModelMetadata(self, __a:'vtkModelMetadata') -> None: ...
|
||||
def SetStoreDoubles(self, _arg:int) -> None: ...
|
||||
def SetWriteAllTimeSteps(self, _arg:int) -> None: ...
|
||||
def SetWriteOutBlockIdArray(self, _arg:int) -> None: ...
|
||||
def SetWriteOutGlobalElementIdArray(self, _arg:int) -> None: ...
|
||||
def SetWriteOutGlobalNodeIdArray(self, _arg:int) -> None: ...
|
||||
def WriteAllTimeStepsOff(self) -> None: ...
|
||||
def WriteAllTimeStepsOn(self) -> None: ...
|
||||
def WriteOutBlockIdArrayOff(self) -> None: ...
|
||||
def WriteOutBlockIdArrayOn(self) -> None: ...
|
||||
def WriteOutGlobalElementIdArrayOff(self) -> None: ...
|
||||
def WriteOutGlobalElementIdArrayOn(self) -> None: ...
|
||||
def WriteOutGlobalNodeIdArrayOff(self) -> None: ...
|
||||
def WriteOutGlobalNodeIdArrayOn(self) -> None: ...
|
||||
|
||||
class vtkModelMetadata(vtkmodules.vtkCommonCore.vtkObject):
|
||||
all_variables_defined_in_all_blocks:'getset_descriptor'
|
||||
block_attributes:'getset_descriptor'
|
||||
block_attributes_index:'getset_descriptor'
|
||||
block_element_id_list:'getset_descriptor'
|
||||
block_element_id_list_index:'getset_descriptor'
|
||||
block_ids:'getset_descriptor'
|
||||
block_nodes_per_element:'getset_descriptor'
|
||||
block_number_of_attributes_per_element:'getset_descriptor'
|
||||
block_number_of_elements:'getset_descriptor'
|
||||
block_property_value:'getset_descriptor'
|
||||
dimension:'getset_descriptor'
|
||||
element_variable_number_of_components:'getset_descriptor'
|
||||
element_variable_truth_table:'getset_descriptor'
|
||||
global_variable_value:'getset_descriptor'
|
||||
map_to_original_element_variable_names:'getset_descriptor'
|
||||
map_to_original_node_variable_names:'getset_descriptor'
|
||||
node_set_distribution_factor_index:'getset_descriptor'
|
||||
node_set_distribution_factors:'getset_descriptor'
|
||||
node_set_ids:'getset_descriptor'
|
||||
node_set_names:'getset_descriptor'
|
||||
node_set_node_id_list:'getset_descriptor'
|
||||
node_set_node_id_list_index:'getset_descriptor'
|
||||
node_set_number_of_distribution_factors:'getset_descriptor'
|
||||
node_set_property_value:'getset_descriptor'
|
||||
node_set_size:'getset_descriptor'
|
||||
node_variable_number_of_components:'getset_descriptor'
|
||||
number_of_block_properties:'getset_descriptor'
|
||||
number_of_blocks:'getset_descriptor'
|
||||
number_of_element_variables:'getset_descriptor'
|
||||
number_of_global_variables:'getset_descriptor'
|
||||
number_of_information_lines:'getset_descriptor'
|
||||
number_of_node_set_properties:'getset_descriptor'
|
||||
number_of_node_sets:'getset_descriptor'
|
||||
number_of_node_variables:'getset_descriptor'
|
||||
number_of_side_set_properties:'getset_descriptor'
|
||||
number_of_side_sets:'getset_descriptor'
|
||||
number_of_time_steps:'getset_descriptor'
|
||||
original_number_of_element_variables:'getset_descriptor'
|
||||
original_number_of_node_variables:'getset_descriptor'
|
||||
side_set_distribution_factor_index:'getset_descriptor'
|
||||
side_set_distribution_factors:'getset_descriptor'
|
||||
side_set_element_list:'getset_descriptor'
|
||||
side_set_ids:'getset_descriptor'
|
||||
side_set_list_index:'getset_descriptor'
|
||||
side_set_names:'getset_descriptor'
|
||||
side_set_num_df_per_side:'getset_descriptor'
|
||||
side_set_number_of_distribution_factors:'getset_descriptor'
|
||||
side_set_property_value:'getset_descriptor'
|
||||
side_set_side_list:'getset_descriptor'
|
||||
side_set_size:'getset_descriptor'
|
||||
size_block_attribute_array:'getset_descriptor'
|
||||
sum_dist_fact_per_node_set:'getset_descriptor'
|
||||
sum_dist_fact_per_side_set:'getset_descriptor'
|
||||
sum_elements_per_block:'getset_descriptor'
|
||||
sum_nodes_per_node_set:'getset_descriptor'
|
||||
sum_sides_per_side_set:'getset_descriptor'
|
||||
time_step_index:'getset_descriptor'
|
||||
time_step_values:'getset_descriptor'
|
||||
title:'getset_descriptor'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def AllVariablesDefinedInAllBlocksOff(self) -> None: ...
|
||||
def AllVariablesDefinedInAllBlocksOn(self) -> None: ...
|
||||
def FreeAllGlobalData(self) -> None: ...
|
||||
def FreeAllLocalData(self) -> None: ...
|
||||
def FreeBlockDependentData(self) -> None: ...
|
||||
def FreeOriginalElementVariableNames(self) -> None: ...
|
||||
def FreeOriginalNodeVariableNames(self) -> None: ...
|
||||
def FreeUsedElementVariableNames(self) -> None: ...
|
||||
def FreeUsedElementVariables(self) -> None: ...
|
||||
def FreeUsedNodeVariableNames(self) -> None: ...
|
||||
def FreeUsedNodeVariables(self) -> None: ...
|
||||
def GetAllVariablesDefinedInAllBlocks(self) -> int: ...
|
||||
def GetBlockAttributes(self) -> Pointer: ...
|
||||
def GetBlockAttributesIndex(self) -> Pointer: ...
|
||||
def GetBlockElementIdList(self) -> Pointer: ...
|
||||
def GetBlockElementIdListIndex(self) -> Pointer: ...
|
||||
def GetBlockIds(self) -> Pointer: ...
|
||||
def GetBlockNodesPerElement(self) -> Pointer: ...
|
||||
def GetBlockNumberOfAttributesPerElement(self) -> Pointer: ...
|
||||
def GetBlockNumberOfElements(self) -> Pointer: ...
|
||||
def GetBlockPropertyValue(self) -> Pointer: ...
|
||||
def GetDimension(self) -> int: ...
|
||||
def GetElementVariableNumberOfComponents(self) -> Pointer: ...
|
||||
def GetElementVariableTruthTable(self) -> Pointer: ...
|
||||
def GetGlobalVariableValue(self) -> Pointer: ...
|
||||
def GetMapToOriginalElementVariableNames(self) -> Pointer: ...
|
||||
def GetMapToOriginalNodeVariableNames(self) -> Pointer: ...
|
||||
def GetNodeSetDistributionFactorIndex(self) -> Pointer: ...
|
||||
def GetNodeSetDistributionFactors(self) -> Pointer: ...
|
||||
def GetNodeSetIds(self) -> Pointer: ...
|
||||
def GetNodeSetNames(self) -> 'vtkStringArray': ...
|
||||
def GetNodeSetNodeIdList(self) -> Pointer: ...
|
||||
def GetNodeSetNodeIdListIndex(self) -> Pointer: ...
|
||||
def GetNodeSetNumberOfDistributionFactors(self) -> Pointer: ...
|
||||
def GetNodeSetPropertyValue(self) -> Pointer: ...
|
||||
def GetNodeSetSize(self) -> Pointer: ...
|
||||
def GetNodeVariableNumberOfComponents(self) -> Pointer: ...
|
||||
def GetNumberOfBlockProperties(self) -> int: ...
|
||||
def GetNumberOfBlocks(self) -> int: ...
|
||||
def GetNumberOfElementVariables(self) -> int: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def GetNumberOfGlobalVariables(self) -> int: ...
|
||||
def GetNumberOfInformationLines(self) -> int: ...
|
||||
def GetNumberOfNodeSetProperties(self) -> int: ...
|
||||
def GetNumberOfNodeSets(self) -> int: ...
|
||||
def GetNumberOfNodeVariables(self) -> int: ...
|
||||
def GetNumberOfSideSetProperties(self) -> int: ...
|
||||
def GetNumberOfSideSets(self) -> int: ...
|
||||
def GetNumberOfTimeSteps(self) -> int: ...
|
||||
def GetOriginalNumberOfElementVariables(self) -> int: ...
|
||||
def GetOriginalNumberOfNodeVariables(self) -> int: ...
|
||||
def GetSideSetDistributionFactorIndex(self) -> Pointer: ...
|
||||
def GetSideSetDistributionFactors(self) -> Pointer: ...
|
||||
def GetSideSetElementList(self) -> Pointer: ...
|
||||
def GetSideSetIds(self) -> Pointer: ...
|
||||
def GetSideSetListIndex(self) -> Pointer: ...
|
||||
def GetSideSetNames(self) -> 'vtkStringArray': ...
|
||||
def GetSideSetNumDFPerSide(self) -> Pointer: ...
|
||||
def GetSideSetNumberOfDistributionFactors(self) -> Pointer: ...
|
||||
def GetSideSetPropertyValue(self) -> Pointer: ...
|
||||
def GetSideSetSideList(self) -> Pointer: ...
|
||||
def GetSideSetSize(self) -> Pointer: ...
|
||||
def GetSizeBlockAttributeArray(self) -> int: ...
|
||||
def GetSumDistFactPerNodeSet(self) -> int: ...
|
||||
def GetSumDistFactPerSideSet(self) -> int: ...
|
||||
def GetSumElementsPerBlock(self) -> int: ...
|
||||
def GetSumNodesPerNodeSet(self) -> int: ...
|
||||
def GetSumSidesPerSideSet(self) -> int: ...
|
||||
def GetTimeStepIndex(self) -> int: ...
|
||||
def GetTimeStepValues(self) -> Pointer: ...
|
||||
def GetTitle(self) -> str: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkModelMetadata': ...
|
||||
def PrintGlobalInformation(self) -> None: ...
|
||||
def PrintLocalInformation(self) -> None: ...
|
||||
def Reset(self) -> None: ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkModelMetadata': ...
|
||||
def SetAllVariablesDefinedInAllBlocks(self, _arg:int) -> None: ...
|
||||
def SetBlockAttributes(self, __a:MutableSequence[float]) -> None: ...
|
||||
def SetBlockElementIdList(self, __a:MutableSequence[int]) -> None: ...
|
||||
def SetBlockIds(self, __a:MutableSequence[int]) -> None: ...
|
||||
def SetBlockNodesPerElement(self, __a:MutableSequence[int]) -> None: ...
|
||||
def SetBlockNumberOfAttributesPerElement(self, natts:MutableSequence[int]) -> int: ...
|
||||
def SetBlockNumberOfElements(self, nelts:MutableSequence[int]) -> int: ...
|
||||
def SetBlockPropertyValue(self, __a:MutableSequence[int]) -> None: ...
|
||||
def SetElementVariableTruthTable(self, __a:MutableSequence[int]) -> None: ...
|
||||
def SetGlobalVariableValue(self, f:MutableSequence[float]) -> None: ...
|
||||
def SetNodeSetDistributionFactors(self, __a:MutableSequence[float]) -> None: ...
|
||||
def SetNodeSetIds(self, __a:MutableSequence[int]) -> None: ...
|
||||
def SetNodeSetNames(self, names:'vtkStringArray') -> None: ...
|
||||
def SetNodeSetNodeIdList(self, __a:MutableSequence[int]) -> None: ...
|
||||
def SetNodeSetNumberOfDistributionFactors(self, __a:MutableSequence[int]) -> None: ...
|
||||
def SetNodeSetPropertyValue(self, __a:MutableSequence[int]) -> None: ...
|
||||
def SetNodeSetSize(self, __a:MutableSequence[int]) -> None: ...
|
||||
def SetNumberOfBlocks(self, _arg:int) -> None: ...
|
||||
def SetNumberOfNodeSets(self, _arg:int) -> None: ...
|
||||
def SetNumberOfSideSets(self, _arg:int) -> None: ...
|
||||
def SetSideSetDistributionFactors(self, __a:MutableSequence[float]) -> None: ...
|
||||
def SetSideSetElementList(self, __a:MutableSequence[int]) -> None: ...
|
||||
def SetSideSetIds(self, __a:MutableSequence[int]) -> None: ...
|
||||
def SetSideSetNames(self, names:'vtkStringArray') -> None: ...
|
||||
def SetSideSetNumDFPerSide(self, numNodes:MutableSequence[int]) -> None: ...
|
||||
def SetSideSetNumberOfDistributionFactors(self, df:MutableSequence[int]) -> int: ...
|
||||
def SetSideSetPropertyValue(self, __a:MutableSequence[int]) -> None: ...
|
||||
def SetSideSetSideList(self, __a:MutableSequence[int]) -> None: ...
|
||||
def SetSideSetSize(self, sizes:MutableSequence[int]) -> int: ...
|
||||
def SetSumNodesPerNodeSet(self, _arg:int) -> None: ...
|
||||
def SetSumSidesPerSideSet(self, _arg:int) -> None: ...
|
||||
def SetTimeStepIndex(self, _arg:int) -> None: ...
|
||||
def SetTimeSteps(self, numberOfTimeSteps:int, timeStepValues:MutableSequence[float]) -> None: ...
|
||||
def SetTitle(self, _arg:str) -> None: ...
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,38 @@
|
||||
from typing import overload, Any, Callable, TypeVar, Union
|
||||
from typing import Tuple, List, Sequence, MutableSequence
|
||||
|
||||
Callback = Union[Callable[..., None], None]
|
||||
Buffer = TypeVar('Buffer')
|
||||
Pointer = TypeVar('Pointer')
|
||||
Template = TypeVar('Template')
|
||||
|
||||
import vtkmodules.vtkCommonCore
|
||||
import vtkmodules.vtkCommonExecutionModel
|
||||
|
||||
class vtkFDSReader(vtkmodules.vtkCommonExecutionModel.vtkPartitionedDataSetCollectionAlgorithm):
|
||||
assembly:'getset_descriptor'
|
||||
assembly_tag:'getset_descriptor'
|
||||
file_name:'getset_descriptor'
|
||||
stream:'getset_descriptor'
|
||||
time_tolerance:'getset_descriptor'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def AddSelector(self, selector:str) -> bool: ...
|
||||
def ClearSelectors(self) -> None: ...
|
||||
def GetAssembly(self) -> 'vtkDataAssembly': ...
|
||||
def GetAssemblyTag(self) -> int: ...
|
||||
def GetFileName(self) -> str: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def GetStream(self) -> 'vtkResourceStream': ...
|
||||
def GetTimeTolerance(self) -> float: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkFDSReader': ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkFDSReader': ...
|
||||
def SetFileName(self, _arg:str) -> None: ...
|
||||
def SetStream(self, stream:'vtkResourceStream') -> None: ...
|
||||
def SetTimeTolerance(self, _arg:float) -> None: ...
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
from typing import overload, Any, Callable, TypeVar, Union
|
||||
from typing import Tuple, List, Sequence, MutableSequence
|
||||
|
||||
Callback = Union[Callable[..., None], None]
|
||||
Buffer = TypeVar('Buffer')
|
||||
Pointer = TypeVar('Pointer')
|
||||
Template = TypeVar('Template')
|
||||
|
||||
import vtkmodules.vtkCommonCore
|
||||
import vtkmodules.vtkCommonExecutionModel
|
||||
|
||||
class vtkH5RageReader(vtkmodules.vtkCommonExecutionModel.vtkImageAlgorithm):
|
||||
current_time_step:'getset_descriptor'
|
||||
file_name:'getset_descriptor'
|
||||
number_of_point_arrays:'getset_descriptor'
|
||||
output:'getset_descriptor'
|
||||
def __init__(self, **properties:Any) -> None: ...
|
||||
def DisableAllPointArrays(self) -> None: ...
|
||||
def EnableAllPointArrays(self) -> None: ...
|
||||
def GetCurrentTimeStep(self) -> int: ...
|
||||
def GetFileName(self) -> str: ...
|
||||
def GetNumberOfGenerationsFromBase(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def GetNumberOfGenerationsFromBaseType(type:str) -> int: ...
|
||||
def GetNumberOfPointArrays(self) -> int: ...
|
||||
@overload
|
||||
def GetOutput(self) -> 'vtkImageData': ...
|
||||
@overload
|
||||
def GetOutput(self, index:int) -> 'vtkImageData': ...
|
||||
def GetPointArrayName(self, index:int) -> str: ...
|
||||
def GetPointArrayStatus(self, name:str) -> int: ...
|
||||
def IsA(self, type:str) -> int: ...
|
||||
@staticmethod
|
||||
def IsTypeOf(type:str) -> int: ...
|
||||
def NewInstance(self) -> 'vtkH5RageReader': ...
|
||||
@staticmethod
|
||||
def SafeDownCast(o:'vtkObjectBase') -> 'vtkH5RageReader': ...
|
||||
def SetCurrentTimeStep(self, _arg:int) -> None: ...
|
||||
def SetFileName(self, _arg:str) -> None: ...
|
||||
def SetPointArrayStatus(self, name:str, status:int) -> None: ...
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user