From c477fa1cc8cf0808b22bbb4d60ac675edae2303d Mon Sep 17 00:00:00 2001 From: Sylvain Thery Date: Wed, 12 Dec 2012 17:34:59 +0100 Subject: [PATCH] add Doo Sabin subdivision --- include/Algo/Modelisation/subdivision.h | 9 ++ include/Algo/Modelisation/subdivision.hpp | 106 ++++++++++++++++++++++ 2 files changed, 115 insertions(+) diff --git a/include/Algo/Modelisation/subdivision.h b/include/Algo/Modelisation/subdivision.h index e436255dc..bd7263bab 100644 --- a/include/Algo/Modelisation/subdivision.h +++ b/include/Algo/Modelisation/subdivision.h @@ -27,6 +27,7 @@ #include #include +#include "Algo/Geometry/centroid.h" namespace CGoGN { @@ -111,6 +112,12 @@ void TwoNPlusOneSubdivision(typename PFP::MAP& map, EMBV& attributs, const Funct template void reverseOrientation(typename PFP::MAP& map) ; +/** + * Doo-Sabin subdivision scheme + */ +template +void DooSabin(typename PFP::MAP& map, VertexAttribute& position); + ///** // * Dual mesh computation // */ @@ -124,6 +131,8 @@ void reverseOrientation(typename PFP::MAP& map) ; //void Sqrt3Subdivision(typename PFP::MAP& map, typename PFP::TVEC3& position, const FunctorSelect& selected = allDarts) ; + + } // namespace Modelisation } // namespace Algo diff --git a/include/Algo/Modelisation/subdivision.hpp b/include/Algo/Modelisation/subdivision.hpp index 6bec57ddd..f01f494c5 100644 --- a/include/Algo/Modelisation/subdivision.hpp +++ b/include/Algo/Modelisation/subdivision.hpp @@ -533,6 +533,112 @@ void reverseOrientation(typename PFP::MAP& map) map.template swapAttributes(phi1, phi_1) ; } + +template +void DooSabin(typename PFP::MAP& map, VertexAttribute& position) +{ + DartMarker dm(map); + // storage of boundary of hole (missing vertex faces) + std::vector fp; + fp.reserve(16384); + + // storage of initial faces for position updating + std::vector faces; + faces.reserve(16384); + + + // create the edge faces + for(Dart d=map.begin(); d != map.end(); map.next(d)) + { + if (!dm.isMarked(d)) + { + faces.push_back(d); + Dart e = d; + do + { + Dart e2 = map.phi2(e); + if (!dm.isMarked(e2)) + { + map.unsewFaces(e,false); + Dart nf = map.newFace(4,false); + map.sewFaces(e,nf,false); + map.sewFaces(e2,map.template phi<11>(nf),false); + // take care of edge embedding + if(map.template isOrbitEmbedded()) + { + map.template setOrbitEmbedding(nf, map.template getEmbedding(e)); + map.template setOrbitEmbedding(map.template phi<11>(nf), map.template getEmbedding(e2)); + } + + dm.markOrbit(nf); + fp.push_back(map.phi1(nf)); + fp.push_back(map.phi_1(nf)); + } + dm.markOrbit(e); + e = map.phi1(e); + }while (e!=d); + } + } + // fill (create) the new vertex faces + for (std::vector::iterator di=fp.begin(); di != fp.end(); ++di) + { + if (map.phi2(*di) == *di) + { + map.PFP::MAP::TOPO_MAP::closeHole(*di,false); + + if(map.template isOrbitEmbedded()) + { + Dart df = map.phi2(*di); + Dart d = df; + do + { + map.template setOrbitEmbedding(d,map.template getEmbedding(map.phi2(d))); + d = map.phi1(d); + } while (d != df); + } + } + } + + std::vector buffer; + buffer.reserve(8); + for (std::vector::iterator di=faces.begin(); di != faces.end(); ++di) + { + Dart e = *di; + typename PFP::VEC3 center = Algo::Geometry::faceCentroid(map,e,position); + + do + { + // compute DoSabin + buffer.push_back(position[e]); + e = map.phi1(e); + }while (e != * di); + + int N = buffer.size(); + for (int i=0; i(e); + position[e] = P; + e = map.phi1(e); + } + buffer.clear(); + } +} + + //template //void computeDual(typename PFP::MAP& map, const FunctorSelect& selected) //{ -- GitLab