#include "SceneGraph.h" #include "Exporter.h" #include "UnigraphicsParser.h" #include "X3dParser.h" #include "Preprocessor.h" #include "ViewCell.h" #include "Environment.h" #include "RenderSimulator.h" Preprocessor::Preprocessor(): mKdTree(NULL), mBspTree(NULL), mVspKdTree(NULL), mRenderSimulator(NULL) { } Preprocessor::~Preprocessor() { DEL_PTR(mBspTree); DEL_PTR(mKdTree); DEL_PTR(mRenderSimulator); DeleteViewCells(); } bool Preprocessor::LoadViewCells(const string filename) { X3dParser parser; environment->GetFloatValue("ViewCells.height", parser.mViewCellHeight); return parser.ParseFile(filename, mViewCells); } bool Preprocessor::ParseViewCellsOptions() { // parse type of view cells char viewCellsStr[64]; environment->GetStringValue("ViewCells.hierarchy", viewCellsStr); if (strcmp(viewCellsStr, "bspTree") == 0) { ViewCell::sHierarchy = ViewCell::BSP; } else if (strcmp(viewCellsStr, "kdTree") == 0) { ViewCell::sHierarchy = ViewCell::KD; } else if (strcmp(viewCellsStr, "vspTree") == 0) { ViewCell::sHierarchy = ViewCell::VSP; } else if (strcmp(viewCellsStr, "sceneDependent") == 0) { //TODO } else { cerr<<"Wrong view cells type" << viewCellsStr << endl; exit(1); } return true; } RenderSimulator *Preprocessor::GetRenderSimulator() { if (mRenderSimulator) return mRenderSimulator; float objRenderCost = 0, vcOverhead = 0, moveSpeed = 0; environment->GetFloatValue("Simulation.objRenderCost",objRenderCost); environment->GetFloatValue("Simulation.vcOverhead", vcOverhead); environment->GetFloatValue("Simulation.moveSpeed", moveSpeed); Debug << "render simulator using render cost=" << objRenderCost << ", vc overhead=" << vcOverhead << ", move speed=" << moveSpeed << endl; if (ViewCell::sHierarchy == ViewCell::BSP) { mRenderSimulator = new BspViewCellRenderSimulator(objRenderCost, vcOverhead, moveSpeed, mBspTree); Debug << "creating bsp render simulator" << endl; } else if (ViewCell::sHierarchy == ViewCell::KD)// KD view cells { mRenderSimulator = new KdViewCellRenderSimulator(objRenderCost, vcOverhead, moveSpeed, mKdTree); Debug << "creating kd render simulator" << endl; } else { Debug << "not implemented yet" << endl; return NULL; } return mRenderSimulator; } void Preprocessor::DeleteViewCells() { for (int i = 0; i < (int)mViewCells.size(); ++ i) { Mesh *mesh = mViewCells[i]->GetMesh(); DEL_PTR(mesh); } CLEAR_CONTAINER(mViewCells); } int SplitFilenames(const string str, vector &filenames) { int pos = 0; while(1) { int npos = 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 filenames.size(); } bool Preprocessor::LoadScene(const string filename) { // use leaf nodes of the original spatial hiearrchy as occludees mSceneGraph = new SceneGraph; Parser *parser; vector filenames; int files = SplitFilenames(filename, filenames); cout<ParseFile(filename, &mSceneGraph->mRoot); delete parser; } else { // root for different files mSceneGraph->mRoot = new SceneGraphNode; for (int i= 0; i < filenames.size(); i++) { if (strstr(filenames[i].c_str(), ".x3d")) parser = new X3dParser; else parser = new UnigraphicsParser; SceneGraphNode *node; if (parser->ParseFile(filenames[i], &node)) { mSceneGraph->mRoot->mChildren.push_back(node); // at least one file parsed result = true; } delete parser; } } if (result) { mSceneGraph->AssignObjectIds(); int intersectables, faces; mSceneGraph->GetStatistics(intersectables, faces); cout<GetRoot(); mSceneGraph->CollectObjects(&root->mObjects); mKdTree->Construct(); return true; } void Preprocessor::KdTreeStatistics(ostream &s) { s<GetStatistics(); } void Preprocessor::BspTreeStatistics(ostream &s) { s << mBspTree->GetStatistics(); } bool Preprocessor::Export( const string filename, const bool scene, const bool kdtree, const bool bsptree ) { Exporter *exporter = Exporter::GetExporter(filename); if (exporter) { if (scene) exporter->ExportScene(mSceneGraph->mRoot); if (kdtree) { exporter->SetWireframe(); exporter->ExportKdTree(*mKdTree); } if (bsptree) { //exporter->SetWireframe(); exporter->ExportBspTree(*mBspTree); } delete exporter; return true; } return false; } void Preprocessor::ExportSplits(const ObjectContainer &objects, const RayContainer &sampleRays, const int visSamples) { Exporter *exporter = Exporter::GetExporter("bsp_splits.x3d"); if (exporter) { Material m; m.mDiffuseColor = RgbColor(1, 0, 0); exporter->SetForcedMaterial(m); exporter->SetWireframe(); exporter->ExportBspSplits(*mBspTree, true); // take forced material, else big scenes cannot be viewed m.mDiffuseColor = RgbColor(0, 1, 0); exporter->SetForcedMaterial(m); exporter->SetFilled(); exporter->ResetForcedMaterial(); // export rays if (0) { RayContainer outRays; for (int i = 0; i < sampleRays.size(); ++ i) { // only rays piercing geometry if (!sampleRays[i]->intersections.empty()) outRays.push_back(sampleRays[i]); } if (BspTree::sConstructionMethod == BspTree::FROM_SAMPLES) { // export rays exporter->ExportRays(outRays, 1000, RgbColor(1, 1, 0)); } } if (1) ExportSceneGeometry(exporter, objects); delete exporter; } } inline bool vc_gt(ViewCell *a, ViewCell *b) { return a->GetPvs().GetSize() > b->GetPvs().GetSize(); } void Preprocessor::ExportBspPvs(const ObjectContainer &objects, const RayContainer &sampleRays, const int visSamples) { const int leafOut = 10; ViewCell::NewMail(); //-- some rays for output const int raysOut = min((int)sampleRays.size(), visSamples); cout << "visualization using " << visSamples << " samples" << endl; vector vcRays[leafOut]; if (0) { //-- some random view cells and rays for output vector bspLeaves; for (int i = 0; i < leafOut; ++ i) bspLeaves.push_back(mBspTree->GetRandomLeaf()); for (int i = 0; i < bspLeaves.size(); ++ i) { cout << "creating output for view cell " << i << " ... "; // check whether we can add the current ray to the output rays for (int k = 0; k < raysOut; ++ k) { Ray *ray = sampleRays[k]; for (int j = 0; j < (int)ray->bspIntersections.size(); ++ j) { BspLeaf *leaf = ray->bspIntersections[j].mLeaf; if (bspLeaves[i]->GetViewCell() == leaf->GetViewCell()) { vcRays[i].push_back(ray); } } } Intersectable::NewMail(); BspViewCell *vc = dynamic_cast(bspLeaves[i]->GetViewCell()); //bspLeaves[j]->Mail(); char s[64]; sprintf(s, "bsp-pvs%04d.x3d", i); Exporter *exporter = Exporter::GetExporter(s); exporter->SetFilled(); ViewCellPvsMap::iterator it = vc->GetPvs().mEntries.begin(); exporter->SetWireframe(); //exporter->SetFilled(); Material m;//= RandomMaterial(); m.mDiffuseColor = RgbColor(0, 1, 0); exporter->SetForcedMaterial(m); if (vc->GetMesh()) exporter->ExportViewCell(vc); else { PolygonContainer cell; // export view cell geometry mBspTree->ConstructGeometry(vc, cell); exporter->ExportPolygons(cell); CLEAR_CONTAINER(cell); } Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize() << ", piercing rays=" << (int)vcRays[i].size() << endl; // export rays piercing this view cell exporter->ExportRays(vcRays[i], 1000, RgbColor(0, 1, 0)); m.mDiffuseColor = RgbColor(1, 0, 0); exporter->SetForcedMaterial(m); // exporter->SetWireframe(); exporter->SetFilled(); // output PVS of view cell for (; it != vc->GetPvs().mEntries.end(); ++ it) { Intersectable *intersect = (*it).first; if (!intersect->Mailed()) { exporter->ExportIntersectable(intersect); intersect->Mail(); } } // output rest of the objects if (0) { Material m;//= RandomMaterial(); m.mDiffuseColor = RgbColor(0, 0, 1); exporter->SetForcedMaterial(m); for (int j = 0; j < objects.size(); ++ j) if (!objects[j]->Mailed()) { exporter->SetForcedMaterial(m); exporter->ExportIntersectable(objects[j]); objects[j]->Mail(); } } DEL_PTR(exporter); cout << "finished" << endl; } } else { ViewCellContainer viewCells; mBspTree->CollectViewCells(viewCells); stable_sort(viewCells.begin(), viewCells.end(), vc_gt); int limit = min(leafOut, (int)viewCells.size()); for (int i = 0; i < limit; ++ i) { cout << "creating output for view cell " << i << " ... "; Intersectable::NewMail(); BspViewCell *vc = dynamic_cast(viewCells[i]); cout << "creating output for view cell " << i << " ... "; // check whether we can add the current ray to the output rays for (int k = 0; k < raysOut; ++ k) { Ray *ray = sampleRays[k]; for (int j = 0; j < (int)ray->bspIntersections.size(); ++ j) { BspLeaf *leaf = ray->bspIntersections[j].mLeaf; if (vc == leaf->GetViewCell()) { vcRays[i].push_back(ray); } } } //bspLeaves[j]->Mail(); char s[64]; sprintf(s, "bsp-pvs%04d.x3d", i); Exporter *exporter = Exporter::GetExporter(s); exporter->SetWireframe(); Material m;//= RandomMaterial(); m.mDiffuseColor = RgbColor(0, 1, 0); exporter->SetForcedMaterial(m); if (vc->GetMesh()) exporter->ExportViewCell(vc); else { PolygonContainer cell; // export view cell mBspTree->ConstructGeometry(vc, cell); exporter->ExportPolygons(cell); CLEAR_CONTAINER(cell); } Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize() << ", piercing rays=" << (int)vcRays[i].size() << endl; // export rays piercing this view cell exporter->ExportRays(vcRays[i], 1000, RgbColor(0, 1, 0)); m.mDiffuseColor = RgbColor(1, 0, 0); exporter->SetForcedMaterial(m); ViewCellPvsMap::const_iterator it, it_end = vc->GetPvs().mEntries.end(); // output PVS of view cell for (it = vc->GetPvs().mEntries.begin(); it != it_end; ++ it) { Intersectable *intersect = (*it).first; if (!intersect->Mailed()) { Material m = RandomMaterial(); exporter->SetForcedMaterial(m); exporter->ExportIntersectable(intersect); intersect->Mail(); } } DEL_PTR(exporter); cout << "finished" << endl; } } } void Preprocessor::ExportSceneGeometry(Exporter *exporter, const ObjectContainer &objects) { Material m;//= RandomMaterial(); m.mDiffuseColor = RgbColor(0, 1, 0); exporter->SetForcedMaterial(m); exporter->SetWireframe(); for (int j = 0; j < objects.size(); ++ j) exporter->ExportIntersectable(objects[j]); }