Merge FG_Tools as subdirectory
This commit is contained in:
commit
c54ce2dd85
190 changed files with 52483 additions and 0 deletions
62
Tools/Areas/Makefile.am
Normal file
62
Tools/Areas/Makefile.am
Normal file
|
@ -0,0 +1,62 @@
|
|||
#---------------------------------------------------------------------------
|
||||
# Makefile
|
||||
#
|
||||
# Written by Curtis Olson, started January 1998.
|
||||
#
|
||||
# Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
|
||||
#
|
||||
# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
# $Id$
|
||||
# (Log is kept at end of this file)
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
|
||||
bin_PROGRAMS = areas
|
||||
|
||||
areas_SOURCES = area.cxx area.hxx main.cxx
|
||||
|
||||
areas_LDADD = \
|
||||
$(top_builddir)/Lib/Bucket/libBucket.a \
|
||||
$(base_LIBS)
|
||||
|
||||
INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# $Log$
|
||||
# Revision 1.3 1998/11/04 23:01:43 curt
|
||||
# Changes to the automake/autoconf system to reduce the number of libraries
|
||||
# that are unnecessarily linked into the various executables.
|
||||
#
|
||||
# Revision 1.2 1998/07/30 23:49:18 curt
|
||||
# Removed libtool support.
|
||||
#
|
||||
# Revision 1.1 1998/07/20 12:54:53 curt
|
||||
# Whoops, need to commit Makefile.am, not Makefile.
|
||||
#
|
||||
# Revision 1.2 1998/04/14 02:25:59 curt
|
||||
# Code reorganizations. Added a Lib/ directory for more general libraries.
|
||||
#
|
||||
# Revision 1.1 1998/04/08 22:54:57 curt
|
||||
# Adopted Gnu automake/autoconf system.
|
||||
#
|
||||
# Revision 1.2 1998/01/21 02:55:46 curt
|
||||
# Incorporated new make system from Bob Kuehne <rpk@sgi.com>.
|
||||
#
|
||||
# Revision 1.1 1998/01/15 02:45:25 curt
|
||||
# Initial revision.
|
||||
#
|
||||
|
161
Tools/Areas/area.cxx
Normal file
161
Tools/Areas/area.cxx
Normal file
|
@ -0,0 +1,161 @@
|
|||
// area.c -- routines to assist with inserting "areas" into FG terrain
|
||||
//
|
||||
// Written by Curtis Olson, started March 1998.
|
||||
//
|
||||
// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
//
|
||||
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Include/fg_constants.h>
|
||||
|
||||
#include "area.hxx"
|
||||
|
||||
|
||||
// calc new x, y for a rotation
|
||||
double rot_x(double x, double y, double theta) {
|
||||
return ( x * cos(theta) + y * sin(theta) );
|
||||
}
|
||||
|
||||
|
||||
// calc new x, y for a rotation
|
||||
double rot_y(double x, double y, double theta) {
|
||||
return ( -x * sin(theta) + y * cos(theta) );
|
||||
}
|
||||
|
||||
|
||||
// calc new lon/lat given starting lon/lat, and offset radial, and
|
||||
// distance. NOTE: distance is specified in meters (and converted
|
||||
// internally to radians)
|
||||
point2d calc_lon_lat( point2d orig, point2d offset ) {
|
||||
point2d result;
|
||||
|
||||
offset.dist *= METER_TO_NM * NM_TO_RAD;
|
||||
|
||||
result.lat = asin( sin(orig.lat) * cos(offset.dist) +
|
||||
cos(orig.lat) * sin(offset.dist) * cos(offset.theta) );
|
||||
|
||||
if ( cos(result.lat) < FG_EPSILON ) {
|
||||
result.lon = orig.lon; // endpoint a pole
|
||||
} else {
|
||||
result.lon =
|
||||
fmod(orig.lon - asin( sin(offset.theta) * sin(offset.dist) /
|
||||
cos(result.lat) ) + FG_PI, FG_2PI) - FG_PI;
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
point2d cart_to_polar_2d(point2d in) {
|
||||
point2d result;
|
||||
result.dist = sqrt( in.x * in.x + in.y * in.y );
|
||||
result.theta = atan2(in.y, in.x);
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
void batch_cart_to_polar_2d(point2d *in, point2d *out, int size) {
|
||||
int i;
|
||||
|
||||
for ( i = 0; i < size; i++ ) {
|
||||
out[i] = cart_to_polar_2d( in[i] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// given a set of 2d coordinates relative to a center point, and the
|
||||
// lon, lat of that center point, as well as a potential orientation
|
||||
// angle, generate the corresponding lon and lat of the original 2d
|
||||
// verticies.
|
||||
void make_area(point2d orig, point2d *cart, point2d *result,
|
||||
int size, double angle ) {
|
||||
point2d rad[size];
|
||||
int i;
|
||||
|
||||
// convert to polar coordinates
|
||||
batch_cart_to_polar_2d(cart, rad, size);
|
||||
for ( i = 0; i < size; i++ ) {
|
||||
printf("(%.2f, %.2f)\n", rad[i].dist, rad[i].theta);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
// rotate by specified angle
|
||||
for ( i = 0; i < size; i++ ) {
|
||||
rad[i].theta += angle;
|
||||
while ( rad[i].theta > FG_2PI ) {
|
||||
rad[i].theta -= FG_2PI;
|
||||
}
|
||||
printf("(%.2f, %.2f)\n", rad[i].dist, rad[i].theta);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
for ( i = 0; i < size; i++ ) {
|
||||
result[i] = calc_lon_lat(orig, rad[i]);
|
||||
printf("(%.8f, %.8f)\n", result[i].lon, result[i].lat);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
// generate an area for a runway
|
||||
void gen_runway_area( double lon, double lat, double heading,
|
||||
double length, double width,
|
||||
point2d *result, int *count)
|
||||
{
|
||||
point2d cart[4];
|
||||
point2d orig;
|
||||
double l, w;
|
||||
int i;
|
||||
|
||||
orig.lon = lon;
|
||||
orig.lat = lat;
|
||||
l = (length / 2.0) + (length * 0.1);
|
||||
w = (width / 2.0) + (width * 0.1);
|
||||
|
||||
// generate untransformed runway area vertices
|
||||
cart[0].x = l; cart[0].y = w;
|
||||
cart[1].x = l; cart[1].y = -w;
|
||||
cart[2].x = -l; cart[2].y = -w;
|
||||
cart[3].x = -l; cart[3].y = w;
|
||||
for ( i = 0; i < 4; i++ ) {
|
||||
printf("(%.2f, %.2f)\n", cart[i].x, cart[i].y);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
make_area(orig, cart, result, 4, heading);
|
||||
|
||||
for ( i = 0; i < 4; i++ ) {
|
||||
printf("(%.8f, %.8f)\n", result[i].lon, result[i].lat);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
*count = 4;
|
||||
}
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.1 1998/07/20 12:54:05 curt
|
||||
// Initial revision.
|
||||
//
|
||||
//
|
57
Tools/Areas/area.hxx
Normal file
57
Tools/Areas/area.hxx
Normal file
|
@ -0,0 +1,57 @@
|
|||
// area.h -- routines to assist with inserting "areas" into FG terrain
|
||||
//
|
||||
// Written by Curtis Olson, started February 1998.
|
||||
//
|
||||
// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
//
|
||||
|
||||
|
||||
#ifndef _AREA_H
|
||||
#define _AREA_H
|
||||
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
double x;
|
||||
double dist;
|
||||
double lon;
|
||||
};
|
||||
union {
|
||||
double y;
|
||||
double theta;
|
||||
double lat;
|
||||
};
|
||||
} point2d;
|
||||
|
||||
|
||||
// generate an area for a runway
|
||||
void gen_runway_area( double lon, double lat, double heading,
|
||||
double length, double width,
|
||||
point2d *result, int *count );
|
||||
|
||||
|
||||
#endif // _AREA_H
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.1 1998/07/20 12:54:05 curt
|
||||
// Initial revision.
|
||||
//
|
||||
//
|
130
Tools/Areas/main.cxx
Normal file
130
Tools/Areas/main.cxx
Normal file
|
@ -0,0 +1,130 @@
|
|||
// main.c -- main loop
|
||||
//
|
||||
// Written by Curtis Olson, started March 1998.
|
||||
//
|
||||
// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
//
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "area.hxx"
|
||||
|
||||
#include <Bucket/bucketutils.h>
|
||||
#include <Include/fg_constants.h>
|
||||
|
||||
|
||||
int main( int argc, char **argv ) {
|
||||
fgBUCKET b;
|
||||
point2d nodes[4];
|
||||
FILE *fd;
|
||||
char base[256], path[256], command[256], file[256], exfile[256];
|
||||
double lon, lat, elevation, heading;
|
||||
double length, width;
|
||||
long int index;
|
||||
int i, count;
|
||||
|
||||
if ( argc != 2 ) {
|
||||
printf("Usage %s <work dir>\n", argv[0]);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// P13 (Globe, AZ)
|
||||
// lon = -110.6642442;
|
||||
// lat = 33.3528903;
|
||||
// heading = 102.0 * DEG_TO_RAD;
|
||||
// length = 1769;
|
||||
// width = 23;
|
||||
|
||||
// KANE
|
||||
lon = -93.2113889;
|
||||
lat = 45.145;
|
||||
elevation = 912 * FEET_TO_METER;
|
||||
heading = 270.0 * DEG_TO_RAD;
|
||||
length = 1220;
|
||||
width = 23;
|
||||
|
||||
gen_runway_area( lon * DEG_TO_RAD, lat * DEG_TO_RAD,
|
||||
heading, length, width, nodes, &count );
|
||||
|
||||
fgBucketFind(lon, lat, &b);
|
||||
printf( "Bucket = lon,lat = %d,%d x,y index = %d,%d\n",
|
||||
b.lon, b.lat, b.x, b.y);
|
||||
|
||||
index = fgBucketGenIndex(&b);
|
||||
fgBucketGenBasePath(&b, base);
|
||||
sprintf(path, "%s/Scenery/%s", argv[1], base);
|
||||
sprintf(command, "mkdir -p %s\n", path);
|
||||
system(command);
|
||||
|
||||
sprintf(exfile, "%s/%ld.node.ex", path, index);
|
||||
sprintf(file, "%s/%ld.poly", path, index);
|
||||
printf( "extra node file = %s\n", exfile);
|
||||
printf( "poly file = %s\n", file);
|
||||
|
||||
// output extra nodes
|
||||
if ( (fd = fopen(exfile, "w")) == NULL ) {
|
||||
printf("Cannot open file: %s\n", exfile);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
fprintf(fd, "%d 2 0 0\n", count);
|
||||
for ( i = 0; i < count; i++ ) {
|
||||
fprintf( fd, "%d %.2f %.2f %.2f\n", i + 1,
|
||||
nodes[i].lon * RAD_TO_ARCSEC, nodes[i].lat * RAD_TO_ARCSEC,
|
||||
elevation);
|
||||
}
|
||||
fclose(fd);
|
||||
|
||||
// output poly
|
||||
if ( (fd = fopen(file, "w")) == NULL ) {
|
||||
printf("Cannot open file: %s\n", file);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// output empty node list
|
||||
fprintf(fd, "0 2 0 0\n");
|
||||
|
||||
// output segments
|
||||
fprintf(fd, "%d 0\n", count);
|
||||
for ( i = 0; i < count - 1; i++ ) {
|
||||
fprintf( fd, "%d %d %d\n", i + 1, i + 1, i + 2 );
|
||||
}
|
||||
fprintf( fd, "%d %d %d\n", count, count, 1 );
|
||||
|
||||
// output hole center
|
||||
fprintf( fd, "1\n");
|
||||
fprintf( fd, "1 %.2f %.2f\n", lon * 3600.0, lat * 3600);
|
||||
|
||||
fclose(fd);
|
||||
}
|
||||
|
||||
|
||||
// $Log: main.c,v
|
||||
//
|
25
Tools/Array/Makefile.am
Normal file
25
Tools/Array/Makefile.am
Normal file
|
@ -0,0 +1,25 @@
|
|||
noinst_LIBRARIES = libArray.a
|
||||
|
||||
libArray_a_SOURCES = array.cxx array.hxx
|
||||
|
||||
bin_PROGRAMS = testarray
|
||||
|
||||
testarray_SOURCES = testarray.cxx
|
||||
|
||||
testarray_LDADD = \
|
||||
$(top_builddir)/Tools/Construct/Array/libArray.a \
|
||||
$(top_builddir)/Lib/Bucket/libBucket.a \
|
||||
$(top_builddir)/Lib/Math/libMath.a \
|
||||
$(top_builddir)/Lib/Misc/libMisc.a \
|
||||
$(top_builddir)/Lib/zlib/libz.a
|
||||
|
||||
INCLUDES += \
|
||||
-I$(top_builddir) \
|
||||
-I$(top_builddir)/Lib \
|
||||
-I$(top_builddir)/Tools/Construct
|
||||
|
||||
# We can't build this with "-O2" (optimization) since this causes a seg fault
|
||||
# I haven't found a way to strip this out of the CXXFLAGS, so I'm just
|
||||
# setting it to "-g"
|
||||
# CXXFLAGS = -g
|
||||
|
607
Tools/Array/array.cxx
Normal file
607
Tools/Array/array.cxx
Normal file
|
@ -0,0 +1,607 @@
|
|||
// array.cxx -- Array management class
|
||||
//
|
||||
// Written by Curtis Olson, started March 1998.
|
||||
//
|
||||
// Copyright (C) 1998 - 1999 Curtis L. Olson - curt@flightgear.org
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <Include/compiler.h>
|
||||
|
||||
// #include <ctype.h> // isspace()
|
||||
// #include <stdlib.h> // atoi()
|
||||
// #include <math.h> // rint()
|
||||
// #include <stdio.h>
|
||||
// #include <string.h>
|
||||
// #ifdef HAVE_SYS_STAT_H
|
||||
// # include <sys/stat.h> // stat()
|
||||
// #endif
|
||||
// #ifdef FG_HAVE_STD_INCLUDES
|
||||
// # include <cerrno>
|
||||
// #else
|
||||
// # include <errno.h>
|
||||
// #endif
|
||||
// #ifdef HAVE_UNISTD_H
|
||||
// # include <unistd.h> // stat()
|
||||
// #endif
|
||||
|
||||
#include STL_STRING
|
||||
|
||||
#include <Include/fg_constants.h>
|
||||
#include <Misc/fgstream.hxx>
|
||||
#include <Misc/strutils.hxx>
|
||||
#include <Math/leastsqs.hxx>
|
||||
|
||||
#include "array.hxx"
|
||||
|
||||
FG_USING_STD(string);
|
||||
|
||||
|
||||
FGArray::FGArray( void ) {
|
||||
// cout << "class FGArray CONstructor called." << endl;
|
||||
in_data = new float[ARRAY_SIZE_1][ARRAY_SIZE_1];
|
||||
// out_data = new float[ARRAY_SIZE_1][ARRAY_SIZE_1];
|
||||
}
|
||||
|
||||
|
||||
FGArray::FGArray( const string &file ) {
|
||||
// cout << "class FGArray CONstructor called." << endl;
|
||||
in_data = new float[ARRAY_SIZE_1][ARRAY_SIZE_1];
|
||||
// out_data = new float[ARRAY_SIZE_1][ARRAY_SIZE_1];
|
||||
|
||||
FGArray::open(file);
|
||||
}
|
||||
|
||||
|
||||
// open an Array file
|
||||
int
|
||||
FGArray::open( const string& file ) {
|
||||
// open input file (or read from stdin)
|
||||
if ( file == "-" ) {
|
||||
cout << " Opening array data pipe from stdin" << endl;
|
||||
// fd = stdin;
|
||||
// fd = gzdopen(STDIN_FILENO, "r");
|
||||
cout << " Not yet ported ..." << endl;
|
||||
return 0;
|
||||
} else {
|
||||
in = new fg_gzifstream( file );
|
||||
if ( ! in->is_open() ) {
|
||||
cout << " Cannot open " << file << endl;
|
||||
return 0;
|
||||
}
|
||||
cout << " Opening array data file: " << file << endl;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// close an Array file
|
||||
int
|
||||
FGArray::close() {
|
||||
// the fg_gzifstream doesn't seem to have a close()
|
||||
|
||||
delete in;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// parse Array file, pass in the bucket so we can make up values when
|
||||
// the file wasn't found.
|
||||
int
|
||||
FGArray::parse( FGBucket& b ) {
|
||||
if ( in->is_open() ) {
|
||||
// file open, parse
|
||||
*in >> originx >> originy;
|
||||
*in >> cols >> col_step;
|
||||
*in >> rows >> row_step;
|
||||
|
||||
cout << " origin = " << originx << " " << originy << endl;
|
||||
cout << " cols = " << cols << " rows = " << rows << endl;
|
||||
cout << " col_step = " << col_step
|
||||
<< " row_step = " << row_step <<endl;
|
||||
|
||||
for ( int i = 0; i < cols; i++ ) {
|
||||
for ( int j = 0; j < rows; j++ ) {
|
||||
*in >> in_data[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
cout << " Done parsing\n";
|
||||
} else {
|
||||
// file not open (not found?), fill with zero'd data
|
||||
|
||||
originx = ( b.get_center_lon() - 0.5 * b.get_width() ) * 3600.0;
|
||||
originy = ( b.get_center_lat() - 0.5 * b.get_height() ) * 3600.0;
|
||||
|
||||
double max_x = ( b.get_center_lon() + 0.5 * b.get_width() ) * 3600.0;
|
||||
double max_y = ( b.get_center_lat() + 0.5 * b.get_height() ) * 3600.0;
|
||||
|
||||
cols = 3;
|
||||
col_step = (max_x - originx) / (cols - 1);
|
||||
rows = 3;
|
||||
row_step = (max_y - originy) / (rows - 1);
|
||||
|
||||
cout << " origin = " << originx << " " << originy << endl;
|
||||
cout << " cols = " << cols << " rows = " << rows << endl;
|
||||
cout << " col_step = " << col_step
|
||||
<< " row_step = " << row_step <<endl;
|
||||
|
||||
for ( int i = 0; i < cols; i++ ) {
|
||||
for ( int j = 0; j < rows; j++ ) {
|
||||
in_data[i][j] = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
cout << " File not open, so using zero'd data" << endl;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// add a node to the output corner node list
|
||||
void FGArray::add_corner_node( int i, int j, double val ) {
|
||||
|
||||
double x = (originx + i * col_step) / 3600.0;
|
||||
double y = (originy + j * row_step) / 3600.0;
|
||||
// cout << "originx = " << originx << " originy = " << originy << endl;
|
||||
// cout << "corner = " << Point3D(x, y, val) << endl;
|
||||
corner_list.push_back( Point3D(x, y, val) );
|
||||
}
|
||||
|
||||
|
||||
// add a node to the output fitted node list
|
||||
void FGArray::add_fit_node( int i, int j, double val ) {
|
||||
double x = (originx + i * col_step) / 3600.0;
|
||||
double y = (originy + j * row_step) / 3600.0;
|
||||
// cout << Point3D(x, y, val) << endl;
|
||||
node_list.push_back( Point3D(x, y, val) );
|
||||
}
|
||||
|
||||
|
||||
// Use least squares to fit a simpler data set to dem data. Return
|
||||
// the number of fitted nodes
|
||||
int FGArray::fit( double error ) {
|
||||
double x[ARRAY_SIZE_1], y[ARRAY_SIZE_1];
|
||||
double m, b, max_error, error_sq;
|
||||
double x1, y1;
|
||||
// double ave_error;
|
||||
double cury, lasty;
|
||||
int n, row, start, end;
|
||||
int colmin, colmax, rowmin, rowmax;
|
||||
bool good_fit;
|
||||
// FILE *dem, *fit, *fit1;
|
||||
|
||||
error_sq = error * error;
|
||||
|
||||
cout << " Initializing fitted node list" << endl;
|
||||
corner_list.clear();
|
||||
node_list.clear();
|
||||
|
||||
// determine dimensions
|
||||
colmin = 0;
|
||||
colmax = cols;
|
||||
rowmin = 0;
|
||||
rowmax = rows;
|
||||
cout << " Fitting region = " << colmin << "," << rowmin << " to "
|
||||
<< colmax << "," << rowmax << endl;;
|
||||
|
||||
// generate corners list
|
||||
add_corner_node( colmin, rowmin, in_data[colmin][rowmin] );
|
||||
add_corner_node( colmin, rowmax-1, in_data[colmin][rowmax] );
|
||||
add_corner_node( colmax-1, rowmin, in_data[colmax][rowmin] );
|
||||
add_corner_node( colmax-1, rowmax-1, in_data[colmax][rowmax] );
|
||||
|
||||
cout << " Beginning best fit procedure" << endl;
|
||||
lasty = 0;
|
||||
|
||||
for ( row = rowmin; row < rowmax; row++ ) {
|
||||
// fit = fopen("fit.dat", "w");
|
||||
// fit1 = fopen("fit1.dat", "w");
|
||||
|
||||
start = colmin;
|
||||
|
||||
// cout << " fitting row = " << row << endl;
|
||||
|
||||
while ( start < colmax - 1 ) {
|
||||
end = start + 1;
|
||||
good_fit = true;
|
||||
|
||||
x[0] = start * col_step;
|
||||
y[0] = in_data[start][row];
|
||||
|
||||
x[1] = end * col_step;
|
||||
y[1] = in_data[end][row];
|
||||
|
||||
n = 2;
|
||||
|
||||
// cout << "Least square of first 2 points" << endl;
|
||||
least_squares(x, y, n, &m, &b);
|
||||
|
||||
end++;
|
||||
|
||||
while ( (end < colmax) && good_fit ) {
|
||||
++n;
|
||||
// cout << "Least square of first " << n << " points" << endl;
|
||||
x[n-1] = x1 = end * col_step;
|
||||
y[n-1] = y1 = in_data[end][row];
|
||||
least_squares_update(x1, y1, &m, &b);
|
||||
// ave_error = least_squares_error(x, y, n, m, b);
|
||||
max_error = least_squares_max_error(x, y, n, m, b);
|
||||
|
||||
/*
|
||||
printf("%d - %d ave error = %.2f max error = %.2f y = %.2f*x + %.2f\n",
|
||||
start, end, ave_error, max_error, m, b);
|
||||
|
||||
f = fopen("gnuplot.dat", "w");
|
||||
for ( j = 0; j <= end; j++) {
|
||||
fprintf(f, "%.2f %.2f\n", 0.0 + ( j * col_step ),
|
||||
in_data[row][j]);
|
||||
}
|
||||
for ( j = start; j <= end; j++) {
|
||||
fprintf(f, "%.2f %.2f\n", 0.0 + ( j * col_step ),
|
||||
in_data[row][j]);
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
printf("Please hit return: "); gets(junk);
|
||||
*/
|
||||
|
||||
if ( max_error > error_sq ) {
|
||||
good_fit = false;
|
||||
}
|
||||
|
||||
end++;
|
||||
}
|
||||
|
||||
if ( !good_fit ) {
|
||||
// error exceeded the threshold, back up
|
||||
end -= 2; // back "end" up to the last good enough fit
|
||||
n--; // back "n" up appropriately too
|
||||
} else {
|
||||
// we popped out of the above loop while still within
|
||||
// the error threshold, so we must be at the end of
|
||||
// the data set
|
||||
end--;
|
||||
}
|
||||
|
||||
least_squares(x, y, n, &m, &b);
|
||||
// ave_error = least_squares_error(x, y, n, m, b);
|
||||
max_error = least_squares_max_error(x, y, n, m, b);
|
||||
|
||||
/*
|
||||
printf("\n");
|
||||
printf("%d - %d ave error = %.2f max error = %.2f y = %.2f*x + %.2f\n",
|
||||
start, end, ave_error, max_error, m, b);
|
||||
printf("\n");
|
||||
|
||||
fprintf(fit1, "%.2f %.2f\n", x[0], m * x[0] + b);
|
||||
fprintf(fit1, "%.2f %.2f\n", x[end-start], m * x[end-start] + b);
|
||||
*/
|
||||
|
||||
if ( start > colmin ) {
|
||||
// skip this for the first line segment
|
||||
cury = m * x[0] + b;
|
||||
add_fit_node( start, row, (lasty + cury) / 2 );
|
||||
// fprintf(fit, "%.2f %.2f\n", x[0], (lasty + cury) / 2);
|
||||
}
|
||||
|
||||
lasty = m * x[end-start] + b;
|
||||
start = end;
|
||||
}
|
||||
|
||||
/*
|
||||
fclose(fit);
|
||||
fclose(fit1);
|
||||
|
||||
dem = fopen("gnuplot.dat", "w");
|
||||
for ( j = 0; j < ARRAY_SIZE_1; j++) {
|
||||
fprintf(dem, "%.2f %.2f\n", 0.0 + ( j * col_step ),
|
||||
in_data[j][row]);
|
||||
}
|
||||
fclose(dem);
|
||||
*/
|
||||
|
||||
// NOTICE, this is for testing only. This instance of
|
||||
// output_nodes should be removed. It should be called only
|
||||
// once at the end once all the nodes have been generated.
|
||||
// newmesh_output_nodes(&nm, "mesh.node");
|
||||
// printf("Please hit return: "); gets(junk);
|
||||
}
|
||||
|
||||
// outputmesh_output_nodes(fg_root, p);
|
||||
|
||||
// return fit nodes + 4 corners
|
||||
return node_list.size() + 4;
|
||||
}
|
||||
|
||||
|
||||
// return the current altitude based on grid data. We should rewrite
|
||||
// this to interpolate exact values, but for now this is good enough
|
||||
double FGArray::interpolate_altitude( double lon, double lat ) const {
|
||||
// we expect incoming (lon,lat) to be in arcsec for now
|
||||
|
||||
double xlocal, ylocal, dx, dy, zA, zB, elev;
|
||||
int x1, x2, x3, y1, y2, y3;
|
||||
float z1, z2, z3;
|
||||
int xindex, yindex;
|
||||
|
||||
/* determine if we are in the lower triangle or the upper triangle
|
||||
______
|
||||
| /|
|
||||
| / |
|
||||
| / |
|
||||
|/ |
|
||||
------
|
||||
|
||||
then calculate our end points
|
||||
*/
|
||||
|
||||
xlocal = (lon - originx) / col_step;
|
||||
ylocal = (lat - originy) / row_step;
|
||||
|
||||
xindex = (int)(xlocal);
|
||||
yindex = (int)(ylocal);
|
||||
|
||||
// printf("xindex = %d yindex = %d\n", xindex, yindex);
|
||||
|
||||
if ( xindex + 1 == cols ) {
|
||||
xindex--;
|
||||
}
|
||||
|
||||
if ( yindex + 1 == rows ) {
|
||||
yindex--;
|
||||
}
|
||||
|
||||
if ( (xindex < 0) || (xindex + 1 >= cols) ||
|
||||
(yindex < 0) || (yindex + 1 >= rows) ) {
|
||||
cout << "WARNING: Attempt to interpolate value outside of array!!!"
|
||||
<< endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
dx = xlocal - xindex;
|
||||
dy = ylocal - yindex;
|
||||
|
||||
if ( dx > dy ) {
|
||||
// lower triangle
|
||||
// printf(" Lower triangle\n");
|
||||
|
||||
x1 = xindex;
|
||||
y1 = yindex;
|
||||
z1 = in_data[x1][y1];
|
||||
|
||||
x2 = xindex + 1;
|
||||
y2 = yindex;
|
||||
z2 = in_data[x2][y2];
|
||||
|
||||
x3 = xindex + 1;
|
||||
y3 = yindex + 1;
|
||||
z3 = in_data[x3][y3];
|
||||
|
||||
// printf(" dx = %.2f dy = %.2f\n", dx, dy);
|
||||
// printf(" (x1,y1,z1) = (%d,%d,%d)\n", x1, y1, z1);
|
||||
// printf(" (x2,y2,z2) = (%d,%d,%d)\n", x2, y2, z2);
|
||||
// printf(" (x3,y3,z3) = (%d,%d,%d)\n", x3, y3, z3);
|
||||
|
||||
zA = dx * (z2 - z1) + z1;
|
||||
zB = dx * (z3 - z1) + z1;
|
||||
|
||||
// printf(" zA = %.2f zB = %.2f\n", zA, zB);
|
||||
|
||||
if ( dx > FG_EPSILON ) {
|
||||
elev = dy * (zB - zA) / dx + zA;
|
||||
} else {
|
||||
elev = zA;
|
||||
}
|
||||
} else {
|
||||
// upper triangle
|
||||
// printf(" Upper triangle\n");
|
||||
|
||||
x1 = xindex;
|
||||
y1 = yindex;
|
||||
z1 = in_data[x1][y1];
|
||||
|
||||
x2 = xindex;
|
||||
y2 = yindex + 1;
|
||||
z2 = in_data[x2][y2];
|
||||
|
||||
x3 = xindex + 1;
|
||||
y3 = yindex + 1;
|
||||
z3 = in_data[x3][y3];
|
||||
|
||||
// printf(" dx = %.2f dy = %.2f\n", dx, dy);
|
||||
// printf(" (x1,y1,z1) = (%d,%d,%d)\n", x1, y1, z1);
|
||||
// printf(" (x2,y2,z2) = (%d,%d,%d)\n", x2, y2, z2);
|
||||
// printf(" (x3,y3,z3) = (%d,%d,%d)\n", x3, y3, z3);
|
||||
|
||||
zA = dy * (z2 - z1) + z1;
|
||||
zB = dy * (z3 - z1) + z1;
|
||||
|
||||
// printf(" zA = %.2f zB = %.2f\n", zA, zB );
|
||||
// printf(" xB - xA = %.2f\n", col_step * dy / row_step);
|
||||
|
||||
if ( dy > FG_EPSILON ) {
|
||||
elev = dx * (zB - zA) / dy + zA;
|
||||
} else {
|
||||
elev = zA;
|
||||
}
|
||||
}
|
||||
|
||||
return(elev);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
// Write out a node file that can be used by the "triangle" program.
|
||||
// Check for an optional "index.node.ex" file in case there is a .poly
|
||||
// file to go along with this node file. Include these nodes first
|
||||
// since they are referenced by position from the .poly file.
|
||||
void FGArray::outputmesh_output_nodes( const string& fg_root, FGBucket& p )
|
||||
{
|
||||
double exnodes[MAX_EX_NODES][3];
|
||||
struct stat stat_buf;
|
||||
string dir, file;
|
||||
char exfile[256];
|
||||
#ifdef WIN32
|
||||
char tmp_path[256];
|
||||
#endif
|
||||
string command;
|
||||
FILE *fd;
|
||||
int colmin, colmax, rowmin, rowmax;
|
||||
int i, j, count, excount, result;
|
||||
|
||||
// determine dimensions
|
||||
colmin = p.get_x() * ( (cols - 1) / 8);
|
||||
colmax = colmin + ( (cols - 1) / 8);
|
||||
rowmin = p.get_y() * ( (rows - 1) / 8);
|
||||
rowmax = rowmin + ( (rows - 1) / 8);
|
||||
cout << " dumping region = " << colmin << "," << rowmin << " to " <<
|
||||
colmax << "," << rowmax << "\n";
|
||||
|
||||
// generate the base directory
|
||||
string base_path = p.gen_base_path();
|
||||
cout << " fg_root = " << fg_root << " Base Path = " << base_path << endl;
|
||||
dir = fg_root + "/Scenery/" + base_path;
|
||||
cout << " Dir = " << dir << endl;
|
||||
|
||||
// stat() directory and create if needed
|
||||
errno = 0;
|
||||
result = stat(dir.c_str(), &stat_buf);
|
||||
if ( result != 0 && errno == ENOENT ) {
|
||||
cout << " Creating directory\n";
|
||||
|
||||
command = "mkdir -p " + dir + "\n";
|
||||
system( command.c_str() );
|
||||
} else {
|
||||
// assume directory exists
|
||||
}
|
||||
|
||||
// get index and generate output file name
|
||||
file = dir + "/" + p.gen_index_str() + ".node";
|
||||
|
||||
// get (optional) extra node file name (in case there is matching
|
||||
// .poly file.
|
||||
exfile = file + ".ex";
|
||||
|
||||
// load extra nodes if they exist
|
||||
excount = 0;
|
||||
if ( (fd = fopen(exfile, "r")) != NULL ) {
|
||||
int junki;
|
||||
fscanf(fd, "%d %d %d %d", &excount, &junki, &junki, &junki);
|
||||
|
||||
if ( excount > MAX_EX_NODES - 1 ) {
|
||||
printf("Error, too many 'extra' nodes, increase array size\n");
|
||||
exit(-1);
|
||||
} else {
|
||||
printf(" Expecting %d 'extra' nodes\n", excount);
|
||||
}
|
||||
|
||||
for ( i = 1; i <= excount; i++ ) {
|
||||
fscanf(fd, "%d %lf %lf %lf\n", &junki,
|
||||
&exnodes[i][0], &exnodes[i][1], &exnodes[i][2]);
|
||||
printf("(extra) %d %.2f %.2f %.2f\n",
|
||||
i, exnodes[i][0], exnodes[i][1], exnodes[i][2]);
|
||||
}
|
||||
fclose(fd);
|
||||
}
|
||||
|
||||
printf("Creating node file: %s\n", file);
|
||||
fd = fopen(file, "w");
|
||||
|
||||
// first count regular nodes to generate header
|
||||
count = 0;
|
||||
for ( j = rowmin; j <= rowmax; j++ ) {
|
||||
for ( i = colmin; i <= colmax; i++ ) {
|
||||
if ( out_data[i][j] > -9000.0 ) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
// printf(" count = %d\n", count);
|
||||
}
|
||||
fprintf(fd, "%d 2 1 0\n", count + excount);
|
||||
|
||||
// now write out extra node data
|
||||
for ( i = 1; i <= excount; i++ ) {
|
||||
fprintf(fd, "%d %.2f %.2f %.2f\n",
|
||||
i, exnodes[i][0], exnodes[i][1], exnodes[i][2]);
|
||||
}
|
||||
|
||||
// write out actual node data
|
||||
count = excount + 1;
|
||||
for ( j = rowmin; j <= rowmax; j++ ) {
|
||||
for ( i = colmin; i <= colmax; i++ ) {
|
||||
if ( out_data[i][j] > -9000.0 ) {
|
||||
fprintf(fd, "%d %.2f %.2f %.2f\n",
|
||||
count++,
|
||||
originx + (double)i * col_step,
|
||||
originy + (double)j * row_step,
|
||||
out_data[i][j]);
|
||||
}
|
||||
}
|
||||
// printf(" count = %d\n", count);
|
||||
}
|
||||
|
||||
fclose(fd);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
FGArray::~FGArray( void ) {
|
||||
// printf("class FGArray DEstructor called.\n");
|
||||
delete [] in_data;
|
||||
// delete [] out_data;
|
||||
}
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.8 1999/04/05 02:15:23 curt
|
||||
// Make dem fitting more robust in cases when no dem file available.
|
||||
//
|
||||
// Revision 1.7 1999/03/27 14:05:10 curt
|
||||
// More sensible handling of the case where no dem file for this tile exists
|
||||
// (or has been generated).
|
||||
//
|
||||
// Revision 1.6 1999/03/27 05:20:13 curt
|
||||
// Handle corner nodes separately from the rest of the fitted nodes.
|
||||
// Fixed some "const" related warnings.
|
||||
//
|
||||
// Revision 1.5 1999/03/25 19:03:50 curt
|
||||
// Minor tweaks related to FGBucket usage.
|
||||
//
|
||||
// Revision 1.4 1999/03/20 20:32:51 curt
|
||||
// First mostly successful tile triangulation works. There's plenty of tweaking
|
||||
// to do, but we are marching in the right direction.
|
||||
//
|
||||
// Revision 1.3 1999/03/17 23:48:17 curt
|
||||
// Removed forced -g compile flag.
|
||||
// Fixed a couple compiler warnings.
|
||||
//
|
||||
// Revision 1.2 1999/03/13 23:50:26 curt
|
||||
// Tweaked output formatting a bit.
|
||||
//
|
||||
// Revision 1.1 1999/03/13 18:45:02 curt
|
||||
// Initial revision. (derived from libDEM.a code.)
|
||||
//
|
146
Tools/Array/array.hxx
Normal file
146
Tools/Array/array.hxx
Normal file
|
@ -0,0 +1,146 @@
|
|||
// array.hxx -- Array management class
|
||||
//
|
||||
// Written by Curtis Olson, started March 1998.
|
||||
//
|
||||
// Copyright (C) 1998 - 1999 Curtis L. Olson - curt@flightgear.org
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
|
||||
|
||||
#ifndef _ARRAY_HXX
|
||||
#define _ARRAY_HXX
|
||||
|
||||
|
||||
#ifndef __cplusplus
|
||||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
|
||||
#include <Include/compiler.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <Bucket/newbucket.hxx>
|
||||
#include <Math/point3d.hxx>
|
||||
#include <Misc/fgstream.hxx>
|
||||
|
||||
#include <Main/construct_types.hxx>
|
||||
|
||||
FG_USING_STD(vector);
|
||||
|
||||
|
||||
#define ARRAY_SIZE 1200
|
||||
#define ARRAY_SIZE_1 1201
|
||||
|
||||
|
||||
class FGArray {
|
||||
|
||||
private:
|
||||
|
||||
// file pointer for input
|
||||
// gzFile fd;
|
||||
fg_gzifstream *in;
|
||||
|
||||
// coordinates (in arc seconds) of south west corner
|
||||
double originx, originy;
|
||||
|
||||
// number of columns and rows
|
||||
int cols, rows;
|
||||
|
||||
// Distance between column and row data points (in arc seconds)
|
||||
double col_step, row_step;
|
||||
|
||||
// pointers to the actual grid data allocated here
|
||||
float (*in_data)[ARRAY_SIZE_1];
|
||||
// float (*out_data)[ARRAY_SIZE_1];
|
||||
|
||||
// output nodes
|
||||
point_list corner_list;
|
||||
point_list node_list;
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
FGArray( void );
|
||||
FGArray( const string& file );
|
||||
|
||||
// Destructor
|
||||
~FGArray( void );
|
||||
|
||||
// open an Array file (use "-" if input is coming from stdin)
|
||||
int open ( const string& file );
|
||||
|
||||
// close a Array file
|
||||
int close();
|
||||
|
||||
// parse a Array file
|
||||
int parse( FGBucket& b );
|
||||
|
||||
// Use least squares to fit a simpler data set to dem data.
|
||||
// Return the number of fitted nodes
|
||||
int fit( double error );
|
||||
|
||||
// add a node to the output corner node list
|
||||
void add_corner_node( int i, int j, double val );
|
||||
|
||||
// add a node to the output fitted node list
|
||||
void add_fit_node( int i, int j, double val );
|
||||
|
||||
// return the current altitude based on grid data. We should
|
||||
// rewrite this to interpolate exact values, but for now this is
|
||||
// good enough
|
||||
double interpolate_altitude( double lon, double lat ) const;
|
||||
|
||||
// Informational methods
|
||||
inline double get_originx() const { return originx; }
|
||||
inline double get_originy() const { return originy; }
|
||||
inline int get_cols() const { return cols; }
|
||||
inline int get_rows() const { return rows; }
|
||||
inline double get_col_step() const { return col_step; }
|
||||
inline double get_row_step() const { return row_step; }
|
||||
|
||||
inline point_list get_corner_node_list() const { return corner_list; }
|
||||
inline point_list get_fit_node_list() const { return node_list; }
|
||||
};
|
||||
|
||||
|
||||
#endif // _ARRAY_HXX
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.6 1999/04/05 02:15:24 curt
|
||||
// Make dem fitting more robust in cases when no dem file available.
|
||||
//
|
||||
// Revision 1.5 1999/03/29 13:11:02 curt
|
||||
// Shuffled stl type names a bit.
|
||||
// Began adding support for tri-fanning (or maybe other arrangments too.)
|
||||
//
|
||||
// Revision 1.4 1999/03/27 05:20:14 curt
|
||||
// Handle corner nodes separately from the rest of the fitted nodes.
|
||||
// Fixed some "const" related warnings.
|
||||
//
|
||||
// Revision 1.3 1999/03/20 20:32:52 curt
|
||||
// First mostly successful tile triangulation works. There's plenty of tweaking
|
||||
// to do, but we are marching in the right direction.
|
||||
//
|
||||
// Revision 1.2 1999/03/13 23:50:27 curt
|
||||
// Tweaked output formatting a bit.
|
||||
//
|
||||
// Revision 1.1 1999/03/13 18:45:02 curt
|
||||
// Initial revision. (derived from libDEM.a code.)
|
||||
//
|
33
Tools/Array/testarray.cxx
Normal file
33
Tools/Array/testarray.cxx
Normal file
|
@ -0,0 +1,33 @@
|
|||
#include <Bucket/newbucket.hxx>
|
||||
|
||||
#include "array.hxx"
|
||||
|
||||
main(int argc, char **argv) {
|
||||
double lon, lat;
|
||||
|
||||
if ( argc != 2 ) {
|
||||
cout << "Usage: " << argv[0] << " work_dir" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
string work_dir = argv[1];
|
||||
|
||||
lon = -146.248360; lat = 61.133950; // PAVD (Valdez, AK)
|
||||
lon = -110.664244; lat = 33.352890; // P13
|
||||
|
||||
FGBucket b( lon, lat );
|
||||
string base = b.gen_base_path();
|
||||
string path = work_dir + "/Scenery/" + base;
|
||||
|
||||
string arrayfile = path + "/" + b.gen_index_str() + ".dem";
|
||||
cout << "arrayfile = " << arrayfile << endl;
|
||||
|
||||
FGArray a(arrayfile);
|
||||
a.parse( b );
|
||||
|
||||
lon *= 3600;
|
||||
lat *= 3600;
|
||||
cout << " " << a.interpolate_altitude(lon, lat) << endl;
|
||||
|
||||
a.fit( 100 );
|
||||
}
|
62
Tools/AssemTris/Makefile.am
Normal file
62
Tools/AssemTris/Makefile.am
Normal file
|
@ -0,0 +1,62 @@
|
|||
#---------------------------------------------------------------------------
|
||||
# Makefile
|
||||
#
|
||||
# Written by Curtis Olson, started January 1998.
|
||||
#
|
||||
# Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
|
||||
#
|
||||
# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
# $Id$
|
||||
# (Log is kept at end of this file)
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
|
||||
bin_PROGRAMS = assemtris
|
||||
|
||||
assemtris_SOURCES = assemtris.cxx assemtris.hxx
|
||||
|
||||
assemtris_LDADD = \
|
||||
$(top_builddir)/Lib/Bucket/libBucket.a \
|
||||
$(base_LIBS)
|
||||
|
||||
INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# $Log$
|
||||
# Revision 1.5 1998/11/04 23:01:45 curt
|
||||
# Changes to the automake/autoconf system to reduce the number of libraries
|
||||
# that are unnecessarily linked into the various executables.
|
||||
#
|
||||
# Revision 1.4 1998/09/25 19:35:25 curt
|
||||
# Renamed assemtris.[ch] to assemtris.[ch]xx
|
||||
#
|
||||
# Revision 1.3 1998/07/30 23:49:23 curt
|
||||
# Removed libtool support.
|
||||
#
|
||||
# Revision 1.2 1998/04/14 02:25:59 curt
|
||||
# Code reorganizations. Added a Lib/ directory for more general libraries.
|
||||
#
|
||||
# Revision 1.1 1998/04/08 22:54:57 curt
|
||||
# Adopted Gnu automake/autoconf system.
|
||||
#
|
||||
# Revision 1.2 1998/01/21 02:55:46 curt
|
||||
# Incorporated new make system from Bob Kuehne <rpk@sgi.com>.
|
||||
#
|
||||
# Revision 1.1 1998/01/15 02:45:25 curt
|
||||
# Initial revision.
|
||||
#
|
||||
|
600
Tools/AssemTris/assemtris.cxx
Normal file
600
Tools/AssemTris/assemtris.cxx
Normal file
|
@ -0,0 +1,600 @@
|
|||
// assemtris.cxx -- reassemble the pieces produced by splittris
|
||||
//
|
||||
// Written by Curtis Olson, started January 1998.
|
||||
//
|
||||
// Copyright (C) 1997 Curtis L. Olson - curt@me.umn.edu
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> // for atoi()
|
||||
#include <string.h>
|
||||
#include <sys/stat.h> // for stat()
|
||||
#include <unistd.h> // for stat()
|
||||
|
||||
#include "assemtris.hxx"
|
||||
|
||||
#include <Include/fg_constants.h>
|
||||
#include <Bucket/bucketutils.h>
|
||||
|
||||
|
||||
// #define OFFSET_LON 0.1
|
||||
// #define OFFSET_LAT 0.1
|
||||
|
||||
#define OFFSET_LON 0.0
|
||||
#define OFFSET_LAT 0.0
|
||||
|
||||
int nodecount = 0;
|
||||
int excount = 0;
|
||||
|
||||
static double nodes[MAX_NODES][3];
|
||||
static double exnodes[MAX_NODES][3];
|
||||
|
||||
|
||||
fgBUCKET my_index;
|
||||
fgBUCKET ne_index, nw_index, sw_index, se_index;
|
||||
fgBUCKET north_index, south_index, east_index, west_index;
|
||||
|
||||
|
||||
// return the file base name ( foo/bar/file.ext = file.ext )
|
||||
void extract_file(char *in, char *base) {
|
||||
int len, i;
|
||||
|
||||
len = strlen(in);
|
||||
|
||||
i = len - 1;
|
||||
while ( (i >= 0) && (in[i] != '/') ) {
|
||||
i--;
|
||||
}
|
||||
|
||||
in += (i + 1);
|
||||
strcpy(base, in);
|
||||
}
|
||||
|
||||
|
||||
// return the file path name ( foo/bar/file.ext = foo/bar )
|
||||
void extract_path(char *in, char *base) {
|
||||
int len, i;
|
||||
|
||||
len = strlen(in);
|
||||
strcpy(base, in);
|
||||
|
||||
i = len - 1;
|
||||
while ( (i >= 0) && (in[i] != '/') ) {
|
||||
i--;
|
||||
}
|
||||
|
||||
base[i] = '\0';
|
||||
}
|
||||
|
||||
|
||||
// check to see if specified node is in the extra list
|
||||
int is_extra_node(double *n) {
|
||||
int i;
|
||||
|
||||
for ( i = 1; i <= excount; i++ ) {
|
||||
// we only check lon/lat in case the height got fooled with
|
||||
// along the way
|
||||
if ( (fabs(n[0] - exnodes[i][0]) < FG_EPSILON) &&
|
||||
(fabs(n[1] - exnodes[i][1]) < FG_EPSILON) ) {
|
||||
return(i);
|
||||
}
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
// Read all the extra nodes. These typically define inner areas to
|
||||
// exclude from triangulations. There will be a .poly file that
|
||||
// refers to these by position number which assumes all the extra
|
||||
// nodes come first in the generated .node file.
|
||||
void read_extra_nodes(char *exfile) {
|
||||
FILE *fd;
|
||||
int i, junk1, junk2, junk3;
|
||||
|
||||
// load extra nodes if they exist
|
||||
excount = 0;
|
||||
if ( (fd = fopen(exfile, "r")) != NULL ) {
|
||||
printf("Found and 'extra' node file = %s\n", exfile);
|
||||
fscanf(fd, "%d %d %d %d", &excount, &junk1, &junk2, &junk3);
|
||||
|
||||
if ( excount > MAX_NODES - 1 ) {
|
||||
printf("Error, too many 'extra' nodes, increase array size\n");
|
||||
exit(-1);
|
||||
} else {
|
||||
printf(" Expecting %d 'extra' nodes\n", excount);
|
||||
}
|
||||
|
||||
for ( i = 1; i <= excount; i++ ) {
|
||||
fscanf(fd, "%d %lf %lf %lf\n", &junk1,
|
||||
&exnodes[i][0], &exnodes[i][1], &exnodes[i][2]);
|
||||
printf("(extra) %d %.2f %.2f %.2f\n",
|
||||
i, exnodes[i][0], exnodes[i][1], exnodes[i][2]);
|
||||
}
|
||||
fclose(fd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// check if a file exists
|
||||
int file_exists(char *file) {
|
||||
struct stat stat_buf;
|
||||
int result;
|
||||
|
||||
printf("checking %s ... ", file);
|
||||
|
||||
result = stat(file, &stat_buf);
|
||||
|
||||
if ( result != 0 ) {
|
||||
// stat failed, no file
|
||||
printf("not found.\n");
|
||||
return(0);
|
||||
} else {
|
||||
// stat succeeded, file exists
|
||||
printf("exists.\n");
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// check to see if a shared object exists
|
||||
int shared_object_exists(char *basepath, char *ext, char *file) {
|
||||
char scene_path[256];
|
||||
long int index;
|
||||
|
||||
if ( strcmp(ext, ".sw") == 0 ) {
|
||||
fgBucketGenBasePath(&my_index, scene_path);
|
||||
index = fgBucketGenIndex(&my_index);
|
||||
sprintf(file, "%s/%s/%ld.1.sw", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
fgBucketGenBasePath(&west_index, scene_path);
|
||||
index = fgBucketGenIndex(&west_index);
|
||||
sprintf(file, "%s/%s/%ld.1.se", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
fgBucketGenBasePath(&sw_index, scene_path);
|
||||
index = fgBucketGenIndex(&sw_index);
|
||||
sprintf(file, "%s/%s/%ld.1.ne", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
fgBucketGenBasePath(&south_index, scene_path);
|
||||
index = fgBucketGenIndex(&south_index);
|
||||
sprintf(file, "%s/%s/%ld.1.nw", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
if ( strcmp(ext, ".se") == 0 ) {
|
||||
fgBucketGenBasePath(&my_index, scene_path);
|
||||
index = fgBucketGenIndex(&my_index);
|
||||
sprintf(file, "%s/%s/%ld.1.se", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
fgBucketGenBasePath(&east_index, scene_path);
|
||||
index = fgBucketGenIndex(&east_index);
|
||||
sprintf(file, "%s/%s/%ld.1.sw", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
fgBucketGenBasePath(&se_index, scene_path);
|
||||
index = fgBucketGenIndex(&se_index);
|
||||
sprintf(file, "%s/%s/%ld.1.nw", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
fgBucketGenBasePath(&south_index, scene_path);
|
||||
index = fgBucketGenIndex(&south_index);
|
||||
sprintf(file, "%s/%s/%ld.1.ne", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
if ( strcmp(ext, ".ne") == 0 ) {
|
||||
fgBucketGenBasePath(&my_index, scene_path);
|
||||
index = fgBucketGenIndex(&my_index);
|
||||
sprintf(file, "%s/%s/%ld.1.ne", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
fgBucketGenBasePath(&east_index, scene_path);
|
||||
index = fgBucketGenIndex(&east_index);
|
||||
sprintf(file, "%s/%s/%ld.1.nw", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
fgBucketGenBasePath(&ne_index, scene_path);
|
||||
index = fgBucketGenIndex(&ne_index);
|
||||
sprintf(file, "%s/%s/%ld.1.sw", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
fgBucketGenBasePath(&north_index, scene_path);
|
||||
index = fgBucketGenIndex(&north_index);
|
||||
sprintf(file, "%s/%s/%ld.1.se", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
if ( strcmp(ext, ".nw") == 0 ) {
|
||||
fgBucketGenBasePath(&my_index, scene_path);
|
||||
index = fgBucketGenIndex(&my_index);
|
||||
sprintf(file, "%s/%s/%ld.1.nw", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
fgBucketGenBasePath(&west_index, scene_path);
|
||||
index = fgBucketGenIndex(&west_index);
|
||||
sprintf(file, "%s/%s/%ld.1.ne", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
fgBucketGenBasePath(&nw_index, scene_path);
|
||||
index = fgBucketGenIndex(&nw_index);
|
||||
sprintf(file, "%s/%s/%ld.1.se", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
fgBucketGenBasePath(&north_index, scene_path);
|
||||
index = fgBucketGenIndex(&north_index);
|
||||
sprintf(file, "%s/%s/%ld.1.sw", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
if ( strcmp(ext, ".south") == 0 ) {
|
||||
fgBucketGenBasePath(&my_index, scene_path);
|
||||
index = fgBucketGenIndex(&my_index);
|
||||
sprintf(file, "%s/%s/%ld.1.south", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
fgBucketGenBasePath(&south_index, scene_path);
|
||||
index = fgBucketGenIndex(&south_index);
|
||||
sprintf(file, "%s/%s/%ld.1.north", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
if ( strcmp(ext, ".north") == 0 ) {
|
||||
fgBucketGenBasePath(&my_index, scene_path);
|
||||
index = fgBucketGenIndex(&my_index);
|
||||
sprintf(file, "%s/%s/%ld.1.north", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
fgBucketGenBasePath(&north_index, scene_path);
|
||||
index = fgBucketGenIndex(&north_index);
|
||||
sprintf(file, "%s/%s/%ld.1.south", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
if ( strcmp(ext, ".west") == 0 ) {
|
||||
fgBucketGenBasePath(&my_index, scene_path);
|
||||
index = fgBucketGenIndex(&my_index);
|
||||
sprintf(file, "%s/%s/%ld.1.west", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
fgBucketGenBasePath(&west_index, scene_path);
|
||||
index = fgBucketGenIndex(&west_index);
|
||||
sprintf(file, "%s/%s/%ld.1.east", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
if ( strcmp(ext, ".east") == 0 ) {
|
||||
fgBucketGenBasePath(&my_index, scene_path);
|
||||
index = fgBucketGenIndex(&my_index);
|
||||
sprintf(file, "%s/%s/%ld.1.east", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
fgBucketGenBasePath(&east_index, scene_path);
|
||||
index = fgBucketGenIndex(&east_index);
|
||||
sprintf(file, "%s/%s/%ld.1.west", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
if ( strcmp(ext, ".body") == 0 ) {
|
||||
fgBucketGenBasePath(&my_index, scene_path);
|
||||
index = fgBucketGenIndex(&my_index);
|
||||
sprintf(file, "%s/%s/%ld.1.body", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
// my custom file opening routine ... don't open if a shared edge or
|
||||
// vertex alread exists
|
||||
FILE *my_open(char *basename, char *basepath, char *ext) {
|
||||
FILE *fp;
|
||||
char filename[256];
|
||||
|
||||
// check if a shared object already exists
|
||||
if ( shared_object_exists(basepath, ext, filename) ) {
|
||||
// not an actual file open error, but we've already got the
|
||||
// shared edge, so we don't want to create another one
|
||||
fp = fopen(filename, "r");
|
||||
printf("Opening %s\n", filename);
|
||||
return(fp);
|
||||
} else {
|
||||
// open the file
|
||||
printf("not opening\n");
|
||||
return(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// given a file pointer, read all the gdn (geodetic nodes from it.)
|
||||
// The specified offset values (in arcsec) are used to overlap the
|
||||
// edges of the tile slightly to cover gaps induced by floating point
|
||||
// precision problems. 1 arcsec == about 100 feet so 0.01 arcsec ==
|
||||
// about 1 foot
|
||||
void read_nodes(FILE *fp, double offset_lon, double offset_lat) {
|
||||
double n[3];
|
||||
char line[256];
|
||||
int ex_index;
|
||||
|
||||
offset_lon = offset_lat = 0.0;
|
||||
|
||||
while ( fgets(line, 250, fp) != NULL ) {
|
||||
if ( strncmp(line, "gdn ", 4) == 0 ) {
|
||||
sscanf(line, "gdn %lf %lf %lf\n", &n[0], &n[1], &n[2]);
|
||||
|
||||
ex_index = is_extra_node(n);
|
||||
|
||||
if ( ex_index == 0 ) {
|
||||
// not an extra node
|
||||
nodes[nodecount][0] = n[0] + offset_lon;
|
||||
nodes[nodecount][1] = n[1] + offset_lat;
|
||||
nodes[nodecount][2] = n[2];
|
||||
|
||||
// printf("read_nodes(%d) %.2f %.2f %.2f %s", nodecount,
|
||||
// nodes[nodecount][0], nodes[nodecount][1],
|
||||
// nodes[nodecount][2], line);
|
||||
|
||||
|
||||
nodecount++;
|
||||
} else {
|
||||
// is an extra node
|
||||
printf("found extra node %.2f %.2f %.2f\n", n[0], n[1], n[2]);
|
||||
// preserve the DEM altitude for now
|
||||
exnodes[ex_index][2] = n[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// load in nodes from the various split and shared pieces to
|
||||
// reconstruct a tile
|
||||
void build_node_list(char *basename, char *basepath) {
|
||||
char exfile[256];
|
||||
FILE *ne, *nw, *se, *sw, *north, *south, *east, *west, *body;
|
||||
|
||||
// load extra nodes if they exist
|
||||
strcpy(exfile, basename);
|
||||
strcat(exfile, ".node.ex");
|
||||
read_extra_nodes(exfile);
|
||||
|
||||
ne = my_open(basename, basepath, ".ne");
|
||||
read_nodes(ne, OFFSET_LON, OFFSET_LAT);
|
||||
fclose(ne);
|
||||
|
||||
nw = my_open(basename, basepath, ".nw");
|
||||
read_nodes(nw, -1.0 * OFFSET_LON, OFFSET_LAT);
|
||||
fclose(nw);
|
||||
|
||||
se = my_open(basename, basepath, ".se");
|
||||
read_nodes(se, OFFSET_LON, -1.0 * OFFSET_LAT);
|
||||
fclose(se);
|
||||
|
||||
sw = my_open(basename, basepath, ".sw");
|
||||
read_nodes(sw, -1.0 * OFFSET_LON, -1.0 * OFFSET_LAT);
|
||||
fclose(sw);
|
||||
|
||||
north = my_open(basename, basepath, ".north");
|
||||
read_nodes(north, 0.0, OFFSET_LAT);
|
||||
fclose(north);
|
||||
|
||||
south = my_open(basename, basepath, ".south");
|
||||
read_nodes(south, 0.0, -1.0 * OFFSET_LAT);
|
||||
fclose(south);
|
||||
|
||||
east = my_open(basename, basepath, ".east");
|
||||
read_nodes(east, OFFSET_LON, 0.0);
|
||||
fclose(east);
|
||||
|
||||
west = my_open(basename, basepath, ".west");
|
||||
read_nodes(west, -1.0 * OFFSET_LON, 0.0);
|
||||
fclose(west);
|
||||
|
||||
body = my_open(basename, basepath, ".body");
|
||||
read_nodes(body, 0.0, 0.0);
|
||||
fclose(body);
|
||||
}
|
||||
|
||||
|
||||
// dump in WaveFront .obj format
|
||||
void dump_nodes(char *basename) {
|
||||
char file[256];
|
||||
FILE *fd;
|
||||
int i;
|
||||
|
||||
// generate output file name
|
||||
strcpy(file, basename);
|
||||
// len = strlen(file);
|
||||
// file[len-2] = '\0';
|
||||
strcat(file, ".node");
|
||||
|
||||
// dump vertices
|
||||
printf("Creating node file: %s\n", file);
|
||||
printf(" writing vertices in .node format.\n");
|
||||
fd = fopen(file, "w");
|
||||
|
||||
fprintf(fd, "%d 2 1 0\n", excount + nodecount);
|
||||
|
||||
// now write out extra node data
|
||||
for ( i = 1; i <= excount; i++ ) {
|
||||
fprintf(fd, "%d %.2f %.2f %.2f 0\n",
|
||||
i, exnodes[i][0], exnodes[i][1], exnodes[i][2]);
|
||||
}
|
||||
|
||||
// now write out actual node data
|
||||
for ( i = 0; i < nodecount; i++ ) {
|
||||
fprintf(fd, "%d %.2f %.2f %.2f 0\n", excount + i + 1,
|
||||
nodes[i][0], nodes[i][1], nodes[i][2]);
|
||||
}
|
||||
|
||||
fclose(fd);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
char basename[256], basepath[256], temp[256];
|
||||
long int tmp_index;
|
||||
int len;
|
||||
|
||||
// derive base name
|
||||
strcpy(basename, argv[1]);
|
||||
len = strlen(basename);
|
||||
|
||||
// find the base path of the file
|
||||
extract_path(basename, basepath);
|
||||
extract_path(basepath, basepath);
|
||||
extract_path(basepath, basepath);
|
||||
printf("%s\n", basepath);
|
||||
|
||||
// find the index of the current file
|
||||
extract_file(basename, temp);
|
||||
// len = strlen(temp);
|
||||
// if ( len >= 2 ) {
|
||||
// temp[len-2] = '\0';
|
||||
// }
|
||||
tmp_index = atoi(temp);
|
||||
printf("%ld\n", tmp_index);
|
||||
fgBucketParseIndex(tmp_index, &my_index);
|
||||
|
||||
printf("bucket = %d %d %d %d\n",
|
||||
my_index.lon, my_index.lat, my_index.x, my_index.y);
|
||||
// generate the indexes of the neighbors
|
||||
fgBucketOffset(&my_index, &ne_index, 1, 1);
|
||||
fgBucketOffset(&my_index, &nw_index, -1, 1);
|
||||
fgBucketOffset(&my_index, &se_index, 1, -1);
|
||||
fgBucketOffset(&my_index, &sw_index, -1, -1);
|
||||
|
||||
fgBucketOffset(&my_index, &north_index, 0, 1);
|
||||
fgBucketOffset(&my_index, &south_index, 0, -1);
|
||||
fgBucketOffset(&my_index, &east_index, 1, 0);
|
||||
fgBucketOffset(&my_index, &west_index, -1, 0);
|
||||
|
||||
// printf("Corner indexes = %ld %ld %ld %ld\n",
|
||||
// ne_index, nw_index, sw_index, se_index);
|
||||
// printf("Edge indexes = %ld %ld %ld %ld\n",
|
||||
// north_index, south_index, east_index, west_index);
|
||||
|
||||
|
||||
// load the input data files
|
||||
build_node_list(basename, basepath);
|
||||
|
||||
// dump in WaveFront .obj format
|
||||
dump_nodes(basename);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.3 1998/11/02 18:25:40 curt
|
||||
// Check for __CYGWIN__ (b20) as well as __CYGWIN32__ (pre b20 compilers)
|
||||
// Other misc. tweaks.
|
||||
//
|
||||
// Revision 1.2 1998/09/25 19:38:01 curt
|
||||
// Minor tweaks so that this actually compiles.
|
||||
//
|
||||
// Revision 1.1 1998/09/25 19:35:29 curt
|
||||
// Renamed assemtris.[ch] to assemtris.[ch]xx
|
||||
//
|
||||
// Revision 1.13 1998/09/21 20:56:30 curt
|
||||
// Changes to avoid setting airport area nodes back to their original
|
||||
// elevations if they have been changed.
|
||||
//
|
||||
//
|
||||
// Revision 1.12 1998/09/09 16:24:51 curt
|
||||
// Fixed a bug in the handling of exclude files which was causing
|
||||
// a crash by calling fclose() on an invalid file handle.
|
||||
// Removed overlapping offsets.
|
||||
//
|
||||
// Revision 1.11 1998/08/06 12:47:59 curt
|
||||
// Removed overlap in tiles as a test.
|
||||
//
|
||||
// Revision 1.10 1998/07/21 04:34:20 curt
|
||||
// Mods to handle extra nodes (i.e. preserve cutouts).
|
||||
//
|
||||
// Revision 1.9 1998/07/04 00:55:39 curt
|
||||
// typedef'd struct fgBUCKET.
|
||||
//
|
||||
// Revision 1.8 1998/06/01 17:58:19 curt
|
||||
// Added a slight border overlap to try to minimize pixel wide gaps between
|
||||
// tiles due to round off error. This is not a perfect solution, but helps.
|
||||
//
|
||||
// Revision 1.7 1998/04/14 02:26:00 curt
|
||||
// Code reorganizations. Added a Lib/ directory for more general libraries.
|
||||
//
|
||||
// Revision 1.6 1998/04/08 22:54:58 curt
|
||||
// Adopted Gnu automake/autoconf system.
|
||||
//
|
||||
// Revision 1.5 1998/03/03 16:00:52 curt
|
||||
// More c++ compile tweaks.
|
||||
//
|
||||
// Revision 1.4 1998/01/31 00:41:23 curt
|
||||
// Made a few changes converting floats to doubles.
|
||||
//
|
||||
// Revision 1.3 1998/01/27 18:37:00 curt
|
||||
// Lots of updates to get back in sync with changes made over in .../Src/
|
||||
//
|
||||
// Revision 1.2 1998/01/15 21:33:36 curt
|
||||
// Assembling triangles and building a new .node file with the proper shared
|
||||
// vertices now works. Now we just have to use the shared normals and we'll
|
||||
// be all set.
|
||||
//
|
||||
// Revision 1.1 1998/01/15 02:45:26 curt
|
||||
// Initial revision.
|
||||
//
|
||||
|
51
Tools/AssemTris/assemtris.hxx
Normal file
51
Tools/AssemTris/assemtris.hxx
Normal file
|
@ -0,0 +1,51 @@
|
|||
// splittris.hxx -- reassemble the pieces produced by splittris
|
||||
//
|
||||
// Written by Curtis Olson, started January 1998.
|
||||
//
|
||||
// Copyright (C) 1997 Curtis L. Olson - curt@me.umn.edu
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
|
||||
|
||||
|
||||
#ifndef ASSEMTRIS_H
|
||||
#define ASSEMTRIS_H
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#define MAX_NODES 200000
|
||||
#define MAX_TRIS 400000
|
||||
|
||||
|
||||
#endif // SPLITTRIS_H
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.2 1998/09/25 19:38:03 curt
|
||||
// Minor tweaks so that this actually compiles.
|
||||
//
|
||||
// Revision 1.1 1998/09/25 19:35:31 curt
|
||||
// Renamed assemtris.[ch] to assemtris.[ch]xx
|
||||
//
|
||||
// Revision 1.1 1998/01/15 02:45:26 curt
|
||||
// Initial revision.
|
||||
//
|
||||
|
13
Tools/CVSROOT/checkoutlist
Normal file
13
Tools/CVSROOT/checkoutlist
Normal file
|
@ -0,0 +1,13 @@
|
|||
# The "checkoutlist" file is used to support additional version controlled
|
||||
# administrative files in $CVSROOT/CVSROOT, such as template files.
|
||||
#
|
||||
# The first entry on a line is a filename which will be checked out from
|
||||
# the corresponding RCS file in the $CVSROOT/CVSROOT directory.
|
||||
# The remainder of the line is an error message to use if the file cannot
|
||||
# be checked out.
|
||||
#
|
||||
# File format:
|
||||
#
|
||||
# [<whitespace>]<filename><whitespace><error message><end-of-line>
|
||||
#
|
||||
# comment lines begin with '#'
|
15
Tools/CVSROOT/commitinfo
Normal file
15
Tools/CVSROOT/commitinfo
Normal file
|
@ -0,0 +1,15 @@
|
|||
# The "commitinfo" file is used to control pre-commit checks.
|
||||
# The filter on the right is invoked with the repository and a list
|
||||
# of files to check. A non-zero exit of the filter program will
|
||||
# cause the commit to be aborted.
|
||||
#
|
||||
# The first entry on a line is a regular expression which is tested
|
||||
# against the directory that the change is being committed to, relative
|
||||
# to the $CVSROOT. For the first match that is found, then the remainder
|
||||
# of the line is the name of the filter to run.
|
||||
#
|
||||
# If the repository name does not match any of the regular expressions in this
|
||||
# file, the "DEFAULT" line is used, if it is specified.
|
||||
#
|
||||
# If the name "ALL" appears as a regular expression it is always used
|
||||
# in addition to the first matching regex or "DEFAULT".
|
22
Tools/CVSROOT/cvswrappers
Normal file
22
Tools/CVSROOT/cvswrappers
Normal file
|
@ -0,0 +1,22 @@
|
|||
# This file describes wrappers and other binary files to CVS.
|
||||
#
|
||||
# Wrappers are the concept where directories of files are to be
|
||||
# treated as a single file. The intended use is to wrap up a wrapper
|
||||
# into a single tar such that the tar archive can be treated as a
|
||||
# single binary file in CVS.
|
||||
#
|
||||
# To solve the problem effectively, it was also necessary to be able to
|
||||
# prevent rcsmerge from merging these files.
|
||||
#
|
||||
# Format of wrapper file ($CVSROOT/CVSROOT/cvswrappers or .cvswrappers)
|
||||
#
|
||||
# wildcard [option value][option value]...
|
||||
#
|
||||
# where option is one of
|
||||
# -f from cvs filter value: path to filter
|
||||
# -t to cvs filter value: path to filter
|
||||
# -m update methodology value: MERGE or COPY
|
||||
#
|
||||
# and value is a single-quote delimited value.
|
||||
#
|
||||
# For example:
|
21
Tools/CVSROOT/editinfo
Normal file
21
Tools/CVSROOT/editinfo
Normal file
|
@ -0,0 +1,21 @@
|
|||
# The "editinfo" file is used to allow verification of logging
|
||||
# information. It works best when a template (as specified in the
|
||||
# rcsinfo file) is provided for the logging procedure. Given a
|
||||
# template with locations for, a bug-id number, a list of people who
|
||||
# reviewed the code before it can be checked in, and an external
|
||||
# process to catalog the differences that were code reviewed, the
|
||||
# following test can be applied to the code:
|
||||
#
|
||||
# Making sure that the entered bug-id number is correct.
|
||||
# Validating that the code that was reviewed is indeed the code being
|
||||
# checked in (using the bug-id number or a seperate review
|
||||
# number to identify this particular code set.).
|
||||
#
|
||||
# If any of the above test failed, then the commit would be aborted.
|
||||
#
|
||||
# Actions such as mailing a copy of the report to each reviewer are
|
||||
# better handled by an entry in the loginfo file.
|
||||
#
|
||||
# One thing that should be noted is the the ALL keyword is not
|
||||
# supported. There can be only one entry that matches a given
|
||||
# repository.
|
19
Tools/CVSROOT/loginfo
Normal file
19
Tools/CVSROOT/loginfo
Normal file
|
@ -0,0 +1,19 @@
|
|||
# The "loginfo" file is used to control where "cvs commit" log information is
|
||||
# sent. The first entry on a line is a regular expression which is tested
|
||||
# against the directory that the change is being made to, relative to the
|
||||
# $CVSROOT. For the first match that is found, the remainder of the line is a
|
||||
# filter program that should expect log information on its standard input
|
||||
#
|
||||
# If the repository name does not match any of the regular expressions in the
|
||||
# first field of this file, the "DEFAULT" line is used, if it is specified.
|
||||
#
|
||||
# If the name "ALL" appears as a regular expression it is always used
|
||||
# in addition to the first matching regex or "DEFAULT".
|
||||
#
|
||||
# The filter program may use one and only one "%s" modifier (ala printf). If
|
||||
# such a "%s" is specified in the filter program, a brief title is included
|
||||
# (as one argument, enclosed in single quotes) showing the relative directory
|
||||
# name and listing the modified file names.
|
||||
#
|
||||
# For example:
|
||||
#DEFAULT (echo ""; who am i; echo %s; date; cat) >> $CVSROOT/CVSROOT/commitlog
|
26
Tools/CVSROOT/modules
Normal file
26
Tools/CVSROOT/modules
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Three different line formats are valid:
|
||||
# key -a aliases...
|
||||
# key [options] directory
|
||||
# key [options] directory files...
|
||||
#
|
||||
# Where "options" are composed of:
|
||||
# -i prog Run "prog" on "cvs commit" from top-level of module.
|
||||
# -o prog Run "prog" on "cvs checkout" of module.
|
||||
# -e prog Run "prog" on "cvs export" of module.
|
||||
# -t prog Run "prog" on "cvs rtag" of module.
|
||||
# -u prog Run "prog" on "cvs update" of module.
|
||||
# -d dir Place module in directory "dir" instead of module name.
|
||||
# -l Top-level directory only -- do not recurse.
|
||||
#
|
||||
# NOTE: If you change any of the "Run" options above, you'll have to
|
||||
# release and re-checkout any working directories of these modules.
|
||||
#
|
||||
# And "directory" is a path to a directory relative to $CVSROOT.
|
||||
#
|
||||
# The "-a" option specifies an alias. An alias is interpreted as if
|
||||
# everything on the right of the "-a" had been typed on the command line.
|
||||
#
|
||||
# You can encode a module within a module by using the special '&'
|
||||
# character to interpose another module into the current module. This
|
||||
# can be useful for creating a module that consists of many directories
|
||||
# spread out over the entire source repository.
|
12
Tools/CVSROOT/notify
Normal file
12
Tools/CVSROOT/notify
Normal file
|
@ -0,0 +1,12 @@
|
|||
# The "notify" file controls where notifications from watches set by
|
||||
# "cvs watch add" or "cvs edit" are sent. The first entry on a line is
|
||||
# a regular expression which is tested against the directory that the
|
||||
# change is being made to, relative to the $CVSROOT. If it matches,
|
||||
# then the remainder of the line is a filter program that should contain
|
||||
# one occurrence of %s for the user to notify, and information on its
|
||||
# standard input.
|
||||
#
|
||||
# "ALL" or "DEFAULT" can be used in place of the regular expression.
|
||||
#
|
||||
# For example:
|
||||
#ALL mail %s -s "CVS notification"
|
13
Tools/CVSROOT/rcsinfo
Normal file
13
Tools/CVSROOT/rcsinfo
Normal file
|
@ -0,0 +1,13 @@
|
|||
# The "rcsinfo" file is used to control templates with which the editor
|
||||
# is invoked on commit and import.
|
||||
#
|
||||
# The first entry on a line is a regular expression which is tested
|
||||
# against the directory that the change is being made to, relative to the
|
||||
# $CVSROOT. For the first match that is found, then the remainder of the
|
||||
# line is the name of the file that contains the template.
|
||||
#
|
||||
# If the repository name does not match any of the regular expressions in this
|
||||
# file, the "DEFAULT" line is used, if it is specified.
|
||||
#
|
||||
# If the name "ALL" appears as a regular expression it is always used
|
||||
# in addition to the first matching regex or "DEFAULT".
|
20
Tools/CVSROOT/taginfo
Normal file
20
Tools/CVSROOT/taginfo
Normal file
|
@ -0,0 +1,20 @@
|
|||
# The "taginfo" file is used to control pre-tag checks.
|
||||
# The filter on the right is invoked with the following arguments:
|
||||
#
|
||||
# $1 -- tagname
|
||||
# $2 -- operation "add" for tag, "mov" for tag -F, and "del" for tag -d
|
||||
# $3 -- repository
|
||||
# $4-> file revision [file revision ...]
|
||||
#
|
||||
# A non-zero exit of the filter program will cause the tag to be aborted.
|
||||
#
|
||||
# The first entry on a line is a regular expression which is tested
|
||||
# against the directory that the change is being committed to, relative
|
||||
# to the $CVSROOT. For the first match that is found, then the remainder
|
||||
# of the line is the name of the filter to run.
|
||||
#
|
||||
# If the repository name does not match any of the regular expressions in this
|
||||
# file, the "DEFAULT" line is used, if it is specified.
|
||||
#
|
||||
# If the name "ALL" appears as a regular expression it is always used
|
||||
# in addition to the first matching regex or "DEFAULT".
|
16
Tools/Clipper/Makefile.am
Normal file
16
Tools/Clipper/Makefile.am
Normal file
|
@ -0,0 +1,16 @@
|
|||
noinst_LIBRARIES = libClipper.a
|
||||
|
||||
libClipper_a_SOURCES = clipper.cxx clipper.hxx
|
||||
|
||||
bin_PROGRAMS = testclipper
|
||||
|
||||
testclipper_SOURCES = testclipper.cxx
|
||||
|
||||
testclipper_LDADD = $(top_builddir)/Tools/Construct/Clipper/libClipper.a \
|
||||
$(top_builddir)/Tools/Lib/Polygon/libPolygon.a \
|
||||
$(top_builddir)/Lib/Debug/libDebug.a \
|
||||
$(top_builddir)/Lib/Misc/libMisc.a \
|
||||
$(top_builddir)/Lib/zlib/libz.a \
|
||||
-lgfc -lgpc
|
||||
|
||||
INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib -I$(top_builddir)/Tools/Lib
|
304
Tools/Clipper/clipper.cxx
Normal file
304
Tools/Clipper/clipper.cxx
Normal file
|
@ -0,0 +1,304 @@
|
|||
// 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 - curt@flightgear.org
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
|
||||
|
||||
|
||||
#include <Debug/logstream.hxx>
|
||||
#include <Include/fg_constants.h>
|
||||
#include <Misc/fgstream.hxx>
|
||||
#include <Polygon/names.hxx>
|
||||
|
||||
#include "clipper.hxx"
|
||||
|
||||
|
||||
// Constructor
|
||||
FGClipper::FGClipper( void ) {
|
||||
}
|
||||
|
||||
|
||||
// Destructor
|
||||
FGClipper::~FGClipper( void ) {
|
||||
}
|
||||
|
||||
|
||||
// Initialize Clipper (allocate and/or connect structures)
|
||||
bool FGClipper::init() {
|
||||
v_list.num_vertices = 0;
|
||||
v_list.vertex = new gpc_vertex[FG_MAX_VERTICES];;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Load a polygon definition file
|
||||
bool FGClipper::load_polys(const string& path) {
|
||||
string poly_name;
|
||||
AreaType poly_type = DefaultArea;
|
||||
int contours, count, i, j;
|
||||
double startx, starty, x, y, lastx, lasty;
|
||||
|
||||
FG_LOG( FG_CLIPPER, FG_INFO, "Loading " << path << " ..." );
|
||||
|
||||
fg_gzifstream in( path );
|
||||
|
||||
if ( !in ) {
|
||||
FG_LOG( FG_CLIPPER, FG_ALERT, "Cannot open file: " << path );
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
gpc_polygon *poly = new gpc_polygon;
|
||||
poly->num_contours = 0;
|
||||
poly->contour = NULL;
|
||||
|
||||
in >> skipcomment;
|
||||
while ( !in.eof() ) {
|
||||
in >> poly_name;
|
||||
cout << "poly name = " << poly_name << endl;
|
||||
poly_type = get_area_type( poly_name );
|
||||
cout << "poly type (int) = " << (int)poly_type << endl;
|
||||
in >> contours;
|
||||
cout << "num contours = " << contours << endl;
|
||||
|
||||
for ( i = 0; i < contours; ++i ) {
|
||||
in >> count;
|
||||
|
||||
if ( count < 3 ) {
|
||||
FG_LOG( FG_CLIPPER, FG_ALERT,
|
||||
"Polygon with less than 3 data points." );
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
in >> startx;
|
||||
in >> starty;
|
||||
v_list.vertex[0].x = startx;
|
||||
v_list.vertex[0].y = starty;
|
||||
FG_LOG( FG_CLIPPER, FG_BULK, "0 = "
|
||||
<< startx << ", " << starty );
|
||||
|
||||
for ( j = 1; j < count - 1; ++j ) {
|
||||
in >> x;
|
||||
in >> y;
|
||||
v_list.vertex[j].x = x;
|
||||
v_list.vertex[j].y = y;
|
||||
FG_LOG( FG_CLIPPER, FG_BULK, j << " = " << x << ", " << y );
|
||||
}
|
||||
v_list.num_vertices = count - 1;
|
||||
|
||||
in >> lastx;
|
||||
in >> lasty;
|
||||
|
||||
if ( (fabs(startx - lastx) < FG_EPSILON)
|
||||
&& (fabs(starty - lasty) < FG_EPSILON) ) {
|
||||
// last point same as first, discard
|
||||
} else {
|
||||
v_list.vertex[count - 1].x = lastx;
|
||||
v_list.vertex[count - 1].y = lasty;
|
||||
++v_list.num_vertices;
|
||||
FG_LOG( FG_CLIPPER, FG_BULK, count - 1 << " = "
|
||||
<< lastx << ", " << lasty );
|
||||
}
|
||||
|
||||
gpc_add_contour( poly, &v_list );
|
||||
|
||||
}
|
||||
|
||||
in >> skipcomment;
|
||||
}
|
||||
|
||||
int area = (int)poly_type;
|
||||
if ( area < FG_MAX_AREA_TYPES ) {
|
||||
polys_in.polys[area].push_back(poly);
|
||||
} else {
|
||||
FG_LOG( FG_CLIPPER, FG_ALERT, "Polygon type out of range = "
|
||||
<< (int)poly_type);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// FILE *ofp= fopen("outfile", "w");
|
||||
// gpc_write_polygon(ofp, &polys.landuse);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Do actually clipping work
|
||||
bool FGClipper::clip_all(const point2d& min, const point2d& max) {
|
||||
gpc_polygon accum, result_union, tmp;
|
||||
gpc_polygon *result_diff, *remains;
|
||||
gpcpoly_iterator current, last;
|
||||
|
||||
FG_LOG( FG_CLIPPER, FG_INFO, "Running master clipper" );
|
||||
|
||||
accum.num_contours = 0;
|
||||
|
||||
cout << " (" << min.x << "," << min.y << ") ("
|
||||
<< max.x << "," << max.y << ")" << endl;
|
||||
|
||||
// set up clipping tile
|
||||
v_list.vertex[0].x = min.x;
|
||||
v_list.vertex[0].y = min.y;
|
||||
|
||||
v_list.vertex[1].x = max.x;
|
||||
v_list.vertex[1].y = min.y;
|
||||
|
||||
v_list.vertex[2].x = max.x;
|
||||
v_list.vertex[2].y = max.y;
|
||||
|
||||
v_list.vertex[3].x = min.x;
|
||||
v_list.vertex[3].y = max.y;
|
||||
|
||||
v_list.num_vertices = 4;
|
||||
|
||||
polys_in.safety_base.num_contours = 0;
|
||||
polys_in.safety_base.contour = NULL;
|
||||
gpc_add_contour( &polys_in.safety_base, &v_list );
|
||||
|
||||
// process polygons in priority order
|
||||
for ( int i = 0; i < FG_MAX_AREA_TYPES; ++i ) {
|
||||
// cout << "num polys of this type = "
|
||||
// << polys_in.polys[i].size() << endl;
|
||||
current = polys_in.polys[i].begin();
|
||||
last = polys_in.polys[i].end();
|
||||
for ( ; current != last; ++current ) {
|
||||
FG_LOG( FG_CLIPPER, FG_DEBUG, get_area_name( (AreaType)i )
|
||||
<< " = " << (*current)->contour->num_vertices );
|
||||
|
||||
#ifdef EXTRA_SAFETY_CLIP
|
||||
// clip to base tile
|
||||
gpc_polygon_clip(GPC_INT, *current, &polys_in.safety_base, &tmp);
|
||||
#else
|
||||
tmp = *current;
|
||||
#endif
|
||||
|
||||
// clip current polygon against previous higher priority
|
||||
// stuff
|
||||
result_diff = new gpc_polygon;
|
||||
result_diff->num_contours = 0;
|
||||
result_diff->contour = NULL;
|
||||
|
||||
if ( accum.num_contours == 0 ) {
|
||||
*result_diff = tmp;
|
||||
result_union = tmp;
|
||||
} else {
|
||||
// cout << "DIFF: tmp.num_contours = " << tmp.num_contours
|
||||
// << " accum.num_contours = " << accum.num_contours
|
||||
// << endl;
|
||||
// tmp output accum
|
||||
FILE *ofp= fopen("tmp-debug", "w");
|
||||
gpc_write_polygon(ofp, &tmp);
|
||||
fclose(ofp);
|
||||
|
||||
ofp= fopen("accum-debug", "w");
|
||||
gpc_write_polygon(ofp, &accum);
|
||||
fclose(ofp);
|
||||
|
||||
gpc_polygon_clip(GPC_DIFF, &tmp, &accum, result_diff);
|
||||
gpc_polygon_clip(GPC_UNION, &tmp, &accum, &result_union);
|
||||
}
|
||||
|
||||
/*
|
||||
cout << "original contours = " << tmp.num_contours << endl;
|
||||
|
||||
for ( int j = 0; j < tmp.num_contours; j++ ) {
|
||||
for (int k = 0;k < tmp.contour[j].num_vertices;k++ ) {
|
||||
cout << tmp.contour[j].vertex[k].x << ","
|
||||
<< tmp.contour[j].vertex[k].y << endl;
|
||||
}
|
||||
}
|
||||
|
||||
cout << "clipped contours = " << result_diff->num_contours << endl;
|
||||
|
||||
for ( int j = 0; j < result_diff->num_contours; j++ ) {
|
||||
for (int k = 0;k < result_diff->contour[j].num_vertices;k++ ) {
|
||||
cout << result_diff->contour[j].vertex[k].x << ","
|
||||
<< result_diff->contour[j].vertex[k].y << endl;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// only add to output list if the clip left us with a polygon
|
||||
if ( result_diff->num_contours > 0 ) {
|
||||
polys_clipped.polys[i].push_back(result_diff);
|
||||
}
|
||||
accum = result_union;
|
||||
}
|
||||
}
|
||||
|
||||
// finally, what ever is left over goes to base terrain
|
||||
|
||||
// clip to accum against original base tile
|
||||
remains = new gpc_polygon;
|
||||
remains->num_contours = 0;
|
||||
remains->contour = NULL;
|
||||
gpc_polygon_clip(GPC_DIFF, &polys_in.safety_base, &accum,
|
||||
remains);
|
||||
if ( remains->num_contours > 0 ) {
|
||||
polys_clipped.polys[0].push_back(remains);
|
||||
}
|
||||
|
||||
// tmp output accum
|
||||
FILE *ofp= fopen("accum", "w");
|
||||
gpc_write_polygon(ofp, &accum);
|
||||
fclose(ofp);
|
||||
|
||||
// tmp output safety_base
|
||||
ofp= fopen("remains", "w");
|
||||
gpc_write_polygon(ofp, remains);
|
||||
fclose(ofp);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.9 1999/03/31 23:46:38 curt
|
||||
// Debuggin output tweaks.
|
||||
//
|
||||
// Revision 1.8 1999/03/30 23:49:22 curt
|
||||
// Added some debugging output.
|
||||
//
|
||||
// Revision 1.7 1999/03/30 13:41:38 curt
|
||||
// Working towards better handling of multi-contoured polygons.
|
||||
//
|
||||
// Revision 1.6 1999/03/27 05:20:53 curt
|
||||
// Pass along default area explicitely to triangulator.
|
||||
//
|
||||
// Revision 1.5 1999/03/19 22:28:46 curt
|
||||
// Only add non-null polygons to output list.
|
||||
//
|
||||
// Revision 1.4 1999/03/19 00:26:18 curt
|
||||
// Fixed a clipping bug (polygons specified in wrong order).
|
||||
// Touched up a few compiler warnings.
|
||||
//
|
||||
// Revision 1.3 1999/03/17 23:48:58 curt
|
||||
// minor renaming and a bit of rearranging.
|
||||
//
|
||||
// Revision 1.2 1999/03/13 23:51:33 curt
|
||||
// Renamed main.cxx to testclipper.cxx
|
||||
// Converted clipper routines to a class FGClipper.
|
||||
//
|
||||
// Revision 1.1 1999/03/01 15:39:39 curt
|
||||
// Initial revision.
|
||||
//
|
129
Tools/Clipper/clipper.hxx
Normal file
129
Tools/Clipper/clipper.hxx
Normal file
|
@ -0,0 +1,129 @@
|
|||
// 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 - curt@flightgear.org
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
|
||||
|
||||
|
||||
#ifndef _CLIPPER_HXX
|
||||
#define _CLIPPER_HXX
|
||||
|
||||
|
||||
#ifndef __cplusplus
|
||||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
|
||||
#include <Include/compiler.h>
|
||||
|
||||
|
||||
// include Generic Polygon Clipping Library
|
||||
//
|
||||
// http://www.cs.man.ac.uk/aig/staff/alan/software/
|
||||
//
|
||||
extern "C" {
|
||||
#include <gpc.h>
|
||||
}
|
||||
|
||||
#include STL_STRING
|
||||
#include <vector>
|
||||
|
||||
FG_USING_STD(string);
|
||||
FG_USING_STD(vector);
|
||||
|
||||
|
||||
typedef vector < gpc_polygon * > gpcpoly_container;
|
||||
typedef gpcpoly_container::iterator gpcpoly_iterator;
|
||||
typedef gpcpoly_container::const_iterator const_gpcpoly_iterator;
|
||||
|
||||
|
||||
#define FG_MAX_AREA_TYPES 20
|
||||
#define EXTRA_SAFETY_CLIP
|
||||
#define FG_MAX_VERTICES 100000
|
||||
|
||||
|
||||
class point2d {
|
||||
public:
|
||||
double x, y;
|
||||
};
|
||||
|
||||
|
||||
class FGgpcPolyList {
|
||||
public:
|
||||
gpcpoly_container polys[FG_MAX_AREA_TYPES];
|
||||
gpc_polygon safety_base;
|
||||
};
|
||||
|
||||
|
||||
class FGClipper {
|
||||
|
||||
private:
|
||||
|
||||
gpc_vertex_list v_list;
|
||||
// static gpc_polygon poly;
|
||||
FGgpcPolyList polys_in, polys_clipped;
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
FGClipper( void );
|
||||
|
||||
// Destructor
|
||||
~FGClipper( void );
|
||||
|
||||
// Initialize Clipper (allocate and/or connect structures)
|
||||
bool init();
|
||||
|
||||
// Load a polygon definition file
|
||||
bool load_polys(const string& path);
|
||||
|
||||
// Do actually clipping work
|
||||
bool clip_all(const point2d& min, const point2d& max);
|
||||
|
||||
// return output poly list
|
||||
inline FGgpcPolyList get_polys_clipped() const { return polys_clipped; }
|
||||
};
|
||||
|
||||
|
||||
#endif // _CLIPPER_HXX
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.5 1999/03/19 00:26:19 curt
|
||||
// Fixed a clipping bug (polygons specified in wrong order).
|
||||
// Touched up a few compiler warnings.
|
||||
//
|
||||
// Revision 1.4 1999/03/18 04:31:10 curt
|
||||
// Let's not pass copies of huge structures on the stack ... ye might see a
|
||||
// segfault ... :-)
|
||||
//
|
||||
// Revision 1.3 1999/03/17 23:48:59 curt
|
||||
// minor renaming and a bit of rearranging.
|
||||
//
|
||||
// Revision 1.2 1999/03/13 23:51:34 curt
|
||||
// Renamed main.cxx to testclipper.cxx
|
||||
// Converted clipper routines to a class FGClipper.
|
||||
//
|
||||
// Revision 1.1 1999/03/01 15:39:39 curt
|
||||
// Initial revision.
|
||||
//
|
119
Tools/Clipper/testclipper.cxx
Normal file
119
Tools/Clipper/testclipper.cxx
Normal file
|
@ -0,0 +1,119 @@
|
|||
// main.cxx -- sample use of the clipper lib
|
||||
//
|
||||
// Written by Curtis Olson, started February 1999.
|
||||
//
|
||||
// Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
|
||||
|
||||
|
||||
#include <Debug/logstream.hxx>
|
||||
#include <Bucket/newbucket.hxx>
|
||||
|
||||
#include "clipper.hxx"
|
||||
|
||||
|
||||
int main( int argc, char **argv ) {
|
||||
point2d global_min, global_max;
|
||||
|
||||
fglog().setLogLevels( FG_ALL, FG_DEBUG );
|
||||
|
||||
global_min.x = global_min.y = 200;
|
||||
global_max.y = global_max.x = -200;
|
||||
|
||||
FGClipper clipper;
|
||||
clipper.init();
|
||||
|
||||
if ( argc < 2 ) {
|
||||
FG_LOG( FG_CLIPPER, FG_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);
|
||||
FGBucket 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 = bucket_span(c.y);
|
||||
|
||||
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 - FG_HALF_BUCKET_SPAN;
|
||||
max.y = c.y + FG_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 {
|
||||
FG_LOG ( FG_GENERAL, FG_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);
|
||||
|
||||
FG_LOG( FG_CLIPPER, FG_INFO, "finished main" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// $Log$
|
||||
// Revision 1.1 1999/03/13 23:51:36 curt
|
||||
// Renamed main.cxx to testclipper.cxx
|
||||
// Converted clipper routines to a class FGClipper.
|
||||
//
|
||||
// Revision 1.1 1999/03/01 15:39:39 curt
|
||||
// Initial revision.
|
||||
//
|
9
Tools/Combine/Makefile.am
Normal file
9
Tools/Combine/Makefile.am
Normal file
|
@ -0,0 +1,9 @@
|
|||
noinst_LIBRARIES = libCombine.a
|
||||
|
||||
libCombine_a_SOURCES = genfans.cxx genfans.hxx
|
||||
|
||||
INCLUDES += \
|
||||
-I$(top_builddir) \
|
||||
-I$(top_builddir)/Lib \
|
||||
-I$(top_builddir)/Tools/Lib \
|
||||
-I$(top_builddir)/Tools/Construct
|
266
Tools/Combine/genfans.cxx
Normal file
266
Tools/Combine/genfans.cxx
Normal file
|
@ -0,0 +1,266 @@
|
|||
// genfans.cxx -- Combine individual triangles into more optimal fans.
|
||||
//
|
||||
// Written by Curtis Olson, started March 1999.
|
||||
//
|
||||
// Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
|
||||
|
||||
#include "genfans.hxx"
|
||||
|
||||
|
||||
// make sure the list is expanded at least to hold "n" and then push
|
||||
// "i" onto the back of the "n" list.
|
||||
void FGGenFans::add_and_expand( reverse_list& by_node, int n, int i ) {
|
||||
int_list empty;
|
||||
|
||||
int size = (int)by_node.size();
|
||||
if ( size > n ) {
|
||||
// ok
|
||||
} else {
|
||||
// cout << "capacity = " << by_node.capacity() << endl;
|
||||
// cout << "size = " << size << " n = " << n
|
||||
// << " need to push = " << n - size + 1 << endl;
|
||||
for ( int i = 0; i < n - size + 1; ++i ) {
|
||||
by_node.push_back(empty);
|
||||
}
|
||||
}
|
||||
|
||||
by_node[n].push_back(i);
|
||||
}
|
||||
|
||||
|
||||
// given an input triangle, shuffle nodes so that "center" is the
|
||||
// first node, but maintain winding order.
|
||||
static FGTriEle canonify( const FGTriEle& t, int center ) {
|
||||
if ( t.get_n1() == center ) {
|
||||
// already ok
|
||||
return t;
|
||||
} else if ( t.get_n2() == center ) {
|
||||
return FGTriEle( t.get_n2(), t.get_n3(), t.get_n1(), 0.0 );
|
||||
} else if ( t.get_n3() == center ) {
|
||||
return FGTriEle( t.get_n3(), t.get_n1(), t.get_n2(), 0.0 );
|
||||
} else {
|
||||
cout << "ERROR, index doesn't refer to this triangle!!!" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
// returns a list of triangle indices
|
||||
static int_list make_best_fan( const triele_list& master_tris,
|
||||
const int center, const int_list& local_tris )
|
||||
{
|
||||
int_list best_result;
|
||||
|
||||
// try starting with each of local_tris to find the best fan
|
||||
// arrangement
|
||||
for ( int start = 0; start < (int)local_tris.size(); ++start ) {
|
||||
// cout << "trying with first triangle = " << local_tris[start] << endl;
|
||||
|
||||
int_list tmp_result;
|
||||
tmp_result.clear();
|
||||
|
||||
FGTriEle current_tri;
|
||||
FGTriEle test;
|
||||
current_tri = canonify( master_tris[local_tris[start]], center );
|
||||
tmp_result.push_back( local_tris[start] );
|
||||
|
||||
// follow the ring
|
||||
int next = -1;
|
||||
bool matches = true;
|
||||
while ( (next != start) && matches ) {
|
||||
// find next triangle in ring
|
||||
matches = false;
|
||||
for ( int i = 0; i < (int)local_tris.size(); ++i ) {
|
||||
test = canonify( master_tris[local_tris[i]], center );
|
||||
if ( current_tri.get_n3() == test.get_n2() ) {
|
||||
if ( i != start ) {
|
||||
// cout << " next triangle = " << local_tris[i] << endl;
|
||||
current_tri = test;
|
||||
tmp_result.push_back( local_tris[i] );
|
||||
matches = true;
|
||||
next = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( tmp_result.size() == local_tris.size() ) {
|
||||
// we found a complete usage, no need to go on
|
||||
// cout << "we found a complete usage, no need to go on" << endl;
|
||||
best_result = tmp_result;
|
||||
break;
|
||||
} else if ( tmp_result.size() > best_result.size() ) {
|
||||
// we found a better way to fan
|
||||
// cout << "we found a better fan arrangement" << endl;
|
||||
best_result = tmp_result;
|
||||
}
|
||||
}
|
||||
|
||||
return best_result;
|
||||
}
|
||||
|
||||
|
||||
static bool in_fan(int index, const int_list& fan ) {
|
||||
const_int_list_iterator current = fan.begin();
|
||||
const_int_list_iterator last = fan.end();
|
||||
|
||||
for ( ; current != last; ++current ) {
|
||||
if ( index == *current ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// recursive build fans from triangle list
|
||||
fan_list FGGenFans::greedy_build( triele_list tris ) {
|
||||
cout << "starting greedy build of fans" << endl;
|
||||
|
||||
fans.clear();
|
||||
|
||||
while ( ! tris.empty() ) {
|
||||
// cout << "building reverse_list" << endl;
|
||||
reverse_list by_node;
|
||||
by_node.clear();
|
||||
|
||||
// traverse the triangle list and for each node, build a list of
|
||||
// triangles that attach to it.
|
||||
|
||||
for ( int i = 0; i < (int)tris.size(); ++i ) {
|
||||
int n1 = tris[i].get_n1();
|
||||
int n2 = tris[i].get_n2();
|
||||
int n3 = tris[i].get_n3();
|
||||
|
||||
add_and_expand( by_node, n1, i );
|
||||
add_and_expand( by_node, n2, i );
|
||||
add_and_expand( by_node, n3, i );
|
||||
}
|
||||
|
||||
// find the node in the tris list that attaches to the most
|
||||
// triangles
|
||||
|
||||
// cout << "find most connected node" << endl;
|
||||
|
||||
int_list biggest_group;
|
||||
reverse_list_iterator r_current = by_node.begin();
|
||||
reverse_list_iterator r_last = by_node.end();
|
||||
int index = 0;
|
||||
int counter = 0;
|
||||
for ( ; r_current != r_last; ++r_current ) {
|
||||
if ( r_current->size() > biggest_group.size() ) {
|
||||
biggest_group = *r_current;
|
||||
index = counter;
|
||||
}
|
||||
++counter;
|
||||
}
|
||||
// cout << "triangle pool = " << tris.size() << endl;
|
||||
// cout << "biggest_group = " << biggest_group.size() << endl;
|
||||
// cout << "center node = " << index << endl;
|
||||
|
||||
// make the best fan we can out of this group
|
||||
// cout << "before make_best_fan()" << endl;
|
||||
int_list best_fan = make_best_fan( tris, index, biggest_group );
|
||||
// cout << "after make_best_fan()" << endl;
|
||||
|
||||
// generate point form of best_fan
|
||||
int_list node_list;
|
||||
node_list.clear();
|
||||
|
||||
int_list_iterator i_start = best_fan.begin();
|
||||
int_list_iterator i_current = i_start;
|
||||
int_list_iterator i_last = best_fan.end();
|
||||
for ( ; i_current != i_last; ++i_current ) {
|
||||
FGTriEle t = canonify( tris[*i_current], index );
|
||||
if ( i_start == i_current ) {
|
||||
node_list.push_back( t.get_n1() );
|
||||
node_list.push_back( t.get_n2() );
|
||||
}
|
||||
node_list.push_back( t.get_n3() );
|
||||
}
|
||||
// cout << "best list size = " << node_list.size() << endl;
|
||||
|
||||
// add this fan to the fan list
|
||||
fans.push_back( node_list );
|
||||
|
||||
// delete the triangles in best_fan out of tris and repeat
|
||||
triele_list_iterator t_current = tris.begin();
|
||||
triele_list_iterator t_last = tris.end();
|
||||
counter = 0;
|
||||
while ( t_current != t_last ) {
|
||||
if ( in_fan(counter, best_fan) ) {
|
||||
// cout << "erasing "
|
||||
// << t_current->get_n1() << ","
|
||||
// << t_current->get_n2() << ","
|
||||
// << t_current->get_n3()
|
||||
// << " from master tri pool"
|
||||
// << endl;
|
||||
tris.erase( t_current );
|
||||
} else {
|
||||
++t_current;
|
||||
}
|
||||
++counter;
|
||||
}
|
||||
}
|
||||
|
||||
cout << "end of greedy build of fans" << endl;
|
||||
cout << "average fan size = " << ave_size() << endl;
|
||||
|
||||
return fans;
|
||||
}
|
||||
|
||||
|
||||
// report average fan size
|
||||
double FGGenFans::ave_size() {
|
||||
double sum = 0.0;
|
||||
|
||||
fan_list_iterator current = fans.begin();
|
||||
fan_list_iterator last = fans.end();
|
||||
for ( ; current != last; ++current ) {
|
||||
sum += current->size();
|
||||
}
|
||||
|
||||
return sum / (double)fans.size();
|
||||
}
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.6 1999/04/05 02:16:02 curt
|
||||
// Fixed a compiler warning.
|
||||
//
|
||||
// Revision 1.5 1999/03/31 23:46:49 curt
|
||||
// Debugging output tweaks.
|
||||
//
|
||||
// Revision 1.4 1999/03/31 13:26:39 curt
|
||||
// Debugging output tweeaks.
|
||||
//
|
||||
// Revision 1.3 1999/03/31 05:35:04 curt
|
||||
// Fixed bug in genfans (deleting the wrong triangles from the available pool.)
|
||||
//
|
||||
// Revision 1.2 1999/03/30 23:50:15 curt
|
||||
// Fannifier is clearly bugging ... working on debugging it. I suspect there
|
||||
// is a problem related to deleting triangles from the triangle pool as they
|
||||
// are combined into fans.
|
||||
//
|
||||
// Revision 1.1 1999/03/29 13:08:35 curt
|
||||
// Initial revision.
|
||||
//
|
85
Tools/Combine/genfans.hxx
Normal file
85
Tools/Combine/genfans.hxx
Normal file
|
@ -0,0 +1,85 @@
|
|||
// genfans.hxx -- Combine individual triangles into more optimal fans.
|
||||
//
|
||||
// Written by Curtis Olson, started March 1999.
|
||||
//
|
||||
// Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
|
||||
|
||||
#ifndef _GENFANS_HXX
|
||||
#define _GENFANS_HXX
|
||||
|
||||
|
||||
#ifndef __cplusplus
|
||||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
|
||||
#include <Include/compiler.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <Main/construct_types.hxx>
|
||||
#include <Triangulate/trieles.hxx>
|
||||
|
||||
FG_USING_STD(vector);
|
||||
|
||||
|
||||
typedef vector < int_list > fan_list;
|
||||
typedef fan_list::iterator fan_list_iterator;
|
||||
typedef fan_list::const_iterator const_fan_list_iterator;
|
||||
|
||||
typedef vector < int_list > reverse_list;
|
||||
typedef reverse_list::iterator reverse_list_iterator;
|
||||
typedef reverse_list::const_iterator const_reverse_list_iterator;
|
||||
|
||||
|
||||
|
||||
class FGGenFans {
|
||||
|
||||
private:
|
||||
|
||||
fan_list fans;
|
||||
|
||||
// make sure the list is expanded at least to hold "n" and then
|
||||
// push "i" onto the back of the "n" list.
|
||||
void add_and_expand( reverse_list& by_node, int n, int i );
|
||||
|
||||
public:
|
||||
|
||||
// Constructor && Destructor
|
||||
inline FGGenFans() { }
|
||||
inline ~FGGenFans() { }
|
||||
|
||||
// recursive build fans from triangle list
|
||||
// fan_list greedy_build( triele_list tris );
|
||||
fan_list greedy_build( triele_list tris );
|
||||
|
||||
// report average fan size
|
||||
double ave_size();
|
||||
};
|
||||
|
||||
|
||||
#endif // _GENFANS_HXX
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.1 1999/03/29 13:08:35 curt
|
||||
// Initial revision.
|
||||
//
|
7
Tools/Construct/Makefile.am
Normal file
7
Tools/Construct/Makefile.am
Normal file
|
@ -0,0 +1,7 @@
|
|||
SUBDIRS = \
|
||||
Array \
|
||||
Clipper \
|
||||
Combine \
|
||||
GenOutput \
|
||||
Triangulate \
|
||||
Main
|
11
Tools/DEM/Makefile.am
Normal file
11
Tools/DEM/Makefile.am
Normal file
|
@ -0,0 +1,11 @@
|
|||
noinst_LIBRARIES = libDEM.a
|
||||
|
||||
libDEM_a_SOURCES = dem.cxx dem.hxx
|
||||
|
||||
INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib
|
||||
|
||||
# We can't build this with "-O2" (optimization) since this causes a seg fault
|
||||
# I haven't found a way to strip this out of the CXXFLAGS, so I'm just
|
||||
# setting it to "-g"
|
||||
# CXXFLAGS = -g
|
||||
|
977
Tools/DEM/dem.cxx
Normal file
977
Tools/DEM/dem.cxx
Normal file
|
@ -0,0 +1,977 @@
|
|||
// dem.cxx -- DEM management class
|
||||
//
|
||||
// Written by Curtis Olson, started March 1998.
|
||||
//
|
||||
// Copyright (C) 1998 Curtis L. Olson - curt@flightgear.org
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <Include/compiler.h>
|
||||
|
||||
#include <ctype.h> // isspace()
|
||||
#include <stdlib.h> // atoi()
|
||||
#include <math.h> // rint()
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
# include <sys/stat.h> // stat()
|
||||
#endif
|
||||
|
||||
#ifdef FG_HAVE_STD_INCLUDES
|
||||
# include <cerrno>
|
||||
#else
|
||||
# include <errno.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h> // stat()
|
||||
#endif
|
||||
|
||||
#include <Misc/fgstream.hxx>
|
||||
#include <Misc/strutils.hxx>
|
||||
#include <Include/fg_constants.h>
|
||||
|
||||
#include "dem.hxx"
|
||||
|
||||
|
||||
#define MAX_EX_NODES 10000
|
||||
|
||||
#if 0
|
||||
#ifdef WIN32
|
||||
# ifdef __BORLANDC__
|
||||
# include <dir.h>
|
||||
# define MKDIR(a) mkdir(a)
|
||||
# else
|
||||
# define MKDIR(a) mkdir(a,S_IRWXU) // I am just guessing at this flag (NHV)
|
||||
# endif // __BORLANDC__
|
||||
#endif // WIN32
|
||||
#endif //0
|
||||
|
||||
|
||||
FGDem::FGDem( void ) {
|
||||
// cout << "class FGDem CONstructor called." << endl;
|
||||
dem_data = new float[DEM_SIZE_1][DEM_SIZE_1];
|
||||
output_data = new float[DEM_SIZE_1][DEM_SIZE_1];
|
||||
}
|
||||
|
||||
|
||||
FGDem::FGDem( const string &file ) {
|
||||
// cout << "class FGDem CONstructor called." << endl;
|
||||
dem_data = new float[DEM_SIZE_1][DEM_SIZE_1];
|
||||
output_data = new float[DEM_SIZE_1][DEM_SIZE_1];
|
||||
|
||||
FGDem::open(file);
|
||||
}
|
||||
|
||||
|
||||
// open a DEM file
|
||||
int
|
||||
FGDem::open ( const string& file ) {
|
||||
// open input file (or read from stdin)
|
||||
if ( file == "-" ) {
|
||||
printf("Loading DEM data file: stdin\n");
|
||||
// fd = stdin;
|
||||
// fd = gzdopen(STDIN_FILENO, "r");
|
||||
printf("Not yet ported ...\n");
|
||||
return 0;
|
||||
} else {
|
||||
in = new fg_gzifstream( file );
|
||||
if ( !(*in) ) {
|
||||
cout << "Cannot open " << file << endl;
|
||||
return 0;
|
||||
}
|
||||
cout << "Loading DEM data file: " << file << endl;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// close a DEM file
|
||||
int
|
||||
FGDem::close () {
|
||||
// the fg_gzifstream doesn't seem to have a close()
|
||||
|
||||
delete in;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// return next token from input stream
|
||||
string
|
||||
FGDem::next_token() {
|
||||
string token;
|
||||
|
||||
*in >> token;
|
||||
|
||||
// cout << " returning " + token + "\n";
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
|
||||
// return next integer from input stream
|
||||
int
|
||||
FGDem::next_int() {
|
||||
int result;
|
||||
|
||||
*in >> result;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// return next double from input stream
|
||||
double
|
||||
FGDem::next_double() {
|
||||
double result;
|
||||
|
||||
*in >> result;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// return next exponential num from input stream
|
||||
double
|
||||
FGDem::next_exp() {
|
||||
string token;
|
||||
|
||||
token = next_token();
|
||||
|
||||
const char* p = token.c_str();
|
||||
char buf[64];
|
||||
char* bp = buf;
|
||||
|
||||
for ( ; *p != 0; ++p )
|
||||
{
|
||||
if ( *p == 'D' )
|
||||
*bp++ = 'E';
|
||||
else
|
||||
*bp++ = *p;
|
||||
}
|
||||
*bp = 0;
|
||||
return ::atof( buf );
|
||||
}
|
||||
|
||||
|
||||
// read and parse DEM "A" record
|
||||
int
|
||||
FGDem::read_a_record() {
|
||||
int i, inum;
|
||||
double dnum;
|
||||
string name, token;
|
||||
char c;
|
||||
|
||||
// get the name field (144 characters)
|
||||
for ( i = 0; i < 144; i++ ) {
|
||||
in->get(c);
|
||||
name += c;
|
||||
}
|
||||
|
||||
// clean off the trailing whitespace
|
||||
name = trim(name);
|
||||
cout << " Quad name field: " << name << endl;
|
||||
|
||||
// DEM level code, 3 reflects processing by DMA
|
||||
inum = next_int();
|
||||
cout << " DEM level code = " << inum << "\n";
|
||||
|
||||
if ( inum > 3 ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Pattern code, 1 indicates a regular elevation pattern
|
||||
inum = next_int();
|
||||
cout << " Pattern code = " << inum << "\n";
|
||||
|
||||
// Planimetric reference system code, 0 indicates geographic
|
||||
// coordinate system.
|
||||
inum = next_int();
|
||||
cout << " Planimetric reference code = " << inum << "\n";
|
||||
|
||||
// Zone code
|
||||
inum = next_int();
|
||||
cout << " Zone code = " << inum << "\n";
|
||||
|
||||
// Map projection parameters (ignored)
|
||||
for ( i = 0; i < 15; i++ ) {
|
||||
dnum = next_exp();
|
||||
// printf("%d: %f\n",i,dnum);
|
||||
}
|
||||
|
||||
// Units code, 3 represents arc-seconds as the unit of measure for
|
||||
// ground planimetric coordinates throughout the file.
|
||||
inum = next_int();
|
||||
if ( inum != 3 ) {
|
||||
cout << " Unknown (X,Y) units code = " << inum << "!\n";
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// Units code; 2 represents meters as the unit of measure for
|
||||
// elevation coordinates throughout the file.
|
||||
inum = next_int();
|
||||
if ( inum != 2 ) {
|
||||
cout << " Unknown (Z) units code = " << inum << "!\n";
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// Number (n) of sides in the polygon which defines the coverage of
|
||||
// the DEM file (usually equal to 4).
|
||||
inum = next_int();
|
||||
if ( inum != 4 ) {
|
||||
cout << " Unknown polygon dimension = " << inum << "!\n";
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// Ground coordinates of bounding box in arc-seconds
|
||||
dem_x1 = originx = next_exp();
|
||||
dem_y1 = originy = next_exp();
|
||||
cout << " Origin = (" << originx << "," << originy << ")\n";
|
||||
|
||||
dem_x2 = next_exp();
|
||||
dem_y2 = next_exp();
|
||||
|
||||
dem_x3 = next_exp();
|
||||
dem_y3 = next_exp();
|
||||
|
||||
dem_x4 = next_exp();
|
||||
dem_y4 = next_exp();
|
||||
|
||||
// Minimum/maximum elevations in meters
|
||||
dem_z1 = next_exp();
|
||||
dem_z2 = next_exp();
|
||||
cout << " Elevation range " << dem_z1 << " to " << dem_z2 << "\n";
|
||||
|
||||
// Counterclockwise angle from the primary axis of ground
|
||||
// planimetric referenced to the primary axis of the DEM local
|
||||
// reference system.
|
||||
token = next_token();
|
||||
|
||||
// Accuracy code; 0 indicates that a record of accuracy does not
|
||||
// exist and that no record type C will follow.
|
||||
|
||||
// DEM spacial resolution. Usually (3,3,1) (3,6,1) or (3,9,1)
|
||||
// depending on latitude
|
||||
|
||||
// I will eventually have to do something with this for data at
|
||||
// higher latitudes */
|
||||
token = next_token();
|
||||
cout << " accuracy & spacial resolution string = " << token << endl;
|
||||
i = token.length();
|
||||
cout << " length = " << i << "\n";
|
||||
|
||||
inum = atoi( token.substr( 0, i - 36 ) );
|
||||
row_step = atof( token.substr( i - 24, 12 ) );
|
||||
col_step = atof( token.substr( i - 36, 12 ) );
|
||||
cout << " Accuracy code = " << inum << "\n";
|
||||
cout << " column step = " << col_step <<
|
||||
" row step = " << row_step << "\n";
|
||||
|
||||
// dimension of arrays to follow (1)
|
||||
token = next_token();
|
||||
|
||||
// number of profiles
|
||||
dem_num_profiles = cols = next_int();
|
||||
cout << " Expecting " << dem_num_profiles << " profiles\n";
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// read and parse DEM "B" record
|
||||
void
|
||||
FGDem::read_b_record( ) {
|
||||
string token;
|
||||
int i;
|
||||
|
||||
// row / column id of this profile
|
||||
prof_row = next_int();
|
||||
prof_col = next_int();
|
||||
// printf("col id = %d row id = %d\n", prof_col, prof_row);
|
||||
|
||||
// Number of columns and rows (elevations) in this profile
|
||||
prof_num_rows = rows = next_int();
|
||||
prof_num_cols = next_int();
|
||||
// printf(" profile num rows = %d\n", prof_num_rows);
|
||||
|
||||
// Ground planimetric coordinates (arc-seconds) of the first
|
||||
// elevation in the profile
|
||||
prof_x1 = next_exp();
|
||||
prof_y1 = next_exp();
|
||||
// printf(" Starting at %.2f %.2f\n", prof_x1, prof_y1);
|
||||
|
||||
// Elevation of local datum for the profile. Always zero for
|
||||
// 1-degree DEM, the reference is mean sea level.
|
||||
token = next_token();
|
||||
|
||||
// Minimum and maximum elevations for the profile.
|
||||
token = next_token();
|
||||
token = next_token();
|
||||
|
||||
// One (usually) dimensional array (prof_num_cols,1) of elevations
|
||||
for ( i = 0; i < prof_num_rows; i++ ) {
|
||||
prof_data = next_int();
|
||||
dem_data[cur_col][i] = (float)prof_data;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// parse dem file
|
||||
int
|
||||
FGDem::parse( ) {
|
||||
int i;
|
||||
|
||||
cur_col = 0;
|
||||
|
||||
if ( !read_a_record() ) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
for ( i = 0; i < dem_num_profiles; i++ ) {
|
||||
// printf("Ready to read next b record\n");
|
||||
read_b_record();
|
||||
cur_col++;
|
||||
|
||||
if ( cur_col % 100 == 0 ) {
|
||||
cout << " loaded " << cur_col << " profiles of data\n";
|
||||
}
|
||||
}
|
||||
|
||||
cout << " Done parsing\n";
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// write out the area of data covered by the specified bucket. Data
|
||||
// is written out column by column starting at the lower left hand
|
||||
// corner.
|
||||
int
|
||||
FGDem::write_area( const string& root, FGBucket& b, bool compress ) {
|
||||
// calculate some boundaries
|
||||
double min_x = ( b.get_center_lon() - 0.5 * b.get_width() ) * 3600.0;
|
||||
double max_x = ( b.get_center_lon() + 0.5 * b.get_width() ) * 3600.0;
|
||||
|
||||
double min_y = ( b.get_center_lat() - 0.5 * b.get_height() ) * 3600.0;
|
||||
double max_y = ( b.get_center_lat() + 0.5 * b.get_height() ) * 3600.0;
|
||||
|
||||
cout << b << endl;
|
||||
cout << "width = " << b.get_width() << " height = " << b.get_height()
|
||||
<< endl;
|
||||
|
||||
int start_x = (int)((min_x - originx) / col_step);
|
||||
int span_x = (int)(b.get_width() * 3600.0 / col_step);
|
||||
|
||||
int start_y = (int)((min_y - originy) / row_step);
|
||||
int span_y = (int)(b.get_height() * 3600.0 / row_step);
|
||||
|
||||
cout << "start_x = " << start_x << " span_x = " << span_x << endl;
|
||||
cout << "start_y = " << start_y << " span_y = " << span_y << endl;
|
||||
|
||||
// Do a simple sanity checking. But, please, please be nice to
|
||||
// this write_area() routine and feed it buckets that coincide
|
||||
// well with the underlying grid structure and spacing.
|
||||
|
||||
if ( ( min_x < originx )
|
||||
|| ( max_x > originx + cols * col_step )
|
||||
|| ( min_y < originy )
|
||||
|| ( max_y > originy + rows * row_step ) ) {
|
||||
cout << " ERROR: bucket at least partially outside DEM data range!" <<
|
||||
endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// generate output file name
|
||||
string base = b.gen_base_path();
|
||||
string path = root + "/Scenery/" + base;
|
||||
string command = "mkdir -p " + path;
|
||||
system( command.c_str() );
|
||||
|
||||
string demfile = path + "/" + b.gen_index_str() + ".dem";
|
||||
cout << "demfile = " << demfile << endl;
|
||||
|
||||
// write the file
|
||||
FILE *fp;
|
||||
if ( (fp = fopen(demfile.c_str(), "w")) == NULL ) {
|
||||
cout << "cannot open " << demfile << " for writing!" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
fprintf( fp, "%d %d\n", (int)min_x, (int)min_y );
|
||||
fprintf( fp, "%d %d %d %d\n", span_x + 1, (int)col_step,
|
||||
span_y + 1, (int)row_step );
|
||||
for ( int i = start_x; i <= start_x + span_x; ++i ) {
|
||||
for ( int j = start_y; j <= start_y + span_y; ++j ) {
|
||||
fprintf( fp, "%d ", (int)dem_data[i][j] );
|
||||
}
|
||||
fprintf( fp, "\n" );
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
if ( compress ) {
|
||||
string command = "gzip --best -f " + demfile;
|
||||
system( command.c_str() );
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
// return the current altitude based on grid data. We should rewrite
|
||||
// this to interpolate exact values, but for now this is good enough
|
||||
double FGDem::interpolate_altitude( double lon, double lat ) {
|
||||
// we expect incoming (lon,lat) to be in arcsec for now
|
||||
|
||||
double xlocal, ylocal, dx, dy, zA, zB, elev;
|
||||
int x1, x2, x3, y1, y2, y3;
|
||||
float z1, z2, z3;
|
||||
int xindex, yindex;
|
||||
|
||||
/* determine if we are in the lower triangle or the upper triangle
|
||||
______
|
||||
| /|
|
||||
| / |
|
||||
| / |
|
||||
|/ |
|
||||
------
|
||||
|
||||
then calculate our end points
|
||||
*/
|
||||
|
||||
xlocal = (lon - originx) / col_step;
|
||||
ylocal = (lat - originy) / row_step;
|
||||
|
||||
xindex = (int)(xlocal);
|
||||
yindex = (int)(ylocal);
|
||||
|
||||
// printf("xindex = %d yindex = %d\n", xindex, yindex);
|
||||
|
||||
if ( xindex + 1 == cols ) {
|
||||
xindex--;
|
||||
}
|
||||
|
||||
if ( yindex + 1 == rows ) {
|
||||
yindex--;
|
||||
}
|
||||
|
||||
if ( (xindex < 0) || (xindex + 1 >= cols) ||
|
||||
(yindex < 0) || (yindex + 1 >= rows) ) {
|
||||
return(-9999);
|
||||
}
|
||||
|
||||
dx = xlocal - xindex;
|
||||
dy = ylocal - yindex;
|
||||
|
||||
if ( dx > dy ) {
|
||||
// lower triangle
|
||||
// printf(" Lower triangle\n");
|
||||
|
||||
x1 = xindex;
|
||||
y1 = yindex;
|
||||
z1 = dem_data[x1][y1];
|
||||
|
||||
x2 = xindex + 1;
|
||||
y2 = yindex;
|
||||
z2 = dem_data[x2][y2];
|
||||
|
||||
x3 = xindex + 1;
|
||||
y3 = yindex + 1;
|
||||
z3 = dem_data[x3][y3];
|
||||
|
||||
// printf(" dx = %.2f dy = %.2f\n", dx, dy);
|
||||
// printf(" (x1,y1,z1) = (%d,%d,%d)\n", x1, y1, z1);
|
||||
// printf(" (x2,y2,z2) = (%d,%d,%d)\n", x2, y2, z2);
|
||||
// printf(" (x3,y3,z3) = (%d,%d,%d)\n", x3, y3, z3);
|
||||
|
||||
zA = dx * (z2 - z1) + z1;
|
||||
zB = dx * (z3 - z1) + z1;
|
||||
|
||||
// printf(" zA = %.2f zB = %.2f\n", zA, zB);
|
||||
|
||||
if ( dx > FG_EPSILON ) {
|
||||
elev = dy * (zB - zA) / dx + zA;
|
||||
} else {
|
||||
elev = zA;
|
||||
}
|
||||
} else {
|
||||
// upper triangle
|
||||
// printf(" Upper triangle\n");
|
||||
|
||||
x1 = xindex;
|
||||
y1 = yindex;
|
||||
z1 = dem_data[x1][y1];
|
||||
|
||||
x2 = xindex;
|
||||
y2 = yindex + 1;
|
||||
z2 = dem_data[x2][y2];
|
||||
|
||||
x3 = xindex + 1;
|
||||
y3 = yindex + 1;
|
||||
z3 = dem_data[x3][y3];
|
||||
|
||||
// printf(" dx = %.2f dy = %.2f\n", dx, dy);
|
||||
// printf(" (x1,y1,z1) = (%d,%d,%d)\n", x1, y1, z1);
|
||||
// printf(" (x2,y2,z2) = (%d,%d,%d)\n", x2, y2, z2);
|
||||
// printf(" (x3,y3,z3) = (%d,%d,%d)\n", x3, y3, z3);
|
||||
|
||||
zA = dy * (z2 - z1) + z1;
|
||||
zB = dy * (z3 - z1) + z1;
|
||||
|
||||
// printf(" zA = %.2f zB = %.2f\n", zA, zB );
|
||||
// printf(" xB - xA = %.2f\n", col_step * dy / row_step);
|
||||
|
||||
if ( dy > FG_EPSILON ) {
|
||||
elev = dx * (zB - zA) / dy + zA;
|
||||
} else {
|
||||
elev = zA;
|
||||
}
|
||||
}
|
||||
|
||||
return(elev);
|
||||
}
|
||||
|
||||
|
||||
// Use least squares to fit a simpler data set to dem data
|
||||
void FGDem::fit( double error, FGBucket& p ) {
|
||||
double x[DEM_SIZE_1], y[DEM_SIZE_1];
|
||||
double m, b, ave_error, max_error;
|
||||
double cury, lasty;
|
||||
int n, row, start, end;
|
||||
int colmin, colmax, rowmin, rowmax;
|
||||
bool good_fit;
|
||||
// FILE *dem, *fit, *fit1;
|
||||
|
||||
printf("Initializing output mesh structure\n");
|
||||
outputmesh_init();
|
||||
|
||||
// determine dimensions
|
||||
colmin = p.get_x() * ( (cols - 1) / 8);
|
||||
colmax = colmin + ( (cols - 1) / 8);
|
||||
rowmin = p.get_y() * ( (rows - 1) / 8);
|
||||
rowmax = rowmin + ( (rows - 1) / 8);
|
||||
printf("Fitting region = %d,%d to %d,%d\n", colmin, rowmin, colmax, rowmax);
|
||||
|
||||
// include the corners explicitly
|
||||
outputmesh_set_pt(colmin, rowmin, dem_data[colmin][rowmin]);
|
||||
outputmesh_set_pt(colmin, rowmax, dem_data[colmin][rowmax]);
|
||||
outputmesh_set_pt(colmax, rowmax, dem_data[colmax][rowmax]);
|
||||
outputmesh_set_pt(colmax, rowmin, dem_data[colmax][rowmin]);
|
||||
|
||||
printf("Beginning best fit procedure\n");
|
||||
|
||||
for ( row = rowmin; row <= rowmax; row++ ) {
|
||||
// fit = fopen("fit.dat", "w");
|
||||
// fit1 = fopen("fit1.dat", "w");
|
||||
|
||||
start = colmin;
|
||||
|
||||
// printf(" fitting row = %d\n", row);
|
||||
|
||||
while ( start < colmax ) {
|
||||
end = start + 1;
|
||||
good_fit = true;
|
||||
|
||||
x[(end - start) - 1] = 0.0 + ( start * col_step );
|
||||
y[(end - start) - 1] = dem_data[start][row];
|
||||
|
||||
while ( (end <= colmax) && good_fit ) {
|
||||
n = (end - start) + 1;
|
||||
// printf("Least square of first %d points\n", n);
|
||||
x[end - start] = 0.0 + ( end * col_step );
|
||||
y[end - start] = dem_data[end][row];
|
||||
least_squares(x, y, n, &m, &b);
|
||||
ave_error = least_squares_error(x, y, n, m, b);
|
||||
max_error = least_squares_max_error(x, y, n, m, b);
|
||||
|
||||
/*
|
||||
printf("%d - %d ave error = %.2f max error = %.2f y = %.2f*x + %.2f\n",
|
||||
start, end, ave_error, max_error, m, b);
|
||||
|
||||
f = fopen("gnuplot.dat", "w");
|
||||
for ( j = 0; j <= end; j++) {
|
||||
fprintf(f, "%.2f %.2f\n", 0.0 + ( j * col_step ),
|
||||
dem_data[row][j]);
|
||||
}
|
||||
for ( j = start; j <= end; j++) {
|
||||
fprintf(f, "%.2f %.2f\n", 0.0 + ( j * col_step ),
|
||||
dem_data[row][j]);
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
printf("Please hit return: "); gets(junk);
|
||||
*/
|
||||
|
||||
if ( max_error > error ) {
|
||||
good_fit = false;
|
||||
}
|
||||
|
||||
end++;
|
||||
}
|
||||
|
||||
if ( !good_fit ) {
|
||||
// error exceeded the threshold, back up
|
||||
end -= 2; // back "end" up to the last good enough fit
|
||||
n--; // back "n" up appropriately too
|
||||
} else {
|
||||
// we popped out of the above loop while still within
|
||||
// the error threshold, so we must be at the end of
|
||||
// the data set
|
||||
end--;
|
||||
}
|
||||
|
||||
least_squares(x, y, n, &m, &b);
|
||||
ave_error = least_squares_error(x, y, n, m, b);
|
||||
max_error = least_squares_max_error(x, y, n, m, b);
|
||||
|
||||
/*
|
||||
printf("\n");
|
||||
printf("%d - %d ave error = %.2f max error = %.2f y = %.2f*x + %.2f\n",
|
||||
start, end, ave_error, max_error, m, b);
|
||||
printf("\n");
|
||||
|
||||
fprintf(fit1, "%.2f %.2f\n", x[0], m * x[0] + b);
|
||||
fprintf(fit1, "%.2f %.2f\n", x[end-start], m * x[end-start] + b);
|
||||
*/
|
||||
|
||||
if ( start > colmin ) {
|
||||
// skip this for the first line segment
|
||||
cury = m * x[0] + b;
|
||||
outputmesh_set_pt(start, row, (lasty + cury) / 2);
|
||||
// fprintf(fit, "%.2f %.2f\n", x[0], (lasty + cury) / 2);
|
||||
}
|
||||
|
||||
lasty = m * x[end-start] + b;
|
||||
start = end;
|
||||
}
|
||||
|
||||
/*
|
||||
fclose(fit);
|
||||
fclose(fit1);
|
||||
|
||||
dem = fopen("gnuplot.dat", "w");
|
||||
for ( j = 0; j < DEM_SIZE_1; j++) {
|
||||
fprintf(dem, "%.2f %.2f\n", 0.0 + ( j * col_step ),
|
||||
dem_data[j][row]);
|
||||
}
|
||||
fclose(dem);
|
||||
*/
|
||||
|
||||
// NOTICE, this is for testing only. This instance of
|
||||
// output_nodes should be removed. It should be called only
|
||||
// once at the end once all the nodes have been generated.
|
||||
// newmesh_output_nodes(&nm, "mesh.node");
|
||||
// printf("Please hit return: "); gets(junk);
|
||||
}
|
||||
|
||||
// outputmesh_output_nodes(fg_root, p);
|
||||
}
|
||||
|
||||
|
||||
// Initialize output mesh structure
|
||||
void FGDem::outputmesh_init( void ) {
|
||||
int i, j;
|
||||
|
||||
for ( j = 0; j < DEM_SIZE_1; j++ ) {
|
||||
for ( i = 0; i < DEM_SIZE_1; i++ ) {
|
||||
output_data[i][j] = -9999.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Get the value of a mesh node
|
||||
double FGDem::outputmesh_get_pt( int i, int j ) {
|
||||
return ( output_data[i][j] );
|
||||
}
|
||||
|
||||
|
||||
// Set the value of a mesh node
|
||||
void FGDem::outputmesh_set_pt( int i, int j, double value ) {
|
||||
// printf("Setting data[%d][%d] = %.2f\n", i, j, value);
|
||||
output_data[i][j] = value;
|
||||
}
|
||||
|
||||
|
||||
// Write out a node file that can be used by the "triangle" program.
|
||||
// Check for an optional "index.node.ex" file in case there is a .poly
|
||||
// file to go along with this node file. Include these nodes first
|
||||
// since they are referenced by position from the .poly file.
|
||||
void FGDem::outputmesh_output_nodes( const string& fg_root, FGBucket& p )
|
||||
{
|
||||
double exnodes[MAX_EX_NODES][3];
|
||||
struct stat stat_buf;
|
||||
string dir;
|
||||
char file[256], exfile[256];
|
||||
#ifdef WIN32
|
||||
char tmp_path[256];
|
||||
#endif
|
||||
string command;
|
||||
FILE *fd;
|
||||
long int index;
|
||||
int colmin, colmax, rowmin, rowmax;
|
||||
int i, j, count, excount, result;
|
||||
|
||||
// determine dimensions
|
||||
colmin = p.get_x() * ( (cols - 1) / 8);
|
||||
colmax = colmin + ( (cols - 1) / 8);
|
||||
rowmin = p.get_y() * ( (rows - 1) / 8);
|
||||
rowmax = rowmin + ( (rows - 1) / 8);
|
||||
cout << " dumping region = " << colmin << "," << rowmin << " to " <<
|
||||
colmax << "," << rowmax << "\n";
|
||||
|
||||
// generate the base directory
|
||||
string base_path = p.gen_base_path();
|
||||
cout << "fg_root = " << fg_root << " Base Path = " << base_path << endl;
|
||||
dir = fg_root + "/Scenery/" + base_path;
|
||||
cout << "Dir = " << dir << endl;
|
||||
|
||||
// stat() directory and create if needed
|
||||
errno = 0;
|
||||
result = stat(dir.c_str(), &stat_buf);
|
||||
if ( result != 0 && errno == ENOENT ) {
|
||||
cout << "Creating directory\n";
|
||||
|
||||
// #ifndef WIN32
|
||||
|
||||
command = "mkdir -p " + dir + "\n";
|
||||
system( command.c_str() );
|
||||
|
||||
#if 0
|
||||
// #else // WIN32
|
||||
|
||||
// Cygwin crashes when trying to output to node file
|
||||
// explicitly making directory structure seems OK on Win95
|
||||
|
||||
extract_path (base_path, tmp_path);
|
||||
|
||||
dir = fg_root + "/Scenery";
|
||||
if (my_mkdir ( dir.c_str() )) { exit (-1); }
|
||||
|
||||
dir = fg_root + "/Scenery/" + tmp_path;
|
||||
if (my_mkdir ( dir.c_str() )) { exit (-1); }
|
||||
|
||||
dir = fg_root + "/Scenery/" + base_path;
|
||||
if (my_mkdir ( dir.c_str() )) { exit (-1); }
|
||||
|
||||
// #endif // WIN32
|
||||
#endif //0
|
||||
|
||||
} else {
|
||||
// assume directory exists
|
||||
}
|
||||
|
||||
// get index and generate output file name
|
||||
index = p.gen_index();
|
||||
sprintf(file, "%s/%ld.node", dir.c_str(), index);
|
||||
|
||||
// get (optional) extra node file name (in case there is matching
|
||||
// .poly file.
|
||||
strcpy(exfile, file);
|
||||
strcat(exfile, ".ex");
|
||||
|
||||
// load extra nodes if they exist
|
||||
excount = 0;
|
||||
if ( (fd = fopen(exfile, "r")) != NULL ) {
|
||||
int junki;
|
||||
fscanf(fd, "%d %d %d %d", &excount, &junki, &junki, &junki);
|
||||
|
||||
if ( excount > MAX_EX_NODES - 1 ) {
|
||||
printf("Error, too many 'extra' nodes, increase array size\n");
|
||||
exit(-1);
|
||||
} else {
|
||||
printf(" Expecting %d 'extra' nodes\n", excount);
|
||||
}
|
||||
|
||||
for ( i = 1; i <= excount; i++ ) {
|
||||
fscanf(fd, "%d %lf %lf %lf\n", &junki,
|
||||
&exnodes[i][0], &exnodes[i][1], &exnodes[i][2]);
|
||||
printf("(extra) %d %.2f %.2f %.2f\n",
|
||||
i, exnodes[i][0], exnodes[i][1], exnodes[i][2]);
|
||||
}
|
||||
fclose(fd);
|
||||
}
|
||||
|
||||
printf("Creating node file: %s\n", file);
|
||||
fd = fopen(file, "w");
|
||||
|
||||
// first count regular nodes to generate header
|
||||
count = 0;
|
||||
for ( j = rowmin; j <= rowmax; j++ ) {
|
||||
for ( i = colmin; i <= colmax; i++ ) {
|
||||
if ( output_data[i][j] > -9000.0 ) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
// printf(" count = %d\n", count);
|
||||
}
|
||||
fprintf(fd, "%d 2 1 0\n", count + excount);
|
||||
|
||||
// now write out extra node data
|
||||
for ( i = 1; i <= excount; i++ ) {
|
||||
fprintf(fd, "%d %.2f %.2f %.2f\n",
|
||||
i, exnodes[i][0], exnodes[i][1], exnodes[i][2]);
|
||||
}
|
||||
|
||||
// write out actual node data
|
||||
count = excount + 1;
|
||||
for ( j = rowmin; j <= rowmax; j++ ) {
|
||||
for ( i = colmin; i <= colmax; i++ ) {
|
||||
if ( output_data[i][j] > -9000.0 ) {
|
||||
fprintf(fd, "%d %.2f %.2f %.2f\n",
|
||||
count++,
|
||||
originx + (double)i * col_step,
|
||||
originy + (double)j * row_step,
|
||||
output_data[i][j]);
|
||||
}
|
||||
}
|
||||
// printf(" count = %d\n", count);
|
||||
}
|
||||
|
||||
fclose(fd);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
FGDem::~FGDem( void ) {
|
||||
// printf("class FGDem DEstructor called.\n");
|
||||
delete [] dem_data;
|
||||
delete [] output_data;
|
||||
}
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.27 1999/03/25 19:04:36 curt
|
||||
// Minor tweaks related to FGBucket usage.
|
||||
//
|
||||
// Revision 1.26 1999/03/13 17:40:37 curt
|
||||
// Moved point interpolation and least squares fitting to contruction program
|
||||
// area.
|
||||
// Moved leastsqs.* to Lib/Math/
|
||||
//
|
||||
// Revision 1.25 1999/03/12 22:53:07 curt
|
||||
// Added a routine to dump out the portion of the dem data covered by a
|
||||
// specified bucket. Other changes related to needs of scenery tools overhaul.
|
||||
//
|
||||
// Revision 1.24 1999/03/11 23:31:56 curt
|
||||
// Tweaks to use newbucket.hxx
|
||||
//
|
||||
// Revision 1.23 1999/03/10 01:09:12 curt
|
||||
// Tweaks to go along with scenery tools overhaul.
|
||||
// Added a new constructor that accepts the file name.
|
||||
//
|
||||
// Revision 1.22 1999/01/19 20:56:56 curt
|
||||
// MacOS portability changes contributed by "Robert Puyol" <puyol@abvent.fr>
|
||||
//
|
||||
// Revision 1.21 1998/11/06 14:04:32 curt
|
||||
// Changes due to updates in fgstream.
|
||||
//
|
||||
// Revision 1.20 1998/10/28 19:38:20 curt
|
||||
// Elliminate some unnecessary win32 specific stuff (by Norman Vine)
|
||||
//
|
||||
// Revision 1.19 1998/10/22 21:59:19 curt
|
||||
// Fixed a couple subtle bugs that resulted from some of my c++ conversions.
|
||||
// One bug could cause a segfault on certain input, and the other bug could
|
||||
// cause the whole procedure to go balistic and generate huge files (also only
|
||||
// on rare input combinations.)
|
||||
//
|
||||
// Revision 1.18 1998/10/18 01:17:09 curt
|
||||
// Point3D tweaks.
|
||||
//
|
||||
// Revision 1.17 1998/10/16 19:08:12 curt
|
||||
// Portability updates from Bernie Bright.
|
||||
//
|
||||
// Revision 1.16 1998/10/02 21:41:39 curt
|
||||
// Fixes for win32.
|
||||
//
|
||||
// Revision 1.15 1998/09/21 20:53:59 curt
|
||||
// minor tweaks to clean a few additional things up after the rewrite.
|
||||
//
|
||||
// Revision 1.14 1998/09/19 17:59:45 curt
|
||||
// Use c++ streams (fg_gzifstream). Also converted many character arrays to
|
||||
// the string class.
|
||||
//
|
||||
// Revision 1.13 1998/09/09 16:24:04 curt
|
||||
// Fixed a bug in the handling of exclude files which was causing
|
||||
// a crash by calling fclose() on an invalid file handle.
|
||||
//
|
||||
// Revision 1.12 1998/08/24 20:03:31 curt
|
||||
// Eliminated a possible memory overrun error.
|
||||
// Use the proper free() rather than the incorrect delete().
|
||||
//
|
||||
// Revision 1.11 1998/07/20 12:46:11 curt
|
||||
// When outputing to a .node file, first check for an optional
|
||||
// "index.node.ex" file in case there is a .poly file to go along with this
|
||||
// node file. Include these nodes first since they are referenced by position
|
||||
// from the .poly file. This is my first pass at adding an area "cutout"
|
||||
// feature to the terrain generation pipeline.
|
||||
//
|
||||
// Revision 1.10 1998/07/13 20:58:02 curt
|
||||
// .
|
||||
//
|
||||
// Revision 1.9 1998/07/13 15:29:49 curt
|
||||
// Added #ifdef HAVE_CONFIG_H
|
||||
//
|
||||
// Revision 1.8 1998/07/04 00:47:18 curt
|
||||
// typedef'd struct fgBUCKET.
|
||||
//
|
||||
// Revision 1.7 1998/06/05 18:14:39 curt
|
||||
// Abort out early when reading the "A" record if it doesn't look like
|
||||
// a proper DEM file.
|
||||
//
|
||||
// Revision 1.6 1998/05/02 01:49:21 curt
|
||||
// Fixed a bug where the wrong variable was being initialized.
|
||||
//
|
||||
// Revision 1.5 1998/04/25 15:00:32 curt
|
||||
// Changed "r" to "rb" in gzopen() options. This fixes bad behavior in win32.
|
||||
//
|
||||
// Revision 1.4 1998/04/22 13:14:46 curt
|
||||
// Fixed a bug in zlib usage.
|
||||
//
|
||||
// Revision 1.3 1998/04/18 03:53:05 curt
|
||||
// Added zlib support.
|
||||
//
|
||||
// Revision 1.2 1998/04/14 02:43:27 curt
|
||||
// Used "new" to auto-allocate large DEM parsing arrays in class constructor.
|
||||
//
|
||||
// Revision 1.1 1998/04/08 22:57:22 curt
|
||||
// Adopted Gnu automake/autoconf system.
|
||||
//
|
||||
// Revision 1.3 1998/04/06 21:09:41 curt
|
||||
// Additional win32 support.
|
||||
// Fixed a bad bug in dem file parsing that was causing the output to be
|
||||
// flipped about x = y.
|
||||
//
|
||||
// Revision 1.2 1998/03/23 20:35:41 curt
|
||||
// Updated to use FG_EPSILON
|
||||
//
|
||||
// Revision 1.1 1998/03/19 02:54:47 curt
|
||||
// Reorganized into a class lib called fgDEM.
|
||||
//
|
||||
// Revision 1.1 1998/03/19 01:46:28 curt
|
||||
// Initial revision.
|
||||
//
|
210
Tools/DEM/dem.hxx
Normal file
210
Tools/DEM/dem.hxx
Normal file
|
@ -0,0 +1,210 @@
|
|||
// dem.hxx -- DEM management class
|
||||
//
|
||||
// Written by Curtis Olson, started March 1998.
|
||||
//
|
||||
// Copyright (C) 1998 Curtis L. Olson - curt@flightgear.org
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
|
||||
|
||||
#ifndef _DEM_HXX
|
||||
#define _DEM_HXX
|
||||
|
||||
|
||||
#ifndef __cplusplus
|
||||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
|
||||
#include <Bucket/newbucket.hxx>
|
||||
#include <Misc/fgstream.hxx>
|
||||
|
||||
|
||||
#define DEM_SIZE 1200
|
||||
#define DEM_SIZE_1 1201
|
||||
|
||||
|
||||
class FGDem {
|
||||
|
||||
private:
|
||||
|
||||
// file pointer for input
|
||||
// gzFile fd;
|
||||
fg_gzifstream *in;
|
||||
|
||||
// coordinates (in arc seconds) of south west corner
|
||||
double originx, originy;
|
||||
|
||||
// number of columns and rows
|
||||
int cols, rows;
|
||||
|
||||
// Distance between column and row data points (in arc seconds)
|
||||
double col_step, row_step;
|
||||
|
||||
// pointers to the actual grid data allocated here
|
||||
float (*dem_data)[DEM_SIZE_1];
|
||||
float (*output_data)[DEM_SIZE_1];
|
||||
|
||||
// Current "A" Record Information
|
||||
char dem_description[80], dem_quadrangle[80];
|
||||
double dem_x1, dem_y1, dem_x2, dem_y2, dem_x3, dem_y3, dem_x4, dem_y4;
|
||||
double dem_z1, dem_z2;
|
||||
int dem_resolution, dem_num_profiles;
|
||||
|
||||
// Current "B" Record Information
|
||||
int prof_col, prof_row;
|
||||
int prof_num_cols, prof_num_rows;
|
||||
double prof_x1, prof_y1;
|
||||
int prof_data;
|
||||
|
||||
// temporary values for the class to use
|
||||
char option_name[32];
|
||||
int do_data;
|
||||
int cur_col, cur_row;
|
||||
|
||||
// return next token from input stream
|
||||
string next_token();
|
||||
|
||||
// return next integer from input stream
|
||||
int next_int();
|
||||
|
||||
// return next double from input stream
|
||||
double next_double();
|
||||
|
||||
// return next exponential num from input stream
|
||||
double next_exp();
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
FGDem( void );
|
||||
FGDem( const string& file );
|
||||
|
||||
// Destructor
|
||||
~FGDem( void );
|
||||
|
||||
// open a DEM file (use "-" if input is coming from stdin)
|
||||
int open ( const string& file );
|
||||
|
||||
// close a DEM file
|
||||
int close();
|
||||
|
||||
// parse a DEM file
|
||||
int parse();
|
||||
|
||||
// read and parse DEM "A" record
|
||||
int read_a_record();
|
||||
|
||||
// read and parse DEM "B" record
|
||||
void read_b_record();
|
||||
|
||||
// write out the area of data covered by the specified bucket.
|
||||
// Data is written out column by column starting at the lower left
|
||||
// hand corner.
|
||||
int write_area( const string& root, FGBucket& b, bool compress );
|
||||
|
||||
#if 0
|
||||
// return the current altitude based on grid data. We should
|
||||
// rewrite this to interpolate exact values, but for now this is
|
||||
// good enough
|
||||
double interpolate_altitude( double lon, double lat );
|
||||
|
||||
// Use least squares to fit a simpler data set to dem data
|
||||
void fit( double error, FGBucket& p );
|
||||
|
||||
// Initialize output mesh structure
|
||||
void outputmesh_init( void );
|
||||
|
||||
// Get the value of a mesh node
|
||||
double outputmesh_get_pt( int i, int j );
|
||||
|
||||
// Set the value of a mesh node
|
||||
void outputmesh_set_pt( int i, int j, double value );
|
||||
|
||||
// Write out a node file that can be used by the "triangle" program
|
||||
void outputmesh_output_nodes( const string& fg_root, FGBucket& p );
|
||||
#endif
|
||||
|
||||
// Informational methods
|
||||
inline double get_originx() const { return originx; }
|
||||
inline double get_originy() const { return originy; }
|
||||
inline int get_cols() const { return cols; }
|
||||
inline int get_rows() const { return rows; }
|
||||
inline double get_col_step() const { return col_step; }
|
||||
inline double get_row_step() const { return row_step; }
|
||||
};
|
||||
|
||||
|
||||
#endif // _DEM_HXX
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.13 1999/03/13 17:40:39 curt
|
||||
// Moved point interpolation and least squares fitting to contruction program
|
||||
// area.
|
||||
// Moved leastsqs.* to Lib/Math/
|
||||
//
|
||||
// Revision 1.12 1999/03/12 22:53:09 curt
|
||||
// Added a routine to dump out the portion of the dem data covered by a
|
||||
// specified bucket. Other changes related to needs of scenery tools overhaul.
|
||||
//
|
||||
// Revision 1.11 1999/03/11 23:31:57 curt
|
||||
// Tweaks to use newbucket.hxx
|
||||
//
|
||||
// Revision 1.10 1999/03/10 01:09:13 curt
|
||||
// Tweaks to go along with scenery tools overhaul.
|
||||
// Added a new constructor that accepts the file name.
|
||||
//
|
||||
// Revision 1.9 1998/10/16 19:08:14 curt
|
||||
// Portability updates from Bernie Bright.
|
||||
//
|
||||
// Revision 1.8 1998/09/19 17:59:46 curt
|
||||
// Use c++ streams (fg_gzifstream). Also converted many character arrays to
|
||||
// the string class.
|
||||
//
|
||||
// Revision 1.7 1998/07/04 00:47:19 curt
|
||||
// typedef'd struct fgBUCKET.
|
||||
//
|
||||
// Revision 1.6 1998/06/05 18:14:40 curt
|
||||
// Abort out early when reading the "A" record if it doesn't look like
|
||||
// a proper DEM file.
|
||||
//
|
||||
// Revision 1.5 1998/04/22 13:14:46 curt
|
||||
// Fixed a bug in zlib usage.
|
||||
//
|
||||
// Revision 1.4 1998/04/21 17:03:41 curt
|
||||
// Prepairing for C++ integration.
|
||||
//
|
||||
// Revision 1.3 1998/04/18 03:53:06 curt
|
||||
// Added zlib support.
|
||||
//
|
||||
// Revision 1.2 1998/04/14 02:43:28 curt
|
||||
// Used "new" to auto-allocate large DEM parsing arrays in class constructor.
|
||||
//
|
||||
// Revision 1.1 1998/04/08 22:57:23 curt
|
||||
// Adopted Gnu automake/autoconf system.
|
||||
//
|
||||
// Revision 1.2 1998/03/23 20:35:42 curt
|
||||
// Updated to use FG_EPSILON
|
||||
//
|
||||
// Revision 1.1 1998/03/19 02:54:47 curt
|
||||
// Reorganized into a class lib called fgDEM.
|
||||
//
|
||||
// Revision 1.1 1998/03/19 01:46:29 curt
|
||||
// Initial revision.
|
||||
//
|
58
Tools/DemChop/Makefile.am
Normal file
58
Tools/DemChop/Makefile.am
Normal file
|
@ -0,0 +1,58 @@
|
|||
#---------------------------------------------------------------------------
|
||||
# Makefile
|
||||
#
|
||||
# Written by Curtis Olson, started March 1999.
|
||||
#
|
||||
# Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
|
||||
#
|
||||
# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
# $Id$
|
||||
# (Log is kept at end of this file)
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
|
||||
bin_PROGRAMS = demchop
|
||||
|
||||
demchop_SOURCES = \
|
||||
demchop.cxx point2d.hxx
|
||||
|
||||
demchop_LDADD = \
|
||||
$(top_builddir)/Tools/Lib/DEM/libDEM.a \
|
||||
$(top_builddir)/Lib/Bucket/libBucket.a \
|
||||
$(top_builddir)/Lib/Misc/libMisc.a \
|
||||
$(top_builddir)/Lib/Debug/libDebug.a \
|
||||
$(top_builddir)/Lib/zlib/libz.a \
|
||||
$(base_LIBS)
|
||||
|
||||
INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib -I$(top_builddir)/Tools/Lib
|
||||
|
||||
# We can't build this with "-O2" (optimization) since this causes a seg fault
|
||||
# I haven't found a way to strip this out of the CXXFLAGS, so I'm just
|
||||
# setting it to "-g"
|
||||
# CXXFLAGS = -g
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# $Log$
|
||||
# Revision 1.3 1999/03/17 23:51:07 curt
|
||||
# Removed forced -g compiler flag.
|
||||
#
|
||||
# Revision 1.2 1999/03/12 22:53:45 curt
|
||||
# First working version!
|
||||
#
|
||||
# Revision 1.1 1999/03/10 01:02:54 curt
|
||||
# Initial revision.
|
||||
#
|
113
Tools/DemChop/demchop.cxx
Normal file
113
Tools/DemChop/demchop.cxx
Normal file
|
@ -0,0 +1,113 @@
|
|||
// demchop.cxx -- chop up a dem file into it's corresponding pieces and stuff
|
||||
// them into the workspace directory
|
||||
//
|
||||
// Written by Curtis Olson, started March 1999.
|
||||
//
|
||||
// Copyright (C) 1997 Curtis L. Olson - curt@flightgear.org
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
|
||||
|
||||
#include <Include/compiler.h>
|
||||
|
||||
#include STL_STRING
|
||||
|
||||
#include <Debug/logstream.hxx>
|
||||
#include <Bucket/newbucket.hxx>
|
||||
#include <DEM/dem.hxx>
|
||||
|
||||
#include "point2d.hxx"
|
||||
|
||||
FG_USING_STD(string);
|
||||
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
/*
|
||||
fgDEM dem;
|
||||
FGBucket p;
|
||||
string fg_root;
|
||||
string filename;
|
||||
double error;
|
||||
int i, j;
|
||||
*/
|
||||
|
||||
fglog().setLogLevels( FG_ALL, FG_DEBUG );
|
||||
|
||||
if ( argc != 3 ) {
|
||||
FG_LOG( FG_GENERAL, FG_ALERT,
|
||||
"Usage " << argv[0] << " <dem_file> <work_dir>" );
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
string dem_name = argv[1];
|
||||
string work_dir = argv[2];
|
||||
string command = "mkdir -p " + work_dir;
|
||||
system( command.c_str() );
|
||||
|
||||
FGDem dem(dem_name);
|
||||
dem.parse();
|
||||
dem.close();
|
||||
|
||||
point2d min, max;
|
||||
min.x = dem.get_originx() / 3600.0 + FG_HALF_BUCKET_SPAN;
|
||||
min.y = dem.get_originy() / 3600.0 + FG_HALF_BUCKET_SPAN;
|
||||
FGBucket b_min( min.x, min.y );
|
||||
|
||||
max.x = (dem.get_originx() + dem.get_cols() * dem.get_col_step()) / 3600.0
|
||||
- FG_HALF_BUCKET_SPAN;
|
||||
max.y = (dem.get_originy() + dem.get_rows() * dem.get_row_step()) / 3600.0
|
||||
- FG_HALF_BUCKET_SPAN;
|
||||
FGBucket b_max( max.x, max.y );
|
||||
|
||||
if ( b_min == b_max ) {
|
||||
dem.write_area( work_dir, b_min, true );
|
||||
} else {
|
||||
FGBucket b_cur;
|
||||
int dx, dy, i, j;
|
||||
|
||||
fgBucketDiff(b_min, b_max, &dx, &dy);
|
||||
cout << "DEM file spans tile boundaries" << endl;
|
||||
cout << " dx = " << dx << " dy = " << dy << endl;
|
||||
|
||||
if ( (dx > 20) || (dy > 20) ) {
|
||||
cout << "somethings really wrong!!!!" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
for ( j = 0; j <= dy; j++ ) {
|
||||
for ( i = 0; i <= dx; i++ ) {
|
||||
b_cur = fgBucketOffset(min.x, min.y, i, j);
|
||||
dem.write_area( work_dir, b_cur, true );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.3 1999/03/12 22:53:46 curt
|
||||
// First working version!
|
||||
//
|
||||
// Revision 1.2 1999/03/10 16:09:44 curt
|
||||
// Hacking towards the first working version.
|
||||
//
|
||||
// Revision 1.1 1999/03/10 01:02:54 curt
|
||||
// Initial revision.
|
||||
//
|
44
Tools/DemChop/point2d.cxx
Normal file
44
Tools/DemChop/point2d.cxx
Normal file
|
@ -0,0 +1,44 @@
|
|||
// point2d.cxx -- 2d coordinate routines
|
||||
//
|
||||
// Written by Curtis Olson, started September 1998.
|
||||
//
|
||||
// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
//
|
||||
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "point2d.hxx"
|
||||
|
||||
|
||||
// convert a point from cartesian to polar coordinates
|
||||
point2d cart_to_polar_2d(point2d in) {
|
||||
point2d result;
|
||||
result.dist = sqrt( in.x * in.x + in.y * in.y );
|
||||
result.theta = atan2(in.y, in.x);
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.1 1999/03/10 01:02:54 curt
|
||||
// Initial revision.
|
||||
//
|
62
Tools/DemChop/point2d.hxx
Normal file
62
Tools/DemChop/point2d.hxx
Normal file
|
@ -0,0 +1,62 @@
|
|||
// point2d.hxx -- define a 2d point class
|
||||
//
|
||||
// Written by Curtis Olson, started February 1998.
|
||||
//
|
||||
// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
//
|
||||
|
||||
|
||||
#ifndef _POINT2D_HXX
|
||||
#define _POINT2D_HXX
|
||||
|
||||
|
||||
#include <list>
|
||||
|
||||
|
||||
class point2d {
|
||||
public:
|
||||
union {
|
||||
double x;
|
||||
double dist;
|
||||
double lon;
|
||||
};
|
||||
union {
|
||||
double y;
|
||||
double theta;
|
||||
double lat;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// convert a point from cartesian to polar coordinates
|
||||
point2d cart_to_polar_2d(point2d in);
|
||||
|
||||
|
||||
#endif // _POINT2D_HXX
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.1 1999/03/10 16:09:45 curt
|
||||
// Hacking towards the first working version.
|
||||
//
|
||||
// Revision 1.1 1998/09/04 23:04:53 curt
|
||||
// Beginning of convex hull genereration routine.
|
||||
//
|
||||
//
|
70
Tools/DemInfo/Makefile.am
Normal file
70
Tools/DemInfo/Makefile.am
Normal file
|
@ -0,0 +1,70 @@
|
|||
#---------------------------------------------------------------------------
|
||||
# Makefile
|
||||
#
|
||||
# Written by Curtis Olson, started June 1998.
|
||||
#
|
||||
# Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
|
||||
#
|
||||
# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
# $Id$
|
||||
# (Log is kept at end of this file)
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
|
||||
bin_PROGRAMS = deminfo
|
||||
|
||||
deminfo_SOURCES = \
|
||||
deminfo.cxx
|
||||
|
||||
deminfo_LDADD = \
|
||||
$(top_builddir)/Tools/Lib/DEM/libDEM.a \
|
||||
$(top_builddir)/Lib/Bucket/libBucket.a \
|
||||
$(top_builddir)/Lib/Misc/libMisc.a \
|
||||
$(top_builddir)/Lib/zlib/libz.a \
|
||||
$(base_LIBS)
|
||||
|
||||
INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib -I$(top_builddir)/Tools/Lib
|
||||
|
||||
# We can't build this with "-O2" (optimization) since this causes a seg fault
|
||||
# I haven't found a way to strip this out of the CXXFLAGS, so I'm just
|
||||
# setting it to "-g"
|
||||
# CXXFLAGS = -g
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# $Log$
|
||||
# Revision 1.7 1999/03/17 23:51:14 curt
|
||||
# Removed forced -g compiler flag.
|
||||
#
|
||||
# Revision 1.6 1999/03/08 22:00:46 curt
|
||||
# Lots of directory layout reorganization.
|
||||
#
|
||||
# Revision 1.5 1999/02/01 21:09:27 curt
|
||||
# Moving location of Lib/DEM/ to Tools/DEM/
|
||||
#
|
||||
# Revision 1.4 1998/11/04 23:01:48 curt
|
||||
# Changes to the automake/autoconf system to reduce the number of libraries
|
||||
# that are unnecessarily linked into the various executables.
|
||||
#
|
||||
# Revision 1.3 1998/09/19 18:01:21 curt
|
||||
# Support for changes to libDEM.a
|
||||
#
|
||||
# Revision 1.2 1998/07/30 23:49:24 curt
|
||||
# Removed libtool support.
|
||||
#
|
||||
# Revision 1.1 1998/06/04 19:18:04 curt
|
||||
# Initial revision.
|
||||
#
|
78
Tools/DemInfo/deminfo.cxx
Normal file
78
Tools/DemInfo/deminfo.cxx
Normal file
|
@ -0,0 +1,78 @@
|
|||
// deminfo.cxx -- main loop
|
||||
//
|
||||
// Written by Curtis Olson, started June 1998.
|
||||
//
|
||||
// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
//
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
|
||||
#include <DEM/dem.hxx>
|
||||
|
||||
|
||||
// static float dem_data[DEM_SIZE_1][DEM_SIZE_1];
|
||||
// static float output_data[DEM_SIZE_1][DEM_SIZE_1];
|
||||
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
// DEM data
|
||||
FGDem dem;
|
||||
string filename;
|
||||
double error;
|
||||
int i, j;
|
||||
|
||||
if ( argc != 2 ) {
|
||||
printf("Usage: %s <file.dem>\n", argv[0]);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// set input dem file name
|
||||
filename = argv[1];
|
||||
|
||||
dem.open(filename);
|
||||
|
||||
if ( dem.read_a_record() ) {
|
||||
cout << "Results = " << filename << " "
|
||||
<< dem.get_originx() / 3600.0 << " "
|
||||
<< dem.get_originy() / 3600.0 << "\n";
|
||||
} else {
|
||||
cout << "Error parsing DEM file.\n";
|
||||
}
|
||||
|
||||
dem.close();
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.3 1999/03/12 22:54:04 curt
|
||||
// Convert fgDEM to FGDem ...
|
||||
//
|
||||
// Revision 1.2 1998/09/19 18:01:22 curt
|
||||
// Support for changes to libDEM.a
|
||||
//
|
||||
// Revision 1.1 1998/06/04 19:18:05 curt
|
||||
// Initial revision.
|
||||
//
|
61
Tools/DemInfo/gather-dem-info.pl
Executable file
61
Tools/DemInfo/gather-dem-info.pl
Executable file
|
@ -0,0 +1,61 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# script to gather DEM position info so we can associate a file name with a
|
||||
# position.
|
||||
#
|
||||
# Written by Curtis Olson, started June 1998.
|
||||
#
|
||||
# Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
|
||||
#
|
||||
# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
# $Id$
|
||||
# (Log is kept at end of this file)
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
|
||||
if ( $#ARGV < 0 ) {
|
||||
die "Usage: $0 search_dir ... \n";
|
||||
}
|
||||
|
||||
while ( $dir = shift(@ARGV) ) {
|
||||
# print "processing $dir\n";
|
||||
|
||||
@allfiles = `find $dir -print`;
|
||||
|
||||
foreach $file (@allfiles) {
|
||||
chop($file);
|
||||
# print "trying $file\n";
|
||||
if ( -f $file ) {
|
||||
# print "really trying $file\n";
|
||||
open ( INFO, "./deminfo $file |" );
|
||||
while ( <INFO> ) {
|
||||
if ( m/Results = / ) {
|
||||
$_ =~ s/Results = //;
|
||||
print $_;
|
||||
}
|
||||
}
|
||||
close(INFO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# $Log$
|
||||
# Revision 1.1 1998/06/04 19:18:06 curt
|
||||
# Initial revision.
|
||||
#
|
47
Tools/DemRaw2ascii/Makefile.am
Normal file
47
Tools/DemRaw2ascii/Makefile.am
Normal file
|
@ -0,0 +1,47 @@
|
|||
#---------------------------------------------------------------------------
|
||||
# Makefile
|
||||
#
|
||||
# Written by Curtis Olson, started February 1998.
|
||||
#
|
||||
# Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
|
||||
#
|
||||
# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
# $Id$
|
||||
# (Log is kept at end of this file)
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
|
||||
bin_PROGRAMS = raw2ascii
|
||||
|
||||
raw2ascii_SOURCES = main.c rawdem.c rawdem.h
|
||||
|
||||
raw2ascii_LDADD = $(base_LIBS)
|
||||
|
||||
INCLUDES +=
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# $Log$
|
||||
# Revision 1.3 1998/11/04 23:01:50 curt
|
||||
# Changes to the automake/autoconf system to reduce the number of libraries
|
||||
# that are unnecessarily linked into the various executables.
|
||||
#
|
||||
# Revision 1.2 1998/04/24 00:44:04 curt
|
||||
# Added zlib support.
|
||||
#
|
||||
# Revision 1.1 1998/04/18 03:59:44 curt
|
||||
# Incorporated into gnu automake/autoconf system.
|
||||
#
|
90
Tools/DemRaw2ascii/main.c
Normal file
90
Tools/DemRaw2ascii/main.c
Normal file
|
@ -0,0 +1,90 @@
|
|||
/* main.c -- main loop
|
||||
*
|
||||
* Written by Curtis Olson, started February 1998.
|
||||
*
|
||||
* Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id$
|
||||
* (Log is kept at end of this file)
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "rawdem.h"
|
||||
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
fgRAWDEM raw;
|
||||
char basename[256], output_dir[256], hdr_file[256], dem_file[256];
|
||||
int i, start_lat, end_lat;
|
||||
|
||||
if ( argc != 3 ) {
|
||||
printf("Usage: %s <input_file_basename> <output_dir>\n", argv[0]);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/* get basename */
|
||||
strcpy(basename, argv[1]);
|
||||
|
||||
/* get output dir */
|
||||
strcpy(output_dir, argv[2]);
|
||||
|
||||
/* generate header file name */
|
||||
strcpy(hdr_file, basename);
|
||||
strcat(hdr_file, ".HDR");
|
||||
|
||||
/* generate input file name (raw dem) */
|
||||
strcpy(dem_file, basename);
|
||||
strcat(dem_file, ".DEM");
|
||||
|
||||
printf("Header file = %s Input file = %s\n", hdr_file, dem_file);
|
||||
printf("Output Directory = %s\n", output_dir);
|
||||
|
||||
/* scan the header file and extract important values */
|
||||
rawReadDemHdr(&raw, hdr_file);
|
||||
|
||||
/* open up the raw data file */
|
||||
rawOpenDemFile(&raw, dem_file);
|
||||
|
||||
end_lat = raw.rooty / 3600;
|
||||
start_lat = end_lat - ((raw.nrows * raw.ydim) / 3600);
|
||||
printf("Latitude ranges from %d to %d\n", start_lat, end_lat);
|
||||
|
||||
for ( i = start_lat + 1; i <= end_lat; i++ ) {
|
||||
rawProcessStrip(&raw, i, output_dir);
|
||||
}
|
||||
|
||||
/* close the raw data file */
|
||||
rawCloseDemFile(&raw);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/* $Log$
|
||||
/* Revision 1.3 1998/03/03 21:54:50 curt
|
||||
/* Changes to process 30 arcsec binary DEM files.
|
||||
/*
|
||||
* Revision 1.2 1998/03/03 13:10:28 curt
|
||||
* Close to a working version.
|
||||
*
|
||||
* Revision 1.1 1998/03/02 23:31:01 curt
|
||||
* Initial revision.
|
||||
*
|
||||
*/
|
485
Tools/DemRaw2ascii/rawdem.c
Normal file
485
Tools/DemRaw2ascii/rawdem.c
Normal file
|
@ -0,0 +1,485 @@
|
|||
/* rawdem.c -- library of routines for processing raw dem files (30 arcsec)
|
||||
*
|
||||
* Written by Curtis Olson, started February 1998.
|
||||
*
|
||||
* Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id$
|
||||
* (Log is kept at end of this file)
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <math.h> /* rint() */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> /* atoi() atof() */
|
||||
#include <string.h> /* swab() */
|
||||
|
||||
#include <sys/types.h> /* open() */
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h> /* close() */
|
||||
|
||||
#include "rawdem.h"
|
||||
|
||||
|
||||
/* Read the DEM header to determine various key parameters for this
|
||||
* DEM file */
|
||||
void rawReadDemHdr( fgRAWDEM *raw, char *hdr_file ) {
|
||||
FILE *hdr;
|
||||
char line[256], key[256], value[256];
|
||||
int i, len, offset;
|
||||
double tmp;
|
||||
|
||||
if ( (hdr = fopen(hdr_file, "r")) == NULL ) {
|
||||
printf("Error opening DEM header file: %s\n", hdr_file);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/* process each line */
|
||||
while ( (fgets(line, 256, hdr) != NULL) ) {
|
||||
/* printf("%s", line); */
|
||||
len = strlen(line);
|
||||
|
||||
/* extract key */
|
||||
i = 0;
|
||||
while ( (line[i] != ' ') && (i < len) ) {
|
||||
key[i] = line[i];
|
||||
i++;
|
||||
}
|
||||
key[i] = '\0';
|
||||
|
||||
/* skip middle space */
|
||||
while ( (line[i] == ' ') && (i < len) ) {
|
||||
i++;
|
||||
}
|
||||
offset = i;
|
||||
|
||||
/* extract value */
|
||||
while ( (line[i] != '\n') && (i < len) ) {
|
||||
value[i-offset] = line[i];
|
||||
i++;
|
||||
}
|
||||
value[i-offset] = '\0';
|
||||
/* printf("key='%s' value='%s'\n", key, value); */
|
||||
|
||||
if ( strcmp(key, "NROWS") == 0 ) {
|
||||
raw->nrows = atoi(value);
|
||||
} else if ( strcmp(key, "NCOLS") == 0 ) {
|
||||
raw->ncols = atoi(value);
|
||||
} else if ( strcmp(key, "ULXMAP") == 0 ) {
|
||||
tmp = atof(value);
|
||||
#ifdef HAVE_RINT
|
||||
raw->ulxmap = (int)rint(tmp * 3600.0); /* convert to arcsec */
|
||||
#else
|
||||
# error Port me rint()
|
||||
#endif
|
||||
} else if ( strcmp(key, "ULYMAP") == 0 ) {
|
||||
tmp = atof(value);
|
||||
#ifdef HAVE_RINT
|
||||
raw->ulymap = (int)rint(tmp * 3600.0); /* convert to arcsec */
|
||||
#else
|
||||
# error Port me rint()
|
||||
#endif
|
||||
} else if ( strcmp(key, "XDIM") == 0 ) {
|
||||
tmp = atof(value);
|
||||
#ifdef HAVE_RINT
|
||||
raw->xdim = (int)rint(tmp * 3600.0); /* convert to arcsec */
|
||||
#else
|
||||
# error Port me rint()
|
||||
#endif
|
||||
} else if ( strcmp(key, "YDIM") == 0 ) {
|
||||
tmp = atof(value);
|
||||
#ifdef HAVE_RINT
|
||||
raw->ydim = (int)rint(tmp * 3600.0); /* convert to arcsec */
|
||||
#else
|
||||
# error Port me rint()
|
||||
#endif
|
||||
} else {
|
||||
/* ignore for now */
|
||||
}
|
||||
}
|
||||
|
||||
raw->rootx = raw->ulxmap - (raw->xdim / 2);
|
||||
raw->rooty = raw->ulymap + (raw->ydim / 2);
|
||||
|
||||
printf("%d %d %d %d %d %d %d %d\n", raw->nrows, raw->ncols,
|
||||
raw->ulxmap, raw->ulymap, raw->rootx, raw->rooty, raw->xdim,
|
||||
raw->ydim);
|
||||
}
|
||||
|
||||
|
||||
/* Open a raw DEM file. */
|
||||
void rawOpenDemFile( fgRAWDEM *raw, char *raw_dem_file ) {
|
||||
printf("Opening Raw DEM file: %s\n", raw_dem_file);
|
||||
if ( (raw->fd = open(raw_dem_file ,O_RDONLY)) == -1 ) {
|
||||
printf("Error opening Raw DEM file: %s\n", raw_dem_file);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Close a raw DEM file. */
|
||||
void rawCloseDemFile( fgRAWDEM *raw ) {
|
||||
close(raw->fd);
|
||||
}
|
||||
|
||||
|
||||
/* Advance file pointer position to correct latitude (row) */
|
||||
void rawAdvancePosition( fgRAWDEM *raw, int arcsec ) {
|
||||
long offset, result;
|
||||
|
||||
offset = 2 * raw->ncols * ( arcsec / raw->ydim );
|
||||
|
||||
if ( (result = lseek(raw->fd, offset, SEEK_SET)) == -1 ) {
|
||||
printf("Error lseek filed trying to offset by %ld\n", offset);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
printf("Successful seek ahead of %ld bytes\n", result);
|
||||
}
|
||||
|
||||
|
||||
/* Read the next row of data */
|
||||
void rawReadNextRow( fgRAWDEM *raw, int index ) {
|
||||
char buf[MAX_COLS_X_2];
|
||||
int i, result;
|
||||
|
||||
if ( raw->ncols > MAX_ROWS ) {
|
||||
printf("Error, buf needs to be bigger in rawReadNextRow()\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/* printf("Attempting to read %d bytes\n", 2 * raw->ncols); */
|
||||
result = read(raw->fd, buf, 2 * raw->ncols);
|
||||
/* printf("Read %d bytes\n", result); */
|
||||
|
||||
/* reverse byte order */
|
||||
/* it would be nice to test in advance some how if we need to do
|
||||
* this */
|
||||
/* swab(frombuf, tobuf, 2 * raw->ncols); */
|
||||
|
||||
for ( i = 0; i < raw->ncols; i++ ) {
|
||||
/* printf("hi = %d lo = %d\n", buf[2*i], buf[2*i + 1]); */
|
||||
raw->strip[index][i] = ( (buf[2*i] + 1) << 8 ) + buf[2*i + 1];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Convert from pixel centered values to pixel corner values. This is
|
||||
accomplished by taking the average of the closes center nodes. In
|
||||
the following diagram "x" marks the data point location:
|
||||
|
||||
+-----+ x-----x
|
||||
| | | |
|
||||
| x | ===> | |
|
||||
| | | |
|
||||
+-----+ x-----x
|
||||
|
||||
*/
|
||||
void rawConvertCenter2Edge( fgRAWDEM *raw ) {
|
||||
int i, j;
|
||||
|
||||
/* derive corner nodes */
|
||||
raw->edge[0][0] = raw->center[0][0];
|
||||
raw->edge[120][0] = raw->center[119][0];
|
||||
raw->edge[120][120] = raw->center[119][119];
|
||||
raw->edge[0][120] = raw->center[0][119];
|
||||
|
||||
/* derive edge nodes */
|
||||
for ( i = 1; i < 120; i++ ) {
|
||||
raw->edge[i][0] = (raw->center[i-1][0] + raw->center[i][0]) / 2.0;
|
||||
raw->edge[i][120] = (raw->center[i-1][119] + raw->center[i][119]) / 2.0;
|
||||
raw->edge[0][i] = (raw->center[0][i-1] + raw->center[0][i]) / 2.0;
|
||||
raw->edge[120][i] = (raw->center[119][i-1] + raw->center[119][i]) / 2.0;
|
||||
}
|
||||
|
||||
/* derive internal nodes */
|
||||
for ( j = 1; j < 120; j++ ) {
|
||||
for ( i = 1; i < 120; i++ ) {
|
||||
raw->edge[i][j] = ( raw->center[i-1][j-1] +
|
||||
raw->center[i] [j-1] +
|
||||
raw->center[i] [j] +
|
||||
raw->center[i-1][j] ) / 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Dump out the ascii format DEM file */
|
||||
void rawDumpAsciiDEM( fgRAWDEM *raw, char *path, int ilon, int ilat ) {
|
||||
char outfile[256];
|
||||
char tmp[256];
|
||||
int lon, lat;
|
||||
char lon_sign, lat_sign;
|
||||
int i, j;
|
||||
FILE *fd;
|
||||
|
||||
/* Generate output file name */
|
||||
|
||||
if ( ilon >= 0 ) {
|
||||
lon = ilon;
|
||||
lon_sign = 'e';
|
||||
} else {
|
||||
lon = -ilon;
|
||||
lon_sign = 'w';
|
||||
}
|
||||
|
||||
if ( ilat >= 0 ) {
|
||||
lat = ilat;
|
||||
lat_sign = 'n';
|
||||
} else {
|
||||
lat = -ilat;
|
||||
lat_sign = 's';
|
||||
}
|
||||
|
||||
sprintf(outfile, "%s/%c%03d%c%03d.dem", path, lon_sign, lon, lat_sign, lat);
|
||||
|
||||
printf("outfile = %s\n", outfile);
|
||||
|
||||
if ( (fd = fopen(outfile, "w")) == NULL ) {
|
||||
printf("Error opening output file = %s\n", outfile);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/* Dump the "A" record */
|
||||
|
||||
/* print descriptive header (144 characters) */
|
||||
sprintf(tmp, "%s - Generated from a 30 arcsec binary DEM", outfile);
|
||||
fprintf(fd, "%-144s", tmp);
|
||||
|
||||
/* DEM level code, 3 reflects processing by DMA */
|
||||
fprintf(fd, "%6d", 1);
|
||||
|
||||
/* Pattern code, 1 indicates a regular elevation pattern */
|
||||
fprintf(fd, "%6d", 1);
|
||||
|
||||
/* Planimetric reference system code, 0 indicates geographic
|
||||
* coordinate system. */
|
||||
fprintf(fd, "%6d", 0);
|
||||
|
||||
/* Zone code */
|
||||
fprintf(fd, "%6d", 0);
|
||||
|
||||
/* Map projection parameters (ignored) */
|
||||
for ( i = 0; i < 15; i++ ) {
|
||||
fprintf(fd, "%6.1f%18s", 0.0, "");
|
||||
}
|
||||
|
||||
/* Units code, 3 represents arc-seconds as the unit of measure for
|
||||
* ground planimetric coordinates throughout the file. */
|
||||
fprintf(fd, "%6d", 3);
|
||||
|
||||
/* Units code; 2 represents meters as the unit of measure for
|
||||
* elevation coordinates throughout the file. */
|
||||
fprintf(fd, "%6d", 2);
|
||||
|
||||
/* Number (n) of sides in the polygon which defines the coverage of
|
||||
* the DEM file (usually equal to 4). */
|
||||
fprintf(fd, "%6d", 4);
|
||||
|
||||
/* Ground coordinates of bounding box in arc-seconds */
|
||||
fprintf(fd, "%20.15fD+06", ilon * 3600.0 / 1000000.0);
|
||||
fprintf(fd, "%20.15fD+06", ilat * 3600.0 / 1000000.0);
|
||||
|
||||
fprintf(fd, "%20.15fD+06", ilon * 3600.0 / 1000000.0);
|
||||
fprintf(fd, "%20.15fD+06", (ilat+1) * 3600.0 / 1000000.0);
|
||||
|
||||
fprintf(fd, "%20.15fD+06", (ilon+1) * 3600.0 / 1000000.0);
|
||||
fprintf(fd, "%20.15fD+06", (ilat+1) * 3600.0 / 1000000.0);
|
||||
|
||||
fprintf(fd, "%20.15fD+06", (ilon+1) * 3600.0 / 1000000.0);
|
||||
fprintf(fd, "%20.15fD+06", (ilat) * 3600.0 / 1000000.0);
|
||||
|
||||
/* Minimum/maximum elevations in meters */
|
||||
fprintf(fd, " %20.15E", (double)raw->tmp_min);
|
||||
fprintf(fd, " %20.15E", (double)raw->tmp_max);
|
||||
|
||||
/* Counterclockwise angle from the primary axis of ground
|
||||
* planimetric referenced to the primary axis of the DEM local
|
||||
* reference system. */
|
||||
fprintf(fd, "%6.1f", 0.0);
|
||||
|
||||
/* Accuracy code; 0 indicates that a record of accuracy does not
|
||||
* exist and that no record type C will follow. */
|
||||
fprintf(fd, "%24d", 0);
|
||||
|
||||
/* DEM spacial resolution. Usually (3,3) (3,6) or (3,9)
|
||||
* depending on latitude */
|
||||
fprintf(fd, "%12.6E", 30.0);
|
||||
fprintf(fd, "%12.6E", 30.0);
|
||||
|
||||
/* accuracy code */
|
||||
fprintf(fd, "%12.6E", 1.0);
|
||||
|
||||
/* dimension of arrays to follow (1)*/
|
||||
fprintf(fd, "%6d", 1);
|
||||
|
||||
/* number of profiles */
|
||||
fprintf(fd, "%6d", 3600 / raw->ydim + 1);
|
||||
|
||||
/* pad the end */
|
||||
fprintf(fd, "%160s", "");
|
||||
|
||||
|
||||
/* Dump "B" records */
|
||||
|
||||
for ( j = 0; j <= 120; j++ ) {
|
||||
/* row / column id of this profile */
|
||||
fprintf(fd, "%6d%6d", 1, j + 1);
|
||||
|
||||
/* Number of rows and columns (elevation points) in this
|
||||
profile */
|
||||
fprintf(fd, "%6d%6d", 3600 / raw->xdim + 1, 1);
|
||||
|
||||
/* Ground planimetric coordinates (arc-seconds) of the first
|
||||
* elevation in the profile */
|
||||
fprintf(fd, "%20.15fD+06", ilon * 3600.0 / 1000000.0);
|
||||
fprintf(fd, "%20.15fD+06", (ilat * 3600.0 + j * raw->ydim) / 1000000.0);
|
||||
|
||||
/* Elevation of local datum for the profile. Always zero for
|
||||
* 1-degree DEM, the reference is mean sea level. */
|
||||
fprintf(fd, "%6.1f", 0.0);
|
||||
fprintf(fd, "%18s", "");
|
||||
|
||||
/* Minimum and maximum elevations for the profile. */
|
||||
fprintf(fd, " %20.15E", 0.0);
|
||||
fprintf(fd, " %20.15E", 0.0);
|
||||
|
||||
/* One (usually) dimensional array (1,prof_num_cols) of
|
||||
elevations */
|
||||
for ( i = 0; i <= 120; i++ ) {
|
||||
fprintf(fd, "%6.0f", raw->edge[j][i]);
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(fd, "\n");
|
||||
|
||||
fclose(fd);
|
||||
}
|
||||
|
||||
|
||||
/* Read a horizontal strip of (1 vertical degree) from the raw DEM
|
||||
* file specified by the upper latitude of the stripe specified in
|
||||
* degrees. The output the individual ASCII format DEM tiles. */
|
||||
void rawProcessStrip( fgRAWDEM *raw, int lat_degrees, char *path ) {
|
||||
int lat, yrange;
|
||||
int i, j, index, row, col;
|
||||
int min, max;
|
||||
int span, num_degrees, tile_width;
|
||||
int xstart, xend;
|
||||
|
||||
/* convert to arcsec */
|
||||
lat = lat_degrees * 3600;
|
||||
|
||||
printf("Max Latitude = %d arcsec\n", lat);
|
||||
|
||||
/* validity check ... */
|
||||
if ( (lat > raw->rooty) ||
|
||||
(lat < (raw->rooty - raw->nrows * raw->ydim + 1)) ) {
|
||||
printf("Latitude out of range for this DEM file\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf ("Reading strip starting at %d (top and working down)\n", lat);
|
||||
|
||||
/* advance to the correct latitude */
|
||||
rawAdvancePosition(raw, (raw->rooty - lat));
|
||||
|
||||
/* printf("short = %d\n", sizeof(short)); */
|
||||
|
||||
yrange = 3600 / raw->ydim;
|
||||
|
||||
for ( i = 0; i < yrange; i++ ) {
|
||||
index = yrange - i - 1;
|
||||
/* printf("About to read into row %d\n", index); */
|
||||
rawReadNextRow(raw, index);
|
||||
|
||||
for ( j = 0; j < raw->ncols; j++ ) {
|
||||
if ( raw->strip[index][j] == -9999 ) {
|
||||
/* map ocean to 0 for now */
|
||||
raw->strip[index][j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* extract individual tiles from the strip */
|
||||
span = raw->ncols * raw->xdim;
|
||||
num_degrees = span / 3600;
|
||||
tile_width = raw->ncols / num_degrees;
|
||||
printf("span = %d num_degrees = %d width = %d\n",
|
||||
span, num_degrees, tile_width);
|
||||
|
||||
for ( i = 0; i < num_degrees; i++ ) {
|
||||
xstart = i * tile_width;
|
||||
xend = xstart + 120;
|
||||
|
||||
min = 10000; max = -10000;
|
||||
for ( row = 0; row < yrange; row++ ) {
|
||||
for ( col = xstart; col < xend; col++ ) {
|
||||
/* Copy from strip to pixel centered tile. Yep,
|
||||
* row/col are reversed here. raw->strip is backwards
|
||||
* for convenience. I am converting to [x,y] now. */
|
||||
raw->center[col-xstart][row] = raw->strip[row][col];
|
||||
|
||||
if ( raw->strip[row][col] < min) {
|
||||
min = raw->strip[row][col];
|
||||
}
|
||||
|
||||
if ( raw->strip[row][col] > max) {
|
||||
max = raw->strip[row][col];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
raw->tmp_min = min;
|
||||
raw->tmp_max = max;
|
||||
|
||||
/* Convert from pixel centered to pixel edge values */
|
||||
rawConvertCenter2Edge(raw);
|
||||
|
||||
/* Dump out the ascii format DEM file */
|
||||
rawDumpAsciiDEM(raw, path, (raw->rootx / 3600) + i, lat_degrees - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* $Log$
|
||||
/* Revision 1.6 1998/04/27 03:32:03 curt
|
||||
/* Wrapped rint()'s in #ifdef HAVE_RINT
|
||||
/*
|
||||
* Revision 1.5 1998/04/18 03:59:46 curt
|
||||
* Incorporated into gnu automake/autoconf system.
|
||||
*
|
||||
* Revision 1.4 1998/04/06 21:09:43 curt
|
||||
* Additional win32 support.
|
||||
* Fixed a bad bug in dem file parsing that was causing the output to be
|
||||
* flipped about x = y.
|
||||
*
|
||||
* Revision 1.3 1998/03/03 13:10:29 curt
|
||||
* Close to a working version.
|
||||
*
|
||||
* Revision 1.2 1998/03/03 02:04:01 curt
|
||||
* Starting DEM Ascii format output routine.
|
||||
*
|
||||
* Revision 1.1 1998/03/02 23:31:01 curt
|
||||
* Initial revision.
|
||||
*
|
||||
*/
|
85
Tools/DemRaw2ascii/rawdem.h
Normal file
85
Tools/DemRaw2ascii/rawdem.h
Normal file
|
@ -0,0 +1,85 @@
|
|||
/* rawdem.h -- library of routines for processing raw dem files (30 arcsec)
|
||||
*
|
||||
* Written by Curtis Olson, started February 1998.
|
||||
*
|
||||
* Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id$
|
||||
* (Log is kept at end of this file)
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _RAWDEM_H
|
||||
#define _RAWDEM_H
|
||||
|
||||
|
||||
#define MAX_ROWS 6000
|
||||
#define MAX_COLS 7200
|
||||
#define MAX_COLS_X_2 14400
|
||||
|
||||
typedef struct {
|
||||
/* header info */
|
||||
int nrows; /* number of rows */
|
||||
int ncols; /* number of cols */
|
||||
int ulxmap; /* X coord of center of upper left pixel in arcsec */
|
||||
int ulymap; /* Y coord of center of upper left pixel in arcsec */
|
||||
int rootx; /* X coord of upper left *edge* of DEM region in degrees */
|
||||
int rooty; /* Y coord of upper left *edge* of DEM region in degrees */
|
||||
int xdim; /* X dimension of a pixel */
|
||||
int ydim; /* Y dimension of a pixel */
|
||||
int tmp_min; /* current 1x1 degree tile minimum */
|
||||
int tmp_max; /* current 1x1 degree tile maximum */
|
||||
|
||||
/* file ptr */
|
||||
int fd; /* Raw DEM file descriptor */
|
||||
|
||||
/* storage area for a 1 degree high strip of data. Note, for
|
||||
* convenience this is in y,x order */
|
||||
short strip[120][MAX_ROWS];
|
||||
|
||||
short center[120][120]; /* tile with data taken at center of pixel */
|
||||
float edge[121][121]; /* tile with data converted to corners */
|
||||
} fgRAWDEM;
|
||||
|
||||
|
||||
/* Read the DEM header to determine various key parameters for this
|
||||
* DEM file */
|
||||
void rawReadDemHdr( fgRAWDEM *raw, char *hdr_file );
|
||||
|
||||
/* Open a raw DEM file. */
|
||||
void rawOpenDemFile( fgRAWDEM *raw, char *raw_dem_file );
|
||||
|
||||
/* Close a raw DEM file. */
|
||||
void rawCloseDemFile( fgRAWDEM *raw );
|
||||
|
||||
/* Read a horizontal strip of (1 vertical degree) from the raw DEM
|
||||
* file specified by the upper latitude of the stripe specified in
|
||||
* degrees. The output the individual ASCII format DEM tiles. */
|
||||
void rawProcessStrip( fgRAWDEM *raw, int lat_degrees, char *path );
|
||||
|
||||
|
||||
#endif /* _RAWDEM_H */
|
||||
|
||||
|
||||
/* $Log$
|
||||
/* Revision 1.2 1998/03/03 13:10:30 curt
|
||||
/* Close to a working version.
|
||||
/*
|
||||
* Revision 1.1 1998/03/02 23:31:02 curt
|
||||
* Initial revision.
|
||||
*
|
||||
*/
|
95
Tools/FixNode/Makefile.am
Normal file
95
Tools/FixNode/Makefile.am
Normal file
|
@ -0,0 +1,95 @@
|
|||
#---------------------------------------------------------------------------
|
||||
# Makefile
|
||||
#
|
||||
# Written by Curtis Olson, started October 1997.
|
||||
#
|
||||
# Copyright (C) 1997 - 1998 Curtis L. Olson - curt@me.umn.edu
|
||||
#
|
||||
# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
# $Id$
|
||||
# (Log is kept at end of this file)
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
|
||||
bin_PROGRAMS = fixnode
|
||||
|
||||
fixnode_SOURCES = \
|
||||
fixnode.cxx fixnode.hxx \
|
||||
main.cxx
|
||||
|
||||
fixnode_LDADD = \
|
||||
$(top_builddir)/Tools/Lib/DEM/libDEM.a \
|
||||
$(top_builddir)/Lib/Bucket/libBucket.a \
|
||||
$(top_builddir)/Lib/Misc/libMisc.a \
|
||||
$(top_builddir)/Lib/zlib/libz.a \
|
||||
$(base_LIBS)
|
||||
|
||||
INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib -I$(top_builddir)/Tools/Lib
|
||||
|
||||
# We can't build this with "-O2" (optimization) since this causes a seg fault
|
||||
# I haven't found a way to strip this out of the CXXFLAGS, so I'm just
|
||||
# setting it to "-g"
|
||||
# CXXFLAGS = -g
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# $Log$
|
||||
# Revision 1.10 1999/03/17 23:50:59 curt
|
||||
# Removed forced -g compiler flag.
|
||||
#
|
||||
# Revision 1.9 1999/03/08 22:00:45 curt
|
||||
# Lots of directory layout reorganization.
|
||||
#
|
||||
# Revision 1.8 1999/02/01 21:09:30 curt
|
||||
# Moving location of Lib/DEM/ to Tools/DEM/
|
||||
#
|
||||
# Revision 1.7 1998/11/04 23:01:51 curt
|
||||
# Changes to the automake/autoconf system to reduce the number of libraries
|
||||
# that are unnecessarily linked into the various executables.
|
||||
#
|
||||
# Revision 1.6 1998/09/19 20:43:50 curt
|
||||
# C++-ified and STL-ified the code. Combined triload.* and fixnode.* into
|
||||
# a single file.
|
||||
#
|
||||
# Revision 1.5 1998/09/19 18:01:26 curt
|
||||
# Support for changes to libDEM.a
|
||||
#
|
||||
# Revision 1.4 1998/07/30 23:49:24 curt
|
||||
# Removed libtool support.
|
||||
#
|
||||
# Revision 1.3 1998/04/18 04:02:54 curt
|
||||
# Added zlib support in placed and other misc. tweaks.
|
||||
#
|
||||
# Revision 1.2 1998/04/14 02:26:02 curt
|
||||
# Code reorganizations. Added a Lib/ directory for more general libraries.
|
||||
#
|
||||
# Revision 1.1 1998/04/08 23:05:54 curt
|
||||
# Adopted Gnu automake/autoconf system.
|
||||
#
|
||||
# Revision 1.4 1998/04/06 21:09:44 curt
|
||||
# Additional win32 support.
|
||||
# Fixed a bad bug in dem file parsing that was causing the output to be
|
||||
# flipped about x = y.
|
||||
#
|
||||
# Revision 1.3 1998/03/19 02:50:19 curt
|
||||
# Updated to support -lDEM class.
|
||||
#
|
||||
# Revision 1.2 1998/01/21 02:55:50 curt
|
||||
# Incorporated new make system from Bob Kuehne <rpk@sgi.com>.
|
||||
#
|
||||
# Revision 1.1 1997/11/27 00:17:32 curt
|
||||
# Initial revision.
|
||||
#
|
161
Tools/FixNode/fixnode.cxx
Normal file
161
Tools/FixNode/fixnode.cxx
Normal file
|
@ -0,0 +1,161 @@
|
|||
// fixnode.cxx -- traverse the node file and fix the elevation of all the new
|
||||
// interpolated points.
|
||||
//
|
||||
// Written by Curtis Olson, started November 1997.
|
||||
//
|
||||
// Copyright (C) 1997 Curtis L. Olson - curt@me.umn.edu
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
# include <stdlib.h>
|
||||
#endif // HAVE_STDLIB_H
|
||||
|
||||
#include <Misc/fgstream.hxx>
|
||||
|
||||
#include "fixnode.hxx"
|
||||
|
||||
|
||||
// load extra nodes
|
||||
void load_extra(const string& filename, container& extra_list) {
|
||||
}
|
||||
|
||||
|
||||
// load the node information
|
||||
void load_nodes(const string& filename, container& node_list) {
|
||||
Point3D node;
|
||||
int dim, junk1, junk2;
|
||||
int i, nodecount;
|
||||
|
||||
cout << "Loading node file: " << filename << " ...\n";
|
||||
|
||||
fg_gzifstream in( filename );
|
||||
if ( !in ) {
|
||||
cout << "Cannot open " + filename + "\n";
|
||||
// exit immediately assuming an airport file for this tile
|
||||
// doesn't exist.
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// Read header line
|
||||
in >> nodecount >> dim >> junk1 >> junk2;
|
||||
cout << " Expecting " << nodecount << " nodes\n";
|
||||
|
||||
// start with an empty list :-)
|
||||
node_list.erase( node_list.begin(), node_list.end() );
|
||||
|
||||
in >> skipcomment;
|
||||
while ( ! in.eof() ) {
|
||||
in >> junk1 >> node >> junk2;
|
||||
in >> skipcomment;
|
||||
node_list.push_back(node);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// fix the node elevations
|
||||
void fix_nodes( const string& filename, fgDEM& dem, container& node_list )
|
||||
{
|
||||
string toname;
|
||||
FILE *fd;
|
||||
int i;
|
||||
|
||||
cout << "Fixing up node elevations\n";
|
||||
|
||||
iterator current;
|
||||
iterator last = node_list.end();
|
||||
for ( current = node_list.begin() ; current != last ; ++current ) {
|
||||
// printf("Current: %d %.2f %.2f %.2f\n", i, nodes[i][0],
|
||||
// nodes[i][1], nodes[i][2]);
|
||||
|
||||
(*current).setz(
|
||||
dem.interpolate_altitude( (*current).x(),
|
||||
(*current).y() ) );
|
||||
|
||||
// printf("Fixed: %d %.2f %.2f %.2f\n", i, nodes[i][0],
|
||||
// nodes[i][1], nodes[i][2]);
|
||||
}
|
||||
|
||||
|
||||
toname = filename + ".orig";
|
||||
cout << "Moving " + filename + " to " + toname + "\n";
|
||||
rename( filename.c_str(), toname.c_str() );
|
||||
|
||||
cout << "Saving new node file: " + filename + "\n";
|
||||
|
||||
fd = fopen(filename.c_str(), "w");
|
||||
|
||||
fprintf( fd, "%d 2 1 0\n", node_list.size() );
|
||||
|
||||
i = 1;
|
||||
for ( current = node_list.begin() ; current != last ; ++current ) {
|
||||
fprintf( fd, "%d %.2f %.2f %.2f 0\n", i,
|
||||
(*current).x(), (*current).y(), (*current).z() );
|
||||
++i;
|
||||
}
|
||||
|
||||
fclose(fd);
|
||||
}
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.7 1998/11/06 21:33:55 curt
|
||||
// Updates to go along with changes in fgstream.
|
||||
//
|
||||
// Revision 1.6 1998/10/20 15:49:22 curt
|
||||
// Converted to Point3D class.
|
||||
//
|
||||
// Revision 1.5 1998/09/22 23:49:10 curt
|
||||
// eliminated a left over #include
|
||||
//
|
||||
// Revision 1.4 1998/09/19 20:43:52 curt
|
||||
// C++-ified and STL-ified the code. Combined triload.* and fixnode.* into
|
||||
// a single file.
|
||||
//
|
||||
// Revision 1.3 1998/07/22 21:46:40 curt
|
||||
// Fixed a bug that was triggering a seg fault.
|
||||
//
|
||||
// Revision 1.2 1998/04/14 02:26:03 curt
|
||||
// Code reorganizations. Added a Lib/ directory for more general libraries.
|
||||
//
|
||||
// Revision 1.1 1998/04/08 23:05:56 curt
|
||||
// Adopted Gnu automake/autoconf system.
|
||||
//
|
||||
// Revision 1.5 1998/03/19 02:50:19 curt
|
||||
// Updated to support -lDEM class.
|
||||
//
|
||||
// Revision 1.4 1998/03/03 16:00:57 curt
|
||||
// More c++ compile tweaks.
|
||||
//
|
||||
// Revision 1.3 1998/01/09 23:03:08 curt
|
||||
// Restructured to split 1deg x 1deg dem's into 64 subsections.
|
||||
//
|
||||
// Revision 1.2 1997/12/02 13:12:07 curt
|
||||
// Updated to fix every node.
|
||||
//
|
||||
// Revision 1.1 1997/11/27 00:17:33 curt
|
||||
// Initial revision.
|
||||
//
|
||||
|
95
Tools/FixNode/fixnode.hxx
Normal file
95
Tools/FixNode/fixnode.hxx
Normal file
|
@ -0,0 +1,95 @@
|
|||
// fixnode.hxx -- traverse the node file and fix the elevation of all the new
|
||||
// interpolated points.
|
||||
//
|
||||
// Written by Curtis Olson, started November 1997.
|
||||
//
|
||||
// Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
//
|
||||
|
||||
|
||||
#ifndef _FIXNODE_H
|
||||
#define _FIXNODE_H
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
|
||||
#include <vector>
|
||||
#include "Include/fg_stl_config.h"
|
||||
|
||||
#ifdef NEEDNAMESPACESTD
|
||||
using namespace std;
|
||||
#endif
|
||||
|
||||
#include <DEM/dem.hxx>
|
||||
#include <Math/point3d.hxx>
|
||||
|
||||
|
||||
typedef vector < Point3D > container;
|
||||
typedef container::iterator iterator;
|
||||
typedef container::const_iterator const_iterator;
|
||||
|
||||
|
||||
// Initialize a new mesh structure
|
||||
void load_nodes(const string& basename, container& node_list);
|
||||
|
||||
|
||||
// load the extra nodes. These are always the first n nodes of the
|
||||
// .node file. (??? These will be tagged with a code indicating what
|
||||
// needs to be done with this node's elevation such as adjust to local
|
||||
// DEM elevation, or massage the local DEM points to match this
|
||||
// elevation point. ???)
|
||||
void load_extra_nodes(const string& filename, container& node_list);
|
||||
|
||||
|
||||
// fix the node elevations
|
||||
void fix_nodes( const string& basename, fgDEM& dem, container& node_list );
|
||||
|
||||
|
||||
#endif // _FIXNODE_H
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.4 1998/10/20 15:49:23 curt
|
||||
// Converted to Point3D class.
|
||||
//
|
||||
// Revision 1.3 1998/09/19 20:43:53 curt
|
||||
// C++-ified and STL-ified the code. Combined triload.* and fixnode.* into
|
||||
// a single file.
|
||||
//
|
||||
// Revision 1.2 1998/07/22 21:46:41 curt
|
||||
// Fixed a bug that was triggering a seg fault.
|
||||
//
|
||||
// Revision 1.1 1998/04/08 23:05:56 curt
|
||||
// Adopted Gnu automake/autoconf system.
|
||||
//
|
||||
// Revision 1.4 1998/03/19 02:50:19 curt
|
||||
// Updated to support -lDEM class.
|
||||
//
|
||||
// Revision 1.3 1998/03/03 16:00:58 curt
|
||||
// More c++ compile tweaks.
|
||||
//
|
||||
// Revision 1.2 1997/12/02 13:12:07 curt
|
||||
// Updated to fix every node.
|
||||
//
|
||||
// Revision 1.1 1997/11/27 00:17:33 curt
|
||||
// Initial revision.
|
||||
//
|
146
Tools/FixNode/main.cxx
Normal file
146
Tools/FixNode/main.cxx
Normal file
|
@ -0,0 +1,146 @@
|
|||
// main.cxx -- read in a .node file and fix the z values of the interpolated
|
||||
// points
|
||||
//
|
||||
// Written by Curtis Olson, started November 1997.
|
||||
//
|
||||
// Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
//
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
// #include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
# include <stdlib.h>
|
||||
#endif // HAVE_STDLIB_H
|
||||
|
||||
#include <DEM/dem.hxx>
|
||||
|
||||
#include "fixnode.hxx"
|
||||
|
||||
|
||||
// find all the matching files in the specified directory and fix them
|
||||
void process_files(const string& root_path, fgDEM& dem) {
|
||||
container node_list;
|
||||
DIR *d;
|
||||
struct dirent *de;
|
||||
string file_path;
|
||||
char *ptr;
|
||||
int len;
|
||||
|
||||
if ( (d = opendir( root_path.c_str() )) == NULL ) {
|
||||
cout << "cannot open directory " + root_path + "\n";
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
while ( (de = readdir(d)) != NULL ) {
|
||||
len = strlen(de->d_name);
|
||||
if ( len > 7 ) {
|
||||
ptr = de->d_name;
|
||||
ptr += (len - 7);
|
||||
// printf("--> %s \n", ptr);
|
||||
|
||||
if ( strcmp(ptr, ".1.node") == 0 ) {
|
||||
file_path = root_path + "/" + de->d_name;
|
||||
cout << "File = " + file_path + "\n";
|
||||
|
||||
// load the input data files
|
||||
load_nodes(file_path, node_list);
|
||||
|
||||
fix_nodes(file_path, dem, node_list);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// main
|
||||
int main(int argc, char **argv) {
|
||||
fgDEM dem;
|
||||
string demfile, root_path;
|
||||
|
||||
if ( argc != 3 ) {
|
||||
cout << "Usage " << argv[0] << " demfile root_path\n";
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
cout << "Starting fixnode\n";
|
||||
|
||||
demfile = argv[1];
|
||||
root_path = argv[2];
|
||||
|
||||
// load the corresponding dem file so we can interpolate elev values
|
||||
dem.open(demfile);
|
||||
dem.parse();
|
||||
dem.close();
|
||||
|
||||
// process all the *.1.node files in the specified directory
|
||||
process_files(root_path, dem);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.7 1998/09/19 20:43:54 curt
|
||||
// C++-ified and STL-ified the code. Combined triload.* and fixnode.* into
|
||||
// a single file.
|
||||
//
|
||||
// Revision 1.6 1998/09/19 18:01:27 curt
|
||||
// Support for changes to libDEM.a
|
||||
//
|
||||
// Revision 1.5 1998/07/22 21:46:41 curt
|
||||
// Fixed a bug that was triggering a seg fault.
|
||||
//
|
||||
// Revision 1.4 1998/06/27 16:55:24 curt
|
||||
// Changed include order for <sys/types.h>
|
||||
//
|
||||
// Revision 1.3 1998/04/26 05:02:06 curt
|
||||
// Added #ifdef HAVE_STDLIB_H
|
||||
//
|
||||
// Revision 1.2 1998/04/14 02:26:04 curt
|
||||
// Code reorganizations. Added a Lib/ directory for more general libraries.
|
||||
//
|
||||
// Revision 1.1 1998/04/08 23:05:57 curt
|
||||
// Adopted Gnu automake/autoconf system.
|
||||
//
|
||||
// Revision 1.6 1998/04/06 21:09:44 curt
|
||||
// Additional win32 support.
|
||||
// Fixed a bad bug in dem file parsing that was causing the output to be
|
||||
// flipped about x = y.
|
||||
//
|
||||
// Revision 1.5 1998/03/19 02:50:20 curt
|
||||
// Updated to support -lDEM class.
|
||||
//
|
||||
// Revision 1.4 1998/03/03 16:00:58 curt
|
||||
// More c++ compile tweaks.
|
||||
//
|
||||
// Revision 1.3 1998/01/09 23:03:08 curt
|
||||
// Restructured to split 1deg x 1deg dem's into 64 subsections.
|
||||
//
|
||||
// Revision 1.2 1997/12/02 13:12:07 curt
|
||||
// Updated to fix every node.
|
||||
//
|
||||
// Revision 1.1 1997/11/27 00:17:34 curt
|
||||
// Initial revision.
|
||||
//
|
69
Tools/FixObj/Makefile.am
Normal file
69
Tools/FixObj/Makefile.am
Normal file
|
@ -0,0 +1,69 @@
|
|||
#---------------------------------------------------------------------------
|
||||
# Makefile
|
||||
#
|
||||
# Written by Curtis Olson, started October 1997.
|
||||
#
|
||||
# Copyright (C) 1997 - 1998 Curtis L. Olson - curt@me.umn.edu
|
||||
#
|
||||
# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
# $Id$
|
||||
# (Log is kept at end of this file)
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
|
||||
bin_PROGRAMS = fixobj
|
||||
|
||||
fixobj_SOURCES = main.cxx obj.cxx obj.hxx
|
||||
|
||||
fixobj_LDADD = \
|
||||
$(top_builddir)/Lib/Math/libMath.a \
|
||||
$(top_builddir)/Lib/Debug/libDebug.a \
|
||||
$(top_builddir)/Lib/zlib/libz.a \
|
||||
$(base_LIBS)
|
||||
|
||||
INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# $Log$
|
||||
# Revision 1.7 1998/11/04 23:01:53 curt
|
||||
# Changes to the automake/autoconf system to reduce the number of libraries
|
||||
# that are unnecessarily linked into the various executables.
|
||||
#
|
||||
# Revision 1.6 1998/07/30 23:49:25 curt
|
||||
# Removed libtool support.
|
||||
#
|
||||
# Revision 1.5 1998/06/08 17:11:44 curt
|
||||
# Renamed *.[ch] to *.[ch]xx
|
||||
#
|
||||
# Revision 1.4 1998/04/24 00:44:05 curt
|
||||
# Added zlib support.
|
||||
#
|
||||
# Revision 1.3 1998/04/18 04:01:02 curt
|
||||
# Now use libMath rather than having local copies of math routines.
|
||||
#
|
||||
# Revision 1.2 1998/04/14 02:26:05 curt
|
||||
# Code reorganizations. Added a Lib/ directory for more general libraries.
|
||||
#
|
||||
# Revision 1.1 1998/04/08 23:19:35 curt
|
||||
# Adopted Gnu automake/autoconf system.
|
||||
#
|
||||
# Revision 1.2 1998/01/21 02:55:53 curt
|
||||
# Incorporated new make system from Bob Kuehne <rpk@sgi.com>.
|
||||
#
|
||||
# Revision 1.1 1997/12/08 19:28:54 curt
|
||||
# Initial revision.
|
||||
#
|
57
Tools/FixObj/main.cxx
Normal file
57
Tools/FixObj/main.cxx
Normal file
|
@ -0,0 +1,57 @@
|
|||
// main.cxx -- read and fix the stripping order of a .obj file
|
||||
//
|
||||
// Written by Curtis Olson, started December 1997.
|
||||
//
|
||||
// Copyright (C) 1997 - 1998 Curtis L. Olson - curt@me.umn.edu
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "obj.hxx"
|
||||
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
char infile[256], outfile[256];
|
||||
|
||||
if ( argc != 3 ) {
|
||||
printf("Usage %s: infile outfile\n", argv[0]);
|
||||
}
|
||||
|
||||
strcpy(infile, argv[1]);
|
||||
strcpy(outfile, argv[2]);
|
||||
|
||||
// load the input data files
|
||||
obj_fix(infile, outfile);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.1 1998/06/08 17:11:45 curt
|
||||
// Renamed *.[ch] to *.[ch]xx
|
||||
//
|
||||
// Revision 1.2 1998/01/09 23:03:12 curt
|
||||
// Restructured to split 1deg x 1deg dem's into 64 subsections.
|
||||
//
|
||||
// Revision 1.1 1997/12/08 19:28:54 curt
|
||||
// Initial revision.
|
||||
//
|
||||
|
647
Tools/FixObj/obj.cxx
Normal file
647
Tools/FixObj/obj.cxx
Normal file
|
@ -0,0 +1,647 @@
|
|||
// obj.cxx -- routines to handle WaveFront .obj format files.
|
||||
//
|
||||
// Written by Curtis Olson, started October 1997.
|
||||
//
|
||||
// Copyright (C) 1997 - 1998 Curtis L. Olson - curt@me.umn.edu
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
#include <string.h>
|
||||
|
||||
#include <vector>
|
||||
#include "Include/compiler.h"
|
||||
|
||||
#ifdef NEEDNAMESPACESTD
|
||||
using namespace std;
|
||||
#endif
|
||||
|
||||
#include "obj.hxx"
|
||||
|
||||
#include <Math/mat3.h>
|
||||
#include <Math/point3d.hxx>
|
||||
|
||||
|
||||
typedef vector < Point3D > container3;
|
||||
typedef container3::iterator iterator3;
|
||||
typedef container3::const_iterator const_iterator3;
|
||||
|
||||
|
||||
// what do ya' know, here's some global variables
|
||||
container3 nodes;
|
||||
container3 normals;
|
||||
static int faces[MAXNODES][3];
|
||||
int vncount, fcount;
|
||||
|
||||
static int ccw_list[MAXNODES];
|
||||
int ccw_list_ptr;
|
||||
|
||||
static int cw_list[MAXNODES];
|
||||
int cw_list_ptr;
|
||||
|
||||
FILE *in, *out;
|
||||
|
||||
Point3D ref;
|
||||
|
||||
|
||||
// some simple list routines
|
||||
|
||||
// reset the list
|
||||
void list_init(int *list_ptr) {
|
||||
*list_ptr = 0;
|
||||
}
|
||||
|
||||
|
||||
// add to list
|
||||
void list_add(int *list, int *list_ptr, int node) {
|
||||
if ( *list_ptr >= MAXNODES ) {
|
||||
printf("ERROR: list overflow in list_add()\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
list[*list_ptr] = node;
|
||||
*list_ptr += 1;
|
||||
|
||||
// printf("list pointer = %d adding %d\n", *list_ptr, node);
|
||||
}
|
||||
|
||||
|
||||
// fix the cw list and append to ccw_list
|
||||
void fix_cw_list(int *list, int list_ptr) {
|
||||
int i, j, len;
|
||||
|
||||
if ( list_ptr < 3 ) {
|
||||
printf("List is empty ... skipping\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Fixing cw list, size = %d\n", list_ptr);
|
||||
|
||||
i = 0;
|
||||
while ( i < list_ptr ) {
|
||||
// do next strip
|
||||
|
||||
// find length
|
||||
len = 0;
|
||||
// scan rest of strip (until -1)
|
||||
while ( ((i+len) < list_ptr) && (list[i+len] != -1) ) {
|
||||
// printf("len = %d item = %d\n", len, list[i+len] );
|
||||
len++;
|
||||
}
|
||||
// printf(" Final length = %d\n", len);
|
||||
|
||||
if ( (len % 2) != 0 ) {
|
||||
// if length is odd, just reverse order of nodes to
|
||||
// reverse winding
|
||||
if ( ccw_list_ptr ) {
|
||||
list_add(ccw_list, &ccw_list_ptr, -1);
|
||||
}
|
||||
for ( j = i + len - 1; j >= i; j-- ) {
|
||||
// printf(" odd -> item = %d\n", list[j] );
|
||||
list_add(ccw_list, &ccw_list_ptr, list[j]);
|
||||
}
|
||||
} else {
|
||||
// if length is even, reverse order of (n-1) nodes to
|
||||
// reverse winding, and create an orphan triangle for the
|
||||
// last "nth" node
|
||||
if ( ccw_list_ptr ) {
|
||||
list_add(ccw_list, &ccw_list_ptr, -1);
|
||||
}
|
||||
for ( j = i + len - 2; j >= i; j-- ) {
|
||||
// printf(" even -> item = %d\n", list[j] );
|
||||
list_add(ccw_list, &ccw_list_ptr, list[j]);
|
||||
}
|
||||
|
||||
// printf(" even bonus -> item = %d\n", list[i + len - 1] );
|
||||
// printf(" even bonus -> item = %d\n", list[i + len - 2] );
|
||||
// printf(" even bonus -> item = %d\n", list[i + len - 3] );
|
||||
list_add(ccw_list, &ccw_list_ptr, -1);
|
||||
list_add(ccw_list, &ccw_list_ptr, list[i + len - 3]);
|
||||
list_add(ccw_list, &ccw_list_ptr, list[i + len - 2]);
|
||||
list_add(ccw_list, &ccw_list_ptr, list[i + len - 1]);
|
||||
}
|
||||
|
||||
i += len + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void dump_global_bounds( void ) {
|
||||
double dist_squared, radius, radius_squared;
|
||||
|
||||
radius = 0.0;
|
||||
|
||||
fprintf(out, "\n");
|
||||
|
||||
|
||||
iterator3 current = nodes.begin();
|
||||
iterator3 last = nodes.end();
|
||||
|
||||
// skip first dummy node
|
||||
++current;
|
||||
|
||||
for ( ; current != last; ++current ) {
|
||||
dist_squared = ref.distance3Dsquared(*current);
|
||||
// cout << "node = " << *current << " dist = " << dist_squared << endl;
|
||||
|
||||
if ( dist_squared > radius_squared ) {
|
||||
radius_squared = dist_squared;
|
||||
}
|
||||
}
|
||||
|
||||
radius = sqrt(radius_squared);
|
||||
|
||||
fprintf( out,
|
||||
"gbs %.5f %.5f %.5f %.2f\n",
|
||||
ref.x(), ref.y(), ref.z(), radius);
|
||||
}
|
||||
|
||||
|
||||
// dump nodes
|
||||
void dump_nodes( void ) {
|
||||
Point3D p;
|
||||
|
||||
fprintf(out, "\n");
|
||||
|
||||
iterator3 current = nodes.begin();
|
||||
iterator3 last = nodes.end();
|
||||
|
||||
// skip first dummy node
|
||||
++current;
|
||||
|
||||
for ( ; current != last; ++current ) {
|
||||
p = *current - ref;
|
||||
fprintf( out, "v %.5f %.5f %.5f\n", p.x(), p.y(), p.z() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// dump normals
|
||||
void dump_normals( void ) {
|
||||
Point3D p;
|
||||
|
||||
fprintf(out, "\n");
|
||||
|
||||
iterator3 current = normals.begin();
|
||||
iterator3 last = normals.end();
|
||||
|
||||
// skip first dummy normal
|
||||
++current;
|
||||
|
||||
for ( ; current != last; ++current ) {
|
||||
p = *current;
|
||||
fprintf(out, "vn %.5f %.5f %.5f\n", p.x(), p.y(), p.z() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// dump faces
|
||||
void dump_faces( void ) {
|
||||
Point3D p;
|
||||
int i, n1, n2, n3;
|
||||
double xmax, xmin, ymax, ymin, zmax, zmin, dist, radius;
|
||||
|
||||
fprintf(out, "\n");
|
||||
for ( i = 1; i < fcount; i++ ) {
|
||||
n1 = faces[i][0];
|
||||
n2 = faces[i][1];
|
||||
n3 = faces[i][2];
|
||||
|
||||
// calc center of face
|
||||
xmin = xmax = nodes[n1].x();
|
||||
ymin = ymax = nodes[n1].y();
|
||||
zmin = zmax = nodes[n1].z();
|
||||
|
||||
if ( nodes[n2].x() < xmin ) { xmin = nodes[n2].x(); }
|
||||
if ( nodes[n2].x() > xmax ) { xmax = nodes[n2].x(); }
|
||||
if ( nodes[n2].y() < ymin ) { ymin = nodes[n2].y(); }
|
||||
if ( nodes[n2].y() > ymax ) { ymax = nodes[n2].y(); }
|
||||
if ( nodes[n2].z() < zmin ) { zmin = nodes[n2].z(); }
|
||||
if ( nodes[n2].z() > zmax ) { zmax = nodes[n2].z(); }
|
||||
|
||||
if ( nodes[n3].x() < xmin ) { xmin = nodes[n3].x(); }
|
||||
if ( nodes[n3].x() > xmax ) { xmax = nodes[n3].x(); }
|
||||
if ( nodes[n3].y() < ymin ) { ymin = nodes[n3].y(); }
|
||||
if ( nodes[n3].y() > ymax ) { ymax = nodes[n3].y(); }
|
||||
if ( nodes[n3].z() < zmin ) { zmin = nodes[n3].z(); }
|
||||
if ( nodes[n3].z() > zmax ) { zmax = nodes[n3].z(); }
|
||||
|
||||
p = Point3D( (xmin + xmax) / 2.0,
|
||||
(ymin + ymax) / 2.0,
|
||||
(zmin + zmax) / 2.0 );
|
||||
|
||||
// calc bounding radius
|
||||
radius = p.distance3D(nodes[n1]);
|
||||
|
||||
dist = p.distance3D(nodes[n2]);
|
||||
if ( dist > radius ) { radius = dist; }
|
||||
|
||||
dist = p.distance3D(nodes[n3]);
|
||||
if ( dist > radius ) { radius = dist; }
|
||||
|
||||
// output data
|
||||
fprintf(out, "bs %.2f %.2f %.2f %.2f\n", p.x(), p.y(), p.z(), radius);
|
||||
fprintf(out, "f %d %d %d\n", n1, n2, n3);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// dump list
|
||||
void dump_list(int *list, int list_ptr) {
|
||||
Point3D p;
|
||||
double xmax, xmin, ymax, ymin, zmax, zmin, dist_squared, radius_squared;
|
||||
double radius;
|
||||
int i, j, len, n;
|
||||
|
||||
if ( list_ptr < 3 ) {
|
||||
printf("List is empty ... skipping\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Dumping list, size = %d\n", list_ptr);
|
||||
|
||||
i = 0;
|
||||
while ( i < list_ptr ) {
|
||||
// do next strip
|
||||
|
||||
if ( (i % 2) == 0 ) {
|
||||
fprintf(out, "\nusemtl desert1\n");
|
||||
} else {
|
||||
fprintf(out, "\nusemtl desert2\n");
|
||||
}
|
||||
|
||||
// find length of next tri strip
|
||||
len = 0;
|
||||
// scan rest of strip (until -1)
|
||||
while ( ((i+len) < list_ptr) && (list[i+len] != -1) ) {
|
||||
// printf("len = %d item = %d\n", len, list[i+len] );
|
||||
len++;
|
||||
}
|
||||
// printf("strip length = %d\n", len);
|
||||
|
||||
// calc center of face
|
||||
n = list[i];
|
||||
xmin = xmax = nodes[n].x();
|
||||
ymin = ymax = nodes[n].y();
|
||||
zmin = zmax = nodes[n].z();
|
||||
// printf("%.2f %.2f %.2f\n", nodes[n].x(), nodes[n].y(), nodes[n].z());
|
||||
|
||||
for ( j = i + 1; j < i + len; j++ ) {
|
||||
// printf("j = %d\n", j);
|
||||
n = list[j];
|
||||
if ( nodes[n].x() < xmin ) { xmin = nodes[n].x(); }
|
||||
if ( nodes[n].x() > xmax ) { xmax = nodes[n].x(); }
|
||||
if ( nodes[n].y() < ymin ) { ymin = nodes[n].y(); }
|
||||
if ( nodes[n].y() > ymax ) { ymax = nodes[n].y(); }
|
||||
if ( nodes[n].z() < zmin ) { zmin = nodes[n].z(); }
|
||||
if ( nodes[n].z() > zmax ) { zmax = nodes[n].z(); }
|
||||
// printf("%.2f %.2f %.2f\n", nodes[n].x(), nodes[n].y(), nodes[n].z());
|
||||
}
|
||||
p = Point3D( (xmin + xmax) / 2.0,
|
||||
(ymin + ymax) / 2.0,
|
||||
(zmin + zmax) / 2.0 );
|
||||
// printf("center = %.2f %.2f %.2f\n", p.x(), p.y(), p.z());
|
||||
|
||||
// calc bounding radius
|
||||
n = list[i];
|
||||
radius_squared = p.distance3Dsquared(nodes[n]);
|
||||
|
||||
for ( j = i + 1; j < i + len; j++ ) {
|
||||
n = list[j];
|
||||
dist_squared = p.distance3Dsquared(nodes[n]);
|
||||
if ( dist_squared > radius_squared ) {
|
||||
radius_squared = dist_squared;
|
||||
}
|
||||
}
|
||||
radius = sqrt(radius_squared);
|
||||
|
||||
// printf("radius = %.2f\n", radius);
|
||||
|
||||
// dump bounding sphere and header
|
||||
fprintf(out, "bs %.2f %.2f %.2f %.2f\n", p.x(), p.y(), p.z(), radius);
|
||||
fprintf(out, "t %d %d %d\n", list[i], list[i+1], list[i+2]);
|
||||
// printf("t %d %d %d\n", list[i], list[i+1], list[i+2]);
|
||||
i += 3;
|
||||
|
||||
// dump rest of strip (until -1)
|
||||
while ( (i < list_ptr) && (list[i] != -1) ) {
|
||||
fprintf(out, "q %d", list[i]);
|
||||
i++;
|
||||
if ( (i < list_ptr) && (list[i] != -1) ) {
|
||||
fprintf(out, " %d", list[i]);
|
||||
i++;
|
||||
}
|
||||
fprintf(out, "\n");
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Check the direction the current triangle faces, compared to it's
|
||||
// pregenerated normal. Returns the dot product between the target
|
||||
// normal and actual normal. If the dot product is close to 1.0, they
|
||||
// nearly match. If the are close to -1.0, the are nearly opposite.
|
||||
double check_cur_face(int n1, int n2, int n3) {
|
||||
double v1[3], v2[3], approx_normal[3], dot_prod, temp;
|
||||
|
||||
// check for the proper rotation by calculating an approximate
|
||||
// normal and seeing if it is close to the precalculated normal
|
||||
v1[0] = nodes[n2].x() - nodes[n1].x();
|
||||
v1[1] = nodes[n2].y() - nodes[n1].y();
|
||||
v1[2] = nodes[n2].z() - nodes[n1].z();
|
||||
v2[0] = nodes[n3].x() - nodes[n1].x();
|
||||
v2[1] = nodes[n3].y() - nodes[n1].y();
|
||||
v2[2] = nodes[n3].z() - nodes[n1].z();
|
||||
|
||||
MAT3cross_product(approx_normal, v1, v2);
|
||||
MAT3_NORMALIZE_VEC(approx_normal,temp);
|
||||
dot_prod = MAT3_DOT_PRODUCT(normals[n1], approx_normal);
|
||||
|
||||
// not first triangle
|
||||
// if ( ((dot_prod < -0.5) && !is_backwards) ||
|
||||
// ((dot_prod > 0.5) && is_backwards) ) {
|
||||
// printf(" Approx normal = %.2f %.2f %.2f\n", approx_normal[0],
|
||||
// approx_normal[1], approx_normal[2]);
|
||||
// printf(" Dot product = %.4f\n", dot_prod);
|
||||
// }
|
||||
// angle = acos(dot_prod);
|
||||
// printf("Normal ANGLE = %.3f rads.\n", angle);
|
||||
|
||||
return(dot_prod);
|
||||
}
|
||||
|
||||
|
||||
// Load a .obj file
|
||||
void obj_fix(char *infile, char *outfile) {
|
||||
Point3D node, normal;
|
||||
char line[256];
|
||||
double dot_prod;
|
||||
int first, n1, n2, n3, n4;
|
||||
double x, y, z, xmax, xmin, ymax, ymin, zmax, zmin;
|
||||
int is_ccw;
|
||||
|
||||
if ( (in = fopen(infile, "r")) == NULL ) {
|
||||
printf("Cannot open file: %s\n", infile);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if ( (out = fopen(outfile, "w")) == NULL ) {
|
||||
printf("Cannot open file: %s\n", outfile);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// push dummy records onto the lists since we start counting with "1"
|
||||
node = Point3D(0.0, 0.0, 0.0);
|
||||
nodes.push_back(node);
|
||||
|
||||
normal = Point3D(0.0, 0.0, 0.0);
|
||||
normals.push_back(normal);
|
||||
|
||||
// initialize other lists
|
||||
list_init(&ccw_list_ptr);
|
||||
list_init(&cw_list_ptr);
|
||||
|
||||
// I start counting at one because that is how the triangle
|
||||
// program refers to nodes and normals
|
||||
first = 1;
|
||||
vncount = 1;
|
||||
fcount = 1;
|
||||
|
||||
printf("Reading file: %s\n", infile);
|
||||
|
||||
while ( fgets(line, 250, in) != NULL ) {
|
||||
if ( line[0] == '#' ) {
|
||||
// pass along the comments verbatim
|
||||
fprintf(out, "%s", line);
|
||||
} else if ( strlen(line) <= 1 ) {
|
||||
// don't pass along empty lines
|
||||
// fprintf(out, "%s", line);
|
||||
} else if ( strncmp(line, "v ", 2) == 0 ) {
|
||||
// save vertex to memory and output to file
|
||||
// printf("vertex = %s", line);
|
||||
sscanf(line, "v %lf %lf %lf\n", &x, &y, &z);
|
||||
|
||||
if ( nodes.size() == 1 ) {
|
||||
// first time through set min's and max'es
|
||||
xmin = x;
|
||||
xmax = x;
|
||||
ymin = y;
|
||||
ymax = y;
|
||||
zmin = z;
|
||||
zmax = z;
|
||||
} else {
|
||||
// update min/max vertex values
|
||||
if ( x < xmin ) xmin = x;
|
||||
if ( x > xmax ) xmax = x;
|
||||
if ( y < ymin ) ymin = y;
|
||||
if ( y > ymax ) ymax = y;
|
||||
if ( z < zmin ) zmin = z;
|
||||
if ( z > zmax ) zmax = z;
|
||||
}
|
||||
|
||||
node = Point3D(x, y, z);
|
||||
nodes.push_back(node);
|
||||
// fprintf(out, "v %.2f %.2f %.2f\n",
|
||||
// node.x(), node.y(), node.z());
|
||||
} else if ( strncmp(line, "vn ", 3) == 0 ) {
|
||||
// save vertex normals to memory and output to file
|
||||
// printf("vertex normal = %s", line);
|
||||
sscanf(line, "vn %lf %lf %lf\n", &x, &y, &z);
|
||||
normal = Point3D(x, y, z);
|
||||
normals.push_back(normal);
|
||||
} else if ( line[0] == 't' ) {
|
||||
// starting a new triangle strip
|
||||
|
||||
printf("Starting a new triangle strip\n");
|
||||
|
||||
n1 = n2 = n3 = n4 = 0;
|
||||
|
||||
printf("new tri strip = %s", line);
|
||||
sscanf(line, "t %d %d %d %d\n", &n1, &n2, &n3, &n4);
|
||||
|
||||
// special cases to handle bugs in our beloved tri striper
|
||||
if ( (n1 == 4) && (n2 == 2) && (n3 == 2) && (n4 == 1) ) {
|
||||
n2 = 3;
|
||||
}
|
||||
if ( (n1 == 3) && (n2 == 1) && (n3 == 1) && (n4 == 0) ) {
|
||||
n3 = 4;
|
||||
}
|
||||
|
||||
dot_prod = check_cur_face(n1, n2, n3);
|
||||
if ( dot_prod < 0.0 ) {
|
||||
// this stripe is backwards (CW)
|
||||
is_ccw = 0;
|
||||
printf(" -> Starting a backwards stripe\n");
|
||||
} else {
|
||||
// this stripe is normal (CCW)
|
||||
is_ccw = 1;
|
||||
}
|
||||
|
||||
if ( is_ccw ) {
|
||||
if ( ccw_list_ptr ) {
|
||||
list_add(ccw_list, &ccw_list_ptr, -1);
|
||||
}
|
||||
|
||||
list_add(ccw_list, &ccw_list_ptr, n1);
|
||||
list_add(ccw_list, &ccw_list_ptr, n2);
|
||||
list_add(ccw_list, &ccw_list_ptr, n3);
|
||||
} else {
|
||||
if ( cw_list_ptr ) {
|
||||
list_add(cw_list, &cw_list_ptr, -1);
|
||||
}
|
||||
|
||||
list_add(cw_list, &cw_list_ptr, n1);
|
||||
list_add(cw_list, &cw_list_ptr, n2);
|
||||
list_add(cw_list, &cw_list_ptr, n3);
|
||||
}
|
||||
|
||||
if ( n4 > 0 ) {
|
||||
if ( is_ccw ) {
|
||||
list_add(ccw_list, &ccw_list_ptr, n4);
|
||||
} else {
|
||||
list_add(cw_list, &cw_list_ptr, n4);
|
||||
}
|
||||
}
|
||||
} else if ( line[0] == 'f' ) {
|
||||
if ( fcount < MAXNODES ) {
|
||||
// pass along the unoptimized faces verbatim
|
||||
sscanf(line, "f %d %d %d\n", &n1, &n2, &n3);
|
||||
faces[fcount][0] = n1;
|
||||
faces[fcount][1] = n2;
|
||||
faces[fcount][2] = n3;
|
||||
|
||||
fcount++;
|
||||
} else {
|
||||
printf("Read too many unoptimized faces ... dying :-(\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// fprintf(out, "%s", line);
|
||||
} else if ( line[0] == 'q' ) {
|
||||
// continue a triangle strip
|
||||
n1 = n2 = 0;
|
||||
|
||||
// printf("continued tri strip = %s ", line);
|
||||
sscanf(line, "q %d %d\n", &n1, &n2);
|
||||
|
||||
if ( is_ccw ) {
|
||||
list_add(ccw_list, &ccw_list_ptr, n1);
|
||||
} else {
|
||||
list_add(cw_list, &cw_list_ptr, n1);
|
||||
}
|
||||
|
||||
if ( n2 > 0 ) {
|
||||
if ( is_ccw ) {
|
||||
list_add(ccw_list, &ccw_list_ptr, n2);
|
||||
} else {
|
||||
list_add(cw_list, &cw_list_ptr, n2);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
printf("Unknown line in %s = %s\n", infile, line);
|
||||
}
|
||||
}
|
||||
|
||||
// reference point is the "center"
|
||||
ref = Point3D( (xmin + xmax) / 2.0,
|
||||
(ymin + ymax) / 2.0,
|
||||
(zmin + zmax) / 2.0 );
|
||||
|
||||
// convert the cw_list to ccw add append to ccw_list
|
||||
fix_cw_list(cw_list, cw_list_ptr);
|
||||
|
||||
dump_global_bounds();
|
||||
dump_nodes();
|
||||
dump_normals();
|
||||
if ( fcount > 1 ) {
|
||||
dump_faces();
|
||||
}
|
||||
|
||||
dump_list(ccw_list, ccw_list_ptr);
|
||||
|
||||
fclose(in);
|
||||
fclose(out);
|
||||
}
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.3 1999/02/01 21:09:40 curt
|
||||
// Optimizations from Norman Vine.
|
||||
//
|
||||
// Revision 1.2 1998/10/21 14:55:55 curt
|
||||
// Converted to Point3D class.
|
||||
//
|
||||
// Revision 1.1 1998/06/08 17:11:46 curt
|
||||
// Renamed *.[ch] to *.[ch]xx
|
||||
//
|
||||
// Revision 1.16 1998/05/27 02:27:22 curt
|
||||
// Commented out a couple of debugging messages.
|
||||
//
|
||||
// Revision 1.15 1998/05/24 02:47:47 curt
|
||||
// For each strip, specify a default material property and calculate a center
|
||||
// and bounding sphere.
|
||||
//
|
||||
// Revision 1.14 1998/05/23 15:19:49 curt
|
||||
// Output more digits after the decimal place.
|
||||
//
|
||||
// Revision 1.13 1998/05/20 20:55:19 curt
|
||||
// Fixed arbitrary polygon winding problem here so all tristrips are passed
|
||||
// to runtime simulator with a consistant counter clockwise winding.
|
||||
//
|
||||
// Revision 1.12 1998/05/16 13:11:26 curt
|
||||
// Fixed an off by one error in node, normal, and face counters.
|
||||
//
|
||||
// Revision 1.11 1998/04/27 15:59:24 curt
|
||||
// Fixed an off by one error.
|
||||
//
|
||||
// Revision 1.10 1998/04/27 03:33:11 curt
|
||||
// Code now calculates a center reference points and outputs everything
|
||||
// relative to that. This is useful in the rendering engine to keep everything
|
||||
// close to (0, 0, 0) where we can avoid many GLfloat precision problems.
|
||||
//
|
||||
// Revision 1.9 1998/04/18 04:01:03 curt
|
||||
// Now use libMath rather than having local copies of math routines.
|
||||
//
|
||||
// Revision 1.8 1998/04/08 23:19:37 curt
|
||||
// Adopted Gnu automake/autoconf system.
|
||||
//
|
||||
// Revision 1.7 1998/03/19 02:51:41 curt
|
||||
// Added special case handling to compensate for bugs in our beloved tri striper
|
||||
//
|
||||
// Revision 1.6 1998/03/03 15:36:12 curt
|
||||
// Tweaks for compiling with g++
|
||||
//
|
||||
// Revision 1.5 1998/03/03 03:37:03 curt
|
||||
// Cumulative tweaks.
|
||||
//
|
||||
// Revision 1.4 1998/01/31 00:41:25 curt
|
||||
// Made a few changes converting floats to doubles.
|
||||
//
|
||||
// Revision 1.3 1998/01/19 19:51:07 curt
|
||||
// A couple final pre-release tweaks.
|
||||
//
|
||||
// Revision 1.2 1998/01/09 23:03:12 curt
|
||||
// Restructured to split 1deg x 1deg dem's into 64 subsections.
|
||||
//
|
||||
// Revision 1.1 1997/12/08 19:28:54 curt
|
||||
// Initial revision.
|
||||
//
|
60
Tools/FixObj/obj.hxx
Normal file
60
Tools/FixObj/obj.hxx
Normal file
|
@ -0,0 +1,60 @@
|
|||
// obj.hxx -- routines to handle WaveFront .obj format files.
|
||||
//
|
||||
// Written by Curtis Olson, started October 1997.
|
||||
//
|
||||
// Copyright (C) 1997 - 1998 Curtis L. Olson - curt@me.umn.edu
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
|
||||
|
||||
#ifndef OBJ_HXX
|
||||
#define OBJ_HXX
|
||||
|
||||
|
||||
#ifndef __cplusplus
|
||||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
|
||||
#define MAXNODES 100000
|
||||
|
||||
|
||||
// Load a .obj file
|
||||
void obj_fix(char *infile, char *outfile);
|
||||
|
||||
|
||||
#endif // OBJ_HXX
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.1 1998/06/08 17:11:46 curt
|
||||
// Renamed *.[ch] to *.[ch]xx
|
||||
//
|
||||
// Revision 1.4 1998/03/03 15:36:13 curt
|
||||
// Tweaks for compiling with g++
|
||||
//
|
||||
// Revision 1.3 1998/01/31 00:41:25 curt
|
||||
// Made a few changes converting floats to doubles.
|
||||
//
|
||||
// Revision 1.2 1998/01/09 23:03:13 curt
|
||||
// Restructured to split 1deg x 1deg dem's into 64 subsections.
|
||||
//
|
||||
// Revision 1.1 1997/12/08 19:28:55 curt
|
||||
// Initial revision.
|
||||
//
|
||||
|
86
Tools/GenAirports/Makefile.am
Normal file
86
Tools/GenAirports/Makefile.am
Normal file
|
@ -0,0 +1,86 @@
|
|||
#---------------------------------------------------------------------------
|
||||
# Makefile
|
||||
#
|
||||
# Written by Curtis Olson, started January 1998.
|
||||
#
|
||||
# Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
|
||||
#
|
||||
# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
# $Id$
|
||||
# (Log is kept at end of this file)
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
|
||||
bin_PROGRAMS = genapts
|
||||
|
||||
genapts_SOURCES = \
|
||||
area.cxx area.hxx \
|
||||
convex_hull.cxx convex_hull.hxx \
|
||||
main.cxx \
|
||||
point2d.cxx point2d.hxx
|
||||
|
||||
genapts_LDADD = \
|
||||
$(top_builddir)/Tools/Lib/Polygon/libPolygon.a \
|
||||
$(top_builddir)/Lib/Bucket/libBucket.a \
|
||||
$(top_builddir)/Lib/Debug/libDebug.a \
|
||||
$(top_builddir)/Lib/Misc/libMisc.a \
|
||||
$(top_builddir)/Lib/zlib/libz.a \
|
||||
$(base_LIBS)
|
||||
|
||||
INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib -I$(top_builddir)/Tools/Lib
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# $Log$
|
||||
# Revision 1.6 1999/03/08 22:00:47 curt
|
||||
# Lots of directory layout reorganization.
|
||||
#
|
||||
# Revision 1.5 1999/02/25 21:32:47 curt
|
||||
# Modified to adhere to new polygon naming convention, and also to read the
|
||||
# new Robin Peel aiport format.
|
||||
#
|
||||
# Revision 1.4 1999/02/11 01:10:50 curt
|
||||
# Start of scenery revamp project.
|
||||
#
|
||||
# Revision 1.3 1998/11/04 23:01:54 curt
|
||||
# Changes to the automake/autoconf system to reduce the number of libraries
|
||||
# that are unnecessarily linked into the various executables.
|
||||
#
|
||||
# Revision 1.2 1998/09/04 23:04:47 curt
|
||||
# Beginning of convex hull genereration routine.
|
||||
#
|
||||
# Revision 1.1 1998/09/01 19:34:32 curt
|
||||
# Initial revision.
|
||||
#
|
||||
# Revision 1.2 1998/07/30 23:49:18 curt
|
||||
# Removed libtool support.
|
||||
#
|
||||
# Revision 1.1 1998/07/20 12:54:53 curt
|
||||
# Whoops, need to commit Makefile.am, not Makefile.
|
||||
#
|
||||
# Revision 1.2 1998/04/14 02:25:59 curt
|
||||
# Code reorganizations. Added a Lib/ directory for more general libraries.
|
||||
#
|
||||
# Revision 1.1 1998/04/08 22:54:57 curt
|
||||
# Adopted Gnu automake/autoconf system.
|
||||
#
|
||||
# Revision 1.2 1998/01/21 02:55:46 curt
|
||||
# Incorporated new make system from Bob Kuehne <rpk@sgi.com>.
|
||||
#
|
||||
# Revision 1.1 1998/01/15 02:45:25 curt
|
||||
# Initial revision.
|
||||
#
|
||||
|
241
Tools/GenAirports/area.cxx
Normal file
241
Tools/GenAirports/area.cxx
Normal file
|
@ -0,0 +1,241 @@
|
|||
// area.c -- routines to assist with inserting "areas" into FG terrain
|
||||
//
|
||||
// Written by Curtis Olson, started March 1998.
|
||||
//
|
||||
// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
//
|
||||
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Include/fg_constants.h>
|
||||
|
||||
#include "area.hxx"
|
||||
#include "point2d.hxx"
|
||||
|
||||
|
||||
// calc new x, y for a rotation
|
||||
double rot_x(double x, double y, double theta) {
|
||||
return ( x * cos(theta) + y * sin(theta) );
|
||||
}
|
||||
|
||||
|
||||
// calc new x, y for a rotation
|
||||
double rot_y(double x, double y, double theta) {
|
||||
return ( -x * sin(theta) + y * cos(theta) );
|
||||
}
|
||||
|
||||
|
||||
// calc new lon/lat given starting lon/lat, and offset radial, and
|
||||
// distance. NOTE: distance is specified in meters (and converted
|
||||
// internally to radians)
|
||||
point2d calc_lon_lat( point2d orig, point2d offset ) {
|
||||
point2d result;
|
||||
|
||||
// printf("calc_lon_lat() offset.theta = %.2f offset.dist = %.2f\n",
|
||||
// offset.theta, offset.dist);
|
||||
|
||||
offset.dist *= METER_TO_NM * NM_TO_RAD;
|
||||
|
||||
result.lat = asin( sin(orig.lat) * cos(offset.dist) +
|
||||
cos(orig.lat) * sin(offset.dist) * cos(offset.theta) );
|
||||
|
||||
if ( cos(result.lat) < FG_EPSILON ) {
|
||||
result.lon = orig.lon; // endpoint a pole
|
||||
} else {
|
||||
result.lon =
|
||||
fmod(orig.lon - asin( sin(offset.theta) * sin(offset.dist) /
|
||||
cos(result.lat) ) + FG_PI, FG_2PI) - FG_PI;
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
list < point2d >
|
||||
batch_cart_to_polar_2d( list < point2d > in_list)
|
||||
{
|
||||
list < point2d > out_list;
|
||||
list < point2d > :: iterator current;
|
||||
list < point2d > :: iterator last;
|
||||
point2d p;
|
||||
|
||||
current = in_list.begin();
|
||||
last = in_list.end();
|
||||
for ( ; current != last ; ++current ) {
|
||||
p = cart_to_polar_2d( *current );
|
||||
out_list.push_back(p);
|
||||
}
|
||||
|
||||
return out_list;
|
||||
}
|
||||
|
||||
|
||||
// given a set of 2d coordinates relative to a center point, and the
|
||||
// lon, lat of that center point (specified in degrees), as well as a
|
||||
// potential orientation angle, generate the corresponding lon and lat
|
||||
// of the original 2d verticies.
|
||||
list < point2d >
|
||||
gen_area(point2d origin, double angle, list < point2d > cart_list)
|
||||
{
|
||||
list < point2d > rad_list;
|
||||
list < point2d > result_list;
|
||||
list < point2d > :: iterator current;
|
||||
list < point2d > :: iterator last;
|
||||
point2d origin_rad, p;
|
||||
|
||||
origin_rad.lon = origin.lon * DEG_TO_RAD;
|
||||
origin_rad.lat = origin.lat * DEG_TO_RAD;
|
||||
|
||||
// convert to polar coordinates
|
||||
rad_list = batch_cart_to_polar_2d(cart_list);
|
||||
|
||||
/*
|
||||
// display points
|
||||
printf("converted to polar\n");
|
||||
current = rad_list.begin();
|
||||
last = rad_list.end();
|
||||
while ( current != last ) {
|
||||
printf("(%.2f, %.2f)\n", current->theta, current->dist);
|
||||
++current;
|
||||
}
|
||||
printf("\n");
|
||||
*/
|
||||
|
||||
// rotate by specified angle
|
||||
// printf("Rotating points by %.2f\n", angle);
|
||||
current = rad_list.begin();
|
||||
last = rad_list.end();
|
||||
for ( ; current != last ; ++current ) {
|
||||
current->theta -= angle;
|
||||
while ( current->theta > FG_2PI ) {
|
||||
current->theta -= FG_2PI;
|
||||
// (*current).theta -= angle;
|
||||
// while ( (*current).theta > FG_2PI ) {
|
||||
// (*current).theta -= FG_2PI;
|
||||
}
|
||||
// printf("(%.2f, %.2f)\n", current->theta, current->dist);
|
||||
}
|
||||
// printf("\n");
|
||||
|
||||
// find actual lon,lat of coordinates
|
||||
// printf("convert to lon, lat relative to %.2f %.2f\n",
|
||||
// origin.lon, origin.lat);
|
||||
current = rad_list.begin();
|
||||
last = rad_list.end();
|
||||
for ( ; current != last ; ++current ) {
|
||||
p = calc_lon_lat(origin_rad, *current);
|
||||
// convert from radians to degress
|
||||
p.lon *= RAD_TO_DEG;
|
||||
p.lat *= RAD_TO_DEG;
|
||||
// printf("(%.8f, %.8f)\n", p.lon, p.lat);
|
||||
result_list.push_back(p);
|
||||
}
|
||||
// printf("\n");
|
||||
|
||||
return result_list;
|
||||
}
|
||||
|
||||
|
||||
// generate an area for a runway
|
||||
list < point2d >
|
||||
gen_runway_area( double lon, double lat, double heading,
|
||||
double length, double width)
|
||||
{
|
||||
list < point2d > result_list;
|
||||
list < point2d > tmp_list;
|
||||
list < point2d > :: iterator current;
|
||||
list < point2d > :: iterator last;
|
||||
|
||||
point2d p;
|
||||
point2d origin;
|
||||
double l, w;
|
||||
int i;
|
||||
|
||||
/*
|
||||
printf("runway: lon = %.2f lat = %.2f hdg = %.2f len = %.2f width = %.2f\n",
|
||||
lon, lat, heading, length, width);
|
||||
*/
|
||||
|
||||
origin.lon = lon;
|
||||
origin.lat = lat;
|
||||
l = length / 2.0;
|
||||
w = width / 2.0;
|
||||
|
||||
// generate untransformed runway area vertices
|
||||
p.x = l; p.y = w; tmp_list.push_back(p);
|
||||
p.x = l; p.y = -w; tmp_list.push_back(p);
|
||||
p.x = -l; p.y = -w; tmp_list.push_back(p);
|
||||
p.x = -l; p.y = w; tmp_list.push_back(p);
|
||||
|
||||
/*
|
||||
// display points
|
||||
printf("Untransformed, unrotated runway\n");
|
||||
current = tmp_list.begin();
|
||||
last = tmp_list.end();
|
||||
while ( current != last ) {
|
||||
printf("(%.2f, %.2f)\n", current->x, current->y);
|
||||
++current;
|
||||
}
|
||||
printf("\n");
|
||||
*/
|
||||
|
||||
// rotate, transform, and convert points to lon, lat in degrees
|
||||
result_list = gen_area(origin, heading, tmp_list);
|
||||
|
||||
/*
|
||||
// display points
|
||||
printf("Results in radians.\n");
|
||||
current = result_list.begin();
|
||||
last = result_list.end();
|
||||
while ( current != last ) {
|
||||
printf("(%.8f, %.8f)\n", current->lon, current->lat);
|
||||
++current;
|
||||
}
|
||||
printf("\n");
|
||||
*/
|
||||
|
||||
return result_list;
|
||||
}
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.5 1998/10/20 15:49:54 curt
|
||||
// tweak ...
|
||||
//
|
||||
// Revision 1.4 1998/09/09 20:59:53 curt
|
||||
// Loop construct tweaks for STL usage.
|
||||
// Output airport file to be used to generate airport scenery on the fly
|
||||
// by the run time sim.
|
||||
//
|
||||
// Revision 1.3 1998/09/09 16:26:31 curt
|
||||
// Continued progress in implementing the convex hull algorithm.
|
||||
//
|
||||
// Revision 1.2 1998/09/04 23:04:48 curt
|
||||
// Beginning of convex hull genereration routine.
|
||||
//
|
||||
// Revision 1.1 1998/09/01 19:34:33 curt
|
||||
// Initial revision.
|
||||
//
|
||||
// Revision 1.1 1998/07/20 12:54:05 curt
|
||||
// Initial revision.
|
||||
//
|
||||
//
|
54
Tools/GenAirports/area.hxx
Normal file
54
Tools/GenAirports/area.hxx
Normal file
|
@ -0,0 +1,54 @@
|
|||
// area.h -- routines to assist with inserting "areas" into FG terrain
|
||||
//
|
||||
// Written by Curtis Olson, started February 1998.
|
||||
//
|
||||
// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
//
|
||||
|
||||
|
||||
#ifndef _AREA_H
|
||||
#define _AREA_H
|
||||
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "point2d.hxx"
|
||||
|
||||
|
||||
// generate an area for a runway (return result points in degrees)
|
||||
list < point2d >
|
||||
gen_runway_area( double lon, double lat, double heading,
|
||||
double length, double width);
|
||||
|
||||
|
||||
#endif // _AREA_H
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.2 1998/09/04 23:04:49 curt
|
||||
// Beginning of convex hull genereration routine.
|
||||
//
|
||||
// Revision 1.1 1998/09/01 19:34:33 curt
|
||||
// Initial revision.
|
||||
//
|
||||
// Revision 1.1 1998/07/20 12:54:05 curt
|
||||
// Initial revision.
|
||||
//
|
||||
//
|
277
Tools/GenAirports/convex_hull.cxx
Normal file
277
Tools/GenAirports/convex_hull.cxx
Normal file
|
@ -0,0 +1,277 @@
|
|||
// convex_hull.cxx -- calculate the convex hull of a set of points
|
||||
//
|
||||
// Written by Curtis Olson, started September 1998.
|
||||
//
|
||||
// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
//
|
||||
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
#ifdef NEEDNAMESPACESTD
|
||||
using namespace std;
|
||||
#endif
|
||||
|
||||
#include <Include/fg_constants.h>
|
||||
|
||||
#include "convex_hull.hxx"
|
||||
#include "point2d.hxx"
|
||||
|
||||
|
||||
// stl map typedefs
|
||||
typedef map < double, double, less<double> > map_container;
|
||||
typedef map_container::iterator map_iterator;
|
||||
|
||||
|
||||
// Calculate theta of angle (a, b, c)
|
||||
double calc_angle(point2d a, point2d b, point2d c) {
|
||||
point2d u, v;
|
||||
double udist, vdist, uv_dot, tmp;
|
||||
|
||||
// u . v = ||u|| * ||v|| * cos(theta)
|
||||
|
||||
u.x = b.x - a.x;
|
||||
u.y = b.y - a.y;
|
||||
udist = sqrt( u.x * u.x + u.y * u.y );
|
||||
// printf("udist = %.6f\n", udist);
|
||||
|
||||
v.x = b.x - c.x;
|
||||
v.y = b.y - c.y;
|
||||
vdist = sqrt( v.x * v.x + v.y * v.y );
|
||||
// printf("vdist = %.6f\n", vdist);
|
||||
|
||||
uv_dot = u.x * v.x + u.y * v.y;
|
||||
// printf("uv_dot = %.6f\n", uv_dot);
|
||||
|
||||
tmp = uv_dot / (udist * vdist);
|
||||
// printf("tmp = %.6f\n", tmp);
|
||||
|
||||
return acos(tmp);
|
||||
}
|
||||
|
||||
|
||||
// Test to see if angle(Pa, Pb, Pc) < 180 degrees
|
||||
bool test_point(point2d Pa, point2d Pb, point2d Pc) {
|
||||
point2d origin, a, b, c;
|
||||
double a1, a2;
|
||||
|
||||
origin.x = origin.y = 0.0;
|
||||
|
||||
a.x = cos(Pa.theta) * Pa.dist;
|
||||
a.y = sin(Pa.theta) * Pa.dist;
|
||||
|
||||
b.x = cos(Pb.theta) * Pb.dist;
|
||||
b.y = sin(Pb.theta) * Pb.dist;
|
||||
|
||||
c.x = cos(Pc.theta) * Pc.dist;
|
||||
c.y = sin(Pc.theta) * Pc.dist;
|
||||
|
||||
// printf("a is %.6f %.6f\n", a.x, a.y);
|
||||
// printf("b is %.6f %.6f\n", b.x, b.y);
|
||||
// printf("c is %.6f %.6f\n", c.x, c.y);
|
||||
|
||||
a1 = calc_angle(a, b, origin);
|
||||
a2 = calc_angle(origin, b, c);
|
||||
|
||||
// printf("a1 = %.2f a2 = %.2f\n", a1 * RAD_TO_DEG, a2 * RAD_TO_DEG);
|
||||
|
||||
return ( (a1 + a2) < FG_PI );
|
||||
}
|
||||
|
||||
|
||||
// calculate the convex hull of a set of points, return as a list of
|
||||
// point2d. The algorithm description can be found at:
|
||||
// http://riot.ieor.berkeley.edu/riot/Applications/ConvexHull/CHDetails.html
|
||||
list_container convex_hull( list_container input_list )
|
||||
{
|
||||
list_iterator current, last;
|
||||
map_iterator map_current, map_next, map_next_next, map_last;
|
||||
|
||||
// list of translated points
|
||||
list_container trans_list;
|
||||
|
||||
// points sorted by radian degrees
|
||||
map_container radians_map;
|
||||
|
||||
// will contain the convex hull
|
||||
list_container con_hull;
|
||||
|
||||
point2d p, average, Pa, Pb, Pc, result;
|
||||
double sum_x, sum_y;
|
||||
int in_count, last_size;
|
||||
|
||||
// STEP ONE: Find an average midpoint of the input set of points
|
||||
current = input_list.begin();
|
||||
last = input_list.end();
|
||||
in_count = input_list.size();
|
||||
sum_x = sum_y = 0.0;
|
||||
|
||||
for ( ; current != last ; ++current ) {
|
||||
sum_x += (*current).x;
|
||||
sum_y += (*current).y;
|
||||
}
|
||||
|
||||
average.x = sum_x / in_count;
|
||||
average.y = sum_y / in_count;
|
||||
|
||||
// printf("Average center point is %.4f %.4f\n", average.x, average.y);
|
||||
|
||||
// STEP TWO: Translate input points so average is at origin
|
||||
current = input_list.begin();
|
||||
last = input_list.end();
|
||||
trans_list.erase( trans_list.begin(), trans_list.end() );
|
||||
|
||||
for ( ; current != last ; ++current ) {
|
||||
p.x = (*current).x - average.x;
|
||||
p.y = (*current).y - average.y;
|
||||
// printf("%.6f %.6f\n", p.x, p.y);
|
||||
trans_list.push_back(p);
|
||||
}
|
||||
|
||||
// STEP THREE: convert to radians and sort by theta
|
||||
current = trans_list.begin();
|
||||
last = trans_list.end();
|
||||
radians_map.erase( radians_map.begin(), radians_map.end() );
|
||||
|
||||
for ( ; current != last ; ++current) {
|
||||
p = cart_to_polar_2d(*current);
|
||||
if ( p.dist > radians_map[p.theta] ) {
|
||||
radians_map[p.theta] = p.dist;
|
||||
}
|
||||
}
|
||||
|
||||
// printf("Sorted list\n");
|
||||
map_current = radians_map.begin();
|
||||
map_last = radians_map.end();
|
||||
for ( ; map_current != map_last ; ++map_current ) {
|
||||
p.x = (*map_current).first;
|
||||
p.y = (*map_current).second;
|
||||
|
||||
// printf("p is %.6f %.6f\n", p.x, p.y);
|
||||
}
|
||||
|
||||
// STEP FOUR: traverse the sorted list and eliminate everything
|
||||
// not on the perimeter.
|
||||
// printf("Traversing list\n");
|
||||
|
||||
// double check list size ... this should never fail because a
|
||||
// single runway will always generate four points.
|
||||
if ( radians_map.size() < 3 ) {
|
||||
cout << "convex hull not possible with < 3 points" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// ensure that we run the while loop at least once
|
||||
last_size = radians_map.size() + 1;
|
||||
|
||||
while ( last_size > radians_map.size() ) {
|
||||
// printf("Running an iteration of the graham scan algorithm\n");
|
||||
last_size = radians_map.size();
|
||||
|
||||
map_current = radians_map.begin();
|
||||
while ( map_current != radians_map.end() ) {
|
||||
// get first element
|
||||
Pa.theta = (*map_current).first;
|
||||
Pa.dist = (*map_current).second;
|
||||
|
||||
// get second element
|
||||
map_next = map_current;
|
||||
++map_next;
|
||||
if ( map_next == radians_map.end() ) {
|
||||
map_next = radians_map.begin();
|
||||
}
|
||||
Pb.theta = (*map_next).first;
|
||||
Pb.dist = (*map_next).second;
|
||||
|
||||
// get third element
|
||||
map_next_next = map_next;
|
||||
++map_next_next;
|
||||
if ( map_next_next == radians_map.end() ) {
|
||||
map_next_next = radians_map.begin();
|
||||
}
|
||||
Pc.theta = (*map_next_next).first;
|
||||
Pc.dist = (*map_next_next).second;
|
||||
|
||||
// printf("Pa is %.6f %.6f\n", Pa.theta, Pa.dist);
|
||||
// printf("Pb is %.6f %.6f\n", Pb.theta, Pb.dist);
|
||||
// printf("Pc is %.6f %.6f\n", Pc.theta, Pc.dist);
|
||||
|
||||
if ( test_point(Pa, Pb, Pc) ) {
|
||||
// printf("Accepted a point\n");
|
||||
// accept point, advance Pa, Pb, and Pc.
|
||||
++map_current;
|
||||
} else {
|
||||
// printf("REJECTED A POINT\n");
|
||||
// reject point, delete it and advance only Pb and Pc
|
||||
map_next = map_current;
|
||||
++map_next;
|
||||
if ( map_next == radians_map.end() ) {
|
||||
map_next = radians_map.begin();
|
||||
}
|
||||
radians_map.erase( map_next );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// translate back to correct lon/lat
|
||||
// printf("Final sorted convex hull\n");
|
||||
con_hull.erase( con_hull.begin(), con_hull.end() );
|
||||
map_current = radians_map.begin();
|
||||
map_last = radians_map.end();
|
||||
for ( ; map_current != map_last ; ++map_current ) {
|
||||
p.theta = (*map_current).first;
|
||||
p.dist = (*map_current).second;
|
||||
|
||||
result.x = cos(p.theta) * p.dist + average.x;
|
||||
result.y = sin(p.theta) * p.dist + average.y;
|
||||
|
||||
// printf("%.6f %.6f\n", result.x, result.y);
|
||||
|
||||
con_hull.push_back(result);
|
||||
}
|
||||
|
||||
return con_hull;
|
||||
}
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.5 1999/02/25 21:32:48 curt
|
||||
// Modified to adhere to new polygon naming convention, and also to read the
|
||||
// new Robin Peel aiport format.
|
||||
//
|
||||
// Revision 1.4 1998/09/17 18:40:42 curt
|
||||
// Debug message tweaks.
|
||||
//
|
||||
// Revision 1.3 1998/09/09 20:59:55 curt
|
||||
// Loop construct tweaks for STL usage.
|
||||
// Output airport file to be used to generate airport scenery on the fly
|
||||
// by the run time sim.
|
||||
//
|
||||
// Revision 1.2 1998/09/09 16:26:32 curt
|
||||
// Continued progress in implementing the convex hull algorithm.
|
||||
//
|
||||
// Revision 1.1 1998/09/04 23:04:51 curt
|
||||
// Beginning of convex hull genereration routine.
|
||||
//
|
||||
//
|
60
Tools/GenAirports/convex_hull.hxx
Normal file
60
Tools/GenAirports/convex_hull.hxx
Normal file
|
@ -0,0 +1,60 @@
|
|||
// convex_hull.hxx -- calculate the convex hull of a set of points
|
||||
//
|
||||
// Written by Curtis Olson, started September 1998.
|
||||
//
|
||||
// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
//
|
||||
|
||||
|
||||
#ifndef _CONVEX_HULL_HXX
|
||||
#define _CONVEX_HULL_HXX
|
||||
|
||||
|
||||
#include <list>
|
||||
|
||||
#ifdef NEEDNAMESPACESTD
|
||||
using namespace std;
|
||||
#endif
|
||||
|
||||
#include "point2d.hxx"
|
||||
|
||||
|
||||
// stl list typedefs
|
||||
typedef list < point2d > list_container;
|
||||
typedef list_container::iterator list_iterator;
|
||||
|
||||
|
||||
// calculate the convex hull of a set of points, return as a list of
|
||||
// point2d. The algorithm description can be found at:
|
||||
// http://riot.ieor.berkeley.edu/riot/Applications/ConvexHull/CHDetails.html
|
||||
list_container convex_hull( list_container input_list );
|
||||
|
||||
|
||||
#endif // _CONVEX_HULL_HXX
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.2 1998/09/09 16:26:33 curt
|
||||
// Continued progress in implementing the convex hull algorithm.
|
||||
//
|
||||
// Revision 1.1 1998/09/04 23:04:51 curt
|
||||
// Beginning of convex hull genereration routine.
|
||||
//
|
||||
//
|
374
Tools/GenAirports/main.cxx
Normal file
374
Tools/GenAirports/main.cxx
Normal file
|
@ -0,0 +1,374 @@
|
|||
// main.cxx -- main loop
|
||||
//
|
||||
// Written by Curtis Olson, started March 1998.
|
||||
//
|
||||
// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
//
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <Include/compiler.h>
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#include <list>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include STL_STRING
|
||||
|
||||
#include <Bucket/newbucket.hxx>
|
||||
#include <Debug/logstream.hxx>
|
||||
#include <Include/fg_constants.h>
|
||||
#include <Misc/fgstream.hxx>
|
||||
#include <Polygon/index.hxx>
|
||||
|
||||
#include "area.hxx"
|
||||
#include "convex_hull.hxx"
|
||||
|
||||
|
||||
// write out airport data
|
||||
void write_airport( long int p_index, list_container hull_list, FGBucket b,
|
||||
const string& root, const bool cut_and_keep ) {
|
||||
char tile_name[256], poly_index[256];
|
||||
|
||||
string base = b.gen_base_path();
|
||||
string path = root + "/Scenery/" + base;
|
||||
string command = "mkdir -p " + path;
|
||||
system( command.c_str() );
|
||||
|
||||
long int b_index = b.gen_index();
|
||||
sprintf(tile_name, "%ld", b_index);
|
||||
string aptfile = path + "/" + tile_name;
|
||||
|
||||
sprintf( poly_index, "%ld", p_index );
|
||||
aptfile += ".";
|
||||
aptfile += poly_index;
|
||||
cout << "apt file = " << aptfile << endl;
|
||||
|
||||
FILE *fd;
|
||||
if ( (fd = fopen(aptfile.c_str(), "a")) == NULL ) {
|
||||
cout << "Cannot open file: " << aptfile << endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// polygon type
|
||||
if ( cut_and_keep ) {
|
||||
fprintf( fd, "AirportKeep\n" );
|
||||
} else {
|
||||
fprintf( fd, "AirportIgnore\n" );
|
||||
}
|
||||
|
||||
// number of contours
|
||||
fprintf( fd, "1\n" );
|
||||
|
||||
// size of first contour
|
||||
fprintf( fd, "%d\n", hull_list.size() );
|
||||
|
||||
// write contour (polygon) points
|
||||
list_iterator current = hull_list.begin();
|
||||
list_iterator last = hull_list.end();
|
||||
for ( ; current != last ; ++current ) {
|
||||
fprintf( fd, "%.7f %.7f\n", (*current).lon, (*current).lat );
|
||||
}
|
||||
|
||||
fclose(fd);
|
||||
}
|
||||
|
||||
|
||||
// process and airport + runway list
|
||||
void process_airport( string airport, list < string > & runway_list,
|
||||
const string& root ) {
|
||||
list_container rwy_list, apt_list, hull_list;
|
||||
list_iterator current, last;
|
||||
|
||||
// parse main airport information
|
||||
int elev;
|
||||
|
||||
cout << airport << endl;
|
||||
string apt_type = airport.substr(0, 1);
|
||||
string apt_code = airport.substr(2, 4);
|
||||
string apt_lat = airport.substr(7, 10);
|
||||
string apt_lon = airport.substr(18, 11);
|
||||
string apt_elev = airport.substr(30, 5);
|
||||
sscanf( apt_elev.c_str(), "%d", &elev );
|
||||
string apt_use = airport.substr(36, 1);
|
||||
string apt_twr = airport.substr(37, 1);
|
||||
string apt_bldg = airport.substr(38, 1);
|
||||
string apt_name = airport.substr(40);
|
||||
|
||||
/*
|
||||
cout << " type = " << apt_type << endl;
|
||||
cout << " code = " << apt_code << endl;
|
||||
cout << " lat = " << apt_lat << endl;
|
||||
cout << " lon = " << apt_lon << endl;
|
||||
cout << " elev = " << apt_elev << " " << elev << endl;
|
||||
cout << " use = " << apt_use << endl;
|
||||
cout << " twr = " << apt_twr << endl;
|
||||
cout << " bldg = " << apt_bldg << endl;
|
||||
cout << " name = " << apt_name << endl;
|
||||
*/
|
||||
|
||||
// parse runways and generate the vertex list
|
||||
string rwy_str;
|
||||
double lon, lat, hdg;
|
||||
int len, width;
|
||||
|
||||
list < string >::iterator last_runway = runway_list.end();
|
||||
for ( list < string >::iterator current_runway = runway_list.begin();
|
||||
current_runway != last_runway ; ++current_runway ) {
|
||||
rwy_str = (*current_runway);
|
||||
|
||||
cout << rwy_str << endl;
|
||||
string rwy_no = rwy_str.substr(2, 4);
|
||||
string rwy_lat = rwy_str.substr(6, 10);
|
||||
sscanf( rwy_lat.c_str(), "%lf", &lat);
|
||||
string rwy_lon = rwy_str.substr(17, 11);
|
||||
sscanf( rwy_lon.c_str(), "%lf", &lon);
|
||||
string rwy_hdg = rwy_str.substr(29, 7);
|
||||
sscanf( rwy_hdg.c_str(), "%lf", &hdg);
|
||||
string rwy_len = rwy_str.substr(36, 7);
|
||||
sscanf( rwy_len.c_str(), "%d", &len);
|
||||
string rwy_width = rwy_str.substr(43, 4);
|
||||
sscanf( rwy_width.c_str(), "%d", &width);
|
||||
string rwy_sfc = rwy_str.substr(47, 4);
|
||||
string rwy_end1 = rwy_str.substr(52, 8);
|
||||
string rwy_end2 = rwy_str.substr(61, 8);
|
||||
|
||||
/*
|
||||
cout << " no = " << rwy_no << endl;
|
||||
cout << " lat = " << rwy_lat << " " << lat << endl;
|
||||
cout << " lon = " << rwy_lon << " " << lon << endl;
|
||||
cout << " hdg = " << rwy_hdg << " " << hdg << endl;
|
||||
cout << " len = " << rwy_len << " " << len << endl;
|
||||
cout << " width = " << rwy_width << " " << width << endl;
|
||||
cout << " sfc = " << rwy_sfc << endl;
|
||||
cout << " end1 = " << rwy_end1 << endl;
|
||||
cout << " end2 = " << rwy_end2 << endl;
|
||||
*/
|
||||
|
||||
rwy_list = gen_runway_area( lon, lat, hdg * DEG_TO_RAD,
|
||||
(double)len * FEET_TO_METER,
|
||||
(double)width * FEET_TO_METER );
|
||||
|
||||
// add rwy_list to apt_list
|
||||
current = rwy_list.begin();
|
||||
last = rwy_list.end();
|
||||
for ( ; current != last ; ++current ) {
|
||||
apt_list.push_back(*current);
|
||||
}
|
||||
}
|
||||
|
||||
if ( apt_list.size() == 0 ) {
|
||||
cout << "no runway points generated" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// printf("Runway points in degrees\n");
|
||||
// current = apt_list.begin();
|
||||
// last = apt_list.end();
|
||||
// for ( ; current != last; ++current ) {
|
||||
// printf( "%.5f %.5f\n", current->lon, current->lat );
|
||||
// }
|
||||
// printf("\n");
|
||||
|
||||
// generate convex hull
|
||||
hull_list = convex_hull(apt_list);
|
||||
|
||||
// get next polygon index
|
||||
long int index = poly_index_next();
|
||||
|
||||
// find average center, min, and max point of convex hull
|
||||
point2d average, min, max;
|
||||
double sum_x, sum_y;
|
||||
int count = hull_list.size();
|
||||
current = hull_list.begin();
|
||||
last = hull_list.end();
|
||||
sum_x = sum_y = 0.0;
|
||||
min.x = min.y = 200.0;
|
||||
max.x = max.y = -200.0;
|
||||
for ( ; current != last; ++current ) {
|
||||
// printf("return = %.6f %.6f\n", (*current).x, (*current).y);
|
||||
sum_x += (*current).x;
|
||||
sum_y += (*current).y;
|
||||
|
||||
if ( (*current).x < min.x ) { min.x = (*current).x; }
|
||||
if ( (*current).y < min.y ) { min.y = (*current).y; }
|
||||
if ( (*current).x > max.x ) { max.x = (*current).x; }
|
||||
if ( (*current).y > max.y ) { max.y = (*current).y; }
|
||||
}
|
||||
average.x = sum_x / count;
|
||||
average.y = sum_y / count;
|
||||
|
||||
// find buckets for center, min, and max points of convex hull.
|
||||
// note to self: self, you should think about checking for runways
|
||||
// that span the data line
|
||||
FGBucket b(average.lon, average.lat);
|
||||
FGBucket b_min(min.x, min.y);
|
||||
FGBucket b_max(max.x, max.y);
|
||||
cout << "Bucket center = " << b << endl;
|
||||
cout << "Bucket min = " << b_min << endl;
|
||||
cout << "Bucket max = " << b_max << endl;
|
||||
|
||||
if ( b_min == b_max ) {
|
||||
write_airport( index, hull_list, b, root, true );
|
||||
} else {
|
||||
FGBucket b_cur;
|
||||
int dx, dy, i, j;
|
||||
|
||||
fgBucketDiff(b_min, b_max, &dx, &dy);
|
||||
cout << "airport spans tile boundaries" << endl;
|
||||
cout << " dx = " << dx << " dy = " << dy << endl;
|
||||
|
||||
if ( (dx > 2) || (dy > 2) ) {
|
||||
cout << "somethings really wrong!!!!" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
for ( j = 0; j <= dy; j++ ) {
|
||||
for ( i = 0; i <= dx; i++ ) {
|
||||
b_cur = fgBucketOffset(min.x, min.y, i, j);
|
||||
if ( b_cur == b ) {
|
||||
write_airport( index, hull_list, b_cur, root, true );
|
||||
} else {
|
||||
write_airport( index, hull_list, b_cur, root, false );
|
||||
}
|
||||
}
|
||||
}
|
||||
// string answer; cin >> answer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// reads the apt_full file and extracts and processes the individual
|
||||
// airport records
|
||||
int main( int argc, char **argv ) {
|
||||
list < string > runway_list;
|
||||
string airport, last_airport;
|
||||
string line;
|
||||
char tmp[256];
|
||||
|
||||
fglog().setLogLevels( FG_ALL, FG_DEBUG );
|
||||
|
||||
if ( argc != 3 ) {
|
||||
FG_LOG( FG_GENERAL, FG_ALERT,
|
||||
"Usage " << argv[0] << " <apt_file> <work_dir>" );
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// make work directory
|
||||
string work_dir = argv[2];
|
||||
string command = "mkdir -p " + work_dir;
|
||||
system( command.c_str() );
|
||||
|
||||
// initialize persistant polygon counter
|
||||
string counter_file = work_dir + "/../work.counter";
|
||||
poly_index_init( counter_file );
|
||||
|
||||
fg_gzifstream in( argv[1] );
|
||||
if ( !in ) {
|
||||
FG_LOG( FG_GENERAL, FG_ALERT, "Cannot open file: " << argv[1] );
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// throw away the first 3 lines
|
||||
in.getline(tmp, 256);
|
||||
in.getline(tmp, 256);
|
||||
in.getline(tmp, 256);
|
||||
|
||||
last_airport = "";
|
||||
|
||||
while ( ! in.eof() ) {
|
||||
in.getline(tmp, 256);
|
||||
line = tmp;
|
||||
// cout << line << endl;
|
||||
|
||||
if ( line.length() == 0 ) {
|
||||
// empty, skip
|
||||
} else if ( line[0] == '#' ) {
|
||||
// comment, skip
|
||||
} else if ( (line[0] == 'A') || (line[0] == 'S') ) {
|
||||
// start of airport record
|
||||
airport = line;
|
||||
|
||||
if ( last_airport.length() ) {
|
||||
// process previous record
|
||||
process_airport(last_airport, runway_list, argv[2]);
|
||||
}
|
||||
|
||||
// clear runway list for start of next airport
|
||||
runway_list.erase(runway_list.begin(), runway_list.end());
|
||||
|
||||
last_airport = airport;
|
||||
} else if ( line[0] == 'R' ) {
|
||||
// runway entry
|
||||
runway_list.push_back(line);
|
||||
} else if ( line == "[End]" ) {
|
||||
// end of file
|
||||
break;
|
||||
} else {
|
||||
FG_LOG( FG_GENERAL, FG_ALERT,
|
||||
"Unknown line in file" << endl << line );
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
if ( last_airport.length() ) {
|
||||
// process previous record
|
||||
process_airport(last_airport, runway_list, argv[2]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.11 1999/03/19 00:27:38 curt
|
||||
// Use long int for index instead of just int.
|
||||
//
|
||||
// Revision 1.10 1999/03/17 23:51:25 curt
|
||||
// Changed polygon index counter file.
|
||||
//
|
||||
// Revision 1.9 1999/03/12 22:54:19 curt
|
||||
// Rearrange a bit of code ...
|
||||
//
|
||||
// Revision 1.8 1999/03/01 15:35:26 curt
|
||||
// Fixed bug in output format generated.
|
||||
//
|
||||
// Revision 1.7 1999/02/25 21:32:49 curt
|
||||
// Modified to adhere to new polygon naming convention, and also to read the
|
||||
// new Robin Peel aiport format.
|
||||
//
|
||||
// Revision 1.6 1999/02/11 01:10:51 curt
|
||||
// Start of scenery revamp project.
|
||||
//
|
||||
// Revision 1.5 1998/09/17 18:40:43 curt
|
||||
// Debug message tweaks.
|
||||
//
|
||||
// Revision 1.4 1998/09/09 20:59:56 curt
|
||||
// Loop construct tweaks for STL usage.
|
||||
// Output airport file to be used to generate airport scenery on the fly
|
||||
// by the run time sim.
|
||||
//
|
||||
//
|
45
Tools/GenAirports/point2d.cxx
Normal file
45
Tools/GenAirports/point2d.cxx
Normal file
|
@ -0,0 +1,45 @@
|
|||
// point2d.cxx -- 2d coordinate routines
|
||||
//
|
||||
// Written by Curtis Olson, started September 1998.
|
||||
//
|
||||
// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
//
|
||||
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "point2d.hxx"
|
||||
|
||||
|
||||
// convert a point from cartesian to polar coordinates
|
||||
point2d cart_to_polar_2d(point2d in) {
|
||||
point2d result;
|
||||
result.dist = sqrt( in.x * in.x + in.y * in.y );
|
||||
result.theta = atan2(in.y, in.x);
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.1 1998/09/04 23:04:53 curt
|
||||
// Beginning of convex hull genereration routine.
|
||||
//
|
||||
//
|
59
Tools/GenAirports/point2d.hxx
Normal file
59
Tools/GenAirports/point2d.hxx
Normal file
|
@ -0,0 +1,59 @@
|
|||
// point2d.hxx -- define a 2d point class
|
||||
//
|
||||
// Written by Curtis Olson, started February 1998.
|
||||
//
|
||||
// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
//
|
||||
|
||||
|
||||
#ifndef _POINT2D_HXX
|
||||
#define _POINT2D_HXX
|
||||
|
||||
|
||||
#include <list>
|
||||
|
||||
|
||||
class point2d {
|
||||
public:
|
||||
union {
|
||||
double x;
|
||||
double dist;
|
||||
double lon;
|
||||
};
|
||||
union {
|
||||
double y;
|
||||
double theta;
|
||||
double lat;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// convert a point from cartesian to polar coordinates
|
||||
point2d cart_to_polar_2d(point2d in);
|
||||
|
||||
|
||||
#endif // _POINT2D_HXX
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.1 1998/09/04 23:04:53 curt
|
||||
// Beginning of convex hull genereration routine.
|
||||
//
|
||||
//
|
9
Tools/GenOutput/Makefile.am
Normal file
9
Tools/GenOutput/Makefile.am
Normal file
|
@ -0,0 +1,9 @@
|
|||
noinst_LIBRARIES = libGenOutput.a
|
||||
|
||||
libGenOutput_a_SOURCES = genobj.cxx genobj.hxx
|
||||
|
||||
INCLUDES += \
|
||||
-I$(top_builddir) \
|
||||
-I$(top_builddir)/Lib \
|
||||
-I$(top_builddir)/Tools/Lib \
|
||||
-I$(top_builddir)/Tools/Construct
|
469
Tools/GenOutput/genobj.cxx
Normal file
469
Tools/GenOutput/genobj.cxx
Normal file
|
@ -0,0 +1,469 @@
|
|||
// 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 - curt@flightgear.org
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include <Math/mat3.h>
|
||||
#include <Polygon/names.hxx>
|
||||
#include <Tools/scenery_version.hxx>
|
||||
|
||||
#include "genobj.hxx"
|
||||
|
||||
|
||||
// build the wgs-84 point list
|
||||
void FGGenOutput::gen_wgs84_points( const FGArray& array ) {
|
||||
cout << "calculating wgs84 point" << endl;
|
||||
Point3D geod, radians, cart;
|
||||
|
||||
const_point_list_iterator current = geod_nodes.begin();
|
||||
const_point_list_iterator last = geod_nodes.end();
|
||||
|
||||
double real_z;
|
||||
|
||||
for ( ; current != last; ++current ) {
|
||||
geod = *current;
|
||||
|
||||
real_z = array.interpolate_altitude( geod.x() * 3600.0,
|
||||
geod.y() * 3600.0 );
|
||||
|
||||
// convert to radians
|
||||
radians = Point3D( geod.x() * DEG_TO_RAD,
|
||||
geod.y() * DEG_TO_RAD,
|
||||
real_z );
|
||||
|
||||
cart = fgGeodToCart(radians);
|
||||
// cout << cart << endl;
|
||||
wgs84_nodes.push_back(cart);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// build the node -> element (triangle) reverse lookup table. there
|
||||
// is an entry for each point containing a list of all the triangles
|
||||
// that share that point.
|
||||
void FGGenOutput::gen_node_ele_lookup_table() {
|
||||
int_list ele_list;
|
||||
ele_list.erase( ele_list.begin(), ele_list.end() );
|
||||
|
||||
// initialize reverse_ele_lookup structure by creating an empty
|
||||
// list for each point
|
||||
const_point_list_iterator w_current = wgs84_nodes.begin();
|
||||
const_point_list_iterator w_last = wgs84_nodes.end();
|
||||
for ( ; w_current != w_last; ++w_current ) {
|
||||
reverse_ele_lookup.push_back( ele_list );
|
||||
}
|
||||
|
||||
// traverse triangle structure building reverse lookup table
|
||||
const_triele_list_iterator current = tri_elements.begin();
|
||||
const_triele_list_iterator last = tri_elements.end();
|
||||
int counter = 0;
|
||||
for ( ; current != last; ++current ) {
|
||||
reverse_ele_lookup[ current->get_n1() ].push_back( counter );
|
||||
reverse_ele_lookup[ current->get_n2() ].push_back( counter );
|
||||
reverse_ele_lookup[ current->get_n3() ].push_back( counter );
|
||||
++counter;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// caclulate the normal for the specified triangle face
|
||||
Point3D FGGenOutput::calc_normal( int i ) {
|
||||
double v1[3], v2[3], normal[3];
|
||||
double temp;
|
||||
|
||||
Point3D p1 = wgs84_nodes[ tri_elements[i].get_n1() ];
|
||||
Point3D p2 = wgs84_nodes[ tri_elements[i].get_n2() ];
|
||||
Point3D p3 = wgs84_nodes[ tri_elements[i].get_n3() ];
|
||||
|
||||
v1[0] = p2.x() - p1.x(); v1[1] = p2.y() - p1.y(); v1[2] = p2.z() - p1.z();
|
||||
v2[0] = p3.x() - p1.x(); v2[1] = p3.y() - p1.y(); v2[2] = p3.z() - p1.z();
|
||||
|
||||
MAT3cross_product(normal, v1, v2);
|
||||
MAT3_NORMALIZE_VEC(normal,temp);
|
||||
|
||||
return Point3D( normal[0], normal[1], normal[2] );
|
||||
}
|
||||
|
||||
|
||||
// build the face normal list
|
||||
void FGGenOutput::gen_face_normals() {
|
||||
// traverse triangle structure building the face normal table
|
||||
|
||||
cout << "calculating face normals" << endl;
|
||||
|
||||
for ( int i = 0; i < (int)tri_elements.size(); i++ ) {
|
||||
// cout << calc_normal( i ) << endl;
|
||||
face_normals.push_back( calc_normal( i ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// calculate the normals for each point in wgs84_nodes
|
||||
void FGGenOutput::gen_normals() {
|
||||
Point3D normal;
|
||||
cout << "caculating node normals" << endl;
|
||||
|
||||
// for each node
|
||||
for ( int i = 0; i < (int)wgs84_nodes.size(); ++i ) {
|
||||
int_list tri_list = reverse_ele_lookup[i];
|
||||
|
||||
int_list_iterator current = tri_list.begin();
|
||||
int_list_iterator last = tri_list.end();
|
||||
|
||||
Point3D average( 0.0 );
|
||||
|
||||
// for each triangle that shares this node
|
||||
for ( ; current != last; ++current ) {
|
||||
normal = face_normals[ *current ];
|
||||
average += normal;
|
||||
// cout << normal << endl;
|
||||
}
|
||||
|
||||
average /= tri_list.size();
|
||||
// cout << "average = " << average << endl;
|
||||
|
||||
point_normals.push_back( average );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// calculate the global bounding sphere. Center is the average of the
|
||||
// points.
|
||||
void FGGenOutput::calc_gbs() {
|
||||
double dist_squared;
|
||||
double radius_squared = 0;
|
||||
|
||||
gbs_center = Point3D( 0.0 );
|
||||
|
||||
const_point_list_iterator current = wgs84_nodes.begin();
|
||||
const_point_list_iterator last = wgs84_nodes.end();
|
||||
|
||||
for ( ; current != last; ++current ) {
|
||||
gbs_center += *current;
|
||||
}
|
||||
|
||||
gbs_center /= wgs84_nodes.size();
|
||||
|
||||
current = wgs84_nodes.begin();
|
||||
for ( ; current != last; ++current ) {
|
||||
dist_squared = gbs_center.distance3Dsquared(*current);
|
||||
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 FGGenOutput::build( const FGArray& array, const FGTriangle& t ) {
|
||||
FGTriNodes trinodes = t.get_out_nodes();
|
||||
|
||||
// copy the geodetic node list into this class
|
||||
geod_nodes = trinodes.get_node_list();
|
||||
|
||||
// copy the triangle list into this class
|
||||
tri_elements = t.get_elelist();
|
||||
|
||||
// build the trifan list
|
||||
cout << "total triangles = " << tri_elements.size() << endl;
|
||||
FGGenFans f;
|
||||
for ( int i = 0; i < FG_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 ( (int)t_current->get_attribute() == i ) {
|
||||
area_tris.push_back( *t_current );
|
||||
}
|
||||
}
|
||||
|
||||
if ( (int)area_tris.size() > 0 ) {
|
||||
cout << "generating fans for area = " << i << endl;
|
||||
fans[i] = f.greedy_build( area_tris );
|
||||
}
|
||||
}
|
||||
|
||||
// generate the point list in wgs-84 coordinates
|
||||
gen_wgs84_points( array );
|
||||
|
||||
// calculate the global bounding sphere
|
||||
calc_gbs();
|
||||
cout << "center = " << gbs_center << " radius = " << gbs_radius << endl;
|
||||
|
||||
// build the node -> element (triangle) reverse lookup table
|
||||
gen_node_ele_lookup_table();
|
||||
|
||||
// build the face normal list
|
||||
gen_face_normals();
|
||||
|
||||
// calculate the normals for each point in wgs84_nodes
|
||||
gen_normals();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// caclulate the bounding sphere for a list of triangle faces
|
||||
void FGGenOutput::calc_group_bounding_sphere( const fan_list& fans,
|
||||
Point3D *center, double *radius )
|
||||
{
|
||||
cout << "calculate group bounding sphere for " << fans.size() << " fans."
|
||||
<< endl;
|
||||
|
||||
// generate a list of unique points from the triangle list
|
||||
FGTriNodes nodes;
|
||||
|
||||
const_fan_list_iterator f_current = fans.begin();
|
||||
const_fan_list_iterator f_last = fans.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
|
||||
Point3D c( 0.0 );
|
||||
point_list points = nodes.get_node_list();
|
||||
// cout << "found " << points.size() << " unique nodes" << endl;
|
||||
point_list_iterator p_current = points.begin();
|
||||
point_list_iterator p_last = points.end();
|
||||
for ( ; p_current != p_last; ++p_current ) {
|
||||
c += *p_current;
|
||||
}
|
||||
c /= 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 = c.distance3Dsquared(*p_current);
|
||||
if ( dist_squared > max_squared ) {
|
||||
max_squared = dist_squared;
|
||||
}
|
||||
}
|
||||
|
||||
*center = c;
|
||||
*radius = sqrt(max_squared);
|
||||
}
|
||||
|
||||
|
||||
// caclulate the bounding sphere for the specified triangle face
|
||||
void FGGenOutput::calc_bounding_sphere( const FGTriEle& t,
|
||||
Point3D *center, double *radius )
|
||||
{
|
||||
Point3D c( 0.0 );
|
||||
|
||||
Point3D p1 = wgs84_nodes[ t.get_n1() ];
|
||||
Point3D p2 = wgs84_nodes[ t.get_n2() ];
|
||||
Point3D p3 = wgs84_nodes[ t.get_n3() ];
|
||||
|
||||
c = p1 + p2 + p3;
|
||||
c /= 3;
|
||||
|
||||
double dist_squared;
|
||||
double max_squared = 0;
|
||||
|
||||
dist_squared = c.distance3Dsquared(p1);
|
||||
if ( dist_squared > max_squared ) {
|
||||
max_squared = dist_squared;
|
||||
}
|
||||
|
||||
dist_squared = c.distance3Dsquared(p2);
|
||||
if ( dist_squared > max_squared ) {
|
||||
max_squared = dist_squared;
|
||||
}
|
||||
|
||||
dist_squared = c.distance3Dsquared(p3);
|
||||
if ( dist_squared > max_squared ) {
|
||||
max_squared = dist_squared;
|
||||
}
|
||||
|
||||
*center = c;
|
||||
*radius = sqrt(max_squared);
|
||||
}
|
||||
|
||||
|
||||
// write out the fgfs scenery file
|
||||
int FGGenOutput::write( const string& base, const FGBucket& b ) {
|
||||
Point3D p;
|
||||
|
||||
string dir = base + "/Scenery/" + b.gen_base_path();
|
||||
string command = "mkdir -p " + dir;
|
||||
system(command.c_str());
|
||||
|
||||
string file = dir + "/" + b.gen_index_str();
|
||||
cout << "Output file = " << file << endl;
|
||||
|
||||
FILE *fp;
|
||||
if ( (fp = fopen( file.c_str(), "w" )) == NULL ) {
|
||||
cout << "ERROR: opening " << file << " for writing!" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// write headers
|
||||
fprintf(fp, "# FGFS Scenery Version %s\n", FG_SCENERY_FILE_FORMAT);
|
||||
|
||||
time_t calendar_time = time(NULL);
|
||||
struct tm *local_tm;
|
||||
local_tm = localtime( &calendar_time );
|
||||
char time_str[256];
|
||||
strftime( time_str, 256, "%a %b %d %H:%M:%S %Z %Y", local_tm);
|
||||
fprintf(fp, "# Created %s\n", time_str );
|
||||
fprintf(fp, "\n");
|
||||
|
||||
// write global bounding sphere
|
||||
fprintf(fp, "# gbs %.5f %.5f %.5f %.2f\n",
|
||||
gbs_center.x(), gbs_center.y(), gbs_center.z(), gbs_radius);
|
||||
fprintf(fp, "\n");
|
||||
|
||||
// write nodes
|
||||
fprintf(fp, "# vertex list\n");
|
||||
const_point_list_iterator w_current = wgs84_nodes.begin();
|
||||
const_point_list_iterator w_last = wgs84_nodes.end();
|
||||
for ( ; w_current != w_last; ++w_current ) {
|
||||
p = *w_current - gbs_center;
|
||||
fprintf(fp, "v %.5f %.5f %.5f\n", p.x(), p.y(), p.z());
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
|
||||
// write vertex normals
|
||||
fprintf(fp, "# vertex normal list\n");
|
||||
const_point_list_iterator n_current = point_normals.begin();
|
||||
const_point_list_iterator n_last = point_normals.end();
|
||||
for ( ; n_current != n_last; ++n_current ) {
|
||||
p = *n_current;
|
||||
fprintf(fp, "vn %.5f %.5f %.5f\n", p.x(), p.y(), p.z());
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
|
||||
// write triangles (grouped by type for now)
|
||||
Point3D center;
|
||||
double radius;
|
||||
fprintf(fp, "# triangle groups\n");
|
||||
fprintf(fp, "\n");
|
||||
|
||||
int total_tris = 0;
|
||||
for ( int i = 0; i < FG_MAX_AREA_TYPES; ++i ) {
|
||||
if ( (int)fans[i].size() > 0 ) {
|
||||
string attr_name = get_area_name( (AreaType)i );
|
||||
calc_group_bounding_sphere( fans[i], ¢er, &radius );
|
||||
cout << "writing " << (int)fans[i].size() << " fans for "
|
||||
<< attr_name << endl;
|
||||
|
||||
fprintf(fp, "# usemtl %s\n", attr_name.c_str() );
|
||||
fprintf(fp, "# bs %.4f %.4f %.4f %.2f\n",
|
||||
center.x(), center.y(), center.z(), radius);
|
||||
|
||||
fan_list_iterator f_current = fans[i].begin();
|
||||
fan_list_iterator f_last = fans[i].end();
|
||||
for ( ; f_current != f_last; ++f_current ) {
|
||||
fprintf( fp, "tf" );
|
||||
total_tris += f_current->size() - 2;
|
||||
int_list_iterator i_current = f_current->begin();
|
||||
int_list_iterator i_last = f_current->end();
|
||||
for ( ; i_current != i_last; ++i_current ) {
|
||||
fprintf( fp, " %d", *i_current );
|
||||
}
|
||||
fprintf( fp, "\n" );
|
||||
|
||||
#if 0
|
||||
{
|
||||
int_list_iterator i_current = f_current->begin();
|
||||
int_list_iterator i_last = f_current->end();
|
||||
int center = *i_current;
|
||||
++i_current;
|
||||
int n2 = *i_current;
|
||||
++i_current;
|
||||
for ( ; i_current != i_last; ++i_current ) {
|
||||
int n3 = *i_current;
|
||||
fprintf( fp, "f %d %d %d\n", center, n2, n3 );
|
||||
n2 = n3;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
fprintf( fp, "\n" );
|
||||
}
|
||||
}
|
||||
cout << "wrote " << total_tris << " tris to output file" << endl;
|
||||
|
||||
fclose(fp);
|
||||
|
||||
command = "gzip --force --best " + file;
|
||||
system(command.c_str());
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.10 1999/03/31 23:46:57 curt
|
||||
// Debugging output tweaks.
|
||||
//
|
||||
// Revision 1.9 1999/03/31 13:26:40 curt
|
||||
// Debugging output tweeaks.
|
||||
//
|
||||
// Revision 1.8 1999/03/31 05:35:05 curt
|
||||
// Fixed bug in genfans (deleting the wrong triangles from the available pool.)
|
||||
//
|
||||
// Revision 1.7 1999/03/30 23:50:43 curt
|
||||
// Modifications to fanify by attribute.
|
||||
//
|
||||
// Revision 1.6 1999/03/29 13:11:03 curt
|
||||
// Shuffled stl type names a bit.
|
||||
// Began adding support for tri-fanning (or maybe other arrangments too.)
|
||||
//
|
||||
// Revision 1.5 1999/03/27 14:06:42 curt
|
||||
// Tweaks to bounding sphere calculation routines.
|
||||
// Group like triangles together for output to be in a single display list,
|
||||
// even though they are individual, non-fanified, triangles.
|
||||
//
|
||||
// Revision 1.4 1999/03/27 05:23:22 curt
|
||||
// Interpolate real z value of all nodes from dem data.
|
||||
// Write scenery file to correct location.
|
||||
// Pass along correct triangle attributes and write to output file.
|
||||
//
|
||||
// Revision 1.3 1999/03/25 19:04:21 curt
|
||||
// Preparations for outputing scenery file to correct location.
|
||||
//
|
||||
// Revision 1.2 1999/03/23 22:02:03 curt
|
||||
// Worked on creating data to output ... normals, bounding spheres, etc.
|
||||
//
|
||||
// Revision 1.1 1999/03/22 23:51:51 curt
|
||||
// Initial revision.
|
||||
//
|
165
Tools/GenOutput/genobj.hxx
Normal file
165
Tools/GenOutput/genobj.hxx
Normal file
|
@ -0,0 +1,165 @@
|
|||
// 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 - curt@flightgear.org
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
|
||||
|
||||
#ifndef _GENOBJ_HXX
|
||||
#define _GENOBJ_HXX
|
||||
|
||||
|
||||
#ifndef __cplusplus
|
||||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
|
||||
#include <Include/compiler.h>
|
||||
|
||||
#include STL_STRING
|
||||
|
||||
#include <Bucket/newbucket.hxx>
|
||||
#include <Math/fg_geodesy.hxx>
|
||||
#include <Math/point3d.hxx>
|
||||
|
||||
#include <Combine/genfans.hxx>
|
||||
#include <Main/construct_types.hxx>
|
||||
#include <Triangulate/triangle.hxx>
|
||||
|
||||
FG_USING_STD(string);
|
||||
FG_USING_STD(vector);
|
||||
|
||||
|
||||
typedef 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 FGGenOutput {
|
||||
|
||||
private:
|
||||
|
||||
// node list in geodetic coordinats
|
||||
point_list geod_nodes;
|
||||
|
||||
// node list in cartesian coords (wgs84 model)
|
||||
point_list wgs84_nodes;
|
||||
|
||||
// face normal list (for flat shading)
|
||||
point_list face_normals;
|
||||
|
||||
// normal list (for each point) in cart coords (for smooth
|
||||
// shading)
|
||||
point_list point_normals;
|
||||
|
||||
// triangles (by index into point list)
|
||||
triele_list tri_elements;
|
||||
|
||||
// fan list
|
||||
fan_list fans[FG_MAX_AREA_TYPES];
|
||||
|
||||
// for each node, a list of triangle indices that contain this node
|
||||
belongs_to_list reverse_ele_lookup;
|
||||
|
||||
// global bounding sphere
|
||||
Point3D gbs_center;
|
||||
double gbs_radius;
|
||||
|
||||
// build the wgs-84 point list
|
||||
void gen_wgs84_points( const FGArray& array );
|
||||
|
||||
// build the node -> element (triangle) reverse lookup table.
|
||||
// there is an entry for each point containing a list of all the
|
||||
// triangles that share that point.
|
||||
void gen_node_ele_lookup_table();
|
||||
|
||||
// calculate the normals for each point in wgs84_nodes
|
||||
void gen_normals();
|
||||
|
||||
// build the face normal list
|
||||
void gen_face_normals();
|
||||
|
||||
// caclulate the normal for the specified triangle face
|
||||
Point3D calc_normal( int i );
|
||||
|
||||
// calculate the global bounding sphere. Center is the average of
|
||||
// the points.
|
||||
void calc_gbs();
|
||||
|
||||
// caclulate the bounding sphere for a list of triangle faces
|
||||
void calc_group_bounding_sphere( const fan_list& fans,
|
||||
Point3D *center, double *radius );
|
||||
|
||||
// caclulate the bounding sphere for the specified triangle face
|
||||
void calc_bounding_sphere( const FGTriEle& t,
|
||||
Point3D *center, double *radius );
|
||||
|
||||
public:
|
||||
|
||||
// Constructor && Destructor
|
||||
inline FGGenOutput() { }
|
||||
inline ~FGGenOutput() { }
|
||||
|
||||
// build the necessary output structures based on the
|
||||
// triangulation data
|
||||
int build( const FGArray& array, const FGTriangle& t );
|
||||
|
||||
// write out the fgfs scenery file
|
||||
int write( const string& base, const FGBucket& b );
|
||||
};
|
||||
|
||||
|
||||
#endif // _GENOBJ_HXX
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.9 1999/03/31 23:46:58 curt
|
||||
// Debugging output tweaks.
|
||||
//
|
||||
// Revision 1.8 1999/03/30 23:50:44 curt
|
||||
// Modifications to fanify by attribute.
|
||||
//
|
||||
// Revision 1.7 1999/03/29 13:11:04 curt
|
||||
// Shuffled stl type names a bit.
|
||||
// Began adding support for tri-fanning (or maybe other arrangments too.)
|
||||
//
|
||||
// Revision 1.6 1999/03/27 14:06:43 curt
|
||||
// Tweaks to bounding sphere calculation routines.
|
||||
// Group like triangles together for output to be in a single display list,
|
||||
// even though they are individual, non-fanified, triangles.
|
||||
//
|
||||
// Revision 1.5 1999/03/27 05:23:23 curt
|
||||
// Interpolate real z value of all nodes from dem data.
|
||||
// Write scenery file to correct location.
|
||||
// Pass along correct triangle attributes and write to output file.
|
||||
//
|
||||
// Revision 1.4 1999/03/25 19:04:22 curt
|
||||
// Preparations for outputing scenery file to correct location.
|
||||
//
|
||||
// Revision 1.3 1999/03/23 22:02:04 curt
|
||||
// Worked on creating data to output ... normals, bounding spheres, etc.
|
||||
//
|
||||
// Revision 1.2 1999/03/23 17:44:49 curt
|
||||
// Beginning work on generating output scenery.
|
||||
//
|
||||
// Revision 1.1 1999/03/22 23:51:51 curt
|
||||
// Initial revision.
|
||||
//
|
4
Tools/Lib/Makefile.am
Normal file
4
Tools/Lib/Makefile.am
Normal file
|
@ -0,0 +1,4 @@
|
|||
SUBDIRS = \
|
||||
DEM \
|
||||
Polygon \
|
||||
Triangle
|
24
Tools/Main/Makefile.am
Normal file
24
Tools/Main/Makefile.am
Normal file
|
@ -0,0 +1,24 @@
|
|||
bin_PROGRAMS = construct
|
||||
|
||||
construct_SOURCES = construct.cxx construct_types.hxx
|
||||
|
||||
construct_LDADD = \
|
||||
$(top_builddir)/Tools/Construct/Array/libArray.a \
|
||||
$(top_builddir)/Tools/Construct/Clipper/libClipper.a \
|
||||
$(top_builddir)/Tools/Construct/GenOutput/libGenOutput.a \
|
||||
$(top_builddir)/Tools/Construct/Combine/libCombine.a \
|
||||
$(top_builddir)/Tools/Construct/Triangulate/libTriangulate.a \
|
||||
$(top_builddir)/Tools/Lib/Polygon/libPolygon.a \
|
||||
$(top_builddir)/Tools/Lib/Triangle/libTriangle.a \
|
||||
$(top_builddir)/Lib/Bucket/libBucket.a \
|
||||
$(top_builddir)/Lib/Math/libMath.a \
|
||||
$(top_builddir)/Lib/Misc/libMisc.a \
|
||||
$(top_builddir)/Lib/Debug/libDebug.a \
|
||||
$(top_builddir)/Lib/zlib/libz.a \
|
||||
-lgpc -lgfc
|
||||
|
||||
INCLUDES += \
|
||||
-I$(top_builddir) \
|
||||
-I$(top_builddir)/Lib \
|
||||
-I$(top_builddir)/Tools/Lib \
|
||||
-I$(top_builddir)/Tools/Construct
|
373
Tools/Main/construct.cxx
Normal file
373
Tools/Main/construct.cxx
Normal file
|
@ -0,0 +1,373 @@
|
|||
// main.cxx -- top level construction routines
|
||||
//
|
||||
// Written by Curtis Olson, started March 1999.
|
||||
//
|
||||
// Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
|
||||
|
||||
#include <sys/types.h> // for directory reading
|
||||
#include <dirent.h> // for directory reading
|
||||
|
||||
#include <Bucket/newbucket.hxx>
|
||||
#include <Include/fg_constants.h>
|
||||
|
||||
#include <Debug/logstream.hxx>
|
||||
#include <Array/array.hxx>
|
||||
#include <Clipper/clipper.hxx>
|
||||
#include <GenOutput/genobj.hxx>
|
||||
#include <Triangulate/triangle.hxx>
|
||||
|
||||
|
||||
// load regular grid of elevation data (dem based), return list of
|
||||
// fitted nodes
|
||||
int load_dem(const string& work_base, FGBucket& b, FGArray& array) {
|
||||
point_list result;
|
||||
string base = b.gen_base_path();
|
||||
|
||||
string dem_path = work_base + ".dem" + "/Scenery/" + base
|
||||
+ "/" + b.gen_index_str() + ".dem";
|
||||
cout << "dem_path = " << dem_path << endl;
|
||||
|
||||
if ( ! array.open(dem_path) ) {
|
||||
cout << "ERROR: cannot open " << dem_path << endl;
|
||||
}
|
||||
|
||||
array.parse( b );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// fit dem nodes, return number of fitted nodes
|
||||
int fit_dem(FGArray& array, int error) {
|
||||
return array.fit( error );
|
||||
}
|
||||
|
||||
|
||||
// do actual scan of directory and loading of files
|
||||
int actual_load_polys( const string& dir, FGBucket& b, FGClipper& clipper ) {
|
||||
int counter = 0;
|
||||
string base = b.gen_base_path();
|
||||
string tile_str = b.gen_index_str();
|
||||
string ext;
|
||||
|
||||
DIR *d;
|
||||
struct dirent *de;
|
||||
|
||||
if ( (d = opendir( dir.c_str() )) == NULL ) {
|
||||
cout << "cannot open directory " << dir << "\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
// load all matching polygon files
|
||||
string file, f_index, full_path;
|
||||
int pos;
|
||||
while ( (de = readdir(d)) != NULL ) {
|
||||
file = de->d_name;
|
||||
pos = file.find(".");
|
||||
f_index = file.substr(0, pos);
|
||||
|
||||
if ( tile_str == f_index ) {
|
||||
ext = file.substr(pos + 1);
|
||||
cout << file << " " << f_index << " '" << ext << "'" << endl;
|
||||
full_path = dir + "/" + file;
|
||||
if ( (ext == "dem") || (ext == "dem.gz") ) {
|
||||
// skip
|
||||
} else {
|
||||
cout << "ext = '" << ext << "'" << endl;
|
||||
clipper.load_polys( full_path );
|
||||
++counter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return counter;
|
||||
}
|
||||
|
||||
|
||||
// load all 2d polygons matching the specified base path and clip
|
||||
// against each other to resolve any overlaps
|
||||
int load_polys( const string& work_base, FGBucket& b, FGClipper& clipper) {
|
||||
string base = b.gen_base_path();
|
||||
int result;
|
||||
|
||||
// initialize clipper
|
||||
clipper.init();
|
||||
|
||||
// load airports
|
||||
string poly_path = work_base + ".apt" + "/Scenery/" + base;
|
||||
cout << "poly_path = " << poly_path << endl;
|
||||
result = actual_load_polys( poly_path, b, clipper );
|
||||
cout << " loaded " << result << " polys" << endl;
|
||||
|
||||
// load hydro
|
||||
poly_path = work_base + ".hydro" + "/Scenery/" + base;
|
||||
cout << "poly_path = " << poly_path << endl;
|
||||
result = actual_load_polys( poly_path, b, clipper );
|
||||
cout << " loaded " << result << " polys" << endl;
|
||||
|
||||
point2d min, max;
|
||||
min.x = b.get_center_lon() - 0.5 * b.get_width();
|
||||
min.y = b.get_center_lat() - 0.5 * b.get_height();
|
||||
max.x = b.get_center_lon() + 0.5 * b.get_width();
|
||||
max.y = b.get_center_lat() + 0.5 * b.get_height();
|
||||
|
||||
// do clipping
|
||||
cout << "clipping polygons" << endl;
|
||||
clipper.clip_all(min, max);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// triangulate the data for each polygon
|
||||
void do_triangulate( const FGArray& array, const FGClipper& clipper,
|
||||
FGTriangle& t ) {
|
||||
// first we need to consolidate the points of the DEM fit list and
|
||||
// all the polygons into a more "Triangle" friendly format
|
||||
|
||||
point_list corner_list = array.get_corner_node_list();
|
||||
point_list fit_list = array.get_fit_node_list();
|
||||
FGgpcPolyList gpc_polys = clipper.get_polys_clipped();
|
||||
|
||||
cout << "ready to build node list and polygons" << endl;
|
||||
t.build( corner_list, fit_list, gpc_polys );
|
||||
cout << "done building node list and polygons" << endl;
|
||||
|
||||
cout << "ready to do triangulation" << endl;
|
||||
t.run_triangulate();
|
||||
cout << "finished triangulation" << endl;
|
||||
}
|
||||
|
||||
|
||||
// generate the flight gear scenery file
|
||||
void do_output( const string& base, const FGBucket &b, const FGTriangle& t,
|
||||
const FGArray& array, FGGenOutput& output ) {
|
||||
output.build( array, t );
|
||||
output.write( base, b );
|
||||
}
|
||||
|
||||
|
||||
void construct_tile( const string& work_base, const string& output_base,
|
||||
FGBucket& b )
|
||||
{
|
||||
cout << "Construct tile, bucket = " << b << endl;
|
||||
|
||||
// fit with ever increasing error tolerance until we produce <=
|
||||
// 80% of max nodes. We should really have the sim end handle
|
||||
// arbitrarily complex tiles.
|
||||
|
||||
const int min_nodes = 50;
|
||||
const int max_nodes = (int)(MAX_NODES * 0.8);
|
||||
|
||||
bool acceptable = false;
|
||||
double error = 200.0;
|
||||
int count = 0;
|
||||
|
||||
// load and fit grid of elevation data
|
||||
FGArray array;
|
||||
load_dem( work_base, b, array );
|
||||
|
||||
FGTriangle t;
|
||||
|
||||
while ( ! acceptable ) {
|
||||
// fit the data
|
||||
array.fit( error );
|
||||
|
||||
// load and clip 2d polygon data
|
||||
FGClipper clipper;
|
||||
load_polys( work_base, b, clipper );
|
||||
|
||||
// triangulate the data for each polygon
|
||||
do_triangulate( array, clipper, t );
|
||||
|
||||
acceptable = true;
|
||||
|
||||
count = t.get_out_nodes_size();
|
||||
|
||||
if ( (count < min_nodes) && (error >= 25.0) ) {
|
||||
// reduce error tolerance until number of points exceeds the
|
||||
// minimum threshold
|
||||
cout << "produced too few nodes ..." << endl;
|
||||
|
||||
acceptable = false;
|
||||
|
||||
error /= 1.5;
|
||||
cout << "Setting error to " << error << " and retrying fit."
|
||||
<< endl;
|
||||
}
|
||||
|
||||
if ( (count > max_nodes) && (error <= 1000.0) ) {
|
||||
// increase error tolerance until number of points drops below
|
||||
// the maximum threshold
|
||||
cout << "produced too many nodes ..." << endl;
|
||||
|
||||
acceptable = false;
|
||||
|
||||
error *= 1.5;
|
||||
cout << "Setting error to " << error << " and retrying fit."
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
|
||||
cout << "finished fit with error = " << error << " node count = "
|
||||
<< count << endl;
|
||||
|
||||
// generate the output
|
||||
FGGenOutput output;
|
||||
do_output( output_base, b, t, array, output );
|
||||
}
|
||||
|
||||
|
||||
main(int argc, char **argv) {
|
||||
double lon, lat;
|
||||
|
||||
fglog().setLogLevels( FG_ALL, FG_DEBUG );
|
||||
|
||||
if ( argc != 3 ) {
|
||||
cout << "Usage: " << argv[0] << " <work_base> <output_base>" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
string work_base = argv[1];
|
||||
string output_base = argv[2];
|
||||
|
||||
// lon = -146.248360; lat = 61.133950; // PAVD (Valdez, AK)
|
||||
// lon = -110.664244; lat = 33.352890; // P13
|
||||
// lon = -93.211389; lat = 45.145000; // KANE
|
||||
// lon = -92.486188; lat = 44.590190; // KRGK
|
||||
// lon = -89.744682312011719; lat= 29.314495086669922;
|
||||
// lon = -122.488090; lat = 42.743183; // 64S
|
||||
// lon = -114.861097; lat = 35.947480; // 61B
|
||||
// lon = -112.012175; lat = 41.195944; // KOGD
|
||||
// lon = -90.757128; lat = 46.790212; // WI32
|
||||
// lon = -122.220717; lat = 37.721291; // KOAK
|
||||
// lon = -111.721477; lat = 40.215641; // KPVU
|
||||
// lon = -122.309313; lat = 47.448982; // KSEA
|
||||
lon = -148.798131; lat = 63.645099; // AK06 (Danali, AK)
|
||||
|
||||
double min_x = lon - 3;
|
||||
double min_y = lat - 1;
|
||||
FGBucket b_min( min_x, min_y );
|
||||
FGBucket b_max( lon + 3, lat + 1 );
|
||||
|
||||
FGBucket b_omit(550314L);
|
||||
// FGBucket b(517745L);
|
||||
// FGBucket b(-146.248360, 61.133950);
|
||||
// construct_tile( work_base, output_base, b );
|
||||
// exit(0);
|
||||
|
||||
if ( b_min == b_max ) {
|
||||
construct_tile( work_base, output_base, b_min );
|
||||
} else {
|
||||
FGBucket b_cur;
|
||||
int dx, dy, i, j;
|
||||
|
||||
fgBucketDiff(b_min, b_max, &dx, &dy);
|
||||
cout << " construction area spans tile boundaries" << endl;
|
||||
cout << " dx = " << dx << " dy = " << dy << endl;
|
||||
|
||||
for ( j = 0; j <= dy; j++ ) {
|
||||
for ( i = 0; i <= dx; i++ ) {
|
||||
b_cur = fgBucketOffset(min_x, min_y, i, j);
|
||||
|
||||
if ( b_cur != b_omit ) {
|
||||
construct_tile( work_base, output_base, b_cur );
|
||||
}
|
||||
}
|
||||
}
|
||||
// string answer; cin >> answer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.18 1999/04/05 02:16:51 curt
|
||||
// Dynamically update "error" until the resulting tile data scales within
|
||||
// a lower and upper bounds.
|
||||
//
|
||||
// Revision 1.17 1999/04/03 05:22:57 curt
|
||||
// Found a bug in dividing and adding unique verticle segments which could
|
||||
// cause the triangulator to end up in an infinite loop. Basically the code
|
||||
// was correct, but the verticle line test was a bit to selective.
|
||||
//
|
||||
// Revision 1.16 1999/04/01 13:52:12 curt
|
||||
// Version 0.6.0
|
||||
// Shape name tweak.
|
||||
// Removing tool: FixNode
|
||||
//
|
||||
// Revision 1.15 1999/03/31 23:47:02 curt
|
||||
// Debugging output tweaks.
|
||||
//
|
||||
// Revision 1.14 1999/03/31 13:26:41 curt
|
||||
// Debugging output tweeaks.
|
||||
//
|
||||
// Revision 1.13 1999/03/31 05:35:06 curt
|
||||
// Fixed bug in genfans (deleting the wrong triangles from the available pool.)
|
||||
//
|
||||
// Revision 1.12 1999/03/30 23:51:14 curt
|
||||
// fiddling ...
|
||||
//
|
||||
// Revision 1.11 1999/03/29 13:11:06 curt
|
||||
// Shuffled stl type names a bit.
|
||||
// Began adding support for tri-fanning (or maybe other arrangments too.)
|
||||
//
|
||||
// Revision 1.10 1999/03/27 05:25:02 curt
|
||||
// Fit with a value of 200 rather than 100.
|
||||
// Handle corner nodes separately from the rest of the fitted nodes.
|
||||
// Write scenery file to correct location.
|
||||
// First hack at generating scenery for multiple tiles in one invocation.
|
||||
//
|
||||
// Revision 1.9 1999/03/25 19:04:31 curt
|
||||
// Preparations for outputing scenery file to correct location.
|
||||
// Minor tweaks related to FGBucket usage.
|
||||
//
|
||||
// Revision 1.8 1999/03/23 22:02:17 curt
|
||||
// Worked on creating data to output ... normals, bounding spheres, etc.
|
||||
//
|
||||
// Revision 1.7 1999/03/22 23:48:29 curt
|
||||
// Added GenOutput/
|
||||
//
|
||||
// Revision 1.6 1999/03/21 15:48:01 curt
|
||||
// Removed Dem2node from the Tools fold.
|
||||
// Tweaked the triangulator options to add quality mesh refinement.
|
||||
//
|
||||
// Revision 1.5 1999/03/21 14:02:05 curt
|
||||
// Added a mechanism to dump out the triangle structures for viewing.
|
||||
// Fixed a couple bugs in first pass at triangulation.
|
||||
// - needed to explicitely initialize the polygon accumulator in triangle.cxx
|
||||
// before each polygon rather than depending on the default behavior.
|
||||
// - Fixed a problem with region attribute propagation where I wasn't generating
|
||||
// the hole points correctly.
|
||||
//
|
||||
// Revision 1.4 1999/03/20 20:32:54 curt
|
||||
// First mostly successful tile triangulation works. There's plenty of tweaking
|
||||
// to do, but we are marching in the right direction.
|
||||
//
|
||||
// Revision 1.3 1999/03/19 00:26:52 curt
|
||||
// Minor tweaks ...
|
||||
//
|
||||
// Revision 1.2 1999/03/17 23:49:52 curt
|
||||
// Started work on Triangulate/ section.
|
||||
//
|
||||
// Revision 1.1 1999/03/14 00:03:24 curt
|
||||
// Initial revision.
|
||||
//
|
||||
|
||||
|
58
Tools/Main/construct_types.hxx
Normal file
58
Tools/Main/construct_types.hxx
Normal file
|
@ -0,0 +1,58 @@
|
|||
// construct_types.hxx -- commonly used types in the construction business.
|
||||
//
|
||||
// Written by Curtis Olson, started March 1999.
|
||||
//
|
||||
// Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
|
||||
|
||||
#ifndef _CONSTRUCT_TYPES_HXX
|
||||
#define _CONSTRUCT_TYPES_HXX
|
||||
|
||||
|
||||
#ifndef __cplusplus
|
||||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
|
||||
#include <Include/compiler.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <Math/point3d.hxx>
|
||||
|
||||
FG_USING_STD(vector);
|
||||
|
||||
|
||||
typedef vector < int > int_list;
|
||||
typedef int_list::iterator int_list_iterator;
|
||||
typedef int_list::const_iterator const_int_list_iterator;
|
||||
|
||||
typedef vector < Point3D > point_list;
|
||||
typedef point_list::iterator point_list_iterator;
|
||||
typedef point_list::const_iterator const_point_list_iterator;
|
||||
|
||||
|
||||
#endif // _CONSTRUCT_TYPES_HXX
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.1 1999/03/29 13:19:44 curt
|
||||
// Initial revision.
|
||||
//
|
9
Tools/Makedir/Makefile.am
Normal file
9
Tools/Makedir/Makefile.am
Normal file
|
@ -0,0 +1,9 @@
|
|||
bin_PROGRAMS = makedir
|
||||
|
||||
makedir_SOURCES = makedir.cxx
|
||||
|
||||
makedir_LDADD = \
|
||||
$(top_builddir)/Lib/Bucket/libBucket.a \
|
||||
$(base_LIBS)
|
||||
|
||||
INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib
|
119
Tools/Makedir/makedir.cxx
Normal file
119
Tools/Makedir/makedir.cxx
Normal file
|
@ -0,0 +1,119 @@
|
|||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h> // stat()
|
||||
#include <unistd.h> // stat()
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <Bucket/bucketutils.h>
|
||||
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
#ifndef TRUE
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
char* PathDivider()
|
||||
{
|
||||
return "\\";
|
||||
} // PathDivider
|
||||
|
||||
void ReplaceDivider( char* path )
|
||||
{
|
||||
char div = PathDivider()[0];
|
||||
int i;
|
||||
|
||||
if ( ! path )
|
||||
return;
|
||||
if ( div == '/' )
|
||||
return;
|
||||
|
||||
for ( i = 0; path[i]; i++ )
|
||||
if ( path[i] == '/' )
|
||||
path[i] = div;
|
||||
|
||||
} // ReplaceDivider
|
||||
|
||||
int Exists( char* path )
|
||||
{
|
||||
struct stat statbuff;
|
||||
|
||||
ReplaceDivider( path );
|
||||
if ( path[strlen( path ) - 1] == ':' )
|
||||
return TRUE;
|
||||
if ( _stat( path, &statbuff ) != 0 )
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
} // Exists
|
||||
|
||||
|
||||
void CreateDir( char* path )
|
||||
{
|
||||
if ( ! path || ! strlen( path ) )
|
||||
return;
|
||||
ReplaceDivider( path );
|
||||
// see if the parent exists yet
|
||||
int i; // looping index
|
||||
string parent; // path to parent
|
||||
|
||||
parent = path;
|
||||
for ( i = strlen( parent.c_str() )-1; i >= 0; i-- )
|
||||
if ( parent[i] == PathDivider()[0] )
|
||||
{
|
||||
parent[i] = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
if ( ! Exists( parent.c_str() ) )
|
||||
{
|
||||
CreateDir( parent.c_str() );
|
||||
}
|
||||
|
||||
if ( ! Exists( path ) )
|
||||
{
|
||||
if (mkdir(path, S_IRWXU) != 0 )
|
||||
{
|
||||
cout << "Could not create directory " << path << endl;
|
||||
}else{
|
||||
cout << "CreateDir: " << path << endl;
|
||||
}
|
||||
}
|
||||
|
||||
} // CreateDir
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
string root;
|
||||
|
||||
if(argc != 2)
|
||||
{
|
||||
cout << "Makedir failed needs one argument\n";
|
||||
return(10);
|
||||
}
|
||||
root = argv[1];
|
||||
|
||||
CreateDir(root.c_str());
|
||||
|
||||
return(0);
|
||||
}
|
||||
#else
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
cout << "This program is intended to work with windoze\n";
|
||||
cout << "Other platforms can use mkdir\n";
|
||||
}
|
||||
|
||||
#endif // WIN32
|
||||
|
7
Tools/Polygon/Makefile.am
Normal file
7
Tools/Polygon/Makefile.am
Normal file
|
@ -0,0 +1,7 @@
|
|||
noinst_LIBRARIES = libPolygon.a
|
||||
|
||||
libPolygon_a_SOURCES = \
|
||||
index.cxx index.hxx \
|
||||
names.cxx names.hxx
|
||||
|
||||
INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib
|
79
Tools/Polygon/index.cxx
Normal file
79
Tools/Polygon/index.cxx
Normal file
|
@ -0,0 +1,79 @@
|
|||
// index.cxx -- routines to handle a unique/persistant integer polygon index
|
||||
//
|
||||
// Written by Curtis Olson, started February 1999.
|
||||
//
|
||||
// Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
|
||||
#include <Include/compiler.h>
|
||||
|
||||
#include STL_STRING
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "index.hxx"
|
||||
|
||||
|
||||
static long int poly_index;
|
||||
static string poly_path;
|
||||
|
||||
|
||||
// initialize the unique polygon index counter stored in path
|
||||
bool poly_index_init( string path ) {
|
||||
poly_path = path;
|
||||
|
||||
FILE *fp = fopen( poly_path.c_str(), "r" );
|
||||
|
||||
if ( fp == NULL ) {
|
||||
cout << "Error cannot open " << poly_path << endl;
|
||||
poly_index = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
fscanf( fp, "%ld", &poly_index );
|
||||
|
||||
fclose( fp );
|
||||
}
|
||||
|
||||
|
||||
// increment the persistant counter and return the next poly_index
|
||||
long int poly_index_next() {
|
||||
++poly_index;
|
||||
|
||||
FILE *fp = fopen( poly_path.c_str(), "w" );
|
||||
|
||||
if ( fp == NULL ) {
|
||||
cout << "Error cannot open " << poly_path << " for writing" << endl;
|
||||
}
|
||||
|
||||
fprintf( fp, "%ld\n", poly_index );
|
||||
|
||||
fclose( fp );
|
||||
|
||||
return poly_index;
|
||||
}
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.2 1999/03/19 00:27:30 curt
|
||||
// Use long int for index instead of just int.
|
||||
//
|
||||
// Revision 1.1 1999/02/25 21:30:24 curt
|
||||
// Initial revision.
|
||||
//
|
51
Tools/Polygon/index.hxx
Normal file
51
Tools/Polygon/index.hxx
Normal file
|
@ -0,0 +1,51 @@
|
|||
// index.cxx -- routines to handle a unique/persistant integer polygon index
|
||||
//
|
||||
// Written by Curtis Olson, started February 1999.
|
||||
//
|
||||
// Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
|
||||
|
||||
#ifndef _INDEX_HXX
|
||||
#define _INDEX_HXX
|
||||
|
||||
|
||||
#include <Include/compiler.h>
|
||||
|
||||
#include STL_STRING
|
||||
|
||||
|
||||
// initialize the unique polygon index counter stored in path
|
||||
bool poly_index_init( string path );
|
||||
|
||||
// increment the persistant counter and return the next poly_index
|
||||
long int poly_index_next();
|
||||
|
||||
|
||||
|
||||
#endif // _INDEX_HXX
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.2 1999/03/19 00:27:31 curt
|
||||
// Use long int for index instead of just int.
|
||||
//
|
||||
// Revision 1.1 1999/02/25 21:30:24 curt
|
||||
// Initial revision.
|
||||
//
|
146
Tools/Polygon/names.cxx
Normal file
146
Tools/Polygon/names.cxx
Normal file
|
@ -0,0 +1,146 @@
|
|||
// names.cxx -- process shapefiles names
|
||||
//
|
||||
// Written by Curtis Olson, started February 1999.
|
||||
//
|
||||
// Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
|
||||
#include <Include/compiler.h>
|
||||
|
||||
#include STL_STRING
|
||||
|
||||
#include "names.hxx"
|
||||
|
||||
|
||||
// return area type from text name
|
||||
AreaType get_area_type( string area ) {
|
||||
if ( area == "Default" ) {
|
||||
return DefaultArea;
|
||||
} else if ( area == "AirportKeep" ) {
|
||||
return AirportKeepArea;
|
||||
} else if ( area == "AirportIgnore" ) {
|
||||
return AirportIgnoreArea;
|
||||
} else if ( (area == "Swamp or Marsh")
|
||||
|| (area == "Marsh") ) {
|
||||
return MarshArea;
|
||||
} else if ( (area == "Bay Estuary or Ocean")
|
||||
|| (area == "Ocean") ) {
|
||||
return OceanArea;
|
||||
} else if ( area == "Lake" ) {
|
||||
return LakeArea;
|
||||
} else if ( (area == "Lake Dry")
|
||||
|| (area == "DryLake") ) {
|
||||
return DryLakeArea;
|
||||
} else if ( (area == "Lake Intermittent")
|
||||
|| (area == "IntermittentLake") ) {
|
||||
return IntLakeArea;
|
||||
} else if ( area == "Reservoir" ) {
|
||||
return ReservoirArea;
|
||||
} else if ( (area == "Reservoir Intermittent")
|
||||
|| (area == "IntermittentReservoir") ) {
|
||||
return IntReservoirArea;
|
||||
} else if ( area == "Stream" ) {
|
||||
return StreamArea;
|
||||
} else if ( area == "Canal" ) {
|
||||
return CanalArea;
|
||||
} else if ( area == "Glacier" ) {
|
||||
return GlacierArea;
|
||||
} else if ( area == "Void Area" ) {
|
||||
return VoidArea;
|
||||
} else if ( area == "Null" ) {
|
||||
return NullArea;
|
||||
} else {
|
||||
cout << "unknown area = '" << area << "'" << endl;
|
||||
// cout << "area = " << area << endl;
|
||||
// for ( int i = 0; i < area.length(); i++ ) {
|
||||
// cout << i << ") " << (int)area[i] << endl;
|
||||
// }
|
||||
return UnknownArea;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// return text from of area name
|
||||
string get_area_name( AreaType area ) {
|
||||
if ( area == DefaultArea ) {
|
||||
return "Default";
|
||||
} else if ( area == AirportKeepArea ) {
|
||||
return "AirportKeep";
|
||||
} else if ( area == AirportIgnoreArea ) {
|
||||
return "AirportIgnore";
|
||||
} else if ( area == MarshArea ) {
|
||||
return "Marsh";
|
||||
} else if ( area == OceanArea ) {
|
||||
return "Ocean";
|
||||
} else if ( area == LakeArea ) {
|
||||
return "Lake";
|
||||
} else if ( area == DryLakeArea ) {
|
||||
return "DryLake";
|
||||
} else if ( area == IntLakeArea ) {
|
||||
return "IntermittentLake";
|
||||
} else if ( area == ReservoirArea ) {
|
||||
return "Reservoir";
|
||||
} else if ( area == IntReservoirArea ) {
|
||||
return "IntermittentReservoir";
|
||||
} else if ( area == StreamArea ) {
|
||||
return "Stream";
|
||||
} else if ( area == CanalArea ) {
|
||||
return "Canal";
|
||||
} else if ( area == GlacierArea ) {
|
||||
return "Glacier";
|
||||
} else if ( area == VoidArea ) {
|
||||
return "VoidArea";
|
||||
} else if ( area == NullArea ) {
|
||||
return "Null";
|
||||
} else {
|
||||
cout << "unknown area code = " << (int)area << endl;
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.7 1999/04/01 13:52:13 curt
|
||||
// Version 0.6.0
|
||||
// Shape name tweak.
|
||||
// Removing tool: FixNode
|
||||
//
|
||||
// Revision 1.6 1999/03/27 05:31:24 curt
|
||||
// Make 0 the default area type since this corresponds well with the conventions
|
||||
// used by the triangulator.
|
||||
//
|
||||
// Revision 1.5 1999/03/22 23:49:29 curt
|
||||
// Moved AreaType get_shapefile_type(GDBFile *dbf, int rec) to where it
|
||||
// belongs in ShapeFile/
|
||||
//
|
||||
// Revision 1.4 1999/03/13 18:47:04 curt
|
||||
// Removed an unused variable.
|
||||
//
|
||||
// Revision 1.3 1999/03/02 01:03:58 curt
|
||||
// Added more reverse lookup support.
|
||||
//
|
||||
// Revision 1.2 1999/03/01 15:35:52 curt
|
||||
// Generalized the routines a bit to make them more useful.
|
||||
//
|
||||
// Revision 1.1 1999/02/25 21:30:24 curt
|
||||
// Initial revision.
|
||||
//
|
||||
// Revision 1.1 1999/02/23 01:29:05 curt
|
||||
// Additional progress.
|
||||
//
|
89
Tools/Polygon/names.hxx
Normal file
89
Tools/Polygon/names.hxx
Normal file
|
@ -0,0 +1,89 @@
|
|||
// names.hxx -- process shapefiles names
|
||||
//
|
||||
// Written by Curtis Olson, started February 1999.
|
||||
//
|
||||
// Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
|
||||
|
||||
#ifndef _NAMES_HXX
|
||||
#define _NAMES_HXX
|
||||
|
||||
|
||||
#include <Include/compiler.h>
|
||||
|
||||
#include STL_STRING
|
||||
|
||||
FG_USING_STD(string);
|
||||
|
||||
|
||||
// Posible shape file types. Note the order of these is important and
|
||||
// defines the priority of these shapes if they should intersect. The
|
||||
// smaller the number, the higher the priority.
|
||||
enum AreaType {
|
||||
DefaultArea = 0,
|
||||
AirportKeepArea = 1,
|
||||
AirportIgnoreArea = 2,
|
||||
OceanArea = 3,
|
||||
LakeArea = 4,
|
||||
DryLakeArea = 5,
|
||||
IntLakeArea = 6,
|
||||
ReservoirArea = 7,
|
||||
IntReservoirArea = 8,
|
||||
StreamArea = 9,
|
||||
CanalArea = 10,
|
||||
GlacierArea = 11,
|
||||
MarshArea = 12,
|
||||
VoidArea = 9997,
|
||||
NullArea = 9998,
|
||||
UnknownArea = 9999
|
||||
};
|
||||
|
||||
|
||||
// return area type from text name
|
||||
AreaType get_area_type( string area );
|
||||
|
||||
// return text form of area name
|
||||
string get_area_name( AreaType area );
|
||||
|
||||
|
||||
#endif // _NAMES_HXX
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.5 1999/03/27 05:31:25 curt
|
||||
// Make 0 the default area type since this corresponds well with the conventions
|
||||
// used by the triangulator.
|
||||
//
|
||||
// Revision 1.4 1999/03/22 23:49:30 curt
|
||||
// Moved AreaType get_shapefile_type(GDBFile *dbf, int rec) to where it
|
||||
// belongs in ShapeFile/
|
||||
//
|
||||
// Revision 1.3 1999/03/01 15:35:53 curt
|
||||
// Generalized the routines a bit to make them more useful.
|
||||
//
|
||||
// Revision 1.2 1999/02/26 22:10:42 curt
|
||||
// Updated names and priorities of area types.
|
||||
//
|
||||
// Revision 1.1 1999/02/25 21:30:24 curt
|
||||
// Initial revision.
|
||||
//
|
||||
// Revision 1.1 1999/02/23 01:29:05 curt
|
||||
// Additional progress.
|
||||
//
|
6
Tools/Prep/Makefile.am
Normal file
6
Tools/Prep/Makefile.am
Normal file
|
@ -0,0 +1,6 @@
|
|||
SUBDIRS = \
|
||||
DemChop \
|
||||
DemInfo \
|
||||
DemRaw2ascii \
|
||||
GenAirports \
|
||||
ShapeFile
|
14
Tools/ShapeFile/Makefile.am
Normal file
14
Tools/ShapeFile/Makefile.am
Normal file
|
@ -0,0 +1,14 @@
|
|||
bin_PROGRAMS = shape-decode
|
||||
|
||||
shape_decode_SOURCES = main.cxx shape.cxx shape.hxx
|
||||
|
||||
shape_decode_LDADD = \
|
||||
$(top_builddir)/Tools/Lib/Polygon/libPolygon.a \
|
||||
$(top_builddir)/Lib/Debug/libDebug.a \
|
||||
$(top_builddir)/Lib/Bucket/libBucket.a \
|
||||
$(top_builddir)/Lib/Misc/libMisc.a \
|
||||
$(top_builddir)/Lib/zlib/libz.a \
|
||||
-lgfc -lgpc
|
||||
|
||||
|
||||
INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib -I$(top_builddir)/Tools/Lib
|
333
Tools/ShapeFile/main.cxx
Normal file
333
Tools/ShapeFile/main.cxx
Normal file
|
@ -0,0 +1,333 @@
|
|||
// main.cxx -- process shapefiles and extract polygon outlines,
|
||||
// clipping against and sorting them into the revelant
|
||||
// tiles.
|
||||
//
|
||||
// Written by Curtis Olson, started February 1999.
|
||||
//
|
||||
// Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
|
||||
|
||||
// Include Geographic Foundation Classes library
|
||||
|
||||
// libgfc.a includes need this bit o' strangeness
|
||||
#if defined ( linux )
|
||||
# define _LINUX_
|
||||
#endif
|
||||
#include <gfc/gadt_polygon.h>
|
||||
#include <gfc/gdbf.h>
|
||||
#include <gfc/gshapefile.h>
|
||||
#undef E
|
||||
#undef DEG_TO_RAD
|
||||
#undef RAD_TO_DEG
|
||||
|
||||
// include Generic Polygon Clipping Library
|
||||
extern "C" {
|
||||
#include <gpc.h>
|
||||
}
|
||||
|
||||
#include <Include/compiler.h>
|
||||
|
||||
#include STL_STRING
|
||||
|
||||
#include <Debug/logstream.hxx>
|
||||
|
||||
#include <Polygon/index.hxx>
|
||||
#include <Polygon/names.hxx>
|
||||
#include "shape.hxx"
|
||||
|
||||
|
||||
// return the type of the shapefile record
|
||||
AreaType get_shapefile_type(GDBFile *dbf, int rec) {
|
||||
// GDBFieldDesc *fdesc[128]; // 128 is an arbitrary number here
|
||||
GDBFValue *fields; //an array of field values
|
||||
char* dbf_rec; //a record containing all the fields
|
||||
|
||||
// grab the meta-information for all the fields
|
||||
// this applies to all the records in the DBF file.
|
||||
// for ( int i = 0; i < dbf->numFields(); i++ ) {
|
||||
// fdesc[i] = dbf->getFieldDesc(i);
|
||||
// cout << i << ") " << fdesc[i]->name << endl;
|
||||
// }
|
||||
|
||||
// this is the whole name record
|
||||
dbf_rec = dbf->getRecord( rec );
|
||||
|
||||
// parse it into individual fields
|
||||
if ( dbf_rec ) {
|
||||
fields = dbf->recordDeform( dbf_rec );
|
||||
} else {
|
||||
return UnknownArea;
|
||||
}
|
||||
|
||||
string area = fields[4].str_v;
|
||||
// strip leading spaces
|
||||
while ( area[0] == ' ' ) {
|
||||
area = area.substr(1, area.length() - 1);
|
||||
}
|
||||
// strip trailing spaces
|
||||
while ( area[area.length() - 1] == ' ' ) {
|
||||
area = area.substr(0, area.length() - 1);
|
||||
}
|
||||
// strip other junk encountered
|
||||
while ( (int)area[area.length() - 1] == 9 ) {
|
||||
area = area.substr(0, area.length() - 1);
|
||||
}
|
||||
|
||||
return get_area_type( area );
|
||||
}
|
||||
|
||||
|
||||
int main( int argc, char **argv ) {
|
||||
gpc_polygon gpc_shape;
|
||||
int i, j;
|
||||
|
||||
fglog().setLogLevels( FG_ALL, FG_DEBUG );
|
||||
|
||||
if ( argc != 3 ) {
|
||||
FG_LOG( FG_GENERAL, FG_ALERT, "Usage: " << argv[0]
|
||||
<< " <shape_file> <work_dir>" );
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
FG_LOG( FG_GENERAL, FG_DEBUG, "Opening " << argv[1] << " for reading." );
|
||||
|
||||
// make work directory
|
||||
string work_dir = argv[2];
|
||||
string command = "mkdir -p " + work_dir;
|
||||
system( command.c_str() );
|
||||
|
||||
// initialize persistant polygon counter
|
||||
string counter_file = work_dir + "/../work.counter";
|
||||
poly_index_init( counter_file );
|
||||
|
||||
// initialize structure for building gpc polygons
|
||||
shape_utils_init();
|
||||
|
||||
GShapeFile * sf = new GShapeFile( argv[1] );
|
||||
GDBFile *dbf = new GDBFile( argv[1] );
|
||||
string path = argv[2];
|
||||
|
||||
GPolygon shape;
|
||||
double *coords; // in decimal degrees
|
||||
int n_vertices;
|
||||
|
||||
FG_LOG( FG_GENERAL, FG_INFO, "shape file records = " << sf->numRecords() );
|
||||
|
||||
GShapeFile::ShapeType t = sf->shapeType();
|
||||
if ( t != GShapeFile::av_Polygon ) {
|
||||
FG_LOG( FG_GENERAL, FG_ALERT, "Can't handle non-polygon shape files" );
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
for ( i = 0; i < sf->numRecords(); i++ ) {
|
||||
//fetch i-th record (shape)
|
||||
sf->getShapeRec(i, &shape);
|
||||
FG_LOG( FG_GENERAL, FG_DEBUG, "Record = " << i << " rings = "
|
||||
<< shape.numRings() );
|
||||
|
||||
AreaType area = get_shapefile_type(dbf, i);
|
||||
FG_LOG( FG_GENERAL, FG_DEBUG, "area type = " << get_area_name(area)
|
||||
<< " (" << (int)area << ")" );
|
||||
|
||||
FG_LOG( FG_GENERAL, FG_INFO, " record = " << i
|
||||
<< " ring = " << 0 );
|
||||
|
||||
if ( area == MarshArea ) {
|
||||
// interior of polygon is marsh, holes are water
|
||||
|
||||
// do main outline first
|
||||
init_shape(&gpc_shape);
|
||||
n_vertices = shape.getRing(0, coords);
|
||||
add_to_shape(n_vertices, coords, &gpc_shape);
|
||||
process_shape(path, area, &gpc_shape);
|
||||
free_shape(&gpc_shape);
|
||||
|
||||
// do lakes (individually) next
|
||||
for ( j = 1; j < shape.numRings(); j++ ) {
|
||||
FG_LOG( FG_GENERAL, FG_INFO, " record = " << i
|
||||
<< " ring = " << j );
|
||||
init_shape(&gpc_shape);
|
||||
n_vertices = shape.getRing(j, coords);
|
||||
add_to_shape(n_vertices, coords, &gpc_shape);
|
||||
process_shape(path, LakeArea, &gpc_shape);
|
||||
free_shape(&gpc_shape);
|
||||
}
|
||||
} else if ( area == OceanArea ) {
|
||||
// interior of polygon is ocean, holes are islands
|
||||
|
||||
init_shape(&gpc_shape);
|
||||
for ( j = 0; j < shape.numRings(); j++ ) {
|
||||
n_vertices = shape.getRing(j, coords);
|
||||
add_to_shape(n_vertices, coords, &gpc_shape);
|
||||
}
|
||||
process_shape(path, area, &gpc_shape);
|
||||
free_shape(&gpc_shape);
|
||||
} else if ( area == LakeArea ) {
|
||||
// interior of polygon is lake, holes are islands
|
||||
|
||||
init_shape(&gpc_shape);
|
||||
for ( j = 0; j < shape.numRings(); j++ ) {
|
||||
n_vertices = shape.getRing(j, coords);
|
||||
add_to_shape(n_vertices, coords, &gpc_shape);
|
||||
}
|
||||
process_shape(path, area, &gpc_shape);
|
||||
free_shape(&gpc_shape);
|
||||
} else if ( area == DryLakeArea ) {
|
||||
// interior of polygon is dry lake, holes are islands
|
||||
|
||||
init_shape(&gpc_shape);
|
||||
for ( j = 0; j < shape.numRings(); j++ ) {
|
||||
n_vertices = shape.getRing(j, coords);
|
||||
add_to_shape(n_vertices, coords, &gpc_shape);
|
||||
}
|
||||
process_shape(path, area, &gpc_shape);
|
||||
free_shape(&gpc_shape);
|
||||
} else if ( area == IntLakeArea ) {
|
||||
// interior of polygon is intermittent lake, holes are islands
|
||||
|
||||
init_shape(&gpc_shape);
|
||||
for ( j = 0; j < shape.numRings(); j++ ) {
|
||||
n_vertices = shape.getRing(j, coords);
|
||||
add_to_shape(n_vertices, coords, &gpc_shape);
|
||||
}
|
||||
process_shape(path, area, &gpc_shape);
|
||||
free_shape(&gpc_shape);
|
||||
} else if ( area == ReservoirArea ) {
|
||||
// interior of polygon is reservoir, holes are islands
|
||||
|
||||
init_shape(&gpc_shape);
|
||||
for ( j = 0; j < shape.numRings(); j++ ) {
|
||||
n_vertices = shape.getRing(j, coords);
|
||||
add_to_shape(n_vertices, coords, &gpc_shape);
|
||||
}
|
||||
process_shape(path, area, &gpc_shape);
|
||||
free_shape(&gpc_shape);
|
||||
} else if ( area == IntReservoirArea ) {
|
||||
// interior of polygon is intermittent reservoir, holes are islands
|
||||
|
||||
init_shape(&gpc_shape);
|
||||
for ( j = 0; j < shape.numRings(); j++ ) {
|
||||
n_vertices = shape.getRing(j, coords);
|
||||
add_to_shape(n_vertices, coords, &gpc_shape);
|
||||
}
|
||||
process_shape(path, area, &gpc_shape);
|
||||
free_shape(&gpc_shape);
|
||||
} else if ( area == StreamArea ) {
|
||||
// interior of polygon is stream, holes are islands
|
||||
|
||||
init_shape(&gpc_shape);
|
||||
for ( j = 0; j < shape.numRings(); j++ ) {
|
||||
n_vertices = shape.getRing(j, coords);
|
||||
add_to_shape(n_vertices, coords, &gpc_shape);
|
||||
}
|
||||
process_shape(path, area, &gpc_shape);
|
||||
free_shape(&gpc_shape);
|
||||
} else if ( area == CanalArea ) {
|
||||
// interior of polygon is canal, holes are islands
|
||||
|
||||
init_shape(&gpc_shape);
|
||||
for ( j = 0; j < shape.numRings(); j++ ) {
|
||||
n_vertices = shape.getRing(j, coords);
|
||||
add_to_shape(n_vertices, coords, &gpc_shape);
|
||||
}
|
||||
process_shape(path, area, &gpc_shape);
|
||||
free_shape(&gpc_shape);
|
||||
} else if ( area == GlacierArea ) {
|
||||
// interior of polygon is glacier, holes are dry land
|
||||
|
||||
init_shape(&gpc_shape);
|
||||
for ( j = 0; j < shape.numRings(); j++ ) {
|
||||
n_vertices = shape.getRing(j, coords);
|
||||
add_to_shape(n_vertices, coords, &gpc_shape);
|
||||
}
|
||||
process_shape(path, area, &gpc_shape);
|
||||
free_shape(&gpc_shape);
|
||||
} else if ( area == VoidArea ) {
|
||||
// interior is ????
|
||||
|
||||
// skip for now
|
||||
FG_LOG( FG_GENERAL, FG_ALERT, "Void area ... SKIPPING!" );
|
||||
|
||||
if ( shape.numRings() > 1 ) {
|
||||
FG_LOG( FG_GENERAL, FG_ALERT, " Void area with holes!" );
|
||||
// exit(-1);
|
||||
}
|
||||
|
||||
init_shape(&gpc_shape);
|
||||
for ( j = 0; j < shape.numRings(); j++ ) {
|
||||
n_vertices = shape.getRing(j, coords);
|
||||
add_to_shape(n_vertices, coords, &gpc_shape);
|
||||
}
|
||||
// process_shape(path, area, &gpc_shape);
|
||||
free_shape(&gpc_shape);
|
||||
} else if ( area == NullArea ) {
|
||||
// interior is ????
|
||||
|
||||
// skip for now
|
||||
FG_LOG( FG_GENERAL, FG_ALERT, "Null area ... SKIPPING!" );
|
||||
|
||||
if ( shape.numRings() > 1 ) {
|
||||
FG_LOG( FG_GENERAL, FG_ALERT, " Null area with holes!" );
|
||||
// exit(-1);
|
||||
}
|
||||
|
||||
init_shape(&gpc_shape);
|
||||
for ( j = 0; j < shape.numRings(); j++ ) {
|
||||
n_vertices = shape.getRing(j, coords);
|
||||
add_to_shape(n_vertices, coords, &gpc_shape);
|
||||
}
|
||||
// process_shape(path, area, &gpc_shape);
|
||||
free_shape(&gpc_shape);
|
||||
} else {
|
||||
FG_LOG( FG_GENERAL, FG_ALERT, "Uknown area!" );
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.8 1999/03/22 23:49:36 curt
|
||||
// Moved AreaType get_shapefile_type(GDBFile *dbf, int rec) to where it
|
||||
// belongs in ShapeFile/
|
||||
//
|
||||
// Revision 1.7 1999/03/17 23:51:29 curt
|
||||
// Changed polygon index counter file.
|
||||
//
|
||||
// Revision 1.6 1999/03/02 01:04:28 curt
|
||||
// Don't crash when work directory doesn't exist ... create it.
|
||||
//
|
||||
// Revision 1.5 1999/03/01 15:36:28 curt
|
||||
// Tweaked a function call name in "names.hxx".
|
||||
//
|
||||
// Revision 1.4 1999/02/25 21:31:05 curt
|
||||
// First working version???
|
||||
//
|
||||
// Revision 1.3 1999/02/23 01:29:04 curt
|
||||
// Additional progress.
|
||||
//
|
||||
// Revision 1.2 1999/02/19 19:05:18 curt
|
||||
// Working on clipping shapes and distributing into buckets.
|
||||
//
|
||||
// Revision 1.1 1999/02/15 19:10:23 curt
|
||||
// Initial revision.
|
||||
//
|
255
Tools/ShapeFile/shape.cxx
Normal file
255
Tools/ShapeFile/shape.cxx
Normal file
|
@ -0,0 +1,255 @@
|
|||
// shape.cxx -- shape/gpc utils
|
||||
//
|
||||
// Written by Curtis Olson, started February 1999.
|
||||
//
|
||||
// Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
|
||||
|
||||
#include <Include/compiler.h>
|
||||
|
||||
#include STL_STRING
|
||||
|
||||
#include <Bucket/newbucket.hxx>
|
||||
#include <Debug/logstream.hxx>
|
||||
|
||||
#include <Polygon/index.hxx>
|
||||
#include <Polygon/names.hxx>
|
||||
#include "shape.hxx"
|
||||
|
||||
|
||||
#define FG_MAX_VERTICES 100000
|
||||
static gpc_vertex_list v_list;
|
||||
|
||||
|
||||
class point2d {
|
||||
public:
|
||||
double x, y;
|
||||
};
|
||||
|
||||
|
||||
static void clip_and_write_poly( string root, long int p_index, AreaType area,
|
||||
FGBucket b, gpc_polygon *shape ) {
|
||||
point2d c, min, max;
|
||||
c.x = b.get_center_lon();
|
||||
c.y = b.get_center_lat();
|
||||
double span = bucket_span(c.y);
|
||||
gpc_polygon base, result;
|
||||
char tile_name[256], poly_index[256];
|
||||
|
||||
// calculate bucket dimensions
|
||||
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 - FG_HALF_BUCKET_SPAN;
|
||||
max.y = c.y + FG_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 {
|
||||
FG_LOG ( FG_GENERAL, FG_ALERT,
|
||||
"Out of range latitude in clip_and_write_poly() = " << c.y );
|
||||
}
|
||||
|
||||
FG_LOG( FG_GENERAL, FG_INFO, " (" << min.x << "," << min.y << ") ("
|
||||
<< max.x << "," << max.y << ")" );
|
||||
|
||||
// set up clipping tile
|
||||
v_list.vertex[0].x = min.x;
|
||||
v_list.vertex[0].y = min.y;
|
||||
|
||||
v_list.vertex[1].x = max.x;
|
||||
v_list.vertex[1].y = min.y;
|
||||
|
||||
v_list.vertex[2].x = max.x;
|
||||
v_list.vertex[2].y = max.y;
|
||||
|
||||
v_list.vertex[3].x = min.x;
|
||||
v_list.vertex[3].y = max.y;
|
||||
|
||||
v_list.num_vertices = 4;
|
||||
|
||||
base.num_contours = 0;
|
||||
base.contour = NULL;
|
||||
gpc_add_contour( &base, &v_list );
|
||||
|
||||
// FG_LOG( FG_GENERAL, FG_DEBUG, "base = 4 vertices" );
|
||||
|
||||
/*
|
||||
FILE *bfp= fopen("base", "w");
|
||||
gpc_write_polygon(bfp, &base);
|
||||
fclose(bfp);
|
||||
*/
|
||||
|
||||
gpc_polygon_clip(GPC_INT, &base, shape, &result);
|
||||
|
||||
if ( result.num_contours > 0 ) {
|
||||
long int t_index = b.gen_index();
|
||||
string path = root + "/Scenery/" + b.gen_base_path();
|
||||
string command = "mkdir -p " + path;
|
||||
system( command.c_str() );
|
||||
|
||||
sprintf( tile_name, "%ld", t_index );
|
||||
string polyfile = path + "/" + tile_name;
|
||||
|
||||
sprintf( poly_index, "%ld", p_index );
|
||||
polyfile += ".";
|
||||
polyfile += poly_index;
|
||||
|
||||
string poly_type = get_area_name( area );
|
||||
if ( poly_type == "Unknown" ) {
|
||||
cout << "unknown area type in clip_and_write_poly()!" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
FILE *rfp= fopen( polyfile.c_str(), "w" );
|
||||
fprintf( rfp, "%s\n", poly_type.c_str() );
|
||||
gpc_write_polygon( rfp, &result );
|
||||
fclose( rfp );
|
||||
}
|
||||
|
||||
gpc_free_polygon(&base);
|
||||
gpc_free_polygon(&result);
|
||||
}
|
||||
|
||||
|
||||
// Initialize structure we use to create polygons for the gpc library
|
||||
bool shape_utils_init() {
|
||||
v_list.num_vertices = 0;
|
||||
v_list.vertex = new gpc_vertex[FG_MAX_VERTICES];;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// initialize a gpc_polygon
|
||||
void init_shape(gpc_polygon *shape) {
|
||||
shape->num_contours = 0;
|
||||
shape->contour = NULL;
|
||||
}
|
||||
|
||||
|
||||
// make a gpc_polygon
|
||||
void add_to_shape(int count, double *coords, gpc_polygon *shape) {
|
||||
|
||||
for ( int i = 0; i < count; i++ ) {
|
||||
v_list.vertex[i].x = coords[i*2+0];
|
||||
v_list.vertex[i].y = coords[i*2+1];
|
||||
}
|
||||
|
||||
v_list.num_vertices = count;
|
||||
gpc_add_contour( shape, &v_list );
|
||||
}
|
||||
|
||||
|
||||
// process shape (write polygon to all intersecting tiles)
|
||||
void process_shape(string path, AreaType area, gpc_polygon *gpc_shape) {
|
||||
point2d min, max;
|
||||
long int index;
|
||||
int i, j;
|
||||
|
||||
min.x = min.y = 200.0;
|
||||
max.x = max.y = -200.0;
|
||||
|
||||
// find min/max of polygon
|
||||
for ( i = 0; i < gpc_shape->num_contours; i++ ) {
|
||||
for ( j = 0; j < gpc_shape->contour[i].num_vertices; j++ ) {
|
||||
double x = gpc_shape->contour[i].vertex[j].x;
|
||||
double y = gpc_shape->contour[i].vertex[j].y;
|
||||
|
||||
if ( x < min.x ) { min.x = x; }
|
||||
if ( y < min.y ) { min.y = y; }
|
||||
if ( x > max.x ) { max.x = x; }
|
||||
if ( y > max.y ) { max.y = y; }
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
FILE *sfp= fopen("shape", "w");
|
||||
gpc_write_polygon(sfp, gpc_shape);
|
||||
fclose(sfp);
|
||||
exit(-1);
|
||||
*/
|
||||
|
||||
// get next polygon index
|
||||
index = poly_index_next();
|
||||
|
||||
FG_LOG( FG_GENERAL, FG_INFO, " min = " << min.x << "," << min.y
|
||||
<< " max = " << max.x << "," << max.y );
|
||||
|
||||
// find buckets for min, and max points of convex hull.
|
||||
// note to self: self, you should think about checking for
|
||||
// polygons that span the date line
|
||||
FGBucket b_min(min.x, min.y);
|
||||
FGBucket b_max(max.x, max.y);
|
||||
FG_LOG( FG_GENERAL, FG_INFO, " Bucket min = " << b_min );
|
||||
FG_LOG( FG_GENERAL, FG_INFO, " Bucket max = " << b_max );
|
||||
|
||||
if ( b_min == b_max ) {
|
||||
clip_and_write_poly( path, index, area, b_min, gpc_shape );
|
||||
} else {
|
||||
FGBucket b_cur;
|
||||
int dx, dy, i, j;
|
||||
|
||||
fgBucketDiff(b_min, b_max, &dx, &dy);
|
||||
FG_LOG( FG_GENERAL, FG_INFO,
|
||||
" polygon spans tile boundaries" );
|
||||
FG_LOG( FG_GENERAL, FG_INFO, " dx = " << dx
|
||||
<< " dy = " << dy );
|
||||
|
||||
if ( (dx > 100) || (dy > 100) ) {
|
||||
FG_LOG( FG_GENERAL, FG_ALERT,
|
||||
"somethings really wrong!!!!" );
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
for ( j = 0; j <= dy; j++ ) {
|
||||
for ( i = 0; i <= dx; i++ ) {
|
||||
b_cur = fgBucketOffset(min.x, min.y, i, j);
|
||||
clip_and_write_poly( path, index, area, b_cur, gpc_shape );
|
||||
}
|
||||
}
|
||||
// string answer; cin >> answer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// free a gpc_polygon
|
||||
void free_shape(gpc_polygon *shape) {
|
||||
gpc_free_polygon(shape);
|
||||
}
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.3 1999/03/19 00:27:41 curt
|
||||
// Use long int for index instead of just int.
|
||||
//
|
||||
// Revision 1.2 1999/02/25 21:31:08 curt
|
||||
// First working version???
|
||||
//
|
||||
// Revision 1.1 1999/02/23 01:29:06 curt
|
||||
// Additional progress.
|
||||
//
|
64
Tools/ShapeFile/shape.hxx
Normal file
64
Tools/ShapeFile/shape.hxx
Normal file
|
@ -0,0 +1,64 @@
|
|||
// shape.hxx -- shape/gpc utils
|
||||
//
|
||||
// Written by Curtis Olson, started February 1999.
|
||||
//
|
||||
// Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
|
||||
|
||||
#ifndef _SHAPE_HXX
|
||||
#define _SHAPE_HXX
|
||||
|
||||
|
||||
// include Generic Polygon Clipping Library
|
||||
extern "C" {
|
||||
#include <gpc.h>
|
||||
}
|
||||
|
||||
#include <Polygon/names.hxx>
|
||||
|
||||
|
||||
// Initialize structure we use to create polygons for the gpc library
|
||||
// this must be called once from main for any program that uses this library
|
||||
bool shape_utils_init();
|
||||
|
||||
|
||||
// initialize a gpc_polygon
|
||||
void init_shape(gpc_polygon *shape);
|
||||
|
||||
// make a gpc_polygon
|
||||
void add_to_shape(int count, double *coords, gpc_polygon *shape);
|
||||
|
||||
// process shape (write polygon to all intersecting tiles)
|
||||
void process_shape(string path, AreaType area, gpc_polygon *gpc_shape);
|
||||
|
||||
// free a gpc_polygon
|
||||
void free_shape(gpc_polygon *shape);
|
||||
|
||||
|
||||
#endif // _SHAPE_HXX
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.2 1999/02/25 21:31:09 curt
|
||||
// First working version???
|
||||
//
|
||||
// Revision 1.1 1999/02/23 01:29:06 curt
|
||||
// Additional progress.
|
||||
//
|
77
Tools/SplitTris/Makefile.am
Normal file
77
Tools/SplitTris/Makefile.am
Normal file
|
@ -0,0 +1,77 @@
|
|||
#---------------------------------------------------------------------------
|
||||
# Makefile
|
||||
#
|
||||
# Written by Curtis Olson, started January 1998.
|
||||
#
|
||||
# Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
|
||||
#
|
||||
# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
# $Id$
|
||||
# (Log is kept at end of this file)
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
|
||||
bin_PROGRAMS = splittris
|
||||
|
||||
splittris_SOURCES = splittris.cxx splittris.hxx
|
||||
|
||||
splittris_LDADD = \
|
||||
$(top_builddir)/Lib/Bucket/libBucket.a \
|
||||
$(top_builddir)/Lib/Math/libMath.a \
|
||||
$(top_builddir)/Lib/Debug/libDebug.a \
|
||||
$(top_builddir)/Lib/Misc/libMisc.a \
|
||||
$(top_builddir)/Lib/zlib/libz.a \
|
||||
$(base_LIBS)
|
||||
|
||||
INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# $Log$
|
||||
# Revision 1.8 1998/11/04 23:01:57 curt
|
||||
# Changes to the automake/autoconf system to reduce the number of libraries
|
||||
# that are unnecessarily linked into the various executables.
|
||||
#
|
||||
# Revision 1.7 1998/10/18 01:17:25 curt
|
||||
# Point3D tweaks.
|
||||
#
|
||||
# Revision 1.6 1998/07/30 23:49:26 curt
|
||||
# Removed libtool support.
|
||||
#
|
||||
# Revision 1.5 1998/07/08 14:49:13 curt
|
||||
# tweaks.
|
||||
#
|
||||
# Revision 1.4 1998/04/24 00:44:06 curt
|
||||
# Added zlib support.
|
||||
#
|
||||
# Revision 1.3 1998/04/18 04:01:17 curt
|
||||
# Now use libMath rather than having local copies of math routines.
|
||||
#
|
||||
# Revision 1.2 1998/04/14 02:26:06 curt
|
||||
# Code reorganizations. Added a Lib/ directory for more general libraries.
|
||||
#
|
||||
# Revision 1.1 1998/04/08 23:21:10 curt
|
||||
# Adopted Gnu automake/autoconf system.
|
||||
#
|
||||
# Revision 1.3 1998/01/21 02:55:55 curt
|
||||
# Incorporated new make system from Bob Kuehne <rpk@sgi.com>.
|
||||
#
|
||||
# Revision 1.2 1998/01/14 15:54:42 curt
|
||||
# Initial revision completed.
|
||||
#
|
||||
# Revision 1.1 1998/01/14 02:11:30 curt
|
||||
# Initial revision.
|
||||
#
|
673
Tools/SplitTris/splittris.cxx
Normal file
673
Tools/SplitTris/splittris.cxx
Normal file
|
@ -0,0 +1,673 @@
|
|||
// splittris.cxx -- read in a .ele/.node file pair generated by the
|
||||
// triangle program and output a simple Wavefront .obj
|
||||
// file for the north, south, east, and west edge
|
||||
// verticies ... including the normals.
|
||||
//
|
||||
// Written by Curtis Olson, started January 1998.
|
||||
//
|
||||
// Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> // for atoi()
|
||||
#include <string.h>
|
||||
#include <sys/stat.h> // for stat()
|
||||
#include <unistd.h> // for stat()
|
||||
|
||||
#include "splittris.hxx"
|
||||
|
||||
#include <Include/fg_constants.h>
|
||||
#include <Bucket/bucketutils.h>
|
||||
#include <Math/fg_geodesy.hxx>
|
||||
#include <Math/mat3.h>
|
||||
#include <Math/point3d.hxx>
|
||||
#include <Math/polar3d.hxx>
|
||||
#include <Misc/fgstream.hxx>
|
||||
|
||||
// int nodecount, tricount;
|
||||
double xmin, xmax, ymin, ymax;
|
||||
|
||||
// static double nodes_orig[MAX_NODES][3];
|
||||
// static Point3D nodes_cart[MAX_NODES];
|
||||
// static int tris[MAX_TRIS][3];
|
||||
|
||||
container_3d nodes_orig;
|
||||
container_3d nodes_cart;
|
||||
container_tri tri_list;
|
||||
|
||||
fgBUCKET ne_index, nw_index, sw_index, se_index;
|
||||
fgBUCKET north_index, south_index, east_index, west_index;
|
||||
|
||||
|
||||
// given three points defining a triangle, calculate the normal
|
||||
void calc_normal(const Point3D& p1, const Point3D& p2,
|
||||
const Point3D& p3, double normal[3])
|
||||
{
|
||||
double v1[3], v2[3];
|
||||
double temp;
|
||||
|
||||
v1[0] = p2.x() - p1.x(); v1[1] = p2.y() - p1.y(); v1[2] = p2.z() - p1.z();
|
||||
v2[0] = p3.x() - p1.x(); v2[1] = p3.y() - p1.y(); v2[2] = p3.z() - p1.z();
|
||||
|
||||
MAT3cross_product(normal, v1, v2);
|
||||
MAT3_NORMALIZE_VEC(normal,temp);
|
||||
|
||||
// printf(" Normal = %.2f %.2f %.2f\n", normal[0], normal[1], normal[2]);
|
||||
}
|
||||
|
||||
|
||||
// return the file base name ( foo/bar/file.ext = file.ext )
|
||||
string extract_file(const string& input) {
|
||||
int pos;
|
||||
|
||||
pos = input.rfind("/");
|
||||
++pos;
|
||||
|
||||
return input.substr(pos);
|
||||
}
|
||||
|
||||
|
||||
// return the file path name ( foo/bar/file.ext = foo/bar )
|
||||
string extract_path(const string& input) {
|
||||
int pos;
|
||||
|
||||
pos = input.rfind("/");
|
||||
|
||||
return input.substr(0, pos);
|
||||
}
|
||||
|
||||
|
||||
// return the index of all triangles containing the specified node
|
||||
void find_tris(int n, int *t1, int *t2, int *t3, int *t4, int *t5) {
|
||||
int i;
|
||||
|
||||
*t1 = *t2 = *t3 = *t4 = *t5 = 0;
|
||||
|
||||
i = 1;
|
||||
iterator_tri last = tri_list.end();
|
||||
iterator_tri current = tri_list.begin();
|
||||
|
||||
// skip first null record
|
||||
++current;
|
||||
|
||||
for ( ; current != last; ++current )
|
||||
{
|
||||
if ( (n == (*current).n1) || (n == (*current).n2) ||
|
||||
(n == (*current).n3) )
|
||||
{
|
||||
if ( *t1 == 0 ) {
|
||||
*t1 = i;
|
||||
} else if ( *t2 == 0 ) {
|
||||
*t2 = i;
|
||||
} else if ( *t3 == 0 ) {
|
||||
*t3 = i;
|
||||
} else if ( *t4 == 0 ) {
|
||||
*t4 = i;
|
||||
} else {
|
||||
*t5 = i;
|
||||
}
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Initialize a new mesh structure
|
||||
void triload(const string& basename) {
|
||||
string nodename, elename;
|
||||
Point3D node1, node2, p;
|
||||
triangle tri;
|
||||
int nodecount, tricount, dim, junk1, junk2;
|
||||
int i;
|
||||
|
||||
nodename = basename + ".node";
|
||||
elename = basename + ".ele";
|
||||
|
||||
cout << "Loading node file: " + nodename + " ...\n";
|
||||
|
||||
fg_gzifstream node_in( nodename );
|
||||
if ( !node_in ) {
|
||||
cout << "Cannot open file " + nodename + "\n";
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// the triangle program starts counting at 1 by default which is
|
||||
// pretty obnoxious. Let's just push null record zero's onto our
|
||||
// list to compensate
|
||||
nodes_orig.push_back(node1);
|
||||
nodes_cart.push_back(node1);
|
||||
tri_list.push_back(tri);
|
||||
|
||||
node_in >> nodecount >> dim >> junk1 >> junk2;
|
||||
cout << " Expecting " << nodecount << " nodes\n";
|
||||
|
||||
for ( i = 1; i <= nodecount; i++ ) {
|
||||
node_in >> junk1 >> node1 >> junk2;
|
||||
nodes_orig.push_back(node1);
|
||||
// printf("%d %.2f %.2f %.2f\n", junk1, node1.x, node1.y, node1.z);
|
||||
|
||||
// convert to radians (before we can convert to cartesian)
|
||||
p = Point3D( node1.x() * ARCSEC_TO_RAD,
|
||||
node1.y() * ARCSEC_TO_RAD,
|
||||
node1.z() );
|
||||
|
||||
node2 = fgGeodToCart(p);
|
||||
nodes_cart.push_back(node2);
|
||||
// printf("%d %.2f %.2f %.2f\n", junk1, node2.x, node2.y, node2.z);
|
||||
|
||||
if ( i == 1 ) {
|
||||
xmin = xmax = node1.x();
|
||||
ymin = ymax = node1.y();
|
||||
} else {
|
||||
if ( node1.x() < xmin ) {
|
||||
xmin = node1.x();
|
||||
}
|
||||
if ( node1.x() > xmax ) {
|
||||
xmax = node1.x();
|
||||
}
|
||||
if ( node1.y() < ymin ) {
|
||||
ymin = node1.y();
|
||||
}
|
||||
if ( node1.y() > ymax ) {
|
||||
ymax = node1.y();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cout << "Loading element file: " + elename + " ...\n";
|
||||
fg_gzifstream ele_in( elename );
|
||||
if ( !ele_in ) {
|
||||
cout << "Cannot open file " + elename + "\n";
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
ele_in >> tricount >> junk1 >> junk2;
|
||||
cout << " Expecting " << tricount << " elements\n";
|
||||
|
||||
for ( i = 1; i <= tricount; i++ ) {
|
||||
// fscanf(ele_file, "%d %d %d %d\n", &junk1,
|
||||
// &(tri.n1), &(tri.n2), &(tri.n3));
|
||||
ele_in >> junk1 >> tri.n1 >> tri.n2 >> tri.n3;
|
||||
// printf("%d %d %d %d\n", junk1, tri.n1, tri.n2, tri.n3);
|
||||
tri_list.push_back(tri);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// check if a file exists
|
||||
int file_exists(char *file) {
|
||||
struct stat stat_buf;
|
||||
int result;
|
||||
|
||||
cout << "checking " << file << " ... ";
|
||||
|
||||
result = stat(file, &stat_buf);
|
||||
|
||||
if ( result != 0 ) {
|
||||
// stat failed, no file
|
||||
cout << "not found.\n";
|
||||
return 0;
|
||||
} else {
|
||||
// stat succeeded, file exists
|
||||
cout << "exists.\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// check to see if a shared object exists
|
||||
int shared_object_exists(const char *basepath, const string& ext) {
|
||||
char file[256], scene_path[256];
|
||||
long int index;
|
||||
|
||||
if ( ext == ".sw" ) {
|
||||
fgBucketGenBasePath(&west_index, scene_path);
|
||||
index = fgBucketGenIndex(&west_index);
|
||||
sprintf(file, "%s/%s/%ld.1.se", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
fgBucketGenBasePath(&sw_index, scene_path);
|
||||
index = fgBucketGenIndex(&sw_index);
|
||||
sprintf(file, "%s/%s/%ld.1.ne", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
fgBucketGenBasePath(&south_index, scene_path);
|
||||
index = fgBucketGenIndex(&south_index);
|
||||
sprintf(file, "%s/%s/%ld.1.nw", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ext == ".se" ) {
|
||||
fgBucketGenBasePath(&east_index, scene_path);
|
||||
index = fgBucketGenIndex(&east_index);
|
||||
sprintf(file, "%s/%s/%ld.1.sw", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
fgBucketGenBasePath(&se_index, scene_path);
|
||||
index = fgBucketGenIndex(&se_index);
|
||||
sprintf(file, "%s/%s/%ld.1.nw", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
fgBucketGenBasePath(&south_index, scene_path);
|
||||
index = fgBucketGenIndex(&south_index);
|
||||
sprintf(file, "%s/%s/%ld.1.ne", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ext == ".ne" ) {
|
||||
fgBucketGenBasePath(&east_index, scene_path);
|
||||
index = fgBucketGenIndex(&east_index);
|
||||
sprintf(file, "%s/%s/%ld.1.nw", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
fgBucketGenBasePath(&ne_index, scene_path);
|
||||
index = fgBucketGenIndex(&ne_index);
|
||||
sprintf(file, "%s/%s/%ld.1.sw", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
fgBucketGenBasePath(&north_index, scene_path);
|
||||
index = fgBucketGenIndex(&north_index);
|
||||
sprintf(file, "%s/%s/%ld.1.se", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ext == ".nw" ) {
|
||||
fgBucketGenBasePath(&west_index, scene_path);
|
||||
index = fgBucketGenIndex(&west_index);
|
||||
sprintf(file, "%s/%s/%ld.1.ne", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
fgBucketGenBasePath(&nw_index, scene_path);
|
||||
index = fgBucketGenIndex(&nw_index);
|
||||
sprintf(file, "%s/%s/%ld.1.se", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
fgBucketGenBasePath(&north_index, scene_path);
|
||||
index = fgBucketGenIndex(&north_index);
|
||||
sprintf(file, "%s/%s/%ld.1.sw", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ext == ".south" ) {
|
||||
fgBucketGenBasePath(&south_index, scene_path);
|
||||
index = fgBucketGenIndex(&south_index);
|
||||
sprintf(file, "%s/%s/%ld.1.north", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ext == ".north" ) {
|
||||
fgBucketGenBasePath(&north_index, scene_path);
|
||||
index = fgBucketGenIndex(&north_index);
|
||||
sprintf(file, "%s/%s/%ld.1.south", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ext == ".west" ) {
|
||||
fgBucketGenBasePath(&west_index, scene_path);
|
||||
index = fgBucketGenIndex(&west_index);
|
||||
sprintf(file, "%s/%s/%ld.1.east", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ext == ".east" ) {
|
||||
fgBucketGenBasePath(&east_index, scene_path);
|
||||
index = fgBucketGenIndex(&east_index);
|
||||
sprintf(file, "%s/%s/%ld.1.west", basepath, scene_path, index);
|
||||
if ( file_exists(file) ) {
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
// my custom file opening routine ... don't open if a shared edge or
|
||||
// vertex alread exists
|
||||
FILE *my_open(const string& basename, const string& basepath,
|
||||
const string& ext)
|
||||
{
|
||||
FILE *fp;
|
||||
string filename;
|
||||
|
||||
// create the output file name
|
||||
filename = basename + ext;
|
||||
|
||||
// check if a shared object already exist from a different tile
|
||||
|
||||
if ( shared_object_exists(basepath.c_str(), ext) ) {
|
||||
// not an actual file open error, but we've already got the
|
||||
// shared edge, so we don't want to create another one
|
||||
cout << "not opening\n";
|
||||
return(NULL);
|
||||
} else {
|
||||
// open the file
|
||||
fp = fopen(filename.c_str(), "w");
|
||||
cout << "Opening " + filename + "\n";
|
||||
return(fp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// dump in WaveFront .obj format
|
||||
void dump_obj(const string& basename, const string& basepath) {
|
||||
Point3D node;
|
||||
double n1[3], n2[3], n3[3], n4[3], n5[3], norm[3], temp;
|
||||
FILE *fp, *sw, *se, *ne, *nw, *north, *south, *east, *west, *body;
|
||||
int i, t1, t2, t3, t4, t5, count, size;
|
||||
double x, y, z;
|
||||
|
||||
sw = my_open(basename, basepath, ".sw");
|
||||
se = my_open(basename, basepath, ".se");
|
||||
ne = my_open(basename, basepath, ".ne");
|
||||
nw = my_open(basename, basepath, ".nw");
|
||||
|
||||
north = my_open(basename, basepath, ".north");
|
||||
south = my_open(basename, basepath, ".south");
|
||||
east = my_open(basename, basepath, ".east");
|
||||
west = my_open(basename, basepath, ".west");
|
||||
|
||||
body = my_open(basename, basepath, ".body");
|
||||
|
||||
cout << "Dumping edges file basename: " + basename + " ...\n";
|
||||
|
||||
// dump vertices
|
||||
cout << " writing vertices\n";
|
||||
|
||||
iterator_3d last = nodes_orig.end();
|
||||
iterator_3d current = nodes_orig.begin();
|
||||
++current;
|
||||
for ( ; current != last; ++current) {
|
||||
node = *current;
|
||||
|
||||
if ( (fabs(node.y() - ymin) < FG_EPSILON) &&
|
||||
(fabs(node.x() - xmin) < FG_EPSILON) ) {
|
||||
fp = sw;
|
||||
} else if ( (fabs(node.y() - ymin) < FG_EPSILON) &&
|
||||
(fabs(node.x() - xmax) < FG_EPSILON) ) {
|
||||
fp = se;
|
||||
} else if ( (fabs(node.y() - ymax) < FG_EPSILON) &&
|
||||
(fabs(node.x() - xmax) < FG_EPSILON)) {
|
||||
fp = ne;
|
||||
} else if ( (fabs(node.y() - ymax) < FG_EPSILON) &&
|
||||
(fabs(node.x() - xmin) < FG_EPSILON) ) {
|
||||
fp = nw;
|
||||
} else if ( fabs(node.x() - xmin) < FG_EPSILON ) {
|
||||
fp = west;
|
||||
} else if ( fabs(node.x() - xmax) < FG_EPSILON ) {
|
||||
fp = east;
|
||||
} else if ( fabs(node.y() - ymin) < FG_EPSILON ) {
|
||||
fp = south;
|
||||
} else if ( fabs(node.y() - ymax) < FG_EPSILON ) {
|
||||
fp = north;
|
||||
} else {
|
||||
fp = body;
|
||||
}
|
||||
|
||||
x = node.x();
|
||||
y = node.y();
|
||||
z = node.z();
|
||||
|
||||
if ( fp != NULL ) {
|
||||
fprintf(fp, "gdn %.2f %.2f %.2f\n", x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
cout << " calculating and writing normals\n";
|
||||
|
||||
// calculate and generate normals
|
||||
size = nodes_orig.size();
|
||||
for ( i = 1; i < size; i++ ) {
|
||||
// printf("Finding normal\n");
|
||||
|
||||
find_tris(i, &t1, &t2, &t3, &t4, &t5);
|
||||
|
||||
n1[0] = n1[1] = n1[2] = 0.0;
|
||||
n2[0] = n2[1] = n2[2] = 0.0;
|
||||
n3[0] = n3[1] = n3[2] = 0.0;
|
||||
n4[0] = n4[1] = n4[2] = 0.0;
|
||||
n5[0] = n5[1] = n5[2] = 0.0;
|
||||
|
||||
count = 1;
|
||||
calc_normal(nodes_cart[tri_list[t1].n1],
|
||||
nodes_cart[tri_list[t1].n2],
|
||||
nodes_cart[tri_list[t1].n3],
|
||||
n1);
|
||||
|
||||
if ( t2 > 0 ) {
|
||||
calc_normal(nodes_cart[tri_list[t2].n1],
|
||||
nodes_cart[tri_list[t2].n2],
|
||||
nodes_cart[tri_list[t2].n3],
|
||||
n2);
|
||||
count = 2;
|
||||
}
|
||||
|
||||
if ( t3 > 0 ) {
|
||||
calc_normal(nodes_cart[tri_list[t3].n1],
|
||||
nodes_cart[tri_list[t3].n2],
|
||||
nodes_cart[tri_list[t3].n3],
|
||||
n3);
|
||||
count = 3;
|
||||
}
|
||||
|
||||
if ( t4 > 0 ) {
|
||||
calc_normal(nodes_cart[tri_list[t4].n1],
|
||||
nodes_cart[tri_list[t4].n2],
|
||||
nodes_cart[tri_list[t4].n3],
|
||||
n4);
|
||||
count = 4;
|
||||
}
|
||||
|
||||
if ( t5 > 0 ) {
|
||||
calc_normal(nodes_cart[tri_list[t5].n1],
|
||||
nodes_cart[tri_list[t5].n2],
|
||||
nodes_cart[tri_list[t5].n3],
|
||||
n5);
|
||||
count = 5;
|
||||
}
|
||||
|
||||
// printf(" norm[2] = %.2f %.2f %.2f\n", n1[2], n2[2], n3[2]);
|
||||
|
||||
norm[0] = ( n1[0] + n2[0] + n3[0] + n4[0] + n5[0] ) / (double)count;
|
||||
norm[1] = ( n1[1] + n2[1] + n3[1] + n4[1] + n5[1] ) / (double)count;
|
||||
norm[2] = ( n1[2] + n2[2] + n3[2] + n4[2] + n5[2] ) / (double)count;
|
||||
|
||||
// printf(" count = %d\n", count);
|
||||
// printf(" Ave. normal = %.4f %.4f %.4f\n", norm[0], norm[1],
|
||||
// norm[2]);
|
||||
MAT3_NORMALIZE_VEC(norm, temp);
|
||||
// printf(" Normalized ave. normal = %.4f %.4f %.4f\n",
|
||||
// norm[0], norm[1], norm[2]);
|
||||
|
||||
fp = NULL;
|
||||
|
||||
if ( (fabs(nodes_orig[i].y() - ymin) < FG_EPSILON) &&
|
||||
(fabs(nodes_orig[i].x() - xmin) < FG_EPSILON) ) {
|
||||
fp = sw;
|
||||
} else if ( (fabs(nodes_orig[i].y() - ymin) < FG_EPSILON) &&
|
||||
(fabs(nodes_orig[i].x() - xmax) < FG_EPSILON) ) {
|
||||
fp = se;
|
||||
} else if ( (fabs(nodes_orig[i].y() - ymax) < FG_EPSILON) &&
|
||||
(fabs(nodes_orig[i].x() - xmax) < FG_EPSILON)) {
|
||||
fp = ne;
|
||||
} else if ( (fabs(nodes_orig[i].y() - ymax) < FG_EPSILON) &&
|
||||
(fabs(nodes_orig[i].x() - xmin) < FG_EPSILON) ) {
|
||||
fp = nw;
|
||||
} else if ( fabs(nodes_orig[i].x() - xmin) < FG_EPSILON ) {
|
||||
fp = west;
|
||||
} else if ( fabs(nodes_orig[i].x() - xmax) < FG_EPSILON ) {
|
||||
fp = east;
|
||||
} else if ( fabs(nodes_orig[i].y() - ymin) < FG_EPSILON ) {
|
||||
fp = south;
|
||||
} else if ( fabs(nodes_orig[i].y() - ymax) < FG_EPSILON ) {
|
||||
fp = north;
|
||||
}
|
||||
if ( fp != NULL ) {
|
||||
fprintf(fp, "vn %.4f %.4f %.4f\n", norm[0], norm[1], norm[2]);
|
||||
}
|
||||
}
|
||||
|
||||
if ( sw ) { fclose(sw); }
|
||||
if ( se ) { fclose(se); }
|
||||
if ( ne ) { fclose(ne); }
|
||||
if ( nw ) { fclose(nw); }
|
||||
|
||||
if ( north ) { fclose(north); }
|
||||
if ( south ) { fclose(south); }
|
||||
if ( east ) { fclose(east); }
|
||||
if ( west ) { fclose(west); }
|
||||
|
||||
if ( body ) { fclose(body); }
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
string basename, basepath, temp;
|
||||
fgBUCKET p;
|
||||
long int index;
|
||||
int len;
|
||||
|
||||
basename = argv[1];
|
||||
|
||||
// find the base path of the file
|
||||
basepath = extract_path(basename);
|
||||
basepath = extract_path(basepath);
|
||||
basepath = extract_path(basepath);
|
||||
cout << "basepath = " + basepath + "\n";
|
||||
|
||||
// find the index of the current file
|
||||
temp = extract_file(basename);
|
||||
len = temp.length();
|
||||
if ( len >= 2 ) {
|
||||
temp = temp.substr(0, len-2);
|
||||
}
|
||||
index = atoi( temp.c_str() );
|
||||
cout << "index = " << index << "\n";
|
||||
fgBucketParseIndex(index, &p);
|
||||
|
||||
cout << "bucket = " << p.lon << " " << p.lat << " " <<
|
||||
p.x << " " << p.y << "\n";
|
||||
|
||||
// generate the indexes of the neighbors
|
||||
fgBucketOffset(&p, &ne_index, 1, 1);
|
||||
fgBucketOffset(&p, &nw_index, -1, 1);
|
||||
fgBucketOffset(&p, &se_index, 1, -1);
|
||||
fgBucketOffset(&p, &sw_index, -1, -1);
|
||||
|
||||
fgBucketOffset(&p, &north_index, 0, 1);
|
||||
fgBucketOffset(&p, &south_index, 0, -1);
|
||||
fgBucketOffset(&p, &east_index, 1, 0);
|
||||
fgBucketOffset(&p, &west_index, -1, 0);
|
||||
|
||||
// printf("Corner indexes = %ld %ld %ld %ld\n",
|
||||
// ne_index, nw_index, sw_index, se_index);
|
||||
// printf("Edge indexes = %ld %ld %ld %ld\n",
|
||||
// north_index, south_index, east_index, west_index);
|
||||
|
||||
|
||||
// load the input data files
|
||||
triload(basename);
|
||||
|
||||
// dump in WaveFront .obj format
|
||||
dump_obj(basename, basepath);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.7 1998/11/06 21:33:57 curt
|
||||
// Updates to go along with changes in fgstream.
|
||||
//
|
||||
// Revision 1.6 1998/10/21 14:56:20 curt
|
||||
// Fixed a units conversion bug.
|
||||
//
|
||||
// Revision 1.5 1998/10/20 15:50:33 curt
|
||||
// whitespace tweak.
|
||||
//
|
||||
// Revision 1.4 1998/10/18 01:17:27 curt
|
||||
// Point3D tweaks.
|
||||
//
|
||||
// Revision 1.3 1998/09/22 23:49:56 curt
|
||||
// C++-ified, STL-ified, and string-ified.
|
||||
//
|
||||
// Revision 1.2 1998/09/21 23:16:23 curt
|
||||
// Converted to c++ style comments.
|
||||
//
|
||||
// Revision 1.1 1998/07/08 14:59:13 curt
|
||||
// *.[ch] renamed to *.[ch]xx
|
||||
//
|
||||
// Revision 1.11 1998/07/04 00:56:40 curt
|
||||
// typedef'd struct fgBUCKET.
|
||||
//
|
||||
// Revision 1.10 1998/05/02 01:54:37 curt
|
||||
// Converting to polar3d.h routines.
|
||||
//
|
||||
// Revision 1.9 1998/04/18 04:01:20 curt
|
||||
// Now use libMath rather than having local copies of math routines.
|
||||
//
|
||||
// Revision 1.8 1998/04/14 02:26:08 curt
|
||||
// Code reorganizations. Added a Lib/ directory for more general libraries.
|
||||
//
|
||||
// Revision 1.7 1998/04/08 23:21:13 curt
|
||||
// Adopted Gnu automake/autoconf system.
|
||||
//
|
||||
// Revision 1.6 1998/03/03 15:36:13 curt
|
||||
// Tweaks for compiling with g++
|
||||
//
|
||||
// Revision 1.5 1998/03/03 03:37:04 curt
|
||||
// Cumulative tweaks.
|
||||
//
|
||||
// Revision 1.4 1998/01/31 00:41:26 curt
|
||||
// Made a few changes converting floats to doubles.
|
||||
//
|
||||
// Revision 1.3 1998/01/27 18:37:04 curt
|
||||
// Lots of updates to get back in sync with changes made over in .../Src/
|
||||
//
|
||||
// Revision 1.2 1998/01/14 15:54:43 curt
|
||||
// Initial revision completed.
|
||||
//
|
||||
// Revision 1.1 1998/01/14 02:11:31 curt
|
||||
// Initial revision.
|
||||
//
|
||||
|
89
Tools/SplitTris/splittris.hxx
Normal file
89
Tools/SplitTris/splittris.hxx
Normal file
|
@ -0,0 +1,89 @@
|
|||
// splittris.hxx -- read in a .ele/.node file pair generated by the triangle
|
||||
// program and output edge vertices w/ normals.
|
||||
//
|
||||
// Written by Curtis Olson, started January 1998.
|
||||
//
|
||||
// Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com
|
||||
//
|
||||
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
// (Log is kept at end of this file)
|
||||
|
||||
|
||||
|
||||
#ifndef SPLITTRIS_HXX
|
||||
#define SPLITTRIS_HXX
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
|
||||
#include <vector>
|
||||
#include "Include/fg_stl_config.h"
|
||||
|
||||
#ifdef NEEDNAMESPACESTD
|
||||
using namespace std;
|
||||
#endif
|
||||
|
||||
#include <Math/point3d.hxx>
|
||||
|
||||
|
||||
// A triangle (indices of the three nodes)
|
||||
typedef struct {
|
||||
int n1, n2, n3;
|
||||
} triangle;
|
||||
|
||||
|
||||
typedef vector < Point3D > container_3d;
|
||||
typedef container_3d::iterator iterator_3d;
|
||||
typedef container_3d::const_iterator const_iterator_3d;
|
||||
|
||||
typedef vector < triangle > container_tri;
|
||||
typedef container_tri::iterator iterator_tri;
|
||||
typedef container_tri::const_iterator const_iterator_tri;
|
||||
|
||||
|
||||
// Initialize a new mesh structure
|
||||
void triload(const string& basename);
|
||||
|
||||
|
||||
#endif // SPLITTRIS_HXX
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.4 1998/10/18 01:17:28 curt
|
||||
// Point3D tweaks.
|
||||
//
|
||||
// Revision 1.3 1998/09/22 23:49:58 curt
|
||||
// C++-ified, STL-ified, and string-ified.
|
||||
//
|
||||
// Revision 1.2 1998/09/21 23:16:24 curt
|
||||
// Converted to c++ style comments.
|
||||
//
|
||||
// Revision 1.1 1998/07/08 14:59:14 curt
|
||||
// *.[ch] renamed to *.[ch]xx
|
||||
//
|
||||
// Revision 1.3 1998/03/03 15:36:13 curt
|
||||
// Tweaks for compiling with g++
|
||||
//
|
||||
// Revision 1.2 1998/01/15 02:49:25 curt
|
||||
// Misc. housekeeping.
|
||||
//
|
||||
// Revision 1.1 1998/01/14 02:11:32 curt
|
||||
// Initial revision.
|
||||
//
|
||||
|
30
Tools/Stripe_u/Makefile.am
Normal file
30
Tools/Stripe_u/Makefile.am
Normal file
|
@ -0,0 +1,30 @@
|
|||
bin_PROGRAMS = strips
|
||||
|
||||
strips_SOURCES = \
|
||||
add.c add.h \
|
||||
bands.c \
|
||||
common.c common.h \
|
||||
define.h \
|
||||
extend.h \
|
||||
free.c free.h \
|
||||
global.h \
|
||||
glove.h \
|
||||
init.c init.h \
|
||||
local.c local.h \
|
||||
my_global.h \
|
||||
newpolve.c \
|
||||
options.c options.h \
|
||||
output.c output.h \
|
||||
outputex.c outputex.h \
|
||||
partial.c partial.h \
|
||||
polverts.h polvertsex.h \
|
||||
queue.c queue.h \
|
||||
sgi_triang.c sgi_triangex.c \
|
||||
struct.c struct.h \
|
||||
structex.c \
|
||||
sturcts.h sturctsex.h \
|
||||
ties.c ties.h \
|
||||
triangulate.h triangulatex.h \
|
||||
util.c util.h
|
||||
|
||||
strips_LDADD = $(base_LIBS)
|
386
Tools/Stripe_u/add.c
Normal file
386
Tools/Stripe_u/add.c
Normal file
|
@ -0,0 +1,386 @@
|
|||
/********************************************************************/
|
||||
/* STRIPE: converting a polygonal model to triangle strips
|
||||
Francine Evans, 1996.
|
||||
SUNY @ Stony Brook
|
||||
Advisors: Steven Skiena and Amitabh Varshney
|
||||
*/
|
||||
/********************************************************************/
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* STRIPE: add.c
|
||||
This file contains the procedure code that will add information
|
||||
to our data structures.
|
||||
*/
|
||||
/*---------------------------------------------------------------------*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include "global.h"
|
||||
#include "queue.h"
|
||||
#include "polverts.h"
|
||||
#include "triangulate.h"
|
||||
#include "ties.h"
|
||||
#include "outputex.h"
|
||||
#include "options.h"
|
||||
#include "local.h"
|
||||
|
||||
BOOL new_vertex(double difference, int id1,int id2,
|
||||
struct vert_struct *n)
|
||||
{
|
||||
/* Is the difference between id1 and id2 (2 normal vertices that
|
||||
mapped to the same vertex) greater than the
|
||||
threshold that was specified?
|
||||
*/
|
||||
struct vert_struct *pn1,*pn2;
|
||||
double dot_product;
|
||||
double distance1, distance2,distance;
|
||||
double rad;
|
||||
char arg1[100];
|
||||
char arg2[100];
|
||||
|
||||
pn1 = n + id1;
|
||||
pn2 = n + id2;
|
||||
|
||||
dot_product = ((pn1->x) * (pn2->x)) +
|
||||
((pn1->y) * (pn2->y)) +
|
||||
((pn1->z) * (pn2->z));
|
||||
/* Get the absolute value */
|
||||
if (dot_product < 0)
|
||||
dot_product = dot_product * -1;
|
||||
|
||||
distance1 = sqrt( (pn1->x * pn1->x) +
|
||||
(pn1->y * pn1->y) +
|
||||
(pn1->z * pn1->z) );
|
||||
distance2 = sqrt( (pn2->x * pn2->x) +
|
||||
(pn2->y * pn2->y) +
|
||||
(pn2->z * pn2->z) );
|
||||
distance = distance1 * distance2;
|
||||
|
||||
rad = acos((double)dot_product/(double)distance);
|
||||
/* convert to degrees */
|
||||
rad = (180 * rad)/PI;
|
||||
|
||||
if ( rad <= difference)
|
||||
return FALSE;
|
||||
|
||||
/* double checking because of imprecision with floating
|
||||
point acos function
|
||||
*/
|
||||
sprintf( arg1,"%.5f", rad );
|
||||
sprintf( arg2,"%.5f", difference );
|
||||
if ( strcmp( arg1, arg2 ) <=0 )
|
||||
return( FALSE );
|
||||
if ( rad <= difference)
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL Check_VN(int vertex,int normal, struct vert_added *added)
|
||||
{
|
||||
/* Check to see if we already added this vertex and normal */
|
||||
register int x,n;
|
||||
|
||||
n = (added+vertex)->num;
|
||||
for (x = 0; x < n; x++)
|
||||
{
|
||||
if (*((added+vertex)->normal+x) == normal)
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL norm_array(int id, int vertex, double normal_difference,
|
||||
struct vert_struct *n, int num_vert)
|
||||
{
|
||||
static int last;
|
||||
static struct vert_added *added;
|
||||
register int x;
|
||||
static BOOL first = TRUE;
|
||||
|
||||
if (first)
|
||||
{
|
||||
/* This is the first time that we are in here, so we will allocate
|
||||
a structure that will save the vertices that we added, so that we
|
||||
do not add the same thing twice
|
||||
*/
|
||||
first = FALSE;
|
||||
added = (struct vert_added *) malloc (sizeof (struct vert_added ) * num_vert);
|
||||
/* The number of vertices added for each vertex must be initialized to
|
||||
zero
|
||||
*/
|
||||
for (x = 0; x < num_vert; x++)
|
||||
(added+x)->num = 0;
|
||||
}
|
||||
|
||||
if (vertex)
|
||||
/* Set the pointer to the vertex, we will be calling again with the
|
||||
normal to fill it with
|
||||
*/
|
||||
last = id;
|
||||
else
|
||||
{
|
||||
/* Fill the pointer with the id of the normal */
|
||||
if (*(vert_norms + last) == 0)
|
||||
*(vert_norms + last) = id;
|
||||
else if ((*(vert_norms + last) != id) && ((int)normal_difference != 360))
|
||||
{
|
||||
/* difference is big enough, we need to create a new vertex */
|
||||
if (new_vertex(normal_difference,id,*(vert_norms + last),n))
|
||||
{
|
||||
/* First check to see if we added this vertex and normal already */
|
||||
if (Check_VN(last,id,added))
|
||||
return FALSE;
|
||||
/* OK, create the new vertex, and have its id = the number of vertices
|
||||
and its normal what we have here
|
||||
*/
|
||||
vert_norms = realloc(vert_norms, sizeof(int) * (num_vert + 1));
|
||||
if (!vert_norms)
|
||||
{
|
||||
printf("Allocation error - aborting\n");
|
||||
exit(1);
|
||||
}
|
||||
*(vert_norms + num_vert) = id;
|
||||
/* We created a new vertex, now put it in our added structure so
|
||||
we do not add the same thing twice
|
||||
*/
|
||||
(added+last)->num = (added+last)->num + 1;
|
||||
if ((added+last)->num == 1)
|
||||
{
|
||||
/* First time */
|
||||
(added+last)->normal = (int *) malloc (sizeof (int ) * 1);
|
||||
*((added+last)->normal) = id;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Not the first time, reallocate space */
|
||||
(added+last)->normal = realloc((added+last)->normal,sizeof(int) * (added+last)->num);
|
||||
*((added+last)->normal+((added+last)->num-1)) = id;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void add_texture(int id,BOOL vertex)
|
||||
{
|
||||
/* Save the texture with its vertex for future use when outputting */
|
||||
static int last;
|
||||
|
||||
if (vertex)
|
||||
last = id;
|
||||
else
|
||||
*(vert_texture+last) = id;
|
||||
}
|
||||
|
||||
int add_vert_id(int id, int index_count)
|
||||
{
|
||||
register int x;
|
||||
|
||||
/* Test if degenerate, if so do not add degenerate vertex */
|
||||
for (x = 1; x < index_count ; x++)
|
||||
{
|
||||
if (ids[x] == id)
|
||||
return 0;
|
||||
}
|
||||
ids[index_count] = id;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void add_norm_id(int id, int index_count)
|
||||
{
|
||||
norms[index_count] = id;
|
||||
}
|
||||
|
||||
void AddNewFace(int ids[MAX1], int vert_count, int face_id, int norms[MAX1])
|
||||
{
|
||||
PF_FACES pfNode;
|
||||
int *pTempInt;
|
||||
int *pnorms;
|
||||
F_EDGES **pTempVertptr;
|
||||
int *pTempmarked, *pTempwalked;
|
||||
register int y,count = 0,sum = 0;
|
||||
|
||||
/* Add a new face into our face data structure */
|
||||
|
||||
pfNode = (PF_FACES) malloc(sizeof(F_FACES) );
|
||||
if ( pfNode )
|
||||
{
|
||||
pfNode->pPolygon = (int*) malloc(sizeof(int) * (vert_count) );
|
||||
pfNode->pNorms = (int*) malloc(sizeof(int) * (vert_count) );
|
||||
pfNode->VertandId = (F_EDGES**)malloc(sizeof(F_EDGES*) * (vert_count));
|
||||
pfNode->marked = (int*)malloc(sizeof(int) * (vert_count));
|
||||
pfNode->walked = (int*)malloc(sizeof(int) * (vert_count));
|
||||
}
|
||||
pTempInt =pfNode->pPolygon;
|
||||
pnorms = pfNode->pNorms;
|
||||
pTempmarked = pfNode->marked;
|
||||
pTempwalked = pfNode->walked;
|
||||
pTempVertptr = pfNode->VertandId;
|
||||
pfNode->nPolSize = vert_count;
|
||||
pfNode->seen = -1;
|
||||
pfNode->seen2 = -1;
|
||||
for (y=1;y<=vert_count;y++)
|
||||
{
|
||||
*(pTempInt + count) = ids[y];
|
||||
*(pnorms + count) = norms[y];
|
||||
*(pTempmarked + count) = FALSE;
|
||||
*(pTempwalked + count) = -1;
|
||||
*(pTempVertptr+count) = NULL;
|
||||
count++;
|
||||
}
|
||||
AddHead(PolFaces[face_id-1],(PLISTINFO) pfNode);
|
||||
}
|
||||
|
||||
|
||||
void CopyFace(int ids[MAX1], int vert_count, int face_id, int norms[MAX1])
|
||||
{
|
||||
PF_FACES pfNode;
|
||||
int *pTempInt;
|
||||
int *pnorms;
|
||||
F_EDGES **pTempVertptr;
|
||||
int *pTempmarked, *pTempwalked;
|
||||
register int y,count = 0,sum = 0;
|
||||
|
||||
/* Copy a face node into a new node, used after the global algorithm
|
||||
is run, so that we can save whatever is left into a new structure
|
||||
*/
|
||||
|
||||
pfNode = (PF_FACES) malloc(sizeof(F_FACES) );
|
||||
if ( pfNode )
|
||||
{
|
||||
pfNode->pPolygon = (int*) malloc(sizeof(int) * (vert_count) );
|
||||
pfNode->pNorms = (int*) malloc(sizeof(int) * (vert_count) );
|
||||
pfNode->VertandId = (F_EDGES**)malloc(sizeof(F_EDGES*) * (vert_count));
|
||||
pfNode->marked = (int*)malloc(sizeof(int) * (vert_count));
|
||||
pfNode->walked = (int*)malloc(sizeof(int) * (vert_count));
|
||||
}
|
||||
pTempInt =pfNode->pPolygon;
|
||||
pnorms = pfNode->pNorms;
|
||||
pTempmarked = pfNode->marked;
|
||||
pTempwalked = pfNode->walked;
|
||||
pTempVertptr = pfNode->VertandId;
|
||||
pfNode->nPolSize = vert_count;
|
||||
pfNode->seen = -1;
|
||||
pfNode->seen2 = -1;
|
||||
for (y=0;y<vert_count;y++)
|
||||
{
|
||||
*(pTempInt + count) = ids[y];
|
||||
*(pnorms + count) = norms[y];
|
||||
*(pTempmarked + count) = FALSE;
|
||||
*(pTempwalked + count) = -1;
|
||||
*(pTempVertptr+count) = NULL;
|
||||
count++;
|
||||
}
|
||||
AddHead(PolFaces[face_id-1],(PLISTINFO) pfNode);
|
||||
}
|
||||
|
||||
void Add_Edge(int v1,int v2)
|
||||
{
|
||||
PF_EDGES temp = NULL;
|
||||
ListHead *pListHead;
|
||||
BOOL flag = TRUE;
|
||||
register int t,count = 0;
|
||||
|
||||
/* Add a new edge into the edge data structure */
|
||||
if (v1 > v2)
|
||||
{
|
||||
t = v1;
|
||||
v1 = v2;
|
||||
v2 = t;
|
||||
}
|
||||
|
||||
pListHead = PolEdges[v1];
|
||||
temp = (PF_EDGES) PeekList(pListHead,LISTHEAD,count);
|
||||
if (temp == NULL)
|
||||
{
|
||||
printf("Have the wrong edge \n:");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
while (flag)
|
||||
{
|
||||
if (v2 == temp->edge[0])
|
||||
return;
|
||||
else
|
||||
temp = (PF_EDGES) PeekList(pListHead,LISTHEAD,++count);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void Add_AdjEdge(int v1,int v2,int fnum,int index1 )
|
||||
{
|
||||
PF_EDGES temp = NULL;
|
||||
PF_FACES temp2 = NULL;
|
||||
PF_EDGES pfNode;
|
||||
ListHead *pListHead;
|
||||
ListHead *pListFace;
|
||||
BOOL flag = TRUE;
|
||||
register int count = 0;
|
||||
register int t,v3 = -1;
|
||||
|
||||
if (v1 > v2)
|
||||
{
|
||||
t = v1;
|
||||
v1 = v2;
|
||||
v2 = t;
|
||||
}
|
||||
pListFace = PolFaces[fnum];
|
||||
temp2 = (PF_FACES) PeekList(pListFace,LISTHEAD,0);
|
||||
pListHead = PolEdges[v1];
|
||||
temp = (PF_EDGES) PeekList(pListHead,LISTHEAD,count);
|
||||
if (temp == NULL)
|
||||
flag = FALSE;
|
||||
count++;
|
||||
while (flag)
|
||||
{
|
||||
if (v2 == temp->edge[0])
|
||||
{
|
||||
/* If greater than 2 polygons adjacent to an edge, then we will
|
||||
only save the first 2 that we found. We will have a small performance
|
||||
hit, but this does not happen often.
|
||||
*/
|
||||
if (temp->edge[2] == -1)
|
||||
temp->edge[2] = fnum;
|
||||
else
|
||||
v3 = temp->edge[2];
|
||||
flag = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = (PF_EDGES) PeekList(pListHead,LISTHEAD,count);
|
||||
count++;
|
||||
if (temp == NULL)
|
||||
flag = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Did not find it */
|
||||
if (temp == NULL)
|
||||
{
|
||||
pfNode = (PF_EDGES) malloc(sizeof(F_EDGES) );
|
||||
if ( pfNode )
|
||||
{
|
||||
pfNode->edge[0] = v2;
|
||||
pfNode->edge[1] = fnum;
|
||||
pfNode->edge[2] = v3;
|
||||
AddTail( PolEdges[v1], (PLISTINFO) pfNode );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Out of memory!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
*(temp2->VertandId+index1) = pfNode;
|
||||
}
|
||||
else
|
||||
*(temp2->VertandId+index1) = temp;
|
||||
|
||||
}
|
||||
|
||||
|
25
Tools/Stripe_u/add.h
Normal file
25
Tools/Stripe_u/add.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
/********************************************************************/
|
||||
/* STRIPE: converting a polygonal model to triangle strips
|
||||
Francine Evans, 1996.
|
||||
SUNY @ Stony Brook
|
||||
Advisors: Steven Skiena and Amitabh Varshney
|
||||
*/
|
||||
/********************************************************************/
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* STRIPE: add.h
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
BOOL new_vertex();
|
||||
BOOL Check_VN();
|
||||
BOOL norm_array();
|
||||
void add_texture();
|
||||
int add_vert_id();
|
||||
void add_norm_id();
|
||||
void AddNewFace();
|
||||
void CopyFace();
|
||||
void Add_Edge();
|
||||
void Add_AdjEdge();
|
||||
|
||||
|
||||
|
549
Tools/Stripe_u/bands.c
Normal file
549
Tools/Stripe_u/bands.c
Normal file
|
@ -0,0 +1,549 @@
|
|||
/********************************************************************/
|
||||
/* STRIPE: converting a polygonal model to triangle strips
|
||||
Francine Evans, 1996.
|
||||
SUNY @ Stony Brook
|
||||
Advisors: Steven Skiena and Amitabh Varshney
|
||||
*/
|
||||
/********************************************************************/
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* STRIPE: bands.c
|
||||
This file contains the main procedure code that will read in the
|
||||
object and then call the routines that produce the triangle strips.
|
||||
*/
|
||||
/*---------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include "global.h"
|
||||
#include "polverts.h"
|
||||
#include "triangulate.h"
|
||||
#include "ties.h"
|
||||
#include "outputex.h"
|
||||
#include "options.h"
|
||||
#include "local.h"
|
||||
#include "init.h"
|
||||
#include "free.h"
|
||||
#include "add.h"
|
||||
|
||||
#define MAX1 60
|
||||
/* TIMING for Windows */
|
||||
#ifdef WIN32
|
||||
#include <sys/timeb.h>
|
||||
#include <time.h>
|
||||
/* TIMING for UNIX */
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/times.h>
|
||||
#include <sys/time.h>
|
||||
struct timeval tm;
|
||||
struct timezone tz;
|
||||
double et;
|
||||
#define START gettimeofday(&tm,&tz);\
|
||||
et = (tm.tv_sec)+ (0.000001* (tm.tv_usec));
|
||||
|
||||
#define STOP gettimeofday(&tm,&tz);\
|
||||
et = (tm.tv_sec)+(0.000001*(tm.tv_usec)) - et;
|
||||
#endif
|
||||
|
||||
|
||||
void get_time()
|
||||
{
|
||||
/* For timing */
|
||||
#ifdef WIN32
|
||||
struct _timeb timebuffer;
|
||||
char *timeline;
|
||||
#else
|
||||
long timer;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
_ftime( &timebuffer );
|
||||
timeline = ctime( & ( timebuffer.time ) );
|
||||
printf( "The time is %.19s.%hu %s", timeline, timebuffer.millitm, &timeline[20] );
|
||||
#else
|
||||
printf("Time for last frame = %lf seconds\n", et);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
**
|
||||
Here the main program begins. It will start by loading in a .obj file
|
||||
then it will convert the polygonal model into triangle strips.
|
||||
**
|
||||
*/
|
||||
|
||||
void main (int argc,char *argv[])
|
||||
{
|
||||
char *fname,*all,buff[255], *ptr, *ptr2;
|
||||
FILE *file, *bands;
|
||||
int face_id=0, vert_count, loop, num=0,num2;
|
||||
float center[3];
|
||||
int temp[MAX1],vertex,strips, swaps,tempi,cost,triangles;
|
||||
int f,t,tr,g;
|
||||
char *file_open;
|
||||
int num_vert = 0,
|
||||
num_faces = 0,
|
||||
num_nvert = 0,
|
||||
num_edges = 0,
|
||||
num_texture = 0,
|
||||
num_tris = 0;
|
||||
double fra = 0.0;
|
||||
BOOL texture, normal, normal_and_texture,quads = FALSE;
|
||||
|
||||
/* Options variables */
|
||||
float norm_difference;
|
||||
|
||||
/* Structures for the object */
|
||||
struct vert_struct *vertices = NULL,
|
||||
*nvertices = NULL,
|
||||
*pvertices = NULL,
|
||||
*pnvertices = NULL;
|
||||
|
||||
get_time();
|
||||
START
|
||||
|
||||
/* File that will contain the triangle strip data */
|
||||
bands = fopen("bands.d","w");
|
||||
|
||||
/*
|
||||
Scan the file once to find out the number of vertices,
|
||||
vertice normals, and faces so we can set up some memory
|
||||
structures
|
||||
*/
|
||||
/* Interpret the options specified */
|
||||
norm_difference = get_options(argc,argv,&f,&t,&tr,&g);
|
||||
if (f == BINARY)
|
||||
file_open = "rb";
|
||||
else
|
||||
file_open = "r";
|
||||
|
||||
fname = argv[argc-1];
|
||||
printf ("File: %s\n",fname);
|
||||
/*printf ("Scanning...%s ",file_open);*/
|
||||
|
||||
|
||||
/* File can be in binary for faster reading */
|
||||
if (file = fopen (fname,file_open))
|
||||
{
|
||||
while (!feof (file))
|
||||
{
|
||||
/* Read a line */
|
||||
if (f == BINARY)
|
||||
fread (buff,sizeof(char) * 255,1, file);
|
||||
else
|
||||
fgets (buff, sizeof(char) * 255, file);
|
||||
num++;
|
||||
/* At a vertex */
|
||||
if (*buff == 'v')
|
||||
{
|
||||
/* At a normal */
|
||||
if (*(buff+1)=='n')
|
||||
num_nvert++;
|
||||
else if (*(buff+1)=='t')
|
||||
num_texture++;
|
||||
/* At a regular vertex */
|
||||
else
|
||||
num_vert++;
|
||||
}
|
||||
/* At a face */
|
||||
else if (*buff == 'f')
|
||||
{
|
||||
num_faces++;
|
||||
strtok(buff, " ");
|
||||
tempi = 0;
|
||||
while (strtok(NULL, " ") != NULL) tempi++;
|
||||
num_tris += tempi - 2;
|
||||
}
|
||||
}
|
||||
fclose (file);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
printf("Error in the file name\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
/* Allocate structures for the information */
|
||||
Start_Face_Struct(num_faces);
|
||||
vertices = (struct vert_struct *)
|
||||
malloc (sizeof (struct vert_struct) * num_vert);
|
||||
|
||||
if (num_nvert > 0)
|
||||
{
|
||||
nvertices = (struct vert_struct *)
|
||||
malloc (sizeof (struct vert_struct) * num_nvert);
|
||||
vert_norms = (int *)
|
||||
malloc (sizeof (int) * num_vert);
|
||||
/* Initialize entries to zero, in case there are 2 hits
|
||||
to the same vertex we will know it - used for determining
|
||||
the normal difference
|
||||
*/
|
||||
init_vert_norms(num_vert);
|
||||
}
|
||||
else
|
||||
nvertices = NULL;
|
||||
|
||||
if (num_texture > 0)
|
||||
{
|
||||
vert_texture = (int *) malloc (sizeof(int) * num_vert);
|
||||
init_vert_texture(num_vert);
|
||||
}
|
||||
|
||||
/* Set up the temporary 'p' pointers
|
||||
*/
|
||||
pvertices = vertices;
|
||||
pnvertices = nvertices;
|
||||
|
||||
/* Load the object into memory */
|
||||
/*printf (" Loading...");*/
|
||||
|
||||
fprintf(bands,"#%s: a triangle strip representation created by STRIPE.\n#This is a .objf file\n#by Francine Evans\n",fname);
|
||||
|
||||
/* File will be put in a list for faster execution if file is in binary */
|
||||
if (file = fopen(fname,file_open))
|
||||
{
|
||||
if (f == BINARY)
|
||||
{
|
||||
all = (char *) malloc (sizeof(char) * 255 * num);
|
||||
fread(all,sizeof(char) * 255 * num, 1, file);
|
||||
ptr = all;
|
||||
}
|
||||
else
|
||||
ptr = (char *) malloc (sizeof(char) * 255 * num);
|
||||
}
|
||||
|
||||
|
||||
while (num > 0)
|
||||
{
|
||||
num--;
|
||||
if (f == ASCII)
|
||||
fgets (ptr, sizeof(char) * 255, file);
|
||||
else
|
||||
ptr = ptr + 255;
|
||||
|
||||
/* Load in vertices/normals */
|
||||
if (*ptr == 'v')
|
||||
{
|
||||
if (*(ptr+1)=='n')
|
||||
{
|
||||
sscanf (ptr+3,"%lf%lf%lf",
|
||||
&(pnvertices->x),
|
||||
&(pnvertices->y),
|
||||
&(pnvertices->z));
|
||||
fprintf(bands,"vn %lf %lf %lf\n",
|
||||
pnvertices->x,pnvertices->y,pnvertices->z);
|
||||
++pnvertices;
|
||||
}
|
||||
else if (*(ptr+1)=='t')
|
||||
{
|
||||
sscanf (ptr+3,"%f%f%f",¢er[0],¢er[1],¢er[2]);
|
||||
fprintf(bands,"vt %f %f %f\n",center[0],center[1],center[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
sscanf (ptr+2,"%lf%lf%lf",
|
||||
&(pvertices->x),
|
||||
&(pvertices->y),
|
||||
&(pvertices->z));
|
||||
fprintf(bands,"v %lf %lf %lf\n",
|
||||
pvertices->x,pvertices->y,pvertices->z);
|
||||
++pvertices;
|
||||
}
|
||||
}
|
||||
|
||||
else if (*ptr == 'f')
|
||||
{
|
||||
/* Read in faces */
|
||||
num2 = 0;
|
||||
face_id++;
|
||||
ptr2 = ptr+1;
|
||||
normal = FALSE; texture = FALSE, normal_and_texture = FALSE;
|
||||
while (*ptr2)
|
||||
{
|
||||
if (*ptr2 >='0' && *ptr2 <='9')
|
||||
{
|
||||
num2++;
|
||||
++ptr2;
|
||||
while (*ptr2 && (*ptr2!=' ' && *ptr2!='/'))
|
||||
ptr2++;
|
||||
/* There are normals in this line */
|
||||
if (*ptr2 == '/')
|
||||
{
|
||||
if (*(ptr2+1) == '/')
|
||||
normal = TRUE;
|
||||
else
|
||||
texture = TRUE;
|
||||
}
|
||||
else if (*ptr2 == ' ')
|
||||
{
|
||||
if ((num2 == 3) && (texture))
|
||||
normal_and_texture = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
++ptr2;
|
||||
}
|
||||
|
||||
ptr2 = ptr+1;
|
||||
|
||||
/* loop on the number of numbers in this line of face data
|
||||
*/
|
||||
vert_count = 0;
|
||||
|
||||
for (loop=0;loop<num2;loop++)
|
||||
{
|
||||
/* skip the whitespace */
|
||||
while (*ptr2<'0' || *ptr2>'9')
|
||||
{
|
||||
if (*ptr2 == '-')
|
||||
break;
|
||||
ptr2++;
|
||||
}
|
||||
vertex = atoi(ptr2)-1;
|
||||
if (vertex < 0)
|
||||
{
|
||||
vertex = num_vert + vertex;
|
||||
*ptr2 = ' ';
|
||||
ptr2++;
|
||||
}
|
||||
/* If there are either normals or textures with the vertices
|
||||
in this file, the data alternates so we must read it this way
|
||||
*/
|
||||
if ( (normal) && (!normal_and_texture))
|
||||
{
|
||||
if (loop%2)
|
||||
{
|
||||
add_norm_id(vertex,vert_count);
|
||||
/* Test here to see if we added a new vertex, since the
|
||||
vertex has more than one normal and the 2 normals are greater
|
||||
than the threshold specified
|
||||
*/
|
||||
if (norm_array(vertex,0,norm_difference,nvertices,num_vert))
|
||||
{
|
||||
/* Add a new vertex and change the
|
||||
id of the vertex that we just read to the id of the new
|
||||
vertex that we just added
|
||||
*/
|
||||
/* Put it in the output file, note the added vertices will
|
||||
be after the normals and separated from the rest of the
|
||||
vertices. Will not affect our viewer
|
||||
*/
|
||||
fprintf(bands,"v %lf %lf %lf\n",
|
||||
(vertices + temp[vert_count - 1])->x,
|
||||
(vertices + temp[vert_count - 1])->y,
|
||||
(vertices + temp[vert_count - 1])->z);
|
||||
num_vert++;
|
||||
temp[vert_count - 1] = num_vert - 1;
|
||||
if (!(add_vert_id(num_vert - 1,vert_count)))
|
||||
vert_count--;
|
||||
}
|
||||
}
|
||||
/* the vertex */
|
||||
else
|
||||
{
|
||||
temp[vert_count] = vertex ;
|
||||
vert_count++;
|
||||
if (!(add_vert_id(vertex,vert_count)))
|
||||
vert_count--;
|
||||
norm_array(vertex,1,norm_difference,nvertices,num_vert);
|
||||
}
|
||||
}
|
||||
|
||||
/* Else there are vertices and textures with the data */
|
||||
else if (normal_and_texture)
|
||||
{
|
||||
if( !((loop+1)%3))
|
||||
{
|
||||
add_norm_id(vertex,vert_count);
|
||||
/* Test here to see if we added a new vertex, since the
|
||||
vertex has more than one normal and the 2 normals are greater
|
||||
than the threshold specified
|
||||
*/
|
||||
if (norm_array(vertex,0,norm_difference,nvertices,num_vert))
|
||||
{
|
||||
/* Add a new vertex and change the
|
||||
id of the vertex that we just read to the id of the new
|
||||
vertex that we just added
|
||||
*/
|
||||
/* Put it in the output file, note the added vertices will
|
||||
be after the normals and separated from the rest of the
|
||||
vertices. Will not affect our viewer
|
||||
*/
|
||||
fprintf(bands,"v %lf %lf %lf\n",
|
||||
(vertices + temp[vert_count - 1])->x,
|
||||
(vertices + temp[vert_count - 1])->y,
|
||||
(vertices + temp[vert_count - 1])->z);
|
||||
num_vert++;
|
||||
temp[vert_count - 1] = num_vert - 1;
|
||||
if (!(add_vert_id(num_vert - 1,vert_count)))
|
||||
vert_count--;
|
||||
}
|
||||
}
|
||||
/* the vertex */
|
||||
else if ((loop == 0) || (*(ptr2-1) == ' '))
|
||||
{
|
||||
temp[vert_count] = vertex ;
|
||||
vert_count++;
|
||||
if (vert_count == 4)
|
||||
quads = TRUE;
|
||||
if (!(add_vert_id(vertex,vert_count)))
|
||||
vert_count--;
|
||||
add_texture(vertex,TRUE);
|
||||
norm_array(vertex,1,norm_difference,nvertices,num_vert);
|
||||
}
|
||||
else /* The texture */
|
||||
add_texture(vertex,FALSE);
|
||||
}
|
||||
|
||||
else if ( texture )
|
||||
{
|
||||
/* the vertex */
|
||||
if (!(loop%2))
|
||||
{
|
||||
temp[vert_count] = vertex ;
|
||||
vert_count++;
|
||||
if (vert_count == 4)
|
||||
quads = TRUE;
|
||||
add_texture(vertex,TRUE);
|
||||
if (!(add_vert_id(vertex,vert_count)))
|
||||
vert_count--;
|
||||
norm_array(vertex,1,norm_difference,nvertices,num_vert);
|
||||
}
|
||||
else /* texture */
|
||||
add_texture(vertex,FALSE);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
/*** no nvertices ***/
|
||||
temp[vert_count] = vertex ;
|
||||
vert_count++;
|
||||
if (vert_count == 4)
|
||||
quads = TRUE;
|
||||
if (!(add_vert_id(vertex,vert_count)))
|
||||
vert_count--;
|
||||
}
|
||||
while (*ptr2>='0' && *ptr2<='9')
|
||||
ptr2++;
|
||||
}
|
||||
/* Done with the polygon */
|
||||
num_edges += vert_count;
|
||||
/* add it to face structure */
|
||||
if (vert_count >= 3)
|
||||
AddNewFace(ids,vert_count,face_id,norms);
|
||||
else
|
||||
face_id--;
|
||||
if (vert_count == 4)
|
||||
quads = TRUE;
|
||||
}
|
||||
else if ((g == TRUE) && (face_id > 0)
|
||||
&& ((*ptr == 'g') || (*ptr == 's') || (*ptr == 'm') || (*ptr == 'o')))
|
||||
{
|
||||
/* The user specified that the strips will be contained in each group
|
||||
from the data file, so we just finished a group and will find the
|
||||
triangle strips in it.
|
||||
*/
|
||||
Start_Edge_Struct(num_vert);
|
||||
Find_Adjacencies(face_id);
|
||||
if (quads)
|
||||
{
|
||||
Init_Table_SGI();
|
||||
Build_SGI_Table(num_vert,face_id);
|
||||
/* Code for lengths of walks in each direction */
|
||||
Save_Walks(face_id,TRUE);
|
||||
|
||||
/* Code for finding the bands */
|
||||
Find_Bands(face_id,bands,&swaps,&strips,&cost,&triangles,num_nvert,vert_norms,num_texture,vert_texture);
|
||||
|
||||
/* Remove the faces that we did so that we can
|
||||
run the strip code on the rest of the faces that are left
|
||||
*/
|
||||
if (cost != 0)
|
||||
{
|
||||
printf("Total %d triangles with %d cost\n",triangles,cost);
|
||||
Save_Rest(&face_id);
|
||||
printf("We saved %d .... now doing the local algorithm\n",face_id);
|
||||
fprintf(bands,"\n#local\n");
|
||||
End_Edge_Struct(num_vert);
|
||||
Start_Edge_Struct(num_vert);
|
||||
Find_Adjacencies(face_id);
|
||||
}
|
||||
}
|
||||
|
||||
SGI_Strip(num_vert,face_id,bands,t,tr);
|
||||
|
||||
/* Get the total cost */
|
||||
Output_TriEx(-1,-2,-3,NULL,-1,-20,cost);
|
||||
|
||||
End_Face_Struct(num_faces);
|
||||
End_Edge_Struct(num_vert);
|
||||
cost = 0;
|
||||
face_id = 0;
|
||||
quads = FALSE;
|
||||
Start_Face_Struct(num_faces-face_id);
|
||||
num_faces = num_faces - face_id;
|
||||
Free_Strips();
|
||||
}
|
||||
}
|
||||
|
||||
/* Done reading in all the information into data structures */
|
||||
num_faces = face_id;
|
||||
fclose (file);
|
||||
/*printf(" Done.\n\n");*/
|
||||
free(vertices);
|
||||
free(nvertices);
|
||||
|
||||
/*printf ("Vertices: %d\nNormals: %d\nFaces: %d\n",num_vert,num_nvert,num_faces);*/
|
||||
Start_Edge_Struct(num_vert);
|
||||
Find_Adjacencies(num_faces);
|
||||
|
||||
/* Initialize it */
|
||||
Init_Table_SGI();
|
||||
/* Build it */
|
||||
Build_SGI_Table(num_vert,num_faces);
|
||||
|
||||
InitStripTable();
|
||||
|
||||
|
||||
if (quads)
|
||||
{
|
||||
/* Code for lengths of walks in each direction */
|
||||
Save_Walks(num_faces,TRUE);
|
||||
|
||||
/* Code for finding the bands */
|
||||
Find_Bands(num_faces,bands,&swaps,&strips,&cost,&triangles,num_nvert,vert_norms,num_texture,vert_texture);
|
||||
/*printf("Total %d triangles with %d cost\n",triangles,cost);*/
|
||||
|
||||
/* Remove the faces that we did so that we can
|
||||
run the strip code on the rest of the faces that are left
|
||||
*/
|
||||
Save_Rest(&num_faces);
|
||||
/*printf("We saved %d .... now doing the local algorithm\n",num_faces);*/
|
||||
fprintf(bands,"\n#local\n");
|
||||
End_Edge_Struct(num_vert);
|
||||
Start_Edge_Struct(num_vert);
|
||||
Find_Adjacencies(num_faces);
|
||||
}
|
||||
|
||||
SGI_Strip(num_vert,num_faces,bands,t,tr);
|
||||
|
||||
/* Get the total cost */
|
||||
Output_TriEx(-1,-2,-3,NULL,-1,-20,cost);
|
||||
|
||||
End_Face_Struct(num_faces);
|
||||
End_Edge_Struct(num_vert);
|
||||
fclose(bands);
|
||||
STOP
|
||||
|
||||
get_time();
|
||||
|
||||
}
|
||||
|
811
Tools/Stripe_u/common.c
Normal file
811
Tools/Stripe_u/common.c
Normal file
|
@ -0,0 +1,811 @@
|
|||
/********************************************************************/
|
||||
/* STRIPE: converting a polygonal model to triangle strips
|
||||
Francine Evans, 1996.
|
||||
SUNY @ Stony Brook
|
||||
Advisors: Steven Skiena and Amitabh Varshney
|
||||
*/
|
||||
/********************************************************************/
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* STRIPE: common.c
|
||||
This file contains common code used in both the local and global algorithm
|
||||
*/
|
||||
/*---------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "polverts.h"
|
||||
#include "extend.h"
|
||||
#include "output.h"
|
||||
#include "triangulate.h"
|
||||
#include "util.h"
|
||||
#include "add.h"
|
||||
|
||||
int Old_Adj(int face_id)
|
||||
{
|
||||
/* Find the bucket that the face_id is currently in,
|
||||
because maybe we will be deleting it.
|
||||
*/
|
||||
PF_FACES temp = NULL;
|
||||
ListHead *pListHead;
|
||||
int size,y;
|
||||
|
||||
pListHead = PolFaces[face_id];
|
||||
temp = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 );
|
||||
if ( temp == NULL )
|
||||
{
|
||||
printf("The face was already deleted, there is an error\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
size = temp->nPolSize;
|
||||
if (Done(face_id,size,&y) == NULL)
|
||||
{
|
||||
printf("There is an error in finding the face\n");
|
||||
exit(0);
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
int Number_Adj(int id1, int id2, int curr_id)
|
||||
{
|
||||
/* Given edge whose endpoints are specified by id1 and id2,
|
||||
determine how many polygons share this edge and return that
|
||||
number minus one (since we do not want to include the polygon
|
||||
that the caller has already).
|
||||
*/
|
||||
|
||||
int size,y,count=0;
|
||||
PF_EDGES temp = NULL;
|
||||
PF_FACES temp2 = NULL;
|
||||
ListHead *pListHead;
|
||||
BOOL there= FALSE;
|
||||
|
||||
/* Always want smaller id first */
|
||||
switch_lower(&id1,&id2);
|
||||
|
||||
pListHead = PolEdges[id1];
|
||||
temp = (PF_EDGES) PeekList(pListHead,LISTHEAD,count);
|
||||
if (temp == NULL)
|
||||
/* new edge that was created might not be here */
|
||||
return 0;
|
||||
while (temp->edge[0] != id2)
|
||||
{
|
||||
count++;
|
||||
temp = (PF_EDGES) PeekList(pListHead,LISTHEAD,count);
|
||||
if (temp == NULL)
|
||||
/* This edge was not there in the original, which
|
||||
mean that we created it in the partial triangulation.
|
||||
So it is adjacent to nothing.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
/* Was not adjacent to anything else except itself */
|
||||
if (temp->edge[2] == -1)
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
/* It was adjacent to another polygon, but maybe we did this
|
||||
polygon already, and it was done partially so that this edge
|
||||
could have been done
|
||||
*/
|
||||
if (curr_id != temp->edge[1])
|
||||
{
|
||||
/* Did we use this polygon already?and it was deleted
|
||||
completely from the structure
|
||||
*/
|
||||
pListHead = PolFaces[temp->edge[1]];
|
||||
temp2 = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 );
|
||||
if (Done(temp->edge[1],temp2->nPolSize,&size) == NULL)
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
pListHead = PolFaces[temp->edge[2]];
|
||||
temp2 = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 );
|
||||
if (Done(temp->edge[2],temp2->nPolSize,&size)== NULL)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Now we have to check whether it was partially done, before
|
||||
we can say definitely if it is adjacent.
|
||||
Check each edge of the face and tally the number of adjacent
|
||||
polygons to this face.
|
||||
*/
|
||||
if ( temp2 != NULL )
|
||||
{
|
||||
/* Size of the polygon */
|
||||
size = temp2->nPolSize;
|
||||
for (y = 0; y< size; y++)
|
||||
{
|
||||
/* If we are doing partial triangulation, we must check
|
||||
to see whether the edge is still there in the polygon,
|
||||
since we might have done a portion of the polygon
|
||||
and saved the rest for later.
|
||||
*/
|
||||
if (y != (size-1))
|
||||
{
|
||||
if( ((id1 == *(temp2->pPolygon+y)) && (id2 ==*(temp2->pPolygon+y+1)))
|
||||
|| ((id2 == *(temp2->pPolygon+y)) && (id1 ==*(temp2->pPolygon+y+1))))
|
||||
/* edge is still there we are ok */
|
||||
there = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( ((id1 == *(temp2->pPolygon)) && (id2 == *(temp2->pPolygon+size-1)))
|
||||
|| ((id2 == *(temp2->pPolygon)) && (id1 ==*(temp2->pPolygon+size-1))))
|
||||
/* edge is still there we are ok */
|
||||
there = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (there )
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int Min_Adj(int id)
|
||||
{
|
||||
/* Used for the lookahead to break ties. It will
|
||||
return the minimum adjacency found at this face.
|
||||
*/
|
||||
int y,numverts,t,x=60;
|
||||
PF_FACES temp=NULL;
|
||||
ListHead *pListHead;
|
||||
|
||||
/* If polygon was used then we can't use this face */
|
||||
if (Done(id,59,&y) == NULL)
|
||||
return 60;
|
||||
|
||||
/* It was not used already */
|
||||
pListHead = PolFaces[id];
|
||||
temp = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 );
|
||||
if ( temp != NULL )
|
||||
{
|
||||
numverts = temp->nPolSize;
|
||||
for (y = 0; y< numverts; y++)
|
||||
{
|
||||
if (y != (numverts-1))
|
||||
t = Number_Adj(*(temp->pPolygon+y),*(temp->pPolygon+y+1),id);
|
||||
else
|
||||
t = Number_Adj(*(temp->pPolygon),*(temp->pPolygon+(numverts-1)),id);
|
||||
if (t < x)
|
||||
x = t;
|
||||
}
|
||||
}
|
||||
if (x == -1)
|
||||
{
|
||||
printf("Error in the look\n");
|
||||
exit(0);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Edge_Least(int *index,int *new1,int *new2,int face_id,int size)
|
||||
{
|
||||
/* We had a polygon without an input edge and now we re going to pick one
|
||||
of the edges with the least number of adjacencies to be the input
|
||||
edge
|
||||
*/
|
||||
register int x,value,smallest=60;
|
||||
|
||||
for (x = 0; x<size; x++)
|
||||
{
|
||||
if (x != (size -1) )
|
||||
value = Number_Adj(*(index+x),*(index+x+1),face_id);
|
||||
else
|
||||
value = Number_Adj(*(index),*(index+size-1),face_id);
|
||||
if (value < smallest)
|
||||
{
|
||||
smallest = value;
|
||||
if (x != (size -1))
|
||||
{
|
||||
*new1 = *(index+x);
|
||||
*new2 = *(index+x+1);
|
||||
}
|
||||
else
|
||||
{
|
||||
*new1 = *(index);
|
||||
*new2 = *(index+size-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((smallest == 60) || (smallest < 0))
|
||||
{
|
||||
printf("There is an error in getting the least edge\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Check_In_Polygon(int face_id, int *min, int size)
|
||||
{
|
||||
/* Check to see the adjacencies by going into a polygon that has
|
||||
greater than 4 sides.
|
||||
*/
|
||||
|
||||
ListHead *pListHead;
|
||||
PF_FACES temp;
|
||||
int y,id1,id2,id3,x=0,z=0;
|
||||
int saved[2];
|
||||
int big_saved[60];
|
||||
|
||||
pListHead = PolFaces[face_id];
|
||||
temp = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 );
|
||||
|
||||
/* Get the input edge that we came in on */
|
||||
Last_Edge(&id1,&id2,&id3,0);
|
||||
|
||||
/* Find the number of adjacencies to the edges that are adjacent
|
||||
to the input edge.
|
||||
*/
|
||||
for (y=0; y< size; y++)
|
||||
{
|
||||
if (y != (size-1))
|
||||
{
|
||||
if (((*(temp->pPolygon+y) == id2) && (*(temp->pPolygon+y+1) != id3))
|
||||
|| ((*(temp->pPolygon+y) == id3) && (*(temp->pPolygon+y+1) != id2)))
|
||||
{
|
||||
saved[x++] = Number_Adj(*(temp->pPolygon+y),*(temp->pPolygon+y+1),face_id);
|
||||
big_saved[z++] = saved[x-1];
|
||||
}
|
||||
else
|
||||
big_saved[z++] = Number_Adj(*(temp->pPolygon+y),*(temp->pPolygon+y+1),face_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (((*(temp->pPolygon) == id2) && (*(temp->pPolygon+size-1) != id3))
|
||||
|| ((*(temp->pPolygon) == id3) && (*(temp->pPolygon+size-1) != id2)))
|
||||
{
|
||||
saved[x++] = Number_Adj(*(temp->pPolygon),*(temp->pPolygon+size-1),face_id);
|
||||
big_saved[z++] = saved[x-1];
|
||||
}
|
||||
else
|
||||
big_saved[z++] = Number_Adj(*(temp->pPolygon),*(temp->pPolygon+size-1),face_id);
|
||||
}
|
||||
}
|
||||
/* There was an input edge */
|
||||
if (x == 2)
|
||||
{
|
||||
if (saved[0] < saved[1])
|
||||
/* Count the polygon that we will be cutting as another adjacency*/
|
||||
*min = saved[0] + 1;
|
||||
else
|
||||
*min = saved[1] + 1;
|
||||
}
|
||||
/* There was not an input edge */
|
||||
else
|
||||
{
|
||||
if (z != size)
|
||||
{
|
||||
printf("There is an error with the z %d %d\n",size,z);
|
||||
exit(0);
|
||||
}
|
||||
*min = 60;
|
||||
for (x = 0; x < size; x++)
|
||||
{
|
||||
if (*min > big_saved[x])
|
||||
*min = big_saved[x];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void New_Face (int face_id, int v1, int v2, int v3)
|
||||
{
|
||||
/* We want to change the face that was face_id, we will
|
||||
change it to a triangle, since the rest of the polygon
|
||||
was already outputtted
|
||||
*/
|
||||
ListHead *pListHead;
|
||||
PF_FACES temp = NULL;
|
||||
|
||||
pListHead = PolFaces[face_id];
|
||||
temp = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0);
|
||||
/* Check each edge of the face and tally the number of adjacent
|
||||
polygons to this face.
|
||||
*/
|
||||
if ( temp != NULL )
|
||||
{
|
||||
/* Size of the polygon */
|
||||
if (temp->nPolSize != 4)
|
||||
{
|
||||
printf("There is a miscalculation in the partial\n");
|
||||
exit (0);
|
||||
}
|
||||
temp->nPolSize = 3;
|
||||
*(temp->pPolygon) = v1;
|
||||
*(temp->pPolygon+1) = v2;
|
||||
*(temp->pPolygon+2) = v3;
|
||||
}
|
||||
}
|
||||
|
||||
void New_Size_Face (int face_id)
|
||||
{
|
||||
/* We want to change the face that was face_id, we will
|
||||
change it to a triangle, since the rest of the polygon
|
||||
was already outputtted
|
||||
*/
|
||||
ListHead *pListHead;
|
||||
PF_FACES temp = NULL;
|
||||
|
||||
pListHead = PolFaces[face_id];
|
||||
temp = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 );
|
||||
/* Check each edge of the face and tally the number of adjacent
|
||||
polygons to this face.
|
||||
*/
|
||||
if ( temp != NULL )
|
||||
(temp->nPolSize)--;
|
||||
else
|
||||
printf("There is an error in updating the size\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Check_In_Quad(int face_id,int *min)
|
||||
{
|
||||
/* Check to see what the adjacencies are for the polygons that
|
||||
are inside the quad, ie the 2 triangles that we can form.
|
||||
*/
|
||||
ListHead *pListHead;
|
||||
int y,id1,id2,id3,x=0;
|
||||
int saved[4];
|
||||
PF_FACES temp;
|
||||
register int size = 4;
|
||||
|
||||
pListHead = PolFaces[face_id];
|
||||
temp = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 );
|
||||
|
||||
/* Get the input edge that we came in on */
|
||||
Last_Edge(&id1,&id2,&id3,0);
|
||||
|
||||
/* Now find the adjacencies for the inside triangles */
|
||||
for (y = 0; y< size; y++)
|
||||
{
|
||||
/* Will not do this if the edge is the input edge */
|
||||
if (y != (size-1))
|
||||
{
|
||||
if ((((*(temp->pPolygon+y) == id2) && (*(temp->pPolygon+y+1) == id3))) ||
|
||||
(((*(temp->pPolygon+y) == id3) && (*(temp->pPolygon+y+1) == id2))))
|
||||
saved[x++] = -1;
|
||||
else
|
||||
{
|
||||
if (x == 4)
|
||||
{
|
||||
printf("There is an error in the check in quad \n");
|
||||
exit(0);
|
||||
}
|
||||
/* Save the number of Adjacent Polygons to this edge */
|
||||
saved[x++] = Number_Adj(*(temp->pPolygon+y),*(temp->pPolygon+y+1),face_id);
|
||||
}
|
||||
}
|
||||
else if ((((*(temp->pPolygon) == id2) && (*(temp->pPolygon+size-1) == id3))) ||
|
||||
(((*(temp->pPolygon) == id3) && (*(temp->pPolygon+size-1) == id2))) )
|
||||
saved[x++] = -1;
|
||||
else
|
||||
{
|
||||
if (x == 4)
|
||||
{
|
||||
printf("There is an error in the check in quad \n");
|
||||
exit(0);
|
||||
}
|
||||
/* Save the number of Adjacent Polygons to this edge */
|
||||
saved[x++] = Number_Adj(*(temp->pPolygon),*(temp->pPolygon+size-1),face_id);
|
||||
|
||||
}
|
||||
}
|
||||
if (x != 4)
|
||||
{
|
||||
printf("Did not enter all the values %d \n",x);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
*min = 10;
|
||||
for (x=0; x<4; x++)
|
||||
{
|
||||
if (x!= 3)
|
||||
{
|
||||
if ((saved[x] != -1) && (saved[x+1] != -1) &&
|
||||
((saved[x] + saved[x+1]) < *min))
|
||||
*min = saved[x] + saved[x+1];
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((saved[0] != -1) && (saved[x] != -1) &&
|
||||
((saved[x] + saved[0]) < *min))
|
||||
*min = saved[0] + saved[x];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int Get_Output_Edge(int face_id, int size, int *index,int id2,int id3)
|
||||
{
|
||||
/* Return the vertex adjacent to either input1 or input2 that
|
||||
is adjacent to the least number of polygons on the edge that
|
||||
is shared with either input1 or input2.
|
||||
*/
|
||||
register int x=0,y;
|
||||
int saved[2];
|
||||
int edges[2][1];
|
||||
|
||||
for (y = 0; y < size; y++)
|
||||
{
|
||||
if (y != (size-1))
|
||||
{
|
||||
if (((*(index+y) == id2) && (*(index+y+1) != id3))
|
||||
|| ((*(index+y) == id3) && (*(index+y+1) != id2)))
|
||||
{
|
||||
saved[x++] = Number_Adj(*(index+y),*(index+y+1),face_id);
|
||||
edges[x-1][0] = *(index+y+1);
|
||||
}
|
||||
else if (y != 0)
|
||||
{
|
||||
if (( (*(index+y) == id2) && (*(index+y-1) != id3) ) ||
|
||||
( (*(index+y) == id3) && (*(index+y-1) != id2)) )
|
||||
{
|
||||
saved[x++] = Number_Adj(*(index+y),*(index+y-1),face_id);
|
||||
edges[x-1][0] = *(index+y-1);
|
||||
}
|
||||
}
|
||||
else if (y == 0)
|
||||
{
|
||||
if (( (*(index) == id2) && (*(index+size-1) != id3) ) ||
|
||||
( (*(index) == id3) && (*(index+size-1) != id2)) )
|
||||
{
|
||||
saved[x++] = Number_Adj(*(index),*(index+size-1),face_id);
|
||||
edges[x-1][0] = *(index+size-1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (((*(index+size-1) == id2) && (*(index) != id3))
|
||||
|| ((*(index+size-1) == id3) && (*(index) != id2)))
|
||||
{
|
||||
saved[x++] = Number_Adj(*(index),*(index+size-1),face_id);
|
||||
edges[x-1][0] = *(index);
|
||||
}
|
||||
|
||||
if (( (*(index+size-1) == id2) && (*(index+y-1) != id3) ) ||
|
||||
( (*(index+size-1) == id3) && (*(index+y-1) != id2)) )
|
||||
{
|
||||
saved[x++] = Number_Adj(*(index+size-1),*(index+y-1),face_id);
|
||||
edges[x-1][0] = *(index+y-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((x != 2))
|
||||
{
|
||||
printf("There is an error in getting the input edge %d \n",x);
|
||||
exit(0);
|
||||
}
|
||||
if (saved[0] < saved[1])
|
||||
return edges[0][0];
|
||||
else
|
||||
return edges[1][0];
|
||||
|
||||
}
|
||||
|
||||
void Get_Input_Edge(int *index,int id1,int id2,int id3,int *new1,int *new2,int size,
|
||||
int face_id)
|
||||
{
|
||||
/* We had a polygon without an input edge and now we are going to pick one
|
||||
as the input edge. The last triangle was id1,id2,id3, we will try to
|
||||
get an edge to have something in common with one of those vertices, otherwise
|
||||
we will pick the edge with the least number of adjacencies.
|
||||
*/
|
||||
|
||||
register int x;
|
||||
int saved[3];
|
||||
|
||||
saved[0] = -1;
|
||||
saved[1] = -1;
|
||||
saved[2] = -1;
|
||||
|
||||
/* Go through the edges to see if there is one in common with one
|
||||
of the vertices of the last triangle that we had, preferably id2 or
|
||||
id3 since those are the last 2 things in the stack of size 2.
|
||||
*/
|
||||
for (x=0; x< size; x++)
|
||||
{
|
||||
if (*(index+x) == id1)
|
||||
{
|
||||
if (x != (size-1))
|
||||
saved[0] = *(index+x+1);
|
||||
else
|
||||
saved[0] = *(index);
|
||||
}
|
||||
|
||||
if (*(index+x) == id2)
|
||||
{
|
||||
if (x != (size-1))
|
||||
saved[1] = *(index+x+1);
|
||||
else
|
||||
saved[1] = *(index);
|
||||
}
|
||||
|
||||
if (*(index+x) == id3)
|
||||
{
|
||||
if (x != (size -1))
|
||||
saved[2] = *(index+x+1);
|
||||
else
|
||||
saved[2] = *(index);
|
||||
}
|
||||
}
|
||||
/* Now see what we saved */
|
||||
if (saved[2] != -1)
|
||||
{
|
||||
*new1 = id3;
|
||||
*new2 = saved[2];
|
||||
return;
|
||||
}
|
||||
else if (saved[1] != -1)
|
||||
{
|
||||
*new1 = id2;
|
||||
*new2 = saved[1];
|
||||
return;
|
||||
}
|
||||
else if (saved[0] != -1)
|
||||
{
|
||||
*new1 = id1;
|
||||
*new2 = saved[0];
|
||||
return;
|
||||
}
|
||||
/* We did not find anything so get the edge with the least number of adjacencies */
|
||||
Edge_Least(index,new1,new2,face_id,size);
|
||||
|
||||
}
|
||||
|
||||
int Find_Face(int current_face, int id1, int id2, int *bucket)
|
||||
{
|
||||
/* Find the face that is adjacent to the edge and is not the
|
||||
current face.
|
||||
*/
|
||||
register int size,each_poly=0,y,tally=0,count=0;
|
||||
PF_EDGES temp = NULL;
|
||||
PF_FACES temp2 = NULL;
|
||||
ListHead *pListHead;
|
||||
int next_face;
|
||||
BOOL there = FALSE;
|
||||
|
||||
|
||||
/* Always want smaller id first */
|
||||
switch_lower(&id1,&id2);
|
||||
|
||||
pListHead = PolEdges[id1];
|
||||
temp = (PF_EDGES) PeekList(pListHead,LISTHEAD,count);
|
||||
/* The input edge was a new edge */
|
||||
if (temp == NULL)
|
||||
return -1;
|
||||
|
||||
while (temp->edge[0] != id2)
|
||||
{
|
||||
count++;
|
||||
temp = (PF_EDGES) PeekList(pListHead,LISTHEAD,count);
|
||||
/* The input edge was a new edge */
|
||||
if (temp == NULL)
|
||||
return -1;
|
||||
}
|
||||
/* Was not adjacent to anything else except itself */
|
||||
if (temp->edge[2] == -1)
|
||||
return -1;
|
||||
else
|
||||
{
|
||||
if (temp->edge[2] == current_face)
|
||||
next_face = temp->edge[1];
|
||||
else
|
||||
next_face = temp->edge[2];
|
||||
}
|
||||
/* We have the other face adjacent to this edge, it is
|
||||
next_face.
|
||||
*/
|
||||
pListHead = PolFaces[next_face];
|
||||
temp2 = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 );
|
||||
|
||||
/* See if the face was already deleted, and where
|
||||
it is if it was not
|
||||
*/
|
||||
|
||||
if (Done(next_face,59,bucket) == NULL)
|
||||
return -1;
|
||||
|
||||
/* Make sure the edge is still in this polygon, and that it is not
|
||||
done
|
||||
*/
|
||||
/* Size of the polygon */
|
||||
size = temp2->nPolSize;
|
||||
for (y = 0; y< size; y++)
|
||||
{
|
||||
/* Make sure that the edge is still in the
|
||||
polygon and was not deleted, because if the edge was
|
||||
deleted, then we used it already.
|
||||
*/
|
||||
if (y != (size-1))
|
||||
{
|
||||
if( ((id1 == *(temp2->pPolygon+y)) && (id2 ==*(temp2->pPolygon+y+1)))
|
||||
|| ((id2 == *(temp2->pPolygon+y)) && (id1 ==*(temp2->pPolygon+y+1))))
|
||||
/* edge is still there we are ok */
|
||||
there = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( ((id1 == *(temp2->pPolygon)) && (id2 ==*(temp2->pPolygon+size-1)))
|
||||
|| ((id2 == *(temp2->pPolygon)) && (id1 ==*(temp2->pPolygon+size-1))))
|
||||
/* edge is still there we are ok */
|
||||
there = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!there)
|
||||
/* Edge already used and deleted from the polygon*/
|
||||
return -1;
|
||||
else
|
||||
return next_face;
|
||||
}
|
||||
|
||||
BOOL Look_Up(int id1,int id2,int face_id)
|
||||
{
|
||||
/* See if the endpoints of the edge specified by id1 and id2
|
||||
are adjacent to the face with face_id
|
||||
*/
|
||||
register int count = 0;
|
||||
PF_EDGES temp = NULL;
|
||||
ListHead *pListHead;
|
||||
PF_FACES temp2 = NULL;
|
||||
|
||||
/* Always want smaller id first */
|
||||
switch_lower(&id1,&id2);
|
||||
|
||||
pListHead = PolEdges[id1];
|
||||
temp = (PF_EDGES) PeekList(pListHead,LISTHEAD,count);
|
||||
if (temp == NULL)
|
||||
/* Was a new edge that we created */
|
||||
return 0;
|
||||
|
||||
while (temp->edge[0] != id2)
|
||||
{
|
||||
count++;
|
||||
temp = (PF_EDGES) PeekList(pListHead,LISTHEAD,count);
|
||||
if (temp == NULL)
|
||||
/* Was a new edge that we created */
|
||||
return 0;
|
||||
}
|
||||
/* Was not adjacent to anything else except itself */
|
||||
if ((temp->edge[2] == face_id) || (temp->edge[1] == face_id))
|
||||
{
|
||||
/* Edge was adjacent to face, make sure that edge is
|
||||
still there
|
||||
*/
|
||||
if (Exist(face_id,id1,id2))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void Add_Id_Strips(int id, int where)
|
||||
{
|
||||
/* Just save the triangle for later */
|
||||
P_STRIPS pfNode;
|
||||
|
||||
pfNode = (P_STRIPS) malloc(sizeof(Strips) );
|
||||
if ( pfNode )
|
||||
{
|
||||
pfNode->face_id = id;
|
||||
if (where == 1)
|
||||
AddTail(strips[0],(PLISTINFO) pfNode);
|
||||
/* We are backtracking in the strip */
|
||||
else
|
||||
AddHead(strips[0],(PLISTINFO) pfNode);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("There is not enough memory to allocate for the strips\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int Num_Adj(int id1, int id2)
|
||||
{
|
||||
/* Given edge whose endpoints are specified by id1 and id2,
|
||||
determine how many polygons share this edge and return that
|
||||
number minus one (since we do not want to include the polygon
|
||||
that the caller has already).
|
||||
*/
|
||||
|
||||
PF_EDGES temp = NULL;
|
||||
ListHead *pListHead;
|
||||
register count=-1;
|
||||
|
||||
/* Always want smaller id first */
|
||||
switch_lower(&id1,&id2);
|
||||
|
||||
pListHead = PolEdges[id1];
|
||||
temp = (PF_EDGES) PeekList(pListHead,LISTHEAD,count);
|
||||
if (temp == NULL)
|
||||
{
|
||||
printf("There is an error in the creation of the table \n");
|
||||
exit(0);
|
||||
}
|
||||
while (temp->edge[0] != id2)
|
||||
{
|
||||
count++;
|
||||
temp = (PF_EDGES) PeekList(pListHead,LISTHEAD,count);
|
||||
if (temp == NULL)
|
||||
{
|
||||
printf("There is an error in the creation of the table\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
/* Was not adjacent to anything else except itself */
|
||||
if (temp->edge[2] == -1)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void Add_Sgi_Adj(int bucket,int face_id)
|
||||
{
|
||||
/* This routine will add the face to the proper bucket,
|
||||
depending on how many faces are adjacent to it (what the
|
||||
value bucket should be).
|
||||
*/
|
||||
P_ADJACENCIES pfNode;
|
||||
|
||||
pfNode = (P_ADJACENCIES) malloc(sizeof(ADJACENCIES) );
|
||||
if ( pfNode )
|
||||
{
|
||||
pfNode->face_id = face_id;
|
||||
AddHead(array[bucket],(PLISTINFO) pfNode);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Out of memory for the SGI adj list!\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
void Find_Adjacencies(int num_faces)
|
||||
{
|
||||
register int x,y;
|
||||
register int numverts;
|
||||
PF_FACES temp=NULL;
|
||||
ListHead *pListHead;
|
||||
|
||||
/* Fill in the adjacencies data structure for all the faces */
|
||||
for (x=0;x<num_faces;x++)
|
||||
{
|
||||
pListHead = PolFaces[x];
|
||||
temp = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 );
|
||||
if ( temp != NULL )
|
||||
{
|
||||
numverts = temp->nPolSize;
|
||||
if (numverts != 1)
|
||||
{
|
||||
for (y = 0; y< numverts; y++)
|
||||
{
|
||||
if (y != (numverts-1))
|
||||
Add_AdjEdge(*(temp->pPolygon+y),*(temp->pPolygon+y+1),x,y);
|
||||
|
||||
else
|
||||
Add_AdjEdge(*(temp->pPolygon),*(temp->pPolygon+(numverts-1)),x,numverts-1);
|
||||
|
||||
}
|
||||
}
|
||||
temp = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
41
Tools/Stripe_u/common.h
Normal file
41
Tools/Stripe_u/common.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/********************************************************************/
|
||||
/* STRIPE: converting a polygonal model to triangle strips
|
||||
Francine Evans, 1996.
|
||||
SUNY @ Stony Brook
|
||||
Advisors: Steven Skiena and Amitabh Varshney
|
||||
*/
|
||||
/********************************************************************/
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* STRIPE: common.h
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
void Add_AdjEdge();
|
||||
void Find_Adjacencies();
|
||||
void Add_Sgi_Adj();
|
||||
int Num_Adj();
|
||||
void Add_Id_Strips();
|
||||
BOOL Look_Up();
|
||||
int Number_Adj();
|
||||
int Old_Adj();
|
||||
int Min_Adj();
|
||||
int Find_Face();
|
||||
void Edge_Least();
|
||||
void Get_Input_Edge();
|
||||
int Get_Output_Edge();
|
||||
void Check_In_Polygon();
|
||||
void Check_In_Quad();
|
||||
void New_Size_Face ();
|
||||
void New_Face ();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
13
Tools/Stripe_u/define.h
Normal file
13
Tools/Stripe_u/define.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
|
||||
#define VRDATA double
|
||||
#define MAX1 60
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
#define PI 3.1415926573
|
||||
|
||||
struct vert_struct {
|
||||
VRDATA x, y, z; /* point coordinates */
|
||||
};
|
||||
|
17
Tools/Stripe_u/extend.h
Normal file
17
Tools/Stripe_u/extend.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
/********************************************************************/
|
||||
/* STRIPE: converting a polygonal model to triangle strips
|
||||
Francine Evans, 1996.
|
||||
SUNY @ Stony Brook
|
||||
Advisors: Steven Skiena and Amitabh Varshney
|
||||
*/
|
||||
/********************************************************************/
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* STRIPE: extend.h
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
int Bottom_Left();
|
||||
int Top_Left();
|
||||
void Start_Edge();
|
||||
|
||||
|
110
Tools/Stripe_u/free.c
Normal file
110
Tools/Stripe_u/free.c
Normal file
|
@ -0,0 +1,110 @@
|
|||
/********************************************************************/
|
||||
/* STRIPE: converting a polygonal model to triangle strips
|
||||
Francine Evans, 1996.
|
||||
SUNY @ Stony Brook
|
||||
Advisors: Steven Skiena and Amitabh Varshney
|
||||
*/
|
||||
/********************************************************************/
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* STRIPE: free.c
|
||||
This file contains the code used to free the data structures.
|
||||
*/
|
||||
/*---------------------------------------------------------------------*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "polverts.h"
|
||||
|
||||
void ParseAndFreeList( ListHead *pListHead )
|
||||
{
|
||||
PLISTINFO value;
|
||||
register int c,num;
|
||||
|
||||
/* Freeing a linked list */
|
||||
num = NumOnList(pListHead);
|
||||
for (c = 0; c< num; c++)
|
||||
value = RemHead(pListHead);
|
||||
}
|
||||
|
||||
void FreePolygonNode( PF_VERTS pfVerts)
|
||||
{
|
||||
/* Free a vertex node */
|
||||
if ( pfVerts->pPolygon )
|
||||
free( pfVerts->pPolygon );
|
||||
free( pfVerts );
|
||||
|
||||
}
|
||||
|
||||
void Free_Strips()
|
||||
{
|
||||
P_STRIPS temp = NULL;
|
||||
|
||||
/* Free strips data structure */
|
||||
if (strips[0] == NULL)
|
||||
return;
|
||||
else
|
||||
ParseAndFreeList(strips[0]);
|
||||
}
|
||||
|
||||
void FreeFaceNode( PF_FACES pfFaces)
|
||||
{
|
||||
/* Free face node */
|
||||
if ( pfFaces->pPolygon )
|
||||
free( pfFaces->pPolygon );
|
||||
free( pfFaces );
|
||||
}
|
||||
|
||||
|
||||
void FreeFaceTable(int nSize)
|
||||
{
|
||||
register int nIndex;
|
||||
|
||||
for ( nIndex=0; nIndex < nSize; nIndex++ )
|
||||
{
|
||||
if ( PolFaces[nIndex] != NULL )
|
||||
ParseAndFreeList( PolFaces[nIndex] );
|
||||
}
|
||||
free( PolFaces );
|
||||
}
|
||||
|
||||
void FreeEdgeTable(int nSize)
|
||||
{
|
||||
register int nIndex;
|
||||
|
||||
for ( nIndex=0; nIndex < nSize; nIndex++ )
|
||||
{
|
||||
if ( PolEdges[nIndex] != NULL )
|
||||
ParseAndFreeList( PolEdges[nIndex] );
|
||||
}
|
||||
free( PolEdges );
|
||||
}
|
||||
|
||||
|
||||
void Free_All_Strips()
|
||||
{
|
||||
|
||||
ListHead *pListHead;
|
||||
register int y;
|
||||
|
||||
for (y =0; ; y++)
|
||||
{
|
||||
pListHead = all_strips[y];
|
||||
if (pListHead == NULL)
|
||||
return;
|
||||
else
|
||||
ParseAndFreeList(all_strips[y]);
|
||||
}
|
||||
}
|
||||
|
||||
void End_Face_Struct(int numfaces)
|
||||
{
|
||||
FreeFaceTable(numfaces);
|
||||
}
|
||||
|
||||
void End_Edge_Struct(int numverts)
|
||||
{
|
||||
FreeEdgeTable(numverts);
|
||||
}
|
||||
|
||||
|
22
Tools/Stripe_u/free.h
Normal file
22
Tools/Stripe_u/free.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
/********************************************************************/
|
||||
/* STRIPE: converting a polygonal model to triangle strips
|
||||
Francine Evans, 1996.
|
||||
SUNY @ Stony Brook
|
||||
Advisors: Steven Skiena and Amitabh Varshney
|
||||
*/
|
||||
/********************************************************************/
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* STRIPE: free.h
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
void Free_All_Strips();
|
||||
void ParseAndFreeList();
|
||||
void FreePolygonNode();
|
||||
void Free_Strips();
|
||||
void FreeFaceTable();
|
||||
void FreeEdgeTable();
|
||||
void End_Face_Struct();
|
||||
void End_Edge_Struct();
|
||||
|
||||
|
37
Tools/Stripe_u/global.h
Normal file
37
Tools/Stripe_u/global.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/********************************************************************/
|
||||
/* STRIPE: converting a polygonal model to triangle strips
|
||||
Francine Evans, 1996.
|
||||
SUNY @ Stony Brook
|
||||
Advisors: Steven Skiena and Amitabh Varshney
|
||||
*/
|
||||
/********************************************************************/
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* STRIPE: global.h
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
#define VRDATA double
|
||||
#define MAX1 60
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
#ifndef PI
|
||||
# define PI 3.1415926573
|
||||
#endif /* PI */
|
||||
#define ATOI(C) (C -'0')
|
||||
#define X 0
|
||||
#define Y 1
|
||||
#define Z 2
|
||||
#define EVEN(x) (((x) & 1) == 0)
|
||||
#define MAX_BAND 10000
|
||||
|
||||
struct vert_struct {
|
||||
VRDATA x, y, z; /* point coordinates */
|
||||
};
|
||||
|
||||
int ids[MAX1];
|
||||
int norms[MAX1];
|
||||
int *vert_norms;
|
||||
int *vert_texture;
|
||||
|
151
Tools/Stripe_u/glove.h
Normal file
151
Tools/Stripe_u/glove.h
Normal file
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
* dg2lib.h - header file for the DG2 library libdg2.a
|
||||
*
|
||||
* copyright 1988-92 VPL Research Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/******** error returns from the library */
|
||||
|
||||
extern int DG2_error; /* for error information */
|
||||
extern float DG2_lib_version; /* for the library version */
|
||||
extern int DG2_box_version; /* for the firmware version */
|
||||
extern int DG2_glove_sensors; /* for the number of sensors in the glove */
|
||||
|
||||
/* defines for DG2_error values */
|
||||
|
||||
#define DG2_AOK 0
|
||||
#define DG2_SETTINGS_FILE -1
|
||||
#define DG2_SERIAL_OPEN -2
|
||||
#define DG2_SERIAL_PORT -4
|
||||
#define DG2_RESET -6
|
||||
#define DG2_PARAMETER -7
|
||||
#define DG2_FILE_IO -8
|
||||
#define DG2_CALIBRATION_FILE -9
|
||||
#define DG2_GESTURE_FILE -10
|
||||
#define DG2_CAL_GEST_FILES -11
|
||||
/* defines for DG2_response() */
|
||||
|
||||
#define DATAGLOVE 1
|
||||
#define POLHEMUS 2
|
||||
#define GESTURE 8
|
||||
|
||||
#define DG2_60Hz 1
|
||||
#define DG2_30Hz 2
|
||||
#define DG2_oneShot 3
|
||||
|
||||
/* defines for DG2_DataGlove_select() */
|
||||
|
||||
#define THUMB_INNER 0x1
|
||||
#define THUMB_OUTER 0x2
|
||||
#define INDEX_INNER 0x4
|
||||
#define INDEX_OUTER 0x8
|
||||
#define MIDDLE_INNER 0x10
|
||||
#define MIDDLE_OUTER 0x20
|
||||
#define RING_INNER 0x40
|
||||
#define RING_OUTER 0x80
|
||||
#define LITTLE_INNER 0x100
|
||||
#define LITTLE_OUTER 0x200
|
||||
#define NORMAL_JOINTS 0x3ff
|
||||
#define FLEX11 0x400
|
||||
#define FLEX12 0x800
|
||||
#define FLEX13 0x1000
|
||||
#define FLEX14 0x2000
|
||||
#define FLEX15 0x4000
|
||||
#define FLEX16 0x8000
|
||||
|
||||
|
||||
/* defines for DG2_DataGlove_trans_select() */
|
||||
|
||||
#define DG2_TRANSLATED 5
|
||||
#define DG2_RAW 6
|
||||
|
||||
/* defines for DG2_Polhemus_units() */
|
||||
|
||||
#define POL_RAW 0
|
||||
#define POL_INCHES 1
|
||||
#define POL_CM 2
|
||||
|
||||
/* defines for DG2_user_IRQ() */
|
||||
|
||||
#define IRQ_ON 1
|
||||
#define IRQ_OFF 2
|
||||
|
||||
|
||||
/* defines for DG2_get_data() */
|
||||
|
||||
#define DG2_report 1
|
||||
#define DG2_userport 2
|
||||
|
||||
|
||||
/* dg2 command codes*/
|
||||
#define LEADINGBYTE 0x24
|
||||
#define RPT60 0x41 /* repeat 60 */
|
||||
#define RPT30 0x42 /* repeat 30 */
|
||||
#define ONESHOT 0x43 /* one shot */
|
||||
#define SYSID 0x44 /* system ID */
|
||||
#define EPTBUF 0x45 /* empty buffer */
|
||||
#define USRRD 0x46 /* user read */
|
||||
#define USRIRQ 0x47 /* user IRQ */
|
||||
#define QBRT 0x48 /* query bright */
|
||||
#define CDRST 0x49 /* cold reset */
|
||||
#define WMRST 0x4A /* warm reset */
|
||||
#define MEMALLO 0x4B /* memory alloc */
|
||||
#define DLTSND 0x4C /* delta send */
|
||||
#define SETBRT 0x4D /* set bright */
|
||||
#define SETDIM 0x4E /* set dim */
|
||||
#define FILBUF 0x4F /* fill buffer */
|
||||
#define LDTBL 0x50 /* load table */
|
||||
#define LDPOL 0x51 /* send up to 63 bytes to Polhemus */
|
||||
#define ANGLE 0x52 /* angles */
|
||||
#define NSNSR 0x53 /* num sensors */
|
||||
#define SETFB 0x54 /* set feedback */
|
||||
#define QCUT 0X55 /* query cutoff*/
|
||||
#define SETCUT 0X56 /* set cutoff */
|
||||
#define FLXVAL 0X57 /* raw flex values */
|
||||
#define USRWR 0X58 /* user write */
|
||||
#define JNTMAP 0X59 /* joint map */
|
||||
#define ERRMESS 0XFF /* error in command input */
|
||||
#define TIMOUT 0XFE /* timed out during command */
|
||||
|
||||
/* response structure */
|
||||
|
||||
typedef struct DG2_data {
|
||||
char gesture;
|
||||
double location[3]; /* X,Y,Z */
|
||||
double orientation[3]; /* yaw, pitch, roll */
|
||||
short flex[16];
|
||||
char gesture_name[20];
|
||||
short reserved[16];
|
||||
/* user port data: */
|
||||
char user_nibble;
|
||||
char user_analog[3];
|
||||
} DG2_data;
|
||||
|
||||
|
||||
/**************function prototypes*************/
|
||||
/*NOTE: all DG2_ functions return -1 on error*/
|
||||
|
||||
extern int DG2_open(char *portname, int baud);
|
||||
extern int DG2_close(int filedes);
|
||||
extern int DG2_direct(int filedes,char *message,int count);
|
||||
extern int DG2_response(int filedes,int devices,int rate);
|
||||
extern int DG2_DataGlove_select(int filedes,int flex_sensors);
|
||||
extern int DG2_DataGlove_translation(int filedes,int flex_sensors,char table[16][256]);
|
||||
extern int DG2_DataGlove_trans_select(int filedes,int status);
|
||||
extern int DG2_DataGlove_LED_set(int filedes,int LED);
|
||||
extern int DG2_DataGlove_LED_read(int filedes);
|
||||
extern int DG2_Polhemus_units(int filedes,char type);
|
||||
extern int DG2_Polhemus_direct(int filedes,char *message,int count);
|
||||
extern int DG2_user_write(int filedes,int nibble);
|
||||
extern int DG2_user_IRQ(int filedes,int mode);
|
||||
extern int DG2_user_read(int filedes,DG2_data *data);
|
||||
extern int DG2_get_data(int filedes,DG2_data *data);
|
||||
extern int DG2_gesture_load(int filedes,char *calib,char *gest);
|
||||
|
||||
/*use this with caution since it does not return until it gets a correct
|
||||
*response from the DG2
|
||||
*/
|
||||
extern int DG2U_get_reply(int filedes,char *buff,int response,int size);
|
217
Tools/Stripe_u/init.c
Normal file
217
Tools/Stripe_u/init.c
Normal file
|
@ -0,0 +1,217 @@
|
|||
/********************************************************************/
|
||||
/* STRIPE: converting a polygonal model to triangle strips
|
||||
Francine Evans, 1996.
|
||||
SUNY @ Stony Brook
|
||||
Advisors: Steven Skiena and Amitabh Varshney
|
||||
*/
|
||||
/********************************************************************/
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* STRIPE: init.c
|
||||
This file contains the initialization of data structures.
|
||||
*/
|
||||
/*---------------------------------------------------------------------*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "global.h"
|
||||
#include "polverts.h"
|
||||
|
||||
void init_vert_norms(int num_vert)
|
||||
{
|
||||
/* Initialize vertex/normal array to have all zeros to
|
||||
start with.
|
||||
*/
|
||||
register int x;
|
||||
|
||||
for (x = 0; x < num_vert; x++)
|
||||
*(vert_norms + x) = 0;
|
||||
}
|
||||
|
||||
void init_vert_texture(int num_vert)
|
||||
{
|
||||
/* Initialize vertex/normal array to have all zeros to
|
||||
start with.
|
||||
*/
|
||||
register int x;
|
||||
|
||||
for (x = 0; x < num_vert; x++)
|
||||
*(vert_texture + x) = 0;
|
||||
}
|
||||
|
||||
BOOL InitVertTable( int nSize )
|
||||
{
|
||||
register int nIndex;
|
||||
|
||||
/* Initialize the vertex table */
|
||||
PolVerts = (ListHead**) malloc(sizeof(ListHead*) * nSize );
|
||||
if ( PolVerts )
|
||||
{
|
||||
for ( nIndex=0; nIndex < nSize; nIndex++ )
|
||||
{
|
||||
PolVerts[nIndex] = NULL;
|
||||
}
|
||||
return( TRUE );
|
||||
}
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
BOOL InitFaceTable( int nSize )
|
||||
{
|
||||
register int nIndex;
|
||||
|
||||
/* Initialize the face table */
|
||||
PolFaces = (ListHead**) malloc(sizeof(ListHead*) * nSize );
|
||||
if ( PolFaces )
|
||||
{
|
||||
for ( nIndex=0; nIndex < nSize; nIndex++ )
|
||||
{
|
||||
PolFaces[nIndex] = NULL;
|
||||
}
|
||||
return( TRUE );
|
||||
}
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
BOOL InitEdgeTable( int nSize )
|
||||
{
|
||||
register int nIndex;
|
||||
|
||||
/* Initialize the edge table */
|
||||
PolEdges = (ListHead**) malloc(sizeof(ListHead*) * nSize );
|
||||
if ( PolEdges )
|
||||
{
|
||||
for ( nIndex=0; nIndex < nSize; nIndex++ )
|
||||
{
|
||||
PolEdges[nIndex] = NULL;
|
||||
}
|
||||
return( TRUE );
|
||||
}
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
|
||||
void InitStripTable( )
|
||||
{
|
||||
|
||||
PLISTHEAD pListHead;
|
||||
|
||||
/* Initialize the strip table */
|
||||
pListHead = ( PLISTHEAD ) malloc(sizeof(ListHead));
|
||||
if ( pListHead )
|
||||
{
|
||||
InitList( pListHead );
|
||||
strips[0] = pListHead;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Out of memory !\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Init_Table_SGI()
|
||||
{
|
||||
PLISTHEAD pListHead;
|
||||
int max_adj = 60;
|
||||
register int x;
|
||||
|
||||
/* This routine will initialize the table that will
|
||||
have the faces sorted by the number of adjacent polygons
|
||||
to it.
|
||||
*/
|
||||
|
||||
for (x=0; x< max_adj; x++)
|
||||
{
|
||||
/* We are allowing the max number of sides of a polygon
|
||||
to be max_adj.
|
||||
*/
|
||||
pListHead = ( PLISTHEAD ) malloc(sizeof(ListHead));
|
||||
if ( pListHead )
|
||||
{
|
||||
InitList( pListHead );
|
||||
array[x] = pListHead;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Out of memory !\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BuildVertTable( int nSize )
|
||||
{
|
||||
register int nIndex;
|
||||
PLISTHEAD pListHead;
|
||||
|
||||
for ( nIndex=0; nIndex < nSize; nIndex++ )
|
||||
{
|
||||
pListHead = ( PLISTHEAD ) malloc(sizeof(ListHead));
|
||||
if ( pListHead )
|
||||
{
|
||||
InitList( pListHead );
|
||||
PolVerts[nIndex] = pListHead;
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BuildFaceTable( int nSize )
|
||||
{
|
||||
register int nIndex;
|
||||
PLISTHEAD pListHead;
|
||||
|
||||
for ( nIndex=0; nIndex < nSize; nIndex++ )
|
||||
{
|
||||
pListHead = ( PLISTHEAD ) malloc(sizeof(ListHead));
|
||||
if ( pListHead )
|
||||
{
|
||||
InitList( pListHead );
|
||||
PolFaces[nIndex] = pListHead;
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void BuildEdgeTable( int nSize )
|
||||
{
|
||||
register int nIndex;
|
||||
PLISTHEAD pListHead;
|
||||
|
||||
for ( nIndex=0; nIndex < nSize; nIndex++ )
|
||||
{
|
||||
pListHead = ( PLISTHEAD ) malloc(sizeof(ListHead));
|
||||
if ( pListHead )
|
||||
{
|
||||
InitList( pListHead );
|
||||
PolEdges[nIndex] = pListHead;
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Start_Face_Struct(int numfaces)
|
||||
{
|
||||
if (InitFaceTable(numfaces))
|
||||
{
|
||||
BuildFaceTable(numfaces);
|
||||
}
|
||||
}
|
||||
|
||||
void Start_Edge_Struct(int numverts)
|
||||
{
|
||||
if (InitEdgeTable(numverts))
|
||||
{
|
||||
BuildEdgeTable(numverts);
|
||||
}
|
||||
}
|
||||
|
||||
|
30
Tools/Stripe_u/init.h
Normal file
30
Tools/Stripe_u/init.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
/********************************************************************/
|
||||
/* STRIPE: converting a polygonal model to triangle strips
|
||||
Francine Evans, 1996.
|
||||
SUNY @ Stony Brook
|
||||
Advisors: Steven Skiena and Amitabh Varshney
|
||||
*/
|
||||
/********************************************************************/
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* STRIPE: init.h
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
void init_vert_norms();
|
||||
void init_vert_texture();
|
||||
BOOL InitVertTable();
|
||||
BOOL InitFaceTable();
|
||||
BOOL InitEdgeTable();
|
||||
void InitStripTable();
|
||||
void Init_Table_SGI();
|
||||
void BuildVertTable();
|
||||
void BuildFaceTable();
|
||||
void BuildEdgeTable();
|
||||
void Start_Face_Struct();
|
||||
void Start_Edge_Struct();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
123
Tools/Stripe_u/local.c
Normal file
123
Tools/Stripe_u/local.c
Normal file
|
@ -0,0 +1,123 @@
|
|||
/********************************************************************/
|
||||
/* STRIPE: converting a polygonal model to triangle strips
|
||||
Francine Evans, 1996.
|
||||
SUNY @ Stony Brook
|
||||
Advisors: Steven Skiena and Amitabh Varshney
|
||||
*/
|
||||
/********************************************************************/
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* STRIPE: local.c
|
||||
This file contains the code that initializes the data structures for
|
||||
the local algorithm, and starts the local algorithm going.
|
||||
*/
|
||||
/*---------------------------------------------------------------------*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "polverts.h"
|
||||
#include "local.h"
|
||||
#include "triangulatex.h"
|
||||
#include "sturctsex.h"
|
||||
#include "common.h"
|
||||
#include "outputex.h"
|
||||
#include "util.h"
|
||||
#include "init.h"
|
||||
|
||||
void Find_StripsEx(FILE *output,FILE *strip,int *ties,
|
||||
int tie, int triangulate,
|
||||
int swaps,int *next_id)
|
||||
{
|
||||
/* This routine will peel off the strips from the model */
|
||||
|
||||
ListHead *pListHead;
|
||||
P_ADJACENCIES temp = NULL;
|
||||
register int max,bucket=0;
|
||||
BOOL whole_flag = TRUE;
|
||||
int dummy = 0;
|
||||
|
||||
/* Set the last known input edge to be null */
|
||||
Last_Edge(&dummy,&dummy,&dummy,1);
|
||||
|
||||
/* Search for lowest adjacency polygon and output strips */
|
||||
while (whole_flag)
|
||||
{
|
||||
bucket = -1;
|
||||
/* Search for polygons in increasing number of adjacencies */
|
||||
while (bucket < 59)
|
||||
{
|
||||
bucket++;
|
||||
pListHead = array[bucket];
|
||||
max = NumOnList(pListHead);
|
||||
if (max > 0)
|
||||
{
|
||||
temp = (P_ADJACENCIES) PeekList(pListHead,LISTHEAD,0);
|
||||
if (temp == NULL)
|
||||
{
|
||||
printf("Error in the buckets%d %d %d\n",bucket,max,0);
|
||||
exit(0);
|
||||
}
|
||||
Polygon_OutputEx(temp,temp->face_id,bucket,pListHead,
|
||||
output,strip,ties,tie,triangulate,swaps,next_id,1);
|
||||
/* Try to extend backwards, if the starting polygon in the
|
||||
strip had 2 or more adjacencies to begin with
|
||||
*/
|
||||
if (bucket >= 2)
|
||||
Extend_BackwardsEx(temp->face_id,output,strip,ties,tie,triangulate,
|
||||
swaps,next_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Went through the whole structure, it is empty and we are done.
|
||||
*/
|
||||
if ((bucket == 59) && (max == 0))
|
||||
whole_flag = FALSE;
|
||||
|
||||
/* We just finished a strip, send dummy data to signal the end
|
||||
of the strip so that we can output it.
|
||||
*/
|
||||
else
|
||||
{
|
||||
Output_TriEx(-1,-2,-3,output,-1,-10,1);
|
||||
Last_Edge(&dummy,&dummy,&dummy,1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SGI_Strip(int num_verts,int num_faces,FILE *output,
|
||||
int ties,int triangulate)
|
||||
|
||||
{
|
||||
FILE *strip;
|
||||
int next_id = -1,t=0;
|
||||
|
||||
strip = fopen("output.d","w");
|
||||
/* We are going to output and find triangle strips
|
||||
according the the method that SGI uses, ie always
|
||||
choosing as the next triangle in our strip the triangle
|
||||
that has the least number of adjacencies. We do not have
|
||||
all triangles and will be triangulating on the fly those
|
||||
polygons that have more than 3 sides.
|
||||
*/
|
||||
|
||||
/* Build a table that has all the polygons sorted by the number
|
||||
of polygons adjacent to it.
|
||||
*/
|
||||
/* Initialize it */
|
||||
Init_Table_SGI();
|
||||
/* Build it */
|
||||
Build_SGI_Table(num_verts,num_faces);
|
||||
|
||||
/* We will have a structure to hold all the strips, until
|
||||
outputted.
|
||||
*/
|
||||
InitStripTable();
|
||||
/* Now we have the structure built to find the polygons according
|
||||
to the number of adjacencies. Now use the SGI Method to find
|
||||
strips according to the adjacencies
|
||||
*/
|
||||
Find_StripsEx(output,strip,&t,ties,triangulate,ON,&next_id);
|
||||
|
||||
}
|
19
Tools/Stripe_u/local.h
Normal file
19
Tools/Stripe_u/local.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
/********************************************************************/
|
||||
/* STRIPE: converting a polygonal model to triangle strips
|
||||
Francine Evans, 1996.
|
||||
SUNY @ Stony Brook
|
||||
Advisors: Steven Skiena and Amitabh Varshney
|
||||
*/
|
||||
/********************************************************************/
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* STRIPE:local.h
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
void Local_Polygon_Output();
|
||||
void Local_Output_Tri();
|
||||
int Different();
|
||||
void Local_Non_Blind_Triangulate();
|
||||
void Local_Blind_Triangulate();
|
||||
void Local_Triangulate_Polygon();
|
||||
void SGI_Strip();
|
3
Tools/Stripe_u/my_global.h
Normal file
3
Tools/Stripe_u/my_global.h
Normal file
|
@ -0,0 +1,3 @@
|
|||
int change_in_stripEx = 0;
|
||||
int change_in_strip = 0;
|
||||
|
1667
Tools/Stripe_u/newpolve.c
Normal file
1667
Tools/Stripe_u/newpolve.c
Normal file
File diff suppressed because it is too large
Load diff
181
Tools/Stripe_u/options.c
Normal file
181
Tools/Stripe_u/options.c
Normal file
|
@ -0,0 +1,181 @@
|
|||
/********************************************************************/
|
||||
/* STRIPE: converting a polygonal model to triangle strips
|
||||
Francine Evans, 1996.
|
||||
SUNY @ Stony Brook
|
||||
Advisors: Steven Skiena and Amitabh Varshney
|
||||
*/
|
||||
/********************************************************************/
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* STRIPE: options.c
|
||||
This file contains routines that are used to determine the options
|
||||
that were specified by the user
|
||||
*/
|
||||
/*---------------------------------------------------------------------*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "options.h"
|
||||
#include "global.h"
|
||||
|
||||
int power_10(int power)
|
||||
{
|
||||
/* Raise 10 to the power */
|
||||
register int i,p;
|
||||
|
||||
p = 1;
|
||||
for (i = 1; i <= power; ++i)
|
||||
p = p * 10;
|
||||
return p;
|
||||
}
|
||||
|
||||
float power_negative(int power)
|
||||
{
|
||||
/* Raise 10 to the negative power */
|
||||
|
||||
register int i;
|
||||
float p;
|
||||
|
||||
p = (float)1;
|
||||
for (i = 1; i<=power; i++)
|
||||
p = p * (float).1;
|
||||
return p;
|
||||
}
|
||||
|
||||
float convert_array(int num[],int stack_size)
|
||||
{
|
||||
/* Convert an array of characters to an integer */
|
||||
|
||||
register int counter,c;
|
||||
float temp =(float)0.0;
|
||||
|
||||
for (c=(stack_size-1), counter = 0; c>=0; c--, counter++)
|
||||
{
|
||||
if (num[c] == -1)
|
||||
/* We are at the decimal point, convert to decimal
|
||||
less than 1
|
||||
*/
|
||||
{
|
||||
counter = -1;
|
||||
temp = power_negative(stack_size - c - 1) * temp;
|
||||
}
|
||||
else
|
||||
temp += power_10(counter) * num[c];
|
||||
}
|
||||
|
||||
return(temp);
|
||||
}
|
||||
|
||||
float get_options(int argc, char **argv, int *f, int *t, int *tr, int *group)
|
||||
{
|
||||
char c;
|
||||
int count = 0;
|
||||
int buffer[MAX1];
|
||||
int next = 0;
|
||||
/* tie variable */
|
||||
enum tie_options tie = FIRST;
|
||||
/* triangulation variable */
|
||||
enum triangulation_options triangulate = WHOLE;
|
||||
/* normal difference variable (in degrees) */
|
||||
float norm_difference = (float)360.0;
|
||||
/* file-type variable */
|
||||
enum file_options file_type = ASCII;
|
||||
|
||||
/* User has the wrong number of options */
|
||||
if ((argc > 5) || (argc < 2))
|
||||
{
|
||||
printf("Usage: bands -[file_option][ties_option][triangulation_option][normal_difference] file_name\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* Interpret the options specified */
|
||||
while (--argc > 0 && (*++argv)[0] == '-')
|
||||
{
|
||||
/* At the next option that was specified */
|
||||
next = 1;
|
||||
while (c = *++argv[0])
|
||||
switch (c)
|
||||
{
|
||||
case 'f':
|
||||
/* Use the first polygon we see. */
|
||||
tie = FIRST;
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
/* Randomly choose the next polygon */
|
||||
tie = RANDOM;
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
/* Alternate direction in choosing the next polygon */
|
||||
tie = ALTERNATE;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
/* Use lookahead to choose the next polygon */
|
||||
tie = LOOK;
|
||||
break;
|
||||
|
||||
case 'q':
|
||||
/* Try to reduce swaps */
|
||||
tie = SEQUENTIAL;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
/* Use partial triangulation of polygons */
|
||||
triangulate = PARTIAL;
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
/* Use whole triangulation of polygons */
|
||||
triangulate = WHOLE;
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
/* Input file is in binary */
|
||||
file_type = BINARY;
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
/* Strips will be grouped according to the groups in
|
||||
the data file. We will have to restrict strips to be
|
||||
in the grouping of the data file.
|
||||
*/
|
||||
*group = 1;
|
||||
|
||||
/* Get each the value of the integer */
|
||||
/* We have an integer */
|
||||
default:
|
||||
if ((c >= '0') && (c <= '9'))
|
||||
{
|
||||
/* More than one normal difference specified, use the last one */
|
||||
if (next == 1)
|
||||
{
|
||||
count = 0;
|
||||
next = 0;
|
||||
}
|
||||
buffer[count++] = ATOI(c);
|
||||
}
|
||||
/* At the decimal point */
|
||||
else if (c == '.')
|
||||
{
|
||||
/* More than one normal difference specified, use the last one */
|
||||
if (next == 1)
|
||||
{
|
||||
count = 0;
|
||||
next = 0;
|
||||
}
|
||||
buffer[count++] = -1;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Convert the buffer of characters to a floating pt integer */
|
||||
if (count != 0)
|
||||
norm_difference = convert_array(buffer,count);
|
||||
*f = file_type;
|
||||
*t = tie;
|
||||
*tr = triangulate;
|
||||
return norm_difference;
|
||||
}
|
17
Tools/Stripe_u/options.h
Normal file
17
Tools/Stripe_u/options.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
/********************************************************************/
|
||||
/* STRIPE: converting a polygonal model to triangle strips
|
||||
Francine Evans, 1996.
|
||||
SUNY @ Stony Brook
|
||||
Advisors: Steven Skiena and Amitabh Varshney
|
||||
*/
|
||||
/********************************************************************/
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
/* STRIPE: options.h
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
float get_options();
|
||||
enum file_options {ASCII,BINARY};
|
||||
enum tie_options {FIRST, RANDOM, ALTERNATE, LOOK, SEQUENTIAL};
|
||||
enum triangulation_options {PARTIAL,WHOLE};
|
||||
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue