| [2225] | 1 | |
|---|
| 2 | #include <osg/Notify> |
|---|
| [2759] | 3 | #include <osgDB/FileUtils> |
|---|
| [2225] | 4 | #include <osgDB/FileNameUtils> |
|---|
| 5 | |
|---|
| 6 | |
|---|
| [3920] | 7 | #include <Inventor/SoDB.h> |
|---|
| [2225] | 8 | #include <Inventor/SoInteraction.h> |
|---|
| [3920] | 9 | #include <Inventor/nodekits/SoNodeKit.h> |
|---|
| [2225] | 10 | #include <Inventor/nodes/SoSeparator.h> |
|---|
| [7348] | 11 | #include <Inventor/actions/SoWriteAction.h> |
|---|
| 12 | #include <Inventor/actions/SoCallbackAction.h> |
|---|
| [7512] | 13 | #ifdef __COIN__ |
|---|
| [11032] | 14 | # include <Inventor/VRMLnodes/SoVRMLImageTexture.h> |
|---|
| [6544] | 15 | #endif |
|---|
| [2225] | 16 | |
|---|
| [11032] | 17 | #include "ReaderWriterIV.h" |
|---|
| [2225] | 18 | #include "ConvertFromInventor.h" |
|---|
| [7348] | 19 | #include "ConvertToInventor.h" |
|---|
| [2225] | 20 | |
|---|
| [11032] | 21 | |
|---|
| 22 | static void addSearchPaths(const osgDB::FilePathList *searchPaths); |
|---|
| 23 | static void removeSearchPaths(const osgDB::FilePathList *searchPaths); |
|---|
| [7348] | 24 | |
|---|
| [11032] | 25 | |
|---|
| [2225] | 26 | |
|---|
| [7076] | 27 | REGISTER_OSGPLUGIN(Inventor, ReaderWriterIV) |
|---|
| [2225] | 28 | |
|---|
| [11032] | 29 | |
|---|
| 30 | |
|---|
| 31 | |
|---|
| 32 | |
|---|
| 33 | |
|---|
| [2225] | 34 | ReaderWriterIV::ReaderWriterIV() |
|---|
| 35 | { |
|---|
| [11032] | 36 | |
|---|
| [8578] | 37 | supportsExtension("iv","Inventor format"); |
|---|
| 38 | supportsExtension("wrl","VRML world file"); |
|---|
| [11032] | 39 | |
|---|
| 40 | |
|---|
| 41 | initInventor(); |
|---|
| [2225] | 42 | } |
|---|
| 43 | |
|---|
| [11032] | 44 | |
|---|
| 45 | |
|---|
| 46 | |
|---|
| 47 | |
|---|
| 48 | void ReaderWriterIV::initInventor() const |
|---|
| [2225] | 49 | { |
|---|
| 50 | |
|---|
| [3920] | 51 | SoDB::init(); |
|---|
| 52 | SoNodeKit::init(); |
|---|
| [2225] | 53 | SoInteraction::init(); |
|---|
| 54 | |
|---|
| [7512] | 55 | #ifdef __COIN__ |
|---|
| [6543] | 56 | |
|---|
| 57 | SoVRMLImageTexture::setDelayFetchURL(FALSE); |
|---|
| [6544] | 58 | #endif |
|---|
| [11032] | 59 | } |
|---|
| [6543] | 60 | |
|---|
| [2225] | 61 | |
|---|
| [11032] | 62 | |
|---|
| 63 | |
|---|
| 64 | |
|---|
| 65 | |
|---|
| 66 | osgDB::ReaderWriter::ReadResult |
|---|
| 67 | ReaderWriterIV::readNodeFromSoInput(SoInput &input, |
|---|
| 68 | std::string &fileName, const osgDB::ReaderWriter::Options *options) const |
|---|
| 69 | { |
|---|
| 70 | |
|---|
| 71 | const osgDB::FilePathList *searchPaths = options ? &options->getDatabasePathList() : NULL; |
|---|
| 72 | if (options) |
|---|
| 73 | addSearchPaths(searchPaths); |
|---|
| 74 | |
|---|
| 75 | |
|---|
| [2225] | 76 | SoSeparator* rootIVNode = SoDB::readAll(&input); |
|---|
| 77 | |
|---|
| [11032] | 78 | |
|---|
| 79 | if (options) |
|---|
| 80 | removeSearchPaths(searchPaths); |
|---|
| 81 | |
|---|
| [2225] | 82 | |
|---|
| 83 | input.closeFile(); |
|---|
| 84 | |
|---|
| [11032] | 85 | |
|---|
| 86 | ReadResult result; |
|---|
| [2225] | 87 | if (rootIVNode) |
|---|
| 88 | { |
|---|
| [3393] | 89 | rootIVNode->ref(); |
|---|
| [11032] | 90 | |
|---|
| [2225] | 91 | ConvertFromInventor convertIV; |
|---|
| [11032] | 92 | convertIV.preprocess(rootIVNode); |
|---|
| 93 | result = convertIV.convert(rootIVNode); |
|---|
| [3393] | 94 | rootIVNode->unref(); |
|---|
| [11032] | 95 | } else |
|---|
| 96 | result = ReadResult::FILE_NOT_HANDLED; |
|---|
| 97 | |
|---|
| 98 | |
|---|
| 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; |
|---|
| [2225] | 115 | } |
|---|
| 116 | |
|---|
| [11032] | 117 | return result; |
|---|
| [2225] | 118 | } |
|---|
| 119 | |
|---|
| [7348] | 120 | |
|---|
| [11032] | 121 | |
|---|
| 122 | osgDB::ReaderWriter::ReadResult |
|---|
| 123 | ReaderWriterIV::readNode(const std::string& file, |
|---|
| 124 | const osgDB::ReaderWriter::Options* options) const |
|---|
| 125 | { |
|---|
| 126 | |
|---|
| 127 | std::string ext = osgDB::getLowerCaseFileExtension(file); |
|---|
| 128 | if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; |
|---|
| 129 | |
|---|
| 130 | |
|---|
| 131 | std::string fileName = osgDB::findDataFile( file, options ); |
|---|
| 132 | if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; |
|---|
| 133 | |
|---|
| 134 | |
|---|
| 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; |
|---|
| 139 | |
|---|
| 140 | |
|---|
| 141 | SoInput input; |
|---|
| 142 | if (!input.openFile(fileName.data())) |
|---|
| 143 | { |
|---|
| 144 | osg::notify(osg::WARN) << "osgDB::ReaderWriterIV::readIVFile() " |
|---|
| 145 | << "Cannot open file " << fileName << std::endl; |
|---|
| 146 | return ReadResult::ERROR_IN_READING_FILE; |
|---|
| 147 | } |
|---|
| 148 | |
|---|
| 149 | |
|---|
| 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 | |
|---|
| 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 | |
|---|
| 165 | SoInput input; |
|---|
| 166 | |
|---|
| 167 | |
|---|
| 168 | |
|---|
| 169 | |
|---|
| 170 | |
|---|
| 171 | |
|---|
| 172 | |
|---|
| 173 | |
|---|
| 174 | |
|---|
| 175 | |
|---|
| 176 | |
|---|
| 177 | |
|---|
| 178 | |
|---|
| 179 | size_t bufSize = 126*1024; |
|---|
| 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 | } |
|---|
| 189 | } |
|---|
| 190 | input.setBuffer(buf, dataSize); |
|---|
| 191 | osg::notify(osg::INFO) << "osgDB::ReaderWriterIV::readNode() " |
|---|
| 192 | "Stream size: " << dataSize << std::endl; |
|---|
| 193 | |
|---|
| 194 | |
|---|
| 195 | osgDB::ReaderWriter::ReadResult r; |
|---|
| 196 | std::string fileName(""); |
|---|
| 197 | r = readNodeFromSoInput(input, fileName, options); |
|---|
| 198 | |
|---|
| 199 | |
|---|
| 200 | free(buf); |
|---|
| 201 | return r; |
|---|
| 202 | } |
|---|
| 203 | |
|---|
| 204 | |
|---|
| [7348] | 205 | osgDB::ReaderWriter::WriteResult |
|---|
| 206 | ReaderWriterIV::writeNode(const osg::Node& node, const std::string& fileName, |
|---|
| 207 | const osgDB::ReaderWriter::Options* options) const |
|---|
| 208 | { |
|---|
| 209 | |
|---|
| 210 | std::string ext = osgDB::getLowerCaseFileExtension(fileName); |
|---|
| 211 | if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED; |
|---|
| 212 | bool useVRML1 = !isInventorExtension(osgDB::getFileExtension(fileName)); |
|---|
| 213 | |
|---|
| [11032] | 214 | osg::notify(osg::NOTICE) << "osgDB::ReaderWriterIV::writeNode() Writing file " |
|---|
| 215 | << fileName.data() << std::endl; |
|---|
| [7348] | 216 | |
|---|
| 217 | |
|---|
| 218 | ConvertToInventor osg2iv; |
|---|
| 219 | osg2iv.setVRML1Conversion(useVRML1); |
|---|
| 220 | (const_cast<osg::Node*>(&node))->accept(osg2iv); |
|---|
| 221 | SoNode *ivRoot = osg2iv.getIvSceneGraph(); |
|---|
| 222 | if (ivRoot == NULL) |
|---|
| 223 | return WriteResult::ERROR_IN_WRITING_FILE; |
|---|
| 224 | ivRoot->ref(); |
|---|
| 225 | |
|---|
| 226 | |
|---|
| 227 | |
|---|
| 228 | |
|---|
| 229 | |
|---|
| 230 | if (useVRML1) |
|---|
| 231 | SoBase::setInstancePrefix("_"); |
|---|
| 232 | |
|---|
| 233 | |
|---|
| 234 | SoOutput out; |
|---|
| 235 | out.setHeaderString((useVRML1) ? "#VRML V1.0 ascii" : "#Inventor V2.1 ascii"); |
|---|
| 236 | if (!out.openFile(fileName.c_str())) |
|---|
| 237 | return WriteResult::ERROR_IN_WRITING_FILE; |
|---|
| 238 | SoWriteAction wa(&out); |
|---|
| 239 | wa.apply(ivRoot); |
|---|
| 240 | ivRoot->unref(); |
|---|
| 241 | |
|---|
| 242 | return WriteResult::FILE_SAVED; |
|---|
| 243 | } |
|---|
| [11032] | 244 | |
|---|
| 245 | |
|---|
| 246 | static void addSearchPaths(const osgDB::FilePathList *searchPaths) |
|---|
| 247 | { |
|---|
| 248 | for (int i=searchPaths->size()-1; i>=0; i--) |
|---|
| 249 | SoInput::addDirectoryFirst(searchPaths->operator[](i).c_str()); |
|---|
| 250 | } |
|---|
| 251 | |
|---|
| 252 | |
|---|
| 253 | static void removeSearchPaths(const osgDB::FilePathList *searchPaths) |
|---|
| 254 | { |
|---|
| 255 | for (int i=0, c=searchPaths->size(); i<c; i++) |
|---|
| 256 | SoInput::addDirectoryFirst(searchPaths->operator[](i).c_str()); |
|---|
| 257 | } |
|---|