1
0
Fork 0

handle multiple tile construction in a single fgfs-construct run

This commit is contained in:
Peter Sadrozinski 2012-07-20 22:30:48 -04:00 committed by Christian Schmitt
parent aa3abbe418
commit 22a8d28857
4 changed files with 156 additions and 164 deletions

View file

@ -506,22 +506,7 @@ void Airport::merge_slivers( superpoly_list& polys, poly_list& slivers_list ) {
SG_LOG(SG_GENERAL, SG_DEBUG, " FOUND a poly to merge the sliver with"); SG_LOG(SG_GENERAL, SG_DEBUG, " FOUND a poly to merge the sliver with");
polys[k].set_poly( result ); polys[k].set_poly( result );
done = true; done = true;
}
// poly.write("orig");
// sliver.write("sliver");
// result.write("result");
// cout << "press return: ";
// string input;
// cin >> input;
} else {
// cout << " poly not a match" << endl;
// cout << " original = " << original_contours
// << " result = " << result_contours << endl;
// cout << " sliver = " << endl;
// for ( k = 0; k < (int)contour.size(); ++k ) {
// cout << " " << contour[k].x() << ", "
// << contour[k].y() << endl;
}
} }
if ( !done ) { if ( !done ) {

View file

@ -80,6 +80,8 @@ bool TGConstruct::load_array() {
string base = bucket.gen_base_path(); string base = bucket.gen_base_path();
int i; int i;
SG_LOG(SG_GENERAL, SG_ALERT, "load array");
for ( i = 0; i < (int)load_dirs.size(); ++i ) { for ( i = 0; i < (int)load_dirs.size(); ++i ) {
string array_path = get_work_base() + "/" + load_dirs[i] + "/" + base + "/" + bucket.gen_index_str(); string array_path = get_work_base() + "/" + load_dirs[i] + "/" + base + "/" + bucket.gen_index_str();
@ -90,6 +92,9 @@ bool TGConstruct::load_array() {
} }
} }
SG_LOG(SG_GENERAL, SG_ALERT, "parse array");
array.parse( bucket ); array.parse( bucket );
array.remove_voids( ); array.remove_voids( );
@ -574,7 +579,7 @@ void TGConstruct::add_intermediate_nodes( ) {
after = current.total_size(); after = current.total_size();
if (before != after) { if (before != after) {
SG_LOG( SG_CLIPPER, SG_INFO, "Fixed t-junctions in " << get_area_name( (AreaType)i ) << ": " << j+1 << " of " << (int)polys_clipped.superpolys[i].size() << " nodes increased from " << before << " to " << after ); SG_LOG( SG_CLIPPER, SG_INFO, "Fixed t-juntions in " << get_area_name( (AreaType)i ) << ":" << j << " of " << (int)polys_clipped.superpolys[i].size() << " nodes increased from " << before << " to " << after );
} }
/* Save it back */ /* Save it back */
@ -625,7 +630,6 @@ void TGConstruct::fix_point_heights()
} }
} }
#if 0
// now flatten some stuuf // now flatten some stuuf
for (int i = 0; i < TG_MAX_AREA_TYPES; i++) { for (int i = 0; i < TG_MAX_AREA_TYPES; i++) {
if ( is_lake_area( (AreaType)i ) ) { if ( is_lake_area( (AreaType)i ) ) {
@ -747,9 +751,9 @@ void TGConstruct::fix_point_heights()
double max2 = d2 * 0.30 + min; double max2 = d2 * 0.30 + min;
double max3 = d3 * 0.30 + min; double max3 = d3 * 0.30 + min;
if ( max1 < e1 ) { get_nodes()->SetElevation( n1, max1 ); } if ( max1 < e1 ) { nodes.SetElevation( n1, max1 ); }
if ( max2 < e2 ) { get_nodes()->SetElevation( n2, max2 ); } if ( max2 < e2 ) { nodes.SetElevation( n2, max2 ); }
if ( max3 < e3 ) { get_nodes()->SetElevation( n3, max3 ); } if ( max3 < e3 ) { nodes.SetElevation( n3, max3 ); }
} }
} }
} }
@ -780,7 +784,6 @@ void TGConstruct::fix_point_heights()
} }
} }
} }
#endif
} }
TGPolygon TGConstruct::area_tex_coords( const TGPolygon& tri ) TGPolygon TGConstruct::area_tex_coords( const TGPolygon& tri )
@ -945,12 +948,12 @@ void TGConstruct::do_custom_objects( ) {
index.append( bucket.gen_index_str() ); index.append( bucket.gen_index_str() );
index.concat(".ind"); index.concat(".ind");
string index_file = index.str_native(); string index_file = index.str_native();
//SG_LOG(SG_GENERAL, SG_ALERT, "Collecting custom objects from " << index_file); SG_LOG(SG_GENERAL, SG_ALERT, "collecting custom objects from " << index_file);
sg_gzifstream in( index_file ); sg_gzifstream in( index_file );
if ( ! in.is_open() ) { if ( ! in.is_open() ) {
//SG_LOG(SG_GENERAL, SG_ALERT, "No custom objects"); //cout << "No custom objects" << endl;
} else { } else {
while ( ! in.eof() ) { while ( ! in.eof() ) {
SG_LOG( SG_GENERAL, SG_INFO, "Collecting custom objects from " << index_file ); SG_LOG( SG_GENERAL, SG_INFO, "Collecting custom objects from " << index_file );
@ -987,105 +990,66 @@ void TGConstruct::do_custom_objects( ) {
fclose(fp); fclose(fp);
} }
// Move slivers from in polygon to out polygon.
void TGConstruct::move_slivers( TGPolygon& in, TGPolygon& out ) {
// traverse each contour of the polygon and attempt to identify
// likely slivers
int i;
out.erase();
double angle_cutoff = 10.0 * SGD_DEGREES_TO_RADIANS;
double area_cutoff = 0.00000008;
double min_angle;
double area;
point_list contour;
int hole_flag;
// process contours in reverse order so deleting a contour doesn't
// foul up our sequence
for ( i = in.contours() - 1; i >= 0; --i ) {
min_angle = in.minangle_contour( i );
area = in.area_contour( i );
if ( ((min_angle < angle_cutoff) && (area < area_cutoff)) ||
( area < area_cutoff / 10.0) ) {
// cout << " WE THINK IT'S A SLIVER!" << endl;
// check if this is a hole
hole_flag = in.get_hole_flag( i );
if ( hole_flag ) {
// just delete/eliminate/remove sliver holes
// cout << "just deleting a sliver hole" << endl;
in.delete_contour( i );
} else {
// move sliver contour to out polygon
contour = in.get_contour( i );
in.delete_contour( i );
out.add_contour( contour, hole_flag );
}
}
}
}
// Attempt to merge slivers into a list of polygons. // Attempt to merge slivers into a list of polygons.
// //
// For each sliver contour, see if a union with another polygon yields // For each sliver contour, see if a union with another polygon yields
// a polygon with no increased contours (i.e. the sliver is adjacent // a polygon with no increased contours (i.e. the sliver is adjacent
// and can be merged.) If so, replace the clipped polygon with the // and can be merged.) If so, replace the clipped polygon with the
// new polygon that has the sliver merged in. // new polygon that has the sliver merged in.
void TGConstruct::merge_slivers( TGPolyList& clipped, TGPolygon& slivers ) { void TGConstruct::merge_slivers( TGPolyList& clipped, poly_list& slivers_list ) {
TGPolygon poly, result, sliver; TGPolygon poly, result, slivers, sliver;
point_list contour; point_list contour;
int original_contours, result_contours; int original_contours, result_contours;
bool done; bool done;
int area, i, j; int area, i, j, k;
for ( i = 0; i < slivers.contours(); ++i ) { for ( i = 0; i < (int)slivers_list.size(); i++ ) {
// cout << "Merging sliver = " << i << endl; slivers = slivers_list[i];
// make the sliver polygon for ( j = 0; j < slivers.contours(); ++j ) {
contour = slivers.get_contour( i ); // cout << "Merging sliver = " << i << endl;
sliver.erase();
sliver.add_contour( contour, 0 );
done = false;
for ( area = 0; area < TG_MAX_AREA_TYPES && !done; ++area ) { // make the sliver polygon
contour = slivers.get_contour( j );
sliver.erase();
sliver.add_contour( contour, 0 );
done = false;
if ( is_hole_area( area ) ) { for ( area = 0; area < TG_MAX_AREA_TYPES && !done; ++area ) {
// don't merge a non-hole sliver in with a hole if ( is_hole_area( area ) ) {
continue; // don't merge a non-hole sliver in with a hole
} continue;
}
// cout << " testing area = " << area << " with " // cout << " testing area = " << area << " with "
// << clipped.polys[area].size() << " polys" << endl; // << clipped.polys[area].size() << " polys" << endl;
for ( j = 0; j < (int)clipped.superpolys[area].size() && !done; ++j ) { for ( k = 0; k < (int)clipped.superpolys[area].size() && !done; ++k ) {
// cout << " polygon = " << j << endl; // cout << " polygon = " << j << endl;
poly = clipped.superpolys[area][j].get_poly(); poly = clipped.superpolys[area][k].get_poly();
original_contours = poly.contours(); original_contours = poly.contours();
result = tgPolygonUnion( poly, sliver ); result = tgPolygonUnion( poly, sliver );
result_contours = result.contours(); result_contours = result.contours();
if ( original_contours == result_contours ) { if ( original_contours == result_contours ) {
// cout << " FOUND a poly to merge the sliver with" << endl; // cout << " FOUND a poly to merge the sliver with" << endl;
clipped.superpolys[area][j].set_poly( result ); clipped.superpolys[area][k].set_poly( result );
done = true; done = true;
}
} }
} }
}
if ( !done ) { if ( !done ) {
// cout << "no suitable polys found for sliver merge" << endl; // cout << "no suitable polys found for sliver merge" << endl;
}
} }
} }
} }
bool TGConstruct::clip_all(const point2d& min, const point2d& max) { bool TGConstruct::clip_all(const point2d& min, const point2d& max) {
TGPolygon accum, tmp; TGPolygon accum, clipped, tmp;
TGPolygon slivers, remains; TGPolygon remains;
poly_list slivers;
int i, j; int i, j;
Point3D p; Point3D p;
@ -1144,7 +1108,7 @@ bool TGConstruct::clip_all(const point2d& min, const point2d& max) {
for( j = 0; j < (int)polys_in.superpolys[i].size(); ++j ) { for( j = 0; j < (int)polys_in.superpolys[i].size(); ++j ) {
TGPolygon current = polys_in.superpolys[i][j].get_poly(); TGPolygon current = polys_in.superpolys[i][j].get_poly();
SG_LOG( SG_CLIPPER, SG_INFO, "Clipping " << get_area_name( (AreaType)i ) << ": " << j+1 << " of " << (int)polys_in.superpolys[i].size() ); SG_LOG( SG_CLIPPER, SG_INFO, "Clipping " << get_area_name( (AreaType)i ) << ":" << j << " of " << (int)polys_in.superpolys[i].size() );
tmp = current; tmp = current;
@ -1153,66 +1117,43 @@ bool TGConstruct::clip_all(const point2d& min, const point2d& max) {
tmp = tgPolygonInt( tmp, land_mask ); tmp = tgPolygonInt( tmp, land_mask );
} }
// Airport areas are limited to existing land mass and
// never override water.
//
// 9/26/2005 - CLO: We are going to add the ability to
// manually define airport areas when the default area
// isn't sufficient. It is clear that it is impossible to
// auto-generate correct airport areas in all cases. For
// now we default to topologically continuous scenery and
// wait for people to submit manual fixes.
//
// if ( i == AirportArea ) {
// tmp = tgPolygonInt( tmp, land_mask );
// tmp = tgPolygonDiff( tmp, water_mask );
// }
// if a water area, cut out potential islands // if a water area, cut out potential islands
if ( is_water_area( i ) ) { if ( is_water_area( i ) ) {
// clip against island mask // clip against island mask
tmp = tgPolygonDiff( tmp, island_mask ); tmp = tgPolygonDiff( tmp, island_mask );
} }
// clean the poly before operations clipped = tgPolygonDiff( tmp, accum );
// tmp = reduce_degeneracy( tmp );
TGPolygon result_union, result_diff;
if ( accum.contours() == 0 ) {
result_diff = tmp;
result_union = tmp;
} else {
result_diff = tgPolygonDiff( tmp, accum);
result_union = tgPolygonUnion( tmp, accum);
}
// only add to output list if the clip left us with a polygon // only add to output list if the clip left us with a polygon
if ( result_diff.contours() > 0 ) { if ( clipped.contours() > 0 ) {
// move slivers from result_diff polygon to slivers polygon // move slivers from clipped polygon to slivers polygon
move_slivers(result_diff, slivers); tgPolygonFindSlivers( clipped, slivers );
// merge any slivers with previously clipped // // merge any slivers with previously clipped
// neighboring polygons // // neighboring polygons
if ( slivers.contours() > 0 ) { // if ( slivers.contours() > 0 ) {
merge_slivers(polys_clipped, slivers); // merge_slivers(polys_clipped, slivers);
} // }
// add the sliverless result polygon (from after the // add the sliverless result polygon to the clipped polys list
// move_slivers) to the clipped polys list if ( clipped.contours() > 0 ) {
if ( result_diff.contours() > 0 ) {
TGSuperPoly sp; TGSuperPoly sp;
string material = get_area_name( (AreaType)i ); string material = get_area_name( (AreaType)i );
sp.set_material( material ); sp.set_material( material );
sp.set_poly( result_diff ); sp.set_poly( clipped );
polys_clipped.superpolys[i].push_back( sp ); polys_clipped.superpolys[i].push_back( sp );
} }
} }
accum = result_union;
accum = tgPolygonUnion( tmp, accum );
} }
} }
// Now, merge any slivers with clipped polys
merge_slivers(polys_clipped, slivers);
// finally, what ever is left over goes to ocean // finally, what ever is left over goes to ocean
// clip to accum against original base tile // clip to accum against original base tile
@ -1224,14 +1165,14 @@ bool TGConstruct::clip_all(const point2d& min, const point2d& max) {
if ( remains.contours() > 0 ) { if ( remains.contours() > 0 ) {
// cout << "remains contours = " << remains.contours() << endl; // cout << "remains contours = " << remains.contours() << endl;
// move slivers from remains polygon to slivers polygon // move slivers from remains polygon to slivers polygon
move_slivers(remains, slivers); tgPolygonFindSlivers( remains, slivers );
// cout << " After sliver move:" << endl; // cout << " After sliver move:" << endl;
// cout << " remains = " << remains.contours() << endl; // cout << " remains = " << remains.contours() << endl;
// cout << " slivers = " << slivers.contours() << endl; // cout << " slivers = " << slivers.contours() << endl;
// merge any slivers with previously clipped // merge any slivers with previously clipped
// neighboring polygons // neighboring polygons
if ( slivers.contours() > 0 ) { if ( slivers.size() > 0 ) {
merge_slivers(polys_clipped, slivers); merge_slivers(polys_clipped, slivers);
} }
@ -1329,7 +1270,7 @@ void TGConstruct::construct_bucket( SGBucket b ) {
for (int j = 0; j < (int)polys_clipped.superpolys[i].size(); ++j ) { for (int j = 0; j < (int)polys_clipped.superpolys[i].size(); ++j ) {
TGPolygon poly = polys_clipped.superpolys[i][j].get_poly(); TGPolygon poly = polys_clipped.superpolys[i][j].get_poly();
SG_LOG( SG_CLIPPER, SG_INFO, "Collecting nodes for " << get_area_name( (AreaType)i ) << ": " << j+1 << " of " << (int)polys_clipped.superpolys[i].size() ); SG_LOG( SG_CLIPPER, SG_INFO, "Collecting nodes for " << get_area_name( (AreaType)i ) << ":" << j << " of " << (int)polys_clipped.superpolys[i].size() );
for (int k=0; k< poly.contours(); k++) { for (int k=0; k< poly.contours(); k++) {
for (int l = 0; l < poly.contour_size(k); l++) { for (int l = 0; l < poly.contour_size(k); l++) {
@ -1356,7 +1297,7 @@ void TGConstruct::construct_bucket( SGBucket b ) {
for (int j = 0; j < (int)polys_clipped.superpolys[i].size(); ++j ) { for (int j = 0; j < (int)polys_clipped.superpolys[i].size(); ++j ) {
TGPolygon poly = polys_clipped.superpolys[i][j].get_poly(); TGPolygon poly = polys_clipped.superpolys[i][j].get_poly();
SG_LOG( SG_CLIPPER, SG_INFO, "Tesselating " << get_area_name( (AreaType)i ) << ": " << j+1 << " of " << (int)polys_clipped.superpolys[i].size() << " : flag = " << polys_clipped.superpolys[i][j].get_flag()); SG_LOG( SG_CLIPPER, SG_INFO, "Tesselating " << get_area_name( (AreaType)i ) << ":" << j << " of " << (int)polys_clipped.superpolys[i].size() << " : flag = " << polys_clipped.superpolys[i][j].get_flag());
TGPolygon tri = polygon_tesselate_alt_with_extra( poly, extra, false ); TGPolygon tri = polygon_tesselate_alt_with_extra( poly, extra, false );
TGPolygon tc; TGPolygon tc;
@ -1375,6 +1316,7 @@ void TGConstruct::construct_bucket( SGBucket b ) {
} }
} }
#if 1 // I don't think this is necessary - triangulations set to don't add points...
// Add triangulation points // Add triangulation points
for (int i = 0; i < TG_MAX_AREA_TYPES; i++) { for (int i = 0; i < TG_MAX_AREA_TYPES; i++) {
for (int j = 0; j < (int)polys_clipped.superpolys[i].size(); ++j ) { for (int j = 0; j < (int)polys_clipped.superpolys[i].size(); ++j ) {
@ -1387,6 +1329,7 @@ void TGConstruct::construct_bucket( SGBucket b ) {
} }
} }
} }
#endif
// Step 7) Flatten // Step 7) Flatten
fix_point_heights(); fix_point_heights();
@ -1599,11 +1542,21 @@ void TGConstruct::construct_bucket( SGBucket b ) {
do_output( c, output ); do_output( c, output );
#endif #endif
array.close();
// Step 15) Adding custome objects to the .stg file // Step 15) Adding custome objects to the .stg file
// collect custom objects and move to scenery area // collect custom objects and move to scenery area
do_custom_objects(); do_custom_objects();
// Step 16 : clean the data structures
array.close();
// land class polygons
polys_in.clear();
polys_clipped.clear();
// All Nodes
nodes.clear();
face_normals.clear();
} }
void TGConstruct::clean_clipped_polys() { void TGConstruct::clean_clipped_polys() {
@ -1623,4 +1576,3 @@ void TGConstruct::clean_clipped_polys() {
} }
} }
} }

View file

@ -66,6 +66,21 @@ public:
superpoly_list superpolys[TG_MAX_AREA_TYPES]; superpoly_list superpolys[TG_MAX_AREA_TYPES];
texparams_list texparams[TG_MAX_AREA_TYPES]; texparams_list texparams[TG_MAX_AREA_TYPES];
TGPolygon safety_base; TGPolygon safety_base;
void clear(void)
{
int i;
for (i=0; i<TG_MAX_AREA_TYPES; i++) {
superpolys[i].clear();
}
for (i=0; i<TG_MAX_AREA_TYPES; i++) {
texparams[i].clear();
}
safety_base.erase();
}
}; };
class TGConstruct { class TGConstruct {
@ -131,7 +146,7 @@ public:
void add_poly(int area, const TGPolygon &poly, std::string material); void add_poly(int area, const TGPolygon &poly, std::string material);
void move_slivers( TGPolygon& in, TGPolygon& out ); void move_slivers( TGPolygon& in, TGPolygon& out );
void merge_slivers( TGPolyList& clipped, TGPolygon& slivers ); void merge_slivers( TGPolyList& clipped, poly_list& slivers_list );
bool clip_all(const point2d& min, const point2d& max); bool clip_all(const point2d& min, const point2d& max);

View file

@ -528,24 +528,27 @@ int main(int argc, char **argv) {
#endif // end of stuff that crashes Cygwin #endif // end of stuff that crashes Cygwin
// main construction data management class // main construction data management class
TGConstruct c; TGConstruct* c;
c.set_cover( cover );
c.set_work_base( work_dir );
c.set_output_base( output_dir );
c.set_load_dirs( load_dirs );
c.set_useUKGrid( useUKgrid );
c.set_write_shared_edges( writeSharedEdges );
c.set_use_own_shared_edges( useOwnSharedEdges );
c.set_ignore_landmass( ignoreLandmass );
c.set_nudge( nudge );
if (tile_id == -1) { if (tile_id == -1) {
if (xdist == -1 || ydist == -1) { if (xdist == -1 || ydist == -1) {
// construct the tile around the specified location // construct the tile around the specified location
SG_LOG(SG_GENERAL, SG_ALERT, "Building single tile at " << lat << ',' << lon); SG_LOG(SG_GENERAL, SG_ALERT, "Building single tile at " << lat << ',' << lon);
SGBucket b( lon, lat ); SGBucket b( lon, lat );
c.construct_bucket( b );
c = new TGConstruct();
c->set_cover( cover );
c->set_work_base( work_dir );
c->set_output_base( output_dir );
c->set_load_dirs( load_dirs );
c->set_useUKGrid( useUKgrid );
c->set_write_shared_edges( writeSharedEdges );
c->set_use_own_shared_edges( useOwnSharedEdges );
c->set_ignore_landmass( ignoreLandmass );
c->set_nudge( nudge );
c->construct_bucket( b );
delete c;
} else { } else {
// build all the tiles in an area // build all the tiles in an area
SG_LOG(SG_GENERAL, SG_ALERT, "Building tile(s) at " << lat << ',' << lon << " with x distance " << xdist << " and y distance " << ydist); SG_LOG(SG_GENERAL, SG_ALERT, "Building tile(s) at " << lat << ',' << lon << " with x distance " << xdist << " and y distance " << ydist);
@ -558,7 +561,19 @@ int main(int argc, char **argv) {
bool do_tile = true; bool do_tile = true;
if ( b_min == b_max ) { if ( b_min == b_max ) {
c.construct_bucket( b_min ); c = new TGConstruct();
c->set_cover( cover );
c->set_work_base( work_dir );
c->set_output_base( output_dir );
c->set_load_dirs( load_dirs );
c->set_useUKGrid( useUKgrid );
c->set_write_shared_edges( writeSharedEdges );
c->set_use_own_shared_edges( useOwnSharedEdges );
c->set_ignore_landmass( ignoreLandmass );
c->set_nudge( nudge );
c->construct_bucket( b_min );
delete c;
} else { } else {
SGBucket b_cur; SGBucket b_cur;
int dx, dy, i, j; int dx, dy, i, j;
@ -576,7 +591,19 @@ int main(int argc, char **argv) {
} }
if ( do_tile ) { if ( do_tile ) {
c.construct_bucket( b_cur ); c = new TGConstruct();
c->set_cover( cover );
c->set_work_base( work_dir );
c->set_output_base( output_dir );
c->set_load_dirs( load_dirs );
c->set_useUKGrid( useUKgrid );
c->set_write_shared_edges( writeSharedEdges );
c->set_use_own_shared_edges( useOwnSharedEdges );
c->set_ignore_landmass( ignoreLandmass );
c->set_nudge( nudge );
c->construct_bucket( b_cur );
delete c;
} else { } else {
SG_LOG(SG_GENERAL, SG_ALERT, "skipping " << b_cur); SG_LOG(SG_GENERAL, SG_ALERT, "skipping " << b_cur);
} }
@ -588,7 +615,20 @@ int main(int argc, char **argv) {
// construct the specified tile // construct the specified tile
SG_LOG(SG_GENERAL, SG_ALERT, "Building tile " << tile_id); SG_LOG(SG_GENERAL, SG_ALERT, "Building tile " << tile_id);
SGBucket b( tile_id ); SGBucket b( tile_id );
c.construct_bucket( b );
c = new TGConstruct();
c->set_cover( cover );
c->set_work_base( work_dir );
c->set_output_base( output_dir );
c->set_load_dirs( load_dirs );
c->set_useUKGrid( useUKgrid );
c->set_write_shared_edges( writeSharedEdges );
c->set_use_own_shared_edges( useOwnSharedEdges );
c->set_ignore_landmass( ignoreLandmass );
c->set_nudge( nudge );
c->construct_bucket( b );
delete c;
} }
SG_LOG(SG_GENERAL, SG_ALERT, "[Finished successfully]"); SG_LOG(SG_GENERAL, SG_ALERT, "[Finished successfully]");