add vcglib
This commit is contained in:
1 parent
6f6c0c8eb7
commit
af8100f851
1537 files changed
+634197
No files matched your search
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in new issue
Block a user