FEM Post: Detail filter infrastructure

This commit is contained in:
Stefan Tröger 2015-11-06 22:05:37 +01:00 committed by wmayer
parent 2b9e608501
commit 51f2a0efc6
25 changed files with 2827 additions and 83 deletions

View File

@ -156,8 +156,10 @@ PyMODINIT_FUNC initFem()
Fem::FemPostPipeline ::init();
Fem::FemPostFilter ::init();
Fem::FemPostClipFilter ::init();
Fem::FemPostScalarClipFilter ::init();
Fem::FemPostFunction ::init();
Fem::FemPostFunctionProvider ::init();
Fem::FemPostPlaneFunction ::init();
Fem::FemPostSphereFunction ::init();
#endif
}

View File

@ -1,4 +1,4 @@
<<<<<<< eec6f7aee8b6e5979a799358e2ae69bdc5a7af5b
<<<<<<< 387862dfe753cf0cb062032e97840353b14dcbae
/***************************************************************************
* Copyright (c) 2008 Jürgen Riegel (juergen.riegel@web.de) *
* *
@ -55,8 +55,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();
@ -152,6 +156,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
}
=======
@ -313,9 +321,11 @@ PyMODINIT_FUNC initFem()
Fem::FemPostPipeline ::init();
Fem::FemPostFilter ::init();
Fem::FemPostClipFilter ::init();
Fem::FemPostScalarClipFilter ::init();
Fem::FemPostFunction ::init();
Fem::FemPostFunctionProvider ::init();
Fem::FemPostPlaneFunction ::init();
Fem::FemPostSphereFunction ::init();
#endif
}
>>>>>>> Basic implementation of filter framework
>>>>>>> Detail filter infrastructure

View File

@ -30,6 +30,8 @@
#include "FemPostPipeline.h"
#include <Base/Console.h>
#include <App/DocumentObjectPy.h>
#include <vtkFieldData.h>
#include <vtkPointData.h>
using namespace Fem;
using namespace App;
@ -44,6 +46,9 @@ FemPostFilter::FemPostFilter()
FemPostFilter::~FemPostFilter()
{
//we need to make sure that all vtk filters are disconnected
//as the would stay alive and connected otherwise
clearInput();
}
bool FemPostFilter::valid() {
@ -173,11 +178,11 @@ 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();
m_clipper = vtkTableBasedClipDataSet::New();
clip.source = m_clipper;
clip.target = m_clipper;
clip.visualisation = m_clipper;
@ -224,3 +229,115 @@ void FemPostClipFilter::onChanged(const Property* prop) {
}
PROPERTY_SOURCE(Fem::FemPostScalarClipFilter, Fem::FemPostFilter)
FemPostScalarClipFilter::FemPostScalarClipFilter(void) : FemPostFilter() {
ADD_PROPERTY_TYPE(Value, (0), "Clip", App::Prop_None, "The scalar value used to clip the selected field");
ADD_PROPERTY_TYPE(Scalars, (long(0)), "Clip", App::Prop_None, "The field used to clip");
ADD_PROPERTY_TYPE(InsideOut, (false), "Clip", App::Prop_None, "Invert the clip direction");
Value.setConstraints(&m_constraints);
polyDataSource = vtkGeometryFilter::New();
FilterPipeline clip;
m_clipper = vtkTableBasedClipDataSet::New();
clip.source = m_clipper;
clip.target = m_clipper;
clip.visualisation = m_clipper;
addFilterPipeline(clip, "clip");
setActiveFilterPipeline("clip");
}
FemPostScalarClipFilter::~FemPostScalarClipFilter() {
}
DocumentObjectExecReturn* FemPostScalarClipFilter::execute(void) {
//update the available fields and set the correct input field data for clipping
if(!isConnected())
return StdReturn;
std::string val;
if(m_scalarFields.getEnums() && Scalars.getValue() >= 0)
val = Scalars.getValueAsString();
std::vector<std::string> array;
vtkDataObject* data;
if(hasInputAlgorithmConnected()) {
getConnectedInputAlgorithm()->Update();
data = getConnectedInputAlgorithm()->GetOutputDataObject(0);
}
else
data = getConnectedInputData();
vtkDataSet* dset = dynamic_cast<vtkDataSet*>(data);
if(!dset)
return StdReturn;
vtkPointData* pd = dset->GetPointData();
for(int i=0; i<pd->GetNumberOfArrays(); ++i) {
if(pd->GetArray(i)->GetNumberOfComponents()==1)
array.push_back(pd->GetArrayName(i));
}
App::Enumeration empty;
Scalars.setValue(empty);
m_scalarFields.setEnums(array);
Scalars.setValue(m_scalarFields);
std::vector<std::string>::iterator it = std::find(array.begin(), array.end(), val);
if(!val.empty() && it != array.end())
Scalars.setValue(val.c_str());
//recalculate the filter
return Fem::FemPostFilter::execute();
}
void FemPostScalarClipFilter::onChanged(const Property* prop) {
if(prop == &Value) {
m_clipper->SetValue(Value.getValue());
}
else if(prop == &InsideOut) {
m_clipper->SetInsideOut(InsideOut.getValue());
}
else if(prop == &Scalars && (Scalars.getValue() >= 0)) {
m_clipper->SetInputArrayToProcess(0, 0, 0,
vtkDataObject::FIELD_ASSOCIATION_POINTS, Scalars.getValueAsString() );
setConstraintForField();
}
Fem::FemPostFilter::onChanged(prop);
}
void FemPostScalarClipFilter::setConstraintForField() {
vtkDataObject* data;
if(hasInputAlgorithmConnected()) {
getConnectedInputAlgorithm()->Update();
data = getConnectedInputAlgorithm()->GetOutputDataObject(0);
}
else
data = getConnectedInputData();
vtkDataSet* dset = dynamic_cast<vtkDataSet*>(data);
if(!dset)
return;
vtkDataArray* pdata = dset->GetPointData()->GetArray(Scalars.getValueAsString());
double p[2];
pdata->GetRange(p);
m_constraints.LowerBound = p[0];
m_constraints.UpperBound = p[1];
m_constraints.StepSize = (p[1]-p[0])/100.;
}

View File

@ -25,9 +25,10 @@
#define Fem_FemPostFilter_H
#include "FemPostObject.h"
#include <App/PropertyUnits.h>
#include <vtkSmartPointer.h>
#include <vtkClipDataSet.h>
#include <vtkTableBasedClipDataSet.h>
#include <vtkExtractGeometry.h>
#include <vtkGeometryFilter.h>
#include <vtkPassThrough.h>
@ -92,18 +93,50 @@ public:
FemPostClipFilter(void);
virtual ~FemPostClipFilter();
App::PropertyLink Function;
App::PropertyBool InsideOut;
App::PropertyBool CutCells;
App::PropertyLink Function;
App::PropertyBool InsideOut;
App::PropertyBool CutCells;
virtual const char* getViewProviderName(void) const {
return "FemGui::ViewProviderFemPostClip";
}
protected:
virtual void onChanged(const App::Property* prop);
private:
vtkSmartPointer<vtkClipDataSet> m_clipper;
vtkSmartPointer<vtkTableBasedClipDataSet> m_clipper;
vtkSmartPointer<vtkExtractGeometry> m_extractor;
};
class AppFemExport FemPostScalarClipFilter : public FemPostFilter {
PROPERTY_HEADER(Fem::FemPostScalarClipFilter);
public:
FemPostScalarClipFilter(void);
virtual ~FemPostScalarClipFilter();
App::PropertyBool InsideOut;
App::PropertyFloatConstraint Value;
App::PropertyEnumeration Scalars;
virtual const char* getViewProviderName(void) const {
return "FemGui::ViewProviderFemPostScalarClip";
}
protected:
virtual App::DocumentObjectExecReturn* execute(void);
virtual void onChanged(const App::Property* prop);
void setConstraintForField();
private:
vtkSmartPointer<vtkTableBasedClipDataSet> m_clipper;
App::Enumeration m_scalarFields;
App::PropertyFloatConstraint::Constraints m_constraints;
};
} //namespace Fem

View File

@ -96,3 +96,37 @@ void FemPostPlaneFunction::onChanged(const Property* prop) {
Fem::FemPostFunction::onChanged(prop);
}
PROPERTY_SOURCE(Fem::FemPostSphereFunction, Fem::FemPostFunction)
FemPostSphereFunction::FemPostSphereFunction(void): FemPostFunction() {
ADD_PROPERTY(Radius,(5));
ADD_PROPERTY(Center,(Base::Vector3d(1.0,0.0,0.0)));
m_sphere = vtkSphere::New();
m_implicit = m_sphere;
m_sphere->SetCenter(0., 0., 0.);
m_sphere->SetRadius(5);
}
FemPostSphereFunction::~FemPostSphereFunction() {
}
void FemPostSphereFunction::onChanged(const Property* prop) {
if(prop == &Center) {
const Base::Vector3d& vec = Center.getValue();
m_sphere->SetCenter(vec[0], vec[1], vec[2]);
}
else if(prop == &Radius) {
m_sphere->SetRadius(Radius.getValue());
}
Fem::FemPostFunction::onChanged(prop);
}

View File

@ -25,11 +25,12 @@
#define Fem_FemPostFunction_H
#include "FemPostObject.h"
#include <App/PropertyUnits.h>
#include <vtkSmartPointer.h>
#include <vtkImplicitFunction.h>
#include <vtkPlane.h>
#include <vtkPlaneSource.h>
#include <vtkSphere.h>
namespace Fem
{
@ -103,6 +104,30 @@ protected:
vtkSmartPointer<vtkPlane> m_plane;
};
////////////////////////////////////////////////////////////////////////////////////////////
class AppFemExport FemPostSphereFunction : public FemPostFunction
{
PROPERTY_HEADER(Fem::FemPostSphereFunction);
public:
FemPostSphereFunction(void);
virtual ~FemPostSphereFunction();
App::PropertyDistance Radius;
App::PropertyVectorDistance Center;
virtual const char* getViewProviderName(void) const {
return "FemGui::ViewProviderFemPostSphereFunction";
}
protected:
virtual void onChanged(const App::Property* prop);
vtkSmartPointer<vtkSphere> m_sphere;
};
} //namespace Fem

View File

@ -134,6 +134,10 @@ void FemPostPipeline::onChanged(const Property* prop)
//we check if all connections are right and add new ones if needed
std::vector<App::DocumentObject*> objs = Filter.getValues();
if(objs.empty())
return;
std::vector<App::DocumentObject*>::iterator it = objs.begin();
FemPostFilter* filter = static_cast<FemPostFilter*>(*it);

View File

@ -59,6 +59,7 @@
#include "ViewProviderFemPostObject.h"
#include "ViewProviderFemPostPipeline.h"
#include "ViewProviderFemPostFunction.h"
#include "ViewProviderFemPostFilter.h"
#endif
#ifdef FC_USE_VTK
@ -126,6 +127,9 @@ PyMODINIT_FUNC initFemGui()
FemGui::ViewProviderFemPostFunction ::init();
FemGui::ViewProviderFemPostFunctionProvider::init();
FemGui::ViewProviderFemPostPlaneFunction ::init();
FemGui::ViewProviderFemPostSphereFunction ::init();
FemGui::ViewProviderFemPostClip ::init();
FemGui::ViewProviderFemPostScalarClip ::init();
#endif

View File

@ -67,6 +67,13 @@ set(FemGui_MOC_HDRS
TaskDlgAnalysis.h
TaskDlgMeshShapeNetgen.h
)
if(BUILD_FEM_VTK)
set(FemGui_MOC_HDRS
${FemGui_MOC_HDRS}
TaskPostBoxes.h
ViewProviderFemPostFunction.h
)
endif(BUILD_FEM_VTK)
fc_wrap_cpp(FemGui_MOC_SRCS ${FemGui_MOC_HDRS})
SOURCE_GROUP("Moc" FILES ${FemGui_MOC_SRCS})
@ -84,6 +91,16 @@ set(FemGui_UIC_SRCS
TaskAnalysisInfo.ui
TaskDriver.ui
)
if(BUILD_FEM_VTK)
set(FemGui_UIC_SRCS
${FemGui_UIC_SRCS}
TaskPostDisplay.ui
TaskPostClip.ui
TaskPostScalarClip.ui
PlaneWidget.ui
SphereWidget.ui
)
endif(BUILD_FEM_VTK)
qt4_wrap_ui(FemGui_UIC_HDRS ${FemGui_UIC_SRCS})
SET(FemGui_DLG_SRCS
@ -179,6 +196,18 @@ SET(FemGui_SRCS_TaskBoxes
TaskTetParameter.cpp
TaskTetParameter.h
)
if(BUILD_FEM_VTK)
SET(FemGui_SRCS_TaskBoxes
${FemGui_SRCS_TaskBoxes}
PlaneWidget.ui
SphereWidget.ui
TaskPostClip.ui
TaskPostScalarClip.ui
TaskPostDisplay.ui
TaskPostBoxes.h
TaskPostBoxes.cpp
)
endif(BUILD_FEM_VTK)
SOURCE_GROUP("Task_Boxes" FILES ${FemGui_SRCS_TaskBoxes})
SET(FemGui_SRCS_TaskDlg
@ -217,6 +246,8 @@ if(BUILD_FEM_VTK)
ViewProviderFemPostPipeline.cpp
ViewProviderFemPostFunction.h
ViewProviderFemPostFunction.cpp
ViewProviderFemPostFilter.h
ViewProviderFemPostFilter.cpp
)
SOURCE_GROUP("PostObjects" FILES ${FemGui_SRCS_Post})
endif(BUILD_FEM_VTK)

View File

@ -775,8 +775,8 @@ CmdFemPostCreateClipFilter::CmdFemPostCreateClipFilter()
{
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...");
sMenuText = QT_TR_NOOP("Define/create a clip filter which uses functions to define the cliped region");
sToolTipText = QT_TR_NOOP("Define/create a clip filter which uses functions to define the cliped region");
sWhatsThis = "Fem_PostCreateClipFilter";
sStatusTip = sToolTipText;
sPixmap = "fem-fem-mesh-create-node-by-poly";
@ -784,10 +784,9 @@ CmdFemPostCreateClipFilter::CmdFemPostCreateClipFilter()
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::vector<Fem::FemPostPipeline*> pipelines = App::GetApplication().getActiveDocument()->getObjectsOfType<Fem::FemPostPipeline>();
if (!pipelines.empty()) {
Fem::FemPostPipeline *pipeline = pipelines.front();
std::string FeatName = getUniqueObjectName("Clip");
@ -799,6 +798,8 @@ void CmdFemPostCreateClipFilter::activated(int iMsg)
doCommand(Doc,"del __list__");
this->updateActive();
doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str());
}
else {
QMessageBox::warning(Gui::getMainWindow(),
@ -812,6 +813,50 @@ bool CmdFemPostCreateClipFilter::isActive(void)
return hasActiveDocument();
}
DEF_STD_CMD_A(CmdFemPostCreateScalarClipFilter);
CmdFemPostCreateScalarClipFilter::CmdFemPostCreateScalarClipFilter()
: Command("Fem_PostCreateScalarClipFilter")
{
sAppModule = "Fem";
sGroup = QT_TR_NOOP("Fem");
sMenuText = QT_TR_NOOP("Define/create a clip filter which clips a field with a scalar value");
sToolTipText = QT_TR_NOOP("Define/create a clip filter which clips a field with a scalar value");
sWhatsThis = "Fem_PostCreateScalarClipFilter";
sStatusTip = sToolTipText;
sPixmap = "fem-fem-mesh-create-node-by-poly";
}
void CmdFemPostCreateScalarClipFilter::activated(int iMsg)
{
std::vector<Fem::FemPostPipeline*> pipelines = App::GetApplication().getActiveDocument()->getObjectsOfType<Fem::FemPostPipeline>();
if (!pipelines.empty()) {
Fem::FemPostPipeline *pipeline = pipelines.front();
std::string FeatName = getUniqueObjectName("ScalarClip");
openCommand("Create scalar clip filter");
doCommand(Doc,"App.activeDocument().addObject('Fem::FemPostScalarClipFilter','%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();
doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str());
}
else {
QMessageBox::warning(Gui::getMainWindow(),
qApp->translate("CmdFemPostCreateScalarClipFilter", "Wrong selection"),
qApp->translate("CmdFemPostCreateScalarClipFilter", "Select a pipeline, please."));
}
}
bool CmdFemPostCreateScalarClipFilter::isActive(void)
{
return hasActiveDocument();
}
// #####################################################################################################
@ -826,31 +871,30 @@ CmdFemPostFunctions::CmdFemPostFunctions()
sToolTipText = QT_TR_NOOP("Functions for use in postprocessing filter...");
sWhatsThis = "Fem_PostCreateFunctions";
sStatusTip = sToolTipText;
eType = eType|ForEdit;
}
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");
name = "Sphere";
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());
std::vector<Fem::FemPostPipeline*> pipelines = App::GetApplication().getActiveDocument()->getObjectsOfType<Fem::FemPostPipeline>();
if (!pipelines.empty()) {
Fem::FemPostPipeline *pipeline = pipelines.front();
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()) {
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());
@ -868,6 +912,7 @@ void CmdFemPostFunctions::activated(int iMsg)
doCommand(Doc,"del __list__");
this->updateActive();
doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str());
}
else {
QMessageBox::warning(Gui::getMainWindow(),
@ -891,7 +936,7 @@ Gui::Action * CmdFemPostFunctions::createAction(void)
applyCommandData(this->className(), pcAction);
QAction* cmd0 = pcAction->addAction(QString());
//cmd0->setIcon(Gui::BitmapFactory().pixmap("Part_JoinConnect"));
pcAction->addAction(QString());
_pcAction = pcAction;
languageChange();
@ -912,10 +957,15 @@ void CmdFemPostFunctions::languageChange()
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());
QAction* cmd = a[0];
cmd->setText(QApplication::translate("CmdFemPostFunctions","Plane"));
cmd->setToolTip(QApplication::translate("Fem_PostCreateFunctions","Create a plane function, defined by its orgin and normal"));
cmd->setStatusTip(cmd->toolTip());
cmd = a[1];
cmd->setText(QApplication::translate("CmdFemPostFunctions","Sphere"));
cmd->setToolTip(QApplication::translate("Fem_PostCreateFunctions","Create a phere function, defined by its center and radius"));
cmd->setStatusTip(cmd->toolTip());
}
@ -927,6 +977,7 @@ bool CmdFemPostFunctions::isActive(void)
return false;
}
DEF_STD_CMD_AC(CmdFemPostApllyChanges);
CmdFemPostApllyChanges::CmdFemPostApllyChanges()
@ -939,6 +990,7 @@ CmdFemPostApllyChanges::CmdFemPostApllyChanges()
sWhatsThis = "Fem_PostApplyChanges";
sStatusTip = sToolTipText;
sPixmap = "view-refresh";
eType = eType|ForEdit;
}
void CmdFemPostApllyChanges::activated(int iMsg)
@ -992,6 +1044,7 @@ void CreateFemCommands(void)
#ifdef FC_USE_VTK
rcCmdMgr.addCommand(new CmdFemPostCreateClipFilter);
rcCmdMgr.addCommand(new CmdFemPostCreateScalarClipFilter);
rcCmdMgr.addCommand(new CmdFemPostFunctions);
rcCmdMgr.addCommand(new CmdFemPostApllyChanges);
#endif

View File

@ -1,4 +1,4 @@
<<<<<<< eec6f7aee8b6e5979a799358e2ae69bdc5a7af5b
<<<<<<< 387862dfe753cf0cb062032e97840353b14dcbae
/***************************************************************************
* Copyright (c) 2008 Jürgen Riegel (juergen.riegel@web.de) *
* *
@ -27,6 +27,7 @@
# include <Standard_math.hxx>
# include <QApplication>
# include <QMessageBox>
#include <QAction>
#endif
#include <Inventor/nodes/SoEventCallback.h>
@ -48,6 +49,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>
@ -59,9 +61,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;
@ -758,6 +763,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
//--------------------------------------------------------------------------------------
@ -776,6 +990,12 @@ 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
}
=======
/***************************************************************************
@ -1555,8 +1775,8 @@ CmdFemPostCreateClipFilter::CmdFemPostCreateClipFilter()
{
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...");
sMenuText = QT_TR_NOOP("Define/create a clip filter which uses functions to define the cliped region");
sToolTipText = QT_TR_NOOP("Define/create a clip filter which uses functions to define the cliped region");
sWhatsThis = "Fem_PostCreateClipFilter";
sStatusTip = sToolTipText;
sPixmap = "fem-fem-mesh-create-node-by-poly";
@ -1564,10 +1784,9 @@ CmdFemPostCreateClipFilter::CmdFemPostCreateClipFilter()
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::vector<Fem::FemPostPipeline*> pipelines = App::GetApplication().getActiveDocument()->getObjectsOfType<Fem::FemPostPipeline>();
if (!pipelines.empty()) {
Fem::FemPostPipeline *pipeline = pipelines.front();
std::string FeatName = getUniqueObjectName("Clip");
@ -1579,6 +1798,8 @@ void CmdFemPostCreateClipFilter::activated(int iMsg)
doCommand(Doc,"del __list__");
this->updateActive();
doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str());
}
else {
QMessageBox::warning(Gui::getMainWindow(),
@ -1592,6 +1813,50 @@ bool CmdFemPostCreateClipFilter::isActive(void)
return hasActiveDocument();
}
DEF_STD_CMD_A(CmdFemPostCreateScalarClipFilter);
CmdFemPostCreateScalarClipFilter::CmdFemPostCreateScalarClipFilter()
: Command("Fem_PostCreateScalarClipFilter")
{
sAppModule = "Fem";
sGroup = QT_TR_NOOP("Fem");
sMenuText = QT_TR_NOOP("Define/create a clip filter which clips a field with a scalar value");
sToolTipText = QT_TR_NOOP("Define/create a clip filter which clips a field with a scalar value");
sWhatsThis = "Fem_PostCreateScalarClipFilter";
sStatusTip = sToolTipText;
sPixmap = "fem-fem-mesh-create-node-by-poly";
}
void CmdFemPostCreateScalarClipFilter::activated(int iMsg)
{
std::vector<Fem::FemPostPipeline*> pipelines = App::GetApplication().getActiveDocument()->getObjectsOfType<Fem::FemPostPipeline>();
if (!pipelines.empty()) {
Fem::FemPostPipeline *pipeline = pipelines.front();
std::string FeatName = getUniqueObjectName("ScalarClip");
openCommand("Create scalar clip filter");
doCommand(Doc,"App.activeDocument().addObject('Fem::FemPostScalarClipFilter','%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();
doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str());
}
else {
QMessageBox::warning(Gui::getMainWindow(),
qApp->translate("CmdFemPostCreateScalarClipFilter", "Wrong selection"),
qApp->translate("CmdFemPostCreateScalarClipFilter", "Select a pipeline, please."));
}
}
bool CmdFemPostCreateScalarClipFilter::isActive(void)
{
return hasActiveDocument();
}
// #####################################################################################################
@ -1606,31 +1871,30 @@ CmdFemPostFunctions::CmdFemPostFunctions()
sToolTipText = QT_TR_NOOP("Functions for use in postprocessing filter...");
sWhatsThis = "Fem_PostCreateFunctions";
sStatusTip = sToolTipText;
eType = eType|ForEdit;
}
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");
name = "Sphere";
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());
std::vector<Fem::FemPostPipeline*> pipelines = App::GetApplication().getActiveDocument()->getObjectsOfType<Fem::FemPostPipeline>();
if (!pipelines.empty()) {
Fem::FemPostPipeline *pipeline = pipelines.front();
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()) {
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());
@ -1648,6 +1912,7 @@ void CmdFemPostFunctions::activated(int iMsg)
doCommand(Doc,"del __list__");
this->updateActive();
doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str());
}
else {
QMessageBox::warning(Gui::getMainWindow(),
@ -1671,7 +1936,7 @@ Gui::Action * CmdFemPostFunctions::createAction(void)
applyCommandData(this->className(), pcAction);
QAction* cmd0 = pcAction->addAction(QString());
//cmd0->setIcon(Gui::BitmapFactory().pixmap("Part_JoinConnect"));
pcAction->addAction(QString());
_pcAction = pcAction;
languageChange();
@ -1692,10 +1957,15 @@ void CmdFemPostFunctions::languageChange()
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());
QAction* cmd = a[0];
cmd->setText(QApplication::translate("CmdFemPostFunctions","Plane"));
cmd->setToolTip(QApplication::translate("Fem_PostCreateFunctions","Create a plane function, defined by its orgin and normal"));
cmd->setStatusTip(cmd->toolTip());
cmd = a[1];
cmd->setText(QApplication::translate("CmdFemPostFunctions","Sphere"));
cmd->setToolTip(QApplication::translate("Fem_PostCreateFunctions","Create a phere function, defined by its center and radius"));
cmd->setStatusTip(cmd->toolTip());
}
@ -1707,6 +1977,7 @@ bool CmdFemPostFunctions::isActive(void)
return false;
}
DEF_STD_CMD_AC(CmdFemPostApllyChanges);
CmdFemPostApllyChanges::CmdFemPostApllyChanges()
@ -1719,6 +1990,7 @@ CmdFemPostApllyChanges::CmdFemPostApllyChanges()
sWhatsThis = "Fem_PostApplyChanges";
sStatusTip = sToolTipText;
sPixmap = "view-refresh";
eType = eType|ForEdit;
}
void CmdFemPostApllyChanges::activated(int iMsg)
@ -1772,8 +2044,9 @@ void CreateFemCommands(void)
#ifdef FC_USE_VTK
rcCmdMgr.addCommand(new CmdFemPostCreateClipFilter);
rcCmdMgr.addCommand(new CmdFemPostCreateScalarClipFilter);
rcCmdMgr.addCommand(new CmdFemPostFunctions);
rcCmdMgr.addCommand(new CmdFemPostApllyChanges);
#endif
}
>>>>>>> Basic implementation of filter framework
>>>>>>> Detail filter infrastructure

View File

@ -0,0 +1,196 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PlaneWidget</class>
<widget class="QWidget" name="PlaneWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>287</width>
<height>84</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QFormLayout" name="formLayout">
<property name="verticalSpacing">
<number>2</number>
</property>
<property name="leftMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Origin</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number>2</number>
</property>
<item>
<widget class="QDoubleSpinBox" name="originX">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>70</width>
<height>0</height>
</size>
</property>
<property name="minimum">
<double>-999999999.000000000000000</double>
</property>
<property name="maximum">
<double>999999999.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="originY">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>70</width>
<height>0</height>
</size>
</property>
<property name="minimum">
<double>-999999999.000000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="originZ">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>70</width>
<height>0</height>
</size>
</property>
<property name="minimum">
<double>-999999999.000000000000000</double>
</property>
<property name="maximum">
<double>999999999.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Normal</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>2</number>
</property>
<item>
<widget class="QDoubleSpinBox" name="normalX">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>70</width>
<height>0</height>
</size>
</property>
<property name="minimum">
<double>-999999999.000000000000000</double>
</property>
<property name="maximum">
<double>999999999.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="normalY">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>70</width>
<height>0</height>
</size>
</property>
<property name="minimum">
<double>-999999999.000000000000000</double>
</property>
<property name="maximum">
<double>999999999.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="normalZ">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>70</width>
<height>0</height>
</size>
</property>
<property name="minimum">
<double>-999999999.000000000000000</double>
</property>
<property name="maximum">
<double>999999999.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,164 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SphereWidget</class>
<widget class="QWidget" name="SphereWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>346</width>
<height>84</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QFormLayout" name="formLayout">
<property name="verticalSpacing">
<number>2</number>
</property>
<property name="leftMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Radius</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number>2</number>
</property>
<item>
<widget class="QDoubleSpinBox" name="radius">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>70</width>
<height>0</height>
</size>
</property>
<property name="keyboardTracking">
<bool>false</bool>
</property>
<property name="minimum">
<double>-999999999.000000000000000</double>
</property>
<property name="maximum">
<double>999999999.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Center</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>2</number>
</property>
<item>
<widget class="QDoubleSpinBox" name="centerX">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>70</width>
<height>0</height>
</size>
</property>
<property name="keyboardTracking">
<bool>false</bool>
</property>
<property name="minimum">
<double>-999999999.000000000000000</double>
</property>
<property name="maximum">
<double>999999999.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="centerY">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>70</width>
<height>0</height>
</size>
</property>
<property name="keyboardTracking">
<bool>false</bool>
</property>
<property name="minimum">
<double>-999999999.000000000000000</double>
</property>
<property name="maximum">
<double>999999999.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="centerZ">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>70</width>
<height>0</height>
</size>
</property>
<property name="keyboardTracking">
<bool>false</bool>
</property>
<property name="minimum">
<double>-999999999.000000000000000</double>
</property>
<property name="maximum">
<double>999999999.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,452 @@
/***************************************************************************
* 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 "ui_TaskPostDisplay.h"
#include "ui_TaskPostClip.h"
#include "ui_TaskPostScalarClip.h"
#include "TaskPostBoxes.h"
#include "ViewProviderFemPostObject.h"
#include "ViewProviderFemPostFunction.h"
#include "ViewProviderFemPostFilter.h"
#include <Mod/Fem/App/FemPostObject.h>
#include <Mod/Fem/App/FemPostFilter.h>
#include <Mod/Fem/App/FemPostPipeline.h>
#include <Gui/BitmapFactory.h>
#include <Gui/Application.h>
#include <Gui/Document.h>
#include <Gui/Command.h>
#include <Gui/Action.h>
#include <QMessageBox>
#include <QPushButton>
using namespace FemGui;
using namespace Gui;
//**************************************************************************
//**************************************************************************
// TaskDialog
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
TaskDlgPost::TaskDlgPost(Gui::ViewProviderDocumentObject *view,bool newObj)
: TaskDialog(), m_view(view)
{
assert(view);
}
TaskDlgPost::~TaskDlgPost()
{
}
QDialogButtonBox::StandardButtons TaskDlgPost::getStandardButtons(void) const {
//check if we only have gui task boxes
bool guionly = true;
for(std::vector<TaskPostBox*>::const_iterator it = m_boxes.begin(); it != m_boxes.end(); ++it)
guionly = guionly && (*it)->isGuiTaskOnly();
if(!guionly)
return QDialogButtonBox::Apply|QDialogButtonBox::Ok|QDialogButtonBox::Cancel;
else
return QDialogButtonBox::Ok;
}
void TaskDlgPost::appendBox(TaskPostBox* box) {
m_boxes.push_back(box);
Content.push_back(box);
}
void TaskDlgPost::open()
{
// a transaction is already open at creation time of the pad
QString msg = QObject::tr("Edit post processing object");
Gui::Command::openCommand((const char*)msg.toUtf8());
}
void TaskDlgPost::clicked(int button)
{
if(button == QDialogButtonBox::Apply)
getView()->getObject()->getDocument()->recompute();
}
bool TaskDlgPost::accept()
{
try {
std::vector<TaskPostBox*>::iterator it = m_boxes.begin();
for(;it != m_boxes.end(); ++it)
(*it)->applyPythonCode();
}
catch (const Base::Exception& e) {
QMessageBox::warning(NULL, tr("Input error"), QString::fromAscii(e.what()));
return false;
}
Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()");
return true;
}
bool TaskDlgPost::reject()
{
// roll back the done things
Gui::Command::abortCommand();
Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()");
return true;
}
void TaskDlgPost::modifyStandardButtons(QDialogButtonBox* box) {
box->button(QDialogButtonBox::Apply)->setDefault(true);
}
//############################################################################################
TaskPostBox::TaskPostBox(Gui::ViewProviderDocumentObject* view, const QPixmap &icon, const QString &title, QWidget* parent)
: TaskBox(icon, title, true, parent) {
m_view = view;
m_object = view->getObject();
}
TaskPostBox::~TaskPostBox() {
}
bool TaskPostBox::autoApply() {
ParameterGrp::handle pGroup = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Fem");
return pGroup->GetBool("PostAutoRecompute", false);
}
void TaskPostBox::recompute() {
if(autoApply())
App::GetApplication().getActiveDocument()->recompute();
}
void TaskPostBox::updateEnumerationList(App::PropertyEnumeration& prop, QComboBox* box) {
box->clear();
QStringList list;
std::vector<std::string> vec = prop.getEnumVector();
for(std::vector<std::string>::iterator it = vec.begin(); it != vec.end(); ++it )
list.push_back(QString::fromStdString(*it));
box->insertItems(0, list);
box->setCurrentIndex(prop.getValue());
}
//###########################################################################################################
TaskPostDisplay::TaskPostDisplay(Gui::ViewProviderDocumentObject* view, QWidget *parent)
: TaskPostBox(view, Gui::BitmapFactory().pixmap("fem-fem-mesh-create-node-by-poly"), tr("Display options"), parent)
{
//we need a separate container widget to add all controls to
proxy = new QWidget(this);
ui = new Ui_TaskPostDisplay();
ui->setupUi(proxy);
QMetaObject::connectSlotsByName(this);
this->groupLayout()->addWidget(proxy);
//update all fields
updateEnumerationList(getTypedView<ViewProviderFemPostObject>()->DisplayMode, ui->Representation);
updateEnumerationList(getTypedView<ViewProviderFemPostObject>()->Field, ui->Field);
updateEnumerationList(getTypedView<ViewProviderFemPostObject>()->VectorMode, ui->VectorMode);
}
TaskPostDisplay::~TaskPostDisplay()
{
delete ui;
}
void TaskPostDisplay::on_Representation_activated(int i) {
getTypedView<ViewProviderFemPostObject>()->DisplayMode.setValue(i);
updateEnumerationList(getTypedView<ViewProviderFemPostObject>()->Field, ui->Field);
updateEnumerationList(getTypedView<ViewProviderFemPostObject>()->VectorMode, ui->VectorMode);
}
void TaskPostDisplay::on_Field_activated(int i) {
getTypedView<ViewProviderFemPostObject>()->Field.setValue(i);
updateEnumerationList(getTypedView<ViewProviderFemPostObject>()->VectorMode, ui->VectorMode);
}
void TaskPostDisplay::on_VectorMode_activated(int i) {
getTypedView<ViewProviderFemPostObject>()->VectorMode.setValue(i);
}
void TaskPostDisplay::on_Transparency_valueChanged(int i) {
getTypedView<ViewProviderFemPostObject>()->Transperency.setValue(i);
}
void TaskPostDisplay::applyPythonCode() {
}
//############################################################################################
TaskPostFunction::TaskPostFunction(ViewProviderDocumentObject* view, QWidget* parent): TaskPostBox(view, Gui::BitmapFactory().pixmap("fem-fem-mesh-create-node-by-poly"), tr("Implicit function"), parent) {
assert(view->isDerivedFrom(ViewProviderFemPostFunction::getClassTypeId()));
//we load the views widget
FunctionWidget* w = getTypedView<ViewProviderFemPostFunction>()->createControlWidget();
w->setParent(this);
w->setViewProvider(getTypedView<ViewProviderFemPostFunction>());
this->groupLayout()->addWidget(w);
}
TaskPostFunction::~TaskPostFunction() {
}
void TaskPostFunction::applyPythonCode() {
//we apply the views widgets python code
}
//############################################################################################
TaskPostClip::TaskPostClip(ViewProviderDocumentObject* view, App::PropertyLink* function, QWidget* parent)
: TaskPostBox(view,Gui::BitmapFactory().pixmap("fem-fem-mesh-create-node-by-poly"), tr("Choose implicit function"), parent) {
assert(view->isDerivedFrom(ViewProviderFemPostClip::getClassTypeId()));
assert(function);
fwidget = NULL;
//we load the views widget
proxy = new QWidget(this);
ui = new Ui_TaskPostClip();
ui->setupUi(proxy);
QMetaObject::connectSlotsByName(this);
this->groupLayout()->addWidget(proxy);
//the layout for the container widget
QVBoxLayout *layout = new QVBoxLayout();
ui->Container->setLayout(layout);
//fill up the combo box with possible functions
collectImplicitFunctions();
//add the function creation command
Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager();
rcCmdMgr.getCommandByName("Fem_PostCreateFunctions")->getAction()->addTo(ui->CreateButton);
ui->CreateButton->setPopupMode(QToolButton::InstantPopup);
//load the default values
ui->CutCells->setChecked(static_cast<Fem::FemPostClipFilter*>(getObject())->CutCells.getValue());
ui->InsideOut->setChecked(static_cast<Fem::FemPostClipFilter*>(getObject())->InsideOut.getValue());
}
TaskPostClip::~TaskPostClip() {
}
void TaskPostClip::applyPythonCode() {
}
void TaskPostClip::collectImplicitFunctions() {
std::vector<Fem::FemPostPipeline*> pipelines;
pipelines = App::GetApplication().getActiveDocument()->getObjectsOfType<Fem::FemPostPipeline>();
if (!pipelines.empty()) {
Fem::FemPostPipeline *pipeline = pipelines.front();
if(pipeline->Function.getValue() &&
pipeline->Function.getValue()->getTypeId() == Fem::FemPostFunctionProvider::getClassTypeId()) {
ui->FunctionBox->clear();
QStringList items;
const std::vector<App::DocumentObject*>& funcs = static_cast<Fem::FemPostFunctionProvider*>(
pipeline->Function.getValue())->Functions.getValues();
for(std::size_t i=0; i<funcs.size(); ++i)
items.push_back(QString::fromAscii(funcs[i]->getNameInDocument()));
ui->FunctionBox->addItems(items);
}
}
}
void TaskPostClip::on_CreateButton_triggered(QAction* a) {
collectImplicitFunctions();
recompute();
}
void TaskPostClip::on_FunctionBox_currentIndexChanged(int idx) {
//set the correct property
std::vector<Fem::FemPostPipeline*> pipelines;
pipelines = App::GetApplication().getActiveDocument()->getObjectsOfType<Fem::FemPostPipeline>();
if (!pipelines.empty()) {
Fem::FemPostPipeline *pipeline = pipelines.front();
if(pipeline->Function.getValue() &&
pipeline->Function.getValue()->getTypeId() == Fem::FemPostFunctionProvider::getClassTypeId()) {
const std::vector<App::DocumentObject*>& funcs = static_cast<Fem::FemPostFunctionProvider*>(
pipeline->Function.getValue())->Functions.getValues();
if(idx>=0)
static_cast<Fem::FemPostClipFilter*>(getObject())->Function.setValue(funcs[idx]);
else
static_cast<Fem::FemPostClipFilter*>(getObject())->Function.setValue(NULL);
}
}
//load the correct view
Fem::FemPostFunction* fobj = static_cast<Fem::FemPostFunction*>(
static_cast<Fem::FemPostClipFilter*>(getObject())->Function.getValue());
Gui::ViewProvider* view = NULL;
if(fobj)
view = Gui::Application::Instance->activeDocument()->getViewProvider(fobj);
if(fwidget)
fwidget->deleteLater();
if(view) {
fwidget = static_cast<FemGui::ViewProviderFemPostFunction*>(view)->createControlWidget();
fwidget->setParent(ui->Container);
fwidget->setViewProvider(static_cast<FemGui::ViewProviderFemPostFunction*>(view));
ui->Container->layout()->addWidget(fwidget);
}
recompute();
}
void TaskPostClip::on_CutCells_toggled(bool val) {
static_cast<Fem::FemPostClipFilter*>(getObject())->CutCells.setValue(val);
recompute();
}
void TaskPostClip::on_InsideOut_toggled(bool val) {
static_cast<Fem::FemPostClipFilter*>(getObject())->InsideOut.setValue(val);
recompute();
}
//############################################################################################
TaskPostScalarClip::TaskPostScalarClip(ViewProviderDocumentObject* view, QWidget* parent) :
TaskPostBox(view, Gui::BitmapFactory().pixmap("fem-fem-mesh-create-node-by-poly"), tr("Clip options"), parent) {
assert(view->isDerivedFrom(ViewProviderFemPostScalarClip::getClassTypeId()));
//we load the views widget
proxy = new QWidget(this);
ui = new Ui_TaskPostScalarClip();
ui->setupUi(proxy);
QMetaObject::connectSlotsByName(this);
this->groupLayout()->addWidget(proxy);
//load the default values
updateEnumerationList(getTypedObject<Fem::FemPostScalarClipFilter>()->Scalars, ui->Scalar);
ui->InsideOut->setChecked(static_cast<Fem::FemPostScalarClipFilter*>(getObject())->InsideOut.getValue());
App::PropertyFloatConstraint& value = static_cast<Fem::FemPostScalarClipFilter*>(getObject())->Value;
//don't forget to sync the slider
ui->Value->blockSignals(true);
ui->Value->setValue( value.getValue());
ui->Value->blockSignals(false);
//don't forget to sync the slider
ui->Value->blockSignals(true);
ui->Value->setValue( value.getConstraints()->UpperBound * (1-double(value.getValue())/100.)
+ double(value.getValue())/100.*value.getConstraints()->UpperBound);
ui->Value->blockSignals(false);
}
TaskPostScalarClip::~TaskPostScalarClip() {
}
void TaskPostScalarClip::applyPythonCode() {
}
void TaskPostScalarClip::on_Scalar_currentIndexChanged(int idx) {
static_cast<Fem::FemPostScalarClipFilter*>(getObject())->Scalars.setValue(idx);
recompute();
//update constraints and values
App::PropertyFloatConstraint& value = static_cast<Fem::FemPostScalarClipFilter*>(getObject())->Value;
ui->Maximum->setText(QString::number(value.getConstraints()->UpperBound));
ui->Minimum->setText(QString::number(value.getConstraints()->LowerBound));
//don't forget to sync the slider
ui->Value->blockSignals(true);
ui->Value->setValue( value.getValue());
ui->Value->blockSignals(false);
//don't forget to sync the slider
ui->Value->blockSignals(true);
ui->Value->setValue( value.getConstraints()->UpperBound * (1-double(value.getValue())/100.)
+ double(value.getValue())/100.*value.getConstraints()->UpperBound);
ui->Value->blockSignals(false);
}
void TaskPostScalarClip::on_Slider_valueChanged(int v) {
App::PropertyFloatConstraint& value = static_cast<Fem::FemPostScalarClipFilter*>(getObject())->Value;
double val = value.getConstraints()->LowerBound * (1-double(v)/100.) + double(v)/100.*value.getConstraints()->UpperBound;
value.setValue(val);
recompute();
//don't forget to sync the spinbox
ui->Value->blockSignals(true);
ui->Value->setValue( val );
ui->Value->blockSignals(false);
}
void TaskPostScalarClip::on_Value_valueChanged(double v) {
App::PropertyFloatConstraint& value = static_cast<Fem::FemPostScalarClipFilter*>(getObject())->Value;
value.setValue(v);
recompute();
//don't forget to sync the slider
ui->Slider->blockSignals(true);
ui->Slider->setValue(int(((v- value.getConstraints()->LowerBound)/(value.getConstraints()->UpperBound - value.getConstraints()->LowerBound))*100.));
ui->Slider->blockSignals(false);
}
void TaskPostScalarClip::on_InsideOut_toggled(bool val) {
static_cast<Fem::FemPostScalarClipFilter*>(getObject())->InsideOut.setValue(val);
recompute();
}
#include "moc_TaskPostBoxes.cpp"

View File

@ -0,0 +1,188 @@
/***************************************************************************
* 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 GUI_TASKVIEW_TaskPostDisplay_H
#define GUI_TASKVIEW_TaskPostDisplay_H
#include <Gui/TaskView/TaskView.h>
#include <Gui/TaskView/TaskDialog.h>
#include <Gui/ViewProviderDocumentObject.h>
#include <Base/Parameter.h>
#include <App/PropertyLinks.h>
#include "ViewProviderFemPostFunction.h"
class QComboBox;
class Ui_TaskPostDisplay;
class Ui_TaskPostClip;
class Ui_TaskPostScalarClip;
namespace FemGui {
class TaskPostBox : public Gui::TaskView::TaskBox {
Q_OBJECT
public:
TaskPostBox(Gui::ViewProviderDocumentObject* view, const QPixmap &icon, const QString &title, QWidget *parent = 0);
~TaskPostBox();
virtual void applyPythonCode() = 0;
virtual bool isGuiTaskOnly() {return false;}; //return true if only gui properties are manipulated
protected:
App::DocumentObject* getObject() {return m_object;};
template<typename T>
T* getTypedObject() {return static_cast<T*>(m_object);};
Gui::ViewProviderDocumentObject* getView() {return m_view;};
template<typename T>
T* getTypedView() {return static_cast<T*>(m_view);};
bool autoApply();
void recompute();
static void updateEnumerationList(App::PropertyEnumeration&, QComboBox* box);
private:
App::DocumentObject* m_object;
Gui::ViewProviderDocumentObject* m_view;
};
/// simulation dialog for the TaskView
class TaskDlgPost : public Gui::TaskView::TaskDialog
{
Q_OBJECT
public:
TaskDlgPost(Gui::ViewProviderDocumentObject *view, bool newObj=false);
~TaskDlgPost();
void appendBox(TaskPostBox* box);
Gui::ViewProviderDocumentObject* getView() const
{ return m_view; }
public:
/// is called the TaskView when the dialog is opened
virtual void open();
/// is called by the framework if an button is clicked which has no accept or reject role
virtual void clicked(int);
/// is called by the framework if the dialog is accepted (Ok)
virtual bool accept();
/// is called by the framework if the dialog is rejected (Cancel)
virtual bool reject();
/// is called by the framework if the user presses the help button
virtual bool isAllowedAlterDocument(void) const
{ return false; }
virtual void modifyStandardButtons(QDialogButtonBox*);
/// returns for Close and Help button
virtual QDialogButtonBox::StandardButtons getStandardButtons(void) const;
protected:
Gui::ViewProviderDocumentObject* m_view;
std::vector<TaskPostBox*> m_boxes;
};
class TaskPostDisplay : public TaskPostBox
{
Q_OBJECT
public:
TaskPostDisplay(Gui::ViewProviderDocumentObject* view, QWidget *parent = 0);
~TaskPostDisplay();
virtual void applyPythonCode();
virtual bool isGuiTaskOnly() {return true;};
private Q_SLOTS:
void on_Representation_activated(int i);
void on_Field_activated(int i);
void on_VectorMode_activated(int i);
void on_Transparency_valueChanged(int i);
private:
QWidget* proxy;
Ui_TaskPostDisplay* ui;
};
class TaskPostFunction : public TaskPostBox {
Q_OBJECT
public:
TaskPostFunction(Gui::ViewProviderDocumentObject* view, QWidget* parent = 0);
virtual ~TaskPostFunction();
virtual void applyPythonCode();
};
class TaskPostClip : public TaskPostBox {
Q_OBJECT
public:
TaskPostClip(Gui::ViewProviderDocumentObject* view, App::PropertyLink* function, QWidget* parent = 0);
virtual ~TaskPostClip();
virtual void applyPythonCode();
private Q_SLOTS:
void on_CreateButton_triggered(QAction* a);
void on_FunctionBox_currentIndexChanged(int idx);
void on_InsideOut_toggled(bool val);
void on_CutCells_toggled(bool val);
private:
void collectImplicitFunctions();
App::PropertyLink* m_functionProperty;
QWidget* proxy;
Ui_TaskPostClip* ui;
FunctionWidget* fwidget;
};
class TaskPostScalarClip : public TaskPostBox {
Q_OBJECT
public:
TaskPostScalarClip(Gui::ViewProviderDocumentObject* view, QWidget* parent = 0);
virtual ~TaskPostScalarClip();
virtual void applyPythonCode();
private Q_SLOTS:
void on_Slider_valueChanged(int v);
void on_Value_valueChanged(double v);
void on_Scalar_currentIndexChanged(int idx);
void on_InsideOut_toggled(bool val);
private:
QWidget* proxy;
Ui_TaskPostScalarClip* ui;
};
} //namespace FemGui
#endif // GUI_TASKVIEW_TaskPostDisplay_H

View File

@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TaskPostClip</class>
<widget class="QWidget" name="TaskPostClip">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>413</width>
<height>184</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QComboBox" name="FunctionBox"/>
</item>
<item>
<widget class="QToolButton" name="CreateButton">
<property name="text">
<string>Create</string>
</property>
<property name="icon">
<iconset resource="../../../Gui/Icons/resource.qrc">
<normaloff>:/icons/list-add.svg</normaloff>:/icons/list-add.svg</iconset>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="Container" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Ignored" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QCheckBox" name="InsideOut">
<property name="text">
<string>Inside Out</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="CutCells">
<property name="text">
<string>Cut Cells</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources>
<include location="../../../Gui/Icons/resource.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -0,0 +1,180 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TaskPostDisplay</class>
<widget class="QWidget" name="TaskPostDisplay">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>292</width>
<height>254</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Mode</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="Representation">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>Outline</string>
</property>
</item>
<item>
<property name="text">
<string>Surface</string>
</property>
</item>
<item>
<property name="text">
<string>Surface with Edges</string>
</property>
</item>
<item>
<property name="text">
<string>Wireframe</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Coloring</string>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Field</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="Field">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>Outline</string>
</property>
</item>
<item>
<property name="text">
<string>Surface</string>
</property>
</item>
<item>
<property name="text">
<string>Surface with Edges</string>
</property>
</item>
<item>
<property name="text">
<string>Wireframe</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Vector</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="VectorMode">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>Magnitute</string>
</property>
</item>
<item>
<property name="text">
<string>X</string>
</property>
</item>
<item>
<property name="text">
<string>Y</string>
</property>
</item>
<item>
<property name="text">
<string>Z</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Styling</string>
</property>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Transparency</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSlider" name="Transparency">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,215 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TaskPostScalarClip</class>
<widget class="QWidget" name="TaskPostScalarClip">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>326</width>
<height>172</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Scalar</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="Scalar">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>Outline</string>
</property>
</item>
<item>
<property name="text">
<string>Surface</string>
</property>
</item>
<item>
<property name="text">
<string>Surface with Edges</string>
</property>
</item>
<item>
<property name="text">
<string>Wireframe</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="Slider">
<property name="maximum">
<number>100</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="invertedAppearance">
<bool>false</bool>
</property>
<property name="invertedControls">
<bool>false</bool>
</property>
<property name="tickPosition">
<enum>QSlider::NoTicks</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number>20</number>
</property>
<item>
<widget class="QLineEdit" name="Minimum">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>-100000</string>
</property>
<property name="frame">
<bool>true</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="Value">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="keyboardTracking">
<bool>false</bool>
</property>
<property name="decimals">
<number>3</number>
</property>
<property name="minimum">
<double>-999999999.000000000000000</double>
</property>
<property name="maximum">
<double>999999999.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="Maximum">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>0</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QCheckBox" name="InsideOut">
<property name="text">
<string>InsideOut</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
<zorder>layoutWidget</zorder>
<zorder>minimum</zorder>
<zorder>maximum</zorder>
<zorder>Slider</zorder>
<zorder>line</zorder>
<zorder>minimum</zorder>
<zorder>maximum</zorder>
<zorder></zorder>
<zorder>InsideOut</zorder>
<zorder>horizontalSpacer</zorder>
<zorder></zorder>
<zorder>line_2</zorder>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,71 @@
/***************************************************************************
* 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 "ViewProviderFemPostFilter.h"
#include "TaskPostBoxes.h"
#include <Mod/Fem/App/FemPostFilter.h>
#include <Base/Console.h>
using namespace FemGui;
PROPERTY_SOURCE(FemGui::ViewProviderFemPostClip, FemGui::ViewProviderFemPostObject)
ViewProviderFemPostClip::ViewProviderFemPostClip() {
}
ViewProviderFemPostClip::~ViewProviderFemPostClip() {
}
void ViewProviderFemPostClip::setupTaskDialog(TaskDlgPost* dlg) {
//add the function box
dlg->appendBox(new TaskPostClip(dlg->getView(),
&static_cast<Fem::FemPostClipFilter*>(dlg->getView()->getObject())->Function));
//add the display options
FemGui::ViewProviderFemPostObject::setupTaskDialog(dlg);
}
PROPERTY_SOURCE(FemGui::ViewProviderFemPostScalarClip, FemGui::ViewProviderFemPostObject)
ViewProviderFemPostScalarClip::ViewProviderFemPostScalarClip() {
}
ViewProviderFemPostScalarClip::~ViewProviderFemPostScalarClip() {
}
void ViewProviderFemPostScalarClip::setupTaskDialog(TaskDlgPost* dlg) {
//add the function box
dlg->appendBox(new TaskPostScalarClip(dlg->getView()));
//add the display options
FemGui::ViewProviderFemPostObject::setupTaskDialog(dlg);
}

View File

@ -0,0 +1,61 @@
/***************************************************************************
* 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_VIEWPROVIDERFEMPOSTFILTER_H
#define FEM_VIEWPROVIDERFEMPOSTFILTER_H
#include "ViewProviderFemPostObject.h"
namespace FemGui
{
class FemGuiExport ViewProviderFemPostClip : public ViewProviderFemPostObject {
PROPERTY_HEADER(FemGui::ViewProviderFemPostClip);
public:
/// constructor.
ViewProviderFemPostClip();
~ViewProviderFemPostClip();
protected:
virtual void setupTaskDialog(TaskDlgPost* dlg);
};
class FemGuiExport ViewProviderFemPostScalarClip : public ViewProviderFemPostObject {
PROPERTY_HEADER(FemGui::ViewProviderFemPostScalarClip);
public:
/// constructor.
ViewProviderFemPostScalarClip();
~ViewProviderFemPostScalarClip();
protected:
virtual void setupTaskDialog(TaskDlgPost* dlg);
};
} //namespace FemGui
#endif // FEM_VIEWPROVIDERFEMPOSTFILTER_H

View File

@ -31,14 +31,21 @@
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoTransform.h>
#include <Inventor/nodes/SoMatrixTransform.h>
#include <Inventor/nodes/SoSphere.h>
#include <Inventor/manips/SoTransformManip.h>
#include <Inventor/manips/SoCenterballManip.h>
#include <Inventor/manips/SoTransformerManip.h>
#include <Inventor/manips/SoTransformBoxManip.h>
#include <Inventor/actions/SoSearchAction.h>
#include <Inventor/engines/SoDecomposeMatrix.h>
#include <Inventor/draggers/SoCenterballDragger.h>
#include <Inventor/draggers/SoTransformerDragger.h>
#include <Inventor/draggers/SoTransformBoxDragger.h>
#include <QMessageBox>
#endif
#include "ViewProviderFemPostFunction.h"
#include "TaskPostBoxes.h"
#include <Mod/Fem/App/FemPostFunction.h>
#include <Base/Console.h>
#include <Base/Interpreter.h>
@ -46,9 +53,31 @@
#include <Gui/Document.h>
#include <Gui/SoNavigationDragger.h>
#include <Gui/Macro.h>
#include <Gui/TaskView/TaskDialog.h>
#include <Gui/Control.h>
#include <App/PropertyUnits.h>
#include <boost/bind.hpp>
#include "ui_PlaneWidget.h"
#include "ui_SphereWidget.h"
using namespace FemGui;
void FunctionWidget::setViewProvider(ViewProviderFemPostFunction* view) {
m_view = view;
m_object = static_cast<Fem::FemPostFunction*>(view->getObject());
m_connection = m_object->getDocument()->signalChangedObject.connect(boost::bind(&FunctionWidget::onObjectsChanged, this, _1, _2));
}
void FunctionWidget::onObjectsChanged(const App::DocumentObject& obj, const App::Property& p) {
if(&obj == m_object)
onChange(p);
}
PROPERTY_SOURCE(FemGui::ViewProviderFemPostFunctionProvider, Gui::ViewProviderDocumentObject)
ViewProviderFemPostFunctionProvider::ViewProviderFemPostFunctionProvider() {
@ -141,6 +170,12 @@ void ViewProviderFemPostFunction::attach(App::DocumentObject *pcObj)
setDisplayMaskMode("Default");
}
bool ViewProviderFemPostFunction::doubleClicked(void) {
Gui::Application::Instance->activeDocument()->setEdit(this, (int)ViewProvider::Default);
return true;
}
SoTransformManip* ViewProviderFemPostFunction::setupManipulator() {
return new SoCenterballManip;
@ -187,6 +222,58 @@ void ViewProviderFemPostFunction::dragMotionCallback(void *data, SoDragger *drag
that->getObject()->getDocument()->recompute();
}
bool ViewProviderFemPostFunction::setEdit(int ModNum) {
if (ModNum == ViewProvider::Default || ModNum == 1 ) {
Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog();
TaskDlgPost *postDlg = qobject_cast<TaskDlgPost*>(dlg);
if (postDlg && postDlg->getView() != this)
postDlg = 0; // another pad left open its task panel
if (dlg && !postDlg) {
QMessageBox msgBox;
msgBox.setText(QObject::tr("A dialog is already open in the task panel"));
msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?"));
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
msgBox.setDefaultButton(QMessageBox::Yes);
int ret = msgBox.exec();
if (ret == QMessageBox::Yes)
Gui::Control().reject();
else
return false;
}
// start the edit dialog
if (postDlg)
Gui::Control().showDialog(postDlg);
else {
postDlg = new TaskDlgPost(this);
postDlg->appendBox(new TaskPostFunction(this));
Gui::Control().showDialog(postDlg);
}
return true;
}
else {
return ViewProviderDocumentObject::setEdit(ModNum);
}
}
void ViewProviderFemPostFunction::unsetEdit(int ModNum) {
if (ModNum == ViewProvider::Default) {
// when pressing ESC make sure to close the dialog
Gui::Control().closeDialog();
}
else {
ViewProviderDocumentObject::unsetEdit(ModNum);
}
}
//#################################################################################################
PROPERTY_SOURCE(FemGui::ViewProviderFemPostPlaneFunction, FemGui::ViewProviderFemPostFunction)
ViewProviderFemPostPlaneFunction::ViewProviderFemPostPlaneFunction() {
@ -244,3 +331,199 @@ void ViewProviderFemPostPlaneFunction::updateData(const App::Property* p) {
Gui::ViewProviderDocumentObject::updateData(p);
}
FunctionWidget* ViewProviderFemPostPlaneFunction::createControlWidget() {
return new PlaneWidget();
}
PlaneWidget::PlaneWidget() {
ui = new Ui_PlaneWidget();
ui->setupUi(this);
connect(ui->originX, SIGNAL(valueChanged(double)), this, SLOT(originChanged(double)));
connect(ui->originY, SIGNAL(valueChanged(double)), this, SLOT(originChanged(double)));
connect(ui->originZ, SIGNAL(valueChanged(double)), this, SLOT(originChanged(double)));
connect(ui->normalX, SIGNAL(valueChanged(double)), this, SLOT(normalChanged(double)));
connect(ui->normalY, SIGNAL(valueChanged(double)), this, SLOT(normalChanged(double)));
connect(ui->normalZ, SIGNAL(valueChanged(double)), this, SLOT(normalChanged(double)));
}
PlaneWidget::~PlaneWidget() {
}
void PlaneWidget::applyPythonCode() {
}
void PlaneWidget::setViewProvider(ViewProviderFemPostFunction* view) {
FemGui::FunctionWidget::setViewProvider(view);
onChange(static_cast<Fem::FemPostPlaneFunction*>(getObject())->Normal);
onChange(static_cast<Fem::FemPostPlaneFunction*>(getObject())->Origin);
}
void PlaneWidget::onChange(const App::Property& p) {
setBlockObjectUpdates(true);
if(strcmp(p.getName(), "Normal") == 0) {
const Base::Vector3d& vec = static_cast<const App::PropertyVector*>(&p)->getValue();
ui->normalX->setValue(vec.x);
ui->normalY->setValue(vec.y);
ui->normalZ->setValue(vec.z);
}
else if(strcmp(p.getName(), "Origin") == 0) {
const Base::Vector3d& vec = static_cast<const App::PropertyVectorDistance*>(&p)->getValue();
ui->originX->setValue(vec.x);
ui->originY->setValue(vec.y);
ui->originZ->setValue(vec.z);
}
setBlockObjectUpdates(false);
}
void PlaneWidget::normalChanged(double val) {
if(!blockObjectUpdates()) {
Base::Vector3d vec(ui->normalX->value(), ui->normalY->value(), ui->normalZ->value());
static_cast<Fem::FemPostPlaneFunction*>(getObject())->Normal.setValue(vec);
}
}
void PlaneWidget::originChanged(double val) {
if(!blockObjectUpdates()) {
Base::Vector3d vec(ui->originX->value(), ui->originY->value(), ui->originZ->value());
static_cast<Fem::FemPostPlaneFunction*>(getObject())->Origin.setValue(vec);
}
}
//#################################################################################################
PROPERTY_SOURCE(FemGui::ViewProviderFemPostSphereFunction, FemGui::ViewProviderFemPostFunction)
ViewProviderFemPostSphereFunction::ViewProviderFemPostSphereFunction() {
setAutoScale(true);
//setup the visualisation geometry
m_sphereNode = new SoSphere;
m_sphereNode->ref();
getGeometryNode()->addChild(m_sphereNode);
}
ViewProviderFemPostSphereFunction::~ViewProviderFemPostSphereFunction() {
m_sphereNode->unref();
}
SoTransformManip* ViewProviderFemPostSphereFunction::setupManipulator() {
return new SoTransformBoxManip();
}
void ViewProviderFemPostSphereFunction::draggerUpdate(SoDragger* m) {
Base::Console().Message("dragger udate\n");
Fem::FemPostSphereFunction* func = static_cast<Fem::FemPostSphereFunction*>(getObject());
SoTransformBoxDragger* dragger = static_cast<SoTransformBoxDragger*>(m);
// the new axis of the plane
SbRotation rot, scaleDir;
const SbVec3f& center = dragger->translation.getValue();
SbVec3f norm(0,0,1);
dragger->rotation.getValue().multVec(norm,norm);
func->Center.setValue(center[0], center[1], center[2]);
func->Radius.setValue(dragger->scaleFactor.getValue()[0]);
}
void ViewProviderFemPostSphereFunction::updateData(const App::Property* p) {
/*
Fem::FemPostSphereFunction* func = static_cast<Fem::FemPostSphereFunction*>(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);*/
}
FunctionWidget* ViewProviderFemPostSphereFunction::createControlWidget() {
return new SphereWidget();
}
SphereWidget::SphereWidget() {
ui = new Ui_SphereWidget();
ui->setupUi(this);
connect(ui->centerX, SIGNAL(valueChanged(double)), this, SLOT(centerChanged(double)));
connect(ui->centerY, SIGNAL(valueChanged(double)), this, SLOT(centerChanged(double)));
connect(ui->centerZ, SIGNAL(valueChanged(double)), this, SLOT(centerChanged(double)));
connect(ui->radius, SIGNAL(valueChanged(double)), this, SLOT(radiusChanged(double)));
}
SphereWidget::~SphereWidget() {
}
void SphereWidget::applyPythonCode() {
}
void SphereWidget::setViewProvider(ViewProviderFemPostFunction* view) {
FemGui::FunctionWidget::setViewProvider(view);
onChange(static_cast<Fem::FemPostSphereFunction*>(getObject())->Center);
onChange(static_cast<Fem::FemPostSphereFunction*>(getObject())->Radius);
}
void SphereWidget::onChange(const App::Property& p) {
setBlockObjectUpdates(true);
if(strcmp(p.getName(), "Radius") == 0) {
double val = static_cast<const App::PropertyDistance*>(&p)->getValue();
ui->radius->setValue(val);
}
else if(strcmp(p.getName(), "Center") == 0) {
const Base::Vector3d& vec = static_cast<const App::PropertyVectorDistance*>(&p)->getValue();
ui->centerX->setValue(vec.x);
ui->centerY->setValue(vec.y);
ui->centerZ->setValue(vec.z);
}
setBlockObjectUpdates(false);
}
void SphereWidget::centerChanged(double val) {
if(!blockObjectUpdates()) {
Base::Vector3d vec(ui->centerX->value(), ui->centerY->value(), ui->centerZ->value());
static_cast<Fem::FemPostSphereFunction*>(getObject())->Center.setValue(vec);
}
}
void SphereWidget::radiusChanged(double val) {
if(!blockObjectUpdates()) {
static_cast<Fem::FemPostSphereFunction*>(getObject())->Radius.setValue(ui->radius->value());
}
}
#include "moc_ViewProviderFemPostFunction.cpp"

View File

@ -25,7 +25,31 @@
#define FEM_VIEWPROVIDERFEMPOSTFUNCTION_H
#include <Gui/ViewProviderDocumentObject.h>
#include <Mod/Fem/App/FemPostFunction.h>
#include <Inventor/SbMatrix.h>
#include <QWidget>
#if defined(signals) && defined(QOBJECTDEFS_H) && \
!defined(QT_MOC_CPP)
# undef signals
# define signals signals
#endif
#include <boost/signal.hpp>
namespace boost
{
namespace signalslib = signals;
}
#if defined(signals) && defined(QOBJECTDEFS_H) && \
!defined(QT_MOC_CPP)
# undef signals
// Restore the macro definition of "signals", as it was
// defined by Qt's <qobjectdefs.h>.
# define signals protected
#endif
class SoScale;
class SoSurroundScale;
@ -33,9 +57,41 @@ class SoTransformManip;
class SoComposeMatrix;
class SoMatrixTransform;
class SoDragger;
class SoSphere;
class Ui_PlaneWidget;
class Ui_SphereWidget;
namespace FemGui
{
class ViewProviderFemPostFunction;
class FemGuiExport FunctionWidget : public QWidget {
Q_OBJECT
public:
FunctionWidget() {};
virtual ~FunctionWidget() {};
virtual void applyPythonCode() = 0;
virtual void setViewProvider(ViewProviderFemPostFunction* view);
void onObjectsChanged(const App::DocumentObject& obj, const App::Property&);
protected:
ViewProviderFemPostFunction* getView() {return m_view;};
Fem::FemPostFunction* getObject(){return m_object;};
bool blockObjectUpdates() {return m_block;};
void setBlockObjectUpdates(bool val) {m_block = val;};
virtual void onChange(const App::Property& p) = 0;
private:
bool m_block;
ViewProviderFemPostFunction* m_view;
Fem::FemPostFunction* m_object;
boost::signalslib::scoped_connection m_connection;
};
class FemGuiExport ViewProviderFemPostFunctionProvider : public Gui::ViewProviderDocumentObject
{
@ -59,9 +115,17 @@ public:
~ViewProviderFemPostFunction();
void attach(App::DocumentObject *pcObject);
bool doubleClicked(void);
std::vector<std::string> getDisplayModes() const;
//creates the widget used in the task dalogs, either for the function itself or for
//the fiter using it
virtual FunctionWidget* createControlWidget() {return NULL;};
protected:
virtual bool setEdit(int ModNum);
virtual void unsetEdit(int ModNum);
void setAutoScale(bool value) {m_autoscale = value;};
bool autoScale() {return m_autoscale;};
@ -83,6 +147,27 @@ private:
bool m_autoscale, m_isDragging, m_autoRecompute;
};
//###############################################################################################
class FemGuiExport PlaneWidget : public FunctionWidget {
Q_OBJECT
public:
PlaneWidget();
virtual ~PlaneWidget();
virtual void applyPythonCode();
virtual void onChange(const App::Property& p);
virtual void setViewProvider(ViewProviderFemPostFunction* view);
private Q_SLOTS:
void originChanged(double val);
void normalChanged(double val);
private:
Ui_PlaneWidget* ui;
};
class FemGuiExport ViewProviderFemPostPlaneFunction : public ViewProviderFemPostFunction {
PROPERTY_HEADER(FemGui::ViewProviderFemPostPlaneFunction);
@ -91,11 +176,53 @@ public:
ViewProviderFemPostPlaneFunction();
virtual ~ViewProviderFemPostPlaneFunction();
virtual FunctionWidget* createControlWidget();
protected:
virtual void draggerUpdate(SoDragger* mat);
virtual void updateData(const App::Property*);
};
//###############################################################################################
class FemGuiExport SphereWidget : public FunctionWidget {
Q_OBJECT
public:
SphereWidget();
virtual ~SphereWidget();
virtual void applyPythonCode();
virtual void onChange(const App::Property& p);
virtual void setViewProvider(ViewProviderFemPostFunction* view);
private Q_SLOTS:
void centerChanged(double val);
void radiusChanged(double val);
private:
Ui_SphereWidget* ui;
};
class FemGuiExport ViewProviderFemPostSphereFunction : public ViewProviderFemPostFunction {
PROPERTY_HEADER(FemGui::ViewProviderFemPostSphereFunction);
public:
ViewProviderFemPostSphereFunction();
virtual ~ViewProviderFemPostSphereFunction();
virtual SoTransformManip* setupManipulator();
virtual FunctionWidget* createControlWidget();
protected:
virtual void draggerUpdate(SoDragger* mat);
virtual void updateData(const App::Property*);
private:
SoSphere* m_sphereNode;
};
} //namespace FemGui

View File

@ -39,13 +39,19 @@
#endif
#include "ViewProviderFemPostObject.h"
#include "TaskPostBoxes.h"
#include <Mod/Fem/App/FemPostObject.h>
#include <Base/Console.h>
#include <Gui/TaskView/TaskDialog.h>
#include <Gui/Control.h>
#include <Gui/Application.h>
#include <Gui/Document.h>
#include <vtkPointData.h>
#include <vtkCellArray.h>
#include <vtkCellData.h>
#include <vtkLookupTable.h>
#include <QMessageBox>
using namespace FemGui;
@ -55,14 +61,10 @@ PROPERTY_SOURCE(FemGui::ViewProviderFemPostObject, Gui::ViewProviderDocumentObje
ViewProviderFemPostObject::ViewProviderFemPostObject() : m_blockPropertyChanges(false)
{
//initialize the properties
ADD_PROPERTY(Coloring,((long)0));
ADD_PROPERTY_TYPE(Field,((long)0), "Coloring", App::Prop_None, "Select the field used for calculating the color");
ADD_PROPERTY_TYPE(VectorMode,((long)0), "Coloring", App::Prop_None, "Select what to show for a vector field");
ADD_PROPERTY(Transperency, (0));
m_transperencyConstraint.StepSize = 1;
m_transperencyConstraint.LowerBound = 0;
m_transperencyConstraint.UpperBound = 100;
Transperency.setConstraints(&m_transperencyConstraint);
sPixmap = "fem-fem-mesh-from-shape";
//create the subnodes which do the visualization work
@ -177,15 +179,20 @@ void ViewProviderFemPostObject::update() {
if(!setupPipeline())
return;
m_currentAlgorithm->Update();
vtkPolyData* poly = m_currentAlgorithm->GetOutput();
m_currentAlgorithm->Update();
updateProperties();
update3D();
}
void ViewProviderFemPostObject::updateProperties() {
//update the coloring property
m_blockPropertyChanges = true;
vtkPolyData* poly = m_currentAlgorithm->GetOutput();
//coloring
std::string val;
if(Coloring.getEnums() && Coloring.getValue() >= 0)
val = Coloring.getValueAsString();
if(Field.getEnums() && Field.getValue() >= 0)
val = Field.getValueAsString();
std::vector<std::string> colorArrays;
colorArrays.push_back("None");
@ -199,23 +206,52 @@ void ViewProviderFemPostObject::update() {
colorArrays.push_back(cell->GetArrayName(i));
App::Enumeration empty;
Coloring.setValue(empty);
Field.setValue(empty);
m_coloringEnum.setEnums(colorArrays);
Coloring.setValue(m_coloringEnum);
Field.setValue(m_coloringEnum);
std::vector<std::string>::iterator it = std::find(colorArrays.begin(), colorArrays.end(), val);
if(!val.empty() && it != colorArrays.end())
Coloring.setValue(val.c_str());
Field.setValue(val.c_str());
Coloring.purgeTouched();
Field.purgeTouched();
//Vector mode
if(VectorMode.getEnums() && VectorMode.getValue() >= 0)
val = VectorMode.getValueAsString();
colorArrays.clear();
if(Field.getValue() == 0)
colorArrays.push_back("Not a vector");
else {
int array = Field.getValue() - 1; //0 is none
vtkPolyData* pd = m_currentAlgorithm->GetOutput();
vtkDataArray* data = pd->GetPointData()->GetArray(array);
if(data->GetNumberOfComponents() == 1)
colorArrays.push_back("Not a vector");
else {
colorArrays.push_back("Magnitude");
if(data->GetNumberOfComponents() >= 2) {
colorArrays.push_back("X");
colorArrays.push_back("Y");
}
if(data->GetNumberOfComponents() >= 3)
colorArrays.push_back("Z");
}
}
VectorMode.setValue(empty);
m_vectorEnum.setEnums(colorArrays);
VectorMode.setValue(m_vectorEnum);
it = std::find(colorArrays.begin(), colorArrays.end(), val);
if(!val.empty() && it != colorArrays.end())
VectorMode.setValue(val.c_str());
m_blockPropertyChanges = false;
//update the visualization
update3D();
}
void ViewProviderFemPostObject::update3D() {
if(!setupPipeline())
@ -343,11 +379,11 @@ void ViewProviderFemPostObject::WritePointData(vtkPoints* points, vtkDataArray*
Base::Console().Message("\n");
m_coordinates->point.startEditing();
m_coordinates->point.setNum(points->GetNumberOfPoints());
for (i = 0; i < points->GetNumberOfPoints(); i++) {
p = points->GetPoint(i);
m_coordinates->point.set1Value(i, p[0], p[1], p[2]);
}
m_coordinates->point.setNum(points->GetNumberOfPoints());
m_coordinates->point.finishEditing();
// write out the point normal data
@ -355,11 +391,11 @@ void ViewProviderFemPostObject::WritePointData(vtkPoints* points, vtkDataArray*
Base::Console().Message("Write normals: %i\n", normals->GetNumberOfTuples());
m_normals->vector.startEditing();
m_normals->vector.setNum(normals->GetNumberOfTuples());
for (i = 0; i < normals->GetNumberOfTuples(); i++) {
p = normals->GetTuple(i);
m_normals->vector.set1Value(i, SbVec3f(p[0], p[1], p[2]));
}
m_normals->vector.setNum(normals->GetNumberOfTuples());
m_normals->vector.finishEditing();
m_normalBinding->value = SoNormalBinding::PER_VERTEX_INDEXED;
@ -372,7 +408,7 @@ void ViewProviderFemPostObject::WriteColorData() {
if(!setupPipeline())
return;
if(Coloring.getEnumVector().empty() || Coloring.getValue() == 0) {
if(Field.getEnumVector().empty() || Field.getValue() == 0) {
m_material->diffuseColor.setValue(SbColor(0.8,0.8,0.8));
m_material->transparency.setValue(0.);
@ -382,13 +418,17 @@ void ViewProviderFemPostObject::WriteColorData() {
};
int array = Coloring.getValue() - 1; //0 is none
int array = Field.getValue() - 1; //0 is none
vtkPolyData* pd = m_currentAlgorithm->GetOutput();
vtkDataArray* data = pd->GetPointData()->GetArray(array);
int component = VectorMode.getValue() - 1; //0 is either "Not a vector" or magnitude, for -1 is correct for magnitude. x y and z are one number too high
if(strcmp(VectorMode.getValueAsString(), "Not a vector")==0)
component = 0;
//build the lookuptable
double range[2];
data->GetRange(range, 0);
data->GetRange(range, component);
m_lookup->SetTableRange(range[0], range[1]);
m_lookup->SetScaleToLinear();
m_lookup->Build();
@ -397,7 +437,15 @@ void ViewProviderFemPostObject::WriteColorData() {
for (int i = 0; i < pd->GetNumberOfPoints(); i++) {
double value = data->GetComponent(i, 0);
double value = 0;
if(component >= 0)
value = data->GetComponent(i, component);
else {
for(int j=0; j<data->GetNumberOfComponents(); ++j)
value += std::pow(data->GetComponent(i, j),2);
value = std::sqrt(value);
}
double c[3];
m_lookup->GetColor(value, c);
m_material->diffuseColor.set1Value(i, c[0], c[1], c[2]);
@ -465,12 +513,81 @@ void ViewProviderFemPostObject::onChanged(const App::Property* prop) {
return;
Base::Console().Message("On Changed: %s\n", prop->getName());
if(prop == &Coloring && setupPipeline()) {
if(prop == &Field && setupPipeline()) {
updateProperties();
WriteColorData();
WriteTransperency();
}
else if(prop == &VectorMode && setupPipeline()) {
WriteColorData();
WriteTransperency();
}
else if(prop == &Transperency) {
WriteTransperency();
}
ViewProviderDocumentObject::onChanged(prop);
}
bool ViewProviderFemPostObject::doubleClicked(void) {
Gui::Application::Instance->activeDocument()->setEdit(this, (int)ViewProvider::Default);
return true;
}
bool ViewProviderFemPostObject::setEdit(int ModNum) {
if (ModNum == ViewProvider::Default || ModNum == 1 ) {
Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog();
TaskDlgPost *postDlg = qobject_cast<TaskDlgPost*>(dlg);
if (postDlg && postDlg->getView() != this)
postDlg = 0; // another pad left open its task panel
if (dlg && !postDlg) {
QMessageBox msgBox;
msgBox.setText(QObject::tr("A dialog is already open in the task panel"));
msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?"));
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
msgBox.setDefaultButton(QMessageBox::Yes);
int ret = msgBox.exec();
if (ret == QMessageBox::Yes)
Gui::Control().reject();
else
return false;
}
// start the edit dialog
if (postDlg)
Gui::Control().showDialog(postDlg);
else {
postDlg = new TaskDlgPost(this);
setupTaskDialog(postDlg);
Gui::Control().showDialog(postDlg);
}
return true;
}
else {
return ViewProviderDocumentObject::setEdit(ModNum);
}
}
void ViewProviderFemPostObject::setupTaskDialog(TaskDlgPost* dlg) {
dlg->appendBox(new TaskPostDisplay(this));
}
void ViewProviderFemPostObject::unsetEdit(int ModNum) {
if (ModNum == ViewProvider::Default) {
// and update the pad
//getSketchObject()->getDocument()->recompute();
// when pressing ESC make sure to close the dialog
Gui::Control().closeDialog();
}
else {
ViewProviderDocumentObject::unsetEdit(ModNum);
}
}

View File

@ -58,6 +58,8 @@ class SoIndexedTriangleStripSet;
namespace FemGui
{
class TaskDlgPost;
class FemGuiExport ViewProviderFemPostObject : public Gui::ViewProviderDocumentObject
{
PROPERTY_HEADER(FemGui::ViewProviderFemPostObject);
@ -69,8 +71,9 @@ public:
/// destructor.
~ViewProviderFemPostObject();
App::PropertyEnumeration Coloring;
App::PropertyIntegerConstraint Transperency;
App::PropertyEnumeration Field;
App::PropertyEnumeration VectorMode;
App::PropertyPercent Transperency;
void attach(App::DocumentObject *pcObject);
void setDisplayMode(const char* ModeName);
@ -78,6 +81,11 @@ public:
void updateData(const App::Property*);
void onChanged(const App::Property* prop);
//edit handling
virtual bool doubleClicked(void);
virtual bool setEdit(int ModNum);
virtual void unsetEdit(int ModNum);
/** @name Selection handling
* This group of methodes do the selection handling.
* Here you can define how the selection for your ViewProvider
@ -94,6 +102,7 @@ public:
// //@}
protected:
virtual void setupTaskDialog(TaskDlgPost* dlg);
bool setupPipeline();
void update();
@ -118,14 +127,14 @@ protected:
vtkSmartPointer<vtkLookupTable> m_lookup;
private:
void updateProperties();
void update3D();
void WritePointData(vtkPoints *points, vtkDataArray *normals,
vtkDataArray *tcoords);
void WriteColorData();
void WriteTransperency();
App::Enumeration m_coloringEnum;
App::PropertyIntegerConstraint::Constraints m_transperencyConstraint;
App::Enumeration m_coloringEnum, m_vectorEnum;
bool m_blockPropertyChanges;
};

View File

@ -83,7 +83,10 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
Gui::ToolBarItem* post = new Gui::ToolBarItem(root);
post->setCommand("Post Processing");
*post << "Fem_PostApplyChanges"
<< "Separator"
<< "Fem_PostCreateClipFilter"
<< "Fem_PostCreateScalarClipFilter"
<< "Separator"
<< "Fem_PostCreateFunctions";
#endif