From Abhishek Bansal, with ammendemts by Robet Osfield to get working with recent OpenCascade and usng CMake.

This commit is contained in:
Robert Osfield 2016-11-30 19:11:15 +00:00
parent d4a4993285
commit a9bc508dc4
6 changed files with 665 additions and 0 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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 <iostream>
// OpenCascade Headers
#include <TopTools_HSequenceOfShape.hxx>
#include <TopExp_Explorer.hxx>
#include <Standard_ErrorHandler.hxx>
#include <Standard_CString.hxx>
#include <Standard_Macro.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Face.hxx>
#include <BRepMesh_IncrementalMesh.hxx>
#include <BRep_Tool.hxx>
#include <BRepTools.hxx>
#include <BRepGProp_Face.hxx>
#include <BRepBuilderAPI_Sewing.hxx>
#include <ShapeFix_Shape.hxx>
#include <gp_Pnt2d.hxx>
#include <TColgp_Array1OfPnt2d.hxx>
#include <Poly_Triangulation.hxx>
#include <Poly_Array1OfTriangle.hxx>
#include <IGESControl_Reader.hxx>
#include <IGESControl_Writer.hxx>
#include <IGESControl_Controller.hxx>
#include <TDocStd_Document.hxx>
#include <XCAFDoc_ColorTool.hxx>
#include <XCAFDoc_ShapeTool.hxx>
#include <XCAFDoc_Location.hxx>
#include <XCAFDoc_DocumentTool.hxx>
#include <XCAFApp_Application.hxx>
#include <IGESCAFControl_Reader.hxx>
#include <TDF_Label.hxx>
#include <TDF_LabelSequence.hxx>
#include <TDF_ChildIterator.hxx>
#include <XSDRAW.hxx>
#include <Quantity_Color.hxx>
// osg headers
#include<osg/PrimitiveSet>
#include <osg/MatrixTransform>
#include <osgUtil/TriStripVisitor>
#include <osgUtil/SmoothingVisitor>
//#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<osg::Geometry> ReaderWriterIGES::IGESReader::_createGeometryFromShape(TopoDS_Shape& shape, const osg::Vec3& geomColor, gp_Trsf& transformation)
{
// vector to save vertices
osg::ref_ptr<osg::Vec3Array> vertexList = new osg::Vec3Array();
// vector to save _colorTool
osg::ref_ptr<osg::Vec3Array> colorList = new osg::Vec3Array();
// create one osg primitive set
osg::ref_ptr<osg::DrawElementsUInt> triangleStrip = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);
unsigned int noOfTriangles = 0;
osg::ref_ptr<osg::Geometry> 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<osg::Geode> 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<osg::Geometry> 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

View File

@ -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 <TDF_LabelSequence.hxx>
#include <XCAFDoc_ColorTool.hxx>
#include <XCAFDoc_ShapeTool.hxx>
#include <TopoDS_Shape.hxx>
#include <gp_Trsf.hxx>
#include <osg/Notify>
#include <osg/Geode>
#include <osg/Geometry>
#include <osgDB/Registry>
#include <osgDB/ReadFile>
#include <osgDB/FileNameUtils>
#include <osgDB/FileUtils>
#include <osgUtil/TriStripVisitor>
/// \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<osg::Geode> 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<osg::Geometry> _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<osg::Geode> _modelGeode;
/// \brief shape tool instance to deal with shapes(simple shapes), referredShape, children etc
Handle (XCAFDoc_ShapeTool) _assembly;
};
};
} // namespace
#endif // _READERWRITERIGES_H_