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

958 lines
35 KiB
C++

/*****************************************************************************/
/* */
/* Copyright (C) Martin Held 1999-2025 */
/* */
/* This code is provided at no charge to you for non-commercial purposes */
/* only and only for use internal to your institution. You may use this */
/* code for academic evaluation and applications, following standard */
/* rules of academic conduct including crediting the author(s) and the */
/* copyright holder in any publications. This code is not in the public */
/* domain, and may not be duplicated, altered, sold or re-distributed */
/* without obtaining the prior written consent of the copyright holder. */
/* No part of this code may be used for or included in any commercial */
/* application unless your institution obtains a commercial license. */
/* Please contact the author, Martin Held (held@cs.sbg.ac.at), for */
/* commercial licensing terms. */
/* */
/* 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. */
/* */
/*****************************************************************************/
/* */
/* 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.txt and README_data.txt files before compiling or */
/* using this code! */
/* */
/*****************************************************************************/
/* */
/* get standard libraries */
/* */
#include <stdio.h>
#include <math.h>
#include <limits.h>
#include <assert.h>
#include <stdlib.h>
/* */
/* get my header files */
/* */
#include "fpkernel.h"
#include "vronivector.h"
#include "vroni_object.h"
#include "defs.h"
#include "random.h"
#include "numerics.h"
/*
* please turn those define's only on if you know what you do! (they are
* here only for my debugging purposes!!
*
#define TRACE_VD
#define INIT_FORCED
#define TRACE_INPUT
*
*/
/* */
/* this subroutine drives the computation of the voronoi diagram. the VD is */
/* computed in an area whose width equals (2*bound+1) times the width of the */
/* bounding box of the input data, and whose height equals (2*bound+1) times */
/* the height of the bounding box of the input data. */
/* */
/* if ComputeVD() were to be called from a user's application program then */
/* it is the responsibility of this application program to initialize all */
/* arrays appropriately. see ReadPolygon(), ReadPoly() or ReadSites() in the */
/* file io.c. It might be best to interface to this subroutine only via the */
/* API-functions provided; see main(). */
/* */
void vroniObject::ComputeVD(vr_bool save_data, vr_bool new_input,
int step_size, vr_bool time, int bound,
int sample, int approx, char output_file[],
vr_bool discard_duplicate_sites, int p_step_size,
vr_bool *finished, int a_step_size,
vr_bool pnts_only, vr_bool write_vd_dt,
char vd_dt_file[],
vr_bool left_vd, vr_bool right_vd,
vr_bool clean_up)
{
#ifdef GRAPHICS
int i;
#endif
int j;
#ifdef TRACE
vr_bool trace_write_debug = false;
#endif
#ifdef TRACE_INPUT
vr_bool trace_pnt = true, trace_seg = true, trace_arc = true;
#endif
#ifdef VRONI_INFO
double eps;
#endif
/* */
/* make sure that the compile-time options selected by the user are */
/* reasonable. */
/* */
#ifdef INVERSE
#ifndef SORTED
throw std::runtime_error("VRONI error: ComputeVD() - Inverse sorting requires -DSORTED and -DINVERSE!");
#endif
#endif
#ifdef RANDOM
#ifdef SORTED
throw std::runtime_error("VRONI error: ComputeVD() - Do not use -DRANDOM and -DSORTED together!");
#else /* else if not SORTED */
#ifdef ORDERED
throw std::runtime_error("VRONI error: ComputeVD() - Do not use -DRANDOM and -DORDERED together!");
#else /* else if not ORDERED */
#ifdef FORCED
throw std::runtime_error("VRONI error: ComputeVD() - Do not use -DRANDOM and -DFORCED together!");
#endif /* endif FORCED */
#endif /* endif ORDERED */
#endif /* endif SORTED */
#else /* else if not RANDOM */
#ifdef SORTED
#ifdef ORDERED
throw std::runtime_error("VRONI error: ComputeVD() - Do not use -DSORTED and -DORDERED together!");
#else /* else if not ORDERED */
#ifdef FORCED
throw std::runtime_error("VRONI error: ComputeVD() - Do not use -DSORTED and -DFORCED together!");
#endif /* endif FORCED */
#endif /* endif ORDERED */
#else /* else if not SORTED */
#ifdef ORDERED
#ifdef FORCED
throw std::runtime_error("VRONI error: ComputeVD() - Do not use -DORDERED and -DFORCED together!");
#endif /* endif FORCED */
#endif /* endif ORDERED */
#endif /* endif SORTED */
#endif /* endif RANDOM */
#ifndef RANDOM
#ifndef SORTED
#ifndef ORDERED
#ifndef FORCED
VD_Warning("ComputeVD() - it is recommended to use -DRANDOM!");
#endif
#endif
#endif
#endif
#ifdef INIT_FORCED
#ifndef RANDOM
VD_Warning("ComputeVD() - please use -INIT_FORCED only with -DRANDOM!");
#endif
#endif
/* */
/* actual start of code for inserting sites into a VD */
/* */
#ifdef GRAPHICS
if (graphics) ResetCurBuffer(); /* only if OpenGL display is enabled */
#else
step_size = INT_MAX;
p_step_size = INT_MAX;
a_step_size = INT_MAX;
left_vd = false;
right_vd = false;
#endif
/* */
/* check whether there seems to be input data; note that every seg or arc */
/* results in two pnts to handled! */
/* */
if (num_pnts <= 0) {
VD_Warning("ComputeVD() - no sites!");
*finished = true;
initialized = false;
return;
}
else {
*finished = false;
}
/* */
/* branch depending on whether this call of ComputeVD() is for */
/* - entirely new data, with no pre-existing VD and no appropriate */
/* preprocessing done yet; */
/* - for another round of insertions of sites into an already existing */
/* VD, with preprocessing already done; */
/* - a restart of the code on data that had already been subjected to */
/* preprocessing once; this may happen if the input data suffers from */
/* deficiencies such as self-intersections. */
/* */
if (restart) {
if (vr_incr) {
if (vr_file_handle != ((FILE*)NULL)) fclose(vr_file_handle);
}
restart = false;
if (restart_due_to_intersection) {
restart_due_to_intersection = false;
restart_without_intersection = 0;
++intersection_counter;
}
else {
++restart_counter;
++restart_without_intersection;
}
if (restart_without_intersection > MAX_RESTART) {
throw std::runtime_error("VRONI error: ComputeVD() - aborting computation -- too many restarts!");
}
#ifdef VRONI_INFO
else if (!quiet) {
printf("warning in ComputeVD() - restart # %d of VD computation!\n",
restart_counter + intersection_counter);
}
#endif
ExtApplComputeRestarts;
#ifdef GRAPHICS
ResetBufferData();
#endif
ResetVDData();
ResetVDConstructionData();
ResetFlags();
#ifdef VRONI_INFO
InitRelaxationMemory(TINY);
#endif
sample = 0;
new_input = true;
discard_duplicate_sites = true;
#ifdef INIT_FORCED
fprintf(fcd_output, "\n");
fclose(fcd_output);
#endif
/* */
/* let the user call some application-specific function */
/* */
ExtApplFuncRestart;
}
else if (new_input) {
#ifdef VRONI_INFO
InitRelaxationMemory(TINY);
#endif
removed_pnts = removed_segs = removed_arcs = 0;
restart_counter = intersection_counter = 0;
restart_without_intersection = 0;
bbox_added = false;
io_troubles = false;
cpu_time_pre = 0.0;
cpu_time_pnt = 0.0;
cpu_time_seg = 0.0;
cpu_time_arc = 0.0;
cpu_time_cln = 0.0;
/* */
/* we reset the random number generator in order to guarantee that the */
/* randomized incremental insertion will yield the same result when */
/* applying it repeatedly to the same data set. */
/* */
InitRandom(vr_seed);
#ifdef INIT_FORCED
/* the next three lines might cause troubles on your machine... */
system("rm forced_order_pnts.txt");
system("rm forced_order_segs.txt");
system("rm forced_order_arcs.txt");
#endif
}
else if (!initialized) {
VD_Warning("ComputeVD() - no input!?");
*finished = true;
return;
}
if (new_input) {
/* */
/* preprocessing phase of the VD algorithm */
/* */
VD_Info("...preprocessing -- ");
if (time) (void) elapsed();
num_pnts_deleted = 0;
initialized = true;
new_input = false;
restart = false;
troubles = false;
desperate = false;
numerical = false;
written = false;
done_pnts = false;
done_segs = false;
done_arcs = false;
first_pnts = true;
first_segs = true;
#ifdef GENUINE_ARCS
first_arcs = true;
#endif
incremental = false;
/* */
/* compute the bounding box of the points pnts[0,...,num_pnts-1]. */
/* */
if (!bbox_initialized) SetBoundingBox();
if ((num_arcs > 0) && bbox_initialized &&
(!bbox_added || (num_critical_arcs > 0))) ExtendBoundingBox();
/* */
/* scale the data if scaling is requested. */
/* */
if (bbox_initialized) {
if (scale_data && !data_scaled) {
ScaleData();
#if defined(OGL_GRAPHICS)
if (graphics && data_scaled) UpdateScaleData();
#endif
}
}
/* */
/* enlarge the bounding box according to "bound" by adding four dummy */
/* points. */
/* */
if (bbox_initialized && !bbox_added) AddDummyCorners(bound);
/* */
/* if requested, replace the segs/arcs by a dense sample of points, */
/* note that we also need to adjust the bounding box if arcs are */
/* sampled. */
/* */
if ((sample > 0) && ((num_segs > 0) || (num_arcs > 0)))
SampleData(sample);
/* */
/* if requested, approximate the circular arcs. note that we also need */
/* to adjust the bounding box. */
/* */
if (pnts_only) {
/* */
/* we'll only compute the VD and DT of points. */
/* */
num_segs = 0;
num_arcs = 0;
isolated_pnts = true;
}
#ifndef GENUINE_ARCS
if (num_arcs > 0)
throw std::runtime_error("VRONI error: ComputeVD() - genuine circular arcs not supported!\n");
#endif
#ifdef OTHER
if (cgal && (restart_counter == 0)) {
VD_Info("...writing input data for CGAL's VD code --");
WriteCgalSites("cgal_data.cin");
VD_Info(" done.\n");
printf("note that VRONI's CPU timing is incorrect due to this file I/O!\n");
}
#endif
/* */
/* sort the vertices in lexicographic order, discard duplicate */
/* vertices, and remove zero-length segs/arcs. */
/* */
if (clean_up) discard_duplicate_sites = true;
CleanData(&removed_pnts, &removed_segs, &removed_arcs,
discard_duplicate_sites);
pnts_deleted = false;
/* */
/* preprocess the circular arcs */
/* */
SetPreprocessingThreshold(GetIntersectionThreshold());
num_critical_arcs = 0;
#ifdef GENUINE_ARCS
if (num_arcs > 0) PreprocessArcs(&num_critical_arcs);
#endif
done_arcs = (num_arcs == 0);
/* */
/* preprocess the line segments */
/* */
num_critical_segs = 0;
if (num_segs > 0) PreprocessSegments(&num_critical_segs);
if (restart) return;
done_segs = (num_segs == 0);
/* */
/* build a grid for speeding up the nearest-neighbor search */
/* */
BuildGrid();
if (vr_incr && pnts_only) vr_file_handle = OpenFileVD(vr_file, "w");
if (time) cpu_time_pre += elapsed();
/* */
/* let the user call some application-specific function */
/* */
ExtApplFuncNewInput;
#ifndef NDEBUG
CheckBoundingBox();
#endif
#ifdef GRAPHICS
if (graphics && (p_step_size < INT_MAX)) return;
#endif
VD_Info("done!\n");
}
if (!done_pnts) {
/***********************************************************************/
/* */
/* compute the Voronoi diagram of the points/vertices. */
/* */
/***********************************************************************/
if (first_pnts) {
/* */
/* pnt-specific preprocessing: compute the initial VD and */
/* initialize the insertion order of the pnts */
/* */
VD_Info("...computing VD of points -- ");
if (time) (void)elapsed();
if ((num_segs == 0) && (num_arcs == 0)) pnts_only = true;
first_pnts = false;
ComputeInitialVD();
InitSiteOrder(PNT);
n_pnts = 3;
max_n_pnts = num_pnts - 2;
assert(max_n_pnts >= 3);
#ifdef INIT_FORCED
fcd_output = OpenFileVD("forced_order_pnts.txt", "a");
fprintf(fcd_output, "restart: %d\n", restart_counter);
#endif
#ifdef TRACE_INPUT
if (trace_pnt) {
ClipWriteSiteData(2, PNT, "cwsd.site");
// printf("2\n%20.16f %20.16f\n", pnts[2].p.x, pnts[2].p.y);
}
#endif
#ifdef GRAPHICS
draw_segs = false;
draw_arcs = false;
if (graphics) {
if (p_step_size < INT_MAX) {
draw_pnts = true;
incremental = true;
ResetVDBuffer();
AddVDToBuffer(false, false);
AddDelToBuffer();
return;
}
if ((step_size < INT_MAX) || (a_step_size < INT_MAX)) {
draw_pnts = true;
}
}
#endif
if (vr_incr && pnts_only) {
assert(vr_file_handle != ((FILE*)NULL));
WriteVoronoiRegion(2, vr_file_handle);
}
/* */
/* let the user call some application-specific function */
/* */
ExtApplFuncFirstPnts;
}
/* */
/* insert the points pnts[3,...,num_pnts-3] into the VD according to */
/* the insertion order selected. */
/* recall that pnts[0,1,2,num_pnts-2,num_pnts-1] have been inserted */
/* into the VD by ComputeInitialVD(). */
/* */
#ifdef GRAPHICS
i = 0;
while ((i < p_step_size) && (n_pnts < max_n_pnts)) {
++i;
#else
while (n_pnts < max_n_pnts) {
#endif
j = GetNextSite();
#ifdef INIT_FORCED
fprintf(fcd_output, "%d\n", j);
#endif
#ifdef TRACE_INPUT
if (trace_pnt) {
ClipWriteSiteData(j, PNT, "cwsd.site");
// printf("2\n%20.16f %20.16f\n", pnts[j].p.x, pnts[j].p.y);
}
#endif
InsertPntIntoVD(j);
if (restart) return;
/* */
/* output the newly computed Voronoi region of pnts[j], if required */
/* */
if (vr_incr && pnts_only) {
assert(vr_file_handle != ((FILE*)NULL));
WriteVoronoiRegion(j, vr_file_handle);
}
++n_pnts;
}
if (n_pnts == max_n_pnts) {
/* */
/* all pnts have been inserted into the VD */
/* */
FreeGrid();
FreeTree();
FreeReverseIndex();
#ifdef INIT_FORCED
fprintf(fcd_output, "\n");
fclose(fcd_output);
#endif
#ifdef GRAPHICS
if (graphics) {
if (p_step_size == INT_MAX) ResetCurBuffer();
ResetVDBuffer();
if ((num_segs == 0) || (p_step_size < INT_MAX) ||
(step_size < INT_MAX)) AddVDToBuffer(false, false);
AddDelToBuffer();
}
#endif
/* */
/* if more than just the VD/DT of points is sought */
/* */
if (!done_segs || !done_arcs) {
TakeSquareOfNodes();
InsertDegreeTwoNodes();
}
done_pnts = true;
if (vr_incr && pnts_only) {
assert(vr_file_handle != ((FILE*)NULL));
fclose(vr_file_handle);
}
if (time) cpu_time_pnt += elapsed();
VD_Info("done!\n");
#ifndef NDEBUG
if (!CheckVD(false)) {
VD_Warning("ComputeVD() - topological problem in point VD!");
troubles = true;
}
#endif
/* */
/* let the user call some application-specific function */
/* */
ExtApplFuncDonePnts;
#ifdef GRAPHICS
if (graphics &&
((p_step_size < INT_MAX) || (step_size < INT_MAX)))
return;
#endif
}
#ifdef GRAPHICS
else if (graphics) {
ResetVDBuffer();
AddVDToBuffer(false, false);
AddDelToBuffer();
#ifdef TRACE
if (grid_used) DrawGrid();
else DrawTree();
#endif
return;
}
#endif
}
if (done_pnts && !done_segs) {
/***********************************************************************/
/* */
/* insert the straight-line segments into the VD */
/* */
/***********************************************************************/
if (first_segs) {
/* */
/* seg-specific preprocessing: initialize the insertion order of */
/* the segs */
/* */
VD_Info("...computing VD of segments -- ");
if (time) (void)elapsed();
first_segs = false;
InitSiteOrder(SEG);
n_segs = 0;
#ifdef INIT_FORCED
fcd_output = OpenFileVD("forced_order_segs.txt", "a");
fprintf(fcd_output, "restart: %d\n", restart_counter);
#endif
#ifdef GRAPHICS
draw_segs = true;
if (graphics && (step_size < INT_MAX))
incremental = true;
else
incremental = false;
#endif
/* */
/* let the user call some application-specific function */
/* */
ExtApplFuncFirstSegs;
/*if (restart_counter == 5) SetDebugFlagVD(true);*/
}
/* */
/* insert the segments segs[0,...,num_segs-1] into the VD in the */
/* order selected. */
/* */
#ifdef GRAPHICS
i = 0;
while ((i < step_size) && (n_segs < num_segs)) {
++i;
#else
while (n_segs < num_segs) {
#endif
#ifdef TRACE
if (trace_write_debug) WriteProcessedSites("debug.site");
#endif
j = GetNextSite();
#ifdef INIT_FORCED
fprintf(fcd_output, "%d\n", j);
#endif
#ifdef TRACE_INPUT
if (trace_seg) {
//printf("0\n%20.16f %20.16f %20.16f %20.16f\n",
// pnts[segs[j].i1].p.x, pnts[segs[j].i1].p.y,
// pnts[segs[j].i2].p.x, pnts[segs[j].i2].p.y);
ClipWriteSiteData(j, SEG, "cwsd.site");
}
#endif
InsertSegIntoVD(j);
if (restart) {
#ifdef TRACE_INPUT
ClipWriteSiteData(j, UNKNOWN, "cwsd.site");
#endif
#ifdef TRACE_INPUT
if (trace_seg) WriteSiteData(j, SEG, "restart\n");
#ifdef GRAPHICS
if (graphics) AddToCurBuffer(j, SEG, AlertColor);
#endif
#endif
return;
}
#ifdef VRONI_INFO
ConfirmRelaxationMemory();
#endif
++n_segs;
#ifndef NDEBUG
if (!CheckVD(false)) {
fprintf(stderr, "CheckVD - topological problem in VD! ***\n");
troubles = true;
}
#ifdef VRONI_INFO
else {
if (!quiet) printf("VD OK after %d segs\n", n_segs);
}
#endif
#endif
}
if (n_segs == num_segs) {
/* */
/* all segs have been inserted into the VD */
/* */
done_segs = true;
if (time) cpu_time_seg += elapsed();
VD_Info("done!\n");
#ifdef INIT_FORCED
fprintf(fcd_output, "\n");
fclose(fcd_output);
#endif
#ifndef NDEBUG
if (!done_arcs) {
if (!CheckVD(false)) {
VD_Warning("ComputeVD() - topological problem in seg VD!");
troubles = true;
}
}
#endif
/* */
/* let the user call some application-specific function */
/* */
ExtApplFuncDoneSegs;
}
#ifdef GRAPHICS
if (graphics && (step_size < INT_MAX)) {
ResetVDBuffer();
AddVDToBuffer(false, false);
return;
}
#endif
}
#ifdef GENUINE_ARCS
if (done_pnts && done_segs && !done_arcs) {
/***********************************************************************/
/* */
/* insert the circular arcs */
/* */
/***********************************************************************/
if (first_arcs) {
/* */
/* arc-specific preprocessing: initialize the insertion order of */
/* the arcs */
/* */
VD_Info("...computing VD of circular arcs -- ");
if (time) (void)elapsed();
first_arcs = false;
ResetVDConstructionData();
InitSiteOrder(ARC);
n_arcs = 0;
#ifdef INIT_FORCED
fcd_output = OpenFileVD("forced_order_arcs.txt", "a");
fprintf(fcd_output, "restart: %d\n", restart_counter);
#endif
#ifdef GRAPHICS
draw_arcs = true;
if (graphics && (a_step_size < INT_MAX))
incremental = true;
else
incremental = false;
#endif
/* */
/* let the user call some application-specific function */
/* */
ExtApplFuncFirstArcs;
#ifdef GRAPHICS
if (graphics && (a_step_size < INT_MAX)) {
ResetVDBuffer();
AddVDToBuffer(false, false);
return;
}
#endif
}
/* */
/* insert the circular arcs arcs[0,...,num_arcs-1] into the VD, */
/* either in the order they were stored or in random order. */
/* */
#ifdef GRAPHICS
i = 0;
while ((i < a_step_size) && (n_arcs < num_arcs)) {
++i;
#else
while (n_arcs < num_arcs) {
#endif
#ifdef TRACE
if (trace_write_debug) WriteProcessedSites("debug.site");
#endif
j = GetNextSite();
#ifdef INIT_FORCED
fprintf(fcd_output, "%d\n", j);
#endif
#ifdef TRACE_INPUT
if (trace_arc) {
// printf("arc %d\n", j);
// printf("1\n%20.16f %20.16f %20.16f %20.16f %20.16f %20.16f\n",
// pnts[arcs[j].i1].p.x, pnts[arcs[j].i1].p.y,
// pnts[arcs[j].i2].p.x, pnts[arcs[j].i2].p.y,
// arcs[j].c.x, arcs[j].c.y);
ClipWriteSiteData(j, ARC, "cwsd.site");
}
#endif
InsertArcIntoVD(j);
if (restart) {
#ifdef TRACE_INPUT
ClipWriteSiteData(j, UNKNOWN, "cwsd.site");
#endif
#ifdef TRACE_INPUT
if (trace_arc) WriteSiteData(j, ARC, "restart\n");
#ifdef GRAPHICS
if (graphics) AddToCurBuffer(j, ARC, AlertColor);
#endif
#endif
return;
}
#ifdef VRONI_INFO
ConfirmRelaxationMemory();
#endif
#ifndef NDEBUG
if (!CheckVD(false)) {
VD_Warning("CheckVD - topological problem in VD");
troubles = true;
}
#ifdef VRONI_INFO
else {
if (!quiet) printf("VD OK after %d arcs\n", n_arcs + 1);
}
#endif
#endif
++n_arcs;
}
if (n_arcs == num_arcs) {
/* */
/* all arcs have been inserted into the VD */
/* */
done_arcs = true;
if (time) cpu_time_arc += elapsed();
VD_Info("done!\n");
/* */
/* let the user call some application-specific function */
/* */
ExtApplFuncDoneArcs;
#ifdef INIT_FORCED
fprintf(fcd_output, "\n");
fclose(fcd_output);
#endif
}
#ifdef GRAPHICS
if (graphics && (a_step_size < INT_MAX)) {
ResetVDBuffer();
AddVDToBuffer(false, false);
return;
}
#endif
}
#else
if (!done_arcs) {
throw std::runtime_error("VRONI error: ComputeVD() - circular arcs cannot be handled without approximation!");
}
#endif
if (done_pnts && done_segs && done_arcs) {
if (desperate && (restart_counter < MAX_RESTART)) {
restart = true;
return;
}
/* */
/* do we have isolated points? */
/* */
if ((num_segs > 0) || (num_arcs > 0)) {
if (!GetDataSorted()) {
CheckIsolatedPnts();
}
}
else {
isolated_pnts = true;
}
#ifndef NDEBUG
if (!CheckVD(false)) {
VD_Warning("ComputeVD() - topological problem(s) in VD!");
}
else {
VD_Info("\nComputeVD() - VD is topologically correct!");
}
#endif
SetVDStatusTrue();
#ifdef GRAPHICS
if (graphics && ((num_segs > 0) || (num_arcs > 0))) {
draw_pnts = false;
incremental = false;
ResetVDBuffer();
if (step_size == INT_MAX) ResetCurBuffer();
AddVDToBuffer(left_vd, right_vd);
}
#endif
/* */
/* let the user call some application-specific function */
/* */
ExtApplFuncDoneVD;
if (!written) {
if (save_data) {
VD_Info("\n...writing the output data -- ");
WriteSites(output_file);
written = true;
VD_Info("done!\n");
}
if (pnts_only && write_vd_dt) {
VD_Info("\n...writing VD/DT data -- ");
WriteVDDT(vd_dt_file);
VD_Info("done!\n");
}
written = true;
}
#ifdef VRONI_INFO
if (!quiet) {
if (IsCheckComplete() || (intersection_counter > 0)) {
eps = GetIntersectionThreshold();
if (IsCheckComplete()) eps /= 10.0;
}
else {
eps = 0.0;
}
printf("\nComputeVD() - intersection threshold used: %2.1e\n", eps);
#ifdef VRONI_DBG_WARN
printf("ComputeVD() - maximum relaxation used: %2.1e\n",
ReportRelaxationMemory());
#endif
if ((restart_counter + intersection_counter) > 0) {
printf("\nComputeVD() - problems with the input data caused %d restart(s)!",
restart_counter + intersection_counter);
}
else if (io_troubles) {
VD_Warning("ComputeVD() - problems with input data occurred!");
}
if (desperate) {
VD_Warning("ComputeVD() - VD computed; desperate mode was used!");
}
else if (troubles) {
VD_Warning("ComputeVD() - VD computed; problems occurred!?");
}
else if (numerical) {
VD_Warning("ComputeVD() - VD computed; numerical instabilities!?");
}
else {
VD_Info("\nComputeVD() - VD computed successfully!\n");
}
printf("\n");
}
#endif
}
*finished = true;
initialized = false;
return;
}