Tue, 16 Apr 2013 02:13:11 +0300
Added the radial type, this one sure has been on my wishlist for a while. :)
gldraw.cpp | file | annotate | diff | comparison | revisions | |
gui.cpp | file | annotate | diff | comparison | revisions | |
gui_actions.cpp | file | annotate | diff | comparison | revisions | |
icons/add-radial.png | file | annotate | diff | comparison | revisions | |
icons/corner-verts.png | file | annotate | diff | comparison | revisions | |
icons/radial.png | file | annotate | diff | comparison | revisions | |
icons/select-all.png | file | annotate | diff | comparison | revisions | |
icons/select-color.png | file | annotate | diff | comparison | revisions | |
icons/select-type.png | file | annotate | diff | comparison | revisions | |
ldtypes.cpp | file | annotate | diff | comparison | revisions | |
ldtypes.h | file | annotate | diff | comparison | revisions | |
zz_addObjectDialog.cpp | file | annotate | diff | comparison | revisions | |
zz_addObjectDialog.h | file | annotate | diff | comparison | revisions |
--- a/gldraw.cpp Mon Apr 15 18:07:29 2013 +0300 +++ b/gldraw.cpp Tue Apr 16 02:13:11 2013 +0300 @@ -347,8 +347,19 @@ case OBJ_Subfile: { LDSubfile* ref = static_cast<LDSubfile*> (obj); + vector<LDObject*> objs = ref->inlineContents (true, true); - vector<LDObject*> objs = ref->inlineContents (true, true); + for (LDObject* obj : objs) { + compileOneObject (obj); + delete obj; + } + } + break; + + case OBJ_Radial: + { + LDRadial* pRadial = static_cast<LDRadial*> (obj); + std::vector<LDObject*> objs = pRadial->decompose (true); for (LDObject* obj : objs) { compileOneObject (obj);
--- a/gui.cpp Mon Apr 15 18:07:29 2013 +0300 +++ b/gui.cpp Tue Apr 16 02:13:11 2013 +0300 @@ -54,6 +54,7 @@ EXTERN_ACTION (newQuad) EXTERN_ACTION (newVertex) EXTERN_ACTION (newComment) +EXTERN_ACTION (newRadial) EXTERN_ACTION (help) EXTERN_ACTION (about) EXTERN_ACTION (aboutQt) @@ -71,6 +72,7 @@ #ifndef RELEASE EXTERN_ACTION (addTestQuad) +EXTERN_ACTION (addTestRadial) #endif // RELEASE vector<actionmeta> g_ActionMeta; @@ -180,6 +182,7 @@ qInsertMenu->addAction (ACTION_NAME (newCondLine)); // New Conditional Line qInsertMenu->addAction (ACTION_NAME (newComment)); // New Comment qInsertMenu->addAction (ACTION_NAME (newVertex)); // New Vertex + qInsertMenu->addAction (ACTION_NAME (newRadial)); // New Radial // Edit menu qEditMenu = menuBar ()->addMenu (tr ("&Edit")); @@ -222,6 +225,7 @@ // Debug menu qDebugMenu = menuBar ()->addMenu (tr ("&Debug")); qDebugMenu->addAction (ACTION_NAME (addTestQuad)); // Add Test Quad + qDebugMenu->addAction (ACTION_NAME (addTestRadial)); // Add Test Radial #endif // RELEASE // Help menu @@ -283,6 +287,7 @@ ADD_TOOLBAR_ITEM (newCondLine) ADD_TOOLBAR_ITEM (newComment) ADD_TOOLBAR_ITEM (newVertex) + ADD_TOOLBAR_ITEM (newRadial) initSingleToolBar ("Edit"); ADD_TOOLBAR_ITEM (undo)
--- a/gui_actions.cpp Mon Apr 15 18:07:29 2013 +0300 +++ b/gui_actions.cpp Tue Apr 16 02:13:11 2013 +0300 @@ -119,10 +119,15 @@ ACTION (newComment, "New Comment", "add-comment", "Creates a new comment.", 0) { AddObjectDialog::staticDialog (OBJ_Comment, g_ForgeWindow); } + ACTION (newVertex, "New Vertex", "add-vertex", "Creates a new vertex.", 0) { AddObjectDialog::staticDialog (OBJ_Vertex, g_ForgeWindow); } +ACTION (newRadial, "New Radial", "add-radial", "Creates a new radial.", 0) { + AddObjectDialog::staticDialog (OBJ_Radial, g_ForgeWindow); +} + ACTION (help, "Help", "help", "Shows the " APPNAME_DISPLAY " help manual.", KEY (F1)) { } @@ -200,9 +205,9 @@ // ============================================================================= // Debug things #ifndef RELEASE -ACTION (addTestQuad, "Add Test Quad", "add-quad", "Adds a test quad.", CTRL_SHIFT (Q)) { +ACTION (addTestQuad, "Add Test Quad", "add-quad", "Adds a test quad.", (0)) { LDQuad* pQuad = new LDQuad; - pQuad->dColor = rand () % 16; + pQuad->dColor = rand () % 24; pQuad->vaCoords[0] = { 1.0f, 0.0f, 1.0f}; pQuad->vaCoords[1] = {-1.0f, 0.0f, 1.0f}; pQuad->vaCoords[2] = {-1.0f, 0.0f, -1.0f}; @@ -212,4 +217,20 @@ History::addEntry (new AddHistory ({(ulong)pQuad->getIndex (g_CurrentFile)}, {pQuad->clone ()})); g_ForgeWindow->refresh (); } + +ACTION (addTestRadial, "Add Test Radial", "add-radial", "Adds a test radial.", (0)) { + LDRadial* pRad = new LDRadial; + pRad->eRadialType = LDRadial::Cone; + pRad->mMatrix = g_mIdentity; + pRad->vPosition = vertex (0, 0, 0); + pRad->dColor = rand () % 24; + pRad->dDivisions = 16; + pRad->dRingNum = 2; + pRad->dSegments = 16; + + g_CurrentFile->addObject (pRad); + History::addEntry (new AddHistory ({(ulong)pRad->getIndex (g_CurrentFile)}, {pRad->clone ()})); + g_ForgeWindow->refresh (); +} + #endif // RELEASE \ No newline at end of file
--- a/ldtypes.cpp Mon Apr 15 18:07:29 2013 +0300 +++ b/ldtypes.cpp Tue Apr 16 02:13:11 2013 +0300 @@ -24,6 +24,7 @@ char const* g_saObjTypeNames[] = { "subfile", + "radial", "quadrilateral", "triangle", "line", @@ -39,6 +40,7 @@ // Should probably get rid of this array sometime char const* g_saObjTypeIcons[] = { "subfile", + "radial", "quad", "triangle", "line", @@ -56,16 +58,14 @@ // ============================================================================= // LDObject constructors LDObject::LDObject () { - commonInit (); -} - -void LDObject::commonInit () { qObjListEntry = null; parent = null; } +void LDObject::commonInit () { +} + LDGibberish::LDGibberish () { - commonInit (); dColor = -1; } @@ -73,46 +73,42 @@ zContents = _zContent; zReason = _zReason; dColor = -1; - - commonInit (); } LDEmpty::LDEmpty () { - commonInit (); dColor = -1; } LDComment::LDComment () { - commonInit (); dColor = -1; } LDSubfile::LDSubfile () { - commonInit (); + } LDLine::LDLine () { - commonInit (); + } LDTriangle::LDTriangle () { - commonInit (); + } LDQuad::LDQuad () { - commonInit (); + } LDCondLine::LDCondLine () { - commonInit (); + } LDVertex::LDVertex () { - commonInit (); + } LDBFC::LDBFC () { - commonInit (); + } // ============================================================================= @@ -273,6 +269,7 @@ LDTriangle::~LDTriangle () {} LDVertex::~LDVertex () {} LDBFC::~LDBFC () {} +LDRadial::~LDRadial () {} // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * @@ -474,7 +471,7 @@ } // ============================================================================= -LDSubfile* LDObject::topLevelParent () { +LDObject* LDObject::topLevelParent () { if (!parent) return null; @@ -483,7 +480,7 @@ while (it->parent) it = it->parent; - return static_cast<LDSubfile*> (it); + return it; } @@ -504,6 +501,10 @@ vPosition += vVector; } +void LDRadial::move (vertex vVector) { + vPosition += vVector; +} + void LDLine::move (vertex vVector) { for (short i = 0; i < 2; ++i) vaCoords[i] += vVector; @@ -522,4 +523,152 @@ void LDCondLine::move (vertex vVector) { for (short i = 0; i < 4; ++i) vaCoords[i] += vVector; +} + +// ===========================================f================================== +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// ============================================================================= +LDRadial::LDRadial () { + +} + +const char* g_saRadialTypeNames[] = { + "Circle", + "Cylinder", + "Disc", + "Disc Negative", + "Ring", + "Cone", + null +}; + +std::vector<LDObject*> LDRadial::decompose (bool bTransform) { + std::vector<LDObject*> paObjects; + + for (short i = 0; i < dSegments; ++i) { + double x0 = cos ((i * 2 * pi) / dDivisions), + x1 = cos (((i + 1) * 2 * pi) / dDivisions), + z0 = sin ((i * 2 * pi) / dDivisions), + z1 = sin (((i + 1) * 2 * pi) / dDivisions); + + switch (eRadialType) { + case LDRadial::Circle: + { + vertex v0 (x0, 0.0f, z0), + v1 (x1, 0.0f, z1); + + if (bTransform) { + v0.transform (mMatrix, vPosition); + v1.transform (mMatrix, vPosition); + } + + LDLine* pLine = new LDLine; + pLine->vaCoords[0] = v0; + pLine->vaCoords[1] = v1; + pLine->dColor = dEdgeColor; + pLine->parent = this; + + paObjects.push_back (pLine); + } + break; + + case LDRadial::Cylinder: + case LDRadial::Ring: + case LDRadial::Cone: + { + double x2, x3, z2, z3; + double y0, y1, y2, y3; + + if (eRadialType == LDRadial::Cylinder) { + x2 = x1; + x3 = x0; + z2 = z1; + z3 = z0; + + y0 = y1 = 0.0f; + y2 = y3 = 1.0f; + } else { + x2 = x1 * (dRingNum + 1); + x3 = x0 * (dRingNum + 1); + z2 = z1 * (dRingNum + 1); + z3 = z0 * (dRingNum + 1); + + x0 *= dRingNum; + x1 *= dRingNum; + z0 *= dRingNum; + z1 *= dRingNum; + + if (eRadialType == LDRadial::Ring) { + y0 = y1 = y2 = y3 = 0.0f; + } else { + y0 = y1 = 1.0f; + y2 = y3 = 0.0f; + } + } + + vertex v0 (x0, y0, z0), + v1 (x1, y1, z1), + v2 (x2, y2, z2), + v3 (x3, y3, z3); + + if (bTransform) { + v0.transform (mMatrix, vPosition); + v1.transform (mMatrix, vPosition); + v2.transform (mMatrix, vPosition); + v3.transform (mMatrix, vPosition); + } + + LDQuad* pQuad = new LDQuad; + pQuad->vaCoords[0] = v0; + pQuad->vaCoords[1] = v1; + pQuad->vaCoords[2] = v2; + pQuad->vaCoords[3] = v3; + pQuad->dColor = dColor; + pQuad->parent = this; + + paObjects.push_back (pQuad); + } + break; + + case LDRadial::Disc: + case LDRadial::DiscNeg: + { + double x2, z2; + + if (eRadialType == LDRadial::Disc) { + x2 = z2 = 0.0f; + } else { + x2 = (x0 >= 0.0f) ? 1.0f : -1.0f; + z2 = (z0 >= 0.0f) ? 1.0f : -1.0f; + } + + vertex v0 (x0, 0.0f, z0), + v1 (x1, 0.0f, z1), + v2 (x2, 0.0f, z2); + + if (bTransform) { + v0.transform (mMatrix, vPosition); + v1.transform (mMatrix, vPosition); + v2.transform (mMatrix, vPosition); + } + + LDTriangle* pSeg = new LDTriangle; + pSeg->vaCoords[0] = v0; + pSeg->vaCoords[1] = v1; + pSeg->vaCoords[2] = v2; + pSeg->dColor = dColor; + pSeg->parent = this; + + paObjects.push_back (pSeg); + } + break; + } + } + + return paObjects; +} + +str LDRadial::getContents () { + // TODO + return "0 !LDFORGE RADIAL"; } \ No newline at end of file
--- a/ldtypes.h Mon Apr 15 18:07:29 2013 +0300 +++ b/ldtypes.h Tue Apr 16 02:13:11 2013 +0300 @@ -44,6 +44,7 @@ // ============================================================================= enum LDObjectType_e { OBJ_Subfile, // Object represents a sub-file reference + OBJ_Radial, // Object represents a generic radial OBJ_Quad, // Object represents a quadrilateral OBJ_Triangle, // Object represents a triangle OBJ_Line, // Object represents a line @@ -81,7 +82,7 @@ uint uGLList, uGLPickList; // Object this object was referenced from, if any - LDSubfile* parent; + LDObject* parent; // Type enumerator of this object virtual LDObjectType_e getType () const { @@ -111,8 +112,8 @@ // Moves this object using the given vertex as a movement vector virtual void move (vertex vVector); - // What subfile in the current file ultimately references this? - LDSubfile* topLevelParent (); + // What object in the current file ultimately references this? + LDObject* topLevelParent (); static void moveObjects (std::vector<LDObject*> objs, const bool bUp); static str objectListContents (std::vector<LDObject*>& objs); @@ -281,7 +282,7 @@ // ============================================================================= // LDVertex // -// The vertex is another LDForce-specific extension. It represents a single +// The vertex is an LDForce-specific extension which represents a single // vertex which can be used as a parameter to tools or to store coordinates // with. Vertices are a part authoring tool and they should not appear in // finished parts. @@ -294,6 +295,44 @@ }; // ============================================================================= +// LDRadial +// +// The generic radial primitive (radial for short) is another LDforge-specific +// extension which represents an arbitrary circular primitive. Radials can appear +// as circles, cylinders, rings, cones, discs and disc negatives; the point is to +// allow part authors to add radial primitives to parts without much hassle about +// non-existant primitive parts. +// ============================================================================= +class LDRadial : public LDObject { +public: + enum Type { + Circle, + Cylinder, + Disc, + DiscNeg, + Ring, + Cone, + NumTypes + }; + + IMPLEMENT_LDTYPE (Radial) + + LDRadial::Type eRadialType; + vertex vPosition; + matrix mMatrix; + short dDivisions, dSegments, dRingNum; + + LDRadial (LDRadial::Type eRadialType, vertex vPosition, matrix mMatrix, + short dDivisions, short dSegments, short dRingNum) : + eRadialType (eRadialType), vPosition (vPosition), mMatrix (mMatrix), + dDivisions (dDivisions), dSegments (dSegments), dRingNum (dRingNum) {} + + std::vector<LDObject*> decompose (bool bTransform); +}; + +extern const char* g_saRadialTypeNames[]; + +// ============================================================================= // Object type names. Pass the return value of getType as the index to get a // string representation of the object's type. extern const char* g_saObjTypeNames[];
--- a/zz_addObjectDialog.cpp Mon Apr 15 18:07:29 2013 +0300 +++ b/zz_addObjectDialog.cpp Tue Apr 16 02:13:11 2013 +0300 @@ -47,18 +47,48 @@ case OBJ_Comment: qCommentLine = new QLineEdit; break; + case OBJ_Line: dCoordCount = 6; break; + case OBJ_Triangle: dCoordCount = 9; break; + case OBJ_Quad: case OBJ_CondLine: dCoordCount = 12; break; + case OBJ_Vertex: dCoordCount = 3; + + case OBJ_Radial: + dCoordCount = 3; + + qRadialTypeLabel = new QLabel ("Type:"); + qRadialResolutionLabel = new QLabel ("Resolution:"); + qRadialSegmentsLabel = new QLabel ("Segments:"); + qRadialRingNumLabel = new QLabel ("Ring number:"); + + qRadialType = new QComboBox; + + for (int i = 0; i < LDRadial::NumTypes; ++i) + qRadialType->addItem (g_saRadialTypeNames[i]); + + connect (qRadialType, SIGNAL (currentIndexChanged (int)), this, SLOT (slot_radialTypeChanged (int))); + + qRadialResolution = new QComboBox; + qRadialResolution->addItems ({"Normal (16)", "Hi-Res (48)"}); + + qRadialSegments = new QSpinBox; + qRadialSegments->setMinimum (1); + + qRadialRingNum = new QSpinBox; + qRadialRingNum->setEnabled (false); + break; + default: break; } @@ -72,6 +102,7 @@ case OBJ_Triangle: case OBJ_Vertex: case OBJ_Subfile: + case OBJ_Radial: bUsesColor = true; break; default: @@ -102,6 +133,18 @@ case OBJ_Comment: qLayout->addWidget (qCommentLine, 0, 1); break; + + case OBJ_Radial: + qLayout->addWidget (qRadialTypeLabel, 1, 1); + qLayout->addWidget (qRadialType, 1, 2); + qLayout->addWidget (qRadialResolutionLabel, 2, 1); + qLayout->addWidget (qRadialResolution, 2, 2); + qLayout->addWidget (qRadialSegmentsLabel, 3, 1); + qLayout->addWidget (qRadialSegments, 3, 2); + qLayout->addWidget (qRadialRingNumLabel, 4, 1); + qLayout->addWidget (qRadialRingNum, 4, 2); + break; + default: break; } @@ -115,10 +158,10 @@ for (short i = 0; i < dCoordCount; ++i) qCoordLayout->addWidget (qaCoordinates[i], (i / 3), (i % 3)); - qLayout->addLayout (qCoordLayout, 0, 1, 2, 1); + qLayout->addLayout (qCoordLayout, 0, 1, 2, 2); } - qLayout->addWidget (qButtons, 2, 1); + qLayout->addWidget (qButtons, 5, 1); setLayout (qLayout); setWindowTitle (str::mkfmt (APPNAME_DISPLAY " - new %s", g_saObjTypeNames[type]).chars()); @@ -148,6 +191,14 @@ // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= +void AddObjectDialog::slot_radialTypeChanged (int dType) { + LDRadial::Type eType = (LDRadial::Type) dType; + qRadialRingNum->setEnabled (eType == LDRadial::Ring || eType == LDRadial::Cone); +} + +// ============================================================================= +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// ============================================================================= void AddObjectDialog::staticDialog (const LDObjectType_e type, ForgeWindow* window) { AddObjectDialog dlg (type, window); LDObject* obj = null; @@ -205,6 +256,23 @@ } break; + case OBJ_Radial: + { + LDRadial* pRad = new LDRadial; + pRad->dColor = dlg.dColor; + pRad->vPosition.x = dlg.qaCoordinates[0]->value (); + pRad->vPosition.y = dlg.qaCoordinates[1]->value (); + pRad->vPosition.z = dlg.qaCoordinates[2]->value (); + pRad->dDivisions = (dlg.qRadialResolution->currentIndex () == 0) ? 16 : 48; + pRad->dSegments = min<short> (dlg.qRadialSegments->value (), pRad->dDivisions); + pRad->eRadialType = (LDRadial::Type) dlg.qRadialType->currentIndex (); + pRad->dRingNum = dlg.qRadialRingNum->value (); + pRad->mMatrix = g_mIdentity; + + obj = pRad; + } + break; + default: break; }
--- a/zz_addObjectDialog.h Mon Apr 15 18:07:29 2013 +0300 +++ b/zz_addObjectDialog.h Tue Apr 16 02:13:11 2013 +0300 @@ -26,6 +26,7 @@ #include <qlabel.h> #include <qspinbox.h> #include <qpushbutton.h> +#include <qcombobox.h> class AddObjectDialog : public QDialog { Q_OBJECT @@ -45,6 +46,12 @@ // Color selection dialog button QPushButton* qColorButton; + // Radial stuff + QComboBox* qRadialType, *qRadialResolution; + QSpinBox* qRadialSegments, *qRadialRingNum; + QLabel* qRadialTypeLabel, *qRadialResolutionLabel, *qRadialSegmentsLabel, + *qRadialRingNumLabel; + QDialogButtonBox* qButtons; private: @@ -54,6 +61,7 @@ private slots: void slot_colorButtonClicked (); + void slot_radialTypeChanged (int dType); }; #endif // __ZZ_ADDOBJECTDIALOG_H__ \ No newline at end of file