Mon, 25 Mar 2013 00:44:11 +0200
Restructured inlining to use a proper caching.. one cache per sub-file reference? What was I thinking? *whacks self with a 55295.dat*
file.cpp | file | annotate | diff | comparison | revisions | |
file.h | file | annotate | diff | comparison | revisions | |
gldraw.cpp | file | annotate | diff | comparison | revisions | |
gui.cpp | file | annotate | diff | comparison | revisions | |
ldtypes.cpp | file | annotate | diff | comparison | revisions | |
ldtypes.h | file | annotate | diff | comparison | revisions | |
misc.cpp | file | annotate | diff | comparison | revisions | |
misc.h | file | annotate | diff | comparison | revisions | |
types.h | file | annotate | diff | comparison | revisions |
--- a/file.cpp Sun Mar 24 21:45:19 2013 +0200 +++ b/file.cpp Mon Mar 25 00:44:11 2013 +0200 @@ -41,6 +41,14 @@ OpenFile* openDATFile (str path) { logf ("Opening %s...\n", path.chars()); + // Convert the file name to lowercase since some parts contain uppercase + // file names. I'll assume here that the library will always use lowercase + // file names for the actual parts.. + str zTruePath = -path; +#ifndef WIN32 + zTruePath.replace ("\\", "/"); +#endif // WIN32 + FILE* fp = fopen (path.chars (), "r"); if (!fp && ~io_ldpath.value) { @@ -51,9 +59,8 @@ for (ushort i = 0; i < sizeof saSubdirectories / sizeof *saSubdirectories; ++i) { str zFilePath = str::mkfmt ("%s" DIRSLASH "%s" DIRSLASH "%s", - io_ldpath.value.chars(), saSubdirectories[i], path.chars()); + io_ldpath.value.chars(), saSubdirectories[i], zTruePath.chars()); - printf ("trying %s...\n", zFilePath.chars ()); fp = fopen (zFilePath.chars (), "r"); if (fp) @@ -113,8 +120,8 @@ // ============================================================================= // Clear everything from the model void OpenFile::close () { - FOREACH (LDObject, *, obj, objects) - delete obj; + for (ulong j = 0; j < objects.size(); ++j) + delete objects[j]; delete this; } @@ -127,8 +134,10 @@ return; // Remove all loaded files and the objects they contain - FOREACH (OpenFile, *, f, g_LoadedFiles) + for (ushort i = 0; i < g_LoadedFiles.size(); i++) { + OpenFile* f = g_LoadedFiles[i]; f->close (); + } // Clear the array g_LoadedFiles.clear(); @@ -185,7 +194,9 @@ return false; // Write all entries now - FOREACH (LDObject, *, obj, objects) { + for (ulong i = 0; i < objects.size(); ++i) { + LDObject* obj = objects[i]; + // LDraw requires lines to have DOS line endings str zLine = str::mkfmt ("%s\r\n",obj->getContents ().chars ()); @@ -273,10 +284,6 @@ CHECK_TOKEN_COUNT (15) CHECK_TOKEN_NUMBERS (1, 13) -#ifndef WIN32 - tokens[14].replace ("\\", "/"); -#endif // WIN32 - // Try open the file OpenFile* pFile = loadSubfile (tokens[14]);
--- a/file.h Sun Mar 24 21:45:19 2013 +0200 +++ b/file.h Mon Mar 25 00:44:11 2013 +0200 @@ -33,6 +33,7 @@ public: str zFileName, zTitle; vector<LDObject*> objects; + vector<LDObject*> objCache; // Cache of this file's contents, if desired // Closes this OpenFile. The object is deleted in the process. void close ();
--- a/gldraw.cpp Sun Mar 24 21:45:19 2013 +0200 +++ b/gldraw.cpp Mon Mar 25 00:44:11 2013 +0200 @@ -247,10 +247,12 @@ { LDSubfile* ref = static_cast<LDSubfile*> (obj); - vector<LDObject*> objs = ref->inlineContents (true, ref->mMatrix, ref->vPosition, true); + vector<LDObject*> objs = ref->inlineContents (true, true); - for (ulong i = 0; i < (ulong)objs.size(); ++i) + for (ulong i = 0; i < (ulong)objs.size(); ++i) { compileOneObject (objs[i], bBackSide); + delete objs[i]; + } } break;
--- a/gui.cpp Sun Mar 24 21:45:19 2013 +0200 +++ b/gui.cpp Mon Mar 25 00:44:11 2013 +0200 @@ -411,8 +411,7 @@ 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->mMatrix, - ref->vPosition, true); + vector<LDObject*> objs = ref->inlineContents (bDeep, true); // Merge in the inlined objects FOREACH (LDObject, *, inlineobj, objs)
--- a/ldtypes.cpp Sun Mar 24 21:45:19 2013 +0200 +++ b/ldtypes.cpp Mon Mar 25 00:44:11 2013 +0200 @@ -107,22 +107,6 @@ } // ============================================================================= -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -// ============================================================================= -ulong LDObject::getIndex () { - if (!g_CurrentFile) - return -1u; - - // TODO: shouldn't rely on g_CurrentFile - for (ulong i = 0; i < g_CurrentFile->objects.size(); ++i) { - if (g_CurrentFile->objects[i] == this) - return i; - } - - return -1u; -} - -// ============================================================================= str LDComment::getContents () { return str::mkfmt ("0 %s", zText.chars ()); } @@ -260,76 +244,114 @@ LDTriangle::~LDTriangle () {} LDVertex::~LDVertex () {} -#define ADD_TYPE(T,N) \ +#define TRANSFORM_TYPE(T,N) \ case OBJ_##T: \ - { \ - LD##T* newobj = static_cast<LD##T*> (obj)->makeClone (); \ - for (short i = 0; i < N; ++i) \ - newobj->vaCoords[i].transform (mMatrix, pos); \ - \ - objs.push_back (newobj); \ - } \ - break; + + +// ============================================================================= +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// ============================================================================= +template<class T> static void transformSubObject (LDObject* obj, matrix mMatrix, + vertex vPos, short dColor) +{ + T* newobj = static_cast<T*> (obj); + for (short i = 0; i < (short)(sizeof newobj->vaCoords / sizeof *newobj->vaCoords); ++i) + newobj->vaCoords[i].transform (mMatrix, vPos); + + if (newobj->dColor == dMainColor) + newobj->dColor = dColor; +} + +// ----------------------------------------------------------------------------- +static void transformObject (LDObject* obj, matrix mMatrix, vertex vPos, + short dColor) +{ + switch (obj->getType()) { + case OBJ_Line: + transformSubObject<LDLine> (obj, mMatrix, vPos, dColor); + break; + case OBJ_CondLine: + transformSubObject<LDCondLine> (obj, mMatrix, vPos, dColor); + break; + case OBJ_Triangle: + transformSubObject<LDTriangle> (obj, mMatrix, vPos, dColor); + break; + case OBJ_Quad: + transformSubObject<LDQuad> (obj, mMatrix, vPos, dColor); + break; + case OBJ_Subfile: + { + LDSubfile* ref = static_cast<LDSubfile*> (obj); + + matrix mNewMatrix = mMatrix * ref->mMatrix; + ref->vPosition.transform (mMatrix, vPos); + ref->mMatrix = mNewMatrix; + } + + break; + default: + break; + } +} // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= -static uint g_uTabs = 0; -vector<LDObject*> LDSubfile::inlineContents (bool bDeepInline, matrix mMatrix, vertex pos, bool bCache) { - // If we have this cached, just return that. - if (bDeepInline && objCache.size ()) - return objCache; - - vector<LDObject*> objs; +vector<LDObject*> LDSubfile::inlineContents (bool bDeepInline, bool bCache) { + vector<LDObject*> objs, cache; - FOREACH (LDObject, *, obj, pFile->objects) { - switch (obj->getType()) { - case OBJ_Comment: - case OBJ_Empty: - case OBJ_Gibberish: - case OBJ_Unidentified: - case OBJ_Vertex: - break; // Skip non-essentials + // If we have this cached, just clone that + if (bDeepInline && pFile->objCache.size ()) { + FOREACH (LDObject, *, obj, pFile->objCache) + objs.push_back (obj->makeClone ()); + } else { + if (!bDeepInline) + bCache = false; - ADD_TYPE (Line, 2) - ADD_TYPE (Triangle, 3) - ADD_TYPE (Quad, 4) - ADD_TYPE (CondLine, 4) - - case OBJ_Subfile: - { + FOREACH (LDObject, *, obj, pFile->objects) { + // Skip those without schemantic meaning + switch (obj->getType ()) { + case OBJ_Comment: + case OBJ_Empty: + case OBJ_Gibberish: + case OBJ_Unidentified: + case OBJ_Vertex: + continue; + default: + break; + } + + // Got another sub-file reference, inline it if we're deep-inlining. If not, + // just add it into the objects normally. Also, we only cache immediate + // subfiles and this is not one. Yay, recursion! + if (bDeepInline && obj->getType() == OBJ_Subfile) { 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) { - matrix mNewMatrix = mMatrix * ref->mMatrix; - vertex vNewPos = ref->vPosition; - vNewPos.transform (mMatrix, pos); - - // Only cache immediate subfiles, this is not one. Yay recursion! - g_uTabs++; - vector<LDObject*> otherobjs = ref->inlineContents (true, mNewMatrix, vNewPos, false); - g_uTabs--; + vector<LDObject*> otherobjs = ref->inlineContents (true, false); + + FOREACH (LDObject, *, otherobj, otherobjs) { + // Cache this object if desired + if (bCache) + cache.push_back (otherobj->makeClone ()); - for (ulong i = 0; i < otherobjs.size(); ++i) - objs.push_back (otherobjs[i]); - } else { - LDSubfile* clone = ref->makeClone (); - clone->vPosition.transform (mMatrix, pos); - clone->mMatrix *= mMatrix; - - objs.push_back (clone); + objs.push_back (otherobj); } + } else { + // Cache it, if desired + if (bCache) + cache.push_back (obj->makeClone ()); + + objs.push_back (obj->makeClone ()); } - - break; } + + if (bCache) + pFile->objCache = cache; } - // If we cache this stuff, keep it around - if (bCache) - objCache = objs; + // Transform the objects + FOREACH (LDObject, *, obj, objs) + transformObject (obj, mMatrix, vPosition, dColor); return objs; }
--- a/ldtypes.h Sun Mar 24 21:45:19 2013 +0200 +++ b/ldtypes.h Mon Mar 25 00:44:11 2013 +0200 @@ -67,7 +67,7 @@ virtual ~LDObject (); // Index (i.e. line number) of this object - unsigned long getIndex (); + long getIndex (OpenFile* pFile); // Color used by this object. Comments, gibberish and empty entries // do not use this field. @@ -93,8 +93,6 @@ // object and any pointers to it become invalid. void replace (LDObject* replacement); - long getIndex (OpenFile* pFile); - QTreeWidgetItem* qObjListEntry; }; @@ -155,11 +153,9 @@ matrix mMatrix; // Transformation matrix for the subpart str zFileName; // Filename of the subpart OpenFile* pFile; // Pointer to opened file for this subfile. nullptr if unopened. - vector<LDObject*> objCache; // Cache of this file's contents, if desired // Gets the inlined contents of this subfile. - std::vector<LDObject*> inlineContents (bool bDeepInline, matrix mMatrix, - vertex pos, bool bCache); + std::vector<LDObject*> inlineContents (bool bDeepInline, bool bCache); }; // =============================================================================
--- a/misc.cpp Sun Mar 24 21:45:19 2013 +0200 +++ b/misc.cpp Mon Mar 25 00:44:11 2013 +0200 @@ -85,15 +85,4 @@ } return true; -} - -// ============================================================================= -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -// ============================================================================= -template<class T> bool in (T needle, std::initializer_list<T> haystack) { - for (size_t i = 0; i < haystack.size(); ++i) - if (needle = haystack[i]) - return true; - - return false; } \ No newline at end of file
--- a/misc.h Sun Mar 24 21:45:19 2013 +0200 +++ b/misc.h Mon Mar 25 00:44:11 2013 +0200 @@ -35,6 +35,12 @@ // Converts a float value to a string value. str ftoa (double fCoord); -template<class T> bool in (T needle, std::initializer_list<T> haystack); +template<class T> bool in (T needle, std::initializer_list<T> haystack) { + for (size_t i = 0; i < haystack.size(); ++i) + if (needle = *(haystack.begin() + i)) + return true; + + return false; +} #endif // __MISC_H__ \ No newline at end of file