33 #include "DGtal/topology/CVertexPredicate.h"
44 template <
typename TDigitalSurfaceContainer>
48 if ( myTracker != 0 )
delete myTracker;
51 template <
typename TDigitalSurfaceContainer>
61 template <
typename TDigitalSurfaceContainer>
64 (
const TDigitalSurfaceContainer & aContainer )
67 if ( ! myContainer->empty() )
69 Surfel s = *( myContainer->begin() );
70 myTracker = myContainer->newTracker( s );
71 myUmbrellaComputer.init( *myTracker, 0,
false, 1 );
77 template <
typename TDigitalSurfaceContainer>
80 ( TDigitalSurfaceContainer* containerPtr )
81 : myContainer( containerPtr )
83 if ( ! myContainer->empty() )
85 Surfel s = *( myContainer->begin() );
86 myTracker = myContainer->newTracker( s );
87 myUmbrellaComputer.init( *myTracker, 0,
false, 1 );
93 template <
typename TDigitalSurfaceContainer>
102 if ( myTracker != 0 )
delete myTracker;
109 template <
typename TDigitalSurfaceContainer>
111 const TDigitalSurfaceContainer &
117 template <
typename TDigitalSurfaceContainer>
119 TDigitalSurfaceContainer &
125 template <
typename TDigitalSurfaceContainer>
130 return myContainer->begin();
133 template <
typename TDigitalSurfaceContainer>
138 return myContainer->end();
141 template <
typename TDigitalSurfaceContainer>
146 return myContainer->nbSurfels();
149 template <
typename TDigitalSurfaceContainer>
154 return KSpace::dimension*2 - 2;
157 template <
typename TDigitalSurfaceContainer>
165 myTracker->move( v );
166 for (
typename KSpace::DirIterator q = container().space().sDirs( v );
169 if ( myTracker->adjacent( s, *q,
true ) )
171 if ( myTracker->adjacent( s, *q,
false ) )
177 template <
typename TDigitalSurfaceContainer>
178 template <
typename OutputIterator>
186 myTracker->move( v );
187 for (
typename KSpace::DirIterator q = container().space().sDirs( v );
190 if ( myTracker->adjacent( s, *q,
true ) )
192 if ( myTracker->adjacent( s, *q,
false ) )
197 template <
typename TDigitalSurfaceContainer>
198 template <
typename OutputIterator,
typename VertexPredicate>
204 const VertexPredicate & pred )
const
208 myTracker->move( v );
209 for (
typename KSpace::DirIterator q = container().space().sDirs( v );
212 if ( myTracker->adjacent( s, *q,
true ) )
214 if ( pred( s ) ) *it++ = s;
216 if ( myTracker->adjacent( s, *q,
false ) )
218 if ( pred( s ) ) *it++ = s;
224 template <
typename TDigitalSurfaceContainer>
232 myTracker->move( v );
233 for (
typename KSpace::DirIterator q = container().space().sDirs( v );
237 if ( myTracker->adjacent( s, i,
true ) )
238 arcs.push_back(
Arc( v, i,
true ) );
239 if ( myTracker->adjacent( s, i,
false ) )
240 arcs.push_back(
Arc( v, i,
false ) );
245 template <
typename TDigitalSurfaceContainer>
253 myTracker->move( v );
254 for (
typename KSpace::DirIterator q = container().space().sDirs( v );
258 if ( myTracker->adjacent( s, i,
true ) )
259 arcs.push_back( opposite(
Arc( v, i,
true ) ) );
260 if ( myTracker->adjacent( s, i,
false ) )
261 arcs.push_back( opposite(
Arc( v, i,
false ) ) );
267 template <
typename TDigitalSurfaceContainer>
273 typedef typename ArcRange::const_iterator ArcRangeConstIterator;
277 std::back_insert_iterator<FaceRange> output_it = std::back_inserter( faces );
278 for ( ArcRangeConstIterator it = arcs.begin(), it_end = arcs.end();
283 FaceRange faces_of_arc = facesAroundArc( *it );
285 std::copy( faces_of_arc.begin(), faces_of_arc.end(), output_it );
290 template <
typename TDigitalSurfaceContainer>
297 myTracker->move( a.
base );
303 template <
typename TDigitalSurfaceContainer>
312 template <
typename TDigitalSurfaceContainer>
319 myTracker->move( a.
base );
322 if ( code == 2 )
return Arc( s, a.
k, ! a.
epsilon );
325 bool orientation = container().space().sDirect( a.
base, a.
k );
326 unsigned int i = myTracker->orthDir();
329 == container().space().sDirect( s, i ) );
333 template <
typename TDigitalSurfaceContainer>
339 const KSpace & K = container().space();
340 Point p1 = K.sKCoords( t );
341 Point p2 = K.sKCoords( h );
343 for (
typename KSpace::DirIterator q = K.sDirs( h );
347 if ( p1[ i ] != 0 )
return Arc( t, i, p1[ i ] > 0 );
349 ASSERT(
false &&
"DGtal::DigitalSurface<TDigitalSurfaceContainer>::arc( tail, head ): tail and head are not adjacent." );
350 return Arc( t, 0,
true );
353 template <
typename TDigitalSurfaceContainer>
361 myUmbrellaComputer.setState( state );
362 SCell sep = myUmbrellaComputer.separator();
364 for (
typename KSpace::DirIterator q = container().space().sDirs( sep );
368 faces.push_back( computeFace( state ) );
374 template <
typename TDigitalSurfaceContainer>
381 myUmbrellaComputer.setState( f.
state );
382 for (
unsigned int i = 0; i < f.
nbVertices; ++i )
384 vertices.push_back( myUmbrellaComputer.surfel() );
385 myUmbrellaComputer.previous();
390 template <
typename TDigitalSurfaceContainer>
397 for (
ConstIterator it = begin(), it_end = end(); it != it_end; ++it )
399 FaceRange local_faces = facesAroundVertex( *it );
400 all_faces.insert( local_faces.begin(), local_faces.end() );
405 template <
typename TDigitalSurfaceContainer>
412 for (
ConstIterator it = begin(), it_end = end(); it != it_end; ++it )
414 FaceRange local_faces = facesAroundVertex( *it );
415 for (
typename FaceRange::const_iterator lit = local_faces.begin(),
416 lit_end = local_faces.end(); lit != lit_end; ++lit )
417 if ( lit->isClosed() )
418 all_faces.insert( *lit );
423 template <
typename TDigitalSurfaceContainer>
430 for (
ConstIterator it = begin(), it_end = end(); it != it_end; ++it )
432 FaceRange local_faces = facesAroundVertex( *it );
433 for (
typename FaceRange::const_iterator lit = local_faces.begin(),
434 lit_end = local_faces.end(); lit != lit_end; ++lit )
435 if ( ! lit->isClosed() )
436 all_faces.insert( *lit );
442 template <
typename TDigitalSurfaceContainer>
448 myUmbrellaComputer.setState( state );
449 Surfel start = state.surfel;
457 code = myUmbrellaComputer.previous();
458 if ( code == 0 )
break;
459 if ( myUmbrellaComputer.state() < state )
460 state = myUmbrellaComputer.
state();
462 while ( myUmbrellaComputer.surfel() != start );
471 code = myUmbrellaComputer.next();
474 return Face( myUmbrellaComputer.state(), nb,
false );
477 return Face( state, nb,
true );
480 template <
typename TDigitalSurfaceContainer>
486 return container().space().sIncident( a.
base, a.
k, a.
epsilon );
499 template <
typename TDigitalSurfaceContainer>
507 return container().space().sDirectIncident( sep, f.
state.j );
519 template <
typename TDigitalSurfaceContainer>
524 out <<
"[DigitalSurface]";
531 template <
typename TDigitalSurfaceContainer>
536 return myTracker != 0;
544 template <
typename TDigitalSurfaceContainer>
551 std::map<Vertex, Number> index;
555 index[ *it ] = nbv++;
558 FaceSet faces = allClosedFaces();
562 for (
typename FaceSet::const_iterator
563 itf = faces.begin(), itf_end = faces.end();
564 itf != itf_end; ++itf )
566 if ( itf->isClosed() )
567 { nbe += itf->nbVertices; ++nbf; }
569 { nbe += itf->nbVertices - 1; }
573 out <<
"OFF" << std::endl
574 <<
"# Generated by DGtal::DigitalSurface." << std::endl
575 << nbv <<
" " << nbf <<
" " << ( nbe / 2 ) << std::endl;
577 const KSpace & K = container().space();
581 Point p = K.sKCoords( *it );
582 out << p[ 0 ] <<
" " << p[ 1 ] <<
" " << p[ 2 ] << std::endl;
586 for (
typename FaceSet::const_iterator
587 itf = faces.begin(), itf_end = faces.end();
588 itf != itf_end; ++itf )
590 if ( itf->isClosed() )
592 out << itf->nbVertices;
594 for (
typename VertexRange::const_iterator
595 itv = vtcs.begin(), itv_end = vtcs.end();
596 itv != itv_end; ++itv )
597 out <<
" " << index[ *itv ];
604 template <
typename TDigitalSurfaceContainer>
605 template <
typename CellEmbedder>
609 ( std::ostream & out,
610 const CellEmbedder & cembedder )
const
616 std::map<Vertex, Number> index;
620 index[ *it ] = nbv++;
623 FaceSet faces = allClosedFaces();
627 for (
typename FaceSet::const_iterator
628 itf = faces.begin(), itf_end = faces.end();
629 itf != itf_end; ++itf )
631 if ( itf->isClosed() )
632 { nbe += itf->nbVertices; ++nbf; }
634 { nbe += itf->nbVertices - 1; }
638 out <<
"OFF" << std::endl
639 <<
"# Generated by DGtal::DigitalSurface." << std::endl
640 << nbv <<
" " << nbf <<
" " << ( nbe / 2 ) << std::endl;
642 typedef typename CellEmbedder::RealPoint RealPoint;
643 const KSpace & K = container().space();
647 RealPoint p( cembedder( K.unsigns( *it ) ) );
648 out << p[ 0 ] <<
" " << p[ 1 ] <<
" " << p[ 2 ] << std::endl;
652 for (
typename FaceSet::const_iterator
653 itf = faces.begin(), itf_end = faces.end();
654 itf != itf_end; ++itf )
656 if ( itf->isClosed() )
658 out << itf->nbVertices;
660 for (
typename VertexRange::const_iterator
661 itv = vtcs.begin(), itv_end = vtcs.end();
662 itv != itv_end; ++itv )
663 out <<
" " << index[ *itv ];
670 template <
typename TDigitalSurfaceContainer>
671 template <
typename CellEmbedder>
675 ( std::ostream & out,
676 const CellEmbedder & cembedder )
const
681 typedef typename CellEmbedder::GradientMap GradientMap;
682 typedef typename CellEmbedder::Cell MyCell;
683 typedef typename CellEmbedder::RealPoint RealPoint;
684 typedef typename CellEmbedder::RealVector RealVector;
688 GradientMap gradMap = cembedder.gradientMap();
690 std::map<Vertex, Number> index;
694 index[ *it ] = nbv++;
697 FaceSet faces = allClosedFaces();
701 for (
typename FaceSet::const_iterator
702 itf = faces.begin(), itf_end = faces.end();
703 itf != itf_end; ++itf )
705 if ( itf->isClosed() )
706 { nbe += itf->nbVertices; ++nbf; }
708 { nbe += itf->nbVertices - 1; }
712 out <<
"NOFF" << std::endl
713 <<
"# Generated by DGtal::DigitalSurface." << std::endl
714 << nbv <<
" " << nbf <<
" " << ( nbe / 2 ) << std::endl;
716 const KSpace & K = container().space();
722 MyCell c = K.unsigns( *it );
726 double norm = v.norm();
727 if ( norm != 0.0 ) v /= norm;
728 out << p[ 0 ] <<
" " << p[ 1 ] <<
" " << p[ 2 ] <<
" "
729 << v[ 0 ] <<
" " << v[ 1 ] <<
" " << v[ 2 ] << std::endl;
733 for (
typename FaceSet::const_iterator
734 itf = faces.begin(), itf_end = faces.end();
735 itf != itf_end; ++itf )
737 if ( itf->isClosed() )
739 out << itf->nbVertices;
741 for (
typename VertexRange::const_iterator
742 itv = vtcs.begin(), itv_end = vtcs.end();
743 itv != itv_end; ++itv )
744 out <<
" " << index[ *itv ];
751 template <
typename TDigitalSurfaceContainer>
752 template <
typename SCellEmbedderWithGradientMap>
756 ( std::ostream & out,
757 const SCellEmbedderWithGradientMap & scembedder )
const
762 typedef typename SCellEmbedderWithGradientMap::GradientMap GradientMap;
763 typedef typename SCellEmbedderWithGradientMap::SCell MySCell;
764 typedef typename SCellEmbedderWithGradientMap::RealPoint RealPoint;
765 typedef typename SCellEmbedderWithGradientMap::RealVector RealVector;
769 GradientMap gradMap = scembedder.gradientMap();
771 std::map<Vertex, Number> index;
775 index[ *it ] = nbv++;
778 FaceSet faces = allClosedFaces();
782 for (
typename FaceSet::const_iterator
783 itf = faces.begin(), itf_end = faces.end();
784 itf != itf_end; ++itf )
786 if ( itf->isClosed() )
787 { nbe += itf->nbVertices; ++nbf; }
789 { nbe += itf->nbVertices - 1; }
793 out <<
"NOFF" << std::endl
794 <<
"# Generated by DGtal::DigitalSurface." << std::endl
795 << nbv <<
" " << nbf <<
" " << ( nbe / 2 ) << std::endl;
806 double norm = v.norm();
807 if ( norm != 0.0 ) v /= norm;
808 out << p[ 0 ] <<
" " << p[ 1 ] <<
" " << p[ 2 ] <<
" "
809 << v[ 0 ] <<
" " << v[ 1 ] <<
" " << v[ 2 ] << std::endl;
813 for (
typename FaceSet::const_iterator
814 itf = faces.begin(), itf_end = faces.end();
815 itf != itf_end; ++itf )
817 if ( itf->isClosed() )
819 out << itf->nbVertices;
821 for (
typename VertexRange::const_iterator
822 itv = vtcs.begin(), itv_end = vtcs.end();
823 itv != itv_end; ++itv )
824 out <<
" " << index[ *itv ];
831 template <
typename TDigitalSurfaceContainer>
832 template <
typename CellEmbedder>
836 ( std::ostream & out,
837 const CellEmbedder & cembedder )
const
841 std::map<Vertex, Number> index;
845 index[ *it ] = nbv++;
848 FaceSet faces = allClosedFaces();
852 for (
typename FaceSet::const_iterator
853 itf = faces.begin(), itf_end = faces.end();
854 itf != itf_end; ++itf )
856 if ( itf->isClosed() )
857 { nbe += itf->nbVertices; ++nbf; }
859 { nbe += itf->nbVertices - 1; }
863 out <<
"NOFF" << std::endl
864 <<
"# Generated by DGtal::DigitalSurface." << std::endl
865 << nbv <<
" " << nbf <<
" " << ( nbe / 2 ) << std::endl;
867 typedef typename CellEmbedder::RealPoint RealPoint;
868 typedef typename CellEmbedder::RealVector RealVector;
869 const KSpace & K = container().space();
875 cembedder.embedSurfel( it, p, v );
876 double norm = v.
norm();
877 if ( norm != 0.0 ) v /= norm;
878 out << p[ 0 ] <<
" " << p[ 1 ] <<
" " << p[ 2 ] <<
" "
879 << v[ 0 ] <<
" " << v[ 1 ] <<
" " << v[ 2 ] << std::endl;
883 for (
typename FaceSet::const_iterator
884 itf = faces.begin(), itf_end = faces.end();
885 itf != itf_end; ++itf )
887 if ( itf->isClosed() )
889 out << itf->nbVertices;
891 for (
typename VertexRange::const_iterator
892 itv = vtcs.begin(), itv_end = vtcs.end();
893 itv != itv_end; ++itv )
894 out <<
" " << index[ *itv ];
906 template <
typename TDigitalSurfaceContainer>
912 object.selfDisplay( out );