refactor from TGPolygon and TGSuperPoly to tgPolygon
fix for missing texture coordinates. Need to kill, or shrink TGShape / clip ,asks, etc.
This commit is contained in:
parent
c0555a1270
commit
89e69a863f
18 changed files with 624 additions and 466 deletions
|
@ -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 );
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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", "" );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
|
Loading…
Add table
Reference in a new issue