virtual ReadResult readObject(const std::string& file, const osgDB::ReaderWriter::Options* options) const { std::string ext = osgDB::getLowerCaseFileExtension(file); if( !acceptsExtension(ext) ) return ReadResult::FILE_NOT_HANDLED; std::string fileName = osgDB::findDataFile( file, options ); if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; // code for setting up the database path so that internally referenced file are searched for on relative paths. osgDB::ifstream fin(fileName.c_str()); if (fin) { return readObject(fin, options); } return 0L; }
virtual ReadResult readImage(const std::string & filename, const osgDB::ReaderWriter::Options* options) const { const std::string ext = osgDB::getLowerCaseFileExtension(filename); if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; const std::string path = osgDB::containsServerAddress(filename) ? filename : osgDB::findDataFile(filename, options); if (path.empty()) return ReadResult::FILE_NOT_FOUND; osg::ref_ptr<osgGStreamer::GStreamerImageStream> imageStream = new osgGStreamer::GStreamerImageStream(); if (!imageStream->open(filename)) return ReadResult::FILE_NOT_HANDLED; return imageStream.release(); }
virtual ReadResult readImage(const std::string& file, const osgDB::ReaderWriter::Options* options) const { std::string ext = osgDB::getLowerCaseFileExtension(file); if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; std::string fileName(file); if (ext=="avfoundation") { fileName = osgDB::getNameLessExtension(fileName); OSG_INFO<<"AVFoundation stipped filename = "<<fileName<<std::endl; } if (!osgDB::containsServerAddress(fileName)) { fileName = osgDB::findDataFile( fileName, options ); if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; } OSG_INFO<<"ReaderWriterAVFoundation::readImage "<< fileName<< std::endl; osg::ref_ptr<OSXAVFoundationVideo> video = new OSXAVFoundationVideo(); bool disable_multi_threaded_frame_dispatching = options ? (options->getPluginStringData("disableMultiThreadedFrameDispatching") == "true") : false; bool disable_core_video = true; // options ? (options->getPluginStringData("disableCoreVideo") == "true") : false; OSG_INFO << "disableMultiThreadedFrameDispatching: " << disable_multi_threaded_frame_dispatching << std::endl; OSG_INFO << "disableCoreVideo : " << disable_core_video << std::endl; if (!options || (!disable_multi_threaded_frame_dispatching && disable_core_video)) { static osg::ref_ptr<osgVideo::VideoFrameDispatcher> video_frame_dispatcher(NULL); if (!video_frame_dispatcher) { std::string num_threads_str = options ? options->getPluginStringData("numFrameDispatchThreads") : "0"; video_frame_dispatcher = new osgVideo::VideoFrameDispatcher(atoi(num_threads_str.c_str())); } video_frame_dispatcher->addVideo(video); } video->open(fileName); return video->valid() ? video.release() : NULL; }
virtual ReadResult readObject(const std::string& file, const osgDB::ReaderWriter::Options* options) const { std::string ext = osgDB::getLowerCaseFileExtension( file ); if ( !acceptsExtension(ext) ) return ReadResult::FILE_NOT_HANDLED; NxPhysicsSDKDesc desc; NxSDKCreateError errorCode = NXCE_NO_ERROR; NxPhysicsSDK* physicsSDK = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION, NULL, new ErrorStream, desc, &errorCode); if ( !physicsSDK ) { OSG_WARN << "[PhysXInterface] Unable to initialize the PhysX SDK, error code: " << errorCode << std::endl; return NULL; } osgPhysics::setPhysxInstance( physicsSDK ); osg::ref_ptr<osgPhysics::PhysXInterface> interface = new osgPhysics::PhysXInterface; interface->setPhysicsData( physicsSDK ); return interface.get(); }
virtual ReadResult readImage(const std::string& file, const osgDB::ReaderWriter::Options* options) const { std::string ext = osgDB::getLowerCaseFileExtension(file); if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; std::string fileName = osgDB::findDataFile( file, options ); if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; unsigned char *imageData = NULL; int width_ret; int height_ret; int numComponents_ret; imageData = simage_pic_load(fileName.c_str(),&width_ret,&height_ret,&numComponents_ret); if (imageData==NULL) return ReadResult::FILE_NOT_HANDLED; int s = width_ret; int t = height_ret; int r = 1; int internalFormat = numComponents_ret; unsigned int pixelFormat = numComponents_ret == 1 ? GL_LUMINANCE : numComponents_ret == 2 ? GL_LUMINANCE_ALPHA : numComponents_ret == 3 ? GL_RGB : numComponents_ret == 4 ? GL_RGBA : (GLenum)-1; unsigned int dataType = GL_UNSIGNED_BYTE; osg::Image* pOsgImage = new osg::Image; pOsgImage->setFileName(fileName.c_str()); pOsgImage->setImage(s,t,r, internalFormat, pixelFormat, dataType, imageData, osg::Image::USE_NEW_DELETE); return pOsgImage; }
//============================================================================ //============================================================================ virtual ReadResult readNode(const std::string& file, const osgDB::ReaderWriter::Options* options) const { std::string ext = osgDB::getLowerCaseFileExtension(file); if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; NgpFileName fileName(file); std::string foundPath = osgDB::findDataFile( fileName.settings().filePath, options ); if (foundPath.size() <= 0) { OSG_WARN << "Unable to find plant file: " << fileName.settings().filePath << std::endl; return NULL; } fileName.setFilePath(foundPath); osg::Geode *node = createPlant( fileName ); return node; }
virtual ReadResult readNode(const std::string& fileName, const osgDB::ReaderWriter::Options* /*options*/) const { std::string ext = osgDB::getLowerCaseFileExtension(fileName); if( !acceptsExtension(ext) ) return ReadResult::FILE_NOT_HANDLED; osg::notify(osg::INFO) << "ReaderWriterTRACKER( \"" << fileName << "\" )" << std::endl; // strip the pseudo-loader extension std::string tmpName = osgDB::getNameLessExtension( fileName ); // get the next "extension", which actually the osgVRPN tracker name std::string trkName = osgDB::getFileExtension( tmpName ); if( trkName.empty() ) { osg::notify(osg::WARN) << "Missing trkName for " EXTENSION_NAME " pseudo-loader" << std::endl; return ReadResult::FILE_NOT_HANDLED; } // strip the trkName "extension", which must leave a sub-filename. std::string subFileName = osgDB::getNameLessExtension( tmpName ); if( subFileName == tmpName ) { osg::notify(osg::WARN) << "Missing subfilename for " EXTENSION_NAME " pseudo-loader" << std::endl; return ReadResult::FILE_NOT_HANDLED; } // recursively load the subfile. osg::Node *node = osgDB::readNodeFile( subFileName ); if( !node ) { // propagate the read failure upwards osg::notify(osg::WARN) << "Subfile \"" << subFileName << "\" could not be loaded" << std::endl; return ReadResult::FILE_NOT_HANDLED; } osgVRPN::Tracker *tracker = new osgVRPN::Tracker( trkName.c_str() ); osgVRPN::TrackerTransform *xform = new osgVRPN::TrackerTransform; xform->setTracker( tracker ); xform->addChild( node ); return xform; }
osgDB::ReaderWriter::WriteResult ReaderWriterCURLEX::writeObject(const osg::Object& object, const std::string& fileName, const osgDB::ReaderWriter::Options* options) const { std::string ext = osgDB::getFileExtension(fileName); if (options != NULL && acceptsExtension(options->getPluginStringData("VIRTUALDATASCENE_DEFINE_PLUGIN")) && acceptsExtension(ext)) { const VirtualDataSceneBase::StreamObject* curlexObject = dynamic_cast<const VirtualDataSceneBase::StreamObject*>(&object); if (curlexObject) { std::string sFileName = fileName; #if _WIN32 tryConvertStringFromUTF8ToGB2312(fileName, sFileName); #endif std::ofstream out(sFileName.c_str(), std::ios::binary | std::ios::out); return writeObject(object, out, options); } } return osgDB::ReaderWriter::WriteResult::FILE_NOT_HANDLED; }
virtual ReadResult readImage(const std::string& file, const osgDB::ReaderWriter::Options* options) const { std::string ext = osgDB::getLowerCaseFileExtension(file); if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; if (!_initialized) { if (osgWidget::BrowserManager::instance()->getApplication().empty()) { osgWidget::BrowserManager::instance()->setApplication(osg::DisplaySettings::instance()->getApplication()); } osgWidget::BrowserManager::instance()->init(osgWidget::BrowserManager::instance()->getApplication()); } unsigned int width = 1024; unsigned int height = 1024; return osgWidget::BrowserManager::instance()->createBrowserImage(osgDB::getNameLessExtension(file), width, height); }
osgDB::ReaderWriter::WriteResult ReaderWriterOSGObjects::writeObject( const osg::Object& obj, const std::string& fileName, const Options* options ) const { OSG_INFO << "ReaderWriterOSGObjects: writeObject " << fileName << std::endl; const std::string ext = osgDB::getFileExtension( fileName ); if( !acceptsExtension( ext ) ) return( WriteResult::FILE_NOT_HANDLED ); bool result( false ); osg::Object* nonConstObj( const_cast< osg::Object* >( &obj ) ); osg::Array* array( dynamic_cast< osg::Array* >( nonConstObj ) ); if( array != NULL ) { osgDB::Output ostr( fileName.c_str() ); result = Array_writeLocalData( *array, ostr ); } return( result ? WriteResult::FILE_SAVED : WriteResult::ERROR_IN_WRITING_FILE ); }
// Read node osgDB::ReaderWriter::ReadResult ReaderWriterDirectX::readNode(const std::string& file, const osgDB::ReaderWriter::Options* options) const { std::string ext = osgDB::getLowerCaseFileExtension(file); if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; std::string fileName = osgDB::findDataFile( file, options ); if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; osg::notify(osg::INFO) << "ReaderWriterDirectX::readNode(" << fileName.c_str() << ")\n"; // Load DirectX mesh DX::Object obj; if (obj.load(fileName.c_str()) == false) { return ReadResult::ERROR_IN_READING_FILE; } // code for setting up the database path so that internally referenced file are searched for on relative paths. osg::ref_ptr<Options> local_opt = options ? static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options; local_opt->setDatabasePath(osgDB::getFilePath(fileName)); // Options? bool flipTexture = true; float creaseAngle = 80.0f; if (options) { const std::string option = options->getOptionString(); if (option.find("flipTexture") != std::string::npos) { flipTexture = false; } if (option.find("creaseAngle") != std::string::npos) { // TODO } } // Convert to osg::Group osg::Group* group = convertFromDX(obj, flipTexture, creaseAngle, local_opt.get()); if (!group) { return ReadResult::ERROR_IN_READING_FILE; } return group; }
virtual WriteResult writeNode(const osg::Node& node,const std::string& fileName,const Options* options=NULL) const { if (!acceptsExtension(osgDB::getFileExtension(fileName))) return WriteResult(WriteResult::FILE_NOT_HANDLED); ObjOptionsStruct localOptions = parseOptions(options); osgDB::ofstream f(fileName.c_str()); f.precision(localOptions.precision); std::string materialFile = osgDB::getNameLessExtension(fileName) + ".mtl"; OBJWriterNodeVisitor nv(f, osgDB::getSimpleFileName(materialFile)); // we must cast away constness (const_cast<osg::Node*>(&node))->accept(nv); osgDB::ofstream mf(materialFile.c_str()); nv.writeMaterials(mf); return WriteResult(WriteResult::FILE_SAVED); }
virtual ReadResult readImage(const std::string &file, const osgDB::ReaderWriter::Options *options) const { std::string ext = osgDB::getLowerCaseFileExtension(file); if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; std::string fileName = osgDB::findDataFile(file, options); if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; osgDB::ifstream istream(fileName.c_str(), std::ios::in | std::ios::binary); if (!istream) return ReadResult::FILE_NOT_HANDLED; ReadResult rr = readTIFStream(istream); if (rr.validImage()) rr.getImage()->setFileName(file); return rr; }
bool getDicomFilesInDirectory(const std::string& path, Files& files) const { osgDB::DirectoryContents contents = osgDB::getDirectoryContents(path); std::sort(contents.begin(), contents.end()); for(osgDB::DirectoryContents::iterator itr = contents.begin(); itr != contents.end(); ++itr) { std::string localFile = path + "/" + *itr; info()<<"contents = "<<localFile<<std::endl; if (acceptsExtension(osgDB::getLowerCaseFileExtension(localFile)) && osgDB::fileType(localFile) == osgDB::REGULAR_FILE) { files.push_back(localFile); } } return !files.empty(); }
// Read node osgDB::ReaderWriter::ReadResult ReaderWriterDirectX::readNode(const std::string& file, const osgDB::ReaderWriter::Options* options) const { std::string ext = osgDB::getLowerCaseFileExtension(file); if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; std::string fileName = osgDB::findDataFile( file, options ); if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; OSG_INFO << "ReaderWriterDirectX::readNode(" << fileName << ")\n"; osgDB::ifstream fin(fileName.c_str()); if (fin.bad()) { OSG_WARN << "ReaderWriterDirectX failed to read '" << fileName.c_str() << "'\n"; return ReadResult::ERROR_IN_READING_FILE; } // code for setting up the database path so that internally referenced file are searched for on relative paths. osg::ref_ptr<Options> local_opt = options ? static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options; local_opt->setDatabasePath(osgDB::getFilePath(fileName)); return readNode(fin, local_opt.get()); }
osgDB::ReaderWriter::ReadResult ReaderWriterPaths::readObject(const std::string& file, const osgDB::Options* options) const { std::string ext = osgDB::getLowerCaseFileExtension(file); if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; OSG_INFO<<"ReaderWriterPaths::readObject("<<file<<")"<<std::endl; std::string fileName = osgDB::findDataFile( file, options ); if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; OSG_INFO<<" Found path file :"<<fileName<<std::endl; // code for setting up the database path so that internally referenced file are searched for on relative paths. osg::ref_ptr<osgDB::ReaderWriter::Options> local_opt = options ? static_cast<osgDB::ReaderWriter::Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options; local_opt->setPluginStringData("filename",fileName); osgDB::ifstream input(fileName.c_str()); return readObject(input, local_opt.get()); }
virtual ReadResult readNode(const std::string &file, const osgDB::ReaderWriter::Options *options) const { std::string ext = osgDB::getLowerCaseFileExtension(file); if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; std::string fileName = osgDB::findDataFile(file, options); if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; // code for setting up the database path so that internally referenced file are searched for on relative paths. osg::ref_ptr<Options> local_opt = options ? static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options; local_opt->setDatabasePath(osgDB::getFilePath(fileName)); lwosg::SceneLoader::Options conv_options = parse_options(local_opt.get()); lwosg::SceneLoader scene_loader(conv_options); osg::ref_ptr<osg::Node> node = scene_loader.load(fileName, local_opt.get()); if (node.valid()) { return node.release(); } return ReadResult::FILE_NOT_HANDLED; }
osgDB::ReaderWriter::WriteResult ReaderWriterIV::writeNode(const osg::Node& node, const std::string& fileName, const osgDB::ReaderWriter::Options* /*options*/) const { // accept extension std::string ext = osgDB::getLowerCaseFileExtension(fileName); if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED; bool useVRML1 = !isInventorExtension(osgDB::getFileExtension(fileName)); OSG_NOTICE << "osgDB::ReaderWriterIV::writeNode() Writing file " << fileName.data() << std::endl; // Convert OSG graph to Inventor graph ConvertToInventor osg2iv; osg2iv.setVRML1Conversion(useVRML1); (const_cast<osg::Node*>(&node))->accept(osg2iv); SoNode *ivRoot = osg2iv.getIvSceneGraph(); if (ivRoot == NULL) return WriteResult::ERROR_IN_WRITING_FILE; ivRoot->ref(); // Change prefix according to VRML spec: // Node names must not begin with a digit, and must not contain spaces or // control characters, single or double quote characters, backslashes, curly braces, // the sharp (#) character, the plus (+) character or the period character. if (useVRML1) SoBase::setInstancePrefix("_"); // Write Inventor graph to file SoOutput out; out.setHeaderString((useVRML1) ? "#VRML V1.0 ascii" : "#Inventor V2.1 ascii"); if (!out.openFile(fileName.c_str())) return WriteResult::ERROR_IN_WRITING_FILE; SoWriteAction wa(&out); wa.apply(ivRoot); ivRoot->unref(); return WriteResult::FILE_SAVED; }
virtual ReadResult readNode( const std::string& file, const osgDB::ReaderWriter::Options* options ) const { std::string ext = osgDB::getLowerCaseFileExtension(file); if ( ext=="assimp" ) return readNode(osgDB::getNameLessExtension(file), options); if ( !acceptsExtension(ext) ) return ReadResult::FILE_NOT_HANDLED; std::string fileName = osgDB::findDataFile( file, options ); if ( fileName.empty() ) return ReadResult::FILE_NOT_FOUND; Assimp::Importer importer; const aiScene* aiScene = importer.ReadFile( fileName.c_str(), aiProcessPreset_TargetRealtime_Quality ); if ( !aiScene ) { OSG_WARN << "ReaderWriterAssImp:: fail to load " + file << ", because of " << importer.GetErrorString() << std::endl; return ReadResult::ERROR_IN_READING_FILE; } // Read scene nodes recursively TextureMap textures; osg::Node* root = traverseAIScene( fileName, aiScene, aiScene->mRootNode, textures, options ); return root; }
virtual ReadResult readImage( const std::string& file, const osgDB::ReaderWriter::Options* options ) const { std::string ext = osgDB::getLowerCaseFileExtension(file); if ( !acceptsExtension(ext) ) return ReadResult::FILE_NOT_HANDLED; std::string url = osgDB::getNameLessExtension(file); int w = 1024, h = 1024; osg::ref_ptr<VideoPlayer> image; if ( options ) { int ww = atoi( options->getPluginStringData("height").c_str() ); int hh = atoi( options->getPluginStringData("width").c_str() ); if ( ww>0 ) w = ww; if ( hh>0 ) h = hh; const void* args = options->getPluginData("arguments"); if ( args ) image = new VideoPlayer( (const char**)args ); } if ( !image ) image = new VideoPlayer; image->open( url, w, h ); return image.get(); }
// read file and convert to OSG. osgDB::ReaderWriter::ReadResult ReaderWriterVDPM::readNode(const std::string& file, const osgDB::ReaderWriter::Options* options) const { std::string ext = osgDB::getLowerCaseFileExtension(file); if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; std::string fileName = osgDB::findDataFile( file, options ); if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; osgDB::ifstream fin(fileName.c_str(), std::ios_base::in | std::ios_base::binary); if (fin) { vdpm::StdInStream ins(&fin); vdpm::SRMesh* srmesh = vdpm::Serializer::getInstance().loadSRMesh(ins); // code for setting up the database path so that internally referenced file are searched for on relative paths. osg::ref_ptr<Options> local_opt = options ? static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options; local_opt->setDatabasePath(osgDB::getFilePath(fileName)); osg::Node* node = convertSRMeshToSceneGraph(*srmesh, local_opt); return node; } return ReadResult::FILE_NOT_HANDLED; }
osgDB::ReaderWriter::WriteResult ReaderWriterSTL::writeNode(const osg::Node& node, const std::string& fileName, const Options* opts) const { std::string ext = osgDB::getLowerCaseFileExtension(fileName); if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED; if (ext != "stl") { OSG_FATAL << "ReaderWriterSTL::writeNode: Only STL ASCII files supported" << std::endl; return WriteResult::FILE_NOT_HANDLED; } CreateStlVisitor createStlVisitor(fileName, opts); const_cast<osg::Node&>(node).accept(createStlVisitor); if (createStlVisitor.getErrorString().empty()) { return WriteResult::FILE_SAVED; } else { OSG_FATAL << "Error: " << createStlVisitor.getErrorString() << std::endl; return WriteResult::ERROR_IN_WRITING_FILE; } }
osgDB::ReaderWriter::WriteResult ReaderWriterGZ::writeFile(ObjectType objectType, const osg::Object *object, const std::string &fullFileName, const osgDB::ReaderWriter::Options *options) const { std::string ext = osgDB::getLowerCaseFileExtension(fullFileName); if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED; osgDB::ReaderWriter *rw = 0; if (osgDB::equalCaseInsensitive(ext, "osgz")) { rw = osgDB::Registry::instance()->getReaderWriterForExtension("osg"); OSG_NOTICE << "osgz ReaderWriter " << rw << std::endl; } else if (osgDB::equalCaseInsensitive(ext, "ivez")) { rw = osgDB::Registry::instance()->getReaderWriterForExtension("ive"); OSG_NOTICE << "ivez ReaderWriter " << rw << std::endl; } else { std::string baseFileName = osgDB::getNameLessExtension(fullFileName); std::string baseExt = osgDB::getLowerCaseFileExtension(baseFileName); rw = osgDB::Registry::instance()->getReaderWriterForExtension(baseExt); OSG_NOTICE << baseExt << " ReaderWriter " << rw << std::endl; } std::stringstream strstream; osgDB::ReaderWriter::WriteResult writeResult = writeFile(objectType, object, rw, strstream, options); osgDB::ofstream fout(fullFileName.c_str(), std::ios::binary | std::ios::out); write(fout, strstream.str()); return writeResult; }
virtual ReadResult openArchive(const std::string &file, ArchiveStatus status, unsigned int indexBlockSize = 4096, const Options *options = NULL) const { std::string ext = osgDB::getLowerCaseFileExtension(file); if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; std::string fileName = osgDB::findDataFile(file, options); if (fileName.empty()) { if (status == READ) return ReadResult::FILE_NOT_FOUND; fileName = file; } osg::ref_ptr<OSGA_Archive> archive = new OSGA_Archive; if (!archive->open(fileName, status, indexBlockSize)) { return ReadResult(ReadResult::FILE_NOT_HANDLED); } return archive.get(); }
virtual ReadResult readImage(const std::string& file, const osgDB::ReaderWriter::Options* options) const { notice()<<"Reading DICOM file "<<file<<" using DCMTK"<<std::endl; std::string ext = osgDB::getLowerCaseFileExtension(file); if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; std::string fileName = file; if (ext=="dicom") { fileName = osgDB::getNameLessExtension(file); } fileName = osgDB::findDataFile( fileName, options ); if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; Files files; osgDB::FileType fileType = osgDB::fileType(fileName); if (fileType==osgDB::DIRECTORY) { getDicomFilesInDirectory(fileName, files); } else { #if 1 files.push_back(fileName); #else if (!getDicomFilesInDirectory(osgDB::getFilePath(fileName), files)) { files.push_back(fileName); } #endif } if (files.empty()) { return ReadResult::FILE_NOT_FOUND; } osg::ref_ptr<osg::RefMatrix> matrix = new osg::RefMatrix; osg::ref_ptr<osg::Image> image; unsigned int imageNum = 0; EP_Representation pixelRep = EPR_Uint8; int numPlanes = 0; GLenum pixelFormat = 0; GLenum dataType = 0; unsigned int pixelSize = 0; typedef std::list<FileInfo> FileInfoList; FileInfoList fileInfoList; typedef std::map<double, FileInfo> DistanceFileInfoMap; typedef std::map<osg::Vec3d, DistanceFileInfoMap> OrientationFileInfoMap; OrientationFileInfoMap orientationFileInfoMap; unsigned int totalNumSlices = 0; for(Files::iterator itr = files.begin(); itr != files.end(); ++itr) { DcmFileFormat fileformat; OFCondition status = fileformat.loadFile((*itr).c_str()); if(!status.good()) return ReadResult::ERROR_IN_READING_FILE; FileInfo fileInfo; fileInfo.filename = *itr; double pixelSize_y = 1.0; double pixelSize_x = 1.0; double sliceThickness = 1.0; double imagePositionPatient[3] = {0, 0, 0}; double imageOrientationPatient[6] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0 }; Uint16 numOfSlices = 1; double value = 0.0; if (fileformat.getDataset()->findAndGetFloat64(DCM_PixelSpacing, value,0).good()) { pixelSize_y = value; fileInfo.matrix(1,1) = pixelSize_y; } if (fileformat.getDataset()->findAndGetFloat64(DCM_PixelSpacing, value,1).good()) { pixelSize_x = value; fileInfo.matrix(0,0) = pixelSize_x; } // Get slice thickness if (fileformat.getDataset()->findAndGetFloat64(DCM_SliceThickness, value).good()) { sliceThickness = value; notice()<<"sliceThickness = "<<sliceThickness<<std::endl; fileInfo.sliceThickness = sliceThickness; } notice()<<"tagExistsWithValue(DCM_NumberOfFrames)="<<fileformat.getDataset()->tagExistsWithValue(DCM_NumberOfFrames)<<std::endl; notice()<<"tagExistsWithValue(DCM_NumberOfSlices)="<<fileformat.getDataset()->tagExistsWithValue(DCM_NumberOfSlices)<<std::endl; Uint32 numFrames; if (fileformat.getDataset()->findAndGetUint32(DCM_NumberOfFrames, numFrames).good()) { fileInfo.numSlices = numFrames; notice()<<"Read number of frames = "<<numFrames<<std::endl; } OFString numFramesStr; if (fileformat.getDataset()->findAndGetOFString(DCM_NumberOfFrames, numFramesStr).good()) { fileInfo.numSlices = atoi(numFramesStr.c_str()); notice()<<"Read number of frames = "<<numFramesStr<<std::endl; } if (fileformat.getDataset()->findAndGetUint16(DCM_NumberOfFrames, numOfSlices).good()) { fileInfo.numSlices = numOfSlices; notice()<<"Read number of frames = "<<numOfSlices<<std::endl; } if (fileformat.getDataset()->findAndGetUint16(DCM_NumberOfSlices, numOfSlices).good()) { fileInfo.numSlices = numOfSlices; notice()<<"Read number of slices = "<<numOfSlices<<std::endl; } // patient position for(int i=0; i<3; ++i) { if (fileformat.getDataset()->findAndGetFloat64(DCM_ImagePositionPatient, imagePositionPatient[i],i).good()) { notice()<<"Read DCM_ImagePositionPatient["<<i<<"], "<<imagePositionPatient[i]<<std::endl; } else { notice()<<"Have not read DCM_ImagePositionPatient["<<i<<"]"<<std::endl; } } //notice()<<"imagePositionPatient[2]="<<imagePositionPatient[2]<<std::endl; fileInfo.matrix.setTrans(imagePositionPatient[0],imagePositionPatient[1],imagePositionPatient[2]); for(int i=0; i<6; ++i) { double value = 0.0; if (fileformat.getDataset()->findAndGetFloat64(DCM_ImageOrientationPatient, value,i).good()) { imageOrientationPatient[i] = value; notice()<<"Read imageOrientationPatient["<<i<<"], "<<imageOrientationPatient[i]<<std::endl; } else { notice()<<"Have not read imageOrientationPatient["<<i<<"]"<<std::endl; } } osg::Vec3d dirX(imageOrientationPatient[0],imageOrientationPatient[1],imageOrientationPatient[2]); osg::Vec3d dirY(imageOrientationPatient[3],imageOrientationPatient[4],imageOrientationPatient[5]); osg::Vec3d dirZ = dirX ^ dirY; dirZ.normalize(); dirX *= pixelSize_x; dirY *= pixelSize_y; fileInfo.matrix(0,0) = dirX[0]; fileInfo.matrix(1,0) = dirX[1]; fileInfo.matrix(2,0) = dirX[2]; fileInfo.matrix(0,1) = dirY[0]; fileInfo.matrix(1,1) = dirY[1]; fileInfo.matrix(2,1) = dirY[2]; fileInfo.matrix(0,2) = dirZ[0]; fileInfo.matrix(1,2) = dirZ[1]; fileInfo.matrix(2,2) = dirZ[2]; fileInfo.distance = dirZ * (osg::Vec3d(0.0,0.0,0.0)*fileInfo.matrix); notice()<<"dirX = "<<dirX<<std::endl; notice()<<"dirY = "<<dirY<<std::endl; notice()<<"dirZ = "<<dirZ<<std::endl; notice()<<"matrix = "<<fileInfo.matrix<<std::endl; notice()<<"pos = "<<osg::Vec3d(0.0,0.0,0.0)*fileInfo.matrix<<std::endl; notice()<<"dist = "<<fileInfo.distance<<std::endl; notice()<<std::endl; (orientationFileInfoMap[dirZ])[fileInfo.distance] = fileInfo; totalNumSlices += fileInfo.numSlices; } if (orientationFileInfoMap.empty()) return 0; typedef std::map<double, FileInfo> DistanceFileInfoMap; typedef std::map<osg::Vec3d, DistanceFileInfoMap> OrientationFileInfoMap; for(OrientationFileInfoMap::iterator itr = orientationFileInfoMap.begin(); itr != orientationFileInfoMap.end(); ++itr) { notice()<<"Orientation = "<<itr->first<<std::endl; DistanceFileInfoMap& dfim = itr->second; for(DistanceFileInfoMap::iterator ditr = dfim.begin(); ditr != dfim.end(); ++ditr) { FileInfo& fileInfo = ditr->second; notice()<<" d = "<<fileInfo.distance<<" "<<fileInfo.filename<<std::endl; } } DistanceFileInfoMap& dfim = orientationFileInfoMap.begin()->second; if (dfim.empty()) return 0; double totalDistance = 0.0; if (dfim.size()>1) { totalDistance = fabs(dfim.rbegin()->first - dfim.begin()->first); } else { totalDistance = dfim.begin()->second.sliceThickness * double(dfim.begin()->second.numSlices); } notice()<<"Total Distance including ends "<<totalDistance<<std::endl; double averageThickness = totalNumSlices<=1 ? 1.0 : totalDistance / double(totalNumSlices-1); notice()<<"Average thickness "<<averageThickness<<std::endl; for(DistanceFileInfoMap::iterator ditr = dfim.begin(); ditr != dfim.end(); ++ditr) { FileInfo& fileInfo = ditr->second; std::auto_ptr<DicomImage> dcmImage(new DicomImage(fileInfo.filename.c_str())); if (dcmImage.get()) { if (dcmImage->getStatus()==EIS_Normal) { // get the pixel data const DiPixel* pixelData = dcmImage->getInterData(); if(!pixelData) { warning()<<"Error: no data in DicomImage object."<<std::endl; return ReadResult::ERROR_IN_READING_FILE; } osg::ref_ptr<osg::Image> imageAdapter = new osg::Image; EP_Representation curr_pixelRep; int curr_numPlanes; GLenum curr_pixelFormat; GLenum curr_dataType; unsigned int curr_pixelSize; // create the new image convertPixelTypes(pixelData, curr_pixelRep, curr_numPlanes, curr_dataType, curr_pixelFormat, curr_pixelSize); imageAdapter->setImage(dcmImage->getWidth(), dcmImage->getHeight(), dcmImage->getFrameCount(), curr_pixelFormat, curr_pixelFormat, curr_dataType, (unsigned char*)(pixelData->getData()), osg::Image::NO_DELETE); if (!image) { pixelRep = curr_pixelRep; numPlanes = curr_numPlanes; dataType = curr_dataType; pixelFormat = curr_pixelFormat; pixelSize = curr_pixelSize; (*matrix)(0,0) = fileInfo.matrix(0,0); (*matrix)(1,0) = fileInfo.matrix(1,0); (*matrix)(2,0) = fileInfo.matrix(2,0); (*matrix)(0,1) = fileInfo.matrix(0,1); (*matrix)(1,1) = fileInfo.matrix(1,1); (*matrix)(2,1) = fileInfo.matrix(2,1); (*matrix)(0,2) = fileInfo.matrix(0,2) * averageThickness; (*matrix)(1,2) = fileInfo.matrix(1,2) * averageThickness; (*matrix)(2,2) = fileInfo.matrix(2,2) * averageThickness; image = new osg::Image; image->setUserData(matrix.get()); image->setFileName(fileName.c_str()); image->allocateImage(dcmImage->getWidth(), dcmImage->getHeight(), totalNumSlices, pixelFormat, dataType); matrix->preMult(osg::Matrix::scale(double(image->s()), double(image->t()), double(image->r()))); notice()<<"Image dimensions = "<<image->s()<<", "<<image->t()<<", "<<image->r()<<" pixelFormat=0x"<<std::hex<<pixelFormat<<" dataType=0x"<<std::hex<<dataType<<std::dec<<std::endl; } else if (pixelData->getPlanes()>numPlanes || pixelData->getRepresentation()>pixelRep) { notice()<<"Need to reallocated "<<image->s()<<", "<<image->t()<<", "<<image->r()<<std::endl; // record the previous image settings to use when we copy back the content. osg::ref_ptr<osg::Image> previous_image = image; // create the new image convertPixelTypes(pixelData, pixelRep, numPlanes, dataType, pixelFormat, pixelSize); image = new osg::Image; image->setUserData(previous_image->getUserData()); image->setFileName(fileName.c_str()); image->allocateImage(dcmImage->getWidth(), dcmImage->getHeight(), totalNumSlices, pixelFormat, dataType); osg::copyImage(previous_image.get(), 0,0,0, previous_image->s(), previous_image->t(), imageNum, image.get(), 0, 0, 0, false); } osg::copyImage(imageAdapter.get(), 0,0,0, imageAdapter->s(), imageAdapter->t(), imageAdapter->r(), image.get(), 0, 0, imageNum, false); imageNum += dcmImage->getFrameCount(); } else { warning()<<"Error in reading dicom file "<<fileName.c_str()<<", error = "<<DicomImage::getString(dcmImage->getStatus())<<std::endl; } } } if (!image) { return ReadResult::ERROR_IN_READING_FILE; } notice()<<"Spacing = "<<*matrix<<std::endl; return image.get(); }
virtual ReadResult readImage(const std::string& file, const osgDB::ReaderWriter::Options* options) const { std::string ext = osgDB::getLowerCaseFileExtension(file); if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; std::string fileName = osgDB::findDataFile( file, options ); if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; notice()<<"Reading DICOM file "<<fileName<<std::endl; typedef unsigned short PixelType; const unsigned int Dimension = 3; typedef itk::Image< PixelType, Dimension > ImageType; typedef itk::ImageFileReader< ImageType > ReaderType; ReaderType::Pointer reader = ReaderType::New(); reader->SetFileName( fileName.c_str() ); typedef itk::GDCMImageIO ImageIOType; ImageIOType::Pointer gdcmImageIO = ImageIOType::New(); reader->SetImageIO( gdcmImageIO ); try { reader->Update(); } catch (itk::ExceptionObject & e) { std::cerr << "exception in file reader " << std::endl; std::cerr << e.GetDescription() << std::endl; std::cerr << e.GetLocation() << std::endl; return ReadResult::ERROR_IN_READING_FILE; } ImageType::Pointer inputImage = reader->GetOutput(); ImageType::RegionType region = inputImage->GetBufferedRegion(); ImageType::SizeType size = region.GetSize(); ImageType::IndexType start = region.GetIndex(); //inputImage->GetSpacing(); //inputImage->GetOrigin(); unsigned int width = size[0]; unsigned int height = size[1]; unsigned int depth = size[2]; osg::RefMatrix* matrix = new osg::RefMatrix; notice()<<"width = "<<width<<" height = "<<height<<" depth = "<<depth<<std::endl; for(unsigned int i=0; i<Dimension; ++i) { (*matrix)(i,i) = inputImage->GetSpacing()[i]; (*matrix)(3,i) = inputImage->GetOrigin()[i]; } osg::Image* image = new osg::Image; image->allocateImage(width, height, depth, GL_LUMINANCE, GL_UNSIGNED_BYTE, 1); unsigned char* data = image->data(); typedef itk::ImageRegionConstIterator< ImageType > IteratorType; IteratorType it(inputImage, region); it.GoToBegin(); while (!it.IsAtEnd()) { *data = it.Get(); ++data; ++it; } image->setUserData(matrix); matrix->preMult(osg::Matrix::scale(double(image->s()), double(image->t()), double(image->r()))); return image; }
osgDB::ReaderWriter::ReadResult ReaderWriterFBX::readNode(const std::string& filenameInit, const Options* options) const { try { std::string ext(osgDB::getLowerCaseFileExtension(filenameInit)); if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; std::string filename(osgDB::findDataFile(filenameInit, options)); if (filename.empty()) return ReadResult::FILE_NOT_FOUND; KFbxSdkManager* pSdkManager = KFbxSdkManager::Create(); if (!pSdkManager) { return ReadResult::ERROR_IN_READING_FILE; } CleanUpFbx cleanUpFbx(pSdkManager); pSdkManager->SetIOSettings(KFbxIOSettings::Create(pSdkManager, IOSROOT)); KFbxScene* pScene = KFbxScene::Create(pSdkManager, ""); // The FBX SDK interprets the filename as UTF-8 #ifdef OSG_USE_UTF8_FILENAME const std::string& utf8filename(filename); #else std::string utf8filename(osgDB::convertStringFromCurrentCodePageToUTF8(filename)); #endif KFbxImporter* lImporter = KFbxImporter::Create(pSdkManager, ""); if (!lImporter->Initialize(utf8filename.c_str(), -1, pSdkManager->GetIOSettings())) { return std::string(lImporter->GetLastErrorString()); } if (!lImporter->IsFBX()) { return ReadResult::ERROR_IN_READING_FILE; } for (int i = 0; i < lImporter->GetTakeCount(); i++) { KFbxTakeInfo* lTakeInfo = lImporter->GetTakeInfo(i); lTakeInfo->mSelect = true; } if (!lImporter->Import(pScene)) { return std::string(lImporter->GetLastErrorString()); } //KFbxAxisSystem::OpenGL.ConvertScene(pScene); // Doesn't work as expected. Still need to transform vertices. if (KFbxNode* pNode = pScene->GetRootNode()) { pScene->SetCurrentTake(pScene->GetCurrentTakeName()); bool useFbxRoot = false; if (options) { std::istringstream iss(options->getOptionString()); std::string opt; while (iss >> opt) { if (opt == "UseFbxRoot") { useFbxRoot = true; } } } osg::ref_ptr<osgAnimation::AnimationManagerBase> pAnimationManager; bool bIsBone = false; int nLightCount = 0; osg::ref_ptr<Options> localOptions = NULL; if (options) localOptions = options->cloneOptions(); else localOptions = new osgDB::Options(); localOptions->setObjectCacheHint(osgDB::ReaderWriter::Options::CACHE_IMAGES); std::string filePath = osgDB::getFilePath(filename); FbxMaterialToOsgStateSet fbxMaterialToOsgStateSet(filePath, localOptions.get()); std::set<const KFbxNode*> fbxSkeletons; findLinkedFbxSkeletonNodes(pNode, fbxSkeletons); std::map<KFbxNode*, osg::Node*> nodeMap; BindMatrixMap boneBindMatrices; std::map<KFbxNode*, osgAnimation::Skeleton*> skeletonMap; ReadResult res = readFbxNode(*pSdkManager, *pScene, pNode, pAnimationManager, bIsBone, nLightCount, fbxMaterialToOsgStateSet, nodeMap, boneBindMatrices, fbxSkeletons, skeletonMap, *localOptions); if (res.success()) { fbxMaterialToOsgStateSet.checkInvertTransparency(); resolveBindMatrices(*res.getNode(), boneBindMatrices, nodeMap); osg::Node* osgNode = res.getNode(); osgNode->getOrCreateStateSet()->setMode(GL_RESCALE_NORMAL,osg::StateAttribute::ON); osgNode->getOrCreateStateSet()->setMode(GL_NORMALIZE,osg::StateAttribute::ON); if (pAnimationManager.valid()) { if (osgNode->getUpdateCallback()) { osg::Group* osgGroup = new osg::Group; osgGroup->addChild(osgNode); osgNode = osgGroup; } //because the animations may be altered after registering pAnimationManager->buildTargetReference(); osgNode->setUpdateCallback(pAnimationManager.get()); } KFbxAxisSystem fbxAxis = pScene->GetGlobalSettings().GetAxisSystem(); if (fbxAxis != KFbxAxisSystem::OpenGL) { int upSign; KFbxAxisSystem::eUpVector eUp = fbxAxis.GetUpVector(upSign); bool bLeftHanded = fbxAxis.GetCoorSystem() == KFbxAxisSystem::LeftHanded; float fSign = upSign < 0 ? -1.0f : 1.0f; float zScale = bLeftHanded ? -1.0f : 1.0f; osg::Matrix mat; switch (eUp) { case KFbxAxisSystem::XAxis: mat.set(0,fSign,0,0,-fSign,0,0,0,0,0,zScale,0,0,0,0,1); break; case KFbxAxisSystem::YAxis: mat.set(1,0,0,0,0,fSign,0,0,0,0,fSign*zScale,0,0,0,0,1); break; case KFbxAxisSystem::ZAxis: mat.set(1,0,0,0,0,0,-fSign*zScale,0,0,fSign,0,0,0,0,0,1); break; } osg::Transform* pTransformTemp = osgNode->asTransform(); osg::MatrixTransform* pMatrixTransform = pTransformTemp ? pTransformTemp->asMatrixTransform() : NULL; if (pMatrixTransform) { pMatrixTransform->setMatrix(pMatrixTransform->getMatrix() * mat); } else { pMatrixTransform = new osg::MatrixTransform(mat); if (useFbxRoot && isBasicRootNode(*osgNode)) { // If root node is a simple group, put all FBX elements under the OSG root osg::Group* osgGroup = osgNode->asGroup(); for(unsigned int i = 0; i < osgGroup->getNumChildren(); ++i) { pMatrixTransform->addChild(osgGroup->getChild(i)); } pMatrixTransform->setName(osgGroup->getName()); } else { pMatrixTransform->addChild(osgNode); } } osgNode = pMatrixTransform; } osgNode->setName(filenameInit); return osgNode; } } } catch (...) { OSG_WARN << "Exception thrown while importing \"" << filenameInit << '\"' << std::endl; } return ReadResult::ERROR_IN_READING_FILE; }
osgDB::ReaderWriter::ReadResult ReaderWriterFBX::readNode(const std::string& filenameInit, const Options* options) const { try { std::string ext(osgDB::getLowerCaseFileExtension(filenameInit)); if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; std::string filename(osgDB::findDataFile(filenameInit, options)); if (filename.empty()) return ReadResult::FILE_NOT_FOUND; FbxManager* pSdkManager = FbxManager::Create(); if (!pSdkManager) { return ReadResult::ERROR_IN_READING_FILE; } CleanUpFbx cleanUpFbx(pSdkManager); pSdkManager->SetIOSettings(FbxIOSettings::Create(pSdkManager, IOSROOT)); FbxScene* pScene = FbxScene::Create(pSdkManager, ""); // The FBX SDK interprets the filename as UTF-8 #ifdef OSG_USE_UTF8_FILENAME const std::string& utf8filename(filename); #else std::string utf8filename(osgDB::convertStringFromCurrentCodePageToUTF8(filename)); #endif FbxImporter* lImporter = FbxImporter::Create(pSdkManager, ""); if (!lImporter->Initialize(utf8filename.c_str(), -1, pSdkManager->GetIOSettings())) { #if FBXSDK_VERSION_MAJOR < 2014 return std::string(lImporter->GetLastErrorString()); #else return std::string(lImporter->GetStatus().GetErrorString()); #endif } if (!lImporter->IsFBX()) { return ReadResult::ERROR_IN_READING_FILE; } for (int i = 0; FbxTakeInfo* lTakeInfo = lImporter->GetTakeInfo(i); i++) { lTakeInfo->mSelect = true; } if (!lImporter->Import(pScene)) { #if FBXSDK_VERSION_MAJOR < 2014 return std::string(lImporter->GetLastErrorString()); #else return std::string(lImporter->GetStatus().GetErrorString()); #endif } //FbxAxisSystem::OpenGL.ConvertScene(pScene); // Doesn't work as expected. Still need to transform vertices. if (FbxNode* pNode = pScene->GetRootNode()) { bool useFbxRoot = false; bool lightmapTextures = false; bool tessellatePolygons = false; if (options) { std::istringstream iss(options->getOptionString()); std::string opt; while (iss >> opt) { if (opt == "UseFbxRoot") { useFbxRoot = true; } if (opt == "LightmapTextures") { lightmapTextures = true; } if (opt == "TessellatePolygons") { tessellatePolygons = true; } } } bool bIsBone = false; int nLightCount = 0; osg::ref_ptr<Options> localOptions = NULL; if (options) localOptions = options->cloneOptions(); else localOptions = new osgDB::Options(); localOptions->setObjectCacheHint(osgDB::ReaderWriter::Options::CACHE_IMAGES); std::string filePath = osgDB::getFilePath(filename); FbxMaterialToOsgStateSet fbxMaterialToOsgStateSet(filePath, localOptions.get(), lightmapTextures); std::set<const FbxNode*> fbxSkeletons; findLinkedFbxSkeletonNodes(pNode, fbxSkeletons); OsgFbxReader::AuthoringTool authoringTool = OsgFbxReader::UNKNOWN; if (FbxDocumentInfo* pDocInfo = pScene->GetDocumentInfo()) { struct ToolName { const char* name; OsgFbxReader::AuthoringTool tool; }; ToolName authoringTools[] = { {"OpenSceneGraph", OsgFbxReader::OPENSCENEGRAPH}, {"3ds Max", OsgFbxReader::AUTODESK_3DSTUDIO_MAX} }; FbxString appName = pDocInfo->LastSaved_ApplicationName.Get(); for (unsigned int i = 0; i < sizeof(authoringTools) / sizeof(authoringTools[0]); ++i) { if (0 == #ifdef WIN32 _strnicmp #else strncasecmp #endif (appName, authoringTools[i].name, strlen(authoringTools[i].name))) { authoringTool = authoringTools[i].tool; break; } } } OsgFbxReader reader(*pSdkManager, *pScene, fbxMaterialToOsgStateSet, fbxSkeletons, *localOptions, authoringTool, lightmapTextures, tessellatePolygons); ReadResult res = reader.readFbxNode(pNode, bIsBone, nLightCount); if (res.success()) { fbxMaterialToOsgStateSet.checkInvertTransparency(); resolveBindMatrices(*res.getNode(), reader.boneBindMatrices, reader.nodeMap); osg::Node* osgNode = res.getNode(); osgNode->getOrCreateStateSet()->setMode(GL_RESCALE_NORMAL,osg::StateAttribute::ON); osgNode->getOrCreateStateSet()->setMode(GL_NORMALIZE,osg::StateAttribute::ON); if (reader.pAnimationManager.valid()) { if (osgNode->getUpdateCallback()) { osg::Group* osgGroup = new osg::Group; osgGroup->addChild(osgNode); osgNode = osgGroup; } //because the animations may be altered after registering reader.pAnimationManager->buildTargetReference(); osgNode->setUpdateCallback(reader.pAnimationManager.get()); } FbxAxisSystem fbxAxis = pScene->GetGlobalSettings().GetAxisSystem(); if (fbxAxis != FbxAxisSystem::OpenGL) { int upSign; FbxAxisSystem::EUpVector eUp = fbxAxis.GetUpVector(upSign); bool bLeftHanded = fbxAxis.GetCoorSystem() == FbxAxisSystem::eLeftHanded; float fSign = upSign < 0 ? -1.0f : 1.0f; float zScale = bLeftHanded ? -1.0f : 1.0f; osg::Matrix mat; switch (eUp) { case FbxAxisSystem::eXAxis: mat.set(0,fSign,0,0,-fSign,0,0,0,0,0,zScale,0,0,0,0,1); break; case FbxAxisSystem::eYAxis: mat.set(1,0,0,0,0,fSign,0,0,0,0,fSign*zScale,0,0,0,0,1); break; case FbxAxisSystem::eZAxis: mat.set(1,0,0,0,0,0,-fSign*zScale,0,0,fSign,0,0,0,0,0,1); break; } osg::Transform* pTransformTemp = osgNode->asTransform(); osg::MatrixTransform* pMatrixTransform = pTransformTemp ? pTransformTemp->asMatrixTransform() : NULL; if (pMatrixTransform) { pMatrixTransform->setMatrix(pMatrixTransform->getMatrix() * mat); } else { pMatrixTransform = new osg::MatrixTransform(mat); if (useFbxRoot && isBasicRootNode(*osgNode)) { // If root node is a simple group, put all FBX elements under the OSG root osg::Group* osgGroup = osgNode->asGroup(); for(unsigned int i = 0; i < osgGroup->getNumChildren(); ++i) { pMatrixTransform->addChild(osgGroup->getChild(i)); } pMatrixTransform->setName(osgGroup->getName()); } else { pMatrixTransform->addChild(osgNode); } } osgNode = pMatrixTransform; } osgNode->setName(filenameInit); return osgNode; } } } catch (...) { OSG_WARN << "Exception thrown while importing \"" << filenameInit << '\"' << std::endl; } return ReadResult::ERROR_IN_READING_FILE; }
virtual ReadResult readNode(const std::string& uri, const Options* options) const { std::string ext = osgDB::getFileExtension(uri); if ( acceptsExtension(ext) ) { // See if the filename starts with server: and strip it off. This will trick OSG // into passing in the filename to our plugin instead of using the CURL plugin if // the filename contains a URL. So, if you want to read a URL, you can use the // following format: osgDB::readNodeFile("server:http://myserver/myearth.earth"). // This should only be necessary for the first level as the other files will have // a tilekey prepended to them. if ((uri.length() > 7) && (uri.substr(0, 7) == "server:")) return readNode(uri.substr(7), options); // parse the tile key and engine ID: std::string tileDef = osgDB::getNameLessExtension(uri); unsigned int lod, x, y, engineID; sscanf(tileDef.c_str(), "%d/%d/%d.%d", &lod, &x, &y, &engineID); // find the appropriate engine: osg::ref_ptr<MPTerrainEngineNode> engineNode; MPTerrainEngineNode::getEngineByUID( (UID)engineID, engineNode ); if ( engineNode.valid() ) { OE_START_TIMER(tileLoadTime); // see if we have a progress tracker ProgressCallback* progress = options ? const_cast<ProgressCallback*>( dynamic_cast<const ProgressCallback*>(options->getUserData())) : 0L; // must have a ProgressCallback if we're profiling. bool ownProgress = (progress == 0L); if ( !progress && _profiling ) progress = new ProgressCallback(); // assemble the key and create the node: const Profile* profile = engineNode->getMap()->getProfile(); TileKey key( lod, x, y, profile ); osg::ref_ptr<osg::Node> node; if ( "osgearth_engine_mp_tile" == ext ) { node = engineNode->createNode(key, progress); } else if ( "osgearth_engine_mp_standalone_tile" == ext ) { node = engineNode->createStandaloneNode(key, progress); } double tileLoadTime = OE_STOP_TIMER(tileLoadTime); if ( progress ) progress->stats()["tile_load_time"] = tileLoadTime; if ( _profiling ) { OE_NOTICE << "tile: " << tileDef << std::endl; for(std::map<std::string,double>::iterator i = progress->stats().begin(); i != progress->stats().end(); ++i) { OE_NOTICE << " " << i->first << " = " << std::setprecision(4) << i->second << " (" << (int)((i->second/tileLoadTime)*100) << "%)" << std::endl; } if ( ownProgress ) { delete progress; progress = 0L; } } // Deal with failed loads. if ( !node.valid() ) { if ( key.getLOD() == 0 || (progress && progress->isCanceled()) ) { // the tile will ask again next time. return ReadResult::FILE_NOT_FOUND; } else { // the parent tile will never ask again as long as it remains in memory. node = new InvalidTileNode( key ); } } else { // notify the Terrain interface of a new tile osg::Timer_t start = osg::Timer::instance()->tick(); engineNode->getTerrain()->notifyTileAdded(key, node.get()); osg::Timer_t end = osg::Timer::instance()->tick(); } return ReadResult( node.get(), ReadResult::FILE_LOADED ); } else { return ReadResult::FILE_NOT_FOUND; } } else { return ReadResult::FILE_NOT_HANDLED; } }
osgDB::ReaderWriter::WriteResult ReaderWriterFBX::writeNode( const osg::Node& node, const std::string& filename, const Options* options) const { try { std::string ext = osgDB::getLowerCaseFileExtension(filename); if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED; osg::ref_ptr<Options> localOptions = options ? static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options; localOptions->getDatabasePathList().push_front(osgDB::getFilePath(filename)); KFbxSdkManager* pSdkManager = KFbxSdkManager::Create(); if (!pSdkManager) { return WriteResult::ERROR_IN_WRITING_FILE; } CleanUpFbx cleanUpFbx(pSdkManager); pSdkManager->SetIOSettings(KFbxIOSettings::Create(pSdkManager, IOSROOT)); bool useFbxRoot = false; if (options) { std::istringstream iss(options->getOptionString()); std::string opt; while (iss >> opt) { if (opt == "Embedded") { pSdkManager->GetIOSettings()->SetBoolProp(EXP_FBX_EMBEDDED, true); } else if (opt == "UseFbxRoot") { useFbxRoot = true; } } } KFbxScene* pScene = KFbxScene::Create(pSdkManager, ""); pluginfbx::WriterNodeVisitor writerNodeVisitor(pScene, pSdkManager, filename, options, osgDB::getFilePath(node.getName().empty() ? filename : node.getName())); if (useFbxRoot && isBasicRootNode(node)) { // If root node is a simple group, put all elements under the FBX root const osg::Group * osgGroup = node.asGroup(); for(unsigned int child=0; child<osgGroup->getNumChildren(); ++child) { const_cast<osg::Node *>(osgGroup->getChild(child))->accept(writerNodeVisitor); } } else { // Normal scene const_cast<osg::Node&>(node).accept(writerNodeVisitor); } KFbxExporter* lExporter = KFbxExporter::Create(pSdkManager, ""); pScene->GetGlobalSettings().SetAxisSystem(KFbxAxisSystem::eOpenGL); // Ensure the directory exists or else the FBX SDK will fail if (!osgDB::makeDirectoryForFile(filename)) { OSG_NOTICE << "Can't create directory for file '" << filename << "'. FBX SDK may fail creating the file." << std::endl; } // The FBX SDK interprets the filename as UTF-8 #ifdef OSG_USE_UTF8_FILENAME const std::string& utf8filename(filename); #else std::string utf8filename(osgDB::convertStringFromCurrentCodePageToUTF8(filename)); #endif if (!lExporter->Initialize(utf8filename.c_str())) { return std::string(lExporter->GetLastErrorString()); } if (!lExporter->Export(pScene)) { return std::string(lExporter->GetLastErrorString()); } return WriteResult::FILE_SAVED; } catch (const std::string& s) { return s; } catch (const char* s) { return std::string(s); } catch (...) { } return WriteResult::ERROR_IN_WRITING_FILE; }