| 32 | | } |
| 33 | | |
| 34 | | // Read file and convert to OSG |
| 35 | | osgDB::ReaderWriter::ReadResult |
| 36 | | ReaderWriterIV::readNode(const std::string& file, |
| 37 | | const osgDB::ReaderWriter::Options* options) const |
| 38 | | { |
| 39 | | std::string ext = osgDB::getLowerCaseFileExtension(file); |
| 40 | | if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; |
| 41 | | |
| 42 | | std::string fileName = osgDB::findDataFile( file, options ); |
| 43 | | if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; |
| 44 | | |
| 45 | | osg::notify(osg::INFO) << "osgDB::ReaderWriterIV::readNode() Reading file " |
| 46 | | << fileName.data() << std::endl; |
| 47 | | |
| | 39 | |
| | 40 | // Initialize Inventor |
| | 41 | initInventor(); |
| | 42 | } |
| | 43 | |
| | 44 | |
| | 45 | /** |
| | 46 | * Initializes Open Inventor. |
| | 47 | */ |
| | 48 | void ReaderWriterIV::initInventor() const |
| | 49 | { |
| | 59 | } |
| | 60 | |
| | 61 | |
| | 62 | /** |
| | 63 | * Read from SoInput and convert to OSG. |
| | 64 | * This is a method used by readNode(string,options) and readNode(istream,options). |
| | 65 | */ |
| | 66 | osgDB::ReaderWriter::ReadResult |
| | 67 | ReaderWriterIV::readNodeFromSoInput(SoInput &input, |
| | 68 | std::string &fileName, const osgDB::ReaderWriter::Options *options) const |
| | 69 | { |
| | 70 | // Parse options and add search paths to SoInput |
| | 71 | const osgDB::FilePathList *searchPaths = options ? &options->getDatabasePathList() : NULL; |
| | 72 | if (options) |
| | 73 | addSearchPaths(searchPaths); |
| | 74 | |
| | 75 | // Create the inventor scenegraph by reading from SoInput |
| | 76 | SoSeparator* rootIVNode = SoDB::readAll(&input); |
| | 77 | |
| | 78 | // Remove recently appened search paths |
| | 79 | if (options) |
| | 80 | removeSearchPaths(searchPaths); |
| | 81 | |
| | 82 | // Close the file |
| | 83 | input.closeFile(); |
| | 84 | |
| | 85 | // Perform conversion |
| | 86 | ReadResult result; |
| | 87 | if (rootIVNode) |
| | 88 | { |
| | 89 | rootIVNode->ref(); |
| | 90 | // Convert the inventor scenegraph to an osg scenegraph |
| | 91 | ConvertFromInventor convertIV; |
| | 92 | convertIV.preprocess(rootIVNode); |
| | 93 | result = convertIV.convert(rootIVNode); |
| | 94 | rootIVNode->unref(); |
| | 95 | } else |
| | 96 | result = ReadResult::FILE_NOT_HANDLED; |
| | 97 | |
| | 98 | // Notify |
| | 99 | if (result.success()) { |
| | 100 | if (fileName.length()) |
| | 101 | osg::notify(osg::NOTICE) << "osgDB::ReaderWriterIV::readNode() " |
| | 102 | << "File " << fileName.data() |
| | 103 | << " loaded successfully." << std::endl; |
| | 104 | else |
| | 105 | osg::notify(osg::NOTICE) << "osgDB::ReaderWriterIV::readNode() " |
| | 106 | << "Stream loaded successfully." << std::endl; |
| | 107 | } else { |
| | 108 | if (fileName.length()) |
| | 109 | osg::notify(osg::WARN) << "osgDB::ReaderWriterIV::readNode() " |
| | 110 | << "Failed to load file " << fileName.data() |
| | 111 | << "." << std::endl; |
| | 112 | else |
| | 113 | osg::notify(osg::WARN) << "osgDB::ReaderWriterIV::readNode() " |
| | 114 | << "Failed to load stream." << std::endl; |
| | 115 | } |
| | 116 | |
| | 117 | return result; |
| | 118 | } |
| | 119 | |
| | 120 | |
| | 121 | // Read file and convert to OSG |
| | 122 | osgDB::ReaderWriter::ReadResult |
| | 123 | ReaderWriterIV::readNode(const std::string& file, |
| | 124 | const osgDB::ReaderWriter::Options* options) const |
| | 125 | { |
| | 126 | // Accept extension |
| | 127 | std::string ext = osgDB::getLowerCaseFileExtension(file); |
| | 128 | if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; |
| | 129 | |
| | 130 | // Find file |
| | 131 | std::string fileName = osgDB::findDataFile( file, options ); |
| | 132 | if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; |
| | 133 | |
| | 134 | // Notify |
| | 135 | osg::notify(osg::NOTICE) << "osgDB::ReaderWriterIV::readNode() Reading file " |
| | 136 | << fileName.data() << std::endl; |
| | 137 | osg::notify(osg::INFO) << "osgDB::ReaderWriterIV::readNode() Inventor version: " |
| | 138 | << SoDB::getVersion() << std::endl; |
| 71 | | // Create the inventor scenegraph from the file |
| 72 | | SoSeparator* rootIVNode = SoDB::readAll(&input); |
| 73 | | |
| 74 | | // Close the file |
| 75 | | input.closeFile(); |
| 76 | | |
| 77 | | if (rootIVNode) |
| 78 | | { |
| 79 | | rootIVNode->ref(); |
| 80 | | // Convert the inventor scenegraph to an osg scenegraph and return it |
| 81 | | ConvertFromInventor convertIV; |
| 82 | | ReadResult result = convertIV.convert(rootIVNode); |
| 83 | | rootIVNode->unref(); |
| 84 | | return result; |
| | 149 | // Perform reading from SoInput |
| | 150 | return readNodeFromSoInput(input, fileName, options); |
| | 151 | } |
| | 152 | |
| | 153 | |
| | 154 | osgDB::ReaderWriter::ReadResult |
| | 155 | ReaderWriterIV::readNode(std::istream& fin, |
| | 156 | const osgDB::ReaderWriter::Options* options) const |
| | 157 | { |
| | 158 | // Notify |
| | 159 | osg::notify(osg::NOTICE) << "osgDB::ReaderWriterIV::readNode() " |
| | 160 | "Reading from stream." << std::endl; |
| | 161 | osg::notify(osg::INFO) << "osgDB::ReaderWriterIV::readNode() " |
| | 162 | "Inventor version: " << SoDB::getVersion() << std::endl; |
| | 163 | |
| | 164 | // Open the file |
| | 165 | SoInput input; |
| | 166 | |
| | 167 | // Assign istream to SoInput |
| | 168 | // note: It seems there is no straightforward way to do that. |
| | 169 | // SoInput accepts only FILE by setFilePointer or memory buffer |
| | 170 | // by setBuffer. The FILE is dangerous on Windows, since it forces |
| | 171 | // the plugin and Inventor DLL to use the same runtime library |
| | 172 | // (otherwise there are app crashes). |
| | 173 | // The memory buffer seems much better option here, even although |
| | 174 | // there will not be a real streaming. However, the model data |
| | 175 | // are usually much smaller than textures, so we should not worry |
| | 176 | // about it and think how to stream textures instead. |
| | 177 | |
| | 178 | // Get the data to the buffer |
| | 179 | size_t bufSize = 126*1024; // let's make it something bellow 128KB |
| | 180 | char *buf = (char*)malloc(bufSize); |
| | 181 | size_t dataSize = 0; |
| | 182 | while (!fin.eof() && fin.good()) { |
| | 183 | fin.read(buf+dataSize, bufSize-dataSize); |
| | 184 | dataSize += fin.gcount(); |
| | 185 | if (bufSize == dataSize) { |
| | 186 | bufSize *= 2; |
| | 187 | buf = (char*)realloc(buf, bufSize); |
| | 188 | } |
| 86 | | |
| 87 | | return ReadResult::FILE_NOT_HANDLED; |
| | 190 | input.setBuffer(buf, dataSize); |
| | 191 | osg::notify(osg::INFO) << "osgDB::ReaderWriterIV::readNode() " |
| | 192 | "Stream size: " << dataSize << std::endl; |
| | 193 | |
| | 194 | // Perform reading from SoInput |
| | 195 | osgDB::ReaderWriter::ReadResult r; |
| | 196 | std::string fileName(""); |
| | 197 | r = readNodeFromSoInput(input, fileName, options); |
| | 198 | |
| | 199 | // clean up and return |
| | 200 | free(buf); |
| | 201 | return r; |