Implemented shape file debug capability via command line options:
--debug-dir=pathname points to the debug root directory. each tile will create a sub directory in this existing directory. (default is '.') --debug-shapes=tileid:shape1,shape2,etc.. lists the shapes to debug within a tile example: if the tesselator crashes in shape id '123', you can rerun with --debug-shapes=2678440:337 implemented the same bounding box optimization from tesselate in FixTJunctions. Also fixed a bounding box issue that could cause some elevation points to be missed. brought in the latest version of clipper - and moved the #define to the construct header some debug cleanup (especially in polygon loading)
This commit is contained in:
parent
cf6d6f42b9
commit
5f83fe82c6
12 changed files with 259 additions and 184 deletions
|
@ -25,6 +25,9 @@
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
#include <simgear/compiler.h>
|
#include <simgear/compiler.h>
|
||||||
|
@ -53,7 +56,6 @@ double gSnap = 0.00000001; // approx 1 mm
|
||||||
static const double cover_size = 1.0 / 120.0;
|
static const double cover_size = 1.0 / 120.0;
|
||||||
static const double half_cover_size = cover_size * 0.5;
|
static const double half_cover_size = cover_size * 0.5;
|
||||||
|
|
||||||
#define USE_CLIPPER (0)
|
|
||||||
|
|
||||||
// If we don't offset land use squares by some amount, then we can get
|
// If we don't offset land use squares by some amount, then we can get
|
||||||
// land use square boundaries coinciding with tile boundaries.
|
// land use square boundaries coinciding with tile boundaries.
|
||||||
|
@ -65,20 +67,12 @@ static const double half_cover_size = cover_size * 0.5;
|
||||||
// problem.
|
// problem.
|
||||||
static const double quarter_cover_size = cover_size * 0.25;
|
static const double quarter_cover_size = cover_size * 0.25;
|
||||||
|
|
||||||
|
|
||||||
// For debug:
|
|
||||||
void* ds_id = NULL; // If we are going to build shapefiles
|
|
||||||
void* l_id = NULL; // datasource and layer IDs
|
|
||||||
char ds_name[128]; // need to clean this up and add cmdline options
|
|
||||||
char layer_name[128];
|
|
||||||
char feature_name[128];
|
|
||||||
|
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
TGConstruct::TGConstruct():
|
TGConstruct::TGConstruct():
|
||||||
useUKGrid(false),
|
useUKGrid(false),
|
||||||
writeSharedEdges(true),
|
writeSharedEdges(true),
|
||||||
useOwnSharedEdges(false)
|
useOwnSharedEdges(false),
|
||||||
|
ds_id((void*)-1)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
@ -94,6 +88,64 @@ TGConstruct::~TGConstruct() {
|
||||||
nodes.clear();
|
nodes.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TGConstruct::set_debug( std::string path, std::vector<string> defs )
|
||||||
|
{
|
||||||
|
SG_LOG(SG_GENERAL, SG_ALERT, "Set debug Path " << path);
|
||||||
|
|
||||||
|
debug_path = path;
|
||||||
|
|
||||||
|
/* Find any ids for our tile */
|
||||||
|
for (unsigned int i=0; i< defs.size(); i++) {
|
||||||
|
string dsd = defs[i];
|
||||||
|
size_t d_pos = dsd.find(":");
|
||||||
|
string tile = dsd.substr(0, d_pos);
|
||||||
|
|
||||||
|
if( tile == bucket.gen_index_str() ) {
|
||||||
|
dsd.erase(0, d_pos+1);
|
||||||
|
std::stringstream ss(dsd);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
while (ss >> i)
|
||||||
|
{
|
||||||
|
SG_LOG(SG_GENERAL, SG_ALERT, "Adding debug file " << i);
|
||||||
|
|
||||||
|
debug_shapes.push_back(i);
|
||||||
|
|
||||||
|
if (ss.peek() == ',')
|
||||||
|
ss.ignore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TGConstruct::IsDebugShape( unsigned int id )
|
||||||
|
{
|
||||||
|
bool is_debug = false;
|
||||||
|
|
||||||
|
for (unsigned int i=0; i<debug_shapes.size(); i++) {
|
||||||
|
SG_LOG(SG_GENERAL, SG_ALERT, "have debug id " << debug_shapes[i] << " looking for " << id );
|
||||||
|
|
||||||
|
if ( debug_shapes[i] == id ) {
|
||||||
|
is_debug = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return is_debug;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TGConstruct::WriteDebugShape( const char* layer_name, unsigned int area, unsigned int shape )
|
||||||
|
{
|
||||||
|
ds_id = tgShapefileOpenDatasource( ds_name );
|
||||||
|
l_id = tgShapefileOpenLayer( ds_id, layer_name );
|
||||||
|
|
||||||
|
sprintf( feature_name, "%s_%d", get_area_name( area ).c_str(), polys_clipped.get_shape( area, shape ).id );
|
||||||
|
tgShapefileCreateFeature( ds_id, l_id, polys_in.get_mask(area, shape), feature_name );
|
||||||
|
|
||||||
|
// close after each write
|
||||||
|
ds_id = tgShapefileCloseDatasource( ds_id );
|
||||||
|
}
|
||||||
|
|
||||||
// STEP 1
|
// STEP 1
|
||||||
// Load elevation data from an Array file (a regular grid of elevation data)
|
// Load elevation data from an Array file (a regular grid of elevation data)
|
||||||
// and return list of fitted nodes.
|
// and return list of fitted nodes.
|
||||||
|
@ -153,6 +205,7 @@ bool TGConstruct::load_poly(const string& path) {
|
||||||
int hole_flag;
|
int hole_flag;
|
||||||
int num_polys;
|
int num_polys;
|
||||||
double startx, starty, startz, x, y, z, lastx, lasty, lastz;
|
double startx, starty, startz, x, y, z, lastx, lasty, lastz;
|
||||||
|
static unsigned int cur_id = 0;
|
||||||
|
|
||||||
sg_gzifstream in( path );
|
sg_gzifstream in( path );
|
||||||
|
|
||||||
|
@ -208,18 +261,11 @@ bool TGConstruct::load_poly(const string& path) {
|
||||||
// only allow 1000 shapes per material
|
// only allow 1000 shapes per material
|
||||||
int extension = polys_in.area_size( area ) / 1000;
|
int extension = polys_in.area_size( area ) / 1000;
|
||||||
|
|
||||||
SG_LOG( SG_CLIPPER, SG_INFO, "extension " << extension );
|
|
||||||
|
|
||||||
if (extension)
|
if (extension)
|
||||||
{
|
{
|
||||||
char buff[32];
|
char buff[32];
|
||||||
sprintf( buff, "%s_%d", get_area_name( area ).c_str(), extension );
|
sprintf( buff, "%s_%d", get_area_name( area ).c_str(), extension );
|
||||||
|
|
||||||
SG_LOG( SG_CLIPPER, SG_INFO, "buff " << buff );
|
|
||||||
|
|
||||||
material = buff;
|
material = buff;
|
||||||
|
|
||||||
SG_LOG( SG_CLIPPER, SG_INFO, "material " << material );
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -261,8 +307,6 @@ bool TGConstruct::load_poly(const string& path) {
|
||||||
|
|
||||||
in >> contours;
|
in >> contours;
|
||||||
|
|
||||||
SG_LOG( SG_CLIPPER, SG_INFO, "Loading " << path << ":" << poly_name << "-" << poly_type << " contours = " << contours );
|
|
||||||
|
|
||||||
poly.erase();
|
poly.erase();
|
||||||
|
|
||||||
for ( i = 0; i < contours; ++i ) {
|
for ( i = 0; i < contours; ++i ) {
|
||||||
|
@ -355,6 +399,8 @@ bool TGConstruct::load_poly(const string& path) {
|
||||||
|
|
||||||
// Once the full poly is loaded, build the clip mask
|
// Once the full poly is loaded, build the clip mask
|
||||||
shape.BuildMask();
|
shape.BuildMask();
|
||||||
|
shape.id = cur_id++;
|
||||||
|
|
||||||
polys_in.add_shape( area, shape );
|
polys_in.add_shape( area, shape );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -481,6 +527,8 @@ int TGConstruct::LoadLandclassPolys( void ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
simgear::PathList files = d.children(simgear::Dir::TYPE_FILE);
|
simgear::PathList files = d.children(simgear::Dir::TYPE_FILE);
|
||||||
|
SG_LOG( SG_CLIPPER, SG_INFO, "Loading " << files.size() << " polys from " << d.path() );
|
||||||
|
|
||||||
BOOST_FOREACH(const SGPath& p, files) {
|
BOOST_FOREACH(const SGPath& p, files) {
|
||||||
if (p.file_base() != tile_str) {
|
if (p.file_base() != tile_str) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -1267,17 +1315,6 @@ bool TGConstruct::ClipLandclassPolys( void ) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
if ( (i == 3) && (j == 137) ) {
|
|
||||||
SG_LOG( SG_CLIPPER, SG_INFO, "Error Poly\n" << tmp );
|
|
||||||
|
|
||||||
sprintf( layer_name, "preclip" );
|
|
||||||
l_id = tgShapefileOpenLayer( ds_id, layer_name );
|
|
||||||
sprintf( feature_name, "preclip" );
|
|
||||||
tgShapefileCreateFeature( ds_id, l_id, tmp, feature_name );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if USE_CLIPPER
|
#if USE_CLIPPER
|
||||||
clipped = tgPolygonDiffClipper( tmp, accum );
|
clipped = tgPolygonDiffClipper( tmp, accum );
|
||||||
#else
|
#else
|
||||||
|
@ -1298,6 +1335,7 @@ bool TGConstruct::ClipLandclassPolys( void ) {
|
||||||
// copy all of the superpolys and texparams
|
// copy all of the superpolys and texparams
|
||||||
shape.SetMask( clipped );
|
shape.SetMask( clipped );
|
||||||
shape.textured = polys_in.get_textured( i, j );
|
shape.textured = polys_in.get_textured( i, j );
|
||||||
|
shape.id = polys_in.get_shape( i, j ).id;
|
||||||
shape.sps = polys_in.get_shape( i, j ).sps;
|
shape.sps = polys_in.get_shape( i, j ).sps;
|
||||||
shape.tps = polys_in.get_shape( i, j ).tps;
|
shape.tps = polys_in.get_shape( i, j ).tps;
|
||||||
|
|
||||||
|
@ -1625,6 +1663,12 @@ void TGConstruct::TesselatePolys( void )
|
||||||
|
|
||||||
for (unsigned int area = 0; area < TG_MAX_AREA_TYPES; area++) {
|
for (unsigned int area = 0; area < TG_MAX_AREA_TYPES; area++) {
|
||||||
for (unsigned int shape = 0; shape < polys_clipped.area_size(area); shape++ ) {
|
for (unsigned int shape = 0; shape < polys_clipped.area_size(area); shape++ ) {
|
||||||
|
unsigned int id = polys_clipped.get_shape( area, shape ).id;
|
||||||
|
|
||||||
|
if ( IsDebugShape( id ) ) {
|
||||||
|
WriteDebugShape( "preteselate", area, shape );
|
||||||
|
}
|
||||||
|
|
||||||
for ( unsigned int segment = 0; segment < polys_clipped.shape_size(area, shape); segment++ ) {
|
for ( unsigned int segment = 0; segment < polys_clipped.shape_size(area, shape); segment++ ) {
|
||||||
TGPolygon poly = polys_clipped.get_poly(area, shape, segment);
|
TGPolygon poly = polys_clipped.get_poly(area, shape, segment);
|
||||||
poly.get_bounding_box(min, max);
|
poly.get_bounding_box(min, max);
|
||||||
|
@ -1634,21 +1678,6 @@ void TGConstruct::TesselatePolys( void )
|
||||||
shape+1 << "-" << segment << " of " << (int)polys_clipped.area_size(area) <<
|
shape+1 << "-" << segment << " of " << (int)polys_clipped.area_size(area) <<
|
||||||
": flag = " << polys_clipped.get_flag(area, shape, segment));
|
": flag = " << polys_clipped.get_flag(area, shape, segment));
|
||||||
|
|
||||||
#if 0
|
|
||||||
if ( (i == 3) && (j == 137) ) {
|
|
||||||
SG_LOG( SG_CLIPPER, SG_INFO, "Error Poly\n" << poly );
|
|
||||||
|
|
||||||
|
|
||||||
sprintf( layer_name, "pretesselate" );
|
|
||||||
l_id = tgShapefileOpenLayer( ds_id, layer_name );
|
|
||||||
sprintf( feature_name, "pretesselate" );
|
|
||||||
tgShapefileCreateFeature( ds_id, l_id, poly, feature_name );
|
|
||||||
|
|
||||||
// close befoe the crash
|
|
||||||
tgShapefileCloseDatasource( ds_id );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
TGPolygon tri = polygon_tesselate_alt_with_extra( poly, poly_extra, false );
|
TGPolygon tri = polygon_tesselate_alt_with_extra( poly, poly_extra, false );
|
||||||
|
|
||||||
// ensure all added nodes are accounted for
|
// ensure all added nodes are accounted for
|
||||||
|
@ -1849,10 +1878,10 @@ void TGConstruct::CalcTextureCoordinates( void )
|
||||||
TGPolygon tc;
|
TGPolygon tc;
|
||||||
|
|
||||||
if ( polys_clipped.get_textured( area, shape ) ) {
|
if ( polys_clipped.get_textured( area, shape ) ) {
|
||||||
SG_LOG(SG_GENERAL, SG_INFO, "USE TEXTURE PARAMS for tex coord calculations" );
|
SG_LOG(SG_GENERAL, SG_DEBUG, "USE TEXTURE PARAMS for tex coord calculations" );
|
||||||
tc = linear_tex_coords( tri, polys_clipped.get_texparams(area, shape, segment) );
|
tc = linear_tex_coords( tri, polys_clipped.get_texparams(area, shape, segment) );
|
||||||
} else {
|
} else {
|
||||||
SG_LOG(SG_GENERAL, SG_INFO, "USE SIMGEAR for tex coord calculations" );
|
SG_LOG(SG_GENERAL, SG_DEBUG, "USE SIMGEAR for tex coord calculations" );
|
||||||
tc = area_tex_coords( tri );
|
tc = area_tex_coords( tri );
|
||||||
}
|
}
|
||||||
polys_clipped.set_texcoords( area, shape, segment, tc );
|
polys_clipped.set_texcoords( area, shape, segment, tc );
|
||||||
|
@ -1867,14 +1896,14 @@ void TGConstruct::CalcTextureCoordinates( void )
|
||||||
// loading, clipping, tesselating, normals, and output
|
// loading, clipping, tesselating, normals, and output
|
||||||
// Also, we are still calculating some thing more than one
|
// Also, we are still calculating some thing more than one
|
||||||
// (like face area - need to move this into superpoly )
|
// (like face area - need to move this into superpoly )
|
||||||
void TGConstruct::ConstructBucket( SGBucket b ) {
|
void TGConstruct::ConstructBucket() {
|
||||||
|
|
||||||
sprintf(ds_name, "./construct_debug_%ld", b.gen_index() );
|
/* If we have some debug IDs, create a datasource */
|
||||||
ds_id = tgShapefileOpenDatasource( ds_name );
|
if ( debug_shapes.size() ) {
|
||||||
|
sprintf(ds_name, "%s/constructdbg_%s", debug_path.c_str(), bucket.gen_index_str().c_str() );
|
||||||
|
}
|
||||||
|
|
||||||
bucket = b;
|
SG_LOG(SG_GENERAL, SG_ALERT, "Construct tile, bucket = " << bucket << " debug_string: " << ds_name );
|
||||||
|
|
||||||
SG_LOG(SG_GENERAL, SG_ALERT, "Construct tile, bucket = " << bucket );
|
|
||||||
|
|
||||||
// STEP 1)
|
// STEP 1)
|
||||||
// Load grid of elevation data (Array)
|
// Load grid of elevation data (Array)
|
||||||
|
|
|
@ -50,6 +50,8 @@
|
||||||
|
|
||||||
#include "priorities.hxx"
|
#include "priorities.hxx"
|
||||||
|
|
||||||
|
#define USE_CLIPPER (0)
|
||||||
|
|
||||||
class TGShape
|
class TGShape
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -57,6 +59,7 @@ public:
|
||||||
bool textured;
|
bool textured;
|
||||||
superpoly_list sps;
|
superpoly_list sps;
|
||||||
texparams_list tps;
|
texparams_list tps;
|
||||||
|
unsigned int id;
|
||||||
|
|
||||||
void SetMask( TGPolygon mask )
|
void SetMask( TGPolygon mask )
|
||||||
{
|
{
|
||||||
|
@ -71,7 +74,11 @@ public:
|
||||||
for (unsigned int i=0; i<sps.size(); i++)
|
for (unsigned int i=0; i<sps.size(); i++)
|
||||||
{
|
{
|
||||||
poly = sps[i].get_poly();
|
poly = sps[i].get_poly();
|
||||||
|
#ifdef USE_CLIPPER
|
||||||
|
clip_mask = tgPolygonUnionClipper( clip_mask, poly );
|
||||||
|
#else
|
||||||
clip_mask = tgPolygonUnion( clip_mask, poly );
|
clip_mask = tgPolygonUnion( clip_mask, poly );
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +89,11 @@ public:
|
||||||
for (unsigned int i=0; i<sps.size(); i++)
|
for (unsigned int i=0; i<sps.size(); i++)
|
||||||
{
|
{
|
||||||
original = sps[i].get_poly();
|
original = sps[i].get_poly();
|
||||||
|
#ifdef USE_CLIPPER
|
||||||
|
intersect = tgPolygonIntClipper( clip_mask, original );
|
||||||
|
#else
|
||||||
intersect = tgPolygonInt( clip_mask, original );
|
intersect = tgPolygonInt( clip_mask, original );
|
||||||
|
#endif
|
||||||
sps[i].set_poly( intersect );
|
sps[i].set_poly( intersect );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -240,7 +251,6 @@ private:
|
||||||
// flag indicating whether this is a rebuild and Shared edge
|
// flag indicating whether this is a rebuild and Shared edge
|
||||||
// data should only be used for fitting, but not rewritten
|
// data should only be used for fitting, but not rewritten
|
||||||
bool writeSharedEdges;
|
bool writeSharedEdges;
|
||||||
|
|
||||||
// flag indicating whether the shared edge data of the
|
// flag indicating whether the shared edge data of the
|
||||||
// tile to be built should be used in addition to neighbour data
|
// tile to be built should be used in addition to neighbour data
|
||||||
bool useOwnSharedEdges;
|
bool useOwnSharedEdges;
|
||||||
|
@ -248,6 +258,20 @@ private:
|
||||||
// flag indicating whether to ignore the landmass
|
// flag indicating whether to ignore the landmass
|
||||||
bool ignoreLandmass;
|
bool ignoreLandmass;
|
||||||
|
|
||||||
|
// path to the debug shapes
|
||||||
|
std::string debug_path;
|
||||||
|
|
||||||
|
// list of shapes to dump during debug
|
||||||
|
std::vector<unsigned int> debug_shapes;
|
||||||
|
|
||||||
|
// OGR encode variables
|
||||||
|
// For debug:
|
||||||
|
void* ds_id; // If we are going to build shapefiles
|
||||||
|
void* l_id; // datasource and layer IDs
|
||||||
|
char ds_name[128];
|
||||||
|
char layer_name[128];
|
||||||
|
char feature_name[128];
|
||||||
|
|
||||||
// this bucket
|
// this bucket
|
||||||
SGBucket bucket;
|
SGBucket bucket;
|
||||||
|
|
||||||
|
@ -291,7 +315,7 @@ private:
|
||||||
void TesselatePolys( void );
|
void TesselatePolys( void );
|
||||||
|
|
||||||
// Elevation and Flattening
|
// Elevation and Flattening
|
||||||
void CalcElevations( void );
|
void CalcElevations( void );
|
||||||
|
|
||||||
// Normals and texture coords
|
// Normals and texture coords
|
||||||
void LookupNodesPerVertex( void );
|
void LookupNodesPerVertex( void );
|
||||||
|
@ -311,6 +335,10 @@ private:
|
||||||
void calc_normals( point_list& wgs84_nodes, TGSuperPoly& sp );
|
void calc_normals( point_list& wgs84_nodes, TGSuperPoly& sp );
|
||||||
double calc_tri_area( int_list& triangle_nodes );
|
double calc_tri_area( int_list& triangle_nodes );
|
||||||
|
|
||||||
|
// debug
|
||||||
|
bool IsDebugShape( unsigned int id );
|
||||||
|
void WriteDebugShape( const char* layer_name, unsigned int area, unsigned int shape );
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Constructor
|
// Constructor
|
||||||
TGConstruct();
|
TGConstruct();
|
||||||
|
@ -318,7 +346,9 @@ public:
|
||||||
// Destructor
|
// Destructor
|
||||||
~TGConstruct();
|
~TGConstruct();
|
||||||
|
|
||||||
void ConstructBucket( SGBucket b );
|
void set_bucket( SGBucket b ) { bucket = b; }
|
||||||
|
|
||||||
|
void ConstructBucket();
|
||||||
|
|
||||||
|
|
||||||
void calc_gc_course_dist( const Point3D& start, const Point3D& dest,
|
void calc_gc_course_dist( const Point3D& start, const Point3D& dest,
|
||||||
|
@ -369,6 +399,9 @@ public:
|
||||||
// normal list (for each point) in cart coords (for smooth
|
// normal list (for each point) in cart coords (for smooth
|
||||||
// shading)
|
// shading)
|
||||||
inline point_list get_point_normals() const { return nodes.get_normals(); }
|
inline point_list get_point_normals() const { return nodes.get_normals(); }
|
||||||
|
|
||||||
|
// Debug
|
||||||
|
void set_debug( std::string path, std::vector<std::string> defs );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -173,6 +173,9 @@ int main(int argc, char **argv) {
|
||||||
double ydist = -1;
|
double ydist = -1;
|
||||||
long tile_id = -1;
|
long tile_id = -1;
|
||||||
|
|
||||||
|
string debug_dir = ".";
|
||||||
|
vector<string> debug_defs;
|
||||||
|
|
||||||
// flag indicating whether UK grid should be used for in-UK
|
// flag indicating whether UK grid should be used for in-UK
|
||||||
// texture coordinate generation
|
// texture coordinate generation
|
||||||
bool useUKgrid = false;
|
bool useUKgrid = false;
|
||||||
|
@ -229,6 +232,10 @@ int main(int argc, char **argv) {
|
||||||
useOwnSharedEdges = true;
|
useOwnSharedEdges = true;
|
||||||
} else if (arg.find("--ignore-landmass") == 0) {
|
} else if (arg.find("--ignore-landmass") == 0) {
|
||||||
ignoreLandmass = true;
|
ignoreLandmass = true;
|
||||||
|
} else if (arg.find("--debug-dir=") == 0) {
|
||||||
|
debug_dir = arg.substr(12);
|
||||||
|
} else if (arg.find("--debug-shapes=") == 0) {
|
||||||
|
debug_defs.push_back( arg.substr(15) );
|
||||||
} else if (arg.find("--") == 0) {
|
} else if (arg.find("--") == 0) {
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
} else {
|
} else {
|
||||||
|
@ -318,8 +325,11 @@ int main(int argc, char **argv) {
|
||||||
c->set_use_own_shared_edges( useOwnSharedEdges );
|
c->set_use_own_shared_edges( useOwnSharedEdges );
|
||||||
c->set_ignore_landmass( ignoreLandmass );
|
c->set_ignore_landmass( ignoreLandmass );
|
||||||
c->set_nudge( nudge );
|
c->set_nudge( nudge );
|
||||||
|
c->set_bucket( b );
|
||||||
|
|
||||||
c->ConstructBucket( b );
|
c->set_debug( debug_dir, debug_defs );
|
||||||
|
|
||||||
|
c->ConstructBucket();
|
||||||
delete c;
|
delete c;
|
||||||
} else {
|
} else {
|
||||||
// build all the tiles in an area
|
// build all the tiles in an area
|
||||||
|
@ -343,8 +353,11 @@ int main(int argc, char **argv) {
|
||||||
c->set_use_own_shared_edges( useOwnSharedEdges );
|
c->set_use_own_shared_edges( useOwnSharedEdges );
|
||||||
c->set_ignore_landmass( ignoreLandmass );
|
c->set_ignore_landmass( ignoreLandmass );
|
||||||
c->set_nudge( nudge );
|
c->set_nudge( nudge );
|
||||||
|
c->set_bucket( b_min );
|
||||||
|
|
||||||
c->ConstructBucket( b_min );
|
c->set_debug( debug_dir, debug_defs );
|
||||||
|
|
||||||
|
c->ConstructBucket();
|
||||||
delete c;
|
delete c;
|
||||||
} else {
|
} else {
|
||||||
SGBucket b_cur;
|
SGBucket b_cur;
|
||||||
|
@ -373,8 +386,11 @@ int main(int argc, char **argv) {
|
||||||
c->set_use_own_shared_edges( useOwnSharedEdges );
|
c->set_use_own_shared_edges( useOwnSharedEdges );
|
||||||
c->set_ignore_landmass( ignoreLandmass );
|
c->set_ignore_landmass( ignoreLandmass );
|
||||||
c->set_nudge( nudge );
|
c->set_nudge( nudge );
|
||||||
|
c->set_bucket( b_cur );
|
||||||
|
|
||||||
c->ConstructBucket( b_cur );
|
c->set_debug( debug_dir, debug_defs );
|
||||||
|
|
||||||
|
c->ConstructBucket();
|
||||||
delete c;
|
delete c;
|
||||||
} else {
|
} else {
|
||||||
SG_LOG(SG_GENERAL, SG_ALERT, "skipping " << b_cur);
|
SG_LOG(SG_GENERAL, SG_ALERT, "skipping " << b_cur);
|
||||||
|
@ -398,8 +414,11 @@ int main(int argc, char **argv) {
|
||||||
c->set_use_own_shared_edges( useOwnSharedEdges );
|
c->set_use_own_shared_edges( useOwnSharedEdges );
|
||||||
c->set_ignore_landmass( ignoreLandmass );
|
c->set_ignore_landmass( ignoreLandmass );
|
||||||
c->set_nudge( nudge );
|
c->set_nudge( nudge );
|
||||||
|
c->set_bucket( b );
|
||||||
|
|
||||||
c->ConstructBucket( b );
|
c->set_debug( debug_dir, debug_defs );
|
||||||
|
|
||||||
|
c->ConstructBucket();
|
||||||
delete c;
|
delete c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -441,8 +441,8 @@ inline bool Point3D::HasElevation() const
|
||||||
|
|
||||||
inline bool Point3D::IsWithin( Point3D min, Point3D max ) const
|
inline bool Point3D::IsWithin( Point3D min, Point3D max ) const
|
||||||
{
|
{
|
||||||
return ( (min.n[PX] < n[PX]) && (min.n[PY] < n[PY]) &&
|
return ( (min.n[PX] <= n[PX]) && (min.n[PY] <= n[PY]) &&
|
||||||
(max.n[PX] > n[PX]) && (max.n[PY] > n[PY]) );
|
(max.n[PX] >= n[PX]) && (max.n[PY] >= n[PY]) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// FRIENDS
|
// FRIENDS
|
||||||
|
|
|
@ -34,11 +34,9 @@
|
||||||
// Divide segment if there are other existing points on it, return the
|
// Divide segment if there are other existing points on it, return the
|
||||||
// new polygon
|
// new polygon
|
||||||
void add_intermediate_nodes( int contour, const Point3D& start,
|
void add_intermediate_nodes( int contour, const Point3D& start,
|
||||||
const Point3D& end, const TGTriNodes& tmp_nodes,
|
const Point3D& end, point_list& tmp_nodes,
|
||||||
TGPolygon *result )
|
TGPolygon *result )
|
||||||
{
|
{
|
||||||
point_list nodes = tmp_nodes.get_node_list();
|
|
||||||
|
|
||||||
// SG_LOG(SG_GENERAL, SG_DEBUG, " add_intermediate_nodes()");
|
// SG_LOG(SG_GENERAL, SG_DEBUG, " add_intermediate_nodes()");
|
||||||
char buf[200];
|
char buf[200];
|
||||||
snprintf(buf, 199, " %.7f %.7f %.7f <=> %.7f %.7f %.7f\n",
|
snprintf(buf, 199, " %.7f %.7f %.7f <=> %.7f %.7f %.7f\n",
|
||||||
|
@ -47,7 +45,7 @@ void add_intermediate_nodes( int contour, const Point3D& start,
|
||||||
|
|
||||||
|
|
||||||
Point3D new_pt;
|
Point3D new_pt;
|
||||||
bool found_extra = find_intermediate_node( start, end, nodes, &new_pt );
|
bool found_extra = find_intermediate_node( start, end, tmp_nodes, &new_pt );
|
||||||
|
|
||||||
if ( found_extra ) {
|
if ( found_extra ) {
|
||||||
// recurse with two sub segments
|
// recurse with two sub segments
|
||||||
|
@ -72,9 +70,10 @@ void add_intermediate_nodes( int contour, const Point3D& start,
|
||||||
// avoid "T" intersections.
|
// avoid "T" intersections.
|
||||||
|
|
||||||
TGPolygon add_nodes_to_poly( const TGPolygon& poly,
|
TGPolygon add_nodes_to_poly( const TGPolygon& poly,
|
||||||
const TGTriNodes& tmp_nodes ) {
|
const TGTriNodes& nodes ) {
|
||||||
int i, j;
|
int i, j;
|
||||||
TGPolygon result; result.erase();
|
TGPolygon result; result.erase();
|
||||||
|
point_list tmp_nodes = nodes.get_node_list();
|
||||||
Point3D p0, p1;
|
Point3D p0, p1;
|
||||||
|
|
||||||
// SG_LOG(SG_GENERAL, SG_DEBUG, "add_nodes_to_poly");
|
// SG_LOG(SG_GENERAL, SG_DEBUG, "add_nodes_to_poly");
|
||||||
|
@ -114,42 +113,18 @@ TGPolygon add_nodes_to_poly( const TGPolygon& poly,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Divide segment if there are other existing points on it, return the
|
|
||||||
// new polygon
|
|
||||||
void add_intermediate_tgnodes( int contour, const Point3D& start,
|
|
||||||
const Point3D& end, const TGNodes* nodes,
|
|
||||||
TGPolygon *result )
|
|
||||||
{
|
|
||||||
point_list points = nodes->get_geod_nodes();
|
|
||||||
|
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, " add_intermediate_nodes()");
|
|
||||||
char buf[200];
|
|
||||||
snprintf(buf, 199, " %.7f %.7f %.7f <=> %.7f %.7f %.7f\n",
|
|
||||||
start.x(), start.y(), start.z(), end.x(), end.y(), end.z() );
|
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, buf);
|
|
||||||
|
|
||||||
Point3D new_pt;
|
|
||||||
bool found_extra = find_intermediate_node( start, end, points, &new_pt );
|
|
||||||
|
|
||||||
if ( found_extra ) {
|
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, "dividing " << start << " " << new_pt << " " << end);
|
|
||||||
add_intermediate_tgnodes( contour, start, new_pt, nodes, result );
|
|
||||||
|
|
||||||
result->add_node( contour, 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 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TGPolygon add_tgnodes_to_poly( const TGPolygon& poly,
|
TGPolygon add_tgnodes_to_poly( const TGPolygon& poly,
|
||||||
const TGNodes* nodes ) {
|
const TGNodes* nodes ) {
|
||||||
TGPolygon result; result.erase();
|
TGPolygon result; result.erase();
|
||||||
|
Point3D min, max;
|
||||||
Point3D p0, p1;
|
Point3D p0, p1;
|
||||||
|
point_list poly_points;
|
||||||
|
|
||||||
|
poly.get_bounding_box(min, max);
|
||||||
|
SG_LOG(SG_GENERAL, SG_DEBUG, "add_tgnodes_to_poly : min " << min << " max " << max );
|
||||||
|
|
||||||
|
poly_points = nodes->get_geod_inside( min, max );
|
||||||
|
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, "add_nodes_to_poly");
|
|
||||||
for ( int i = 0; i < poly.contours(); ++i ) {
|
for ( int i = 0; i < poly.contours(); ++i ) {
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, "contour = " << i);
|
SG_LOG(SG_GENERAL, SG_DEBUG, "contour = " << i);
|
||||||
for ( int j = 0; j < poly.contour_size(i) - 1; ++j ) {
|
for ( int j = 0; j < poly.contour_size(i) - 1; ++j ) {
|
||||||
|
@ -160,7 +135,7 @@ TGPolygon add_tgnodes_to_poly( const TGPolygon& poly,
|
||||||
result.add_node( i, p0 );
|
result.add_node( i, p0 );
|
||||||
|
|
||||||
// add intermediate points
|
// add intermediate points
|
||||||
add_intermediate_tgnodes( i, p0, p1, nodes, &result );
|
add_intermediate_nodes( i, p0, p1, poly_points, &result );
|
||||||
|
|
||||||
// end of segment is beginning of next segment
|
// end of segment is beginning of next segment
|
||||||
}
|
}
|
||||||
|
@ -171,7 +146,7 @@ TGPolygon add_tgnodes_to_poly( const TGPolygon& poly,
|
||||||
result.add_node( i, p0 );
|
result.add_node( i, p0 );
|
||||||
|
|
||||||
// add intermediate points
|
// add intermediate points
|
||||||
add_intermediate_tgnodes( i, p0, p1, nodes, &result );
|
add_intermediate_nodes( i, p0, p1, poly_points, &result );
|
||||||
|
|
||||||
// maintain original hole flag setting
|
// maintain original hole flag setting
|
||||||
result.set_hole_flag( i, poly.get_hole_flag( i ) );
|
result.set_hole_flag( i, poly.get_hole_flag( i ) );
|
||||||
|
@ -179,4 +154,3 @@ TGPolygon add_tgnodes_to_poly( const TGPolygon& poly,
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -991,8 +991,8 @@ bool find_intermediate_node( const Point3D& start, const Point3D& end,
|
||||||
// cout << i << endl;
|
// cout << i << endl;
|
||||||
Point3D current = nodes[i];
|
Point3D current = nodes[i];
|
||||||
|
|
||||||
if ( (current.x() > (p_min.x() + SG_EPSILON))
|
if ( (current.x() > (p_min.x() + (SG_EPSILON)))
|
||||||
&& (current.x() < (p_max.x() - SG_EPSILON)) ) {
|
&& (current.x() < (p_max.x() - (SG_EPSILON))) ) {
|
||||||
|
|
||||||
// printf( "found a potential candidate %.7f %.7f %.7f\n",
|
// printf( "found a potential candidate %.7f %.7f %.7f\n",
|
||||||
// current.x(), current.y(), current.z() );
|
// current.x(), current.y(), current.z() );
|
||||||
|
@ -1039,8 +1039,8 @@ bool find_intermediate_node( const Point3D& start, const Point3D& end,
|
||||||
for ( int i = 0; i < (int)nodes.size(); ++i ) {
|
for ( int i = 0; i < (int)nodes.size(); ++i ) {
|
||||||
Point3D current = nodes[i];
|
Point3D current = nodes[i];
|
||||||
|
|
||||||
if ( (current.y() > (p_min.y() + SG_EPSILON))
|
if ( (current.y() > (p_min.y() + (SG_EPSILON)))
|
||||||
&& (current.y() < (p_max.y() - SG_EPSILON)) ) {
|
&& (current.y() < (p_max.y() - (SG_EPSILON))) ) {
|
||||||
|
|
||||||
// printf( "found a potential candidate %.7f %.7f %.7f\n",
|
// printf( "found a potential candidate %.7f %.7f %.7f\n",
|
||||||
// current.x(), current.y(), current.z() );
|
// current.x(), current.y(), current.z() );
|
||||||
|
@ -1508,9 +1508,14 @@ void* tgShapefileOpenDatasource( const char* datasource_name )
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
datasource = ogrdriver->CreateDataSource(datasource_name, NULL);
|
datasource = ogrdriver->Open(datasource_name, TRUE);
|
||||||
|
|
||||||
if (!datasource) {
|
if (!datasource) {
|
||||||
SG_LOG(SG_GENERAL, SG_ALERT, "Unable to create datasource: " << datasource_name);
|
datasource = ogrdriver->CreateDataSource(datasource_name, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!datasource) {
|
||||||
|
SG_LOG(SG_GENERAL, SG_ALERT, "Unable to open or create datasource: " << datasource_name);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1523,19 +1528,25 @@ void* tgShapefileOpenLayer( void* ds_id, const char* layer_name ) {
|
||||||
|
|
||||||
OGRSpatialReference srs;
|
OGRSpatialReference srs;
|
||||||
srs.SetWellKnownGeogCS("WGS84");
|
srs.SetWellKnownGeogCS("WGS84");
|
||||||
layer = datasource->CreateLayer( layer_name, &srs, wkbPolygon25D, NULL);
|
|
||||||
|
layer = datasource->GetLayerByName(layer_name);
|
||||||
|
|
||||||
|
if (!layer) {
|
||||||
|
layer = datasource->CreateLayer( layer_name, &srs, wkbPolygon25D, NULL);
|
||||||
|
|
||||||
|
OGRFieldDefn descriptionField("ID", OFTString);
|
||||||
|
descriptionField.SetWidth(128);
|
||||||
|
|
||||||
|
if( layer->CreateField( &descriptionField ) != OGRERR_NONE ) {
|
||||||
|
SG_LOG(SG_GENERAL, SG_ALERT, "Creation of field 'Description' failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!layer) {
|
if (!layer) {
|
||||||
SG_LOG(SG_GENERAL, SG_ALERT, "Creation of layer '" << layer_name << "' failed");
|
SG_LOG(SG_GENERAL, SG_ALERT, "Creation of layer '" << layer_name << "' failed");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
OGRFieldDefn descriptionField("ID", OFTString);
|
|
||||||
descriptionField.SetWidth(128);
|
|
||||||
|
|
||||||
if( layer->CreateField( &descriptionField ) != OGRERR_NONE ) {
|
|
||||||
SG_LOG(SG_GENERAL, SG_ALERT, "Creation of field 'Description' failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
return (void*)layer;
|
return (void*)layer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1588,10 +1599,11 @@ void tgShapefileCloseLayer( void* l_id )
|
||||||
//OGRLayer::DestroyLayer( layer );
|
//OGRLayer::DestroyLayer( layer );
|
||||||
}
|
}
|
||||||
|
|
||||||
void tgShapefileCloseDatasource( void* ds_id )
|
void* tgShapefileCloseDatasource( void* ds_id )
|
||||||
{
|
{
|
||||||
OGRDataSource* datasource = (OGRDataSource *)ds_id;
|
OGRDataSource* datasource = (OGRDataSource *)ds_id;
|
||||||
|
|
||||||
OGRDataSource::DestroyDataSource( datasource );
|
OGRDataSource::DestroyDataSource( datasource );
|
||||||
}
|
|
||||||
|
|
||||||
|
return (void *)-1;
|
||||||
|
}
|
|
@ -116,7 +116,7 @@ void* tgShapefileOpenDatasource( const char* datasource_name );
|
||||||
void* tgShapefileOpenLayer( void* ds_id, const char* layer_name );
|
void* tgShapefileOpenLayer( void* ds_id, const char* layer_name );
|
||||||
void tgShapefileCreateFeature( void* ds_id, void* l_id, const TGPolygon &poly, const char* feature_name );
|
void tgShapefileCreateFeature( void* ds_id, void* l_id, const TGPolygon &poly, const char* feature_name );
|
||||||
void tgShapefileCloseLayer( void* l_id );
|
void tgShapefileCloseLayer( void* l_id );
|
||||||
void tgShapefileCloseDatasource( void* ds_id );
|
void* tgShapefileCloseDatasource( void* ds_id );
|
||||||
|
|
||||||
|
|
||||||
#endif // _POLY_SUPPORT_HXX
|
#endif // _POLY_SUPPORT_HXX
|
||||||
|
|
|
@ -109,6 +109,10 @@ point_list TGNodes::get_geod_inside( Point3D min, Point3D max ) const {
|
||||||
|
|
||||||
if ( pt.IsWithin( min, max ) ) {
|
if ( pt.IsWithin( min, max ) ) {
|
||||||
points.push_back( pt );
|
points.push_back( pt );
|
||||||
|
} else {
|
||||||
|
if ( (pt < max) && (pt > min) ) {
|
||||||
|
SG_LOG(SG_GENERAL, SG_ALERT, "pt " << pt << " failes IsWithin, but sholdn't have: min " << min << " max " << max );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* *
|
* *
|
||||||
* Author : Angus Johnson *
|
* Author : Angus Johnson *
|
||||||
* Version : 4.8.5 *
|
* Version : 4.8.3 *
|
||||||
* Date : 15 July 2012 *
|
* Date : 27 May 2012 *
|
||||||
* Website : http://www.angusj.com *
|
* Website : http://www.angusj.com *
|
||||||
* Copyright : Angus Johnson 2010-2012 *
|
* Copyright : Angus Johnson 2010-2012 *
|
||||||
* *
|
* *
|
||||||
|
@ -61,7 +61,7 @@ enum Direction { dRightToLeft, dLeftToRight };
|
||||||
|
|
||||||
inline long64 Abs(long64 val)
|
inline long64 Abs(long64 val)
|
||||||
{
|
{
|
||||||
return val < 0 ? -val : val;
|
if (val < 0) return -val; else return val;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -1221,7 +1221,7 @@ bool PolySort(OutRec *or1, OutRec *or2)
|
||||||
{
|
{
|
||||||
if (or1->pts != or2->pts)
|
if (or1->pts != or2->pts)
|
||||||
{
|
{
|
||||||
return or1->pts ? true : false;
|
if (or1->pts) return true; else return false;
|
||||||
}
|
}
|
||||||
else return false;
|
else return false;
|
||||||
}
|
}
|
||||||
|
@ -1235,7 +1235,8 @@ bool PolySort(OutRec *or1, OutRec *or2)
|
||||||
int result = i1 - i2;
|
int result = i1 - i2;
|
||||||
if (result == 0 && (or1->isHole != or2->isHole))
|
if (result == 0 && (or1->isHole != or2->isHole))
|
||||||
{
|
{
|
||||||
return or1->isHole ? false : true;
|
if (or1->isHole) return false;
|
||||||
|
else return true;
|
||||||
}
|
}
|
||||||
else return result < 0;
|
else return result < 0;
|
||||||
}
|
}
|
||||||
|
@ -1578,10 +1579,8 @@ void Clipper::AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &pt)
|
||||||
e1->outIdx = -1;
|
e1->outIdx = -1;
|
||||||
e2->outIdx = -1;
|
e2->outIdx = -1;
|
||||||
}
|
}
|
||||||
else if (e1->outIdx < e2->outIdx)
|
|
||||||
AppendPolygon(e1, e2);
|
|
||||||
else
|
else
|
||||||
AppendPolygon(e2, e1);
|
AppendPolygon( e1, e2 );
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -2098,8 +2097,7 @@ void Clipper::AddOutPt(TEdge *e, const IntPoint &pt)
|
||||||
op->next = op;
|
op->next = op;
|
||||||
op->prev = op;
|
op->prev = op;
|
||||||
SetHoleState(e, outRec);
|
SetHoleState(e, outRec);
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
{
|
{
|
||||||
OutRec *outRec = m_PolyOuts[e->outIdx];
|
OutRec *outRec = m_PolyOuts[e->outIdx];
|
||||||
OutPt* op = outRec->pts;
|
OutPt* op = outRec->pts;
|
||||||
|
@ -2110,16 +2108,11 @@ void Clipper::AddOutPt(TEdge *e, const IntPoint &pt)
|
||||||
{
|
{
|
||||||
//check for 'rounding' artefacts ...
|
//check for 'rounding' artefacts ...
|
||||||
if (outRec->sides == esNeither && pt.Y == op->pt.Y)
|
if (outRec->sides == esNeither && pt.Y == op->pt.Y)
|
||||||
{
|
|
||||||
if (ToFront)
|
if (ToFront)
|
||||||
{
|
{
|
||||||
if (pt.X == op->pt.X +1) return; //ie wrong side of bottomPt
|
if (pt.X == op->pt.X +1) return; //ie wrong side of bottomPt
|
||||||
}
|
}
|
||||||
else
|
else if (pt.X == op->pt.X -1) return; //ie wrong side of bottomPt
|
||||||
{
|
|
||||||
if (pt.X == op->pt.X -1) return; //ie wrong side of bottomPt
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
outRec->sides = (EdgeSide)(outRec->sides | e->side);
|
outRec->sides = (EdgeSide)(outRec->sides | e->side);
|
||||||
if (outRec->sides == esBoth)
|
if (outRec->sides == esBoth)
|
||||||
|
@ -2317,7 +2310,8 @@ void Clipper::SwapPositionsInSEL(TEdge *edge1, TEdge *edge2)
|
||||||
|
|
||||||
TEdge* GetNextInAEL(TEdge *e, Direction dir)
|
TEdge* GetNextInAEL(TEdge *e, Direction dir)
|
||||||
{
|
{
|
||||||
return dir == dLeftToRight ? e->nextInAEL : e->prevInAEL;
|
if( dir == dLeftToRight ) return e->nextInAEL;
|
||||||
|
else return e->prevInAEL;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -2534,12 +2528,12 @@ bool Process1Before2(IntersectNode &node1, IntersectNode &node2)
|
||||||
if (node1.edge1 == node2.edge1 || node1.edge2 == node2.edge1)
|
if (node1.edge1 == node2.edge1 || node1.edge2 == node2.edge1)
|
||||||
{
|
{
|
||||||
result = node2.pt.X > node1.pt.X;
|
result = node2.pt.X > node1.pt.X;
|
||||||
return node2.edge1->dx > 0 ? !result : result;
|
if (node2.edge1->dx > 0) return !result; else return result;
|
||||||
}
|
}
|
||||||
else if (node1.edge1 == node2.edge2 || node1.edge2 == node2.edge2)
|
else if (node1.edge1 == node2.edge2 || node1.edge2 == node2.edge2)
|
||||||
{
|
{
|
||||||
result = node2.pt.X > node1.pt.X;
|
result = node2.pt.X > node1.pt.X;
|
||||||
return node2.edge2->dx > 0 ? !result : result;
|
if (node2.edge2->dx > 0) return !result; else return result;
|
||||||
}
|
}
|
||||||
else return node2.pt.X > node1.pt.X;
|
else return node2.pt.X > node1.pt.X;
|
||||||
}
|
}
|
||||||
|
@ -2865,7 +2859,8 @@ bool Clipper::FixupIntersections()
|
||||||
|
|
||||||
bool E2InsertsBeforeE1(TEdge &e1, TEdge &e2)
|
bool E2InsertsBeforeE1(TEdge &e1, TEdge &e2)
|
||||||
{
|
{
|
||||||
return e2.xcurr == e1.xcurr ? e2.dx > e1.dx : e2.xcurr < e1.xcurr;
|
if (e2.xcurr == e1.xcurr) return e2.dx > e1.dx;
|
||||||
|
else return e2.xcurr < e1.xcurr;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -3131,13 +3126,12 @@ struct DoublePoint
|
||||||
Polygon BuildArc(const IntPoint &pt,
|
Polygon BuildArc(const IntPoint &pt,
|
||||||
const double a1, const double a2, const double r)
|
const double a1, const double a2, const double r)
|
||||||
{
|
{
|
||||||
long64 steps = std::max(6, int(std::sqrt(std::fabs(r)) * std::fabs(a2 - a1)));
|
int steps = std::max(6, int(std::sqrt(std::fabs(r)) * std::fabs(a2 - a1)));
|
||||||
if (steps > 0x100000) steps = 0x100000;
|
Polygon result(steps);
|
||||||
int n = (unsigned)steps;
|
int n = steps - 1;
|
||||||
Polygon result(n);
|
double da = (a2 - a1) / n;
|
||||||
double da = (a2 - a1) / (n -1);
|
|
||||||
double a = a1;
|
double a = a1;
|
||||||
for (int i = 0; i < n; ++i)
|
for (int i = 0; i <= n; ++i)
|
||||||
{
|
{
|
||||||
result[i].X = pt.X + Round(std::cos(a)*r);
|
result[i].X = pt.X + Round(std::cos(a)*r);
|
||||||
result[i].Y = pt.Y + Round(std::sin(a)*r);
|
result[i].Y = pt.Y + Round(std::sin(a)*r);
|
||||||
|
@ -3290,18 +3284,19 @@ void DoSquare(double mul = 1.0)
|
||||||
(long64)Round(m_p[m_i][m_j].Y + normals[m_k].Y * m_delta));
|
(long64)Round(m_p[m_i][m_j].Y + normals[m_k].Y * m_delta));
|
||||||
IntPoint pt2 = IntPoint((long64)Round(m_p[m_i][m_j].X + normals[m_j].X * m_delta),
|
IntPoint pt2 = IntPoint((long64)Round(m_p[m_i][m_j].X + normals[m_j].X * m_delta),
|
||||||
(long64)Round(m_p[m_i][m_j].Y + normals[m_j].Y * m_delta));
|
(long64)Round(m_p[m_i][m_j].Y + normals[m_j].Y * m_delta));
|
||||||
double sinAngle = normals[m_k].X * normals[m_j].Y - normals[m_j].X * normals[m_k].Y;
|
if ((normals[m_k].X * normals[m_j].Y - normals[m_j].X * normals[m_k].Y) * m_delta >= 0)
|
||||||
if (sinAngle * m_delta >= 0)
|
|
||||||
{
|
{
|
||||||
//occasionally (due to floating point math) sinAngle can be > 1 so ...
|
double a1 = std::atan2(normals[m_k].Y, normals[m_k].X);
|
||||||
if (sinAngle > 1) sinAngle = 1; else if (sinAngle < -1) sinAngle = -1;
|
double a2 = std::atan2(-normals[m_j].Y, -normals[m_j].X);
|
||||||
double dx = tan((pi - asin(sinAngle))/4) * abs(m_delta*mul);
|
a1 = std::fabs(a2 - a1);
|
||||||
pt1 = IntPoint((long64)(pt1.X -normals[m_k].Y * dx),
|
if (a1 > pi) a1 = pi * 2 - a1;
|
||||||
(long64)(pt1.Y + normals[m_k].X * dx));
|
double dx = std::tan((pi - a1)/4) * std::fabs(m_delta * mul);
|
||||||
AddPoint(pt1);
|
pt1 = IntPoint((long64)(pt1.X -normals[m_k].Y * dx),
|
||||||
pt2 = IntPoint((long64)(pt2.X + normals[m_j].Y * dx),
|
(long64)(pt1.Y + normals[m_k].X * dx));
|
||||||
(long64)(pt2.Y -normals[m_j].X * dx));
|
AddPoint(pt1);
|
||||||
AddPoint(pt2);
|
pt2 = IntPoint((long64)(pt2.X + normals[m_j].Y * dx),
|
||||||
|
(long64)(pt2.Y -normals[m_j].X * dx));
|
||||||
|
AddPoint(pt2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* *
|
* *
|
||||||
* Author : Angus Johnson *
|
* Author : Angus Johnson *
|
||||||
* Version : 4.8.5 *
|
* Version : 4.8.3 *
|
||||||
* Date : 15 July 2012 *
|
* Date : 27 May 2012 *
|
||||||
* Website : http://www.angusj.com *
|
* Website : http://www.angusj.com *
|
||||||
* Copyright : Angus Johnson 2010-2012 *
|
* Copyright : Angus Johnson 2010-2012 *
|
||||||
* *
|
* *
|
||||||
|
|
|
@ -51,6 +51,27 @@ TGPolygon::TGPolygon( void )
|
||||||
TGPolygon::~TGPolygon( void ) {
|
TGPolygon::~TGPolygon( void ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TGPolygon::get_bounding_box( Point3D& min, Point3D& max ) const
|
||||||
|
{
|
||||||
|
double minx = std::numeric_limits<double>::infinity();
|
||||||
|
double miny = std::numeric_limits<double>::infinity();
|
||||||
|
double maxx = -std::numeric_limits<double>::infinity();
|
||||||
|
double maxy = -std::numeric_limits<double>::infinity();
|
||||||
|
|
||||||
|
for ( int i = 0; i < contours(); i++ ) {
|
||||||
|
for (unsigned int j = 0; j < poly[i].size(); j++) {
|
||||||
|
Point3D pt = poly[i][j];
|
||||||
|
if ( pt.x() < minx ) { minx = pt.x(); }
|
||||||
|
if ( pt.x() > maxx ) { maxx = pt.x(); }
|
||||||
|
if ( pt.y() < miny ) { miny = pt.y(); }
|
||||||
|
if ( pt.y() > maxy ) { maxy = pt.y(); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
min = Point3D( minx, miny, 0.0 );
|
||||||
|
max = Point3D( maxx, maxy, 0.0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Set the elevations of points in the current polgyon based on the
|
// Set the elevations of points in the current polgyon based on the
|
||||||
// elevations of points in source. For points that are not found in
|
// elevations of points in source. For points that are not found in
|
||||||
|
|
|
@ -153,19 +153,7 @@ inline void set_pt( int contour, int i, const Point3D& p )
|
||||||
poly[contour][i] = p;
|
poly[contour][i] = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void get_bounding_box( Point3D& min, Point3D& max )
|
void get_bounding_box( Point3D& min, Point3D& max ) const;
|
||||||
{
|
|
||||||
min = Point3D( std::numeric_limits<double>::infinity(), std::numeric_limits<double>::infinity(), 0.0 );
|
|
||||||
max = Point3D( -std::numeric_limits<double>::infinity(), -std::numeric_limits<double>::infinity(), 0.0 );
|
|
||||||
|
|
||||||
for ( int i = 0; i < contours(); i++ ) {
|
|
||||||
for (unsigned int j = 0; j < poly[i].size(); j++) {
|
|
||||||
Point3D pt = poly[i][j];
|
|
||||||
if ( pt < min ) { min = pt; }
|
|
||||||
if ( pt > max ) { max = pt; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// get and set an arbitrary point inside the specified polygon contour
|
// get and set an arbitrary point inside the specified polygon contour
|
||||||
inline Point3D get_point_inside( const int contour ) const
|
inline Point3D get_point_inside( const int contour ) const
|
||||||
|
|
Loading…
Add table
Reference in a new issue