| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | """Methods to verify if the python VTK module is the correct one |
| | |
| | FreeCAD is linked with VTK libraries during its build process. To use the VTK |
| | python module and pass objects between python and c++ the compiled module library |
| | needs to be linked to the exact same vtk library as FreeCAD is. This is ensured by |
| | installing VTK via linux app managers: All known distros install the python side |
| | packages together with vtk libs. Libpack and other OS systems ensure this too. |
| | |
| | However, if a vtk python package is installed manually, e.g. by "pip install vtk", |
| | it could be found instead of the system module. This python API brings its own |
| | set of VTK libs, and hence object passing in FreeCAD fails. (Note: import and |
| | pure vtk python code still works, only passing to c++ fails) |
| | |
| | This file provides functions that detect this situation and inform the user. |
| | Additionally we try to find the correct module in the path and offer to use |
| | it instead. |
| | |
| | Note that this problem occurs with all "compiled binary" python APIs, also |
| | with PySide. It is the users responsibility to handle his python path and keep |
| | it clean/working. The functions provided here are a workaround only. |
| | """ |
| |
|
| | __title__ = "FEM GUI vtk python module check" |
| | __author__ = "Stefan Tröger" |
| | __url__ = "https://www.freecad.org" |
| |
|
| |
|
| | |
| | |
| |
|
| | __user_input_received = False |
| |
|
| |
|
| | def vtk_module_compatible(): |
| | |
| | |
| |
|
| | |
| | |
| | unload = not _vtk_is_loaded() |
| |
|
| | import Fem |
| | from vtkmodules.vtkCommonCore import vtkVersion, vtkBitArray |
| |
|
| | |
| | if Fem.getVtkVersion() != vtkVersion.GetVTKVersion(): |
| | return False |
| |
|
| | |
| | result = Fem.isVtkCompatible(vtkBitArray()) |
| |
|
| | if unload: |
| | |
| | _unload_vtk_modules() |
| |
|
| | return result |
| |
|
| |
|
| | def _vtk_is_loaded(): |
| | import sys |
| |
|
| | return any("vtkmodules" in module for module in sys.modules) |
| |
|
| |
|
| | def _unload_vtk_modules(): |
| | |
| | |
| |
|
| | import sys |
| |
|
| | for module in sys.modules.copy(): |
| | if "vtkmodules" in module: |
| | del sys.modules[module] |
| |
|
| |
|
| | def _find_compatible_module(): |
| | |
| |
|
| | import Fem |
| | import sys |
| |
|
| | |
| | _unload_vtk_modules() |
| |
|
| | path = sys.path.copy() |
| |
|
| | for folder in reversed(path): |
| | try: |
| | |
| | sys.path = [folder] |
| | if vtk_module_compatible(): |
| | |
| | _unload_vtk_modules() |
| | sys.path = path |
| | return folder |
| |
|
| | except: |
| | continue |
| |
|
| | |
| | sys.path = path |
| | return None |
| |
|
| |
|
| | def _load_vtk_from(folder): |
| |
|
| | import sys |
| |
|
| | path = sys.path |
| | try: |
| | sys.path = [folder] |
| | import vtkmodules |
| | finally: |
| | sys.path = path |
| |
|
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | def vtk_module_handling(): |
| |
|
| | import sys |
| | import FreeCAD |
| |
|
| | if not "BUILD_FEM_VTK_PYTHON" in FreeCAD.__cmake__: |
| | |
| | return |
| |
|
| | |
| | global __user_input_received |
| | if __user_input_received: |
| | return |
| | __user_input_received = True |
| |
|
| | loaded = _vtk_is_loaded() |
| |
|
| | |
| | if not vtk_module_compatible(): |
| |
|
| | if not FreeCAD.GuiUp: |
| | FreeCAD.Console.PrintError( |
| | "FEM: VTK Python module is not compatible with internal VTK library" |
| | ) |
| | return |
| |
|
| | import FreeCAD, Fem |
| | from vtkmodules.vtkCommonCore import vtkVersion |
| | import inspect |
| | from PySide import QtGui |
| |
|
| | translate = FreeCAD.Qt.translate |
| |
|
| | path = inspect.getfile(vtkVersion) |
| | path = path[: path.find("vtkmodules")] |
| |
|
| | message = translate( |
| | "FEM", |
| | ( |
| | "FreeCAD is linked to a different VTK library than the imported " |
| | "VTK Python module. This is incompatible and will lead to errors." |
| | "\n\nWrong python module is imported from: \n{}" |
| | ), |
| | ).format(path) |
| |
|
| | buttons = QtGui.QMessageBox.Discard |
| |
|
| | |
| | compatible_module = _find_compatible_module() |
| |
|
| | if compatible_module: |
| | |
| | message += translate("FEM", "\n\nCorrect module found in: \n{}").format( |
| | compatible_module |
| | ) |
| |
|
| | if not loaded: |
| | |
| | message += translate("FEM", "\n\nShould this module be loaded instead?") |
| |
|
| | buttons = QtGui.QMessageBox.Yes | QtGui.QMessageBox.No |
| |
|
| | else: |
| | message += translate( |
| | "FEM", |
| | ( |
| | "\n\nAs the wrong module was already loaded, a reload is not possible. " |
| | "Restart FreeCAD to get the option for loading this module." |
| | ), |
| | ) |
| |
|
| | else: |
| | message += translate( |
| | "FEM", "\n\nNo matching module was found in the current Python path." |
| | ) |
| |
|
| | |
| | import FreeCADGui |
| |
|
| | button = QtGui.QMessageBox.critical( |
| | FreeCADGui.getMainWindow(), |
| | translate("FEM", "VTK Python module conflict"), |
| | message, |
| | buttons=buttons, |
| | ) |
| |
|
| | if button == QtGui.QMessageBox.Yes: |
| | |
| | _load_vtk_from(compatible_module) |
| |
|
| |
|
| | |
| | |
| | def vtk_compatibility_abort(inform=True): |
| |
|
| | if not vtk_module_compatible(): |
| |
|
| | if inform: |
| | |
| | import FreeCAD |
| | import FreeCADGui |
| | from PySide import QtGui |
| |
|
| | translate = FreeCAD.Qt.translate |
| |
|
| | button = QtGui.QMessageBox.critical( |
| | FreeCADGui.getMainWindow(), |
| | translate("FEM", "VTK Python Module Conflict"), |
| | translate( |
| | "FEM", "This functionality is not available due to VTK Python module conflict" |
| | ), |
| | buttons=QtGui.QMessageBox.Discard, |
| | ) |
| |
|
| | return True |
| |
|
| | return False |
| |
|