2000-02-09 19:51:45 +00:00
|
|
|
// 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$
|
|
|
|
|
|
|
|
|
Contributed by Bruce Finney:
The following files have been changed to enable the latest Terragear CVS
to compile with MSVC++ 5.0
.\construct\clipper\clipper.cxx
for( int i - lots of places
.\construct\genoutput\genobj.cxx
fix directory logic for windows, line 320 and following
.\construct\main\main.cxx
windows does not have an opendir function
added code for windows directory functions
disabled the mem allocation limit code - windows does not
have similar functions
for ( int i - several places
.\construct\match\match.cxx
moved the definition of file and command outside of the ifdef line 420
.\lib\e00\e00.cxx
for( int i - several places
.\lib\e00\e00.cxx
use simgear/compiler.h constructs
.\lib\geometry\contour_tree.hxx
removed a cout statement
.\lib\geometry\poly_support.cxx
added float.h changed 1.0e+999 to DBL_MAX, windows doesn't go that big
lots of for ( int i changes
lines 193 and 208 no != operator defined - changed logic
line 801 flag should be int, not bool, get_hole_flag returns int
.\lib\landcover\landcover.cxx
.\lib\landcover\landcover.hxx
add include simgear/compiler.h
see comments
.\lib\optimize\genfans.cxx
function canonify added return at end, windows complains
added using std for cout and endl
.\lib\optimize\genstrips.cxx
function tgGenStrips no return value, moved by_node into outer scope
fix for ( int i ...
.\lib\poly2tri\construct.c
added include <memory.h> for windows
remove unused variables lines 435 & 437
.\lib\poly2tri\misc.c
added HAVE_SYS_TIME_H logic for sys/time.h include file
added logic to uses windows functions for time and rand
.\lib\poly2tri\monotone.c
added include <memory.h> for windows
lines 286-288 remove unused variables
.\lib\poly2tri\tri.c
remove sys/time.h - no time functions called
added include <memory.h> for windows
.\lib\polygon\polygon.cxx
function polygon_to_tristrip will not compile I don't think the
logic is complete, no returned data added if else endif around
function and polygon_to_tristrip_old, renamed _old function.
Search of code reveals that function is not called by anyone.
.\lib\polygon\superpoly.cxx
changed include <superpoly.hxx> to "superpoly.hxx"
.\lib\polygon\superpoly.hxx
add include <windows.h> for windows before include <gl.h>
needed for definitions used in Microsoft version of opengl
.\lib\shapelib\dbfopen.c
added include files for windows
lines 195-197 271-272 515-517 removed unused variables
.\lib\shapelib\shpopen.c
added #include <stdlib.h> for malloc() and friends
added include files for windows
line 279 527 813 1127 removed unused variables
line 827 cast result to int
.\lib\win32\mkdir.cpp
documented function, remove debug lines
.\prep\demraw2ascii\main.c
lines 46-50 remove unused variables
.\prep\demraw2ascii\rawdem.c
line 47 changed logic to compile with MSVC
line 244-256 set real constants to float, windows complains with
double constants
.\prep\genairports\build.cxx
lots of for ( int i changes
.\prep\genairports\main.cxx
fix mkdir logic for windows
.\prep\genairports\output.cxx
added using std cout endl
lots of for ( int i changes
fix mkdir logic for windows
.\prep\genairports\runway.cxx
for ( int i changes
lines 117-118 161-162 remove default values for function parameters
.\prep\gshhs\main.cxx
added using std cout
.\prep\shapefile\noaa_decode.cxx
.\prep\shapefile\shape_decode.cxx
added using std for cout
lines 45-49 moved unused variables inside #if 0 block
2000-11-25 19:39:46 +00:00
|
|
|
#include <simgear/compiler.h>
|
|
|
|
|
|
|
|
#include STL_IOSTREAM
|
|
|
|
|
2000-02-09 19:51:45 +00:00
|
|
|
#include "genfans.hxx"
|
|
|
|
|
2001-03-23 21:59:33 +00:00
|
|
|
SG_USING_STD( cout );
|
|
|
|
SG_USING_STD( endl );
|
Contributed by Bruce Finney:
The following files have been changed to enable the latest Terragear CVS
to compile with MSVC++ 5.0
.\construct\clipper\clipper.cxx
for( int i - lots of places
.\construct\genoutput\genobj.cxx
fix directory logic for windows, line 320 and following
.\construct\main\main.cxx
windows does not have an opendir function
added code for windows directory functions
disabled the mem allocation limit code - windows does not
have similar functions
for ( int i - several places
.\construct\match\match.cxx
moved the definition of file and command outside of the ifdef line 420
.\lib\e00\e00.cxx
for( int i - several places
.\lib\e00\e00.cxx
use simgear/compiler.h constructs
.\lib\geometry\contour_tree.hxx
removed a cout statement
.\lib\geometry\poly_support.cxx
added float.h changed 1.0e+999 to DBL_MAX, windows doesn't go that big
lots of for ( int i changes
lines 193 and 208 no != operator defined - changed logic
line 801 flag should be int, not bool, get_hole_flag returns int
.\lib\landcover\landcover.cxx
.\lib\landcover\landcover.hxx
add include simgear/compiler.h
see comments
.\lib\optimize\genfans.cxx
function canonify added return at end, windows complains
added using std for cout and endl
.\lib\optimize\genstrips.cxx
function tgGenStrips no return value, moved by_node into outer scope
fix for ( int i ...
.\lib\poly2tri\construct.c
added include <memory.h> for windows
remove unused variables lines 435 & 437
.\lib\poly2tri\misc.c
added HAVE_SYS_TIME_H logic for sys/time.h include file
added logic to uses windows functions for time and rand
.\lib\poly2tri\monotone.c
added include <memory.h> for windows
lines 286-288 remove unused variables
.\lib\poly2tri\tri.c
remove sys/time.h - no time functions called
added include <memory.h> for windows
.\lib\polygon\polygon.cxx
function polygon_to_tristrip will not compile I don't think the
logic is complete, no returned data added if else endif around
function and polygon_to_tristrip_old, renamed _old function.
Search of code reveals that function is not called by anyone.
.\lib\polygon\superpoly.cxx
changed include <superpoly.hxx> to "superpoly.hxx"
.\lib\polygon\superpoly.hxx
add include <windows.h> for windows before include <gl.h>
needed for definitions used in Microsoft version of opengl
.\lib\shapelib\dbfopen.c
added include files for windows
lines 195-197 271-272 515-517 removed unused variables
.\lib\shapelib\shpopen.c
added #include <stdlib.h> for malloc() and friends
added include files for windows
line 279 527 813 1127 removed unused variables
line 827 cast result to int
.\lib\win32\mkdir.cpp
documented function, remove debug lines
.\prep\demraw2ascii\main.c
lines 46-50 remove unused variables
.\prep\demraw2ascii\rawdem.c
line 47 changed logic to compile with MSVC
line 244-256 set real constants to float, windows complains with
double constants
.\prep\genairports\build.cxx
lots of for ( int i changes
.\prep\genairports\main.cxx
fix mkdir logic for windows
.\prep\genairports\output.cxx
added using std cout endl
lots of for ( int i changes
fix mkdir logic for windows
.\prep\genairports\runway.cxx
for ( int i changes
lines 117-118 161-162 remove default values for function parameters
.\prep\gshhs\main.cxx
added using std cout
.\prep\shapefile\noaa_decode.cxx
.\prep\shapefile\shape_decode.cxx
added using std for cout
lines 45-49 moved unused variables inside #if 0 block
2000-11-25 19:39:46 +00:00
|
|
|
|
2000-02-09 19:51:45 +00:00
|
|
|
|
|
|
|
// make sure the list is expanded at least to hold "n" and then push
|
|
|
|
// "i" onto the back of the "n" list.
|
2000-05-08 17:17:21 +00:00
|
|
|
static void add_and_expand( opt_list& by_node, int n, int i ) {
|
2000-02-09 19:51:45 +00:00
|
|
|
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);
|
|
|
|
}
|
Contributed by Bruce Finney:
The following files have been changed to enable the latest Terragear CVS
to compile with MSVC++ 5.0
.\construct\clipper\clipper.cxx
for( int i - lots of places
.\construct\genoutput\genobj.cxx
fix directory logic for windows, line 320 and following
.\construct\main\main.cxx
windows does not have an opendir function
added code for windows directory functions
disabled the mem allocation limit code - windows does not
have similar functions
for ( int i - several places
.\construct\match\match.cxx
moved the definition of file and command outside of the ifdef line 420
.\lib\e00\e00.cxx
for( int i - several places
.\lib\e00\e00.cxx
use simgear/compiler.h constructs
.\lib\geometry\contour_tree.hxx
removed a cout statement
.\lib\geometry\poly_support.cxx
added float.h changed 1.0e+999 to DBL_MAX, windows doesn't go that big
lots of for ( int i changes
lines 193 and 208 no != operator defined - changed logic
line 801 flag should be int, not bool, get_hole_flag returns int
.\lib\landcover\landcover.cxx
.\lib\landcover\landcover.hxx
add include simgear/compiler.h
see comments
.\lib\optimize\genfans.cxx
function canonify added return at end, windows complains
added using std for cout and endl
.\lib\optimize\genstrips.cxx
function tgGenStrips no return value, moved by_node into outer scope
fix for ( int i ...
.\lib\poly2tri\construct.c
added include <memory.h> for windows
remove unused variables lines 435 & 437
.\lib\poly2tri\misc.c
added HAVE_SYS_TIME_H logic for sys/time.h include file
added logic to uses windows functions for time and rand
.\lib\poly2tri\monotone.c
added include <memory.h> for windows
lines 286-288 remove unused variables
.\lib\poly2tri\tri.c
remove sys/time.h - no time functions called
added include <memory.h> for windows
.\lib\polygon\polygon.cxx
function polygon_to_tristrip will not compile I don't think the
logic is complete, no returned data added if else endif around
function and polygon_to_tristrip_old, renamed _old function.
Search of code reveals that function is not called by anyone.
.\lib\polygon\superpoly.cxx
changed include <superpoly.hxx> to "superpoly.hxx"
.\lib\polygon\superpoly.hxx
add include <windows.h> for windows before include <gl.h>
needed for definitions used in Microsoft version of opengl
.\lib\shapelib\dbfopen.c
added include files for windows
lines 195-197 271-272 515-517 removed unused variables
.\lib\shapelib\shpopen.c
added #include <stdlib.h> for malloc() and friends
added include files for windows
line 279 527 813 1127 removed unused variables
line 827 cast result to int
.\lib\win32\mkdir.cpp
documented function, remove debug lines
.\prep\demraw2ascii\main.c
lines 46-50 remove unused variables
.\prep\demraw2ascii\rawdem.c
line 47 changed logic to compile with MSVC
line 244-256 set real constants to float, windows complains with
double constants
.\prep\genairports\build.cxx
lots of for ( int i changes
.\prep\genairports\main.cxx
fix mkdir logic for windows
.\prep\genairports\output.cxx
added using std cout endl
lots of for ( int i changes
fix mkdir logic for windows
.\prep\genairports\runway.cxx
for ( int i changes
lines 117-118 161-162 remove default values for function parameters
.\prep\gshhs\main.cxx
added using std cout
.\prep\shapefile\noaa_decode.cxx
.\prep\shapefile\shape_decode.cxx
added using std for cout
lines 45-49 moved unused variables inside #if 0 block
2000-11-25 19:39:46 +00:00
|
|
|
|
|
|
|
// MSVC kludge (code should never reach this point, but it makes
|
|
|
|
// the MSVC compiler happy)
|
|
|
|
return t;
|
2000-02-09 19:51:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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
|
2000-05-08 17:17:21 +00:00
|
|
|
opt_list FGGenFans::greedy_build( triele_list tris ) {
|
2000-02-09 19:51:45 +00:00
|
|
|
cout << "starting greedy build of fans" << endl;
|
|
|
|
|
|
|
|
fans.clear();
|
|
|
|
|
|
|
|
while ( ! tris.empty() ) {
|
|
|
|
// traverse the triangle list and for each node, build a list of
|
|
|
|
// triangles that attach to it.
|
|
|
|
|
2000-05-08 17:17:21 +00:00
|
|
|
// cout << "building by_node list" << endl;
|
|
|
|
opt_list by_node;
|
|
|
|
by_node.clear();
|
|
|
|
|
2000-02-09 19:51:45 +00:00
|
|
|
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;
|
2000-05-08 17:17:21 +00:00
|
|
|
opt_list_iterator r_current = by_node.begin();
|
|
|
|
opt_list_iterator r_last = by_node.end();
|
2000-02-09 19:51:45 +00:00
|
|
|
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;
|
|
|
|
|
2000-05-08 17:17:21 +00:00
|
|
|
opt_list_iterator current = fans.begin();
|
|
|
|
opt_list_iterator last = fans.end();
|
2000-02-09 19:51:45 +00:00
|
|
|
for ( ; current != last; ++current ) {
|
|
|
|
sum += current->size();
|
|
|
|
}
|
|
|
|
|
|
|
|
return sum / (double)fans.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
|