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.

Sun, 24 Mar 2013 18:03:33 +0200

author
Santeri Piippo <crimsondusk64@gmail.com>
date
Sun, 24 Mar 2013 18:03:33 +0200
changeset 63
aa40ce18f869
parent 62
915fc477cb6a
child 64
ada4679d5bce

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 ();
Binary file icons/inline-deep.png has changed
Binary file icons/inline.png has changed
--- 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);
 };
 
 // =============================================================================

mercurial