FEM Post: Basic implementation of filter framework

This commit is contained in:
Stefan Tröger 2015-10-31 18:02:53 +01:00 committed by wmayer
parent 4d09c09dc0
commit 2b9e608501
24 changed files with 3223 additions and 241 deletions

View File

@ -54,8 +54,12 @@
#include "FemResultObject.h"
#include "FemSolverObject.h"
#ifdef FC_USE_VTK
#include "FemPostPipeline.h"
#include "FemPostFilter.h"
#include "FemPostFunction.h"
#endif
namespace Fem {
extern PyObject* initModule();
@ -151,5 +155,9 @@ PyMODINIT_FUNC initFem()
Fem::FemPostObject ::init();
Fem::FemPostPipeline ::init();
Fem::FemPostFilter ::init();
Fem::FemPostClipFilter ::init();
Fem::FemPostFunction ::init();
Fem::FemPostFunctionProvider ::init();
Fem::FemPostPlaneFunction ::init();
#endif
}

View File

@ -1,4 +1,4 @@
<<<<<<< 09326bbbdaf756fe381d51d340e0db27fd8c452a
<<<<<<< eec6f7aee8b6e5979a799358e2ae69bdc5a7af5b
/***************************************************************************
* Copyright (c) 2008 Jürgen Riegel (juergen.riegel@web.de) *
* *
@ -55,6 +55,8 @@
#include "FemResultObject.h"
#include "FemSolverObject.h"
#include "FemPostPipeline.h"
#include "FemPostFilter.h"
namespace Fem {
extern PyObject* initModule();
@ -143,9 +145,14 @@ PyMODINIT_FUNC initFem()
Fem::ConstraintDisplacement ::init();
Fem::FemResultObject ::init();
Fem::FemResultObjectPython ::init();
Fem::FemSolverObject ::init();
Fem::FemSolverObjectPython ::init();
#ifdef FC_USE_VTK
Fem::FemPostObject ::init();
Fem::FemPostPipeline ::init();
Fem::FemPostFilter ::init();
#endif
}
=======
/***************************************************************************
@ -204,8 +211,12 @@ PyMODINIT_FUNC initFem()
#include "FemResultObject.h"
#include "FemSolverObject.h"
#ifdef FC_USE_VTK
#include "FemPostPipeline.h"
#include "FemPostFilter.h"
#include "FemPostFunction.h"
#endif
namespace Fem {
extern PyObject* initModule();
@ -301,6 +312,10 @@ PyMODINIT_FUNC initFem()
Fem::FemPostObject ::init();
Fem::FemPostPipeline ::init();
Fem::FemPostFilter ::init();
Fem::FemPostClipFilter ::init();
Fem::FemPostFunction ::init();
Fem::FemPostFunctionProvider ::init();
Fem::FemPostPlaneFunction ::init();
#endif
}
>>>>>>> Move post processing to fem objects
>>>>>>> Basic implementation of filter framework

View File

@ -187,6 +187,7 @@ private:
pcFeature->Label.setValue(file.fileNamePure().c_str());
pcFeature->read(file);
pcFeature->touch();
pcDoc->recomputeFeature(pcFeature);
}
else
throw e;

View File

@ -1,4 +1,4 @@
<<<<<<< 09326bbbdaf756fe381d51d340e0db27fd8c452a
<<<<<<< eec6f7aee8b6e5979a799358e2ae69bdc5a7af5b
/***************************************************************************
* Copyright (c) 2008 Jürgen Riegel (juergen.riegel@web.de) *
* *
@ -65,6 +65,7 @@
#include "FemMesh.h"
#include "FemMeshObject.h"
#include "FemPostPipeline.h"
#include "FemMeshPy.h"
#include <cstdlib>
@ -164,16 +165,36 @@ private:
pcDoc = App::GetApplication().newDocument(DocName);
}
std::auto_ptr<FemMesh> mesh(new FemMesh);
mesh->read(EncodedName.c_str());
Base::FileInfo file(EncodedName.c_str());
FemMeshObject *pcFeature = static_cast<FemMeshObject *>
(pcDoc->addObject("Fem::FemMeshObject", file.fileNamePure().c_str()));
pcFeature->Label.setValue(file.fileNamePure().c_str());
pcFeature->FemMesh.setValuePtr(mesh.get());
(void)mesh.release();
pcFeature->purgeTouched();
try {
std::auto_ptr<FemMesh> mesh(new FemMesh);
mesh->read(EncodedName.c_str());
FemMeshObject *pcFeature = static_cast<FemMeshObject *>
(pcDoc->addObject("Fem::FemMeshObject", file.fileNamePure().c_str()));
pcFeature->Label.setValue(file.fileNamePure().c_str());
pcFeature->FemMesh.setValuePtr(mesh.get());
(void)mesh.release();
pcFeature->purgeTouched();
}
catch(Base::Exception& e) {
#ifdef FC_USE_VTK
if( FemPostPipeline::canRead(file) ) {
FemPostPipeline *pcFeature = static_cast<FemPostPipeline *>
(pcDoc->addObject("Fem::FemPostPipeline", file.fileNamePure().c_str()));
pcFeature->Label.setValue(file.fileNamePure().c_str());
pcFeature->read(file);
pcFeature->touch();
}
else
throw e;
#else
throw e;
#endif
}
return Py::None();
}
@ -432,6 +453,7 @@ private:
pcFeature->Label.setValue(file.fileNamePure().c_str());
pcFeature->read(file);
pcFeature->touch();
pcDoc->recomputeFeature(pcFeature);
}
else
throw e;
@ -507,4 +529,4 @@ PyObject* initModule()
}
} // namespace Fem
>>>>>>> Move post processing to fem objects
>>>>>>> Basic implementation of filter framework

View File

@ -208,6 +208,8 @@ if(BUILD_FEM_VTK)
FemPostPipeline.cpp
FemPostFilter.h
FemPostFilter.cpp
FemPostFunction.h
FemPostFunction.cpp
)
SOURCE_GROUP("PostObjects" FILES ${FemPost_SRCS})
endif(BUILD_FEM_VTK)

View File

@ -189,17 +189,6 @@ SET(FemConstraints_SRCS
)
SOURCE_GROUP("Constraints" FILES ${FemConstraints_SRCS})
<<<<<<< 09326bbbdaf756fe381d51d340e0db27fd8c452a
SET(FemResult_SRCS
)
SOURCE_GROUP("ResultObjects" FILES ${FemResult_SRCS})
SET(Fem_SRCS
${FemBase_SRCS}
${FemSet_SRCS}
${FemConstraints_SRCS}
${FemResult_SRCS}
=======
if(BUILD_FEM_VTK)
SET(FemPost_SRCS
FemPostObject.h
@ -208,17 +197,23 @@ if(BUILD_FEM_VTK)
FemPostPipeline.cpp
FemPostFilter.h
FemPostFilter.cpp
<<<<<<< eec6f7aee8b6e5979a799358e2ae69bdc5a7af5b
)
=======
FemPostFunction.h
FemPostFunction.cpp
)
>>>>>>> Basic implementation of filter framework
SOURCE_GROUP("PostObjects" FILES ${FemPost_SRCS})
endif(BUILD_FEM_VTK)
SET(Fem_SRCS
${FemBase_SRCS}
${FemSet_SRCS}
${FemConstraints_SRCS}
${FemPost_SRCS}
>>>>>>> Move post processing to fem objects
${FemBase_SRCS}
${FemSet_SRCS}
${FemConstraints_SRCS}
${FemResult_SRCS}
....${FemPost_SRCS}
${Mod_SRCS}
${Python_SRCS}
)

View File

@ -27,6 +27,8 @@
#endif
#include "FemPostFilter.h"
#include "FemPostPipeline.h"
#include <Base/Console.h>
#include <App/DocumentObjectPy.h>
using namespace Fem;
@ -37,30 +39,188 @@ PROPERTY_SOURCE(Fem::FemPostFilter, Fem::FemPostObject)
FemPostFilter::FemPostFilter()
{
m_pass = vtkPassThrough::New();
}
FemPostFilter::~FemPostFilter()
{
}
short FemPostFilter::mustExecute(void) const
{
return 0;
bool FemPostFilter::valid() {
return polyDataSource && !m_pipelines.empty() && !m_activePipeline.empty();
}
PyObject *FemPostFilter::getPyObject()
{
if (PythonObject.is(Py::_None())){
// ref counter is set to 1
PythonObject = Py::Object(new DocumentObjectPy(this),true);
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 Py::new_reference_to(PythonObject);
return StdReturn;
}
void FemPostFilter::onChanged(const Property* prop)
{
App::GeoFeature::onChanged(prop);
// if the placement has changed apply the change to the grid data as well
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;
}
FemPostFilter::FilterPipeline& FemPostFilter::getFilterPipeline(std::string name) {
return m_pipelines[name];
}
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());
}
}
PROPERTY_SOURCE(Fem::FemPostClipFilter, Fem::FemPostFilter)
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 = vtkClipDataSet::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);
setActiveFilterPipeline("extract");
}
FemPostClipFilter::~FemPostClipFilter() {
}
void FemPostClipFilter::onChanged(const Property* prop) {
if(prop == &Function) {
if(Function.getValue() && Function.getValue()->isDerivedFrom(FemPostFunction::getClassTypeId())) {
m_clipper->SetClipFunction(static_cast<FemPostFunction*>(Function.getValue())->getImplicitFunction());
m_extractor->SetImplicitFunction(static_cast<FemPostFunction*>(Function.getValue())->getImplicitFunction());
}
}
else if(prop == &InsideOut) {
m_clipper->SetInsideOut(InsideOut.getValue());
m_extractor->SetExtractInside( (InsideOut.getValue()) ? 1 : 0 );
}
else if(prop == &CutCells) {
if(!CutCells.getValue())
setActiveFilterPipeline("extract");
else
setActiveFilterPipeline("clip");
};
Fem::FemPostFilter::onChanged(prop);
}

View File

@ -27,7 +27,11 @@
#include "FemPostObject.h"
#include <vtkSmartPointer.h>
#include <vtkUnstructuredGrid.h>
#include <vtkClipDataSet.h>
#include <vtkExtractGeometry.h>
#include <vtkGeometryFilter.h>
#include <vtkPassThrough.h>
#include <vtkPlane.h>
namespace Fem
{
@ -40,19 +44,64 @@ public:
/// Constructor
FemPostFilter(void);
virtual ~FemPostFilter();
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();
/// returns the type name of the ViewProvider
virtual const char* getViewProviderName(void) const {
return "FemGui::ViewProviderPostPipeline";
}
short mustExecute(void) const;
PyObject* getPyObject();
protected:
//pipeline handling for derived filter
struct FilterPipeline {
vtkSmartPointer<vtkAlgorithm> source, target, visualisation;
std::vector<vtkSmartPointer<vtkAlgorithm> > algorithmStorage;
};
void addFilterPipeline(const FilterPipeline& p, std::string name);
void setActiveFilterPipeline(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 {
PROPERTY_HEADER(Fem::FemPostClipFilter);
public:
FemPostClipFilter(void);
virtual ~FemPostClipFilter();
App::PropertyLink Function;
App::PropertyBool InsideOut;
App::PropertyBool CutCells;
protected:
virtual void onChanged(const App::Property* prop);
//members
vtkSmartPointer<vtkUnstructuredGrid> source;
private:
vtkSmartPointer<vtkClipDataSet> m_clipper;
vtkSmartPointer<vtkExtractGeometry> m_extractor;
};
} //namespace Fem

View File

@ -0,0 +1,98 @@
/***************************************************************************
* Copyright (c) 2015 Stefan Tröger <stefantroeger@gmx.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
#endif
#include "FemPostFunction.h"
#include <Base/Console.h>
using namespace Fem;
using namespace App;
PROPERTY_SOURCE(Fem::FemPostFunctionProvider, App::DocumentObject)
FemPostFunctionProvider::FemPostFunctionProvider(void): DocumentObject() {
ADD_PROPERTY(Functions, (0));
}
FemPostFunctionProvider::~FemPostFunctionProvider() {
}
void FemPostFunctionProvider::onChanged(const Property* prop) {
App::DocumentObject::onChanged(prop);
}
PROPERTY_SOURCE(Fem::FemPostFunction, App::DocumentObject)
FemPostFunction::FemPostFunction()
{
}
FemPostFunction::~FemPostFunction()
{
}
DocumentObjectExecReturn* FemPostFunction::execute(void) {
return DocumentObject::StdReturn;
}
PROPERTY_SOURCE(Fem::FemPostPlaneFunction, Fem::FemPostFunction)
FemPostPlaneFunction::FemPostPlaneFunction(void): FemPostFunction() {
ADD_PROPERTY(Origin,(Base::Vector3d(0.0,0.0,0.0)));
ADD_PROPERTY(Normal,(Base::Vector3d(1.0,0.0,0.0)));
m_plane = vtkPlane::New();
m_implicit = m_plane;
m_plane->SetOrigin(0., 0., 0.);
m_plane->SetNormal(1., 0., 0.);
}
FemPostPlaneFunction::~FemPostPlaneFunction() {
}
void FemPostPlaneFunction::onChanged(const Property* prop) {
Base::Console().Message("Changed origin and normal\n");
if(prop == &Origin) {
const Base::Vector3d& vec = Origin.getValue();
m_plane->SetOrigin(vec[0], vec[1], vec[2]);
}
else if(prop == &Normal) {
const Base::Vector3d& vec = Normal.getValue();
m_plane->SetNormal(vec[0], vec[1], vec[2]);
}
Fem::FemPostFunction::onChanged(prop);
}

View File

@ -0,0 +1,109 @@
/***************************************************************************
* Copyright (c) 2015 Stefan Tröger <stefantroeger@gmx.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef Fem_FemPostFunction_H
#define Fem_FemPostFunction_H
#include "FemPostObject.h"
#include <vtkSmartPointer.h>
#include <vtkImplicitFunction.h>
#include <vtkPlane.h>
#include <vtkPlaneSource.h>
namespace Fem
{
class AppFemExport FemPostFunction : public App::DocumentObject
{
PROPERTY_HEADER(Fem::FemPostFunction);
public:
/// Constructor
FemPostFunction(void);
virtual ~FemPostFunction();
virtual const char* getViewProviderName(void) const {
return "FemGui::ViewProviderFemPostFunction";
}
virtual App::DocumentObjectExecReturn* execute(void);
//bound box handling
void setBoundingBox(vtkBoundingBox b) {m_boundingBox = b;};
//get the algorithm or the data
vtkSmartPointer<vtkImplicitFunction> getImplicitFunction() {return m_implicit;};
protected:
vtkSmartPointer<vtkImplicitFunction> m_implicit;
vtkBoundingBox m_boundingBox;
};
class FemPostFunctionProvider : public App::DocumentObject {
PROPERTY_HEADER(Fem::FemPostFunctionProvider);
public:
FemPostFunctionProvider(void);
virtual ~FemPostFunctionProvider();
virtual const char* getViewProviderName(void) const {
return "FemGui::ViewProviderFemPostFunctionProvider";
}
App::PropertyLinkList Functions;
protected:
virtual void onChanged(const App::Property* prop);
};
////////////////////////////////////////////////////////////////////////////////////////////
class AppFemExport FemPostPlaneFunction : public FemPostFunction
{
PROPERTY_HEADER(Fem::FemPostPlaneFunction);
public:
FemPostPlaneFunction(void);
virtual ~FemPostPlaneFunction();
App::PropertyVector Normal;
App::PropertyVectorDistance Origin;
virtual const char* getViewProviderName(void) const {
return "FemGui::ViewProviderFemPostPlaneFunction";
}
protected:
virtual void onChanged(const App::Property* prop);
vtkSmartPointer<vtkPlane> m_plane;
};
} //namespace Fem
#endif // Fem_FemPostFunction_H

View File

@ -28,6 +28,8 @@
#include "FemPostObject.h"
#include <Base/Console.h>
#include <App/Application.h>
#include <App/Document.h>
#include <App/DocumentObjectPy.h>
#include <vtkPointData.h>
#include <vtkCellData.h>
@ -53,42 +55,25 @@ short FemPostObject::mustExecute(void) const
}
DocumentObjectExecReturn* FemPostObject::execute(void) {
//analyse the data and print
Base::Console().Message("\nPoly Data Analysis:\n");
vtkPolyData* poly = polyDataSource->GetOutput();
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(polyDataSource && static_cast<unsigned long>(ModificationTime.getValue()) < polyDataSource->GetMTime())
ModificationTime.setValue(static_cast<unsigned long>(polyDataSource->GetMTime()));
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()));
}
}
return DocumentObject::StdReturn;
}
PyObject *FemPostObject::getPyObject()
{
if (PythonObject.is(Py::_None())){
// ref counter is set to 1
PythonObject = Py::Object(new DocumentObjectPy(this),true);
}
return Py::new_reference_to(PythonObject);
}
void FemPostObject::onChanged(const Property* prop)
{
App::GeoFeature::onChanged(prop);
// if the placement has changed apply the change to the grid data as well
}

View File

@ -28,6 +28,7 @@
#include <vtkSmartPointer.h>
#include <vtkPolyDataAlgorithm.h>
#include <vtkBoundingBox.h>
namespace Fem
{
@ -52,11 +53,13 @@ public:
short mustExecute(void) const;
virtual App::DocumentObjectExecReturn* execute(void);
PyObject* getPyObject();
//bounding box handling. By default the bounding box is calcualted from the poly data output
//which is visualized
virtual vtkBoundingBox getBoundingBox() {return m_boundingBox;};
//get the algorithm or the data
vtkPolyData* getPolyData() {return polyDataSource->GetOutput();};
vtkSmartPointer<vtkPolyDataAlgorithm> getPolyAlgorithm() {return polyDataSource;};
//poly data algorithm handling
virtual bool providesPolyData() {return getPolyAlgorithm()!=NULL;};
vtkSmartPointer<vtkPolyDataAlgorithm> getPolyAlgorithm() {return polyDataSource;};
protected:
@ -64,6 +67,9 @@ protected:
//members
vtkSmartPointer<vtkPolyDataAlgorithm> polyDataSource;
private:
vtkBoundingBox m_boundingBox;
};
} //namespace Fem

View File

@ -28,21 +28,31 @@
#include "FemPostPipeline.h"
#include <Base/Console.h>
#include <App/Document.h>
#include <App/DocumentObjectPy.h>
#include <vtkDataSetReader.h>
#include <vtkGeometryFilter.h>
#include <vtkPointData.h>
#include <vtkStructuredGrid.h>
#include <vtkCellData.h>
#include <vtkUnstructuredGrid.h>
using namespace Fem;
using namespace App;
PROPERTY_SOURCE(Fem::FemPostPipeline, Fem::FemPostObject)
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(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()
@ -51,27 +61,26 @@ FemPostPipeline::~FemPostPipeline()
short FemPostPipeline::mustExecute(void) const
{
return 1;
}
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());
}
// 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());
// }
return Fem::FemPostObject::execute();
}
@ -110,19 +119,54 @@ void FemPostPipeline::read(Base::FileInfo File) {
}
PyObject *FemPostPipeline::getPyObject()
{
if (PythonObject.is(Py::_None())){
// ref counter is set to 1
PythonObject = Py::Object(new DocumentObjectPy(this),true);
}
return Py::new_reference_to(PythonObject);
}
// PyObject *FemPostPipeline::getPyObject()
// {
// if (PythonObject.is(Py::_None())){
// // ref counter is set to 1
// PythonObject = Py::Object(new DocumentObjectPy(this),true);
// }
// return Py::new_reference_to(PythonObject);
// }
void FemPostPipeline::onChanged(const Property* prop)
{
if(prop == &Filter || prop == &Mode) {
//we check if all connections are right and add new ones if needed
std::vector<App::DocumentObject*> objs = Filter.getValues();
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());
//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) {
if(!nextFilter->hasInputAlgorithmConnected() || nextFilter->getConnectedInputAlgorithm() != filter->getOutputAlgorithm())
nextFilter->connectInputAlgorithm(filter->getOutputAlgorithm());
}
else {
if(!nextFilter->hasInputDataConnected() || nextFilter->getConnectedInputData() != getSource())
nextFilter->connectInputData(getSource());
}
filter = nextFilter;
};
}
App::GeoFeature::onChanged(prop);
// if the placement has changed apply the change to the grid data as well
}
FemPostObject* FemPostPipeline::getLastPostObject() {
if(Filter.getValues().empty())
return this;
return static_cast<FemPostObject*>(Filter.getValues().back());
}

View File

@ -25,6 +25,8 @@
#define Fem_FemPostPipeline_H
#include "FemPostObject.h"
#include "FemPostFilter.h"
#include "FemPostFunction.h"
#include <vtkSmartPointer.h>
#include <vtkDataSet.h>
@ -40,25 +42,33 @@ public:
/// Constructor
FemPostPipeline(void);
virtual ~FemPostPipeline();
/// returns the type name of the ViewProvider
// virtual const char* getViewProviderName(void) const {
// return "FemGui::ViewProviderPostPipeline";
// }
App::PropertyLinkList Filter;
App::PropertyLink Function;
App::PropertyEnumeration Mode;
short mustExecute(void) const;
virtual App::DocumentObjectExecReturn* execute(void);
PyObject* getPyObject();
//PyObject* getPyObject();
virtual const char* getViewProviderName(void) const {
return "FemGui::ViewProviderFemPostPipeline";
}
//load data from files
static bool canRead(Base::FileInfo file);
void read(Base::FileInfo file);
//Pipeline handling
vtkSmartPointer<vtkDataSet> getSource() {return source;};
FemPostObject* getLastPostObject();
protected:
virtual void onChanged(const App::Property* prop);
//members
private:
vtkSmartPointer<vtkDataSet> source;
static const char* ModeEnums[];
};
} //namespace Fem

View File

@ -55,6 +55,12 @@
#include "ViewProviderResult.h"
#include "Workbench.h"
#ifdef FC_USE_VTK
#include "ViewProviderFemPostObject.h"
#include "ViewProviderFemPostPipeline.h"
#include "ViewProviderFemPostFunction.h"
#endif
#ifdef FC_USE_VTK
#include "ViewProviderFemPostObject.h"
#endif
@ -116,6 +122,10 @@ PyMODINIT_FUNC initFemGui()
#ifdef FC_USE_VTK
FemGui::ViewProviderFemPostObject ::init();
FemGui::ViewProviderFemPostPipeline ::init();
FemGui::ViewProviderFemPostFunction ::init();
FemGui::ViewProviderFemPostFunctionProvider::init();
FemGui::ViewProviderFemPostPlaneFunction ::init();
#endif

View File

@ -213,6 +213,10 @@ if(BUILD_FEM_VTK)
SET(FemGui_SRCS_Post
ViewProviderFemPostObject.h
ViewProviderFemPostObject.cpp
ViewProviderFemPostPipeline.h
ViewProviderFemPostPipeline.cpp
ViewProviderFemPostFunction.h
ViewProviderFemPostFunction.cpp
)
SOURCE_GROUP("PostObjects" FILES ${FemGui_SRCS_Post})
endif(BUILD_FEM_VTK)

View File

@ -26,6 +26,7 @@
# include <Standard_math.hxx>
# include <QApplication>
# include <QMessageBox>
#include <QAction>
#endif
#include <Inventor/nodes/SoEventCallback.h>
@ -47,6 +48,7 @@
#include <Gui/View3DInventor.h>
#include <Gui/View3DInventorViewer.h>
#include <Gui/Utilities.h>
#include <Gui/Action.h>
#include <SMESH_Mesh.hxx>
#include <SMESHDS_Mesh.hxx>
@ -58,9 +60,12 @@
#include <strstream>
#include <Mod/Fem/App/FemConstraint.h>
#include <Mod/Fem/App/FemAnalysis.h>
#include "ActiveAnalysisObserver.h"
#ifdef FC_USE_VTK
#include <Mod/Fem/App/FemPostPipeline.h>
#endif
using namespace std;
@ -757,6 +762,215 @@ bool CmdFemCreateNodesSet::isActive(void)
return hasActiveDocument();
}
// #####################################################################################################
#ifdef FC_USE_VTK
DEF_STD_CMD_A(CmdFemPostCreateClipFilter);
CmdFemPostCreateClipFilter::CmdFemPostCreateClipFilter()
: Command("Fem_PostCreateClipFilter")
{
sAppModule = "Fem";
sGroup = QT_TR_NOOP("Fem");
sMenuText = QT_TR_NOOP("Define/create a clip filter for a post processing pipeline...");
sToolTipText = QT_TR_NOOP("Define/create a clip filter for a post processing pipeline...");
sWhatsThis = "Fem_PostCreateClipFilter";
sStatusTip = sToolTipText;
sPixmap = "fem-fem-mesh-create-node-by-poly";
}
void CmdFemPostCreateClipFilter::activated(int iMsg)
{
Gui::SelectionFilter ObjectFilter("SELECT Fem::FemPostPipeline COUNT 1");
if (ObjectFilter.match()) {
Fem::FemPostPipeline *pipeline = static_cast<Fem::FemPostPipeline*>(ObjectFilter.Result[0][0].getObject());
std::string FeatName = getUniqueObjectName("Clip");
openCommand("Create clip filter");
doCommand(Doc,"App.activeDocument().addObject('Fem::FemPostClipFilter','%s')",FeatName.c_str());
doCommand(Doc,"__list__ = App.ActiveDocument.%s.Filter", pipeline->getNameInDocument());
doCommand(Doc,"__list__.append(App.ActiveDocument.%s)", FeatName.c_str());
doCommand(Doc,"App.ActiveDocument.%s.Filter = __list__", pipeline->getNameInDocument());
doCommand(Doc,"del __list__");
this->updateActive();
}
else {
QMessageBox::warning(Gui::getMainWindow(),
qApp->translate("CmdFemPostCreateClipFilter", "Wrong selection"),
qApp->translate("CmdFemPostCreateClipFilter", "Select a pipeline, please."));
}
}
bool CmdFemPostCreateClipFilter::isActive(void)
{
return hasActiveDocument();
}
// #####################################################################################################
DEF_STD_CMD_ACL(CmdFemPostFunctions);
CmdFemPostFunctions::CmdFemPostFunctions()
: Command("Fem_PostCreateFunctions")
{
sAppModule = "Fem";
sGroup = QT_TR_NOOP("Fem");
sMenuText = QT_TR_NOOP("Functions for use in postprocessing filter...");
sToolTipText = QT_TR_NOOP("Functions for use in postprocessing filter...");
sWhatsThis = "Fem_PostCreateFunctions";
sStatusTip = sToolTipText;
}
void CmdFemPostFunctions::activated(int iMsg)
{
Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager();
std::string name;
if (iMsg==0)
name = "Plane";
else if (iMsg==1)
rcCmdMgr.runCommandByName("Part_JoinEmbed");
else if (iMsg==2)
rcCmdMgr.runCommandByName("Part_JoinCutout");
else
return;
//create the object
Gui::SelectionFilter ObjectFilter("SELECT Fem::FemPostPipeline COUNT 1");
if (ObjectFilter.match()) {
Fem::FemPostPipeline *pipeline = static_cast<Fem::FemPostPipeline*>(ObjectFilter.Result[0][0].getObject());
openCommand("Create function");
//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()) {
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());
provider = static_cast<Fem::FemPostFunctionProvider*>(getDocument()->getObject(FuncName.c_str()));
}
else
provider = static_cast<Fem::FemPostFunctionProvider*>(pipeline->Function.getValue());
//build the object
std::string FeatName = getUniqueObjectName(name.c_str());
doCommand(Doc,"App.activeDocument().addObject('Fem::FemPost%sFunction','%s')", name.c_str(), FeatName.c_str());
doCommand(Doc,"__list__ = App.ActiveDocument.%s.Functions", provider->getNameInDocument());
doCommand(Doc,"__list__.append(App.ActiveDocument.%s)", FeatName.c_str());
doCommand(Doc,"App.ActiveDocument.%s.Functions = __list__", provider->getNameInDocument());
doCommand(Doc,"del __list__");
this->updateActive();
}
else {
QMessageBox::warning(Gui::getMainWindow(),
qApp->translate("CmdFemPostCreateClipFilter", "Wrong selection"),
qApp->translate("CmdFemPostCreateClipFilter", "Select a pipeline, please."));
}
// Since the default icon is reset when enabing/disabling the command we have
// to explicitly set the icon of the used command.
Gui::ActionGroup* pcAction = qobject_cast<Gui::ActionGroup*>(_pcAction);
QList<QAction*> a = pcAction->actions();
assert(iMsg < a.size());
pcAction->setIcon(a[iMsg]->icon());
}
Gui::Action * CmdFemPostFunctions::createAction(void)
{
Gui::ActionGroup* pcAction = new Gui::ActionGroup(this, Gui::getMainWindow());
pcAction->setDropDownMenu(true);
applyCommandData(this->className(), pcAction);
QAction* cmd0 = pcAction->addAction(QString());
//cmd0->setIcon(Gui::BitmapFactory().pixmap("Part_JoinConnect"));
_pcAction = pcAction;
languageChange();
pcAction->setIcon(cmd0->icon());
int defaultId = 0;
pcAction->setProperty("defaultAction", QVariant(defaultId));
return pcAction;
}
void CmdFemPostFunctions::languageChange()
{
Command::languageChange();
if (!_pcAction)
return;
Gui::ActionGroup* pcAction = qobject_cast<Gui::ActionGroup*>(_pcAction);
QList<QAction*> a = pcAction->actions();
QAction* cmd0 = a[0];
cmd0->setText(QApplication::translate("CmdFemPostFunctions","Plane"));
cmd0->setToolTip(QApplication::translate("Fem_PostCreateFunctions","Create a plane function, defined by its orgin and normal"));
cmd0->setStatusTip(cmd0->toolTip());
}
bool CmdFemPostFunctions::isActive(void)
{
if (getActiveGuiDocument())
return true;
else
return false;
}
DEF_STD_CMD_AC(CmdFemPostApllyChanges);
CmdFemPostApllyChanges::CmdFemPostApllyChanges()
: Command("Fem_PostApplyChanges")
{
sAppModule = "Fem";
sGroup = QT_TR_NOOP("Fem");
sMenuText = QT_TR_NOOP("Apply changes to parameters directly and not on recompute only...");
sToolTipText = QT_TR_NOOP("Apply changes to parameters directly and not on recompute only...");
sWhatsThis = "Fem_PostApplyChanges";
sStatusTip = sToolTipText;
sPixmap = "view-refresh";
}
void CmdFemPostApllyChanges::activated(int iMsg)
{
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Fem");
if (iMsg == 1)
hGrp->SetBool("PostAutoRecompute", true);
else
hGrp->SetBool("PostAutoRecompute", false);
}
bool CmdFemPostApllyChanges::isActive(void)
{
if (getActiveGuiDocument())
return true;
else
return false;
}
Gui::Action * CmdFemPostApllyChanges::createAction(void)
{
Gui::Action *pcAction = Command::createAction();
pcAction->setCheckable(true);
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Fem");
pcAction->setChecked(hGrp->GetBool("PostAutoRecompute", false));
return pcAction;
}
#endif
//--------------------------------------------------------------------------------------
@ -775,4 +989,10 @@ void CreateFemCommands(void)
rcCmdMgr.addCommand(new CmdFemConstraintGear());
rcCmdMgr.addCommand(new CmdFemConstraintPulley());
rcCmdMgr.addCommand(new CmdFemConstraintDisplacement());
#ifdef FC_USE_VTK
rcCmdMgr.addCommand(new CmdFemPostCreateClipFilter);
rcCmdMgr.addCommand(new CmdFemPostFunctions);
rcCmdMgr.addCommand(new CmdFemPostApllyChanges);
#endif
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,246 @@
/***************************************************************************
* Copyright (c) 2015 Stefan Tröger <stefantroeger@gmx.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
#include <Inventor/nodes/SoCoordinate3.h>
#include <Inventor/nodes/SoMaterial.h>
#include <Inventor/nodes/SoSurroundScale.h>
#include <Inventor/nodes/SoLineSet.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoTransform.h>
#include <Inventor/nodes/SoMatrixTransform.h>
#include <Inventor/manips/SoTransformManip.h>
#include <Inventor/manips/SoCenterballManip.h>
#include <Inventor/actions/SoSearchAction.h>
#include <Inventor/engines/SoDecomposeMatrix.h>
#include <Inventor/draggers/SoCenterballDragger.h>
#endif
#include "ViewProviderFemPostFunction.h"
#include <Mod/Fem/App/FemPostFunction.h>
#include <Base/Console.h>
#include <Base/Interpreter.h>
#include <Gui/Application.h>
#include <Gui/Document.h>
#include <Gui/SoNavigationDragger.h>
#include <Gui/Macro.h>
using namespace FemGui;
PROPERTY_SOURCE(FemGui::ViewProviderFemPostFunctionProvider, Gui::ViewProviderDocumentObject)
ViewProviderFemPostFunctionProvider::ViewProviderFemPostFunctionProvider() {
}
ViewProviderFemPostFunctionProvider::~ViewProviderFemPostFunctionProvider() {
}
std::vector< App::DocumentObject* > ViewProviderFemPostFunctionProvider::claimChildren(void) const {
return static_cast<Fem::FemPostFunctionProvider*>(getObject())->Functions.getValues();
}
std::vector< App::DocumentObject* > ViewProviderFemPostFunctionProvider::claimChildren3D(void) const {
return claimChildren();
}
PROPERTY_SOURCE(FemGui::ViewProviderFemPostFunction, Gui::ViewProviderDocumentObject)
ViewProviderFemPostFunction::ViewProviderFemPostFunction() : m_autoscale(false), m_isDragging(false)
{
m_geometrySeperator = new SoSeparator();
m_geometrySeperator->ref();
m_scale = new SoScale();
m_scale->ref();
m_scale->scaleFactor = SbVec3f(1,1,1);
}
ViewProviderFemPostFunction::~ViewProviderFemPostFunction()
{
m_geometrySeperator->unref();
m_manip->unref();
m_scale->unref();
}
void ViewProviderFemPostFunction::attach(App::DocumentObject *pcObj)
{
ViewProviderDocumentObject::attach(pcObj);
Fem::FemPostPlaneFunction* func = static_cast<Fem::FemPostPlaneFunction*>(getObject());
// setup the graph for editing the function unit geometry
SoMaterial* color = new SoMaterial();
color->diffuseColor.setValue(0,0,1);
color->transparency.setValue(0.5);
SoTransform* trans = new SoTransform;
const Base::Vector3d& norm = func->Normal.getValue();
const Base::Vector3d& base = func->Origin.getValue();
SbRotation rot(SbVec3f(0,0,1), SbVec3f(norm.x,norm.y,norm.z));
trans->rotation.setValue(rot);
trans->translation.setValue(base.x,base.y,base.z);
trans->center.setValue(0.0f,0.0f,0.0f);
m_manip = setupManipulator();
m_manip->ref();
SoSeparator* pcEditNode = new SoSeparator();
pcEditNode->addChild(color);
pcEditNode->addChild(trans);
pcEditNode->addChild(m_geometrySeperator);
m_geometrySeperator->insertChild(m_scale, 0);
// Now we replace the SoTransform node by a manipulator
// Note: Even SoCenterballManip inherits from SoTransform
// we cannot use it directly (in above code) because the
// translation and center fields are overridden.
SoSearchAction sa;
sa.setInterest(SoSearchAction::FIRST);
sa.setSearchingAll(FALSE);
sa.setNode(trans);
sa.apply(pcEditNode);
SoPath * path = sa.getPath();
if (path) {
m_manip->replaceNode(path);
SoDragger* dragger = m_manip->getDragger();
dragger->addStartCallback(dragStartCallback, this);
dragger->addFinishCallback(dragFinishCallback, this);
dragger->addMotionCallback(dragMotionCallback, this);
}
addDisplayMaskMode(pcEditNode, "Default");
setDisplayMaskMode("Default");
}
SoTransformManip* ViewProviderFemPostFunction::setupManipulator() {
return new SoCenterballManip;
}
std::vector<std::string> ViewProviderFemPostFunction::getDisplayModes(void) const
{
std::vector<std::string> StrList;
StrList.push_back("Default");
return StrList;
}
void ViewProviderFemPostFunction::dragStartCallback(void *data, SoDragger *)
{
// This is called when a manipulator is about to manipulating
Gui::Application::Instance->activeDocument()->openCommand("Edit Mirror");
reinterpret_cast<ViewProviderFemPostFunction*>(data)->m_isDragging = true;
ViewProviderFemPostFunction* that = reinterpret_cast<ViewProviderFemPostFunction*>(data);
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Fem");
that->m_autoRecompute = hGrp->GetBool("PostAutoRecompute", false);
}
void ViewProviderFemPostFunction::dragFinishCallback(void *data, SoDragger *)
{
// This is called when a manipulator has done manipulating
Gui::Application::Instance->activeDocument()->commitCommand();
ViewProviderFemPostFunction* that = reinterpret_cast<ViewProviderFemPostFunction*>(data);
if(that->m_autoRecompute)
that->getObject()->getDocument()->recompute();
reinterpret_cast<ViewProviderFemPostFunction*>(data)->m_isDragging = false;
}
void ViewProviderFemPostFunction::dragMotionCallback(void *data, SoDragger *drag)
{
Base::Console().Message("dragger callback\n");
ViewProviderFemPostFunction* that = reinterpret_cast<ViewProviderFemPostFunction*>(data);
that->draggerUpdate(drag);
if(that->m_autoRecompute)
that->getObject()->getDocument()->recompute();
}
PROPERTY_SOURCE(FemGui::ViewProviderFemPostPlaneFunction, FemGui::ViewProviderFemPostFunction)
ViewProviderFemPostPlaneFunction::ViewProviderFemPostPlaneFunction() {
setAutoScale(true);
//setup the visualisation geometry
SoCoordinate3* points = new SoCoordinate3();
points->point.setNum(4);
points->point.set1Value(0, -0.5, -0.5, 0);
points->point.set1Value(1, -0.5, 0.5, 0);
points->point.set1Value(2, 0.5, 0.5, 0);
points->point.set1Value(3, 0.5, -0.5, 0);
points->point.set1Value(4, -0.5, -0.5, 0);
SoLineSet* line = new SoLineSet();
getGeometryNode()->addChild(points);
getGeometryNode()->addChild(line);
}
ViewProviderFemPostPlaneFunction::~ViewProviderFemPostPlaneFunction() {
}
void ViewProviderFemPostPlaneFunction::draggerUpdate(SoDragger* m) {
Base::Console().Message("dragger udate\n");
Fem::FemPostPlaneFunction* func = static_cast<Fem::FemPostPlaneFunction*>(getObject());
SoCenterballDragger* dragger = static_cast<SoCenterballDragger*>(m);
// the new axis of the plane
SbRotation rot, scaleDir;
const SbVec3f& center = dragger->center.getValue();
SbVec3f norm(0,0,1);
dragger->rotation.getValue().multVec(norm,norm);
func->Origin.setValue(center[0], center[1], center[2]);
func->Normal.setValue(norm[0],norm[1],norm[2]);
}
void ViewProviderFemPostPlaneFunction::updateData(const App::Property* p) {
Fem::FemPostPlaneFunction* func = static_cast<Fem::FemPostPlaneFunction*>(getObject());
if(!isDragging() && (p == &func->Origin || p == &func->Normal)) {
const Base::Vector3d& trans = func->Origin.getValue();
const Base::Vector3d& norm = func->Normal.getValue();
SbRotation rot(SbVec3f(0.,0.,1.), SbVec3f(norm.x, norm.y, norm.z));
Base::Console().Message("Updated propertes\n");
static_cast<SoCenterballManip*>(getManipulator())->center.setValue(SbVec3f(trans[0], trans[1], trans[2]));
static_cast<SoCenterballManip*>(getManipulator())->rotation.setValue(rot);
}
Gui::ViewProviderDocumentObject::updateData(p);
}

View File

@ -0,0 +1,102 @@
/***************************************************************************
* Copyright (c) 2015 Stefan Tröger <stefantroeger@gmx.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef FEM_VIEWPROVIDERFEMPOSTFUNCTION_H
#define FEM_VIEWPROVIDERFEMPOSTFUNCTION_H
#include <Gui/ViewProviderDocumentObject.h>
#include <Inventor/SbMatrix.h>
class SoScale;
class SoSurroundScale;
class SoTransformManip;
class SoComposeMatrix;
class SoMatrixTransform;
class SoDragger;
namespace FemGui
{
class FemGuiExport ViewProviderFemPostFunctionProvider : public Gui::ViewProviderDocumentObject
{
PROPERTY_HEADER(FemGui::ViewProviderFemPostFunction);
public:
ViewProviderFemPostFunctionProvider();
virtual ~ViewProviderFemPostFunctionProvider();
virtual std::vector< App::DocumentObject* > claimChildren(void) const;
virtual std::vector< App::DocumentObject* > claimChildren3D(void) const;
};
class FemGuiExport ViewProviderFemPostFunction : public Gui::ViewProviderDocumentObject
{
PROPERTY_HEADER(FemGui::ViewProviderFemPostFunction);
public:
/// constructor.
ViewProviderFemPostFunction();
~ViewProviderFemPostFunction();
void attach(App::DocumentObject *pcObject);
std::vector<std::string> getDisplayModes() const;
protected:
void setAutoScale(bool value) {m_autoscale = value;};
bool autoScale() {return m_autoscale;};
bool isDragging() {return m_isDragging;};
virtual SoTransformManip* setupManipulator();
virtual void draggerUpdate(SoDragger* m) {};
SoTransformManip* getManipulator() {return m_manip;};
SoSeparator* getGeometryNode() {return m_geometrySeperator;};
private:
static void dragStartCallback(void * data, SoDragger * d);
static void dragFinishCallback(void * data, SoDragger * d);
static void dragMotionCallback(void * data, SoDragger * d);
SoSeparator* m_geometrySeperator;
SoTransformManip* m_manip;
SoScale* m_scale;
bool m_autoscale, m_isDragging, m_autoRecompute;
};
class FemGuiExport ViewProviderFemPostPlaneFunction : public ViewProviderFemPostFunction {
PROPERTY_HEADER(FemGui::ViewProviderFemPostPlaneFunction);
public:
ViewProviderFemPostPlaneFunction();
virtual ~ViewProviderFemPostPlaneFunction();
protected:
virtual void draggerUpdate(SoDragger* mat);
virtual void updateData(const App::Property*);
};
} //namespace FemGui
#endif // FEM_VIEWPROVIDERFEMPOSTFUNCTION_H

View File

@ -369,7 +369,7 @@ void ViewProviderFemPostObject::WritePointData(vtkPoints* points, vtkDataArray*
void ViewProviderFemPostObject::WriteColorData() {
if(!m_currentAlgorithm)
if(!setupPipeline())
return;
if(Coloring.getEnumVector().empty() || Coloring.getValue() == 0) {
@ -429,7 +429,7 @@ void ViewProviderFemPostObject::updateData(const App::Property* p) {
bool ViewProviderFemPostObject::setupPipeline() {
if(!static_cast<Fem::FemPostObject*>(getObject())->getPolyAlgorithm())
if(!static_cast<Fem::FemPostObject*>(getObject())->providesPolyData())
return false;
if(!m_currentAlgorithm) {

View File

@ -0,0 +1,59 @@
/***************************************************************************
* Copyright (c) 2015 Stefan Tröger <stefantroeger@gmx.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#include "ViewProviderFemPostPipeline.h"
#include <Mod/Fem/App/FemPostPipeline.h>
#include <Base/Console.h>
using namespace FemGui;
PROPERTY_SOURCE(FemGui::ViewProviderFemPostPipeline, FemGui::ViewProviderFemPostObject)
ViewProviderFemPostPipeline::ViewProviderFemPostPipeline()
{
}
ViewProviderFemPostPipeline::~ViewProviderFemPostPipeline()
{
}
std::vector< App::DocumentObject* > ViewProviderFemPostPipeline::claimChildren(void) const {
Fem::FemPostPipeline* pipeline = static_cast<Fem::FemPostPipeline*>(getObject());
std::vector<App::DocumentObject*> children;
if(pipeline->Function.getValue())
children.push_back(pipeline->Function.getValue());
children.insert(children.end(), pipeline->Filter.getValues().begin(), pipeline->Filter.getValues().end());
Base::Console().Message("claim children pipeline: %i\n", children.size());
return children;
}
std::vector< App::DocumentObject* > ViewProviderFemPostPipeline::claimChildren3D(void) const {
return claimChildren();
}

View File

@ -0,0 +1,49 @@
/***************************************************************************
* Copyright (c) 2015 Stefan Tröger <stefantroeger@gmx.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef FEM_VIEWPROVIDERFEMPOSTPIPELINE_H
#define FEM_VIEWPROVIDERFEMPOSTPIPELINE_H
#include "ViewProviderFemPostObject.h"
namespace FemGui
{
class FemGuiExport ViewProviderFemPostPipeline : public ViewProviderFemPostObject {
PROPERTY_HEADER(FemGui::ViewProviderFemPostPipeline);
public:
/// constructor.
ViewProviderFemPostPipeline();
~ViewProviderFemPostPipeline();
virtual std::vector< App::DocumentObject* > claimChildren(void) const;
virtual std::vector< App::DocumentObject* > claimChildren3D(void) const;
};
} //namespace FemGui
#endif // FEM_VIEWPROVIDERFEMPOSTPIPELINE_H

View File

@ -1,116 +1,125 @@
/***************************************************************************
* Copyright (c) 2008 Werner Mayer <werner.wm.mayer@gmx.de> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <qobject.h>
#endif
#include "Workbench.h"
#include <Gui/ToolBarManager.h>
#include <Gui/MenuManager.h>
using namespace FemGui;
#if 0 // needed for Qt's lupdate utility
qApp->translate("Workbench", "FEM");
qApp->translate("Workbench", "&FEM");
#endif
/// @namespace FemGui @class Workbench
TYPESYSTEM_SOURCE(FemGui::Workbench, Gui::StdWorkbench)
Workbench::Workbench()
{
}
Workbench::~Workbench()
{
}
Gui::ToolBarItem* Workbench::setupToolBars() const
{
Gui::ToolBarItem* root = StdWorkbench::setupToolBars();
Gui::ToolBarItem* fem = new Gui::ToolBarItem(root);
fem->setCommand("FEM");
*fem << "Fem_Analysis"
<< "Fem_SolverCalculix"
// << "Fem_SolverZ88"
<< "Fem_MeshFromShape"
<< "Fem_MechanicalMaterial"
<< "Fem_BeamSection"
<< "Fem_ShellThickness"
<< "Separator"
<< "Fem_CreateNodesSet"
<< "Separator"
<< "Fem_ConstraintFixed"
<< "Fem_ConstraintDisplacement"
<< "Separator"
<< "Fem_ConstraintForce"
<< "Fem_ConstraintPressure"
<< "Fem_ConstraintBearing"
<< "Fem_ConstraintGear"
<< "Fem_ConstraintPulley"
<< "Separator"
<< "Fem_ControlSolver"
<< "Fem_RunSolver"
<< "Fem_PurgeResults"
<< "Fem_ShowResult";
return root;
}
Gui::MenuItem* Workbench::setupMenuBar() const
{
Gui::MenuItem* root = StdWorkbench::setupMenuBar();
Gui::MenuItem* item = root->findItem("&Windows");
Gui::MenuItem* fem = new Gui::MenuItem;
root->insertItem(item, fem);
fem->setCommand("&FEM");
*fem << "Fem_Analysis"
<< "Fem_SolverCalculix"
<< "Fem_SolverZ88"
<< "Fem_MeshFromShape"
<< "Fem_MechanicalMaterial"
<< "Fem_BeamSection"
<< "Fem_ShellThickness"
<< "Separator"
<< "Fem_CreateNodesSet"
<< "Separator"
<< "Fem_ConstraintFixed"
<< "Fem_ConstraintDisplacement"
<< "Separator"
<< "Fem_ConstraintForce"
<< "Fem_ConstraintPressure"
<< "Fem_ConstraintBearing"
<< "Fem_ConstraintGear"
<< "Fem_ConstraintPulley"
<< "Separator"
<< "Fem_ControlSolver"
<< "Fem_RunSolver"
<< "Fem_PurgeResults"
<< "Fem_ShowResult";
return root;
}
/***************************************************************************
* Copyright (c) 2008 Werner Mayer <werner.wm.mayer@gmx.de> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <qobject.h>
#endif
#include "Workbench.h"
#include <Gui/ToolBarManager.h>
#include <Gui/MenuManager.h>
using namespace FemGui;
#if 0 // needed for Qt's lupdate utility
qApp->translate("Workbench", "FEM");
qApp->translate("Workbench", "&FEM");
#endif
/// @namespace FemGui @class Workbench
TYPESYSTEM_SOURCE(FemGui::Workbench, Gui::StdWorkbench)
Workbench::Workbench()
{
}
Workbench::~Workbench()
{
}
Gui::ToolBarItem* Workbench::setupToolBars() const
{
Gui::ToolBarItem* root = StdWorkbench::setupToolBars();
Gui::ToolBarItem* fem = new Gui::ToolBarItem(root);
fem->setCommand("FEM");
*fem << "Fem_Analysis"
<< "Fem_SolverCalculix"
// << "Fem_SolverZ88"
<< "Fem_MeshFromShape"
<< "Fem_MechanicalMaterial"
<< "Fem_BeamSection"
<< "Fem_ShellThickness"
<< "Separator"
<< "Fem_CreateNodesSet"
<< "Separator"
<< "Fem_ConstraintFixed"
<< "Fem_ConstraintDisplacement"
<< "Separator"
<< "Fem_ConstraintForce"
<< "Fem_ConstraintPressure"
<< "Fem_ConstraintBearing"
<< "Fem_ConstraintGear"
<< "Fem_ConstraintPulley"
<< "Separator"
<< "Fem_ControlSolver"
<< "Fem_RunSolver"
<< "Fem_PurgeResults"
<< "Fem_ShowResult";
#ifdef FC_USE_VTK
Gui::ToolBarItem* post = new Gui::ToolBarItem(root);
post->setCommand("Post Processing");
*post << "Fem_PostApplyChanges"
<< "Fem_PostCreateClipFilter"
<< "Fem_PostCreateFunctions";
#endif
return root;
}
Gui::MenuItem* Workbench::setupMenuBar() const
{
Gui::MenuItem* root = StdWorkbench::setupMenuBar();
Gui::MenuItem* item = root->findItem("&Windows");
Gui::MenuItem* fem = new Gui::MenuItem;
root->insertItem(item, fem);
fem->setCommand("&FEM");
*fem << "Fem_Analysis"
<< "Fem_SolverCalculix"
<< "Fem_SolverZ88"
<< "Fem_MeshFromShape"
<< "Fem_MechanicalMaterial"
<< "Fem_BeamSection"
<< "Fem_ShellThickness"
<< "Separator"
<< "Fem_CreateNodesSet"
<< "Separator"
<< "Fem_ConstraintFixed"
<< "Fem_ConstraintDisplacement"
<< "Separator"
<< "Fem_ConstraintForce"
<< "Fem_ConstraintPressure"
<< "Fem_ConstraintBearing"
<< "Fem_ConstraintGear"
<< "Fem_ConstraintPulley"
<< "Separator"
<< "Fem_ControlSolver"
<< "Fem_RunSolver"
<< "Fem_PurgeResults"
<< "Fem_ShowResult";
return root;
}