316 lines
9.0 KiB
Python
316 lines
9.0 KiB
Python
|
|
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)
|