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"
59 #include "OptimizationType.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 
113  double** vertices;
114 
119 
125  int** triangles;
126 
131 
143  int** levels;
144 
148  int nLevels;
149 
164 
169 
180  int** neighbors;
181 
197  double*** edges;
198 
203  mutable double** circumCenters;
204 
213  string gridID;
214 
219 
224 
229 
235 
239  int refCount;
240 
245  mutable vector< vector< vector<int> > > vtxTriangles;
246 
252  mutable vector< set<int> > connectedVertices;
253 
265 
269  GeoTessGrid* loadGridAscii(const string& inputFile);
270 
274  GeoTessGrid* loadGridAscii(IFStreamAscii& input);
275 
276  static void loadGridAsciiFront(IFStreamAscii& input, int& gridFileFormat,
277  string& gridSWVersion, string& fileCreationDate,
278  string& gridid, const string& grdInptFile);
279 
283  GeoTessGrid* loadGridBinary(const string& inputFile);
284 
285  static void loadGridBinaryFront(IFStreamBinary& ifs, int& gridFileFormat,
286  string& gridSWVersion, string& fileCreationDate,
287  string& gridid, const string& grdInptFile);
288 
301  void findEdges();
302 
306  virtual GeoTessGrid* loadGridBinary(IFStreamBinary& ifs);
307 
321  int** findNeighbors();
322 
326  GeoTessGrid(const string& gid, const OptimizationType* opttype) :
327  vertices(NULL), triangles(NULL), levels(NULL), tessellations(NULL),
328  neighbors(NULL), edges(NULL), circumCenters(NULL), gridID(gid),
329  gridInputFile("null"), gridOutputFile("null"), gridSoftwareVersion(""),
330  gridGenerationDate(""), refCount(0), optimization(opttype)
331  {
332  }
333 
334 public:
335 
342  vertices(NULL), triangles(NULL), levels(NULL), tessellations(NULL),
343  neighbors(NULL), edges(NULL), circumCenters(NULL), gridID(""),
344  gridInputFile("null"), gridOutputFile("null"), gridSoftwareVersion(""),
345  gridGenerationDate(""), refCount(0), optimization(&OptimizationType::SPEED)
346  {
347  }
348 
352  GeoTessGrid(const OptimizationType* opttype) :
353  vertices(NULL), triangles(NULL), levels(NULL), tessellations(NULL),
354  neighbors(NULL), edges(NULL), circumCenters(NULL), gridID(""),
355  gridInputFile("null"), gridOutputFile("null"), gridSoftwareVersion(""),
356  gridGenerationDate(""), refCount(0), optimization(opttype)
357  {
358  }
359 
363  GeoTessGrid(GeoTessGrid &other);
364 
368  GeoTessGrid& operator = (const GeoTessGrid& other);
369 
373  GeoTessGrid* loadGrid(const string& inputFile);
374 
379  static string getGridID(const string& fileName);
380 
387  static bool isGeoTessGrid(const string& inputFile);
388 
392  bool operator == (const GeoTessGrid& g) const
393  { return (gridID == g.gridID); }
394 
398  bool operator != (const GeoTessGrid& g) const
399  { return !(*this == g); }
400 
411  const string& getGridID() const
412  {
413  return gridID;
414  }
415 
419  const OptimizationType* getOptimizationType() const { return optimization; }
420 
427  void setGridSoftwareVersion(const string& swVersion) {gridSoftwareVersion = swVersion; };
428 
435  const string& getGridSoftwareVersion() const {return gridSoftwareVersion; };
436 
443  void setGridGenerationDate(const string& gridDate) {gridGenerationDate = gridDate; };
444 
451  const string& getGridGenerationDate() const {return gridGenerationDate; };
452 
456  void setGridInputFile(const string& gridFile) { gridInputFile = gridFile; }
457 
465  const string& getGridInputFile() const {return gridInputFile; }
466 
474  const string& getGridOutputFile() const { return gridOutputFile; }
475 
479  const double* getVertex(int vertex) const
480  {
481  return vertices[vertex];
482  }
483 
499  int getVertexIndex(int tessId, int level, int triangle, int corner) const
500  {
501  return triangles[levels[tessellations[tessId][0] + level][0] + triangle][corner];
502  }
503 
515  double* getVertex(int tessId, int level, int triangle, int corner)
516  {
517  return vertices[triangles[levels[tessellations[tessId][0] + level][0] + triangle][corner]];
518  }
519 
528  double const* const* getVertices() const { return vertices; }
529 
538  void getVerticesTopLevel(const int& tessellation, set<const double*>& vectors)
539  {
540  getVertices(tessellation, getNLevels(tessellation)-1, vectors);
541  }
542 
552  void getVertices(const int& tessellation, const int& level, set<const double*>& vectors);
553 
568  const set<int>& getVertexIndices(const int& level);
569 
582  const set<int>& getVertexIndices(const int& tessId, const int& level)
583  { return getVertexIndices(getLevel(tessId, level)); }
584 
596  const set<int>& getVertexIndicesTopLevel(const int& tessId)
597  { return getVertexIndices(tessellations[tessId][1] - 1); }
598 
607  void clearVertexIndices() { connectedVertices.clear(); }
608 
612  int getNVertices() const { return nVertices; }
613 
617  int getNTessellations() const { return nTessellations; }
618 
622  int getNLevels() const { return nLevels; }
623 
632  int getNLevels(int tessellation) const
633  { return tessellations[tessellation][1] - tessellations[tessellation][0]; }
634 
644  int getLevel(int tessellation, int i) const
645  { return tessellations[tessellation][0] + i; }
646 
653  int getLastLevel(int tessellation) const
654  { return tessellations[tessellation][1] - 1; }
655 
659  int getNTriangles() const { return nTriangles; }
660 
670  int getNTriangles(int tessellation, int level) const
671  {
672  return levels[tessellations[tessellation][0] + level][1]
673  - levels[tessellations[tessellation][0] + level][0];
674  }
675 
686  int getTriangle(int tessellation, int level, int i) const
687  { return levels[tessellations[tessellation][0] + level][0] + i; }
688 
698  int getFirstTriangle(int tessellation, int level) const
699  { return levels[tessellations[tessellation][0] + level][0]; }
700 
710  int getLastTriangle(int tessellation, int level) const
711  { return levels[tessellations[tessellation][0] + level][1]-1; }
712 
722  int const* const* getTriangles() const { return triangles; }
723 
735  const int* getTriangleVertexIndexes(int triangleIndex) const
736  { return triangles[triangleIndex]; }
737 
749  int getTriangleVertexIndex(int triangleIndex, int cornerIndex) const
750  { return triangles[triangleIndex][cornerIndex]; }
751 
763  const double* getTriangleVertex(int triangleIndex, int cornerIndex) const
764  { return vertices[triangles[triangleIndex][cornerIndex]]; }
765 
766 
775  void getTriangleVertices(int triangle, double** triVrt)
776  {
777  int* corners = triangles[triangle];
778  triVrt[0][0] = vertices[corners[0]][0];
779  triVrt[0][1] = vertices[corners[0]][1];
780  triVrt[0][2] = vertices[corners[0]][2];
781  triVrt[1][0] = vertices[corners[1]][0];
782  triVrt[1][1] = vertices[corners[1]][1];
783  triVrt[1][2] = vertices[corners[1]][2];
784  triVrt[2][0] = vertices[corners[2]][0];
785  triVrt[2][1] = vertices[corners[2]][1];
786  triVrt[2][2] = vertices[corners[2]][2];
787  }
788 
803  const double* getCircumCenter(int triangle, double* const pA) const
804  {
805  // if SPEED optimization is off calculate circumcenter and store into pA
806 
807  if (edges == NULL)
808  {
809  // edges == null means that optimization level is MEMORY, not SPEED
810  int* corners = triangles[triangle];
811  GeoTessUtils::circumCenter(vertices[corners[0]], vertices[corners[1]],
812  vertices[corners[2]], pA);
813  return pA;
814  }
815 
816  // SPEED optimization is on ... ensure circumcenter array is created and
817  // initialized
818 
819  if (circumCenters == NULL)
820  {
821  circumCenters = CPPUtils::new2DArray<double>(nTriangles, 3);
822  CPPUtils::resetArray<double>(nTriangles*3, circumCenters[0], -2.0);
823  }
824 
825  // define circumcenter if it has not been evaluated and return result
826 
827  if (circumCenters[triangle][0] == -2.0)
828  {
829  int* corners = triangles[triangle];
830  GeoTessUtils::circumCenter(vertices[corners[0]], vertices[corners[1]],
831  vertices[corners[2]], circumCenters[triangle]);
832  }
833  return circumCenters[triangle];
834  }
835 
850  int getNeighbor(int triangleIndex, int neighborIndex) const
851  { return neighbors[triangleIndex][neighborIndex]; }
852 
866  const int* getNeighbors(int triangleIndex) const
867  { return neighbors[triangleIndex]; }
868 
891  const int* getNeighbors(const int& tessellation, const int& level, const int& triangle)
892  { return neighbors[getTriangle(tessellation, level, triangle)]; }
893 
918  int getNeighbor(const int& tessellation, const int& level, const int& triangle, const int& side)
919  { return neighbors[getTriangle(tessellation, level, triangle)][side]; }
920 
925  int const* const* getNeighbors() const { return neighbors; }
926 
940  int getNeighborIndex(const int& tid, const int& nid)
941  {
942  if (neighbors[tid][0] == nid)
943  return 0;
944  if (neighbors[tid][1] == nid)
945  return 1;
946  if (neighbors[tid][2] == nid)
947  return 2;
948  return -1;
949  }
950 
954  string toString();
955 
963  int getTriangle(int triangleIndex, double* vector);
964 
977  const vector<int>& getVertexTriangles(const int& tessId, const int& level, const int& vertex) const;
978 
992  const vector<int>& getVertexTriangles(int tessId, int vertex) const
993  { return getVertexTriangles(tessId, getNLevels(tessId)-1, vertex); }
994 
1001  void clearVertexTriangles(const int& level);
1002 
1009  void clearVertexTriangles();
1010 
1020  void getVertexNeighborsOrdered(const int& tessId, const int& level, const int& vertex, vector<int>& v);
1021 
1033  void getVertexNeighbors(const int& tessId, const int& level, const int& vertex, set<int>& nbrs)
1034  { getVertexNeighbors(tessId, level, vertex, 1, nbrs); }
1035 
1053  void getVertexNeighbors(const int& tessId, const int& level, const int& vertex,
1054  const int& order, set<int>& nbrs);
1055 
1056  // All methods below this point are public but are not documented in the doxygen documentation.
1057  // These are methods that typical applications will never need to call. They have to be
1058  // public because other classes in the GeoTess namespace need to access them.
1059  //
1061 
1065  GeoTessGrid(IFStreamAscii& input, const OptimizationType* opttype) :
1066  vertices(NULL), triangles(NULL), levels(NULL), tessellations(NULL),
1067  neighbors(NULL), edges(NULL), circumCenters(NULL), gridID(""),
1068  gridInputFile("null"), gridOutputFile("null"), gridSoftwareVersion(""),
1069  gridGenerationDate(""), refCount(0), optimization(opttype)
1070  { loadGridAscii(input); }
1071 
1075  GeoTessGrid(IFStreamBinary& input, const OptimizationType* opttype) :
1076  vertices(NULL), triangles(NULL), levels(NULL), tessellations(NULL),
1077  neighbors(NULL), edges(NULL), circumCenters(NULL), gridID(""),
1078  gridInputFile("null"), gridOutputFile("null"), gridSoftwareVersion(""),
1079  gridGenerationDate(""), refCount(0), optimization(opttype)
1080  { loadGridBinary(input); }
1081 
1085  virtual ~GeoTessGrid();
1086 
1090  int getReferenceCount() { return refCount; }
1091 
1095  void addReference() { ++refCount; }
1096 
1100  void removeReference()
1101  {
1102  if (isNotReferenced())
1103  {
1104  ostringstream os;
1105  os << endl << "ERROR in GeoTessGrid::removeReference" << endl
1106  << "Reference count (" << refCount << ") is already zero." << endl;
1107  throw GeoTessException(os, __FILE__, __LINE__, 2001);
1108  }
1109 
1110  --refCount;
1111  }
1112 
1116  bool isNotReferenced() { return (refCount == 0); }
1117 
1123  void writeGrid(const string& fileName);
1124 
1128  void writeGridAscii(const string& fileName);
1129 
1133  void writeGridAscii(IFStreamAscii& output);
1134 
1138  void writeGridBinary(const string& fileName);
1139 
1143  void writeGridBinary(IFStreamBinary& output);
1144 
1162  double const* const* const* getEdges() const { return edges; }
1163 
1184  void getEdgeList(const int& tessId, const int& level, const int& vertex, ArrayReuse<int>& store,
1185  list<int*>& e)
1186  { return getEdgeList(tessId, level, vertex, -1, store, e); }
1187 
1191  void getEdgeList(const int& tessId, const int& level, const int& vertex, const int& firstNeighborVertex,
1192  ArrayReuse<int>& store, list<int*>& e) const;
1193 
1195 
1199  bool isSupportedFormatVersion(int frmtVrsn)
1200  { return (frmtVrsn == 2); }
1201 
1210  void testGrid();
1211 
1212 };
1213 // end class GeoTessGrid
1214 
1215 }// end namespace geotess
1216 
1217 #endif // GEOTESSGRID_OBJECT_H