G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsAAPolyline.h
Go to the documentation of this file.
1
14#pragma once
15
17
18namespace gismo
19{
20
21template<class T>
22class gsAAPolyline
23{
29public:
30
31 gsAAPolyline()
32 {
33 m_closed = false;
34 }
35
36 gsAAPolyline(gsVSegment<T> VSeg)
37 {
38 std::vector<T> newPoint(2);
39 newPoint[0] = VSeg.getX();
40 newPoint[1] = VSeg.getYDown();
41 m_vertices.push_back( newPoint );
42 newPoint[1] = VSeg.getYUp();
43 m_vertices.push_back( newPoint );
44 m_closed = false;
45 }
46
48 std::vector< std::vector< index_t > > writeParasolid();
49
51 std::vector< std::vector<unsigned int > > writeParasolidUnsigned();
52
54 inline bool addVerticalSegment( int x, int y0, int y1 )
55 {
56 return ((pushBack(x, y0, y1)) ||
57 (pushBack(x, y1, y0)) ||
58 (pushFront(x, y0, y1)) ||
59 (pushFront(x, y1, y0)));
60 }
61
63 inline bool canBeExtended( gsVSegment<T> vert_seg )
64 {
65 return addVerticalSegment( vert_seg.getX(), vert_seg.getYDown(), vert_seg.getYUp() );
66 }
67
70 bool almostClosed()
71 {
72 if ( frontY() == backY() )
73 {
74 // It could have happened that the vertices forming the last and first line are colinear.
75 if( frontX() == backX() ) // WARNING: Assumes the last end first line to be vertical.
76 {
77 m_vertices.pop_back();
78 m_vertices.front()[1] = backY();
79 m_vertices.pop_back();
80 }
81 return true;
82 }
83 return false;
84 }
85
87 bool mergeWith( gsAAPolyline<T>& other_poly );
88
89 inline std::list< std::vector<T> > getVertices()
90 {
91 return m_vertices;
92 }
93
94 inline T frontX()
95 {
96 return m_vertices.front()[0];
97 }
98
99 inline T backX()
100 {
101 return m_vertices.back()[0];
102 }
103
104 inline T frontY()
105 {
106 return m_vertices.front()[1];
107 }
108
109 inline T backY()
110 {
111 return m_vertices.back()[1];
112 }
113
114protected:
115
117 std::list< std::vector<T> > m_vertices;
118
120 bool m_closed;
121
123 bool pushBack( T x, T y0, T y1 );
124
126 bool pushFront( T x, T y0, T y1 );
127};
128
129template <class T>
130bool gsAAPolyline<T>::pushBack( T x, T y0, T y1 )
131{
132 if( m_vertices.empty() || (y0 == backY() ))
133 {
134 if( m_vertices.empty() || x != backX() ) // new segment
135 {
136 std::vector< T > newVertex (2);
137
138 newVertex[0] = x;
139 newVertex[1] = y0;
140 m_vertices.push_back( newVertex );
141
142 newVertex[1] = y1; // x coord is the same
143 m_vertices.push_back( newVertex );
144 }
145 else // prolongation of the last segment
146 m_vertices.back()[1] = y1;
147
148 m_closed = almostClosed(); // This also looks, if the last and first segment can be merged.
149 return true;
150 }
151
152 else // appending would not be axis aligned
153 return false;
154}
155
156template <class T>
157bool gsAAPolyline<T>::pushFront( T x, T y0, T y1 ) // Symmetric case to push_back
158{
159 if( m_vertices.empty() || y0 == frontY() )
160 {
161 if( m_vertices.empty() || x != frontX() ) // Adding a segment with a different x coordinate
162 {
163 std::vector< T > newVertex (2);
164
165 newVertex[0] = x;
166 newVertex[1] = y0;
167 m_vertices.push_front( newVertex );
168
169 newVertex[1] = y1;
170 m_vertices.push_front( newVertex );
171 }
172 else
173 m_vertices.front()[1] = y1; // Adding a colinear point is just a prolongation.
174
175 m_closed = almostClosed();
176 return true;
177 }
178 else
179 return false;
180}
181
182template<class T>
183std::vector< std::vector< index_t > > gsAAPolyline<T>::writeParasolid()
184{
185 std::vector< std::vector< index_t > > result;
186
187 if( m_vertices.size() < 4 )
188 {
189 gsWarn << "Function write_parasolid() says: only " << m_vertices.size() << " vertices.\n";
190 return result;
191 }
192
193 if( !almostClosed() )
194 {
195 gsWarn << "Function write_parasolid() says: your curve should be closed but it isn't.";
196 return result;
197 }
198
199 std::vector< index_t > item(4);
200
201 // it will go through m_vertices; it_fwd will be pointing always to it's next % m_vertices.size().
202 auto it_fwd = m_vertices.begin();
203 ++it_fwd;
204 for(auto it = m_vertices.begin(); it != m_vertices.end(); ++it, ++it_fwd)
205 {
206 if( it_fwd == m_vertices.end() ) // cyclic list
207 it_fwd = m_vertices.begin();
208
209 // The lines are expected oriented from left to right, from bottom up.
210 item[0] = std::min( (*it)[0], (*it_fwd)[0] );
211 item[1] = std::min( (*it)[1], (*it_fwd)[1] );
212 item[2] = std::max( (*it)[0], (*it_fwd)[0] );
213 item[3] = std::max( (*it)[1], (*it_fwd)[1] );
214
215 result.push_back( item );
216 }
217 return result;
218}
219
220
221template<class T>
222std::vector< std::vector< unsigned int > > gsAAPolyline<T>::writeParasolidUnsigned()
223{
224 std::vector< std::vector<unsigned int > > result;
225
226 if( m_vertices.size() < 4 )
227 {
228 gsWarn << "write_parasolid() says: only " << m_vertices.size() << " vertices.\n";
229 return result;
230 }
231
232 if( !almostClosed() )
233 {
234 gsWarn << "write_parasolid() says: your curve should be closed but it isn't.";
235 return result;
236 }
237
238 std::vector< unsigned int > item(4,0);
239
240 // it will go through m_vertices; it_fwd will be pointing always to it's next % m_vertices.size().
241 auto it_fwd = m_vertices.begin();
242 ++it_fwd;
243 for(auto it = m_vertices.begin(); it != m_vertices.end(); ++it, ++it_fwd)
244 {
245 if( it_fwd == m_vertices.end() ) // cyclic list
246 it_fwd = m_vertices.begin();
247
248 // The lines are expected oriented from left to right, from bottom up.
249 item[0] = std::min( (*it)[0], (*it_fwd)[0] );
250 item[1] = std::min( (*it)[1], (*it_fwd)[1] );
251 item[2] = std::max( (*it)[0], (*it_fwd)[0] );
252 item[3] = std::max( (*it)[1], (*it_fwd)[1] );
253
254 result.push_back( item );
255 }
256 return result;
257}
258
259template <class T>
260bool gsAAPolyline<T>::mergeWith( gsAAPolyline<T>& otherPoly )
261{
262 // We assume both polylines to be ending with a vertical segment (!).
263 std::list< std::vector<T> > newVertices;
264
265 // adding in front of m_vertices
266 if( otherPoly.backY() == frontY() )
267 {
268 newVertices = otherPoly.getVertices();
269 if( newVertices.back() == m_vertices.front() )
270 {
271 newVertices.pop_back();
272 m_vertices.pop_front();
273 }
274 m_vertices.splice( m_vertices.begin(), newVertices );
275 m_closed = almostClosed();
276 return true;
277 }
278 // adding behind vertices in reverse order
279 else if( otherPoly.backY() == backY() )
280 {
281 newVertices = otherPoly.getVertices();
282 newVertices.reverse();
283 if( newVertices.front() == m_vertices.back() )
284 {
285 newVertices.pop_front();
286 m_vertices.pop_back();
287 }
288 m_vertices.splice( m_vertices.end(), newVertices );
289 m_closed = almostClosed();
290 return true;
291 }
292 // adding in front of m_vertices in reverse order
293 else if( otherPoly.frontY() == frontY() )
294 {
295 newVertices = otherPoly.getVertices();
296 newVertices.reverse();
297 if( newVertices.back() == m_vertices.front() )
298 {
299 newVertices.pop_back();
300 m_vertices.pop_front();
301 }
302 m_vertices.splice( m_vertices.begin(), newVertices );
303 m_closed = almostClosed();
304 return true;
305 }
306 // adding behind m_vertices
307 else if( otherPoly.frontY() == backY() )
308 {
309 newVertices = otherPoly.getVertices();
310 if( newVertices.front() == m_vertices.back() )
311 {
312 newVertices.pop_front();
313 m_vertices.pop_back();
314 }
315 m_vertices.splice( m_vertices.end(), newVertices );
316 m_closed = almostClosed();
317 return true;
318 }
319 // none of the previous was possible
320 else
321 return false;
322}
323
324
325} // namespace gismo
#define gsWarn
Definition gsDebug.h:50
Helper class for gsAAPolyline.
The G+Smo namespace, containing all definitions for the library.