#define USE_THREADS 0 #ifdef UNICODE #undef UNICODE #endif #define NOMINMAX #include #include #include #include "PreprocessorFactory.h" #include "Parser.h" #include "Environment.h" #include "MeshKdTree.h" #include "Preprocessor.h" #include "common.h" #include "PreprocessorThread.h" #include "ObjExporter.h" #include "SceneGraph.h" #include "GlobalLinesRenderer.h" #include "ViewCellsManager.h" #ifdef USE_QT #include "QtPreprocessorThread.h" #include "QtGlViewer.h" #include "QtGlRenderer.h" #else #if USE_THREADS #include "BoostPreprocessorThread.h" #endif #endif #include "ResourceManager.h" #include "GlRenderer.h" #define USE_EXE_PATH false using namespace GtpVisibilityPreprocessor; //Preprocessor *preprocessor = NULL; GlRendererWidget *rendererWidget = NULL; //GlobalLinesRenderer *globalLinesRenderer = NULL; // DLL function signature typedef GlRendererWidget *(*importFunction)(Preprocessor *); void Cleanup() { DEL_PTR(rendererWidget); DEL_PTR(preprocessor); Environment::DelSingleton(); MeshManager::DelSingleton(); MaterialManager::DelSingleton(); } static string ReplaceSuffix(string filename, string a, string b) { string result = filename; int pos = (int)filename.rfind(a, (int)filename.size() - 1); if (pos == filename.size() - a.size()) { result.replace(pos, a.size(), b); } return result; } static int SplitFilenames(const string str, vector &filenames) { int pos = 0; while(1) { int npos = (int)str.find(';', pos); if (npos < 0 || npos - pos < 1) break; filenames.push_back(string(str, pos, npos - pos)); pos = npos + 1; } filenames.push_back(string(str, pos, str.size() - pos)); return (int)filenames.size(); } static string GetInternFilename(const string &filename, const string newSuffix) { vector filenames; const int files = SplitFilenames(filename, filenames); vector::const_iterator sit, sit_end = filenames.end(); string kdFilename; int i = 0; for (sit = filenames.begin(); sit != sit_end; ++ sit, ++ i) { string currentFile = *sit; string strippedFilename; if (i == 0) { strippedFilename = currentFile; } else { char *str = StripPath(currentFile.c_str()); strippedFilename = string(str); delete [] str; } string suffix("_"); if (i == (int)filenames.size() - 1) { suffix = newSuffix; } if (strstr(strippedFilename.c_str(), ".x3d")) { kdFilename += ReplaceSuffix(strippedFilename, ".x3d", suffix); } else if (strstr(strippedFilename.c_str(), ".dat")) { kdFilename += ReplaceSuffix(strippedFilename, ".dat", suffix); } else if (strstr(strippedFilename.c_str(), ".obj")) { kdFilename += ReplaceSuffix(strippedFilename, ".obj", suffix); } else { cerr << "Error: Currently unsupported format for kd, filename " << currentFile << endl; } } //cout << "kdfilename: " << kdFilename << endl; return kdFilename; } int main(int argc, char **argv) { //Now just call this function at the start of your program and if you're //compiling in debug mode (F5), any leaks will be displayed in the Output //window when the program shuts down. If you're not in debug mode this will //be ignored. Use it as you will! //note: from GDNet Direct [3.8.04 - 3.14.04] void detectMemoryLeaks() { #if 1 _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF|_CRTDBG_ALLOC_MEM_DF); _CrtSetReportMode(_CRT_ASSERT,_CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_ASSERT,_CRTDBG_FILE_STDERR); #endif int returnCode = 0; InitTiming(); Debug.open("debug.log"); #if 0 cout<<"Allocating 1.5GB..."<Parse(argc, argv, USE_EXE_PATH); MeshKdTree::ParseEnvironment(); char buff[128]; Environment::GetSingleton()->GetStringValue("Preprocessor.type", buff); string preprocessorType(buff); if (!(preprocessor = PreprocessorFactory::CreatePreprocessor(preprocessorType))) { Environment::DelSingleton(); cerr << "Unknown preprocessor type" << endl; exit(1); } Environment::GetSingleton()->GetStringValue("Scene.filename", buff); string filename(buff); const string externKdTree = ReplaceSuffix(filename, ".obj", ".kdf"); const string internKdTree = GetInternFilename(filename, preprocessor->mLoadMeshes ? ".kdm" : ".kdt"); if (preprocessor->InitRayCast(externKdTree, internKdTree)) { cout << "ray casting initialized!" << endl; } else { cout << "ray casting initialization failed!" << endl; Cleanup(); exit(1); } //Debug << "using pvs type " << PVS_TYPE << endl; ///////////// //-- load scene if (!preprocessor->LoadScene(filename)) { cout << "loading file " << filename << " failed" << endl; Cleanup(); exit(1); } //////////// //-- initialize external ray caster if (preprocessor->LoadInternKdTree(internKdTree)) { cout << "intern kd tree loaded!" << endl; } else { cout << "loading intern kd tree failed!" << endl; Cleanup(); exit(1); } // export objects as obj if (preprocessor->mExportObj) { if (strstr(filename.c_str(), ".obj")) { cerr << "already in obj format" << endl; if (0) preprocessor->ExportObj("test.obj", preprocessor->mObjects); } else { const string objname = GetInternFilename(filename, ".obj"); cout << "exporting scene to " << objname << endl; bool success = preprocessor->ExportObj(objname, preprocessor->mObjects); if (success) { cout << "finished exporting obj" << endl; } else { cerr << "error exporting " << objname << endl; } } } // parse view cells related options if (!preprocessor->PrepareViewCells()) { cerr << "error: view cells could not be loaded" << endl; Cleanup(); exit(1); } string viewCellPointsFile; if (strstr(filename.c_str(), ".obj")) viewCellPointsFile = ReplaceSuffix(filename, ".obj", ".vc"); else if (strstr(filename.c_str(), ".dat")) viewCellPointsFile = ReplaceSuffix(filename, ".dat", ".vc"); else if (strstr(filename.c_str(), ".x3d")) viewCellPointsFile = ReplaceSuffix(filename, ".x3d", ".vc"); bool importRandomViewCells; Environment::GetSingleton()->GetBoolValue("ViewCells.importRandomViewCells", importRandomViewCells); if (importRandomViewCells) { cout << "importing random view cells" << endl; preprocessor->mViewCellsManager->ImportRandomViewCells(viewCellPointsFile); cout << "finished" << endl; } bool useHwGlobalLines; Environment::GetSingleton()->GetBoolValue("Preprocessor.useHwGlobalLines", useHwGlobalLines); if (useHwGlobalLines) preprocessor->PrepareHwGlobalLines(); // create a preprocessor thread (note: capsulates calls to boost fuctions!) PreprocessorThread *pt = NULL; #ifdef TRY_GLOBAL_LINES preprocessor->PrepareHwGlobalLines(); globalLinesRenderer->Run(); #else #ifdef USE_QT // create a qt application first (must be created before any opengl widget ...) QApplication *app = new QApplication(argc, NULL); pt = new QtPreprocessorThread(preprocessor); #else //#if USE_THREADS // pt = new BoostPreprocessorThread(preprocessor); //#else // use a dummy thread pt = new DummyPreprocessorThread(preprocessor); //#endif #endif preprocessor->SetThread(pt); bool guiSupported = false; bool useRendererBuffer = true; int frames; Environment::GetSingleton()->GetIntValue("Preprocessor.pvsRenderErrorSamples", frames); #ifdef USE_QT if (importRandomViewCells || frames) { QGLFormat f; f.setStencil(true); QGLFormat::setDefaultFormat(f); // NOTE: render texture should be power of 2 and square // renderer must be initialised // $$matt preprocessor->renderer = new QtGlRendererBuffer(1024, 1024, preprocessor->mSceneGraph, preprocessor->mViewCellsManager, preprocessor->mKdTree); } #endif if (preprocessor->mUseGlRenderer || preprocessor->mUseGlDebugger) { #ifdef USE_QT cout << "using gl widget" << endl; // create and run the preprocessor application in a parallel thread pt->InitThread(); pt->RunThread(); // display the render widget if (!rendererWidget) { if (!QGLFormat::hasOpenGL() || !QGLPixelBuffer::hasOpenGLPbuffers()) { QMessageBox::information(0, "OpenGL pbuffers", "This system does not support OpenGL/pbuffers.", QMessageBox::Ok); return NULL; } rendererWidget = new QtGlRendererWidget(preprocessor->mSceneGraph, preprocessor->mViewCellsManager, preprocessor->mKdTree); rendererWidget->Show(); QtGlViewer *viewer = new QtGlViewer(NULL, (QtGlRendererWidget *)rendererWidget); viewer->show(); guiSupported = true; } bool exportRandomViewCells; Environment::GetSingleton()->GetBoolValue("ViewCells.exportRandomViewCells", exportRandomViewCells); if (exportRandomViewCells) { cout << "exporting random view cells" << endl; preprocessor->mViewCellsManager->ExportRandomViewCells(viewCellPointsFile); cout << "finished" << endl; } /*bool evaluatePixelError; Environment::GetSingleton()->GetBoolValue("Preprocessor.evaluatePixelError", evaluatePixelError); if (evaluatePixelError) { cout << "evaluating pixel error" << endl; preprocessor->ComputeRenderError(); }*/ qApp->exec(); #endif } // no gui available if (!guiSupported) { if (preprocessor->mUseGlRenderer || preprocessor->mUseGlDebugger) cout << "warning: gui not supported!" << endl; preprocessor->mUseGlRenderer = false; preprocessor->mUseGlDebugger = false; } if (!(preprocessor->mUseGlRenderer || preprocessor->mUseGlDebugger)) { cout << "executing main thread" << endl; // just call the mail method -> will be executed in the main thread pt->Main(); } #endif // release memory Cleanup(); delete pt; return returnCode; }