Mon, 27 May 2013 18:17:21 +0300
Added ability to snap to pre-existing vertices while drawing, added changelog
changelog.txt | file | annotate | diff | comparison | revisions | |
src/gldraw.cpp | file | annotate | diff | comparison | revisions | |
src/gldraw.h | file | annotate | diff | comparison | revisions | |
src/main.cpp | file | annotate | diff | comparison | revisions | |
src/types.cpp | file | annotate | diff | comparison | revisions | |
src/types.h | file | annotate | diff | comparison | revisions |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/changelog.txt Mon May 27 18:17:21 2013 +0300 @@ -0,0 +1,12 @@ +================================================= +== Changes in version 1.1 +================================================= + +- Added a progress dialog for file loading to respond to desktops while loading files. With large files + the no-response policy could be a bad thing. +- Added Export To File action, moved it + insert from to File menu +- Fixed: text editing did not trigger checks while setting LDraw path, removed the Configure + button from the LDraw path config dialog, it's no longer needed. +- Fixed: Coordinates weren't drawn properly on a bright background (was always drawn in bright colors..). +- Parts are now zoomed to fit properly +- Added ability to snap to pre-existing vertices while drawing. \ No newline at end of file
--- a/src/gldraw.cpp Mon May 27 13:49:07 2013 +0300 +++ b/src/gldraw.cpp Mon May 27 18:17:21 2013 +0300 @@ -667,6 +667,8 @@ if (!file ()) return; + m_knownVerts.clear (); + for (LDObject* obj : file ()->objs ()) compileObject (obj); @@ -675,11 +677,13 @@ m_axeslist = glGenLists (1); glNewList (m_axeslist, GL_COMPILE); glBegin (GL_LINES); + for (const GLAxis& ax : g_GLAxes) { qglColor (ax.col); compileVertex (ax.vert); compileVertex (-ax.vert); } + glEnd (); glEndList (); } @@ -841,6 +845,7 @@ void GLRenderer::mouseReleaseEvent (QMouseEvent* ev) { const bool wasLeft = (m_lastButtons & Qt::LeftButton) && !(ev->buttons() & Qt::LeftButton); const bool wasRight = (m_lastButtons & Qt::RightButton) && !(ev->buttons() & Qt::RightButton); + const bool wasMid = (m_lastButtons & Qt::MidButton) && !(ev->buttons() & Qt::MidButton); if (wasLeft) { // Check if we selected a camera icon @@ -900,6 +905,40 @@ return; } + if (wasMid && editMode () == Draw && m_drawedVerts.size () < 4) { + // Find the closest vertex to our cursor + double mindist = 1024.0f; + vertex closest; + bool valid = false; + + QPoint curspos = coordconv3_2 (m_hoverpos); + + for (const vertex& pos3d: m_knownVerts) { + QPoint pos2d = coordconv3_2 (pos3d); + + // Measure squared distance + double dx = abs (pos2d.x () - curspos.x ()); + double dy = abs (pos2d.y () - curspos.y ()); + double distsq = (dx * dx) + (dy * dy); + + if (distsq >= 1024.0f) // 32.0f ** 2 + continue; // too far away + + if (distsq < mindist) { + mindist = distsq; + closest = pos3d; + valid = true; + } + } + + if (valid) { + m_drawedVerts << closest; + update (); + } + + return; + } + if (wasRight && m_drawedVerts.size () > 0) { // Remove the last vertex m_drawedVerts.erase (m_drawedVerts.size () - 1); @@ -1108,17 +1147,14 @@ delete[] pixeldata; - // Remove duplicate entries. For this to be effective, the vector must be - // sorted first. - vector<LDObject*>& sel = g_win->sel (); - std::sort (sel.begin (), sel.end ()); - vector<LDObject*>::it pos = std::unique (sel.begin (), sel.end ()); - sel.resize (std::distance (sel.begin (), pos)); + // Remove duplicated entries + g_win->sel ().makeUnique (); + // Update everything now. g_win->updateSelection (); // Recompile the objects now to update their color - for (LDObject* obj : sel) + for (LDObject* obj : g_win->sel ()) compileObject (obj); if (removedObj) @@ -1235,6 +1271,29 @@ m_rectdraw = false; } +static vector<vertex> getVertices (LDObject* obj) { + vector<vertex> verts; + + if (obj->vertices () >= 2) + for (int i = 0; i < obj->vertices (); ++i) + verts << obj->coords[i]; + else if (obj->getType () == LDObject::Subfile || obj->getType () == LDObject::Radial) { + vector<LDObject*> objs; + + if (obj->getType () == LDObject::Subfile) + objs = static_cast<LDSubfile*> (obj)->inlineContents (true, true); + else + objs = static_cast<LDRadial*> (obj)->decompose (true); + + for (LDObject* obj : objs) { + verts << getVertices (obj); + delete obj; + } + } + + return verts; +} + // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= @@ -1254,6 +1313,10 @@ glEndList (); } + // Mark in known vertices of this object + m_knownVerts << getVertices (obj); + m_knownVerts.makeUnique (); + obj->m_glinit = true; }
--- a/src/gldraw.h Mon May 27 13:49:07 2013 +0300 +++ b/src/gldraw.h Mon May 27 18:17:21 2013 +0300 @@ -124,6 +124,7 @@ QColor m_bgcolor; double m_depthValues[6]; overlayMeta m_overlays[6]; + vector<vertex> m_knownVerts; void calcCameraIcons (); // Compute geometry for camera icons void clampAngle (double& angle) const; // Clamps an angle to [0, 360]
--- a/src/main.cpp Mon May 27 13:49:07 2013 +0300 +++ b/src/main.cpp Mon May 27 18:17:21 2013 +0300 @@ -40,6 +40,8 @@ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= int main (int argc, char* argv[]) { + const QApplication app (argc, argv); + // Load or create the configuration if (!config::load ()) { printf ("Creating configuration file...\n"); @@ -49,7 +51,6 @@ printf ("failed to create configuration file!\n"); } - const QApplication app (argc, argv); LDPaths::initPaths (); initColors ();
--- a/src/types.cpp Mon May 27 13:49:07 2013 +0300 +++ b/src/types.cpp Mon May 27 18:17:21 2013 +0300 @@ -109,6 +109,26 @@ return *this; } +int vertex::operator< (const vertex& other) const { + if (operator== (other)) + return false; + + if (coord (X) < other[X]) + return true; + + if (coord (X) > other[X]) + return false; + + if (coord (Y) < other[Y]) + return true; + + if (coord (Y) > other[Y]) + return false; + + return coord (Z) < other[Z]; +} + +// ============================================================================= matrix::matrix (double vals[]) { for (short i = 0; i < 9; ++i) m_vals[i] = vals[i]; @@ -123,8 +143,6 @@ assert (vals.size() == 9); memcpy (&m_vals[0], &(*vals.begin ()), sizeof m_vals); } - -// ============================================================================= void matrix::puts () const { for (short i = 0; i < 3; ++i) { for (short j = 0; j < 3; ++j)
--- a/src/types.h Mon May 27 13:49:07 2013 +0300 +++ b/src/types.h Mon May 27 18:17:21 2013 +0300 @@ -106,6 +106,7 @@ bool operator== (const vertex& other) const; bool operator!= (const vertex& other) const; vertex operator- () const; + int operator< (const vertex& other) const; double& operator[] (const Axis ax); const double& operator[] (const Axis ax) const; double& operator[] (const int ax); @@ -158,6 +159,11 @@ m_vect.push_back (value); } + void push_back (const vector<T>& vals) { + for (const T& val : vals) + push_back (val); + } + bool pop (T& val) { if (size () == 0) return false; @@ -172,6 +178,11 @@ return *this; } + vector<T>& operator<< (const vector<T>& vals) { + push_back (vals); + return *this; + } + bool operator>> (T& value) { return pop (value); } @@ -193,6 +204,14 @@ m_vect.insert (m_vect.begin () + pos, value); } + void makeUnique () { + // Remove duplicate entries. For this to be effective, the vector must be + // sorted first. + sort (); + it pos = std::unique (begin (), end ()); + resize (std::distance (begin (), pos)); + } + ulong size () const { return m_vect.size (); } @@ -211,11 +230,8 @@ m_vect.resize (size); } - template<int N> vector<T>& operator= (T vals[N]) { - for (int i = 0; i < N; ++i) - push_back (vals[i]); - - return *this; + void sort () { + std::sort (begin (), end ()); } private: