45 #define FILEOBJPLUGIN_C 49 #include <OpenMesh/Core/Utils/color_cast.hh> 50 #include <OpenMesh/Core/Geometry/VectorT.hh> 55 template<
class MeshT >
58 bool optionColorAlpha =
false;
59 bool optionTextures =
false;
60 bool optionCopyTextures =
false;
61 bool optionCreateTexFolder =
false;
64 if ( !OpenFlipper::Options::savingSettings() && saveOptions_ != 0) {
65 optionColorAlpha = saveAlpha_->isChecked();
66 optionTextures = saveTextures_->isChecked();
67 optionCopyTextures = saveCopyTextures_->isChecked();
68 optionCreateTexFolder = saveCreateTexFolder_->isChecked();
72 std::fstream matStream( _filename.toStdString().c_str(), std::ios_base::out );
76 emit log(
LOGERR, tr(
"writeMaterial : cannot not open file %1").arg(_filename) );
87 typename MeshT::FaceIter f_it;
88 typename MeshT::FaceIter f_end = _mesh.faces_end();
91 for (f_it = _mesh.faces_begin(); f_it != f_end; ++f_it){
92 getMaterial(_mesh, *f_it, _objId);
97 Material& mat = (*it).second;
98 matStream <<
"newmtl " << mat <<
'\n';
99 matStream <<
"Ka 0.5000 0.5000 0.5000" <<
'\n';
101 matStream <<
"Kd " << c[0] <<
" " << c[1] <<
" " << c[2] <<
'\n';
102 if(optionColorAlpha) {
103 matStream <<
"Tr " << mat.Tr() <<
'\n';
105 matStream <<
"illum 1" <<
'\n';
108 if(optionTextures && mat.has_Texture()) {
109 if(optionCopyTextures) {
111 QFileInfo file(mat.map_Kd().c_str());
112 if(optionCreateTexFolder) {
113 QFileInfo materialFilename(_filename);
115 matStream <<
"map_Kd " << materialFilename.baseName().toStdString() <<
"_textures" << QDir::separator().toLatin1()
116 << file.fileName().toStdString() <<
'\n';
118 matStream <<
"map_Kd " << file.fileName().toStdString() <<
'\n';
122 matStream <<
"map_Kd " << mat.map_Kd() <<
'\n';
136 template<
class MeshT >
140 bool optionColorAlpha =
false;
141 if ( !OpenFlipper::Options::savingSettings() && saveOptions_ != 0)
142 optionColorAlpha = saveAlpha_->isChecked();
148 if(!textureIndexPropFetched_) {
149 emit textureIndexPropertyName(_objId, textureIndexPropertyName_);
150 textureIndexPropFetched_ =
true;
155 if ( _mesh.get_property_handle(texture_index_property, textureIndexPropertyName_.toStdString()) ) {
156 texIndex = _mesh.property(texture_index_property, _fh);
157 }
else if ( _mesh.get_property_handle(texture_index_property,
"f:textureindex") ) {
158 texIndex = _mesh.property(texture_index_property, _fh);
159 }
else if(_mesh.has_face_texture_index()) {
160 texIndex = _mesh.texture_index(_fh);
163 emit getCurrentTexture(_objId, texName);
164 if(texName !=
"NONE")
165 emit textureIndex(texName, _objId, texIndex);
169 bool hasTexture =
false;
174 std::map<int,QString>::iterator it = texIndexFileMap_.find(texIndex);
176 if(it != texIndexFileMap_.end()) {
178 filename = (*it).second;
183 emit textureName(_objId, texIndex, texName);
185 if(texName !=
"NOT_FOUND") {
186 emit textureFilename( _objId, texName, filename );
188 texIndexFileMap_.insert(std::pair<int,QString>(texIndex, filename));
199 if(((*it).second).Kd() ==
ACG::Vec3f(c[0], c[1], c[2]) &&
200 ((optionColorAlpha && ((*it).second).Tr() == c[3]) || !optionColorAlpha))
204 QString mKd(((*it).second).map_Kd().c_str());
205 if((((*it).second).Kd() ==
ACG::Vec3f(c[0], c[1], c[2]) &&
206 ((optionColorAlpha && ((*it).second).Tr() == c[3]) || !optionColorAlpha)) &&
207 (filename == mKd && ((*it).second).map_Kd_index() == texIndex))
215 mat.set_Kd(c[0], c[1], c[2]);
217 if(optionColorAlpha) mat.set_Tr(c[3]);
221 mat.set_map_Kd(filename.toStdString(), texIndex);
223 materials_.insert(std::make_pair(QString(
"Material%1").arg(mat.material_number()).toStdString(), mat));
234 template<
class MeshT >
235 bool FileOBJPlugin::writeMesh(std::ostream& _out, QString _filename, MeshT& _mesh,
int _objId){
237 unsigned int i, nV, idx;
240 typename MeshT::VertexHandle vh;
241 bool useMaterial =
false;
244 bool optionFaceColors =
false;
245 bool optionVertexNormals =
false;
246 bool optionVertexTexCoords =
true;
247 bool optionTextures =
false;
248 bool optionCopyTextures =
false;
249 bool optionCreateTexFolder =
false;
251 QFileInfo fi(_filename);
254 if ( !OpenFlipper::Options::savingSettings() && saveOptions_ != 0) {
255 optionFaceColors = saveFaceColor_->isChecked();
256 optionVertexNormals = saveNormals_->isChecked();
257 optionVertexTexCoords = saveTexCoords_->isChecked();
258 optionTextures = saveTextures_->isChecked();
259 optionCopyTextures = saveCopyTextures_->isChecked();
260 optionCreateTexFolder = saveCreateTexFolder_->isChecked();
261 _out.precision(savePrecision_->value());
266 if ( optionFaceColors || optionTextures ){
268 QString matFile = fi.absolutePath() + QDir::separator() + fi.baseName() +
".mtl";
274 _out <<
"# " << _mesh.n_vertices() <<
" vertices, ";
275 _out << _mesh.n_faces() <<
" faces" <<
'\n';
278 if (useMaterial && optionFaceColors )
279 _out <<
"mtllib " << fi.baseName().toStdString() <<
".mtl" <<
'\n';
284 std::map<typename MeshT::VertexHandle, int> vtMapV;
288 for (i=0, nV=_mesh.n_vertices(); i<nV; ++i)
290 vh =
typename MeshT::VertexHandle(i);
292 n = _mesh.normal(vh);
294 if ( _mesh.has_vertex_texcoords2D() && !_mesh.has_halfedge_texcoords2D() )
295 t = _mesh.texcoord2D(vh);
298 _out <<
"v " << v[0] <<
" "<< v[1] <<
" "<< v[2] <<
'\n';
301 if ( optionVertexNormals)
302 _out <<
"vn " << n[0] <<
" "<< n[1] <<
" "<< n[2] <<
'\n';
305 if ( optionVertexTexCoords && _mesh.has_vertex_texcoords2D() && !_mesh.has_halfedge_texcoords2D()) {
306 _out <<
"vt " << t[0] <<
" "<< t[1] <<
'\n';
307 vtMapV.insert(std::pair<typename MeshT::VertexHandle, int>(vh, cf));
312 typename MeshT::FaceVertexIter fv_it;
313 typename MeshT::FaceHalfedgeIter fh_it;
314 typename MeshT::FaceIter f_it;
319 std::map<typename MeshT::HalfedgeHandle, int> vtMap;
322 if(optionVertexTexCoords && _mesh.has_halfedge_texcoords2D()) {
324 for (f_it = _mesh.faces_begin(); f_it != _mesh.faces_end(); ++f_it) {
325 for(fh_it=_mesh.fh_iter(*f_it); fh_it.is_valid(); ++fh_it) {
327 _out <<
"vt " << t[0] <<
" " << t[1] <<
'\n';
328 vtMap.insert(std::pair<typename MeshT::HalfedgeHandle, int>(*fh_it, count));
337 bool vertexOnly = !(optionVertexTexCoords && _mesh.has_halfedge_texcoords2D())
338 && !(optionVertexTexCoords && !_mesh.has_halfedge_texcoords2D() && _mesh.has_vertex_texcoords2D())
339 && !(optionVertexNormals);
341 for (f_it = _mesh.faces_begin(); f_it != _mesh.faces_end(); ++f_it){
343 if (useMaterial && optionFaceColors) {
345 Material& material = getMaterial(_mesh, *f_it, _objId);
348 if(lastMat != material) {
349 _out <<
"usemtl " << material <<
'\n';
357 for(fh_it=_mesh.fh_iter(*f_it); fh_it.is_valid(); ++fh_it) {
360 idx = _mesh.to_vertex_handle(*fh_it).idx() + 1;
368 if ( optionVertexTexCoords ) {
370 if ( optionVertexTexCoords && _mesh.has_halfedge_texcoords2D()) {
372 typename std::map<typename MeshT::HalfedgeHandle, int>::iterator it = vtMap.find(*fh_it);
373 if(it != vtMap.end())
374 _out << (*it).second;
375 }
else if (optionVertexTexCoords && !_mesh.has_halfedge_texcoords2D() && _mesh.has_vertex_texcoords2D()) {
377 typename std::map<typename MeshT::VertexHandle, int>::iterator it = vtMapV.find(_mesh.to_vertex_handle(*fh_it));
378 if(it != vtMapV.end())
379 _out << (*it).second;
384 if ( optionVertexNormals ) {
397 if(optionCopyTextures) {
400 bool testedOnce =
false;
402 Material& mat = (*it).second;
404 if(!mat.has_Texture())
continue;
406 QImage img(mat.map_Kd().c_str());
407 QFileInfo img_f(mat.map_Kd().c_str());
411 emit log(
LOGERR, tr(
"An error occurred when trying to copy a texture file."));
414 if(optionCreateTexFolder) {
416 QDir dir(fi.absolutePath());
417 if(!testedOnce && dir.exists(fi.absolutePath() + QDir::separator() + fi.baseName() +
"_textures")) {
418 emit log(
LOGERR, tr(
"The specified target folder already contains a subfolder called textures. Skipping!"));
421 dir.mkdir(fi.baseName() +
"_textures");
422 img.save(fi.absolutePath() + QDir::separator() + fi.baseName() +
"_textures" + QDir::separator() + img_f.fileName());
427 img.save(fi.absolutePath() + QDir::separator() + img_f.fileName());
434 texIndexFileMap_.clear();
435 textureIndexPropFetched_ =
false;
VectorT< float, 3 > Vec3f
bool writeMaterial(QString _filename, MeshT &_mesh, int _objId)
writer functions
Handle for a face entity.
Add 2D texture coordinates (vertices, halfedges)
MaterialList materials_
List that contains the material properties.