From 89e69a863fb5d8998d418b499a42596b01c8e925 Mon Sep 17 00:00:00 2001 From: Peter Sadrozinski <psadrozinski@gmail.com> Date: Sun, 2 Dec 2012 11:01:31 -0500 Subject: [PATCH] refactor from TGPolygon and TGSuperPoly to tgPolygon fix for missing texture coordinates. Need to kill, or shrink TGShape / clip ,asks, etc. --- src/BuildTiles/Main/tgconstruct.hxx | 9 +- src/BuildTiles/Main/tgconstruct_cleanup.cxx | 100 +++----- src/BuildTiles/Main/tgconstruct_clip.cxx | 150 ++++++------ src/BuildTiles/Main/tgconstruct_debug.cxx | 4 +- src/BuildTiles/Main/tgconstruct_elevation.cxx | 68 ++---- src/BuildTiles/Main/tgconstruct_landclass.cxx | 6 +- src/BuildTiles/Main/tgconstruct_lookup.cxx | 27 +- src/BuildTiles/Main/tgconstruct_math.cxx | 50 ++-- src/BuildTiles/Main/tgconstruct_output.cxx | 47 ++-- src/BuildTiles/Main/tgconstruct_poly.cxx | 98 +++----- src/BuildTiles/Main/tgconstruct_shared.cxx | 43 ++-- src/BuildTiles/Main/tgconstruct_tesselate.cxx | 19 +- src/BuildTiles/Main/tgconstruct_texture.cxx | 14 +- src/BuildTiles/Main/tglandclass.hxx | 47 ++-- src/BuildTiles/Main/tgshape.cxx | 90 +++---- src/BuildTiles/Main/tgshape.hxx | 7 +- src/Lib/Polygon/polygon.cxx | 230 +++++++++++++++++- src/Lib/Polygon/polygon.hxx | 81 +++++- 18 files changed, 624 insertions(+), 466 deletions(-) diff --git a/src/BuildTiles/Main/tgconstruct.hxx b/src/BuildTiles/Main/tgconstruct.hxx index 04cae17e..fda359c9 100644 --- a/src/BuildTiles/Main/tgconstruct.hxx +++ b/src/BuildTiles/Main/tgconstruct.hxx @@ -124,13 +124,13 @@ private: int LoadLandclassPolys( void ); // Load Data Helpers bool load_poly(const std::string& path); - void add_poly(int area, const TGPolygon &poly, std::string material); + void add_poly(int area, tgPolygon& poly, std::string material); // Clip Data bool ClipLandclassPolys( void ); // Clip Helpers void move_slivers( TGPolygon& in, TGPolygon& out ); - void merge_slivers( TGLandclass& clipped, poly_list& slivers_list ); + void merge_slivers( TGLandclass& clipped, tgcontour_list& sliver_list ); // Shared edge Matching void SaveSharedEdgeDataStage2( void ); @@ -164,7 +164,7 @@ private: void CalcPointNormals( void ); void CalcTextureCoordinates( void ); // Helpers - SGVec3d calc_normal( double area, const SGVec3d& p1, const SGVec3d& p2, const SGVec3d& p3 ); + SGVec3f calc_normal( double area, const SGVec3d& p1, const SGVec3d& p2, const SGVec3d& p3 ); TGPolygon linear_tex_coords( const TGPolygon& tri, const TGTexParams& tp ); TGPolygon area_tex_coords( const TGPolygon& tri ); @@ -173,8 +173,7 @@ private: void AddCustomObjects( void ); // Misc - void calc_normals( std::vector<SGVec3d>& wgs84_nodes, TGSuperPoly& sp ); - double calc_tri_area( int_list& triangle_nodes ); + void calc_normals( std::vector<SGGeod>& geod_nodes, std::vector<SGVec3d>& wgs84_nodes, tgPolygon& sp ); // debug bool IsDebugShape( unsigned int id ); diff --git a/src/BuildTiles/Main/tgconstruct_cleanup.cxx b/src/BuildTiles/Main/tgconstruct_cleanup.cxx index 15a6bb8f..b97d4a70 100644 --- a/src/BuildTiles/Main/tgconstruct_cleanup.cxx +++ b/src/BuildTiles/Main/tgconstruct_cleanup.cxx @@ -39,16 +39,18 @@ using std::string; void TGConstruct::FixTJunctions( void ) { int before, after; + std::vector<SGGeod> points; + nodes.get_geod_nodes( points ); // 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.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); + tgPolygon current = polys_clipped.get_poly(i, j, k); - before = current.total_size(); - current = add_tgnodes_to_poly( current, &nodes ); - after = current.total_size(); + before = current.TotalNodes(); + current = tgPolygon::AddColinearNodes( current, points ); + after = current.TotalNodes(); if (before != 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 ); @@ -67,69 +69,35 @@ void TGConstruct::FixTJunctions( 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( TGLandclass& clipped, poly_list& slivers_list ) { - TGPolygon poly, result, slivers, sliver; - point_list contour; - int original_contours, result_contours; - bool done; - int area, shape, segment, i, j; - int merged = 0; - int total = 0; +void TGConstruct::merge_slivers( TGLandclass& clipped, tgcontour_list& sliver_list ) { + for ( unsigned int area = 0; area < TG_MAX_AREA_TYPES && sliver_list.size(); ++area ) { + if ( is_hole_area( area ) ) { + // don't merge a non-hole sliver in with a hole + continue; + } - for ( i = 0; i < (int)slivers_list.size(); i++ ) { - slivers = slivers_list[i]; + for ( unsigned int s = 0; s < clipped.area_size(area) && sliver_list.size(); ++s ) { + TGShape shape = clipped.get_shape( area, s ); - for ( j = 0; j < slivers.contours(); ++j ) { - // make the sliver polygon - contour = slivers.get_contour( j ); - total++; + unsigned int before = sliver_list.size(); + sliver_list = tgPolygon::MergeSlivers( shape.polys, sliver_list ); + unsigned int after = sliver_list.size(); - sliver.erase(); - sliver.add_contour( contour, 0 ); - done = false; + if (before != after) { + shape.BuildMask(); - for ( area = 0; area < TG_MAX_AREA_TYPES && !done; ++area ) { - if ( is_hole_area( area ) ) { - // don't merge a non-hole sliver in with a hole - continue; - } - - for ( shape = 0; shape < (int)clipped.area_size(area) && !done; ++shape ) { - unsigned int shape_id = clipped.get_shape( area, shape ).id; - - for ( segment = 0; segment < (int)clipped.shape_size(area, shape) && !done; ++segment ) { - - poly = clipped.get_poly( area, shape, segment ); - original_contours = poly.contours(); - result = tgPolygonUnion( poly, sliver ); - result_contours = result.contours(); - - if ( original_contours == result_contours ) { - SG_LOG(SG_GENERAL, SG_INFO, "MERGED SLIVER " << i << ", " << j << " into area " << get_area_name( (AreaType)area ) << " id: " << shape_id << " segment: " << segment ); - - clipped.set_poly( area, shape, segment, result ); - merged++; - - /* add the sliver to the clip_mask, too */ - TGPolygon mask = clipped.get_mask( area, shape ); - result = tgPolygonUnion( mask, sliver ); - clipped.set_mask( area, shape, result ); - - if ( IsDebugShape( shape_id ) ) { - WriteDebugShape( "with_slivers", clipped.get_shape( area, shape ) ); - } - - done = true; - } - } +#if 0 + if ( IsDebugShape( shape.id ) ) { + WriteDebugShape( "with_slivers", shape ); } +#endif } } } - slivers_list.clear(); + SG_LOG(SG_GENERAL, SG_INFO, " UNMERGED SLIVERS: " << sliver_list.size() ); - SG_LOG(SG_GENERAL, SG_INFO, " UNMERGED SLIVERS: " << total - merged ); + sliver_list.clear(); } void TGConstruct::CleanClippedPolys() { @@ -141,35 +109,35 @@ void TGConstruct::CleanClippedPolys() { // step 1 : snap for ( unsigned int segment = 0; segment < polys_clipped.shape_size(area, shape); segment++ ) { - TGPolygon poly = polys_clipped.get_poly(area, shape, segment); - poly = snap(poly, gSnap); + tgPolygon poly = polys_clipped.get_poly(area, shape, segment); + poly = tgPolygon::Snap(poly, gSnap); polys_clipped.set_poly( area, shape, segment, poly ); } if ( IsDebugShape( id ) ) { - WriteDebugShape( "snapped", polys_clipped.get_shape( area, shape ) ); + tgPolygon::ToShapefile( polys_clipped.get_shape( area, shape ).mask, ds_name, "snapped", "" ); } // step 2 : remove_dups for ( unsigned int segment = 0; segment < polys_clipped.shape_size(area, shape); segment++ ) { - TGPolygon poly = polys_clipped.get_poly(area, shape, segment); - poly = remove_dups( poly ); + tgPolygon poly = polys_clipped.get_poly(area, shape, segment); + poly = tgPolygon::RemoveDups( poly ); polys_clipped.set_poly( area, shape, segment, poly ); } if ( IsDebugShape( id ) ) { - WriteDebugShape( "rem dupes", polys_clipped.get_shape( area, shape ) ); + tgPolygon::ToShapefile( polys_clipped.get_shape( area, shape ).mask, ds_name, "rem_dups", "" ); } // step 3 : remove_bad_contours for ( unsigned int segment = 0; segment < polys_clipped.shape_size(area, shape); segment++ ) { - TGPolygon poly = polys_clipped.get_poly(area, shape, segment); - poly = remove_bad_contours( poly ); + tgPolygon poly = polys_clipped.get_poly(area, shape, segment); + poly = tgPolygon::RemoveBadContours( poly ); polys_clipped.set_poly( area, shape, segment, poly ); } if ( IsDebugShape( id ) ) { - WriteDebugShape( "rem bad contours", polys_clipped.get_shape( area, shape ) ); + tgPolygon::ToShapefile( polys_clipped.get_shape( area, shape ).mask, ds_name, "rem_bcs", "" ); } // todo - add up all segments in a shape for printout diff --git a/src/BuildTiles/Main/tgconstruct_clip.cxx b/src/BuildTiles/Main/tgconstruct_clip.cxx index 2fd6df4b..e436f4c2 100644 --- a/src/BuildTiles/Main/tgconstruct_clip.cxx +++ b/src/BuildTiles/Main/tgconstruct_clip.cxx @@ -31,12 +31,12 @@ using std::string; bool TGConstruct::ClipLandclassPolys( void ) { - TGPolygon clipped, tmp; - TGPolygon remains; - TGPolygon safety_base; - poly_list slivers; + tgPolygon clipped, tmp; + tgPolygon remains; + tgPolygon safety_base; + tgcontour_list slivers; int i, j; - Point3D p; + SGGeod p; SGVec2d min, max; bool debug_area, debug_shape; static int accum_idx = 0; @@ -47,118 +47,118 @@ bool TGConstruct::ClipLandclassPolys( void ) { max.x() = bucket.get_center_lon() + 0.5 * bucket.get_width(); max.y() = bucket.get_center_lat() + 0.5 * bucket.get_height(); - tgPolygonInitClipperAccumulator(); + tgAccumulator accum; // set up clipping tile : and remember to add the nodes! - safety_base.erase(); + p = SGGeod::fromDegM( min.x(), min.y(), -9999.0 ); + safety_base.AddNode( 0, p ); + nodes.unique_add( p ); - p = Point3D(min.x(), min.y(), -9999.0); - safety_base.add_node( 0, p ); - nodes.unique_add( p.toSGGeod() ); + p = SGGeod::fromDegM( max.x(), min.y(), -9999.0 ); + safety_base.AddNode( 0, p ); + nodes.unique_add( p ); - p = Point3D(max.x(), min.y(), -9999.0); - safety_base.add_node( 0, p ); - nodes.unique_add( p.toSGGeod() ); + p = SGGeod::fromDegM( max.x(), max.y(), -9999.0 ); + safety_base.AddNode( 0, p ); + nodes.unique_add( p ); - p = Point3D(max.x(), max.y(), -9999.0); - safety_base.add_node( 0, p ); - nodes.unique_add( p.toSGGeod() ); - - p = Point3D(min.x(), max.y(), -9999.0); - safety_base.add_node( 0, p ); - nodes.unique_add( p.toSGGeod() ); + p = SGGeod::fromDegM( min.x(), max.y(), -9999.0 ); + safety_base.AddNode( 0, p ); + nodes.unique_add( p ); // set up land mask, we clip most things to this since it is our // best representation of land vs. ocean. If we have other less // accurate data that spills out into the ocean, we want to just // clip it. // also set up a mask for all water and islands - TGPolygon land_mask, water_mask, island_mask; - land_mask.erase(); - water_mask.erase(); - island_mask.erase(); + tgPolygon land_mask, water_mask, island_mask; + tgpolygon_list land_list, water_list, island_list; for ( i = 0; i < TG_MAX_AREA_TYPES; i++ ) { if ( is_landmass_area( i ) && !ignoreLandmass ) { for ( unsigned int j = 0; j < polys_in.area_size(i); ++j ) { - land_mask = tgPolygonUnion( polys_in.get_mask(i, j), land_mask ); + land_list.push_back( polys_in.get_mask(i, j) ); } } else if ( is_water_area( i ) ) { for (unsigned int j = 0; j < polys_in.area_size(i); j++) { - water_mask = tgPolygonUnion( polys_in.get_mask(i, j), water_mask ); + water_list.push_back( polys_in.get_mask(i, j) ); } } else if ( is_island_area( i ) ) { for (unsigned int j = 0; j < polys_in.area_size(i); j++) { - island_mask = tgPolygonUnion( polys_in.get_mask(i, j), island_mask ); + island_list.push_back( polys_in.get_mask(i, j) ); } } } + land_mask = tgPolygon::Union( land_list ); + water_mask = tgPolygon::Union( water_list ); + island_mask = tgPolygon::Union( island_list ); + // Dump the masks if ( debug_all || debug_shapes.size() || debug_areas.size() ) { - WriteDebugPoly( "land_mask", "", land_mask ); - WriteDebugPoly( "water_mask", "", water_mask ); - WriteDebugPoly( "island_mask", "", island_mask ); + tgPolygon::ToShapefile( land_mask, ds_name, "land_mask", "" ); + tgPolygon::ToShapefile( water_mask, ds_name, "water_mask", "" ); + tgPolygon::ToShapefile( island_mask, ds_name, "island_mask", "" ); } // process polygons in priority order for ( i = 0; i < TG_MAX_AREA_TYPES; ++i ) { debug_area = IsDebugArea( i ); for( j = 0; j < (int)polys_in.area_size(i); ++j ) { - TGPolygon current = polys_in.get_mask(i, j); + tgPolygon current = polys_in.get_mask(i, j); debug_shape = IsDebugShape( polys_in.get_shape( i, j ).id ); SG_LOG( SG_CLIPPER, SG_INFO, "Clipping " << get_area_name( (AreaType)i ) << "(" << i << "):" << j+1 << " of " << polys_in.area_size(i) << " id " << polys_in.get_shape( i, j ).id ); tmp = current; - // if not a hole, clip the area to the land_mask if ( !ignoreLandmass && !is_hole_area( i ) ) { - tmp = tgPolygonInt( tmp, land_mask ); + tmp = tgPolygon::Intersect( tmp, land_mask ); } // if a water area, cut out potential islands if ( is_water_area( i ) ) { // clip against island mask - tmp = tgPolygonDiff( tmp, island_mask ); + tmp = tgPolygon::Diff( tmp, island_mask ); } if ( debug_area || debug_shape ) { char layer[32]; char name[32]; + sprintf(layer, "pre_clip_%d", polys_in.get_shape( i, j ).id ); sprintf(name, "shape %d,%d", i,j); - WriteDebugPoly( layer, name, tmp ); + tgPolygon::ToShapefile( tmp, ds_name, layer, name ); sprintf(layer, "pre_clip_accum_%d_%d", accum_idx, polys_in.get_shape( i, j ).id ); - sprintf(name, "shape_accum %d,%d", i,j); - - tgPolygonDumpAccumulator( ds_name, layer, name ); + accum.ToShapefiles( ds_name, layer ); } - clipped = tgPolygonDiffClipperWithAccumulator( tmp ); + clipped = accum.Diff( tmp ); if ( debug_area || debug_shape ) { char layer[32]; char name[32]; + sprintf(layer, "post_clip_%d", polys_in.get_shape( i, j ).id ); sprintf(name, "shape %d,%d", i,j); - WriteDebugPoly( layer, name, clipped ); + + tgPolygon::ToShapefile( clipped, ds_name, layer, name ); } - + // only add to output list if the clip left us with a polygon - if ( clipped.contours() > 0 ) { + if ( clipped.Contours() > 0 ) { #if FIND_SLIVERS // move slivers from clipped polygon to slivers polygon - tgPolygonFindSlivers( clipped, slivers ); + tgPolygon::RemoveSlivers( clipped, slivers ); #endif // add the sliverless result polygon to the clipped polys list - if ( clipped.contours() > 0 ) { + if ( clipped.Contours() > 0 ) { TGShape shape; // copy all of the superpolys and texparams @@ -166,40 +166,39 @@ bool TGConstruct::ClipLandclassPolys( void ) { shape.textured = polys_in.get_textured( i, j ); shape.id = polys_in.get_shape( i, j ).id; - shape.area= polys_in.get_shape( i, j ).area; - shape.sps = polys_in.get_shape( i, j ).sps; - shape.tps = polys_in.get_shape( i, j ).tps; + shape.area = polys_in.get_shape( i, j ).area; + shape.polys = polys_in.get_shape( i, j ).polys; // shape.sps.push_back( sp ); polys_clipped.add_shape( i, shape ); +#if 0 if ( debug_area || debug_shape ) { WriteDebugShape( "clipped", shape ); } +#endif } } - if ( debug_shape ) { - tgPolygonAddToClipperAccumulator( tmp, true ); - } else { - tgPolygonAddToClipperAccumulator( tmp, false ); - } - + accum.Add( tmp ); if ( debug_area || debug_shape ) { char layer[32]; - char name[32]; sprintf(layer, "post_clip_accum_%d_%d", accum_idx, polys_in.get_shape( i, j ).id ); - sprintf(name, "shape_accum %d,%d", i,j); - tgPolygonDumpAccumulator( ds_name, layer, name ); + accum.ToShapefiles( ds_name, layer ); } + accum_idx++; } } if ( debug_all || debug_shapes.size() || debug_areas.size() ) { // Dump the sliver list - WriteDebugPolys( "poly_slivers", slivers ); + char name[32]; + for ( unsigned int i=0; i<slivers.size(); i++ ) { + sprintf( name, "sliver %4d", i ); + tgContour::ToShapefile( slivers[i], ds_name, "slivers", name ); + } } #if FIND_SLIVERS @@ -210,51 +209,44 @@ bool TGConstruct::ClipLandclassPolys( void ) { slivers.clear(); // finally, what ever is left over goes to ocean - remains = tgPolygonDiffClipperWithAccumulator( safety_base ); + remains = accum.Diff( safety_base ); - if ( remains.contours() > 0 ) { + if ( remains.Contours() > 0 ) { // cout << "remains contours = " << remains.contours() << endl; // move slivers from remains polygon to slivers polygon #if FIND_SLIVERS - tgPolygonFindSlivers( remains, slivers ); -#endif - // cout << " After sliver move:" << endl; - // cout << " remains = " << remains.contours() << endl; - // cout << " slivers = " << slivers.contours() << endl; + tgPolygon::RemoveSlivers( remains, slivers ); -#if FIND_SLIVERS - // merge any slivers with previously clipped - // neighboring polygons if ( slivers.size() > 0 ) { if ( debug_all || debug_shapes.size() || debug_areas.size() ) { // Dump the sliver list - WriteDebugPolys( "remains_slivers", slivers ); + char name[32]; + for ( unsigned int i=0; i<slivers.size(); i++ ) { + sprintf( name, "sliver %4d", i ); + tgContour::ToShapefile( slivers[i], ds_name, "remains slivers", name ); + } } merge_slivers(polys_clipped, slivers); } #endif - if ( remains.contours() > 0 ) { - TGSuperPoly sp; + if ( remains.Contours() > 0 ) { TGShape shape; string material = get_area_name(get_sliver_target_area_type()); + remains.SetMaterial( material ); - sp.set_material( material ); - sp.set_poly( remains ); shape.SetMask( remains ); shape.textured = false; - shape.sps.push_back( sp ); + shape.polys.push_back( remains ); polys_clipped.add_shape( (int)get_sliver_target_area_type(), shape ); } } - tgPolygonFreeClipperAccumulator(); - // 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++ ) { @@ -267,14 +259,14 @@ bool TGConstruct::ClipLandclassPolys( void ) { 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 ); + tgPolygon poly = polys_clipped.get_poly( area, shape, segment ); 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++) { + for (unsigned int con=0; con < poly.Contours(); con++) { + for (unsigned int node = 0; node < poly.ContourSize( con ); node++) { // ensure we have all nodes... - nodes.unique_add( poly.get_pt( con, node ).toSGGeod() ); + nodes.unique_add( poly.GetNode( con, node ) ); } } } diff --git a/src/BuildTiles/Main/tgconstruct_debug.cxx b/src/BuildTiles/Main/tgconstruct_debug.cxx index ba3e4af6..a7566abb 100644 --- a/src/BuildTiles/Main/tgconstruct_debug.cxx +++ b/src/BuildTiles/Main/tgconstruct_debug.cxx @@ -133,6 +133,7 @@ bool TGConstruct::IsDebugArea( unsigned int area ) return is_debug; } +#if 0 void TGConstruct::WriteDebugShape( const char* layer_name, const TGShape& shape ) { char name[64]; @@ -141,7 +142,7 @@ void TGConstruct::WriteDebugShape( const char* layer_name, const TGShape& shape ds_id = tgShapefileOpenDatasource( ds_name ); l_id = tgShapefileOpenLayer( ds_id, layer_name ); - tgShapefileCreateFeature( ds_id, l_id, shape.clip_mask, name ); + tgShapefileCreateFeature( ds_id, l_id, shape.mask, name ); // close after each write ds_id = tgShapefileCloseDatasource( ds_id ); @@ -171,6 +172,7 @@ void TGConstruct::WriteDebugPolys( const char* layer_name, const poly_list& poly // close after each write ds_id = tgShapefileCloseDatasource( ds_id ); } +#endif // TODO : Add to TGNodes class #if 0 diff --git a/src/BuildTiles/Main/tgconstruct_elevation.cxx b/src/BuildTiles/Main/tgconstruct_elevation.cxx index 4968677d..d3c397ab 100644 --- a/src/BuildTiles/Main/tgconstruct_elevation.cxx +++ b/src/BuildTiles/Main/tgconstruct_elevation.cxx @@ -91,11 +91,10 @@ static double distanceSphere( const SGGeoc& p1, const SGGeod& p2 ) { // hopefully, this will get better when we have the area lookup via superpoly... void TGConstruct::CalcElevations( void ) { - TGPolyNodes tri_nodes; - double e1, e2, e3, min; - int n1, n2, n3; std::vector<SGGeod> raw_nodes; SGGeoc p; + double e1, e2, e3, min; + int n1, n2, n3; SG_LOG(SG_GENERAL, SG_ALERT, "fixing node heights"); @@ -110,6 +109,7 @@ void TGConstruct::CalcElevations( void ) } nodes.get_geod_nodes(raw_nodes); + // now flatten some stuff for (unsigned int area = 0; area < TG_MAX_AREA_TYPES; area++) { if ( is_lake_area( (AreaType)area ) ) { @@ -117,19 +117,14 @@ void TGConstruct::CalcElevations( void ) for (int segment = 0; segment < (int)polys_clipped.shape_size(area, shape); ++segment ) { 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 ); + tgPolygon poly = polys_clipped.get_poly( area, shape, segment ); - 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( tri, 0 ); + for (unsigned int tri=0; tri < poly.Triangles(); tri++) { + n1 = poly.GetTriIdx( tri, 0 ); e1 = nodes.get_node(n1).GetPosition().getElevationM(); - n2 = tri_nodes.get_pt( tri, 1 ); + n2 = poly.GetTriIdx( tri, 1 ); e2 = nodes.get_node(n2).GetPosition().getElevationM(); - n3 = tri_nodes.get_pt( tri, 2 ); + n3 = poly.GetTriIdx( tri, 2 ); e3 = nodes.get_node(n3).GetPosition().getElevationM(); min = e1; @@ -149,20 +144,14 @@ void TGConstruct::CalcElevations( void ) for (int segment = 0; segment < (int)polys_clipped.shape_size(area, shape); ++segment ) { 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 ); + tgPolygon poly = polys_clipped.get_poly( area, shape, segment ); - 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( tri, 0 ); + for (unsigned int tri=0; tri < poly.Triangles(); tri++) { + n1 = poly.GetTriIdx( tri, 0 ); e1 = nodes.get_node(n1).GetPosition().getElevationM(); - n2 = tri_nodes.get_pt( tri, 1 ); + n2 = poly.GetTriIdx( tri, 1 ); e2 = nodes.get_node(n2).GetPosition().getElevationM(); - n3 = tri_nodes.get_pt( tri, 2 ); + n3 = poly.GetTriIdx( tri, 2 ); e3 = nodes.get_node(n3).GetPosition().getElevationM(); min = e1; @@ -192,20 +181,14 @@ void TGConstruct::CalcElevations( void ) for (int segment = 0; segment < (int)polys_clipped.shape_size(area, shape); ++segment ) { 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 ); + tgPolygon poly = polys_clipped.get_poly( area, shape, segment ); - 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( tri, 0 ); + for (unsigned int tri=0; tri < poly.Triangles(); tri++) { + n1 = poly.GetTriIdx( tri, 0 ); e1 = nodes.get_node(n1).GetPosition().getElevationM(); - n2 = tri_nodes.get_pt( tri, 1 ); + n2 = poly.GetTriIdx( tri, 1 ); e2 = nodes.get_node(n2).GetPosition().getElevationM(); - n3 = tri_nodes.get_pt( tri, 2 ); + n3 = poly.GetTriIdx( tri, 2 ); e3 = nodes.get_node(n3).GetPosition().getElevationM(); min = e1; @@ -235,17 +218,12 @@ void TGConstruct::CalcElevations( void ) for (int segment = 0; segment < (int)polys_clipped.shape_size(area, shape); ++segment ) { 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 ); + tgPolygon poly = polys_clipped.get_poly( area, shape, segment ); - 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( tri, 0 ); - n2 = tri_nodes.get_pt( tri, 1 ); - n3 = tri_nodes.get_pt( tri, 2 ); + for (unsigned int tri=0; tri < poly.Triangles(); tri++) { + n1 = poly.GetTriIdx( tri, 0 ); + n2 = poly.GetTriIdx( tri, 1 ); + n3 = poly.GetTriIdx( tri, 2 ); nodes.SetElevation( n1, 0.0 ); nodes.SetElevation( n2, 0.0 ); diff --git a/src/BuildTiles/Main/tgconstruct_landclass.cxx b/src/BuildTiles/Main/tgconstruct_landclass.cxx index 62021048..76166f74 100644 --- a/src/BuildTiles/Main/tgconstruct_landclass.cxx +++ b/src/BuildTiles/Main/tgconstruct_landclass.cxx @@ -217,12 +217,13 @@ static void fix_land_cover_assignments( TGConstruct& c ) { int TGConstruct::load_landcover() { int count = 0; +#if 0 try { LandCover cover(get_cover()); - TGPolygon polys[TG_MAX_AREA_TYPES]; - TGPolygon poly; // working polygon + tgPolygon polys[TG_MAX_AREA_TYPES]; + tgPolygon poly; // working polygon // Get the lower left (SW) corner of the tile double base_lon = bucket.get_center_lon() @@ -275,6 +276,7 @@ int TGConstruct::load_landcover() exit(-1); } +#endif // Return the number of polygons actually read. return count; } diff --git a/src/BuildTiles/Main/tgconstruct_lookup.cxx b/src/BuildTiles/Main/tgconstruct_lookup.cxx index 4cf6b493..c00d44ec 100644 --- a/src/BuildTiles/Main/tgconstruct_lookup.cxx +++ b/src/BuildTiles/Main/tgconstruct_lookup.cxx @@ -40,22 +40,21 @@ void TGConstruct::LookupNodesPerVertex( void ) 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; + tgPolygon poly = polys_clipped.get_poly( area, shape, segment ); - 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 ).toSGGeod() ); + for (unsigned int tri=0; tri < poly.Triangles(); tri++) { + for (unsigned int vertex = 0; vertex < 3; vertex++) { + int idx = nodes.find( poly.GetTriNode( tri, vertex ) ); if (idx >= 0) { - tri_nodes.add_node( tri, idx ); + poly.SetTriIdx( tri, vertex, idx ); } else { - SG_LOG(SG_GENERAL, SG_ALERT, "didn't find vertex! " << tris.get_pt( tri, vertex ) ); + SG_LOG(SG_GENERAL, SG_ALERT, "didn't find vertex! " << poly.GetTriNode( tri, vertex ) ); exit(0); } } } - polys_clipped.set_tri_idxs(area, shape, segment, tri_nodes); + + polys_clipped.set_poly( area, shape, segment, poly ); } } } @@ -69,12 +68,12 @@ void TGConstruct::LookupFacesPerNode( void ) 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); + tgPolygon poly = polys_clipped.get_poly(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 ).toSGGeod() ); - nodes.AddFace( n, area, shape, segment, tri ); + for (unsigned int tri=0; tri < poly.Triangles(); tri++) { + for (int v = 0; v < 3; v++) { + int i = poly.GetTriIdx( tri, v ); + nodes.AddFace( i, area, shape, segment, tri ); } } } diff --git a/src/BuildTiles/Main/tgconstruct_math.cxx b/src/BuildTiles/Main/tgconstruct_math.cxx index 481c4907..0c02a822 100644 --- a/src/BuildTiles/Main/tgconstruct_math.cxx +++ b/src/BuildTiles/Main/tgconstruct_math.cxx @@ -31,6 +31,7 @@ //using std::string; +#if 0 double TGConstruct::calc_tri_area( int_list& triangle_nodes ) { SGGeod p1 = nodes.get_node( triangle_nodes[0] ).GetPosition(); SGGeod p2 = nodes.get_node( triangle_nodes[1] ).GetPosition(); @@ -38,9 +39,11 @@ double TGConstruct::calc_tri_area( int_list& triangle_nodes ) { return triangle_area( p1, p2, p3 ); } +#endif -SGVec3d TGConstruct::calc_normal( double area, const SGVec3d& p1, const SGVec3d& p2, const SGVec3d& p3 ) { - SGVec3d v1, v2, normal; +SGVec3f TGConstruct::calc_normal( double area, const SGVec3d& p1, const SGVec3d& p2, const SGVec3d& p3 ) { + SGVec3f v1, v2; + SGVec3f normal; // do some sanity checking. With the introduction of landuse // areas, we can get some long skinny triangles that blow up our @@ -62,7 +65,7 @@ SGVec3d TGConstruct::calc_normal( double area, const SGVec3d& p1, const SGVec3d& } if ( degenerate ) { - normal = normalize(SGVec3d(p1.x(), p1.y(), p1.z())); + normal = normalize(SGVec3f(p1.x(), p1.y(), p1.z())); } else { v1[0] = p2.x() - p1.x(); v1[1] = p2.y() - p1.y(); @@ -76,34 +79,26 @@ SGVec3d TGConstruct::calc_normal( double area, const SGVec3d& p1, const SGVec3d& return normal; } -void TGConstruct::calc_normals( std::vector<SGVec3d>& wgs84_nodes, TGSuperPoly& sp ) { +void TGConstruct::calc_normals( std::vector<SGGeod>& geod_nodes, std::vector<SGVec3d>& wgs84_nodes, tgPolygon& poly ) { // for each face in the superpoly, calculate a face normal - SGVec3d normal; - TGPolyNodes tri_nodes = sp.get_tri_idxs(); - int_list face_nodes; - double_list face_areas; - point_list face_normals; + SGVec3f normal; double area; - face_normals.clear(); - face_areas.clear(); + for (unsigned int tri = 0; tri < poly.Triangles(); tri++) { + SGGeod g1 = geod_nodes[ poly.GetTriIdx( tri, 0 ) ]; + SGGeod g2 = geod_nodes[ poly.GetTriIdx( tri, 1 ) ]; + SGGeod g3 = geod_nodes[ poly.GetTriIdx( tri, 2 ) ]; - for (int i=0; i<tri_nodes.contours(); i++) { - face_nodes = tri_nodes.get_contour(i); + SGVec3d v1 = wgs84_nodes[ poly.GetTriIdx( tri, 0 ) ]; + SGVec3d v2 = wgs84_nodes[ poly.GetTriIdx( tri, 1 ) ]; + SGVec3d v3 = wgs84_nodes[ poly.GetTriIdx( tri, 2 ) ]; - SGVec3d p1 = wgs84_nodes[ face_nodes[0] ]; - SGVec3d p2 = wgs84_nodes[ face_nodes[1] ]; - SGVec3d p3 = wgs84_nodes[ face_nodes[2] ]; + area = triangle_area( g1, g2, g3 ); + normal = calc_normal( area, v1, v2, v3 ); - area = calc_tri_area( face_nodes ); - normal = calc_normal( area, p1, p2, p3 ); - - face_normals.push_back( Point3D::fromSGVec3( normal ) ); - face_areas.push_back( area ); + poly.SetTriFaceArea( tri, area ); + poly.SetTriFaceNormal( tri, normal ); } - - sp.set_face_normals( face_normals ); - sp.set_face_areas( face_areas ); } void TGConstruct::CalcFaceNormals( void ) @@ -112,11 +107,14 @@ void TGConstruct::CalcFaceNormals( void ) std::vector<SGVec3d> wgs84_nodes; nodes.get_wgs84_nodes( wgs84_nodes ); + std::vector<SGGeod> geod_nodes; + nodes.get_geod_nodes( geod_nodes ); + 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 ) ); + calc_normals( geod_nodes, wgs84_nodes, polys_clipped.get_poly( area, shape, segment ) ); } } } @@ -156,10 +154,8 @@ void TGConstruct::CalcPointNormals( void ) unsigned int shape = faces[j].shape; unsigned int segment = faces[j].seg; unsigned int tri = faces[j].tri; - int_list face_nodes; normal = polys_clipped.get_face_normal( at, shape, segment, tri ).toSGVec3d(); - 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 diff --git a/src/BuildTiles/Main/tgconstruct_output.cxx b/src/BuildTiles/Main/tgconstruct_output.cxx index 4b27acf2..208a7c4a 100644 --- a/src/BuildTiles/Main/tgconstruct_output.cxx +++ b/src/BuildTiles/Main/tgconstruct_output.cxx @@ -29,7 +29,9 @@ #include <simgear/io/sg_binobj.hxx> #include <simgear/structure/exception.hxx> #include <simgear/debug/logstream.hxx> -#include <Geometry/trinodes.hxx> + +#include <Polygon/tg_unique_vec3f.hxx> +#include <Polygon/tg_unique_vec2f.hxx> #include "tgconstruct.hxx" @@ -111,9 +113,8 @@ void TGConstruct::AddCustomObjects( void ) { void TGConstruct::WriteBtgFile( void ) { - TGTriNodes normals, texcoords; - normals.clear(); - texcoords.clear(); + UniqueSGVec3fSet normals; + UniqueSGVec2fSet texcoords; group_list pts_v; pts_v.clear(); group_list pts_n; pts_n.clear(); @@ -134,6 +135,8 @@ void TGConstruct::WriteBtgFile( void ) int_list pt_n, tri_n, strip_n; int_list tri_tc, strip_tc; + SG_LOG(SG_GENERAL, SG_INFO, "Output triangles" ); + for (unsigned int area = 0; area < TG_MAX_AREA_TYPES; area++) { // only tesselate non holes if ( !is_hole_area( area ) ) { @@ -142,24 +145,24 @@ void TGConstruct::WriteBtgFile( void ) 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.get_tri_idxs(area, shape, segment); - TGPolygon tri_txs = polys_clipped.get_texcoords(area, shape, segment); + tgPolygon poly = polys_clipped.get_poly(area, shape, segment); string material = polys_clipped.get_material(area, shape, segment); - for (int k = 0; k < tri_nodes.contours(); ++k) { + SG_LOG(SG_GENERAL, SG_INFO, " num tris " << poly.Triangles() ); + + for (unsigned int k = 0; k < poly.Triangles(); ++k) { tri_v.clear(); tri_n.clear(); tri_tc.clear(); - for (int l = 0; l < tri_nodes.contour_size(k); ++l) { - index = tri_nodes.get_pt( k, l ); + for (int l = 0; l < 3; ++l) { + index = poly.GetTriIdx( k, l ); tri_v.push_back( index ); // add the node's normal - index = normals.unique_add( Point3D::fromSGVec3( nodes.GetNormal( index ) ) ); + index = normals.add( nodes.GetNormal( index ) ); tri_n.push_back( index ); - Point3D tc = tri_txs.get_pt( k, l ); - index = texcoords.unique_add( tc ); + index = texcoords.add( poly.GetTriTexCoord( k, l ) ); tri_tc.push_back( index ); } tris_v.push_back( tri_v ); @@ -167,6 +170,8 @@ void TGConstruct::WriteBtgFile( void ) tris_tc.push_back( tri_tc ); material = polys_clipped.get_material(area, shape, segment); + SG_LOG(SG_GENERAL, SG_INFO, "Add tri material " << material); + tri_materials.push_back( material ); } } @@ -203,27 +208,13 @@ void TGConstruct::WriteBtgFile( void ) string txtname = bucket.gen_index_str(); txtname += ".txt"; - std::vector< SGVec3f > normals_3f; - for (int i=0; i < (int)normals.get_node_list().size(); i++ ) - { - Point3D node = normals.get_node_list()[i]; - normals_3f.push_back( node.toSGVec3f() ); - } - - std::vector< SGVec2f > texcoords_2f; - for (int i=0; i < (int)texcoords.get_node_list().size(); i++ ) - { - Point3D node = texcoords.get_node_list()[i]; - texcoords_2f.push_back( node.toSGVec2f() ); - } - SGBinObject obj; obj.set_gbs_center( gbs_center ); obj.set_gbs_radius( gbs_radius ); obj.set_wgs84_nodes( wgs84_nodes ); - obj.set_normals( normals_3f ); - obj.set_texcoords( texcoords_2f ); + obj.set_normals( normals.get_list() ); + obj.set_texcoords( texcoords.get_list() ); obj.set_pts_v( pts_v ); obj.set_pts_n( pts_n ); obj.set_pt_materials( pt_materials ); diff --git a/src/BuildTiles/Main/tgconstruct_poly.cxx b/src/BuildTiles/Main/tgconstruct_poly.cxx index 9dbf4cac..cf76696b 100644 --- a/src/BuildTiles/Main/tgconstruct_poly.cxx +++ b/src/BuildTiles/Main/tgconstruct_poly.cxx @@ -38,16 +38,12 @@ using std::string; static unsigned int cur_poly_id = 0; // Add a polygon to the clipper. - only used by load_osgb36_poly - make that function more like ogr load -void TGConstruct::add_poly( int area, const TGPolygon &poly, string material ) { +void TGConstruct::add_poly( int area, tgPolygon &poly, string material ) { TGShape shape; - TGSuperPoly sp; if ( area < TG_MAX_AREA_TYPES ) { - sp.set_poly( poly ); - sp.set_material( material ); - - shape.sps.push_back( sp ); - + poly.SetMaterial( material ); + shape.polys.push_back( poly ); polys_in.add_shape( area, shape ); } else { SG_LOG( SG_CLIPPER, SG_ALERT, "Polygon type out of range = " << area); @@ -73,9 +69,8 @@ bool TGConstruct::load_poly(const string& path) { exit(-1); } - TGPolygon poly; - TGTexParams tp; - Point3D p; + tgPolygon poly; + tgTexParams tp; // (this could break things, why is it here) in >> skipcomment; while ( !in.eof() ) { @@ -120,40 +115,29 @@ bool TGConstruct::load_poly(const string& path) { // Generate a new Shape for the poly TGShape shape; - TGSuperPoly sp; - + tgPolygon poly; + SGGeod p; + for (k=0; k<num_polys;k++) { if ( with_tp ) { - double width, length; - double heading; - double minu, maxu; - double minv, maxv; - in >> x; in >> y; - in >> width; - in >> length; - in >> heading; - in >> minu; - in >> maxu; - in >> minv; - in >> maxv; + tp.ref = SGGeod::fromDeg(x,y); - tp.set_ref( SGGeod::fromDeg(x,y) ); - tp.set_width( width ); - tp.set_length( length ); - tp.set_heading( heading ); - tp.set_minu( minu ); - tp.set_maxu( maxu ); - tp.set_minv( minv ); - tp.set_maxv( maxv ); + in >> tp.width; + in >> tp.length; + in >> tp.heading; + in >> tp.minu; + in >> tp.maxu; + in >> tp.minv; + in >> tp.maxv; + poly.SetTexParams( tp ); } in >> contours; - poly.erase(); - + poly.Erase(); for ( i = 0; i < contours; ++i ) { in >> count; @@ -172,14 +156,13 @@ bool TGConstruct::load_poly(const string& path) { startz = -9999.0; } - p = Point3D(startx+nudge, starty+nudge, startz); - p.snap( gSnap ); - poly.add_node( i, p ); + p = SGGeod::fromDegM(startx+nudge, starty+nudge, startz ); + poly.AddNode( i, p ); if ( poly3d ) { - nodes.unique_add_fixed_elevation( p.toSGGeod() ); + nodes.unique_add_fixed_elevation( p ); } else { - nodes.unique_add( p.toSGGeod() ); + nodes.unique_add( p ); } for ( j = 1; j < count - 1; ++j ) { @@ -190,13 +173,14 @@ bool TGConstruct::load_poly(const string& path) { } else { z = -9999.0; } - p = Point3D( x+nudge, y+nudge, z ); - p.snap( gSnap ); - poly.add_node( i, p ); + + p = SGGeod::fromDegM( x+nudge, y+nudge, z ); + poly.AddNode( i, p ); + if ( poly3d ) { - nodes.unique_add_fixed_elevation( p.toSGGeod() ); + nodes.unique_add_fixed_elevation( p ); } else { - nodes.unique_add( p.toSGGeod() ); + nodes.unique_add( p ); } } @@ -213,31 +197,27 @@ bool TGConstruct::load_poly(const string& path) { (fabs(startz - lastz) < SG_EPSILON) ) { // last point same as first, discard } else { - p = Point3D( lastx+nudge, lasty+nudge, lastz ); - p.snap( gSnap ); - poly.add_node( i, p ); + p = SGGeod::fromDegM( lastx+nudge, lasty+nudge, lastz ); + poly.AddNode( i, p ); + if ( poly3d ) { - nodes.unique_add_fixed_elevation( p.toSGGeod() ); + nodes.unique_add_fixed_elevation( p ); } else { - nodes.unique_add( p.toSGGeod() ); + nodes.unique_add( p ); } } } - poly = remove_dups( poly ); - - sp.set_poly( poly ); - sp.set_material( material ); - shape.sps.push_back( sp ); + poly = tgPolygon::Snap( poly, gSnap ); + poly = tgPolygon::RemoveDups( poly ); + poly.SetMaterial( material ); if ( with_tp ) { shape.textured = true; - shape.tps.push_back( tp ); - } - else - { + } else { shape.textured = false; } + shape.polys.push_back( poly ); in >> skipcomment; } @@ -250,7 +230,7 @@ bool TGConstruct::load_poly(const string& path) { polys_in.add_shape( area, shape ); if ( IsDebugShape( shape.id ) ) { - WriteDebugShape( "loaded", shape ); + tgPolygon::ToShapefile( shape.mask, ds_name, "loaded", "" ); } } diff --git a/src/BuildTiles/Main/tgconstruct_shared.cxx b/src/BuildTiles/Main/tgconstruct_shared.cxx index ee591545..a5287b8e 100644 --- a/src/BuildTiles/Main/tgconstruct_shared.cxx +++ b/src/BuildTiles/Main/tgconstruct_shared.cxx @@ -128,22 +128,21 @@ void TGConstruct::WriteNeighborFaces( gzFile& fp, Point3D pt ) unsigned int segment = faces[j].seg; unsigned int tri = faces[j].tri; - int_list face_nodes = polys_clipped.get_tri_idxs( at, shape, segment ).get_contour( tri ) ; - { - SGGeod p1 = nodes.get_node( face_nodes[0] ).GetPosition(); - SGGeod p2 = nodes.get_node( face_nodes[1] ).GetPosition(); - SGGeod p3 = nodes.get_node( face_nodes[2] ).GetPosition(); + tgPolygon poly = polys_clipped.get_poly( at, shape, segment ); - SGVec3d wgs_p1 = nodes.get_node( face_nodes[0] ).GetWgs84(); - SGVec3d wgs_p2 = nodes.get_node( face_nodes[1] ).GetWgs84(); - SGVec3d wgs_p3 = nodes.get_node( face_nodes[2] ).GetWgs84(); + SGGeod p1 = nodes.get_node( poly.GetTriIdx( tri, 0) ).GetPosition(); + SGGeod p2 = nodes.get_node( poly.GetTriIdx( tri, 1) ).GetPosition(); + SGGeod p3 = nodes.get_node( poly.GetTriIdx( tri, 2) ).GetPosition(); - double face_area = triangle_area( p1, p2, p3 ); - SGVec3d face_normal = calc_normal( face_area, wgs_p1, wgs_p2, wgs_p3 ); + SGVec3d wgs_p1 = nodes.get_node( poly.GetTriIdx( tri, 0) ).GetWgs84(); + SGVec3d wgs_p2 = nodes.get_node( poly.GetTriIdx( tri, 0) ).GetWgs84(); + SGVec3d wgs_p3 = nodes.get_node( poly.GetTriIdx( tri, 0) ).GetWgs84(); - sgWriteDouble( fp, face_area ); - sgWritedVec3( fp, face_normal ); - } + double face_area = triangle_area( p1, p2, p3 ); + SGVec3f face_normal = calc_normal( face_area, wgs_p1, wgs_p2, wgs_p3 ); + + sgWriteDouble( fp, face_area ); + sgWriteVec3( fp, face_normal ); } } @@ -180,20 +179,20 @@ void TGConstruct::ReadNeighborFaces( gzFile& fp ) for (int i=0; i<count; i++) { TGNeighborFaces* pFaces; - Point3D node; + SGGeod node; int num_faces; - sgReadPoint3D( fp, node ); + sgReadGeod( fp, node ); // look to see if we already have this node // If we do, (it's a corner) add more faces to it. // otherwise, initialize it with our elevation data - pFaces = FindNeighborFaces( node ); + pFaces = FindNeighborFaces( Point3D::fromSGGeod( node ) ); if ( !pFaces ) { - pFaces = AddNeighborFaces( node ); + pFaces = AddNeighborFaces( Point3D::fromSGGeod( node ) ); // new face - let's add our elevation first - int idx = nodes.find( node.toSGGeod() ); + int idx = nodes.find( node ); if (idx >= 0) { TGNode local = nodes.get_node( idx ); pFaces->elevations.push_back( local.GetPosition().getElevationM() ); @@ -201,19 +200,19 @@ void TGConstruct::ReadNeighborFaces( gzFile& fp ) } // remember all of the elevation data for the node, so we can average - pFaces->elevations.push_back( node.z() ); + pFaces->elevations.push_back( node.getElevationM() ); sgReadInt( fp, &num_faces ); for (int j=0; j<num_faces; j++) { double area; - Point3D normal; + SGVec3f normal; sgReadDouble( fp, &area ); pFaces->face_areas.push_back( area ); - sgReadPoint3D( fp, normal ); - pFaces->face_normals.push_back( normal ); + sgReadVec3( fp, normal ); + pFaces->face_normals.push_back( Point3D::fromSGVec3( normal ) ); } } } diff --git a/src/BuildTiles/Main/tgconstruct_tesselate.cxx b/src/BuildTiles/Main/tgconstruct_tesselate.cxx index 676f0da5..99df3b46 100644 --- a/src/BuildTiles/Main/tgconstruct_tesselate.cxx +++ b/src/BuildTiles/Main/tgconstruct_tesselate.cxx @@ -46,14 +46,14 @@ void TGConstruct::TesselatePolys( void ) unsigned int id = polys_clipped.get_shape( area, shape ).id; if ( IsDebugShape( id ) ) { - WriteDebugShape( "preteselate", polys_clipped.get_shape(area, shape) ); + tgPolygon::ToShapefile( polys_clipped.get_shape( area, shape ).mask, ds_name, "preteselate", "" ); } for ( unsigned int segment = 0; segment < polys_clipped.shape_size(area, shape); segment++ ) { - TGPolygon poly = polys_clipped.get_poly(area, shape, segment); + tgPolygon poly = polys_clipped.get_poly(area, shape, segment); - poly.get_bounding_box(min, max); - nodes.get_geod_inside( min, max, poly_extra ); + tg::Rectangle rect = poly.GetBoundingBox(); + nodes.get_geod_inside( rect.getMin(), rect.getMax(), poly_extra ); SG_LOG( SG_CLIPPER, SG_INFO, "Tesselating " << get_area_name( (AreaType)area ) << "(" << area << "): " << shape+1 << "-" << segment << " of " << (int)polys_clipped.area_size(area) << @@ -63,18 +63,17 @@ void TGConstruct::TesselatePolys( void ) SG_LOG( SG_CLIPPER, SG_INFO, poly ); } - TGPolygon tri = polygon_tesselate_alt_with_extra_cgal( poly, poly_extra, false ); + poly.Tesselate( poly_extra ); // ensure all added nodes are accounted for - for (int k=0; k< tri.contours(); k++) { - for (int l = 0; l < tri.contour_size(k); l++) { + for (unsigned int k=0; k < poly.Triangles(); k++) { + for (int l = 0; l < 3; l++) { // ensure we have all nodes... - nodes.unique_add( tri.get_pt( k, l ).toSGGeod() ); + nodes.unique_add( poly.GetTriNode( k, l ) ); } } - // Save the triangulation - polys_clipped.set_tris( area, shape, segment, tri ); + polys_clipped.set_poly( area, shape, segment, poly ); } } } diff --git a/src/BuildTiles/Main/tgconstruct_texture.cxx b/src/BuildTiles/Main/tgconstruct_texture.cxx index 1f20fd59..19cb7842 100644 --- a/src/BuildTiles/Main/tgconstruct_texture.cxx +++ b/src/BuildTiles/Main/tgconstruct_texture.cxx @@ -166,21 +166,19 @@ void TGConstruct::CalcTextureCoordinates( void ) 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); + 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) ); - - TGPolygon tri = polys_clipped.get_tris( area, shape, segment ); - TGPolygon tc; + shape+1 << "-" << segment << " of " << polys_clipped.area_size(area) << " with " << poly.GetMaterial() ); if ( polys_clipped.get_textured( area, shape ) ) { SG_LOG(SG_GENERAL, SG_DEBUG, "USE TEXTURE PARAMS for tex coord calculations" ); - tc = linear_tex_coords( tri, polys_clipped.get_texparams(area, shape, segment) ); + poly.SetTexMethod( TG_TEX_BY_TPS_CLIPUV, -1, -1, 1, 1 ); } else { SG_LOG(SG_GENERAL, SG_DEBUG, "USE SIMGEAR for tex coord calculations" ); - tc = area_tex_coords( tri ); + poly.SetTexMethod( TG_TEX_BY_GEODE, bucket.get_center_lat() ); } - polys_clipped.set_texcoords( area, shape, segment, tc ); + poly.Texture( ); + polys_clipped.set_poly(area, shape, segment, poly); } } } diff --git a/src/BuildTiles/Main/tglandclass.hxx b/src/BuildTiles/Main/tglandclass.hxx index 01f9c118..a1f812ff 100644 --- a/src/BuildTiles/Main/tglandclass.hxx +++ b/src/BuildTiles/Main/tglandclass.hxx @@ -50,7 +50,7 @@ public: } inline unsigned int shape_size( unsigned int area, unsigned int shape ) { - return shapes[area][shape].sps.size(); + return shapes[area][shape].polys.size(); } inline void add_shape( unsigned int area, TGShape shape ) @@ -62,13 +62,13 @@ public: return shapes[area][shape]; } - inline TGPolygon get_mask( unsigned int area, unsigned int shape ) + inline tgPolygon get_mask( unsigned int area, unsigned int shape ) { - return shapes[area][shape].clip_mask; + return shapes[area][shape].mask; } - inline void set_mask( unsigned int area, unsigned int shape, TGPolygon mask ) + inline void set_mask( unsigned int area, unsigned int shape, tgPolygon mask ) { - shapes[area][shape].clip_mask = mask; + shapes[area][shape].mask = mask; } inline bool get_textured( unsigned int area, unsigned int shape ) @@ -80,24 +80,16 @@ public: shapes[area][shape].textured = t; } - inline TGSuperPoly& get_superpoly( unsigned int area, unsigned int shape, unsigned int segment ) + inline tgPolygon& get_poly( unsigned int area, unsigned int shape, unsigned int segment ) { - return shapes[area][shape].sps[segment]; + return shapes[area][shape].polys[segment]; } - inline void set_superpoly( unsigned int area, unsigned int shape, unsigned int segment, TGSuperPoly sp ) + inline void set_poly( unsigned int area, unsigned int shape, unsigned int segment, const tgPolygon& 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 ); + shapes[area][shape].polys[segment] = sp; } +#if 0 inline TGPolygon get_tris( unsigned int area, unsigned int shape, unsigned int segment ) { return shapes[area][shape].sps[segment].get_tris(); @@ -106,32 +98,35 @@ public: { shapes[area][shape].sps[segment].set_tris( tris ); } +#endif 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 ); + return Point3D::fromSGVec3( shapes[area][shape].polys[segment].GetTriFaceNormal( 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 ); + return shapes[area][shape].polys[segment].GetTriFaceArea( tri ); } +#if 0 inline std::string get_flag( unsigned int area, unsigned int shape, unsigned int segment ) { return shapes[area][shape].sps[segment].get_flag(); } +#endif inline std::string get_material( unsigned int area, unsigned int shape, unsigned int segment ) { - return shapes[area][shape].sps[segment].get_material(); + return shapes[area][shape].polys[segment].GetMaterial(); } - inline TGTexParams& get_texparams( unsigned int area, unsigned int shape, unsigned int segment ) + inline const tgTexParams& get_texparams( unsigned int area, unsigned int shape, unsigned int segment ) { - return shapes[area][shape].tps[segment]; + return shapes[area][shape].polys[segment].GetTexParams(); } - +/* inline TGPolygon get_texcoords( unsigned int area, unsigned int shape, unsigned int segment ) { return shapes[area][shape].sps[segment].get_texcoords(); @@ -140,7 +135,9 @@ public: { 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(); @@ -149,6 +146,8 @@ public: { return shapes[area][shape].sps[segment].set_tri_idxs( tis ); } +*/ + void SaveToGzFile( gzFile& fp ); void LoadFromGzFile( gzFile& fp ); diff --git a/src/BuildTiles/Main/tgshape.cxx b/src/BuildTiles/Main/tgshape.cxx index 540dadd9..54e1ec72 100644 --- a/src/BuildTiles/Main/tgshape.cxx +++ b/src/BuildTiles/Main/tgshape.cxx @@ -35,92 +35,69 @@ void TGShape::GetName( char* name ) const sprintf( name, "%s_%d", get_area_name( (AreaType)area ).c_str(), id ); } -void TGShape::SetMask( TGPolygon mask ) +void TGShape::SetMask( const tgPolygon& m ) { - clip_mask = mask; + mask = m; } void TGShape::BuildMask( void ) { - TGPolygon poly; - poly_list polys; - clip_mask.erase(); - - for (unsigned int i=0; i<sps.size(); i++) - { - polys.push_back( sps[i].get_poly() ); - } - - clip_mask = tgPolygonUnion( polys ); + mask = tgPolygon::Union( polys ); } void TGShape::IntersectPolys( void ) { - if ( sps.size() > 1 ) { - TGPolygon original, intersect; - - for (unsigned int i=0; i<sps.size(); i++) + if ( polys.size() > 1 ) { + for (unsigned int i=0; i<polys.size(); i++) { - original = sps[i].get_poly(); - - intersect = tgPolygonInt( clip_mask, original ); - - sps[i].set_poly( intersect ); + SG_LOG(SG_GENERAL, SG_INFO, " before is " << polys[i].GetMaterial() ); + polys[i] = tgPolygon::Intersect( polys[i], mask ); + SG_LOG(SG_GENERAL, SG_INFO, " after is " << polys[i].GetMaterial() ); } } else { - sps[0].set_poly( clip_mask ); + std::string material = polys[0].GetMaterial(); + tgTexParams tp = polys[0].GetTexParams(); + polys[0] = mask; + polys[0].SetMaterial( material ); + polys[0].SetTexParams( tp ); } } void TGShape::LoadFromGzFile(gzFile& fp) { int i, count; + // First, load the clipmask - clip_mask.LoadFromGzFile( fp ); + SG_LOG(SG_GENERAL, SG_INFO, " load mask" ); + mask.LoadFromGzFile( fp ); + SG_LOG(SG_GENERAL, SG_INFO, " done" ); - // Then load superpolys + // Then load individual polys sgReadInt( fp, &count ); for (i=0; i<count; i++) { - TGSuperPoly sp; - sp.LoadFromGzFile( fp ); - sps.push_back( sp ); - } - - // Then load texparams - sgReadInt( fp, &count ); - for (i=0; i<count; i++) { - TGTexParams tp; - tp.LoadFromGzFile( fp ); - tps.push_back( tp ); + tgPolygon poly; + poly.LoadFromGzFile( fp ); + polys.push_back( poly ); } // Load the id, area type and textured flag sgReadUInt( fp, &id ); - sgReadInt( fp, (int*)&area ); - sgReadInt( fp, (int*)&textured ); + sgReadInt( fp, (int*)&area ); + sgReadInt( fp, (int*)&textured ); } std::ostream& operator<< ( std::ostream& out, const TGShape& p ) { int i, count; -// TGSuperPoly sp; -// TGTexParams tp; // First, save the clipmask - out << p.clip_mask; + out << p.mask; // Then save superpolys - count = p.sps.size(); + count = p.polys.size(); out << count << "\n"; for (i=0; i<count; i++) { - out << p.sps[i]; - } - - // Then save texparams - count = p.tps.size(); - out << count << "\n"; - for (i=0; i<count; i++) { - out << p.tps[i]; + out << p.polys[i]; } // Save the id, area type and textured flag @@ -135,21 +112,14 @@ void TGShape::SaveToGzFile(gzFile& fp) { int i, count; - // First, load the clipmask - clip_mask.SaveToGzFile( fp ); + // First, save the clipmask + mask.SaveToGzFile( fp ); // Then save superpolys - count = sps.size(); + count = polys.size(); sgWriteInt( fp, count ); for (i=0; i<count; i++) { - sps[i].SaveToGzFile( fp ); - } - - // Then save texparams - count = tps.size(); - sgWriteInt( fp, count ); - for (i=0; i<count; i++) { - tps[i].SaveToGzFile( fp ); + polys[i].SaveToGzFile( fp ); } // Save the id, area type and textured flag diff --git a/src/BuildTiles/Main/tgshape.hxx b/src/BuildTiles/Main/tgshape.hxx index 17e6f0cc..dc15e9b3 100644 --- a/src/BuildTiles/Main/tgshape.hxx +++ b/src/BuildTiles/Main/tgshape.hxx @@ -45,15 +45,14 @@ class TGShape { public: - TGPolygon clip_mask; + tgpolygon_list polys; + tgPolygon mask; bool textured; - superpoly_list sps; - texparams_list tps; AreaType area; unsigned int id; void GetName( char* name ) const; - void SetMask( TGPolygon mask ); + void SetMask( const tgPolygon& mask ); void BuildMask( void ); void IntersectPolys( void ); void SaveToGzFile( gzFile& fp ); diff --git a/src/Lib/Polygon/polygon.cxx b/src/Lib/Polygon/polygon.cxx index 2190fc7b..31d8ec0f 100644 --- a/src/Lib/Polygon/polygon.cxx +++ b/src/Lib/Polygon/polygon.cxx @@ -23,14 +23,15 @@ #include <fstream> #include <limits.h> +#include <simgear/constants.h> #include <simgear/threads/SGThread.hxx> #include <simgear/threads/SGGuard.hxx> -#include <simgear/constants.h> +#include <simgear/math/sg_geodesy.hxx> +#include <simgear/misc/texcoord.hxx> +#include <simgear/structure/exception.hxx> #include <simgear/debug/logstream.hxx> #include <Geometry/point3d.hxx> #include <Geometry/poly_support.hxx> -#include <simgear/math/sg_geodesy.hxx> -#include <simgear/structure/exception.hxx> #include <Geometry/trinodes.hxx> @@ -1962,6 +1963,36 @@ bool tgContour::FindColinearLine( const tgContour& subject, const SGGeod& node, return false; } +void tgContour::SaveToGzFile( gzFile& fp ) +{ + // Save the nodelist + sgWriteUInt( fp, node_list.size() ); + for (unsigned int i = 0; i < node_list.size(); i++) { + sgWriteGeod( fp, node_list[i] ); + } + + // and the hole flag + sgWriteInt( fp, (int)hole ); +} + +void tgContour::LoadFromGzFile( gzFile& fp ) +{ + unsigned int count; + SGGeod node; + + // Start Clean + Erase(); + + // Load the nodelist + sgReadUInt( fp, &count ); + for (unsigned int i = 0; i < count; i++) { + sgReadGeod( fp, node ); + node_list.push_back( node ); + } + + sgReadInt( fp, (int *)&hole ); +} + std::ostream& operator<< ( std::ostream& output, const tgContour& subject ) { // Save the data @@ -2429,10 +2460,11 @@ void tgPolygon::RemoveSlivers( tgPolygon& subject, tgcontour_list& slivers ) #endif } -void tgPolygon::MergeSlivers( tgpolygon_list& polys, tgcontour_list& sliver_list ) { +tgcontour_list tgPolygon::MergeSlivers( tgpolygon_list& polys, tgcontour_list& sliver_list ) { tgPolygon poly, result; tgContour sliver; tgContour contour; + tgcontour_list unmerged; unsigned int original_contours, result_contours; bool done; @@ -2462,8 +2494,11 @@ void tgPolygon::MergeSlivers( tgpolygon_list& polys, tgcontour_list& sliver_list if ( !done ) { SG_LOG(SG_GENERAL, SG_DEBUG, "couldn't merge sliver " << i ); + unmerged.push_back( sliver ); } } + + return unmerged; } tgPolygon tgPolygon::AddColinearNodes( const tgPolygon& subject, TGTriNodes& nodes ) @@ -2561,12 +2596,31 @@ void tgPolygon::Texture( void ) switch( tp.method ) { case TG_TEX_BY_GEODE: - break; + { + // The Simgear General texture coordinate routine takes a fan. + // Simgear could probably use a new function that just takes a Geod vector + // For now, just create an identity fan... + std::vector< int > node_idxs; + for (int i = 0; i < 3; i++) { + node_idxs.push_back(i); + } + + for ( unsigned int i = 0; i < triangles.size(); i++ ) { + std::vector< SGVec2f > tc_list; + std::vector< SGGeod > nodes; + + nodes = triangles[i].GetNodeList(); + tc_list = sgCalcTexCoords( tp.center_lat, nodes, node_idxs ); + triangles[i].SetTexCoordList( tc_list ); + } + } + break; case TG_TEX_BY_TPS_NOCLIP: case TG_TEX_BY_TPS_CLIPU: case TG_TEX_BY_TPS_CLIPV: case TG_TEX_BY_TPS_CLIPUV: + { for ( unsigned int i = 0; i < triangles.size(); i++ ) { for ( unsigned int j = 0; j < 3; j++ ) { p = triangles[i].GetNode( j ); @@ -2631,8 +2685,8 @@ void tgPolygon::Texture( void ) triangles[i].SetTexCoord( j, t ); } } - - break; + } + break; } } @@ -2691,6 +2745,82 @@ void tgPolygon::ToShapefile( const tgPolygon& subject, const std::string& dataso ds_id = tgShapefileCloseDatasource( ds_id ); } + tgcontour_list contours; + tgtriangle_list triangles; + + std::string material; + std::string flag; // let's get rid of this.... + tgTexParams tp; + + +void tgPolygon::SaveToGzFile( gzFile& fp ) +{ + // Save the contours + sgWriteUInt( fp, contours.size() ); + for (unsigned int i = 0; i < contours.size(); i++) { + contours[i].SaveToGzFile( fp ); + } + + // Save the triangles + sgWriteUInt( fp, triangles.size() ); + for (unsigned int i = 0; i < triangles.size(); i++) { + triangles[i].SaveToGzFile( fp ); + } + + // Save the tex params + tp.SaveToGzFile( fp ); + + // and the rest + sgWriteString( fp, material.c_str() ); + sgWriteString( fp, flag.c_str() ); +} + +void tgPolygon::LoadFromGzFile( gzFile& fp ) +{ + unsigned int count; + tgContour contour; + tgTriangle triangle; + char *strbuff; + + // Start clean + Erase(); + + // Load the contours + sgReadUInt( fp, &count ); + for (unsigned int i = 0; i < count; i++) { + contour.LoadFromGzFile( fp ); + AddContour(contour); + } + + // load the triangles + sgReadUInt( fp, &count ); + SG_LOG(SG_GENERAL, SG_INFO, " load " << count << " triangles" ); + + for (unsigned int i = 0; i < count; i++) { + triangle.LoadFromGzFile( fp ); + AddTriangle(triangle); + } + + SG_LOG(SG_GENERAL, SG_INFO, " load texparams" ); + + // Load the tex params + tp.LoadFromGzFile( fp ); + + // and the rest + SG_LOG(SG_GENERAL, SG_INFO, " load material" ); + + sgReadString( fp, &strbuff ); + if ( strbuff ) { + material = strbuff; + delete strbuff; + } + + sgReadString( fp, &strbuff ); + if ( strbuff ) { + flag = strbuff; + delete strbuff; + } +} ////////////////////////////// CHOP //////////////////////////////// #include <simgear/bucket/newbucket.hxx> @@ -3058,7 +3188,7 @@ void tg_insert_polygon(CDT& cdt,const Polygon_2& polygon) } } -void tgPolygon::Tesselate( std::vector<SGGeod> extra ) +void tgPolygon::Tesselate( const std::vector<SGGeod>& extra ) { CDT cdt; @@ -3355,3 +3485,87 @@ void tgAccumulator::Add( const tgPolygon& subject ) ClipperLib::Polygons clipper_subject = tgPolygon::ToClipper( subject ); accum.push_back( clipper_subject ); } + + std::vector<SGGeod> node_list; + std::vector<SGVec2f> tc_list; + std::vector<SGVec3d> norm_list; + std::vector<int> idx_list; + + SGVec3f face_normal; + double face_area; + + +void tgTriangle::SaveToGzFile( gzFile& fp ) +{ + // Save the three nodes, and their attributes + for (unsigned int i = 0; i < 3; i++) { + sgWriteGeod( fp, node_list[i] ); + sgWriteVec2( fp, tc_list[i] ); + sgWritedVec3( fp, norm_list[i] ); + sgWriteInt( fp, idx_list[i] ); + } + + // and the area, and face normal + sgWriteVec3( fp, face_normal ); + sgWriteDouble( fp, face_area ); +} + +void tgTriangle::LoadFromGzFile( gzFile& fp ) +{ + // Load the nodelist + for (unsigned int i = 0; i < 3; i++) { + sgReadGeod( fp, node_list[i] ); + sgReadVec2( fp, tc_list[i] ); + sgReaddVec3( fp, norm_list[i] ); + sgReadInt( fp, &idx_list[i] ); + } + + // and the area, and face normal + sgReadVec3( fp, face_normal ); + sgReadDouble( fp, &face_area ); +} + +void tgTexParams::SaveToGzFile( gzFile& fp ) +{ + // Save the parameters + sgWriteGeod( fp, ref ); + + sgWriteDouble( fp, width ); + sgWriteDouble( fp, length ); + sgWriteDouble( fp, heading ); + + sgWriteDouble( fp, minu ); + sgWriteDouble( fp, maxu ); + sgWriteDouble( fp, minv ); + sgWriteDouble( fp, maxv ); + + sgWriteDouble( fp, min_clipu ); + sgWriteDouble( fp, max_clipu ); + sgWriteDouble( fp, min_clipv ); + sgWriteDouble( fp, max_clipv ); + + sgWriteInt( fp, (int)method ); +} + +void tgTexParams::LoadFromGzFile( gzFile& fp ) +{ + // Load the parameters + sgReadGeod( fp, ref ); + + sgReadDouble( fp, &width ); + sgReadDouble( fp, &length ); + sgReadDouble( fp, &heading ); + + sgReadDouble( fp, &minu ); + sgReadDouble( fp, &maxu ); + sgReadDouble( fp, &minv ); + sgReadDouble( fp, &maxv ); + + sgReadDouble( fp, &min_clipu ); + sgReadDouble( fp, &max_clipu ); + sgReadDouble( fp, &min_clipv ); + sgReadDouble( fp, &max_clipv ); + + sgReadInt( fp, (int*)&method ); +} + diff --git a/src/Lib/Polygon/polygon.hxx b/src/Lib/Polygon/polygon.hxx index b127ad6c..3d13eb1f 100644 --- a/src/Lib/Polygon/polygon.hxx +++ b/src/Lib/Polygon/polygon.hxx @@ -386,6 +386,11 @@ public: static tgContour Expand( const tgContour& subject, double offset ); + static void ToShapefile( const tgContour& subject, const std::string& datasource, const std::string& layer, const std::string& feature ); + + void SaveToGzFile( gzFile& fp ); + void LoadFromGzFile( gzFile& fp ); + // Friend for output friend std::ostream& operator<< ( std::ostream&, const tgContour& ); @@ -401,6 +406,13 @@ typedef tgcontour_list::const_iterator const_tgcontour_list_iterator; class tgTriangle { public: + tgTriangle() { + node_list.resize( 3, SGGeod::fromDegM(0.0, 0.0, 0.0) ); + tc_list.resize( 3, SGVec2f(0.0, 0.0) ); + norm_list.resize( 3, SGVec3d(0.0, 0.0, 0.0) ); + idx_list.resize( 3, -1 ); + } + tgTriangle( const SGGeod& p0, const SGGeod& p1, const SGGeod& p2 ) { node_list.push_back( p0 ); node_list.push_back( p1 ); @@ -414,12 +426,42 @@ public: SGGeod GetNode( unsigned int i ) const { return node_list[i]; } + std::vector<SGGeod>& GetNodeList( void ) { + return node_list; + } + SGVec2f GetTexCoord( unsigned int i ) const { return tc_list[i]; } void SetTexCoord( unsigned int i, const SGVec2f tc ) { tc_list[i] = tc; } + void SetTexCoordList( const std::vector<SGVec2f>& tcs ) { + tc_list = tcs; + } + int GetIndex( unsigned int i ) const { + return idx_list[i]; + } + void SetIndex( unsigned int i, int idx ) { + idx_list[i] = idx; + } + + void SetFaceNormal( const SGVec3f& n ) { + face_normal = n; + }; + SGVec3f GetFaceNormal( void ) const { + return face_normal; + } + + void SetFaceArea( double a ) { + face_area = a; + } + double GetFaceArea( void ) const { + return face_area; + } + + void SaveToGzFile( gzFile& fp ); + void LoadFromGzFile( gzFile& fp ); // Friend for output friend std::ostream& operator<< ( std::ostream&, const tgTriangle& ); @@ -430,7 +472,7 @@ private: std::vector<SGVec3d> norm_list; std::vector<int> idx_list; - SGVec3d face_normal; + SGVec3f face_normal; double face_area; }; @@ -466,6 +508,11 @@ public: tgTexMethod method; + double center_lat; + + void SaveToGzFile( gzFile& fp ); + void LoadFromGzFile( gzFile& fp ); + // Friend for output friend std::ostream& operator<< ( std::ostream&, const tgTexParams& ); }; @@ -531,6 +578,9 @@ public: unsigned int Triangles( void ) const { return triangles.size(); } + void AddTriangle( const tgTriangle& triangle ) { + triangles.push_back( triangle ); + } void AddTriangle( const SGGeod& p1, const SGGeod p2, const SGGeod p3 ) { triangles.push_back( tgTriangle( p1, p2, p3 ) ); } @@ -541,6 +591,24 @@ public: SGVec2f GetTriTexCoord( unsigned int c, unsigned int i ) const { return triangles[c].GetTexCoord( i ); } + void SetTriIdx( unsigned int c, unsigned int i, int idx ) { + triangles[c].SetIndex( i, idx ); + } + int GetTriIdx( unsigned int c, unsigned int i ) const { + return triangles[c].GetIndex( i ); + } + void SetTriFaceNormal( unsigned int c, const SGVec3f& n ) { + triangles[c].SetFaceNormal( n ); + } + SGVec3f GetTriFaceNormal( unsigned int c ) const { + return triangles[c].GetFaceNormal(); + } + void SetTriFaceArea( unsigned int c, double a ) { + triangles[c].SetFaceArea( a ); + } + double GetTriFaceArea( unsigned int c ) const { + return triangles[c].GetFaceArea(); + } std::string GetMaterial( void ) const { return material; @@ -560,7 +628,7 @@ public: const tgTexParams& GetTexParams( void ) const { return tp; } - + void SetTexLimits( double minu, double minv, double maxu, double maxv ) { tp.minu = minu; tp.minv = minv; @@ -577,9 +645,14 @@ public: tp.max_clipu = max_cu; tp.max_clipv = max_cv; } + void SetTexMethod( tgTexMethod m, double cl ) { + tp.method = m; + tp.center_lat = cl; + } + void Tesselate( void ); - void Tesselate( std::vector<SGGeod> extra ); + void Tesselate( const std::vector<SGGeod>& extra ); void Texture( void ); @@ -623,7 +696,7 @@ public: static bool FindColinearLine( const tgPolygon& subject, SGGeod& node, SGGeod& start, SGGeod& end ); static void RemoveSlivers( tgPolygon& subject, tgcontour_list& slivers ); - static void MergeSlivers( tgpolygon_list& subjects, tgcontour_list& slivers ); + static tgcontour_list MergeSlivers( tgpolygon_list& subjects, tgcontour_list& slivers ); void SaveToGzFile( gzFile& fp ); void LoadFromGzFile( gzFile& fp );