FEM: DataAlongLine: core implementation

This commit is contained in:
mkhizenz
2016-12-20 18:10:35 +01:00
committed by Yorik van Havre
parent 5606d5cda2
commit 89cf335f3d
12 changed files with 878 additions and 13 deletions

View File

@@ -28,6 +28,7 @@
#include "ui_TaskPostDisplay.h"
#include "ui_TaskPostClip.h"
#include "ui_TaskPostDataAlongLine.h"
#include "ui_TaskPostScalarClip.h"
#include "ui_TaskPostWarpVector.h"
#include "ui_TaskPostCut.h"
@@ -45,10 +46,98 @@
#include <Gui/Action.h>
#include <QMessageBox>
#include <QPushButton>
#include <Gui/View3DInventor.h>
#include <Gui/View3DInventorViewer.h>
# include <Inventor/events/SoMouseButtonEvent.h>
# include <sstream>
# include <QApplication>
# include <Inventor/SoPickedPoint.h>
# include <Inventor/nodes/SoAnnotation.h>
# include <Inventor/nodes/SoBaseColor.h>
# include <Inventor/nodes/SoFontStyle.h>
# include <Inventor/nodes/SoPickStyle.h>
# include <Inventor/nodes/SoText2.h>
# include <Inventor/nodes/SoTranslation.h>
# include <Inventor/nodes/SoCoordinate3.h>
# include <Inventor/nodes/SoIndexedLineSet.h>
# include <Inventor/nodes/SoMarkerSet.h>
# include <Inventor/nodes/SoDrawStyle.h>
#include <Gui/View3DInventorViewer.h>
#include <Base/Console.h>
#include <App/PropertyGeo.h>
#include <App/PropertyStandard.h>
#include <Base/Quantity.h>
using namespace FemGui;
using namespace Gui;
// ----------------------------------------------------------------------------
PointMarker::PointMarker(Gui::View3DInventorViewer* iv, std::string ObjName) : view(iv),
vp(new ViewProviderPointMarker)
{
view->addViewProvider(vp);
m_name = ObjName;
}
PointMarker::~PointMarker()
{
view->removeViewProvider(vp);
delete vp;
}
void PointMarker::addPoint(const SbVec3f& pt)
{
int ct = countPoints();
vp->pCoords->point.set1Value(ct, pt);
}
int PointMarker::countPoints() const
{
return vp->pCoords->point.getNum();
}
void PointMarker::customEvent(QEvent*)
{
const SbVec3f& pt1 = vp->pCoords->point[0];
const SbVec3f& pt2 = vp->pCoords->point[1];
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Point1 = App.Vector(%f, %f, %f)", m_name.c_str(), pt1[0],pt1[1], pt1[2]);
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Point2 = App.Vector(%f, %f, %f)", m_name.c_str(), pt2[0],pt2[1], pt2[2]);
Gui::Command::doCommand(Gui::Command::Doc, ObjectInvisible().c_str());
PointsChanged(pt1[0],pt1[1], pt1[2], pt2[0],pt2[1], pt2[2]);
}
std::string PointMarker::ObjectInvisible(){
return "for amesh in App.activeDocument().Objects:\n\
if \"Mesh\" in amesh.TypeId:\n\
aparttoshow = amesh.Name.replace(\"_Mesh\",\"\")\n\
for apart in App.activeDocument().Objects:\n\
if aparttoshow == apart.Name:\n\
apart.ViewObject.Visibility = False\n";
}
PROPERTY_SOURCE(FemGui::ViewProviderPointMarker, Gui::ViewProviderDocumentObject)
ViewProviderPointMarker::ViewProviderPointMarker()
{
pCoords = new SoCoordinate3();
pCoords->ref();
pCoords->point.setNum(0);
SoGroup* grp = new SoGroup();
grp->addChild(pCoords);
addDisplayMaskMode(grp, "Base");
setDisplayMaskMode("Base");
}
ViewProviderPointMarker::~ViewProviderPointMarker()
{
pCoords->unref();
}
//**************************************************************************
//**************************************************************************
// TaskDialog
@@ -129,8 +218,6 @@ void TaskDlgPost::modifyStandardButtons(QDialogButtonBox* box) {
if(box->button(QDialogButtonBox::Apply))
box->button(QDialogButtonBox::Apply)->setDefault(true);
}
//############################################################################################
TaskPostBox::TaskPostBox(Gui::ViewProviderDocumentObject* view, const QPixmap &icon, const QString &title, QWidget* parent)
@@ -161,8 +248,9 @@ void TaskPostBox::updateEnumerationList(App::PropertyEnumeration& prop, QComboBo
box->clear();
QStringList list;
std::vector<std::string> vec = prop.getEnumVector();
for(std::vector<std::string>::iterator it = vec.begin(); it != vec.end(); ++it )
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());
@@ -221,7 +309,7 @@ void TaskPostDisplay::applyPythonCode() {
//############################################################################################
TaskPostFunction::TaskPostFunction(ViewProviderDocumentObject* view, QWidget* parent): TaskPostBox(view, Gui::BitmapFactory().pixmap("fem-femmesh-create-node-by-poly"), tr("Implicit function"), parent) {
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()));
@@ -359,6 +447,222 @@ void TaskPostClip::on_InsideOut_toggled(bool val) {
static_cast<Fem::FemPostClipFilter*>(getObject())->InsideOut.setValue(val);
recompute();
}
//############################################################################################
TaskPostDataAlongLine::TaskPostDataAlongLine(ViewProviderDocumentObject* view, QWidget* parent)
: TaskPostBox(view,Gui::BitmapFactory().pixmap("fem-femmesh-create-node-by-poly"), tr("Data Along Line"), parent) {
assert(view->isDerivedFrom(ViewProviderFemPostDataAlongLine::getClassTypeId()));
//we load the views widget
proxy = new QWidget(this);
ui = new Ui_TaskPostDataAlongLine();
ui->setupUi(proxy);
QMetaObject::connectSlotsByName(this);
this->groupLayout()->addWidget(proxy);
const Base::Vector3d& vec1 = static_cast<Fem::FemPostDataAlongLineFilter*>(getObject())->Point1.getValue();
ui->point1X->setValue(vec1.x);
ui->point1Y->setValue(vec1.y);
ui->point1Z->setValue(vec1.z);
const Base::Vector3d& vec2 = static_cast<Fem::FemPostDataAlongLineFilter*>(getObject())->Point2.getValue();
ui->point2X->setValue(vec2.x);
ui->point2Y->setValue(vec2.y);
ui->point2Z->setValue(vec2.z);
int res = static_cast<Fem::FemPostDataAlongLineFilter*>(getObject())->Resolution.getValue();
ui->resolution->setValue(res);
connect(ui->point1X, SIGNAL(valueChanged(double)), this, SLOT(point1Changed(double)));
connect(ui->point1Y, SIGNAL(valueChanged(double)), this, SLOT(point1Changed(double)));
connect(ui->point1Z, SIGNAL(valueChanged(double)), this, SLOT(point1Changed(double)));
connect(ui->point2X, SIGNAL(valueChanged(double)), this, SLOT(point2Changed(double)));
connect(ui->point2Y, SIGNAL(valueChanged(double)), this, SLOT(point2Changed(double)));
connect(ui->point2Z, SIGNAL(valueChanged(double)), this, SLOT(point2Changed(double)));
connect(ui->resolution, SIGNAL(valueChanged(int)), this, SLOT(resolutionChanged(int)));
//update all fields
updateEnumerationList(getTypedView<ViewProviderFemPostObject>()->DisplayMode, ui->Representation);
updateEnumerationList(getTypedView<ViewProviderFemPostObject>()->Field, ui->Field);
updateEnumerationList(getTypedView<ViewProviderFemPostObject>()->VectorMode, ui->VectorMode);
}
TaskPostDataAlongLine::~TaskPostDataAlongLine() {
}
void TaskPostDataAlongLine::applyPythonCode() {
}
static const char * cursor_triangle[] = {
"32 32 3 1",
" c None",
". c #FFFFFF",
"+ c #FF0000",
" . ",
" . ",
" . ",
" . ",
" . ",
" ",
"..... ..... ",
" ",
" . ",
" . ",
" . ++ ",
" . + + ",
" . + ++ + ",
" + ++++ + ",
" + ++ ++ + ",
" + ++++++++ + ",
" ++ ++ ++ ++ "};
void TaskPostDataAlongLine::on_SelectPoints_clicked() {
Gui::Command::doCommand(Gui::Command::Doc, ObjectVisible().c_str());
Gui::Document* doc = Gui::Application::Instance->activeDocument();
Gui::View3DInventor* view = static_cast<Gui::View3DInventor*>(doc->getActiveView());
if (view) {
Gui::View3DInventorViewer* viewer = view->getViewer();
viewer->setEditing(true);
viewer->setEditingCursor(QCursor(QPixmap(cursor_triangle), 7, 7));
// Derives from QObject and we have a parent object, so we don't
// require a delete.
std::string ObjName = static_cast<Fem::FemPostDataAlongLineFilter*>(getObject())->Label.getValue();
FemGui::PointMarker* marker = new FemGui::PointMarker(viewer, ObjName);
viewer->addEventCallback(SoMouseButtonEvent::getClassTypeId(),
FemGui::TaskPostDataAlongLine::pointCallback, marker);
connect(marker, SIGNAL(PointsChanged(double, double, double, double, double, double)), this, SLOT(onChange(double, double, double, double, double, double)));
}
}
std::string TaskPostDataAlongLine::ObjectVisible(){
return "for amesh in App.activeDocument().Objects:\n\
if \"Mesh\" in amesh.TypeId:\n\
aparttoshow = amesh.Name.replace(\"_Mesh\",\"\")\n\
for apart in App.activeDocument().Objects:\n\
if aparttoshow == apart.Name:\n\
apart.ViewObject.Visibility = True\n";
}
void TaskPostDataAlongLine::on_CreatePlot_clicked() {
std::string ObjName = static_cast<Fem::FemPostDataAlongLineFilter*>(getObject())->Label.getValue();
Gui::Command::doCommand(Gui::Command::Doc,"x = App.ActiveDocument.%s.XAxisData",ObjName.c_str());
Gui::Command::doCommand(Gui::Command::Doc,"y = App.ActiveDocument.%s.YAxisData",ObjName.c_str());
Gui::Command::doCommand(Gui::Command::Doc,"title = App.ActiveDocument.%s.PlotData",ObjName.c_str());
Gui::Command::doCommand(Gui::Command::Doc, Plot().c_str());
recompute();
}
void TaskPostDataAlongLine::onChange(double x1, double y1, double z1, double x2, double y2, double z2) {
ui->point2X->setValue(x2);
ui->point2Y->setValue(y2);
ui->point2Z->setValue(z2);
ui->point1X->setValue(x1);
ui->point1Y->setValue(y1);
ui->point1Z->setValue(z1);
}
void TaskPostDataAlongLine::point1Changed(double) {
Base::Vector3d vec(ui->point1X->value(), ui->point1Y->value(), ui->point1Z->value());
std::string ObjName = static_cast<Fem::FemPostDataAlongLineFilter*>(getObject())->Label.getValue();
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Point1 = App.Vector(%f, %f, %f)",ObjName.c_str(), ui->point1X->value(), ui->point1Y->value(), ui->point1Z->value());
}
void TaskPostDataAlongLine::point2Changed(double) {
Base::Vector3d vec(ui->point2X->value(), ui->point2Y->value(), ui->point2Z->value());
std::string ObjName = static_cast<Fem::FemPostDataAlongLineFilter*>(getObject())->Label.getValue();
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Point2 = App.Vector(%f, %f, %f)", ObjName.c_str(), ui->point2X->value(), ui->point2Y->value(), ui->point2Z->value());
}
void TaskPostDataAlongLine::resolutionChanged(int val) {
static_cast<Fem::FemPostDataAlongLineFilter*>(getObject())->Resolution.setValue(val);
}
void TaskPostDataAlongLine::pointCallback(void * ud, SoEventCallback * n)
{
const SoMouseButtonEvent * mbe = static_cast<const SoMouseButtonEvent*>(n->getEvent());
Gui::View3DInventorViewer* view = reinterpret_cast<Gui::View3DInventorViewer*>(n->getUserData());
PointMarker *pm = reinterpret_cast<PointMarker*>(ud);
// Mark all incoming mouse button events as handled, especially, to deactivate the selection node
n->getAction()->setHandled();
if (mbe->getButton() == SoMouseButtonEvent::BUTTON1 && mbe->getState() == SoButtonEvent::DOWN) {
const SoPickedPoint * point = n->getPickedPoint();
if (point == NULL) {
Base::Console().Message("No point picked.\n");
return;
}
n->setHandled();
pm->addPoint(point->getPoint());
if (pm->countPoints() == 2) {
QEvent *e = new QEvent(QEvent::User);
QApplication::postEvent(pm, e);
// leave mode
view->setEditing(false);
view->removeEventCallback(SoMouseButtonEvent::getClassTypeId(), pointCallback, ud);
}
}
else if (mbe->getButton() != SoMouseButtonEvent::BUTTON1 && mbe->getState() == SoButtonEvent::UP) {
n->setHandled();
view->setEditing(false);
view->removeEventCallback(SoMouseButtonEvent::getClassTypeId(), pointCallback, ud);
pm->deleteLater();
}
}
void TaskPostDataAlongLine::on_Representation_activated(int i) {
getTypedView<ViewProviderFemPostObject>()->DisplayMode.setValue(i);
updateEnumerationList(getTypedView<ViewProviderFemPostObject>()->Field, ui->Field);
updateEnumerationList(getTypedView<ViewProviderFemPostObject>()->VectorMode, ui->VectorMode);
}
void TaskPostDataAlongLine::on_Field_activated(int i) {
getTypedView<ViewProviderFemPostObject>()->Field.setValue(i);
std::string FieldName = ui->Field->currentText().toStdString();
static_cast<Fem::FemPostDataAlongLineFilter*>(getObject())->PlotData.setValue(FieldName);
updateEnumerationList(getTypedView<ViewProviderFemPostObject>()->VectorMode, ui->VectorMode);
}
void TaskPostDataAlongLine::on_VectorMode_activated(int i) {
getTypedView<ViewProviderFemPostObject>()->VectorMode.setValue(i);
}
std::string TaskPostDataAlongLine::Plot() {
return "import FreeCAD\n\
import numpy as np\n\
from matplotlib import pyplot as plt\n\
plt.figure(1)\n\
plt.plot(x, y)\n\
plt.xlabel(\"Length\")\n\
plt.ylabel(title)\n\
plt.title(title)\n\
plt.grid()\n\
plt.show()\n";
}
//############################################################################################