Checkpoint 2
- fixed tile matching using add_intermediate_nodes - source code rearrangement phase 1 - remove a lot of libraries that are not used by other apps - move some of the Buildtiles libraries that are used by other apps (and libs) into terragear lib directory - debug message overhal - to show some progress. TODO - not implemented yet - caculate face nodes and save in superpoly (where the faces are stored) - calculate node normals, and store in tg_nodes (where the nodes are stored) TODO - bugs - find_intermediate_nodes isn't working for a lot of roads - still many t-juntions making visible gaps - flatten ocean nosed is also creating gaps - there's a grey poly on madeira - need to investigate
This commit is contained in:
parent
e6ac493395
commit
ffc9db1b82
35 changed files with 1799 additions and 3742 deletions
|
@ -50,13 +50,13 @@
|
|||
#include <Geometry/poly_support.hxx>
|
||||
#include <Geometry/poly_extra.hxx>
|
||||
#include <Geometry/trinodes.hxx>
|
||||
#include <Geometry/trieles.hxx>
|
||||
#include <Output/output.hxx>
|
||||
#include <Polygon/chop.hxx>
|
||||
#include <Polygon/index.hxx>
|
||||
#include <Polygon/polygon.hxx>
|
||||
#include <Polygon/superpoly.hxx>
|
||||
#include <Polygon/texparams.hxx>
|
||||
#include <Triangulate/trieles.hxx>
|
||||
|
||||
#include "apt_surface.hxx"
|
||||
#include "convex_hull.hxx"
|
||||
|
|
|
@ -36,7 +36,7 @@ using std::string;
|
|||
struct sections
|
||||
{
|
||||
const char* tex;
|
||||
int size;
|
||||
double size;
|
||||
};
|
||||
|
||||
// UK Precision runway sections from after the designation number
|
||||
|
|
|
@ -4,9 +4,6 @@ include_directories(${PROJECT_SOURCE_DIR}/src/Lib)
|
|||
include_directories(${PROJECT_SOURCE_DIR}/src/BuildTiles)
|
||||
|
||||
add_subdirectory(Osgb36)
|
||||
add_subdirectory(Parallel)
|
||||
add_subdirectory(Triangulate)
|
||||
add_subdirectory(Clipper)
|
||||
add_subdirectory(GenOutput)
|
||||
add_subdirectory(Parallel)
|
||||
add_subdirectory(Match)
|
||||
add_subdirectory(Main)
|
||||
|
|
1
src/BuildTiles/Clipper/.gitignore
vendored
1
src/BuildTiles/Clipper/.gitignore
vendored
|
@ -1 +0,0 @@
|
|||
testclipper
|
|
@ -1,15 +0,0 @@
|
|||
|
||||
|
||||
add_library(Clipper STATIC
|
||||
clipper.cxx clipper.hxx priorities.cxx priorities.hxx
|
||||
)
|
||||
|
||||
add_executable(testclipper testclipper.cxx)
|
||||
|
||||
target_link_libraries(testclipper
|
||||
Clipper Osgb36 Triangulate Polygon Geometry
|
||||
${SIMGEAR_CORE_LIBRARIES}
|
||||
${SIMGEAR_CORE_LIBRARY_DEPENDENCIES}
|
||||
${GPC_LIBRARY})
|
||||
|
||||
INSTALL(FILES default_priorities.txt DESTINATION ${PKGDATADIR} )
|
|
@ -1,567 +0,0 @@
|
|||
// clipper.cxx -- top level routines to take a series of arbitrary areas and
|
||||
// produce a tight fitting puzzle pieces that combine to make a
|
||||
// tile
|
||||
//
|
||||
// Written by Curtis Olson, started February 1999.
|
||||
//
|
||||
// Copyright (C) 1999 Curtis L. Olson - http://www.flightgear.org/~curt
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
// $Id: clipper.cxx,v 1.33 2006-11-29 22:19:33 curt Exp $
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
#include <simgear/constants.h>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/misc/sgstream.hxx>
|
||||
|
||||
#include <Clipper/priorities.hxx>
|
||||
#include <Osgb36/osgb36.hxx>
|
||||
|
||||
#include "clipper.hxx"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
using std::string;
|
||||
|
||||
#define MASK_CLIP 1
|
||||
|
||||
|
||||
// Constructor.
|
||||
TGClipper::TGClipper():
|
||||
nudge(0.0),
|
||||
m_ignore_landmass(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// Destructor.
|
||||
TGClipper::~TGClipper() {
|
||||
}
|
||||
|
||||
|
||||
// Initialize the clipper (empty all the polygon buckets.)
|
||||
bool TGClipper::init() {
|
||||
for ( int i = 0; i < TG_MAX_AREA_TYPES; ++i ) {
|
||||
polys_in.superpolys[i].clear();
|
||||
}
|
||||
nodes.clear();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Load a polygon definition file.
|
||||
bool TGClipper::load_polys(const string& path) {
|
||||
bool poly3d = false;
|
||||
string first_line;
|
||||
string poly_name;
|
||||
AreaType poly_type;
|
||||
int contours, count, i, j;
|
||||
int hole_flag;
|
||||
double startx, starty, startz, x, y, z, lastx, lasty, lastz;
|
||||
|
||||
SG_LOG( SG_CLIPPER, SG_INFO, "Loading " << path << " ..." );
|
||||
|
||||
sg_gzifstream in( path );
|
||||
|
||||
if ( !in ) {
|
||||
SG_LOG( SG_CLIPPER, SG_ALERT, "Cannot open file: " << path );
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
TGPolygon poly;
|
||||
|
||||
Point3D p;
|
||||
// (this could break things, why is it here) in >> skipcomment;
|
||||
while ( !in.eof() ) {
|
||||
in >> first_line;
|
||||
if ( first_line == "#2D" ) {
|
||||
poly3d = false;
|
||||
in >> poly_name;
|
||||
} else if ( first_line == "#3D" ) {
|
||||
poly3d = true;
|
||||
in >> poly_name;
|
||||
} else {
|
||||
// support old format (default to 2d)
|
||||
poly3d = false;
|
||||
poly_name = first_line;
|
||||
}
|
||||
SG_LOG( SG_CLIPPER, SG_INFO, "poly name = " << poly_name);
|
||||
poly_type = get_area_type( poly_name );
|
||||
SG_LOG( SG_CLIPPER, SG_INFO, "poly type (int) = " << (int)poly_type);
|
||||
in >> contours;
|
||||
SG_LOG( SG_CLIPPER, SG_INFO, "num contours = " << contours);
|
||||
|
||||
poly.erase();
|
||||
|
||||
for ( i = 0; i < contours; ++i ) {
|
||||
in >> count;
|
||||
|
||||
if ( count < 3 ) {
|
||||
SG_LOG( SG_CLIPPER, SG_ALERT, "Polygon with less than 3 data points." );
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
in >> hole_flag;
|
||||
|
||||
in >> startx;
|
||||
in >> starty;
|
||||
if ( poly3d ) {
|
||||
in >> startz;
|
||||
} else {
|
||||
startz = -9999.0;
|
||||
}
|
||||
p = Point3D(startx+nudge, starty+nudge, startz);
|
||||
poly.add_node( i, p );
|
||||
|
||||
if ( poly3d ) {
|
||||
nodes.unique_add_fixed_elevation( p );
|
||||
} else {
|
||||
nodes.unique_add( p );
|
||||
}
|
||||
|
||||
for ( j = 1; j < count - 1; ++j ) {
|
||||
in >> x;
|
||||
in >> y;
|
||||
if ( poly3d ) {
|
||||
in >> z;
|
||||
} else {
|
||||
z = -9999.0;
|
||||
}
|
||||
p = Point3D( x+nudge, y+nudge, z );
|
||||
poly.add_node( i, p );
|
||||
if ( poly3d ) {
|
||||
nodes.unique_add_fixed_elevation( p );
|
||||
} else {
|
||||
nodes.unique_add( p );
|
||||
}
|
||||
}
|
||||
|
||||
in >> lastx;
|
||||
in >> lasty;
|
||||
if ( poly3d ) {
|
||||
in >> lastz;
|
||||
} else {
|
||||
lastz = -9999.0;
|
||||
}
|
||||
|
||||
if ( (fabs(startx - lastx) < SG_EPSILON) &&
|
||||
(fabs(starty - lasty) < SG_EPSILON) &&
|
||||
(fabs(startz - lastz) < SG_EPSILON) ) {
|
||||
// last point same as first, discard
|
||||
} else {
|
||||
p = Point3D( lastx+nudge, lasty+nudge, lastz );
|
||||
poly.add_node( i, p );
|
||||
if ( poly3d ) {
|
||||
nodes.unique_add_fixed_elevation( p );
|
||||
} else {
|
||||
nodes.unique_add( p );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int area = (int)poly_type;
|
||||
string material = get_area_name( area );
|
||||
|
||||
add_poly(area, poly, material);
|
||||
|
||||
in >> skipcomment;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Load a polygon definition file containing osgb36 Eastings and Northings
|
||||
// and convert them to WGS84 Latitude and Longitude
|
||||
bool TGClipper::load_osgb36_polys(const string& path) {
|
||||
string poly_name;
|
||||
AreaType poly_type;
|
||||
int contours, count, i, j;
|
||||
int hole_flag;
|
||||
double startx, starty, x, y, lastx, lasty;
|
||||
|
||||
SG_LOG( SG_CLIPPER, SG_INFO, "Loading " << path << " ..." );
|
||||
|
||||
sg_gzifstream in( path );
|
||||
|
||||
if ( !in ) {
|
||||
SG_LOG( SG_CLIPPER, SG_ALERT, "Cannot open file: " << path );
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
TGPolygon poly;
|
||||
|
||||
Point3D p;
|
||||
Point3D OSRef;
|
||||
in >> skipcomment;
|
||||
while ( !in.eof() ) {
|
||||
in >> poly_name;
|
||||
SG_LOG( SG_CLIPPER, SG_INFO, "poly name = " << poly_name);
|
||||
poly_type = get_area_type( poly_name );
|
||||
SG_LOG( SG_CLIPPER, SG_INFO, "poly type (int) = " << (int)poly_type);
|
||||
in >> contours;
|
||||
SG_LOG( SG_CLIPPER, SG_INFO, "num contours = " << contours);
|
||||
|
||||
poly.erase();
|
||||
|
||||
for ( i = 0; i < contours; ++i ) {
|
||||
in >> count;
|
||||
|
||||
if ( count < 3 ) {
|
||||
SG_LOG( SG_CLIPPER, SG_ALERT, "Polygon with less than 3 data points." );
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
in >> hole_flag;
|
||||
|
||||
in >> startx;
|
||||
in >> starty;
|
||||
OSRef = Point3D(startx, starty, -9999.0);
|
||||
|
||||
//Convert from OSGB36 Eastings/Northings to WGS84 Lat/Lon
|
||||
//Note that startx and starty themselves must not be altered since we compare them with unaltered lastx and lasty later
|
||||
p = OSGB36ToWGS84(OSRef);
|
||||
|
||||
poly.add_node( i, p );
|
||||
nodes.unique_add( p );
|
||||
|
||||
SG_LOG( SG_CLIPPER, SG_BULK, "0 = " << startx << ", " << starty );
|
||||
|
||||
for ( j = 1; j < count - 1; ++j ) {
|
||||
in >> x;
|
||||
in >> y;
|
||||
OSRef = Point3D( x, y, -9999.0 );
|
||||
p = OSGB36ToWGS84(OSRef);
|
||||
|
||||
poly.add_node( i, p );
|
||||
nodes.unique_add( p );
|
||||
SG_LOG( SG_CLIPPER, SG_BULK, j << " = " << x << ", " << y );
|
||||
}
|
||||
|
||||
in >> lastx;
|
||||
in >> lasty;
|
||||
|
||||
if ( (fabs(startx - lastx) < SG_EPSILON) &&
|
||||
(fabs(starty - lasty) < SG_EPSILON) ) {
|
||||
// last point same as first, discard
|
||||
} else {
|
||||
OSRef = Point3D( lastx, lasty, -9999.0 );
|
||||
p = OSGB36ToWGS84(OSRef);
|
||||
|
||||
poly.add_node( i, p );
|
||||
nodes.unique_add( p );
|
||||
SG_LOG( SG_CLIPPER, SG_BULK, count - 1 << " = " << lastx << ", " << lasty );
|
||||
}
|
||||
}
|
||||
|
||||
int area = (int)poly_type;
|
||||
string material = get_area_name( area );
|
||||
|
||||
add_poly(area, poly, material);
|
||||
|
||||
in >> skipcomment;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Add a polygon to the clipper.
|
||||
void TGClipper::add_poly( int area, const TGPolygon &poly, string material )
|
||||
{
|
||||
TGSuperPoly sp;
|
||||
|
||||
if ( area < TG_MAX_AREA_TYPES ) {
|
||||
sp.set_poly( poly );
|
||||
sp.set_material( material );
|
||||
|
||||
polys_in.superpolys[area].push_back(sp);
|
||||
} else {
|
||||
SG_LOG( SG_CLIPPER, SG_ALERT, "Polygon type out of range = " << area);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Move slivers from in polygon to out polygon.
|
||||
void TGClipper::move_slivers( TGPolygon& in, TGPolygon& out ) {
|
||||
// traverse each contour of the polygon and attempt to identify
|
||||
// likely slivers
|
||||
int i;
|
||||
|
||||
out.erase();
|
||||
|
||||
double angle_cutoff = 10.0 * SGD_DEGREES_TO_RADIANS;
|
||||
double area_cutoff = 0.00000008;
|
||||
double min_angle;
|
||||
double area;
|
||||
|
||||
point_list contour;
|
||||
int hole_flag;
|
||||
|
||||
// process contours in reverse order so deleting a contour doesn't
|
||||
// foul up our sequence
|
||||
for ( i = in.contours() - 1; i >= 0; --i ) {
|
||||
min_angle = in.minangle_contour( i );
|
||||
area = in.area_contour( i );
|
||||
|
||||
if ( ((min_angle < angle_cutoff) && (area < area_cutoff)) ||
|
||||
( area < area_cutoff / 10.0) ) {
|
||||
// cout << " WE THINK IT'S A SLIVER!" << endl;
|
||||
|
||||
// check if this is a hole
|
||||
hole_flag = in.get_hole_flag( i );
|
||||
|
||||
if ( hole_flag ) {
|
||||
// just delete/eliminate/remove sliver holes
|
||||
// cout << "just deleting a sliver hole" << endl;
|
||||
in.delete_contour( i );
|
||||
} else {
|
||||
// move sliver contour to out polygon
|
||||
contour = in.get_contour( i );
|
||||
in.delete_contour( i );
|
||||
out.add_contour( contour, hole_flag );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Attempt to merge slivers into a list of polygons.
|
||||
//
|
||||
// For each sliver contour, see if a union with another polygon yields
|
||||
// a polygon with no increased contours (i.e. the sliver is adjacent
|
||||
// and can be merged.) If so, replace the clipped polygon with the
|
||||
// new polygon that has the sliver merged in.
|
||||
void TGClipper::merge_slivers( TGPolyList& clipped, TGPolygon& slivers ) {
|
||||
TGPolygon poly, result, sliver;
|
||||
point_list contour;
|
||||
int original_contours, result_contours;
|
||||
bool done;
|
||||
int area, i, j;
|
||||
|
||||
for ( i = 0; i < slivers.contours(); ++i ) {
|
||||
// cout << "Merging sliver = " << i << endl;
|
||||
|
||||
// make the sliver polygon
|
||||
contour = slivers.get_contour( i );
|
||||
sliver.erase();
|
||||
sliver.add_contour( contour, 0 );
|
||||
done = false;
|
||||
|
||||
for ( area = 0; area < TG_MAX_AREA_TYPES && !done; ++area ) {
|
||||
|
||||
if ( is_hole_area( area ) ) {
|
||||
// don't merge a non-hole sliver in with a hole
|
||||
continue;
|
||||
}
|
||||
|
||||
// cout << " testing area = " << area << " with "
|
||||
// << clipped.polys[area].size() << " polys" << endl;
|
||||
for ( j = 0; j < (int)clipped.superpolys[area].size() && !done; ++j ) {
|
||||
// cout << " polygon = " << j << endl;
|
||||
poly = clipped.superpolys[area][j].get_poly();
|
||||
original_contours = poly.contours();
|
||||
result = tgPolygonUnion( poly, sliver );
|
||||
result_contours = result.contours();
|
||||
|
||||
if ( original_contours == result_contours ) {
|
||||
// cout << " FOUND a poly to merge the sliver with" << endl;
|
||||
clipped.superpolys[area][j].set_poly( result );
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !done ) {
|
||||
// cout << "no suitable polys found for sliver merge" << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Clip all the polygons against each other in a priority scheme based
|
||||
// on order of the polygon type in the polygon type enum.
|
||||
bool TGClipper::clip_all(const point2d& min, const point2d& max) {
|
||||
TGPolygon accum, tmp;
|
||||
TGPolygon slivers, remains;
|
||||
int i, j;
|
||||
Point3D p;
|
||||
|
||||
SG_LOG( SG_CLIPPER, SG_INFO, "Running master clipper" );
|
||||
SG_LOG( SG_CLIPPER, SG_INFO, " (" << min.x << "," << min.y << ") (" << max.x << "," << max.y << ")" );
|
||||
|
||||
accum.erase();
|
||||
|
||||
// set up clipping tile : and remember to add the nodes!
|
||||
polys_in.safety_base.erase();
|
||||
|
||||
p = Point3D(min.x, min.y, -9999.0);
|
||||
polys_in.safety_base.add_node( 0, p );
|
||||
nodes.unique_add( p );
|
||||
|
||||
p = Point3D(max.x, min.y, -9999.0);
|
||||
polys_in.safety_base.add_node( 0, p );
|
||||
nodes.unique_add( p );
|
||||
|
||||
p = Point3D(max.x, max.y, -9999.0);
|
||||
polys_in.safety_base.add_node( 0, p );
|
||||
nodes.unique_add( p );
|
||||
|
||||
p = Point3D(min.x, max.y, -9999.0);
|
||||
polys_in.safety_base.add_node( 0, p );
|
||||
nodes.unique_add( p );
|
||||
|
||||
// set up land mask, we clip most things to this since it is our
|
||||
// best representation of land vs. ocean. If we have other less
|
||||
// accurate data that spills out into the ocean, we want to just
|
||||
// clip it.
|
||||
// also set up a mask for all water and islands
|
||||
TGPolygon land_mask, water_mask, island_mask;
|
||||
land_mask.erase();
|
||||
water_mask.erase();
|
||||
island_mask.erase();
|
||||
for ( i = 0; i < TG_MAX_AREA_TYPES; i++ ) {
|
||||
if ( is_landmass_area( i ) && !m_ignore_landmass ) {
|
||||
for ( unsigned int j = 0; j < polys_in.superpolys[i].size(); ++j ) {
|
||||
land_mask = tgPolygonUnion( land_mask, polys_in.superpolys[i][j].get_poly() );
|
||||
}
|
||||
} else if ( is_water_area( i ) ) {
|
||||
for (unsigned int j = 0; j < polys_in.superpolys[i].size(); j++) {
|
||||
water_mask = tgPolygonUnion( water_mask, polys_in.superpolys[i][j].get_poly() );
|
||||
}
|
||||
} else if ( is_island_area( i ) ) {
|
||||
for (unsigned int j = 0; j < polys_in.superpolys[i].size(); j++) {
|
||||
island_mask = tgPolygonUnion( island_mask, polys_in.superpolys[i][j].get_poly() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// process polygons in priority order
|
||||
for ( i = 0; i < TG_MAX_AREA_TYPES; ++i ) {
|
||||
SG_LOG( SG_CLIPPER, SG_INFO, "num polys of type (" << i << ") = " << polys_in.superpolys[i].size() );
|
||||
for( j = 0; j < (int)polys_in.superpolys[i].size(); ++j ) {
|
||||
TGPolygon current = polys_in.superpolys[i][j].get_poly();
|
||||
SG_LOG( SG_CLIPPER, SG_INFO, get_area_name( (AreaType)i ) << " = " << current.contours() );
|
||||
|
||||
tmp = current;
|
||||
|
||||
// if not a hole, clip the area to the land_mask
|
||||
if ( !m_ignore_landmass && !is_hole_area( i ) ) {
|
||||
tmp = tgPolygonInt( tmp, land_mask );
|
||||
}
|
||||
|
||||
// Airport areas are limited to existing land mass and
|
||||
// never override water.
|
||||
//
|
||||
// 9/26/2005 - CLO: We are going to add the ability to
|
||||
// manually define airport areas when the default area
|
||||
// isn't sufficient. It is clear that it is impossible to
|
||||
// auto-generate correct airport areas in all cases. For
|
||||
// now we default to topologically continuous scenery and
|
||||
// wait for people to submit manual fixes.
|
||||
//
|
||||
// if ( i == AirportArea ) {
|
||||
// tmp = tgPolygonInt( tmp, land_mask );
|
||||
// tmp = tgPolygonDiff( tmp, water_mask );
|
||||
// }
|
||||
|
||||
// if a water area, cut out potential islands
|
||||
if ( is_water_area( i ) ) {
|
||||
// clip against island mask
|
||||
tmp = tgPolygonDiff( tmp, island_mask );
|
||||
}
|
||||
|
||||
TGPolygon result_union, result_diff;
|
||||
|
||||
if ( accum.contours() == 0 ) {
|
||||
result_diff = tmp;
|
||||
result_union = tmp;
|
||||
} else {
|
||||
result_diff = tgPolygonDiff( tmp, accum);
|
||||
result_union = tgPolygonUnion( tmp, accum);
|
||||
}
|
||||
|
||||
// only add to output list if the clip left us with a polygon
|
||||
if ( result_diff.contours() > 0 ) {
|
||||
// move slivers from result_diff polygon to slivers polygon
|
||||
move_slivers(result_diff, slivers);
|
||||
|
||||
// merge any slivers with previously clipped
|
||||
// neighboring polygons
|
||||
if ( slivers.contours() > 0 ) {
|
||||
merge_slivers(polys_clipped, slivers);
|
||||
}
|
||||
|
||||
// add the sliverless result polygon (from after the
|
||||
// move_slivers) to the clipped polys list
|
||||
if ( result_diff.contours() > 0 ) {
|
||||
TGSuperPoly sp;
|
||||
string material = get_area_name( (AreaType)i );
|
||||
|
||||
sp.set_material( material );
|
||||
sp.set_poly( result_diff );
|
||||
polys_clipped.superpolys[i].push_back( sp );
|
||||
}
|
||||
}
|
||||
accum = result_union;
|
||||
}
|
||||
}
|
||||
|
||||
// finally, what ever is left over goes to ocean
|
||||
|
||||
// clip to accum against original base tile
|
||||
// remains = new gpc_polygon;
|
||||
// remains->num_contours = 0;
|
||||
// remains->contour = NULL;
|
||||
remains = tgPolygonDiff( polys_in.safety_base, accum );
|
||||
|
||||
if ( remains.contours() > 0 ) {
|
||||
// cout << "remains contours = " << remains.contours() << endl;
|
||||
// move slivers from remains polygon to slivers polygon
|
||||
move_slivers(remains, slivers);
|
||||
// cout << " After sliver move:" << endl;
|
||||
// cout << " remains = " << remains.contours() << endl;
|
||||
// cout << " slivers = " << slivers.contours() << endl;
|
||||
|
||||
// merge any slivers with previously clipped
|
||||
// neighboring polygons
|
||||
if ( slivers.contours() > 0 ) {
|
||||
merge_slivers(polys_clipped, slivers);
|
||||
}
|
||||
|
||||
if ( remains.contours() > 0 ) {
|
||||
TGSuperPoly sp;
|
||||
string material = get_area_name(get_sliver_target_area_type());
|
||||
|
||||
sp.set_material( material );
|
||||
sp.set_poly( remains );
|
||||
|
||||
polys_clipped.superpolys[(int)get_sliver_target_area_type()].push_back(sp);
|
||||
}
|
||||
}
|
||||
|
||||
SG_LOG( SG_CLIPPER, SG_INFO, " master clipper finished." );
|
||||
|
||||
return true;
|
||||
}
|
|
@ -1,127 +0,0 @@
|
|||
// clipper.hxx -- top level routines to take a series of arbitrary areas and
|
||||
// produce a tight fitting puzzle pieces that combine to make a
|
||||
// tile
|
||||
//
|
||||
// Written by Curtis Olson, started February 1999.
|
||||
//
|
||||
// Copyright (C) 1999 Curtis L. Olson - http://www.flightgear.org/~curt
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
// $Id: clipper.hxx,v 1.11 2007-08-15 14:36:52 curt Exp $
|
||||
|
||||
|
||||
|
||||
#ifndef _CLIPPER_HXX
|
||||
#define _CLIPPER_HXX
|
||||
|
||||
|
||||
#ifndef __cplusplus
|
||||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
//#include <Geometry/trinodes.hxx>
|
||||
#include <Geometry/tg_nodes.hxx>
|
||||
#include <Polygon/superpoly.hxx>
|
||||
#include <Polygon/texparams.hxx>
|
||||
#include <Polygon/point2d.hxx>
|
||||
|
||||
#include <string>
|
||||
|
||||
#define TG_MAX_AREA_TYPES 128 // FIXME also defined in
|
||||
// MergerClipper/clipper.hxx
|
||||
#define EXTRA_SAFETY_CLIP
|
||||
|
||||
|
||||
class TGPolyList
|
||||
{
|
||||
public:
|
||||
superpoly_list superpolys[TG_MAX_AREA_TYPES];
|
||||
texparams_list texparams[TG_MAX_AREA_TYPES];
|
||||
TGPolygon safety_base;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class TGClipper
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
TGPolyList polys_in, polys_clipped;
|
||||
//TGTriNodes fixed_elevations;
|
||||
TGNodes nodes;
|
||||
|
||||
public:
|
||||
|
||||
// Constructor.
|
||||
TGClipper (void);
|
||||
|
||||
// Destructor.
|
||||
~TGClipper (void);
|
||||
|
||||
// Initialize Clipper (allocate and/or connect structures.)
|
||||
bool init();
|
||||
|
||||
// Load a polygon definition file
|
||||
bool load_polys(const std::string& path);
|
||||
|
||||
// Load an Osgb36 polygon definition file
|
||||
bool load_osgb36_polys(const std::string& path);
|
||||
|
||||
// Add a polygon.
|
||||
void add_poly(int area, const TGPolygon &poly, std::string material);
|
||||
|
||||
// Remove any slivers from in polygon and move them to out
|
||||
// polygon.
|
||||
void move_slivers( TGPolygon& in, TGPolygon& out );
|
||||
|
||||
// For each sliver contour, see if a union with another polygon
|
||||
// yields a polygon with no increased contours (i.e. the sliver is
|
||||
// adjacent and can be merged.) If so, replace the clipped
|
||||
// polygon with the new polygon that has the sliver merged in.
|
||||
void merge_slivers( TGPolyList& clipped, TGPolygon& slivers );
|
||||
|
||||
// Do actual clipping work.
|
||||
bool clip_all(const point2d& min, const point2d& max);
|
||||
|
||||
// Return output poly list
|
||||
inline TGPolyList get_polys_clipped() const { return polys_clipped; }
|
||||
|
||||
// Return the fixed elevation points list
|
||||
inline TGNodes get_nodes() const { return nodes; }
|
||||
|
||||
inline node_list get_fixed_elevations_nodes() { return nodes.get_fixed_elevation_nodes(); }
|
||||
|
||||
double nudge;
|
||||
|
||||
bool ignore_landmass() const {
|
||||
return m_ignore_landmass;
|
||||
}
|
||||
|
||||
void ignore_landmass(bool b) {
|
||||
m_ignore_landmass = b;
|
||||
}
|
||||
protected:
|
||||
bool m_ignore_landmass;
|
||||
};
|
||||
|
||||
|
||||
#endif // _CLIPPER_HXX
|
||||
|
||||
|
|
@ -1,116 +0,0 @@
|
|||
// main.cxx -- sample use of the clipper lib
|
||||
//
|
||||
// Written by Curtis Olson, started February 1999.
|
||||
//
|
||||
// Copyright (C) 1999 Curtis L. Olson - http://www.flightgear.org/~curt
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
// $Id: testclipper.cxx,v 1.7 2004-11-19 22:25:49 curt Exp $
|
||||
|
||||
|
||||
|
||||
#include <simgear/bucket/newbucket.hxx>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
#include "clipper.hxx"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::string;
|
||||
|
||||
|
||||
int main( int argc, char **argv ) {
|
||||
point2d global_min, global_max;
|
||||
|
||||
sglog().setLogLevels( SG_ALL, SG_DEBUG );
|
||||
|
||||
global_min.x = global_min.y = 200;
|
||||
global_max.y = global_max.x = -200;
|
||||
|
||||
TGClipper clipper;
|
||||
clipper.init();
|
||||
|
||||
if ( argc < 2 ) {
|
||||
SG_LOG( SG_CLIPPER, SG_ALERT, "Usage: " << argv[0]
|
||||
<< " file1 file2 ..." );
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// process all specified polygon files
|
||||
for ( int i = 1; i < argc; i++ ) {
|
||||
string full_path = argv[i];
|
||||
|
||||
// determine bucket for this polygon
|
||||
int pos = full_path.rfind("/");
|
||||
string file_name = full_path.substr(pos + 1);
|
||||
cout << "file name = " << file_name << endl;
|
||||
|
||||
pos = file_name.find(".");
|
||||
string base_name = file_name.substr(0, pos);
|
||||
cout << "base_name = " << base_name << endl;
|
||||
|
||||
long int index;
|
||||
sscanf( base_name.c_str(), "%ld", &index);
|
||||
SGBucket b(index);
|
||||
cout << "bucket = " << b << endl;
|
||||
|
||||
// calculate bucket dimensions
|
||||
point2d c, min, max;
|
||||
|
||||
c.x = b.get_center_lon();
|
||||
c.y = b.get_center_lat();
|
||||
double span = b.get_width();
|
||||
|
||||
if ( (c.y >= -89.0) && (c.y < 89.0) ) {
|
||||
min.x = c.x - span / 2.0;
|
||||
max.x = c.x + span / 2.0;
|
||||
min.y = c.y - SG_HALF_BUCKET_SPAN;
|
||||
max.y = c.y + SG_HALF_BUCKET_SPAN;
|
||||
} else if ( c.y < -89.0) {
|
||||
min.x = -90.0;
|
||||
max.x = -89.0;
|
||||
min.y = -180.0;
|
||||
max.y = 180.0;
|
||||
} else if ( c.y >= 89.0) {
|
||||
min.x = 89.0;
|
||||
max.x = 90.0;
|
||||
min.y = -180.0;
|
||||
max.y = 180.0;
|
||||
} else {
|
||||
SG_LOG ( SG_GENERAL, SG_ALERT,
|
||||
"Out of range latitude in clip_and_write_poly() = "
|
||||
<< c.y );
|
||||
}
|
||||
|
||||
if ( min.x < global_min.x ) global_min.x = min.x;
|
||||
if ( min.y < global_min.y ) global_min.y = min.y;
|
||||
if ( max.x > global_max.x ) global_max.x = max.x;
|
||||
if ( max.y > global_max.y ) global_max.y = max.y;
|
||||
|
||||
// finally, load the polygon(s) from this file
|
||||
clipper.load_polys( full_path );
|
||||
}
|
||||
|
||||
// do the clipping
|
||||
clipper.clip_all(global_min, global_max);
|
||||
|
||||
SG_LOG( SG_CLIPPER, SG_INFO, "finished main" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
|
||||
|
||||
add_library(GenOutput STATIC
|
||||
genobj.cxx genobj.hxx
|
||||
)
|
|
@ -1,519 +0,0 @@
|
|||
// genobj.hxx -- Generate the flight gear "obj" file format from the
|
||||
// triangle output
|
||||
//
|
||||
// Written by Curtis Olson, started March 1999.
|
||||
//
|
||||
// Copyright (C) 1999 Curtis L. Olson - http://www.flightgear.org/~curt
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
// $Id: genobj.cxx,v 1.26 2004-11-19 22:25:49 curt Exp $
|
||||
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
#include <simgear/io/sg_binobj.hxx>
|
||||
#include <simgear/math/SGGeometry.hxx>
|
||||
#include <simgear/misc/texcoord.hxx>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
#include <Output/output.hxx>
|
||||
#include <Clipper/priorities.hxx>
|
||||
|
||||
#include <Osgb36/osgbtc.hxx>
|
||||
#include <Osgb36/uk.hxx>
|
||||
|
||||
#include "genobj.hxx"
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::string;
|
||||
|
||||
|
||||
// calculate the global bounding sphere. Center is the center of the
|
||||
// tile and zero elevation
|
||||
void TGGenOutput::calc_gbs( TGConstruct& c ) {
|
||||
point_list wgs84_nodes = c.get_wgs84_nodes();
|
||||
gbs_center = SGVec3d::fromGeod( c.get_bucket().get_center() );
|
||||
|
||||
double dist_squared, radius_squared = 0;
|
||||
for ( unsigned int i = 0; i < wgs84_nodes.size(); ++i ) {
|
||||
dist_squared = distSqr(gbs_center, wgs84_nodes[i].toSGVec3d());
|
||||
if ( dist_squared > radius_squared ) {
|
||||
radius_squared = dist_squared;
|
||||
}
|
||||
}
|
||||
gbs_radius = sqrt(radius_squared);
|
||||
}
|
||||
|
||||
// build the necessary output structures based on the triangulation
|
||||
// data
|
||||
int TGGenOutput::build_fans( TGConstruct& c ) {
|
||||
// TGTriNodes trinodes = c.get_tri_nodes();
|
||||
TGNodes* nodes = c.get_nodes();
|
||||
|
||||
string tile_id = c.get_bucket().gen_index_str();
|
||||
|
||||
// copy the geodetic node list into this class
|
||||
geod_nodes = nodes->get_geod_nodes();
|
||||
|
||||
// copy the triangle list into this class
|
||||
tri_elements = c.get_tri_elements();
|
||||
|
||||
// build the trifan list
|
||||
cout << "total triangles = " << tri_elements.size() << endl;
|
||||
|
||||
TGGenFans f;
|
||||
|
||||
// Sort the triangles by area type
|
||||
// TODO: Need to sort on Material type - going to make the attribute an index
|
||||
// into an array of texparams / material names
|
||||
for ( unsigned int i = 0; i < TG_MAX_AREA_TYPES; ++i ) {
|
||||
triele_list area_tris;
|
||||
area_tris.erase( area_tris.begin(), area_tris.end() );
|
||||
|
||||
const_triele_list_iterator t_current = tri_elements.begin();
|
||||
const_triele_list_iterator t_last = tri_elements.end();
|
||||
|
||||
for ( ; t_current != t_last; ++t_current ) {
|
||||
if ( t_current->get_attribute() == i ) {
|
||||
area_tris.push_back( *t_current );
|
||||
}
|
||||
}
|
||||
|
||||
if ( (int)area_tris.size() > 0 ) {
|
||||
cout << "generating fans for area = " << i << endl;
|
||||
primitives[i] = f.greedy_build( area_tris );
|
||||
}
|
||||
}
|
||||
|
||||
// build the texture coordinate list and make a parallel structure
|
||||
// to the fan list for pointers into the texture list
|
||||
cout << "calculating texture coordinates" << endl;
|
||||
cout << "c.get_useUKGrid() = " << c.get_useUKGrid() << endl;
|
||||
tex_coords.clear();
|
||||
std::vector < SGGeod > convGeodNodes;
|
||||
for ( unsigned int k = 0; k < geod_nodes.size(); k++ ) {
|
||||
Point3D node = geod_nodes[k];
|
||||
convGeodNodes.push_back( SGGeod::fromDegM( node.x(), node.y(), node.z() ) );
|
||||
}
|
||||
|
||||
for ( unsigned int i = 0; i < TG_MAX_AREA_TYPES; ++i ) {
|
||||
// cout << " area = " << i << endl;
|
||||
for ( unsigned int j = 0; j < primitives[i].size(); ++j ) {
|
||||
SG_LOG( SG_CLIPPER, SG_INFO, tile_id << ": Texturing " << get_area_name( (AreaType)i ) << " primitive " << j+1 << " of " << primitives[i].size() );
|
||||
|
||||
SGBucket b = c.get_bucket();
|
||||
Point3D ourPosition;
|
||||
|
||||
ourPosition.setlon(b.get_chunk_lon());
|
||||
ourPosition.setlat(b.get_chunk_lat());
|
||||
|
||||
int_list ti_list;
|
||||
ti_list.clear();
|
||||
|
||||
//dcl - here read the flag to check if we are building UK grid
|
||||
//If so - check if the bucket is within the UK lat & lon
|
||||
if( (c.get_useUKGrid()) && (isInUK(ourPosition)) ) {
|
||||
point_list tp_list;
|
||||
tp_list = UK_calc_tex_coords( b, geod_nodes, primitives[i][j], 1.0 );
|
||||
for ( unsigned int k = 0; k < tp_list.size(); ++k ) {
|
||||
// cout << " tc = " << tp_list[k] << endl;
|
||||
int index = tex_coords.simple_add( tp_list[k] );
|
||||
ti_list.push_back( index );
|
||||
}
|
||||
} else {
|
||||
std::vector< SGVec2f > tp_list = sgCalcTexCoords( b, convGeodNodes, primitives[i][j] );
|
||||
for ( unsigned int k = 0; k < tp_list.size(); ++k ) {
|
||||
SGVec2f tc = tp_list[k];
|
||||
// SG_LOG(SG_GENERAL, SG_DEBUG, "base_tc = " << tc);
|
||||
int index = tex_coords.simple_add( Point3D( tc.x(), tc.y(), 0 ) );
|
||||
ti_list.push_back( index );
|
||||
}
|
||||
}
|
||||
|
||||
textures[i].push_back( ti_list );
|
||||
}
|
||||
}
|
||||
|
||||
// calculate the global bounding sphere
|
||||
calc_gbs( c );
|
||||
cout << "center = " << gbs_center << " radius = " << gbs_radius << endl;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static opt_list tgGenTris( const triele_list tris ) {
|
||||
triele_list remaining = tris;
|
||||
opt_list tri_lists;
|
||||
int_list tri;
|
||||
|
||||
tri_lists.clear();
|
||||
for ( unsigned int i = 0; i < tris.size(); ++i ) {
|
||||
tri.clear();
|
||||
|
||||
tri.push_back( tris[i].get_n1() );
|
||||
tri.push_back( tris[i].get_n2() );
|
||||
tri.push_back( tris[i].get_n3() );
|
||||
|
||||
tri_lists.push_back( tri );
|
||||
}
|
||||
|
||||
return tri_lists;
|
||||
}
|
||||
|
||||
int TGGenOutput::build_tris( TGConstruct& c ) {
|
||||
// TGTriNodes trinodes = c.get_tri_nodes();
|
||||
TGNodes* nodes = c.get_nodes();
|
||||
|
||||
string tile_id = c.get_bucket().gen_index_str();
|
||||
|
||||
// copy the geodetic node list into this class
|
||||
geod_nodes = nodes->get_geod_nodes();
|
||||
|
||||
// copy the triangle list into this class
|
||||
tri_elements = c.get_tri_elements();
|
||||
|
||||
// build the trifan list
|
||||
cout << "total triangles = " << tri_elements.size() << endl;
|
||||
|
||||
// Sort the triangles by area type
|
||||
// TODO: Need to sort on Material type - going to make the attribute an index
|
||||
// into an array of texparams / material names
|
||||
for ( unsigned int i = 0; i < TG_MAX_AREA_TYPES; ++i ) {
|
||||
triele_list area_tris;
|
||||
area_tris.erase( area_tris.begin(), area_tris.end() );
|
||||
|
||||
const_triele_list_iterator t_current = tri_elements.begin();
|
||||
const_triele_list_iterator t_last = tri_elements.end();
|
||||
|
||||
for ( ; t_current != t_last; ++t_current ) {
|
||||
if ( t_current->get_attribute() == i ) {
|
||||
area_tris.push_back( *t_current );
|
||||
}
|
||||
}
|
||||
|
||||
if ( area_tris.size() > 0 ) {
|
||||
cout << "generating tris for area = " << i << endl;
|
||||
primitives[i] = tgGenTris( area_tris );
|
||||
}
|
||||
}
|
||||
|
||||
// build the texture coordinate list and make a parallel structure
|
||||
// to the fan list for pointers into the texture list
|
||||
cout << "calculating texture coordinates" << endl;
|
||||
cout << "c.get_useUKGrid() = " << c.get_useUKGrid() << endl;
|
||||
tex_coords.clear();
|
||||
std::vector < SGGeod > convGeodNodes;
|
||||
for ( unsigned int k = 0; k < geod_nodes.size(); k++ ) {
|
||||
Point3D node = geod_nodes[k];
|
||||
convGeodNodes.push_back( SGGeod::fromDegM( node.x(), node.y(), node.z() ) );
|
||||
}
|
||||
|
||||
for ( unsigned int i = 0; i < TG_MAX_AREA_TYPES; ++i ) {
|
||||
// cout << " area = " << i << endl;
|
||||
for ( unsigned int j = 0; j < primitives[i].size(); ++j ) {
|
||||
SG_LOG( SG_CLIPPER, SG_INFO, tile_id << ": Texturing " << get_area_name( (AreaType)i ) << " primitive " << j+1 << " of " << primitives[i].size() );
|
||||
|
||||
SGBucket b = c.get_bucket();
|
||||
Point3D ourPosition;
|
||||
|
||||
ourPosition.setlon(b.get_chunk_lon());
|
||||
ourPosition.setlat(b.get_chunk_lat());
|
||||
|
||||
int_list ti_list;
|
||||
ti_list.clear();
|
||||
|
||||
//dcl - here read the flag to check if we are building UK grid
|
||||
//If so - check if the bucket is within the UK lat & lon
|
||||
if( (c.get_useUKGrid()) && (isInUK(ourPosition)) ) {
|
||||
point_list tp_list;
|
||||
tp_list = UK_calc_tex_coords( b, geod_nodes, primitives[i][j], 1.0 );
|
||||
for ( unsigned int k = 0; k < tp_list.size(); ++k ) {
|
||||
// cout << " tc = " << tp_list[k] << endl;
|
||||
int index = tex_coords.simple_add( tp_list[k] );
|
||||
ti_list.push_back( index );
|
||||
}
|
||||
} else {
|
||||
std::vector< SGVec2f > tp_list = sgCalcTexCoords( b, convGeodNodes, primitives[i][j] );
|
||||
for ( unsigned int k = 0; k < tp_list.size(); ++k ) {
|
||||
SGVec2f tc = tp_list[k];
|
||||
// SG_LOG(SG_GENERAL, SG_DEBUG, "base_tc = " << tc);
|
||||
int index = tex_coords.simple_add( Point3D( tc.x(), tc.y(), 0 ) );
|
||||
ti_list.push_back( index );
|
||||
}
|
||||
}
|
||||
|
||||
textures[i].push_back( ti_list );
|
||||
}
|
||||
}
|
||||
|
||||
// calculate the global bounding sphere
|
||||
calc_gbs( c );
|
||||
cout << "center = " << gbs_center << " radius = " << gbs_radius << endl;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// calculate the bounding sphere for a list of triangle faces
|
||||
void TGGenOutput::calc_group_bounding_sphere( TGConstruct& c,
|
||||
const opt_list& primitives,
|
||||
Point3D *center, double *radius )
|
||||
{
|
||||
cout << "calculate group bounding sphere for " << primitives.size() << " primitives." << endl;
|
||||
|
||||
point_list wgs84_nodes = c.get_wgs84_nodes();
|
||||
|
||||
// generate a list of unique points from the triangle list
|
||||
TGTriNodes nodes;
|
||||
|
||||
const_opt_list_iterator f_current = primitives.begin();
|
||||
const_opt_list_iterator f_last = primitives.end();
|
||||
for ( ; f_current != f_last; ++f_current ) {
|
||||
const_int_list_iterator i_current = f_current->begin();
|
||||
const_int_list_iterator i_last = f_current->end();
|
||||
for ( ; i_current != i_last; ++i_current ) {
|
||||
Point3D p1 = wgs84_nodes[ *i_current ];
|
||||
nodes.unique_add(p1);
|
||||
}
|
||||
}
|
||||
|
||||
// find average of point list
|
||||
*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 ) {
|
||||
*center += *p_current;
|
||||
}
|
||||
*center /= points.size();
|
||||
|
||||
// find max radius
|
||||
double dist_squared;
|
||||
double max_squared = 0;
|
||||
|
||||
p_current = points.begin();
|
||||
p_last = points.end();
|
||||
for ( ; p_current != p_last; ++p_current ) {
|
||||
dist_squared = (*center).distance3Dsquared(*p_current);
|
||||
if ( dist_squared > max_squared ) {
|
||||
max_squared = dist_squared;
|
||||
}
|
||||
}
|
||||
|
||||
*radius = sqrt(max_squared);
|
||||
}
|
||||
|
||||
|
||||
// calculate the bounding sphere for the specified triangle face
|
||||
void TGGenOutput::calc_bounding_sphere( TGConstruct& c, const TGTriEle& t,
|
||||
Point3D *center, double *radius )
|
||||
{
|
||||
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() ];
|
||||
|
||||
*center = p1 + p2 + p3;
|
||||
*center /= 3;
|
||||
|
||||
double dist_squared;
|
||||
double max_squared = 0;
|
||||
|
||||
dist_squared = (*center).distance3Dsquared(p1);
|
||||
if ( dist_squared > max_squared ) {
|
||||
max_squared = dist_squared;
|
||||
}
|
||||
|
||||
dist_squared = (*center).distance3Dsquared(p2);
|
||||
if ( dist_squared > max_squared ) {
|
||||
max_squared = dist_squared;
|
||||
}
|
||||
|
||||
dist_squared = (*center).distance3Dsquared(p3);
|
||||
if ( dist_squared > max_squared ) {
|
||||
max_squared = dist_squared;
|
||||
}
|
||||
|
||||
*radius = sqrt(max_squared);
|
||||
}
|
||||
|
||||
// write out the fgfs scenery file (using fans)
|
||||
int TGGenOutput::write_fans( TGConstruct &c ) {
|
||||
// Assemble all the data into the final format
|
||||
|
||||
SGBucket b = c.get_bucket();
|
||||
string base = c.get_output_base();
|
||||
string name = b.gen_index_str();
|
||||
name += ".btg";
|
||||
|
||||
std::vector< SGVec3d > wgs84_nodes;
|
||||
for ( unsigned int i = 0; i < c.get_wgs84_nodes().size(); i++ ) {
|
||||
Point3D node = c.get_wgs84_nodes()[i];
|
||||
wgs84_nodes.push_back( node.toSGVec3d() );
|
||||
}
|
||||
std::vector< SGVec3f > normals;
|
||||
for ( unsigned int i = 0; i < c.get_point_normals().size(); i++ ) {
|
||||
Point3D node = c.get_point_normals()[i];
|
||||
normals.push_back( node.toSGVec3f() );
|
||||
}
|
||||
cout << "dumping normals = " << normals.size() << endl;
|
||||
/* for ( i = 0; i < (int)normals.size(); ++i ) {
|
||||
Point3D p = normals[i];
|
||||
printf("vn %.5f %.5f %.5f\n", p.x(), p.y(), p.z());
|
||||
} */
|
||||
std::vector< SGVec2f > texcoords;
|
||||
for ( unsigned int i = 0; i < tex_coords.get_node_list().size(); i++ ) {
|
||||
Point3D node = tex_coords.get_node_list()[i];
|
||||
texcoords.push_back( node.toSGVec2f() );
|
||||
}
|
||||
|
||||
// allocate and initialize triangle group structures
|
||||
group_list tris_v; group_list tris_tc; string_list tri_materials;
|
||||
tris_v.clear(); tris_tc.clear(); tri_materials.clear();
|
||||
|
||||
group_list strips_v; group_list strips_tc; string_list strip_materials;
|
||||
strips_v.clear(); strips_tc.clear(); strip_materials.clear();
|
||||
|
||||
group_list fans_v; group_list fans_tc; string_list fan_materials;
|
||||
fans_v.clear(); fans_tc.clear(); fan_materials.clear();
|
||||
|
||||
for ( unsigned int i = 0; i < TG_MAX_AREA_TYPES; ++i ) {
|
||||
if ( primitives[i].size() > 0 ) {
|
||||
cout << "creating " << primitives[i].size() << " fans of type " << i << endl;
|
||||
string attr_name = get_area_name( (AreaType)i );
|
||||
|
||||
int_list vs, tcs;
|
||||
for ( unsigned int j = 0; j < primitives[i].size(); ++j ) {
|
||||
vs.clear(); tcs.clear();
|
||||
for ( unsigned int k = 0; k < primitives[i][j].size(); ++k ) {
|
||||
vs.push_back( primitives[i][j][k] );
|
||||
tcs.push_back( textures[i][j][k] );
|
||||
}
|
||||
fans_v.push_back( vs );
|
||||
fans_tc.push_back( tcs );
|
||||
fan_materials.push_back( attr_name );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SGBinObject obj;
|
||||
|
||||
obj.set_gbs_center( gbs_center );
|
||||
obj.set_gbs_radius( gbs_radius );
|
||||
obj.set_wgs84_nodes( wgs84_nodes );
|
||||
obj.set_normals( normals );
|
||||
obj.set_texcoords( texcoords );
|
||||
obj.set_tris_v( tris_v );
|
||||
obj.set_tris_tc( tris_tc );
|
||||
obj.set_tri_materials( tri_materials );
|
||||
obj.set_strips_v( strips_v );
|
||||
obj.set_strips_tc( strips_tc );
|
||||
obj.set_strip_materials( strip_materials );
|
||||
obj.set_fans_v( fans_v );
|
||||
obj.set_fans_tc( fans_tc );
|
||||
obj.set_fan_materials( fan_materials );
|
||||
|
||||
obj.write_bin( base, name, b );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// write out the fgfs scenery file (using tris)
|
||||
int TGGenOutput::write_tris( TGConstruct &c ) {
|
||||
// Assemble all the data into the final format
|
||||
|
||||
SGBucket b = c.get_bucket();
|
||||
string base = c.get_output_base();
|
||||
string name = b.gen_index_str();
|
||||
name += ".btg";
|
||||
|
||||
std::vector< SGVec3d > wgs84_nodes;
|
||||
for ( unsigned int i = 0; i < c.get_wgs84_nodes().size(); i++ ) {
|
||||
Point3D node = c.get_wgs84_nodes()[i];
|
||||
wgs84_nodes.push_back( node.toSGVec3d() );
|
||||
}
|
||||
std::vector< SGVec3f > normals;
|
||||
for ( unsigned int i = 0; i < c.get_point_normals().size(); i++ ) {
|
||||
Point3D node = c.get_point_normals()[i];
|
||||
normals.push_back( node.toSGVec3f() );
|
||||
}
|
||||
cout << "dumping normals = " << normals.size() << endl;
|
||||
/* for ( i = 0; i < (int)normals.size(); ++i ) {
|
||||
Point3D p = normals[i];
|
||||
printf("vn %.5f %.5f %.5f\n", p.x(), p.y(), p.z());
|
||||
} */
|
||||
std::vector< SGVec2f > texcoords;
|
||||
for ( unsigned int i = 0; i < tex_coords.get_node_list().size(); i++ ) {
|
||||
Point3D node = tex_coords.get_node_list()[i];
|
||||
texcoords.push_back( node.toSGVec2f() );
|
||||
}
|
||||
|
||||
// allocate and initialize triangle group structures
|
||||
group_list tris_v; group_list tris_tc; string_list tri_materials;
|
||||
tris_v.clear(); tris_tc.clear(); tri_materials.clear();
|
||||
|
||||
group_list strips_v; group_list strips_tc; string_list strip_materials;
|
||||
strips_v.clear(); strips_tc.clear(); strip_materials.clear();
|
||||
|
||||
group_list fans_v; group_list fans_tc; string_list fan_materials;
|
||||
fans_v.clear(); fans_tc.clear(); fan_materials.clear();
|
||||
|
||||
for ( unsigned int i = 0; i < TG_MAX_AREA_TYPES; ++i ) {
|
||||
if ( primitives[i].size() > 0 ) {
|
||||
cout << "creating " << primitives[i].size() << " tris of type " << i << endl;
|
||||
string attr_name = get_area_name( (AreaType)i );
|
||||
|
||||
int_list vs, tcs;
|
||||
for ( unsigned int j = 0; j < primitives[i].size(); ++j ) {
|
||||
vs.clear(); tcs.clear();
|
||||
for ( unsigned int k = 0; k < primitives[i][j].size(); ++k ) {
|
||||
vs.push_back( primitives[i][j][k] );
|
||||
tcs.push_back( textures[i][j][k] );
|
||||
}
|
||||
tris_v.push_back( vs );
|
||||
tris_tc.push_back( tcs );
|
||||
tri_materials.push_back( attr_name );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SGBinObject obj;
|
||||
|
||||
obj.set_gbs_center( gbs_center );
|
||||
obj.set_gbs_radius( gbs_radius );
|
||||
obj.set_wgs84_nodes( wgs84_nodes );
|
||||
obj.set_normals( normals );
|
||||
obj.set_texcoords( texcoords );
|
||||
obj.set_tris_v( tris_v );
|
||||
obj.set_tris_tc( tris_tc );
|
||||
obj.set_tri_materials( tri_materials );
|
||||
obj.set_strips_v( strips_v );
|
||||
obj.set_strips_tc( strips_tc );
|
||||
obj.set_strip_materials( strip_materials );
|
||||
obj.set_fans_v( fans_v );
|
||||
obj.set_fans_tc( fans_tc );
|
||||
obj.set_fan_materials( fan_materials );
|
||||
|
||||
obj.write_bin( base, name, b );
|
||||
|
||||
return 1;
|
||||
}
|
|
@ -1,107 +0,0 @@
|
|||
// genobj.hxx -- Generate the flight gear "obj" file format from the
|
||||
// triangle output
|
||||
//
|
||||
// Written by Curtis Olson, started March 1999.
|
||||
//
|
||||
// Copyright (C) 1999 Curtis L. Olson - http://www.flightgear.org/~curt
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
// $Id: genobj.hxx,v 1.9 2004-11-19 22:25:49 curt Exp $
|
||||
|
||||
|
||||
#ifndef _GENOBJ_HXX
|
||||
#define _GENOBJ_HXX
|
||||
|
||||
|
||||
#ifndef __cplusplus
|
||||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include <simgear/bucket/newbucket.hxx>
|
||||
#include <Geometry/point3d.hxx>
|
||||
#include <simgear/math/sg_geodesy.hxx>
|
||||
#include <simgear/math/sg_types.hxx>
|
||||
|
||||
#include <Optimize/genfans.hxx>
|
||||
#include <Main/construct.hxx>
|
||||
#include <Triangulate/triangle.hxx>
|
||||
|
||||
typedef std::vector < int_list > tex_list;
|
||||
typedef tex_list::iterator tex_list_iterator;
|
||||
typedef tex_list::const_iterator const_tex_list_iterator;
|
||||
|
||||
class TGGenOutput {
|
||||
|
||||
private:
|
||||
|
||||
// node list in geodetic coordinates
|
||||
point_list geod_nodes;
|
||||
|
||||
// triangles (by index into point list)
|
||||
triele_list tri_elements;
|
||||
|
||||
// texture coordinates
|
||||
TGTriNodes tex_coords;
|
||||
|
||||
// fan / triangle list
|
||||
opt_list primitives[TG_MAX_AREA_TYPES];
|
||||
|
||||
// textures pointer list
|
||||
tex_list textures[TG_MAX_AREA_TYPES];
|
||||
|
||||
// global bounding sphere
|
||||
SGVec3d gbs_center;
|
||||
double gbs_radius;
|
||||
|
||||
// calculate the global bounding sphere. Center is the average of
|
||||
// the points.
|
||||
void calc_gbs( TGConstruct& c );
|
||||
|
||||
// caclulate the bounding sphere for a list of triangle faces
|
||||
void calc_group_bounding_sphere( TGConstruct& c, const opt_list& fans,
|
||||
Point3D *center, double *radius );
|
||||
|
||||
// caclulate the bounding sphere for the specified triangle face
|
||||
void calc_bounding_sphere( TGConstruct& c, const TGTriEle& t,
|
||||
Point3D *center, double *radius );
|
||||
|
||||
// traverse the specified fan and attempt to calculate "none
|
||||
// stretching" texture coordinates
|
||||
// int_list calc_tex_coords( TGConstruct& c, point_list geod_nodes, int_list fan );
|
||||
|
||||
public:
|
||||
|
||||
// Constructor && Destructor
|
||||
inline TGGenOutput() { }
|
||||
inline ~TGGenOutput() { }
|
||||
|
||||
// build the necessary output structures based on the
|
||||
// triangulation data
|
||||
int build_fans( TGConstruct& c );
|
||||
int build_tris( TGConstruct& c );
|
||||
|
||||
// write out the fgfs scenery file
|
||||
int write_fans( TGConstruct &c );
|
||||
int write_tris( TGConstruct &c );
|
||||
};
|
||||
|
||||
|
||||
#endif // _GENOBJ_HXX
|
||||
|
||||
|
|
@ -1,18 +1,22 @@
|
|||
|
||||
|
||||
add_executable(fgfs-construct
|
||||
construct.cxx construct.hxx
|
||||
usgs.cxx main.cxx)
|
||||
construct.cxx
|
||||
construct.hxx
|
||||
priorities.cxx
|
||||
priorities.hxx
|
||||
usgs.cxx
|
||||
main.cxx)
|
||||
|
||||
set_target_properties(fgfs-construct PROPERTIES
|
||||
COMPILE_DEFINITIONS
|
||||
"DEFAULT_USGS_MAPFILE=\"${PKGDATADIR}/usgsmap.txt\";DEFAULT_PRIORITIES_FILE=\"${PKGDATADIR}/default_priorities.txt\"" )
|
||||
|
||||
target_link_libraries(fgfs-construct
|
||||
Clipper GenOutput Osgb36 Triangulate
|
||||
Osgb36
|
||||
Match
|
||||
Polygon Geometry
|
||||
Array Optimize Output landcover poly2tri
|
||||
Array Optimize landcover poly2tri
|
||||
TriangleJRS
|
||||
${GDAL_LIBRARY}
|
||||
${SIMGEAR_CORE_LIBRARIES}
|
||||
|
@ -20,15 +24,6 @@ target_link_libraries(fgfs-construct
|
|||
${GPC_LIBRARY})
|
||||
|
||||
install(TARGETS fgfs-construct RUNTIME DESTINATION bin)
|
||||
|
||||
INSTALL(FILES usgsmap.txt DESTINATION ${PKGDATADIR} )
|
||||
|
||||
|
||||
add_executable(fgfs-master
|
||||
master.cxx)
|
||||
|
||||
target_link_libraries(fgfs-master
|
||||
${SIMGEAR_CORE_LIBRARIES}
|
||||
${SIMGEAR_CORE_LIBRARY_DEPENDENCIES}
|
||||
)
|
||||
|
||||
install(TARGETS fgfs-master RUNTIME DESTINATION bin)
|
||||
INSTALL(FILES default_priorities.txt DESTINATION ${PKGDATADIR} )
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -31,28 +31,42 @@
|
|||
#endif
|
||||
|
||||
|
||||
// Maximum nodes per tile
|
||||
#define TG_MAX_NODES 4000
|
||||
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
#define TG_MAX_AREA_TYPES 128
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
#include <simgear/bucket/newbucket.hxx>
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
|
||||
#include <Array/array.hxx>
|
||||
|
||||
#include <Polygon/superpoly.hxx>
|
||||
#include <Polygon/texparams.hxx>
|
||||
#include <Geometry/tg_nodes.hxx>
|
||||
|
||||
#include <landcover/landcover.hxx>
|
||||
|
||||
// TO REMOVE
|
||||
#include <Geometry/trieles.hxx>
|
||||
#include <Geometry/trinodes.hxx>
|
||||
#include <Geometry/trisegs.hxx>
|
||||
#include <Clipper/priorities.hxx>
|
||||
// TO REMOVE
|
||||
|
||||
#include <Clipper/clipper.hxx>
|
||||
#include <Triangulate/trieles.hxx>
|
||||
#include "priorities.hxx"
|
||||
|
||||
typedef std::vector < int_list > belongs_to_list;
|
||||
typedef belongs_to_list::iterator belongs_to_list_iterator;
|
||||
typedef belongs_to_list::const_iterator belongs_to_list_tripoly_iterator;
|
||||
|
||||
class TGPolyList
|
||||
{
|
||||
public:
|
||||
superpoly_list superpolys[TG_MAX_AREA_TYPES];
|
||||
texparams_list texparams[TG_MAX_AREA_TYPES];
|
||||
TGPolygon safety_base;
|
||||
};
|
||||
|
||||
class TGConstruct {
|
||||
|
||||
|
@ -65,10 +79,14 @@ private:
|
|||
std::string work_base;
|
||||
std::string output_base;
|
||||
|
||||
std::vector<std::string> load_dirs;
|
||||
|
||||
// flag indicating whether to align texture coords within the UK
|
||||
// with the UK grid
|
||||
bool useUKGrid;
|
||||
|
||||
double nudge;
|
||||
|
||||
// flag indicating whether this is a rebuild and Shared edge
|
||||
// data should only be used for fitting, but not rewritten
|
||||
bool writeSharedEdges;
|
||||
|
@ -80,39 +98,20 @@ private:
|
|||
// flag indicating whether to ignore the landmass
|
||||
bool ignoreLandmass;
|
||||
|
||||
// detail level constraints
|
||||
int min_nodes;
|
||||
int max_nodes;
|
||||
|
||||
// this bucket
|
||||
SGBucket bucket;
|
||||
|
||||
// clipped polygons (gpc format)
|
||||
TGPolyList clipped_polys;
|
||||
// Elevation data
|
||||
TGArray array;
|
||||
|
||||
// Fixed elevations (from polygon input data with z values
|
||||
// pre-specified)
|
||||
node_list fixed_elevations;
|
||||
// land class polygons
|
||||
TGPolyList polys_in;
|
||||
TGPolyList polys_clipped;
|
||||
|
||||
// raw node list (after triangulation)
|
||||
TGTriNodes tri_nodes;
|
||||
// All Nodes
|
||||
TGNodes nodes;
|
||||
|
||||
// node list in geodetic coords (with fixed elevation)
|
||||
point_list geod_nodes;
|
||||
|
||||
// node list in cartesian coords (wgs84 model)
|
||||
point_list wgs84_nodes;
|
||||
|
||||
// triangle elements (after triangulation)
|
||||
triele_list tri_elements;
|
||||
|
||||
// edge segments (after triangulation)
|
||||
TGTriSegments tri_segs;
|
||||
|
||||
// for each node, a list of triangle indices that contain this node
|
||||
belongs_to_list reverse_ele_lookup;
|
||||
|
||||
// TODO : Add to superpoly
|
||||
// face normal list (for flat shading)
|
||||
point_list face_normals;
|
||||
|
||||
|
@ -124,6 +123,39 @@ public:
|
|||
// Destructor
|
||||
~TGConstruct();
|
||||
|
||||
void construct_bucket( SGBucket b );
|
||||
bool load_array();
|
||||
int load_polys();
|
||||
bool load_poly(const std::string& path);
|
||||
bool load_osgb36_poly(const std::string& path);
|
||||
void add_poly(int area, const TGPolygon &poly, std::string material);
|
||||
|
||||
void move_slivers( TGPolygon& in, TGPolygon& out );
|
||||
void merge_slivers( TGPolyList& clipped, TGPolygon& slivers );
|
||||
|
||||
bool clip_all(const point2d& min, const point2d& max);
|
||||
|
||||
void add_intermediate_nodes(void);
|
||||
void clean_clipped_polys(void);
|
||||
|
||||
void calc_gc_course_dist( const Point3D& start, const Point3D& dest,
|
||||
double *course, double *dist );
|
||||
double distanceSphere( const Point3D p1, const Point3D p2 );
|
||||
void fix_point_heights();
|
||||
|
||||
TGPolygon linear_tex_coords( const TGPolygon& tri, const TGTexParams& tp );
|
||||
TGPolygon area_tex_coords( const TGPolygon& tri );
|
||||
|
||||
int load_landcover ();
|
||||
void add_to_polys( TGPolygon &accum, const TGPolygon &poly);
|
||||
double measure_roughness( TGPolygon &poly );
|
||||
AreaType get_landcover_type (const LandCover &cover, double xpos, double ypos, double dx, double dy);
|
||||
void make_area( const LandCover &cover, TGPolygon *polys,
|
||||
double x1, double y1, double x2, double y2,
|
||||
double half_dx, double half_dy );
|
||||
|
||||
void do_custom_objects(void);
|
||||
|
||||
// land cover file
|
||||
inline std::string get_cover () const { return cover; }
|
||||
inline void set_cover (const std::string &s) { cover = s; }
|
||||
|
@ -133,71 +165,29 @@ public:
|
|||
inline void set_work_base( const std::string s ) { work_base = s; }
|
||||
inline std::string get_output_base() const { return output_base; }
|
||||
inline void set_output_base( const std::string s ) { output_base = s; }
|
||||
inline void set_load_dirs( const std::vector<std::string> ld ) { load_dirs = ld; }
|
||||
|
||||
// UK grid flag
|
||||
inline bool get_useUKGrid() const { return useUKGrid; }
|
||||
inline void set_useUKGrid( const bool b ) { useUKGrid = b; }
|
||||
|
||||
// Nudge
|
||||
inline void set_nudge( double n ) { nudge = n; }
|
||||
|
||||
// shared edge write flag
|
||||
inline bool get_write_shared_edges() const { return writeSharedEdges; }
|
||||
inline void set_write_shared_edges( const bool b ) { writeSharedEdges = b; }
|
||||
|
||||
// own shared edge use flag
|
||||
inline bool get_use_own_shared_edges() const { return useOwnSharedEdges; }
|
||||
inline void set_use_own_shared_edges( const bool b ) { useOwnSharedEdges = b; }
|
||||
|
||||
// ignore landmass flag
|
||||
inline bool get_ignore_landmass() const { return ignoreLandmass; }
|
||||
inline void set_ignore_landmass( const bool b) { ignoreLandmass = b; }
|
||||
|
||||
// detail level constraints
|
||||
inline int get_min_nodes() const { return min_nodes; }
|
||||
inline void set_min_nodes( const int n ) { min_nodes = n; }
|
||||
inline int get_max_nodes() const { return max_nodes; }
|
||||
inline void set_max_nodes( const int n ) { max_nodes = n; }
|
||||
|
||||
// this bucket
|
||||
inline SGBucket get_bucket() const { return bucket; }
|
||||
inline void set_bucket( const SGBucket b ) { bucket = b; }
|
||||
|
||||
// clipped polygons
|
||||
inline TGPolyList get_clipped_polys() const { return clipped_polys; }
|
||||
inline void set_clipped_polys( TGPolyList p ) { clipped_polys = p; }
|
||||
|
||||
// Fixed elevations (from polygon input data with z values pre-specified)
|
||||
inline node_list get_fixed_elevations() const { return nodes.get_fixed_elevation_nodes(); }
|
||||
|
||||
// node list (after triangulation) : No need - we won't add nodes....
|
||||
// inline TGTriNodes get_tri_nodes() const { return tri_nodes; }
|
||||
// inline void set_tri_nodes( TGTriNodes n ) { tri_nodes = n; }
|
||||
|
||||
// TODO : REMOVE
|
||||
inline TGNodes* get_nodes() { return &nodes; }
|
||||
inline void set_nodes( TGNodes n ) { nodes = n; }
|
||||
|
||||
// triangle elements (after triangulation) : No need - will be in the triangulated polygons
|
||||
inline triele_list get_tri_elements() const { return tri_elements; }
|
||||
inline void set_tri_elements( triele_list e ) { tri_elements = e; }
|
||||
inline void set_tri_attribute( int num, AreaType a ) { tri_elements[num].set_attribute( a ); }
|
||||
|
||||
// edge segments (after triangulation) : Same as above
|
||||
inline TGTriSegments get_tri_segs() const { return tri_segs; }
|
||||
inline void set_tri_segs( TGTriSegments s ) { tri_segs = s; }
|
||||
|
||||
// node list in geodetic coords (with fixed elevation)
|
||||
inline point_list get_geod_nodes() const { return nodes.get_geod_nodes(); }
|
||||
// inline void set_geod_nodes( point_list n ) { geod_nodes = n; }
|
||||
|
||||
// node list in cartesian coords (wgs84 model)
|
||||
inline point_list get_wgs84_nodes() const { return nodes.get_wgs84_nodes_as_Point3d(); }
|
||||
// inline void set_wgs84_nodes( point_list n ) { wgs84_nodes = n; }
|
||||
|
||||
// for each node, a list of triangle indices that contain this node
|
||||
inline belongs_to_list get_reverse_ele_lookup() const {
|
||||
return reverse_ele_lookup;
|
||||
}
|
||||
inline void set_reverse_ele_lookup( belongs_to_list r ) {
|
||||
reverse_ele_lookup = r;
|
||||
}
|
||||
|
||||
// face normal list (for flat shading)
|
||||
inline point_list get_face_normals() const { return face_normals; }
|
||||
|
|
|
@ -7,6 +7,13 @@ Hole hole # Leave area completely empty
|
|||
Airport other
|
||||
Freeway road
|
||||
Road road
|
||||
Road-Motorway road
|
||||
Road-Trunk road
|
||||
Road-Residential road
|
||||
Road-Primary road
|
||||
Road-Secondary road
|
||||
Road-Tertiary road
|
||||
|
||||
Railroad road
|
||||
Asphalt road
|
||||
Pond lake
|
File diff suppressed because it is too large
Load diff
|
@ -22,11 +22,11 @@
|
|||
#ifndef _USGS_HXX
|
||||
#define _USGS_HXX
|
||||
|
||||
#include <Clipper/priorities.hxx>
|
||||
#include <string>
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include <string>
|
||||
#include "priorities.hxx"
|
||||
|
||||
int load_usgs_map( const std::string& filename );
|
||||
AreaType translateUSGSCover( int usgs_value );
|
||||
|
|
|
@ -141,14 +141,10 @@ void TGMatch::scan_share_file( const string& dir, const SGBucket& b,
|
|||
|
||||
|
||||
// try to find info for the specified shared component
|
||||
void TGMatch::load_shared( const TGConstruct& c, neighbor_type n ) {
|
||||
SGBucket b = c.get_bucket();
|
||||
|
||||
void TGMatch::load_shared( SGBucket b, string base, neighbor_type n ) {
|
||||
double clon = b.get_center_lon();
|
||||
double clat = b.get_center_lat();
|
||||
|
||||
string base = c.get_work_base() + "/Shared/";
|
||||
|
||||
SGBucket cb;
|
||||
|
||||
if ( n == SW_Corner ) {
|
||||
|
@ -205,27 +201,29 @@ void TGMatch::load_shared( const TGConstruct& c, neighbor_type n ) {
|
|||
|
||||
// load any previously existing shared data from all neighbors (if
|
||||
// shared data for a component exists set that components flag to true
|
||||
void TGMatch::load_neighbor_shared( TGConstruct& c ) {
|
||||
void TGMatch::load_neighbor_shared( SGBucket b, string work ) {
|
||||
cout << "Loading existing shared data from neighbor tiles" << endl;
|
||||
|
||||
string base = work + "/Shared/";
|
||||
|
||||
// start with all flags false
|
||||
sw_flag = se_flag = ne_flag = nw_flag = false;
|
||||
north_flag = south_flag = east_flag = west_flag = false;
|
||||
|
||||
load_shared( c, SW_Corner );
|
||||
load_shared( c, SE_Corner );
|
||||
load_shared( c, NE_Corner );
|
||||
load_shared( c, NW_Corner );
|
||||
load_shared( b, base, SW_Corner );
|
||||
load_shared( b, base, SE_Corner );
|
||||
load_shared( b, base, NE_Corner );
|
||||
load_shared( b, base, NW_Corner );
|
||||
|
||||
north_nodes.clear();
|
||||
south_nodes.clear();
|
||||
east_nodes.clear();
|
||||
west_nodes.clear();
|
||||
|
||||
load_shared( c, NORTH );
|
||||
load_shared( c, SOUTH );
|
||||
load_shared( c, EAST );
|
||||
load_shared( c, WEST );
|
||||
load_shared( b, base, NORTH );
|
||||
load_shared( b, base, SOUTH );
|
||||
load_shared( b, base, EAST );
|
||||
load_shared( b, base, WEST );
|
||||
|
||||
cout << "Shared data read in:" << endl;
|
||||
if ( sw_flag ) {
|
||||
|
@ -271,13 +269,11 @@ void TGMatch::load_neighbor_shared( TGConstruct& c ) {
|
|||
}
|
||||
|
||||
// try to load any missing shared data from our own shared data file
|
||||
void TGMatch::load_missing_shared( TGConstruct& c ) {
|
||||
SGBucket b = c.get_bucket();
|
||||
|
||||
void TGMatch::load_missing_shared( SGBucket b, string work ) {
|
||||
double clon = b.get_center_lon();
|
||||
double clat = b.get_center_lat();
|
||||
|
||||
string base = c.get_work_base() + "/Shared/";
|
||||
string base = work + "/Shared/";
|
||||
|
||||
if ( !nw_flag ) {
|
||||
scan_share_file( base, b, NW_Corner, NW_Corner );
|
||||
|
@ -332,7 +328,7 @@ Point3D tgFakeNormal( const Point3D& p ) {
|
|||
// segments and the body. This must be done after calling
|
||||
// load_neighbor_data() and will ignore any shared data from the
|
||||
// current tile that already exists from a neighbor.
|
||||
void TGMatch::split_tile( TGConstruct& c ) {
|
||||
void TGMatch::split_tile( SGBucket b, TGConstruct* c ) {
|
||||
int i;
|
||||
|
||||
cout << "Spliting tile" << endl;
|
||||
|
@ -340,7 +336,7 @@ void TGMatch::split_tile( TGConstruct& c ) {
|
|||
|
||||
// calculate tile boundaries
|
||||
point2d min, max;
|
||||
SGBucket b = c.get_bucket();
|
||||
|
||||
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();
|
||||
|
@ -368,8 +364,8 @@ void TGMatch::split_tile( TGConstruct& c ) {
|
|||
|
||||
body_nodes.clear();
|
||||
|
||||
point_list nodes = c.get_geod_nodes();
|
||||
point_list point_normals = c.get_point_normals();
|
||||
point_list nodes = c->get_geod_nodes();
|
||||
point_list point_normals = c->get_point_normals();
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "number of geod nodes = " << nodes.size() );
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "number of normals = " << point_normals.size() );
|
||||
|
@ -509,9 +505,8 @@ void TGMatch::split_tile( TGConstruct& c ) {
|
|||
|
||||
// write the new shared edge points, normals, and segments for this
|
||||
// tile
|
||||
void TGMatch::write_shared( TGConstruct& c ) {
|
||||
string base = c.get_work_base();
|
||||
SGBucket b = c.get_bucket();
|
||||
void TGMatch::write_shared( SGBucket b, TGConstruct* c ) {
|
||||
string base = c->get_work_base();
|
||||
|
||||
string dir = base + "/Shared/" + b.gen_base_path();
|
||||
string file = dir + "/" + b.gen_index_str();
|
||||
|
@ -548,30 +543,30 @@ void TGMatch::write_shared( TGConstruct& c ) {
|
|||
* means that the adjacent tile already has been built.
|
||||
*/
|
||||
if ( ! sw_flag ) {
|
||||
fprintf( fp, "sw_node %.6f %.6f %.6f\n",
|
||||
fprintf( fp, "sw_node %.10f %.10f %.10f\n",
|
||||
sw_node.x(), sw_node.y(), sw_node.z() );
|
||||
fprintf( fp, "sw_normal %.6f %.6f %.6f\n",
|
||||
fprintf( fp, "sw_normal %.10f %.10f %.10f\n",
|
||||
sw_normal.x(), sw_normal.y(), sw_normal.z() );
|
||||
}
|
||||
|
||||
if ( ! se_flag ) {
|
||||
fprintf( fp, "se_node %.6f %.6f %.6f\n",
|
||||
fprintf( fp, "se_node %.10f %.10f %.10f\n",
|
||||
se_node.x(), se_node.y(), se_node.z() );
|
||||
fprintf( fp, "se_normal %.6f %.6f %.6f\n",
|
||||
fprintf( fp, "se_normal %.10f %.10f %.10f\n",
|
||||
se_normal.x(), se_normal.y(), se_normal.z() );
|
||||
}
|
||||
|
||||
if ( ! nw_flag ) {
|
||||
fprintf( fp, "nw_node %.6f %.6f %.6f\n",
|
||||
fprintf( fp, "nw_node %.10f %.10f %.10f\n",
|
||||
nw_node.x(), nw_node.y(), nw_node.z() );
|
||||
fprintf( fp, "nw_normal %.6f %.6f %.6f\n",
|
||||
fprintf( fp, "nw_normal %.10f %.10f %.10f\n",
|
||||
nw_normal.x(), nw_normal.y(), nw_normal.z() );
|
||||
}
|
||||
|
||||
if ( ! ne_flag ) {
|
||||
fprintf( fp, "ne_node %.6f %.6f %.6f\n",
|
||||
fprintf( fp, "ne_node %.10f %.10f %.10f\n",
|
||||
ne_node.x(), ne_node.y(), ne_node.z() );
|
||||
fprintf( fp, "ne_normal %.6f %.6f %.6f\n",
|
||||
fprintf( fp, "ne_normal %.10f %.10f %.10f\n",
|
||||
ne_normal.x(), ne_normal.y(), ne_normal.z() );
|
||||
}
|
||||
|
||||
|
@ -580,10 +575,10 @@ void TGMatch::write_shared( TGConstruct& c ) {
|
|||
fprintf( fp, "n_null -999.0 -999.0 -999.0\n" );
|
||||
} else {
|
||||
for ( int i = 0; i < (int)north_nodes.size(); ++i ) {
|
||||
fprintf( fp, "n_node %.6f %.6f %.6f\n",
|
||||
fprintf( fp, "n_node %.10f %.10f %.10f\n",
|
||||
north_nodes[i].x(), north_nodes[i].y(),
|
||||
north_nodes[i].z() );
|
||||
fprintf( fp, "n_normal %.6f %.6f %.6f\n",
|
||||
fprintf( fp, "n_normal %.10f %.10f %.10f\n",
|
||||
north_normals[i].x(), north_normals[i].y(),
|
||||
north_normals[i].z() );
|
||||
}
|
||||
|
@ -595,10 +590,10 @@ void TGMatch::write_shared( TGConstruct& c ) {
|
|||
fprintf( fp, "s_null -999.0 -999.0 -999.0\n" );
|
||||
} else {
|
||||
for ( int i = 0; i < (int)south_nodes.size(); ++i ) {
|
||||
fprintf( fp, "s_node %.6f %.6f %.6f\n",
|
||||
fprintf( fp, "s_node %.10f %.10f %.10f\n",
|
||||
south_nodes[i].x(), south_nodes[i].y(),
|
||||
south_nodes[i].z() );
|
||||
fprintf( fp, "s_normal %.6f %.6f %.6f\n",
|
||||
fprintf( fp, "s_normal %.10f %.10f %.10f\n",
|
||||
south_normals[i].x(), south_normals[i].y(),
|
||||
south_normals[i].z() );
|
||||
}
|
||||
|
@ -610,10 +605,10 @@ void TGMatch::write_shared( TGConstruct& c ) {
|
|||
fprintf( fp, "e_null -999.0 -999.0 -999.0\n" );
|
||||
} else {
|
||||
for ( int i = 0; i < (int)east_nodes.size(); ++i ) {
|
||||
fprintf( fp, "e_node %.6f %.6f %.6f\n",
|
||||
fprintf( fp, "e_node %.10f %.10f %.10f\n",
|
||||
east_nodes[i].x(), east_nodes[i].y(),
|
||||
east_nodes[i].z() );
|
||||
fprintf( fp, "e_normal %.6f %.6f %.6f\n",
|
||||
fprintf( fp, "e_normal %.10f %.10f %.10f\n",
|
||||
east_normals[i].x(), east_normals[i].y(),
|
||||
east_normals[i].z() );
|
||||
}
|
||||
|
@ -625,10 +620,10 @@ void TGMatch::write_shared( TGConstruct& c ) {
|
|||
fprintf( fp, "w_null -999.0 -999.0 -999.0\n" );
|
||||
} else {
|
||||
for ( int i = 0; i < (int)west_nodes.size(); ++i ) {
|
||||
fprintf( fp, "w_node %.6f %.6f %.6f\n",
|
||||
fprintf( fp, "w_node %.10f %.10f %.10f\n",
|
||||
west_nodes[i].x(), west_nodes[i].y(),
|
||||
west_nodes[i].z() );
|
||||
fprintf( fp, "w_normal %.6f %.6f %.6f\n",
|
||||
fprintf( fp, "w_normal %.10f %.10f %.10f\n",
|
||||
west_normals[i].x(), west_normals[i].y(),
|
||||
west_normals[i].z() );
|
||||
}
|
||||
|
@ -642,28 +637,28 @@ void TGMatch::write_shared( TGConstruct& c ) {
|
|||
for ( int i = 0; i < (int)north_segs.size(); ++i ) {
|
||||
p1 = nodes[ north_segs[i].get_n1() ];
|
||||
p2 = nodes[ north_segs[i].get_n2() ];
|
||||
fprintf( fp, "n_seg %.6f %.6f %.6f %.6f\n",
|
||||
fprintf( fp, "n_seg %.10f %.10f %.10f %.10f\n",
|
||||
p1.x(), p1.y(), p2.x(), p2.y() );
|
||||
}
|
||||
|
||||
for ( int i = 0; i < (int)south_segs.size(); ++i ) {
|
||||
p1 = nodes[ south_segs[i].get_n1() ];
|
||||
p2 = nodes[ south_segs[i].get_n2() ];
|
||||
fprintf( fp, "s_seg %.6f %.6f %.6f %.6f\n",
|
||||
fprintf( fp, "s_seg %.10f %.10f %.10f %.10f\n",
|
||||
p1.x(), p1.y(), p2.x(), p2.y() );
|
||||
}
|
||||
|
||||
for ( int i = 0; i < (int)east_segs.size(); ++i ) {
|
||||
p1 = nodes[ east_segs[i].get_n1() ];
|
||||
p2 = nodes[ east_segs[i].get_n2() ];
|
||||
fprintf( fp, "e_seg %.6f %.6f %.6f %.6f\n",
|
||||
fprintf( fp, "e_seg %.10f %.10f %.10f %.10f\n",
|
||||
p1.x(), p1.y(), p2.x(), p2.y() );
|
||||
}
|
||||
|
||||
for ( int i = 0; i < (int)west_segs.size(); ++i ) {
|
||||
p1 = nodes[ west_segs[i].get_n1() ];
|
||||
p2 = nodes[ west_segs[i].get_n2() ];
|
||||
fprintf( fp, "w_seg %.6f %.6f %.6f %.6f\n",
|
||||
fprintf( fp, "w_seg %.10f %.10f %.10f %.10f\n",
|
||||
p1.x(), p1.y(), p2.x(), p2.y() );
|
||||
}
|
||||
#endif
|
||||
|
@ -688,9 +683,9 @@ void insert_normal( point_list& normals, Point3D n, int i ) {
|
|||
}
|
||||
|
||||
// Just add nodes and normals to the node list
|
||||
void TGMatch::add_shared_nodes( TGConstruct& c ) {
|
||||
void TGMatch::add_shared_nodes( TGConstruct* c ) {
|
||||
TGNodes* nodes;
|
||||
nodes = c.get_nodes();
|
||||
nodes = c->get_nodes();
|
||||
|
||||
cout << " BEFORE ADDING SHARED NODES: " << nodes->size() << endl;
|
||||
|
||||
|
@ -739,7 +734,7 @@ void TGMatch::add_shared_nodes( TGConstruct& c ) {
|
|||
|
||||
// reassemble the tile pieces (combining the shared data and our own
|
||||
// data)
|
||||
void TGMatch::assemble_tile( TGConstruct& c ) {
|
||||
void TGMatch::assemble_tile( TGConstruct* c ) {
|
||||
int i;
|
||||
TGTriNodes new_nodes;
|
||||
new_nodes.clear();
|
||||
|
@ -824,7 +819,7 @@ void TGMatch::assemble_tile( TGConstruct& c ) {
|
|||
|
||||
// add the body segments
|
||||
|
||||
point_list geod_nodes = c.get_geod_nodes();
|
||||
point_list geod_nodes = c->get_geod_nodes();
|
||||
|
||||
TGTriSeg seg;
|
||||
Point3D p1, p2;
|
||||
|
|
|
@ -83,35 +83,35 @@ public:
|
|||
// load any previously existing shared data from all neighbors (if
|
||||
// shared data for a component exists set that components flag to
|
||||
// true
|
||||
void load_neighbor_shared( TGConstruct& c );
|
||||
void load_neighbor_shared( SGBucket b, std::string base );
|
||||
|
||||
// try to load any missing shared data from our own shared data file
|
||||
void load_missing_shared( TGConstruct& c );
|
||||
void load_missing_shared( SGBucket b, std::string base );
|
||||
|
||||
// scan the specified share file for the specified information
|
||||
void scan_share_file( const std::string& dir, const SGBucket& b,
|
||||
neighbor_type search, neighbor_type dest );
|
||||
|
||||
// try to find info for the specified shared component
|
||||
void load_shared( const TGConstruct& c, neighbor_type n );
|
||||
void load_shared( SGBucket b, std::string base, neighbor_type n );
|
||||
|
||||
// NEW TILE MATCHING - PRE TRIANGULATION
|
||||
// Just add nodes and normals to the node list
|
||||
void add_shared_nodes( TGConstruct& c );
|
||||
void add_shared_nodes( TGConstruct* c );
|
||||
|
||||
// split up the tile between the shared edge points, normals, and
|
||||
// segments and the body. This must be done after calling
|
||||
// load_neighbor_data() and will ignore any shared data from the
|
||||
// current tile that already exists from a neighbor.
|
||||
void split_tile( TGConstruct& c );
|
||||
void split_tile( SGBucket b, TGConstruct* c );
|
||||
|
||||
// write the new shared edge points, normals, and segments for
|
||||
// this tile
|
||||
void write_shared( TGConstruct& c );
|
||||
void write_shared( SGBucket b, TGConstruct* c );
|
||||
|
||||
// reassemble the tile pieces (combining the shared data and our
|
||||
// own data)
|
||||
void assemble_tile( TGConstruct& c );
|
||||
void assemble_tile( TGConstruct* c );
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
|
||||
|
||||
add_library(Triangulate STATIC
|
||||
triangle.cxx triangle.hxx
|
||||
trieles.cxx trieles.hxx
|
||||
)
|
|
@ -1,567 +0,0 @@
|
|||
// triangle.cxx -- "Triangle" interface class
|
||||
//
|
||||
// Written by Curtis Olson, started March 1999.
|
||||
//
|
||||
// Copyright (C) 1999 Curtis L. Olson - http://www.flightgear.org/~curt
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
// $Id: triangle.cxx,v 1.25 2005-10-31 18:45:19 curt Exp $
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include <Geometry/poly_support.hxx>
|
||||
#include <Polygon/polygon.hxx>
|
||||
#include <Polygon/superpoly.hxx>
|
||||
#include <TriangleJRS/tri_support.h>
|
||||
|
||||
#include "triangle.hxx"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::string;
|
||||
|
||||
|
||||
// Constructor
|
||||
TGTriangle::TGTriangle( void ) {
|
||||
}
|
||||
|
||||
|
||||
// Destructor
|
||||
TGTriangle::~TGTriangle( void ) {
|
||||
}
|
||||
|
||||
|
||||
// populate this class based on the specified gpc_polys list
|
||||
int
|
||||
TGTriangle::build( const point_list& corner_list,
|
||||
const point_list& fit_list,
|
||||
const TGPolyList& gpc_polys )
|
||||
{
|
||||
int debug_counter = 0;
|
||||
int index;
|
||||
int i;
|
||||
|
||||
in_nodes.clear();
|
||||
in_segs.clear();
|
||||
|
||||
// Point3D junkp;
|
||||
// int junkc = 0;
|
||||
// FILE *junkfp;
|
||||
|
||||
// traverse the array corner and fit lists and gpc_polys building a
|
||||
// unified node list and converting the polygons so that they
|
||||
// reference the node list by index (starting at zero) rather than
|
||||
// listing the points explicitely
|
||||
|
||||
// first the corners since these are important
|
||||
for ( i = 0; i < (int)corner_list.size(); ++i ) {
|
||||
Point3D p = corner_list[i];
|
||||
p.setz( -9999.0 );
|
||||
index = in_nodes.unique_add( p );
|
||||
}
|
||||
|
||||
// next process the polygons
|
||||
TGSuperPoly sp;
|
||||
TGPolygon gpc_poly;
|
||||
const_superpoly_list_iterator current, last;
|
||||
|
||||
// process polygons in priority order
|
||||
cout << "prepairing node list and polygons" << endl;
|
||||
|
||||
for ( i = 0; i < TG_MAX_AREA_TYPES; ++i ) {
|
||||
polylist[i].clear();
|
||||
|
||||
cout << "area type = " << i << " polys = " << gpc_polys.superpolys[i].size() << endl;
|
||||
debug_counter = 0;
|
||||
current = gpc_polys.superpolys[i].begin();
|
||||
last = gpc_polys.superpolys[i].end();
|
||||
for ( ; current != last; ++current ) {
|
||||
sp = *current;
|
||||
gpc_poly = sp.get_poly();
|
||||
|
||||
// cout << "processing a polygon, contours = " << gpc_poly.contours() << endl;
|
||||
|
||||
if (gpc_poly.contours() <= 0 ) {
|
||||
cout << "FATAL ERROR! no contours in this polygon" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
int j;
|
||||
for ( j = 0; j < gpc_poly.contours(); ++j ) {
|
||||
// cout << " processing contour = " << j << ", nodes = " << gpc_poly.contour_size( j ) << ", hole = " << gpc_poly.get_hole_flag( j ) << endl;
|
||||
|
||||
/*
|
||||
char junkn[256];
|
||||
sprintf(junkn, "c%d", j);
|
||||
gpc_poly.write_contour( j, junkn );
|
||||
*/
|
||||
|
||||
for ( int k = 0; k < gpc_poly.contour_size( j ); k++ ) {
|
||||
Point3D p = gpc_poly.get_pt( j, k );
|
||||
index = in_nodes.unique_add( p );
|
||||
// junkp = in_nodes.get_node( index );
|
||||
// fprintf(junkfp, "%.4f %.4f\n", junkp.x(), junkp.y());
|
||||
// cout << " - " << index << endl;
|
||||
}
|
||||
// fprintf(junkfp, "%.4f %.4f\n",
|
||||
// gpc_poly->contour[j].vertex[0].x,
|
||||
// gpc_poly->contour[j].vertex[0].y);
|
||||
// fclose(junkfp);
|
||||
}
|
||||
|
||||
/* if ( i == OceanArea ) {
|
||||
cout << "temporary exit point" << endl;
|
||||
exit(-1);
|
||||
} */
|
||||
|
||||
// for each contour, calculate a point inside (but not
|
||||
// also inside any interior contours
|
||||
|
||||
// new way
|
||||
|
||||
// try to make sure our polygons aren't goofy
|
||||
#if 0
|
||||
// CLO 09/18/2001: if we snap polygons including holes
|
||||
// will this screw up the edge matching when objects are
|
||||
// inserted into their holes?
|
||||
gpc_poly = snap(gpc_poly, 0.000001);
|
||||
#endif
|
||||
gpc_poly = remove_dups( gpc_poly );
|
||||
gpc_poly = reduce_degeneracy( gpc_poly );
|
||||
gpc_poly = reduce_degeneracy( gpc_poly ); // can happen multiple time
|
||||
gpc_poly = remove_dups( gpc_poly );
|
||||
gpc_poly = remove_bad_contours( gpc_poly );
|
||||
gpc_poly = remove_cycles( gpc_poly );
|
||||
|
||||
// cout << "after sanity checks, contours = " << gpc_poly.contours() << endl;
|
||||
|
||||
/*
|
||||
for ( j = 0; j < gpc_poly.contours(); ++j ) {
|
||||
cout << " contour " << j << " size = "
|
||||
<< gpc_poly.contour_size( j ) << endl;
|
||||
char junkn[256];
|
||||
sprintf(junkn, "d%d", j);
|
||||
gpc_poly.write_contour( j, junkn );
|
||||
}
|
||||
*/
|
||||
|
||||
// cout << "before calc_points_inside()" << endl;
|
||||
calc_points_inside( gpc_poly );
|
||||
// cout << "after calc_points_inside()" << endl;
|
||||
|
||||
#if 0
|
||||
// old way
|
||||
Point3D inside_pt;
|
||||
for ( j = 0; j < gpc_poly.contours(); ++j ) {
|
||||
inside_pt = calc_point_inside( gpc_poly, j, in_nodes );
|
||||
gpc_poly.set_point_inside( j, inside_pt );
|
||||
}
|
||||
#endif
|
||||
|
||||
polylist[i].push_back( gpc_poly );
|
||||
|
||||
#if 0
|
||||
// temporary ... write out hole/polygon info for debugging
|
||||
for ( j = 0; j < (int)gpc_poly.contours(); ++j ) {
|
||||
char pname[256];
|
||||
sprintf(pname, "poly%02d-%02d-%02d", i, debug_counter, j);
|
||||
cout << "writing to " << pname << endl;
|
||||
FILE *fp = fopen( pname, "w" );
|
||||
Point3D point;
|
||||
for ( int k = 0; k < gpc_poly.contour_size( j ); ++k ) {
|
||||
point = gpc_poly.get_pt( j, k );
|
||||
fprintf( fp, "%.6f %.6f\n", point.x(), point.y() );
|
||||
}
|
||||
point = gpc_poly.get_pt( j, 0 );
|
||||
fprintf( fp, "%.6f %.6f\n", point.x(), point.y() );
|
||||
fclose(fp);
|
||||
|
||||
char hname[256];
|
||||
sprintf(hname, "hole%02d-%02d-%02d", i, debug_counter, j);
|
||||
FILE *fh = fopen( hname, "w" );
|
||||
point = gpc_poly.get_point_inside( j );
|
||||
fprintf( fh, "%.6f %.6f\n", point.x(), point.y() );
|
||||
fclose(fh);
|
||||
}
|
||||
|
||||
// cout << "type a letter + enter to continue: ";
|
||||
// string input;
|
||||
// cin >> input;
|
||||
#endif
|
||||
|
||||
++debug_counter;
|
||||
}
|
||||
}
|
||||
|
||||
// last, do the rest of the height nodes
|
||||
for ( i = 0; i < (int)fit_list.size(); ++i ) {
|
||||
index = in_nodes.course_add( fit_list[i] );
|
||||
}
|
||||
|
||||
for ( i = 0; i < TG_MAX_AREA_TYPES; ++i ) {
|
||||
if ( polylist[i].size() ) {
|
||||
cout << get_area_name((AreaType)i) << " = "
|
||||
<< polylist[i].size() << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// traverse the polygon lists and build the segment (edge) list
|
||||
// that is used by the "Triangle" lib.
|
||||
|
||||
cout << "building segment list" << endl;
|
||||
int i1, i2;
|
||||
Point3D p1, p2;
|
||||
point_list node_list = in_nodes.get_node_list();
|
||||
TGPolygon poly;
|
||||
|
||||
for ( i = 0; i < TG_MAX_AREA_TYPES; ++i ) {
|
||||
cout << "area type = " << i << endl;
|
||||
poly_list_iterator tp_current, tp_last;
|
||||
tp_current = polylist[i].begin();
|
||||
tp_last = polylist[i].end();
|
||||
|
||||
// process each polygon in list
|
||||
for ( ; tp_current != tp_last; ++tp_current ) {
|
||||
poly = *tp_current;
|
||||
// cout << " processing a polygon with contours = " << poly.contours() << endl;
|
||||
for ( int j = 0; j < (int)poly.contours(); ++j) {
|
||||
for ( int k = 0; k < (int)(poly.contour_size(j) - 1); ++k ) {
|
||||
p1 = poly.get_pt( j, k );
|
||||
p2 = poly.get_pt( j, k + 1 );
|
||||
i1 = in_nodes.find( p1 );
|
||||
i2 = in_nodes.find( p2 );
|
||||
// calc_line_params(i1, i2, &m, &b);
|
||||
if ( is_hole_area(i) ) {
|
||||
// mark as a boundary
|
||||
in_segs.unique_divide_and_add( node_list,
|
||||
TGTriSeg(i1, i2, 1) );
|
||||
} else {
|
||||
// non boundary
|
||||
in_segs.unique_divide_and_add( node_list,
|
||||
TGTriSeg(i1, i2, 0) );
|
||||
}
|
||||
}
|
||||
p1 = poly.get_pt( j, 0 );
|
||||
p2 = poly.get_pt( j, poly.contour_size(j) - 1 );
|
||||
i1 = in_nodes.find( p1 );
|
||||
i2 = in_nodes.find( p2 );
|
||||
// calc_line_params(i1, i2, &m, &b);
|
||||
if ( is_hole_area(i) ) {
|
||||
// mark as a boundary
|
||||
in_segs.unique_divide_and_add( node_list,
|
||||
TGTriSeg(i1, i2, 1) );
|
||||
} else {
|
||||
// non boundary
|
||||
in_segs.unique_divide_and_add( node_list,
|
||||
TGTriSeg(i1, i2, 0) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// populate this class based on the specified gpc_polys list
|
||||
int TGTriangle::rebuild( TGConstruct& c ) {
|
||||
in_nodes.clear();
|
||||
in_segs.clear();
|
||||
|
||||
#if 0
|
||||
in_nodes = c.get_tri_nodes();
|
||||
in_segs = c.get_tri_segs();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Front end triangulator for polygon list. Allocates and builds up
|
||||
// all the needed structures for the triangulator, runs it, copies the
|
||||
// results, and frees all the data structures used by the
|
||||
// triangulator. "pass" can be 1 or 2. 1 = first pass which
|
||||
// generates extra nodes for a better triangulation. 2 = second pass
|
||||
// after split/reassem where we don't want any extra nodes generated.
|
||||
|
||||
int TGTriangle::run_triangulate( double angle, const int pass ) {
|
||||
TGPolygon poly;
|
||||
Point3D p;
|
||||
struct triangulateio in, out, vorout;
|
||||
int counter;
|
||||
int i, j;
|
||||
|
||||
|
||||
// point list
|
||||
point_list node_list = in_nodes.get_node_list();
|
||||
|
||||
cout << "TRIANGULATE : NUMBER OF INPUT NODES: " << node_list.size() << endl;
|
||||
|
||||
in.numberofpoints = node_list.size();
|
||||
in.pointlist = (REAL *) malloc(in.numberofpoints * 2 * sizeof(REAL));
|
||||
|
||||
for ( i = 0; i < in.numberofpoints; ++i ) {
|
||||
in.pointlist[2*i] = node_list[i].x();
|
||||
in.pointlist[2*i + 1] = node_list[i].y();
|
||||
}
|
||||
|
||||
in.numberofpointattributes = 1;
|
||||
in.pointattributelist = (REAL *) malloc(in.numberofpoints *
|
||||
in.numberofpointattributes *
|
||||
sizeof(REAL));
|
||||
for ( i = 0; i < in.numberofpoints * in.numberofpointattributes; ++i) {
|
||||
in.pointattributelist[i] = node_list[i].z();
|
||||
}
|
||||
|
||||
in.pointmarkerlist = (int *) malloc(in.numberofpoints * sizeof(int));
|
||||
for ( i = 0; i < in.numberofpoints; ++i) {
|
||||
in.pointmarkerlist[i] = 0;
|
||||
}
|
||||
|
||||
// triangle list
|
||||
in.numberoftriangles = 0;
|
||||
|
||||
// segment 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 *) malloc(in.numberofsegments * sizeof(int));
|
||||
|
||||
triseg_list_iterator s_current, s_last;
|
||||
s_current = seg_list.begin();
|
||||
s_last = seg_list.end();
|
||||
counter = 0;
|
||||
for ( ; s_current != s_last; ++s_current ) {
|
||||
in.segmentlist[counter++] = s_current->get_n1();
|
||||
in.segmentlist[counter++] = s_current->get_n2();
|
||||
}
|
||||
s_current = seg_list.begin();
|
||||
s_last = seg_list.end();
|
||||
counter = 0;
|
||||
for ( ; s_current != s_last; ++s_current ) {
|
||||
in.segmentmarkerlist[counter++] = s_current->get_boundary_marker();
|
||||
}
|
||||
|
||||
// hole list (make holes for airport ignore areas)
|
||||
poly_list_iterator h_current, h_last;
|
||||
in.numberofholes = 0;
|
||||
for ( i = 0; i < TG_MAX_AREA_TYPES; i++) {
|
||||
if ( is_hole_area( i ) ) {
|
||||
h_current = polylist[i].begin();
|
||||
h_last = polylist[i].end();
|
||||
for ( ; h_current != h_last; ++h_current ) {
|
||||
poly = *h_current;
|
||||
for ( j = 0; j < poly.contours(); ++j ) {
|
||||
in.numberofholes++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
in.holelist = (REAL *) malloc(in.numberofholes * 2 * sizeof(REAL));
|
||||
|
||||
counter = 0;
|
||||
for ( i = 0; i < TG_MAX_AREA_TYPES; i++) {
|
||||
if ( is_hole_area( i ) ) {
|
||||
h_current = polylist[i].begin();
|
||||
h_last = polylist[i].end();
|
||||
for ( ; h_current != h_last; ++h_current ) {
|
||||
poly = *h_current;
|
||||
for ( j = 0; j < poly.contours(); ++j ) {
|
||||
p = poly.get_point_inside( j );
|
||||
in.holelist[counter++] = p.x();
|
||||
in.holelist[counter++] = p.y();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// region list
|
||||
in.numberofregions = 0;
|
||||
for ( i = 0; i < TG_MAX_AREA_TYPES; ++i ) {
|
||||
if ( ! is_hole_area( i ) ) {
|
||||
poly_list_iterator h_current, h_last;
|
||||
h_current = polylist[i].begin();
|
||||
h_last = polylist[i].end();
|
||||
for ( ; h_current != h_last; ++h_current ) {
|
||||
poly = *h_current;
|
||||
for ( j = 0; j < poly.contours(); ++j ) {
|
||||
if ( ! poly.get_hole_flag( j ) ) {
|
||||
++in.numberofregions;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
in.regionlist = (REAL *) malloc(in.numberofregions * 4 * sizeof(REAL));
|
||||
counter = 0;
|
||||
for ( i = 0; i < TG_MAX_AREA_TYPES; ++i ) {
|
||||
if ( ! is_hole_area( i ) ) {
|
||||
poly_list_iterator h_current, h_last;
|
||||
h_current = polylist[(int)i].begin();
|
||||
h_last = polylist[(int)i].end();
|
||||
for ( ; h_current != h_last; ++h_current ) {
|
||||
poly = *h_current;
|
||||
for ( j = 0; j < poly.contours(); ++j ) {
|
||||
if ( ! poly.get_hole_flag( j ) ) {
|
||||
p = poly.get_point_inside( j );
|
||||
cout << "Region point = " << p << endl;
|
||||
in.regionlist[counter++] = p.x(); // x coord
|
||||
in.regionlist[counter++] = p.y(); // y coord
|
||||
in.regionlist[counter++] = i; // region attribute
|
||||
in.regionlist[counter++] = -1.0; // area constraint
|
||||
// (unused)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// prep the output structures
|
||||
out.pointlist = (REAL *) NULL; // Not needed if -N switch used.
|
||||
// Not needed if -N switch used or number of point attributes is zero:
|
||||
out.pointattributelist = (REAL *) NULL;
|
||||
out.pointmarkerlist = (int *) NULL; // Not needed if -N or -B switch used.
|
||||
out.trianglelist = (int *) NULL; // Not needed if -E switch used.
|
||||
// Not needed if -E switch used or number of triangle attributes is zero:
|
||||
out.triangleattributelist = (REAL *) NULL;
|
||||
out.neighborlist = (int *) NULL; // Needed only if -n switch used.
|
||||
// Needed only if segments are output (-p or -c) and -P not used:
|
||||
out.segmentlist = (int *) NULL;
|
||||
// Needed only if segments are output (-p or -c) and -P and -B not used:
|
||||
out.segmentmarkerlist = (int *) NULL;
|
||||
out.edgelist = (int *) NULL; // Needed only if -e switch used.
|
||||
out.edgemarkerlist = (int *) NULL; // Needed if -e used and -B not used.
|
||||
|
||||
vorout.pointlist = (REAL *) NULL; // Needed only if -v switch used.
|
||||
// Needed only if -v switch used and number of attributes is not zero:
|
||||
vorout.pointattributelist = (REAL *) NULL;
|
||||
vorout.edgelist = (int *) NULL; // Needed only if -v switch used.
|
||||
vorout.normlist = (REAL *) NULL; // Needed only if -v switch used.
|
||||
|
||||
// TEMPORARY
|
||||
// write_tri_data(&in); exit(1);
|
||||
|
||||
// Triangulate the points. Switches are chosen to read and write
|
||||
// a PSLG (p), preserve the convex hull (c), number everything
|
||||
// from zero (z), assign a regional attribute to each element (A),
|
||||
// and produce an edge list (e), and a triangle neighbor list (n).
|
||||
|
||||
string tri_options;
|
||||
if ( pass == 1 ) {
|
||||
// use a quality value of 10 (q10) meaning no interior
|
||||
// triangle angles less than 10 degrees
|
||||
// tri_options = "pczAen";
|
||||
#if 0
|
||||
if ( angle < 0.00001 ) {
|
||||
tri_options = "pczAen";
|
||||
} else {
|
||||
char angle_str[256];
|
||||
sprintf( angle_str, "%.2f", angle );
|
||||
tri_options = "pczq";
|
||||
tri_options += angle_str;
|
||||
tri_options += "Aen";
|
||||
}
|
||||
#else
|
||||
|
||||
// TEST TEST TEST : NO ADDING POINTS
|
||||
tri_options = "pzenYYQ";
|
||||
|
||||
#endif
|
||||
|
||||
// // string tri_options = "pzAen";
|
||||
// // string tri_options = "pczq15S400Aen";
|
||||
} else if ( pass == 2 ) {
|
||||
// no new points on boundary (Y), no internal segment
|
||||
// splitting (YY), no quality refinement (q)
|
||||
tri_options = "pczYYAen";
|
||||
} else {
|
||||
cout << "unknown pass number = " << pass
|
||||
<< " in TGTriangle::run_triangulate()" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
cout << "Triangulation with options = " << tri_options << endl;
|
||||
|
||||
triangulate( (char *)tri_options.c_str(), &in, &out, &vorout );
|
||||
|
||||
// TEMPORARY
|
||||
// write_tri_data(&out);
|
||||
|
||||
// now copy the results back into the corresponding TGTriangle
|
||||
// structures
|
||||
|
||||
cout << "TRIANGULATE : NUMBER OF OUTPUT NODES: " << out.numberofpoints << endl;
|
||||
|
||||
// nodes
|
||||
out_nodes.clear();
|
||||
for ( i = 0; i < out.numberofpoints; ++i ) {
|
||||
Point3D p( out.pointlist[2*i], out.pointlist[2*i + 1],
|
||||
out.pointattributelist[i] );
|
||||
out_nodes.simple_add( p );
|
||||
}
|
||||
|
||||
// segments
|
||||
out_segs.clear();
|
||||
for ( i = 0; i < out.numberofsegments; ++i ) {
|
||||
out_segs.unique_add( TGTriSeg( out.segmentlist[2*i],
|
||||
out.segmentlist[2*i+1],
|
||||
out.segmentmarkerlist[i] ) );
|
||||
}
|
||||
|
||||
// triangles
|
||||
elelist.clear();
|
||||
int n1, n2, n3;
|
||||
double attribute;
|
||||
for ( i = 0; i < out.numberoftriangles; ++i ) {
|
||||
n1 = out.trianglelist[i * 3];
|
||||
n2 = out.trianglelist[i * 3 + 1];
|
||||
n3 = out.trianglelist[i * 3 + 2];
|
||||
if ( out.numberoftriangleattributes > 0 ) {
|
||||
attribute = out.triangleattributelist[i];
|
||||
} else {
|
||||
attribute = 0.0;
|
||||
}
|
||||
// cout << "triangle = " << n1 << " " << n2 << " " << n3 << endl;
|
||||
|
||||
elelist.push_back( TGTriEle( n1, n2, n3, attribute ) );
|
||||
}
|
||||
|
||||
// free mem allocated to the "Triangle" structures
|
||||
free(in.pointlist);
|
||||
free(in.pointattributelist);
|
||||
free(in.pointmarkerlist);
|
||||
free(in.regionlist);
|
||||
free(out.pointlist);
|
||||
free(out.pointattributelist);
|
||||
free(out.pointmarkerlist);
|
||||
free(out.trianglelist);
|
||||
free(out.triangleattributelist);
|
||||
// free(out.trianglearealist);
|
||||
free(out.neighborlist);
|
||||
free(out.segmentlist);
|
||||
free(out.segmentmarkerlist);
|
||||
free(out.edgelist);
|
||||
free(out.edgemarkerlist);
|
||||
free(vorout.pointlist);
|
||||
free(vorout.pointattributelist);
|
||||
free(vorout.edgelist);
|
||||
free(vorout.normlist);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,105 +0,0 @@
|
|||
// triangle.hxx -- "Triangle" interface class
|
||||
//
|
||||
// Written by Curtis Olson, started March 1999.
|
||||
//
|
||||
// Copyright (C) 1999 Curtis L. Olson - http://www.flightgear.org/~curt
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
// $Id: triangle.hxx,v 1.7 2004-11-19 22:25:50 curt Exp $
|
||||
|
||||
|
||||
#ifndef _TRIANGLE_HXX
|
||||
#define _TRIANGLE_HXX
|
||||
|
||||
|
||||
#ifndef __cplusplus
|
||||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
#include <Geometry/point3d.hxx>
|
||||
|
||||
#include <Array/array.hxx>
|
||||
#include <Main/construct.hxx>
|
||||
|
||||
#include <Geometry/trinodes.hxx>
|
||||
#include <Geometry/trisegs.hxx>
|
||||
#include <Clipper/priorities.hxx>
|
||||
#include <Polygon/polygon.hxx>
|
||||
|
||||
#define REAL double
|
||||
extern "C" {
|
||||
#include <TriangleJRS/triangle.h>
|
||||
}
|
||||
|
||||
#include "trieles.hxx"
|
||||
|
||||
|
||||
class TGTriangle {
|
||||
|
||||
private:
|
||||
|
||||
// list of nodes
|
||||
TGTriNodes in_nodes;
|
||||
TGTriNodes out_nodes;
|
||||
|
||||
// list of segments
|
||||
TGTriSegments in_segs;
|
||||
TGTriSegments out_segs;
|
||||
|
||||
// polygon list
|
||||
poly_list polylist[TG_MAX_AREA_TYPES];
|
||||
|
||||
// triangle list
|
||||
triele_list elelist;
|
||||
|
||||
public:
|
||||
|
||||
// Constructor and destructor
|
||||
TGTriangle( void );
|
||||
~TGTriangle( void );
|
||||
|
||||
// add nodes from the dem fit
|
||||
int add_nodes();
|
||||
|
||||
// populate this class based on the specified gpc_polys list
|
||||
int build( const point_list& corner_list,
|
||||
const point_list& fit_list,
|
||||
const TGPolyList& gpc_polys );
|
||||
|
||||
// populate this class based on the specified gpc_polys list
|
||||
int rebuild( TGConstruct& c );
|
||||
|
||||
// Front end triangulator for polygon list. Allocates and builds
|
||||
// up all the needed structures for the triangulator, runs it,
|
||||
// copies the results, and frees all the data structures used by
|
||||
// the triangulator. "pass" can be 1 or 2. 1 = first pass which
|
||||
// generates extra nodes for a better triangulation. 2 = second
|
||||
// pass after split/reassem where we don't want any extra nodes
|
||||
// generated.
|
||||
int run_triangulate( double angle, const int pass );
|
||||
|
||||
inline TGTriNodes get_out_nodes() const { return out_nodes; }
|
||||
inline size_t get_out_nodes_size() const { return out_nodes.size(); }
|
||||
inline triele_list get_elelist() const { return elelist; }
|
||||
inline TGTriSegments get_out_segs() const { return out_segs; }
|
||||
};
|
||||
|
||||
|
||||
#endif // _TRIANGLE_HXX
|
||||
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
// trieles.cxx -- "Triangle" element management class
|
||||
//
|
||||
// Written by Curtis Olson, started March 1999.
|
||||
//
|
||||
// Copyright (C) 1999 Curtis L. Olson - http://www.flightgear.org/~curt
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
// $Id: trieles.cxx,v 1.2 2004-11-19 22:25:50 curt Exp $
|
||||
|
||||
|
||||
#include "trieles.hxx"
|
||||
|
||||
|
|
@ -136,7 +136,9 @@ void add_intermediate_tgnodes( int contour, const Point3D& start,
|
|||
add_intermediate_tgnodes( contour, start, new_pt, nodes, result );
|
||||
|
||||
result->add_node( contour, new_pt );
|
||||
SG_LOG(SG_GENERAL, SG_INFO, " added = " << new_pt);
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, " added = " << new_pt);
|
||||
|
||||
// DEBUG : Was new node shared?
|
||||
|
||||
add_intermediate_tgnodes( contour, new_pt, end, nodes, result );
|
||||
}
|
||||
|
|
|
@ -35,8 +35,6 @@
|
|||
#include <Polygon/polygon.hxx>
|
||||
#include <Polygon/chop.hxx>
|
||||
|
||||
#include <Triangulate/trieles.hxx>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
|
|
|
@ -35,8 +35,8 @@
|
|||
#include <simgear/math/sg_types.hxx>
|
||||
|
||||
#include <Polygon/polygon.hxx>
|
||||
#include <Triangulate/trieles.hxx>
|
||||
|
||||
#include "trieles.hxx"
|
||||
#include "trinodes.hxx"
|
||||
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ int TGNodes::unique_add( const Point3D& p ) {
|
|||
last = tg_node_list.end();
|
||||
|
||||
for ( ; current != last; ++current ) {
|
||||
if ( close_enough_3d(p, (*current).GetPosition() ) ) {
|
||||
if ( close_enough_2d(p, (*current).GetPosition() ) ) {
|
||||
// cout << "found an existing match!" << endl;
|
||||
return counter;
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ int TGNodes::unique_add_fixed_elevation( const Point3D& p ) {
|
|||
last = tg_node_list.end();
|
||||
|
||||
for ( ; current != last; ++current ) {
|
||||
if ( close_enough_3d(p, (*current).GetPosition() ) ) {
|
||||
if ( close_enough_2d(p, (*current).GetPosition() ) ) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "Adding fixed elev node : node already exists at " << counter << " old position is " << (*current).GetPosition() << " new position is " << p );
|
||||
|
||||
// Force the match to our position, and mark as fixed
|
||||
|
@ -168,6 +168,7 @@ point_list TGNodes::get_normals( void ) const {
|
|||
return points;
|
||||
}
|
||||
|
||||
#if 0
|
||||
bool TGNodes::LookupFixedElevation( Point3D p, double* z )
|
||||
{
|
||||
int index = find( p );
|
||||
|
@ -183,3 +184,4 @@ bool TGNodes::LookupFixedElevation( Point3D p, double* z )
|
|||
|
||||
return found;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -108,7 +108,7 @@ public:
|
|||
// tolerance as unique_add(). Returns -1 if not found.
|
||||
int find( const Point3D& p ) const;
|
||||
|
||||
bool LookupFixedElevation( Point3D p, double* z );
|
||||
// bool LookupFixedElevation( Point3D p, double* z );
|
||||
void SetElevation( int idx, double z ) { tg_node_list[idx].SetElevation( z ); }
|
||||
|
||||
// return the master node list
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
#include <simgear/math/sg_types.hxx>
|
||||
|
||||
#include <Triangulate/trieles.hxx>
|
||||
#include <Geometry/trieles.hxx>
|
||||
|
||||
typedef std::vector < int_list > opt_list;
|
||||
typedef opt_list::iterator opt_list_iterator;
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
#include <simgear/math/sg_types.hxx>
|
||||
|
||||
#include <Triangulate/trieles.hxx>
|
||||
#include <Geometry/trieles.hxx>
|
||||
|
||||
typedef std::vector < int_list > opt_list;
|
||||
typedef opt_list::iterator opt_list_iterator;
|
||||
|
|
|
@ -45,4 +45,5 @@ void TGSuperPoly::erase()
|
|||
normals.erase();
|
||||
texcoords.erase();
|
||||
tris.erase();
|
||||
face_normals.clear();
|
||||
}
|
||||
|
|
|
@ -42,12 +42,13 @@ class TGSuperPoly {
|
|||
|
||||
private:
|
||||
|
||||
std::string material; // material/texture name
|
||||
TGPolygon poly; // master polygon
|
||||
TGPolygon normals; // corresponding normals
|
||||
TGPolygon texcoords; // corresponding texture coordinates
|
||||
TGPolygon tris; // triangulation
|
||||
std::string flag; // For various potential record keeping needs
|
||||
std::string material; // material/texture name
|
||||
TGPolygon poly; // master polygon
|
||||
TGPolygon normals; // corresponding normals
|
||||
TGPolygon texcoords; // corresponding texture coordinates
|
||||
TGPolygon tris; // triangulation
|
||||
point_list face_normals; // triangle normals
|
||||
std::string flag; // For various potential record keeping needs
|
||||
|
||||
public:
|
||||
|
||||
|
|
Loading…
Reference in a new issue