diff --git a/src/Mod/Fem/App/AppFem.cpp b/src/Mod/Fem/App/AppFem.cpp
index 2ce88a60c..a6fe0ccbc 100644
--- a/src/Mod/Fem/App/AppFem.cpp
+++ b/src/Mod/Fem/App/AppFem.cpp
@@ -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
}
diff --git a/src/Mod/Fem/App/AppFem.cpp.orig b/src/Mod/Fem/App/AppFem.cpp.orig
index b247959bc..4292d473a 100644
--- a/src/Mod/Fem/App/AppFem.cpp.orig
+++ b/src/Mod/Fem/App/AppFem.cpp.orig
@@ -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
diff --git a/src/Mod/Fem/App/FemPostFilter.cpp b/src/Mod/Fem/App/FemPostFilter.cpp
index 7950009e8..92d5492df 100644
--- a/src/Mod/Fem/App/FemPostFilter.cpp
+++ b/src/Mod/Fem/App/FemPostFilter.cpp
@@ -30,6 +30,8 @@
#include "FemPostPipeline.h"
#include
#include
+#include
+#include
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 array;
+
+ vtkDataObject* data;
+ if(hasInputAlgorithmConnected()) {
+ getConnectedInputAlgorithm()->Update();
+ data = getConnectedInputAlgorithm()->GetOutputDataObject(0);
+ }
+ else
+ data = getConnectedInputData();
+
+ vtkDataSet* dset = dynamic_cast(data);
+ if(!dset)
+ return StdReturn;
+
+ vtkPointData* pd = dset->GetPointData();
+
+ for(int i=0; iGetNumberOfArrays(); ++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::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(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.;
+}
+
+
diff --git a/src/Mod/Fem/App/FemPostFilter.h b/src/Mod/Fem/App/FemPostFilter.h
index 8b2e7e939..5bd209067 100644
--- a/src/Mod/Fem/App/FemPostFilter.h
+++ b/src/Mod/Fem/App/FemPostFilter.h
@@ -25,9 +25,10 @@
#define Fem_FemPostFilter_H
#include "FemPostObject.h"
+#include
#include
-#include
+#include
#include
#include
#include
@@ -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 m_clipper;
+ vtkSmartPointer m_clipper;
vtkSmartPointer 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 m_clipper;
+ App::Enumeration m_scalarFields;
+ App::PropertyFloatConstraint::Constraints m_constraints;
+};
+
} //namespace Fem
diff --git a/src/Mod/Fem/App/FemPostFunction.cpp b/src/Mod/Fem/App/FemPostFunction.cpp
index d1172eacd..1c7749209 100644
--- a/src/Mod/Fem/App/FemPostFunction.cpp
+++ b/src/Mod/Fem/App/FemPostFunction.cpp
@@ -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);
+}
diff --git a/src/Mod/Fem/App/FemPostFunction.h b/src/Mod/Fem/App/FemPostFunction.h
index 81e90fed0..58f3a232e 100644
--- a/src/Mod/Fem/App/FemPostFunction.h
+++ b/src/Mod/Fem/App/FemPostFunction.h
@@ -25,11 +25,12 @@
#define Fem_FemPostFunction_H
#include "FemPostObject.h"
+#include
#include
#include
#include
-#include
+#include
namespace Fem
{
@@ -103,6 +104,30 @@ protected:
vtkSmartPointer 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 m_sphere;
+};
+
} //namespace Fem
diff --git a/src/Mod/Fem/App/FemPostPipeline.cpp b/src/Mod/Fem/App/FemPostPipeline.cpp
index 608f6fc69..dc5c2ff8c 100644
--- a/src/Mod/Fem/App/FemPostPipeline.cpp
+++ b/src/Mod/Fem/App/FemPostPipeline.cpp
@@ -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 objs = Filter.getValues();
+
+ if(objs.empty())
+ return;
+
std::vector::iterator it = objs.begin();
FemPostFilter* filter = static_cast(*it);
diff --git a/src/Mod/Fem/Gui/AppFemGui.cpp b/src/Mod/Fem/Gui/AppFemGui.cpp
index 1b8340587..34832cc6c 100644
--- a/src/Mod/Fem/Gui/AppFemGui.cpp
+++ b/src/Mod/Fem/Gui/AppFemGui.cpp
@@ -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
diff --git a/src/Mod/Fem/Gui/CMakeLists.txt b/src/Mod/Fem/Gui/CMakeLists.txt
index 9d4d9b9f7..fcb10dabc 100755
--- a/src/Mod/Fem/Gui/CMakeLists.txt
+++ b/src/Mod/Fem/Gui/CMakeLists.txt
@@ -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)
diff --git a/src/Mod/Fem/Gui/Command.cpp b/src/Mod/Fem/Gui/Command.cpp
index e5fae8ca8..9a53ad21c 100644
--- a/src/Mod/Fem/Gui/Command.cpp
+++ b/src/Mod/Fem/Gui/Command.cpp
@@ -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(ObjectFilter.Result[0][0].getObject());
+ std::vector pipelines = App::GetApplication().getActiveDocument()->getObjectsOfType();
+ 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 pipelines = App::GetApplication().getActiveDocument()->getObjectsOfType();
+ 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(ObjectFilter.Result[0][0].getObject());
+ std::vector pipelines = App::GetApplication().getActiveDocument()->getObjectsOfType();
+ 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(_pcAction);
QList 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
diff --git a/src/Mod/Fem/Gui/Command.cpp.orig b/src/Mod/Fem/Gui/Command.cpp.orig
index e891aab6d..ee2618df2 100644
--- a/src/Mod/Fem/Gui/Command.cpp.orig
+++ b/src/Mod/Fem/Gui/Command.cpp.orig
@@ -1,4 +1,4 @@
-<<<<<<< eec6f7aee8b6e5979a799358e2ae69bdc5a7af5b
+<<<<<<< 387862dfe753cf0cb062032e97840353b14dcbae
/***************************************************************************
* Copyright (c) 2008 Jürgen Riegel (juergen.riegel@web.de) *
* *
@@ -27,6 +27,7 @@
# include
# include
# include
+#include
#endif
#include
@@ -48,6 +49,7 @@
#include
#include
#include
+#include
#include
#include
@@ -59,9 +61,12 @@
#include
#include
#include
-
#include "ActiveAnalysisObserver.h"
+#ifdef FC_USE_VTK
+#include
+#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(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(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(getDocument()->getObject(FuncName.c_str()));
+ }
+ else
+ provider = static_cast(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(_pcAction);
+ QList 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(_pcAction);
+ QList 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(ObjectFilter.Result[0][0].getObject());
+ std::vector pipelines = App::GetApplication().getActiveDocument()->getObjectsOfType();
+ 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 pipelines = App::GetApplication().getActiveDocument()->getObjectsOfType();
+ 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(ObjectFilter.Result[0][0].getObject());
+ std::vector pipelines = App::GetApplication().getActiveDocument()->getObjectsOfType();
+ 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(_pcAction);
QList 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
diff --git a/src/Mod/Fem/Gui/PlaneWidget.ui b/src/Mod/Fem/Gui/PlaneWidget.ui
new file mode 100644
index 000000000..c150cfb5c
--- /dev/null
+++ b/src/Mod/Fem/Gui/PlaneWidget.ui
@@ -0,0 +1,196 @@
+
+
+ PlaneWidget
+
+
+
+ 0
+ 0
+ 287
+ 84
+
+
+
+ Form
+
+
+
+ 2
+
+
+ 6
+
+
+ 0
+
+ -
+
+
+ Origin
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ 2
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 70
+ 0
+
+
+
+ -999999999.000000000000000
+
+
+ 999999999.000000000000000
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 70
+ 0
+
+
+
+ -999999999.000000000000000
+
+
+ 0.000000000000000
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 70
+ 0
+
+
+
+ -999999999.000000000000000
+
+
+ 999999999.000000000000000
+
+
+
+
+
+ -
+
+
+ Normal
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ 2
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 70
+ 0
+
+
+
+ -999999999.000000000000000
+
+
+ 999999999.000000000000000
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 70
+ 0
+
+
+
+ -999999999.000000000000000
+
+
+ 999999999.000000000000000
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 70
+ 0
+
+
+
+ -999999999.000000000000000
+
+
+ 999999999.000000000000000
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Mod/Fem/Gui/SphereWidget.ui b/src/Mod/Fem/Gui/SphereWidget.ui
new file mode 100644
index 000000000..1c559ff4d
--- /dev/null
+++ b/src/Mod/Fem/Gui/SphereWidget.ui
@@ -0,0 +1,164 @@
+
+
+ SphereWidget
+
+
+
+ 0
+ 0
+ 346
+ 84
+
+
+
+ Form
+
+
+
+ 2
+
+
+ 6
+
+
+ 0
+
+ -
+
+
+ Radius
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ 2
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 70
+ 0
+
+
+
+ false
+
+
+ -999999999.000000000000000
+
+
+ 999999999.000000000000000
+
+
+
+
+
+ -
+
+
+ Center
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ 2
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 70
+ 0
+
+
+
+ false
+
+
+ -999999999.000000000000000
+
+
+ 999999999.000000000000000
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 70
+ 0
+
+
+
+ false
+
+
+ -999999999.000000000000000
+
+
+ 999999999.000000000000000
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 70
+ 0
+
+
+
+ false
+
+
+ -999999999.000000000000000
+
+
+ 999999999.000000000000000
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Mod/Fem/Gui/TaskPostBoxes.cpp b/src/Mod/Fem/Gui/TaskPostBoxes.cpp
new file mode 100644
index 000000000..91ae9fc6a
--- /dev/null
+++ b/src/Mod/Fem/Gui/TaskPostBoxes.cpp
@@ -0,0 +1,452 @@
+/***************************************************************************
+ * Copyright (c) 2015 Stefan Tröger *
+ * *
+ * 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
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+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::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::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 vec = prop.getEnumVector();
+ for(std::vector::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()->DisplayMode, ui->Representation);
+ updateEnumerationList(getTypedView()->Field, ui->Field);
+ updateEnumerationList(getTypedView()->VectorMode, ui->VectorMode);
+}
+
+TaskPostDisplay::~TaskPostDisplay()
+{
+ delete ui;
+}
+
+void TaskPostDisplay::on_Representation_activated(int i) {
+
+ getTypedView()->DisplayMode.setValue(i);
+ updateEnumerationList(getTypedView()->Field, ui->Field);
+ updateEnumerationList(getTypedView()->VectorMode, ui->VectorMode);
+}
+
+void TaskPostDisplay::on_Field_activated(int i) {
+
+ getTypedView()->Field.setValue(i);
+ updateEnumerationList(getTypedView()->VectorMode, ui->VectorMode);
+}
+
+void TaskPostDisplay::on_VectorMode_activated(int i) {
+
+ getTypedView()->VectorMode.setValue(i);
+}
+
+void TaskPostDisplay::on_Transparency_valueChanged(int i) {
+
+ getTypedView()->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()->createControlWidget();
+ w->setParent(this);
+ w->setViewProvider(getTypedView());
+ 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(getObject())->CutCells.getValue());
+ ui->InsideOut->setChecked(static_cast(getObject())->InsideOut.getValue());
+}
+
+TaskPostClip::~TaskPostClip() {
+
+}
+
+void TaskPostClip::applyPythonCode() {
+
+}
+
+void TaskPostClip::collectImplicitFunctions() {
+
+ std::vector pipelines;
+ pipelines = App::GetApplication().getActiveDocument()->getObjectsOfType();
+ 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& funcs = static_cast(
+ pipeline->Function.getValue())->Functions.getValues();
+ for(std::size_t i=0; igetNameInDocument()));
+
+ 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 pipelines;
+ pipelines = App::GetApplication().getActiveDocument()->getObjectsOfType();
+ if (!pipelines.empty()) {
+ Fem::FemPostPipeline *pipeline = pipelines.front();
+ if(pipeline->Function.getValue() &&
+ pipeline->Function.getValue()->getTypeId() == Fem::FemPostFunctionProvider::getClassTypeId()) {
+
+ const std::vector& funcs = static_cast(
+ pipeline->Function.getValue())->Functions.getValues();
+ if(idx>=0)
+ static_cast(getObject())->Function.setValue(funcs[idx]);
+ else
+ static_cast(getObject())->Function.setValue(NULL);
+ }
+ }
+
+ //load the correct view
+ Fem::FemPostFunction* fobj = static_cast(
+ static_cast(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(view)->createControlWidget();
+ fwidget->setParent(ui->Container);
+ fwidget->setViewProvider(static_cast(view));
+ ui->Container->layout()->addWidget(fwidget);
+ }
+ recompute();
+}
+
+void TaskPostClip::on_CutCells_toggled(bool val) {
+
+ static_cast(getObject())->CutCells.setValue(val);
+ recompute();
+}
+
+void TaskPostClip::on_InsideOut_toggled(bool val) {
+
+ static_cast(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()->Scalars, ui->Scalar);
+ ui->InsideOut->setChecked(static_cast(getObject())->InsideOut.getValue());
+
+ App::PropertyFloatConstraint& value = static_cast(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(getObject())->Scalars.setValue(idx);
+ recompute();
+
+ //update constraints and values
+ App::PropertyFloatConstraint& value = static_cast(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(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(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(getObject())->InsideOut.setValue(val);
+ recompute();
+}
+
+
+#include "moc_TaskPostBoxes.cpp"
diff --git a/src/Mod/Fem/Gui/TaskPostBoxes.h b/src/Mod/Fem/Gui/TaskPostBoxes.h
new file mode 100644
index 000000000..7894ebcce
--- /dev/null
+++ b/src/Mod/Fem/Gui/TaskPostBoxes.h
@@ -0,0 +1,188 @@
+/***************************************************************************
+ * Copyright (c) 2015 Stefan Tröger *
+ * *
+ * 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
+#include
+#include
+#include
+#include
+#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
+ T* getTypedObject() {return static_cast(m_object);};
+ Gui::ViewProviderDocumentObject* getView() {return m_view;};
+ template
+ T* getTypedView() {return static_cast(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 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
diff --git a/src/Mod/Fem/Gui/TaskPostClip.ui b/src/Mod/Fem/Gui/TaskPostClip.ui
new file mode 100644
index 000000000..446021801
--- /dev/null
+++ b/src/Mod/Fem/Gui/TaskPostClip.ui
@@ -0,0 +1,92 @@
+
+
+ TaskPostClip
+
+
+
+ 0
+ 0
+ 413
+ 184
+
+
+
+
+ 0
+ 0
+
+
+
+ Form
+
+
+ -
+
+
-
+
+
+ -
+
+
+ Create
+
+
+
+ :/icons/list-add.svg:/icons/list-add.svg
+
+
+ Qt::ToolButtonTextBesideIcon
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
-
+
+
+ Inside Out
+
+
+
+ -
+
+
+ Cut Cells
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Mod/Fem/Gui/TaskPostDisplay.ui b/src/Mod/Fem/Gui/TaskPostDisplay.ui
new file mode 100644
index 000000000..7fe56eac5
--- /dev/null
+++ b/src/Mod/Fem/Gui/TaskPostDisplay.ui
@@ -0,0 +1,180 @@
+
+
+ TaskPostDisplay
+
+
+
+ 0
+ 0
+ 292
+ 254
+
+
+
+ Form
+
+
+ -
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ Mode
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
-
+
+ Outline
+
+
+ -
+
+ Surface
+
+
+ -
+
+ Surface with Edges
+
+
+ -
+
+ Wireframe
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Coloring
+
+
+
-
+
+
+ Field
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
-
+
+ Outline
+
+
+ -
+
+ Surface
+
+
+ -
+
+ Surface with Edges
+
+
+ -
+
+ Wireframe
+
+
+
+
+ -
+
+
+ Vector
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
-
+
+ Magnitute
+
+
+ -
+
+ X
+
+
+ -
+
+ Y
+
+
+ -
+
+ Z
+
+
+
+
+
+
+
+ -
+
+
+ Styling
+
+
+
-
+
+
+ Transparency
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Mod/Fem/Gui/TaskPostScalarClip.ui b/src/Mod/Fem/Gui/TaskPostScalarClip.ui
new file mode 100644
index 000000000..d91c92f46
--- /dev/null
+++ b/src/Mod/Fem/Gui/TaskPostScalarClip.ui
@@ -0,0 +1,215 @@
+
+
+ TaskPostScalarClip
+
+
+
+ 0
+ 0
+ 326
+ 172
+
+
+
+ Form
+
+
+ -
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ Scalar
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
-
+
+ Outline
+
+
+ -
+
+ Surface
+
+
+ -
+
+ Surface with Edges
+
+
+ -
+
+ Wireframe
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+ 100
+
+
+ Qt::Horizontal
+
+
+ false
+
+
+ false
+
+
+ QSlider::NoTicks
+
+
+
+ -
+
+
+ 20
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 50
+ 0
+
+
+
+ Qt::NoFocus
+
+
+ -100000
+
+
+ true
+
+
+ true
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 50
+ 0
+
+
+
+ false
+
+
+ 3
+
+
+ -999999999.000000000000000
+
+
+ 999999999.000000000000000
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 50
+ 0
+
+
+
+ Qt::NoFocus
+
+
+ 0
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ true
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
-
+
+
+ InsideOut
+
+
+
+
+
+
+ layoutWidget
+ minimum
+ maximum
+ Slider
+ line
+ minimum
+ maximum
+
+ InsideOut
+ horizontalSpacer
+
+ line_2
+
+
+
+
diff --git a/src/Mod/Fem/Gui/ViewProviderFemPostFilter.cpp b/src/Mod/Fem/Gui/ViewProviderFemPostFilter.cpp
new file mode 100644
index 000000000..c4b94b5fc
--- /dev/null
+++ b/src/Mod/Fem/Gui/ViewProviderFemPostFilter.cpp
@@ -0,0 +1,71 @@
+/***************************************************************************
+ * Copyright (c) 2015 Stefan Tröger *
+ * *
+ * 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
+#include
+
+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(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);
+}
diff --git a/src/Mod/Fem/Gui/ViewProviderFemPostFilter.h b/src/Mod/Fem/Gui/ViewProviderFemPostFilter.h
new file mode 100644
index 000000000..12efb2bb2
--- /dev/null
+++ b/src/Mod/Fem/Gui/ViewProviderFemPostFilter.h
@@ -0,0 +1,61 @@
+/***************************************************************************
+ * Copyright (c) 2015 Stefan Tröger *
+ * *
+ * 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
\ No newline at end of file
diff --git a/src/Mod/Fem/Gui/ViewProviderFemPostFunction.cpp b/src/Mod/Fem/Gui/ViewProviderFemPostFunction.cpp
index 1f0157b55..59d9629ec 100644
--- a/src/Mod/Fem/Gui/ViewProviderFemPostFunction.cpp
+++ b/src/Mod/Fem/Gui/ViewProviderFemPostFunction.cpp
@@ -31,14 +31,21 @@
#include
#include
#include
+#include
#include
#include
+#include
+#include
#include
#include
#include
+#include
+#include
+#include
#endif
#include "ViewProviderFemPostFunction.h"
+#include "TaskPostBoxes.h"
#include
#include
#include
@@ -46,9 +53,31 @@
#include
#include
#include
+#include
+#include
+#include
+
+#include
+
+#include "ui_PlaneWidget.h"
+#include "ui_SphereWidget.h"
using namespace FemGui;
+void FunctionWidget::setViewProvider(ViewProviderFemPostFunction* view) {
+
+ m_view = view;
+ m_object = static_cast(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(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(getObject())->Normal);
+ onChange(static_cast(getObject())->Origin);
+}
+
+void PlaneWidget::onChange(const App::Property& p) {
+
+ setBlockObjectUpdates(true);
+ if(strcmp(p.getName(), "Normal") == 0) {
+ const Base::Vector3d& vec = static_cast(&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(&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(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(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(getObject());
+ SoTransformBoxDragger* dragger = static_cast(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(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(getManipulator())->center.setValue(SbVec3f(trans[0], trans[1], trans[2]));
+ static_cast(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(getObject())->Center);
+ onChange(static_cast(getObject())->Radius);
+}
+
+void SphereWidget::onChange(const App::Property& p) {
+
+ setBlockObjectUpdates(true);
+ if(strcmp(p.getName(), "Radius") == 0) {
+ double val = static_cast(&p)->getValue();
+ ui->radius->setValue(val);
+ }
+ else if(strcmp(p.getName(), "Center") == 0) {
+ const Base::Vector3d& vec = static_cast(&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(getObject())->Center.setValue(vec);
+ }
+}
+
+void SphereWidget::radiusChanged(double val) {
+
+ if(!blockObjectUpdates()) {
+ static_cast(getObject())->Radius.setValue(ui->radius->value());
+ }
+}
+
+#include "moc_ViewProviderFemPostFunction.cpp"
\ No newline at end of file
diff --git a/src/Mod/Fem/Gui/ViewProviderFemPostFunction.h b/src/Mod/Fem/Gui/ViewProviderFemPostFunction.h
index eb448930c..6a1b4b1dc 100644
--- a/src/Mod/Fem/Gui/ViewProviderFemPostFunction.h
+++ b/src/Mod/Fem/Gui/ViewProviderFemPostFunction.h
@@ -25,7 +25,31 @@
#define FEM_VIEWPROVIDERFEMPOSTFUNCTION_H
#include
+#include
#include
+#include
+
+
+#if defined(signals) && defined(QOBJECTDEFS_H) && \
+ !defined(QT_MOC_CPP)
+# undef signals
+# define signals signals
+#endif
+
+#include
+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 .
+# 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 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
diff --git a/src/Mod/Fem/Gui/ViewProviderFemPostObject.cpp b/src/Mod/Fem/Gui/ViewProviderFemPostObject.cpp
index 91404d391..a258f7790 100644
--- a/src/Mod/Fem/Gui/ViewProviderFemPostObject.cpp
+++ b/src/Mod/Fem/Gui/ViewProviderFemPostObject.cpp
@@ -39,13 +39,19 @@
#endif
#include "ViewProviderFemPostObject.h"
+#include "TaskPostBoxes.h"
#include
#include
+#include
+#include
+#include
+#include
#include
#include
#include
#include
+#include
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 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::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; jGetNumberOfComponents(); ++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(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);
+ }
+}
+
diff --git a/src/Mod/Fem/Gui/ViewProviderFemPostObject.h b/src/Mod/Fem/Gui/ViewProviderFemPostObject.h
index 249ce2e0f..938878708 100644
--- a/src/Mod/Fem/Gui/ViewProviderFemPostObject.h
+++ b/src/Mod/Fem/Gui/ViewProviderFemPostObject.h
@@ -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 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;
};
diff --git a/src/Mod/Fem/Gui/Workbench.cpp b/src/Mod/Fem/Gui/Workbench.cpp
index 0505a9bc2..81f10435d 100755
--- a/src/Mod/Fem/Gui/Workbench.cpp
+++ b/src/Mod/Fem/Gui/Workbench.cpp
@@ -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