GeoTessCPP  2.0.0
Software to facilitate storage and retrieval of 3D information about the Earth.
 All Classes Namespaces Files Functions Variables Typedefs Friends Defines
include/GeoTessGrid.h
Go to the documentation of this file.
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 "GeoTessOptimizationType.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   GeoTessOptimizationType*                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 GeoTessOptimizationType* 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(&GeoTessOptimizationType::SPEED)
00379         {
00380         }
00381 
00386         GeoTessGrid(const GeoTessOptimizationType* 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 GeoTessOptimizationType* 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 GeoTessOptimizationType* 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 GeoTessOptimizationType* 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         GeoTessGrid(double** _vertices, int& _nVertices, 
01136                 int** _triangles, int& _nTriangles,
01137                 int** _levels, int& _nLevels,
01138                 int** _tessellations, int& _nTessellations,
01139                 string& _gridID,
01140                 string& _gridInputFile, 
01141                 string& _gridOutputFile, 
01142                 string& _gridSoftwareVersion,
01143                 string& _gridGenerationDate, 
01144                 const GeoTessOptimizationType* _opttype) :
01145                         vertices(_vertices), nVertices(_nVertices),
01146                         triangles(_triangles), nTriangles(_nTriangles),
01147                         levels(_levels), nLevels(_nLevels),
01148                         tessellations(_tessellations), nTessellations(_nTessellations),
01149                         neighbors(NULL), 
01150                         edges(NULL), 
01151                         circumCenters(NULL),
01152                         gridID(_gridID),
01153                         gridInputFile(_gridInputFile), 
01154                         gridOutputFile(_gridOutputFile), 
01155                         gridSoftwareVersion(_gridSoftwareVersion),
01156                         gridGenerationDate(_gridGenerationDate), 
01157                         refCount(0), 
01158                         optimization(_opttype)
01159                 { findNeighbors(); }
01160 
01164         virtual ~GeoTessGrid();
01165 
01169         int getReferenceCount() { return refCount; }
01170 
01174         void addReference() { ++refCount; }
01175 
01179         void removeReference()
01180         {
01181                 if (isNotReferenced())
01182                 {
01183                         ostringstream os;
01184                         os << endl << "ERROR in GeoTessGrid::removeReference" << endl
01185                                         << "Reference count (" << refCount << ") is already zero." << endl;
01186                         throw GeoTessException(os, __FILE__, __LINE__, 2001);
01187                 }
01188 
01189                 --refCount;
01190         }
01191 
01195         bool isNotReferenced() { return (refCount == 0); }
01196 
01202         void writeGrid(const string& fileName);
01203 
01207         void writeGridAscii(const string& fileName);
01208 
01212         void writeGridAscii(IFStreamAscii& output);
01213 
01217         void writeGridBinary(const string& fileName);
01218 
01222         void writeGridBinary(IFStreamBinary& output);
01223 
01241         double const* const* const* getEdges() const { return edges; }
01242 
01263         void getEdgeList(const int& tessId, const int& level, const int& vertex, ArrayReuse<int>& store,
01264                         list<int*>& e)
01265         { return getEdgeList(tessId, level, vertex, -1, store, e); }
01266 
01270         void getEdgeList(const int& tessId, const int& level, const int& vertex, const int& firstNeighborVertex,
01271                         ArrayReuse<int>& store, list<int*>& e) const;
01272 
01278         bool isSupportedFormatVersion(int frmtVrsn)
01279         { return (frmtVrsn == 2); }
01280 
01282 
01291         void testGrid();
01292 
01298   int getNLevels() const { return nLevels; }
01299 
01311   int const* const* getLevels() const { return levels; }
01312 
01327   int const* const* getTessellations() const { return tessellations; }
01328 
01336   int getNTriangles() const { return nTriangles; }
01337 
01338         
01339 };
01340 // end class GeoTessGrid
01341 
01342 }// end namespace geotess
01343 
01344 #endif  // GEOTESSGRID_OBJECT_H