Files
vroni/driver.cc
T
SaraP 739088af9f Vroni 7.8 :
- aggiornamento versione.
2025-01-29 16:24:30 +01:00

491 lines
17 KiB
C++

/*****************************************************************************/
/* */
/* Copyright (C) Martin Held 1999-2025 */
/* */
/* */
/* 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 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-611 */
/* Voice Mail: (+43 662) 8044-6304 */
/* Snail Mail: Martin Held */
/* FB Informatik */
/* Universitaet Salzburg */
/* A-5020 Salzburg, Austria */
/* */
/*****************************************************************************/
/* */
/* Please read the files README.txt and README_data.txt prior to 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>
/* */
/* get my header files */
/* */
#include "fpkernel.h"
#include "vronivector.h"
#include "vroni_object.h"
#ifdef GRAPHICS
#include "numerics.h"
#endif
#define Bell '\007'
void vroniObject::ProceedWithoutGraphics(vr_bool new_data)
{
#ifdef MIC
coord center;
double rad;
#endif
if (!new_data) return;
new_input = new_data;
/* */
/* no interactive graphics; compute the VD */
/* */
API_ComputeVD(save_data, new_input, time_it, bound, sample, approx,
output_file, discard_dupl_s, pnts_only, write_vd_dt,
vd_dt_file, clean_up);
/* */
/* compute all offset curves */
/* */
if (auto_offset || (t_offset > 0.0))
API_ComputeOff(time_it, off_file, write_off, dxf_format,
t_offset, d_offset,
auto_offset, left_offset, right_offset);
#ifdef WRITE_VD
/* */
/* approximate conic VD edges by straight-line segments and write every */
/* Voronoi region as one polygon to an OBJ file. the clearance radii */
/* are added as z-coordinates of the vertices */
/* */
if (write_vd) {
API_Output_VD(vd_file, vd_apx_dist, left_vd, right_vd);
write_vd = false;
}
#endif
#ifdef MAT
/* */
/* compute the weighted medial axis */
/* */
if (compute_wmat && !pnts_only) {
API_ComputeWMAT(auto_wmat, wmat_angle, wmat_dist, time_it,
left_offset, right_offset);
if (write_ma) API_OutputMA(ma_file);
}
#endif
/* */
/* compute the maximum inscribed/empty circle */
/* */
#ifdef MIC
if (compute_mic && !pnts_only)
API_ComputeOutputMIC(time_it, left_offset, right_offset, &center, &rad);
center.x = center.y = rad = 0.0; /* avoid compiler complaints since */
/* we don't use those variables... */
#endif
#ifdef HSM
if (compute_path) {
ComputePath(time_it, path_file, write_path, dxf_format, tool_rad,
step_over, angle);
}
#endif
return;
}
void vroniObject::ParseCommandLineArgs(int argc, char *argv[],
vr_bool *do_graphics,
vr_bool *color_graphics,
vr_bool *full_screen)
{
if (!ArgEval(argc, argv, color_graphics, do_graphics, &save_data,
output_file, &read_polygon, input_file, &read_poly,
&driver_step_size, &verbose, &write_ipe, &help, &time_it,
&statistics, &print_copy, &quiet, &bound, &sample,
&scale_data, &approx,
&read_sites, &read_xdr, &read_graphml, &discard_dupl_s,
&p_step_size, &read_e00, &read_dxf, &read_polylines,
&t_offset, &d_offset, &write_off, off_file, &o_step_size,
&auto_offset, full_screen, &read_usgs, &left_offset,
&right_offset, &compute_wmat, &wmat_angle, &wmat_dist,
&auto_wmat, &pnts_only, &compute_mic, &a_step_size,
&check_data, &write_vd_dt, vd_dt_file, &read_pnts,
&dxf_format, &read_file, &write_ma, ma_file, &clean_up,
&write_vd, vd_file, &vd_apx_dist, &left_vd, &right_vd,
&vr_incr, vr_file, &inputprec, &mpfr_prec, &vr_seed,
&compute_path, &tool_rad, &angle, &step_over,
&write_path, path_file)) {
Copyright();
EvalError();
throw std::runtime_error("VRONI error: ArgEval() - unrecognized CL option!");
}
else if (print_copy && !quiet) {
Copyright();
}
if (help) {
Help();
EvalError();
exit(0);
}
#ifdef GRAPHICS
graphics = *do_graphics;
if (read_pnts || pnts_only) draw_pnts = true;
#endif
#ifdef WITH_COREBACKEND
if(inputprec == -1) {
setDefaultInputDigits(CORE_INFTY);
} else {
setDefaultInputDigits(inputprec);
}
#elif defined(WITH_MPFRBACKEND)
set_mpfrbackend_prec(mpfr_prec, verbose);
#endif
return;
}
void vroniObject::GetInputData(vr_bool *input_read)
{
vr_bool format_specified;
format_specified = read_polygon || read_poly || read_sites ||
read_xdr || read_e00 || read_polylines || read_usgs ||
read_dxf || read_pnts || read_graphml;
/* */
/* get input data */
/* */
if (format_specified || read_file) {
/* */
/* read sites from input file. use API_ArrayInput() for a simple way */
/* to feed data directly into VRONI. */
/* */
if (format_specified)
API_HandleInput(input_file, &new_input, read_polygon, read_poly,
read_sites, read_xdr, read_e00, read_polylines,
read_usgs, read_dxf, read_pnts, read_graphml);
else
API_FileInput(input_file, &new_input);
*input_read = new_input;
#if defined (OGL_GRAPHICS)
data_read = new_input;
draw_pnts = isolated_pnts;
#endif
}
else {
*input_read = false;
}
return;
}
#ifdef OGL_GRAPHICS
void vroniObject::HandleComputeVD(void)
{
vr_bool stop_for_debugging = false; /* for my debugging purposes */
vr_bool dummy_draw_pnts;
#ifdef MIC
coord center;
double rad;
#endif
if (!computed) {
if (io_flag == 1) VD_Info("done!\n");
new_input = data_read || new_input || (new_pnts > 0);
finished = !new_input;
}
io_flag = 2;
if (!finished) {
do {
ComputeVD(save_data, new_input, driver_step_size, time_it, bound, sample,
approx, output_file, discard_dupl_s, p_step_size,
&finished, a_step_size, pnts_only, write_vd_dt, vd_dt_file,
left_offset, right_offset, clean_up);
/*stop_for_debugging = true;*/
} while (restart && !stop_for_debugging);
computed = true;
data_read = false;
new_input = false;
if (finished && auto_offset) off_init = true;
}
if (computed && finished && !off_finished) {
if (auto_offset || (t_offset > 0.0)) {
if (off_init) {
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;
off_init = false;
}
if (left_offset && right_offset) {
left_offset = right_offset = false;
}
if (gt(t_offset, ZERO))
ComputeOff(o_step_size, time_it, off_file, write_off, dxf_format,
t_offset, d_offset, &off_finished,
left_offset, right_offset);
else
off_finished = true;
}
else {
off_finished = true;
}
}
#ifdef WRITE_VD
if (computed && finished && write_vd) {
OutputVD(vd_file, vd_apx_dist, left_vd, right_vd);
write_vd = false;
}
#endif
#ifdef MAT
if (computed && finished && off_finished && !wmat_computed &&
!pnts_only) {
#ifdef WMAT
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;
}
#else
wmat_angle = wmat_dist = 0.0;
#endif
if (compute_wmat) {
draw_mat = true;
ComputeWMAT(wmat_angle, wmat_dist, time_it, left_offset,
right_offset);
wmat_computed = true;
if (write_ma) OutputMA(ma_file);
}
}
#endif
#ifdef MIC
if (computed && finished && !mic_computed && !pnts_only) {
if (compute_mic) {
draw_mic = true;
ComputeMIC(time_it, left_offset, right_offset, &center, &rad);
center.x = center.y = rad = 0.0; /* avoid GCC complaints ...*/
mic_computed = true;
}
}
#endif
#ifdef HSM
if (computed && finished && !path_computed) {
if (compute_path) {
ComputePath(time_it, path_file, write_path, dxf_format, tool_rad,
step_over, angle);
path_computed = true;
}
}
#endif
if (computed && finished && !quiet && (off_finished || path_computed)) {
/* */
/* hey, let's ring the bell */
/* */
if (write_ipe) {
dummy_draw_pnts = draw_pnts;
draw_pnts = true;
WriteIpeOutput(output_file);
draw_pnts = dummy_draw_pnts;
}
printf("%c\n", Bell);
printf("%c\n", Bell);
printf("%c\n", Bell);
}
return;
}
void vroniObject::ClosePolygon(void)
{
if (!computed && (io_flag != 2)) {
if (first_pnt != last_pnt) {
assert(first_pnt != NIL);
assert(last_pnt != NIL);
assert(new_pnts > 0);
#ifdef EXT_APPL_SITES
CloseSeg(last_pnt, first_pnt, eas_NIL);
#else
CloseSeg(last_pnt, first_pnt);
#endif
DrawSeg(GetPntCoords(last_pnt), GetPntCoords(first_pnt), SegColor);
new_input = true;
}
else {
new_input = (new_pnts > 0);
fprintf(stderr, "\n\n***** No polygon to close! *****\n");
}
first_pnt = NIL;
last_pnt = NIL;
new_pnts = 0;
new_input = data_read || new_input;
}
io_flag = 2;
return;
}
void vroniObject::StartNewPolygon(void)
{
if (!computed) {
if (first_input) {
VD_Info("...storing the input data -- ");
first_input = false;
draw_pnts = true;
}
io_flag = 1;
first_pnt = NIL;
last_pnt = NIL;
isolated_pnts = true;
}
return;
}
void vroniObject::AddPolygonVertex(double_arg xc1, double_arg yc1)
{
int i;
if (!computed && (io_flag == 1)) {
if (first_pnt == NIL) {
#ifdef EXT_APPL_PNTS
first_pnt = HandlePnt(xc1, yc1, eap_NIL);
#else
first_pnt = HandlePnt(xc1, yc1);
#endif
last_pnt = first_pnt;
}
else {
i = last_pnt;
#ifdef EXT_APPL_SITES
AddSeg(&last_pnt, xc1, yc1, eas_NIL);
#else
AddSeg(&last_pnt, xc1, yc1);
#endif
DrawSeg(GetPntCoords(last_pnt), GetPntCoords(i), SegColor);
}
DrawPnt(GetPntCoords(last_pnt), PntColor, true);
if (pnts_only) {
StartNewPolygon();
#ifdef OGL_GRAPHICS
ResetRubberLine();
#endif
}
FlushDisplay();
++new_pnts;
}
return;
}
void vroniObject::ResetOnlineGraphicsData(void)
{
first_input = true;
first_pnt = NIL;
last_pnt = NIL;
new_pnts = 0;
return;
}
void vroniObject::ResetDriverData(void)
{
computed = false;
finished = false;
off_finished = false;
off_init = false;
wmat_computed = false;
mic_computed = false;
vd_output = false;
io_flag = 0;
return;
}
#endif /* OGL_GRAPHICS */