29 #include <boost/regex.hpp>
31 #include "WMeshReaderOBJ.h"
45 boost::filesystem::path file )
48 std::string fileName = file.string();
49 WAssert( !fileName.empty(),
"No filename specified." );
51 std::shared_ptr< WProgress > progress(
new WProgress(
"Read Mesh" ) );
52 parentProgress->addSubProgress( progress );
55 ifs.open( fileName.c_str(), std::ifstream::in );
56 if( !ifs || ifs.bad() )
58 throw WDHIOFailure(
"Could not open \"" + fileName +
"\" for reading." );
63 static const boost::regex faceVRegex(
"^ *[f,F] *([0-9]+) +([0-9]+) +([0-9]+).*$" );
65 static const boost::regex faceVTRegex(
"^ *[f,F] *([0-9]+)/([0-9]+) +([0-9]+)/([0-9]+) +([0-9]+)/([0-9]+).*$" );
67 static const boost::regex faceVTNRegex(
"^ *[f,F] *([0-9]+)/([0-9]+)/([0-9]+) +([0-9]+)/([0-9]+)/([0-9]+) +([0-9]+)/([0-9]+)/([0-9]+).*$" );
69 static const boost::regex faceVNRegex(
"^ *[f,F] *([0-9]+)//([0-9]+) +([0-9]+)//([0-9]+) +([0-9]+)//([0-9]+).*$" );
71 static const boost::regex vertexRegex(
"^ *[v,V][^n] *(-?[0-9]*\\.?[0-9]*) +(-?[0-9]*\\.?[0-9]*) +(-?[0-9]*\\.?[0-9]*).*$" );
72 static const boost::regex vertexColorRegex(
"^ *[v,V][^n] *(-?[0-9]*\\.?[0-9]*) +(-?[0-9]*\\.?[0-9]*) +(-?[0-9]*\\.?[0-9]*) (-?[0-9]*\\.?[0-9]*) +(-?[0-9]*\\.?[0-9]*) +(-?[0-9]*\\.?[0-9]*).*$" );
73 static const boost::regex normalRegex(
"^ *[v,V][n,N] *(-?[0-9]*\\.?[0-9]*) +(-?[0-9]*\\.?[0-9]*) +(-?[0-9]*\\.?[0-9]*).*$" );
74 static const boost::regex commentRegex(
"^ *#.*$" );
78 size_t numUnsupported = 0;
79 std::string line =
"";
81 std::vector< float > vertices;
82 std::vector< float > colors;
83 std::vector< size_t > faces;
84 std::vector< size_t > normals;
86 vertices.reserve( 3000 );
87 faces.reserve( 3000 );
93 std::getline( ifs, line,
'\n' );
103 boost::smatch matches;
106 if( boost::regex_match( line, matches, vertexColorRegex ) )
108 vertices.push_back( string_utils::fromString< float >( matches[1] ) );
109 vertices.push_back( string_utils::fromString< float >( matches[2] ) );
110 vertices.push_back( string_utils::fromString< float >( matches[3] ) );
111 colors.push_back( string_utils::fromString< float >( matches[4] ) );
112 colors.push_back( string_utils::fromString< float >( matches[5] ) );
113 colors.push_back( string_utils::fromString< float >( matches[6] ) );
115 else if( boost::regex_match( line, matches, vertexRegex ) )
117 vertices.push_back( string_utils::fromString< float >( matches[1] ) );
118 vertices.push_back( string_utils::fromString< float >( matches[2] ) );
119 vertices.push_back( string_utils::fromString< float >( matches[3] ) );
121 else if( boost::regex_match( line, matches, normalRegex ) )
123 normals.push_back( string_utils::fromString< float >( matches[1] ) );
124 normals.push_back( string_utils::fromString< float >( matches[2] ) );
125 normals.push_back( string_utils::fromString< float >( matches[3] ) );
128 else if( boost::regex_match( line, matches, faceVRegex ) )
131 faces.push_back( string_utils::fromString< size_t >( matches[1] ) - 1 );
132 faces.push_back( string_utils::fromString< size_t >( matches[2] ) - 1 );
133 faces.push_back( string_utils::fromString< size_t >( matches[3] ) - 1 );
135 else if( boost::regex_match( line, matches, faceVTRegex ) )
138 faces.push_back( string_utils::fromString< size_t >( matches[1] ) - 1 );
139 faces.push_back( string_utils::fromString< size_t >( matches[3] ) - 1 );
140 faces.push_back( string_utils::fromString< size_t >( matches[5] ) - 1 );
142 else if( boost::regex_match( line, matches, faceVTNRegex ) )
145 faces.push_back( string_utils::fromString< size_t >( matches[1] ) - 1 );
146 faces.push_back( string_utils::fromString< size_t >( matches[4] ) - 1 );
147 faces.push_back( string_utils::fromString< size_t >( matches[7] ) - 1 );
149 else if( boost::regex_match( line, matches, faceVNRegex ) )
152 faces.push_back( string_utils::fromString< size_t >( matches[1] ) - 1 );
153 faces.push_back( string_utils::fromString< size_t >( matches[3] ) - 1 );
154 faces.push_back( string_utils::fromString< size_t >( matches[5] ) - 1 );
157 else if( boost::regex_match( line, matches, commentRegex ) )
170 wlog::error(
"Read Mesh" ) <<
"There where " << numUnsupported <<
" unsupported lines.";
181 WAssert( ( vertices.size() == normals.size() ) || ( normals.size() == 0 ),
"Number of normals and vertices do not match." );
183 for(
size_t i = 0; i < vertices.size(); i += 3 )
185 triMesh->addVertex( vertices[ i + 0 ], vertices[ i + 1 ], vertices[ i + 2 ] );
187 for(
size_t i = 0; i < faces.size(); i += 3 )
189 triMesh->addTriangle( faces[ i + 0 ], faces[ i + 1 ], faces[ i + 2 ] );
191 for(
size_t i = 0; i < normals.size(); i += 3 )
193 triMesh->setVertexNormal( i / 3, normals[ i + 0 ], normals[ i + 1 ], normals[ i + 2 ] );
195 for(
size_t i = 0; i < colors.size(); i += 3 )
197 triMesh->setVertexColor( i / 3, osg::Vec4( colors[ i + 0 ], colors[ i + 1 ], colors[ i + 2 ], 1.0 ) );
202 parentProgress->removeSubProgress( progress );
Use this for IO error handling.
Define the interface which is injected into an WObjectNDIP.
WMeshReaderOBJ()
Constructor.
virtual ~WMeshReaderOBJ()
Destructor.
virtual WTriangleMesh::SPtr operator()(WProgressCombiner::SPtr parentProgress, boost::filesystem::path file)
Load the dataset.
This is a base class for everything which has a Name,Description,Icon and Properties (=NDIP).
std::shared_ptr< WProgressCombiner > SPtr
Abbreviate shared_ptr for this class.
Class managing progress inside of modules.
Triangle mesh data structure allowing for convenient access of the elements.
std::shared_ptr< WTriangleMesh > SPtr
Shared pointer.
WStreamedLogger error(const std::string &source)
Logging an error message.