Fem: make python filter build process more elegant

This commit is contained in:
Stefan Tröger
2025-04-14 20:48:58 +02:00
parent 9430bdde01
commit bbf5695562
8 changed files with 72 additions and 19 deletions

View File

@@ -64,9 +64,11 @@ macro(SetupSalomeSMESH)
set(BUILD_FEM_VTK ON)
# check if PythonWrapperCore was found (vtk 9 only)
# Check if PythonWrapperCore was found
# Note: vtk 9 only, as the implementations use the vtk modules introduced in 9.0
# VTK_WrappingPythonCore_FOUND is named differently for versions <9.0
if (${VTK_WrappingPythonCore_FOUND})
add_compile_definitions(BUILD_FEM_VTK_WRAPPER)
set(BUILD_FEM_VTK_PYTHON 1)
message(STATUS "VTK python wrapper: available")
else()
message(STATUS "VTK python wrapper: NOT available")

View File

@@ -35,7 +35,7 @@
#include "FemPostFilterPy.cpp"
// clang-format on
#ifdef BUILD_FEM_VTK_WRAPPER
#ifdef FC_USE_VTK_PYTHON
#include <vtkUnstructuredGrid.h>
#include <vtkPythonUtil.h>
#endif //BUILD_FEM_VTK
@@ -54,7 +54,7 @@ std::string FemPostFilterPy::representation() const
PyObject* FemPostFilterPy::addFilterPipeline(PyObject* args)
{
#ifdef BUILD_FEM_VTK_WRAPPER
#ifdef FC_USE_VTK_PYTHON
const char* name;
PyObject *source = nullptr;
PyObject *target = nullptr;
@@ -116,7 +116,7 @@ PyObject* FemPostFilterPy::getParentPostGroup(PyObject* args)
PyObject* FemPostFilterPy::getInputData(PyObject* args)
{
#ifdef BUILD_FEM_VTK_WRAPPER
#ifdef FC_USE_VTK_PYTHON
// we take no arguments
if (!PyArg_ParseTuple(args, "")) {
return nullptr;

View File

@@ -42,7 +42,7 @@
#include <vtkXMLUnstructuredGridReader.h>
#endif
#ifdef BUILD_FEM_VTK_WRAPPER
#ifdef FC_USE_VTK_PYTHON
#include <vtkPythonUtil.h>
#endif
@@ -166,7 +166,7 @@ int PropertyPostDataObject::getDataType()
PyObject* PropertyPostDataObject::getPyObject()
{
#ifdef BUILD_FEM_VTK_WRAPPER
#ifdef FC_USE_VTK_PYTHON
//create a copy first
auto copy = static_cast<PropertyPostDataObject*>(Copy());
@@ -182,9 +182,22 @@ PyObject* PropertyPostDataObject::getPyObject()
#endif
}
void PropertyPostDataObject::setPyObject(PyObject* /*value*/)
void PropertyPostDataObject::setPyObject(PyObject* value)
{
#ifdef FC_USE_VTK_PYTHON
vtkObjectBase *obj = vtkPythonUtil::GetPointerFromObject(value, "vtkDataObject");
if (!obj) {
throw Base::TypeError("Can only set vtkDataObject");
}
auto dobj = static_cast<vtkDataObject*>(obj);
createDataObjectByExternalType(dobj);
aboutToSetValue();
m_dataObject->DeepCopy(dobj);
hasSetValue();
#else
throw Base::NotImplementedError();
#endif
}
App::Property* PropertyPostDataObject::Copy() const

View File

@@ -1,6 +1,12 @@
if(BUILD_FEM_VTK)
add_definitions(-DFC_USE_VTK)
# we may use VTK but do not have the python wrappers available
if(BUILD_FEM_VTK_PYTHON)
add_definitions(-DFC_USE_VTK_PYTHON)
endif(BUILD_FEM_VTK_PYTHON)
endif(BUILD_FEM_VTK)
@@ -202,12 +208,18 @@ SET(FemObjects_SRCS
femobjects/mesh_netgen.py
femobjects/mesh_region.py
femobjects/mesh_result.py
femobjects/post_glyphfilter.py
femobjects/result_mechanical.py
femobjects/solver_calculix.py
femobjects/solver_ccxtools.py
)
if(BUILD_FEM_VTK_PYTHON)
SET(FemObjects_SRCS
${FemObjects_SRCS}
femobjects/post_glyphfilter.py
)
endif(BUILD_FEM_VTK_PYTHON)
SET(FemResult_SRCS
femresult/__init__.py
femresult/resulttools.py
@@ -605,12 +617,18 @@ SET(FemGuiTaskPanels_SRCS
femtaskpanels/task_mesh_group.py
femtaskpanels/task_mesh_region.py
femtaskpanels/task_mesh_netgen.py
femtaskpanels/task_post_glyphfilter.py
femtaskpanels/task_result_mechanical.py
femtaskpanels/task_solver_calculix.py
femtaskpanels/task_solver_ccxtools.py
)
if(BUILD_FEM_VTK_PYTHON)
SET(FemGuiTaskPanels_SRCS
${FemGuiTaskPanels_SRCS}
femtaskpanels/task_post_glyphfilter.py
)
endif(BUILD_FEM_VTK_PYTHON)
SET(FemGuiTests_SRCS
femtest/gui/__init__.py
femtest/gui/test_open.py
@@ -656,12 +674,18 @@ SET(FemGuiViewProvider_SRCS
femviewprovider/view_mesh_netgen.py
femviewprovider/view_mesh_region.py
femviewprovider/view_mesh_result.py
femviewprovider/view_post_glyphfilter.py
femviewprovider/view_result_mechanical.py
femviewprovider/view_solver_calculix.py
femviewprovider/view_solver_ccxtools.py
)
if(BUILD_FEM_VTK_PYTHON)
SET(FemGuiViewProvider_SRCS
${FemGuiViewProvider_SRCS}
femviewprovider/view_post_glyphfilter.py
)
endif(BUILD_FEM_VTK_PYTHON)
SET(FemGuiPreferencePages_SRCS
fempreferencepages/__init__.py
fempreferencepages/dlg_settings_netgen.py

View File

@@ -206,7 +206,7 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
<< "FEM_PostFilterCutFunction"
<< "FEM_PostFilterClipRegion"
<< "FEM_PostFilterContours"
#ifdef BUILD_FEM_VTK_WRAPPER
#ifdef FC_USE_VTK_PYTHON
<< "FEM_PostFilterGlyph"
#endif
<< "FEM_PostFilterDataAlongLine"
@@ -358,6 +358,9 @@ Gui::MenuItem* Workbench::setupMenuBar() const
<< "FEM_PostFilterCutFunction"
<< "FEM_PostFilterClipRegion"
<< "FEM_PostFilterContours"
#ifdef FC_USE_VTK_PYTHON
<< "FEM_PostFilterGlyph"
#endif
<< "FEM_PostFilterDataAlongLine"
<< "FEM_PostFilterLinearizedStresses"
<< "FEM_PostFilterDataAtPoint"

View File

@@ -652,7 +652,7 @@ def makePostVtkFilterContours(doc, base_vtk_result, name="VtkFilterContours"):
base_vtk_result.addObject(obj)
return obj
def makePostVtkFilterGlyph(doc, base_vtk_result, name="Glyph"):
def makePostFilterGlyph(doc, base_vtk_result, name="Glyph"):
"""makePostVtkFilterGlyph(document, [name]):
creates a FEM post processing filter that visualizes vector fields with glyphs
"""

View File

@@ -1225,7 +1225,7 @@ class _PostFilterGlyph(CommandManager):
self.accel = "F, G"
self.tooltip = Qt.QT_TRANSLATE_NOOP("FEM_PostFilterGlyph", "Post processing filter that adds glyphs to the mesh vertices for vertex data visualization")
self.is_active = "with_vtk_selresult"
self.do_activated = "add_filter"
self.do_activated = "add_filter_set_edit"
# the string in add command will be the page name on FreeCAD wiki
@@ -1282,4 +1282,6 @@ FreeCADGui.addCommand("FEM_SolverElmer", _SolverElmer())
FreeCADGui.addCommand("FEM_SolverMystran", _SolverMystran())
FreeCADGui.addCommand("FEM_SolverRun", _SolverRun())
FreeCADGui.addCommand("FEM_SolverZ88", _SolverZ88())
FreeCADGui.addCommand("FEM_PostFilterGlyph", _PostFilterGlyph())
if "BUILD_FEM_VTK_PYTHON" in FreeCAD.__cmake__:
FreeCADGui.addCommand("FEM_PostFilterGlyph", _PostFilterGlyph())

View File

@@ -148,8 +148,8 @@ class CommandManager:
self.add_obj_on_gui_selobj_set_edit(self.__class__.__name__.lstrip("_"))
elif self.do_activated == "add_obj_on_gui_selobj_expand_noset_edit":
self.add_obj_on_gui_selobj_expand_noset_edit(self.__class__.__name__.lstrip("_"))
elif self.do_activated == "add_filter":
self.add_filter(self.__class__.__name__.lstrip("_"))
elif self.do_activated == "add_filter_set_edit":
self.add_filter_set_edit(self.__class__.__name__.lstrip("_"))
# in all other cases Activated is implemented it the command class
def results_present(self):
@@ -377,7 +377,7 @@ class CommandManager:
# expand selobj in tree view
expandParentObject()
def add_filter(self, filtertype):
def add_filter_set_edit(self, filtertype):
# like add_obj_on_gui_selobj_noset_edit but the selection is kept
# and the selobj is expanded in the tree to see the added obj
@@ -404,5 +404,14 @@ class CommandManager:
"FreeCAD.ActiveDocument.{}.ViewObject.Visibility = False".format(self.selobj.Name)
)
# expand selobj in tree view
# recompute, expand selobj in tree view
expandParentObject()
FreeCADGui.doCommand(
"FreeCAD.ActiveDocument.ActiveObject.recompute()"
)
# set edit
FreeCADGui.Selection.clearSelection()
FreeCADGui.doCommand(
"FreeCADGui.ActiveDocument.setEdit(FreeCAD.ActiveDocument.ActiveObject.Name)"
)