diff --git a/.gitignore b/.gitignore index 85e2bb49..d4574fb8 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ Makefile.in .deps *.o *.a +*~ COPYING INSTALL VERSION diff --git a/src/Airports/GenAirports/build.cxx b/src/Airports/GenAirports/build.cxx index 9e074dc5..52c56455 100644 --- a/src/Airports/GenAirports/build.cxx +++ b/src/Airports/GenAirports/build.cxx @@ -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 diff --git a/src/Airports/GenAirports850/airport.cxx b/src/Airports/GenAirports850/airport.cxx index 1898035e..a476e38e 100644 --- a/src/Airports/GenAirports850/airport.cxx +++ b/src/Airports/GenAirports850/airport.cxx @@ -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; iGetMidpoint().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; iGetLoc().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; iGetDescription() ); + 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; iIsPrecision() ) { 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; iBuildBtg( 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; iGetDescription()); + 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; iGetsShoulder() ) { 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(*it) < 32 || static_cast(*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; iAddRunway( 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; } diff --git a/src/Airports/GenAirports850/runway.cxx b/src/Airports/GenAirports850/runway.cxx index 27363327..6cb430fd 100644 --- a/src/Airports/GenAirports850/runway.cxx +++ b/src/Airports/GenAirports850/runway.cxx @@ -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); diff --git a/src/Airports/GenAirports850/rwy_gen.cxx b/src/Airports/GenAirports850/rwy_gen.cxx index 75eae0a3..53b0c1d7 100644 --- a/src/Airports/GenAirports850/rwy_gen.cxx +++ b/src/Airports/GenAirports850/rwy_gen.cxx @@ -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; jpush_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 ); } } } diff --git a/src/Lib/Array/array.cxx b/src/Lib/Array/array.cxx index fb5ac989..d8883562 100644 --- a/src/Lib/Array/array.cxx +++ b/src/Lib/Array/array.cxx @@ -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 ); } diff --git a/src/Lib/Geometry/poly_support.cxx b/src/Lib/Geometry/poly_support.cxx index 66c50ee8..caf231dc 100644 --- a/src/Lib/Geometry/poly_support.cxx +++ b/src/Lib/Geometry/poly_support.cxx @@ -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; } } diff --git a/src/Lib/Geometry/poly_support.hxx b/src/Lib/Geometry/poly_support.hxx index 328f6aac..eb57c53d 100644 --- a/src/Lib/Geometry/poly_support.hxx +++ b/src/Lib/Geometry/poly_support.hxx @@ -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 ); diff --git a/src/Lib/Geometry/trinodes.hxx b/src/Lib/Geometry/trinodes.hxx index 6998a73c..7753d91c 100644 --- a/src/Lib/Geometry/trinodes.hxx +++ b/src/Lib/Geometry/trinodes.hxx @@ -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 {