From 7cce9f185f2e4056c4ca2b6d92ae7c9bc9cc7961 Mon Sep 17 00:00:00 2001 From: Paolo Cignoni Date: Thu, 28 Oct 2021 13:24:24 +0200 Subject: [PATCH 01/11] Update export_ply.h --- wrap/io_trimesh/export_ply.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/wrap/io_trimesh/export_ply.h b/wrap/io_trimesh/export_ply.h index 95d52350..c69106b2 100644 --- a/wrap/io_trimesh/export_ply.h +++ b/wrap/io_trimesh/export_ply.h @@ -579,7 +579,7 @@ public: fprintf(fpout,"%.*g ",DGTVR,vp->R()); if( HasPerVertexTexCoord(m) && (pi.mask & Mask::IOM_VERTTEXCOORD) ) - fprintf(fpout,"%.*g %.*g",DGTVT,vp->T().u(),vp->T().v()); + fprintf(fpout,"%.*g %.*g",DGTVT,vp->T().u(),DGTVT,vp->T().v()); for(size_t i=0;iVN()*2); for(int k=0;kVN();++k) fprintf(fpout,"%.*g %.*g " - ,DGTFT - ,fp->V(k)->T().u() - ,fp->V(k)->T().v() + ,DGTFT,fp->V(k)->T().u() + ,DGTFT,fp->V(k)->T().v() ); } else if( HasPerWedgeTexCoord(m) && (pi.mask & Mask::IOM_WEDGTEXCOORD) ) From 448c340d3a57f0d3617306b543c6b9f8a03a60d1 Mon Sep 17 00:00:00 2001 From: Paolo Cignoni Date: Thu, 28 Oct 2021 21:21:15 +0200 Subject: [PATCH 02/11] removed useless selection count call in append --- vcg/complex/append.h | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/vcg/complex/append.h b/vcg/complex/append.h index bba38581..33229da3 100644 --- a/vcg/complex/append.h +++ b/vcg/complex/append.h @@ -299,9 +299,10 @@ static void MeshAppendConst( // vertex remap.vert.resize(mr.vert.size(), Remap::InvalidIndex()); VertexIteratorLeft vp; - size_t svn = UpdateSelection::VertexCount(mr); - if(selected) + if(selected){ + size_t svn = UpdateSelection::VertexCount(mr); vp=Allocator::AddVertices(ml,int(svn)); + } else vp=Allocator::AddVertices(ml,mr.vn); @@ -317,8 +318,10 @@ static void MeshAppendConst( // edge remap.edge.resize(mr.edge.size(), Remap::InvalidIndex()); EdgeIteratorLeft ep; - size_t sen = UpdateSelection::EdgeCount(mr); - if(selected) ep=Allocator::AddEdges(ml,sen); + if(selected) { + size_t sen = UpdateSelection::EdgeCount(mr); + ep=Allocator::AddEdges(ml,sen); + } else ep=Allocator::AddEdges(ml,mr.en); ForEachEdge(mr, [&](const EdgeRight& e) @@ -333,8 +336,10 @@ static void MeshAppendConst( // face remap.face.resize(mr.face.size(), Remap::InvalidIndex()); FaceIteratorLeft fp; - size_t sfn = UpdateSelection::FaceCount(mr); - if(selected) fp=Allocator::AddFaces(ml,sfn); + if(selected) { + size_t sfn = UpdateSelection::FaceCount(mr); + fp=Allocator::AddFaces(ml,sfn); + } else fp=Allocator::AddFaces(ml,mr.fn); ForEachFace(mr, [&](const FaceRight& f) From a0d239ec268014aad46a95fe3510b240f3446fb4 Mon Sep 17 00:00:00 2001 From: Paolo Cignoni Date: Thu, 28 Oct 2021 21:22:19 +0200 Subject: [PATCH 03/11] improved behaviour of distribution/histogram in presence of NaN --- vcg/complex/algorithms/stat.h | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/vcg/complex/algorithms/stat.h b/vcg/complex/algorithms/stat.h index f0e8502e..c9b0e7cb 100644 --- a/vcg/complex/algorithms/stat.h +++ b/vcg/complex/algorithms/stat.h @@ -299,11 +299,14 @@ public: static void ComputePerVertexQualityDistribution(const MeshType & m, Distribution & h, bool selectionOnly = false) // V1.0 { tri::RequirePerVertexQuality(m); + h.Clear(); for(ConstVertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi) if(!(*vi).IsD() && ((!selectionOnly) || (*vi).IsS()) ) { - assert(!math::IsNAN((*vi).Q()) && "You should never try to compute Histogram with Invalid Floating points numbers (NaN)"); - h.Add((*vi).Q()); + if(!math::IsNAN((*vi).Q())) + h.Add((*vi).Q()); + else + assert( "You should never try to compute Histogram with Invalid Floating points numbers (NaN)"); } } @@ -311,11 +314,14 @@ public: bool selectionOnly = false) // V1.0 { tri::RequirePerFaceQuality(m); + h.Clear(); for(ConstFaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi) if(!(*fi).IsD() && ((!selectionOnly) || (*fi).IsS()) ) { - assert(!math::IsNAN((*fi).Q()) && "You should never try to compute Histogram with Invalid Floating points numbers (NaN)"); - h.Add((*fi).Q()); + if(!math::IsNAN((*fi).Q())) + h.Add((*fi).Q()); + else + assert( "You should never try to compute Histogram with Invalid Floating points numbers (NaN)"); } } From b6110a93df2258a1f7a3e8f7a210b8b15d1cdb6f Mon Sep 17 00:00:00 2001 From: Paolo Cignoni Date: Thu, 28 Oct 2021 21:22:42 +0200 Subject: [PATCH 04/11] removed useless var --- vcg/complex/algorithms/update/curvature_fitting.h | 1 - 1 file changed, 1 deletion(-) diff --git a/vcg/complex/algorithms/update/curvature_fitting.h b/vcg/complex/algorithms/update/curvature_fitting.h index 9de9fe3e..332b3d36 100644 --- a/vcg/complex/algorithms/update/curvature_fitting.h +++ b/vcg/complex/algorithms/update/curvature_fitting.h @@ -633,7 +633,6 @@ class Quadric if (cb && ((i%1024)==00)) { (*cb)(int(100.0f * (float)i / (float)mesh.vn),"Vertices Analysis"); } - int count; expandSphereLocal (mesh, &*vi, radiusSphere, 5, &vv); assert (vv.size() >= 5); From 49c8678ec3583f4eb7d0d7ff147a4a32584e3d00 Mon Sep 17 00:00:00 2001 From: Paolo Cignoni Date: Fri, 29 Oct 2021 14:26:00 +0200 Subject: [PATCH 05/11] removed useless HG components from the vertex component set Replaced by much simpler attributes --- vcg/complex/base.h | 3 -- vcg/simplex/vertex/component.h | 49 ------------------------------ vcg/simplex/vertex/component_ocf.h | 44 --------------------------- 3 files changed, 96 deletions(-) diff --git a/vcg/complex/base.h b/vcg/complex/base.h index befda76c..b59e26e6 100644 --- a/vcg/complex/base.h +++ b/vcg/complex/base.h @@ -666,7 +666,6 @@ template < class VertexType> bool VertexVectorHasPerVertexColor (const std template < class VertexType> bool VertexVectorHasPerVertexMark (const std::vector &) { return VertexType::HasMark (); } template < class VertexType> bool VertexVectorHasPerVertexFlags (const std::vector &) { return VertexType::HasFlags (); } template < class VertexType> bool VertexVectorHasPerVertexRadius (const std::vector &) { return VertexType::HasRadius (); } -template < class VertexType> bool VertexVectorHasPerVertexCurvature (const std::vector &) { return VertexType::HasCurvature (); } template < class VertexType> bool VertexVectorHasPerVertexCurvatureDir(const std::vector &) { return VertexType::HasCurvatureDir(); } template < class VertexType> bool VertexVectorHasPerVertexTexCoord (const std::vector &) { return VertexType::HasTexCoord (); } @@ -676,7 +675,6 @@ template < class TriMeshType> bool HasPerVertexColor (const TriMeshType &m template < class TriMeshType> bool HasPerVertexMark (const TriMeshType &m) { return tri::VertexVectorHasPerVertexMark (m.vert); } template < class TriMeshType> bool HasPerVertexFlags (const TriMeshType &m) { return tri::VertexVectorHasPerVertexFlags (m.vert); } template < class TriMeshType> bool HasPerVertexRadius (const TriMeshType &m) { return tri::VertexVectorHasPerVertexRadius (m.vert); } -template < class TriMeshType> bool HasPerVertexCurvature (const TriMeshType &m) { return tri::VertexVectorHasPerVertexCurvature (m.vert); } template < class TriMeshType> bool HasPerVertexCurvatureDir(const TriMeshType &m) { return tri::VertexVectorHasPerVertexCurvatureDir(m.vert); } template < class TriMeshType> bool HasPerVertexTexCoord (const TriMeshType &m) { return tri::VertexVectorHasPerVertexTexCoord (m.vert); } @@ -877,7 +875,6 @@ template void RequirePerVertexColor (const MeshType &m) { template void RequirePerVertexMark (const MeshType &m) { if(!tri::HasPerVertexMark (m)) throw vcg::MissingComponentException("PerVertexMark "); } template void RequirePerVertexFlags (const MeshType &m) { if(!tri::HasPerVertexFlags (m)) throw vcg::MissingComponentException("PerVertexFlags "); } template void RequirePerVertexRadius (const MeshType &m) { if(!tri::HasPerVertexRadius (m)) throw vcg::MissingComponentException("PerVertexRadius "); } -template void RequirePerVertexCurvature (const MeshType &m) { if(!tri::HasPerVertexCurvature (m)) throw vcg::MissingComponentException("PerVertexCurvature "); } template void RequirePerVertexCurvatureDir(const MeshType &m) { if(!tri::HasPerVertexCurvatureDir(m)) throw vcg::MissingComponentException("PerVertexCurvatureDir"); } template void RequirePerVertexTexCoord (const MeshType &m) { if(!tri::HasPerVertexTexCoord (m)) throw vcg::MissingComponentException("PerVertexTexCoord "); } diff --git a/vcg/simplex/vertex/component.h b/vcg/simplex/vertex/component.h index dab25640..37f27f93 100644 --- a/vcg/simplex/vertex/component.h +++ b/vcg/simplex/vertex/component.h @@ -158,15 +158,8 @@ public: static bool HasVHAdjacency() { return false; } typedef float CurScalarType; - typedef float ScalarTypeCur; typedef Point3f CurVecType; typedef Point2f CurvatureType; - float &Kh() { static float dummy = 0.f; assert(0);return dummy;} - float &Kg() { static float dummy = 0.f; assert(0);return dummy;} - float Kh() const { static float dummy = 0.f; assert(0); return dummy;} - float Kg() const { static float dummy = 0.f; assert(0); return dummy;} - float cKh() const { static float dummy = 0.f; assert(0); return dummy;} - float cKg() const { static float dummy = 0.f; assert(0); return dummy;} typedef CurvatureDirBaseType CurvatureDirType; CurVecType &PD1() {static CurVecType v(0,0,0); assert(0);return v;} @@ -183,9 +176,7 @@ public: CurScalarType cK1() const {static ScalarType v = 0.0;assert(0);return v;} CurScalarType cK2() const {static ScalarType v = 0.0;assert(0);return v;} - static bool HasCurvature() { return false; } static bool HasCurvatureDir() { return false; } - inline bool IsCurvatureEnabled() const { return TT::VertexType::HasCurvature();} inline bool IsCurvatureDirEnabled() const { return TT::VertexType::HasCurvatureDir();} template < class RightValueType> @@ -428,46 +419,6 @@ template class Qualityd: public Quality { public: static void Name(std::vector & name){name.push_back(std::string("Qualityd"));TT::Name(name);} }; - /*-------------------------- Curvature ----------------------------------*/ - - /*! \brief \em Component: Per vertex basic \b curvature - This component keeps the mean an gaussian curvature for a vertex. Used by some of the algorithms of vcg::tri::UpdateCurvature to store the computed curvatures. - */ - template class Curvature: public TT { - public: - typedef Point2 CurvatureType; - typedef typename CurvatureType::ScalarType ScalarTypeCur; - const ScalarTypeCur &Kh() const { return _hk[0]; } - const ScalarTypeCur &Kg() const { return _hk[1]; } - ScalarTypeCur &Kh() { return _hk[0]; } - ScalarTypeCur &Kg() { return _hk[1]; } - ScalarTypeCur cKh() const { return _hk[0]; } - ScalarTypeCur cKg() const { return _hk[1]; } - - template < class RightValueType> - void ImportData(const RightValueType & rVert ) { - if(rVert.IsCurvatureEnabled()) { - Kh() = rVert.cKh(); - Kg() = rVert.cKg(); - } - TT::ImportData( rVert); - } - - static bool HasCurvature() { return true; } - static void Name(std::vector & name){name.push_back(std::string("Curvature"));TT::Name(name);} - - private: - Point2 _hk; - }; - - - template class Curvaturef: public Curvature< float, T> { - public: static void Name(std::vector & name){name.push_back(std::string("Curvaturef"));T::Name(name);} - }; - template class Curvatured: public Curvature { - public: static void Name(std::vector & name){name.push_back(std::string("Curvatured"));T::Name(name);} - }; - /*-------------------------- Curvature Direction ----------------------------------*/ /*! \brief \em Component: Per vertex \b curvature \b directions diff --git a/vcg/simplex/vertex/component_ocf.h b/vcg/simplex/vertex/component_ocf.h index 8750066c..4ad90edb 100644 --- a/vcg/simplex/vertex/component_ocf.h +++ b/vcg/simplex/vertex/component_ocf.h @@ -432,50 +432,6 @@ public: }; -///*-------------------------- CURVATURE ----------------------------------*/ - -template class CurvatureOcf: public TT { -public: - typedef Point2 CurvatureType; - typedef typename CurvatureType::ScalarType ScalarTypeCur; - - ScalarTypeCur &Kh(){ assert((*this).Base().CurvatureEnabled); return (*this).Base().CuV[(*this).Index()][0]; } - ScalarTypeCur &Kg(){ assert((*this).Base().CurvatureEnabled); return (*this).Base().CuV[(*this).Index()][1]; } - ScalarTypeCur cKh() const - { - assert((*this).Base().CurvatureEnabled); - return (*this).Base().CuV[(*this).Index()][0]; - } - - ScalarTypeCur cKg() const - { - assert((*this).Base().CurvatureEnabled); - return (*this).Base().CuV[(*this).Index()][1]; - } - - template - void ImportData(const RightVertexType & rightV){ - if((*this).IsCurvatureEnabled() && rightV.IsCurvatureEnabled()) - { - (*this).Base().CuV[(*this).Index()][0] = rightV.cKh(); - (*this).Base().CuV[(*this).Index()][1] = rightV.cKg(); - } - TT::ImportData(rightV); - } - - inline bool IsCurvatureEnabled( ) const - { - return this->Base().IsCurvatureEnabled(); - } - - static bool HasCurvature() { return true; } - static bool HasCurvatureOcf() { return true; } -}; - -template class CurvaturefOcf: public CurvatureOcf {public: static void Name(std::vector & name){name.push_back(std::string("CurvaturefOcf"));T::Name(name);} }; -template class CurvaturedOcf: public CurvatureOcf {public: static void Name(std::vector & name){name.push_back(std::string("CurvaturedOcf"));T::Name(name);} }; - - ///*-------------------------- CURVATURE DIR ----------------------------------*/ template From 11b7b362ec96ef14d9c575bb4317e5c61e06f888 Mon Sep 17 00:00:00 2001 From: Paolo Cignoni Date: Fri, 29 Oct 2021 14:26:38 +0200 Subject: [PATCH 06/11] Updated curvature and quality function to do not use components but attributes --- vcg/complex/algorithms/update/curvature.h | 126 ++++++++++++---------- vcg/complex/algorithms/update/quality.h | 54 +++++----- 2 files changed, 96 insertions(+), 84 deletions(-) diff --git a/vcg/complex/algorithms/update/curvature.h b/vcg/complex/algorithms/update/curvature.h index 5b9a5364..e61e2ce8 100644 --- a/vcg/complex/algorithms/update/curvature.h +++ b/vcg/complex/algorithms/update/curvature.h @@ -400,7 +400,6 @@ For further details, please, refer to: \n static void MeanAndGaussian(MeshType & m) { tri::RequireFFAdjacency(m); - tri::RequirePerVertexCurvature(m); float area0, area1, area2, angle0, angle1, angle2; FaceIterator fi; @@ -411,13 +410,16 @@ static void MeanAndGaussian(MeshType & m) SimpleTempData TDContr(m.vert); vcg::tri::UpdateNormal::PerVertexNormalized(m); + auto KH = vcg::tri::Allocator:: template GetPerVertexAttribute (m, std::string("KH")); + auto KG = vcg::tri::Allocator:: template GetPerVertexAttribute (m, std::string("KG")); + //Compute AreaMix in H (vale anche per K) for(vi=m.vert.begin(); vi!=m.vert.end(); ++vi) if(!(*vi).IsD()) { (TDAreaPtr)[*vi].A = 0.0; (TDContr)[*vi] =typename MeshType::CoordType(0.0,0.0,0.0); - (*vi).Kh() = 0.0; - (*vi).Kg() = (float)(2.0 * M_PI); + KH[*vi] = 0.0; + KG[*vi] = (ScalarType)(2.0 * M_PI); } for(fi=m.face.begin();fi!=m.face.end();++fi) if( !(*fi).IsD()) @@ -482,10 +484,10 @@ static void MeanAndGaussian(MeshType & m) TDContr[(*fi).V(0)] += ( e20v * (1.0/tan(angle1)) - e01v * (1.0/tan(angle2)) ) / 4.0; TDContr[(*fi).V(1)] += ( e01v * (1.0/tan(angle2)) - e12v * (1.0/tan(angle0)) ) / 4.0; TDContr[(*fi).V(2)] += ( e12v * (1.0/tan(angle0)) - e20v * (1.0/tan(angle1)) ) / 4.0; - - (*fi).V(0)->Kg() -= angle0; - (*fi).V(1)->Kg() -= angle1; - (*fi).V(2)->Kg() -= angle2; + + KG[(*fi).V(0)] -= angle0; + KG[(*fi).V(1)] -= angle1; + KG[(*fi).V(2)] -= angle2; for(int i=0;i<3;i++) @@ -501,7 +503,7 @@ static void MeanAndGaussian(MeshType & m) hp1.FlipV(); hp1.NextB(); e2=hp1.v->cP() - hp.v->cP(); - (*fi).V(i)->Kg() -= math::Abs(Angle(e1,e2)); + KG[(*fi).V(i)] -= math::Abs(Angle(e1,e2)); } } } @@ -510,13 +512,13 @@ static void MeanAndGaussian(MeshType & m) { if((TDAreaPtr)[*vi].A<=std::numeric_limits::epsilon()) { - (*vi).Kh() = 0; - (*vi).Kg() = 0; + KH[(*vi)] = 0; + KG[(*vi)] = 0; } else { - (*vi).Kh() = (((TDContr)[*vi].dot((*vi).cN())>0)?1.0:-1.0)*((TDContr)[*vi] / (TDAreaPtr) [*vi].A).Norm(); - (*vi).Kg() /= (TDAreaPtr)[*vi].A; + KH[(*vi)] = (((TDContr)[*vi].dot((*vi).cN())>0)?1.0:-1.0)*((TDContr)[*vi] / (TDAreaPtr) [*vi].A).Norm(); + KG[(*vi)] /= (TDAreaPtr)[*vi].A; } } } @@ -526,78 +528,86 @@ static void MeanAndGaussian(MeshType & m) /** The function uses the VF adiacency to walk around the vertex. - \return It will return the voronoi area around the vertex. If (norm == true) the mean and the gaussian curvature are normalized. - Based on the paper "Optimizing 3d triangulations using discrete curvature analysis" - */ - - static float ComputeSingleVertexCurvature(VertexPointer v, bool norm = true) + + Based on the paper + "Optimizing 3d triangulations using discrete curvature analysis" + it compute an approximation of the gaussian and of the absolute mean curvature + */ +static void PerVertexAbsoluteMeanAndGaussian(MeshType & m) +{ + tri::RequireVFAdjacency(m); + tri::RequireCompactness(m); + const bool areaNormalize = true; + const bool barycentricArea=false; + auto KH = vcg::tri::Allocator:: template GetPerVertexAttribute (m, std::string("KH")); + auto KG = vcg::tri::Allocator:: template GetPerVertexAttribute (m, std::string("KG")); + int faceCnt=0; + for(VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi) { + VertexPointer v=&*vi; VFIteratorType vfi(v); - float A = 0; + ScalarType A = 0; - v->Kh() = 0; - v->Kg() = 2 * M_PI; + KH[v] = 0; + ScalarType AngleDefect = (ScalarType)(2.0 * M_PI);; while (!vfi.End()) { - if (!vfi.F()->IsD()) { + faceCnt++; FacePointer f = vfi.F(); CoordType nf = TriangleNormal(*f); int i = vfi.I(); VertexPointer v0 = f->V0(i), v1 = f->V1(i), v2 = f->V2(i); + assert (v==v0); - float ang0 = math::Abs(Angle(v1->P() - v0->P(), v2->P() - v0->P() )); - float ang1 = math::Abs(Angle(v0->P() - v1->P(), v2->P() - v1->P() )); - float ang2 = M_PI - ang0 - ang1; + ScalarType ang0 = math::Abs(Angle(v1->P() - v0->P(), v2->P() - v0->P() )); + ScalarType ang1 = math::Abs(Angle(v0->P() - v1->P(), v2->P() - v1->P() )); + ScalarType ang2 = M_PI - ang0 - ang1; - float s01 = SquaredDistance(v1->P(), v0->P()); - float s02 = SquaredDistance(v2->P(), v0->P()); + ScalarType s01 = SquaredDistance(v1->P(), v0->P()); + ScalarType s02 = SquaredDistance(v2->P(), v0->P()); // voronoi cell of current vertex - if (ang0 >= M_PI/2) - A += (0.5f * DoubleArea(*f) - (s01 * tan(ang1) + s02 * tan(ang2)) / 8.0 ); - else if (ang1 >= M_PI/2) - A += (s01 * tan(ang0)) / 8.0; - else if (ang2 >= M_PI/2) - A += (s02 * tan(ang0)) / 8.0; - else // non obctuse triangle - A += ((s02 / tan(ang1)) + (s01 / tan(ang2))) / 8.0; - + if(barycentricArea) + A+=vcg::DoubleArea(*f)/6.0; + else + { + if (ang0 >= M_PI/2) + A += (0.5f * DoubleArea(*f) - (s01 * tan(ang1) + s02 * tan(ang2)) / 8.0 ); + else if (ang1 >= M_PI/2) + A += (s01 * tan(ang0)) / 8.0; + else if (ang2 >= M_PI/2) + A += (s02 * tan(ang0)) / 8.0; + else // non obctuse triangle + A += ((s02 / tan(ang1)) + (s01 / tan(ang2))) / 8.0; + } // gaussian curvature update - v->Kg() -= ang0; + AngleDefect -= ang0; // mean curvature update - ang1 = math::Abs(Angle(nf, v1->N())); - ang2 = math::Abs(Angle(nf, v2->N())); - v->Kh() += ( (math::Sqrt(s01) / 2.0) * ang1 + - (math::Sqrt(s02) / 2.0) * ang2 ); - } - + // Note that the standard abs mean curvature approximation would require + // to sum all the edges*diehedralAngle. Here with just VF adjacency + // we make a rough approximation that 1/2 of the edge len plus something + // that is half of the diedral angle + ang1 = math::Abs(Angle(nf, v1->N()+v0->N())); + ang2 = math::Abs(Angle(nf, v2->N()+v0->N())); + KH[v] += math::Sqrt(s01)*ang1 + math::Sqrt(s02)*ang2 ; ++vfi; } - v->Kh() /= 4.0f; + KH[v] /= 4.0; - if(norm) { + if(areaNormalize) { if(A <= std::numeric_limits::epsilon()) { - v->Kh() = 0; - v->Kg() = 0; + KH[v] = 0; + KG[v] = 0; } else { - v->Kh() /= A; - v->Kg() /= A; + KH[v] /= A; + KG[v] = AngleDefect / A; } } - - return A; - } - - static void PerVertex(MeshType & m) - { - tri::RequireVFAdjacency(m); - - for(VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi) - ComputeSingleVertexCurvature(&*vi,false); } +} diff --git a/vcg/complex/algorithms/update/quality.h b/vcg/complex/algorithms/update/quality.h index 728c6e5f..cdb0c223 100644 --- a/vcg/complex/algorithms/update/quality.h +++ b/vcg/complex/algorithms/update/quality.h @@ -224,6 +224,15 @@ static void VertexFromAttributeHandle(MeshType &m, typename MeshType::template P (*vi).Q()=VertexQualityType(h[vi]); } +static void VertexFromAttributeName(MeshType &m, const std::string &AttrName) +{ + tri::RequirePerVertexQuality(m); + auto KH = tri::Allocator:: template FindPerVertexAttribute (m, AttrName); + if(!tri::Allocator::template IsValidHandle(m, KH)) throw vcg::MissingPreconditionException("Required Attribute is non existent"); + for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD()) + (*vi).Q() = KH[vi]; +} + template static void FaceFromAttributeHandle(MeshType &m, typename MeshType::template PerFaceAttributeHandle &h) { @@ -232,6 +241,15 @@ static void FaceFromAttributeHandle(MeshType &m, typename MeshType::template Per (*fi).Q() =FaceQualityType(h[fi]); } +static void FaceFromAttributeName(MeshType &m, const std::string &AttrName) +{ + tri::RequirePerFaceQuality(m); + auto KH = tri::Allocator:: template FindPerFaceAttribute (m, AttrName); + if(!tri::Allocator::template IsValidHandle(m, KH)) throw vcg::MissingPreconditionException("Required Attribute is non existent"); + for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD()) + (*fi).Q() =FaceQualityType(KH[fi]); +} + static void FaceFromVertex( MeshType &m) { tri::RequirePerFaceQuality(m); @@ -252,22 +270,6 @@ static void VertexFromPlane(MeshType &m, const Plane3 &pl) (*vi).Q() =SignedDistancePlanePoint(pl,(*vi).cP()); } -static void VertexFromGaussianCurvatureHG(MeshType &m) -{ - tri::RequirePerVertexQuality(m); - tri::RequirePerVertexCurvature(m); - for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD()) - (*vi).Q() = (*vi).Kg(); -} - -static void VertexFromMeanCurvatureHG(MeshType &m) -{ - tri::RequirePerVertexQuality(m); - tri::RequirePerVertexCurvature(m); - for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD()) - (*vi).Q() = (*vi).Kh(); -} - static void VertexFromGaussianCurvatureDir(MeshType &m) { tri::RequirePerVertexQuality(m); @@ -364,14 +366,14 @@ static void VertexFromCurvednessCurvatureDir(MeshType &m) static void VertexFromAbsoluteCurvature(MeshType &m) { tri::RequirePerVertexQuality(m); - tri::RequirePerVertexCurvature(m); - VertexIterator vi; - for(vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD()) + auto KH = vcg::tri::Allocator:: template GetPerVertexAttribute (m, std::string("KH")); + auto KG = vcg::tri::Allocator:: template GetPerVertexAttribute (m, std::string("KG")); + for(auto vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD()) { - if((*vi).Kg() >= 0) - (*vi).Q() = math::Abs( 2*(*vi).Kh() ); + if(KG[vi] >= 0) + (*vi).Q() = math::Abs( 2.0*KH[vi] ); else - (*vi).Q() = 2*math::Sqrt(math::Abs( (*vi).Kh()*(*vi).Kh() - (*vi).Kg())); + (*vi).Q() = 2*math::Sqrt(math::Abs( KH[vi]*KH[vi] - KG[vi])); } } @@ -385,10 +387,10 @@ static void VertexFromAbsoluteCurvature(MeshType &m) static void VertexFromRMSCurvature(MeshType &m) { tri::RequirePerVertexQuality(m); - tri::RequirePerVertexCurvature(m); - VertexIterator vi; - for(vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD()) - (*vi).Q() = math::Sqrt(math::Abs( 4*(*vi).Kh()*(*vi).Kh() - 2*(*vi).Kg())); + auto KH = vcg::tri::Allocator:: template GetPerVertexAttribute (m, std::string("KH")); + auto KG = vcg::tri::Allocator:: template GetPerVertexAttribute (m, std::string("KG")); + for(auto vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD()) + (*vi).Q() = math::Sqrt(math::Abs( 4*KH[vi]*KH[vi] - 2*KG[vi])); } /* From 442a289bf6f43efeaf54e6dc566aa9acb0655a97 Mon Sep 17 00:00:00 2001 From: Paolo Cignoni Date: Fri, 29 Oct 2021 14:58:18 +0200 Subject: [PATCH 07/11] renamed curvature extracting method for sake of coherence --- vcg/complex/algorithms/update/quality.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/vcg/complex/algorithms/update/quality.h b/vcg/complex/algorithms/update/quality.h index cdb0c223..51e8237b 100644 --- a/vcg/complex/algorithms/update/quality.h +++ b/vcg/complex/algorithms/update/quality.h @@ -270,7 +270,7 @@ static void VertexFromPlane(MeshType &m, const Plane3 &pl) (*vi).Q() =SignedDistancePlanePoint(pl,(*vi).cP()); } -static void VertexFromGaussianCurvatureDir(MeshType &m) +static void VertexGaussianFromCurvatureDir(MeshType &m) { tri::RequirePerVertexQuality(m); tri::RequirePerVertexCurvatureDir(m); @@ -278,21 +278,21 @@ static void VertexFromGaussianCurvatureDir(MeshType &m) (*vi).Q() = (*vi).K1()*(*vi).K2(); } -static void VertexFromMeanCurvatureDir(MeshType &m) +static void VertexMeanFromCurvatureDir(MeshType &m) { tri::RequirePerVertexQuality(m); tri::RequirePerVertexCurvatureDir(m); for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD()) (*vi).Q() = ((*vi).K1()+(*vi).K2())/2.0f; } -static void VertexFromMinCurvatureDir(MeshType &m) +static void VertexMinCurvFromCurvatureDir(MeshType &m) { tri::RequirePerVertexQuality(m); tri::RequirePerVertexCurvatureDir(m); for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD()) (*vi).Q() = (*vi).K1(); } -static void VertexFromMaxCurvatureDir(MeshType &m) +static void VertexMaxCurvFromCurvatureDir(MeshType &m) { tri::RequirePerVertexQuality(m); tri::RequirePerVertexCurvatureDir(m); @@ -301,7 +301,7 @@ static void VertexFromMaxCurvatureDir(MeshType &m) } /** - * @brief VertexFromShapeIndexCurvatureDir + * @brief VertexShapeIndexFromCurvatureDir * Compute from the current Curvature Direction the Shape Index S as defined by [Koenderink 1992] * and store it in the per-vertex Quality. * S = 2/pi atan(k1+k2/k1-k2) @@ -311,7 +311,7 @@ static void VertexFromMaxCurvatureDir(MeshType &m) * Image and vision computing, 10(8):557–565, 1992. */ -static void VertexFromShapeIndexCurvatureDir(MeshType &m) +static void VertexShapeIndexFromCurvatureDir(MeshType &m) { tri::RequirePerVertexQuality(m); tri::RequirePerVertexCurvatureDir(m); @@ -324,7 +324,7 @@ static void VertexFromShapeIndexCurvatureDir(MeshType &m) } } /** - * @brief VertexFromCurvednessCurvatureDir + * @brief VertexCurvednessFromCurvatureDir * Compute from the current Curvature Direction the Curvedness as defined by [Koenderink 1992] * and store it in the per-vertex Quality. * C = Sqrt((k1*k1+k2*k2)/2.0) @@ -333,7 +333,7 @@ static void VertexFromShapeIndexCurvatureDir(MeshType &m) * Surface shape and curvature scales. * Image and vision computing, 10(8):557–565, 1992. */ -static void VertexFromCurvednessCurvatureDir(MeshType &m) +static void VertexCurvednessFromCurvatureDir(MeshType &m) { tri::RequirePerVertexQuality(m); tri::RequirePerVertexCurvatureDir(m); @@ -363,7 +363,7 @@ static void VertexFromCurvednessCurvatureDir(MeshType &m) * N Dyn, K Hormann, SJ Kim, D Levin - Mathematical Methods for Curves and Surfaces: Oslo, 2000 */ -static void VertexFromAbsoluteCurvature(MeshType &m) +static void VertexAbsoluteCurvatureFromHGAttribute(MeshType &m) { tri::RequirePerVertexQuality(m); auto KH = vcg::tri::Allocator:: template GetPerVertexAttribute (m, std::string("KH")); @@ -384,7 +384,7 @@ static void VertexFromAbsoluteCurvature(MeshType &m) * Improved curvature estimation for watershed segmentation of 3-dimensional meshes * S Pulla, A Razdan, G Farin - Arizona State University, Tech. Rep, 2001 */ -static void VertexFromRMSCurvature(MeshType &m) +static void VertexRMSCurvatureFromHGAttribute(MeshType &m) { tri::RequirePerVertexQuality(m); auto KH = vcg::tri::Allocator:: template GetPerVertexAttribute (m, std::string("KH")); From 72200b9d9b9a90e1f57846a2bbaf86b2ea38da39 Mon Sep 17 00:00:00 2001 From: Paolo Cignoni Date: Fri, 29 Oct 2021 16:11:50 +0200 Subject: [PATCH 08/11] Updated curvature sample to the last changes --- .../trimesh_curvature/trimesh_curvature.cpp | 72 ++++++++++++++----- .../trimesh_curvature/trimesh_curvature.pro | 2 +- 2 files changed, 57 insertions(+), 17 deletions(-) diff --git a/apps/sample/trimesh_curvature/trimesh_curvature.cpp b/apps/sample/trimesh_curvature/trimesh_curvature.cpp index 8569c6e5..47104819 100644 --- a/apps/sample/trimesh_curvature/trimesh_curvature.cpp +++ b/apps/sample/trimesh_curvature/trimesh_curvature.cpp @@ -23,46 +23,86 @@ /*! \file trimesh_curvature.cpp \ingroup code_sample -\brief an example showing the various techniques for computing curvatures +\brief an example showing various techniques for computing curvatures */ #include #include #include +#include -#include +#include -class MyEdge; class MyFace; class MyVertex; struct MyUsedTypes : public vcg::UsedTypes< vcg::Use ::AsVertexType, - vcg::Use ::AsEdgeType, vcg::Use ::AsFaceType>{}; -class MyVertex : public vcg::Vertex{}; -class MyFace : public vcg::Face< MyUsedTypes, vcg::face::FFAdj, vcg::face::VFAdj, vcg::face::VertexRef, vcg::face::BitFlags > {}; -class MyEdge : public vcg::Edge{}; -class MyMesh : public vcg::tri::TriMesh< std::vector, std::vector , std::vector > {}; +class MyVertex : public vcg::Vertex{}; +class MyFace : public vcg::Face< MyUsedTypes, vcg::face::FFAdj, vcg::face::VFAdj, vcg::face::Normal3f, vcg::face::VertexRef, vcg::face::BitFlags > {}; +class MyMesh : public vcg::tri::TriMesh< std::vector, std::vector > {}; int main( int /*argc*/, char **/*argv*/ ) { MyMesh m; - vcg::tri::Torus(m,30,10); + // in a torus with radii 1 and 4 + // on the outside the principal curvature should be 1 and 1/5 + // and internally the principal curvature should be 1 and -1/3 + // Gaussian range -0.333 .. 0.200 + // mean range 0.333 .. 0.600 + //vcg::tri::Torus(m,4,1,32,16); + + + // in a sphere of radius 2 the curvature is everywhere 0.5 + // Gaussian 0.25 + // Mean 0.5 + vcg::tri::Sphere(m,5); + vcg::tri::UpdatePosition::Scale(m, 2.0); vcg::tri::UpdateTopology::FaceFace(m); vcg::tri::UpdateTopology::VertexFace(m); + vcg::tri::UpdateNormal::PerVertexNormalizedPerFaceNormalized(m); + vcg::Distribution distr; + printf("Starting mesh vn:%i fn:%i\n",m.VN(),m.FN()); - // Two different techniques for computing Discrete Gaussian and Mean Curvature - // they require the presence of the vertex::Curvature component - vcg::tri::UpdateCurvature::PerVertex(m); + // Method 1 (discrete - Optimizing 3d triangulations using discrete curvature analysis 2003) + vcg::tri::UpdateCurvature::PerVertexAbsoluteMeanAndGaussian(m); + vcg::tri::UpdateQuality::VertexFromAttributeName(m,"KG"); + vcg::tri::Stat::ComputePerVertexQualityDistribution(m,distr); + printf("Gaussian Curvature method 1 Min %f Max %f\n",distr.Min(),distr.Max()); + vcg::tri::UpdateQuality::VertexFromAttributeName(m,"KH"); + vcg::tri::Stat::ComputePerVertexQualityDistribution(m,distr); + printf("Mean Curvature method 1 Min %f Max %f\n",distr.Min(),distr.Max()); + + // Method 2 (discrete - Discrete Differential-Geometry Operators for Triangulated 2-Manifolds 2002) vcg::tri::UpdateCurvature::MeanAndGaussian(m); + vcg::tri::UpdateQuality::VertexFromAttributeName(m,"KG"); + vcg::tri::Stat::ComputePerVertexQualityDistribution(m,distr); + printf("Gaussian Curvature method 2 Min %f Max %f\n",distr.Min(),distr.Max()); + vcg::tri::UpdateQuality::VertexFromAttributeName(m,"KH"); + vcg::tri::Stat::ComputePerVertexQualityDistribution(m,distr); + printf("Mean Curvature method 2 Min %f Max %f\n",distr.Min(),distr.Max()); + vcg::tri::io::ExporterPLY::Save(m,"Torus_Discrete_Mean2.ply",vcg::tri::io::Mask::IOM_VERTQUALITY); - // Two different techniques for computing Principal Curvature Directions - // they require the presence of the vertex::CurvatureDir component + // Method 3 (directions - Estimating the Tensor of Curvature of a Surface from a Polyhedral Approximation - 1995) vcg::tri::UpdateCurvature::PrincipalDirections(m); + vcg::tri::UpdateQuality::VertexGaussianFromCurvatureDir(m); + vcg::tri::Stat::ComputePerVertexQualityDistribution(m,distr); + printf("Gaussian Curvature method 3 Min %f Max %f\n",distr.Min(),distr.Max()); + vcg::tri::UpdateQuality::VertexMeanFromCurvatureDir(m); + vcg::tri::Stat::ComputePerVertexQualityDistribution(m,distr); + printf("Mean Curvature method 3 Min %f Max %f\n",distr.Min(),distr.Max()); + + // Method 4 (directions - Restricted delaunay triangulations and normal cycle ) vcg::tri::UpdateCurvature::PrincipalDirectionsNormalCycle(m); - printf("Input mesh vn:%i fn:%i\n",m.VN(),m.FN()); - + vcg::tri::UpdateQuality::VertexGaussianFromCurvatureDir(m); + vcg::tri::Stat::ComputePerVertexQualityDistribution(m,distr); + printf("Gaussian Curvature method 4 Min %f Max %f\n",distr.Min(),distr.Max()); + vcg::tri::UpdateQuality::VertexMeanFromCurvatureDir(m); + vcg::tri::Stat::ComputePerVertexQualityDistribution(m,distr); + printf("Mean Curvature method 4 Min %f Max %f\n",distr.Min(),distr.Max()); + + return 0; } diff --git a/apps/sample/trimesh_curvature/trimesh_curvature.pro b/apps/sample/trimesh_curvature/trimesh_curvature.pro index 8342dfa4..343a355e 100644 --- a/apps/sample/trimesh_curvature/trimesh_curvature.pro +++ b/apps/sample/trimesh_curvature/trimesh_curvature.pro @@ -1,3 +1,3 @@ include(../common.pri) TARGET = trimesh_curvature -SOURCES += trimesh_curvature.cpp +SOURCES += trimesh_curvature.cpp ../../../wrap/ply/plylib.cpp From d1d106a4ce3a46d42fdfa665bb3e17b0c6ba61bd Mon Sep 17 00:00:00 2001 From: Paolo Cignoni Date: Fri, 29 Oct 2021 16:36:17 +0200 Subject: [PATCH 09/11] Updated cmakelist --- apps/sample/trimesh_curvature/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/sample/trimesh_curvature/CMakeLists.txt b/apps/sample/trimesh_curvature/CMakeLists.txt index a09fe6e1..57265ce7 100644 --- a/apps/sample/trimesh_curvature/CMakeLists.txt +++ b/apps/sample/trimesh_curvature/CMakeLists.txt @@ -3,7 +3,8 @@ project(trimesh_curvature) if (VCG_HEADER_ONLY) set(SOURCES - trimesh_curvature.cpp) + trimesh_curvature.cpp + ${VCG_INCLUDE_DIRS}/wrap/ply/plylib.cpp) endif() add_executable(trimesh_curvature From 23a24290a28ca0096c77544ff59d2df841d3b568 Mon Sep 17 00:00:00 2001 From: Luigi Malomo Date: Wed, 3 Nov 2021 14:19:44 +0100 Subject: [PATCH 10/11] commented out per vertex curvature property (todo: decide how to handle complete removal) --- wrap/nanoply/include/nanoply.hpp | 12 ++--- wrap/nanoply/include/nanoplyWrapper.hpp | 60 ++++++++++++------------- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/wrap/nanoply/include/nanoply.hpp b/wrap/nanoply/include/nanoply.hpp index 5a213560..e4110928 100644 --- a/wrap/nanoply/include/nanoply.hpp +++ b/wrap/nanoply/include/nanoply.hpp @@ -104,8 +104,8 @@ namespace nanoply NNP_BITFLAG = 0x00040000, /**< Bit flags. */ NNP_K1 = 0x00080000, /**< Main curvaure value k1. */ NNP_K2 = 0x00100000, /**< Main curvaure value k2. */ - NNP_KG = 0x00200000, /**< Gaussian curvature value. */ - NNP_KH = 0x00400000, /**< Mean curvature value. */ +// NNP_KG = 0x00200000, /**< Gaussian curvature value. */ +// NNP_KH = 0x00400000, /**< Mean curvature value. */ NNP_K1DIR = 0x00800000, /**< Curvature direction k1. */ NNP_K2DIR = 0x01000000, /**< Curvature direction k2. */ NNP_EDGE_V1 = 0x02000000, /**< Index of the first vertex of the edge. */ @@ -242,8 +242,8 @@ namespace nanoply { PlyEntity::NNP_BITFLAG, NameVector({ "flags" }) }, { PlyEntity::NNP_K1, NameVector({ "k1" }) }, { PlyEntity::NNP_K2, NameVector({ "k2" }) }, - { PlyEntity::NNP_KG, NameVector({ "k" }) }, - { PlyEntity::NNP_KH, NameVector({ "h" }) }, +// { PlyEntity::NNP_KG, NameVector({ "k" }) }, +// { PlyEntity::NNP_KH, NameVector({ "h" }) }, { PlyEntity::NNP_K1DIR, NameVector({ "k1dir" }) }, { PlyEntity::NNP_K2DIR, NameVector({ "k2dir" }) }, { PlyEntity::NNP_EDGE_V1, NameVector({ "vertex1", "v1" }) }, @@ -738,8 +738,8 @@ namespace nanoply case NNP_BITFLAG: return "NNP_BITFLAG "; case NNP_K1: return "NNP_K1 "; case NNP_K2: return "NNP_K2 "; - case NNP_KG: return "NNP_K "; - case NNP_KH: return "NNP_H "; +// case NNP_KG: return "NNP_K "; +// case NNP_KH: return "NNP_H "; case NNP_K1DIR: return "NNP_K1DIR "; case NNP_K2DIR: return "NNP_K2DIR "; case NNP_EDGE_V1: return "NNP_EDGE_V1 "; diff --git a/wrap/nanoply/include/nanoplyWrapper.hpp b/wrap/nanoply/include/nanoplyWrapper.hpp index abab3417..800b3427 100644 --- a/wrap/nanoply/include/nanoplyWrapper.hpp +++ b/wrap/nanoply/include/nanoplyWrapper.hpp @@ -856,8 +856,8 @@ namespace nanoply case NNP_DENSITY: mask |= BitMask::IO_VERTRADIUS; break; case NNP_TEXTURE2D: case NNP_TEXTURE3D: mask |= BitMask::IO_VERTTEXCOORD; break; - case NNP_KH: - case NNP_KG: mask |= BitMask::IO_VERTCURV; break; +// case NNP_KH: +// case NNP_KG: mask |= BitMask::IO_VERTCURV; break; case NNP_K1: case NNP_K2: case NNP_K1DIR: @@ -1012,21 +1012,21 @@ namespace nanoply else vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_TEXTURE2D, (*mesh.vert.begin()).T().P().V())); } - if ((bitMask & BitMask::IO_VERTCURV) && vcg::tri::HasPerVertexCurvature(mesh)) - { - if (ocfVertexMask & BitMask::IO_VERTCURV) - { - vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_KG, &(*mesh.vert.begin()).Kg())); - vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_KH, &(*mesh.vert.begin()).Kh())); - } - else - { - vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_KG, &(*mesh.vert.begin()).Kg())); - vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_KH, &(*mesh.vert.begin()).Kh())); - } - } - if ((bitMask & BitMask::IO_VERTCURVDIR) && vcg::tri::HasPerVertexCurvatureDir(mesh)) - { +// if ((bitMask & BitMask::IO_VERTCURV) && vcg::tri::HasPerVertexCurvature(mesh)) +// { +// if (ocfVertexMask & BitMask::IO_VERTCURV) +// { +// vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_KG, &(*mesh.vert.begin()).Kg())); +// vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_KH, &(*mesh.vert.begin()).Kh())); +// } +// else +// { +// vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_KG, &(*mesh.vert.begin()).Kg())); +// vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_KH, &(*mesh.vert.begin()).Kh())); +// } +// } + if ((bitMask & BitMask::IO_VERTCURVDIR) && vcg::tri::HasPerVertexCurvatureDir(mesh)) + { if (ocfVertexMask & BitMask::IO_VERTCURVDIR) { vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_K1, &(*mesh.vert.begin()).K1())); @@ -1380,19 +1380,19 @@ namespace nanoply else PushDescriport(vertexProp, vertexDescr, NNP_TEXTURE2D, (*mesh.vert.begin()).T().P().V()); } - if ((bitMask & BitMask::IO_VERTCURV) && vcg::tri::HasPerVertexCurvature(mesh)) - { - if (ocfVertexMask & BitMask::IO_VERTTEXCOORD) - { - PushDescriport(vertexProp, vertexDescr, NNP_KG, &(*mesh.vert.begin()).Kg()); - PushDescriport(vertexProp, vertexDescr, NNP_KH, &(*mesh.vert.begin()).Kh()); - } - else - { - PushDescriport(vertexProp, vertexDescr, NNP_KG, &(*mesh.vert.begin()).Kg()); - PushDescriport(vertexProp, vertexDescr, NNP_KH, &(*mesh.vert.begin()).Kh()); - } - } +// if ((bitMask & BitMask::IO_VERTCURV) && vcg::tri::HasPerVertexCurvature(mesh)) +// { +// if (ocfVertexMask & BitMask::IO_VERTTEXCOORD) +// { +// PushDescriport(vertexProp, vertexDescr, NNP_KG, &(*mesh.vert.begin()).Kg()); +// PushDescriport(vertexProp, vertexDescr, NNP_KH, &(*mesh.vert.begin()).Kh()); +// } +// else +// { +// PushDescriport(vertexProp, vertexDescr, NNP_KG, &(*mesh.vert.begin()).Kg()); +// PushDescriport(vertexProp, vertexDescr, NNP_KH, &(*mesh.vert.begin()).Kh()); +// } +// } if ((bitMask & BitMask::IO_VERTCURVDIR) && vcg::tri::HasPerVertexCurvatureDir(mesh)) { if (ocfVertexMask & BitMask::IO_VERTCURVDIR) From 117daf1a76b80ef4da6e6eddb8ee1051f83e7b4b Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Fri, 5 Nov 2021 12:24:52 +0100 Subject: [PATCH 11/11] obj materials importer less restrictive when reads something unexpected --- wrap/io_trimesh/import_obj.h | 78 +++++++++++++++--------------------- 1 file changed, 33 insertions(+), 45 deletions(-) diff --git a/wrap/io_trimesh/import_obj.h b/wrap/io_trimesh/import_obj.h index 0a3a6347..5b8ab94d 100644 --- a/wrap/io_trimesh/import_obj.h +++ b/wrap/io_trimesh/import_obj.h @@ -985,20 +985,16 @@ public: currentMaterial.illum = 2; bool first = true; - while (!stream.eof()) - { + while (!stream.eof()) { tokens.clear(); TokenizeNextLine(stream, tokens, line, 0); - if (tokens.size() > 0) - { + if (tokens.size() > 0) { header.clear(); header = tokens[0]; - if (header.compare("newmtl")==0) - { - if (!first) - { + if (header.compare("newmtl")==0) { + if (!first) { materials.push_back(currentMaterial); currentMaterial = Material(); currentMaterial.index = (unsigned int)(-1); @@ -1013,43 +1009,39 @@ public: else currentMaterial.materialName = line.substr(7); //space in the name, get everything after "newmtl " } - else if (header.compare("Ka")==0) - { - if (tokens.size() < 4) return false; - currentMaterial.Ka = Point3fFrom3Tokens(tokens,1); + else if (header.compare("Ka")==0) { + if (tokens.size() < 4) { + currentMaterial.Ka = Point3fFrom3Tokens(tokens,1); + } } - else if (header.compare("Kd")==0) - { - if (tokens.size() < 4) return false; - currentMaterial.Kd = Point3fFrom3Tokens(tokens,1); + else if (header.compare("Kd")==0) { + if (tokens.size() < 4) { + currentMaterial.Kd = Point3fFrom3Tokens(tokens,1); + } } - else if (header.compare("Ks")==0) - { - if (tokens.size() < 4) return false; - currentMaterial.Ks = Point3fFrom3Tokens(tokens,1); + else if (header.compare("Ks")==0) { + if (tokens.size() < 4) { + currentMaterial.Ks = Point3fFrom3Tokens(tokens,1); + } } - else if ( (header.compare("d")==0) || - (header.compare("Tr")==0) ) // alpha - { - if (tokens.size() < 2) return false; - currentMaterial.Tr = (float) atof(tokens[1].c_str()); + else if ((header.compare("d")==0) || (header.compare("Tr")==0)) { // alpha + if (tokens.size() < 2) { + currentMaterial.Tr = (float) atof(tokens[1].c_str()); + } } - else if (header.compare("Ns")==0) // shininess - { - if (tokens.size() < 2) return false; - currentMaterial.Ns = float(atoi(tokens[1].c_str())); + else if (header.compare("Ns")==0) { // shininess + if (tokens.size() < 2) { + currentMaterial.Ns = float(atoi(tokens[1].c_str())); + } } - else if (header.compare("illum")==0) // specular illumination on/off - { - if (tokens.size() < 2) return false; - currentMaterial.illum = atoi(tokens[1].c_str());; + else if (header.compare("illum")==0) { // specular illumination on/off + if (tokens.size() < 2) { + currentMaterial.illum = atoi(tokens[1].c_str()); + } } - else if(header.compare("map_Kd")==0) // texture name - { + else if(header.compare("map_Kd")==0) { // texture name std::string textureName; - if (tokens.size() < 2) - return false; - else { + if (tokens.size() == 2) { //the tex name is the last one (after any option) textureName = tokens[tokens.size()-1]; } @@ -1074,19 +1066,15 @@ public: stream.close(); // Sometimes some materials have texture and no texture // in this case for sake of uniformity we just use the first texture. - if(!textures.empty()) - { - for(size_t i=0;i