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"
This commit is contained in:
@@ -1,5 +1,3 @@
|
||||
#include "ReaderWriterIV.h"
|
||||
|
||||
// OSG headers
|
||||
#include <osg/Notify>
|
||||
#include <osgDB/FileUtils>
|
||||
@@ -12,52 +10,132 @@
|
||||
#include <Inventor/nodes/SoSeparator.h>
|
||||
#include <Inventor/actions/SoWriteAction.h>
|
||||
#include <Inventor/actions/SoCallbackAction.h>
|
||||
|
||||
#ifdef __COIN__
|
||||
#include <Inventor/VRMLnodes/SoVRMLImageTexture.h>
|
||||
# include <Inventor/VRMLnodes/SoVRMLImageTexture.h>
|
||||
#endif
|
||||
|
||||
#include "ReaderWriterIV.h"
|
||||
#include "ConvertFromInventor.h"
|
||||
#include "GroupSoLOD.h"
|
||||
#include "ConvertToInventor.h"
|
||||
|
||||
// forward declarations of static functions
|
||||
static void addSearchPaths(const osgDB::FilePathList *searchPaths);
|
||||
static void removeSearchPaths(const osgDB::FilePathList *searchPaths);
|
||||
|
||||
|
||||
// Register with Registry to instantiate the inventor reader.
|
||||
REGISTER_OSGPLUGIN(Inventor, ReaderWriterIV)
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* Initializes the ReaderWriterIV.
|
||||
*/
|
||||
ReaderWriterIV::ReaderWriterIV()
|
||||
{
|
||||
// Set supported extensions and options
|
||||
supportsExtension("iv","Inventor format");
|
||||
supportsExtension("wrl","VRML world file");
|
||||
|
||||
// Initialize Inventor
|
||||
initInventor();
|
||||
}
|
||||
|
||||
// Read file and convert to OSG
|
||||
osgDB::ReaderWriter::ReadResult
|
||||
ReaderWriterIV::readNode(const std::string& file,
|
||||
const osgDB::ReaderWriter::Options* options) const
|
||||
|
||||
/**
|
||||
* Initializes Open Inventor.
|
||||
*/
|
||||
void ReaderWriterIV::initInventor() 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) << "osgDB::ReaderWriterIV::readNode() Reading file "
|
||||
<< fileName.data() << std::endl;
|
||||
|
||||
// Initialize Inventor
|
||||
SoDB::init();
|
||||
SoNodeKit::init();
|
||||
SoInteraction::init();
|
||||
|
||||
|
||||
// Initial GroupSoLOD node
|
||||
GroupSoLOD::initClass();
|
||||
|
||||
#ifdef __COIN__
|
||||
// Disable delayed loading of VRML textures
|
||||
SoVRMLImageTexture::setDelayFetchURL(FALSE);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read from SoInput and convert to OSG.
|
||||
* This is a method used by readNode(string,options) and readNode(istream,options).
|
||||
*/
|
||||
osgDB::ReaderWriter::ReadResult
|
||||
ReaderWriterIV::readNodeFromSoInput(SoInput &input,
|
||||
std::string &fileName, const osgDB::ReaderWriter::Options *options) const
|
||||
{
|
||||
// Parse options and add search paths to SoInput
|
||||
const osgDB::FilePathList *searchPaths = options ? &options->getDatabasePathList() : NULL;
|
||||
if (options)
|
||||
addSearchPaths(searchPaths);
|
||||
|
||||
// Create the inventor scenegraph by reading from SoInput
|
||||
SoSeparator* rootIVNode = SoDB::readAll(&input);
|
||||
|
||||
// Remove recently appened search paths
|
||||
if (options)
|
||||
removeSearchPaths(searchPaths);
|
||||
|
||||
// Close the file
|
||||
input.closeFile();
|
||||
|
||||
// Perform conversion
|
||||
ReadResult result;
|
||||
if (rootIVNode)
|
||||
{
|
||||
rootIVNode->ref();
|
||||
// Convert the inventor scenegraph to an osg scenegraph
|
||||
ConvertFromInventor convertIV;
|
||||
convertIV.preprocess(rootIVNode);
|
||||
result = convertIV.convert(rootIVNode);
|
||||
rootIVNode->unref();
|
||||
} else
|
||||
result = ReadResult::FILE_NOT_HANDLED;
|
||||
|
||||
// Notify
|
||||
if (result.success()) {
|
||||
if (fileName.length())
|
||||
osg::notify(osg::NOTICE) << "osgDB::ReaderWriterIV::readNode() "
|
||||
<< "File " << fileName.data()
|
||||
<< " loaded successfully." << std::endl;
|
||||
else
|
||||
osg::notify(osg::NOTICE) << "osgDB::ReaderWriterIV::readNode() "
|
||||
<< "Stream loaded successfully." << std::endl;
|
||||
} else {
|
||||
if (fileName.length())
|
||||
osg::notify(osg::WARN) << "osgDB::ReaderWriterIV::readNode() "
|
||||
<< "Failed to load file " << fileName.data()
|
||||
<< "." << std::endl;
|
||||
else
|
||||
osg::notify(osg::WARN) << "osgDB::ReaderWriterIV::readNode() "
|
||||
<< "Failed to load stream." << std::endl;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// Read file and convert to OSG
|
||||
osgDB::ReaderWriter::ReadResult
|
||||
ReaderWriterIV::readNode(const std::string& file,
|
||||
const osgDB::ReaderWriter::Options* options) const
|
||||
{
|
||||
// Accept extension
|
||||
std::string ext = osgDB::getLowerCaseFileExtension(file);
|
||||
if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
|
||||
|
||||
// Find file
|
||||
std::string fileName = osgDB::findDataFile( file, options );
|
||||
if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
|
||||
|
||||
// Notify
|
||||
osg::notify(osg::NOTICE) << "osgDB::ReaderWriterIV::readNode() Reading file "
|
||||
<< fileName.data() << std::endl;
|
||||
osg::notify(osg::INFO) << "osgDB::ReaderWriterIV::readNode() Inventor version: "
|
||||
<< SoDB::getVersion() << std::endl;
|
||||
|
||||
// Open the file
|
||||
SoInput input;
|
||||
@@ -68,23 +146,59 @@ ReaderWriterIV::readNode(const std::string& file,
|
||||
return ReadResult::ERROR_IN_READING_FILE;
|
||||
}
|
||||
|
||||
// Create the inventor scenegraph from the file
|
||||
SoSeparator* rootIVNode = SoDB::readAll(&input);
|
||||
// Perform reading from SoInput
|
||||
return readNodeFromSoInput(input, fileName, options);
|
||||
}
|
||||
|
||||
// Close the file
|
||||
input.closeFile();
|
||||
|
||||
if (rootIVNode)
|
||||
{
|
||||
rootIVNode->ref();
|
||||
// Convert the inventor scenegraph to an osg scenegraph and return it
|
||||
ConvertFromInventor convertIV;
|
||||
ReadResult result = convertIV.convert(rootIVNode);
|
||||
rootIVNode->unref();
|
||||
return result;
|
||||
osgDB::ReaderWriter::ReadResult
|
||||
ReaderWriterIV::readNode(std::istream& fin,
|
||||
const osgDB::ReaderWriter::Options* options) const
|
||||
{
|
||||
// Notify
|
||||
osg::notify(osg::NOTICE) << "osgDB::ReaderWriterIV::readNode() "
|
||||
"Reading from stream." << std::endl;
|
||||
osg::notify(osg::INFO) << "osgDB::ReaderWriterIV::readNode() "
|
||||
"Inventor version: " << SoDB::getVersion() << std::endl;
|
||||
|
||||
// Open the file
|
||||
SoInput input;
|
||||
|
||||
// Assign istream to SoInput
|
||||
// note: It seems there is no straightforward way to do that.
|
||||
// SoInput accepts only FILE by setFilePointer or memory buffer
|
||||
// by setBuffer. The FILE is dangerous on Windows, since it forces
|
||||
// the plugin and Inventor DLL to use the same runtime library
|
||||
// (otherwise there are app crashes).
|
||||
// The memory buffer seems much better option here, even although
|
||||
// there will not be a real streaming. However, the model data
|
||||
// are usually much smaller than textures, so we should not worry
|
||||
// about it and think how to stream textures instead.
|
||||
|
||||
// Get the data to the buffer
|
||||
size_t bufSize = 126*1024; // let's make it something bellow 128KB
|
||||
char *buf = (char*)malloc(bufSize);
|
||||
size_t dataSize = 0;
|
||||
while (!fin.eof() && fin.good()) {
|
||||
fin.read(buf+dataSize, bufSize-dataSize);
|
||||
dataSize += fin.gcount();
|
||||
if (bufSize == dataSize) {
|
||||
bufSize *= 2;
|
||||
buf = (char*)realloc(buf, bufSize);
|
||||
}
|
||||
}
|
||||
input.setBuffer(buf, dataSize);
|
||||
osg::notify(osg::INFO) << "osgDB::ReaderWriterIV::readNode() "
|
||||
"Stream size: " << dataSize << std::endl;
|
||||
|
||||
return ReadResult::FILE_NOT_HANDLED;
|
||||
// Perform reading from SoInput
|
||||
osgDB::ReaderWriter::ReadResult r;
|
||||
std::string fileName("");
|
||||
r = readNodeFromSoInput(input, fileName, options);
|
||||
|
||||
// clean up and return
|
||||
free(buf);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@@ -97,11 +211,8 @@ ReaderWriterIV::writeNode(const osg::Node& node, const std::string& fileName,
|
||||
if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED;
|
||||
bool useVRML1 = !isInventorExtension(osgDB::getFileExtension(fileName));
|
||||
|
||||
osg::notify(osg::INFO) << "osgDB::ReaderWriterIV::writeNode() Writing file "
|
||||
<< fileName.data() << std::endl;
|
||||
|
||||
// Initialize Inventor
|
||||
SoInteraction::init();
|
||||
osg::notify(osg::NOTICE) << "osgDB::ReaderWriterIV::writeNode() Writing file "
|
||||
<< fileName.data() << std::endl;
|
||||
|
||||
// Convert OSG graph to Inventor graph
|
||||
ConvertToInventor osg2iv;
|
||||
@@ -130,3 +241,18 @@ ReaderWriterIV::writeNode(const osg::Node& node, const std::string& fileName,
|
||||
|
||||
return WriteResult::FILE_SAVED;
|
||||
}
|
||||
|
||||
|
||||
static void addSearchPaths(const osgDB::FilePathList *searchPaths)
|
||||
{
|
||||
for (int i=searchPaths->size()-1; i>=0; i--)
|
||||
SoInput::addDirectoryFirst(searchPaths->operator[](i).c_str());
|
||||
}
|
||||
|
||||
|
||||
static void removeSearchPaths(const osgDB::FilePathList *searchPaths)
|
||||
{
|
||||
for (int i=0, c=searchPaths->size(); i<c; i++)
|
||||
SoInput::addDirectoryFirst(searchPaths->operator[](i).c_str());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user