GeoTessCPP
2.0.0
Software to facilitate storage and retrieval of 3D information about the Earth.
|
00001 //- **************************************************************************** 00002 //- 00003 //- Copyright 2009 Sandia Corporation. Under the terms of Contract 00004 //- DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government 00005 //- retains certain rights in this software. 00006 //- 00007 //- BSD Open Source License. 00008 //- All rights reserved. 00009 //- 00010 //- Redistribution and use in source and binary forms, with or without 00011 //- modification, are permitted provided that the following conditions are met: 00012 //- 00013 //- * Redistributions of source code must retain the above copyright notice, 00014 //- this list of conditions and the following disclaimer. 00015 //- * Redistributions in binary form must reproduce the above copyright 00016 //- notice, this list of conditions and the following disclaimer in the 00017 //- documentation and/or other materials provided with the distribution. 00018 //- * Neither the name of Sandia National Laboratories nor the names of its 00019 //- contributors may be used to endorse or promote products derived from 00020 //- this software without specific prior written permission. 00021 //- 00022 //- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00023 //- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00024 //- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00025 //- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 00026 //- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00027 //- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00028 //- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00029 //- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00030 //- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00031 //- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00032 //- POSSIBILITY OF SUCH DAMAGE. 00033 //- 00034 //- **************************************************************************** 00035 00036 #ifndef GEOTESSGRID_OBJECT_H 00037 #define GEOTESSGRID_OBJECT_H 00038 00039 // **** _SYSTEM INCLUDES_ ****************************************************** 00040 00041 #include <iostream> 00042 #include <string> 00043 #include <fstream> 00044 #include <vector> 00045 #include <set> 00046 #include <list> 00047 #include <set> 00048 #include <sstream> 00049 00050 // use standard library objects 00051 using namespace std; 00052 00053 // **** _LOCAL INCLUDES_ ******************************************************* 00054 00055 #include "CPPUtils.h" 00056 #include "GeoTessUtils.h" 00057 #include "ArrayReuse.h" 00058 #include "GeoTessException.h" 00059 #include "OptimizationType.h" 00060 00061 // **** _BEGIN GEOTESS NAMESPACE_ ********************************************** 00062 00063 namespace geotess 00064 { 00065 00066 // **** _FORWARD REFERENCES_ *************************************************** 00067 00068 class IFStreamAscii; 00069 class IFStreamBinary; 00070 00071 // **** _CLASS DEFINITION_ ***************************************************** 00072 00102 class GEOTESS_EXP_IMP GeoTessGrid 00103 { 00104 protected: 00105 00106 // All methods below this point are public but are not documented in the doxygen documentation. 00107 // These are methods that typical applications will never need to call. They have to be 00108 // public because other classes in the GeoTess namespace need to access them. 00109 // 00111 00118 double** vertices; 00119 00123 int nVertices; 00124 00130 int** triangles; 00131 00135 int nTriangles; 00136 00148 int** levels; 00149 00153 int nLevels; 00154 00168 int** tessellations; 00169 00173 int nTessellations; 00174 00185 int** neighbors; 00186 00202 double*** edges; 00203 00208 mutable double** circumCenters; 00209 00218 string gridID; 00219 00223 string gridInputFile; 00224 00228 string gridOutputFile; 00229 00233 string gridSoftwareVersion; 00234 00239 string gridGenerationDate; 00240 00244 int refCount; 00245 00250 mutable vector< vector< vector<int> > > vtxTriangles; 00251 00257 mutable vector< set<int> > connectedVertices; 00258 00269 const OptimizationType* optimization; 00270 00274 GeoTessGrid* loadGridAscii(const string& inputFile); 00275 00280 GeoTessGrid* loadGridAscii(IFStreamAscii& input); 00281 00285 GeoTessGrid* loadGridBinary(const string& inputFile); 00286 00299 void findEdges(); 00300 00304 virtual GeoTessGrid* loadGridBinary(IFStreamBinary& ifs); 00305 00319 int** findNeighbors(); 00320 00324 GeoTessGrid(const string& gid, const OptimizationType* opttype) : 00325 vertices(NULL), triangles(NULL), levels(NULL), tessellations(NULL), 00326 neighbors(NULL), edges(NULL), circumCenters(NULL), gridID(gid), 00327 gridInputFile("null"), gridOutputFile("null"), gridSoftwareVersion(""), 00328 gridGenerationDate(""), refCount(0), optimization(opttype) 00329 { 00330 } 00331 00332 static void loadGridAsciiFront(IFStreamAscii& input, int& gridFileFormat, 00333 string& gridSWVersion, string& fileCreationDate, 00334 string& gridid, const string& grdInptFile); 00335 00336 static void loadGridBinaryFront(IFStreamBinary& ifs, int& gridFileFormat, 00337 string& gridSWVersion, string& fileCreationDate, 00338 string& gridid, const string& grdInptFile); 00339 00354 const set<int>& getVertexIndices(const int& level); 00355 00363 void clearVertexTriangles(const int& level); 00364 00366 00367 public: 00368 00374 GeoTessGrid() : 00375 vertices(NULL), triangles(NULL), levels(NULL), tessellations(NULL), 00376 neighbors(NULL), edges(NULL), circumCenters(NULL), gridID(""), 00377 gridInputFile("null"), gridOutputFile("null"), gridSoftwareVersion(""), 00378 gridGenerationDate(""), refCount(0), optimization(&OptimizationType::SPEED) 00379 { 00380 } 00381 00386 GeoTessGrid(const OptimizationType* opttype) : 00387 vertices(NULL), triangles(NULL), levels(NULL), tessellations(NULL), 00388 neighbors(NULL), edges(NULL), circumCenters(NULL), gridID(""), 00389 gridInputFile("null"), gridOutputFile("null"), gridSoftwareVersion(""), 00390 gridGenerationDate(""), refCount(0), optimization(opttype) 00391 { 00392 } 00393 00398 GeoTessGrid(GeoTessGrid &other); 00399 00405 GeoTessGrid& operator= (const GeoTessGrid& other); 00406 00412 GeoTessGrid* loadGrid(const string& inputFile); 00413 00420 static string getGridID(const string& fileName); 00421 00428 static bool isGeoTessGrid(const string& inputFile); 00429 00435 bool operator == (const GeoTessGrid& g) const 00436 { return (gridID == g.gridID); } 00437 00443 bool operator != (const GeoTessGrid& g) const 00444 { return !(*this == g); } 00445 00456 const string& getGridID() const 00457 { 00458 return gridID; 00459 } 00460 00465 const OptimizationType* getOptimizationType() const { return optimization; } 00466 00473 void setGridSoftwareVersion(const string& swVersion) {gridSoftwareVersion = swVersion; }; 00474 00481 const string& getGridSoftwareVersion() const {return gridSoftwareVersion; }; 00482 00489 void setGridGenerationDate(const string& gridDate) {gridGenerationDate = gridDate; }; 00490 00497 const string& getGridGenerationDate() const {return gridGenerationDate; }; 00498 00503 void setGridInputFile(const string& gridFile) { gridInputFile = gridFile; } 00504 00512 const string& getGridInputFile() const {return gridInputFile; } 00513 00521 const string& getGridOutputFile() const { return gridOutputFile; } 00522 00528 const double* getVertex(int vertex) const 00529 { 00530 return vertices[vertex]; 00531 } 00532 00541 int findClosestVertex(double* unit_vector, int tessId) 00542 { 00543 int* t = triangles[getTriangle(getFirstTriangle(tessId, 0), unit_vector)]; 00544 00545 int index = 0; 00546 double dot = GeoTessUtils::dot(unit_vector, vertices[t[0]]); 00547 00548 double doti = GeoTessUtils::dot(unit_vector, vertices[t[1]]); 00549 if (doti > dot) 00550 { 00551 index = 1; 00552 dot = doti; 00553 } 00554 00555 doti = GeoTessUtils::dot(unit_vector, vertices[t[2]]); 00556 if (doti > dot) 00557 { 00558 index = 2; 00559 dot = doti; 00560 } 00561 00562 return t[index]; 00563 } 00564 00580 int getVertexIndex(int tessId, int level, int triangle, int corner) const 00581 { 00582 return triangles[levels[tessellations[tessId][0] + level][0] + triangle][corner]; 00583 } 00584 00596 double* getVertex(int tessId, int level, int triangle, int corner) 00597 { 00598 return vertices[triangles[levels[tessellations[tessId][0] + level][0] + triangle][corner]]; 00599 } 00600 00610 double const* const* getVertices() const { return vertices; } 00611 00620 void getVerticesTopLevel(const int& tessellation, set<const double*>& vectors) 00621 { 00622 getVertices(tessellation, getNLevels(tessellation)-1, vectors); 00623 } 00624 00634 void getVertices(const int& tessellation, const int& level, set<const double*>& vectors); 00635 00648 const set<int>& getVertexIndices(const int& tessId, const int& level) 00649 { return getVertexIndices(getLevel(tessId, level)); } 00650 00662 const set<int>& getVertexIndicesTopLevel(const int& tessId) 00663 { return getVertexIndices(tessellations[tessId][1] - 1); } 00664 00673 void clearVertexIndices() { connectedVertices.clear(); } 00674 00679 int getNVertices() const { return nVertices; } 00680 00685 int getNTessellations() const { return nTessellations; } 00686 00694 int getNLevels(int tessellation) const 00695 { return tessellations[tessellation][1] - tessellations[tessellation][0]; } 00696 00706 int getLevel(int tessellation, int i) const 00707 { return tessellations[tessellation][0] + i; } 00708 00715 int getLastLevel(int tessellation) const 00716 { return tessellations[tessellation][1] - 1; } 00717 00727 int getNTriangles(int tessellation, int level) const 00728 { 00729 return levels[tessellations[tessellation][0] + level][1] 00730 - levels[tessellations[tessellation][0] + level][0]; 00731 } 00732 00744 int getTriangle(int tessellation, int level, int i) const 00745 { return levels[tessellations[tessellation][0] + level][0] + i; } 00746 00756 int getFirstTriangle(int tessellation, int level) const 00757 { return levels[tessellations[tessellation][0] + level][0]; } 00758 00768 int getLastTriangle(int tessellation, int level) const 00769 { return levels[tessellations[tessellation][0] + level][1]-1; } 00770 00780 int const* const* getTriangles() const { return triangles; } 00781 00793 const int* getTriangleVertexIndexes(int triangleIndex) const 00794 { return triangles[triangleIndex]; } 00795 00807 int getTriangleVertexIndex(int triangleIndex, int cornerIndex) const 00808 { return triangles[triangleIndex][cornerIndex]; } 00809 00821 const double* getTriangleVertex(int triangleIndex, int cornerIndex) const 00822 { return vertices[triangles[triangleIndex][cornerIndex]]; } 00823 00824 00833 void getTriangleVertices(int triangle, double** triVrt) 00834 { 00835 int* corners = triangles[triangle]; 00836 triVrt[0][0] = vertices[corners[0]][0]; 00837 triVrt[0][1] = vertices[corners[0]][1]; 00838 triVrt[0][2] = vertices[corners[0]][2]; 00839 triVrt[1][0] = vertices[corners[1]][0]; 00840 triVrt[1][1] = vertices[corners[1]][1]; 00841 triVrt[1][2] = vertices[corners[1]][2]; 00842 triVrt[2][0] = vertices[corners[2]][0]; 00843 triVrt[2][1] = vertices[corners[2]][1]; 00844 triVrt[2][2] = vertices[corners[2]][2]; 00845 } 00846 00861 const double* getCircumCenter(int triangle, double* const pA) const 00862 { 00863 // if SPEED optimization is off calculate circumcenter and store into pA 00864 00865 if (edges == NULL) 00866 { 00867 // edges == null means that optimization level is MEMORY, not SPEED 00868 int* corners = triangles[triangle]; 00869 GeoTessUtils::circumCenter(vertices[corners[0]], vertices[corners[1]], 00870 vertices[corners[2]], pA); 00871 return pA; 00872 } 00873 00874 // SPEED optimization is on ... ensure circumcenter array is created and 00875 // initialized 00876 00877 if (circumCenters == NULL) 00878 { 00879 circumCenters = CPPUtils::new2DArray<double>(nTriangles, 3); 00880 CPPUtils::resetArray<double>(nTriangles*3, circumCenters[0], -2.0); 00881 } 00882 00883 // define circumcenter if it has not been evaluated and return result 00884 00885 if (circumCenters[triangle][0] == -2.0) 00886 { 00887 int* corners = triangles[triangle]; 00888 GeoTessUtils::circumCenter(vertices[corners[0]], vertices[corners[1]], 00889 vertices[corners[2]], circumCenters[triangle]); 00890 } 00891 return circumCenters[triangle]; 00892 } 00893 00908 int getNeighbor(int triangleIndex, int neighborIndex) const 00909 { return neighbors[triangleIndex][neighborIndex]; } 00910 00924 const int* getNeighbors(int triangleIndex) const 00925 { return neighbors[triangleIndex]; } 00926 00949 const int* getNeighbors(const int& tessellation, const int& level, const int& triangle) 00950 { return neighbors[getTriangle(tessellation, level, triangle)]; } 00951 00976 int getNeighbor(const int& tessellation, const int& level, const int& triangle, const int& side) 00977 { return neighbors[getTriangle(tessellation, level, triangle)][side]; } 00978 00983 int const* const* getNeighbors() const { return neighbors; } 00984 00998 int getNeighborIndex(const int& tid, const int& nid) 00999 { 01000 if (neighbors[tid][0] == nid) 01001 return 0; 01002 if (neighbors[tid][1] == nid) 01003 return 1; 01004 if (neighbors[tid][2] == nid) 01005 return 2; 01006 return -1; 01007 } 01008 01012 string toString(); 01013 01021 int getTriangle(int triangleIndex, double* vector); 01022 01035 const vector<int>& getVertexTriangles(const int& tessId, const int& level, const int& vertex) const; 01036 01050 const vector<int>& getVertexTriangles(int tessId, int vertex) const 01051 { return getVertexTriangles(tessId, getNLevels(tessId)-1, vertex); } 01052 01059 void clearVertexTriangles(); 01060 01070 void getVertexNeighborsOrdered(const int& tessId, const int& level, const int& vertex, vector<int>& v); 01071 01083 void getVertexNeighbors(const int& tessId, const int& level, const int& vertex, set<int>& nbrs) 01084 { getVertexNeighbors(tessId, level, vertex, 1, nbrs); } 01085 01103 void getVertexNeighbors(const int& tessId, const int& level, const int& vertex, 01104 const int& order, set<int>& nbrs); 01105 01106 // All methods below this point are public but are not documented in the doxygen documentation. 01107 // These are methods that typical applications will never need to call. They have to be 01108 // public because other classes in the GeoTess namespace need to access them. 01109 // 01111 01115 GeoTessGrid(IFStreamAscii& input, const OptimizationType* opttype) : 01116 vertices(NULL), triangles(NULL), levels(NULL), tessellations(NULL), 01117 neighbors(NULL), edges(NULL), circumCenters(NULL), gridID(""), 01118 gridInputFile("null"), gridOutputFile("null"), gridSoftwareVersion(""), 01119 gridGenerationDate(""), refCount(0), optimization(opttype) 01120 { loadGridAscii(input); } 01121 01125 GeoTessGrid(IFStreamBinary& input, const OptimizationType* opttype) : 01126 vertices(NULL), triangles(NULL), levels(NULL), tessellations(NULL), 01127 neighbors(NULL), edges(NULL), circumCenters(NULL), gridID(""), 01128 gridInputFile("null"), gridOutputFile("null"), gridSoftwareVersion(""), 01129 gridGenerationDate(""), refCount(0), optimization(opttype) 01130 { loadGridBinary(input); } 01131 01135 virtual ~GeoTessGrid(); 01136 01140 int getReferenceCount() { return refCount; } 01141 01145 void addReference() { ++refCount; } 01146 01150 void removeReference() 01151 { 01152 if (isNotReferenced()) 01153 { 01154 ostringstream os; 01155 os << endl << "ERROR in GeoTessGrid::removeReference" << endl 01156 << "Reference count (" << refCount << ") is already zero." << endl; 01157 throw GeoTessException(os, __FILE__, __LINE__, 2001); 01158 } 01159 01160 --refCount; 01161 } 01162 01166 bool isNotReferenced() { return (refCount == 0); } 01167 01173 void writeGrid(const string& fileName); 01174 01178 void writeGridAscii(const string& fileName); 01179 01183 void writeGridAscii(IFStreamAscii& output); 01184 01188 void writeGridBinary(const string& fileName); 01189 01193 void writeGridBinary(IFStreamBinary& output); 01194 01212 double const* const* const* getEdges() const { return edges; } 01213 01234 void getEdgeList(const int& tessId, const int& level, const int& vertex, ArrayReuse<int>& store, 01235 list<int*>& e) 01236 { return getEdgeList(tessId, level, vertex, -1, store, e); } 01237 01241 void getEdgeList(const int& tessId, const int& level, const int& vertex, const int& firstNeighborVertex, 01242 ArrayReuse<int>& store, list<int*>& e) const; 01243 01249 bool isSupportedFormatVersion(int frmtVrsn) 01250 { return (frmtVrsn == 2); } 01251 01253 01262 void testGrid(); 01263 01264 }; 01265 // end class GeoTessGrid 01266 01267 }// end namespace geotess 01268 01269 #endif // GEOTESSGRID_OBJECT_H