1
0
Fork 0

Use binary gzip files to store intermediate and shared edge files

Sort the nodelist to speedup node lookup after all nodes inserted
retrieve the node list just once in flatten elevation
This commit is contained in:
Peter Sadrozinski 2012-10-17 18:56:54 -04:00
parent b6a4dacf33
commit c336c134bf
18 changed files with 757 additions and 199 deletions

View file

@ -84,8 +84,8 @@ void TGConstruct::ConstructBucketStage1() {
} }
// STEP 1) // STEP 1)
// Load grid of elevation data (Array) // Load grid of elevation data (Array), and add the nodes
LoadElevationArray(); LoadElevationArray( true );
// STEP 2) // STEP 2)
// Clip 2D polygons against one another // Clip 2D polygons against one another
@ -131,37 +131,42 @@ void TGConstruct::ConstructBucketStage2() {
} }
// STEP 7) // STEP 7)
// Need the array of elevation data for stage 2 // Need the array of elevation data for stage 2, but don't add the nodes - we already have them
LoadElevationArray(); LoadElevationArray( false );
// STEP 6) // STEP 8)
// Merge in Shared data - should just be x,y nodes on the borders from stage1 // Merge in Shared data - should just be x,y nodes on the borders from stage1
LoadSharedEdgeData( 1 ); LoadSharedEdgeData( 1 );
// STEP 7) // STEP 9)
// Fix T-Junctions by finding nodes that lie close to polygon edges, and // Fix T-Junctions by finding nodes that lie close to polygon edges, and
// inserting them into the edge // inserting them into the edge
FixTJunctions(); FixTJunctions();
// STEP 8) // STEP 10)
// Generate triangles - we can't generate the node-face lookup table // Generate triangles - we can't generate the node-face lookup table
// until all polys are tesselated, as extra nodes can still be generated // until all polys are tesselated, as extra nodes can still be generated
TesselatePolys(); TesselatePolys();
// STEP 9) // STEP 11)
// Optimize the node list now since linear add is faster than sorted add.
// no more nodes can be added from this point on
nodes.SortNodes();
// STEP 12)
// Generate triangle vertex coordinates to node index lists // Generate triangle vertex coordinates to node index lists
// NOTE: After this point, no new nodes can be added // NOTE: After this point, no new nodes can be added
LookupNodesPerVertex(); LookupNodesPerVertex();
// STEP 10) // STEP 13)
// Interpolate elevations, and flatten stuff // Interpolate elevations, and flatten stuff
CalcElevations(); CalcElevations();
// STEP 11) // STEP 14)
// Generate face_connected list // Generate face_connected list
LookupFacesPerNode(); LookupFacesPerNode();
// STEP 12) // STEP 15)
// Save the tile boundary info for stage 3 // Save the tile boundary info for stage 3
// includes elevation info, and a list of connected triangles // includes elevation info, and a list of connected triangles
SaveSharedEdgeData( 2 ); SaveSharedEdgeData( 2 );
@ -182,22 +187,24 @@ void TGConstruct::ConstructBucketStage3() {
strcpy( ds_name, "" ); strcpy( ds_name, "" );
} }
// STEP 16)
// Load in the neighbor faces and elevation data // Load in the neighbor faces and elevation data
LoadSharedEdgeDataStage2(); LoadSharedEdgeDataStage2();
// STEP 12) // STEP 17)
// Average out the elevation for nodes on tile boundaries // Average out the elevation for nodes on tile boundaries
AverageEdgeElevations(); AverageEdgeElevations();
// STEP 12) // STEP 18)
// Calculate Face Normals // Calculate Face Normals
CalcFaceNormals(); CalcFaceNormals();
// STEP 13) // STEP 19)
// Calculate Point Normals // Calculate Point Normals
CalcPointNormals(); CalcPointNormals();
#if 0 #if 0
// STEP 20)
if ( c.get_cover().size() > 0 ) { if ( c.get_cover().size() > 0 ) {
// Now for all the remaining "default" land cover polygons, assign // Now for all the remaining "default" land cover polygons, assign
// each one it's proper type from the land use/land cover // each one it's proper type from the land use/land cover
@ -206,15 +213,15 @@ void TGConstruct::ConstructBucketStage3() {
} }
#endif #endif
// STEP 14) // STEP 21)
// Calculate Texture Coordinates // Calculate Texture Coordinates
CalcTextureCoordinates(); CalcTextureCoordinates();
// STEP 16) // STEP 22)
// Generate the btg file // Generate the btg file
WriteBtgFile(); WriteBtgFile();
// STEP 17) // STEP 23)
// Write Custom objects to .stg file // Write Custom objects to .stg file
AddCustomObjects(); AddCustomObjects();
} }

View file

@ -120,7 +120,7 @@ private:
bool IsOceanTile() { return isOcean; } bool IsOceanTile() { return isOcean; }
// Load Data // Load Data
void LoadElevationArray( void ); void LoadElevationArray( bool add_nodes );
int LoadLandclassPolys( void ); int LoadLandclassPolys( void );
// Load Data Helpers // Load Data Helpers
bool load_poly(const std::string& path); bool load_poly(const std::string& path);
@ -135,14 +135,14 @@ private:
// Shared edge Matching // Shared edge Matching
void SaveSharedEdgeDataStage2( void ); void SaveSharedEdgeDataStage2( void );
void LoadSharedEdgeDataStage2( void ); void LoadSharedEdgeDataStage2( void );
void WriteSharedEdgeNeighboorFaces( std::ofstream& ofs_e, Point3D pt ); void WriteSharedEdgeNeighboorFaces( gzFile& fp, Point3D pt );
void LoadSharedEdgeData( int stage ); void LoadSharedEdgeData( int stage );
void LoadNeighboorEdgeDataStage1( SGBucket& b, point_list& north, point_list& south, point_list& east, point_list& west ); void LoadNeighboorEdgeDataStage1( SGBucket& b, point_list& north, point_list& south, point_list& east, point_list& west );
void SaveSharedEdgeData( int stage ); void SaveSharedEdgeData( int stage );
void ReadNeighborFaces( std::ifstream& ifs_e ); void ReadNeighborFaces( gzFile& fp );
void WriteNeighborFaces( std::ofstream& ofs_e, Point3D pt ); void WriteNeighborFaces( gzFile& fp, Point3D pt );
TGNeighborFaces* AddNeighborFaces( Point3D node ); TGNeighborFaces* AddNeighborFaces( Point3D node );
TGNeighborFaces* FindNeighborFaces( Point3D node ); TGNeighborFaces* FindNeighborFaces( Point3D node );

View file

@ -32,7 +32,7 @@ using std::string;
// Load elevation data from an Array file (a regular grid of elevation data) // Load elevation data from an Array file (a regular grid of elevation data)
// and return list of fitted nodes. // and return list of fitted nodes.
void TGConstruct::LoadElevationArray( void ) { void TGConstruct::LoadElevationArray( bool add_nodes ) {
string base = bucket.gen_base_path(); string base = bucket.gen_base_path();
int i; int i;
@ -49,6 +49,7 @@ void TGConstruct::LoadElevationArray( void ) {
array.parse( bucket ); array.parse( bucket );
array.remove_voids( ); array.remove_voids( );
if ( add_nodes ) {
point_list corner_list = array.get_corner_list(); point_list corner_list = array.get_corner_list();
for (unsigned int i=0; i<corner_list.size(); i++) { for (unsigned int i=0; i<corner_list.size(); i++) {
nodes.unique_add(corner_list[i]); nodes.unique_add(corner_list[i]);
@ -59,6 +60,7 @@ void TGConstruct::LoadElevationArray( void ) {
nodes.unique_add(fit_list[i]); nodes.unique_add(fit_list[i]);
} }
} }
}
static void calc_gc_course_dist( const Point3D& start, const Point3D& dest, static void calc_gc_course_dist( const Point3D& start, const Point3D& dest,
double *course, double *dist ) { double *course, double *dist ) {
@ -92,6 +94,7 @@ void TGConstruct::CalcElevations( void )
TGPolyNodes tri_nodes; TGPolyNodes tri_nodes;
double e1, e2, e3, min; double e1, e2, e3, min;
int n1, n2, n3; int n1, n2, n3;
point_list raw_nodes;
Point3D p; Point3D p;
SG_LOG(SG_GENERAL, SG_ALERT, "fixing node heights"); SG_LOG(SG_GENERAL, SG_ALERT, "fixing node heights");
@ -106,6 +109,7 @@ void TGConstruct::CalcElevations( void )
} }
} }
raw_nodes = nodes.get_geod_nodes();
// now flatten some stuff // now flatten some stuff
for (unsigned int area = 0; area < TG_MAX_AREA_TYPES; area++) { for (unsigned int area = 0; area < TG_MAX_AREA_TYPES; area++) {
if ( is_lake_area( (AreaType)area ) ) { if ( is_lake_area( (AreaType)area ) ) {
@ -153,7 +157,6 @@ void TGConstruct::CalcElevations( void )
exit(0); exit(0);
} }
point_list raw_nodes = nodes.get_geod_nodes();
n1 = tri_nodes.get_pt( tri, 0 ); n1 = tri_nodes.get_pt( tri, 0 );
e1 = nodes.get_node(n1).GetPosition().z(); e1 = nodes.get_node(n1).GetPosition().z();
@ -197,7 +200,6 @@ void TGConstruct::CalcElevations( void )
exit(0); exit(0);
} }
point_list raw_nodes = nodes.get_geod_nodes();
n1 = tri_nodes.get_pt( tri, 0 ); n1 = tri_nodes.get_pt( tri, 0 );
e1 = nodes.get_node(n1).GetPosition().z(); e1 = nodes.get_node(n1).GetPosition().z();

View file

@ -34,7 +34,7 @@
// indexes into the node array (cast as unsigned long) // indexes into the node array (cast as unsigned long)
void TGConstruct::LookupNodesPerVertex( void ) void TGConstruct::LookupNodesPerVertex( void )
{ {
SG_LOG(SG_GENERAL, SG_ALERT, "LookupNodexPerVertex"); SG_LOG(SG_GENERAL, SG_ALERT, "LookupNodesPerVertex");
// for each node, traverse all the triangles - and create face lists // for each node, traverse all the triangles - and create face lists
for ( unsigned int area = 0; area < TG_MAX_AREA_TYPES; area++ ) { for ( unsigned int area = 0; area < TG_MAX_AREA_TYPES; area++ ) {
@ -50,6 +50,7 @@ void TGConstruct::LookupNodesPerVertex( void )
if (idx >= 0) { if (idx >= 0) {
tri_nodes.add_node( tri, idx ); tri_nodes.add_node( tri, idx );
} else { } else {
SG_LOG(SG_GENERAL, SG_ALERT, "didn't find vertex! " << tris.get_pt( tri, vertex ) );
exit(0); exit(0);
} }
} }

View file

@ -28,6 +28,7 @@
#include <simgear/misc/sg_dir.hxx> #include <simgear/misc/sg_dir.hxx>
#include <simgear/debug/logstream.hxx> #include <simgear/debug/logstream.hxx>
#include <simgear/io/lowlevel.hxx>
#include <Geometry/poly_support.hxx> #include <Geometry/poly_support.hxx>
@ -37,8 +38,7 @@ using std::string;
void TGConstruct::SaveSharedEdgeData( int stage ) void TGConstruct::SaveSharedEdgeData( int stage )
{ {
string dir; string filepath;
string file;
switch( stage ) { switch( stage ) {
case 1: case 1:
@ -48,48 +48,47 @@ void TGConstruct::SaveSharedEdgeData( int stage )
nodes.get_geod_edge( bucket, north, south, east, west ); nodes.get_geod_edge( bucket, north, south, east, west );
dir = share_base + "/stage1/" + bucket.gen_base_path(); filepath = share_base + "/stage1/" + bucket.gen_base_path() + "/" + bucket.gen_index_str() + "_edges";
SGPath file(filepath);
file.create_dir( 0755 );
SGPath sgp( dir ); gzFile fp;
sgp.append( "dummy" ); if ( (fp = gzopen( filepath.c_str(), "wb9" )) == NULL ) {
sgp.create_dir( 0755 ); SG_LOG( SG_GENERAL, SG_INFO, "ERROR: opening " << file.str() << " for writing!" );
return;
}
file = dir + "/" + bucket.gen_index_str() + "_edges"; sgClearWriteError();
std::ofstream ofs_e( file.c_str() );
// first, set the precision
ofs_e << std::setprecision(12);
ofs_e << std::fixed;
// north // north
nCount = north.size(); nCount = north.size();
ofs_e << nCount << "\n"; sgWriteInt( fp, nCount );
for (int i=0; i<nCount; i++) { for (int i=0; i<nCount; i++) {
ofs_e << north[i]; sgWritePoint3D( fp, north[i] );
} }
// south // south
nCount = south.size(); nCount = south.size();
ofs_e << nCount << "\n"; sgWriteInt( fp, nCount );
for (int i=0; i<nCount; i++) { for (int i=0; i<nCount; i++) {
ofs_e << south[i]; sgWritePoint3D( fp, south[i] );
} }
// east // east
nCount = east.size(); nCount = east.size();
ofs_e << nCount << "\n"; sgWriteInt( fp, nCount );
for (int i=0; i<nCount; i++) { for (int i=0; i<nCount; i++) {
ofs_e << east[i]; sgWritePoint3D( fp, east[i] );
} }
// west // west
nCount = west.size(); nCount = west.size();
ofs_e << nCount << "\n"; sgWriteInt( fp, nCount );
for (int i=0; i<nCount; i++) { for (int i=0; i<nCount; i++) {
ofs_e << west[i]; sgWritePoint3D( fp, west[i] );
} }
ofs_e.close(); gzclose(fp);
} }
break; break;
@ -111,7 +110,7 @@ void TGConstruct::SaveSharedEdgeData( int stage )
} }
} }
void TGConstruct::WriteNeighborFaces( std::ofstream& ofs_e, Point3D pt ) void TGConstruct::WriteNeighborFaces( gzFile& fp, Point3D pt )
{ {
// find all neighboors of this point // find all neighboors of this point
int n = nodes.find( pt ); int n = nodes.find( pt );
@ -119,7 +118,7 @@ void TGConstruct::WriteNeighborFaces( std::ofstream& ofs_e, Point3D pt )
TGFaceList faces = node.GetFaces(); TGFaceList faces = node.GetFaces();
// write the number of neighboor faces // write the number of neighboor faces
ofs_e << faces.size() << "\n"; sgWriteInt( fp, faces.size() );
// write out each face normal and size // write out each face normal and size
for (unsigned int j=0; j<faces.size(); j++) { for (unsigned int j=0; j<faces.size(); j++) {
@ -142,11 +141,10 @@ void TGConstruct::WriteNeighborFaces( std::ofstream& ofs_e, Point3D pt )
double face_area = triangle_area( p1, p2, p3 ); double face_area = triangle_area( p1, p2, p3 );
Point3D face_normal = Point3D::fromSGVec3( calc_normal( face_area, wgs_p1, wgs_p2, wgs_p3 ) ); Point3D face_normal = Point3D::fromSGVec3( calc_normal( face_area, wgs_p1, wgs_p2, wgs_p3 ) );
ofs_e << face_area << " "; sgWriteDouble( fp, face_area );
ofs_e << face_normal; sgWritePoint3D( fp, face_normal );
} }
} }
ofs_e << "\n";
} }
TGNeighborFaces* TGConstruct::FindNeighborFaces( Point3D node ) TGNeighborFaces* TGConstruct::FindNeighborFaces( Point3D node )
@ -173,19 +171,19 @@ TGNeighborFaces* TGConstruct::AddNeighborFaces( Point3D node )
return &neighbor_faces[neighbor_faces.size()-1]; return &neighbor_faces[neighbor_faces.size()-1];
} }
void TGConstruct::ReadNeighborFaces( std::ifstream& in ) void TGConstruct::ReadNeighborFaces( gzFile& fp )
{ {
int count; int count;
// read the count // read the count
in >> count; sgReadInt( fp, &count );
for (int i=0; i<count; i++) { for (int i=0; i<count; i++) {
TGNeighborFaces* pFaces; TGNeighborFaces* pFaces;
Point3D node; Point3D node;
int num_faces; int num_faces;
in >> node; sgReadPoint3D( fp, node );
// look to see if we already have this node // look to see if we already have this node
// If we do, (it's a corner) add more faces to it. // If we do, (it's a corner) add more faces to it.
@ -205,16 +203,16 @@ void TGConstruct::ReadNeighborFaces( std::ifstream& in )
// remember all of the elevation data for the node, so we can average // remember all of the elevation data for the node, so we can average
pFaces->elevations.push_back( node.z() ); pFaces->elevations.push_back( node.z() );
in >> num_faces; sgReadInt( fp, &num_faces );
for (int j=0; j<num_faces; j++) for (int j=0; j<num_faces; j++)
{ {
double area; double area;
Point3D normal; Point3D normal;
in >> area; sgReadDouble( fp, &area );
pFaces->face_areas.push_back( area ); pFaces->face_areas.push_back( area );
in >> normal; sgReadPoint3D( fp, normal );
pFaces->face_normals.push_back( normal ); pFaces->face_normals.push_back( normal );
} }
} }
@ -225,7 +223,6 @@ void TGConstruct::SaveSharedEdgeDataStage2( void )
string dir; string dir;
string file; string file;
point_list north, south, east, west; point_list north, south, east, west;
std::ofstream ofs_e;
int nCount; int nCount;
nodes.get_geod_edge( bucket, north, south, east, west ); nodes.get_geod_edge( bucket, north, south, east, west );
@ -239,110 +236,123 @@ void TGConstruct::SaveSharedEdgeDataStage2( void )
// north edge // north edge
file = dir + "/" + bucket.gen_index_str() + "_north_edge"; file = dir + "/" + bucket.gen_index_str() + "_north_edge";
ofs_e.open( file.c_str() ); gzFile fp;
ofs_e << std::setprecision(12); if ( (fp = gzopen( file.c_str(), "wb9" )) == NULL ) {
ofs_e << std::fixed; SG_LOG( SG_GENERAL, SG_INFO,"ERROR: opening " << file.c_str() << " for writing!" );
return;
}
sgClearWriteError();
nCount = north.size(); nCount = north.size();
ofs_e << nCount << "\n"; sgWriteInt( fp, nCount );
for (int i=0; i<nCount; i++) { for (int i=0; i<nCount; i++) {
// write the 3d point // write the 3d point
ofs_e << north[i]; sgWritePoint3D( fp, north[i] );
WriteNeighborFaces( ofs_e, north[i] ); WriteNeighborFaces( fp, north[i] );
} }
ofs_e.close(); gzclose(fp);
// south edge // south edge
file = dir + "/" + bucket.gen_index_str() + "_south_edge"; file = dir + "/" + bucket.gen_index_str() + "_south_edge";
ofs_e.open( file.c_str() ); if ( (fp = gzopen( file.c_str(), "wb9" )) == NULL ) {
ofs_e << std::setprecision(12); SG_LOG( SG_GENERAL, SG_INFO,"ERROR: opening " << file.c_str() << " for writing!" );
ofs_e << std::fixed; return;
}
sgClearWriteError();
nCount = south.size(); nCount = south.size();
ofs_e << nCount << "\n"; sgWriteInt( fp, nCount );
for (int i=0; i<nCount; i++) { for (int i=0; i<nCount; i++) {
ofs_e << south[i]; sgWritePoint3D( fp, south[i] );
WriteNeighborFaces( ofs_e, south[i] ); WriteNeighborFaces( fp, south[i] );
} }
ofs_e.close(); gzclose(fp);
// east edge // east edge
file = dir + "/" + bucket.gen_index_str() + "_east_edge"; file = dir + "/" + bucket.gen_index_str() + "_east_edge";
ofs_e.open( file.c_str() ); if ( (fp = gzopen( file.c_str(), "wb9" )) == NULL ) {
ofs_e << std::setprecision(12); SG_LOG( SG_GENERAL, SG_INFO,"ERROR: opening " << file.c_str() << " for writing!" );
ofs_e << std::fixed; return;
}
sgClearWriteError();
nCount = east.size(); nCount = east.size();
ofs_e << nCount << "\n"; sgWriteInt( fp, nCount );
for (int i=0; i<nCount; i++) { for (int i=0; i<nCount; i++) {
ofs_e << east[i]; sgWritePoint3D( fp, east[i] );
WriteNeighborFaces( ofs_e, east[i] ); WriteNeighborFaces( fp, east[i] );
} }
ofs_e.close(); gzclose(fp);
// west egde // west egde
file = dir + "/" + bucket.gen_index_str() + "_west_edge"; file = dir + "/" + bucket.gen_index_str() + "_west_edge";
ofs_e.open( file.c_str() ); if ( (fp = gzopen( file.c_str(), "wb9" )) == NULL ) {
ofs_e << std::setprecision(12); SG_LOG( SG_GENERAL, SG_INFO,"ERROR: opening " << file.c_str() << " for writing!" );
ofs_e << std::fixed; return;
}
sgClearWriteError();
nCount = west.size(); nCount = west.size();
ofs_e << nCount << "\n"; sgWriteInt( fp, nCount );
for (int i=0; i<nCount; i++) { for (int i=0; i<nCount; i++) {
ofs_e << west[i]; sgWritePoint3D( fp, west[i] );
WriteNeighborFaces( ofs_e, west[i] ); WriteNeighborFaces( fp, west[i] );
} }
ofs_e.close(); gzclose(fp);
} }
void TGConstruct::LoadSharedEdgeDataStage2( void ) void TGConstruct::LoadSharedEdgeDataStage2( void )
{ {
string dir; string dir;
string file; string file;
std::ifstream ifs_edge;
double clon = bucket.get_center_lon(); double clon = bucket.get_center_lon();
double clat = bucket.get_center_lat(); double clat = bucket.get_center_lat();
gzFile fp;
SGBucket b; SGBucket b;
// Read Northern tile and add its southern node faces // Read Northern tile and add its southern node faces
b = sgBucketOffset(clon, clat, 0, 1); b = sgBucketOffset(clon, clat, 0, 1);
dir = share_base + "/stage2/" + b.gen_base_path(); dir = share_base + "/stage2/" + b.gen_base_path();
file = dir + "/" + b.gen_index_str() + "_south_edge"; file = dir + "/" + b.gen_index_str() + "_south_edge";
ifs_edge.open( file.c_str() ); fp = gzopen( file.c_str(), "rb" );
if ( ifs_edge.is_open() ) { if (fp) {
ReadNeighborFaces( ifs_edge ); sgClearReadError();
ReadNeighborFaces( fp );
gzclose( fp );
} }
ifs_edge.close();
// Read Southern tile and add its northern node faces // Read Southern tile and add its northern node faces
b = sgBucketOffset(clon, clat, 0, -1); b = sgBucketOffset(clon, clat, 0, -1);
dir = share_base + "/stage2/" + b.gen_base_path(); dir = share_base + "/stage2/" + b.gen_base_path();
file = dir + "/" + b.gen_index_str() + "_north_edge"; file = dir + "/" + b.gen_index_str() + "_north_edge";
ifs_edge.open( file.c_str() ); fp = gzopen( file.c_str(), "rb" );
if ( ifs_edge.is_open() ) { if (fp) {
ReadNeighborFaces( ifs_edge ); sgClearReadError();
ReadNeighborFaces( fp );
gzclose( fp );
} }
ifs_edge.close();
// Read Eastern tile and add its western node faces // Read Eastern tile and add its western node faces
b = sgBucketOffset(clon, clat, 1, 0); b = sgBucketOffset(clon, clat, 1, 0);
dir = share_base + "/stage2/" + b.gen_base_path(); dir = share_base + "/stage2/" + b.gen_base_path();
file = dir + "/" + b.gen_index_str() + "_west_edge"; file = dir + "/" + b.gen_index_str() + "_west_edge";
ifs_edge.open( file.c_str() ); fp = gzopen( file.c_str(), "rb" );
if ( ifs_edge.is_open() ) { if (fp) {
ReadNeighborFaces( ifs_edge ); sgClearReadError();
ReadNeighborFaces( fp );
gzclose( fp );
} }
ifs_edge.close();
// Read Western tile and add its eastern node faces // Read Western tile and add its eastern node faces
b = sgBucketOffset(clon, clat, -1, 0); b = sgBucketOffset(clon, clat, -1, 0);
dir = share_base + "/stage2/" + b.gen_base_path(); dir = share_base + "/stage2/" + b.gen_base_path();
file = dir + "/" + b.gen_index_str() + "_east_edge"; file = dir + "/" + b.gen_index_str() + "_east_edge";
ifs_edge.open( file.c_str() ); fp = gzopen( file.c_str(), "rb" );
if ( ifs_edge.is_open() ) { if (fp) {
ReadNeighborFaces( ifs_edge ); sgClearReadError();
ReadNeighborFaces( fp );
gzclose( fp );
} }
ifs_edge.close();
} }
@ -350,6 +360,7 @@ void TGConstruct::SaveToIntermediateFiles( int stage )
{ {
string dir; string dir;
string file; string file;
gzFile fp;
switch( stage ) { switch( stage ) {
case 1: // Save the clipped polys and node list case 1: // Save the clipped polys and node list
@ -363,22 +374,22 @@ void TGConstruct::SaveToIntermediateFiles( int stage )
sgp.create_dir( 0755 ); sgp.create_dir( 0755 );
file = dir + "/" + bucket.gen_index_str() + "_clipped_polys"; file = dir + "/" + bucket.gen_index_str() + "_clipped_polys";
std::ofstream ofs_cp( file.c_str() ); if ( (fp = gzopen( file.c_str(), "wb9" )) == NULL ) {
SG_LOG( SG_GENERAL, SG_INFO,"ERROR: opening " << file.c_str() << " for writing!" );
// first, set the precision return;
ofs_cp << std::setprecision(15); }
ofs_cp << std::fixed; sgClearWriteError();
ofs_cp << polys_clipped; polys_clipped.SaveToGzFile( fp );
ofs_cp.close(); gzclose( fp );
file = dir + "/" + bucket.gen_index_str() + "_nodes"; file = dir + "/" + bucket.gen_index_str() + "_nodes";
std::ofstream ofs_n( file.c_str() ); if ( (fp = gzopen( file.c_str(), "wb9" )) == NULL ) {
SG_LOG( SG_GENERAL, SG_INFO,"ERROR: opening " << file.c_str() << " for writing!" );
// first, set the precision return;
ofs_n << std::setprecision(15); }
ofs_n << std::fixed; sgClearWriteError();
ofs_n << nodes; nodes.SaveToGzFile( fp );
ofs_n.close(); gzclose( fp );
} }
break; break;
@ -394,22 +405,22 @@ void TGConstruct::SaveToIntermediateFiles( int stage )
sgp.create_dir( 0755 ); sgp.create_dir( 0755 );
file = dir + "/" + bucket.gen_index_str() + "_clipped_polys"; file = dir + "/" + bucket.gen_index_str() + "_clipped_polys";
std::ofstream ofs_cp( file.c_str() ); if ( (fp = gzopen( file.c_str(), "wb9" )) == NULL ) {
SG_LOG( SG_GENERAL, SG_INFO,"ERROR: opening " << file.c_str() << " for writing!" );
// first, set the precision return;
ofs_cp << std::setprecision(15); }
ofs_cp << std::fixed; sgClearWriteError();
ofs_cp << polys_clipped; polys_clipped.SaveToGzFile( fp );
ofs_cp.close(); gzclose( fp );
file = dir + "/" + bucket.gen_index_str() + "_nodes"; file = dir + "/" + bucket.gen_index_str() + "_nodes";
std::ofstream ofs_n( file.c_str() ); if ( (fp = gzopen( file.c_str(), "wb9" )) == NULL ) {
SG_LOG( SG_GENERAL, SG_INFO,"ERROR: opening " << file.c_str() << " for writing!" );
// first, set the precision return;
ofs_n << std::setprecision(15); }
ofs_n << std::fixed; sgClearWriteError();
ofs_n << nodes; nodes.SaveToGzFile( fp );
ofs_n.close(); gzclose( fp );
} }
break; break;
} }
@ -420,52 +431,53 @@ void TGConstruct::LoadNeighboorEdgeDataStage1( SGBucket& b, point_list& north, p
{ {
string dir; string dir;
string file; string file;
gzFile fp;
Point3D pt; Point3D pt;
int nCount; int nCount;
dir = share_base + "/stage1/" + b.gen_base_path(); dir = share_base + "/stage1/" + b.gen_base_path();
file = dir + "/" + b.gen_index_str() + "_edges"; file = dir + "/" + b.gen_index_str() + "_edges";
std::ifstream ifs_edges( file.c_str() ); fp = gzopen( file.c_str(), "rb" );
north.clear(); north.clear();
south.clear(); south.clear();
east.clear(); east.clear();
west.clear(); west.clear();
if ( ifs_edges.is_open() ) { if (fp) {
// North // North
ifs_edges >> nCount; sgReadInt( fp, &nCount );
SG_LOG( SG_CLIPPER, SG_INFO, "loading " << nCount << "Points on " << b.gen_index_str() << " north boundary"); SG_LOG( SG_CLIPPER, SG_INFO, "loading " << nCount << "Points on " << b.gen_index_str() << " north boundary");
for (int i=0; i<nCount; i++) { for (int i=0; i<nCount; i++) {
ifs_edges >> pt; sgReadPoint3D( fp, pt );
north.push_back(pt); north.push_back(pt);
} }
// South // South
ifs_edges >> nCount; sgReadInt( fp, &nCount );
SG_LOG( SG_CLIPPER, SG_INFO, "loading " << nCount << "Points on " << b.gen_index_str() << " south boundary"); SG_LOG( SG_CLIPPER, SG_INFO, "loading " << nCount << "Points on " << b.gen_index_str() << " south boundary");
for (int i=0; i<nCount; i++) { for (int i=0; i<nCount; i++) {
ifs_edges >> pt; sgReadPoint3D( fp, pt );
south.push_back(pt); south.push_back(pt);
} }
// East // East
ifs_edges >> nCount; sgReadInt( fp, &nCount );
SG_LOG( SG_CLIPPER, SG_INFO, "loading " << nCount << "Points on " << b.gen_index_str() << " east boundary"); SG_LOG( SG_CLIPPER, SG_INFO, "loading " << nCount << "Points on " << b.gen_index_str() << " east boundary");
for (int i=0; i<nCount; i++) { for (int i=0; i<nCount; i++) {
ifs_edges >> pt; sgReadPoint3D( fp, pt );
east.push_back(pt); east.push_back(pt);
} }
// West // West
ifs_edges >> nCount; sgReadInt( fp, &nCount );
SG_LOG( SG_CLIPPER, SG_INFO, "loading " << nCount << "Points on " << b.gen_index_str() << " west boundary"); SG_LOG( SG_CLIPPER, SG_INFO, "loading " << nCount << "Points on " << b.gen_index_str() << " west boundary");
for (int i=0; i<nCount; i++) { for (int i=0; i<nCount; i++) {
ifs_edges >> pt; sgReadPoint3D( fp, pt );
west.push_back(pt); west.push_back(pt);
} }
ifs_edges.close(); gzclose( fp );
} }
} }
@ -517,6 +529,7 @@ void TGConstruct::LoadFromIntermediateFiles( int stage )
{ {
string dir; string dir;
string file; string file;
gzFile fp;
bool read_ok = false; bool read_ok = false;
switch( stage ) { switch( stage ) {
@ -524,18 +537,18 @@ void TGConstruct::LoadFromIntermediateFiles( int stage )
{ {
dir = share_base + "/stage1/" + bucket.gen_base_path(); dir = share_base + "/stage1/" + bucket.gen_base_path();
file = dir + "/" + bucket.gen_index_str() + "_clipped_polys"; file = dir + "/" + bucket.gen_index_str() + "_clipped_polys";
fp = gzopen( file.c_str(), "rb" );
std::ifstream ifs_cp( file.c_str() ); if ( fp ) {
if ( ifs_cp.good() ) { polys_clipped.LoadFromGzFile( fp );
ifs_cp >> polys_clipped; gzclose( fp );
ifs_cp.close();
file = dir + "/" + bucket.gen_index_str() + "_nodes"; file = dir + "/" + bucket.gen_index_str() + "_nodes";
fp = gzopen( file.c_str(), "rb" );
std::ifstream ifs_n( file.c_str() ); if ( fp ) {
if ( ifs_n.good() ) { nodes.LoadFromGzFile( fp );
ifs_n >> nodes; gzclose( fp );
ifs_n.close();
read_ok = true; read_ok = true;
} }
@ -548,18 +561,18 @@ void TGConstruct::LoadFromIntermediateFiles( int stage )
{ {
dir = share_base + "/stage2/" + bucket.gen_base_path(); dir = share_base + "/stage2/" + bucket.gen_base_path();
file = dir + "/" + bucket.gen_index_str() + "_clipped_polys"; file = dir + "/" + bucket.gen_index_str() + "_clipped_polys";
fp = gzopen( file.c_str(), "rb" );
std::ifstream ifs_cp( file.c_str() ); if ( fp ) {
if ( ifs_cp.good() ) { polys_clipped.LoadFromGzFile( fp );
ifs_cp >> polys_clipped; gzclose( fp );
ifs_cp.close();
file = dir + "/" + bucket.gen_index_str() + "_nodes"; file = dir + "/" + bucket.gen_index_str() + "_nodes";
fp = gzopen( file.c_str(), "rb" );
std::ifstream ifs_n( file.c_str() ); if ( fp ) {
if ( ifs_n.good() ) { nodes.LoadFromGzFile( fp );
ifs_n >> nodes; gzclose( fp );
ifs_n.close();
read_ok = true; read_ok = true;
} }

View file

@ -31,6 +31,7 @@
#endif #endif
#include "tglandclass.hxx" #include "tglandclass.hxx"
#include <simgear/io/lowlevel.hxx>
void TGLandclass::clear(void) void TGLandclass::clear(void)
{ {
@ -61,6 +62,22 @@ std::istream& operator >> ( std::istream& in, TGLandclass& lc)
return in; return in;
} }
void TGLandclass::LoadFromGzFile(gzFile& fp)
{
int i, j, count;
// Load all landclass shapes
for (i=0; i<TG_MAX_AREA_TYPES; i++) {
sgReadInt( fp, &count );
for (j=0; j<count; j++) {
TGShape shape;
shape.LoadFromGzFile( fp );
shapes[i].push_back( shape );
}
}
}
std::ostream& operator<< ( std::ostream& out, const TGLandclass& lc ) std::ostream& operator<< ( std::ostream& out, const TGLandclass& lc )
{ {
int i, j, count; int i, j, count;
@ -77,4 +94,19 @@ std::ostream& operator<< ( std::ostream& out, const TGLandclass& lc )
} }
return out; return out;
} }
void TGLandclass::SaveToGzFile(gzFile& fp)
{
int i, j, count;
TGShape shape;
// Save all landclass shapes
for (i=0; i<TG_MAX_AREA_TYPES; i++) {
count = shapes[i].size();
sgWriteInt( fp, count );
for (j=0; j<count; j++) {
shapes[i][j].SaveToGzFile( fp );
}
}
}

View file

@ -33,6 +33,8 @@
# error This library requires C++ # error This library requires C++
#endif #endif
#include <simgear/math/sg_types.hxx>
#include <simgear/io/lowlevel.hxx>
#define TG_MAX_AREA_TYPES 128 #define TG_MAX_AREA_TYPES 128
#include "tgshape.hxx" #include "tgshape.hxx"
@ -147,6 +149,8 @@ public:
{ {
return shapes[area][shape].sps[segment].set_tri_idxs( tis ); return shapes[area][shape].sps[segment].set_tri_idxs( tis );
} }
void SaveToGzFile( gzFile& fp );
void LoadFromGzFile( gzFile& fp );
// Friends for serialization // Friends for serialization
friend std::istream& operator>> ( std::istream&, TGLandclass& ); friend std::istream& operator>> ( std::istream&, TGLandclass& );

View file

@ -103,11 +103,39 @@ std::istream& operator >> ( std::istream& in, TGShape& p)
return in; return in;
} }
void TGShape::LoadFromGzFile(gzFile& fp)
{
int i, count;
// First, load the clipmask
clip_mask.LoadFromGzFile( fp );
// Then load superpolys
sgReadInt( fp, &count );
for (i=0; i<count; i++) {
TGSuperPoly sp;
sp.LoadFromGzFile( fp );
sps.push_back( sp );
}
// Then load texparams
sgReadInt( fp, &count );
for (i=0; i<count; i++) {
TGTexParams tp;
tp.LoadFromGzFile( fp );
tps.push_back( tp );
}
// Load the id, area type and textured flag
sgReadUInt( fp, &id );
sgReadInt( fp, (int*)&area );
sgReadInt( fp, (int*)&textured );
}
std::ostream& operator<< ( std::ostream& out, const TGShape& p ) std::ostream& operator<< ( std::ostream& out, const TGShape& p )
{ {
int i, count; int i, count;
TGSuperPoly sp; // TGSuperPoly sp;
TGTexParams tp; // TGTexParams tp;
// First, save the clipmask // First, save the clipmask
out << p.clip_mask; out << p.clip_mask;
@ -133,3 +161,30 @@ std::ostream& operator<< ( std::ostream& out, const TGShape& p )
return out; return out;
} }
void TGShape::SaveToGzFile(gzFile& fp)
{
int i, count;
// First, load the clipmask
clip_mask.SaveToGzFile( fp );
// Then save superpolys
count = sps.size();
sgWriteInt( fp, count );
for (i=0; i<count; i++) {
sps[i].SaveToGzFile( fp );
}
// Then save texparams
count = tps.size();
sgWriteInt( fp, count );
for (i=0; i<count; i++) {
tps[i].SaveToGzFile( fp );
}
// Save the id, area type and textured flag
sgWriteUInt( fp, id );
sgWriteInt( fp, (int)area );
sgWriteInt( fp, (int)textured );
}

View file

@ -33,11 +33,9 @@
#define TG_MAX_AREA_TYPES 128 #define TG_MAX_AREA_TYPES 128
//#include <string> #include <simgear/compiler.h>
//#include <vector> #include <simgear/debug/logstream.hxx>
#include <simgear/io/lowlevel.hxx>
//#include <simgear/compiler.h>
//#include <simgear/debug/logstream.hxx>
#include <Polygon/superpoly.hxx> #include <Polygon/superpoly.hxx>
#include <Polygon/texparams.hxx> #include <Polygon/texparams.hxx>
@ -58,6 +56,8 @@ public:
void SetMask( TGPolygon mask ); void SetMask( TGPolygon mask );
void BuildMask( void ); void BuildMask( void );
void IntersectPolys( void ); void IntersectPolys( void );
void SaveToGzFile( gzFile& fp );
void LoadFromGzFile( gzFile& fp );
// Friends for serialization // Friends for serialization
friend std::istream& operator>> ( std::istream&, TGShape& ); friend std::istream& operator>> ( std::istream&, TGShape& );

View file

@ -46,6 +46,7 @@
#include <simgear/math/SGMath.hxx> #include <simgear/math/SGMath.hxx>
#include <simgear/io/lowlevel.hxx>
//const double fgPoint3_Epsilon = 0.0000001; //const double fgPoint3_Epsilon = 0.0000001;
const double fgPoint3_Epsilon = 0.000001; const double fgPoint3_Epsilon = 0.000001;
@ -173,6 +174,16 @@ inline std::ostream& operator<< ( std::ostream& out, const Point3D& p )
return out; return out;
} }
inline void sgWritePoint3D ( gzFile fd, const Point3D& var ) {
sgWriteDouble ( fd, 3, var.get_n() ) ;
}
inline void sgReadPoint3D ( gzFile fd, Point3D& var ) {
double data[3];
sgReadDouble ( fd, 3, data );
var = Point3D(data[0], data[1], data[2]);
}
/////////////////////////// ///////////////////////////
// //
// Point3D Member functions // Point3D Member functions

View file

@ -3,9 +3,60 @@
#include "tg_nodes.hxx" #include "tg_nodes.hxx"
// compare node's positions (x, then y)
int compare_position(const TGNode& n1, const TGNode& n2)
{
Point3D pos1 = n1.GetPosition();
Point3D pos2 = n2.GetPosition();
if ( pos1.x() == pos2.x() ) {
return ( pos1.y() < pos2.y() );
} else {
return ( pos1.x() < pos2.x() );
}
}
int fuzzy_compare_xposition(const TGNode& n1, const TGNode& n2)
{
Point3D pos1 = n1.GetPosition();
Point3D pos2 = n2.GetPosition();
if ( fabs(pos1.x() - pos2.x()) < FG_PROXIMITY_EPSILON ) {
/* if x coords are within vacinity, then pos1 < pos2 */
return 1;
} else {
return compare_position( n1, n2 );
}
}
void TGNodes::SortNodes( void )
{
std::sort(tg_node_list.begin(), tg_node_list.end(), compare_position);
sorted = true;
}
// Find the index of the specified point (compair to the same // Find the index of the specified point (compair to the same
// tolerance as unique_add(). Returns -1 if not found. // tolerance as unique_add(). Returns -1 if not found.
int TGNodes::find( const Point3D& p ) const { int TGNodes::sorted_find( const Point3D& p ) const {
TGNode node( p );
const_node_list_iterator lb, ub;
// first, find the range to search
ub=lower_bound( tg_node_list.begin(), tg_node_list.end(), node, fuzzy_compare_xposition );
lb=upper_bound( tg_node_list.begin(), tg_node_list.end(), node, fuzzy_compare_xposition );
// then do a normal linear search in the range
if ( lb != tg_node_list.end() ) {
for ( ; lb != ub; ++lb ) {
if ( close_enough_2d(p, lb->GetPosition()) ) {
return std::distance( tg_node_list.begin(), lb );
}
}
}
return -1;
}
int TGNodes::linear_find( const Point3D& p ) const {
const_node_list_iterator current, last; const_node_list_iterator current, last;
Point3D pos; Point3D pos;
int counter = 0; int counter = 0;
@ -25,9 +76,45 @@ int TGNodes::find( const Point3D& p ) const {
return -1; return -1;
} }
int TGNodes::unique_add( const Point3D& p ) { #if 0
void TGNodes::sorted_unique_add( const Point3D& p ) {
# if 0
TGNode node( p );
node.SetFixedPosition( false );
node_list_iterator idx = std::lower_bound( tg_node_list.begin(), tg_node_list.end(), node, compare_position );
tg_node_list.insert( idx, node );
#else
TGNode node( p );
node.SetFixedPosition( false );
node_list_iterator lb, ub, idx;
// first, find the range to search
ub=lower_bound( tg_node_list.begin(), tg_node_list.end(), node, fuzzy_compare_xposition );
lb=upper_bound( tg_node_list.begin(), tg_node_list.end(), node, fuzzy_compare_xposition );
// then do a normal linear search in the range
if ( lb != tg_node_list.end() ) {
for ( ; lb != ub; ++lb ) {
if ( close_enough_2d(p, lb->GetPosition()) ) {
// return std::distance( tg_node_list.begin(), lb );
return;
}
}
}
// we didn't find an existing node - insert new one in correct order
idx = std::lower_bound( lb, ub, node, compare_position );
tg_node_list.insert( idx, node );
// return std::distance( tg_node_list.begin(), idx );
#endif
}
#endif
void TGNodes::linear_unique_add( const Point3D& p ) {
node_list_iterator current, last; node_list_iterator current, last;
int counter = 0;
// see if point already exists // see if point already exists
current = tg_node_list.begin(); current = tg_node_list.begin();
@ -35,11 +122,9 @@ int TGNodes::unique_add( const Point3D& p ) {
for ( ; current != last; ++current ) { for ( ; current != last; ++current ) {
if ( close_enough_2d(p, (*current).GetPosition() ) ) { if ( close_enough_2d(p, (*current).GetPosition() ) ) {
// cout << "found an existing match!" << endl; return;
return counter;
} }
++counter;
} }
TGNode node( p ); TGNode node( p );
@ -47,13 +132,59 @@ int TGNodes::unique_add( const Point3D& p ) {
// add to list // add to list
tg_node_list.push_back( node ); tg_node_list.push_back( node );
return counter;
} }
int TGNodes::unique_add_fixed_elevation( const Point3D& p ) { #if 0
void TGNodes::sorted_unique_add_fixed_elevation( const Point3D& p ) {
# if 0
TGNode node( p );
node.SetFixedPosition(true);
node_list_iterator idx = std::lower_bound( tg_node_list.begin(), tg_node_list.end(), node, compare_position );
if ( idx != tg_node_list.end() ) {
if ( close_enough_2d( p, idx->GetPosition() ) ) {
SG_LOG(SG_GENERAL, SG_ALERT, "AddFixedLocation: node " << p << " exists at " << std::distance(tg_node_list.begin(), idx) );
idx->SetPosition( p );
idx->SetFixedPosition( true );
} else {
tg_node_list.insert( idx, node );
}
}
#else
TGNode node( p );
node.SetFixedPosition(true);
node_list_iterator lb, ub, idx;
// first, find the range to search
ub=lower_bound( tg_node_list.begin(), tg_node_list.end(), node, fuzzy_compare_xposition );
lb=upper_bound( tg_node_list.begin(), tg_node_list.end(), node, fuzzy_compare_xposition );
// then do a normal linear search in the range
if ( lb != tg_node_list.end() ) {
for ( ; lb != ub; ++lb ) {
if ( close_enough_2d(p, lb->GetPosition()) ) {
lb->SetPosition( p );
lb->SetFixedPosition( true );
// return std::distance( tg_node_list.begin(), lb );
return;
}
}
}
// we didn't find an existing node - insert new one in correct order
idx = std::lower_bound( lb, ub, node, compare_position );
tg_node_list.insert( idx, node );
// return std::distance( tg_node_list.begin(), idx );
#endif
}
#endif
void TGNodes::linear_unique_add_fixed_elevation( const Point3D& p ) {
node_list_iterator current, last; node_list_iterator current, last;
int counter = 0;
// see if point already exists // see if point already exists
current = tg_node_list.begin(); current = tg_node_list.begin();
@ -61,16 +192,14 @@ int TGNodes::unique_add_fixed_elevation( const Point3D& p ) {
for ( ; current != last; ++current ) { for ( ; current != last; ++current ) {
if ( close_enough_2d(p, (*current).GetPosition() ) ) { if ( close_enough_2d(p, (*current).GetPosition() ) ) {
SG_LOG(SG_GENERAL, SG_ALERT, "Adding fixed elev node : node already exists at " << counter << " old position is " << (*current).GetPosition() << " new position is " << p );
// Force the match to our position, and mark as fixed // Force the match to our position, and mark as fixed
(*current).SetPosition( p ); (*current).SetPosition( p );
(*current).SetFixedPosition( true ); (*current).SetFixedPosition( true );
return counter; return;
} }
++counter;
} }
TGNode node( p ); TGNode node( p );
@ -79,7 +208,6 @@ int TGNodes::unique_add_fixed_elevation( const Point3D& p ) {
// add to list // add to list
tg_node_list.push_back( node ); tg_node_list.push_back( node );
return counter;
} }
point_list TGNodes::get_geod_nodes( void ) const { point_list TGNodes::get_geod_nodes( void ) const {
@ -97,6 +225,9 @@ point_list TGNodes::get_geod_nodes( void ) const {
return points; return points;
} }
// TODO: if the list is sorted, we should be able to get the range from x=min to x=max,
// then within that range, add each point where y is within ymin, max
// still linear search, but should be less points
point_list TGNodes::get_geod_inside( Point3D min, Point3D max ) const { point_list TGNodes::get_geod_inside( Point3D min, Point3D max ) const {
point_list points; point_list points;
const_node_list_iterator current, last; const_node_list_iterator current, last;
@ -260,6 +391,30 @@ std::istream& operator >> ( std::istream& in, TGNode& n )
return in; return in;
} }
void TGNode::LoadFromGzFile(gzFile& fp)
{
int i, nCount;
// Load a tgnode
sgReadPoint3D( fp, position);
CalcWgs84();
sgReadPoint3D( fp, normal );
sgReadInt( fp, (int*)&fixed_position );
sgReadInt( fp, (int*)&fixed_normal );
sgReadInt( fp, &nCount );
for (i=0; i<nCount; i++) {
TGFaceLookup face;
sgReadUInt( fp, &face.area );
sgReadUInt( fp, &face.shape );
sgReadUInt( fp, &face.seg );
sgReadUInt( fp, &face.tri );
faces.push_back( face );
}
}
std::ostream& operator<< ( std::ostream& out, const TGNode& n ) std::ostream& operator<< ( std::ostream& out, const TGNode& n )
{ {
int i, nCount; int i, nCount;
@ -282,11 +437,33 @@ std::ostream& operator<< ( std::ostream& out, const TGNode& n )
return out; return out;
} }
void TGNode::SaveToGzFile(gzFile& fp)
{
int i, nCount;
// Save a tgnode
sgWritePoint3D( fp, position );
sgWritePoint3D( fp, normal );
sgWriteInt( fp, (int)fixed_position );
sgWriteInt( fp, (int)fixed_normal );
nCount = faces.size();
sgWriteInt( fp, nCount );
for (i=0; i<nCount; i++) {
sgWriteUInt( fp, faces[i].area );
sgWriteUInt( fp, faces[i].shape );
sgWriteUInt( fp, faces[i].seg );
sgWriteUInt( fp, faces[i].tri );
}
}
// input from stream // input from stream
std::istream& operator >> ( std::istream& in, TGNodes& ns ) std::istream& operator >> ( std::istream& in, TGNodes& ns )
{ {
int i, nCount; int i, nCount;
// Load sorted flag
in >> ns.sorted;
// Load all tgnodes // Load all tgnodes
in >> nCount; in >> nCount;
@ -300,10 +477,30 @@ std::istream& operator >> ( std::istream& in, TGNodes& ns )
return in; return in;
} }
void TGNodes::LoadFromGzFile(gzFile& fp)
{
int i, nCount;
// Load sorted flag
sgReadInt( fp, (int*)&sorted );
// Load all tgnodes
sgReadInt( fp, &nCount );
for (i=0; i<nCount; i++) {
TGNode node;
node.LoadFromGzFile( fp );
tg_node_list.push_back( node );
}
}
std::ostream& operator<< ( std::ostream& out, const TGNodes& ns ) std::ostream& operator<< ( std::ostream& out, const TGNodes& ns )
{ {
int i, nCount; int i, nCount;
// Save sorted flag
out << ns.sorted << "\n";
// Save all tgnodes // Save all tgnodes
nCount = ns.tg_node_list.size(); nCount = ns.tg_node_list.size();
out << nCount << "\n"; out << nCount << "\n";
@ -315,6 +512,21 @@ std::ostream& operator<< ( std::ostream& out, const TGNodes& ns )
return out; return out;
} }
void TGNodes::SaveToGzFile(gzFile& fp)
{
int i, nCount;
// Save sorted flag
sgWriteInt( fp, (int)sorted );
// Save all tgnodes
nCount = tg_node_list.size();
sgWriteInt( fp, nCount );
for (i=0; i<nCount; i++) {
tg_node_list[i].SaveToGzFile( fp );
}
}
#if 0 #if 0
bool TGNodes::LookupFixedElevation( Point3D p, double* z ) bool TGNodes::LookupFixedElevation( Point3D p, double* z )

View file

@ -1,15 +1,21 @@
#ifndef _TG_NODES_HXX #ifndef _TG_NODES_HXX
#define _TG_NODES_HXX #define _TG_NODES_HXX
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#ifndef __cplusplus #ifndef __cplusplus
# error This library requires C++ # error This library requires C++
#endif #endif
#include <cstdlib>
#include <simgear/compiler.h> #include <simgear/compiler.h>
#include <simgear/bucket/newbucket.hxx> #include <simgear/bucket/newbucket.hxx>
#include <Geometry/point3d.hxx>
#include <simgear/math/sg_types.hxx> #include <simgear/math/sg_types.hxx>
#include <simgear/io/lowlevel.hxx>
#include <Geometry/point3d.hxx>
#define FG_PROXIMITY_EPSILON 0.000001 #define FG_PROXIMITY_EPSILON 0.000001
#define FG_COURSE_EPSILON 0.0001 #define FG_COURSE_EPSILON 0.0001
@ -93,6 +99,8 @@ public:
inline void SetNormal( const Point3D& n ) { normal = n; } inline void SetNormal( const Point3D& n ) { normal = n; }
inline Point3D GetNormal( void ) const { return normal; } inline Point3D GetNormal( void ) const { return normal; }
void SaveToGzFile( gzFile& fp );
void LoadFromGzFile( gzFile& fp );
// Friends for serialization // Friends for serialization
friend std::istream& operator>> ( std::istream&, TGNode& ); friend std::istream& operator>> ( std::istream&, TGNode& );
friend std::ostream& operator<< ( std::ostream&, const TGNode& ); friend std::ostream& operator<< ( std::ostream&, const TGNode& );
@ -118,35 +126,53 @@ class TGNodes {
public: public:
// Constructor and destructor // Constructor and destructor
TGNodes( void ) {} TGNodes( void ) {
sorted = false;
}
~TGNodes( void ) {} ~TGNodes( void ) {}
// delete all the data out of node_list // delete all the data out of node_list
inline void clear() { tg_node_list.clear(); } inline void clear() {
tg_node_list.clear();
sorted = false;
}
// Add a point to the point list if it doesn't already exist. // Add a point to the point list if it doesn't already exist.
// Returns the index (starting at zero) of the point in the list. // Returns the index (starting at zero) of the point in the list.
int unique_add( const Point3D& p ); void unique_add( const Point3D& p ) {
if ( !sorted ) {
linear_unique_add( p );
} else {
SG_LOG(SG_GENERAL, SG_ALERT, "ADDING NODE AFTER SORT!");
exit(0);
}
}
// Add a point to the point list if it doesn't already exist // Add a point to the point list if it doesn't already exist
// (checking all three dimensions.) Returns the index (starting // (checking all three dimensions.) Returns the index (starting
// at zero) of the point in the list. // at zero) of the point in the list.
int unique_add_fixed_elevation( const Point3D& p ); void unique_add_fixed_elevation( const Point3D& p ) {
node_list get_fixed_elevation_nodes( void ) const; if ( !sorted ) {
linear_unique_add_fixed_elevation( p );
// Add the point with no uniqueness checking } else {
int simple_add( const Point3D& p ); SG_LOG(SG_GENERAL, SG_ALERT, "ADDING NODE AFTER SORT!");
exit(0);
// Add a point to the point list if it doesn't already exist. }
// Returns the index (starting at zero) of the point in the list. }
// Use a course proximity check
int course_add( const Point3D& p );
// Find the index of the specified point (compair to the same // Find the index of the specified point (compair to the same
// tolerance as unique_add(). Returns -1 if not found. // tolerance as unique_add(). Returns -1 if not found.
int find( const Point3D& p ) const; int find( const Point3D& p ) const {
if ( sorted ) {
return sorted_find( p );
} else {
return linear_find( p );
}
}
// bool LookupFixedElevation( Point3D p, double* z ); node_list get_fixed_elevation_nodes( void ) const;
void SortNodes( void );
void SetElevation( int idx, double z ) { tg_node_list[idx].SetElevation( z ); } void SetElevation( int idx, double z ) { tg_node_list[idx].SetElevation( z ); }
Point3D GetNormal( int idx ) const { return tg_node_list[idx].GetNormal(); } Point3D GetNormal( int idx ) const { return tg_node_list[idx].GetNormal(); }
@ -184,13 +210,21 @@ public:
inline size_t size() const { return tg_node_list.size(); } inline size_t size() const { return tg_node_list.size(); }
void Dump( void ); void Dump( void );
void SaveToGzFile( gzFile& fp );
void LoadFromGzFile( gzFile& fp );
// Friends for serialization // Friends for serialization
friend std::istream& operator>> ( std::istream&, TGNodes& ); friend std::istream& operator>> ( std::istream&, TGNodes& );
friend std::ostream& operator<< ( std::ostream&, const TGNodes& ); friend std::ostream& operator<< ( std::ostream&, const TGNodes& );
private: private:
void linear_unique_add( const Point3D& p );
void linear_unique_add_fixed_elevation( const Point3D& p );
int sorted_find( const Point3D& p ) const;
int linear_find( const Point3D& p ) const;
node_list tg_node_list; node_list tg_node_list;
bool sorted;
// return true of the two points are "close enough" as defined by // return true of the two points are "close enough" as defined by
// FG_PROXIMITY_EPSILON // FG_PROXIMITY_EPSILON

View file

@ -960,10 +960,30 @@ std::ostream& operator << (std::ostream &output, const TGPolygon &poly)
return output; return output;
} }
void TGPolygon::SaveToGzFile(gzFile& fp)
{
int nContours = poly.size();
// Save the number of contours
sgWriteInt( fp, nContours );
for (int i = 0; i < nContours; i++) {
int nPoints = poly[i].size();
// Save number of points in the contour
sgWriteInt( fp, nPoints );
// Then save the points
for ( int j = 0; j < nPoints; j++ ) {
sgWritePoint3D( fp, poly[i][j] );
}
sgWriteInt( fp, hole_list[i] );
}
}
// Read a polygon from input buffer. // Read a polygon from input buffer.
std::istream& operator >> (std::istream &input, TGPolygon &poly) std::istream& operator >> (std::istream &input, TGPolygon &poly)
{ {
int nContours = poly.contours(); int nContours;
double x, y, z; double x, y, z;
// Read the number of contours // Read the number of contours
@ -991,3 +1011,26 @@ std::istream& operator >> (std::istream &input, TGPolygon &poly)
return input; return input;
} }
void TGPolygon::LoadFromGzFile(gzFile& fp)
{
int nContours;
int nPoints;
int hole;
Point3D pt;
// Save the number of contours
sgReadInt( fp, &nContours );
for (int i = 0; i < nContours; i++) {
sgReadInt( fp, &nPoints );
// Then read the points
for ( int j = 0; j < nPoints; j++ ) {
sgReadPoint3D( fp, pt );
add_node( i, pt );
}
sgReadInt( fp, &hole );
set_hole_flag( i, hole );
}
}

View file

@ -206,6 +206,9 @@ public:
// output // output
void write_contour( const int contour, const std::string& file ) const; void write_contour( const int contour, const std::string& file ) const;
void SaveToGzFile( gzFile& fp );
void LoadFromGzFile( gzFile& fp );
// Friends for serialization // Friends for serialization
friend std::istream& operator>> ( std::istream&, TGPolygon& ); friend std::istream& operator>> ( std::istream&, TGPolygon& );
friend std::ostream& operator<< ( std::ostream&, const TGPolygon& ); friend std::ostream& operator<< ( std::ostream&, const TGPolygon& );

View file

@ -81,10 +81,39 @@ std::ostream& operator<< ( std::ostream& output, const TGSuperPoly& sp )
} else { } else {
output << sp.flag << "\n"; output << sp.flag << "\n";
} }
return output; return output;
} }
void TGSuperPoly::SaveToGzFile(gzFile& fp)
{
int nFaceNormals;
int nFaceAreas;
// Save the data
sgWriteString( fp, material.c_str() );
poly.SaveToGzFile( fp );
normals.SaveToGzFile( fp );
texcoords.SaveToGzFile( fp );
tris.SaveToGzFile( fp );
tri_idxs.SaveToGzFile( fp );
nFaceNormals = face_normals.size();
sgWriteInt( fp, nFaceNormals );
for ( int i = 0; i < nFaceNormals; i++ ) {
sgWritePoint3D( fp, face_normals[i] );
}
nFaceAreas = face_areas.size();
sgWriteInt( fp, nFaceAreas );
for ( int i = 0; i < nFaceAreas; i++ ) {
sgWriteDouble( fp, face_areas[i] );
}
sgWriteString( fp, flag.c_str() );
}
std::istream& operator>> ( std::istream& input, TGSuperPoly& sp ) std::istream& operator>> ( std::istream& input, TGSuperPoly& sp )
{ {
int nFaceNormals; int nFaceNormals;
@ -117,6 +146,47 @@ std::istream& operator>> ( std::istream& input, TGSuperPoly& sp )
return input; return input;
} }
void TGSuperPoly::LoadFromGzFile(gzFile& fp)
{
int nFaceNormals;
int nFaceAreas;
Point3D normal;
double area;
char* strbuf;
// Load the data
sgReadString( fp, &strbuf );
if ( strbuf ) {
material = strbuf;
delete strbuf;
}
poly.LoadFromGzFile( fp );
normals.LoadFromGzFile( fp );
texcoords.LoadFromGzFile( fp );
tris.LoadFromGzFile( fp );
tri_idxs.LoadFromGzFile( fp );
sgReadInt( fp, &nFaceNormals );
for ( int i = 0; i < nFaceNormals; i++ ) {
sgReadPoint3D( fp, normal );
face_normals.push_back( normal );
}
sgReadInt( fp, &nFaceAreas );
for ( int i = 0; i < nFaceAreas; i++ ) {
sgReadDouble( fp, &area );
face_areas.push_back( area );
}
sgReadString( fp, &strbuf );
if ( strbuf ) {
flag = strbuf;
delete strbuf;
}
}
std::ostream& operator<< ( std::ostream& output, const TGPolyNodes& pn ) std::ostream& operator<< ( std::ostream& output, const TGPolyNodes& pn )
{ {
int nContours; int nContours;
@ -137,6 +207,22 @@ std::ostream& operator<< ( std::ostream& output, const TGPolyNodes& pn )
return output; return output;
} }
void TGPolyNodes::SaveToGzFile(gzFile& fp)
{
int nContours;
int nPoints;
// Save the data
nContours = poly.size();
sgWriteInt( fp, nContours );
for(int i=0; i<nContours; i++) {
nPoints = poly[i].size();
sgWriteInt( fp, nPoints );
for (int j=0; j<nPoints; j++) {
sgWriteInt( fp, poly[i][j] );
}
}
}
std::istream& operator>> ( std::istream& input, TGPolyNodes& pn ) std::istream& operator>> ( std::istream& input, TGPolyNodes& pn )
{ {
@ -158,4 +244,24 @@ std::istream& operator>> ( std::istream& input, TGPolyNodes& pn )
} }
return input; return input;
}
void TGPolyNodes::LoadFromGzFile(gzFile& fp)
{
int nContours;
int nPoints;
int point;
// Load the data
sgReadInt( fp, &nContours );
for( int i=0; i<nContours; i++ ) {
int_list points;
sgReadInt( fp, &nPoints );
for (int j=0; j<nPoints; j++) {
sgReadInt( fp, &point );
points.push_back( point );
}
poly.push_back( points );
}
} }

View file

@ -120,6 +120,9 @@ public:
poly[contour][i] = n; poly[contour][i] = n;
} }
void SaveToGzFile( gzFile& fp );
void LoadFromGzFile( gzFile& fp );
// Friends for serialization // Friends for serialization
friend std::istream& operator>> ( std::istream&, TGPolyNodes& ); friend std::istream& operator>> ( std::istream&, TGPolyNodes& );
friend std::ostream& operator<< ( std::ostream&, const TGPolyNodes& ); friend std::ostream& operator<< ( std::ostream&, const TGPolyNodes& );
@ -244,6 +247,9 @@ public:
// erase the polygon // erase the polygon
void erase(); void erase();
void SaveToGzFile( gzFile& fp );
void LoadFromGzFile( gzFile& fp );
// Friends for serialization // Friends for serialization
friend std::istream& operator>> ( std::istream&, TGSuperPoly& ); friend std::istream& operator>> ( std::istream&, TGSuperPoly& );
friend std::ostream& operator<< ( std::ostream&, const TGSuperPoly& ); friend std::ostream& operator<< ( std::ostream&, const TGSuperPoly& );

View file

@ -17,6 +17,19 @@ std::ostream& operator << (std::ostream &output, const TGTexParams &tp)
return output; return output;
} }
void TGTexParams::SaveToGzFile(gzFile& fp)
{
sgWritePoint3D( fp, ref );
sgWriteDouble( fp, width );
sgWriteDouble( fp, length );
sgWriteDouble( fp, heading );
sgWriteDouble( fp, minu );
sgWriteDouble( fp, maxu );
sgWriteDouble( fp, minv );
sgWriteDouble( fp, maxv );
}
// Read a polygon from input buffer. // Read a polygon from input buffer.
std::istream& operator >> (std::istream &input, TGTexParams &tp) std::istream& operator >> (std::istream &input, TGTexParams &tp)
{ {
@ -32,4 +45,17 @@ std::istream& operator >> (std::istream &input, TGTexParams &tp)
input >> tp.maxv; input >> tp.maxv;
return input; return input;
} }
void TGTexParams::LoadFromGzFile(gzFile& fp)
{
sgReadPoint3D( fp, ref );
sgReadDouble( fp, &width );
sgReadDouble( fp, &length );
sgReadDouble( fp, &heading );
sgReadDouble( fp, &minu );
sgReadDouble( fp, &maxu );
sgReadDouble( fp, &minv );
sgReadDouble( fp, &maxv );
}

View file

@ -144,6 +144,9 @@ public:
maxv = x; maxv = x;
} }
void SaveToGzFile( gzFile& fp );
void LoadFromGzFile( gzFile& fp );
// Friends for serialization // Friends for serialization
friend std::istream& operator>> ( std::istream&, TGTexParams& ); friend std::istream& operator>> ( std::istream&, TGTexParams& );
friend std::ostream& operator<< ( std::ostream&, const TGTexParams& ); friend std::ostream& operator<< ( std::ostream&, const TGTexParams& );