Sat, 11 May 2013 04:02:13 +0300
Readded BFC red-green view, although determining inversion isn't always correct and it cannot handle CW-certified files...
--- a/ldforge.qrc Fri May 10 21:45:36 2013 +0300 +++ b/ldforge.qrc Sat May 11 04:02:13 2013 +0300 @@ -32,6 +32,7 @@ <file>./icons/condline.png</file> <file>./icons/copy.png</file> <file>./icons/corner-verts.png</file> + <file>./icons/coverer.png</file> <file>./icons/cut.png</file> <file>./icons/delete.png</file> <file>./icons/del-line.png</file>
--- a/mkqrc.sh Fri May 10 21:45:36 2013 +0300 +++ b/mkqrc.sh Sat May 11 04:02:13 2013 +0300 @@ -20,4 +20,4 @@ printf "\t<file>$f</file>\n" >> $QRCFILE done -printf "</qresource>\n</RCC>\n" >> $QRCFILE \ No newline at end of file +printf "</qresource>\n</RCC>\n" >> $QRCFILE
--- a/src/addObjectDialog.cpp Fri May 10 21:45:36 2013 +0300 +++ b/src/addObjectDialog.cpp Sat May 11 04:02:13 2013 +0300 @@ -265,7 +265,7 @@ QLabel* lb_matrix = new QLabel ("Matrix:"); le_matrix = new QLineEdit; // le_matrix->setValidator (new QDoubleValidator); - matrix<3> defval = g_identity; + matrix defval = g_identity; if (obj) { if (obj->getType () == LDObject::Subfile) @@ -385,7 +385,7 @@ if (!newObject) backup = obj->clone (); - matrix<3> transform = g_identity; + matrix transform = g_identity; if (type == LDObject::Subfile || type == LDObject::Radial) { vector<str> matrixstrvals = str (dlg.le_matrix->text ()).split (" "); @@ -396,7 +396,7 @@ for (str val : matrixstrvals) matrixvals[i++] = atof (val); - transform = matrix<3> (matrixvals); + transform = matrix (matrixvals); } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/checkboxgroup.h Sat May 11 04:02:13 2013 +0300 @@ -0,0 +1,40 @@ +#include <QGroupBox> +#include <QCheckBox> +#include <QBoxLayout> +#include <map> + +QBoxLayout::Direction makeDirection (Qt::Orientation orient, bool invert = false); + +template<class T> class CheckBoxGroup : public QGroupBox { +public: + CheckBoxGroup (const char* label, Qt::Orientation orient = Qt::Horizontal, QWidget* parent = null) : QGroupBox (parent) { + m_layout = new QBoxLayout (makeDirection (orient)); + setTitle (label); + setLayout (m_layout); + } + + void addCheckBox (const char* label, T key, bool checked = false) { + if (m_vals.find (key) != m_vals.end ()) + return; + + QCheckBox* box = new QCheckBox (label); + box->setChecked (checked); + + m_vals[key] = box; + m_layout->addWidget (box); + } + + std::vector<T> checkedValues () const { + std::vector<T> vals; + + for (const auto& kv : m_vals) + if (kv.second->isChecked ()) + vals.push_back (kv.first); + + return vals; + } + +private: + QBoxLayout* m_layout; + std::map<T, QCheckBox*> m_vals; +}; \ No newline at end of file
--- a/src/common.h Fri May 10 21:45:36 2013 +0300 +++ b/src/common.h Sat May 11 04:02:13 2013 +0300 @@ -177,6 +177,6 @@ // ----------------------------------------------------------------------------- // Identity matrix -extern const matrix<3> g_identity; +extern const matrix g_identity; #endif // COMMON_H \ No newline at end of file
--- a/src/configDialog.cpp Fri May 10 21:45:36 2013 +0300 +++ b/src/configDialog.cpp Sat May 11 04:02:13 2013 +0300 @@ -38,7 +38,6 @@ extern_cfg (int, gl_linethickness); extern_cfg (int, gui_toolbar_iconsize); extern_cfg (str, gui_colortoolbar); -extern_cfg (bool, gl_selflash); extern_cfg (bool, edit_schemanticinline); extern_cfg (bool, gl_blackedges); @@ -124,10 +123,6 @@ cb_colorBFC->setWhatsThis ("Polygons' front sides become green and back " "sides red. Not implemented yet."); - cb_selFlash = new QCheckBox ("Selection flash"); - cb_selFlash->setChecked (gl_selflash); - cb_colorBFC->setWhatsThis ("A pulse effect for clearer selection view."); - cb_blackEdges = new QCheckBox ("Black edges"); cb_blackEdges->setWhatsThis ("Makes all edgelines appear black. If this is " "not set, edge lines take their color as defined in LDConfig.ldr"); @@ -140,7 +135,6 @@ "actual meaning in the part file like comments and such) are filtered out."); cb_schemanticInline->setEnabled (false); - cb_colorBFC->setEnabled (false); QGridLayout* layout = new QGridLayout; layout->addWidget (lb_viewBg, 0, 0); @@ -158,9 +152,8 @@ layout->addWidget (cb_colorize, 3, 0, 1, 4); layout->addWidget (cb_colorBFC, 4, 0, 1, 4); - layout->addWidget (cb_selFlash, 5, 0, 1, 4); - layout->addWidget (cb_blackEdges, 6, 0, 1, 4); - layout->addWidget (cb_schemanticInline, 7, 0, 1, 4); + layout->addWidget (cb_blackEdges, 5, 0, 1, 4); + layout->addWidget (cb_schemanticInline, 6, 0, 1, 4); mainTab->setLayout (layout); // Add the tab to the manager @@ -689,7 +682,6 @@ if (dlg.exec ()) { lv_colorize = dlg.cb_colorize->isChecked (); gl_colorbfc = dlg.cb_colorBFC->isChecked (); - gl_selflash = dlg.cb_selFlash->isChecked (); edit_schemanticinline = dlg.cb_schemanticInline->isChecked (); gl_blackedges = dlg.cb_blackEdges->isChecked ();
--- a/src/configDialog.h Fri May 10 21:45:36 2013 +0300 +++ b/src/configDialog.h Sat May 11 04:02:13 2013 +0300 @@ -55,8 +55,7 @@ QLabel* lb_viewBg, *lb_viewFg, *lb_viewFgAlpha; QLabel* lb_lineThickness, *lb_iconSize; QPushButton* pb_viewBg, *pb_viewFg; - QCheckBox* cb_colorize, *cb_colorBFC, *cb_selFlash, *cb_schemanticInline, - *cb_blackEdges; + QCheckBox* cb_colorize, *cb_colorBFC, *cb_schemanticInline, *cb_blackEdges; QSlider* sl_viewFgAlpha, *sl_lineThickness, *sl_iconSize; // =========================================================================
--- a/src/gldraw.cpp Fri May 10 21:45:36 2013 +0300 +++ b/src/gldraw.cpp Sat May 11 04:02:13 2013 +0300 @@ -31,10 +31,6 @@ static double g_objOffset[3]; -static short g_pulseTick = 0; -static const short g_numPulseTicks = 8; -static const short g_pulseInterval = 65; - static const struct staticCameraMeta { const char glrotate[3]; const Axis axisX, axisY; @@ -53,7 +49,6 @@ cfg (float, gl_maincolor_alpha, 1.0); cfg (int, gl_linethickness, 2); cfg (bool, gl_colorbfc, true); -cfg (bool, gl_selflash, false); cfg (int, gl_camera, GLRenderer::Free); cfg (bool, gl_blackedges, true); cfg (bool, gl_axes, false); @@ -98,9 +93,6 @@ m_drawToolTip = false; m_planeDraw = false; - m_pulseTimer = new QTimer (this); - connect (m_pulseTimer, SIGNAL (timeout ()), this, SLOT (slot_timerUpdate ())); - m_toolTipTimer = new QTimer (this); m_toolTipTimer->setSingleShot (true); connect (m_toolTipTimer, SIGNAL (timeout ()), this, SLOT (slot_toolTipTimer ())); @@ -119,7 +111,7 @@ info->cam = cam; } - calcCameraIconRects (); + calcCameraIcons (); } // ============================================================================= @@ -131,7 +123,7 @@ // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= -void GLRenderer::calcCameraIconRects () { +void GLRenderer::calcCameraIcons () { ushort i = 0; for (CameraIcon& info : g_CameraIcons) { @@ -167,7 +159,7 @@ setAutoFillBackground (false); setMouseTracking (true); setFocusPolicy (Qt::WheelFocus); - compileObjects (); + compileAllObjects (); } // ============================================================================= @@ -199,7 +191,7 @@ // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= -static vector<short> g_daWarnedColors; +static vector<short> g_warnedColors; void GLRenderer::setObjectColor (LDObject* obj, const ListType list) { QColor qcol; @@ -208,15 +200,9 @@ if (list == GL::PickList) { // Make the color by the object's index color if we're picking, so we can - // make the index from the color we get from the picking results. - long i = obj->getIndex (g_curfile); - - // If we couldn't find the index, this object must not be from this file, - // therefore it must be an object inlined from a subfile reference or - // decomposed from a radial. Find the top level parent object and use - // its index. - if (i == -1) - i = obj->topLevelParent ()->getIndex (g_curfile); + // make the index from the color we get from the picking results. Be sure + // to use the top level parent's index since inlinees don't have an index. + long i = obj->topLevelParent ()->getIndex (g_curfile); // We should have the index now. assert (i != -1); @@ -232,48 +218,45 @@ return; } -#if 0 - if (gl_colorbfc && + if ((list == BFCFrontList || list == BFCBackList) && obj->getType () != LDObject::Line && obj->getType () != LDObject::CondLine) { - if (bBackSide) - glColor4f (0.9f, 0.0f, 0.0f, 1.0f); + if (list == GL::BFCFrontList) + qcol = QColor (80, 192, 0); else - glColor4f (0.0f, 0.8f, 0.0f, 1.0f); - return; - } -#endif - - if (obj->color == maincolor) - qcol = getMainColor (); - else { - color* col = getColor (obj->color); - qcol = col->faceColor; - } - - if (obj->color == edgecolor) { - qcol = Qt::black; - color* col; + qcol = QColor (224, 0, 0); + } else { + if (obj->color == maincolor) + qcol = getMainColor (); + else { + color* col = getColor (obj->color); + qcol = col->faceColor; + } - if (!gl_blackedges && obj->parent != null && (col = getColor (obj->parent->color)) != null) - qcol = col->edgeColor; - } - - if (qcol.isValid () == false) { - // The color was unknown. Use main color to make the object at least - // not appear pitch-black. - if (obj->color != edgecolor) - qcol = getMainColor (); + if (obj->color == edgecolor) { + qcol = Qt::black; + color* col; + + if (!gl_blackedges && obj->parent != null && (col = getColor (obj->parent->color)) != null) + qcol = col->edgeColor; + } - // Warn about the unknown colors, but only once. - for (short i : g_daWarnedColors) - if (obj->color == i) - return; - - printf ("%s: Unknown color %d!\n", __func__, obj->color); - g_daWarnedColors.push_back (obj->color); - return; + if (qcol.isValid () == false) { + // The color was unknown. Use main color to make the object at least + // not appear pitch-black. + if (obj->color != edgecolor) + qcol = getMainColor (); + + // Warn about the unknown colors, but only once. + for (short i : g_warnedColors) + if (obj->color == i) + return; + + printf ("%s: Unknown color %d!\n", __func__, obj->color); + g_warnedColors.push_back (obj->color); + return; + } } long r = qcol.red (), @@ -281,9 +264,10 @@ b = qcol.blue (), a = qcol.alpha (); - // Brighten it up for the select list. - if (list == GL::SelectList) { + if (obj->topLevelParent ()->selected ()) { + // Brighten it up for the select list. const uchar add = 51; + r = min (r + add, 255l); g = min (g + add, 255l); b = min (b + add, 255l); @@ -306,7 +290,7 @@ // ============================================================================= void GLRenderer::hardRefresh () { - compileObjects (); + compileAllObjects (); refresh (); glLineWidth (gl_linethickness); @@ -319,7 +303,7 @@ m_width = w; m_height = h; - calcCameraIconRects (); + calcCameraIcons (); glViewport (0, 0, w, h); glMatrixMode (GL_PROJECTION); @@ -363,11 +347,28 @@ glRotatef (m_rotZ, 0.0f, 0.0f, 1.0f); } - for (LDObject* obj : g_curfile->m_objs) { - if (obj->hidden ()) - continue; // Don't draw hidden objects + if (gl_colorbfc && !m_picking) { + glEnable (GL_CULL_FACE); - glCallList (obj->glLists[(m_picking) ? PickList : (obj->selected ()) ? SelectList : NormalList]); + for (LDObject* obj : g_curfile->m_objs) { + if (obj->hidden ()) + continue; + + glCullFace (GL_BACK); + glCallList (obj->glLists[BFCFrontList]); + + glCullFace (GL_FRONT); + glCallList (obj->glLists[BFCBackList]); + } + + glDisable (GL_CULL_FACE); + } else { + for (LDObject* obj : g_curfile->m_objs) { + if (obj->hidden ()) + continue; + + glCallList (obj->glLists[(m_picking) ? PickList : NormalList]); + } } if (gl_axes && !m_picking) @@ -598,7 +599,7 @@ // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= -void GLRenderer::compileObjects () { +void GLRenderer::compileAllObjects () { if (g_BBox.empty () == false) { g_objOffset[X] = -(g_BBox.v0 ()[X] + g_BBox.v1 ()[X]) / 2; g_objOffset[Y] = -(g_BBox.v0 ()[Y] + g_BBox.v1 ()[Y]) / 2; @@ -632,13 +633,19 @@ // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= +static bool g_glInvert = false; + void GLRenderer::compileSubObject (LDObject* obj, const GLenum gltype) { glBegin (gltype); const short numverts = (obj->getType () != LDObject::CondLine) ? obj->vertices () : 2; - for (short i = 0; i < numverts; ++i) - compileVertex (obj->coords[i]); + if (g_glInvert == false) + for (short i = 0; i < numverts; ++i) + compileVertex (obj->coords[i]); + else + for (short i = numverts - 1; i >= 0; --i) + compileVertex (obj->coords[i]); glEnd (); } @@ -678,22 +685,43 @@ LDSubfile* ref = static_cast<LDSubfile*> (obj); vector<LDObject*> objs = ref->inlineContents (true, true); + bool oldinvert = g_glInvert; + + if (ref->transform.determinant () < 0) + g_glInvert = !g_glInvert; + + LDObject* prev = ref->prev (); + if (prev->getType () == LDObject::BFC && static_cast<LDBFC*> (prev)->type == LDBFC::InvertNext) + g_glInvert = !g_glInvert; + for (LDObject* obj : objs) { compileList (obj, list); delete obj; } + + g_glInvert = oldinvert; } break; case LDObject::Radial: { - LDRadial* pRadial = static_cast<LDRadial*> (obj); - std::vector<LDObject*> objs = pRadial->decompose (true); + LDRadial* rad = static_cast<LDRadial*> (obj); + std::vector<LDObject*> objs = rad->decompose (true); + + bool oldinvert = g_glInvert; + if (rad->transform.determinant () < 0) + g_glInvert = !g_glInvert; + + LDObject* prev = rad->prev (); + if (prev->getType () == LDObject::BFC && static_cast<LDBFC*> (prev)->type == LDBFC::InvertNext) + g_glInvert = !g_glInvert; for (LDObject* obj : objs) { compileList (obj, list); delete obj; } + + g_glInvert = oldinvert; } break; @@ -898,17 +926,6 @@ // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= -void GLRenderer::updateSelFlash () { - if (gl_selflash && g_win->sel ().size() > 0) { - m_pulseTimer->start (g_pulseInterval); - g_pulseTick = 0; - } else - m_pulseTimer->stop (); -} - -// ============================================================================= -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -// ============================================================================= void GLRenderer::pick (uint mouseX, uint mouseY) { // Check if we selected a camera icon if (!m_rangepick) { @@ -930,8 +947,10 @@ std::vector<LDObject*> oldsel = g_win->sel (); g_win->sel ().clear (); - for (LDObject* obj : oldsel) + for (LDObject* obj : oldsel) { + obj->setSelected (false); compileObject (obj); + } } m_picking = true; @@ -939,6 +958,7 @@ // Paint the picking scene glDisable (GL_DITHER); glClearColor (1.0f, 1.0f, 1.0f, 1.0f); + drawGLScene (); glGetIntegerv (GL_VIEWPORT, viewport); @@ -1006,6 +1026,7 @@ for (ulong i = 0; i < g_win->sel ().size(); ++i) { if (g_win->sel ()[i] == obj) { g_win->sel ().erase (g_win->sel ().begin () + i); + obj->setSelected (false); removed = true; removedObj = obj; } @@ -1034,13 +1055,14 @@ for (LDObject* obj : sel) compileObject (obj); + if (removedObj) + compileObject (removedObj); + m_picking = false; m_rangepick = false; glEnable (GL_DITHER); setBackground (); - updateSelFlash (); - update (); } @@ -1162,16 +1184,6 @@ } // ============================================================================= -void GLRenderer::slot_timerUpdate () { - ++g_pulseTick %= g_numPulseTicks; - - for (LDObject* obj : g_win->sel ()) - compileObject (obj); - - update (); -} - -// ============================================================================= void GLRenderer::slot_toolTipTimer () { // We come here if the cursor has stayed in one place for longer than a // a second. Check if we're holding it over a camera icon - if so, draw
--- a/src/gldraw.h Fri May 10 21:45:36 2013 +0300 +++ b/src/gldraw.h Sat May 11 04:02:13 2013 +0300 @@ -45,46 +45,42 @@ Free }; - enum ListType { NormalList, PickList, SelectList }; + enum ListType { NormalList, PickList, BFCFrontList, BFCBackList }; GLRenderer (QWidget* parent = null); ~GLRenderer (); - void hardRefresh (); - void compileObjects (); - void setBackground (); - void pick (uint mouseX, uint mouseY); - QColor getMainColor (); - void compileObject (LDObject* obj); - void refresh (); - void updateSelFlash (); - void resetAngles (); - uchar* screencap (ushort& w, ushort& h); - void setCamera (const GLRenderer::Camera cam); - void beginPlaneDraw (); - void endPlaneDraw (bool accept); - - GLRenderer::Camera camera () { return m_camera; } - bool picking () { return m_picking; } - void setZoom (const double zoom) { m_zoom = zoom; } - double zoom () const { return m_zoom; } + void beginPlaneDraw (); + Camera camera () const { return m_camera; } + void compileObject (LDObject* obj); + void compileAllObjects (); + void endPlaneDraw (bool accept); + QColor getMainColor (); + void hardRefresh (); + bool picking () { return m_picking; } + void refresh (); + void resetAngles (); + uchar* screencap (ushort& w, ushort& h); + void setBackground (); + void setCamera (const GLRenderer::Camera cam); + void setZoom (const double zoom) { m_zoom = zoom; } + double zoom () const { return m_zoom; } protected: - void initializeGL (); - void resizeGL (int w, int h); - - void mousePressEvent (QMouseEvent* ev); - void mouseMoveEvent (QMouseEvent* ev); - void mouseReleaseEvent (QMouseEvent* ev); - void keyPressEvent (QKeyEvent* ev); - void keyReleaseEvent (QKeyEvent* ev); - void wheelEvent (QWheelEvent* ev); - void paintEvent (QPaintEvent* ev); - void leaveEvent (QEvent* ev); - void contextMenuEvent (QContextMenuEvent* ev); + void contextMenuEvent (QContextMenuEvent* ev); + void initializeGL (); + void keyPressEvent (QKeyEvent* ev); + void keyReleaseEvent (QKeyEvent* ev); + void leaveEvent (QEvent* ev); + void mousePressEvent (QMouseEvent* ev); + void mouseMoveEvent (QMouseEvent* ev); + void mouseReleaseEvent (QMouseEvent* ev); + void paintEvent (QPaintEvent* ev); + void resizeGL (int w, int h); + void wheelEvent (QWheelEvent* ev); private: - QTimer* m_pulseTimer, *m_toolTipTimer; + QTimer* m_toolTipTimer; Qt::MouseButtons m_lastButtons; Qt::KeyboardModifiers m_keymods; ulong m_totalmove; @@ -98,20 +94,19 @@ ushort m_width, m_height; std::vector<vertex> m_planeDrawVerts; - void compileList (LDObject* obj, const ListType list); - void compileSubObject (LDObject* obj, const GLenum gltype); - void compileVertex (const vertex& vrt); - void clampAngle (double& angle); - void setObjectColor (LDObject* obj, const ListType list); - void drawGLScene () const; - void calcCameraIconRects (); - - vertex coord_2to3 (const QPoint& pos2d, const bool snap) const; - QPoint coord_3to2 (const vertex& pos3d) const; + void calcCameraIcons (); + void clampAngle (double& angle); + void compileList (LDObject* obj, const ListType list); + void compileSubObject (LDObject* obj, const GLenum gltype); + void compileVertex (const vertex& vrt); + vertex coord_2to3 (const QPoint& pos2d, const bool snap) const; + QPoint coord_3to2 (const vertex& pos3d) const; + void drawGLScene () const; + void pick (uint mouseX, uint mouseY); + void setObjectColor (LDObject* obj, const ListType list); private slots: - void slot_timerUpdate (); - void slot_toolTipTimer (); + void slot_toolTipTimer (); }; // Alias for short namespaces @@ -120,7 +115,8 @@ static const GLRenderer::ListType g_glListTypes[] = { GL::NormalList, GL::PickList, - GL::SelectList + GL::BFCFrontList, + GL::BFCBackList, }; #endif // GLDRAW_H \ No newline at end of file
--- a/src/gui.cpp Fri May 10 21:45:36 2013 +0300 +++ b/src/gui.cpp Sat May 11 04:02:13 2013 +0300 @@ -396,7 +396,6 @@ meta.push_back ({null, null, true}); } else { color* col = getColor (atoi (colorname)); - printf ("color: %d\n", atoi (colorname)); assert (col != null); meta.push_back ({col, null, false}); } @@ -730,7 +729,6 @@ for (LDObject* obj : priorSelection) m_renderer->compileObject (obj); - m_renderer->updateSelFlash (); m_renderer->refresh (); } @@ -821,9 +819,6 @@ bool ForgeWindow::isSelected (LDObject* obj) { LDObject* needle = obj->topLevelParent (); - if (needle == null) - needle = obj; - for (LDObject* hay : m_sel) if (hay == needle) return true;
--- a/src/gui_editactions.cpp Fri May 10 21:45:36 2013 +0300 +++ b/src/gui_editactions.cpp Sat May 11 04:02:13 2013 +0300 @@ -621,7 +621,7 @@ const double angle = (pi * currentGrid ().confs[Grid::Angle]->value) / 360; // ref: http://en.wikipedia.org/wiki/Transformation_matrix#Rotation_2 - matrix<3> transform ({ + matrix transform ({ (l * l * (1 - cos (angle))) + cos (angle), (m * l * (1 - cos (angle))) - (n * sin (angle)), (n * l * (1 - cos (angle))) + (m * sin (angle)),
--- a/src/ldtypes.cpp Fri May 10 21:45:36 2013 +0300 +++ b/src/ldtypes.cpp Sat May 11 04:02:13 2013 +0300 @@ -216,7 +216,7 @@ // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= -static void transformObject (LDObject* obj, matrix<3> transform, vertex pos, short parentcolor) { +static void transformObject (LDObject* obj, matrix transform, vertex pos, short parentcolor) { switch (obj->getType()) { case LDObject::Line: case LDObject::CondLine: @@ -230,7 +230,7 @@ { LDSubfile* ref = static_cast<LDSubfile*> (obj); - matrix<3> newMatrix = transform * ref->transform; + matrix newMatrix = transform * ref->transform; ref->pos.transform (transform, pos); ref->transform = newMatrix; } @@ -319,7 +319,7 @@ // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= -long LDObject::getIndex (OpenFile* pFile) { +long LDObject::getIndex (OpenFile* pFile) const { for (ulong i = 0; i < pFile->m_objs.size(); ++i) if (pFile->m_objs[i] == this) return i; @@ -396,7 +396,7 @@ // ============================================================================= LDObject* LDObject::topLevelParent () { if (!parent) - return null; + return this; LDObject* it = this; @@ -406,46 +406,67 @@ return it; } +// ============================================================================= +LDObject* LDObject::next () const { + long idx = getIndex (g_curfile); + assert (idx != -1); + + if (idx == (long) g_curfile->m_objs.size () - 1) + return null; + + return g_curfile->m_objs[idx + 1]; +} + +// ============================================================================= +LDObject* LDObject::prev () const { + long idx = getIndex (g_curfile); + assert (idx != -1); + + if (idx == 0) + return null; + + return g_curfile->m_objs[idx - 1]; +} // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= -void LDObject::move (vertex vVector) { vVector = vVector; /* to shut up GCC */ } -void LDEmpty::move (vertex vVector) { vVector = vVector; } -void LDBFC::move (vertex vVector) { vVector = vVector; } -void LDComment::move (vertex vVector) { vVector = vVector; } -void LDGibberish::move (vertex vVector) { vVector = vVector; } +void LDObject::move (vertex vect) { (void) vect; } +void LDEmpty::move (vertex vect) { (void) vect; } +void LDBFC::move (vertex vect) { (void) vect; } +void LDComment::move (vertex vect) { (void) vect; } +void LDGibberish::move (vertex vect) { (void) vect; } -void LDVertex::move (vertex vVector) { - pos += vVector; +void LDVertex::move (vertex vect) { + pos += vect; } -void LDSubfile::move (vertex vVector) { - pos += vVector; +void LDSubfile::move (vertex vect) { + pos += vect; } -void LDRadial::move (vertex vVector) { - pos += vVector; +void LDRadial::move (vertex vect) { + pos += vect; } -void LDLine::move (vertex vVector) { +void LDLine::move (vertex vect) { for (short i = 0; i < 2; ++i) - coords[i] += vVector; + coords[i] += vect; } -void LDTriangle::move (vertex vVector) { +void LDTriangle::move (vertex vect) { for (short i = 0; i < 3; ++i) - coords[i] += vVector; + coords[i] += vect; } -void LDQuad::move (vertex vVector) { +void LDQuad::move (vertex vect) { for (short i = 0; i < 4; ++i) - coords[i] += vVector; + coords[i] += vect; } -void LDCondLine::move (vertex vVector) { +void LDCondLine::move (vertex vect) { for (short i = 0; i < 4; ++i) - coords[i] += vVector; + coords[i] += vect; } // =============================================================================
--- a/src/ldtypes.h Fri May 10 21:45:36 2013 +0300 +++ b/src/ldtypes.h Sat May 11 04:02:13 2013 +0300 @@ -77,14 +77,14 @@ virtual ~LDObject (); // Index (i.e. line number) of this object - long getIndex (OpenFile* pFile); + long getIndex (OpenFile* pFile) const; // Color used by this object. Comments, gibberish and empty entries // do not use this field. short color; // OpenGL list for this object - uint glLists[3]; + uint glLists[4]; // Vertices of this object vertex coords[4]; @@ -138,10 +138,12 @@ // Object list entry for this object QListWidgetItem* qObjListEntry; - bool hidden () const { return m_hidden; } - void setHidden (const bool hidden) { m_hidden = hidden; } - bool selected () const { return m_selected; } - void setSelected (bool selected) { m_selected = selected; } + bool hidden () const { return m_hidden; } + LDObject* next () const; + LDObject* prev () const; + void setHidden (const bool hidden) { m_hidden = hidden; } + bool selected () const { return m_selected; } + void setSelected (bool selected) { m_selected = selected; } private: bool m_hidden; @@ -242,7 +244,7 @@ LDOBJ_SCHEMANTIC vertex pos; // Position of the subpart (TODO: should get rid of this) - matrix<3> transform; // Transformation matrix for the subpart + matrix transform; // Transformation matrix for the subpart str fileName; // Filename of the subpart (TODO: rid this too - use fileInfo->fileName instead) OpenFile* fileInfo; // Pointer to opened file for this subfile. null if unopened. @@ -360,10 +362,10 @@ LDRadial::Type radType; vertex pos; - matrix<3> transform; + matrix transform; short divs, segs, ringNum; - LDRadial (LDRadial::Type radType, vertex pos, matrix<3> transform, short divs, short segs, short ringNum) : + LDRadial (LDRadial::Type radType, vertex pos, matrix transform, short divs, short segs, short ringNum) : radType (radType), pos (pos), transform (transform), divs (divs), segs (segs), ringNum (ringNum) {} // Returns a set of objects that provide the equivalent of this radial.
--- a/src/main.cpp Fri May 10 21:45:36 2013 +0300 +++ b/src/main.cpp Sat May 11 04:02:13 2013 +0300 @@ -32,7 +32,7 @@ const QApplication* g_app = null; const vertex g_origin (0.0f, 0.0f, 0.0f); -const matrix<3> g_identity ({1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f}); +const matrix g_identity ({1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f}); // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
--- a/src/string.h Fri May 10 21:45:36 2013 +0300 +++ b/src/string.h Sat May 11 04:02:13 2013 +0300 @@ -38,8 +38,8 @@ typedef vector<String> stringlist; String () {} - String (const char* data) { m_string = data; } - String (const QString data) { m_string = data.toStdString (); } + String (const char* data) { m_string = data; } + String (const QString data) { m_string = data.toStdString (); } String (std::string data) { m_string = data; } void append (const char* data) { m_string.append (data); }
--- a/src/types.cpp Fri May 10 21:45:36 2013 +0300 +++ b/src/types.cpp Sat May 11 04:02:13 2013 +0300 @@ -3,8 +3,18 @@ #include "types.h" #include "misc.h" +vertex::vertex (double x, double y, double z) { + m_coords[X] = x; + m_coords[Y] = y; + m_coords[Z] = z; +} + // ============================================================================= -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +void vertex::move (vertex other) { + for (const Axis ax : g_Axes) + m_coords[ax] += other[ax]; +} + // ============================================================================= vertex vertex::midpoint (vertex& other) { vertex mid; @@ -16,8 +26,6 @@ } // ============================================================================= -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -// ============================================================================= str vertex::stringRep (const bool mangled) { return fmt (mangled ? "(%s, %s, %s)" : "%s %s %s", ftoa (coord (X)).chars(), @@ -26,9 +34,7 @@ } // ============================================================================= -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -// ============================================================================= -void vertex::transform (matrix<3> matr, vertex pos) { +void vertex::transform (matrix matr, vertex pos) { double x2 = (matr[0] * x ()) + (matr[1] * y ()) + (matr[2] * z ()) + pos[X]; double y2 = (matr[3] * x ()) + (matr[4] * y ()) + (matr[5] * z ()) + pos[Y]; double z2 = (matr[6] * x ()) + (matr[7] * y ()) + (matr[8] * z ()) + pos[Z]; @@ -38,16 +44,114 @@ z () = z2; } -// ============================================================================= -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +vertex vertex::operator-() const { + return vertex (-m_coords[X], -m_coords[Y], -m_coords[Z]); +} + +bool vertex::operator!= (const vertex& other) const { + return !operator== (other); +} + +double& vertex::operator[] (const Axis ax) { + return coord ((ushort) ax); +} + +const double& vertex::operator[] (const Axis ax) const { + return coord ((ushort) ax); +} + +bool vertex::operator== (const vertex& other) const { + return coord (X) == other[X] && + coord (Y) == other[Y] && + coord (Z) == other[Z]; +} + +vertex& vertex::operator/= (const double d) { + for (const Axis ax : g_Axes) + m_coords[ax] /= d; + + return *this; +} + +vertex vertex::operator/ (const double d) const { + vertex other (*this); + return other /= d; +} + +vertex& vertex::operator+= (vertex other) { + move (other); + return *this; +} + +matrix::matrix (double vals[]) { + for (short i = 0; i < 9; ++i) + m_vals[i] = vals[i]; +} + +matrix::matrix (double fillval) { + for (short i = 0; i < 9; ++i) + m_vals[i] = fillval; +} + +matrix::matrix (initlist<double> vals) { + assert (vals.size() == 9); + memcpy (&m_vals[0], &(*vals.begin ()), sizeof m_vals); +} + // ============================================================================= -void vertex::transform (matrix<4> matr) { - double x2 = (matr[0] * x ()) + (matr[4] + y ()) + (matr[8] + z ()) + matr[12]; - double y2 = (matr[1] * x ()) + (matr[5] + y ()) + (matr[9] + z ()) + matr[13]; - double z2 = (matr[2] * x ()) + (matr[6] + y ()) + (matr[10] + z ()) + matr[14]; - double w2 = (matr[3] * x ()) + (matr[7] + y ()) + (matr[11] + z ()) + matr[15]; +void matrix::puts () const { + for (short i = 0; i < 3; ++i) { + for (short j = 0; j < 3; ++j) + printf ("%*f\t", 10, m_vals[(i * 3) + j]); + + printf ("\n"); + } +} + +// ============================================================================= +str matrix::stringRep () const { + str val; + for (short i = 0; i < 9; ++i) { + if (i > 0) + val += ' '; + + val += fmt ("%s", ftoa (m_vals[i]).chars()); + } - x () = x2 / w2; - y () = y2 / w2; - z () = z2 / w2; + return val; +} + +// ============================================================================= +void matrix::zero () { + memset (&m_vals[0], 0, sizeof (double) * 9); +} + +// ============================================================================= +matrix matrix::mult (matrix other) { + matrix val; + val.zero (); + + for (short i = 0; i < 3; ++i) + for (short j = 0; j < 3; ++j) + for (short k = 0; k < 3; ++k) + val[(i * 3) + j] += m_vals[(i * 3) + k] * other[(k * 3) + j]; + + return val; +} + +// ============================================================================= +matrix& matrix::operator= (matrix other) { + memcpy (&m_vals[0], &other.m_vals[0], sizeof (double) * 9); + return *this; +} + +// ============================================================================= +double matrix::determinant () const { + return + (val (0) * val (4) * val (8)) + + (val (1) * val (5) * val (6)) + + (val (2) * val (3) * val (7)) - + (val (2) * val (4) * val (6)) - + (val (1) * val (3) * val (8)) - + (val (0) * val (5) * val (7)); } \ No newline at end of file
--- a/src/types.h Fri May 10 21:45:36 2013 +0300 +++ b/src/types.h Sat May 11 04:02:13 2013 +0300 @@ -49,91 +49,28 @@ // // A templated, mathematical N x N matrix // ============================================================================= -template<int N> class matrix { +class matrix { public: - // Constructors matrix () {} - matrix (initlist<double> vals) { - assert (vals.size() == N * N); - memcpy (&m_vals[0], &(*vals.begin ()), sizeof m_vals); - } - - matrix (double fillval) { - for (short i = 0; i < (N * N); ++i) - m_vals[i] = fillval; - } - - matrix (double vals[]) { - for (short i = 0; i < (N * N); ++i) - m_vals[i] = vals[i]; - } - - template<int M> matrix (matrix<M> other) { - assert (M >= N); - - for (short i = 0; i < M; ++i) - for (short j = 0; j < M; ++j) { - const short idx = (i * M) + j; - m_vals[idx] = other[idx]; - } - } - - matrix<N> mult (matrix<N> other) { - matrix val; - val.zero (); - - for (short i = 0; i < N; ++i) - for (short j = 0; j < N; ++j) - for (short k = 0; k < N; ++k) - val[(i * N) + j] += m_vals[(i * N) + k] * other[(k * N) + j]; - - return val; - } + matrix (initlist<double> vals); + matrix (double fillval); + matrix (double vals[]); - matrix<N>& operator= (matrix<N> other) { - memcpy (&m_vals[0], &other.m_vals[0], sizeof (double) * N * N); - return *this; - } - - matrix<N> operator* (matrix<N> other) { - return mult (other); - } - - double& operator[] (const uint idx) { - return m_vals[idx]; - } - - const double& operator[] (const uint idx) const { - return m_vals[idx]; - } - - void zero () { - memset (&m_vals[0], 0, sizeof (double) * N * N); - } + double determinant () const; + matrix mult (matrix other); + void puts () const; + str stringRep () const; + void zero (); + double& val (const uint idx) { return m_vals[idx]; } + const double& val (const uint idx) const { return m_vals[idx]; } - void puts () const { - for (short i = 0; i < N; ++i) { - for (short j = 0; j < N; ++j) - printf ("%*f\t", 10, m_vals[(i * N) + j]); - - printf ("\n"); - } - } - - str stringRep () const { - str val; - for (short i = 0; i < N * N; ++i) { - if (i > 0) - val += ' '; - - val += fmt ("%s", ftoa (m_vals[i]).chars()); - } - - return val; - } + matrix& operator= (matrix other); + matrix operator* (matrix other) { return mult (other); } + double& operator[] (const uint idx) { return m_vals[idx]; } + const double& operator[] (const uint idx) const { return m_vals[idx]; } private: - double m_vals[N * N]; + double m_vals[9]; }; // ============================================================================= @@ -146,77 +83,33 @@ // ============================================================================= class vertex { public: - double m_coords[3]; - vertex () {} - vertex (double x, double y, double z) { - m_coords[X] = x; - m_coords[Y] = y; - m_coords[Z] = z; - } - - void move (vertex other) { - for (const Axis ax : g_Axes) - m_coords[ax] += other[ax]; - } - - vertex& operator+= (vertex other) { - move (other); - return *this; - } - - vertex operator/ (const double d) const { - vertex other (*this); - return other /= d; - } - - vertex& operator/= (const double d) { - for (const Axis ax : g_Axes) - m_coords[ax] /= d; - return *this; - } - - bool operator== (const vertex& other) const { - return coord (X) == other[X] && - coord (Y) == other[Y] && - coord (Z) == other[Z]; - } + vertex (double x, double y, double z); - bool operator!= (const vertex& other) const { - return !operator== (other); - } - - vertex operator- () const { - return vertex (-m_coords[X], -m_coords[Y], -m_coords[Z]); - } - - double& coord (const ushort n) { - return m_coords[n]; - } - - const double& coord (const ushort n) const { - return m_coords[n]; - } + double& coord (const ushort n) { return m_coords[n]; } + const double& coord (const ushort n) const { return m_coords[n]; } + vertex midpoint (vertex& other); + void move (vertex other); + str stringRep (const bool mangled); + void transform (matrix matr, vertex pos); + double& x () { return m_coords[X]; } + const double& x () const { return m_coords[X]; } + double& y () { return m_coords[Y]; } + const double& y () const { return m_coords[Y]; } + double& z () { return m_coords[Z]; } + const double& z () const { return m_coords[Z]; } - double& operator[] (const Axis ax) { - return coord ((ushort) ax); - } - - const double& operator[] (const Axis ax) const { - return coord ((ushort) ax); - } - - double& x () { return m_coords[X]; } - double& y () { return m_coords[Y]; } - double& z () { return m_coords[Z]; } - const double& x () const { return m_coords[X]; } - const double& y () const { return m_coords[Y]; } - const double& z () const { return m_coords[Z]; } - - vertex midpoint (vertex& other); - str stringRep (const bool mangled); - void transform (matrix<3> matr, vertex pos); - void transform (matrix<4> matr); + vertex& operator+= (vertex other); + vertex operator/ (const double d) const; + vertex& operator/= (const double d); + bool operator== (const vertex& other) const; + bool operator!= (const vertex& other) const; + vertex operator- () const; + double& operator[] (const Axis ax); + const double& operator[] (const Axis ax) const; + +private: + double m_coords[3]; }; #endif // TYPES_H \ No newline at end of file