From c1d973238161f74f6194f0746454725dd39cc00b Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Fri, 2 Apr 2021 17:02:03 +0200 Subject: [PATCH] support export per face point custom attributes on ply --- wrap/io_trimesh/export_ply.h | 128 +++++++++++++++++++++++++---------- wrap/io_trimesh/io_ply.h | 15 ++++ 2 files changed, 108 insertions(+), 35 deletions(-) diff --git a/wrap/io_trimesh/export_ply.h b/wrap/io_trimesh/export_ply.h index 0138dba1..4f120237 100644 --- a/wrap/io_trimesh/export_ply.h +++ b/wrap/io_trimesh/export_ply.h @@ -284,8 +284,24 @@ public: fprintf(fpout,"property %s quality\n",fqtp); } - for(size_t i=0;i0 && (pi.mask & Mask::IOM_EDGEINDEX) ) fprintf( @@ -406,21 +422,33 @@ public: std::vector > thsf(pi.FaceDescriptorVec.size()); std::vector > thcf(pi.FaceDescriptorVec.size()); std::vector > thuf(pi.FaceDescriptorVec.size()); + std::vector > thp3ff(pi.FaceDescriptorVec.size()); + std::vector > thp3df(pi.FaceDescriptorVec.size()); for(size_t i=0;i::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; - case ply::T_DOUBLE : thdf[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; - case ply::T_INT : thif[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; - case ply::T_SHORT : thsf[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; - case ply::T_CHAR : thcf[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; - case ply::T_UCHAR : thuf[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; - default : assert(0); + if (!pi.FaceDescriptorVec[i].islist) { + switch (pi.FaceDescriptorVec[i].stotype1) + { + case ply::T_FLOAT : thff[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; + case ply::T_DOUBLE : thdf[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; + case ply::T_INT : thif[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; + case ply::T_SHORT : thsf[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; + case ply::T_CHAR : thcf[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; + case ply::T_UCHAR : thuf[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; + default : assert(0); + } + } + else { + switch (pi.FaceDescriptorVec[i].stotype1) + { + case ply::T_FLOAT : thp3ff[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; + case ply::T_DOUBLE : thp3df[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; + default : assert(0); + } } } } @@ -579,12 +607,12 @@ public: { switch (pi.VertDescriptorVec[i].memtype1) { - case ply::T_FLOAT : tf=*( (float *) (((char *)vp)+pi.VertDescriptorVec[i].offset1)); fprintf(fpout,"%f ",tf); break; - case ply::T_DOUBLE : td=*( (double *) (((char *)vp)+pi.VertDescriptorVec[i].offset1)); fprintf(fpout,"%lf ",tf); break; - case ply::T_INT : ti=*( (int *) (((char *)vp)+pi.VertDescriptorVec[i].offset1)); fprintf(fpout,"%i ",ti); break; - case ply::T_SHORT : ti=*( (short *) (((char *)vp)+pi.VertDescriptorVec[i].offset1)); fprintf(fpout,"%i ",ti); break; - 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; + case ply::T_FLOAT : tf=*( (float *) (((char *)vp)+pi.VertDescriptorVec[i].offset1)); fprintf(fpout,"%f ",tf); break; + case ply::T_DOUBLE : td=*( (double *) (((char *)vp)+pi.VertDescriptorVec[i].offset1)); fprintf(fpout,"%lf ",tf); break; + case ply::T_INT : ti=*( (int *) (((char *)vp)+pi.VertDescriptorVec[i].offset1)); fprintf(fpout,"%i ",ti); break; + case ply::T_SHORT : ti=*( (short *) (((char *)vp)+pi.VertDescriptorVec[i].offset1)); fprintf(fpout,"%i ",ti); break; + 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); } } @@ -692,15 +720,35 @@ public: 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 : tf=thff[i][fp]; fwrite(&tf, sizeof(float),1,fpout); break; - case ply::T_DOUBLE : td=thdf[i][fp]; fwrite(&td, sizeof(double),1,fpout); break; - 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); + if (!pi.FaceDescriptorVec[i].islist){ + switch (pi.FaceDescriptorVec[i].stotype1) + { + case ply::T_FLOAT : tf=thff[i][fp]; fwrite(&tf, sizeof(float),1,fpout); break; + case ply::T_DOUBLE : td=thdf[i][fp]; fwrite(&td, sizeof(double),1,fpout); break; + 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 { + static const unsigned char psize = 3; + switch (pi.FaceDescriptorVec[i].stotype1) + { + case ply::T_FLOAT : + fwrite(&psize, sizeof(unsigned char), 1,fpout); + fwrite(&thp3ff[i][fp][0], sizeof(float), 1,fpout); + fwrite(&thp3ff[i][fp][1], sizeof(float), 1,fpout); + fwrite(&thp3ff[i][fp][2], sizeof(float), 1,fpout); + break; + case ply::T_DOUBLE : + fwrite(&psize, sizeof(unsigned char), 1,fpout); + fwrite(&thp3df[i][fp][0], sizeof(double), 1,fpout); + fwrite(&thp3df[i][fp][1], sizeof(double), 1,fpout); + fwrite(&thp3df[i][fp][2], sizeof(double), 1,fpout); + default : assert(0); + } } } else @@ -777,15 +825,25 @@ public: 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 : tf=thff[i][fp]; fprintf(fpout,"%f ",tf); break; - case ply::T_DOUBLE : td=thdf[i][fp]; fprintf(fpout,"%g ",td); break; - case ply::T_INT : ti=thif[i][fp]; fprintf(fpout,"%i ",ti); break; - case ply::T_SHORT : ti=thsf[i][fp]; fprintf(fpout,"%i ",ti); break; - case ply::T_CHAR : ti=thcf[i][fp]; fprintf(fpout,"%i ",ti); break; - case ply::T_UCHAR : ti=thuf[i][fp]; fprintf(fpout,"%i ",ti); break; - default : assert(0); + if(!pi.FaceDescriptorVec[i].islist) { + switch (pi.FaceDescriptorVec[i].stotype1) + { + case ply::T_FLOAT : tf=thff[i][fp]; fprintf(fpout,"%f ",tf); break; + case ply::T_DOUBLE : td=thdf[i][fp]; fprintf(fpout,"%g ",td); break; + case ply::T_INT : ti=thif[i][fp]; fprintf(fpout,"%i ",ti); break; + case ply::T_SHORT : ti=thsf[i][fp]; fprintf(fpout,"%i ",ti); break; + case ply::T_CHAR : ti=thcf[i][fp]; fprintf(fpout,"%i ",ti); break; + case ply::T_UCHAR : ti=thuf[i][fp]; fprintf(fpout,"%i ",ti); break; + default : assert(0); + } + } + else { + switch (pi.FaceDescriptorVec[i].stotype1) + { + case ply::T_FLOAT : fprintf(fpout,"%d %f %f %f", 3, thp3ff[i][fp][0], thp3ff[i][fp][1], thp3ff[i][fp][2]); break; + case ply::T_DOUBLE : fprintf(fpout,"%d %lf %lf %lf", 3, thp3df[i][fp][0], thp3df[i][fp][1], thp3df[i][fp][2]); break; + default : assert(0); + } } } else diff --git a/wrap/io_trimesh/io_ply.h b/wrap/io_trimesh/io_ply.h index 92ba9f2d..05c25cab 100644 --- a/wrap/io_trimesh/io_ply.h +++ b/wrap/io_trimesh/io_ply.h @@ -160,6 +160,21 @@ public: addPerElemPointAttribute(0,vcg::ply::PlyTypes::T_DOUBLE, attrName,propName); } + void addPerFacePoint3mAttribute(const std::string& attrName, vcg::ply::PlyTypes attrType, std::string propName="") + { + addPerElemPointAttribute(1,attrType, attrName,propName); + } + + void addPerFacePoint3fAttribute(const std::string& attrName, std::string propName="") + { + addPerElemPointAttribute(1,vcg::ply::PlyTypes::T_FLOAT, attrName,propName); + } + + void addPerFacePoint3dAttribute(const std::string& attrName, std::string propName="") + { + addPerElemPointAttribute(1,vcg::ply::PlyTypes::T_DOUBLE, attrName,propName); + } + /* Note that saving a per vertex point3 attribute is a mess. * Actually require to allocate 3 float attribute and save them. And they are never deallocated... */ template