FEM Post: FreeCADify the vtk post processing
- Data property for saving/loading vtk data - Use FreeCAD recompute system instead of vtk pipeline
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "FemPostFilter.h"
|
||||
#include "FemPostPipeline.h"
|
||||
#include <Base/Console.h>
|
||||
#include <App/Document.h>
|
||||
#include <App/DocumentObjectPy.h>
|
||||
#include <vtkFieldData.h>
|
||||
#include <vtkPointData.h>
|
||||
@@ -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<std::string, FilterPipeline>::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<std::string, FilterPipeline>::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<std::string, FilterPipeline>::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<FemPostObject*>()->Data.getValue();
|
||||
}
|
||||
else {
|
||||
//get the pipeline and use the pipelinedata
|
||||
std::vector<App::DocumentObject*> objs = getDocument()->getObjectsOfType(FemPostPipeline::getClassTypeId());
|
||||
for(std::vector<App::DocumentObject*>::iterator it = objs.begin(); it != objs.end(); ++it) {
|
||||
|
||||
if(static_cast<FemPostPipeline*>(*it)->holdsPostObject(this)) {
|
||||
|
||||
return static_cast<FemPostObject*>(*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<std::string> array;
|
||||
|
||||
vtkDataObject* data;
|
||||
if(hasInputAlgorithmConnected()) {
|
||||
getConnectedInputAlgorithm()->Update();
|
||||
data = getConnectedInputAlgorithm()->GetOutputDataObject(0);
|
||||
}
|
||||
else
|
||||
data = getConnectedInputData();
|
||||
|
||||
vtkDataSet* dset = dynamic_cast<vtkDataSet*>(data);
|
||||
if(!dset)
|
||||
vtkSmartPointer<vtkDataObject> data = getInputData();
|
||||
if(!data || !data->IsA("vtkDataSet"))
|
||||
return StdReturn;
|
||||
|
||||
vtkDataSet* dset = vtkDataSet::SafeDownCast(data);
|
||||
vtkPointData* pd = dset->GetPointData();
|
||||
|
||||
for(int i=0; i<pd->GetNumberOfArrays(); ++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<vtkDataSet*>(data);
|
||||
if(!dset)
|
||||
vtkSmartPointer<vtkDataObject> 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<std::string> array;
|
||||
|
||||
vtkDataObject* data;
|
||||
if(hasInputAlgorithmConnected()) {
|
||||
getConnectedInputAlgorithm()->Update();
|
||||
data = getConnectedInputAlgorithm()->GetOutputDataObject(0);
|
||||
}
|
||||
else
|
||||
data = getConnectedInputData();
|
||||
|
||||
vtkDataSet* dset = dynamic_cast<vtkDataSet*>(data);
|
||||
if(!dset)
|
||||
vtkSmartPointer<vtkDataObject> data = getInputData();
|
||||
if(!data || !data->IsA("vtkDataSet"))
|
||||
return StdReturn;
|
||||
|
||||
vtkDataSet* dset = vtkDataSet::SafeDownCast(data);
|
||||
vtkPointData* pd = dset->GetPointData();
|
||||
|
||||
for(int i=0; i<pd->GetNumberOfArrays(); ++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();
|
||||
}
|
||||
|
||||
|
||||
@@ -47,44 +47,27 @@ public:
|
||||
/// Constructor
|
||||
FemPostFilter(void);
|
||||
virtual ~FemPostFilter();
|
||||
|
||||
|
||||
App::PropertyLink Input;
|
||||
|
||||
virtual App::DocumentObjectExecReturn* execute(void);
|
||||
|
||||
vtkSmartPointer<vtkAlgorithm> getOutputAlgorithm();
|
||||
|
||||
bool hasInputAlgorithmConnected();
|
||||
void connectInputAlgorithm(vtkSmartPointer<vtkAlgorithm> algo);
|
||||
vtkSmartPointer<vtkAlgorithm> getConnectedInputAlgorithm();
|
||||
|
||||
bool hasInputDataConnected();
|
||||
void connectInputData(vtkSmartPointer<vtkDataSet> data);
|
||||
vtkSmartPointer<vtkDataObject> 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<vtkAlgorithm> source, target, visualisation;
|
||||
vtkSmartPointer<vtkAlgorithm> source, target;
|
||||
std::vector<vtkSmartPointer<vtkAlgorithm> > 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<std::string, FilterPipeline> m_pipelines;
|
||||
std::string m_activePipeline;
|
||||
vtkSmartPointer<vtkPassThrough> 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<vtkTableBasedClipDataSet> m_clipper;
|
||||
vtkSmartPointer<vtkExtractGeometry> m_extractor;
|
||||
vtkSmartPointer<vtkTableBasedClipDataSet> m_clipper;
|
||||
vtkSmartPointer<vtkExtractGeometry> 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);
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <vtkImplicitFunction.h>
|
||||
#include <vtkPlane.h>
|
||||
#include <vtkSphere.h>
|
||||
#include <vtkBoundingBox.h>
|
||||
|
||||
namespace Fem
|
||||
{
|
||||
|
||||
@@ -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<vtkPolyData> poly = polyDataSource->GetOutput();
|
||||
|
||||
if(static_cast<unsigned long>(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<long>(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;
|
||||
}
|
||||
|
||||
@@ -25,11 +25,10 @@
|
||||
#define Fem_FemPostObject_H
|
||||
|
||||
#include <App/GeoFeature.h>
|
||||
|
||||
#include <vtkSmartPointer.h>
|
||||
#include <vtkPolyDataAlgorithm.h>
|
||||
#include "PropertyPostDataObject.h"
|
||||
#include <vtkBoundingBox.h>
|
||||
|
||||
|
||||
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<vtkPolyDataAlgorithm> getPolyAlgorithm() {return polyDataSource;};
|
||||
|
||||
|
||||
protected:
|
||||
virtual void onChanged(const App::Property* prop);
|
||||
|
||||
//members
|
||||
vtkSmartPointer<vtkPolyDataAlgorithm> polyDataSource;
|
||||
|
||||
private:
|
||||
vtkBoundingBox m_boundingBox;
|
||||
vtkBoundingBox getBoundingBox();
|
||||
};
|
||||
|
||||
} //namespace Fem
|
||||
|
||||
@@ -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<vtkStructuredGrid*>(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<vtkDataSetReader> reader = vtkSmartPointer<vtkDataSetReader>::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<App::DocumentObject*>::iterator it = objs.begin();
|
||||
FemPostFilter* filter = static_cast<FemPostFilter*>(*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<FemPostFilter*>(*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<FemPostFilter*>(*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<FemPostFilter*>(*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<FemPostObject*>(Filter.getValues().back());
|
||||
}
|
||||
|
||||
bool FemPostPipeline::holdsPostObject(FemPostObject* obj) {
|
||||
|
||||
std::vector<App::DocumentObject*>::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<vtkUnstructuredGrid> grid = vtkUnstructuredGrid::New();
|
||||
source = grid;
|
||||
|
||||
//first copy the mesh over
|
||||
//########################
|
||||
@@ -329,15 +354,11 @@ void FemPostPipeline::load(FemResultObject* res) {
|
||||
|
||||
for(std::vector<Base::Vector3d>::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);
|
||||
}
|
||||
|
||||
@@ -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<vtkDataSet> getSource() {return source;};
|
||||
FemPostObject* getLastPostObject();
|
||||
bool holdsPostObject(FemPostObject* obj);
|
||||
|
||||
protected:
|
||||
virtual void onChanged(const App::Property* prop);
|
||||
|
||||
private:
|
||||
vtkSmartPointer<vtkDataSet> source;
|
||||
static const char* ModeEnums[];
|
||||
};
|
||||
|
||||
|
||||
@@ -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<Fem::FemPostFunctionProvider*>(getDocument()->getObject(FuncName.c_str()));
|
||||
}
|
||||
else
|
||||
provider = static_cast<Fem::FemPostFunctionProvider*>(pipeline->Function.getValue());
|
||||
provider = static_cast<Fem::FemPostFunctionProvider*>(pipeline->Functions.getValue());
|
||||
|
||||
//build the object
|
||||
std::string FeatName = getUniqueObjectName(name.c_str());
|
||||
|
||||
@@ -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<Fem::FemPostFunctionProvider*>(getDocument()->getObject(FuncName.c_str()));
|
||||
}
|
||||
else
|
||||
provider = static_cast<Fem::FemPostFunctionProvider*>(pipeline->Function.getValue());
|
||||
provider = static_cast<Fem::FemPostFunctionProvider*>(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
|
||||
|
||||
@@ -289,13 +289,13 @@ void TaskPostClip::collectImplicitFunctions() {
|
||||
pipelines = App::GetApplication().getActiveDocument()->getObjectsOfType<Fem::FemPostPipeline>();
|
||||
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<App::DocumentObject*>& funcs = static_cast<Fem::FemPostFunctionProvider*>(
|
||||
pipeline->Function.getValue())->Functions.getValues();
|
||||
pipeline->Functions.getValue())->Functions.getValues();
|
||||
for(std::size_t i=0; i<funcs.size(); ++i)
|
||||
items.push_back(QString::fromAscii(funcs[i]->getNameInDocument()));
|
||||
|
||||
@@ -317,11 +317,11 @@ void TaskPostClip::on_FunctionBox_currentIndexChanged(int idx) {
|
||||
pipelines = App::GetApplication().getActiveDocument()->getObjectsOfType<Fem::FemPostPipeline>();
|
||||
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<App::DocumentObject*>& funcs = static_cast<Fem::FemPostFunctionProvider*>(
|
||||
pipeline->Function.getValue())->Functions.getValues();
|
||||
pipeline->Functions.getValue())->Functions.getValues();
|
||||
if(idx>=0)
|
||||
static_cast<Fem::FemPostClipFilter*>(getObject())->Function.setValue(funcs[idx]);
|
||||
else
|
||||
@@ -581,13 +581,13 @@ void TaskPostCut::collectImplicitFunctions() {
|
||||
pipelines = App::GetApplication().getActiveDocument()->getObjectsOfType<Fem::FemPostPipeline>();
|
||||
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<App::DocumentObject*>& funcs = static_cast<Fem::FemPostFunctionProvider*>(
|
||||
pipeline->Function.getValue())->Functions.getValues();
|
||||
pipeline->Functions.getValue())->Functions.getValues();
|
||||
for(std::size_t i=0; i<funcs.size(); ++i)
|
||||
items.push_back(QString::fromAscii(funcs[i]->getNameInDocument()));
|
||||
|
||||
@@ -609,11 +609,11 @@ void TaskPostCut::on_FunctionBox_currentIndexChanged(int idx) {
|
||||
pipelines = App::GetApplication().getActiveDocument()->getObjectsOfType<Fem::FemPostPipeline>();
|
||||
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<App::DocumentObject*>& funcs = static_cast<Fem::FemPostFunctionProvider*>(
|
||||
pipeline->Function.getValue())->Functions.getValues();
|
||||
pipeline->Functions.getValue())->Functions.getValues();
|
||||
if(idx>=0)
|
||||
static_cast<Fem::FemPostCutFilter*>(getObject())->Function.setValue(funcs[idx]);
|
||||
else
|
||||
|
||||
@@ -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<Fem::FemPostObject*>(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<Fem::FemPostObject*>(getObject())->providesPolyData())
|
||||
vtkDataObject* data = static_cast<Fem::FemPostObject*>(getObject())->Data.getValue();
|
||||
|
||||
if(!data)
|
||||
return false;
|
||||
|
||||
if(!m_currentAlgorithm) {
|
||||
|
||||
vtkSmartPointer<vtkPolyDataAlgorithm> algorithm = static_cast<Fem::FemPostObject*>(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();
|
||||
|
||||
@@ -47,8 +47,8 @@ std::vector< App::DocumentObject* > ViewProviderFemPostPipeline::claimChildren(v
|
||||
Fem::FemPostPipeline* pipeline = static_cast<Fem::FemPostPipeline*>(getObject());
|
||||
std::vector<App::DocumentObject*> 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<Fem::FemPostPipeline*>(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<FemGui::ViewProviderFemPostFunctionProvider*>(
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user