Added new texturing method. Added sanity check for polygon file
reading. New texturing method TG_TEX_HORIZ_REF requires that each polygon has a reference texture coordinate specified for a specific point on the polygon. The coordinate changes parallel to a direction (also stored) and the other texture coordinate changes perpendicular to this direction. The reference texture coordinates in polygons of the same type can be chosen to match that of their neighbours to produce a continous map onto a texture. This technique can be used to texture rivers or cliffs as their direction changes. The sanity checks simply make sure that the number of contours or polygons reported in a file are not too large. This could happen if a polygon file was generated by a previous version of terragear tools with an incompatible layout of polygon information, or a non-polygon file is present in the input directory and is opened as a polygon file.
This commit is contained in:
parent
b718d909a4
commit
61ea3cd50a
9 changed files with 214 additions and 85 deletions
|
@ -75,14 +75,21 @@ int TGConstruct::LoadLandclassPolys( void ) {
|
|||
unsigned int count;
|
||||
|
||||
sgReadUInt( fp, &count );
|
||||
if ( count > 1000000 ) {
|
||||
SG_LOG( SG_GENERAL, SG_ALERT, " Too many polys in " << p.realpath() << ":" << count );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
SG_LOG( SG_GENERAL, SG_DEBUG, " Load " << count << " polys from " << p.realpath() );
|
||||
|
||||
for ( unsigned int idx = 0; idx < count; ++idx ) {
|
||||
poly.LoadFromGzFile( fp );
|
||||
if ( poly.LoadFromGzFile( fp ) == EXIT_FAILURE ) {
|
||||
SG_LOG( SG_GENERAL, SG_DEBUG, "Failed to load from " << p.realpath() );
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
int area = area_defs.get_area_priority( poly.GetFlag() );
|
||||
material = area_defs.get_area_name( area );
|
||||
bool isRoad = area_defs.is_road_area( area );
|
||||
|
||||
|
||||
poly.SetMaterial( material );
|
||||
poly.SetId( cur_poly_id++ );
|
||||
|
||||
|
|
|
@ -30,14 +30,18 @@
|
|||
|
||||
void TGConstruct::CalcTextureCoordinates( void )
|
||||
{
|
||||
std::vector<SGGeod> geod_nodes;
|
||||
nodes.get_geod_nodes( geod_nodes );
|
||||
|
||||
for ( unsigned int area = 0; area < area_defs.size(); area++ ) {
|
||||
for( unsigned int p = 0; p < polys_clipped.area_size(area); p++ ) {
|
||||
tgPolygon poly = polys_clipped.get_poly(area, p);
|
||||
SG_LOG( SG_CLIPPER, SG_DEBUG, "Texturing " << area_defs.get_area_name(area) << "(" << area << "): " <<
|
||||
p+1 << " of " << polys_clipped.area_size(area) << " with " << poly.GetMaterial() );
|
||||
|
||||
poly.Texture( );
|
||||
poly.Texture( geod_nodes );
|
||||
polys_clipped.set_poly(area, p, poly);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -137,10 +137,18 @@ void TGArray::load_cliffs(const string & height_base)
|
|||
gzFile fp = gzopen( p.c_str(), "rb" );
|
||||
unsigned int count;
|
||||
sgReadUInt( fp, &count );
|
||||
SG_LOG( SG_GENERAL, SG_DEBUG, " Load " << count << " contours from " << p.realpath() );
|
||||
// Sanity check
|
||||
if ( count > 100000 ) {
|
||||
SG_LOG( SG_GENERAL, SG_ALERT, "Too many polys (" << count << ") in " << p.realpath() );
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
SG_LOG( SG_GENERAL, SG_DEBUG, " Load " << count << " polys from " << p.realpath() );
|
||||
|
||||
for ( unsigned int i=0; i<count; i++ ) {
|
||||
poly.LoadFromGzFile( fp );
|
||||
if ( poly.LoadFromGzFile( fp ) == EXIT_FAILURE ) {
|
||||
SG_LOG( SG_GENERAL, SG_ALERT, "Error in file " << p.realpath() );
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if ( poly.Contours()==1 ) { //should always have one contour
|
||||
cliffs_list.push_back(poly.GetContour(0));
|
||||
} else {
|
||||
|
|
|
@ -33,6 +33,11 @@ tgPolygon tgChopper::Clip( const tgPolygon& subject,
|
|||
// need to set center latitude for geodetic texturing
|
||||
result.SetTexMethod( TG_TEX_BY_GEODE, b.get_center_lat() );
|
||||
}
|
||||
if ( subject.GetTexMethod() == TG_TEX_BY_HORIZ_REF ) {
|
||||
// need to preserve reference point and coord
|
||||
result.SetTexReference( subject.GetTexRefPt(), subject.GetRefTexCoord() );
|
||||
}
|
||||
|
||||
result.SetFlag(type);
|
||||
if (!subject.IsClosed()) {
|
||||
result.SetOpen();
|
||||
|
@ -133,6 +138,11 @@ void tgChopper::Add( const tgPolygon& subject, const std::string& type )
|
|||
// need to set center latitude for geodetic texturing
|
||||
clipped.SetTexMethod( TG_TEX_BY_GEODE, b_clip.get_center_lat() );
|
||||
}
|
||||
if ( subject.GetTexMethod() == TG_TEX_BY_HORIZ_REF ) {
|
||||
// need to preserve reference point and coord
|
||||
clipped.SetTexReference( subject.GetTexRefPt(), subject.GetRefTexCoord() );
|
||||
}
|
||||
|
||||
clipped.SetFlag(type);
|
||||
|
||||
ClipRow( clipped, b_clip.get_center_lat(), type );
|
||||
|
|
|
@ -995,6 +995,11 @@ tgContour tgContour::Expand( const tgContour& subject, double offset )
|
|||
}
|
||||
|
||||
tgpolygon_list tgContour::ExpandToPolygons( const tgContour& subject, double width )
|
||||
{
|
||||
return ExpandToPolygons(subject,width,TG_TEX_BY_TPS_CLIPU);
|
||||
}
|
||||
|
||||
tgpolygon_list tgContour::ExpandToPolygons( const tgContour& subject, double width, int texturing )
|
||||
{
|
||||
SGGeod cur_inner;
|
||||
SGGeod cur_outer;
|
||||
|
@ -1007,6 +1012,7 @@ tgpolygon_list tgContour::ExpandToPolygons( const tgContour& subject, double wid
|
|||
tgPolygon segment;
|
||||
tgAccumulator accum("ExpandToPolygons");
|
||||
tgpolygon_list result;
|
||||
double total_length = 0; //Will become texture cooordinate
|
||||
|
||||
// generate poly and texparam lists for each line segment
|
||||
for (unsigned int i = 0; i < subject.GetSize(); i++)
|
||||
|
@ -1055,47 +1061,58 @@ tgpolygon_list tgContour::ExpandToPolygons( const tgContour& subject, double wid
|
|||
expanded.AddNode( prev_inner );
|
||||
expanded.AddNode( prev_outer );
|
||||
|
||||
// we need to extend one of the points so we're sure we don't create adjacent edges
|
||||
if (turn_dir == 0)
|
||||
{
|
||||
// turned right - offset outer
|
||||
if ( intersection( prev_inner, prev_outer, cur_inner, cur_outer, intersect ) )
|
||||
{
|
||||
// yes - make a triangle with inner edge = 0
|
||||
expanded.AddNode( cur_outer );
|
||||
cur_inner = prev_inner;
|
||||
}
|
||||
else
|
||||
{
|
||||
expanded.AddNode( cur_outer );
|
||||
expanded.AddNode( cur_inner );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// turned left - offset inner
|
||||
if ( intersection( prev_inner, prev_outer, cur_inner, cur_outer, intersect ) )
|
||||
{
|
||||
// yes - make a triangle with outer edge = 0
|
||||
expanded.AddNode( cur_inner );
|
||||
cur_outer = prev_outer;
|
||||
}
|
||||
else
|
||||
{
|
||||
expanded.AddNode( cur_outer );
|
||||
expanded.AddNode( cur_inner );
|
||||
}
|
||||
}
|
||||
// we need to extend one of the points so we're sure we don't create adjacent edges
|
||||
if (turn_dir == 0)
|
||||
{
|
||||
// turned right - offset outer
|
||||
if ( intersection( prev_inner, prev_outer, cur_inner, cur_outer, intersect ) )
|
||||
{
|
||||
// yes - make a triangle with inner edge = 0
|
||||
expanded.AddNode( cur_outer );
|
||||
cur_inner = prev_inner;
|
||||
}
|
||||
else
|
||||
{
|
||||
expanded.AddNode( cur_outer );
|
||||
expanded.AddNode( cur_inner );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// turned left - offset inner
|
||||
if ( intersection( prev_inner, prev_outer, cur_inner, cur_outer, intersect ) )
|
||||
{
|
||||
// yes - make a triangle with outer edge = 0
|
||||
expanded.AddNode( cur_inner );
|
||||
cur_outer = prev_outer;
|
||||
}
|
||||
else
|
||||
{
|
||||
expanded.AddNode( cur_outer );
|
||||
expanded.AddNode( cur_inner );
|
||||
}
|
||||
}
|
||||
|
||||
double last_end_v = 0.0;
|
||||
|
||||
expanded.SetHole(false);
|
||||
segment.AddContour(expanded);
|
||||
segment.SetTexParams( prev_inner, width, 20.0f, heading );
|
||||
segment.SetTexLimits( 0, last_end_v, 1, 1 );
|
||||
segment.SetTexMethod( TG_TEX_BY_TPS_CLIPU, -1.0, 0.0, 1.0, 0.0 );
|
||||
if( texturing == TG_TEX_BY_TPS_CLIPU )
|
||||
{
|
||||
segment.SetTexLimits( 0, last_end_v, 1, 1 );
|
||||
segment.SetTexMethod( TG_TEX_BY_TPS_CLIPU, -1.0, 0.0, 1.0, 0.0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
segment.SetTexMethod( TG_TEX_BY_HORIZ_REF );
|
||||
segment.SetTexReference( prev_mp, total_length ); //Ref is midpoint
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "HORIZ_REF " << total_length);
|
||||
}
|
||||
result.push_back( segment );
|
||||
|
||||
total_length = total_length + dist; //Total length of line
|
||||
|
||||
// BUG??: value will never be utilized
|
||||
last_end_v = 1.0f - (fmod( (double)(dist - last_end_v), (double)1.0f ));
|
||||
}
|
||||
|
@ -1131,6 +1148,11 @@ void tgContour::LoadFromGzFile( gzFile& fp )
|
|||
|
||||
// Load the nodelist
|
||||
sgReadUInt( fp, &count );
|
||||
// Sanity check
|
||||
if ( count > 1000000 ) {
|
||||
SG_LOG(SG_GENERAL,SG_ALERT, "Got bad contour count " << count);
|
||||
exit(1);
|
||||
}
|
||||
for (unsigned int i = 0; i < count; i++) {
|
||||
sgReadGeod( fp, node );
|
||||
node_list.push_back( node );
|
||||
|
|
|
@ -46,13 +46,13 @@ public:
|
|||
return hole;
|
||||
}
|
||||
|
||||
bool GetOpen(void) const {
|
||||
return keep_open;
|
||||
}
|
||||
bool GetOpen(void) const {
|
||||
return keep_open;
|
||||
}
|
||||
|
||||
void SetOpen(bool o) {
|
||||
keep_open = o;
|
||||
}
|
||||
void SetOpen(bool o) {
|
||||
keep_open = o;
|
||||
}
|
||||
|
||||
unsigned int GetSize( void ) const {
|
||||
return node_list.size();
|
||||
|
@ -65,15 +65,19 @@ public:
|
|||
void AddNode( SGGeod n ) {
|
||||
node_list.push_back( n );
|
||||
}
|
||||
|
||||
void SetNode( unsigned int i, SGGeod n ) {
|
||||
node_list[i] = n;
|
||||
}
|
||||
|
||||
void DelNode( unsigned int i ) {
|
||||
node_list.erase( node_list.begin()+i);
|
||||
}
|
||||
|
||||
SGGeod GetNode( unsigned int i ) const {
|
||||
return node_list[i];
|
||||
}
|
||||
|
||||
SGGeod const& operator[]( int index ) const {
|
||||
return node_list[index];
|
||||
}
|
||||
|
@ -83,6 +87,7 @@ public:
|
|||
node_list.erase( node_list.begin() + idx );
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveNodeRange( unsigned int from, unsigned int to ) {
|
||||
if ( ( from < to ) && ( to < node_list.size() ) ) {
|
||||
node_list.erase( node_list.begin()+from,node_list.begin()+to );
|
||||
|
@ -139,6 +144,7 @@ public:
|
|||
|
||||
static tgContour Expand( const tgContour& subject, double offset );
|
||||
static tgpolygon_list ExpandToPolygons( const tgContour& subject, double width );
|
||||
static tgpolygon_list ExpandToPolygons( const tgContour& subject, double width, int texturing );
|
||||
|
||||
static void ToShapefile( const tgContour& subject, const std::string& datasource, const std::string& layer, const std::string& feature );
|
||||
|
||||
|
@ -151,7 +157,7 @@ public:
|
|||
private:
|
||||
std::vector<SGGeod> node_list;
|
||||
bool hole;
|
||||
bool keep_open; //If non-closed contour, keep open
|
||||
bool keep_open; //If non-closed contour, keep open
|
||||
};
|
||||
|
||||
typedef std::vector <tgContour> tgcontour_list;
|
||||
|
|
|
@ -207,7 +207,7 @@ void tgPolygon::InheritElevations( const tgPolygon& source )
|
|||
}
|
||||
}
|
||||
|
||||
void tgPolygon::Texture( void )
|
||||
void tgPolygon::Texture( const std::vector<SGGeod>& geod_nodes )
|
||||
{
|
||||
SGGeod p;
|
||||
SGVec2f t;
|
||||
|
@ -240,8 +240,10 @@ void tgPolygon::Texture( void )
|
|||
case TG_TEX_BY_TPS_CLIPU:
|
||||
case TG_TEX_BY_TPS_CLIPV:
|
||||
case TG_TEX_BY_TPS_CLIPUV:
|
||||
case TG_TEX_BY_HORIZ_REF:
|
||||
{
|
||||
for ( unsigned int i = 0; i < triangles.size(); i++ ) {
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Triangle " << i);
|
||||
for ( unsigned int j = 0; j < 3; j++ ) {
|
||||
p = triangles[i].GetNode( j );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "point = " << p);
|
||||
|
@ -277,28 +279,42 @@ void tgPolygon::Texture( void )
|
|||
//
|
||||
// 4. Map x, y point into texture coordinates
|
||||
//
|
||||
float tmp;
|
||||
|
||||
tmp = (float)x / (float)tp.width;
|
||||
float tx = tmp * (float)(tp.maxu - tp.minu) + (float)tp.minu;
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, " (" << tx << ")");
|
||||
|
||||
// clip u?
|
||||
if ( (tp.method == TG_TEX_BY_TPS_CLIPU) || (tp.method == TG_TEX_BY_TPS_CLIPUV) ) {
|
||||
if ( tx < (float)tp.min_clipu ) { tx = (float)tp.min_clipu; }
|
||||
if ( tx > (float)tp.max_clipu ) { tx = (float)tp.max_clipu; }
|
||||
float tmp,tx,ty;
|
||||
if ( tp.method == TG_TEX_BY_HORIZ_REF ) {
|
||||
// The horizontal coordinate is textured as a continuous
|
||||
// coordinate through all polygons, the vertical coordinate
|
||||
// is based on (geodetic) height only
|
||||
SGGeod fullpt = geod_nodes[ GetTriIdx(i,j) ];
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "full pt = " << fullpt);
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "texture start = " << tp.custom_s);
|
||||
ty = fullpt.getElevationM();
|
||||
tx = tp.custom_s - (float) y;
|
||||
// and scale...we assume a 1000m x 1000m scale
|
||||
tx = tx / 1000.0;
|
||||
ty = ty / 1000.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp = (float)x / (float)tp.width;
|
||||
tx = tmp * (float)(tp.maxu - tp.minu) + (float)tp.minu;
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, " (" << tx << ")");
|
||||
|
||||
tmp = (float)y / (float)tp.length;
|
||||
float ty = tmp * (float)(tp.maxv - tp.minv) + (float)tp.minv;
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, " (" << ty << ")");
|
||||
// clip u?
|
||||
if ( (tp.method == TG_TEX_BY_TPS_CLIPU) || (tp.method == TG_TEX_BY_TPS_CLIPUV) ) {
|
||||
if ( tx < (float)tp.min_clipu ) { tx = (float)tp.min_clipu; }
|
||||
if ( tx > (float)tp.max_clipu ) { tx = (float)tp.max_clipu; }
|
||||
}
|
||||
|
||||
// clip v?
|
||||
if ( (tp.method == TG_TEX_BY_TPS_CLIPV) || (tp.method == TG_TEX_BY_TPS_CLIPUV) ) {
|
||||
if ( ty < (float)tp.min_clipv ) { ty = (float)tp.min_clipv; }
|
||||
if ( ty > (float)tp.max_clipv ) { ty = (float)tp.max_clipv; }
|
||||
tmp = (float)y / (float)tp.length;
|
||||
ty = tmp * (float)(tp.maxv - tp.minv) + (float)tp.minv;
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, " (" << ty << ")");
|
||||
|
||||
// clip v?
|
||||
if ( (tp.method == TG_TEX_BY_TPS_CLIPV) || (tp.method == TG_TEX_BY_TPS_CLIPUV) ) {
|
||||
if ( ty < (float)tp.min_clipv ) { ty = (float)tp.min_clipv; }
|
||||
if ( ty > (float)tp.max_clipv ) { ty = (float)tp.max_clipv; }
|
||||
}
|
||||
}
|
||||
|
||||
t = SGVec2f( tx, ty );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, " (" << tx << ", " << ty << ")");
|
||||
|
||||
|
@ -333,7 +349,7 @@ void tgPolygon::SaveToGzFile( gzFile& fp ) const
|
|||
sgWriteInt( fp, (int)preserve3d );
|
||||
}
|
||||
|
||||
void tgPolygon::LoadFromGzFile( gzFile& fp )
|
||||
int tgPolygon::LoadFromGzFile( gzFile& fp )
|
||||
{
|
||||
unsigned int count;
|
||||
tgContour contour;
|
||||
|
@ -345,6 +361,12 @@ void tgPolygon::LoadFromGzFile( gzFile& fp )
|
|||
|
||||
// Load the contours
|
||||
sgReadUInt( fp, &count );
|
||||
|
||||
// Sanity check
|
||||
if ( count > 100000 ) {
|
||||
SG_LOG(SG_GENERAL,SG_ALERT, "Got bad contour count " << count);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
for (unsigned int i = 0; i < count; i++) {
|
||||
contour.LoadFromGzFile( fp );
|
||||
AddContour(contour);
|
||||
|
@ -352,13 +374,20 @@ void tgPolygon::LoadFromGzFile( gzFile& fp )
|
|||
|
||||
// load the triangles
|
||||
sgReadUInt( fp, &count );
|
||||
// Sanity check
|
||||
if ( count > 1000000 ) {
|
||||
SG_LOG(SG_GENERAL,SG_ALERT, "Got bad triangle count " << count);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
for (unsigned int i = 0; i < count; i++) {
|
||||
triangle.LoadFromGzFile( fp );
|
||||
AddTriangle(triangle);
|
||||
}
|
||||
|
||||
// Load the tex params
|
||||
tp.LoadFromGzFile( fp );
|
||||
if ( tp.LoadFromGzFile( fp ) == EXIT_FAILURE ) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// and the rest
|
||||
sgReadString( fp, &strbuff );
|
||||
|
@ -374,6 +403,7 @@ void tgPolygon::LoadFromGzFile( gzFile& fp )
|
|||
}
|
||||
|
||||
sgReadInt( fp, (int *)&preserve3d );
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
void tgPolygon::ToClipperFile( const tgPolygon& subject, const std::string& path, const std::string& filename )
|
||||
|
@ -513,14 +543,22 @@ void tgTexParams::SaveToGzFile( gzFile& fp ) const
|
|||
sgWriteDouble( fp, min_clipv );
|
||||
sgWriteDouble( fp, max_clipv );
|
||||
}
|
||||
if ( method == TG_TEX_BY_HORIZ_REF ) {
|
||||
sgWriteDouble( fp, custom_s );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tgTexParams::LoadFromGzFile( gzFile& fp )
|
||||
int tgTexParams::LoadFromGzFile( gzFile& fp )
|
||||
{
|
||||
// Load the parameters
|
||||
sgReadInt( fp, (int*)&method );
|
||||
|
||||
// Sanity check
|
||||
if ( method > 100 ) {
|
||||
SG_LOG( SG_GENERAL,SG_ALERT, "Got bad texture method " << method );
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if ( method == TG_TEX_BY_GEODE ) {
|
||||
sgReadDouble( fp, ¢er_lat );
|
||||
} else {
|
||||
|
@ -545,5 +583,10 @@ void tgTexParams::LoadFromGzFile( gzFile& fp )
|
|||
sgReadDouble( fp, &min_clipv );
|
||||
sgReadDouble( fp, &max_clipv );
|
||||
}
|
||||
|
||||
if ( method == TG_TEX_BY_HORIZ_REF) {
|
||||
sgReadDouble( fp, &custom_s );
|
||||
}
|
||||
}
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -206,7 +206,8 @@ typedef enum {
|
|||
TG_TEX_BY_TPS_NOCLIP,
|
||||
TG_TEX_BY_TPS_CLIPU,
|
||||
TG_TEX_BY_TPS_CLIPV,
|
||||
TG_TEX_BY_TPS_CLIPUV
|
||||
TG_TEX_BY_TPS_CLIPUV,
|
||||
TG_TEX_BY_HORIZ_REF //Tex coord calculated from ht and horiz reference
|
||||
} tgTexMethod;
|
||||
|
||||
class tgTexParams
|
||||
|
@ -227,12 +228,14 @@ public:
|
|||
double min_clipv;
|
||||
double max_clipv;
|
||||
|
||||
double custom_s;
|
||||
|
||||
tgTexMethod method;
|
||||
|
||||
double center_lat;
|
||||
|
||||
void SaveToGzFile( gzFile& fp ) const;
|
||||
void LoadFromGzFile( gzFile& fp );
|
||||
int LoadFromGzFile( gzFile& fp );
|
||||
|
||||
// Friend for output
|
||||
friend std::ostream& operator<< ( std::ostream&, const tgTexParams& );
|
||||
|
@ -245,6 +248,7 @@ public:
|
|||
preserve3d = false;
|
||||
closed = true;
|
||||
id = 0;
|
||||
tp.method = TG_TEX_BY_GEODE;
|
||||
}
|
||||
|
||||
~tgPolygon() {
|
||||
|
@ -405,6 +409,7 @@ public:
|
|||
void SetTexMethod( tgTexMethod m ) {
|
||||
tp.method = m;
|
||||
}
|
||||
|
||||
void SetTexMethod( tgTexMethod m, double min_cu, double min_cv, double max_cu, double max_cv ) {
|
||||
tp.method = m;
|
||||
tp.min_clipu = min_cu;
|
||||
|
@ -416,10 +421,24 @@ public:
|
|||
tp.method = m;
|
||||
tp.center_lat = cl;
|
||||
}
|
||||
|
||||
void SetTexReference( SGGeod g, double tex_coord ) {
|
||||
tp.ref = g;
|
||||
tp.custom_s = tex_coord;
|
||||
}
|
||||
|
||||
SGGeod GetTexRefPt() const {
|
||||
return tp.ref;
|
||||
}
|
||||
|
||||
double GetRefTexCoord() const {
|
||||
return tp.custom_s;
|
||||
}
|
||||
|
||||
tgTexMethod GetTexMethod( void ) const {
|
||||
return tp.method;
|
||||
}
|
||||
void Texture( void );
|
||||
void Texture( const std::vector<SGGeod>& geod_nodes );
|
||||
|
||||
// Tesselation
|
||||
void Tesselate( void );
|
||||
|
@ -463,7 +482,7 @@ public:
|
|||
|
||||
// IO
|
||||
void SaveToGzFile( gzFile& fp ) const;
|
||||
void LoadFromGzFile( gzFile& fp );
|
||||
int LoadFromGzFile( gzFile& fp );
|
||||
|
||||
friend std::ostream& operator<< ( std::ostream&, const tgPolygon& );
|
||||
|
||||
|
@ -476,7 +495,7 @@ private:
|
|||
bool preserve3d;
|
||||
unsigned int id; // unique polygon id for debug
|
||||
tgTexParams tp;
|
||||
bool closed; // if we treat it as a closed shape
|
||||
bool closed; // if we treat it as a closed shape
|
||||
};
|
||||
|
||||
#endif // _POLYGON_HXX
|
||||
|
|
|
@ -57,6 +57,7 @@ string area_type="Default";
|
|||
string area_type_col;
|
||||
int continue_on_errors=0;
|
||||
bool texture_lines = false;
|
||||
bool texture_cliffs = false;
|
||||
int seperate_segments = 0;
|
||||
int max_segment_length=0; // ==0 => don't split
|
||||
int start_record=0;
|
||||
|
@ -99,7 +100,7 @@ private:
|
|||
virtual void run();
|
||||
|
||||
void processPoint(OGRPoint* poGeometry, const string& area_type, int width );
|
||||
void processLineString(OGRLineString* poGeometry, const string& area_type, int width, int with_texture );
|
||||
void processLineString(OGRLineString* poGeometry, const string& area_type, int width, int with_texture, bool texture_cliffs );
|
||||
void processPolygon(OGRPolygon* poGeometry, const string& area_type );
|
||||
|
||||
private:
|
||||
|
@ -128,7 +129,7 @@ void Decoder::processPoint(OGRPoint* poGeometry, const string& area_type, int wi
|
|||
chopper.Add( shape, area_type );
|
||||
}
|
||||
|
||||
void Decoder::processLineString(OGRLineString* poGeometry, const string& area_type, int width, int with_texture )
|
||||
void Decoder::processLineString(OGRLineString* poGeometry, const string& area_type, int width, int with_texture, bool texture_cliffs )
|
||||
{
|
||||
tgpolygon_list segments;
|
||||
tgContour line;
|
||||
|
@ -184,15 +185,17 @@ void Decoder::processLineString(OGRLineString* poGeometry, const string& area_ty
|
|||
line.AddNode( SGGeodesy::direct(p1, heading, EP_STRETCH) );
|
||||
|
||||
// make a plygons from the line segments
|
||||
segments = tgContour::ExpandToPolygons( line, width );
|
||||
int texturing;
|
||||
if ( with_texture ) {
|
||||
texturing = TG_TEX_BY_TPS_CLIPU;
|
||||
}
|
||||
else {
|
||||
texturing = TG_TEX_BY_GEODE;
|
||||
}
|
||||
if ( texture_cliffs ) texturing = TG_TEX_BY_HORIZ_REF;
|
||||
segments = tgContour::ExpandToPolygons( line, width, texturing );
|
||||
for ( unsigned int i = 0; i < segments.size(); ++i ) {
|
||||
segments[i].SetPreserve3D( false );
|
||||
if (with_texture) {
|
||||
segments[i].SetTexMethod( TG_TEX_BY_TPS_CLIPU );
|
||||
} else {
|
||||
segments[i].SetTexMethod( TG_TEX_BY_GEODE );
|
||||
}
|
||||
|
||||
chopper.Add( segments[i], area_type );
|
||||
}
|
||||
}
|
||||
|
@ -311,7 +314,8 @@ void Decoder::run()
|
|||
}
|
||||
}
|
||||
|
||||
processLineString((OGRLineString*)poGeometry, area_type_name, width, texture_lines);
|
||||
processLineString((OGRLineString*)poGeometry, area_type_name, width, texture_lines,
|
||||
texture_cliffs);
|
||||
break;
|
||||
}
|
||||
case wkbMultiLineString: {
|
||||
|
@ -326,7 +330,7 @@ void Decoder::run()
|
|||
|
||||
OGRMultiLineString* multilines=(OGRMultiLineString*)poGeometry;
|
||||
for (int i = 0; i < multilines->getNumGeometries(); ++i) {
|
||||
processLineString((OGRLineString*)(multilines->getGeometryRef(i)), area_type_name, width, texture_lines);
|
||||
processLineString((OGRLineString*)(multilines->getGeometryRef(i)), area_type_name, width, texture_lines, texture_cliffs);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -525,6 +529,8 @@ void usage(char* progname) {
|
|||
SG_LOG( SG_GENERAL, SG_ALERT, " spatial query extents" );
|
||||
SG_LOG( SG_GENERAL, SG_ALERT, "--texture-lines" );
|
||||
SG_LOG( SG_GENERAL, SG_ALERT, " Enable textured lines" );
|
||||
SG_LOG( SG_GENERAL, SG_ALERT, "--texture-cliffs" );
|
||||
SG_LOG( SG_GENERAL, SG_ALERT, " Generate texture coordinates for cliff faces" );
|
||||
SG_LOG( SG_GENERAL, SG_ALERT, "--threads" );
|
||||
SG_LOG( SG_GENERAL, SG_ALERT, " Enable multithreading with user specified number of threads" );
|
||||
SG_LOG( SG_GENERAL, SG_ALERT, "--all-threads" );
|
||||
|
@ -623,6 +629,10 @@ int main( int argc, char **argv ) {
|
|||
argv++;
|
||||
argc--;
|
||||
texture_lines=true;
|
||||
} else if (!strcmp(argv[1],"--texture-cliffs")) {
|
||||
argv++;
|
||||
argc--;
|
||||
texture_cliffs=true;
|
||||
} else if (!strcmp(argv[1],"--seperate-segments")) {
|
||||
argv++;
|
||||
argc--;
|
||||
|
|
Loading…
Add table
Reference in a new issue