GeoTessCPP: include/GeoTessGrid.h Source File

GeoTessCPP 2.1 Software to facilitate storage and retrieval of 3D information about the Earth.

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Friends Macros
GeoTessGrid.h
Go to the documentation of this file.
1 //- ****************************************************************************
2 //-
3 //- Copyright 2009 Sandia Corporation. Under the terms of Contract
4 //- DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
5 //- retains certain rights in this software.
6 //-
7 //- BSD Open Source License.
8 //- All rights reserved.
9 //-
10 //- Redistribution and use in source and binary forms, with or without
11 //- modification, are permitted provided that the following conditions are met:
12 //-
13 //- * Redistributions of source code must retain the above copyright notice,
14 //- this list of conditions and the following disclaimer.
15 //- * Redistributions in binary form must reproduce the above copyright
16 //- notice, this list of conditions and the following disclaimer in the
17 //- documentation and/or other materials provided with the distribution.
18 //- * Neither the name of Sandia National Laboratories nor the names of its
19 //- contributors may be used to endorse or promote products derived from
20 //- this software without specific prior written permission.
21 //-
22 //- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 //- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 //- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 //- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
26 //- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 //- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 //- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 //- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 //- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 //- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 //- POSSIBILITY OF SUCH DAMAGE.
33 //-
34 //- ****************************************************************************
35
36 #ifndef GEOTESSGRID_OBJECT_H
37 #define GEOTESSGRID_OBJECT_H
38
39 // **** _SYSTEM INCLUDES_ ******************************************************
40
41 #include <iostream>
42 #include <string>
43 #include <fstream>
44 #include <vector>
45 #include <set>
46 #include <list>
47 #include <set>
48 #include <sstream>
49
50 // use standard library objects
51 using namespace std;
52
53 // **** _LOCAL INCLUDES_ *******************************************************
54
55 #include "CPPUtils.h"
56 #include "GeoTessUtils.h"
57 #include "ArrayReuse.h"
58 #include "GeoTessException.h"
59 #include "GeoTessOptimizationType.h"
60
61 // **** _BEGIN GEOTESS NAMESPACE_ **********************************************
62
63 namespace geotess
64 {
65
66 // **** _FORWARD REFERENCES_ ***************************************************
67
68 class IFStreamAscii;
69 class IFStreamBinary;
70
71 // **** _CLASS DEFINITION_ *****************************************************
72
98 struct Edge
99 {
103 int vj;
104
108 int vk;
109
110 int cornerj;
111
115 int tLeft;
116
120 int tRight;
121
125 double normal[3]; //
126
131 Edge* next; //
132 };
133
163 class GEOTESS_EXP_IMP GeoTessGrid
164 {
165 protected:
166
174 double** vertices;
175
179 int nVertices;
180
186 int** triangles;
187
191 int nTriangles;
192
204 int** levels;
205
209 int nLevels;
210
224 int** tessellations;
225
229 int nTessellations;
230
236 void initialize();
237
241 GeoTessGrid(const string& gid) :
242 vertices(NULL), nVertices(0),
243 triangles(NULL), nTriangles(0),
244 levels(NULL), nLevels(0),
245 tessellations(NULL), nTessellations(0),
246 descendants(NULL), gridID(gid),
247 gridInputFile("null"), gridOutputFile("null"), gridSoftwareVersion(""),
248 gridGenerationDate(""), refCount(0)
249 {
250 }
251
252 private:
253
261 int* descendants;
262
280 vector<vector<Edge*> > edgeList;
281
294 mutable vector<vector<Edge*> > spokeList;
295
302 mutable vector<double*> circumCenters;
303
312 string gridID;
313
317 string gridInputFile;
318
322 string gridOutputFile;
323
327 string gridSoftwareVersion;
328
333 string gridGenerationDate;
334
338 int refCount;
339
344 vector< vector< vector<int> > > vtxTriangles;
345
351 mutable vector< set<int> > connectedVertices;
352
356 GeoTessGrid* loadGridAscii(const string& inputFile);
357
362 GeoTessGrid* loadGridAscii(IFStreamAscii& input);
363
367 GeoTessGrid* loadGridBinary(const string& inputFile);
368
372 virtual GeoTessGrid* loadGridBinary(IFStreamBinary& ifs);
373
374 static void loadGridAsciiFront(IFStreamAscii& input, int& gridFileFormat,
375 string& gridSWVersion, string& fileCreationDate,
376 string& gridid, const string& grdInptFile);
377
378 static void loadGridBinaryFront(IFStreamBinary& ifs, int& gridFileFormat,
379 string& gridSWVersion, string& fileCreationDate,
380 string& gridid, const string& grdInptFile);
381
396 const set<int>& getVertexIndices(const int& level);
397
398 void computeSpokeLists(const int& level) const;
399
400 public:
401
407 GeoTessGrid() :
408 vertices(NULL), nVertices(0),
409 triangles(NULL), nTriangles(0),
410 levels(NULL), nLevels(0),
411 tessellations(NULL), nTessellations(0),
412 descendants(NULL), gridID(""),
413 gridInputFile("null"), gridOutputFile("null"), gridSoftwareVersion(""),
414 gridGenerationDate(""), refCount(0)
415 { }
416
420 GeoTessGrid(IFStreamAscii& input) :
421 vertices(NULL), triangles(NULL), levels(NULL), tessellations(NULL),
422 descendants(NULL), gridID(""),
423 gridInputFile("null"), gridOutputFile("null"), gridSoftwareVersion(""),
424 gridGenerationDate(""), refCount(0)
425 { loadGridAscii(input); }
426
430 GeoTessGrid(IFStreamBinary& input) :
431 vertices(NULL), triangles(NULL), levels(NULL), tessellations(NULL),
432 descendants(NULL), gridID(""),
433 gridInputFile("null"), gridOutputFile("null"), gridSoftwareVersion(""),
434 gridGenerationDate(""), refCount(0)
435 { loadGridBinary(input); }
436
441 GeoTessGrid(GeoTessGrid &other);
442
448 GeoTessGrid& operator= (const GeoTessGrid& other);
449
454 LONG_INT getMemory()
455 {
456 LONG_INT memory = (LONG_INT)sizeof(GeoTessGrid);
457
458 // double** vertices
459 memory += nVertices * (LONG_INT)sizeof(double*) + nVertices * 3 * (LONG_INT)sizeof(double);
460
461 // int** triangles
462 memory += nTriangles * (LONG_INT)sizeof(int*) + nTriangles * 3 * (LONG_INT)sizeof(int);
463
464 // int** levels
465 memory += nLevels * (LONG_INT)sizeof(int*) + nLevels * 2 * (LONG_INT)sizeof(int);
466
467 // int** tessellations
468 memory += nTessellations * (LONG_INT)sizeof(int*) + nTessellations * 2 * (LONG_INT)sizeof(int);
469
470 // int* descendants
471 memory += nTriangles * (LONG_INT)sizeof(int);
472
473 // vector<vector<Edge*> > edgeList : nTriangles x 3 array of Edges
474 memory += (LONG_INT) (edgeList.capacity() * sizeof(vector<Edge*>)
475 + edgeList.size() * 3 * (sizeof(Edge*) + sizeof(Edge)));
476
477 // vector<vector<Edge*> > spokeList;
478 memory += (LONG_INT) (spokeList.capacity() * sizeof(vector<Edge*>)
479 + spokeList.size() * 3 * sizeof(Edge*));
480
481 // vector<double*> circumCenters is nTriangles x 3 array of doubles
482 memory += (LONG_INT) (circumCenters.capacity() * sizeof(double*));
483 for (int i=0; i<(int)circumCenters.size(); ++i)
484 if (circumCenters[i]) memory += 3 * (LONG_INT)sizeof(double);
485
486 // An nLevels x nVertices x n array that stores the indices of the n
487 // triangles of which each vertex is a member.
488 // vector< vector< vector<int> > > vtxTriangles;
489 memory += (LONG_INT) (vtxTriangles.capacity() * sizeof(vector< vector<int> >));
490 for (int i=0; i<(int)vtxTriangles.size(); ++i)
491 {
492 memory += (LONG_INT) (vtxTriangles[i].capacity() * sizeof(vector<int>));
493 for (int j=0; j<(int)vtxTriangles[i].size(); ++j)
494 memory += (LONG_INT) (vtxTriangles[i][j].capacity() * sizeof(int));
495 }
496
497 // An nLevels x n array that stores the indexes of the n vertices
498 // that are connected together by triangles on the corresponding
499 // level. Lazy evaluation is used to construct this array of sets.
500 // vector< set<int> > connectedVertices;
501 memory += (LONG_INT) (connectedVertices.capacity() * sizeof(set<int>));
502 for (int i=0; i<(int)connectedVertices.size(); ++i)
503 memory += (LONG_INT) (connectedVertices[i].size() * sizeof(int));
504
505 // add memory requirements for all the string variables.
506 memory += (LONG_INT) (gridID.length() + gridInputFile.length() + gridOutputFile.length()
507 + gridSoftwareVersion.length() + gridGenerationDate.length());
508
509 return memory;
510 }
511
517 GeoTessGrid* loadGrid(const string& inputFile);
518
525 static string getGridID(const string& fileName);
526
533 static bool isGeoTessGrid(const string& inputFile);
534
540 bool operator == (const GeoTessGrid& g) const
541 { return (gridID == g.gridID); }
542
548 bool operator != (const GeoTessGrid& g) const
549 { return !(*this == g); }
550
561 const string& getGridID() const
562 {
563 return gridID;
564 }
565
572 void setGridSoftwareVersion(const string& swVersion) {gridSoftwareVersion = swVersion; };
573
580 const string& getGridSoftwareVersion() const {return gridSoftwareVersion; };
581
588 void setGridGenerationDate(const string& gridDate) {gridGenerationDate = gridDate; };
589
596 const string& getGridGenerationDate() const {return gridGenerationDate; };
597
602 void setGridInputFile(const string& gridFile) { gridInputFile = gridFile; }
603
611 const string& getGridInputFile() const {return gridInputFile; }
612
620 const string& getGridOutputFile() const { return gridOutputFile; }
621
627 const double* getVertex(int vertex) const
628 {
629 return vertices[vertex];
630 }
631
640 int findClosestVertex(double* unit_vector, int tessId)
641 {
642 int* t = triangles[getTriangle(getFirstTriangle(tessId, 0), unit_vector)];
643
644 int index = 0;
645 double dot = GeoTessUtils::dot(unit_vector, vertices[t[0]]);
646
647 double doti = GeoTessUtils::dot(unit_vector, vertices[t[1]]);
648 if (doti > dot)
649 {
650 index = 1;
651 dot = doti;
652 }
653
654 doti = GeoTessUtils::dot(unit_vector, vertices[t[2]]);
655 if (doti > dot)
656 {
657 index = 2;
658 dot = doti;
659 }
660
661 return t[index];
662 }
663
672 int getVertexIndex(int triangle, int corner) const
673 { return triangles[triangle][corner]; }
674
690 int getVertexIndex(int tessId, int level, int triangle, int corner) const
691 {
692 return triangles[levels[tessellations[tessId][0] + level][0] + triangle][corner];
693 }
694
701 int getVertexIndex(const double* u)
702 {
703 for (int i=nTessellations-1; i>=0; --i)
704 {
705 int vid = getVertexIndex(u, i);
706 if (vid >= 0)
707 return vid;
708 }
709 return -1;
710 }
711
720 int getVertexIndex(const double* u, int tessId)
721 {
722 int* t = triangles[getTriangle(getFirstTriangle(tessId, 0), u)];
723
724 if (GeoTessUtils::dot(u, vertices[t[0]]) > cos(1e-7))
725 return t[0];
726 if (GeoTessUtils::dot(u, vertices[t[1]]) > cos(1e-7))
727 return t[1];
728 if (GeoTessUtils::dot(u, vertices[t[2]]) > cos(1e-7))
729 return t[2];
730 return -1;
731 }
732
744 double* getVertex(int tessId, int level, int triangle, int corner)
745 {
746 return vertices[triangles[levels[tessellations[tessId][0] + level][0] + triangle][corner]];
747 }
748
758 double const* const* getVertices() const { return vertices; }
759
768 void getVerticesTopLevel(const int& tessellation, set<const double*>& vectors)
769 {
770 getVertices(tessellation, getNLevels(tessellation)-1, vectors);
771 }
772
782 void getVertices(const int& tessellation, const int& level, set<const double*>& vectors);
783
796 const set<int>& getVertexIndices(const int& tessId, const int& level)
797 { return getVertexIndices(getLevel(tessId, level)); }
798
810 const set<int>& getVertexIndicesTopLevel(const int& tessId)
811 { return getVertexIndices(tessellations[tessId][1] - 1); }
812
817 int getNVertices() const { return nVertices; }
818
823 int getNTessellations() const { return nTessellations; }
824
832 int getNLevels(int tessellation) const
833 { return tessellations[tessellation][1] - tessellations[tessellation][0]; }
834
843 int getLevel(int tessellation, int i) const
844 { return tessellations[tessellation][0] + i; }
845
861 int getLastLevel(int tessellation) const
862 { return tessellations[tessellation][1] - 1; }
863
878 int getTopLevel(int tessellation) const
879 { return tessellations[tessellation][1] - tessellations[tessellation][0] - 1; }
880
890 int getNTriangles(int tessellation, int level) const
891 {
892 return levels[tessellations[tessellation][0] + level][1]
893 - levels[tessellations[tessellation][0] + level][0];
894 }
895
907 int getTriangle(int tessellation, int level, int i) const
908 { return levels[tessellations[tessellation][0] + level][0] + i; }
909
919 int getFirstTriangle(int tessellation, int level) const
920 { return levels[tessellations[tessellation][0] + level][0]; }
921
931 int getLastTriangle(int tessellation, int level) const
932 { return levels[tessellations[tessellation][0] + level][1]-1; }
933
943 int const* const* getTriangles() const { return triangles; }
944
956 const int* getTriangleVertexIndexes(int triangleIndex) const
957 { return triangles[triangleIndex]; }
958
970 int getTriangleVertexIndex(int triangleIndex, int cornerIndex) const
971 { return triangles[triangleIndex][cornerIndex]; }
972
984 const double* getTriangleVertex(int triangleIndex, int cornerIndex) const
985 { return vertices[triangles[triangleIndex][cornerIndex]]; }
986
987
996 void getTriangleVertices(int triangle, double** triVrt)
997 {
998 int* corners = triangles[triangle];
999 triVrt[0][0] = vertices[corners[0]][0];
1000 triVrt[0][1] = vertices[corners[0]][1];
1001 triVrt[0][2] = vertices[corners[0]][2];
1002 triVrt[1][0] = vertices[corners[1]][0];
1003 triVrt[1][1] = vertices[corners[1]][1];
1004 triVrt[1][2] = vertices[corners[1]][2];
1005 triVrt[2][0] = vertices[corners[2]][0];
1006 triVrt[2][1] = vertices[corners[2]][1];
1007 triVrt[2][2] = vertices[corners[2]][2];
1008 }
1009
1014 const void computeCircumCenters()
1015 {
1016 if (circumCenters.empty()) circumCenters.resize(nTriangles, NULL);
1017
1018 for (int triangle=0; triangle<nTriangles; ++triangle)
1019 if (circumCenters[triangle] == NULL)
1020 {
1021 int* corners = triangles[triangle];
1022 circumCenters[triangle] = GeoTessUtils::circumCenterPlus(vertices[corners[0]],
1023 vertices[corners[1]], vertices[corners[2]]);
1024 }
1025 }
1026
1031 const void computeCircumCenters(const int& level)
1032 {
1033 if (circumCenters.empty()) circumCenters.resize(nTriangles);
1034
1035 if (circumCenters[levels[level][0]] == NULL)
1036 {
1037 for (int triangle=levels[level][0]; triangle<levels[level][1]; ++triangle)
1038 {
1039 int* corners = triangles[triangle];
1040 circumCenters[triangle] = GeoTessUtils::circumCenterPlus(vertices[corners[0]],
1041 vertices[corners[1]], vertices[corners[2]]);
1042 }
1043 }
1044 }
1045
1061 const double* getCircumCenter(const int& triangle) const { return circumCenters[triangle]; }
1062
1080 void getCircumCenter(const int& triangle, double* cc) const
1081 { cc[0]=circumCenters[triangle][0]; cc[1]=circumCenters[triangle][1]; cc[2]=circumCenters[triangle][2]; }
1082
1097 int getNeighbor(const int& triangleIndex, const int& neighborIndex) const
1098 { return neighborIndex == 3 ? descendants[triangleIndex] : edgeList[triangleIndex][neighborIndex]->tLeft; }
1099
1124 int getNeighbor(const int& tessellation, const int& level, const int& triangle, const int& side)
1125 { return getNeighbor(getTriangle(tessellation, level, triangle), side); }
1126
1141 void getNeighbors(int triangleIndex, vector<int>& neighbors)
1142 {
1143 neighbors.clear();
1144 vector<Edge*> edges = edgeList[triangleIndex];
1145 neighbors.push_back(edges[0]->tLeft);
1146 neighbors.push_back(edges[1]->tLeft);
1147 neighbors.push_back(edges[2]->tLeft);
1148 neighbors.push_back(descendants[triangleIndex]);
1149 }
1150
1173 void getNeighbors(const int& tessellation, const int& level, const int& triangle, vector<int>& neighbors)
1174 { getNeighbors(getTriangle(tessellation, level, triangle), neighbors); }
1175
1189 int getNeighborIndex(const int& tid, const int& nid)
1190 {
1191 if (edgeList[tid][0]->tLeft == nid)
1192 return 0;
1193 if (edgeList[tid][1]->tLeft == nid)
1194 return 1;
1195 if (edgeList[tid][2]->tLeft == nid)
1196 return 2;
1197 return -1;
1198 }
1199
1200 int const* getDescendants() const { return descendants; }
1201
1202 int getDescendant(const int& triangle) const { return descendants[triangle]; }
1203
1204 int getDescendant(const int& tessId, const int& level, const int& triangle) const
1205 { return descendants[getTriangle(tessId, level, triangle)]; }
1206
1210 string toString();
1211
1219 int getTriangle(int triangleIndex, const double* vector);
1220
1228 const vector<vector<int> >& getVertexTriangles(const int& level) const { return vtxTriangles[level]; }
1229
1242 const vector<int>& getVertexTriangles(const int& tessId, const int& level, const int& vertex) const
1243 { return vtxTriangles[tessellations[tessId][0] + level][vertex]; }
1244
1258 const vector<int>& getVertexTriangles(int tessId, int vertex) const
1259 { return getVertexTriangles(tessId, getNLevels(tessId)-1, vertex); }
1260
1267 //void clearVertexTriangles();
1268
1278 void getVertexNeighborsOrdered(const int& tessId, const int& level, const int& vertex, vector<int>& v);
1279
1291 void getVertexNeighbors(const int& tessId, const int& level, const int& vertex, set<int>& nbrs)
1292 { getVertexNeighbors(tessId, level, vertex, 1, nbrs); }
1293
1311 void getVertexNeighbors(const int& tessId, const int& level, const int& vertex,
1312 const int& order, set<int>& nbrs);
1313
1314 // All methods below this point are public but are not documented in the doxygen documentation.
1315 // These are methods that typical applications will never need to call. They have to be
1316 // public because other classes in the GeoTess namespace need to access them.
1317 //
1319
1325 GeoTessGrid(const GeoTessOptimizationType* opttype) :
1326 vertices(NULL), nVertices(0),
1327 triangles(NULL), nTriangles(0),
1328 levels(NULL), nLevels(0),
1329 tessellations(NULL), nTessellations(0),
1330 descendants(NULL), gridID(""),
1331 gridInputFile("null"), gridOutputFile("null"), gridSoftwareVersion(""),
1332 gridGenerationDate(""), refCount(0)
1333 { }
1334
1339 GeoTessGrid(IFStreamAscii& input, const GeoTessOptimizationType* opttype) :
1340 vertices(NULL), triangles(NULL), levels(NULL), tessellations(NULL),
1341 descendants(NULL), gridID(""),
1342 gridInputFile("null"), gridOutputFile("null"), gridSoftwareVersion(""),
1343 gridGenerationDate(""), refCount(0)
1344 { loadGridAscii(input); }
1345
1350 GeoTessGrid(IFStreamBinary& input, const GeoTessOptimizationType* opttype) :
1351 vertices(NULL), triangles(NULL), levels(NULL), tessellations(NULL),
1352 descendants(NULL), gridID(""),
1353 gridInputFile("null"), gridOutputFile("null"), gridSoftwareVersion(""),
1354 gridGenerationDate(""), refCount(0)
1355 { loadGridBinary(input); }
1356
1361 GeoTessGrid(double** _vertices, int& _nVertices,
1362 int** _triangles, int& _nTriangles,
1363 int** _levels, int& _nLevels,
1364 int** _tessellations, int& _nTessellations,
1365 string& _gridID,
1366 string& _gridInputFile,
1367 string& _gridOutputFile,
1368 string& _gridSoftwareVersion,
1369 string& _gridGenerationDate) :
1370 vertices(_vertices), nVertices(_nVertices),
1371 triangles(_triangles), nTriangles(_nTriangles),
1372 levels(_levels), nLevels(_nLevels),
1373 tessellations(_tessellations), nTessellations(_nTessellations),
1374 descendants(NULL),
1375 gridID(_gridID),
1376 gridInputFile(_gridInputFile),
1377 gridOutputFile(_gridOutputFile),
1378 gridSoftwareVersion(_gridSoftwareVersion),
1379 gridGenerationDate(_gridGenerationDate),
1380 refCount(0)
1381 { initialize(); }
1382
1386 virtual ~GeoTessGrid();
1387
1391 int getReferenceCount() { return refCount; }
1392
1396 void addReference() { ++refCount; }
1397
1401 void removeReference()
1402 {
1403 if (isNotReferenced())
1404 {
1405 ostringstream os;
1406 os << endl << "ERROR in GeoTessGrid::removeReference" << endl
1407 << "Reference count (" << refCount << ") is already zero." << endl;
1408 throw GeoTessException(os, __FILE__, __LINE__, 2001);
1409 }
1410
1411 --refCount;
1412 }
1413
1417 bool isNotReferenced() { return (refCount == 0); }
1418
1424 void writeGrid(const string& fileName);
1425
1429 void writeGridAscii(const string& fileName);
1430
1434 void writeGridAscii(IFStreamAscii& output);
1435
1439 void writeGridBinary(const string& fileName);
1440
1444 void writeGridBinary(IFStreamBinary& output);
1445
1451 bool isSupportedFormatVersion(int frmtVrsn)
1452 { return (frmtVrsn == 2); }
1453
1454 // deprecated. GeoTessOptimizationType is no longer used. Always optimized for speed.
1455 const GeoTessOptimizationType& getOptimizationType() const { return GeoTessOptimizationType::SPEED; }
1456
1458
1467 void testGrid();
1468
1474 int getNLevels() const { return nLevels; }
1475
1487 int const* const* getLevels() const { return levels; }
1488
1503 int const* const* getTessellations() const { return tessellations; }
1504
1512 int getNTriangles() const { return nTriangles; }
1513
1514 vector<Edge*>& getSpokeList(const int& level) const
1515 { computeSpokeLists(level); return spokeList[level]; }
1516
1517 const vector<vector<Edge*> >& getEdgeList() const { return edgeList; }
1518
1519 const vector<Edge*>& getEdgeList(const int& triangle) const { return edgeList[triangle]; }
1520
1527 void getCenter(const int& triangle, double* center)
1528 {
1529 vector<double*> corners;
1530 corners.push_back(vertices[triangles[triangle][0]]);
1531 corners.push_back(vertices[triangles[triangle][1]]);
1532 corners.push_back(vertices[triangles[triangle][2]]);
1533 GeoTessUtils::center(corners, center);
1534 }
1535
1541 int delaunay();
1542
1543 };
1544 // end class GeoTessGrid
1545
1546 }// end namespace geotess
1547
1548 #endif // GEOTESSGRID_OBJECT_H