FEM: Keep result pipeline and only reload data. Fixes #20542

This commit is contained in:
Stefan Tröger
2025-08-17 19:52:09 +02:00
parent a8cd293d6a
commit 96ed82f0cf
5 changed files with 72 additions and 10 deletions

View File

@@ -61,6 +61,13 @@ class GroupExtension(DocumentObjectExtension):
"""
...
def getObjectsOfType(self, typename: str) -> List[Any]:
"""
Returns all object in the group of given type
@param typename The Freecad type identifier
"""
...
def hasObject(self, obj: Any, recursive: bool = False) -> bool:
"""
hasObject(obj, recursive=false)

View File

@@ -278,6 +278,22 @@ PyObject* GroupExtensionPy::getObject(PyObject* args)
}
}
PyObject* GroupExtensionPy::getObjectsOfType(PyObject* args)
{
char* pcName;
if (!PyArg_ParseTuple(args, "s", &pcName)) {
return nullptr;
}
std::vector<DocumentObject*> objs = getGroupExtensionPtr()->getObjectsOfType(Base::Type::fromName(pcName));
Py::List result;
for (App::DocumentObject* obj : objs) {
result.append(Py::asObject(obj->getPyObject()));
}
return Py::new_reference_to(result);
}
PyObject* GroupExtensionPy::hasObject(PyObject* args)
{
PyObject* object;

View File

@@ -66,21 +66,33 @@ def setupPipeline(doc, analysis, results_name, result_data):
if not "BUILD_FEM_VTK" in FreeCAD.__cmake__:
return
# create a results pipeline if not already existing
# create a results pipeline (dependend on user settings)
pipeline_name = "Pipeline_" + results_name
pipeline_obj = doc.getObject(pipeline_name)
if pipeline_obj is None:
pipelines = analysis.getObjectsOfType("Fem::FemPostPipeline")
fem_prefs = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem/General")
keep_results_on_rerun = fem_prefs.GetBool("KeepResultsOnReRun", False)
if not pipelines or keep_results_on_rerun:
# needs to create a new pipeline!
pipeline_obj = ObjectsFem.makePostVtkResult(doc, result_data, results_name)
pipeline_visibility = True
if analysis:
analysis.addObject(pipeline_obj)
else:
# by default get the last one
pipeline_obj = pipelines[-1]
# maybe there is one with the correct name
named_pipeline = analysis.getObject(pipeline_name)
if named_pipeline:
pipeline_obj = named_pipeline
if FreeCAD.GuiUp:
# store pipeline visibility because pipeline_obj.load makes the
# pipeline always visible
pipeline_visibility = pipeline_obj.ViewObject.Visibility
# relabel the pipeline and load the data into it
pipeline_obj.Label = pipeline_name
pipeline_obj.load(*result_data)
# update the pipeline

View File

@@ -34,7 +34,7 @@ import FreeCAD
from femtools.femutils import is_of_type
def purge_results(analysis):
def purge_result_objects(analysis):
"""Removes all result objects and result meshes from an analysis group.
Parameters
@@ -43,11 +43,6 @@ def purge_results(analysis):
analysis group as a container for all objects needed for the analysis
"""
# if analysis type check is used, result mesh
# without result obj is created in the analysis
# we could run into trouble in one loop because
# we will delete objects and try to access them later
# result object
for m in analysis.Group:
if m.isDerivedFrom("Fem::FemResultObject"):
@@ -68,6 +63,16 @@ def purge_results(analysis):
analysis.Document.removeObject(m.Name)
analysis.Document.recompute()
def purge_postprocessing_objects(analysis):
"""Removes all postprocessing objects and visualizations form the analysis
Parameters
----------
analysis : Fem::FemAnalysis
analysis group as a container for all objects needed for the analysis
"""
# result pipeline and filter
for m in analysis.Group:
if is_of_type(m, "Fem::FemPostPipeline"):
@@ -82,6 +87,24 @@ def purge_results(analysis):
analysis.Document.recompute()
def purge_results(analysis):
"""Removes all result and postprocessing objects and result meshes from an analysis group.
Parameters
----------
analysis : Fem::FemAnalysis
analysis group as a container for all objects needed for the analysis
"""
# if analysis type check is used, result mesh
# without result obj is created in the analysis
# we could run into trouble in one loop because
# we will delete objects and try to access them later
purge_result_objects(analysis)
purge_postprocessing_objects(analysis)
def reset_mesh_deformation(resultobj):
"""Resets result mesh deformation.

View File

@@ -162,7 +162,11 @@ class FemToolsCcx(QtCore.QRunnable, QtCore.QObject):
self.fem_prefs = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem/General")
keep_results_on_rerun = self.fem_prefs.GetBool("KeepResultsOnReRun", False)
if not keep_results_on_rerun:
self.purge_results()
# we remove the result objects only, not the postprocessing ones.
# Reason: "Not keep results" means for the user override the data. For postprocessing
# this means keeping all filters, just change the data.
from femresult.resulttools import purge_result_objects as purge
purge(self.analysis)
def reset_all(self):
"""Reset mesh color, deformation and removes all result objects"""