Show
Ignore:
Timestamp:
01/31/10 13:55:29 (3 years ago)
Author:
robert
Message:

From Jan Peciva, "I am sending improved version of Inventor plugin. Attaching just
modified files, while GroupSoLOD.h and .cpp was deleted. Please, delete
it from repository, it is not used any longer and I doubt if it is
probably not used for anything meaningful for a while. In the new code,
there is no GroupSoLOD. Please, delete it.

I am using new plugin version for about 1.5 month so I consider it
stable by myself.

List of changes:
- rewritten Inventor state stack
- shaders support
- light attenuation support
- support for reading from stream (readNode(std::istream& fin, options))
- improved grouping node handling (SoSeparator?, SoGroup?,...)
- fixed transformation bug when two SoShapes/Drawables? with different transformations are placed bellow one grouping node
- introduced preprocessing to handle more advanced usage schemes of SoLOD and SoSwitch? nodes
- unused code clean up
- improved notify messages
- animation callbacks fixes
- FindInventor?.cmake improved finding routines, support for Coin3 and Coin4"

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/src/osgPlugins/Inventor/ReaderWriterIV.cpp

    r8578 r11032  
    1 #include "ReaderWriterIV.h" 
    2  
    31// OSG headers 
    42#include <osg/Notify> 
     
    1311#include <Inventor/actions/SoWriteAction.h> 
    1412#include <Inventor/actions/SoCallbackAction.h> 
    15  
    1613#ifdef __COIN__ 
    17 #include <Inventor/VRMLnodes/SoVRMLImageTexture.h> 
     14# include <Inventor/VRMLnodes/SoVRMLImageTexture.h> 
    1815#endif 
    1916 
     17#include "ReaderWriterIV.h" 
    2018#include "ConvertFromInventor.h" 
    21 #include "GroupSoLOD.h" 
    2219#include "ConvertToInventor.h" 
     20 
     21// forward declarations of static functions 
     22static void addSearchPaths(const osgDB::FilePathList *searchPaths); 
     23static void removeSearchPaths(const osgDB::FilePathList *searchPaths); 
    2324 
    2425 
     
    2627REGISTER_OSGPLUGIN(Inventor, ReaderWriterIV) 
    2728 
     29 
     30/** 
     31 * Constructor. 
     32 * Initializes the ReaderWriterIV. 
     33 */ 
    2834ReaderWriterIV::ReaderWriterIV() 
    2935{ 
     36    // Set supported extensions and options 
    3037    supportsExtension("iv","Inventor format"); 
    3138    supportsExtension("wrl","VRML world file"); 
    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 */ 
     48void ReaderWriterIV::initInventor() const 
     49{ 
    4850    // Initialize Inventor 
    4951    SoDB::init(); 
    5052    SoNodeKit::init(); 
    5153    SoInteraction::init(); 
    52      
    53  
    54     // Initial GroupSoLOD node 
    55     GroupSoLOD::initClass(); 
    5654 
    5755#ifdef __COIN__ 
     
    5957    SoVRMLImageTexture::setDelayFetchURL(FALSE); 
    6058#endif 
     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 */ 
     66osgDB::ReaderWriter::ReadResult 
     67ReaderWriterIV::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 
     122osgDB::ReaderWriter::ReadResult 
     123ReaderWriterIV::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; 
    61139 
    62140    // Open the file 
     
    69147    } 
    70148 
    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 
     154osgDB::ReaderWriter::ReadResult 
     155ReaderWriterIV::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        } 
    85189    } 
    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; 
    88202} 
    89203 
     
    98212    bool useVRML1 = !isInventorExtension(osgDB::getFileExtension(fileName)); 
    99213 
    100     osg::notify(osg::INFO) << "osgDB::ReaderWriterIV::writeNode() Writing file "  
    101                            << fileName.data() << std::endl; 
    102      
    103     // Initialize Inventor 
    104     SoInteraction::init(); 
     214    osg::notify(osg::NOTICE) << "osgDB::ReaderWriterIV::writeNode() Writing file " 
     215                             << fileName.data() << std::endl; 
    105216 
    106217    // Convert OSG graph to Inventor graph 
     
    131242    return WriteResult::FILE_SAVED; 
    132243} 
     244 
     245 
     246static 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 
     253static 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} 
     258