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