Sat, 17 Mar 2018 12:29:52 +0200
Added a new tool for clamping vertices
--- a/CMakeLists.txt Sat Mar 17 11:35:07 2018 +0200 +++ b/CMakeLists.txt Sat Mar 17 12:29:52 2018 +0200 @@ -182,6 +182,7 @@ src/dialogs/replacecoordinatesdialog.ui src/dialogs/rotationpointdialog.ui src/dialogs/ytruderdialog.ui + src/toolsets/fixroundingerrors.ui src/mainwindow.ui src/partdownloader.ui src/widgets/headeredit.ui
--- a/src/mainwindow.ui Sat Mar 17 11:35:07 2018 +0200 +++ b/src/mainwindow.ui Sat Mar 17 12:29:52 2018 +0200 @@ -327,6 +327,7 @@ <addaction name="actionMakeBorders"/> <addaction name="actionRoundCoordinates"/> <addaction name="actionReplaceCoordinates"/> + <addaction name="actionFixRoundingErrors"/> <addaction name="actionFlip"/> <addaction name="actionDemote"/> <addaction name="actionOpenSubfiles"/> @@ -1734,6 +1735,11 @@ <string>Polar grid</string> </property> </action> + <action name="actionFixRoundingErrors"> + <property name="text"> + <string>Fix rounding errors</string> + </property> + </action> </widget> <customwidgets> <customwidget>
--- a/src/toolsets/algorithmtoolset.cpp Sat Mar 17 11:35:07 2018 +0200 +++ b/src/toolsets/algorithmtoolset.cpp Sat Mar 17 12:29:52 2018 +0200 @@ -20,6 +20,7 @@ #include <QDir> #include <QInputDialog> #include <QMessageBox> +#include <QPushButton> #include "../mainwindow.h" #include "../main.h" #include "../lddocument.h" @@ -39,6 +40,7 @@ #include "ui_replacecoordinatesdialog.h" #include "ui_editrawdialog.h" #include "ui_flipdialog.h" +#include "ui_fixroundingerrors.h" #include "algorithmtoolset.h" AlgorithmToolset::AlgorithmToolset (MainWindow* parent) : @@ -196,6 +198,93 @@ print (tr ("Rounded %1 values"), num); } +void AlgorithmToolset::fixRoundingErrors() +{ + QDialog dialog {m_window}; + Ui::FixRoundingErrors ui; + ui.setupUi(&dialog); + auto updateDialogButtonBox = [&]() + { + QPushButton* button = ui.buttonBox->button(QDialogButtonBox::Ok); + + if (button) + { + button->setEnabled( + ui.checkboxX->isChecked() + or ui.checkboxY->isChecked() + or ui.checkboxZ->isChecked() + ); + } + }; + updateDialogButtonBox(); + connect(ui.checkboxX, &QCheckBox::clicked, updateDialogButtonBox); + connect(ui.checkboxY, &QCheckBox::clicked, updateDialogButtonBox); + connect(ui.checkboxZ, &QCheckBox::clicked, updateDialogButtonBox); + const int result = dialog.exec(); + + if (result == QDialog::Accepted) + { + const Vertex referencePoint = { + ui.valueX->value(), + ui.valueY->value(), + ui.valueZ->value() + }; + + // Find out which axes to consider + QSet<Axis> axes; + if (ui.checkboxX->isChecked()) + axes << X; + if (ui.checkboxY->isChecked()) + axes << Y; + if (ui.checkboxZ->isChecked()) + axes << Z; + + // Make a reference distance from the threshold value. + // If we're only comparing one dimension, this is the square of the threshold. + // If we're comparing multiple dimensions, the distance is multiplied to adjust. + double thresholdDistanceSquared = countof(axes) * std::pow(ui.threshold->value(), 2); + // Add some tiny leeway to fix rounding errors in the rounding error fixer. + thresholdDistanceSquared += 1e-10; + + auto fixVertex = [&](Vertex& vertex) + { + double distanceSquared = 0.0; + + for (Axis axis : axes) + distanceSquared += std::pow(vertex[axis] - referencePoint[axis], 2); + + if (distanceSquared < thresholdDistanceSquared) + { + // It's close enough, so clamp it + for (Axis axis : axes) + vertex.setCoordinate(axis, referencePoint[axis]); + } + }; + + for (const QModelIndex& index : m_window->selectedIndexes()) + { + LDObject* object = currentDocument()->lookup(index); + + if (object) + { + for (int i : range(0, 1, object->numVertices() - 1)) + { + Vertex point = object->vertex(i); + fixVertex(point); + object->setVertex(i, point); + } + if (object->type() == LDObjectType::SubfileReference) + { + LDSubfileReference* reference = static_cast<LDSubfileReference*>(object); + Vertex point = reference->position(); + fixVertex(point); + reference->setPosition(point); + } + } + } + } +} + void AlgorithmToolset::replaceCoordinates() { QDialog dialog {m_window};
--- a/src/toolsets/algorithmtoolset.h Sat Mar 17 11:35:07 2018 +0200 +++ b/src/toolsets/algorithmtoolset.h Sat Mar 17 12:29:52 2018 +0200 @@ -28,6 +28,7 @@ Q_INVOKABLE void autocolor(); Q_INVOKABLE void demote(); Q_INVOKABLE void editRaw(); + Q_INVOKABLE void fixRoundingErrors(); Q_INVOKABLE void flip(); Q_INVOKABLE void makeBorders(); Q_INVOKABLE void replaceCoordinates();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/toolsets/fixroundingerrors.ui Sat Mar 17 12:29:52 2018 +0200 @@ -0,0 +1,253 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>FixRoundingErrors</class> + <widget class="QDialog" name="FixRoundingErrors"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>235</width> + <height>243</height> + </rect> + </property> + <property name="windowTitle"> + <string>Fix rounding errors</string> + </property> + <layout class="QFormLayout" name="formLayout"> + <item row="0" column="0" colspan="2"> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>Co-ordinates</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QCheckBox" name="checkboxX"> + <property name="text"> + <string>X</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>=</string> + </property> + <property name="buddy"> + <cstring>valueX</cstring> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QDoubleSpinBox" name="valueX"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="decimals"> + <number>5</number> + </property> + <property name="maximum"> + <double>10000.000000000000000</double> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QCheckBox" name="checkboxY"> + <property name="text"> + <string>Y</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>=</string> + </property> + <property name="buddy"> + <cstring>valueY</cstring> + </property> + </widget> + </item> + <item row="1" column="2"> + <widget class="QDoubleSpinBox" name="valueY"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="decimals"> + <number>5</number> + </property> + <property name="maximum"> + <double>10000.000000000000000</double> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QCheckBox" name="checkboxZ"> + <property name="text"> + <string>Z</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>=</string> + </property> + <property name="buddy"> + <cstring>valueZ</cstring> + </property> + </widget> + </item> + <item row="2" column="2"> + <widget class="QDoubleSpinBox" name="valueZ"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="decimals"> + <number>5</number> + </property> + <property name="maximum"> + <double>10000.000000000000000</double> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Threshold:</string> + </property> + <property name="buddy"> + <cstring>threshold</cstring> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QDoubleSpinBox" name="threshold"> + <property name="decimals"> + <number>5</number> + </property> + <property name="minimum"> + <double>0.000010000000000</double> + </property> + <property name="maximum"> + <double>10000.000000000000000</double> + </property> + <property name="singleStep"> + <double>0.000100000000000</double> + </property> + <property name="value"> + <double>0.001000000000000</double> + </property> + </widget> + </item> + <item row="2" column="0" colspan="2"> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + <zorder>buttonBox</zorder> + <zorder>label_2</zorder> + <zorder>groupBox</zorder> + <zorder>threshold</zorder> + </widget> + <tabstops> + <tabstop>checkboxX</tabstop> + <tabstop>valueX</tabstop> + <tabstop>checkboxY</tabstop> + <tabstop>valueY</tabstop> + <tabstop>checkboxZ</tabstop> + <tabstop>valueZ</tabstop> + <tabstop>threshold</tabstop> + </tabstops> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>FixRoundingErrors</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>225</x> + <y>215</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>242</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>FixRoundingErrors</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>225</x> + <y>221</y> + </hint> + <hint type="destinationlabel"> + <x>234</x> + <y>242</y> + </hint> + </hints> + </connection> + <connection> + <sender>checkboxX</sender> + <signal>clicked(bool)</signal> + <receiver>valueX</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>49</x> + <y>53</y> + </hint> + <hint type="destinationlabel"> + <x>93</x> + <y>47</y> + </hint> + </hints> + </connection> + <connection> + <sender>checkboxY</sender> + <signal>clicked(bool)</signal> + <receiver>valueY</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>60</x> + <y>94</y> + </hint> + <hint type="destinationlabel"> + <x>132</x> + <y>91</y> + </hint> + </hints> + </connection> + <connection> + <sender>checkboxZ</sender> + <signal>clicked(bool)</signal> + <receiver>valueZ</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>61</x> + <y>129</y> + </hint> + <hint type="destinationlabel"> + <x>107</x> + <y>133</y> + </hint> + </hints> + </connection> + </connections> +</ui>