1
0
Fork 0

multistage coming along - need TGNodes derialization

This commit is contained in:
Peter Sadrozinski 2012-09-07 21:16:23 -04:00 committed by Christian Schmitt
parent f52e3fef75
commit 779db9566b
11 changed files with 991 additions and 457 deletions

View file

@ -27,6 +27,7 @@
#include <iostream>
#include <sstream>
#include <fstream>
#include <boost/foreach.hpp>
@ -2116,6 +2117,98 @@ void TGConstruct::CalcTextureCoordinates( void )
}
}
void TGConstruct::SaveToIntermediateFiles( int stage )
{
string dir;
string file;
switch( stage ) {
case 1: // Save the clipped polys and node list
{
dir = share_base + "/stage1/" + bucket.gen_base_path();
file = dir + "/" + bucket.gen_index_str() + "_clipped_polys";
SGPath sgp( dir );
sgp.append( "dummy" );
sgp.create_dir( 0755 );
std::ofstream ofs_cp( file.c_str() );
ofs_cp << polys_clipped;
ofs_cp.close();
file = dir + "/" + bucket.gen_index_str() + "_nodes";
std::ofstream ofs_n( file.c_str() );
ofs_n << nodes;
ofs_n.close();
break;
}
case 2: // Save the clipped polys and node list
{
dir = share_base + "/stage2/" + bucket.gen_base_path();
file = dir + "/" + bucket.gen_index_str() + "_clipped_polys";
SGPath sgp( dir );
sgp.append( "dummy" );
sgp.create_dir( 0755 );
std::ofstream ofs_cp( file.c_str() );
ofs_cp << polys_clipped;
ofs_cp.close();
file = dir + "/" + bucket.gen_index_str() + "_nodes";
std::ofstream ofs_n( file.c_str() );
ofs_n << nodes;
ofs_n.close();
break;
}
}
}
void TGConstruct::LoadFromIntermediateFiles( int stage )
{
string dir;
string file;
switch( stage ) {
case 1: // Load the clipped polys and node list
{
dir = share_base + "/stage1/" + bucket.gen_base_path();
file = dir + "/" + bucket.gen_index_str() + "_clipped_polys";
std::ifstream ifs_cp( file.c_str() );
ifs_cp >> polys_clipped;
ifs_cp.close();
file = dir + "/" + bucket.gen_index_str() + "_nodes";
std::ifstream ifs_n( file.c_str() );
ifs_n >> nodes;
ifs_n.close();
break;
}
case 2: // Load the clipped polys and node list
{
dir = share_base + "/stage2/" + bucket.gen_base_path();
file = dir + "/" + bucket.gen_index_str() + "_clipped_polys";
std::ifstream ifs_cp( file.c_str() );
ifs_cp >> polys_clipped;
ifs_cp.close();
file = dir + "/" + bucket.gen_index_str() + "_nodes";
std::ifstream ifs_n( file.c_str() );
ifs_n >> nodes;
ifs_n.close();
break;
}
}
}
// master construction routine
// TODO : Split each step into its own function, and move
// into seperate files by major functionality
@ -2137,7 +2230,7 @@ void TGConstruct::ConstructBucketStage1() {
// STEP 1)
// Load grid of elevation data (Array)
LoadElevationArray();
// STEP 2)
// Clip 2D polygons against one another
if ( LoadLandclassPolys() == 0 ) {
@ -2160,54 +2253,81 @@ void TGConstruct::ConstructBucketStage1() {
// Clean the polys - after this, we shouldn't change their shape (other than slightly for
// fix T-Junctions - as This is the end of the first pass for multicore design
CleanClippedPolys();
}
// END OF FIRST PASS : SAVE THE TILE DATA
void TGConstruct::ConstructBucketStage2() {
// STEP 5)
// Merge in Shared data (just add the nodes to the nodelist)
// When this step is complete, some nodes will have normals (from shared tiles)
// and some will not
// Load Shared Edge Data X,Y coords only
SG_LOG(SG_GENERAL, SG_ALERT, "\nConstructing tile ID " << bucket.gen_index_str() << " in " << bucket.gen_base_path() );
/* If we have some debug IDs, create a datasource */
if ( debug_shapes.size() || debug_all ) {
sprintf(ds_name, "%s/constructdbg_%s", debug_path.c_str(), bucket.gen_index_str().c_str() );
SG_LOG(SG_GENERAL, SG_ALERT, "Debug_string: " << ds_name );
} else {
strcpy( ds_name, "" );
}
// TEMP TEMP TEMP - save in intermediate file...)
// Load grid of elevation data (Array)
LoadElevationArray();
// restore construct from stage1 intermediate files
LoadFromIntermediateFiles( 1 );
// STEP 6)
// Merge in Shared data - should just be x,y nodes on the borders from stage1
LoadSharedEdgeData();
// STEP 6)
// STEP 7)
// Fix T-Junctions by finding nodes that lie close to polygon edges, and
// inserting them into the edge
FixTJunctions();
// TODO : Needs to be part of clipping
// just before union : If we need to clean again after fixing tjunctions, make
// sure we don't alter the shape
// CleanClippedPolys();
// STEP 7)
// STEP 8)
// Generate triangles - we can't generate the node-face lookup table
// until all polys are tesselated, as extra nodes can still be generated
TesselatePolys();
// STEP 8)
// STEP 9)
// Generate triangle vertex coordinates to node index lists
// NOTE: After this point, no new nodes can be added
LookupNodesPerVertex();
// STEP 9)
// STEP 10)
// Interpolate elevations, and flatten stuff
CalcElevations();
}
// STEP 10)
// Generate face_connected list - shared data contains faces, too - save them somehow
LookupFacesPerNode();
void TGConstruct::ConstructBucketStage3() {
// END OF SECOND PASS : SAVE THE TILE DATA
SG_LOG(SG_GENERAL, SG_ALERT, "\nConstructing tile ID " << bucket.gen_index_str() << " in " << bucket.gen_base_path() );
// load shared edge data (with elevations, and face connected list)
// LoadSharedEdgeDataWithElevation();
/* If we have some debug IDs, create a datasource */
if ( debug_shapes.size() || debug_all ) {
sprintf(ds_name, "%s/constructdbg_%s", debug_path.c_str(), bucket.gen_index_str().c_str() );
SG_LOG(SG_GENERAL, SG_ALERT, "Debug_string: " << ds_name );
} else {
strcpy( ds_name, "" );
}
// TEMP TEMP TEMP )
// Load grid of elevation data (Array)
LoadElevationArray();
// STEP 11)
// Merge in Shared data - nodes on the shared edge should have x,y,z - we'll average the z
// shared edge data nodes also have 1 or 2 connected nodes so we can see their connected faces
//LoadSharedEdgeData();
// STEP 12)
// Generate face_connected list
LookupFacesPerNode();
// STEP 12)
// Calculate Face Normals
CalcFaceNormals();
// STEP 12)
// STEP 13)
// Calculate Point Normals
CalcPointNormals();
@ -2220,19 +2340,19 @@ void TGConstruct::ConstructBucketStage1() {
}
#endif
// STEP 13)
// STEP 14)
// Calculate Texture Coordinates
CalcTextureCoordinates();
// STEP 14)
// STEP 15) // only if not stages...
// Write out the shared edge data
SaveSharedEdgeData();
// STEP 15)
// STEP 16)
// Generate the btg file
WriteBtgFile();
// STEP 16)
// STEP 17)
// Write Custom objects to .stg file
AddCustomObjects();
}

View file

@ -35,6 +35,7 @@
#include <string>
#include <vector>
#include <iomanip>
#include <simgear/compiler.h>
#include <simgear/bucket/newbucket.hxx>
@ -54,6 +55,9 @@
#define FIND_SLIVERS (1)
#define USE_ACCUMULATOR (1)
class TGShape
{
public:
@ -64,17 +68,17 @@ public:
AreaType area;
unsigned int id;
void GetName( char* name ) const
void GetName( char* name ) const
{
sprintf( name, "%s_%d", get_area_name( (AreaType)area ).c_str(), id );
}
void SetMask( TGPolygon mask )
void SetMask( TGPolygon mask )
{
clip_mask = mask;
}
void BuildMask( void )
void BuildMask( void )
{
TGPolygon poly;
clip_mask.erase();
@ -86,7 +90,7 @@ public:
}
}
void IntersectPolys( void )
void IntersectPolys( void )
{
if ( sps.size() > 1 ) {
TGPolygon original, intersect;
@ -103,12 +107,90 @@ public:
sps[0].set_poly( clip_mask );
}
}
// Friends for serialization
friend std::istream& operator>> ( std::istream&, TGShape& );
friend std::ostream& operator<< ( std::ostream&, const TGShape& );
};
// input from stream
inline std::istream& operator >> ( std::istream& in, TGShape& p)
{
int i, count;
TGSuperPoly sp;
TGTexParams tp;
// First, load the clipmask
SG_LOG(SG_GENERAL, SG_ALERT, "\tshape: clipmask" );
in >> p.clip_mask;
// Then load superpolys
in >> count;
SG_LOG(SG_GENERAL, SG_ALERT, "\tshape: superpoly count " << count );
for (i=0; i<count; i++) {
SG_LOG(SG_GENERAL, SG_ALERT, "\tshape: load superpoly " << i );
in >> sp;
p.sps.push_back( sp );
}
// Then load texparams
in >> count;
SG_LOG(SG_GENERAL, SG_ALERT, "\tshape: texparams count " << count );
for (i=0; i<count; i++) {
SG_LOG(SG_GENERAL, SG_ALERT, "\tshape: load texparam " << i );
in >> tp;
p.tps.push_back( tp );
}
// Load the id, area type and textured flag
in >> p.id;
in >> p.area;
in >> p.textured;
return in;
}
inline std::ostream& operator<< ( std::ostream& out, const TGShape& p )
{
int i, count;
TGSuperPoly sp;
TGTexParams tp;
// First, save the clipmask
out << p.clip_mask;
// Then save superpolys
count = p.sps.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];
}
// Save the id, area type and textured flag
out << p.id << " ";
out << p.area << " ";
out << p.textured << "\n";
return out;
}
typedef std::vector < TGShape > shape_list;
typedef shape_list::iterator shape_list_iterator;
typedef shape_list::const_iterator const_shape_list_iterator;
class TGLandclass
{
public:
@ -228,10 +310,63 @@ public:
return shapes[area][shape].sps[segment].set_tri_idxs( tis );
}
// Friends for serialization
friend std::istream& operator>> ( std::istream&, TGLandclass& );
friend std::ostream& operator<< ( std::ostream&, const TGLandclass& );
private:
shape_list shapes[TG_MAX_AREA_TYPES];
};
// input from stream
inline std::istream& operator >> ( std::istream& in, TGLandclass& lc)
{
int i, j, count;
// Load all landclass shapes
for (i=0; i<TG_MAX_AREA_TYPES; i++) {
in >> count;
SG_LOG(SG_GENERAL, SG_ALERT, "Loading Landclass: area " << i << " size is " << count );
for (j=0; j<count; j++) {
SG_LOG(SG_GENERAL, SG_ALERT, "Loading Landclass: load shape " << j << " of " << count );
TGShape shape;
in >> shape;
lc.shapes[i].push_back( shape );
}
}
return in;
}
inline std::ostream& operator<< ( std::ostream& out, const TGLandclass& lc )
{
int i, j, count;
TGShape shape;
// first, set the precision
out << std::setprecision(12);
out << std::fixed;
// Save all landclass shapes
for (i=0; i<TG_MAX_AREA_TYPES; i++) {
count = lc.shapes[i].size();
out << count << "\n";
for (j=0; j<count; j++) {
out << lc.shapes[i][j] << " ";
}
out << "\n";
}
return out;
}
// forward declaration
class TGMatch;
@ -315,7 +450,7 @@ private:
// Shared edge Matching
void LoadSharedEdgeData( void );
void SaveSharedEdgeData( void );
void SaveSharedEdgeData( void );
// Polygon Cleaning
void CleanClippedPolys( void );
@ -361,10 +496,15 @@ public:
~TGConstruct();
void set_bucket( SGBucket b ) { bucket = b; }
// New shared edge matching
void SaveToIntermediateFiles( int stage );
void LoadFromIntermediateFiles( int stage );
// Three stage construct
void ConstructBucketStage1();
void ConstructBucketStage2();
void ConstructBucketStage3();
void calc_gc_course_dist( const Point3D& start, const Point3D& dest,
double *course, double *dist );

View file

@ -273,32 +273,33 @@ int main(int argc, char **argv) {
exit(-1);
}
// main construction data management class
TGConstruct* c;
// main construction data management class : Stage 1
if (tile_id == -1) {
if (xdist == -1 || ydist == -1) {
// construct the tile around the specified location
SG_LOG(SG_GENERAL, SG_ALERT, "Building single tile at " << lat << ',' << lon);
SGBucket b( lon, lat );
TGConstruct* all_stages;
c = new TGConstruct();
c->set_cover( cover );
c->set_work_base( work_dir );
c->set_output_base( output_dir );
c->set_share_base( share_dir );
c->set_load_dirs( load_dirs );
c->set_useUKGrid( useUKgrid );
c->set_write_shared_edges( writeSharedEdges );
c->set_use_own_shared_edges( useOwnSharedEdges );
c->set_ignore_landmass( ignoreLandmass );
c->set_nudge( nudge );
c->set_bucket( b );
all_stages = new TGConstruct();
all_stages->set_cover( cover );
all_stages->set_work_base( work_dir );
all_stages->set_output_base( output_dir );
all_stages->set_share_base( share_dir );
all_stages->set_load_dirs( load_dirs );
all_stages->set_useUKGrid( useUKgrid );
all_stages->set_write_shared_edges( writeSharedEdges );
all_stages->set_use_own_shared_edges( useOwnSharedEdges );
all_stages->set_ignore_landmass( ignoreLandmass );
all_stages->set_nudge( nudge );
all_stages->set_bucket( b );
all_stages->set_debug( debug_dir, debug_area_defs, debug_shape_defs );
c->set_debug( debug_dir, debug_area_defs, debug_shape_defs );
all_stages->ConstructBucketStage1();
all_stages->ConstructBucketStage2();
all_stages->ConstructBucketStage3();
c->ConstructBucketStage1();
delete c;
delete all_stages;
} else {
// build all the tiles in an area
SG_LOG(SG_GENERAL, SG_ALERT, "Building tile(s) at " << lat << ',' << lon << " with x distance " << xdist << " and y distance " << ydist);
@ -311,23 +312,27 @@ int main(int argc, char **argv) {
bool do_tile = true;
if ( b_min == b_max ) {
c = new TGConstruct();
c->set_cover( cover );
c->set_work_base( work_dir );
c->set_output_base( output_dir );
c->set_share_base( share_dir );
c->set_load_dirs( load_dirs );
c->set_useUKGrid( useUKgrid );
c->set_write_shared_edges( writeSharedEdges );
c->set_use_own_shared_edges( useOwnSharedEdges );
c->set_ignore_landmass( ignoreLandmass );
c->set_nudge( nudge );
c->set_bucket( b_min );
TGConstruct* all_stages;
c->set_debug( debug_dir, debug_area_defs, debug_shape_defs );
all_stages = new TGConstruct();
all_stages->set_cover( cover );
all_stages->set_work_base( work_dir );
all_stages->set_output_base( output_dir );
all_stages->set_share_base( share_dir );
all_stages->set_load_dirs( load_dirs );
all_stages->set_useUKGrid( useUKgrid );
all_stages->set_write_shared_edges( writeSharedEdges );
all_stages->set_use_own_shared_edges( useOwnSharedEdges );
all_stages->set_ignore_landmass( ignoreLandmass );
all_stages->set_nudge( nudge );
all_stages->set_bucket( b_min );
all_stages->set_debug( debug_dir, debug_area_defs, debug_shape_defs );
c->ConstructBucketStage1();
delete c;
all_stages->ConstructBucketStage1();
all_stages->ConstructBucketStage2();
all_stages->ConstructBucketStage3();
delete all_stages;
} else {
SGBucket b_cur;
int dx, dy, i, j;
@ -336,6 +341,8 @@ int main(int argc, char **argv) {
SG_LOG(SG_GENERAL, SG_ALERT, " construction area spans tile boundaries");
SG_LOG(SG_GENERAL, SG_ALERT, " dx = " << dx << " dy = " << dy);
// construct stage 1
for ( j = 0; j <= dy; j++ ) {
for ( i = 0; i <= dx; i++ ) {
b_cur = sgBucketOffset(min_x, min_y, i, j);
@ -345,23 +352,99 @@ int main(int argc, char **argv) {
}
if ( do_tile ) {
c = new TGConstruct();
c->set_cover( cover );
c->set_work_base( work_dir );
c->set_output_base( output_dir );
c->set_share_base( share_dir );
c->set_load_dirs( load_dirs );
c->set_useUKGrid( useUKgrid );
c->set_write_shared_edges( writeSharedEdges );
c->set_use_own_shared_edges( useOwnSharedEdges );
c->set_ignore_landmass( ignoreLandmass );
c->set_nudge( nudge );
c->set_bucket( b_cur );
TGConstruct* stage1;
stage1 = new TGConstruct();
stage1->set_cover( cover );
stage1->set_work_base( work_dir );
stage1->set_output_base( output_dir );
stage1->set_share_base( share_dir );
stage1->set_load_dirs( load_dirs );
stage1->set_useUKGrid( useUKgrid );
stage1->set_write_shared_edges( writeSharedEdges );
stage1->set_use_own_shared_edges( useOwnSharedEdges );
stage1->set_ignore_landmass( ignoreLandmass );
stage1->set_nudge( nudge );
stage1->set_bucket( b_cur );
stage1->set_debug( debug_dir, debug_defs );
c->set_debug( debug_dir, debug_area_defs, debug_shape_defs );
stage1->ConstructBucketStage1();
stage1->SaveToIntermediateFiles(1);
delete stage1;
} else {
SG_LOG(SG_GENERAL, SG_ALERT, "skipping " << b_cur);
}
}
}
c->ConstructBucketStage1();
delete c;
// construct stage 2
for ( j = 0; j <= dy; j++ ) {
for ( i = 0; i <= dx; i++ ) {
b_cur = sgBucketOffset(min_x, min_y, i, j);
if ( b_cur == b_start ) {
do_tile = true;
}
if ( do_tile ) {
TGConstruct* stage2;
stage2 = new TGConstruct();
stage2->set_cover( cover );
stage2->set_work_base( work_dir );
stage2->set_output_base( output_dir );
stage2->set_share_base( share_dir );
stage2->set_load_dirs( load_dirs );
stage2->set_useUKGrid( useUKgrid );
stage2->set_write_shared_edges( writeSharedEdges );
stage2->set_use_own_shared_edges( useOwnSharedEdges );
stage2->set_ignore_landmass( ignoreLandmass );
stage2->set_nudge( nudge );
stage2->set_bucket( b_cur );
stage2->set_debug( debug_dir, debug_area_defs, debug_shape_defs );
stage2->LoadFromIntermediateFiles(1);
stage2->ConstructBucketStage2();
stage2->SaveToIntermediateFiles(2);
delete stage2;
} else {
SG_LOG(SG_GENERAL, SG_ALERT, "skipping " << b_cur);
}
}
}
// construct stage 3
for ( j = 0; j <= dy; j++ ) {
for ( i = 0; i <= dx; i++ ) {
b_cur = sgBucketOffset(min_x, min_y, i, j);
if ( b_cur == b_start ) {
do_tile = true;
}
if ( do_tile ) {
TGConstruct* stage3;
stage3 = new TGConstruct();
stage3->set_cover( cover );
stage3->set_work_base( work_dir );
stage3->set_output_base( output_dir );
stage3->set_share_base( share_dir );
stage3->set_load_dirs( load_dirs );
stage3->set_useUKGrid( useUKgrid );
stage3->set_write_shared_edges( writeSharedEdges );
stage3->set_use_own_shared_edges( useOwnSharedEdges );
stage3->set_ignore_landmass( ignoreLandmass );
stage3->set_nudge( nudge );
stage3->set_bucket( b_cur );
stage3->set_debug( debug_dir, debug_area_defs, debug_shape_defs );
stage3->LoadFromIntermediateFiles(2);
stage3->ConstructBucketStage3();
delete stage3;
} else {
SG_LOG(SG_GENERAL, SG_ALERT, "skipping " << b_cur);
}
@ -373,24 +456,27 @@ int main(int argc, char **argv) {
// construct the specified tile
SG_LOG(SG_GENERAL, SG_ALERT, "Building tile " << tile_id);
SGBucket b( tile_id );
TGConstruct* all_stages;
c = new TGConstruct();
c->set_cover( cover );
c->set_work_base( work_dir );
c->set_output_base( output_dir );
c->set_share_base( share_dir );
c->set_load_dirs( load_dirs );
c->set_useUKGrid( useUKgrid );
c->set_write_shared_edges( writeSharedEdges );
c->set_use_own_shared_edges( useOwnSharedEdges );
c->set_ignore_landmass( ignoreLandmass );
c->set_nudge( nudge );
c->set_bucket( b );
all_stages = new TGConstruct();
all_stages->set_cover( cover );
all_stages->set_work_base( work_dir );
all_stages->set_output_base( output_dir );
all_stages->set_share_base( share_dir );
all_stages->set_load_dirs( load_dirs );
all_stages->set_useUKGrid( useUKgrid );
all_stages->set_write_shared_edges( writeSharedEdges );
all_stages->set_use_own_shared_edges( useOwnSharedEdges );
all_stages->set_ignore_landmass( ignoreLandmass );
all_stages->set_nudge( nudge );
all_stages->set_bucket( b );
all_stages->set_debug( debug_dir, debug_area_defs, debug_shape_defs );
c->set_debug( debug_dir, debug_area_defs, debug_shape_defs );
all_stages->ConstructBucketStage1();
all_stages->ConstructBucketStage2();
all_stages->ConstructBucketStage3();
c->ConstructBucketStage1();
delete c;
delete all_stages;
}
SG_LOG(SG_GENERAL, SG_ALERT, "[Finished successfully]");

View file

@ -155,44 +155,22 @@ public:
// input from stream
inline std::istream&
operator >> ( std::istream& in, Point3D& p)
inline std::istream& operator >> ( std::istream& in, Point3D& p)
{
char c;
in >> p.n[PX];
// read past optional comma
while ( in.get(c) ) {
if ( (c != ' ') && (c != ',') ) {
// push back on the stream
in.putback(c);
break;
}
}
in >> p.n[PY];
// read past optional comma
while ( in.get(c) ) {
if ( (c != ' ') && (c != ',') ) {
// push back on the stream
in.putback(c);
break;
}
}
in >> p.n[PZ];
return in;
}
inline std::ostream&
operator<< ( std::ostream& out, const Point3D& p )
inline std::ostream& operator<< ( std::ostream& out, const Point3D& p )
{
char buff[128];
sprintf( buff, "(%3.10lf, %3.10lf, %3.10lf)", p.n[PX], p.n[PY], p.n[PZ]);
return out << buff;
out << p.n[PX] << " ";
out << p.n[PY] << " ";
out << p.n[PZ] << "\n";
return out;
}
///////////////////////////

View file

@ -13,6 +13,8 @@ add_library(Polygon STATIC
polygon.hxx
simple_clip.hxx
superpoly.hxx
texparams.cxx
texparams.hxx
clipper.cpp
clipper.hpp
)

View file

@ -968,30 +968,61 @@ TGPolygon tgPolygonSimplify(const TGPolygon &poly)
// Send a polygon to standard output.
ostream &
operator<< (ostream &output, const TGPolygon &poly)
std::ostream& operator << (std::ostream &output, const TGPolygon &poly)
{
char buff[128];
int nContours = poly.contours();
int nContours = poly.contours();
output << "Contours : " << nContours << endl;
// Save the number of contours
output << nContours << "\n";
for (int i = 0; i < nContours; i++) {
int nPoints = poly.contour_size(i);
if ( poly.get_hole_flag(i) ) {
output << " hole contour " << i << " has " << nPoints << " points " << endl;
} else {
output << " boundary contour " << i << " has " << nPoints << " points " << endl;
// Save number of points in the contour
output << nPoints << "\n";
// Then save the points
for ( int j = 0; j < nPoints; j++ ) {
output << poly.get_pt(i, j).x() << " ";
output << poly.get_pt(i, j).y() << " ";
output << poly.get_pt(i, j).z() << "\n";
}
for (int j = 0; j < nPoints; j++) {
sprintf( buff, "(%3.10lf,%3.10lf,%3.10lf)",
poly.get_pt(i, j).x(),
poly.get_pt(i, j).y(),
poly.get_pt(i, j).z()
);
output << buff << endl;
}
// Then save contour hole flag
output << poly.get_hole_flag(i) << "\n";
}
return output; // MSVC
return output;
}
// Read a polygon from input buffer.
std::istream& operator >> (std::istream &input, TGPolygon &poly)
{
int nContours = poly.contours();
double x, y, z;
// Read the number of contours
input >> nContours;
for (int i = 0; i < nContours; i++) {
int nPoints;
int hole;
// Read number of points in the contour
input >> nPoints;
// Then read the points
for ( int j = 0; j < nPoints; j++ ) {
input >> x;
input >> y;
input >> z;
poly.add_node(i, Point3D(x,y,z));
}
// Then read contour hole flag
input >> hole;
poly.set_hole_flag(i, hole);
}
return input;
}

View file

@ -56,157 +56,161 @@ class TGPolygon {
private:
polytype poly; // polygons
point_list inside_list; // point inside list
int_list hole_list; // hole flag list
polytype poly; // polygons
point_list inside_list; // point inside list
int_list hole_list; // hole flag list
public:
// Constructor and destructor
TGPolygon( void );
~TGPolygon( void );
// Constructor and destructor
TGPolygon( void );
~TGPolygon( void );
// Add a contour
inline void add_contour( const point_list contour, const int hole_flag )
{
poly.push_back( contour );
inside_list.push_back( Point3D( 0.0 ) );
hole_list.push_back( hole_flag );
}
// Get a contour
inline point_list get_contour( const int i ) const
{
return poly[i];
}
// Delete a contour
inline void delete_contour( const int i )
{
polytype_iterator start_poly = poly.begin();
poly.erase( start_poly + i );
point_list_iterator start_inside = inside_list.begin();
inside_list.erase( start_inside + i );
int_list_iterator start_hole = hole_list.begin();
hole_list.erase( start_hole + i );
}
// Add the specified node (index) to the polygon
inline void add_node( int contour, Point3D p )
{
if ( contour >= (int)poly.size() ) {
// extend polygon
point_list empty_contour;
empty_contour.clear();
for ( int i = 0; i < contour - (int)poly.size() + 1; ++i ) {
poly.push_back( empty_contour );
inside_list.push_back( Point3D(0.0) );
hole_list.push_back( 0 );
}
// Add a contour
inline void add_contour( const point_list contour, const int hole_flag )
{
poly.push_back( contour );
inside_list.push_back( Point3D( 0.0 ) );
hole_list.push_back( hole_flag );
}
poly[contour].push_back( p );
}
// return size
inline int contours() const
{
return poly.size();
}
inline int contour_size( int contour ) const
{
return poly[contour].size();
}
inline int total_size() const
{
int size = 0;
// Get a contour
inline point_list get_contour( const int i ) const
{
return poly[i];
}
for ( int i = 0; i < contours(); ++i )
size += poly[i].size();
return size;
}
// Delete a contour
inline void delete_contour( const int i )
{
polytype_iterator start_poly = poly.begin();
// return the ith point from the specified contour
inline Point3D get_pt( int contour, int i ) const
{
return poly[contour][i];
}
poly.erase( start_poly + i );
// update the value of a point
inline void set_pt( int contour, int i, const Point3D& p )
{
poly[contour][i] = p;
}
point_list_iterator start_inside = inside_list.begin();
inside_list.erase( start_inside + i );
void get_bounding_box( Point3D& min, Point3D& max ) const;
int_list_iterator start_hole = hole_list.begin();
hole_list.erase( start_hole + i );
}
// get and set an arbitrary point inside the specified polygon contour
inline Point3D get_point_inside( const int contour ) const
{
return inside_list[contour];
}
inline void set_point_inside( int contour, const Point3D& p )
{
inside_list[contour] = p;
}
// Add the specified node (index) to the polygon
inline void add_node( int contour, Point3D p )
{
if ( contour >= (int)poly.size() ) {
// extend polygon
point_list empty_contour;
empty_contour.clear();
for ( int i = 0; i < contour - (int)poly.size() + 1; ++i ) {
poly.push_back( empty_contour );
inside_list.push_back( Point3D(0.0) );
hole_list.push_back( 0 );
}
}
poly[contour].push_back( p );
}
// get and set hole flag
inline int get_hole_flag( const int contour ) const
{
return hole_list[contour];
}
inline void set_hole_flag( const int contour, const int flag )
{
hole_list[contour] = flag;
}
inline bool has_holes() const
{
for (int i = 0; i < contours(); i++)
if (get_hole_flag(i))
return true;
return false;
}
// return size
inline int contours() const
{
return poly.size();
}
inline int contour_size( int contour ) const
{
return poly[contour].size();
}
inline int total_size() const
{
int size = 0;
// Set the elevations of points in the current polgyon based on
// the elevations of points in source. For points that are not
// found in source, propogate the value from the nearest matching
// point.
void inherit_elevations( const TGPolygon &source );
for ( int i = 0; i < contours(); ++i )
size += poly[i].size();
return size;
}
// Set the elevations of all points to the specified values
void set_elevations( double elev );
// return the ith point from the specified contour
inline Point3D get_pt( int contour, int i ) const
{
return poly[contour][i];
}
// shift every point in the polygon by lon, lat
void shift( double lon, double lat );
// update the value of a point
inline void set_pt( int contour, int i, const Point3D& p )
{
poly[contour][i] = p;
}
// erase
inline void erase()
{
poly.clear();
}
void get_bounding_box( Point3D& min, Point3D& max ) const;
// informational
// get and set an arbitrary point inside the specified polygon contour
inline Point3D get_point_inside( const int contour ) const
{
return inside_list[contour];
}
inline void set_point_inside( int contour, const Point3D& p )
{
inside_list[contour] = p;
}
// return the area of a contour (assumes simple polygons,
// i.e. non-self intersecting.)
//
// negative areas indicate counter clockwise winding
// positive areas indicate clockwise winding.
double area_contour( const int contour ) const;
// get and set hole flag
inline int get_hole_flag( const int contour ) const
{
return hole_list[contour];
}
inline void set_hole_flag( const int contour, const int flag )
{
hole_list[contour] = flag;
}
inline bool has_holes() const
{
for (int i = 0; i < contours(); i++)
if (get_hole_flag(i))
return true;
return false;
}
// return the smallest interior angle of the contour
double minangle_contour( const int contour );
// Set the elevations of points in the current polgyon based on
// the elevations of points in source. For points that are not
// found in source, propogate the value from the nearest matching
// point.
void inherit_elevations( const TGPolygon &source );
// return true if contour B is inside countour A
bool is_inside( int a, int b ) const;
// Set the elevations of all points to the specified values
void set_elevations( double elev );
// output
void write( const std::string& file ) const;
// shift every point in the polygon by lon, lat
void shift( double lon, double lat );
// output
void write_contour( const int contour, const std::string& file ) const;
// erase
inline void erase()
{
poly.clear();
}
// informational
// return the area of a contour (assumes simple polygons,
// i.e. non-self intersecting.)
//
// negative areas indicate counter clockwise winding
// positive areas indicate clockwise winding.
double area_contour( const int contour ) const;
// return the smallest interior angle of the contour
double minangle_contour( const int contour );
// return true if contour B is inside countour A
bool is_inside( int a, int b ) const;
// output
void write( const std::string& file ) const;
// output
void write_contour( const int contour, const std::string& file ) const;
// Friends for serialization
friend std::istream& operator>> ( std::istream&, TGPolygon& );
friend std::ostream& operator<< ( std::ostream&, const TGPolygon& );
};

View file

@ -22,6 +22,7 @@
#include "superpoly.hxx"
#include <simgear/debug/logstream.hxx>
// Constructor
@ -46,3 +47,130 @@ void TGSuperPoly::erase()
tris.erase();
face_normals.clear();
}
// Friends for serialization
std::ostream& operator<< ( std::ostream& output, const TGSuperPoly& sp )
{
int nFaceNormals;
int nFaceAreas;
// Save the data
output << sp.material << "\n";
output << sp.poly;
output << sp.normals;
output << sp.texcoords;
output << sp.tris;
output << sp.tri_idxs;
nFaceNormals = sp.face_normals.size();
output << nFaceNormals << "\n";
for ( int i = 0; i < nFaceNormals; i++ ) {
output << sp.face_normals[i];
}
nFaceAreas = sp.face_areas.size();
output << nFaceAreas;
for ( int i = 0; i < nFaceAreas; i++ ) {
output << sp.face_areas[i] << " ";
}
output << "\n";
if ( sp.flag.empty() ) {
output << "none\n";
} else {
output << sp.flag << "\n";
}
return output;
}
std::istream& operator>> ( std::istream& input, TGSuperPoly& sp )
{
int nFaceNormals;
int nFaceAreas;
Point3D normal;
double area;
// Load the data
input >> sp.material;
SG_LOG(SG_GENERAL, SG_ALERT, "\t\tsp: material " << sp.material );
input >> sp.poly;
SG_LOG(SG_GENERAL, SG_ALERT, "\t\tsp: poly " << sp.poly );
input >> sp.normals;
SG_LOG(SG_GENERAL, SG_ALERT, "\t\tsp: normals " << sp.normals );
input >> sp.texcoords;
SG_LOG(SG_GENERAL, SG_ALERT, "\t\tsp: texcoords " << sp.texcoords );
input >> sp.tris;
SG_LOG(SG_GENERAL, SG_ALERT, "\t\tsp: tris " << sp.tris );
input >> sp.tri_idxs;
SG_LOG(SG_GENERAL, SG_ALERT, "\t\tsp: tri_idxs " << sp.tri_idxs );
input >> nFaceNormals;
SG_LOG(SG_GENERAL, SG_ALERT, "\t\tsp: nFaceNormals " << nFaceNormals );
for ( int i = 0; i < nFaceNormals; i++ ) {
input >> normal;
sp.face_normals.push_back(normal);
}
input >> nFaceAreas;
SG_LOG(SG_GENERAL, SG_ALERT, "\t\tsp: nFaceAreas " << nFaceAreas );
for ( int i = 0; i < nFaceAreas; i++ ) {
input >> area;
sp.face_areas.push_back(area);
}
input >> sp.flag;
SG_LOG(SG_GENERAL, SG_ALERT, "\t\tsp: flag " << sp.flag );
return input;
}
std::ostream& operator<< ( std::ostream& output, const TGPolyNodes& pn )
{
int nContours;
int nPoints;
// Save the data
nContours = pn.poly.size();
output << nContours << "\n";
for(int i=0; i<nContours; i++) {
nPoints = pn.poly[i].size();
output << nPoints << "\n";
for (int j=0; j<nPoints; j++) {
output << pn.poly[i][j] << " ";
}
output << "\n";
}
return output;
}
std::istream& operator>> ( std::istream& input, TGPolyNodes& pn )
{
int nContours;
int nPoints;
int point;
// Load the data
input >> nContours;
for(int i=0; i<nContours; i++) {
int_list points;
input >> nPoints;
for (int j=0; j<nPoints; j++) {
input >> point;
points.push_back( point );
}
pn.poly.push_back( points );
}
return input;
}

View file

@ -119,6 +119,10 @@ public:
{
poly[contour][i] = n;
}
// Friends for serialization
friend std::istream& operator>> ( std::istream&, TGPolyNodes& );
friend std::ostream& operator<< ( std::ostream&, const TGPolyNodes& );
};
// END TODO
@ -128,118 +132,121 @@ class TGSuperPoly {
private:
std::string material; // material/texture name
TGPolygon poly; // master polygon
TGPolygon normals; // corresponding normals
TGPolygon texcoords; // corresponding texture coordinates
std::string material; // material/texture name
TGPolygon poly; // master polygon
TGPolygon normals; // corresponding normals
TGPolygon texcoords; // corresponding texture coordinates
TGPolygon tris; // triangulation
TGPolyNodes tri_idxs; // triangle node indexes
TGPolygon tris; // triangulation
TGPolyNodes tri_idxs; // triangle node indexes
point_list face_normals; // triangle normals
double_list face_areas; // triangle areas
std::string flag; // For various potential record keeping needs
point_list face_normals; // triangle normals
double_list face_areas; // triangle areas
std::string flag; // For various potential record keeping needs
public:
// Constructor and destructor
TGSuperPoly( void );
~TGSuperPoly( void );
// Constructor and destructor
TGSuperPoly( void );
~TGSuperPoly( void );
inline std::string get_material() const
{
return material;
}
inline void set_material( const std::string &m )
{
material = m;
}
inline std::string get_material() const
{
return material;
}
inline void set_material( const std::string &m )
{
material = m;
}
inline TGPolygon get_poly() const
{
return poly;
}
inline void set_poly( const TGPolygon &p )
{
poly = p;
}
inline TGPolygon get_poly() const
{
return poly;
}
inline void set_poly( const TGPolygon &p )
{
poly = p;
}
inline TGPolygon get_normals() const
{
return normals;
}
inline void set_normals( const TGPolygon &p )
{
normals = p;
}
inline TGPolygon get_normals() const
{
return normals;
}
inline void set_normals( const TGPolygon &p )
{
normals = p;
}
inline TGPolygon get_texcoords() const
{
return texcoords;
}
inline void set_texcoords( const TGPolygon &p )
{
texcoords = p;
}
inline TGPolygon get_texcoords() const
{
return texcoords;
}
inline void set_texcoords( const TGPolygon &p )
{
texcoords = p;
}
inline TGPolygon get_tris() const
{
return tris;
}
inline void set_tris( const TGPolygon &p )
{
tris = p;
}
inline TGPolygon get_tris() const
{
return tris;
}
inline void set_tris( const TGPolygon &p )
{
tris = p;
}
inline TGPolyNodes get_tri_idxs() const
{
return tri_idxs;
}
inline void set_tri_idxs( const TGPolyNodes &p )
{
tri_idxs = p;
}
inline TGPolyNodes get_tri_idxs() const
{
return tri_idxs;
}
inline void set_tri_idxs( const TGPolyNodes &p )
{
tri_idxs = p;
}
inline Point3D get_face_normal( int tri ) const
{
return face_normals[tri];
}
inline Point3D get_face_normal( int tri ) const
{
return face_normals[tri];
}
inline point_list get_face_normals() const
{
return face_normals;
}
inline void set_face_normals( const point_list &fns )
{
face_normals = fns;
}
inline point_list get_face_normals() const
{
return face_normals;
}
inline void set_face_normals( const point_list &fns )
{
face_normals = fns;
}
inline double get_face_area( int tri ) const
{
return face_areas[tri];
}
inline double get_face_area( int tri ) const
{
return face_areas[tri];
}
inline double_list get_face_areas() const
{
return face_areas;
}
inline void set_face_areas( const double_list &fas )
{
face_areas = fas;
}
inline double_list get_face_areas() const
{
return face_areas;
}
inline void set_face_areas( const double_list &fas )
{
face_areas = fas;
}
inline std::string get_flag() const
{
return flag;
}
inline void set_flag( const std::string f )
{
flag = f;
}
inline std::string get_flag() const
{
return flag;
}
inline void set_flag( const std::string f )
{
flag = f;
}
// erase the polygon
void erase();
// erase the polygon
void erase();
// Friends for serialization
friend std::istream& operator>> ( std::istream&, TGSuperPoly& );
friend std::ostream& operator<< ( std::ostream&, const TGSuperPoly& );
};

View file

@ -0,0 +1,35 @@
#include "texparams.hxx"
// Send a TexParam to standard output.
std::ostream& operator << (std::ostream &output, const TGTexParams &tp)
{
// Save the data
output << tp.ref;
output << tp.width << " ";
output << tp.length << " ";
output << tp.heading << "\n";
output << tp.minu << " ";
output << tp.maxu << " ";
output << tp.minv << " ";
output << tp.maxv << "\n";
return output;
}
// Read a polygon from input buffer.
std::istream& operator >> (std::istream &input, TGTexParams &tp)
{
// Load the data
input >> tp.ref;
input >> tp.width;
input >> tp.length;
input >> tp.heading;
input >> tp.minu;
input >> tp.maxu;
input >> tp.minv;
input >> tp.maxv;
return input;
}

View file

@ -34,120 +34,123 @@
#include <simgear/compiler.h>
#include <simgear/math/sg_types.hxx>
#include <Geometry/point3d.hxx>
#include <vector>
class TGTexParams {
private:
Point3D ref;
double width;
double length;
double heading;
Point3D ref;
double width;
double length;
double heading;
double minu;
double maxu;
double minv;
double maxv;
double minu;
double maxu;
double minv;
double maxv;
public:
// Constructor and destructor
inline TGTexParams( void )
{
}
inline TGTexParams( const Point3D &r, const double w, const double l,
const double h )
{
ref = r;
width = w;
length = l;
heading = h;
// Constructor and destructor
inline TGTexParams( void )
{
}
inline TGTexParams( const Point3D &r, const double w, const double l, const double h )
{
ref = r;
width = w;
length = l;
heading = h;
minu = minv = 0.0;
maxu = maxv = 1.0;
}
inline ~TGTexParams( void )
{
}
minu = minv = 0.0;
maxu = maxv = 1.0;
}
inline ~TGTexParams( void )
{
}
inline Point3D get_ref() const
{
return ref;
}
inline void set_ref( const Point3D &r )
{
ref = r;
}
inline Point3D get_ref() const
{
return ref;
}
inline void set_ref( const Point3D &r )
{
ref = r;
}
inline double get_width() const
{
return width;
}
inline void set_width( const double w )
{
width = w;
}
inline double get_width() const
{
return width;
}
inline void set_width( const double w )
{
width = w;
}
inline double get_length() const
{
return length;
}
inline void set_length( const double l )
{
length = l;
}
inline double get_length() const
{
return length;
}
inline void set_length( const double l )
{
length = l;
}
inline double get_heading() const
{
return heading;
}
inline void set_heading( const double h )
{
heading = h;
}
inline double get_heading() const
{
return heading;
}
inline void set_heading( const double h )
{
heading = h;
}
inline double get_minu() const
{
return minu;
}
inline void set_minu( const double x )
{
minu = x;
}
inline double get_minu() const
{
return minu;
}
inline void set_minu( const double x )
{
minu = x;
}
inline double get_maxu() const
{
return maxu;
}
inline void set_maxu( const double x )
{
maxu = x;
}
inline double get_maxu() const
{
return maxu;
}
inline void set_maxu( const double x )
{
maxu = x;
}
inline double get_minv() const
{
return minv;
}
inline void set_minv( const double x )
{
minv = x;
}
inline double get_minv() const
{
return minv;
}
inline void set_minv( const double x )
{
minv = x;
}
inline double get_maxv() const
{
return maxv;
}
inline void set_maxv( const double x )
{
maxv = x;
}
inline double get_maxv() const
{
return maxv;
}
inline void set_maxv( const double x )
{
maxv = x;
}
// Friends for serialization
friend std::istream& operator>> ( std::istream&, TGTexParams& );
friend std::ostream& operator<< ( std::ostream&, const TGTexParams& );
};
typedef std::vector < TGTexParams > texparams_list;
typedef texparams_list::iterator texparams_list_iterator;
typedef texparams_list::const_iterator const_texparams_list_iterator;
#endif // _TEXPARAMS_HXX