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 )
|
void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
||||||
{
|
{
|
||||||
ClipPolyType accum;
|
ClipPolyType accum;
|
||||||
|
|
||||||
|
// try to keep line accumulator in clipper format for speed...
|
||||||
ClipPolyType line_accum;
|
ClipPolyType line_accum;
|
||||||
|
|
||||||
TGPolygon apt_base;
|
TGPolygon apt_base;
|
||||||
TGPolygon apt_clearing;
|
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++ )
|
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() );
|
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 );
|
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++ )
|
for ( unsigned int i=0; i<lightobjects.size(); i++ )
|
||||||
{
|
{
|
||||||
SG_LOG(SG_GENERAL, SG_INFO, "Build runway light " << i << " of " << lightobjects.size());
|
SG_LOG(SG_GENERAL, SG_INFO, "Build runway light " << i << " of " << lightobjects.size());
|
||||||
|
|
||||||
lightobjects[i]->BuildBtg( altitude, &rwy_lights );
|
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++ )
|
for ( unsigned int i=0; i<helipads.size(); i++ )
|
||||||
{
|
{
|
||||||
SG_LOG(SG_GENERAL, SG_INFO, "Build helipad " << i << " of " << helipads.size());
|
SG_LOG(SG_GENERAL, SG_INFO, "Build helipad " << i << " of " << helipads.size());
|
||||||
|
|
||||||
if (boundary)
|
if (boundary)
|
||||||
{
|
{
|
||||||
helipads[i]->BuildBtg( altitude, &rwy_polys, &rwy_tps, &rwy_lights, &accum, NULL, NULL );
|
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());
|
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)
|
if (boundary)
|
||||||
{
|
{
|
||||||
pavements[i]->BuildBtg( altitude, &pvmt_polys, &pvmt_tps, &accum, NULL, NULL );
|
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)
|
if (boundary)
|
||||||
{
|
{
|
||||||
SG_LOG(SG_GENERAL, SG_INFO, "Build user defined boundary " );
|
SG_LOG(SG_GENERAL, SG_INFO, "Build user defined boundary " );
|
||||||
|
|
||||||
boundary->BuildBtg( altitude, &apt_base, &apt_clearing );
|
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"
|
// add segments to polygons to remove any possible "T"
|
||||||
// intersections
|
// intersections
|
||||||
TGTriNodes tmp_nodes;
|
TGTriNodes tmp_pvmt_nodes;
|
||||||
|
TGTriNodes tmp_feat_nodes;
|
||||||
|
|
||||||
// build temporary node list from runways...
|
// build temporary node list from runways...
|
||||||
SG_LOG(SG_GENERAL, SG_INFO, "Build Node List " );
|
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 )
|
for ( int j = 0; j < poly.contour_size( i ); ++j )
|
||||||
{
|
{
|
||||||
tmp_nodes.unique_add( poly.get_pt(i, j) );
|
tmp_pvmt_nodes.unique_add( poly.get_pt(i, j) );
|
||||||
//tmp_nodes.course_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 )
|
for ( int j = 0; j < poly.contour_size( i ); ++j )
|
||||||
{
|
{
|
||||||
tmp_nodes.unique_add( poly.get_pt(i, j) );
|
tmp_pvmt_nodes.unique_add( poly.get_pt(i, j) );
|
||||||
//tmp_nodes.course_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 )
|
for ( unsigned int k = 0; k < line_polys.size(); ++k )
|
||||||
{
|
{
|
||||||
TGPolygon poly = line_polys[k].get_poly();
|
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 )
|
for ( int j = 0; j < poly.contour_size( i ); ++j )
|
||||||
{
|
{
|
||||||
tmp_nodes.unique_add( poly.get_pt(i, j) );
|
tmp_feat_nodes.unique_add( poly.get_pt(i, j) );
|
||||||
//tmp_nodes.course_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 )
|
for ( int j = 0; j < base_poly.contour_size( i ); ++j )
|
||||||
{
|
{
|
||||||
tmp_nodes.unique_add( base_poly.get_pt(i, j) );
|
tmp_pvmt_nodes.unique_add( base_poly.get_pt(i, j) );
|
||||||
//tmp_nodes.course_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 )
|
for ( int j = 0; j < divided_base.contour_size( i ); ++j )
|
||||||
{
|
{
|
||||||
tmp_nodes.unique_add( divided_base.get_pt(i, j) );
|
tmp_pvmt_nodes.unique_add( divided_base.get_pt(i, j) );
|
||||||
//tmp_nodes.course_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 )
|
for ( unsigned int k = 0; k < rwy_polys.size(); ++k )
|
||||||
{
|
{
|
||||||
TGPolygon poly = rwy_polys[k].get_poly();
|
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());
|
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after add nodes = " << poly.total_size());
|
||||||
|
|
||||||
rwy_polys[k].set_poly( poly );
|
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 )
|
for ( unsigned int k = 0; k < pvmt_polys.size(); ++k )
|
||||||
{
|
{
|
||||||
TGPolygon poly = pvmt_polys[k].get_poly();
|
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());
|
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after add nodes = " << poly.total_size());
|
||||||
|
|
||||||
pvmt_polys[k].set_poly( poly );
|
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 )
|
for ( unsigned int k = 0; k < line_polys.size(); ++k )
|
||||||
{
|
{
|
||||||
TGPolygon poly = line_polys[k].get_poly();
|
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());
|
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after add nodes = " << poly.total_size());
|
||||||
|
|
||||||
line_polys[k].set_poly( poly );
|
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, "add nodes base ");
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, " before: " << base_poly);
|
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);
|
SG_LOG(SG_GENERAL, SG_DEBUG, " after adding tmp_nodes: " << base_poly);
|
||||||
|
|
||||||
base_poly = remove_cycles( 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();
|
TGPolygon poly = pvmt_polys[i].get_poly();
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if ( i == 62 ) {
|
if ( i == 0 ) {
|
||||||
tgChopNormalPolygon( "/home/pete", "Base", poly, false );
|
tgChopNormalPolygon( "/home/pete", "Base", poly, false );
|
||||||
verbose_triangulation = true;
|
verbose_triangulation = true;
|
||||||
|
} else {
|
||||||
|
verbose_triangulation = false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -787,9 +788,11 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
||||||
TGPolygon poly = line_polys[i].get_poly();
|
TGPolygon poly = line_polys[i].get_poly();
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if ( i == 62 ) {
|
if ( i == 4558 ) {
|
||||||
tgChopNormalPolygon( "/home/pete", "Base", poly, false );
|
tgChopNormalPolygon( "/home/pete", "Base", poly, false );
|
||||||
verbose_triangulation = true;
|
verbose_triangulation = true;
|
||||||
|
} else {
|
||||||
|
verbose_triangulation = false;
|
||||||
}
|
}
|
||||||
#endif
|
#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 ");
|
SG_LOG(SG_GENERAL, SG_INFO, "Tesselating base poly ");
|
||||||
TGPolygon base_tris = polygon_tesselate_alt( base_poly, verbose_triangulation );
|
TGPolygon base_tris = polygon_tesselate_alt( base_poly, verbose_triangulation );
|
||||||
|
SG_LOG(SG_GENERAL, SG_INFO, "Tesselating base poly - done");
|
||||||
|
|
||||||
|
|
||||||
gettimeofday(&triangulation_end, NULL);
|
gettimeofday(&triangulation_end, NULL);
|
||||||
timersub(&triangulation_end, &triangulation_start, &triangulation_time);
|
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_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 )
|
for ( unsigned int k = 0; k < rwy_polys.size(); ++k )
|
||||||
{
|
{
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, "tri " << 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 )
|
for ( int j = 0; j < tri_poly.contour_size(i); ++j )
|
||||||
{
|
{
|
||||||
p = tri_poly.get_pt( i, j );
|
p = tri_poly.get_pt( i, j );
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, "adding runway point = " << p);
|
|
||||||
|
|
||||||
index = nodes.unique_add( p );
|
index = nodes.unique_add( p );
|
||||||
|
SG_LOG(SG_GENERAL, SG_DEBUG, "added rwy point " << p << " at " << index );
|
||||||
tri_v.push_back( index );
|
tri_v.push_back( index );
|
||||||
|
|
||||||
// use 'the' normal
|
// 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 )
|
for ( unsigned int k = 0; k < pvmt_polys.size(); ++k )
|
||||||
{
|
{
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, "tri " << 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 );
|
p = tri_poly.get_pt( i, j );
|
||||||
index = nodes.unique_add( p );
|
index = nodes.unique_add( p );
|
||||||
|
SG_LOG(SG_GENERAL, SG_DEBUG, "added pvmnt point " << p << " at " << index );
|
||||||
tri_v.push_back( index );
|
tri_v.push_back( index );
|
||||||
|
|
||||||
// use 'the' normal
|
// 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 )
|
for ( unsigned int k = 0; k < line_polys.size(); ++k )
|
||||||
{
|
{
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, "tri " << 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 );
|
p = tri_poly.get_pt( i, j );
|
||||||
index = nodes.unique_add( p );
|
index = nodes.unique_add( p );
|
||||||
|
SG_LOG(SG_GENERAL, SG_DEBUG, "added line point " << p << " at " << index );
|
||||||
tri_v.push_back( index );
|
tri_v.push_back( index );
|
||||||
|
|
||||||
// use 'the' normal
|
// use 'the' normal
|
||||||
|
@ -982,6 +991,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
||||||
std::vector< SGVec2f > base_txs;
|
std::vector< SGVec2f > base_txs;
|
||||||
int_list base_tc;
|
int_list base_tc;
|
||||||
|
|
||||||
|
SG_LOG(SG_GENERAL, SG_INFO, "Adding base nodes and normals");
|
||||||
for ( int i = 0; i < base_tris.contours(); ++i )
|
for ( int i = 0; i < base_tris.contours(); ++i )
|
||||||
{
|
{
|
||||||
tri_v.clear();
|
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 )
|
for ( int j = 0; j < base_tris.contour_size(i); ++j )
|
||||||
{
|
{
|
||||||
p = base_tris.get_pt( i, j );
|
p = base_tris.get_pt( i, j );
|
||||||
|
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, "adding base point " << p);
|
|
||||||
index = nodes.unique_add( p );
|
index = nodes.unique_add( p );
|
||||||
|
SG_LOG(SG_GENERAL, SG_DEBUG, "added base point " << p << " at " << index );
|
||||||
tri_v.push_back( index );
|
tri_v.push_back( index );
|
||||||
|
|
||||||
index = normals.unique_add( vn );
|
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
|
// 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
|
// missed. Make sure they are all in the node list so we can
|
||||||
// build a proper skirt.
|
// build a proper skirt.
|
||||||
|
|
||||||
for ( int i = 0; i < divided_base.contours(); ++i )
|
for ( int i = 0; i < divided_base.contours(); ++i )
|
||||||
{
|
{
|
||||||
for ( int j = 0; j < divided_base.contour_size( i ); ++j )
|
for ( int j = 0; j < divided_base.contour_size( i ); ++j )
|
||||||
{
|
{
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, "adding divided base point " << p);
|
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 );
|
||||||
nodes.unique_add( divided_base.get_pt(i, j) );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.
|
// airport is located in a bowl or on a hill.
|
||||||
|
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, " calcaverage elevation");
|
SG_LOG(SG_GENERAL, SG_DEBUG, " calcaverage elevation");
|
||||||
|
|
||||||
{
|
{
|
||||||
point_list dbg = nodes.get_node_list();
|
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() );
|
double average = tgAverageElevation( root, elev_src, nodes.get_node_list() );
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, " done");
|
|
||||||
|
|
||||||
// cout << "average airport elevation = " << average << endl;
|
// cout << "average airport elevation = " << average << endl;
|
||||||
|
|
||||||
// Now build the fitted airport surface ...
|
// Now build the fitted airport surface ...
|
||||||
|
|
||||||
// calculation min/max coordinates of airport area
|
// 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);
|
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 )
|
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];
|
Point3D p = nodes.get_node_list()[j];
|
||||||
if ( p.lon() < min_deg.lon() )
|
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() );
|
min_deg.setlon( p.lon() );
|
||||||
}
|
}
|
||||||
if ( p.lon() > max_deg.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() );
|
max_deg.setlon( p.lon() );
|
||||||
}
|
}
|
||||||
if ( p.lat() < min_deg.lat() )
|
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() );
|
min_deg.setlat( p.lat() );
|
||||||
}
|
}
|
||||||
if ( p.lat() > max_deg.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() );
|
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
|
// extend the min/max coordinates of airport area to cover all
|
||||||
// lights as well
|
// 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() );
|
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 )
|
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 " );
|
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 );
|
max_deg.setlon( max_deg.lon() + 0.01 * dlon );
|
||||||
min_deg.setlat( min_deg.lat() - 0.01 * dlat );
|
min_deg.setlat( min_deg.lat() - 0.01 * dlat );
|
||||||
max_deg.setlat( max_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 );
|
TGAptSurface apt_surf( root, elev_src, min_deg, max_deg, average );
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Airport surface created");
|
SG_LOG(SG_GENERAL, SG_DEBUG, "Airport surface created");
|
||||||
|
|
|
@ -88,34 +88,42 @@ class BezNode
|
||||||
public:
|
public:
|
||||||
BezNode( Point3D l ) : prev_cp(0.0f, 0.0f, 0.0f), next_cp(0.0f, 0.0f, 0.0f)
|
BezNode( Point3D l ) : prev_cp(0.0f, 0.0f, 0.0f), next_cp(0.0f, 0.0f, 0.0f)
|
||||||
{
|
{
|
||||||
loc = l;
|
loc = l;
|
||||||
mark = 0;
|
mark = 0;
|
||||||
light = 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)
|
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 );
|
loc = Point3D( lon, lat, 0.0f );
|
||||||
mark = 0;
|
mark = 0;
|
||||||
light = 0;
|
light = 0;
|
||||||
|
term = false;
|
||||||
|
close = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
BezNode( Point3D l, Point3D cp )
|
BezNode( Point3D l, Point3D cp )
|
||||||
{
|
{
|
||||||
loc = l;
|
loc = l;
|
||||||
next_cp = cp;
|
next_cp = cp;
|
||||||
prev_cp = Mirror(cp);
|
prev_cp = Mirror(cp);
|
||||||
mark = 0;
|
mark = 0;
|
||||||
light = 0;
|
light = 0;
|
||||||
|
term = false;
|
||||||
|
close = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
BezNode( double lat, double lon, double cp_lat, double cp_lon )
|
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 );
|
next_cp = Point3D( cp_lon, cp_lat, 0.0f );
|
||||||
prev_cp = Mirror( next_cp );
|
prev_cp = Mirror( next_cp );
|
||||||
mark = 0;
|
mark = 0;
|
||||||
light = 0;
|
light = 0;
|
||||||
|
term = false;
|
||||||
|
close = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Point3D Mirror( Point3D pt )
|
Point3D Mirror( Point3D pt )
|
||||||
|
@ -144,6 +152,16 @@ public:
|
||||||
return light;
|
return light;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetClose( bool c )
|
||||||
|
{
|
||||||
|
close = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetTerm( bool t )
|
||||||
|
{
|
||||||
|
term = t;
|
||||||
|
}
|
||||||
|
|
||||||
bool IsAt( double lat, double lon )
|
bool IsAt( double lat, double lon )
|
||||||
{
|
{
|
||||||
return ( (loc.lat() == lat) && (loc.lon() == lon) );
|
return ( (loc.lat() == lat) && (loc.lon() == lon) );
|
||||||
|
@ -199,6 +217,8 @@ private:
|
||||||
Point3D next_cp;
|
Point3D next_cp;
|
||||||
unsigned int mark;
|
unsigned int mark;
|
||||||
unsigned int light;
|
unsigned int light;
|
||||||
|
bool term;
|
||||||
|
bool close;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -132,7 +132,7 @@ void ClosedPoly::CloseCurContour()
|
||||||
if (cur_feature)
|
if (cur_feature)
|
||||||
{
|
{
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, "We still have an active linear feature - add the first node to close it");
|
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);
|
features.push_back(cur_feature);
|
||||||
cur_feature = NULL;
|
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");
|
SG_LOG(SG_GENERAL, SG_DEBUG, "BuildBtg: original poly has " << pre_tess.contours() << " contours");
|
||||||
|
|
||||||
// do this before clipping and generating the base
|
// do this before clipping and generating the base
|
||||||
|
pre_tess = remove_bad_contours( pre_tess );
|
||||||
pre_tess = remove_dups( pre_tess );
|
pre_tess = remove_dups( pre_tess );
|
||||||
pre_tess = reduce_degeneracy( 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: 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
|
// grow pretess by a little bit
|
||||||
pre_tess = tgPolygonExpand( pre_tess, 0.05); // 5cm
|
//pre_tess = tgPolygonExpand( pre_tess, 0.05); // 5cm
|
||||||
|
|
||||||
TGSuperPoly sp;
|
TGSuperPoly sp;
|
||||||
TGTexParams tp;
|
TGTexParams tp;
|
||||||
|
|
||||||
TGPolygon clipped = tgPolygonDiff( pre_tess, *accum );
|
SG_LOG(SG_GENERAL, SG_DEBUG, "BuildBtg: expanded poly has " << pre_tess.contours() << " contours");
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, "BuildBtg: clipped poly has " << clipped.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 );
|
TGPolygon split = tgPolygonSplitLongEdges( clipped, 400.0 );
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, "BuildBtg: split poly has " << split.contours() << " contours");
|
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 );
|
rwy_polys->push_back( sp );
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, "clipped = " << clipped.contours());
|
SG_LOG(SG_GENERAL, SG_DEBUG, "clipped = " << clipped.contours());
|
||||||
|
#if 1
|
||||||
|
*accum = tgPolygonUnionClipper( pre_tess, *accum );
|
||||||
|
#else
|
||||||
*accum = tgPolygonUnion( pre_tess, *accum );
|
*accum = tgPolygonUnion( pre_tess, *accum );
|
||||||
|
#endif
|
||||||
tp = TGTexParams( pre_tess.get_pt(0,0), 5.0, 5.0, texture_heading );
|
tp = TGTexParams( pre_tess.get_pt(0,0), 5.0, 5.0, texture_heading );
|
||||||
texparams->push_back( tp );
|
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);
|
safe_base = tgPolygonExpand( pre_tess, 50.0);
|
||||||
|
|
||||||
// add this to the airport clearing
|
// 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
|
// 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, ...);
|
// int fscanf(FILE *stream, const char *format, ...);
|
||||||
sscanf(definition, "%s %lf %lf %lf %lf %lf %d %d %d %lf %d",
|
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);
|
&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 );
|
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
|
// Now generate the helipad lights
|
||||||
superpoly_list s = gen_helipad_lights();
|
superpoly_list s = gen_helipad_lights();
|
||||||
for ( int i = 0; i < s.size(); ++i ) {
|
for ( unsigned int i = 0; i < s.size(); ++i ) {
|
||||||
rwy_lights->push_back( s[i] );
|
rwy_lights->push_back( s[i] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include "linearfeature.hxx"
|
#include "linearfeature.hxx"
|
||||||
#include "math.h"
|
#include "math.h"
|
||||||
|
|
||||||
void LinearFeature::ConvertContour( BezContour* src )
|
void LinearFeature::ConvertContour( BezContour* src, bool closed )
|
||||||
{
|
{
|
||||||
BezNode* prevNode;
|
BezNode* prevNode;
|
||||||
BezNode* curNode;
|
BezNode* curNode;
|
||||||
|
@ -243,9 +243,9 @@ void LinearFeature::ConvertContour( BezContour* src )
|
||||||
Point3D destLoc = nextNode->GetLoc();
|
Point3D destLoc = nextNode->GetLoc();
|
||||||
geo_inverse_wgs_84( curLoc.y(), curLoc.x(), destLoc.y(), destLoc.x(), &az1, &az2, &dist);
|
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++)
|
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
|
// now set set prev and cur locations for the next iteration
|
||||||
prevLoc = curLoc;
|
prevLoc = curLoc;
|
||||||
curLoc = nextLoc;
|
curLoc = nextLoc;
|
||||||
|
|
||||||
|
SG_LOG(SG_GENERAL, SG_DEBUG, "Set prevLoc = (" << prevLoc.x() << "," << prevLoc.y() << ") and curLoc = (" << curLoc.x() << "," << curLoc.y() << ")" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
nextLoc = nextNode->GetLoc();
|
||||||
|
|
||||||
// just add the one vertex - dist is small
|
// just add the one vertex - dist is small
|
||||||
points.push_back( curLoc );
|
points.push_back( curLoc );
|
||||||
|
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, "adding Linear Anchor node at (" << curLoc.x() << "," << curLoc.y() << ")");
|
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...
|
// 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() );
|
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;
|
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...
|
// 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() );
|
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;
|
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 );
|
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 poly;
|
||||||
TGPolygon normals_poly;
|
TGPolygon normals_poly;
|
||||||
|
@ -499,7 +520,7 @@ int LinearFeature::Finish()
|
||||||
// create the inner and outer boundaries to generate polys
|
// create the inner and outer boundaries to generate polys
|
||||||
// this generates 2 point lists for the contours, and remembers
|
// this generates 2 point lists for the contours, and remembers
|
||||||
// the start stop points for markings and lights
|
// the start stop points for markings and lights
|
||||||
ConvertContour( &contour );
|
ConvertContour( &contour, closed );
|
||||||
|
|
||||||
// now generate the supoerpoly and texparams lists for markings
|
// now generate the supoerpoly and texparams lists for markings
|
||||||
for (unsigned int i=0; i<marks.size(); i++)
|
for (unsigned int i=0; i<marks.size(); i++)
|
||||||
|
@ -782,11 +803,8 @@ int LinearFeature::Finish()
|
||||||
cur_light_dist += light_delta;
|
cur_light_dist += light_delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
// add the remaining distance to the last light
|
// start next segment at the correct distance
|
||||||
// cur_light_dist += modf( dist, &intpart );
|
cur_light_dist = cur_light_dist - dist;
|
||||||
|
|
||||||
// remove
|
|
||||||
cur_light_dist = fmod (cur_light_dist, light_delta);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -817,24 +835,28 @@ int LinearFeature::BuildBtg(float alt_m, superpoly_list* line_polys, texparams_l
|
||||||
{
|
{
|
||||||
TGPolygon poly;
|
TGPolygon poly;
|
||||||
TGPolygon clipped;
|
TGPolygon clipped;
|
||||||
//TGPolygon split;
|
|
||||||
|
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, "\nLinearFeature::BuildBtg: " << description);
|
SG_LOG(SG_GENERAL, SG_DEBUG, "\nLinearFeature::BuildBtg: " << description);
|
||||||
|
|
||||||
for ( unsigned int i = 0; i < marking_polys.size(); i++)
|
for ( unsigned int i = 0; i < marking_polys.size(); i++)
|
||||||
{
|
{
|
||||||
poly = marking_polys[i].get_poly();
|
poly = marking_polys[i].get_poly();
|
||||||
|
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, "LinearFeature::BuildBtg: clipping poly " << i << " of " << marking_polys.size() );
|
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 );
|
clipped = tgPolygonDiffClipper( poly, *line_accum );
|
||||||
|
#endif
|
||||||
// TGPolygon split = tgPolygonSplitLongEdges( clipped, 400.0 );
|
|
||||||
// SG_LOG(SG_GENERAL, SG_DEBUG, "LinearFeature::BuildBtg: split poly has " << split.contours() << " contours");
|
|
||||||
|
|
||||||
marking_polys[i].set_poly( clipped );
|
marking_polys[i].set_poly( clipped );
|
||||||
line_polys->push_back( marking_polys[i] );
|
line_polys->push_back( marking_polys[i] );
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
*line_accum = tgPolygonUnion( poly, *line_accum );
|
||||||
|
#else
|
||||||
*line_accum = tgPolygonUnionClipper( poly, *line_accum );
|
*line_accum = tgPolygonUnionClipper( poly, *line_accum );
|
||||||
|
#endif
|
||||||
|
|
||||||
line_tps->push_back( marking_tps[i] );
|
line_tps->push_back( marking_tps[i] );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -91,8 +91,9 @@ public:
|
||||||
contour.push_back( b );
|
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, 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:
|
private:
|
||||||
Point3D OffsetPointFirst( Point3D *cur, Point3D *next, double offset_by );
|
Point3D OffsetPointFirst( Point3D *cur, Point3D *next, double offset_by );
|
||||||
|
@ -108,7 +109,7 @@ private:
|
||||||
LightingList lights;
|
LightingList lights;
|
||||||
Lighting* cur_light;
|
Lighting* cur_light;
|
||||||
|
|
||||||
void ConvertContour( BezContour* src );
|
void ConvertContour( BezContour* src, bool closed );
|
||||||
|
|
||||||
// text description
|
// text description
|
||||||
string description;
|
string description;
|
||||||
|
|
|
@ -19,10 +19,15 @@ Beacon::Beacon( char* definition )
|
||||||
Sign::Sign( char* definition )
|
Sign::Sign( char* definition )
|
||||||
{
|
{
|
||||||
char sgdef[256];
|
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;
|
sgn_def = sgdef;
|
||||||
}
|
}
|
||||||
|
|
|
@ -309,7 +309,6 @@ void Parser::AddAirports( long start_pos, float min_lat, float min_lon, float ma
|
||||||
void Parser::Parse()
|
void Parser::Parse()
|
||||||
{
|
{
|
||||||
char tmp[2048];
|
char tmp[2048];
|
||||||
int i;
|
|
||||||
struct timeval parse_start;
|
struct timeval parse_start;
|
||||||
struct timeval parse_end;
|
struct timeval parse_end;
|
||||||
struct timeval parse_time;
|
struct timeval parse_time;
|
||||||
|
@ -325,7 +324,7 @@ void Parser::Parse()
|
||||||
}
|
}
|
||||||
|
|
||||||
// for each position in parse_positions, parse an airport
|
// 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);
|
SetState(STATE_NONE);
|
||||||
in.clear();
|
in.clear();
|
||||||
|
@ -502,6 +501,9 @@ BezNode* Parser::ParseNode( int type, char* line, BezNode* prevNode )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
curNode->SetTerm( term );
|
||||||
|
curNode->SetClose( close );
|
||||||
|
|
||||||
return curNode;
|
return curNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -533,7 +535,7 @@ ClosedPoly* Parser::ParsePavement( char* line )
|
||||||
char *d = NULL;
|
char *d = NULL;
|
||||||
int numParams;
|
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)
|
if (numParams == 4)
|
||||||
{
|
{
|
||||||
|
@ -557,7 +559,7 @@ ClosedPoly* Parser::ParseBoundary( char* line )
|
||||||
char *d = NULL;
|
char *d = NULL;
|
||||||
int numParams;
|
int numParams;
|
||||||
|
|
||||||
numParams = sscanf(line, "%ls", desc);
|
numParams = sscanf(line, "%s", desc);
|
||||||
|
|
||||||
if (numParams == 1)
|
if (numParams == 1)
|
||||||
{
|
{
|
||||||
|
@ -595,6 +597,8 @@ int Parser::SetState( int state )
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_state = 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...
|
// 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)
|
if (cur_airport)
|
||||||
{
|
{
|
||||||
cur_feat->Finish();
|
cur_feat->Finish( true );
|
||||||
cur_airport->AddFeature( cur_feat );
|
cur_airport->AddFeature( cur_feat );
|
||||||
}
|
}
|
||||||
cur_feat = NULL;
|
cur_feat = NULL;
|
||||||
|
@ -790,7 +794,7 @@ int Parser::ParseLine(char* line)
|
||||||
}
|
}
|
||||||
if (cur_airport)
|
if (cur_airport)
|
||||||
{
|
{
|
||||||
cur_feat->Finish();
|
cur_feat->Finish( false );
|
||||||
cur_airport->AddFeature( cur_feat );
|
cur_airport->AddFeature( cur_feat );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,8 +40,8 @@ Runway::Runway(char* definition)
|
||||||
// int fscanf(FILE *stream, const char *format, ...);
|
// 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",
|
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.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[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[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)
|
// calculate runway heading and length (used a lot)
|
||||||
|
@ -53,7 +53,7 @@ Runway::Runway(char* definition)
|
||||||
|
|
||||||
WaterRunway::WaterRunway(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 );
|
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
|
// and add the clearing to the base
|
||||||
*apt_base = tgPolygonUnion( base, *apt_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;
|
int numSegs = (rwy.length / max_dist) + 1;
|
||||||
double dist = rwy.length / (double)numSegs;
|
double dist = rwy.length / (double)numSegs;
|
||||||
|
|
||||||
|
//int numSegs = 1;
|
||||||
|
//double dist = rwy.length;
|
||||||
|
|
||||||
// Create both shoulder sides
|
// Create both shoulder sides
|
||||||
for (int i=0; i<2; ++i){
|
for (int i=0; i<2; ++i){
|
||||||
double step;
|
double step;
|
||||||
|
@ -395,18 +398,25 @@ void Runway::BuildShoulder( float alt_m,
|
||||||
for (int j=0; j<numSegs; j++)
|
for (int j=0; j<numSegs; j++)
|
||||||
{
|
{
|
||||||
geo_direct_wgs_84 ( alt_m, ref.y(), ref.x(), rwy.heading, (j*dist), &lat, &lon, &r );
|
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;
|
TGSuperPoly sp;
|
||||||
TGTexParams tp;
|
TGTexParams tp;
|
||||||
|
#if 1
|
||||||
TGPolygon clipped = tgPolygonDiff( shoulderSegment, *accum );
|
TGPolygon clipped = tgPolygonDiff( shoulderSegment, *accum );
|
||||||
|
#else
|
||||||
|
TGPolygon clipped = tgPolygonDiffClipper( shoulderSegment, *accum );
|
||||||
|
#endif
|
||||||
sp.erase();
|
sp.erase();
|
||||||
sp.set_poly( clipped );
|
sp.set_poly( clipped );
|
||||||
sp.set_material( shoulder_surface );
|
sp.set_material( shoulder_surface );
|
||||||
rwy_polys->push_back( sp );
|
rwy_polys->push_back( sp );
|
||||||
|
|
||||||
|
#if 1
|
||||||
*accum = tgPolygonUnion( shoulderSegment, *accum );
|
*accum = tgPolygonUnion( shoulderSegment, *accum );
|
||||||
|
#else
|
||||||
|
*accum = tgPolygonUnionClipper( shoulderSegment, *accum );
|
||||||
|
#endif
|
||||||
|
|
||||||
tp = TGTexParams( shoulderSegment.get_pt(0,0), -shoulder_width, dist, rwy.heading );
|
tp = TGTexParams( shoulderSegment.get_pt(0,0), -shoulder_width, dist, rwy.heading );
|
||||||
if (i == 0){
|
if (i == 0){
|
||||||
|
|
|
@ -46,7 +46,8 @@
|
||||||
#include <simgear/math/SGMath.hxx>
|
#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
|
enum {PX, PY, PZ}; // axes
|
||||||
|
|
||||||
|
|
|
@ -349,16 +349,12 @@ TGPolygon polygon_tesselate_alt( TGPolygon &p, bool verbose ) {
|
||||||
|
|
||||||
// Bail right away if polygon is empty
|
// Bail right away if polygon is empty
|
||||||
if ( p.contours() == 0 ) {
|
if ( p.contours() == 0 ) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1. Robustly find a point inside each contour that is not
|
// 1. Robustly find a point inside each contour that is not
|
||||||
// inside any other contour
|
// inside any other contour
|
||||||
calc_points_inside( p );
|
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
|
// 2. Do a final triangulation of the entire polygon
|
||||||
triele_list trieles;
|
triele_list trieles;
|
||||||
|
@ -366,8 +362,21 @@ TGPolygon polygon_tesselate_alt( TGPolygon &p, bool verbose ) {
|
||||||
string flags;
|
string flags;
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
flags = "pzqenXYY";
|
flags = "pzqenXYY";
|
||||||
|
// flags = "pzqenXY"; // allow adding interior points
|
||||||
} else {
|
} else {
|
||||||
flags = "pzqenXYYQ";
|
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 ) {
|
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 *
|
* Author : Angus Johnson *
|
||||||
* Version : 4.5.5 *
|
* Version : 4.6.5 *
|
||||||
* Date : 6 October 2011 *
|
* Date : 17 January 2011 *
|
||||||
* Website : http://www.angusj.com *
|
* Website : http://www.angusj.com *
|
||||||
* Copyright : Angus Johnson 2010-2011 *
|
* Copyright : Angus Johnson 2010-2012 *
|
||||||
* *
|
* *
|
||||||
* License: *
|
* License: *
|
||||||
* Use, modification & distribution is subject to Boost Software License Ver 1. *
|
* Use, modification & distribution is subject to Boost Software License Ver 1. *
|
||||||
|
@ -21,6 +21,14 @@
|
||||||
* Springer; 1 edition (January 4, 2005) *
|
* Springer; 1 edition (January 4, 2005) *
|
||||||
* http://books.google.com/books?q=vatti+clipping+agoston *
|
* 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
|
#ifndef clipper_hpp
|
||||||
|
@ -39,8 +47,8 @@ enum PolyType { ptSubject, ptClip };
|
||||||
//By far the most widely used winding rules for polygon filling are
|
//By far the most widely used winding rules for polygon filling are
|
||||||
//EvenOdd & NonZero (GDI, GDI+, XLib, OpenGL, Cairo, AGG, Quartz, SVG, Gr32)
|
//EvenOdd & NonZero (GDI, GDI+, XLib, OpenGL, Cairo, AGG, Quartz, SVG, Gr32)
|
||||||
//Others rules include Positive, Negative and ABS_GTR_EQ_TWO (only in OpenGL)
|
//Others rules include Positive, Negative and ABS_GTR_EQ_TWO (only in OpenGL)
|
||||||
//see http://www.songho.ca/opengl/gl_tessellation.html#winding_rules
|
//see http://glprogramming.com/red/chapter11.html
|
||||||
enum PolyFillType { pftEvenOdd, pftNonZero };
|
enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative };
|
||||||
|
|
||||||
typedef signed long long long64;
|
typedef signed long long long64;
|
||||||
typedef unsigned long long ulong64;
|
typedef unsigned long long ulong64;
|
||||||
|
@ -71,6 +79,9 @@ bool Orientation(const Polygon &poly);
|
||||||
double Area(const Polygon &poly);
|
double Area(const Polygon &poly);
|
||||||
void OffsetPolygons(const Polygons &in_polys, Polygons &out_polys,
|
void OffsetPolygons(const Polygons &in_polys, Polygons &out_polys,
|
||||||
double delta, JoinType jointype = jtSquare, double MiterLimit = 2);
|
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(Polygon& p);
|
||||||
void ReversePoints(Polygons& p);
|
void ReversePoints(Polygons& p);
|
||||||
|
@ -193,13 +204,13 @@ public:
|
||||||
Clipper();
|
Clipper();
|
||||||
~Clipper();
|
~Clipper();
|
||||||
bool Execute(ClipType clipType,
|
bool Execute(ClipType clipType,
|
||||||
Polygons &solution,
|
Polygons &solution,
|
||||||
PolyFillType subjFillType = pftEvenOdd,
|
PolyFillType subjFillType = pftEvenOdd,
|
||||||
PolyFillType clipFillType = pftEvenOdd);
|
PolyFillType clipFillType = pftEvenOdd);
|
||||||
bool Execute(ClipType clipType,
|
bool Execute(ClipType clipType,
|
||||||
ExPolygons &solution,
|
ExPolygons &solution,
|
||||||
PolyFillType subjFillType = pftEvenOdd,
|
PolyFillType subjFillType = pftEvenOdd,
|
||||||
PolyFillType clipFillType = pftEvenOdd);
|
PolyFillType clipFillType = pftEvenOdd);
|
||||||
void Clear();
|
void Clear();
|
||||||
bool ReverseSolution() {return m_ReverseOutput;};
|
bool ReverseSolution() {return m_ReverseOutput;};
|
||||||
void ReverseSolution(bool value) {m_ReverseOutput = value;};
|
void ReverseSolution(bool value) {m_ReverseOutput = value;};
|
||||||
|
@ -221,8 +232,8 @@ private:
|
||||||
bool m_ReverseOutput;
|
bool m_ReverseOutput;
|
||||||
void DisposeScanbeamList();
|
void DisposeScanbeamList();
|
||||||
void SetWindingCount(TEdge& edge);
|
void SetWindingCount(TEdge& edge);
|
||||||
bool IsNonZeroFillType(const TEdge& edge) const;
|
bool IsEvenOddFillType(const TEdge& edge) const;
|
||||||
bool IsNonZeroAltFillType(const TEdge& edge) const;
|
bool IsEvenOddAltFillType(const TEdge& edge) const;
|
||||||
void InsertScanbeam(const long64 Y);
|
void InsertScanbeam(const long64 Y);
|
||||||
long64 PopScanbeam();
|
long64 PopScanbeam();
|
||||||
void InsertLocalMinimaIntoAEL(const long64 botY);
|
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 )
|
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.AddPolygons(clipper_clip, ptClip);
|
||||||
|
|
||||||
c.Execute(op, clipper_result, pftEvenOdd, pftEvenOdd);
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -608,7 +644,6 @@ TGPolygon tgPolygonUnionClipper( const TGPolygon& subject, const TGPolygon& clip
|
||||||
return polygon_clip_clipper( POLY_UNION, subject, clip );
|
return polygon_clip_clipper( POLY_UNION, subject, clip );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// canonify the polygon winding, outer contour must be anti-clockwise,
|
// canonify the polygon winding, outer contour must be anti-clockwise,
|
||||||
// all inner contours must be clockwise.
|
// all inner contours must be clockwise.
|
||||||
TGPolygon polygon_canonify( const TGPolygon& in_poly ) {
|
TGPolygon polygon_canonify( const TGPolygon& in_poly ) {
|
||||||
|
|
|
@ -275,7 +275,6 @@ TGPolygon tgPolygonDiffClipper( const TGPolygon& subject, const TGPolygon& clip
|
||||||
// Union
|
// Union
|
||||||
TGPolygon tgPolygonUnionClipper( const TGPolygon& subject, const TGPolygon& clip );
|
TGPolygon tgPolygonUnionClipper( const TGPolygon& subject, const TGPolygon& clip );
|
||||||
|
|
||||||
|
|
||||||
// Expand / Shrink
|
// Expand / Shrink
|
||||||
TGPolygon tgPolygonExpand(const TGPolygon &poly, double delta);
|
TGPolygon tgPolygonExpand(const TGPolygon &poly, double delta);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue