📄 convertfrominventor.cpp
字号:
#include "ConvertFromInventor.h"#include "PendulumCallback.h"#include "ShuttleCallback.h"// OSG headers#include <osg/MatrixTransform>#include <osg/Node>#include <osg/Geode>#include <osg/Notify>#include <osg/LineWidth>#include <osg/Point>#include <osg/TexEnv>#include <osg/Texture2D>#include <osg/PolygonMode>#include <osg/BlendFunc>#include <osg/Material>#include <osg/CullFace>#include <osg/LightModel>#include <osg/LightSource>#include <osg/ShadeModel>#include <osg/LOD>#include <osgUtil/TransformCallback>// Inventor headers#include <Inventor/SoDB.h>#include <Inventor/SoInteraction.h>#include <Inventor/nodes/SoSeparator.h>#include <Inventor/nodes/SoShape.h>#include <Inventor/nodes/SoVertexShape.h>#include <Inventor/nodes/SoLight.h>#include <Inventor/nodes/SoDirectionalLight.h>#include <Inventor/nodes/SoSpotLight.h>#include <Inventor/nodes/SoPointLight.h>#include <Inventor/nodes/SoRotor.h>#include <Inventor/nodes/SoPendulum.h>#include <Inventor/nodes/SoShuttle.h>#include <Inventor/nodes/SoLOD.h>#include <Inventor/nodes/SoTexture2.h>#include <Inventor/misc/SoChildList.h>#include <Inventor/SoPrimitiveVertex.h>#include <Inventor/SbLinear.h>#include <Inventor/nodes/SoTransform.h>#include <Inventor/nodes/SoInfo.h>#ifdef __COIN__#include <Inventor/VRMLnodes/SoVRMLImageTexture.h>#include <Inventor/VRMLnodes/SoVRMLTransform.h>#include <Inventor/VRMLnodes/SoVRMLAppearance.h>#include <Inventor/VRMLnodes/SoVRMLMaterial.h>#endif#include "GroupSoLOD.h"#include <map>#include <assert.h>#include <math.h>#include <string.h>#ifdef __linux#include <values.h>#endif#ifdef __APPLE__#include <float.h>#endif#define DEBUG_IV_PLUGIN///////////////////////////////////////////ConvertFromInventor::ConvertFromInventor(){ numPrimitives = 0; transformInfoName = ""; appearanceName = ""; inAppearanceWithNoTexture = false; lightGroup = NULL;}///////////////////////////////////////////ConvertFromInventor::~ConvertFromInventor(){}///////////////////////////////////////////////////////////osg::Node* ConvertFromInventor::convert(SoNode* rootIVNode){ // Transformation matrix for converting Inventor coordinate system to OSG // coordinate system osg::Matrix ivToOSGMat(osg::Matrix(1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,-1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0)); // Create a root node and push it onto the stack _root = new osg::MatrixTransform; _root->setMatrix(ivToOSGMat); groupStack.push(_root.get()); // Push an empty list of light and push it onto the light stack LightList lightList; lightStack.push(lightList); // Create callback actions for the inventor nodes // These callback functions perform the conversion // note: if one class is derived from the other and both callbacks // are registered, both functions will be called SoCallbackAction cbAction; cbAction.addPreCallback(SoShape::getClassTypeId(), preShape, this); cbAction.addPostCallback(SoShape::getClassTypeId(), postShape, this); cbAction.addPreCallback(SoGroup::getClassTypeId(), preGroup, this); cbAction.addPostCallback(SoGroup::getClassTypeId(), postGroup, this); cbAction.addPreCallback(SoTexture2::getClassTypeId(), preTexture, this);#ifdef __COIN__ cbAction.addPreCallback(SoVRMLImageTexture::getClassTypeId(), preVRMLImageTexture, this); cbAction.addPreCallback(SoVRMLAppearance::getClassTypeId(), preVRMLAppearance, this); cbAction.addPreCallback(SoInfo::getClassTypeId(), preInfo, this);#endif cbAction.addPreCallback(SoLight::getClassTypeId(), preLight, this); cbAction.addPreCallback(SoRotor::getClassTypeId(), preRotor, this); cbAction.addPreCallback(SoPendulum::getClassTypeId(), prePendulum, this); cbAction.addPreCallback(SoShuttle::getClassTypeId(), preShuttle, this); cbAction.addTriangleCallback(SoShape::getClassTypeId(), addTriangleCB, this); cbAction.addLineSegmentCallback(SoShape::getClassTypeId(), addLineSegmentCB, this); cbAction.addPointCallback(SoShape::getClassTypeId(), addPointCB, this); // Traverse the inventor scene graph cbAction.apply(rootIVNode); // Pop all the groups that are Transforms // Verify that the last transform is _root . assert(groupStack.size() > 0 && "groupStack underflow."); osg::ref_ptr<osg::Group> group = groupStack.top(); while (strcmp(group->className(), "MatrixTransform") == 0) { groupStack.pop(); if (groupStack.empty()) break; group = groupStack.top(); } assert(group.get() == _root.get() && "groupStack error"); assert(groupStack.size() == 0 && "groupStack is not empty after traversal."); assert(soTexStack.size() == 0 && "soTexStack was left at inconsistent state."); assert(lightStack.size() == 1 && "lightStack was left at inconsistent state."); lightStack.pop(); return _root.get(); }///////////////////////////////////////////////////////////////////SoCallbackAction::Response ConvertFromInventor::preShape(void* data, SoCallbackAction* action, const SoNode* node){#ifdef DEBUG_IV_PLUGIN osg::notify(osg::INFO) << "preShape() " << node->getTypeId().getName().getString() << std::endl;#endif ConvertFromInventor* thisPtr = (ConvertFromInventor *) (data); // Normal and color binding map from Inventor to OSG static std::map<SoNormalBinding::Binding, osg::Geometry::AttributeBinding> normBindingMap; static std::map<SoMaterialBinding::Binding, osg::Geometry::AttributeBinding> colBindingMap; static bool firstTime = true; if (firstTime) { normBindingMap[SoNormalBinding::OVERALL] = osg::Geometry::BIND_OVERALL; normBindingMap[SoNormalBinding::PER_PART] = osg::Geometry::BIND_PER_PRIMITIVE; normBindingMap[SoNormalBinding::PER_PART_INDEXED] = osg::Geometry::BIND_PER_PRIMITIVE; normBindingMap[SoNormalBinding::PER_FACE] = osg::Geometry::BIND_PER_PRIMITIVE; normBindingMap[SoNormalBinding::PER_FACE_INDEXED] = osg::Geometry::BIND_PER_PRIMITIVE; normBindingMap[SoNormalBinding::PER_VERTEX] = osg::Geometry::BIND_PER_VERTEX; normBindingMap[SoNormalBinding::PER_VERTEX_INDEXED] = osg::Geometry::BIND_PER_VERTEX; colBindingMap[SoMaterialBinding::OVERALL] = osg::Geometry::BIND_OVERALL; colBindingMap[SoMaterialBinding::PER_PART] = osg::Geometry::BIND_PER_PRIMITIVE; colBindingMap[SoMaterialBinding::PER_PART_INDEXED] = osg::Geometry::BIND_PER_PRIMITIVE; colBindingMap[SoMaterialBinding::PER_FACE] = osg::Geometry::BIND_PER_PRIMITIVE; colBindingMap[SoMaterialBinding::PER_FACE_INDEXED] = osg::Geometry::BIND_PER_PRIMITIVE; colBindingMap[SoMaterialBinding::PER_VERTEX] = osg::Geometry::BIND_PER_VERTEX; colBindingMap[SoMaterialBinding::PER_VERTEX_INDEXED] = osg::Geometry::BIND_PER_VERTEX; firstTime = false; } // Get normal and color binding if (node->isOfType(SoVertexShape::getClassTypeId())) { thisPtr->normalBinding = normBindingMap[action->getNormalBinding()]; thisPtr->colorBinding = colBindingMap[action->getMaterialBinding()]; } else { thisPtr->normalBinding = osg::Geometry::BIND_PER_VERTEX; thisPtr->colorBinding = osg::Geometry::BIND_PER_VERTEX; } // Check vertex ordering if (action->getVertexOrdering() == SoShapeHints::CLOCKWISE) thisPtr->vertexOrder = CLOCKWISE; else thisPtr->vertexOrder = COUNTER_CLOCKWISE; // Clear the data from the previous shape callback thisPtr->numPrimitives = 0; thisPtr->vertices.clear(); thisPtr->normals.clear(); thisPtr->colors.clear(); thisPtr->textureCoords.clear(); return SoCallbackAction::CONTINUE;}///////////////////////////////////////////////////////////// OSG doesn't seem to have a transpose function ////for matrices /////////////////////////////////////////////////////////////void ConvertFromInventor::transposeMatrix(osg::Matrix& mat){ float tmp; for (int j = 0; j < 4; j++) { for (int i = j + 1; i < 4; i++) { tmp = mat.operator()(j,i); mat.operator()(j,i) = mat.operator()(i,j); mat.operator()(i,j) = tmp; } }}////////////////////////////////////////////////////////////////////SoCallbackAction::Response ConvertFromInventor::postShape(void* data, SoCallbackAction* action, const SoNode* node){#ifdef DEBUG_IV_PLUGIN osg::notify(osg::INFO) << "postShape() " << node->getTypeId().getName().getString() << std::endl;#endif ConvertFromInventor* thisPtr = (ConvertFromInventor *) (data); // Create a new Geometry osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry; osg::ref_ptr<osg::Vec3Array> coords = new osg::Vec3Array(thisPtr->vertices.size()); for (unsigned int i = 0; i < thisPtr->vertices.size(); i++) (*coords)[i] = thisPtr->vertices[i]; geometry->setVertexArray(coords.get()); osg::ref_ptr<osg::Vec3Array> norms = NULL; if (thisPtr->normalBinding == osg::Geometry::BIND_OVERALL) { norms = new osg::Vec3Array(1); const SbVec3f &norm = action->getNormal(0); (*norms)[0].set(norm[0], norm[1], norm[2]); } else { norms = new osg::Vec3Array(thisPtr->normals.size()); for (unsigned int i = 0; i < thisPtr->normals.size(); i++) { (*norms)[i] = thisPtr->normals[i]; } } geometry->setNormalArray(norms.get()); geometry->setNormalBinding(thisPtr->normalBinding); // Set the colors osg::ref_ptr<osg::Vec4Array> cols; if (thisPtr->colorBinding == osg::Geometry::BIND_OVERALL) { cols = new osg::Vec4Array(1); SbColor ambient, diffuse, specular, emission; float transparency, shininess; action->getMaterial(ambient, diffuse, specular, emission, shininess, transparency, 0); (*cols)[0].set(diffuse[0], diffuse[1], diffuse[2], 1.0 - transparency); } else { cols = new osg::Vec4Array(thisPtr->colors.size()); for (unsigned int i = 0; i < thisPtr->colors.size(); i++) (*cols)[i] = thisPtr->colors[i]; } geometry->setColorArray(cols.get()); geometry->setColorBinding(thisPtr->colorBinding); if (thisPtr->textureCoords.empty()) osg::notify(osg::INFO)<<"tex coords not found"<<std::endl; else { // report texture coordinate conditions if (action->getNumTextureCoordinates()>0) osg::notify(osg::INFO)<<"tex coords found"<<std::endl; else osg::notify(osg::INFO)<<"tex coords generated"<<std::endl; // Get the texture transformation matrix osg::Matrix textureMat;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -