diff --git a/include/Algo/Geometry/feature.h b/include/Algo/Geometry/feature.h index 4188a90c8867d677792333e5fcaf2c2fbbb40a4d..34239f9fd5b630d6bab63ef5b78ccb25e715c925 100644 --- a/include/Algo/Geometry/feature.h +++ b/include/Algo/Geometry/feature.h @@ -25,6 +25,8 @@ #ifndef __ALGO_GEOMETRY_FEATURE_H__ #define __ALGO_GEOMETRY_FEATURE_H__ + + namespace CGoGN { @@ -34,6 +36,14 @@ namespace Algo namespace Geometry { +#define EMPTY 0 +#define SEGMENT 1 +#define BARY 2 + +typedef struct { Dart d ; float w ; } e0point ; +typedef struct { e0point p1 ; e0point p2 ; int valid ; } e0segment ; +typedef NoMathIONameAttribute ridgeSegment ; + template void featureEdgeDetection(typename PFP::MAP& map, const typename PFP::TVEC3& position, CellMarker& featureEdge) ; @@ -50,7 +60,13 @@ template void computeTriangleType(typename PFP::MAP& map, const typename PFP::TVEC3& position, CellMarker& regularMarker, const FunctorSelect& select = allDarts, unsigned int thread = 0) ; template -void computeCurvatureSign(typename PFP::MAP& map, const typename PFP::TVEC3& position, CellMarker& regularMarker, typename PFP::TVEC3& faceGradient, const typename PFP::TREAL& area, const typename PFP::TREAL& k, const FunctorSelect& select = allDarts, unsigned int thread = 0) ; +void computeRidgeLines(typename PFP::MAP& map, const typename PFP::TVEC3& position, CellMarker& regularMarker, const typename PFP::TVEC3& faceGradient, const typename PFP::TREAL& area, typename PFP::TVEC3& k, AttributeHandler& ridge_segments, const FunctorSelect& select = allDarts, unsigned int thread = 0) ; + +template +void initRidgeSegments(typename PFP::MAP& map, const typename PFP::TVEC3& position, AttributeHandler& ridge_segments, const FunctorSelect& select = allDarts, unsigned int thread = 0) ; + +template +void computeSingularTriangle(typename PFP::MAP& map, const typename PFP::TVEC3& position, CellMarker& regularMarker, typename PFP::TVEC3& k, AttributeHandler& ridge_segments, const FunctorSelect& select = allDarts, unsigned int thread = 0) ; template std::vector occludingContoursDetection(typename PFP::MAP& map, const typename PFP::VEC3& cameraPosition, const typename PFP::TVEC3& position, const typename PFP::TVEC3& normal) ; @@ -68,14 +84,20 @@ template bool isInSameOctant(const typename PFP::VEC3& pos1, const typename PFP::VEC3& pos2) ; template -void curvatureSign(typename PFP::MAP& map, Dart d, const typename PFP::TVEC3& position, CellMarker& regularMarker, typename PFP::TREAL& k, typename PFP::TVEC3& faceGradient, typename PFP::TREAL& area) ; +void ridgeLines(typename PFP::MAP& map, Dart d, const typename PFP::TVEC3& position, CellMarker& regularMarker, typename PFP::TVEC3& k, const typename PFP::TVEC3& faceGradient, const typename PFP::TREAL& area, AttributeHandler& ridge_segments) ; template -typename PFP::REAL extremality(typename PFP::MAP& map, Dart d, const typename PFP::TVEC3& position, typename PFP::TREAL& k, typename PFP::TVEC3& faceGradient, typename PFP::TREAL& area) ; +typename PFP::REAL extremality(typename PFP::MAP& map, Dart d, const typename PFP::TVEC3& position, typename PFP::TVEC3& k, const typename PFP::TVEC3& faceGradient, const typename PFP::TREAL& area) ; template typename PFP::TVEC3 vertexGradient(typename PFP::MAP& map, Dart d, const typename PFP::TVEC3& position, const typename PFP::TVEC3& face_gradient, const typename PFP::TREAL& area) ; +template +void singularTriangle(typename PFP::MAP& map, Dart d, const typename PFP::TVEC3& position, CellMarker& regularMarker, AttributeHandler& ridge_segments) ; + +template +bool isEdgeInTriangle(typename PFP::MAP& map, Dart edge, Dart triangle) ; + } // namespace Geometry } // namespace Algo diff --git a/include/Algo/Geometry/feature.hpp b/include/Algo/Geometry/feature.hpp index 13ee288450bc1d12bd85aa0aca1e8bfc04d2939e..cf7656032950b7a792cdf8d1aa38a48d8e8ee5a6 100644 --- a/include/Algo/Geometry/feature.hpp +++ b/include/Algo/Geometry/feature.hpp @@ -92,24 +92,37 @@ void computeTriangleType(typename PFP::MAP& map, const typename PFP::TVEC3& posi } template -void computeCurvatureSign(typename PFP::MAP& map, const typename PFP::TVEC3& position, CellMarker& regularMarker, typename PFP::TVEC3& faceGradient, const typename PFP::TREAL& area, const typename PFP::TREAL& k, const FunctorSelect& select = allDarts, unsigned int thread = 0) +void computeRidgeLines(typename PFP::MAP& map, const typename PFP::TVEC3& position, CellMarker& regularMarker, const typename PFP::TVEC3& faceGradient, const typename PFP::TREAL& area, typename PFP::TVEC3& k, AttributeHandler& ridge_segments, const FunctorSelect& select = allDarts, unsigned int thread = 0) { - /*CellMarker mv(map, VERTEX, thread); - TraversorV trav(map, select, thread); + TraversorF trav(map, select, thread); for (Dart d = trav.begin(); d != trav.end(); d = trav.next()) { - if (!mv.isMarked(d)) + if (regularMarker.isMarked(d)) { - curvatureSign(map, d, position, triangle_type, k) ; + ridgeLines(map, d, position, regularMarker, k, faceGradient, area, ridge_segments) ; } - }*/ + } +} +template +void initRidgeSegments(typename PFP::MAP& map, const typename PFP::TVEC3& position, AttributeHandler& ridge_segments, const FunctorSelect& select = allDarts, unsigned int thread = 0) +{ TraversorF trav(map, select, thread); for (Dart d = trav.begin(); d != trav.end(); d = trav.next()) { - if (regularMarker.isMarked(d)) + ridge_segments[d].valid = EMPTY ; + } +} + +template +void computeSingularTriangle(typename PFP::MAP& map, const typename PFP::TVEC3& position, CellMarker& regularMarker, AttributeHandler& ridge_segments, const FunctorSelect& select = allDarts, unsigned int thread = 0) +{ + TraversorF trav(map, select, thread); + for (Dart d = trav.begin(); d != trav.end(); d = trav.next()) + { + if (! regularMarker.isMarked(d)) { - curvatureSign(map, d, position, regularMarker, k, faceGradient, area) ; + singularTriangle(map, d, position, regularMarker, ridge_segments) ; } } } @@ -306,87 +319,124 @@ bool isInSameOctant(const typename PFP::VEC3& pos1, const typename PFP::VEC3& po } template -void curvatureSign(typename PFP::MAP& map, Dart d, const typename PFP::TVEC3& position, CellMarker& regularMarker, typename PFP::TREAL& k, typename PFP::TVEC3& faceGradient, typename PFP::TREAL& area) +void ridgeLines(typename PFP::MAP& map, Dart d, const typename PFP::TVEC3& position, CellMarker& regularMarker, typename PFP::TVEC3& k, const typename PFP::TVEC3& faceGradient, const typename PFP::TREAL& area, AttributeHandler& ridge_segments) { - /*sommetTraité = true ;*/ - - /*Traversor2VE trav2(map, d) ; - for (Dart d2 = trav2.begin(); d2 != trav2.end(); d2 = trav2.next()) - { - if (arrete non traité true) - { - if((k[d] * k[d2]) <= 0) - { - k[d2] *= -1 ; - } - } - }*/ - - /* Choix du signe */ - typedef typename PFP::REAL REAL ; typedef typename PFP::VEC3 VEC3 ; - VEC3 pos1(0) ; - VEC3 pos2(0) ; - VEC3 pos3(0) ; - Traversor2FV t(map, d) ; - Dart it = t.begin() ; + Dart v1 = t.begin() ; + Dart v2 = t.next() ; + Dart v3 = t.next() ; - pos1 += position[it] ; - it = t.next() ; - pos2 += position[it] ; - it = t.next() ; - pos3 += position[it] ; - - if((k[pos1] ^ k[pos2]) <= 0) + if((k[v1] * k[v2]) <= 0) { - k[pos2] *= -1 ; + k[v2] *= -1 ; } - if((k[pos1] ^ k[pos3]) <= 0) + if((k[v1] * k[v3]) <= 0) { - k[pos3] *= -1 ; + k[v3] *= -1 ; } /* Calcul coefficient extremalite */ REAL e1, e2, e3 ; - e1 = extremality(map, d, position, k, faceGradient, area) ; - e2 = extremality(map, d, position, k, faceGradient, area) ; - e3 = extremality(map, d, position, k, faceGradient, area) ; + e1 = extremality(map, v1, position, k, faceGradient, area) ; + e2 = extremality(map, v2, position, k, faceGradient, area) ; + e3 = extremality(map, v3, position, k, faceGradient, area) ; /* Stockage des zeros */ if( (e1 < 0 and e2 > 0) or (e1 > 0 and e2 < 0) ) { REAL alpha = abs(e1) / ( abs(e1) + abs(e2) ) ; - std::cout << "alpha : " << alpha << "\n" ; + ridge_segments[d].valid = SEGMENT ; + ridge_segments[d].p1.d = v1 ; + ridge_segments[d].p1.w = alpha ; } if( (e1 < 0 and e3 > 0) or (e1 > 0 and e3 < 0) ) { - + REAL alpha = abs(e1) / ( abs(e1) + abs(e2) ) ; + if(ridge_segments[d].valid == EMPTY) + { + ridge_segments[d].valid = SEGMENT ; + ridge_segments[d].p1.d = v2 ; + ridge_segments[d].p1.w = alpha ; + } + else + { + ridge_segments[d].p2.d = v2 ; + ridge_segments[d].p2.w = alpha ; + } } if( (e2 < 0 and e3 > 0) or (e2 > 0 and e3 < 0) ) { - + REAL alpha = abs(e1) / ( abs(e1) + abs(e2) ) ; + ridge_segments[d].p2.d = v3 ; + ridge_segments[d].p2.w = alpha ; } + + //stockage des zeros avec une autre methode pour le calcul du coefficient alpha + /*if( (e1 < 0 and e3 > 0) ) + { + REAL alpha = -e1 / ( e3 - e1 ) ; + if(ridge_segments[d].valid == false) + { + ridge_segments[d].valid = true ; + ridge_segments[d].p1.d = v2 ; + ridge_segments[d].p1.w = alpha ; + } + else + { + ridge_segments[d].p2.d = v2 ; + ridge_segments[d].p2.w = alpha ; + } + } + else if(e1 > 0 and e3 < 0) + { + REAL alpha = -e3 / ( e1 - e3 ) ; + if(ridge_segments[d].valid == false) + { + ridge_segments[d].valid = true ; + ridge_segments[d].p1.d = v2 ; + ridge_segments[d].p1.w = alpha ; + } + else + { + ridge_segments[d].p2.d = v2 ; + ridge_segments[d].p2.w = alpha ; + } + } + + if( (e2 < 0 and e3 > 0) ) + { + REAL alpha = -e2 / ( e3 - e2 ) ; + ridge_segments[d].p2.d = v3 ; + ridge_segments[d].p2.w = alpha ; + } + else if(e2 > 0 and e3 < 0) + { + REAL alpha = -e3 / ( e2 - e3 ) ; + ridge_segments[d].p2.d = v3 ; + ridge_segments[d].p2.w = alpha ; + }*/ } template -typename PFP::REAL extremality(typename PFP::MAP& map, Dart d, const typename PFP::TVEC3& position, typename PFP::TREAL& k, typename PFP::TVEC3& faceGradient, typename PFP::TREAL& area) +typename PFP::REAL extremality(typename PFP::MAP& map, Dart d, const typename PFP::TVEC3& position, typename PFP::TVEC3& k, const typename PFP::TVEC3& faceGradient, const typename PFP::TREAL& area) { typedef typename PFP::REAL REAL ; - REAL a, e ; + REAL a = 0 ; + REAL e = 0 ; Traversor2VF trav(map, d) ; for (Dart d2 = trav.begin(); d2 != trav.end(); d2 = trav.next()) { a += area[d2] ; - e += area[d2] * ( faceGradient[d2] ^ k[d] ) ; + e += area[d2] * ( faceGradient[d2] * k[d] ) ; } return (e / a) ; @@ -415,6 +465,67 @@ typename PFP::TVEC3 vertexGradient(typename PFP::MAP& map, Dart d, const typenam return G ; } +template +void singularTriangle(typename PFP::MAP& map, Dart d, const typename PFP::TVEC3& position, CellMarker& regularMarker, AttributeHandler& ridge_segments) +{ + int nbPoint = 0 ; + + Traversor2FFaE f(map, d) ; + for (Dart d2 = f.begin(); d2 != f.end(); d2 = f.next()) + { + if(regularMarker.isMarked(d2) and ridge_segments[d2].valid == SEGMENT) + { + if(isEdgeInTriangle(map, ridge_segments[d2].p1.d, d)) + { + if(nbPoint == 0) + { + ridge_segments[d].p1.d = map.phi2(ridge_segments[d2].p1.d) ; + ridge_segments[d].p1.w = 1 - ridge_segments[d2].p1.w ; + } + else + { + ridge_segments[d].valid ++ ; + ridge_segments[d].p2.d = map.phi2(ridge_segments[d2].p1.d) ; + ridge_segments[d].p2.w = 1 - ridge_segments[d2].p1.w ; + } + nbPoint ++ ; + } + else if(isEdgeInTriangle(map, ridge_segments[d2].p1.d, d)) + { + if(nbPoint == 0) + { + ridge_segments[d].p1.d = map.phi2(ridge_segments[d2].p2.d) ; + ridge_segments[d].p1.w = 1 - ridge_segments[d2].p2.w ; + } + else + { + ridge_segments[d].valid ++ ; + ridge_segments[d].p2.d = map.phi2(ridge_segments[d2].p2.d) ; + ridge_segments[d].p2.w = 1 - ridge_segments[d2].p2.w ; + } + nbPoint ++ ; + } + } + } +} + +template +bool isEdgeInTriangle(typename PFP::MAP& map, Dart edge, Dart triangle) +{ + bool inTriangle = false ; + + Traversor2FE t(map, triangle) ; + for (Dart e = t.begin(); e != t.end(); e = t.next()) + { + if(map.phi2(e) == edge) + { + inTriangle = true ; + } + } + + return inTriangle ; +} + } // namespace Geometry } // namespace Algo