35 #include "DGtal/kernel/CPointPredicate.h"
36 #include "DGtal/images/imagesSetsUtils/ImageFromSet.h"
37 #include "DGtal/images/ImageSelector.h"
38 #include "DGtal/topology/CSurfelPredicate.h"
39 #include "DGtal/helpers/StdDefs.h"
54 template <
typename TKSpace>
60 template <
typename TKSpace>
61 template <
typename Po
intPredicate>
66 const PointPredicate & pp,
72 Point sizes = K.upperBound() - K.lowerBound();
73 Point x1 = K.lowerBound();
76 bool val_v1 = pp( x1 );
79 for (
unsigned int j = 0; j < nbtries; ++j )
81 for (
Dimension i = 0; i < K.dimension; ++i )
84 x2[ i ] = ( r % sizes[ i ] ) + K.min( i );
86 bool val_v2 = pp( x2 );
87 if ( val_v2 != val_v1 )
93 if ( ! found )
throw dgtalerror;
94 return findABel( K, pp, x1, x2 );
97 template <
typename TKSpace>
98 template <
typename Po
intPredicate>
103 const PointPredicate & pp,
108 bool val_v1 = pp( x1 );
109 ASSERT( val_v1 != pp( x2 ) );
112 bool alreadyOnSameAxis =
true;
113 for (
Dimension i = 0; i < K.dimension; ++i )
115 if ( x1[ i ] != x2[ i ] )
117 for (
Dimension j = i + 1; j < K.dimension; ++j )
119 if ( x1[ j ] != x2[ j ] )
121 alreadyOnSameAxis =
false;
124 bool val_v2 = pp( x2 );
125 if ( val_v2 != val_v1 )
137 if ( alreadyOnSameAxis )
143 for (
Dimension i = 0; i < K.dimension; ++i )
145 if ( ( i == d ) && ( x1[ i ] == x2[ i ] ) )
146 std::cerr <<
"[DGtal::Surfaces::findABel] Error 1a along "
148 if ( ( i != d ) && ( x1[ i ] != x2[ i ] ) )
149 std::cerr <<
"[DGtal::Surfaces::findABel] Error 1b along "
157 xmid[ d ] = ( x1[ d ] + x2[ d ] ) / 2;
158 if ( ( xmid[ d ] == x1[ d ] ) || ( xmid[ d ] == x2[ d ] ) )
160 bool val_mid = pp( xmid );
161 if ( val_mid != val_v1 )
168 for (
Dimension i = 0; i < K.dimension; ++i )
172 if ( ( i == d ) && ( x1[ i ] != x2[ i ] - 1 ) )
173 std::cerr <<
"[DGtal::Surfaces::findABel] Error 2a along "
175 if ( ( i != d ) && ( x1[ i ] != x2[ i ] ) )
176 std::cerr <<
"[DGtal::Surfaces::findABel] Error 2a along "
182 return K.sIncident( K.sSpel( x1, K.POS ), d, true );
184 return K.sIncident( K.sSpel( x1, K.NEG ), d, true );
187 template <
typename TKSpace>
188 template <
typename SCellSet,
typename Po
intPredicate >
194 const PointPredicate & pp,
195 const SCell & start_surfel )
201 ASSERT( K.sIsSurfel( start_surfel ) );
205 SN.
init( &K, &surfel_adj, start_surfel );
206 std::queue<SCell> qbels;
207 qbels.push( start_surfel );
208 surface.insert( start_surfel );
210 while ( ! qbels.empty() )
221 if ( surface.find( bn ) == surface.end() )
223 surface.insert( bn );
230 if ( surface.find( bn ) == surface.end() )
232 surface.insert( bn );
240 template <
typename TKSpace>
241 template <
typename SCellSet,
typename SurfelPredicate >
247 const SurfelPredicate & sp,
248 const SCell & start_surfel )
254 ASSERT( K.sIsSurfel( start_surfel ) );
258 SN.
init( &K, &surfel_adj, start_surfel );
259 std::queue<SCell> qbels;
260 qbels.push( start_surfel );
261 surface.insert( start_surfel );
263 while ( ! qbels.empty() )
274 if ( surface.find( bn ) == surface.end() )
276 surface.insert( bn );
283 if ( surface.find( bn ) == surface.end() )
285 surface.insert( bn );
294 template <
typename TKSpace>
295 template <
typename SCellSet,
typename SurfelPredicate >
301 const SurfelPredicate & sp,
302 const SCell & start_surfel )
308 ASSERT( K.sIsSurfel( start_surfel ) );
312 SN.
init( &K, &surfel_adj, start_surfel );
313 std::queue<SCell> qbels;
314 qbels.push( start_surfel );
315 surface.insert( start_surfel );
317 while ( ! qbels.empty() )
327 K.sDirect( b, track_dir ) ) )
329 if ( surface.find( bn ) == surface.end() )
331 surface.insert( bn );
341 template <
typename TKSpace>
342 template <
typename Po
intPredicate>
345 ( std::vector<SCell> & aSCellContour2D,
348 const PointPredicate & pp,
349 const SCell & start_surfel )
352 ASSERT( K.dimension == 2 );
354 SCell b= start_surfel;
356 ASSERT( K.sIsSurfel( start_surfel ) );
359 aSCellContour2D.clear();
360 aSCellContour2D.push_back(start_surfel);
362 SN.
init( &K, &surfel_adj, start_surfel );
365 bool hasPrevNeighbor =
true;
366 while ( hasPrevNeighbor )
368 hasPrevNeighbor=
false;
372 ! K.sDirect( b, track_dir ) ) )
374 if ( bn != start_surfel )
377 hasPrevNeighbor=
true;
378 aSCellContour2D.push_back( bn );
385 reverse(aSCellContour2D.begin(), aSCellContour2D.end());
386 if ( b != start_surfel )
389 bool hasNextNeighbor =
true;
390 while ( hasNextNeighbor )
392 hasNextNeighbor=
false;
396 K.sDirect( b, track_dir ) ) )
400 aSCellContour2D.push_back( bn );
401 hasNextNeighbor=
true;
413 template <
typename TKSpace>
414 template <
typename Po
intPredicate>
417 ( std::vector<SCell> & aSCellContour2D,
421 const PointPredicate & pp,
422 const SCell & start_surfel )
425 SCell b= start_surfel;
427 ASSERT( K.sIsSurfel( start_surfel ) );
430 aSCellContour2D.clear();
431 aSCellContour2D.push_back(start_surfel);
433 SN.
init( &K, &surfel_adj, start_surfel );
435 Dimension orthDir = K.sOrthDir( start_surfel );
436 bool hasPrevNeighbor =
true;
437 while ( hasPrevNeighbor )
439 hasPrevNeighbor=
false;
441 Dimension track_dir = K.sOrthDir( b ) == orthDir ? trackDir : orthDir;
444 !K.sDirect( b, track_dir ) ) )
446 if ( bn != start_surfel )
449 hasPrevNeighbor=
true;
450 aSCellContour2D.push_back( bn );
457 reverse(aSCellContour2D.begin(), aSCellContour2D.end());
458 if ( b != start_surfel )
461 bool hasNextNeighbor =
true;
462 while ( hasNextNeighbor )
464 hasNextNeighbor=
false;
466 Dimension track_dir = K.sOrthDir( b ) == orthDir ? trackDir : orthDir;
469 K.sDirect( b, track_dir ) ) )
473 aSCellContour2D.push_back( bn );
475 hasNextNeighbor=
true;
484 template <
typename TKSpace>
485 template <
typename SurfelPredicate >
492 const SurfelPredicate & sp,
493 const SCell & start_surfel )
496 ASSERT( KSpace::dimension == 2 );
498 SCell b= start_surfel;
500 ASSERT( K.sIsSurfel( start_surfel ) );
501 aSCellContour.clear();
502 aSCellContour.push_back(start_surfel);
504 SN.
init( &K, &surfel_adj, start_surfel );
507 bool hasPrevNeighbor =
true;
508 while ( hasPrevNeighbor )
510 hasPrevNeighbor=
false;
514 ! K.sDirect( b, track_dir ) ) )
516 if ( bn != start_surfel )
518 hasPrevNeighbor=
true;
519 aSCellContour.push_back( bn );
525 reverse( aSCellContour.begin(), aSCellContour.end() );
526 if ( b != start_surfel )
529 bool hasNextNeighbor =
true;
530 while ( hasNextNeighbor )
532 hasNextNeighbor=
false;
536 K.sDirect( b, track_dir ) ) )
538 aSCellContour.push_back( bn );
539 hasNextNeighbor=
true;
547 template <
typename TKSpace>
548 template <
typename SurfelPredicate >
556 const SurfelPredicate & sp,
557 const SCell & start_surfel )
560 SCell b= start_surfel;
562 ASSERT( K.sIsSurfel( start_surfel ) );
563 aSCellContour.clear();
564 aSCellContour.push_back(start_surfel);
566 SN.
init( &K, &surfel_adj, start_surfel );
568 Dimension orthDir = K.sOrthDir( start_surfel );
569 bool hasPrevNeighbor =
true;
570 while ( hasPrevNeighbor )
572 hasPrevNeighbor=
false;
574 Dimension track_dir = K.sOrthDir( b ) == orthDir ? trackDir : orthDir;
577 !K.sDirect( b, track_dir ) ) )
579 if ( bn != start_surfel )
581 hasPrevNeighbor=
true;
582 aSCellContour.push_back( bn );
588 reverse( aSCellContour.begin(), aSCellContour.end() );
589 if ( b != start_surfel )
592 bool hasNextNeighbor =
true;
593 while ( hasNextNeighbor )
595 hasNextNeighbor=
false;
597 Dimension track_dir = K.sOrthDir( b ) == orthDir ? trackDir : orthDir;
600 K.sDirect( b, track_dir ) ) )
602 aSCellContour.push_back( bn );
603 hasNextNeighbor=
true;
613 template <
typename TKSpace>
614 template <
typename Po
intPredicate>
618 ( std::vector<Point> & aVectorOfPoints,
621 const PointPredicate & pp,
622 const SCell & start_surfel )
624 aVectorOfPoints.clear();
627 std::vector<SCell> vectBdrySCell;
629 K, surfel_adj, pp, start_surfel );
630 typedef typename std::vector<SCell>::const_iterator SCellConstIterator;
631 for ( SCellConstIterator it = vectBdrySCell.begin(),
632 it_end = vectBdrySCell.end();
636 SCell pointel = K.sIndirectIncident( *it, track );
637 aVectorOfPoints.push_back( K.sCoords( pointel ) );
645 template <
typename TKSpace>
646 template <
typename Po
intPredicate>
652 const PointPredicate & pp )
654 std::set<SCell> bdry;
655 sMakeBoundary( bdry, aKSpace, pp,
656 aKSpace.lowerBound(), aKSpace.upperBound() );
657 aVectSCellContour2D.clear();
658 while( ! bdry.empty() )
660 std::vector<SCell> aContour;
661 SCell aCell = *(bdry.begin());
662 track2DBoundary( aContour, aKSpace, aSurfelAdj, pp, aCell );
663 aVectSCellContour2D.push_back( aContour );
665 for(
unsigned int i = 0; i < aContour.size(); i++ )
667 SCell sc = aContour.at(i);
676 template <
typename TKSpace>
677 template <
typename Po
intPredicate>
680 const KSpace & aKSpace,
const PointPredicate & pp ){
681 for(
typename vector<SCell>::iterator it = aVectOfSCell.begin();
682 it!=aVectOfSCell.end(); it++){
683 SCell incidUpperDim = aKSpace.sDirectIncident(*it, aKSpace.sOrthDir(*it));
684 if( pp( aKSpace.sCoords(incidUpperDim) )){
685 aKSpace.sSetSign (*it, !aKSpace.sDirect(*it, aKSpace.sOrthDir(*it)) );
687 aKSpace.sSetSign (*it, aKSpace.sDirect(*it, !aKSpace.sOrthDir(*it)) );
696 template <
typename TKSpace>
697 template <
typename Po
intPredicate>
701 ( std::vector< std::vector<SCell> > & aVectConnectedSCell,
704 const PointPredicate & pp,
705 bool forceOrientCellExterior )
709 sMakeBoundary( bdry, aKSpace, pp,
710 aKSpace.lowerBound(), aKSpace.upperBound() );
711 aVectConnectedSCell.clear();
712 while(!bdry.empty()){
713 set<SCell> aConnectedSCellSet;
714 SCell aCell = *(bdry.begin());
715 trackBoundary(aConnectedSCellSet, aKSpace, aSurfelAdj, pp, aCell );
718 for(
typename set<SCell>::iterator it = aConnectedSCellSet.begin(); it!= aConnectedSCellSet.end(); ++it){
723 if(forceOrientCellExterior){
724 orientSCellExterior(vCS, aKSpace, pp);
726 aVectConnectedSCell.push_back(vCS);
734 template <
typename TKSpace>
735 template <
typename Po
intPredicate>
740 const PointPredicate & pp,
743 aVectPointContour2D.clear();
745 std::vector< std::vector<SCell> > vectContoursBdrySCell;
746 extractAll2DSCellContours( vectContoursBdrySCell,
747 aKSpace, aSAdj, pp );
749 for(
unsigned int i=0; i< vectContoursBdrySCell.size(); i++){
750 std::vector< Point > aContour;
751 for(
unsigned int j=0; j< vectContoursBdrySCell.at(i).size(); j++){
752 SCell sc = vectContoursBdrySCell.at(i).at(j);
757 bool xodd = ( sc.myCoordinates[ 0 ] & 1 );
758 bool yodd = ( sc.myCoordinates[ 1 ] & 1 );
759 double x0 = !xodd ? x - 0.5 : (!aKSpace.sSign(sc)? x - 0.5: x + 0.5) ;
760 double y0 = !yodd ? y - 0.5 : (!aKSpace.sSign(sc)? y - 0.5: y + 0.5);
761 double x1 = !xodd ? x - 0.5 : (aKSpace.sSign(sc)? x - 0.5: x + 0.5) ;
762 double y1 = !yodd ? y - 0.5 : (aKSpace.sSign(sc)? y - 0.5: y + 0.5);
764 Point ptA((
const int)(x0+0.5), (
const int)(y0-0.5));
765 Point ptB((
const int)(x1+0.5), (
const int)(y1-0.5)) ;
766 aContour.push_back(ptA);
767 if(sc== vectContoursBdrySCell.at(i).at(vectContoursBdrySCell.at(i).size()-1)){
768 aContour.push_back(ptB);
771 aVectPointContour2D.push_back(aContour);
778 template <
typename TKSpace>
779 template <
typename SCellSet,
typename Po
intPredicate >
785 const PointPredicate & pp,
786 const SCell & start_surfel )
790 ASSERT( K.sIsSurfel( start_surfel ) );
794 SN.
init( &K, &surfel_adj, start_surfel );
795 std::queue<SCell> qbels;
796 qbels.push( start_surfel );
797 surface.insert( start_surfel );
799 while ( ! qbels.empty() )
809 K.sDirect( b, track_dir ) ) )
811 if ( surface.find( bn ) == surface.end() )
813 surface.insert( bn );
822 template <
typename TKSpace>
823 template <
typename CellSet,
typename Po
intPredicate >
828 const PointPredicate & pp,
829 const Point & aLowerBound,
830 const Point & aUpperBound )
833 bool in_here, in_further;
834 for ( k = 0; k < aKSpace.dimension; ++k )
836 Cell dir_low_uid = aKSpace.uSpel( aLowerBound );
837 Cell dir_up_uid = aKSpace.uGetDecr( aKSpace.uSpel( aUpperBound ), k);
838 Cell p = dir_low_uid;
841 in_here = pp( aKSpace.uCoords(p) );
842 in_further = pp( aKSpace.uCoords(aKSpace.uGetIncr( p, k )) );
843 if ( in_here != in_further )
845 aBoundary.insert( aKSpace.uIncident( p, k,
true ));
848 while ( aKSpace.uNext( p, dir_low_uid, dir_up_uid ) );
855 template <
typename TKSpace>
856 template <
typename SCellSet,
typename Po
intPredicate >
861 const PointPredicate & pp,
862 const Point & aLowerBound,
863 const Point & aUpperBound )
866 bool in_here, in_further;
868 for ( k = 0; k < aKSpace.dimension; ++k )
870 Cell dir_low_uid = aKSpace.uSpel( aLowerBound );
871 Cell dir_up_uid = aKSpace.uGetDecr( aKSpace.uSpel( aUpperBound ), k);
872 Cell p = dir_low_uid;
875 in_here = pp( aKSpace.uCoords(p) );
876 in_further = pp( aKSpace.uCoords(aKSpace.uGetIncr( p, k )) );
877 if ( in_here != in_further )
879 aBoundary.insert( aKSpace.sIncident( aKSpace.signs( p, in_here ),
883 while ( aKSpace.uNext( p, dir_low_uid, dir_up_uid ) );
889 template <
typename TKSpace>
890 template <
typename OutputIterator,
typename Po
intPredicate >
895 const PointPredicate & pp,
896 const Point & aLowerBound,
const Point & aUpperBound )
899 bool in_here, in_further;
900 for ( k = 0; k < aKSpace.dimension; ++k )
902 Cell dir_low_uid = aKSpace.uSpel( aLowerBound );
903 Cell dir_up_uid = aKSpace.uGetDecr( aKSpace.uSpel( aUpperBound ), k);
904 Cell p = dir_low_uid;
907 in_here = pp( aKSpace.uCoords(p) );
908 in_further = pp( aKSpace.uCoords(aKSpace.uGetIncr( p, k )) );
909 if ( in_here != in_further )
911 *out_it++ = aKSpace.uIncident( p, k,
true );
914 while ( aKSpace.uNext( p, dir_low_uid, dir_up_uid ) );
921 template <
typename TKSpace>
922 template <
typename OutputIterator,
typename Po
intPredicate >
927 const PointPredicate & pp,
928 const Point & aLowerBound,
const Point & aUpperBound )
932 bool in_here, in_before;
934 typedef typename KSpace::Space Space;
936 std::vector< Dimension > axes( aKSpace.dimension );
937 for ( k = 0; k < aKSpace.dimension; ++k )
940 for ( k = 0; k < aKSpace.dimension; ++k )
944 std::swap( axes[ 0 ], axes[ k ] );
945 Point low = aLowerBound; ++low[ k ];
946 Point up = aUpperBound;
947 Domain domain( low, up );
949 typename Domain::ConstSubRange range = domain.subRange( axes );
950 for (
typename Domain::ConstSubRange::ConstIterator
951 it = range.begin(), it_end = range.end();
954 const Point & p = *it;
958 Point p2( p ); --p2[ k ];
959 in_before = pp( p2 );
966 if ( in_here != in_before )
968 *out_it++ = aKSpace.sIncident( aKSpace.sSpel( p, in_here ),
1002 template <
typename TKSpace>
1007 out <<
"[Surfaces]";
1014 template <
typename TKSpace>
1027 template <
typename TKSpace>
1033 object.selfDisplay( out );