FEM: change behavior of Force dialog to the one of all other constraint dialogs

This commit is contained in:
donovaly
2020-02-20 01:09:33 +01:00
committed by Bernd Hahnebach
parent 2f58af7af6
commit 4c368c7c21
5 changed files with 192 additions and 111 deletions

View File

@@ -50,9 +50,6 @@
#include "ui_TaskFemConstraintDisplacement.h"
#include <App/Application.h>
#include <Gui/Command.h>
#include <Gui/Selection.h>
#include <Gui/SelectionFilter.h>

View File

@@ -9,7 +9,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<width>330</width>
<height>800</height>
</rect>
</property>
@@ -21,7 +21,7 @@
</property>
<property name="minimumSize">
<size>
<width>400</width>
<width>330</width>
<height>800</height>
</size>
</property>
@@ -37,7 +37,7 @@
<widget class="QWidget" name="verticalLayoutWidget">
<property name="geometry">
<rect>
<x>40</x>
<x>10</x>
<y>0</y>
<width>311</width>
<height>743</height>

View File

@@ -82,8 +82,6 @@ TaskFemConstraintForce::TaskFemConstraintForce(ViewProviderFemConstraintForce *C
connect(ui->spinForce, SIGNAL(valueChanged(double)),
this, SLOT(onForceChanged(double)));
connect(ui->buttonReference, SIGNAL(pressed()),
this, SLOT(onButtonReference()));
connect(ui->buttonDirection, SIGNAL(pressed()),
this, SLOT(onButtonDirection()));
connect(ui->checkReverse, SIGNAL(toggled(bool)),
@@ -94,7 +92,6 @@ TaskFemConstraintForce::TaskFemConstraintForce(ViewProviderFemConstraintForce *C
// Temporarily prevent unnecessary feature recomputes
ui->spinForce->blockSignals(true);
ui->listReferences->blockSignals(true);
ui->buttonReference->blockSignals(true);
ui->buttonDirection->blockSignals(true);
ui->checkReverse->blockSignals(true);
@@ -123,10 +120,13 @@ TaskFemConstraintForce::TaskFemConstraintForce(ViewProviderFemConstraintForce *C
ui->spinForce->blockSignals(false);
ui->listReferences->blockSignals(false);
ui->buttonReference->blockSignals(false);
ui->buttonDirection->blockSignals(false);
ui->checkReverse->blockSignals(false);
//Selection buttons
connect(ui->btnAdd, SIGNAL(clicked()), this, SLOT(addToSelection()));
connect(ui->btnRemove, SIGNAL(clicked()), this, SLOT(removeFromSelection()));
updateUI();
}
@@ -137,105 +137,141 @@ void TaskFemConstraintForce::updateUI()
onButtonReference(true);
return;
}
std::string ref = ui->listReferences->item(0)->text().toStdString();
int pos = ref.find_last_of(":");
if (ref.substr(pos+1, 6) == "Vertex")
ui->labelForce->setText(tr("Point load"));
else if (ref.substr(pos+1, 4) == "Edge")
ui->labelForce->setText(tr("Line load"));
else if (ref.substr(pos+1, 4) == "Face")
ui->labelForce->setText(tr("Area load"));
}
void TaskFemConstraintForce::onSelectionChanged(const Gui::SelectionChanges& msg)
void TaskFemConstraintForce::addToSelection()
{
if (msg.Type == Gui::SelectionChanges::AddSelection) {
// Don't allow selection in other document
if (strcmp(msg.pDocName, ConstraintView->getObject()->getDocument()->getName()) != 0)
std::vector<Gui::SelectionObject> selection = Gui::Selection().getSelectionEx(); //gets vector of selected objects of active document
if (selection.size() == 0) {
QMessageBox::warning(this, tr("Selection error"), tr("Nothing selected!"));
return;
}
Fem::ConstraintForce* pcConstraint = static_cast<Fem::ConstraintForce*>(ConstraintView->getObject());
std::vector<App::DocumentObject*> Objects = pcConstraint->References.getValues();
std::vector<std::string> SubElements = pcConstraint->References.getSubValues();
for (std::vector<Gui::SelectionObject>::iterator it = selection.begin(); it != selection.end(); ++it) {//for every selected object
if (static_cast<std::string>(it->getTypeName()).substr(0, 4).compare(std::string("Part")) != 0) {
QMessageBox::warning(this, tr("Selection error"), tr("Selected object is not a part!"));
return;
}
if (!msg.pSubName || msg.pSubName[0] == '\0')
return;
std::string subName(msg.pSubName);
if (selectionMode == selnone)
return;
std::vector<std::string> references(1,subName);
Fem::ConstraintForce* pcConstraint = static_cast<Fem::ConstraintForce*>(ConstraintView->getObject());
App::DocumentObject* obj = ConstraintView->getObject()->getDocument()->getObject(msg.pObjectName);
Part::Feature* feat = static_cast<Part::Feature*>(obj);
TopoDS_Shape ref = feat->Shape.getShape().getSubShape(subName.c_str());
if (selectionMode == selref) {
std::vector<App::DocumentObject*> Objects = pcConstraint->References.getValues();
std::vector<std::string> SubElements = pcConstraint->References.getSubValues();
// Ensure we don't have mixed reference types
if (SubElements.size() > 0) {
if (subName.substr(0,4) != SubElements.front().substr(0,4)) {
QMessageBox::warning(this, tr("Selection error"), tr("Mixed shape types are not possible. Use a second constraint instead"));
return;
std::vector<std::string> subNames = it->getSubNames();
App::DocumentObject* obj = ConstraintView->getObject()->getDocument()->getObject(it->getFeatName());
for (unsigned int subIt = 0; subIt < (subNames.size()); ++subIt) {// for every selected sub element
bool addMe = true;
for (std::vector<std::string>::iterator itr = std::find(SubElements.begin(), SubElements.end(), subNames[subIt]);
itr != SubElements.end();
itr = std::find(++itr, SubElements.end(), subNames[subIt]))
{// for every sub element in selection that matches one in old list
if (obj == Objects[std::distance(SubElements.begin(), itr)]) {//if selected sub element's object equals the one in old list then it was added before so don't add
addMe = false;
}
}
else {
if ((subName.substr(0,4) != "Face") && (subName.substr(0,4) != "Edge") && (subName.substr(0,6) != "Vertex")) {
QMessageBox::warning(this, tr("Selection error"), tr("Only faces, edges and vertices can be picked"));
return;
}
}
// Avoid duplicates
std::size_t pos = 0;
for (; pos < Objects.size(); pos++) {
if (obj == Objects[pos]) {
// limit constraint such that only vertexes or faces or edges can be used depending on what was selected first
std::string searchStr("");
if (subNames[subIt].find("Vertex") != std::string::npos)
searchStr = "Vertex";
else if (subNames[subIt].find("Edge") != std::string::npos)
searchStr = "Edge";
else
searchStr = "Face";
for (unsigned int iStr = 0; iStr < (SubElements.size()); ++iStr) {
if ((SubElements[iStr].find(searchStr) == std::string::npos) && (SubElements.size() > 0)) {
QString msg = tr("Only one type of selection (vertex,face or edge) per constraint allowed!");
QMessageBox::warning(this, tr("Selection error"), msg);
addMe = false;
break;
}
}
if (pos != Objects.size()) {
if (subName == SubElements[pos]) {
return;
}
if (addMe) {
disconnect(ui->listReferences, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)),
this, SLOT(setSelection(QListWidgetItem*)));
Objects.push_back(obj);
SubElements.push_back(subNames[subIt]);
ui->listReferences->addItem(makeRefText(obj, subNames[subIt]));
connect(ui->listReferences, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)),
this, SLOT(setSelection(QListWidgetItem*)));
}
// add the new reference
Objects.push_back(obj);
SubElements.push_back(subName);
pcConstraint->References.setValues(Objects,SubElements);
ui->listReferences->addItem(makeRefText(obj, subName));
// Turn off reference selection mode
onButtonReference(false);
}
else if (selectionMode == seldir) {
if (subName.substr(0,4) == "Face") {
if (!Fem::Tools::isPlanar(TopoDS::Face(ref))) {
QMessageBox::warning(this, tr("Selection error"), tr("Only planar faces can be picked"));
return;
}
}
else if (subName.substr(0,4) == "Edge") {
if (!Fem::Tools::isLinear(TopoDS::Edge(ref))) {
QMessageBox::warning(this, tr("Selection error"), tr("Only linear edges can be picked"));
return;
}
}
else {
QMessageBox::warning(this, tr("Selection error"), tr("Only faces and edges can be picked"));
return;
}
pcConstraint->Direction.setValue(obj, references);
ui->lineDirection->setText(makeRefText(obj, subName));
// Turn off direction selection mode
onButtonDirection(false);
}
Gui::Selection().clearSelection();
updateUI();
}
//Update UI
pcConstraint->References.setValues(Objects, SubElements);
updateUI();
}
void TaskFemConstraintForce::removeFromSelection()
{
std::vector<Gui::SelectionObject> selection = Gui::Selection().getSelectionEx(); //gets vector of selected objects of active document
if (selection.size() == 0) {
QMessageBox::warning(this, tr("Selection error"), tr("Nothing selected!"));
return;
}
Fem::ConstraintForce* pcConstraint = static_cast<Fem::ConstraintForce*>(ConstraintView->getObject());
std::vector<App::DocumentObject*> Objects = pcConstraint->References.getValues();
std::vector<std::string> SubElements = pcConstraint->References.getSubValues();
std::vector<unsigned int> itemsToDel;
for (std::vector<Gui::SelectionObject>::iterator it = selection.begin(); it != selection.end(); ++it) {//for every selected object
if (static_cast<std::string>(it->getTypeName()).substr(0, 4).compare(std::string("Part")) != 0) {
QMessageBox::warning(this, tr("Selection error"), tr("Selected object is not a part!"));
return;
}
std::vector<std::string> subNames = it->getSubNames();
App::DocumentObject* obj = ConstraintView->getObject()->getDocument()->getObject(it->getFeatName());
for (unsigned int subIt = 0; subIt < (subNames.size()); ++subIt) {// for every selected sub element
for (std::vector<std::string>::iterator itr = std::find(SubElements.begin(), SubElements.end(), subNames[subIt]);
itr != SubElements.end();
itr = std::find(++itr, SubElements.end(), subNames[subIt]))
{// for every sub element in selection that matches one in old list
if (obj == Objects[std::distance(SubElements.begin(), itr)]) {//if selected sub element's object equals the one in old list then it was added before so mark for deletion
itemsToDel.push_back(std::distance(SubElements.begin(), itr));
}
}
}
}
std::sort(itemsToDel.begin(), itemsToDel.end());
while (itemsToDel.size() > 0) {
Objects.erase(Objects.begin() + itemsToDel.back());
SubElements.erase(SubElements.begin() + itemsToDel.back());
itemsToDel.pop_back();
}
//Update UI
disconnect(ui->listReferences, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)),
this, SLOT(setSelection(QListWidgetItem*)));
ui->listReferences->clear();
for (unsigned int j = 0; j < Objects.size(); j++) {
ui->listReferences->addItem(makeRefText(Objects[j], SubElements[j]));
}
connect(ui->listReferences, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)),
this, SLOT(setSelection(QListWidgetItem*)));
pcConstraint->References.setValues(Objects, SubElements);
updateUI();
}
void TaskFemConstraintForce::setSelection(QListWidgetItem* item) {
std::string s = item->text().toStdString();
std::string docName = ConstraintView->getObject()->getDocument()->getName();
std::string delimiter = ":";
size_t pos = 0;
std::string objName;
std::string subName;
pos = s.find(delimiter);
objName = s.substr(0, pos);
s.erase(0, pos + delimiter.length());
subName = s;
Gui::Selection().clearSelection();
Gui::Selection().addSelection(docName.c_str(), objName.c_str(), subName.c_str(), 0, 0, 0);
}
void TaskFemConstraintForce::onForceChanged(double f)
@@ -245,10 +281,7 @@ void TaskFemConstraintForce::onForceChanged(double f)
}
void TaskFemConstraintForce::onReferenceDeleted() {
int row = ui->listReferences->currentIndex().row();
TaskFemConstraint::onReferenceDeleted(row);
ui->listReferences->model()->removeRow(row);
ui->listReferences->setCurrentRow(0, QItemSelectionModel::ClearAndSelect);
TaskFemConstraintForce::removeFromSelection(); //OvG: On right-click face is automatically selected, so just remove
}
void TaskFemConstraintForce::onButtonDirection(const bool pressed) {

View File

@@ -33,6 +33,7 @@
#include "ViewProviderFemConstraintForce.h"
#include <QKeyEvent>
#include <QListWidgetItem>
class Ui_TaskFemConstraintForce;
@@ -53,9 +54,8 @@ class TaskFemConstraintForce : public TaskFemConstraint
public:
TaskFemConstraintForce(ViewProviderFemConstraintForce *ConstraintView,QWidget *parent = 0);
virtual ~TaskFemConstraintForce();
double getForce(void) const;
virtual const std::string getReferences() const;
const std::string getReferences() const;
const std::string getDirectionName(void) const;
const std::string getDirectionObject(void) const;
bool getReverse(void) const;
@@ -65,13 +65,15 @@ private Q_SLOTS:
void onForceChanged(double);
void onButtonDirection(const bool pressed = true);
void onCheckReverse(bool);
void addToSelection();
void removeFromSelection();
void setSelection(QListWidgetItem* item);
protected:
bool event(QEvent *e);
virtual void changeEvent(QEvent *e);
private:
virtual void onSelectionChanged(const Gui::SelectionChanges& msg);
void updateUI();
private:

View File

@@ -6,23 +6,72 @@
<rect>
<x>0</x>
<y>0</y>
<width>257</width>
<height>233</height>
<width>330</width>
<height>350</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>3</horstretch>
<verstretch>35</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>330</width>
<height>350</height>
</size>
</property>
<property name="baseSize">
<size>
<width>400</width>
<height>800</height>
</size>
</property>
<property name="windowTitle">
<string>Form</string>
<string>Prescribed Force</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="buttonReference">
<widget class="QLabel" name="lbl_info">
<property name="text">
<string>Add reference</string>
<string>Select multiple face(s), click Add or Remove</string>
</property>
</widget>
</item>
<item>
<widget class="QListWidget" name="listReferences"/>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="btnAdd">
<property name="text">
<string>Add</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnRemove">
<property name="text">
<string>Remove</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QListWidget" name="listReferences">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>100</height>
</size>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="layoutForce">
@@ -34,8 +83,8 @@
</widget>
</item>
<item>
<widget class="Gui::QuantitySpinBox" name="spinForce">
<property name="value">
<widget class="Gui::QuantitySpinBox" name="spinForce" native="true">
<property name="value" stdset="0">
<double>500.000000000000000</double>
</property>
</widget>