FEM: change behavior of Force dialog to the one of all other constraint dialogs
This commit is contained in:
committed by
Bernd Hahnebach
parent
2f58af7af6
commit
4c368c7c21
@@ -50,9 +50,6 @@
|
||||
#include "ui_TaskFemConstraintDisplacement.h"
|
||||
#include <App/Application.h>
|
||||
#include <Gui/Command.h>
|
||||
|
||||
|
||||
|
||||
#include <Gui/Selection.h>
|
||||
#include <Gui/SelectionFilter.h>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user