34 #ifndef AIMS_IO_WAVEFRONTMESHR_H 35 #define AIMS_IO_WAVEFRONTMESHR_H 63 inline static void r( std::istream & s, T & tex )
70 template <
typename T,
int D>
78 for( i=0; i<3 && i<D; ++i )
92 template<
long D,
typename T>
100 const carto::AllocatorContext & context,
105 const std::vector<Point3df> & vertices,
106 const std::vector<Point3df> &normals,
108 const std::vector<T> & texture,
109 const std::vector<int> & normals_ind,
110 const std::vector<int> & texture_ind,
int timestep );
114 void setMtl(
carto::Object mtl_dict,
const std::string & mtl_objname,
121 template <
long D,
typename T>
126 reader.
read( thing, thing.allocator(),
132 template <
long D,
typename T>
135 std::string & mtl_filename )
139 std::ifstream ms( mtl_filename.c_str() );
142 std::cerr <<
"warning: could not open " << mtl_filename << std::endl;
146 ms.setf( std::ios::skipws );
151 std::string l, element, objname;
154 while( ds && !ds.
eof() )
162 std::cerr <<
"warning: could read " << mtl_filename <<
", line " 163 << line + 1 << std::endl;
169 if( l.empty() || l[0] ==
'#' )
172 std::stringstream s( l );
175 if( element ==
"newmtl" )
177 objname = l.substr( s.tellg(), l.length() - s.tellg() );
179 while( !objname.empty() && objname[i] ==
' ' )
181 objname = objname.substr( i, objname.length() - i );
184 mtl_dict->setProperty( objname, current_obj );
186 current_obj->setProperty(
"material", current_mat );
188 else if( element ==
"Ka" )
192 std::cerr <<
"MTL error: no current object.\n";
195 std::vector<float> ambient( 3 );
196 s >> ambient[0] >> ambient[1] >> ambient[2];
197 current_mat->setProperty(
"ambient", ambient );
199 else if( element ==
"Kd" )
203 std::cerr <<
"MTL error: no current object.\n";
206 std::vector<float> diffuse( 4, 1. );
207 if( current_mat->getProperty(
"diffuse", diffuse ) )
208 while( diffuse.size() < 4 )
209 diffuse.push_back( 1. );
210 s >> diffuse[0] >> diffuse[1] >> diffuse[2];
211 current_mat->setProperty(
"diffuse", diffuse );
213 else if( element ==
"Ks" )
217 std::cerr <<
"MTL error: no current object.\n";
220 std::vector<float> specular( 3 );
221 s >> specular[0] >> specular[1] >> specular[2];
222 current_mat->setProperty(
"specular", specular );
224 else if( element ==
"Ns" )
228 std::cerr <<
"MTL error: no current object.\n";
233 current_mat->setProperty(
"shininess", ns );
235 else if( element ==
"d" )
239 std::cerr <<
"MTL error: no current object.\n";
244 std::vector<float> diffuse( 4, 0.8 );
245 if( current_mat->getProperty(
"diffuse", diffuse ) )
246 while( diffuse.size() < 4 )
247 diffuse.push_back( 0.8 );
249 current_mat->setProperty(
"diffuse", diffuse );
251 else if( element ==
"Tr" )
255 std::cerr <<
"MTL error: no current object.\n";
260 std::vector<float> diffuse( 4, 0.8 );
261 if( current_mat->getProperty(
"diffuse", diffuse ) )
262 while( diffuse.size() < 4 )
263 diffuse.push_back( 0.8 );
264 diffuse[3] = 1.f - a;
265 current_mat->setProperty(
"diffuse", diffuse );
267 else if( element ==
"map_Kd" )
271 std::cerr <<
"MTL error: no current object.\n";
276 bool image_found =
false;
277 while( !image_found && s )
283 std::vector<float> tex_offset( 3 );
284 s >> tex_offset[0] >> tex_offset[1] >> tex_offset[2];
285 current_obj->setProperty(
"texture_offset", tex_offset );
287 else if( item ==
"-s" )
290 std::vector<float> tex_scale( 3 );
291 s >> tex_scale[0] >> tex_scale[1] >> tex_scale[2];
292 current_obj->setProperty(
"texture_scale", tex_scale );
294 else if( item ==
"-clamp" )
300 std::string teximage_fname
307 std::map<int, carto::Object> palettes;
308 mtl_dict->getProperty(
"_texture_palettes", palettes );
310 mtl_dict->setProperty(
"_texture_palettes", palettes );
314 std::cout <<
"failed to read texture image " << teximage_fname
320 else if( element ==
"illum" )
324 std::cerr <<
"MTL error: no current object.\n";
329 current_obj->setProperty(
"illum", illum );
334 std::cout <<
"unrecognized MTL tag: " << element << std::endl;
342 template <
long D,
typename T>
345 const std::string & mtl_objname,
354 mat = m->getProperty(
"material" );
356 mat->copyProperties( minfmat );
366 if( mtl_dict->hasProperty(
"_texture_palettes" ) )
368 carto::Object palettes = mtl_dict->getProperty(
"_texture_palettes" );
374 template <
long D,
typename T>
378 const std::vector<Point3df> & vertices,
379 const std::vector<Point3df> &normals,
381 const std::vector<T> & texture,
382 const std::vector<int> & normals_ind,
383 const std::vector<int> & texture_ind,
int timestep )
385 thing[timestep].
vertex() = vertices;
386 std::vector<Point3df> o_normals;
387 if( normals_ind.size() != normals.size() )
391 o_normals.resize( normals_ind.size() );
393 for(
int i=0, k=normals_ind.size(); i<k; ++i )
395 if( normals_ind[i] < 0 || normals_ind[i] >= static_cast<int>(vertices.size()) )
398 s <<
"normal index out of range: " << normals_ind[i] <<
" / " 399 << vertices.size() <<
" at index " << i;
402 o_normals[i] = normals[normals_ind[i]];
405 thing[timestep].
normal() = o_normals;
406 thing[timestep].
polygon() = polygons;
412 std::vector<T> o_texture;
413 o_texture.resize( texture_ind.size() );
414 for(
int i=0, k=texture_ind.size(); i<k; ++i )
416 if( texture_ind[i] < 0
417 || texture_ind[i] >= static_cast<int>(texture.size()) )
420 if( texture_ind[i] >= 0 )
422 s <<
"texture index out of range: " << texture_ind[i] <<
" / " 423 << texture.size() <<
" at index " << i;
427 o_texture[i] = texture[0];
430 o_texture[i] = texture[texture_ind[i]];
432 thing[timestep].
texture() = o_texture;
437 template <
long D,
typename T>
440 const carto::AllocatorContext & ,
443 std::string filename = _name;
447 std::ifstream istr( filename.c_str(), std::ios::in );
448 istr.unsetf( std::ios::skipws );
450 soma::io_error::launchErrnoExcept( filename );
452 istr.setf( std::ios::skipws );
458 std::vector<Point3df> vertices, normals;
459 std::vector<AimsVector<uint, D> > polygons;
460 std::vector<T> texture;
461 std::vector<int> normals_ind;
462 std::vector<int> texture_ind;
464 bool update_normals =
false;
467 while( ds && !ds.
eof() )
474 throw soma::wrong_format_error( filename );
482 std::stringstream s(l);
488 if( timestep != 0 || !vertices.empty() )
490 storeMesh( thing, vertices, normals, polygons, texture, normals_ind,
491 texture_ind, timestep );
493 if( thing[timestep].normal().size() != vertices.size() )
494 update_normals =
true;
504 else if( element ==
"g" )
506 else if( element ==
"s" )
508 else if( element ==
"mtllib" )
510 std::string mtl_filename;
511 mtl_filename = l.substr( s.tellg(), l.length() - s.tellg() );
513 while( !mtl_filename.empty() && mtl_filename[i] ==
' ' )
515 mtl_filename = mtl_filename.substr( i, mtl_filename.length() - i );
518 mtl_dict = readMtlFle( mtl_filename );
520 else if( element ==
"usemtl" )
522 std::string mtl_objname;
523 mtl_objname = l.substr( s.tellg(), l.length() - s.tellg() );
525 while( !mtl_objname.empty() && mtl_objname[i] ==
' ' )
527 mtl_objname = mtl_objname.substr( i, mtl_objname.length() - i );
528 setMtl( mtl_dict, mtl_objname, hdr );
530 else if( element ==
"v" )
534 s >> p[0] >> p[1] >> p[2];
535 vertices.push_back(p);
537 else if( element ==
"vn" )
541 s >> p[0] >> p[1] >> p[2];
542 normals.push_back(p);
544 else if( element ==
"vt" )
548 _readTexture<T>::r( s, tex );
549 texture.push_back(tex);
551 else if( element ==
"f" || (D == 2 && element ==
"l" ) )
555 std::string::size_type pos, pos0;
560 for(
int p=0; p<D; ++p )
563 pos0 = item.find(
'/' );
564 std::stringstream z( item.substr(0, pos0 ) );
567 poly[p] = vertices.size() + pol;
570 if( pos0 == std::string::npos )
574 pos = item.find(
'/', pos0 );
578 std::stringstream z( item.substr(pos0, pos - pos0 ) );
580 if( texture_ind.size() <= poly[p] )
581 texture_ind.resize( poly[p] + 1, -1 );
582 if( texture_ind[ poly[p] ] < 0 )
583 texture_ind[ poly[p] ] = tex - 1;
584 else if( texture_ind[ poly[p] ] != tex - 1 )
588 vertices.push_back( vertices[ poly[p] ] );
589 poly[p] = vertices.size() - 1;
590 texture_ind.resize( poly[p] + 1, -1 );
591 texture_ind[ poly[p] ] = tex - 1;
594 else if( pos != pos0 )
596 if( pos == std::string::npos )
599 std::stringstream n( item.substr( pos0, item.length() - pos0 ) );
602 norm = vertices.size() + norm + 1;
603 if( normals_ind.size() <= poly[p] )
604 normals_ind.resize( poly[p] + 1 );
605 normals_ind[ poly[p] ] = norm - 1;
607 polygons.push_back( poly );
611 std::cerr <<
"unrecognized element: " << element <<
", " << D <<
", " << l << std::endl;
620 storeMesh( thing, vertices, normals, polygons, texture, normals_ind,
621 texture_ind, timestep );
623 if( update_normals || thing[timestep].normal().size() != vertices.size() )
void read(AimsTimeSurface< D, T > &thing, const carto::AllocatorContext &context, carto::Object options)
static bool getline(DataSource &ds, std::string &)
virtual bool getProperty(const std::string &, Object &) const
The class for EcatSino data write operation.
virtual bool removeProperty(const std::string &)
WavefrontMeshReader< D, T > & operator>>(WavefrontMeshReader< D, T > &reader, AimsTimeSurface< D, T > &thing)
The template class to manage a mesh with time if needed.
const std::vector< T > & texture() const
Get a const reference to the vector of textures of the 0 surface.
const std::vector< AimsVector< uint, D > > & polygon() const
Get a const reference to the vector of polygons of the 0 surface.
const std::vector< Point3df > & normal() const
Get a const reference to the vector of normals of the 0 surface.
WavefrontMeshReader(const std::string &name)
static std::string dirname(const std::string &)
Generic reader for every format of Aims object.
void updateNormals()
Update/Compute the normals.
GenericObject * get() const
std::map< std::string, Object > Dictionary
const std::vector< Point3df > & vertex() const
Get a const reference to the vector of verteces of the surface of index 0.
virtual void setProperty(const std::string &, Object)
AIMSDATA_API float norm(const Tensor &thing)
virtual void copyProperties(Object source)
virtual bool read(T &obj, int border=0, const std::string *format=0, int frame=-1)
Finds the correct format and reads the object. if format is specified, this format is tried first...
virtual bool hasProperty(const std::string &) const
void setHeader(const aims::PythonHeader &hdr)
Set the header.
void erase()
Clear all the meshes.