Sun, 24 Mar 2013 18:03:33 +0200
Implemented the inline action to expose inlining to the user. Also added a `deep inline` action to inline subfile recursively down into polygons and lines only.
common.h | file | annotate | diff | comparison | revisions | |
gldraw.cpp | file | annotate | diff | comparison | revisions | |
gui.cpp | file | annotate | diff | comparison | revisions | |
gui.h | file | annotate | diff | comparison | revisions | |
icons/inline-deep.png | file | annotate | diff | comparison | revisions | |
icons/inline.png | file | annotate | diff | comparison | revisions | |
ldtypes.cpp | file | annotate | diff | comparison | revisions | |
ldtypes.h | file | annotate | diff | comparison | revisions |
--- a/common.h Sun Mar 24 01:05:59 2013 +0200 +++ b/common.h Sun Mar 24 18:03:33 2013 +0200 @@ -158,4 +158,8 @@ typedef uint32_t xulong; typedef uint64_t xulonglong; +#define FOREACH(T, PTRS, COUNTER, ARRAY) \ + for (T PTRS* COUNTER##ptr = &(*ARRAY.begin ()), PTRS COUNTER = *COUNTER##ptr; \ + COUNTER##ptr < &(*ARRAY.end ()); COUNTER = *(++COUNTER##ptr)) + #endif \ No newline at end of file
--- a/gldraw.cpp Sun Mar 24 01:05:59 2013 +0200 +++ b/gldraw.cpp Sun Mar 24 18:03:33 2013 +0200 @@ -247,7 +247,7 @@ { LDSubfile* ref = static_cast<LDSubfile*> (obj); - vector<LDObject*> objs = ref->inlineContents (ref->faMatrix, ref->vPosition, true); + vector<LDObject*> objs = ref->inlineContents (true, ref->faMatrix, ref->vPosition, true); for (ulong i = 0; i < (ulong)objs.size(); ++i) compileOneObject (objs[i], bBackSide);
--- a/gui.cpp Sun Mar 24 01:05:59 2013 +0200 +++ b/gui.cpp Sun Mar 24 18:03:33 2013 +0200 @@ -97,6 +97,7 @@ MAKE_ACTION (setColor, "Set Color", "palette", "Set the color on given objects.") MAKE_ACTION (inline, "Inline", "inline", "Inline selected subfiles.") + MAKE_ACTION (deepInline, "Deep Inline", "inline-deep", "Recursively inline selected subfiles down to polygons only.") MAKE_ACTION (splitQuads, "Split Quads", "quad-split", "Split quads into triangles.") MAKE_ACTION (setContents, "Set Contents", "set-contents", "Set the raw code of this object.") MAKE_ACTION (makeBorders, "Make Borders", "make-borders", "Add borders around given polygons.") @@ -130,7 +131,6 @@ QAction* qaDisabledActions[] = { qAct_newSubfile, qAct_about, - qAct_inline, qAct_help, }; @@ -172,6 +172,7 @@ qEditMenu->addAction (qAct_setColor); // Set Color qEditMenu->addSeparator (); // ----- qEditMenu->addAction (qAct_inline); // Inline + qEditMenu->addAction (qAct_deepInline); // Deep Inline qEditMenu->addAction (qAct_splitQuads); // Split Quads qEditMenu->addAction (qAct_setContents); // Set Contents qEditMenu->addAction (qAct_makeBorders); // Make Borders @@ -400,12 +401,54 @@ refresh (); } +// ============================================================================= +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// ============================================================================= void ForgeWindow::slot_newVertex () { AddObjectDialog::staticDialog (OBJ_Vertex, this); } +// ============================================================================= +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// ============================================================================= +void ForgeWindow::doInline (bool bDeep) { + vector<LDObject*> sel = getSelectedObjects (); + + FOREACH (LDObject, *, obj, sel) { + // Obviously, only subfiles can be inlined. + if (obj->getType() != OBJ_Subfile) + continue; + + // Get the index of the subfile so we know where to insert the + // inlined contents. + long idx = obj->getIndex (g_CurrentFile); + if (idx == -1) + continue; + + LDSubfile* ref = static_cast<LDSubfile*> (obj); + + // Get the inlined objects. These are clones of the subfile's contents. + vector<LDObject*> objs = ref->inlineContents (bDeep, ref->faMatrix, + ref->vPosition, true); + + // Merge in the inlined objects + FOREACH (LDObject, *, inlineobj, objs) + g_CurrentFile->objects.insert (g_CurrentFile->objects.begin() + idx++, inlineobj); + + // Delete the subfile now as it's been inlined. + g_CurrentFile->forgetObject (ref); + delete ref; + } + + refresh (); +} + void ForgeWindow::slot_inline () { + doInline (false); +} +void ForgeWindow::slot_deepInline () { + doInline (true); } // =============================================================================
--- a/gui.h Sun Mar 24 01:05:59 2013 +0200 +++ b/gui.h Sun Mar 24 18:03:33 2013 +0200 @@ -59,7 +59,7 @@ QAction* qAct_cut, *qAct_copy, *qAct_paste, *qAct_delete; QAction* qAct_newSubfile, *qAct_newLine, *qAct_newTriangle, *qAct_newQuad; QAction* qAct_newCondLine, *qAct_newComment, *qAct_newVertex; - QAction* qAct_splitQuads, *qAct_setContents, *qAct_inline, *qAct_makeBorders; + QAction* qAct_splitQuads, *qAct_setContents, *qAct_inline, *qAct_deepInline, *qAct_makeBorders; QAction* qAct_settings; QAction* qAct_help, *qAct_about, *qAct_aboutQt; QAction* qAct_setColor; @@ -79,6 +79,7 @@ void createToolbars (); bool copyToClipboard (); void deleteSelection (); + void doInline (bool bDeep); private slots: void slot_selectionChanged (); @@ -98,6 +99,7 @@ void slot_newVertex (); void slot_inline (); + void slot_deepInline (); void slot_splitQuads (); void slot_setContents (); void slot_makeBorders ();
--- a/ldtypes.cpp Sun Mar 24 01:05:59 2013 +0200 +++ b/ldtypes.cpp Sun Mar 24 18:03:33 2013 +0200 @@ -191,12 +191,9 @@ // ============================================================================= void LDQuad::splitToTriangles () { // Find the index of this quad - ulong ulIndex; - for (ulIndex = 0; ulIndex < g_CurrentFile->objects.size(); ++ulIndex) - if (g_CurrentFile->objects[ulIndex] == this) - break; + long lIndex = getIndex (g_CurrentFile); - if (ulIndex >= g_CurrentFile->objects.size()) { + if (lIndex == -1) { // couldn't find it? logf (LOG_Error, "LDQuad::splitToTriangles: Couldn't find quad %p in " "current object list!!\n", this); @@ -226,8 +223,8 @@ // Replace the quad with the first triangle and add the second triangle // after the first one. - g_CurrentFile->objects[ulIndex] = tri1; - g_CurrentFile->objects.insert (g_CurrentFile->objects.begin() + ulIndex + 1, tri2); + g_CurrentFile->objects[lIndex] = tri1; + g_CurrentFile->objects.insert (g_CurrentFile->objects.begin() + lIndex + 1, tri2); // Delete this quad now, it has been split. delete this; @@ -280,9 +277,9 @@ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= static uint g_uTabs = 0; -vector<LDObject*> LDSubfile::inlineContents (double* matrix, vertex pos, bool bCache) { +vector<LDObject*> LDSubfile::inlineContents (bool bDeepInline, double* matrix, vertex pos, bool bCache) { // If we have this cached, just return that. - if (objCache.size ()) + if (bDeepInline && objCache.size ()) return objCache; vector<LDObject*> objs; @@ -304,24 +301,38 @@ ADD_TYPE (CondLine, 4) case OBJ_Subfile: - // Got another sub-file reference, inline it. - LDSubfile* ref = static_cast<LDSubfile*> (obj); - - double faNewMatrix[9]; - - for (short i = 0; i < 9; ++i) - faNewMatrix[i] = matrix[i] * ref->faMatrix[i]; + { + LDSubfile* ref = static_cast<LDSubfile*> (obj); + + // Got another sub-file reference, inline it if we're deep-inlining. If not, + // just add it into the objects normally. + if (bDeepInline) { + double faNewMatrix[9]; + + for (short i = 0; i < 9; ++i) + faNewMatrix[i] = matrix[i] * ref->faMatrix[i]; + + vertex vNewPos = ref->vPosition; + vNewPos.transform (matrix, pos); + + // Only cache immediate subfiles, this is not one. Yay recursion! + g_uTabs++; + vector<LDObject*> otherobjs = ref->inlineContents (true, faNewMatrix, vNewPos, false); + g_uTabs--; + + for (ulong i = 0; i < otherobjs.size(); ++i) + objs.push_back (otherobjs[i]); + } else { + LDSubfile* clone = ref->makeClone (); + clone->vPosition.transform (matrix, pos); + + for (short i = 0; i < 9; ++i) + clone->faMatrix[i] *= matrix[i]; + + objs.push_back (clone); + } + } - vertex vNewPos = ref->vPosition; - vNewPos.transform (matrix, pos); - - // Only cache immediate subfiles, this is not one. Yay recursion! - g_uTabs++; - vector<LDObject*> otherobjs = ref->inlineContents (faNewMatrix, vNewPos, false); - g_uTabs--; - - for (ulong i = 0; i < otherobjs.size(); ++i) - objs.push_back (otherobjs[i]); break; } } @@ -331,4 +342,17 @@ objCache = objs; return objs; +} + +// ============================================================================= +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// ============================================================================= +long LDObject::getIndex (OpenFile* pFile) { + long lIndex; + + for (lIndex = 0; lIndex < (long)pFile->objects.size(); ++lIndex) + if (pFile->objects[lIndex] == this) + return lIndex; + + return -1; } \ No newline at end of file
--- a/ldtypes.h Sun Mar 24 01:05:59 2013 +0200 +++ b/ldtypes.h Sun Mar 24 18:03:33 2013 +0200 @@ -92,6 +92,8 @@ // object and any pointers to it become invalid. void replace (LDObject* replacement); + long getIndex (OpenFile* pFile); + QTreeWidgetItem* qObjListEntry; }; @@ -155,7 +157,8 @@ vector<LDObject*> objCache; // Cache of this file's contents, if desired // Gets the inlined contents of this subfile. - std::vector<LDObject*> inlineContents (double* matrix, vertex pos, bool bCache); + std::vector<LDObject*> inlineContents (bool bDeepInline, double* matrix, + vertex pos, bool bCache); }; // =============================================================================