+ Advanced options for different meshing algorithms

This commit is contained in:
wmayer
2013-11-07 02:16:33 +01:00
parent e28f387b9e
commit c57ab85991
7 changed files with 665 additions and 167 deletions

View File

@@ -135,30 +135,111 @@ wireFromSegment(PyObject *self, PyObject *args)
}
static PyObject *
meshFromShape(PyObject *self, PyObject *args)
meshFromShape(PyObject *self, PyObject *args, PyObject* kwds)
{
PyObject *shape;
float maxLength=1.0f/*0.5f*/;
float maxArea=0/*1.0f*/;
float localLen=0/*0.1f*/;
float deflection=0/*0.01f*/;
if (!PyArg_ParseTuple(args, "O!|ffff", &(Part::TopoShapePy::Type), &shape,
&maxLength,&maxArea,&localLen,&deflection))
return 0;
try {
MeshPart::Mesher mesher(static_cast<Part::TopoShapePy*>(shape)->getTopoShapePtr()->_Shape);
mesher.setMaxLength(maxLength);
mesher.setMaxArea(maxArea);
mesher.setLocalLength(localLen);
mesher.setDeflection(deflection);
mesher.setRegular(true);
return new Mesh::MeshPy(mesher.createMesh());
PyObject *shape;
static char* kwds_maxLength[] = {"Shape", "MaxLength",NULL};
PyErr_Clear();
double maxLength=0;
if (PyArg_ParseTupleAndKeywords(args, kwds, "O!d", kwds_maxLength,
&(Part::TopoShapePy::Type), &shape, &maxLength)) {
MeshPart::Mesher mesher(static_cast<Part::TopoShapePy*>(shape)->getTopoShapePtr()->_Shape);
mesher.setMaxLength(maxLength);
mesher.setRegular(true);
return new Mesh::MeshPy(mesher.createMesh());
}
static char* kwds_maxArea[] = {"Shape", "MaxArea",NULL};
PyErr_Clear();
double maxArea=0;
if (PyArg_ParseTupleAndKeywords(args, kwds, "O!d", kwds_maxArea,
&(Part::TopoShapePy::Type), &shape, &maxArea)) {
MeshPart::Mesher mesher(static_cast<Part::TopoShapePy*>(shape)->getTopoShapePtr()->_Shape);
mesher.setMaxArea(maxArea);
mesher.setRegular(true);
return new Mesh::MeshPy(mesher.createMesh());
}
static char* kwds_localLen[] = {"Shape", "LocalLength",NULL};
PyErr_Clear();
double localLen=0;
if (PyArg_ParseTupleAndKeywords(args, kwds, "O!d", kwds_localLen,
&(Part::TopoShapePy::Type), &shape, &localLen)) {
MeshPart::Mesher mesher(static_cast<Part::TopoShapePy*>(shape)->getTopoShapePtr()->_Shape);
mesher.setLocalLength(localLen);
mesher.setRegular(true);
return new Mesh::MeshPy(mesher.createMesh());
}
static char* kwds_deflection[] = {"Shape", "Deflection",NULL};
PyErr_Clear();
double deflection=0;
if (PyArg_ParseTupleAndKeywords(args, kwds, "O!d", kwds_deflection,
&(Part::TopoShapePy::Type), &shape, &deflection)) {
MeshPart::Mesher mesher(static_cast<Part::TopoShapePy*>(shape)->getTopoShapePtr()->_Shape);
mesher.setDeflection(deflection);
mesher.setRegular(true);
return new Mesh::MeshPy(mesher.createMesh());
}
static char* kwds_minmaxLen[] = {"Shape", "MinLength","MaxLength",NULL};
PyErr_Clear();
double minLen=0, maxLen=0;
if (PyArg_ParseTupleAndKeywords(args, kwds, "O!dd", kwds_minmaxLen,
&(Part::TopoShapePy::Type), &shape, &minLen, &maxLen)) {
MeshPart::Mesher mesher(static_cast<Part::TopoShapePy*>(shape)->getTopoShapePtr()->_Shape);
mesher.setMinMaxLengths(minLen, maxLen);
mesher.setRegular(true);
return new Mesh::MeshPy(mesher.createMesh());
}
static char* kwds_fineness[] = {"Shape", "Fineness", "SecondOrder", "Optimize", "AllowQuad",NULL};
PyErr_Clear();
int fineness=0, secondOrder=0, optimize=1, allowquad=0;
if (PyArg_ParseTupleAndKeywords(args, kwds, "O!i|iii", kwds_fineness,
&(Part::TopoShapePy::Type), &shape, &fineness,
&secondOrder, &optimize, &allowquad)) {
MeshPart::Mesher mesher(static_cast<Part::TopoShapePy*>(shape)->getTopoShapePtr()->_Shape);
mesher.setFineness(fineness);
mesher.setSecondOrder(secondOrder > 0);
mesher.setOptimize(optimize > 0);
mesher.setQuadAllowed(allowquad > 0);
return new Mesh::MeshPy(mesher.createMesh());
}
static char* kwds_user[] = {"Shape", "GrowthRate", "SegPerEdge", "SegPerRadius", "SecondOrder", "Optimize", "AllowQuad",NULL};
PyErr_Clear();
double growthRate=0, nbSegPerEdge=0, nbSegPerRadius=0;
if (PyArg_ParseTupleAndKeywords(args, kwds, "O!|dddiii", kwds_user,
&(Part::TopoShapePy::Type), &shape,
&growthRate, &nbSegPerEdge, &nbSegPerRadius,
&secondOrder, &optimize, &allowquad)) {
MeshPart::Mesher mesher(static_cast<Part::TopoShapePy*>(shape)->getTopoShapePtr()->_Shape);
mesher.setGrowthRate(growthRate);
mesher.setNbSegPerEdge(nbSegPerEdge);
mesher.setNbSegPerRadius(nbSegPerRadius);
mesher.setSecondOrder(secondOrder > 0);
mesher.setOptimize(optimize > 0);
mesher.setQuadAllowed(allowquad > 0);
return new Mesh::MeshPy(mesher.createMesh());
}
PyErr_Clear();
if (PyArg_ParseTuple(args, "O!", &(Part::TopoShapePy::Type), &shape)) {
MeshPart::Mesher mesher(static_cast<Part::TopoShapePy*>(shape)->getTopoShapePtr()->_Shape);
mesher.setRegular(true);
return new Mesh::MeshPy(mesher.createMesh());
}
}
catch (const Base::Exception& e) {
PyErr_SetString(PyExc_Exception, e.what());
return 0;
}
PyErr_SetString(PyExc_Exception,"Wrong arguments");
return 0;
}
/* registration table */
@@ -166,7 +247,7 @@ struct PyMethodDef MeshPart_methods[] = {
{"loftOnCurve",loftOnCurve, METH_VARARGS, loft_doc},
{"wireFromSegment",wireFromSegment, METH_VARARGS,
"Create wire(s) from boundary of segment"},
{"meshFromShape",meshFromShape, METH_VARARGS,
{"meshFromShape",(PyCFunction)meshFromShape, METH_VARARGS|METH_KEYWORDS,
"Create mesh from shape"},
{NULL, NULL} /* end of table marker */
};

View File

@@ -90,7 +90,9 @@ int MeshingOutput::sync()
Mesher::Mesher(const TopoDS_Shape& s)
: shape(s), maxLength(0), maxArea(0), localLength(0),
deflection(0), minLen(0), maxLen(0), regular(false)
deflection(0), minLen(0), maxLen(0), regular(false),
fineness(5), growthRate(0), nbSegPerEdge(0), nbSegPerRadius(0),
secondOrder(false), optimize(true), allowquad(false)
{
}
@@ -112,37 +114,22 @@ Mesh::MeshObject* Mesher::createMesh() const
#if defined(_MSC_VER)
NETGENPlugin_Hypothesis_2D* hyp2d = new NETGENPlugin_Hypothesis_2D(hyp++,0,meshgen);
//TODO: Try to find values so that we get similar results as with Mefisto meshing
double growth = 0;
if (maxLength > 0 && localLength > 0) {
growth = std::min<double>(maxLength, localLength);
if (fineness >=0 && fineness < 5) {
hyp2d->SetFineness(NETGENPlugin_Hypothesis_2D::Fineness(fineness));
}
else if (maxLength > 0) {
growth = maxLength;
}
else if (localLength > 0) {
growth = localLength;
// user defined values
else {
if (growthRate > 0)
hyp2d->SetGrowthRate(growthRate);
if (nbSegPerEdge > 0)
hyp2d->SetNbSegPerEdge(nbSegPerEdge);
if (nbSegPerRadius > 0)
hyp2d->SetNbSegPerRadius(nbSegPerRadius);
}
if (growth == 0.0)
hyp2d->SetFineness(NETGENPlugin_Hypothesis_2D::Moderate);
else if (growth <= 0.1)
hyp2d->SetFineness(NETGENPlugin_Hypothesis_2D::VeryFine);
else if (growth <= 0.2f)
hyp2d->SetFineness(NETGENPlugin_Hypothesis_2D::Fine);
else if (growth <= 0.5f)
hyp2d->SetFineness(NETGENPlugin_Hypothesis_2D::Moderate);
else if (growth <= 0.7f)
hyp2d->SetFineness(NETGENPlugin_Hypothesis_2D::Coarse);
else
hyp2d->SetFineness(NETGENPlugin_Hypothesis_2D::VeryCoarse);
//hyp2d->SetGrowthRate(growth);
//hyp2d->SetNbSegPerEdge(5);
//hyp2d->SetNbSegPerRadius(10);
hyp2d->SetQuadAllowed(false);
hyp2d->SetOptimize(true);
hyp2d->SetSecondOrder(true); // apply bisecting to create four triangles out of one
hyp2d->SetQuadAllowed(allowquad);
hyp2d->SetOptimize(optimize);
hyp2d->SetSecondOrder(secondOrder); // apply bisecting to create four triangles out of one
hypoth.push_back(hyp2d);
NETGENPlugin_NETGEN_2D* alg2d = new NETGENPlugin_NETGEN_2D(hyp++,0,meshgen);
@@ -285,6 +272,53 @@ Mesh::MeshObject* Mesher::createMesh() const
faces.push_back(f3);
faces.push_back(f4);
}
#if 0 // FIXME: how does the structure look like?
else if (aFace->NbNodes() == 8) {
MeshCore::MeshFacet f1, f2, f3, f4, f5, f6;
const SMDS_MeshNode* node0 = aFace->GetNode(0);
const SMDS_MeshNode* node1 = aFace->GetNode(1);
const SMDS_MeshNode* node2 = aFace->GetNode(2);
const SMDS_MeshNode* node3 = aFace->GetNode(3);
const SMDS_MeshNode* node4 = aFace->GetNode(4);
const SMDS_MeshNode* node5 = aFace->GetNode(5);
const SMDS_MeshNode* node6 = aFace->GetNode(5);
const SMDS_MeshNode* node7 = aFace->GetNode(5);
f1._aulPoints[0] = mapNodeIndex[node0];
f1._aulPoints[1] = mapNodeIndex[node4];
f1._aulPoints[2] = mapNodeIndex[node7];
f2._aulPoints[0] = mapNodeIndex[node1];
f2._aulPoints[1] = mapNodeIndex[node5];
f2._aulPoints[2] = mapNodeIndex[node4];
f3._aulPoints[0] = mapNodeIndex[node2];
f3._aulPoints[1] = mapNodeIndex[node6];
f3._aulPoints[2] = mapNodeIndex[node5];
f4._aulPoints[0] = mapNodeIndex[node3];
f4._aulPoints[1] = mapNodeIndex[node7];
f4._aulPoints[2] = mapNodeIndex[node6];
f5._aulPoints[0] = mapNodeIndex[node4];
f5._aulPoints[1] = mapNodeIndex[node6];
f5._aulPoints[2] = mapNodeIndex[node7];
f6._aulPoints[0] = mapNodeIndex[node4];
f6._aulPoints[1] = mapNodeIndex[node5];
f6._aulPoints[2] = mapNodeIndex[node6];
faces.push_back(f1);
faces.push_back(f2);
faces.push_back(f3);
faces.push_back(f4);
faces.push_back(f5);
faces.push_back(f6);
}
#endif
else {
Base::Console().Warning("Face with %d nodes ignored\n", aFace->NbNodes());
}
}
// clean up

View File

@@ -37,6 +37,8 @@ public:
Mesher(const TopoDS_Shape&);
~Mesher();
/** @name Mefisto settings */
//@{
void setMaxLength(double s)
{ maxLength = s; }
double getMaxLength() const
@@ -61,6 +63,39 @@ public:
{ regular = s; }
bool isRegular() const
{ return regular; }
//@}
/** @name Netgen settings */
//@{
void setFineness(int s)
{ fineness = s; }
int getFineness() const
{ return fineness; }
void setGrowthRate(double r)
{ growthRate = r; }
double getGrowthRate() const
{ return growthRate; }
void setNbSegPerEdge(double v)
{ nbSegPerEdge = v;}
double getNbSegPerEdge() const
{ return nbSegPerEdge; }
void setNbSegPerRadius(double v)
{ nbSegPerRadius = v; }
double getNbSegPerRadius() const
{ return nbSegPerRadius; }
void setSecondOrder(bool on)
{ secondOrder = on; }
bool getSecondOrder() const
{ return secondOrder; }
void setOptimize(bool on)
{ optimize = on;}
bool getOptimize() const
{ return optimize; }
void setQuadAllowed(bool on)
{ allowquad = on;}
bool isQuadAllowed() const
{ return allowquad; }
//@}
Mesh::MeshObject* createMesh() const;
@@ -72,6 +107,13 @@ private:
double deflection;
double minLen, maxLen;
bool regular;
int fineness;
double growthRate;
double nbSegPerEdge;
double nbSegPerRadius;
bool secondOrder;
bool optimize;
bool allowquad;
};
class MeshingOutput : public std::streambuf

View File

@@ -4,6 +4,10 @@ else(MSVC)
add_definitions(-DHAVE_LIMITS_H -DHAVE_CONFIG_H)
endif(MSVC)
if(FREECAD_BUILD_FEM_NETGEN)
add_definitions(-DHAVE_NETGEN)
endif(FREECAD_BUILD_FEM_NETGEN)
include_directories(
${CMAKE_SOURCE_DIR}/src
${CMAKE_CURRENT_BINARY_DIR}

View File

@@ -49,6 +49,31 @@ Tessellation::Tessellation(QWidget* parent)
: QWidget(parent), ui(new Ui_Tessellation)
{
ui->setupUi(this);
buttonGroup = new QButtonGroup(this);
buttonGroup->addButton(ui->radioButtonStandard, 0);
buttonGroup->addButton(ui->radioButtonMefisto, 1);
buttonGroup->addButton(ui->radioButtonNetgen, 2);
connect(buttonGroup, SIGNAL(buttonClicked(int)),
this, SLOT(meshingMethod(int)));
// set the standard method
ui->radioButtonStandard->setChecked(true);
ui->comboFineness->setCurrentIndex(2);
on_comboFineness_currentIndexChanged(2);
#if defined (_MSC_VER)
ui->radioButtonMefisto->setDisabled(true);
#else
ui->radioButtonMefisto->setChecked(true);
#endif
#if !defined (HAVE_NETGEN)
ui->radioButtonNetgen->setDisabled(true);
#else
ui->radioButtonNetgen->setChecked(true);
#endif
meshingMethod(buttonGroup->checkedId());
Gui::Command::doCommand(Gui::Command::Doc, "import Mesh, MeshPart");
findShapes();
}
@@ -57,24 +82,73 @@ Tessellation::~Tessellation()
{
}
void Tessellation::on_checkSimpleMethod_toggled(bool on)
void Tessellation::meshingMethod(int id)
{
if (!on) {
if (ui->checkMaxEdgeLength->isChecked()) {
ui->checkMaxEdgeLength->setEnabled(true);
ui->spinMaxEdgeLength->setEnabled(true);
}
ui->stackedWidget->setCurrentIndex(id);
}
void Tessellation::on_comboFineness_currentIndexChanged(int index)
{
if (index == 5) {
ui->doubleGrading->setEnabled(true);
ui->spinEdgeElements->setEnabled(true);
ui->spinCurvatureElements->setEnabled(true);
}
else {
ui->checkMaxEdgeLength->setEnabled(false);
ui->spinMaxEdgeLength->setEnabled(false);
ui->doubleGrading->setEnabled(false);
ui->spinEdgeElements->setEnabled(false);
ui->spinCurvatureElements->setEnabled(false);
}
switch (index) {
case 0: // Very coarse
ui->doubleGrading->setValue(0.7);
ui->spinEdgeElements->setValue(0.3);
ui->spinCurvatureElements->setValue(1.0);
break;
case 1: // Coarse
ui->doubleGrading->setValue(0.5);
ui->spinEdgeElements->setValue(0.5);
ui->spinCurvatureElements->setValue(1.5);
break;
case 2: // Moderate
ui->doubleGrading->setValue(0.3);
ui->spinEdgeElements->setValue(1.0);
ui->spinCurvatureElements->setValue(2.0);
break;
case 3: // Fine
ui->doubleGrading->setValue(0.2);
ui->spinEdgeElements->setValue(2.0);
ui->spinCurvatureElements->setValue(3.0);
break;
case 4: // Very fine
ui->doubleGrading->setValue(0.1);
ui->spinEdgeElements->setValue(3.0);
ui->spinCurvatureElements->setValue(5.0);
break;
default:
break;
}
}
void Tessellation::on_checkSecondOrder_toggled(bool on)
{
if (on)
ui->checkQuadDominated->setChecked(false);
}
void Tessellation::on_checkQuadDominated_toggled(bool on)
{
if (on)
ui->checkSecondOrder->setChecked(false);
}
void Tessellation::changeEvent(QEvent *e)
{
if (e->type() == QEvent::LanguageChange) {
int index = ui->comboFineness->currentIndex();
ui->retranslateUi(this);
ui->comboFineness->setCurrentIndex(index);
}
QWidget::changeEvent(e);
}
@@ -123,7 +197,7 @@ void Tessellation::findShapes()
}
}
ui->spinMaxEdgeLength->setValue(edgeLen/10);
ui->spinMaximumEdgeLength->setValue(edgeLen/10);
if (foundSelection)
ui->treeWidget->hide();
}
@@ -147,17 +221,7 @@ bool Tessellation::accept()
QString shape, label;
Gui::WaitCursor wc;
bool simple = ui->checkSimpleMethod->isChecked();
double devFace = ui->spinDeviation->value();
if (!ui->spinDeviation->isEnabled()) {
if (simple)
devFace = 0.1;
else
devFace = 0;
}
double maxEdge = ui->spinMaxEdgeLength->value();
if (!ui->spinMaxEdgeLength->isEnabled())
maxEdge = 0;
int method = buttonGroup->checkedId();
activeDoc->openTransaction("Meshing");
QList<QTreeWidgetItem *> items = ui->treeWidget->selectedItems();
@@ -167,32 +231,81 @@ bool Tessellation::accept()
label = (*it)->text(0);
QString cmd;
if (simple) {
if (method == 0) { // Standard
double devFace = ui->spinSurfaceDeviation->value();
cmd = QString::fromAscii(
"__doc__=FreeCAD.getDocument(\"%1\")\n"
"__mesh__=__doc__.addObject(\"Mesh::Feature\",\"Mesh\")\n"
"__mesh__.Mesh=Mesh.Mesh(__doc__.getObject(\"%2\").Shape.tessellate(%3))\n"
"__mesh__.Label=\"%4 (Meshed)\"\n"
"__mesh__.ViewObject.CreaseAngle=25.0\n"
"del __doc__, __mesh__\n")
.arg(this->document)
.arg(shape)
.arg(devFace)
.arg(label);
}
else {
else if (method == 1) { // Mefisto
double maxEdge = ui->spinMaximumEdgeLength->value();
if (!ui->spinMaximumEdgeLength->isEnabled())
maxEdge = 0;
cmd = QString::fromAscii(
"__doc__=FreeCAD.getDocument(\"%1\")\n"
"__mesh__=__doc__.addObject(\"Mesh::Feature\",\"Mesh\")\n"
"__mesh__.Mesh=MeshPart.meshFromShape(__doc__.getObject(\"%2\").Shape,%3,0,0,%4)\n"
"__mesh__.Label=\"%5 (Meshed)\"\n"
"__mesh__.Mesh=MeshPart.meshFromShape(Shape=__doc__.getObject(\"%2\").Shape,MaxLength=%3)\n"
"__mesh__.Label=\"%4 (Meshed)\"\n"
"__mesh__.ViewObject.CreaseAngle=25.0\n"
"del __doc__, __mesh__\n")
.arg(this->document)
.arg(shape)
.arg(maxEdge)
.arg(devFace)
.arg(label);
}
else if (method == 2) { // Netgen
int fineness = ui->comboFineness->currentIndex();
double growthRate = ui->doubleGrading->value();
double nbSegPerEdge = ui->spinEdgeElements->value();
double nbSegPerRadius = ui->spinCurvatureElements->value();
bool secondOrder = ui->checkSecondOrder->isChecked();
bool optimize = ui->checkOptimizeSurface->isChecked();
bool allowquad = ui->checkQuadDominated->isChecked();
if (fineness < 5) {
cmd = QString::fromAscii(
"__doc__=FreeCAD.getDocument(\"%1\")\n"
"__mesh__=__doc__.addObject(\"Mesh::Feature\",\"Mesh\")\n"
"__mesh__.Mesh=MeshPart.meshFromShape(Shape=__doc__.getObject(\"%2\").Shape,"
"Fineness=%3,SecondOrder=%4,Optimize=%5,AllowQuad=%6)\n"
"__mesh__.Label=\"%7 (Meshed)\"\n"
"__mesh__.ViewObject.CreaseAngle=25.0\n"
"del __doc__, __mesh__\n")
.arg(this->document)
.arg(shape)
.arg(fineness)
.arg(secondOrder ? 1 : 0)
.arg(optimize ? 1 : 0)
.arg(allowquad ? 1 : 0)
.arg(label);
}
else {
cmd = QString::fromAscii(
"__doc__=FreeCAD.getDocument(\"%1\")\n"
"__mesh__=__doc__.addObject(\"Mesh::Feature\",\"Mesh\")\n"
"__mesh__.Mesh=MeshPart.meshFromShape(Shape=__doc__.getObject(\"%2\").Shape,"
"GrowthRate=%3,SegPerEdge=%4,SegPerRadius=%5,SecondOrder=%6,Optimize=%7,AllowQuad=%8)\n"
"__mesh__.Label=\"%9 (Meshed)\"\n"
"__mesh__.ViewObject.CreaseAngle=25.0\n"
"del __doc__, __mesh__\n")
.arg(this->document)
.arg(shape)
.arg(growthRate)
.arg(nbSegPerEdge)
.arg(nbSegPerRadius)
.arg(secondOrder ? 1 : 0)
.arg(optimize ? 1 : 0)
.arg(allowquad ? 1 : 0)
.arg(label);
}
}
Gui::Command::doCommand(Gui::Command::Doc, (const char*)cmd.toAscii());
}
activeDoc->commitTransaction();

View File

@@ -29,6 +29,8 @@
#include <Gui/Selection.h>
#include <memory>
class QButtonGroup;
namespace MeshPartGui {
class Ui_Tessellation;
@@ -48,10 +50,14 @@ private:
void findShapes();
private Q_SLOTS:
void on_checkSimpleMethod_toggled(bool);
void meshingMethod(int id);
void on_comboFineness_currentIndexChanged(int);
void on_checkSecondOrder_toggled(bool);
void on_checkQuadDominated_toggled(bool);
private:
QString document;
QButtonGroup* buttonGroup;
std::auto_ptr<Ui_Tessellation> ui;
};

View File

@@ -6,14 +6,14 @@
<rect>
<x>0</x>
<y>0</y>
<width>329</width>
<height>431</height>
<width>363</width>
<height>508</height>
</rect>
</property>
<property name="windowTitle">
<string>Tessellation</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<layout class="QGridLayout" name="gridLayout_7">
<item row="0" column="0">
<widget class="QTreeWidget" name="treeWidget">
<property name="selectionMode">
@@ -27,73 +27,312 @@
</widget>
</item>
<item row="1" column="0">
<widget class="QGroupBox" name="groupBox">
<widget class="QGroupBox" name="groupBoxMeshingOptions">
<property name="title">
<string>Settings</string>
<string>Meshing options</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<layout class="QGridLayout" name="gridLayout_6">
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QCheckBox" name="checkDeviation">
<property name="text">
<string>Surface deviation:</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QDoubleSpinBox" name="spinDeviation">
<property name="decimals">
<number>3</number>
</property>
<property name="minimum">
<double>0.001000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QCheckBox" name="checkSimpleMethod">
<property name="text">
<string>Use simplified mesh generation method</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="checkMaxEdgeLength">
<property name="text">
<string>Max. edge length:</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="spinMaxEdgeLength">
<property name="decimals">
<number>3</number>
</property>
<property name="minimum">
<double>0.001000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
</layout>
<widget class="QRadioButton" name="radioButtonStandard">
<property name="text">
<string>Standard</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QRadioButton" name="radioButtonMefisto">
<property name="text">
<string>Mefisto</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QRadioButton" name="radioButtonNetgen">
<property name="text">
<string>Netgen</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="3">
<widget class="QStackedWidget" name="stackedWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="pageStandard">
<layout class="QGridLayout" name="gridLayout_8">
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="labelSurfaceDeviation">
<property name="text">
<string>Surface deviation:</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="spinSurfaceDeviation">
<property name="decimals">
<number>3</number>
</property>
<property name="minimum">
<double>0.001000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>0.100000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>189</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="pageMefisto">
<layout class="QGridLayout" name="gridLayout_9">
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QCheckBox" name="checkMaximumEdgeLength">
<property name="text">
<string>Maximum edge length:</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="spinMaximumEdgeLength">
<property name="decimals">
<number>3</number>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>189</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="pageNetgen">
<layout class="QGridLayout" name="gridLayout_5">
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<widget class="QLabel" name="labelFineness">
<property name="text">
<string>Fineness:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="comboFineness">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="currentIndex">
<number>2</number>
</property>
<item>
<property name="text">
<string>Very coarse</string>
</property>
</item>
<item>
<property name="text">
<string>Coarse</string>
</property>
</item>
<item>
<property name="text">
<string>Moderate</string>
</property>
</item>
<item>
<property name="text">
<string>Fine</string>
</property>
</item>
<item>
<property name="text">
<string>Very fine</string>
</property>
</item>
<item>
<property name="text">
<string>User defined</string>
</property>
</item>
</widget>
</item>
<item row="1" column="1">
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="labelGrading">
<property name="text">
<string>Mesh size grading:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QDoubleSpinBox" name="doubleGrading">
<property name="enabled">
<bool>false</bool>
</property>
<property name="decimals">
<number>1</number>
</property>
<property name="minimum">
<double>0.100000000000000</double>
</property>
<property name="maximum">
<double>1.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>0.300000000000000</double>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelEdgeElements">
<property name="text">
<string>Elements per edge:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="spinEdgeElements">
<property name="enabled">
<bool>false</bool>
</property>
<property name="decimals">
<number>1</number>
</property>
<property name="minimum">
<double>0.200000000000000</double>
</property>
<property name="maximum">
<double>10.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="labelCurvatureElements">
<property name="text">
<string>Elements per curvature radius:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="spinCurvatureElements">
<property name="enabled">
<bool>false</bool>
</property>
<property name="decimals">
<number>1</number>
</property>
<property name="minimum">
<double>0.200000000000000</double>
</property>
<property name="maximum">
<double>10.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>2.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0" colspan="2">
<widget class="QCheckBox" name="checkOptimizeSurface">
<property name="text">
<string>Optimize surface</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QCheckBox" name="checkSecondOrder">
<property name="text">
<string>Second order elements</string>
</property>
</widget>
</item>
<item row="4" column="0" colspan="2">
<widget class="QCheckBox" name="checkQuadDominated">
<property name="text">
<string>Quad dominated</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>37</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
@@ -102,43 +341,22 @@
</widget>
<tabstops>
<tabstop>treeWidget</tabstop>
<tabstop>checkDeviation</tabstop>
<tabstop>spinDeviation</tabstop>
<tabstop>checkSimpleMethod</tabstop>
<tabstop>checkMaxEdgeLength</tabstop>
<tabstop>spinMaxEdgeLength</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>checkDeviation</sender>
<sender>checkMaximumEdgeLength</sender>
<signal>toggled(bool)</signal>
<receiver>spinDeviation</receiver>
<receiver>spinMaximumEdgeLength</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>104</x>
<y>359</y>
<x>81</x>
<y>343</y>
</hint>
<hint type="destinationlabel">
<x>308</x>
<y>360</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkMaxEdgeLength</sender>
<signal>toggled(bool)</signal>
<receiver>spinMaxEdgeLength</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>112</x>
<y>396</y>
</hint>
<hint type="destinationlabel">
<x>197</x>
<y>399</y>
<x>208</x>
<y>350</y>
</hint>
</hints>
</connection>