You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
217 lines
6.6 KiB
217 lines
6.6 KiB
/**************************************************************************** |
|
* VCGLib o o * |
|
* Visual and Computer Graphics Library o o * |
|
* _ O _ * |
|
* Copyright(C) 2004-2016 \/)\/ * |
|
* Visual Computing Lab /\/| * |
|
* ISTI - Italian National Research Council | * |
|
* \ * |
|
* All rights reserved. * |
|
* * |
|
* This program is free software; you can redistribute it and/or modify * |
|
* it under the terms of the GNU General Public License as published by * |
|
* the Free Software Foundation; either version 2 of the License, or * |
|
* (at your option) any later version. * |
|
* * |
|
* This program is distributed in the hope that it will be useful, * |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of * |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * |
|
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * |
|
* for more details. * |
|
* * |
|
****************************************************************************/ |
|
|
|
/* This code has been adapted from the GTS exporter and Gael's GTS exporter from Expe */ |
|
|
|
/** |
|
@name Save in GTS format |
|
*/ |
|
//@{ |
|
|
|
#ifndef __VCGLIB_EXPORT_GTS |
|
#define __VCGLIB_EXPORT_GTS |
|
|
|
#include <QFile> |
|
#include <QTextStream> |
|
#include <map> |
|
#include <unordered_map> |
|
#include <wrap/io_trimesh/io_mask.h> |
|
|
|
|
|
namespace vcg { |
|
namespace tri { |
|
namespace io { |
|
template <class SaveMeshType> |
|
class ExporterGTS |
|
{ |
|
|
|
public: |
|
typedef typename SaveMeshType::ConstVertexPointer VertexPointer; |
|
typedef typename SaveMeshType::ScalarType ScalarType; |
|
typedef typename SaveMeshType::VertexType VertexType; |
|
typedef typename SaveMeshType::FaceType FaceType; |
|
typedef typename SaveMeshType::ConstFacePointer FacePointer; |
|
typedef typename SaveMeshType::ConstVertexIterator VertexIterator; |
|
typedef typename SaveMeshType::ConstFaceIterator FaceIterator; |
|
|
|
static int Save(const SaveMeshType &m, const char * filename, int /*mask*/ ) |
|
{ |
|
QFile device(filename); |
|
if (!device.open(QFile::WriteOnly)) |
|
return 1; |
|
|
|
QTextStream stream(&device); |
|
|
|
// update vertex indices |
|
//std::vector<int> FlagV; |
|
std::unordered_map<VertexPointer, int> vertFlags; |
|
VertexPointer vp; |
|
VertexIterator vi; |
|
int j; |
|
for(j=0,vi=m.vert.begin(); vi!=m.vert.end(); ++vi) |
|
{ |
|
vp = &(*vi); |
|
//FlagV.push_back(vp->Flags()); |
|
if (!vp->IsD()) |
|
{ |
|
vertFlags[vp] = j; |
|
//vp->Flags() = j; |
|
j++; |
|
} |
|
} |
|
assert(j==m.vn); |
|
|
|
// build the edge list, and count the number of edges |
|
typedef std::pair<int,int> Edge; |
|
typedef std::map<Edge,int> Edge2Index; |
|
Edge2Index edge2index; |
|
|
|
// loop over all edge's faces |
|
FacePointer fp; |
|
int edgeCount = 0; |
|
FaceIterator fi; |
|
for (j=0,fi=m.face.begin(); fi!=m.face.end(); ++fi) |
|
{ |
|
fp = &(*fi); |
|
if (!fp->IsD() ) |
|
{ |
|
for (int k=0; k<3; ++k) |
|
{ |
|
int a = vertFlags[fp->cV(k)];//fp->cV(k)->Flags(); |
|
int b = vertFlags[fp->cV((k+1)%3)];//fp->cV((k+1)%3)->Flags(); |
|
if (a>b) |
|
std::swap(a,b); |
|
Edge e(a,b); |
|
Edge2Index::iterator it = edge2index.find(e); |
|
if (it==edge2index.end()) |
|
{ |
|
edge2index[e] = edgeCount; |
|
edgeCount++; |
|
} |
|
} |
|
} |
|
} |
|
|
|
stream << m.vn << " " |
|
<< edgeCount << " " |
|
<< m.fn << " " |
|
<< "GtsSurface GtsFace GtsEdge GtsVertex\n"; |
|
|
|
// export vertices |
|
for (vi=m.vert.begin();vi!=m.vert.end();++vi) |
|
{ |
|
vp=&(*vi); |
|
if (!vp->IsD()) |
|
{ |
|
stream << vp->P()[0] << " " << vp->P()[1] << " " << vp->P()[2] << "\n"; |
|
} |
|
} |
|
|
|
// export the edges |
|
for (j=0,fi=m.face.begin(); fi!=m.face.end(); ++fi) |
|
{ |
|
fp = &(*fi); |
|
if (!fp->IsD() ) |
|
{ |
|
for (int k=0; k<3; ++k) |
|
{ |
|
int a = vertFlags[fp->cV(k)];//fp->cV(k)->Flags(); |
|
int b = vertFlags[fp->cV((k+1)%3)];//fp->cV((k+1)%3)->Flags(); |
|
if (a>b) |
|
std::swap(a,b); |
|
Edge e(a,b); |
|
Edge2Index::iterator it = edge2index.find(e); |
|
if (it!=edge2index.end()) |
|
{ |
|
stream << a+1 << " " << b+1 << "\n"; |
|
} |
|
} |
|
} |
|
} |
|
|
|
// third pass to export the face to edge connectivity |
|
for (j=0,fi=m.face.begin(); fi!=m.face.end(); ++fi) |
|
{ |
|
fp = &(*fi); |
|
if (!fp->IsD() ) |
|
{ |
|
for (int k=0; k<3; ++k) |
|
{ |
|
int a = vertFlags[fp->cV(k)];//fp->cV(k)->Flags(); |
|
int b = vertFlags[fp->cV((k+1)%3)];//fp->cV((k+1)%3)->Flags(); |
|
if (a>b) |
|
std::swap(a,b); |
|
Edge e(a,b); |
|
Edge2Index::iterator it = edge2index.find(e); |
|
if (it!=edge2index.end()) |
|
stream << it->second+1 << " "; |
|
else |
|
return 2; // internal error |
|
} |
|
stream << "\n"; |
|
} |
|
} |
|
|
|
// Recupera i flag originali |
|
//for(j=0,vi=m.vert.begin();vi!=m.vert.end();++vi) |
|
// (*vi).Flags()=FlagV[j++]; |
|
|
|
|
|
int result = 0; |
|
if (stream.status() != QTextStream::Ok) result = 3; |
|
stream.flush(); |
|
return result; |
|
} |
|
|
|
static const char *ErrorMsg(int error) |
|
{ |
|
static std::vector<std::string> off_error_msg; |
|
if (off_error_msg.empty()) |
|
{ |
|
off_error_msg.resize(4); |
|
off_error_msg[0] = "No errors"; |
|
off_error_msg[1] = "Can't open file"; |
|
off_error_msg[2] = "Internal error"; |
|
off_error_msg[3] = "Otput Stream Error"; |
|
} |
|
|
|
if (error>3 || error<0) return "Unknown error"; |
|
else return off_error_msg[error].c_str(); |
|
} |
|
/* |
|
returns mask of capability one define with what are the saveable information of the format. |
|
*/ |
|
static int GetExportMaskCapability() |
|
{ |
|
int capability = 0; |
|
capability |= vcg::tri::io::Mask::IOM_VERTCOORD; |
|
capability |= vcg::tri::io::Mask::IOM_FACEINDEX; |
|
return capability; |
|
} |
|
|
|
}; // end class |
|
} // end namespace tri |
|
} // end namespace io |
|
} // end namespace vcg |
|
//@} |
|
#endif
|
|
|