Thu, 16 May 2013 22:59:10 +0300
Added dialog for rotation points
--- a/src/aboutDialog.cpp Thu May 16 02:26:50 2013 +0300 +++ b/src/aboutDialog.cpp Thu May 16 22:59:10 2013 +0300 @@ -27,8 +27,6 @@ #include "aboutDialog.h" AboutDialog::AboutDialog (QWidget* parent, Qt::WindowFlags f) : QDialog (parent, f) { - QWidget* mainTab, *licenseTab; - // Application icon - in full 64 x 64 glory. QLabel* icon = new QLabel; icon->setPixmap (getIcon ("ldforge"));
--- a/src/colors.cpp Thu May 16 02:26:50 2013 +0300 +++ b/src/colors.cpp Thu May 16 22:59:10 2013 +0300 @@ -56,17 +56,6 @@ } // ============================================================================= -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -// ============================================================================= -static bool parseLDConfigTag (StringParser& pars, char const* tag, str& val) { - short pos; - if (!pars.findToken (pos, tag, 1)) - return false; - - return pars.getToken (val, pos + 1); -} - -// ============================================================================= uchar luma (QColor& col) { return (0.2126f * col.red ()) + (0.7152f * col.green ()) + @@ -74,7 +63,18 @@ } // ============================================================================= -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// Helper function for parseLDConfig +static bool parseLDConfigTag (StringParser& pars, char const* tag, str& val) { + short pos; + + // Try find the token and get its position + if (!pars.findToken (pos, tag, 1)) + return false; + + // Get the token after it and store it into val + return pars.getToken (val, pos + 1); +} + // ============================================================================= void parseLDConfig () { FILE* fp = openLDrawFile ("LDConfig.ldr", false); @@ -82,13 +82,13 @@ if (!fp) return; - // Even though LDConfig.ldr is technically an LDraw file, parsing it as one - // would be overkill by any standard. + // Read in the lines char buf[1024]; while (fgets (buf, sizeof buf, fp)) { if (strlen (buf) == 0 || buf[0] != '0') continue; // empty or illogical + // Use StringParser to parse the LDConfig.ldr file. str line = str (buf).strip ({'\n', '\r'}); StringParser pars (line, ' '); @@ -102,21 +102,20 @@ // Replace underscores in the name with spaces for readability name.replace ("_", " "); - // get the CODE tag + // Get the CODE tag if (!parseLDConfigTag (pars, "CODE", valuestr)) continue; - // Ensure that the code is within range. must be within 0 - 512 + if (!isNumber (valuestr)) + continue; // not a number + + // Ensure that the code is within [0 - 511] code = atoi (valuestr); if (code < 0 || code >= 512) continue; - // VALUE tag - if (!parseLDConfigTag (pars, "VALUE", facename)) - continue; - - // EDGE tag - if (!parseLDConfigTag (pars, "EDGE", edgename)) + // VALUE and EDGE tags + if (!parseLDConfigTag (pars, "VALUE", facename) || !parseLDConfigTag (pars, "EDGE", edgename)) continue; // Ensure that our colors are correct
--- a/src/common.h Thu May 16 02:26:50 2013 +0300 +++ b/src/common.h Thu May 16 22:59:10 2013 +0300 @@ -92,22 +92,11 @@ class OpenFile; class QApplication; -// ============================================================================= +// ----------------------------------------------------------------------------- // Plural expression -#define PLURAL(n) ((n != 1) ? "s" : "") - -// ----------------------------------------------------------------------------- -// Shortcut for formatting -#define PERFORM_FORMAT(in, out) \ - va_list v; \ - va_start (v, in); \ - char* out = vdynformat (in, v, 256); \ - va_end (v); - -// ----------------------------------------------------------------------------- -// Shortcuts for stuffing vertices into printf-formatting. -#define FMT_VERTEX "(%.3f, %.3f, %.3f)" -#define FVERTEX(V) V.x, V.y, V.z +template<class T> static inline const char* plural (T n) { + return (n != 1) ? "s" : ""; +} // ----------------------------------------------------------------------------- // Templated clamp @@ -131,15 +120,23 @@ } // Quick QString to const char* conversion -static inline const char* qchars (QString qstr) { +static inline const char* qchars (const QString& qstr) { return qstr.toStdString ().c_str (); } static const double pi = 3.14159265358979323846f; -#ifdef IN_IDE_PARSER // KDevelop workaround +#ifdef IN_IDE_PARSER // KDevelop workarounds: // Current function name static const char* __func__ = ""; + +#ifndef va_start +#define va_start(va, arg) +#endif // va_start + +#ifndef va_end +#define va_end(va) +#endif // va_end #endif // IN_IDE_PARSER // -----------------------------------------------------------------------------
--- a/src/configDialog.cpp Thu May 16 02:26:50 2013 +0300 +++ b/src/configDialog.cpp Thu May 16 22:59:10 2013 +0300 @@ -120,11 +120,10 @@ "colored in the object list. A red polygon will have its description " "written in red text."); - cb_colorBFC = new QCheckBox ("Red/green BFC view"); + cb_colorBFC = new QCheckBox ("Red/green BFC view (incomplete)"); cb_colorBFC->setChecked (gl_colorbfc); - cb_colorBFC->setWhatsThis ("Polygons' front sides become green and back " - "sides red. Not implemented yet."); - + cb_colorBFC->setWhatsThis ("Polygons' front sides become green and back sides red."); + 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"); @@ -267,8 +266,8 @@ // ============================================================================= void ConfigDialog::initGridTab () { QWidget* tab = new QWidget; - QGridLayout* layout = new QGridLayout; - QVBoxLayout* l2 = new QVBoxLayout; + QGridLayout* gridlayout = new QGridLayout; + QVBoxLayout* mainlayout = new QVBoxLayout; QLabel* xlabel = new QLabel ("X"), *ylabel = new QLabel ("Y"), @@ -278,7 +277,7 @@ short i = 1; for (QLabel* label : std::initializer_list<QLabel*> ({xlabel, ylabel, zlabel, anglabel})) { label->setAlignment (Qt::AlignCenter); - layout->addWidget (label, 0, i++); + gridlayout->addWidget (label, 0, i++); } for (int i = 0; i < g_NumGrids; ++i) { @@ -292,20 +291,20 @@ QHBoxLayout* labellayout = new QHBoxLayout; labellayout->addWidget (lb_gridIcons[i]); labellayout->addWidget (lb_gridLabels[i]); - layout->addLayout (labellayout, i + 1, 0); + gridlayout->addLayout (labellayout, i + 1, 0); // Add the widgets for (int j = 0; j < 4; ++j) { dsb_gridData[i][j] = new QDoubleSpinBox; dsb_gridData[i][j]->setValue (g_GridInfo[i].confs[j]->value); - layout->addWidget (dsb_gridData[i][j], i + 1, j + 1); + gridlayout->addWidget (dsb_gridData[i][j], i + 1, j + 1); } } - l2->addLayout (layout); - l2->addStretch (1); + mainlayout->addLayout (gridlayout); + mainlayout->addStretch (1); - tab->setLayout (l2); + tab->setLayout (mainlayout); tabs->addTab (tab, "Grids"); } @@ -360,7 +359,7 @@ pathsBox->setLayout (pathsLayout); layout->addWidget (pathsBox); - layout->addSpacing (10); + layout->addStretch (1); tab->setLayout (layout); tabs->addTab (tab, "Ext. Programs");
--- a/src/dialogs.cpp Thu May 16 02:26:50 2013 +0300 +++ b/src/dialogs.cpp Thu May 16 22:59:10 2013 +0300 @@ -24,6 +24,7 @@ #include <QLabel> #include <QPushButton> #include <QBoxLayout> +#include <QGridLayout> #include "dialogs.h" #include "widgets.h" @@ -419,4 +420,51 @@ g_win->fullRefresh (); } +} + +RotationPointDialog::RotationPointDialog (QWidget* parent, Qt::WindowFlags f) : QDialog (parent, f) { + rb_rotpoint = new RadioBox ("Rotation Point", { "Object center", "Custom" }, 0, Qt::Vertical, this); + connect (rb_rotpoint, SIGNAL (valueChanged (int)), this, SLOT (radioBoxChanged ())); + + gb_customPos = new QGroupBox ("Custom point", this); + dsb_customX = new QDoubleSpinBox; + dsb_customY = new QDoubleSpinBox; + dsb_customZ = new QDoubleSpinBox; + + QGridLayout* customLayout = new QGridLayout (gb_customPos); + customLayout->setColumnStretch (1, 1); + customLayout->addWidget (new QLabel ("X"), 0, 0); + customLayout->addWidget (dsb_customX, 0, 1); + customLayout->addWidget (new QLabel ("Y"), 1, 0); + customLayout->addWidget (dsb_customY, 1, 1); + customLayout->addWidget (new QLabel ("Z"), 2, 0); + customLayout->addWidget (dsb_customZ, 2, 1); + + QVBoxLayout* layout = new QVBoxLayout (this); + layout->addWidget (rb_rotpoint); + layout->addWidget (gb_customPos); + layout->addWidget (makeButtonBox (*this)); +} + +bool RotationPointDialog::custom () const { + return rb_rotpoint->value () == 1; +} + +vertex RotationPointDialog::customPos () const { + return vertex (dsb_customX->value (), dsb_customY->value (), dsb_customZ->value ()); +} + +void RotationPointDialog::setCustom (bool custom) { + rb_rotpoint->setValue (custom == true ? 1 : 0); + gb_customPos->setEnabled (custom); +} + +void RotationPointDialog::setCustomPos (const vertex& pos) { + dsb_customX->setValue (pos[X]); + dsb_customY->setValue (pos[Y]); + dsb_customZ->setValue (pos[Z]); +} + +void RotationPointDialog::radioBoxChanged () { + setCustom (rb_rotpoint->value ()); } \ No newline at end of file
--- a/src/dialogs.h Thu May 16 02:26:50 2013 +0300 +++ b/src/dialogs.h Thu May 16 22:59:10 2013 +0300 @@ -4,6 +4,7 @@ #include <QDialog> #include "common.h" +class QGroupBox; class QDialogButtonBox; class QDoubleSpinBox; class QPushButton; @@ -74,6 +75,7 @@ QLineEdit* le_contents; }; +// ============================================================================= class LDrawPathDialog : public QDialog { Q_OBJECT @@ -99,6 +101,7 @@ void slot_exit (); }; +// ============================================================================= class NewPartDialog : public QDialog { public: enum { CCAL, NonCA, NoLicense }; @@ -112,4 +115,25 @@ RadioBox* rb_license, *rb_BFC; }; +// ============================================================================= +class RotationPointDialog : public QDialog { + Q_OBJECT + +public: + explicit RotationPointDialog (QWidget* parent = null, Qt::WindowFlags f = 0); + + vertex customPos () const; + bool custom () const; + void setCustom (bool custom); + void setCustomPos (const vertex& pos); + +private: + QDoubleSpinBox* dsb_customX, *dsb_customY, *dsb_customZ; + RadioBox* rb_rotpoint; + QGroupBox* gb_customPos; + +private slots: + void radioBoxChanged (); +}; + #endif // DIALOGS_H \ No newline at end of file
--- a/src/extprogs.cpp Thu May 16 02:26:50 2013 +0300 +++ b/src/extprogs.cpp Thu May 16 22:59:10 2013 +0300 @@ -137,11 +137,11 @@ writeObjects (objects, fp); -#ifndef RELEASE +#if 0 ushort idx = rand (); printf ("%s -> debug_%u\n", fname.chars (), idx); QFile::copy (fname.chars (), fmt ("debug_%u", idx)); -#endif // RELEASE +#endif // 0 fclose (fp); }
--- a/src/file.cpp Thu May 16 02:26:50 2013 +0300 +++ b/src/file.cpp Thu May 16 22:59:10 2013 +0300 @@ -227,7 +227,7 @@ g_loadedFiles.push_back (load); logf ("File %s parsed successfully (%lu warning%s).\n", - path.chars(), numWarnings, PLURAL (numWarnings)); + path.chars(), numWarnings, plural (numWarnings)); return load; }
--- a/src/gldraw.cpp Thu May 16 02:26:50 2013 +0300 +++ b/src/gldraw.cpp Thu May 16 22:59:10 2013 +0300 @@ -157,7 +157,10 @@ m_panX = m_panY = m_rotZ = 0.0f; // Set the default zoom based on the bounding box - m_zoom = g_BBox.size () * 6; + if (g_BBox.empty () == false) + m_zoom = g_BBox.size () * 6; + else + m_zoom = 30.0f; } // =============================================================================
--- a/src/gui.cpp Thu May 16 02:26:50 2013 +0300 +++ b/src/gui.cpp Thu May 16 22:59:10 2013 +0300 @@ -249,6 +249,7 @@ addMenuAction ("rotateYNeg"); // Rotate -Y addMenuAction ("rotateZPos"); // Rotate +Z addMenuAction ("rotateZNeg"); // Rotate -Z + addMenuAction ("rotpoint"); // Set Rotation Point initMenu ("E&xternal Programs"); addMenuAction ("ytruder"); @@ -361,6 +362,7 @@ addToolBarAction ("rotateYNeg"); addToolBarAction ("rotateZPos"); addToolBarAction ("rotateZNeg"); + addToolBarAction ("rotpoint"); // ========================================== initSingleToolBar ("Grids"); @@ -723,15 +725,11 @@ } // Update the GL renderer - for (LDObject* obj : m_sel) { - printf ("recompile %lu\n", obj->getIndex (g_curfile)); + for (LDObject* obj : m_sel) m_renderer->compileObject (obj); - } - for (LDObject* obj : priorSelection) { + for (LDObject* obj : priorSelection) printf ("recompile %lu\n", obj->getIndex (g_curfile)); - m_renderer->compileObject (obj); - } m_renderer->update (); } @@ -1065,7 +1063,7 @@ QIcon ico = makeColorIcon (col, 16); box->addItem (ico, fmt ("[%d] %s (%lu object%s)", - pair.first, col->name.chars (), pair.second, PLURAL (pair.second))); + pair.first, col->name.chars (), pair.second, plural (pair.second))); box->setItemData (row, pair.first); ++row;
--- a/src/gui_editactions.cpp Thu May 16 02:26:50 2013 +0300 +++ b/src/gui_editactions.cpp Thu May 16 22:59:10 2013 +0300 @@ -27,7 +27,6 @@ #include "colorSelectDialog.h" #include "historyDialog.h" #include "misc.h" -#include "bbox.h" #include "widgets.h" #include "extprogs.h" #include "gldraw.h" @@ -541,53 +540,40 @@ // ============================================================================= static void doRotate (const short l, const short m, const short n) { std::vector<LDObject*> sel = g_win->sel (); - bbox box; vertex origin; std::vector<vertex*> queue; const double angle = (pi * currentGrid ().confs[Grid::Angle]->value) / 360; // ref: http://en.wikipedia.org/wiki/Transformation_matrix#Rotation_2 + const double cosangle = cos (angle), + sinangle = sin (angle); + 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)), + (l * l * (1 - cosangle)) + cosangle, + (m * l * (1 - cosangle)) - (n * sinangle), + (n * l * (1 - cosangle)) + (m * sinangle), - (l * m * (1 - cos (angle))) + (n * sin (angle)), - (m * m * (1 - cos (angle))) + cos (angle), - (n * m * (1 - cos (angle))) - (l * sin (angle)), + (l * m * (1 - cosangle)) + (n * sinangle), + (m * m * (1 - cosangle)) + cosangle, + (n * m * (1 - cosangle)) - (l * sinangle), - (l * n * (1 - cos (angle))) - (m * sin (angle)), - (m * n * (1 - cos (angle))) + (l * sin (angle)), - (n * n * (1 - cos (angle))) + cos (angle) + (l * n * (1 - cosangle)) - (m * sinangle), + (m * n * (1 - cosangle)) + (l * sinangle), + (n * n * (1 - cosangle)) + cosangle }); - // Calculate center vertex - for (LDObject* obj : sel) { - if (obj->getType () == LDObject::Subfile) - box << static_cast<LDSubfile*> (obj)->pos; - else if (obj->getType () == LDObject::Radial) - box << static_cast<LDRadial*> (obj)->pos; - else - box << obj; - } - - origin = box.center (); + origin = rotPoint (sel); // Apply the above matrix to everything for (LDObject* obj : sel) { if (obj->vertices ()) for (short i = 0; i < obj->vertices (); ++i) queue.push_back (&obj->coords[i]); - else if (obj->getType () == LDObject::Subfile) { - LDSubfile* ref = static_cast<LDSubfile*> (obj); + else if (obj->hasMatrix ()) { + LDMatrixObject* mobj = static_cast<LDSubfile*> (obj); - queue.push_back (&ref->pos); - ref->transform = ref->transform * transform; - } else if (obj->getType () == LDObject::Radial) { - LDRadial* rad = static_cast<LDRadial*> (obj); - - queue.push_back (&rad->pos); - rad->transform = rad->transform * transform; + queue.push_back (&mobj->pos); + mobj->transform = mobj->transform * transform; } else if (obj->getType () == LDObject::Vertex) queue.push_back (&static_cast<LDVertex*> (obj)->pos); @@ -627,6 +613,11 @@ doRotate (0, 0, -1); } +// ========================================================================================================================================= +MAKE_ACTION (rotpoint, "Set Rotation Point", "rotpoint", "Configure the rotation point.", (0)) { + configRotationPoint (); +} + // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // =============================================================================
--- a/src/historyDialog.cpp Thu May 16 02:26:50 2013 +0300 +++ b/src/historyDialog.cpp Thu May 16 22:59:10 2013 +0300 @@ -128,8 +128,8 @@ case HISTORY_QuadSplit: { QuadSplitHistory* subentry = static_cast<QuadSplitHistory*> (entry); - ulong ulCount = subentry->paQuads.size (); - text.format ("Split %lu quad%s to triangles", ulCount, PLURAL (ulCount)); + ulong count = subentry->paQuads.size (); + text.format ("Split %lu quad%s to triangles", count, plural (count)); entryIcon = getIcon ("quad-split"); }
--- a/src/ldtypes.cpp Thu May 16 02:26:50 2013 +0300 +++ b/src/ldtypes.cpp Thu May 16 22:59:10 2013 +0300 @@ -385,7 +385,7 @@ if (!firstDetails) text += ", "; - str noun = fmt ("%s%s", g_saObjTypeNames[objType], PLURAL (objCount)); + str noun = fmt ("%s%s", g_saObjTypeNames[objType], plural (objCount)); // Plural of "vertex" is "vertices". Stupid English. if (objType == LDObject::Vertex && objCount != 1)
--- a/src/ldtypes.h Thu May 16 02:26:50 2013 +0300 +++ b/src/ldtypes.h Thu May 16 22:59:10 2013 +0300 @@ -24,7 +24,7 @@ class HistoryEntry; -#define IMPLEMENT_LDTYPE(T, NUMVERTS) \ +#define LDOBJ(T) \ LD##T () {} \ virtual ~LD##T () {} \ virtual LDObject::Type getType () const { \ @@ -35,9 +35,9 @@ return new LD##T (*this); \ } \ virtual void move (vertex vVector); \ - virtual short vertices () const { return NUMVERTS; } \ virtual HistoryEntry* invert (); +#define LDOBJ_VERTICES(V) virtual short vertices () const { return V; } #define LDOBJ_SETCOLORED(V) virtual bool isColored () const { return V; } #define LDOBJ_COLORED LDOBJ_SETCOLORED (true) #define LDOBJ_UNCOLORED LDOBJ_SETCOLORED (false) @@ -46,10 +46,29 @@ #define LDOBJ_SCHEMANTIC LDOBJ_CUSTOM_SCHEMANTIC { return true; } #define LDOBJ_NON_SCHEMANTIC LDOBJ_CUSTOM_SCHEMANTIC { return false; } +#define LDOBJ_SETMATRIX(V) virtual bool hasMatrix () const { return V; } +#define LDOBJ_HAS_MATRIX LDOBJ_SETMATRIX (true) +#define LDOBJ_NO_MATRIX LDOBJ_SETMATRIX (false) + class QListWidgetItem; class LDSubfile; // ============================================================================= +// LDMatrixObject +// +// Common code for objects with matrices +// ============================================================================= +class LDMatrixObject { +public: + LDMatrixObject () {} + LDMatrixObject (const matrix& transform, const vertex& pos) : + transform (transform), pos (pos) {} + + matrix transform; + vertex pos; +}; + +// ============================================================================= // LDObject // // Base class object for all LD* types. Each LDObject represents a single line @@ -142,6 +161,7 @@ QListWidgetItem* qObjListEntry; bool hidden () const { return m_hidden; } + virtual bool hasMatrix () const { return false; } virtual HistoryEntry* invert (); LDObject* next () const; LDObject* prev () const; @@ -164,9 +184,11 @@ // ============================================================================= class LDGibberish : public LDObject { public: - IMPLEMENT_LDTYPE (Gibberish, 0) + LDOBJ (Gibberish) + LDOBJ_VERTICES (0) LDOBJ_UNCOLORED LDOBJ_SCHEMANTIC + LDOBJ_NO_MATRIX LDGibberish (str _zContent, str _zReason); @@ -184,9 +206,11 @@ // ============================================================================= class LDEmpty : public LDObject { public: - IMPLEMENT_LDTYPE (Empty, 0) + LDOBJ (Empty) + LDOBJ_VERTICES (0) LDOBJ_UNCOLORED LDOBJ_NON_SCHEMANTIC + LDOBJ_NO_MATRIX }; // ============================================================================= @@ -197,9 +221,11 @@ // ============================================================================= class LDComment : public LDObject { public: - IMPLEMENT_LDTYPE (Comment, 0) + LDOBJ (Comment) + LDOBJ_VERTICES (0) LDOBJ_UNCOLORED LDOBJ_NON_SCHEMANTIC + LDOBJ_NO_MATRIX LDComment (str text) : text (text) {} @@ -214,19 +240,13 @@ // ============================================================================= class LDBFC : public LDComment { public: - enum Type { - CertifyCCW, - CCW, - CertifyCW, - CW, - NoCertify, // Winding becomes disabled (0 BFC NOCERTIFY) - InvertNext, // Winding is inverted for next object (0 BFC INVERTNEXT) - NumStatements - }; + enum Type { CertifyCCW, CCW, CertifyCW, CW, NoCertify, InvertNext, NumStatements }; - IMPLEMENT_LDTYPE (BFC, 0) + LDOBJ (BFC) + LDOBJ_VERTICES (0) LDOBJ_UNCOLORED LDOBJ_CUSTOM_SCHEMANTIC { return (type == InvertNext); } + LDOBJ_NO_MATRIX LDBFC (const LDBFC::Type type) : type (type) {} @@ -241,14 +261,14 @@ // // Represents a single code-1 subfile reference. // ============================================================================= -class LDSubfile : public LDObject { +class LDSubfile : public LDObject, public LDMatrixObject { public: - IMPLEMENT_LDTYPE (Subfile, 0) + LDOBJ (Subfile) + LDOBJ_VERTICES (0) LDOBJ_COLORED LDOBJ_SCHEMANTIC + LDOBJ_HAS_MATRIX - vertex pos; // Position of the subpart (TODO: should get rid of this) - 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. @@ -266,9 +286,11 @@ // ============================================================================= class LDLine : public LDObject { public: - IMPLEMENT_LDTYPE (Line, 2) + LDOBJ (Line) + LDOBJ_VERTICES (2) LDOBJ_COLORED LDOBJ_SCHEMANTIC + LDOBJ_NO_MATRIX LDLine (vertex v1, vertex v2); }; @@ -281,9 +303,11 @@ // ============================================================================= class LDCondLine : public LDLine { public: - IMPLEMENT_LDTYPE (CondLine, 4) + LDOBJ (CondLine) + LDOBJ_VERTICES (4) LDOBJ_COLORED LDOBJ_SCHEMANTIC + LDOBJ_NO_MATRIX }; // ============================================================================= @@ -295,9 +319,11 @@ // ============================================================================= class LDTriangle : public LDObject { public: - IMPLEMENT_LDTYPE (Triangle, 3) + LDOBJ (Triangle) + LDOBJ_VERTICES (3) LDOBJ_COLORED LDOBJ_SCHEMANTIC + LDOBJ_NO_MATRIX LDTriangle (vertex _v0, vertex _v1, vertex _v2) { coords[0] = _v0; @@ -314,9 +340,11 @@ // ============================================================================= class LDQuad : public LDObject { public: - IMPLEMENT_LDTYPE (Quad, 4) + LDOBJ (Quad) + LDOBJ_VERTICES (4) LDOBJ_COLORED LDOBJ_SCHEMANTIC + LDOBJ_NO_MATRIX // Split this quad into two triangles (note: heap-allocated) vector<LDTriangle*> splitToTriangles (); @@ -332,9 +360,11 @@ // ============================================================================= class LDVertex : public LDObject { public: - IMPLEMENT_LDTYPE (Vertex, 0) // TODO: move pos to vaCoords[0] + LDOBJ (Vertex) + LDOBJ_VERTICES (0) // TODO: move pos to vaCoords[0] LDOBJ_COLORED LDOBJ_NON_SCHEMANTIC + LDOBJ_NO_MATRIX vertex pos; }; @@ -348,7 +378,7 @@ // allow part authors to add radial primitives to parts without much hassle about // non-existant primitive parts. // ============================================================================= -class LDRadial : public LDObject { +class LDRadial : public LDObject, public LDMatrixObject { public: enum Type { Circle, @@ -360,17 +390,17 @@ NumTypes }; - IMPLEMENT_LDTYPE (Radial, 0) + LDOBJ (Radial) + LDOBJ_VERTICES (0) LDOBJ_COLORED LDOBJ_SCHEMANTIC + LDOBJ_HAS_MATRIX LDRadial::Type radType; - vertex pos; - matrix transform; short divs, segs, 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) {} + LDMatrixObject (transform, pos), radType (radType), divs (divs), segs (segs), ringNum (ringNum) {} // Returns a set of objects that provide the equivalent of this radial. // Note: objects are heap-allocated.
--- a/src/misc.cpp Thu May 16 02:26:50 2013 +0300 +++ b/src/misc.cpp Thu May 16 22:59:10 2013 +0300 @@ -22,6 +22,8 @@ #include "common.h" #include "misc.h" #include "gui.h" +#include "bbox.h" +#include "dialogs.h" // Prime number table. const ushort g_primes[NUM_PRIMES] = { @@ -98,6 +100,10 @@ cfg (float, grid_fine_y, 0.1f); cfg (float, grid_fine_z, 0.1f); cfg (float, grid_fine_angle, 7.5f); +cfg (int, edit_rotpoint, 0); +cfg (float, edit_rotpoint_x, 0.0f); // TODO: make a vertexconfig object and use it here +cfg (float, edit_rotpoint_y, 0.0f); +cfg (float, edit_rotpoint_z, 0.0f); const gridinfo g_GridInfo[3] = { { "Coarse", { &grid_coarse_x, &grid_coarse_y, &grid_coarse_z, &grid_coarse_angle }, &ACTION (gridCoarse) }, @@ -204,6 +210,42 @@ } // ============================================================================= +vertex rotPoint (const vector<LDObject*>& objs) { + if (edit_rotpoint == 1) + return vertex (edit_rotpoint_x, edit_rotpoint_y, edit_rotpoint_z); + + bbox box; + + // Calculate center vertex + for (LDObject* obj : objs) { + if (obj->getType () == LDObject::Subfile) + box << static_cast<LDSubfile*> (obj)->pos; + else if (obj->getType () == LDObject::Radial) + box << static_cast<LDRadial*> (obj)->pos; + else + box << obj; + } + + return box.center (); +} + +void configRotationPoint () { + RotationPointDialog dlg; + dlg.setCustom (edit_rotpoint); + dlg.setCustomPos (vertex (edit_rotpoint_x, edit_rotpoint_y, edit_rotpoint_z)); + + if (!dlg.exec ()) + return; + + edit_rotpoint = dlg.custom (); + + vertex pos = dlg.customPos (); + edit_rotpoint_x = pos[X]; + edit_rotpoint_y = pos[Y]; + edit_rotpoint_z = pos[Z]; +} + +// ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= StringParser::StringParser (str inText, char sep) {
--- a/src/misc.h Thu May 16 02:26:50 2013 +0300 +++ b/src/misc.h Thu May 16 22:59:10 2013 +0300 @@ -54,6 +54,11 @@ return g_GridInfo[grid]; } +// ============================================================================= +vertex rotPoint (const vector<LDObject*>& objs); +void configRotationPoint (); + +// ============================================================================= namespace Grid { enum Type { Coarse,
--- a/src/types.cpp Thu May 16 02:26:50 2013 +0300 +++ b/src/types.cpp Thu May 16 22:59:10 2013 +0300 @@ -130,12 +130,12 @@ 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; }