RE: Add function to approximate B-Spline from points
This commit is contained in:
@@ -74,6 +74,7 @@ class Module : public Py::ExtensionModule<Module>
|
||||
public:
|
||||
Module() : Py::ExtensionModule<Module>("ReverseEngineering")
|
||||
{
|
||||
add_keyword_method("approxCurve", &Module::approxCurve, "Approximate curve");
|
||||
add_keyword_method("approxSurface",&Module::approxSurface,
|
||||
"approxSurface(Points, UDegree=3, VDegree=3, NbUPoles=6, NbVPoles=6,\n"
|
||||
"Smooth=True, Weight=0.1, Grad=1.0, Bend=0.0, Curv=0.0\n"
|
||||
@@ -159,6 +160,169 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
static std::vector<Base::Vector3d> getPoints(PyObject* pts, bool closed)
|
||||
{
|
||||
std::vector<Base::Vector3d> data;
|
||||
if (PyObject_TypeCheck(pts, &(Points::PointsPy::Type))) {
|
||||
std::vector<Base::Vector3d> normal;
|
||||
auto pypts = static_cast<Points::PointsPy*>(pts);
|
||||
Points::PointKernel* points = pypts->getPointKernelPtr();
|
||||
points->getPoints(data, normal, 0.0);
|
||||
}
|
||||
else {
|
||||
Py::Sequence l(pts);
|
||||
data.reserve(l.size());
|
||||
for (Py::Sequence::iterator it = l.begin(); it != l.end(); ++it) {
|
||||
Py::Tuple t(*it);
|
||||
data.emplace_back(
|
||||
Py::Float(t.getItem(0)),
|
||||
Py::Float(t.getItem(1)),
|
||||
Py::Float(t.getItem(2))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (closed) {
|
||||
if (!data.empty()) {
|
||||
data.push_back(data.front());
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static PyObject* approx1(const Py::Tuple& args, const Py::Dict& kwds)
|
||||
{
|
||||
PyObject* pts {};
|
||||
PyObject* closed = Py_False;
|
||||
int minDegree = 3; // NOLINT
|
||||
int maxDegree = 8; // NOLINT
|
||||
int cont = int(GeomAbs_C2);
|
||||
double tol3d = 1.0e-3; // NOLINT
|
||||
|
||||
static const std::array<const char *, 7> kwds_approx{"Points",
|
||||
"Closed",
|
||||
"MinDegree",
|
||||
"MaxDegree",
|
||||
"Continuity",
|
||||
"Tolerance",
|
||||
nullptr};
|
||||
if (!Base::Wrapped_ParseTupleAndKeywords(args.ptr(), kwds.ptr(), "O|O!iiid", kwds_approx,
|
||||
&pts, &PyBool_Type, &closed, &minDegree,
|
||||
&maxDegree, &cont, &tol3d)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<Base::Vector3d> data = getPoints(pts, Base::asBoolean(closed));
|
||||
|
||||
Part::GeomBSplineCurve curve;
|
||||
curve.approximate(data, minDegree, maxDegree, GeomAbs_Shape(cont), tol3d);
|
||||
return curve.getPyObject();
|
||||
}
|
||||
|
||||
static PyObject* approx2(const Py::Tuple& args, const Py::Dict& kwds)
|
||||
{
|
||||
PyObject* pts {};
|
||||
char* parType {};
|
||||
PyObject* closed = Py_False;
|
||||
int minDegree = 3; // NOLINT
|
||||
int maxDegree = 8; // NOLINT
|
||||
int cont = int(GeomAbs_C2);
|
||||
double tol3d = 1.0e-3; // NOLINT
|
||||
|
||||
static const std::array<const char *, 8> kwds_approx{"Points",
|
||||
"ParametrizationType",
|
||||
"Closed",
|
||||
"MinDegree",
|
||||
"MaxDegree",
|
||||
"Continuity",
|
||||
"Tolerance",
|
||||
nullptr};
|
||||
if (!Base::Wrapped_ParseTupleAndKeywords(args.ptr(), kwds.ptr(), "Os|O!iiid", kwds_approx,
|
||||
&pts, &parType, &PyBool_Type, &closed, &minDegree,
|
||||
&maxDegree, &cont, &tol3d)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<Base::Vector3d> data = getPoints(pts, Base::asBoolean(closed));
|
||||
|
||||
Approx_ParametrizationType pt {Approx_ChordLength};
|
||||
std::string pstr = parType;
|
||||
if (pstr == "Uniform") {
|
||||
pt = Approx_IsoParametric;
|
||||
}
|
||||
else if (pstr == "Centripetal") {
|
||||
pt = Approx_Centripetal;
|
||||
}
|
||||
|
||||
Part::GeomBSplineCurve curve;
|
||||
curve.approximate(data, pt, minDegree, maxDegree, GeomAbs_Shape(cont), tol3d);
|
||||
return curve.getPyObject();
|
||||
}
|
||||
|
||||
static PyObject* approx3(const Py::Tuple& args, const Py::Dict& kwds)
|
||||
{
|
||||
PyObject* pts {};
|
||||
double weight1 {};
|
||||
double weight2 {};
|
||||
double weight3 {};
|
||||
PyObject* closed = Py_False;
|
||||
int maxDegree = 8; // NOLINT
|
||||
int cont = int(GeomAbs_C2);
|
||||
double tol3d = 1.0e-3; // NOLINT
|
||||
|
||||
static const std::array<const char *, 9> kwds_approx{"Points",
|
||||
"Weight1",
|
||||
"Weight2",
|
||||
"Weight3",
|
||||
"Closed",
|
||||
"MaxDegree",
|
||||
"Continuity",
|
||||
"Tolerance",
|
||||
nullptr};
|
||||
if (!Base::Wrapped_ParseTupleAndKeywords(args.ptr(), kwds.ptr(), "Oddd|O!iid", kwds_approx,
|
||||
&pts, &weight1, &weight2, &weight3,
|
||||
&PyBool_Type, &closed,
|
||||
&maxDegree, &cont, &tol3d)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<Base::Vector3d> data = getPoints(pts, Base::asBoolean(closed));
|
||||
|
||||
Part::GeomBSplineCurve curve;
|
||||
curve.approximate(data, weight1, weight2, weight3, maxDegree, GeomAbs_Shape(cont), tol3d);
|
||||
return curve.getPyObject();
|
||||
}
|
||||
|
||||
Py::Object approxCurve(const Py::Tuple& args, const Py::Dict& kwds)
|
||||
{
|
||||
try {
|
||||
using approxFunc = std::function<PyObject*(const Py::Tuple& args, const Py::Dict& kwds)>;
|
||||
|
||||
std::vector<approxFunc> funcs;
|
||||
funcs.emplace_back(approx3);
|
||||
funcs.emplace_back(approx2);
|
||||
funcs.emplace_back(approx1);
|
||||
|
||||
for (const auto& func : funcs) {
|
||||
if (PyObject* py = func(args, kwds)) {
|
||||
return Py::asObject(py);
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
}
|
||||
|
||||
throw Py::ValueError("Wrong arguments ReverseEngineering.approxCurve()");
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
std::string msg = e.what();
|
||||
if (msg.empty()) {
|
||||
msg = "ReverseEngineering.approxCurve() failed";
|
||||
}
|
||||
throw Py::RuntimeError(msg);
|
||||
}
|
||||
}
|
||||
|
||||
Py::Object approxSurface(const Py::Tuple& args, const Py::Dict& kwds)
|
||||
{
|
||||
PyObject *o;
|
||||
|
||||
@@ -23,6 +23,7 @@ qt_create_resource_file(${ReverseEngineering_TR_QRC} ${QM_SRCS})
|
||||
qt_add_resources(ReenGui_QRC_SRCS Resources/ReverseEngineering.qrc ${ReverseEngineering_TR_QRC})
|
||||
|
||||
set(Dialogs_UIC_SRCS
|
||||
FitBSplineCurve.ui
|
||||
FitBSplineSurface.ui
|
||||
Poisson.ui
|
||||
Segmentation.ui
|
||||
@@ -32,6 +33,8 @@ set(Dialogs_UIC_SRCS
|
||||
SET(Dialogs_SRCS
|
||||
${Dialogs_UIC_HDRS}
|
||||
${Dialogs_UIC_SRCS}
|
||||
FitBSplineCurve.cpp
|
||||
FitBSplineCurve.h
|
||||
FitBSplineSurface.cpp
|
||||
FitBSplineSurface.h
|
||||
Poisson.cpp
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
#include <Mod/Points/App/Structured.h>
|
||||
#include <Mod/ReverseEngineering/App/ApproxSurface.h>
|
||||
|
||||
#include "FitBSplineCurve.h"
|
||||
#include "FitBSplineSurface.h"
|
||||
#include "Poisson.h"
|
||||
#include "Segmentation.h"
|
||||
@@ -59,6 +60,39 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
DEF_STD_CMD_A(CmdApproxCurve)
|
||||
|
||||
CmdApproxCurve::CmdApproxCurve()
|
||||
: Command("Reen_ApproxCurve")
|
||||
{
|
||||
sAppModule = "Reen";
|
||||
sGroup = QT_TR_NOOP("Reverse Engineering");
|
||||
sMenuText = QT_TR_NOOP("Approximate B-spline curve...");
|
||||
sToolTipText = QT_TR_NOOP("Approximate a B-spline curve");
|
||||
sWhatsThis = "Reen_ApproxCurve";
|
||||
sStatusTip = sToolTipText;
|
||||
}
|
||||
|
||||
void CmdApproxCurve::activated(int)
|
||||
{
|
||||
App::DocumentObjectT objT;
|
||||
auto obj = Gui::Selection().getObjectsOfType(App::GeoFeature::getClassTypeId());
|
||||
if (obj.size() != 1 || !(obj.at(0)->isDerivedFrom(Points::Feature::getClassTypeId()))) {
|
||||
QMessageBox::warning(Gui::getMainWindow(),
|
||||
qApp->translate("Reen_ApproxSurface", "Wrong selection"),
|
||||
qApp->translate("Reen_ApproxSurface", "Please select a point cloud."));
|
||||
return;
|
||||
}
|
||||
|
||||
objT = obj.front();
|
||||
Gui::Control().showDialog(new ReenGui::TaskFitBSplineCurve(objT));
|
||||
}
|
||||
|
||||
bool CmdApproxCurve::isActive()
|
||||
{
|
||||
return (hasActiveDocument() && !Gui::Control().activeDialog());
|
||||
}
|
||||
|
||||
DEF_STD_CMD_A(CmdApproxSurface)
|
||||
|
||||
CmdApproxSurface::CmdApproxSurface()
|
||||
@@ -648,6 +682,7 @@ bool CmdViewTriangulation::isActive()
|
||||
void CreateReverseEngineeringCommands()
|
||||
{
|
||||
Gui::CommandManager& rcCmdMgr = Gui::Application::Instance->commandManager();
|
||||
rcCmdMgr.addCommand(new CmdApproxCurve());
|
||||
rcCmdMgr.addCommand(new CmdApproxSurface());
|
||||
rcCmdMgr.addCommand(new CmdApproxPlane());
|
||||
rcCmdMgr.addCommand(new CmdApproxCylinder());
|
||||
|
||||
182
src/Mod/ReverseEngineering/Gui/FitBSplineCurve.cpp
Normal file
182
src/Mod/ReverseEngineering/Gui/FitBSplineCurve.cpp
Normal file
@@ -0,0 +1,182 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Werner Mayer <wmayer[at]users.sourceforge.net> *
|
||||
* *
|
||||
* This file is part of FreeCAD. *
|
||||
* *
|
||||
* FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU Lesser General Public License as *
|
||||
* published by the Free Software Foundation, either version 2.1 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* FreeCAD is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with FreeCAD. If not, see *
|
||||
* <https://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
#include <algorithm>
|
||||
#include <QMessageBox>
|
||||
#endif
|
||||
|
||||
#include <Gui/CommandT.h>
|
||||
#include <Gui/WaitCursor.h>
|
||||
|
||||
#include "FitBSplineCurve.h"
|
||||
#include "ui_FitBSplineCurve.h"
|
||||
|
||||
|
||||
using namespace ReenGui;
|
||||
|
||||
class FitBSplineCurveWidget::Private
|
||||
{
|
||||
public:
|
||||
Ui_FitBSplineCurve ui {};
|
||||
App::DocumentObjectT obj {};
|
||||
};
|
||||
|
||||
/* TRANSLATOR ReenGui::FitBSplineCurveWidget */
|
||||
|
||||
FitBSplineCurveWidget::FitBSplineCurveWidget(const App::DocumentObjectT& obj, QWidget* parent)
|
||||
: d(new Private())
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
d->ui.setupUi(this);
|
||||
d->obj = obj;
|
||||
|
||||
// clang-format off
|
||||
connect(d->ui.checkBox, &QCheckBox::toggled,
|
||||
this, &FitBSplineCurveWidget::toggleParametrizationType);
|
||||
connect(d->ui.groupBoxSmooth, &QGroupBox::toggled,
|
||||
this, &FitBSplineCurveWidget::toggleSmoothing);
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
FitBSplineCurveWidget::~FitBSplineCurveWidget()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
void FitBSplineCurveWidget::toggleParametrizationType(bool on)
|
||||
{
|
||||
d->ui.paramType->setEnabled(on);
|
||||
if (on) {
|
||||
d->ui.groupBoxSmooth->setChecked(false);
|
||||
}
|
||||
}
|
||||
|
||||
void FitBSplineCurveWidget::toggleSmoothing(bool on)
|
||||
{
|
||||
if (on) {
|
||||
d->ui.checkBox->setChecked(false);
|
||||
d->ui.paramType->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
bool FitBSplineCurveWidget::accept()
|
||||
{
|
||||
try {
|
||||
tryAccept();
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
Gui::Command::abortCommand();
|
||||
QMessageBox::warning(this, tr("Input error"), QString::fromLatin1(e.what()));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FitBSplineCurveWidget::tryAccept()
|
||||
{
|
||||
QString document = QString::fromStdString(d->obj.getDocumentPython());
|
||||
QString object = QString::fromStdString(d->obj.getObjectPython());
|
||||
|
||||
QStringList arguments;
|
||||
arguments.append(
|
||||
QString::fromLatin1("Points=getattr(%1, %1.getPropertyNameOfGeometry())").arg(object));
|
||||
if (!d->ui.groupBoxSmooth->isChecked()) {
|
||||
arguments.append(QString::fromLatin1("MinDegree = %1").arg(d->ui.degreeMin->value()));
|
||||
}
|
||||
arguments.append(QString::fromLatin1("MaxDegree = %1").arg(d->ui.degreeMax->value()));
|
||||
arguments.append(QString::fromLatin1("Continuity = %1").arg(d->ui.continuity->currentIndex()));
|
||||
if (d->ui.checkBoxClosed->isChecked()) {
|
||||
arguments.append(QString::fromLatin1("Closed = True"));
|
||||
}
|
||||
else {
|
||||
arguments.append(QString::fromLatin1("Closed = False"));
|
||||
}
|
||||
if (d->ui.checkBox->isChecked()) {
|
||||
int index = d->ui.paramType->currentIndex();
|
||||
arguments.append(QString::fromLatin1("ParametrizationType = %1").arg(index));
|
||||
}
|
||||
if (d->ui.groupBoxSmooth->isChecked()) {
|
||||
arguments.append(QString::fromLatin1("Weight1 = %1").arg(d->ui.curveLength->value()));
|
||||
arguments.append(QString::fromLatin1("Weight2 = %1").arg(d->ui.curvature->value()));
|
||||
arguments.append(QString::fromLatin1("Weight3 = %1").arg(d->ui.torsion->value()));
|
||||
}
|
||||
|
||||
QString argument = arguments.join(QLatin1String(", "));
|
||||
QString command = QString::fromLatin1("%1.addObject(\"Part::Spline\", \"Spline\").Shape = "
|
||||
"ReverseEngineering.approxCurve(%2).toShape()")
|
||||
.arg(document, argument);
|
||||
|
||||
tryCommand(command);
|
||||
}
|
||||
|
||||
void FitBSplineCurveWidget::exeCommand(const QString& cmd)
|
||||
{
|
||||
Gui::WaitCursor wc;
|
||||
Gui::Command::addModule(Gui::Command::App, "ReverseEngineering");
|
||||
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Fit B-Spline"));
|
||||
Gui::Command::runCommand(Gui::Command::Doc, cmd.toLatin1());
|
||||
Gui::Command::commitCommand();
|
||||
Gui::Command::updateActive();
|
||||
}
|
||||
|
||||
void FitBSplineCurveWidget::tryCommand(const QString& cmd)
|
||||
{
|
||||
try {
|
||||
exeCommand(cmd);
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
Gui::Command::abortCommand();
|
||||
e.ReportException();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FitBSplineCurveWidget::changeEvent(QEvent* e)
|
||||
{
|
||||
QWidget::changeEvent(e);
|
||||
if (e->type() == QEvent::LanguageChange) {
|
||||
d->ui.retranslateUi(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* TRANSLATOR ReenGui::TaskFitBSplineCurve */
|
||||
|
||||
TaskFitBSplineCurve::TaskFitBSplineCurve(const App::DocumentObjectT& obj)
|
||||
: widget {new FitBSplineCurveWidget(obj)}
|
||||
{
|
||||
addTaskBox(widget);
|
||||
}
|
||||
|
||||
void TaskFitBSplineCurve::open()
|
||||
{}
|
||||
|
||||
bool TaskFitBSplineCurve::accept()
|
||||
{
|
||||
return widget->accept();
|
||||
}
|
||||
|
||||
#include "moc_FitBSplineCurve.cpp"
|
||||
81
src/Mod/ReverseEngineering/Gui/FitBSplineCurve.h
Normal file
81
src/Mod/ReverseEngineering/Gui/FitBSplineCurve.h
Normal file
@@ -0,0 +1,81 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Werner Mayer <wmayer[at]users.sourceforge.net> *
|
||||
* *
|
||||
* This file is part of FreeCAD. *
|
||||
* *
|
||||
* FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU Lesser General Public License as *
|
||||
* published by the Free Software Foundation, either version 2.1 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* FreeCAD is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with FreeCAD. If not, see *
|
||||
* <https://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef REENGUI_FITBSPLINECURVE_H
|
||||
#define REENGUI_FITBSPLINECURVE_H
|
||||
|
||||
#include <Gui/TaskView/TaskDialog.h>
|
||||
#include <Gui/TaskView/TaskView.h>
|
||||
|
||||
|
||||
namespace ReenGui
|
||||
{
|
||||
|
||||
class FitBSplineCurveWidget: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit FitBSplineCurveWidget(const App::DocumentObjectT&, QWidget* parent = nullptr);
|
||||
~FitBSplineCurveWidget() override;
|
||||
|
||||
bool accept();
|
||||
|
||||
protected:
|
||||
void changeEvent(QEvent* e) override;
|
||||
|
||||
private:
|
||||
void toggleParametrizationType(bool on);
|
||||
void toggleSmoothing(bool on);
|
||||
void tryAccept();
|
||||
void exeCommand(const QString&);
|
||||
void tryCommand(const QString&);
|
||||
|
||||
private:
|
||||
class Private;
|
||||
Private* d;
|
||||
};
|
||||
|
||||
class TaskFitBSplineCurve: public Gui::TaskView::TaskDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TaskFitBSplineCurve(const App::DocumentObjectT&);
|
||||
|
||||
public:
|
||||
void open() override;
|
||||
bool accept() override;
|
||||
|
||||
QDialogButtonBox::StandardButtons getStandardButtons() const override
|
||||
{
|
||||
return QDialogButtonBox::Ok | QDialogButtonBox::Cancel;
|
||||
}
|
||||
|
||||
private:
|
||||
FitBSplineCurveWidget* widget;
|
||||
};
|
||||
|
||||
} // namespace ReenGui
|
||||
|
||||
#endif // REENGUI_FITBSPLINECURVE_H
|
||||
249
src/Mod/ReverseEngineering/Gui/FitBSplineCurve.ui
Normal file
249
src/Mod/ReverseEngineering/Gui/FitBSplineCurve.ui
Normal file
@@ -0,0 +1,249 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ReenGui::FitBSplineCurve</class>
|
||||
<widget class="QWidget" name="ReenGui::FitBSplineCurve">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>360</width>
|
||||
<height>375</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Fit B-spline surface</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="groupBoxU">
|
||||
<property name="title">
|
||||
<string>Parameters</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Maximum degree</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="paramType">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Chord length</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Centripetal</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Iso-Parametric</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Continuity</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QSpinBox" name="degreeMax">
|
||||
<property name="minimum">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>11</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>6</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QSpinBox" name="degreeMin">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>11</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>2</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="checkBox">
|
||||
<property name="text">
|
||||
<string>Parametrization type</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="continuity">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>C0</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>G1</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>C1</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>G2</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>C2</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>C3</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>CN</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Minimum degree</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="checkBoxClosed">
|
||||
<property name="text">
|
||||
<string>Closed curve</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QGroupBox" name="groupBoxSmooth">
|
||||
<property name="title">
|
||||
<string>Smoothing</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<string>Torsion</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>Curve length</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>Curvature</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QDoubleSpinBox" name="curvature">
|
||||
<property name="maximum">
|
||||
<double>1.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="1">
|
||||
<widget class="QDoubleSpinBox" name="torsion">
|
||||
<property name="maximum">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QDoubleSpinBox" name="curveLength">
|
||||
<property name="maximum">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>15</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>degreeMin</tabstop>
|
||||
<tabstop>degreeMax</tabstop>
|
||||
<tabstop>continuity</tabstop>
|
||||
<tabstop>checkBox</tabstop>
|
||||
<tabstop>paramType</tabstop>
|
||||
<tabstop>checkBoxClosed</tabstop>
|
||||
<tabstop>groupBoxSmooth</tabstop>
|
||||
<tabstop>curveLength</tabstop>
|
||||
<tabstop>curvature</tabstop>
|
||||
<tabstop>torsion</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -74,7 +74,8 @@ Gui::MenuItem* Workbench::setupMenuBar() const
|
||||
<< "Reen_ApproxSphere"
|
||||
<< "Reen_ApproxPolynomial"
|
||||
<< "Separator"
|
||||
<< "Reen_ApproxSurface";
|
||||
<< "Reen_ApproxSurface"
|
||||
<< "Reen_ApproxCurve";
|
||||
*reen << approx;
|
||||
|
||||
return root;
|
||||
|
||||
Reference in New Issue
Block a user