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);