diff --git a/src/Mod/Fem/App/AppFem.cpp b/src/Mod/Fem/App/AppFem.cpp index c94061ed63..ea0eff09ed 100644 --- a/src/Mod/Fem/App/AppFem.cpp +++ b/src/Mod/Fem/App/AppFem.cpp @@ -59,6 +59,7 @@ #include "FemPostPipeline.h" #include "FemPostFilter.h" #include "FemPostFunction.h" +#include "PropertyPostDataObject.h" #endif namespace Fem { @@ -163,5 +164,6 @@ PyMODINIT_FUNC initFem() Fem::FemPostFunctionProvider ::init(); Fem::FemPostPlaneFunction ::init(); Fem::FemPostSphereFunction ::init(); + Fem::PropertyPostDataObject ::init(); #endif } diff --git a/src/Mod/Fem/App/AppFem.cpp.orig b/src/Mod/Fem/App/AppFem.cpp.orig index c24fb78392..7bb1cdda8a 100644 --- a/src/Mod/Fem/App/AppFem.cpp.orig +++ b/src/Mod/Fem/App/AppFem.cpp.orig @@ -1,4 +1,4 @@ -<<<<<<< 559b38429c3ec5bcad9eced553e5d7ca544cb55e +<<<<<<< 43b51b168bc838480fd6a0a4b9f67e0bf864a560 /*************************************************************************** * Copyright (c) 2008 Jürgen Riegel (juergen.riegel@web.de) * * * @@ -159,6 +159,7 @@ PyMODINIT_FUNC initFem() Fem::FemPostClipFilter ::init(); Fem::FemPostScalarClipFilter ::init(); Fem::FemPostWarpVectorFilter ::init(); + Fem::FemPostCutFilter ::init(); Fem::FemPostFunction ::init(); Fem::FemPostFunctionProvider ::init(); Fem::FemPostPlaneFunction ::init(); @@ -227,6 +228,7 @@ PyMODINIT_FUNC initFem() #include "FemPostPipeline.h" #include "FemPostFilter.h" #include "FemPostFunction.h" +#include "PropertyPostDataObject.h" #endif namespace Fem { @@ -331,6 +333,7 @@ PyMODINIT_FUNC initFem() Fem::FemPostFunctionProvider ::init(); Fem::FemPostPlaneFunction ::init(); Fem::FemPostSphereFunction ::init(); + Fem::PropertyPostDataObject ::init(); #endif } ->>>>>>> Add cut filter +>>>>>>> FreeCADify the vtk post processing diff --git a/src/Mod/Fem/App/CMakeLists.txt b/src/Mod/Fem/App/CMakeLists.txt index 805172815f..220d98d71f 100755 --- a/src/Mod/Fem/App/CMakeLists.txt +++ b/src/Mod/Fem/App/CMakeLists.txt @@ -202,6 +202,8 @@ SOURCE_GROUP("Constraints" FILES ${FemConstraints_SRCS}) if(BUILD_FEM_VTK) SET(FemPost_SRCS + PropertyPostDataObject.h + PropertyPostDataObject.cpp FemPostObject.h FemPostObject.cpp FemPostPipeline.h diff --git a/src/Mod/Fem/App/FemPostFilter.cpp b/src/Mod/Fem/App/FemPostFilter.cpp index 99e6602538..35e8b38fd5 100644 --- a/src/Mod/Fem/App/FemPostFilter.cpp +++ b/src/Mod/Fem/App/FemPostFilter.cpp @@ -29,6 +29,7 @@ #include "FemPostFilter.h" #include "FemPostPipeline.h" #include +#include #include #include #include @@ -41,115 +42,14 @@ PROPERTY_SOURCE(Fem::FemPostFilter, Fem::FemPostObject) FemPostFilter::FemPostFilter() { - m_pass = vtkPassThrough::New(); + ADD_PROPERTY(Input,(0)); } FemPostFilter::~FemPostFilter() { - //we need to make sure that all vtk filters are disconnected - //as the would stay alive and connected otherwise - clearInput(); + } -bool FemPostFilter::valid() { - return polyDataSource && !m_pipelines.empty() && !m_activePipeline.empty(); -} - -bool FemPostFilter::isConnected() { - return valid() && (m_pipelines[m_activePipeline].source->GetTotalNumberOfInputConnections() > 0); -} - -bool FemPostFilter::providesPolyData() { - return isConnected(); -} - - -DocumentObjectExecReturn* FemPostFilter::execute(void) { - - if(isConnected()) { - - FilterPipeline& pipe = m_pipelines[m_activePipeline]; - if(pipe.source->GetTotalNumberOfInputConnections() > 0) { - pipe.target->Update(); - return Fem::FemPostObject::execute(); - } - } - - return StdReturn; -} - - -void FemPostFilter::clearInput() { - - if(isConnected()) { - for(std::map::iterator it = m_pipelines.begin(); it != m_pipelines.end(); ++it) { - it->second.source->RemoveAllInputConnections(0); - it->second.source->RemoveAllInputs(); - } - polyDataSource->RemoveAllInputConnections(0); - } -} - -bool FemPostFilter::hasInputAlgorithmConnected() { - - return isConnected(); -} - -void FemPostFilter::connectInputAlgorithm(vtkSmartPointer< vtkAlgorithm > algo) { - - clearInput(); - if(isValid()) { - for(std::map::iterator it = m_pipelines.begin(); it != m_pipelines.end(); ++it) { - it->second.source->SetInputConnection(algo->GetOutputPort()); - } - polyDataSource->SetInputConnection(m_pipelines[m_activePipeline].visualisation->GetOutputPort()); - touch(); - } -} - -vtkSmartPointer< vtkAlgorithm > FemPostFilter::getConnectedInputAlgorithm() { - - if(!isConnected()) - return vtkSmartPointer< vtkAlgorithm >(); - - return m_pipelines[m_activePipeline].source->GetInputAlgorithm(0,0); -} - -bool FemPostFilter::hasInputDataConnected() { - - if(!isValid()) - return false; - - return (m_pipelines[m_activePipeline].source->GetInputDataObject(0,0) != NULL); -} - - -void FemPostFilter::connectInputData(vtkSmartPointer< vtkDataSet > data) { - - clearInput(); - if(isValid()) { - - for(std::map::iterator it = m_pipelines.begin(); it != m_pipelines.end(); ++it) { - it->second.source->SetInputDataObject(data); - } - polyDataSource->SetInputConnection(m_pipelines[m_activePipeline].visualisation->GetOutputPort()); - touch(); - } -} - -vtkSmartPointer< vtkDataObject > FemPostFilter::getConnectedInputData() { - - if(!isValid()) - return vtkSmartPointer< vtkDataSet >(); - - return m_pipelines[m_activePipeline].source->GetInputDataObject(0,0); -} - -vtkSmartPointer< vtkAlgorithm > FemPostFilter::getOutputAlgorithm() { - return m_pass; -} - - void FemPostFilter::addFilterPipeline(const FemPostFilter::FilterPipeline& p, std::string name) { m_pipelines[name] = p; } @@ -162,13 +62,43 @@ void FemPostFilter::setActiveFilterPipeline(std::string name) { if(m_activePipeline != name && isValid()) { m_activePipeline = name; - m_pass->RemoveAllInputConnections(0); - polyDataSource->RemoveAllInputConnections(0); - polyDataSource->SetInputConnection(m_pipelines[m_activePipeline].visualisation->GetOutputPort()); - m_pass->SetInputConnection(m_pipelines[m_activePipeline].target->GetOutputPort()); } } +DocumentObjectExecReturn* FemPostFilter::execute(void) { + + Base::Console().Message("Recalculate filter\n"); + if(!m_pipelines.empty() && !m_activePipeline.empty()) { + + FemPostFilter::FilterPipeline& pipe = m_pipelines[m_activePipeline]; + pipe.source->SetInputDataObject(getInputData()); + pipe.target->Update(); + + Data.setValue(pipe.target->GetOutputDataObject(0)); + } + Base::Console().Message("Done Recalculate filter\n"); + return StdReturn; +} + +vtkDataObject* FemPostFilter::getInputData() { + + if(Input.getValue()) { + return Input.getValue()->Data.getValue(); + } + else { + //get the pipeline and use the pipelinedata + std::vector objs = getDocument()->getObjectsOfType(FemPostPipeline::getClassTypeId()); + for(std::vector::iterator it = objs.begin(); it != objs.end(); ++it) { + + if(static_cast(*it)->holdsPostObject(this)) { + + return static_cast(*it)->Data.getValue(); + } + } + } + + return NULL; +} PROPERTY_SOURCE(Fem::FemPostClipFilter, Fem::FemPostFilter) @@ -178,21 +108,17 @@ FemPostClipFilter::FemPostClipFilter(void) : FemPostFilter() { ADD_PROPERTY_TYPE(Function, (0), "Clip", App::Prop_None, "The function object which defines the clip regions"); ADD_PROPERTY_TYPE(InsideOut, (false), "Clip", App::Prop_None, "Invert the clip direction"); ADD_PROPERTY_TYPE(CutCells, (false), "Clip", App::Prop_None, "Decides if cells are cuttet and interpolated or if the cells are kept as a whole"); - - polyDataSource = vtkGeometryFilter::New(); FilterPipeline clip; m_clipper = vtkTableBasedClipDataSet::New(); clip.source = m_clipper; clip.target = m_clipper; - clip.visualisation = m_clipper; addFilterPipeline(clip, "clip"); FilterPipeline extr; m_extractor = vtkExtractGeometry::New(); extr.source = m_extractor; extr.target = m_extractor; - extr.visualisation = m_extractor; addFilterPipeline(extr, "extract"); m_extractor->SetExtractInside(0); @@ -228,6 +154,17 @@ void FemPostClipFilter::onChanged(const Property* prop) { Fem::FemPostFilter::onChanged(prop); } +short int FemPostClipFilter::mustExecute(void) const { + + if(Function.isTouched() || + InsideOut.isTouched() || + CutCells.isTouched()) { + + return 1; + } + else return App::DocumentObject::mustExecute(); +} + @@ -240,14 +177,11 @@ FemPostScalarClipFilter::FemPostScalarClipFilter(void) : FemPostFilter() { ADD_PROPERTY_TYPE(InsideOut, (false), "Clip", App::Prop_None, "Invert the clip direction"); Value.setConstraints(&m_constraints); - - polyDataSource = vtkGeometryFilter::New(); - + FilterPipeline clip; m_clipper = vtkTableBasedClipDataSet::New(); clip.source = m_clipper; clip.target = m_clipper; - clip.visualisation = m_clipper; addFilterPipeline(clip, "clip"); setActiveFilterPipeline("clip"); } @@ -257,10 +191,6 @@ FemPostScalarClipFilter::~FemPostScalarClipFilter() { } DocumentObjectExecReturn* FemPostScalarClipFilter::execute(void) { - - //update the available fields and set the correct input field data for clipping - if(!isConnected()) - return StdReturn; std::string val; if(m_scalarFields.getEnums() && Scalars.getValue() >= 0) @@ -268,18 +198,11 @@ DocumentObjectExecReturn* FemPostScalarClipFilter::execute(void) { std::vector array; - vtkDataObject* data; - if(hasInputAlgorithmConnected()) { - getConnectedInputAlgorithm()->Update(); - data = getConnectedInputAlgorithm()->GetOutputDataObject(0); - } - else - data = getConnectedInputData(); - - vtkDataSet* dset = dynamic_cast(data); - if(!dset) + vtkSmartPointer data = getInputData(); + if(!data || !data->IsA("vtkDataSet")) return StdReturn; + vtkDataSet* dset = vtkDataSet::SafeDownCast(data); vtkPointData* pd = dset->GetPointData(); for(int i=0; iGetNumberOfArrays(); ++i) { @@ -318,20 +241,25 @@ void FemPostScalarClipFilter::onChanged(const Property* prop) { Fem::FemPostFilter::onChanged(prop); } +short int FemPostScalarClipFilter::mustExecute(void) const { + + if(Value.isTouched() || + InsideOut.isTouched() || + Scalars.isTouched()) { + + return 1; + } + else return App::DocumentObject::mustExecute(); +} + void FemPostScalarClipFilter::setConstraintForField() { - vtkDataObject* data; - if(hasInputAlgorithmConnected()) { - getConnectedInputAlgorithm()->Update(); - data = getConnectedInputAlgorithm()->GetOutputDataObject(0); - } - else - data = getConnectedInputData(); - - vtkDataSet* dset = dynamic_cast(data); - if(!dset) + vtkSmartPointer data = getInputData(); + if(!data || !data->IsA("vtkDataSet")) return; + vtkDataSet* dset = vtkDataSet::SafeDownCast(data); + vtkDataArray* pdata = dset->GetPointData()->GetArray(Scalars.getValueAsString()); double p[2]; pdata->GetRange(p); @@ -347,14 +275,11 @@ FemPostWarpVectorFilter::FemPostWarpVectorFilter(void): FemPostFilter() { ADD_PROPERTY_TYPE(Factor, (0), "Warp", App::Prop_None, "The factor by which the vector is added to the node positions"); ADD_PROPERTY_TYPE(Vector, (long(0)), "Warp", App::Prop_None, "The field added to the node position"); - - polyDataSource = vtkGeometryFilter::New(); - + FilterPipeline warp; m_warp = vtkWarpVector::New(); warp.source = m_warp; warp.target = m_warp; - warp.visualisation = m_warp; addFilterPipeline(warp, "warp"); setActiveFilterPipeline("warp"); } @@ -365,10 +290,6 @@ FemPostWarpVectorFilter::~FemPostWarpVectorFilter() { DocumentObjectExecReturn* FemPostWarpVectorFilter::execute(void) { - - //update the available fields and set the correct input field data for clipping - if(!isConnected()) - return StdReturn; std::string val; if(m_vectorFields.getEnums() && Vector.getValue() >= 0) @@ -376,18 +297,11 @@ DocumentObjectExecReturn* FemPostWarpVectorFilter::execute(void) { std::vector array; - vtkDataObject* data; - if(hasInputAlgorithmConnected()) { - getConnectedInputAlgorithm()->Update(); - data = getConnectedInputAlgorithm()->GetOutputDataObject(0); - } - else - data = getConnectedInputData(); - - vtkDataSet* dset = dynamic_cast(data); - if(!dset) + vtkSmartPointer data = getInputData(); + if(!data || !data->IsA("vtkDataSet")) return StdReturn; + vtkDataSet* dset = vtkDataSet::SafeDownCast(data); vtkPointData* pd = dset->GetPointData(); for(int i=0; iGetNumberOfArrays(); ++i) { @@ -422,20 +336,27 @@ void FemPostWarpVectorFilter::onChanged(const Property* prop) { Fem::FemPostFilter::onChanged(prop); } +short int FemPostWarpVectorFilter::mustExecute(void) const { + + if(Factor.isTouched() || + Vector.isTouched()) { + + return 1; + } + else return App::DocumentObject::mustExecute(); +} + PROPERTY_SOURCE(Fem::FemPostCutFilter, Fem::FemPostFilter) FemPostCutFilter::FemPostCutFilter(void) : FemPostFilter() { ADD_PROPERTY_TYPE(Function, (0), "Cut", App::Prop_None, "The function object which defines the clip cut function"); - - polyDataSource = vtkGeometryFilter::New(); FilterPipeline clip; m_cutter = vtkCutter::New(); clip.source = m_cutter; clip.target = m_cutter; - clip.visualisation = m_cutter; addFilterPipeline(clip, "cut"); setActiveFilterPipeline("cut"); } @@ -455,3 +376,13 @@ void FemPostCutFilter::onChanged(const Property* prop) { Fem::FemPostFilter::onChanged(prop); } + +short int FemPostCutFilter::mustExecute(void) const { + + if(Function.isTouched()) { + + return 1; + } + else return App::DocumentObject::mustExecute(); +} + diff --git a/src/Mod/Fem/App/FemPostFilter.h b/src/Mod/Fem/App/FemPostFilter.h index 064af759b9..17773a1ff5 100644 --- a/src/Mod/Fem/App/FemPostFilter.h +++ b/src/Mod/Fem/App/FemPostFilter.h @@ -47,44 +47,27 @@ public: /// Constructor FemPostFilter(void); virtual ~FemPostFilter(); - + + App::PropertyLink Input; + virtual App::DocumentObjectExecReturn* execute(void); - vtkSmartPointer getOutputAlgorithm(); - - bool hasInputAlgorithmConnected(); - void connectInputAlgorithm(vtkSmartPointer algo); - vtkSmartPointer getConnectedInputAlgorithm(); - - bool hasInputDataConnected(); - void connectInputData(vtkSmartPointer data); - vtkSmartPointer getConnectedInputData(); - void clearInput(); - - //returns true if the pipelines are set up correctly - bool valid(); - //returns true if the filter is valid and connected - bool isConnected(); - //override poly data providing to let the object know we only provide poly data if connected - //to something - virtual bool providesPolyData(); - protected: + vtkDataObject* getInputData(); + //pipeline handling for derived filter struct FilterPipeline { - vtkSmartPointer source, target, visualisation; + vtkSmartPointer source, target; std::vector > algorithmStorage; }; void addFilterPipeline(const FilterPipeline& p, std::string name); void setActiveFilterPipeline(std::string name); - FilterPipeline& getFilterPipeline(std::string name); - + FilterPipeline& getFilterPipeline(std::string name); private: //handling of multiple pipelines which can be the filter std::map m_pipelines; std::string m_activePipeline; - vtkSmartPointer m_pass; }; class AppFemExport FemPostClipFilter : public FemPostFilter { @@ -102,13 +85,14 @@ public: virtual const char* getViewProviderName(void) const { return "FemGui::ViewProviderFemPostClip"; } + virtual short int mustExecute(void) const; protected: virtual void onChanged(const App::Property* prop); private: - vtkSmartPointer m_clipper; - vtkSmartPointer m_extractor; + vtkSmartPointer m_clipper; + vtkSmartPointer m_extractor; }; @@ -127,6 +111,7 @@ public: virtual const char* getViewProviderName(void) const { return "FemGui::ViewProviderFemPostScalarClip"; } + virtual short int mustExecute(void) const; protected: virtual App::DocumentObjectExecReturn* execute(void); @@ -153,6 +138,7 @@ public: virtual const char* getViewProviderName(void) const { return "FemGui::ViewProviderFemPostWarpVector"; } + virtual short int mustExecute(void) const; protected: virtual App::DocumentObjectExecReturn* execute(void); @@ -176,6 +162,7 @@ public: virtual const char* getViewProviderName(void) const { return "FemGui::ViewProviderFemPostCut"; } + virtual short int mustExecute(void) const; protected: virtual void onChanged(const App::Property* prop); diff --git a/src/Mod/Fem/App/FemPostFunction.h b/src/Mod/Fem/App/FemPostFunction.h index 58f3a232ee..c019bf9a38 100644 --- a/src/Mod/Fem/App/FemPostFunction.h +++ b/src/Mod/Fem/App/FemPostFunction.h @@ -31,6 +31,7 @@ #include #include #include +#include namespace Fem { diff --git a/src/Mod/Fem/App/FemPostObject.cpp b/src/Mod/Fem/App/FemPostObject.cpp index e3d44a623a..883d272423 100644 --- a/src/Mod/Fem/App/FemPostObject.cpp +++ b/src/Mod/Fem/App/FemPostObject.cpp @@ -42,38 +42,21 @@ PROPERTY_SOURCE(Fem::FemPostObject, App::GeoFeature) FemPostObject::FemPostObject() { - ADD_PROPERTY(ModificationTime,(0)); + ADD_PROPERTY(Data,(0)); } FemPostObject::~FemPostObject() { } -short FemPostObject::mustExecute(void) const -{ - return 1; -} +vtkBoundingBox FemPostObject::getBoundingBox() { -DocumentObjectExecReturn* FemPostObject::execute(void) { - - if(providesPolyData()) { - polyDataSource->Update(); - vtkSmartPointer poly = polyDataSource->GetOutput(); - - if(static_cast(ModificationTime.getValue()) != poly->GetMTime()) { - - //update the bounding box - m_boundingBox = vtkBoundingBox(poly->GetBounds()); - - //update the modification time to let the viewprovider know something changed - ModificationTime.setValue(static_cast(poly->GetMTime())); - } - } + vtkBoundingBox box; - return DocumentObject::StdReturn; -} - -void FemPostObject::onChanged(const Property* prop) -{ - App::GeoFeature::onChanged(prop); + if(Data.getValue() && Data.getValue()->IsA("vtkDataSet")) + box.AddBounds(vtkDataSet::SafeDownCast(Data.getValue())->GetBounds()); + + //TODO: add calculation of multiblock and Multipiece datasets + + return box; } diff --git a/src/Mod/Fem/App/FemPostObject.h b/src/Mod/Fem/App/FemPostObject.h index 0907ceb051..4688bb4e81 100644 --- a/src/Mod/Fem/App/FemPostObject.h +++ b/src/Mod/Fem/App/FemPostObject.h @@ -25,11 +25,10 @@ #define Fem_FemPostObject_H #include - -#include -#include +#include "PropertyPostDataObject.h" #include + namespace Fem { @@ -43,33 +42,9 @@ public: FemPostObject(void); virtual ~FemPostObject(); - App::PropertyInteger ModificationTime; - - /// returns the type name of the ViewProvider - virtual const char* getViewProviderName(void) const { - return "FemGui::ViewProviderFemPostObject"; - } + Fem::PropertyPostDataObject Data; - short mustExecute(void) const; - virtual App::DocumentObjectExecReturn* execute(void); - - //bounding box handling. By default the bounding box is calcualted from the poly data output - //which is visualized - virtual vtkBoundingBox getBoundingBox() {return m_boundingBox;}; - - //poly data algorithm handling - virtual bool providesPolyData() {return getPolyAlgorithm()!=NULL;}; - vtkSmartPointer getPolyAlgorithm() {return polyDataSource;}; - - -protected: - virtual void onChanged(const App::Property* prop); - - //members - vtkSmartPointer polyDataSource; - -private: - vtkBoundingBox m_boundingBox; + vtkBoundingBox getBoundingBox(); }; } //namespace Fem diff --git a/src/Mod/Fem/App/FemPostPipeline.cpp b/src/Mod/Fem/App/FemPostPipeline.cpp index 88a36f91c7..4b9e72da87 100644 --- a/src/Mod/Fem/App/FemPostPipeline.cpp +++ b/src/Mod/Fem/App/FemPostPipeline.cpp @@ -56,13 +56,11 @@ const char* FemPostPipeline::ModeEnums[]= {"Serial","Parallel",NULL}; FemPostPipeline::FemPostPipeline() { ADD_PROPERTY_TYPE(Filter, (0), "Pipeline", App::Prop_None, "The filter used in in this pipeline"); - ADD_PROPERTY_TYPE(Function, (0), "Pipeline", App::Prop_Hidden, "The function provider which groups all pipeline functions"); + ADD_PROPERTY_TYPE(Functions, (0), "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 parrallel every" "filter gets the pipelien source as input."); Mode.setEnums(ModeEnums); - - source = vtkUnstructuredGrid::New(); } FemPostPipeline::~FemPostPipeline() @@ -76,21 +74,11 @@ short FemPostPipeline::mustExecute(void) const DocumentObjectExecReturn* FemPostPipeline::execute(void) { -// Base::Console().Message("Pipeline analysis: \n"); -// Base::Console().Message("Data Type: %i\n", source->GetDataObjectType()); -// -// if(source->GetDataObjectType() == VTK_STRUCTURED_GRID ) { -// vtkStructuredGrid* poly = static_cast(source.GetPointer()); -// vtkPointData* point = poly->GetPointData(); -// Base::Console().Message("Point components: %i\n", point->GetNumberOfComponents()); -// Base::Console().Message("Point arrays: %i\n", point->GetNumberOfArrays()); -// Base::Console().Message("Point tuples: %i\n", point->GetNumberOfTuples()); -// -// vtkCellData* cell = poly->GetCellData(); -// Base::Console().Message("Cell components: %i\n", cell->GetNumberOfComponents()); -// Base::Console().Message("Cell arrays: %i\n", cell->GetNumberOfArrays()); -// Base::Console().Message("Point tuples: %i\n", cell->GetNumberOfTuples()); -// } + + //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 + + return Fem::FemPostObject::execute(); } @@ -98,9 +86,14 @@ DocumentObjectExecReturn* FemPostPipeline::execute(void) { bool FemPostPipeline::canRead(Base::FileInfo File) { - if (File.hasExtension("vtk") ) + if (File.hasExtension("vtk") || + File.hasExtension("vtp") || + File.hasExtension("vts") || + File.hasExtension("vtr") || + File.hasExtension("vtu") || + File.hasExtension("vti")) return true; - + return false; } @@ -111,21 +104,16 @@ void FemPostPipeline::read(Base::FileInfo File) { if (!File.isReadable()) throw Base::Exception("File to load not existing or not readable"); - if (File.hasExtension("vtk") ) { + if (canRead(File)) { vtkSmartPointer reader = vtkSmartPointer::New(); reader->SetFileName(File.filePath().c_str()); reader->Update(); - source = reader->GetOutput(); - + Data.setValue(reader->GetOutput()); } else{ throw Base::Exception("Unknown extension"); } - - polyDataSource = vtkGeometryFilter::New(); - polyDataSource->SetInputData(source); - polyDataSource->Update(); } @@ -151,26 +139,53 @@ void FemPostPipeline::onChanged(const Property* prop) std::vector::iterator it = objs.begin(); FemPostFilter* filter = static_cast(*it); - //the first one is always connected to the pipeline - if(!filter->hasInputDataConnected() || filter->getConnectedInputData() != getSource()) - filter->connectInputData(getSource()); + //If we have a Input we need to ensure our filters are connected correctly + if(Input.getValue()) { - //all the others need to be connected to the previous filter or the source, dependend on the mode - ++it; - for(; it != objs.end(); ++it) { - FemPostFilter* nextFilter = static_cast(*it); + //the first filter is always connected to the input + if(filter->Input.getValue() != Input.getValue()) + filter->Input.setValue(Input.getValue()); - if(Mode.getValue() == 0) { - if(!nextFilter->hasInputAlgorithmConnected() || nextFilter->getConnectedInputAlgorithm() != filter->getOutputAlgorithm()) - nextFilter->connectInputAlgorithm(filter->getOutputAlgorithm()); - } - else { - if(!nextFilter->hasInputDataConnected() || nextFilter->getConnectedInputData() != getSource()) - nextFilter->connectInputData(getSource()); - } + //all the others need to be connected to the previous filter or the source, dependend on the mode + ++it; + for(; it != objs.end(); ++it) { + FemPostFilter* nextFilter = static_cast(*it); + + if(Mode.getValue() == 0) { //serial mode + if( nextFilter->Input.getValue() != filter) + nextFilter->Input.setValue(filter); + } + else { //Parallel mode + if( nextFilter->Input.getValue() != Input.getValue()) + nextFilter->Input.setValue(Input.getValue()); + } + + filter = nextFilter; + }; + } + //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() != NULL) + filter->Input.setValue(NULL); - filter = nextFilter; - }; + //all the others need to be connected to the previous filter or grab the data, dependend on mode + ++it; + for(; it != objs.end(); ++it) { + FemPostFilter* nextFilter = static_cast(*it); + + if(Mode.getValue() == 0) { //serial mode + if( nextFilter->Input.getValue() != filter) + nextFilter->Input.setValue(filter); + } + else { //Parallel mode + if( nextFilter->Input.getValue() != NULL) + nextFilter->Input.setValue(NULL); + } + + filter = nextFilter; + }; + } } App::GeoFeature::onChanged(prop); @@ -185,11 +200,21 @@ FemPostObject* FemPostPipeline::getLastPostObject() { return static_cast(Filter.getValues().back()); } +bool FemPostPipeline::holdsPostObject(FemPostObject* obj) { + + std::vector::const_iterator it = Filter.getValues().begin(); + for(; it != Filter.getValues().end(); ++it) { + + if(*it == obj) + return true; + } + return false; +} + void FemPostPipeline::load(FemResultObject* res) { vtkSmartPointer grid = vtkUnstructuredGrid::New(); - source = grid; //first copy the mesh over //######################## @@ -329,15 +354,11 @@ void FemPostPipeline::load(FemResultObject* res) { for(std::vector::const_iterator it=vec.begin(); it!=vec.end(); ++it) { double tuple[] = {it->x, it->y, it->z}; - Base::Console().Message("disp mag; %f\n", it->Length()); data->InsertNextTuple(tuple); } grid->GetPointData()->AddArray(data); } - - polyDataSource = vtkGeometryFilter::New(); - polyDataSource->SetInputData(source); - polyDataSource->Update(); + Data.setValue(grid); } diff --git a/src/Mod/Fem/App/FemPostPipeline.h b/src/Mod/Fem/App/FemPostPipeline.h index 2d561ea7cc..6a23acef15 100644 --- a/src/Mod/Fem/App/FemPostPipeline.h +++ b/src/Mod/Fem/App/FemPostPipeline.h @@ -35,7 +35,7 @@ namespace Fem { -class AppFemExport FemPostPipeline : public Fem::FemPostObject +class AppFemExport FemPostPipeline : public Fem::FemPostFilter { PROPERTY_HEADER(Fem::FemPostPipeline); @@ -45,7 +45,7 @@ public: virtual ~FemPostPipeline(); App::PropertyLinkList Filter; - App::PropertyLink Function; + App::PropertyLink Functions; App::PropertyEnumeration Mode; short mustExecute(void) const; @@ -64,14 +64,13 @@ public: void load(FemResultObject* res); //Pipeline handling - vtkSmartPointer getSource() {return source;}; FemPostObject* getLastPostObject(); + bool holdsPostObject(FemPostObject* obj); protected: virtual void onChanged(const App::Property* prop); private: - vtkSmartPointer source; static const char* ModeEnums[]; }; diff --git a/src/Mod/Fem/Gui/Command.cpp b/src/Mod/Fem/Gui/Command.cpp index 8bf1911fbe..7ada716d93 100644 --- a/src/Mod/Fem/Gui/Command.cpp +++ b/src/Mod/Fem/Gui/Command.cpp @@ -930,14 +930,14 @@ void CmdFemPostFunctions::activated(int iMsg) //check if the pipeline has a filter provider and add one if needed Fem::FemPostFunctionProvider* provider; - if(!pipeline->Function.getValue() || pipeline->Function.getValue()->getTypeId() != Fem::FemPostFunctionProvider::getClassTypeId()) { + if(!pipeline->Functions.getValue() || pipeline->Functions.getValue()->getTypeId() != Fem::FemPostFunctionProvider::getClassTypeId()) { std::string FuncName = getUniqueObjectName("Functions"); doCommand(Doc,"App.ActiveDocument.addObject('Fem::FemPostFunctionProvider','%s')", FuncName.c_str()); - doCommand(Doc,"App.ActiveDocument.%s.Function = App.ActiveDocument.%s", pipeline->getNameInDocument(), FuncName.c_str()); + doCommand(Doc,"App.ActiveDocument.%s.Functions = App.ActiveDocument.%s", pipeline->getNameInDocument(), FuncName.c_str()); provider = static_cast(getDocument()->getObject(FuncName.c_str())); } else - provider = static_cast(pipeline->Function.getValue()); + provider = static_cast(pipeline->Functions.getValue()); //build the object std::string FeatName = getUniqueObjectName(name.c_str()); diff --git a/src/Mod/Fem/Gui/Command.cpp.orig b/src/Mod/Fem/Gui/Command.cpp.orig index 7e1adebfd6..60d18be1a1 100644 --- a/src/Mod/Fem/Gui/Command.cpp.orig +++ b/src/Mod/Fem/Gui/Command.cpp.orig @@ -1,4 +1,4 @@ -<<<<<<< 90bd13697472f7f895b8e12b9d1050220d69f763 +<<<<<<< 43b51b168bc838480fd6a0a4b9f67e0bf864a560 /*************************************************************************** * Copyright (c) 2008 Jürgen Riegel (juergen.riegel@web.de) * * * @@ -948,6 +948,22 @@ void CmdFemPostFunctions::activated(int iMsg) doCommand(Doc,"App.ActiveDocument.%s.Functions = __list__", provider->getNameInDocument()); doCommand(Doc,"del __list__"); + //set the default values, for this get the bounding box + vtkBoundingBox box = pipeline->getBoundingBox(); + + double center[3]; + box.GetCenter(center); + + if (iMsg==0) + doCommand(Doc,"App.ActiveDocument.%s.Origin = App.Vector(%f, %f, %f)", FeatName.c_str(), center[0], + center[1], center[2]); + else if (iMsg==1) { + doCommand(Doc,"App.ActiveDocument.%s.Center = App.Vector(%f, %f, %f)", FeatName.c_str(), center[0], + center[1] + box.GetLength(1)/2, center[2] + box.GetLength(2)/2); + doCommand(Doc,"App.ActiveDocument.%s.Radius = %f", FeatName.c_str(), box.GetDiagonalLength()/2); + } + + this->updateActive(); //most of the times functions are added inside of a filter, make sure this still works if(Gui::Application::Instance->activeDocument()->getInEdit() == NULL) @@ -2072,14 +2088,14 @@ void CmdFemPostFunctions::activated(int iMsg) //check if the pipeline has a filter provider and add one if needed Fem::FemPostFunctionProvider* provider; - if(!pipeline->Function.getValue() || pipeline->Function.getValue()->getTypeId() != Fem::FemPostFunctionProvider::getClassTypeId()) { + if(!pipeline->Functions.getValue() || pipeline->Functions.getValue()->getTypeId() != Fem::FemPostFunctionProvider::getClassTypeId()) { std::string FuncName = getUniqueObjectName("Functions"); doCommand(Doc,"App.ActiveDocument.addObject('Fem::FemPostFunctionProvider','%s')", FuncName.c_str()); - doCommand(Doc,"App.ActiveDocument.%s.Function = App.ActiveDocument.%s", pipeline->getNameInDocument(), FuncName.c_str()); + doCommand(Doc,"App.ActiveDocument.%s.Functions = App.ActiveDocument.%s", pipeline->getNameInDocument(), FuncName.c_str()); provider = static_cast(getDocument()->getObject(FuncName.c_str())); } else - provider = static_cast(pipeline->Function.getValue()); + provider = static_cast(pipeline->Functions.getValue()); //build the object std::string FeatName = getUniqueObjectName(name.c_str()); @@ -2296,4 +2312,4 @@ void CreateFemCommands(void) rcCmdMgr.addCommand(new CmdFemPostCutFilter); #endif } ->>>>>>> Update function manipulators +>>>>>>> FreeCADify the vtk post processing diff --git a/src/Mod/Fem/Gui/TaskPostBoxes.cpp b/src/Mod/Fem/Gui/TaskPostBoxes.cpp index 58c9253eb0..c2ed472173 100644 --- a/src/Mod/Fem/Gui/TaskPostBoxes.cpp +++ b/src/Mod/Fem/Gui/TaskPostBoxes.cpp @@ -289,13 +289,13 @@ void TaskPostClip::collectImplicitFunctions() { pipelines = App::GetApplication().getActiveDocument()->getObjectsOfType(); if (!pipelines.empty()) { Fem::FemPostPipeline *pipeline = pipelines.front(); - if(pipeline->Function.getValue() && - pipeline->Function.getValue()->getTypeId() == Fem::FemPostFunctionProvider::getClassTypeId()) { + if(pipeline->Functions.getValue() && + pipeline->Functions.getValue()->getTypeId() == Fem::FemPostFunctionProvider::getClassTypeId()) { ui->FunctionBox->clear(); QStringList items; const std::vector& funcs = static_cast( - pipeline->Function.getValue())->Functions.getValues(); + pipeline->Functions.getValue())->Functions.getValues(); for(std::size_t i=0; igetNameInDocument())); @@ -317,11 +317,11 @@ void TaskPostClip::on_FunctionBox_currentIndexChanged(int idx) { pipelines = App::GetApplication().getActiveDocument()->getObjectsOfType(); if (!pipelines.empty()) { Fem::FemPostPipeline *pipeline = pipelines.front(); - if(pipeline->Function.getValue() && - pipeline->Function.getValue()->getTypeId() == Fem::FemPostFunctionProvider::getClassTypeId()) { + if(pipeline->Functions.getValue() && + pipeline->Functions.getValue()->getTypeId() == Fem::FemPostFunctionProvider::getClassTypeId()) { const std::vector& funcs = static_cast( - pipeline->Function.getValue())->Functions.getValues(); + pipeline->Functions.getValue())->Functions.getValues(); if(idx>=0) static_cast(getObject())->Function.setValue(funcs[idx]); else @@ -581,13 +581,13 @@ void TaskPostCut::collectImplicitFunctions() { pipelines = App::GetApplication().getActiveDocument()->getObjectsOfType(); if (!pipelines.empty()) { Fem::FemPostPipeline *pipeline = pipelines.front(); - if(pipeline->Function.getValue() && - pipeline->Function.getValue()->getTypeId() == Fem::FemPostFunctionProvider::getClassTypeId()) { + if(pipeline->Functions.getValue() && + pipeline->Functions.getValue()->getTypeId() == Fem::FemPostFunctionProvider::getClassTypeId()) { ui->FunctionBox->clear(); QStringList items; const std::vector& funcs = static_cast( - pipeline->Function.getValue())->Functions.getValues(); + pipeline->Functions.getValue())->Functions.getValues(); for(std::size_t i=0; igetNameInDocument())); @@ -609,11 +609,11 @@ void TaskPostCut::on_FunctionBox_currentIndexChanged(int idx) { pipelines = App::GetApplication().getActiveDocument()->getObjectsOfType(); if (!pipelines.empty()) { Fem::FemPostPipeline *pipeline = pipelines.front(); - if(pipeline->Function.getValue() && - pipeline->Function.getValue()->getTypeId() == Fem::FemPostFunctionProvider::getClassTypeId()) { + if(pipeline->Functions.getValue() && + pipeline->Functions.getValue()->getTypeId() == Fem::FemPostFunctionProvider::getClassTypeId()) { const std::vector& funcs = static_cast( - pipeline->Function.getValue())->Functions.getValues(); + pipeline->Functions.getValue())->Functions.getValues(); if(idx>=0) static_cast(getObject())->Function.setValue(funcs[idx]); else diff --git a/src/Mod/Fem/Gui/ViewProviderFemPostObject.cpp b/src/Mod/Fem/Gui/ViewProviderFemPostObject.cpp index 1c48bc7c7f..318dfaa164 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemPostObject.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemPostObject.cpp @@ -93,6 +93,20 @@ ViewProviderFemPostObject::ViewProviderFemPostObject() : m_blockPropertyChanges( m_drawStyle->ref(); m_seperator = new SoSeparator(); m_seperator->ref(); + + //create the vtk algorithms we use for visualisation + m_outline = vtkOutlineCornerFilter::New(); + m_points = vtkVertexGlyphFilter::New(); + m_surface = vtkGeometryFilter::New(); + m_wireframe = vtkExtractEdges::New(); + m_surfaceEdges = vtkAppendPolyData::New(); + m_surfaceEdges->AddInputConnection(m_surface->GetOutputPort()); + m_surfaceEdges->AddInputConnection(m_wireframe->GetOutputPort()); + + m_lookup = vtkLookupTable::New(); + m_lookup->SetRampToLinear(); + + m_currentAlgorithm = m_outline; } ViewProviderFemPostObject::~ViewProviderFemPostObject() @@ -147,15 +161,12 @@ void ViewProviderFemPostObject::attach(App::DocumentObject *pcObj) void ViewProviderFemPostObject::setDisplayMode(const char* ModeName) { - if(!setupPipeline()) - return; - if (strcmp("Outline",ModeName)==0) m_currentAlgorithm = m_outline; else if (strcmp("Surface with Edges",ModeName)==0) m_currentAlgorithm = m_surfaceEdges; else if (strcmp("Surface",ModeName)==0) - m_currentAlgorithm = static_cast(getObject())->getPolyAlgorithm(); + m_currentAlgorithm = m_surface; else if (strcmp("Wireframe",ModeName)==0) m_currentAlgorithm = m_wireframe; else if (strcmp("Nodes",ModeName)==0) @@ -257,9 +268,6 @@ void ViewProviderFemPostObject::updateProperties() { void ViewProviderFemPostObject::update3D() { - if(!setupPipeline()) - return; - vtkPolyData* pd = m_currentAlgorithm->GetOutput(); vtkPointData *pntData; @@ -468,41 +476,23 @@ void ViewProviderFemPostObject::WriteTransperency() { void ViewProviderFemPostObject::updateData(const App::Property* p) { - if( strcmp(p->getName(), "ModificationTime") == 0 && setupPipeline() ) { + if( strcmp(p->getName(), "Data") == 0 ) { update(); } } bool ViewProviderFemPostObject::setupPipeline() { - if(!static_cast(getObject())->providesPolyData()) + vtkDataObject* data = static_cast(getObject())->Data.getValue(); + + if(!data) return false; - if(!m_currentAlgorithm) { - vtkSmartPointer algorithm = static_cast(getObject())->getPolyAlgorithm(); - - m_outline = vtkOutlineCornerFilter::New(); - m_outline->SetInputConnection(algorithm->GetOutputPort()); - - m_points = vtkVertexGlyphFilter::New(); - m_points->SetInputConnection(algorithm->GetOutputPort()); - - m_surface = vtkGeometryFilter::New(); - m_surface->SetInputConnection(algorithm->GetOutputPort()); - - m_wireframe = vtkExtractEdges::New(); - m_wireframe->SetInputConnection(algorithm->GetOutputPort()); - - m_surfaceEdges = vtkAppendPolyData::New(); - m_surfaceEdges->AddInputConnection(m_surface->GetOutputPort()); - m_surfaceEdges->AddInputConnection(m_wireframe->GetOutputPort()); - - m_lookup = vtkLookupTable::New(); - m_lookup->SetRampToLinear(); - - m_currentAlgorithm = m_outline; - } + m_outline->SetInputData(data); + m_surface->SetInputData(data); + m_wireframe->SetInputData(data); + m_points->SetInputData(data); return true; } @@ -513,7 +503,6 @@ void ViewProviderFemPostObject::onChanged(const App::Property* prop) { if(m_blockPropertyChanges) return; - Base::Console().Message("On Changed: %s\n", prop->getName()); if(prop == &Field && setupPipeline()) { updateProperties(); WriteColorData(); diff --git a/src/Mod/Fem/Gui/ViewProviderFemPostPipeline.cpp b/src/Mod/Fem/Gui/ViewProviderFemPostPipeline.cpp index ccc60b9cef..f6fb84a255 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemPostPipeline.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemPostPipeline.cpp @@ -47,8 +47,8 @@ std::vector< App::DocumentObject* > ViewProviderFemPostPipeline::claimChildren(v Fem::FemPostPipeline* pipeline = static_cast(getObject()); std::vector children; - if(pipeline->Function.getValue()) - children.push_back(pipeline->Function.getValue()); + if(pipeline->Functions.getValue()) + children.push_back(pipeline->Functions.getValue()); children.insert(children.end(), pipeline->Filter.getValues().begin(), pipeline->Filter.getValues().end()); Base::Console().Message("claim children pipeline: %i\n", children.size()); @@ -77,14 +77,14 @@ void ViewProviderFemPostPipeline::updateFunctionSize() { //we need to get the bounding box and set the function provider size Fem::FemPostPipeline* obj = static_cast(getObject()); - if(!obj->Function.getValue() || !obj->Function.getValue()->isDerivedFrom(Fem::FemPostFunctionProvider::getClassTypeId())) + if(!obj->Functions.getValue() || !obj->Functions.getValue()->isDerivedFrom(Fem::FemPostFunctionProvider::getClassTypeId())) return; //get the functtion provider FemGui::ViewProviderFemPostFunctionProvider* vp = static_cast( - Gui::Application::Instance->getViewProvider(obj->Function.getValue())); + Gui::Application::Instance->getViewProvider(obj->Functions.getValue())); - if(obj->providesPolyData()) { + if(obj->Data.getValue() && obj->Data.getValue()->IsA("vtkDataSet")) { vtkBoundingBox box = obj->getBoundingBox(); vp->SizeX.setValue(box.GetLength(0)*1.2);