diff --git a/src/Mod/Fem/App/FemPostPipeline.cpp b/src/Mod/Fem/App/FemPostPipeline.cpp index 5ebe1f0d58..0e23b9bc9c 100644 --- a/src/Mod/Fem/App/FemPostPipeline.cpp +++ b/src/Mod/Fem/App/FemPostPipeline.cpp @@ -55,15 +55,16 @@ using namespace Fem; using namespace App; PROPERTY_SOURCE(Fem::FemPostPipeline, Fem::FemPostObject) -const char* FemPostPipeline::ModeEnums[]= {"Serial","Parallel",nullptr}; +const char* FemPostPipeline::ModeEnums[] = { "Serial", "Parallel", "Custom", nullptr }; FemPostPipeline::FemPostPipeline() { ADD_PROPERTY_TYPE(Filter, (nullptr), "Pipeline", App::Prop_None, "The filter used in this pipeline"); ADD_PROPERTY_TYPE(Functions, (nullptr), "Pipeline", App::Prop_Hidden, "The function provider which groups all pipeline functions"); - ADD_PROPERTY_TYPE(Mode,(long(0)), "Pipeline", App::Prop_None, "Selects the pipeline data transition mode. In serial, every filter" - "gets the output of the previous one as input. In parallel, every" - "filter gets the pipeline source as input."); + ADD_PROPERTY_TYPE(Mode, (long(2)), "Pipeline", App::Prop_None, "Selects the pipeline data transition mode.\n" + "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" + "In custom, every filter keeps its input set by the user."); Mode.setEnums(ModeEnums); } @@ -73,7 +74,7 @@ FemPostPipeline::~FemPostPipeline() short FemPostPipeline::mustExecute(void) const { - if(Mode.isTouched()) + if (Mode.isTouched()) return 1; return FemPostFilter::mustExecute(); @@ -81,27 +82,25 @@ short FemPostPipeline::mustExecute(void) const DocumentObjectExecReturn* FemPostPipeline::execute(void) { - //if we are the toplevel pipeline our data object is not created by filters, we are the main source! - if(!Input.getValue()) + //if we are the toplevel pipeline our data object is not created by filters, we are the main source + if (!Input.getValue()) return StdReturn; //now if we are a filter than our data object is created by the filter we hold //if we are in serial mode we just copy over the data of the last filter, //but if we are in parallel we need to combine all filter results - if(Mode.getValue() == 0) { - + if (Mode.getValue() == 0) { //serial Data.setValue(getLastPostObject()->Data.getValue()); } - else { - - //parallel. go through all filters and append the result + else if (Mode.getValue() == 1) { + //parallel, go through all filters and append the result const std::vector& filters = Filter.getValues(); std::vector::const_iterator it = filters.begin(); vtkSmartPointer append = vtkSmartPointer::New(); - for(;it != filters.end(); ++it) { + for (; it != filters.end(); ++it) { append->AddInputDataObject(static_cast(*it)->Data.getValue()); } @@ -110,7 +109,6 @@ DocumentObjectExecReturn* FemPostPipeline::execute(void) { Data.setValue(append->GetOutputDataObject(0)); } - return Fem::FemPostObject::execute(); } @@ -151,47 +149,42 @@ void FemPostPipeline::read(Base::FileInfo File) { throw Base::FileException("Unknown extension"); } - -// PyObject *FemPostPipeline::getPyObject() -// { -// if (PythonObject.is(Py::_None())){ -// // ref counter is set to 1 -// PythonObject = Py::Object(new DocumentObjectPy(this),true); -// } -// return Py::new_reference_to(PythonObject); -// } - void FemPostPipeline::onChanged(const Property* prop) { - if(prop == &Filter || prop == &Mode) { + if (prop == &Filter || prop == &Mode) { + + // if we are in custom mode the user is free to set the input + // thus nothing needs to be done here + if (Mode.getValue() == 2) // custom + return; //we check if all connections are right and add new ones if needed std::vector objs = Filter.getValues(); - if(objs.empty()) + if (objs.empty()) return; std::vector::iterator it = objs.begin(); FemPostFilter* filter = static_cast(*it); //If we have a Input we need to ensure our filters are connected correctly - if(Input.getValue()) { + if (Input.getValue()) { //the first filter is always connected to the input - if(filter->Input.getValue() != Input.getValue()) + if (filter->Input.getValue() != Input.getValue()) filter->Input.setValue(Input.getValue()); //all the others need to be connected to the previous filter or the source, dependent on the mode ++it; - for(; it != objs.end(); ++it) { + for (; it != objs.end(); ++it) { FemPostFilter* nextFilter = static_cast(*it); - if(Mode.getValue() == 0) { //serial mode - if( nextFilter->Input.getValue() != filter) + if (Mode.getValue() == 0) { //serial mode + if (nextFilter->Input.getValue() != filter) nextFilter->Input.setValue(filter); } else { //Parallel mode - if( nextFilter->Input.getValue() != Input.getValue()) + if (nextFilter->Input.getValue() != Input.getValue()) nextFilter->Input.setValue(Input.getValue()); } @@ -201,20 +194,20 @@ void FemPostPipeline::onChanged(const Property* prop) //if we have no input the filters are responsible of grabbing the pipeline data themself else { //the first filter must always grab the data - if(filter->Input.getValue() != nullptr) + if (filter->Input.getValue() != nullptr) filter->Input.setValue(nullptr); //all the others need to be connected to the previous filter or grab the data, dependent on mode ++it; - for(; it != objs.end(); ++it) { + for (; it != objs.end(); ++it) { FemPostFilter* nextFilter = static_cast(*it); - if(Mode.getValue() == 0) { //serial mode - if( nextFilter->Input.getValue() != filter) + if (Mode.getValue() == 0) { //serial mode + if (nextFilter->Input.getValue() != filter) nextFilter->Input.setValue(filter); } else { //Parallel mode - if( nextFilter->Input.getValue() != nullptr) + if (nextFilter->Input.getValue() != nullptr) nextFilter->Input.setValue(nullptr); } @@ -229,7 +222,7 @@ void FemPostPipeline::onChanged(const Property* prop) FemPostObject* FemPostPipeline::getLastPostObject() { - if(Filter.getValues().empty()) + if (Filter.getValues().empty()) return this; return static_cast(Filter.getValues().back()); @@ -238,9 +231,9 @@ FemPostObject* FemPostPipeline::getLastPostObject() { bool FemPostPipeline::holdsPostObject(FemPostObject* obj) { std::vector::const_iterator it = Filter.getValues().begin(); - for(; it != Filter.getValues().end(); ++it) { + for (; it != Filter.getValues().end(); ++it) { - if(*it == obj) + if (*it == obj) return true; } return false; @@ -251,7 +244,7 @@ void FemPostPipeline::load(FemResultObject* res) { Base::Console().Log("Result mesh object is empty.\n"); return; } - if(!res->Mesh.getValue()->isDerivedFrom(Fem::FemMeshObject::getClassTypeId())) { + if (!res->Mesh.getValue()->isDerivedFrom(Fem::FemMeshObject::getClassTypeId())) { Base::Console().Log("Result mesh object is not derived from Fem::FemMeshObject.\n"); return; } @@ -273,7 +266,7 @@ PyObject* FemPostPipeline::getPyObject(void) { if (PythonObject.is(Py::_None())) { // ref counter is set to 1 - PythonObject = Py::Object(new FemPostPipelinePy(this),true); + PythonObject = Py::Object(new FemPostPipelinePy(this), true); } return Py::new_reference_to(PythonObject); }