GeoTessCPP  2.0.0
Software to facilitate storage and retrieval of 3D information about the Earth.
 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"
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 
103 {
104 protected:
105 
106  // All methods below this point are public but are not documented in the doxygen documentation.
107  // These are methods that typical applications will never need to call. They have to be
108  // public because other classes in the GeoTess namespace need to access them.
109  //
111 
118  double** vertices;
119 
123  int nVertices;
124 
130  int** triangles;
131 
135  int nTriangles;
136 
148  int** levels;
149 
153  int nLevels;
154 
168  int** tessellations;
169 
173  int nTessellations;
174 
185  int** neighbors;
186 
202  double*** edges;
203 
208  mutable double** circumCenters;
209 
218  string gridID;
219 
223  string gridInputFile;
224 
228  string gridOutputFile;
229 
233  string gridSoftwareVersion;
234 
239  string gridGenerationDate;
240 
244  int refCount;
245 
250  mutable vector< vector< vector<int> > > vtxTriangles;
251 
257  mutable vector< set<int> > connectedVertices;
258 
269  const GeoTessOptimizationType* optimization;
270 
274  GeoTessGrid* loadGridAscii(const string& inputFile);
275 
280  GeoTessGrid* loadGridAscii(IFStreamAscii& input);
281 
285  GeoTessGrid* loadGridBinary(const string& inputFile);
286 
299  void findEdges();
300 
304  virtual GeoTessGrid* loadGridBinary(IFStreamBinary& ifs);
305 
319  int** findNeighbors();
320 
324  GeoTessGrid(const string& gid, const GeoTessOptimizationType* opttype) :
325  vertices(NULL), triangles(NULL), levels(NULL), tessellations(NULL),
326  neighbors(NULL), edges(NULL), circumCenters(NULL), gridID(gid),
327  gridInputFile("null"), gridOutputFile("null"), gridSoftwareVersion(""),
328  gridGenerationDate(""), refCount(0), optimization(opttype)
329  {
330  }
331 
332  static void loadGridAsciiFront(IFStreamAscii& input, int& gridFileFormat,
333  string& gridSWVersion, string& fileCreationDate,
334  string& gridid, const string& grdInptFile);
335 
336  static void loadGridBinaryFront(IFStreamBinary& ifs, int& gridFileFormat,
337  string& gridSWVersion, string& fileCreationDate,
338  string& gridid, const string& grdInptFile);
339 
354  const set<int>& getVertexIndices(const int& level);
355 
363  void clearVertexTriangles(const int& level);
364 
366 
367 public:
368 
375  vertices(NULL), triangles(NULL), levels(NULL), tessellations(NULL),
376  neighbors(NULL), edges(NULL), circumCenters(NULL), gridID(""),
377  gridInputFile("null"), gridOutputFile("null"), gridSoftwareVersion(""),
378  gridGenerationDate(""), refCount(0), optimization(&GeoTessOptimizationType::SPEED)
379  {
380  }
381 
387  vertices(NULL), triangles(NULL), levels(NULL), tessellations(NULL),
388  neighbors(NULL), edges(NULL), circumCenters(NULL), gridID(""),
389  gridInputFile("null"), gridOutputFile("null"), gridSoftwareVersion(""),
390  gridGenerationDate(""), refCount(0), optimization(opttype)
391  {
392  }
393 
398  GeoTessGrid(GeoTessGrid &other);
399 
405  GeoTessGrid& operator= (const GeoTessGrid& other);
406 
412  GeoTessGrid* loadGrid(const string& inputFile);
413 
420  static string getGridID(const string& fileName);
421 
428  static bool isGeoTessGrid(const string& inputFile);
429 
435  bool operator == (const GeoTessGrid& g) const
436  { return (gridID == g.gridID); }
437 
443  bool operator != (const GeoTessGrid& g) const
444  { return !(*this == g); }
445 
456  const string& getGridID() const
457  {
458  return gridID;
459  }
460 
465  const GeoTessOptimizationType* getOptimizationType() const { return optimization; }
466 
473  void setGridSoftwareVersion(const string& swVersion) {gridSoftwareVersion = swVersion; };
474 
481  const string& getGridSoftwareVersion() const {return gridSoftwareVersion; };
482 
489  void setGridGenerationDate(const string& gridDate) {gridGenerationDate = gridDate; };
490 
497  const string& getGridGenerationDate() const {return gridGenerationDate; };
498 
503  void setGridInputFile(const string& gridFile) { gridInputFile = gridFile; }
504 
512  const string& getGridInputFile() const {return gridInputFile; }
513 
521  const string& getGridOutputFile() const { return gridOutputFile; }
522 
528  const double* getVertex(int vertex) const
529  {
530  return vertices[vertex];
531  }
532 
541  int findClosestVertex(double* unit_vector, int tessId)
542  {
543  int* t = triangles[getTriangle(getFirstTriangle(tessId, 0), unit_vector)];
544 
545  int index = 0;
546  double dot = GeoTessUtils::dot(unit_vector, vertices[t[0]]);
547 
548  double doti = GeoTessUtils::dot(unit_vector, vertices[t[1]]);
549  if (doti > dot)
550  {
551  index = 1;
552  dot = doti;
553  }
554 
555  doti = GeoTessUtils::dot(unit_vector, vertices[t[2]]);
556  if (doti > dot)
557  {
558  index = 2;
559  dot = doti;
560  }
561 
562  return t[index];
563  }
564 
580  int getVertexIndex(int tessId, int level, int triangle, int corner) const
581  {
582  return triangles[levels[tessellations[tessId][0] + level][0] + triangle][corner];
583  }
584 
596  double* getVertex(int tessId, int level, int triangle, int corner)
597  {
598  return vertices[triangles[levels[tessellations[tessId][0] + level][0] + triangle][corner]];
599  }
600 
610  double const* const* getVertices() const { return vertices; }
611 
620  void getVerticesTopLevel(const int& tessellation, set<const double*>& vectors)
621  {
622  getVertices(tessellation, getNLevels(tessellation)-1, vectors);
623  }
624 
634  void getVertices(const int& tessellation, const int& level, set<const double*>& vectors);
635 
648  const set<int>& getVertexIndices(const int& tessId, const int& level)
649  { return getVertexIndices(getLevel(tessId, level)); }
650 
662  const set<int>& getVertexIndicesTopLevel(const int& tessId)
663  { return getVertexIndices(tessellations[tessId][1] - 1); }
664 
673  void clearVertexIndices() { connectedVertices.clear(); }
674 
679  int getNVertices() const { return nVertices; }
680 
685  int getNTessellations() const { return nTessellations; }
686 
694  int getNLevels(int tessellation) const
695  { return tessellations[tessellation][1] - tessellations[tessellation][0]; }
696 
706  int getLevel(int tessellation, int i) const
707  { return tessellations[tessellation][0] + i; }
708 
715  int getLastLevel(int tessellation) const
716  { return tessellations[tessellation][1] - 1; }
717 
727  int getNTriangles(int tessellation, int level) const
728  {
729  return levels[tessellations[tessellation][0] + level][1]
730  - levels[tessellations[tessellation][0] + level][0];
731  }
732 
744  int getTriangle(int tessellation, int level, int i) const
745  { return levels[tessellations[tessellation][0] + level][0] + i; }
746 
756  int getFirstTriangle(int tessellation, int level) const
757  { return levels[tessellations[tessellation][0] + level][0]; }
758 
768  int getLastTriangle(int tessellation, int level) const
769  { return levels[tessellations[tessellation][0] + level][1]-1; }
770 
780  int const* const* getTriangles() const { return triangles; }
781 
793  const int* getTriangleVertexIndexes(int triangleIndex) const
794  { return triangles[triangleIndex]; }
795 
807  int getTriangleVertexIndex(int triangleIndex, int cornerIndex) const
808  { return triangles[triangleIndex][cornerIndex]; }
809 
821  const double* getTriangleVertex(int triangleIndex, int cornerIndex) const
822  { return vertices[triangles[triangleIndex][cornerIndex]]; }
823 
824 
833  void getTriangleVertices(int triangle, double** triVrt)
834  {
835  int* corners = triangles[triangle];
836  triVrt[0][0] = vertices[corners[0]][0];
837  triVrt[0][1] = vertices[corners[0]][1];
838  triVrt[0][2] = vertices[corners[0]][2];
839  triVrt[1][0] = vertices[corners[1]][0];
840  triVrt[1][1] = vertices[corners[1]][1];
841  triVrt[1][2] = vertices[corners[1]][2];
842  triVrt[2][0] = vertices[corners[2]][0];
843  triVrt[2][1] = vertices[corners[2]][1];
844  triVrt[2][2] = vertices[corners[2]][2];
845  }
846 
861  const double* getCircumCenter(int triangle, double* const pA) const
862  {
863  // if SPEED optimization is off calculate circumcenter and store into pA
864 
865  if (edges == NULL)
866  {
867  // edges == null means that optimization level is MEMORY, not SPEED
868  int* corners = triangles[triangle];
869  GeoTessUtils::circumCenter(vertices[corners[0]], vertices[corners[1]],
870  vertices[corners[2]], pA);
871  return pA;
872  }
873 
874  // SPEED optimization is on ... ensure circumcenter array is created and
875  // initialized
876 
877  if (circumCenters == NULL)
878  {
879  circumCenters = CPPUtils::new2DArray<double>(nTriangles, 3);
880  CPPUtils::resetArray<double>(nTriangles*3, circumCenters[0], -2.0);
881  }
882 
883  // define circumcenter if it has not been evaluated and return result
884 
885  if (circumCenters[triangle][0] == -2.0)
886  {
887  int* corners = triangles[triangle];
888  GeoTessUtils::circumCenter(vertices[corners[0]], vertices[corners[1]],
889  vertices[corners[2]], circumCenters[triangle]);
890  }
891  return circumCenters[triangle];
892  }
893 
908  int getNeighbor(int triangleIndex, int neighborIndex) const
909  { return neighbors[triangleIndex][neighborIndex]; }
910 
924  const int* getNeighbors(int triangleIndex) const
925  { return neighbors[triangleIndex]; }
926 
949  const int* getNeighbors(const int& tessellation, const int& level, const int& triangle)
950  { return neighbors[getTriangle(tessellation, level, triangle)]; }
951 
976  int getNeighbor(const int& tessellation, const int& level, const int& triangle, const int& side)
977  { return neighbors[getTriangle(tessellation, level, triangle)][side]; }
978 
983  int const* const* getNeighbors() const { return neighbors; }
984 
998  int getNeighborIndex(const int& tid, const int& nid)
999  {
1000  if (neighbors[tid][0] == nid)
1001  return 0;
1002  if (neighbors[tid][1] == nid)
1003  return 1;
1004  if (neighbors[tid][2] == nid)
1005  return 2;
1006  return -1;
1007  }
1008 
1012  string toString();
1013 
1021  int getTriangle(int triangleIndex, double* vector);
1022 
1035  const vector<int>& getVertexTriangles(const int& tessId, const int& level, const int& vertex) const;
1036 
1050  const vector<int>& getVertexTriangles(int tessId, int vertex) const
1051  { return getVertexTriangles(tessId, getNLevels(tessId)-1, vertex); }
1052 
1059  void clearVertexTriangles();
1060 
1070  void getVertexNeighborsOrdered(const int& tessId, const int& level, const int& vertex, vector<int>& v);
1071 
1083  void getVertexNeighbors(const int& tessId, const int& level, const int& vertex, set<int>& nbrs)
1084  { getVertexNeighbors(tessId, level, vertex, 1, nbrs); }
1085 
1103  void getVertexNeighbors(const int& tessId, const int& level, const int& vertex,
1104  const int& order, set<int>& nbrs);
1105 
1106  // All methods below this point are public but are not documented in the doxygen documentation.
1107  // These are methods that typical applications will never need to call. They have to be
1108  // public because other classes in the GeoTess namespace need to access them.
1109  //
1111 
1115  GeoTessGrid(IFStreamAscii& input, const GeoTessOptimizationType* opttype) :
1116  vertices(NULL), triangles(NULL), levels(NULL), tessellations(NULL),
1117  neighbors(NULL), edges(NULL), circumCenters(NULL), gridID(""),
1118  gridInputFile("null"), gridOutputFile("null"), gridSoftwareVersion(""),
1119  gridGenerationDate(""), refCount(0), optimization(opttype)
1120  { loadGridAscii(input); }
1121 
1125  GeoTessGrid(IFStreamBinary& input, const GeoTessOptimizationType* opttype) :
1126  vertices(NULL), triangles(NULL), levels(NULL), tessellations(NULL),
1127  neighbors(NULL), edges(NULL), circumCenters(NULL), gridID(""),
1128  gridInputFile("null"), gridOutputFile("null"), gridSoftwareVersion(""),
1129  gridGenerationDate(""), refCount(0), optimization(opttype)
1130  { loadGridBinary(input); }
1131 
1135  GeoTessGrid(double** _vertices, int& _nVertices,
1136  int** _triangles, int& _nTriangles,
1137  int** _levels, int& _nLevels,
1138  int** _tessellations, int& _nTessellations,
1139  string& _gridID,
1140  string& _gridInputFile,
1141  string& _gridOutputFile,
1142  string& _gridSoftwareVersion,
1143  string& _gridGenerationDate,
1144  const GeoTessOptimizationType* _opttype) :
1145  vertices(_vertices), nVertices(_nVertices),
1146  triangles(_triangles), nTriangles(_nTriangles),
1147  levels(_levels), nLevels(_nLevels),
1148  tessellations(_tessellations), nTessellations(_nTessellations),
1149  neighbors(NULL),
1150  edges(NULL),
1151  circumCenters(NULL),
1152  gridID(_gridID),
1153  gridInputFile(_gridInputFile),
1154  gridOutputFile(_gridOutputFile),
1155  gridSoftwareVersion(_gridSoftwareVersion),
1156  gridGenerationDate(_gridGenerationDate),
1157  refCount(0),
1158  optimization(_opttype)
1159  { findNeighbors(); }
1160 
1164  virtual ~GeoTessGrid();
1165 
1169  int getReferenceCount() { return refCount; }
1170 
1174  void addReference() { ++refCount; }
1175 
1179  void removeReference()
1180  {
1181  if (isNotReferenced())
1182  {
1183  ostringstream os;
1184  os << endl << "ERROR in GeoTessGrid::removeReference" << endl
1185  << "Reference count (" << refCount << ") is already zero." << endl;
1186  throw GeoTessException(os, __FILE__, __LINE__, 2001);
1187  }
1188 
1189  --refCount;
1190  }
1191 
1195  bool isNotReferenced() { return (refCount == 0); }
1196 
1202  void writeGrid(const string& fileName);
1203 
1207  void writeGridAscii(const string& fileName);
1208 
1212  void writeGridAscii(IFStreamAscii& output);
1213 
1217  void writeGridBinary(const string& fileName);
1218 
1222  void writeGridBinary(IFStreamBinary& output);
1223 
1241  double const* const* const* getEdges() const { return edges; }
1242 
1263  void getEdgeList(const int& tessId, const int& level, const int& vertex, ArrayReuse<int>& store,
1264  list<int*>& e)
1265  { return getEdgeList(tessId, level, vertex, -1, store, e); }
1266 
1270  void getEdgeList(const int& tessId, const int& level, const int& vertex, const int& firstNeighborVertex,
1271  ArrayReuse<int>& store, list<int*>& e) const;
1272 
1278  bool isSupportedFormatVersion(int frmtVrsn)
1279  { return (frmtVrsn == 2); }
1280 
1282 
1291  void testGrid();
1292 
1298  int getNLevels() const { return nLevels; }
1299 
1311  int const* const* getLevels() const { return levels; }
1312 
1327  int const* const* getTessellations() const { return tessellations; }
1328 
1336  int getNTriangles() const { return nTriangles; }
1337 
1338 
1339 };
1340 // end class GeoTessGrid
1341 
1342 }// end namespace geotess
1343 
1344 #endif // GEOTESSGRID_OBJECT_H