From 46e46a14669bb656f764f2a06bd1044b2c457e15 Mon Sep 17 00:00:00 2001 From: wmayer Date: Wed, 24 Feb 2021 23:59:10 +0100 Subject: [PATCH] FEM: [skip ci] fixes #0004405: Using PartDesign axis / plane as direction for constraints --- src/Mod/Fem/Gui/TaskFemConstraintForce.cpp | 117 ++++++++++++--------- src/Mod/Fem/Gui/TaskFemConstraintForce.h | 2 + 2 files changed, 69 insertions(+), 50 deletions(-) diff --git a/src/Mod/Fem/Gui/TaskFemConstraintForce.cpp b/src/Mod/Fem/Gui/TaskFemConstraintForce.cpp index 0dff70627d..83e4986e19 100644 --- a/src/Mod/Fem/Gui/TaskFemConstraintForce.cpp +++ b/src/Mod/Fem/Gui/TaskFemConstraintForce.cpp @@ -50,6 +50,7 @@ #include #include #include +#include #include #include #include @@ -258,65 +259,81 @@ void TaskFemConstraintForce::onReferenceDeleted() { TaskFemConstraintForce::removeFromSelection(); //OvG: On right-click face is automatically selected, so just remove } +std::pair +TaskFemConstraintForce::getDirection(const std::vector& selection) const +{ + std::pair link; + if (selection.empty()) { + return link; + } + + // we only handle the first selected object + Gui::SelectionObject selectionElement = selection.at(0); + + // Line or Plane + Base::Type line = Base::Type::fromName("PartDesign::Line"); + Base::Type plane = Base::Type::fromName("PartDesign::Plane"); + if (selectionElement.isObjectTypeOf(App::Line::getClassTypeId()) || + selectionElement.isObjectTypeOf(App::Plane::getClassTypeId())) { + link = std::make_pair(selectionElement.getObject(), std::string()); + } + else if (selectionElement.isObjectTypeOf(line)) { + link = std::make_pair(selectionElement.getObject(), std::string("Edge1")); + } + else if (selectionElement.isObjectTypeOf(plane)) { + link = std::make_pair(selectionElement.getObject(), std::string("Face1")); + } + // Sub-element of Part object + else if (selectionElement.isObjectTypeOf(Part::Feature::getClassTypeId())) { + const std::vector& subNames = selectionElement.getSubNames(); + if (subNames.size() != 1) { + return link; + } + + std::string subNamesElement = subNames[0]; + + const Part::Feature* feat = static_cast(selectionElement.getObject()); + TopoDS_Shape ref = feat->Shape.getShape().getSubShape(subNamesElement.c_str()); + + if (ref.ShapeType() == TopAbs_EDGE) { + if (Fem::Tools::isLinear(TopoDS::Edge(ref))) { + link = std::make_pair(selectionElement.getObject(), subNamesElement); + } + } + else if (ref.ShapeType() == TopAbs_FACE) { + if (Fem::Tools::isPlanar(TopoDS::Face(ref))) { + link = std::make_pair(selectionElement.getObject(), subNamesElement); + } + } + } + + return link; +} + void TaskFemConstraintForce::onButtonDirection(const bool pressed) { // sets the normal vector of the currently selecteed planar face as direction - Q_UNUSED(pressed) - //get vector of selected objects of active document - std::vector selection = Gui::Selection().getSelectionEx(); - if (selection.size() == 0) { - QMessageBox::warning(this, tr("Empty selection"), tr("Select an edge or a face, please.")); - return; - } - Fem::ConstraintForce* pcConstraint = static_cast(ConstraintView->getObject()); - // we only handle the first selected object - Gui::SelectionObject& selectionElement = selection.at(0); - - // we can only handle part objects - if (!selectionElement.isObjectTypeOf(Part::Feature::getClassTypeId())) { - QMessageBox::warning(this, tr("Wrong selection"), tr("Selected object is not a part object!")); - return; - } - // get the names of the subobjects - const std::vector& subNames = selectionElement.getSubNames(); - - if (subNames.size() != 1) { - QMessageBox::warning(this, tr("Wrong selection"), tr("Only one planar face or edge can be selected!")); - return; - } - // we are now sure we only have one object - std::string subNamesElement = subNames[0]; - // vector for the direction - std::vector direction(1, subNamesElement); - - Part::Feature* feat = static_cast(selectionElement.getObject()); - TopoDS_Shape ref = feat->Shape.getShape().getSubShape(subNamesElement.c_str()); - - if (subNamesElement.substr(0, 4) == "Face") { - if (!Fem::Tools::isPlanar(TopoDS::Face(ref))) { - QMessageBox::warning(this, tr("Wrong selection"), tr("Only planar faces can be picked for 3D")); - return; - } - } - else if (subNamesElement.substr(0, 4) == "Edge") { // 2D or 3D can use edge as direction vector - if (!Fem::Tools::isLinear(TopoDS::Edge(ref))) { - QMessageBox::warning(this, tr("Wrong selection"), tr("Only planar edges can be picked for 2D")); - return; - } - } - else { - QMessageBox::warning(this, tr("Wrong selection"), tr("Only faces for 3D part or edges for 2D can be picked")); + auto link = getDirection(Gui::Selection().getSelectionEx()); + if (!link.first) { + QMessageBox::warning(this, tr("Wrong selection"), tr("Select an edge or a face, please.")); return; } - // update the direction - pcConstraint->Direction.setValue(feat, direction); - ui->lineDirection->setText(makeRefText(feat, subNamesElement)); + try { + std::vector direction(1, link.second); + Fem::ConstraintForce* pcConstraint = static_cast(ConstraintView->getObject()); - //Update UI - updateUI(); + // update the direction + pcConstraint->Direction.setValue(link.first, direction); + ui->lineDirection->setText(makeRefText(link.first, link.second)); + + updateUI(); + } + catch (const Base::Exception& e) { + QMessageBox::warning(this, tr("Wrong selection"), QString::fromLatin1(e.what())); + } } void TaskFemConstraintForce::onCheckReverse(const bool pressed) diff --git a/src/Mod/Fem/Gui/TaskFemConstraintForce.h b/src/Mod/Fem/Gui/TaskFemConstraintForce.h index fa5f0f51ca..893bb76364 100644 --- a/src/Mod/Fem/Gui/TaskFemConstraintForce.h +++ b/src/Mod/Fem/Gui/TaskFemConstraintForce.h @@ -41,6 +41,7 @@ class Property; } namespace Gui { +class SelectionObject; class ViewProvider; } @@ -72,6 +73,7 @@ protected: virtual void changeEvent(QEvent *e); private: + std::pair getDirection(const std::vector&) const; void updateUI(); private: