1
0
Fork 0

added seperate-segments option to ogr-decode.

- generates an intermediate file for the whole linestring, but as seperate poly/texcoord pairs
- construct generates the union ofthe polys for the main clip routine
- intersection ot the original segment with the clipped mask gives the clipped segment
  This cuts ~75% of clipping time for really complex tiles.  8 tiles for Madeira went from
  4:45:00 to 1:04:00
This commit is contained in:
Peter Sadrozinski 2012-08-05 08:20:52 -04:00 committed by Christian Schmitt
parent 465fccc6a0
commit feeaf602b7
5 changed files with 607 additions and 441 deletions
src

View file

@ -127,27 +127,30 @@ void TGConstruct::LoadElevationArray( void ) {
// Add a polygon to the clipper.
void TGConstruct::add_poly( int area, const TGPolygon &poly, string material ) {
TGShape shape;
TGSuperPoly sp;
if ( area < TG_MAX_AREA_TYPES ) {
sp.set_poly( poly );
sp.set_material( material );
polys_in.superpolys[area].push_back(sp);
shape.sps.push_back( sp );
polys_in.add_shape( area, shape );
} else {
SG_LOG( SG_CLIPPER, SG_ALERT, "Polygon type out of range = " << area);
exit(-1);
}
}
// Load a polygon definition file.
bool TGConstruct::load_poly(const string& path) {
bool poly3d = false;
string first_line;
string poly_name;
AreaType poly_type;
int contours, count, i, j;
int contours, count, i, j, k;
int hole_flag;
int num_polys;
double startx, starty, startz, x, y, z, lastx, lasty, lastz;
sg_gzifstream in( path );
@ -166,15 +169,31 @@ bool TGConstruct::load_poly(const string& path) {
if ( first_line == "#2D" ) {
poly3d = false;
in >> poly_name;
num_polys = 1;
} else if ( first_line == "#2D_WITH_MASK" ) {
poly3d = false;
in >> poly_name;
in >> num_polys;
} else if ( first_line == "#3D" ) {
poly3d = true;
in >> poly_name;
num_polys = 1;
} else {
// support old format (default to 2d)
poly3d = false;
poly_name = first_line;
num_polys = 1;
}
poly_type = get_area_type( poly_name );
int area = (int)poly_type;
string material = get_area_name( area );
// Generate a new Shape for the poly
TGShape shape;
TGSuperPoly sp;
for (k=0; k<num_polys;k++) {
in >> contours;
SG_LOG( SG_CLIPPER, SG_INFO, "Loading " << path << ":" << poly_name << "-" << poly_type << " contours = " << contours );
@ -252,15 +271,18 @@ bool TGConstruct::load_poly(const string& path) {
}
poly = remove_dups( poly );
int area = (int)poly_type;
string material = get_area_name( area );
add_poly(area, poly, material);
sp.set_poly( poly );
sp.set_material( material );
shape.sps.push_back( sp );
in >> skipcomment;
}
// Once the full poly is loaded, build the clip mask
shape.BuildMask();
polys_in.add_shape( area, shape );
}
return true;
}
@ -348,10 +370,11 @@ bool TGConstruct::load_osgb36_poly(const string& path) {
}
}
// TODO : Make like OGR
int area = (int)poly_type;
string material = get_area_name( area );
add_poly(area, poly, material);
// END TODO
in >> skipcomment;
}
@ -368,9 +391,7 @@ int TGConstruct::LoadLandclassPolys( void ) {
string poly_path;
int count = 0;
for ( int i = 0; i < TG_MAX_AREA_TYPES; ++i ) {
polys_in.superpolys[i].clear();
}
polys_in.clear();
// load 2D polygons from all directories provided
for ( i = 0; i < (int)load_dirs.size(); ++i ) {
@ -579,6 +600,7 @@ int TGConstruct::load_landcover()
// type. Add the remaining polygons to the clipper.
for ( int i = 0; i < TG_MAX_AREA_TYPES; i++ ) {
if ( polys[i].contours() ) {
// TODO : REMOVE add_poly
add_poly( i, polys[i], get_area_name((AreaType)i ));
count++;
}
@ -597,19 +619,21 @@ void TGConstruct::FixTJunctions( void ) {
// traverse each poly, and add intermediate nodes
for ( unsigned int i = 0; i < TG_MAX_AREA_TYPES; ++i ) {
for( unsigned int j = 0; j < polys_clipped.superpolys[i].size(); ++j ) {
TGPolygon current = polys_clipped.superpolys[i][j].get_poly();
for( unsigned int j = 0; j < polys_clipped.area_size(i); ++j ) {
for( unsigned int k = 0; k < polys_clipped.shape_size(i, j); ++k ) {
TGPolygon current = polys_clipped.get_poly(i, j, k);
before = current.total_size();
current = add_tgnodes_to_poly( current, &nodes );
after = current.total_size();
if (before != after) {
SG_LOG( SG_CLIPPER, SG_INFO, "Fixed T-Junctions in " << get_area_name( (AreaType)i ) << ":" << j+1 << " of " << (int)polys_clipped.superpolys[i].size() << " nodes increased from " << before << " to " << after );
SG_LOG( SG_CLIPPER, SG_INFO, "Fixed T-Junctions in " << get_area_name( (AreaType)i ) << ":" << j+1 << "-" << k << " of " << (int)polys_clipped.area_size(i) << " nodes increased from " << before << " to " << after );
}
/* Save it back */
polys_clipped.superpolys[i][j].set_poly( current );
polys_clipped.set_poly( i, j, k, current );
}
}
}
}
@ -644,7 +668,6 @@ double TGConstruct::distanceSphere( const Point3D p1, const Point3D p2 ) {
// hopefully, this will get better when we have the area lookup via superpoly...
void TGConstruct::CalcElevations( void )
{
//TGPolygon tri_poly;
TGPolyNodes tri_nodes;
double e1, e2, e3, min;
int n1, n2, n3;
@ -663,24 +686,25 @@ void TGConstruct::CalcElevations( void )
}
// now flatten some stuff
for (int i = 0; i < TG_MAX_AREA_TYPES; i++) {
if ( is_lake_area( (AreaType)i ) ) {
for (int j = 0; j < (int)polys_clipped.superpolys[i].size(); ++j ) {
SG_LOG( SG_CLIPPER, SG_INFO, "Flattening " << get_area_name( (AreaType)i ) << ":" << j+1 << " of " << (int)polys_clipped.superpolys[i].size() );
for (unsigned int area = 0; area < TG_MAX_AREA_TYPES; area++) {
if ( is_lake_area( (AreaType)area ) ) {
for (int shape = 0; shape < (int)polys_clipped.area_size(area); ++shape ) {
for (int segment = 0; segment < (int)polys_clipped.shape_size(area, shape); ++segment ) {
tri_nodes = polys_clipped.superpolys[i][j].get_tri_idxs();
SG_LOG( SG_CLIPPER, SG_INFO, "Flattening " << get_area_name( (AreaType)area ) << ":" << shape+1 << "-" << segment << " of " << (int)polys_clipped.area_size(area) );
tri_nodes = polys_clipped.get_tri_idxs( area, shape, segment );
for (int k=0; k< tri_nodes.contours(); k++) {
if (tri_nodes.contour_size(k) != 3) {
SG_LOG(SG_GENERAL, SG_ALERT, "triangle doesnt have 3 nodes" << tri_nodes.contour_size(k) );
for (int tri=0; tri < tri_nodes.contours(); tri++) {
if (tri_nodes.contour_size( tri ) != 3) {
SG_LOG(SG_GENERAL, SG_ALERT, "triangle doesnt have 3 nodes" << tri_nodes.contour_size( tri ) );
exit(0);
}
n1 = tri_nodes.get_pt( k, 0 );
n1 = tri_nodes.get_pt( tri, 0 );
e1 = nodes.get_node(n1).GetPosition().z();
n2 = tri_nodes.get_pt( k, 1 );
n2 = tri_nodes.get_pt( tri, 1 );
e2 = nodes.get_node(n2).GetPosition().z();
n3 = tri_nodes.get_pt( k, 2 );
n3 = tri_nodes.get_pt( tri, 2 );
e3 = nodes.get_node(n3).GetPosition().z();
min = e1;
@ -693,26 +717,28 @@ void TGConstruct::CalcElevations( void )
}
}
}
}
if ( is_stream_area( (AreaType)i ) ) {
for (int j = 0; j < (int)polys_clipped.superpolys[i].size(); ++j ) {
SG_LOG( SG_CLIPPER, SG_INFO, "Flattening " << get_area_name( (AreaType)i ) << ":" << j+1 << " of " << (int)polys_clipped.superpolys[i].size() );
if ( is_stream_area( (AreaType)area ) ) {
for (int shape = 0; shape < (int)polys_clipped.area_size(area); ++shape ) {
for (int segment = 0; segment < (int)polys_clipped.shape_size(area, shape); ++segment ) {
tri_nodes = polys_clipped.superpolys[i][j].get_tri_idxs();
SG_LOG( SG_CLIPPER, SG_INFO, "Flattening " << get_area_name( (AreaType)area ) << ":" << shape+1 << "-" << segment << " of " << (int)polys_clipped.area_size(area) );
tri_nodes = polys_clipped.get_tri_idxs( area, shape, segment );
for (int k=0; k< tri_nodes.contours(); k++) {
if (tri_nodes.contour_size(k) != 3) {
SG_LOG(SG_GENERAL, SG_ALERT, "triangle doesnt have 3 nodes" << tri_nodes.contour_size(k) );
for (int tri=0; tri < tri_nodes.contours(); tri++) {
if (tri_nodes.contour_size( tri ) != 3) {
SG_LOG(SG_GENERAL, SG_ALERT, "triangle doesnt have 3 nodes" << tri_nodes.contour_size( tri ) );
exit(0);
}
point_list raw_nodes = nodes.get_geod_nodes();
n1 = tri_nodes.get_pt( k, 0 );
n1 = tri_nodes.get_pt( tri, 0 );
e1 = nodes.get_node(n1).GetPosition().z();
n2 = tri_nodes.get_pt( k, 1 );
n2 = tri_nodes.get_pt( tri, 1 );
e2 = nodes.get_node(n2).GetPosition().z();
n3 = tri_nodes.get_pt( k, 2 );
n3 = tri_nodes.get_pt( tri, 2 );
e3 = nodes.get_node(n3).GetPosition().z();
min = e1;
@ -735,26 +761,28 @@ void TGConstruct::CalcElevations( void )
}
}
}
}
if ( is_road_area( (AreaType)i ) ) {
for (int j = 0; j < (int)polys_clipped.superpolys[i].size(); ++j ) {
SG_LOG( SG_CLIPPER, SG_INFO, "Flattening " << get_area_name( (AreaType)i ) << ":" << j+1 << " of " << (int)polys_clipped.superpolys[i].size() );
if ( is_road_area( (AreaType)area ) ) {
for (int shape = 0; shape < (int)polys_clipped.area_size(area); ++shape ) {
for (int segment = 0; segment < (int)polys_clipped.shape_size(area, shape); ++segment ) {
tri_nodes = polys_clipped.superpolys[i][j].get_tri_idxs();
SG_LOG( SG_CLIPPER, SG_INFO, "Flattening " << get_area_name( (AreaType)area ) << ":" << shape+1 << "-" << segment << " of " << (int)polys_clipped.area_size(area) );
tri_nodes = polys_clipped.get_tri_idxs( area, shape, segment );
for (int k=0; k< tri_nodes.contours(); k++) {
if (tri_nodes.contour_size(k) != 3) {
SG_LOG(SG_GENERAL, SG_ALERT, "triangle doesnt have 3 nodes" << tri_nodes.contour_size(k) );
for (int tri=0; tri < tri_nodes.contours(); tri++) {
if (tri_nodes.contour_size( tri ) != 3) {
SG_LOG(SG_GENERAL, SG_ALERT, "triangle doesnt have 3 nodes" << tri_nodes.contour_size( tri ) );
exit(0);
}
point_list raw_nodes = nodes.get_geod_nodes();
n1 = tri_nodes.get_pt( k, 0 );
n1 = tri_nodes.get_pt( tri, 0 );
e1 = nodes.get_node(n1).GetPosition().z();
n2 = tri_nodes.get_pt( k, 1 );
n2 = tri_nodes.get_pt( tri, 1 );
e2 = nodes.get_node(n2).GetPosition().z();
n3 = tri_nodes.get_pt( k, 2 );
n3 = tri_nodes.get_pt( tri, 2 );
e3 = nodes.get_node(n3).GetPosition().z();
min = e1;
@ -777,23 +805,24 @@ void TGConstruct::CalcElevations( void )
}
}
}
}
if ( is_ocean_area( (AreaType)i ) ) {
for (int j = 0; j < (int)polys_clipped.superpolys[i].size(); ++j ) {
if ( is_ocean_area( (AreaType)area ) ) {
for (int shape = 0; shape < (int)polys_clipped.area_size(area); ++shape ) {
for (int segment = 0; segment < (int)polys_clipped.shape_size(area, shape); ++segment ) {
tri_nodes = polys_clipped.superpolys[i][j].get_tri_idxs();
SG_LOG( SG_CLIPPER, SG_INFO, "Flattening " << get_area_name( (AreaType)area ) << ":" << shape+1 << "-" << segment << " of " << (int)polys_clipped.area_size(area) );
tri_nodes = polys_clipped.get_tri_idxs( area, shape, segment );
SG_LOG( SG_CLIPPER, SG_INFO, "Flattening " << get_area_name( (AreaType)i ) << ":" << j+1 << " of " << (int)polys_clipped.superpolys[i].size() );
for (int k=0; k< tri_nodes.contours(); k++) {
if (tri_nodes.contour_size(k) != 3) {
SG_LOG(SG_GENERAL, SG_ALERT, "triangle doesnt have 3 nodes" << tri_nodes.contour_size(k) );
for (int tri=0; tri < tri_nodes.contours(); tri++) {
if (tri_nodes.contour_size( tri ) != 3) {
SG_LOG(SG_GENERAL, SG_ALERT, "triangle doesnt have 3 nodes" << tri_nodes.contour_size( tri ) );
exit(0);
}
n1 = tri_nodes.get_pt( k, 0 );
n2 = tri_nodes.get_pt( k, 1 );
n3 = tri_nodes.get_pt( k, 2 );
n1 = tri_nodes.get_pt( tri, 0 );
n2 = tri_nodes.get_pt( tri, 1 );
n3 = tri_nodes.get_pt( tri, 2 );
nodes.SetElevation( n1, 0.0 );
nodes.SetElevation( n2, 0.0 );
@ -802,6 +831,7 @@ void TGConstruct::CalcElevations( void )
}
}
}
}
}
TGPolygon TGConstruct::area_tex_coords( const TGPolygon& tri )
@ -1013,19 +1043,17 @@ void TGConstruct::AddCustomObjects( void ) {
// a polygon with no increased contours (i.e. the sliver is adjacent
// and can be merged.) If so, replace the clipped polygon with the
// new polygon that has the sliver merged in.
void TGConstruct::merge_slivers( TGPolyList& clipped, poly_list& slivers_list ) {
void TGConstruct::merge_slivers( TGLandclass& clipped, poly_list& slivers_list ) {
TGPolygon poly, result, slivers, sliver;
point_list contour;
int original_contours, result_contours;
bool done;
int area, i, j, k;
int area, shape, segment, i, j;
for ( i = 0; i < (int)slivers_list.size(); i++ ) {
slivers = slivers_list[i];
for ( j = 0; j < slivers.contours(); ++j ) {
// cout << "Merging sliver = " << i << endl;
// make the sliver polygon
contour = slivers.get_contour( j );
sliver.erase();
@ -1038,11 +1066,10 @@ void TGConstruct::merge_slivers( TGPolyList& clipped, poly_list& slivers_list )
continue;
}
// cout << " testing area = " << area << " with "
// << clipped.polys[area].size() << " polys" << endl;
for ( k = 0; k < (int)clipped.superpolys[area].size() && !done; ++k ) {
// cout << " polygon = " << j << endl;
poly = clipped.superpolys[area][k].get_poly();
for ( shape = 0; shape < (int)clipped.area_size(area) && !done; ++shape ) {
for ( segment = 0; segment < (int)clipped.shape_size(area, shape) && !done; ++segment ) {
poly = clipped.get_poly( area, shape, segment );
original_contours = poly.contours();
#if USE_CLIPPER
result = tgPolygonUnionClipper( poly, sliver );
@ -1052,15 +1079,11 @@ void TGConstruct::merge_slivers( TGPolyList& clipped, poly_list& slivers_list )
result_contours = result.contours();
if ( original_contours == result_contours ) {
// cout << " FOUND a poly to merge the sliver with" << endl;
clipped.superpolys[area][k].set_poly( result );
clipped.set_poly( area, shape, segment, result );
done = true;
}
}
}
if ( !done ) {
// cout << "no suitable polys found for sliver merge" << endl;
}
}
}
@ -1069,6 +1092,7 @@ void TGConstruct::merge_slivers( TGPolyList& clipped, poly_list& slivers_list )
bool TGConstruct::ClipLandclassPolys( void ) {
TGPolygon accum, clipped, tmp;
TGPolygon remains;
TGPolygon safety_base;
poly_list slivers;
int i, j;
Point3D p;
@ -1083,22 +1107,22 @@ bool TGConstruct::ClipLandclassPolys( void ) {
accum.erase();
// set up clipping tile : and remember to add the nodes!
polys_in.safety_base.erase();
safety_base.erase();
p = Point3D(min.x, min.y, -9999.0);
polys_in.safety_base.add_node( 0, p );
safety_base.add_node( 0, p );
nodes.unique_add( p );
p = Point3D(max.x, min.y, -9999.0);
polys_in.safety_base.add_node( 0, p );
safety_base.add_node( 0, p );
nodes.unique_add( p );
p = Point3D(max.x, max.y, -9999.0);
polys_in.safety_base.add_node( 0, p );
safety_base.add_node( 0, p );
nodes.unique_add( p );
p = Point3D(min.x, max.y, -9999.0);
polys_in.safety_base.add_node( 0, p );
safety_base.add_node( 0, p );
nodes.unique_add( p );
// set up land mask, we clip most things to this since it is our
@ -1110,30 +1134,31 @@ bool TGConstruct::ClipLandclassPolys( void ) {
land_mask.erase();
water_mask.erase();
island_mask.erase();
for ( i = 0; i < TG_MAX_AREA_TYPES; i++ ) {
if ( is_landmass_area( i ) && !ignoreLandmass ) {
for ( unsigned int j = 0; j < polys_in.superpolys[i].size(); ++j ) {
for ( unsigned int j = 0; j < polys_in.area_size(i); ++j ) {
#if USE_CLIPPER
land_mask = tgPolygonUnionClipper( land_mask, polys_in.superpolys[i][j].get_poly() );
land_mask = tgPolygonUnionClipper( land_mask, polys_in.get_mask(i, j) );
#else
land_mask = tgPolygonUnion( land_mask, polys_in.superpolys[i][j].get_poly() );
land_mask = tgPolygonUnion( land_mask, polys_in.get_mask(i, j) );
#endif
}
} else if ( is_water_area( i ) ) {
for (unsigned int j = 0; j < polys_in.superpolys[i].size(); j++) {
for (unsigned int j = 0; j < polys_in.area_size(i); j++) {
#if USE_CLIPPER
water_mask = tgPolygonUnionClipper( water_mask, polys_in.superpolys[i][j].get_poly() );
water_mask = tgPolygonUnionClipper( water_mask, polys_in.get_mask(i, j) );
#else
water_mask = tgPolygonUnion( water_mask, polys_in.superpolys[i][j].get_poly() );
water_mask = tgPolygonUnion( water_mask, polys_in.get_mask(i, j) );
#endif
}
} else if ( is_island_area( i ) ) {
for (unsigned int j = 0; j < polys_in.superpolys[i].size(); j++) {
for (unsigned int j = 0; j < polys_in.area_size(i); j++) {
#if USE_CLIPPER
island_mask = tgPolygonUnionClipper( island_mask, polys_in.superpolys[i][j].get_poly() );
island_mask = tgPolygonUnionClipper( island_mask, polys_in.get_mask(i, j) );
#else
island_mask = tgPolygonUnion( island_mask, polys_in.superpolys[i][j].get_poly() );
island_mask = tgPolygonUnion( island_mask, polys_in.get_mask(i, j) );
#endif
}
}
@ -1141,10 +1166,10 @@ bool TGConstruct::ClipLandclassPolys( void ) {
// process polygons in priority order
for ( i = 0; i < TG_MAX_AREA_TYPES; ++i ) {
for( j = 0; j < (int)polys_in.superpolys[i].size(); ++j ) {
TGPolygon current = polys_in.superpolys[i][j].get_poly();
for( j = 0; j < (int)polys_in.area_size(i); ++j ) {
TGPolygon current = polys_in.get_mask(i, j);
SG_LOG( SG_CLIPPER, SG_INFO, "Clipping " << get_area_name( (AreaType)i ) << ":" << j+1 << " of " << (int)polys_in.superpolys[i].size() );
SG_LOG( SG_CLIPPER, SG_INFO, "Clipping " << get_area_name( (AreaType)i ) << ":" << j+1 << " of " << polys_in.area_size(i) );
tmp = current;
@ -1188,20 +1213,20 @@ bool TGConstruct::ClipLandclassPolys( void ) {
// move slivers from clipped polygon to slivers polygon
tgPolygonFindSlivers( clipped, slivers );
// merge any slivers with previously clipped
// neighboring polygons
//if ( slivers.contours() > 0 ) {
// merge_slivers(polys_clipped, slivers);
//}
// add the sliverless result polygon to the clipped polys list
if ( clipped.contours() > 0 ) {
TGShape shape;
TGSuperPoly sp;
string material = get_area_name( (AreaType)i );
sp.set_material( material );
sp.set_poly( clipped );
polys_clipped.superpolys[i].push_back( sp );
sp.set_material( get_area_name( (AreaType)i ) );
// copy all of the superpolys and texparams
shape.SetMask( clipped );
shape.sps = polys_in.get_shape( i, j ).sps;
shape.tps = polys_in.get_shape( i, j ).tps;
shape.sps.push_back( sp );
polys_clipped.add_shape( i, shape );
}
}
@ -1223,9 +1248,9 @@ bool TGConstruct::ClipLandclassPolys( void ) {
// remains->num_contours = 0;
// remains->contour = NULL;
#if USE_CLIPPER
remains = tgPolygonDiffClipper( polys_in.safety_base, accum );
remains = tgPolygonDiffClipper( safety_base, accum );
#else
remains = tgPolygonDiff( polys_in.safety_base, accum );
remains = tgPolygonDiff( safety_base, accum );
#endif
if ( remains.contours() > 0 ) {
@ -1244,27 +1269,39 @@ bool TGConstruct::ClipLandclassPolys( void ) {
if ( remains.contours() > 0 ) {
TGSuperPoly sp;
TGShape shape;
string material = get_area_name(get_sliver_target_area_type());
sp.set_material( material );
sp.set_poly( remains );
shape.sps.push_back( sp );
polys_clipped.superpolys[(int)get_sliver_target_area_type()].push_back(sp);
polys_clipped.add_shape( (int)get_sliver_target_area_type(), shape );
}
}
// Once clipping is complete, make sure any newly added intersection nodes
// are added to the tgnodes
for (int i = 0; i < TG_MAX_AREA_TYPES; i++) {
for (int j = 0; j < (int)polys_clipped.superpolys[i].size(); ++j ) {
TGPolygon poly = polys_clipped.superpolys[i][j].get_poly();
// Once clipping is complete, intersect the individual segments with their clip masks
for (unsigned int area = 0; area < TG_MAX_AREA_TYPES; area++) {
for (unsigned int shape = 0; shape < polys_clipped.area_size(area); shape++ ) {
SG_LOG( SG_CLIPPER, SG_INFO, "Seperating segments from clip mask for " << get_area_name( (AreaType)area ) << ":" << shape+1 << " of " << polys_clipped.area_size(area) );
polys_clipped.get_shape(area, shape).IntersectPolys();
}
}
SG_LOG( SG_CLIPPER, SG_INFO, "Collecting nodes for " << get_area_name( (AreaType)i ) << ":" << j+1 << " of " << (int)polys_clipped.superpolys[i].size() );
// Now make sure any newly added intersection nodes are added to the tgnodes
for (unsigned int area = 0; area < TG_MAX_AREA_TYPES; area++) {
for (unsigned int shape = 0; shape < polys_clipped.area_size(area); shape++ ) {
for (unsigned int segment = 0; segment < polys_clipped.shape_size(area, shape); segment++) {
TGPolygon poly = polys_clipped.get_poly( area, shape, segment );
for (int k=0; k< poly.contours(); k++) {
for (int l = 0; l < poly.contour_size(k); l++) {
SG_LOG( SG_CLIPPER, SG_INFO, "Collecting nodes for " << get_area_name( (AreaType)area ) << ":" << shape+1 << "-" << segment << " of " << polys_clipped.area_size(area) );
for (int con=0; con < poly.contours(); con++) {
for (int node = 0; node < poly.contour_size( con ); node++) {
// ensure we have all nodes...
nodes.unique_add( poly.get_pt( k, l ) );
nodes.unique_add( poly.get_pt( con, node ) );
}
}
}
}
@ -1314,15 +1351,14 @@ void TGConstruct::LookupNodesPerVertex( void )
SG_LOG(SG_GENERAL, SG_ALERT, "LookupNodexPerVertex");
// for each node, traverse all the triangles - and create face lists
for ( unsigned int area = 0; area < TG_MAX_AREA_TYPES; ++area ) {
for( unsigned int p = 0; p < polys_clipped.superpolys[area].size(); ++p ) {
TGPolygon tris = polys_clipped.superpolys[area][p].get_tris();
for ( unsigned int area = 0; area < TG_MAX_AREA_TYPES; area++ ) {
for( unsigned int shape = 0; shape < polys_clipped.area_size(area); shape++ ) {
for ( unsigned int segment = 0; segment < polys_clipped.shape_size(area, shape); segment++ ) {
TGPolygon tris = polys_clipped.get_tris( area, shape, segment );
TGPolyNodes tri_nodes;
int idx;
for (int tri=0; tri < tris.contours(); tri++) {
for (int vertex = 0; vertex < tris.contour_size(tri); vertex++) {
idx = nodes.find( tris.get_pt( tri, vertex ) );
if (idx >= 0) {
@ -1332,7 +1368,8 @@ void TGConstruct::LookupNodesPerVertex( void )
}
}
}
polys_clipped.superpolys[area][p].set_tri_idxs(tri_nodes);
polys_clipped.set_tri_idxs(area, shape, segment, tri_nodes);
}
}
}
}
@ -1342,14 +1379,16 @@ void TGConstruct::LookupFacesPerNode( void )
SG_LOG(SG_GENERAL, SG_ALERT, "LookupFacesPerNode");
// Add each face that includes a node to the node's face list
for ( unsigned int area = 0; area < TG_MAX_AREA_TYPES; ++area ) {
for( unsigned int p = 0; p < polys_clipped.superpolys[area].size(); ++p ) {
TGPolygon tris = polys_clipped.superpolys[area][p].get_tris();
for ( unsigned int area = 0; area < TG_MAX_AREA_TYPES; area++ ) {
for( unsigned int shape = 0; shape < polys_clipped.area_size(area); shape++ ) {
for ( unsigned int segment = 0; segment < polys_clipped.shape_size(area, shape); segment++ ) {
TGPolygon tris = polys_clipped.get_tris(area, shape, segment);
for (int tri=0; tri < tris.contours(); tri++) {
for (int sub = 0; sub < tris.contour_size(tri); sub++) {
int n = nodes.find( tris.get_pt( tri, sub ) );
nodes.AddFace( n, area, p, tri );
nodes.AddFace( n, area, shape, segment, tri );
}
}
}
}
@ -1433,11 +1472,12 @@ void TGConstruct::CalcFaceNormals( void )
// traverse the superpols, and calc normals for each tri within
point_list wgs84_nodes = nodes.get_wgs84_nodes_as_Point3d();
for (int i = 0; i < TG_MAX_AREA_TYPES; i++) {
for (int j = 0; j < (int)polys_clipped.superpolys[i].size(); ++j ) {
SG_LOG( SG_CLIPPER, SG_INFO, "Calculating face normals for " << get_area_name( (AreaType)i ) << ":" << j+1 << " of " << (int)polys_in.superpolys[i].size() );
calc_normals( wgs84_nodes, polys_clipped.superpolys[i][j] );
for (unsigned int area = 0; area < TG_MAX_AREA_TYPES; area++) {
for (unsigned int shape = 0; shape < polys_clipped.area_size(area); shape++ ) {
for ( unsigned int segment = 0; segment < polys_clipped.shape_size(area, shape); segment++ ) {
SG_LOG( SG_CLIPPER, SG_INFO, "Calculating face normals for " << get_area_name( (AreaType)area ) << ":" << shape+1 << "-" << segment << " of " << polys_in.area_size(area) );
calc_normals( wgs84_nodes, polys_clipped.get_superpoly( area, shape, segment ) );
}
}
}
}
@ -1460,21 +1500,21 @@ void TGConstruct::CalcPointNormals( void )
// for each triangle that shares this node
for ( unsigned int j = 0; j < faces.size(); ++j ) {
unsigned int at = faces[j].area;
unsigned int poly = faces[j].poly;
unsigned int shape = faces[j].shape;
unsigned int segment = faces[j].seg;
unsigned int tri = faces[j].tri;
int_list face_nodes;
double face_area;
normal = polys_clipped.superpolys[at][poly].get_face_normal( tri );
face_nodes = polys_clipped.superpolys[at][poly].get_tri_idxs().get_contour( tri ) ;
face_area = polys_clipped.superpolys[at][poly].get_face_area( tri );
normal = polys_clipped.get_face_normal( at, shape, segment, tri );
face_nodes = polys_clipped.get_tri_idxs( at, shape, segment ).get_contour( tri ) ;
face_area = polys_clipped.get_face_area( at, shape, segment, tri );
normal *= face_area; // scale normal weight relative to area
total_area += face_area;
average += normal;
}
average /= total_area;
nodes.SetNormal( i, average );
}
}
@ -1504,11 +1544,15 @@ void TGConstruct::TesselatePolys( void )
{
// tesselate the polygons and prepair them for final output
point_list extra = nodes.get_geod_nodes();
for (int i = 0; i < TG_MAX_AREA_TYPES; i++) {
for (int j = 0; j < (int)polys_clipped.superpolys[i].size(); ++j ) {
TGPolygon poly = polys_clipped.superpolys[i][j].get_poly();
SG_LOG( SG_CLIPPER, SG_INFO, "Tesselating " << get_area_name( (AreaType)i ) << "(" << i << "): " << j+1 << " of " << (int)polys_clipped.superpolys[i].size() << ": flag = " << polys_clipped.superpolys[i][j].get_flag());
for (unsigned int area = 0; area < TG_MAX_AREA_TYPES; area++) {
for (unsigned int shape = 0; shape < polys_clipped.area_size(area); shape++ ) {
for ( unsigned int segment = 0; segment < polys_clipped.shape_size(area, shape); segment++ ) {
TGPolygon poly = polys_clipped.get_poly(area, shape, segment);
SG_LOG( SG_CLIPPER, SG_INFO, "Tesselating " << get_area_name( (AreaType)area ) << "(" << area << "): " <<
shape+1 << "-" << segment << " of " << (int)polys_clipped.area_size(area) <<
": flag = " << polys_clipped.get_flag(area, shape, segment));
#if 0
if ( (i == 3) && (j == 137) ) {
@ -1536,7 +1580,8 @@ void TGConstruct::TesselatePolys( void )
}
// Save the triangulation
polys_clipped.superpolys[i][j].set_tris( tri );
polys_clipped.set_tris( area, shape, segment, tri );
}
}
}
}
@ -1566,23 +1611,23 @@ void TGConstruct::WriteBtgFile( void )
int_list pt_n, tri_n, strip_n;
int_list tri_tc, strip_tc;
for (int i = 0; i < TG_MAX_AREA_TYPES; i++) {
for (unsigned int area = 0; area < TG_MAX_AREA_TYPES; area++) {
// only tesselate non holes
if ( !is_hole_area( i ) ) {
for (int j = 0; j < (int)polys_clipped.superpolys[i].size(); ++j ) {
SG_LOG( SG_CLIPPER, SG_INFO, "Ouput nodes for " << get_area_name( (AreaType)i ) << ":" << j+1 << " of " << (int)polys_clipped.superpolys[i].size() );
if ( !is_hole_area( area ) ) {
for (unsigned int shape = 0; shape < polys_clipped.area_size(area); shape++ ) {
for ( unsigned int segment = 0; segment < polys_clipped.shape_size(area, shape); segment++ ) {
SG_LOG( SG_CLIPPER, SG_INFO, "Ouput nodes for " << get_area_name( (AreaType)area ) << ":" <<
shape+1 << "-" << segment << " of " << polys_clipped.area_size(area) );
TGPolyNodes tri_nodes = polys_clipped.superpolys[i][j].get_tri_idxs();
TGPolygon tri_txs = polys_clipped.superpolys[i][j].get_texcoords();
string material = polys_clipped.superpolys[i][j].get_material();
TGPolyNodes tri_nodes = polys_clipped.get_tri_idxs(area, shape, segment);
TGPolygon tri_txs = polys_clipped.get_texcoords(area, shape, segment);
string material = polys_clipped.get_material(area, shape, segment);
for (int k = 0; k < tri_nodes.contours(); ++k)
{
for (int k = 0; k < tri_nodes.contours(); ++k) {
tri_v.clear();
tri_n.clear();
tri_tc.clear();
for (int l = 0; l < tri_nodes.contour_size(k); ++l)
{
for (int l = 0; l < tri_nodes.contour_size(k); ++l) {
index = tri_nodes.get_pt( k, l );
tri_v.push_back( index );
@ -1602,6 +1647,7 @@ void TGConstruct::WriteBtgFile( void )
}
}
}
}
std::vector< SGVec3d > wgs84_nodes = nodes.get_wgs84_nodes_as_SGVec3d();
SGSphered d;
@ -1680,15 +1726,15 @@ void TGConstruct::WriteBtgFile( void )
}
void TGConstruct::clean_clipped_polys() {
int i, j;
// Clean the polys
for ( i = 0; i < TG_MAX_AREA_TYPES; ++i ) {
for( j = 0; j < (int)polys_clipped.superpolys[i].size(); ++j ) {
TGPolygon poly = polys_clipped.superpolys[i][j].get_poly();
SG_LOG( SG_CLIPPER, SG_INFO, "Cleaning poly " << get_area_name( (AreaType)i ) << ":" << j+1 << " of " << polys_clipped.superpolys[i].size() );
for ( unsigned int area = 0; area < TG_MAX_AREA_TYPES; area++ ) {
for( unsigned int shape = 0; shape < polys_clipped.area_size(area); shape++ ) {
for ( unsigned int segment = 0; segment < polys_clipped.shape_size(area, shape); segment++ ) {
TGPolygon poly = polys_clipped.get_poly(area, shape, segment);
SG_LOG( SG_CLIPPER, SG_INFO, "Cleaning poly " << get_area_name( (AreaType)area ) <<
":" << shape+1 << "-" << segment << " of " << polys_clipped.area_size(area) );
if ( i == 3 ) {
if ( area == 3 ) {
poly = remove_cycles( poly );
poly = remove_dups( poly );
poly = remove_bad_contours( poly );
@ -1704,23 +1750,26 @@ void TGConstruct::clean_clipped_polys() {
poly = remove_bad_contours( poly );
}
polys_clipped.superpolys[i][j].set_poly( poly );
polys_clipped.set_poly( area, shape, segment, poly );
}
}
}
}
void TGConstruct::CalcTextureCoordinates( void )
{
for (int i = 0; i < TG_MAX_AREA_TYPES; i++) {
for (int j = 0; j < (int)polys_clipped.superpolys[i].size(); ++j ) {
TGPolygon poly = polys_clipped.superpolys[i][j].get_poly();
for ( unsigned int area = 0; area < TG_MAX_AREA_TYPES; area++ ) {
for( unsigned int shape = 0; shape < polys_clipped.area_size(area); shape++ ) {
for ( unsigned int segment = 0; segment < polys_clipped.shape_size(area, shape); segment++ ) {
TGPolygon poly = polys_clipped.get_poly(area, shape, segment);
SG_LOG( SG_CLIPPER, SG_INFO, "Texturing " << get_area_name( (AreaType)area ) << "(" << area << "): " <<
shape+1 << "-" << segment << " of " << polys_clipped.area_size(area) <<
": flag = " << polys_clipped.get_flag(area, shape, segment));
SG_LOG( SG_CLIPPER, SG_INFO, "Texturing " << get_area_name( (AreaType)i ) << "(" << i << "): " << j+1 << " of " << (int)polys_clipped.superpolys[i].size() << ": flag = " << polys_clipped.superpolys[i][j].get_flag());
TGPolygon tri = polys_clipped.superpolys[i][j].get_tris();
TGPolygon tri = polys_clipped.get_tris( area, shape, segment );
TGPolygon tc;
if ( polys_clipped.superpolys[i][j].get_flag() == "textured" ) {
if ( polys_clipped.get_flag( area, shape, segment ) == "textured" ) {
// SG_LOG(SG_GENERAL, SG_DEBUG, "USE TEXTURE PARAMS for tex coord calculations" );
// tc = linear_tex_coords( tri, clipped_polys.texparams[i][j] );
tc = area_tex_coords( tri );
@ -1728,7 +1777,8 @@ void TGConstruct::CalcTextureCoordinates( void )
// SG_LOG(SG_GENERAL, SG_DEBUG, "USE SIMGEAR for tex coord calculations" );
tc = area_tex_coords( tri );
}
polys_clipped.superpolys[i][j].set_texcoords( tc );
polys_clipped.set_texcoords( area, shape, segment, tc );
}
}
}
}

View file

@ -48,39 +48,157 @@
#include <landcover/landcover.hxx>
// TO REMOVE
#include <Geometry/trieles.hxx>
#include <Geometry/trinodes.hxx>
#include <Geometry/trisegs.hxx>
// TO REMOVE
#include "priorities.hxx"
typedef std::vector < int_list > belongs_to_list;
typedef belongs_to_list::iterator belongs_to_list_iterator;
typedef belongs_to_list::const_iterator belongs_to_list_tripoly_iterator;
class TGPolyList
class TGShape
{
public:
superpoly_list superpolys[TG_MAX_AREA_TYPES];
texparams_list texparams[TG_MAX_AREA_TYPES];
TGPolygon safety_base;
TGPolygon clip_mask;
superpoly_list sps;
texparams_list tps;
void SetMask( TGPolygon mask )
{
clip_mask = mask;
}
void BuildMask( void )
{
TGPolygon poly;
clip_mask.erase();
for (unsigned int i=0; i<sps.size(); i++)
{
poly = sps[i].get_poly();
clip_mask = tgPolygonUnion( clip_mask, poly );
}
}
void IntersectPolys( void )
{
TGPolygon original, intersect;
for (unsigned int i=0; i<sps.size(); i++)
{
original = sps[i].get_poly();
intersect = tgPolygonInt( clip_mask, original );
sps[i].set_poly( intersect );
}
}
};
typedef std::vector < TGShape > shape_list;
typedef shape_list::iterator shape_list_iterator;
typedef shape_list::const_iterator const_shape_list_iterator;
class TGLandclass
{
public:
void clear(void)
{
int i;
for (i=0; i<TG_MAX_AREA_TYPES; i++) {
superpolys[i].clear();
shapes[i].clear();
}
}
for (i=0; i<TG_MAX_AREA_TYPES; i++) {
texparams[i].clear();
inline unsigned int area_size( unsigned int area )
{
return shapes[area].size();
}
inline unsigned int shape_size( unsigned int area, unsigned int shape )
{
return shapes[area][shape].sps.size();
}
safety_base.erase();
inline void add_shape( unsigned int area, TGShape shape )
{
shapes[area].push_back( shape );
}
inline TGShape& get_shape( unsigned int area, unsigned int shape )
{
return shapes[area][shape];
}
inline TGPolygon get_mask( unsigned int area, unsigned int shape )
{
return shapes[area][shape].clip_mask;
}
inline void set_mask( unsigned int area, unsigned int shape, TGPolygon mask )
{
shapes[area][shape].clip_mask = mask;
}
inline TGSuperPoly& get_superpoly( unsigned int area, unsigned int shape, unsigned int segment )
{
return shapes[area][shape].sps[segment];
}
inline void set_superpoly( unsigned int area, unsigned int shape, unsigned int segment, TGSuperPoly sp )
{
shapes[area][shape].sps[segment] = sp;
}
inline TGPolygon get_poly( unsigned int area, unsigned int shape, unsigned int segment )
{
return shapes[area][shape].sps[segment].get_poly();
}
inline void set_poly( unsigned int area, unsigned int shape, unsigned int segment, TGPolygon poly )
{
return shapes[area][shape].sps[segment].set_poly( poly );
}
inline TGPolygon get_tris( unsigned int area, unsigned int shape, unsigned int segment )
{
return shapes[area][shape].sps[segment].get_tris();
}
inline void set_tris( unsigned int area, unsigned int shape, unsigned int segment, TGPolygon tris )
{
shapes[area][shape].sps[segment].set_tris( tris );
}
inline Point3D get_face_normal( unsigned int area, unsigned int shape, unsigned int segment, unsigned int tri )
{
return shapes[area][shape].sps[segment].get_face_normal( tri );
}
inline double get_face_area( unsigned int area, unsigned int shape, unsigned int segment, unsigned int tri )
{
return shapes[area][shape].sps[segment].get_face_area( tri );
}
inline std::string get_flag( unsigned int area, unsigned int shape, unsigned int segment )
{
return shapes[area][shape].sps[segment].get_flag();
}
inline std::string get_material( unsigned int area, unsigned int shape, unsigned int segment )
{
return shapes[area][shape].sps[segment].get_material();
}
inline TGPolygon get_texcoords( unsigned int area, unsigned int shape, unsigned int segment )
{
return shapes[area][shape].sps[segment].get_texcoords();
}
inline void set_texcoords( unsigned int area, unsigned int shape, unsigned int segment, TGPolygon tcs )
{
return shapes[area][shape].sps[segment].set_texcoords( tcs );
}
inline TGPolyNodes get_tri_idxs( unsigned int area, unsigned int shape, unsigned int segment )
{
return shapes[area][shape].sps[segment].get_tri_idxs();
}
inline void set_tri_idxs( unsigned int area, unsigned int shape, unsigned int segment, TGPolyNodes tis )
{
return shapes[area][shape].sps[segment].set_tri_idxs( tis );
}
private:
shape_list shapes[TG_MAX_AREA_TYPES];
};
// forward declaration
@ -123,8 +241,8 @@ private:
TGArray array;
// land class polygons
TGPolyList polys_in;
TGPolyList polys_clipped;
TGLandclass polys_in;
TGLandclass polys_clipped;
// All Nodes
TGNodes nodes;
@ -145,7 +263,7 @@ private:
bool ClipLandclassPolys( void );
// Clip Helpers
void move_slivers( TGPolygon& in, TGPolygon& out );
void merge_slivers( TGPolyList& clipped, poly_list& slivers_list );
void merge_slivers( TGLandclass& clipped, poly_list& slivers_list );
// Shared edge Matching
void LoadSharedEdgeData( void );
@ -234,10 +352,6 @@ public:
// node list in geodetic coords (with fixed elevation)
inline point_list get_geod_nodes() const { return nodes.get_geod_nodes(); }
// face normal list (for flat shading)
// inline point_list get_face_normals() const { return face_normals; }
// inline void set_face_normals( point_list n ) { face_normals = n; }
// normal list (for each point) in cart coords (for smooth
// shading)
inline point_list get_point_normals() const { return nodes.get_normals(); }

View file

@ -172,7 +172,7 @@ void TGNodes::Dump( void ) {
if ( node.GetFaces().size() ) {
TGFaceList faces = node.GetFaces();
for (unsigned int j=0; j<faces.size(); j++) {
SG_LOG(SG_GENERAL, SG_ALERT, "\tface " << faces[j].area << "," << faces[j].poly << "," << faces[j].tri );
SG_LOG(SG_GENERAL, SG_ALERT, "\tface " << faces[j].area << "," << faces[j].shape << "," << faces[j].seg << "," << faces[j].tri );
}
}
}

View file

@ -17,7 +17,8 @@
// is a member of.
struct TGFaceLookup {
unsigned int area;
unsigned int poly;
unsigned int shape;
unsigned int seg;
unsigned int tri;
};
typedef std::vector < TGFaceLookup > TGFaceList;
@ -49,11 +50,12 @@ public:
wgs84 = SGVec3d::fromGeod(geod);
}
inline void AddFace( unsigned int area, unsigned int poly, unsigned int tri )
inline void AddFace( unsigned int area, unsigned int shape, unsigned int segment, unsigned int tri )
{
TGFaceLookup face;
face.area = area;
face.poly = poly;
face.shape = shape;
face.seg = segment;
face.tri = tri;
faces.push_back( face );
@ -158,9 +160,9 @@ public:
// return the ith point
inline TGNode get_node( int i ) const { return tg_node_list[i]; }
inline void AddFace( int i, unsigned int area, unsigned int poly, unsigned int tri )
inline void AddFace( int i, unsigned int area, unsigned int shape, unsigned int segment, unsigned int tri )
{
tg_node_list[i].AddFace( area, poly, tri );
tg_node_list[i].AddFace( area, shape, segment, tri );
}
// return the size of the node list

View file

@ -58,6 +58,7 @@ string area_type="Default";
string area_type_col;
int continue_on_errors=0;
int texture_lines = 0;
int seperate_segments = 0;
int max_segment_length=0; // ==0 => don't split
int start_record=0;
bool use_attribute_query=false;
@ -175,16 +176,7 @@ void processLineStringWithMask(OGRLineString* poGeometry,
// make a plygons from the line segments
tg::makePolygons(line,width,segments);
#if 1
for ( i = 0; i < (int)segments.size(); ++i ) {
segment = segments[i];
tgChopNormalPolygon(work_dir, area_type, segment, false);
}
#else
tgChopNormalPolygonsWithMask(work_dir, area_type, segments, false);
#endif
}
void processLineStringWithTextureInfo(OGRLineString* poGeometry,
@ -482,8 +474,10 @@ void processLayer(OGRLayer* poLayer,
}
if (texture_lines) {
processLineStringWithTextureInfo((OGRLineString*)poGeometry,work_dir,area_type_name,width);
} else {
} else if (seperate_segments) {
processLineStringWithMask((OGRLineString*)poGeometry,work_dir,area_type_name,width);
} else {
processLineString((OGRLineString*)poGeometry,work_dir,area_type_name,width);
}
break;
}
@ -497,8 +491,10 @@ void processLayer(OGRLayer* poLayer,
for (int i=0;i<multils->getNumGeometries();i++) {
if (texture_lines) {
processLineStringWithTextureInfo((OGRLineString*)poGeometry,work_dir,area_type_name,width);
} else {
} else if (seperate_segments) {
processLineStringWithMask((OGRLineString*)poGeometry,work_dir,area_type_name,width);
} else {
processLineString((OGRLineString*)poGeometry,work_dir,area_type_name,width);
}
}
break;
@ -614,6 +610,10 @@ int main( int argc, char **argv ) {
argv++;
argc--;
texture_lines=1;
} else if (!strcmp(argv[1],"--seperate-segments")) {
argv++;
argc--;
seperate_segments=1;
} else if (!strcmp(argv[1],"--continue-on-errors")) {
argv++;
argc--;