1
2 ///////////////////////////////////////////////////////////
3 // //
4 // SAGA //
5 // //
6 // System for Automated Geoscientific Analyses //
7 // //
8 // Application Programming Interface //
9 // //
10 // Library: SAGA_API //
11 // //
12 //-------------------------------------------------------//
13 // //
14 // tin.cpp //
15 // //
16 // Copyright (C) 2005 by Olaf Conrad //
17 // //
18 //-------------------------------------------------------//
19 // //
20 // This file is part of 'SAGA - System for Automated //
21 // Geoscientific Analyses'. //
22 // //
23 // This library is free software; you can redistribute //
24 // it and/or modify it under the terms of the GNU Lesser //
25 // General Public License as published by the Free //
26 // Software Foundation, either version 2.1 of the //
27 // License, or (at your option) any later version. //
28 // //
29 // This library is distributed in the hope that it will //
30 // be useful, but WITHOUT ANY WARRANTY; without even the //
31 // implied warranty of MERCHANTABILITY or FITNESS FOR A //
32 // PARTICULAR PURPOSE. See the GNU Lesser General Public //
33 // License for more details. //
34 // //
35 // You should have received a copy of the GNU Lesser //
36 // General Public License along with this program; if //
37 // not, see <http://www.gnu.org/licenses/>. //
38 // //
39 //-------------------------------------------------------//
40 // //
41 // contact: Olaf Conrad //
42 // Institute of Geography //
43 // University of Goettingen //
44 // Goldschmidtstr. 5 //
45 // 37077 Goettingen //
46 // Germany //
47 // //
48 // e-mail: oconrad@saga-gis.org //
49 // //
50 ///////////////////////////////////////////////////////////
51
52 //---------------------------------------------------------
53 #include "tin.h"
54
55
56 ///////////////////////////////////////////////////////////
57 // //
58 // //
59 // //
60 ///////////////////////////////////////////////////////////
61
62 //---------------------------------------------------------
SG_Create_TIN(void)63 CSG_TIN * SG_Create_TIN(void)
64 {
65 return( new CSG_TIN );
66 }
67
68 //---------------------------------------------------------
SG_Create_TIN(const CSG_TIN & TIN)69 CSG_TIN * SG_Create_TIN(const CSG_TIN &TIN)
70 {
71 return( new CSG_TIN(TIN) );
72 }
73
74 //---------------------------------------------------------
SG_Create_TIN(const CSG_String & File_Name)75 CSG_TIN * SG_Create_TIN(const CSG_String &File_Name)
76 {
77 return( new CSG_TIN(File_Name) );
78 }
79
80 //---------------------------------------------------------
SG_Create_TIN(CSG_Shapes * pShapes)81 CSG_TIN * SG_Create_TIN(CSG_Shapes *pShapes)
82 {
83 return( new CSG_TIN(pShapes) );
84 }
85
86
87 ///////////////////////////////////////////////////////////
88 // //
89 // //
90 // //
91 ///////////////////////////////////////////////////////////
92
93 //---------------------------------------------------------
CSG_TIN(void)94 CSG_TIN::CSG_TIN(void)
95 : CSG_Table()
96 {
97 _On_Construction();
98 }
99
100 //---------------------------------------------------------
CSG_TIN(const CSG_TIN & TIN)101 CSG_TIN::CSG_TIN(const CSG_TIN &TIN)
102 : CSG_Table()
103 {
104 _On_Construction();
105
106 Create(TIN);
107 }
108
109 //---------------------------------------------------------
CSG_TIN(const CSG_String & File_Name)110 CSG_TIN::CSG_TIN(const CSG_String &File_Name)
111 : CSG_Table()
112 {
113 _On_Construction();
114
115 Create(File_Name);
116 }
117
118 //---------------------------------------------------------
CSG_TIN(CSG_Shapes * pShapes)119 CSG_TIN::CSG_TIN(CSG_Shapes *pShapes)
120 : CSG_Table()
121 {
122 _On_Construction();
123
124 Create(pShapes);
125 }
126
127
128 ///////////////////////////////////////////////////////////
129 // //
130 ///////////////////////////////////////////////////////////
131
132 //---------------------------------------------------------
_On_Construction(void)133 void CSG_TIN::_On_Construction(void)
134 {
135 CSG_Table::_On_Construction();
136
137 m_Edges = NULL;
138 m_nEdges = 0;
139
140 m_Triangles = NULL;
141 m_nTriangles = 0;
142 }
143
144
145 ///////////////////////////////////////////////////////////
146 // //
147 ///////////////////////////////////////////////////////////
148
149 //---------------------------------------------------------
Create(const CSG_TIN & TIN)150 bool CSG_TIN::Create(const CSG_TIN &TIN)
151 {
152 return( Assign((CSG_Data_Object *)&TIN) );
153 }
154
155 //---------------------------------------------------------
Create(const CSG_String & File_Name)156 bool CSG_TIN::Create(const CSG_String &File_Name)
157 {
158 CSG_Shapes Shapes(File_Name);
159
160 if( Create(&Shapes) )
161 {
162 Get_History().Add_Child(_TL("Created from file"), File_Name);
163 Get_History().Add_Children(Shapes.Get_History());
164
165 Set_File_Name(File_Name, true);
166 Set_Modified(false);
167 Set_Update_Flag();
168
169 return( true );
170 }
171
172 return( false );
173 }
174
175 //---------------------------------------------------------
Create(CSG_Shapes * pShapes)176 bool CSG_TIN::Create(CSG_Shapes *pShapes)
177 {
178 Destroy();
179
180 if( pShapes && pShapes->is_Valid() )
181 {
182 SG_UI_Msg_Add(CSG_String::Format("%s: %s...", _TL("Create TIN from shapes"), pShapes->Get_Name()), true);
183
184 CSG_Table::Create(pShapes);
185
186 Set_Name(pShapes->Get_Name());
187
188 //-------------------------------------------------
189 for(int iShape=0; iShape<pShapes->Get_Count() && SG_UI_Process_Set_Progress(iShape, pShapes->Get_Count()); iShape++)
190 {
191 CSG_Shape *pShape = pShapes->Get_Shape(iShape);
192
193 for(int iPart=0; iPart<pShape->Get_Part_Count(); iPart++)
194 {
195 for(int iPoint=0; iPoint<pShape->Get_Point_Count(iPart); iPoint++)
196 {
197 Add_Node(pShape->Get_Point(iPoint, iPart), pShape, false);
198 }
199 }
200 }
201
202 SG_UI_Process_Set_Ready();
203
204 if( Update() )
205 {
206 SG_UI_Msg_Add(_TL("okay"), false, SG_UI_MSG_STYLE_SUCCESS);
207
208 return( true );
209 }
210 }
211
212 SG_UI_Msg_Add(_TL("failed"), false, SG_UI_MSG_STYLE_FAILURE);
213
214 return( false );
215 }
216
217
218 ///////////////////////////////////////////////////////////
219 // //
220 ///////////////////////////////////////////////////////////
221
222 //---------------------------------------------------------
~CSG_TIN(void)223 CSG_TIN::~CSG_TIN(void)
224 {
225 Destroy();
226 }
227
228 //---------------------------------------------------------
Destroy(void)229 bool CSG_TIN::Destroy(void)
230 {
231 _Destroy_Triangles();
232 _Destroy_Edges();
233 _Destroy_Nodes();
234
235 CSG_Table::Destroy();
236
237 return( true );
238 }
239
240
241 ///////////////////////////////////////////////////////////
242 // //
243 ///////////////////////////////////////////////////////////
244
245 //---------------------------------------------------------
_Destroy_Nodes(void)246 bool CSG_TIN::_Destroy_Nodes(void)
247 {
248 return( Del_Records() );
249 }
250
251 //---------------------------------------------------------
_Destroy_Edges(void)252 bool CSG_TIN::_Destroy_Edges(void)
253 {
254 if( m_nEdges > 0 )
255 {
256 for(int i=0; i<m_nEdges; i++)
257 {
258 delete(m_Edges[i]);
259 }
260
261 SG_Free(m_Edges);
262 m_Edges = NULL;
263 m_nEdges = 0;
264 }
265
266 return( true );
267 }
268
269 //---------------------------------------------------------
_Destroy_Triangles(void)270 bool CSG_TIN::_Destroy_Triangles(void)
271 {
272 if( m_nTriangles > 0 )
273 {
274 for(int i=0; i<m_nTriangles; i++)
275 {
276 delete(m_Triangles[i]);
277 }
278
279 SG_Free(m_Triangles);
280 m_Triangles = NULL;
281 m_nTriangles = 0;
282 }
283
284 return( true );
285 }
286
287
288 ///////////////////////////////////////////////////////////
289 // //
290 ///////////////////////////////////////////////////////////
291
292 //---------------------------------------------------------
Assign(CSG_Data_Object * pObject)293 bool CSG_TIN::Assign(CSG_Data_Object *pObject)
294 {
295 if( pObject && pObject->is_Valid() && pObject->Get_ObjectType() == Get_ObjectType() )
296 {
297 CSG_TIN *pTIN = (CSG_TIN *)pObject;
298
299 Destroy();
300
301 CSG_Table::Create(pTIN);
302
303 Set_Name(pTIN->Get_Name());
304
305 Get_History() = pTIN->Get_History();
306
307 //-------------------------------------------------
308 for(int iNode=0; iNode<pTIN->Get_Node_Count(); iNode++)
309 {
310 CSG_TIN_Node *pNode = pTIN->Get_Node(iNode);
311
312 Add_Node(pNode->Get_Point(), pNode, false);
313 }
314
315 //-------------------------------------------------
316 for(int iTriangle=0; iTriangle<pTIN->Get_Triangle_Count(); iTriangle++)
317 {
318 CSG_TIN_Triangle *pTriangle = pTIN->Get_Triangle(iTriangle);
319
320 _Add_Triangle(
321 Get_Node(pTriangle->Get_Node(0)->Get_Index()),
322 Get_Node(pTriangle->Get_Node(1)->Get_Index()),
323 Get_Node(pTriangle->Get_Node(2)->Get_Index())
324 );
325 }
326
327 return( true );
328 }
329
330 return( false );
331 }
332
333
334 ///////////////////////////////////////////////////////////
335 // //
336 ///////////////////////////////////////////////////////////
337
338 //---------------------------------------------------------
Save(const CSG_String & File,int Format)339 bool CSG_TIN::Save(const CSG_String &File, int Format)
340 {
341 bool bResult = false;
342
343 if( Get_Triangle_Count() > 0 )
344 {
345 switch( Format )
346 {
347 case 0: default:
348 {
349 CSG_Shapes Points;
350
351 Points.Create(SHAPE_TYPE_Point, Get_Name(), this);
352
353 for(int i=0; i<Get_Node_Count(); i++)
354 {
355 CSG_TIN_Node *pNode = Get_Node(i);
356
357 Points.Add_Shape(pNode)->Add_Point(pNode->Get_Point());
358 }
359
360 bResult = Points.Save(File);
361 }
362 break;
363 }
364 }
365
366 if( bResult )
367 {
368 Set_Modified(false);
369
370 Set_File_Name(File, true);
371 }
372
373 return( bResult );
374 }
375
376
377 ///////////////////////////////////////////////////////////
378 // //
379 ///////////////////////////////////////////////////////////
380
381 //---------------------------------------------------------
_Get_New_Record(int Index)382 CSG_Table_Record * CSG_TIN::_Get_New_Record(int Index)
383 {
384 return( new CSG_TIN_Node(this, Index) );
385 }
386
387 //---------------------------------------------------------
Add_Node(TSG_Point Point,CSG_Table_Record * pRecord,bool bUpdateNow)388 CSG_TIN_Node * CSG_TIN::Add_Node(TSG_Point Point, CSG_Table_Record *pRecord, bool bUpdateNow)
389 {
390 CSG_TIN_Node *pNode = (CSG_TIN_Node *)Add_Record(pRecord);
391
392 if( pNode )
393 {
394 pNode->m_Point = Point;
395
396 if( bUpdateNow )
397 {
398 Update();
399 }
400 }
401
402 return( pNode );
403 }
404
405 //---------------------------------------------------------
Del_Node(int iNode,bool bUpdateNow)406 bool CSG_TIN::Del_Node(int iNode, bool bUpdateNow)
407 {
408 if( Del_Record(iNode) )
409 {
410 if( bUpdateNow )
411 {
412 Update();
413 }
414
415 return( true );
416 }
417
418 return( false );
419 }
420
421
422 ///////////////////////////////////////////////////////////
423 // //
424 ///////////////////////////////////////////////////////////
425
426 //---------------------------------------------------------
_Add_Edge(CSG_TIN_Node * a,CSG_TIN_Node * b)427 inline bool CSG_TIN::_Add_Edge(CSG_TIN_Node *a, CSG_TIN_Node *b)
428 {
429 m_Edges = (CSG_TIN_Edge **)SG_Realloc(m_Edges, (m_nEdges + 1) * sizeof(CSG_TIN_Edge *));
430 m_Edges[m_nEdges++] = new CSG_TIN_Edge(a, b);
431
432 return( true );
433 }
434
435 //---------------------------------------------------------
_Add_Triangle(CSG_TIN_Node * a,CSG_TIN_Node * b,CSG_TIN_Node * c)436 bool CSG_TIN::_Add_Triangle(CSG_TIN_Node *a, CSG_TIN_Node *b, CSG_TIN_Node *c)
437 {
438 CSG_TIN_Triangle *pTriangle;
439
440 m_Triangles = (CSG_TIN_Triangle **)SG_Realloc(m_Triangles, (m_nTriangles + 1) * sizeof(CSG_TIN_Triangle *));
441 m_Triangles[m_nTriangles++] = pTriangle = new CSG_TIN_Triangle(a, b, c);
442
443 if( a->_Add_Neighbor(b) )
444 {
445 b->_Add_Neighbor(a);
446 _Add_Edge(a, b);
447 }
448
449 if( b->_Add_Neighbor(c) )
450 {
451 c->_Add_Neighbor(b);
452 _Add_Edge(b, c);
453 }
454
455 if( c->_Add_Neighbor(a) )
456 {
457 a->_Add_Neighbor(c);
458 _Add_Edge(c, a);
459 }
460
461 a->_Add_Triangle(pTriangle);
462 b->_Add_Triangle(pTriangle);
463 c->_Add_Triangle(pTriangle);
464
465 return( true );
466 }
467
468
469 ///////////////////////////////////////////////////////////
470 // //
471 ///////////////////////////////////////////////////////////
472
473 //---------------------------------------------------------
On_Update(void)474 bool CSG_TIN::On_Update(void)
475 {
476 return( _Triangulate() );
477 }
478
479
480 ///////////////////////////////////////////////////////////
481 // //
482 ///////////////////////////////////////////////////////////
483
484 //---------------------------------------------------------
On_Reload(void)485 bool CSG_TIN::On_Reload(void)
486 {
487 return( Create(Get_File_Name(false)) );
488 }
489
490 //---------------------------------------------------------
On_Delete(void)491 bool CSG_TIN::On_Delete(void)
492 {
493 return( false );
494 }
495
496
497 ///////////////////////////////////////////////////////////
498 // //
499 // //
500 // //
501 ///////////////////////////////////////////////////////////
502
503 //---------------------------------------------------------
504