Stability checkpoint
- When adding intermediate nodes, keep linear feature nodes list seperate from the rest, as they are seperate accumulation buffers. - Revert expand poly by 5cm. It broke more airports than it fixed :( - Going back to GPC as well. Feature Fixes - finally got around to the last segment in closed linear features. I think I am feature complete now. Remaining issues. - I still see terrain holes between the base and clearing polys when an airport traverses a tile boundary. I'm not sure where to start here, as genapt doesn't really know about the tile boundary. (Is the clearing part of the tile construction? - need to look into this) )
This commit is contained in:
parent
372cbdf38f
commit
1090e602c2
16 changed files with 651 additions and 392 deletions
|
@ -359,7 +359,10 @@ static TGPolygon calc_elevations( TGAptSurface &surf,
|
|||
void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
||||
{
|
||||
ClipPolyType accum;
|
||||
|
||||
// try to keep line accumulator in clipper format for speed...
|
||||
ClipPolyType line_accum;
|
||||
|
||||
TGPolygon apt_base;
|
||||
TGPolygon apt_clearing;
|
||||
|
||||
|
@ -432,9 +435,6 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
for ( unsigned int i=0; i<features.size(); i++ )
|
||||
{
|
||||
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 );
|
||||
features[i]->BuildBtg( altitude, &line_polys, &line_tps, &line_accum, &rwy_lights );
|
||||
}
|
||||
}
|
||||
|
@ -472,7 +472,6 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
for ( unsigned int 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 );
|
||||
}
|
||||
}
|
||||
|
@ -483,7 +482,6 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
for ( unsigned int i=0; i<helipads.size(); i++ )
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_INFO, "Build helipad " << i << " of " << helipads.size());
|
||||
|
||||
if (boundary)
|
||||
{
|
||||
helipads[i]->BuildBtg( altitude, &rwy_polys, &rwy_tps, &rwy_lights, &accum, NULL, NULL );
|
||||
|
@ -502,6 +500,14 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
{
|
||||
SG_LOG(SG_GENERAL, SG_INFO, "Build Pavement " << i << " of " << pavements.size() << " : " << pavements[i]->GetDescription());
|
||||
|
||||
#if 0
|
||||
if (i == 30) {
|
||||
sglog().setLogLevels( SG_GENERAL, SG_BULK );
|
||||
} else {
|
||||
sglog().setLogLevels( SG_GENERAL, SG_INFO );
|
||||
}
|
||||
#endif
|
||||
|
||||
if (boundary)
|
||||
{
|
||||
pavements[i]->BuildBtg( altitude, &pvmt_polys, &pvmt_tps, &accum, NULL, NULL );
|
||||
|
@ -535,7 +541,6 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
if (boundary)
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_INFO, "Build user defined boundary " );
|
||||
|
||||
boundary->BuildBtg( altitude, &apt_base, &apt_clearing );
|
||||
}
|
||||
|
||||
|
@ -556,7 +561,8 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
|
||||
// add segments to polygons to remove any possible "T"
|
||||
// intersections
|
||||
TGTriNodes tmp_nodes;
|
||||
TGTriNodes tmp_pvmt_nodes;
|
||||
TGTriNodes tmp_feat_nodes;
|
||||
|
||||
// build temporary node list from runways...
|
||||
SG_LOG(SG_GENERAL, SG_INFO, "Build Node List " );
|
||||
|
@ -568,8 +574,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
{
|
||||
for ( int 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) );
|
||||
tmp_pvmt_nodes.unique_add( poly.get_pt(i, j) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -582,13 +587,12 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
{
|
||||
for ( int 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) );
|
||||
tmp_pvmt_nodes.unique_add( poly.get_pt(i, j) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// and linear features
|
||||
// and linear features ( keep Linear feature nodes seperate)
|
||||
for ( unsigned int k = 0; k < line_polys.size(); ++k )
|
||||
{
|
||||
TGPolygon poly = line_polys[k].get_poly();
|
||||
|
@ -596,8 +600,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
{
|
||||
for ( int 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) );
|
||||
tmp_feat_nodes.unique_add( poly.get_pt(i, j) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -607,8 +610,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
{
|
||||
for ( int 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) );
|
||||
tmp_pvmt_nodes.unique_add( base_poly.get_pt(i, j) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -618,8 +620,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
{
|
||||
for ( int 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) );
|
||||
tmp_pvmt_nodes.unique_add( divided_base.get_pt(i, j) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -630,9 +631,8 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
for ( unsigned int k = 0; k < rwy_polys.size(); ++k )
|
||||
{
|
||||
TGPolygon poly = rwy_polys[k].get_poly();
|
||||
poly = add_nodes_to_poly( poly, tmp_nodes );
|
||||
poly = add_nodes_to_poly( poly, tmp_pvmt_nodes );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after add nodes = " << poly.total_size());
|
||||
|
||||
rwy_polys[k].set_poly( poly );
|
||||
}
|
||||
|
||||
|
@ -640,9 +640,8 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
for ( unsigned int k = 0; k < pvmt_polys.size(); ++k )
|
||||
{
|
||||
TGPolygon poly = pvmt_polys[k].get_poly();
|
||||
poly = add_nodes_to_poly( poly, tmp_nodes );
|
||||
poly = add_nodes_to_poly( poly, tmp_pvmt_nodes );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after add nodes = " << poly.total_size());
|
||||
|
||||
pvmt_polys[k].set_poly( poly );
|
||||
}
|
||||
|
||||
|
@ -650,9 +649,8 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
for ( unsigned int k = 0; k < line_polys.size(); ++k )
|
||||
{
|
||||
TGPolygon poly = line_polys[k].get_poly();
|
||||
poly = add_nodes_to_poly( poly, tmp_nodes );
|
||||
poly = add_nodes_to_poly( poly, tmp_feat_nodes );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after add nodes = " << poly.total_size());
|
||||
|
||||
line_polys[k].set_poly( poly );
|
||||
}
|
||||
|
||||
|
@ -707,9 +705,10 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "add nodes base ");
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, " before: " << base_poly);
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, " tmp_nodes size = " << tmp_nodes.get_node_list().size());
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, " tmp_pvmt_nodes size = " << tmp_pvmt_nodes.get_node_list().size());
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, " tmp_feat_nodes size = " << tmp_feat_nodes.get_node_list().size());
|
||||
|
||||
base_poly = add_nodes_to_poly( base_poly, tmp_nodes );
|
||||
base_poly = add_nodes_to_poly( base_poly, tmp_pvmt_nodes );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, " after adding tmp_nodes: " << base_poly);
|
||||
|
||||
base_poly = remove_cycles( base_poly );
|
||||
|
@ -755,9 +754,11 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
TGPolygon poly = pvmt_polys[i].get_poly();
|
||||
|
||||
#if 0
|
||||
if ( i == 62 ) {
|
||||
if ( i == 0 ) {
|
||||
tgChopNormalPolygon( "/home/pete", "Base", poly, false );
|
||||
verbose_triangulation = true;
|
||||
} else {
|
||||
verbose_triangulation = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -787,9 +788,11 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
TGPolygon poly = line_polys[i].get_poly();
|
||||
|
||||
#if 0
|
||||
if ( i == 62 ) {
|
||||
if ( i == 4558 ) {
|
||||
tgChopNormalPolygon( "/home/pete", "Base", poly, false );
|
||||
verbose_triangulation = true;
|
||||
} else {
|
||||
verbose_triangulation = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -813,6 +816,8 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
|
||||
SG_LOG(SG_GENERAL, SG_INFO, "Tesselating base poly ");
|
||||
TGPolygon base_tris = polygon_tesselate_alt( base_poly, verbose_triangulation );
|
||||
SG_LOG(SG_GENERAL, SG_INFO, "Tesselating base poly - done");
|
||||
|
||||
|
||||
gettimeofday(&triangulation_end, NULL);
|
||||
timersub(&triangulation_end, &triangulation_start, &triangulation_time);
|
||||
|
@ -868,6 +873,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "found normal for this airport = " << tmp);
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_INFO, "Adding runway nodes and normals");
|
||||
for ( unsigned int k = 0; k < rwy_polys.size(); ++k )
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "tri " << k);
|
||||
|
@ -886,9 +892,8 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
for ( int 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 );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "added rwy point " << p << " at " << index );
|
||||
tri_v.push_back( index );
|
||||
|
||||
// use 'the' normal
|
||||
|
@ -906,6 +911,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
}
|
||||
}
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_INFO, "Adding pavement nodes and normals");
|
||||
for ( unsigned int k = 0; k < pvmt_polys.size(); ++k )
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "tri " << k);
|
||||
|
@ -925,6 +931,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
{
|
||||
p = tri_poly.get_pt( i, j );
|
||||
index = nodes.unique_add( p );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "added pvmnt point " << p << " at " << index );
|
||||
tri_v.push_back( index );
|
||||
|
||||
// use 'the' normal
|
||||
|
@ -942,6 +949,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
}
|
||||
}
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_INFO, "Adding line nodes and normals");
|
||||
for ( unsigned int k = 0; k < line_polys.size(); ++k )
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "tri " << k);
|
||||
|
@ -961,6 +969,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
{
|
||||
p = tri_poly.get_pt( i, j );
|
||||
index = nodes.unique_add( p );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "added line point " << p << " at " << index );
|
||||
tri_v.push_back( index );
|
||||
|
||||
// use 'the' normal
|
||||
|
@ -982,6 +991,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
std::vector< SGVec2f > base_txs;
|
||||
int_list base_tc;
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_INFO, "Adding base nodes and normals");
|
||||
for ( int i = 0; i < base_tris.contours(); ++i )
|
||||
{
|
||||
tri_v.clear();
|
||||
|
@ -990,9 +1000,8 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
for ( int 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 );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "added base point " << p << " at " << index );
|
||||
tri_v.push_back( index );
|
||||
|
||||
index = normals.unique_add( vn );
|
||||
|
@ -1025,14 +1034,12 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
// on rare occasion, one or more of the divided base points can be
|
||||
// missed. Make sure they are all in the node list so we can
|
||||
// build a proper skirt.
|
||||
|
||||
for ( int i = 0; i < divided_base.contours(); ++i )
|
||||
{
|
||||
for ( int 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) );
|
||||
index = nodes.unique_add( divided_base.get_pt(i, j) );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "added base point " << divided_base.get_pt(i, j) << " at " << index );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1044,7 +1051,6 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
// 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();
|
||||
|
||||
|
@ -1057,14 +1063,13 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
}
|
||||
|
||||
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 ...
|
||||
|
||||
// calculation min/max coordinates of airport area
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, " calculation min/max coordinates of airport area");
|
||||
SG_LOG(SG_GENERAL, SG_INFO, " calculation min/max coordinates of airport area");
|
||||
|
||||
Point3D min_deg(9999.0, 9999.0, 0), max_deg(-9999.0, -9999.0, 0);
|
||||
for ( unsigned int j = 0; j < nodes.get_node_list().size(); ++j )
|
||||
|
@ -1072,27 +1077,32 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
Point3D p = nodes.get_node_list()[j];
|
||||
if ( p.lon() < min_deg.lon() )
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "new min lon from node " << j << " is " << p.lon() );
|
||||
min_deg.setlon( p.lon() );
|
||||
}
|
||||
if ( p.lon() > max_deg.lon() )
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "new max lon from node " << j << " is " << p.lon() );
|
||||
max_deg.setlon( p.lon() );
|
||||
}
|
||||
if ( p.lat() < min_deg.lat() )
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "new min lat from node " << j << " is " << p.lat() );
|
||||
min_deg.setlat( p.lat() );
|
||||
}
|
||||
if ( p.lat() > max_deg.lat() )
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "new max lat from node " << j << " is " << p.lat() );
|
||||
max_deg.setlat( p.lat() );
|
||||
}
|
||||
}
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_INFO, "Before extending for lights: min = " << min_deg << " max = " << max_deg );
|
||||
|
||||
// extend the min/max coordinates of airport area to cover all
|
||||
// lights as well
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, " extend the min/max coordinates of airport area to cover all lights as well : num rwy lights is " << rwy_lights.size() );
|
||||
|
||||
for ( unsigned int i = 0; i < rwy_lights.size(); ++i )
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, " extend the min/max coordinates of airport area to cover all lights as well : rwy light " << i << "has " << rwy_lights[i].get_poly().get_contour(0).size() << " lights " );
|
||||
|
@ -1128,7 +1138,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
max_deg.setlon( max_deg.lon() + 0.01 * dlon );
|
||||
min_deg.setlat( min_deg.lat() - 0.01 * dlat );
|
||||
max_deg.setlat( max_deg.lat() + 0.01 * dlat );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "min = " << min_deg << " max = " << max_deg );
|
||||
SG_LOG(SG_GENERAL, SG_INFO, "min = " << min_deg << " max = " << max_deg );
|
||||
|
||||
TGAptSurface apt_surf( root, elev_src, min_deg, max_deg, average );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Airport surface created");
|
||||
|
|
|
@ -88,34 +88,42 @@ class BezNode
|
|||
public:
|
||||
BezNode( Point3D l ) : prev_cp(0.0f, 0.0f, 0.0f), next_cp(0.0f, 0.0f, 0.0f)
|
||||
{
|
||||
loc = l;
|
||||
mark = 0;
|
||||
loc = l;
|
||||
mark = 0;
|
||||
light = 0;
|
||||
term = false;
|
||||
close = false;
|
||||
}
|
||||
|
||||
BezNode( double lat, double lon ) : prev_cp(0.0f, 0.0f, 0.0f), next_cp(0.0f, 0.0f, 0.0f)
|
||||
{
|
||||
loc = Point3D( lon, lat, 0.0f );
|
||||
mark = 0;
|
||||
loc = Point3D( lon, lat, 0.0f );
|
||||
mark = 0;
|
||||
light = 0;
|
||||
term = false;
|
||||
close = false;
|
||||
}
|
||||
|
||||
BezNode( Point3D l, Point3D cp )
|
||||
{
|
||||
loc = l;
|
||||
loc = l;
|
||||
next_cp = cp;
|
||||
prev_cp = Mirror(cp);
|
||||
mark = 0;
|
||||
light = 0;
|
||||
mark = 0;
|
||||
light = 0;
|
||||
term = false;
|
||||
close = false;
|
||||
}
|
||||
|
||||
BezNode( double lat, double lon, double cp_lat, double cp_lon )
|
||||
{
|
||||
loc = Point3D( lon, lat, 0.0f );
|
||||
loc = Point3D( lon, lat, 0.0f );
|
||||
next_cp = Point3D( cp_lon, cp_lat, 0.0f );
|
||||
prev_cp = Mirror( next_cp );
|
||||
mark = 0;
|
||||
light = 0;
|
||||
mark = 0;
|
||||
light = 0;
|
||||
term = false;
|
||||
close = false;
|
||||
}
|
||||
|
||||
Point3D Mirror( Point3D pt )
|
||||
|
@ -144,6 +152,16 @@ public:
|
|||
return light;
|
||||
}
|
||||
|
||||
void SetClose( bool c )
|
||||
{
|
||||
close = c;
|
||||
}
|
||||
|
||||
void SetTerm( bool t )
|
||||
{
|
||||
term = t;
|
||||
}
|
||||
|
||||
bool IsAt( double lat, double lon )
|
||||
{
|
||||
return ( (loc.lat() == lat) && (loc.lon() == lon) );
|
||||
|
@ -199,6 +217,8 @@ private:
|
|||
Point3D next_cp;
|
||||
unsigned int mark;
|
||||
unsigned int light;
|
||||
bool term;
|
||||
bool close;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -132,7 +132,7 @@ void ClosedPoly::CloseCurContour()
|
|||
if (cur_feature)
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "We still have an active linear feature - add the first node to close it");
|
||||
cur_feature->Finish();
|
||||
cur_feature->Finish(true);
|
||||
|
||||
features.push_back(cur_feature);
|
||||
cur_feature = NULL;
|
||||
|
@ -535,6 +535,7 @@ int ClosedPoly::BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list
|
|||
SG_LOG(SG_GENERAL, SG_DEBUG, "BuildBtg: original poly has " << pre_tess.contours() << " contours");
|
||||
|
||||
// do this before clipping and generating the base
|
||||
pre_tess = remove_bad_contours( pre_tess );
|
||||
pre_tess = remove_dups( pre_tess );
|
||||
pre_tess = reduce_degeneracy( pre_tess );
|
||||
|
||||
|
@ -545,15 +546,36 @@ int ClosedPoly::BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list
|
|||
// SG_LOG(SG_GENERAL, SG_DEBUG, "BuildBtg: contour " << c << " pt " << pt << ": (" << pre_tess.get_pt(c, pt).x() << "," << pre_tess.get_pt(c, pt).y() << ")" );
|
||||
// }
|
||||
//}
|
||||
|
||||
//SG_LOG(SG_GENERAL, SG_DEBUG, "BuildBtg: original poly has " << pre_tess.contours() << " contours");
|
||||
//for (int i=0; i<pre_tess.contours(); i++)
|
||||
//{
|
||||
// SG_LOG(SG_GENERAL, SG_DEBUG, "BuildBtg: original countour " << i << " has " << pre_tess.contour_size(i) << " points" );
|
||||
//}
|
||||
|
||||
// grow pretess by a little bit
|
||||
pre_tess = tgPolygonExpand( pre_tess, 0.05); // 5cm
|
||||
//pre_tess = tgPolygonExpand( pre_tess, 0.05); // 5cm
|
||||
|
||||
TGSuperPoly sp;
|
||||
TGTexParams tp;
|
||||
|
||||
TGPolygon clipped = tgPolygonDiff( pre_tess, *accum );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "BuildBtg: clipped poly has " << clipped.contours() << " contours");
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "BuildBtg: expanded poly has " << pre_tess.contours() << " contours");
|
||||
for (int i=0; i<pre_tess.contours(); i++)
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "BuildBtg: expanded countour " << i << " has " << pre_tess.contour_size(i) << " points" );
|
||||
}
|
||||
|
||||
#if 1
|
||||
TGPolygon clipped = tgPolygonDiffClipper( pre_tess, *accum );
|
||||
#else
|
||||
TGPolygon clipped = tgPolygonDiff( pre_tess, *accum );
|
||||
#endif
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "BuildBtg: clipped poly has " << clipped.contours() << " contours");
|
||||
for (int i=0; i<clipped.contours(); i++)
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "BuildBtg: clipped poly countour " << i << " has " << clipped.contour_size(i) << " points" );
|
||||
}
|
||||
|
||||
TGPolygon split = tgPolygonSplitLongEdges( clipped, 400.0 );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "BuildBtg: split poly has " << split.contours() << " contours");
|
||||
|
||||
|
@ -564,7 +586,11 @@ int ClosedPoly::BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list
|
|||
|
||||
rwy_polys->push_back( sp );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "clipped = " << clipped.contours());
|
||||
#if 1
|
||||
*accum = tgPolygonUnionClipper( pre_tess, *accum );
|
||||
#else
|
||||
*accum = tgPolygonUnion( pre_tess, *accum );
|
||||
#endif
|
||||
tp = TGTexParams( pre_tess.get_pt(0,0), 5.0, 5.0, texture_heading );
|
||||
texparams->push_back( tp );
|
||||
|
||||
|
@ -581,10 +607,10 @@ int ClosedPoly::BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list
|
|||
safe_base = tgPolygonExpand( pre_tess, 50.0);
|
||||
|
||||
// add this to the airport clearing
|
||||
*apt_clearing = tgPolygonUnion( safe_base, *apt_clearing);
|
||||
*apt_clearing = tgPolygonUnionClipper( safe_base, *apt_clearing);
|
||||
|
||||
// and add the clearing to the base
|
||||
*apt_base = tgPolygonUnion( base, *apt_base );
|
||||
*apt_base = tgPolygonUnionClipper( base, *apt_base );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ Helipad::Helipad(char* definition)
|
|||
|
||||
// int fscanf(FILE *stream, const char *format, ...);
|
||||
sscanf(definition, "%s %lf %lf %lf %lf %lf %d %d %d %lf %d",
|
||||
&heli.designator, &heli.lat, &heli.lon, &heli.heading, &heli.length, &heli.width, &heli.surface,
|
||||
heli.designator, &heli.lat, &heli.lon, &heli.heading, &heli.length, &heli.width, &heli.surface,
|
||||
&heli.marking, &heli.shoulder, &heli.smoothness, &heli.edge_lights);
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Read helipad: (" << heli.lon << "," << heli.lat << ") heading: " << heli.heading << " length: " << heli.length << " width: " << heli.width );
|
||||
|
@ -131,7 +131,7 @@ void Helipad::BuildBtg( float alt_m,
|
|||
|
||||
// Now generate the helipad lights
|
||||
superpoly_list s = gen_helipad_lights();
|
||||
for ( int i = 0; i < s.size(); ++i ) {
|
||||
rwy_lights->push_back( s[i] );
|
||||
}
|
||||
for ( unsigned int i = 0; i < s.size(); ++i ) {
|
||||
rwy_lights->push_back( s[i] );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include "linearfeature.hxx"
|
||||
#include "math.h"
|
||||
|
||||
void LinearFeature::ConvertContour( BezContour* src )
|
||||
void LinearFeature::ConvertContour( BezContour* src, bool closed )
|
||||
{
|
||||
BezNode* prevNode;
|
||||
BezNode* curNode;
|
||||
|
@ -243,9 +243,9 @@ void LinearFeature::ConvertContour( BezContour* src )
|
|||
Point3D destLoc = nextNode->GetLoc();
|
||||
geo_inverse_wgs_84( curLoc.y(), curLoc.x(), destLoc.y(), destLoc.x(), &az1, &az2, &dist);
|
||||
|
||||
if (dist > 10.0)
|
||||
if (dist > 100.0)
|
||||
{
|
||||
int num_segs = (dist / 10.0f) + 1;
|
||||
int num_segs = (dist / 100.0f) + 1;
|
||||
|
||||
for (int p=0; p<num_segs; p++)
|
||||
{
|
||||
|
@ -267,21 +267,42 @@ void LinearFeature::ConvertContour( BezContour* src )
|
|||
// now set set prev and cur locations for the next iteration
|
||||
prevLoc = curLoc;
|
||||
curLoc = nextLoc;
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Set prevLoc = (" << prevLoc.x() << "," << prevLoc.y() << ") and curLoc = (" << curLoc.x() << "," << curLoc.y() << ")" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nextLoc = nextNode->GetLoc();
|
||||
|
||||
// just add the one vertex - dist is small
|
||||
points.push_back( curLoc );
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "adding Linear Anchor node at (" << curLoc.x() << "," << curLoc.y() << ")");
|
||||
|
||||
prevLoc = curLoc;
|
||||
curLoc = nextLoc;
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Set prevLoc = (" << prevLoc.x() << "," << prevLoc.y() << ") and curLoc = (" << curLoc.x() << "," << curLoc.y() << ")" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TEST TEST TEST : This should do it
|
||||
#if 1
|
||||
if (closed)
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Closed COntour : adding last node at (" << curLoc.x() << "," << curLoc.y() << ")");
|
||||
|
||||
// need to add the markings for last segment
|
||||
points.push_back( curLoc );
|
||||
}
|
||||
#endif
|
||||
// TEST TEST TEST
|
||||
|
||||
// check for marking that goes all the way to the end...
|
||||
if (cur_mark)
|
||||
{
|
||||
if (cur_mark)
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "LinearFeature::ConvertContour Marking from " << cur_mark->start_idx << " with type " << cur_mark->type << " ends at the end of the contour: " << points.size() );
|
||||
|
||||
cur_mark->end_idx = points.size()-1;
|
||||
|
@ -290,8 +311,8 @@ void LinearFeature::ConvertContour( BezContour* src )
|
|||
}
|
||||
|
||||
// check for lighting that goes all the way to the end...
|
||||
if (cur_light)
|
||||
{
|
||||
if (cur_light)
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "LinearFeature::ConvertContour Lighting from " << cur_light->start_idx << " with type " << cur_light->type << " ends at the end of the contour: " << points.size() );
|
||||
|
||||
cur_light->end_idx = points.size()-1;
|
||||
|
@ -477,7 +498,7 @@ Point3D midpoint( Point3D p0, Point3D p1 )
|
|||
return Point3D( (p0.x() + p1.x()) / 2, (p0.y() + p1.y()) / 2, (p0.z() + p1.z()) / 2 );
|
||||
}
|
||||
|
||||
int LinearFeature::Finish()
|
||||
int LinearFeature::Finish( bool closed )
|
||||
{
|
||||
TGPolygon poly;
|
||||
TGPolygon normals_poly;
|
||||
|
@ -499,7 +520,7 @@ int LinearFeature::Finish()
|
|||
// create the inner and outer boundaries to generate polys
|
||||
// this generates 2 point lists for the contours, and remembers
|
||||
// the start stop points for markings and lights
|
||||
ConvertContour( &contour );
|
||||
ConvertContour( &contour, closed );
|
||||
|
||||
// now generate the supoerpoly and texparams lists for markings
|
||||
for (unsigned int i=0; i<marks.size(); i++)
|
||||
|
@ -782,11 +803,8 @@ int LinearFeature::Finish()
|
|||
cur_light_dist += light_delta;
|
||||
}
|
||||
|
||||
// add the remaining distance to the last light
|
||||
// cur_light_dist += modf( dist, &intpart );
|
||||
|
||||
// remove
|
||||
cur_light_dist = fmod (cur_light_dist, light_delta);
|
||||
// start next segment at the correct distance
|
||||
cur_light_dist = cur_light_dist - dist;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -817,24 +835,28 @@ int LinearFeature::BuildBtg(float alt_m, superpoly_list* line_polys, texparams_l
|
|||
{
|
||||
TGPolygon poly;
|
||||
TGPolygon clipped;
|
||||
//TGPolygon split;
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "\nLinearFeature::BuildBtg: " << description);
|
||||
|
||||
for ( unsigned int i = 0; i < marking_polys.size(); i++)
|
||||
{
|
||||
poly = marking_polys[i].get_poly();
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "LinearFeature::BuildBtg: clipping poly " << i << " of " << marking_polys.size() );
|
||||
#if 1
|
||||
clipped = tgPolygonDiff( poly, *line_accum );
|
||||
#else
|
||||
clipped = tgPolygonDiffClipper( poly, *line_accum );
|
||||
|
||||
// TGPolygon split = tgPolygonSplitLongEdges( clipped, 400.0 );
|
||||
// SG_LOG(SG_GENERAL, SG_DEBUG, "LinearFeature::BuildBtg: split poly has " << split.contours() << " contours");
|
||||
#endif
|
||||
|
||||
marking_polys[i].set_poly( clipped );
|
||||
line_polys->push_back( marking_polys[i] );
|
||||
|
||||
#if 1
|
||||
*line_accum = tgPolygonUnion( poly, *line_accum );
|
||||
#else
|
||||
*line_accum = tgPolygonUnionClipper( poly, *line_accum );
|
||||
#endif
|
||||
|
||||
line_tps->push_back( marking_tps[i] );
|
||||
}
|
||||
|
||||
|
|
|
@ -91,8 +91,9 @@ public:
|
|||
contour.push_back( b );
|
||||
}
|
||||
|
||||
int Finish();
|
||||
int Finish( bool closed );
|
||||
int BuildBtg( float alt_m, superpoly_list* line_polys, texparams_list* line_tps, ClipPolyType* line_accum, superpoly_list* lights );
|
||||
int BuildBtg( float alt_m, superpoly_list* line_polys, texparams_list* line_tps, Polygons* line_accum, superpoly_list* lights );
|
||||
|
||||
private:
|
||||
Point3D OffsetPointFirst( Point3D *cur, Point3D *next, double offset_by );
|
||||
|
@ -108,7 +109,7 @@ private:
|
|||
LightingList lights;
|
||||
Lighting* cur_light;
|
||||
|
||||
void ConvertContour( BezContour* src );
|
||||
void ConvertContour( BezContour* src, bool closed );
|
||||
|
||||
// text description
|
||||
string description;
|
||||
|
|
|
@ -19,10 +19,15 @@ Beacon::Beacon( char* definition )
|
|||
Sign::Sign( char* definition )
|
||||
{
|
||||
char sgdef[256];
|
||||
double def_heading;
|
||||
|
||||
sscanf(definition, "%lf %lf %lf %d %d %s", &lat, &lon, &heading, &reserved, &size, sgdef );
|
||||
sscanf(definition, "%lf %lf %lf %d %d %s", &lat, &lon, &def_heading, &reserved, &size, sgdef );
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Read Sign: (" << lon << "," << lat << ") heading " << heading << " size " << size << " definition: " << sgdef );
|
||||
// 850 format sign heading is the heading which points away from the visible numbers
|
||||
// Flightgear wants the heading to be the heading in which the sign is read
|
||||
heading = -def_heading + 360.0;
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Read Sign: (" << lon << "," << lat << ") heading " << def_heading << " size " << size << " definition: " << sgdef << " calc view heading: " << heading );
|
||||
|
||||
sgn_def = sgdef;
|
||||
}
|
||||
|
|
|
@ -309,7 +309,6 @@ void Parser::AddAirports( long start_pos, float min_lat, float min_lon, float ma
|
|||
void Parser::Parse()
|
||||
{
|
||||
char tmp[2048];
|
||||
int i;
|
||||
struct timeval parse_start;
|
||||
struct timeval parse_end;
|
||||
struct timeval parse_time;
|
||||
|
@ -325,7 +324,7 @@ void Parser::Parse()
|
|||
}
|
||||
|
||||
// for each position in parse_positions, parse an airport
|
||||
for (i=0; i<parse_positions.size(); i++)
|
||||
for ( unsigned int i=0; i < parse_positions.size(); i++)
|
||||
{
|
||||
SetState(STATE_NONE);
|
||||
in.clear();
|
||||
|
@ -502,6 +501,9 @@ BezNode* Parser::ParseNode( int type, char* line, BezNode* prevNode )
|
|||
}
|
||||
}
|
||||
|
||||
curNode->SetTerm( term );
|
||||
curNode->SetClose( close );
|
||||
|
||||
return curNode;
|
||||
}
|
||||
|
||||
|
@ -533,7 +535,7 @@ ClosedPoly* Parser::ParsePavement( char* line )
|
|||
char *d = NULL;
|
||||
int numParams;
|
||||
|
||||
numParams = sscanf(line, "%d %f %f %ls", &st, &s, &th, desc);
|
||||
numParams = sscanf(line, "%d %f %f %s", &st, &s, &th, desc);
|
||||
|
||||
if (numParams == 4)
|
||||
{
|
||||
|
@ -557,7 +559,7 @@ ClosedPoly* Parser::ParseBoundary( char* line )
|
|||
char *d = NULL;
|
||||
int numParams;
|
||||
|
||||
numParams = sscanf(line, "%ls", desc);
|
||||
numParams = sscanf(line, "%s", desc);
|
||||
|
||||
if (numParams == 1)
|
||||
{
|
||||
|
@ -595,6 +597,8 @@ int Parser::SetState( int state )
|
|||
}
|
||||
|
||||
cur_state = state;
|
||||
|
||||
return cur_state;
|
||||
}
|
||||
|
||||
// TODO: This should be a loop here, and main should just pass the file name and airport code...
|
||||
|
@ -756,7 +760,7 @@ int Parser::ParseLine(char* line)
|
|||
}
|
||||
if (cur_airport)
|
||||
{
|
||||
cur_feat->Finish();
|
||||
cur_feat->Finish( true );
|
||||
cur_airport->AddFeature( cur_feat );
|
||||
}
|
||||
cur_feat = NULL;
|
||||
|
@ -790,7 +794,7 @@ int Parser::ParseLine(char* line)
|
|||
}
|
||||
if (cur_airport)
|
||||
{
|
||||
cur_feat->Finish();
|
||||
cur_feat->Finish( false );
|
||||
cur_airport->AddFeature( cur_feat );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,8 +40,8 @@ Runway::Runway(char* definition)
|
|||
// int fscanf(FILE *stream, const char *format, ...);
|
||||
sscanf(definition, "%lf %d %d %lf %d %d %d %s %lf %lf %lf %lf %d %d %d %d %s %lf %lf %lf %lf %d %d %d %d",
|
||||
&rwy.width, &rwy.surface, &rwy.shoulder, &rwy.smoothness, &rwy.centerline_lights, &rwy.edge_lights, &rwy.dist_remain_signs,
|
||||
&rwy.rwnum[0], &rwy.lat[0], &rwy.lon[0], &rwy.threshold[0], &rwy.overrun[0], &rwy.marking[0], &rwy.approach_lights[0], &rwy.tz_lights[0], &rwy.reil[0],
|
||||
&rwy.rwnum[1], &rwy.lat[1], &rwy.lon[1], &rwy.threshold[1], &rwy.overrun[1], &rwy.marking[1], &rwy.approach_lights[1], &rwy.tz_lights[1], &rwy.reil[1]
|
||||
rwy.rwnum[0], &rwy.lat[0], &rwy.lon[0], &rwy.threshold[0], &rwy.overrun[0], &rwy.marking[0], &rwy.approach_lights[0], &rwy.tz_lights[0], &rwy.reil[0],
|
||||
rwy.rwnum[1], &rwy.lat[1], &rwy.lon[1], &rwy.threshold[1], &rwy.overrun[1], &rwy.marking[1], &rwy.approach_lights[1], &rwy.tz_lights[1], &rwy.reil[1]
|
||||
);
|
||||
|
||||
// calculate runway heading and length (used a lot)
|
||||
|
@ -53,7 +53,7 @@ Runway::Runway(char* definition)
|
|||
|
||||
WaterRunway::WaterRunway(char* definition)
|
||||
{
|
||||
sscanf(definition, "%lf %d %s %lf %lf %s %lf %lf", &width, &buoys, &rwnum[0], &lat[0], &lon[0], &rwnum[1], &lat[1], &lon[1]);
|
||||
sscanf(definition, "%lf %d %s %lf %lf %s %lf %lf", &width, &buoys, rwnum[0], &lat[0], &lon[0], rwnum[1], &lat[1], &lon[1]);
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Read water runway: (" << lon[0] << "," << lat[0] << ") to (" << lon[1] << "," << lat[1] << ") width: " << width << " buoys = " << buoys );
|
||||
}
|
||||
|
@ -175,4 +175,6 @@ int Runway::BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list* te
|
|||
// and add the clearing to the base
|
||||
*apt_base = tgPolygonUnion( base, *apt_base );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -372,6 +372,9 @@ void Runway::BuildShoulder( float alt_m,
|
|||
int numSegs = (rwy.length / max_dist) + 1;
|
||||
double dist = rwy.length / (double)numSegs;
|
||||
|
||||
//int numSegs = 1;
|
||||
//double dist = rwy.length;
|
||||
|
||||
// Create both shoulder sides
|
||||
for (int i=0; i<2; ++i){
|
||||
double step;
|
||||
|
@ -395,18 +398,25 @@ void Runway::BuildShoulder( float alt_m,
|
|||
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 );
|
||||
TGPolygon shoulderSegment = gen_wgs84_rect( lat, lon, rwy.heading, dist, shoulder_width+0.1 );
|
||||
|
||||
TGSuperPoly sp;
|
||||
TGTexParams tp;
|
||||
#if 1
|
||||
TGPolygon clipped = tgPolygonDiff( shoulderSegment, *accum );
|
||||
|
||||
#else
|
||||
TGPolygon clipped = tgPolygonDiffClipper( shoulderSegment, *accum );
|
||||
#endif
|
||||
sp.erase();
|
||||
sp.set_poly( clipped );
|
||||
sp.set_material( shoulder_surface );
|
||||
rwy_polys->push_back( sp );
|
||||
|
||||
#if 1
|
||||
*accum = tgPolygonUnion( shoulderSegment, *accum );
|
||||
#else
|
||||
*accum = tgPolygonUnionClipper( shoulderSegment, *accum );
|
||||
#endif
|
||||
|
||||
tp = TGTexParams( shoulderSegment.get_pt(0,0), -shoulder_width, dist, rwy.heading );
|
||||
if (i == 0){
|
||||
|
|
|
@ -46,7 +46,8 @@
|
|||
#include <simgear/math/SGMath.hxx>
|
||||
|
||||
|
||||
const double fgPoint3_Epsilon = 0.0000001;
|
||||
//const double fgPoint3_Epsilon = 0.0000001;
|
||||
const double fgPoint3_Epsilon = 0.000001;
|
||||
|
||||
enum {PX, PY, PZ}; // axes
|
||||
|
||||
|
|
|
@ -349,16 +349,12 @@ TGPolygon polygon_tesselate_alt( TGPolygon &p, bool verbose ) {
|
|||
|
||||
// Bail right away if polygon is empty
|
||||
if ( p.contours() == 0 ) {
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
// 1. Robustly find a point inside each contour that is not
|
||||
// inside any other contour
|
||||
calc_points_inside( p );
|
||||
for ( i = 0; i < p.contours(); ++i ) {
|
||||
//cout << "final point inside =" << p.get_point_inside( i )
|
||||
// << endl;
|
||||
}
|
||||
|
||||
// 2. Do a final triangulation of the entire polygon
|
||||
triele_list trieles;
|
||||
|
@ -366,8 +362,21 @@ TGPolygon polygon_tesselate_alt( TGPolygon &p, bool verbose ) {
|
|||
string flags;
|
||||
if (verbose) {
|
||||
flags = "pzqenXYY";
|
||||
// flags = "pzqenXY"; // allow adding interior points
|
||||
} else {
|
||||
flags = "pzqenXYYQ";
|
||||
// flags = "pzqenXYQ"; // allow adding interior points
|
||||
}
|
||||
|
||||
// check the input for nan point
|
||||
for (int c = 0; c < p.contours(); c++) {
|
||||
point_list contour = p.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 before tesselation\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( polygon_tesselate( p, extra_nodes, trieles, nodes, flags ) >= 0 ) {
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,10 +1,10 @@
|
|||
/*******************************************************************************
|
||||
* *
|
||||
* Author : Angus Johnson *
|
||||
* Version : 4.5.5 *
|
||||
* Date : 6 October 2011 *
|
||||
* Version : 4.6.5 *
|
||||
* Date : 17 January 2011 *
|
||||
* Website : http://www.angusj.com *
|
||||
* Copyright : Angus Johnson 2010-2011 *
|
||||
* Copyright : Angus Johnson 2010-2012 *
|
||||
* *
|
||||
* License: *
|
||||
* Use, modification & distribution is subject to Boost Software License Ver 1. *
|
||||
|
@ -21,6 +21,14 @@
|
|||
* Springer; 1 edition (January 4, 2005) *
|
||||
* http://books.google.com/books?q=vatti+clipping+agoston *
|
||||
* *
|
||||
* See also: *
|
||||
* "Polygon Offsetting by Computing Winding Numbers" *
|
||||
* Paper no. DETC2005-85513 pp. 565-575 *
|
||||
* ASME 2005 International Design Engineering Technical Conferences *
|
||||
* and Computers and Information in Engineering Conference (IDETC/CIE2005) *
|
||||
* September 24–28, 2005 , Long Beach, California, USA *
|
||||
* http://www.me.berkeley.edu/~mcmains/pubs/DAC05OffsetPolygon.pdf *
|
||||
* *
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef clipper_hpp
|
||||
|
@ -39,8 +47,8 @@ enum PolyType { ptSubject, ptClip };
|
|||
//By far the most widely used winding rules for polygon filling are
|
||||
//EvenOdd & NonZero (GDI, GDI+, XLib, OpenGL, Cairo, AGG, Quartz, SVG, Gr32)
|
||||
//Others rules include Positive, Negative and ABS_GTR_EQ_TWO (only in OpenGL)
|
||||
//see http://www.songho.ca/opengl/gl_tessellation.html#winding_rules
|
||||
enum PolyFillType { pftEvenOdd, pftNonZero };
|
||||
//see http://glprogramming.com/red/chapter11.html
|
||||
enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative };
|
||||
|
||||
typedef signed long long long64;
|
||||
typedef unsigned long long ulong64;
|
||||
|
@ -71,6 +79,9 @@ bool Orientation(const Polygon &poly);
|
|||
double Area(const Polygon &poly);
|
||||
void OffsetPolygons(const Polygons &in_polys, Polygons &out_polys,
|
||||
double delta, JoinType jointype = jtSquare, double MiterLimit = 2);
|
||||
void SimplifyPolygon(const Polygon &in_poly, Polygons &out_polys);
|
||||
void SimplifyPolygons(const Polygons &in_polys, Polygons &out_polys);
|
||||
void SimplifyPolygons(Polygons &polys);
|
||||
|
||||
void ReversePoints(Polygon& p);
|
||||
void ReversePoints(Polygons& p);
|
||||
|
@ -193,13 +204,13 @@ public:
|
|||
Clipper();
|
||||
~Clipper();
|
||||
bool Execute(ClipType clipType,
|
||||
Polygons &solution,
|
||||
PolyFillType subjFillType = pftEvenOdd,
|
||||
PolyFillType clipFillType = pftEvenOdd);
|
||||
Polygons &solution,
|
||||
PolyFillType subjFillType = pftEvenOdd,
|
||||
PolyFillType clipFillType = pftEvenOdd);
|
||||
bool Execute(ClipType clipType,
|
||||
ExPolygons &solution,
|
||||
PolyFillType subjFillType = pftEvenOdd,
|
||||
PolyFillType clipFillType = pftEvenOdd);
|
||||
ExPolygons &solution,
|
||||
PolyFillType subjFillType = pftEvenOdd,
|
||||
PolyFillType clipFillType = pftEvenOdd);
|
||||
void Clear();
|
||||
bool ReverseSolution() {return m_ReverseOutput;};
|
||||
void ReverseSolution(bool value) {m_ReverseOutput = value;};
|
||||
|
@ -221,8 +232,8 @@ private:
|
|||
bool m_ReverseOutput;
|
||||
void DisposeScanbeamList();
|
||||
void SetWindingCount(TEdge& edge);
|
||||
bool IsNonZeroFillType(const TEdge& edge) const;
|
||||
bool IsNonZeroAltFillType(const TEdge& edge) const;
|
||||
bool IsEvenOddFillType(const TEdge& edge) const;
|
||||
bool IsEvenOddAltFillType(const TEdge& edge) const;
|
||||
void InsertScanbeam(const long64 Y);
|
||||
long64 PopScanbeam();
|
||||
void InsertLocalMinimaIntoAEL(const long64 botY);
|
||||
|
|
|
@ -540,6 +540,38 @@ void make_tg_poly_from_clipper( const Polygons& in, TGPolygon *out )
|
|||
}
|
||||
}
|
||||
|
||||
Polygons clipper_simplify( ExPolygons &in )
|
||||
{
|
||||
Polygons out;
|
||||
Polygon contour;
|
||||
|
||||
for (unsigned int i=0; i<in.size(); i++)
|
||||
{
|
||||
const struct ExPolygon* pg = &in[i];
|
||||
|
||||
// first the boundary
|
||||
contour = pg->outer;
|
||||
if ( !Orientation( contour ) ) {
|
||||
ReversePoints( contour );
|
||||
}
|
||||
out.push_back( contour );
|
||||
|
||||
// then the holes
|
||||
for (unsigned int j = 0; j < pg->holes.size(); j++)
|
||||
{
|
||||
contour = pg->holes[j];
|
||||
if ( Orientation( contour ) ) {
|
||||
ReversePoints( contour );
|
||||
}
|
||||
out.push_back( contour );
|
||||
}
|
||||
}
|
||||
|
||||
// Now simplify
|
||||
SimplifyPolygons(out);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
TGPolygon polygon_clip_clipper( clip_op poly_op, const TGPolygon& subject, const TGPolygon& clip )
|
||||
{
|
||||
|
@ -572,7 +604,11 @@ TGPolygon polygon_clip_clipper( clip_op poly_op, const TGPolygon& subject, const
|
|||
c.AddPolygons(clipper_clip, ptClip);
|
||||
|
||||
c.Execute(op, clipper_result, pftEvenOdd, pftEvenOdd);
|
||||
make_tg_poly_from_clipper_ex( clipper_result, &result );
|
||||
|
||||
// verify each result is simple
|
||||
Polygons simple_result = clipper_simplify( clipper_result );
|
||||
|
||||
make_tg_poly_from_clipper( simple_result, &result );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -608,7 +644,6 @@ TGPolygon tgPolygonUnionClipper( const TGPolygon& subject, const TGPolygon& clip
|
|||
return polygon_clip_clipper( POLY_UNION, subject, clip );
|
||||
}
|
||||
|
||||
|
||||
// canonify the polygon winding, outer contour must be anti-clockwise,
|
||||
// all inner contours must be clockwise.
|
||||
TGPolygon polygon_canonify( const TGPolygon& in_poly ) {
|
||||
|
|
|
@ -275,7 +275,6 @@ TGPolygon tgPolygonDiffClipper( const TGPolygon& subject, const TGPolygon& clip
|
|||
// Union
|
||||
TGPolygon tgPolygonUnionClipper( const TGPolygon& subject, const TGPolygon& clip );
|
||||
|
||||
|
||||
// Expand / Shrink
|
||||
TGPolygon tgPolygonExpand(const TGPolygon &poly, double delta);
|
||||
|
||||
|
|
Loading…
Reference in a new issue