34 #ifndef AIMS_IO_WAVEFRONTMESHW_H
35 #define AIMS_IO_WAVEFRONTMESHW_H
53 T _clamp(
const T& value,
float m )
57 if( (
float) value < m )
59 else if( (
float) value > 1. - m )
60 new_value = (T) ( 1. - m );
77 class _printTextureCoord
81 std::string p(
const T & tex,
float m = 0.001 )
84 s << _clamp( tex, m ) <<
" 0";
90 template <
typename T,
int D>
98 for(
int i=0; i<3 && i<D; ++i )
102 s << _clamp( tex[i], m );
116 template<
int D,
class T>
132 const Header & header, std::ostream & os,
const std::string & filename,
134 inline static void writeObjectHeader( std::ostream & os,
int timestep,
136 const std::string & obj_filename,
155 template <
int U,
typename T>
162 const Header & header, std::ostream & os,
const std::string & filename,
164 inline static void writeObjectHeader(
174 template <
int D,
class T>
180 writer.
write( thing );
185 template <
int D,
class T>
inline
187 const std::string& name )
193 template <
int D,
class T>
inline
195 const Header & header, std::ostream & os,
const std::string & filename,
203 template <
int D,
class T>
inline
204 void WavefrontMeshWriter<D,T>::writeObjectHeader(
205 std::ostream & os,
int timestep,
206 PythonHeader *hdr,
const std::string & obj_filename,
209 WavefrontMeshWriter<D, Void>::writeObjectHeader( os, timestep, hdr,
210 obj_filename, options );
214 template <
int D,
class T>
inline
215 void WavefrontMeshWriter<D,T>::writeMtl( PythonHeader *hdr,
218 WavefrontMeshWriter<D, Void>::writeMtl( hdr, options );
223 template <
int D>
inline
225 const std::string& name )
227 std::string res = name;
229 if( res.length() > 4 )
230 ext = res.substr(
int(res.length() - 4), 4 );
232 res = res.substr( 0, res.length() - 4 );
238 PythonHeader* WavefrontMeshWriter<D, Void>::writeHeader(
239 const Header & header, std::ostream & os,
const std::string & filename,
242 PythonHeader *hdr =
new PythonHeader;
244 *ph =
dynamic_cast<const PythonHeader *
>( &header );
248 if( hdr->hasProperty(
"nb_t_pos" ) )
249 hdr->removeProperty(
"nb_t_pos" );
250 hdr->setProperty(
"file_type", std::string(
"WAVEFRONT" ) );
251 hdr->setProperty(
"object_type",
255 hdr->setProperty(
"data_type", dtype );
257 os <<
"# Wavefront OBJ\n" << std::endl;
262 material = hdr->getProperty(
"material" );
267 << std::endl << std::endl;
271 mtl->setProperty(
"filename", mtlfilename );
283 void WavefrontMeshWriter<D, Void>::writeObjectHeader(
284 std::ostream & os,
int timestep, PythonHeader *hdr,
287 std::stringstream namess;
289 obj_filename ) ) <<
"_" << timestep;
290 std::string name = namess.str();
291 os <<
"o " << name << std::endl << std::endl;
292 os <<
"s 1\n" << std::endl;
294 if( hdr->hasProperty(
"material" ) )
297 material = hdr->getProperty(
"material" );
298 mtl = hdr->getProperty(
"mtl" );
300 os <<
"usemtl " << name << std::endl << std::endl;
306 mtldict = mtl->getProperty( name );
310 mtl->setProperty( name, mtldict );
318 for(
int i=0; it->isValid() && i < 3; it->next(), ++i )
322 s << it->currentValue()->getScalar();
324 mtldict->setProperty(
"Ka", s.str() );
336 for( i=0; it->isValid() && i < 3; it->next(), ++i )
340 s << it->currentValue()->getScalar();
342 mtldict->setProperty(
"Kd", s.str() );
343 if( i == 3 && it->isValid() )
345 std::stringstream sd;
346 sd << it->currentValue()->getScalar();
347 mtldict->setProperty(
"d", sd.str() );
356 carto::Object specular = material->getProperty(
"specular" );
359 for(
int i=0; it->isValid() && i < 3; it->next(), ++i )
363 s << it->currentValue()->getScalar();
365 mtldict->setProperty(
"Ks", s.str() );
373 carto::Object shininess = material->getProperty(
"shininess" );
375 s << shininess->getScalar();
376 mtldict->setProperty(
"Ns", s.str() );
384 if( hdr->hasProperty(
"_texture_palettes" ) )
386 std::map<int, carto::Object> palettes;
387 hdr->getProperty(
"_texture_palettes", palettes );
388 std::map<int, carto::Object>::iterator ip = palettes.find( timestep );
389 if( ip != palettes.end() )
391 std::string pal_fname = name +
".png";
398 mtldict = mtl->getProperty( name );
402 mtl->setProperty( name, mtldict );
407 std::stringstream mapkd_val_s;
408 std::vector<float> texoffset;
409 if( hdr->getProperty(
"texture_offset", texoffset )
410 && texoffset.size() == 3 )
412 mapkd_val_s <<
"-o " << texoffset[0] <<
" " << texoffset[1] <<
" "
413 << texoffset[2] <<
" ";
415 std::vector<float> texscale;
416 if( hdr->getProperty(
"texture_scale", texscale )
417 && texscale.size() == 3 )
419 mapkd_val_s <<
"-s " << texscale[0] <<
" " << texscale[1] <<
" "
420 << texscale[2] <<
" ";
422 mtldict->setProperty(
"map_Kd", mapkd_val_s.str() + pal_fname );
425 Writer<carto::Volume<AimsRGBA> > w( pal_fname );
434 void WavefrontMeshWriter<D, Void>::writeMtl( PythonHeader *hdr,
440 mtl = hdr->getProperty(
"mtl" );
447 std::string mtlfilename = mtl->getProperty(
"filename" )->getString();
448 std::ofstream ms( mtlfilename.c_str() );
450 for( ; oit->isValid(); oit->next() )
452 if( oit->key() ==
"filename" )
454 std::string oname = oit->key();
455 ms <<
"newmtl " << oname << std::endl << std::endl;
457 for( ; it->isValid(); it->next() )
459 ms << it->key() <<
" " << it->currentValue()->getString() << std::endl;
462 hdr->removeProperty(
"mtl" );
467 template <
int D,
class T>
471 std::string fname = _name;
472 std::ofstream os( fname.c_str() );
477 thing.
header(), os, _name,
483 for( is=thing.begin(); is!=es; ++is, ++timestep )
485 writeObjectHeader( os, timestep, hdr, fname, options );
487 const std::vector<Point3df> &vert = (*is).second.vertex();
488 const std::vector<Point3df> &
norm = (*is).second.normal();
489 const std::vector<AimsVector<uint,D> > &poly= is->second.
polygon();
492 for( std::vector<Point3df>::const_iterator iv = vert.begin();
493 iv != vert.end(); ++iv )
494 os <<
"v " << (*iv)[0] <<
" " << (*iv)[1] <<
" " << (*iv)[2]
499 for( std::vector<Point3df>::const_iterator in =
norm.begin();
500 in !=
norm.end(); ++in )
501 os <<
"vn " << (*in)[0] <<
" " << (*in)[1] <<
" " << (*in)[2]
506 typename std::vector<T>::const_iterator it,
515 for( it=is->second.
texture().begin(); it!=et; ++it )
517 os <<
"vt " << _printTextureCoord<T>::p( *it, m ) << std::endl;
523 poly.
begin(); ip != poly.end(); ++ip )
529 for(
int p=0; p<D; ++p )
531 os <<
" " << (*ip)[p] + 1 <<
"/" << (*ip)[p] + 1 <<
"/"
539 writeMtl( hdr, options );
550 std::string fname = _name;
551 std::ofstream os( fname.c_str() );
561 for( is=thing.begin(); is!=es; ++is, ++timestep )
563 writeObjectHeader( os, timestep, hdr, fname, options );
565 const std::vector<Point3df> &vert = (*is).second.vertex();
566 const std::vector<Point3df> &
norm = (*is).second.normal();
567 const std::vector<AimsVector<uint,D> > &poly= is->second.
polygon();
570 for( std::vector<Point3df>::const_iterator iv = vert.begin();
571 iv != vert.end(); ++iv )
572 os <<
"v " << (*iv)[0] <<
" " << (*iv)[1] <<
" " << (*iv)[2]
577 for( std::vector<Point3df>::const_iterator in =
norm.begin();
578 in !=
norm.end(); ++in )
579 os <<
"vn " << (*in)[0] <<
" " << (*in)[1] <<
" " << (*in)[2]
585 poly.
begin(); ip != poly.end(); ++ip )
591 for(
int p=0; p<D; ++p )
593 os <<
" " << (*ip)[p] + 1 <<
"//" << (*ip)[p] + 1;
600 writeMtl( hdr, options );
The template class to manage a mesh with time if needed.
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.
const aims::PythonHeader & header() const
Get the header.
std::map< int, AimsSurface< D, T > >::const_iterator const_iterator
WavefrontMeshWriter(const std::string &name)
void write(const AimsTimeSurface< D, T > &thing, carto::Object options=carto::none())
static std::string removeExtension(const std::string &name)
Return a name without .obj extension.
WavefrontMeshWriter(const std::string &name)
static std::string dirname(const std::string &)
static std::string basename(const std::string &)
static std::string removeExtension(const std::string &)
GenericObject * get() const
The class for EcatSino data write operation.
MotionWriter & operator<<(MotionWriter &writer, const AffineTransformation3d &thing) __attribute__((__deprecated__("OBSOLETE")))
— OBSOLETE —
std::map< std::string, Object > Dictionary
AIMSDATA_API float norm(const Tensor &thing)