From 73a89349da20dda3fbabb56fc3163c90ee2d7f07 Mon Sep 17 00:00:00 2001 From: nico Date: Fri, 24 Feb 2017 18:21:21 +0100 Subject: [PATCH] refactored a bit the code and cleaned some commented function --- vcg/complex/algorithms/polygonal_algorithms.h | 325 +++++++++++++----- 1 file changed, 235 insertions(+), 90 deletions(-) diff --git a/vcg/complex/algorithms/polygonal_algorithms.h b/vcg/complex/algorithms/polygonal_algorithms.h index 0502b7db..ced5214b 100644 --- a/vcg/complex/algorithms/polygonal_algorithms.h +++ b/vcg/complex/algorithms/polygonal_algorithms.h @@ -75,74 +75,46 @@ class PolygonalAlgorithm typedef typename PolyMeshType::VertexType VertexType; typedef typename PolyMeshType::CoordType CoordType; typedef typename PolyMeshType::ScalarType ScalarType; - - - static bool CollapseBorderSmallEdgesStep(PolyMeshType &poly_m, - const ScalarType edge_limit) + typedef typename vcg::face::Pos PosType; +public: + static bool CollapseEdges(PolyMeshType &poly_m, + const std::vector &CollapsePos, + const std::vector &InterpPos) { - bool collapsed=false; - - //update topology - vcg::tri::UpdateTopology::FaceFace(poly_m); - - //update border vertices - //UpdateBorderVertexFromPFFAdj(poly_m); - vcg::tri::UpdateFlags::VertexBorderFromFaceAdj(poly_m); - - //get border edges - std::vector > IsBorder; - //BorderEdgeFromPFFAdj(poly_m,IsBorder); - vcg::tri::UpdateFlags::VertexBorderFromFaceAdj(poly_m); - //deselect all vertices - vcg::tri::UpdateFlags::VertexClearS(poly_m); //this set how to remap the vertices after deletion std::map VertexRemap; + vcg::tri::UpdateFlags::VertexClearS(poly_m); + + bool collapsed=false; //go over all faces and check the ones needed to be deleted - for (size_t i=0;iVN(); + VertexType *v0=currF->V(IndexE); + VertexType *v1=currF->V((IndexE+1)%NumV); - bool IsBV0=v0->IsB(); - bool IsBV1=v1->IsB(); + //safety check + assert(v0!=v1); - //in these cases is not possible to collapse - if ((!IsBV0)&&(!IsBV1))continue; - if ((!IsBorder[i][j])&&(IsBV0)&&(IsBV1))continue; - if (v0->IsS())continue; - if (v1->IsS())continue; + if (v0->IsS())continue; + if (v1->IsS())continue; - assert((IsBV0)||(IsBV1)); - CoordType pos0=v0->P(); - CoordType pos1=v1->P(); - ScalarType currL=(pos0-pos1).Norm(); - if (currL>edge_limit)continue; + //put on the same position + v0->P()=InterpPos[i]; + v1->P()=InterpPos[i]; - //then collapse the point - CoordType InterpPos; - if ((IsBV0)&&(!IsBV1))InterpPos=pos0; - if ((!IsBV0)&&(IsBV1))InterpPos=pos1; - if ((IsBV0)&&(IsBV1))InterpPos=(pos0+pos1)/2.0; + //select the the two vertices + v0->SetS(); + v1->SetS(); - //put on the same position - v0->P()=InterpPos; - v1->P()=InterpPos; + //set the remap + VertexRemap[v1]=v0; - //select the the two vertices - v0->SetS(); - v1->SetS(); - - //set the remap - VertexRemap[v1]=v0; - - collapsed=true; - } + collapsed=true; } //then remap vertices @@ -186,8 +158,181 @@ class PolygonalAlgorithm poly_m.face[i].V(j)=FaceV[j]; } + //remove unreferenced vertices + vcg::tri::Clean::RemoveUnreferencedVertex(poly_m); + + //and compact them + vcg::tri::Allocator::CompactEveryVector(poly_m); + return collapsed; } +private: +// static bool CollapseBorderSmallEdgesStep(PolyMeshType &poly_m, +// const ScalarType edge_limit) +// { +// bool collapsed=false; + +// //update topology +// vcg::tri::UpdateTopology::FaceFace(poly_m); + +// //update border vertices +// //UpdateBorderVertexFromPFFAdj(poly_m); +// vcg::tri::UpdateFlags::VertexBorderFromFaceAdj(poly_m); + +// //get border edges +// std::vector > IsBorder; +// //BorderEdgeFromPFFAdj(poly_m,IsBorder); +// vcg::tri::UpdateFlags::VertexBorderFromFaceAdj(poly_m); +// //deselect all vertices +// vcg::tri::UpdateFlags::VertexClearS(poly_m); + +// //this set how to remap the vertices after deletion +// std::map VertexRemap; + +// //go over all faces and check the ones needed to be deleted +// for (size_t i=0;iIsB(); +// bool IsBV1=v1->IsB(); + +// //in these cases is not possible to collapse +// if ((!IsBV0)&&(!IsBV1))continue; +// //if ((!IsBorder[i][j])&&(IsBV0)&&(IsBV1))continue; +// bool IsBorderE=poly_m.face[i].FFp(j); +// if ((IsBorderE)&&(IsBV0)&&(IsBV1))continue; +// if (v0->IsS())continue; +// if (v1->IsS())continue; + +// assert((IsBV0)||(IsBV1)); +// CoordType pos0=v0->P(); +// CoordType pos1=v1->P(); +// ScalarType currL=(pos0-pos1).Norm(); +// if (currL>edge_limit)continue; + +// //then collapse the point +// CoordType InterpPos; +// if ((IsBV0)&&(!IsBV1))InterpPos=pos0; +// if ((!IsBV0)&&(IsBV1))InterpPos=pos1; +// if ((IsBV0)&&(IsBV1))InterpPos=(pos0+pos1)/2.0; + +// //put on the same position +// v0->P()=InterpPos; +// v1->P()=InterpPos; + +// //select the the two vertices +// v0->SetS(); +// v1->SetS(); + +// //set the remap +// VertexRemap[v1]=v0; + +// collapsed=true; +// } +// } + +// //then remap vertices +// for (size_t i=0;i FaceV; +// for (int j=0;j::FaceFace(poly_m); + + //update border vertices + vcg::tri::UpdateFlags::VertexBorderFromFaceAdj(poly_m); + + + std::vector CollapsePos; + std::vector InterpPos; + + //go over all faces and check the ones needed to be deleted + for (size_t i=0;iIsB(); + bool IsBV1=v1->IsB(); + + //in these cases is not possible to collapse + if ((!IsBV0)&&(!IsBV1))continue; + bool IsBorderE=poly_m.face[i].FFp(j); + if ((IsBorderE)&&(IsBV0)&&(IsBV1))continue; + + assert((IsBV0)||(IsBV1)); + CoordType pos0=v0->P(); + CoordType pos1=v1->P(); + ScalarType currL=(pos0-pos1).Norm(); + if (currL>edge_limit)continue; + + //then collapse the point + CoordType CurrInterpPos; + if ((IsBV0)&&(!IsBV1))CurrInterpPos=pos0; + if ((!IsBV0)&&(IsBV1))CurrInterpPos=pos1; + if ((IsBV0)&&(IsBV1))CurrInterpPos=(pos0+pos1)/2.0; + + CollapsePos.push_back(PosType(&poly_m.face[i],j)); + InterpPos.push_back(CurrInterpPos); + } + } + + return CollapseEdges(poly_m,CollapsePos,InterpPos); + } static void LaplacianPos(PolyMeshType &poly_m,std::vector &AvVert) { @@ -266,45 +411,45 @@ public: UpdateNormalByFitting(poly_m.face[i]); } -// ///METTERE SOTTO TOPOLOGY? -// static void BorderEdgeFromPFFAdj(FaceType &F,std::vector &IsBorder) -// { -// IsBorder.resize(F.VN(),false); -// for (int j=0;j &IsBorder) + // { + // IsBorder.resize(F.VN(),false); + // for (int j=0;j > &IsBorder) -// { -// IsBorder.resize(poly_m.face.size()); -// for (size_t i=0;i > &IsBorder) + // { + // IsBorder.resize(poly_m.face.size()); + // for (size_t i=0;i > IsBorderE; -// BorderEdgeFromPFFAdj(poly_m,IsBorderE); + // static void UpdateBorderVertexFromPFFAdj(PolyMeshType &poly_m) + // { + // //get per edge border flag + // std::vector > IsBorderE; + // BorderEdgeFromPFFAdj(poly_m,IsBorderE); -// //then update per vertex -// vcg::tri::UpdateFlags::VertexClearB(poly_m); -// for (size_t i=0;i::VertexClearB(poly_m); + // for (size_t i=0;iSetB(); -// poly_m.face[i].V1(j)->SetB(); -// } -// } -// } + // for (int j=0;jSetB(); + // poly_m.face[i].V1(j)->SetB(); + // } + // } + // } enum PolyQualityType{QAngle,QPlanar,QTemplate};