430c32be19
- aggiornamento versione.
1220 lines
38 KiB
C++
1220 lines
38 KiB
C++
/*****************************************************************************/
|
|
/* */
|
|
/* Copyright (C) Martin Held 1999-2023 */
|
|
/* */
|
|
/* */
|
|
/* C O P Y R I G H T */
|
|
/* */
|
|
/* This code is provided at no charge to you for purely non-profit purposes */
|
|
/* and only for use internal to your institution. You may use this code for */
|
|
/* academic applications, following standard rules of academic conduct */
|
|
/* including crediting the author(s) and the copyright holder in any */
|
|
/* publication. This code is not in the public domain, and no parts of it */
|
|
/* may be duplicated, altered, sold, re-distributed (in either source-code */
|
|
/* or binary format), or used as a blueprint for somebody else's own */
|
|
/* implementation without obtaining the prior written consent of the */
|
|
/* copyright holder. All rights reserved! */
|
|
/* */
|
|
/* Free use of this code is restricted to purely non-profit purposes within */
|
|
/* academic research institutions. Absolutely all other forms of use require */
|
|
/* the signing of a non-disclosure agreement or of a commercial license. */
|
|
/* Please read the file STANDARD_REPLY.txt for a detailed explanation, and */
|
|
/* contact me, Martin Held (held@cs.sbg.ac.at), for commercial evaluation */
|
|
/* and licensing terms. */
|
|
/* */
|
|
/* D I S C L A I M E R */
|
|
/* */
|
|
/* In any case, this code is provided `as is', and you use it at your own */
|
|
/* risk. The author does not accept any responsibility, to the extent */
|
|
/* permitted by applicable law, for the consequences of using it or for its */
|
|
/* usefulness for any particular application. */
|
|
/* */
|
|
/* Please report any bugs to held@cs.sbg.ac.at. */
|
|
/* */
|
|
/*****************************************************************************/
|
|
/* */
|
|
/* Written by: Martin Held */
|
|
/* */
|
|
/* E-Mail: held@cs.sbg.ac.at */
|
|
/* Fax Mail: (+43 662) 8044-172 */
|
|
/* Voice Mail: (+43 662) 8044-6304 */
|
|
/* Snail Mail: Martin Held */
|
|
/* FB Informatik */
|
|
/* Universitaet Salzburg */
|
|
/* A-5020 Salzburg, Austria */
|
|
/* */
|
|
/*****************************************************************************/
|
|
/* */
|
|
/* Please read the README and README_data files before compiling or using */
|
|
/* this code! */
|
|
/* */
|
|
/*****************************************************************************/
|
|
|
|
/* */
|
|
/* get standard libraries */
|
|
/* */
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
#include <limits.h>
|
|
#include <float.h>
|
|
#include <assert.h>
|
|
#include <string.h>
|
|
|
|
|
|
/* */
|
|
/* get my header files */
|
|
/* */
|
|
#include "fpkernel.h"
|
|
#include "vroni_object.h"
|
|
|
|
|
|
/* */
|
|
/* global constants */
|
|
/* */
|
|
|
|
|
|
/* */
|
|
/* VRONI object base class implementation */
|
|
/* */
|
|
|
|
vroniObject::vroniObject()
|
|
{
|
|
/* from driver.cc */
|
|
save_data = false;
|
|
read_poly = false;
|
|
read_polygon = false;
|
|
read_sites = false;
|
|
read_xdr = false;
|
|
read_graphml = false;
|
|
read_polylines = false;
|
|
read_e00 = false;
|
|
read_usgs = false;
|
|
read_dxf = false;
|
|
read_pnts = false;
|
|
read_file = false;
|
|
write_ipe = false;
|
|
write_vd_dt = false;
|
|
help = false;
|
|
time_it = false;
|
|
print_copy = true;
|
|
discard_dupl_s = false;
|
|
write_off = false;
|
|
auto_offset = false;
|
|
left_offset = false;
|
|
right_offset = false;
|
|
compute_wmat = false;
|
|
auto_wmat = false;
|
|
pnts_only = false;
|
|
compute_mic = false;
|
|
dxf_format = false;
|
|
write_ma = false;
|
|
clean_up = false;
|
|
new_input = false;
|
|
write_vd = false;
|
|
left_vd = false;
|
|
right_vd = false;
|
|
vr_incr = false;
|
|
|
|
driver_step_size = INT_MAX;
|
|
p_step_size = INT_MAX;
|
|
o_step_size = INT_MAX;
|
|
a_step_size = INT_MAX;
|
|
sample = 0;
|
|
bound = 3;
|
|
approx = 0;
|
|
io_flag = 0;
|
|
inputprec = -1;
|
|
mpfr_prec = 53;
|
|
vr_seed = 12345 ;
|
|
|
|
t_offset = 0.0;
|
|
d_offset = 0.0;
|
|
wmat_angle = 0.0;
|
|
wmat_dist = 0.0;
|
|
vd_apx_dist = 0.0;
|
|
|
|
#if defined (OGL_GRAPHICS)
|
|
off_init = false;
|
|
data_read = false;
|
|
finished = false;
|
|
off_finished = false;
|
|
computed = false;
|
|
wmat_computed = false;
|
|
mic_computed = false;
|
|
vd_output = false;
|
|
first_input = true;
|
|
first_pnt = NIL;
|
|
last_pnt = NIL;
|
|
new_pnts = 0;
|
|
#endif
|
|
|
|
/* from redraw.cc */
|
|
#ifdef GRAPHICS
|
|
pnt_buf = (buffer*)NULL;
|
|
seg_buf = (buffer*)NULL;
|
|
arc_buf = (buffer*)NULL;
|
|
vdn_buf = (buffer*)NULL;
|
|
|
|
num_pnt_buf = 0;
|
|
max_num_pnt_buf = 0;
|
|
num_seg_buf = 0;
|
|
max_num_seg_buf = 0;
|
|
num_arc_buf = 0;
|
|
max_num_arc_buf = 0;
|
|
num_vdn_buf = 0;
|
|
max_num_vdn_buf = 0;
|
|
|
|
num_vde_buf = 0;
|
|
max_num_vde_buf = 0;
|
|
|
|
num_off_buf = 0;
|
|
max_num_off_buf = 0;
|
|
|
|
cur_buf = (cur_buffer*)NULL;
|
|
num_cur_buf = 0;
|
|
max_num_cur_buf = 0;
|
|
|
|
num_cir_buf = 0;
|
|
max_num_cir_buf = 0;
|
|
#endif
|
|
|
|
/* from api_functions.cc */
|
|
verbose = true;
|
|
quiet = false;
|
|
statistics = false;
|
|
numerical = false;
|
|
scale_data = true;
|
|
check_data = true;
|
|
|
|
#ifdef GRAPHICS
|
|
graphics = false;
|
|
draw_pnts = false;
|
|
draw_segs = true;
|
|
draw_off = true;
|
|
draw_arcs = true;
|
|
draw_vde = true;
|
|
draw_vdn = false;
|
|
draw_dte = false;
|
|
draw_mat = false;
|
|
draw_mic = false;
|
|
draw_tool = true;
|
|
#endif
|
|
|
|
pntd = (in_pnts*)NULL;
|
|
segd = (in_segs*)NULL;
|
|
arcd = (in_arcs*)NULL;
|
|
|
|
|
|
/* from data.cc */
|
|
data_scaled = false;
|
|
scale_factor = 1.0;
|
|
shift = coord(0.0, 0.0);
|
|
|
|
max_num_pnts = 0;
|
|
max_num_segs = 0;
|
|
max_num_arcs = 0;
|
|
|
|
bbox_initialized = false;
|
|
bbox_added = false;
|
|
|
|
support_vtx_added = false;
|
|
|
|
num_pnts_added = 0;
|
|
num_pnts_deleted = 0;
|
|
num_segs_deleted = 0;
|
|
num_arcs_deleted = 0;
|
|
|
|
#ifdef RANDOM
|
|
m_num_rnd_sites = 0;
|
|
m_max_num_rnd_sites = 0;
|
|
m_cur_rnd_sites = 0;
|
|
#endif
|
|
|
|
#ifdef FORCED
|
|
num_fcd_sites = 0;
|
|
max_num_fcd_sites = 0;
|
|
cur_fcd_sites = 0;
|
|
#endif
|
|
|
|
#ifdef SORTED
|
|
num_srt_sites = 0;
|
|
max_num_srt_sites = 0;
|
|
#endif
|
|
|
|
dxf_poly_started = false;
|
|
dxf_vertex_added = false;
|
|
dxf_vertex_index = NIL;
|
|
dxf_vertex_first = NIL;
|
|
|
|
#ifdef ORDERED
|
|
site_counter = 0;
|
|
num_ord_sites = 0;
|
|
max_num_ord_sites = 0;
|
|
#endif
|
|
|
|
#ifndef ORDERED
|
|
#ifndef SORTED
|
|
#ifndef RANDOM
|
|
#ifndef FORCED
|
|
nosr = 0;
|
|
#endif
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
/* from data_off.cc */
|
|
stack = (STACK_TYPE*)NULL;
|
|
num_stack = 0;
|
|
max_num_stack = 0;
|
|
|
|
num_edge_data = 0;
|
|
max_num_edge_data = 0;
|
|
|
|
edge_flags = (e_flag*)NULL;
|
|
num_edge_flags = 0;
|
|
max_num_edge_flags = 0;
|
|
|
|
active_edges = (int*)NULL;
|
|
num_active_edges = 0;
|
|
max_num_active_edges = 0;
|
|
|
|
min_pnt_ind = -1;
|
|
max_pnt_ind = INT_MAX;
|
|
|
|
e_data_init = true;
|
|
|
|
data_off_VD_ID = 0;
|
|
|
|
/* from mic.cc */
|
|
MIC_computed = false;
|
|
|
|
/* from io_basic.cc */
|
|
isolated_pnts = false;
|
|
|
|
/* from offset.cc */
|
|
num_offset_list = 0;
|
|
max_num_offset_list = 0;
|
|
|
|
num_offset_data = 0;
|
|
max_num_offset_data = 0;
|
|
|
|
max_t_offset = DBL_MAX;
|
|
|
|
#ifdef VISUAL_TEST_OFFSETS
|
|
small_increment = true;
|
|
#endif
|
|
|
|
unscaleXYZ = true;
|
|
|
|
offset_VD_ID = 0;
|
|
|
|
/* from io_dxf.cc */
|
|
dxf_handle = 43;
|
|
|
|
/* from vd_basic.cc */
|
|
#ifdef VRONI_INFO
|
|
max_relaxation = TINY;
|
|
curr_relaxation = TINY;
|
|
#endif
|
|
|
|
too_large = LARGE;
|
|
|
|
num_nodes = 0;
|
|
max_num_nodes = 0;
|
|
|
|
num_edges = 0;
|
|
max_num_edges = 0;
|
|
|
|
num_free_nodes = 0;
|
|
max_num_free_nodes = 0;
|
|
num_free_edges = 0;
|
|
max_num_free_edges = 0;
|
|
|
|
dummies = (dummy_node*)NULL;
|
|
num_dummies = 0;
|
|
max_num_dummies = 0;
|
|
|
|
VD_computed = false;
|
|
deg2_nodes_inserted = false;
|
|
VD_nodes_squared = true;
|
|
|
|
VD_identifier = 0;
|
|
|
|
/* wmat.cc */
|
|
WMAT_computed = false;
|
|
|
|
/* prepro.cc */
|
|
preProZero = ZERO;
|
|
|
|
/* vd_data.cc */
|
|
debug_flag_VD = true;
|
|
|
|
sites_visited = (s_visited*)NULL;
|
|
num_visited = 0;
|
|
max_num_visited = 0;
|
|
|
|
pnt_visited = (int*)NULL;
|
|
num_pnt_visited = 0;
|
|
max_num_pnt_visited = 0;
|
|
|
|
nodes_checked = (int*)NULL;
|
|
num_checked = 0;
|
|
max_num_checked = 0;
|
|
|
|
preserve = (preserve_buffer*)NULL;
|
|
num_preserve = 0;
|
|
max_num_preserve = 0;
|
|
|
|
loop_stack = (int*)NULL;
|
|
num_loop_stack = 0;
|
|
min_loop_stack = 0;
|
|
max_num_loop_stack = 0;
|
|
|
|
#ifdef TRACE
|
|
threshold_counter = 0;
|
|
dbg_center = false;
|
|
#endif
|
|
|
|
/* from misc.cc */
|
|
#ifdef GENUINE_ARCS
|
|
misc_step_size = 0.000001;
|
|
#else
|
|
misc_step_size = 0.0005;
|
|
#endif
|
|
invalid_i1 = NIL;
|
|
invalid_i2 = NIL;
|
|
invalid_t1 = UNKNOWN;
|
|
invalid_t2 = UNKNOWN;
|
|
invalid_eps = ZERO;
|
|
|
|
/* intersections.cc */
|
|
check_completed = true;
|
|
eps_int = ZERO;
|
|
|
|
/* clean_data.cc */
|
|
max_num_reverse_ind = 0;
|
|
num_reverse_ind = 0;
|
|
reverse_index_exists = false;
|
|
data_sorted = false;
|
|
clean_initialized = false;
|
|
|
|
/* arg_eval.cc */
|
|
#ifdef TRACE
|
|
center = false;
|
|
write_debug = false;
|
|
proto = false;
|
|
max_cntr = 1;
|
|
#endif
|
|
|
|
#ifdef OTHER
|
|
cgal = false;
|
|
#endif
|
|
|
|
/* voronoi.cc */
|
|
#ifdef TRACE
|
|
stack_size = 0;
|
|
max_stack_size = 0;
|
|
#endif
|
|
|
|
/* moved from vddata.h */
|
|
num_pnts = 0;
|
|
num_segs = 0;
|
|
num_arcs = 0;
|
|
|
|
/* grid.cc */
|
|
N_Initial = 0;
|
|
|
|
the_grid = (int*)NULL;
|
|
max_num_grid = 0;
|
|
|
|
max_num_raster_x = 0;
|
|
max_num_raster_y = 0;
|
|
|
|
pnt_list = (pnt_node*)NULL;
|
|
num_pnt_list = 0;
|
|
max_num_pnt_list = 0;
|
|
|
|
first_N_pnts = (int*)NULL;
|
|
first_counter = 0;
|
|
|
|
/* from heap.cc */
|
|
num_heap = 0;
|
|
max_num_heap = 0;
|
|
|
|
deleted = false;
|
|
not_updated = false;
|
|
|
|
/* from tree.cc */
|
|
tree = (tree_node*)NULL;
|
|
num_tree = 0;
|
|
max_num_tree = 0;
|
|
|
|
/* from hsm/path.cc */
|
|
path_VD_ID = 0;
|
|
num_path_data = 0;
|
|
max_num_path_data = 0;
|
|
|
|
/* from memory.cc */
|
|
#ifdef DEBUG_MEMORY
|
|
curr_memory = 0;
|
|
max_memory = 0;
|
|
memory_dbg_cursor = 0;
|
|
#endif
|
|
|
|
/* from elapsed.cc */
|
|
#ifndef NO_CPUTIME
|
|
#ifdef CPUTIME_BY_CHRONO
|
|
elapsed_initialized = false;
|
|
#else
|
|
#ifdef CPUTIME_IN_MILLISECONDS
|
|
total_secs = 0;
|
|
total_usecs = 0;
|
|
#else /* ifndef CPUTIME_IN_MILLISECONDS */
|
|
#ifdef CPUTIME_VIA_CLOCK
|
|
elapsed_initialized = false;
|
|
#else /* ifndef CPUTIME_IN_MILLISECONDS || CPUTIME_VIA_CLOCK */
|
|
total = 0;
|
|
HZ = 0;
|
|
#endif
|
|
#endif
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
|
|
vroniObject::~vroniObject()
|
|
{
|
|
apiTerminateProgram();
|
|
}
|
|
|
|
|
|
void vroniObject::apiHandleError(void)
|
|
{
|
|
ExtApplFuncVRONI_HandleError;
|
|
|
|
try {
|
|
throw;
|
|
}
|
|
catch (const std::runtime_error& VRONIerror) {
|
|
std::cout << "\n" << VRONIerror.what() << "\n";
|
|
}
|
|
catch (const std::exception& VRONIerror) {
|
|
std::cout << "\n" << VRONIerror.what() << "\n";
|
|
}
|
|
catch ( ... ) {
|
|
std::cout << "VRONI error: unknown type of error.\n";
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
void vroniObject::apiInitializeProgram(void)
|
|
{
|
|
double precision;
|
|
#ifndef DBL_EPSILON
|
|
double dummy;
|
|
#endif
|
|
|
|
/* */
|
|
/* Please make sure that the "epsilons" are set to useful values. You are */
|
|
/* urged not to change the predefined settings unless you are sure to */
|
|
/* know what you are doing. (And if you don't blame me afterwards in case */
|
|
/* that the code should misbehave.) While the "relaxation of epsilons" */
|
|
/* makes this code much less dependent on the actual settings of these */
|
|
/* thresholds, and although the code is supposed not to crash even if */
|
|
/* obviously "stupid" thresholds were to be used, you should be aware of */
|
|
/* the fact that the best performance of the code is likely achieved with */
|
|
/* the pre-defined settings. In particular, the code's ability to */
|
|
/* determine whether a numerical data that does not meet its consistency */
|
|
/* checks is due to numerical problems or due to bogus input data relies */
|
|
/* heavily on the carefully designed interplay of the epsilons used. */
|
|
/* */
|
|
/* SMALL is used to filter out those numerical values for which some */
|
|
/* computation might become numerically instable. In such a case, an */
|
|
/* alternate method of computation is used. */
|
|
/* */
|
|
/* Any number whose absolute value is less than ZERO may be treated as 0. */
|
|
/* In particular, two points whose distance is less than ZERO may be */
|
|
/* regarded as one point. This constant must not be set to 0 in order to */
|
|
/* avoid fp-overflows. ZERO2 should be set to ZERO * ZERO. */
|
|
/* */
|
|
/* ZERO_MAX is the largest value which, if required by the computation in */
|
|
/* order to succeed without a restart, can still be regarded as 0. It is */
|
|
/* also used for deciding whether a computation that is numerically */
|
|
/* sensitive might be unstable. */
|
|
/* */
|
|
/* TINY is a constant that is about the size of the machine precision. */
|
|
/* It is used for avoiding divisions by zero in calculations that should */
|
|
/* be carried out at the precision of the machine arithmetic, irrelevant */
|
|
/* of the actual values of the other thresholds. Don't redefine it! */
|
|
/* */
|
|
#ifndef DOUBLE_OVERRIDE
|
|
if (SMALL != 0.0078125) {
|
|
throw std::runtime_error("VRONI error: apiInitializeProgram() - constant SMALL modified by user!");
|
|
}
|
|
#ifdef DBL_EPSILON
|
|
precision = 10.0 * DBL_EPSILON;
|
|
#else
|
|
precision = 1.0;
|
|
dummy = 1.0 + precision;
|
|
while (dummy > 1.0) {
|
|
/* printf("precision- %10.6e: %40.36f\n", precision, dummy); */
|
|
precision /= 2.0;
|
|
dummy = precision + 1.0;
|
|
}
|
|
precision *= 20.0;
|
|
#endif
|
|
if ((TINY < precision * 4.0) || (TINY > precision * 100.0)) {
|
|
#ifdef VRONI_INFO
|
|
FP_fprintf(stderr, "Please set the constant TINY (in defs.h) to %3.1e!\n",
|
|
FP_PRNTARG(precision * 10.0));
|
|
#endif
|
|
throw std::runtime_error("VRONI error: apiInitializeProgram() - constant TINY modified by user!");
|
|
}
|
|
precision *= 10.0;
|
|
if ((ZERO > ZERO_MAX) || (ZERO < precision) || (ZERO < TINY)) {
|
|
throw std::runtime_error("VRONI error: apiInitializeProgram() - constant ZERO modified by user!");
|
|
}
|
|
if ((ZERO2 > (ZERO * ZERO * 10.0)) || (ZERO2 < (precision * precision / 10.0))) {
|
|
throw std::runtime_error("VRONI error: apiInitializeProgram() - constant ZERO2 modified by user!");
|
|
}
|
|
if ((THRESHOLD > (ZERO_MAX / 5.0)) ||
|
|
(THRESHOLD < (ZERO_MAX / 20.0))) {
|
|
throw std::runtime_error("VRONI error: apiInitializeProgram() - constant THRESHOLD modified by user!");
|
|
}
|
|
#endif
|
|
|
|
LARGE = sqrt(DBL_MAX) / 100.0;
|
|
|
|
/* */
|
|
/* let the user modify the default initializations. */
|
|
/* */
|
|
ExtApplInitializeProgram;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
void vroniObject::apiHandleInput(char input_file[], vr_bool *new_input,
|
|
vr_bool read_polygon, vr_bool read_poly,
|
|
vr_bool read_sites, vr_bool read_xdr,
|
|
vr_bool read_e00, vr_bool read_polylines,
|
|
vr_bool read_usgs, vr_bool read_dxf,
|
|
vr_bool read_pnts, vr_bool read_graphml)
|
|
{
|
|
#ifdef VRONI_INFO
|
|
if (!quiet) printf("\n...processing file: `%s'\n", input_file);
|
|
#endif
|
|
|
|
/* */
|
|
/* read data from input file */
|
|
/* */
|
|
VD_Info("...reading the input data -- ");
|
|
|
|
if (read_polygon) ReadPolygon(input_file, new_input);
|
|
else if (read_pnts) ReadPoints(input_file, new_input);
|
|
else if (read_poly) ReadPoly(input_file, new_input);
|
|
else if (read_sites) ReadSites(input_file, new_input);
|
|
else if (read_xdr) ReadXDRFile(input_file, new_input);
|
|
else if (read_e00) ReadE00File(input_file, new_input);
|
|
else if (read_polylines) ReadPolylines(input_file, new_input);
|
|
else if (read_usgs) ReadUSGS(input_file, new_input);
|
|
else if (read_dxf) ReadDXFFile(input_file, new_input);
|
|
else if (read_graphml) ReadGraphML(input_file, new_input);
|
|
else {
|
|
throw std::runtime_error("VRONI error: apiHandleInput() - no correct input file type specified!");
|
|
}
|
|
|
|
#ifdef VRONI_INFO
|
|
if (!quiet) VD_Info("done!\n");
|
|
#endif
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
void vroniObject::apiFileInput(char input_file[], vr_bool *new_input)
|
|
{
|
|
char *ext;
|
|
|
|
#ifdef VRONI_INFO
|
|
if (!quiet) printf("\n...processing file: `%s'\n", input_file);
|
|
#endif
|
|
|
|
/* */
|
|
/* read data from input file */
|
|
/* */
|
|
VD_Info("...reading the input data -- ");
|
|
|
|
/* find last dot in input_file name*/
|
|
ext = strrchr(input_file, '.');
|
|
if (ext == NULL) {
|
|
throw std::runtime_error("VRONI error: apiFileInput() - file extension missing!");
|
|
}
|
|
else {
|
|
if (!strcmp(ext, ".pnt")) ReadPoints(input_file, new_input);
|
|
else if (!strcmp(ext, ".poly")) ReadPoly(input_file, new_input);
|
|
else if (!strcmp(ext, ".site")) ReadSites(input_file, new_input);
|
|
else if (!strcmp(ext, ".xdr")) ReadXDRFile(input_file, new_input);
|
|
else if (!strcmp(ext, ".e00")) ReadE00File(input_file, new_input);
|
|
else if (!strcmp(ext, ".line")) ReadPolylines(input_file, new_input);
|
|
else if (!strcmp(ext, ".usgs")) ReadUSGS(input_file, new_input);
|
|
else if (!strcmp(ext, ".dxf")) ReadDXFFile(input_file, new_input);
|
|
else if (!strcmp(ext, ".dat")) ReadPolygon(input_file, new_input);
|
|
else if (!strcmp(ext, ".xml")) ReadXML(input_file, new_input);
|
|
else if (!strcmp(ext, ".ipe")) ReadXML(input_file, new_input);
|
|
else if (!strcmp(ext, ".bdm")) ReadBDM(input_file, new_input);
|
|
else if (!strcmp(ext, ".graphml")) ReadGraphML(input_file, new_input);
|
|
else {
|
|
throw std::runtime_error("VRONI error: apiFileInput() - unkown file extension!");
|
|
}
|
|
}
|
|
|
|
#ifdef VRONI_INFO
|
|
if (!quiet) VD_Info("done!\n");
|
|
#endif
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
void vroniObject::apiArrayInput(int number_of_points, in_pnts *point_data,
|
|
int number_of_segments, in_segs *segment_data,
|
|
int number_of_arcs, in_arcs *arc_data,
|
|
vr_bool *new_input)
|
|
{
|
|
int i;
|
|
|
|
/* */
|
|
/* allocate space for the new sites */
|
|
/* */
|
|
InitPnts(number_of_points);
|
|
InitSegs(number_of_segments);
|
|
InitArcs(number_of_arcs);
|
|
|
|
#ifdef VRONI_INFO
|
|
if (!quiet) printf("\n...copying input data:\n");
|
|
#endif
|
|
|
|
for (i = 0; i < number_of_points; ++i) {
|
|
#ifdef EXT_APPL_PNTS
|
|
(void) HandlePnt(point_data[i].x1, point_data[i].y1,
|
|
point_data[i].ext_appl);
|
|
#else
|
|
(void)HandlePnt(point_data[i].x1, point_data[i].y1);
|
|
#endif
|
|
}
|
|
|
|
for (i = 0; i < number_of_segments; ++i) {
|
|
#ifdef EXT_APPL_SITES
|
|
HandleSeg(segment_data[i].x1, segment_data[i].y1,
|
|
segment_data[i].x2, segment_data[i].y2,
|
|
segment_data[i].ext_appl);
|
|
#else
|
|
HandleSeg(segment_data[i].x1, segment_data[i].y1,
|
|
segment_data[i].x2, segment_data[i].y2);
|
|
#endif
|
|
}
|
|
|
|
for (i = 0; i < number_of_arcs; ++i) {
|
|
#ifdef EXT_APPL_SITES
|
|
if (arc_data[i].attr)
|
|
HandleArc(arc_data[i].x1, arc_data[i].y1,
|
|
arc_data[i].x2, arc_data[i].y2,
|
|
arc_data[i].x3, arc_data[i].y3,
|
|
ARC,
|
|
arc_data[i].ext_appl);
|
|
else
|
|
HandleArc(arc_data[i].x1, arc_data[i].y1,
|
|
arc_data[i].x2, arc_data[i].y2,
|
|
arc_data[i].x3, arc_data[i].y3,
|
|
-ARC,
|
|
arc_data[i].ext_appl);
|
|
#else
|
|
if (arc_data[i].attr)
|
|
HandleArc(arc_data[i].x1, arc_data[i].y1,
|
|
arc_data[i].x2, arc_data[i].y2,
|
|
arc_data[i].x3, arc_data[i].y3,
|
|
ARC);
|
|
else
|
|
HandleArc(arc_data[i].x1, arc_data[i].y1,
|
|
arc_data[i].x2, arc_data[i].y2,
|
|
arc_data[i].x3, arc_data[i].y3,
|
|
-ARC);
|
|
#endif
|
|
}
|
|
|
|
*new_input = ((number_of_points > 0) ||
|
|
(number_of_segments > 0) ||
|
|
(number_of_arcs > 0));
|
|
#ifdef VRONI_INFO
|
|
if (!quiet) VD_Info("done!\n");
|
|
#endif
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
void vroniObject::apiComputeVD(vr_bool save_data, vr_bool new_input, vr_bool time,
|
|
int bound, int sample, int approx,
|
|
char output_file[], vr_bool discard_dupl_s,
|
|
vr_bool pnts_only, vr_bool write_vd,
|
|
char vd_dt_file[], vr_bool clean_up)
|
|
{
|
|
vr_bool finished;
|
|
|
|
#ifdef TRACE
|
|
printf("\n\n---- parameter values at first call of apiComputeVD() ----\n");
|
|
PrintVarValue(stdout, (void*)&save_data, "save_data", vroniBOOLEAN);
|
|
PrintVarValue(stdout, (void*)&new_input, "new_input", vroniBOOLEAN);
|
|
PrintVarValue(stdout, (void*)&time, "time", vroniBOOLEAN);
|
|
PrintVarValue(stdout, (void*)&bound, "bound", vroniINTEGER);
|
|
PrintVarValue(stdout, (void*)&sample, "sample", vroniINTEGER);
|
|
PrintVarValue(stdout, (void*)&approx, "approx", vroniINTEGER);
|
|
PrintVarValue(stdout, (void*)output_file, "output_file", vroniCHARS);
|
|
PrintVarValue(stdout, (void*)&discard_dupl_s, "discard_dupl_s", vroniBOOLEAN);
|
|
PrintVarValue(stdout, (void*)&pnts_only, "pnts_only", vroniBOOLEAN);
|
|
PrintVarValue(stdout, (void*)&write_vd, "write_vd", vroniBOOLEAN);
|
|
PrintVarValue(stdout, (void*)vd_dt_file, "vd_dt_file", vroniCHARS);
|
|
PrintVarValue(stdout, (void*)clean_up, "clean_up", vroniBOOLEAN);
|
|
printf("-----------------------------------------------------------\n");
|
|
#endif
|
|
|
|
/* */
|
|
/* no interactive graphics; compute the VD */
|
|
/* */
|
|
restart = false;
|
|
restart_due_to_intersection = false;
|
|
pnts_deleted = false;
|
|
desperate = false;
|
|
|
|
cpu_time_path = 0.0;
|
|
cpu_time_pre = 0.0;
|
|
cpu_time_pnt = 0.0;
|
|
cpu_time_seg = 0.0;
|
|
cpu_time_arc = 0.0;
|
|
cpu_time_off = 0.0;
|
|
cpu_time_wmat = 0.0;
|
|
cpu_time_mic = 0.0;
|
|
cpu_time_cln = 0.0;
|
|
|
|
do {
|
|
ComputeVD(save_data, new_input, INT_MAX, time,
|
|
bound, sample, approx, output_file, discard_dupl_s,
|
|
INT_MAX, &finished, INT_MAX, pnts_only, write_vd, vd_dt_file,
|
|
false, false, clean_up);
|
|
} while (restart);
|
|
|
|
// MODIF dealloco le variabili usate per la costruzione di Voronoi
|
|
MyFreeVDConstructionData() ;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
#ifdef WRITE_VD
|
|
/* */
|
|
/* Please be warned that this function results in an approximation of all */
|
|
/* conic VD edges by straight-line segments and, thus, destroys the VD */
|
|
/* computed by VRONI. */
|
|
/* It is only to be used if an export of an (approximate) VD is sought, and */
|
|
/* if no further computations on the VD computed by VRONI are required! */
|
|
/* */
|
|
void vroniObject::apiOutput_VD(char vd_file[], double vd_apx_dist,
|
|
vr_bool left_vd, vr_bool right_vd)
|
|
{
|
|
OutputVD(vd_file, vd_apx_dist, left_vd, right_vd);
|
|
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
|
|
void vroniObject::apiTerminateProgram()
|
|
{
|
|
#ifdef VRONI_INFO
|
|
unsigned long max_num_bytes = 0;
|
|
#ifdef TRACE
|
|
unsigned long threshold_counter;
|
|
#endif
|
|
|
|
#ifdef API_PARABOLIC
|
|
vroniObject::apiParabolicStatistics();
|
|
#endif
|
|
|
|
if (!quiet && (num_pnts > 0)) {
|
|
printf("\n#(Input Points): %8d\n", num_pnts - 4);
|
|
printf("#(Input Segments): %8d\n", num_segs);
|
|
printf("#(Input Arcs): %8d\n", num_arcs);
|
|
#ifdef TRACE
|
|
threshold_counter = GetThresholdCounter();
|
|
if (threshold_counter == 0)
|
|
printf("#(Threshold Advances): %8ld\n",
|
|
threshold_counter);
|
|
else
|
|
printf("#(Threshold Advances): %8ld\n",
|
|
threshold_counter);
|
|
|
|
#endif /* TRACE */
|
|
}
|
|
#endif /* VRONI_INFO */
|
|
|
|
#ifdef WITH_TIMING
|
|
if (time_it) {
|
|
if (!quiet) {
|
|
if (cpu_time_pre > 0.0) {
|
|
FP_printf("\nCPU-time Preprocessing (MS): %9.1f",
|
|
FP_PRNTARG(cpu_time_pre));
|
|
}
|
|
else {
|
|
FP_printf("\nCPU-time Preprocessing (MS): %9.1f (< 10 MS)",
|
|
FP_PRNTARG(cpu_time_pre));
|
|
}
|
|
if (cpu_time_cln > 0.0) {
|
|
FP_printf("\nCPU-time Data Clean-up (MS): %9.1f",
|
|
FP_PRNTARG(cpu_time_cln));
|
|
}
|
|
else {
|
|
FP_printf("\nCPU-time Data Clean-up (MS): %9.1f (< 10 MS)",
|
|
FP_PRNTARG(cpu_time_cln));
|
|
}
|
|
if (cpu_time_pnt > 0.0) {
|
|
FP_printf("\nCPU-time Point VD (MS): %9.1f",
|
|
FP_PRNTARG(cpu_time_pnt));
|
|
}
|
|
else {
|
|
FP_printf("\nCPU-time Point VD (MS): %9.1f (< 10 MS)",
|
|
FP_PRNTARG(cpu_time_pnt));
|
|
}
|
|
if (cpu_time_seg > 0.0) {
|
|
FP_printf("\nCPU-time Segment VD (MS): %9.1f",
|
|
FP_PRNTARG(cpu_time_seg));
|
|
}
|
|
else {
|
|
FP_printf("\nCPU-time Segment VD (MS): %9.1f (< 10 MS)",
|
|
FP_PRNTARG(cpu_time_seg));
|
|
}
|
|
if (cpu_time_arc > 0.0) {
|
|
FP_printf("\nCPU-time Arc VD (MS): %9.1f",
|
|
FP_PRNTARG(cpu_time_arc));
|
|
}
|
|
else {
|
|
FP_printf("\nCPU-time Arc VD (MS): %9.1f (< 10 MS)",
|
|
FP_PRNTARG(cpu_time_arc));
|
|
}
|
|
if (cpu_time_off > 0.0) {
|
|
FP_printf("\nCPU-time Offsetting (MS): %9.1f",
|
|
FP_PRNTARG(cpu_time_off));
|
|
}
|
|
else {
|
|
FP_printf("\nCPU-time Offsetting (MS): %9.1f (< 10 MS)",
|
|
FP_PRNTARG(cpu_time_off));
|
|
}
|
|
#ifdef HSM
|
|
if (cpu_time_path > 0.0) {
|
|
FP_printf("\nCPU-time HSM path (MS): %9.1f",
|
|
FP_PRNTARG(cpu_time_path));
|
|
}
|
|
else {
|
|
FP_printf("\nCPU-time HSM path (MS): %9.1f (< 10 MS)",
|
|
FP_PRNTARG(cpu_time_path));
|
|
}
|
|
#endif
|
|
if (cpu_time_wmat > 0.0) {
|
|
FP_printf("\nCPU-time WMAT Computation (MS): %9.1f",
|
|
FP_PRNTARG(cpu_time_wmat));
|
|
}
|
|
else {
|
|
FP_printf("\nCPU-time WMAT Computation (MS): %9.1f (< 10 MS)",
|
|
FP_PRNTARG(cpu_time_wmat));
|
|
}
|
|
if (cpu_time_mic > 0.0) {
|
|
FP_printf("\nCPU-time MIC Computation (MS): %9.1f",
|
|
FP_PRNTARG(cpu_time_mic));
|
|
}
|
|
else {
|
|
FP_printf("\nCPU-time MIC Computation (MS): %9.1f (< 10 MS)",
|
|
FP_PRNTARG(cpu_time_mic));
|
|
}
|
|
}
|
|
double cpu_time_tot = cpu_time_pre + cpu_time_pnt + cpu_time_seg
|
|
+ cpu_time_arc + cpu_time_off + cpu_time_wmat + cpu_time_mic
|
|
+ cpu_time_cln + cpu_time_path;
|
|
if (!quiet) {
|
|
if (cpu_time_tot > 0.0) {
|
|
FP_printf("\n\nTotal CPU-time Consumption (MS): %9.1f\n",
|
|
FP_PRNTARG(cpu_time_tot));
|
|
}
|
|
else {
|
|
FP_printf("\n\nTotal CPU-time Consumption (MS): %9.1f (< 10 MS)\n",
|
|
FP_PRNTARG(cpu_time_tot));
|
|
}
|
|
}
|
|
else {
|
|
FP_printf("%9.1f\n", FP_PRNTARG(cpu_time_tot));
|
|
}
|
|
}
|
|
#endif /* WITH_TIMING */
|
|
|
|
/* */
|
|
/* free all memory allocated */
|
|
/* */
|
|
FreeInputData();
|
|
FreeVDData();
|
|
FreeVDConstructionData();
|
|
FreeEdgeData();
|
|
FreeOffsetData();
|
|
#ifdef GRAPHICS
|
|
if (graphics) {
|
|
FreeDrawingBuffer();
|
|
}
|
|
#endif
|
|
|
|
#ifdef VRONI_INFO
|
|
/* */
|
|
/* check and report memory used */
|
|
/* */
|
|
max_num_bytes = ReportMaxNumberBytes();
|
|
if (verbose && !quiet) {
|
|
if (max_num_bytes > 0)
|
|
printf("Maximum number of bytes allocated -- %lu\n\n",
|
|
max_num_bytes);
|
|
|
|
if (!AllMemoryFreed()) {
|
|
printf("***** Memory has been allocated but ");
|
|
printf("not freed! *****\n");
|
|
} else {
|
|
printf("\nMemory successfully freed.\n");
|
|
|
|
}
|
|
}
|
|
|
|
if (!quiet)
|
|
printf("************************************************************\n");
|
|
#endif
|
|
|
|
#ifdef GRAPHICS
|
|
if (graphics) {
|
|
#if defined(OGL_GRAPHICS)
|
|
exit(0);
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|
|
void vroniObject::apiComputeOff(vr_bool time, char off_file[], vr_bool write_off,
|
|
vr_bool dxf_format, double t_offset,
|
|
double d_offset, vr_bool auto_offset,
|
|
vr_bool left_offset, vr_bool right_offset)
|
|
{
|
|
vr_bool off_finished;
|
|
|
|
#ifdef TRACE
|
|
printf("\n\n---- parameter values at first call of apiComputeOff() ---\n");
|
|
PrintVarValue(stdout, (void*)&time, "time", vroniBOOLEAN);
|
|
PrintVarValue(stdout, (void*)off_file, "off_file", vroniCHARS);
|
|
PrintVarValue(stdout, (void*)&write_off, "write_off", vroniBOOLEAN);
|
|
PrintVarValue(stdout, (void*)&dxf_format, "dxf_format", vroniBOOLEAN);
|
|
PrintVarValue(stdout, (void*)&t_offset, "t_offset", vroniDOUBLE);
|
|
PrintVarValue(stdout, (void*)&d_offset, "d_offset", vroniDOUBLE);
|
|
PrintVarValue(stdout, (void*)&auto_offset, "auto_offset", vroniBOOLEAN);
|
|
PrintVarValue(stdout, (void*)&left_offset, "left_offset", vroniBOOLEAN);
|
|
PrintVarValue(stdout, (void*)&right_offset, "right_offset", vroniBOOLEAN);
|
|
printf("-----------------------------------------------------------\n");
|
|
#endif
|
|
|
|
if (auto_offset) {
|
|
if (data_scaled) {
|
|
assert(scale_factor > 0.0);
|
|
t_offset = UnscaleV(0.001);
|
|
}
|
|
else {
|
|
t_offset = 0.001;
|
|
}
|
|
if (num_pnts > 30)
|
|
d_offset = 30.0 * t_offset / log(log((double)num_pnts));
|
|
else
|
|
d_offset = 30.0 * t_offset;
|
|
if (d_offset < (10.0 * t_offset)) d_offset = 10.0 * t_offset;
|
|
if (num_pnts > 250000) d_offset *= 10.0;
|
|
}
|
|
if (le(t_offset, ZERO)) {
|
|
return;
|
|
}
|
|
|
|
if (left_offset && right_offset) {
|
|
left_offset = right_offset = false;
|
|
}
|
|
|
|
if (!GetVDStatus()) {
|
|
throw std::runtime_error("VRONI error: apiComputeOff() - VD not known or not up-to-date!");
|
|
}
|
|
|
|
e_data_init = true;
|
|
|
|
/* */
|
|
/* no interactive graphics; compute the offset curves */
|
|
/* */
|
|
ComputeOff(INT_MAX, time, off_file, write_off, dxf_format, t_offset,
|
|
d_offset, &off_finished, left_offset, right_offset);
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
#ifdef MAT
|
|
void vroniObject::apiComputeWMAT(vr_bool auto_wmat, double wmat_angle,
|
|
double wmat_dist, vr_bool time,
|
|
vr_bool left_wmat, vr_bool right_wmat)
|
|
{
|
|
#ifdef TRACE
|
|
printf("\n\n--- parameter values at first call of apiComputeWMAT() ---\n");
|
|
PrintVarValue(stdout, (void*)&auto_wmat, "auto_wmat", vroniBOOLEAN);
|
|
PrintVarValue(stdout, (void*)&wmat_angle, "wmat_angle", vroniDOUBLE);
|
|
PrintVarValue(stdout, (void*)&wmat_dist, "wmat_dist", vroniDOUBLE);
|
|
PrintVarValue(stdout, (void*)&time, "time", vroniBOOLEAN);
|
|
PrintVarValue(stdout, (void*)&left_wmat, "left_wmat", vroniBOOLEAN);
|
|
PrintVarValue(stdout, (void*)&right_wmat, "right_wmat", vroniBOOLEAN);
|
|
printf("-----------------------------------------------------------\n");
|
|
#endif
|
|
|
|
if (!GetVDStatus()) {
|
|
throw std::runtime_error("VRONI error: apiComputeWMAT() - VD not known or not up-to-date!");
|
|
}
|
|
ResetWMATStatus();
|
|
|
|
if (auto_wmat) {
|
|
if (data_scaled) {
|
|
assert(scale_factor > 0.0);
|
|
wmat_dist = 0.001 / scale_factor;
|
|
}
|
|
else {
|
|
wmat_dist = 0.001;
|
|
}
|
|
wmat_angle = 0.1;
|
|
}
|
|
|
|
#ifndef WMAT
|
|
wmat_angle = wmat_dist = 0.0;
|
|
#endif
|
|
|
|
/* */
|
|
/* no interactive graphics; compute the WMAT */
|
|
/* */
|
|
ComputeWMAT(wmat_angle, wmat_dist, time, left_wmat, right_wmat);
|
|
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
|
|
void vroniObject::apiComputeOutputMIC(vr_bool time,
|
|
vr_bool left_mic, vr_bool right_mic,
|
|
coord *center, double *radius)
|
|
{
|
|
#ifdef TRACE
|
|
printf("\n\n---- parameter values at first call of apiComputeOutputMIC() ---\n");
|
|
PrintVarValue(stdout, (void*)&time, "time", vroniBOOLEAN);
|
|
PrintVarValue(stdout, (void*)&left_mic, "left_mic", vroniBOOLEAN);
|
|
PrintVarValue(stdout, (void*)&right_mic, "right_mic", vroniBOOLEAN);
|
|
printf("-----------------------------------------------------------\n");
|
|
#endif
|
|
|
|
#ifdef MIC
|
|
if (!GetVDStatus()) {
|
|
throw std::runtime_error("VRONI error: apiComputeOutputMIC() - VD not known or not up-to-date!");
|
|
}
|
|
|
|
/* */
|
|
/* no interactive graphics; compute the MIC */
|
|
/* */
|
|
ComputeMIC(time, left_mic, right_mic, center, radius);
|
|
#else
|
|
time = false;
|
|
left_mic = false;
|
|
right_mic = false;
|
|
center->x = center->y = *radius = 0.0; /* avoid compiler complaints ... */
|
|
#endif
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
void vroniObject::apiResetAll(void)
|
|
{
|
|
/* */
|
|
/* reset global and static data within individual files */
|
|
/* */
|
|
#ifdef GRAPHICS
|
|
if (graphics) {
|
|
#if defined (OGL_GRAPHICS)
|
|
ResetGraphicsData();
|
|
#else
|
|
ExtApplResetGraphicsData;
|
|
#endif
|
|
ResetBufferData();
|
|
}
|
|
#endif
|
|
ResetInputData();
|
|
ResetVDData();
|
|
ResetVDConstructionData();
|
|
ResetEdgeData();
|
|
ResetOffsetData();
|
|
#ifdef MAT
|
|
ResetWMATStatus();
|
|
#endif
|
|
ResetIntersectionData();
|
|
ResetIntersectionStatus();
|
|
ResetCleanStatus();
|
|
|
|
isolated_pnts = false;
|
|
|
|
/* */
|
|
/* let the user call some application-specific function */
|
|
/* */
|
|
ExtApplFuncReset;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
void vroniObject::apiResetOffsetData(void)
|
|
{
|
|
ResetOffsetData();
|
|
}
|
|
|
|
|
|
const char* vroniObject::apiGetProgName()
|
|
{
|
|
return PROG_NAME;
|
|
}
|
|
|
|
|
|
|
|
const char* vroniObject::apiGetProgVersion()
|
|
{
|
|
return PROG_VERSION;
|
|
}
|
|
|
|
|
|
|
|
const char* vroniObject::apiGetProgYear()
|
|
{
|
|
return PROG_YEAR;
|
|
}
|
|
|
|
|