diff --git a/src/Mod/Fem/App/FemPostBranchFilterPy.xml b/src/Mod/Fem/App/FemPostBranchFilterPy.xml
index 91cd392996..c84b8f438b 100644
--- a/src/Mod/Fem/App/FemPostBranchFilterPy.xml
+++ b/src/Mod/Fem/App/FemPostBranchFilterPy.xml
@@ -13,6 +13,11 @@
The FemPostBranch class.
+
+
+ Returns all filters, that this pipeline uses (non recursive, result does not contain branch child filters)
+
+
Recomputes all children of the pipeline
diff --git a/src/Mod/Fem/App/FemPostBranchFilterPyImp.cpp b/src/Mod/Fem/App/FemPostBranchFilterPyImp.cpp
index 23051912b2..583844f7a1 100644
--- a/src/Mod/Fem/App/FemPostBranchFilterPyImp.cpp
+++ b/src/Mod/Fem/App/FemPostBranchFilterPyImp.cpp
@@ -42,6 +42,20 @@ std::string FemPostBranchFilterPy::representation() const
return {""};
}
+PyObject* FemPostBranchFilterPy::getFilter(PyObject* args)
+{
+ if (!PyArg_ParseTuple(args, "")) {
+ return nullptr;
+ }
+
+ auto filters = getFemPostBranchFilterPtr()->getFilter();
+ Py::List sequence;
+ for (auto filter : filters) {
+ sequence.append(Py::asObject(filter->getPyObject()));
+ }
+
+ return Py::new_reference_to(sequence);
+}
PyObject* FemPostBranchFilterPy::recomputeChildren(PyObject* args)
{
diff --git a/src/Mod/Fem/App/FemPostFilter.cpp b/src/Mod/Fem/App/FemPostFilter.cpp
index f1f7789566..6fd7616e58 100644
--- a/src/Mod/Fem/App/FemPostFilter.cpp
+++ b/src/Mod/Fem/App/FemPostFilter.cpp
@@ -98,15 +98,13 @@ FemPostFilter::FilterPipeline& FemPostFilter::getActiveFilterPipeline()
void FemPostFilter::onChanged(const App::Property* prop)
{
//make sure we inform our parent object that we changed, it then can inform others if needed
- if(prop != &Data) {
- App::DocumentObject* group = FemPostGroupExtension::getGroupOfObject(this);
- if (!group) {
- return;
- }
- if (group->hasExtension(FemPostGroupExtension::getExtensionClassTypeId())) {
- auto postgroup = group->getExtensionByType();
- postgroup->filterChanged(this);
- }
+ App::DocumentObject* group = FemPostGroupExtension::getGroupOfObject(this);
+ if (!group) {
+ return;
+ }
+ if (group->hasExtension(FemPostGroupExtension::getExtensionClassTypeId())) {
+ auto postgroup = group->getExtensionByType();
+ postgroup->filterChanged(this);
}
return FemPostObject::onChanged(prop);
diff --git a/src/Mod/Fem/App/FemPostFunction.cpp b/src/Mod/Fem/App/FemPostFunction.cpp
index 683c5c464f..6c1833e9ac 100644
--- a/src/Mod/Fem/App/FemPostFunction.cpp
+++ b/src/Mod/Fem/App/FemPostFunction.cpp
@@ -44,7 +44,7 @@ bool FemPostFunctionProvider::allowObject(App::DocumentObject* obj)
return obj->isDerivedFrom(FemPostFunction::getClassTypeId());
}
-void FemPostFunctionProvider::unsetupObject()
+void FemPostFunctionProvider::unsetupObject()
{
// remove all children!
auto document = getExtendedObject()->getDocument();
@@ -53,6 +53,24 @@ void FemPostFunctionProvider::unsetupObject()
}
}
+void FemPostFunctionProvider::handleChangedPropertyName(Base::XMLReader& reader,
+ const char* typeName,
+ const char* propName)
+{
+ if (strcmp(propName, "Functions") == 0
+ && Base::Type::fromName(typeName) == App::PropertyLinkList::getClassTypeId()) {
+
+ // add the formerly Functions values to the group
+ App::PropertyLinkList functions;
+ functions.setContainer(this);
+ functions.Restore(reader);
+ Group.setValues(functions.getValues());
+ }
+ else {
+ App::DocumentObject::handleChangedPropertyName(reader, typeName, propName);
+ }
+}
+
PROPERTY_SOURCE(Fem::FemPostFunction, App::DocumentObject)
FemPostFunction::FemPostFunction() = default;
diff --git a/src/Mod/Fem/App/FemPostFunction.h b/src/Mod/Fem/App/FemPostFunction.h
index a23ad01f36..cd59f37ac0 100644
--- a/src/Mod/Fem/App/FemPostFunction.h
+++ b/src/Mod/Fem/App/FemPostFunction.h
@@ -90,6 +90,9 @@ public:
protected:
bool allowObject(App::DocumentObject* obj) override;
void unsetupObject() override;
+
+ // update documents
+ void handleChangedPropertyName(Base::XMLReader &reader, const char * TypeName, const char *PropName) override;
};
// ---------------------------------------------------------------------------
diff --git a/src/Mod/Fem/App/FemPostGroupExtension.cpp b/src/Mod/Fem/App/FemPostGroupExtension.cpp
index 7c10703064..040df298a3 100644
--- a/src/Mod/Fem/App/FemPostGroupExtension.cpp
+++ b/src/Mod/Fem/App/FemPostGroupExtension.cpp
@@ -42,12 +42,6 @@ FemPostGroupExtension::FemPostGroupExtension() : App::GroupExtension() {
"In serial, every filter gets the output of the previous one as input.\n"
"In parallel, every filter gets the pipeline source as input.\n");
- EXTENSION_ADD_PROPERTY_TYPE(Filter,
- (nullptr),
- "Pipeline",
- App::Prop_Transient,
- "List of all filters");
-
Mode.setEnums(ModeEnums);
}
@@ -70,15 +64,7 @@ void FemPostGroupExtension::extensionOnChanged(const App::Property* p)
{
if(p == &Group) {
if (!m_blockChange) {
- // make sure filter property holds all our filters (and non filters are in front)
- std::vector filters;
- for(auto obj : Group.getValues()) {
- if(obj->isDerivedFrom(FemPostFilter::getClassTypeId())) {
- filters.push_back(obj);
- }
- }
-
- // sort the group, so that non filter objects are always on top
+ // sort the group, so that non filter objects are always on top (in case any object using this extension allows those)
auto objs = Group.getValues();
std::sort( objs.begin( ), objs.end( ), [ ]( const App::DocumentObject* lhs, const App::DocumentObject* rhs ){
@@ -88,41 +74,24 @@ void FemPostGroupExtension::extensionOnChanged(const App::Property* p)
});
m_blockChange = true;
Group.setValue(objs);
- Filter.setValue(filters);
- m_blockChange = false;
- }
- }
- else if (p == &Filter) {
- if (!m_blockChange) {
- // someone external changed filter, make sure group represents this
-
- // collect all filters
- std::vector filters;
- for (auto obj : Filter.getValues()) {
- if (obj->isDerivedFrom(Fem::FemPostFilter::getClassTypeId())) {
- filters.push_back(obj);
- }
- }
-
- //collect all other items that are not filters
- std::vector objs;
- for (auto obj : Group.getValues()) {
- if (!obj->isDerivedFrom(Fem::FemPostFilter::getClassTypeId())) {
- objs.push_back(obj);
- }
- }
-
- // set the properties correctly
- m_blockChange = true;
- objs.insert( objs.end(), filters.begin(), filters.end() );
- Filter.setValue(filters);
- Group.setValue(objs);
m_blockChange = false;
}
}
GroupExtension::extensionOnChanged(p);
}
+std::vector FemPostGroupExtension::getFilter()
+{
+ //collect all other items that are not filters
+ std::vector filters;
+ for (auto obj : Group.getValues()) {
+ if (obj->isDerivedFrom(Fem::FemPostFilter::getClassTypeId())) {
+ filters.push_back(static_cast(obj));
+ }
+ }
+ return filters;
+}
+
App::DocumentObject* FemPostGroupExtension::getGroupOfObject(const App::DocumentObject* obj)
{
for (auto o : obj->getInList()) {
diff --git a/src/Mod/Fem/App/FemPostGroupExtension.h b/src/Mod/Fem/App/FemPostGroupExtension.h
index 4691b08abf..cbb9ef125e 100644
--- a/src/Mod/Fem/App/FemPostGroupExtension.h
+++ b/src/Mod/Fem/App/FemPostGroupExtension.h
@@ -44,7 +44,6 @@ public:
void initExtension(App::ExtensionContainer* obj) override;
App::PropertyEnumeration Mode;
- App::PropertyLinkList Filter;
// Pipeline handling
virtual void filterChanged(FemPostFilter*) {}; // settings change in filter
@@ -54,6 +53,7 @@ public:
virtual bool holdsPostObject(FemPostObject* obj);
// general
+ std::vector getFilter();
static App::DocumentObject* getGroupOfObject(const App::DocumentObject* obj);
protected:
diff --git a/src/Mod/Fem/App/FemPostPipeline.cpp b/src/Mod/Fem/App/FemPostPipeline.cpp
index e646129a9e..19c4fc8d25 100644
--- a/src/Mod/Fem/App/FemPostPipeline.cpp
+++ b/src/Mod/Fem/App/FemPostPipeline.cpp
@@ -71,10 +71,10 @@ FemFrameSourceAlgorithm::FemFrameSourceAlgorithm::FemFrameSourceAlgorithm()
FemFrameSourceAlgorithm::FemFrameSourceAlgorithm::~FemFrameSourceAlgorithm()
-{
-}
+{}
-void FemFrameSourceAlgorithm::setDataObject(vtkSmartPointer data ) {
+void FemFrameSourceAlgorithm::setDataObject(vtkSmartPointer data)
+{
m_data = data;
Update();
}
@@ -94,7 +94,7 @@ std::vector FemFrameSourceAlgorithm::getFrameValues()
unsigned long nblocks = multiblock->GetNumberOfBlocks();
std::vector tFrames(nblocks);
- for (unsigned long i=0; iGetBlock(i);
// check if the TimeValue field is available
@@ -102,10 +102,9 @@ std::vector FemFrameSourceAlgorithm::getFrameValues()
break;
}
- //store the time value!
+ // store the time value!
vtkDataArray* TimeValue = block->GetFieldData()->GetArray("TimeValue");
- if (!TimeValue->IsA("vtkFloatArray") ||
- TimeValue->GetNumberOfTuples() < 1) {
+ if (!TimeValue->IsA("vtkFloatArray") || TimeValue->GetNumberOfTuples() < 1) {
break;
}
@@ -120,11 +119,12 @@ std::vector FemFrameSourceAlgorithm::getFrameValues()
return tFrames;
}
-int FemFrameSourceAlgorithm::RequestInformation(vtkInformation*reqInfo, vtkInformationVector **inVector, vtkInformationVector* outVector)
+int FemFrameSourceAlgorithm::RequestInformation(vtkInformation* reqInfo,
+ vtkInformationVector** inVector,
+ vtkInformationVector* outVector)
{
- if (!this->Superclass::RequestInformation(reqInfo, inVector, outVector))
- {
+ if (!this->Superclass::RequestInformation(reqInfo, inVector, outVector)) {
return 0;
}
@@ -151,14 +151,17 @@ int FemFrameSourceAlgorithm::RequestInformation(vtkInformation*reqInfo, vtkInfor
return 1;
}
-int FemFrameSourceAlgorithm::RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector* outVector)
+int FemFrameSourceAlgorithm::RequestData(vtkInformation*,
+ vtkInformationVector**,
+ vtkInformationVector* outVector)
{
std::stringstream strstm;
outVector->Print(strstm);
vtkInformation* outInfo = outVector->GetInformationObject(0);
- vtkUnstructuredGrid* output = vtkUnstructuredGrid::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));
+ vtkUnstructuredGrid* output =
+ vtkUnstructuredGrid::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));
if (!output || !m_data) {
return 0;
@@ -173,14 +176,15 @@ int FemFrameSourceAlgorithm::RequestData(vtkInformation*, vtkInformationVector**
vtkSmartPointer multiblock = vtkMultiBlockDataSet::SafeDownCast(m_data);
// find the block asked for (lazy implementation)
unsigned long idx = 0;
- if (outInfo->Has(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP()))
- {
+ if (outInfo->Has(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP())) {
auto time = outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP());
auto frames = getFrameValues();
- // we have float values, so be aware of roundign erros. lets subtract the searched time and then use the smalles value
- for(auto& frame : frames)
- frame = std::abs(frame-time);
+ // we have float values, so be aware of roundign erros. lets subtract the searched time and
+ // then use the smalles value
+ for (auto& frame : frames) {
+ frame = std::abs(frame - time);
+ }
auto it = std::min_element(std::begin(frames), std::end(frames));
idx = std::distance(std::begin(frames), it);
@@ -194,7 +198,9 @@ int FemFrameSourceAlgorithm::RequestData(vtkInformation*, vtkInformationVector**
PROPERTY_SOURCE_WITH_EXTENSIONS(Fem::FemPostPipeline, Fem::FemPostObject)
-FemPostPipeline::FemPostPipeline() : FemPostObject(), FemPostGroupExtension()
+FemPostPipeline::FemPostPipeline()
+ : FemPostObject()
+ , FemPostGroupExtension()
{
FemPostGroupExtension::initExtension(this);
@@ -203,7 +209,8 @@ FemPostPipeline::FemPostPipeline() : FemPostObject(), FemPostGroupExtension()
(long(0)),
"Pipeline",
App::Prop_None,
- "The frame used to calculate the data in the pipeline processing (read only, set via pipeline object).");
+ "The frame used to calculate the data in the pipeline processing (read only, "
+ "set via pipeline object).");
// create our source algorithm
m_source_algorithm = vtkSmartPointer::New();
@@ -213,14 +220,15 @@ FemPostPipeline::~FemPostPipeline() = default;
short FemPostPipeline::mustExecute() const
{
- if (Mode.isTouched() ) {
+ if (Mode.isTouched()) {
return 1;
}
return FemPostObject::mustExecute();
}
-vtkDataSet* FemPostPipeline::getDataSet() {
+vtkDataSet* FemPostPipeline::getDataSet()
+{
vtkDataObject* data = m_source_algorithm->GetOutputDataObject(0);
if (!data) {
@@ -234,11 +242,12 @@ vtkDataSet* FemPostPipeline::getDataSet() {
return nullptr;
}
-Fem::FemPostFunctionProvider* FemPostPipeline::getFunctionProvider() {
+Fem::FemPostFunctionProvider* FemPostPipeline::getFunctionProvider()
+{
// see if we have one
- for (auto obj : Group.getValues()){
- if(obj->isDerivedFrom(FemPostFunctionProvider::getClassTypeId())) {
+ for (auto obj : Group.getValues()) {
+ if (obj->isDerivedFrom(FemPostFunctionProvider::getClassTypeId())) {
return static_cast(obj);
}
}
@@ -309,7 +318,7 @@ void FemPostPipeline::scale(double s)
void FemPostPipeline::onChanged(const Property* prop)
{
- /* onChanged handles the Pipeline setup: we connect the inputs and outputs
+ /* onChanged handles the Pipeline setup: we connect the inputs and outputs
* of our child filters correctly according to the new settings
*/
@@ -334,7 +343,7 @@ void FemPostPipeline::onChanged(const Property* prop)
auto unit = getFrameUnit();
for (const double& frame : frames) {
auto quantity = Base::Quantity(frame, unit);
- frame_values.push_back(quantity.getUserString().toStdString());
+ frame_values.push_back(quantity.getUserString());
}
}
@@ -343,7 +352,8 @@ void FemPostPipeline::onChanged(const Property* prop)
m_frameEnum.setEnums(frame_values);
Frame.setValue(m_frameEnum);
- std::vector::iterator it = std::find(frame_values.begin(), frame_values.end(), val);
+ std::vector::iterator it =
+ std::find(frame_values.begin(), frame_values.end(), val);
if (!val.empty() && it != frame_values.end()) {
Frame.setValue(val.c_str());
}
@@ -356,8 +366,7 @@ void FemPostPipeline::onChanged(const Property* prop)
// update the algorithm for the visulization
auto frames = getFrameValues();
- if (!frames.empty() &&
- Frame.getValue() < long(frames.size())) {
+ if (!frames.empty() && Frame.getValue() < long(frames.size())) {
double time = frames[Frame.getValue()];
m_source_algorithm->UpdateTimeStep(time);
@@ -369,39 +378,40 @@ void FemPostPipeline::onChanged(const Property* prop)
// connect all filters correctly to the source
- if (prop == &Filter || prop == &Mode) {
+ if (prop == &Group || prop == &Mode) {
// we check if all connections are right and add new ones if needed
- std::vector objs = Filter.getValues();
+ std::vector objs = getFilter();
if (objs.empty()) {
return;
}
FemPostFilter* filter = NULL;
- std::vector::iterator it = objs.begin();
+ std::vector::iterator it = objs.begin();
for (; it != objs.end(); ++it) {
// prepare the filter: make all connections new
- FemPostFilter* nextFilter = static_cast(*it);
+ FemPostFilter* nextFilter = *it;
nextFilter->getActiveFilterPipeline().source->RemoveAllInputConnections(0);
- // handle input modes
- if (Mode.getValue() == 0) {
- // serial: the next filter gets the previous output, the first one gets our input
- if (filter == NULL) {
- nextFilter->getActiveFilterPipeline().source->SetInputConnection(m_source_algorithm->GetOutputPort(0));
- } else {
- nextFilter->getActiveFilterPipeline().source->SetInputConnection(filter->getActiveFilterPipeline().target->GetOutputPort());
- }
-
- }
- else if (Mode.getValue() == 1) {
+ // handle input modes (Parallel is seperated, alll other settings are serial, just in
+ // case an old document is loaded with "custom" mode, idx 2)
+ if (Mode.getValue() == 1) {
// parallel: all filters get out input
- nextFilter->getActiveFilterPipeline().source->SetInputConnection(m_source_algorithm->GetOutputPort(0));
+ nextFilter->getActiveFilterPipeline().source->SetInputConnection(
+ m_source_algorithm->GetOutputPort(0));
}
else {
- throw Base::ValueError("Unknown Mode set for Pipeline");
+ // serial: the next filter gets the previous output, the first one gets our input
+ if (filter == NULL) {
+ nextFilter->getActiveFilterPipeline().source->SetInputConnection(
+ m_source_algorithm->GetOutputPort(0));
+ }
+ else {
+ nextFilter->getActiveFilterPipeline().source->SetInputConnection(
+ filter->getActiveFilterPipeline().target->GetOutputPort());
+ }
}
filter = nextFilter;
@@ -411,7 +421,7 @@ void FemPostPipeline::onChanged(const Property* prop)
void FemPostPipeline::filterChanged(FemPostFilter* filter)
{
- //we only need to update the following children if we are in serial mode
+ // we only need to update the following children if we are in serial mode
if (Mode.getValue() == 0) {
std::vector objs = Group.getValues();
@@ -434,7 +444,8 @@ void FemPostPipeline::filterChanged(FemPostFilter* filter)
}
}
-void FemPostPipeline::filterPipelineChanged(FemPostFilter*) {
+void FemPostPipeline::filterPipelineChanged(FemPostFilter*)
+{
// one of our filters has changed its active pipeline. We need to reconnect it properly.
// As we are cheap we just reconnect everything
// TODO: Do more efficiently
@@ -446,8 +457,7 @@ void FemPostPipeline::recomputeChildren()
// get the frame we use
double frame = 0;
auto frames = getFrameValues();
- if (!frames.empty() &&
- Frame.getValue() < long(frames.size())) {
+ if (!frames.empty() && Frame.getValue() < long(frames.size())) {
frame = frames[Frame.getValue()];
}
@@ -484,9 +494,7 @@ std::string FemPostPipeline::getFrameType()
}
vtkAbstractArray* TimeInfo = multiblock->GetFieldData()->GetAbstractArray("TimeInfo");
- if (!TimeInfo ||
- !TimeInfo->IsA("vtkStringArray") ||
- TimeInfo->GetNumberOfTuples() < 2) {
+ if (!TimeInfo || !TimeInfo->IsA("vtkStringArray") || TimeInfo->GetNumberOfTuples() < 2) {
return std::string("unknown");
}
@@ -512,14 +520,13 @@ Base::Unit FemPostPipeline::getFrameUnit()
}
vtkAbstractArray* TimeInfo = multiblock->GetFieldData()->GetAbstractArray("TimeInfo");
- if (!TimeInfo->IsA("vtkStringArray") ||
- TimeInfo->GetNumberOfTuples() < 2) {
+ if (!TimeInfo->IsA("vtkStringArray") || TimeInfo->GetNumberOfTuples() < 2) {
// units cannot be undefined, so use time
return Base::Unit::TimeSpan;
}
- return Base::Unit(QString::fromStdString(vtkStringArray::SafeDownCast(TimeInfo)->GetValue(1)));
+ return Base::Unit(vtkStringArray::SafeDownCast(TimeInfo)->GetValue(1));
}
std::vector FemPostPipeline::getFrameValues()
@@ -560,21 +567,25 @@ void FemPostPipeline::load(FemResultObject* res)
// set multiple result objects as frames for one pipeline
// Notes:
// 1. values vector must contain growing value, smallest first
-void FemPostPipeline::load(std::vector res, std::vector values, Base::Unit unit, std::string frame_type) {
+void FemPostPipeline::load(std::vector res,
+ std::vector values,
+ Base::Unit unit,
+ std::string frame_type)
+{
- if (res.size() != values.size() ) {
+ if (res.size() != values.size()) {
Base::Console().Error("Result values and frame values have different length.\n");
return;
}
- // setup the time information for the multiblock
+ // setup the time information for the multiblock
vtkStringArray* TimeInfo = vtkStringArray::New();
TimeInfo->SetName("TimeInfo");
TimeInfo->InsertNextValue(frame_type);
- TimeInfo->InsertNextValue(unit.getString().toStdString());
+ TimeInfo->InsertNextValue(unit.getString());
auto multiblock = vtkSmartPointer::New();
- for (ulong i=0; iMesh.getValue()->isDerivedFrom(Fem::FemMeshObject::getClassTypeId())) {
Base::Console().Error("Result mesh object is not derived from Fem::FemMeshObject.\n");
@@ -582,7 +593,8 @@ void FemPostPipeline::load(std::vector res, std::vector(res[i]->Mesh.getValue())->FemMesh.getValue();
+ const FemMesh& mesh =
+ static_cast(res[i]->Mesh.getValue())->FemMesh.getValue();
vtkSmartPointer grid = vtkSmartPointer::New();
FemVTKTools::exportVTKMesh(&mesh, grid);
@@ -604,6 +616,49 @@ void FemPostPipeline::load(std::vector res, std::vector 1 || Mode.getValue() < 0) {
+ Mode.setValue(long(0));
+ }
+}
+
PyObject* FemPostPipeline::getPyObject()
{
if (PythonObject.is(Py::_None())) {
diff --git a/src/Mod/Fem/App/FemPostPipeline.h b/src/Mod/Fem/App/FemPostPipeline.h
index 5303b4e25e..0d147c1f4f 100644
--- a/src/Mod/Fem/App/FemPostPipeline.h
+++ b/src/Mod/Fem/App/FemPostPipeline.h
@@ -110,6 +110,10 @@ protected:
void onChanged(const App::Property* prop) override;
bool allowObject(App::DocumentObject* obj) override;
+ // update documents
+ void handleChangedPropertyName(Base::XMLReader &reader, const char * TypeName, const char *PropName) override;
+ void onDocumentRestored() override;
+
private:
App::Enumeration m_frameEnum;
vtkSmartPointer m_source_algorithm;
diff --git a/src/Mod/Fem/App/FemPostPipelinePy.xml b/src/Mod/Fem/App/FemPostPipelinePy.xml
index 47b1710f5d..ba73bf9479 100644
--- a/src/Mod/Fem/App/FemPostPipelinePy.xml
+++ b/src/Mod/Fem/App/FemPostPipelinePy.xml
@@ -28,6 +28,11 @@
Load a single result object or create a multiframe result by loading multiple result frames. If multistep is wanted, 4 argumenhts are needed: 1. List of result object each being one frame, 2. List of values valid for each frame (e.g. [s] if time data), 3. the unit of the value, 4. the Description of the frames
+
+
+ Returns all filters, that this pipeline uses (non recursive, result does not contain branch child filters)
+
+
Recomputes all children of the pipeline
diff --git a/src/Mod/Fem/App/FemPostPipelinePyImp.cpp b/src/Mod/Fem/App/FemPostPipelinePyImp.cpp
index fd26f3f60c..e983269c82 100644
--- a/src/Mod/Fem/App/FemPostPipelinePyImp.cpp
+++ b/src/Mod/Fem/App/FemPostPipelinePyImp.cpp
@@ -150,6 +150,22 @@ PyObject* FemPostPipelinePy::load(PyObject* args)
Py_Return;
}
+
+PyObject* FemPostPipelinePy::getFilter(PyObject* args)
+{
+ if (!PyArg_ParseTuple(args, "")) {
+ return nullptr;
+ }
+
+ auto filters = getFemPostPipelinePtr()->getFilter();
+ Py::List sequence;
+ for (auto filter : filters) {
+ sequence.append(Py::asObject(filter->getPyObject()));
+ }
+
+ return Py::new_reference_to(sequence);
+}
+
PyObject* FemPostPipelinePy::recomputeChildren(PyObject* args)
{
if (!PyArg_ParseTuple(args, "")) {
diff --git a/src/Mod/Fem/Gui/TaskPostBoxes.cpp b/src/Mod/Fem/Gui/TaskPostBoxes.cpp
index d4f78a0465..503be20e16 100644
--- a/src/Mod/Fem/Gui/TaskPostBoxes.cpp
+++ b/src/Mod/Fem/Gui/TaskPostBoxes.cpp
@@ -481,10 +481,8 @@ void TaskPostFunction::applyPythonCode()
// ***************************************************************************
// Frames
TaskPostFrames::TaskPostFrames(ViewProviderFemPostObject* view, QWidget* parent)
- : TaskPostBox(view,
- Gui::BitmapFactory().pixmap("FEM_PostFrames"),
- tr("Result Frames"),
- parent), ui(new Ui_TaskPostFrames)
+ : TaskPostBox(view, Gui::BitmapFactory().pixmap("FEM_PostFrames"), tr("Result Frames"), parent)
+ , ui(new Ui_TaskPostFrames)
{
// we load the views widget
proxy = new QWidget(this);
@@ -498,12 +496,13 @@ TaskPostFrames::TaskPostFrames(ViewProviderFemPostObject* view, QWidget* parent)
auto unit = pipeline->getFrameUnit();
auto steps = pipeline->getFrameValues();
- for (unsigned long i=0; iFrameTable->rowCount();
- ui->FrameTable->insertRow (rowIdx);
+ ui->FrameTable->insertRow(rowIdx);
ui->FrameTable->setItem(rowIdx, 0, idx);
ui->FrameTable->setItem(rowIdx, 1, value);
}
@@ -530,14 +529,12 @@ void TaskPostFrames::onSelectionChanged()
}
-
void TaskPostFrames::applyPythonCode()
{
// we apply the views widgets python code
}
-
// ***************************************************************************
// in the following, the different filters sorted alphabetically
// ***************************************************************************
@@ -549,7 +546,8 @@ TaskPostBranch::TaskPostBranch(ViewProviderFemPostBranchFilter* view, QWidget* p
: TaskPostBox(view,
Gui::BitmapFactory().pixmap("FEM_PostBranchFilter"),
tr("Branch behaviour"),
- parent), ui(new Ui_TaskPostBranch)
+ parent)
+ , ui(new Ui_TaskPostBranch)
{
// we load the views widget
proxy = new QWidget(this);
@@ -590,14 +588,12 @@ void TaskPostBranch::onOutputIndexChanged(int idx)
}
-
void TaskPostBranch::applyPythonCode()
{
// we apply the views widgets python code
}
-
// ***************************************************************************
// data along line filter
TaskPostDataAlongLine::TaskPostDataAlongLine(ViewProviderFemPostDataAlongLine* view,
diff --git a/src/Mod/Fem/Gui/ViewProviderFemPostBranchFilter.cpp b/src/Mod/Fem/Gui/ViewProviderFemPostBranchFilter.cpp
index 22c4698df1..be32921876 100644
--- a/src/Mod/Fem/Gui/ViewProviderFemPostBranchFilter.cpp
+++ b/src/Mod/Fem/Gui/ViewProviderFemPostBranchFilter.cpp
@@ -56,7 +56,7 @@ bool ViewProviderFemPostBranchFilter::acceptReorderingObjects() const {
return true;
}
-bool ViewProviderFemPostBranchFilter::canDragObjectToTarget(App::DocumentObject* obj, App::DocumentObject* target) const {
+bool ViewProviderFemPostBranchFilter::canDragObjectToTarget(App::DocumentObject*, App::DocumentObject* target) const {
// allow drag only to other post groups
if (target) {
diff --git a/src/Mod/Fem/Gui/ViewProviderFemPostPipeline.cpp b/src/Mod/Fem/Gui/ViewProviderFemPostPipeline.cpp
index 596ae9435f..3d82cf233a 100644
--- a/src/Mod/Fem/Gui/ViewProviderFemPostPipeline.cpp
+++ b/src/Mod/Fem/Gui/ViewProviderFemPostPipeline.cpp
@@ -233,7 +233,7 @@ bool ViewProviderFemPostPipeline::acceptReorderingObjects() const {
return true;
}
-bool ViewProviderFemPostPipeline::canDragObjectToTarget(App::DocumentObject* obj, App::DocumentObject* target) const {
+bool ViewProviderFemPostPipeline::canDragObjectToTarget(App::DocumentObject*, App::DocumentObject* target) const {
// allow drag only to other post groups
if (target) {
diff --git a/src/Mod/Fem/Gui/ViewProviderFemPostPipeline.h b/src/Mod/Fem/Gui/ViewProviderFemPostPipeline.h
index f126df276c..f83f2a7e18 100644
--- a/src/Mod/Fem/Gui/ViewProviderFemPostPipeline.h
+++ b/src/Mod/Fem/Gui/ViewProviderFemPostPipeline.h
@@ -51,6 +51,10 @@ public:
void scaleField(vtkDataSet* dset, vtkDataArray* pdata, double FieldFactor);
PyObject* getPyObject() override;
+ // override, to not show/hide children as the parent is shown/hidden like normal groups
+ void extensionHide() override {};
+ void extensionShow() override {};
+
protected:
void updateFunctionSize();
virtual void setupTaskDialog(TaskDlgPost* dlg) override;
diff --git a/src/Mod/Fem/femresult/resulttools.py b/src/Mod/Fem/femresult/resulttools.py
index a0e7362c13..4a2df17f2c 100644
--- a/src/Mod/Fem/femresult/resulttools.py
+++ b/src/Mod/Fem/femresult/resulttools.py
@@ -71,10 +71,7 @@ def purge_results(analysis):
# result pipeline and filter
for m in analysis.Group:
if is_of_type(m, "Fem::FemPostPipeline"):
- # delete associated filters
- for filter_obj in m.Filter:
- analysis.Document.removeObject(filter_obj.Name)
- # delete the pipeline itself
+ # delete the pipeline itself (it removes all fiters itself)
analysis.Document.removeObject(m.Name)
analysis.Document.recompute()