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>
 
  122   inline WavefrontMeshReader<D,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
 
  303             Reader<carto::Volume<AimsRGBA> > r( 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>
 
  344   void WavefrontMeshReader<D,T>::setMtl( 
carto::Object mtl_dict,
 
  345                                          const std::string & mtl_objname,
 
  354       mat = m->getProperty( 
"material" );
 
  356       mat->copyProperties( minfmat );
 
  362     hdr.copyProperties( m );
 
  364       hdr.setProperty( 
"material", mat );
 
  366     if( mtl_dict->hasProperty( 
"_texture_palettes" ) )
 
  368       carto::Object palettes = mtl_dict->getProperty( 
"_texture_palettes" );
 
  369       hdr.setProperty( 
"_texture_palettes", palettes );
 
  374   template <
long D, 
typename T>
 
  376   void WavefrontMeshReader<D,T>::storeMesh(
 
  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 ) );
 
  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() )
 
The template class to manage a mesh with time if needed.
void erase()
Clear all the meshes.
void setHeader(const aims::PythonHeader &hdr)
Set the header.
const std::vector< AimsVector< uint, D > > & polygon() const
Get a const reference to the vector of polygons of the 0 surface.
const std::vector< T > & texture() const
Get a const reference to the vector of textures of the 0 surface.
void updateNormals()
Update/Compute the normals.
const std::vector< Point3df > & normal() const
Get a const reference to the vector of normals of the 0 surface.
const std::vector< Point3df > & vertex() const
Get a const reference to the vector of verteces of the surface of index 0.
void read(AimsTimeSurface< D, T > &thing, const carto::AllocatorContext &context, carto::Object options)
WavefrontMeshReader(const std::string &name)
static std::string dirname(const std::string &)
virtual bool removeProperty(const std::string &)
virtual bool hasProperty(const std::string &) const
GenericObject * get() const
static bool getline(DataSource &ds, std::string &)
The class for EcatSino data write operation.
GenesisReader< T > & operator>>(GenesisReader< T > &reader, AimsData< T > &thing)
std::map< std::string, Object > Dictionary
AIMSDATA_API float norm(const Tensor &thing)