ProxyGroupPtr createPart(int i, partStats &stats) { CreateGeoRec r; SLOG << "Assembling geometry for part " << i + 1 << " of " << nparts << endLog; split->feedResults(i, &r, &CreateGeoRec::pnt, &CreateGeoRec::tri); SLOG << "Got " << r.getNVert() << " verts, " << r.getNTris() << " tris, creating object..." << endLog; partStats s(r.getNVert(), r.getNTris()); stats += s; char name[filebasename.size() + 20]; sprintf(name, "%s_%04d.%s", filebasename.c_str(), i, outformat.c_str()); NodePtr node = r.createScene(); SLOG << "Running graph ops..." << endLog; opseq.run(node); SLOG << "Writing..." << endLog; SceneFileHandler::the().write(node, name); // Wrap it in a ProxyGroup and keep it ProxyGroupPtr proxy = ProxyGroup::create(); beginEditCP(proxy); proxy->setVolume(node->getVolume(true)); proxy->setUrl(name); proxy->setIndices(r.getNTris() * 3); proxy->setTriangles(r.getNTris()); proxy->setPositions(r.getNVert()); proxy->setGeometries(1); proxy->setConcurrentLoad(concurrent); endEditCP(proxy); subRefCP(node); return proxy; }
// Initialize GLUT & OpenSG and set up the scene int main(int argc, char **argv) { if(argc != 2) { std::cout << "Usage: 04Xml2Osb.exe [Filename]" << std::endl; return -1; } Path FilePath(argv[1]); if(!boost::filesystem::exists(FilePath)) { std::cout << "No file by name: "<< FilePath.string() << " exists." << std::endl; return -1; } // OSG init osgInit(argc,argv); NodePtr TheScene(NullFC); //Load the Scene FCFileType::FCPtrStore NewContainers; NewContainers = FCFileHandler::the()->read(FilePath); FCFileType::FCPtrStore::iterator Itor; for(Itor = NewContainers.begin() ; Itor != NewContainers.end() ; ++Itor) { if( (*Itor)->getType() == Node::getClassType() && Node::Ptr::dcast(*Itor)->getParent() == NullFC) { TheScene = Node::Ptr::dcast(*Itor); } } //Check if the scene was loaded if(TheScene == NullFC) { std::cout << "Failed to load a scene from: "<< FilePath.string() << "." << std::endl; return -1; } //Run Graph optimizations GraphOpSeq *graphop = new GraphOpSeq; graphop->addGraphOp(new VerifyGeoGraphOp); graphop->addGraphOp(new StripeGraphOp); //graphop->addGraphOp(new MaterialMergeGraphOp); //graphop->addGraphOp(new SharePtrGraphOp); if(graphop != NULL) { graphop->run(TheScene); } //Export the Scene to an osb file std::string ExportFileName(FilePath.string().substr(0,FilePath.string().size()-3) + "osb"); SceneFileHandler::the().write(TheScene, ExportFileName.c_str()); // OSG exit osgExit(); return 0; }
int main(int argc, char *argv[]) { osgInit(argc,argv); osgLog().addHeaderElem(LOG_TIMESTAMP_HEADER); std::string opstring("Stripe() GeoType(filter=Ind+Len)"); while(argc > 1 && argv[1][0] == '-') { if(!strcmp(argv[1], "-go")) { opstring = argv[2]; SLOG << "opt: graphop seq set to " << opstring << endLog; argc -= 2, argv += 2; } else if(!strcmp(argv[1], "-of")) { outformat = argv[2]; SLOG << "opt: output format set to " << outformat << endLog; argc -= 2, argv += 2; } else if(!strcmp(argv[1], "-tmp")) { tmppath = argv[2]; SLOG << "opt: tmp path set to " << tmppath << endLog; argc -= 2, argv += 2; } else if(!strcmp(argv[1], "-v")) { vertPerPart = atoi(argv[2]); SLOG << "opt: splitting into partition with " << vertPerPart << " vertices" << endLog; argc -= 2, argv += 2; } else if(!strcmp(argv[1], "-pa")) { nparts = atoi(argv[2]); SLOG << "opt: splitting into " << nparts << " parts" << endLog; argc -= 2, argv += 2; } else if(!strcmp(argv[1], "-ps")) { pagesize = atoi(argv[2]); SLOG << "opt: RAFile pagesize set to " << pagesize << endLog; argc -= 2, argv += 2; } else if(!strcmp(argv[1], "-np")) { npages = atoi(argv[2]); SLOG << "opt: RAFile npages set to " << npages << endLog; argc -= 2, argv += 2; } else if(!strcmp(argv[1], "-rc")) { random_color = true; SLOG << "opt: random coloring activated" << endLog; argc -= 1, argv += 1; } else if(!strcmp(argv[1], "-con")) { concurrent = true; SLOG << "opt: concurrent loading Proxy activated" << endLog; argc -= 1, argv += 1; } else if(!strcmp(argv[1], "-nt")) { nthreads = atoi(argv[2]); SLOG << "opt: use " << nthreads << " threads for geometry creation" << endLog; argc -= 2, argv += 2; SLOG << "WARNING: multi-threading doesn't work with all" << " file formats (notably OSB)!" << endLog; } else { usage(); } } opseq.setGraphOps(opstring.c_str()); OOCFeeder *feeder = NULL; NodeRefPtr geo; if(argc == 1) { //geo = makeLatLongSphere(4, 4, 2); //geo = makeTorus(.5, 1.5, 20, 20); geo = makeBox(1,1,1, 2,2,1); filebasename = "test"; feeder = new OOCOSGFeeder(geo); } else { filebasename = argv[1]; int i = filebasename.rfind("."); if(!filebasename.compare(i,3,".gz")) i = filebasename.rfind(".", i - 1); if(!filebasename.compare(i,4,".ply")) { SLOG << "Found PLY, running out of core..." << endLog; feeder = new OOCPLYFeeder(argv+1, argc - 1); } else if(!filebasename.compare(i,4,".smb")) { SLOG << "Found SMB, running out of core..." << endLog; feeder = new OOCSMBFeeder(argv+1, argc - 1); } else { SLOG << "Generic format, using piece load feeder..." << endLog; feeder = new OOCOSGFeeder(argv+1, argc - 1); } if(i != std::string::npos) filebasename.erase(i); if((i = filebasename.rfind("/")) != std::string::npos) { filebasename.erase(filebasename.begin(), filebasename.begin() + i + 1); } } SLOG << "Calculating BBox..." << endLog; // Pass 1: Calc BBox and count vertices Vec3f bblow, bbhigh; UInt32 npts; #if 0 BBoxGeoRec bb; feeder->feedPoints(&bb, &BBoxGeoRec::receive); bblow = bb.getLow(); bbhigh = bb.getHigh(); npts = bb.getNPts(); SLOG << "done: " << bb << endLog; #else feeder->calcBasics(); bblow = feeder->getBBMin(); bbhigh = feeder->getBBMax(); npts = feeder->getNPoints(); SLOG << "done: " << npts << " pts, (" << bblow << ")-(" << bbhigh << ")" << endLog; #endif // Pass 2: Build and partition grid SLOG << "Building vertex grid..." << endLog; VGrid *grid = new VGrid(bblow, bbhigh, osgMin(npts, UInt32(10000000))); feeder->feedPoints(grid, &VGrid::insert); SLOG << "Vertex Grid done: " << *grid << endLog; if(nparts == 0) nparts = int(ceil(npts / (Real32)vertPerPart)); SLOG << "Partitioning into " << nparts << " parts..." << endLog; grid->partition(nparts); SLOG << "Partitioning done" << endLog; // Pass 3: Build split geometry files and cluster-index file SLOG << "Running Point splitting..." << endLog; std::string tname = tmppath + '/' + filebasename; split = new SplitGeoRec(nparts, grid, tname); feeder->feedPoints(split, &SplitGeoRec::splitPnts); split->finishPnts(pagesize, npages); SLOG << "Point splitting done" << endLog; // Pass 4: Add triangles to split files, adding new verts if necessary // This takes the most time, as it needs to random access the vertices SLOG << "Running Face splitting..." << endLog; feeder->feedTris(split, &SplitGeoRec::splitTris); SLOG << "Face splitting done..." << endLog; // Pass 5: Fixup newly added verts SLOG << "Running Point fixup..." << endLog; feeder->feedPoints(split, &SplitGeoRec::fixPnts); SLOG << "Point fixup done..." << endLog; SLOG << *split << endLog; split->finishFixups(); delete grid; // Don't need it any more // At this point the split files contain everything that's needed // to create the geometry. Do it. SLOG << "Creating Geometry..." << endLog; if(0) { for(UInt32 i = 0; i < nparts; ++i) { PrintGeoRec p; SLOG << "Partition " << i << endLog; split->feedResults(i, &p, &PrintGeoRec::pnt, &PrintGeoRec::tri); } } if (nthreads > 0) { std::vector<ThreadData> threads; threads.resize(nthreads); // Divide the work for(int i = 0; i < nthreads; ++i) { threads[i].firstPart = (int)(nparts * i / (Real32) nthreads); threads[i].nParts = (int)(nparts * (i+1) / (Real32) nthreads) - threads[i].firstPart; } // Start the threads for(int j = 0; j < nthreads; ++j) { threads[j].thread = dynamic_cast<Thread *> (ThreadManager::the()->getThread(NULL)); threads[j].thread->runFunction(runThread, 0, &threads[j]); } // Wait for them to finish for(int j = 0; j < nthreads; ++j) { OSG::Thread::join(threads[j].thread); } // Merge the results GroupPtr group; group = Group::create(); NodePtr gnode = makeNodeFor(group); partStats stats; beginEditCP(gnode); for(UInt32 i = 0; i < nthreads; ++i) { for(UInt32 j = 0; j < threads[i].proxies.size(); ++j) { gnode->addChild(makeNodeFor(threads[i].proxies[j])); } stats += threads[i].stats; } endEditCP(gnode); SLOG << "Vertices (min/avg/max):" << stats.vertmin << " " << stats.vertsum / nparts << " " << stats.vertmax << endLog; SLOG << "Triangles (min/avg/max):" << stats.trimin << " " << stats.trisum / nparts << " " << stats.trimax << endLog; char name[filebasename.size() + 20]; sprintf(name, "%s_prox.%s", filebasename.c_str(), outformat.c_str()); SLOG << "Writing *_prox..." << endLog; SceneFileHandler::the().write(gnode, name); } else // Create Geometry & ProxyGroup { GroupPtr group; group = Group::create(); NodePtr gnode = makeNodeFor(group); partStats stats; beginEditCP(gnode); for(UInt32 i = 0; i < nparts; ++i) { ProxyGroupPtr proxy = createPart(i, stats); gnode->addChild(makeNodeFor(proxy)); } endEditCP(gnode); SLOG << "Vertices (min/avg/max):" << stats.vertmin << " " << stats.vertsum / nparts << " " << stats.vertmax << endLog; SLOG << "Triangles (min/avg/max):" << stats.trimin << " " << stats.trisum / nparts << " " << stats.trimax << endLog; char name[filebasename.size() + 20]; sprintf(name, "%s_prox.%s", filebasename.c_str(), outformat.c_str()); SLOG << "Writing *_prox..." << endLog; SceneFileHandler::the().write(gnode, name); } split->finish(); // Done osgExit(); return 0; }