Added support of attributes in saving of ply
with an easy to use AddPerVertexFloatAttribute helper
This commit is contained in:
parent
2341123df5
commit
fe69d16df4
|
|
@ -96,7 +96,6 @@ namespace vcg {
|
||||||
static int Save(SaveMeshType &m, const char * filename, bool binary, PlyInfo &pi, CallBackPos *cb=0) // V1.0
|
static int Save(SaveMeshType &m, const char * filename, bool binary, PlyInfo &pi, CallBackPos *cb=0) // V1.0
|
||||||
{
|
{
|
||||||
FILE * fpout;
|
FILE * fpout;
|
||||||
int i;
|
|
||||||
const char * hbin = "binary_little_endian";
|
const char * hbin = "binary_little_endian";
|
||||||
const char * hasc = "ascii";
|
const char * hasc = "ascii";
|
||||||
const char * h;
|
const char * h;
|
||||||
|
|
@ -127,7 +126,7 @@ namespace vcg {
|
||||||
{
|
{
|
||||||
const char * TFILE = "TextureFile";
|
const char * TFILE = "TextureFile";
|
||||||
|
|
||||||
for(i=0; i < static_cast<int>(m.textures.size()); ++i)
|
for(size_t i=0; i < m.textures.size(); ++i)
|
||||||
fprintf(fpout,"comment %s %s\n", TFILE, (const char *)(m.textures[i].c_str()) );
|
fprintf(fpout,"comment %s %s\n", TFILE, (const char *)(m.textures[i].c_str()) );
|
||||||
|
|
||||||
if(m.textures.size()>1 && (HasPerWedgeTexCoord(m) || HasPerVertexTexCoord(m))) multit = true;
|
if(m.textures.size()>1 && (HasPerWedgeTexCoord(m) || HasPerVertexTexCoord(m))) multit = true;
|
||||||
|
|
@ -211,8 +210,8 @@ namespace vcg {
|
||||||
"property float texture_v\n"
|
"property float texture_v\n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
for(i=0;i<pi.vdn;i++)
|
for(size_t i=0;i<pi.VertDescriptorVec.size();i++)
|
||||||
fprintf(fpout,"property %s %s\n",pi.VertexData[i].stotypename(),pi.VertexData[i].propname);
|
fprintf(fpout,"property %s %s\n",pi.VertDescriptorVec[i].stotypename(),pi.VertDescriptorVec[i].propname);
|
||||||
|
|
||||||
fprintf(fpout,
|
fprintf(fpout,
|
||||||
"element face %d\n"
|
"element face %d\n"
|
||||||
|
|
@ -226,13 +225,17 @@ namespace vcg {
|
||||||
"property int flags\n"
|
"property int flags\n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
// Note that you can save VT as WT if you really want it...
|
||||||
if( (HasPerWedgeTexCoord(m) || HasPerVertexTexCoord(m) ) && pi.mask & Mask::IOM_WEDGTEXCOORD ) // Note that you can save VT as WT if you really want it...
|
if( (HasPerWedgeTexCoord(m) || HasPerVertexTexCoord(m) ) && pi.mask & Mask::IOM_WEDGTEXCOORD )
|
||||||
{
|
{
|
||||||
fprintf(fpout,
|
fprintf(fpout,
|
||||||
"property list uchar float texcoord\n"
|
"property list uchar float texcoord\n"
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
// The per-face texture index information has to be saved (if necessary) both for PerVert and PerWedg
|
||||||
|
if( ( HasPerWedgeTexCoord(m) || HasPerVertexTexCoord(m) ) &&
|
||||||
|
( (pi.mask & Mask::IOM_WEDGTEXCOORD) || (pi.mask & Mask::IOM_VERTTEXCOORD ) ) )
|
||||||
|
{
|
||||||
if(multit)
|
if(multit)
|
||||||
fprintf(fpout,
|
fprintf(fpout,
|
||||||
"property int texnumber\n"
|
"property int texnumber\n"
|
||||||
|
|
@ -262,8 +265,8 @@ namespace vcg {
|
||||||
fprintf(fpout,"property %s quality\n",fqtp);
|
fprintf(fpout,"property %s quality\n",fqtp);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i=0;i<pi.fdn;i++)
|
for(size_t i=0;i<pi.FaceDescriptorVec.size();i++)
|
||||||
fprintf(fpout,"property %s %s\n",pi.FaceData[i].stotypename(),pi.FaceData[i].propname);
|
fprintf(fpout,"property %s %s\n",pi.FaceDescriptorVec[i].stotypename(),pi.FaceDescriptorVec[i].propname);
|
||||||
// Saving of edges is enabled if requested
|
// Saving of edges is enabled if requested
|
||||||
if( m.en>0 && (pi.mask & Mask::IOM_EDGEINDEX) )
|
if( m.en>0 && (pi.mask & Mask::IOM_EDGEINDEX) )
|
||||||
fprintf(fpout,
|
fprintf(fpout,
|
||||||
|
|
@ -345,6 +348,58 @@ namespace vcg {
|
||||||
VertexIterator vi;
|
VertexIterator vi;
|
||||||
SimpleTempData<typename SaveMeshType::VertContainer,int> indices(m.vert);
|
SimpleTempData<typename SaveMeshType::VertContainer,int> indices(m.vert);
|
||||||
|
|
||||||
|
std::vector<typename SaveMeshType:: template PerVertexAttributeHandle<float > > thfv(pi.VertDescriptorVec.size());
|
||||||
|
std::vector<typename SaveMeshType:: template PerVertexAttributeHandle<double> > thdv(pi.VertDescriptorVec.size());
|
||||||
|
std::vector<typename SaveMeshType:: template PerVertexAttributeHandle<int > > thiv(pi.VertDescriptorVec.size());
|
||||||
|
std::vector<typename SaveMeshType:: template PerVertexAttributeHandle<short > > thsv(pi.VertDescriptorVec.size());
|
||||||
|
std::vector<typename SaveMeshType:: template PerVertexAttributeHandle<char > > thcv(pi.VertDescriptorVec.size());
|
||||||
|
std::vector<typename SaveMeshType:: template PerVertexAttributeHandle<unsigned char> > thuv(pi.VertDescriptorVec.size());
|
||||||
|
|
||||||
|
for(size_t i=0;i<pi.VertDescriptorVec.size();i++)
|
||||||
|
{
|
||||||
|
if(!pi.VertAttrNameVec.empty() && !pi.VertAttrNameVec[i].empty())
|
||||||
|
{ // trying to use named attribute to retrieve the value to store
|
||||||
|
assert(vcg::tri::HasPerVertexAttribute(m,pi.VertAttrNameVec[i]));
|
||||||
|
switch (pi.VertDescriptorVec[i].stotype1)
|
||||||
|
{
|
||||||
|
case ply::T_FLOAT : thfv[i] = vcg::tri::Allocator<SaveMeshType>::template FindPerVertexAttribute<float>(m,pi.VertAttrNameVec[i]); break;
|
||||||
|
case ply::T_DOUBLE : thdv[i] = vcg::tri::Allocator<SaveMeshType>::template FindPerVertexAttribute<double>(m,pi.VertAttrNameVec[i]); break;
|
||||||
|
case ply::T_INT : thiv[i] = vcg::tri::Allocator<SaveMeshType>::template FindPerVertexAttribute<int >(m,pi.VertAttrNameVec[i]); break;
|
||||||
|
case ply::T_SHORT : thsv[i] = vcg::tri::Allocator<SaveMeshType>::template FindPerVertexAttribute<short >(m,pi.VertAttrNameVec[i]); break;
|
||||||
|
case ply::T_CHAR : thcv[i] = vcg::tri::Allocator<SaveMeshType>::template FindPerVertexAttribute<char>(m,pi.VertAttrNameVec[i]); break;
|
||||||
|
case ply::T_UCHAR : thuv[i] = vcg::tri::Allocator<SaveMeshType>::template FindPerVertexAttribute<unsigned char>(m,pi.VertAttrNameVec[i]); break;
|
||||||
|
default : assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::vector<typename SaveMeshType:: template PerFaceAttributeHandle<float > > thff(pi.FaceDescriptorVec.size());
|
||||||
|
std::vector<typename SaveMeshType:: template PerFaceAttributeHandle<double> > thdf(pi.FaceDescriptorVec.size());
|
||||||
|
std::vector<typename SaveMeshType:: template PerFaceAttributeHandle<int > > thif(pi.FaceDescriptorVec.size());
|
||||||
|
std::vector<typename SaveMeshType:: template PerFaceAttributeHandle<short > > thsf(pi.FaceDescriptorVec.size());
|
||||||
|
std::vector<typename SaveMeshType:: template PerFaceAttributeHandle<char > > thcf(pi.FaceDescriptorVec.size());
|
||||||
|
std::vector<typename SaveMeshType:: template PerFaceAttributeHandle<unsigned char> > thuf(pi.FaceDescriptorVec.size());
|
||||||
|
|
||||||
|
for(size_t i=0;i<pi.FaceDescriptorVec.size();i++)
|
||||||
|
{
|
||||||
|
if(!pi.FaceAttrNameVec.empty() && !pi.FaceAttrNameVec[i].empty())
|
||||||
|
{ // trying to use named attribute to retrieve the value to store
|
||||||
|
assert(vcg::tri::HasPerFaceAttribute(m,pi.FaceAttrNameVec[i]));
|
||||||
|
switch (pi.FaceDescriptorVec[i].stotype1)
|
||||||
|
{
|
||||||
|
case ply::T_FLOAT : thff[i] = vcg::tri::Allocator<SaveMeshType>::template FindPerFaceAttribute<float>(m,pi.FaceAttrNameVec[i]); break;
|
||||||
|
case ply::T_DOUBLE : thdf[i] = vcg::tri::Allocator<SaveMeshType>::template FindPerFaceAttribute<double>(m,pi.FaceAttrNameVec[i]); break;
|
||||||
|
case ply::T_INT : thif[i] = vcg::tri::Allocator<SaveMeshType>::template FindPerFaceAttribute<int >(m,pi.FaceAttrNameVec[i]); break;
|
||||||
|
case ply::T_SHORT : thsf[i] = vcg::tri::Allocator<SaveMeshType>::template FindPerFaceAttribute<short >(m,pi.FaceAttrNameVec[i]); break;
|
||||||
|
case ply::T_CHAR : thcf[i] = vcg::tri::Allocator<SaveMeshType>::template FindPerFaceAttribute<char>(m,pi.FaceAttrNameVec[i]); break;
|
||||||
|
case ply::T_UCHAR : thuf[i] = vcg::tri::Allocator<SaveMeshType>::template FindPerFaceAttribute<unsigned char>(m,pi.FaceAttrNameVec[i]); break;
|
||||||
|
default : assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for(j=0,vi=m.vert.begin();vi!=m.vert.end();++vi){
|
for(j=0,vi=m.vert.begin();vi!=m.vert.end();++vi){
|
||||||
vp=&(*vi);
|
vp=&(*vi);
|
||||||
indices[vi] = j;
|
indices[vi] = j;
|
||||||
|
|
@ -381,22 +436,39 @@ namespace vcg {
|
||||||
|
|
||||||
if( HasPerVertexTexCoord(m) && (pi.mask & Mask::IOM_VERTTEXCOORD) )
|
if( HasPerVertexTexCoord(m) && (pi.mask & Mask::IOM_VERTTEXCOORD) )
|
||||||
{
|
{
|
||||||
t = float(vp->T().u()); fwrite(&t,sizeof(float),1,fpout);
|
t = ScalarType(vp->T().u()); fwrite(&t,sizeof(ScalarType),1,fpout);
|
||||||
t = float(vp->T().v()); fwrite(&t,sizeof(float),1,fpout);
|
t = ScalarType(vp->T().v()); fwrite(&t,sizeof(ScalarType),1,fpout);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i=0;i<pi.vdn;i++)
|
for(size_t i=0;i<pi.VertDescriptorVec.size();i++)
|
||||||
{
|
{
|
||||||
double td(0); float tf(0);int ti;short ts; char tc; unsigned char tuc;
|
double td(0); float tf(0);int ti;short ts; char tc; unsigned char tu;
|
||||||
switch (pi.VertexData[i].stotype1)
|
if(!pi.VertAttrNameVec.empty() && !pi.VertAttrNameVec[i].empty())
|
||||||
|
{ // trying to use named attribute to retrieve the value to store
|
||||||
|
assert(vcg::tri::HasPerVertexAttribute(m,pi.VertAttrNameVec[i]));
|
||||||
|
switch (pi.VertDescriptorVec[i].stotype1)
|
||||||
|
{
|
||||||
|
case ply::T_FLOAT : tf=thfv[i][vp]; fwrite(&tf, sizeof(float),1,fpout); break;
|
||||||
|
case ply::T_DOUBLE : td=thdv[i][vp]; fwrite(&td, sizeof(double),1,fpout); break;
|
||||||
|
case ply::T_INT : ti=thiv[i][vp]; fwrite(&ti, sizeof(int),1,fpout); break;
|
||||||
|
case ply::T_SHORT : ts=thsv[i][vp]; fwrite(&ts, sizeof(short),1,fpout); break;
|
||||||
|
case ply::T_CHAR : tc=thcv[i][vp]; fwrite(&tc, sizeof(char),1,fpout); break;
|
||||||
|
case ply::T_UCHAR : tu=thuv[i][vp]; fwrite(&tu,sizeof(unsigned char),1,fpout); break;
|
||||||
|
default : assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
case ply::T_FLOAT : PlyConv(pi.VertexData[i].memtype1, ((char *)vp)+pi.VertexData[i].offset1, tf ); fwrite(&tf, sizeof(float),1,fpout); break;
|
switch (pi.VertDescriptorVec[i].stotype1)
|
||||||
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_FLOAT : PlyConv(pi.VertDescriptorVec[i].memtype1, ((char *)vp)+pi.VertDescriptorVec[i].offset1, tf ); fwrite(&tf, sizeof(float),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_DOUBLE : PlyConv(pi.VertDescriptorVec[i].memtype1, ((char *)vp)+pi.VertDescriptorVec[i].offset1, td ); fwrite(&td, sizeof(double),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_INT : PlyConv(pi.VertDescriptorVec[i].memtype1, ((char *)vp)+pi.VertDescriptorVec[i].offset1, ti ); fwrite(&ti, sizeof(int),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;
|
case ply::T_SHORT : PlyConv(pi.VertDescriptorVec[i].memtype1, ((char *)vp)+pi.VertDescriptorVec[i].offset1, ts ); fwrite(&ts, sizeof(short),1,fpout); break;
|
||||||
default : assert(0);
|
case ply::T_CHAR : PlyConv(pi.VertDescriptorVec[i].memtype1, ((char *)vp)+pi.VertDescriptorVec[i].offset1, tc ); fwrite(&tc, sizeof(char),1,fpout); break;
|
||||||
|
case ply::T_UCHAR : PlyConv(pi.VertDescriptorVec[i].memtype1, ((char *)vp)+pi.VertDescriptorVec[i].offset1, tu ); fwrite(&tu,sizeof(unsigned char),1,fpout); break;
|
||||||
|
default : assert(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -422,19 +494,35 @@ namespace vcg {
|
||||||
if( HasPerVertexTexCoord(m) && (pi.mask & Mask::IOM_VERTTEXCOORD) )
|
if( HasPerVertexTexCoord(m) && (pi.mask & Mask::IOM_VERTTEXCOORD) )
|
||||||
fprintf(fpout,"%f %f",vp->T().u(),vp->T().v());
|
fprintf(fpout,"%f %f",vp->T().u(),vp->T().v());
|
||||||
|
|
||||||
for(i=0;i<pi.vdn;i++)
|
for(size_t i=0;i<pi.VertDescriptorVec.size();i++)
|
||||||
{
|
{
|
||||||
float tf(0); double td(0);
|
float tf(0); double td(0); int ti;
|
||||||
int ti;
|
if(!pi.VertAttrNameVec.empty() && !pi.VertAttrNameVec[i].empty())
|
||||||
switch (pi.VertexData[i].memtype1)
|
{ // trying to use named attribute to retrieve the value to store
|
||||||
|
assert(vcg::tri::HasPerVertexAttribute(m,pi.VertAttrNameVec[i]));
|
||||||
|
switch (pi.VertDescriptorVec[i].stotype1)
|
||||||
|
{
|
||||||
|
case ply::T_FLOAT : tf=thfv[i][vp]; fprintf(fpout,"%f ",tf); break;
|
||||||
|
case ply::T_DOUBLE : td=thdv[i][vp]; fprintf(fpout,"%lf ",td); break;
|
||||||
|
case ply::T_INT : ti=thiv[i][vp]; fprintf(fpout,"%i ",ti); break;
|
||||||
|
case ply::T_SHORT : ti=thsv[i][vp]; fprintf(fpout,"%i ",ti); break;
|
||||||
|
case ply::T_CHAR : ti=thcv[i][vp]; fprintf(fpout,"%i ",ti); break;
|
||||||
|
case ply::T_UCHAR : ti=thuv[i][vp]; fprintf(fpout,"%i ",ti); break;
|
||||||
|
default : assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
case ply::T_FLOAT : tf=*( (float *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%f ",tf); break;
|
switch (pi.VertDescriptorVec[i].memtype1)
|
||||||
case ply::T_DOUBLE : td=*( (double *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%f ",tf); break;
|
{
|
||||||
case ply::T_INT : ti=*( (int *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%i ",ti); break;
|
case ply::T_FLOAT : tf=*( (float *) (((char *)vp)+pi.VertDescriptorVec[i].offset1)); fprintf(fpout,"%f ",tf); break;
|
||||||
case ply::T_SHORT : ti=*( (short *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%i ",ti); break;
|
case ply::T_DOUBLE : td=*( (double *) (((char *)vp)+pi.VertDescriptorVec[i].offset1)); fprintf(fpout,"%f ",tf); break;
|
||||||
case ply::T_CHAR : ti=*( (char *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%i ",ti); break;
|
case ply::T_INT : ti=*( (int *) (((char *)vp)+pi.VertDescriptorVec[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;
|
case ply::T_SHORT : ti=*( (short *) (((char *)vp)+pi.VertDescriptorVec[i].offset1)); fprintf(fpout,"%i ",ti); break;
|
||||||
default : assert(0);
|
case ply::T_CHAR : ti=*( (char *) (((char *)vp)+pi.VertDescriptorVec[i].offset1)); fprintf(fpout,"%i ",ti); break;
|
||||||
|
case ply::T_UCHAR : ti=*( (unsigned char *) (((char *)vp)+pi.VertDescriptorVec[i].offset1)); fprintf(fpout,"%i ",ti); break;
|
||||||
|
default : assert(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -524,17 +612,34 @@ namespace vcg {
|
||||||
fwrite( &(fp->Q()),sizeof(typename FaceType::ScalarType),1,fpout);
|
fwrite( &(fp->Q()),sizeof(typename FaceType::ScalarType),1,fpout);
|
||||||
|
|
||||||
|
|
||||||
for(i=0;i<pi.fdn;i++)
|
for(size_t i=0;i<pi.FaceDescriptorVec.size();i++)
|
||||||
{
|
{
|
||||||
double td(0); float tf(0);int ti;short ts; char tc; unsigned char tuc;
|
double td(0); float tf(0);int ti;short ts; char tc; unsigned char tu;
|
||||||
switch (pi.FaceData[i].stotype1){
|
if(!pi.FaceAttrNameVec.empty() && !pi.FaceAttrNameVec[i].empty())
|
||||||
case ply::T_FLOAT : PlyConv(pi.FaceData[i].memtype1, ((char *)fp)+pi.FaceData[i].offset1, tf ); fwrite(&tf, sizeof(float),1,fpout); break;
|
{ // trying to use named attribute to retrieve the value to store
|
||||||
case ply::T_DOUBLE : PlyConv(pi.FaceData[i].memtype1, ((char *)fp)+pi.FaceData[i].offset1, td ); fwrite(&td, sizeof(double),1,fpout); break;
|
assert(vcg::tri::HasPerFaceAttribute(m,pi.FaceAttrNameVec[i]));
|
||||||
case ply::T_INT : PlyConv(pi.FaceData[i].memtype1, ((char *)fp)+pi.FaceData[i].offset1, ti ); fwrite(&ti, sizeof(int),1,fpout); break;
|
switch (pi.FaceDescriptorVec[i].stotype1)
|
||||||
case ply::T_SHORT : PlyConv(pi.FaceData[i].memtype1, ((char *)fp)+pi.FaceData[i].offset1, ts ); fwrite(&ts, sizeof(short),1,fpout); break;
|
{
|
||||||
case ply::T_CHAR : PlyConv(pi.FaceData[i].memtype1, ((char *)fp)+pi.FaceData[i].offset1, tc ); fwrite(&tc, sizeof(char),1,fpout); break;
|
case ply::T_FLOAT : tf=thff[i][fp]; fwrite(&tf, sizeof(float),1,fpout); break;
|
||||||
case ply::T_UCHAR : PlyConv(pi.FaceData[i].memtype1, ((char *)fp)+pi.FaceData[i].offset1, tuc); fwrite(&tuc,sizeof(unsigned char),1,fpout); break;
|
case ply::T_DOUBLE : td=thdf[i][fp]; fwrite(&td, sizeof(double),1,fpout); break;
|
||||||
default : assert(0);
|
case ply::T_INT : ti=thif[i][fp]; fwrite(&ti, sizeof(int),1,fpout); break;
|
||||||
|
case ply::T_SHORT : ts=thsf[i][fp]; fwrite(&ts, sizeof(short),1,fpout); break;
|
||||||
|
case ply::T_CHAR : tc=thcf[i][fp]; fwrite(&tc, sizeof(char),1,fpout); break;
|
||||||
|
case ply::T_UCHAR : tu=thuf[i][fp]; fwrite(&tu,sizeof(unsigned char),1,fpout); break;
|
||||||
|
default : assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (pi.FaceDescriptorVec[i].stotype1){
|
||||||
|
case ply::T_FLOAT : PlyConv(pi.FaceDescriptorVec[i].memtype1, ((char *)fp)+pi.FaceDescriptorVec[i].offset1, tf ); fwrite(&tf, sizeof(float),1,fpout); break;
|
||||||
|
case ply::T_DOUBLE : PlyConv(pi.FaceDescriptorVec[i].memtype1, ((char *)fp)+pi.FaceDescriptorVec[i].offset1, td ); fwrite(&td, sizeof(double),1,fpout); break;
|
||||||
|
case ply::T_INT : PlyConv(pi.FaceDescriptorVec[i].memtype1, ((char *)fp)+pi.FaceDescriptorVec[i].offset1, ti ); fwrite(&ti, sizeof(int),1,fpout); break;
|
||||||
|
case ply::T_SHORT : PlyConv(pi.FaceDescriptorVec[i].memtype1, ((char *)fp)+pi.FaceDescriptorVec[i].offset1, ts ); fwrite(&ts, sizeof(short),1,fpout); break;
|
||||||
|
case ply::T_CHAR : PlyConv(pi.FaceDescriptorVec[i].memtype1, ((char *)fp)+pi.FaceDescriptorVec[i].offset1, tc ); fwrite(&tc, sizeof(char),1,fpout); break;
|
||||||
|
case ply::T_UCHAR : PlyConv(pi.FaceDescriptorVec[i].memtype1, ((char *)fp)+pi.FaceDescriptorVec[i].offset1, tu ); fwrite(&tu, sizeof(unsigned char),1,fpout); break;
|
||||||
|
default : assert(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -589,20 +694,36 @@ namespace vcg {
|
||||||
if( HasPerFaceQuality(m) && (pi.mask & Mask::IOM_FACEQUALITY) )
|
if( HasPerFaceQuality(m) && (pi.mask & Mask::IOM_FACEQUALITY) )
|
||||||
fprintf(fpout,"%.*g ",DGTFQ,fp->Q());
|
fprintf(fpout,"%.*g ",DGTFQ,fp->Q());
|
||||||
|
|
||||||
for(i=0;i<pi.fdn;i++)
|
for(size_t i=0;i<pi.FaceDescriptorVec.size();i++)
|
||||||
{
|
{
|
||||||
float tf(0); double td(0);
|
float tf(0); double td(0); int ti;
|
||||||
int ti;
|
if(!pi.FaceAttrNameVec.empty() && !pi.FaceAttrNameVec[i].empty())
|
||||||
switch (pi.FaceData[i].memtype1)
|
{ // trying to use named attribute to retrieve the value to store
|
||||||
|
assert(vcg::tri::HasPerFaceAttribute(m,pi.FaceAttrNameVec[i]));
|
||||||
|
switch (pi.FaceDescriptorVec[i].stotype1)
|
||||||
{
|
{
|
||||||
case ply::T_FLOAT : tf=*( (float *) (((char *)fp)+pi.FaceData[i].offset1)); fprintf(fpout,"%g ",tf); break;
|
case ply::T_FLOAT : tf=thff[i][fp]; fprintf(fpout,"%f ",tf); break;
|
||||||
case ply::T_DOUBLE : td=*( (double *) (((char *)fp)+pi.FaceData[i].offset1)); fprintf(fpout,"%g ",tf); break;
|
case ply::T_DOUBLE : td=thdf[i][fp]; fprintf(fpout,"%g ",td); break;
|
||||||
case ply::T_INT : ti=*( (int *) (((char *)fp)+pi.FaceData[i].offset1)); fprintf(fpout,"%i ",ti); break;
|
case ply::T_INT : ti=thif[i][fp]; fprintf(fpout,"%i ",ti); break;
|
||||||
case ply::T_SHORT : ti=*( (short *) (((char *)fp)+pi.FaceData[i].offset1)); fprintf(fpout,"%i ",ti); break;
|
case ply::T_SHORT : ti=thsf[i][fp]; fprintf(fpout,"%i ",ti); break;
|
||||||
case ply::T_CHAR : ti=*( (char *) (((char *)fp)+pi.FaceData[i].offset1)); fprintf(fpout,"%i ",ti); break;
|
case ply::T_CHAR : ti=thcf[i][fp]; fprintf(fpout,"%i ",ti); break;
|
||||||
case ply::T_UCHAR : ti=*( (unsigned char *) (((char *)fp)+pi.FaceData[i].offset1)); fprintf(fpout,"%i ",ti); break;
|
case ply::T_UCHAR : ti=thuf[i][fp]; fprintf(fpout,"%i ",ti); break;
|
||||||
default : assert(0);
|
default : assert(0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (pi.FaceDescriptorVec[i].memtype1)
|
||||||
|
{
|
||||||
|
case ply::T_FLOAT : tf=*( (float *) (((char *)fp)+pi.FaceDescriptorVec[i].offset1)); fprintf(fpout,"%g ",tf); break;
|
||||||
|
case ply::T_DOUBLE : td=*( (double *) (((char *)fp)+pi.FaceDescriptorVec[i].offset1)); fprintf(fpout,"%g ",tf); break;
|
||||||
|
case ply::T_INT : ti=*( (int *) (((char *)fp)+pi.FaceDescriptorVec[i].offset1)); fprintf(fpout,"%i ",ti); break;
|
||||||
|
case ply::T_SHORT : ti=*( (short *) (((char *)fp)+pi.FaceDescriptorVec[i].offset1)); fprintf(fpout,"%i ",ti); break;
|
||||||
|
case ply::T_CHAR : ti=*( (char *) (((char *)fp)+pi.FaceDescriptorVec[i].offset1)); fprintf(fpout,"%i ",ti); break;
|
||||||
|
case ply::T_UCHAR : ti=*( (unsigned char *) (((char *)fp)+pi.FaceDescriptorVec[i].offset1)); fprintf(fpout,"%i ",ti); break;
|
||||||
|
default : assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(fpout,"\n");
|
fprintf(fpout,"\n");
|
||||||
|
|
|
||||||
|
|
@ -547,15 +547,15 @@ static int Open( OpenMeshType &m, const char * filename, PlyInfo &pi )
|
||||||
}
|
}
|
||||||
|
|
||||||
// User defined descriptors
|
// User defined descriptors
|
||||||
std::vector<PropDescriptor> VPV(pi.vdn); // property descriptor relative al tipo LoadPly_VertexAux
|
std::vector<PropDescriptor> VPV(pi.VertDescriptorVec.size()); // property descriptor relative al tipo LoadPly_VertexAux
|
||||||
std::vector<PropDescriptor> FPV(pi.fdn); // property descriptor relative al tipo LoadPly_FaceAux
|
std::vector<PropDescriptor> FPV(pi.FaceDescriptorVec.size()); // property descriptor relative al tipo LoadPly_FaceAux
|
||||||
if(pi.vdn>0){
|
if(pi.VertDescriptorVec.size()>0){
|
||||||
// Compute the total size needed to load additional per vertex data.
|
// Compute the total size needed to load additional per vertex data.
|
||||||
size_t totsz=0;
|
size_t totsz=0;
|
||||||
for(int i=0;i<pi.vdn;i++){
|
for(size_t i=0;i<pi.VertDescriptorVec.size();i++){
|
||||||
VPV[i] = pi.VertexData[i];
|
VPV[i] = pi.VertDescriptorVec[i];
|
||||||
VPV[i].offset1=offsetof(LoadPly_VertAux<ScalarType>,data)+totsz;
|
VPV[i].offset1=offsetof(LoadPly_VertAux<ScalarType>,data)+totsz;
|
||||||
totsz+=pi.VertexData[i].memtypesize();
|
totsz+=pi.VertDescriptorVec[i].memtypesize();
|
||||||
if( pf.AddToRead(VPV[i])==-1 ) { pi.status = pf.GetError(); return pi.status; }
|
if( pf.AddToRead(VPV[i])==-1 ) { pi.status = pf.GetError(); return pi.status; }
|
||||||
}
|
}
|
||||||
if(totsz > MAX_USER_DATA)
|
if(totsz > MAX_USER_DATA)
|
||||||
|
|
@ -564,12 +564,12 @@ static int Open( OpenMeshType &m, const char * filename, PlyInfo &pi )
|
||||||
return pi.status;
|
return pi.status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(pi.fdn>0){
|
if(pi.FaceDescriptorVec.size()>0){
|
||||||
size_t totsz=0;
|
size_t totsz=0;
|
||||||
for(int i=0;i<pi.fdn;i++){
|
for(size_t i=0;i<pi.FaceDescriptorVec.size();i++){
|
||||||
FPV[i] = pi.FaceData[i];
|
FPV[i] = pi.FaceDescriptorVec[i];
|
||||||
FPV[i].offset1=offsetof(LoadPly_FaceAux,data)+totsz;
|
FPV[i].offset1=offsetof(LoadPly_FaceAux,data)+totsz;
|
||||||
totsz+=pi.FaceData[i].memtypesize();
|
totsz+=pi.FaceDescriptorVec[i].memtypesize();
|
||||||
if( pf.AddToRead(FPV[i])==-1 ) { pi.status = pf.GetError(); return pi.status; }
|
if( pf.AddToRead(FPV[i])==-1 ) { pi.status = pf.GetError(); return pi.status; }
|
||||||
}
|
}
|
||||||
if(totsz > MAX_USER_DATA)
|
if(totsz > MAX_USER_DATA)
|
||||||
|
|
@ -583,7 +583,7 @@ static int Open( OpenMeshType &m, const char * filename, PlyInfo &pi )
|
||||||
/* Main Reading Loop */
|
/* Main Reading Loop */
|
||||||
/**************************************************************/
|
/**************************************************************/
|
||||||
m.Clear();
|
m.Clear();
|
||||||
for(int i=0;i<int(pf.elements.size());i++)
|
for(size_t i=0;i<pf.elements.size();i++)
|
||||||
{
|
{
|
||||||
int n = pf.ElemNumber(i);
|
int n = pf.ElemNumber(i);
|
||||||
|
|
||||||
|
|
@ -695,8 +695,8 @@ static int Open( OpenMeshType &m, const char * filename, PlyInfo &pi )
|
||||||
(*vi).R() = va.radius;
|
(*vi).R() = va.radius;
|
||||||
|
|
||||||
|
|
||||||
for(int k=0;k<pi.vdn;k++)
|
for(size_t k=0;k<pi.VertDescriptorVec.size();k++)
|
||||||
memcpy((char *)(&*vi) + pi.VertexData[k].offset1,
|
memcpy((char *)(&*vi) + pi.VertDescriptorVec[k].offset1,
|
||||||
(char *)(&va) + VPV[k].offset1,
|
(char *)(&va) + VPV[k].offset1,
|
||||||
VPV[k].memtypesize());
|
VPV[k].memtypesize());
|
||||||
++vi;
|
++vi;
|
||||||
|
|
@ -820,8 +820,8 @@ static int Open( OpenMeshType &m, const char * filename, PlyInfo &pi )
|
||||||
// tag faux vertices of first face
|
// tag faux vertices of first face
|
||||||
if (fa.size>3) fi->SetF(2);
|
if (fa.size>3) fi->SetF(2);
|
||||||
|
|
||||||
for(k=0;k<pi.fdn;k++)
|
for(size_t k=0;k<pi.FaceDescriptorVec.size();k++)
|
||||||
memcpy((char *)(&(*fi)) + pi.FaceData[k].offset1,
|
memcpy((char *)(&(*fi)) + pi.FaceDescriptorVec[k].offset1,
|
||||||
(char *)(&fa) + FPV[k].offset1,
|
(char *)(&fa) + FPV[k].offset1,
|
||||||
FPV[k].memtypesize());
|
FPV[k].memtypesize());
|
||||||
|
|
||||||
|
|
@ -861,8 +861,8 @@ static int Open( OpenMeshType &m, const char * filename, PlyInfo &pi )
|
||||||
fi->SetF(0);
|
fi->SetF(0);
|
||||||
if(qq<(fa.size-4)) fi->SetF(2);
|
if(qq<(fa.size-4)) fi->SetF(2);
|
||||||
|
|
||||||
for(k=0;k<pi.fdn;k++)
|
for(size_t k=0;k<pi.FaceDescriptorVec.size();k++)
|
||||||
memcpy((char *)(&(*fi)) + pi.FaceData[k].offset1,
|
memcpy((char *)(&(*fi)) + pi.FaceDescriptorVec[k].offset1,
|
||||||
(char *)(&fa) + FPV[k].offset1, FPV[k].memtypesize());
|
(char *)(&fa) + FPV[k].offset1, FPV[k].memtypesize());
|
||||||
++fi;
|
++fi;
|
||||||
}
|
}
|
||||||
|
|
@ -911,7 +911,7 @@ static int Open( OpenMeshType &m, const char * filename, PlyInfo &pi )
|
||||||
//qDebug("Starting Reading of Range Grid");
|
//qDebug("Starting Reading of Range Grid");
|
||||||
if(RangeGridCols==0) // not initialized.
|
if(RangeGridCols==0) // not initialized.
|
||||||
{
|
{
|
||||||
for(int co=0;co<int(pf.comments.size());++co)
|
for(size_t co=0;co< pf.comments.size();++co)
|
||||||
{
|
{
|
||||||
std::string num_cols = "num_cols";
|
std::string num_cols = "num_cols";
|
||||||
std::string num_rows = "num_rows";
|
std::string num_rows = "num_rows";
|
||||||
|
|
@ -974,20 +974,20 @@ static int Open( OpenMeshType &m, const char * filename, PlyInfo &pi )
|
||||||
m.textures.clear();
|
m.textures.clear();
|
||||||
m.normalmaps.clear();
|
m.normalmaps.clear();
|
||||||
|
|
||||||
for(int co=0;co<int(pf.comments.size());++co)
|
for(size_t co=0;co<pf.comments.size();++co)
|
||||||
{
|
{
|
||||||
std::string TFILE = "TextureFile";
|
std::string TFILE = "TextureFile";
|
||||||
std::string NFILE = "TextureNormalFile";
|
std::string NFILE = "TextureNormalFile";
|
||||||
std::string &c = pf.comments[co];
|
std::string &c = pf.comments[co];
|
||||||
// char buf[256];
|
// char buf[256];
|
||||||
std::string bufstr,bufclean;
|
std::string bufstr,bufclean;
|
||||||
int i,n;
|
int n;
|
||||||
|
|
||||||
if( TFILE == c.substr(0,TFILE.length()) )
|
if( TFILE == c.substr(0,TFILE.length()) )
|
||||||
{
|
{
|
||||||
bufstr = c.substr(TFILE.length()+1);
|
bufstr = c.substr(TFILE.length()+1);
|
||||||
n = static_cast<int>(bufstr.length());
|
n = static_cast<int>(bufstr.length());
|
||||||
for(i=0;i<n;i++)
|
for(int i=0;i<n;i++)
|
||||||
if( bufstr[i]!=' ' && bufstr[i]!='\t' && bufstr[i]>32 && bufstr[i]<125 ) bufclean.push_back(bufstr[i]);
|
if( bufstr[i]!=' ' && bufstr[i]!='\t' && bufstr[i]>32 && bufstr[i]<125 ) bufclean.push_back(bufstr[i]);
|
||||||
|
|
||||||
char buf2[255];
|
char buf2[255];
|
||||||
|
|
@ -1036,8 +1036,7 @@ int LoadCamera(const char * filename)
|
||||||
|
|
||||||
|
|
||||||
bool found = true;
|
bool found = true;
|
||||||
int i;
|
for(int i=0;i<23;++i)
|
||||||
for(i=0;i<23;++i)
|
|
||||||
{
|
{
|
||||||
if( pf.AddToRead(CameraDesc(i))==-1 )
|
if( pf.AddToRead(CameraDesc(i))==-1 )
|
||||||
{
|
{
|
||||||
|
|
@ -1049,7 +1048,7 @@ int LoadCamera(const char * filename)
|
||||||
if(!found)
|
if(!found)
|
||||||
return this->pi.status;
|
return this->pi.status;
|
||||||
|
|
||||||
for(i=0;i<int(pf.elements.size());i++)
|
for(size_t i=0;i<pf.elements.size();i++)
|
||||||
{
|
{
|
||||||
int n = pf.ElemNumber(i);
|
int n = pf.ElemNumber(i);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,8 @@ namespace tri {
|
||||||
namespace io {
|
namespace io {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** Additional data needed or useful for parsing a ply mesh.
|
/** Additional data needed or useful for parsing a ply mesh.
|
||||||
This class can be passed to the ImporterPLY::Open() function for
|
This class can be passed to the ImporterPLY::Open() function for
|
||||||
- retrieving additional per-vertex per-face data
|
- retrieving additional per-vertex per-face data
|
||||||
|
|
@ -64,13 +66,34 @@ class PlyInfo
|
||||||
public:
|
public:
|
||||||
typedef ::vcg::ply::PropDescriptor PropDescriptor ;
|
typedef ::vcg::ply::PropDescriptor PropDescriptor ;
|
||||||
|
|
||||||
|
void AddPerVertexFloatAttribute(const std::string &attrName, std::string propName="")
|
||||||
|
{
|
||||||
|
static const char *vertStr="vertex";
|
||||||
|
if(propName.empty()) propName=attrName;
|
||||||
|
VertDescriptorVec.push_back(PropDescriptor());
|
||||||
|
VertAttrNameVec.push_back(attrName);
|
||||||
|
VertDescriptorVec.back().elemname=vertStr;
|
||||||
|
VertDescriptorVec.back().propname=propName.c_str();
|
||||||
|
VertDescriptorVec.back().stotype1 = vcg::ply::T_FLOAT;
|
||||||
|
VertDescriptorVec.back().memtype1 = vcg::ply::T_FLOAT;
|
||||||
|
}
|
||||||
|
void AddPerFaceFloatAttribute(const std::string &attrName, std::string propName="")
|
||||||
|
{
|
||||||
|
static const char *faceStr="face";
|
||||||
|
if(propName.empty()) propName=attrName;
|
||||||
|
FaceDescriptorVec.push_back(PropDescriptor());
|
||||||
|
FaceAttrNameVec.push_back(attrName);
|
||||||
|
FaceDescriptorVec.back().elemname=faceStr;
|
||||||
|
FaceDescriptorVec.back().propname=propName.c_str();
|
||||||
|
FaceDescriptorVec.back().stotype1 = vcg::ply::T_FLOAT;
|
||||||
|
FaceDescriptorVec.back().memtype1 = vcg::ply::T_FLOAT;
|
||||||
|
}
|
||||||
|
|
||||||
PlyInfo()
|
PlyInfo()
|
||||||
{
|
{
|
||||||
status=0;
|
status=0;
|
||||||
mask=0;
|
mask=0;
|
||||||
cb=0;
|
cb=0;
|
||||||
vdn=fdn=0;
|
|
||||||
VertexData=FaceData=0;
|
|
||||||
}
|
}
|
||||||
/// Store the error codes enconutered when parsing a ply
|
/// Store the error codes enconutered when parsing a ply
|
||||||
int status;
|
int status;
|
||||||
|
|
@ -81,15 +104,16 @@ public:
|
||||||
// it returns the current position, and formats a string with a description of what th efunction is doing (loading vertexes, faces...)
|
// it returns the current position, and formats a string with a description of what th efunction is doing (loading vertexes, faces...)
|
||||||
CallBackPos *cb;
|
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
|
/// The additional vertex descriptor that a user can specify to load additional per-vertex non-standard data stored in a ply
|
||||||
PropDescriptor *VertexData;
|
std::vector<PropDescriptor> VertDescriptorVec;
|
||||||
/// the number of per-face descriptor (usually 0)
|
/// AttributeName is an array, externally allocated, containing the names of the attributes to be saved (loaded).
|
||||||
int fdn;
|
/// We assume that AttributeName[], if not empty, is exactly of the same size of VertexdData[]
|
||||||
|
/// If AttributeName[i] is not empty we use it to retrieve/store the info instead of the offsetted space in the current vertex
|
||||||
|
std::vector<std::string> VertAttrNameVec;
|
||||||
|
|
||||||
/// The additional vertex descriptor that a user can specify to load additional per-face non-standard data stored in a ply
|
/// The additional vertex descriptor that a user can specify to load additional per-face non-standard data stored in a ply
|
||||||
PropDescriptor *FaceData;
|
std::vector<PropDescriptor> FaceDescriptorVec;
|
||||||
|
std::vector<std::string> FaceAttrNameVec;
|
||||||
|
|
||||||
/// a string containing the current ply header. Useful for showing it to the user.
|
/// a string containing the current ply header. Useful for showing it to the user.
|
||||||
std::string header;
|
std::string header;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue