From Jan Peciva, Added write support into Inventor plugin.
Note from Robert Osfield. A couple of lines of code in ConvertToInventor.cpp would not compile under g++ 4.1.2, so rather than hold back the dev release till this is resolved I've optional compiled out the problem section. The #define DISABLE_PROBLEM_COMPILE_SECTIONS is used to compile out the problem section, this define is add via the CMakeLists.txt file.
This commit is contained in:
@@ -2,21 +2,25 @@ INCLUDE(OsgMacroUtils)
|
||||
|
||||
INCLUDE_DIRECTORIES( ${INVENTOR_INCLUDE_DIR} )
|
||||
|
||||
# Disable the build of a problem section in ConvertToInventor.cpp
|
||||
ADD_DEFINITIONS(-DDISABLE_PROBLEM_COMPILE_SECTIONS)
|
||||
|
||||
SET(TARGET_SRC
|
||||
ConvertToInventor.cpp
|
||||
ConvertFromInventor.cpp
|
||||
GroupSoLOD.cpp
|
||||
PendulumCallback.cpp
|
||||
ReaderWriterIV.cpp
|
||||
ShuttleCallback.cpp
|
||||
)
|
||||
)
|
||||
SET(TARGET_HDRS
|
||||
ConvertToInventor.h
|
||||
ConvertFromInventor.h
|
||||
GroupSoLOD.h
|
||||
PendulumCallback.h
|
||||
ReaderWriterIV.h
|
||||
ShuttleCallback.h
|
||||
)
|
||||
)
|
||||
|
||||
SET(TARGET_EXTERNAL_LIBRARIES ${INVENTOR_LIBRARY} )
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
#include <Inventor/SoPrimitiveVertex.h>
|
||||
#include <Inventor/SbLinear.h>
|
||||
|
||||
#ifdef COIN_BASIC_H
|
||||
#ifdef __COIN__
|
||||
#include <Inventor/VRMLnodes/SoVRMLImageTexture.h>
|
||||
#endif
|
||||
|
||||
@@ -95,7 +95,7 @@ osg::Node* ConvertFromInventor::convert(SoNode* rootIVNode)
|
||||
cbAction.addPreCallback(SoGroup::getClassTypeId(), preGroup, this);
|
||||
cbAction.addPostCallback(SoGroup::getClassTypeId(), postGroup, this);
|
||||
cbAction.addPreCallback(SoTexture2::getClassTypeId(), preTexture, this);
|
||||
#ifdef COIN_BASIC_H
|
||||
#ifdef __COIN__
|
||||
cbAction.addPreCallback(SoVRMLImageTexture::getClassTypeId(),
|
||||
preVRMLImageTexture, this);
|
||||
#endif
|
||||
@@ -498,6 +498,51 @@ ConvertFromInventor::getStateSet(SoCallbackAction* action)
|
||||
// Inherit modes from the global state
|
||||
stateSet->clear();
|
||||
|
||||
// Convert the IV texture to OSG texture if any
|
||||
osg::ref_ptr<osg::Texture2D> texture;
|
||||
const SoNode *ivTexture = soTexStack.top();
|
||||
if (ivTexture)
|
||||
{
|
||||
osg::notify(osg::INFO)<<"Have texture"<<std::endl;
|
||||
|
||||
// Found a corresponding OSG texture object
|
||||
if (ivToOsgTexMap[ivTexture])
|
||||
texture = ivToOsgTexMap[ivTexture];
|
||||
else
|
||||
{
|
||||
// Create a new osg texture
|
||||
texture = convertIVTexToOSGTex(ivTexture, action);
|
||||
|
||||
// Add the new texture to the database
|
||||
ivToOsgTexMap[ivTexture] = texture.get();
|
||||
}
|
||||
|
||||
stateSet->setTextureAttributeAndModes(0, texture.get(), osg::StateAttribute::ON);
|
||||
|
||||
// Set the texture environment
|
||||
osg::ref_ptr<osg::TexEnv> texEnv = new osg::TexEnv;
|
||||
switch (action->getTextureModel())
|
||||
{
|
||||
case SoTexture2::MODULATE:
|
||||
texEnv->setMode(osg::TexEnv::MODULATE);
|
||||
break;
|
||||
case SoTexture2::DECAL:
|
||||
texEnv->setMode(osg::TexEnv::DECAL);
|
||||
break;
|
||||
case SoTexture2::BLEND:
|
||||
texEnv->setMode(osg::TexEnv::BLEND);
|
||||
break;
|
||||
|
||||
// SGI's Inventor does not have REPLACE mode, but the Coin 3D library does.
|
||||
// Coin supports REPLACE since 2.2 release, TGS Inventor from 4.0.
|
||||
// Let's convert to the TexEnv anyway.
|
||||
case (SoTexture2::Model)GL_REPLACE: // SoTexture2::REPLACE is the same as GL_REPLACE
|
||||
texEnv->setMode(osg::TexEnv::REPLACE);
|
||||
break;
|
||||
}
|
||||
stateSet->setTextureAttributeAndModes(0,texEnv.get(),osg::StateAttribute::ON);
|
||||
}
|
||||
|
||||
SbColor ambient, diffuse, specular, emission;
|
||||
float shininess, transparency;
|
||||
|
||||
@@ -506,7 +551,24 @@ ConvertFromInventor::getStateSet(SoCallbackAction* action)
|
||||
shininess, transparency, 0);
|
||||
|
||||
// Set transparency
|
||||
if (transparency > 0)
|
||||
SbBool hasTextureTransparency = FALSE;
|
||||
if (ivTexture) {
|
||||
SbVec2s tmp;
|
||||
int bpp;
|
||||
if (ivTexture->isOfType(SoTexture2::getClassTypeId()))
|
||||
((SoTexture2*)ivTexture)->image.getValue(tmp, bpp);
|
||||
#ifdef __COIN__
|
||||
else
|
||||
if (ivTexture->isOfType(SoVRMLImageTexture::getClassTypeId())) {
|
||||
const SbImage *img = ((SoVRMLImageTexture*)ivTexture)->getImage();
|
||||
if (img) img->getValue(tmp, bpp);
|
||||
else bpp = 0;
|
||||
}
|
||||
#endif
|
||||
hasTextureTransparency = bpp==4 || bpp==2;
|
||||
}
|
||||
|
||||
if (transparency > 0 || hasTextureTransparency)
|
||||
{
|
||||
osg::ref_ptr<osg::BlendFunc> transparency = new osg::BlendFunc;
|
||||
stateSet->setAttributeAndModes(transparency.get(),
|
||||
@@ -621,51 +683,6 @@ ConvertFromInventor::getStateSet(SoCallbackAction* action)
|
||||
osg::StateAttribute::ON);
|
||||
}
|
||||
|
||||
// Convert the IV texture to OSG texture if any
|
||||
osg::ref_ptr<osg::Texture2D> texture;
|
||||
if (soTexStack.top())
|
||||
{
|
||||
osg::notify(osg::INFO)<<"Have texture"<<std::endl;
|
||||
|
||||
// Found a corresponding OSG texture object
|
||||
if (ivToOsgTexMap[soTexStack.top()])
|
||||
texture = ivToOsgTexMap[soTexStack.top()];
|
||||
else
|
||||
{
|
||||
// Create a new osg texture
|
||||
texture = convertIVTexToOSGTex(soTexStack.top(), action);
|
||||
|
||||
// Add the new texture to the database
|
||||
ivToOsgTexMap[soTexStack.top()] = texture.get();
|
||||
}
|
||||
|
||||
stateSet->setTextureAttributeAndModes(0,texture.get(), osg::StateAttribute::ON);
|
||||
|
||||
// Set the texture environment
|
||||
osg::ref_ptr<osg::TexEnv> texEnv = new osg::TexEnv;
|
||||
switch (action->getTextureModel())
|
||||
{
|
||||
case SoTexture2::MODULATE:
|
||||
texEnv->setMode(osg::TexEnv::MODULATE);
|
||||
break;
|
||||
case SoTexture2::DECAL:
|
||||
texEnv->setMode(osg::TexEnv::DECAL);
|
||||
break;
|
||||
case SoTexture2::BLEND:
|
||||
texEnv->setMode(osg::TexEnv::BLEND);
|
||||
break;
|
||||
|
||||
#ifdef __COIN__
|
||||
// SGI's Inventor does not have REPLACE mode, but the Coin 3D library does.
|
||||
// Coin supports REPLACE since 2.2 release, TGS Inventor from 4.0.
|
||||
case SoTexture2::REPLACE:
|
||||
texEnv->setMode(osg::TexEnv::REPLACE);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
stateSet->setTextureAttributeAndModes(0,texEnv.get(),osg::StateAttribute::ON);
|
||||
}
|
||||
|
||||
return stateSet;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -696,7 +713,7 @@ ConvertFromInventor::convertIVTexToOSGTex(const SoNode* soNode,
|
||||
std::string fileName;
|
||||
if (soNode->isOfType(SoTexture2::getClassTypeId()))
|
||||
fileName = ((SoTexture2*)soNode)->filename.getValue().getString();
|
||||
#ifdef COIN_BASIC_H
|
||||
#ifdef __COIN__
|
||||
else
|
||||
if (soNode->isOfType(SoVRMLImageTexture::getClassTypeId()))
|
||||
fileName = ((SoVRMLImageTexture*)soNode)->url.getNum() >= 1 ?
|
||||
@@ -733,7 +750,7 @@ ConvertFromInventor::convertIVTexToOSGTex(const SoNode* soNode,
|
||||
}
|
||||
|
||||
// Set texture wrap mode
|
||||
#ifdef COIN_BASIC_H
|
||||
#ifdef __COIN__
|
||||
if (soNode->isOfType(SoVRMLImageTexture::getClassTypeId())) {
|
||||
// It looks like there is a high probability of bug in Coin (investigated on version 2.4.6).
|
||||
// action->getTextureWrap() returns correct value on SoTexture2 (SoTexture2::CLAMP = 0x2900,
|
||||
|
||||
1857
src/osgPlugins/Inventor/ConvertToInventor.cpp
Normal file
1857
src/osgPlugins/Inventor/ConvertToInventor.cpp
Normal file
File diff suppressed because it is too large
Load Diff
138
src/osgPlugins/Inventor/ConvertToInventor.h
Normal file
138
src/osgPlugins/Inventor/ConvertToInventor.h
Normal file
@@ -0,0 +1,138 @@
|
||||
#ifndef OSG_CONVERT_TO_INVENTOR_H
|
||||
#define OSG_CONVERT_TO_INVENTOR_H
|
||||
//
|
||||
// ConvertToInventor converts OSG scene graph to Inventor or VRML 1 scene graph
|
||||
//
|
||||
// It requires OSG and Inventor compatible library, such as Coin,
|
||||
// SGI Inventor , or TGS Inventor.
|
||||
//
|
||||
//
|
||||
// Autor: PCJohn (peciva _at fit.vutbr.cz)
|
||||
//
|
||||
// License: public domain
|
||||
//
|
||||
//
|
||||
// THIS SOFTWARE IS NOT COPYRIGHTED
|
||||
//
|
||||
// This source code is offered for use in the public domain.
|
||||
// You may use, modify or distribute it freely.
|
||||
//
|
||||
// This source code is distributed in the hope that it will be useful but
|
||||
// WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
|
||||
// DISCLAIMED. This includes but is not limited to warranties of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// If you find the source code useful, authors will kindly welcome
|
||||
// if you give them credit and keep their names with their source code,
|
||||
// but you are not forced to do so.
|
||||
//
|
||||
|
||||
#include <stack>
|
||||
#include <osg/CullFace>
|
||||
#include <osg/FrontFace>
|
||||
|
||||
class SoSeparator;
|
||||
|
||||
namespace osg {
|
||||
class BlendFunc;
|
||||
class CullFace;
|
||||
class FrontFace;
|
||||
class Material;
|
||||
class ShapeDrawable;
|
||||
class TexEnv;
|
||||
class TexGen;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class ConvertToInventor : public osg::NodeVisitor
|
||||
{
|
||||
public:
|
||||
ConvertToInventor();
|
||||
virtual ~ConvertToInventor();
|
||||
|
||||
SoNode* getIvSceneGraph() const;
|
||||
void setVRML1Conversion(bool useVRML1) { vrml1Conversion = useVRML1; };
|
||||
|
||||
virtual void apply(osg::Node &node);
|
||||
virtual void apply(osg::Geode &node);
|
||||
virtual void apply(osg::Group &node);
|
||||
#if 0
|
||||
virtual void apply(Billboard& node) { apply((Geode&)node); }
|
||||
virtual void apply(ProxyNode& node) { apply((Group&)node); }
|
||||
virtual void apply(Projection& node) { apply((Group&)node); }
|
||||
virtual void apply(CoordinateSystemNode& node) { apply((Group&)node); }
|
||||
|
||||
virtual void apply(ClipNode& node) { apply((Group&)node); }
|
||||
virtual void apply(TexGenNode& node) { apply((Group&)node); }
|
||||
virtual void apply(LightSource& node) { apply((Group&)node); }
|
||||
#endif
|
||||
//virtual void apply(Transform& node);
|
||||
//virtual void apply(Camera& node) { apply((Transform&)node); }
|
||||
//virtual void apply(CameraView& node) { apply((Transform&)node); }
|
||||
virtual void apply(osg::MatrixTransform& node);
|
||||
virtual void apply(osg::PositionAttitudeTransform& node);
|
||||
#if 0
|
||||
virtual void apply(Switch& node) { apply((Group&)node); }
|
||||
virtual void apply(Sequence& node) { apply((Group&)node); }
|
||||
virtual void apply(LOD& node) { apply((Group&)node); }
|
||||
virtual void apply(PagedLOD& node) { apply((LOD&)node); }
|
||||
virtual void apply(ClearNode& node) { apply((Group&)node); }
|
||||
virtual void apply(OccluderNode& node) { apply((Group&)node); }
|
||||
#endif
|
||||
|
||||
protected:
|
||||
bool vrml1Conversion;
|
||||
bool useIvExtensions;
|
||||
SoSeparator *ivRoot;
|
||||
|
||||
typedef struct InventorState {
|
||||
class SoSeparator *ivSeparator;
|
||||
class SoTexture2 *ivTexture;
|
||||
class SoNode *ivMaterial;
|
||||
const osg::Material *osgMaterial;
|
||||
bool osgTexture2Enabled;
|
||||
const osg::Texture *osgTexture;
|
||||
const osg::TexEnv *osgTexEnv;
|
||||
bool osgTexGenS, osgTexGenT;
|
||||
const osg::TexGen *osgTexGen;
|
||||
bool osgLighting;
|
||||
bool osgTwoSided;
|
||||
osg::FrontFace::Mode osgFrontFace;
|
||||
bool osgCullFaceEnabled;
|
||||
osg::CullFace::Mode osgCullFace;
|
||||
bool osgBlendEnabled;
|
||||
const osg::BlendFunc *osgBlendFunc;
|
||||
|
||||
InventorState() {}
|
||||
InventorState(SoSeparator *separator) : ivSeparator(separator), ivTexture(NULL),
|
||||
ivMaterial(NULL), osgMaterial(NULL),
|
||||
osgTexture2Enabled(false), osgTexture(NULL), osgTexEnv(NULL),
|
||||
osgTexGenS(false), osgTexGenT(false), osgTexGen(NULL),
|
||||
osgLighting(true), osgTwoSided(false), osgFrontFace(osg::FrontFace::COUNTER_CLOCKWISE),
|
||||
osgCullFaceEnabled(false), osgCullFace(osg::CullFace::BACK),
|
||||
osgBlendEnabled(false), osgBlendFunc(NULL) {}
|
||||
InventorState(const InventorState &s) : ivSeparator(s.ivSeparator), ivTexture(s.ivTexture),
|
||||
ivMaterial(s.ivMaterial), osgMaterial(s.osgMaterial),
|
||||
osgTexture2Enabled(s.osgTexture2Enabled), osgTexture(s.osgTexture), osgTexEnv(s.osgTexEnv),
|
||||
osgTexGenS(s.osgTexGenS), osgTexGenT(s.osgTexGenT), osgTexGen(osgTexGen),
|
||||
osgLighting(s.osgLighting), osgTwoSided(s.osgTwoSided), osgFrontFace(s.osgFrontFace),
|
||||
osgCullFaceEnabled(s.osgCullFaceEnabled), osgCullFace(s.osgCullFace),
|
||||
osgBlendEnabled(s.osgBlendEnabled), osgBlendFunc(s.osgBlendFunc) {}
|
||||
static InventorState createTopLevelState(SoSeparator *ivRoot) { return InventorState(ivRoot); }
|
||||
};
|
||||
std::stack<InventorState> ivStack;
|
||||
|
||||
typedef std::map<const class osg::TexEnv*, class SoTexture2*> Env2ivTexMap;
|
||||
std::map<const osg::Texture*, Env2ivTexMap> ivTexturesMap;
|
||||
int uniqueIdGenerator;
|
||||
|
||||
void processGeometry(const osg::Geometry *g, InventorState *ivState);
|
||||
void processShapeDrawable(const osg::ShapeDrawable *d, InventorState *ivState);
|
||||
|
||||
virtual InventorState* createInventorState(const osg::StateSet *ss);
|
||||
virtual void popInventorState();
|
||||
};
|
||||
|
||||
|
||||
#endif /* OSG_CONVERT_TO_INVENTOR_H */
|
||||
@@ -1,17 +1,27 @@
|
||||
########################################################
|
||||
# #
|
||||
# Inventor plugin #
|
||||
# Supported file formats (import only): #
|
||||
# #
|
||||
# Supported import formats: #
|
||||
# - iv (ascii, binary) file format #
|
||||
# - vrml 1.0 #
|
||||
# - vrml 2.0 (when using Coin) #
|
||||
# - VRML 1.0 #
|
||||
# - VRML 2.0 (when using Coin) #
|
||||
# #
|
||||
# Supported export formats: #
|
||||
# - iv format #
|
||||
# - VRML 1.0 #
|
||||
# #
|
||||
########################################################
|
||||
|
||||
|
||||
The plugin requires one of Inventor libraries:
|
||||
|
||||
- Coin (http://www.coin3d.org) - GPL, support of VRML 2.0
|
||||
- Coin - GPL, support of VRML 2.0
|
||||
(http://www.coin3d.org)
|
||||
- SGI Inventor - LGPL
|
||||
(http://oss.sgi.com/projects/inventor/)
|
||||
- TGS Inventor - commercial
|
||||
(http://www.tgs.com/)
|
||||
|
||||
|
||||
Contributors:
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#include <Inventor/SoInteraction.h>
|
||||
#include <Inventor/nodekits/SoNodeKit.h>
|
||||
#include <Inventor/nodes/SoSeparator.h>
|
||||
#include <Inventor/actions/SoWriteAction.h>
|
||||
#include <Inventor/actions/SoCallbackAction.h>
|
||||
|
||||
#ifdef COIN_BASIC_H
|
||||
#include <Inventor/VRMLnodes/SoVRMLImageTexture.h>
|
||||
@@ -17,6 +19,8 @@
|
||||
|
||||
#include "ConvertFromInventor.h"
|
||||
#include "GroupSoLOD.h"
|
||||
#include "ConvertToInventor.h"
|
||||
|
||||
|
||||
// Register with Registry to instantiate the inventor reader.
|
||||
REGISTER_OSGPLUGIN(Inventor, ReaderWriterIV)
|
||||
@@ -81,3 +85,46 @@ ReaderWriterIV::readNode(const std::string& file,
|
||||
return ReadResult::FILE_NOT_HANDLED;
|
||||
}
|
||||
|
||||
|
||||
osgDB::ReaderWriter::WriteResult
|
||||
ReaderWriterIV::writeNode(const osg::Node& node, const std::string& fileName,
|
||||
const osgDB::ReaderWriter::Options* options) const
|
||||
{
|
||||
// accept extension
|
||||
std::string ext = osgDB::getLowerCaseFileExtension(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();
|
||||
|
||||
// Convert OSG graph to Inventor graph
|
||||
ConvertToInventor osg2iv;
|
||||
osg2iv.setVRML1Conversion(useVRML1);
|
||||
(const_cast<osg::Node*>(&node))->accept(osg2iv);
|
||||
SoNode *ivRoot = osg2iv.getIvSceneGraph();
|
||||
if (ivRoot == NULL)
|
||||
return WriteResult::ERROR_IN_WRITING_FILE;
|
||||
ivRoot->ref();
|
||||
|
||||
// Change prefix according to VRML spec:
|
||||
// Node names must not begin with a digit, and must not contain spaces or
|
||||
// control characters, single or double quote characters, backslashes, curly braces,
|
||||
// the sharp (#) character, the plus (+) character or the period character.
|
||||
if (useVRML1)
|
||||
SoBase::setInstancePrefix("_");
|
||||
|
||||
// Write Inventor graph to file
|
||||
SoOutput out;
|
||||
out.setHeaderString((useVRML1) ? "#VRML V1.0 ascii" : "#Inventor V2.1 ascii");
|
||||
if (!out.openFile(fileName.c_str()))
|
||||
return WriteResult::ERROR_IN_WRITING_FILE;
|
||||
SoWriteAction wa(&out);
|
||||
wa.apply(ivRoot);
|
||||
ivRoot->unref();
|
||||
|
||||
return WriteResult::FILE_SAVED;
|
||||
}
|
||||
|
||||
@@ -11,18 +11,25 @@ class ReaderWriterIV : public osgDB::ReaderWriter
|
||||
|
||||
virtual const char* className() const
|
||||
{
|
||||
return "Inventor Reader";
|
||||
return "Inventor reader/writer";
|
||||
}
|
||||
|
||||
bool isInventorExtension(const std::string& extension) const
|
||||
{
|
||||
return osgDB::equalCaseInsensitive(extension, "iv") ? true : false;
|
||||
}
|
||||
|
||||
virtual bool acceptsExtension(const std::string& extension) const
|
||||
{
|
||||
return osgDB::equalCaseInsensitive(extension, "iv") ? true :
|
||||
return isInventorExtension(extension) ? true :
|
||||
osgDB::equalCaseInsensitive(extension, "wrl") ? true : false;
|
||||
}
|
||||
|
||||
virtual ReadResult readNode(const std::string& filename,
|
||||
const osgDB::ReaderWriter::Options *) const;
|
||||
|
||||
virtual WriteResult writeNode(const osg::Node& node, const std::string& filename,
|
||||
const osgDB::ReaderWriter::Options* options = NULL) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user