Restructuring code and data to facilitate the tile edge matching process.
This commit is contained in:
parent
134d7cf480
commit
f2fb1eb99a
10 changed files with 239 additions and 197 deletions
|
@ -17,9 +17,3 @@ INCLUDES += \
|
|||
-I$(top_builddir) \
|
||||
-I$(top_builddir)/Lib \
|
||||
-I$(top_builddir)/Tools/Construct
|
||||
|
||||
# We can't build this with "-O2" (optimization) since this causes a seg fault
|
||||
# I haven't found a way to strip this out of the CXXFLAGS, so I'm just
|
||||
# setting it to "-g"
|
||||
# CXXFLAGS = -g
|
||||
|
||||
|
|
|
@ -47,6 +47,10 @@ bool FGClipper::init() {
|
|||
v_list.num_vertices = 0;
|
||||
v_list.vertex = new gpc_vertex[FG_MAX_VERTICES];;
|
||||
|
||||
for ( int i = 0; i < FG_MAX_AREA_TYPES; ++i ) {
|
||||
polys_in.polys[i].clear();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -178,8 +182,8 @@ bool FGClipper::clip_all(const point2d& min, const point2d& max) {
|
|||
|
||||
// process polygons in priority order
|
||||
for ( int i = 0; i < FG_MAX_AREA_TYPES; ++i ) {
|
||||
// cout << "num polys of this type = "
|
||||
// << polys_in.polys[i].size() << endl;
|
||||
cout << "num polys of type (" << i << ") = "
|
||||
<< polys_in.polys[i].size() << endl;
|
||||
current = polys_in.polys[i].begin();
|
||||
last = polys_in.polys[i].end();
|
||||
for ( ; current != last; ++current ) {
|
||||
|
@ -220,24 +224,24 @@ bool FGClipper::clip_all(const point2d& min, const point2d& max) {
|
|||
}
|
||||
|
||||
/*
|
||||
cout << "original contours = " << tmp.num_contours << endl;
|
||||
cout << "original contours = " << tmp.num_contours << endl;
|
||||
|
||||
for ( int j = 0; j < tmp.num_contours; j++ ) {
|
||||
for (int k = 0;k < tmp.contour[j].num_vertices;k++ ) {
|
||||
cout << tmp.contour[j].vertex[k].x << ","
|
||||
<< tmp.contour[j].vertex[k].y << endl;
|
||||
}
|
||||
}
|
||||
for ( int j = 0; j < tmp.num_contours; j++ ) {
|
||||
for (int k = 0;k < tmp.contour[j].num_vertices;k++ ) {
|
||||
cout << tmp.contour[j].vertex[k].x << ","
|
||||
<< tmp.contour[j].vertex[k].y << endl;
|
||||
}
|
||||
}
|
||||
|
||||
cout << "clipped contours = " << result_diff->num_contours << endl;
|
||||
cout << "clipped contours = " << result_diff->num_contours << endl;
|
||||
|
||||
for ( int j = 0; j < result_diff->num_contours; j++ ) {
|
||||
for (int k = 0;k < result_diff->contour[j].num_vertices;k++ ) {
|
||||
cout << result_diff->contour[j].vertex[k].x << ","
|
||||
<< result_diff->contour[j].vertex[k].y << endl;
|
||||
}
|
||||
}
|
||||
*/
|
||||
for ( int j = 0; j < result_diff->num_contours; j++ ) {
|
||||
for (int k = 0;k < result_diff->contour[j].num_vertices;k++ ) {
|
||||
cout << result_diff->contour[j].vertex[k].x << ","
|
||||
<< result_diff->contour[j].vertex[k].y << endl;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// only add to output list if the clip left us with a polygon
|
||||
if ( result_diff->num_contours > 0 ) {
|
||||
|
@ -259,15 +263,21 @@ bool FGClipper::clip_all(const point2d& min, const point2d& max) {
|
|||
polys_clipped.polys[0].push_back(remains);
|
||||
}
|
||||
|
||||
FILE *ofp;
|
||||
|
||||
// tmp output accum
|
||||
FILE *ofp= fopen("accum", "w");
|
||||
gpc_write_polygon(ofp, 1, &accum);
|
||||
fclose(ofp);
|
||||
if ( accum.num_contours ) {
|
||||
ofp = fopen("accum", "w");
|
||||
gpc_write_polygon(ofp, 1, &accum);
|
||||
fclose(ofp);
|
||||
}
|
||||
|
||||
// tmp output safety_base
|
||||
ofp= fopen("remains", "w");
|
||||
gpc_write_polygon(ofp, 1, remains);
|
||||
fclose(ofp);
|
||||
if ( remains->num_contours ) {
|
||||
ofp= fopen("remains", "w");
|
||||
gpc_write_polygon(ofp, 1, remains);
|
||||
fclose(ofp);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -31,43 +31,16 @@
|
|||
#include "genobj.hxx"
|
||||
|
||||
|
||||
// build the wgs-84 point list
|
||||
void FGGenOutput::gen_wgs84_points( const FGArray& array ) {
|
||||
cout << "calculating wgs84 point" << endl;
|
||||
Point3D geod, radians, cart;
|
||||
|
||||
const_point_list_iterator current = geod_nodes.begin();
|
||||
const_point_list_iterator last = geod_nodes.end();
|
||||
|
||||
double real_z;
|
||||
|
||||
for ( ; current != last; ++current ) {
|
||||
geod = *current;
|
||||
|
||||
real_z = array.interpolate_altitude( geod.x() * 3600.0,
|
||||
geod.y() * 3600.0 );
|
||||
|
||||
// convert to radians
|
||||
radians = Point3D( geod.x() * DEG_TO_RAD,
|
||||
geod.y() * DEG_TO_RAD,
|
||||
real_z );
|
||||
|
||||
cart = fgGeodToCart(radians);
|
||||
// cout << cart << endl;
|
||||
wgs84_nodes.push_back(cart);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// build the node -> element (triangle) reverse lookup table. there
|
||||
// is an entry for each point containing a list of all the triangles
|
||||
// that share that point.
|
||||
void FGGenOutput::gen_node_ele_lookup_table() {
|
||||
void FGGenOutput::gen_node_ele_lookup_table( FGConstruct& c ) {
|
||||
int_list ele_list;
|
||||
ele_list.erase( ele_list.begin(), ele_list.end() );
|
||||
|
||||
// initialize reverse_ele_lookup structure by creating an empty
|
||||
// list for each point
|
||||
point_list wgs84_nodes = c.get_wgs84_nodes();
|
||||
const_point_list_iterator w_current = wgs84_nodes.begin();
|
||||
const_point_list_iterator w_last = wgs84_nodes.end();
|
||||
for ( ; w_current != w_last; ++w_current ) {
|
||||
|
@ -88,10 +61,12 @@ void FGGenOutput::gen_node_ele_lookup_table() {
|
|||
|
||||
|
||||
// caclulate the normal for the specified triangle face
|
||||
Point3D FGGenOutput::calc_normal( int i ) {
|
||||
Point3D FGGenOutput::calc_normal( FGConstruct& c, int i ) {
|
||||
double v1[3], v2[3], normal[3];
|
||||
double temp;
|
||||
|
||||
point_list wgs84_nodes = c.get_wgs84_nodes();
|
||||
|
||||
Point3D p1 = wgs84_nodes[ tri_elements[i].get_n1() ];
|
||||
Point3D p2 = wgs84_nodes[ tri_elements[i].get_n2() ];
|
||||
Point3D p3 = wgs84_nodes[ tri_elements[i].get_n3() ];
|
||||
|
@ -107,24 +82,26 @@ Point3D FGGenOutput::calc_normal( int i ) {
|
|||
|
||||
|
||||
// build the face normal list
|
||||
void FGGenOutput::gen_face_normals() {
|
||||
void FGGenOutput::gen_face_normals( FGConstruct& c ) {
|
||||
// traverse triangle structure building the face normal table
|
||||
|
||||
cout << "calculating face normals" << endl;
|
||||
|
||||
for ( int i = 0; i < (int)tri_elements.size(); i++ ) {
|
||||
// cout << calc_normal( i ) << endl;
|
||||
face_normals.push_back( calc_normal( i ) );
|
||||
face_normals.push_back( calc_normal( c, i ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// calculate the normals for each point in wgs84_nodes
|
||||
void FGGenOutput::gen_normals() {
|
||||
void FGGenOutput::gen_normals( FGConstruct& c ) {
|
||||
Point3D normal;
|
||||
cout << "caculating node normals" << endl;
|
||||
|
||||
point_list wgs84_nodes = c.get_wgs84_nodes();
|
||||
|
||||
// for each node
|
||||
for ( int i = 0; i < (int)wgs84_nodes.size(); ++i ) {
|
||||
int_list tri_list = reverse_ele_lookup[i];
|
||||
|
@ -151,12 +128,13 @@ void FGGenOutput::gen_normals() {
|
|||
|
||||
// calculate the global bounding sphere. Center is the average of the
|
||||
// points.
|
||||
void FGGenOutput::calc_gbs() {
|
||||
void FGGenOutput::calc_gbs( FGConstruct& c ) {
|
||||
double dist_squared;
|
||||
double radius_squared = 0;
|
||||
|
||||
gbs_center = Point3D( 0.0 );
|
||||
|
||||
point_list wgs84_nodes = c.get_wgs84_nodes();
|
||||
const_point_list_iterator current = wgs84_nodes.begin();
|
||||
const_point_list_iterator last = wgs84_nodes.end();
|
||||
|
||||
|
@ -180,14 +158,14 @@ void FGGenOutput::calc_gbs() {
|
|||
|
||||
// build the necessary output structures based on the triangulation
|
||||
// data
|
||||
int FGGenOutput::build( const FGArray& array, const FGTriangle& t ) {
|
||||
FGTriNodes trinodes = t.get_out_nodes();
|
||||
int FGGenOutput::build( FGConstruct& c, const FGArray& array ) {
|
||||
FGTriNodes trinodes = c.get_tri_nodes();
|
||||
|
||||
// copy the geodetic node list into this class
|
||||
geod_nodes = trinodes.get_node_list();
|
||||
|
||||
// copy the triangle list into this class
|
||||
tri_elements = t.get_elelist();
|
||||
tri_elements = c.get_tri_elements();
|
||||
|
||||
// build the trifan list
|
||||
cout << "total triangles = " << tri_elements.size() << endl;
|
||||
|
@ -210,33 +188,33 @@ int FGGenOutput::build( const FGArray& array, const FGTriangle& t ) {
|
|||
}
|
||||
}
|
||||
|
||||
// generate the point list in wgs-84 coordinates
|
||||
gen_wgs84_points( array );
|
||||
|
||||
// calculate the global bounding sphere
|
||||
calc_gbs();
|
||||
calc_gbs( c );
|
||||
cout << "center = " << gbs_center << " radius = " << gbs_radius << endl;
|
||||
|
||||
// build the node -> element (triangle) reverse lookup table
|
||||
gen_node_ele_lookup_table();
|
||||
gen_node_ele_lookup_table( c );
|
||||
|
||||
// build the face normal list
|
||||
gen_face_normals();
|
||||
gen_face_normals( c );
|
||||
|
||||
// calculate the normals for each point in wgs84_nodes
|
||||
gen_normals();
|
||||
gen_normals( c );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// caclulate the bounding sphere for a list of triangle faces
|
||||
void FGGenOutput::calc_group_bounding_sphere( const fan_list& fans,
|
||||
void FGGenOutput::calc_group_bounding_sphere( FGConstruct& c,
|
||||
const fan_list& fans,
|
||||
Point3D *center, double *radius )
|
||||
{
|
||||
cout << "calculate group bounding sphere for " << fans.size() << " fans."
|
||||
<< endl;
|
||||
|
||||
point_list wgs84_nodes = c.get_wgs84_nodes();
|
||||
|
||||
// generate a list of unique points from the triangle list
|
||||
FGTriNodes nodes;
|
||||
|
||||
|
@ -252,15 +230,15 @@ void FGGenOutput::calc_group_bounding_sphere( const fan_list& fans,
|
|||
}
|
||||
|
||||
// find average of point list
|
||||
Point3D c( 0.0 );
|
||||
*center = Point3D( 0.0 );
|
||||
point_list points = nodes.get_node_list();
|
||||
// cout << "found " << points.size() << " unique nodes" << endl;
|
||||
point_list_iterator p_current = points.begin();
|
||||
point_list_iterator p_last = points.end();
|
||||
for ( ; p_current != p_last; ++p_current ) {
|
||||
c += *p_current;
|
||||
*center += *p_current;
|
||||
}
|
||||
c /= points.size();
|
||||
*center /= points.size();
|
||||
|
||||
// find max radius
|
||||
double dist_squared;
|
||||
|
@ -269,57 +247,60 @@ void FGGenOutput::calc_group_bounding_sphere( const fan_list& fans,
|
|||
p_current = points.begin();
|
||||
p_last = points.end();
|
||||
for ( ; p_current != p_last; ++p_current ) {
|
||||
dist_squared = c.distance3Dsquared(*p_current);
|
||||
dist_squared = (*center).distance3Dsquared(*p_current);
|
||||
if ( dist_squared > max_squared ) {
|
||||
max_squared = dist_squared;
|
||||
}
|
||||
}
|
||||
|
||||
*center = c;
|
||||
*radius = sqrt(max_squared);
|
||||
}
|
||||
|
||||
|
||||
// caclulate the bounding sphere for the specified triangle face
|
||||
void FGGenOutput::calc_bounding_sphere( const FGTriEle& t,
|
||||
void FGGenOutput::calc_bounding_sphere( FGConstruct& c, const FGTriEle& t,
|
||||
Point3D *center, double *radius )
|
||||
{
|
||||
Point3D c( 0.0 );
|
||||
point_list wgs84_nodes = c.get_wgs84_nodes();
|
||||
|
||||
*center = Point3D( 0.0 );
|
||||
|
||||
Point3D p1 = wgs84_nodes[ t.get_n1() ];
|
||||
Point3D p2 = wgs84_nodes[ t.get_n2() ];
|
||||
Point3D p3 = wgs84_nodes[ t.get_n3() ];
|
||||
|
||||
c = p1 + p2 + p3;
|
||||
c /= 3;
|
||||
*center = p1 + p2 + p3;
|
||||
*center /= 3;
|
||||
|
||||
double dist_squared;
|
||||
double max_squared = 0;
|
||||
|
||||
dist_squared = c.distance3Dsquared(p1);
|
||||
dist_squared = (*center).distance3Dsquared(p1);
|
||||
if ( dist_squared > max_squared ) {
|
||||
max_squared = dist_squared;
|
||||
}
|
||||
|
||||
dist_squared = c.distance3Dsquared(p2);
|
||||
dist_squared = (*center).distance3Dsquared(p2);
|
||||
if ( dist_squared > max_squared ) {
|
||||
max_squared = dist_squared;
|
||||
}
|
||||
|
||||
dist_squared = c.distance3Dsquared(p3);
|
||||
dist_squared = (*center).distance3Dsquared(p3);
|
||||
if ( dist_squared > max_squared ) {
|
||||
max_squared = dist_squared;
|
||||
}
|
||||
|
||||
*center = c;
|
||||
*radius = sqrt(max_squared);
|
||||
}
|
||||
|
||||
|
||||
// write out the fgfs scenery file
|
||||
int FGGenOutput::write( const string& base, const FGBucket& b ) {
|
||||
int FGGenOutput::write( FGConstruct &c ) {
|
||||
Point3D p;
|
||||
|
||||
string base = c.get_output_base();
|
||||
FGBucket b = c.get_bucket();
|
||||
|
||||
string dir = base + "/Scenery/" + b.gen_base_path();
|
||||
string command = "mkdir -p " + dir;
|
||||
system(command.c_str());
|
||||
|
@ -350,6 +331,7 @@ int FGGenOutput::write( const string& base, const FGBucket& b ) {
|
|||
fprintf(fp, "\n");
|
||||
|
||||
// write nodes
|
||||
point_list wgs84_nodes = c.get_wgs84_nodes();
|
||||
fprintf(fp, "# vertex list\n");
|
||||
const_point_list_iterator w_current = wgs84_nodes.begin();
|
||||
const_point_list_iterator w_last = wgs84_nodes.end();
|
||||
|
@ -379,7 +361,7 @@ int FGGenOutput::write( const string& base, const FGBucket& b ) {
|
|||
for ( int i = 0; i < FG_MAX_AREA_TYPES; ++i ) {
|
||||
if ( (int)fans[i].size() > 0 ) {
|
||||
string attr_name = get_area_name( (AreaType)i );
|
||||
calc_group_bounding_sphere( fans[i], ¢er, &radius );
|
||||
calc_group_bounding_sphere( c, fans[i], ¢er, &radius );
|
||||
cout << "writing " << (int)fans[i].size() << " fans for "
|
||||
<< attr_name << endl;
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
|
||||
#include <Combine/genfans.hxx>
|
||||
#include <Main/construct_types.hxx>
|
||||
#include <Main/construct.hxx>
|
||||
#include <Triangulate/triangle.hxx>
|
||||
|
||||
FG_USING_STD(string);
|
||||
|
@ -56,12 +57,9 @@ class FGGenOutput {
|
|||
|
||||
private:
|
||||
|
||||
// node list in geodetic coordinats
|
||||
// node list in geodetic coordinates
|
||||
point_list geod_nodes;
|
||||
|
||||
// node list in cartesian coords (wgs84 model)
|
||||
point_list wgs84_nodes;
|
||||
|
||||
// face normal list (for flat shading)
|
||||
point_list face_normals;
|
||||
|
||||
|
@ -82,33 +80,30 @@ private:
|
|||
Point3D gbs_center;
|
||||
double gbs_radius;
|
||||
|
||||
// build the wgs-84 point list
|
||||
void gen_wgs84_points( const FGArray& array );
|
||||
|
||||
// build the node -> element (triangle) reverse lookup table.
|
||||
// there is an entry for each point containing a list of all the
|
||||
// triangles that share that point.
|
||||
void gen_node_ele_lookup_table();
|
||||
void gen_node_ele_lookup_table( FGConstruct& c );
|
||||
|
||||
// calculate the normals for each point in wgs84_nodes
|
||||
void gen_normals();
|
||||
void gen_normals( FGConstruct& c );
|
||||
|
||||
// build the face normal list
|
||||
void gen_face_normals();
|
||||
void gen_face_normals( FGConstruct& c );
|
||||
|
||||
// caclulate the normal for the specified triangle face
|
||||
Point3D calc_normal( int i );
|
||||
Point3D calc_normal( FGConstruct& c, int i );
|
||||
|
||||
// calculate the global bounding sphere. Center is the average of
|
||||
// the points.
|
||||
void calc_gbs();
|
||||
void calc_gbs( FGConstruct& c );
|
||||
|
||||
// caclulate the bounding sphere for a list of triangle faces
|
||||
void calc_group_bounding_sphere( const fan_list& fans,
|
||||
void calc_group_bounding_sphere( FGConstruct& c, const fan_list& fans,
|
||||
Point3D *center, double *radius );
|
||||
|
||||
// caclulate the bounding sphere for the specified triangle face
|
||||
void calc_bounding_sphere( const FGTriEle& t,
|
||||
void calc_bounding_sphere( FGConstruct& c, const FGTriEle& t,
|
||||
Point3D *center, double *radius );
|
||||
|
||||
public:
|
||||
|
@ -119,10 +114,10 @@ public:
|
|||
|
||||
// build the necessary output structures based on the
|
||||
// triangulation data
|
||||
int build( const FGArray& array, const FGTriangle& t );
|
||||
int build( FGConstruct& c, const FGArray& array );
|
||||
|
||||
// write out the fgfs scenery file
|
||||
int write( const string& base, const FGBucket& b );
|
||||
int write( FGConstruct &c );
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
bin_PROGRAMS = construct
|
||||
|
||||
construct_SOURCES = main.cxx construct_types.hxx
|
||||
construct_SOURCES = construct.cxx construct.hxx main.cxx construct_types.hxx
|
||||
|
||||
construct_LDADD = \
|
||||
$(top_builddir)/Tools/Construct/Array/libArray.a \
|
||||
|
|
|
@ -33,37 +33,14 @@
|
|||
#include <GenOutput/genobj.hxx>
|
||||
#include <Triangulate/triangle.hxx>
|
||||
|
||||
|
||||
// load regular grid of elevation data (dem based), return list of
|
||||
// fitted nodes
|
||||
int load_dem(const string& work_base, FGBucket& b, FGArray& array) {
|
||||
point_list result;
|
||||
string base = b.gen_base_path();
|
||||
|
||||
string dem_path = work_base + ".dem" + "/Scenery/" + base
|
||||
+ "/" + b.gen_index_str() + ".dem";
|
||||
cout << "dem_path = " << dem_path << endl;
|
||||
|
||||
if ( ! array.open(dem_path) ) {
|
||||
cout << "ERROR: cannot open " << dem_path << endl;
|
||||
}
|
||||
|
||||
array.parse( b );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// fit dem nodes, return number of fitted nodes
|
||||
int fit_dem(FGArray& array, int error) {
|
||||
return array.fit( error );
|
||||
}
|
||||
#include "construct.hxx"
|
||||
|
||||
|
||||
// do actual scan of directory and loading of files
|
||||
int actual_load_polys( const string& dir, FGBucket& b, FGClipper& clipper ) {
|
||||
int actual_load_polys( const string& dir, FGConstruct& c, FGClipper& clipper ) {
|
||||
int counter = 0;
|
||||
string base = b.gen_base_path();
|
||||
string tile_str = b.gen_index_str();
|
||||
string base = c.get_bucket().gen_base_path();
|
||||
string tile_str = c.get_bucket().gen_index_str();
|
||||
string ext;
|
||||
|
||||
DIR *d;
|
||||
|
@ -102,48 +79,79 @@ int actual_load_polys( const string& dir, FGBucket& b, FGClipper& clipper ) {
|
|||
|
||||
// load all 2d polygons matching the specified base path and clip
|
||||
// against each other to resolve any overlaps
|
||||
int load_polys( const string& work_base, FGBucket& b, FGClipper& clipper) {
|
||||
string base = b.gen_base_path();
|
||||
int load_polys( FGConstruct& c ) {
|
||||
FGClipper clipper;
|
||||
|
||||
string base = c.get_bucket().gen_base_path();
|
||||
int result;
|
||||
|
||||
// initialize clipper
|
||||
clipper.init();
|
||||
|
||||
// load airports
|
||||
string poly_path = work_base + ".apt" + "/Scenery/" + base;
|
||||
string poly_path = c.get_work_base() + ".apt" + "/Scenery/" + base;
|
||||
cout << "poly_path = " << poly_path << endl;
|
||||
result = actual_load_polys( poly_path, b, clipper );
|
||||
result = actual_load_polys( poly_path, c, clipper );
|
||||
cout << " loaded " << result << " polys" << endl;
|
||||
|
||||
// load hydro
|
||||
poly_path = work_base + ".hydro" + "/Scenery/" + base;
|
||||
poly_path = c.get_work_base() + ".hydro" + "/Scenery/" + base;
|
||||
cout << "poly_path = " << poly_path << endl;
|
||||
result = actual_load_polys( poly_path, b, clipper );
|
||||
result = actual_load_polys( poly_path, c, clipper );
|
||||
cout << " loaded " << result << " polys" << endl;
|
||||
|
||||
point2d min, max;
|
||||
min.x = b.get_center_lon() - 0.5 * b.get_width();
|
||||
min.y = b.get_center_lat() - 0.5 * b.get_height();
|
||||
max.x = b.get_center_lon() + 0.5 * b.get_width();
|
||||
max.y = b.get_center_lat() + 0.5 * b.get_height();
|
||||
min.x = c.get_bucket().get_center_lon() - 0.5 * c.get_bucket().get_width();
|
||||
min.y = c.get_bucket().get_center_lat() - 0.5 * c.get_bucket().get_height();
|
||||
max.x = c.get_bucket().get_center_lon() + 0.5 * c.get_bucket().get_width();
|
||||
max.y = c.get_bucket().get_center_lat() + 0.5 * c.get_bucket().get_height();
|
||||
|
||||
// do clipping
|
||||
cout << "clipping polygons" << endl;
|
||||
clipper.clip_all(min, max);
|
||||
|
||||
// update main data repository
|
||||
c.set_clipped_polys( clipper.get_polys_clipped() );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// load regular grid of elevation data (dem based), return list of
|
||||
// fitted nodes
|
||||
int load_dem( FGConstruct& c, FGArray& array) {
|
||||
point_list result;
|
||||
string base = c.get_bucket().gen_base_path();
|
||||
|
||||
string dem_path = c.get_work_base() + ".dem" + "/Scenery/" + base
|
||||
+ "/" + c.get_bucket().gen_index_str() + ".dem";
|
||||
cout << "dem_path = " << dem_path << endl;
|
||||
|
||||
if ( ! array.open(dem_path) ) {
|
||||
cout << "ERROR: cannot open " << dem_path << endl;
|
||||
}
|
||||
|
||||
FGBucket b = c.get_bucket();
|
||||
array.parse( b );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// fit dem nodes, return number of fitted nodes
|
||||
int fit_dem(FGArray& array, int error) {
|
||||
return array.fit( error );
|
||||
}
|
||||
|
||||
|
||||
// triangulate the data for each polygon
|
||||
void do_triangulate( const FGArray& array, const FGClipper& clipper,
|
||||
void do_triangulate( FGConstruct& c, const FGArray& array,
|
||||
FGTriangle& t ) {
|
||||
// first we need to consolidate the points of the DEM fit list and
|
||||
// all the polygons into a more "Triangle" friendly format
|
||||
|
||||
point_list corner_list = array.get_corner_node_list();
|
||||
point_list fit_list = array.get_fit_node_list();
|
||||
FGgpcPolyList gpc_polys = clipper.get_polys_clipped();
|
||||
FGgpcPolyList gpc_polys = c.get_clipped_polys();
|
||||
|
||||
cout << "ready to build node list and polygons" << endl;
|
||||
t.build( corner_list, fit_list, gpc_polys );
|
||||
|
@ -155,37 +163,64 @@ void do_triangulate( const FGArray& array, const FGClipper& clipper,
|
|||
}
|
||||
|
||||
|
||||
// generate the flight gear scenery file
|
||||
void do_output( const string& base, const FGBucket &b, const FGTriangle& t,
|
||||
const FGArray& array, FGGenOutput& output ) {
|
||||
output.build( array, t );
|
||||
output.write( base, b );
|
||||
// build the wgs-84 point list
|
||||
static point_list gen_wgs84_points( FGConstruct& c, const FGArray& array ) {
|
||||
point_list wgs84_nodes;
|
||||
cout << "calculating wgs84 point" << endl;
|
||||
Point3D geod, radians, cart;
|
||||
|
||||
point_list geod_nodes = c.get_tri_nodes().get_node_list();
|
||||
const_point_list_iterator current = geod_nodes.begin();
|
||||
const_point_list_iterator last = geod_nodes.end();
|
||||
|
||||
double real_z;
|
||||
|
||||
for ( ; current != last; ++current ) {
|
||||
geod = *current;
|
||||
|
||||
real_z = array.interpolate_altitude( geod.x() * 3600.0,
|
||||
geod.y() * 3600.0 );
|
||||
|
||||
// convert to radians
|
||||
radians = Point3D( geod.x() * DEG_TO_RAD,
|
||||
geod.y() * DEG_TO_RAD,
|
||||
real_z );
|
||||
|
||||
cart = fgGeodToCart(radians);
|
||||
// cout << cart << endl;
|
||||
wgs84_nodes.push_back(cart);
|
||||
}
|
||||
|
||||
return wgs84_nodes;
|
||||
}
|
||||
|
||||
|
||||
void construct_tile( const string& work_base, const string& output_base,
|
||||
FGBucket& b )
|
||||
{
|
||||
cout << "Construct tile, bucket = " << b << endl;
|
||||
// generate the flight gear scenery file
|
||||
void do_output( FGConstruct& c, const FGTriangle& t,
|
||||
const FGArray& array, FGGenOutput& output ) {
|
||||
output.build( c, array );
|
||||
output.write( c );
|
||||
}
|
||||
|
||||
|
||||
// master construction routine
|
||||
void construct_tile( FGConstruct& c ) {
|
||||
cout << "Construct tile, bucket = " << c.get_bucket() << endl;
|
||||
|
||||
// fit with ever increasing error tolerance until we produce <=
|
||||
// 80% of max nodes. We should really have the sim end handle
|
||||
// arbitrarily complex tiles.
|
||||
|
||||
const int min_nodes = 50;
|
||||
const int max_nodes = (int)(MAX_NODES * 0.8);
|
||||
|
||||
bool acceptable = false;
|
||||
double error = 200.0;
|
||||
int count = 0;
|
||||
|
||||
// load and clip 2d polygon data
|
||||
FGClipper clipper;
|
||||
load_polys( work_base, b, clipper );
|
||||
load_polys( c );
|
||||
|
||||
// load grid of elevation data (dem)
|
||||
FGArray array;
|
||||
load_dem( work_base, b, array );
|
||||
load_dem( c, array );
|
||||
|
||||
FGTriangle t;
|
||||
|
||||
|
@ -195,13 +230,13 @@ void construct_tile( const string& work_base, const string& output_base,
|
|||
array.fit( error );
|
||||
|
||||
// triangulate the data for each polygon
|
||||
do_triangulate( array, clipper, t );
|
||||
do_triangulate( c, array, t );
|
||||
|
||||
acceptable = true;
|
||||
|
||||
count = t.get_out_nodes_size();
|
||||
|
||||
if ( (count < min_nodes) && (error >= 25.0) ) {
|
||||
if ( (count < c.get_min_nodes()) && (error >= 25.0) ) {
|
||||
// reduce error tolerance until number of points exceeds the
|
||||
// minimum threshold
|
||||
cout << "produced too few nodes ..." << endl;
|
||||
|
@ -213,7 +248,7 @@ void construct_tile( const string& work_base, const string& output_base,
|
|||
<< endl;
|
||||
}
|
||||
|
||||
if ( (count > max_nodes) && (error <= 1000.0) ) {
|
||||
if ( (count > c.get_max_nodes()) && (error <= 1000.0) ) {
|
||||
// increase error tolerance until number of points drops below
|
||||
// the maximum threshold
|
||||
cout << "produced too many nodes ..." << endl;
|
||||
|
@ -229,9 +264,16 @@ void construct_tile( const string& work_base, const string& output_base,
|
|||
cout << "finished fit with error = " << error << " node count = "
|
||||
<< count << endl;
|
||||
|
||||
// save the results of the triangulation
|
||||
c.set_tri_nodes( t.get_out_nodes() );
|
||||
c.set_tri_elements( t.get_elelist() );
|
||||
|
||||
// calculate wgs84 (cartesian) form of node list
|
||||
c.set_wgs84_nodes( gen_wgs84_points( c, array ) );
|
||||
|
||||
// generate the output
|
||||
FGGenOutput output;
|
||||
do_output( output_base, b, t, array, output );
|
||||
do_output( c, t, array, output );
|
||||
}
|
||||
|
||||
|
||||
|
@ -245,9 +287,15 @@ main(int argc, char **argv) {
|
|||
exit(-1);
|
||||
}
|
||||
|
||||
string work_base = argv[1];
|
||||
string output_base = argv[2];
|
||||
|
||||
// main construction data management class
|
||||
FGConstruct c;
|
||||
|
||||
c.set_work_base( argv[1] );
|
||||
c.set_output_base( argv[2] );
|
||||
|
||||
c.set_min_nodes( 50 );
|
||||
c.set_max_nodes( (int)(FG_MAX_NODES * 0.8) );
|
||||
|
||||
// lon = -146.248360; lat = 61.133950; // PAVD (Valdez, AK)
|
||||
// lon = -110.664244; lat = 33.352890; // P13
|
||||
// lon = -93.211389; lat = 45.145000; // KANE
|
||||
|
@ -277,11 +325,13 @@ main(int argc, char **argv) {
|
|||
// FGBucket b_omit(-1L);
|
||||
// FGBucket b(1122504L);
|
||||
FGBucket b(-146.248360, 61.133950);
|
||||
construct_tile( work_base, output_base, b );
|
||||
c.set_bucket( b );
|
||||
construct_tile( c );
|
||||
exit(0);
|
||||
|
||||
|
||||
if ( b_min == b_max ) {
|
||||
construct_tile( work_base, output_base, b_min );
|
||||
c.set_bucket( b_min );
|
||||
construct_tile( c );
|
||||
} else {
|
||||
FGBucket b_cur;
|
||||
int dx, dy, i, j;
|
||||
|
@ -299,7 +349,8 @@ main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
if ( do_tile ) {
|
||||
construct_tile( work_base, output_base, b_cur );
|
||||
c.set_bucket( b_cur );
|
||||
construct_tile( c );
|
||||
} else {
|
||||
cout << "skipping " << b_cur << endl;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ SUBDIRS = \
|
|||
Clipper \
|
||||
Combine \
|
||||
GenOutput \
|
||||
Match \
|
||||
Triangulate \
|
||||
Main
|
||||
|
||||
# Match
|
||||
|
|
|
@ -153,8 +153,8 @@ void FGPolygon::calc_point_inside( const int contour,
|
|||
for ( int i = 0; i < (int)poly.size(); ++i ) {
|
||||
cout << "contour = " << i << " size = " << poly[i].size() << endl;
|
||||
for ( int j = 0; j < (int)(poly[i].size() - 1); ++j ) {
|
||||
cout << " p1 = " << poly[i][j] << " p2 = "
|
||||
<< poly[i][j+1] << endl;
|
||||
// cout << " p1 = " << poly[i][j] << " p2 = "
|
||||
// << poly[i][j+1] << endl;
|
||||
p1 = trinodes.get_node( poly[i][j] );
|
||||
p2 = trinodes.get_node( poly[i][j+1] );
|
||||
|
||||
|
@ -166,8 +166,8 @@ void FGPolygon::calc_point_inside( const int contour,
|
|||
}
|
||||
}
|
||||
}
|
||||
cout << " p1 = " << poly[i][0] << " p2 = "
|
||||
<< poly[i][poly[i].size() - 1] << endl;
|
||||
// cout << " p1 = " << poly[i][0] << " p2 = "
|
||||
// << poly[i][poly[i].size() - 1] << endl;
|
||||
p1 = trinodes.get_node( poly[i][0] );
|
||||
p2 = trinodes.get_node( poly[i][poly[i].size() - 1] );
|
||||
if ( intersects(p1, p2, m.x(), &result) ) {
|
||||
|
|
|
@ -45,7 +45,7 @@ FGTriangle::build( const point_list& corner_list,
|
|||
int index;
|
||||
|
||||
in_nodes.clear();
|
||||
trisegs.clear();
|
||||
in_segs.clear();
|
||||
|
||||
// Point3D junkp;
|
||||
// int junkc = 0;
|
||||
|
@ -93,7 +93,7 @@ FGTriangle::build( const point_list& corner_list,
|
|||
|
||||
int j;
|
||||
|
||||
for ( j = 0; j < gpc_poly->num_contours; j++ ) {
|
||||
for ( j = 0; j < gpc_poly->num_contours; ++j ) {
|
||||
cout << " processing contour = " << j << ", nodes = "
|
||||
<< gpc_poly->contour[j].num_vertices << ", hole = "
|
||||
<< gpc_poly->hole[j] << endl;
|
||||
|
@ -109,7 +109,7 @@ FGTriangle::build( const point_list& corner_list,
|
|||
// junkp = in_nodes.get_node( index );
|
||||
// fprintf(junkfp, "%.4f %.4f\n", junkp.x(), junkp.y());
|
||||
poly.add_node(j, index);
|
||||
cout << " - " << index << endl;
|
||||
// cout << " - " << index << endl;
|
||||
}
|
||||
// fprintf(junkfp, "%.4f %.4f\n",
|
||||
// gpc_poly->contour[j].vertex[0].x,
|
||||
|
@ -123,7 +123,8 @@ FGTriangle::build( const point_list& corner_list,
|
|||
poly.calc_point_inside( j, in_nodes );
|
||||
}
|
||||
|
||||
// temporary ... write out/hole polygon info for debugging
|
||||
#if 0
|
||||
// temporary ... write out hole/polygon info for debugging
|
||||
for ( j = 0; j < (int)poly.contours(); ++j ) {
|
||||
char pname[256];
|
||||
sprintf(pname, "poly%02d-%02d-%02d", i, debug_counter, j);
|
||||
|
@ -147,6 +148,7 @@ FGTriangle::build( const point_list& corner_list,
|
|||
fprintf( fh, "%.6f %.6f\n", point.x(), point.y() );
|
||||
fclose(fh);
|
||||
}
|
||||
#endif
|
||||
|
||||
polylist[i].push_back( poly );
|
||||
|
||||
|
@ -188,12 +190,12 @@ FGTriangle::build( const point_list& corner_list,
|
|||
i1 = poly.get_pt_index( j, k );
|
||||
i2 = poly.get_pt_index( j, k + 1 );
|
||||
// calc_line_params(i1, i2, &m, &b);
|
||||
trisegs.unique_divide_and_add( node_list, FGTriSeg(i1, i2) );
|
||||
in_segs.unique_divide_and_add( node_list, FGTriSeg(i1, i2) );
|
||||
}
|
||||
i1 = poly.get_pt_index( j, 0 );
|
||||
i2 = poly.get_pt_index( j, poly.contour_size(j) - 1 );
|
||||
// calc_line_params(i1, i2, &m, &b);
|
||||
trisegs.unique_divide_and_add( node_list, FGTriSeg(i1, i2) );
|
||||
in_segs.unique_divide_and_add( node_list, FGTriSeg(i1, i2) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -206,7 +208,7 @@ static void write_out_data(struct triangulateio *out) {
|
|||
FILE *node = fopen("tile.node", "w");
|
||||
fprintf(node, "%d 2 %d 0\n",
|
||||
out->numberofpoints, out->numberofpointattributes);
|
||||
for (int i = 0; i < out->numberofpoints; i++) {
|
||||
for (int i = 0; i < out->numberofpoints; ++i) {
|
||||
fprintf(node, "%d %.6f %.6f %.2f\n",
|
||||
i, out->pointlist[2*i], out->pointlist[2*i + 1], 0.0);
|
||||
}
|
||||
|
@ -214,12 +216,12 @@ static void write_out_data(struct triangulateio *out) {
|
|||
|
||||
FILE *ele = fopen("tile.ele", "w");
|
||||
fprintf(ele, "%d 3 0\n", out->numberoftriangles);
|
||||
for (int i = 0; i < out->numberoftriangles; i++) {
|
||||
for (int i = 0; i < out->numberoftriangles; ++i) {
|
||||
fprintf(ele, "%d ", i);
|
||||
for (int j = 0; j < out->numberofcorners; j++) {
|
||||
for (int j = 0; j < out->numberofcorners; ++j) {
|
||||
fprintf(ele, "%d ", out->trianglelist[i * out->numberofcorners + j]);
|
||||
}
|
||||
for (int j = 0; j < out->numberoftriangleattributes; j++) {
|
||||
for (int j = 0; j < out->numberoftriangleattributes; ++j) {
|
||||
fprintf(ele, "%.6f ",
|
||||
out->triangleattributelist[i
|
||||
* out->numberoftriangleattributes
|
||||
|
@ -238,12 +240,12 @@ static void write_out_data(struct triangulateio *out) {
|
|||
i, out->segmentlist[2*i], out->segmentlist[2*i + 1]);
|
||||
}
|
||||
fprintf(fp, "%d\n", out->numberofholes);
|
||||
for (int i = 0; i < out->numberofholes; i++) {
|
||||
for (int i = 0; i < out->numberofholes; ++i) {
|
||||
fprintf(fp, "%d %.6f %.6f\n",
|
||||
i, out->holelist[2*i], out->holelist[2*i + 1]);
|
||||
}
|
||||
fprintf(fp, "%d\n", out->numberofregions);
|
||||
for (int i = 0; i < out->numberofregions; i++) {
|
||||
for (int i = 0; i < out->numberofregions; ++i) {
|
||||
fprintf(fp, "%d %.6f %.6f %.6f\n",
|
||||
i, out->regionlist[4*i], out->regionlist[4*i + 1],
|
||||
out->regionlist[4*i + 2]);
|
||||
|
@ -277,12 +279,12 @@ int FGTriangle::run_triangulate() {
|
|||
in.pointattributelist = (REAL *) malloc(in.numberofpoints *
|
||||
in.numberofpointattributes *
|
||||
sizeof(REAL));
|
||||
for ( int i = 0; i < in.numberofpoints * in.numberofpointattributes; i++) {
|
||||
for ( int i = 0; i < in.numberofpoints * in.numberofpointattributes; ++i) {
|
||||
in.pointattributelist[i] = 0.0;
|
||||
}
|
||||
|
||||
in.pointmarkerlist = (int *) malloc(in.numberofpoints * sizeof(int));
|
||||
for ( int i = 0; i < in.numberofpoints; i++) {
|
||||
for ( int i = 0; i < in.numberofpoints; ++i) {
|
||||
in.pointmarkerlist[i] = 0;
|
||||
}
|
||||
|
||||
|
@ -290,7 +292,7 @@ int FGTriangle::run_triangulate() {
|
|||
in.numberoftriangles = 0;
|
||||
|
||||
// segment list
|
||||
triseg_list seg_list = trisegs.get_seg_list();
|
||||
triseg_list seg_list = in_segs.get_seg_list();
|
||||
in.numberofsegments = seg_list.size();
|
||||
in.segmentlist = (int *) malloc(in.numberofsegments * 2 * sizeof(int));
|
||||
in.segmentmarkerlist = (int *) NULL;
|
||||
|
@ -314,7 +316,7 @@ int FGTriangle::run_triangulate() {
|
|||
counter = 0;
|
||||
for ( ; h_current != h_last; ++h_current ) {
|
||||
poly = *h_current;
|
||||
for ( int j = 0; j < poly.contours(); j++ ) {
|
||||
for ( int j = 0; j < poly.contours(); ++j ) {
|
||||
p = poly.get_point_inside( j );
|
||||
in.holelist[counter++] = p.x();
|
||||
in.holelist[counter++] = p.y();
|
||||
|
@ -329,7 +331,7 @@ int FGTriangle::run_triangulate() {
|
|||
h_last = polylist[i].end();
|
||||
for ( ; h_current != h_last; ++h_current ) {
|
||||
poly = *h_current;
|
||||
for ( int j = 0; j < poly.contours(); j++ ) {
|
||||
for ( int j = 0; j < poly.contours(); ++j ) {
|
||||
if ( ! poly.get_hole_flag( j ) ) {
|
||||
++in.numberofregions;
|
||||
}
|
||||
|
@ -345,7 +347,7 @@ int FGTriangle::run_triangulate() {
|
|||
h_last = polylist[(int)i].end();
|
||||
for ( ; h_current != h_last; ++h_current ) {
|
||||
poly = *h_current;
|
||||
for ( int j = 0; j < poly.contours(); j++ ) {
|
||||
for ( int j = 0; j < poly.contours(); ++j ) {
|
||||
if ( ! poly.get_hole_flag( j ) ) {
|
||||
p = poly.get_point_inside( j );
|
||||
cout << "Region point = " << p << endl;
|
||||
|
@ -404,17 +406,24 @@ int FGTriangle::run_triangulate() {
|
|||
|
||||
// nodes
|
||||
out_nodes.clear();
|
||||
for ( int i = 0; i < out.numberofpoints; i++ ) {
|
||||
for ( int i = 0; i < out.numberofpoints; ++i ) {
|
||||
Point3D p( out.pointlist[2*i], out.pointlist[2*i + 1], 0.0 );
|
||||
// cout << "point = " << p << endl;
|
||||
out_nodes.simple_add( p );
|
||||
}
|
||||
|
||||
// segments
|
||||
out_segs.clear();
|
||||
for ( int i = 0; i < out.numberofsegments; ++i ) {
|
||||
out_segs.unique_add( FGTriSeg( out.segmentlist[2*i],
|
||||
out.segmentlist[2*i+1] ) );
|
||||
}
|
||||
|
||||
// triangles
|
||||
elelist.clear();
|
||||
int n1, n2, n3;
|
||||
double attribute;
|
||||
for ( int i = 0; i < out.numberoftriangles; i++ ) {
|
||||
for ( int i = 0; i < out.numberoftriangles; ++i ) {
|
||||
n1 = out.trianglelist[i * 3];
|
||||
n2 = out.trianglelist[i * 3 + 1];
|
||||
n3 = out.trianglelist[i * 3 + 2];
|
||||
|
|
|
@ -57,7 +57,8 @@ private:
|
|||
FGTriNodes out_nodes;
|
||||
|
||||
// list of segments
|
||||
FGTriSegments trisegs;
|
||||
FGTriSegments in_segs;
|
||||
FGTriSegments out_segs;
|
||||
|
||||
// polygon list
|
||||
poly_list polylist[FG_MAX_AREA_TYPES];
|
||||
|
|
Loading…
Add table
Reference in a new issue