# HG changeset patch # User Santeri Piippo # Date 1386356016 -7200 # Node ID 46a33bdc0b36efd60ba782f39f52f6fa31e903e9 # Parent 0e38beeb050aac3b2d5ed8a3a674c01093ab9806 - Improved coordinate rounding, replaced the hack with a proper implementation, now rounds properly and works on subfiles as well diff -r 0e38beeb050a -r 46a33bdc0b36 changelog.txt --- a/changelog.txt Fri Dec 06 00:29:44 2013 +0200 +++ b/changelog.txt Fri Dec 06 20:53:36 2013 +0200 @@ -10,6 +10,9 @@ the registry under Windows and into ~/.config/LDForge under Linux. Unfortunately this means settings get lost during transition from version 0.2 and 0.3. - Added a new editing mode for drawing circles. +- Coordinate rounding now works properly, figures scientific notation and rounds subfile position and matrix. + Values are also now properly rounded instead of just floored, 1.2348 now rounds to 1.235 and not 1.234. + Subfile matrix values are rounded to 4 decimals, everything else to 3 decimals. - Corrections to the primitive generator: - Fixed: "Hi-Res" was not prepended to the names of 48/ primitives. - Fixed: Checking the Hi-Res option would not allow segment values over 16. diff -r 0e38beeb050a -r 46a33bdc0b36 src/addObjectDialog.cpp --- a/src/addObjectDialog.cpp Fri Dec 06 00:29:44 2013 +0200 +++ b/src/addObjectDialog.cpp Fri Dec 06 20:53:36 2013 +0200 @@ -221,7 +221,7 @@ if (mo) { for (const Axis ax : g_Axes) - dsb_coords[ax]->setValue (mo->getPosition() [ax]); + dsb_coords[ax]->setValue (mo->getPosition()[ax]); defaultMatrix = mo->getTransform(); } diff -r 0e38beeb050a -r 46a33bdc0b36 src/configDialog.cpp --- a/src/configDialog.cpp Fri Dec 06 00:29:44 2013 +0200 +++ b/src/configDialog.cpp Fri Dec 06 20:53:36 2013 +0200 @@ -663,21 +663,21 @@ return val; } -// ========================================================================================================================= -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -// ========================================================================================================================= -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -// ========================================================================================================================= -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -// ========================================================================================================================= +// =============================================================================================== +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// =============================================================================================== +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// =============================================================================================== +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// =============================================================================================== KeySequenceDialog::KeySequenceDialog (QKeySequence seq, QWidget* parent, Qt::WindowFlags f) : QDialog (parent, f), seq (seq) { lb_output = new QLabel; IMPLEMENT_DIALOG_BUTTONS - setWhatsThis ("Into this dialog you can input a key sequence for use as a " - "shortcut in LDForge. Use OK to confirm the new shortcut and Cancel to " - "dismiss."); + setWhatsThis (tr ("Into this dialog you can input a key sequence for use as a " + "shortcut in LDForge. Use OK to confirm the new shortcut and Cancel to " + "dismiss.")); QVBoxLayout* layout = new QVBoxLayout; layout->addWidget (lb_output); diff -r 0e38beeb050a -r 46a33bdc0b36 src/file.cpp --- a/src/file.cpp Fri Dec 06 00:29:44 2013 +0200 +++ b/src/file.cpp Fri Dec 06 20:53:36 2013 +0200 @@ -508,13 +508,11 @@ f->setImplicit (false); g_loadedFiles << f; LDFile::setCurrent (f); - LDFile::closeInitialFile(); - g_win->R()->setFile (f); g_win->doFullRefresh(); g_win->updateTitle(); - f->getHistory()->updateActions(); + g_win->updateActions(); } // ============================================================================= diff -r 0e38beeb050a -r 46a33bdc0b36 src/gldraw.cpp --- a/src/gldraw.cpp Fri Dec 06 00:29:44 2013 +0200 +++ b/src/gldraw.cpp Fri Dec 06 20:53:36 2013 +0200 @@ -1213,10 +1213,10 @@ // x0 and y0 must be less than x1 and y1, respectively. if (x0 > x1) - dataswap (x0, x1); + qSwap (x0, x1); if (y0 > y1) - dataswap (y0, y1); + qSwap (y0, y1); // Clamp the values to ensure they're within bounds x0 = max (0, x0); diff -r 0e38beeb050a -r 46a33bdc0b36 src/gui.cpp --- a/src/gui.cpp Fri Dec 06 00:29:44 2013 +0200 +++ b/src/gui.cpp Fri Dec 06 20:53:36 2013 +0200 @@ -130,8 +130,13 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void ForgeWindow::invokeAction (QAction* act, void (*func) ()) -{ beginAction (act); +void ForgeWindow::invokeAction (QAction* act, void (*func)()) +{ +#ifdef DEBUG + log ("Action %1 triggered", act->iconText()); +#endif + + beginAction (act); (*func) (); endAction(); } @@ -154,7 +159,7 @@ QAction* first = null; -for (const QVariant & it : io_recentfiles) + for (const QVariant& it : io_recentfiles) { str file = it.toString(); QAction* recent = new QAction (getIcon ("open-recent"), file, this); @@ -571,30 +576,30 @@ QMenu* contextMenu = new QMenu; if (single && singleObj->getType() != LDObject::Empty) - { contextMenu->addAction (ACTION (Edit)); + { contextMenu->addAction (ui->actionEdit); contextMenu->addSeparator(); } - contextMenu->addAction (ACTION (Cut)); - contextMenu->addAction (ACTION (Copy)); - contextMenu->addAction (ACTION (Paste)); - contextMenu->addAction (ACTION (Delete)); + contextMenu->addAction (ui->actionCut); + contextMenu->addAction (ui->actionCopy); + contextMenu->addAction (ui->actionPaste); + contextMenu->addAction (ui->actionDelete); contextMenu->addSeparator(); - contextMenu->addAction (ACTION (SetColor)); + contextMenu->addAction (ui->actionSetColor); if (single) - contextMenu->addAction (ACTION (EditRaw)); + contextMenu->addAction (ui->actionEditRaw); - contextMenu->addAction (ACTION (Borders)); - contextMenu->addAction (ACTION (SetOverlay)); - contextMenu->addAction (ACTION (ClearOverlay)); - contextMenu->addAction (ACTION (ModeSelect)); - contextMenu->addAction (ACTION (ModeDraw)); - contextMenu->addAction (ACTION (ModeCircle)); + contextMenu->addAction (ui->actionBorders); + contextMenu->addAction (ui->actionSetOverlay); + contextMenu->addAction (ui->actionClearOverlay); + contextMenu->addAction (ui->actionModeSelect); + contextMenu->addAction (ui->actionModeDraw); + contextMenu->addAction (ui->actionModeCircle); if (R()->camera() != GL::Free) { contextMenu->addSeparator(); - contextMenu->addAction (ACTION (SetDrawDepth)); + contextMenu->addAction (ui->actionSetDrawDepth); } contextMenu->exec (pos); @@ -628,9 +633,9 @@ // ----------------------------------------------------------------------------- void ForgeWindow::updateEditModeActions() { const EditMode mode = R()->getEditMode(); - ACTION (ModeSelect)->setChecked (mode == Select); - ACTION (ModeDraw)->setChecked (mode == Draw); - ACTION (ModeCircle)->setChecked (mode == CircleMode); + ui->actionModeSelect->setChecked (mode == Select); + ui->actionModeDraw->setChecked (mode == Draw); + ui->actionModeCircle->setChecked (mode == CircleMode); } // ============================================================================= @@ -856,7 +861,7 @@ void ForgeWindow::beginAction (QAction* act) { // Open the history so we can record the edits done during this action. - if (act == ACTION (Undo) || act == ACTION (Redo) || act == ACTION (Open)) + if (act == ui->actionUndo || act == ui->actionRedo || act == ui->actionOpen) LDFile::current()->getHistory()->setIgnoring (true); } @@ -906,6 +911,15 @@ buildObjList(); } +void ForgeWindow::updateActions() +{ History* his = LDFile::current()->getHistory(); + int pos = his->getPosition(); + ui->actionUndo->setEnabled (pos != -1); + ui->actionRedo->setEnabled (pos < (long) his->getSize() - 1); + ui->actionAxes->setChecked (gl_axes); + ui->actionBFCView->setChecked (gl_colorbfc); +} + QImage imageFromScreencap (uchar* data, int w, int h) { // GL and Qt formats have R and B swapped. Also, GL flips Y - correct it as well. return QImage (data, w, h, QImage::Format_ARGB32).rgbSwapped().mirrored(); diff -r 0e38beeb050a -r 46a33bdc0b36 src/gui.h --- a/src/gui.h Fri Dec 06 00:29:44 2013 +0200 +++ b/src/gui.h Fri Dec 06 20:53:36 2013 +0200 @@ -113,6 +113,7 @@ int deleteSelection(); void deleteByColor (const int colnum); void save (LDFile* f, bool saveAs); + void updateActions(); inline GLRenderer* R() { return m_renderer; diff -r 0e38beeb050a -r 46a33bdc0b36 src/gui_actions.cpp --- a/src/gui_actions.cpp Fri Dec 06 00:29:44 2013 +0200 +++ b/src/gui_actions.cpp Fri Dec 06 20:53:36 2013 +0200 @@ -466,7 +466,7 @@ extern_cfg (Bool, gl_axes); DEFINE_ACTION (Axes, 0) { gl_axes = !gl_axes; - ACTION (Axes)->setChecked (gl_axes); + g_win->updateActions(); g_win->R()->update(); } @@ -610,7 +610,7 @@ // ----------------------------------------------------------------------------- DEFINE_ACTION (BFCView, SHIFT (B)) { gl_colorbfc = !gl_colorbfc; - ACTION (BFCView)->setChecked (gl_colorbfc); + g_win->updateActions(); g_win->R()->refresh(); } diff -r 0e38beeb050a -r 46a33bdc0b36 src/gui_editactions.cpp --- a/src/gui_editactions.cpp Fri Dec 06 00:29:44 2013 +0200 +++ b/src/gui_editactions.cpp Fri Dec 06 20:53:36 2013 +0200 @@ -375,27 +375,27 @@ // ============================================================================= // ----------------------------------------------------------------------------- DEFINE_ACTION (MoveXNeg, KEY (Left)) -{ doMoveObjects ( { -1, 0, 0}); +{ doMoveObjects ({ -1, 0, 0}); } DEFINE_ACTION (MoveYNeg, KEY (Home)) -{ doMoveObjects ( {0, -1, 0}); +{ doMoveObjects ({0, -1, 0}); } DEFINE_ACTION (MoveZNeg, KEY (Down)) -{ doMoveObjects ( {0, 0, -1}); +{ doMoveObjects ({0, 0, -1}); } DEFINE_ACTION (MoveXPos, KEY (Right)) -{ doMoveObjects ( {1, 0, 0}); +{ doMoveObjects ({1, 0, 0}); } DEFINE_ACTION (MoveYPos, KEY (End)) -{ doMoveObjects ( {0, 1, 0}); +{ doMoveObjects ({0, 1, 0}); } DEFINE_ACTION (MoveZPos, KEY (Up)) -{ doMoveObjects ( {0, 0, 1}); +{ doMoveObjects ({0, 0, 1}); } // ============================================================================= @@ -453,7 +453,6 @@ obj->setVertex (i, v); } } elif (obj->hasMatrix()) - { LDMatrixObject* mo = dynamic_cast (obj); // Transform the position @@ -508,23 +507,40 @@ int num = 0; for (LDObject* obj : selection()) - { for (int i = 0; i < obj->vertices(); ++i) - { vertex v = obj->getVertex (i); + { LDMatrixObject* mo = dynamic_cast (obj); + + if (mo != null) + { vertex v = mo->getPosition(); + matrix t = mo->getTransform(); for (const Axis ax : g_Axes) - { // HACK: .. should find a better way to do this - str valstr; - valstr.sprintf ("%.3f", v[ax]); - v[ax] = valstr.toDouble(); + roundToDecimals (v[ax], 3); + + // Let matrix values be rounded to 4 decimals, + // they need that extra precision + for (int i = 0; i < 9; ++i) + roundToDecimals (t[i], 4); + + mo->setPosition (v); + mo->setTransform (t); + num += 10; + } + else + { for (int i = 0; i < obj->vertices(); ++i) + { vertex v = obj->getVertex (i); + + for (const Axis ax : g_Axes) + roundToDecimals (v[ax], 3); + + obj->setVertex (i, v); + g_win->R()->compileObject (obj); + num += 3; } - - obj->setVertex (i, v); - g_win->R()->compileObject (obj); - num += 3; } } - log (ForgeWindow::tr ("Rounded %1 coordinates"), num); + log (ForgeWindow::tr ("Rounded %1 values"), num); + g_win->refreshObjectList(); g_win->refresh(); } diff -r 0e38beeb050a -r 46a33bdc0b36 src/history.cpp --- a/src/history.cpp Fri Dec 06 00:29:44 2013 +0200 +++ b/src/history.cpp Fri Dec 06 20:53:36 2013 +0200 @@ -50,7 +50,7 @@ else g_win->doFullRefresh(); - updateActions(); + g_win->updateActions(); } // ============================================================================= @@ -73,7 +73,7 @@ else g_win->doFullRefresh(); - updateActions(); + g_win->updateActions(); } // ============================================================================= @@ -88,13 +88,6 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void History::updateActions() const -{ ACTION (Undo)->setEnabled (getPosition() != -1); - ACTION (Redo)->setEnabled (getPosition() < (long) m_changesets.size() - 1); -} - -// ============================================================================= -// ----------------------------------------------------------------------------- void History::addStep() { if (m_currentChangeset.isEmpty()) return; @@ -105,7 +98,7 @@ m_changesets << m_currentChangeset; m_currentChangeset.clear(); setPosition (getPosition() + 1); - updateActions(); + g_win->updateActions(); } // ============================================================================= diff -r 0e38beeb050a -r 46a33bdc0b36 src/history.h --- a/src/history.h Fri Dec 06 00:29:44 2013 +0200 +++ b/src/history.h Fri Dec 06 20:53:36 2013 +0200 @@ -51,7 +51,6 @@ void undo(); void redo(); void clear(); - void updateActions() const; void addStep(); void add (AbstractHistoryEntry* entry); diff -r 0e38beeb050a -r 46a33bdc0b36 src/ldtypes.cpp --- a/src/ldtypes.cpp Fri Dec 06 00:29:44 2013 +0200 +++ b/src/ldtypes.cpp Fri Dec 06 20:53:36 2013 +0200 @@ -669,8 +669,6 @@ // Hook the set accessors of certain properties to this changeProperty function. // It takes care of history management so we can capture low-level changes, this // makes history stuff work out of the box. -// -// TODO: use new PROPERTY-callbacks // ----------------------------------------------------------------------------- template static void changeProperty (LDObject* obj, T* ptr, const T& val) { long idx; @@ -701,6 +699,8 @@ { return m_coords[i]->data(); } +// ============================================================================= +// ----------------------------------------------------------------------------- void LDObject::setVertex (int i, const vertex& vert) { changeProperty (this, &m_coords[i], LDSharedVertex::getSharedVertex (vert)); } @@ -708,7 +708,7 @@ // ============================================================================= // ----------------------------------------------------------------------------- void LDMatrixObject::setPosition (const vertex& a) -{ changeProperty (getLinkPointer(), &m_position, LDSharedVertex::getSharedVertex (a)); +{ changeProperty (getLinkPointer(), &m_Position, LDSharedVertex::getSharedVertex (a)); } // ============================================================================= diff -r 0e38beeb050a -r 46a33bdc0b36 src/ldtypes.h --- a/src/ldtypes.h Fri Dec 06 00:29:44 2013 +0200 +++ b/src/ldtypes.h Fri Dec 06 20:53:36 2013 +0200 @@ -180,26 +180,29 @@ // this class distinct in case I get new extension ideas. :) // ============================================================================= class LDMatrixObject -{ PROPERTY (public, LDObject*, LinkPointer, NO_OPS, STOCK_WRITE) - PROPERTY (public, vertex, Position, NO_OPS, CUSTOM_WRITE) - PROPERTY (public, matrix, Transform, NO_OPS, CUSTOM_WRITE) +{ PROPERTY (public, LDObject*, LinkPointer, NO_OPS, STOCK_WRITE) + PROPERTY (public, matrix, Transform, NO_OPS, CUSTOM_WRITE) public: LDMatrixObject() {} LDMatrixObject (const matrix& transform, const vertex& pos) : m_Transform (transform), - m_position (LDSharedVertex::getSharedVertex (pos)) {} + m_Position (LDSharedVertex::getSharedVertex (pos)) {} - const double& setCoordinate (const Axis ax, double value) + inline const vertex& getPosition() const + { return m_Position->data(); + } + + void setCoordinate (const Axis ax, double value) { vertex v = getPosition(); v[ax] = value; setPosition (v); - - return getPosition()[ax]; } + void setPosition (const vertex& a); + private: - LDSharedVertex* m_position; + LDSharedVertex* m_Position; }; // ============================================================================= diff -r 0e38beeb050a -r 46a33bdc0b36 src/misc.cpp --- a/src/misc.cpp Fri Dec 06 00:29:44 2013 +0200 +++ b/src/misc.cpp Fri Dec 06 20:53:36 2013 +0200 @@ -81,6 +81,19 @@ 3517, 3527, 3529, 3533, 3539, 3541, 3547, 3557, 3559, 3571, }; +static const int32 g_e10[] = +{ 1, + 10, + 100, + 1000, + 10000, + 100000, + 1000000, + 10000000, + 100000000, + 1000000000, +}; + // ============================================================================= // ----------------------------------------------------------------------------- // Grid stuff @@ -410,3 +423,10 @@ // one is chosen. return true; } + +// ============================================================================= +// ----------------------------------------------------------------------------- +void roundToDecimals (double& a, int decimals) +{ assert (decimals >= 0 && decimals < (signed) (sizeof g_e10 / sizeof *g_e10)); + a = round (a * g_e10[decimals]) / g_e10[decimals]; +} \ No newline at end of file diff -r 0e38beeb050a -r 46a33bdc0b36 src/misc.h --- a/src/misc.h Fri Dec 06 00:29:44 2013 +0200 +++ b/src/misc.h Fri Dec 06 20:53:36 2013 +0200 @@ -38,6 +38,8 @@ // Simplifies the given fraction. void simplify (int& numer, int& denom); +void roundToDecimals (double& a, int decimals); + str join (initlist vals, str delim = " "); // Grid stuff @@ -138,13 +140,6 @@ extern RingFinder g_RingFinder; -// ============================================================================= -template void dataswap (T& a, T& b) -{ T c = a; - a = b; - b = c; -} - // ----------------------------------------------------------------------------- // Plural expression template static inline const char* plural (T n)