DGtal 1.4.0
Loading...
Searching...
No Matches
ParDirCollapse.ih
1/**
2 * This program is free software: you can redistribute it and/or modify
3 * it under the terms of the GNU Lesser General Public License as
4 * published by the Free Software Foundation, either version 3 of the
5 * License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 *
15 **/
16
17/**
18 * @file ParDirCollapse.ih
19 * @author Bibiana MARTINEZ (\c bibiana.martinez@edu.esiee.fr )
20 * @author Mohamad ONAYSSI (\c mohamad.onayssi@edu.esiee.fr )
21 * @author Mohamed MELLOULI (\c mohamed.mellouli@edu.esiee.fr )
22 * ESIEE Paris
23 *
24 * @author Kacper Pluta (\c kacper.pluta@esiee.fr )
25 * Laboratoire d'Informatique Gaspard-Monge - LIGM, France
26 *
27 *
28 * @date 2015/12/22
29 *
30 *
31 * This file is part of the DGtal library.
32 */
33
34#include <vector>
35#include <stdexcept>
36
37///////////////////////////////////////////////////////////////////////////////
38// Implementation of inline methods //
39
40template < typename CC >
41inline
42DGtal::ParDirCollapse<CC >::ParDirCollapse( const KSpace & k ) : K ( k )
43{
44 complex = nullptr;
45}
46
47template < typename CC >
48inline
49bool
50DGtal::ParDirCollapse< CC >::isValid ( ) const
51{
52 return complex != nullptr;
53}
54
55template < typename CC >
56inline
57void
58DGtal::ParDirCollapse< CC >::attach ( Alias<CC> pComplex )
59{
60 complex = &pComplex;
61}
62
63template < typename CC >
64inline
65unsigned int
66DGtal::ParDirCollapse< CC >::eval ( unsigned int iterations )
67{
68 assert ( isValid() );
69 std::vector<Cell> SUB;
70 unsigned int collapseval = 0;
71 unsigned int removed = 1;
72 typename CC::DefaultCellMapIteratorPriority P;
73 for ( unsigned int i = 0; i < iterations && removed > 0; i++ )
74 {
75 CC boundary = complex->boundary();
76 unsigned int priority = 0;
77 for ( Dimension dir = 0; dir < K.dimension; dir++ )
78 {
79 for ( int orient = -1 ; orient <= 1; orient += 2 )
80 {
81 for ( int dim = K.dimension - 1; dim >= 0; dim-- )
82 {
83 for ( CellMapConstIterator begin = boundary.begin ( dim ); begin != boundary.end ( dim ); ++begin, priority++ )
84 {
85 if ( K.uDim ( begin->first ) == (unsigned int) dim )
86 {
87 Cell G;
88 if ( completeFreepair ( begin, G, orient, dir ) )
89 {
90 SUB.push_back ( G );
91 complex->insertCell ( SUB.back(), priority );
92 SUB.push_back ( begin->first );
93 complex->insertCell ( SUB.back(), priority );
94 }
95 }
96 }
97 removed = DGtal::functions::collapse ( *complex, SUB.begin(), SUB.end(), P, true, true, verbose );
98 SUB.clear();
99 priority = 0;
100 collapseval += removed;
101 }
102 }
103 }
104 }
105 return collapseval;
106}
107
108template < typename CC >
109inline
110bool
111DGtal::ParDirCollapse< CC >::completeFreepair ( CellMapConstIterator F, Cell & G, int orient, int dir )
112{
113 if ( F->second.data == CC::FIXED )
114 return false;
115 Cells faces = K.uUpperIncident ( F->first );
116 Dimension dim = K.uDim ( F->first ) + 1;
117 for ( Size j = 0; j < faces.size(); j++ )
118 {
119 if ( complex->findCell ( dim, faces[j] ) != complex->end ( dim ) )
120 {
121 if ( getOrientation ( (*F).first, faces[j] ) == orient && getDirection ( (*F).first, faces[j] ) == dir )
122 {
123 CellMapConstIterator cmIt = complex->findCell ( dim, faces[j] );
124 if ( cmIt->second.data != CC::FIXED )
125 {
126 G = faces[j];
127 return true;
128 }
129 else
130 return false;
131 }
132 }
133 }
134 return false;
135}
136
137template < typename CC >
138inline
139int
140DGtal::ParDirCollapse< CC >::getOrientation( const Cell& F, const Cell& G ) const
141{
142 Point V = K.uKCoords ( F ) - K.uKCoords ( G );
143 for ( Dimension i = 0; i < K.dimension; i++ )
144 if ( V[i] != 0 ) return V[i];
145 throw std::runtime_error ( "Cells F and G are same!" );
146}
147
148template < typename CC >
149inline
150int
151DGtal::ParDirCollapse< CC >::getDirection ( const Cell& F, const Cell& G ) const
152{
153 Point V = K.uKCoords ( F ) - K.uKCoords ( G );
154 for ( Dimension i = 0; i< K.dimension; i++ )
155 if ( V[i] != 0 ) return i;
156 throw std::runtime_error ( "Cells F and G are same!" );
157}
158
159template < typename CC >
160inline
161void
162DGtal::ParDirCollapse< CC >::collapseSurface()
163{
164 while ( eval ( 1 ) )
165 {
166 CellMapConstIterator constIterator = complex->begin ( K.dimension - 1 );
167 CellMapConstIterator itEd = complex->end ( K.dimension - 1 );
168 for ( ; constIterator != itEd; ++constIterator )
169 if ( isNotIncludedInUpperDim ( constIterator ) )
170 complex->insertCell ( constIterator->first, CC::FIXED );
171 }
172}
173
174template < typename CC >
175inline
176void
177DGtal::ParDirCollapse< CC >::collapseIsthmus()
178{
179 while ( eval ( 1 ) )
180 {
181 CellMapConstIterator constIterator = complex->begin ( K.dimension - 1 );
182 CellMapConstIterator itEd = complex->end ( K.dimension - 1 );
183 for ( ; constIterator != itEd; ++constIterator )
184 if ( isNotIncludedInUpperDim ( constIterator ) && isIsthmus ( constIterator ) )
185 complex->insertCell ( constIterator->first, CC::FIXED );
186 }
187}
188
189template < typename CC >
190inline
191bool
192DGtal::ParDirCollapse< CC >::isNotIncludedInUpperDim ( CellMapConstIterator F )
193{
194 Cells faces = K.uUpperIncident ( F->first );
195 Dimension dim = K.uDim ( F->first ) + 1;
196 for ( Size i = 0; i < faces.size(); i++ )
197 if ( complex->findCell ( dim, faces[i] ) != complex->end ( dim ) )
198 return false;
199 return true;
200}
201
202template < typename CC >
203inline
204bool
205DGtal::ParDirCollapse< CC >::isIsthmus ( CellMapConstIterator F )
206{
207 Cells faces = K.uLowerIncident ( F->first );
208 for ( Size i = 0; i < faces.size(); i++ )
209 {
210 int count = 0;
211 if ( K.uDim ( faces[i] ) == K.dimension - 2 )
212 {
213 Cells facesUpper = K.uUpperIncident ( faces[i] );
214 for ( Size j = 0; j < facesUpper.size(); j++ )
215 if ( complex->findCell ( K.dimension - 1, facesUpper[j] ) != complex->end ( K.dimension - 1 ) )
216 count++;
217 if ( count <= 1 )
218 return false;
219 }
220 }
221 return true;
222}
223
224// //
225///////////////////////////////////////////////////////////////////////////////