From 779db9566ba8602395fc55fe9a8cc398573aada7 Mon Sep 17 00:00:00 2001 From: Peter Sadrozinski Date: Fri, 7 Sep 2012 21:16:23 -0400 Subject: [PATCH] multistage coming along - need TGNodes derialization --- src/BuildTiles/Main/construct.cxx | 174 +++++++++++++++++--- src/BuildTiles/Main/construct.hxx | 154 +++++++++++++++++- src/BuildTiles/Main/main.cxx | 212 +++++++++++++++++------- src/Lib/Geometry/point3d.hxx | 36 +--- src/Lib/Polygon/CMakeLists.txt | 2 + src/Lib/Polygon/polygon.cxx | 65 ++++++-- src/Lib/Polygon/polygon.hxx | 262 +++++++++++++++--------------- src/Lib/Polygon/superpoly.cxx | 128 +++++++++++++++ src/Lib/Polygon/superpoly.hxx | 195 +++++++++++----------- src/Lib/Polygon/texparams.cxx | 35 ++++ src/Lib/Polygon/texparams.hxx | 185 ++++++++++----------- 11 files changed, 991 insertions(+), 457 deletions(-) create mode 100644 src/Lib/Polygon/texparams.cxx diff --git a/src/BuildTiles/Main/construct.cxx b/src/BuildTiles/Main/construct.cxx index eb5154f2..41539ecb 100644 --- a/src/BuildTiles/Main/construct.cxx +++ b/src/BuildTiles/Main/construct.cxx @@ -27,6 +27,7 @@ #include #include +#include #include @@ -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(); } diff --git a/src/BuildTiles/Main/construct.hxx b/src/BuildTiles/Main/construct.hxx index fc20157f..5f03f5c0 100644 --- a/src/BuildTiles/Main/construct.hxx +++ b/src/BuildTiles/Main/construct.hxx @@ -35,6 +35,7 @@ #include #include +#include #include #include @@ -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> 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> 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 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> count; + SG_LOG(SG_GENERAL, SG_ALERT, "Loading Landclass: area " << i << " size is " << count ); + + for (j=0; j> 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; iset_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]"); diff --git a/src/Lib/Geometry/point3d.hxx b/src/Lib/Geometry/point3d.hxx index fd606f2f..da226abf 100644 --- a/src/Lib/Geometry/point3d.hxx +++ b/src/Lib/Geometry/point3d.hxx @@ -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; } /////////////////////////// diff --git a/src/Lib/Polygon/CMakeLists.txt b/src/Lib/Polygon/CMakeLists.txt index 3bd7c47c..043d27f8 100644 --- a/src/Lib/Polygon/CMakeLists.txt +++ b/src/Lib/Polygon/CMakeLists.txt @@ -13,6 +13,8 @@ add_library(Polygon STATIC polygon.hxx simple_clip.hxx superpoly.hxx + texparams.cxx + texparams.hxx clipper.cpp clipper.hpp ) diff --git a/src/Lib/Polygon/polygon.cxx b/src/Lib/Polygon/polygon.cxx index c980e344..d48b214c 100644 --- a/src/Lib/Polygon/polygon.cxx +++ b/src/Lib/Polygon/polygon.cxx @@ -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; } diff --git a/src/Lib/Polygon/polygon.hxx b/src/Lib/Polygon/polygon.hxx index f36d0fc6..e114a87e 100644 --- a/src/Lib/Polygon/polygon.hxx +++ b/src/Lib/Polygon/polygon.hxx @@ -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& ); }; diff --git a/src/Lib/Polygon/superpoly.cxx b/src/Lib/Polygon/superpoly.cxx index 10cc9a70..83154ffd 100644 --- a/src/Lib/Polygon/superpoly.cxx +++ b/src/Lib/Polygon/superpoly.cxx @@ -22,6 +22,7 @@ #include "superpoly.hxx" +#include // 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> ( std::istream& input, TGPolyNodes& pn ) +{ + int nContours; + int nPoints; + int point; + + // Load the data + input >> nContours; + for(int i=0; i> nPoints; + for (int j=0; j> point; + points.push_back( point ); + } + pn.poly.push_back( points ); + } + + return input; +} \ No newline at end of file diff --git a/src/Lib/Polygon/superpoly.hxx b/src/Lib/Polygon/superpoly.hxx index 2a32e004..8cb4f413 100644 --- a/src/Lib/Polygon/superpoly.hxx +++ b/src/Lib/Polygon/superpoly.hxx @@ -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& ); }; diff --git a/src/Lib/Polygon/texparams.cxx b/src/Lib/Polygon/texparams.cxx new file mode 100644 index 00000000..c965537a --- /dev/null +++ b/src/Lib/Polygon/texparams.cxx @@ -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; +} \ No newline at end of file diff --git a/src/Lib/Polygon/texparams.hxx b/src/Lib/Polygon/texparams.hxx index 568bfe74..1c53036c 100644 --- a/src/Lib/Polygon/texparams.hxx +++ b/src/Lib/Polygon/texparams.hxx @@ -34,120 +34,123 @@ #include #include +#include + #include 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