Skip to content

Commit

Permalink
FEM: change behavior of Force dialog to the one of all other constrai…
Browse files Browse the repository at this point in the history
…nt dialogs
  • Loading branch information
donovaly authored and berndhahnebach committed Feb 20, 2020
1 parent 4db7fc9 commit 325b31a
Show file tree
Hide file tree
Showing 5 changed files with 184 additions and 103 deletions.
3 changes: 0 additions & 3 deletions src/Mod/Fem/Gui/TaskFemConstraintDisplacement.cpp
Expand Up @@ -50,9 +50,6 @@
#include "ui_TaskFemConstraintDisplacement.h"
#include <App/Application.h>
#include <Gui/Command.h>



#include <Gui/Selection.h>
#include <Gui/SelectionFilter.h>

Expand Down
6 changes: 3 additions & 3 deletions src/Mod/Fem/Gui/TaskFemConstraintDisplacement.ui
Expand Up @@ -9,7 +9,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<width>330</width>
<height>800</height>
</rect>
</property>
Expand All @@ -21,7 +21,7 @@
</property>
<property name="minimumSize">
<size>
<width>400</width>
<width>330</width>
<height>800</height>
</size>
</property>
Expand All @@ -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>
Expand Down
205 changes: 119 additions & 86 deletions src/Mod/Fem/Gui/TaskFemConstraintForce.cpp
Expand Up @@ -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)),
Expand All @@ -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);

Expand Down Expand Up @@ -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();
}

Expand All @@ -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)
return;
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;
}

if (!msg.pSubName || msg.pSubName[0] == '\0')
return;
std::string subName(msg.pSubName);
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();

if (selectionMode == selnone)
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> 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;
}
}
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;
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;
}
}

// 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*)));
}
}
}
//Update UI
pcConstraint->References.setValues(Objects, SubElements);
updateUI();
}

// add the new reference
Objects.push_back(obj);
SubElements.push_back(subName);
pcConstraint->References.setValues(Objects,SubElements);
ui->listReferences->addItem(makeRefText(obj, subName));
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;
}

// Turn off reference selection mode
onButtonReference(false);
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;
}
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;

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));
}
}
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);
}
}

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*)));

Gui::Selection().clearSelection();
updateUI();
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)
Expand All @@ -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) {
Expand Down
8 changes: 5 additions & 3 deletions src/Mod/Fem/Gui/TaskFemConstraintForce.h
Expand Up @@ -33,6 +33,7 @@
#include "ViewProviderFemConstraintForce.h"

#include <QKeyEvent>
#include <QListWidgetItem>

class Ui_TaskFemConstraintForce;

Expand All @@ -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;
Expand All @@ -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:
Expand Down

0 comments on commit 325b31a

Please sign in to comment.