add vcglib

This commit is contained in:
yuanlin zhong committed 2025-11-03 17:46:44 +08:00
1 parent 6f6c0c8eb7
commit af8100f851
1537 files changed
+634197

No files matched your search

+491
View File
@@ -0,0 +1,491 @@
/****************************************************************************
* 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. *
* *
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
****************************************************************************/
/**
@name Load and Save in Ply format
*/
//@{
#ifndef __VCGLIB_TETRAEXPORT_PLY
#define __VCGLIB_TETRAEXPORT_PLY
#include<wrap/io_tetramesh/io_mask.h>
#include<wrap/io_tetramesh/io_ply.h>
#include<wrap/io_trimesh/precision.h>
#include <stdio.h>
namespace vcg {
namespace tetra {
namespace io {
template <class SaveMeshType>
class ExporterPLY
{
// Si occupa di convertire da un tipo all'altro.
// usata nella saveply per matchare i tipi tra stotype e memtype.
// Ad es se in memoria c'e' un int e voglio salvare un float
// src sara in effetti un puntatore a int il cui valore deve
// essere convertito al tipo di ritorno desiderato (stotype)
template <class StoType>
static void PlyConv(int mem_type, void *src, StoType &dest)
{
switch (mem_type){
case ply::T_FLOAT : dest = (StoType) (* ((float *) src)); break;
case ply::T_DOUBLE : dest = (StoType) (* ((double *) src)); break;
case ply::T_INT : dest = (StoType) (* ((int *) src)); break;
case ply::T_SHORT : dest = (StoType) (* ((short *) src)); break;
case ply::T_CHAR : dest = (StoType) (* ((char *) src)); break;
case ply::T_UCHAR : dest = (StoType) (* ((unsigned char *)src)); break;
default : assert(0);
}
}
public:
typedef ::vcg::ply::PropDescriptor PropDescriptor ;
typedef typename SaveMeshType::VertexPointer VertexPointer;
typedef typename SaveMeshType::ScalarType ScalarType;
typedef typename SaveMeshType::VertexType VertexType;
typedef typename SaveMeshType::TetraType TetraType;
typedef typename SaveMeshType::TetraPointer TetraPointer;
typedef typename SaveMeshType::VertexIterator VertexIterator;
typedef typename SaveMeshType::TetraIterator TetraIterator;
static bool Save(SaveMeshType &m, const char * filename, bool binary=true)
{
PlyInfo pi;
return Save(m,filename,binary,pi);
}
static bool Save(SaveMeshType &m, const char * filename, int savemask, bool binary=true )
{
PlyInfo pi;
pi.mask=savemask;
return Save(m,filename,binary,pi);
}
static bool Save(SaveMeshType &m, const char * filename, bool binary, PlyInfo & pi ) // V1.0
{
FILE * fpout;
int i;
const char * hbin = "binary_little_endian";
const char * hasc = "ascii";
const char * h;
bool multit = false;
const int DGT = vcg::tri::io::Precision<ScalarType>::digits();
const int DGTVQ = vcg::tri::io::Precision<typename VertexType::QualityType>::digits();
const int DGTVR = vcg::tri::io::Precision<typename VertexType::RadiusType>::digits();
const int DGTTQ = vcg::tri::io::Precision<typename TetraType::QualityType>::digits();
if(binary) h=hbin;
else h=hasc;
fpout = fopen(filename,"wb");
if(fpout==NULL) {
pi.status=::vcg::ply::E_CANTOPEN;
return ::vcg::ply::E_CANTOPEN;
}
fprintf(fpout,
"ply\n"
"format %s 1.0\n"
"comment VCGLIB generated\n"
,h
);
//if( pi.mask & ply::PLYMask::PM_WEDGTEXCOORD )
//{
// //const char * TFILE = "TextureFile";
// //for(i=0;i<textures.size();++i)
// // fprintf(fpout,"comment %s %s\n", TFILE, (const char *)(textures[i]) );
// //if(textures.size()>1 && (HasPerWedgeTexture() || HasPerVertexTexture())) multit = true;
//}
//if( (pi.mask & PLYMask::PM_CAMERA) && camera.IsValid() )
/*{
fprintf(fpout,
"element camera 1\n"
"property float view_px\n"
"property float view_py\n"
"property float view_pz\n"
"property float x_axisx\n"
"property float x_axisy\n"
"property float x_axisz\n"
"property float y_axisx\n"
"property float y_axisy\n"
"property float y_axisz\n"
"property float z_axisx\n"
"property float z_axisy\n"
"property float z_axisz\n"
"property float focal\n"
"property float scalex\n"
"property float scaley\n"
"property float centerx\n"
"property float centery\n"
"property int viewportx\n"
"property int viewporty\n"
"property float k1\n"
"property float k2\n"
"property float k3\n"
"property float k4\n"
);
}*/
// VERT
const char* vttp = vcg::tri::io::Precision<ScalarType>::typeName();
fprintf(fpout,"element vertex %d\n",m.vn);
fprintf(fpout,"property %s x\n",vttp);
fprintf(fpout,"property %s y\n",vttp);
fprintf(fpout,"property %s z\n",vttp);
if( HasPerVertexFlags(m) &&( pi.mask & Mask::IOM_VERTFLAGS) )
{
fprintf(fpout,
"property int flags\n"
);
}
if( HasPerVertexColor(m) && (pi.mask & Mask::IOM_VERTCOLOR) )
{
fprintf(fpout,
"property uchar red\n"
"property uchar green\n"
"property uchar blue\n"
"property uchar alpha\n"
);
}
if( HasPerVertexQuality(m) && (pi.mask & Mask::IOM_VERTQUALITY) )
{
const char* vqtp = vcg::tri::io::Precision<typename VertexType::ScalarType>::typeName();
fprintf(fpout,"property %s quality\n",vqtp);
}
for(i=0;i<pi.vdn;i++)
fprintf(fpout,"property %s %s\n",pi.VertexData[i].stotypename(),pi.VertexData[i].propname);
// TETRA
fprintf(fpout,
"element tetra %d\n"
"property list uchar int vertex_indices\n"
,m.tn
);
if( pi.mask & Mask::IOM_TETRAFLAGS)
{
fprintf(fpout,
"property int flags\n"
);
}
if( (pi.mask & Mask::IOM_TETRACOLOR) )
{
fprintf(fpout,
"property uchar red\n"
"property uchar green\n"
"property uchar blue\n"
"property uchar alpha\n"
);
}
if( (pi.mask & Mask::IOM_TETRAQUALITY) )
{
const char* vqtp = vcg::tri::io::Precision<typename TetraType::ScalarType>::typeName();
fprintf(fpout,"property %s quality\n",vqtp);
}
for(i=0;i<pi.fdn;i++)
fprintf(fpout,"property %s %s\n",pi.TetraData[i].stotypename(),pi.TetraData[i].propname);
fprintf(fpout, "end_header\n" );
// Salvataggio camera
//if( (pi.mask & ply::PLYMask::PM_CAMERA) && camera.IsValid() )
//{
//if(binary)
//{
// float t[17];
// t[ 0] = camera.view_p[0];
// t[ 1] = camera.view_p[1];
// t[ 2] = camera.view_p[2];
// t[ 3] = camera.x_axis[0];
// t[ 4] = camera.x_axis[1];
// t[ 5] = camera.x_axis[2];
// t[ 6] = camera.y_axis[0];
// t[ 7] = camera.y_axis[1];
// t[ 8] = camera.y_axis[2];
// t[ 9] = camera.z_axis[0];
// t[10] = camera.z_axis[1];
// t[11] = camera.z_axis[2];
// t[12] = camera.f;
// t[13] = camera.s[0];
// t[14] = camera.s[1];
// t[15] = camera.c[0];
// t[16] = camera.c[1];
// fwrite(t,sizeof(float),17,fpout);
// fwrite( camera.viewport,sizeof(int),2,fpout );
// t[ 0] = camera.k[0];
// t[ 1] = camera.k[1];
// t[ 2] = camera.k[2];
// t[ 3] = camera.k[3];
// fwrite(t,sizeof(float),4,fpout);
//}
//else
//{
// fprintf(fpout,"%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %d %d %g %g %g %g\n"
// ,camera.view_p[0]
// ,camera.view_p[1]
// ,camera.view_p[2]
// ,camera.x_axis[0]
// ,camera.x_axis[1]
// ,camera.x_axis[2]
// ,camera.y_axis[0]
// ,camera.y_axis[1]
// ,camera.y_axis[2]
// ,camera.z_axis[0]
// ,camera.z_axis[1]
// ,camera.z_axis[2]
// ,camera.f
// ,camera.s[0]
// ,camera.s[1]
// ,camera.c[0]
// ,camera.c[1]
// ,camera.viewport[0]
// ,camera.viewport[1]
// ,camera.k[0]
// ,camera.k[1]
// ,camera.k[2]
// ,camera.k[3]
// );
//}
//}
SimpleTempData<typename SaveMeshType::VertContainer,int> indices(m.vert);
int j;
std::vector<int> FlagV;
VertexPointer vp;
VertexIterator vi;
for(j=0,vi=m.vert.begin();vi!=m.vert.end();++vi)
{
vp=&(*vi);
indices[vi] = j;
FlagV.push_back(vp->Flags()); // Salva in ogni caso flag del vertice
if( ! vp->IsD() )
{
if(binary)
{
float t;
t = float(vp->P()[0]); fwrite(&t,sizeof(float),1,fpout);
t = float(vp->P()[1]); fwrite(&t,sizeof(float),1,fpout);
t = float(vp->P()[2]); fwrite(&t,sizeof(float),1,fpout);
if( pi.mask & Mask::IOM_VERTFLAGS )
fwrite(&(vp->Flags()),sizeof(int),1,fpout);
if( HasPerVertexColor(m) && (pi.mask & Mask::IOM_VERTCOLOR) )
fwrite(&( vp->C() ),sizeof(char),4,fpout);
if( HasPerVertexQuality(m) && (pi.mask & Mask::IOM_VERTQUALITY) )
fwrite(&( vp->Q() ),DGTVQ,1,fpout);
for(i=0;i<pi.vdn;i++)
{
double td; float tf;int ti;short ts; char tc; unsigned char tuc;
switch (pi.VertexData[i].stotype1)
{
case ply::T_FLOAT : PlyConv(pi.VertexData[i].memtype1, ((char *)vp)+pi.VertexData[i].offset1, tf ); fwrite(&tf, sizeof(float),1,fpout); break;
case ply::T_DOUBLE : PlyConv(pi.VertexData[i].memtype1, ((char *)vp)+pi.VertexData[i].offset1, td ); fwrite(&td, sizeof(double),1,fpout); break;
case ply::T_INT : PlyConv(pi.VertexData[i].memtype1, ((char *)vp)+pi.VertexData[i].offset1, ti ); fwrite(&ti, sizeof(int),1,fpout); break;
case ply::T_SHORT : PlyConv(pi.VertexData[i].memtype1, ((char *)vp)+pi.VertexData[i].offset1, ts ); fwrite(&ts, sizeof(short),1,fpout); break;
case ply::T_CHAR : PlyConv(pi.VertexData[i].memtype1, ((char *)vp)+pi.VertexData[i].offset1, tc ); fwrite(&tc, sizeof(char),1,fpout); break;
case ply::T_UCHAR : PlyConv(pi.VertexData[i].memtype1, ((char *)vp)+pi.VertexData[i].offset1, tuc); fwrite(&tuc,sizeof(unsigned char),1,fpout); break;
default : assert(0);
}
}
}
else // ***** ASCII *****
{
fprintf(fpout,"%g %g %g " ,vp->P()[0],vp->P()[1],vp->P()[2]);
if( pi.mask & Mask::IOM_VERTFLAGS )
fprintf(fpout,"%d ",vp->Flags());
if( HasPerVertexColor(m) && (pi.mask & Mask::IOM_VERTCOLOR) )
fprintf(fpout,"%d %d %d %d ",vp->C()[0], vp->C()[1], vp->C()[2], vp->C()[3] );
if( HasPerVertexQuality(m) && (pi.mask & Mask::IOM_VERTQUALITY) )
fprintf(fpout,"%g ",vp->Q());
for(i=0;i<pi.vdn;i++)
{
float tf; double td;
int ti;
switch (pi.VertexData[i].memtype1)
{
case ply::T_FLOAT : tf=*( (float *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%g ",tf); break;
case ply::T_DOUBLE : td=*( (double *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%g ",tf); break;
case ply::T_INT : ti=*( (int *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%i ",ti); break;
case ply::T_SHORT : ti=*( (short *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%i ",ti); break;
case ply::T_CHAR : ti=*( (char *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%i ",ti); break;
case ply::T_UCHAR : ti=*( (unsigned char *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%i ",ti); break;
default : assert(0);
}
}
fprintf(fpout,"\n");
}
vp->Flags()=j; // Trucco! Nascondi nei flags l'indice del vertice non deletato!
j++;
}
}
assert(j==m.vn);
char c = 4;
unsigned char b9 = 9;
unsigned char b6 = 6;
TetraPointer fp;
int vv[4];
TetraIterator fi;
int fcnt=0;
for(j=0,fi=m.tetra.begin();fi!=m.tetra.end();++fi)
{
fp=&(*fi);
if( ! fp->IsD() )
{ fcnt++;
if(binary)
{
vv[0]=indices[fp->cV(0)];
vv[1]=indices[fp->cV(1)];
vv[2]=indices[fp->cV(2)];
vv[3]=indices[fp->cV(3)];
fwrite(&c,1,1,fpout);
fwrite(vv,sizeof(int),4,fpout);
if( pi.mask & Mask::IOM_TETRAFLAGS )
fwrite(&(fp->Flags()),sizeof(int),1,fpout);
if( (pi.mask & Mask::IOM_TETRACOLOR) )
fwrite(&( fp->C() ), sizeof(char),4,fpout);
if( (pi.mask & Mask::IOM_TETRAQUALITY) )
fwrite( &(fp->Q()), DGTTQ,1,fpout);
for(i=0;i<pi.fdn;i++)
{
double td; float tf;int ti;short ts; char tc; unsigned char tuc;
switch (pi.TetraData[i].stotype1){
case ply::T_FLOAT : PlyConv(pi.TetraData[i].memtype1, ((char *)fp)+pi.TetraData[i].offset1, tf ); fwrite(&tf, sizeof(float),1,fpout); break;
case ply::T_DOUBLE : PlyConv(pi.TetraData[i].memtype1, ((char *)fp)+pi.TetraData[i].offset1, td ); fwrite(&td, sizeof(double),1,fpout); break;
case ply::T_INT : PlyConv(pi.TetraData[i].memtype1, ((char *)fp)+pi.TetraData[i].offset1, ti ); fwrite(&ti, sizeof(int),1,fpout); break;
case ply::T_SHORT : PlyConv(pi.TetraData[i].memtype1, ((char *)fp)+pi.TetraData[i].offset1, ts ); fwrite(&ts, sizeof(short),1,fpout); break;
case ply::T_CHAR : PlyConv(pi.TetraData[i].memtype1, ((char *)fp)+pi.TetraData[i].offset1, tc ); fwrite(&tc, sizeof(char),1,fpout); break;
case ply::T_UCHAR : PlyConv(pi.TetraData[i].memtype1, ((char *)fp)+pi.TetraData[i].offset1, tuc); fwrite(&tuc,sizeof(unsigned char),1,fpout); break;
default : assert(0);
}
}
}
else // ***** ASCII *****
{
fprintf(fpout,"%d " , 4);
fprintf(fpout,"%d %d %d %d ",
indices[fp->cV(0)], indices[fp->cV(1)], indices[fp->cV(2)], indices[fp->cV(3)]);
if( pi.mask & Mask::IOM_TETRAFLAGS )
fprintf(fpout,"%d ",fp->Flags());
if( TetraType::HasColor() && (pi.mask & Mask::IOM_TETRACOLOR) )
fprintf(fpout,"%d %d %d %d ",vp->C()[0],vp->C()[1],vp->C()[2],vp->C()[3] );
if((pi.mask & Mask::IOM_TETRAQUALITY) )
fprintf(fpout,"%g ",fp->Q());
for(i=0;i<pi.fdn;i++)
{
float tf; double td;
int ti;
switch (pi.TetraData[i].memtype1)
{
case ply::T_FLOAT : tf=*( (float *) (((char *)fp)+pi.TetraData[i].offset1)); fprintf(fpout,"%g ",tf); break;
case ply::T_DOUBLE : td=*( (double *) (((char *)fp)+pi.TetraData[i].offset1)); fprintf(fpout,"%g ",tf); break;
case ply::T_INT : ti=*( (int *) (((char *)fp)+pi.TetraData[i].offset1)); fprintf(fpout,"%i ",ti); break;
case ply::T_SHORT : ti=*( (short *) (((char *)fp)+pi.TetraData[i].offset1)); fprintf(fpout,"%i ",ti); break;
case ply::T_CHAR : ti=*( (char *) (((char *)fp)+pi.TetraData[i].offset1)); fprintf(fpout,"%i ",ti); break;
case ply::T_UCHAR : ti=*( (unsigned char *) (((char *)fp)+pi.TetraData[i].offset1)); fprintf(fpout,"%i ",ti); break;
default : assert(0);
}
}
fprintf(fpout,"\n");
}
}
}
assert(fcnt==m.tn);
fclose(fpout);
// Recupera i flag originali
for(j=0,vi=m.vert.begin();vi!=m.vert.end();++vi)
(*vi).Flags()=FlagV[j++];
return 0;
}
}; // end class
} // end namespace tetra
} // end namespace io
} // end namespace vcg
#endif
+117
View File
@@ -0,0 +1,117 @@
/****************************************************************************
* 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. *
* *
****************************************************************************/
/**
@name Load and Save in Tetgen File format
*/
//@{
#ifndef __VCGLIB_TETRAEXPORT_TET
#define __VCGLIB_TETRAEXPORT_TET
#include<wrap/io_trimesh/precision.h>
#include <stdio.h>
namespace vcg {
namespace tetra {
namespace io {
template <class SaveMeshType>
class ExporterTET
{
public:
typedef ::vcg::ply::PropDescriptor PropDescriptor ;
typedef typename SaveMeshType::VertexPointer VertexPointer;
typedef typename SaveMeshType::ScalarType ScalarType;
typedef typename SaveMeshType::VertexType VertexType;
typedef typename SaveMeshType::TetraType TetraType;
typedef typename SaveMeshType::TetraPointer TetraPointer;
typedef typename SaveMeshType::VertexIterator VertexIterator;
typedef typename SaveMeshType::TetraIterator TetraIterator;
static bool Save(SaveMeshType &m, const char * filename) // V1.0
{
FILE * eleFile;
FILE * nodeFile;
const int DGT = vcg::tri::io::Precision<ScalarType>::digits();
std::string eleName(filename);
std::string nodeName(filename);
eleName.append(".ele");
nodeName.append(".node");
eleFile = fopen(eleName.c_str() , "wb");
if (eleFile == NULL)
return 1;
nodeFile = fopen(nodeName.c_str() , "wb");
if (nodeFile == NULL)
return 1;
fprintf(eleFile,
"#VCG lib .ele generated file\n"
"#This file contains the tetra definition in accord to Tetgen file format\n");
fprintf(nodeFile,
"#VCG lib .node generated file\n"
"#This file contains the vertex definition in accord to Tetgen file format\n");
fprintf(nodeFile, "%d 3 0 0\n", m.VN());
int vi = 0;
SimpleTempData<typename SaveMeshType::VertContainer, int> indices(m.vert);
ForEachVertex(m, [&] (VertexType & v) {
indices[&v] = vi;
fprintf(nodeFile, "%d %g %g %g\n", vi++, double(v.P().X()), double(v.P().Y()), double(v.P().Z()));
});
fprintf(eleFile, "%d 4 0\n", m.TN());
int ti = 0;
ForEachTetra(m, [&] (SaveMeshType::TetraType & t) {
fprintf(eleFile, "%d %d %d %d %d\n", ti++, indices[t.V(0)], indices[t.V(1)], indices[t.V(2)], indices[t.V(3)]);
});
fclose(eleFile);
fclose(nodeFile);
return 0;
}
}; // end class
} // end namespace tetra
} // end namespace io
} // end namespace vcg
#endif
+103
View File
@@ -0,0 +1,103 @@
/****************************************************************************
* 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. *
* *
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
Revision 1.1 2004/10/11 17:41:41 ganovelli
added
Revision 1.1 2004/06/03 13:16:32 ganovelli
created
Revision 1.3 2004/05/10 13:14:28 ganovelli
converted to library style (namespaces etc..)
****************************************************************************/
#ifndef __VCGLIB_EXPORTERSMF
#define __VCGLIB_EXPORTERSMF
#include <vcg/space/point3.h>
namespace vcg {
namespace tetra {
namespace io {
template <typename MESHTYPE>
struct ExporterTS{
typedef typename MESHTYPE::VertexPointer VertexPointer;
typedef typename MESHTYPE::VertexType VertexType;
typedef typename MESHTYPE::TetraType FaceType;
typedef typename MESHTYPE::VertexIterator VertexIterator;
typedef typename MESHTYPE::TetraIterator TetraIterator;
typedef typename MESHTYPE::ScalarType ScalarType;
typedef Point3<ScalarType> Point3x;
static FILE *& F(){static FILE * f; return f;}
inline static void WritePos(const Point3<ScalarType> &p){
fprintf(F(),"%g %g %g\n",p[0],p[1],p[2]);
}
inline static void WritePos(const Point4<ScalarType> &p){
fprintf(F(),"%g %g %g %g\n",p[0],p[1],p[2],p[3]);
}
static int Save( MESHTYPE & m, const char * filename )
{
F() = fopen(filename,"w");
if(F() == NULL )
{
printf( "The file could not be opened\n" );
return -1;
}
else
{
fprintf(F(), "%i\n", m.vn );
fprintf(F(), "%i\n", m.tn );
VertexIterator vi;
for (vi = m.vert.begin(); vi != m.vert.end();++vi)
//fprintf(F(), "%f %f %f \n", (*vi).P()[0],(*vi).P()[1],(*vi).P()[2] );
WritePos((*vi).P());
TetraIterator ti;
for( ti = m.tetra.begin(); ti != m.tetra.end(); ++ti)
fprintf(F(), "%d %d %d %d \n",
(*ti).V(0)-&*m.vert.begin(),
(*ti).V(1)-&*m.vert.begin(),
(*ti).V(2)-&*m.vert.begin(),
(*ti).V(3)-&*m.vert.begin());
}
return 0;
}
};// end class
};// end of io
};// end of tri
};// end of vcg
#endif
+146
View File
@@ -0,0 +1,146 @@
/****************************************************************************
* 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. *
* *
****************************************************************************/
/**
@name Load and Save in Tetgen File format
*/
//@{
#ifndef __VCGLIB_TETRAEXPORT_VTK
#define __VCGLIB_TETRAEXPORT_VTK
#include <wrap/io_trimesh/precision.h>
#include <stdio.h>
namespace vcg
{
namespace tetra
{
namespace io
{
template <class SaveMeshType>
class ExporterVTK
{
public:
typedef ::vcg::ply::PropDescriptor PropDescriptor;
typedef typename SaveMeshType::VertexPointer VertexPointer;
typedef typename SaveMeshType::ScalarType ScalarType;
typedef typename SaveMeshType::VertexType VertexType;
typedef typename SaveMeshType::TetraType TetraType;
typedef typename SaveMeshType::TetraPointer TetraPointer;
typedef typename SaveMeshType::VertexIterator VertexIterator;
typedef typename SaveMeshType::TetraIterator TetraIterator;
enum
{
VTK_VERTEX = 1,
VTK_POLY_VERTEX,
VTK_LINE,
VTK_POLY_LINE,
VTK_TRIANGLE,
VTK_TRIANGLE_STRIP,
VTK_POLYGON,
VTK_PIXEL,
VTK_QUAD,
VTK_TETRA,
VTK_VOXEL,
VTK_HEXAHEDRON,
VTK_WEDGE,
VTK_PYRAMID
};
static bool Save(SaveMeshType &m, const char *filename) // V1.0
{
FILE *vtkFile;
const int DGT = vcg::tri::io::Precision<ScalarType>::digits();
const char* vttp = vcg::tri::io::Precision<ScalarType>::typeName();
std::string vtkName(filename);
vtkFile = fopen(vtkName.c_str(), "wb");
if (vtkFile == NULL)
return 1;
fprintf(vtkFile, "# vtk DataFile Version 2.0\n");
fprintf(vtkFile, "VCG_mesh\n");
fprintf(vtkFile, "ASCII\n");
fprintf(vtkFile, "DATASET UNSTRUCTURED_GRID\n");
fprintf(vtkFile, "POINTS %d %s\n", m.VN(), vttp);
int vi = 0;
SimpleTempData<typename SaveMeshType::VertContainer, int> indices(m.vert);
int maxQ = 0;
ForEachVertex(m, [&](VertexType &v) {
indices[&v] = vi++;
fprintf(vtkFile, "%g %g %g\n", v.P().X(), v.P().Y(), v.P().Z());
});
fprintf(vtkFile, "CELLS %d %d\n", m.TN(), m.TN()*5);
int ti = 0;
ForEachTetra(m, [&](SaveMeshType::TetraType &t) {
++ti;
fprintf(vtkFile, "%d %d %d %d %d\n", 4, indices[t.V(0)], indices[t.V(1)], indices[t.V(2)], indices[t.V(3)]);
});
fprintf(vtkFile, "CELL_TYPES %d\n", m.TN());
ForEachTetra(m, [&](SaveMeshType::TetraType &t) {
fprintf(vtkFile, "%d\n", VTK_TETRA);
});
if( HasPerVertexQuality(m))
{
fprintf(vtkFile, "POINT_DATA %d\n", m.VN());
fprintf(vtkFile, "SCALARS vquality %s 1\n", vttp);
fprintf(vtkFile, "LOOKUP_TABLE default\n");
ForEachVertex(m, [&](VertexType &v) {
fprintf(vtkFile, "%g\n", v.Q());
});
}
if( HasPerTetraQuality(m))
{
fprintf(vtkFile, "CELL_DATA %d\n", m.TN());
fprintf(vtkFile, "SCALARS tquality %s 1\n", vttp);
fprintf(vtkFile, "LOOKUP_TABLE default\n");
ForEachTetra(m, [&](TetraType &t) {
fprintf(vtkFile, "%g\n", t.Q());
});
}
fclose(vtkFile);
return 0;
}
}; // end class
} // namespace io
} // namespace tetra
} // end namespace vcg
#endif
+152
View File
@@ -0,0 +1,152 @@
/****************************************************************************
* 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. *
* *
****************************************************************************/
/****************************************************************************
****************************************************************************/
#ifndef __VCGLIB_TETRA_IMPORT
#define __VCGLIB_TETRA_IMPORT
#include <wrap/io_tetramesh/import_ply.h>
#include <wrap/io_tetramesh/import_msh.h>
#include <locale>
namespace vcg {
namespace tetra {
namespace io {
/**
This class encapsulate a filter for automatically importing meshes by guessing
the right filter according to the extension
*/
template <class OpenMeshType>
class Importer
{
private:
enum KnownTypes { KT_UNKNOWN, KT_PLY, KT_MSH };
static int &LastType()
{
static int lastType= KT_UNKNOWN;
return lastType;
}
public:
enum ImporterError {
E_NOERROR =0 // No error =0 is the standard for ALL the imported files.
};
// simple aux function that returns true if a given file has a given extesnion
static bool FileExtension(std::string filename, std::string extension)
{
std::transform(filename.begin(), filename.end(), filename.begin(), ::tolower);
std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
std::string end=filename.substr(filename.length() - extension.length(), extension.length());
return end == extension;
}
// Open Mesh, returns 0 on success.
static int Open(OpenMeshType &m, const char *filename, CallBackPos *cb=0)
{
int dummymask = 0;
return Open(m, filename, dummymask, cb);
}
/// Open Mesh and fills the load mask (the load mask must be initialized first); returns 0 on success.
static int Open(OpenMeshType &m, const char *filename, int &loadmask, CallBackPos *cb=0)
{
int err;
if(FileExtension(filename,"ply"))
{
err = tetra::io::ImporterPLY<OpenMeshType>::Open(m, filename, loadmask, cb);
LastType()=KT_PLY;
}
else if(FileExtension(filename,"msh"))
{
err = tetra::io::ImporterMSH<OpenMeshType>::Open(m, filename, cb);
LastType()=KT_MSH;
}
else
{
err=1;
LastType()=KT_UNKNOWN;
}
return err;
}
static bool ErrorCritical(int error)
{
switch(LastType())
{
case KT_PLY : return (error > 0); break;
case KT_MSH : return (error > 0); break;
}
return true;
}
static const char *ErrorMsg(int error)
{
switch(LastType())
{
// case KT_PLY : return ImporterPLY<OpenMeshType>::ErrorMsg(error); break;
// case KT_STL : return ImporterSTL<OpenMeshType>::ErrorMsg(error); break;
// case KT_OFF : return ImporterOFF<OpenMeshType>::ErrorMsg(error); break;
// case KT_OBJ : return ImporterOBJ<OpenMeshType>::ErrorMsg(error); break;
// case KT_VMI : return ImporterVMI<OpenMeshType>::ErrorMsg(error); break;
}
return "Unknown type";
}
static bool LoadMask(const char * filename, int &mask)
{
bool err;
if(FileExtension(filename, "ply"))
{
err = tetra::io::ImporterPLY<OpenMeshType>::LoadMask(filename, mask);
LastType() = KT_PLY;
}
else if(FileExtension(filename, "msh"))
{
mask = Mask::IOM_VERTCOORD | Mask::IOM_TETRAINDEX;
err = true;
LastType() = KT_MSH;
}
else
{
err = false;
LastType()=KT_UNKNOWN;
}
return err;
}
}; // end class
} // end Namespace tetra
} // end Namespace io
} // end Namespace vcg
#endif
+515
View File
@@ -0,0 +1,515 @@
#ifndef __VCGLIB_IMPORTTETMSH_H
#define __VCGLIB_IMPORTTETMSH_H
#include <iostream>
namespace vcg {
namespace tetra {
namespace io {
template <class MeshType>
class MshInfo
{
typedef std::map<std::string, double *> FieldMap;
FieldMap nodeFields;
FieldMap elemFields;
template <typename Scalar, int Dimensions>
struct AttribTraits
{
typedef std::vector<Scalar> Type;
enum { Dimension = Dimensions };
};
template <typename Scalar>
struct AttribTraits<Scalar, 1>
{
typedef Scalar Type;
enum { Dimension = 1 };
};
template <typename AttrHandle, typename Scalar, int Dimension>
struct AttribHelper
{
static void assign(AttrHandle & handle, int index, const double * data)
{
for (int i=0; i<Dimension; ++i)
{
handle[index][i] = Scalar(data[Dimension * index + i]);
}
}
};
template <typename AttrHandle, typename Scalar>
struct AttribHelper<AttrHandle, Scalar, 1>
{
static void assign(AttrHandle & handle, int index, const double * data)
{
handle[index] = Scalar(data[index]);
}
};
template <bool PerNode, typename Scalar>
static void fillMeshAttributes(const std::string & attrib_name, int attrib_dim, MeshType & mesh, const double * data)
{
if (PerNode)
{
switch(attrib_dim)
{
case 1 : fillMeshWithAttributePerNode<Scalar, 1>(attrib_name, mesh, data); break;
case 2 : fillMeshWithAttributePerNode<Scalar, 2>(attrib_name, mesh, data); break;
case 3 : fillMeshWithAttributePerNode<Scalar, 3>(attrib_name, mesh, data); break;
case 4 : fillMeshWithAttributePerNode<Scalar, 4>(attrib_name, mesh, data); break;
case 5 : fillMeshWithAttributePerNode<Scalar, 5>(attrib_name, mesh, data); break;
case 6 : fillMeshWithAttributePerNode<Scalar, 6>(attrib_name, mesh, data); break;
case 7 : fillMeshWithAttributePerNode<Scalar, 7>(attrib_name, mesh, data); break;
case 8 : fillMeshWithAttributePerNode<Scalar, 8>(attrib_name, mesh, data); break;
case 9 : fillMeshWithAttributePerNode<Scalar, 9>(attrib_name, mesh, data); break;
default : throw std::string("Dimension of custom attribute vector unsupported");
}
}
else
{
switch(attrib_dim)
{
case 1 : fillMeshWithAttributePerElement<Scalar, 1>(attrib_name, mesh, data); break;
case 2 : fillMeshWithAttributePerElement<Scalar, 2>(attrib_name, mesh, data); break;
case 3 : fillMeshWithAttributePerElement<Scalar, 3>(attrib_name, mesh, data); break;
case 4 : fillMeshWithAttributePerElement<Scalar, 4>(attrib_name, mesh, data); break;
case 5 : fillMeshWithAttributePerElement<Scalar, 5>(attrib_name, mesh, data); break;
case 6 : fillMeshWithAttributePerElement<Scalar, 6>(attrib_name, mesh, data); break;
case 7 : fillMeshWithAttributePerElement<Scalar, 7>(attrib_name, mesh, data); break;
case 8 : fillMeshWithAttributePerElement<Scalar, 8>(attrib_name, mesh, data); break;
case 9 : fillMeshWithAttributePerElement<Scalar, 9>(attrib_name, mesh, data); break;
default : throw std::string("Dimension of custom attribute vector unsupported");
}
}
}
template <typename Scalar, int Dimension/* = 1*/>
static void fillMeshWithAttributePerNode(const std::string & attrib_name, MeshType & mesh, const double * data)
{
typedef typename AttribTraits<Scalar, Dimension>::Type AttrType;
typedef typename MeshType::template PerVertexAttributeHandle<AttrType> AttrHandle;
AttrHandle handle = vcg::tri::Allocator<MeshType>::template GetPerVertexAttribute<AttrType>(mesh, attrib_name);
size_t num_nodes = size_t(mesh.VN());
for (int i=0; i<int(num_nodes); ++i)
AttribHelper<AttrHandle, Scalar, Dimension>::assign(handle, i, data);
}
template <typename Scalar, int Dimension/* = 1*/>
static void fillMeshWithAttributePerElement(const std::string & attrib_name, MeshType & mesh, const double * data)
{
typedef typename AttribTraits<Scalar, Dimension>::Type AttrType;
typedef typename MeshType::template PerFaceAttributeHandle<AttrType> AttrHandle;
AttrHandle handle = vcg::tri::Allocator<MeshType>::template GetPerFaceAttribute<AttrType>(mesh, attrib_name);
size_t num_elements = size_t(mesh.TN());
for (int i=0; i<int(num_elements); ++i)
AttribHelper<AttrHandle, Scalar, Dimension>::assign(handle, i, data);
}
};
template <class MeshType>
class ImporterMSH
{
typedef typename MeshType::ScalarType ScalarType;
typedef typename MeshType::CoordType CoordType;
typedef typename MeshType::VertexType VertexType;
typedef typename MeshType::TetraType TetraType;
typedef typename MeshType::VertexIterator VertexIterator;
typedef typename MeshType::TetraIterator TetraIterator;
enum ErrorCodes
{
INVALID_FORMAT = 1,
INVALID_VERSION,
NOT_IMPLEMENTED,
IO_ERROR
};
static inline void parseWhiteSpace(std::ifstream &fin)
{
//we don't want to consume non whitespace bytes, just peek it..
char next = fin.peek();
while (next == '\n' || next == ' ' || next == '\t' || next == '\r')
{
fin.get();
next = fin.peek();
}
}
static int parseNodes(MeshType &m, std::ifstream &fin, bool binary)
{
int numOfNodes;
fin >> numOfNodes;
if (numOfNodes < 0)
return INVALID_FORMAT;
VertexIterator vi = vcg::tri::Allocator<MeshType>::AddVertices(m, numOfNodes);
if (binary)
{
size_t lineBytes = (4 + 3 * 8); //int index + 3 * double coords
size_t bytes = numOfNodes * lineBytes;
char *data = new char[bytes];
parseWhiteSpace(fin);
fin.read(data, bytes);
for (int i = 0; i < numOfNodes; ++i)
{
int index = *reinterpret_cast<int *>(&data[i * lineBytes]) - 1;
if (index < 0)
return INVALID_FORMAT;
m.vert[index].P().X() = *reinterpret_cast<double *>(&data[i * lineBytes + 4]);
m.vert[index].P().Y() = *reinterpret_cast<double *>(&data[i * lineBytes + 4 + 8]);
m.vert[index].P().Z() = *reinterpret_cast<double *>(&data[i * lineBytes + 4 + 2 * 8]);
}
delete[] data;
}
else
{
for (int i = 0; i < numOfNodes; ++i)
{
int index;
fin >> index;
--index;
if (index < 0)
return INVALID_FORMAT;
fin >> m.vert[index].P().X();
fin >> m.vert[index].P().Y();
fin >> m.vert[index].P().Z();
}
}
return 0;
}
static int parseElements(MeshType &m, std::ifstream &fin, bool binary)
{
int numOfElements;
fin >> numOfElements;
if (numOfElements < 0)
return INVALID_FORMAT;
TetraIterator ti = vcg::tri::Allocator<MeshType>::AddTetras(m, numOfElements);
if (binary)
{
parseWhiteSpace(fin);
size_t parsedElems = 0;
while (parsedElems < numOfElements)
{
//MSH in binary format has a elem-header 3*4 bytes: {elems_type, numElems, tagsPerElem}
//followed by the list of elems under this header and eventually a new header and list.
int type, elements, tags;
fin.read((char *)&type, sizeof(int));
fin.read((char *)&elements, sizeof(int));
fin.read((char *)&tags, sizeof(int));
//check for tetra type
if (type != 4)
return NOT_IMPLEMENTED;
//read tags and throw them
for (size_t j = 0; j < tags; ++j)
{
int tag;
fin.read((char *)&tag, sizeof(int));
}
//foreach element
for (int i = 0; i < elements; ++i)
{
int index;
fin.read((char *)&index, sizeof(int));
--index;
//check index validity
if (index < 0)
return INVALID_FORMAT;
//read element nodes
TetraType * t = &m.tetra[index];
for (int i = 0; i < 4; ++i)
{
int nodeIndex;
fin.read((char *)&nodeIndex, sizeof(int));
--nodeIndex;
if (nodeIndex < 0 || nodeIndex >= m.VN())
return INVALID_FORMAT;
t->V(i) = &m.vert[nodeIndex];
}
++parsedElems;
}
}
}
else
{
for (int i = 0; i < numOfElements; ++i)
{
int index, type, tags;
fin >> index >> type >> tags;
--index;
//check for tetra type
if (type != 4)
return NOT_IMPLEMENTED;
//check index validity
if (index < 0)
return INVALID_FORMAT;
//read tags and throw them
for (size_t j = 0; j < tags; ++j)
{
int tag;
fin >> tag;
}
TetraType *t = &m.tetra[index];
for (int i = 0; i < 4; ++i)
{
int nodeIndex;
fin >> nodeIndex;
--nodeIndex;
if (nodeIndex < 0 || nodeIndex > m.VN())
return INVALID_FORMAT;
t->V(i) = &m.vert[nodeIndex];
}
}
}
return 0;
}
static int parseDataField(MeshType &m, std::ifstream &fin, bool binary)
{
int numString, numReal, numInteger;
fin >> numString;
std::string *strTags = new std::string[numString];
for (int i = 0; i < numString; ++i)
{
parseWhiteSpace(fin);
fin >> strTags[i];
}
fin >> numReal;
double *doubleTags = new double[numReal];
for (int i = 0; i < numReal; ++i)
fin >> doubleTags[i];
fin >> numInteger;
if (numString <= 0 || numInteger < 3)
return INVALID_FORMAT;
int *integerTags = new int[numInteger];
for (int i = 0; i < numInteger; ++i)
fin >> integerTags[i];
std::string fieldName = strTags[0];
int fieldComponents = integerTags[1];
int fieldSize = integerTags[2];
double *fieldVec = new double[fieldComponents * fieldSize];
delete[] strTags;
delete[] doubleTags;
delete[] integerTags;
if (binary)
{
size_t totalBytes = (4 + 8 * fieldComponents) * fieldSize;
char *data = new char[totalBytes];
parseWhiteSpace(fin);
fin.read(data, totalBytes);
for (int i = 0; i < fieldSize; ++i)
{
int index = *reinterpret_cast<int *>(&data[i * (4 + fieldComponents * 8)]);
--index;
if (index < 0)
return INVALID_FORMAT;
//values
int baseIndex = i * (4 + fieldComponents * 8) + 4;
for (int j = 0; j < fieldComponents; ++j)
fieldVec[index * fieldComponents + j] = *reinterpret_cast<float *>(&data[baseIndex + j * 8]);
}
}
else
{
for (int i = 0; i < fieldSize; ++i)
{
int index;
fin >> index;
--index;
if (index < 0)
return INVALID_FORMAT;
for (int j = 0; j < fieldComponents; ++j)
fin >> fieldVec[index * fieldComponents + j];
}
}
}
static int parseNodeData(MeshType &m, MshInfo<MeshType> & info, std::ifstream &fin, bool binary)
{
return parseDataField(m, fin, binary);
}
static int parseElementData(MeshType &m, MshInfo<MeshType> & info, std::ifstream &fin, bool binary)
{
return parseDataField(m, fin, binary);
}
static int parseUnsupportedTag(std::ifstream &fin, std::string &tag)
{
std::cerr << "found unsupported tag" << std::endl;
std::string tagName = tag.substr(1, tag.size() - 1);
std::string tagEnd = tag.substr(0, 1) + "End" + tagName;
std::string buf;
while (buf != tagEnd && !fin.eof())
fin >> buf;
return 0;
}
static int parseMshMesh(MeshType &m, std::string &filename, MshInfo<MeshType> & info)
{
std::ifstream fin(filename.c_str(), std::ios::in | std::ios::binary);
if (!fin.is_open())
return IO_ERROR;
std::string lookAhead;
fin >> lookAhead;
if (lookAhead != "$MeshFormat")
return INVALID_FORMAT;
double version;
int type, dataSize;
fin >> version >> type >> dataSize;
if (version != 2.2)
return INVALID_VERSION;
bool binary = (type == 1);
if (dataSize != 8)
return INVALID_FORMAT;
// Read endiannes info in binary header...it's a 1 used to detect endiannes.
if (binary)
{
int one;
parseWhiteSpace(fin);
fin.read(reinterpret_cast<char *>(&one), sizeof(int));
if (one != 1)
{
std::cerr << "Warning: binary msh file " << filename
<< " is saved with different endianness than this machine."
<< std::endl;
throw NOT_IMPLEMENTED;
}
}
lookAhead.clear();
fin >> lookAhead;
if (lookAhead != "$EndMeshFormat")
return INVALID_FORMAT;
while (!fin.eof())
{
lookAhead.clear();
fin >> lookAhead;
if (lookAhead == "$Nodes")
{
int res = parseNodes(m, fin, binary);
if (res != 0)
return res;
fin >> lookAhead;
if (lookAhead != "$EndNodes")
return INVALID_FORMAT;
}
else if (lookAhead == "$Elements")
{
int res = parseElements(m, fin, binary);
if (res != 0)
return res;
fin >> lookAhead;
if (lookAhead != "$EndElements")
return INVALID_FORMAT;
}
else if (lookAhead == "$NodeData")
{
parseNodeData(m, info, fin, binary);
fin >> lookAhead;
if (lookAhead != "$EndNodeData")
return INVALID_FORMAT;
}
else if (lookAhead == "$ElementData")
{
parseElementData(m, info, fin, binary);
fin >> lookAhead;
if (lookAhead != "$EndElementData")
return INVALID_FORMAT;
}
else if (fin.eof())
{
break;
}
else
{
parseUnsupportedTag(fin, lookAhead);
}
}
fin.close();
return 0;
}
public:
static int Open(MeshType &m, const char *filename, CallBackPos *cb = 0)
{
MshInfo<MeshType> info;
return Open(m, filename, info, cb);
}
static int Open(MeshType &m, const char *filename, MshInfo<MeshType> & info, CallBackPos *cb = 0)
{
std::string name(filename);
return parseMshMesh(m, name, info);
}
};
} // namespace io
} // namespace tetra
} // namespace vcg
#endif
+628
View File
@@ -0,0 +1,628 @@
/****************************************************************************
* 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. *
* *
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
Revision 1.1 2004/06/03 13:16:32 ganovelli
created
****************************************************************************/
#ifndef __VCGLIB_TETRAIMPORTER_PLY
#define __VCGLIB_TETRAIMPORTER_PLY
#include<wrap/callback.h>
#include<wrap/ply/plylib.h>
#include<wrap/io_tetramesh/io_mask.h>
#include<wrap/io_tetramesh/io_ply.h>
namespace vcg {
namespace tetra {
namespace io {
template <class TYPE>
int PlyType () { return 0;}
template <> inline int PlyType <float >() { return ply::T_FLOAT; }
template <> inline int PlyType <double>() { return ply::T_DOUBLE; }
template <> inline int PlyType <int >() { return ply::T_INT; }
template <> inline int PlyType <short >() { return ply::T_SHORT; }
template <> inline int PlyType <unsigned char >() { return ply::T_UCHAR; }
/**
This class encapsulate a filter for opening ply meshes.
The ply file format is quite extensible...
*/
template <class OpenMeshType>
class ImporterPLY
{
public:
typedef ::vcg::ply::PropDescriptor PropDescriptor ;
typedef typename OpenMeshType::VertexPointer VertexPointer;
typedef typename OpenMeshType::ScalarType ScalarType;
typedef typename OpenMeshType::VertexType VertexType;
typedef typename OpenMeshType::TetraType TetraType;
typedef typename OpenMeshType::VertexIterator VertexIterator;
typedef typename OpenMeshType::TetraIterator TetraIterator;
//template <class T> int PlyType () { assert(0); return 0;}
#define MAX_USER_DATA 256
// Struttura ausiliaria per la lettura del file ply
struct LoadPly_TetraAux
{
unsigned char size;
int v[512];
int flags;
float q;
float texcoord[32];
unsigned char ntexcoord;
int texcoordind;
float colors[32];
unsigned char ncolors;
unsigned char r;
unsigned char g;
unsigned char b;
unsigned char a;
unsigned char data[MAX_USER_DATA];
};
//struct LoadPly_TristripAux
//{
// int size;
// int *v;
// unsigned char data[MAX_USER_DATA];
//};
// Struttura ausiliaria per la lettura del file ply
template<class S>
struct LoadPly_VertAux
{
S p[3];
int flags;
float q;
unsigned char r;
unsigned char g;
unsigned char b;
unsigned char a;
unsigned char data[MAX_USER_DATA];
};
// Struttura ausiliaria caricamento camera
//struct LoadPly_Camera
//{
// float view_px;
// float view_py;
// float view_pz;
// float x_axisx;
// float x_axisy;
// float x_axisz;
// float y_axisx;
// float y_axisy;
// float y_axisz;
// float z_axisx;
// float z_axisy;
// float z_axisz;
// float focal;
// float scalex;
// float scaley;
// float centerx;
// float centery;
// int viewportx;
// int viewporty;
// float k1;
// float k2;
// float k3;
// float k4;
//};
static const PropDescriptor &VertDesc(int i)
{
const static PropDescriptor pv[13]={
/*00*/ {"vertex", "x", ply::T_FLOAT, PlyType<ScalarType>(), offsetof(LoadPly_VertAux<ScalarType>,p), 0, 0, 0, 0, 0, 0},
/*01*/ {"vertex", "y", ply::T_FLOAT, PlyType<ScalarType>(), offsetof(LoadPly_VertAux<ScalarType>,p) + sizeof(ScalarType), 0, 0, 0, 0, 0, 0},
/*02*/ {"vertex", "z", ply::T_FLOAT, PlyType<ScalarType>(), offsetof(LoadPly_VertAux<ScalarType>,p) + 2*sizeof(ScalarType), 0, 0, 0, 0, 0, 0},
/*03*/ {"vertex", "flags", ply::T_INT, ply::T_INT, offsetof(LoadPly_VertAux<ScalarType>,flags), 0, 0, 0, 0, 0, 0},
/*04*/ {"vertex", "quality", ply::T_FLOAT, PlyType<ScalarType>(), offsetof(LoadPly_VertAux<ScalarType>,q), 0, 0, 0, 0, 0, 0},
/*05*/ {"vertex", "red" , ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux<ScalarType>,r), 0, 0, 0, 0, 0, 0},
/*06*/ {"vertex", "green", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux<ScalarType>,g), 0, 0, 0, 0, 0, 0},
/*07*/ {"vertex", "blue" , ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux<ScalarType>,b), 0, 0, 0, 0, 0, 0},
/*08*/ {"vertex", "alpha" , ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_VertAux<ScalarType>,a), 0, 0, 0, 0, 0, 0},
// DOUBLE
/*09*/ {"vertex", "x", ply::T_DOUBLE, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,p), 0, 0, 0, 0, 0, 0},
/*10*/ {"vertex", "y", ply::T_DOUBLE, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,p) + sizeof(ScalarType), 0, 0, 0, 0, 0, 0},
/*11*/ {"vertex", "z", ply::T_DOUBLE, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,p) + 2*sizeof(ScalarType), 0, 0, 0, 0, 0, 0},
/*12*/ {"vertex", "quality", ply::T_DOUBLE, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,q), 0, 0, 0, 0, 0, 0}
};
return pv[i];
}
static const PropDescriptor &TetraDesc(int i)
{
const static PropDescriptor qf[10]=
{
{"tetra", "vertex_indices", ply::T_INT, ply::T_INT, offsetof(LoadPly_TetraAux,v), 1, 0, ply::T_UCHAR,ply::T_UCHAR,offsetof(LoadPly_TetraAux,size), 0},
{"tetra", "flags", ply::T_INT, ply::T_INT, offsetof(LoadPly_TetraAux,flags), 0, 0, 0, 0, 0, 0},
{"tetra", "quality", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_TetraAux,q), 0, 0, 0, 0, 0, 0},
{"tetra", "texcoord", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_TetraAux,texcoord), 1, 0, ply::T_UCHAR,ply::T_UCHAR,offsetof(LoadPly_TetraAux,ntexcoord), 0},
{"tetra", "color", ply::T_FLOAT, ply::T_FLOAT, offsetof(LoadPly_TetraAux,colors), 1, 0, ply::T_UCHAR,ply::T_UCHAR,offsetof(LoadPly_TetraAux,ncolors), 0},
{"tetra", "texnumber", ply::T_INT, ply::T_INT, offsetof(LoadPly_TetraAux,texcoordind), 0, 0, 0, 0, 0, 0},
{"tetra", "red" , ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_TetraAux,r), 0, 0, 0, 0, 0, 0},
{"tetra", "green", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_TetraAux,g), 0, 0, 0, 0, 0, 0},
{"tetra", "blue" , ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_TetraAux,b), 0, 0, 0, 0, 0, 0},
{"tetra", "alpha" , ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_TetraAux,a), 0, 0, 0, 0, 0, 0},
};
return qf[i];
}
/// Standard call for reading a mesh
static int Open( OpenMeshType &m, const char * filename, CallBackPos *cb=0)
{
PlyInfo pi;
pi.cb=cb;
return Open(m, filename, pi);
}
/// Read a mesh and store in loadmask the loaded field
static int Open( OpenMeshType &m, const char * filename, int & loadmask, CallBackPos *cb =0)
{
PlyInfo pi;
pi.mask=loadmask;
return Open(m, filename,pi);
loadmask=pi.mask;
}
/// read a mesh with all the possible option specified in the PlyInfo obj.
static int Open( OpenMeshType &m, const char * filename, PlyInfo & pi )
{
assert(filename!=0);
std::vector<VertexPointer> index;
LoadPly_TetraAux fa;
LoadPly_VertAux<ScalarType> va;
pi.mask = 0;
va.flags = 42;
pi.status = ::vcg::ply::E_NOERROR;
// The main descriptor of the ply file
vcg::ply::PlyFile pf;
// Open the file and parse the header
std::cerr << "Parsing the header.." << std::endl;
if( pf.Open(filename,vcg::ply::PlyFile::MODE_READ)== -1 )
{
pi.status = pf.GetError();
return -1;
}
std::cerr << "Parsed the header.." << std::endl;
pi.header = pf.GetHeader();
// Descrittori dati standard (vertex coord e faces)
if( pf.AddToRead(VertDesc(0)) == -1 && pf.AddToRead(VertDesc(9)) == -1 ) { pi.status = PlyInfo::E_NO_VERTEX; return pi.status; }
if( pf.AddToRead(VertDesc(1)) == -1 && pf.AddToRead(VertDesc(10)) == -1 ) { pi.status = PlyInfo::E_NO_VERTEX; return pi.status; }
if( pf.AddToRead(VertDesc(2)) == -1 && pf.AddToRead(VertDesc(11)) == -1 ) { pi.status = PlyInfo::E_NO_VERTEX; return pi.status; }
if( pf.AddToRead(TetraDesc(0)) == -1 ) { pi.status = PlyInfo::E_NO_VERTEX; return pi.status; }
// Descrittori facoltativi dei flags
if( pf.AddToRead(VertDesc(3)) != -1 )
pi.mask |= vcg::tetra::io::Mask::IOM_VERTFLAGS;
if( VertexType::HasQuality() )
{
if( pf.AddToRead(VertDesc(4)) != -1 ||
pf.AddToRead(VertDesc(9)) != -1 )
pi.mask |= vcg::tetra::io::Mask::IOM_VERTQUALITY;
}
if( VertexType::HasColor() )
{
if( pf.AddToRead(VertDesc(5))!=-1 )
{
pf.AddToRead(VertDesc(6));
pf.AddToRead(VertDesc(7));
pf.AddToRead(VertDesc(8));
pi.mask |= vcg::tetra::io::Mask::IOM_VERTCOLOR;
}
}
// se ci sono i flag per vertice ci devono essere anche i flag per faccia
if( pf.AddToRead(TetraDesc(1))!=-1 )
pi.mask |= vcg::tetra::io::Mask::IOM_TETRAFLAGS;
if( TetraType::HasQuality())
{
if( pf.AddToRead(TetraDesc(2))!=-1 )
pi.mask |= vcg::tetra::io::Mask::IOM_TETRAQUALITY;
}
if( TetraType::HasColor() )
{
if( pf.AddToRead(TetraDesc(6))!=-1 )
{
pf.AddToRead(TetraDesc(7));
pf.AddToRead(TetraDesc(8));
pf.AddToRead(TetraDesc(9));
pi.mask |= vcg::tetra::io::Mask::IOM_TETRACOLOR;
}
}
// Descrittori definiti dall'utente,
std::vector<PropDescriptor> VPV(pi.vdn); // property descriptor relative al tipo LoadPly_VertexAux
std::vector<PropDescriptor> FPV(pi.fdn); // property descriptor relative al tipo LoadPly_FaceAux
if(pi.vdn>0){
// Compute the total size needed to load additional per vertex data.
size_t totsz=0;
for(int i=0;i<pi.vdn;i++){
VPV[i] = pi.VertexData[i];
VPV[i].offset1=offsetof(LoadPly_VertAux<ScalarType>,data)+totsz;
totsz+=pi.VertexData[i].memtypesize();
if( pf.AddToRead(VPV[i])==-1 ) { pi.status = pf.GetError(); return -1; }
}
if(totsz > MAX_USER_DATA)
{
pi.status = vcg::ply::E_BADTYPE;
return -1;
}
}
if(pi.fdn>0){
size_t totsz=0;
for(int i=0;i<pi.fdn;i++){
FPV[i] = pi.TetraData[i];
FPV[i].offset1=offsetof(LoadPly_TetraAux,data)+totsz;
totsz+=pi.TetraData[i].memtypesize();
if( pf.AddToRead(FPV[i])==-1 ) { pi.status = pf.GetError(); return -1; }
}
if(totsz > MAX_USER_DATA)
{
pi.status = vcg::ply::E_BADTYPE;
return -1;
}
}
/**************************************************************/
/* Main Reading Loop */
/**************************************************************/
m.Clear();
for(int i=0;i<int(pf.elements.size());i++)
{
int n = pf.ElemNumber(i);
if( !strcmp( pf.ElemName(i),"vertex" ) )
{
int j;
pf.SetCurElement(i);
VertexIterator vi=vcg::tri::Allocator<OpenMeshType>::AddVertices(m,n);
for(j=0;j<n;++j)
{
if(pi.cb && (j%1000)==0) pi.cb(j*50/n,"Vertex Loading");
if( pf.Read( (void *)&(va) )==-1 )
{
pi.status = PlyInfo::E_SHORTFILE;
return -1;
}
(*vi).P()[0] = va.p[0];
(*vi).P()[1] = va.p[1];
(*vi).P()[2] = va.p[2];
if( pi.mask & vcg::tetra::io::Mask::IOM_VERTFLAGS )
(*vi).Flags() = va.flags;
if( pi.mask & vcg::tetra::io::Mask::IOM_VERTQUALITY )
(*vi).Q() = va.q;
if( pi.mask & vcg::tetra::io::Mask::IOM_VERTCOLOR )
{
(*vi).C()[0] = va.r;
(*vi).C()[1] = va.g;
(*vi).C()[2] = va.b;
(*vi).C()[3] = va.a;
}
for(int k=0;k<pi.vdn;k++)
memcpy((char *)(&*vi) + pi.VertexData[k].offset1,
(char *)(&va) + VPV[k].offset1,
VPV[k].memtypesize());
++vi;
}
index.resize(n);
for(j=0,vi=m.vert.begin();j<n;++j,++vi)
index[j] = &*vi;
}
else if( !strcmp( pf.ElemName(i),"tetra") )/************************************************************/
{
int j;
int k;
TetraIterator ti = vcg::tri::Allocator<OpenMeshType>::AddTetras(m, n);
pf.SetCurElement(i);
for(j=0;j<n;++j)
{
if(pi.cb && (j%1000)==0) pi.cb(50+j*50/n,"Tetra Loading");
if( pf.Read(&fa)==-1 )
{
pi.status = PlyInfo::E_SHORTFILE;
return -1;
}
if(fa.size!=4)
{
pi.status = PlyInfo::E_NO_3VERTINFACE;
return -1;
}
for(k=0;k<4;++k)
{
if( fa.v[k]<0 || fa.v[k]>=m.vn )
{
pi.status = PlyInfo::E_BAD_VERT_INDEX;
return -1;
}
(*ti).V(k) = index[ fa.v[k] ];
}
if( pi.mask & vcg::tetra::io::Mask::IOM_TETRAFLAGS )
{
(*ti).Flags() = fa.flags;
}
if( pi.mask & vcg::tetra::io::Mask::IOM_TETRAQUALITY )
{
(*ti).Q() = fa.q;
}
if( pi.mask & vcg::tetra::io::Mask::IOM_TETRACOLOR )
{
(*ti).C()[0] = fa.r;
(*ti).C()[1] = fa.g;
(*ti).C()[2] = fa.b;
(*ti).C()[3] = fa.a;
}
++ti;
}
for(k=0;k<pi.fdn;k++)
memcpy((char *)(&(*ti)) + pi.TetraData[k].offset1,
(char *)(&fa) + FPV[k].offset1,
FPV[k].memtypesize());
}
else
{
// Skippaggio elementi non gestiti
int n = pf.ElemNumber(i);
pf.SetCurElement(i);
for(int j=0;j<n;j++)
{
if( pf.Read(0)==-1)
{
pi.status = PlyInfo::E_SHORTFILE;
return -1;
}
}
}
}
// // Parsing texture names
//textures.clear();
//normalmaps.clear();
//for(int co=0;co<int(pf.comments.size());++co)
//{
// const char * TFILE = "TextureFile";
// const char * NFILE = "TextureNormalFile";
// const char * c = pf.comments[co];
// char buf[256];
// int i,j,n;
// if( !strncmp(c,TFILE,strlen(TFILE)) )
// {
// strcpy(buf,c+strlen(TFILE)+1);
// n = strlen(buf);
// for(i=j=0;i<n;i++)
// if( buf[i]!=' ' && buf[i]!='\t' && buf[i]>32 && buf[i]<125 ) buf[j++] = buf[i];
//
// buf[j] = 0;
// char buf2[255];
// __interpret_texture_name( buf,filename,buf2 );
// textures.push_back( xstring(buf2) );
// }
// if( !strncmp(c,NFILE,strlen(NFILE)) )
// {
// strcpy(buf,c+strlen(NFILE)+1);
// n = strlen(buf);
// for(i=j=0;i<n;i++)
// if( buf[i]!=' ' && buf[i]!='\t' && buf[i]>32 && buf[i]<125 ) buf[j++] = buf[i];
//
// buf[j] = 0;
// char buf2[255];
// __interpret_texture_name( buf,filename,buf2 );
// normalmaps.push_back( xstring(buf2) );
// }
//}
// vn and fn should be correct but if someone wrongly saved some deleted elements they can be wrong.
m.vn = 0;
VertexIterator vi;
for(vi=m.vert.begin();vi!=m.vert.end();++vi)
if( ! (*vi).IsD() )
++m.vn;
m.tn = 0;
TetraIterator fi;
for(fi=m.tetra.begin();fi!=m.tetra.end();++fi)
if( ! (*fi).IsD() )
++m.tn;
return 0;
}
// // Caricamento camera da un ply
// int LoadCamera(const char * filename)
// {
// vcg::ply::PlyFile pf;
// if( pf.Open(filename,vcg::ply::PlyFile::MODE_READ)==-1 )
// {
// pi.status = pf.GetError();
// return -1;
// }
// bool found = true;
// int i;
// for(i=0;i<23;++i)
// {
// if( pf.AddToRead(CameraDesc(i))==-1 )
// {
// found = false;
// break;
// }
// }
// if(!found)
// return -1;
// for(i=0;i<int(pf.elements.size());i++)
// {
// int n = pf.ElemNumber(i);
// if( !strcmp( pf.ElemName(i),"camera" ) )
// {
// pf.SetCurElement(i);
// //LoadPly_Camera ca;
// for(int j=0;j<n;++j)
// {
// if( pf.Read( (void *)&(ca) )==-1 )
// {
// pi.status = PlyInfo::E_SHORTFILE;
// return -1;
// }
// camera.valid = true;
// camera.view_p[0] = ca.view_px;
// camera.view_p[1] = ca.view_py;
// camera.view_p[2] = ca.view_pz;
// camera.x_axis[0] = ca.x_axisx;
// camera.x_axis[1] = ca.x_axisy;
// camera.x_axis[2] = ca.x_axisz;
// camera.y_axis[0] = ca.y_axisx;
// camera.y_axis[1] = ca.y_axisy;
// camera.y_axis[2] = ca.y_axisz;
// camera.z_axis[0] = ca.z_axisx;
// camera.z_axis[1] = ca.z_axisy;
// camera.z_axis[2] = ca.z_axisz;
// camera.f = ca.focal;
// camera.s[0] = ca.scalex;
// camera.s[1] = ca.scaley;
// camera.c[0] = ca.centerx;
// camera.c[1] = ca.centery;
// camera.viewport[0] = ca.viewportx;
// camera.viewport[1] = ca.viewporty;
// camera.k[0] = ca.k1;
// camera.k[1] = ca.k2;
// camera.k[2] = ca.k3;
// camera.k[3] = ca.k4;
// }
// break;
// }
// }
// return 0;
// }
static bool LoadMask(const char * filename, int &mask)
{
PlyInfo pi;
return LoadMask(filename, mask, pi);
}
static bool LoadMask(const char * filename, int &mask, PlyInfo &pi)
{
mask=0;
vcg::ply::PlyFile pf;
if( pf.Open(filename,vcg::ply::PlyFile::MODE_READ)==-1 )
{
pi.status = pf.GetError();
return false;
}
if( pf.AddToRead(VertDesc(0))!=-1 &&
pf.AddToRead(VertDesc(1))!=-1 &&
pf.AddToRead(VertDesc(2))!=-1 )
mask |= vcg::tetra::io::Mask::IOM_VERTCOORD;
if( pf.AddToRead(VertDesc(3))!=-1 )
mask |= vcg::tetra::io::Mask::IOM_VERTFLAGS;
if( pf.AddToRead(VertDesc(4))!=-1 )
mask |= vcg::tetra::io::Mask::IOM_VERTQUALITY;
if( ( pf.AddToRead(VertDesc(5))!=-1 ) &&
( pf.AddToRead(VertDesc(6))!=-1 ) &&
( pf.AddToRead(VertDesc(7))!=-1 ) &&
( pf.AddToRead(VertDesc(8))!=-1 ))
mask |= vcg::tetra::io::Mask::IOM_VERTCOLOR;
if( pf.AddToRead(TetraDesc(0))!=-1 )
mask |= vcg::tetra::io::Mask::IOM_TETRAINDEX;
if( pf.AddToRead(TetraDesc(1))!=-1 )
mask |= vcg::tetra::io::Mask::IOM_TETRAFLAGS;
if( pf.AddToRead(TetraDesc(2))!=-1 )
mask |= vcg::tetra::io::Mask::IOM_TETRAQUALITY;
if( ( pf.AddToRead(TetraDesc(6))!=-1 ) &&
( pf.AddToRead(TetraDesc(7))!=-1 ) &&
( pf.AddToRead(TetraDesc(8))!=-1 ) &&
( pf.AddToRead(TetraDesc(9))!=-1 ))
mask |= vcg::tetra::io::Mask::IOM_TETRACOLOR;
return true;
}
}; // end class
} // end namespace tri
} // end namespace io
} // end namespace vcg
#endif
+109
View File
@@ -0,0 +1,109 @@
/****************************************************************************
* MeshLab o o *
* An extendible mesh processor o o *
* _ O _ *
* Copyright(C) 2005, 2009 \/)\/ *
* 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. *
* *
****************************************************************************/
#ifndef __VCGLIB_IMPORTERTS
#define __VCGLIB_IMPORTERTS
#define NULL 0
#include <vcg/space/point3.h>
#include <vcg/space/point4.h>
namespace vcg {
namespace tetra {
namespace io {
template <typename MESHTYPE>
class ImporterTS{
typedef MESHTYPE Tetramesh;
typedef typename Tetramesh::VertexPointer VertexPointer;
typedef typename Tetramesh::VertexType VertexType;
typedef typename Tetramesh::TetraType FaceType;
typedef typename Tetramesh::VertexIterator VertexIterator;
typedef typename Tetramesh::TetraIterator FaceIterator;
typedef typename Tetramesh::ScalarType ScalarType;
typedef Point3<ScalarType> Point3x;
static FILE *& F(){static FILE * f; return f;}
inline static void ReadPos( Point3<double> &p){
fscanf(F(),"%lg %lg %lg",&p[0],&p[1],&p[2]);
}
inline static void ReadPos( Point3<float> &p){
fscanf(F(),"%f %f %f",&p[0],&p[1],&p[2]);
}
inline static void ReadPos( Point4<ScalarType> &p){
fscanf(F(),"%g %g %g %g",&p[0],&p[1],&p[2],&p[3]);
}
public:
static int Open( Tetramesh & m, const char * filename )
{
int nvertex;
int ntetra;
int tp0;
int tp1;
int tp2;
int tp3;
typename Tetramesh::VertexType p1;
F() = fopen(filename,"r");
if(F() == NULL )
{
printf( "The file was not opened\n" );
return -1;
}
else
{
fscanf(F(), "%i", &nvertex );
fscanf(F(), "%i", &ntetra );
m.tetra.reserve(ntetra);
m.vert.reserve(nvertex);
int j;
for (j=0;j<nvertex;j++)
{
m.vert.push_back(VertexType());
ReadPos(m.vert.back().P());
m.vert.back().ClearFlags();
}
for (j=0;j<ntetra;j++)
{
fscanf(F(), "%i", &tp0 );
fscanf(F(), "%i", &tp1 );
fscanf(F(), "%i", &tp2 );
fscanf(F(), "%i", &tp3 );
m.tetra.push_back(typename Tetramesh::TetraType());
m.tetra.back().V(0) = &m.vert[tp0];
m.tetra.back().V(1) = &m.vert[tp1];
m.tetra.back().V(2) = &m.vert[tp2];
m.tetra.back().V(3) = &m.vert[tp3];
m.tetra.back().Flags() = 0;
}
}
m.vn = nvertex;
m.tn = ntetra;
return 0;
}
};// end class
}// end of io
}// end of tetra
}// end of vcg
#endif
+80
View File
@@ -0,0 +1,80 @@
/****************************************************************************
* 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. *
* *
****************************************************************************/
#ifndef __VCGLIB_IOTETRAMESH_IO_MASK
#define __VCGLIB_IOTETRAMESH_IO_MASK
namespace vcg {
namespace tetra {
namespace io {
/**
@name Input/output data mask
*/
//@{
class Mask
{
public:
/*
Bitmask for specifying what data has to be loaded or saved or it is present in a given plyfile;
*/
enum {
IOM_NONE = 0x00000,
IOM_VERTCOORD = 0x00001,
IOM_VERTFLAGS = 0x00002,
IOM_VERTCOLOR = 0x00004,
IOM_VERTQUALITY = 0x00008,
IOM_VERTRADIUS = 0x10000,
IOM_EDGEINDEX = 0x80000,
IOM_TETRAINDEX = 0x00010,
IOM_TETRAFLAGS = 0x00020,
IOM_TETRACOLOR = 0x00040,
IOM_TETRAQUALITY = 0x00080,
IOM_CAMERA = 0x08000,
IOM_FLAGS = IOM_VERTFLAGS + IOM_TETRAFLAGS,
IOM_ALL = 0xFFFFF
};
template <class MeshType>
static void ClampMask(MeshType &m, int &mask)
{
if( (mask & IOM_TETRACOLOR) && !HasPerTetraColor(m) ) mask = mask & (~IOM_TETRACOLOR);
if( (mask & IOM_VERTCOLOR) && !HasPerVertexColor(m) ) mask = mask & (~IOM_VERTCOLOR);
}
}; // end class
//@}
} // end namespace tetra
} // end namespace io
} // end namespace vcg
#endif
+113
View File
@@ -0,0 +1,113 @@
/****************************************************************************
* 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. *
* *
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
Revision 1.3 2004/05/12 10:19:30 ganovelli
new line added at the end of file
Revision 1.2 2004/03/09 21:26:47 cignoni
cr lf mismatch
Revision 1.1 2004/03/08 09:21:34 cignoni
Initial commit
Revision 1.1 2004/03/03 15:00:51 cignoni
Initial commit
****************************************************************************/
#ifndef __VCGLIB_IOTETRAMESH_IO_PLY
#define __VCGLIB_IOTETRAMESH_IO_PLY
/**
@name Load and Save in Ply format
*/
//@{
#include<wrap/callback.h>
#include<wrap/ply/plylib.h>
namespace vcg {
namespace tetra {
namespace io {
/** Additional data needed or useful for parsing a ply mesh.
This class can be passed to the ImporterPLY::Open() function for
- retrieving additional per-vertex per-tetra data
- specifying a callback for long ply parsing
- knowing what data is contained in a ply file
*/
class PlyInfo
{
public:
typedef ::vcg::ply::PropDescriptor PropDescriptor ;
PlyInfo()
{
status=0;
mask=0;
cb=0;
vdn=fdn=0;
VertexData=TetraData=0;
}
/// Store the error codes enconutered when parsing a ply
int status;
/// It returns a bit mask describing the field present in the ply file
int mask;
/// a Simple callback that can be used for long ply parsing.
// it returns the current position, and formats a string with a description of what th efunction is doing (loading vertexes, faces...)
CallBackPos *cb;
/// the number of per-vertex descriptor (usually 0)
int vdn;
/// The additional vertex descriptor that a user can specify to load additional per-vertex non-standard data stored in a ply
PropDescriptor *VertexData;
/// the number of per-face descriptor (usually 0)
int fdn;
/// The additional vertex descriptor that a user can specify to load additional per-face non-standard data stored in a ply
PropDescriptor *TetraData;
/// a string containing the current ply header. Useful for showing it to the user.
std::string header;
enum Error
{
// Funzioni superiori
E_NO_VERTEX, // 14
E_NO_FACE, // 15
E_SHORTFILE, // 16
E_NO_3VERTINFACE, // 17
E_BAD_VERT_INDEX, // 18
E_NO_6TCOORD, // 19
E_DIFFER_COLORS, // 20
};
}; // end class
} // end namespace tri
} // end namespace io
} // end namespace vcg
#endif