From Gustav Haapalahti and Robert Osfield,

First Submission email from Gustav:
"This submission adds a --cache option to osgconv and osgviewer that enables setObjectCacheHint(osgDB::Options::CACHE_ALL); It greatly reduces memory usage when a .osg file has lots of external references with ProxyNode:s that points to the same file.

Options are also added to the osg plugin. The code was already mostly implemented but there was no way to change the options.
includeExternalReferences
writeExternalReferenceFiles
A counter is added to keep track if an external file has already been written down to avoid writing the same file over and over again. If it has already been written once then it is not written again.
The counter is added to the Output class in osgDB.
"

Second Submission email from Gustav:
"This is a continuation to my previous submission.
I noticed that the same problem that I fixed in ProxyNode.cpp for the osg plugin (external files being written over and over again) also existed in the ive plugin. I attached a submission where the ive plugin remembers which external files that have already been written and do not write them again."


Changes to the above done by Robert Osfield,

    changed command line parameter to --enable-object-cache
    changed set/get methods in osgDB::Output and ive/DataOutputStream.cpp to be s/getExternalFileWritten(const std::string&)
    cleaned up set up of osgDB::Options.
This commit is contained in:
Robert Osfield 2009-06-08 16:50:50 +00:00
parent e1b7de4b3d
commit 3171be0ff7
9 changed files with 85 additions and 5 deletions

View File

@ -516,6 +516,7 @@ static void usage( const char *prog, const char *msg )
osg::notify(osg::NOTICE)<<" --addMissingColors - Adding a white color value to all geometry that don't have\n"
" their own color values (--addMissingColours also accepted)."<< std::endl;
osg::notify(osg::NOTICE)<<" --overallNormal - Replace normals with a single overall normal."<< std::endl;
osg::notify(osg::NOTICE)<<" --enable-object-cache - Enable caching of objects, images, etc."<< std::endl;
osg::notify( osg::NOTICE ) << std::endl;
osg::notify( osg::NOTICE ) <<
@ -731,6 +732,9 @@ int main( int argc, char **argv )
bool do_overallNormal = false;
while(arguments.read("--overallNormal") || arguments.read("--overallNormal")) { do_overallNormal = true; }
bool enableObjectCache = false;
while(arguments.read("--enable-object-cache")) { enableObjectCache = true; }
// any option left unread are converted into errors to write out later.
arguments.reportRemainingOptionsAsUnrecognized();
@ -749,6 +753,11 @@ int main( int argc, char **argv )
}
}
if (enableObjectCache)
{
if (osgDB::Registry::instance()->getOptions()==0) osgDB::Registry::instance()->setOptions(new osgDB::Options());
osgDB::Registry::instance()->getOptions()->setObjectCacheHint(osgDB::Options::CACHE_ALL);
}
std::string fileNameOut("converted.osg");
if (fileNames.size()>1)

View File

@ -100,7 +100,10 @@ class OSGDB_EXPORT Output : public osgDB::ofstream
bool getOutputShaderFiles() const { return _outputShaderFiles; }
virtual std::string getShaderFileNameForOutput();
void setExternalFileWritten(const std::string& filename, bool hasBeenWritten=true);
bool getExternalFileWritten(const std::string& filename) const;
protected:
@ -127,6 +130,9 @@ class OSGDB_EXPORT Output : public osgDB::ofstream
unsigned int _shaderFileNameNumber;
bool _writeOutDefaultValues;
typedef std::map<std::string, bool> ExternalFileWrittenMap;
ExternalFileWrittenMap _externalFileWritten;
};
}

View File

@ -245,3 +245,14 @@ std::string Output::getShaderFileNameForOutput()
return fileName;
}
void Output::setExternalFileWritten(const std::string& filename, bool hasBeenWritten)
{
_externalFileWritten[filename] = hasBeenWritten;
}
bool Output::getExternalFileWritten(const std::string& filename) const
{
ExternalFileWrittenMap::const_iterator itr = _externalFileWritten.find(filename);
if (itr != _externalFileWritten.end()) return itr->second;
return false;
}

View File

@ -1835,3 +1835,15 @@ void DataOutputStream::writeObject(const osg::Object* object)
// fallback, osg::Object type not supported, so can't write out
writeInt(-1);
}
void DataOutputStream::setExternalFileWritten(const std::string& filename, bool hasBeenWritten)
{
_externalFileWritten[filename] = hasBeenWritten;
}
bool DataOutputStream::getExternalFileWritten(const std::string& filename) const
{
ExternalFileWrittenMap::const_iterator itr = _externalFileWritten.find(filename);
if (itr != _externalFileWritten.end()) return itr->second;
return false;
}

View File

@ -138,6 +138,10 @@ public:
bool compress(std::ostream& fout, const std::string& source) const;
void setExternalFileWritten(const std::string& filename, bool hasBeenWritten=true);
bool getExternalFileWritten(const std::string& filename) const;
private:
std::ostream* _ostream;
@ -182,6 +186,9 @@ private:
IncludeImageMode _includeImageMode;
osg::ref_ptr<const osgDB::ReaderWriter::Options> _options;
typedef std::map<std::string, bool> ExternalFileWrittenMap;
ExternalFileWrittenMap _externalFileWritten;
};
}

View File

@ -120,12 +120,20 @@ void ProxyNode::write(DataOutputStream* out)
{
if(!writeOutExternalIVEFIles)
{
osgDB::writeNodeFile(*getChild(i), getFileName(i));
if (!out->getExternalFileWritten(getFileName(i)))
{
osgDB::writeNodeFile(*getChild(i), getFileName(i));
out->setExternalFileWritten(getFileName(i), true);
}
}
else
{
std::string ivename = writeDirectory + osgDB::getStrippedName(getFileName(i)) +".ive";
osgDB::writeNodeFile(*getChild(i), ivename);
if (!out->getExternalFileWritten(getFileName(i)))
{
osgDB::writeNodeFile(*getChild(i), ivename);
out->setExternalFileWritten(ivename, true);
}
}
}
}

View File

@ -164,6 +164,14 @@ bool ProxyNode_writeLocalData(const Object& obj, Output& fw)
bool includeExternalReferences = false;
bool useOriginalExternalReferences = true;
bool writeExternalReferenceFiles = false;
std::string optionsString = fw.getOptions()->getOptionString();
includeExternalReferences = optionsString.find("includeExternalReferences")!=std::string::npos;
bool newExternals = optionsString.find("writeExternalReferenceFiles")!=std::string::npos;
if (newExternals)
{
useOriginalExternalReferences = false;
writeExternalReferenceFiles = true;
}
const ProxyNode& proxyNode = static_cast<const ProxyNode&>(obj);
@ -238,14 +246,23 @@ bool ProxyNode_writeLocalData(const Object& obj, Output& fw)
{
if(useOriginalExternalReferences) //out->getUseOriginalExternalReferences())
{
osgDB::writeNodeFile(*proxyNode.getChild(i), proxyNode.getFileName(i));
std::string origname = proxyNode.getFileName(i);
if (!fw.getExternalFileWritten(origname))
{
osgDB::writeNodeFile(*proxyNode.getChild(i), origname);
fw.setExternalFileWritten(proxyNode.getFileName(i), true);
}
}
else
{
std::string path = osgDB::getFilePath(fw.getFileName());
std::string new_filename = osgDB::getStrippedName(proxyNode.getFileName(i)) +".osg";
std::string osgname = path.empty() ? new_filename : (path +"/"+ new_filename) ;
osgDB::writeNodeFile(*proxyNode.getChild(i), osgname);
if (!fw.getExternalFileWritten(osgname))
{
osgDB::writeNodeFile(*proxyNode.getChild(i), osgname);
fw.setExternalFileWritten(osgname, true);
}
}
}
}

View File

@ -110,6 +110,8 @@ class OSGReaderWriter : public ReaderWriter
supportsExtension("osgs","Psuedo OpenSceneGraph file loaded, with file encoded in filename string");
supportsOption("precision","Set the floating point precision when writing out files");
supportsOption("OutputTextureFiles","Write out the texture images to file");
supportsOption("includeExternalReferences","Export option");
supportsOption("writeExternalReferenceFiles","Export option");
}
virtual const char* className() const { return "OSG Reader/Writer"; }

View File

@ -57,6 +57,7 @@ Viewer::Viewer(osg::ArgumentParser& arguments)
arguments.getApplicationUsage()->addCommandLineOption("--run-on-demand","Set the run methods frame rate management to only rendering frames when required.");
arguments.getApplicationUsage()->addCommandLineOption("--run-continuous","Set the run methods frame rate management to rendering frames continuously.");
arguments.getApplicationUsage()->addCommandLineOption("--run-max-frame-rate","Set the run methods maximum permissable frame rate, 0.0 is default and switching off frame rate capping.");
arguments.getApplicationUsage()->addCommandLineOption("--enable-object-cache","Enable caching of objects, images, etc.");
// FIXME: Uncomment these lines when the options have been documented properly
//arguments.getApplicationUsage()->addCommandLineOption("--3d-sd","");
@ -72,6 +73,13 @@ Viewer::Viewer(osg::ArgumentParser& arguments)
readConfig = readConfiguration(filename) || readConfig;
}
// Enable caching?
while (arguments.read("--enable-object-cache"))
{
if (osgDB::Registry::instance()->getOptions()==0) osgDB::Registry::instance()->setOptions(new osgDB::Options());
osgDB::Registry::instance()->getOptions()->setObjectCacheHint(osgDB::Options::CACHE_ALL);
}
while (arguments.read("--SingleThreaded")) setThreadingModel(SingleThreaded);
while (arguments.read("--CullDrawThreadPerContext")) setThreadingModel(CullDrawThreadPerContext);
while (arguments.read("--DrawThreadPerContext")) setThreadingModel(DrawThreadPerContext);