Stability checkpoint for genapt850
- break up and expand shoulder polys, so they overlap runways. This keeps cracks from forming between the shoulder and runway do to roundoff error - Add verbose option to polygon_tesselate functions to aid in debugging can set at runtime to produce triangulation output for just 1 poly. - add remove_small_cycles to poly cleanup routines before triangulation - more warnings cleanup in ClosePoly.cxx - add more output in normal execution path, as some airports can go for hours without printing any status. Hard to tell if it's locked up
This commit is contained in:
parent
27c31404ca
commit
37a46c4075
17 changed files with 559 additions and 404 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -3,6 +3,7 @@ Makefile.in
|
|||
.deps
|
||||
*.o
|
||||
*.a
|
||||
*~
|
||||
COPYING
|
||||
INSTALL
|
||||
VERSION
|
||||
|
|
|
@ -828,7 +828,7 @@ void build_airport( string airport_id, float alt_m,
|
|||
|
||||
TGPolygon poly = rwy_polys[i].get_poly();
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "total size before = " << poly.total_size());
|
||||
TGPolygon tri = polygon_tesselate_alt( poly );
|
||||
TGPolygon tri = polygon_tesselate_alt( poly, false );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after = " << tri.total_size());
|
||||
|
||||
TGPolygon tc;
|
||||
|
@ -844,7 +844,7 @@ void build_airport( string airport_id, float alt_m,
|
|||
}
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Tesselating base");
|
||||
TGPolygon base_tris = polygon_tesselate_alt( base_poly );
|
||||
TGPolygon base_tris = polygon_tesselate_alt( base_poly, false );
|
||||
|
||||
#if 0
|
||||
// dump more debugging output
|
||||
|
|
|
@ -325,6 +325,8 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
int i, j, k;
|
||||
Point3D p;
|
||||
|
||||
bool verbose_triangulation = false;
|
||||
|
||||
// parse main airport information
|
||||
double apt_lon = 0.0, apt_lat = 0.0;
|
||||
|
||||
|
@ -334,16 +336,24 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
struct timeval cleanup_end;
|
||||
struct timeval triangulation_start;
|
||||
struct timeval triangulation_end;
|
||||
struct timeval log_time;
|
||||
|
||||
// Find the average of all the runway long / lats
|
||||
// TODO : Need runway object...
|
||||
// Find the average of all the runway and heliport long / lats
|
||||
int num_samples = 0;
|
||||
for (i=0; i<runways.size(); i++)
|
||||
{
|
||||
apt_lon += runways.at(i)->GetMidpoint().x();
|
||||
apt_lat += runways.at(i)->GetMidpoint().y();
|
||||
apt_lon += runways[i]->GetMidpoint().x();
|
||||
apt_lat += runways[i]->GetMidpoint().y();
|
||||
num_samples++;
|
||||
}
|
||||
apt_lon = apt_lon / (double)runways.size();
|
||||
apt_lat = apt_lat / (double)runways.size();
|
||||
for (i=0; i<helipads.size(); i++)
|
||||
{
|
||||
apt_lon += helipads[i]->GetLoc().x();
|
||||
apt_lat += helipads[i]->GetLoc().y();
|
||||
num_samples++;
|
||||
}
|
||||
apt_lon = apt_lon / (double)num_samples;
|
||||
apt_lat = apt_lat / (double)num_samples;
|
||||
|
||||
SGBucket b( apt_lon, apt_lat );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, b.gen_base_path() << "/" << b.gen_index_str());
|
||||
|
@ -368,7 +378,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
{
|
||||
for ( i=0; i<features.size(); i++ )
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Build Feature Poly " << i << ": " << features[i]->GetDescription() );
|
||||
SG_LOG(SG_GENERAL, SG_INFO, "Build Feature Poly " << i << " of " << features.size() << " : " << features[i]->GetDescription() );
|
||||
|
||||
// cut the linear feature in until we get the geometry right...
|
||||
// features[i]->BuildBtg( altitude, &line_polys, &line_tps, &line_accum );
|
||||
|
@ -380,9 +390,14 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
SG_LOG(SG_GENERAL, SG_DEBUG, "no markings");
|
||||
}
|
||||
|
||||
gettimeofday(&log_time, NULL);
|
||||
SG_LOG( SG_GENERAL, SG_ALERT, "Finished building Linear Features for " << icao << " at " << ctime(&log_time.tv_sec) );
|
||||
|
||||
// Build runways next
|
||||
for (i=0; i<runways.size(); i++ )
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_INFO, "Build Runway " << i << " of " << runways.size());
|
||||
|
||||
if ( runways[i]->IsPrecision() )
|
||||
{
|
||||
if (boundary)
|
||||
|
@ -393,13 +408,18 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
{
|
||||
runways[i]->BuildBtg( altitude, &rwy_polys, &rwy_tps, &rwy_lights, &accum, &apt_base, &apt_clearing );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gettimeofday(&log_time, NULL);
|
||||
SG_LOG( SG_GENERAL, SG_ALERT, "Finished building runways for " << icao << " at " << ctime(&log_time.tv_sec) );
|
||||
|
||||
if (lightobjects.size())
|
||||
{
|
||||
for ( i=0; i<lightobjects.size(); i++ )
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_INFO, "Build runway light " << i << " of " << lightobjects.size());
|
||||
|
||||
lightobjects[i]->BuildBtg( altitude, &rwy_lights );
|
||||
}
|
||||
}
|
||||
|
@ -407,6 +427,8 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
// Build helipads (use runway poly- and texture list for this)
|
||||
if (helipads.size())
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Build helipad " << i << " of " << helipads.size());
|
||||
|
||||
for (i=0; i<helipads.size(); i++ )
|
||||
{
|
||||
if (boundary)
|
||||
|
@ -419,12 +441,13 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Build the pavements
|
||||
if (pavements.size())
|
||||
{
|
||||
for ( i=0; i<pavements.size(); i++ )
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Build Pavement Poly " << i << ": " << pavements[i]->GetDescription());
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Build Pavement " << i << " of " << pavements.size() << " : " << pavements[i]->GetDescription());
|
||||
|
||||
if (boundary)
|
||||
{
|
||||
|
@ -441,9 +464,14 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
SG_LOG(SG_GENERAL, SG_DEBUG, "no pavements");
|
||||
}
|
||||
|
||||
gettimeofday(&log_time, NULL);
|
||||
SG_LOG( SG_GENERAL, SG_ALERT, "Finished building pavements for " << icao << " at " << ctime(&log_time.tv_sec) );
|
||||
|
||||
// Build runway shoulders here
|
||||
for (i=0; i<runways.size(); i++ )
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Build Runway shoulder " << i << " of " << runways.size());
|
||||
|
||||
if ( runways[i]->GetsShoulder() )
|
||||
{
|
||||
runways[i]->BuildShoulder( altitude, &rwy_polys, &rwy_tps, &accum );
|
||||
|
@ -453,10 +481,12 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
// build the base and clearing if there's a boundary
|
||||
if (boundary)
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Build user defined boundary " );
|
||||
|
||||
boundary->BuildBtg( altitude, &apt_base, &apt_clearing );
|
||||
}
|
||||
|
||||
if ( apt_base.total_size() == 0 )
|
||||
if ( apt_base.total_size() == 0 )
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "no airport points generated");
|
||||
return;
|
||||
|
@ -464,7 +494,6 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
|
||||
TGPolygon filled_base = tgPolygonStripHoles( apt_base );
|
||||
TGPolygon divided_base = tgPolygonSplitLongEdges( filled_base, 200.0 );
|
||||
//TGPolygon base_poly = tgPolygonDiff( filled_base, accum );
|
||||
TGPolygon base_poly = tgPolygonDiff( divided_base, accum );
|
||||
|
||||
gettimeofday(&build_end, NULL);
|
||||
|
@ -477,6 +506,8 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
TGTriNodes tmp_nodes;
|
||||
|
||||
// build temporary node list from runways...
|
||||
SG_LOG(SG_GENERAL, SG_INFO, "Build Node List " );
|
||||
|
||||
for ( k = 0; k < (int)rwy_polys.size(); ++k )
|
||||
{
|
||||
TGPolygon poly = rwy_polys[k].get_poly();
|
||||
|
@ -484,7 +515,8 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
{
|
||||
for ( j = 0; j < poly.contour_size( i ); ++j )
|
||||
{
|
||||
tmp_nodes.unique_add( poly.get_pt(i, j) );
|
||||
tmp_nodes.unique_add( poly.get_pt(i, j) );
|
||||
//tmp_nodes.course_add( poly.get_pt(i, j) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -498,6 +530,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
for ( j = 0; j < poly.contour_size( i ); ++j )
|
||||
{
|
||||
tmp_nodes.unique_add( poly.get_pt(i, j) );
|
||||
//tmp_nodes.course_add( poly.get_pt(i, j) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -511,6 +544,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
for ( j = 0; j < poly.contour_size( i ); ++j )
|
||||
{
|
||||
tmp_nodes.unique_add( poly.get_pt(i, j) );
|
||||
//tmp_nodes.course_add( poly.get_pt(i, j) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -521,6 +555,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
for ( j = 0; j < base_poly.contour_size( i ); ++j )
|
||||
{
|
||||
tmp_nodes.unique_add( base_poly.get_pt(i, j) );
|
||||
//tmp_nodes.course_add( base_poly.get_pt(i, j) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -531,9 +566,13 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
for ( j = 0; j < divided_base.contour_size( i ); ++j )
|
||||
{
|
||||
tmp_nodes.unique_add( divided_base.get_pt(i, j) );
|
||||
//tmp_nodes.course_add( divided_base.get_pt(i, j) );
|
||||
}
|
||||
}
|
||||
|
||||
gettimeofday(&log_time, NULL);
|
||||
SG_LOG( SG_GENERAL, SG_ALERT, "Finished collecting nodes for " << icao << " at " << ctime(&log_time.tv_sec) );
|
||||
|
||||
// second pass : runways
|
||||
for ( k = 0; k < (int)rwy_polys.size(); ++k )
|
||||
{
|
||||
|
@ -564,6 +603,8 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
line_polys[k].set_poly( poly );
|
||||
}
|
||||
|
||||
gettimeofday(&log_time, NULL);
|
||||
SG_LOG( SG_GENERAL, SG_ALERT, "Finished adding intermediate nodes for " << icao << " at " << ctime(&log_time.tv_sec) );
|
||||
|
||||
// One more pass to try to get rid of other yukky stuff
|
||||
for ( k = 0; k < (int)rwy_polys.size(); ++k )
|
||||
|
@ -572,12 +613,10 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "total size of section " << k << " before =" << poly.total_size());
|
||||
|
||||
poly = remove_cycles( poly );
|
||||
poly = remove_dups( poly );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after remove_dups() = " << poly.total_size());
|
||||
poly = remove_bad_contours( poly );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after remove_bad() = " << poly.total_size());
|
||||
poly = remove_tiny_contours( poly );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after remove_tiny_contours() = " << poly.total_size());
|
||||
|
||||
rwy_polys[k].set_poly( poly );
|
||||
}
|
||||
|
@ -588,12 +627,10 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "total size of section " << k << " before =" << poly.total_size());
|
||||
|
||||
poly = remove_cycles( poly );
|
||||
poly = remove_dups( poly );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after remove_dups() = " << poly.total_size());
|
||||
poly = remove_bad_contours( poly );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after remove_bad() = " << poly.total_size());
|
||||
poly = remove_tiny_contours( poly );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after remove_tiny_contours() = " << poly.total_size());
|
||||
|
||||
pvmt_polys[k].set_poly( poly );
|
||||
}
|
||||
|
@ -604,17 +641,16 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "total size of section " << k << " before =" << poly.total_size());
|
||||
|
||||
poly = remove_cycles( poly );
|
||||
poly = remove_dups( poly );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after remove_dups() = " << poly.total_size());
|
||||
poly = remove_bad_contours( poly );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after remove_bad() = " << poly.total_size());
|
||||
poly = remove_tiny_contours( poly );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after remove_tiny_contours() = " << poly.total_size());
|
||||
|
||||
line_polys[k].set_poly( poly );
|
||||
}
|
||||
|
||||
|
||||
gettimeofday(&log_time, NULL);
|
||||
SG_LOG( SG_GENERAL, SG_ALERT, "Finished cleaning poly for " << icao << " at " << ctime(&log_time.tv_sec) );
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "add nodes base ");
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, " before: " << base_poly);
|
||||
|
@ -623,15 +659,10 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
base_poly = add_nodes_to_poly( base_poly, tmp_nodes );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, " after adding tmp_nodes: " << base_poly);
|
||||
|
||||
// write_polygon( base_poly, "base-add" );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "remove dups base ");
|
||||
base_poly = remove_cycles( base_poly );
|
||||
base_poly = remove_dups( base_poly );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "remove bad contours base");
|
||||
base_poly = remove_bad_contours( base_poly );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "remove small contours base");
|
||||
base_poly = remove_tiny_contours( base_poly );
|
||||
// write_polygon( base_poly, "base-fin" );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, " after clean up: " << base_poly);
|
||||
|
||||
gettimeofday(&cleanup_end, NULL);
|
||||
timersub(&cleanup_end, &cleanup_start, &cleanup_time);
|
||||
|
@ -641,11 +672,19 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
// tesselate the polygons and prepair them for final output
|
||||
for ( i = 0; i < (int)rwy_polys.size(); ++i )
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Tesselating section = " << i << " flag = " << rwy_polys[i].get_flag());
|
||||
SG_LOG(SG_GENERAL, SG_INFO, "Tesselating runway poly = " << i << " of " << rwy_polys.size() << " : flag = " << rwy_polys[i].get_flag());
|
||||
|
||||
TGPolygon poly = rwy_polys[i].get_poly();
|
||||
|
||||
#if 0
|
||||
if ( i == 62 ) {
|
||||
tgChopNormalPolygon( "/home/pete", "Base", poly, false );
|
||||
verbose_triangulation = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "contours before " << poly.contours() << " total points before = " << poly.total_size());
|
||||
TGPolygon tri = polygon_tesselate_alt( poly );
|
||||
TGPolygon tri = polygon_tesselate_alt( poly, verbose_triangulation );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after = " << tri.total_size());
|
||||
|
||||
TGPolygon tc;
|
||||
|
@ -658,11 +697,11 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
// tesselate the polygons and prepair them for final output
|
||||
for ( i = 0; i < (int)pvmt_polys.size(); ++i )
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Tesselating section = " << i << " flag = " << pvmt_polys[i].get_flag());
|
||||
SG_LOG(SG_GENERAL, SG_INFO, "Tesselating pavement poly = " << i << " of " << pvmt_polys.size() << " : flag = " << pvmt_polys[i].get_flag());
|
||||
|
||||
TGPolygon poly = pvmt_polys[i].get_poly();
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "contours before " << poly.contours() << " total points before = " << poly.total_size());
|
||||
TGPolygon tri = polygon_tesselate_alt( poly );
|
||||
TGPolygon tri = polygon_tesselate_alt( poly, false );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after = " << tri.total_size());
|
||||
|
||||
TGPolygon tc;
|
||||
|
@ -682,27 +721,30 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
// tesselate the polygons and prepair them for final output
|
||||
for ( i = 0; i < (int)line_polys.size(); ++i )
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Tesselating section = " << i << " flag = " << line_polys[i].get_flag());
|
||||
SG_LOG(SG_GENERAL, SG_INFO, "Tesselating line poly = " << i << " of " << line_polys.size() << " : flag = " << line_polys[i].get_flag());
|
||||
|
||||
TGPolygon poly = line_polys[i].get_poly();
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "contours before " << poly.contours() << " total points before = " << poly.total_size());
|
||||
TGPolygon tri = polygon_tesselate_alt( poly );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after = " << tri.total_size());
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "contours before " << poly.contours() << " total points before = " << poly.total_size());
|
||||
TGPolygon tri = polygon_tesselate_alt( poly, false );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after = " << tri.total_size());
|
||||
|
||||
TGPolygon tc;
|
||||
tc = linear_feature_tex_coords( tri, line_tps[i] );
|
||||
|
||||
line_polys[i].set_tris( tri );
|
||||
line_polys[i].set_texcoords( tc );
|
||||
line_polys[i].set_tris( tri );
|
||||
line_polys[i].set_texcoords( tc );
|
||||
}
|
||||
|
||||
#if 0
|
||||
{
|
||||
string polypath = root + "/AirportArea";
|
||||
tgChopNormalPolygon( polypath, "Base", base_poly, false );
|
||||
}
|
||||
#if 1
|
||||
{
|
||||
tgChopNormalPolygon( "/home/pete", "Base", base_poly, false );
|
||||
verbose_triangulation = true;
|
||||
}
|
||||
#endif
|
||||
TGPolygon base_tris = polygon_tesselate_alt( base_poly );
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_INFO, "Tesselating base poly ");
|
||||
TGPolygon base_tris = polygon_tesselate_alt( base_poly, verbose_triangulation );
|
||||
|
||||
gettimeofday(&triangulation_end, NULL);
|
||||
timersub(&triangulation_end, &triangulation_start, &triangulation_time);
|
||||
|
@ -776,6 +818,8 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
for ( j = 0; j < tri_poly.contour_size(i); ++j )
|
||||
{
|
||||
p = tri_poly.get_pt( i, j );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "adding runway point = " << p);
|
||||
|
||||
index = nodes.unique_add( p );
|
||||
tri_v.push_back( index );
|
||||
|
||||
|
@ -878,6 +922,8 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
for ( j = 0; j < base_tris.contour_size(i); ++j )
|
||||
{
|
||||
p = base_tris.get_pt( i, j );
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "adding base point " << p);
|
||||
index = nodes.unique_add( p );
|
||||
tri_v.push_back( index );
|
||||
|
||||
|
@ -916,6 +962,8 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
{
|
||||
for ( j = 0; j < divided_base.contour_size( i ); ++j )
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "adding divided base point " << p);
|
||||
|
||||
nodes.unique_add( divided_base.get_pt(i, j) );
|
||||
}
|
||||
}
|
||||
|
@ -927,7 +975,22 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
// it avoids biases introduced from the surrounding area if the
|
||||
// airport is located in a bowl or on a hill.
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, " calcaverage elevation");
|
||||
|
||||
{
|
||||
point_list dbg = nodes.get_node_list();
|
||||
|
||||
// dump the node list
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, " node list size is " << dbg.size() );
|
||||
for (unsigned int w = 0; w<dbg.size(); w++)
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, " node " << w << " is " << dbg[w] );
|
||||
}
|
||||
}
|
||||
|
||||
double average = tgAverageElevation( root, elev_src, nodes.get_node_list() );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, " done");
|
||||
|
||||
// cout << "average airport elevation = " << average << endl;
|
||||
|
||||
// Now build the fitted airport surface ...
|
||||
|
|
|
@ -51,7 +51,7 @@ public:
|
|||
|
||||
void AddFeatures( FeatureList* feature_list )
|
||||
{
|
||||
for (int i=0; i<feature_list->size(); i++)
|
||||
for (unsigned int i=0; i<feature_list->size(); i++)
|
||||
{
|
||||
features.push_back( feature_list->at(i) );
|
||||
}
|
||||
|
|
|
@ -172,6 +172,39 @@ TGPolygon gen_wgs84_area( Point3D end1, Point3D end2,
|
|||
return result_list;
|
||||
}
|
||||
|
||||
TGPolygon gen_wgs84_rect( double lat, double lon, double heading, double length, double width )
|
||||
{
|
||||
TGPolygon result_list;
|
||||
double ptlat, ptlon, r;
|
||||
Point3D p;
|
||||
|
||||
// starting point is in the middle of the rectangle width, at the beginning - stretch to heading
|
||||
|
||||
// Point 1 is -90deg, 1/2 width away
|
||||
double left_hdg = heading -90;
|
||||
if ( left_hdg < 0 ) { left_hdg += 360.0; }
|
||||
|
||||
geo_direct_wgs_84 ( 0.0, lat, lon, left_hdg, width / 2.0, &ptlat, &ptlon, &r );
|
||||
p = Point3D( ptlon, ptlat, 0.0 );
|
||||
result_list.add_node( 0, p );
|
||||
|
||||
// Point 2 is heading, length away from point 1
|
||||
geo_direct_wgs_84 ( 0.0, ptlat, ptlon, heading, length, &ptlat, &ptlon, &r );
|
||||
p = Point3D( ptlon, ptlat, 0.0 );
|
||||
result_list.add_node( 0, p );
|
||||
|
||||
// Point 3 is -90deg, -width away from point 2
|
||||
geo_direct_wgs_84 ( 0.0, ptlat, ptlon, left_hdg, -width, &ptlat, &ptlon, &r );
|
||||
p = Point3D( ptlon, ptlat, 0.0 );
|
||||
result_list.add_node( 0, p );
|
||||
|
||||
// last point is heading, -length from point 3
|
||||
geo_direct_wgs_84 ( 0.0, ptlat, ptlon, heading, -length, &ptlat, &ptlon, &r );
|
||||
p = Point3D( ptlon, ptlat, 0.0 );
|
||||
result_list.add_node( 0, p );
|
||||
|
||||
return result_list;
|
||||
}
|
||||
|
||||
// generate a section of texture
|
||||
void gen_tex_section( const TGPolygon& runway,
|
||||
|
|
|
@ -25,6 +25,9 @@ TGPolygon gen_wgs84_area( Point3D end1, Point3D end2,
|
|||
double alt_m,
|
||||
bool add_mid );
|
||||
|
||||
TGPolygon gen_wgs84_rect( double lat, double lon, double heading, double length, double width );
|
||||
|
||||
|
||||
void gen_tex_section( const TGPolygon& runway,
|
||||
double startl_pct, double endl_pct,
|
||||
double startw_pct, double endw_pct,
|
||||
|
|
|
@ -10,6 +10,15 @@
|
|||
#include "convex_hull.hxx"
|
||||
#include "closedpoly.hxx"
|
||||
|
||||
static void stringPurifier( string& s )
|
||||
{
|
||||
for ( string::iterator it = s.begin(), itEnd = s.end(); it!=itEnd; ++it) {
|
||||
if ( static_cast<unsigned int>(*it) < 32 || static_cast<unsigned int>(*it) > 127 ) {
|
||||
(*it) = ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ClosedPoly::ClosedPoly( char* desc )
|
||||
{
|
||||
is_pavement = false;
|
||||
|
@ -17,6 +26,7 @@ ClosedPoly::ClosedPoly( char* desc )
|
|||
if ( desc )
|
||||
{
|
||||
description = desc;
|
||||
stringPurifier(description);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -38,6 +48,7 @@ ClosedPoly::ClosedPoly( int st, float s, float th, char* desc )
|
|||
if ( desc )
|
||||
{
|
||||
description = desc;
|
||||
stringPurifier(description);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -65,7 +76,7 @@ void ClosedPoly::AddNode( BezNode* node )
|
|||
{
|
||||
if (!cur_feature)
|
||||
{
|
||||
string feature_desc = description + ":";
|
||||
string feature_desc = description + " - ";
|
||||
if (boundary)
|
||||
{
|
||||
feature_desc += "hole";
|
||||
|
@ -84,10 +95,10 @@ void ClosedPoly::AddNode( BezNode* node )
|
|||
|
||||
void ClosedPoly::CreateConvexHull( void )
|
||||
{
|
||||
TGPolygon convexHull;
|
||||
point_list nodes;
|
||||
Point3D p;
|
||||
int i;
|
||||
TGPolygon convexHull;
|
||||
point_list nodes;
|
||||
Point3D p;
|
||||
unsigned int i;
|
||||
|
||||
if (boundary->size() > 2)
|
||||
{
|
||||
|
@ -105,7 +116,7 @@ void ClosedPoly::CreateConvexHull( void )
|
|||
}
|
||||
}
|
||||
|
||||
int ClosedPoly::CloseCurContour()
|
||||
void ClosedPoly::CloseCurContour()
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Close Contour");
|
||||
|
||||
|
@ -151,7 +162,7 @@ void ClosedPoly::ConvertContour( BezContour* src, point_list *dst )
|
|||
Point3D cp2;
|
||||
|
||||
int curve_type = CURVE_LINEAR;
|
||||
int i;
|
||||
unsigned int i;
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Creating a contour with " << src->size() << " nodes");
|
||||
|
||||
|
@ -346,7 +357,7 @@ void ClosedPoly::ExpandContour( point_list& src, TGPolygon& dst, double dist )
|
|||
double h1;
|
||||
double o1;
|
||||
double az2;
|
||||
int i;
|
||||
unsigned int i;
|
||||
|
||||
// iterate through each bezier node in the contour
|
||||
for (i=0; i<src.size(); i++)
|
||||
|
@ -427,7 +438,7 @@ void ClosedPoly::ExpandContour( point_list& src, TGPolygon& dst, double dist )
|
|||
}
|
||||
|
||||
// finish the poly - convert to TGPolygon, and tesselate
|
||||
int ClosedPoly::Finish()
|
||||
void ClosedPoly::Finish()
|
||||
{
|
||||
point_list dst_contour;
|
||||
|
||||
|
@ -448,7 +459,7 @@ int ClosedPoly::Finish()
|
|||
pre_tess.add_contour( dst_contour, 0 );
|
||||
|
||||
// The convert the hole contours
|
||||
for (int i=0; i<holes.size(); i++)
|
||||
for (unsigned int i=0; i<holes.size(); i++)
|
||||
{
|
||||
dst_contour.clear();
|
||||
ConvertContour( holes[i], &dst_contour );
|
||||
|
@ -574,4 +585,6 @@ int ClosedPoly::BuildBtg( float alt_m, TGPolygon* apt_base, TGPolygon* apt_clear
|
|||
// and add the clearing to the base
|
||||
*apt_base = tgPolygonUnion( pre_tess, *apt_base );
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -24,8 +24,8 @@ public:
|
|||
|
||||
inline string GetDescription() { return description; }
|
||||
void AddNode( BezNode* node );
|
||||
int CloseCurContour();
|
||||
int Finish();
|
||||
void CloseCurContour();
|
||||
void Finish();
|
||||
|
||||
// Build BTG for airport base for airports with boundary
|
||||
int BuildBtg( float alt_m, TGPolygon* apt_base, TGPolygon* apt_clearing );
|
||||
|
|
|
@ -68,21 +68,23 @@ double tgAverageElevation( const string &root, const string_list elev_src,
|
|||
}
|
||||
|
||||
while ( !done ) {
|
||||
// find first node with -9999 elevation
|
||||
// find first node with -9999 elevation
|
||||
Point3D first(0.0);
|
||||
bool found_one = false;
|
||||
for ( i = 0; i < points.size(); ++i ) {
|
||||
if ( points[i].z() < -9000.0 && !found_one ) {
|
||||
first = points[i];
|
||||
SG_LOG( SG_GENERAL, SG_DEBUG, "founf first = " << first );
|
||||
|
||||
found_one = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( found_one ) {
|
||||
SGBucket b( first.x(), first.y() );
|
||||
string base = b.gen_base_path();
|
||||
if ( found_one ) {
|
||||
SGBucket b( first.x(), first.y() );
|
||||
string base = b.gen_base_path();
|
||||
|
||||
// try the various elevation sources
|
||||
// try the various elevation sources
|
||||
i = 0;
|
||||
bool found_file = false;
|
||||
while ( !found_file && i < elev_src.size() ) {
|
||||
|
@ -98,7 +100,7 @@ double tgAverageElevation( const string &root, const string_list elev_src,
|
|||
|
||||
// this will fill in a zero structure if no array data
|
||||
// found/opened
|
||||
array.parse( b );
|
||||
array.parse( b );
|
||||
|
||||
// this will do a hasty job of removing voids by inserting
|
||||
// data from the nearest neighbor (sort of)
|
||||
|
|
|
@ -125,7 +125,7 @@ int main(int argc, char **argv)
|
|||
setup_default_elevation_sources(elev_src);
|
||||
|
||||
// Set verbose
|
||||
// sglog().setLogLevels( SG_GENERAL, SG_BULK );
|
||||
// sglog().setLogLevels( SG_GENERAL, SG_BULK );
|
||||
sglog().setLogLevels( SG_GENERAL, SG_INFO );
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_INFO, "Run genapt");
|
||||
|
|
|
@ -345,6 +345,8 @@ void Parser::Parse()
|
|||
}
|
||||
gettimeofday(&parse_end, NULL);
|
||||
timersub(&parse_end, &parse_start, &parse_time);
|
||||
|
||||
SG_LOG( SG_GENERAL, SG_ALERT, "Finished parsing airport " << airport_icaos[i] << " at " << ctime(&parse_end.tv_sec) );
|
||||
|
||||
// write the airport BTG
|
||||
if (cur_airport)
|
||||
|
@ -536,9 +538,13 @@ ClosedPoly* Parser::ParsePavement( char* line )
|
|||
if (numParams == 4)
|
||||
{
|
||||
d = strstr(line,desc);
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Creating Closed Poly with st " << st << " smoothness " << s << " thexture heading " << th << " and description " << d);
|
||||
}
|
||||
else
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Creating Closed Poly with st " << st << " smoothness " << s << " thexture heading " << th );
|
||||
}
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Creating Closed Poly with st " << st << " smoothness " << s << " thexture heading " << th << " and description " << d);
|
||||
poly = new ClosedPoly(st, s, th, d);
|
||||
|
||||
return poly;
|
||||
|
@ -599,178 +605,146 @@ int Parser::ParseLine(char* line)
|
|||
|
||||
BezNode* cur_node = NULL;
|
||||
|
||||
// Get the number code
|
||||
tok = strtok(line, " \t\r\n");
|
||||
|
||||
if (tok)
|
||||
if (*line != '#')
|
||||
{
|
||||
line += strlen(tok)+1;
|
||||
code = atoi(tok);
|
||||
// Get the number code
|
||||
tok = strtok(line, " \t\r\n");
|
||||
|
||||
switch(code)
|
||||
if (tok)
|
||||
{
|
||||
case LAND_AIRPORT_CODE:
|
||||
case SEA_AIRPORT_CODE:
|
||||
if (cur_state == STATE_NONE)
|
||||
{
|
||||
line += strlen(tok)+1;
|
||||
code = atoi(tok);
|
||||
|
||||
switch(code)
|
||||
{
|
||||
case LAND_AIRPORT_CODE:
|
||||
case SEA_AIRPORT_CODE:
|
||||
if (cur_state == STATE_NONE)
|
||||
{
|
||||
SetState( STATE_PARSE_SIMPLE );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing land airport: " << line);
|
||||
cur_airport = new Airport( code, line );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetState( STATE_DONE );
|
||||
}
|
||||
break;
|
||||
case HELIPORT_CODE:
|
||||
if (cur_state == STATE_NONE)
|
||||
{
|
||||
SetState( STATE_PARSE_SIMPLE );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing heliport: " << line);
|
||||
cur_airport = new Airport( code, line );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetState( STATE_DONE );
|
||||
}
|
||||
break;
|
||||
|
||||
case LAND_RUNWAY_CODE:
|
||||
SetState( STATE_PARSE_SIMPLE );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing land airport: " << line);
|
||||
cur_airport = new Airport( code, line );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetState( STATE_DONE );
|
||||
}
|
||||
break;
|
||||
case HELIPORT_CODE:
|
||||
if (cur_state == STATE_NONE)
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing runway: " << line);
|
||||
cur_runway = new Runway(line);
|
||||
if (cur_airport)
|
||||
{
|
||||
cur_airport->AddRunway( cur_runway );
|
||||
}
|
||||
break;
|
||||
|
||||
case WATER_RUNWAY_CODE:
|
||||
SetState( STATE_PARSE_SIMPLE );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing heliport: " << line);
|
||||
cur_airport = new Airport( code, line );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetState( STATE_DONE );
|
||||
}
|
||||
break;
|
||||
|
||||
case LAND_RUNWAY_CODE:
|
||||
SetState( STATE_PARSE_SIMPLE );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing runway: " << line);
|
||||
cur_runway = new Runway(line);
|
||||
if (cur_airport)
|
||||
{
|
||||
cur_airport->AddRunway( cur_runway );
|
||||
}
|
||||
break;
|
||||
|
||||
case WATER_RUNWAY_CODE:
|
||||
SetState( STATE_PARSE_SIMPLE );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing water runway: " << line);
|
||||
cur_waterrunway = new WaterRunway(line);
|
||||
if (cur_airport)
|
||||
{
|
||||
cur_airport->AddWaterRunway( cur_waterrunway );
|
||||
}
|
||||
break;
|
||||
case HELIPAD_CODE:
|
||||
SetState( STATE_PARSE_SIMPLE );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing helipad: " << line);
|
||||
cur_helipad = new Helipad(line);
|
||||
if (cur_airport)
|
||||
{
|
||||
cur_airport->AddHelipad( cur_helipad );
|
||||
}
|
||||
break;
|
||||
|
||||
case PAVEMENT_CODE:
|
||||
SetState( STATE_PARSE_PAVEMENT );
|
||||
cur_pavement = ParsePavement( line );
|
||||
break;
|
||||
|
||||
case LINEAR_FEATURE_CODE:
|
||||
SetState( STATE_PARSE_FEATURE );
|
||||
cur_feat = ParseFeature( line );
|
||||
break;
|
||||
|
||||
case BOUNDRY_CODE:
|
||||
SetState( STATE_PARSE_BOUNDARY );
|
||||
cur_boundary = ParseBoundary( line );
|
||||
break;
|
||||
|
||||
case NODE_CODE:
|
||||
case BEZIER_NODE_CODE:
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing node: " << line);
|
||||
cur_node = ParseNode( code, line, prev_node );
|
||||
|
||||
if ( prev_node && (cur_node != prev_node) )
|
||||
{
|
||||
// prev node is done - process it\n");
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing water runway: " << line);
|
||||
cur_waterrunway = new WaterRunway(line);
|
||||
if (cur_airport)
|
||||
{
|
||||
cur_airport->AddWaterRunway( cur_waterrunway );
|
||||
}
|
||||
break;
|
||||
case HELIPAD_CODE:
|
||||
SetState( STATE_PARSE_SIMPLE );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing helipad: " << line);
|
||||
cur_helipad = new Helipad(line);
|
||||
if (cur_airport)
|
||||
{
|
||||
cur_airport->AddHelipad( cur_helipad );
|
||||
}
|
||||
break;
|
||||
|
||||
case PAVEMENT_CODE:
|
||||
SetState( STATE_PARSE_PAVEMENT );
|
||||
cur_pavement = ParsePavement( line );
|
||||
break;
|
||||
|
||||
case LINEAR_FEATURE_CODE:
|
||||
SetState( STATE_PARSE_FEATURE );
|
||||
cur_feat = ParseFeature( line );
|
||||
break;
|
||||
|
||||
case BOUNDRY_CODE:
|
||||
SetState( STATE_PARSE_BOUNDARY );
|
||||
cur_boundary = ParseBoundary( line );
|
||||
break;
|
||||
|
||||
case NODE_CODE:
|
||||
case BEZIER_NODE_CODE:
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing node: " << line);
|
||||
cur_node = ParseNode( code, line, prev_node );
|
||||
|
||||
if ( prev_node && (cur_node != prev_node) )
|
||||
{
|
||||
// prev node is done - process it\n");
|
||||
if ( cur_state == STATE_PARSE_PAVEMENT )
|
||||
{
|
||||
cur_pavement->AddNode( prev_node );
|
||||
}
|
||||
else if ( cur_state == STATE_PARSE_FEATURE )
|
||||
{
|
||||
cur_feat->AddNode( prev_node );
|
||||
}
|
||||
else if ( cur_state == STATE_PARSE_BOUNDARY )
|
||||
{
|
||||
cur_boundary->AddNode( prev_node );
|
||||
}
|
||||
}
|
||||
|
||||
prev_node = cur_node;
|
||||
break;
|
||||
|
||||
case CLOSE_NODE_CODE:
|
||||
case CLOSE_BEZIER_NODE_CODE:
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing close loop node: " << line);
|
||||
cur_node = ParseNode( code, line, prev_node );
|
||||
|
||||
if ( cur_state == STATE_PARSE_PAVEMENT )
|
||||
{
|
||||
cur_pavement->AddNode( prev_node );
|
||||
}
|
||||
else if ( cur_state == STATE_PARSE_FEATURE )
|
||||
{
|
||||
cur_feat->AddNode( prev_node );
|
||||
if (cur_node != prev_node)
|
||||
{
|
||||
cur_pavement->AddNode( prev_node );
|
||||
cur_pavement->AddNode( cur_node );
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_pavement->AddNode( cur_node );
|
||||
}
|
||||
cur_pavement->CloseCurContour();
|
||||
}
|
||||
else if ( cur_state == STATE_PARSE_BOUNDARY )
|
||||
{
|
||||
cur_boundary->AddNode( prev_node );
|
||||
if (cur_node != prev_node)
|
||||
{
|
||||
cur_boundary->AddNode( prev_node );
|
||||
cur_boundary->AddNode( cur_node );
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_boundary->AddNode( cur_node );
|
||||
}
|
||||
cur_boundary->CloseCurContour();
|
||||
}
|
||||
}
|
||||
|
||||
prev_node = cur_node;
|
||||
break;
|
||||
|
||||
case CLOSE_NODE_CODE:
|
||||
case CLOSE_BEZIER_NODE_CODE:
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing close loop node: " << line);
|
||||
cur_node = ParseNode( code, line, prev_node );
|
||||
|
||||
if ( cur_state == STATE_PARSE_PAVEMENT )
|
||||
{
|
||||
if (cur_node != prev_node)
|
||||
else if ( cur_state == STATE_PARSE_FEATURE )
|
||||
{
|
||||
cur_pavement->AddNode( prev_node );
|
||||
cur_pavement->AddNode( cur_node );
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_pavement->AddNode( cur_node );
|
||||
}
|
||||
cur_pavement->CloseCurContour();
|
||||
}
|
||||
else if ( cur_state == STATE_PARSE_BOUNDARY )
|
||||
{
|
||||
if (cur_node != prev_node)
|
||||
{
|
||||
cur_boundary->AddNode( prev_node );
|
||||
cur_boundary->AddNode( cur_node );
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_boundary->AddNode( cur_node );
|
||||
}
|
||||
cur_boundary->CloseCurContour();
|
||||
}
|
||||
else if ( cur_state == STATE_PARSE_FEATURE )
|
||||
{
|
||||
if (cur_node != prev_node)
|
||||
{
|
||||
cur_feat->AddNode( prev_node );
|
||||
cur_feat->AddNode( cur_node );
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_feat->AddNode( cur_node );
|
||||
}
|
||||
if (cur_airport)
|
||||
{
|
||||
cur_feat->Finish();
|
||||
cur_airport->AddFeature( cur_feat );
|
||||
}
|
||||
cur_feat = NULL;
|
||||
SetState( STATE_NONE );
|
||||
}
|
||||
prev_node = NULL;
|
||||
cur_node = NULL;
|
||||
break;
|
||||
|
||||
case TERM_NODE_CODE:
|
||||
case TERM_BEZIER_NODE_CODE:
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing termination node: " << line);
|
||||
|
||||
if ( cur_state == STATE_PARSE_FEATURE )
|
||||
{
|
||||
// we have some bad data - termination nodes right after the
|
||||
// linear feature declaration - can't do anything with a
|
||||
// single point - detect and delete.
|
||||
if ( prev_node )
|
||||
{
|
||||
cur_node = ParseNode( code, line, prev_node );
|
||||
|
||||
if (cur_node != prev_node)
|
||||
{
|
||||
cur_feat->AddNode( prev_node );
|
||||
|
@ -785,87 +759,122 @@ int Parser::ParseLine(char* line)
|
|||
cur_feat->Finish();
|
||||
cur_airport->AddFeature( cur_feat );
|
||||
}
|
||||
cur_feat = NULL;
|
||||
SetState( STATE_NONE );
|
||||
}
|
||||
else
|
||||
prev_node = NULL;
|
||||
cur_node = NULL;
|
||||
break;
|
||||
|
||||
case TERM_NODE_CODE:
|
||||
case TERM_BEZIER_NODE_CODE:
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing termination node: " << line);
|
||||
|
||||
if ( cur_state == STATE_PARSE_FEATURE )
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "Parsing termination node with no previous nodes!!!" );
|
||||
|
||||
// this feature is bogus...
|
||||
delete cur_feat;
|
||||
// we have some bad data - termination nodes right after the
|
||||
// linear feature declaration - can't do anything with a
|
||||
// single point - detect and delete.
|
||||
if ( prev_node )
|
||||
{
|
||||
cur_node = ParseNode( code, line, prev_node );
|
||||
|
||||
if (cur_node != prev_node)
|
||||
{
|
||||
cur_feat->AddNode( prev_node );
|
||||
cur_feat->AddNode( cur_node );
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_feat->AddNode( cur_node );
|
||||
}
|
||||
if (cur_airport)
|
||||
{
|
||||
cur_feat->Finish();
|
||||
cur_airport->AddFeature( cur_feat );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "Parsing termination node with no previous nodes!!!" );
|
||||
|
||||
// this feature is bogus...
|
||||
delete cur_feat;
|
||||
}
|
||||
cur_feat = NULL;
|
||||
SetState( STATE_NONE );
|
||||
}
|
||||
cur_feat = NULL;
|
||||
SetState( STATE_NONE );
|
||||
}
|
||||
prev_node = NULL;
|
||||
cur_node = NULL;
|
||||
break;
|
||||
|
||||
case AIRPORT_VIEWPOINT_CODE:
|
||||
SetState( STATE_PARSE_SIMPLE );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing viewpoint: " << line);
|
||||
break;
|
||||
case AIRPLANE_STARTUP_LOCATION_CODE:
|
||||
SetState( STATE_PARSE_SIMPLE );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing airplane startup location: " << line);
|
||||
break;
|
||||
case LIGHT_BEACON_CODE:
|
||||
SetState( STATE_PARSE_SIMPLE );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing light beacon: " << line);
|
||||
cur_beacon = new Beacon(line);
|
||||
cur_airport->AddBeacon( cur_beacon );
|
||||
break;
|
||||
case WINDSOCK_CODE:
|
||||
SetState( STATE_PARSE_SIMPLE );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing windsock: " << line);
|
||||
cur_windsock = new Windsock(line);
|
||||
cur_airport->AddWindsock( cur_windsock );
|
||||
break;
|
||||
case TAXIWAY_SIGN:
|
||||
SetState( STATE_PARSE_SIMPLE );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing taxiway sign: " << line);
|
||||
cur_sign = new Sign(line);
|
||||
cur_airport->AddSign( cur_sign );
|
||||
break;
|
||||
case LIGHTING_OBJECT:
|
||||
SetState( STATE_PARSE_SIMPLE );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing lighting object: " << line);
|
||||
cur_object = new LightingObj(line);
|
||||
cur_airport->AddObj( cur_object );
|
||||
break;
|
||||
case COMM_FREQ1_CODE:
|
||||
SetState( STATE_PARSE_SIMPLE );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 1: " << line);
|
||||
break;
|
||||
case COMM_FREQ2_CODE:
|
||||
SetState( STATE_PARSE_SIMPLE );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 2: " << line);
|
||||
break;
|
||||
case COMM_FREQ3_CODE:
|
||||
SetState( STATE_PARSE_SIMPLE );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 3: " << line);
|
||||
break;
|
||||
case COMM_FREQ4_CODE:
|
||||
SetState( STATE_PARSE_SIMPLE );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 4: " << line);
|
||||
break;
|
||||
case COMM_FREQ5_CODE:
|
||||
SetState( STATE_PARSE_SIMPLE );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 5: " << line);
|
||||
break;
|
||||
case COMM_FREQ6_CODE:
|
||||
SetState( STATE_PARSE_SIMPLE );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 6: " << line);
|
||||
break;
|
||||
case COMM_FREQ7_CODE:
|
||||
SetState( STATE_PARSE_SIMPLE );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 7: " << line);
|
||||
break;
|
||||
case END_OF_FILE :
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Reached end of file");
|
||||
SetState( STATE_DONE );
|
||||
break;
|
||||
prev_node = NULL;
|
||||
cur_node = NULL;
|
||||
break;
|
||||
|
||||
case AIRPORT_VIEWPOINT_CODE:
|
||||
SetState( STATE_PARSE_SIMPLE );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing viewpoint: " << line);
|
||||
break;
|
||||
case AIRPLANE_STARTUP_LOCATION_CODE:
|
||||
SetState( STATE_PARSE_SIMPLE );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing airplane startup location: " << line);
|
||||
break;
|
||||
case LIGHT_BEACON_CODE:
|
||||
SetState( STATE_PARSE_SIMPLE );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing light beacon: " << line);
|
||||
cur_beacon = new Beacon(line);
|
||||
cur_airport->AddBeacon( cur_beacon );
|
||||
break;
|
||||
case WINDSOCK_CODE:
|
||||
SetState( STATE_PARSE_SIMPLE );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing windsock: " << line);
|
||||
cur_windsock = new Windsock(line);
|
||||
cur_airport->AddWindsock( cur_windsock );
|
||||
break;
|
||||
case TAXIWAY_SIGN:
|
||||
SetState( STATE_PARSE_SIMPLE );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing taxiway sign: " << line);
|
||||
cur_sign = new Sign(line);
|
||||
cur_airport->AddSign( cur_sign );
|
||||
break;
|
||||
case LIGHTING_OBJECT:
|
||||
SetState( STATE_PARSE_SIMPLE );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing lighting object: " << line);
|
||||
cur_object = new LightingObj(line);
|
||||
cur_airport->AddObj( cur_object );
|
||||
break;
|
||||
case COMM_FREQ1_CODE:
|
||||
SetState( STATE_PARSE_SIMPLE );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 1: " << line);
|
||||
break;
|
||||
case COMM_FREQ2_CODE:
|
||||
SetState( STATE_PARSE_SIMPLE );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 2: " << line);
|
||||
break;
|
||||
case COMM_FREQ3_CODE:
|
||||
SetState( STATE_PARSE_SIMPLE );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 3: " << line);
|
||||
break;
|
||||
case COMM_FREQ4_CODE:
|
||||
SetState( STATE_PARSE_SIMPLE );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 4: " << line);
|
||||
break;
|
||||
case COMM_FREQ5_CODE:
|
||||
SetState( STATE_PARSE_SIMPLE );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 5: " << line);
|
||||
break;
|
||||
case COMM_FREQ6_CODE:
|
||||
SetState( STATE_PARSE_SIMPLE );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 6: " << line);
|
||||
break;
|
||||
case COMM_FREQ7_CODE:
|
||||
SetState( STATE_PARSE_SIMPLE );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 7: " << line);
|
||||
break;
|
||||
case END_OF_FILE :
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Reached end of file");
|
||||
SetState( STATE_DONE );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return cur_state;
|
||||
}
|
||||
|
|
|
@ -136,8 +136,8 @@ int Runway::BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list* te
|
|||
case 4: // Dirt
|
||||
case 5: // Gravel
|
||||
SG_LOG( SG_GENERAL, SG_DEBUG, "Build Runway: Turf, Dirt or Gravel" << rwy.surface );
|
||||
gen_simple_rwy( alt_m, material, rwy_polys, texparams, accum );
|
||||
gen_runway_lights( alt_m, rwy_lights );
|
||||
gen_simple_rwy( alt_m, material, rwy_polys, texparams, accum );
|
||||
gen_runway_lights( alt_m, rwy_lights );
|
||||
break;
|
||||
|
||||
case 12: // dry lakebed
|
||||
|
@ -164,10 +164,10 @@ int Runway::BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list* te
|
|||
if (apt_base)
|
||||
{
|
||||
// generate area around runways
|
||||
base = gen_runway_area_w_extend( 0.0, rwy.width * 0.25, -rwy.overrun[0], -rwy.overrun[1], rwy.width * 0.25);
|
||||
base = gen_runway_area_w_extend( 0.0, 20.0, -rwy.overrun[0], -rwy.overrun[1], 20.0);
|
||||
|
||||
// also clear a safe area around the runway
|
||||
safe_base = gen_runway_area_w_extend( 0.0, rwy.width, -rwy.overrun[0], -rwy.overrun[1], rwy.width );
|
||||
safe_base = gen_runway_area_w_extend( 0.0, 180.0, -rwy.overrun[0], -rwy.overrun[1], 50.0 );
|
||||
|
||||
// add this to the airport clearing
|
||||
*apt_clearing = tgPolygonUnion(safe_base, *apt_clearing);
|
||||
|
|
|
@ -354,7 +354,7 @@ void Runway::BuildShoulder( float alt_m,
|
|||
} else SG_LOG(SG_GENERAL, SG_ALERT, "Unknown shoulder surface code = " << rwy.shoulder );
|
||||
|
||||
} else if (rwy.shoulder == 0){ // We add a fake shoulder if the runway has an asphalt or concrete surface
|
||||
shoulder_width = 1;
|
||||
shoulder_width = 1.0;
|
||||
if (rwy.surface == 1){
|
||||
shoulder_surface = "pa_shoulder_f";
|
||||
} else if (rwy.surface == 2){
|
||||
|
@ -365,6 +365,13 @@ void Runway::BuildShoulder( float alt_m,
|
|||
SG_LOG(SG_GENERAL, SG_DEBUG, "Shoulder surface is: " << shoulder_surface );
|
||||
|
||||
if (shoulder_width > 0.0f) {
|
||||
|
||||
// we need to break these shoulders up into managable pieces, as we're asked to triangulate
|
||||
// 3-4 km long by 1m wide strips - jrs-can't handle it.
|
||||
double max_dist = (double)shoulder_width * 50.0f;
|
||||
int numSegs = (rwy.length / max_dist) + 1;
|
||||
double dist = rwy.length / (double)numSegs;
|
||||
|
||||
// Create both shoulder sides
|
||||
for (int i=0; i<2; ++i){
|
||||
double step;
|
||||
|
@ -374,44 +381,40 @@ void Runway::BuildShoulder( float alt_m,
|
|||
/* If the are 'equal' there's a good chance roundoff error can create a */
|
||||
/* REALY thin long polygon, which causes a segfault */
|
||||
if (i == 0){
|
||||
step= (rwy.width + shoulder_width)*0.5 - 0.00001;
|
||||
step= (rwy.width + shoulder_width)*0.5;
|
||||
} else if (i == 1) {
|
||||
step= -(rwy.width + shoulder_width)*0.5 + 0.00001;
|
||||
step= -(rwy.width + shoulder_width)*0.5;
|
||||
}
|
||||
double left_hdg = rwy.heading - 90.0;
|
||||
|
||||
if ( left_hdg < 0 ) { left_hdg += 360.0; }
|
||||
|
||||
geo_direct_wgs_84 ( alt_m, rwy.lat[0], rwy.lon[0], left_hdg,
|
||||
step, &lat, &lon, &r );
|
||||
geo_direct_wgs_84 ( alt_m, rwy.lat[0], rwy.lon[0], left_hdg, step, &lat, &lon, &r );
|
||||
Point3D ref = Point3D( lon, lat, 0.0f );
|
||||
|
||||
Point3D shoulder1 = Point3D( lon, lat, 0.0f );
|
||||
for (int j=0; j<numSegs; j++)
|
||||
{
|
||||
geo_direct_wgs_84 ( alt_m, ref.y(), ref.x(), rwy.heading, (j*dist), &lat, &lon, &r );
|
||||
TGPolygon shoulderSegment = gen_wgs84_rect( lat, lon, rwy.heading, dist+0.2, shoulder_width+0.5 );
|
||||
|
||||
geo_direct_wgs_84 ( alt_m, rwy.lat[1], rwy.lon[1], left_hdg,
|
||||
step, &lat, &lon, &r );
|
||||
TGSuperPoly sp;
|
||||
TGTexParams tp;
|
||||
TGPolygon clipped = tgPolygonDiff( shoulderSegment, *accum );
|
||||
|
||||
Point3D shoulder2 = Point3D( lon, lat, 0.0f );
|
||||
sp.erase();
|
||||
sp.set_poly( clipped );
|
||||
sp.set_material( shoulder_surface );
|
||||
rwy_polys->push_back( sp );
|
||||
|
||||
TGPolygon shoulder = gen_wgs84_area( shoulder1, shoulder2, 0.0, 0.0, 0.0, shoulder_width, rwy.heading, alt_m, false);
|
||||
*accum = tgPolygonUnion( shoulderSegment, *accum );
|
||||
|
||||
TGSuperPoly sp;
|
||||
TGTexParams tp;
|
||||
TGPolygon clipped = tgPolygonDiff( shoulder, *accum );
|
||||
TGPolygon split = tgPolygonSplitLongEdges( clipped, 400.0 );
|
||||
|
||||
sp.erase();
|
||||
sp.set_poly( split );
|
||||
sp.set_material( shoulder_surface );
|
||||
rwy_polys->push_back( sp );
|
||||
|
||||
*accum = tgPolygonUnion( shoulder, *accum );
|
||||
|
||||
tp = TGTexParams( shoulder.get_pt(0,0), shoulder_width , rwy.length + 2, rwy.heading );
|
||||
if (i == 1){
|
||||
tp.set_maxu(0);
|
||||
tp.set_minu(1);
|
||||
tp = TGTexParams( shoulderSegment.get_pt(0,0), -shoulder_width, dist, rwy.heading );
|
||||
if (i == 0){
|
||||
tp.set_maxu(0);
|
||||
tp.set_minu(1);
|
||||
}
|
||||
texparams->push_back( tp );
|
||||
}
|
||||
texparams->push_back( tp );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,6 +63,8 @@ TGArray::TGArray( const string &file ):
|
|||
for (int i = 0; i < ARRAY_SIZE_1; i++)
|
||||
in_data[i] = new int[ARRAY_SIZE_1];
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "ps TGArray CONstructor called." );
|
||||
|
||||
TGArray::open(file);
|
||||
}
|
||||
|
||||
|
@ -75,7 +77,7 @@ bool TGArray::open( const string& file_base ) {
|
|||
string array_name = file_base + ".arr.gz";
|
||||
array_in = new sg_gzifstream( array_name );
|
||||
if ( ! array_in->is_open() ) {
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, " Cannot open " << array_name );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, " ps: Cannot open " << array_name );
|
||||
success = false;
|
||||
} else {
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, " Opening array data file: " << array_name );
|
||||
|
@ -89,7 +91,7 @@ bool TGArray::open( const string& file_base ) {
|
|||
// can do a really stupid/crude fit on the fly, but it will
|
||||
// not be nearly as nice as what the offline terrafit utility
|
||||
// would have produced.
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, " Cannot open " << fitted_name );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, " ps: Cannot open " << fitted_name );
|
||||
} else {
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, " Opening fitted data file: " << fitted_name );
|
||||
}
|
||||
|
|
|
@ -50,8 +50,6 @@ extern "C" {
|
|||
#include "trisegs.hxx"
|
||||
|
||||
using std::copy;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::ostream_iterator;
|
||||
using std::sort;
|
||||
using std::vector;
|
||||
|
@ -117,7 +115,7 @@ static bool intersects( Point3D p0, Point3D p1, double x, Point3D *result ) {
|
|||
|
||||
// basic triangulation of a polygon with out adding points or
|
||||
// splitting edges, this should triangulate around interior holes.
|
||||
void polygon_tesselate( const TGPolygon &p,
|
||||
int polygon_tesselate( const TGPolygon &p,
|
||||
const point_list &extra_nodes,
|
||||
triele_list &elelist,
|
||||
point_list &out_pts,
|
||||
|
@ -125,8 +123,7 @@ void polygon_tesselate( const TGPolygon &p,
|
|||
{
|
||||
struct triangulateio in, out, vorout;
|
||||
int i;
|
||||
|
||||
tri_flags = "pzqenXYYQ";
|
||||
int success = 0;
|
||||
|
||||
// make sure all elements of these structs point to "NULL"
|
||||
zero_triangulateio( &in );
|
||||
|
@ -272,7 +269,7 @@ void polygon_tesselate( const TGPolygon &p,
|
|||
// no new points on boundary (Y), no internal segment
|
||||
// splitting (YY), no quality refinement (q)
|
||||
// Quite (Q)
|
||||
triangulate( (char *)tri_flags.c_str(), &in, &out, &vorout );
|
||||
success = triangulate( (char *)tri_flags.c_str(), &in, &out, &vorout );
|
||||
|
||||
// TEMPORARY
|
||||
// write_tri_data(&out);
|
||||
|
@ -280,33 +277,36 @@ void polygon_tesselate( const TGPolygon &p,
|
|||
// now copy the results back into the corresponding TGTriangle
|
||||
// structures
|
||||
|
||||
// triangles
|
||||
elelist.clear();
|
||||
int n1, n2, n3;
|
||||
double attribute;
|
||||
for ( i = 0; i < out.numberoftriangles; ++i ) {
|
||||
n1 = out.trianglelist[i * 3];
|
||||
n2 = out.trianglelist[i * 3 + 1];
|
||||
n3 = out.trianglelist[i * 3 + 2];
|
||||
if ( out.numberoftriangleattributes > 0 ) {
|
||||
attribute = out.triangleattributelist[i];
|
||||
} else {
|
||||
attribute = 0.0;
|
||||
if (success >= 0) {
|
||||
|
||||
// triangles
|
||||
elelist.clear();
|
||||
int n1, n2, n3;
|
||||
double attribute;
|
||||
for ( i = 0; i < out.numberoftriangles; ++i ) {
|
||||
n1 = out.trianglelist[i * 3];
|
||||
n2 = out.trianglelist[i * 3 + 1];
|
||||
n3 = out.trianglelist[i * 3 + 2];
|
||||
if ( out.numberoftriangleattributes > 0 ) {
|
||||
attribute = out.triangleattributelist[i];
|
||||
} else {
|
||||
attribute = 0.0;
|
||||
}
|
||||
// cout << "triangle = " << n1 << " " << n2 << " " << n3 << endl;
|
||||
elelist.push_back( TGTriEle( n1, n2, n3, attribute ) );
|
||||
}
|
||||
|
||||
// output points
|
||||
out_pts.clear();
|
||||
double x, y, z;
|
||||
for ( i = 0; i < out.numberofpoints; ++i ) {
|
||||
x = out.pointlist[i * 2 ];
|
||||
y = out.pointlist[i * 2 + 1];
|
||||
z = out.pointattributelist[i];
|
||||
out_pts.push_back( Point3D(x, y, z) );
|
||||
}
|
||||
// cout << "triangle = " << n1 << " " << n2 << " " << n3 << endl;
|
||||
elelist.push_back( TGTriEle( n1, n2, n3, attribute ) );
|
||||
}
|
||||
|
||||
// output points
|
||||
out_pts.clear();
|
||||
double x, y, z;
|
||||
for ( i = 0; i < out.numberofpoints; ++i ) {
|
||||
x = out.pointlist[i * 2 ];
|
||||
y = out.pointlist[i * 2 + 1];
|
||||
z = out.pointattributelist[i];
|
||||
out_pts.push_back( Point3D(x, y, z) );
|
||||
}
|
||||
|
||||
// free mem allocated to the "Triangle" structures
|
||||
free(in.pointlist);
|
||||
free(in.pointattributelist);
|
||||
|
@ -327,6 +327,8 @@ void polygon_tesselate( const TGPolygon &p,
|
|||
free(vorout.pointattributelist);
|
||||
free(vorout.edgelist);
|
||||
free(vorout.normlist);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
|
@ -336,7 +338,7 @@ void polygon_tesselate( const TGPolygon &p,
|
|||
// wrapper for the polygon_tesselate() function. Note, this routine
|
||||
// will modify the points_inside list for your polygon.
|
||||
|
||||
TGPolygon polygon_tesselate_alt( TGPolygon &p ) {
|
||||
TGPolygon polygon_tesselate_alt( TGPolygon &p, bool verbose ) {
|
||||
TGPolygon result;
|
||||
point_list extra_nodes;
|
||||
result.erase();
|
||||
|
@ -358,25 +360,42 @@ TGPolygon polygon_tesselate_alt( TGPolygon &p ) {
|
|||
// 2. Do a final triangulation of the entire polygon
|
||||
triele_list trieles;
|
||||
point_list nodes;
|
||||
// polygon_tesselate( p, extra_nodes, trieles, nodes, "pzYYenQ" );
|
||||
polygon_tesselate( p, extra_nodes, trieles, nodes, "pzenQ" );
|
||||
string flags;
|
||||
if (verbose) {
|
||||
flags = "pzqenXYY";
|
||||
} else {
|
||||
flags = "pzqenXYYQ";
|
||||
}
|
||||
|
||||
// 3. Convert the tesselated output to a list of tringles.
|
||||
// basically a polygon with a contour for every triangle
|
||||
for ( i = 0; i < (int)trieles.size(); ++i ) {
|
||||
TGTriEle t = trieles[i];
|
||||
Point3D p1 = nodes[ t.get_n1() ];
|
||||
Point3D p2 = nodes[ t.get_n2() ];
|
||||
Point3D p3 = nodes[ t.get_n3() ];
|
||||
result.add_node( i, p1 );
|
||||
result.add_node( i, p2 );
|
||||
result.add_node( i, p3 );
|
||||
if ( polygon_tesselate( p, extra_nodes, trieles, nodes, flags ) >= 0 ) {
|
||||
// 3. Convert the tesselated output to a list of tringles.
|
||||
// basically a polygon with a contour for every triangle
|
||||
for ( i = 0; i < (int)trieles.size(); ++i ) {
|
||||
TGTriEle t = trieles[i];
|
||||
Point3D p1 = nodes[ t.get_n1() ];
|
||||
Point3D p2 = nodes[ t.get_n2() ];
|
||||
Point3D p3 = nodes[ t.get_n3() ];
|
||||
result.add_node( i, p1 );
|
||||
result.add_node( i, p2 );
|
||||
result.add_node( i, p3 );
|
||||
}
|
||||
}
|
||||
|
||||
// check the result for nan point
|
||||
for (int c = 0; c < result.contours(); c++) {
|
||||
point_list contour = result.get_contour( c );
|
||||
for ( int d = 0; d < (int)contour.size(); ++d ) {
|
||||
if ( isnan( contour[d].x() ) || isnan( contour[d].y() ) ) {
|
||||
printf("Uh-oh - got nan from tesselation\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
TGPolygon polygon_tesselate_alt_with_extra( TGPolygon &p, const point_list& extra_nodes ) {
|
||||
TGPolygon polygon_tesselate_alt_with_extra( TGPolygon &p, const point_list& extra_nodes, bool verbose ) {
|
||||
TGPolygon result;
|
||||
result.erase();
|
||||
int i;
|
||||
|
@ -394,18 +413,25 @@ TGPolygon polygon_tesselate_alt_with_extra( TGPolygon &p, const point_list& extr
|
|||
// 2. Do a final triangulation of the entire polygon
|
||||
triele_list trieles;
|
||||
point_list nodes;
|
||||
polygon_tesselate( p, extra_nodes, trieles, nodes, "pzenQ" );
|
||||
string flags;
|
||||
if (verbose) {
|
||||
flags = "VVpzqenXYY";
|
||||
} else {
|
||||
flags = "pzqenXYYQ";
|
||||
}
|
||||
|
||||
// 3. Convert the tesselated output to a list of tringles.
|
||||
// basically a polygon with a contour for every triangle
|
||||
for ( i = 0; i < (int)trieles.size(); ++i ) {
|
||||
TGTriEle t = trieles[i];
|
||||
Point3D p1 = nodes[ t.get_n1() ];
|
||||
Point3D p2 = nodes[ t.get_n2() ];
|
||||
Point3D p3 = nodes[ t.get_n3() ];
|
||||
result.add_node( i, p1 );
|
||||
result.add_node( i, p2 );
|
||||
result.add_node( i, p3 );
|
||||
if ( polygon_tesselate( p, extra_nodes, trieles, nodes, flags ) >= 0 ) {
|
||||
// 3. Convert the tesselated output to a list of tringles.
|
||||
// basically a polygon with a contour for every triangle
|
||||
for ( i = 0; i < (int)trieles.size(); ++i ) {
|
||||
TGTriEle t = trieles[i];
|
||||
Point3D p1 = nodes[ t.get_n1() ];
|
||||
Point3D p2 = nodes[ t.get_n2() ];
|
||||
Point3D p3 = nodes[ t.get_n3() ];
|
||||
result.add_node( i, p1 );
|
||||
result.add_node( i, p2 );
|
||||
result.add_node( i, p3 );
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -598,7 +624,7 @@ static void calc_point_inside( TGContourNode *node, TGPolygon &p ) {
|
|||
}
|
||||
|
||||
static void print_contour_tree( TGContourNode *node, string indent ) {
|
||||
cout << indent << node->get_contour_num() << endl;
|
||||
// cout << indent << node->get_contour_num() << endl;
|
||||
|
||||
indent += " ";
|
||||
for ( int i = 0; i < node->get_num_kids(); ++i ) {
|
||||
|
@ -997,7 +1023,7 @@ static point_list reduce_contour_degeneracy( const point_list& contour ) {
|
|||
// remove bad node from contour. But only remove one node. If
|
||||
// the 'badness' is caused by coincident adjacent nodes, we don't
|
||||
// want to remove both of them, just one (either will do.)
|
||||
cout << "found a bad node = " << bad_node << endl;
|
||||
// cout << "found a bad node = " << bad_node << endl;
|
||||
point_list tmp; tmp.clear();
|
||||
bool found_one = false;
|
||||
for ( int j = 0; j < (int)result.size(); ++j ) {
|
||||
|
@ -1045,11 +1071,11 @@ static point_list remove_small_cycles( const point_list& contour ) {
|
|||
result.push_back( contour[i] );
|
||||
for ( unsigned int j = i + 1; j < contour.size(); ++j ) {
|
||||
if ( contour[i] == contour[j] && i + 4 > j ) {
|
||||
cout << "detected a small cycle: i = "
|
||||
<< i << " j = " << j << endl;
|
||||
for ( unsigned int k = i; k <= j; ++k ) {
|
||||
cout << " " << contour[k] << endl;
|
||||
}
|
||||
// cout << "detected a small cycle: i = "
|
||||
// << i << " j = " << j << endl;
|
||||
//for ( unsigned int k = i; k <= j; ++k ) {
|
||||
// cout << " " << contour[k] << endl;
|
||||
//}
|
||||
i = j;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ inline double triangle_area( const Point3D p1,
|
|||
|
||||
// basic triangulation of a polygon with out adding points or
|
||||
// splitting edges
|
||||
void polygon_tesselate( const TGPolygon &p,
|
||||
int polygon_tesselate( const TGPolygon &p,
|
||||
const point_list &extra_nodes,
|
||||
triele_list &elelist,
|
||||
point_list &out_pts,
|
||||
|
@ -64,10 +64,10 @@ void polygon_tesselate( const TGPolygon &p,
|
|||
// with one contour per tesselated triangle. This is mostly just a
|
||||
// wrapper for the polygon_tesselate() function. Note, this routine
|
||||
// will modify the points_inside list for your polygon.
|
||||
TGPolygon polygon_tesselate_alt( TGPolygon &p );
|
||||
TGPolygon polygon_tesselate_alt( TGPolygon &p, bool verbose );
|
||||
|
||||
TGPolygon polygon_tesselate_alt_with_extra( TGPolygon &p,
|
||||
const point_list &extra_nodes );
|
||||
const point_list &extra_nodes, bool verbose );
|
||||
|
||||
// calculate some "arbitrary" point inside each of the polygons contours
|
||||
void calc_points_inside( TGPolygon& p );
|
||||
|
|
|
@ -36,8 +36,8 @@
|
|||
|
||||
|
||||
#define FG_PROXIMITY_EPSILON 0.000001
|
||||
#define FG_COURSE_EPSILON 0.0003
|
||||
|
||||
//#define FG_COURSE_EPSILON 0.0003
|
||||
#define FG_COURSE_EPSILON 0.0001
|
||||
|
||||
class TGTriNodes {
|
||||
|
||||
|
|
Loading…
Reference in a new issue