diff --git a/CMakeLists.txt b/CMakeLists.txt index 2ef7822ff..326caa5e7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -721,6 +721,7 @@ ELSE() FIND_PACKAGE(Inventor) FIND_PACKAGE(Jasper) FIND_PACKAGE(OpenEXR) + FIND_PACKAGE(OpenCascade) FIND_PACKAGE(COLLADA) FIND_PACKAGE(FBX) FIND_PACKAGE(ZLIB) diff --git a/CMakeModules/FindOpenCascade.cmake b/CMakeModules/FindOpenCascade.cmake new file mode 100644 index 000000000..4b8407fcd --- /dev/null +++ b/CMakeModules/FindOpenCascade.cmake @@ -0,0 +1,106 @@ +# LocateOPENCASCADE +# This module defines +# OPENCASCADE_LIBRARY +# OPENCASCADE_FOUND, if false, do not try to link to OPENCASCADE +# OPENCASCADE_INCLUDE_DIR, where to find the headers +# +# $OPENCASCADE_DIR is an environment variable that would +# correspond to the ./configure --prefix=$OPENCASCADE_DIR +# used in building OPENCASCADE. + +FIND_PATH(OPENCASCADE_INCLUDE_DIR BRepMesh.hxx + PATHS + ${OPENCASCADE_DIR} + $ENV{OPENCASCADE_DIR} + ~/Library/Frameworks + /Library/Frameworks + /usr/local + /usr + /sw # Fink + /opt/local # DarwinPorts + /opt/csw # Blastwave + /opt + /usr/freeware + PATH_SUFFIXES + opencascade + inc + include + inc/cascade + include/cascade +) + +MACRO(FIND_OPENCASCADE_LIBRARY MYLIBRARY MYLIBRARYNAME) + + FIND_LIBRARY("${MYLIBRARY}" + NAMES "${MYLIBRARYNAME}" + PATHS + $ENV{OPENCASCADE_DIR}/lib} + $ENV{OPENCASCADE_LIB} + ${OPENCASCADE_DIR}/lib + $ENV{OPENCASCADE_DIR}/lib + ${OPENCASCADE_DIR}/lib/ + ~/Library/Frameworks + /Library/Frameworks + /usr/local/lib + /usr/lib + /sw/lib + /opt/local/lib + /opt/csw/lib + /opt/lib + /usr/freeware/lib64 + ) + + +ENDMACRO(FIND_OPENCASCADE_LIBRARY LIBRARY LIBRARYNAME) + +# Find release (optimized) libs +FIND_OPENCASCADE_LIBRARY(OPENCASCADE_TKVRML_LIBRARY TKVrml) +FIND_OPENCASCADE_LIBRARY(OPENCASCADE_TKSTL_LIBRARY TKStl) +FIND_OPENCASCADE_LIBRARY(OPENCASCADE_TKBREP_LIBRARY TKBRep) +FIND_OPENCASCADE_LIBRARY(OPENCASCADE_TKIGES_LIBRARY TKIGES) +FIND_OPENCASCADE_LIBRARY(OPENCASCADE_TKSHHEALING_LIBRARY TKShHealing) +FIND_OPENCASCADE_LIBRARY(OPENCASCADE_TKSTEP_LIBRARY TKSTEP) +FIND_OPENCASCADE_LIBRARY(OPENCASCADE_TKSTEP209_LIBRARY TKSTEP209) +FIND_OPENCASCADE_LIBRARY(OPENCASCADE_TKSTEPATTR_LIBRARY TKSTEPAttr) +FIND_OPENCASCADE_LIBRARY(OPENCASCADE_TKSTEPBASE_LIBRARY TKSTEPBase) +FIND_OPENCASCADE_LIBRARY(OPENCASCADE_TKXSBASE_LIBRARY TKXSBase) +FIND_OPENCASCADE_LIBRARY(OPENCASCADE_TKSHAPESCHEMA_LIBRARY TKShapeSchema) +FIND_OPENCASCADE_LIBRARY(OPENCASCADE_TKBO_LIBRARY TKBO) +FIND_OPENCASCADE_LIBRARY(OPENCASCADE_FWOSPLUGIN_LIBRARY FWOSPlugin) +FIND_OPENCASCADE_LIBRARY(OPENCASCADE_PTKERNEL_LIBRARY PTKernel) +FIND_OPENCASCADE_LIBRARY(OPENCASCADE_TKBOOL_LIBRARY TKBool) +FIND_OPENCASCADE_LIBRARY(OPENCASCADE_TKCAF_LIBRARY TKCAF) +FIND_OPENCASCADE_LIBRARY(OPENCASCADE_TKCDF_LIBRARY TKCDF) +FIND_OPENCASCADE_LIBRARY(OPENCASCADE_TKERNEL_LIBRARY TKernel) +FIND_OPENCASCADE_LIBRARY(OPENCASCADE_TKFEAT_LIBRARY TKFeat) +FIND_OPENCASCADE_LIBRARY(OPENCASCADE_TKFILLET_LIBRARY TKFillet) +FIND_OPENCASCADE_LIBRARY(OPENCASCADE_TKG2D_LIBRARY TKG2d) +FIND_OPENCASCADE_LIBRARY(OPENCASCADE_TKG3d_LIBRARY TKG3D) +FIND_OPENCASCADE_LIBRARY(OPENCASCADE_TKGEOMALGO_LIBRARY TKGeomAlgo) +FIND_OPENCASCADE_LIBRARY(OPENCASCADE_TKGEOMBASE_LIBRARY TKGeomBase) +FIND_OPENCASCADE_LIBRARY(OPENCASCADE_TKHLR_LIBRARY TKHLR) +FIND_OPENCASCADE_LIBRARY(OPENCASCADE_TKMATH_LIBRARY TKMath) +FIND_OPENCASCADE_LIBRARY(OPENCASCADE_TKOFFSET_LIBRARY TKOffset) +FIND_OPENCASCADE_LIBRARY(OPENCASCADE_TKPCAF_LIBRARY TKPCAF) +FIND_OPENCASCADE_LIBRARY(OPENCASCADE_TKPRIM_LIBRARY TKPrim) +FIND_OPENCASCADE_LIBRARY(OPENCASCADE_TKPSHAPE_LIBRARY TKPShape) +FIND_OPENCASCADE_LIBRARY(OPENCASCADE_TKSERVICE_LIBRARY TKService) +FIND_OPENCASCADE_LIBRARY(OPENCASCADE_TKTOPALGO_LIBRARY TKTopAlgo) +FIND_OPENCASCADE_LIBRARY(OPENCASCADE_TKMESH_LIBRARY TKMesh) +FIND_OPENCASCADE_LIBRARY(OPENCASCADE_TKV3D_LIBRARY TKV3d) +FIND_OPENCASCADE_LIBRARY(OPENCASCADE_TKXCAF_LIBRARY TKXCAF) +FIND_OPENCASCADE_LIBRARY(OPENCASCADE_TKXDEIGES_LIBRARY TKXDEIGES) +FIND_OPENCASCADE_LIBRARY(OPENCASCADE_TKXLCAF_LIBRARY TKXLCAF) +FIND_OPENCASCADE_LIBRARY(OPENCASCADE_TKLCAF_LIBRARY TKLCAF) + + +SET(OPENCASCADE_LIBRARY ${OPENCASCADE_TKMESH_LIBRARY}) + +SET(OPENCASCADE_FOUND "NO") +IF(OPENCASCADE_LIBRARY AND OPENCASCADE_INCLUDE_DIR) + SET(OPENCASCADE_FOUND "YES") +ENDIF(OPENCASCADE_LIBRARY AND OPENCASCADE_INCLUDE_DIR) + +IF(OPENCASCADE_INCLUDE_DIR) + SET(OPENCASCADE_FOUND "YES") +ENDIF(OPENCASCADE_INCLUDE_DIR) diff --git a/src/osgPlugins/CMakeLists.txt b/src/osgPlugins/CMakeLists.txt index 36d1d17e1..2ee6b37b1 100644 --- a/src/osgPlugins/CMakeLists.txt +++ b/src/osgPlugins/CMakeLists.txt @@ -153,6 +153,10 @@ IF(FBX_FOUND AND OSG_CPP_EXCEPTIONS_AVAILABLE) ADD_SUBDIRECTORY(fbx) ENDIF() +IF(OPENCASCADE_FOUND) + ADD_SUBDIRECTORY(iges) +ENDIF() + ADD_SUBDIRECTORY(bvh) ADD_SUBDIRECTORY(x) ADD_SUBDIRECTORY(dxf) diff --git a/src/osgPlugins/iges/CMakeLists.txt b/src/osgPlugins/iges/CMakeLists.txt new file mode 100644 index 000000000..3501104f1 --- /dev/null +++ b/src/osgPlugins/iges/CMakeLists.txt @@ -0,0 +1,17 @@ +INCLUDE_DIRECTORIES(${OPENCASCADE_INCLUDE_DIR}) + +SET(TARGET_SRC + ReaderWriterIGES.cpp +) + +SET(TARGET_H + ReaderWriterIGES.h +) + +SET(TARGET_LIBRARIES_VARS OPENCASCADE_LIBRARY) + +# requires CMake 3.1 to do the following: +set (CMAKE_CXX_STANDARD 11) + +#### end var setup ### +SETUP_PLUGIN(iges) diff --git a/src/osgPlugins/iges/ReaderWriterIGES.cpp b/src/osgPlugins/iges/ReaderWriterIGES.cpp new file mode 100644 index 000000000..1826be715 --- /dev/null +++ b/src/osgPlugins/iges/ReaderWriterIGES.cpp @@ -0,0 +1,397 @@ +/**************************************************************************** + * + * + * Copyright 2010-2013, VizExpertsIndia Pvt. Ltd. (unpublished) + * + * All rights reserved. This notice is intended as a precaution against + * inadvertent publication and does not imply publication or any waiver + * of confidentiality. The year included in the foregoing notice is the + * year of creation of the work. No part of this work may be used, + * reproduced, or transmitted in any form or by any means without the prior + * written permission of Vizexperts India Pvt Ltd. + * + * + *************************************************************************** + */ + +/// \file ReaderWriterIGES.cpp +/// \brief implementation file for osgdb plugin for IGES format +/// contains implementation of ReaderWriterIGES class +/// \author Abhishek Bansal + +#include "ReaderWriterIGES.h" + +#include + +// OpenCascade Headers +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include + +#include +#include + +// osg headers +#include +#include + +#include +#include + +//#define _LOG_DEBUG_ + +namespace IGES +{ + REGISTER_OSGPLUGIN(iges, ReaderWriterIGES) + + osgDB::ReaderWriter::ReadResult ReaderWriterIGES::readNode(const std::string& fileName, const osgDB::ReaderWriter::Options* options) const + { + // some error handling + std::string ext = osgDB::getLowerCaseFileExtension(fileName); + if (!acceptsExtension(ext)) + return ReadResult::FILE_NOT_HANDLED; + + std::string file = osgDB::findDataFile(fileName, options); + if (file.empty()) + return ReadResult::FILE_NOT_FOUND; + + OSG_INFO << "ReaderWriterIGES::readNode(" << file.c_str() << ")\n"; + + IGESReader reader; + return reader.igesToOSGGeode(fileName); + } + + osgDB::ReaderWriter::WriteResult ReaderWriterIGES::writeNode(const osg::Node& /*node*/,const std::string& fileName /*fileName*/,const Options*) const + { + // some error handling + std::string ext = osgDB::getLowerCaseFileExtension(fileName); + if (!acceptsExtension(ext)) + return WriteResult::FILE_NOT_HANDLED; + + std::cout << "File Writing not supported yet" << std::endl; + return WriteResult::FILE_NOT_HANDLED; + } + + /// \brief heals a opencascade shape + /// \detail http://www.opencascade.org/org/forum/thread_12716/?forum=3 + /// Usually IGES files suffer from precision problems (when transfering from + /// one CAD system to another).It might be the case that faces are not sewed + /// properly, or do not have the right precision, and so the tesselator does + /// not treat them like "sewed". this needs to be done for sewing + /// \param shape opencascade shape to be healed + void ReaderWriterIGES::IGESReader::_healShape(TopoDS_Shape& shape) + { + #ifdef _LOG_DEBUG_ + std::cout << std::endl << "Going to heal shape!!"; + #endif + + ShapeFix_Shape fixer(shape); + fixer.Perform(); + shape = fixer.Shape(); + + BRepBuilderAPI_Sewing sew; + sew.Add(shape); + sew.Perform(); + shape = sew.SewedShape(); + } + + /// \brief takes and OpenCascadeShape and returns OSG geometry(drawable), which further can be added to a geode + /// \detail it iterates shape and breaks it into faces, builds vertex list, color list and creates geometry + /// transformation is applied to each vertex before storing it into vertex list + /// all vertices are assigned same color + /// \param shape shape to be converted in geometry. Not a const because it needs to be modified if healing + /// is enabled + /// \param color color of geometry + /// \param transformation matrix with which vertex position has to be transformed + osg::ref_ptr ReaderWriterIGES::IGESReader::_createGeometryFromShape(TopoDS_Shape& shape, const osg::Vec3& geomColor, gp_Trsf& transformation) + { + // vector to save vertices + osg::ref_ptr vertexList = new osg::Vec3Array(); + // vector to save _colorTool + osg::ref_ptr colorList = new osg::Vec3Array(); + + // create one osg primitive set + osg::ref_ptr triangleStrip = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0); + unsigned int noOfTriangles = 0; + + osg::ref_ptr geom = new osg::Geometry; + if(!shape.IsNull()) + { + // clean any previous triangulation + BRepTools::Clean(shape); + + //_healShape(shape); + + #ifdef _LOG_DEBUG_ + std::cout << std::endl << "Building a Mesh !!" ; + #endif + + /// call to incremental mesh on this shape + /// \todo not sure why this 1 is passed. Its called deflection BTW + /// need to find a way to calculate it + double linearDeflection = 1.0; + BRepMesh_IncrementalMesh(shape, linearDeflection); + + ///iterate faces + // this variable will help in keeping track of face indices + unsigned int index = 0; + for (TopExp_Explorer ex(shape, TopAbs_FACE); ex.More(); ex.Next()) + { + TopoDS_Face face = TopoDS::Face(ex.Current()); + TopLoc_Location location; + + /// triangulate current face + Handle (Poly_Triangulation) triangulation = BRep_Tool::Triangulation(face, location); + if (!triangulation.IsNull()) + { + int noOfNodes = triangulation->NbNodes(); + + // Store vertices. Build vertex array here + for(int j = 1; j <= triangulation->NbNodes(); j++) + { + // populate vertex list + // Ref: http://www.opencascade.org/org/forum/thread_16694/?forum=3 + gp_Pnt pt = (triangulation->Nodes())(j).Transformed(transformation * location.Transformation()); + vertexList->push_back(osg::Vec3(pt.X(), pt.Y(), pt.Z())); + + // populate color list + colorList->push_back(geomColor); + } + + /// now we need to get face indices for triangles + // get list of triangle first + const Poly_Array1OfTriangle& triangles = triangulation->Triangles(); + + //No of triangles in this triangulation + noOfTriangles = triangulation->NbTriangles(); + + Standard_Integer v1, v2, v3; + for (unsigned int j = 1; j <= noOfTriangles; j++) + { + /// If face direction is reversed then we add verticews in reverse order + /// order of vertices is important for normal calculation later + if (face.Orientation() == TopAbs_REVERSED) + { + triangles(j).Get(v1, v3, v2); + } + else + { + triangles(j).Get(v1, v2, v3); + } + triangleStrip->push_back(index + v1 - 1); + triangleStrip->push_back(index + v2 - 1); + triangleStrip->push_back(index + v3 - 1); + } + index = index + noOfNodes; + } + } + + #ifdef _LOG_DEBUG_ + std::cout << "Creating a geometry.." << std::endl; + #endif + + geom->setVertexArray(vertexList.get()); + + geom->setColorArray(colorList.get()); + geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX); + + #ifdef _LOG_DEBUG_ + std::cout << "Adding Primitive set" << std::endl; + #endif + + geom->addPrimitiveSet(triangleStrip); + } + + return geom; + } + + /// \brief this function is single point of contact for this class. + /// it takes path of IGES file and returns an OpenSceneGraph Geode + /// which directly can be used anywhere. It calculates normals using osgUtil::smoother + osg::ref_ptr ReaderWriterIGES::IGESReader::igesToOSGGeode(const std::string& filePath) + { + // XDE: Extended Data Exchange + // OCAF: OpenCascade Application Technology Framework + /// Getting an XDE document + Handle(TDocStd_Document) doc; + XCAFApp_Application::GetApplication()->NewDocument("MDTV-XCAF", doc); + + IGESCAFControl_Reader reader; + reader.SetColorMode(true); + reader.SetNameMode(true); + reader.SetLayerMode(true); + + //IGESControl_Reader Reader; + reader.ReadFile( (Standard_CString)filePath.c_str() ); + /// transfer data from reader to doc + if(!reader.Transfer(doc)) + { + cout << "Cannot read any relevant data from the IGES file" << endl; + return NULL; + } + + // To get a node considered as an Assembly from an XDE structure, you can use the Label of the node. + _assembly = XCAFDoc_DocumentTool::ShapeTool(doc->Main()); + + // To query, edit, or initialize a Document to handle Colors of XCAF + _colorTool = XCAFDoc_DocumentTool::ColorTool(doc->Main()); + + // free shape sequence + // get sequence of free shape lables + TDF_LabelSequence freeShapes; + _assembly->GetFreeShapes(freeShapes); + + if(freeShapes.Length() == 0) + { + std::cout << "No Shapes found" << endl; + return NULL; + } + else + { + std::cout << std::endl << "No of Free Shapes: " << freeShapes.Length(); + } + + _modelGeode = new osg::Geode(); + /// send all root nodes for recursive traversing + /// find transformation as it will be needed for location calculation later + for (int i = 1; i <= freeShapes.Length(); i++) + { + Handle(XCAFDoc_Location) attribute; + gp_Trsf transformation; + freeShapes.Value(i).FindAttribute(XCAFDoc_Location::GetID(), attribute); + if(attribute.IsNull() == Standard_False) + { + TopLoc_Location location = attribute->Get(); + transformation = location.Transformation(); + } + _traverse(freeShapes.Value(i), transformation); + } + + /// calculate normals + #ifdef _LOG_DEBUG_ + std::cout << "Calculating Normals" << std::endl; + #endif + + osgUtil::SmoothingVisitor sv; + _modelGeode->accept(sv); + + return _modelGeode; + } + + /// \brief recursively traverse opencascade assembly structure and build a osg geode + /// this function also finds color for leaf node shapes and calculates transformation from parent + /// to leaf + /// \param shapeTree its a OCT(OpenCascade Technology) XDE document label which might contain children or referred shapes + /// \param transformation contains transformation matrix to be applied + /// \note Simple Shape: is a shape which is not a compound. Its can be a free or non free shape + /// \note Support Thread: http://www.opencascade.org/org/forum/thread_25512/?forum=3 + void ReaderWriterIGES::IGESReader::_traverse(const TDF_Label &shapeTree, gp_Trsf& transformation) + { + TDF_Label referredShape; + /// find if current shape referes some shape. if it does then traverse that + /// else it is a simple shape and do visualize that simple shape + if(_assembly->GetReferredShape(shapeTree, referredShape)) + { + Handle(XCAFDoc_Location) attribute; + referredShape.FindAttribute(XCAFDoc_Location::GetID(), attribute); + if(attribute.IsNull() == Standard_False) + { + TopLoc_Location location = attribute->Get(); + transformation *= location.Transformation(); + } + + /// if referred shape has children traverse them first else + /// travese the shape itself + if(referredShape.HasChild()) + { + TDF_ChildIterator it; + for(it.Initialize(referredShape); it.More(); it.Next()) + { + _traverse(it.Value(), transformation); + } + } + else + { + #ifdef _LOG_DEBUG_ + std::cout << std::endl << "No children found"; + #endif + _traverse(referredShape, transformation); + } + } + else + { + /// Find out if this simple shape has any color store that color as color of geometry + Quantity_Color color; + osg::Vec3 geomColor = osg::Vec3(.7, .7, .7); + if(_colorTool->GetColor(shapeTree, XCAFDoc_ColorGen, color) || + _colorTool->GetColor(shapeTree, XCAFDoc_ColorSurf, color) || + _colorTool->GetColor(shapeTree, XCAFDoc_ColorCurv, color) ) + { + #ifdef _LOG_DEBUG_ + std::cout << std::endl << "Free Shape has a color !! " << color.Red() << " " << color.Green() << " "<< color.Blue(); + #endif + geomColor = osg::Vec3(color.Red(),color.Green(), color.Blue()); + } + + TopoDS_Shape shape = _assembly->GetShape(shapeTree); + + Handle(XCAFDoc_Location) attribute; + shapeTree.FindAttribute(XCAFDoc_Location::GetID(), attribute); + if(attribute.IsNull() == Standard_False) + { + TopLoc_Location location = attribute->Get(); + transformation *= location.Transformation(); + } + + osg::ref_ptr geom = _createGeometryFromShape(shape, geomColor, transformation); + /// add this geometry to model geode + if(geom.valid()) + { + _modelGeode->addDrawable(geom); + } + else + { + std::cout << std::endl << "Invalid Geometry found !!"; + } + } + } + +} // namespace diff --git a/src/osgPlugins/iges/ReaderWriterIGES.h b/src/osgPlugins/iges/ReaderWriterIGES.h new file mode 100644 index 000000000..953e73945 --- /dev/null +++ b/src/osgPlugins/iges/ReaderWriterIGES.h @@ -0,0 +1,140 @@ +/* + * IGES importer for OpenSceneGraph. + * Copyright (c)2013 VizExperts India Pvt. Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _READERWRITERIGES_H_ +#define _READERWRITERIGES_H_ + +/// \file ReaderWriterIGES.h +/// \brief header file for creating osgdb plugin for IGES format +/// \author Abhishek Bansal, Engineer Graphics, vizExperts India Pvt. Ltd. + +/// \brief preproccessor macro required for compilation with open cascade +/// \todo not sure what it does +#define WNT + +#include + +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include + +/// \class ReaderWriterIGES +/// \brief contains implementation of reading IGES models +/// depends on OpenCascade library +/// this code was written with version 6.6.0 +/// \todo enabling/disabling Healing can be added as reader writer options + +namespace IGES +{ + class ReaderWriterIGES: public osgDB::ReaderWriter + { + public: + /// \brief constructor + ReaderWriterIGES() + { + supportsExtension("IGES","IGES file format"); + supportsExtension("iges","IGES file format"); + supportsExtension("IGS","IGS file format"); + supportsExtension("igs","IGS file format"); + } + + /// \brief returns class name + virtual const char* className() const { return "IGES Reader"; } + + virtual osgDB::ReaderWriter::ReadResult readNode(const std::string& fileName, const osgDB::ReaderWriter::Options*) const; + + virtual osgDB::ReaderWriter::WriteResult writeNode(const osg::Node&, const std::string&, const Options* =NULL) const ; + + private: + + /// \brief following class will contain all reading related functionality + /// \detail this class uses OCT XDE module to read IGES file. XDE mechanism is needed + /// to find out colors and transformation of sub shapes. + /// normal IGESReader wasn't giving very good results with shapes. Edges weren't sharp enough + /// and also there is no way in which we can get color information with that + /// \Note Go through XDE user guide and IGES User guide supplied with + /// \todo OSG automatic normal calculation is not working good for few mnodels + /// try to get from XDE document only + class IGESReader + { + public: + + /// \brief this function is single point of contact for this class. + /// it takes path of IGES file and returns an OpenSceneGraph Geode + /// which directly can be used anywhere. It calculates normals using osgUtil::smoother + osg::ref_ptr igesToOSGGeode(const std::string& filePath); + + private: + + /// \brief heals a opencascade shape + /// \detail http://www.opencascade.org/org/forum/thread_12716/?forum=3 + /// Usually IGES files suffer from precision problems (when transfering from + /// one CAD system to another).It might be the case that faces are not sewed + /// properly, or do not have the right precision, and so the tesselator does + /// not treat them like "sewed". this needs to be done for sewing + /// \param[in,out] shape opencascade shape to be healed + void _healShape(TopoDS_Shape& shape); + + /// \brief recursively traverse opencascade assembly structure and build a osg geode + /// this function also finds color for leaf node shapes and calculates transformation from parent + /// to leaf + /// \param[in] shapeTree its a OCT(OpenCascade Technology) XDE document label which might contain children or referred shapes + /// \param[in] transformation contains transformation matrix to be applied + void _traverse(const TDF_Label &shapeTree, gp_Trsf& transformation); + + + /// \brief takes and OpenCascadeShape and returns OSG geometry(drawable), which further can be added to a geode + /// \detail it iterates shape and breaks it into faces, builds vertex list, color list and creates geometry + /// transformation is applied to each vertex before storing it into vertex list + /// all vertices are assigned same color + /// \param[in] shape shape to be converted in geometry. Not a const because it needs to be modified if healing + /// is enabled + /// \param[in] color color of geometry + /// \param[in] transformation matrix with which vertex position has to be transformed + osg::ref_ptr _createGeometryFromShape(TopoDS_Shape& shape, const osg::Vec3& color, gp_Trsf& transformation); + + private: + + /// \bried XDE document color tool it stores all colors in color table + /// and used to get color from a label + Handle(XCAFDoc_ColorTool) _colorTool; + + /// \brief geode to contain full model + osg::ref_ptr _modelGeode; + + /// \brief shape tool instance to deal with shapes(simple shapes), referredShape, children etc + Handle (XCAFDoc_ShapeTool) _assembly; + }; + }; +} // namespace + +#endif // _READERWRITERIGES_H_ \ No newline at end of file