Merge pull request #23164 from ickby/FEM_post_fixes_4

Fem: Fix for 3 issues
This commit is contained in:
Chris Hennes
2025-08-19 19:00:55 -05:00
committed by GitHub
9 changed files with 87 additions and 17 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

@@ -109,11 +109,8 @@ App::DocumentObject* FemPostGroupExtension::getGroupOfObject(const App::Document
void FemPostGroupExtension::onExtendedUnsetupObject()
{
// remove all children!
auto document = getExtendedObject()->getDocument();
for (const auto& obj : Group.getValues()) {
document->removeObject(obj->getNameInDocument());
}
// remove all children (if not already removed)!
removeObjectsFromDocument();
}
bool FemPostGroupExtension::allowObject(App::DocumentObject* obj)

View File

@@ -58,9 +58,10 @@ void ViewProviderFemPostPipeline::updateData(const App::Property* prop)
FemGui::ViewProviderFemPostObject::updateData(prop);
Fem::FemPostPipeline* pipeline = getObject<Fem::FemPostPipeline>();
if ((prop == &pipeline->Data) || (prop == &pipeline->Group)) {
if ((prop == &pipeline->Data) || (prop == &pipeline->Group) || (prop == &pipeline->Frame)) {
updateFunctionSize();
updateColorBars();
}
}
@@ -150,7 +151,7 @@ void ViewProviderFemPostPipeline::updateColorBars()
}
// if pipeline is visible, update it
if (this->isVisible()) {
if (this->Visibility.getValue()) {
updateMaterial();
}
}

View File

@@ -926,7 +926,9 @@ class _ResultsPurge(CommandManager):
def Activated(self):
import femresult.resulttools as resulttools
FreeCAD.ActiveDocument.openTransaction("Purge FEM results")
resulttools.purge_results(self.active_analysis)
FreeCAD.ActiveDocument.commitTransaction()
class _SolverCalculixContextManager:

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

@@ -80,6 +80,7 @@ class PostVisualization(base_fempythonobject.BaseFemPythonObject):
def __init__(self, obj):
super().__init__(obj)
self.Type = "Fem::FemPostVisualization"
obj.addExtension("App::GroupExtensionPython")
self._setup_properties(obj)

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"):
@@ -75,6 +80,30 @@ def purge_results(analysis):
analysis.Document.removeObject(m.Name)
analysis.Document.recompute()
# remove visulizations
for m in analysis.Group:
if is_of_type(m, "Fem::FemPostVisualization"):
analysis.Document.removeObject(m.Name)
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,12 @@ 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"""