[FEM] make the Fluid Boundary dialog behave like the other dialogs

- allows highlighting and multiple selection
This commit is contained in:
donovaly
2020-02-21 02:41:55 +01:00
committed by Bernd Hahnebach
parent 950943f15e
commit ec213a4d98
3 changed files with 695 additions and 568 deletions

View File

@@ -156,23 +156,27 @@ TaskFemConstraintFluidBoundary::TaskFemConstraintFluidBoundary(ViewProviderFemCo
connect(ui->comboThermalBoundaryType, SIGNAL(currentIndexChanged(int)),
this, SLOT(onThermalBoundaryTypeChanged(void)));
connect(ui->buttonReference, SIGNAL(pressed()),
this, SLOT(onButtonReference()));
connect(ui->buttonDirection, SIGNAL(pressed()),
this, SLOT(onButtonDirection()));
connect(ui->checkReverse, SIGNAL(toggled(bool)),
this, SLOT(onCheckReverse(bool)));
connect(ui->listReferences, SIGNAL(itemClicked(QListWidgetItem*)),
this, SLOT(setSelection(QListWidgetItem*)));
this->groupLayout()->addWidget(proxy);
// Temporarily prevent unnecessary feature recomputes
ui->spinBoundaryValue->blockSignals(true);
ui->listReferences->blockSignals(true);
// boundaryType and subType combo signal is Temporarily prevented in initComboBox()
ui->buttonReference->blockSignals(true);
ui->buttonDirection->blockSignals(true);
ui->checkReverse->blockSignals(true);
//Selection buttons
connect(ui->btnAdd, SIGNAL(clicked()), this, SLOT(addToSelection()));
connect(ui->btnRemove, SIGNAL(clicked()), this, SLOT(removeFromSelection()));
// Get the feature data
Fem::ConstraintFluidBoundary* pcConstraint = static_cast<Fem::ConstraintFluidBoundary*>(ConstraintView->getObject());
@@ -310,11 +314,11 @@ TaskFemConstraintFluidBoundary::TaskFemConstraintFluidBoundary(ViewProviderFemCo
ui->checkReverse->setVisible(true); // it is still useful to swap direction of an edge
ui->listReferences->blockSignals(false);
ui->buttonReference->blockSignals(false);
ui->spinBoundaryValue->blockSignals(false);
ui->buttonDirection->blockSignals(false);
ui->checkReverse->blockSignals(false);
updateSelectionUI();
updateUI();
}
const Fem::FemSolverObject* TaskFemConstraintFluidBoundary::getFemSolver(void) const
@@ -502,122 +506,6 @@ void TaskFemConstraintFluidBoundary::updateThermalBoundaryUI()
}
}
void TaskFemConstraintFluidBoundary::updateSelectionUI()
{
if (ui->listReferences->model()->rowCount() == 0) {
// Go into reference selection mode if no reference has been selected yet
onButtonReference(true);
return;
}
/** not needed for fluid boundary, as it must be Face for 3D part,
* Edge type boundary is needed for 2D CFD, but it is not supported yet
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 TaskFemConstraintFluidBoundary::onSelectionChanged(const Gui::SelectionChanges& msg)
{
if (msg.Type == Gui::SelectionChanges::AddSelection) {
// Don't allow selection in other document
if (strcmp(msg.pDocName, ConstraintView->getObject()->getDocument()->getName()) != 0)
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::ConstraintFluidBoundary* pcConstraint = static_cast<Fem::ConstraintFluidBoundary*>(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());
//* string conversion: <Base/Tools.h> toStdString()/fromStdString()
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" && dimension == 3)) {
QMessageBox::warning(this, tr("Selection error"), tr("Only faces can be picked for fluid boundary of 3D geometry"));
return;
}
if ((subName.substr(0,4) != "Edge" && dimension == 2)) {
QMessageBox::warning(this, tr("Selection error"), tr("Only edges can be picked for fluid boundary of 2D geometry"));
return;
}
}
// Avoid duplicates
std::size_t pos = 0;
for (; pos < Objects.size(); pos++) {
if (obj == Objects[pos]) {
break;
}
}
if (pos != Objects.size()) {
if (subName == SubElements[pos]) {
return;
}
}
// 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) { // select direction, can be Edge or Face(Face normal)
if (subName.substr(0,4) == "Face" && dimension ==3) {
if (!Fem::Tools::isPlanar(TopoDS::Face(ref))) {
QMessageBox::warning(this, tr("Selection error"), tr("Only planar faces can be picked for 3D"));
return;
}
}
else if (subName.substr(0,4) == "Edge") { // 2D or 3D can use edge as direction vector
if (!Fem::Tools::isLinear(TopoDS::Edge(ref))) {
QMessageBox::warning(this, tr("Selection error"), tr("Only planar edges can be picked for 2D"));
return;
}
}
else {
QMessageBox::warning(this, tr("Selection error"), tr("Only faces for 3D part or edges for 2D 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();
updateSelectionUI();
// recompute (redrawing has been called by FemConstraint base class? )
//bool ret = pcConstraint->recomputeFeature(); // not needed
}
}
void TaskFemConstraintFluidBoundary::onBoundaryTypeChanged(void)
{
Fem::ConstraintFluidBoundary* pcConstraint = static_cast<Fem::ConstraintFluidBoundary*>(ConstraintView->getObject());
@@ -660,25 +548,70 @@ void TaskFemConstraintFluidBoundary::onThermalBoundaryTypeChanged(void)
}
void TaskFemConstraintFluidBoundary::onReferenceDeleted() {
int row = ui->listReferences->currentIndex().row();
TaskFemConstraint::onReferenceDeleted(row);
ui->listReferences->model()->removeRow(row);
ui->listReferences->setCurrentRow(0, QItemSelectionModel::ClearAndSelect);
TaskFemConstraintFluidBoundary::removeFromSelection(); //On right-click face is automatically selected, so just remove
}
void TaskFemConstraintFluidBoundary::onButtonDirection(const bool pressed) {
if (pressed) {
selectionMode = seldir;
} else {
selectionMode = selnone;
// sets the normal vector of the currently selecteed planar face as direction
//get vector of selected objects of active document
std::vector<Gui::SelectionObject> selection = Gui::Selection().getSelectionEx();
if (selection.size() == 0) {
QMessageBox::warning(this, tr("Selection error"), tr("Nothing selected!"));
return;
}
ui->buttonDirection->setChecked(pressed);
Gui::Selection().clearSelection();
/* minor bug: once Direction property(edge link) is cleared in UI, arrow direction is not updated.
Direction property can not be easily setup in C++, see example at the end of this file `accept()`
redraw will only happen once taskpanel is closed,
*/
//pcConstraint->Direction.setValue(pressed);
Fem::ConstraintFluidBoundary* pcConstraint = static_cast<Fem::ConstraintFluidBoundary*>(ConstraintView->getObject());
// we only handle the first selected object
std::vector<Gui::SelectionObject>::iterator selectionElement = selection.begin();
std::string TypeName = static_cast<std::string>(selectionElement->getTypeName());
// we can only handle part objects
if (TypeName.substr(0, 4).compare(std::string("Part")) != 0) {
QMessageBox::warning(this, tr("Selection error"), tr("Selected object is not a part!"));
return;
}
// get the names of the subobjects
std::vector<std::string> subNames = selectionElement->getSubNames();
if (subNames.size() > 1) {
QMessageBox::warning(this, tr("Selection error"), 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<std::string> direction(1, subNamesElement);
App::DocumentObject* obj = ConstraintView->getObject()->getDocument()->getObject(selectionElement->getFeatName());
Part::Feature* feat = static_cast<Part::Feature*>(obj);
TopoDS_Shape ref = feat->Shape.getShape().getSubShape(subNamesElement.c_str());
if (TypeName.substr(0, 4).compare(std::string("Part")) != 0) {
QMessageBox::warning(this, tr("Selection error"), tr("Selected object is not a part!"));
return;
}
if (subNamesElement.substr(0, 4) == "Face") {
if (!Fem::Tools::isPlanar(TopoDS::Face(ref))) {
QMessageBox::warning(this, tr("Selection error"), 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("Selection error"), tr("Only planar edges can be picked for 2D"));
return;
}
}
else {
QMessageBox::warning(this, tr("Selection error"), tr("Only faces for 3D part or edges for 2D can be picked"));
return;
}
// update the direction
pcConstraint->Direction.setValue(obj, direction);
ui->lineDirection->setText(makeRefText(obj, subNamesElement));
//Update UI
updateUI();
}
void TaskFemConstraintFluidBoundary::onCheckReverse(const bool pressed)
@@ -798,6 +731,150 @@ TaskFemConstraintFluidBoundary::~TaskFemConstraintFluidBoundary()
delete ui;
}
void TaskFemConstraintFluidBoundary::addToSelection()
{
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::ConstraintFluidBoundary* pcConstraint = static_cast<Fem::ConstraintFluidBoundary*>(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;
}
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;
}
}
// 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 (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();
}
void TaskFemConstraintFluidBoundary::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::ConstraintFluidBoundary* pcConstraint = static_cast<Fem::ConstraintFluidBoundary*>(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 TaskFemConstraintFluidBoundary::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 TaskFemConstraintFluidBoundary::updateUI()
{
if (ui->listReferences->model()->rowCount() == 0) {
// Go into reference selection mode if no reference has been selected yet
onButtonReference(true);
return;
}
}
bool TaskFemConstraintFluidBoundary::event(QEvent *e)
{
return TaskFemConstraint::KeyEvent(e);

View File

@@ -34,6 +34,7 @@
#include "ViewProviderFemConstraintFluidBoundary.h"
#include <QKeyEvent>
#include <QListWidgetItem>
class Ui_TaskFemConstraintFluidBoundary;
@@ -72,7 +73,7 @@ public:
double getHeatFluxValue(void) const;
double getHTCoeffValue(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;
@@ -86,18 +87,20 @@ private Q_SLOTS:
void onReferenceDeleted(void);
void onButtonDirection(const bool pressed = true);
void onCheckReverse(bool); // consider removing this slot as the UI is hidden
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 updateSelectionUI();
void updateBoundaryTypeUI();
void updateSubtypeUI();
void updateThermalBoundaryUI();
void updateTurbulenceUI();
void updateUI();
private:
Ui_TaskFemConstraintFluidBoundary* ui;

View File

@@ -6,459 +6,506 @@
<rect>
<x>0</x>
<y>0</y>
<width>292</width>
<height>477</height>
<width>330</width>
<height>430</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>330</width>
<height>430</height>
</size>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<layout class="QFormLayout" name="layoutBoundaryType">
<item row="0" column="0">
<widget class="QLabel" name="labelBoundaryType">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Boundary </string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="comboBoundaryType">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelSubtype">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Subtype</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="comboSubtype">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QPushButton" name="buttonReference">
<property name="text">
<string>Add geometry reference</string>
</property>
</widget>
</item>
<item>
<widget class="QListWidget" name="listReferences">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>120</height>
</size>
</property>
<property name="baseSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelHelpText">
<property name="text">
<string>Help text</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="enabled">
<bool>true</bool>
</property>
<property name="currentIndex">
<number>2</number>
</property>
<widget class="QWidget" name="tabBasicBoundary">
<property name="enabled">
<bool>true</bool>
</property>
<attribute name="title">
<string>Tab 1</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="labelBoundaryValue">
<property name="enabled">
<bool>true</bool>
</property>
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QFormLayout" name="layoutBoundaryType">
<item row="0" column="0">
<widget class="QLabel" name="labelBoundaryType">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Value [Unit]</string>
<string>Boundary </string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="layoutBoundaryValue">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QDoubleSpinBox" name="spinBoundaryValue">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="minimum">
<double>-99999.000000000000000</double>
</property>
<property name="maximum">
<double>99999.000000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="layoutDirection">
<item>
<widget class="QPushButton" name="buttonDirection">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Direction </string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineDirection">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>75</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="baseSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="checkReverse">
<property name="enabled">
<bool>true</bool>
</property>
<property name="minimumSize">
<size>
<width>160</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Reverse direction</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>7</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="tabTurbulenceBoundary">
<attribute name="title">
<string>Page</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="labelTurbulenceSpecification">
<property name="text">
<string>Turbulence specification</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboTurbulenceSpecification">
<item row="0" column="1">
<widget class="QComboBox" name="comboBoundaryType">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frame">
<bool>true</bool>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelSubtype">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Subtype</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="comboSubtype">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="lbl_info">
<property name="text">
<string>Select multiple face(s), click Add or Remove</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QPushButton" name="btnAdd">
<property name="text">
<string>Add</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="layoutTurbulenceValue">
<item>
<widget class="QLabel" name="labelTurbulentIntensityValue">
<property name="text">
<string>Intensity </string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="spinTurbulentIntensityValue">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="labelTurbulentLengthValue">
<property name="text">
<string>Length [m]</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="spinTurbulentLengthValue">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="tabThermalBoundary">
<attribute name="title">
<string>Tab 2</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
<widget class="QPushButton" name="btnRemove">
<property name="text">
<string>Remove</string>
</property>
<item row="0" column="0">
<widget class="QLabel" name="labelThermalBoundaryType">
<property name="text">
<string> Type </string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="comboThermalBoundaryType">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelTemperature">
<property name="text">
<string>Temperature[K]</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="spinTemperatureValue">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimum">
<double>-273.149999999999977</double>
</property>
<property name="maximum">
<double>9999.000000000000000</double>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="labelHeatFlux">
<property name="text">
<string>Heat flux [W/m2]</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="labelHTCeoff">
<property name="text">
<string>HT coeff</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QDoubleSpinBox" name="spinHTCoeffValue">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimum">
<double>0.000000000000000</double>
</property>
<property name="maximum">
<double>99999.000000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="spinHeatFluxValue">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimum">
<double>0.000000000000000</double>
</property>
<property name="maximum">
<double>99999.000000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</widget>
</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>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="baseSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelHelpText">
<property name="text">
<string>Help text</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="enabled">
<bool>true</bool>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tabBasicBoundary">
<property name="enabled">
<bool>true</bool>
</property>
<attribute name="title">
<string>Tab 1</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="labelBoundaryValue">
<property name="enabled">
<bool>true</bool>
</property>
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Value [Unit]</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="layoutBoundaryValue">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QDoubleSpinBox" name="spinBoundaryValue">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="minimum">
<double>-99999.000000000000000</double>
</property>
<property name="maximum">
<double>99999.000000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="layoutDirection">
<item>
<widget class="QPushButton" name="buttonDirection">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Select a planar edge or face, then press this button</string>
</property>
<property name="text">
<string>Direction </string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineDirection">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>75</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="baseSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>The direction of the edge or the direction of the
normal vector of the face is used as direction</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="checkReverse">
<property name="enabled">
<bool>true</bool>
</property>
<property name="minimumSize">
<size>
<width>160</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Reverse direction</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>7</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="tabTurbulenceBoundary">
<attribute name="title">
<string>Page</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="labelTurbulenceSpecification">
<property name="text">
<string>Turbulence specification</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboTurbulenceSpecification">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frame">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="layoutTurbulenceValue">
<item>
<widget class="QLabel" name="labelTurbulentIntensityValue">
<property name="text">
<string>Intensity </string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="spinTurbulentIntensityValue">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="labelTurbulentLengthValue">
<property name="text">
<string>Length [m]</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="spinTurbulentLengthValue">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="tabThermalBoundary">
<attribute name="title">
<string>Tab 2</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="labelThermalBoundaryType">
<property name="text">
<string> Type </string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="comboThermalBoundaryType">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelTemperature">
<property name="text">
<string>Temperature[K]</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="spinTemperatureValue">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimum">
<double>-273.149999999999977</double>
</property>
<property name="maximum">
<double>9999.000000000000000</double>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="labelHeatFlux">
<property name="text">
<string>Heat flux [W/m2]</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="labelHTCeoff">
<property name="text">
<string>HT coeff</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QDoubleSpinBox" name="spinHTCoeffValue">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimum">
<double>0.000000000000000</double>
</property>
<property name="maximum">
<double>99999.000000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="spinHeatFluxValue">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimum">
<double>0.000000000000000</double>
</property>
<property name="maximum">
<double>99999.000000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</item>
</layout>
</widget>