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

View File

@ -1,153 +1,4 @@
<<<<<<< 09326bbbdaf756fe381d51d340e0db27fd8c452a <<<<<<< eec6f7aee8b6e5979a799358e2ae69bdc5a7af5b
/***************************************************************************
* Copyright (c) 2008 Jürgen Riegel (juergen.riegel@web.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 <Python.h>
#endif
#include <Base/Console.h>
#include <Base/Interpreter.h>
#include <CXX/Extensions.hxx>
#include "FemMeshPy.h"
#include "FemMesh.h"
#include "FemMeshProperty.h"
#include "FemAnalysis.h"
#include "FemMeshObject.h"
#include "FemMeshShapeObject.h"
#include "FemMeshShapeNetgenObject.h"
#include "FemSetElementsObject.h"
#include "FemSetFacesObject.h"
#include "FemSetGeometryObject.h"
#include "FemSetNodesObject.h"
#include "HypothesisPy.h"
#include "FemConstraintBearing.h"
#include "FemConstraintFixed.h"
#include "FemConstraintForce.h"
#include "FemConstraintPressure.h"
#include "FemConstraintGear.h"
#include "FemConstraintPulley.h"
#include "FemConstraintDisplacement.h"
#include "FemResultObject.h"
#include "FemSolverObject.h"
namespace Fem {
extern PyObject* initModule();
}
/* Python entry */
PyMODINIT_FUNC initFem()
{
// load dependend module
try {
Base::Interpreter().loadModule("Part");
//Base::Interpreter().loadModule("Mesh");
}
catch(const Base::Exception& e) {
PyErr_SetString(PyExc_ImportError, e.what());
return;
}
PyObject* femModule = Fem::initModule();
Base::Console().Log("Loading Fem module... done\n");
Fem::StdMeshers_Arithmetic1DPy ::init_type(femModule);
Fem::StdMeshers_AutomaticLengthPy ::init_type(femModule);
Fem::StdMeshers_NotConformAllowedPy ::init_type(femModule);
Fem::StdMeshers_MaxLengthPy ::init_type(femModule);
Fem::StdMeshers_LocalLengthPy ::init_type(femModule);
Fem::StdMeshers_QuadranglePreferencePy ::init_type(femModule);
Fem::StdMeshers_Quadrangle_2DPy ::init_type(femModule);
Fem::StdMeshers_MaxElementAreaPy ::init_type(femModule);
Fem::StdMeshers_Regular_1DPy ::init_type(femModule);
Fem::StdMeshers_UseExisting_1DPy ::init_type(femModule);
Fem::StdMeshers_UseExisting_2DPy ::init_type(femModule);
Fem::StdMeshers_CompositeSegment_1DPy ::init_type(femModule);
Fem::StdMeshers_Deflection1DPy ::init_type(femModule);
Fem::StdMeshers_LayerDistributionPy ::init_type(femModule);
Fem::StdMeshers_LengthFromEdgesPy ::init_type(femModule);
Fem::StdMeshers_MaxElementVolumePy ::init_type(femModule);
Fem::StdMeshers_MEFISTO_2DPy ::init_type(femModule);
Fem::StdMeshers_NumberOfLayersPy ::init_type(femModule);
Fem::StdMeshers_NumberOfSegmentsPy ::init_type(femModule);
Fem::StdMeshers_Prism_3DPy ::init_type(femModule);
Fem::StdMeshers_Projection_1DPy ::init_type(femModule);
Fem::StdMeshers_Projection_2DPy ::init_type(femModule);
Fem::StdMeshers_Projection_3DPy ::init_type(femModule);
Fem::StdMeshers_ProjectionSource1DPy ::init_type(femModule);
Fem::StdMeshers_ProjectionSource2DPy ::init_type(femModule);
Fem::StdMeshers_ProjectionSource3DPy ::init_type(femModule);
Fem::StdMeshers_QuadraticMeshPy ::init_type(femModule);
Fem::StdMeshers_RadialPrism_3DPy ::init_type(femModule);
Fem::StdMeshers_SegmentAroundVertex_0DPy ::init_type(femModule);
Fem::StdMeshers_SegmentLengthAroundVertexPy ::init_type(femModule);
Fem::StdMeshers_StartEndLengthPy ::init_type(femModule);
Fem::StdMeshers_TrianglePreferencePy ::init_type(femModule);
Fem::StdMeshers_Hexa_3DPy ::init_type(femModule);
// Add Types to module
Base::Interpreter().addType(&Fem::FemMeshPy::Type,femModule,"FemMesh");
// NOTE: To finish the initialization of our own type objects we must
// call PyType_Ready, otherwise we run into a segmentation fault, later on.
// This function is responsible for adding inherited slots from a type's base class.
Fem::FemAnalysis ::init();
Fem::FemAnalysisPython ::init();
Fem::DocumentObject ::init();
Fem::FeaturePython ::init();
Fem::FemMesh ::init();
Fem::FemMeshObject ::init();
Fem::FemMeshShapeObject ::init();
Fem::FemMeshShapeNetgenObject ::init();
Fem::PropertyFemMesh ::init();
Fem::FemSetObject ::init();
Fem::FemSetElementsObject ::init();
Fem::FemSetFacesObject ::init();
Fem::FemSetGeometryObject ::init();
Fem::FemSetNodesObject ::init();
Fem::Constraint ::init();
Fem::ConstraintBearing ::init();
Fem::ConstraintFixed ::init();
Fem::ConstraintForce ::init();
Fem::ConstraintPressure ::init();
Fem::ConstraintGear ::init();
Fem::ConstraintPulley ::init();
Fem::ConstraintDisplacement ::init();
Fem::FemResultObject ::init();
Fem::FemResultObjectPython ::init();
Fem::FemSolverObject ::init();
Fem::FemSolverObjectPython ::init();
}
=======
/*************************************************************************** /***************************************************************************
* Copyright (c) 2008 Jürgen Riegel (juergen.riegel@web.de) * * Copyright (c) 2008 Jürgen Riegel (juergen.riegel@web.de) *
* * * *
@ -303,4 +154,168 @@ PyMODINIT_FUNC initFem()
Fem::FemPostFilter ::init(); Fem::FemPostFilter ::init();
#endif #endif
} }
>>>>>>> Move post processing to fem objects =======
/***************************************************************************
* Copyright (c) 2008 Jürgen Riegel (juergen.riegel@web.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 <Python.h>
#endif
#include <Base/Console.h>
#include <Base/Interpreter.h>
#include <CXX/Extensions.hxx>
#include "FemMeshPy.h"
#include "FemMesh.h"
#include "FemMeshProperty.h"
#include "FemAnalysis.h"
#include "FemMeshObject.h"
#include "FemMeshShapeObject.h"
#include "FemMeshShapeNetgenObject.h"
#include "FemSetElementsObject.h"
#include "FemSetFacesObject.h"
#include "FemSetGeometryObject.h"
#include "FemSetNodesObject.h"
#include "HypothesisPy.h"
#include "FemConstraintBearing.h"
#include "FemConstraintFixed.h"
#include "FemConstraintForce.h"
#include "FemConstraintPressure.h"
#include "FemConstraintGear.h"
#include "FemConstraintPulley.h"
#include "FemConstraintDisplacement.h"
#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();
}
/* Python entry */
PyMODINIT_FUNC initFem()
{
// load dependend module
try {
Base::Interpreter().loadModule("Part");
//Base::Interpreter().loadModule("Mesh");
}
catch(const Base::Exception& e) {
PyErr_SetString(PyExc_ImportError, e.what());
return;
}
PyObject* femModule = Fem::initModule();
Base::Console().Log("Loading Fem module... done\n");
Fem::StdMeshers_Arithmetic1DPy ::init_type(femModule);
Fem::StdMeshers_AutomaticLengthPy ::init_type(femModule);
Fem::StdMeshers_NotConformAllowedPy ::init_type(femModule);
Fem::StdMeshers_MaxLengthPy ::init_type(femModule);
Fem::StdMeshers_LocalLengthPy ::init_type(femModule);
Fem::StdMeshers_QuadranglePreferencePy ::init_type(femModule);
Fem::StdMeshers_Quadrangle_2DPy ::init_type(femModule);
Fem::StdMeshers_MaxElementAreaPy ::init_type(femModule);
Fem::StdMeshers_Regular_1DPy ::init_type(femModule);
Fem::StdMeshers_UseExisting_1DPy ::init_type(femModule);
Fem::StdMeshers_UseExisting_2DPy ::init_type(femModule);
Fem::StdMeshers_CompositeSegment_1DPy ::init_type(femModule);
Fem::StdMeshers_Deflection1DPy ::init_type(femModule);
Fem::StdMeshers_LayerDistributionPy ::init_type(femModule);
Fem::StdMeshers_LengthFromEdgesPy ::init_type(femModule);
Fem::StdMeshers_MaxElementVolumePy ::init_type(femModule);
Fem::StdMeshers_MEFISTO_2DPy ::init_type(femModule);
Fem::StdMeshers_NumberOfLayersPy ::init_type(femModule);
Fem::StdMeshers_NumberOfSegmentsPy ::init_type(femModule);
Fem::StdMeshers_Prism_3DPy ::init_type(femModule);
Fem::StdMeshers_Projection_1DPy ::init_type(femModule);
Fem::StdMeshers_Projection_2DPy ::init_type(femModule);
Fem::StdMeshers_Projection_3DPy ::init_type(femModule);
Fem::StdMeshers_ProjectionSource1DPy ::init_type(femModule);
Fem::StdMeshers_ProjectionSource2DPy ::init_type(femModule);
Fem::StdMeshers_ProjectionSource3DPy ::init_type(femModule);
Fem::StdMeshers_QuadraticMeshPy ::init_type(femModule);
Fem::StdMeshers_RadialPrism_3DPy ::init_type(femModule);
Fem::StdMeshers_SegmentAroundVertex_0DPy ::init_type(femModule);
Fem::StdMeshers_SegmentLengthAroundVertexPy ::init_type(femModule);
Fem::StdMeshers_StartEndLengthPy ::init_type(femModule);
Fem::StdMeshers_TrianglePreferencePy ::init_type(femModule);
Fem::StdMeshers_Hexa_3DPy ::init_type(femModule);
// Add Types to module
Base::Interpreter().addType(&Fem::FemMeshPy::Type,femModule,"FemMesh");
// NOTE: To finish the initialization of our own type objects we must
// call PyType_Ready, otherwise we run into a segmentation fault, later on.
// This function is responsible for adding inherited slots from a type's base class.
Fem::FemAnalysis ::init();
Fem::FemAnalysisPython ::init();
Fem::DocumentObject ::init();
Fem::FeaturePython ::init();
Fem::FemMesh ::init();
Fem::FemMeshObject ::init();
Fem::FemMeshShapeObject ::init();
Fem::FemMeshShapeNetgenObject ::init();
Fem::PropertyFemMesh ::init();
Fem::FemSetObject ::init();
Fem::FemSetElementsObject ::init();
Fem::FemSetFacesObject ::init();
Fem::FemSetGeometryObject ::init();
Fem::FemSetNodesObject ::init();
Fem::Constraint ::init();
Fem::ConstraintBearing ::init();
Fem::ConstraintFixed ::init();
Fem::ConstraintForce ::init();
Fem::ConstraintPressure ::init();
Fem::ConstraintGear ::init();
Fem::ConstraintPulley ::init();
Fem::ConstraintDisplacement ::init();
Fem::FemResultObject ::init();
Fem::FemSolverObject ::init();
Fem::FemSolverObjectPython ::init();
#ifdef FC_USE_VTK
Fem::FemPostObject ::init();
Fem::FemPostPipeline ::init();
Fem::FemPostFilter ::init();
Fem::FemPostClipFilter ::init();
Fem::FemPostFunction ::init();
Fem::FemPostFunctionProvider ::init();
Fem::FemPostPlaneFunction ::init();
#endif
}
>>>>>>> Basic implementation of filter framework

View File

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

View File

@ -1,248 +1,4 @@
<<<<<<< 09326bbbdaf756fe381d51d340e0db27fd8c452a <<<<<<< eec6f7aee8b6e5979a799358e2ae69bdc5a7af5b
/***************************************************************************
* Copyright (c) 2008 Jürgen Riegel (juergen.riegel@web.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 <Python.h>
# include <memory>
#endif
#include <CXX/Extensions.hxx>
#include <CXX/Objects.hxx>
#include <Base/Console.h>
#include <Base/Tools.h>
#include <Base/VectorPy.h>
#include <Base/PlacementPy.h>
#include <App/Application.h>
#include <App/Document.h>
#include <App/DocumentObject.h>
#include <App/DocumentObjectPy.h>
//#include <Mod/Mesh/App/Core/MeshKernel.h>
//#include <Mod/Mesh/App/Core/Evaluation.h>
//#include <Mod/Mesh/App/Core/Iterator.h>
#include <SMESH_Gen.hxx>
#include <SMESH_Group.hxx>
#include <SMESHDS_Mesh.hxx>
#include <SMDS_MeshNode.hxx>
#include <StdMeshers_MaxLength.hxx>
#include <StdMeshers_LocalLength.hxx>
#include <StdMeshers_NumberOfSegments.hxx>
#include <StdMeshers_AutomaticLength.hxx>
#include <StdMeshers_TrianglePreference.hxx>
#include <StdMeshers_MEFISTO_2D.hxx>
#include <StdMeshers_Deflection1D.hxx>
#include <StdMeshers_MaxElementArea.hxx>
#include <StdMeshers_Regular_1D.hxx>
#include <StdMeshers_QuadranglePreference.hxx>
#include <StdMeshers_Quadrangle_2D.hxx>
#include <StdMeshers_LengthFromEdges.hxx>
#include <StdMeshers_NotConformAllowed.hxx>
#include <StdMeshers_Arithmetic1D.hxx>
#include "FemMesh.h"
#include "FemMeshObject.h"
#include "FemMeshPy.h"
#include <cstdlib>
#include <Standard_Real.hxx>
#include <Base/Vector3D.h>
#include <Mod/Part/App/OCCError.h>
namespace Fem {
class Module : public Py::ExtensionModule<Module>
{
public:
Module() : Py::ExtensionModule<Module>("Fem")
{
add_varargs_method("open",&Module::open,
"open(string) -- Create a new document and a Mesh::Import feature to load the file into the document."
);
add_varargs_method("insert",&Module::insert,
"insert(string|mesh,[string]) -- Load or insert a mesh into the given or active document."
);
add_varargs_method("export",&Module::exporter,
"export(list,string) -- Export a list of objects into a single file."
);
add_varargs_method("read",&Module::read,
"Read a mesh from a file and returns a Mesh object."
);
add_varargs_method("show",&Module::show,
"show(shape) -- Add the shape to the active document or create one if no document exists."
);
initialize("This module is the Fem module."); // register with Python
}
virtual ~Module() {}
private:
virtual Py::Object invoke_method_varargs(void *method_def, const Py::Tuple &args)
{
try {
return Py::ExtensionModule<Module>::invoke_method_varargs(method_def, args);
}
catch (const Standard_Failure &e) {
std::string str;
Standard_CString msg = e.GetMessageString();
str += typeid(e).name();
str += " ";
if (msg) {str += msg;}
else {str += "No OCCT Exception Message";}
throw Py::Exception(Part::PartExceptionOCCError, str);
}
catch (const Base::Exception &e) {
throw Py::RuntimeError(e.what());
}
catch (const std::exception &e) {
throw Py::RuntimeError(e.what());
}
}
Py::Object open(const Py::Tuple& args)
{
char* Name;
if (!PyArg_ParseTuple(args.ptr(), "et","utf-8",&Name))
throw Py::Exception();
std::string EncodedName = std::string(Name);
PyMem_Free(Name);
std::auto_ptr<FemMesh> mesh(new FemMesh);
mesh->read(EncodedName.c_str());
Base::FileInfo file(EncodedName.c_str());
// create new document and add Import feature
App::Document *pcDoc = App::GetApplication().newDocument("Unnamed");
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();
return Py::None();
}
Py::Object insert(const Py::Tuple& args)
{
char* Name;
const char* DocName = 0;
if (!PyArg_ParseTuple(args.ptr(), "et|s","utf-8",&Name,&DocName))
throw Py::Exception();
std::string EncodedName = std::string(Name);
PyMem_Free(Name);
App::Document *pcDoc = 0;
if (DocName)
pcDoc = App::GetApplication().getDocument(DocName);
else
pcDoc = App::GetApplication().getActiveDocument();
if (!pcDoc) {
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();
return Py::None();
}
Py::Object exporter(const Py::Tuple& args)
{
PyObject* object;
char* Name;
if (!PyArg_ParseTuple(args.ptr(), "Oet",&object,"utf-8",&Name))
throw Py::Exception();
std::string EncodedName = std::string(Name);
PyMem_Free(Name);
Py::Sequence list(object);
Base::Type meshId = Base::Type::fromName("Fem::FemMeshObject");
for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
PyObject* item = (*it).ptr();
if (PyObject_TypeCheck(item, &(App::DocumentObjectPy::Type))) {
App::DocumentObject* obj = static_cast<App::DocumentObjectPy*>(item)->getDocumentObjectPtr();
if (obj->getTypeId().isDerivedFrom(meshId)) {
static_cast<FemMeshObject*>(obj)->FemMesh.getValue().write(EncodedName.c_str());
break;
}
}
}
return Py::None();
}
Py::Object read(const Py::Tuple& args)
{
char* Name;
if (!PyArg_ParseTuple(args.ptr(), "et","utf-8",&Name))
throw Py::Exception();
std::string EncodedName = std::string(Name);
PyMem_Free(Name);
std::auto_ptr<FemMesh> mesh(new FemMesh);
mesh->read(EncodedName.c_str());
return Py::asObject(new FemMeshPy(mesh.release()));
}
Py::Object show(const Py::Tuple& args)
{
PyObject *pcObj;
if (!PyArg_ParseTuple(args.ptr(), "O!", &(FemMeshPy::Type), &pcObj))
throw Py::Exception();
App::Document *pcDoc = App::GetApplication().getActiveDocument();
if (!pcDoc)
pcDoc = App::GetApplication().newDocument();
FemMeshPy* pShape = static_cast<FemMeshPy*>(pcObj);
Fem::FemMeshObject *pcFeature = (Fem::FemMeshObject *)pcDoc->addObject("Fem::FemMeshObject", "Mesh");
// copy the data
//TopoShape* shape = new MeshObject(*pShape->getTopoShapeObjectPtr());
pcFeature->FemMesh.setValue(*(pShape->getFemMeshPtr()));
pcDoc->recompute();
return Py::None();
}
};
PyObject* initModule()
{
return (new Module)->module().ptr();
}
} // namespace Fem
=======
/*************************************************************************** /***************************************************************************
* Copyright (c) 2008 Jürgen Riegel (juergen.riegel@web.de) * * Copyright (c) 2008 Jürgen Riegel (juergen.riegel@web.de) *
* * * *
@ -507,4 +263,270 @@ PyObject* initModule()
} }
} // namespace Fem } // namespace Fem
>>>>>>> Move post processing to fem objects =======
/***************************************************************************
* Copyright (c) 2008 Jürgen Riegel (juergen.riegel@web.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 <Python.h>
# include <memory>
#endif
#include <CXX/Extensions.hxx>
#include <CXX/Objects.hxx>
#include <Base/Console.h>
#include <Base/Tools.h>
#include <Base/VectorPy.h>
#include <Base/PlacementPy.h>
#include <App/Application.h>
#include <App/Document.h>
#include <App/DocumentObject.h>
#include <App/DocumentObjectPy.h>
//#include <Mod/Mesh/App/Core/MeshKernel.h>
//#include <Mod/Mesh/App/Core/Evaluation.h>
//#include <Mod/Mesh/App/Core/Iterator.h>
#include <SMESH_Gen.hxx>
#include <SMESH_Group.hxx>
#include <SMESHDS_Mesh.hxx>
#include <SMDS_MeshNode.hxx>
#include <StdMeshers_MaxLength.hxx>
#include <StdMeshers_LocalLength.hxx>
#include <StdMeshers_NumberOfSegments.hxx>
#include <StdMeshers_AutomaticLength.hxx>
#include <StdMeshers_TrianglePreference.hxx>
#include <StdMeshers_MEFISTO_2D.hxx>
#include <StdMeshers_Deflection1D.hxx>
#include <StdMeshers_MaxElementArea.hxx>
#include <StdMeshers_Regular_1D.hxx>
#include <StdMeshers_QuadranglePreference.hxx>
#include <StdMeshers_Quadrangle_2D.hxx>
#include <StdMeshers_LengthFromEdges.hxx>
#include <StdMeshers_NotConformAllowed.hxx>
#include <StdMeshers_Arithmetic1D.hxx>
#include "FemMesh.h"
#include "FemMeshObject.h"
#include "FemPostPipeline.h"
#include "FemMeshPy.h"
#include <cstdlib>
#include <Standard_Real.hxx>
#include <Base/Vector3D.h>
#include <Mod/Part/App/OCCError.h>
namespace Fem {
class Module : public Py::ExtensionModule<Module>
{
public:
Module() : Py::ExtensionModule<Module>("Fem")
{
add_varargs_method("open",&Module::open,
"open(string) -- Create a new document and a Mesh::Import feature to load the file into the document."
);
add_varargs_method("insert",&Module::insert,
"insert(string|mesh,[string]) -- Load or insert a mesh into the given or active document."
);
add_varargs_method("export",&Module::exporter,
"export(list,string) -- Export a list of objects into a single file."
);
add_varargs_method("read",&Module::read,
"Read a mesh from a file and returns a Mesh object."
);
add_varargs_method("show",&Module::show,
"show(shape) -- Add the shape to the active document or create one if no document exists."
);
initialize("This module is the Fem module."); // register with Python
}
virtual ~Module() {}
private:
virtual Py::Object invoke_method_varargs(void *method_def, const Py::Tuple &args)
{
try {
return Py::ExtensionModule<Module>::invoke_method_varargs(method_def, args);
}
catch (const Standard_Failure &e) {
std::string str;
Standard_CString msg = e.GetMessageString();
str += typeid(e).name();
str += " ";
if (msg) {str += msg;}
else {str += "No OCCT Exception Message";}
throw Py::Exception(Part::PartExceptionOCCError, str);
}
catch (const Base::Exception &e) {
throw Py::RuntimeError(e.what());
}
catch (const std::exception &e) {
throw Py::RuntimeError(e.what());
}
}
Py::Object open(const Py::Tuple& args)
{
char* Name;
if (!PyArg_ParseTuple(args.ptr(), "et","utf-8",&Name))
throw Py::Exception();
std::string EncodedName = std::string(Name);
PyMem_Free(Name);
std::auto_ptr<FemMesh> mesh(new FemMesh);
mesh->read(EncodedName.c_str());
Base::FileInfo file(EncodedName.c_str());
// create new document and add Import feature
App::Document *pcDoc = App::GetApplication().newDocument("Unnamed");
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();
return Py::None();
}
Py::Object insert(const Py::Tuple& args)
{
char* Name;
const char* DocName = 0;
if (!PyArg_ParseTuple(args.ptr(), "et|s","utf-8",&Name,&DocName))
throw Py::Exception();
std::string EncodedName = std::string(Name);
PyMem_Free(Name);
App::Document *pcDoc = 0;
if (DocName)
pcDoc = App::GetApplication().getDocument(DocName);
else
pcDoc = App::GetApplication().getActiveDocument();
if (!pcDoc) {
pcDoc = App::GetApplication().newDocument(DocName);
}
Base::FileInfo file(EncodedName.c_str());
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();
pcDoc->recomputeFeature(pcFeature);
}
else
throw e;
#else
throw e;
#endif
}
return Py::None();
}
Py::Object exporter(const Py::Tuple& args)
{
PyObject* object;
char* Name;
if (!PyArg_ParseTuple(args.ptr(), "Oet",&object,"utf-8",&Name))
throw Py::Exception();
std::string EncodedName = std::string(Name);
PyMem_Free(Name);
Py::Sequence list(object);
Base::Type meshId = Base::Type::fromName("Fem::FemMeshObject");
for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
PyObject* item = (*it).ptr();
if (PyObject_TypeCheck(item, &(App::DocumentObjectPy::Type))) {
App::DocumentObject* obj = static_cast<App::DocumentObjectPy*>(item)->getDocumentObjectPtr();
if (obj->getTypeId().isDerivedFrom(meshId)) {
static_cast<FemMeshObject*>(obj)->FemMesh.getValue().write(EncodedName.c_str());
break;
}
}
}
return Py::None();
}
Py::Object read(const Py::Tuple& args)
{
char* Name;
if (!PyArg_ParseTuple(args.ptr(), "et","utf-8",&Name))
throw Py::Exception();
std::string EncodedName = std::string(Name);
PyMem_Free(Name);
std::auto_ptr<FemMesh> mesh(new FemMesh);
mesh->read(EncodedName.c_str());
return Py::asObject(new FemMeshPy(mesh.release()));
}
Py::Object show(const Py::Tuple& args)
{
PyObject *pcObj;
if (!PyArg_ParseTuple(args.ptr(), "O!", &(FemMeshPy::Type), &pcObj))
throw Py::Exception();
App::Document *pcDoc = App::GetApplication().getActiveDocument();
if (!pcDoc)
pcDoc = App::GetApplication().newDocument();
FemMeshPy* pShape = static_cast<FemMeshPy*>(pcObj);
Fem::FemMeshObject *pcFeature = (Fem::FemMeshObject *)pcDoc->addObject("Fem::FemMeshObject", "Mesh");
// copy the data
//TopoShape* shape = new MeshObject(*pShape->getTopoShapeObjectPtr());
pcFeature->FemMesh.setValue(*(pShape->getFemMeshPtr()));
pcDoc->recompute();
return Py::None();
}
};
PyObject* initModule()
{
return (new Module)->module().ptr();
}
} // namespace Fem
>>>>>>> Basic implementation of filter framework

View File

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

View File

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

View File

@ -27,6 +27,8 @@
#endif #endif
#include "FemPostFilter.h" #include "FemPostFilter.h"
#include "FemPostPipeline.h"
#include <Base/Console.h>
#include <App/DocumentObjectPy.h> #include <App/DocumentObjectPy.h>
using namespace Fem; using namespace Fem;
@ -37,30 +39,188 @@ PROPERTY_SOURCE(Fem::FemPostFilter, Fem::FemPostObject)
FemPostFilter::FemPostFilter() FemPostFilter::FemPostFilter()
{ {
m_pass = vtkPassThrough::New();
} }
FemPostFilter::~FemPostFilter() FemPostFilter::~FemPostFilter()
{ {
} }
short FemPostFilter::mustExecute(void) const bool FemPostFilter::valid() {
{ return polyDataSource && !m_pipelines.empty() && !m_activePipeline.empty();
return 0;
} }
PyObject *FemPostFilter::getPyObject() bool FemPostFilter::isConnected() {
{ return valid() && (m_pipelines[m_activePipeline].source->GetTotalNumberOfInputConnections() > 0);
if (PythonObject.is(Py::_None())){ }
// ref counter is set to 1
PythonObject = Py::Object(new DocumentObjectPy(this),true); 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 "FemPostObject.h"
#include <vtkSmartPointer.h> #include <vtkSmartPointer.h>
#include <vtkUnstructuredGrid.h> #include <vtkClipDataSet.h>
#include <vtkExtractGeometry.h>
#include <vtkGeometryFilter.h>
#include <vtkPassThrough.h>
#include <vtkPlane.h>
namespace Fem namespace Fem
{ {
@ -41,18 +45,63 @@ public:
FemPostFilter(void); FemPostFilter(void);
virtual ~FemPostFilter(); virtual ~FemPostFilter();
/// returns the type name of the ViewProvider virtual App::DocumentObjectExecReturn* execute(void);
virtual const char* getViewProviderName(void) const {
return "FemGui::ViewProviderPostPipeline"; vtkSmartPointer<vtkAlgorithm> getOutputAlgorithm();
}
short mustExecute(void) const; bool hasInputAlgorithmConnected();
PyObject* getPyObject(); 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:
//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: protected:
virtual void onChanged(const App::Property* prop); virtual void onChanged(const App::Property* prop);
//members private:
vtkSmartPointer<vtkUnstructuredGrid> source; vtkSmartPointer<vtkClipDataSet> m_clipper;
vtkSmartPointer<vtkExtractGeometry> m_extractor;
}; };
} //namespace Fem } //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 "FemPostObject.h"
#include <Base/Console.h> #include <Base/Console.h>
#include <App/Application.h>
#include <App/Document.h>
#include <App/DocumentObjectPy.h> #include <App/DocumentObjectPy.h>
#include <vtkPointData.h> #include <vtkPointData.h>
#include <vtkCellData.h> #include <vtkCellData.h>
@ -54,41 +56,24 @@ short FemPostObject::mustExecute(void) const
DocumentObjectExecReturn* FemPostObject::execute(void) { DocumentObjectExecReturn* FemPostObject::execute(void) {
//analyse the data and print if(providesPolyData()) {
Base::Console().Message("\nPoly Data Analysis:\n"); polyDataSource->Update();
vtkSmartPointer<vtkPolyData> poly = polyDataSource->GetOutput();
vtkPolyData* poly = polyDataSource->GetOutput(); if(static_cast<unsigned long>(ModificationTime.getValue()) != poly->GetMTime()) {
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(); //update the bounding box
Base::Console().Message("Cell components: %i\n", cell->GetNumberOfComponents()); m_boundingBox = vtkBoundingBox(poly->GetBounds());
Base::Console().Message("Cell arrays: %i\n", cell->GetNumberOfArrays());
Base::Console().Message("Point tuples: %i\n", cell->GetNumberOfTuples());
//update the modification time to let the viewprovider know something changed
if(polyDataSource && static_cast<unsigned long>(ModificationTime.getValue()) < polyDataSource->GetMTime()) ModificationTime.setValue(static_cast<long>(poly->GetMTime()));
ModificationTime.setValue(static_cast<unsigned long>(polyDataSource->GetMTime())); }
}
return DocumentObject::StdReturn; 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) void FemPostObject::onChanged(const Property* prop)
{ {
App::GeoFeature::onChanged(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 <vtkSmartPointer.h>
#include <vtkPolyDataAlgorithm.h> #include <vtkPolyDataAlgorithm.h>
#include <vtkBoundingBox.h>
namespace Fem namespace Fem
{ {
@ -52,11 +53,13 @@ public:
short mustExecute(void) const; short mustExecute(void) const;
virtual App::DocumentObjectExecReturn* execute(void); 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 //poly data algorithm handling
vtkPolyData* getPolyData() {return polyDataSource->GetOutput();}; virtual bool providesPolyData() {return getPolyAlgorithm()!=NULL;};
vtkSmartPointer<vtkPolyDataAlgorithm> getPolyAlgorithm() {return polyDataSource;}; vtkSmartPointer<vtkPolyDataAlgorithm> getPolyAlgorithm() {return polyDataSource;};
protected: protected:
@ -64,6 +67,9 @@ protected:
//members //members
vtkSmartPointer<vtkPolyDataAlgorithm> polyDataSource; vtkSmartPointer<vtkPolyDataAlgorithm> polyDataSource;
private:
vtkBoundingBox m_boundingBox;
}; };
} //namespace Fem } //namespace Fem

View File

@ -28,21 +28,31 @@
#include "FemPostPipeline.h" #include "FemPostPipeline.h"
#include <Base/Console.h> #include <Base/Console.h>
#include <App/Document.h>
#include <App/DocumentObjectPy.h> #include <App/DocumentObjectPy.h>
#include <vtkDataSetReader.h> #include <vtkDataSetReader.h>
#include <vtkGeometryFilter.h> #include <vtkGeometryFilter.h>
#include <vtkPointData.h> #include <vtkPointData.h>
#include <vtkStructuredGrid.h> #include <vtkStructuredGrid.h>
#include <vtkCellData.h> #include <vtkCellData.h>
#include <vtkUnstructuredGrid.h>
using namespace Fem; using namespace Fem;
using namespace App; using namespace App;
PROPERTY_SOURCE(Fem::FemPostPipeline, Fem::FemPostObject) PROPERTY_SOURCE(Fem::FemPostPipeline, Fem::FemPostObject)
const char* FemPostPipeline::ModeEnums[]= {"Serial","Parallel",NULL};
FemPostPipeline::FemPostPipeline() 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() FemPostPipeline::~FemPostPipeline()
@ -51,27 +61,26 @@ FemPostPipeline::~FemPostPipeline()
short FemPostPipeline::mustExecute(void) const short FemPostPipeline::mustExecute(void) const
{ {
return 1; return 1;
} }
DocumentObjectExecReturn* FemPostPipeline::execute(void) { DocumentObjectExecReturn* FemPostPipeline::execute(void) {
Base::Console().Message("Pipeline analysis: \n"); // Base::Console().Message("Pipeline analysis: \n");
Base::Console().Message("Data Type: %i\n", source->GetDataObjectType()); // Base::Console().Message("Data Type: %i\n", source->GetDataObjectType());
//
if(source->GetDataObjectType() == VTK_STRUCTURED_GRID ) { // if(source->GetDataObjectType() == VTK_STRUCTURED_GRID ) {
vtkStructuredGrid* poly = static_cast<vtkStructuredGrid*>(source.GetPointer()); // vtkStructuredGrid* poly = static_cast<vtkStructuredGrid*>(source.GetPointer());
vtkPointData* point = poly->GetPointData(); // vtkPointData* point = poly->GetPointData();
Base::Console().Message("Point components: %i\n", point->GetNumberOfComponents()); // Base::Console().Message("Point components: %i\n", point->GetNumberOfComponents());
Base::Console().Message("Point arrays: %i\n", point->GetNumberOfArrays()); // Base::Console().Message("Point arrays: %i\n", point->GetNumberOfArrays());
Base::Console().Message("Point tuples: %i\n", point->GetNumberOfTuples()); // Base::Console().Message("Point tuples: %i\n", point->GetNumberOfTuples());
//
vtkCellData* cell = poly->GetCellData(); // vtkCellData* cell = poly->GetCellData();
Base::Console().Message("Cell components: %i\n", cell->GetNumberOfComponents()); // Base::Console().Message("Cell components: %i\n", cell->GetNumberOfComponents());
Base::Console().Message("Cell arrays: %i\n", cell->GetNumberOfArrays()); // Base::Console().Message("Cell arrays: %i\n", cell->GetNumberOfArrays());
Base::Console().Message("Point tuples: %i\n", cell->GetNumberOfTuples()); // Base::Console().Message("Point tuples: %i\n", cell->GetNumberOfTuples());
} // }
return Fem::FemPostObject::execute(); return Fem::FemPostObject::execute();
} }
@ -110,19 +119,54 @@ void FemPostPipeline::read(Base::FileInfo File) {
} }
PyObject *FemPostPipeline::getPyObject() // PyObject *FemPostPipeline::getPyObject()
{ // {
if (PythonObject.is(Py::_None())){ // if (PythonObject.is(Py::_None())){
// ref counter is set to 1 // // ref counter is set to 1
PythonObject = Py::Object(new DocumentObjectPy(this),true); // PythonObject = Py::Object(new DocumentObjectPy(this),true);
} // }
return Py::new_reference_to(PythonObject); // return Py::new_reference_to(PythonObject);
} // }
void FemPostPipeline::onChanged(const Property* prop) 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); 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 #define Fem_FemPostPipeline_H
#include "FemPostObject.h" #include "FemPostObject.h"
#include "FemPostFilter.h"
#include "FemPostFunction.h"
#include <vtkSmartPointer.h> #include <vtkSmartPointer.h>
#include <vtkDataSet.h> #include <vtkDataSet.h>
@ -41,24 +43,32 @@ public:
FemPostPipeline(void); FemPostPipeline(void);
virtual ~FemPostPipeline(); virtual ~FemPostPipeline();
/// returns the type name of the ViewProvider App::PropertyLinkList Filter;
// virtual const char* getViewProviderName(void) const { App::PropertyLink Function;
// return "FemGui::ViewProviderPostPipeline"; App::PropertyEnumeration Mode;
// }
short mustExecute(void) const; short mustExecute(void) const;
virtual App::DocumentObjectExecReturn* execute(void); virtual App::DocumentObjectExecReturn* execute(void);
PyObject* getPyObject(); //PyObject* getPyObject();
virtual const char* getViewProviderName(void) const {
return "FemGui::ViewProviderFemPostPipeline";
}
//load data from files //load data from files
static bool canRead(Base::FileInfo file); static bool canRead(Base::FileInfo file);
void read(Base::FileInfo file); void read(Base::FileInfo file);
//Pipeline handling
vtkSmartPointer<vtkDataSet> getSource() {return source;};
FemPostObject* getLastPostObject();
protected: protected:
virtual void onChanged(const App::Property* prop); virtual void onChanged(const App::Property* prop);
//members private:
vtkSmartPointer<vtkDataSet> source; vtkSmartPointer<vtkDataSet> source;
static const char* ModeEnums[];
}; };
} //namespace Fem } //namespace Fem

View File

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

View File

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

View File

@ -26,6 +26,7 @@
# include <Standard_math.hxx> # include <Standard_math.hxx>
# include <QApplication> # include <QApplication>
# include <QMessageBox> # include <QMessageBox>
#include <QAction>
#endif #endif
#include <Inventor/nodes/SoEventCallback.h> #include <Inventor/nodes/SoEventCallback.h>
@ -47,6 +48,7 @@
#include <Gui/View3DInventor.h> #include <Gui/View3DInventor.h>
#include <Gui/View3DInventorViewer.h> #include <Gui/View3DInventorViewer.h>
#include <Gui/Utilities.h> #include <Gui/Utilities.h>
#include <Gui/Action.h>
#include <SMESH_Mesh.hxx> #include <SMESH_Mesh.hxx>
#include <SMESHDS_Mesh.hxx> #include <SMESHDS_Mesh.hxx>
@ -58,9 +60,12 @@
#include <strstream> #include <strstream>
#include <Mod/Fem/App/FemConstraint.h> #include <Mod/Fem/App/FemConstraint.h>
#include <Mod/Fem/App/FemAnalysis.h> #include <Mod/Fem/App/FemAnalysis.h>
#include "ActiveAnalysisObserver.h" #include "ActiveAnalysisObserver.h"
#ifdef FC_USE_VTK
#include <Mod/Fem/App/FemPostPipeline.h>
#endif
using namespace std; using namespace std;
@ -757,6 +762,215 @@ bool CmdFemCreateNodesSet::isActive(void)
return hasActiveDocument(); 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 CmdFemConstraintGear());
rcCmdMgr.addCommand(new CmdFemConstraintPulley()); rcCmdMgr.addCommand(new CmdFemConstraintPulley());
rcCmdMgr.addCommand(new CmdFemConstraintDisplacement()); 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() { void ViewProviderFemPostObject::WriteColorData() {
if(!m_currentAlgorithm) if(!setupPipeline())
return; return;
if(Coloring.getEnumVector().empty() || Coloring.getValue() == 0) { if(Coloring.getEnumVector().empty() || Coloring.getValue() == 0) {
@ -429,7 +429,7 @@ void ViewProviderFemPostObject::updateData(const App::Property* p) {
bool ViewProviderFemPostObject::setupPipeline() { bool ViewProviderFemPostObject::setupPipeline() {
if(!static_cast<Fem::FemPostObject*>(getObject())->getPolyAlgorithm()) if(!static_cast<Fem::FemPostObject*>(getObject())->providesPolyData())
return false; return false;
if(!m_currentAlgorithm) { 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

@ -78,6 +78,15 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
<< "Fem_RunSolver" << "Fem_RunSolver"
<< "Fem_PurgeResults" << "Fem_PurgeResults"
<< "Fem_ShowResult"; << "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; return root;
} }