mirror of
https://github.com/Dark98/SliceBeam.git
synced 2026-07-07 08:49:06 +00:00
Public source code release
This commit is contained in:
@@ -0,0 +1,290 @@
|
||||
# Simple gcc Makefile for reentrant qhull and rbox (default gcc/g++)
|
||||
#
|
||||
# make help
|
||||
# See README.txt and ../../Makefile
|
||||
#
|
||||
# Variables
|
||||
# DESTDIR directory for staged installs (GNU Makefile standards)
|
||||
# PREFIX install directory for 'make install' (default /usr/local)
|
||||
# BINDIR directory where to copy executables
|
||||
# DOCDIR directory where to copy html documentation
|
||||
# INCDIR directory where to copy headers
|
||||
# LIBDIR directory where to copy libraries
|
||||
# MANDIR directory where to copy manual pages
|
||||
# PCDIR directory where to copy pkg-config files
|
||||
# PRINTMAN command for printing manual pages
|
||||
# PRINTC command for printing C files
|
||||
# CC ANSI C or C++ compiler
|
||||
# CC_OPTS1 options used to compile .c files
|
||||
# CC_OPTS2 options used to link .o files
|
||||
# CC_OPTS3 options to build shared libraries
|
||||
#
|
||||
# LIBQHULL_OBJS .o files for linking
|
||||
# LIBQHULL_HDRS .h files for printing
|
||||
# CFILES .c files for printing
|
||||
# DOCFILES documentation files
|
||||
# FILES miscellaneous files for printing
|
||||
# TFILES .txt versions of html files
|
||||
# FILES all other files
|
||||
# LIBQHULL_OBJS specifies the object files of libqhullstatic_r.a
|
||||
#
|
||||
# Results
|
||||
# rbox Generates points sets for qhull, qconvex, etc.
|
||||
# qhull Computes convex hulls and related structures
|
||||
# qconvex, qdelaunay, qhalf, qvoronoi
|
||||
# Specializations of qhull for each geometric structure
|
||||
# libqhullstatic_r.a Static library for reentrant qhull
|
||||
# testqset_r Standalone test of reentrant qset_r.c with mem_r.c
|
||||
# user_eg An example of using qhull (reentrant)
|
||||
# user_eg2 An example of using qhull (reentrant)
|
||||
#
|
||||
# Make targets
|
||||
# make Build results using gcc or another compiler
|
||||
# make all
|
||||
# make clean Remove object files
|
||||
# make cleanall Remove generated files
|
||||
# make doc Print documentation
|
||||
# make help
|
||||
# make install Copy results and documentation to BINDIR, DOCDIR, INCDIR, LIBDIR, MANDIR, PCDOC
|
||||
# make uninstall Delete Qhull files from BINDIR, DOCDIR, INCDIR, LIBDIR, MANDIR, PCDOC
|
||||
# make new Rebuild qhull and rbox from source
|
||||
# make printall Print all files
|
||||
# make qtest Quick test of qset, rbox, and qhull
|
||||
# make test Quck test of qhull, qconvex, etc.
|
||||
#
|
||||
# $Id: //main/2019/qhull/src/libqhull_r/Makefile#13 $
|
||||
|
||||
# Do not replace tabs with spaces. Needed for build rules
|
||||
# Unix line endings (\n)
|
||||
|
||||
PREFIX ?= /usr/local
|
||||
BINDIR ?= bin
|
||||
INCDIR ?= include
|
||||
LIBDIR ?= lib
|
||||
DOCDIR ?= share/doc/qhull
|
||||
MANDIR ?= share/man/man1
|
||||
PCDIR ?= $(LIBDIR)/pkgconfig
|
||||
|
||||
ABS_BINDIR = $(DESTDIR)$(PREFIX)/$(BINDIR)
|
||||
ABS_INCDIR = $(DESTDIR)$(PREFIX)/$(INCDIR)
|
||||
ABS_LIBDIR = $(DESTDIR)$(PREFIX)/$(LIBDIR)
|
||||
ABS_DOCDIR = $(DESTDIR)$(PREFIX)/$(DOCDIR)
|
||||
ABS_MANDIR = $(DESTDIR)$(PREFIX)/$(MANDIR)
|
||||
ABS_PCDIR = $(DESTDIR)$(PREFIX)/$(PCDIR)
|
||||
|
||||
qhull_VERSION=$(shell grep 'set.qhull_VERSION ' ../../CMakeLists.txt | grep -o '[0-9.]\+' || echo 0unknown)
|
||||
|
||||
# if you do not have enscript, try a2ps or just use lpr. The files are text.
|
||||
PRINTMAN = enscript -2rl
|
||||
PRINTC = enscript -2r
|
||||
# PRINTMAN = lpr
|
||||
# PRINTC = lpr
|
||||
|
||||
#for Gnu's gcc compiler, -O3 for optimization, -g for debugging, -pg for profiling
|
||||
# caller may define CC_WARNINGS
|
||||
# Qhull uses less memory for 32-bit builds on 64-bit hosts
|
||||
# Enable 32-bit builds with 'make M32=-m32'
|
||||
# M32 = -m32
|
||||
# -fpic is required for linking to shared libraries
|
||||
# -fpic may be slower for 32-bit builds on 64-bit hosts
|
||||
# Disable -fpic with 'make FPIC='
|
||||
FPIC = -fpic
|
||||
CC = gcc
|
||||
CC_OPTS1 = -O3 -ansi -I../../src $(CC_WARNINGS) $(M32) $(FPIC)
|
||||
|
||||
# for Sun's cc compiler, -fast or O2 for optimization, -g for debugging, -Xc for ANSI
|
||||
#CC = cc
|
||||
#CC_OPTS1 = -Xc -v -fast -I../../src
|
||||
|
||||
# for Silicon Graphics cc compiler, -O2 for optimization, -g for debugging
|
||||
#CC = cc
|
||||
#CC_OPTS1 = -ansi -O2 -I../../src
|
||||
|
||||
# for Next cc compiler with fat executable
|
||||
#CC = cc
|
||||
#CC_OPTS1 = -ansi -O2 -I../../src -arch m68k -arch i386 -arch hppa
|
||||
|
||||
# For loader, ld,
|
||||
CC_OPTS2 = $(CC_OPTS1)
|
||||
|
||||
# Default targets for make
|
||||
|
||||
all: qhull_links qhull_all qtest
|
||||
|
||||
help:
|
||||
head -n 54 Makefile
|
||||
|
||||
clean:
|
||||
rm -f *.o
|
||||
# Delete linked files from other directories [qhull_links]
|
||||
rm -f qconvex_r.c unix_r.c qdelaun_r.c qhalf_r.c qvoronoi_r.c rbox_r.c
|
||||
rm -f user_eg_r.c user_eg2_r.c testqset_r.c
|
||||
|
||||
cleanall: clean
|
||||
rm -f qconvex qdelaunay qhalf qvoronoi qhull *.exe
|
||||
rm -f core user_eg_r user_eg2_r testqset_r libqhullstatic_r.a
|
||||
|
||||
doc:
|
||||
$(PRINTMAN) $(TXTFILES) $(DOCFILES)
|
||||
|
||||
install:
|
||||
mkdir -p $(ABS_BINDIR)
|
||||
mkdir -p $(ABS_DOCDIR)
|
||||
mkdir -p $(ABS_DOCDIR)/src
|
||||
mkdir -p $(ABS_INCDIR)/libqhull_r
|
||||
mkdir -p $(ABS_LIBDIR)
|
||||
mkdir -p $(ABS_MANDIR)
|
||||
mkdir -p $(ABS_PCDIR)
|
||||
cp -p qconvex qdelaunay qhalf qhull qvoronoi rbox $(ABS_BINDIR)
|
||||
cp -p libqhullstatic_r.a $(ABS_LIBDIR)
|
||||
(cd ../.. && cp -p README.txt REGISTER.txt Announce.txt COPYING.txt index.htm $(ABS_DOCDIR)/)
|
||||
(cd ../.. && cp -pr html $(ABS_DOCDIR)/)
|
||||
(cd ../.. && cp -p src/Changes.txt $(ABS_DOCDIR)/src/)
|
||||
cp -p ../../html/qhull.man $(ABS_MANDIR)/qhull.1
|
||||
cp -p ../../html/rbox.man $(ABS_MANDIR)/rbox.1
|
||||
cp *.h $(ABS_INCDIR)/libqhull_r
|
||||
sed \
|
||||
-e 's#@qhull_VERSION@#$(qhull_VERSION)#' \
|
||||
-e 's#@CMAKE_INSTALL_PREFIX@#$(PREFIX)#' \
|
||||
-e 's#@LIB_INSTALL_DIR@#$(LIBDIR)#' \
|
||||
-e 's#@INCLUDE_INSTALL_DIR@#$(INCDIR)#' \
|
||||
-e 's#@LIBRARY_NAME@#qhullstatic_r#' \
|
||||
-e 's#@LIBRARY_DESCRIPTION@#Qhull reentrant static library#' \
|
||||
../../build/qhull.pc.in > $(ABS_PCDIR)/qhullstatic_r.pc
|
||||
|
||||
uninstall:
|
||||
-(cd $(ABS_BINDIR) && rm -f qconvex qdelaunay qhalf qhull qvoronoi rbox)
|
||||
-(cd $(ABS_BINDIR) && rm -f qconvex.exe qdelaunay.exe qhalf.exe qhull.exe qvoronoi.exe rbox.exe)
|
||||
-(cd $(ABS_MANDIR) && rm -f qhull.1 rbox.1)
|
||||
-(cd $(ABS_DOCDIR) && rm -f README.txt REGISTER.txt Announce.txt COPYING.txt index.htm src/Changes.txt)
|
||||
-(cd $(ABS_DOCDIR) && rm -rf html)
|
||||
-(cd $(ABS_LIBDIR) && rm -f libqhullstatic_r.a)
|
||||
-(cd $(ABS_INCDIR) && rm -rf libqhull_r)
|
||||
-(cd $(ABS_PCDIR) && rm -f qhullstatic_r.pc)
|
||||
-rmdir $(ABS_DOCDIR)/src
|
||||
-rmdir $(ABS_DOCDIR)
|
||||
|
||||
new: cleanall all
|
||||
|
||||
printall: doc printh printc printf
|
||||
|
||||
printh:
|
||||
$(PRINTC) $(LIBQHULL_HDRS)
|
||||
|
||||
printc:
|
||||
$(PRINTC) $(CFILES)
|
||||
|
||||
# LIBQHULL_OBJS_1 ordered by frequency of execution with small files at end. Better locality.
|
||||
# Same definitions as ../../Makefile
|
||||
|
||||
LIBQHULLS_OBJS_1= global_r.o stat_r.o geom2_r.o poly2_r.o merge_r.o \
|
||||
libqhull_r.o geom_r.o poly_r.o qset_r.o mem_r.o random_r.o
|
||||
|
||||
LIBQHULLS_OBJS_2= $(LIBQHULLS_OBJS_1) usermem_r.o userprintf_r.o io_r.o user_r.o
|
||||
|
||||
LIBQHULLS_OBJS= $(LIBQHULLS_OBJS_2) rboxlib_r.o userprintf_rbox_r.o
|
||||
|
||||
LIBQHULL_HDRS= user_r.h libqhull_r.h qhull_ra.h geom_r.h \
|
||||
io_r.h mem_r.h merge_r.h poly_r.h random_r.h \
|
||||
qset_r.h stat_r.h
|
||||
|
||||
# CFILES for 'printc', ordered alphabetically after libqhull_r.c
|
||||
CFILES= ../qhull/unix_r.c libqhull_r.c geom_r.c geom2_r.c global_r.c io_r.c \
|
||||
mem_r.c merge_r.c poly_r.c poly2_r.c random_r.c rboxlib_r.c \
|
||||
qset_r.c stat_r.c user_r.c usermem_r.c userprintf_r.c \
|
||||
../qconvex/qconvex_r.c ../qdelaunay/qdelaun_r.c \
|
||||
../qhalf/qhalf_r.c ../qvoronoi/qvoronoi_r.c
|
||||
|
||||
TXTFILES= ../../Announce.txt ../../REGISTER.txt ../../COPYING.txt ../../README.txt ../Changes.txt
|
||||
DOCFILES= ../../html/rbox.txt ../../html/qhull.txt
|
||||
|
||||
.c.o:
|
||||
$(CC) -c $(CC_OPTS1) -o $@ $<
|
||||
|
||||
# Work around problems with ../ in Red Hat Linux
|
||||
qhull_links:
|
||||
# On MINSYS, 'ln -s' may create a copy instead of a symbolic link
|
||||
[ -f qconvex_r.c ] || ln -s ../qconvex/qconvex_r.c
|
||||
[ -f qdelaun_r.c ] || ln -s ../qdelaunay/qdelaun_r.c
|
||||
[ -f qhalf_r.c ] || ln -s ../qhalf/qhalf_r.c
|
||||
[ -f qvoronoi_r.c ] || ln -s ../qvoronoi/qvoronoi_r.c
|
||||
[ -f rbox_r.c ] || ln -s ../rbox/rbox_r.c
|
||||
[ -f testqset_r.c ] || ln -s ../testqset_r/testqset_r.c
|
||||
[ -f unix_r.c ] || ln -s ../qhull/unix_r.c
|
||||
[ -f user_eg_r.c ] || ln -s ../user_eg/user_eg_r.c
|
||||
[ -f user_eg2_r.c ] || ln -s ../user_eg2/user_eg2_r.c
|
||||
# user_eg3_r.c not compiled. It requires all of libqhullcpp; use qhull/Makefile instead
|
||||
|
||||
# compile qhull without using bin/libqhullstatic_r.a
|
||||
qhull_all: qconvex_r.o qdelaun_r.o qhalf_r.o qvoronoi_r.o unix_r.o user_eg_r.o user_eg2_r.o rbox_r.o testqset_r.o $(LIBQHULLS_OBJS)
|
||||
$(CC) -o qconvex $(CC_OPTS2) $(LIBQHULLS_OBJS_2) qconvex_r.o -lm
|
||||
$(CC) -o qdelaunay $(CC_OPTS2) $(LIBQHULLS_OBJS_2) qdelaun_r.o -lm
|
||||
$(CC) -o qhalf $(CC_OPTS2) $(LIBQHULLS_OBJS_2) qhalf_r.o -lm
|
||||
$(CC) -o qvoronoi $(CC_OPTS2) $(LIBQHULLS_OBJS_2) qvoronoi_r.o -lm
|
||||
$(CC) -o qhull $(CC_OPTS2) $(LIBQHULLS_OBJS_2) unix_r.o -lm
|
||||
$(CC) -o rbox $(CC_OPTS2) $(LIBQHULLS_OBJS) rbox_r.o -lm
|
||||
$(CC) -o user_eg $(CC_OPTS2) $(LIBQHULLS_OBJS_2) user_eg_r.o -lm
|
||||
$(CC) -o user_eg2 $(CC_OPTS2) $(LIBQHULLS_OBJS_1) user_eg2_r.o usermem_r.o userprintf_r.o io_r.o -lm
|
||||
$(CC) -o testqset_r $(CC_OPTS2) mem_r.o qset_r.o usermem_r.o testqset_r.o -lm
|
||||
-ar -rs libqhullstatic_r.a $(LIBQHULLS_OBJS)
|
||||
#libqhullstatic_r.a is not needed for qhull
|
||||
#If 'ar -rs' fails try using 'ar -s' with 'ranlib'
|
||||
#ranlib libqhullstatic_r.a
|
||||
|
||||
qtest:
|
||||
@echo ============================================
|
||||
@echo == make qtest ==============================
|
||||
@echo ============================================
|
||||
@echo -n "== "
|
||||
@date
|
||||
@echo
|
||||
@echo Testing qset_r.c and mem_r.c with testqset_r
|
||||
./testqset_r 10000
|
||||
@echo Run the qhull smoketest
|
||||
./rbox D4 | ./qhull
|
||||
@echo ============================================
|
||||
@echo == To smoketest qhull programs
|
||||
@echo '== make test'
|
||||
@echo ============================================
|
||||
@echo
|
||||
@echo ============================================
|
||||
@echo == To install qhull or show help
|
||||
@echo '== make help'
|
||||
@echo '== make install'
|
||||
@echo ============================================
|
||||
@echo
|
||||
|
||||
test: qtest
|
||||
@echo ==============================
|
||||
@echo ========= qconvex ============
|
||||
@echo ==============================
|
||||
-./rbox 10 | ./qconvex Tv
|
||||
@echo
|
||||
@echo ==============================
|
||||
@echo ========= qdelaunay ==========
|
||||
@echo ==============================
|
||||
-./rbox 10 | ./qdelaunay Tv
|
||||
@echo
|
||||
@echo ==============================
|
||||
@echo ========= qhalf ==============
|
||||
@echo ==============================
|
||||
-./rbox 10 | ./qconvex FQ FV n Tv | ./qhalf Tv
|
||||
@echo
|
||||
@echo ==============================
|
||||
@echo ========= qvoronoi ===========
|
||||
@echo ==============================
|
||||
-./rbox 10 | ./qvoronoi Tv
|
||||
@echo
|
||||
@echo ==============================
|
||||
@echo ========= user_eg ============
|
||||
@echo == w/o shared library ========
|
||||
@echo ==============================
|
||||
-./user_eg
|
||||
@echo
|
||||
@echo ==============================
|
||||
@echo ========= user_eg2 ===========
|
||||
@echo ==============================
|
||||
-./user_eg2
|
||||
@echo
|
||||
|
||||
# end of Makefile
|
||||
@@ -0,0 +1,69 @@
|
||||
#include <stdlib.h>
|
||||
#include "libqhull_r.h"
|
||||
|
||||
qhT *qh_alloc_qh(FILE *errfile) {
|
||||
qhT *qh = (qhT*) qh_malloc(sizeof(qhT));
|
||||
QHULL_LIB_CHECK
|
||||
if (qh) qh_zero(qh, errfile);
|
||||
return qh;
|
||||
}
|
||||
|
||||
/* Free the qhT pointer.
|
||||
|
||||
Note: qh_freeqhull and qh_memfreeshort should be called before calling qh_free_qh. */
|
||||
void qh_free_qh(qhT *qh) {
|
||||
qh_free(qh);
|
||||
}
|
||||
|
||||
#define GETTER(TYPE, FIELD) TYPE qh_get_##FIELD(const qhT *qh) { return qh->FIELD; }
|
||||
#define SETTER(TYPE, FIELD) void qh_set_##FIELD(qhT *qh, TYPE _val_) { qh->FIELD = _val_; }
|
||||
|
||||
/* required to emulate the various FOR* macros */
|
||||
GETTER(facetT*, facet_list)
|
||||
GETTER(pointT*, first_point)
|
||||
GETTER(int, hull_dim)
|
||||
GETTER(int, num_facets)
|
||||
GETTER(int, num_points)
|
||||
GETTER(int, num_vertices)
|
||||
GETTER(vertexT*, vertex_list)
|
||||
|
||||
/* suggested by @blegat based on Qhull.jl wrappers */
|
||||
GETTER(realT, totarea)
|
||||
GETTER(realT, totvol)
|
||||
GETTER(boolT, hasAreaVolume)
|
||||
SETTER(boolT, hasAreaVolume)
|
||||
GETTER(boolT, hasTriangulation)
|
||||
SETTER(boolT, hasTriangulation)
|
||||
|
||||
/* suggested by @JuhaHeiskala based on his DirectQHull.jl wrapper */
|
||||
GETTER(int, num_good)
|
||||
GETTER(setT*, del_vertices)
|
||||
GETTER(int, input_dim)
|
||||
|
||||
/* other accessors, mimicking those provided by the scipy API: */
|
||||
GETTER(boolT, DELAUNAY)
|
||||
GETTER(boolT, SCALElast)
|
||||
GETTER(boolT, KEEPcoplanar)
|
||||
GETTER(boolT, MERGEexact)
|
||||
GETTER(boolT, NOerrexit)
|
||||
GETTER(boolT, PROJECTdelaunay)
|
||||
GETTER(boolT, ATinfinity)
|
||||
GETTER(boolT, UPPERdelaunay)
|
||||
GETTER(int, normal_size)
|
||||
GETTER(int, num_visible)
|
||||
GETTER(int, center_size)
|
||||
GETTER(const char *, qhull_command)
|
||||
GETTER(facetT*, facet_tail)
|
||||
GETTER(vertexT*, vertex_tail)
|
||||
GETTER(unsigned int, facet_id)
|
||||
GETTER(unsigned int, visit_id)
|
||||
GETTER(unsigned int, vertex_visit)
|
||||
GETTER(pointT*, input_points)
|
||||
GETTER(coordT*, feasible_point)
|
||||
GETTER(realT, last_low)
|
||||
GETTER(realT, last_high)
|
||||
GETTER(realT, last_newhigh)
|
||||
GETTER(realT, max_outside)
|
||||
GETTER(realT, MINoutside)
|
||||
GETTER(realT, DISTround)
|
||||
GETTER(setT*, other_points)
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,189 @@
|
||||
/*<html><pre> -<a href="qh-geom_r.htm"
|
||||
>-------------------------------</a><a name="TOP">-</a>
|
||||
|
||||
geom_r.h
|
||||
header file for geometric routines
|
||||
|
||||
see qh-geom_r.htm and geom_r.c
|
||||
|
||||
Copyright (c) 1993-2020 The Geometry Center.
|
||||
$Id: //main/2019/qhull/src/libqhull_r/geom_r.h#2 $$Change: 2953 $
|
||||
$DateTime: 2020/05/21 22:05:32 $$Author: bbarber $
|
||||
*/
|
||||
|
||||
#ifndef qhDEFgeom
|
||||
#define qhDEFgeom 1
|
||||
|
||||
#include "libqhull_r.h"
|
||||
|
||||
/* ============ -macros- ======================== */
|
||||
|
||||
/*-<a href="qh-geom_r.htm#TOC"
|
||||
>--------------------------------</a><a name="fabs_">-</a>
|
||||
|
||||
fabs_(a)
|
||||
returns the absolute value of a
|
||||
*/
|
||||
#define fabs_( a ) ((( a ) < 0 ) ? -( a ):( a ))
|
||||
|
||||
/*-<a href="qh-geom_r.htm#TOC"
|
||||
>--------------------------------</a><a name="fmax_">-</a>
|
||||
|
||||
fmax_(a,b)
|
||||
returns the maximum value of a and b
|
||||
*/
|
||||
#define fmax_( a,b ) ( ( a ) < ( b ) ? ( b ) : ( a ) )
|
||||
|
||||
/*-<a href="qh-geom_r.htm#TOC"
|
||||
>--------------------------------</a><a name="fmin_">-</a>
|
||||
|
||||
fmin_(a,b)
|
||||
returns the minimum value of a and b
|
||||
*/
|
||||
#define fmin_( a,b ) ( ( a ) > ( b ) ? ( b ) : ( a ) )
|
||||
|
||||
/*-<a href="qh-geom_r.htm#TOC"
|
||||
>--------------------------------</a><a name="maximize_">-</a>
|
||||
|
||||
maximize_(maxval, val)
|
||||
set maxval to val if val is greater than maxval
|
||||
*/
|
||||
#define maximize_( maxval, val ) { if (( maxval ) < ( val )) ( maxval )= ( val ); }
|
||||
|
||||
/*-<a href="qh-geom_r.htm#TOC"
|
||||
>--------------------------------</a><a name="minimize_">-</a>
|
||||
|
||||
minimize_(minval, val)
|
||||
set minval to val if val is less than minval
|
||||
*/
|
||||
#define minimize_( minval, val ) { if (( minval ) > ( val )) ( minval )= ( val ); }
|
||||
|
||||
/*-<a href="qh-geom_r.htm#TOC"
|
||||
>--------------------------------</a><a name="det2_">-</a>
|
||||
|
||||
det2_(a1, a2,
|
||||
b1, b2)
|
||||
|
||||
compute a 2-d determinate
|
||||
*/
|
||||
#define det2_( a1,a2,b1,b2 ) (( a1 )*( b2 ) - ( a2 )*( b1 ))
|
||||
|
||||
/*-<a href="qh-geom_r.htm#TOC"
|
||||
>--------------------------------</a><a name="det3_">-</a>
|
||||
|
||||
det3_(a1, a2, a3,
|
||||
b1, b2, b3,
|
||||
c1, c2, c3)
|
||||
|
||||
compute a 3-d determinate
|
||||
*/
|
||||
#define det3_( a1,a2,a3,b1,b2,b3,c1,c2,c3 ) ( ( a1 )*det2_( b2,b3,c2,c3 ) \
|
||||
- ( b1 )*det2_( a2,a3,c2,c3 ) + ( c1 )*det2_( a2,a3,b2,b3 ) )
|
||||
|
||||
/*-<a href="qh-geom_r.htm#TOC"
|
||||
>--------------------------------</a><a name="dX">-</a>
|
||||
|
||||
dX( p1, p2 )
|
||||
dY( p1, p2 )
|
||||
dZ( p1, p2 )
|
||||
|
||||
given two indices into rows[],
|
||||
|
||||
compute the difference between X, Y, or Z coordinates
|
||||
*/
|
||||
#define dX( p1,p2 ) ( *( rows[p1] ) - *( rows[p2] ))
|
||||
#define dY( p1,p2 ) ( *( rows[p1]+1 ) - *( rows[p2]+1 ))
|
||||
#define dZ( p1,p2 ) ( *( rows[p1]+2 ) - *( rows[p2]+2 ))
|
||||
#define dW( p1,p2 ) ( *( rows[p1]+3 ) - *( rows[p2]+3 ))
|
||||
|
||||
/*============= prototypes in alphabetical order, infrequent at end ======= */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void qh_backnormal(qhT *qh, realT **rows, int numrow, int numcol, boolT sign, coordT *normal, boolT *nearzero);
|
||||
void qh_distplane(qhT *qh, pointT *point, facetT *facet, realT *dist);
|
||||
facetT *qh_findbest(qhT *qh, pointT *point, facetT *startfacet,
|
||||
boolT bestoutside, boolT isnewfacets, boolT noupper,
|
||||
realT *dist, boolT *isoutside, int *numpart);
|
||||
facetT *qh_findbesthorizon(qhT *qh, boolT ischeckmax, pointT *point,
|
||||
facetT *startfacet, boolT noupper, realT *bestdist, int *numpart);
|
||||
facetT *qh_findbestnew(qhT *qh, pointT *point, facetT *startfacet, realT *dist,
|
||||
boolT bestoutside, boolT *isoutside, int *numpart);
|
||||
void qh_gausselim(qhT *qh, realT **rows, int numrow, int numcol, boolT *sign, boolT *nearzero);
|
||||
realT qh_getangle(qhT *qh, pointT *vect1, pointT *vect2);
|
||||
pointT *qh_getcenter(qhT *qh, setT *vertices);
|
||||
pointT *qh_getcentrum(qhT *qh, facetT *facet);
|
||||
coordT qh_getdistance(qhT *qh, facetT *facet, facetT *neighbor, coordT *mindist, coordT *maxdist);
|
||||
void qh_normalize(qhT *qh, coordT *normal, int dim, boolT toporient);
|
||||
void qh_normalize2(qhT *qh, coordT *normal, int dim, boolT toporient,
|
||||
realT *minnorm, boolT *ismin);
|
||||
pointT *qh_projectpoint(qhT *qh, pointT *point, facetT *facet, realT dist);
|
||||
|
||||
void qh_setfacetplane(qhT *qh, facetT *newfacets);
|
||||
void qh_sethyperplane_det(qhT *qh, int dim, coordT **rows, coordT *point0,
|
||||
boolT toporient, coordT *normal, realT *offset, boolT *nearzero);
|
||||
void qh_sethyperplane_gauss(qhT *qh, int dim, coordT **rows, pointT *point0,
|
||||
boolT toporient, coordT *normal, coordT *offset, boolT *nearzero);
|
||||
boolT qh_sharpnewfacets(qhT *qh);
|
||||
|
||||
/*========= infrequently used code in geom2_r.c =============*/
|
||||
|
||||
coordT *qh_copypoints(qhT *qh, coordT *points, int numpoints, int dimension);
|
||||
void qh_crossproduct(int dim, realT vecA[3], realT vecB[3], realT vecC[3]);
|
||||
realT qh_determinant(qhT *qh, realT **rows, int dim, boolT *nearzero);
|
||||
realT qh_detjoggle(qhT *qh, pointT *points, int numpoints, int dimension);
|
||||
void qh_detmaxoutside(qhT *qh);
|
||||
void qh_detroundoff(qhT *qh);
|
||||
realT qh_detsimplex(qhT *qh, pointT *apex, setT *points, int dim, boolT *nearzero);
|
||||
realT qh_distnorm(int dim, pointT *point, pointT *normal, realT *offsetp);
|
||||
realT qh_distround(qhT *qh, int dimension, realT maxabs, realT maxsumabs);
|
||||
realT qh_divzero(realT numer, realT denom, realT mindenom1, boolT *zerodiv);
|
||||
realT qh_facetarea(qhT *qh, facetT *facet);
|
||||
realT qh_facetarea_simplex(qhT *qh, int dim, coordT *apex, setT *vertices,
|
||||
vertexT *notvertex, boolT toporient, coordT *normal, realT *offset);
|
||||
pointT *qh_facetcenter(qhT *qh, setT *vertices);
|
||||
facetT *qh_findgooddist(qhT *qh, pointT *point, facetT *facetA, realT *distp, facetT **facetlist);
|
||||
vertexT *qh_furthestnewvertex(qhT *qh, unsigned int unvisited, facetT *facet, realT *maxdistp /* qh.newvertex_list */);
|
||||
vertexT *qh_furthestvertex(qhT *qh, facetT *facetA, facetT *facetB, realT *maxdistp, realT *mindistp);
|
||||
void qh_getarea(qhT *qh, facetT *facetlist);
|
||||
boolT qh_gram_schmidt(qhT *qh, int dim, realT **rows);
|
||||
boolT qh_inthresholds(qhT *qh, coordT *normal, realT *angle);
|
||||
void qh_joggleinput(qhT *qh);
|
||||
realT *qh_maxabsval(realT *normal, int dim);
|
||||
setT *qh_maxmin(qhT *qh, pointT *points, int numpoints, int dimension);
|
||||
realT qh_maxouter(qhT *qh);
|
||||
void qh_maxsimplex(qhT *qh, int dim, setT *maxpoints, pointT *points, int numpoints, setT **simplex);
|
||||
realT qh_minabsval(realT *normal, int dim);
|
||||
int qh_mindiff(realT *vecA, realT *vecB, int dim);
|
||||
boolT qh_orientoutside(qhT *qh, facetT *facet);
|
||||
void qh_outerinner(qhT *qh, facetT *facet, realT *outerplane, realT *innerplane);
|
||||
coordT qh_pointdist(pointT *point1, pointT *point2, int dim);
|
||||
void qh_printmatrix(qhT *qh, FILE *fp, const char *string, realT **rows, int numrow, int numcol);
|
||||
void qh_printpoints(qhT *qh, FILE *fp, const char *string, setT *points);
|
||||
void qh_projectinput(qhT *qh);
|
||||
void qh_projectpoints(qhT *qh, signed char *project, int n, realT *points,
|
||||
int numpoints, int dim, realT *newpoints, int newdim);
|
||||
void qh_rotateinput(qhT *qh, realT **rows);
|
||||
void qh_rotatepoints(qhT *qh, realT *points, int numpoints, int dim, realT **rows);
|
||||
void qh_scaleinput(qhT *qh);
|
||||
void qh_scalelast(qhT *qh, coordT *points, int numpoints, int dim, coordT low,
|
||||
coordT high, coordT newhigh);
|
||||
void qh_scalepoints(qhT *qh, pointT *points, int numpoints, int dim,
|
||||
realT *newlows, realT *newhighs);
|
||||
boolT qh_sethalfspace(qhT *qh, int dim, coordT *coords, coordT **nextp,
|
||||
coordT *normal, coordT *offset, coordT *feasible);
|
||||
coordT *qh_sethalfspace_all(qhT *qh, int dim, int count, coordT *halfspaces, pointT *feasible);
|
||||
coordT qh_vertex_bestdist(qhT *qh, setT *vertices);
|
||||
coordT qh_vertex_bestdist2(qhT *qh, setT *vertices, vertexT **vertexp, vertexT **vertexp2);
|
||||
pointT *qh_voronoi_center(qhT *qh, int dim, setT *points);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /* qhDEFgeom */
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,269 @@
|
||||
<!-- Do not edit with Front Page, it adds too many spaces -->
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type"
|
||||
content="text/html; charset=iso-8859-1">
|
||||
<title>Reentrant Qhull functions, macros, and data structures</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- Navigation links -->
|
||||
<p><a name="TOP"><b>Up:</b></a> <a
|
||||
href="http://www.qhull.org">Home page</a> for Qhull (<a href="../index.htm">local</a>)<br>
|
||||
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: contents <br>
|
||||
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
|
||||
• <a href="../../html/qh-quick.htm#options">Options</a>
|
||||
• <a href="../../html/qh-opto.htm#output">Output</a>
|
||||
• <a href="../../html/qh-optf.htm#format">Formats</a>
|
||||
• <a href="../../html/qh-optg.htm#geomview">Geomview</a>
|
||||
• <a href="../../html/qh-optp.htm#print">Print</a>
|
||||
• <a href="../../html/qh-optq.htm#qhull">Qhull</a>
|
||||
• <a href="../../html/qh-optc.htm#prec">Precision</a>
|
||||
• <a href="../../html/qh-optt.htm#trace">Trace</a>
|
||||
• <a href="http://www.qhull.org/src/libqhull_r/index.htm">Functions</a> (<a href="index.htm">local</a>)<br>
|
||||
<b>Up:</b> <a href="../../html/qh-code.htm">Qhull code</a><br>
|
||||
<b>To:</b> <a href="#TOC">Qhull files</a><br>
|
||||
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> • <a href="qh-globa_r.htm">Global</a>
|
||||
• <a href="qh-io_r.htm">Io</a> • <a href="qh-mem_r.htm">Mem</a>
|
||||
• <a href="qh-merge_r.htm">Merge</a> • <a href="qh-poly_r.htm">Poly</a>
|
||||
• <a href="qh-qhull_r.htm">Qhull</a> • <a href="qh-set_r.htm">Set</a>
|
||||
• <a href="qh-stat_r.htm">Stat</a> • <a href="qh-user_r.htm">User</a>
|
||||
|
||||
<hr>
|
||||
<!-- Main text of document. -->
|
||||
|
||||
<h1>Reentrant Qhull functions, macros, and data structures</h1>
|
||||
<blockquote>
|
||||
<p>The following sections provide an overview and index to
|
||||
reentrant Qhull's functions, macros, and data structures.
|
||||
Each section starts with an introduction.
|
||||
See also <a href=../../html/qh-code.htm#library>Calling
|
||||
Qhull from C programs</a> and <a href="../../html/qh-code.htm#cpp">Calling Qhull from C++ programs</a>.</p>
|
||||
|
||||
<p>Qhull uses the following conventions:</p>
|
||||
<blockquote>
|
||||
|
||||
<ul>
|
||||
<li>in code, global variables start with "qh "
|
||||
<li>in documentation, global variables start with 'qh.'
|
||||
<li>constants start with an upper case word
|
||||
<li>important globals include an '_'
|
||||
<li>functions, macros, and constants start with "qh_"</li>
|
||||
<li>data types end in "T"</li>
|
||||
<li>macros with arguments end in "_"</li>
|
||||
<li>iterators are macros that use local variables</li>
|
||||
<li>iterators for sets start with "FOREACH"</li>
|
||||
<li>iterators for lists start with "FORALL"</li>
|
||||
<li>qhull options are in single quotes (e.g., 'Pdn')</li>
|
||||
<li>lists are sorted alphabetically</li>
|
||||
<li>preprocessor directives on left margin for older compilers</li>
|
||||
</ul>
|
||||
</blockquote>
|
||||
<p>
|
||||
Reentrant Qhull is nearly the same as non-reentrant Qhull. In reentrant
|
||||
Qhull, the qhT data structure is the first parameter to most functions. Qhull accesses
|
||||
this data structure with 'qh->...'.
|
||||
In non-reentrant Qhull, the global data structure is either a struct (qh_QHpointer==0)
|
||||
or a pointer (qh_QHpointer==1). The non-reentrant code looks different because this data
|
||||
structure is accessed via the 'qh' macro. This macro expands to 'qh_qh.' or 'qh_qh->' (resp.).
|
||||
<p>
|
||||
When reading code with an editor, a search for
|
||||
'<i>"function</i>'
|
||||
will locate the header of <i>qh_function</i>. A search for '<i>* function</i>'
|
||||
will locate the tail of <i>qh_function</i>.
|
||||
|
||||
<p>A useful starting point is <a href="libqhull_r.h">libqhull_r.h</a>. It defines most
|
||||
of Qhull data structures and top-level functions. Search for <i>'PFn'</i> to
|
||||
determine the corresponding constant in Qhull. Search for <i>'Fp'</i> to
|
||||
determine the corresponding <a href="libqhull_r.h#qh_PRINT">qh_PRINT...</a> constant.
|
||||
Search <a href="io_r.c">io_r.c</a> to learn how the print function is implemented.</p>
|
||||
|
||||
<p>If your web browser is configured for .c and .h files, the function, macro, and data type links
|
||||
go to the corresponding source location.
|
||||
<ul>
|
||||
<li>Internet Explorer -- OK for web access but not for file access
|
||||
<li>Chrome -- OK for web access but not for file access
|
||||
<li>Firefox -- OK for web access but not for file access
|
||||
<pre>
|
||||
# .htaccess on web server with NL line endings
|
||||
AddType text/html .c .h
|
||||
</pre>
|
||||
<li>Opera 12.10
|
||||
<ol>
|
||||
<li>In Tools > Preferences > Advanced > Downloads
|
||||
<li>Uncheck 'Hide file types opened with Opera'
|
||||
<li>Quick find 'html'
|
||||
<li>Select 'text/html' > Edit
|
||||
<li>Add File extensions 'c,h,'
|
||||
<li>Click 'OK'
|
||||
</ol>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Please report documentation and link errors
|
||||
to <a href="mailto:qhull-bug@qhull.org">qhull-bug@qhull.org</a>.
|
||||
</blockquote>
|
||||
|
||||
<p><b>Copyright © 1997-2020 C.B. Barber</b></p>
|
||||
|
||||
<hr>
|
||||
|
||||
<h2><a href="#TOP">»</a><a name="TOC">Qhull files</a> </h2>
|
||||
<blockquote>
|
||||
|
||||
<p>This sections lists the .c and .h files for Qhull. Please
|
||||
refer to these files for detailed information.</p>
|
||||
<blockquote>
|
||||
|
||||
<dl>
|
||||
<dt><a href="../../Makefile"><b>Makefile</b></a><b>, </b><a href="../../CMakeLists.txt"><b>CMakeLists.txt</b></a></dt>
|
||||
<dd><tt>Makefile</tt> is preconfigured for gcc. <tt>CMakeLists.txt</tt> supports multiple
|
||||
platforms with <a href=http://www.cmake.org/>CMake</a>.
|
||||
Qhull includes project files for Visual Studio and Qt.
|
||||
</dd>
|
||||
|
||||
<dt> </dt>
|
||||
<dt><a href="libqhull_r.h"><b>libqhull_r.h</b></a> </dt>
|
||||
<dd>Include file for the Qhull library (<tt>libqhull.so</tt>, <tt>qhull.dll</tt>, <tt>libqhullstatic.a</tt>).
|
||||
Data structures are documented under <a href="qh-poly_r.htm">Poly</a>.
|
||||
Global variables are documented under <a href="qh-globa_r.htm">Global</a>.
|
||||
Other data structures and variables are documented under
|
||||
<a href="qh-qhull_r.htm#TOC">Qhull</a> or <a href="qh-geom_r.htm"><b>Geom</b></a><b>.</b></dd>
|
||||
|
||||
<dt> </dt>
|
||||
<dt><a href="qh-geom_r.htm"><b>Geom</b></a><b>, </b>
|
||||
<a href="geom_r.h"><b>geom_r.h</b></a><b>, </b>
|
||||
<a href="geom_r.c"><b>geom_r.c</b></a><b>, </b>
|
||||
<a href="geom2_r.c"><b>geom2_r.c</b></a><b>, </b>
|
||||
<a href="random_r.c"><b>random_r.c</b></a><b>, </b>
|
||||
<a href="random_r.h"><b>random_r.h</b></a></dt>
|
||||
<dd>Geometric routines. These routines implement mathematical
|
||||
functions such as Gaussian elimination and geometric
|
||||
routines needed for Qhull. Frequently used routines are
|
||||
in <tt>geom_r.c</tt> while infrequent ones are in <tt>geom2_r.c</tt>.
|
||||
</dd>
|
||||
|
||||
<dt> </dt>
|
||||
<dt><a href="qh-globa_r.htm"><b>Global</b></a><b>, </b>
|
||||
<a href="global_r.c"><b>global_r.c</b></a><b>, </b>
|
||||
<a href="libqhull_r.h"><b>libqhull_r.h</b></a> </dt>
|
||||
<dd>Global routines. Qhull uses a global data structure, <tt>qh</tt>,
|
||||
to store globally defined constants, lists, sets, and
|
||||
variables.
|
||||
<tt>global_r.c</tt> initializes and frees these
|
||||
structures. </dd>
|
||||
|
||||
<dt> </dt>
|
||||
<dt><a href="qh-io_r.htm"><b>Io</b></a><b>, </b><a href="io_r.h"><b>io_r.h</b></a><b>,
|
||||
</b><a href="io_r.c"><b>io_r.c</b></a> </dt>
|
||||
<dd>Input and output routines. Qhull provides a wide range of
|
||||
input and output options.</dd>
|
||||
|
||||
<dt> </dt>
|
||||
<dt><a href="qh-mem_r.htm"><b>Mem</b></a><b>, </b>
|
||||
<a href="mem_r.h"><b>mem_r.h</b></a><b>, </b>
|
||||
<a href="mem_r.c"><b>mem_r.c</b></a> </dt>
|
||||
<dd>Memory routines. Qhull provides memory allocation and
|
||||
deallocation. It uses quick-fit allocation.</dd>
|
||||
|
||||
<dt> </dt>
|
||||
<dt><a href="qh-merge_r.htm"><b>Merge</b></a><b>, </b>
|
||||
<a href="merge_r.h"><b>merge_r.h</b></a><b>, </b>
|
||||
<a href="merge_r.c"><b>merge_r.c</b></a> </dt>
|
||||
<dd>Merge routines. Qhull handles precision problems by
|
||||
merged facets or joggled input. These routines merge simplicial facets,
|
||||
merge non-simplicial facets, merge cycles of facets, and
|
||||
rename redundant vertices.</dd>
|
||||
|
||||
<dt> </dt>
|
||||
<dt><a href="qh-poly_r.htm"><b>Poly</b></a><b>, </b>
|
||||
<a href="poly_r.h"><b>poly_r.h</b></a><b>, </b>
|
||||
<a href="poly_r.c"><b>poly_r.c</b></a><b>, </b>
|
||||
<a href="poly2_r.c"><b>poly2_r.c</b></a><b>, </b>
|
||||
<a href="libqhull_r.h"><b>libqhull_r.h</b></a> </dt>
|
||||
<dd>Polyhedral routines. Qhull produces a polyhedron as a
|
||||
list of facets with vertices, neighbors, ridges, and
|
||||
geometric information. <tt>libqhull_r.h</tt> defines the main
|
||||
data structures. Frequently used routines are in <tt>poly_r.c</tt>
|
||||
while infrequent ones are in <tt>poly2_r.c</tt>.</dd>
|
||||
|
||||
<dt> </dt>
|
||||
<dt><a href="qh-qhull_r.htm#TOC"><b>Qhull</b></a><b>, </b>
|
||||
<a href="libqhull_r.c"><b>libqhull_r.c</b></a><b>, </b>
|
||||
<a href="libqhull_r.h"><b>libqhull_r.h</b></a><b>, </b>
|
||||
<a href="qhull_ra.h"><b>qhull_ra.h</b></a><b>, </b>
|
||||
<a href="../qhull/unix_r.c"><b>unix_r.c</b></a> <b>, </b>
|
||||
<a href="../qconvex/qconvex_r.c"><b>qconvex_r.c</b></a> <b>, </b>
|
||||
<a href="../qdelaunay/qdelaun_r.c"><b>qdelaun_r.c</b></a> <b>, </b>
|
||||
<a href="../qhalf/qhalf_r.c"><b>qhalf_r.c</b></a> <b>, </b>
|
||||
<a href="../qvoronoi/qvoronoi_r.c"><b>qvoronoi_r.c</b></a> </dt>
|
||||
<dd>Top-level routines. The Quickhull algorithm is
|
||||
implemented by <tt>libqhull_r.c</tt>. <tt>qhull_ra.h</tt>
|
||||
includes all header files. </dd>
|
||||
|
||||
<dt> </dt>
|
||||
<dt><a href="qh-set_r.htm"><b>Set</b></a><b>, </b>
|
||||
<a href="qset_r.h"><b>qset_r.h</b></a><b>, </b>
|
||||
<a href="qset_r.c"><b>qset_r.c</b></a> </dt>
|
||||
<dd>Set routines. Qhull implements its data structures as
|
||||
sets. A set is an array of pointers that is expanded as
|
||||
needed. This is a separate package that may be used in
|
||||
other applications. </dd>
|
||||
|
||||
<dt> </dt>
|
||||
<dt><a href="qh-stat_r.htm"><b>Stat</b></a><b>, </b>
|
||||
<a href="stat_r.h"><b>stat_r.h</b></a><b>, </b>
|
||||
<a href="stat_r.c"><b>stat_r.c</b></a> </dt>
|
||||
<dd>Statistical routines. Qhull maintains statistics about
|
||||
its implementation. </dd>
|
||||
|
||||
<dt> </dt>
|
||||
<dt><a href="qh-user_r.htm"><b>User</b></a><b>, </b>
|
||||
<a href="user_r.h"><b>user_r.h</b></a><b>, </b>
|
||||
<a href="user_r.c"><b>user_r.c</b></a><b>, </b>
|
||||
<a href="../user_eg/user_eg_r.c"><b>user_eg_r.c</b></a><b>, </b>
|
||||
<a href="../user_eg2/user_eg2_r.c"><b>user_eg2_r.c</b></a><b>, </b>
|
||||
<a href="../user_eg3/user_eg3_r.cpp"><b>user_eg3_r.cpp</b></a><b>, </b>
|
||||
</dt>
|
||||
<dd>User-defined routines. Qhull allows the user to configure
|
||||
the code with defined constants and specialized routines.
|
||||
</dd>
|
||||
</dl>
|
||||
</blockquote>
|
||||
|
||||
</blockquote>
|
||||
<p><!-- Navigation links --> </p>
|
||||
<hr>
|
||||
<p><b>Up:</b>
|
||||
<a href="http://www.qhull.org">Home page</a> for
|
||||
Qhull (<a href="../index.htm">local</a>) <br>
|
||||
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: contents<br>
|
||||
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
|
||||
• <a href="../../html/qh-quick.htm#options">Options</a>
|
||||
• <a href="../../html/qh-opto.htm#output">Output</a>
|
||||
• <a href="../../html/qh-optf.htm#format">Formats</a>
|
||||
• <a href="../../html/qh-optg.htm#geomview">Geomview</a>
|
||||
• <a href="../../html/qh-optp.htm#print">Print</a>
|
||||
• <a href="../../html/qh-optq.htm#qhull">Qhull</a>
|
||||
• <a href="../../html/qh-optc.htm#prec">Precision</a>
|
||||
• <a href="../../html/qh-optt.htm#trace">Trace</a>
|
||||
• <a href="http://www.qhull.org/src/libqhull_r/index.htm">Functions</a> (<a href="index.htm">local</a>)<br>
|
||||
<b>Up:</b> <a href="../../html/qh-code.htm">Qhull code</a> <br>
|
||||
<b>To:</b> <a href="#TOC">Qhull files</a><br>
|
||||
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> •
|
||||
<a href="qh-globa_r.htm">Global</a> • <a href="qh-io_r.htm">Io</a>
|
||||
• <a href="qh-mem_r.htm">Mem</a> • <a href="qh-merge_r.htm">Merge</a>
|
||||
• <a href="qh-poly_r.htm">Poly</a> • <a href="qh-qhull_r.htm#TOC">Qhull</a>
|
||||
• <a href="qh-set_r.htm">Set</a> • <a href="qh-stat_r.htm">Stat</a>
|
||||
• <a href="qh-user_r.htm">User</a><br>
|
||||
|
||||
<p><!-- GC common information --> </p>
|
||||
<hr>
|
||||
<p><a href="http://www.geom.uiuc.edu/"><img
|
||||
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
|
||||
Geometry Center Home Page </i></p>
|
||||
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
|
||||
<br>
|
||||
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,166 @@
|
||||
/*<html><pre> -<a href="qh-io_r.htm"
|
||||
>-------------------------------</a><a name="TOP">-</a>
|
||||
|
||||
io_r.h
|
||||
declarations of Input/Output functions
|
||||
|
||||
see README, libqhull_r.h and io_r.c
|
||||
|
||||
Copyright (c) 1993-2020 The Geometry Center.
|
||||
$Id: //main/2019/qhull/src/libqhull_r/io_r.h#3 $$Change: 2953 $
|
||||
$DateTime: 2020/05/21 22:05:32 $$Author: bbarber $
|
||||
*/
|
||||
|
||||
#ifndef qhDEFio
|
||||
#define qhDEFio 1
|
||||
|
||||
#include "libqhull_r.h"
|
||||
|
||||
/*============ constants and flags ==================*/
|
||||
|
||||
/*-<a href="qh-io_r.htm#TOC"
|
||||
>--------------------------------</a><a name="qh_MAXfirst">-</a>
|
||||
|
||||
qh_MAXfirst
|
||||
maximum length of first two lines of stdin
|
||||
*/
|
||||
#define qh_MAXfirst 200
|
||||
|
||||
/*-<a href="qh-io_r.htm#TOC"
|
||||
>--------------------------------</a><a name="qh_MINradius">-</a>
|
||||
|
||||
qh_MINradius
|
||||
min radius for Gp and Gv, fraction of maxcoord
|
||||
*/
|
||||
#define qh_MINradius 0.02
|
||||
|
||||
/*-<a href="qh-io_r.htm#TOC"
|
||||
>--------------------------------</a><a name="qh_GEOMepsilon">-</a>
|
||||
|
||||
qh_GEOMepsilon
|
||||
adjust outer planes for 'lines closer' and geomview roundoff.
|
||||
This prevents bleed through.
|
||||
*/
|
||||
#define qh_GEOMepsilon 2e-3
|
||||
|
||||
/*-<a href="qh-io_r.htm#TOC"
|
||||
>--------------------------------</a><a name="qh_WHITESPACE">-</a>
|
||||
|
||||
qh_WHITESPACE
|
||||
possible values of white space
|
||||
*/
|
||||
#define qh_WHITESPACE " \n\t\v\r\f"
|
||||
|
||||
|
||||
/*-<a href="qh-io_r.htm#TOC"
|
||||
>--------------------------------</a><a name="RIDGE">-</a>
|
||||
|
||||
qh_RIDGE
|
||||
to select which ridges to print in qh_eachvoronoi
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
qh_RIDGEall= 0, qh_RIDGEinner, qh_RIDGEouter
|
||||
}
|
||||
qh_RIDGE;
|
||||
|
||||
/*-<a href="qh-io_r.htm#TOC"
|
||||
>--------------------------------</a><a name="printvridgeT">-</a>
|
||||
|
||||
printvridgeT
|
||||
prints results of qh_printvdiagram
|
||||
|
||||
see:
|
||||
<a href="io_r.c#printvridge">qh_printvridge</a> for an example
|
||||
*/
|
||||
typedef void (*printvridgeT)(qhT *qh, FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded);
|
||||
|
||||
/*============== -prototypes in alphabetical order =========*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void qh_dfacet(qhT *qh, unsigned int id);
|
||||
void qh_dvertex(qhT *qh, unsigned int id);
|
||||
int qh_compare_facetarea(const void *p1, const void *p2);
|
||||
int qh_compare_facetvisit(const void *p1, const void *p2);
|
||||
int qh_compare_nummerge(const void *p1, const void *p2);
|
||||
void qh_copyfilename(qhT *qh, char *filename, int size, const char* source, int length);
|
||||
void qh_countfacets(qhT *qh, facetT *facetlist, setT *facets, boolT printall,
|
||||
int *numfacetsp, int *numsimplicialp, int *totneighborsp,
|
||||
int *numridgesp, int *numcoplanarsp, int *numnumtricoplanarsp);
|
||||
pointT *qh_detvnorm(qhT *qh, vertexT *vertex, vertexT *vertexA, setT *centers, realT *offsetp);
|
||||
setT *qh_detvridge(qhT *qh, vertexT *vertex);
|
||||
setT *qh_detvridge3(qhT *qh, vertexT *atvertex, vertexT *vertex);
|
||||
int qh_eachvoronoi(qhT *qh, FILE *fp, printvridgeT printvridge, vertexT *atvertex, boolT visitall, qh_RIDGE innerouter, boolT inorder);
|
||||
int qh_eachvoronoi_all(qhT *qh, FILE *fp, printvridgeT printvridge, boolT isUpper, qh_RIDGE innerouter, boolT inorder);
|
||||
void qh_facet2point(qhT *qh, facetT *facet, pointT **point0, pointT **point1, realT *mindist);
|
||||
setT *qh_facetvertices(qhT *qh, facetT *facetlist, setT *facets, boolT allfacets);
|
||||
void qh_geomplanes(qhT *qh, facetT *facet, realT *outerplane, realT *innerplane);
|
||||
void qh_markkeep(qhT *qh, facetT *facetlist);
|
||||
setT *qh_markvoronoi(qhT *qh, facetT *facetlist, setT *facets, boolT printall, boolT *isLowerp, int *numcentersp);
|
||||
void qh_order_vertexneighbors(qhT *qh, vertexT *vertex);
|
||||
void qh_prepare_output(qhT *qh);
|
||||
void qh_printafacet(qhT *qh, FILE *fp, qh_PRINT format, facetT *facet, boolT printall);
|
||||
void qh_printbegin(qhT *qh, FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall);
|
||||
void qh_printcenter(qhT *qh, FILE *fp, qh_PRINT format, const char *string, facetT *facet);
|
||||
void qh_printcentrum(qhT *qh, FILE *fp, facetT *facet, realT radius);
|
||||
void qh_printend(qhT *qh, FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall);
|
||||
void qh_printend4geom(qhT *qh, FILE *fp, facetT *facet, int *num, boolT printall);
|
||||
void qh_printextremes(qhT *qh, FILE *fp, facetT *facetlist, setT *facets, boolT printall);
|
||||
void qh_printextremes_2d(qhT *qh, FILE *fp, facetT *facetlist, setT *facets, boolT printall);
|
||||
void qh_printextremes_d(qhT *qh, FILE *fp, facetT *facetlist, setT *facets, boolT printall);
|
||||
void qh_printfacet(qhT *qh, FILE *fp, facetT *facet);
|
||||
void qh_printfacet2math(qhT *qh, FILE *fp, facetT *facet, qh_PRINT format, int notfirst);
|
||||
void qh_printfacet2geom(qhT *qh, FILE *fp, facetT *facet, realT color[3]);
|
||||
void qh_printfacet2geom_points(qhT *qh, FILE *fp, pointT *point1, pointT *point2,
|
||||
facetT *facet, realT offset, realT color[3]);
|
||||
void qh_printfacet3math(qhT *qh, FILE *fp, facetT *facet, qh_PRINT format, int notfirst);
|
||||
void qh_printfacet3geom_nonsimplicial(qhT *qh, FILE *fp, facetT *facet, realT color[3]);
|
||||
void qh_printfacet3geom_points(qhT *qh, FILE *fp, setT *points, facetT *facet, realT offset, realT color[3]);
|
||||
void qh_printfacet3geom_simplicial(qhT *qh, FILE *fp, facetT *facet, realT color[3]);
|
||||
void qh_printfacet3vertex(qhT *qh, FILE *fp, facetT *facet, qh_PRINT format);
|
||||
void qh_printfacet4geom_nonsimplicial(qhT *qh, FILE *fp, facetT *facet, realT color[3]);
|
||||
void qh_printfacet4geom_simplicial(qhT *qh, FILE *fp, facetT *facet, realT color[3]);
|
||||
void qh_printfacetNvertex_nonsimplicial(qhT *qh, FILE *fp, facetT *facet, int id, qh_PRINT format);
|
||||
void qh_printfacetNvertex_simplicial(qhT *qh, FILE *fp, facetT *facet, qh_PRINT format);
|
||||
void qh_printfacetheader(qhT *qh, FILE *fp, facetT *facet);
|
||||
void qh_printfacetridges(qhT *qh, FILE *fp, facetT *facet);
|
||||
void qh_printfacets(qhT *qh, FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall);
|
||||
void qh_printhyperplaneintersection(qhT *qh, FILE *fp, facetT *facet1, facetT *facet2,
|
||||
setT *vertices, realT color[3]);
|
||||
void qh_printline3geom(qhT *qh, FILE *fp, pointT *pointA, pointT *pointB, realT color[3]);
|
||||
void qh_printneighborhood(qhT *qh, FILE *fp, qh_PRINT format, facetT *facetA, facetT *facetB, boolT printall);
|
||||
void qh_printpoint(qhT *qh, FILE *fp, const char *string, pointT *point);
|
||||
void qh_printpointid(qhT *qh, FILE *fp, const char *string, int dim, pointT *point, int id);
|
||||
void qh_printpoint3(qhT *qh, FILE *fp, pointT *point);
|
||||
void qh_printpoints_out(qhT *qh, FILE *fp, facetT *facetlist, setT *facets, boolT printall);
|
||||
void qh_printpointvect(qhT *qh, FILE *fp, pointT *point, coordT *normal, pointT *center, realT radius, realT color[3]);
|
||||
void qh_printpointvect2(qhT *qh, FILE *fp, pointT *point, coordT *normal, pointT *center, realT radius);
|
||||
void qh_printridge(qhT *qh, FILE *fp, ridgeT *ridge);
|
||||
void qh_printspheres(qhT *qh, FILE *fp, setT *vertices, realT radius);
|
||||
void qh_printvdiagram(qhT *qh, FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall);
|
||||
int qh_printvdiagram2(qhT *qh, FILE *fp, printvridgeT printvridge, setT *vertices, qh_RIDGE innerouter, boolT inorder);
|
||||
void qh_printvertex(qhT *qh, FILE *fp, vertexT *vertex);
|
||||
void qh_printvertexlist(qhT *qh, FILE *fp, const char* string, facetT *facetlist,
|
||||
setT *facets, boolT printall);
|
||||
void qh_printvertices(qhT *qh, FILE *fp, const char* string, setT *vertices);
|
||||
void qh_printvneighbors(qhT *qh, FILE *fp, facetT* facetlist, setT *facets, boolT printall);
|
||||
void qh_printvoronoi(qhT *qh, FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall);
|
||||
void qh_printvnorm(qhT *qh, FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded);
|
||||
void qh_printvridge(qhT *qh, FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded);
|
||||
void qh_produce_output(qhT *qh);
|
||||
void qh_produce_output2(qhT *qh);
|
||||
void qh_projectdim3(qhT *qh, pointT *source, pointT *destination);
|
||||
int qh_readfeasible(qhT *qh, int dim, const char *curline);
|
||||
coordT *qh_readpoints(qhT *qh, int *numpoints, int *dimension, boolT *ismalloc);
|
||||
void qh_setfeasible(qhT *qh, int dim);
|
||||
boolT qh_skipfacet(qhT *qh, facetT *facet);
|
||||
char *qh_skipfilename(qhT *qh, char *filename);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* qhDEFio */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,68 @@
|
||||
# -------------------------------------------------
|
||||
# libqhull_r.pro -- Qt project for Qhull shared library
|
||||
#
|
||||
# It uses reentrant Qhull
|
||||
# -------------------------------------------------
|
||||
|
||||
include(../qhull-warn.pri)
|
||||
|
||||
DESTDIR = ../../lib
|
||||
DLLDESTDIR = ../../bin
|
||||
TEMPLATE = lib
|
||||
CONFIG += shared warn_on
|
||||
CONFIG -= qt
|
||||
|
||||
build_pass:CONFIG(debug, debug|release):{
|
||||
TARGET = qhull_rd
|
||||
OBJECTS_DIR = Debug
|
||||
}else:build_pass:CONFIG(release, debug|release):{
|
||||
TARGET = qhull_r
|
||||
OBJECTS_DIR = Release
|
||||
}
|
||||
win32-msvc* : QMAKE_LFLAGS += /INCREMENTAL:NO
|
||||
|
||||
win32-msvc* : DEF_FILE += ../../src/libqhull_r/qhull_r-exports.def
|
||||
|
||||
# Order object files by frequency of execution. Small files at end.
|
||||
# libqhull_r/libqhull_r.pro and ../qhull-libqhull-src_r.pri have the same SOURCES and HEADERS
|
||||
|
||||
SOURCES += ../libqhull_r/global_r.c
|
||||
SOURCES += ../libqhull_r/stat_r.c
|
||||
SOURCES += ../libqhull_r/geom2_r.c
|
||||
SOURCES += ../libqhull_r/poly2_r.c
|
||||
SOURCES += ../libqhull_r/merge_r.c
|
||||
SOURCES += ../libqhull_r/libqhull_r.c
|
||||
SOURCES += ../libqhull_r/geom_r.c
|
||||
SOURCES += ../libqhull_r/poly_r.c
|
||||
SOURCES += ../libqhull_r/qset_r.c
|
||||
SOURCES += ../libqhull_r/mem_r.c
|
||||
SOURCES += ../libqhull_r/random_r.c
|
||||
SOURCES += ../libqhull_r/usermem_r.c
|
||||
SOURCES += ../libqhull_r/userprintf_r.c
|
||||
SOURCES += ../libqhull_r/io_r.c
|
||||
SOURCES += ../libqhull_r/user_r.c
|
||||
SOURCES += ../libqhull_r/rboxlib_r.c
|
||||
SOURCES += ../libqhull_r/userprintf_rbox_r.c
|
||||
|
||||
HEADERS += ../libqhull_r/geom_r.h
|
||||
HEADERS += ../libqhull_r/io_r.h
|
||||
HEADERS += ../libqhull_r/libqhull_r.h
|
||||
HEADERS += ../libqhull_r/mem_r.h
|
||||
HEADERS += ../libqhull_r/merge_r.h
|
||||
HEADERS += ../libqhull_r/poly_r.h
|
||||
HEADERS += ../libqhull_r/random_r.h
|
||||
HEADERS += ../libqhull_r/qhull_ra.h
|
||||
HEADERS += ../libqhull_r/qset_r.h
|
||||
HEADERS += ../libqhull_r/stat_r.h
|
||||
HEADERS += ../libqhull_r/user_r.h
|
||||
|
||||
OTHER_FILES += qh-geom_r.htm
|
||||
OTHER_FILES += qh-globa_r.htm
|
||||
OTHER_FILES += qh-io_r.htm
|
||||
OTHER_FILES += qh-mem_r.htm
|
||||
OTHER_FILES += qh-merge_r.htm
|
||||
OTHER_FILES += qh-poly_r.htm
|
||||
OTHER_FILES += qh-qhull_r.htm
|
||||
OTHER_FILES += qh-set_r.htm
|
||||
OTHER_FILES += qh-stat_r.htm
|
||||
OTHER_FILES += qh-user_r.htm
|
||||
@@ -0,0 +1,566 @@
|
||||
/*<html><pre> -<a href="qh-mem_r.htm"
|
||||
>-------------------------------</a><a name="TOP">-</a>
|
||||
|
||||
mem_r.c
|
||||
memory management routines for qhull
|
||||
|
||||
See libqhull/mem.c for a standalone program.
|
||||
|
||||
To initialize memory:
|
||||
|
||||
qh_meminit(qh, stderr);
|
||||
qh_meminitbuffers(qh, qh->IStracing, qh_MEMalign, 7, qh_MEMbufsize,qh_MEMinitbuf);
|
||||
qh_memsize(qh, (int)sizeof(facetT));
|
||||
qh_memsize(qh, (int)sizeof(facetT));
|
||||
...
|
||||
qh_memsetup(qh);
|
||||
|
||||
To free up all memory buffers:
|
||||
qh_memfreeshort(qh, &curlong, &totlong);
|
||||
|
||||
if qh_NOmem,
|
||||
malloc/free is used instead of mem_r.c
|
||||
|
||||
notes:
|
||||
uses Quickfit algorithm (freelists for commonly allocated sizes)
|
||||
assumes small sizes for freelists (it discards the tail of memory buffers)
|
||||
|
||||
see:
|
||||
qh-mem_r.htm and mem_r.h
|
||||
global_r.c (qh_initbuffers) for an example of using mem_r.c
|
||||
|
||||
Copyright (c) 1993-2020 The Geometry Center.
|
||||
$Id: //main/2019/qhull/src/libqhull_r/mem_r.c#7 $$Change: 2953 $
|
||||
$DateTime: 2020/05/21 22:05:32 $$Author: bbarber $
|
||||
*/
|
||||
|
||||
#include "libqhull_r.h" /* includes user_r.h and mem_r.h */
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef qh_NOmem
|
||||
|
||||
/*============= internal functions ==============*/
|
||||
|
||||
static int qh_intcompare(const void *i, const void *j);
|
||||
|
||||
/*========== functions in alphabetical order ======== */
|
||||
|
||||
/*-<a href="qh-mem_r.htm#TOC"
|
||||
>-------------------------------</a><a name="intcompare">-</a>
|
||||
|
||||
qh_intcompare( i, j )
|
||||
used by qsort and bsearch to compare two integers
|
||||
*/
|
||||
static int qh_intcompare(const void *i, const void *j) {
|
||||
return(*((const int *)i) - *((const int *)j));
|
||||
} /* intcompare */
|
||||
|
||||
|
||||
/*-<a href="qh-mem_r.htm#TOC"
|
||||
>--------------------------------</a><a name="memalloc">-</a>
|
||||
|
||||
qh_memalloc(qh, insize )
|
||||
returns object of insize bytes
|
||||
qhmem is the global memory structure
|
||||
|
||||
returns:
|
||||
pointer to allocated memory
|
||||
errors if insufficient memory
|
||||
|
||||
notes:
|
||||
use explicit type conversion to avoid type warnings on some compilers
|
||||
actual object may be larger than insize
|
||||
use qh_memalloc_() for inline code for quick allocations
|
||||
logs allocations if 'T5'
|
||||
caller is responsible for freeing the memory.
|
||||
short memory is freed on shutdown by qh_memfreeshort unless qh_NOmem
|
||||
|
||||
design:
|
||||
if size < qh->qhmem.LASTsize
|
||||
if qh->qhmem.freelists[size] non-empty
|
||||
return first object on freelist
|
||||
else
|
||||
round up request to size of qh->qhmem.freelists[size]
|
||||
allocate new allocation buffer if necessary
|
||||
allocate object from allocation buffer
|
||||
else
|
||||
allocate object with qh_malloc() in user_r.c
|
||||
*/
|
||||
void *qh_memalloc(qhT *qh, int insize) {
|
||||
void **freelistp, *newbuffer;
|
||||
int idx, size, n;
|
||||
int outsize, bufsize;
|
||||
void *object;
|
||||
|
||||
if (insize<0) {
|
||||
qh_fprintf(qh, qh->qhmem.ferr, 6235, "qhull error (qh_memalloc): negative request size (%d). Did int overflow due to high-D?\n", insize); /* WARN64 */
|
||||
qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
|
||||
}
|
||||
if (insize>=0 && insize <= qh->qhmem.LASTsize) {
|
||||
idx= qh->qhmem.indextable[insize];
|
||||
outsize= qh->qhmem.sizetable[idx];
|
||||
qh->qhmem.totshort += outsize;
|
||||
freelistp= qh->qhmem.freelists+idx;
|
||||
if ((object= *freelistp)) {
|
||||
qh->qhmem.cntquick++;
|
||||
qh->qhmem.totfree -= outsize;
|
||||
*freelistp= *((void **)*freelistp); /* replace freelist with next object */
|
||||
#ifdef qh_TRACEshort
|
||||
n= qh->qhmem.cntshort+qh->qhmem.cntquick+qh->qhmem.freeshort;
|
||||
if (qh->qhmem.IStracing >= 5)
|
||||
qh_fprintf(qh, qh->qhmem.ferr, 8141, "qh_mem %p n %8d alloc quick: %d bytes (tot %d cnt %d)\n", object, n, outsize, qh->qhmem.totshort, qh->qhmem.cntshort+qh->qhmem.cntquick-qh->qhmem.freeshort);
|
||||
#endif
|
||||
return(object);
|
||||
}else {
|
||||
qh->qhmem.cntshort++;
|
||||
if (outsize > qh->qhmem.freesize) {
|
||||
qh->qhmem.totdropped += qh->qhmem.freesize;
|
||||
if (!qh->qhmem.curbuffer)
|
||||
bufsize= qh->qhmem.BUFinit;
|
||||
else
|
||||
bufsize= qh->qhmem.BUFsize;
|
||||
if (!(newbuffer= qh_malloc((size_t)bufsize))) {
|
||||
qh_fprintf(qh, qh->qhmem.ferr, 6080, "qhull error (qh_memalloc): insufficient memory to allocate short memory buffer (%d bytes)\n", bufsize);
|
||||
qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
|
||||
}
|
||||
*((void **)newbuffer)= qh->qhmem.curbuffer; /* prepend newbuffer to curbuffer
|
||||
list. newbuffer!=0 by QH6080 */
|
||||
qh->qhmem.curbuffer= newbuffer;
|
||||
size= ((int)sizeof(void **) + qh->qhmem.ALIGNmask) & ~qh->qhmem.ALIGNmask;
|
||||
qh->qhmem.freemem= (void *)((char *)newbuffer+size);
|
||||
qh->qhmem.freesize= bufsize - size;
|
||||
qh->qhmem.totbuffer += bufsize - size; /* easier to check */
|
||||
/* Periodically test totbuffer. It matches at beginning and exit of every call */
|
||||
n= qh->qhmem.totshort + qh->qhmem.totfree + qh->qhmem.totdropped + qh->qhmem.freesize - outsize;
|
||||
if (qh->qhmem.totbuffer != n) {
|
||||
qh_fprintf(qh, qh->qhmem.ferr, 6212, "qhull internal error (qh_memalloc): short totbuffer %d != totshort+totfree... %d\n", qh->qhmem.totbuffer, n);
|
||||
qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
|
||||
}
|
||||
}
|
||||
object= qh->qhmem.freemem;
|
||||
qh->qhmem.freemem= (void *)((char *)qh->qhmem.freemem + outsize);
|
||||
qh->qhmem.freesize -= outsize;
|
||||
qh->qhmem.totunused += outsize - insize;
|
||||
#ifdef qh_TRACEshort
|
||||
n= qh->qhmem.cntshort+qh->qhmem.cntquick+qh->qhmem.freeshort;
|
||||
if (qh->qhmem.IStracing >= 5)
|
||||
qh_fprintf(qh, qh->qhmem.ferr, 8140, "qh_mem %p n %8d alloc short: %d bytes (tot %d cnt %d)\n", object, n, outsize, qh->qhmem.totshort, qh->qhmem.cntshort+qh->qhmem.cntquick-qh->qhmem.freeshort);
|
||||
#endif
|
||||
return object;
|
||||
}
|
||||
}else { /* long allocation */
|
||||
if (!qh->qhmem.indextable) {
|
||||
qh_fprintf(qh, qh->qhmem.ferr, 6081, "qhull internal error (qh_memalloc): qhmem has not been initialized.\n");
|
||||
qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
|
||||
}
|
||||
outsize= insize;
|
||||
qh->qhmem.cntlong++;
|
||||
qh->qhmem.totlong += outsize;
|
||||
if (qh->qhmem.maxlong < qh->qhmem.totlong)
|
||||
qh->qhmem.maxlong= qh->qhmem.totlong;
|
||||
if (!(object= qh_malloc((size_t)outsize))) {
|
||||
qh_fprintf(qh, qh->qhmem.ferr, 6082, "qhull error (qh_memalloc): insufficient memory to allocate %d bytes\n", outsize);
|
||||
qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
|
||||
}
|
||||
if (qh->qhmem.IStracing >= 5)
|
||||
qh_fprintf(qh, qh->qhmem.ferr, 8057, "qh_mem %p n %8d alloc long: %d bytes (tot %d cnt %d)\n", object, qh->qhmem.cntlong+qh->qhmem.freelong, outsize, qh->qhmem.totlong, qh->qhmem.cntlong-qh->qhmem.freelong);
|
||||
}
|
||||
return(object);
|
||||
} /* memalloc */
|
||||
|
||||
|
||||
/*-<a href="qh-mem_r.htm#TOC"
|
||||
>--------------------------------</a><a name="memcheck">-</a>
|
||||
|
||||
qh_memcheck(qh)
|
||||
*/
|
||||
void qh_memcheck(qhT *qh) {
|
||||
int i, count, totfree= 0;
|
||||
void *object;
|
||||
|
||||
if (!qh) {
|
||||
qh_fprintf_stderr(6243, "qhull internal error (qh_memcheck): qh is 0. It does not point to a qhT\n");
|
||||
qh_exit(qhmem_ERRqhull); /* can not use qh_errexit() */
|
||||
}
|
||||
if (qh->qhmem.ferr == 0 || qh->qhmem.IStracing < 0 || qh->qhmem.IStracing > 10 || (((qh->qhmem.ALIGNmask+1) & qh->qhmem.ALIGNmask) != 0)) {
|
||||
qh_fprintf_stderr(6244, "qhull internal error (qh_memcheck): either qh->qhmem is overwritten or qh->qhmem is not initialized. Call qh_meminit or qh_new_qhull before calling qh_mem routines. ferr 0x%x, IsTracing %d, ALIGNmask 0x%x\n",
|
||||
qh->qhmem.ferr, qh->qhmem.IStracing, qh->qhmem.ALIGNmask);
|
||||
qh_exit(qhmem_ERRqhull); /* can not use qh_errexit() */
|
||||
}
|
||||
if (qh->qhmem.IStracing != 0)
|
||||
qh_fprintf(qh, qh->qhmem.ferr, 8143, "qh_memcheck: check size of freelists on qh->qhmem\nqh_memcheck: A segmentation fault indicates an overwrite of qh->qhmem\n");
|
||||
for (i=0; i < qh->qhmem.TABLEsize; i++) {
|
||||
count=0;
|
||||
for (object= qh->qhmem.freelists[i]; object; object= *((void **)object))
|
||||
count++;
|
||||
totfree += qh->qhmem.sizetable[i] * count;
|
||||
}
|
||||
if (totfree != qh->qhmem.totfree) {
|
||||
qh_fprintf(qh, qh->qhmem.ferr, 6211, "qhull internal error (qh_memcheck): totfree %d not equal to freelist total %d\n", qh->qhmem.totfree, totfree);
|
||||
qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
|
||||
}
|
||||
if (qh->qhmem.IStracing != 0)
|
||||
qh_fprintf(qh, qh->qhmem.ferr, 8144, "qh_memcheck: total size of freelists totfree is the same as qh->qhmem.totfree\n", totfree);
|
||||
} /* memcheck */
|
||||
|
||||
/*-<a href="qh-mem_r.htm#TOC"
|
||||
>--------------------------------</a><a name="memfree">-</a>
|
||||
|
||||
qh_memfree(qh, object, insize )
|
||||
free up an object of size bytes
|
||||
size is insize from qh_memalloc
|
||||
|
||||
notes:
|
||||
object may be NULL
|
||||
type checking warns if using (void **)object
|
||||
use qh_memfree_() for quick free's of small objects
|
||||
|
||||
design:
|
||||
if size <= qh->qhmem.LASTsize
|
||||
append object to corresponding freelist
|
||||
else
|
||||
call qh_free(object)
|
||||
*/
|
||||
void qh_memfree(qhT *qh, void *object, int insize) {
|
||||
void **freelistp;
|
||||
int idx, outsize;
|
||||
|
||||
if (!object)
|
||||
return;
|
||||
if (insize <= qh->qhmem.LASTsize) {
|
||||
qh->qhmem.freeshort++;
|
||||
idx= qh->qhmem.indextable[insize];
|
||||
outsize= qh->qhmem.sizetable[idx];
|
||||
qh->qhmem.totfree += outsize;
|
||||
qh->qhmem.totshort -= outsize;
|
||||
freelistp= qh->qhmem.freelists + idx;
|
||||
*((void **)object)= *freelistp;
|
||||
*freelistp= object;
|
||||
#ifdef qh_TRACEshort
|
||||
idx= qh->qhmem.cntshort+qh->qhmem.cntquick+qh->qhmem.freeshort;
|
||||
if (qh->qhmem.IStracing >= 5)
|
||||
qh_fprintf(qh, qh->qhmem.ferr, 8142, "qh_mem %p n %8d free short: %d bytes (tot %d cnt %d)\n", object, idx, outsize, qh->qhmem.totshort, qh->qhmem.cntshort+qh->qhmem.cntquick-qh->qhmem.freeshort);
|
||||
#endif
|
||||
}else {
|
||||
qh->qhmem.freelong++;
|
||||
qh->qhmem.totlong -= insize;
|
||||
if (qh->qhmem.IStracing >= 5)
|
||||
qh_fprintf(qh, qh->qhmem.ferr, 8058, "qh_mem %p n %8d free long: %d bytes (tot %d cnt %d)\n", object, qh->qhmem.cntlong+qh->qhmem.freelong, insize, qh->qhmem.totlong, qh->qhmem.cntlong-qh->qhmem.freelong);
|
||||
qh_free(object);
|
||||
}
|
||||
} /* memfree */
|
||||
|
||||
|
||||
/*-<a href="qh-mem_r.htm#TOC"
|
||||
>-------------------------------</a><a name="memfreeshort">-</a>
|
||||
|
||||
qh_memfreeshort(qh, curlong, totlong )
|
||||
frees up all short and qhmem memory allocations
|
||||
|
||||
returns:
|
||||
number and size of current long allocations
|
||||
|
||||
notes:
|
||||
if qh_NOmem (qh_malloc() for all allocations),
|
||||
short objects (e.g., facetT) are not recovered.
|
||||
use qh_freeqhull(qh, qh_ALL) instead.
|
||||
|
||||
see:
|
||||
qh_freeqhull(qh, allMem)
|
||||
qh_memtotal(qh, curlong, totlong, curshort, totshort, maxlong, totbuffer);
|
||||
*/
|
||||
void qh_memfreeshort(qhT *qh, int *curlong, int *totlong) {
|
||||
void *buffer, *nextbuffer;
|
||||
FILE *ferr;
|
||||
|
||||
*curlong= qh->qhmem.cntlong - qh->qhmem.freelong;
|
||||
*totlong= qh->qhmem.totlong;
|
||||
for (buffer=qh->qhmem.curbuffer; buffer; buffer= nextbuffer) {
|
||||
nextbuffer= *((void **) buffer);
|
||||
qh_free(buffer);
|
||||
}
|
||||
qh->qhmem.curbuffer= NULL;
|
||||
if (qh->qhmem.LASTsize) {
|
||||
qh_free(qh->qhmem.indextable);
|
||||
qh_free(qh->qhmem.freelists);
|
||||
qh_free(qh->qhmem.sizetable);
|
||||
}
|
||||
ferr= qh->qhmem.ferr;
|
||||
memset((char *)&qh->qhmem, 0, sizeof(qh->qhmem)); /* every field is 0, FALSE, NULL */
|
||||
qh->qhmem.ferr= ferr;
|
||||
} /* memfreeshort */
|
||||
|
||||
|
||||
/*-<a href="qh-mem_r.htm#TOC"
|
||||
>--------------------------------</a><a name="meminit">-</a>
|
||||
|
||||
qh_meminit(qh, ferr )
|
||||
initialize qhmem and test sizeof(void *)
|
||||
Does not throw errors. qh_exit on failure
|
||||
*/
|
||||
void qh_meminit(qhT *qh, FILE *ferr) {
|
||||
|
||||
memset((char *)&qh->qhmem, 0, sizeof(qh->qhmem)); /* every field is 0, FALSE, NULL */
|
||||
if (ferr)
|
||||
qh->qhmem.ferr= ferr;
|
||||
else
|
||||
qh->qhmem.ferr= stderr;
|
||||
if (sizeof(void *) < sizeof(int)) {
|
||||
qh_fprintf(qh, qh->qhmem.ferr, 6083, "qhull internal error (qh_meminit): sizeof(void *) %d < sizeof(int) %d. qset_r.c will not work\n", (int)sizeof(void*), (int)sizeof(int));
|
||||
qh_exit(qhmem_ERRqhull); /* can not use qh_errexit() */
|
||||
}
|
||||
if (sizeof(void *) > sizeof(ptr_intT)) {
|
||||
qh_fprintf(qh, qh->qhmem.ferr, 6084, "qhull internal error (qh_meminit): sizeof(void *) %d > sizeof(ptr_intT) %d. Change ptr_intT in mem_r.h to 'long long'\n", (int)sizeof(void*), (int)sizeof(ptr_intT));
|
||||
qh_exit(qhmem_ERRqhull); /* can not use qh_errexit() */
|
||||
}
|
||||
qh_memcheck(qh);
|
||||
} /* meminit */
|
||||
|
||||
/*-<a href="qh-mem_r.htm#TOC"
|
||||
>-------------------------------</a><a name="meminitbuffers">-</a>
|
||||
|
||||
qh_meminitbuffers(qh, tracelevel, alignment, numsizes, bufsize, bufinit )
|
||||
initialize qhmem
|
||||
if tracelevel >= 5, trace memory allocations
|
||||
alignment= desired address alignment for memory allocations
|
||||
numsizes= number of freelists
|
||||
bufsize= size of additional memory buffers for short allocations
|
||||
bufinit= size of initial memory buffer for short allocations
|
||||
*/
|
||||
void qh_meminitbuffers(qhT *qh, int tracelevel, int alignment, int numsizes, int bufsize, int bufinit) {
|
||||
|
||||
qh->qhmem.IStracing= tracelevel;
|
||||
qh->qhmem.NUMsizes= numsizes;
|
||||
qh->qhmem.BUFsize= bufsize;
|
||||
qh->qhmem.BUFinit= bufinit;
|
||||
qh->qhmem.ALIGNmask= alignment-1;
|
||||
if (qh->qhmem.ALIGNmask & ~qh->qhmem.ALIGNmask) {
|
||||
qh_fprintf(qh, qh->qhmem.ferr, 6085, "qhull internal error (qh_meminit): memory alignment %d is not a power of 2\n", alignment);
|
||||
qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
|
||||
}
|
||||
qh->qhmem.sizetable= (int *) calloc((size_t)numsizes, sizeof(int));
|
||||
qh->qhmem.freelists= (void **) calloc((size_t)numsizes, sizeof(void *));
|
||||
if (!qh->qhmem.sizetable || !qh->qhmem.freelists) {
|
||||
qh_fprintf(qh, qh->qhmem.ferr, 6086, "qhull error (qh_meminit): insufficient memory\n");
|
||||
qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
|
||||
}
|
||||
if (qh->qhmem.IStracing >= 1)
|
||||
qh_fprintf(qh, qh->qhmem.ferr, 8059, "qh_meminitbuffers: memory initialized with alignment %d\n", alignment);
|
||||
} /* meminitbuffers */
|
||||
|
||||
/*-<a href="qh-mem_r.htm#TOC"
|
||||
>-------------------------------</a><a name="memsetup">-</a>
|
||||
|
||||
qh_memsetup(qh)
|
||||
set up memory after running memsize()
|
||||
*/
|
||||
void qh_memsetup(qhT *qh) {
|
||||
int k,i;
|
||||
|
||||
qsort(qh->qhmem.sizetable, (size_t)qh->qhmem.TABLEsize, sizeof(int), qh_intcompare);
|
||||
qh->qhmem.LASTsize= qh->qhmem.sizetable[qh->qhmem.TABLEsize-1];
|
||||
if (qh->qhmem.LASTsize >= qh->qhmem.BUFsize || qh->qhmem.LASTsize >= qh->qhmem.BUFinit) {
|
||||
qh_fprintf(qh, qh->qhmem.ferr, 6087, "qhull error (qh_memsetup): largest mem size %d is >= buffer size %d or initial buffer size %d\n",
|
||||
qh->qhmem.LASTsize, qh->qhmem.BUFsize, qh->qhmem.BUFinit);
|
||||
qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
|
||||
}
|
||||
if (!(qh->qhmem.indextable= (int *)qh_malloc((size_t)(qh->qhmem.LASTsize+1) * sizeof(int)))) {
|
||||
qh_fprintf(qh, qh->qhmem.ferr, 6088, "qhull error (qh_memsetup): insufficient memory\n");
|
||||
qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
|
||||
}
|
||||
for (k=qh->qhmem.LASTsize+1; k--; )
|
||||
qh->qhmem.indextable[k]= k;
|
||||
i= 0;
|
||||
for (k=0; k <= qh->qhmem.LASTsize; k++) {
|
||||
if (qh->qhmem.indextable[k] <= qh->qhmem.sizetable[i])
|
||||
qh->qhmem.indextable[k]= i;
|
||||
else
|
||||
qh->qhmem.indextable[k]= ++i;
|
||||
}
|
||||
} /* memsetup */
|
||||
|
||||
/*-<a href="qh-mem_r.htm#TOC"
|
||||
>-------------------------------</a><a name="memsize">-</a>
|
||||
|
||||
qh_memsize(qh, size )
|
||||
define a free list for this size
|
||||
*/
|
||||
void qh_memsize(qhT *qh, int size) {
|
||||
int k;
|
||||
|
||||
if (qh->qhmem.LASTsize) {
|
||||
qh_fprintf(qh, qh->qhmem.ferr, 6089, "qhull internal error (qh_memsize): qh_memsize called after qh_memsetup\n");
|
||||
qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
|
||||
}
|
||||
size= (size + qh->qhmem.ALIGNmask) & ~qh->qhmem.ALIGNmask;
|
||||
if (qh->qhmem.IStracing >= 3)
|
||||
qh_fprintf(qh, qh->qhmem.ferr, 3078, "qh_memsize: quick memory of %d bytes\n", size);
|
||||
for (k=qh->qhmem.TABLEsize; k--; ) {
|
||||
if (qh->qhmem.sizetable[k] == size)
|
||||
return;
|
||||
}
|
||||
if (qh->qhmem.TABLEsize < qh->qhmem.NUMsizes)
|
||||
qh->qhmem.sizetable[qh->qhmem.TABLEsize++]= size;
|
||||
else
|
||||
qh_fprintf(qh, qh->qhmem.ferr, 7060, "qhull warning (qh_memsize): free list table has room for only %d sizes\n", qh->qhmem.NUMsizes);
|
||||
} /* memsize */
|
||||
|
||||
|
||||
/*-<a href="qh-mem_r.htm#TOC"
|
||||
>-------------------------------</a><a name="memstatistics">-</a>
|
||||
|
||||
qh_memstatistics(qh, fp )
|
||||
print out memory statistics
|
||||
|
||||
Verifies that qh->qhmem.totfree == sum of freelists
|
||||
*/
|
||||
void qh_memstatistics(qhT *qh, FILE *fp) {
|
||||
int i;
|
||||
int count;
|
||||
void *object;
|
||||
|
||||
qh_memcheck(qh);
|
||||
qh_fprintf(qh, fp, 9278, "\nmemory statistics:\n\
|
||||
%7d quick allocations\n\
|
||||
%7d short allocations\n\
|
||||
%7d long allocations\n\
|
||||
%7d short frees\n\
|
||||
%7d long frees\n\
|
||||
%7d bytes of short memory in use\n\
|
||||
%7d bytes of short memory in freelists\n\
|
||||
%7d bytes of dropped short memory\n\
|
||||
%7d bytes of unused short memory (estimated)\n\
|
||||
%7d bytes of long memory allocated (max, except for input)\n\
|
||||
%7d bytes of long memory in use (in %d pieces)\n\
|
||||
%7d bytes of short memory buffers (minus links)\n\
|
||||
%7d bytes per short memory buffer (initially %d bytes)\n",
|
||||
qh->qhmem.cntquick, qh->qhmem.cntshort, qh->qhmem.cntlong,
|
||||
qh->qhmem.freeshort, qh->qhmem.freelong,
|
||||
qh->qhmem.totshort, qh->qhmem.totfree,
|
||||
qh->qhmem.totdropped + qh->qhmem.freesize, qh->qhmem.totunused,
|
||||
qh->qhmem.maxlong, qh->qhmem.totlong, qh->qhmem.cntlong - qh->qhmem.freelong,
|
||||
qh->qhmem.totbuffer, qh->qhmem.BUFsize, qh->qhmem.BUFinit);
|
||||
if (qh->qhmem.cntlarger) {
|
||||
qh_fprintf(qh, fp, 9279, "%7d calls to qh_setlarger\n%7.2g average copy size\n",
|
||||
qh->qhmem.cntlarger, ((double)qh->qhmem.totlarger)/(double)qh->qhmem.cntlarger);
|
||||
qh_fprintf(qh, fp, 9280, " freelists(bytes->count):");
|
||||
}
|
||||
for (i=0; i < qh->qhmem.TABLEsize; i++) {
|
||||
count=0;
|
||||
for (object= qh->qhmem.freelists[i]; object; object= *((void **)object))
|
||||
count++;
|
||||
qh_fprintf(qh, fp, 9281, " %d->%d", qh->qhmem.sizetable[i], count);
|
||||
}
|
||||
qh_fprintf(qh, fp, 9282, "\n\n");
|
||||
} /* memstatistics */
|
||||
|
||||
|
||||
/*-<a href="qh-mem_r.htm#TOC"
|
||||
>-------------------------------</a><a name="NOmem">-</a>
|
||||
|
||||
qh_NOmem
|
||||
turn off quick-fit memory allocation
|
||||
|
||||
notes:
|
||||
uses qh_malloc() and qh_free() instead
|
||||
*/
|
||||
#else /* qh_NOmem */
|
||||
|
||||
void *qh_memalloc(qhT *qh, int insize) {
|
||||
void *object;
|
||||
|
||||
if (!(object= qh_malloc((size_t)insize))) {
|
||||
qh_fprintf(qh, qh->qhmem.ferr, 6090, "qhull error (qh_memalloc): insufficient memory\n");
|
||||
qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
|
||||
}
|
||||
qh->qhmem.cntlong++;
|
||||
qh->qhmem.totlong += insize;
|
||||
if (qh->qhmem.maxlong < qh->qhmem.totlong)
|
||||
qh->qhmem.maxlong= qh->qhmem.totlong;
|
||||
if (qh->qhmem.IStracing >= 5)
|
||||
qh_fprintf(qh, qh->qhmem.ferr, 8060, "qh_mem %p n %8d alloc long: %d bytes (tot %d cnt %d)\n", object, qh->qhmem.cntlong+qh->qhmem.freelong, insize, qh->qhmem.totlong, qh->qhmem.cntlong-qh->qhmem.freelong);
|
||||
return object;
|
||||
}
|
||||
|
||||
void qh_memcheck(qhT *qh) {
|
||||
}
|
||||
|
||||
void qh_memfree(qhT *qh, void *object, int insize) {
|
||||
|
||||
if (!object)
|
||||
return;
|
||||
qh_free(object);
|
||||
qh->qhmem.freelong++;
|
||||
qh->qhmem.totlong -= insize;
|
||||
if (qh->qhmem.IStracing >= 5)
|
||||
qh_fprintf(qh, qh->qhmem.ferr, 8061, "qh_mem %p n %8d free long: %d bytes (tot %d cnt %d)\n", object, qh->qhmem.cntlong+qh->qhmem.freelong, insize, qh->qhmem.totlong, qh->qhmem.cntlong-qh->qhmem.freelong);
|
||||
}
|
||||
|
||||
void qh_memfreeshort(qhT *qh, int *curlong, int *totlong) {
|
||||
*totlong= qh->qhmem.totlong;
|
||||
*curlong= qh->qhmem.cntlong - qh->qhmem.freelong;
|
||||
memset((char *)&qh->qhmem, 0, sizeof(qh->qhmem)); /* every field is 0, FALSE, NULL */
|
||||
}
|
||||
|
||||
void qh_meminit(qhT *qh, FILE *ferr) {
|
||||
|
||||
memset((char *)&qh->qhmem, 0, sizeof(qh->qhmem)); /* every field is 0, FALSE, NULL */
|
||||
if (ferr)
|
||||
qh->qhmem.ferr= ferr;
|
||||
else
|
||||
qh->qhmem.ferr= stderr;
|
||||
if (sizeof(void *) < sizeof(int)) {
|
||||
qh_fprintf(qh, qh->qhmem.ferr, 6091, "qhull internal error (qh_meminit): sizeof(void *) %d < sizeof(int) %d. qset_r.c will not work\n", (int)sizeof(void*), (int)sizeof(int));
|
||||
qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void qh_meminitbuffers(qhT *qh, int tracelevel, int alignment, int numsizes, int bufsize, int bufinit) {
|
||||
|
||||
qh->qhmem.IStracing= tracelevel;
|
||||
}
|
||||
|
||||
void qh_memsetup(qhT *qh) {
|
||||
}
|
||||
|
||||
void qh_memsize(qhT *qh, int size) {
|
||||
}
|
||||
|
||||
void qh_memstatistics(qhT *qh, FILE *fp) {
|
||||
|
||||
qh_fprintf(qh, fp, 9409, "\nmemory statistics:\n\
|
||||
%7d long allocations\n\
|
||||
%7d long frees\n\
|
||||
%7d bytes of long memory allocated (max, except for input)\n\
|
||||
%7d bytes of long memory in use (in %d pieces)\n",
|
||||
qh->qhmem.cntlong,
|
||||
qh->qhmem.freelong,
|
||||
qh->qhmem.maxlong, qh->qhmem.totlong, qh->qhmem.cntlong - qh->qhmem.freelong);
|
||||
}
|
||||
|
||||
#endif /* qh_NOmem */
|
||||
|
||||
/*-<a href="qh-mem_r.htm#TOC"
|
||||
>-------------------------------</a><a name="memtotlong">-</a>
|
||||
|
||||
qh_memtotal(qh, totlong, curlong, totshort, curshort, maxlong, totbuffer )
|
||||
Return the total, allocated long and short memory
|
||||
|
||||
returns:
|
||||
Returns the total current bytes of long and short allocations
|
||||
Returns the current count of long and short allocations
|
||||
Returns the maximum long memory and total short buffer (minus one link per buffer)
|
||||
Does not error (for deprecated UsingLibQhull.cpp in libqhullpcpp)
|
||||
*/
|
||||
void qh_memtotal(qhT *qh, int *totlong, int *curlong, int *totshort, int *curshort, int *maxlong, int *totbuffer) {
|
||||
*totlong= qh->qhmem.totlong;
|
||||
*curlong= qh->qhmem.cntlong - qh->qhmem.freelong;
|
||||
*totshort= qh->qhmem.totshort;
|
||||
*curshort= qh->qhmem.cntshort + qh->qhmem.cntquick - qh->qhmem.freeshort;
|
||||
*maxlong= qh->qhmem.maxlong;
|
||||
*totbuffer= qh->qhmem.totbuffer;
|
||||
} /* memtotlong */
|
||||
|
||||
@@ -0,0 +1,235 @@
|
||||
/*<html><pre> -<a href="qh-mem_r.htm"
|
||||
>-------------------------------</a><a name="TOP">-</a>
|
||||
|
||||
mem_r.h
|
||||
prototypes for memory management functions
|
||||
|
||||
see qh-mem_r.htm, mem_r.c and qset_r.h
|
||||
|
||||
for error handling, writes message and calls
|
||||
qh_errexit(qhT *qh, qhmem_ERRmem, NULL, NULL) if insufficient memory
|
||||
and
|
||||
qh_errexit(qhT *qh, qhmem_ERRqhull, NULL, NULL) otherwise
|
||||
|
||||
Copyright (c) 1993-2020 The Geometry Center.
|
||||
$Id: //main/2019/qhull/src/libqhull_r/mem_r.h#6 $$Change: 2953 $
|
||||
$DateTime: 2020/05/21 22:05:32 $$Author: bbarber $
|
||||
*/
|
||||
|
||||
#ifndef qhDEFmem
|
||||
#define qhDEFmem 1
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef DEFsetT
|
||||
#define DEFsetT 1
|
||||
typedef struct setT setT; /* defined in qset_r.h */
|
||||
#endif
|
||||
|
||||
#ifndef DEFqhT
|
||||
#define DEFqhT 1
|
||||
typedef struct qhT qhT; /* defined in libqhull_r.h */
|
||||
#endif
|
||||
|
||||
/*-<a href="qh-mem_r.htm#TOC"
|
||||
>-------------------------------</a><a name="NOmem">-</a>
|
||||
|
||||
qh_NOmem
|
||||
turn off quick-fit memory allocation
|
||||
|
||||
notes:
|
||||
mem_r.c implements Quickfit memory allocation for about 20% time
|
||||
savings. If it fails on your machine, try to locate the
|
||||
problem, and send the answer to qhull@qhull.org. If this can
|
||||
not be done, define qh_NOmem to use malloc/free instead.
|
||||
|
||||
#define qh_NOmem
|
||||
*/
|
||||
|
||||
/*-<a href="qh-mem_r.htm#TOC"
|
||||
>-------------------------------</a><a name="TRACEshort">-</a>
|
||||
|
||||
qh_TRACEshort
|
||||
Trace short and quick memory allocations at T5
|
||||
|
||||
*/
|
||||
#define qh_TRACEshort
|
||||
|
||||
/*-------------------------------------------
|
||||
to avoid bus errors, memory allocation must consider alignment requirements.
|
||||
malloc() automatically takes care of alignment. Since mem_r.c manages
|
||||
its own memory, we need to explicitly specify alignment in
|
||||
qh_meminitbuffers().
|
||||
|
||||
A safe choice is sizeof(double). sizeof(float) may be used if doubles
|
||||
do not occur in data structures and pointers are the same size. Be careful
|
||||
of machines (e.g., DEC Alpha) with large pointers. If gcc is available,
|
||||
use __alignof__(double) or fmax_(__alignof__(float), __alignof__(void *)).
|
||||
|
||||
see <a href="user_r.h#MEMalign">qh_MEMalign</a> in user_r.h for qhull's alignment
|
||||
*/
|
||||
|
||||
#define qhmem_ERRmem 4 /* matches qh_ERRmem in libqhull_r.h */
|
||||
#define qhmem_ERRqhull 5 /* matches qh_ERRqhull in libqhull_r.h */
|
||||
|
||||
/*-<a href="qh-mem_r.htm#TOC"
|
||||
>--------------------------------</a><a name="ptr_intT">-</a>
|
||||
|
||||
ptr_intT
|
||||
for casting a void * to an integer-type that holds a pointer
|
||||
Used for integer expressions (e.g., computing qh_gethash() in poly_r.c)
|
||||
|
||||
notes:
|
||||
WARN64 -- these notes indicate 64-bit issues
|
||||
On 64-bit machines, a pointer may be larger than an 'int'.
|
||||
qh_meminit()/mem_r.c checks that 'ptr_intT' holds a 'void*'
|
||||
ptr_intT is typically a signed value, but not necessarily so
|
||||
size_t is typically unsigned, but should match the parameter type
|
||||
Qhull uses int instead of size_t except for system calls such as malloc, qsort, qh_malloc, etc.
|
||||
This matches Qt convention and is easier to work with.
|
||||
*/
|
||||
#if (defined(__MINGW64__)) && defined(_WIN64)
|
||||
typedef long long ptr_intT;
|
||||
#elif defined(_MSC_VER) && defined(_WIN64)
|
||||
typedef long long ptr_intT;
|
||||
#else
|
||||
typedef long ptr_intT;
|
||||
#endif
|
||||
|
||||
/*-<a href="qh-mem_r.htm#TOC"
|
||||
>--------------------------------</a><a name="qhmemT">-</a>
|
||||
|
||||
qhmemT
|
||||
global memory structure for mem_r.c
|
||||
|
||||
notes:
|
||||
users should ignore qhmem except for writing extensions
|
||||
qhmem is allocated in mem_r.c
|
||||
|
||||
qhmem could be swapable like qh and qhstat, but then
|
||||
multiple qh's and qhmem's would need to keep in synch.
|
||||
A swapable qhmem would also waste memory buffers. As long
|
||||
as memory operations are atomic, there is no problem with
|
||||
multiple qh structures being active at the same time.
|
||||
If you need separate address spaces, you can swap the
|
||||
contents of qh->qhmem.
|
||||
*/
|
||||
typedef struct qhmemT qhmemT;
|
||||
|
||||
struct qhmemT { /* global memory management variables */
|
||||
int BUFsize; /* size of memory allocation buffer */
|
||||
int BUFinit; /* initial size of memory allocation buffer */
|
||||
int TABLEsize; /* actual number of sizes in free list table */
|
||||
int NUMsizes; /* maximum number of sizes in free list table */
|
||||
int LASTsize; /* last size in free list table */
|
||||
int ALIGNmask; /* worst-case alignment, must be 2^n-1 */
|
||||
void **freelists; /* free list table, linked by offset 0 */
|
||||
int *sizetable; /* size of each freelist */
|
||||
int *indextable; /* size->index table */
|
||||
void *curbuffer; /* current buffer, linked by offset 0 */
|
||||
void *freemem; /* free memory in curbuffer */
|
||||
int freesize; /* size of freemem in bytes */
|
||||
setT *tempstack; /* stack of temporary memory, managed by users */
|
||||
FILE *ferr; /* file for reporting errors when 'qh' may be undefined */
|
||||
int IStracing; /* =5 if tracing memory allocations */
|
||||
int cntquick; /* count of quick allocations */
|
||||
/* Note: removing statistics doesn't effect speed */
|
||||
int cntshort; /* count of short allocations */
|
||||
int cntlong; /* count of long allocations */
|
||||
int freeshort; /* count of short memfrees */
|
||||
int freelong; /* count of long memfrees */
|
||||
int totbuffer; /* total short memory buffers minus buffer links */
|
||||
int totdropped; /* total dropped memory at end of short memory buffers (e.g., freesize) */
|
||||
int totfree; /* total size of free, short memory on freelists */
|
||||
int totlong; /* total size of long memory in use */
|
||||
int maxlong; /* maximum totlong */
|
||||
int totshort; /* total size of short memory in use */
|
||||
int totunused; /* total unused short memory (estimated, short size - request size of first allocations) */
|
||||
int cntlarger; /* count of setlarger's */
|
||||
int totlarger; /* total copied by setlarger */
|
||||
};
|
||||
|
||||
|
||||
/*==================== -macros ====================*/
|
||||
|
||||
/*-<a href="qh-mem_r.htm#TOC"
|
||||
>--------------------------------</a><a name="memalloc_">-</a>
|
||||
|
||||
qh_memalloc_(qh, insize, freelistp, object, type)
|
||||
returns object of size bytes
|
||||
assumes size<=qh->qhmem.LASTsize and void **freelistp is a temp
|
||||
*/
|
||||
|
||||
#if defined qh_NOmem
|
||||
#define qh_memalloc_(qh, insize, freelistp, object, type) {\
|
||||
(void)freelistp; /* Avoid warnings */ \
|
||||
object= (type *)qh_memalloc(qh, insize); }
|
||||
#elif defined qh_TRACEshort
|
||||
#define qh_memalloc_(qh, insize, freelistp, object, type) {\
|
||||
(void)freelistp; /* Avoid warnings */ \
|
||||
object= (type *)qh_memalloc(qh, insize); }
|
||||
#else /* !qh_NOmem */
|
||||
|
||||
#define qh_memalloc_(qh, insize, freelistp, object, type) {\
|
||||
freelistp= qh->qhmem.freelists + qh->qhmem.indextable[insize];\
|
||||
if ((object= (type *)*freelistp)) {\
|
||||
qh->qhmem.totshort += qh->qhmem.sizetable[qh->qhmem.indextable[insize]]; \
|
||||
qh->qhmem.totfree -= qh->qhmem.sizetable[qh->qhmem.indextable[insize]]; \
|
||||
qh->qhmem.cntquick++; \
|
||||
*freelistp= *((void **)*freelistp);\
|
||||
}else object= (type *)qh_memalloc(qh, insize);}
|
||||
#endif
|
||||
|
||||
/*-<a href="qh-mem_r.htm#TOC"
|
||||
>--------------------------------</a><a name="memfree_">-</a>
|
||||
|
||||
qh_memfree_(qh, object, insize, freelistp)
|
||||
free up an object
|
||||
|
||||
notes:
|
||||
object may be NULL
|
||||
assumes size<=qh->qhmem.LASTsize and void **freelistp is a temp
|
||||
*/
|
||||
#if defined qh_NOmem
|
||||
#define qh_memfree_(qh, object, insize, freelistp) {\
|
||||
(void)freelistp; /* Avoid warnings */ \
|
||||
qh_memfree(qh, object, insize); }
|
||||
#elif defined qh_TRACEshort
|
||||
#define qh_memfree_(qh, object, insize, freelistp) {\
|
||||
(void)freelistp; /* Avoid warnings */ \
|
||||
qh_memfree(qh, object, insize); }
|
||||
#else /* !qh_NOmem */
|
||||
|
||||
#define qh_memfree_(qh, object, insize, freelistp) {\
|
||||
if (object) { \
|
||||
qh->qhmem.freeshort++;\
|
||||
freelistp= qh->qhmem.freelists + qh->qhmem.indextable[insize];\
|
||||
qh->qhmem.totshort -= qh->qhmem.sizetable[qh->qhmem.indextable[insize]]; \
|
||||
qh->qhmem.totfree += qh->qhmem.sizetable[qh->qhmem.indextable[insize]]; \
|
||||
*((void **)object)= *freelistp;\
|
||||
*freelistp= object;}}
|
||||
#endif
|
||||
|
||||
/*=============== prototypes in alphabetical order ============*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void *qh_memalloc(qhT *qh, int insize);
|
||||
void qh_memcheck(qhT *qh);
|
||||
void qh_memfree(qhT *qh, void *object, int insize);
|
||||
void qh_memfreeshort(qhT *qh, int *curlong, int *totlong);
|
||||
void qh_meminit(qhT *qh, FILE *ferr);
|
||||
void qh_meminitbuffers(qhT *qh, int tracelevel, int alignment, int numsizes,
|
||||
int bufsize, int bufinit);
|
||||
void qh_memsetup(qhT *qh);
|
||||
void qh_memsize(qhT *qh, int size);
|
||||
void qh_memstatistics(qhT *qh, FILE *fp);
|
||||
void qh_memtotal(qhT *qh, int *totlong, int *curlong, int *totshort, int *curshort, int *maxlong, int *totbuffer);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* qhDEFmem */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,238 @@
|
||||
/*<html><pre> -<a href="qh-merge_r.htm"
|
||||
>-------------------------------</a><a name="TOP">-</a>
|
||||
|
||||
merge_r.h
|
||||
header file for merge_r.c
|
||||
|
||||
see qh-merge_r.htm and merge_r.c
|
||||
|
||||
Copyright (c) 1993-2020 C.B. Barber.
|
||||
$Id: //main/2019/qhull/src/libqhull_r/merge_r.h#2 $$Change: 2953 $
|
||||
$DateTime: 2020/05/21 22:05:32 $$Author: bbarber $
|
||||
*/
|
||||
|
||||
#ifndef qhDEFmerge
|
||||
#define qhDEFmerge 1
|
||||
|
||||
#include "libqhull_r.h"
|
||||
|
||||
|
||||
/*============ -constants- ==============*/
|
||||
|
||||
/*-<a href="qh-merge_r.htm#TOC"
|
||||
>--------------------------------</a><a name="qh_ANGLEnone">-</a>
|
||||
|
||||
qh_ANGLEnone
|
||||
indicates missing angle for mergeT->angle
|
||||
*/
|
||||
#define qh_ANGLEnone 2.0
|
||||
|
||||
/*-<a href="qh-merge_r.htm#TOC"
|
||||
>--------------------------------</a><a name="MRG">-</a>
|
||||
|
||||
MRG... (mergeType)
|
||||
indicates the type of a merge (mergeT->type)
|
||||
MRGcoplanar...MRGtwisted set by qh_test_centrum_merge, qh_test_nonsimplicial_merge
|
||||
*/
|
||||
typedef enum { /* must match mergetypes[] */
|
||||
MRGnone= 0,
|
||||
/* MRGcoplanar..MRGtwisted go into qh.facet_mergeset for qh_all_merges
|
||||
qh_compare_facetmerge selects lower mergetypes for merging first */
|
||||
MRGcoplanar, /* (1) centrum coplanar if centrum ('Cn') or vertex not clearly above or below neighbor */
|
||||
MRGanglecoplanar, /* (2) angle coplanar if angle ('An') is coplanar */
|
||||
MRGconcave, /* (3) concave ridge */
|
||||
MRGconcavecoplanar, /* (4) concave and coplanar ridge, one side concave, other side coplanar */
|
||||
MRGtwisted, /* (5) twisted ridge, both concave and convex, facet1 is wider */
|
||||
/* MRGflip go into qh.facet_mergeset for qh_flipped_merges */
|
||||
MRGflip, /* (6) flipped facet if qh.interior_point is above facet, w/ facet1 == facet2 */
|
||||
/* MRGdupridge go into qh.facet_mergeset for qh_forcedmerges */
|
||||
MRGdupridge, /* (7) dupridge if more than two neighbors. Set by qh_mark_dupridges for qh_MERGEridge */
|
||||
/* MRGsubridge and MRGvertices go into vertex_mergeset */
|
||||
MRGsubridge, /* (8) merge pinched vertex to remove the subridge of a MRGdupridge */
|
||||
MRGvertices, /* (9) merge pinched vertex to remove a facet's ridges with the same vertices */
|
||||
/* MRGdegen, MRGredundant, and MRGmirror go into qh.degen_mergeset */
|
||||
MRGdegen, /* (10) degenerate facet (!enough neighbors) facet1 == facet2 */
|
||||
MRGredundant, /* (11) redundant facet (vertex subset) */
|
||||
/* merge_degenredundant assumes degen < redundant */
|
||||
MRGmirror, /* (12) mirror facets: same vertices due to null facets in qh_triangulate
|
||||
f.redundant for both facets*/
|
||||
/* MRGcoplanarhorizon for qh_mergecycle_all only */
|
||||
MRGcoplanarhorizon, /* (13) new facet coplanar with the horizon (qh_mergecycle_all) */
|
||||
ENDmrg
|
||||
} mergeType;
|
||||
|
||||
/*-<a href="qh-merge_r.htm#TOC"
|
||||
>--------------------------------</a><a name="qh_MERGEapex">-</a>
|
||||
|
||||
qh_MERGEapex
|
||||
flag for qh_mergefacet() to indicate an apex merge
|
||||
*/
|
||||
#define qh_MERGEapex True
|
||||
|
||||
/*============ -structures- ====================*/
|
||||
|
||||
/*-<a href="qh-merge_r.htm#TOC"
|
||||
>--------------------------------</a><a name="mergeT">-</a>
|
||||
|
||||
mergeT
|
||||
structure used to merge facets
|
||||
*/
|
||||
|
||||
typedef struct mergeT mergeT;
|
||||
struct mergeT { /* initialize in qh_appendmergeset */
|
||||
realT angle; /* cosine of angle between normals of facet1 and facet2,
|
||||
null value and right angle is 0.0, coplanar is 1.0, narrow is -1.0 */
|
||||
realT distance; /* absolute value of distance between vertices, centrum and facet, or vertex and facet */
|
||||
facetT *facet1; /* will merge facet1 into facet2 */
|
||||
facetT *facet2;
|
||||
vertexT *vertex1; /* will merge vertext1 into vertex2 for MRGsubridge or MRGvertices */
|
||||
vertexT *vertex2;
|
||||
ridgeT *ridge1; /* the duplicate ridges resolved by MRGvertices */
|
||||
ridgeT *ridge2; /* merge is deleted if either ridge is deleted (qh_delridge) */
|
||||
mergeType mergetype;
|
||||
};
|
||||
|
||||
|
||||
/*=========== -macros- =========================*/
|
||||
|
||||
/*-<a href="qh-merge_r.htm#TOC"
|
||||
>--------------------------------</a><a name="FOREACHmerge_">-</a>
|
||||
|
||||
FOREACHmerge_( merges ) {...}
|
||||
assign 'merge' to each merge in merges
|
||||
|
||||
notes:
|
||||
uses 'mergeT *merge, **mergep;'
|
||||
if qh_mergefacet(),
|
||||
restart or use qh_setdellast() since qh.facet_mergeset may change
|
||||
see <a href="qset_r.h#FOREACHsetelement_">FOREACHsetelement_</a>
|
||||
*/
|
||||
#define FOREACHmerge_(merges) FOREACHsetelement_(mergeT, merges, merge)
|
||||
|
||||
/*-<a href="qh-poly_r.htm#TOC"
|
||||
>--------------------------------</a><a name="FOREACHmergeA_">-</a>
|
||||
|
||||
FOREACHmergeA_( vertices ) { ... }
|
||||
assign 'mergeA' to each merge in merges
|
||||
|
||||
notes:
|
||||
uses 'mergeT *mergeA, *mergeAp;'
|
||||
see <a href="qset_r.h#FOREACHsetelement_">FOREACHsetelement_</a>
|
||||
*/
|
||||
#define FOREACHmergeA_(merges) FOREACHsetelement_(mergeT, merges, mergeA)
|
||||
|
||||
/*-<a href="qh-poly_r.htm#TOC"
|
||||
>--------------------------------</a><a name="FOREACHmerge_i_">-</a>
|
||||
|
||||
FOREACHmerge_i_(qh, vertices ) { ... }
|
||||
assign 'merge' and 'merge_i' for each merge in mergeset
|
||||
|
||||
declare:
|
||||
mergeT *merge;
|
||||
int merge_n, merge_i;
|
||||
|
||||
see:
|
||||
<a href="qset_r.h#FOREACHsetelement_i_">FOREACHsetelement_i_</a>
|
||||
*/
|
||||
#define FOREACHmerge_i_(qh, mergeset) FOREACHsetelement_i_(qh, mergeT, mergeset, merge)
|
||||
|
||||
/*============ prototypes in alphabetical order after pre/postmerge =======*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void qh_premerge(qhT *qh, int apexpointid, realT maxcentrum, realT maxangle);
|
||||
void qh_postmerge(qhT *qh, const char *reason, realT maxcentrum, realT maxangle,
|
||||
boolT vneighbors);
|
||||
void qh_all_merges(qhT *qh, boolT othermerge, boolT vneighbors);
|
||||
void qh_all_vertexmerges(qhT *qh, int apexpointid, facetT *facet, facetT **retryfacet);
|
||||
void qh_appendmergeset(qhT *qh, facetT *facet, facetT *neighbor, mergeType mergetype, coordT dist, realT angle);
|
||||
void qh_appendvertexmerge(qhT *qh, vertexT *vertex, vertexT *destination, mergeType mergetype, realT distance, ridgeT *ridge1, ridgeT *ridge2);
|
||||
setT *qh_basevertices(qhT *qh, facetT *samecycle);
|
||||
void qh_check_dupridge(qhT *qh, facetT *facet1, realT dist1, facetT *facet2, realT dist2);
|
||||
void qh_checkconnect(qhT *qh /* qh.new_facets */);
|
||||
void qh_checkdelfacet(qhT *qh, facetT *facet, setT *mergeset);
|
||||
void qh_checkdelridge(qhT *qh /* qh.visible_facets, vertex_mergeset */);
|
||||
boolT qh_checkzero(qhT *qh, boolT testall);
|
||||
int qh_compare_anglemerge(const void *p1, const void *p2);
|
||||
int qh_compare_facetmerge(const void *p1, const void *p2);
|
||||
int qh_comparevisit(const void *p1, const void *p2);
|
||||
void qh_copynonconvex(qhT *qh, ridgeT *atridge);
|
||||
void qh_degen_redundant_facet(qhT *qh, facetT *facet);
|
||||
void qh_drop_mergevertex(qhT *qh, mergeT *merge);
|
||||
void qh_delridge_merge(qhT *qh, ridgeT *ridge);
|
||||
vertexT *qh_find_newvertex(qhT *qh, vertexT *oldvertex, setT *vertices, setT *ridges);
|
||||
vertexT *qh_findbest_pinchedvertex(qhT *qh, mergeT *merge, vertexT *apex, vertexT **pinchedp, realT *distp /* qh.newfacet_list */);
|
||||
vertexT *qh_findbest_ridgevertex(qhT *qh, ridgeT *ridge, vertexT **pinchedp, coordT *distp);
|
||||
void qh_findbest_test(qhT *qh, boolT testcentrum, facetT *facet, facetT *neighbor,
|
||||
facetT **bestfacet, realT *distp, realT *mindistp, realT *maxdistp);
|
||||
facetT *qh_findbestneighbor(qhT *qh, facetT *facet, realT *distp, realT *mindistp, realT *maxdistp);
|
||||
void qh_flippedmerges(qhT *qh, facetT *facetlist, boolT *wasmerge);
|
||||
void qh_forcedmerges(qhT *qh, boolT *wasmerge);
|
||||
void qh_freemergesets(qhT *qh);
|
||||
void qh_getmergeset(qhT *qh, facetT *facetlist);
|
||||
void qh_getmergeset_initial(qhT *qh, facetT *facetlist);
|
||||
boolT qh_getpinchedmerges(qhT *qh, vertexT *apex, coordT maxdupdist, boolT *iscoplanar /* qh.newfacet_list, vertex_mergeset */);
|
||||
boolT qh_hasmerge(setT *mergeset, mergeType type, facetT *facetA, facetT *facetB);
|
||||
void qh_hashridge(qhT *qh, setT *hashtable, int hashsize, ridgeT *ridge, vertexT *oldvertex);
|
||||
ridgeT *qh_hashridge_find(qhT *qh, setT *hashtable, int hashsize, ridgeT *ridge,
|
||||
vertexT *vertex, vertexT *oldvertex, int *hashslot);
|
||||
void qh_initmergesets(qhT *qh);
|
||||
void qh_makeridges(qhT *qh, facetT *facet);
|
||||
void qh_mark_dupridges(qhT *qh, facetT *facetlist, boolT allmerges);
|
||||
void qh_maybe_duplicateridge(qhT *qh, ridgeT *ridge);
|
||||
void qh_maybe_duplicateridges(qhT *qh, facetT *facet);
|
||||
void qh_maydropneighbor(qhT *qh, facetT *facet);
|
||||
int qh_merge_degenredundant(qhT *qh);
|
||||
void qh_merge_nonconvex(qhT *qh, facetT *facet1, facetT *facet2, mergeType mergetype);
|
||||
void qh_merge_pinchedvertices(qhT *qh, int apexpointid /* qh.newfacet_list */);
|
||||
void qh_merge_twisted(qhT *qh, facetT *facet1, facetT *facet2);
|
||||
void qh_mergecycle(qhT *qh, facetT *samecycle, facetT *newfacet);
|
||||
void qh_mergecycle_all(qhT *qh, facetT *facetlist, boolT *wasmerge);
|
||||
void qh_mergecycle_facets(qhT *qh, facetT *samecycle, facetT *newfacet);
|
||||
void qh_mergecycle_neighbors(qhT *qh, facetT *samecycle, facetT *newfacet);
|
||||
void qh_mergecycle_ridges(qhT *qh, facetT *samecycle, facetT *newfacet);
|
||||
void qh_mergecycle_vneighbors(qhT *qh, facetT *samecycle, facetT *newfacet);
|
||||
void qh_mergefacet(qhT *qh, facetT *facet1, facetT *facet2, mergeType mergetype, realT *mindist, realT *maxdist, boolT mergeapex);
|
||||
void qh_mergefacet2d(qhT *qh, facetT *facet1, facetT *facet2);
|
||||
void qh_mergeneighbors(qhT *qh, facetT *facet1, facetT *facet2);
|
||||
void qh_mergeridges(qhT *qh, facetT *facet1, facetT *facet2);
|
||||
void qh_mergesimplex(qhT *qh, facetT *facet1, facetT *facet2, boolT mergeapex);
|
||||
void qh_mergevertex_del(qhT *qh, vertexT *vertex, facetT *facet1, facetT *facet2);
|
||||
void qh_mergevertex_neighbors(qhT *qh, facetT *facet1, facetT *facet2);
|
||||
void qh_mergevertices(qhT *qh, setT *vertices1, setT **vertices);
|
||||
setT *qh_neighbor_intersections(qhT *qh, vertexT *vertex);
|
||||
setT *qh_neighbor_vertices(qhT *qh, vertexT *vertex, setT *subridge);
|
||||
void qh_neighbor_vertices_facet(qhT *qh, vertexT *vertexA, facetT *facet, setT **vertices);
|
||||
void qh_newvertices(qhT *qh, setT *vertices);
|
||||
mergeT *qh_next_vertexmerge(qhT *qh);
|
||||
facetT *qh_opposite_horizonfacet(qhT *qh, mergeT *merge, vertexT **vertex);
|
||||
boolT qh_reducevertices(qhT *qh);
|
||||
vertexT *qh_redundant_vertex(qhT *qh, vertexT *vertex);
|
||||
boolT qh_remove_extravertices(qhT *qh, facetT *facet);
|
||||
void qh_remove_mergetype(qhT *qh, setT *mergeset, mergeType type);
|
||||
void qh_rename_adjacentvertex(qhT *qh, vertexT *oldvertex, vertexT *newvertex, realT dist);
|
||||
vertexT *qh_rename_sharedvertex(qhT *qh, vertexT *vertex, facetT *facet);
|
||||
boolT qh_renameridgevertex(qhT *qh, ridgeT *ridge, vertexT *oldvertex, vertexT *newvertex);
|
||||
void qh_renamevertex(qhT *qh, vertexT *oldvertex, vertexT *newvertex, setT *ridges,
|
||||
facetT *oldfacet, facetT *neighborA);
|
||||
boolT qh_test_appendmerge(qhT *qh, facetT *facet, facetT *neighbor, boolT simplicial);
|
||||
void qh_test_degen_neighbors(qhT *qh, facetT *facet);
|
||||
boolT qh_test_centrum_merge(qhT *qh, facetT *facet, facetT *neighbor, realT angle, boolT okangle);
|
||||
boolT qh_test_nonsimplicial_merge(qhT *qh, facetT *facet, facetT *neighbor, realT angle, boolT okangle);
|
||||
void qh_test_redundant_neighbors(qhT *qh, facetT *facet);
|
||||
boolT qh_test_vneighbors(qhT *qh /* qh.newfacet_list */);
|
||||
void qh_tracemerge(qhT *qh, facetT *facet1, facetT *facet2, mergeType mergetype);
|
||||
void qh_tracemerging(qhT *qh);
|
||||
void qh_undo_newfacets(qhT *qh);
|
||||
void qh_updatetested(qhT *qh, facetT *facet1, facetT *facet2);
|
||||
setT *qh_vertexridges(qhT *qh, vertexT *vertex, boolT allneighbors);
|
||||
void qh_vertexridges_facet(qhT *qh, vertexT *vertex, facetT *facet, setT **ridges);
|
||||
void qh_willdelete(qhT *qh, facetT *facet, facetT *replace);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* qhDEFmerge */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,310 @@
|
||||
/*<html><pre> -<a href="qh-poly_r.htm"
|
||||
>-------------------------------</a><a name="TOP">-</a>
|
||||
|
||||
poly_r.h
|
||||
header file for poly_r.c and poly2_r.c
|
||||
|
||||
see qh-poly_r.htm, libqhull_r.h and poly_r.c
|
||||
|
||||
Copyright (c) 1993-2020 The Geometry Center.
|
||||
$Id: //main/2019/qhull/src/libqhull_r/poly_r.h#5 $$Change: 2963 $
|
||||
$DateTime: 2020/06/03 19:31:01 $$Author: bbarber $
|
||||
*/
|
||||
|
||||
#ifndef qhDEFpoly
|
||||
#define qhDEFpoly 1
|
||||
|
||||
#include "libqhull_r.h"
|
||||
|
||||
/*=============== constants ========================== */
|
||||
|
||||
/*-<a href="qh-geom_r.htm#TOC"
|
||||
>--------------------------------</a><a name="ALGORITHMfault">-</a>
|
||||
|
||||
qh_ALGORITHMfault
|
||||
use as argument to checkconvex() to report errors during buildhull
|
||||
*/
|
||||
#define qh_ALGORITHMfault 0
|
||||
|
||||
/*-<a href="qh-poly_r.htm#TOC"
|
||||
>--------------------------------</a><a name="DATAfault">-</a>
|
||||
|
||||
qh_DATAfault
|
||||
use as argument to checkconvex() to report errors during initialhull
|
||||
*/
|
||||
#define qh_DATAfault 1
|
||||
|
||||
/*-<a href="qh-poly_r.htm#TOC"
|
||||
>--------------------------------</a><a name="DUPLICATEridge">-</a>
|
||||
|
||||
qh_DUPLICATEridge
|
||||
special value for facet->neighbor to indicate a duplicate ridge
|
||||
|
||||
notes:
|
||||
set by qh_matchneighbor for qh_matchdupridge
|
||||
*/
|
||||
#define qh_DUPLICATEridge (facetT *)1L
|
||||
|
||||
/*-<a href="qh-poly_r.htm#TOC"
|
||||
>--------------------------------</a><a name="MERGEridge">-</a>
|
||||
|
||||
qh_MERGEridge flag in facet
|
||||
special value for facet->neighbor to indicate a duplicate ridge that needs merging
|
||||
|
||||
notes:
|
||||
set by qh_matchnewfacets..qh_matchdupridge from qh_DUPLICATEridge
|
||||
used by qh_mark_dupridges to set facet->mergeridge, facet->mergeridge2 from facet->dupridge
|
||||
*/
|
||||
#define qh_MERGEridge (facetT *)2L
|
||||
|
||||
|
||||
/*============ -structures- ====================*/
|
||||
|
||||
/*=========== -macros- =========================*/
|
||||
|
||||
/*-<a href="qh-poly_r.htm#TOC"
|
||||
>--------------------------------</a><a name="FORALLfacet_">-</a>
|
||||
|
||||
FORALLfacet_( facetlist ) { ... }
|
||||
assign 'facet' to each facet in facetlist
|
||||
|
||||
notes:
|
||||
uses 'facetT *facet;'
|
||||
assumes last facet is a sentinel
|
||||
|
||||
see:
|
||||
FORALLfacets
|
||||
*/
|
||||
#define FORALLfacet_( facetlist ) if (facetlist) for ( facet=(facetlist); facet && facet->next; facet= facet->next )
|
||||
|
||||
/*-<a href="qh-poly_r.htm#TOC"
|
||||
>--------------------------------</a><a name="FORALLnew_facets">-</a>
|
||||
|
||||
FORALLnew_facets { ... }
|
||||
assign 'newfacet' to each facet in qh.newfacet_list
|
||||
|
||||
notes:
|
||||
uses 'facetT *newfacet;'
|
||||
at exit, newfacet==NULL
|
||||
*/
|
||||
#define FORALLnew_facets for ( newfacet=qh->newfacet_list; newfacet && newfacet->next; newfacet=newfacet->next )
|
||||
|
||||
/*-<a href="qh-poly_r.htm#TOC"
|
||||
>--------------------------------</a><a name="FORALLvertex_">-</a>
|
||||
|
||||
FORALLvertex_( vertexlist ) { ... }
|
||||
assign 'vertex' to each vertex in vertexlist
|
||||
|
||||
notes:
|
||||
uses 'vertexT *vertex;'
|
||||
at exit, vertex==NULL
|
||||
*/
|
||||
#define FORALLvertex_( vertexlist ) for (vertex=( vertexlist );vertex && vertex->next;vertex= vertex->next )
|
||||
|
||||
/*-<a href="qh-poly_r.htm#TOC"
|
||||
>--------------------------------</a><a name="FORALLvisible_facets">-</a>
|
||||
|
||||
FORALLvisible_facets { ... }
|
||||
assign 'visible' to each visible facet in qh.visible_list
|
||||
|
||||
notes:
|
||||
uses 'vacetT *visible;'
|
||||
at exit, visible==NULL
|
||||
*/
|
||||
#define FORALLvisible_facets for (visible=qh->visible_list; visible && visible->visible; visible= visible->next)
|
||||
|
||||
/*-<a href="qh-poly_r.htm#TOC"
|
||||
>--------------------------------</a><a name="FORALLsame_">-</a>
|
||||
|
||||
FORALLsame_( newfacet ) { ... }
|
||||
assign 'same' to each facet in newfacet->f.samecycle
|
||||
|
||||
notes:
|
||||
uses 'facetT *same;'
|
||||
stops when it returns to newfacet
|
||||
*/
|
||||
#define FORALLsame_(newfacet) for (same= newfacet->f.samecycle; same != newfacet; same= same->f.samecycle)
|
||||
|
||||
/*-<a href="qh-poly_r.htm#TOC"
|
||||
>--------------------------------</a><a name="FORALLsame_cycle_">-</a>
|
||||
|
||||
FORALLsame_cycle_( newfacet ) { ... }
|
||||
assign 'same' to each facet in newfacet->f.samecycle
|
||||
|
||||
notes:
|
||||
uses 'facetT *same;'
|
||||
at exit, same == NULL
|
||||
*/
|
||||
#define FORALLsame_cycle_(newfacet) \
|
||||
for (same= newfacet->f.samecycle; \
|
||||
same; same= (same == newfacet ? NULL : same->f.samecycle))
|
||||
|
||||
/*-<a href="qh-poly_r.htm#TOC"
|
||||
>--------------------------------</a><a name="FOREACHneighborA_">-</a>
|
||||
|
||||
FOREACHneighborA_( facet ) { ... }
|
||||
assign 'neighborA' to each neighbor in facet->neighbors
|
||||
|
||||
FOREACHneighborA_( vertex ) { ... }
|
||||
assign 'neighborA' to each neighbor in vertex->neighbors
|
||||
|
||||
declare:
|
||||
facetT *neighborA, **neighborAp;
|
||||
|
||||
see:
|
||||
<a href="qset_r.h#FOREACHsetelement_">FOREACHsetelement_</a>
|
||||
*/
|
||||
#define FOREACHneighborA_(facet) FOREACHsetelement_(facetT, facet->neighbors, neighborA)
|
||||
|
||||
/*-<a href="qh-poly_r.htm#TOC"
|
||||
>--------------------------------</a><a name="FOREACHvisible_">-</a>
|
||||
|
||||
FOREACHvisible_( facets ) { ... }
|
||||
assign 'visible' to each facet in facets
|
||||
|
||||
notes:
|
||||
uses 'facetT *facet, *facetp;'
|
||||
see <a href="qset_r.h#FOREACHsetelement_">FOREACHsetelement_</a>
|
||||
*/
|
||||
#define FOREACHvisible_(facets) FOREACHsetelement_(facetT, facets, visible)
|
||||
|
||||
/*-<a href="qh-poly_r.htm#TOC"
|
||||
>--------------------------------</a><a name="FOREACHnewfacet_">-</a>
|
||||
|
||||
FOREACHnewfacet_( facets ) { ... }
|
||||
assign 'newfacet' to each facet in facets
|
||||
|
||||
notes:
|
||||
uses 'facetT *newfacet, *newfacetp;'
|
||||
see <a href="qset_r.h#FOREACHsetelement_">FOREACHsetelement_</a>
|
||||
*/
|
||||
#define FOREACHnewfacet_(facets) FOREACHsetelement_(facetT, facets, newfacet)
|
||||
|
||||
/*-<a href="qh-poly_r.htm#TOC"
|
||||
>--------------------------------</a><a name="FOREACHvertexA_">-</a>
|
||||
|
||||
FOREACHvertexA_( vertices ) { ... }
|
||||
assign 'vertexA' to each vertex in vertices
|
||||
|
||||
notes:
|
||||
uses 'vertexT *vertexA, *vertexAp;'
|
||||
see <a href="qset_r.h#FOREACHsetelement_">FOREACHsetelement_</a>
|
||||
*/
|
||||
#define FOREACHvertexA_(vertices) FOREACHsetelement_(vertexT, vertices, vertexA)
|
||||
|
||||
/*-<a href="qh-poly_r.htm#TOC"
|
||||
>--------------------------------</a><a name="FOREACHvertexreverse12_">-</a>
|
||||
|
||||
FOREACHvertexreverse12_( vertices ) { ... }
|
||||
assign 'vertex' to each vertex in vertices
|
||||
reverse order of first two vertices
|
||||
|
||||
notes:
|
||||
uses 'vertexT *vertex, *vertexp;'
|
||||
see <a href="qset_r.h#FOREACHsetelement_">FOREACHsetelement_</a>
|
||||
*/
|
||||
#define FOREACHvertexreverse12_(vertices) FOREACHsetelementreverse12_(vertexT, vertices, vertex)
|
||||
|
||||
|
||||
/*=============== prototypes poly_r.c in alphabetical order ================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void qh_appendfacet(qhT *qh, facetT *facet);
|
||||
void qh_appendvertex(qhT *qh, vertexT *vertex);
|
||||
void qh_attachnewfacets(qhT *qh /* qh.visible_list, qh.newfacet_list */);
|
||||
boolT qh_checkflipped(qhT *qh, facetT *facet, realT *dist, boolT allerror);
|
||||
void qh_delfacet(qhT *qh, facetT *facet);
|
||||
void qh_deletevisible(qhT *qh /* qh.visible_list, qh.horizon_list */);
|
||||
setT *qh_facetintersect(qhT *qh, facetT *facetA, facetT *facetB, int *skipAp,int *skipBp, int extra);
|
||||
int qh_gethash(qhT *qh, int hashsize, setT *set, int size, int firstindex, void *skipelem);
|
||||
facetT *qh_getreplacement(qhT *qh, facetT *visible);
|
||||
facetT *qh_makenewfacet(qhT *qh, setT *vertices, boolT toporient, facetT *facet);
|
||||
void qh_makenewplanes(qhT *qh /* qh.newfacet_list */);
|
||||
facetT *qh_makenew_nonsimplicial(qhT *qh, facetT *visible, vertexT *apex, int *numnew);
|
||||
facetT *qh_makenew_simplicial(qhT *qh, facetT *visible, vertexT *apex, int *numnew);
|
||||
void qh_matchneighbor(qhT *qh, facetT *newfacet, int newskip, int hashsize,
|
||||
int *hashcount);
|
||||
coordT qh_matchnewfacets(qhT *qh);
|
||||
boolT qh_matchvertices(qhT *qh, int firstindex, setT *verticesA, int skipA,
|
||||
setT *verticesB, int *skipB, boolT *same);
|
||||
facetT *qh_newfacet(qhT *qh);
|
||||
ridgeT *qh_newridge(qhT *qh);
|
||||
int qh_pointid(qhT *qh, pointT *point);
|
||||
void qh_removefacet(qhT *qh, facetT *facet);
|
||||
void qh_removevertex(qhT *qh, vertexT *vertex);
|
||||
void qh_update_vertexneighbors(qhT *qh);
|
||||
void qh_update_vertexneighbors_cone(qhT *qh);
|
||||
|
||||
|
||||
/*========== -prototypes poly2_r.c in alphabetical order ===========*/
|
||||
|
||||
boolT qh_addfacetvertex(qhT *qh, facetT *facet, vertexT *newvertex);
|
||||
void qh_addhash(void *newelem, setT *hashtable, int hashsize, int hash);
|
||||
void qh_check_bestdist(qhT *qh);
|
||||
void qh_check_maxout(qhT *qh);
|
||||
void qh_check_output(qhT *qh);
|
||||
void qh_check_point(qhT *qh, pointT *point, facetT *facet, realT *maxoutside, realT *maxdist, facetT **errfacet1, facetT **errfacet2, int *errcount);
|
||||
void qh_check_points(qhT *qh);
|
||||
void qh_checkconvex(qhT *qh, facetT *facetlist, int fault);
|
||||
void qh_checkfacet(qhT *qh, facetT *facet, boolT newmerge, boolT *waserrorp);
|
||||
void qh_checkflipped_all(qhT *qh, facetT *facetlist);
|
||||
boolT qh_checklists(qhT *qh, facetT *facetlist);
|
||||
void qh_checkpolygon(qhT *qh, facetT *facetlist);
|
||||
void qh_checkvertex(qhT *qh, vertexT *vertex, boolT allchecks, boolT *waserrorp);
|
||||
void qh_clearcenters(qhT *qh, qh_CENTER type);
|
||||
void qh_createsimplex(qhT *qh, setT *vertices);
|
||||
void qh_delridge(qhT *qh, ridgeT *ridge);
|
||||
void qh_delvertex(qhT *qh, vertexT *vertex);
|
||||
setT *qh_facet3vertex(qhT *qh, facetT *facet);
|
||||
facetT *qh_findbestfacet(qhT *qh, pointT *point, boolT bestoutside,
|
||||
realT *bestdist, boolT *isoutside);
|
||||
facetT *qh_findbestlower(qhT *qh, facetT *upperfacet, pointT *point, realT *bestdistp, int *numpart);
|
||||
facetT *qh_findfacet_all(qhT *qh, pointT *point, boolT noupper, realT *bestdist, boolT *isoutside,
|
||||
int *numpart);
|
||||
int qh_findgood(qhT *qh, facetT *facetlist, int goodhorizon);
|
||||
void qh_findgood_all(qhT *qh, facetT *facetlist);
|
||||
void qh_furthestnext(qhT *qh /* qh.facet_list */);
|
||||
void qh_furthestout(qhT *qh, facetT *facet);
|
||||
void qh_infiniteloop(qhT *qh, facetT *facet);
|
||||
void qh_initbuild(qhT *qh);
|
||||
void qh_initialhull(qhT *qh, setT *vertices);
|
||||
setT *qh_initialvertices(qhT *qh, int dim, setT *maxpoints, pointT *points, int numpoints);
|
||||
vertexT *qh_isvertex(pointT *point, setT *vertices);
|
||||
vertexT *qh_makenewfacets(qhT *qh, pointT *point /* qh.horizon_list, visible_list */);
|
||||
coordT qh_matchdupridge(qhT *qh, facetT *atfacet, int atskip, int hashsize, int *hashcount);
|
||||
void qh_nearcoplanar(qhT *qh /* qh.facet_list */);
|
||||
vertexT *qh_nearvertex(qhT *qh, facetT *facet, pointT *point, realT *bestdistp);
|
||||
int qh_newhashtable(qhT *qh, int newsize);
|
||||
vertexT *qh_newvertex(qhT *qh, pointT *point);
|
||||
facetT *qh_nextfacet2d(facetT *facet, vertexT **nextvertexp);
|
||||
ridgeT *qh_nextridge3d(ridgeT *atridge, facetT *facet, vertexT **vertexp);
|
||||
vertexT *qh_opposite_vertex(qhT *qh, facetT *facetA, facetT *neighbor);
|
||||
void qh_outcoplanar(qhT *qh /* qh.facet_list */);
|
||||
pointT *qh_point(qhT *qh, int id);
|
||||
void qh_point_add(qhT *qh, setT *set, pointT *point, void *elem);
|
||||
setT *qh_pointfacet(qhT *qh /* qh.facet_list */);
|
||||
setT *qh_pointvertex(qhT *qh /* qh.facet_list */);
|
||||
void qh_prependfacet(qhT *qh, facetT *facet, facetT **facetlist);
|
||||
void qh_printhashtable(qhT *qh, FILE *fp);
|
||||
void qh_printlists(qhT *qh);
|
||||
void qh_replacefacetvertex(qhT *qh, facetT *facet, vertexT *oldvertex, vertexT *newvertex);
|
||||
void qh_resetlists(qhT *qh, boolT stats, boolT resetVisible /* qh.newvertex_list qh.newfacet_list qh.visible_list */);
|
||||
void qh_setvoronoi_all(qhT *qh);
|
||||
void qh_triangulate(qhT *qh /* qh.facet_list */);
|
||||
void qh_triangulate_facet(qhT *qh, facetT *facetA, vertexT **first_vertex);
|
||||
void qh_triangulate_link(qhT *qh, facetT *oldfacetA, facetT *facetA, facetT *oldfacetB, facetT *facetB);
|
||||
void qh_triangulate_mirror(qhT *qh, facetT *facetA, facetT *facetB);
|
||||
void qh_triangulate_null(qhT *qh, facetT *facetA);
|
||||
void qh_vertexintersect(qhT *qh, setT **vertexsetA,setT *vertexsetB);
|
||||
setT *qh_vertexintersect_new(qhT *qh, setT *vertexsetA,setT *vertexsetB);
|
||||
void qh_vertexneighbors(qhT *qh /* qh.facet_list */);
|
||||
boolT qh_vertexsubset(setT *vertexsetA, setT *vertexsetB);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* qhDEFpoly */
|
||||
@@ -0,0 +1,303 @@
|
||||
<!-- Do not edit with Front Page, it adds too many spaces -->
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type"
|
||||
content="text/html; charset=iso-8859-1">
|
||||
<title>geom_r.c, geom2_r.c -- geometric and floating point routines</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- Navigation links -->
|
||||
<p><a name="TOP"><b>Up:</b></a> <a
|
||||
href="http://www.qhull.org">Home page</a> for Qhull (<a href="../index.htm">local</a>)<br>
|
||||
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: contents <br>
|
||||
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
|
||||
• <a href="../../html/qh-quick.htm#options">Options</a>
|
||||
• <a href="../../html/qh-opto.htm#output">Output</a>
|
||||
• <a href="../../html/qh-optf.htm#format">Formats</a>
|
||||
• <a href="../../html/qh-optg.htm#geomview">Geomview</a>
|
||||
• <a href="../../html/qh-optp.htm#print">Print</a>
|
||||
• <a href="../../html/qh-optq.htm#qhull">Qhull</a>
|
||||
• <a href="../../html/qh-optc.htm#prec">Precision</a>
|
||||
• <a href="../../html/qh-optt.htm#trace">Trace</a>
|
||||
• <a href="http://www.qhull.org/src/libqhull_r/index.htm">Functions</a> (<a href="index.htm">local</a>)<br>
|
||||
<b>Up:</b> <a href="../../html/qh-code.htm">Qhull code</a><br>
|
||||
<b>To:</b> <a href="qh-geom_r.htm#TOC">Geom</a> • <a href="qh-globa_r.htm">Global</a>
|
||||
• <a href="qh-io_r.htm">Io</a> • <a href="qh-mem_r.htm">Mem</a>
|
||||
• <a href="qh-merge_r.htm">Merge</a> • <a href="qh-poly_r.htm">Poly</a>
|
||||
• <a href="qh-qhull_r.htm">Qhull</a> • <a href="qh-set_r.htm">Set</a>
|
||||
• <a href="qh-stat_r.htm">Stat</a> • <a href="qh-user_r.htm">User</a>
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
<!-- Main text of document. -->
|
||||
|
||||
<h2>geom_r.c, geom2_r.c, random_r.c -- geometric and floating point routines</h2>
|
||||
<blockquote>
|
||||
<p>Geometrically, a vertex is a point with <em>d</em> coordinates
|
||||
and a facet is a halfspace. A <em>halfspace</em> is defined by an
|
||||
oriented hyperplane through the facet's vertices. A <em>hyperplane</em>
|
||||
is defined by <em>d</em> normalized coefficients and an offset. A
|
||||
point is <em>above</em> a facet if its distance to the facet is
|
||||
positive.</p>
|
||||
|
||||
<p>Qhull uses floating point coordinates for input points,
|
||||
vertices, halfspace equations, centrums, and an interior point.</p>
|
||||
|
||||
<p>Qhull may be configured for single precision or double
|
||||
precision floating point arithmetic (see <a href="user_r.h#realT">realT</a>
|
||||
). </p>
|
||||
|
||||
<p>Each floating point operation may incur round-off error (see
|
||||
<a href="qh-merge_r.htm#TOC">Merge</a>). The maximum error for distance
|
||||
computations is determined at initialization. The roundoff error
|
||||
in halfspace computation is accounted for by computing the
|
||||
distance from vertices to the halfspace. </p>
|
||||
</blockquote>
|
||||
<p><b>Copyright © 1995-2020 C.B. Barber</b></p>
|
||||
<hr>
|
||||
<p><a href="#TOP">»</a> <b>Geom</b>
|
||||
<a name="TOC">•</a> <a href="qh-globa_r.htm#TOC">Global</a> •
|
||||
<a href="qh-io_r.htm#TOC">Io</a> • <a href="qh-mem_r.htm#TOC">Mem</a> •
|
||||
<a href="qh-merge_r.htm#TOC">Merge</a> • <a href="qh-poly_r.htm#TOC">Poly</a> •
|
||||
<a href="qh-qhull_r.htm#TOC">Qhull</a> • <a href="qh-set_r.htm#TOC">Set</a> •
|
||||
<a href="qh-stat_r.htm#TOC">Stat</a> • <a href="qh-user_r.htm#TOC">User</a> </p>
|
||||
|
||||
<h3>Index to <a href="geom_r.c">geom_r.c</a>,
|
||||
<a href="geom2_r.c">geom2_r.c</a>, <a href="geom_r.h">geom_r.h</a>,
|
||||
<a href="random_r.c">random_r.c</a>, <a href="random_r.h">random_r.h</a>
|
||||
</h3>
|
||||
|
||||
<ul>
|
||||
<li><a href="#gtype">geometric data types and constants</a> </li>
|
||||
<li><a href="#gmacro">mathematical macros</a>
|
||||
</li>
|
||||
<li><a href="#gmath">mathematical functions</a> </li>
|
||||
<li><a href="#gcomp">computational geometry functions</a> </li>
|
||||
<li><a href="#gpoint">point array functions</a> </li>
|
||||
<li><a href="#gfacet">geometric facet functions</a> </li>
|
||||
<li><a href="#ground">geometric roundoff functions</a></li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-geom_r.htm#TOC">»</a><a name="gtype">geometric data types
|
||||
and constants</a></h3>
|
||||
|
||||
<ul>
|
||||
<li><a href="libqhull_r.h#coordT">coordT</a> coordinates and
|
||||
coefficients are stored as realT</li>
|
||||
<li><a href="libqhull_r.h#pointT">pointT</a> a point is an array
|
||||
of <tt>DIM3</tt> coordinates </li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-geom_r.htm#TOC">»</a><a name="gmacro">mathematical macros</a></h3>
|
||||
|
||||
<ul>
|
||||
<li><a href="geom_r.h#fabs_">fabs_</a> returns the absolute
|
||||
value of a </li>
|
||||
<li><a href="geom_r.h#fmax_">fmax_</a> returns the maximum
|
||||
value of a and b </li>
|
||||
<li><a href="geom_r.h#fmin_">fmin_</a> returns the minimum
|
||||
value of a and b </li>
|
||||
<li><a href="geom_r.h#maximize_">maximize_</a> maximize a value
|
||||
</li>
|
||||
<li><a href="geom_r.h#minimize_">minimize_</a> minimize a value
|
||||
</li>
|
||||
<li><a href="geom_r.h#det2_">det2_</a> compute a 2-d
|
||||
determinate </li>
|
||||
<li><a href="geom_r.h#det3_">det3_</a> compute a 3-d
|
||||
determinate </li>
|
||||
<li><a href="geom_r.h#dX">dX, dY, dZ</a> compute the difference
|
||||
between two coordinates </li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-geom_r.htm#TOC">»</a><a name="gmath">mathematical functions</a></h3>
|
||||
|
||||
<ul>
|
||||
<li><a href="geom_r.c#backnormal">qh_backnormal</a> solve for
|
||||
normal using back substitution </li>
|
||||
<li><a href="geom2_r.c#crossproduct">qh_crossproduct</a>
|
||||
compute the cross product of two 3-d vectors </li>
|
||||
<li><a href="geom2_r.c#determinant">qh_determinant</a> compute
|
||||
the determinant of a square matrix </li>
|
||||
<li><a href="geom_r.c#gausselim">qh_gausselim</a> Gaussian
|
||||
elimination with partial pivoting </li>
|
||||
<li><a href="geom2_r.c#gram_schmidt">qh_gram_schmidt</a>
|
||||
implements Gram-Schmidt orthogonalization by rows </li>
|
||||
<li><a href="geom2_r.c#maxabsval">qh_maxabsval</a> return max
|
||||
absolute value of a vector </li>
|
||||
<li><a href="geom2_r.c#minabsval">qh_minabsval</a> return min
|
||||
absolute value of a dim vector </li>
|
||||
<li><a href="geom2_r.c#mindiff">qh_mindiff</a> return index of
|
||||
min absolute difference of two vectors </li>
|
||||
<li><a href="geom_r.c#normalize">qh_normalize</a> normalize a
|
||||
vector </li>
|
||||
<li><a href="geom_r.c#normalize2">qh_normalize2</a> normalize a
|
||||
vector and report if too small </li>
|
||||
<li><a href="geom2_r.c#printmatrix">qh_printmatrix</a> print
|
||||
matrix given by row vectors </li>
|
||||
<li><a href="random_r.c#rand">qh_rand/srand</a> generate random
|
||||
numbers </li>
|
||||
<li><a href="random_r.c#randomfactor">qh_randomfactor</a> return
|
||||
a random factor near 1.0 </li>
|
||||
<li><a href="random_r.c#randommatrix">qh_randommatrix</a>
|
||||
generate a random dimXdim matrix in range (-1,1) </li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-geom_r.htm#TOC">»</a><a name="gcomp">computational geometry functions</a></h3>
|
||||
|
||||
<ul>
|
||||
<li><a href="geom2_r.c#detsimplex">qh_detsimplex</a> compute
|
||||
determinate of a simplex of points </li>
|
||||
<li><a href="io_r.c#detvnorm">qh_detvnorm</a> determine normal for Voronoi ridge </li>
|
||||
<li><a href="geom2_r.c#distnorm">qh_distnorm</a> compute
|
||||
distance from point to hyperplane as defined by normal and offset</li>
|
||||
<li><a href="geom2_r.c#facetarea_simplex">qh_facetarea_simplex</a>
|
||||
return area of a simplex</li>
|
||||
<li><a href="geom_r.c#getangle">qh_getangle</a> return cosine
|
||||
of angle (i.e., dot product) </li>
|
||||
<li><a href="geom_r.c#getcenter">qh_getcenter</a> return
|
||||
arithmetic center for a set of vertices </li>
|
||||
<li><a href="geom2_r.c#pointdist">qh_pointdist</a> return
|
||||
distance between two points </li>
|
||||
<li><a href="geom2_r.c#rotatepoints">qh_rotatepoints</a> rotate
|
||||
numpoints points by a row matrix </li>
|
||||
<li><a href="geom2_r.c#sethalfspace">qh_sethalfspace</a> set
|
||||
coords to dual of halfspace relative to an interior point </li>
|
||||
<li><a href="geom_r.c#sethyperplane_det">qh_sethyperplane_det</a>
|
||||
return hyperplane for oriented simplex using determinates
|
||||
</li>
|
||||
<li><a href="geom_r.c#sethyperplane_gauss">qh_sethyperplane_gauss</a>
|
||||
return hyperplane for oriented simplex using Gaussian
|
||||
elimination </li>
|
||||
<li><a href="geom2_r.c#voronoi_center">qh_voronoi_center</a>
|
||||
return Voronoi center for a set of points </li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-geom_r.htm#TOC">»</a><a name="gpoint">point array functions</a></h3>
|
||||
<ul>
|
||||
<li><a href="geom2_r.c#copypoints">qh_copypoints</a> return
|
||||
malloc'd copy of points</li>
|
||||
<li><a href="geom2_r.c#joggleinput">qh_joggleinput</a> joggle
|
||||
input points by qh.JOGGLEmax </li>
|
||||
<li><a href="geom2_r.c#maxmin">qh_maxmin</a> return max/min
|
||||
points for each dimension</li>
|
||||
<li><a href="geom2_r.c#maxsimplex">qh_maxsimplex</a> determines
|
||||
maximum simplex for a set of points </li>
|
||||
<li><a href="geom2_r.c#printpoints">qh_printpoints</a> print ids for a
|
||||
set of points </li>
|
||||
<li><a href="geom2_r.c#projectinput">qh_projectinput</a> project
|
||||
input using qh DELAUNAY and qh low_bound/high_bound </li>
|
||||
<li><a href="geom2_r.c#projectpoints">qh_projectpoints</a>
|
||||
project points along one or more dimensions </li>
|
||||
<li><a href="geom2_r.c#rotateinput">qh_rotateinput</a> rotate
|
||||
input points using row matrix </li>
|
||||
<li><a href="geom2_r.c#scaleinput">qh_scaleinput</a> scale
|
||||
input points using qh low_bound/high_bound </li>
|
||||
<li><a href="geom2_r.c#scalelast">qh_scalelast</a> scale last
|
||||
coordinate to [0,m] for Delaunay triangulations </li>
|
||||
<li><a href="geom2_r.c#scalepoints">qh_scalepoints</a> scale
|
||||
points to new lowbound and highbound </li>
|
||||
<li><a href="geom2_r.c#setdelaunay">qh_setdelaunay</a> project
|
||||
points to paraboloid for Delaunay triangulation </li>
|
||||
<li><a href="geom2_r.c#sethalfspace_all">qh_sethalfspace_all</a>
|
||||
generate dual for halfspace intersection with interior
|
||||
point </li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-geom_r.htm#TOC">»</a><a name="gfacet">geometric facet functions</a></h3>
|
||||
<ul>
|
||||
<li><a href="geom_r.c#distplane">qh_distplane</a> return
|
||||
distance from point to facet </li>
|
||||
<li><a href="geom2_r.c#facetarea">qh_facetarea</a> return area
|
||||
of a facet </li>
|
||||
<li><a href="geom2_r.c#facetcenter">qh_facetcenter</a> return
|
||||
Voronoi center for a facet's vertices </li>
|
||||
<li><a href="geom_r.c#findbest">qh_findbest</a> find visible
|
||||
facet or best facet for a point </li>
|
||||
<li><a href="geom_r.c#findbesthorizon">qh_findbesthorizon</a>
|
||||
update best new facet with horizon facets</li>
|
||||
<li><a href="geom_r.c#findbestnew">qh_findbestnew</a> find best
|
||||
new facet for point </li>
|
||||
<li><a href="geom2_r.c#furthestnewvertex">qh_furthestnewvertex</a> return
|
||||
furthest new vertex for facet </li>
|
||||
<li><a href="geom2_r.c#furthestvertex">qh_furthestvertex</a> return
|
||||
furthest vertex in facetA above facetB </li>
|
||||
<li><a href="geom2_r.c#getarea">qh_getarea</a> get area and volume of all
|
||||
facets in facetlist, collect statistics </li>
|
||||
<li><a href="geom_r.c#getcentrum">qh_getcentrum</a> return
|
||||
centrum for a facet </li>
|
||||
<li><a href="geom_r.c#getdistance">qh_getdistance</a> returns
|
||||
the max and min distance of a facet's vertices to a
|
||||
neighboring facet</li>
|
||||
<li><a href="geom2_r.c#findgooddist">qh_findgooddist</a> find
|
||||
best good facet visible for point from facet </li>
|
||||
<li><a href="geom2_r.c#inthresholds">qh_inthresholds</a> return
|
||||
True if facet normal within 'Pdn' and 'PDn'</li>
|
||||
<li><a href="geom2_r.c#orientoutside">qh_orientoutside</a>
|
||||
orient facet so that <tt>qh.interior_point</tt> is inside</li>
|
||||
<li><a href="geom_r.c#projectpoint">qh_projectpoint</a> project
|
||||
point onto a facet </li>
|
||||
<li><a href="geom_r.c#setfacetplane">qh_setfacetplane</a> sets
|
||||
the hyperplane for a facet </li>
|
||||
<li><a href="geom2_r.c#sharpnewfacets">qh_sharpnewfacets</a> true
|
||||
if new facets contains a sharp corner</li>
|
||||
<li><a href="geom2_r.c#vertex_bestdist">qh_vertex_bestdist</a>
|
||||
return nearest distance between vertices, except 'skip' </li>
|
||||
<li><a href="geom2_r.c#vertex_isbelow">qh_vertex_isbelow</a> true if
|
||||
vertexA is below vertexB's simplicial facets, or least above </li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-geom_r.htm#TOC">»</a><a name="ground">geometric roundoff functions</a></h3>
|
||||
<ul>
|
||||
<li><a href="geom2_r.c#detjoggle">qh_detjoggle</a> determine
|
||||
default joggle for points and distance roundoff error </li>
|
||||
<li><a href="geom2_r.c#detmaxoutside">qh_detmaxoutside</a>
|
||||
determine qh.MAXoutside target for qh_RATIO... tests </li>
|
||||
<li><a href="geom2_r.c#detroundoff">qh_detroundoff</a>
|
||||
determine maximum roundoff error and other precision constants </li>
|
||||
<li><a href="geom2_r.c#distround">qh_distround</a> compute
|
||||
maximum roundoff error due to a distance computation to a
|
||||
normalized hyperplane </li>
|
||||
<li><a href="geom2_r.c#divzero">qh_divzero</a> divide by a
|
||||
number that is nearly zero </li>
|
||||
<li><a href="geom2_r.c#maxouter">qh_maxouter</a> return maximum outer
|
||||
plane</li>
|
||||
<li><a href="geom2_r.c#outerinner">qh_outerinner</a> return actual
|
||||
outer and inner planes</li>
|
||||
</ul>
|
||||
|
||||
<p><!-- Navigation links --> </p>
|
||||
<hr>
|
||||
<p><b>Up:</b>
|
||||
<a href="http://www.qhull.org">Home page</a> for
|
||||
Qhull (<a href="../index.htm">local</a>) <br>
|
||||
<b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: contents<br>
|
||||
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
|
||||
• <a href="../../html/qh-quick.htm#options">Options</a>
|
||||
• <a href="../../html/qh-opto.htm#output">Output</a>
|
||||
• <a href="../../html/qh-optf.htm#format">Formats</a>
|
||||
• <a href="../../html/qh-optg.htm#geomview">Geomview</a>
|
||||
• <a href="../../html/qh-optp.htm#print">Print</a>
|
||||
• <a href="../../html/qh-optq.htm#qhull">Qhull</a>
|
||||
• <a href="../../html/qh-optc.htm#prec">Precision</a>
|
||||
• <a href="../../html/qh-optt.htm#trace">Trace</a>
|
||||
• <a href="http://www.qhull.org/src/libqhull_r/index.htm">Functions</a> (<a href="index.htm">local</a>)<br>
|
||||
<b>Up:</b> <a href="../../html/qh-code.htm">Qhull code</a> <br>
|
||||
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> •
|
||||
<a href="qh-globa_r.htm">Global</a> • <a href="qh-io_r.htm">Io</a>
|
||||
• <a href="qh-mem_r.htm">Mem</a> • <a href="qh-merge_r.htm">Merge</a>
|
||||
• <a href="qh-poly_r.htm">Poly</a> • <a href="qh-qhull_r.htm#TOC">Qhull</a>
|
||||
• <a href="qh-set_r.htm">Set</a> • <a href="qh-stat_r.htm">Stat</a>
|
||||
• <a href="qh-user_r.htm">User</a><br>
|
||||
|
||||
|
||||
<p><!-- GC common information --> </p>
|
||||
<hr>
|
||||
<p><a href="http://www.geom.uiuc.edu/"><img
|
||||
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
|
||||
Geometry Center Home Page </i></p>
|
||||
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
|
||||
<br>
|
||||
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,169 @@
|
||||
<!-- Do not edit with Front Page, it adds too many spaces -->
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type"
|
||||
content="text/html; charset=iso-8859-1">
|
||||
<title>global_r.c -- global variables and their functions</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- Navigation links -->
|
||||
<p><a name="TOP"><b>Up:</b></a> <a
|
||||
href="http://www.qhull.org">Home page</a> for Qhull (<a href="../index.htm">local</a>)<br>
|
||||
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: contents <br>
|
||||
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
|
||||
• <a href="../../html/qh-quick.htm#options">Options</a>
|
||||
• <a href="../../html/qh-opto.htm#output">Output</a>
|
||||
• <a href="../../html/qh-optf.htm#format">Formats</a>
|
||||
• <a href="../../html/qh-optg.htm#geomview">Geomview</a>
|
||||
• <a href="../../html/qh-optp.htm#print">Print</a>
|
||||
• <a href="../../html/qh-optq.htm#qhull">Qhull</a>
|
||||
• <a href="../../html/qh-optc.htm#prec">Precision</a>
|
||||
• <a href="../../html/qh-optt.htm#trace">Trace</a>
|
||||
• <a href="http://www.qhull.org/src/libqhull_r/index.htm">Functions</a> (<a href="index.htm">local</a>)<br>
|
||||
<b>Up:</b> <a href="../../html/qh-code.htm">Qhull code</a><br>
|
||||
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> • <a href="qh-globa_r.htm#TOC">Global</a>
|
||||
• <a href="qh-io_r.htm">Io</a> • <a href="qh-mem_r.htm">Mem</a>
|
||||
• <a href="qh-merge_r.htm">Merge</a> • <a href="qh-poly_r.htm">Poly</a>
|
||||
• <a href="qh-qhull_r.htm">Qhull</a> • <a href="qh-set_r.htm">Set</a>
|
||||
• <a href="qh-stat_r.htm">Stat</a> • <a href="qh-user_r.htm">User</a>
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
<!-- Main text of document. -->
|
||||
|
||||
<h2>global_r.c -- global variables and their functions</h2>
|
||||
<blockquote>
|
||||
<p>Qhull uses a data structure, <tt>qhT</tt>, to store
|
||||
globally defined constants, lists, sets, and variables. It is passed as the
|
||||
first argument to most functions.
|
||||
</p>
|
||||
</blockquote>
|
||||
<p><b>Copyright © 1995-2020 C.B. Barber</b></p>
|
||||
<hr>
|
||||
<p><a href="#TOP">»</a> <a href="qh-geom_r.htm#TOC">Geom</a>
|
||||
<a name="TOC">•</a> <b>Global</b> •
|
||||
<a href="qh-io_r.htm#TOC">Io</a> • <a href="qh-mem_r.htm#TOC">Mem</a> •
|
||||
<a href="qh-merge_r.htm#TOC">Merge</a> • <a href="qh-poly_r.htm#TOC">Poly</a> •
|
||||
<a href="qh-qhull_r.htm#TOC">Qhull</a> • <a href="qh-set_r.htm#TOC">Set</a> •
|
||||
<a href="qh-stat_r.htm#TOC">Stat</a> • <a href="qh-user_r.htm#TOC">User</a> </p>
|
||||
|
||||
<h3>Index to <a href="global_r.c">global_r.c</a> and
|
||||
<a href="libqhull_r.h">libqhull_r.h</a></h3>
|
||||
|
||||
<ul>
|
||||
<li><a href="#ovar">Qhull's global variables</a> </li>
|
||||
<li><a href="#ofunc">Global variable and initialization
|
||||
routines</a> </li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-globa_r.htm#TOC">»</a><a name="ovar">Qhull's global
|
||||
variables</a></h3>
|
||||
|
||||
<ul>
|
||||
<li><a href=global_r.c#version>qh_version</a> version string
|
||||
<li><a href="libqhull_r.h#qh">qh</a> all global variables for
|
||||
qhull are in <tt>qh,qhmem</tt>, and <tt>qhstat</tt></li>
|
||||
<li><a href="libqhull_r.h#qh">QHULL_LIB_CHECK</a> Check for compatible library</li>
|
||||
<li><a href="libqhull_r.h#qh-const">qh constants</a> configuration
|
||||
flags and constants for Qhull </li>
|
||||
<li><a href="libqhull_r.h#qh-prec">qh precision constants</a>
|
||||
precision constants for Qhull </li>
|
||||
<li><a href="libqhull_r.h#qh-codetern">qh internal constants</a>
|
||||
internal constants for Qhull </li>
|
||||
<li><a href="libqhull_r.h#qh-lists">qh facet and vertex lists</a>
|
||||
lists of facets and vertices </li>
|
||||
<li><a href="libqhull_r.h#qh-var">qh global variables</a> minimum
|
||||
and maximum distances, next visit ids, several flags, and
|
||||
other global variables. </li>
|
||||
<li><a href="libqhull_r.h#qh-set">qh global sets</a> global sets
|
||||
for merging, hashing, input, etc. </li>
|
||||
<li><a href="libqhull_r.h#qh-buf">qh global buffers</a> buffers
|
||||
for matrix operations and input </li>
|
||||
<li><a href="libqhull_r.h#qh-static">qh static variables</a>
|
||||
static variables for individual functions </li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-globa_r.htm#TOC">»</a><a name="ofunc">Global variable and
|
||||
initialization routines</a></h3>
|
||||
|
||||
<ul>
|
||||
<li><a href="global_r.c#appendprint">qh_appendprint</a> append
|
||||
output format to <tt>qh.PRINTout</tt> </li>
|
||||
<li><a href="global_r.c#checkflags">qh_checkflags</a>
|
||||
check flags for multiple frontends to qhull </li>
|
||||
<li><a href="global_r.c#clear_outputflags">qh_clear_outputflags</a> clear
|
||||
output flags for QhullPoints </li>
|
||||
<li><a href="global_r.c#freebuffers">qh_freebuffers</a> free
|
||||
global memory buffers </li>
|
||||
<li><a href="global_r.c#freebuild">qh_freebuild</a>
|
||||
free memory used by qh_initbuild and qh_buildhull </li>
|
||||
<li><a href="global_r.c#freeqhull">qh_freeqhull</a> free memory
|
||||
used by qhull </li>
|
||||
<li><a href="global_r.c#init_A">qh_init_A</a> called before
|
||||
error handling initialized </li>
|
||||
<li><a href="global_r.c#init_B">qh_init_B</a> called after
|
||||
points are defined </li>
|
||||
<li><a href="global_r.c#init_qhull_command">qh_init_qhull_command</a>
|
||||
build <tt>qh.qhull_command</tt> from <tt>argc/argv</tt></li>
|
||||
<li><a href="global_r.c#initflags">qh_initflags</a> set flags
|
||||
and constants from command line </li>
|
||||
<li><a href="global_r.c#initqhull_buffers">qh_initqhull_buffers</a>
|
||||
initialize global memory buffers </li>
|
||||
<li><a href="global_r.c#initqhull_globals">qh_initqhull_globals</a>
|
||||
initialize global variables </li>
|
||||
<li><a href="global_r.c#initqhull_mem">qh_initqhull_mem</a>
|
||||
initialize Qhull memory management </li>
|
||||
<li><a href="global_r.c#initqhull_outputflags">qh_initqhull_outputflags</a> initialize
|
||||
flags concerned with output </li>
|
||||
<li><a href="global_r.c#initqhull_start">qh_initqhull_start</a>
|
||||
allocate qh_qh and call qh_initqhull_start2()
|
||||
<li><a href="global_r.c#initqhull_start2">qh_initqhull_start2</a>
|
||||
initialize default values at Qhull startup </li>
|
||||
<li><a href="global_r.c#initthresholds">qh_initthresholds</a>
|
||||
initialize 'Pdn' and 'PDn' thresholds </li>
|
||||
<li><a href="global_r.c#lib_check">qh_lib_check</a> check for compatible Qhull library. Invoked by QHULL_LIB_CHECK at start of each program.</li>
|
||||
<li><a href="global_r.c#option">qh_option</a> append option
|
||||
description to <tt>qh.global_options</tt> </li>
|
||||
<li><a href="global_r.c#restore_qhull">qh_restore_qhull</a>
|
||||
restores a previously saved qhull </li>
|
||||
<li><a href="global_r.c#save_qhull">qh_save_qhull</a> saves
|
||||
qhull for a later qh_restore_qhull() </li>
|
||||
<li><a href="global_r.c#strtol">qh_strtol</a> duplicates
|
||||
strtod() and strtol() </li>
|
||||
<li><a href="global_r.c#zero">qh_zero</a> zeroes qhT before first use</li>
|
||||
</ul>
|
||||
|
||||
<p><!-- Navigation links --> </p>
|
||||
<hr>
|
||||
<p><b>Up:</b>
|
||||
<a href="http://www.qhull.org">Home page</a> for
|
||||
Qhull (<a href="../index.htm">local</a>)<br>
|
||||
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: contents<br>
|
||||
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
|
||||
• <a href="../../html/qh-quick.htm#options">Options</a>
|
||||
• <a href="../../html/qh-opto.htm#output">Output</a>
|
||||
• <a href="../../html/qh-optf.htm#format">Formats</a>
|
||||
• <a href="../../html/qh-optg.htm#geomview">Geomview</a>
|
||||
• <a href="../../html/qh-optp.htm#print">Print</a>
|
||||
• <a href="../../html/qh-optq.htm#qhull">Qhull</a>
|
||||
• <a href="../../html/qh-optc.htm#prec">Precision</a>
|
||||
• <a href="../../html/qh-optt.htm#trace">Trace</a>
|
||||
• <a href="http://www.qhull.org/src/libqhull_r/index.htm">Functions</a> (<a href="index.htm">local</a>)<br>
|
||||
<b>Up:</b> <a href="../../html/qh-code.htm">Qhull code</a> <br>
|
||||
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> •
|
||||
<a href="qh-globa_r.htm">Global</a> • <a href="qh-io_r.htm">Io</a>
|
||||
• <a href="qh-mem_r.htm">Mem</a> • <a href="qh-merge_r.htm">Merge</a>
|
||||
• <a href="qh-poly_r.htm">Poly</a> • <a href="qh-qhull_r.htm#TOC">Qhull</a>
|
||||
• <a href="qh-set_r.htm">Set</a> • <a href="qh-stat_r.htm">Stat</a>
|
||||
• <a href="qh-user_r.htm">User</a><br>
|
||||
<p><!-- GC common information --> </p>
|
||||
<hr>
|
||||
<p><a href="http://www.geom.uiuc.edu/"><img
|
||||
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
|
||||
Geometry Center Home Page </i></p>
|
||||
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
|
||||
<br>
|
||||
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,299 @@
|
||||
<!-- Do not edit with Front Page, it adds too many spaces -->
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type"
|
||||
content="text/html; charset=iso-8859-1">
|
||||
<title>io_r.c -- input and output operations</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- Navigation links -->
|
||||
<p><a name="TOP"><b>Up:</b></a> <a
|
||||
href="http://www.qhull.org">Home page</a> for Qhull (<a href="../index.htm">local</a>)<br>
|
||||
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: contents <br>
|
||||
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
|
||||
• <a href="../../html/qh-quick.htm#options">Options</a>
|
||||
• <a href="../../html/qh-opto.htm#output">Output</a>
|
||||
• <a href="../../html/qh-optf.htm#format">Formats</a>
|
||||
• <a href="../../html/qh-optg.htm#geomview">Geomview</a>
|
||||
• <a href="../../html/qh-optp.htm#print">Print</a>
|
||||
• <a href="../../html/qh-optq.htm#qhull">Qhull</a>
|
||||
• <a href="../../html/qh-optc.htm#prec">Precision</a>
|
||||
• <a href="../../html/qh-optt.htm#trace">Trace</a>
|
||||
• <a href="http://www.qhull.org/src/libqhull_r/index.htm">Functions</a> (<a href="index.htm">local</a>)<br>
|
||||
<b>Up:</b> <a href="../../html/qh-code.htm">Qhull code</a><br>
|
||||
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> • <a href="qh-globa_r.htm">Global</a>
|
||||
• <a href="qh-io_r.htm#TOC">Io</a> • <a href="qh-mem_r.htm">Mem</a>
|
||||
• <a href="qh-merge_r.htm">Merge</a> • <a href="qh-poly_r.htm">Poly</a>
|
||||
• <a href="qh-qhull_r.htm">Qhull</a> • <a href="qh-set_r.htm">Set</a>
|
||||
• <a href="qh-stat_r.htm">Stat</a> • <a href="qh-user_r.htm">User</a>
|
||||
</p>
|
||||
<hr>
|
||||
|
||||
<h2>io_r.c -- input and output operations</h2>
|
||||
<blockquote>
|
||||
|
||||
<p>Qhull provides a wide range of input
|
||||
and output options. To organize the code, most output formats use
|
||||
the same driver: </p>
|
||||
|
||||
<pre>
|
||||
qh_printbegin( fp, format, facetlist, facets, printall );
|
||||
|
||||
FORALLfacet_( facetlist )
|
||||
qh_printafacet( fp, format, facet, printall );
|
||||
|
||||
FOREACHfacet_( facets )
|
||||
qh_printafacet( fp, format, facet, printall );
|
||||
|
||||
qh_printend( fp, format );
|
||||
</pre>
|
||||
|
||||
<p>Note the 'printall' flag. It selects whether or not
|
||||
qh_skipfacet() is tested. </p>
|
||||
|
||||
</blockquote>
|
||||
<p><b>Copyright © 1995-2020 C.B. Barber</b></p>
|
||||
<hr>
|
||||
<p><a href="#TOP">»</a> <a href="qh-geom_r.htm#TOC">Geom</a> <a name="TOC">•</a>
|
||||
<a href="qh-globa_r.htm#TOC">Global</a> • <b>Io</b> •
|
||||
<a href="qh-mem_r.htm#TOC">Mem</a> • <a href="qh-merge_r.htm#TOC">Merge</a> •
|
||||
<a href="qh-poly_r.htm#TOC">Poly</a> • <a href="qh-qhull_r.htm#TOC">Qhull</a> •
|
||||
<a href="qh-set_r.htm#TOC">Set</a> • <a href="qh-stat_r.htm#TOC">Stat</a> •
|
||||
<a href="qh-user_r.htm#TOC">User</a> </p>
|
||||
|
||||
<h3>Index to <a href="io_r.c">io_r.c</a> and <a href="io_r.h">io_r.h</a></h3>
|
||||
|
||||
<ul>
|
||||
<li><a href="#iconst">io_r.h constants and types</a> </li>
|
||||
<li><a href="#ilevel">User level functions</a> </li>
|
||||
<li><a href="#iprint">Print functions for all output formats</a></li>
|
||||
<li><a href="#itext">Text output functions</a> </li>
|
||||
<li><a href="#iutil">Text utility functions</a></li>
|
||||
<li><a href="#igeom">Geomview output functions</a> </li>
|
||||
<li><a href="#iview">Geomview utility functions</a></li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-io_r.htm#TOC">»</a><a name="iconst">io_r.h constants and types</a></h3>
|
||||
|
||||
<ul>
|
||||
<li><a href="io_r.h#qh_MAXfirst">qh_MAXfirst</a> maximum length
|
||||
of first two lines of stdin </li>
|
||||
<li><a href="io_r.h#qh_WHITESPACE">qh_WHITESPACE</a> possible
|
||||
values of white space </li>
|
||||
<li><a href="io_r.h#printvridgeT">printvridgeT</a> function to
|
||||
print results of qh_printvdiagram or qh_eachvoronoi</li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-io_r.htm#TOC">»</a><a name="ilevel">User level functions</a></h3>
|
||||
|
||||
<ul>
|
||||
<li><a href="io_r.c#copyfilename">qh_copyfilename</a>
|
||||
copy filename identified by qh_skipfilename
|
||||
<li><a href="io_r.c#eachvoronoi_all">qh_eachvoronoi_all</a>
|
||||
visit each Voronoi ridge of the Voronoi diagram
|
||||
<li><a href="io_r.c#prepare_output">qh_prepare_output</a>
|
||||
prepare Qhull for output (called by qh_produce_output())
|
||||
<li><a href="poly2_r.c#printlists">qh_printlists</a>
|
||||
print out facet lists for debugging </li>
|
||||
<li><a href="libqhull_r.c#printsummary">qh_printsummary</a> print
|
||||
summary ('s')</li>
|
||||
<li><a href="io_r.c#produce_output">qh_produce_output</a>
|
||||
prints out the result of qhull()</li>
|
||||
<li><a href="io_r.c#produce_output">qh_produce_output2</a>
|
||||
prints out the result of qhull() without calling qh_prepare_output()</li>
|
||||
<li><a href="io_r.c#readfeasible">qh_readfeasible</a> read
|
||||
interior point from remainder and qh fin ('H')</li>
|
||||
<li><a href="io_r.c#readpoints">qh_readpoints</a> read input
|
||||
points </li>
|
||||
<li><a href="io_r.c#setfeasible">qh_setfeasible</a> set
|
||||
interior point from qh feasible_string ('Hn,n,n')</li>
|
||||
<li><a href="io_r.c#skipfilename">qh_skipfilename</a>
|
||||
skip filename in string
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-io_r.htm#TOC">»</a><a name="iprint">Print functions for all
|
||||
output formats</a></h3>
|
||||
|
||||
<ul>
|
||||
<li><a href="io_r.c#countfacets">qh_countfacets</a> count good
|
||||
facets for printing and set visitid </li>
|
||||
<li><a href="io_r.c#markkeep">qh_markkeep</a> restrict good facets for
|
||||
qh.KEEParea ('PAn'), qh.KEEPmerge ('PMn'), and qh.KEEPminArea ('PFn')</li>
|
||||
<li><a href="io_r.c#order_vertexneighbors">qh_order_vertexneighbors</a>
|
||||
order facet neighbors of vertex by 2-d (orientation), 3-d (adjacency), or n-d (f.visitid,id) ('i', 'o')</li>
|
||||
<li><a href="io_r.c#printafacet">qh_printafacet</a> print facet
|
||||
in an output format </li>
|
||||
<li><a href="io_r.c#printbegin">qh_printbegin</a> print header
|
||||
for an output format </li>
|
||||
<li><a href="io_r.c#printend">qh_printend</a> print trailer for
|
||||
an output format </li>
|
||||
<li><a href="user_r.c#printfacetlist">qh_printfacetlist</a>
|
||||
print facets in a facetlist</li>
|
||||
<li><a href="io_r.c#printfacets">qh_printfacets</a> print
|
||||
facetlist and/or facet set in an output format </li>
|
||||
<li><a href="io_r.c#printneighborhood">qh_printneighborhood</a>
|
||||
print neighborhood of one or two facets ('Po')</li>
|
||||
<li><a href="io_r.c#produce_output">qh_produce_output</a>
|
||||
print the results of qh_qhull() </li>
|
||||
<li><a href="io_r.c#skipfacet">qh_skipfacet</a> True if not
|
||||
printing this facet ('Pdk:n', 'QVn', 'QGn')</li>
|
||||
<li><a href="io_r.c#facetvertices">qh_facetvertices</a> return
|
||||
vertices in a set of facets ('p')</li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-io_r.htm#TOC">»</a><a name="itext">Text output functions</a></h3>
|
||||
<ul>
|
||||
<li><a href="io_r.c#eachvoronoi">qh_eachvoronoi</a>
|
||||
print or visit each Voronoi ridge for an input site of the Voronoi diagram
|
||||
<li><a href="io_r.c#printextremes">qh_printextremes</a> print
|
||||
extreme points by point ID (vertices of convex hull) ('Fx')</li>
|
||||
<li><a href="io_r.c#printextremes_2d">qh_printextremes_2d</a> print
|
||||
2-d extreme points by point ID ('Fx')</li>
|
||||
<li><a href="io_r.c#printextremes_d">qh_printextremes_d</a> print
|
||||
extreme points of input sites for Delaunay triangulations ('Fx')</li>
|
||||
<li><a href="io_r.c#printfacet">qh_printfacet</a> print all
|
||||
fields of a facet ('f')</li>
|
||||
<li><a href="io_r.c#printfacet2math">qh_printfacet2math</a> print
|
||||
2-d Maple or Mathematica output for a facet ('FM' or 'm')</li>
|
||||
<li><a href="io_r.c#printfacet3math">qh_printfacet3math</a>
|
||||
print 3-d Maple or Mathematica facet ('FM' or 'm')</li>
|
||||
<li><a href="io_r.c#printfacet3vertex">qh_printfacet3vertex</a>
|
||||
print vertices for a 3-d facet ('i', 'o')</li>
|
||||
<li><a href="io_r.c#printfacetheader">qh_printfacetheader</a>
|
||||
prints header fields of a facet ('f')</li>
|
||||
<li><a href="io_r.c#printfacetNvertex_nonsimplicial">qh_printfacetNvertex_nonsimplicial</a>
|
||||
print vertices for an N-d non-simplicial facet ('i', 'Ft')</li>
|
||||
<li><a href="io_r.c#printfacetNvertex_simplicial">qh_printfacetNvertex_simplicial</a>
|
||||
print vertices for an N-d simplicial facet ('i', 'o', 'Ft')</li>
|
||||
<li><a href="io_r.c#printfacetridges">qh_printfacetridges</a>
|
||||
prints ridges of a facet ('f')</li>
|
||||
<li><a href="io_r.c#printpoints_out">qh_printpoints_out</a> prints
|
||||
vertices for facets by their point coordinates ('p')</li>
|
||||
<li><a href="io_r.c#printridge">qh_printridge</a> print all
|
||||
fields for a ridge ('f')</li>
|
||||
<li><a href="io_r.c#printvdiagram">qh_printvdiagram</a> print
|
||||
voronoi diagram as Voronoi vertices for each input pair</li>
|
||||
<li><a href="io_r.c#printvertex">qh_printvertex</a> print all
|
||||
fields for a vertex ('f')</li>
|
||||
<li><a href="io_r.c#printvertexlist">qh_printvertexlist</a>
|
||||
print vertices used by a list or set of facets ('f')</li>
|
||||
<li><a href="io_r.c#printvertices">qh_printvertices</a> print a
|
||||
set of vertices ('f')</li>
|
||||
<li><a href="io_r.c#printvneighbors">qh_printvneighbors</a>
|
||||
print vertex neighbors of vertices ('FN')</li>
|
||||
<li><a href="io_r.c#printvoronoi">qh_printvoronoi</a> print
|
||||
voronoi diagram in 'o' or 'G' format</li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-io_r.htm#TOC">»</a><a name="iutil">Text utility functions</a></h3>
|
||||
<ul>
|
||||
<li><a href="io_r.c#dfacet">dfacet</a> print facet by ID </li>
|
||||
<li><a href="io_r.c#dvertex">dvertex</a> print vertex by ID </li>
|
||||
<li><a href="io_r.c#compare_facetarea">qh_compare_facetarea</a>
|
||||
used by qsort() to order facets by area </li>
|
||||
<li><a href="io_r.c#compare_facetvisit">qh_compare_facetvisit</a>
|
||||
used by qsort() to order facets by visit ID or ID </li>
|
||||
<li><a href="io_r.c#compare_nummerge">qh_compare_nummerge</a>
|
||||
used by qsort() to order facets by number of merges </li>
|
||||
<li><a href="io_r.c#detvnorm">qh_detvnorm</a> determine normal for Voronoi ridge </li>
|
||||
<li><a href="io_r.c#detvridge">qh_detvridge</a> determine Voronoi
|
||||
ridge for an input site
|
||||
<li><a href="io_r.c#detvridge3">qh_detvridge3</a> determine 3-d Voronoi
|
||||
ridge for an input site
|
||||
<li><a href="io_r.c#facet2point">qh_facet2point</a> return two
|
||||
projected temporary vertices for a 2-d facet ('m', 'G')</li>
|
||||
<li><a href="io_r.c#markvoronoi">qh_markvoronoi</a> mark Voronoi
|
||||
vertices for printing
|
||||
<li><a href="io_r.c#printcenter">qh_printcenter</a> print
|
||||
facet->center as centrum or Voronoi center ('Ft', 'v p', 'FC', 'f') </li>
|
||||
<li><a href="io_r.c#printpoint">qh_printpoint</a>, qh_printpointid, print
|
||||
coordinates of a point ('p', 'o', 'Fp', 'G', 'f')</li>
|
||||
<li><a href="io_r.c#printpoint3">qh_printpoint3</a> prints 2-d,
|
||||
3-d, or 4-d point as 3-d coordinates ('G')</li>
|
||||
<li><a href="io_r.c#printvdiagram2">qh_printvdiagram2</a> print
|
||||
voronoi diagram for each ridge of each vertex from qh_markvoronoi</li>
|
||||
<li><a href="io_r.c#printvnorm">qh_printvnorm</a> print
|
||||
separating plane of the Voronoi diagram for a pair of input sites</li>
|
||||
<li><a href="io_r.c#printvridge">qh_printvridge</a> print
|
||||
ridge of the Voronoi diagram for a pair of input sites</li>
|
||||
<li><a href="io_r.c#projectdim3">qh_projectdim3</a> project 2-d
|
||||
3-d or 4-d point to a 3-d point ('G')</li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-io_r.htm#TOC">»</a><a name="igeom">Geomview output functions</a></h3>
|
||||
<ul>
|
||||
<li><a href="io_r.c#printfacet2geom">qh_printfacet2geom</a>
|
||||
print facet as a 2-d VECT object </li>
|
||||
<li><a href="io_r.c#printfacet2geom_points">qh_printfacet2geom_points</a>
|
||||
print points as a 2-d VECT object with offset </li>
|
||||
<li><a href="io_r.c#printfacet3geom_nonsimplicial">qh_printfacet3geom_nonsimplicial</a>
|
||||
print Geomview OFF for a 3-d nonsimplicial facet. </li>
|
||||
<li><a href="io_r.c#printfacet3geom_points">qh_printfacet3geom_points</a>
|
||||
prints a 3-d facet as OFF Geomview object. </li>
|
||||
<li><a href="io_r.c#printfacet3geom_simplicial">qh_printfacet3geom_simplicial</a>
|
||||
print Geomview OFF for a 3-d simplicial facet. </li>
|
||||
<li><a href="io_r.c#printfacet4geom_nonsimplicial">qh_printfacet4geom_nonsimplicial</a>
|
||||
print Geomview 4OFF file for a 4d nonsimplicial facet </li>
|
||||
<li><a href="io_r.c#printfacet4geom_simplicial">qh_printfacet4geom_simplicial</a>
|
||||
print Geomview 4OFF file for a 4d simplicial facet </li>
|
||||
<li><a href="io_r.c#printhyperplaneintersection">qh_printhyperplaneintersection</a>
|
||||
print hyperplane intersection as OFF or 4OFF </li>
|
||||
<li><a href="io_r.c#printvoronoi">qh_printvoronoi</a> print
|
||||
voronoi diagram in 'o' or 'G' format</li>
|
||||
</ul>
|
||||
<h3><a href="qh-io_r.htm#TOC">»</a><a name="iview">Geomview utility functions</a></h3>
|
||||
<ul>
|
||||
<li><a href="io_r.c#geomplanes">qh_geomplanes</a>
|
||||
return outer and inner planes for Geomview</li>
|
||||
<li><a href="io_r.c#printcentrum">qh_printcentrum</a> print
|
||||
centrum for a facet in OOGL format </li>
|
||||
<li><a href="io_r.c#printend4geom">qh_printend4geom</a> helper
|
||||
function for qh_printbegin/printend </li>
|
||||
<li><a href="io_r.c#printhyperplaneintersection">qh_printhyperplaneintersection</a>
|
||||
print Geomview OFF or 4OFF for the intersection of two
|
||||
hyperplanes in 3-d or 4-d </li>
|
||||
<li><a href="io_r.c#printline3geom">qh_printline3geom</a> prints a
|
||||
line as a VECT </li>
|
||||
<li><a href="io_r.c#printpointvect">qh_printpointvect</a>
|
||||
prints a 2-d or 3-d point as 3-d VECT's </li>
|
||||
<li><a href="io_r.c#printpointvect2">qh_printpointvect2</a>
|
||||
prints a 2-d or 3-d point as 2 3-d VECT's </li>
|
||||
<li><a href="io_r.c#printspheres">qh_printspheres</a> prints 3-d
|
||||
vertices as OFF spheres </li>
|
||||
</ul>
|
||||
<p>
|
||||
<p><!-- Navigation links --> </p>
|
||||
<hr>
|
||||
<p><b>Up:</b>
|
||||
<a href="http://www.qhull.org">Home page</a> for
|
||||
Qhull (<a href="../index.htm">local</a>) <br>
|
||||
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: contents<br>
|
||||
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
|
||||
• <a href="../../html/qh-quick.htm#options">Options</a>
|
||||
• <a href="../../html/qh-opto.htm#output">Output</a>
|
||||
• <a href="../../html/qh-optf.htm#format">Formats</a>
|
||||
• <a href="../../html/qh-optg.htm#geomview">Geomview</a>
|
||||
• <a href="../../html/qh-optp.htm#print">Print</a>
|
||||
• <a href="../../html/qh-optq.htm#qhull">Qhull</a>
|
||||
• <a href="../../html/qh-optc.htm#prec">Precision</a>
|
||||
• <a href="../../html/qh-optt.htm#trace">Trace</a>
|
||||
• <a href="http://www.qhull.org/src/libqhull_r/index.htm">Functions</a> (<a href="index.htm">local</a>)<br>
|
||||
<b>Up:</b> <a href="../../html/qh-code.htm">Qhull code</a> <br>
|
||||
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> •
|
||||
<a href="qh-globa_r.htm">Global</a> • <a href="qh-io_r.htm">Io</a>
|
||||
• <a href="qh-mem_r.htm">Mem</a> • <a href="qh-merge_r.htm">Merge</a>
|
||||
• <a href="qh-poly_r.htm">Poly</a> • <a href="qh-qhull_r.htm#TOC">Qhull</a>
|
||||
• <a href="qh-set_r.htm">Set</a> • <a href="qh-stat_r.htm">Stat</a>
|
||||
• <a href="qh-user_r.htm">User</a><br>
|
||||
</p>
|
||||
<p><!-- GC common information --> </p>
|
||||
<hr>
|
||||
<p><a href="http://www.geom.uiuc.edu/"><img
|
||||
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
|
||||
Geometry Center Home Page </i></p>
|
||||
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
|
||||
<br>
|
||||
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,143 @@
|
||||
<!-- Do not edit with Front Page, it adds too many spaces -->
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type"
|
||||
content="text/html; charset=iso-8859-1">
|
||||
<title>mem_r.c -- memory operations</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- Navigation links -->
|
||||
<p><a name="TOP"><b>Up:</b></a> <a
|
||||
href="http://www.qhull.org">Home page</a> for Qhull (<a href="../index.htm">local</a>)<br>
|
||||
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: contents <br>
|
||||
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
|
||||
• <a href="../../html/qh-quick.htm#options">Options</a>
|
||||
• <a href="../../html/qh-opto.htm#output">Output</a>
|
||||
• <a href="../../html/qh-optf.htm#format">Formats</a>
|
||||
• <a href="../../html/qh-optg.htm#geomview">Geomview</a>
|
||||
• <a href="../../html/qh-optp.htm#print">Print</a>
|
||||
• <a href="../../html/qh-optq.htm#qhull">Qhull</a>
|
||||
• <a href="../../html/qh-optc.htm#prec">Precision</a>
|
||||
• <a href="../../html/qh-optt.htm#trace">Trace</a>
|
||||
• <a href="http://www.qhull.org/src/libqhull_r/index.htm">Functions</a> (<a href="index.htm">local</a>)<br>
|
||||
<b>Up:</b> <a href="../../html/qh-code.htm">Qhull code</a><br>
|
||||
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> • <a href="qh-globa_r.htm">Global</a>
|
||||
• <a href="qh-io_r.htm">Io</a> • <a href="qh-mem_r.htm#TOC">Mem</a>
|
||||
• <a href="qh-merge_r.htm">Merge</a> • <a href="qh-poly_r.htm">Poly</a>
|
||||
• <a href="qh-qhull_r.htm">Qhull</a> • <a href="qh-set_r.htm">Set</a>
|
||||
• <a href="qh-stat_r.htm">Stat</a> • <a href="qh-user_r.htm">User</a>
|
||||
</p>
|
||||
<hr>
|
||||
|
||||
<h2>mem_r.c -- memory operations</h2>
|
||||
<blockquote>
|
||||
<p>Qhull uses quick-fit memory allocation. It maintains a
|
||||
set of free lists for a variety of small allocations. A
|
||||
small request returns a block from the best fitting free
|
||||
list. If the free list is empty, Qhull allocates a block
|
||||
from a reserved buffer. </p>
|
||||
<p>Use 'T5' to trace memory allocations.</p>
|
||||
|
||||
</blockquote>
|
||||
<p><b>Copyright © 1995-2020 C.B. Barber</b></p>
|
||||
<hr>
|
||||
<p><a href="#TOP">»</a> <a href="qh-geom_r.htm#TOC">Geom</a>
|
||||
<a name="TOC">•</a> <a href="qh-globa_r.htm#TOC">Global</a> •
|
||||
<a href="qh-io_r.htm#TOC">Io</a> • <b>Mem</b>
|
||||
• <a href="qh-merge_r.htm#TOC">Merge</a> • <a href="qh-poly_r.htm#TOC">Poly</a>
|
||||
• <a href="qh-qhull_r.htm#TOC">Qhull</a> • <a href="qh-set_r.htm#TOC">Set</a>
|
||||
• <a href="qh-stat_r.htm#TOC">Stat</a> • <a href="qh-user_r.htm#TOC">User</a>
|
||||
</p>
|
||||
<h3>Index to <a href="mem_r.c">mem_r.c</a> and
|
||||
<a href="mem_r.h">mem_r.h</a></h3>
|
||||
<ul>
|
||||
<li><a href="#etype">mem_r.h data types</a> </li>
|
||||
<li><a href="#emacro">mem_r.h macros</a> </li>
|
||||
<li><a href="#efunc">User level functions</a> </li>
|
||||
</ul>
|
||||
<h3><a href="qh-mem_r.htm#TOC">»</a><a name="etype">mem_r.h data types and constants</a></h3>
|
||||
<ul>
|
||||
<li><a href="mem_r.h#ptr_intT">ptr_intT</a> for casting
|
||||
a void* to an integer-type </li>
|
||||
<li><a href="mem_r.h#qhmemT">qhmemT</a> global memory
|
||||
structure for mem_r.c </li>
|
||||
<li><a href="mem_r.h#NOmem">qh_NOmem</a> disable memory allocation</li>
|
||||
</ul>
|
||||
<h3><a href="qh-mem_r.htm#TOC">»</a><a name="emacro">mem_r.h macros</a></h3>
|
||||
<ul>
|
||||
<li><a href="mem_r.h#memalloc_">qh_memalloc_</a>
|
||||
allocate memory</li>
|
||||
<li><a href="mem_r.h#memfree_">qh_memfree_</a> free
|
||||
memory</li>
|
||||
</ul>
|
||||
<h3><a href="qh-mem_r.htm#TOC">»</a><a name="efunc">User level
|
||||
functions</a></h3>
|
||||
<ul>
|
||||
<li><a href="mem_r.c#memalloc">qh_memalloc</a> allocate
|
||||
memory </li>
|
||||
<li><a href="mem_r.c#memcheck">qh_memcheck</a>
|
||||
quick check of memory for internal consistency</li>
|
||||
<li><a href="mem_r.c#memfree">qh_memfree</a> free
|
||||
memory </li>
|
||||
<li><a href="mem_r.c#meminit">qh_meminit</a> initialize
|
||||
memory </li>
|
||||
<li><a href="mem_r.c#memstatistics">qh_memstatistics</a>
|
||||
print memory statistics </li>
|
||||
<li><a href="mem_r.c#meminit">qh_memtotlong</a> return total, allocated long memory</li>
|
||||
<li><a href="mem_r.c#NOmem">qh_NOmem</a> allocation routines with malloc() and free()
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-mem_r.htm#TOC">»</a><a name="m">Initialization and
|
||||
termination functions</a></h3>
|
||||
<ul>
|
||||
<li><a href="mem_r.c#intcompare">qh_intcompare</a> used by
|
||||
qsort and bsearch to compare two integers </li>
|
||||
<li><a href="mem_r.c#memfreeshort">qh_memfreeshort</a>
|
||||
frees up all short and qhmem memory allocations </li>
|
||||
<li><a href="mem_r.c#meminit">qh_meminit</a> initialize
|
||||
memory </li>
|
||||
<li><a href="mem_r.c#meminitbuffers">qh_meminitbuffers</a>
|
||||
initialize qhmem </li>
|
||||
<li><a href="mem_r.c#memsetup">qh_memsetup</a> set up
|
||||
memory after running memsize() </li>
|
||||
<li><a href="mem_r.c#memsize">qh_memsize</a> define a free
|
||||
list for this size </li>
|
||||
<li><a href="mem_r.c#memstatistics">qh_memstatistics</a>
|
||||
print out memory statistics </li>
|
||||
</ul>
|
||||
|
||||
<p><!-- Navigation links --> </p>
|
||||
<hr>
|
||||
<p><b>Up:</b>
|
||||
<a href="http://www.qhull.org">Home page</a> for
|
||||
Qhull (<a href="../index.htm">local</a>) <br>
|
||||
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: contents<br>
|
||||
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
|
||||
• <a href="../../html/qh-quick.htm#options">Options</a>
|
||||
• <a href="../../html/qh-opto.htm#output">Output</a>
|
||||
• <a href="../../html/qh-optf.htm#format">Formats</a>
|
||||
• <a href="../../html/qh-optg.htm#geomview">Geomview</a>
|
||||
• <a href="../../html/qh-optp.htm#print">Print</a>
|
||||
• <a href="../../html/qh-optq.htm#qhull">Qhull</a>
|
||||
• <a href="../../html/qh-optc.htm#prec">Precision</a>
|
||||
• <a href="../../html/qh-optt.htm#trace">Trace</a>
|
||||
• <a href="http://www.qhull.org/src/libqhull_r/index.htm">Functions</a> (<a href="index.htm">local</a>)<br>
|
||||
<b>Up:</b> <a href="../../html/qh-code.htm">Qhull code</a> <br>
|
||||
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> •
|
||||
<a href="qh-globa_r.htm">Global</a> • <a href="qh-io_r.htm">Io</a>
|
||||
• <a href="qh-mem_r.htm">Mem</a> • <a href="qh-merge_r.htm">Merge</a>
|
||||
• <a href="qh-poly_r.htm">Poly</a> • <a href="qh-qhull_r.htm#TOC">Qhull</a>
|
||||
• <a href="qh-set_r.htm">Set</a> • <a href="qh-stat_r.htm">Stat</a>
|
||||
• <a href="qh-user_r.htm">User</a><br>
|
||||
</p>
|
||||
<p><!-- GC common information --> </p>
|
||||
<hr>
|
||||
<p><a href="http://www.geom.uiuc.edu/"><img
|
||||
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
|
||||
Geometry Center Home Page </i></p>
|
||||
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
|
||||
<br>
|
||||
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,446 @@
|
||||
<!-- Do not edit with Front Page, it adds too many spaces -->
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type"
|
||||
content="text/html; charset=iso-8859-1">
|
||||
<title>merge_r.c -- facet merge operations</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- Navigation links -->
|
||||
<p><a name="TOP"><b>Up:</b></a> <a
|
||||
href="http://www.qhull.org">Home page</a> for Qhull (<a href="../index.htm">local</a>)<br>
|
||||
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: contents <br>
|
||||
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
|
||||
• <a href="../../html/qh-quick.htm#options">Options</a>
|
||||
• <a href="../../html/qh-opto.htm#output">Output</a>
|
||||
• <a href="../../html/qh-optf.htm#format">Formats</a>
|
||||
• <a href="../../html/qh-optg.htm#geomview">Geomview</a>
|
||||
• <a href="../../html/qh-optp.htm#print">Print</a>
|
||||
• <a href="../../html/qh-optq.htm#qhull">Qhull</a>
|
||||
• <a href="../../html/qh-optc.htm#prec">Precision</a>
|
||||
• <a href="../../html/qh-optt.htm#trace">Trace</a>
|
||||
• <a href="http://www.qhull.org/src/libqhull_r/index.htm">Functions</a> (<a href="index.htm">local</a>)<br>
|
||||
<b>Up:</b> <a href="../../html/qh-code.htm">Qhull code</a><br>
|
||||
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> • <a href="qh-globa_r.htm">Global</a>
|
||||
• <a href="qh-io_r.htm">Io</a> • <a href="qh-mem_r.htm">Mem</a>
|
||||
• <a href="qh-merge_r.htm#TOC">Merge</a> • <a href="qh-poly_r.htm">Poly</a>
|
||||
• <a href="qh-qhull_r.htm">Qhull</a> • <a href="qh-set_r.htm">Set</a>
|
||||
• <a href="qh-stat_r.htm">Stat</a> • <a href="qh-user_r.htm">User</a>
|
||||
</p>
|
||||
<hr>
|
||||
|
||||
<h2>merge_r.c -- facet merge operations</h2>
|
||||
<blockquote>
|
||||
<p>Qhull handles precision problems by merged facets or joggled input.
|
||||
Except for redundant vertices, it corrects a problem by
|
||||
merging two facets. When done, all facets are clearly
|
||||
convex. See <a href="../../html/qh-impre.htm">Imprecision in Qhull</a>
|
||||
for further information. </p>
|
||||
<p>Users may joggle the input ('<a href="../../html/qh-optq.htm#QJn">QJn</a>')
|
||||
instead of merging facets. </p>
|
||||
<p>Qhull detects and corrects the following problems: </p>
|
||||
<ul>
|
||||
<li><b>More than two facets meeting at a ridge. </b>When
|
||||
Qhull creates facets, it creates an even number
|
||||
of facets for each ridge. A convex hull always
|
||||
has two facets for each ridge. More than two
|
||||
facets may be created if non-adjacent facets
|
||||
share a subridge. This is called a <em>dupridge</em>. In 2-d, a dupridge would
|
||||
create a loop of facets. See 'pinched vertices'
|
||||
below for the resolution of a dupridge.</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><b>A facet contained in another facet. </b>Facet
|
||||
merging may leave all vertices of one facet as a
|
||||
subset of the vertices of another facet. This is
|
||||
called a <em>redundant facet</em>. </li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><b>A facet with fewer than three neighbors. </b>Facet
|
||||
merging may leave a facet with one or two
|
||||
neighbors. This is called a <em>degenerate facet</em>.
|
||||
</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><b>A facet with flipped orientation. </b>A
|
||||
facet's hyperplane may define a halfspace that
|
||||
does not include the interior point.This is
|
||||
called a <em>flipped facet</em>. </li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><strong>A coplanar horizon facet.</strong> A
|
||||
newly processed point may be coplanar with an
|
||||
horizon facet. Qhull creates a new facet without
|
||||
a hyperplane. It links new facets for the same
|
||||
horizon facet together. This is called a <em>samecycle</em>.
|
||||
The new facet or samecycle is merged into the
|
||||
horizon facet. </li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><b>Concave facets. </b>A facet's centrum may be
|
||||
above a neighboring facet. If so, the facets meet
|
||||
at a concave angle. </li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><b>Coplanar facets. </b>A facet's centrum may be
|
||||
coplanar with a neighboring facet (i.e., it is
|
||||
neither clearly below nor clearly above the
|
||||
facet's hyperplane). Qhull removes coplanar
|
||||
facets in independent sets sorted by angle.</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><b>Redundant vertex. </b>A vertex may have fewer
|
||||
than three neighboring facets. If so, it is
|
||||
redundant and may be renamed to an adjacent
|
||||
vertex without changing the topological
|
||||
structure.This is called a <em>redundant vertex</em>.
|
||||
</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><b>Pinched vertices. </b>Nearly adjacent vertices
|
||||
may allow a dupridge that connects more than two
|
||||
new facets.
|
||||
A <em>pinched vertex</em> is the nearest horizon
|
||||
vertex that is a neighbor of a dupridge vertex. In 4-D and higher,
|
||||
both vertices may be in the same dupridge. If the
|
||||
vertices are in new facets with inverse orientation, the facets
|
||||
cannot be merged. If so, qhull
|
||||
merges the pinched vertices and recreates the cone of new facets.
|
||||
For a discussion, see 'Nearly adjacent vertices within 1e-13' in
|
||||
<a href="../../html/qh-impre.htm#limit">Limitations of merged facets</a>.
|
||||
</li>
|
||||
</ul>
|
||||
</blockquote>
|
||||
<p><b>Copyright © 1995-2020 C.B. Barber</b></p>
|
||||
<hr>
|
||||
<p><a href="#TOP">»</a> <a href="qh-geom_r.htm#TOC">Geom</a>
|
||||
<a name="TOC">•</a> <a href="qh-globa_r.htm#TOC">Global</a>
|
||||
• <a href="qh-io_r.htm#TOC">Io</a> • <a href="qh-mem_r.htm#TOC">Mem</a>
|
||||
• <b>Merge</b> • <a href="qh-poly_r.htm#TOC">Poly</a>
|
||||
• <a href="qh-qhull_r.htm#TOC">Qhull</a> • <a href="qh-set_r.htm#TOC">Set</a>
|
||||
• <a href="qh-stat_r.htm#TOC">Stat</a> • <a href="qh-user_r.htm#TOC">User</a>
|
||||
</p>
|
||||
<h3>Index to <a href="merge_r.c">merge_r.c</a> and
|
||||
<a href="merge_r.h">merge_r.h</a></h3>
|
||||
<ul>
|
||||
<li><a href="#mtype">merge_r.h data types, macros, and
|
||||
global sets</a> </li>
|
||||
<li><a href="#mconst">merge_r.h constants</a> </li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="#mtop">top-level merge functions</a> </li>
|
||||
<li><a href="#mset">functions for identifying merges</a></li>
|
||||
<li><a href="#mbest">functions for determining the
|
||||
best merge</a> </li>
|
||||
<li><a href="#mmerge">functions for merging facets</a>
|
||||
</li>
|
||||
<li><a href="#mcycle">functions for merging a cycle
|
||||
of facets</a> </li>
|
||||
<li><a href="#mpinched">functions for pinched vertices
|
||||
of dupridges</a> </li>
|
||||
<li><a href="#mrename">functions for renaming a
|
||||
vertex</a> </li>
|
||||
<li><a href="#mvertex">functions for identifying
|
||||
vertices for renaming</a> </li>
|
||||
<li><a href="#mcheck">functions for check and trace</a> </li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-merge_r.htm#TOC">»</a><a name="mtype">merge_r.h data
|
||||
types, macros, and global sets</a></h3>
|
||||
<ul>
|
||||
<li><a href="merge_r.h#mergeT">mergeT</a> structure to
|
||||
identify a merge of two facets</li>
|
||||
<li><a href="merge_r.h#FOREACHmerge_">FOREACHmerge_</a>
|
||||
assign 'merge' to each merge in mergeset </li>
|
||||
<li><a href="merge_r.h#FOREACHmergeA_">FOREACHmergeA_</a>
|
||||
assign 'mergeA' to each merge in mergeset </li>
|
||||
<li><a href="merge_r.h#FOREACHmerge_i_">FOREACHmerge_i_</a>
|
||||
assign 'merge' and 'merge_i' to each merge in mergeset </li>
|
||||
<li><a href="libqhull_r.h#qh-set">qh global sets</a>
|
||||
qh.facet_mergeset contains non-convex merges
|
||||
while qh.degen_mergeset contains degenerate and
|
||||
redundant facets</li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-merge_r.htm#TOC">»</a><a name="mconst">merge_r.h
|
||||
constants</a></h3>
|
||||
<ul>
|
||||
<li><a href="libqhull_r.h#qh-prec">qh precision constants</a>
|
||||
precision constants for Qhull </li>
|
||||
<li><a href="merge_r.h#MRG">MRG...</a> indicates the
|
||||
type of a merge (mergeT->type)</li>
|
||||
<li><a href="merge_r.h#qh_ANGLEnone">qh_ANGLEnone</a>
|
||||
indicates missing mergeT.angle </li>
|
||||
<li><a href="merge_r.h#qh_MERGEapex">qh_MERGEapex</a>
|
||||
flag for qh_mergefacet() to indicate an apex
|
||||
merge </li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-merge_r.htm#TOC">»</a><a name="mtop">top-level merge
|
||||
functions</a></h3>
|
||||
<ul>
|
||||
<li><a href="merge_r.c#all_merges">qh_all_merges</a>
|
||||
merge all non-convex facets </li>
|
||||
<li><a href="merge_r.c#checkzero">qh_checkzero</a>
|
||||
check that facets are clearly convex </li>
|
||||
<li><a href="merge_r.c#flippedmerges">qh_flippedmerges</a>
|
||||
merge flipped facets into best neighbor </li>
|
||||
<li><a href="merge_r.c#forcedmerges">qh_forcedmerges</a>
|
||||
merge all dupridges </li>
|
||||
<li><a href="merge_r.c#merge_degenredundant">qh_merge_degenredundant</a>
|
||||
merge degenerate and redundant facets </li>
|
||||
<li><a href="merge_r.c#merge_nonconvex">qh_merge_nonconvex</a>
|
||||
merge a non-convex ridge </li>
|
||||
<li><a href="merge_r.c#merge_twisted">qh_merge_twisted</a>
|
||||
merge a twisted ridge with a convex and a concave opposite vertex </li>
|
||||
<li><a href="merge_r.c#premerge">qh_premerge</a>
|
||||
pre-merge non-convex facets </li>
|
||||
<li><a href="merge_r.c#postmerge">qh_postmerge</a>
|
||||
post-merge nonconvex facets as defined by
|
||||
maxcentrum/maxangle </li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-merge_r.htm#TOC">»</a><a name="mset">functions for
|
||||
identifying merges</a></h3>
|
||||
<ul>
|
||||
<li><a href="merge_r.c#appendmergeset">qh_appendmergeset</a>
|
||||
appends an entry to qh.facet_mergeset</li>
|
||||
<li><a href="merge_r.c#check_dupridge">qh_check_dupridge</a>
|
||||
check dupridge between facet1 and facet2 for wide merge </li>
|
||||
<li><a href="merge_r.c#checkdelfacet">qh_checkdelfacet</a>
|
||||
check that facet is not referenced by a mergeset </li>
|
||||
<li><a href="merge_r.compare_anglemerge">qh_compare_anglemerge</a>
|
||||
used by qsort() to order merges by type and angle </li>
|
||||
<li><a href="merge_r.compare_facetmerge">qh_compare_facetmerge</a>
|
||||
used by qsort() to order merges by type and distance </li>
|
||||
<li><a href="merge_r.c#degen_redundant_facet">qh_degen_redundant_facet</a>
|
||||
check for a degenerate or redundant facet</li>
|
||||
<li><a href="merge_r.c#degen_redundant_neighbors">qh_degen_redundant_neighbors</a>
|
||||
append degenerate and redundant neighbors to qh.degen_mergeset </li>
|
||||
<li><a href="geom2_r.c#detmaxoutside">qh_detmaxoutside</a>
|
||||
determine qh.MAXoutside target for qh_RATIO... tests </li>
|
||||
<li><a href="merge_r.c#getmergeset_initial">qh_getmergeset_initial</a>
|
||||
build initial qh.facet_mergeset </li>
|
||||
<li><a href="merge_r.c#getmergeset">qh_getmergeset</a>
|
||||
update qh.facet_mergeset </li>
|
||||
<li><a href="merge_r.c#hasmerge">qh_hasmerge</a>
|
||||
True if mergeset has mergetype for facetA and facetB </li>
|
||||
<li><a href="merge_r.c#mark_dupridges">qh_mark_dupridges</a>
|
||||
add dupridges to qh.facet_mergeset</li>
|
||||
<li><a href="merge_r.c#maybe_convexvertex">qh_maybe_convexvertex</a>
|
||||
maybe convex vertex for newly merged facet1/vertex1 and facet2 </li>
|
||||
<li><a href="merge_r.c#maybe_duplicateridge">qh_maybe_duplicateridge</a>
|
||||
if a neighboring facet has another ridge with the same vertices, merge the closest pair of vertices </li>
|
||||
<li><a href="merge_r.c#maybe_duplicateridge">qh_maybe_duplicateridges</a>
|
||||
if a merged facet has two ridges with the same vertices, merge the closest pair of vertices </li>
|
||||
<li><a href="merge_r.c#maydropneighbor">qh_maydropneighbor</a>
|
||||
drop neighbor relationship if no ridge between
|
||||
facet and neighbor </li>
|
||||
<li><a href="poly2_r.c#matchduplicates">qh_matchdupridge</a>
|
||||
match dupridges in hash table </li>
|
||||
<li><a href="merge_r.c#merge_dupridges">qh_merge_dupridges</a>
|
||||
identify dupridges for merging </li>
|
||||
<li><a href="merge_r.c#next_facetmerge">qh_next_facetmerge</a>
|
||||
return next facet merge from qh.facet_mergeset</li>
|
||||
<li><a href="merge_r.c#next_vertexmerge">qh_next_vertexmerge</a>
|
||||
return next vertex merge from qh.vertex_mergeset</li>
|
||||
<li><a href="merge_r.c#test_appendmerge">qh_test_appendmerge</a>
|
||||
test a pair of facets for convexity and append to
|
||||
qh.facet_mergeset if non-convex </li>
|
||||
<li><a href="merge_r.c#test_centrum_merge">qh_test_centrum_merge</a>
|
||||
test centrum convexity and append non-convex facets to qh.facet_mergeset </li>
|
||||
<li><a href="merge_r.c#test_degen_neighbors">qh_test_degen_neighbors</a>
|
||||
append degenerate neighbors to qh.degen_mergeset </li>
|
||||
<li><a href="merge_r.c#test_nonsimplicial_merge">qh_test_nonsimplicial_merge</a>
|
||||
test centrum and vertex convexity and append non-convex or redundant facets to qh.facet_mergeset </li>
|
||||
<li><a href="merge_r.c#test_redundant_neighbors">qh_test_redundant_neighbors</a>
|
||||
append degenerate facet or its redundant neighbors to qh.degen_mergeset </li>
|
||||
<li><a href="merge_r.c#test_vneighbors">qh_test_vneighbors</a>
|
||||
test vertex neighbors for convexity </li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-merge_r.htm#TOC">»</a><a name="mbest">functions for
|
||||
determining the best merge</a></h3>
|
||||
<ul>
|
||||
<li><a href="merge_r.c#findbest_test">qh_findbest_test</a>
|
||||
test neighbor for best merge </li>
|
||||
<li><a href="merge_r.c#findbestneighbor">qh_findbestneighbor</a>
|
||||
finds best neighbor of a facet for merging (i.e.,
|
||||
closest hyperplane) </li>
|
||||
<li><a href="merge_r.c#opposite_horizonfacet">qh_opposite_horizonfacet</a>
|
||||
return horizon facet and opposite vertex for merge </li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-merge_r.htm#TOC">»</a><a name="mmerge">functions for
|
||||
merging facets</a></h3>
|
||||
<ul>
|
||||
<li><a href="merge_r.c#checkdelridge">qh_checkdelridge</a> check that
|
||||
qh_delridge_merge is not needed </li>
|
||||
<li><a href="merge_r.c#coplanarhorizon_merge">qh_coplanarhorizon_merge</a>
|
||||
merge new facets separated by a coplanar horizon facet </li>
|
||||
<li><a href="merge_r.c#coplanarhorizon_merges">qh_coplanarhorizon_merges</a>
|
||||
merge new facets separated by coplanar horizon facets </li>
|
||||
<li><a href="merge_r.c#copynonconvex">qh_copynonconvex</a>
|
||||
copy non-convex flag to another ridge for the
|
||||
same neighbor </li>
|
||||
<li><a href="merge_r.c#delridge_merge">qh_delridge_merge</a> delete
|
||||
ridge and associated references, set vertex.delridge </li>
|
||||
<li><a href="merge_r.c#drop_mergevertex">qh_drop_mergevertex</a>
|
||||
clear mergevertex flags for ridges in a facet of a vertex merge </li>
|
||||
<li><a href="merge_r.c#initmergesets">qh_freemergesets</a>
|
||||
free mergesets </li>
|
||||
<li><a href="merge_r.c#initmergesets">qh_initmergesets</a>
|
||||
initialize mergesets </li>
|
||||
<li><a href="merge_r.c#makeridges">qh_makeridges</a>
|
||||
creates explicit ridges between simplicial facets
|
||||
</li>
|
||||
<li><a href="merge_r.c#mergefacet">qh_mergefacet</a>
|
||||
merges one facet into another facet</li>
|
||||
<li><a href="merge_r.c#mergeneighbors">qh_mergeneighbors</a>
|
||||
merges the neighbors of two facets </li>
|
||||
<li><a href="merge_r.c#mergeridges">qh_mergeridges</a>
|
||||
merges the ridge sets of two facets </li>
|
||||
<li><a href="merge_r.c#mergesimplex">qh_mergesimplex</a>
|
||||
merge a simplicial facet into another simplicial
|
||||
facet </li>
|
||||
<li><a href="merge_r.c#mergevertex_del">qh_mergevertex_del</a>
|
||||
delete a vertex due to merging one facet into
|
||||
another facet </li>
|
||||
<li><a href="merge_r.c#mergevertex_neighbors">qh_mergevertex_neighbors</a>
|
||||
merge the vertex neighbors of two facets </li>
|
||||
<li><a href="merge_r.c#mergevertices">qh_mergevertices</a>
|
||||
merge the vertex sets of two facets </li>
|
||||
<li><a href="merge_r.c#newvertices">qh_newvertices</a>
|
||||
register all vertices as new vertices </li>
|
||||
<li><a href="merge_r.c#updatetested">qh_updatetested</a>
|
||||
clear tested flags and centrums involved in a
|
||||
merge </li>
|
||||
<li><a href="merge_r.c#willdelete">qh_willdelete</a>
|
||||
moves facet to qh.visible_list; sets replacement
|
||||
or NULL </li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-merge_r.htm#TOC">»</a><a name="mcycle">functions for
|
||||
merging a cycle of facets</a></h3>
|
||||
<p>If a point is coplanar with an horizon facet, the
|
||||
corresponding new facets are linked together (a <em>samecycle</em>)
|
||||
for merging.</p>
|
||||
<ul>
|
||||
<li><a href="merge_r.c#basevertices">qh_basevertices</a>
|
||||
return temporary set of base vertices for a
|
||||
samecycle </li>
|
||||
<li><a href="merge_r.c#mergecycle">qh_mergecycle</a>
|
||||
merge a samecycle into a horizon facet </li>
|
||||
<li><a href="merge_r.c#mergecycle_all">qh_mergecycle_all</a>
|
||||
merge all samecycles into horizon facets</li>
|
||||
<li><a href="merge_r.c#mergecycle_facets">qh_mergecycle_facets</a>
|
||||
finish merge of samecycle </li>
|
||||
<li><a href="merge_r.c#mergecycle_neighbors">qh_mergecycle_neighbors</a>
|
||||
merge neighbor sets for samecycle </li>
|
||||
<li><a href="merge_r.c#mergecycle_ridges">qh_mergecycle_ridges</a>
|
||||
merge ridge sets for samecycle </li>
|
||||
<li><a href="merge_r.c#mergecycle_vneighbors">qh_mergecycle_vneighbors</a>
|
||||
merge vertex neighbor sets for samecycle </li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-merge_r.htm#TOC">»</a><a name="mpinched">functions
|
||||
for pinched vertices of dupridges</h3>
|
||||
<ul>
|
||||
<li><a href="merge_r.c#findbest_pinchedvertex">qh_findbest_pinchedvertex</a>
|
||||
find the best vertex to merge for a dupridge in qh.newfacet_list </li>
|
||||
<li><a href="merge_r.c#get_maybepinched_vertices">qh_get_maybepinched_vertices</a>
|
||||
return neighboring horizon vertices of a vertex in a dupridge </li>
|
||||
<li><a href="merge_r.c#getpinchedmerges">qh_getpinchedmerges</a>
|
||||
return qh.vertex_mergeset for pinched vertices that cannot be facet merged </li>
|
||||
<li><a href="merge_r.c#merge_pinchedvertices">qh_merge_pinchedvertices</a>
|
||||
merge pinched vertices in qh.vertex_mergeset to avoid qh_forcedmerges of dupridges </li>
|
||||
<li><a href="merge_r.c#neighbor_vertices">qh_neighbor_vertices</a>
|
||||
return neighboring vertices for a vertex </li>
|
||||
<li><a href="merge_r.c#neighbor_vertices_facet">qh_neighbor_vertices_facet</a>
|
||||
return neighboring vertices for a vertex in a facet </li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-merge_r.htm#TOC">»</a><a name="mrename">functions
|
||||
for renaming a vertex</a></h3>
|
||||
<ul>
|
||||
<li><a href="merge_r.c#comparevisit">qh_comparevisit</a>
|
||||
used by qsort() to order vertices by visitid</li>
|
||||
<li><a href="merge_r.c#reducevertices">qh_reducevertices</a>
|
||||
reduce vertex sets </li>
|
||||
<li><a href="merge_r.c#redundant_vertex">qh_redundant_vertex</a>
|
||||
returns true if detect and rename redundant
|
||||
vertex </li>
|
||||
<li><a href="merge_r.c#rename_sharedvertex">qh_rename_sharedvertex</a>
|
||||
detect and rename a shared vertex </li>
|
||||
<li><a href="merge_r.c#renameridgevertex">qh_renameridgevertex</a>
|
||||
rename oldvertex to newvertex in a ridge </li>
|
||||
<li><a href="merge_r.c#renamevertex">qh_renamevertex</a>
|
||||
rename oldvertex to newvertex in ridges </li>
|
||||
<li><a href="merge_r.c#remove_extravertices">qh_remove_extravertices</a>
|
||||
remove extra vertices in non-simplicial facets </li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-merge_r.htm#TOC">»</a><a name="mvertex">functions
|
||||
for identifying vertices for renaming</a></h3>
|
||||
<ul>
|
||||
<li><a href="merge_r.c#find_newvertex">qh_find_newvertex</a>
|
||||
locate new vertex for renaming old vertex </li>
|
||||
<li><a href="merge_r.c#hashridge">qh_hashridge</a> add
|
||||
ridge to hashtable </li>
|
||||
<li><a href="merge_r.c#hashridge_find">qh_hashridge_find</a>
|
||||
returns matching ridge in hashtable</li>
|
||||
<li><a href="merge_r.c#neighbor_intersections">qh_neighbor_intersections</a>
|
||||
return intersection of vertex sets for
|
||||
neighboring facets </li>
|
||||
<li><a href="merge_r.c#vertexridges">qh_vertexridges</a>
|
||||
return temporary set of ridges adjacent to a vertex </li>
|
||||
<li><a href="merge_r.c#vertexridges_facet">qh_vertexridges_facet</a>
|
||||
add adjacent ridges for a vertex in facet </li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-merge_r.htm#TOC">»</a><a name="mcheck">functions for check and
|
||||
trace</a></h3>
|
||||
<ul>
|
||||
<li><a href="merge_r.c#checkconnect">qh_checkconnect</a>
|
||||
check that new facets are connected </li>
|
||||
<li><a href="merge_r.c#tracemerge">qh_tracemerge</a>
|
||||
print trace message after merge </li>
|
||||
<li><a href="merge_r.c#tracemerging">qh_tracemerging</a>
|
||||
print trace message during post-merging </li>
|
||||
</ul>
|
||||
|
||||
<p><!-- Navigation links --> </p>
|
||||
<hr>
|
||||
<p><b>Up:</b>
|
||||
<a href="http://www.qhull.org">Home page</a> for
|
||||
Qhull (<a href="../index.htm">local</a>)<br>
|
||||
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: contents<br>
|
||||
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
|
||||
• <a href="../../html/qh-quick.htm#options">Options</a>
|
||||
• <a href="../../html/qh-opto.htm#output">Output</a>
|
||||
• <a href="../../html/qh-optf.htm#format">Formats</a>
|
||||
• <a href="../../html/qh-optg.htm#geomview">Geomview</a>
|
||||
• <a href="../../html/qh-optp.htm#print">Print</a>
|
||||
• <a href="../../html/qh-optq.htm#qhull">Qhull</a>
|
||||
• <a href="../../html/qh-optc.htm#prec">Precision</a>
|
||||
• <a href="../../html/qh-optt.htm#trace">Trace</a>
|
||||
• <a href="http://www.qhull.org/src/libqhull_r/index.htm">Functions</a> (<a href="index.htm">local</a>)<br>
|
||||
<b>Up:</b> <a href="../../html/qh-code.htm">Qhull code</a> <br>
|
||||
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> •
|
||||
<a href="qh-globa_r.htm">Global</a> • <a href="qh-io_r.htm">Io</a>
|
||||
• <a href="qh-mem_r.htm">Mem</a> • <a href="qh-merge_r.htm">Merge</a>
|
||||
• <a href="qh-poly_r.htm">Poly</a> • <a href="qh-qhull_r.htm#TOC">Qhull</a>
|
||||
• <a href="qh-set_r.htm">Set</a> • <a href="qh-stat_r.htm">Stat</a>
|
||||
• <a href="qh-user_r.htm">User</a><br>
|
||||
</p>
|
||||
<p><!-- GC common information --> </p>
|
||||
<hr>
|
||||
<p><a href="http://www.geom.uiuc.edu/"><img
|
||||
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
|
||||
Geometry Center Home Page </i></p>
|
||||
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
|
||||
<br>
|
||||
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,499 @@
|
||||
<!-- Do not edit with Front Page, it adds too many spaces -->
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type"
|
||||
content="text/html; charset=iso-8859-1">
|
||||
<title>poly_r.c, poly2_r.c -- polyhedron operations</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- Navigation links -->
|
||||
<p><a name="TOP"><b>Up:</b></a> <a
|
||||
href="http://www.qhull.org">Home page</a> for Qhull (<a href="../index.htm">local</a>)<br>
|
||||
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: contents <br>
|
||||
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
|
||||
• <a href="../../html/qh-quick.htm#options">Options</a>
|
||||
• <a href="../../html/qh-opto.htm#output">Output</a>
|
||||
• <a href="../../html/qh-optf.htm#format">Formats</a>
|
||||
• <a href="../../html/qh-optg.htm#geomview">Geomview</a>
|
||||
• <a href="../../html/qh-optp.htm#print">Print</a>
|
||||
• <a href="../../html/qh-optq.htm#qhull">Qhull</a>
|
||||
• <a href="../../html/qh-optc.htm#prec">Precision</a>
|
||||
• <a href="../../html/qh-optt.htm#trace">Trace</a>
|
||||
• <a href="http://www.qhull.org/src/libqhull_r/index.htm">Functions</a> (<a href="index.htm">local</a>)<br>
|
||||
<b>Up:</b> <a href="../../html/qh-code.htm">Qhull code</a><br>
|
||||
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> • <a href="qh-globa_r.htm">Global</a>
|
||||
• <a href="qh-io_r.htm">Io</a> • <a href="qh-mem_r.htm">Mem</a>
|
||||
• <a href="qh-merge_r.htm">Merge</a> • <a href="qh-poly_r.htm#TOC">Poly</a>
|
||||
• <a href="qh-qhull_r.htm">Qhull</a> • <a href="qh-set_r.htm">Set</a>
|
||||
• <a href="qh-stat_r.htm">Stat</a> • <a href="qh-user_r.htm">User</a>
|
||||
</p>
|
||||
<hr>
|
||||
|
||||
<h2>poly_r.c, poly2_r.c -- polyhedron operations</h2>
|
||||
<blockquote>
|
||||
|
||||
<p>Qhull uses dimension-free terminology. Qhull builds a
|
||||
polyhedron in dimension <em>d. </em>A <em>polyhedron</em> is a
|
||||
simplicial complex of faces with geometric information for the
|
||||
top and bottom-level faces. A (<em>d-1</em>)-face is a <em>facet</em>,
|
||||
a (<em>d-2</em>)-face is a <em>ridge</em>, and a <em>0</em>-face
|
||||
is a <em>vertex</em>. For example in 3-d, a facet is a polygon
|
||||
and a ridge is an edge. A facet is built from a ridge (the <em>base</em>)
|
||||
and a vertex (the <em>apex</em>). See
|
||||
<a href="../../html/index.htm#structure">Qhull's data structures</a>.</p>
|
||||
|
||||
<p>Qhull's primary data structure is a polyhedron. A
|
||||
polyhedron is a list of facets. Each facet has a set of
|
||||
neighboring facets and a set of vertices. Each facet has a
|
||||
hyperplane. For example, a tetrahedron has four facets.
|
||||
If its vertices are <em>a, b, c, d</em>, and its facets
|
||||
are <em>1, 2, 3, 4,</em> the tetrahedron is </p>
|
||||
<blockquote>
|
||||
<ul>
|
||||
<li>facet 1 <ul>
|
||||
<li>vertices: b c d </li>
|
||||
<li>neighbors: 2 3 4 </li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>facet 2 <ul>
|
||||
<li>vertices: a c d </li>
|
||||
<li>neighbors: 1 3 4 </li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>facet 3 <ul>
|
||||
<li>vertices: a b d </li>
|
||||
<li>neighbors: 1 2 4 </li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>facet 4 <ul>
|
||||
<li>vertices: a b c </li>
|
||||
<li>neighbors: 1 2 3 </li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</blockquote>
|
||||
<p>A facet may be simplicial or non-simplicial. In 3-d, a
|
||||
<i>simplicial facet</i> has three vertices and three
|
||||
neighbors. A <i>nonsimplicial facet</i> has more than
|
||||
three vertices and more than three neighbors. A
|
||||
nonsimplicial facet has a set of ridges and a centrum. </p>
|
||||
<p>
|
||||
A simplicial facet has an orientation. An <i>orientation</i>
|
||||
is either <i>top</i> or <i>bottom</i>.
|
||||
The flag, <tt>facet->toporient,</tt>
|
||||
defines the orientation of the facet's vertices. For example in 3-d,
|
||||
'top' is left-handed orientation (i.e., the vertex order follows the direction
|
||||
of the left-hand fingers when the thumb is pointing away from the center).
|
||||
Except for axis-parallel facets in 5-d and higher, topological orientation
|
||||
determines the geometric orientation of the facet's hyperplane.
|
||||
|
||||
<p>A nonsimplicial facet is due to merging two or more
|
||||
facets. The facet's ridge set determine a simplicial
|
||||
decomposition of the facet. Each ridge is a 1-face (i.e.,
|
||||
it has two vertices and two neighboring facets). The
|
||||
orientation of a ridge is determined by the order of the
|
||||
neighboring facets. The flag, <tt>facet->toporient,</tt>is
|
||||
ignored. </p>
|
||||
<p>A nonsimplicial facet has a centrum for testing
|
||||
convexity. A <i>centrum</i> is a point on the facet's
|
||||
hyperplane that is near the center of the facet. Except
|
||||
for large facets, it is the arithmetic average of the
|
||||
facet's vertices. </p>
|
||||
<p>A nonsimplicial facet is an approximation that is
|
||||
defined by offsets from the facet's hyperplane. When
|
||||
Qhull finishes, the <i>outer plane</i> is above all
|
||||
points while the <i>inner plane</i> is below the facet's
|
||||
vertices. This guarantees that any exact convex hull
|
||||
passes between the inner and outer planes. The outer
|
||||
plane is defined by <tt>facet->maxoutside</tt> while
|
||||
the inner plane is computed from the facet's vertices.</p>
|
||||
|
||||
<p>Qhull 3.1 includes triangulation of non-simplicial facets
|
||||
('<a href="../../html/qh-optq.htm#Qt">Qt</a>').
|
||||
These facets,
|
||||
called <i>tricoplanar</i>, share the same normal. centrum, and Voronoi center.
|
||||
One facet (keepcentrum) owns these data structures.
|
||||
While tricoplanar facets are more accurate than the simplicial facets from
|
||||
joggled input, they
|
||||
may have zero area or flipped orientation.
|
||||
|
||||
</blockquote>
|
||||
<p><b>Copyright © 1995-2020 C.B. Barber</b></p>
|
||||
<hr>
|
||||
<p><a href="#TOP">»</a> <a href="qh-geom_r.htm#TOC">Geom</a>
|
||||
<a name="TOC">•</a> <a href="qh-globa_r.htm#TOC">Global</a>
|
||||
• <a href="qh-io_r.htm#TOC">Io</a> • <a href="qh-mem_r.htm#TOC">Mem</a>
|
||||
• <a href="qh-merge_r.htm#TOC">Merge</a> • <b>Poly</b>
|
||||
• <a href="qh-qhull_r.htm#TOC">Qhull</a> • <a href="qh-set_r.htm#TOC">Set</a>
|
||||
• <a href="qh-stat_r.htm#TOC">Stat</a> • <a href="qh-user_r.htm#TOC">User</a>
|
||||
</p>
|
||||
<h3>Index to <a href="poly_r.c">poly_r.c</a>,
|
||||
<a href="poly2_r.c">poly2_r.c</a>, <a href="poly_r.h">poly_r.h</a>,
|
||||
and <a href="libqhull_r.h">libqhull_r.h</a></h3>
|
||||
<ul>
|
||||
<li><a href="#ptype">Data types and global
|
||||
lists for polyhedrons</a> </li>
|
||||
<li><a href="#pconst">poly_r.h constants</a> </li>
|
||||
<li><a href="#pgall">Global FORALL macros</a> </li>
|
||||
<li><a href="#pall">FORALL macros</a> </li>
|
||||
<li><a href="#peach">FOREACH macros</a> </li>
|
||||
<li><a href="#pieach">Indexed FOREACH macros</a> </li>
|
||||
<li><a href="#pmacro">Other macros for polyhedrons</a><p> </li>
|
||||
<li><a href="#plist">Facetlist functions</a> </li>
|
||||
<li><a href="#pfacet">Facet functions</a> </li>
|
||||
<li><a href="#pvertex">Vertex, ridge, and point
|
||||
functions</a> </li>
|
||||
<li><a href="#phash">Hashtable functions</a> </li>
|
||||
<li><a href="#pnew">Allocation and deallocation
|
||||
functions</a> </li>
|
||||
<li><a href="#pcheck">Check functions</a> </li>
|
||||
</ul>
|
||||
<h3><a href="qh-poly_r.htm#TOC">»</a><a name="ptype">Data
|
||||
types and global lists for polyhedrons</a></h3>
|
||||
<ul>
|
||||
<li><a href="libqhull_r.h#facetT">facetT</a> defines a
|
||||
facet </li>
|
||||
<li><a href="libqhull_r.h#ridgeT">ridgeT</a> defines a
|
||||
ridge </li>
|
||||
<li><a href="libqhull_r.h#vertexT">vertexT</a> defines a
|
||||
vertex </li>
|
||||
<li><a href="libqhull_r.h#qh-lists">qh facet and vertex
|
||||
lists</a> lists of facets and vertices </li>
|
||||
<li><a href="libqhull_r.h#qh-set">qh global sets</a>
|
||||
global sets for merging, hashing, input, etc. </li>
|
||||
</ul>
|
||||
<h3><a href="qh-poly_r.htm#TOC">»</a><a name="pconst">poly_r.h constants</a></h3>
|
||||
<ul>
|
||||
<li><a href="poly_r.h#ALGORITHMfault">ALGORITHMfault</a>
|
||||
flag to not report errors in qh_checkconvex() </li>
|
||||
<li><a href="poly_r.h#DATAfault">DATAfault</a> flag to
|
||||
report errors in qh_checkconvex() </li>
|
||||
<li><a href="poly_r.h#DUPLICATEridge">DUPLICATEridge</a>
|
||||
special value for facet->neighbor to indicate
|
||||
a duplicate ridge </li>
|
||||
<li><a href="poly_r.h#MERGEridge">MERGEridge</a>
|
||||
special value for facet->neighbor to indicate
|
||||
a merged ridge </li>
|
||||
</ul>
|
||||
<h3><a href="qh-poly_r.htm#TOC">»</a><a name="pgall">Global FORALL
|
||||
macros</a></h3>
|
||||
<ul>
|
||||
<li><a href="libqhull_r.h#FORALLfacets">FORALLfacets</a>
|
||||
assign 'facet' to each facet in qh.facet_list </li>
|
||||
<li><a href="poly_r.h#FORALLnew_facets">FORALLnew_facets</a>
|
||||
assign 'facet' to each facet in qh.newfacet_list </li>
|
||||
<li><a href="poly_r.h#FORALLvisible_facets">FORALLvisible_facets</a>
|
||||
assign 'visible' to each visible facet in
|
||||
qh.visible_list </li>
|
||||
<li><a href="libqhull_r.h#FORALLpoints">FORALLpoints</a>
|
||||
assign 'point' to each point in qh.first_point,
|
||||
qh.num_points </li>
|
||||
<li><a href="libqhull_r.h#FORALLvertices">FORALLvertices</a>
|
||||
assign 'vertex' to each vertex in qh.vertex_list </li>
|
||||
</ul>
|
||||
<h3><a href="qh-poly_r.htm#TOC">»</a><a name="pall">FORALL macros</a></h3>
|
||||
<ul>
|
||||
<li><a href="poly_r.h#FORALLfacet_">FORALLfacet_</a>
|
||||
assign 'facet' to each facet in facetlist </li>
|
||||
<li><a href="libqhull_r.h#FORALLpoint_">FORALLpoint_</a>
|
||||
assign 'point' to each point in points array</li>
|
||||
<li><a href="poly_r.h#FORALLsame_">FORALLsame_</a>
|
||||
assign 'same' to each facet in samecycle</li>
|
||||
<li><a href="poly_r.h#FORALLsame_cycle_">FORALLsame_cycle_</a>
|
||||
assign 'same' to each facet in samecycle</li>
|
||||
<li><a href="poly_r.h#FORALLvertex_">FORALLvertex_</a>
|
||||
assign 'vertex' to each vertex in vertexlist </li>
|
||||
</ul>
|
||||
<h3><a href="qh-poly_r.htm#TOC">»</a><a name="peach">FOREACH macros</a></h3>
|
||||
<ul>
|
||||
<li><a href="libqhull_r.h#FOREACHfacet_">FOREACHfacet_</a>
|
||||
assign 'facet' to each facet in facets </li>
|
||||
<li><a href="libqhull_r.h#FOREACHneighbor_">FOREACHneighbor_</a>
|
||||
assign 'neighbor' to each facet in
|
||||
facet->neighbors or vertex->neighbors</li>
|
||||
<li><a href="poly_r.h#FOREACHnewfacet_">FOREACHnewfacet_</a>
|
||||
assign 'newfacet' to each facet in facet set </li>
|
||||
<li><a href="libqhull_r.h#FOREACHpoint_">FOREACHpoint_</a>
|
||||
assign 'point' to each point in points set </li>
|
||||
<li><a href="libqhull_r.h#FOREACHridge_">FOREACHridge_</a>
|
||||
assign 'ridge' to each ridge in ridge set </li>
|
||||
<li><a href="libqhull_r.h#FOREACHvertex_">FOREACHvertex_</a>
|
||||
assign 'vertex' to each vertex in vertex set </li>
|
||||
<li><a href="poly_r.h#FOREACHvertexA_">FOREACHvertexA_</a>
|
||||
assign 'vertexA' to each vertex in vertex set</li>
|
||||
<li><a href="poly_r.h#FOREACHvisible_">FOREACHvisible_</a>
|
||||
assign 'visible' to each facet in facet set </li>
|
||||
</ul>
|
||||
<h3><a href="qh-poly_r.htm#TOC">»</a><a name="pieach">Indexed
|
||||
FOREACH macros</a></h3>
|
||||
<ul>
|
||||
<li><a href="libqhull_r.h#FOREACHfacet_i_">FOREACHfacet_i_</a>
|
||||
assign 'facet' and 'facet_i' to each facet in
|
||||
facet set </li>
|
||||
<li><a href="libqhull_r.h#FOREACHneighbor_i_">FOREACHneighbor_i_</a>
|
||||
assign 'neighbor' and 'neighbor_i' to each facet
|
||||
in facet->neighbors or vertex->neighbors</li>
|
||||
<li><a href="libqhull_r.h#FOREACHpoint_i_">FOREACHpoint_i_</a>
|
||||
assign 'point' and 'point_i' to each point in
|
||||
points set </li>
|
||||
<li><a href="libqhull_r.h#FOREACHridge_i_">FOREACHridge_i_</a>
|
||||
assign 'ridge' and 'ridge_i' to each ridge in
|
||||
ridges set </li>
|
||||
<li><a href="libqhull_r.h#FOREACHvertex_i_">FOREACHvertex_i_</a>
|
||||
assign 'vertex' and 'vertex_i' to each vertex in
|
||||
vertices set </li>
|
||||
<li><a href="poly_r.h#FOREACHvertexreverse12_">FOREACHvertexreverse12_</a>
|
||||
assign 'vertex' to each vertex in vertex set;
|
||||
reverse the order of first two vertices </li>
|
||||
</ul>
|
||||
<h3><a href="qh-poly_r.htm#TOC">»</a><a name="pmacro">Other macros for polyhedrons</a></h3>
|
||||
<ul>
|
||||
<li><a href="libqhull_r.h#getid_">getid_</a> return ID for
|
||||
a facet, ridge, or vertex </li>
|
||||
<li><a href="libqhull_r.h#otherfacet_">otherfacet_</a>
|
||||
return neighboring facet for a ridge in a facet </li>
|
||||
</ul>
|
||||
<h3><a href="qh-poly_r.htm#TOC">»</a><a name="plist">Facetlist
|
||||
functions</a></h3>
|
||||
<ul>
|
||||
<li><a href="poly_r.c#appendfacet">qh_appendfacet</a>
|
||||
appends facet to end of qh.facet_list</li>
|
||||
<li><a href="poly_r.c#attachnewfacets">qh_attachnewfacets</a>
|
||||
attach new facets in qh.newfacet_list to the
|
||||
horizon </li>
|
||||
<li><a href="poly2_r.c#findgood">qh_findgood</a>
|
||||
identify good facets for qh.PRINTgood </li>
|
||||
<li><a href="poly2_r.c#findgood_all">qh_findgood_all</a>
|
||||
identify more good facets for qh.PRINTgood </li>
|
||||
<li><a href="poly2_r.c#furthestnext">qh_furthestnext</a>
|
||||
move facet with furthest of furthest points to
|
||||
facet_next </li>
|
||||
<li><a href="poly2_r.c#initialhull">qh_initialhull</a>
|
||||
construct the initial hull as a simplex of
|
||||
vertices </li>
|
||||
<li><a href="poly2_r.c#nearcoplanar">qh_nearcoplanar</a>
|
||||
remove near-inside points from coplanar sets</li>
|
||||
<li><a href="poly2_r.c#prependfacet">qh_prependfacet</a>
|
||||
prepends facet to start of facetlist </li>
|
||||
<li><a href="user_r.c#printfacetlist">qh_printfacetlist</a>
|
||||
print facets in a facetlist</li>
|
||||
<li><a href="poly2_r.c#printlists">qh_printlists</a>
|
||||
print out facet list for debugging </li>
|
||||
<li><a href="poly_r.c#removefacet">qh_removefacet</a>
|
||||
unlinks facet from qh.facet_list</li>
|
||||
<li><a href="poly2_r.c#resetlists">qh_resetlists</a>
|
||||
reset qh.newvertex_list, qh.newfacet_list, and
|
||||
qh.visible_list </li>
|
||||
</ul>
|
||||
<h3><a href="qh-poly_r.htm#TOC">»</a><a name="pfacet">Facet
|
||||
functions</a></h3>
|
||||
<ul>
|
||||
<li><a href="poly2_r.c#addfacetvertex">qh_addfacetvertex<a>
|
||||
add newvertex to facet.vertices if not already there</li>
|
||||
<li><a href="poly2_r.c#createsimplex">qh_createsimplex</a>
|
||||
create a simplex of facets from a set of vertices
|
||||
</li>
|
||||
<li><a href="poly2_r.c#findbestlower">qh_findbestlower</a> find best
|
||||
non-upper, non-flipped facet for point at upperfacet</li>
|
||||
<li><a href="poly2_r.c#furthestout">qh_furthestout</a>
|
||||
make furthest outside point the last point of a
|
||||
facet's outside set </li>
|
||||
<li><a href="poly_r.c#getreplacement">qh_getreplacement</a>
|
||||
get replacement facet for a visible facet
|
||||
<li><a href="poly_r.c#makenew_nonsimplicial">qh_makenew_nonsimplicial</a>
|
||||
make new facets from ridges of visible facets </li>
|
||||
<li><a href="poly_r.c#makenew_simplicial">qh_makenew_simplicial</a>
|
||||
make new facets for horizon neighbors </li>
|
||||
<li><a href="poly_r.c#makenewfacet">qh_makenewfacet</a>
|
||||
create a facet from vertices and apex </li>
|
||||
<li><a href="poly2_r.c#makenewfacets">qh_makenewfacets</a>
|
||||
make new facets from vertex, horizon facets, and
|
||||
visible facets </li>
|
||||
<li><a href="poly_r.c#makenewplanes">qh_makenewplanes</a>
|
||||
make new hyperplanes for facets </li>
|
||||
<li><a href="poly2_r.c#nextfacet2d">qh_nextfacet2d</a>
|
||||
return next facet and vertex for a 2d facet in qh_ORIENTclock order </li>
|
||||
<li><a href="poly2_r.c#opposite_vertex">qh_opposite_vertex</a>
|
||||
return the opposite vertex in facetA to neighbor </li>
|
||||
<li><a href="poly2_r.c#outcoplanar">qh_outcoplanar</a>
|
||||
move points from outside set to coplanar set </li>
|
||||
<li><a href="poly2_r.c#replacefacetvertex">qh_replacefacetvertex<a>
|
||||
replace oldvertex with newvertex in facet.vertices</li>
|
||||
<li><a href="poly2_r.c#setvoronoi_all">qh_setvoronoi_all</a>
|
||||
compute Voronoi centers for all facets </li>
|
||||
<li><a href="poly2_r.c#triangulate">qh_triangulate</a>
|
||||
triangulate non-simplicial facets</li>
|
||||
<li><a href="poly2_r.c#triangulate_facet">qh_triangulate_facet</a>
|
||||
triangulate a non-simplicial facet</li>
|
||||
<li><a href="poly2_r.c#triangulate_link">qh_triangulate_link</a>
|
||||
link facets together from qh_triangulate</li>
|
||||
<li><a href="poly2_r.c#triangulate_mirror">qh_triangulate_mirror</a>
|
||||
delete mirrored facets from qh_triangulate</li>
|
||||
<li><a href="poly2_r.c#triangulate_null">qh_triangulate_null</a>
|
||||
delete null facet from qh_triangulate</li>
|
||||
</ul>
|
||||
<h3><a href="qh-poly_r.htm#TOC">»</a><a name="pvertex">Vertex,
|
||||
ridge, and point functions</a></h3>
|
||||
<ul>
|
||||
<li><a href="poly_r.c#appendvertex">qh_appendvertex</a>
|
||||
append vertex to end of qh.vertex_list, </li>
|
||||
<li><a href="io_r.c#detvridge">qh_detvridge</a> determine Voronoi
|
||||
ridge for an input site
|
||||
<li><a href="io_r.c#detvridge3">qh_detvridge3</a> determine 3-d Voronoi
|
||||
ridge for an input site
|
||||
<li><a href="poly2_r.c#facet3vertex">qh_facet3vertex</a>
|
||||
return an oriented vertex set for a 3-d facet </li>
|
||||
<li><a href="poly_r.c#facetintersect">qh_facetintersect</a>
|
||||
return intersection of simplicial facets </li>
|
||||
<li><a href="poly2_r.c#initialvertices">qh_initialvertices</a>
|
||||
return non-singular set of initial vertices </li>
|
||||
<li><a href="poly2_r.c#isvertex">qh_isvertex</a> true
|
||||
if point is in a vertex set </li>
|
||||
<li><a href="poly2_r.c#nearvertex">qh_nearvertex</a>
|
||||
return nearest vertex to point </li>
|
||||
<li><a href="merge_r.c#neighbor_vertices">qh_neighbor_vertices</a>
|
||||
return neighboring vertices for a vertex </li>
|
||||
<li><a href="poly2_r.c#nextridge3d">qh_nextridge3d</a>
|
||||
iterate over each ridge and vertex for a 3-d
|
||||
facet </li>
|
||||
<li><a href="poly2_r.c#point">qh_point</a> return point
|
||||
for a point ID </li>
|
||||
<li><a href="poly2_r.c#pointfacet">qh_pointfacet</a>
|
||||
return temporary set of facets indexed by point
|
||||
ID </li>
|
||||
<li><a href="poly_r.c#pointid">qh_pointid</a> return ID
|
||||
for a point</li>
|
||||
<li><a href="poly2_r.c#pointvertex">qh_pointvertex</a>
|
||||
return temporary set of vertices indexed by point
|
||||
ID </li>
|
||||
<li><a href="poly_r.c#removevertex">qh_removevertex</a>
|
||||
unlink vertex from qh.vertex_list, </li>
|
||||
<li><a href="poly_r.c#update_vertexneighbors">qh_update_vertexneighbors</a>
|
||||
update vertex neighbors and delete interior
|
||||
vertices </li>
|
||||
<li><a href="poly_r.c#update_vertexneighbors_cone">qh_update_vertexneighbors_cone</a>
|
||||
update vertex neighbors for a cone of new facets and delete interior
|
||||
vertices </li>
|
||||
<li><a href="poly2_r.c#vertexintersect">qh_vertexintersect</a>
|
||||
intersect two vertex sets </li>
|
||||
<li><a href="poly2_r.c#vertexintersect_new">qh_vertexintersect_new</a>
|
||||
return intersection of two vertex sets </li>
|
||||
<li><a href="poly2_r.c#vertexneighbors">qh_vertexneighbors</a>
|
||||
for each vertex in hull, determine facet
|
||||
neighbors </li>
|
||||
<li><a href="poly2_r.c#vertexsubset">qh_vertexsubset</a>
|
||||
returns True if vertexsetA is a subset of
|
||||
vertexsetB </li>
|
||||
</ul>
|
||||
<h3><a href="qh-poly_r.htm#TOC">»</a><a name="phash">Hashtable functions</a></h3>
|
||||
<ul>
|
||||
<li><a href="poly2_r.c#addhash">qh_addhash</a> add hash
|
||||
element to linear hash table</li>
|
||||
<li><a href="poly_r.c#gethash">qh_gethash</a> return
|
||||
hash value for a set</li>
|
||||
<li><a href="poly2_r.c#matchdupridge">qh_matchdupridge</a>
|
||||
match duplicate ridges in hash table with a coplanar facet or pinched vertex</li>
|
||||
<li><a href="poly2_r.c#matchdupridge_coplanarhorizon">qh_matchdupridge_coplanarhorizon</a>
|
||||
match duplicate ridges in hash table with a coplanar horizon</li>
|
||||
<li><a href="poly_r.c#matchneighbor">qh_matchneighbor</a>
|
||||
try to match subridge of new facet with a neighbor </li>
|
||||
<li><a href="poly_r.c#matchnewfacets">qh_matchnewfacets</a>
|
||||
match new facets with their new facet neighbors </li>
|
||||
<li><a href="poly_r.c#matchvertices">qh_matchvertices</a>
|
||||
tests whether a facet and hash entry match at a
|
||||
ridge </li>
|
||||
<li><a href="poly2_r.c#newhashtable">qh_newhashtable</a>
|
||||
allocate a new qh.hash_table </li>
|
||||
<li><a href="poly2_r.c#printhashtable">qh_printhashtable</a>
|
||||
print hash table </li>
|
||||
<li><a href="poly2_r.c#printlists">qh_printlists</a>
|
||||
print out facet lists for debugging </li>
|
||||
</ul>
|
||||
<h3><a href="qh-poly_r.htm#TOC">»</a><a name="pnew">Allocation and
|
||||
deallocation functions</a></h3>
|
||||
<ul>
|
||||
<li><a href="poly2_r.c#clearcenters">qh_clearcenters</a>
|
||||
clear old data from facet->center </li>
|
||||
<li><a href="poly_r.c#deletevisible">qh_deletevisible</a>
|
||||
delete visible facets and vertices </li>
|
||||
<li><a href="poly_r.c#delfacet">qh_delfacet</a> free up
|
||||
the memory occupied by a facet </li>
|
||||
<li><a href="poly2_r.c#delridge">qh_delridge</a> free up
|
||||
the memory occupied by a ridge </li>
|
||||
<li><a href="poly2_r.c#delvertex">qh_delvertex</a>
|
||||
delete vertex </li>
|
||||
<li><a href="poly_r.c#newfacet">qh_newfacet</a> create
|
||||
and allocate space for a facet </li>
|
||||
<li><a href="poly_r.c#newridge">qh_newridge</a> create
|
||||
and allocate space for a ridge </li>
|
||||
<li><a href="poly2_r.c#newvertex">qh_newvertex</a>
|
||||
create and allocate space for a vertex </li>
|
||||
</ul>
|
||||
<h3><a href="qh-poly_r.htm#TOC">»</a><a name="pcheck">Check
|
||||
functions</a></h3>
|
||||
<ul>
|
||||
<li><a href="poly2_r.c#check_bestdist">qh_check_bestdist</a>
|
||||
check that points are not outside of facets </li>
|
||||
<li><a href="poly2_r.c#check_maxout">qh_check_maxout</a>
|
||||
updates qh.max_outside and checks all points
|
||||
against bestfacet </li>
|
||||
<li><a href="poly2_r.c#check_output">qh_check_output</a>
|
||||
check topological and geometric output</li>
|
||||
<li><a href="poly2_r.c#check_point">qh_check_point</a>
|
||||
check that point is not outside of facet </li>
|
||||
<li><a href="poly2_r.c#check_points">qh_check_points</a>
|
||||
check that all points are inside all facets </li>
|
||||
<li><a href="poly2_r.c#checkconvex">qh_checkconvex</a>
|
||||
check that each ridge in facetlist is convex </li>
|
||||
<li><a href="poly2_r.c#checkfacet">qh_checkfacet</a>
|
||||
check for consistency errors in facet </li>
|
||||
<li><a href="poly_r.c#checkflipped">qh_checkflipped</a>
|
||||
check facet orientation to the interior point </li>
|
||||
<li><a href="poly2_r.c#checkflipped_all">qh_checkflipped_all</a>
|
||||
check facet orientation for a facet list </li>
|
||||
<li><a href="poly2_r.c#checklists">qh_checklists</a>
|
||||
Check and repair facetlist and its vertexlist for infinite loops or overwritten facets/vertices </li>
|
||||
<li><a href="poly2_r.c#checkpolygon">qh_checkpolygon</a>
|
||||
check topological structure </li>
|
||||
<li><a href="poly2_r.c#checkvertex">qh_checkvertex</a>
|
||||
check vertex for consistency </li>
|
||||
<li><a href="poly2_r.c#infiniteloop">qh_infiniteloop</a>
|
||||
report error for a loop of facets </li>
|
||||
</ul>
|
||||
|
||||
|
||||
<p><!-- Navigation links --> </p>
|
||||
<hr>
|
||||
<p><b>Up:</b>
|
||||
<a href="http://www.qhull.org">Home page</a> for
|
||||
Qhull (<a href="../index.htm">local</a>)<br>
|
||||
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: contents<br>
|
||||
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
|
||||
• <a href="../../html/qh-quick.htm#options">Options</a>
|
||||
• <a href="../../html/qh-opto.htm#output">Output</a>
|
||||
• <a href="../../html/qh-optf.htm#format">Formats</a>
|
||||
• <a href="../../html/qh-optg.htm#geomview">Geomview</a>
|
||||
• <a href="../../html/qh-optp.htm#print">Print</a>
|
||||
• <a href="../../html/qh-optq.htm#qhull">Qhull</a>
|
||||
• <a href="../../html/qh-optc.htm#prec">Precision</a>
|
||||
• <a href="../../html/qh-optt.htm#trace">Trace</a>
|
||||
• <a href="http://www.qhull.org/src/libqhull_r/index.htm">Functions</a> (<a href="index.htm">local</a>)<br>
|
||||
<b>Up:</b> <a href="../../html/qh-code.htm">Qhull code</a> <br>
|
||||
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> •
|
||||
<a href="qh-globa_r.htm">Global</a> • <a href="qh-io_r.htm">Io</a>
|
||||
• <a href="qh-mem_r.htm">Mem</a> • <a href="qh-merge_r.htm">Merge</a>
|
||||
• <a href="qh-poly_r.htm">Poly</a> • <a href="qh-qhull_r.htm#TOC">Qhull</a>
|
||||
• <a href="qh-set_r.htm">Set</a> • <a href="qh-stat_r.htm">Stat</a>
|
||||
• <a href="qh-user_r.htm">User</a><br>
|
||||
</p>
|
||||
<p><!-- GC common information --> </p>
|
||||
<hr>
|
||||
<p><a href="http://www.geom.uiuc.edu/"><img
|
||||
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
|
||||
Geometry Center Home Page </i></p>
|
||||
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
|
||||
<br>
|
||||
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,279 @@
|
||||
<!-- Do not edit with Front Page, it adds too many spaces -->
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type"
|
||||
content="text/html; charset=iso-8859-1">
|
||||
<title>libqhull_r.c -- top-level functions and basic data types</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- Navigation links -->
|
||||
<p><a name="TOP"><b>Up:</b></a> <a
|
||||
href="http://www.qhull.org">Home page</a> for Qhull (<a href="../index.htm">local</a>)<br>
|
||||
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: contents <br>
|
||||
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
|
||||
• <a href="../../html/qh-quick.htm#options">Options</a>
|
||||
• <a href="../../html/qh-opto.htm#output">Output</a>
|
||||
• <a href="../../html/qh-optf.htm#format">Formats</a>
|
||||
• <a href="../../html/qh-optg.htm#geomview">Geomview</a>
|
||||
• <a href="../../html/qh-optp.htm#print">Print</a>
|
||||
• <a href="../../html/qh-optq.htm#qhull">Qhull</a>
|
||||
• <a href="../../html/qh-optc.htm#prec">Precision</a>
|
||||
• <a href="../../html/qh-optt.htm#trace">Trace</a>
|
||||
• <a href="http://www.qhull.org/src/libqhull_r/index.htm">Functions</a> (<a href="index.htm">local</a>)<br>
|
||||
<b>Up:</b> <a href="../../html/qh-code.htm">Qhull code</a><br>
|
||||
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> • <a href="qh-globa_r.htm">Global</a>
|
||||
• <a href="qh-io_r.htm">Io</a> • <a href="qh-mem_r.htm">Mem</a>
|
||||
• <a href="qh-merge_r.htm">Merge</a> • <a href="qh-poly_r.htm">Poly</a>
|
||||
• <a href="qh-qhull_r.htm#TOC">Qhull</a> • <a href="qh-set_r.htm">Set</a>
|
||||
• <a href="qh-stat_r.htm">Stat</a> • <a href="qh-user_r.htm">User</a>
|
||||
</p>
|
||||
<hr>
|
||||
|
||||
<h2>libqhull_r.c -- top-level functions and basic data types</h2>
|
||||
<blockquote>
|
||||
<p>Qhull implements the Quickhull algorithm for computing
|
||||
the convex hull. The Quickhull algorithm combines two
|
||||
well-known algorithms: the 2-d quickhull algorithm and
|
||||
the n-d beneath-beyond algorithm. See
|
||||
<a href="../../html/index.htm#description">Description of Qhull</a>. </p>
|
||||
<p>This section provides an index to the top-level
|
||||
functions and base data types. The top-level header file, <tt>libqhull_r.h</tt>,
|
||||
contains prototypes for these functions.</p>
|
||||
</blockquote>
|
||||
<p><b>Copyright © 1995-2020 C.B. Barber</b></p>
|
||||
<hr>
|
||||
<p><a href="#TOP">»</a> <a href="qh-geom_r.htm#TOC">Geom</a>
|
||||
<a name="TOC">•</a> <a href="qh-globa_r.htm#TOC">Global</a>
|
||||
• <a href="qh-io_r.htm#TOC">Io</a> • <a href="qh-mem_r.htm#TOC">Mem</a>
|
||||
• <a href="qh-merge_r.htm#TOC">Merge</a> • <a href="qh-poly_r.htm#TOC">Poly</a>
|
||||
• <b>Qhull</b> • <a href="qh-set_r.htm#TOC">Set</a>
|
||||
• <a href="qh-stat_r.htm#TOC">Stat</a> • <a href="qh-user_r.htm#TOC">User</a>
|
||||
</p>
|
||||
<h3>Index to <a href="libqhull_r.c">libqhull_r.c</a>,
|
||||
<a href="libqhull_r.h">libqhull_r.h</a>, and
|
||||
<a href="../qhull/unix_r.c">unix_r.c</a></h3>
|
||||
<ul>
|
||||
<li><a href="#qtype">libqhull_r.h and unix_r.c data types and
|
||||
constants</a> </li>
|
||||
<li><a href="#qmacro">libqhull_r.h other macros</a> </li>
|
||||
<li><a href="#qfunc">Quickhull routines in call order</a> </li>
|
||||
<li><a href="#qinit">Top-level routines for initializing and terminating Qhull</a></li>
|
||||
<li><a href="#qin">Top-level routines for reading and modifying the input</a></li>
|
||||
<li><a href="#qcall">Top-level routines for calling Qhull</a></li>
|
||||
<li><a href="#qout">Top-level routines for returning results</a></li>
|
||||
<li><a href="#qtest">Top-level routines for testing and debugging</a></li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-qhull_r.htm#TOC">»</a><a name="qtype">libqhull_r.h and unix_r.c
|
||||
data types and constants</a></h3>
|
||||
<ul>
|
||||
<li><a href="libqhull_r.h#flagT">flagT</a> Boolean flag as
|
||||
a bit </li>
|
||||
<li><a href="libqhull_r.h#boolT">boolT</a> boolean value,
|
||||
either True or False </li>
|
||||
<li><a href="libqhull_r.h#CENTERtype">CENTERtype</a> to
|
||||
distinguish facet->center </li>
|
||||
<li><a href="libqhull_r.h#qh_PRINT">qh_PRINT</a> output
|
||||
formats for printing (qh.PRINTout) </li>
|
||||
<li><a href="libqhull_r.h#qh_ALL">qh_ALL</a> argument flag
|
||||
for selecting everything </li>
|
||||
<li><a href="libqhull_r.h#qh_ERR">qh_ERR</a> Qhull exit status codes
|
||||
for indicating errors </li>
|
||||
<li><a href="libqhull_r.h#qh_FILEstderr">qh_FILEstderr</a> Fake stderr
|
||||
to distinguish error output from normal output [C++ only]</li>
|
||||
<li><a href="../qhull/unix_r.c#prompt">qh_prompt</a> version and long prompt for Qhull</li>
|
||||
<li><a href="../qhull/unix_r.c#prompt2">qh_prompt2</a> synopsis for Qhull</li>
|
||||
<li><a href="../qhull/unix_r.c#prompt3">qh_prompt3</a> concise prompt for Qhull</li>
|
||||
<li><a href="global_r.c#version">qh_version</a> version stamp</li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-qhull_r.htm#TOC">»</a><a name="qmacro">libqhull_r.h other
|
||||
macros</a></h3>
|
||||
<ul>
|
||||
<li><a href="qhull_ra.h#traceN">traceN</a> print trace
|
||||
message if <em>qh.IStracing >= N</em>. </li>
|
||||
<li><a href="qhull_ra.h#QHULL_UNUSED">QHULL_UNUSED</a> declare an
|
||||
unused variable to avoid warnings. </li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-qhull_r.htm#TOC">»</a><a name="qfunc">Quickhull
|
||||
routines in call order</a></h3>
|
||||
<ul>
|
||||
<li><a href="../qhull/unix_r.c#main">main</a> processes the
|
||||
command line, calls qhull() to do the work, and
|
||||
exits </li>
|
||||
<li><a href="libqhull_r.c#qhull">qh_qhull</a> construct
|
||||
the convex hull of a set of points </li>
|
||||
<li><a href="libqhull_r.c#build_withrestart">qh_build_withrestart</a>
|
||||
allow restarts while calling qh_buildhull</li>
|
||||
<li><a href="poly2_r.c#initbuild">qh_initbuild</a>
|
||||
initialize hull and outside sets with point array</li>
|
||||
<li><a href="libqhull_r.c#partitionall">qh_partitionall</a>
|
||||
partition all points into outside sets </li>
|
||||
<li><a href="libqhull_r.c#buildhull">qh_buildhull</a>
|
||||
construct a convex hull by adding points one at a
|
||||
time </li>
|
||||
<li><a href="libqhull_r.c#nextfurthest">qh_nextfurthest</a>
|
||||
return next furthest point for processing </li>
|
||||
<li><a href="libqhull_r.c#buildtracing">qh_buildtracing</a>
|
||||
trace an iteration of buildhull </li>
|
||||
<li><a href="libqhull_r.c#addpoint">qh_addpoint</a> add a
|
||||
point to the convex hull </li>
|
||||
<li><a href="libqhull_r.c#findhorizon">qh_findhorizon</a>
|
||||
find the horizon and visible facets for a point </li>
|
||||
<li><a href="libqhull_r.c#buildcone">qh_buildcone</a>
|
||||
build cone of new facets from furthest to the horizon </li>
|
||||
<li><a href="merge_r.c#premerge">qh_premerge</a>
|
||||
pre-merge non-convex facets </li>
|
||||
<li><a href="libqhull_r.c#partitionvisible">qh_partitionvisible</a>
|
||||
partition points from facets in qh.visible_list
|
||||
to facets in qh.newfacet_list </li>
|
||||
<li><a href="libqhull_r.c#partitionpoint">qh_partitionpoint</a>
|
||||
partition a point as inside, coplanar with, or
|
||||
outside a facet </li>
|
||||
<li><a href="libqhull_r.c#partitioncoplanar">qh_partitioncoplanar</a>
|
||||
partition coplanar point into a facet </li>
|
||||
<li><a href="libqhull_r.c#joggle_restart">qh_joggle_restart</a>
|
||||
if joggle ('QJn') and not merging, restart on precision errors</li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-qhull_r.htm#TOC">»</a><a name="qinit">Top-level routines for initializing and terminating Qhull (in other modules)</a></h3>
|
||||
<ul>
|
||||
<li><a href="global_r.c#freebuild">qh_freebuild</a>
|
||||
free memory used by qh_initbuild and qh_buildhull </li>
|
||||
<li><a href="global_r.c#freeqhull">qh_freeqhull</a>
|
||||
free memory used by qhull </li>
|
||||
<li><a href="global_r.c#init_A">qh_init_A</a> called
|
||||
before error handling initialized </li>
|
||||
<li><a href="global_r.c#init_B">qh_init_B</a> called
|
||||
after points are defined </li>
|
||||
<li><a href="global_r.c#initflags">qh_initflags</a> set
|
||||
flags and constants from command line </li>
|
||||
<li><a href="rboxlib_r.c#rboxpoints">qh_rboxpoints</a>
|
||||
generate points for qhull </li>
|
||||
<li><a href="global_r.c#restore_qhull">qh_restore_qhull</a>
|
||||
restores a saved qhull </li>
|
||||
<li><a href="global_r.c#save_qhull">qh_save_qhull</a>
|
||||
saves qhull for later restoring </li>
|
||||
<li><a href="user_r.c#user_memsizes">qh_user_memsizes</a>
|
||||
define additional quick allocation sizes
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-qhull_r.htm#TOC">»</a><a name="qin">Top-level routines for reading and modifying the input (in other modules)</a></h3>
|
||||
<ul>
|
||||
<li><a href="geom2_r.c#gram_schmidt">qh_gram_schmidt</a>
|
||||
implements Gram-Schmidt orthogonalization by rows </li>
|
||||
<li><a href="geom2_r.c#projectinput">qh_projectinput</a>
|
||||
project input along one or more dimensions +
|
||||
Delaunay projection </li>
|
||||
<li><a href="geom2_r.c#randommatrix">qh_randommatrix</a>
|
||||
generate a random dimXdim matrix in range (-1,1) </li>
|
||||
<li><a href="io_r.c#readpoints">qh_readpoints</a> read
|
||||
points from input </li>
|
||||
<li><a href="geom2_r.c#rotateinput">qh_rotateinput</a> rotate
|
||||
input points using row matrix </li>
|
||||
<li><a href="geom2_r.c#scaleinput">qh_scaleinput</a> scale
|
||||
input points using qh low_bound/high_bound </li>
|
||||
<li><a href="geom2_r.c#setdelaunay">qh_setdelaunay</a> project
|
||||
points to paraboloid for Delaunay triangulation </li>
|
||||
<li><a href="geom2_r.c#sethalfspace_all">qh_sethalfspace_all</a>
|
||||
generate dual for halfspace intersection with interior
|
||||
point </li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-qhull_r.htm#TOC">»</a><a name="qcall">Top-level routines for calling Qhull (in other modules)</a></h3>
|
||||
<ul>
|
||||
<li><a href="libqhull_r.c#addpoint">qh_addpoint</a> add
|
||||
point to convex hull </li>
|
||||
<li><a href="poly2_r.c#findbestfacet">qh_findbestfacet</a>
|
||||
find facet that is furthest below a point </li>
|
||||
<li><a href="poly2_r.c#findfacet_all">qh_findfacet_all</a>
|
||||
exhaustive search for facet below a point </li>
|
||||
<li><a href="libqhull_r.c#qhull">qh_qhull</a> construct
|
||||
the convex hull of a set of points </li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-qhull_r.htm#TOC">»</a><a name="qout">Top-level routines for returning results (in other modules)</a></h3>
|
||||
<ul>
|
||||
<li><a href="stat_r.c#collectstatistics">qh_collectstatistics</a>
|
||||
collect statistics for qh.facet_list </li>
|
||||
<li><a href="poly2_r.c#nearvertex">qh_nearvertex</a>
|
||||
return nearest vertex to point </li>
|
||||
<li><a href="poly2_r.c#point">qh_point</a> return point
|
||||
for a point ID </li>
|
||||
<li><a href="poly2_r.c#pointfacet">qh_pointfacet</a>
|
||||
return temporary set of facets indexed by point
|
||||
ID </li>
|
||||
<li><a href="poly_r.c#pointid">qh_pointid</a> return ID
|
||||
for a point</li>
|
||||
<li><a href="poly2_r.c#pointvertex">qh_pointvertex</a>
|
||||
return vertices (if any) for all points</li>
|
||||
<li><a href="stat_r.c#printallstatistics">qh_printallstatistics</a>
|
||||
print all statistics </li>
|
||||
<li><a href="io_r.c#printneighborhood">qh_printneighborhood</a>
|
||||
print neighborhood of one or two facets </li>
|
||||
<li><a href="libqhull_r.c#printsummary">qh_printsummary</a>
|
||||
print summary </li>
|
||||
<li><a href="io_r.c#produce_output">qh_produce_output</a>
|
||||
print the results of qh_qhull() </li>
|
||||
<li><a href="poly2_r.c#setvoronoi_all">qh_setvoronoi_all</a>
|
||||
compute Voronoi centers for all facets </li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-qhull_r.htm#TOC">»</a><a name="qtest">Top-level routines for testing and debugging (in other modules)</a></h3>
|
||||
<ul>
|
||||
<li><a href="io_r.c#dfacet">dfacet</a> print facet by
|
||||
ID from debugger </li>
|
||||
<li><a href="io_r.c#dvertex">dvertex</a> print vertex
|
||||
by ID from debugger </li>
|
||||
<li><a href="poly2_r.c#check_output">qh_check_output</a>
|
||||
check output </li>
|
||||
<li><a href="poly2_r.c#check_points">qh_check_points</a>
|
||||
verify that all points are inside the convex hull
|
||||
</li>
|
||||
<li><a href="user_r.c#errexit">qh_errexit</a> report
|
||||
error with a facet and a ridge</li>
|
||||
<li><a href="libqhull_r.c#errexit2">qh_errexit2</a> report
|
||||
error with two facets </li>
|
||||
<li><a href="user_r.c#errprint">qh_errprint</a> print
|
||||
erroneous facets, ridge, and vertex </li>
|
||||
<li><a href="user_r.c#printfacetlist">qh_printfacetlist</a>
|
||||
print all fields for a list of facets </li>
|
||||
</ul>
|
||||
|
||||
<p><!-- Navigation links --> </p>
|
||||
<hr>
|
||||
<p><b>Up:</b>
|
||||
<a href="http://www.qhull.org">Home page</a> for
|
||||
Qhull (<a href="../index.htm">local</a>)<br>
|
||||
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: contents<br>
|
||||
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
|
||||
• <a href="../../html/qh-quick.htm#options">Options</a>
|
||||
• <a href="../../html/qh-opto.htm#output">Output</a>
|
||||
• <a href="../../html/qh-optf.htm#format">Formats</a>
|
||||
• <a href="../../html/qh-optg.htm#geomview">Geomview</a>
|
||||
• <a href="../../html/qh-optp.htm#print">Print</a>
|
||||
• <a href="../../html/qh-optq.htm#qhull">Qhull</a>
|
||||
• <a href="../../html/qh-optc.htm#prec">Precision</a>
|
||||
• <a href="../../html/qh-optt.htm#trace">Trace</a>
|
||||
• <a href="http://www.qhull.org/src/libqhull_r/index.htm">Functions</a> (<a href="index.htm">local</a>)<br>
|
||||
<b>Up:</b> <a href="../../html/qh-code.htm">Qhull code</a> <br>
|
||||
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> •
|
||||
<a href="qh-globa_r.htm">Global</a> • <a href="qh-io_r.htm">Io</a>
|
||||
• <a href="qh-mem_r.htm">Mem</a> • <a href="qh-merge_r.htm">Merge</a>
|
||||
• <a href="qh-poly_r.htm">Poly</a> • <a href="qh-qhull_r.htm#TOC">Qhull</a>
|
||||
• <a href="qh-set_r.htm">Set</a> • <a href="qh-stat_r.htm">Stat</a>
|
||||
• <a href="qh-user_r.htm">User</a><br>
|
||||
</p>
|
||||
<p><!-- GC common information --> </p>
|
||||
<hr>
|
||||
<p><a href="http://www.geom.uiuc.edu/"><img
|
||||
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
|
||||
Geometry Center Home Page </i></p>
|
||||
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
|
||||
<br>
|
||||
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,307 @@
|
||||
<!-- Do not edit with Front Page, it adds too many spaces -->
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type"
|
||||
content="text/html; charset=iso-8859-1">
|
||||
<title>qset_r.c -- set data type and operations</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- Navigation links -->
|
||||
<p><a name="TOP"><b>Up:</b></a> <a
|
||||
href="http://www.qhull.org">Home page</a> for Qhull (<a href="../index.htm">local</a>)<br>
|
||||
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: contents <br>
|
||||
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
|
||||
• <a href="../../html/qh-quick.htm#options">Options</a>
|
||||
• <a href="../../html/qh-opto.htm#output">Output</a>
|
||||
• <a href="../../html/qh-optf.htm#format">Formats</a>
|
||||
• <a href="../../html/qh-optg.htm#geomview">Geomview</a>
|
||||
• <a href="../../html/qh-optp.htm#print">Print</a>
|
||||
• <a href="../../html/qh-optq.htm#qhull">Qhull</a>
|
||||
• <a href="../../html/qh-optc.htm#prec">Precision</a>
|
||||
• <a href="../../html/qh-optt.htm#trace">Trace</a>
|
||||
• <a href="http://www.qhull.org/src/libqhull_r/index.htm">Functions</a> (<a href="index.htm">local</a>)<br>
|
||||
<b>Up:</b> <a href="../../html/qh-code.htm">Qhull code</a><br>
|
||||
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> • <a href="qh-globa_r.htm">Global</a>
|
||||
• <a href="qh-io_r.htm">Io</a> • <a href="qh-mem_r.htm">Mem</a>
|
||||
• <a href="qh-merge_r.htm">Merge</a> • <a href="qh-poly_r.htm">Poly</a>
|
||||
• <a href="qh-qhull_r.htm">Qhull</a> • <a href="qh-set_r.htm#TOC">Set</a>
|
||||
• <a href="qh-stat_r.htm">Stat</a> • <a href="qh-user_r.htm">User</a>
|
||||
</p>
|
||||
<hr>
|
||||
|
||||
<h2>qset_r.c -- set data type and operations</h2>
|
||||
<blockquote>
|
||||
<p>Qhull's data structures are constructed from sets. The
|
||||
functions and macros in qset_r.c construct, iterate, and
|
||||
modify these sets. They are the most frequently called
|
||||
functions in Qhull. For this reason, efficiency is the
|
||||
primary concern. </p>
|
||||
<p>In Qhull, a <i>set</i> is represented by an unordered
|
||||
array of pointers with a maximum size and a NULL
|
||||
terminator (<a href="qset_r.h#setT">setT</a>).
|
||||
Most sets correspond to mathematical sets
|
||||
(i.e., the pointers are unique). Some sets are sorted to
|
||||
enforce uniqueness. Some sets are ordered. For example,
|
||||
the order of vertices in a ridge determine the ridge's
|
||||
orientation. If you reverse the order of adjacent
|
||||
vertices, the orientation reverses. Some sets are not
|
||||
mathematical sets. They may be indexed as an array and
|
||||
they may include NULL pointers. </p>
|
||||
<p>The most common operation on a set is to iterate its
|
||||
members. This is done with a 'FOREACH...' macro. Each set
|
||||
has a custom macro. For example, 'FOREACHvertex_'
|
||||
iterates over a set of vertices. Each vertex is assigned
|
||||
to the variable 'vertex' from the pointer 'vertexp'. </p>
|
||||
<p>Most sets are constructed by appending elements to the
|
||||
set. The last element of a set is either NULL or the
|
||||
index of the terminating NULL for a partially full set.
|
||||
If a set is full, appending an element copies the set to
|
||||
a larger array. </p>
|
||||
|
||||
</blockquote>
|
||||
<p><b>Copyright © 1995-2020 C.B. Barber</b></p>
|
||||
<hr>
|
||||
<p><a href="#TOP">»</a> <a href="qh-geom_r.htm#TOC">Geom</a>
|
||||
<a name="TOC">•</a> <a href="qh-globa_r.htm#TOC">Global</a> •
|
||||
<a href="qh-io_r.htm#TOC">Io</a> • <a href="qh-mem_r.htm#TOC">Mem</a> •
|
||||
<a href="qh-merge_r.htm#TOC">Merge</a> • <a href="qh-poly_r.htm#TOC">Poly</a>
|
||||
• <a href="qh-qhull_r.htm#TOC">Qhull</a> • <b>Set</b>
|
||||
• <a href="qh-stat_r.htm#TOC">Stat</a> • <a href="qh-user_r.htm#TOC">User</a>
|
||||
</p>
|
||||
<h3>Index to <a href="qset_r.c">qset_r.c</a> and
|
||||
<a href="qset_r.h">qset_r.h</a></h3>
|
||||
<ul>
|
||||
<li><a href="#stype">Data types and constants</a> </li>
|
||||
<li><a href="#seach">FOREACH macros</a> </li>
|
||||
<li><a href="#saccess">access and size macros</a> </li>
|
||||
<li><a href="#sint">internal macros</a> </li>
|
||||
<li><a href="#saddr">address macros</a><p> </li>
|
||||
|
||||
<li><a href="#snew">Allocation and deallocation functions</a> </li>
|
||||
<li><a href="#spred">Access and predicate functions</a>
|
||||
</li>
|
||||
<li><a href="#sadd">Add functions</a> </li>
|
||||
<li><a href="#scheck">Check and print functions</a></li>
|
||||
<li><a href="#scopy">Copy, compact, and zero functions</a></li>
|
||||
<li><a href="#sdel">Delete functions</a> </li>
|
||||
<li><a href="#stemp">Temporary set functions</a> </li>
|
||||
</ul>
|
||||
<h3><a href="qh-set_r.htm#TOC">»</a><a name="stype">Data types and
|
||||
constants</a></h3>
|
||||
<ul>
|
||||
<li><a href="qset_r.h#SETelemsize">SETelemsize</a> size
|
||||
of a set element in bytes </li>
|
||||
<li><a href="qset_r.h#setT">setT</a> a set with a
|
||||
maximum size and a current size</li>
|
||||
<li><a href="libqhull_r.h#qh-set">qh global sets</a>
|
||||
global sets for temporary sets, etc. </li>
|
||||
</ul>
|
||||
<h3><a href="qh-set_r.htm#TOC">»</a><a name="seach">FOREACH macros</a></h3>
|
||||
<ul>
|
||||
<li><a href="qset_r.h#FOREACHelem_">FOREACHelem_</a>
|
||||
assign 'elem' to each element in a set </li>
|
||||
<li><a href="qset_r.h#FOREACHset_">FOREACHset_</a>
|
||||
assign 'set' to each set in a set of sets </li>
|
||||
<li><a href="qset_r.h#FOREACHsetelement_">FOREACHsetelement_</a>
|
||||
define a FOREACH iterator </li>
|
||||
<li><a href="qset_r.h#FOREACHsetelement_i_">FOREACHsetelement_i_</a>
|
||||
define an indexed FOREACH iterator </li>
|
||||
<li><a href="qset_r.h#FOREACHsetelementreverse_">FOREACHsetelementreverse_</a>
|
||||
define a reversed FOREACH iterator </li>
|
||||
<li><a href="qset_r.h#FOREACHsetelementreverse12_">FOREACHsetelementreverse12_</a>
|
||||
define a FOREACH iterator with e[1] and e[0]
|
||||
reversed </li>
|
||||
</ul>
|
||||
<h3><a href="qh-set_r.htm#TOC">»</a><a name="saccess">Access and
|
||||
size macros</a></h3>
|
||||
<ul>
|
||||
<li><a href="qset_r.h#SETelem_">SETelem_</a> return the
|
||||
n'th element of set </li>
|
||||
<li><a href="qset_r.h#SETelemt_">SETelemt_</a> return
|
||||
the n'th element of set as a type</li>
|
||||
<li><a href="qset_r.h#SETempty_">SETempty_</a> return
|
||||
true (1) if set is empty </li>
|
||||
<li><a href="qset_r.h#SETfirst_">SETfirst_</a> return
|
||||
first element of set </li>
|
||||
<li><a href="qset_r.h#SETfirstt_">SETfirstt_</a> return
|
||||
first element of set as a type</li>
|
||||
<li><a href="qset_r.h#SETindex_">SETindex_</a> return
|
||||
index of elem in set </li>
|
||||
<li><a href="qset_r.h#SETreturnsize_">SETreturnsize_</a>
|
||||
return size of a set (normally use <a href="qset_r.c#setsize">qh_setsize</a>) </li>
|
||||
<li><a href="qset_r.h#SETsecond_">SETsecond_</a> return
|
||||
second element of set </li>
|
||||
<li><a href="qset_r.h#SETsecondt_">SETsecondt_</a>
|
||||
return second element of set as a type</li>
|
||||
<li><a href="qset_r.h#SETtruncate_">SETtruncate_</a>
|
||||
truncate set to size, i.e., qh_settruncate()</li>
|
||||
</ul>
|
||||
<h3><a href="qh-set_r.htm#TOC">»</a><a name="sint">Internal macros</a></h3>
|
||||
<ul>
|
||||
<li><a href="qset_r.c#SETsizeaddr_">SETsizeaddr_</a>
|
||||
return pointer to end element of a set (indicates
|
||||
current size) </li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-set_r.htm#TOC">»</a><a name="saddr">address macros</a></h3>
|
||||
<ul>
|
||||
<li><a href="qset_r.h#SETaddr_">SETaddr_</a> return
|
||||
address of a set's elements </li>
|
||||
<li><a href="qset_r.h#SETelemaddr_">SETelemaddr_</a>
|
||||
return address of the n'th element of a set </li>
|
||||
<li><a href="qset_r.h#SETref_">SETref_</a> l_r.h.s. for
|
||||
modifying the current element in a FOREACH
|
||||
iteration </li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-set_r.htm#TOC">»</a><a name="snew">Allocation and
|
||||
deallocation functions</a></h3>
|
||||
<ul>
|
||||
<li><a href="qset_r.c#setfree">qh_setfree</a> free the
|
||||
space occupied by a set </li>
|
||||
<li><a href="qset_r.c#setfree2">qh_setfree2</a> free a
|
||||
set and its elements </li>
|
||||
<li><a href="qset_r.c#setfreelong">qh_setfreelong</a>
|
||||
free a set only if it is in long memory </li>
|
||||
<li><a href="qset_r.c#setnew">qh_setnew</a> create a new
|
||||
set </li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-set_r.htm#TOC">»</a><a name="spred">Access and predicate functions</a></h3>
|
||||
<ul>
|
||||
<li><a href="qset_r.c#setendpointer">qh_setendpointer</a> return
|
||||
pointer to NULL terminator of a set</li>
|
||||
<li><a href="qset_r.c#setequal">qh_setequal</a> return 1
|
||||
if two sorted sets are equal </li>
|
||||
<li><a href="qset_r.c#setequal_except">qh_setequal_except</a>
|
||||
return 1 if two sorted sets are equal except for
|
||||
an element </li>
|
||||
<li><a href="qset_r.c#setequal_skip">qh_setequal_skip</a>
|
||||
return 1 if two sorted sets are equal except for
|
||||
a pair of skipped elements </li>
|
||||
<li><a href="qset_r.c#setequal_skip">qh_setequal_skip</a>
|
||||
return 1 if two sorted sets are equal except for
|
||||
a pair of skipped elements </li>
|
||||
<li><a href="qset_r.c#setin">qh_setin</a> return 1 if an
|
||||
element is in a set </li>
|
||||
<li><a href="qset_r.c#setindex">qh_setindex</a> return
|
||||
the index of an element in a set </li>
|
||||
<li><a href="qset_r.c#setlast">qh_setlast</a> return
|
||||
last element of a set</li>
|
||||
<li><a href="qset_r.c#setsize">qh_setsize</a> returns
|
||||
the size of a set </li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-set_r.htm#TOC">»</a><a name="sadd">Add functions</a></h3>
|
||||
<ul>
|
||||
<li><a href="qset_r.c#setaddnth">qh_setaddnth</a> add a
|
||||
element as n'th element of sorted or unsorted set
|
||||
</li>
|
||||
<li><a href="qset_r.c#setaddsorted">qh_setaddsorted</a>
|
||||
add an element to a sorted set </li>
|
||||
<li><a href="qset_r.c#setappend">qh_setappend</a> append
|
||||
an element to a set </li>
|
||||
<li><a href="qset_r.c#setappend_set">qh_setappend_set</a>
|
||||
append a set of elements to a set </li>
|
||||
<li><a href="qset_r.c#setappend2ndlast">qh_setappend2ndlast</a>
|
||||
add an element as the next to the last element in
|
||||
a set </li>
|
||||
<li><a href="qset_r.c#setlarger">qh_setlarger</a> return
|
||||
a larger set with the same elements</li>
|
||||
<li><a href="qset_r.c#setlarger_quick">qh_setlarger_quick</a> return
|
||||
True if newsize fits in quick memory </li>
|
||||
<li><a href="qset_r.c#setreplace">qh_setreplace</a>
|
||||
replace one element with another in a set</li>
|
||||
<li><a href="qset_r.c#setunique">qh_setunique</a> add an
|
||||
element if it is not already in a set </li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-set_r.htm#TOC">»</a><a name="scheck">Check and print functions</a></h3>
|
||||
<ul>
|
||||
<li><a href="qset_r.c#setcheck">qh_setcheck</a> check a
|
||||
set for validity </li>
|
||||
<li><a href="qset_r.c#setprint">qh_setprint</a> print a
|
||||
set's elements to fp </li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-set_r.htm#TOC">»</a><a name="scopy">Copy, compact, and zero functions</a></h3>
|
||||
<ul>
|
||||
<li><a href="qset_r.c#setcompact">qh_setcompact</a>
|
||||
compact NULLs from an unsorted set </li>
|
||||
<li><a href="qset_r.c#setcopy">qh_setcopy</a> make a
|
||||
copy of a sorted or unsorted set </li>
|
||||
<li><a href="qset_r.c#setduplicate">qh_setduplicate</a>
|
||||
duplicate a set and its elements </li>
|
||||
<li><a href="qset_r.c#settruncate">qh_settruncate</a>
|
||||
truncate a set to size elements </li>
|
||||
<li><a href="qset_r.c#setzero">qh_setzero</a> zero the
|
||||
remainder of a set </li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-set_r.htm#TOC">»</a><a name="sdel">Delete functions</a></h3>
|
||||
<ul>
|
||||
<li><a href="qset_r.c#setdel">qh_setdel</a> delete an
|
||||
element from an unsorted set. </li>
|
||||
<li><a href="qset_r.c#setdellast">qh_setdellast</a>
|
||||
delete and return last element from a set</li>
|
||||
<li><a href="qset_r.c#setdelnth">qh_setdelnth</a> delete
|
||||
and return nth element from an unsorted set </li>
|
||||
<li><a href="qset_r.c#setdelnthsorted">qh_setdelnthsorted</a>
|
||||
delete and return nth element from a sorted set </li>
|
||||
<li><a href="qset_r.c#setdelsorted">qh_setdelsorted</a>
|
||||
delete an element from a sorted set </li>
|
||||
<li><a href="qset_r.c#setnew_delnthsorted">qh_setnew_delnthsorted</a>
|
||||
create a sorted set not containing the nth
|
||||
element </li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-set_r.htm#TOC">»</a><a name="stemp">Temporary set functions</a></h3>
|
||||
<ul>
|
||||
<li><a href="qset_r.c#settemp">qh_settemp</a> return a
|
||||
temporary set and append it qhmem.tempstack</li>
|
||||
<li><a href="qset_r.c#settempfree">qh_settempfree</a>
|
||||
free and pop a set from qhmem.tempstack</li>
|
||||
<li><a href="qset_r.c#settempfree_all">qh_settempfree_all</a>
|
||||
free all sets in qhmem.tempstack </li>
|
||||
<li><a href="qset_r.c#settemppop">qh_settemppop</a> pop
|
||||
a set from qhmem.tempstack (makes it permanent) </li>
|
||||
<li><a href="qset_r.c#settemppush">qh_settemppush</a>
|
||||
push a set unto qhmem.tempstack (makes it
|
||||
temporary) </li>
|
||||
</ul>
|
||||
|
||||
<p><!-- Navigation links --> </p>
|
||||
<hr>
|
||||
<p><b>Up:</b>
|
||||
<a href="http://www.qhull.org">Home page</a> for
|
||||
Qhull (<a href="../index.htm">local</a>)<br>
|
||||
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: contents<br>
|
||||
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
|
||||
• <a href="../../html/qh-quick.htm#options">Options</a>
|
||||
• <a href="../../html/qh-opto.htm#output">Output</a>
|
||||
• <a href="../../html/qh-optf.htm#format">Formats</a>
|
||||
• <a href="../../html/qh-optg.htm#geomview">Geomview</a>
|
||||
• <a href="../../html/qh-optp.htm#print">Print</a>
|
||||
• <a href="../../html/qh-optq.htm#qhull">Qhull</a>
|
||||
• <a href="../../html/qh-optc.htm#prec">Precision</a>
|
||||
• <a href="../../html/qh-optt.htm#trace">Trace</a>
|
||||
• <a href="http://www.qhull.org/src/libqhull_r/index.htm">Functions</a> (<a href="index.htm">local</a>)<br>
|
||||
<b>Up:</b> <a href="../../html/qh-code.htm">Qhull code</a> <br>
|
||||
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> •
|
||||
<a href="qh-globa_r.htm">Global</a> • <a href="qh-io_r.htm">Io</a>
|
||||
• <a href="qh-mem_r.htm">Mem</a> • <a href="qh-merge_r.htm">Merge</a>
|
||||
• <a href="qh-poly_r.htm">Poly</a> • <a href="qh-qhull_r.htm#TOC">Qhull</a>
|
||||
• <a href="qh-set_r.htm">Set</a> • <a href="qh-stat_r.htm">Stat</a>
|
||||
• <a href="qh-user_r.htm">User</a><br>
|
||||
</p>
|
||||
<p><!-- GC common information --> </p>
|
||||
<hr>
|
||||
<p><a href="http://www.geom.uiuc.edu/"><img
|
||||
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
|
||||
Geometry Center Home Page </i></p>
|
||||
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
|
||||
<br>
|
||||
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,159 @@
|
||||
<!-- Do not edit with Front Page, it adds too many spaces -->
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type"
|
||||
content="text/html; charset=iso-8859-1">
|
||||
<title>stat_r.c -- statistical operations</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- Navigation links -->
|
||||
<p><a name="TOP"><b>Up:</b></a> <a
|
||||
href="http://www.qhull.org">Home page</a> for Qhull (<a href="../index.htm">local</a>)<br>
|
||||
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: contents <br>
|
||||
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
|
||||
• <a href="../../html/qh-quick.htm#options">Options</a>
|
||||
• <a href="../../html/qh-opto.htm#output">Output</a>
|
||||
• <a href="../../html/qh-optf.htm#format">Formats</a>
|
||||
• <a href="../../html/qh-optg.htm#geomview">Geomview</a>
|
||||
• <a href="../../html/qh-optp.htm#print">Print</a>
|
||||
• <a href="../../html/qh-optq.htm#qhull">Qhull</a>
|
||||
• <a href="../../html/qh-optc.htm#prec">Precision</a>
|
||||
• <a href="../../html/qh-optt.htm#trace">Trace</a>
|
||||
• <a href="http://www.qhull.org/src/libqhull_r/index.htm">Functions</a> (<a href="index.htm">local</a>)<br>
|
||||
<b>Up:</b> <a href="../../html/qh-code.htm">Qhull code</a><br>
|
||||
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> • <a href="qh-globa_r.htm">Global</a>
|
||||
• <a href="qh-io_r.htm">Io</a> • <a href="qh-mem_r.htm">Mem</a>
|
||||
• <a href="qh-merge_r.htm">Merge</a> • <a href="qh-poly_r.htm">Poly</a>
|
||||
• <a href="qh-qhull_r.htm">Qhull</a> • <a href="qh-set_r.htm">Set</a>
|
||||
• <a href="qh-stat_r.htm#TOC">Stat</a> • <a href="qh-user_r.htm">User</a>
|
||||
</p>
|
||||
<hr>
|
||||
|
||||
<h2>stat_r.c -- statistical operations</h2>
|
||||
<blockquote>
|
||||
<p>Qhull records many statistics. These functions and
|
||||
macros make it inexpensive to add a statistic.
|
||||
<p>As with Qhull's global variables, the statistics data structure is
|
||||
accessed by a macro, 'qhstat'. If qh_QHpointer is defined, the macro
|
||||
is 'qh_qhstat->', otherwise the macro is 'qh_qhstat.'.
|
||||
Statistics
|
||||
may be turned off in user_r.h. If so, all but the 'zz'
|
||||
statistics are ignored.</p>
|
||||
</blockquote>
|
||||
<p><b>Copyright © 1995-2020 C.B. Barber</b></p>
|
||||
<hr>
|
||||
<p><a href="#TOP">»</a> <a href="qh-geom_r.htm#TOC">Geom</a>
|
||||
<a name="TOC">•</a> <a href="qh-globa_r.htm#TOC">Global</a>
|
||||
• <a href="qh-io_r.htm#TOC">Io</a> • <a href="qh-mem_r.htm#TOC">Mem</a>
|
||||
• <a href="qh-merge_r.htm#TOC">Merge</a> • <a href="qh-poly_r.htm#TOC">Poly</a>
|
||||
• <a href="qh-qhull_r.htm#TOC">Qhull</a> • <a href="qh-set_r.htm#TOC">Set</a>
|
||||
• <b>Stat</b> • <a href="qh-user_r.htm#TOC">User</a>
|
||||
</p>
|
||||
<h3>Index to <a href="stat_r.c">stat_r.c</a> and
|
||||
<a href="stat_r.h">stat_r.h</a></h3>
|
||||
<ul>
|
||||
<li><a href="#ttype">stat_r.h types</a> </li>
|
||||
<li><a href="#tconst">stat_r.h constants</a> </li>
|
||||
<li><a href="#tmacro">stat_r.h macros</a> </li>
|
||||
<li><a href="#tfunc">stat_r.c functions</a> </li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-stat_r.htm#TOC">»</a><a name="ttype">stat_r.h types</a></h3>
|
||||
<ul>
|
||||
<li><a href="stat_r.h#intrealT">intrealT</a> union of
|
||||
integer and real</li>
|
||||
<li><a href="stat_r.h#qhstat">qhstat</a> global data
|
||||
structure for statistics </li>
|
||||
</ul>
|
||||
<h3><a href="qh-stat_r.htm#TOC">»</a><a name="tconst">stat_r.h
|
||||
constants</a></h3>
|
||||
<ul>
|
||||
<li><a href="stat_r.h#KEEPstatistics">qh_KEEPstatistics</a> 0 turns off most statistics</li>
|
||||
<li><a href="stat_r.h#statistics">Z..., W...</a> integer (Z) and real (W) statistics
|
||||
</li>
|
||||
<li><a href="stat_r.h#ZZstat">ZZstat</a> Z.../W... statistics that
|
||||
remain defined if qh_KEEPstatistics=0
|
||||
</li>
|
||||
<li><a href="stat_r.h#ztype">ztype</a> zdoc, zinc, etc.
|
||||
for defining statistics </li>
|
||||
</ul>
|
||||
<h3><a href="qh-stat_r.htm#TOC">»</a><a name="tmacro">stat_r.h macros</a></h3>
|
||||
<ul>
|
||||
<li><a href="stat_r.h#MAYdebugx">MAYdebugx</a> called
|
||||
frequently for error trapping </li>
|
||||
<li><a href="stat_r.h#zadd_">zadd_/wadd_</a> add value
|
||||
to an integer or real statistic </li>
|
||||
<li><a href="stat_r.h#zdef_">zdef_</a> define a
|
||||
statistic </li>
|
||||
<li><a href="stat_r.h#zinc_">zinc_</a> increment an
|
||||
integer statistic </li>
|
||||
<li><a href="stat_r.h#zmax_">zmax_/wmax_</a> update
|
||||
integer or real maximum statistic </li>
|
||||
<li><a href="stat_r.h#zmin_">zmin_/wmin_</a> update
|
||||
integer or real minimum statistic </li>
|
||||
<li><a href="stat_r.h#zval_">zval_/wval_</a> set or
|
||||
return value of a statistic </li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-stat_r.htm#TOC">»</a><a name="tfunc">stat_r.c
|
||||
functions</a></h3>
|
||||
<ul>
|
||||
<li><a href="stat_r.c#allstatA">qh_allstatA</a> define
|
||||
statistics in groups of 20 </li>
|
||||
<li><a href="stat_r.c#allstatistics">qh_allstatistics</a>
|
||||
reset printed flag for all statistics </li>
|
||||
<li><a href="stat_r.c#collectstatistics">qh_collectstatistics</a>
|
||||
collect statistics for qh.facet_list </li>
|
||||
<li><a href="stat_r.c#initstatistics">qh_initstatistics</a>
|
||||
allocate and initialize statistics </li>
|
||||
<li><a href="stat_r.c#newstats">qh_newstats</a> returns
|
||||
True if statistics for zdoc </li>
|
||||
<li><a href="stat_r.c#nostatistic">qh_nostatistic</a>
|
||||
true if no statistic to print </li>
|
||||
<li><a href="stat_r.c#printallstatistics">qh_printallstatistics</a>
|
||||
print all statistics </li>
|
||||
<li><a href="stat_r.c#printstatistics">qh_printstatistics</a>
|
||||
print statistics to a file </li>
|
||||
<li><a href="stat_r.c#printstatlevel">qh_printstatlevel</a>
|
||||
print level information for a statistic </li>
|
||||
<li><a href="stat_r.c#printstats">qh_printstats</a>
|
||||
print statistics for a zdoc group </li>
|
||||
<li><a href="stat_r.c#stddev">qh_stddev</a> compute the
|
||||
standard deviation and average from statistics </li>
|
||||
</ul>
|
||||
|
||||
<p><!-- Navigation links --> </p>
|
||||
<hr>
|
||||
<p><b>Up:</b>
|
||||
<a href="http://www.qhull.org">Home page</a> for
|
||||
Qhull (<a href="../index.htm">local</a>)<br>
|
||||
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: contents<br>
|
||||
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
|
||||
• <a href="../../html/qh-quick.htm#options">Options</a>
|
||||
• <a href="../../html/qh-opto.htm#output">Output</a>
|
||||
• <a href="../../html/qh-optf.htm#format">Formats</a>
|
||||
• <a href="../../html/qh-optg.htm#geomview">Geomview</a>
|
||||
• <a href="../../html/qh-optp.htm#print">Print</a>
|
||||
• <a href="../../html/qh-optq.htm#qhull">Qhull</a>
|
||||
• <a href="../../html/qh-optc.htm#prec">Precision</a>
|
||||
• <a href="../../html/qh-optt.htm#trace">Trace</a>
|
||||
• <a href="http://www.qhull.org/src/libqhull_r/index.htm">Functions</a> (<a href="index.htm">local</a>)<br>
|
||||
<b>Up:</b> <a href="../../html/qh-code.htm">Qhull code</a> <br>
|
||||
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> •
|
||||
<a href="qh-globa_r.htm">Global</a> • <a href="qh-io_r.htm">Io</a>
|
||||
• <a href="qh-mem_r.htm">Mem</a> • <a href="qh-merge_r.htm">Merge</a>
|
||||
• <a href="qh-poly_r.htm">Poly</a> • <a href="qh-qhull_r.htm#TOC">Qhull</a>
|
||||
• <a href="qh-set_r.htm">Set</a> • <a href="qh-stat_r.htm">Stat</a>
|
||||
• <a href="qh-user_r.htm">User</a><br>
|
||||
</p>
|
||||
<p><!-- GC common information --> </p>
|
||||
<hr>
|
||||
<p><a href="http://www.geom.uiuc.edu/"><img
|
||||
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
|
||||
Geometry Center Home Page </i></p>
|
||||
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
|
||||
<br>
|
||||
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,314 @@
|
||||
<!-- Do not edit with Front Page, it adds too many spaces -->
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type"
|
||||
content="text/html; charset=iso-8859-1">
|
||||
<title>user_r.c -- user-definable operations</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- Navigation links -->
|
||||
<p><a name="TOP"><b>Up:</b></a> <a
|
||||
href="http://www.qhull.org">Home page</a> for Qhull (<a href="../index.htm">local</a>)<br>
|
||||
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: contents <br>
|
||||
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
|
||||
• <a href="../../html/qh-quick.htm#options">Options</a>
|
||||
• <a href="../../html/qh-opto.htm#output">Output</a>
|
||||
• <a href="../../html/qh-optf.htm#format">Formats</a>
|
||||
• <a href="../../html/qh-optg.htm#geomview">Geomview</a>
|
||||
• <a href="../../html/qh-optp.htm#print">Print</a>
|
||||
• <a href="../../html/qh-optq.htm#qhull">Qhull</a>
|
||||
• <a href="../../html/qh-optc.htm#prec">Precision</a>
|
||||
• <a href="../../html/qh-optt.htm#trace">Trace</a>
|
||||
• <a href="http://www.qhull.org/src/libqhull_r/index.htm">Functions</a> (<a href="index.htm">local</a>)<br>
|
||||
<b>Up:</b> <a href="../../html/qh-code.htm">Qhull code</a><br>
|
||||
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> • <a href="qh-globa_r.htm">Global</a>
|
||||
• <a href="qh-io_r.htm">Io</a> • <a href="qh-mem_r.htm">Mem</a>
|
||||
• <a href="qh-merge_r.htm">Merge</a> • <a href="qh-poly_r.htm">Poly</a>
|
||||
• <a href="qh-qhull_r.htm">Qhull</a> • <a href="qh-set_r.htm">Set</a>
|
||||
• <a href="qh-stat_r.htm">Stat</a> • <a href="qh-user_r.htm#TOC">User</a>
|
||||
</p>
|
||||
<hr>
|
||||
<h2>user_r.c -- user-definable operations</h2>
|
||||
<blockquote>
|
||||
<p>This section contains functions and constants that the
|
||||
user may want to change. </p>
|
||||
|
||||
</blockquote>
|
||||
<p><b>Copyright © 1995-2020 C.B. Barber</b></p>
|
||||
<hr>
|
||||
<p><a href="#TOP">»</a> <a href="qh-geom_r.htm#TOC">Geom</a>
|
||||
<a name="TOC">•</a> <a href="qh-globa_r.htm#TOC">Global</a>
|
||||
• <a href="qh-io_r.htm#TOC">Io</a> • <a href="qh-mem_r.htm#TOC">Mem</a>
|
||||
• <a href="qh-merge_r.htm#TOC">Merge</a> • <a href="qh-poly_r.htm#TOC">Poly</a>
|
||||
• <a href="qh-qhull_r.htm#TOC">Qhull</a> • <a href="qh-set_r.htm#TOC">Set</a>
|
||||
• <a href="qh-stat_r.htm#TOC">Stat</a> • <b>User</b>
|
||||
</p>
|
||||
<h3>Index to <a href="user_r.c">user_r.c</a>, <a href="usermem_r.c">usermem_r.c</a>, <a href="userprintf_r.c">userprintf_r.c</a>, <a href="userprintf_rbox_r.c">userprintf_rbox_r.c</a> and
|
||||
<a href="user_r.h">user_r.h</a></h3>
|
||||
<ul>
|
||||
<li><a href="#qulllib">qhull library constants</a></li>
|
||||
<li><a href="#utype">user_r.h data types and
|
||||
configuration macros</a> </li>
|
||||
<li><a href="#ujoggle">joggle constants</a></li>
|
||||
<li><a href="#uperform">performance related constants</a></li>
|
||||
<li><a href="#umemory">memory constants</a></li>
|
||||
<li><a href="#ucond">conditional compilation</a></li>
|
||||
<li><a href="#umerge">merge constants</a> </li>
|
||||
<li><a href="#ufunc">user_r.c functions</a> </li>
|
||||
<li><a href="#u2func">usermem_r.c functions</a> </li>
|
||||
<li><a href="#u3func">userprintf_r.c functions</a> </li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-user_r.htm#TOC">»</a><a name="qulllib">Qhull library constants</a></h3>
|
||||
<ul>
|
||||
<li><a href="user_r.h#filenamelen">FILENAMElen</a> -- max length of TI or TO filename </li>
|
||||
<li><a href="user_r.h#msgcode">msgcode</a> -- unique message codes for qh_fprintf </li>
|
||||
<li><a href="user_r.h#qh_OPTIONline">qh_OPTIONline</a> -- max length of option line ('FO')</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3><a href="qh-user_r.htm#TOC">»</a><a name="utype">user_r.h data
|
||||
types and configuration macros</a></h3>
|
||||
<ul>
|
||||
<li><a href="user_r.h#realT">realT, qh_REAL...</a> size
|
||||
of floating point numbers </li>
|
||||
<li><a href="user_r.h#countT">countT, COUNTmax</a> size
|
||||
of counts and identifiers, typically 'int' or 'long long' </li>
|
||||
<li><a href="user_r.h#CPUclock">qh_CPUclock</a> clock()
|
||||
function for reporting the total time spent by
|
||||
Qhull </li>
|
||||
<li><a href="user_r.h#RANDOM">qh_RANDOM...</a> random
|
||||
number generator </li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-user_r.htm#TOC">»</a><a name="udef">definition constants</a></h3>
|
||||
<ul>
|
||||
<li><a href="user_r.h#DEFAULTbox">qh_DEFAULTbox</a>
|
||||
define default box size for rbox, 'Qbb', and 'QbB' (Geomview expects 0.5) </li>
|
||||
<li><a href="user_r.h#INFINITE">qh_INFINITE</a> on
|
||||
output, indicates Voronoi center at infinity </li>
|
||||
<li><a href="user_r.h#ORIENTclock">qh_ORIENTclock</a>
|
||||
define convention for orienting facets</li>
|
||||
<li><a href="user_r.h#RANDOMdist">qh_RANDOMdist</a>
|
||||
for testing qh.DISTround (sets qh.RANDOMfactor for qh.RANDOMdist, same as option 'Rn')</li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-user_r.htm#TOC">»</a><a name="ujoggle">joggle constants</a></h3>
|
||||
<ul>
|
||||
<li><a href="user_r.h#JOGGLEagain">qh_JOGGLEagain</a>
|
||||
how often to retry before using qh_JOGGLEmaxincrease
|
||||
again </li>
|
||||
<li><a href="user_r.h#JOGGLEdefault">qh_JOGGLEdefault</a>
|
||||
default value for qh.JOGGLEmax for 'QP' </li>
|
||||
<li><a href="user_r.h#JOGGLEincrease">qh_JOGGLEincrease</a>
|
||||
factor to increase qh.JOGGLEmax on retrys for
|
||||
'QPn' </li>
|
||||
<li><a href="user_r.h#JOGGLEmaxincrease">qh_JOGGLEmaxincrease</a> max
|
||||
for increasing qh.JOGGLEmax relative to
|
||||
qh.MAXwidth </li>
|
||||
<li><a href="user_r.h#JOGGLEretry">qh_JOGGLEmaxretry</a>
|
||||
report error if this many retries </li>
|
||||
<li><a href="user_r.h#JOGGLEretry">qh_JOGGLEretry</a>
|
||||
how often to retry before using qh_JOGGLEmax </li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-user_r.htm#TOC">»</a><a name="uperform">performance
|
||||
related constants</a></h3>
|
||||
<ul>
|
||||
<li><a href="user_r.h#HASHfactor">qh_HASHfactor</a>
|
||||
total/used hash slots </li>
|
||||
<li><a href="user_r.h#INITIALmax">qh_INITIALmax</a> if
|
||||
dim >= qh_INITIALmax, use min/max coordinate
|
||||
points for initial simplex </li>
|
||||
<li><a href="user_r.h#INITIALsearch">qh_INITIALsearch</a>
|
||||
if qh.INITIALmax, search points up to this
|
||||
dimension </li>
|
||||
<li><a href="user_r.h#NOtrace">qh_NOtrace</a> disallow
|
||||
tracing </li>
|
||||
<li><a href="user_r.h#VERIFYdirect">qh_VERIFYdirect</a>
|
||||
'Tv' verifies all <em>points X facets</em> if op
|
||||
count is smaller </li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-user_r.htm#TOC">»</a><a name="umemory">memory constants</a></h3>
|
||||
<ul>
|
||||
<li><a href="user_r.h#MEMalign">qh_MEMalign</a> memory
|
||||
alignment for qh_meminitbuffers() in global_r.c </li>
|
||||
<li><a href="user_r.h#MEMbufsize">qh_MEMbufsize</a>
|
||||
size of additional memory buffers </li>
|
||||
<li><a href="user_r.h#MEMinitbuf">qh_MEMinitbuf</a>
|
||||
size of initial memory buffer </li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-user_r.htm#TOC">»</a><a name="ucond">conditional compilation</a></h3>
|
||||
<ul>
|
||||
<li><a href="user_r.h#compiler">compiler</a> defined symbols,
|
||||
e.g., _STDC_ and _cplusplus
|
||||
|
||||
<li><a href="user_r.h#COMPUTEfurthest">qh_COMPUTEfurthest</a>
|
||||
compute furthest distance to an outside point instead of storing it with the facet
|
||||
<li><a href="user_r.h#KEEPstatistics">qh_KEEPstatistics</a>
|
||||
enable statistic gathering and reporting with option 'Ts'
|
||||
<li><a href="user_r.h#MAXcheckpoint">qh_MAXcheckpoint</a>
|
||||
report up to qh_MAXcheckpoint errors per facet in qh_check_point ('Tv')
|
||||
<li><a href="user_r.h#MAXoutside">qh_MAXoutside</a>
|
||||
record outer plane for each facet
|
||||
<li><a href="user_r.h#NOmerge">qh_NOmerge</a>
|
||||
disable facet merging
|
||||
<li><a href="user_r.h#NOtrace">qh_NOtrace</a>
|
||||
disable tracing with option 'T4'
|
||||
<li><a href="user_r.h#QHpointer">qh_QHpointer</a>
|
||||
access global data with pointer or static structure
|
||||
<li><a href="user_r.h#QUICKhelp">qh_QUICKhelp</a>
|
||||
use abbreviated help messages, e.g., for degenerate inputs
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-user_r.htm#TOC">»</a><a name="umerge">merge
|
||||
constants</a></h3>
|
||||
<ul>
|
||||
<li><a href="user_r.h#BESTcentrum">qh_BESTcentrum</a>
|
||||
if many vertices for facet, qh_findbestneighbor tests centrums instead of vertices </li>
|
||||
<li><a href="user_r.h#BESTnonconvex">qh_BESTnonconvex</a>
|
||||
if many neighbors for facet, qh_findbestneighbor only tests nonconvex ridges </li>
|
||||
<li><a href="user_r.h#COPLANARratio">qh_COPLANARratio</a>
|
||||
what is qh.MINvisible? </li>
|
||||
<li><a href="user_r.h#DIMreduceBuild">qh_DIMreduceBuild</a>
|
||||
max dimension for vertex reduction </li>
|
||||
<li><a href="user_r.h#DIMmergeVertex">qh_DIMmergeVertex</a>
|
||||
max dimension for vertex merging </li>
|
||||
<li><a href="user_r.h#DISToutside">qh_DISToutside</a>
|
||||
when is a point clearly outside of a facet for qh_findbestnew and qh_partitionall </li>
|
||||
<li><a href="user_r.h#MAXnarrow">qh_MAXnarrow</a> max.
|
||||
cosine for qh.NARROWhull </li>
|
||||
<li><a href="user_r.h#MAXcoplanarcentrum">qh_MAXcoplanarcentrum</a>
|
||||
if 'Qx' and many merges, use f.maxoutside for coplanarity test
|
||||
instead of qh.centrum_radius </li>
|
||||
<li><a href="user_r.h#MAXnarrow">qh_MAXnarrow</a>
|
||||
max. cosine in initial hull that sets qh.NARROWhull </li>
|
||||
<li><a href="user_r.h#MAXnewcentrum">qh_MAXnewcentrum</a>
|
||||
when does qh_reducevertices_centrum() reset the
|
||||
centrum? </li>
|
||||
<li><a href="user_r.h#MAXnewmerges">qh_MAXnewmerges</a>
|
||||
when does qh_merge_nonconvex() call
|
||||
qh_reducevertices_centrums? </li>
|
||||
<li><a href="user_r.h#RATIOconcavehorizon">qh_RATIOconcavehorizon</a>
|
||||
ratio of horizon vertex distance to qh.max_outside for concave, twisted new facets in qh_test_nonsimplicial_merge </li>
|
||||
<li><a href="user_r.h#RATIOconvexmerge">qh_RATIOconvexmerge</a>
|
||||
ratio of vertex distance to qh.min_vertex for clearly convex new facets in qh_test_nonsimplicial_merge </li>
|
||||
<li><a href="user_r.h#RATIOcoplanarapex">qh_RATIOcoplanarapex</a>
|
||||
ratio of best distance for coplanar apex vs. vertex merge in qh_getpinchedmerges </li>
|
||||
<li><a href="user_r.h#RATIOcoplanaroutside">qh_RATIOcoplanaroutside</a>
|
||||
ratio to repartition a coplanar point as an outside point in qh_partitioncoplanar and qh_check_maxout </li>
|
||||
<li><a href="user_r.h#RATIOmaxsimplex">qh_RATIOmaxsimplex</a>
|
||||
ratio for searching all points in qh_maxsimplex </li>
|
||||
<li><a href="user_r.h#RATIOnearinside">qh_RATIOnearinside</a>
|
||||
ratio for retaining inside points for qh_check_maxout </li>
|
||||
<li><a href="user_r.h#RATIOpinchedsubridge">qh_RATIOpinchedsubridge</a>
|
||||
ratio to qh.ONEmerge to accept vertices in qh_findbest_pinchedvertex </li>
|
||||
<li><a href="user_r.h#RATIOtrypinched">qh_RATIOtrypinched</a>
|
||||
ratio to qh.ONEmerge to try qh_getpinchedmerges in qh_buildcone_mergepinched </li>
|
||||
<li><a href="user_r.h#RATIOtwisted">qh_RATIOtwisted</a>
|
||||
maximum ratio to qh.ONEmerge to merge twisted facets in qh_merge_twisted </li>
|
||||
<li><a href="user_r.h#SEARCHdist">qh_SEARCHdist</a>
|
||||
when is facet coplanar with the best facet for qh_findbesthorizon</li>
|
||||
<li><a href="user_r.h#USEfindbestnew">qh_USEfindbestnew</a>
|
||||
when to use qh_findbestnew for qh_partitionpoint()</li>
|
||||
<li><a href="user_r.h#WARNnarrow">qh_WARNnarrow</a>
|
||||
max. cosine in initial hull to warn about qh.NARROWhull </li>
|
||||
<li><a href="user_r.h#WIDEcoplanar">qh_WIDEcoplanar</a>
|
||||
what is a wide facet </li>
|
||||
<li><a href="user_r.h#WIDEduplicate">qh_WIDEduplicate</a>
|
||||
merge ratio for errexit from qh_forcedmerges due to duplicate ridge </li>
|
||||
<li><a href="user_r.h#WIDEduplicate">qh_WIDEridge</a>
|
||||
merge ratio for selecting a forced dupridge merge </li>
|
||||
<li><a href="user_r.h#WIDEmaxoutside">qh_WIDEmaxoutside</a>
|
||||
precision ratio for maximum increase for qh.max_outside in qh_check_maxout </li>
|
||||
<li><a href="user_r.h#WIDEmaxoutside2">qh_WIDEmaxoutside2</a>
|
||||
precision ratio for maximum qh.max_outside in qh_check_maxout </li>
|
||||
<li><a href="user_r.h#WIDEpinched">qh_WIDEpinched</a>
|
||||
merge ratio for distance between pinched vertices compared to current facet width for qh_getpinchedmerges and qh_next_vertexmerge </li>
|
||||
<li><a href="user_r.h#ZEROdelaunay">qh_ZEROdelaunay</a>
|
||||
define facets that are ignored in Delaunay triangulations </li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-user_r.htm#TOC">»</a><a name="ufunc">user_r.c
|
||||
functions</a></h3>
|
||||
<ul>
|
||||
<li><a href="user_r.c#qhull_template">Qhull template</a> for calling qh_new_qhull from your program</li>
|
||||
<li><a href="user_r.c#errexit">qh_errexit</a> report
|
||||
error and exit qhull()</li>
|
||||
<li><a href="user_r.c#errprint">qh_errprint</a> print
|
||||
information about facets and ridges </li>
|
||||
<li><a href="user_r.c#new_qhull">qh_new_qhull</a> call qhull on an array
|
||||
of points</li>
|
||||
<li><a href="user_r.c#printfacetlist">qh_printfacetlist</a>
|
||||
print all fields of all facets </li>
|
||||
<li><a href="user_r.c#printhelp_degenerate">qh_printhelp_degenerate</a>
|
||||
prints descriptive message for precision error </li>
|
||||
<li><a href="user_r.c#printhelp_internal">qh_printhelp_internal</a>
|
||||
print help message for an internal error </li>
|
||||
<li><a href="user_r.c#printhelp_narrowhull">qh_printhelp_narrowhull</a>
|
||||
prints descriptive message to warn about a narrow hull </li>
|
||||
<li><a href="user_r.c#printhelp_singular">qh_printhelp_singular</a>
|
||||
print help message for singular data </li>
|
||||
<li><a href="user_r.c#printhelp_topology">qh_printhelp_topology</a>
|
||||
print help message for a topology error due to merging </li>
|
||||
<li><a href="user_r.c#printhelp_wide">qh_printhelp_wide</a>
|
||||
print help message for a wide merge error </li>
|
||||
<li><a href="user_r.c#user_memsizes">qh_user_memsizes</a>
|
||||
define additional quick allocation sizes
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-user_r.htm#TOC">»</a><a name="u2func">usermem_r.c
|
||||
functions</a></h3>
|
||||
<ul>
|
||||
<li><a href="usermem_r.c#qh_exit">qh_exit</a> exit program, same as exit(). May be redefined as throw "QH10003.." by libqhullcpp/usermem_r-cpp.cpp</li>
|
||||
<li><a href="usermem_r.c#qh_fprintf_stderr">qh_fprintf_stderr</a> print to stderr when qh.ferr is not defined.</li>
|
||||
<li><a href="usermem_r.c#qh_free">qh_free</a> free memory, same as free().</li>
|
||||
<li><a href="usermem_r.c#qh_malloc">qh_malloc</a> allocate memory, same as malloc()</li>
|
||||
</ul>
|
||||
|
||||
<h3><a href="qh-user_r.htm#TOC">»</a><a name="u3func">userprintf_r.c
|
||||
and userprintf_rbox,c functions</a></h3>
|
||||
<ul>
|
||||
<li><a href="userprintf_r.c#qh_fprintf">qh_fprintf</a> print
|
||||
information from Qhull, sames as fprintf(). </li>
|
||||
<li><a href="userprintf_rbox_r.c#qh_fprintf_rbox">qh_fprintf_rbox</a> print
|
||||
information from Rbox, sames as fprintf(). </li>
|
||||
</ul>
|
||||
|
||||
<p><!-- Navigation links --> </p>
|
||||
<hr>
|
||||
<p><b>Up:</b>
|
||||
<a href="http://www.qhull.org">Home page</a> for
|
||||
Qhull (<a href="../index.htm">local</a>)<br>
|
||||
<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: contents<br>
|
||||
<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
|
||||
• <a href="../../html/qh-quick.htm#options">Options</a>
|
||||
• <a href="../../html/qh-opto.htm#output">Output</a>
|
||||
• <a href="../../html/qh-optf.htm#format">Formats</a>
|
||||
• <a href="../../html/qh-optg.htm#geomview">Geomview</a>
|
||||
• <a href="../../html/qh-optp.htm#print">Print</a>
|
||||
• <a href="../../html/qh-optq.htm#qhull">Qhull</a>
|
||||
• <a href="../../html/qh-optc.htm#prec">Precision</a>
|
||||
• <a href="../../html/qh-optt.htm#trace">Trace</a>
|
||||
• <a href="http://www.qhull.org/src/libqhull_r/index.htm">Functions</a> (<a href="index.htm">local</a>)<br>
|
||||
<b>Up:</b> <a href="../../html/qh-code.htm">Qhull code</a> <br>
|
||||
<b>To:</b> <a href="qh-geom_r.htm">Geom</a> •
|
||||
<a href="qh-globa_r.htm">Global</a> • <a href="qh-io_r.htm">Io</a>
|
||||
• <a href="qh-mem_r.htm">Mem</a> • <a href="qh-merge_r.htm">Merge</a>
|
||||
• <a href="qh-poly_r.htm">Poly</a> • <a href="qh-qhull_r.htm#TOC">Qhull</a>
|
||||
• <a href="qh-set_r.htm">Set</a> • <a href="qh-stat_r.htm">Stat</a>
|
||||
• <a href="qh-user_r.htm">User</a><br>
|
||||
</p>
|
||||
<p><!-- GC common information --> </p>
|
||||
<hr>
|
||||
<p><a href="http://www.geom.uiuc.edu/"><img
|
||||
src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
|
||||
Geometry Center Home Page </i></p>
|
||||
<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
|
||||
<br>
|
||||
Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,463 @@
|
||||
; qhull_r-exports.def -- MSVC module-definition file
|
||||
;
|
||||
; Generated from depends.exe by cut-and-paste of exported symbols by mingw gcc
|
||||
; [jan'14] 391 symbols
|
||||
;
|
||||
; Referenced by CMakeLists/add_library, libqhull_r.pro/DEF_FILE,
|
||||
; and libqhull_r.vcxproj/Linker/Input/Module Definition File
|
||||
;
|
||||
; If qh_NOmerge, use qhull_r-nomerge-exports.def
|
||||
; Created by -- grep -vE 'qh_all_merges|qh_appendmergeset|qh_basevertices|qh_check_dupridge|qh_checkconnect|qh_compare_facetmerge|qh_comparevisit|qh_copynonconvex|qh_degen_redundant_facet|qh_delridge_merge|qh_find_newvertex|qh_findbest_test|qh_findbestneighbor|qh_flippedmerges|qh_forcedmerges|qh_getmergeset|qh_getmergeset_initial|qh_hashridge|qh_hashridge_find|qh_makeridges|qh_mark_dupridges|qh_maydropneighbor|qh_merge_degenredundant|qh_merge_nonconvex|qh_mergecycle|qh_mergecycle_all|qh_mergecycle_facets|qh_mergecycle_neighbors|qh_mergecycle_ridges|qh_mergecycle_vneighbors|qh_mergefacet|qh_mergefacet2d|qh_mergeneighbors|qh_mergeridges|qh_mergesimplex|qh_mergevertex_del|qh_mergevertex_neighbors|qh_mergevertices|qh_nearcoplanar|qh_nearvertex|qh_neighbor_intersections|qh_newhashtable|qh_newvertex|qh_newvertices|qh_nextridge3d|qh_reducevertices|qh_redundant_vertex|qh_remove_extravertices|qh_rename_sharedvertex|qh_renameridgevertex|qh_renamevertex|qh_test_appendmerge|qh_test_degen_neighbors|qh_test_redundant_neighbors|qh_test_vneighbors|qh_tracemerge|qh_tracemerging|qh_triangulate_facet|qh_triangulate_link|qh_triangulate_mirror|qh_triangulate_null|qh_updatetested|qh_vertexridges|qh_vertexridges_facet|qh_willdelete' qhull_r-exports.def >qhull_r-nomerge-exports.def
|
||||
;
|
||||
; $Id: //main/2019/qhull/src/libqhull_r/qhull_r-exports.def#5 $$Change: 3396 $
|
||||
; $DateTime: 2023/01/02 16:59:48 $$Author: bbarber $
|
||||
;
|
||||
; Define qhull_VERSION in CMakeLists.txt, Makefile, qhull-exports.def, qhull_p-exports.def, qhull_r-exports.def, and qhull-warn.pri
|
||||
VERSION 8.0
|
||||
EXPORTS
|
||||
qh_addhash
|
||||
qh_addpoint
|
||||
qh_all_merges
|
||||
qh_alloc_qh
|
||||
qh_allstatA
|
||||
qh_allstatB
|
||||
qh_allstatC
|
||||
qh_allstatD
|
||||
qh_allstatE
|
||||
qh_allstatE2
|
||||
qh_allstatF
|
||||
qh_allstatG
|
||||
qh_allstatH
|
||||
qh_allstatI
|
||||
qh_allstatistics
|
||||
qh_appendfacet
|
||||
qh_appendmergeset
|
||||
qh_appendprint
|
||||
qh_appendvertex
|
||||
qh_argv_to_command
|
||||
qh_argv_to_command_size
|
||||
qh_attachnewfacets
|
||||
qh_backnormal
|
||||
qh_basevertices
|
||||
qh_build_withrestart
|
||||
qh_buildhull
|
||||
qh_buildtracing
|
||||
qh_check_bestdist
|
||||
qh_check_dupridge
|
||||
qh_check_maxout
|
||||
qh_check_output
|
||||
qh_check_point
|
||||
qh_check_points
|
||||
qh_checkconnect
|
||||
qh_checkconvex
|
||||
qh_checkdelridge
|
||||
qh_checkfacet
|
||||
qh_checkflags
|
||||
qh_checkflipped
|
||||
qh_checkflipped_all
|
||||
qh_checklists
|
||||
qh_checkpolygon
|
||||
qh_checkvertex
|
||||
qh_checkzero
|
||||
qh_clear_outputflags
|
||||
qh_clearcenters
|
||||
qh_clock
|
||||
qh_collectstatistics
|
||||
qh_compare_facetarea
|
||||
qh_compare_facetmerge
|
||||
qh_compare_facetvisit
|
||||
qh_compare_nummerge
|
||||
qh_comparevisit
|
||||
qh_copyfilename
|
||||
qh_copynonconvex
|
||||
qh_copypoints
|
||||
qh_countfacets
|
||||
qh_createsimplex
|
||||
qh_crossproduct
|
||||
qh_degen_redundant_facet
|
||||
qh_deletevisible
|
||||
qh_delfacet
|
||||
qh_delridge_merge
|
||||
qh_delvertex
|
||||
qh_determinant
|
||||
qh_detjoggle
|
||||
qh_detroundoff
|
||||
qh_detsimplex
|
||||
qh_detvnorm
|
||||
qh_detvridge
|
||||
qh_detvridge3
|
||||
qh_dfacet
|
||||
qh_distnorm
|
||||
qh_distplane
|
||||
qh_distround
|
||||
qh_divzero
|
||||
qh_dvertex
|
||||
qh_eachvoronoi
|
||||
qh_eachvoronoi_all
|
||||
qh_errexit
|
||||
qh_errexit2
|
||||
qh_errexit_rbox
|
||||
qh_errprint
|
||||
qh_exit
|
||||
qh_facet2point
|
||||
qh_facet3vertex
|
||||
qh_facetarea
|
||||
qh_facetarea_simplex
|
||||
qh_facetcenter
|
||||
qh_facetintersect
|
||||
qh_facetvertices
|
||||
qh_find_newvertex
|
||||
qh_findbest
|
||||
qh_findbest_test
|
||||
qh_findbestfacet
|
||||
qh_findbesthorizon
|
||||
qh_findbestlower
|
||||
qh_findbestneighbor
|
||||
qh_findbestnew
|
||||
qh_findfacet_all
|
||||
qh_findgood
|
||||
qh_findgood_all
|
||||
qh_findgooddist
|
||||
qh_findhorizon
|
||||
qh_flippedmerges
|
||||
qh_forcedmerges
|
||||
qh_fprintf
|
||||
qh_fprintf_rbox
|
||||
qh_fprintf_stderr
|
||||
qh_free
|
||||
qh_free_qh
|
||||
qh_freebuffers
|
||||
qh_freebuild
|
||||
qh_freeqhull
|
||||
qh_furthestnext
|
||||
qh_furthestout
|
||||
qh_gausselim
|
||||
qh_geomplanes
|
||||
qh_get_ATinfinity
|
||||
qh_get_center_size
|
||||
qh_get_DELAUNAY
|
||||
qh_get_del_vertices
|
||||
qh_get_DISTround
|
||||
qh_get_facet_id
|
||||
qh_get_facet_list
|
||||
qh_get_facet_tail
|
||||
qh_get_feasible_point
|
||||
qh_get_first_point
|
||||
qh_get_hasAreaVolume
|
||||
qh_get_hasTriangulation
|
||||
qh_get_hull_dim
|
||||
qh_get_input_dim
|
||||
qh_get_input_points
|
||||
qh_get_KEEPcoplanar
|
||||
qh_get_last_high
|
||||
qh_get_last_low
|
||||
qh_get_last_newhigh
|
||||
qh_get_max_outside
|
||||
qh_get_MERGEexact
|
||||
qh_get_MINoutside
|
||||
qh_get_NOerrexit
|
||||
qh_get_normal_size
|
||||
qh_get_num_facets
|
||||
qh_get_num_good
|
||||
qh_get_num_points
|
||||
qh_get_num_vertices
|
||||
qh_get_num_visible
|
||||
qh_get_other_points
|
||||
qh_get_PROJECTdelaunay
|
||||
qh_get_qhull_command
|
||||
qh_get_SCALElast
|
||||
qh_get_totarea
|
||||
qh_get_totvol
|
||||
qh_get_UPPERdelaunay
|
||||
qh_get_vertex_list
|
||||
qh_get_vertex_tail
|
||||
qh_get_vertex_visit
|
||||
qh_get_visit_id
|
||||
qh_getangle
|
||||
qh_getarea
|
||||
qh_getcenter
|
||||
qh_getcentrum
|
||||
qh_getdistance
|
||||
qh_gethash
|
||||
qh_getmergeset
|
||||
qh_getmergeset_initial
|
||||
qh_gram_schmidt
|
||||
qh_hashridge
|
||||
qh_hashridge_find
|
||||
qh_infiniteloop
|
||||
qh_init_A
|
||||
qh_init_B
|
||||
qh_init_qhull_command
|
||||
qh_initbuild
|
||||
qh_initflags
|
||||
qh_initialhull
|
||||
qh_initialvertices
|
||||
qh_initqhull_buffers
|
||||
qh_initqhull_globals
|
||||
qh_initqhull_mem
|
||||
qh_initqhull_outputflags
|
||||
qh_initqhull_start
|
||||
qh_initqhull_start2
|
||||
qh_initstatistics
|
||||
qh_initthresholds
|
||||
qh_inthresholds
|
||||
qh_isvertex
|
||||
qh_joggle_restart
|
||||
qh_joggleinput
|
||||
qh_lib_check
|
||||
qh_makenew_nonsimplicial
|
||||
qh_makenew_simplicial
|
||||
qh_makenewfacet
|
||||
qh_makenewfacets
|
||||
qh_makenewplanes
|
||||
qh_makeridges
|
||||
qh_malloc
|
||||
qh_mark_dupridges
|
||||
qh_markkeep
|
||||
qh_markvoronoi
|
||||
qh_matchdupridge
|
||||
qh_matchneighbor
|
||||
qh_matchnewfacets
|
||||
qh_matchvertices
|
||||
qh_maxabsval
|
||||
qh_maxmin
|
||||
qh_maxouter
|
||||
qh_maxsimplex
|
||||
qh_maydropneighbor
|
||||
qh_memalloc
|
||||
qh_memcheck
|
||||
qh_memfree
|
||||
qh_memfreeshort
|
||||
qh_meminit
|
||||
qh_meminitbuffers
|
||||
qh_memsetup
|
||||
qh_memsize
|
||||
qh_memstatistics
|
||||
qh_memtotal
|
||||
qh_merge_degenredundant
|
||||
qh_merge_nonconvex
|
||||
qh_mergecycle
|
||||
qh_mergecycle_all
|
||||
qh_mergecycle_facets
|
||||
qh_mergecycle_neighbors
|
||||
qh_mergecycle_ridges
|
||||
qh_mergecycle_vneighbors
|
||||
qh_mergefacet
|
||||
qh_mergefacet2d
|
||||
qh_mergeneighbors
|
||||
qh_mergeridges
|
||||
qh_mergesimplex
|
||||
qh_mergevertex_del
|
||||
qh_mergevertex_neighbors
|
||||
qh_mergevertices
|
||||
qh_minabsval
|
||||
qh_mindiff
|
||||
qh_nearcoplanar
|
||||
qh_nearvertex
|
||||
qh_neighbor_intersections
|
||||
qh_new_qhull
|
||||
qh_newfacet
|
||||
qh_newhashtable
|
||||
qh_newridge
|
||||
qh_newstats
|
||||
qh_newvertex
|
||||
qh_newvertices
|
||||
qh_nextfacet2d
|
||||
qh_nextfurthest
|
||||
qh_nextridge3d
|
||||
qh_normalize
|
||||
qh_normalize2
|
||||
qh_nostatistic
|
||||
qh_option
|
||||
qh_order_vertexneighbors
|
||||
qh_orientoutside
|
||||
qh_out1
|
||||
qh_out2n
|
||||
qh_out3n
|
||||
qh_outcoplanar
|
||||
qh_outerinner
|
||||
qh_partitionall
|
||||
qh_partitioncoplanar
|
||||
qh_partitionpoint
|
||||
qh_partitionvisible
|
||||
qh_point
|
||||
qh_point_add
|
||||
qh_pointdist
|
||||
qh_pointfacet
|
||||
qh_pointid
|
||||
qh_pointvertex
|
||||
qh_postmerge
|
||||
qh_premerge
|
||||
qh_prepare_output
|
||||
qh_prependfacet
|
||||
qh_printafacet
|
||||
qh_printallstatistics
|
||||
qh_printbegin
|
||||
qh_printcenter
|
||||
qh_printcentrum
|
||||
qh_printend
|
||||
qh_printend4geom
|
||||
qh_printextremes
|
||||
qh_printextremes_2d
|
||||
qh_printextremes_d
|
||||
qh_printfacet
|
||||
qh_printfacet2geom
|
||||
qh_printfacet2geom_points
|
||||
qh_printfacet2math
|
||||
qh_printfacet3geom_nonsimplicial
|
||||
qh_printfacet3geom_points
|
||||
qh_printfacet3geom_simplicial
|
||||
qh_printfacet3math
|
||||
qh_printfacet3vertex
|
||||
qh_printfacet4geom_nonsimplicial
|
||||
qh_printfacet4geom_simplicial
|
||||
qh_printfacetNvertex_nonsimplicial
|
||||
qh_printfacetNvertex_simplicial
|
||||
qh_printfacetheader
|
||||
qh_printfacetlist
|
||||
qh_printfacetridges
|
||||
qh_printfacets
|
||||
qh_printhashtable
|
||||
qh_printhelp_degenerate
|
||||
qh_printhelp_internal
|
||||
qh_printhelp_narrowhull
|
||||
qh_printhelp_singular
|
||||
qh_printhelp_topology
|
||||
qh_printhelp_wide
|
||||
qh_printhyperplaneintersection
|
||||
qh_printline3geom
|
||||
qh_printlists
|
||||
qh_printmatrix
|
||||
qh_printneighborhood
|
||||
qh_printpoint
|
||||
qh_printpoint3
|
||||
qh_printpointid
|
||||
qh_printpoints
|
||||
qh_printpoints_out
|
||||
qh_printpointvect
|
||||
qh_printpointvect2
|
||||
qh_printridge
|
||||
qh_printspheres
|
||||
qh_printstatistics
|
||||
qh_printstatlevel
|
||||
qh_printstats
|
||||
qh_printsummary
|
||||
qh_printvdiagram
|
||||
qh_printvdiagram2
|
||||
qh_printvertex
|
||||
qh_printvertexlist
|
||||
qh_printvertices
|
||||
qh_printvneighbors
|
||||
qh_printvnorm
|
||||
qh_printvoronoi
|
||||
qh_printvridge
|
||||
qh_produce_output
|
||||
qh_produce_output2
|
||||
qh_projectdim3
|
||||
qh_projectinput
|
||||
qh_projectpoint
|
||||
qh_projectpoints
|
||||
qh_qhull
|
||||
qh_rand
|
||||
qh_randomfactor
|
||||
qh_randommatrix
|
||||
qh_rboxpoints
|
||||
qh_readfeasible
|
||||
qh_readpoints
|
||||
qh_reducevertices
|
||||
qh_redundant_vertex
|
||||
qh_remove_extravertices
|
||||
qh_removefacet
|
||||
qh_removevertex
|
||||
qh_rename_sharedvertex
|
||||
qh_renameridgevertex
|
||||
qh_renamevertex
|
||||
qh_resetlists
|
||||
qh_rotateinput
|
||||
qh_rotatepoints
|
||||
qh_roundi
|
||||
qh_scaleinput
|
||||
qh_scalelast
|
||||
qh_scalepoints
|
||||
qh_set_hasAreaVolume
|
||||
qh_set_hasTriangulation
|
||||
qh_setaddnth
|
||||
qh_setaddsorted
|
||||
qh_setappend
|
||||
qh_setappend2ndlast
|
||||
qh_setappend_set
|
||||
qh_setcheck
|
||||
qh_setcompact
|
||||
qh_setcopy
|
||||
qh_setdel
|
||||
qh_setdelaunay
|
||||
qh_setdellast
|
||||
qh_setdelnth
|
||||
qh_setdelnthsorted
|
||||
qh_setdelsorted
|
||||
qh_setduplicate
|
||||
qh_setendpointer
|
||||
qh_setequal
|
||||
qh_setequal_except
|
||||
qh_setequal_skip
|
||||
qh_setfacetplane
|
||||
qh_setfeasible
|
||||
qh_setfree
|
||||
qh_setfree2
|
||||
qh_setfreelong
|
||||
qh_sethalfspace
|
||||
qh_sethalfspace_all
|
||||
qh_sethyperplane_det
|
||||
qh_sethyperplane_gauss
|
||||
qh_setin
|
||||
qh_setindex
|
||||
qh_setlarger
|
||||
qh_setlarger_quick
|
||||
qh_setlast
|
||||
qh_setnew
|
||||
qh_setnew_delnthsorted
|
||||
qh_setprint
|
||||
qh_setreplace
|
||||
qh_setsize
|
||||
qh_settemp
|
||||
qh_settempfree
|
||||
qh_settempfree_all
|
||||
qh_settemppop
|
||||
qh_settemppush
|
||||
qh_settruncate
|
||||
qh_setunique
|
||||
qh_setvoronoi_all
|
||||
qh_setzero
|
||||
qh_sharpnewfacets
|
||||
qh_skipfacet
|
||||
qh_skipfilename
|
||||
qh_srand
|
||||
qh_stddev
|
||||
qh_strtod
|
||||
qh_strtol
|
||||
qh_test_appendmerge
|
||||
qh_test_degen_neighbors
|
||||
qh_test_redundant_neighbors
|
||||
qh_test_vneighbors
|
||||
qh_tracemerge
|
||||
qh_tracemerging
|
||||
qh_triangulate
|
||||
qh_triangulate_facet
|
||||
qh_triangulate_link
|
||||
qh_triangulate_mirror
|
||||
qh_triangulate_null
|
||||
qh_updatetested
|
||||
qh_update_vertexneighbors
|
||||
qh_update_vertexneighbors_cone
|
||||
qh_user_memsizes
|
||||
qh_version
|
||||
qh_version2
|
||||
qh_vertexintersect
|
||||
qh_vertexintersect_new
|
||||
qh_vertexneighbors
|
||||
qh_vertexridges
|
||||
qh_vertexridges_facet
|
||||
qh_vertexsubset
|
||||
qh_voronoi_center
|
||||
qh_willdelete
|
||||
qh_zero
|
||||
@@ -0,0 +1,396 @@
|
||||
; qhull_r-exports.def --module-definition file
|
||||
;
|
||||
; Generated from depends.exe by cut-and-paste of exported symbols by mingw gcc
|
||||
; [jan'14] 391 symbols
|
||||
; Same as ../libqhullp/qhull-exports.def without DATA items (reentrant)
|
||||
;
|
||||
; Referenced by CMakeLists/add_library, libqhull_r.pro/DEF_FILE,
|
||||
; and libqhull_r.vcxproj/Linker/Input/Module Definition File
|
||||
;
|
||||
; If qh_NOmerge, use qhull_r-nomerge-exports.def
|
||||
; Created by -- grep -vE 'qh_all_merges|qh_appendmergeset|qh_basevertices|qh_check_dupridge|qh_checkconnect|qh_compare_facetmerge|qh_comparevisit|qh_copynonconvex|qh_degen_redundant_facet|qh_delridge_merge|qh_find_newvertex|qh_findbest_test|qh_findbestneighbor|qh_flippedmerges|qh_forcedmerges|qh_getmergeset|qh_getmergeset_initial|qh_hashridge|qh_hashridge_find|qh_makeridges|qh_mark_dupridges|qh_maydropneighbor|qh_merge_degenredundant|qh_merge_nonconvex|qh_mergecycle|qh_mergecycle_all|qh_mergecycle_facets|qh_mergecycle_neighbors|qh_mergecycle_ridges|qh_mergecycle_vneighbors|qh_mergefacet|qh_mergefacet2d|qh_mergeneighbors|qh_mergeridges|qh_mergesimplex|qh_mergevertex_del|qh_mergevertex_neighbors|qh_mergevertices|qh_nearcoplanar|qh_nearvertex|qh_neighbor_intersections|qh_newhashtable|qh_newvertex|qh_newvertices|qh_nextridge3d|qh_reducevertices|qh_redundant_vertex|qh_remove_extravertices|qh_rename_sharedvertex|qh_renameridgevertex|qh_renamevertex|qh_test_appendmerge|qh_test_degen_neighbors|qh_test_redundant_neighbors|qh_test_vneighbors|qh_tracemerge|qh_tracemerging|qh_triangulate_facet|qh_triangulate_link|qh_triangulate_mirror|qh_triangulate_null|qh_updatetested|qh_vertexridges|qh_vertexridges_facet|qh_willdelete' qhull_r-nomerge-exports.def >qhull_r-nomerge-exports.def
|
||||
;
|
||||
; $Id: //main/2019/qhull/src/libqhull_r/qhull_r-nomerge-exports.def#5 $$Change: 3396 $
|
||||
; $DateTime: 2023/01/02 16:59:48 $$Author: bbarber $
|
||||
;
|
||||
; Define qhull_VERSION in CMakeLists.txt, Makefile, qhull-exports.def, qhull_p-exports.def, qhull_r-exports.def, and qhull-warn.pri
|
||||
VERSION 8.0
|
||||
EXPORTS
|
||||
qh_addhash
|
||||
qh_addpoint
|
||||
qh_alloc_qh
|
||||
qh_allstatA
|
||||
qh_allstatB
|
||||
qh_allstatC
|
||||
qh_allstatD
|
||||
qh_allstatE
|
||||
qh_allstatE2
|
||||
qh_allstatF
|
||||
qh_allstatG
|
||||
qh_allstatH
|
||||
qh_allstatI
|
||||
qh_allstatistics
|
||||
qh_appendfacet
|
||||
qh_appendprint
|
||||
qh_appendvertex
|
||||
qh_argv_to_command
|
||||
qh_argv_to_command_size
|
||||
qh_attachnewfacets
|
||||
qh_backnormal
|
||||
qh_build_withrestart
|
||||
qh_buildhull
|
||||
qh_buildtracing
|
||||
qh_check_bestdist
|
||||
qh_check_maxout
|
||||
qh_check_output
|
||||
qh_check_point
|
||||
qh_check_points
|
||||
qh_checkconvex
|
||||
qh_checkdelridge
|
||||
qh_checkfacet
|
||||
qh_checkflags
|
||||
qh_checkflipped
|
||||
qh_checkflipped_all
|
||||
qh_checkpolygon
|
||||
qh_checkvertex
|
||||
qh_checkzero
|
||||
qh_clear_outputflags
|
||||
qh_clearcenters
|
||||
qh_clock
|
||||
qh_collectstatistics
|
||||
qh_compare_facetarea
|
||||
qh_compare_facetvisit
|
||||
qh_compare_nummerge
|
||||
qh_copyfilename
|
||||
qh_copypoints
|
||||
qh_countfacets
|
||||
qh_createsimplex
|
||||
qh_crossproduct
|
||||
qh_deletevisible
|
||||
qh_delfacet
|
||||
qh_delvertex
|
||||
qh_determinant
|
||||
qh_detjoggle
|
||||
qh_detroundoff
|
||||
qh_detsimplex
|
||||
qh_detvnorm
|
||||
qh_detvridge
|
||||
qh_detvridge3
|
||||
qh_dfacet
|
||||
qh_distnorm
|
||||
qh_distplane
|
||||
qh_distround
|
||||
qh_divzero
|
||||
qh_dvertex
|
||||
qh_eachvoronoi
|
||||
qh_eachvoronoi_all
|
||||
qh_errexit
|
||||
qh_errexit2
|
||||
qh_errexit_rbox
|
||||
qh_errprint
|
||||
qh_exit
|
||||
qh_facet2point
|
||||
qh_facet3vertex
|
||||
qh_facetarea
|
||||
qh_facetarea_simplex
|
||||
qh_facetcenter
|
||||
qh_facetintersect
|
||||
qh_facetvertices
|
||||
qh_findbest
|
||||
qh_findbestfacet
|
||||
qh_findbesthorizon
|
||||
qh_findbestlower
|
||||
qh_findbestnew
|
||||
qh_findfacet_all
|
||||
qh_findgood
|
||||
qh_findgood_all
|
||||
qh_findgooddist
|
||||
qh_findhorizon
|
||||
qh_fprintf
|
||||
qh_fprintf_rbox
|
||||
qh_fprintf_stderr
|
||||
qh_free
|
||||
qh_free_qh
|
||||
qh_freebuffers
|
||||
qh_freebuild
|
||||
qh_freeqhull
|
||||
qh_furthestnext
|
||||
qh_furthestout
|
||||
qh_gausselim
|
||||
qh_geomplanes
|
||||
qh_get_ATinfinity
|
||||
qh_get_center_size
|
||||
qh_get_DELAUNAY
|
||||
qh_get_del_vertices
|
||||
qh_get_DISTround
|
||||
qh_get_facet_id
|
||||
qh_get_facet_list
|
||||
qh_get_facet_tail
|
||||
qh_get_feasible_point
|
||||
qh_get_first_point
|
||||
qh_get_hasAreaVolume
|
||||
qh_get_hasTriangulation
|
||||
qh_get_hull_dim
|
||||
qh_get_input_dim
|
||||
qh_get_input_points
|
||||
qh_get_KEEPcoplanar
|
||||
qh_get_last_high
|
||||
qh_get_last_low
|
||||
qh_get_last_newhigh
|
||||
qh_get_max_outside
|
||||
qh_get_MERGEexact
|
||||
qh_get_MINoutside
|
||||
qh_get_NOerrexit
|
||||
qh_get_normal_size
|
||||
qh_get_num_facets
|
||||
qh_get_num_good
|
||||
qh_get_num_points
|
||||
qh_get_num_vertices
|
||||
qh_get_num_visible
|
||||
qh_get_other_points
|
||||
qh_get_PROJECTdelaunay
|
||||
qh_get_qhull_command
|
||||
qh_get_SCALElast
|
||||
qh_get_totarea
|
||||
qh_get_totvol
|
||||
qh_get_UPPERdelaunay
|
||||
qh_get_vertex_list
|
||||
qh_get_vertex_tail
|
||||
qh_get_vertex_visit
|
||||
qh_get_visit_id
|
||||
qh_getangle
|
||||
qh_getarea
|
||||
qh_getcenter
|
||||
qh_getcentrum
|
||||
qh_getdistance
|
||||
qh_gethash
|
||||
qh_gram_schmidt
|
||||
qh_infiniteloop
|
||||
qh_init_A
|
||||
qh_init_B
|
||||
qh_init_qhull_command
|
||||
qh_initbuild
|
||||
qh_initflags
|
||||
qh_initialhull
|
||||
qh_initialvertices
|
||||
qh_initqhull_buffers
|
||||
qh_initqhull_globals
|
||||
qh_initqhull_mem
|
||||
qh_initqhull_outputflags
|
||||
qh_initqhull_start
|
||||
qh_initqhull_start2
|
||||
qh_initstatistics
|
||||
qh_initthresholds
|
||||
qh_inthresholds
|
||||
qh_isvertex
|
||||
qh_joggle_restart
|
||||
qh_joggleinput
|
||||
qh_lib_check
|
||||
qh_makenew_nonsimplicial
|
||||
qh_makenew_simplicial
|
||||
qh_makenewfacet
|
||||
qh_makenewfacets
|
||||
qh_makenewplanes
|
||||
qh_malloc
|
||||
qh_markkeep
|
||||
qh_markvoronoi
|
||||
qh_matchdupridge
|
||||
qh_matchneighbor
|
||||
qh_matchnewfacets
|
||||
qh_matchvertices
|
||||
qh_maxabsval
|
||||
qh_maxmin
|
||||
qh_maxouter
|
||||
qh_maxsimplex
|
||||
qh_memalloc
|
||||
qh_memfree
|
||||
qh_memfreeshort
|
||||
qh_meminit
|
||||
qh_meminitbuffers
|
||||
qh_memsetup
|
||||
qh_memsize
|
||||
qh_memstatistics
|
||||
qh_memtotal
|
||||
qh_minabsval
|
||||
qh_mindiff
|
||||
qh_new_qhull
|
||||
qh_newfacet
|
||||
qh_newridge
|
||||
qh_newstats
|
||||
qh_nextfacet2d
|
||||
qh_nextfurthest
|
||||
qh_normalize
|
||||
qh_normalize2
|
||||
qh_nostatistic
|
||||
qh_option
|
||||
qh_order_vertexneighbors
|
||||
qh_orientoutside
|
||||
qh_out1
|
||||
qh_out2n
|
||||
qh_out3n
|
||||
qh_outcoplanar
|
||||
qh_outerinner
|
||||
qh_partitionall
|
||||
qh_partitioncoplanar
|
||||
qh_partitionpoint
|
||||
qh_partitionvisible
|
||||
qh_point
|
||||
qh_point_add
|
||||
qh_pointdist
|
||||
qh_pointfacet
|
||||
qh_pointid
|
||||
qh_pointvertex
|
||||
qh_postmerge
|
||||
qh_premerge
|
||||
qh_prepare_output
|
||||
qh_prependfacet
|
||||
qh_printafacet
|
||||
qh_printallstatistics
|
||||
qh_printbegin
|
||||
qh_printcenter
|
||||
qh_printcentrum
|
||||
qh_printend
|
||||
qh_printend4geom
|
||||
qh_printextremes
|
||||
qh_printextremes_2d
|
||||
qh_printextremes_d
|
||||
qh_printfacet
|
||||
qh_printfacet2geom
|
||||
qh_printfacet2geom_points
|
||||
qh_printfacet2math
|
||||
qh_printfacet3geom_nonsimplicial
|
||||
qh_printfacet3geom_points
|
||||
qh_printfacet3geom_simplicial
|
||||
qh_printfacet3math
|
||||
qh_printfacet3vertex
|
||||
qh_printfacet4geom_nonsimplicial
|
||||
qh_printfacet4geom_simplicial
|
||||
qh_printfacetNvertex_nonsimplicial
|
||||
qh_printfacetNvertex_simplicial
|
||||
qh_printfacetheader
|
||||
qh_printfacetlist
|
||||
qh_printfacetridges
|
||||
qh_printfacets
|
||||
qh_printhashtable
|
||||
qh_printhelp_degenerate
|
||||
qh_printhelp_internal
|
||||
qh_printhelp_narrowhull
|
||||
qh_printhelp_singular
|
||||
qh_printhelp_topology
|
||||
qh_printhelp_wide
|
||||
qh_printhyperplaneintersection
|
||||
qh_printline3geom
|
||||
qh_printlists
|
||||
qh_printmatrix
|
||||
qh_printneighborhood
|
||||
qh_printpoint
|
||||
qh_printpoint3
|
||||
qh_printpointid
|
||||
qh_printpoints
|
||||
qh_printpoints_out
|
||||
qh_printpointvect
|
||||
qh_printpointvect2
|
||||
qh_printridge
|
||||
qh_printspheres
|
||||
qh_printstatistics
|
||||
qh_printstatlevel
|
||||
qh_printstats
|
||||
qh_printsummary
|
||||
qh_printvdiagram
|
||||
qh_printvdiagram2
|
||||
qh_printvertex
|
||||
qh_printvertexlist
|
||||
qh_printvertices
|
||||
qh_printvneighbors
|
||||
qh_printvnorm
|
||||
qh_printvoronoi
|
||||
qh_printvridge
|
||||
qh_produce_output
|
||||
qh_produce_output2
|
||||
qh_projectdim3
|
||||
qh_projectinput
|
||||
qh_projectpoint
|
||||
qh_projectpoints
|
||||
qh_qhull
|
||||
qh_rand
|
||||
qh_randomfactor
|
||||
qh_randommatrix
|
||||
qh_rboxpoints
|
||||
qh_readfeasible
|
||||
qh_readpoints
|
||||
qh_removefacet
|
||||
qh_removevertex
|
||||
qh_resetlists
|
||||
qh_rotateinput
|
||||
qh_rotatepoints
|
||||
qh_roundi
|
||||
qh_scaleinput
|
||||
qh_scalelast
|
||||
qh_scalepoints
|
||||
qh_set_hasAreaVolume
|
||||
qh_set_hasTriangulation
|
||||
qh_setaddnth
|
||||
qh_setaddsorted
|
||||
qh_setappend
|
||||
qh_setappend2ndlast
|
||||
qh_setappend_set
|
||||
qh_setcheck
|
||||
qh_setcompact
|
||||
qh_setcopy
|
||||
qh_setdel
|
||||
qh_setdelaunay
|
||||
qh_setdellast
|
||||
qh_setdelnth
|
||||
qh_setdelnthsorted
|
||||
qh_setdelsorted
|
||||
qh_setduplicate
|
||||
qh_setequal
|
||||
qh_setequal_except
|
||||
qh_setequal_skip
|
||||
qh_setfacetplane
|
||||
qh_setfeasible
|
||||
qh_setfree
|
||||
qh_setfree2
|
||||
qh_setfreelong
|
||||
qh_sethalfspace
|
||||
qh_sethalfspace_all
|
||||
qh_sethyperplane_det
|
||||
qh_sethyperplane_gauss
|
||||
qh_setin
|
||||
qh_setindex
|
||||
qh_setlarger
|
||||
qh_setlarger_quick
|
||||
qh_setlast
|
||||
qh_setnew
|
||||
qh_setnew_delnthsorted
|
||||
qh_setprint
|
||||
qh_setreplace
|
||||
qh_setsize
|
||||
qh_settemp
|
||||
qh_settempfree
|
||||
qh_settempfree_all
|
||||
qh_settemppop
|
||||
qh_settemppush
|
||||
qh_settruncate
|
||||
qh_setunique
|
||||
qh_setvoronoi_all
|
||||
qh_setzero
|
||||
qh_sharpnewfacets
|
||||
qh_skipfacet
|
||||
qh_skipfilename
|
||||
qh_srand
|
||||
qh_stddev
|
||||
qh_strtod
|
||||
qh_strtol
|
||||
qh_triangulate
|
||||
qh_update_vertexneighbors
|
||||
qh_update_vertexneighbors_cone
|
||||
qh_user_memsizes
|
||||
qh_version
|
||||
qh_version2
|
||||
qh_vertexintersect
|
||||
qh_vertexintersect_new
|
||||
qh_vertexneighbors
|
||||
qh_vertexsubset
|
||||
qh_voronoi_center
|
||||
qh_zero
|
||||
@@ -0,0 +1,161 @@
|
||||
/*<html><pre> -<a href="qh-qhull_r.htm"
|
||||
>-------------------------------</a><a name="TOP">-</a>
|
||||
|
||||
qhull_ra.h
|
||||
all header files for compiling qhull with reentrant code
|
||||
included before C++ headers for user_r.h:QHULL_CRTDBG
|
||||
|
||||
see qh-qhull.htm
|
||||
|
||||
see libqhull_r.h for user-level definitions
|
||||
|
||||
see user_r.h for user-definable constants
|
||||
|
||||
defines internal functions for libqhull_r.c global_r.c
|
||||
|
||||
Copyright (c) 1993-2020 The Geometry Center.
|
||||
$Id: //main/2019/qhull/src/libqhull_r/qhull_ra.h#2 $$Change: 2953 $
|
||||
$DateTime: 2020/05/21 22:05:32 $$Author: bbarber $
|
||||
|
||||
Notes: grep for ((" and (" to catch fprintf("lkasdjf");
|
||||
full parens around (x?y:z)
|
||||
use '#include "libqhull_r/qhull_ra.h"' to avoid name clashes
|
||||
*/
|
||||
|
||||
#ifndef qhDEFqhulla
|
||||
#define qhDEFqhulla 1
|
||||
|
||||
#include "libqhull_r.h" /* Includes user_r.h and data types */
|
||||
|
||||
#include "stat_r.h"
|
||||
#include "random_r.h"
|
||||
#include "mem_r.h"
|
||||
#include "qset_r.h"
|
||||
#include "geom_r.h"
|
||||
#include "merge_r.h"
|
||||
#include "poly_r.h"
|
||||
#include "io_r.h"
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <float.h> /* some compilers will not need float.h */
|
||||
#include <limits.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
/*** uncomment here and qset_r.c
|
||||
if string.h does not define memcpy()
|
||||
#include <memory.h>
|
||||
*/
|
||||
|
||||
#if qh_CLOCKtype == 2 /* defined in user_r.h from libqhull_r.h */
|
||||
#include <sys/types.h>
|
||||
#include <sys/times.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER /* Microsoft Visual C++ -- warning level 4 */
|
||||
#pragma warning( disable : 4100) /* unreferenced formal parameter */
|
||||
#pragma warning( disable : 4127) /* conditional expression is constant */
|
||||
#pragma warning( disable : 4706) /* assignment within conditional function */
|
||||
#pragma warning( disable : 4996) /* function was declared deprecated(strcpy, localtime, etc.) */
|
||||
#endif
|
||||
|
||||
/* ======= -macros- =========== */
|
||||
|
||||
/*-<a href="qh-qhull_r.htm#TOC"
|
||||
>--------------------------------</a><a name="traceN">-</a>
|
||||
|
||||
traceN((qh, qh->ferr, 0Nnnn, "format\n", vars));
|
||||
calls qh_fprintf if qh.IStracing >= N
|
||||
|
||||
Add debugging traps to the end of qh_fprintf
|
||||
|
||||
notes:
|
||||
removing tracing reduces code size but doesn't change execution speed
|
||||
*/
|
||||
#ifndef qh_NOtrace
|
||||
#define trace0(args) {if (qh->IStracing) qh_fprintf args;}
|
||||
#define trace1(args) {if (qh->IStracing >= 1) qh_fprintf args;}
|
||||
#define trace2(args) {if (qh->IStracing >= 2) qh_fprintf args;}
|
||||
#define trace3(args) {if (qh->IStracing >= 3) qh_fprintf args;}
|
||||
#define trace4(args) {if (qh->IStracing >= 4) qh_fprintf args;}
|
||||
#define trace5(args) {if (qh->IStracing >= 5) qh_fprintf args;}
|
||||
#else /* qh_NOtrace */
|
||||
#define trace0(args) {}
|
||||
#define trace1(args) {}
|
||||
#define trace2(args) {}
|
||||
#define trace3(args) {}
|
||||
#define trace4(args) {}
|
||||
#define trace5(args) {}
|
||||
#endif /* qh_NOtrace */
|
||||
|
||||
/*-<a href="qh-qhull_r.htm#TOC"
|
||||
>--------------------------------</a><a name="QHULL_UNUSED">-</a>
|
||||
|
||||
Define an unused variable to avoid compiler warnings
|
||||
|
||||
Derived from Qt's corelib/global/qglobal.h
|
||||
|
||||
*/
|
||||
|
||||
#if defined(__cplusplus) && defined(__INTEL_COMPILER) && !defined(QHULL_OS_WIN)
|
||||
template <typename T>
|
||||
inline void qhullUnused(T &x) { (void)x; }
|
||||
# define QHULL_UNUSED(x) qhullUnused(x);
|
||||
#else
|
||||
# define QHULL_UNUSED(x) (void)x;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***** -libqhull_r.c prototypes (alphabetical after qhull) ********************/
|
||||
|
||||
void qh_qhull(qhT *qh);
|
||||
boolT qh_addpoint(qhT *qh, pointT *furthest, facetT *facet, boolT checkdist);
|
||||
void qh_build_withrestart(qhT *qh);
|
||||
vertexT *qh_buildcone(qhT *qh, pointT *furthest, facetT *facet, int goodhorizon, facetT **retryfacet);
|
||||
boolT qh_buildcone_mergepinched(qhT *qh, vertexT *apex, facetT *facet, facetT **retryfacet);
|
||||
boolT qh_buildcone_onlygood(qhT *qh, vertexT *apex, int goodhorizon);
|
||||
void qh_buildhull(qhT *qh);
|
||||
void qh_buildtracing(qhT *qh, pointT *furthest, facetT *facet);
|
||||
void qh_errexit2(qhT *qh, int exitcode, facetT *facet, facetT *otherfacet);
|
||||
void qh_findhorizon(qhT *qh, pointT *point, facetT *facet, int *goodvisible,int *goodhorizon);
|
||||
pointT *qh_nextfurthest(qhT *qh, facetT **visible);
|
||||
void qh_partitionall(qhT *qh, setT *vertices, pointT *points,int npoints);
|
||||
void qh_partitioncoplanar(qhT *qh, pointT *point, facetT *facet, realT *dist, boolT allnew);
|
||||
void qh_partitionpoint(qhT *qh, pointT *point, facetT *facet);
|
||||
void qh_partitionvisible(qhT *qh, boolT allpoints, int *numpoints);
|
||||
void qh_joggle_restart(qhT *qh, const char *reason);
|
||||
void qh_printsummary(qhT *qh, FILE *fp);
|
||||
|
||||
/***** -global_r.c internal prototypes (alphabetical) ***********************/
|
||||
|
||||
void qh_appendprint(qhT *qh, qh_PRINT format);
|
||||
void qh_freebuild(qhT *qh, boolT allmem);
|
||||
void qh_freebuffers(qhT *qh);
|
||||
void qh_initbuffers(qhT *qh, coordT *points, int numpoints, int dim, boolT ismalloc);
|
||||
|
||||
/***** -stat_r.c internal prototypes (alphabetical) ***********************/
|
||||
|
||||
void qh_allstatA(qhT *qh);
|
||||
void qh_allstatB(qhT *qh);
|
||||
void qh_allstatC(qhT *qh);
|
||||
void qh_allstatD(qhT *qh);
|
||||
void qh_allstatE(qhT *qh);
|
||||
void qh_allstatE2(qhT *qh);
|
||||
void qh_allstatF(qhT *qh);
|
||||
void qh_allstatG(qhT *qh);
|
||||
void qh_allstatH(qhT *qh);
|
||||
void qh_freebuffers(qhT *qh);
|
||||
void qh_initbuffers(qhT *qh, coordT *points, int numpoints, int dim, boolT ismalloc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* qhDEFqhulla */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,506 @@
|
||||
/*<html><pre> -<a href="qh-set_r.htm"
|
||||
>-------------------------------</a><a name="TOP">-</a>
|
||||
|
||||
qset_r.h
|
||||
header file for qset_r.c that implements set
|
||||
|
||||
see qh-set_r.htm and qset_r.c
|
||||
|
||||
only uses mem_r.c, malloc/free
|
||||
|
||||
for error handling, writes message and calls
|
||||
qh_errexit(qhT *qh, qhmem_ERRqhull, NULL, NULL);
|
||||
|
||||
set operations satisfy the following properties:
|
||||
- sets have a max size, the actual size (if different) is stored at the end
|
||||
- every set is NULL terminated
|
||||
- sets may be sorted or unsorted, the caller must distinguish this
|
||||
|
||||
Copyright (c) 1993-2020 The Geometry Center.
|
||||
$Id: //main/2019/qhull/src/libqhull_r/qset_r.h#4 $$Change: 2953 $
|
||||
$DateTime: 2020/05/21 22:05:32 $$Author: bbarber $
|
||||
*/
|
||||
|
||||
#ifndef qhDEFset
|
||||
#define qhDEFset 1
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/*================= -structures- ===============*/
|
||||
|
||||
#ifndef DEFsetT
|
||||
#define DEFsetT 1
|
||||
typedef struct setT setT; /* a set is a sorted or unsorted array of pointers */
|
||||
#endif
|
||||
|
||||
#ifndef DEFqhT
|
||||
#define DEFqhT 1
|
||||
typedef struct qhT qhT; /* defined in libqhull_r.h */
|
||||
#endif
|
||||
|
||||
/* [jan'15] Decided not to use countT. Most sets are small. The code uses signed tests */
|
||||
|
||||
/*-<a href="qh-set_r.htm#TOC"
|
||||
>----------------------------------------</a><a name="setT">-</a>
|
||||
|
||||
setT
|
||||
a set or list of pointers with maximum size and actual size.
|
||||
|
||||
variations:
|
||||
unsorted, unique -- a list of unique pointers with NULL terminator
|
||||
user guarantees uniqueness
|
||||
sorted -- a sorted list of unique pointers with NULL terminator
|
||||
qset_r.c guarantees uniqueness
|
||||
unsorted -- a list of pointers terminated with NULL
|
||||
indexed -- an array of pointers with NULL elements
|
||||
|
||||
structure for set of n elements:
|
||||
|
||||
--------------
|
||||
| maxsize
|
||||
--------------
|
||||
| e[0] - a pointer, may be NULL for indexed sets
|
||||
--------------
|
||||
| e[1]
|
||||
|
||||
--------------
|
||||
| ...
|
||||
--------------
|
||||
| e[n-1]
|
||||
--------------
|
||||
| e[n] = NULL
|
||||
--------------
|
||||
| ...
|
||||
--------------
|
||||
| e[maxsize] - n+1 or NULL (determines actual size of set)
|
||||
--------------
|
||||
|
||||
*/
|
||||
|
||||
/*-- setelemT -- internal type to allow both pointers and indices
|
||||
*/
|
||||
typedef union setelemT setelemT;
|
||||
union setelemT {
|
||||
void *p;
|
||||
int i; /* integer used for e[maxSize] */
|
||||
};
|
||||
|
||||
struct setT {
|
||||
int maxsize; /* maximum number of elements (except NULL) */
|
||||
setelemT e[1]; /* array of pointers, tail is NULL */
|
||||
/* last slot (unless NULL) is actual size+1
|
||||
e[maxsize]==NULL or e[e[maxsize]-1]==NULL */
|
||||
/* this may generate a warning since e[] contains
|
||||
maxsize elements */
|
||||
};
|
||||
|
||||
/*=========== -constants- =========================*/
|
||||
|
||||
/*-<a href="qh-set_r.htm#TOC"
|
||||
>-----------------------------------</a><a name="SETelemsize">-</a>
|
||||
|
||||
SETelemsize
|
||||
size of a set element in bytes
|
||||
*/
|
||||
#define SETelemsize ((int)sizeof(setelemT))
|
||||
|
||||
|
||||
/*=========== -macros- =========================*/
|
||||
|
||||
/*-<a href="qh-set_r.htm#TOC"
|
||||
>-----------------------------------</a><a name="FOREACHsetelement_">-</a>
|
||||
|
||||
FOREACHsetelement_(type, set, variable)
|
||||
define FOREACH iterator
|
||||
|
||||
declare:
|
||||
assumes *variable and **variablep are declared
|
||||
no space in "variable)" [DEC Alpha cc compiler]
|
||||
|
||||
each iteration:
|
||||
variable is set element
|
||||
variablep is one beyond variable.
|
||||
|
||||
to repeat an element:
|
||||
variablep--; / *repeat* /
|
||||
|
||||
at exit:
|
||||
variable is NULL at end of loop
|
||||
|
||||
example:
|
||||
#define FOREACHfacet_(facets) FOREACHsetelement_(facetT, facets, facet)
|
||||
|
||||
notes:
|
||||
use FOREACHsetelement_i_() if need index or include NULLs
|
||||
assumes set is not modified
|
||||
|
||||
WARNING:
|
||||
nested loops can't use the same variable (define another FOREACH)
|
||||
|
||||
needs braces if nested inside another FOREACH
|
||||
this includes intervening blocks, e.g. FOREACH...{ if () FOREACH...} )
|
||||
*/
|
||||
#define FOREACHsetelement_(type, set, variable) \
|
||||
if (((variable= NULL), set)) for (\
|
||||
variable##p= (type **)&((set)->e[0].p); \
|
||||
(variable= *variable##p++);)
|
||||
|
||||
/*-<a href="qh-set_r.htm#TOC"
|
||||
>----------------------------------------</a><a name="FOREACHsetelement_i_">-</a>
|
||||
|
||||
FOREACHsetelement_i_(qh, type, set, variable)
|
||||
define indexed FOREACH iterator
|
||||
|
||||
declare:
|
||||
type *variable, variable_n, variable_i;
|
||||
|
||||
each iteration:
|
||||
variable is set element, may be NULL
|
||||
variable_i is index, variable_n is qh_setsize()
|
||||
|
||||
to repeat an element:
|
||||
variable_i--; variable_n-- repeats for deleted element
|
||||
|
||||
at exit:
|
||||
variable==NULL and variable_i==variable_n
|
||||
|
||||
example:
|
||||
#define FOREACHfacet_i_(qh, facets) FOREACHsetelement_i_(qh, facetT, facets, facet)
|
||||
|
||||
WARNING:
|
||||
nested loops can't use the same variable (define another FOREACH)
|
||||
|
||||
needs braces if nested inside another FOREACH
|
||||
this includes intervening blocks, e.g. FOREACH...{ if () FOREACH...} )
|
||||
*/
|
||||
#define FOREACHsetelement_i_(qh, type, set, variable) \
|
||||
if (((variable= NULL), set)) for (\
|
||||
variable##_i= 0, variable= (type *)((set)->e[0].p), \
|
||||
variable##_n= qh_setsize(qh, set);\
|
||||
variable##_i < variable##_n;\
|
||||
variable= (type *)((set)->e[++variable##_i].p) )
|
||||
|
||||
/*-<a href="qh-set_r.htm#TOC"
|
||||
>--------------------------------------</a><a name="FOREACHsetelementreverse_">-</a>
|
||||
|
||||
FOREACHsetelementreverse_(qh, type, set, variable)-
|
||||
define FOREACH iterator in reverse order
|
||||
|
||||
declare:
|
||||
assumes *variable and **variablep are declared
|
||||
also declare 'int variabletemp'
|
||||
|
||||
each iteration:
|
||||
variable is set element
|
||||
|
||||
to repeat an element:
|
||||
variabletemp++; / *repeat* /
|
||||
|
||||
at exit:
|
||||
variable is NULL
|
||||
|
||||
example:
|
||||
#define FOREACHvertexreverse_(vertices) FOREACHsetelementreverse_(vertexT, vertices, vertex)
|
||||
|
||||
notes:
|
||||
use FOREACHsetelementreverse12_() to reverse first two elements
|
||||
WARNING: needs braces if nested inside another FOREACH
|
||||
*/
|
||||
#define FOREACHsetelementreverse_(qh, type, set, variable) \
|
||||
if (((variable= NULL), set)) for (\
|
||||
variable##temp= qh_setsize(qh, set)-1, variable= qh_setlast(qh, set);\
|
||||
variable; variable= \
|
||||
((--variable##temp >= 0) ? SETelemt_(set, variable##temp, type) : NULL))
|
||||
|
||||
/*-<a href="qh-set_r.htm#TOC"
|
||||
>-----------------------------------</a><a name="FOREACHsetelementreverse12_">-</a>
|
||||
|
||||
FOREACHsetelementreverse12_(type, set, variable)-
|
||||
define FOREACH iterator with e[1] and e[0] reversed
|
||||
|
||||
declare:
|
||||
assumes *variable and **variablep are declared
|
||||
|
||||
each iteration:
|
||||
variable is set element
|
||||
variablep is one after variable.
|
||||
|
||||
to repeat an element:
|
||||
variablep--; / *repeat* /
|
||||
|
||||
at exit:
|
||||
variable is NULL at end of loop
|
||||
|
||||
example
|
||||
#define FOREACHvertexreverse12_(vertices) FOREACHsetelementreverse12_(vertexT, vertices, vertex)
|
||||
|
||||
notes:
|
||||
WARNING: needs braces if nested inside another FOREACH
|
||||
*/
|
||||
#define FOREACHsetelementreverse12_(type, set, variable) \
|
||||
if (((variable= NULL), set)) for (\
|
||||
variable##p= (type **)&((set)->e[1].p); \
|
||||
(variable= *variable##p); \
|
||||
variable##p == ((type **)&((set)->e[0].p))?variable##p += 2: \
|
||||
(variable##p == ((type **)&((set)->e[1].p))?variable##p--:variable##p++))
|
||||
|
||||
/*-<a href="qh-set_r.htm#TOC"
|
||||
>-----------------------------------</a><a name="FOREACHelem_">-</a>
|
||||
|
||||
FOREACHelem_( set )-
|
||||
iterate elements in a set
|
||||
|
||||
declare:
|
||||
void *elem, *elemp;
|
||||
|
||||
each iteration:
|
||||
elem is set element
|
||||
elemp is one beyond
|
||||
|
||||
to repeat an element:
|
||||
elemp--; / *repeat* /
|
||||
|
||||
at exit:
|
||||
elem == NULL at end of loop
|
||||
|
||||
example:
|
||||
FOREACHelem_(set) {
|
||||
|
||||
notes:
|
||||
assumes set is not modified
|
||||
WARNING: needs braces if nested inside another FOREACH
|
||||
*/
|
||||
#define FOREACHelem_(set) FOREACHsetelement_(void, set, elem)
|
||||
|
||||
/*-<a href="qh-set_r.htm#TOC"
|
||||
>-----------------------------------</a><a name="FOREACHset_">-</a>
|
||||
|
||||
FOREACHset_( set )-
|
||||
iterate a set of sets
|
||||
|
||||
declare:
|
||||
setT *set, **setp;
|
||||
|
||||
each iteration:
|
||||
set is set element
|
||||
setp is one beyond
|
||||
|
||||
to repeat an element:
|
||||
setp--; / *repeat* /
|
||||
|
||||
at exit:
|
||||
set == NULL at end of loop
|
||||
|
||||
example
|
||||
FOREACHset_(sets) {
|
||||
|
||||
notes:
|
||||
WARNING: needs braces if nested inside another FOREACH
|
||||
*/
|
||||
#define FOREACHset_(sets) FOREACHsetelement_(setT, sets, set)
|
||||
|
||||
/*-<a href="qh-set_r.htm#TOC"
|
||||
>-----------------------------------------</a><a name="SETindex_">-</a>
|
||||
|
||||
SETindex_( set, elem )
|
||||
return index of elem in set
|
||||
|
||||
notes:
|
||||
for use with FOREACH iteration
|
||||
WARN64 -- Maximum set size is 2G
|
||||
|
||||
example:
|
||||
i= SETindex_(ridges, ridge)
|
||||
*/
|
||||
#define SETindex_(set, elem) ((int)((void **)elem##p - (void **)&(set)->e[1].p))
|
||||
|
||||
/*-<a href="qh-set_r.htm#TOC"
|
||||
>---------------------------------------</a><a name="SETref_">-</a>
|
||||
|
||||
SETref_( elem )
|
||||
l.h.s. for modifying the current element in a FOREACH iteration
|
||||
|
||||
example:
|
||||
SETref_(ridge)= anotherridge;
|
||||
*/
|
||||
#define SETref_(elem) (elem##p[-1])
|
||||
|
||||
/*-<a href="qh-set_r.htm#TOC"
|
||||
>---------------------------------------</a><a name="SETelem_">-</a>
|
||||
|
||||
SETelem_(set, n)
|
||||
return the n'th element of set
|
||||
|
||||
notes:
|
||||
assumes that n is valid [0..size] and that set is defined
|
||||
use SETelemt_() for type cast
|
||||
*/
|
||||
#define SETelem_(set, n) ((set)->e[n].p)
|
||||
|
||||
/*-<a href="qh-set_r.htm#TOC"
|
||||
>---------------------------------------</a><a name="SETelemt_">-</a>
|
||||
|
||||
SETelemt_(set, n, type)
|
||||
return the n'th element of set as a type
|
||||
|
||||
notes:
|
||||
assumes that n is valid [0..size] and that set is defined
|
||||
*/
|
||||
#define SETelemt_(set, n, type) ((type *)((set)->e[n].p))
|
||||
|
||||
/*-<a href="qh-set_r.htm#TOC"
|
||||
>---------------------------------------</a><a name="SETelemaddr_">-</a>
|
||||
|
||||
SETelemaddr_(set, n, type)
|
||||
return address of the n'th element of a set
|
||||
|
||||
notes:
|
||||
assumes that n is valid [0..size] and set is defined
|
||||
*/
|
||||
#define SETelemaddr_(set, n, type) ((type **)(&((set)->e[n].p)))
|
||||
|
||||
/*-<a href="qh-set_r.htm#TOC"
|
||||
>---------------------------------------</a><a name="SETfirst_">-</a>
|
||||
|
||||
SETfirst_(set)
|
||||
return first element of set
|
||||
|
||||
*/
|
||||
#define SETfirst_(set) ((set)->e[0].p)
|
||||
|
||||
/*-<a href="qh-set_r.htm#TOC"
|
||||
>---------------------------------------</a><a name="SETfirstt_">-</a>
|
||||
|
||||
SETfirstt_(set, type)
|
||||
return first element of set as a type
|
||||
|
||||
*/
|
||||
#define SETfirstt_(set, type) ((type *)((set)->e[0].p))
|
||||
|
||||
/*-<a href="qh-set_r.htm#TOC"
|
||||
>---------------------------------------</a><a name="SETsecond_">-</a>
|
||||
|
||||
SETsecond_(set)
|
||||
return second element of set
|
||||
|
||||
*/
|
||||
#define SETsecond_(set) ((set)->e[1].p)
|
||||
|
||||
/*-<a href="qh-set_r.htm#TOC"
|
||||
>---------------------------------------</a><a name="SETsecondt_">-</a>
|
||||
|
||||
SETsecondt_(set, type)
|
||||
return second element of set as a type
|
||||
*/
|
||||
#define SETsecondt_(set, type) ((type *)((set)->e[1].p))
|
||||
|
||||
/*-<a href="qh-set_r.htm#TOC"
|
||||
>---------------------------------------</a><a name="SETaddr_">-</a>
|
||||
|
||||
SETaddr_(set, type)
|
||||
return address of set's elements
|
||||
*/
|
||||
#define SETaddr_(set,type) ((type **)(&((set)->e[0].p)))
|
||||
|
||||
/*-<a href="qh-set_r.htm#TOC"
|
||||
>---------------------------------------</a><a name="SETreturnsize_">-</a>
|
||||
|
||||
SETreturnsize_(set, size)
|
||||
return size of a set
|
||||
|
||||
notes:
|
||||
set must be defined
|
||||
use qh_setsize(qhT *qh, set) unless speed is critical
|
||||
*/
|
||||
#define SETreturnsize_(set, size) (((size)= ((set)->e[(set)->maxsize].i))?(--(size)):((size)= (set)->maxsize))
|
||||
|
||||
/*-<a href="qh-set_r.htm#TOC"
|
||||
>---------------------------------------</a><a name="SETempty_">-</a>
|
||||
|
||||
SETempty_(set)
|
||||
return true(1) if set is empty (i.e., FOREACHsetelement_ is empty)
|
||||
|
||||
notes:
|
||||
set may be NULL
|
||||
qh_setsize may be non-zero if first element is NULL
|
||||
*/
|
||||
#define SETempty_(set) (!set || (SETfirst_(set) ? 0 : 1))
|
||||
|
||||
/*-<a href="qh-set_r.htm#TOC"
|
||||
>-------------------------------<a name="SETsizeaddr_">-</a>
|
||||
|
||||
SETsizeaddr_(set)
|
||||
return pointer to 'actual size+1' of set (set CANNOT be NULL!!)
|
||||
Its type is setelemT* for strict aliasing
|
||||
All SETelemaddr_ must be cast to setelemT
|
||||
|
||||
|
||||
notes:
|
||||
*SETsizeaddr==NULL or e[*SETsizeaddr-1].p==NULL
|
||||
*/
|
||||
#define SETsizeaddr_(set) (&((set)->e[(set)->maxsize]))
|
||||
|
||||
/*-<a href="qh-set_r.htm#TOC"
|
||||
>---------------------------------------</a><a name="SETtruncate_">-</a>
|
||||
|
||||
SETtruncate_(set, size)
|
||||
truncate set to size
|
||||
|
||||
see:
|
||||
qh_settruncate()
|
||||
|
||||
*/
|
||||
#define SETtruncate_(set, size) {set->e[set->maxsize].i= size+1; /* maybe overwritten */ \
|
||||
set->e[size].p= NULL;}
|
||||
|
||||
/*======= prototypes in alphabetical order ============*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void qh_setaddsorted(qhT *qh, setT **setp, void *elem);
|
||||
void qh_setaddnth(qhT *qh, setT **setp, int nth, void *newelem);
|
||||
void qh_setappend(qhT *qh, setT **setp, void *elem);
|
||||
void qh_setappend_set(qhT *qh, setT **setp, setT *setA);
|
||||
void qh_setappend2ndlast(qhT *qh, setT **setp, void *elem);
|
||||
void qh_setcheck(qhT *qh, setT *set, const char *tname, unsigned int id);
|
||||
void qh_setcompact(qhT *qh, setT *set);
|
||||
setT *qh_setcopy(qhT *qh, setT *set, int extra);
|
||||
void *qh_setdel(setT *set, void *elem);
|
||||
void *qh_setdellast(setT *set);
|
||||
void *qh_setdelnth(qhT *qh, setT *set, int nth);
|
||||
void *qh_setdelnthsorted(qhT *qh, setT *set, int nth);
|
||||
void *qh_setdelsorted(setT *set, void *newelem);
|
||||
setT *qh_setduplicate(qhT *qh, setT *set, int elemsize);
|
||||
void **qh_setendpointer(setT *set);
|
||||
int qh_setequal(setT *setA, setT *setB);
|
||||
int qh_setequal_except(setT *setA, void *skipelemA, setT *setB, void *skipelemB);
|
||||
int qh_setequal_skip(setT *setA, int skipA, setT *setB, int skipB);
|
||||
void qh_setfree(qhT *qh, setT **set);
|
||||
void qh_setfree2(qhT *qh, setT **setp, int elemsize);
|
||||
void qh_setfreelong(qhT *qh, setT **set);
|
||||
int qh_setin(setT *set, void *setelem);
|
||||
int qh_setindex(setT *set, void *setelem);
|
||||
void qh_setlarger(qhT *qh, setT **setp);
|
||||
int qh_setlarger_quick(qhT *qh, int setsize, int *newsize);
|
||||
void *qh_setlast(setT *set);
|
||||
setT *qh_setnew(qhT *qh, int size);
|
||||
setT *qh_setnew_delnthsorted(qhT *qh, setT *set, int size, int nth, int prepend);
|
||||
void qh_setprint(qhT *qh, FILE *fp, const char* string, setT *set);
|
||||
void qh_setreplace(qhT *qh, setT *set, void *oldelem, void *newelem);
|
||||
int qh_setsize(qhT *qh, setT *set);
|
||||
setT *qh_settemp(qhT *qh, int setsize);
|
||||
void qh_settempfree(qhT *qh, setT **set);
|
||||
void qh_settempfree_all(qhT *qh);
|
||||
setT *qh_settemppop(qhT *qh);
|
||||
void qh_settemppush(qhT *qh, setT *set);
|
||||
void qh_settruncate(qhT *qh, setT *set, int size);
|
||||
int qh_setunique(qhT *qh, setT **set, void *elem);
|
||||
void qh_setzero(qhT *qh, setT *set, int idx, int size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* qhDEFset */
|
||||
@@ -0,0 +1,249 @@
|
||||
/*<html><pre> -<a href="index_r.htm#TOC"
|
||||
>-------------------------------</a><a name="TOP">-</a>
|
||||
|
||||
random_r.c and utilities
|
||||
Park & Miller's minimimal standard random number generator
|
||||
argc/argv conversion
|
||||
|
||||
Used by rbox. Do not use 'qh'
|
||||
*/
|
||||
|
||||
#include "libqhull_r.h"
|
||||
#include "random_r.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef _MSC_VER /* Microsoft Visual C++ -- warning level 4 */
|
||||
#pragma warning( disable : 4706) /* assignment within conditional function */
|
||||
#pragma warning( disable : 4996) /* function was declared deprecated(strcpy, localtime, etc.) */
|
||||
#endif
|
||||
|
||||
/*-<a href="qh-globa_r.htm#TOC"
|
||||
>-------------------------------</a><a name="argv_to_command">-</a>
|
||||
|
||||
qh_argv_to_command( argc, argv, command, max_size )
|
||||
|
||||
build command from argc/argv
|
||||
max_size is at least
|
||||
|
||||
returns:
|
||||
a space-delimited string of options (just as typed)
|
||||
returns false if max_size is too short
|
||||
|
||||
notes:
|
||||
silently removes
|
||||
makes option string easy to input and output
|
||||
matches qh_argv_to_command_size
|
||||
argc may be 0
|
||||
*/
|
||||
int qh_argv_to_command(int argc, char *argv[], char* command, int max_size) {
|
||||
int i, remaining;
|
||||
char *s;
|
||||
*command= '\0'; /* max_size > 0 */
|
||||
|
||||
if (argc) {
|
||||
if ((s= strrchr( argv[0], '\\')) /* get filename w/o .exe extension */
|
||||
|| (s= strrchr( argv[0], '/')))
|
||||
s++;
|
||||
else
|
||||
s= argv[0];
|
||||
if ((int)strlen(s) < max_size) /* WARN64 */
|
||||
strcpy(command, s);
|
||||
else
|
||||
goto error_argv;
|
||||
if ((s= strstr(command, ".EXE"))
|
||||
|| (s= strstr(command, ".exe")))
|
||||
*s= '\0';
|
||||
}
|
||||
for (i=1; i < argc; i++) {
|
||||
s= argv[i];
|
||||
remaining= max_size - (int)strlen(command) - (int)strlen(s) - 2; /* WARN64 */
|
||||
if (!*s || strchr(s, ' ')) {
|
||||
char *t= command + strlen(command);
|
||||
remaining -= 2;
|
||||
if (remaining < 0) {
|
||||
goto error_argv;
|
||||
}
|
||||
*t++= ' ';
|
||||
*t++= '"';
|
||||
while (*s) {
|
||||
if (*s == '"') {
|
||||
if (--remaining < 0)
|
||||
goto error_argv;
|
||||
*t++= '\\';
|
||||
}
|
||||
*t++= *s++;
|
||||
}
|
||||
*t++= '"';
|
||||
*t= '\0';
|
||||
}else if (remaining < 0) {
|
||||
goto error_argv;
|
||||
}else {
|
||||
strcat(command, " ");
|
||||
strcat(command, s);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
||||
error_argv:
|
||||
return 0;
|
||||
} /* argv_to_command */
|
||||
|
||||
/*-<a href="qh-globa_r.htm#TOC"
|
||||
>-------------------------------</a><a name="argv_to_command_size">-</a>
|
||||
|
||||
qh_argv_to_command_size( argc, argv )
|
||||
|
||||
return size to allocate for qh_argv_to_command()
|
||||
|
||||
notes:
|
||||
only called from rbox with qh_errexit not enabled
|
||||
caller should report error if returned size is less than 1
|
||||
argc may be 0
|
||||
actual size is usually shorter
|
||||
*/
|
||||
int qh_argv_to_command_size(int argc, char *argv[]) {
|
||||
int count= 1; /* null-terminator if argc==0 */
|
||||
int i;
|
||||
char *s;
|
||||
|
||||
for (i=0; i<argc; i++){
|
||||
count += (int)strlen(argv[i]) + 1; /* WARN64 */
|
||||
if (i>0 && strchr(argv[i], ' ')) {
|
||||
count += 2; /* quote delimiters */
|
||||
for (s=argv[i]; *s; s++) {
|
||||
if (*s == '"') {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
} /* argv_to_command_size */
|
||||
|
||||
/*-<a href="qh-geom_r.htm#TOC"
|
||||
>-------------------------------</a><a name="rand">-</a>
|
||||
|
||||
qh_rand()
|
||||
qh_srand(qh, seed )
|
||||
generate pseudo-random number between 1 and 2^31 -2
|
||||
|
||||
notes:
|
||||
For qhull and rbox, called from qh_RANDOMint(),etc. [user_r.h]
|
||||
|
||||
From Park & Miller's minimal standard random number generator
|
||||
Communications of the ACM, 31:1192-1201, 1988.
|
||||
Does not use 0 or 2^31 -1
|
||||
this is silently enforced by qh_srand()
|
||||
Can make 'Rn' much faster by moving qh_rand to qh_distplane
|
||||
*/
|
||||
|
||||
/* Global variables and constants */
|
||||
|
||||
#define qh_rand_a 16807
|
||||
#define qh_rand_m 2147483647
|
||||
#define qh_rand_q 127773 /* m div a */
|
||||
#define qh_rand_r 2836 /* m mod a */
|
||||
|
||||
int qh_rand(qhT *qh) {
|
||||
int lo, hi, test;
|
||||
int seed= qh->last_random;
|
||||
|
||||
hi= seed / qh_rand_q; /* seed div q */
|
||||
lo= seed % qh_rand_q; /* seed mod q */
|
||||
test= qh_rand_a * lo - qh_rand_r * hi;
|
||||
if (test > 0)
|
||||
seed= test;
|
||||
else
|
||||
seed= test + qh_rand_m;
|
||||
qh->last_random= seed;
|
||||
/* seed= seed < qh_RANDOMmax/2 ? 0 : qh_RANDOMmax; for testing */
|
||||
/* seed= qh_RANDOMmax; for testing */
|
||||
return seed;
|
||||
} /* rand */
|
||||
|
||||
void qh_srand(qhT *qh, int seed) {
|
||||
if (seed < 1)
|
||||
qh->last_random= 1;
|
||||
else if (seed >= qh_rand_m)
|
||||
qh->last_random= qh_rand_m - 1;
|
||||
else
|
||||
qh->last_random= seed;
|
||||
} /* qh_srand */
|
||||
|
||||
/*-<a href="qh-geom_r.htm#TOC"
|
||||
>-------------------------------</a><a name="randomfactor">-</a>
|
||||
|
||||
qh_randomfactor(qh, scale, offset )
|
||||
return a random factor r * scale + offset
|
||||
|
||||
notes:
|
||||
qh.RANDOMa/b are defined in global_r.c
|
||||
qh_RANDOMint requires 'qh'
|
||||
*/
|
||||
realT qh_randomfactor(qhT *qh, realT scale, realT offset) {
|
||||
realT randr;
|
||||
|
||||
randr= qh_RANDOMint;
|
||||
return randr * scale + offset;
|
||||
} /* randomfactor */
|
||||
|
||||
/*-<a href="qh-geom_r.htm#TOC"
|
||||
>-------------------------------</a><a name="randommatrix">-</a>
|
||||
|
||||
qh_randommatrix(qh, buffer, dim, rows )
|
||||
generate a random dim X dim matrix in range [-1,1]
|
||||
assumes buffer is [dim+1, dim]
|
||||
|
||||
returns:
|
||||
sets buffer to random numbers
|
||||
sets rows to rows of buffer
|
||||
sets row[dim] as scratch row
|
||||
|
||||
notes:
|
||||
qh_RANDOMint requires 'qh'
|
||||
*/
|
||||
void qh_randommatrix(qhT *qh, realT *buffer, int dim, realT **rows) {
|
||||
int i, k;
|
||||
realT **rowi, *coord, realr;
|
||||
|
||||
coord= buffer;
|
||||
rowi= rows;
|
||||
for (i=0; i < dim; i++) {
|
||||
*(rowi++)= coord;
|
||||
for (k=0; k < dim; k++) {
|
||||
realr= qh_RANDOMint;
|
||||
*(coord++)= 2.0 * realr/(qh_RANDOMmax+1) - 1.0;
|
||||
}
|
||||
}
|
||||
*rowi= coord;
|
||||
} /* randommatrix */
|
||||
|
||||
/*-<a href="qh-globa_r.htm#TOC"
|
||||
>-------------------------------</a><a name="strtol">-</a>
|
||||
|
||||
qh_strtol( s, endp) qh_strtod( s, endp)
|
||||
internal versions of strtol() and strtod()
|
||||
does not skip trailing spaces
|
||||
notes:
|
||||
some implementations of strtol()/strtod() skip trailing spaces
|
||||
*/
|
||||
double qh_strtod(const char *s, char **endp) {
|
||||
double result;
|
||||
|
||||
result= strtod(s, endp);
|
||||
if (s < (*endp) && (*endp)[-1] == ' ')
|
||||
(*endp)--;
|
||||
return result;
|
||||
} /* strtod */
|
||||
|
||||
int qh_strtol(const char *s, char **endp) {
|
||||
int result;
|
||||
|
||||
result= (int) strtol(s, endp, 10); /* WARN64 */
|
||||
if (s< (*endp) && (*endp)[-1] == ' ')
|
||||
(*endp)--;
|
||||
return result;
|
||||
} /* strtol */
|
||||
@@ -0,0 +1,41 @@
|
||||
/*<html><pre> -<a href="qh-geom_r.htm"
|
||||
>-------------------------------</a><a name="TOP">-</a>
|
||||
|
||||
random_r.h
|
||||
header file for random and utility routines
|
||||
|
||||
see qh-geom_r.htm and random_r.c
|
||||
|
||||
Copyright (c) 1993-2020 The Geometry Center.
|
||||
$Id: //main/2019/qhull/src/libqhull_r/random_r.h#3 $$Change: 2953 $
|
||||
$DateTime: 2020/05/21 22:05:32 $$Author: bbarber $
|
||||
*/
|
||||
|
||||
#ifndef qhDEFrandom
|
||||
#define qhDEFrandom 1
|
||||
|
||||
#include "libqhull_r.h"
|
||||
|
||||
/*============= prototypes in alphabetical order ======= */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int qh_argv_to_command(int argc, char *argv[], char* command, int max_size);
|
||||
int qh_argv_to_command_size(int argc, char *argv[]);
|
||||
int qh_rand(qhT *qh);
|
||||
void qh_srand(qhT *qh, int seed);
|
||||
realT qh_randomfactor(qhT *qh, realT scale, realT offset);
|
||||
void qh_randommatrix(qhT *qh, realT *buffer, int dim, realT **row);
|
||||
int qh_strtol(const char *s, char **endp);
|
||||
double qh_strtod(const char *s, char **endp);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* qhDEFrandom */
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,854 @@
|
||||
/*<html><pre> -<a href="index_r.htm#TOC"
|
||||
>-------------------------------</a><a name="TOP">-</a>
|
||||
|
||||
rboxlib_r.c
|
||||
Generate input points
|
||||
|
||||
notes:
|
||||
For documentation, see prompt[] of rbox_r.c
|
||||
50 points generated for 'rbox D4'
|
||||
|
||||
WARNING:
|
||||
incorrect range if qh_RANDOMmax is defined wrong (user_r.h)
|
||||
*/
|
||||
|
||||
#include "libqhull_r.h" /* First for user_r.h */
|
||||
#include "random_r.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <setjmp.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef _MSC_VER /* Microsoft Visual C++ */
|
||||
#pragma warning( disable : 4706) /* assignment within conditional expression. */
|
||||
#pragma warning( disable : 4996) /* this function (strncat,sprintf,strcpy) or variable may be unsafe. */
|
||||
#endif
|
||||
|
||||
#define MAXdim 200
|
||||
#define PI 3.1415926535897932384
|
||||
|
||||
/* ------------------------------ prototypes ----------------*/
|
||||
int qh_roundi(qhT *qh, double a);
|
||||
void qh_out1(qhT *qh, double a);
|
||||
void qh_out2n(qhT *qh, double a, double b);
|
||||
void qh_out3n(qhT *qh, double a, double b, double c);
|
||||
void qh_outcoord(qhT *qh, int iscdd, double *coord, int dim);
|
||||
void qh_outcoincident(qhT *qh, int coincidentpoints, double radius, int iscdd, double *coord, int dim);
|
||||
void qh_rboxpoints2(qhT *qh, char* rbox_command, double **simplex);
|
||||
|
||||
void qh_fprintf_rbox(qhT *qh, FILE *fp, int msgcode, const char *fmt, ... );
|
||||
void qh_free(void *mem);
|
||||
void *qh_malloc(size_t size);
|
||||
int qh_rand(qhT *qh);
|
||||
void qh_srand(qhT *qh, int seed);
|
||||
|
||||
/*-<a href="qh-qhull_r.htm#TOC"
|
||||
>-------------------------------</a><a name="rboxpoints">-</a>
|
||||
|
||||
qh_rboxpoints(qh, rbox_command )
|
||||
Generate points to qh.fout according to rbox options
|
||||
Report errors on qh.ferr
|
||||
|
||||
returns:
|
||||
0 (qh_ERRnone) on success
|
||||
1 (qh_ERRinput) on input error
|
||||
4 (qh_ERRmem) on memory error
|
||||
5 (qh_ERRqhull) on internal error
|
||||
|
||||
notes:
|
||||
To avoid using stdio, redefine qh_malloc, qh_free, and qh_fprintf_rbox (user_r.c)
|
||||
Split out qh_rboxpoints2() to avoid -Wclobbered
|
||||
|
||||
design:
|
||||
Straight line code (consider defining a struct and functions):
|
||||
|
||||
Parse arguments into variables
|
||||
Determine the number of points
|
||||
Generate the points
|
||||
*/
|
||||
int qh_rboxpoints(qhT *qh, char* rbox_command) {
|
||||
int exitcode;
|
||||
double *simplex;
|
||||
|
||||
simplex= NULL;
|
||||
exitcode= setjmp(qh->rbox_errexit);
|
||||
if (exitcode) {
|
||||
/* same code for error exit and normal return. qh.NOerrexit is set */
|
||||
if (simplex)
|
||||
qh_free(simplex);
|
||||
return exitcode;
|
||||
}
|
||||
qh_rboxpoints2(qh, rbox_command, &simplex);
|
||||
/* same code for error exit and normal return */
|
||||
if (simplex)
|
||||
qh_free(simplex);
|
||||
return qh_ERRnone;
|
||||
} /* rboxpoints */
|
||||
|
||||
void qh_rboxpoints2(qhT *qh, char* rbox_command, double **simplex) {
|
||||
int i,j,k;
|
||||
int gendim;
|
||||
int coincidentcount=0, coincidenttotal=0, coincidentpoints=0;
|
||||
int cubesize, diamondsize, seed=0, count, apex;
|
||||
int dim=3, numpoints=0, totpoints, addpoints=0;
|
||||
int issphere=0, isaxis=0, iscdd=0, islens=0, isregular=0, iswidth=0, addcube=0;
|
||||
int isgap=0, isspiral=0, NOcommand=0, adddiamond=0;
|
||||
int israndom=0, istime=0;
|
||||
int isbox=0, issimplex=0, issimplex2=0, ismesh=0;
|
||||
double width=0.0, gap=0.0, radius=0.0, coincidentradius=0.0;
|
||||
double coord[MAXdim], offset, meshm=3.0, meshn=4.0, meshr=5.0;
|
||||
double *coordp, *simplexp;
|
||||
int nthroot, mult[MAXdim];
|
||||
double norm, factor, randr, rangap, tempr, lensangle=0, lensbase=1;
|
||||
double anglediff, angle, x, y, cube=0.0, diamond=0.0;
|
||||
double box= qh_DEFAULTbox; /* scale all numbers before output */
|
||||
double randmax= qh_RANDOMmax;
|
||||
char command[250], seedbuf[50];
|
||||
char *s=command, *t, *first_point=NULL;
|
||||
time_t timedata;
|
||||
|
||||
*command= '\0';
|
||||
strncat(command, rbox_command, sizeof(command)-sizeof(seedbuf)-strlen(command)-1);
|
||||
|
||||
while (*s && !isspace(*s)) /* skip program name */
|
||||
s++;
|
||||
while (*s) {
|
||||
while (*s && isspace(*s))
|
||||
s++;
|
||||
if (*s == '-')
|
||||
s++;
|
||||
if (!*s)
|
||||
break;
|
||||
if (isdigit(*s)) {
|
||||
numpoints= qh_strtol(s, &s);
|
||||
continue;
|
||||
}
|
||||
/* ============= read flags =============== */
|
||||
switch (*s++) {
|
||||
case 'c':
|
||||
addcube= 1;
|
||||
t= s;
|
||||
while (isspace(*t))
|
||||
t++;
|
||||
if (*t == 'G')
|
||||
cube= qh_strtod(++t, &s);
|
||||
break;
|
||||
case 'd':
|
||||
adddiamond= 1;
|
||||
t= s;
|
||||
while (isspace(*t))
|
||||
t++;
|
||||
if (*t == 'G')
|
||||
diamond= qh_strtod(++t, &s);
|
||||
break;
|
||||
case 'h':
|
||||
iscdd= 1;
|
||||
break;
|
||||
case 'l':
|
||||
isspiral= 1;
|
||||
break;
|
||||
case 'n':
|
||||
NOcommand= 1;
|
||||
break;
|
||||
case 'r':
|
||||
isregular= 1;
|
||||
break;
|
||||
case 's':
|
||||
issphere= 1;
|
||||
break;
|
||||
case 't':
|
||||
istime= 1;
|
||||
if (isdigit(*s)) {
|
||||
seed= qh_strtol(s, &s);
|
||||
israndom= 0;
|
||||
}else
|
||||
israndom= 1;
|
||||
break;
|
||||
case 'x':
|
||||
issimplex= 1;
|
||||
break;
|
||||
case 'y':
|
||||
issimplex2= 1;
|
||||
break;
|
||||
case 'z':
|
||||
qh->rbox_isinteger= 1;
|
||||
break;
|
||||
case 'B':
|
||||
box= qh_strtod(s, &s);
|
||||
isbox= 1;
|
||||
break;
|
||||
case 'C':
|
||||
if (*s)
|
||||
coincidentpoints= qh_strtol(s, &s);
|
||||
if (*s == ',') {
|
||||
++s;
|
||||
coincidentradius= qh_strtod(s, &s);
|
||||
}
|
||||
if (*s == ',') {
|
||||
++s;
|
||||
coincidenttotal= qh_strtol(s, &s);
|
||||
}
|
||||
if (*s && !isspace(*s)) {
|
||||
qh_fprintf_rbox(qh, qh->ferr, 7080, "rbox error: arguments for 'Cn,r,m' are not 'int', 'float', and 'int'. Remaining string is '%s'\n", s);
|
||||
qh_errexit_rbox(qh, qh_ERRinput);
|
||||
}
|
||||
if (coincidentpoints==0){
|
||||
qh_fprintf_rbox(qh, qh->ferr, 6268, "rbox error: missing arguments for 'Cn,r,m' where n is the number of coincident points, r is the radius (default 0.0), and m is the number of points\n");
|
||||
qh_errexit_rbox(qh, qh_ERRinput);
|
||||
}
|
||||
if (coincidentpoints<0 || coincidenttotal<0 || coincidentradius<0.0){
|
||||
qh_fprintf_rbox(qh, qh->ferr, 6269, "rbox error: negative arguments for 'Cn,m,r' where n (%d) is the number of coincident points, m (%d) is the number of points, and r (%.2g) is the radius (default 0.0)\n", coincidentpoints, coincidenttotal, coincidentradius);
|
||||
qh_errexit_rbox(qh, qh_ERRinput);
|
||||
}
|
||||
break;
|
||||
case 'D':
|
||||
dim= qh_strtol(s, &s);
|
||||
if (dim < 1
|
||||
|| dim > MAXdim) {
|
||||
qh_fprintf_rbox(qh, qh->ferr, 6189, "rbox error: dimension, D%d, out of bounds (>=%d or <=0)\n", dim, MAXdim);
|
||||
qh_errexit_rbox(qh, qh_ERRinput);
|
||||
}
|
||||
break;
|
||||
case 'G':
|
||||
if (isdigit(*s))
|
||||
gap= qh_strtod(s, &s);
|
||||
else
|
||||
gap= 0.5;
|
||||
isgap= 1;
|
||||
break;
|
||||
case 'L':
|
||||
if (isdigit(*s))
|
||||
radius= qh_strtod(s, &s);
|
||||
else
|
||||
radius= 10;
|
||||
islens= 1;
|
||||
break;
|
||||
case 'M':
|
||||
ismesh= 1;
|
||||
if (*s)
|
||||
meshn= qh_strtod(s, &s);
|
||||
if (*s == ',') {
|
||||
++s;
|
||||
meshm= qh_strtod(s, &s);
|
||||
}else
|
||||
meshm= 0.0;
|
||||
if (*s == ',') {
|
||||
++s;
|
||||
meshr= qh_strtod(s, &s);
|
||||
}else
|
||||
meshr= sqrt(meshn*meshn + meshm*meshm);
|
||||
if (*s && !isspace(*s)) {
|
||||
qh_fprintf_rbox(qh, qh->ferr, 7069, "rbox warning: assuming 'M3,4,5' since mesh args are not integers or reals\n");
|
||||
meshn= 3.0, meshm=4.0, meshr=5.0;
|
||||
}
|
||||
break;
|
||||
case 'O':
|
||||
qh->rbox_out_offset= qh_strtod(s, &s);
|
||||
break;
|
||||
case 'P':
|
||||
if (!first_point)
|
||||
first_point= s - 1;
|
||||
addpoints++;
|
||||
while (*s && !isspace(*s)) /* read points later */
|
||||
s++;
|
||||
break;
|
||||
case 'W':
|
||||
width= qh_strtod(s, &s);
|
||||
iswidth= 1;
|
||||
break;
|
||||
case 'Z':
|
||||
if (isdigit(*s))
|
||||
radius= qh_strtod(s, &s);
|
||||
else
|
||||
radius= 1.0;
|
||||
isaxis= 1;
|
||||
break;
|
||||
default:
|
||||
qh_fprintf_rbox(qh, qh->ferr, 6352, "rbox error: unknown flag at '%s'.\nExecute 'rbox' without arguments for documentation.\n", s - 1);
|
||||
qh_errexit_rbox(qh, qh_ERRinput);
|
||||
}
|
||||
if (*s && !isspace(*s)) {
|
||||
qh_fprintf_rbox(qh, qh->ferr, 6353, "rbox error: missing space between flags at %s.\n", s);
|
||||
qh_errexit_rbox(qh, qh_ERRinput);
|
||||
}
|
||||
}
|
||||
|
||||
/* ============= defaults, constants, and sizes =============== */
|
||||
if (qh->rbox_isinteger && !isbox)
|
||||
box= qh_DEFAULTzbox;
|
||||
if (addcube) {
|
||||
tempr= floor(ldexp(1.0,dim)+0.5);
|
||||
cubesize= (int)tempr;
|
||||
if (cube == 0.0)
|
||||
cube= box;
|
||||
}else
|
||||
cubesize= 0;
|
||||
if (adddiamond) {
|
||||
diamondsize= 2*dim;
|
||||
if (diamond == 0.0)
|
||||
diamond= box;
|
||||
}else
|
||||
diamondsize= 0;
|
||||
if (islens) {
|
||||
if (isaxis) {
|
||||
qh_fprintf_rbox(qh, qh->ferr, 6190, "rbox error: can not combine 'Ln' with 'Zn'\n");
|
||||
qh_errexit_rbox(qh, qh_ERRinput);
|
||||
}
|
||||
if (radius <= 1.0) {
|
||||
qh_fprintf_rbox(qh, qh->ferr, 6191, "rbox error: lens radius %.2g should be greater than 1.0\n",
|
||||
radius);
|
||||
qh_errexit_rbox(qh, qh_ERRinput);
|
||||
}
|
||||
lensangle= asin(1.0/radius);
|
||||
lensbase= radius * cos(lensangle);
|
||||
}
|
||||
|
||||
if (!numpoints) {
|
||||
if (issimplex2)
|
||||
; /* ok */
|
||||
else if (isregular + issimplex + islens + issphere + isaxis + isspiral + iswidth + ismesh) {
|
||||
qh_fprintf_rbox(qh, qh->ferr, 6192, "rbox error: missing count\n");
|
||||
qh_errexit_rbox(qh, qh_ERRinput);
|
||||
}else if (adddiamond + addcube + addpoints)
|
||||
; /* ok */
|
||||
else {
|
||||
numpoints= 50; /* ./rbox D4 is the test case */
|
||||
issphere= 1;
|
||||
}
|
||||
}
|
||||
if ((issimplex + islens + isspiral + ismesh > 1)
|
||||
|| (issimplex + issphere + isspiral + ismesh > 1)) {
|
||||
qh_fprintf_rbox(qh, qh->ferr, 6193, "rbox error: can only specify one of 'l', 's', 'x', 'Ln', or 'Mn,m,r' ('Ln s' is ok).\n");
|
||||
qh_errexit_rbox(qh, qh_ERRinput);
|
||||
}
|
||||
if (coincidentpoints>0 && (numpoints == 0 || coincidenttotal > numpoints)) {
|
||||
qh_fprintf_rbox(qh, qh->ferr, 6270, "rbox error: 'Cn,r,m' requested n coincident points for each of m points. Either there is no points or m (%d) is greater than the number of points (%d).\n", coincidenttotal, numpoints);
|
||||
qh_errexit_rbox(qh, qh_ERRinput);
|
||||
}
|
||||
if (coincidentpoints > 0 && isregular) {
|
||||
qh_fprintf_rbox(qh, qh->ferr, 6423, "rbox error: 'Cn,r,m' is not implemented for regular points ('r')\n");
|
||||
qh_errexit_rbox(qh, qh_ERRinput);
|
||||
}
|
||||
|
||||
if (coincidenttotal == 0)
|
||||
coincidenttotal= numpoints;
|
||||
|
||||
/* ============= print header with total points =============== */
|
||||
if (issimplex || ismesh)
|
||||
totpoints= numpoints;
|
||||
else if (issimplex2)
|
||||
totpoints= numpoints+dim+1;
|
||||
else if (isregular) {
|
||||
totpoints= numpoints;
|
||||
if (dim == 2) {
|
||||
if (islens)
|
||||
totpoints += numpoints - 2;
|
||||
}else if (dim == 3) {
|
||||
if (islens)
|
||||
totpoints += 2 * numpoints;
|
||||
else if (isgap)
|
||||
totpoints += 1 + numpoints;
|
||||
else
|
||||
totpoints += 2;
|
||||
}
|
||||
}else
|
||||
totpoints= numpoints + isaxis;
|
||||
totpoints += cubesize + diamondsize + addpoints;
|
||||
totpoints += coincidentpoints*coincidenttotal;
|
||||
|
||||
/* ============= seed randoms =============== */
|
||||
if (istime == 0) {
|
||||
for (s=command; *s; s++) {
|
||||
if (issimplex2 && *s == 'y') /* make 'y' same seed as 'x' */
|
||||
i= 'x';
|
||||
else
|
||||
i= *s;
|
||||
seed= 11*seed + i;
|
||||
}
|
||||
}else if (israndom) {
|
||||
seed= (int)time(&timedata);
|
||||
sprintf(seedbuf, " t%d", seed); /* appends an extra t, not worth removing */
|
||||
strncat(command, seedbuf, sizeof(command) - strlen(command) - 1);
|
||||
t= strstr(command, " t ");
|
||||
if (t)
|
||||
strcpy(t+1, t+3); /* remove " t " */
|
||||
} /* else, seed explicitly set to n */
|
||||
qh_RANDOMseed_(qh, seed);
|
||||
|
||||
/* ============= print header =============== */
|
||||
|
||||
if (iscdd)
|
||||
qh_fprintf_rbox(qh, qh->fout, 9391, "%s\nbegin\n %d %d %s\n",
|
||||
NOcommand ? "" : command,
|
||||
totpoints, dim+1,
|
||||
qh->rbox_isinteger ? "integer" : "real");
|
||||
else if (NOcommand)
|
||||
qh_fprintf_rbox(qh, qh->fout, 9392, "%d\n%d\n", dim, totpoints);
|
||||
else
|
||||
/* qh_fprintf_rbox special cases 9393 to append 'command' to the RboxPoints.comment() */
|
||||
qh_fprintf_rbox(qh, qh->fout, 9393, "%d %s\n%d\n", dim, command, totpoints);
|
||||
|
||||
/* ============= explicit points =============== */
|
||||
if ((s= first_point)) {
|
||||
while (s && *s) { /* 'P' */
|
||||
count= 0;
|
||||
if (iscdd)
|
||||
qh_out1(qh, 1.0);
|
||||
while (*++s) {
|
||||
qh_out1(qh, qh_strtod(s, &s));
|
||||
count++;
|
||||
if (isspace(*s) || !*s)
|
||||
break;
|
||||
if (*s != ',') {
|
||||
qh_fprintf_rbox(qh, qh->ferr, 6194, "rbox error: missing comma after coordinate in %s\n\n", s);
|
||||
qh_errexit_rbox(qh, qh_ERRinput);
|
||||
}
|
||||
}
|
||||
if (count < dim) {
|
||||
for (k=dim-count; k--; )
|
||||
qh_out1(qh, 0.0);
|
||||
}else if (count > dim) {
|
||||
qh_fprintf_rbox(qh, qh->ferr, 6195, "rbox error: %d coordinates instead of %d coordinates in %s\n\n",
|
||||
count, dim, s);
|
||||
qh_errexit_rbox(qh, qh_ERRinput);
|
||||
}
|
||||
qh_fprintf_rbox(qh, qh->fout, 9394, "\n");
|
||||
while ((s= strchr(s, 'P'))) {
|
||||
if (isspace(s[-1]))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ============= simplex distribution =============== */
|
||||
if (issimplex+issimplex2) {
|
||||
if (!(*simplex= (double *)qh_malloc( (size_t)(dim * (dim+1)) * sizeof(double)))) {
|
||||
qh_fprintf_rbox(qh, qh->ferr, 6196, "rbox error: insufficient memory for simplex\n");
|
||||
qh_errexit_rbox(qh, qh_ERRmem); /* qh_ERRmem */
|
||||
}
|
||||
simplexp= *simplex;
|
||||
if (isregular) {
|
||||
for (i=0; i<dim; i++) {
|
||||
for (k=0; k<dim; k++)
|
||||
*(simplexp++)= i==k ? 1.0 : 0.0;
|
||||
}
|
||||
for (k=0; k<dim; k++)
|
||||
*(simplexp++)= -1.0;
|
||||
}else {
|
||||
for (i=0; i<dim+1; i++) {
|
||||
for (k=0; k<dim; k++) {
|
||||
randr= qh_RANDOMint;
|
||||
*(simplexp++)= 2.0 * randr/randmax - 1.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (issimplex2) {
|
||||
simplexp= *simplex;
|
||||
for (i=0; i<dim+1; i++) {
|
||||
if (iscdd)
|
||||
qh_out1(qh, 1.0);
|
||||
for (k=0; k<dim; k++)
|
||||
qh_out1(qh, *(simplexp++) * box);
|
||||
qh_fprintf_rbox(qh, qh->fout, 9395, "\n");
|
||||
}
|
||||
}
|
||||
for (j=0; j<numpoints; j++) {
|
||||
if (iswidth)
|
||||
apex= qh_RANDOMint % (dim+1);
|
||||
else
|
||||
apex= -1;
|
||||
for (k=0; k<dim; k++)
|
||||
coord[k]= 0.0;
|
||||
norm= 0.0;
|
||||
for (i=0; i<dim+1; i++) {
|
||||
randr= qh_RANDOMint;
|
||||
factor= randr/randmax;
|
||||
if (i == apex)
|
||||
factor *= width;
|
||||
norm += factor;
|
||||
for (k=0; k<dim; k++) {
|
||||
simplexp= *simplex + i*dim + k;
|
||||
coord[k] += factor * (*simplexp);
|
||||
}
|
||||
}
|
||||
for (k=0; k<dim; k++)
|
||||
coord[k] *= box/norm;
|
||||
qh_outcoord(qh, iscdd, coord, dim);
|
||||
if(coincidentcount++ < coincidenttotal)
|
||||
qh_outcoincident(qh, coincidentpoints, coincidentradius, iscdd, coord, dim);
|
||||
}
|
||||
isregular= 0; /* continue with isbox */
|
||||
numpoints= 0;
|
||||
}
|
||||
|
||||
/* ============= mesh distribution =============== */
|
||||
if (ismesh) {
|
||||
nthroot= (int)(pow((double)numpoints, 1.0/dim) + 0.99999);
|
||||
for (k=dim; k--; )
|
||||
mult[k]= 0;
|
||||
for (i=0; i < numpoints; i++) {
|
||||
coordp= coord;
|
||||
for (k=0; k < dim; k++) {
|
||||
if (k == 0)
|
||||
*(coordp++)= mult[0] * meshn + mult[1] * (-meshm);
|
||||
else if (k == 1)
|
||||
*(coordp++)= mult[0] * meshm + mult[1] * meshn;
|
||||
else
|
||||
*(coordp++)= mult[k] * meshr;
|
||||
}
|
||||
qh_outcoord(qh, iscdd, coord, dim);
|
||||
if(coincidentcount++ < coincidenttotal)
|
||||
qh_outcoincident(qh, coincidentpoints, coincidentradius, iscdd, coord, dim);
|
||||
for (k=0; k < dim; k++) {
|
||||
if (++mult[k] < nthroot)
|
||||
break;
|
||||
mult[k]= 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* ============= regular points for 's' =============== */
|
||||
else if (isregular && !islens) {
|
||||
if (dim != 2 && dim != 3) {
|
||||
qh_fprintf_rbox(qh, qh->ferr, 6197, "rbox error: regular points can be used only in 2-d and 3-d\n\n");
|
||||
qh_errexit_rbox(qh, qh_ERRinput);
|
||||
}
|
||||
if (!isaxis || radius == 0.0) {
|
||||
isaxis= 1;
|
||||
radius= 1.0;
|
||||
}
|
||||
if (dim == 3) {
|
||||
if (iscdd)
|
||||
qh_out1(qh, 1.0);
|
||||
qh_out3n(qh, 0.0, 0.0, -box);
|
||||
if (!isgap) {
|
||||
if (iscdd)
|
||||
qh_out1(qh, 1.0);
|
||||
qh_out3n(qh, 0.0, 0.0, box);
|
||||
}
|
||||
}
|
||||
angle= 0.0;
|
||||
anglediff= 2.0 * PI/numpoints;
|
||||
for (i=0; i < numpoints; i++) {
|
||||
angle += anglediff;
|
||||
x= radius * cos(angle);
|
||||
y= radius * sin(angle);
|
||||
if (dim == 2) {
|
||||
if (iscdd)
|
||||
qh_out1(qh, 1.0);
|
||||
qh_out2n(qh, x*box, y*box);
|
||||
}else {
|
||||
norm= sqrt(1.0 + x*x + y*y);
|
||||
if (iscdd)
|
||||
qh_out1(qh, 1.0);
|
||||
qh_out3n(qh, box*x/norm, box*y/norm, box/norm);
|
||||
if (isgap) {
|
||||
x *= 1-gap;
|
||||
y *= 1-gap;
|
||||
norm= sqrt(1.0 + x*x + y*y);
|
||||
if (iscdd)
|
||||
qh_out1(qh, 1.0);
|
||||
qh_out3n(qh, box*x/norm, box*y/norm, box/norm);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* ============= regular points for 'r Ln D2' =============== */
|
||||
else if (isregular && islens && dim == 2) {
|
||||
double cos_0;
|
||||
|
||||
angle= lensangle;
|
||||
anglediff= 2 * lensangle/(numpoints - 1);
|
||||
cos_0= cos(lensangle);
|
||||
for (i=0; i < numpoints; i++, angle -= anglediff) {
|
||||
x= radius * sin(angle);
|
||||
y= radius * (cos(angle) - cos_0);
|
||||
if (iscdd)
|
||||
qh_out1(qh, 1.0);
|
||||
qh_out2n(qh, x*box, y*box);
|
||||
if (i != 0 && i != numpoints - 1) {
|
||||
if (iscdd)
|
||||
qh_out1(qh, 1.0);
|
||||
qh_out2n(qh, x*box, -y*box);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* ============= regular points for 'r Ln D3' =============== */
|
||||
else if (isregular && islens && dim != 2) {
|
||||
if (dim != 3) {
|
||||
qh_fprintf_rbox(qh, qh->ferr, 6198, "rbox error: regular points can be used only in 2-d and 3-d\n\n");
|
||||
qh_errexit_rbox(qh, qh_ERRinput);
|
||||
}
|
||||
angle= 0.0;
|
||||
anglediff= 2* PI/numpoints;
|
||||
if (!isgap) {
|
||||
isgap= 1;
|
||||
gap= 0.5;
|
||||
}
|
||||
offset= sqrt(radius * radius - (1-gap)*(1-gap)) - lensbase;
|
||||
for (i=0; i < numpoints; i++, angle += anglediff) {
|
||||
x= cos(angle);
|
||||
y= sin(angle);
|
||||
if (iscdd)
|
||||
qh_out1(qh, 1.0);
|
||||
qh_out3n(qh, box*x, box*y, 0.0);
|
||||
x *= 1-gap;
|
||||
y *= 1-gap;
|
||||
if (iscdd)
|
||||
qh_out1(qh, 1.0);
|
||||
qh_out3n(qh, box*x, box*y, box * offset);
|
||||
if (iscdd)
|
||||
qh_out1(qh, 1.0);
|
||||
qh_out3n(qh, box*x, box*y, -box * offset);
|
||||
}
|
||||
}
|
||||
/* ============= apex of 'Zn' distribution + gendim =============== */
|
||||
else {
|
||||
if (isaxis) {
|
||||
gendim= dim-1;
|
||||
if (iscdd)
|
||||
qh_out1(qh, 1.0);
|
||||
for (j=0; j < gendim; j++)
|
||||
qh_out1(qh, 0.0);
|
||||
qh_out1(qh, -box);
|
||||
qh_fprintf_rbox(qh, qh->fout, 9398, "\n");
|
||||
}else if (islens)
|
||||
gendim= dim-1;
|
||||
else
|
||||
gendim= dim;
|
||||
/* ============= generate random point in unit cube =============== */
|
||||
for (i=0; i < numpoints; i++) {
|
||||
norm= 0.0;
|
||||
for (j=0; j < gendim; j++) {
|
||||
randr= qh_RANDOMint;
|
||||
coord[j]= 2.0 * randr/randmax - 1.0;
|
||||
norm += coord[j] * coord[j];
|
||||
}
|
||||
norm= sqrt(norm);
|
||||
/* ============= dim-1 point of 'Zn' distribution ========== */
|
||||
if (isaxis) {
|
||||
if (!isgap) {
|
||||
isgap= 1;
|
||||
gap= 1.0;
|
||||
}
|
||||
randr= qh_RANDOMint;
|
||||
rangap= 1.0 - gap * randr/randmax;
|
||||
factor= radius * rangap / norm;
|
||||
for (j=0; j<gendim; j++)
|
||||
coord[j]= factor * coord[j];
|
||||
/* ============= dim-1 point of 'Ln s' distribution =========== */
|
||||
}else if (islens && issphere) {
|
||||
if (!isgap) {
|
||||
isgap= 1;
|
||||
gap= 1.0;
|
||||
}
|
||||
randr= qh_RANDOMint;
|
||||
rangap= 1.0 - gap * randr/randmax;
|
||||
factor= rangap / norm;
|
||||
for (j=0; j<gendim; j++)
|
||||
coord[j]= factor * coord[j];
|
||||
/* ============= dim-1 point of 'Ln' distribution ========== */
|
||||
}else if (islens && !issphere) {
|
||||
if (!isgap) {
|
||||
isgap= 1;
|
||||
gap= 1.0;
|
||||
}
|
||||
j= qh_RANDOMint % gendim;
|
||||
if (coord[j] < 0)
|
||||
coord[j]= -1.0 - coord[j] * gap;
|
||||
else
|
||||
coord[j]= 1.0 - coord[j] * gap;
|
||||
/* ============= point of 'l' distribution =============== */
|
||||
}else if (isspiral) {
|
||||
if (dim != 3) {
|
||||
qh_fprintf_rbox(qh, qh->ferr, 6199, "rbox error: spiral distribution is available only in 3d\n\n");
|
||||
qh_errexit_rbox(qh, qh_ERRinput);
|
||||
}
|
||||
coord[0]= cos(2*PI*i/(numpoints - 1));
|
||||
coord[1]= sin(2*PI*i/(numpoints - 1));
|
||||
coord[2]= 2.0*(double)i/(double)(numpoints - 1) - 1.0;
|
||||
/* ============= point of 's' distribution =============== */
|
||||
}else if (issphere) {
|
||||
factor= 1.0/norm;
|
||||
if (iswidth) {
|
||||
randr= qh_RANDOMint;
|
||||
factor *= 1.0 - width * randr/randmax;
|
||||
}
|
||||
for (j=0; j<dim; j++)
|
||||
coord[j]= factor * coord[j];
|
||||
}
|
||||
/* ============= project 'Zn s' point in to sphere =============== */
|
||||
if (isaxis && issphere) {
|
||||
coord[dim-1]= 1.0;
|
||||
norm= 1.0;
|
||||
for (j=0; j<gendim; j++)
|
||||
norm += coord[j] * coord[j];
|
||||
norm= sqrt(norm);
|
||||
for (j=0; j<dim; j++)
|
||||
coord[j]= coord[j] / norm;
|
||||
if (iswidth) {
|
||||
randr= qh_RANDOMint;
|
||||
coord[dim-1] *= 1 - width * randr/randmax;
|
||||
}
|
||||
/* ============= project 'Zn' point onto cube =============== */
|
||||
}else if (isaxis && !issphere) { /* not very interesting */
|
||||
randr= qh_RANDOMint;
|
||||
coord[dim-1]= 2.0 * randr/randmax - 1.0;
|
||||
/* ============= project 'Ln' point out to sphere =============== */
|
||||
}else if (islens) {
|
||||
coord[dim-1]= lensbase;
|
||||
for (j=0, norm= 0; j<dim; j++)
|
||||
norm += coord[j] * coord[j];
|
||||
norm= sqrt(norm);
|
||||
for (j=0; j<dim; j++)
|
||||
coord[j]= coord[j] * radius/ norm;
|
||||
coord[dim-1] -= lensbase;
|
||||
if (iswidth) {
|
||||
randr= qh_RANDOMint;
|
||||
coord[dim-1] *= 1 - width * randr/randmax;
|
||||
}
|
||||
if (qh_RANDOMint > randmax/2)
|
||||
coord[dim-1]= -coord[dim-1];
|
||||
/* ============= project 'Wn' point toward boundary =============== */
|
||||
}else if (iswidth && !issphere) {
|
||||
j= qh_RANDOMint % gendim;
|
||||
if (coord[j] < 0)
|
||||
coord[j]= -1.0 - coord[j] * width;
|
||||
else
|
||||
coord[j]= 1.0 - coord[j] * width;
|
||||
}
|
||||
/* ============= scale point to box =============== */
|
||||
for (k=0; k<dim; k++)
|
||||
coord[k]= coord[k] * box;
|
||||
|
||||
/* ============= write output =============== */
|
||||
qh_outcoord(qh, iscdd, coord, dim);
|
||||
if(coincidentcount++ < coincidenttotal)
|
||||
qh_outcoincident(qh, coincidentpoints, coincidentradius, iscdd, coord, dim);
|
||||
}
|
||||
}
|
||||
|
||||
/* ============= write cube vertices =============== */
|
||||
if (addcube) {
|
||||
for (j=0; j<cubesize; j++) {
|
||||
if (iscdd)
|
||||
qh_out1(qh, 1.0);
|
||||
for (k=dim-1; k>=0; k--) {
|
||||
if (j & ( 1 << k))
|
||||
qh_out1(qh, cube);
|
||||
else
|
||||
qh_out1(qh, -cube);
|
||||
}
|
||||
qh_fprintf_rbox(qh, qh->fout, 9400, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* ============= write diamond vertices =============== */
|
||||
if (adddiamond) {
|
||||
for (j=0; j<diamondsize; j++) {
|
||||
if (iscdd)
|
||||
qh_out1(qh, 1.0);
|
||||
for (k=dim-1; k>=0; k--) {
|
||||
if (j/2 != k)
|
||||
qh_out1(qh, 0.0);
|
||||
else if (j & 0x1)
|
||||
qh_out1(qh, diamond);
|
||||
else
|
||||
qh_out1(qh, -diamond);
|
||||
}
|
||||
qh_fprintf_rbox(qh, qh->fout, 9401, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (iscdd)
|
||||
qh_fprintf_rbox(qh, qh->fout, 9402, "end\nhull\n");
|
||||
} /* rboxpoints2 */
|
||||
|
||||
/*------------------------------------------------
|
||||
outxxx - output functions for qh_rboxpoints
|
||||
*/
|
||||
int qh_roundi(qhT *qh, double a) {
|
||||
if (a < 0.0) {
|
||||
if (a - 0.5 < INT_MIN) {
|
||||
qh_fprintf_rbox(qh, qh->ferr, 6200, "rbox input error: negative coordinate %2.2g is too large. Reduce 'Bn'\n", a);
|
||||
qh_errexit_rbox(qh, qh_ERRinput);
|
||||
}
|
||||
return (int)(a - 0.5);
|
||||
}else {
|
||||
if (a + 0.5 > INT_MAX) {
|
||||
qh_fprintf_rbox(qh, qh->ferr, 6201, "rbox input error: coordinate %2.2g is too large. Reduce 'Bn'\n", a);
|
||||
qh_errexit_rbox(qh, qh_ERRinput);
|
||||
}
|
||||
return (int)(a + 0.5);
|
||||
}
|
||||
} /* qh_roundi */
|
||||
|
||||
void qh_out1(qhT *qh, double a) {
|
||||
|
||||
if (qh->rbox_isinteger)
|
||||
qh_fprintf_rbox(qh, qh->fout, 9403, "%d ", qh_roundi(qh, a+qh->rbox_out_offset));
|
||||
else
|
||||
qh_fprintf_rbox(qh, qh->fout, 9404, qh_REAL_1, a+qh->rbox_out_offset);
|
||||
} /* qh_out1 */
|
||||
|
||||
void qh_out2n(qhT *qh, double a, double b) {
|
||||
|
||||
if (qh->rbox_isinteger)
|
||||
qh_fprintf_rbox(qh, qh->fout, 9405, "%d %d\n", qh_roundi(qh, a+qh->rbox_out_offset), qh_roundi(qh, b+qh->rbox_out_offset));
|
||||
else
|
||||
qh_fprintf_rbox(qh, qh->fout, 9406, qh_REAL_2n, a+qh->rbox_out_offset, b+qh->rbox_out_offset);
|
||||
} /* qh_out2n */
|
||||
|
||||
void qh_out3n(qhT *qh, double a, double b, double c) {
|
||||
|
||||
if (qh->rbox_isinteger)
|
||||
qh_fprintf_rbox(qh, qh->fout, 9407, "%d %d %d\n", qh_roundi(qh, a+qh->rbox_out_offset), qh_roundi(qh, b+qh->rbox_out_offset), qh_roundi(qh, c+qh->rbox_out_offset));
|
||||
else
|
||||
qh_fprintf_rbox(qh, qh->fout, 9408, qh_REAL_3n, a+qh->rbox_out_offset, b+qh->rbox_out_offset, c+qh->rbox_out_offset);
|
||||
} /* qh_out3n */
|
||||
|
||||
void qh_outcoord(qhT *qh, int iscdd, double *coord, int dim) {
|
||||
double *p= coord;
|
||||
int k;
|
||||
|
||||
if (iscdd)
|
||||
qh_out1(qh, 1.0);
|
||||
for (k=0; k < dim; k++)
|
||||
qh_out1(qh, *(p++));
|
||||
qh_fprintf_rbox(qh, qh->fout, 9396, "\n");
|
||||
} /* qh_outcoord */
|
||||
|
||||
void qh_outcoincident(qhT *qh, int coincidentpoints, double radius, int iscdd, double *coord, int dim) {
|
||||
double *p;
|
||||
double randr, delta;
|
||||
int i,k;
|
||||
double randmax= qh_RANDOMmax;
|
||||
|
||||
for (i=0; i<coincidentpoints; i++) {
|
||||
p= coord;
|
||||
if (iscdd)
|
||||
qh_out1(qh, 1.0);
|
||||
for (k=0; k < dim; k++) {
|
||||
randr= qh_RANDOMint;
|
||||
delta= 2.0 * randr/randmax - 1.0; /* -1..+1 */
|
||||
delta *= radius;
|
||||
qh_out1(qh, *(p++) + delta);
|
||||
}
|
||||
qh_fprintf_rbox(qh, qh->fout, 9410, "\n");
|
||||
}
|
||||
} /* qh_outcoincident */
|
||||
|
||||
/*------------------------------------------------
|
||||
Only called from qh_rboxpoints2 or qh_fprintf_rbox
|
||||
qh_fprintf_rbox is only called from qh_rboxpoints2
|
||||
The largest exitcode is '255' for compatibility with exit()
|
||||
*/
|
||||
void qh_errexit_rbox(qhT *qh, int exitcode)
|
||||
{
|
||||
longjmp(qh->rbox_errexit, exitcode);
|
||||
} /* qh_errexit_rbox */
|
||||
|
||||
@@ -0,0 +1,727 @@
|
||||
/*<html><pre> -<a href="qh-stat_r.htm"
|
||||
>-------------------------------</a><a name="TOP">-</a>
|
||||
|
||||
stat_r.c
|
||||
contains all statistics that are collected for qhull
|
||||
|
||||
see qh-stat_r.htm and stat_r.h
|
||||
|
||||
Copyright (c) 1993-2020 The Geometry Center.
|
||||
$Id: //main/2019/qhull/src/libqhull_r/stat_r.c#9 $$Change: 3037 $
|
||||
$DateTime: 2020/09/03 17:28:32 $$Author: bbarber $
|
||||
*/
|
||||
|
||||
#include "qhull_ra.h"
|
||||
|
||||
/*========== functions in alphabetic order ================*/
|
||||
|
||||
/*-<a href="qh-stat_r.htm#TOC"
|
||||
>-------------------------------</a><a name="allstatA">-</a>
|
||||
|
||||
qh_allstatA()
|
||||
define statistics in groups of 20
|
||||
|
||||
notes:
|
||||
(otherwise, 'gcc -O2' uses too much memory)
|
||||
uses qhstat.next
|
||||
*/
|
||||
void qh_allstatA(qhT *qh) {
|
||||
|
||||
/* zdef_(type,name,doc,average) */
|
||||
zzdef_(zdoc, Zdoc2, "precision statistics", -1);
|
||||
zdef_(zinc, Znewvertex, NULL, -1);
|
||||
zdef_(wadd, Wnewvertex, "ave. distance of a new vertex to a facet", Znewvertex);
|
||||
zzdef_(wmax, Wnewvertexmax, "max. distance of a new vertex to a facet", -1);
|
||||
zdef_(wmax, Wvertexmax, "max. distance of an output vertex to a facet", -1);
|
||||
zdef_(wmin, Wvertexmin, "min. distance of an output vertex to a facet", -1);
|
||||
zdef_(wmin, Wmindenom, "min. denominator in hyperplane computation", -1);
|
||||
|
||||
qh->qhstat.precision= qh->qhstat.next; /* usually call qh_joggle_restart, printed if Q0 or QJn */
|
||||
zzdef_(zdoc, Zdoc3, "precision problems (corrected unless 'Q0' or an error)", -1);
|
||||
zzdef_(zinc, Zcoplanarridges, "coplanar half ridges in output", -1);
|
||||
zzdef_(zinc, Zconcaveridges, "concave half ridges in output", -1);
|
||||
zzdef_(zinc, Zflippedfacets, "flipped facets", -1);
|
||||
zzdef_(zinc, Zcoplanarhorizon, "coplanar horizon facets for new vertices", -1);
|
||||
zzdef_(zinc, Zcoplanarpart, "coplanar points during partitioning", -1);
|
||||
zzdef_(zinc, Zminnorm, "degenerate hyperplanes recomputed with gaussian elimination", -1);
|
||||
zzdef_(zinc, Znearlysingular, "nearly singular or axis-parallel hyperplanes", -1);
|
||||
zzdef_(zinc, Zback0, "zero divisors during back substitute", -1);
|
||||
zzdef_(zinc, Zgauss0, "zero divisors during gaussian elimination", -1);
|
||||
zzdef_(zinc, Zmultiridge, "dupridges with multiple neighbors", -1);
|
||||
zzdef_(zinc, Zflipridge, "dupridges with flip facet into good neighbor", -1);
|
||||
zzdef_(zinc, Zflipridge2, "dupridges with flip facet into good flip neighbor", -1);
|
||||
}
|
||||
void qh_allstatB(qhT *qh) {
|
||||
zzdef_(zdoc, Zdoc1, "summary information", -1);
|
||||
zdef_(zinc, Zvertices, "number of vertices in output", -1);
|
||||
zdef_(zinc, Znumfacets, "number of facets in output", -1);
|
||||
zdef_(zinc, Znonsimplicial, "number of non-simplicial facets in output", -1);
|
||||
zdef_(zinc, Znowsimplicial, "simplicial facets that were non-simplicial", -1);
|
||||
zdef_(zinc, Znumridges, "number of ridges in output", -1);
|
||||
zdef_(zadd, Znumridges, "average number of ridges per facet", Znumfacets);
|
||||
zdef_(zmax, Zmaxridges, "maximum number of ridges", -1);
|
||||
zdef_(zadd, Znumneighbors, "average number of neighbors per facet", Znumfacets);
|
||||
zdef_(zmax, Zmaxneighbors, "maximum number of neighbors", -1);
|
||||
zdef_(zadd, Znumvertices, "average number of vertices per facet", Znumfacets);
|
||||
zdef_(zmax, Zmaxvertices, "maximum number of vertices", -1);
|
||||
zdef_(zadd, Znumvneighbors, "average number of neighbors per vertex", Zvertices);
|
||||
zdef_(zmax, Zmaxvneighbors, "maximum number of neighbors", -1);
|
||||
zdef_(wadd, Wcpu, "cpu seconds for qhull after input", -1);
|
||||
zdef_(zinc, Ztotvertices, "vertices created altogether", -1);
|
||||
zzdef_(zinc, Zsetplane, "facets created altogether", -1);
|
||||
zdef_(zinc, Ztotridges, "ridges created altogether", -1);
|
||||
zdef_(zinc, Zpostfacets, "facets before post merge", -1);
|
||||
zdef_(zadd, Znummergetot, "average merges per facet (at most 511)", Znumfacets);
|
||||
zdef_(zmax, Znummergemax, " maximum merges for a facet (at most 511)", -1);
|
||||
zdef_(zinc, Zangle, NULL, -1);
|
||||
zdef_(wadd, Wangle, "average cosine (angle) of facet normals for all ridges", Zangle);
|
||||
zdef_(wmax, Wanglemax, " maximum cosine of facet normals (flatest) across a ridge", -1);
|
||||
zdef_(wmin, Wanglemin, " minimum cosine of facet normals (sharpest) across a ridge", -1);
|
||||
zdef_(wadd, Wareatot, "total area of facets", -1);
|
||||
zdef_(wmax, Wareamax, " maximum facet area", -1);
|
||||
zdef_(wmin, Wareamin, " minimum facet area", -1);
|
||||
}
|
||||
void qh_allstatC(qhT *qh) {
|
||||
zdef_(zdoc, Zdoc9, "build hull statistics", -1);
|
||||
zzdef_(zinc, Zprocessed, "points processed", -1);
|
||||
zzdef_(zinc, Zretry, "retries due to precision problems", -1);
|
||||
zdef_(wmax, Wretrymax, " max. random joggle", -1);
|
||||
zdef_(zmax, Zmaxvertex, "max. vertices at any one time", -1);
|
||||
zdef_(zinc, Ztotvisible, "ave. visible facets per iteration", Zprocessed);
|
||||
zdef_(zinc, Zinsidevisible, " ave. visible facets without an horizon neighbor", Zprocessed);
|
||||
zdef_(zadd, Zvisfacettot, " ave. facets deleted per iteration", Zprocessed);
|
||||
zdef_(zmax, Zvisfacetmax, " maximum", -1);
|
||||
zdef_(zadd, Zvisvertextot, "ave. visible vertices per iteration", Zprocessed);
|
||||
zdef_(zmax, Zvisvertexmax, " maximum", -1);
|
||||
zdef_(zinc, Ztothorizon, "ave. horizon facets per iteration", Zprocessed);
|
||||
zdef_(zadd, Znewfacettot, "ave. new or merged facets per iteration", Zprocessed);
|
||||
zdef_(zmax, Znewfacetmax, " maximum (includes initial simplex)", -1);
|
||||
zdef_(wadd, Wnewbalance, "average new facet balance", Zprocessed);
|
||||
zdef_(wadd, Wnewbalance2, " standard deviation", -1);
|
||||
zdef_(wadd, Wpbalance, "average partition balance", Zpbalance);
|
||||
zdef_(wadd, Wpbalance2, " standard deviation", -1);
|
||||
zdef_(zinc, Zpbalance, " count", -1);
|
||||
zdef_(zinc, Zsearchpoints, "searches of all points for initial simplex", -1);
|
||||
zdef_(zinc, Zdetfacetarea, "determinants for facet area", -1);
|
||||
zdef_(zinc, Znoarea, " determinants not computed because vertex too low", -1);
|
||||
zdef_(zinc, Zdetsimplex, "determinants for initial hull or voronoi vertices", -1);
|
||||
zdef_(zinc, Znotmax, "points ignored (!above max_outside)", -1);
|
||||
zdef_(zinc, Zpinchedapex, "points ignored (pinched apex)", -1);
|
||||
zdef_(zinc, Znotgood, "points ignored (!above a good facet)", -1);
|
||||
zdef_(zinc, Znotgoodnew, "points ignored (didn't create a good new facet)", -1);
|
||||
zdef_(zinc, Zgoodfacet, "good facets found", -1);
|
||||
zzdef_(zinc, Znumvisibility, "distance tests for facet visibility", -1);
|
||||
zdef_(zinc, Zdistvertex, "distance tests to report minimum vertex", -1);
|
||||
zzdef_(zinc, Ztotcheck, "points checked for facets' outer planes", -1);
|
||||
zzdef_(zinc, Zcheckpart, " ave. distance tests per check", Ztotcheck);
|
||||
}
|
||||
void qh_allstatD(qhT *qh) {
|
||||
zdef_(zinc, Zvisit, "resets of visit_id", -1);
|
||||
zdef_(zinc, Zvvisit, " resets of vertex_visit", -1);
|
||||
zdef_(zmax, Zvisit2max, " max visit_id/2", -1);
|
||||
zdef_(zmax, Zvvisit2max, " max vertex_visit/2", -1);
|
||||
|
||||
zdef_(zdoc, Zdoc4, "partitioning statistics (see previous for outer planes)", -1);
|
||||
zzdef_(zadd, Zdelvertextot, "total vertices deleted", -1);
|
||||
zdef_(zmax, Zdelvertexmax, " maximum vertices deleted per iteration", -1);
|
||||
zdef_(zinc, Zfindbest, "calls to findbest", -1);
|
||||
zdef_(zadd, Zfindbesttot, " ave. facets tested", Zfindbest);
|
||||
zdef_(zmax, Zfindbestmax, " max. facets tested", -1);
|
||||
zdef_(zadd, Zfindcoplanar, " ave. coplanar search", Zfindbest);
|
||||
zdef_(zinc, Zfindnew, "calls to findbestnew", -1);
|
||||
zdef_(zadd, Zfindnewtot, " ave. facets tested", Zfindnew);
|
||||
zdef_(zmax, Zfindnewmax, " max. facets tested", -1);
|
||||
zdef_(zinc, Zfindnewjump, " ave. clearly better", Zfindnew);
|
||||
zdef_(zinc, Zfindnewsharp, " calls due to qh_sharpnewfacets", -1);
|
||||
zdef_(zinc, Zfindhorizon, "calls to findhorizon", -1);
|
||||
zdef_(zadd, Zfindhorizontot, " ave. facets tested", Zfindhorizon);
|
||||
zdef_(zmax, Zfindhorizonmax, " max. facets tested", -1);
|
||||
zdef_(zinc, Zfindjump, " ave. clearly better", Zfindhorizon);
|
||||
zdef_(zinc, Znewbesthorizon, " new bestfacets during qh_findbesthorizon", -1);
|
||||
zdef_(zinc, Zpartangle, "angle tests for repartitioned coplanar points", -1);
|
||||
zdef_(zinc, Zpartcorner, " repartitioned coplanar points above a corner facet", -1);
|
||||
zdef_(zinc, Zparthidden, " repartitioned coplanar points above a hidden facet", -1);
|
||||
zdef_(zinc, Zparttwisted, " repartitioned coplanar points above a twisted facet", -1);
|
||||
}
|
||||
void qh_allstatE(qhT *qh) {
|
||||
zdef_(zinc, Zpartinside, "inside points", -1);
|
||||
zdef_(zinc, Zpartnear, " near inside points kept with a facet", -1);
|
||||
zdef_(zinc, Zcoplanarinside, " inside points that were coplanar with a facet", -1);
|
||||
zdef_(zinc, Zbestlower, "calls to findbestlower", -1);
|
||||
zdef_(zinc, Zbestlowerv, " with search of vertex neighbors", -1);
|
||||
zdef_(zinc, Zbestlowerall, " with rare search of all facets", -1);
|
||||
zdef_(zmax, Zbestloweralln, " facets per search of all facets", -1);
|
||||
zdef_(wadd, Wmaxout, "difference in max_outside at final check", -1);
|
||||
zzdef_(zinc, Zpartitionall, "distance tests for initial partition", -1);
|
||||
zdef_(zinc, Ztotpartition, "partitions of a point", -1);
|
||||
zzdef_(zinc, Zpartition, "distance tests for partitioning", -1);
|
||||
zzdef_(zinc, Zdistcheck, "distance tests for checking flipped facets", -1);
|
||||
zzdef_(zinc, Zdistconvex, "distance tests for checking convexity", -1);
|
||||
zdef_(zinc, Zdistgood, "distance tests for checking good point", -1);
|
||||
zdef_(zinc, Zdistio, "distance tests for output", -1);
|
||||
zdef_(zinc, Zdiststat, "distance tests for statistics", -1);
|
||||
zzdef_(zinc, Zdistplane, "total number of distance tests", -1);
|
||||
zdef_(zinc, Ztotpartcoplanar, "partitions of coplanar points or deleted vertices", -1);
|
||||
zzdef_(zinc, Zpartcoplanar, " distance tests for these partitions", -1);
|
||||
zdef_(zinc, Zcomputefurthest, "distance tests for computing furthest", -1);
|
||||
}
|
||||
void qh_allstatE2(qhT *qh) {
|
||||
zdef_(zdoc, Zdoc5, "statistics for matching ridges", -1);
|
||||
zdef_(zinc, Zhashlookup, "total lookups for matching ridges of new facets", -1);
|
||||
zdef_(zinc, Zhashtests, "average number of tests to match a ridge", Zhashlookup);
|
||||
zdef_(zinc, Zhashridge, "total lookups of subridges (duplicates and boundary)", -1);
|
||||
zdef_(zinc, Zhashridgetest, "average number of tests per subridge", Zhashridge);
|
||||
zdef_(zinc, Zdupsame, "duplicated ridges in same merge cycle", -1);
|
||||
zdef_(zinc, Zdupflip, "duplicated ridges with flipped facets", -1);
|
||||
|
||||
zdef_(zdoc, Zdoc6, "statistics for determining merges", -1);
|
||||
zdef_(zinc, Zangletests, "angles computed for ridge convexity", -1);
|
||||
zdef_(zinc, Zbestcentrum, "best merges used centrum instead of vertices",-1);
|
||||
zzdef_(zinc, Zbestdist, "distance tests for best merge", -1);
|
||||
zzdef_(zinc, Zcentrumtests, "distance tests for centrum convexity", -1);
|
||||
zzdef_(zinc, Zvertextests, "distance tests for vertex convexity", -1);
|
||||
zzdef_(zinc, Zdistzero, "distance tests for checking simplicial convexity", -1);
|
||||
zdef_(zinc, Zcoplanarangle, "coplanar angles in getmergeset", -1);
|
||||
zdef_(zinc, Zcoplanarcentrum, "coplanar centrums or vertices in getmergeset", -1);
|
||||
zdef_(zinc, Zconcaveridge, "concave ridges in getmergeset", -1);
|
||||
zdef_(zinc, Zconcavecoplanarridge, "concave-coplanar ridges in getmergeset", -1);
|
||||
zdef_(zinc, Ztwistedridge, "twisted ridges in getmergeset", -1);
|
||||
}
|
||||
void qh_allstatF(qhT *qh) {
|
||||
zdef_(zdoc, Zdoc7, "statistics for merging", -1);
|
||||
zdef_(zinc, Zpremergetot, "merge iterations", -1);
|
||||
zdef_(zadd, Zmergeinittot, "ave. initial non-convex ridges per iteration", Zpremergetot);
|
||||
zdef_(zadd, Zmergeinitmax, " maximum", -1);
|
||||
zdef_(zadd, Zmergesettot, " ave. additional non-convex ridges per iteration", Zpremergetot);
|
||||
zdef_(zadd, Zmergesetmax, " maximum additional in one pass", -1);
|
||||
zdef_(zadd, Zmergeinittot2, "initial non-convex ridges for post merging", -1);
|
||||
zdef_(zadd, Zmergesettot2, " additional non-convex ridges", -1);
|
||||
zdef_(wmax, Wmaxoutside, "max distance of vertex or coplanar point above facet (w/roundoff)", -1);
|
||||
zdef_(wmin, Wminvertex, "max distance of vertex below facet (or roundoff)", -1);
|
||||
zdef_(zinc, Zwidefacet, "centrums frozen due to a wide merge", -1);
|
||||
zdef_(zinc, Zwidevertices, "centrums frozen due to extra vertices", -1);
|
||||
zzdef_(zinc, Ztotmerge, "total number of facets or cycles of facets merged", -1);
|
||||
zdef_(zinc, Zmergesimplex, "merged a simplex", -1);
|
||||
zdef_(zinc, Zonehorizon, "simplices merged into coplanar horizon", -1);
|
||||
zzdef_(zinc, Zcyclehorizon, "cycles of facets merged into coplanar horizon", -1);
|
||||
zzdef_(zadd, Zcyclefacettot, " ave. facets per cycle", Zcyclehorizon);
|
||||
zdef_(zmax, Zcyclefacetmax, " max. facets", -1);
|
||||
zdef_(zinc, Zmergeintocoplanar, "new facets merged into coplanar horizon", -1);
|
||||
zdef_(zinc, Zmergeintohorizon, "new facets merged into horizon", -1);
|
||||
zdef_(zinc, Zmergenew, "new facets merged", -1);
|
||||
zdef_(zinc, Zmergehorizon, "horizon facets merged into new facets", -1);
|
||||
zdef_(zinc, Zmergevertex, "vertices deleted by merging", -1);
|
||||
zdef_(zinc, Zcyclevertex, "vertices deleted by merging into coplanar horizon", -1);
|
||||
zdef_(zinc, Zdegenvertex, "vertices deleted by degenerate facet", -1);
|
||||
zdef_(zinc, Zmergeflipdup, "merges due to flipped facets in duplicated ridge", -1);
|
||||
zdef_(zinc, Zredundant, "merges due to redundant neighbors", -1);
|
||||
zdef_(zinc, Zredundantmerge, " detected by qh_test_nonsimplicial_merge instead of qh_test_redundant_neighbors", -1);
|
||||
zdef_(zadd, Ztestvneighbor, "non-convex vertex neighbors", -1);
|
||||
}
|
||||
void qh_allstatG(qhT *qh) {
|
||||
zdef_(zinc, Zacoplanar, "merges due to angle coplanar facets", -1);
|
||||
zdef_(wadd, Wacoplanartot, " average merge distance", Zacoplanar);
|
||||
zdef_(wmax, Wacoplanarmax, " maximum merge distance", -1);
|
||||
zdef_(zinc, Zcoplanar, "merges due to coplanar facets", -1);
|
||||
zdef_(wadd, Wcoplanartot, " average merge distance", Zcoplanar);
|
||||
zdef_(wmax, Wcoplanarmax, " maximum merge distance", -1);
|
||||
zdef_(zinc, Zconcave, "merges due to concave facets", -1);
|
||||
zdef_(wadd, Wconcavetot, " average merge distance", Zconcave);
|
||||
zdef_(wmax, Wconcavemax, " maximum merge distance", -1);
|
||||
zdef_(zinc, Zconcavecoplanar, "merges due to concave-coplanar facets", -1);
|
||||
zdef_(wadd, Wconcavecoplanartot, " average merge distance", Zconcavecoplanar);
|
||||
zdef_(wmax, Wconcavecoplanarmax, " maximum merge distance", -1);
|
||||
zdef_(zinc, Zavoidold, "coplanar/concave merges due to avoiding old merge", -1);
|
||||
zdef_(wadd, Wavoidoldtot, " average merge distance", Zavoidold);
|
||||
zdef_(wmax, Wavoidoldmax, " maximum merge distance", -1);
|
||||
zdef_(zinc, Zdegen, "merges due to degenerate facets", -1);
|
||||
zdef_(wadd, Wdegentot, " average merge distance", Zdegen);
|
||||
zdef_(wmax, Wdegenmax, " maximum merge distance", -1);
|
||||
zdef_(zinc, Zflipped, "merges due to removing flipped facets", -1);
|
||||
zdef_(wadd, Wflippedtot, " average merge distance", Zflipped);
|
||||
zdef_(wmax, Wflippedmax, " maximum merge distance", -1);
|
||||
zdef_(zinc, Zduplicate, "merges due to dupridges", -1);
|
||||
zdef_(wadd, Wduplicatetot, " average merge distance", Zduplicate);
|
||||
zdef_(wmax, Wduplicatemax, " maximum merge distance", -1);
|
||||
zdef_(zinc, Ztwisted, "merges due to twisted facets", -1);
|
||||
zdef_(wadd, Wtwistedtot, " average merge distance", Ztwisted);
|
||||
zdef_(wmax, Wtwistedmax, " maximum merge distance", -1);
|
||||
}
|
||||
void qh_allstatH(qhT *qh) {
|
||||
zdef_(zdoc, Zdoc8, "statistics for vertex merges", -1);
|
||||
zzdef_(zinc, Zpinchduplicate, "merge pinched vertices for a duplicate ridge", -1);
|
||||
zzdef_(zinc, Zpinchedvertex, "merge pinched vertices for a dupridge", -1);
|
||||
zdef_(zinc, Zrenameshare, "renamed vertices shared by two facets", -1);
|
||||
zdef_(zinc, Zrenamepinch, "renamed vertices in a pinched facet", -1);
|
||||
zdef_(zinc, Zrenameall, "renamed vertices shared by multiple facets", -1);
|
||||
zdef_(zinc, Zfindfail, "rename failures due to duplicated ridges", -1);
|
||||
zdef_(zinc, Znewvertexridge, " found new vertex in ridge", -1);
|
||||
zdef_(zinc, Zdelridge, "deleted ridges due to renamed vertices", -1);
|
||||
zdef_(zinc, Zdropneighbor, "dropped neighbors due to renamed vertices", -1);
|
||||
zdef_(zinc, Zdropdegen, "merge degenerate facets due to dropped neighbors", -1);
|
||||
zdef_(zinc, Zdelfacetdup, " facets deleted because of no neighbors", -1);
|
||||
zdef_(zinc, Zremvertex, "vertices removed from facets due to no ridges", -1);
|
||||
zdef_(zinc, Zremvertexdel, " deleted", -1);
|
||||
zdef_(zinc, Zretryadd, "retry qh_addpoint after merge pinched vertex", -1);
|
||||
zdef_(zadd, Zretryaddtot, " tot. merge pinched vertex due to dupridge", -1);
|
||||
zdef_(zmax, Zretryaddmax, " max. merge pinched vertex for a qh_addpoint", -1);
|
||||
zdef_(zinc, Zintersectnum, "vertex intersections for locating redundant vertices", -1);
|
||||
zdef_(zinc, Zintersectfail, "intersections failed to find a redundant vertex", -1);
|
||||
zdef_(zinc, Zintersect, "intersections found redundant vertices", -1);
|
||||
zdef_(zadd, Zintersecttot, " ave. number found per vertex", Zintersect);
|
||||
zdef_(zmax, Zintersectmax, " max. found for a vertex", -1);
|
||||
zdef_(zinc, Zvertexridge, NULL, -1);
|
||||
zdef_(zadd, Zvertexridgetot, " ave. number of ridges per tested vertex", Zvertexridge);
|
||||
zdef_(zmax, Zvertexridgemax, " max. number of ridges per tested vertex", -1);
|
||||
|
||||
zdef_(zdoc, Zdoc10, "memory usage statistics (in bytes)", -1);
|
||||
zdef_(zadd, Zmemfacets, "for facets and their normals, neighbor and vertex sets", -1);
|
||||
zdef_(zadd, Zmemvertices, "for vertices and their neighbor sets", -1);
|
||||
zdef_(zadd, Zmempoints, "for input points, outside and coplanar sets, and qhT",-1);
|
||||
zdef_(zadd, Zmemridges, "for ridges and their vertex sets", -1);
|
||||
} /* allstat */
|
||||
|
||||
void qh_allstatI(qhT *qh) {
|
||||
qh->qhstat.vridges= qh->qhstat.next; /* printed in qh_produce_output2 if non-zero Zridge or Zridgemid */
|
||||
zzdef_(zdoc, Zdoc11, "Voronoi ridge statistics", -1);
|
||||
zzdef_(zinc, Zridge, "non-simplicial Voronoi vertices for all ridges", -1);
|
||||
zzdef_(wadd, Wridge, " ave. distance to ridge", Zridge);
|
||||
zzdef_(wmax, Wridgemax, " max. distance to ridge", -1);
|
||||
zzdef_(zinc, Zridgemid, "bounded ridges", -1);
|
||||
zzdef_(wadd, Wridgemid, " ave. distance of midpoint to ridge", Zridgemid);
|
||||
zzdef_(wmax, Wridgemidmax, " max. distance of midpoint to ridge", -1);
|
||||
zzdef_(zinc, Zridgeok, "bounded ridges with ok normal", -1);
|
||||
zzdef_(wadd, Wridgeok, " ave. angle to ridge", Zridgeok);
|
||||
zzdef_(wmax, Wridgeokmax, " max. angle to ridge", -1);
|
||||
zzdef_(zinc, Zridge0, "bounded ridges with near-zero normal", -1);
|
||||
zzdef_(wadd, Wridge0, " ave. angle to ridge", Zridge0);
|
||||
zzdef_(wmax, Wridge0max, " max. angle to ridge", -1);
|
||||
|
||||
zdef_(zdoc, Zdoc12, "Triangulation statistics ('Qt')", -1);
|
||||
zdef_(zinc, Ztricoplanar, "non-simplicial facets triangulated", -1);
|
||||
zdef_(zadd, Ztricoplanartot, " ave. new facets created (may be deleted)", Ztricoplanar);
|
||||
zdef_(zmax, Ztricoplanarmax, " max. new facets created", -1);
|
||||
zdef_(zinc, Ztrinull, "null new facets deleted (duplicated vertex)", -1);
|
||||
zdef_(zinc, Ztrimirror, "mirrored pairs of new facets deleted (same vertices)", -1);
|
||||
zdef_(zinc, Ztridegen, "degenerate new facets in output (same ridge)", -1);
|
||||
} /* allstat */
|
||||
|
||||
/*-<a href="qh-stat_r.htm#TOC"
|
||||
>-------------------------------</a><a name="allstatistics">-</a>
|
||||
|
||||
qh_allstatistics()
|
||||
reset printed flag for all statistics
|
||||
*/
|
||||
void qh_allstatistics(qhT *qh) {
|
||||
int i;
|
||||
|
||||
for(i=ZEND; i--; )
|
||||
qh->qhstat.printed[i]= False;
|
||||
} /* allstatistics */
|
||||
|
||||
#if qh_KEEPstatistics
|
||||
/*-<a href="qh-stat_r.htm#TOC"
|
||||
>-------------------------------</a><a name="collectstatistics">-</a>
|
||||
|
||||
qh_collectstatistics()
|
||||
collect statistics for qh.facet_list
|
||||
|
||||
*/
|
||||
void qh_collectstatistics(qhT *qh) {
|
||||
facetT *facet, *neighbor, **neighborp;
|
||||
vertexT *vertex, **vertexp;
|
||||
realT dotproduct, dist;
|
||||
int sizneighbors, sizridges, sizvertices, i;
|
||||
|
||||
qh->old_randomdist= qh->RANDOMdist;
|
||||
qh->RANDOMdist= False;
|
||||
zval_(Zmempoints)= qh->num_points * qh->normal_size + (int)sizeof(qhT);
|
||||
zval_(Zmemfacets)= 0;
|
||||
zval_(Zmemridges)= 0;
|
||||
zval_(Zmemvertices)= 0;
|
||||
zval_(Zangle)= 0;
|
||||
wval_(Wangle)= 0.0;
|
||||
zval_(Znumridges)= 0;
|
||||
zval_(Znumfacets)= 0;
|
||||
zval_(Znumneighbors)= 0;
|
||||
zval_(Znumvertices)= 0;
|
||||
zval_(Znumvneighbors)= 0;
|
||||
zval_(Znummergetot)= 0;
|
||||
zval_(Znummergemax)= 0;
|
||||
zval_(Zvertices)= qh->num_vertices - qh_setsize(qh, qh->del_vertices);
|
||||
if (qh->MERGING || qh->APPROXhull || qh->JOGGLEmax < REALmax/2)
|
||||
wmax_(Wmaxoutside, qh->max_outside);
|
||||
if (qh->MERGING)
|
||||
wmin_(Wminvertex, qh->min_vertex);
|
||||
if (!qh_checklists(qh, qh->facet_list)) {
|
||||
qh_fprintf(qh, qh->ferr, 6373, "qhull internal error: qh_checklists failed on qh_collectstatistics\n");
|
||||
if (!qh->ERREXITcalled)
|
||||
qh_errexit(qh, qh_ERRqhull, NULL, NULL);
|
||||
}
|
||||
FORALLfacets
|
||||
facet->seen= False;
|
||||
if (qh->DELAUNAY) {
|
||||
FORALLfacets {
|
||||
if (facet->upperdelaunay != qh->UPPERdelaunay)
|
||||
facet->seen= True; /* remove from angle statistics */
|
||||
}
|
||||
}
|
||||
FORALLfacets {
|
||||
if (facet->visible && qh->NEWfacets)
|
||||
continue;
|
||||
sizvertices= qh_setsize(qh, facet->vertices);
|
||||
sizneighbors= qh_setsize(qh, facet->neighbors);
|
||||
sizridges= qh_setsize(qh, facet->ridges);
|
||||
zinc_(Znumfacets);
|
||||
zadd_(Znumvertices, sizvertices);
|
||||
zmax_(Zmaxvertices, sizvertices);
|
||||
zadd_(Znumneighbors, sizneighbors);
|
||||
zmax_(Zmaxneighbors, sizneighbors);
|
||||
zadd_(Znummergetot, facet->nummerge);
|
||||
i= facet->nummerge; /* avoid warnings */
|
||||
zmax_(Znummergemax, i);
|
||||
if (!facet->simplicial) {
|
||||
if (sizvertices == qh->hull_dim) {
|
||||
zinc_(Znowsimplicial);
|
||||
}else {
|
||||
zinc_(Znonsimplicial);
|
||||
}
|
||||
}
|
||||
if (sizridges) {
|
||||
zadd_(Znumridges, sizridges);
|
||||
zmax_(Zmaxridges, sizridges);
|
||||
}
|
||||
zadd_(Zmemfacets, (int)sizeof(facetT) + qh->normal_size + 2*(int)sizeof(setT)
|
||||
+ SETelemsize * (sizneighbors + sizvertices));
|
||||
if (facet->ridges) {
|
||||
zadd_(Zmemridges,
|
||||
(int)sizeof(setT) + SETelemsize * sizridges + sizridges *
|
||||
((int)sizeof(ridgeT) + (int)sizeof(setT) + SETelemsize * (qh->hull_dim-1))/2);
|
||||
}
|
||||
if (facet->outsideset)
|
||||
zadd_(Zmempoints, (int)sizeof(setT) + SETelemsize * qh_setsize(qh, facet->outsideset));
|
||||
if (facet->coplanarset)
|
||||
zadd_(Zmempoints, (int)sizeof(setT) + SETelemsize * qh_setsize(qh, facet->coplanarset));
|
||||
if (facet->seen) /* Delaunay upper envelope */
|
||||
continue;
|
||||
facet->seen= True;
|
||||
FOREACHneighbor_(facet) {
|
||||
if (neighbor == qh_DUPLICATEridge || neighbor == qh_MERGEridge
|
||||
|| neighbor->seen || !facet->normal || !neighbor->normal)
|
||||
continue;
|
||||
dotproduct= qh_getangle(qh, facet->normal, neighbor->normal);
|
||||
zinc_(Zangle);
|
||||
wadd_(Wangle, dotproduct);
|
||||
wmax_(Wanglemax, dotproduct)
|
||||
wmin_(Wanglemin, dotproduct)
|
||||
}
|
||||
if (facet->normal) {
|
||||
FOREACHvertex_(facet->vertices) {
|
||||
zinc_(Zdiststat);
|
||||
qh_distplane(qh, vertex->point, facet, &dist);
|
||||
wmax_(Wvertexmax, dist);
|
||||
wmin_(Wvertexmin, dist);
|
||||
}
|
||||
}
|
||||
}
|
||||
FORALLvertices {
|
||||
if (vertex->deleted)
|
||||
continue;
|
||||
zadd_(Zmemvertices, (int)sizeof(vertexT));
|
||||
if (vertex->neighbors) {
|
||||
sizneighbors= qh_setsize(qh, vertex->neighbors);
|
||||
zadd_(Znumvneighbors, sizneighbors);
|
||||
zmax_(Zmaxvneighbors, sizneighbors);
|
||||
zadd_(Zmemvertices, (int)sizeof(vertexT) + SETelemsize * sizneighbors);
|
||||
}
|
||||
}
|
||||
qh->RANDOMdist= qh->old_randomdist;
|
||||
} /* collectstatistics */
|
||||
#endif /* qh_KEEPstatistics */
|
||||
|
||||
/*-<a href="qh-stat_r.htm#TOC"
|
||||
>-------------------------------</a><a name="initstatistics">-</a>
|
||||
|
||||
qh_initstatistics(qh)
|
||||
initialize statistics
|
||||
|
||||
notes:
|
||||
NOerrors -- qh_initstatistics can not use qh_errexit(), qh_fprintf, or qh.ferr
|
||||
On first call, only qhmem.ferr is defined. qh_memalloc is not setup.
|
||||
Also invoked by QhullQh().
|
||||
*/
|
||||
void qh_initstatistics(qhT *qh) {
|
||||
int i;
|
||||
realT realx;
|
||||
int intx;
|
||||
|
||||
qh_allstatistics(qh);
|
||||
qh->qhstat.next= 0;
|
||||
qh_allstatA(qh);
|
||||
qh_allstatB(qh);
|
||||
qh_allstatC(qh);
|
||||
qh_allstatD(qh);
|
||||
qh_allstatE(qh);
|
||||
qh_allstatE2(qh);
|
||||
qh_allstatF(qh);
|
||||
qh_allstatG(qh);
|
||||
qh_allstatH(qh);
|
||||
qh_allstatI(qh);
|
||||
if (qh->qhstat.next > (int)sizeof(qh->qhstat.id)) {
|
||||
qh_fprintf_stderr(6184, "qhull internal error (qh_initstatistics): increase size of qhstat.id[]. qhstat.next %d should be <= sizeof(qh->qhstat.id) %d\n",
|
||||
qh->qhstat.next, (int)sizeof(qh->qhstat.id));
|
||||
#if 0 /* for locating error, Znumridges should be duplicated */
|
||||
for(i=0; i < ZEND; i++) {
|
||||
int j;
|
||||
for(j=i+1; j < ZEND; j++) {
|
||||
if (qh->qhstat.id[i] == qh->qhstat.id[j]) {
|
||||
qh_fprintf_stderr(6185, "qhull error (qh_initstatistics): duplicated statistic %d at indices %d and %d\n",
|
||||
qh->qhstat.id[i], i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
qh_exit(qh_ERRqhull); /* can not use qh_errexit() */
|
||||
}
|
||||
qh->qhstat.init[zinc].i= 0;
|
||||
qh->qhstat.init[zadd].i= 0;
|
||||
qh->qhstat.init[zmin].i= INT_MAX;
|
||||
qh->qhstat.init[zmax].i= INT_MIN;
|
||||
qh->qhstat.init[wadd].r= 0;
|
||||
qh->qhstat.init[wmin].r= REALmax;
|
||||
qh->qhstat.init[wmax].r= -REALmax;
|
||||
for(i=0; i < ZEND; i++) {
|
||||
if (qh->qhstat.type[i] > ZTYPEreal) {
|
||||
realx= qh->qhstat.init[(unsigned char)(qh->qhstat.type[i])].r;
|
||||
qh->qhstat.stats[i].r= realx;
|
||||
}else if (qh->qhstat.type[i] != zdoc) {
|
||||
intx= qh->qhstat.init[(unsigned char)(qh->qhstat.type[i])].i;
|
||||
qh->qhstat.stats[i].i= intx;
|
||||
}
|
||||
}
|
||||
} /* initstatistics */
|
||||
|
||||
/*-<a href="qh-stat_r.htm#TOC"
|
||||
>-------------------------------</a><a name="newstats">-</a>
|
||||
|
||||
qh_newstats(qh )
|
||||
returns True if statistics for zdoc
|
||||
|
||||
returns:
|
||||
next zdoc
|
||||
*/
|
||||
boolT qh_newstats(qhT *qh, int idx, int *nextindex) {
|
||||
boolT isnew= False;
|
||||
int start, i;
|
||||
|
||||
if (qh->qhstat.type[qh->qhstat.id[idx]] == zdoc)
|
||||
start= idx+1;
|
||||
else
|
||||
start= idx;
|
||||
for(i= start; i < qh->qhstat.next && qh->qhstat.type[qh->qhstat.id[i]] != zdoc; i++) {
|
||||
if (!qh_nostatistic(qh, qh->qhstat.id[i]) && !qh->qhstat.printed[qh->qhstat.id[i]])
|
||||
isnew= True;
|
||||
}
|
||||
*nextindex= i;
|
||||
return isnew;
|
||||
} /* newstats */
|
||||
|
||||
/*-<a href="qh-stat_r.htm#TOC"
|
||||
>-------------------------------</a><a name="nostatistic">-</a>
|
||||
|
||||
qh_nostatistic(qh, index )
|
||||
true if no statistic to print
|
||||
*/
|
||||
boolT qh_nostatistic(qhT *qh, int i) {
|
||||
|
||||
if ((qh->qhstat.type[i] > ZTYPEreal
|
||||
&&qh->qhstat.stats[i].r == qh->qhstat.init[(unsigned char)(qh->qhstat.type[i])].r)
|
||||
|| (qh->qhstat.type[i] < ZTYPEreal
|
||||
&&qh->qhstat.stats[i].i == qh->qhstat.init[(unsigned char)(qh->qhstat.type[i])].i))
|
||||
return True;
|
||||
return False;
|
||||
} /* nostatistic */
|
||||
|
||||
#if qh_KEEPstatistics
|
||||
/*-<a href="qh-stat_r.htm#TOC"
|
||||
>-------------------------------</a><a name="printallstatistics">-</a>
|
||||
|
||||
qh_printallstatistics(qh, fp, string )
|
||||
print all statistics with header 'string'
|
||||
*/
|
||||
void qh_printallstatistics(qhT *qh, FILE *fp, const char *string) {
|
||||
|
||||
qh_allstatistics(qh);
|
||||
qh_collectstatistics(qh);
|
||||
qh_printstatistics(qh, fp, string);
|
||||
qh_memstatistics(qh, fp);
|
||||
}
|
||||
|
||||
|
||||
/*-<a href="qh-stat_r.htm#TOC"
|
||||
>-------------------------------</a><a name="printstatistics">-</a>
|
||||
|
||||
qh_printstatistics(qh, fp, string )
|
||||
print statistics to a file with header 'string'
|
||||
skips statistics with qhstat.printed[] (reset with qh_allstatistics)
|
||||
|
||||
see:
|
||||
qh_printallstatistics()
|
||||
*/
|
||||
void qh_printstatistics(qhT *qh, FILE *fp, const char *string) {
|
||||
int i, k;
|
||||
realT ave; /* ignored */
|
||||
|
||||
if (qh->num_points != qh->num_vertices || zval_(Zpbalance) == 0) {
|
||||
wval_(Wpbalance)= 0.0;
|
||||
wval_(Wpbalance2)= 0.0;
|
||||
}else
|
||||
wval_(Wpbalance2)= qh_stddev(qh, zval_(Zpbalance), wval_(Wpbalance),
|
||||
wval_(Wpbalance2), &ave);
|
||||
if (zval_(Zprocessed) == 0)
|
||||
wval_(Wnewbalance2)= 0.0;
|
||||
else
|
||||
wval_(Wnewbalance2)= qh_stddev(qh, zval_(Zprocessed), wval_(Wnewbalance),
|
||||
wval_(Wnewbalance2), &ave);
|
||||
qh_fprintf(qh, fp, 9350, "\n\
|
||||
%s\n\
|
||||
qhull invoked by: %s | %s\n %s with options:\n%s\n",
|
||||
string, qh->rbox_command, qh->qhull_command, qh_version, qh->qhull_options);
|
||||
|
||||
qh_fprintf(qh, fp, 9351, "\nprecision constants:\n\
|
||||
%6.2g max. abs. coordinate in the (transformed) input ('Qbd:n')\n\
|
||||
%6.2g max. roundoff error for distance computation ('En')\n\
|
||||
%6.2g max. roundoff error for angle computations\n\
|
||||
%6.2g min. distance for outside points ('Wn')\n\
|
||||
%6.2g min. distance for visible facets ('Vn')\n\
|
||||
%6.2g max. distance for coplanar facets ('Un')\n\
|
||||
%6.2g max. facet width for recomputing centrum and area\n\
|
||||
",
|
||||
qh->MAXabs_coord, qh->DISTround, qh->ANGLEround, qh->MINoutside,
|
||||
qh->MINvisible, qh->MAXcoplanar, qh->WIDEfacet);
|
||||
if (qh->KEEPnearinside)
|
||||
qh_fprintf(qh, fp, 9352, "\
|
||||
%6.2g max. distance for near-inside points\n", qh->NEARinside);
|
||||
if (qh->premerge_cos < REALmax/2) qh_fprintf(qh, fp, 9353, "\
|
||||
%6.2g max. cosine for pre-merge angle\n", qh->premerge_cos);
|
||||
if (qh->PREmerge) qh_fprintf(qh, fp, 9354, "\
|
||||
%6.2g radius of pre-merge centrum\n", qh->premerge_centrum);
|
||||
if (qh->postmerge_cos < REALmax/2) qh_fprintf(qh, fp, 9355, "\
|
||||
%6.2g max. cosine for post-merge angle\n", qh->postmerge_cos);
|
||||
if (qh->POSTmerge) qh_fprintf(qh, fp, 9356, "\
|
||||
%6.2g radius of post-merge centrum\n", qh->postmerge_centrum);
|
||||
qh_fprintf(qh, fp, 9357, "\
|
||||
%6.2g max. distance for merging two simplicial facets\n\
|
||||
%6.2g max. roundoff error for arithmetic operations\n\
|
||||
%6.2g min. denominator for division\n\
|
||||
zero diagonal for Gauss: ", qh->ONEmerge, REALepsilon, qh->MINdenom);
|
||||
for(k=0; k < qh->hull_dim; k++)
|
||||
qh_fprintf(qh, fp, 9358, "%6.2e ", qh->NEARzero[k]);
|
||||
qh_fprintf(qh, fp, 9359, "\n\n");
|
||||
for(i=0 ; i < qh->qhstat.next; )
|
||||
qh_printstats(qh, fp, i, &i);
|
||||
} /* printstatistics */
|
||||
#endif /* qh_KEEPstatistics */
|
||||
|
||||
/*-<a href="qh-stat_r.htm#TOC"
|
||||
>-------------------------------</a><a name="printstatlevel">-</a>
|
||||
|
||||
qh_printstatlevel(qh, fp, id )
|
||||
print level information for a statistic
|
||||
|
||||
notes:
|
||||
nop if id >= ZEND, printed, or same as initial value
|
||||
*/
|
||||
void qh_printstatlevel(qhT *qh, FILE *fp, int id) {
|
||||
|
||||
if (id >= ZEND || qh->qhstat.printed[id])
|
||||
return;
|
||||
if (qh->qhstat.type[id] == zdoc) {
|
||||
qh_fprintf(qh, fp, 9360, "%s\n", qh->qhstat.doc[id]);
|
||||
return;
|
||||
}
|
||||
if (qh_nostatistic(qh, id) || !qh->qhstat.doc[id])
|
||||
return;
|
||||
qh->qhstat.printed[id]= True;
|
||||
if (qh->qhstat.count[id] != -1
|
||||
&& qh->qhstat.stats[(unsigned char)(qh->qhstat.count[id])].i == 0)
|
||||
qh_fprintf(qh, fp, 9361, " *0 cnt*");
|
||||
else if (qh->qhstat.type[id] >= ZTYPEreal && qh->qhstat.count[id] == -1)
|
||||
qh_fprintf(qh, fp, 9362, "%7.2g", qh->qhstat.stats[id].r);
|
||||
else if (qh->qhstat.type[id] >= ZTYPEreal && qh->qhstat.count[id] != -1)
|
||||
qh_fprintf(qh, fp, 9363, "%7.2g", qh->qhstat.stats[id].r/ qh->qhstat.stats[(unsigned char)(qh->qhstat.count[id])].i);
|
||||
else if (qh->qhstat.type[id] < ZTYPEreal && qh->qhstat.count[id] == -1)
|
||||
qh_fprintf(qh, fp, 9364, "%7d", qh->qhstat.stats[id].i);
|
||||
else if (qh->qhstat.type[id] < ZTYPEreal && qh->qhstat.count[id] != -1)
|
||||
qh_fprintf(qh, fp, 9365, "%7.3g", (realT) qh->qhstat.stats[id].i / qh->qhstat.stats[(unsigned char)(qh->qhstat.count[id])].i);
|
||||
qh_fprintf(qh, fp, 9366, " %s\n", qh->qhstat.doc[id]);
|
||||
} /* printstatlevel */
|
||||
|
||||
|
||||
/*-<a href="qh-stat_r.htm#TOC"
|
||||
>-------------------------------</a><a name="printstats">-</a>
|
||||
|
||||
qh_printstats(qh, fp, index, nextindex )
|
||||
print statistics for a zdoc group
|
||||
|
||||
returns:
|
||||
next zdoc if non-null
|
||||
*/
|
||||
void qh_printstats(qhT *qh, FILE *fp, int idx, int *nextindex) {
|
||||
int j, nexti;
|
||||
|
||||
if (qh_newstats(qh, idx, &nexti)) {
|
||||
qh_fprintf(qh, fp, 9367, "\n");
|
||||
for (j=idx; j<nexti; j++)
|
||||
qh_printstatlevel(qh, fp, qh->qhstat.id[j]);
|
||||
}
|
||||
if (nextindex)
|
||||
*nextindex= nexti;
|
||||
} /* printstats */
|
||||
|
||||
#if qh_KEEPstatistics
|
||||
|
||||
/*-<a href="qh-stat_r.htm#TOC"
|
||||
>-------------------------------</a><a name="stddev">-</a>
|
||||
|
||||
qh_stddev(qh, num, tot, tot2, ave )
|
||||
compute the standard deviation and average from statistics
|
||||
|
||||
tot2 is the sum of the squares
|
||||
notes:
|
||||
computes r.m.s.:
|
||||
(x-ave)^2
|
||||
== x^2 - 2x tot/num + (tot/num)^2
|
||||
== tot2 - 2 tot tot/num + tot tot/num
|
||||
== tot2 - tot ave
|
||||
*/
|
||||
realT qh_stddev(qhT *qh, int num, realT tot, realT tot2, realT *ave) {
|
||||
realT stddev;
|
||||
|
||||
if (num <= 0) {
|
||||
qh_fprintf(qh, qh->ferr, 7101, "qhull warning (qh_stddev): expecting num > 0. Got num %d, tot %4.4g, tot2 %4.4g. Returning 0.0\n",
|
||||
num, tot, tot2);
|
||||
return 0.0;
|
||||
}
|
||||
*ave= tot/num;
|
||||
stddev= sqrt(fabs(tot2/num - *ave * *ave));
|
||||
return stddev;
|
||||
} /* stddev */
|
||||
#else
|
||||
realT qh_stddev(qhT *qh, int num, realT tot, realT tot2, realT *ave) { /* for qhull_r-exports.def */
|
||||
QHULL_UNUSED(qh)
|
||||
QHULL_UNUSED(num)
|
||||
QHULL_UNUSED(tot)
|
||||
QHULL_UNUSED(tot2)
|
||||
QHULL_UNUSED(ave)
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
#endif /* qh_KEEPstatistics */
|
||||
|
||||
#if !qh_KEEPstatistics
|
||||
void qh_collectstatistics(qhT *qh) {}
|
||||
void qh_printallstatistics(qhT *qh, FILE *fp, const char *string) {}
|
||||
void qh_printstatistics(qhT *qh, FILE *fp, const char *string) {}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,563 @@
|
||||
/*<html><pre> -<a href="qh-stat_r.htm"
|
||||
>-------------------------------</a><a name="TOP">-</a>
|
||||
|
||||
stat_r.h
|
||||
contains all statistics that are collected for qhull
|
||||
|
||||
see qh-stat_r.htm and stat_r.c
|
||||
|
||||
Copyright (c) 1993-2020 The Geometry Center.
|
||||
$Id: //main/2019/qhull/src/libqhull_r/stat_r.h#4 $$Change: 2953 $
|
||||
$DateTime: 2020/05/21 22:05:32 $$Author: bbarber $
|
||||
|
||||
recompile qhull if you change this file
|
||||
|
||||
Integer statistics are Z* while real statistics are W*.
|
||||
|
||||
define MAYdebugx to call a routine at every statistic event
|
||||
|
||||
*/
|
||||
|
||||
#ifndef qhDEFstat
|
||||
#define qhDEFstat 1
|
||||
|
||||
/* Depends on realT. Do not include "libqhull_r" to avoid circular dependency */
|
||||
|
||||
#ifndef DEFqhT
|
||||
#define DEFqhT 1
|
||||
typedef struct qhT qhT; /* Defined by libqhull_r.h */
|
||||
#endif
|
||||
|
||||
#ifndef DEFqhstatT
|
||||
#define DEFqhstatT 1
|
||||
typedef struct qhstatT qhstatT; /* Defined here */
|
||||
#endif
|
||||
|
||||
/*-<a href="qh-stat_r.htm#TOC"
|
||||
>-------------------------------</a><a name="KEEPstatistics">-</a>
|
||||
|
||||
qh_KEEPstatistics
|
||||
0 turns off statistic reporting and gathering (except zzdef/zzinc/zzadd/zzval/wwval)
|
||||
|
||||
set qh_KEEPstatistics in user_r.h to 0 to turn off statistics
|
||||
*/
|
||||
#ifndef qh_KEEPstatistics
|
||||
#define qh_KEEPstatistics 1
|
||||
#endif
|
||||
|
||||
/*-<a href="qh-stat_r.htm#TOC"
|
||||
>-------------------------------</a><a name="statistics">-</a>
|
||||
|
||||
Zxxx for integers, Wxxx for reals
|
||||
|
||||
notes:
|
||||
be sure that all statistics are defined in stat_r.c
|
||||
otherwise initialization may core dump
|
||||
can pick up all statistics by:
|
||||
grep '[zw].*_[(][ZW]' *.c >z.x
|
||||
remove trailers with query">-</a>
|
||||
remove leaders with query-replace-regexp [ ^I]+ (
|
||||
*/
|
||||
#if qh_KEEPstatistics
|
||||
enum qh_statistics { /* alphabetical after Z/W */
|
||||
Zacoplanar,
|
||||
Wacoplanarmax,
|
||||
Wacoplanartot,
|
||||
Zangle,
|
||||
Wangle,
|
||||
Wanglemax,
|
||||
Wanglemin,
|
||||
Zangletests,
|
||||
Wareatot,
|
||||
Wareamax,
|
||||
Wareamin,
|
||||
Zavoidold,
|
||||
Wavoidoldmax,
|
||||
Wavoidoldtot,
|
||||
Zback0,
|
||||
Zbestcentrum,
|
||||
Zbestdist,
|
||||
Zbestlower,
|
||||
Zbestlowerall,
|
||||
Zbestloweralln,
|
||||
Zbestlowerv,
|
||||
Zcentrumtests,
|
||||
Zcheckpart,
|
||||
Zcomputefurthest,
|
||||
Zconcave,
|
||||
Wconcavemax,
|
||||
Wconcavetot,
|
||||
Zconcavecoplanar,
|
||||
Wconcavecoplanarmax,
|
||||
Wconcavecoplanartot,
|
||||
Zconcavecoplanarridge,
|
||||
Zconcaveridge,
|
||||
Zconcaveridges,
|
||||
Zcoplanar,
|
||||
Wcoplanarmax,
|
||||
Wcoplanartot,
|
||||
Zcoplanarangle,
|
||||
Zcoplanarcentrum,
|
||||
Zcoplanarhorizon,
|
||||
Zcoplanarinside,
|
||||
Zcoplanarpart,
|
||||
Zcoplanarridges,
|
||||
Wcpu,
|
||||
Zcyclefacetmax,
|
||||
Zcyclefacettot,
|
||||
Zcyclehorizon,
|
||||
Zcyclevertex,
|
||||
Zdegen,
|
||||
Wdegenmax,
|
||||
Wdegentot,
|
||||
Zdegenvertex,
|
||||
Zdelfacetdup,
|
||||
Zdelridge,
|
||||
Zdelvertextot,
|
||||
Zdelvertexmax,
|
||||
Zdetfacetarea,
|
||||
Zdetsimplex,
|
||||
Zdistcheck,
|
||||
Zdistconvex,
|
||||
Zdistgood,
|
||||
Zdistio,
|
||||
Zdistplane,
|
||||
Zdiststat,
|
||||
Zdistvertex,
|
||||
Zdistzero,
|
||||
Zdoc1,
|
||||
Zdoc2,
|
||||
Zdoc3,
|
||||
Zdoc4,
|
||||
Zdoc5,
|
||||
Zdoc6,
|
||||
Zdoc7,
|
||||
Zdoc8,
|
||||
Zdoc9,
|
||||
Zdoc10,
|
||||
Zdoc11,
|
||||
Zdoc12,
|
||||
Zdropdegen,
|
||||
Zdropneighbor,
|
||||
Zdupflip,
|
||||
Zduplicate,
|
||||
Wduplicatemax,
|
||||
Wduplicatetot,
|
||||
Zdupsame,
|
||||
Zflipped,
|
||||
Wflippedmax,
|
||||
Wflippedtot,
|
||||
Zflippedfacets,
|
||||
Zflipridge,
|
||||
Zflipridge2,
|
||||
Zfindbest,
|
||||
Zfindbestmax,
|
||||
Zfindbesttot,
|
||||
Zfindcoplanar,
|
||||
Zfindfail,
|
||||
Zfindhorizon,
|
||||
Zfindhorizonmax,
|
||||
Zfindhorizontot,
|
||||
Zfindjump,
|
||||
Zfindnew,
|
||||
Zfindnewmax,
|
||||
Zfindnewtot,
|
||||
Zfindnewjump,
|
||||
Zfindnewsharp,
|
||||
Zgauss0,
|
||||
Zgoodfacet,
|
||||
Zhashlookup,
|
||||
Zhashridge,
|
||||
Zhashridgetest,
|
||||
Zhashtests,
|
||||
Zinsidevisible,
|
||||
Zintersect,
|
||||
Zintersectfail,
|
||||
Zintersectmax,
|
||||
Zintersectnum,
|
||||
Zintersecttot,
|
||||
Zmaxneighbors,
|
||||
Wmaxout,
|
||||
Wmaxoutside,
|
||||
Zmaxridges,
|
||||
Zmaxvertex,
|
||||
Zmaxvertices,
|
||||
Zmaxvneighbors,
|
||||
Zmemfacets,
|
||||
Zmempoints,
|
||||
Zmemridges,
|
||||
Zmemvertices,
|
||||
Zmergeflipdup,
|
||||
Zmergehorizon,
|
||||
Zmergeinittot,
|
||||
Zmergeinitmax,
|
||||
Zmergeinittot2,
|
||||
Zmergeintocoplanar,
|
||||
Zmergeintohorizon,
|
||||
Zmergenew,
|
||||
Zmergesettot,
|
||||
Zmergesetmax,
|
||||
Zmergesettot2,
|
||||
Zmergesimplex,
|
||||
Zmergevertex,
|
||||
Wmindenom,
|
||||
Wminvertex,
|
||||
Zminnorm,
|
||||
Zmultiridge,
|
||||
Znearlysingular,
|
||||
Zredundant,
|
||||
Wnewbalance,
|
||||
Wnewbalance2,
|
||||
Znewbesthorizon,
|
||||
Znewfacettot,
|
||||
Znewfacetmax,
|
||||
Znewvertex,
|
||||
Wnewvertex,
|
||||
Wnewvertexmax,
|
||||
Znewvertexridge,
|
||||
Znoarea,
|
||||
Znonsimplicial,
|
||||
Znowsimplicial,
|
||||
Znotgood,
|
||||
Znotgoodnew,
|
||||
Znotmax,
|
||||
Znumfacets,
|
||||
Znummergemax,
|
||||
Znummergetot,
|
||||
Znumneighbors,
|
||||
Znumridges,
|
||||
Znumvertices,
|
||||
Znumvisibility,
|
||||
Znumvneighbors,
|
||||
Zonehorizon,
|
||||
Zpartangle,
|
||||
Zpartcoplanar,
|
||||
Zpartcorner,
|
||||
Zparthidden,
|
||||
Zpartinside,
|
||||
Zpartition,
|
||||
Zpartitionall,
|
||||
Zpartnear,
|
||||
Zparttwisted,
|
||||
Zpbalance,
|
||||
Wpbalance,
|
||||
Wpbalance2,
|
||||
Zpinchduplicate,
|
||||
Zpinchedapex,
|
||||
Zpinchedvertex,
|
||||
Zpostfacets,
|
||||
Zpremergetot,
|
||||
Zprocessed,
|
||||
Zremvertex,
|
||||
Zremvertexdel,
|
||||
Zredundantmerge,
|
||||
Zrenameall,
|
||||
Zrenamepinch,
|
||||
Zrenameshare,
|
||||
Zretry,
|
||||
Wretrymax,
|
||||
Zretryadd,
|
||||
Zretryaddmax,
|
||||
Zretryaddtot,
|
||||
Zridge,
|
||||
Wridge,
|
||||
Wridgemax,
|
||||
Zridge0,
|
||||
Wridge0,
|
||||
Wridge0max,
|
||||
Zridgemid,
|
||||
Wridgemid,
|
||||
Wridgemidmax,
|
||||
Zridgeok,
|
||||
Wridgeok,
|
||||
Wridgeokmax,
|
||||
Zsearchpoints,
|
||||
Zsetplane,
|
||||
Ztestvneighbor,
|
||||
Ztotcheck,
|
||||
Ztothorizon,
|
||||
Ztotmerge,
|
||||
Ztotpartcoplanar,
|
||||
Ztotpartition,
|
||||
Ztotridges,
|
||||
Ztotvertices,
|
||||
Ztotvisible,
|
||||
Ztricoplanar,
|
||||
Ztricoplanarmax,
|
||||
Ztricoplanartot,
|
||||
Ztridegen,
|
||||
Ztrimirror,
|
||||
Ztrinull,
|
||||
Ztwisted,
|
||||
Wtwistedtot,
|
||||
Wtwistedmax,
|
||||
Ztwistedridge,
|
||||
Zvertextests,
|
||||
Wvertexmax,
|
||||
Wvertexmin,
|
||||
Zvertexridge,
|
||||
Zvertexridgetot,
|
||||
Zvertexridgemax,
|
||||
Zvertices,
|
||||
Zvisfacettot,
|
||||
Zvisfacetmax,
|
||||
Zvisit,
|
||||
Zvisit2max,
|
||||
Zvisvertextot,
|
||||
Zvisvertexmax,
|
||||
Zvvisit,
|
||||
Zvvisit2max,
|
||||
Zwidefacet,
|
||||
Zwidevertices,
|
||||
ZEND};
|
||||
|
||||
/*-<a href="qh-stat_r.htm#TOC"
|
||||
>-------------------------------</a><a name="ZZstat">-</a>
|
||||
|
||||
Zxxx/Wxxx statistics that remain defined if qh_KEEPstatistics=0
|
||||
|
||||
notes:
|
||||
be sure to use zzdef, zzinc, etc. with these statistics (no double checking!)
|
||||
*/
|
||||
#else
|
||||
enum qh_statistics { /* for zzdef etc. macros */
|
||||
Zback0,
|
||||
Zbestdist,
|
||||
Zcentrumtests,
|
||||
Zcheckpart,
|
||||
Zconcaveridges,
|
||||
Zcoplanarhorizon,
|
||||
Zcoplanarpart,
|
||||
Zcoplanarridges,
|
||||
Zcyclefacettot,
|
||||
Zcyclehorizon,
|
||||
Zdelvertextot,
|
||||
Zdistcheck,
|
||||
Zdistconvex,
|
||||
Zdistplane,
|
||||
Zdistzero,
|
||||
Zdoc1,
|
||||
Zdoc2,
|
||||
Zdoc3,
|
||||
Zdoc11,
|
||||
Zflippedfacets,
|
||||
Zflipridge,
|
||||
Zflipridge2,
|
||||
Zgauss0,
|
||||
Zminnorm,
|
||||
Zmultiridge,
|
||||
Znearlysingular,
|
||||
Wnewvertexmax,
|
||||
Znumvisibility,
|
||||
Zpartcoplanar,
|
||||
Zpartition,
|
||||
Zpartitionall,
|
||||
Zpinchduplicate,
|
||||
Zpinchedvertex,
|
||||
Zprocessed,
|
||||
Zretry,
|
||||
Zridge,
|
||||
Wridge,
|
||||
Wridgemax,
|
||||
Zridge0,
|
||||
Wridge0,
|
||||
Wridge0max,
|
||||
Zridgemid,
|
||||
Wridgemid,
|
||||
Wridgemidmax,
|
||||
Zridgeok,
|
||||
Wridgeok,
|
||||
Wridgeokmax,
|
||||
Zsetplane,
|
||||
Ztotcheck,
|
||||
Ztotmerge,
|
||||
Zvertextests,
|
||||
ZEND};
|
||||
#endif
|
||||
|
||||
/*-<a href="qh-stat_r.htm#TOC"
|
||||
>-------------------------------</a><a name="ztype">-</a>
|
||||
|
||||
ztype
|
||||
the type of a statistic sets its initial value.
|
||||
|
||||
notes:
|
||||
The type should be the same as the macro for collecting the statistic
|
||||
*/
|
||||
enum ztypes {zdoc,zinc,zadd,zmax,zmin,ZTYPEreal,wadd,wmax,wmin,ZTYPEend};
|
||||
|
||||
/*========== macros and constants =============*/
|
||||
|
||||
/*-<a href="qh-stat_r.htm#TOC"
|
||||
>--------------------------------</a><a name="MAYdebugx">-</a>
|
||||
|
||||
MAYdebugx
|
||||
define as maydebug() to be called frequently for error trapping
|
||||
*/
|
||||
#define MAYdebugx
|
||||
|
||||
/*-<a href="qh-stat_r.htm#TOC"
|
||||
>--------------------------------</a><a name="zdef_">-</a>
|
||||
|
||||
zzdef_, zdef_( type, name, doc, -1)
|
||||
define a statistic (assumes 'qhstat.next= 0;')
|
||||
|
||||
zdef_( type, name, doc, count)
|
||||
define an averaged statistic
|
||||
printed as name/count
|
||||
*/
|
||||
#define zzdef_(stype,name,string,cnt) qh->qhstat.id[qh->qhstat.next++]=name; \
|
||||
qh->qhstat.doc[name]= string; qh->qhstat.count[name]= cnt; qh->qhstat.type[name]= stype
|
||||
#if qh_KEEPstatistics
|
||||
#define zdef_(stype,name,string,cnt) qh->qhstat.id[qh->qhstat.next++]=name; \
|
||||
qh->qhstat.doc[name]= string; qh->qhstat.count[name]= cnt; qh->qhstat.type[name]= stype
|
||||
#else
|
||||
#define zdef_(type,name,doc,count)
|
||||
#endif
|
||||
|
||||
/*-<a href="qh-stat_r.htm#TOC"
|
||||
>--------------------------------</a><a name="zinc_">-</a>
|
||||
|
||||
zzinc_( name ), zinc_( name)
|
||||
increment an integer statistic
|
||||
*/
|
||||
#define zzinc_(id) {MAYdebugx; qh->qhstat.stats[id].i++;}
|
||||
#if qh_KEEPstatistics
|
||||
#define zinc_(id) {MAYdebugx; qh->qhstat.stats[id].i++;}
|
||||
#else
|
||||
#define zinc_(id) {}
|
||||
#endif
|
||||
|
||||
/*-<a href="qh-stat_r.htm#TOC"
|
||||
>--------------------------------</a><a name="zadd_">-</a>
|
||||
|
||||
zzadd_( name, value ), zadd_( name, value ), wadd_( name, value )
|
||||
add value to an integer or real statistic
|
||||
*/
|
||||
#define zzadd_(id, val) {MAYdebugx; qh->qhstat.stats[id].i += (val);}
|
||||
#define wwadd_(id, val) {MAYdebugx; qh->qhstat.stats[id].r += (val);}
|
||||
#if qh_KEEPstatistics
|
||||
#define zadd_(id, val) {MAYdebugx; qh->qhstat.stats[id].i += (val);}
|
||||
#define wadd_(id, val) {MAYdebugx; qh->qhstat.stats[id].r += (val);}
|
||||
#else
|
||||
#define zadd_(id, val) {}
|
||||
#define wadd_(id, val) {}
|
||||
#endif
|
||||
|
||||
/*-<a href="qh-stat_r.htm#TOC"
|
||||
>--------------------------------</a><a name="zval_">-</a>
|
||||
|
||||
zzval_( name ), zval_( name ), wwval_( name )
|
||||
set or return value of a statistic
|
||||
*/
|
||||
#define zzval_(id) ((qh->qhstat.stats[id]).i)
|
||||
#define wwval_(id) ((qh->qhstat.stats[id]).r)
|
||||
#if qh_KEEPstatistics
|
||||
#define zval_(id) ((qh->qhstat.stats[id]).i)
|
||||
#define wval_(id) ((qh->qhstat.stats[id]).r)
|
||||
#else
|
||||
#define zval_(id) qh->qhstat.tempi
|
||||
#define wval_(id) qh->qhstat.tempr
|
||||
#endif
|
||||
|
||||
/*-<a href="qh-stat_r.htm#TOC"
|
||||
>--------------------------------</a><a name="zmax_">-</a>
|
||||
|
||||
zmax_( id, val ), wmax_( id, value )
|
||||
maximize id with val
|
||||
*/
|
||||
#define wwmax_(id, val) {MAYdebugx; maximize_(qh->qhstat.stats[id].r,(val));}
|
||||
#if qh_KEEPstatistics
|
||||
#define zmax_(id, val) {MAYdebugx; maximize_(qh->qhstat.stats[id].i,(val));}
|
||||
#define wmax_(id, val) {MAYdebugx; maximize_(qh->qhstat.stats[id].r,(val));}
|
||||
#else
|
||||
#define zmax_(id, val) {}
|
||||
#define wmax_(id, val) {}
|
||||
#endif
|
||||
|
||||
/*-<a href="qh-stat_r.htm#TOC"
|
||||
>--------------------------------</a><a name="zmin_">-</a>
|
||||
|
||||
zmin_( id, val ), wmin_( id, value )
|
||||
minimize id with val
|
||||
*/
|
||||
#if qh_KEEPstatistics
|
||||
#define zmin_(id, val) {MAYdebugx; minimize_(qh->qhstat.stats[id].i,(val));}
|
||||
#define wmin_(id, val) {MAYdebugx; minimize_(qh->qhstat.stats[id].r,(val));}
|
||||
#else
|
||||
#define zmin_(id, val) {}
|
||||
#define wmin_(id, val) {}
|
||||
#endif
|
||||
|
||||
/*================== stat_r.h types ==============*/
|
||||
|
||||
|
||||
/*-<a href="qh-stat_r.htm#TOC"
|
||||
>--------------------------------</a><a name="intrealT">-</a>
|
||||
|
||||
intrealT
|
||||
union of integer and real, used for statistics
|
||||
*/
|
||||
typedef union intrealT intrealT; /* union of int and realT */
|
||||
union intrealT {
|
||||
int i;
|
||||
realT r;
|
||||
};
|
||||
|
||||
/*-<a href="qh-stat_r.htm#TOC"
|
||||
>--------------------------------</a><a name="qhstat">-</a>
|
||||
|
||||
qhstat
|
||||
Data structure for statistics, similar to qh and qhrbox
|
||||
|
||||
Allocated as part of qhT (libqhull_r.h)
|
||||
*/
|
||||
|
||||
struct qhstatT {
|
||||
intrealT stats[ZEND]; /* integer and real statistics */
|
||||
unsigned char id[ZEND+10]; /* id's in print order */
|
||||
const char *doc[ZEND]; /* array of documentation strings */
|
||||
short int count[ZEND]; /* -1 if none, else index of count to use */
|
||||
char type[ZEND]; /* type, see ztypes above */
|
||||
char printed[ZEND]; /* true, if statistic has been printed */
|
||||
intrealT init[ZTYPEend]; /* initial values by types, set initstatistics */
|
||||
|
||||
int next; /* next index for zdef_ */
|
||||
int precision; /* index for precision problems, printed on qh_errexit and qh_produce_output2/Q0/QJn */
|
||||
int vridges; /* index for Voronoi ridges, printed on qh_produce_output2 */
|
||||
int tempi;
|
||||
realT tempr;
|
||||
};
|
||||
|
||||
/*========== function prototypes ===========*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void qh_allstatA(qhT *qh);
|
||||
void qh_allstatB(qhT *qh);
|
||||
void qh_allstatC(qhT *qh);
|
||||
void qh_allstatD(qhT *qh);
|
||||
void qh_allstatE(qhT *qh);
|
||||
void qh_allstatE2(qhT *qh);
|
||||
void qh_allstatF(qhT *qh);
|
||||
void qh_allstatG(qhT *qh);
|
||||
void qh_allstatH(qhT *qh);
|
||||
void qh_allstatI(qhT *qh);
|
||||
void qh_allstatistics(qhT *qh);
|
||||
void qh_collectstatistics(qhT *qh);
|
||||
void qh_initstatistics(qhT *qh);
|
||||
boolT qh_newstats(qhT *qh, int idx, int *nextindex);
|
||||
boolT qh_nostatistic(qhT *qh, int i);
|
||||
void qh_printallstatistics(qhT *qh, FILE *fp, const char *string);
|
||||
void qh_printstatistics(qhT *qh, FILE *fp, const char *string);
|
||||
void qh_printstatlevel(qhT *qh, FILE *fp, int id);
|
||||
void qh_printstats(qhT *qh, FILE *fp, int idx, int *nextindex);
|
||||
realT qh_stddev(qhT *qh, int num, realT tot, realT tot2, realT *ave);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* qhDEFstat */
|
||||
@@ -0,0 +1,617 @@
|
||||
/*<html><pre> -<a href="qh-user_r.htm"
|
||||
>-------------------------------</a><a name="TOP">-</a>
|
||||
|
||||
user_r.c
|
||||
user redefinable functions
|
||||
|
||||
see user2_r.c for qh_fprintf, qh_malloc, qh_free
|
||||
|
||||
see README.txt see COPYING.txt for copyright information.
|
||||
|
||||
see libqhull_r.h for data structures, macros, and user-callable functions.
|
||||
|
||||
see user_eg_r.c, user_eg2_r.c, and unix_r.c for examples.
|
||||
|
||||
see user_r.h for user-definable constants
|
||||
|
||||
use qh_NOmem in mem_r.h to turn off memory management
|
||||
use qh_NOmerge in user_r.h to turn off facet merging
|
||||
set qh_KEEPstatistics in user_r.h to 0 to turn off statistics
|
||||
|
||||
This is unsupported software. You're welcome to make changes,
|
||||
but you're on your own if something goes wrong. Use 'Tc' to
|
||||
check frequently. Usually qhull will report an error if
|
||||
a data structure becomes inconsistent. If so, it also reports
|
||||
the last point added to the hull, e.g., 102. You can then trace
|
||||
the execution of qhull with "T4P102".
|
||||
|
||||
Please report any errors that you fix to qhull@qhull.org
|
||||
|
||||
Qhull-template is a template for calling qhull from within your application
|
||||
|
||||
if you recompile and load this module, then user.o will not be loaded
|
||||
from qhull.a
|
||||
|
||||
you can add additional quick allocation sizes in qh_user_memsizes
|
||||
|
||||
if the other functions here are redefined to not use qh_print...,
|
||||
then io.o will not be loaded from qhull.a. See user_eg_r.c for an
|
||||
example. We recommend keeping io.o for the extra debugging
|
||||
information it supplies.
|
||||
*/
|
||||
|
||||
#include "qhull_ra.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
/*-<a href="qh-user_r.htm#TOC"
|
||||
>-------------------------------</a><a name="qhull_template">-</a>
|
||||
|
||||
Qhull-template
|
||||
Template for calling qhull from inside your program
|
||||
|
||||
returns:
|
||||
exit code(see qh_ERR... in libqhull_r.h)
|
||||
all memory freed
|
||||
|
||||
notes:
|
||||
This can be called any number of times.
|
||||
*/
|
||||
#if 0
|
||||
{
|
||||
int dim; /* dimension of points */
|
||||
int numpoints; /* number of points */
|
||||
coordT *points; /* array of coordinates for each point */
|
||||
boolT ismalloc; /* True if qhull should free points in qh_freeqhull() or reallocation */
|
||||
char flags[]= "qhull Tv"; /* option flags for qhull, see html/qh-quick.htm */
|
||||
FILE *outfile= stdout; /* output from qh_produce_output
|
||||
use NULL to skip qh_produce_output */
|
||||
FILE *errfile= stderr; /* error messages from qhull code */
|
||||
int exitcode; /* 0 if no error from qhull */
|
||||
facetT *facet; /* set by FORALLfacets */
|
||||
int curlong, totlong; /* memory remaining after qh_memfreeshort */
|
||||
|
||||
qhT qh_qh; /* Qhull's data structure. First argument of most calls */
|
||||
qhT *qh= &qh_qh; /* Alternatively -- qhT *qh= (qhT *)malloc(sizeof(qhT)) */
|
||||
|
||||
QHULL_LIB_CHECK /* Check for compatible library */
|
||||
|
||||
qh_zero(qh, errfile);
|
||||
|
||||
/* initialize dim, numpoints, points[], ismalloc here */
|
||||
exitcode= qh_new_qhull(qh, dim, numpoints, points, ismalloc,
|
||||
flags, outfile, errfile);
|
||||
if (!exitcode) { /* if no error */
|
||||
/* 'qh->facet_list' contains the convex hull */
|
||||
FORALLfacets {
|
||||
/* ... your code ... */
|
||||
}
|
||||
}
|
||||
qh_freeqhull(qh, !qh_ALL);
|
||||
qh_memfreeshort(qh, &curlong, &totlong);
|
||||
if (curlong || totlong)
|
||||
qh_fprintf(qh, errfile, 7079, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n", totlong, curlong);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*-<a href="qh-user_r.htm#TOC"
|
||||
>-------------------------------</a><a name="new_qhull">-</a>
|
||||
|
||||
qh_new_qhull(qh, dim, numpoints, points, ismalloc, qhull_cmd, outfile, errfile )
|
||||
Run qhull
|
||||
Before first call, either call qh_zero(qh, errfile), or set qh to all zero.
|
||||
|
||||
returns:
|
||||
results in qh
|
||||
exitcode (0 if no errors).
|
||||
|
||||
notes:
|
||||
do not modify points until finished with results.
|
||||
The qhull data structure contains pointers into the points array.
|
||||
do not call qhull functions before qh_new_qhull().
|
||||
The qhull data structure is not initialized until qh_new_qhull().
|
||||
do not call qh_init_A (global_r.c)
|
||||
|
||||
Default errfile is stderr, outfile may be null
|
||||
qhull_cmd must start with "qhull "
|
||||
projects points to a new point array for Delaunay triangulations ('d' and 'v')
|
||||
transforms points into a new point array for halfspace intersection ('H')
|
||||
|
||||
see:
|
||||
Qhull-template at the beginning of this file.
|
||||
An example of using qh_new_qhull is user_eg_r.c
|
||||
*/
|
||||
int qh_new_qhull(qhT *qh, int dim, int numpoints, coordT *points, boolT ismalloc,
|
||||
char *qhull_cmd, FILE *outfile, FILE *errfile) {
|
||||
/* gcc may issue a "might be clobbered" warning for dim, points, and ismalloc [-Wclobbered].
|
||||
These parameters are not referenced after a longjmp() and hence not clobbered.
|
||||
See http://stackoverflow.com/questions/7721854/what-sense-do-these-clobbered-variable-warnings-make */
|
||||
int exitcode, hulldim;
|
||||
boolT new_ismalloc;
|
||||
coordT *new_points;
|
||||
|
||||
if(!errfile){
|
||||
errfile= stderr;
|
||||
}
|
||||
if (!qh->qhmem.ferr) {
|
||||
qh_meminit(qh, errfile);
|
||||
} else {
|
||||
qh_memcheck(qh);
|
||||
}
|
||||
if (strncmp(qhull_cmd, "qhull ", (size_t)6) && strcmp(qhull_cmd, "qhull") != 0) {
|
||||
qh_fprintf(qh, errfile, 6186, "qhull error (qh_new_qhull): start qhull_cmd argument with \"qhull \" or set to \"qhull\"\n");
|
||||
return qh_ERRinput;
|
||||
}
|
||||
qh_initqhull_start(qh, NULL, outfile, errfile);
|
||||
if(numpoints==0 && points==NULL){
|
||||
trace1((qh, qh->ferr, 1047, "qh_new_qhull: initialize Qhull\n"));
|
||||
return 0;
|
||||
}
|
||||
trace1((qh, qh->ferr, 1044, "qh_new_qhull: build new Qhull for %d %d-d points with %s\n", numpoints, dim, qhull_cmd));
|
||||
exitcode= setjmp(qh->errexit);
|
||||
if (!exitcode) {
|
||||
qh->NOerrexit= False;
|
||||
qh_initflags(qh, qhull_cmd);
|
||||
if (qh->DELAUNAY)
|
||||
qh->PROJECTdelaunay= True;
|
||||
if (qh->HALFspace) {
|
||||
/* points is an array of halfspaces,
|
||||
the last coordinate of each halfspace is its offset */
|
||||
hulldim= dim-1;
|
||||
qh_setfeasible(qh, hulldim);
|
||||
new_points= qh_sethalfspace_all(qh, dim, numpoints, points, qh->feasible_point);
|
||||
new_ismalloc= True;
|
||||
if (ismalloc)
|
||||
qh_free(points);
|
||||
}else {
|
||||
hulldim= dim;
|
||||
new_points= points;
|
||||
new_ismalloc= ismalloc;
|
||||
}
|
||||
qh_init_B(qh, new_points, numpoints, hulldim, new_ismalloc);
|
||||
qh_qhull(qh);
|
||||
qh_check_output(qh);
|
||||
if (outfile) {
|
||||
qh_produce_output(qh);
|
||||
}else {
|
||||
qh_prepare_output(qh);
|
||||
}
|
||||
if (qh->VERIFYoutput && !qh->FORCEoutput && !qh->STOPadd && !qh->STOPcone && !qh->STOPpoint)
|
||||
qh_check_points(qh);
|
||||
}
|
||||
qh->NOerrexit= True;
|
||||
return exitcode;
|
||||
} /* new_qhull */
|
||||
|
||||
/*-<a href="qh-user_r.htm#TOC"
|
||||
>-------------------------------</a><a name="errexit">-</a>
|
||||
|
||||
qh_errexit(qh, exitcode, facet, ridge )
|
||||
report and exit from an error
|
||||
report facet and ridge if non-NULL
|
||||
reports useful information such as last point processed
|
||||
set qh.FORCEoutput to print neighborhood of facet
|
||||
|
||||
see:
|
||||
qh_errexit2() in libqhull_r.c for printing 2 facets
|
||||
|
||||
design:
|
||||
check for error within error processing
|
||||
compute qh.hulltime
|
||||
print facet and ridge (if any)
|
||||
report commandString, options, qh.furthest_id
|
||||
print summary and statistics (including precision statistics)
|
||||
if qh_ERRsingular
|
||||
print help text for singular data set
|
||||
exit program via long jump (if defined) or exit()
|
||||
*/
|
||||
void qh_errexit(qhT *qh, int exitcode, facetT *facet, ridgeT *ridge) {
|
||||
|
||||
qh->tracefacet= NULL; /* avoid infinite recursion through qh_fprintf */
|
||||
qh->traceridge= NULL;
|
||||
qh->tracevertex= NULL;
|
||||
if (qh->ERREXITcalled) {
|
||||
qh_fprintf(qh, qh->ferr, 8126, "\nqhull error while handling previous error in qh_errexit. Exit program\n");
|
||||
qh_exit(qh_ERRother);
|
||||
}
|
||||
qh->ERREXITcalled= True;
|
||||
if (!qh->QHULLfinished)
|
||||
qh->hulltime= qh_CPUclock - qh->hulltime;
|
||||
qh_errprint(qh, "ERRONEOUS", facet, NULL, ridge, NULL);
|
||||
qh_option(qh, "_maxoutside", NULL, &qh->MAXoutside);
|
||||
qh_fprintf(qh, qh->ferr, 8127, "\nWhile executing: %s | %s\n", qh->rbox_command, qh->qhull_command);
|
||||
qh_fprintf(qh, qh->ferr, 8128, "Options selected for Qhull %s:\n%s\n", qh_version, qh->qhull_options);
|
||||
if (qh->furthest_id >= 0) {
|
||||
qh_fprintf(qh, qh->ferr, 8129, "Last point added to hull was p%d.", qh->furthest_id);
|
||||
if (zzval_(Ztotmerge))
|
||||
qh_fprintf(qh, qh->ferr, 8130, " Last merge was #%d.", zzval_(Ztotmerge));
|
||||
if (qh->QHULLfinished)
|
||||
qh_fprintf(qh, qh->ferr, 8131, "\nQhull has finished constructing the hull.");
|
||||
else if (qh->POSTmerging)
|
||||
qh_fprintf(qh, qh->ferr, 8132, "\nQhull has started post-merging.");
|
||||
qh_fprintf(qh, qh->ferr, 8133, "\n");
|
||||
}
|
||||
if (qh->FORCEoutput && (qh->QHULLfinished || (!facet && !ridge)))
|
||||
qh_produce_output(qh);
|
||||
else if (exitcode != qh_ERRinput) {
|
||||
if (exitcode != qh_ERRsingular && zzval_(Zsetplane) > qh->hull_dim+1) {
|
||||
qh_fprintf(qh, qh->ferr, 8134, "\nAt error exit:\n");
|
||||
qh_printsummary(qh, qh->ferr);
|
||||
if (qh->PRINTstatistics) {
|
||||
qh_collectstatistics(qh);
|
||||
qh_allstatistics(qh);
|
||||
qh_printstatistics(qh, qh->ferr, "at error exit");
|
||||
qh_memstatistics(qh, qh->ferr);
|
||||
}
|
||||
}
|
||||
if (qh->PRINTprecision)
|
||||
qh_printstats(qh, qh->ferr, qh->qhstat.precision, NULL);
|
||||
}
|
||||
if (!exitcode)
|
||||
exitcode= qh_ERRother;
|
||||
else if (exitcode == qh_ERRprec && !qh->PREmerge)
|
||||
qh_printhelp_degenerate(qh, qh->ferr);
|
||||
else if (exitcode == qh_ERRqhull)
|
||||
qh_printhelp_internal(qh, qh->ferr);
|
||||
else if (exitcode == qh_ERRsingular)
|
||||
qh_printhelp_singular(qh, qh->ferr);
|
||||
else if (exitcode == qh_ERRdebug)
|
||||
qh_fprintf(qh, qh->ferr, 8016, "qhull exit due to qh_ERRdebug\n");
|
||||
else if (exitcode == qh_ERRtopology || exitcode == qh_ERRwide || exitcode == qh_ERRprec) {
|
||||
if (qh->NOpremerge && !qh->MERGING)
|
||||
qh_printhelp_degenerate(qh, qh->ferr);
|
||||
else if (exitcode == qh_ERRtopology)
|
||||
qh_printhelp_topology(qh, qh->ferr);
|
||||
else if (exitcode == qh_ERRwide)
|
||||
qh_printhelp_wide(qh, qh->ferr);
|
||||
}else if (exitcode > 255) {
|
||||
qh_fprintf(qh, qh->ferr, 6426, "qhull internal error (qh_errexit): exit code %d is greater than 255. Invalid argument for exit(). Replaced with 255\n", exitcode);
|
||||
exitcode= 255;
|
||||
}
|
||||
if (qh->NOerrexit) {
|
||||
qh_fprintf(qh, qh->ferr, 6187, "qhull internal error (qh_errexit): either error while reporting error QH%d, or qh.NOerrexit not cleared after setjmp(). Exit program with error status %d\n",
|
||||
qh->last_errcode, exitcode);
|
||||
qh_exit(exitcode);
|
||||
}
|
||||
qh->ERREXITcalled= False;
|
||||
qh->NOerrexit= True;
|
||||
qh->ALLOWrestart= False; /* longjmp will undo qh_build_withrestart */
|
||||
longjmp(qh->errexit, exitcode);
|
||||
} /* errexit */
|
||||
|
||||
/*-<a href="qh-user_r.htm#TOC"
|
||||
>-------------------------------</a><a name="errprint">-</a>
|
||||
|
||||
qh_errprint(qh, fp, string, atfacet, otherfacet, atridge, atvertex )
|
||||
prints out the information of facets and ridges to fp
|
||||
also prints neighbors and geomview output
|
||||
|
||||
notes:
|
||||
except for string, any parameter may be NULL
|
||||
*/
|
||||
void qh_errprint(qhT *qh, const char *string, facetT *atfacet, facetT *otherfacet, ridgeT *atridge, vertexT *atvertex) {
|
||||
int i;
|
||||
|
||||
if (atvertex) {
|
||||
qh_fprintf(qh, qh->ferr, 8138, "%s VERTEX:\n", string);
|
||||
qh_printvertex(qh, qh->ferr, atvertex);
|
||||
}
|
||||
if (atridge) {
|
||||
qh_fprintf(qh, qh->ferr, 8137, "%s RIDGE:\n", string);
|
||||
qh_printridge(qh, qh->ferr, atridge);
|
||||
if (!atfacet)
|
||||
atfacet= atridge->top;
|
||||
if (!otherfacet)
|
||||
otherfacet= otherfacet_(atridge, atfacet);
|
||||
if (atridge->top && atridge->top != atfacet && atridge->top != otherfacet)
|
||||
qh_printfacet(qh, qh->ferr, atridge->top);
|
||||
if (atridge->bottom && atridge->bottom != atfacet && atridge->bottom != otherfacet)
|
||||
qh_printfacet(qh, qh->ferr, atridge->bottom);
|
||||
}
|
||||
if (atfacet) {
|
||||
qh_fprintf(qh, qh->ferr, 8135, "%s FACET:\n", string);
|
||||
qh_printfacet(qh, qh->ferr, atfacet);
|
||||
}
|
||||
if (otherfacet) {
|
||||
qh_fprintf(qh, qh->ferr, 8136, "%s OTHER FACET:\n", string);
|
||||
qh_printfacet(qh, qh->ferr, otherfacet);
|
||||
}
|
||||
if (qh->fout && qh->FORCEoutput && atfacet && !qh->QHULLfinished && !qh->IStracing) {
|
||||
qh_fprintf(qh, qh->ferr, 8139, "ERRONEOUS and NEIGHBORING FACETS to output\n");
|
||||
for (i=0; i < qh_PRINTEND; i++) /* use fout for geomview output */
|
||||
qh_printneighborhood(qh, qh->fout, qh->PRINTout[i], atfacet, otherfacet,
|
||||
!qh_ALL);
|
||||
}
|
||||
} /* errprint */
|
||||
|
||||
|
||||
/*-<a href="qh-user_r.htm#TOC"
|
||||
>-------------------------------</a><a name="printfacetlist">-</a>
|
||||
|
||||
qh_printfacetlist(qh, fp, facetlist, facets, printall )
|
||||
print all fields for a facet list and/or set of facets to fp
|
||||
if !printall,
|
||||
only prints good facets
|
||||
|
||||
notes:
|
||||
also prints all vertices
|
||||
*/
|
||||
void qh_printfacetlist(qhT *qh, facetT *facetlist, setT *facets, boolT printall) {
|
||||
facetT *facet, **facetp;
|
||||
|
||||
if (facetlist)
|
||||
qh_checklists(qh, facetlist);
|
||||
qh_fprintf(qh, qh->ferr, 9424, "printfacetlist: vertices\n");
|
||||
qh_printbegin(qh, qh->ferr, qh_PRINTfacets, facetlist, facets, printall);
|
||||
if (facetlist) {
|
||||
qh_fprintf(qh, qh->ferr, 9413, "printfacetlist: facetlist\n");
|
||||
FORALLfacet_(facetlist)
|
||||
qh_printafacet(qh, qh->ferr, qh_PRINTfacets, facet, printall);
|
||||
}
|
||||
if (facets) {
|
||||
qh_fprintf(qh, qh->ferr, 9414, "printfacetlist: %d facets\n", qh_setsize(qh, facets));
|
||||
FOREACHfacet_(facets)
|
||||
qh_printafacet(qh, qh->ferr, qh_PRINTfacets, facet, printall);
|
||||
}
|
||||
qh_fprintf(qh, qh->ferr, 9412, "printfacetlist: end\n");
|
||||
qh_printend(qh, qh->ferr, qh_PRINTfacets, facetlist, facets, printall);
|
||||
} /* printfacetlist */
|
||||
|
||||
|
||||
/*-<a href="qh-user_r.htm#TOC"
|
||||
>-------------------------------</a><a name="printhelp_degenerate">-</a>
|
||||
|
||||
qh_printhelp_degenerate(qh, fp )
|
||||
prints descriptive message for precision error with qh_ERRprec
|
||||
|
||||
notes:
|
||||
no message if qh_QUICKhelp
|
||||
*/
|
||||
void qh_printhelp_degenerate(qhT *qh, FILE *fp) {
|
||||
|
||||
if (qh->MERGEexact || qh->PREmerge || qh->JOGGLEmax < REALmax/2)
|
||||
qh_fprintf(qh, fp, 9368, "\n\
|
||||
A Qhull error has occurred. Qhull should have corrected the above\n\
|
||||
precision error. Please send the input and all of the output to\n\
|
||||
qhull_bug@qhull.org\n");
|
||||
else if (!qh_QUICKhelp) {
|
||||
qh_fprintf(qh, fp, 9369, "\n\
|
||||
Precision problems were detected during construction of the convex hull.\n\
|
||||
This occurs because convex hull algorithms assume that calculations are\n\
|
||||
exact, but floating-point arithmetic has roundoff errors.\n\
|
||||
\n\
|
||||
To correct for precision problems, do not use 'Q0'. By default, Qhull\n\
|
||||
selects 'C-0' or 'Qx' and merges non-convex facets. With option 'QJ',\n\
|
||||
Qhull joggles the input to prevent precision problems. See \"Imprecision\n\
|
||||
in Qhull\" (qh-impre.htm).\n\
|
||||
\n\
|
||||
If you use 'Q0', the output may include\n\
|
||||
coplanar ridges, concave ridges, and flipped facets. In 4-d and higher,\n\
|
||||
Qhull may produce a ridge with four neighbors or two facets with the same \n\
|
||||
vertices. Qhull reports these events when they occur. It stops when a\n\
|
||||
concave ridge, flipped facet, or duplicate facet occurs.\n");
|
||||
#if REALfloat
|
||||
qh_fprintf(qh, fp, 9370, "\
|
||||
\n\
|
||||
Qhull is currently using single precision arithmetic. The following\n\
|
||||
will probably remove the precision problems:\n\
|
||||
- recompile qhull for realT precision(#define REALfloat 0 in user_r.h).\n");
|
||||
#endif
|
||||
if (qh->DELAUNAY && !qh->SCALElast && qh->MAXabs_coord > 1e4)
|
||||
qh_fprintf(qh, fp, 9371, "\
|
||||
\n\
|
||||
When computing the Delaunay triangulation of coordinates > 1.0,\n\
|
||||
- use 'Qbb' to scale the last coordinate to [0,m] (max previous coordinate)\n");
|
||||
if (qh->DELAUNAY && !qh->ATinfinity)
|
||||
qh_fprintf(qh, fp, 9372, "\
|
||||
When computing the Delaunay triangulation:\n\
|
||||
- use 'Qz' to add a point at-infinity. This reduces precision problems.\n");
|
||||
|
||||
qh_fprintf(qh, fp, 9373, "\
|
||||
\n\
|
||||
If you need triangular output:\n\
|
||||
- use option 'Qt' to triangulate the output\n\
|
||||
- use option 'QJ' to joggle the input points and remove precision errors\n\
|
||||
- use option 'Ft'. It triangulates non-simplicial facets with added points.\n\
|
||||
\n\
|
||||
If you must use 'Q0',\n\
|
||||
try one or more of the following options. They can not guarantee an output.\n\
|
||||
- use 'QbB' to scale the input to a cube.\n\
|
||||
- use 'Po' to produce output and prevent partitioning for flipped facets\n\
|
||||
- use 'V0' to set min. distance to visible facet as 0 instead of roundoff\n\
|
||||
- use 'En' to specify a maximum roundoff error less than %2.2g.\n\
|
||||
- options 'Qf', 'Qbb', and 'QR0' may also help\n",
|
||||
qh->DISTround);
|
||||
qh_fprintf(qh, fp, 9374, "\
|
||||
\n\
|
||||
To guarantee simplicial output:\n\
|
||||
- use option 'Qt' to triangulate the output\n\
|
||||
- use option 'QJ' to joggle the input points and remove precision errors\n\
|
||||
- use option 'Ft' to triangulate the output by adding points\n\
|
||||
- use exact arithmetic (see \"Imprecision in Qhull\", qh-impre.htm)\n\
|
||||
");
|
||||
}
|
||||
} /* printhelp_degenerate */
|
||||
|
||||
/*-<a href="qh-user_r.htm#TOC"
|
||||
>-------------------------------</a><a name="printhelp_internal">-</a>
|
||||
|
||||
qh_printhelp_internal(qh, fp )
|
||||
prints descriptive message for qhull internal error with qh_ERRqhull
|
||||
|
||||
notes:
|
||||
no message if qh_QUICKhelp
|
||||
*/
|
||||
void qh_printhelp_internal(qhT *qh, FILE *fp) {
|
||||
|
||||
if (!qh_QUICKhelp) {
|
||||
qh_fprintf(qh, fp, 9426, "\n\
|
||||
A Qhull internal error has occurred. Please send the input and output to\n\
|
||||
qhull_bug@qhull.org. If you can duplicate the error with logging ('T4z'), please\n\
|
||||
include the log file.\n");
|
||||
}
|
||||
} /* printhelp_internal */
|
||||
|
||||
/*-<a href="qh-user_r.htm#TOC"
|
||||
>-------------------------------</a><a name="printhelp_narrowhull">-</a>
|
||||
|
||||
qh_printhelp_narrowhull(qh, minangle )
|
||||
Warn about a narrow hull
|
||||
|
||||
notes:
|
||||
Alternatively, reduce qh_WARNnarrow in user_r.h
|
||||
|
||||
*/
|
||||
void qh_printhelp_narrowhull(qhT *qh, FILE *fp, realT minangle) {
|
||||
|
||||
qh_fprintf(qh, fp, 7089, "qhull precision warning: The initial hull is narrow. Is the input lower\n\
|
||||
dimensional (e.g., a square in 3-d instead of a cube)? Cosine of the minimum\n\
|
||||
angle is %.16f. If so, Qhull may produce a wide facet.\n\
|
||||
Options 'Qs' (search all points), 'Qbb' (scale last coordinate), or\n\
|
||||
'QbB' (scale to unit box) may remove this warning.\n\
|
||||
See 'Limitations' in qh-impre.htm. Use 'Pp' to skip this warning.\n",
|
||||
-minangle); /* convert from angle between normals to angle between facets */
|
||||
} /* printhelp_narrowhull */
|
||||
|
||||
/*-<a href="qh-user_r.htm#TOC"
|
||||
>-------------------------------</a><a name="printhelp_singular">-</a>
|
||||
|
||||
qh_printhelp_singular(qh, fp )
|
||||
prints descriptive message for singular input
|
||||
*/
|
||||
void qh_printhelp_singular(qhT *qh, FILE *fp) {
|
||||
facetT *facet;
|
||||
vertexT *vertex, **vertexp;
|
||||
realT min, max, *coord, dist;
|
||||
int i,k;
|
||||
|
||||
qh_fprintf(qh, fp, 9376, "\n\
|
||||
The input to qhull appears to be less than %d dimensional, or a\n\
|
||||
computation has overflowed.\n\n\
|
||||
Qhull could not construct a clearly convex simplex from points:\n",
|
||||
qh->hull_dim);
|
||||
qh_printvertexlist(qh, fp, "", qh->facet_list, NULL, qh_ALL);
|
||||
if (!qh_QUICKhelp)
|
||||
qh_fprintf(qh, fp, 9377, "\n\
|
||||
The center point is coplanar with a facet, or a vertex is coplanar\n\
|
||||
with a neighboring facet. The maximum round off error for\n\
|
||||
computing distances is %2.2g. The center point, facets and distances\n\
|
||||
to the center point are as follows:\n\n", qh->DISTround);
|
||||
qh_printpointid(qh, fp, "center point", qh->hull_dim, qh->interior_point, qh_IDunknown);
|
||||
qh_fprintf(qh, fp, 9378, "\n");
|
||||
FORALLfacets {
|
||||
qh_fprintf(qh, fp, 9379, "facet");
|
||||
FOREACHvertex_(facet->vertices)
|
||||
qh_fprintf(qh, fp, 9380, " p%d", qh_pointid(qh, vertex->point));
|
||||
zinc_(Zdistio);
|
||||
qh_distplane(qh, qh->interior_point, facet, &dist);
|
||||
qh_fprintf(qh, fp, 9381, " distance= %4.2g\n", dist);
|
||||
}
|
||||
if (!qh_QUICKhelp) {
|
||||
if (qh->HALFspace)
|
||||
qh_fprintf(qh, fp, 9382, "\n\
|
||||
These points are the dual of the given halfspaces. They indicate that\n\
|
||||
the intersection is degenerate.\n");
|
||||
qh_fprintf(qh, fp, 9383,"\n\
|
||||
These points either have a maximum or minimum x-coordinate, or\n\
|
||||
they maximize the determinant for k coordinates. Trial points\n\
|
||||
are first selected from points that maximize a coordinate.\n");
|
||||
if (qh->hull_dim >= qh_INITIALmax)
|
||||
qh_fprintf(qh, fp, 9384, "\n\
|
||||
Because of the high dimension, the min x-coordinate and max-coordinate\n\
|
||||
points are used if the determinant is non-zero. Option 'Qs' will\n\
|
||||
do a better, though much slower, job. Instead of 'Qs', you can change\n\
|
||||
the points by randomly rotating the input with 'QR0'.\n");
|
||||
}
|
||||
qh_fprintf(qh, fp, 9385, "\nThe min and max coordinates for each dimension are:\n");
|
||||
for (k=0; k < qh->hull_dim; k++) {
|
||||
min= REALmax;
|
||||
max= -REALmax;
|
||||
for (i=qh->num_points, coord= qh->first_point+k; i--; coord += qh->hull_dim) {
|
||||
maximize_(max, *coord);
|
||||
minimize_(min, *coord);
|
||||
}
|
||||
qh_fprintf(qh, fp, 9386, " %d: %8.4g %8.4g difference= %4.4g\n", k, min, max, max-min);
|
||||
}
|
||||
if (!qh_QUICKhelp) {
|
||||
qh_fprintf(qh, fp, 9387, "\n\
|
||||
If the input should be full dimensional, you have several options that\n\
|
||||
may determine an initial simplex:\n\
|
||||
- use 'QJ' to joggle the input and make it full dimensional\n\
|
||||
- use 'QbB' to scale the points to the unit cube\n\
|
||||
- use 'QR0' to randomly rotate the input for different maximum points\n\
|
||||
- use 'Qs' to search all points for the initial simplex\n\
|
||||
- use 'En' to specify a maximum roundoff error less than %2.2g.\n\
|
||||
- trace execution with 'T3' to see the determinant for each point.\n",
|
||||
qh->DISTround);
|
||||
#if REALfloat
|
||||
qh_fprintf(qh, fp, 9388, "\
|
||||
- recompile qhull for realT precision(#define REALfloat 0 in libqhull_r.h).\n");
|
||||
#endif
|
||||
qh_fprintf(qh, fp, 9389, "\n\
|
||||
If the input is lower dimensional:\n\
|
||||
- use 'QJ' to joggle the input and make it full dimensional\n\
|
||||
- use 'Qbk:0Bk:0' to delete coordinate k from the input. You should\n\
|
||||
pick the coordinate with the least range. The hull will have the\n\
|
||||
correct topology.\n\
|
||||
- determine the flat containing the points, rotate the points\n\
|
||||
into a coordinate plane, and delete the other coordinates.\n\
|
||||
- add one or more points to make the input full dimensional.\n\
|
||||
");
|
||||
}
|
||||
} /* printhelp_singular */
|
||||
|
||||
/*-<a href="qh-user_r.htm#TOC"
|
||||
>-------------------------------</a><a name="printhelp_topology">-</a>
|
||||
|
||||
qh_printhelp_topology(qh, fp )
|
||||
prints descriptive message for qhull topology error with qh_ERRtopology
|
||||
|
||||
notes:
|
||||
no message if qh_QUICKhelp
|
||||
*/
|
||||
void qh_printhelp_topology(qhT *qh, FILE *fp) {
|
||||
|
||||
if (!qh_QUICKhelp) {
|
||||
qh_fprintf(qh, fp, 9427, "\n\
|
||||
A Qhull topology error has occurred. Qhull did not recover from facet merges and vertex merges.\n\
|
||||
This usually occurs when the input is nearly degenerate and substantial merging has occurred.\n\
|
||||
See http://www.qhull.org/html/qh-impre.htm#limit\n");
|
||||
}
|
||||
} /* printhelp_topology */
|
||||
|
||||
/*-<a href="qh-user_r.htm#TOC"
|
||||
>-------------------------------</a><a name="printhelp_wide">-</a>
|
||||
|
||||
qh_printhelp_wide(qh, fp )
|
||||
prints descriptive message for qhull wide facet with qh_ERRwide
|
||||
|
||||
notes:
|
||||
no message if qh_QUICKhelp
|
||||
*/
|
||||
void qh_printhelp_wide(qhT *qh, FILE *fp) {
|
||||
|
||||
if (!qh_QUICKhelp) {
|
||||
qh_fprintf(qh, fp, 9428, "\n\
|
||||
A wide merge error has occurred. Qhull has produced a wide facet due to facet merges and vertex merges.\n\
|
||||
This usually occurs when the input is nearly degenerate and substantial merging has occurred.\n\
|
||||
See http://www.qhull.org/html/qh-impre.htm#limit\n");
|
||||
}
|
||||
} /* printhelp_wide */
|
||||
|
||||
/*-<a href="qh-user_r.htm#TOC"
|
||||
>-------------------------------</a><a name="user_memsizes">-</a>
|
||||
|
||||
qh_user_memsizes(qh)
|
||||
allocate up to 10 additional, quick allocation sizes
|
||||
|
||||
notes:
|
||||
increase maximum number of allocations in qh_initqhull_mem()
|
||||
*/
|
||||
void qh_user_memsizes(qhT *qh) {
|
||||
|
||||
QHULL_UNUSED(qh)
|
||||
/* qh_memsize(qh, size); */
|
||||
} /* user_memsizes */
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,97 @@
|
||||
/*<html><pre> -<a href="qh-user_r.htm"
|
||||
>-------------------------------</a><a name="TOP">-</a>
|
||||
|
||||
usermem_r.c
|
||||
user redefinable functions -- qh_exit, qh_free, and qh_malloc
|
||||
|
||||
See README.txt.
|
||||
|
||||
If you redefine one of these functions you must redefine all of them.
|
||||
If you recompile and load this file, then usermem.o will not be loaded
|
||||
from qhull.a or qhull.lib
|
||||
|
||||
See libqhull_r.h for data structures, macros, and user-callable functions.
|
||||
See user_r.c for qhull-related, redefinable functions
|
||||
see user_r.h for user-definable constants
|
||||
See userprintf_r.c for qh_fprintf and userprintf_rbox_r.c for qh_fprintf_rbox
|
||||
|
||||
Please report any errors that you fix to qhull@qhull.org
|
||||
*/
|
||||
|
||||
#include "libqhull_r.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*-<a href="qh-user_r.htm#TOC"
|
||||
>-------------------------------</a><a name="qh_exit">-</a>
|
||||
|
||||
qh_exit( exitcode )
|
||||
exit program
|
||||
the exitcode must be 255 or less. Zero indicates success.
|
||||
Note: Exit status ('$?') in bash reports 256 as 0
|
||||
|
||||
notes:
|
||||
qh_exit() is called when qh_errexit() and longjmp() are not available.
|
||||
|
||||
This is the only use of exit() in Qhull
|
||||
To replace qh_exit with 'throw', see libqhullcpp/usermem_r-cpp.cpp
|
||||
*/
|
||||
void qh_exit(int exitcode) {
|
||||
exit(exitcode);
|
||||
} /* exit */
|
||||
|
||||
/*-<a href="qh-user_r.htm#TOC"
|
||||
>-------------------------------</a><a name="qh_fprintf_stderr">-</a>
|
||||
|
||||
qh_fprintf_stderr( msgcode, format, list of args )
|
||||
fprintf to stderr with msgcode (non-zero)
|
||||
|
||||
notes:
|
||||
qh_fprintf_stderr() is called when qh.ferr is not defined, usually due to an initialization error
|
||||
if msgcode is a MSG_ERROR (6000), caller should set qh.last_errcode (like qh_fprintf) or variable 'last_errcode'
|
||||
|
||||
It is typically followed by qh_errexit().
|
||||
|
||||
Redefine this function to avoid using stderr
|
||||
|
||||
Use qh_fprintf [userprintf_r.c] for normal printing
|
||||
*/
|
||||
void qh_fprintf_stderr(int msgcode, const char *fmt, ... ) {
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
if(msgcode)
|
||||
fprintf(stderr, "QH%.4d ", msgcode);
|
||||
vfprintf(stderr, fmt, args);
|
||||
va_end(args);
|
||||
} /* fprintf_stderr */
|
||||
|
||||
/*-<a href="qh-user_r.htm#TOC"
|
||||
>-------------------------------</a><a name="qh_free">-</a>
|
||||
|
||||
qh_free(qh, mem )
|
||||
free memory
|
||||
|
||||
notes:
|
||||
same as free()
|
||||
No calls to qh_errexit()
|
||||
*/
|
||||
void qh_free(void *mem) {
|
||||
free(mem);
|
||||
} /* free */
|
||||
|
||||
/*-<a href="qh-user_r.htm#TOC"
|
||||
>-------------------------------</a><a name="qh_malloc">-</a>
|
||||
|
||||
qh_malloc( mem )
|
||||
allocate memory
|
||||
|
||||
notes:
|
||||
same as malloc()
|
||||
*/
|
||||
void *qh_malloc(size_t size) {
|
||||
return malloc(size);
|
||||
} /* malloc */
|
||||
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
/*<html><pre> -<a href="qh-user_r.htm"
|
||||
>-------------------------------</a><a name="TOP">-</a>
|
||||
|
||||
userprintf_r.c
|
||||
user redefinable function -- qh_fprintf
|
||||
|
||||
see README.txt see COPYING.txt for copyright information.
|
||||
|
||||
If you recompile and load this file, then userprintf_r.o will not be loaded
|
||||
from qhull_r.a or qhull_r.lib
|
||||
|
||||
See libqhull_r.h for data structures, macros, and user-callable functions.
|
||||
See user_r.c for qhull-related, redefinable functions
|
||||
see user_r.h for user-definable constants
|
||||
See usermem_r.c for qh_exit(), qh_free(), and qh_malloc()
|
||||
see Qhull.cpp and RboxPoints.cpp for examples.
|
||||
|
||||
qh_printf is a good location for debugging traps, checked on each log line
|
||||
|
||||
Please report any errors that you fix to qhull@qhull.org
|
||||
*/
|
||||
|
||||
#include "libqhull_r.h"
|
||||
#include "poly_r.h" /* for qh.tracefacet */
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*-<a href="qh-user_r.htm#TOC"
|
||||
>-------------------------------</a><a name="qh_fprintf">-</a>
|
||||
|
||||
qh_fprintf(qh, fp, msgcode, format, list of args )
|
||||
print arguments to *fp according to format
|
||||
Use qh_fprintf_rbox() for rboxlib_r.c
|
||||
|
||||
notes:
|
||||
sets qh.last_errcode if msgcode is error 6000..6999
|
||||
same as fprintf()
|
||||
fgets() is not trapped like fprintf()
|
||||
exit qh_fprintf via qh_errexit()
|
||||
may be called for errors in qh_initstatistics and qh_meminit
|
||||
*/
|
||||
|
||||
void qh_fprintf(qhT *qh, FILE *fp, int msgcode, const char *fmt, ... ) {
|
||||
va_list args;
|
||||
facetT *neighbor, **neighborp;
|
||||
|
||||
if (!fp) {
|
||||
if(!qh){
|
||||
qh_fprintf_stderr(6241, "qhull internal error (userprintf_r.c): fp and qh not defined for qh_fprintf '%s'\n", fmt);
|
||||
qh->last_errcode= 6241;
|
||||
qh_exit(qh_ERRqhull); /* can not use qh_errexit() */
|
||||
}
|
||||
/* could use qh->qhmem.ferr, but probably better to be cautious */
|
||||
qh_fprintf_stderr(6028, "qhull internal error (userprintf_r.c): fp is 0. Wrong qh_fprintf was called.\n");
|
||||
qh->last_errcode= 6028;
|
||||
qh_errexit(qh, qh_ERRqhull, NULL, NULL);
|
||||
}
|
||||
if ((qh && qh->ANNOTATEoutput) || msgcode < MSG_TRACE4) {
|
||||
fprintf(fp, "[QH%.4d]", msgcode);
|
||||
}else if (msgcode >= MSG_ERROR && msgcode < MSG_STDERR ) {
|
||||
fprintf(fp, "QH%.4d ", msgcode);
|
||||
}
|
||||
va_start(args, fmt);
|
||||
vfprintf(fp, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
if (qh) {
|
||||
if (msgcode >= MSG_ERROR && msgcode < MSG_WARNING)
|
||||
qh->last_errcode= msgcode;
|
||||
/* Place debugging traps here. Use with trace option 'Tn'
|
||||
Set qh.tracefacet_id, qh.traceridge_id, and/or qh.tracevertex_id in global_r.c
|
||||
*/
|
||||
if (False) { /* in production skip test for debugging traps */
|
||||
if (qh->tracefacet && qh->tracefacet->tested) {
|
||||
if (qh_setsize(qh, qh->tracefacet->neighbors) < qh->hull_dim)
|
||||
qh_errexit(qh, qh_ERRdebug, qh->tracefacet, qh->traceridge);
|
||||
FOREACHneighbor_(qh->tracefacet) {
|
||||
if (neighbor != qh_DUPLICATEridge && neighbor != qh_MERGEridge && neighbor->visible)
|
||||
qh_errexit2(qh, qh_ERRdebug, qh->tracefacet, neighbor);
|
||||
}
|
||||
}
|
||||
if (qh->traceridge && qh->traceridge->top->id == 234342223) {
|
||||
qh_errexit(qh, qh_ERRdebug, qh->tracefacet, qh->traceridge);
|
||||
}
|
||||
if (qh->tracevertex && qh_setsize(qh, qh->tracevertex->neighbors)>3434334) {
|
||||
qh_errexit(qh, qh_ERRdebug, qh->tracefacet, qh->traceridge);
|
||||
}
|
||||
}
|
||||
if (qh->FLUSHprint)
|
||||
fflush(fp);
|
||||
}
|
||||
} /* qh_fprintf */
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/*<html><pre> -<a href="qh-user_r.htm"
|
||||
>-------------------------------</a><a name="TOP">-</a>
|
||||
|
||||
userprintf_rbox_r.c
|
||||
user redefinable function -- qh_fprintf_rbox
|
||||
|
||||
see README.txt see COPYING.txt for copyright information.
|
||||
|
||||
If you recompile and load this file, then userprintf_rbox_r.o will not be loaded
|
||||
from qhull.a or qhull.lib
|
||||
|
||||
See libqhull_r.h for data structures, macros, and user-callable functions.
|
||||
See user_r.c for qhull-related, redefinable functions
|
||||
see user_r.h for user-definable constants
|
||||
See usermem_r.c for qh_exit(), qh_free(), and qh_malloc()
|
||||
see Qhull.cpp and RboxPoints.cpp for examples.
|
||||
|
||||
Please report any errors that you fix to qhull@qhull.org
|
||||
*/
|
||||
|
||||
#include "libqhull_r.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*-<a href="qh-user_r.htm#TOC"
|
||||
>-------------------------------</a><a name="qh_fprintf_rbox">-</a>
|
||||
|
||||
qh_fprintf_rbox(qh, fp, msgcode, format, list of args )
|
||||
print arguments to *fp according to format
|
||||
Use qh_fprintf_rbox() for rboxlib_r.c
|
||||
|
||||
notes:
|
||||
same as fprintf()
|
||||
fgets() is not trapped like fprintf()
|
||||
exit qh_fprintf_rbox via qh_errexit_rbox()
|
||||
*/
|
||||
|
||||
void qh_fprintf_rbox(qhT *qh, FILE *fp, int msgcode, const char *fmt, ... ) {
|
||||
va_list args;
|
||||
|
||||
if (!fp) {
|
||||
qh_fprintf_stderr(6231, "qhull internal error (userprintf_rbox_r.c): fp is 0. Wrong qh_fprintf_rbox called.\n");
|
||||
qh_errexit_rbox(qh, qh_ERRqhull);
|
||||
}
|
||||
if (msgcode >= MSG_ERROR && msgcode < MSG_STDERR)
|
||||
fprintf(fp, "QH%.4d ", msgcode);
|
||||
va_start(args, fmt);
|
||||
vfprintf(fp, fmt, args);
|
||||
va_end(args);
|
||||
} /* qh_fprintf_rbox */
|
||||
|
||||
@@ -0,0 +1,209 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2009-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/Coordinates.cpp#4 $$Change: 3009 $
|
||||
** $DateTime: 2020/07/30 19:25:22 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "libqhullcpp/Coordinates.h"
|
||||
|
||||
#include "libqhullcpp/functionObjects.h"
|
||||
#include "libqhullcpp/QhullError.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
|
||||
#endif
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
#//! Coordinates -- vector of coordT (normally double)
|
||||
|
||||
#//!\name Constructor
|
||||
|
||||
#//!\name Element access
|
||||
|
||||
// Inefficient without result-value-optimization or implicitly shared object
|
||||
Coordinates Coordinates::
|
||||
mid(countT idx, countT length) const
|
||||
{
|
||||
countT newLength= length;
|
||||
if(length<0 || idx+length > count()){
|
||||
newLength= count()-idx;
|
||||
}
|
||||
Coordinates result;
|
||||
if(newLength>0){
|
||||
std::copy(begin()+idx, begin()+(idx+newLength), std::back_inserter(result));
|
||||
}
|
||||
return result;
|
||||
}//mid
|
||||
|
||||
coordT Coordinates::
|
||||
value(countT idx, const coordT &defaultValue) const
|
||||
{
|
||||
return ((idx < 0 || idx >= count()) ? defaultValue : (*this)[idx]);
|
||||
}//value
|
||||
|
||||
#//!\name GetSet
|
||||
|
||||
Coordinates Coordinates::
|
||||
operator+(const Coordinates &other) const
|
||||
{
|
||||
Coordinates result(*this);
|
||||
std::copy(other.begin(), other.end(), std::back_inserter(result));
|
||||
return result;
|
||||
}//operator+
|
||||
|
||||
Coordinates & Coordinates::
|
||||
operator+=(const Coordinates &other)
|
||||
{
|
||||
if(&other==this){
|
||||
Coordinates clone(other);
|
||||
std::copy(clone.begin(), clone.end(), std::back_inserter(*this));
|
||||
}else{
|
||||
std::copy(other.begin(), other.end(), std::back_inserter(*this));
|
||||
}
|
||||
return *this;
|
||||
}//operator+=
|
||||
|
||||
#//!\name Read-write
|
||||
|
||||
void Coordinates::
|
||||
append(int pointDimension, coordT *c)
|
||||
{
|
||||
if(c){
|
||||
coordT *p= c;
|
||||
for(int i= 0; i<pointDimension; ++i){
|
||||
coordinate_array.push_back(*p++);
|
||||
}
|
||||
}
|
||||
}//append dim coordT
|
||||
|
||||
coordT Coordinates::
|
||||
takeAt(countT idx)
|
||||
{
|
||||
coordT c= at(idx);
|
||||
erase(begin()+idx);
|
||||
return c;
|
||||
}//takeAt
|
||||
|
||||
coordT Coordinates::
|
||||
takeLast()
|
||||
{
|
||||
coordT c= last();
|
||||
removeLast();
|
||||
return c;
|
||||
}//takeLast
|
||||
|
||||
void Coordinates::
|
||||
swap(countT idx, countT other)
|
||||
{
|
||||
coordT c= at(idx);
|
||||
at(idx)= at(other);
|
||||
at(other)= c;
|
||||
}//swap
|
||||
|
||||
#//!\name Search
|
||||
|
||||
bool Coordinates::
|
||||
contains(const coordT &t) const
|
||||
{
|
||||
for(Coordinates::const_iterator i= constBegin(); i!=constEnd(); ++i){
|
||||
if(*i==t){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}//contains
|
||||
|
||||
countT Coordinates::
|
||||
count(const coordT &t) const
|
||||
{
|
||||
countT result= 0;
|
||||
for(Coordinates::const_iterator i= constBegin(); i != constEnd(); ++i){
|
||||
if(*i==t){
|
||||
++result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}//count
|
||||
|
||||
countT Coordinates::
|
||||
indexOf(const coordT &t, countT from) const
|
||||
{
|
||||
if(from<0){
|
||||
from += count();
|
||||
if(from<0){
|
||||
from= 0;
|
||||
}
|
||||
}
|
||||
if(from<count()){
|
||||
const_iterator i= begin()+from;
|
||||
while(i!=constEnd()){
|
||||
if(*i==t){
|
||||
return (static_cast<countT>(i-begin())); // WARN64 coordinate index
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}//indexOf
|
||||
|
||||
countT Coordinates::
|
||||
lastIndexOf(const coordT &t, countT from) const
|
||||
{
|
||||
countT idx;
|
||||
if(from<0){
|
||||
from += count();
|
||||
}else if(from>=count()){
|
||||
from= count()-1;
|
||||
}
|
||||
if(from>=0){
|
||||
const_iterator i= begin()+from+1;
|
||||
while(i-- != constBegin()){
|
||||
if(*i==t){
|
||||
idx= static_cast<countT>(i-begin()); // WARN64 coordinate index
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}//lastIndexOf
|
||||
|
||||
void Coordinates::
|
||||
removeAll(const coordT &t)
|
||||
{
|
||||
std::vector<coordT>::iterator i= coordinate_array.begin();
|
||||
while(i!=coordinate_array.end()){
|
||||
if(*i==t){
|
||||
i= coordinate_array.erase(i);
|
||||
}else{
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}//removeAll
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
#//!\name Global functions
|
||||
|
||||
using std::endl;
|
||||
using std::istream;
|
||||
using std::ostream;
|
||||
using std::string;
|
||||
using std::ws;
|
||||
using orgQhull::Coordinates;
|
||||
|
||||
ostream &
|
||||
operator<<(ostream &os, const Coordinates &cs)
|
||||
{
|
||||
Coordinates::const_iterator c= cs.begin();
|
||||
for(countT i=cs.count(); i--; ){
|
||||
os << *c++ << " ";
|
||||
}
|
||||
return os;
|
||||
}//operator<<
|
||||
|
||||
@@ -0,0 +1,241 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2009-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/Coordinates.h#5 $$Change: 3001 $
|
||||
** $DateTime: 2020/07/24 20:43:28 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QHCOORDINATES_H
|
||||
#define QHCOORDINATES_H
|
||||
|
||||
#include "libqhull_r/qhull_ra.h"
|
||||
#include "libqhullcpp/QhullError.h"
|
||||
|
||||
#include <cstddef> // ptrdiff_t, size_t
|
||||
#include <ostream>
|
||||
// Requires STL vector class. Can use with another vector class such as QList.
|
||||
#include <vector>
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
#//!\name Defined here
|
||||
//! An std::vector of point coordinates independent of dimension
|
||||
//! Used by PointCoordinates for RboxPoints and by Qhull for feasiblePoint
|
||||
//! A QhullPoint refers to previously allocated coordinates
|
||||
class Coordinates;
|
||||
|
||||
//! Java-style iterators are not implemented for Coordinates. std::vector has an expensive copy constructor and copy assignment.
|
||||
//! A pointer to Coordinates is vulnerable to mysterious overwrites (e.g., deleting a returned value and reusing its memory)
|
||||
//! Qt's 'foreach' should not be used. It makes a copy of the std::vector
|
||||
|
||||
class Coordinates {
|
||||
|
||||
private:
|
||||
#//!\name Fields
|
||||
std::vector<coordT> coordinate_array;
|
||||
|
||||
public:
|
||||
#//!\name Subtypes
|
||||
|
||||
class const_iterator;
|
||||
class iterator;
|
||||
typedef iterator Iterator;
|
||||
typedef const_iterator ConstIterator;
|
||||
|
||||
typedef coordT value_type;
|
||||
typedef const value_type *const_pointer;
|
||||
typedef const value_type & const_reference;
|
||||
typedef value_type * pointer;
|
||||
typedef value_type & reference;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef countT size_type;
|
||||
|
||||
#//!\name Construct
|
||||
Coordinates() : coordinate_array() {}
|
||||
explicit Coordinates(const std::vector<coordT> &other) : coordinate_array(other) {}
|
||||
Coordinates(const Coordinates &other) : coordinate_array(other.coordinate_array) {}
|
||||
Coordinates & operator=(const Coordinates &other) { coordinate_array= other.coordinate_array; return *this; }
|
||||
Coordinates & operator=(const std::vector<coordT> &other) { coordinate_array= other; return *this; }
|
||||
~Coordinates() {}
|
||||
|
||||
#//!\name Conversion
|
||||
|
||||
#ifndef QHULL_NO_STL
|
||||
std::vector<coordT> toStdVector() const { return coordinate_array; }
|
||||
#endif //QHULL_NO_STL
|
||||
#ifdef QHULL_USES_QT
|
||||
QList<coordT> toQList() const;
|
||||
#endif //QHULL_USES_QT
|
||||
|
||||
#//!\name GetSet
|
||||
countT count() const { return static_cast<countT>(size()); }
|
||||
coordT * data() { return (isEmpty() ? NULL : &at(0)); }
|
||||
const coordT * data() const { return (isEmpty() ? NULL : &at(0)); }
|
||||
bool isEmpty() const { return coordinate_array.empty(); }
|
||||
bool operator==(const Coordinates &other) const { return coordinate_array==other.coordinate_array; }
|
||||
bool operator!=(const Coordinates &other) const { return coordinate_array!=other.coordinate_array; }
|
||||
size_t size() const { return coordinate_array.size(); }
|
||||
|
||||
#//!\name Element access
|
||||
coordT & at(countT idx) { return coordinate_array.at(idx); }
|
||||
const coordT & at(countT idx) const { return coordinate_array.at(idx); }
|
||||
coordT & back() { return coordinate_array.back(); }
|
||||
const coordT & back() const { return coordinate_array.back(); }
|
||||
coordT & first() { return front(); }
|
||||
const coordT & first() const { return front(); }
|
||||
coordT & front() { return coordinate_array.front(); }
|
||||
const coordT & front() const { return coordinate_array.front(); }
|
||||
coordT & last() { return back(); }
|
||||
const coordT & last() const { return back(); }
|
||||
Coordinates mid(countT idx, countT length= -1) const; //!<\todo countT -1 indicates
|
||||
coordT & operator[](countT idx) { return coordinate_array.operator[](idx); }
|
||||
const coordT & operator[](countT idx) const { return coordinate_array.operator[](idx); }
|
||||
coordT value(countT idx, const coordT &defaultValue) const;
|
||||
|
||||
#//!\name Iterator
|
||||
iterator begin() { return iterator(coordinate_array.begin()); }
|
||||
const_iterator begin() const { return const_iterator(coordinate_array.begin()); }
|
||||
const_iterator constBegin() const { return begin(); }
|
||||
const_iterator constEnd() const { return end(); }
|
||||
iterator end() { return iterator(coordinate_array.end()); }
|
||||
const_iterator end() const { return const_iterator(coordinate_array.end()); }
|
||||
|
||||
#//!\name GetSet
|
||||
Coordinates operator+(const Coordinates &other) const;
|
||||
|
||||
#//!\name Modify
|
||||
void append(int pointDimension, coordT *c);
|
||||
void append(const coordT &c) { push_back(c); }
|
||||
void clear() { coordinate_array.clear(); }
|
||||
iterator erase(iterator idx) { return iterator(coordinate_array.erase(idx.base())); }
|
||||
iterator erase(iterator beginIterator, iterator endIterator) { return iterator(coordinate_array.erase(beginIterator.base(), endIterator.base())); }
|
||||
void insert(countT before, const coordT &c) { insert(begin()+before, c); }
|
||||
iterator insert(iterator before, const coordT &c) { return iterator(coordinate_array.insert(before.base(), c)); }
|
||||
void move(countT from, countT to) { insert(to, takeAt(from)); }
|
||||
Coordinates & operator+=(const Coordinates &other);
|
||||
Coordinates & operator+=(const coordT &c) { append(c); return *this; }
|
||||
Coordinates & operator<<(const Coordinates &other) { return *this += other; }
|
||||
Coordinates & operator<<(const coordT &c) { return *this += c; }
|
||||
void pop_back() { coordinate_array.pop_back(); }
|
||||
void pop_front() { removeFirst(); }
|
||||
void prepend(const coordT &c) { insert(begin(), c); }
|
||||
void push_back(const coordT &c) { coordinate_array.push_back(c); }
|
||||
void push_front(const coordT &c) { insert(begin(), c); }
|
||||
//removeAll below
|
||||
void removeAt(countT idx) { erase(begin()+idx); }
|
||||
void removeFirst() { erase(begin()); }
|
||||
void removeLast() { erase(--end()); }
|
||||
void replace(countT idx, const coordT &c) { (*this)[idx]= c; }
|
||||
void reserve(countT i) { coordinate_array.reserve(i); }
|
||||
void swap(countT idx, countT other);
|
||||
coordT takeAt(countT idx);
|
||||
coordT takeFirst() { return takeAt(0); }
|
||||
coordT takeLast();
|
||||
|
||||
#//!\name Search
|
||||
bool contains(const coordT &t) const;
|
||||
countT count(const coordT &t) const;
|
||||
countT indexOf(const coordT &t, countT from= 0) const;
|
||||
countT lastIndexOf(const coordT &t, countT from= -1) const;
|
||||
void removeAll(const coordT &t);
|
||||
|
||||
#//!\name Coordinates::iterator -- from QhullPoints, forwarding to coordinate_array
|
||||
// before const_iterator for conversion with comparison operators
|
||||
// Reviewed corelib/tools/qlist.h and corelib/tools/qvector.h w/o QT_STRICT_ITERATORS
|
||||
class iterator {
|
||||
|
||||
private:
|
||||
std::vector<coordT>::iterator i;
|
||||
friend class const_iterator;
|
||||
|
||||
public:
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
typedef coordT value_type;
|
||||
typedef value_type *pointer;
|
||||
typedef value_type &reference;
|
||||
typedef ptrdiff_t difference_type;
|
||||
|
||||
iterator() : i() {}
|
||||
iterator(const iterator &other) : i() { i= other.i; }
|
||||
explicit iterator(const std::vector<coordT>::iterator &vi) : i() { i= vi; }
|
||||
iterator & operator=(const iterator &other) { i= other.i; return *this; }
|
||||
std::vector<coordT>::iterator &base() { return i; }
|
||||
coordT & operator*() const { return *i; }
|
||||
// No operator->() when the base type is double
|
||||
coordT & operator[](countT idx) const { return i[idx]; }
|
||||
|
||||
bool operator==(const iterator &other) const { return i==other.i; }
|
||||
bool operator!=(const iterator &other) const { return i!=other.i; }
|
||||
bool operator<(const iterator &other) const { return i<other.i; }
|
||||
bool operator<=(const iterator &other) const { return i<=other.i; }
|
||||
bool operator>(const iterator &other) const { return i>other.i; }
|
||||
bool operator>=(const iterator &other) const { return i>=other.i; }
|
||||
// reinterpret_cast to break circular dependency
|
||||
bool operator==(const Coordinates::const_iterator &other) const { return *this==reinterpret_cast<const iterator &>(other); }
|
||||
bool operator!=(const Coordinates::const_iterator &other) const { return *this!=reinterpret_cast<const iterator &>(other); }
|
||||
bool operator<(const Coordinates::const_iterator &other) const { return *this<reinterpret_cast<const iterator &>(other); }
|
||||
bool operator<=(const Coordinates::const_iterator &other) const { return *this<=reinterpret_cast<const iterator &>(other); }
|
||||
bool operator>(const Coordinates::const_iterator &other) const { return *this>reinterpret_cast<const iterator &>(other); }
|
||||
bool operator>=(const Coordinates::const_iterator &other) const { return *this>=reinterpret_cast<const iterator &>(other); }
|
||||
|
||||
iterator & operator++() { ++i; return *this; }
|
||||
iterator operator++(int) { return iterator(i++); }
|
||||
iterator & operator--() { --i; return *this; }
|
||||
iterator operator--(int) { return iterator(i--); }
|
||||
iterator & operator+=(countT idx) { i += idx; return *this; }
|
||||
iterator & operator-=(countT idx) { i -= idx; return *this; }
|
||||
iterator operator+(countT idx) const { return iterator(i+idx); }
|
||||
iterator operator-(countT idx) const { return iterator(i-idx); }
|
||||
difference_type operator-(iterator other) const { return i-other.i; }
|
||||
};//Coordinates::iterator
|
||||
|
||||
#//!\name Coordinates::const_iterator
|
||||
class const_iterator {
|
||||
|
||||
private:
|
||||
std::vector<coordT>::const_iterator i;
|
||||
|
||||
public:
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
typedef coordT value_type;
|
||||
typedef const value_type *pointer;
|
||||
typedef const value_type &reference;
|
||||
typedef ptrdiff_t difference_type;
|
||||
|
||||
const_iterator() : i() {}
|
||||
const_iterator(const const_iterator &other) : i() { i= other.i; }
|
||||
const_iterator(const iterator &o) : i(o.i) {}
|
||||
explicit const_iterator(const std::vector<coordT>::const_iterator &vi) : i() { i= vi; }
|
||||
const_iterator &operator=(const const_iterator &other) { i= other.i; return *this; }
|
||||
const coordT & operator*() const { return *i; }
|
||||
// No operator->() when the base type is double
|
||||
const coordT & operator[](countT idx) const { return i[idx]; }
|
||||
|
||||
bool operator==(const const_iterator &other) const { return i==other.i; }
|
||||
bool operator!=(const const_iterator &other) const { return i!=other.i; }
|
||||
bool operator<(const const_iterator &other) const { return i<other.i; }
|
||||
bool operator<=(const const_iterator &other) const { return i<=other.i; }
|
||||
bool operator>(const const_iterator &other) const { return i>other.i; }
|
||||
bool operator>=(const const_iterator &other) const { return i>=other.i; }
|
||||
|
||||
const_iterator & operator++() { ++i; return *this; }
|
||||
const_iterator operator++(int) { return const_iterator(i++); }
|
||||
const_iterator & operator--() { --i; return *this; }
|
||||
const_iterator operator--(int) { return const_iterator(i--); }
|
||||
const_iterator & operator+=(countT idx) { i += idx; return *this; }
|
||||
const_iterator & operator-=(countT idx) { i -= idx; return *this; }
|
||||
const_iterator operator+(countT idx) const { return const_iterator(i+idx); }
|
||||
const_iterator operator-(countT idx) const { return const_iterator(i-idx); }
|
||||
difference_type operator-(const_iterator other) const { return i-other.i; }
|
||||
};//Coordinates::const_iterator
|
||||
|
||||
};//Coordinates
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
#//!\name Global
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const orgQhull::Coordinates &c);
|
||||
|
||||
#endif // QHCOORDINATES_H
|
||||
@@ -0,0 +1,349 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2009-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/PointCoordinates.cpp#3 $$Change: 2961 $
|
||||
** $DateTime: 2020/06/01 22:17:03 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "libqhullcpp/PointCoordinates.h"
|
||||
|
||||
#include "libqhullcpp/QhullError.h"
|
||||
#include "libqhullcpp/QhullPoint.h"
|
||||
|
||||
#include <iterator>
|
||||
#include <iostream>
|
||||
|
||||
using std::istream;
|
||||
using std::string;
|
||||
using std::ws;
|
||||
|
||||
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
|
||||
#pragma warning( disable : 4996) // function was declared deprecated(strcpy, localtime, etc.)
|
||||
#endif
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
#//! PointCoordinates -- vector of PointCoordinates
|
||||
|
||||
#//!\name Constructors
|
||||
|
||||
PointCoordinates::
|
||||
PointCoordinates()
|
||||
: QhullPoints()
|
||||
, point_coordinates()
|
||||
, describe_points()
|
||||
{
|
||||
}
|
||||
|
||||
PointCoordinates::
|
||||
PointCoordinates(const std::string &aComment)
|
||||
: QhullPoints()
|
||||
, point_coordinates()
|
||||
, describe_points(aComment)
|
||||
{
|
||||
}
|
||||
|
||||
PointCoordinates::
|
||||
PointCoordinates(int pointDimension, const std::string &aComment)
|
||||
: QhullPoints()
|
||||
, point_coordinates()
|
||||
, describe_points(aComment)
|
||||
{
|
||||
setDimension(pointDimension);
|
||||
}
|
||||
|
||||
//! Qhull and QhullQh constructors are the same
|
||||
PointCoordinates::
|
||||
PointCoordinates(const Qhull &q)
|
||||
: QhullPoints(q)
|
||||
, point_coordinates()
|
||||
, describe_points()
|
||||
{
|
||||
}
|
||||
|
||||
PointCoordinates::
|
||||
PointCoordinates(const Qhull &q, const std::string &aComment)
|
||||
: QhullPoints(q)
|
||||
, point_coordinates()
|
||||
, describe_points(aComment)
|
||||
{
|
||||
}
|
||||
|
||||
PointCoordinates::
|
||||
PointCoordinates(const Qhull &q, int pointDimension, const std::string &aComment)
|
||||
: QhullPoints(q)
|
||||
, point_coordinates()
|
||||
, describe_points(aComment)
|
||||
{
|
||||
setDimension(pointDimension);
|
||||
}
|
||||
|
||||
PointCoordinates::
|
||||
PointCoordinates(const Qhull &q, int pointDimension, const std::string &aComment, countT coordinatesCount, const coordT *c)
|
||||
: QhullPoints(q)
|
||||
, point_coordinates()
|
||||
, describe_points(aComment)
|
||||
{
|
||||
setDimension(pointDimension);
|
||||
append(coordinatesCount, c);
|
||||
}
|
||||
|
||||
PointCoordinates::
|
||||
PointCoordinates(QhullQh *qqh)
|
||||
: QhullPoints(qqh)
|
||||
, point_coordinates()
|
||||
, describe_points()
|
||||
{
|
||||
}
|
||||
|
||||
PointCoordinates::
|
||||
PointCoordinates(QhullQh *qqh, const std::string &aComment)
|
||||
: QhullPoints(qqh)
|
||||
, point_coordinates()
|
||||
, describe_points(aComment)
|
||||
{
|
||||
}
|
||||
|
||||
PointCoordinates::
|
||||
PointCoordinates(QhullQh *qqh, int pointDimension, const std::string &aComment)
|
||||
: QhullPoints(qqh)
|
||||
, point_coordinates()
|
||||
, describe_points(aComment)
|
||||
{
|
||||
setDimension(pointDimension);
|
||||
}
|
||||
|
||||
PointCoordinates::
|
||||
PointCoordinates(QhullQh *qqh, int pointDimension, const std::string &aComment, countT coordinatesCount, const coordT *c)
|
||||
: QhullPoints(qqh)
|
||||
, point_coordinates()
|
||||
, describe_points(aComment)
|
||||
{
|
||||
setDimension(pointDimension);
|
||||
append(coordinatesCount, c);
|
||||
}
|
||||
|
||||
PointCoordinates::
|
||||
PointCoordinates(const PointCoordinates &other)
|
||||
: QhullPoints(other)
|
||||
, point_coordinates(other.point_coordinates)
|
||||
, describe_points(other.describe_points)
|
||||
{
|
||||
makeValid(); // Update point_first and point_end
|
||||
}
|
||||
|
||||
PointCoordinates & PointCoordinates::
|
||||
operator=(const PointCoordinates &other)
|
||||
{
|
||||
QhullPoints::operator=(other);
|
||||
point_coordinates= other.point_coordinates;
|
||||
describe_points= other.describe_points;
|
||||
makeValid(); // Update point_first and point_end
|
||||
return *this;
|
||||
}//operator=
|
||||
|
||||
PointCoordinates::
|
||||
~PointCoordinates()
|
||||
{ }
|
||||
|
||||
#//!\name GetSet
|
||||
|
||||
void PointCoordinates::
|
||||
checkValid() const
|
||||
{
|
||||
if(getCoordinates().data()!=data()
|
||||
|| getCoordinates().count()!=coordinateCount()){
|
||||
throw QhullError(10060, "Qhull error: first point (%x) is not PointCoordinates.data() or count (%d) is not PointCoordinates.count (%d)", coordinateCount(), getCoordinates().count(), 0.0, data());
|
||||
}
|
||||
}//checkValid
|
||||
|
||||
void PointCoordinates::
|
||||
setDimension(int i)
|
||||
{
|
||||
if(i<0){
|
||||
throw QhullError(10062, "Qhull error: can not set PointCoordinates dimension to %d", i);
|
||||
}
|
||||
int currentDimension= dimension(); // QhullPoints
|
||||
if(currentDimension!=0 && i!=currentDimension){
|
||||
throw QhullError(10063, "Qhull error: can not change PointCoordinates dimension (from %d to %d)", currentDimension, i);
|
||||
}
|
||||
QhullPoints::setDimension(i);
|
||||
}//setDimension
|
||||
|
||||
#//!\name Foreach
|
||||
|
||||
Coordinates::ConstIterator PointCoordinates::
|
||||
beginCoordinates(countT pointIndex) const
|
||||
{
|
||||
return point_coordinates.begin()+indexOffset(pointIndex);
|
||||
}
|
||||
|
||||
Coordinates::Iterator PointCoordinates::
|
||||
beginCoordinates(countT pointIndex)
|
||||
{
|
||||
return point_coordinates.begin()+indexOffset(pointIndex);
|
||||
}
|
||||
|
||||
#//!\name Methods
|
||||
|
||||
void PointCoordinates::
|
||||
append(countT coordinatesCount, const coordT *c)
|
||||
{
|
||||
if(coordinatesCount<=0){
|
||||
return;
|
||||
}
|
||||
if(includesCoordinates(c)){
|
||||
throw QhullError(10065, "Qhull error: can not append a subset of PointCoordinates to itself. The coordinates for point %d may move.", indexOf(c, QhullError::NOthrow));
|
||||
}
|
||||
reserveCoordinates(coordinatesCount);
|
||||
std::copy(c, c+coordinatesCount, std::back_inserter(point_coordinates));
|
||||
makeValid();
|
||||
}//append coordT
|
||||
|
||||
void PointCoordinates::
|
||||
append(const PointCoordinates &other)
|
||||
{
|
||||
setDimension(other.dimension());
|
||||
append(other.coordinateCount(), other.data());
|
||||
}//append PointCoordinates
|
||||
|
||||
void PointCoordinates::
|
||||
append(const QhullPoint &p)
|
||||
{
|
||||
setDimension(p.dimension());
|
||||
append(p.dimension(), p.coordinates());
|
||||
}//append QhullPoint
|
||||
|
||||
void PointCoordinates::
|
||||
appendComment(const std::string &s){
|
||||
if(char c= s[0] && describe_points.empty()){
|
||||
if(c=='-' || isdigit(c)){
|
||||
throw QhullError(10028, "Qhull argument error: comments can not start with a number or minus, %s", 0, 0, 0.0, s.c_str());
|
||||
}
|
||||
}
|
||||
describe_points += s;
|
||||
}//appendComment
|
||||
|
||||
//! Read PointCoordinates from istream. First two numbers are dimension and count. A non-digit starts a rboxCommand.
|
||||
//! Overwrites describe_points. See qh_readpoints [io.c]
|
||||
void PointCoordinates::
|
||||
appendPoints(istream &in)
|
||||
{
|
||||
int inDimension;
|
||||
countT inCount;
|
||||
in >> ws >> inDimension >> ws;
|
||||
if(!in.good()){
|
||||
in.clear();
|
||||
string remainder;
|
||||
getline(in, remainder);
|
||||
throw QhullError(10005, "Qhull error: input did not start with dimension or count -- %s", 0, 0, 0, remainder.c_str());
|
||||
}
|
||||
char c= static_cast<char>(in.peek());
|
||||
if(c!='-' && !isdigit(c)){ // Comments start with a non-digit
|
||||
getline(in, describe_points);
|
||||
in >> ws;
|
||||
}
|
||||
in >> inCount >> ws;
|
||||
if(!in.good()){
|
||||
in.clear();
|
||||
string remainder;
|
||||
getline(in, remainder);
|
||||
throw QhullError(10009, "Qhull error: input did not start with dimension and count -- %d %s", inDimension, 0, 0, remainder.c_str());
|
||||
}
|
||||
c= static_cast<char>(in.peek());
|
||||
if(c!='-' && !isdigit(c)){ // Comments start with a non-digit
|
||||
getline(in, describe_points);
|
||||
in >> ws;
|
||||
}
|
||||
if(inCount<inDimension){ // Count may precede dimension
|
||||
std::swap(inCount, inDimension);
|
||||
}
|
||||
setDimension(inDimension);
|
||||
reserveCoordinates(inCount*inDimension);
|
||||
countT coordinatesCount= 0;
|
||||
while(!in.eof()){
|
||||
realT p;
|
||||
in >> p;
|
||||
if(in.fail()){
|
||||
in.clear();
|
||||
string remainder;
|
||||
getline(in, remainder);
|
||||
throw QhullError(10008, "Qhull error: failed to read coordinate %d of point %d\n '%s'", coordinatesCount % inDimension, coordinatesCount/inDimension, 0, remainder.c_str());
|
||||
}else{
|
||||
point_coordinates.push_back(p);
|
||||
coordinatesCount++;
|
||||
}
|
||||
in >> ws;
|
||||
}
|
||||
if(coordinatesCount != inCount*inDimension){
|
||||
if(coordinatesCount%inDimension==0){
|
||||
throw QhullError(10006, "Qhull error: expected %d %d-d PointCoordinates but read %i PointCoordinates", int(inCount), inDimension, 0.0, int(coordinatesCount/inDimension));
|
||||
}else{
|
||||
throw QhullError(10012, "Qhull error: expected %d %d-d PointCoordinates but read %i PointCoordinates plus %f extra coordinates", inCount, inDimension, float(coordinatesCount%inDimension), coordinatesCount/inDimension);
|
||||
}
|
||||
}
|
||||
makeValid();
|
||||
}//appendPoints istream
|
||||
|
||||
PointCoordinates PointCoordinates::
|
||||
operator+(const PointCoordinates &other) const
|
||||
{
|
||||
PointCoordinates pc= *this;
|
||||
pc << other;
|
||||
return pc;
|
||||
}//operator+
|
||||
|
||||
void PointCoordinates::
|
||||
reserveCoordinates(countT newCoordinates)
|
||||
{
|
||||
// vector::reserve is not const
|
||||
point_coordinates.reserve(static_cast<countT>(point_coordinates.size()+newCoordinates)); // WARN64
|
||||
makeValid();
|
||||
}//reserveCoordinates
|
||||
|
||||
#//!\name Helpers
|
||||
|
||||
countT PointCoordinates::
|
||||
indexOffset(countT i) const {
|
||||
countT n= i*dimension();
|
||||
countT coordinatesCount= point_coordinates.count();
|
||||
if(i<0 || n>coordinatesCount){
|
||||
throw QhullError(10061, "Qhull error: point_coordinates is too short (%d) for point %d", coordinatesCount, i);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
#//!\name Global functions
|
||||
|
||||
using std::endl;
|
||||
using std::ostream;
|
||||
|
||||
using orgQhull::Coordinates;
|
||||
using orgQhull::PointCoordinates;
|
||||
|
||||
ostream&
|
||||
operator<<(ostream &os, const PointCoordinates &p)
|
||||
{
|
||||
p.checkValid();
|
||||
countT count= p.count();
|
||||
int dimension= p.dimension();
|
||||
string comment= p.comment();
|
||||
if(comment.empty()){
|
||||
os << dimension << endl;
|
||||
}else{
|
||||
os << dimension << " " << comment << endl;
|
||||
}
|
||||
os << count << endl;
|
||||
Coordinates::ConstIterator c= p.beginCoordinates();
|
||||
for(countT i=0; i<count; i++){
|
||||
for(int j=0; j<dimension; j++){
|
||||
os << *c++ << " ";
|
||||
}
|
||||
os << endl;
|
||||
}
|
||||
return os;
|
||||
}//operator<<
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2009-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/PointCoordinates.h#6 $$Change: 3001 $
|
||||
** $DateTime: 2020/07/24 20:43:28 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QHPOINTCOORDINATES_H
|
||||
#define QHPOINTCOORDINATES_H
|
||||
|
||||
#include "libqhull_r/qhull_ra.h"
|
||||
#include "libqhullcpp/QhullPoints.h"
|
||||
#include "libqhullcpp/Coordinates.h"
|
||||
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
|
||||
#ifndef QHULL_NO_STL
|
||||
#include <vector>
|
||||
#endif
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
#//!\name Defined here
|
||||
//! QhullPoints with Coordinates and description
|
||||
//! Inherited by RboxPoints
|
||||
class PointCoordinates;
|
||||
|
||||
//! Java-style iterators are not implemented for PointCoordinates. Expensive copy constructor and copy assignment for Coordinates (std::vector).
|
||||
//! A pointer to PointCoordinates is vulnerable to mysterious overwrites (e.g., deleting a returned value and reusing its memory)
|
||||
//! 'foreach' likewise makes a copy of point_coordinates and should be avoided
|
||||
|
||||
class PointCoordinates : public QhullPoints {
|
||||
|
||||
private:
|
||||
#//!\name Fields
|
||||
Coordinates point_coordinates; //! std::vector of point coordinates
|
||||
//! may have extraCoordinates()
|
||||
std::string describe_points; //! Comment describing PointCoordinates
|
||||
|
||||
public:
|
||||
#//!\name Construct
|
||||
//! QhullPoint, PointCoordinates, and QhullPoints have similar constructors
|
||||
//! If Qhull/QhullQh is not initialized, then dimension()==0 PointCoordinates();
|
||||
PointCoordinates();
|
||||
explicit PointCoordinates(const std::string &aComment);
|
||||
PointCoordinates(int pointDimension, const std::string &aComment);
|
||||
//! Qhull/QhullQh used for dimension() and QhullPoint equality
|
||||
explicit PointCoordinates(const Qhull &q);
|
||||
PointCoordinates(const Qhull &q, const std::string &aComment);
|
||||
PointCoordinates(const Qhull &q, int pointDimension, const std::string &aComment);
|
||||
PointCoordinates(const Qhull &q, int pointDimension, const std::string &aComment, countT coordinatesCount, const coordT *c); // may be invalid
|
||||
//! Use append() and appendPoints() for Coordinates and vector<coordT>
|
||||
explicit PointCoordinates(QhullQh *qqh);
|
||||
PointCoordinates(QhullQh *qqh, const std::string &aComment);
|
||||
PointCoordinates(QhullQh *qqh, int pointDimension, const std::string &aComment);
|
||||
PointCoordinates(QhullQh *qqh, int pointDimension, const std::string &aComment, countT coordinatesCount, const coordT *c); // may be invalid
|
||||
//! Use append() and appendPoints() for Coordinates and vector<coordT>
|
||||
PointCoordinates(const PointCoordinates &other);
|
||||
PointCoordinates & operator=(const PointCoordinates &other);
|
||||
~PointCoordinates();
|
||||
|
||||
#//!\name Convert
|
||||
//! QhullPoints coordinates, constData, data, count, size
|
||||
#ifndef QHULL_NO_STL
|
||||
void append(const std::vector<coordT> &otherCoordinates) { if(!otherCoordinates.empty()){ append(static_cast<int>(otherCoordinates.size()), &otherCoordinates[0]); } }
|
||||
std::vector<coordT> toStdVector() const { return point_coordinates.toStdVector(); }
|
||||
#endif //QHULL_NO_STL
|
||||
#ifdef QHULL_USES_QT
|
||||
void append(const QList<coordT> &pointCoordinates) { if(!pointCoordinates.isEmpty()){ append(pointCoordinates.count(), &pointCoordinates[0]); } }
|
||||
QList<coordT> toQList() const { return point_coordinates.toQList(); }
|
||||
#endif //QHULL_USES_QT
|
||||
|
||||
#//!\name GetSet
|
||||
//! See QhullPoints for coordinates, coordinateCount, dimension, empty, isEmpty, ==, !=
|
||||
void checkValid() const;
|
||||
std::string comment() const { return describe_points; }
|
||||
void makeValid() { defineAs(point_coordinates.count(), point_coordinates.data()); }
|
||||
const Coordinates & getCoordinates() const { return point_coordinates; }
|
||||
void setComment(const std::string &s) { describe_points= s; }
|
||||
void setDimension(int i);
|
||||
|
||||
private:
|
||||
//! disable QhullPoints.defineAs()
|
||||
void defineAs(countT coordinatesCount, coordT *c) { QhullPoints::defineAs(coordinatesCount, c); }
|
||||
public:
|
||||
|
||||
#//!\name ElementAccess
|
||||
//! See QhullPoints for at, back, first, front, last, mid, [], value
|
||||
|
||||
#//!\name Foreach
|
||||
//! See QhullPoints for begin, constBegin, end
|
||||
Coordinates::ConstIterator beginCoordinates() const { return point_coordinates.begin(); }
|
||||
Coordinates::Iterator beginCoordinates() { return point_coordinates.begin(); }
|
||||
Coordinates::ConstIterator beginCoordinates(countT pointIndex) const;
|
||||
Coordinates::Iterator beginCoordinates(countT pointIndex);
|
||||
Coordinates::ConstIterator endCoordinates() const { return point_coordinates.end(); }
|
||||
Coordinates::Iterator endCoordinates() { return point_coordinates.end(); }
|
||||
|
||||
#//!\name Search
|
||||
//! See QhullPoints for contains, count, indexOf, lastIndexOf
|
||||
|
||||
#//!\name GetSet
|
||||
PointCoordinates operator+(const PointCoordinates &other) const;
|
||||
|
||||
#//!\name Modify
|
||||
// QH11001 FIX: Add clear() and other modify operators from Coordinates.h. Include QhullPoint::operator=()
|
||||
void append(countT coordinatesCount, const coordT *c); //! Dimension previously defined
|
||||
void append(const coordT &c) { append(1, &c); } //! Dimension previously defined
|
||||
void append(const QhullPoint &p);
|
||||
//! See convert for std::vector and QList
|
||||
void append(const Coordinates &c) { append(c.count(), c.data()); }
|
||||
void append(const PointCoordinates &other);
|
||||
void appendComment(const std::string &s);
|
||||
void appendPoints(std::istream &in);
|
||||
PointCoordinates & operator+=(const PointCoordinates &other) { append(other); return *this; }
|
||||
PointCoordinates & operator+=(const coordT &c) { append(c); return *this; }
|
||||
PointCoordinates & operator+=(const QhullPoint &p) { append(p); return *this; }
|
||||
PointCoordinates & operator<<(const PointCoordinates &other) { return *this += other; }
|
||||
PointCoordinates & operator<<(const coordT &c) { return *this += c; }
|
||||
PointCoordinates & operator<<(const QhullPoint &p) { return *this += p; }
|
||||
// reserve() is non-const
|
||||
void reserveCoordinates(countT newCoordinates);
|
||||
|
||||
#//!\name Helpers
|
||||
private:
|
||||
int indexOffset(int i) const;
|
||||
|
||||
};//PointCoordinates
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
#//!\name Global
|
||||
|
||||
std::ostream & operator<<(std::ostream &os, const orgQhull::PointCoordinates &p);
|
||||
|
||||
#endif // QHPOINTCOORDINATES_H
|
||||
@@ -0,0 +1,377 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/Qhull.cpp#12 $$Change: 3009 $
|
||||
** $DateTime: 2020/07/30 19:25:22 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#//! Qhull -- invoke qhull from C++
|
||||
#//! Compile libqhull_r and Qhull together due to use of setjmp/longjmp()
|
||||
|
||||
#include "libqhullcpp/Qhull.h"
|
||||
|
||||
#include "libqhullcpp/QhullError.h"
|
||||
#include "libqhullcpp/RboxPoints.h"
|
||||
#include "libqhullcpp/QhullQh.h"
|
||||
#include "libqhullcpp/QhullFacet.h"
|
||||
#include "libqhullcpp/QhullFacetList.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using std::cerr;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using std::ostream;
|
||||
|
||||
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
|
||||
#pragma warning( disable : 4611) // interaction between '_setjmp' and C++ object destruction is non-portable
|
||||
#pragma warning( disable : 4996) // function was declared deprecated(strcpy, localtime, etc.)
|
||||
#endif
|
||||
|
||||
namespace orgQhull{
|
||||
|
||||
#//!\name Global variables
|
||||
|
||||
const char s_unsupported_options[]=" Fd TI ";
|
||||
const char s_not_output_options[]= " Fd TI A C d E H P Qa Qb QbB Qbb Qc Qf Qg Qi Qm QJ Qr QR Qs Qt Qv Qx Qz Q0 Q1 Q2 Q3 Q4 Q5 Q6 Q7 Q8 Q9 Q10 Q11 Q15 R TA Tc TC TM TP TR Tv TV TW U v V W ";
|
||||
|
||||
#//!\name Constructor, destructor, etc.
|
||||
Qhull::
|
||||
Qhull()
|
||||
: qh_qh(0)
|
||||
, origin_point()
|
||||
, run_called(false)
|
||||
, feasible_point()
|
||||
{
|
||||
allocateQhullQh();
|
||||
}//Qhull
|
||||
|
||||
//! Invokes Qhull on rboxPoints
|
||||
//! Same as runQhull()
|
||||
//! For rbox commands, see http://www.qhull.org/html/rbox.htm or html/rbox.htm
|
||||
//! For qhull commands, see http://www.qhull.org/html/qhull.htm or html/qhull.htm
|
||||
Qhull::
|
||||
Qhull(const RboxPoints &rboxPoints, const char *qhullCommand2)
|
||||
: qh_qh(0)
|
||||
, origin_point()
|
||||
, run_called(false)
|
||||
, feasible_point()
|
||||
{
|
||||
allocateQhullQh();
|
||||
runQhull(rboxPoints, qhullCommand2);
|
||||
}//Qhull rbox
|
||||
|
||||
//! Invokes Qhull on a set of input points
|
||||
//! Same as runQhull()
|
||||
//! For qhull commands, see http://www.qhull.org/html/qhull.htm or html/qhull.htm
|
||||
Qhull::
|
||||
Qhull(const char *inputComment2, int pointDimension, int pointCount, const realT *pointCoordinates, const char *qhullCommand2)
|
||||
: qh_qh(0)
|
||||
, origin_point()
|
||||
, run_called(false)
|
||||
, feasible_point()
|
||||
{
|
||||
allocateQhullQh();
|
||||
runQhull(inputComment2, pointDimension, pointCount, pointCoordinates, qhullCommand2);
|
||||
}//Qhull points
|
||||
|
||||
void Qhull::
|
||||
allocateQhullQh()
|
||||
{
|
||||
QHULL_LIB_CHECK /* Check for compatible library */
|
||||
|
||||
qh_qh= new QhullQh;
|
||||
void *p= qh_qh;
|
||||
void *p2= static_cast<qhT *>(qh_qh);
|
||||
char *s= static_cast<char *>(p);
|
||||
char *s2= static_cast<char *>(p2);
|
||||
if(s!=s2){
|
||||
throw QhullError(10074, "Qhull error: QhullQh at a different address than base type QhT (%d bytes). Please report compiler to qhull.org", int(s2-s));
|
||||
}
|
||||
}//allocateQhullQh
|
||||
|
||||
Qhull::
|
||||
~Qhull() throw()
|
||||
{
|
||||
// Except for cerr, does not throw errors
|
||||
if(qh_qh->hasQhullMessage()){
|
||||
cerr<< "\nQhull messages at ~Qhull()\n"; // QH11005 FIX: where should error and log messages go on ~Qhull?
|
||||
cerr<< qh_qh->qhullMessage();
|
||||
qh_qh->clearQhullMessage();
|
||||
}
|
||||
delete qh_qh;
|
||||
qh_qh= 0;
|
||||
}//~Qhull
|
||||
|
||||
#//!\name GetSet
|
||||
|
||||
void Qhull::
|
||||
checkIfQhullInitialized()
|
||||
{
|
||||
if(!initialized()){ // qh_initqhull_buffers() not called
|
||||
throw QhullError(10023, "Qhull error: checkIfQhullInitialized failed. Call runQhull() first.");
|
||||
}
|
||||
}//checkIfQhullInitialized
|
||||
|
||||
//! Return feasiblePoint for halfspace intersection
|
||||
//! If called before runQhull(), then it returns the value from setFeasiblePoint. qh.feasible_string overrides this value if it is defined.
|
||||
Coordinates Qhull::
|
||||
feasiblePoint() const
|
||||
{
|
||||
Coordinates result;
|
||||
if(qh_qh->feasible_point){
|
||||
result.append(qh_qh->hull_dim, qh_qh->feasible_point);
|
||||
}else{
|
||||
result= feasible_point;
|
||||
}
|
||||
return result;
|
||||
}//feasiblePoint
|
||||
|
||||
//! Return origin point for qh.input_dim
|
||||
QhullPoint Qhull::
|
||||
inputOrigin()
|
||||
{
|
||||
QhullPoint result= origin();
|
||||
result.setDimension(qh_qh->input_dim);
|
||||
return result;
|
||||
}//inputOrigin
|
||||
|
||||
#//!\name GetValue
|
||||
|
||||
double Qhull::
|
||||
area(){
|
||||
checkIfQhullInitialized();
|
||||
if(!qh_qh->hasAreaVolume){
|
||||
QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
|
||||
qh_getarea(qh_qh, qh_qh->facet_list);
|
||||
}
|
||||
qh_qh->NOerrexit= true;
|
||||
qh_qh->maybeThrowQhullMessage(QH_TRY_status);
|
||||
}
|
||||
return qh_qh->totarea;
|
||||
}//area
|
||||
|
||||
double Qhull::
|
||||
volume(){
|
||||
checkIfQhullInitialized();
|
||||
if(!qh_qh->hasAreaVolume){
|
||||
QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
|
||||
qh_getarea(qh_qh, qh_qh->facet_list);
|
||||
}
|
||||
qh_qh->NOerrexit= true;
|
||||
qh_qh->maybeThrowQhullMessage(QH_TRY_status);
|
||||
}
|
||||
return qh_qh->totvol;
|
||||
}//volume
|
||||
|
||||
#//!\name Foreach
|
||||
|
||||
//! Define QhullVertex::neighborFacets().
|
||||
//! Automatically called if merging facets or computing the Voronoi diagram.
|
||||
//! Noop if called multiple times.
|
||||
void Qhull::
|
||||
defineVertexNeighborFacets(){
|
||||
checkIfQhullInitialized();
|
||||
if(!qh_qh->hasAreaVolume){
|
||||
QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
|
||||
qh_vertexneighbors(qh_qh);
|
||||
}
|
||||
qh_qh->NOerrexit= true;
|
||||
qh_qh->maybeThrowQhullMessage(QH_TRY_status);
|
||||
}
|
||||
}//defineVertexNeighborFacets
|
||||
|
||||
QhullFacetList Qhull::
|
||||
facetList() const
|
||||
{
|
||||
return QhullFacetList(beginFacet(), endFacet());
|
||||
}//facetList
|
||||
|
||||
QhullPoints Qhull::
|
||||
points() const
|
||||
{
|
||||
return QhullPoints(qh_qh, qh_qh->hull_dim, qh_qh->num_points*qh_qh->hull_dim, qh_qh->first_point);
|
||||
}//points
|
||||
|
||||
QhullPointSet Qhull::
|
||||
otherPoints() const
|
||||
{
|
||||
return QhullPointSet(qh_qh, qh_qh->other_points);
|
||||
}//otherPoints
|
||||
|
||||
//! Return vertices of the convex hull in qh.vertex_list order
|
||||
//! Vertices are not ordered by adjacency (see QhullFacet::nextFacet2d)
|
||||
QhullVertexList Qhull::
|
||||
vertexList() const
|
||||
{
|
||||
return QhullVertexList(beginVertex(), endVertex());
|
||||
}//vertexList
|
||||
|
||||
#//!\name Methods
|
||||
|
||||
void Qhull::
|
||||
outputQhull()
|
||||
{
|
||||
checkIfQhullInitialized();
|
||||
QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
|
||||
qh_produce_output2(qh_qh);
|
||||
}
|
||||
qh_qh->NOerrexit= true;
|
||||
qh_qh->maybeThrowQhullMessage(QH_TRY_status);
|
||||
}//outputQhull
|
||||
|
||||
void Qhull::
|
||||
outputQhull(const char *outputflags)
|
||||
{
|
||||
checkIfQhullInitialized();
|
||||
string cmd(" "); // qh_checkflags skips first word
|
||||
cmd += outputflags;
|
||||
char *command= const_cast<char*>(cmd.c_str());
|
||||
QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
|
||||
qh_clear_outputflags(qh_qh);
|
||||
char *s= qh_qh->qhull_command + strlen(qh_qh->qhull_command) + 1; //space
|
||||
strncat(qh_qh->qhull_command, command, sizeof(qh_qh->qhull_command)-strlen(qh_qh->qhull_command)-1);
|
||||
qh_checkflags(qh_qh, command, const_cast<char *>(s_not_output_options));
|
||||
qh_initflags(qh_qh, s);
|
||||
qh_initqhull_outputflags(qh_qh);
|
||||
if(qh_qh->KEEPminArea < REALmax/2 || qh_qh->KEEParea || qh_qh->KEEPmerge || qh_qh->GOODvertex
|
||||
|| qh_qh->GOODpoint || qh_qh->GOODthreshold || qh_qh->SPLITthresholds){
|
||||
facetT *facet;
|
||||
qh_qh->ONLYgood= False;
|
||||
FORALLfacet_(qh_qh->facet_list){
|
||||
facet->good= True;
|
||||
}
|
||||
qh_prepare_output(qh_qh);
|
||||
}
|
||||
qh_produce_output2(qh_qh);
|
||||
if(qh_qh->VERIFYoutput && !qh_qh->FORCEoutput && !qh_qh->STOPadd && !qh_qh->STOPcone && !qh_qh->STOPpoint){
|
||||
qh_check_points(qh_qh);
|
||||
}
|
||||
}
|
||||
qh_qh->NOerrexit= true;
|
||||
qh_qh->maybeThrowQhullMessage(QH_TRY_status);
|
||||
}//outputQhull
|
||||
|
||||
//! Prepare Qhull for Voronoi output
|
||||
//! Calls qh_markvoronoi ('v o Fi Fo') and qh_order_vertexneighbors ('v Fi Fo')
|
||||
void Qhull::
|
||||
prepareVoronoi(bool *isLower, int *voronoiVertexCount)
|
||||
{
|
||||
QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
|
||||
boolT isLowerHull;
|
||||
vertexT *vertex;
|
||||
|
||||
setT *vertices= qh_markvoronoi(qh_qh, facetList().first().getFacetT(), NULL, !qh_ALL, &isLowerHull, voronoiVertexCount);
|
||||
*isLower= isLowerHull;
|
||||
|
||||
qhT *qh= qh_qh;
|
||||
FORALLvertices{
|
||||
qh_order_vertexneighbors(qh, vertex);
|
||||
}
|
||||
qh_settempfree(qh, &vertices);
|
||||
}
|
||||
qh_qh->NOerrexit= true;
|
||||
qh_qh->maybeThrowQhullMessage(QH_TRY_status);
|
||||
}//prepareVoronoi
|
||||
|
||||
//! For qhull commands, see http://www.qhull.org/html/qhull.htm or html/qhull.htm
|
||||
void Qhull::
|
||||
runQhull(const RboxPoints &rboxPoints, const char *qhullCommand2)
|
||||
{
|
||||
runQhull(rboxPoints.comment().c_str(), rboxPoints.dimension(), rboxPoints.count(), &*rboxPoints.coordinates(), qhullCommand2);
|
||||
}//runQhull, RboxPoints
|
||||
|
||||
//! pointCoordinates is a array of points, input sites ('d' or 'v'), or halfspaces with offset last ('H')
|
||||
//! Derived from qh_new_qhull [user.c]
|
||||
//! For rbox commands, see http://www.qhull.org/html/rbox.htm or html/rbox.htm
|
||||
//! For qhull commands, see http://www.qhull.org/html/qhull.htm or html/qhull.htm
|
||||
void Qhull::
|
||||
runQhull(const char *inputComment2, int pointDimension, int pointCount, const realT *pointCoordinates, const char *qhullCommand2)
|
||||
{
|
||||
/* gcc may issue a "might be clobbered" warning for pointDimension and pointCoordinates [-Wclobbered].
|
||||
These parameters are not referenced after a longjmp() and hence not clobbered.
|
||||
See http://stackoverflow.com/questions/7721854/what-sense-do-these-clobbered-variable-warnings-make */
|
||||
if(run_called){
|
||||
throw QhullError(10027, "Qhull error: runQhull called twice. Only one call allowed.");
|
||||
}
|
||||
run_called= true;
|
||||
string s("qhull ");
|
||||
s += qhullCommand2;
|
||||
char *command= const_cast<char*>(s.c_str());
|
||||
/************* Expansion of QH_TRY_ for debugging
|
||||
int QH_TRY_status;
|
||||
if(qh_qh->NOerrexit){
|
||||
qh_qh->NOerrexit= False;
|
||||
QH_TRY_status= setjmp(qh_qh->errexit);
|
||||
}else{
|
||||
QH_TRY_status= QH_TRY_ERROR;
|
||||
}
|
||||
if(!QH_TRY_status){
|
||||
*************/
|
||||
QH_TRY_(qh_qh){ // no object creation -- destructors are skipped on longjmp()
|
||||
qh_checkflags(qh_qh, command, const_cast<char *>(s_unsupported_options));
|
||||
qh_initflags(qh_qh, command);
|
||||
*qh_qh->rbox_command= '\0';
|
||||
strncat( qh_qh->rbox_command, inputComment2, sizeof(qh_qh->rbox_command)-1);
|
||||
if(qh_qh->DELAUNAY){
|
||||
qh_qh->PROJECTdelaunay= True; // qh_init_B() calls qh_projectinput()
|
||||
}
|
||||
pointT *newPoints= const_cast<pointT*>(pointCoordinates);
|
||||
int newDimension= pointDimension;
|
||||
int newIsMalloc= False;
|
||||
if(qh_qh->HALFspace){
|
||||
--newDimension;
|
||||
initializeFeasiblePoint(newDimension);
|
||||
newPoints= qh_sethalfspace_all(qh_qh, pointDimension, pointCount, newPoints, qh_qh->feasible_point);
|
||||
newIsMalloc= True;
|
||||
}
|
||||
qh_init_B(qh_qh, newPoints, pointCount, newDimension, newIsMalloc);
|
||||
qh_qhull(qh_qh);
|
||||
qh_check_output(qh_qh);
|
||||
qh_prepare_output(qh_qh);
|
||||
if(qh_qh->VERIFYoutput && !qh_qh->FORCEoutput && !qh_qh->STOPadd && !qh_qh->STOPcone && !qh_qh->STOPpoint){
|
||||
qh_check_points(qh_qh);
|
||||
}
|
||||
}
|
||||
qh_qh->NOerrexit= true;
|
||||
for(int k= qh_qh->hull_dim; k--; ){ // Do not move into QH_TRY block. It may throw an error
|
||||
origin_point << 0.0;
|
||||
}
|
||||
qh_qh->maybeThrowQhullMessage(QH_TRY_status);
|
||||
}//runQhull
|
||||
|
||||
#//!\name Helpers -- be careful of allocating C++ objects due to setjmp/longjmp() error handling by qh_... routines
|
||||
|
||||
//! initialize qh.feasible_point for half-space intersection
|
||||
//! Sets from qh.feasible_string if available, otherwise from Qhull::feasible_point
|
||||
//! called only once from runQhull(), otherwise it leaks memory (the same as qh_setFeasible)
|
||||
void Qhull::
|
||||
initializeFeasiblePoint(int hulldim)
|
||||
{
|
||||
if(qh_qh->feasible_string){
|
||||
qh_setfeasible(qh_qh, hulldim);
|
||||
}else{
|
||||
if(feasible_point.isEmpty()){
|
||||
qh_fprintf(qh_qh, qh_qh->ferr, 6209, "qhull error: missing feasible point for halfspace intersection. Use option 'Hn,n' or Qhull::setFeasiblePoint before runQhull()\n");
|
||||
qh_errexit(qh_qh, qh_ERRmem, NULL, NULL);
|
||||
}
|
||||
if(feasible_point.size()!=static_cast<size_t>(hulldim)){
|
||||
qh_fprintf(qh_qh, qh_qh->ferr, 6210, "qhull error: dimension of feasiblePoint should be %d. It is %u\n", hulldim, feasible_point.size());
|
||||
qh_errexit(qh_qh, qh_ERRmem, NULL, NULL);
|
||||
}
|
||||
qh_qh->feasible_point= static_cast<coordT*>(qh_malloc(static_cast<size_t>(hulldim) * sizeof(coordT)));
|
||||
if(!qh_qh->feasible_point){
|
||||
qh_fprintf(qh_qh, qh_qh->ferr, 6042, "qhull error (Qhull.cpp): insufficient memory for feasible point\n");
|
||||
qh_errexit(qh_qh, qh_ERRmem, NULL, NULL);
|
||||
}
|
||||
coordT *t= qh_qh->feasible_point;
|
||||
// No qh_... routines after here -- longjmp() ignores destructor
|
||||
for(Coordinates::ConstIterator p=feasible_point.begin(); p<feasible_point.end(); p++){
|
||||
*t++= *p;
|
||||
}
|
||||
}
|
||||
}//initializeFeasiblePoint
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/Qhull.h#5 $$Change: 2956 $
|
||||
** $DateTime: 2020/05/23 21:08:29 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QHULLCPP_H
|
||||
#define QHULLCPP_H
|
||||
|
||||
#include "libqhullcpp/QhullPoint.h"
|
||||
#include "libqhullcpp/QhullVertex.h"
|
||||
#include "libqhullcpp/QhullFacet.h"
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
/***
|
||||
Compile qhullcpp and libqhull with the same compiler. setjmp() and longjmp() must be the same.
|
||||
|
||||
#define QHULL_NO_STL
|
||||
Do not supply conversions to STL
|
||||
Coordinates.h requires <vector>. It could be rewritten for another vector class such as QList
|
||||
#define QHULL_USES_QT
|
||||
Supply conversions to QT
|
||||
qhulltest requires QT. It is defined in RoadTest.h
|
||||
|
||||
#define QHULL_ASSERT
|
||||
Defined by QhullError.h
|
||||
It invokes assert()
|
||||
*/
|
||||
|
||||
#//!\name Used here
|
||||
class QhullFacetList;
|
||||
class QhullPoints;
|
||||
class QhullQh;
|
||||
class RboxPoints;
|
||||
|
||||
#//!\name Defined here
|
||||
class Qhull;
|
||||
|
||||
//! Interface to Qhull from C++
|
||||
class Qhull {
|
||||
|
||||
private:
|
||||
#//!\name Members and friends
|
||||
QhullQh * qh_qh; //! qhT for this instance
|
||||
Coordinates origin_point; //! origin for qh_qh->hull_dim. Set by runQhull()
|
||||
bool run_called; //! True at start of runQhull. Errors if call again.
|
||||
Coordinates feasible_point; //! feasible point for half-space intersection (alternative to qh.feasible_string for qh.feasible_point)
|
||||
|
||||
public:
|
||||
#//!\name Constructors
|
||||
Qhull(); //!< call runQhull() next
|
||||
Qhull(const RboxPoints &rboxPoints, const char *qhullCommand2);
|
||||
Qhull(const char *inputComment2, int pointDimension, int pointCount, const realT *pointCoordinates, const char *qhullCommand2);
|
||||
~Qhull() throw();
|
||||
private: //! Disable copy constructor and assignment. Qhull owns QhullQh.
|
||||
Qhull(const Qhull &);
|
||||
Qhull & operator=(const Qhull &);
|
||||
|
||||
private:
|
||||
void allocateQhullQh();
|
||||
|
||||
public:
|
||||
|
||||
#//!\name GetSet
|
||||
void checkIfQhullInitialized();
|
||||
int dimension() const { return qh_qh->input_dim; } //!< Dimension of input and result
|
||||
void disableOutputStream() { qh_qh->disableOutputStream(); }
|
||||
void enableOutputStream() { qh_qh->enableOutputStream(); }
|
||||
countT facetCount() const { return qh_qh->num_facets; }
|
||||
Coordinates feasiblePoint() const;
|
||||
int hullDimension() const { return qh_qh->hull_dim; } //!< Dimension of the computed hull
|
||||
bool hasOutputStream() const { return qh_qh->hasOutputStream(); }
|
||||
bool initialized() const { return (qh_qh->hull_dim>0); }
|
||||
const char * inputComment() const { return qh_qh->rbox_command; }
|
||||
QhullPoint inputOrigin();
|
||||
bool isDelaunay() const { return qh_qh->DELAUNAY; }
|
||||
//! non-const due to QhullPoint
|
||||
QhullPoint origin() { QHULL_ASSERT(initialized()); return QhullPoint(qh_qh, origin_point.data()); }
|
||||
QhullQh * qh() const { return qh_qh; }
|
||||
const char * qhullCommand() const { return qh_qh->qhull_command; }
|
||||
const char * rboxCommand() const { return qh_qh->rbox_command; }
|
||||
int rotateRandom() const { return qh_qh->ROTATErandom; } //!< Return QRn for repeating QR0 runs
|
||||
void setFeasiblePoint(const Coordinates &c) { feasible_point= c; } //!< Sets qh.feasible_point via initializeFeasiblePoint
|
||||
countT vertexCount() const { return qh_qh->num_vertices; }
|
||||
|
||||
#//!\name Delegated to QhullQh
|
||||
double angleEpsilon() const { return qh_qh->angleEpsilon(); } //!< Epsilon for hyperplane angle equality
|
||||
void appendQhullMessage(const std::string &s) { qh_qh->appendQhullMessage(s); }
|
||||
void clearQhullMessage() { qh_qh->clearQhullMessage(); }
|
||||
double distanceEpsilon() const { return qh_qh->distanceEpsilon(); } //!< Epsilon for distance to hyperplane
|
||||
double factorEpsilon() const { return qh_qh->factorEpsilon(); } //!< Factor for angleEpsilon and distanceEpsilon
|
||||
std::string qhullMessage() const { return qh_qh->qhullMessage(); }
|
||||
bool hasQhullMessage() const { return qh_qh->hasQhullMessage(); }
|
||||
int qhullStatus() const { return qh_qh->qhullStatus(); }
|
||||
void setErrorStream(std::ostream *os) { qh_qh->setErrorStream(os); }
|
||||
void setFactorEpsilon(double a) { qh_qh->setFactorEpsilon(a); }
|
||||
void setOutputStream(std::ostream *os) { qh_qh->setOutputStream(os); }
|
||||
|
||||
#//!\name ForEach
|
||||
QhullFacet beginFacet() const { return QhullFacet(qh_qh, qh_qh->facet_list); }
|
||||
QhullVertex beginVertex() const { return QhullVertex(qh_qh, qh_qh->vertex_list); }
|
||||
void defineVertexNeighborFacets(); //!< Automatically called if merging facets or Voronoi diagram
|
||||
QhullFacet endFacet() const { return QhullFacet(qh_qh, qh_qh->facet_tail); }
|
||||
QhullVertex endVertex() const { return QhullVertex(qh_qh, qh_qh->vertex_tail); }
|
||||
QhullFacetList facetList() const;
|
||||
QhullFacet firstFacet() const { return beginFacet(); }
|
||||
QhullVertex firstVertex() const { return beginVertex(); }
|
||||
QhullPoints points() const;
|
||||
QhullPointSet otherPoints() const;
|
||||
//! Same as points().coordinates()
|
||||
coordT * pointCoordinateBegin() const { return qh_qh->first_point; }
|
||||
coordT * pointCoordinateEnd() const { return qh_qh->first_point + qh_qh->num_points*qh_qh->hull_dim; }
|
||||
QhullVertexList vertexList() const;
|
||||
|
||||
#//!\name Methods
|
||||
double area();
|
||||
void outputQhull();
|
||||
void outputQhull(const char * outputflags);
|
||||
void prepareVoronoi(bool *isLower, int *voronoiVertexCount);
|
||||
void runQhull(const RboxPoints &rboxPoints, const char *qhullCommand2);
|
||||
void runQhull(const char *inputComment2, int pointDimension, int pointCount, const realT *pointCoordinates, const char *qhullCommand2);
|
||||
double volume();
|
||||
|
||||
#//!\name Helpers
|
||||
private:
|
||||
void initializeFeasiblePoint(int hulldim);
|
||||
};//Qhull
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
#endif // QHULLCPP_H
|
||||
@@ -0,0 +1,62 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/QhullError.h#4 $$Change: 2953 $
|
||||
** $DateTime: 2020/05/21 22:05:32 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QHULLERROR_H
|
||||
#define QHULLERROR_H
|
||||
|
||||
#include "libqhullcpp/RoadError.h"
|
||||
// No dependencies on libqhull
|
||||
|
||||
#ifndef QHULL_ASSERT
|
||||
#define QHULL_ASSERT assert
|
||||
#include <assert.h>
|
||||
#endif
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
#//!\name Defined here
|
||||
//! QhullError -- std::exception class for Qhull
|
||||
class QhullError;
|
||||
|
||||
class QhullError : public RoadError {
|
||||
|
||||
public:
|
||||
#//!\name Constants
|
||||
enum {
|
||||
QHULLfirstError= 10000, //MSG_QHULL_ERROR in Qhull's user.h
|
||||
QHULLlastError= 10081,
|
||||
NOthrow= 1 //! For flag to indexOf()
|
||||
};
|
||||
|
||||
#//!\name Constructors
|
||||
// default constructors
|
||||
QhullError() : RoadError() {}
|
||||
QhullError(const QhullError &other) : RoadError(other) {}
|
||||
QhullError(int code, const std::string &message) : RoadError(code, message) {}
|
||||
QhullError(int code, const char *fmt) : RoadError(code, fmt) {}
|
||||
QhullError(int code, const char *fmt, int d) : RoadError(code, fmt, d) {}
|
||||
QhullError(int code, const char *fmt, int d, int d2) : RoadError(code, fmt, d, d2) {}
|
||||
QhullError(int code, const char *fmt, int d, int d2, float f) : RoadError(code, fmt, d, d2, f) {}
|
||||
QhullError(int code, const char *fmt, int d, int d2, float f, const char *s) : RoadError(code, fmt, d, d2, f, s) {}
|
||||
QhullError(int code, const char *fmt, int d, int d2, float f, const void *x) : RoadError(code, fmt, d, d2, f, x) {}
|
||||
QhullError(int code, const char *fmt, int d, int d2, float f, int i) : RoadError(code, fmt, d, d2, f, i) {}
|
||||
QhullError(int code, const char *fmt, int d, int d2, float f, long long i) : RoadError(code, fmt, d, d2, f, i) {}
|
||||
QhullError(int code, const char *fmt, int d, int d2, float f, double e) : RoadError(code, fmt, d, d2, f, e) {}
|
||||
QhullError &operator=(const QhullError &other) { this->RoadError::operator=(other); return *this; }
|
||||
~QhullError() throw() {}
|
||||
|
||||
};//class QhullError
|
||||
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
#//!\name Global
|
||||
|
||||
inline std::ostream &operator<<(std::ostream &os, const orgQhull::QhullError &e) { return os << e.what(); }
|
||||
|
||||
#endif // QHULLERROR_H
|
||||
@@ -0,0 +1,550 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/QhullFacet.cpp#5 $$Change: 3009 $
|
||||
** $DateTime: 2020/07/30 19:25:22 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#//! QhullFacet -- Qhull's facet structure, facetT, as a C++ class
|
||||
|
||||
#include "libqhullcpp/QhullFacet.h"
|
||||
|
||||
#include "libqhullcpp/QhullError.h"
|
||||
#include "libqhullcpp/Qhull.h"
|
||||
#include "libqhullcpp/QhullSet.h"
|
||||
#include "libqhullcpp/QhullPoint.h"
|
||||
#include "libqhullcpp/QhullPointSet.h"
|
||||
#include "libqhullcpp/QhullRidge.h"
|
||||
#include "libqhullcpp/QhullFacetSet.h"
|
||||
#include "libqhullcpp/QhullVertex.h"
|
||||
|
||||
#include <ostream>
|
||||
|
||||
using std::endl;
|
||||
using std::ostream;
|
||||
|
||||
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
|
||||
#pragma warning( disable : 4611) // interaction between '_setjmp' and C++ object destruction is non-portable
|
||||
#pragma warning( disable : 4996) // function was declared deprecated(strcpy, localtime, etc.)
|
||||
#endif
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
#//!\name Class objects
|
||||
facetT QhullFacet::
|
||||
s_empty_facet= {
|
||||
#if !qh_COMPUTEfurthest // must match facetT -Wmissing-field-initializers
|
||||
0.0,
|
||||
#endif
|
||||
#if qh_MAXoutside
|
||||
0.0,
|
||||
#endif
|
||||
0.0,NULL,{0.0},
|
||||
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,0,0,
|
||||
false,false,false,false,false,
|
||||
false,false,false,false,false,
|
||||
false,false,false,false,false,
|
||||
false,false,false,false,false,
|
||||
false,false,false};
|
||||
|
||||
#//!\name Constructors
|
||||
|
||||
QhullFacet::
|
||||
QhullFacet(const Qhull &q)
|
||||
: qh_facet(&s_empty_facet)
|
||||
, qh_qh(q.qh())
|
||||
{
|
||||
}
|
||||
|
||||
QhullFacet::
|
||||
QhullFacet(const Qhull &q, facetT *f)
|
||||
: qh_facet(f ? f : &s_empty_facet)
|
||||
, qh_qh(q.qh())
|
||||
{
|
||||
}
|
||||
|
||||
#//!\name GetSet
|
||||
|
||||
//! Return voronoi center or facet centrum. Derived from qh_printcenter [io_r.c]
|
||||
//! if printFormat=qh_PRINTtriangles and qh.DELAUNAY, returns centrum of a Delaunay facet
|
||||
//! Sets center if needed
|
||||
//! Code duplicated for PrintCenter and getCenter
|
||||
//! Returns QhullPoint() if none or qh_INFINITE
|
||||
QhullPoint QhullFacet::
|
||||
getCenter(qh_PRINT printFormat)
|
||||
{
|
||||
if(!qh_qh){
|
||||
// returns QhullPoint()
|
||||
}else if(qh_qh->CENTERtype==qh_ASvoronoi){
|
||||
if(!qh_facet->normal || !qh_facet->upperdelaunay || !qh_qh->ATinfinity){
|
||||
if(!qh_facet->center){
|
||||
QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
|
||||
qh_facet->center= qh_facetcenter(qh_qh, qh_facet->vertices);
|
||||
}
|
||||
qh_qh->NOerrexit= true;
|
||||
qh_qh->maybeThrowQhullMessage(QH_TRY_status);
|
||||
}
|
||||
return QhullPoint(qh_qh, qh_qh->hull_dim-1, qh_facet->center);
|
||||
}
|
||||
}else if(qh_qh->CENTERtype==qh_AScentrum){
|
||||
volatile int numCoords= qh_qh->hull_dim;
|
||||
if(printFormat==qh_PRINTtriangles && qh_qh->DELAUNAY){
|
||||
numCoords--;
|
||||
}
|
||||
if(!qh_facet->center){
|
||||
QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
|
||||
qh_facet->center= qh_getcentrum(qh_qh, getFacetT());
|
||||
}
|
||||
qh_qh->NOerrexit= true;
|
||||
qh_qh->maybeThrowQhullMessage(QH_TRY_status);
|
||||
}
|
||||
return QhullPoint(qh_qh, numCoords, qh_facet->center);
|
||||
}
|
||||
return QhullPoint();
|
||||
}//getCenter
|
||||
|
||||
//! Return innerplane clearly below the vertices
|
||||
//! from io_r.c[qh_PRINTinner]
|
||||
QhullHyperplane QhullFacet::
|
||||
innerplane() const
|
||||
{
|
||||
QhullHyperplane h;
|
||||
if(qh_qh){
|
||||
realT inner;
|
||||
// Does not error, TRY_QHULL_ not needed
|
||||
qh_outerinner(qh_qh, const_cast<facetT *>(getFacetT()), NULL, &inner);
|
||||
h= hyperplane();
|
||||
h.setOffset(h.offset()-inner); //inner is negative
|
||||
}
|
||||
return h;
|
||||
}//innerplane
|
||||
|
||||
QhullFacet QhullFacet::
|
||||
nextFacet2d(QhullVertex *nextVertex) const
|
||||
{
|
||||
QhullFacet f;
|
||||
if(qh_qh && qh_facet){
|
||||
vertexT *vertex;
|
||||
// Does not error, TRY_QHULL_ not needed
|
||||
facetT *facet= qh_nextfacet2d(getFacetT(), &vertex);
|
||||
f.setFacetT(qh_qh, facet);
|
||||
nextVertex->setVertexT(qh_qh, vertex);
|
||||
}
|
||||
return f;
|
||||
}//nextFacet2d
|
||||
|
||||
//! Return outerplane clearly above all points
|
||||
//! from io_r.c[qh_PRINTouter]
|
||||
QhullHyperplane QhullFacet::
|
||||
outerplane() const
|
||||
{
|
||||
QhullHyperplane h;
|
||||
if(qh_qh){
|
||||
realT outer;
|
||||
// Does not error, TRY_QHULL_ not needed
|
||||
qh_outerinner(qh_qh, const_cast<facetT *>(getFacetT()), &outer, NULL);
|
||||
h= hyperplane();
|
||||
h.setOffset(h.offset()-outer); //outer is positive
|
||||
}
|
||||
return h;
|
||||
}//outerplane
|
||||
|
||||
//! Set by qh_triangulate for option 'Qt'.
|
||||
//! Errors if tricoplanar and facetArea() or qh_getarea() called first.
|
||||
QhullFacet QhullFacet::
|
||||
tricoplanarOwner() const
|
||||
{
|
||||
if(qh_facet->tricoplanar){
|
||||
if(qh_facet->isarea){
|
||||
throw QhullError(10018, "Qhull error: facetArea() or qh_getarea() previously called. triCoplanarOwner() is not available.");
|
||||
}
|
||||
return QhullFacet(qh_qh, qh_facet->f.triowner);
|
||||
}
|
||||
return QhullFacet(qh_qh);
|
||||
}//tricoplanarOwner
|
||||
|
||||
QhullPoint QhullFacet::
|
||||
voronoiVertex()
|
||||
{
|
||||
if(qh_qh && qh_qh->CENTERtype!=qh_ASvoronoi){
|
||||
throw QhullError(10052, "Error: QhullFacet.voronoiVertex() requires option 'v' (qh_ASvoronoi)");
|
||||
}
|
||||
return getCenter();
|
||||
}//voronoiVertex
|
||||
|
||||
#//!\name Value
|
||||
|
||||
//! Disables tricoplanarOwner()
|
||||
double QhullFacet::
|
||||
facetArea()
|
||||
{
|
||||
if(qh_qh && !qh_facet->isarea){
|
||||
QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
|
||||
qh_facet->f.area= qh_facetarea(qh_qh, qh_facet);
|
||||
qh_facet->isarea= True;
|
||||
}
|
||||
qh_qh->NOerrexit= true;
|
||||
qh_qh->maybeThrowQhullMessage(QH_TRY_status);
|
||||
}
|
||||
return qh_facet->f.area;
|
||||
}//facetArea
|
||||
|
||||
#//!\name Foreach
|
||||
|
||||
QhullPointSet QhullFacet::
|
||||
coplanarPoints() const
|
||||
{
|
||||
return QhullPointSet(qh_qh, qh_facet->coplanarset);
|
||||
}//coplanarPoints
|
||||
|
||||
QhullFacetSet QhullFacet::
|
||||
neighborFacets() const
|
||||
{
|
||||
return QhullFacetSet(qh_qh, qh_facet->neighbors);
|
||||
}//neighborFacets
|
||||
|
||||
QhullPointSet QhullFacet::
|
||||
outsidePoints() const
|
||||
{
|
||||
return QhullPointSet(qh_qh, qh_facet->outsideset);
|
||||
}//outsidePoints
|
||||
|
||||
QhullRidgeSet QhullFacet::
|
||||
ridges() const
|
||||
{
|
||||
return QhullRidgeSet(qh_qh, qh_facet->ridges);
|
||||
}//ridges
|
||||
|
||||
QhullVertexSet QhullFacet::
|
||||
vertices() const
|
||||
{
|
||||
return QhullVertexSet(qh_qh, qh_facet->vertices);
|
||||
}//vertices
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
#//!\name operator<<
|
||||
|
||||
using std::ostream;
|
||||
|
||||
using orgQhull::QhullFacet;
|
||||
using orgQhull::QhullFacetSet;
|
||||
using orgQhull::QhullPoint;
|
||||
using orgQhull::QhullPointSet;
|
||||
using orgQhull::QhullRidge;
|
||||
using orgQhull::QhullRidgeSet;
|
||||
using orgQhull::QhullSetBase;
|
||||
using orgQhull::QhullVertexSet;
|
||||
|
||||
ostream &
|
||||
operator<<(ostream &os, const QhullFacet::PrintFacet &pr)
|
||||
{
|
||||
os << pr.message;
|
||||
QhullFacet f= *pr.facet;
|
||||
if(f.getFacetT()==0){ // Special values from set iterator
|
||||
os << " NULLfacet" << endl;
|
||||
return os;
|
||||
}
|
||||
if(f.getFacetT()==qh_MERGEridge){
|
||||
os << " MERGEridge" << endl;
|
||||
return os;
|
||||
}
|
||||
if(f.getFacetT()==qh_DUPLICATEridge){
|
||||
os << " DUPLICATEridge" << endl;
|
||||
return os;
|
||||
}
|
||||
os << f.printHeader();
|
||||
if(!f.ridges().isEmpty()){
|
||||
os << f.printRidges();
|
||||
}
|
||||
return os;
|
||||
}//operator<< PrintFacet
|
||||
|
||||
//! Print Voronoi center or facet centrum to stream. Same as qh_printcenter [_r.]
|
||||
//! Code duplicated for PrintCenter and getCenter
|
||||
//! Sets center if needed
|
||||
ostream &
|
||||
operator<<(ostream &os, const QhullFacet::PrintCenter &pr)
|
||||
{
|
||||
facetT *f= pr.facet->getFacetT();
|
||||
if(pr.facet->qh()->CENTERtype!=qh_ASvoronoi && pr.facet->qh()->CENTERtype!=qh_AScentrum){
|
||||
return os;
|
||||
}
|
||||
if(pr.message){
|
||||
os << pr.message;
|
||||
}
|
||||
int numCoords;
|
||||
if(pr.facet->qh()->CENTERtype==qh_ASvoronoi){
|
||||
numCoords= pr.facet->qh()->hull_dim-1;
|
||||
if(!f->normal || !f->upperdelaunay || !pr.facet->qh()->ATinfinity){
|
||||
if(!f->center){
|
||||
f->center= qh_facetcenter(pr.facet->qh(), f->vertices);
|
||||
}
|
||||
for(int k=0; k<numCoords; k++){
|
||||
os << f->center[k] << " "; // QH11010 FIX: qh_REAL_1
|
||||
}
|
||||
}else{
|
||||
for(int k=0; k<numCoords; k++){
|
||||
os << qh_INFINITE << " "; // QH11010 FIX: qh_REAL_1
|
||||
}
|
||||
}
|
||||
}else{ // qh CENTERtype==qh_AScentrum
|
||||
numCoords= pr.facet->qh()->hull_dim;
|
||||
if(pr.print_format==qh_PRINTtriangles && pr.facet->qh()->DELAUNAY){
|
||||
numCoords--;
|
||||
}
|
||||
if(!f->center){
|
||||
f->center= qh_getcentrum(pr.facet->qh(), f);
|
||||
}
|
||||
for(int k=0; k<numCoords; k++){
|
||||
os << f->center[k] << " "; // QH11010 FIX: qh_REAL_1
|
||||
}
|
||||
}
|
||||
if(pr.print_format==qh_PRINTgeom && numCoords==2){
|
||||
os << " 0";
|
||||
}
|
||||
os << endl;
|
||||
return os;
|
||||
}//operator<< PrintCenter
|
||||
|
||||
//! Print flags for facet to stream. Space prefix. From qh_printfacetheader [io_r.c]
|
||||
ostream &
|
||||
operator<<(ostream &os, const QhullFacet::PrintFlags &p)
|
||||
{
|
||||
const facetT *f= p.facet->getFacetT();
|
||||
if(p.message){
|
||||
os << p.message;
|
||||
}
|
||||
|
||||
os << (p.facet->isTopOrient() ? " top" : " bottom");
|
||||
if(p.facet->isSimplicial()){
|
||||
os << " simplicial";
|
||||
}
|
||||
if(p.facet->isTriCoplanar()){
|
||||
os << " tricoplanar";
|
||||
}
|
||||
if(p.facet->isUpperDelaunay()){
|
||||
os << " upperDelaunay";
|
||||
}
|
||||
if(f->visible){
|
||||
os << " visible";
|
||||
}
|
||||
if(f->newfacet){
|
||||
os << " new";
|
||||
}
|
||||
if(f->tested){
|
||||
os << " tested";
|
||||
}
|
||||
if(!f->good){
|
||||
os << " notG";
|
||||
}
|
||||
if(f->seen && p.facet->qh()->IStracing){
|
||||
os << " seen";
|
||||
}
|
||||
if(f->seen2 && p.facet->qh()->IStracing){
|
||||
os << " seen";
|
||||
}
|
||||
if(f->isarea){
|
||||
os << " isarea";
|
||||
}
|
||||
if(f->coplanarhorizon){
|
||||
os << " coplanarhorizon";
|
||||
}
|
||||
if(f->mergehorizon){
|
||||
os << " mergehorizon";
|
||||
}
|
||||
if(f->cycledone){
|
||||
os << " cycledone";
|
||||
}
|
||||
if(f->keepcentrum){
|
||||
os << " keepcentrum";
|
||||
}
|
||||
if(f->dupridge){
|
||||
os << " dupridge";
|
||||
}
|
||||
if(f->mergeridge && !f->mergeridge2){
|
||||
os << " mergeridge1";
|
||||
}
|
||||
if(f->mergeridge2){
|
||||
os << " mergeridge2";
|
||||
}
|
||||
if(f->newmerge){
|
||||
os << " newmerge";
|
||||
}
|
||||
if(f->flipped){
|
||||
os << " flipped";
|
||||
}
|
||||
if(f->notfurthest){
|
||||
os << " notfurthest";
|
||||
}
|
||||
if(f->degenerate){
|
||||
os << " degenerate";
|
||||
}
|
||||
if(f->redundant){
|
||||
os << " redundant";
|
||||
}
|
||||
os << endl;
|
||||
return os;
|
||||
}//operator<< PrintFlags
|
||||
|
||||
//! Print header for facet to stream. Space prefix. From qh_printfacetheader [io_r.c]
|
||||
ostream &
|
||||
operator<<(ostream &os, const QhullFacet::PrintHeader &pr)
|
||||
{
|
||||
QhullFacet facet= *pr.facet;
|
||||
facetT *f= facet.getFacetT();
|
||||
os << "- f" << facet.id() << endl;
|
||||
os << facet.printFlags(" - flags:");
|
||||
if(f->isarea){
|
||||
os << " - area: " << f->f.area << endl; //QH11010 FIX: 2.2g
|
||||
}else if(pr.facet->qh()->NEWfacets && f->visible && f->f.replace){
|
||||
os << " - replacement: f" << f->f.replace->id << endl;
|
||||
}else if(f->newfacet){
|
||||
if(f->f.samecycle && f->f.samecycle != f){
|
||||
os << " - shares same visible/horizon as f" << f->f.samecycle->id << endl;
|
||||
}
|
||||
}else if(f->tricoplanar /* !isarea */){
|
||||
if(f->f.triowner){
|
||||
os << " - owner of normal & centrum is facet f" << f->f.triowner->id << endl;
|
||||
}
|
||||
}else if(f->f.newcycle){
|
||||
os << " - was horizon to f" << f->f.newcycle->id << endl;
|
||||
}
|
||||
if(f->nummerge){
|
||||
os << " - merges: " << f->nummerge << endl;
|
||||
}
|
||||
os << facet.hyperplane().print(" - normal: ", "\n - offset: "); // QH11010 FIX: %10.7g
|
||||
if(pr.facet->qh()->CENTERtype==qh_ASvoronoi || f->center){
|
||||
os << facet.printCenter(qh_PRINTfacets, " - center: ");
|
||||
}
|
||||
#if qh_MAXoutside
|
||||
if(f->maxoutside > pr.facet->qh()->DISTround){
|
||||
os << " - maxoutside: " << f->maxoutside << endl; //QH11010 FIX: %10.7g
|
||||
}
|
||||
#endif
|
||||
QhullPointSet ps= facet.outsidePoints();
|
||||
if(!ps.isEmpty()){
|
||||
QhullPoint furthest= ps.last();
|
||||
if(ps.size() < 6){
|
||||
os << " - outside set(furthest p" << furthest.id() << "):" << endl;
|
||||
for(QhullPointSet::iterator i=ps.begin(); i!=ps.end(); ++i){
|
||||
QhullPoint p= *i;
|
||||
os << p.print(" ");
|
||||
}
|
||||
}else if(ps.size()<21){
|
||||
os << ps.print(" - outside set:");
|
||||
}else{
|
||||
os << " - outside set: " << ps.size() << " points.";
|
||||
os << furthest.print(" Furthest");
|
||||
}
|
||||
#if !qh_COMPUTEfurthest
|
||||
os << " - furthest distance= " << f->furthestdist << endl; //QH11010 FIX: %2.2g
|
||||
#endif
|
||||
}
|
||||
QhullPointSet cs= facet.coplanarPoints();
|
||||
if(!cs.isEmpty()){
|
||||
QhullPoint furthest= cs.last();
|
||||
if(cs.size() < 6){
|
||||
os << " - coplanar set(furthest p" << furthest.id() << "):" << endl;
|
||||
for(QhullPointSet::iterator i=cs.begin(); i!=cs.end(); ++i){
|
||||
QhullPoint p= *i;
|
||||
os << p.print(" ");
|
||||
}
|
||||
}else if(cs.size()<21){
|
||||
os << cs.print(" - coplanar set:");
|
||||
}else{
|
||||
os << " - coplanar set: " << cs.size() << " points.";
|
||||
os << furthest.print(" Furthest");
|
||||
}
|
||||
// QH11027 FIX: Can/should zinc_(Zdistio) be called from C++ interface
|
||||
double d= facet.distance(furthest);
|
||||
os << " furthest distance= " << d << endl; //QH11010 FIX: %2.2g
|
||||
}
|
||||
QhullVertexSet vs= facet.vertices();
|
||||
if(!vs.isEmpty()){
|
||||
os << vs.print(" - vertices:");
|
||||
}
|
||||
QhullFacetSet fs= facet.neighborFacets();
|
||||
fs.selectAll();
|
||||
if(!fs.isEmpty()){
|
||||
os << fs.printIdentifiers(" - neighboring facets:");
|
||||
}
|
||||
return os;
|
||||
}//operator<< PrintHeader
|
||||
|
||||
|
||||
//! Print ridges of facet to stream. Same as qh_printfacetridges [io_r.c]
|
||||
ostream &
|
||||
operator<<(ostream &os, const QhullFacet::PrintRidges &pr)
|
||||
{
|
||||
const QhullFacet facet= *pr.facet;
|
||||
facetT *f= facet.getFacetT();
|
||||
QhullRidgeSet rs= facet.ridges();
|
||||
if(!rs.isEmpty()){
|
||||
if(f->visible && pr.facet->qh()->NEWfacets){
|
||||
os << " - ridges(ids may be garbage):";
|
||||
for(QhullRidgeSet::iterator i=rs.begin(); i!=rs.end(); ++i){
|
||||
QhullRidge r= *i;
|
||||
os << " r" << r.id();
|
||||
}
|
||||
os << endl;
|
||||
}else{
|
||||
os << " - ridges:" << endl;
|
||||
}
|
||||
|
||||
// Keep track of printed ridges
|
||||
for(QhullRidgeSet::iterator i=rs.begin(); i!=rs.end(); ++i){
|
||||
QhullRidge r= *i;
|
||||
r.getRidgeT()->seen= false;
|
||||
}
|
||||
int ridgeCount= 0;
|
||||
if(facet.dimension()==3){
|
||||
for(QhullRidge r= rs.first(); !r.getRidgeT()->seen; r= r.nextRidge3d(facet)){
|
||||
r.getRidgeT()->seen= true;
|
||||
os << r.print("");
|
||||
++ridgeCount;
|
||||
if(!r.hasNextRidge3d(facet)){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
QhullFacetSet ns(facet.neighborFacets());
|
||||
for(QhullFacetSet::iterator i=ns.begin(); i!=ns.end(); ++i){
|
||||
QhullFacet neighbor= *i;
|
||||
QhullRidgeSet nrs(neighbor.ridges());
|
||||
for(QhullRidgeSet::iterator j=nrs.begin(); j!=nrs.end(); ++j){
|
||||
QhullRidge r= *j;
|
||||
if(r.otherFacet(neighbor)==facet){
|
||||
r.getRidgeT()->seen= true;
|
||||
os << r.print("");
|
||||
ridgeCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(ridgeCount!=rs.count()){
|
||||
os << " - all ridges:";
|
||||
for(QhullRidgeSet::iterator i=rs.begin(); i!=rs.end(); ++i){
|
||||
QhullRidge r= *i;
|
||||
os << " r" << r.id();
|
||||
}
|
||||
os << endl;
|
||||
}
|
||||
for(QhullRidgeSet::iterator i=rs.begin(); i!=rs.end(); ++i){
|
||||
QhullRidge r= *i;
|
||||
if(!r.getRidgeT()->seen){
|
||||
os << r.print("");
|
||||
}
|
||||
}
|
||||
}
|
||||
return os;
|
||||
}//operator<< PrintRidges
|
||||
|
||||
// "No conversion" error if defined inline
|
||||
ostream &
|
||||
operator<<(ostream &os, QhullFacet &f)
|
||||
{
|
||||
os << f.print("");
|
||||
return os;
|
||||
}//<< QhullFacet
|
||||
@@ -0,0 +1,156 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/QhullFacet.h#4 $$Change: 2963 $
|
||||
** $DateTime: 2020/06/03 19:31:01 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QHULLFACET_H
|
||||
#define QHULLFACET_H
|
||||
|
||||
#include "libqhull_r/qhull_ra.h"
|
||||
#include "libqhullcpp/QhullHyperplane.h"
|
||||
#include "libqhullcpp/QhullPoint.h"
|
||||
#include "libqhullcpp/QhullSet.h"
|
||||
#include "libqhullcpp/QhullPointSet.h"
|
||||
|
||||
#include <ostream>
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
#//!\name Used here
|
||||
class Coordinates;
|
||||
class Qhull;
|
||||
class QhullFacetSet;
|
||||
class QhullRidge;
|
||||
class QhullVertex;
|
||||
class QhullVertexSet;
|
||||
|
||||
#//!\name Defined here
|
||||
class QhullFacet;
|
||||
typedef QhullSet<QhullRidge> QhullRidgeSet;
|
||||
|
||||
//! A QhullFacet is the C++ equivalent to Qhull's facetT*
|
||||
class QhullFacet {
|
||||
|
||||
#//!\name Defined here
|
||||
public:
|
||||
typedef facetT * base_type; // for QhullVertexSet
|
||||
|
||||
private:
|
||||
#//!\name Fields -- no additions (QhullFacetSet of facetT*)
|
||||
facetT * qh_facet; //!< Corresponding facetT, may be 0 for corner cases (e.g., *facetSet.end()==0) and tricoplanarOwner()
|
||||
QhullQh * qh_qh; //!< QhullQh/qhT for facetT, may be 0
|
||||
|
||||
#//!\name Class objects
|
||||
static facetT s_empty_facet; // needed for shallow copy
|
||||
|
||||
public:
|
||||
#//!\name Constructors
|
||||
QhullFacet() : qh_facet(&s_empty_facet), qh_qh(0) {}
|
||||
explicit QhullFacet(const Qhull &q);
|
||||
QhullFacet(const Qhull &q, facetT *f);
|
||||
explicit QhullFacet(QhullQh *qqh) : qh_facet(&s_empty_facet), qh_qh(qqh) {}
|
||||
QhullFacet(QhullQh *qqh, facetT *f) : qh_facet(f ? f : &s_empty_facet), qh_qh(qqh) {}
|
||||
// Creates an alias. Does not copy QhullFacet. Needed for return by value and parameter passing
|
||||
QhullFacet(const QhullFacet &other) : qh_facet(other.qh_facet ? other.qh_facet : &s_empty_facet), qh_qh(other.qh_qh) {}
|
||||
// Creates an alias. Does not copy QhullFacet. Needed for vector<QhullFacet>
|
||||
QhullFacet & operator=(const QhullFacet &other) { qh_facet= other.qh_facet ? other.qh_facet : &s_empty_facet; qh_qh= other.qh_qh; return *this; }
|
||||
~QhullFacet() {}
|
||||
|
||||
|
||||
#//!\name GetSet
|
||||
int dimension() const { return (qh_qh ? qh_qh->hull_dim : 0); }
|
||||
QhullPoint getCenter() { return getCenter(qh_PRINTpoints); }
|
||||
QhullPoint getCenter(qh_PRINT printFormat);
|
||||
facetT * getBaseT() const { return getFacetT(); } //!< For QhullSet<QhullFacet>
|
||||
// Do not define facetT(). It conflicts with return type facetT*
|
||||
facetT * getFacetT() const { return qh_facet; }
|
||||
bool hasNext() const { return (qh_facet->next != NULL && qh_facet->next != qh_qh->facet_tail); }
|
||||
bool hasPrevious() const { return (qh_facet->previous != NULL); }
|
||||
QhullHyperplane hyperplane() const { return QhullHyperplane(qh_qh, dimension(), qh_facet->normal, qh_facet->offset); }
|
||||
countT id() const { return (qh_facet ? qh_facet->id : static_cast<countT>(qh_IDunknown)); }
|
||||
QhullHyperplane innerplane() const;
|
||||
bool isValid() const { return qh_qh && qh_facet && qh_facet != &s_empty_facet; }
|
||||
bool isGood() const { return qh_facet && qh_facet->good; }
|
||||
bool isSimplicial() const { return qh_facet && qh_facet->simplicial; }
|
||||
bool isTopOrient() const { return qh_facet && qh_facet->toporient; }
|
||||
bool isTriCoplanar() const { return qh_facet && qh_facet->tricoplanar; }
|
||||
bool isUpperDelaunay() const { return qh_facet && qh_facet->upperdelaunay; }
|
||||
QhullFacet next() const { return QhullFacet(qh_qh, qh_facet->next); }
|
||||
QhullFacet nextFacet2d(QhullVertex *nextVertex) const;
|
||||
bool operator==(const QhullFacet &other) const { return qh_facet==other.qh_facet; }
|
||||
bool operator!=(const QhullFacet &other) const { return !operator==(other); }
|
||||
QhullHyperplane outerplane() const;
|
||||
QhullFacet previous() const { return QhullFacet(qh_qh, qh_facet->previous); }
|
||||
QhullQh * qh() const { return qh_qh; }
|
||||
void setFacetT(QhullQh *qqh, facetT *facet) { qh_qh= qqh; qh_facet= facet; }
|
||||
QhullFacet tricoplanarOwner() const;
|
||||
int visitId() const { return (qh_facet ? qh_facet->visitid : -1); }
|
||||
QhullPoint voronoiVertex();
|
||||
|
||||
#//!\name value
|
||||
//! Undefined if c.size() != dimension()
|
||||
double distance(const Coordinates &c) const { return distance(c.data()); }
|
||||
double distance(const pointT *p) const { return distance(QhullPoint(qh_qh, const_cast<coordT *>(p))); }
|
||||
double distance(const QhullPoint &p) const { return hyperplane().distance(p); }
|
||||
double facetArea();
|
||||
|
||||
#//!\name foreach
|
||||
// Can not inline. Otherwise circular reference
|
||||
QhullPointSet coplanarPoints() const;
|
||||
QhullFacetSet neighborFacets() const;
|
||||
QhullPointSet outsidePoints() const;
|
||||
QhullRidgeSet ridges() const;
|
||||
QhullVertexSet vertices() const;
|
||||
|
||||
#//!\name IO
|
||||
struct PrintCenter{
|
||||
QhullFacet * facet; // non-const due to facet.center()
|
||||
const char * message;
|
||||
qh_PRINT print_format;
|
||||
PrintCenter(QhullFacet &f, qh_PRINT printFormat, const char * s) : facet(&f), message(s), print_format(printFormat){}
|
||||
};//PrintCenter
|
||||
PrintCenter printCenter(qh_PRINT printFormat, const char *message) { return PrintCenter(*this, printFormat, message); }
|
||||
|
||||
struct PrintFacet{
|
||||
QhullFacet * facet; // non-const due to f->center()
|
||||
const char * message;
|
||||
explicit PrintFacet(QhullFacet &f, const char * s) : facet(&f), message(s) {}
|
||||
};//PrintFacet
|
||||
PrintFacet print(const char *message) { return PrintFacet(*this, message); }
|
||||
|
||||
struct PrintFlags{
|
||||
const QhullFacet *facet;
|
||||
const char * message;
|
||||
PrintFlags(const QhullFacet &f, const char *s) : facet(&f), message(s) {}
|
||||
};//PrintFlags
|
||||
PrintFlags printFlags(const char *message) const { return PrintFlags(*this, message); }
|
||||
|
||||
struct PrintHeader{
|
||||
QhullFacet * facet; // non-const due to f->center()
|
||||
PrintHeader(QhullFacet &f) : facet(&f) {}
|
||||
};//PrintHeader
|
||||
PrintHeader printHeader() { return PrintHeader(*this); }
|
||||
|
||||
struct PrintRidges{
|
||||
const QhullFacet *facet;
|
||||
PrintRidges(QhullFacet &f) : facet(&f) {}
|
||||
};//PrintRidges
|
||||
PrintRidges printRidges() { return PrintRidges(*this); }
|
||||
|
||||
};//class QhullFacet
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
#//!\name Global
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacet::PrintFacet &pr);
|
||||
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacet::PrintCenter &pr);
|
||||
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacet::PrintFlags &pr);
|
||||
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacet::PrintHeader &pr);
|
||||
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacet::PrintRidges &pr);
|
||||
std::ostream &operator<<(std::ostream &os, orgQhull::QhullFacet &f); // non-const due to qh_getcenter()
|
||||
|
||||
#endif // QHULLFACET_H
|
||||
@@ -0,0 +1,174 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/QhullFacetList.cpp#2 $$Change: 2953 $
|
||||
** $DateTime: 2020/05/21 22:05:32 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#//! QhullFacetList -- Qhull's linked facets, as a C++ class
|
||||
|
||||
#include "libqhullcpp/QhullFacetList.h"
|
||||
|
||||
#include "libqhullcpp/QhullFacet.h"
|
||||
#include "libqhullcpp/QhullPoint.h"
|
||||
#include "libqhullcpp/QhullRidge.h"
|
||||
#include "libqhullcpp/QhullVertex.h"
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
|
||||
#pragma warning( disable : 4611) // interaction between '_setjmp' and C++ object destruction is non-portable
|
||||
#pragma warning( disable : 4996) // function was declared deprecated(strcpy, localtime, etc.)
|
||||
#endif
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
#//!\name Constructors
|
||||
|
||||
QhullFacetList::
|
||||
QhullFacetList(const Qhull &q, facetT *b, facetT *e )
|
||||
: QhullLinkedList<QhullFacet>(QhullFacet(q, b), QhullFacet(q, e))
|
||||
, select_all(false)
|
||||
{
|
||||
}
|
||||
|
||||
#//!\name Conversions
|
||||
|
||||
// See qt_qhull.cpp for QList conversions
|
||||
|
||||
#ifndef QHULL_NO_STL
|
||||
std::vector<QhullFacet> QhullFacetList::
|
||||
toStdVector() const
|
||||
{
|
||||
QhullLinkedListIterator<QhullFacet> i(*this);
|
||||
std::vector<QhullFacet> vs;
|
||||
while(i.hasNext()){
|
||||
QhullFacet f= i.next();
|
||||
if(isSelectAll() || f.isGood()){
|
||||
vs.push_back(f);
|
||||
}
|
||||
}
|
||||
return vs;
|
||||
}//toStdVector
|
||||
#endif //QHULL_NO_STL
|
||||
|
||||
#ifndef QHULL_NO_STL
|
||||
//! Same as PrintVertices
|
||||
std::vector<QhullVertex> QhullFacetList::
|
||||
vertices_toStdVector() const
|
||||
{
|
||||
std::vector<QhullVertex> vs;
|
||||
QhullVertexSet qvs(qh(), first().getFacetT(), 0, isSelectAll());
|
||||
|
||||
for(QhullVertexSet::iterator i=qvs.begin(); i!=qvs.end(); ++i){
|
||||
vs.push_back(*i);
|
||||
}
|
||||
return vs;
|
||||
}//vertices_toStdVector
|
||||
#endif //QHULL_NO_STL
|
||||
|
||||
#//!\name GetSet
|
||||
|
||||
bool QhullFacetList::
|
||||
contains(const QhullFacet &facet) const
|
||||
{
|
||||
if(isSelectAll()){
|
||||
return QhullLinkedList<QhullFacet>::contains(facet);
|
||||
}
|
||||
for(QhullFacetList::const_iterator i=begin(); i != end(); ++i){
|
||||
QhullFacet f= *i;
|
||||
if(f==facet && f.isGood()){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}//contains
|
||||
|
||||
int QhullFacetList::
|
||||
count() const
|
||||
{
|
||||
if(isSelectAll()){
|
||||
return QhullLinkedList<QhullFacet>::count();
|
||||
}
|
||||
int counter= 0;
|
||||
for(QhullFacetList::const_iterator i=begin(); i != end(); ++i){
|
||||
if((*i).isGood()){
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
return counter;
|
||||
}//count
|
||||
|
||||
int QhullFacetList::
|
||||
count(const QhullFacet &facet) const
|
||||
{
|
||||
if(isSelectAll()){
|
||||
return QhullLinkedList<QhullFacet>::count(facet);
|
||||
}
|
||||
int counter= 0;
|
||||
for(QhullFacetList::const_iterator i=begin(); i != end(); ++i){
|
||||
QhullFacet f= *i;
|
||||
if(f==facet && f.isGood()){
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
return counter;
|
||||
}//count
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
#//!\name Global functions
|
||||
|
||||
using std::endl;
|
||||
using std::ostream;
|
||||
using orgQhull::QhullFacet;
|
||||
using orgQhull::QhullFacetList;
|
||||
using orgQhull::QhullVertex;
|
||||
using orgQhull::QhullVertexSet;
|
||||
|
||||
ostream &
|
||||
operator<<(ostream &os, const QhullFacetList::PrintFacetList &pr)
|
||||
{
|
||||
os << pr.print_message;
|
||||
QhullFacetList fs= *pr.facet_list;
|
||||
os << "Vertices for " << fs.count() << " facets" << endl;
|
||||
os << fs.printVertices();
|
||||
os << fs.printFacets();
|
||||
return os;
|
||||
}//operator<<
|
||||
|
||||
//! Print facet list to stream. From qh_printafacet [io_r.c]
|
||||
ostream &
|
||||
operator<<(ostream &os, const QhullFacetList::PrintFacets &pr)
|
||||
{
|
||||
for(QhullFacetList::const_iterator i= pr.facet_list->begin(); i != pr.facet_list->end(); ++i){
|
||||
QhullFacet f= *i;
|
||||
if(pr.facet_list->isSelectAll() || f.isGood()){
|
||||
os << f.print("");
|
||||
}
|
||||
}
|
||||
return os;
|
||||
}//printFacets
|
||||
|
||||
//! Print vertices of good faces in facet list to stream. From qh_printvertexlist [io_r.c]
|
||||
//! Same as vertices_toStdVector
|
||||
ostream &
|
||||
operator<<(ostream &os, const QhullFacetList::PrintVertices &pr)
|
||||
{
|
||||
QhullVertexSet vs(pr.facet_list->qh(), pr.facet_list->first().getFacetT(), NULL, pr.facet_list->isSelectAll());
|
||||
for(QhullVertexSet::iterator i=vs.begin(); i!=vs.end(); ++i){
|
||||
QhullVertex v= *i;
|
||||
os << v.print("");
|
||||
}
|
||||
return os;
|
||||
}//printVertices
|
||||
|
||||
std::ostream &
|
||||
operator<<(ostream &os, const QhullFacetList &fs)
|
||||
{
|
||||
os << fs.printFacets();
|
||||
return os;
|
||||
}//QhullFacetList
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/QhullFacetList.h#3 $$Change: 3001 $
|
||||
** $DateTime: 2020/07/24 20:43:28 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QHULLFACETLIST_H
|
||||
#define QHULLFACETLIST_H
|
||||
|
||||
#include "libqhullcpp/QhullLinkedList.h"
|
||||
#include "libqhullcpp/QhullFacet.h"
|
||||
|
||||
#include <ostream>
|
||||
|
||||
#ifndef QHULL_NO_STL
|
||||
#include <vector>
|
||||
#endif
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
#//!\name Used here
|
||||
class Qhull;
|
||||
class QhullFacet;
|
||||
class QhullQh;
|
||||
|
||||
#//!\name Defined here
|
||||
//! QhullFacetList -- List of QhullFacet/facetT, as a C++ class.
|
||||
//!\see QhullFacetSet.h
|
||||
class QhullFacetList;
|
||||
//! QhullFacetListIterator is a Java-style iterator for QhullFacetList. -- if(f.isGood()){ ... }
|
||||
typedef QhullLinkedListIterator<QhullFacet> QhullFacetListIterator;
|
||||
|
||||
class QhullFacetList : public QhullLinkedList<QhullFacet> {
|
||||
|
||||
#//!\name Fields
|
||||
private:
|
||||
bool select_all; //! True if include bad facets. Default is false.
|
||||
|
||||
#//!\name Constructors
|
||||
public:
|
||||
QhullFacetList(const Qhull &q, facetT *b, facetT *e);
|
||||
QhullFacetList(QhullQh *qqh, facetT *b, facetT *e);
|
||||
QhullFacetList(QhullFacet b, QhullFacet e) : QhullLinkedList<QhullFacet>(b, e), select_all(false) {}
|
||||
//Copy constructor copies pointer but not contents. Needed for return by value and parameter passing.
|
||||
QhullFacetList(const QhullFacetList &other) : QhullLinkedList<QhullFacet>(*other.begin(), *other.end()), select_all(other.select_all) {}
|
||||
QhullFacetList & operator=(const QhullFacetList &other) { QhullLinkedList<QhullFacet>::operator =(other); select_all= other.select_all; return *this; }
|
||||
~QhullFacetList() {}
|
||||
|
||||
private: //!Disable default constructor. See QhullLinkedList
|
||||
QhullFacetList();
|
||||
public:
|
||||
|
||||
#//!\name Conversion
|
||||
#ifndef QHULL_NO_STL
|
||||
std::vector<QhullFacet> toStdVector() const;
|
||||
std::vector<QhullVertex> vertices_toStdVector() const;
|
||||
#endif //QHULL_NO_STL
|
||||
#ifdef QHULL_USES_QT
|
||||
QList<QhullFacet> toQList() const;
|
||||
QList<QhullVertex> vertices_toQList() const;
|
||||
#endif //QHULL_USES_QT
|
||||
|
||||
#//!\name GetSet
|
||||
//! Filtered by facet.isGood(). May be 0 when !isEmpty().
|
||||
countT count() const;
|
||||
bool contains(const QhullFacet &f) const;
|
||||
countT count(const QhullFacet &f) const;
|
||||
bool isSelectAll() const { return select_all; }
|
||||
QhullQh * qh() const { return first().qh(); }
|
||||
void selectAll() { select_all= true; }
|
||||
void selectGood() { select_all= false; }
|
||||
//!< operator==() does not depend on isGood()
|
||||
|
||||
#//!\name IO
|
||||
struct PrintFacetList{
|
||||
const QhullFacetList *facet_list;
|
||||
const char * print_message; //!< non-null message
|
||||
PrintFacetList(const QhullFacetList &fl, const char *message) : facet_list(&fl), print_message(message) {}
|
||||
};//PrintFacetList
|
||||
PrintFacetList print(const char *message) const { return PrintFacetList(*this, message); }
|
||||
|
||||
struct PrintFacets{
|
||||
const QhullFacetList *facet_list;
|
||||
PrintFacets(const QhullFacetList &fl) : facet_list(&fl) {}
|
||||
};//PrintFacets
|
||||
PrintFacets printFacets() const { return PrintFacets(*this); }
|
||||
|
||||
struct PrintVertices{
|
||||
const QhullFacetList *facet_list;
|
||||
PrintVertices(const QhullFacetList &fl) : facet_list(&fl) {}
|
||||
};//PrintVertices
|
||||
PrintVertices printVertices() const { return PrintVertices(*this); }
|
||||
};//class QhullFacetList
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
#//!\name == Global namespace =========================================
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacetList::PrintFacetList &p);
|
||||
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacetList::PrintFacets &p);
|
||||
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacetList::PrintVertices &p);
|
||||
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacetList &fs);
|
||||
|
||||
#endif // QHULLFACETLIST_H
|
||||
@@ -0,0 +1,147 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/QhullFacetSet.cpp#2 $$Change: 2953 $
|
||||
** $DateTime: 2020/05/21 22:05:32 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#//! QhullFacetSet -- Qhull's linked facets, as a C++ class
|
||||
|
||||
#include "libqhullcpp/QhullFacetSet.h"
|
||||
|
||||
#include "libqhullcpp/QhullFacet.h"
|
||||
#include "libqhullcpp/QhullPoint.h"
|
||||
#include "libqhullcpp/QhullRidge.h"
|
||||
#include "libqhullcpp/QhullVertex.h"
|
||||
|
||||
#ifndef QHULL_NO_STL
|
||||
using std::vector;
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
|
||||
#pragma warning( disable : 4611) // interaction between '_setjmp' and C++ object destruction is non-portable
|
||||
#pragma warning( disable : 4996) // function was declared deprecated(strcpy, localtime, etc.)
|
||||
#endif
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
#//!\name Conversions
|
||||
|
||||
// See qt-qhull.cpp for QList conversions
|
||||
|
||||
#ifndef QHULL_NO_STL
|
||||
std::vector<QhullFacet> QhullFacetSet::
|
||||
toStdVector() const
|
||||
{
|
||||
QhullSetIterator<QhullFacet> i(*this);
|
||||
std::vector<QhullFacet> vs;
|
||||
while(i.hasNext()){
|
||||
QhullFacet f= i.next();
|
||||
if(isSelectAll() || f.isGood()){
|
||||
vs.push_back(f);
|
||||
}
|
||||
}
|
||||
return vs;
|
||||
}//toStdVector
|
||||
#endif //QHULL_NO_STL
|
||||
|
||||
#//!\name GetSet
|
||||
|
||||
bool QhullFacetSet::
|
||||
contains(const QhullFacet &facet) const
|
||||
{
|
||||
if(isSelectAll()){
|
||||
return QhullSet<QhullFacet>::contains(facet);
|
||||
}
|
||||
for(QhullFacetSet::const_iterator i=begin(); i != end(); ++i){
|
||||
QhullFacet f= *i;
|
||||
if(f==facet && f.isGood()){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}//contains
|
||||
|
||||
int QhullFacetSet::
|
||||
count() const
|
||||
{
|
||||
if(isSelectAll()){
|
||||
return QhullSet<QhullFacet>::count();
|
||||
}
|
||||
int counter= 0;
|
||||
for(QhullFacetSet::const_iterator i=begin(); i != end(); ++i){
|
||||
QhullFacet f= *i;
|
||||
if(f.isGood()){
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
return counter;
|
||||
}//count
|
||||
|
||||
int QhullFacetSet::
|
||||
count(const QhullFacet &facet) const
|
||||
{
|
||||
if(isSelectAll()){
|
||||
return QhullSet<QhullFacet>::count(facet);
|
||||
}
|
||||
int counter= 0;
|
||||
for(QhullFacetSet::const_iterator i=begin(); i != end(); ++i){
|
||||
QhullFacet f= *i;
|
||||
if(f==facet && f.isGood()){
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
return counter;
|
||||
}//count
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
#//!\name Global functions
|
||||
|
||||
using std::endl;
|
||||
using std::ostream;
|
||||
using orgQhull::QhullFacet;
|
||||
using orgQhull::QhullFacetSet;
|
||||
|
||||
ostream &
|
||||
operator<<(ostream &os, const QhullFacetSet &fs)
|
||||
{
|
||||
os << fs.print("");
|
||||
return os;
|
||||
}//<<QhullFacetSet
|
||||
|
||||
ostream &
|
||||
|
||||
operator<<(ostream &os, const QhullFacetSet::PrintFacetSet &pr)
|
||||
{
|
||||
os << pr.print_message;
|
||||
QhullFacetSet fs= *pr.facet_set;
|
||||
for(QhullFacetSet::iterator i=fs.begin(); i != fs.end(); ++i){
|
||||
QhullFacet f= *i;
|
||||
if(fs.isSelectAll() || f.isGood()){
|
||||
os << f;
|
||||
}
|
||||
}
|
||||
return os;
|
||||
}//<< QhullFacetSet::PrintFacetSet
|
||||
|
||||
//! Print facet identifiers to stream. Space prefix. From qh_printfacetheader [io_r.c]
|
||||
ostream &
|
||||
operator<<(ostream &os, const QhullFacetSet::PrintIdentifiers &p)
|
||||
{
|
||||
os << p.print_message;
|
||||
for(QhullFacetSet::const_iterator i=p.facet_set->begin(); i!=p.facet_set->end(); ++i){
|
||||
const QhullFacet f= *i;
|
||||
if(f.getFacetT()==qh_MERGEridge){
|
||||
os << " MERGE";
|
||||
}else if(f.getFacetT()==qh_DUPLICATEridge){
|
||||
os << " DUP";
|
||||
}else if(p.facet_set->isSelectAll() || f.isGood()){
|
||||
os << " f" << f.id();
|
||||
}
|
||||
}
|
||||
os << endl;
|
||||
return os;
|
||||
}//<<QhullFacetSet::PrintIdentifiers
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/QhullFacetSet.h#3 $$Change: 3001 $
|
||||
** $DateTime: 2020/07/24 20:43:28 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QHULLFACETSET_H
|
||||
#define QHULLFACETSET_H
|
||||
|
||||
#include "libqhullcpp/QhullSet.h"
|
||||
#include "libqhullcpp/QhullFacet.h"
|
||||
|
||||
#include <ostream>
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
#//!\name Used here
|
||||
class Qhull;
|
||||
|
||||
#//!\name Defined here
|
||||
//! QhullFacetSet -- a set of Qhull facets, as a C++ class. See QhullFacetList.h
|
||||
class QhullFacetSet;
|
||||
|
||||
//! QhullFacetSetIterator is a Java-style iterator. It may be used on temporary results.
|
||||
//! QhullFacetSetIterator copies the qh_set and qh_qh pointers in QhullSetBase
|
||||
//! QhullFacetSetIterator, iterator, and const_iterator return all facets. Select good facets with facet.isGood()
|
||||
typedef QhullSetIterator<QhullFacet> QhullFacetSetIterator;
|
||||
|
||||
class QhullFacetSet : public QhullSet<QhullFacet> {
|
||||
|
||||
#//!\name Defined here
|
||||
public:
|
||||
typedef facetT * base_type; // for QhullVertexSet
|
||||
|
||||
private:
|
||||
#//!\name Fields
|
||||
bool select_all; //! True if include bad facets. Default is false.
|
||||
|
||||
public:
|
||||
#//!\name Constructor
|
||||
//Conversion from setT* is not type-safe. Implicit conversion for void* to T
|
||||
QhullFacetSet(const Qhull &q, setT *s) : QhullSet<QhullFacet>(q, s), select_all(false) {}
|
||||
QhullFacetSet(QhullQh *qqh, setT *s) : QhullSet<QhullFacet>(qqh, s), select_all(false) {}
|
||||
//!Copy constructor copies pointers but not contents. Needed for return by value and parameter passing.
|
||||
QhullFacetSet(const QhullFacetSet &other) : QhullSet<QhullFacet>(other), select_all(other.select_all) {}
|
||||
//!Assignment copies pointers but not contents.
|
||||
QhullFacetSet & operator=(const QhullFacetSet &other) { QhullSet<QhullFacet>::operator=(other); select_all= other.select_all; return *this; }
|
||||
|
||||
private:
|
||||
//!Disable default constructor. See QhullSetBase
|
||||
QhullFacetSet();
|
||||
public:
|
||||
|
||||
#//!\name Conversion
|
||||
#ifndef QHULL_NO_STL
|
||||
std::vector<QhullFacet> toStdVector() const;
|
||||
#endif //QHULL_NO_STL
|
||||
#ifdef QHULL_USES_QT
|
||||
QList<QhullFacet> toQList() const;
|
||||
#endif //QHULL_USES_QT
|
||||
|
||||
#//!\name GetSet
|
||||
//! Filtered by facet.isGood(). May be 0 when !isEmpty().
|
||||
countT count() const;
|
||||
bool contains(const QhullFacet &f) const;
|
||||
countT count(const QhullFacet &f) const;
|
||||
bool isSelectAll() const { return select_all; }
|
||||
//! operator==() does not depend on isGood()
|
||||
void selectAll() { select_all= true; }
|
||||
void selectGood() { select_all= false; }
|
||||
|
||||
#//!\name IO
|
||||
// Not same as QhullFacetList#IO. A QhullFacetSet is a component of a QhullFacetList.
|
||||
|
||||
struct PrintFacetSet{
|
||||
const QhullFacetSet *facet_set;
|
||||
const char * print_message; //!< non-null message
|
||||
PrintFacetSet(const char *message, const QhullFacetSet *s) : facet_set(s), print_message(message) {}
|
||||
};//PrintFacetSet
|
||||
const PrintFacetSet print(const char *message) const { return PrintFacetSet(message, this); }
|
||||
|
||||
struct PrintIdentifiers{
|
||||
const QhullFacetSet *facet_set;
|
||||
const char * print_message; //!< non-null message
|
||||
PrintIdentifiers(const char *message, const QhullFacetSet *s) : facet_set(s), print_message(message) {}
|
||||
};//PrintIdentifiers
|
||||
PrintIdentifiers printIdentifiers(const char *message) const { return PrintIdentifiers(message, this); }
|
||||
|
||||
};//class QhullFacetSet
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
#//!\name == Global namespace =========================================
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacetSet &fs);
|
||||
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacetSet::PrintFacetSet &pr);
|
||||
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacetSet::PrintIdentifiers &p);
|
||||
|
||||
#endif // QHULLFACETSET_H
|
||||
@@ -0,0 +1,184 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2009-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/QhullHyperplane.cpp#5 $$Change: 3009 $
|
||||
** $DateTime: 2020/07/30 19:25:22 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "libqhullcpp/QhullHyperplane.h"
|
||||
|
||||
#include "libqhullcpp/Qhull.h"
|
||||
#include "libqhullcpp/QhullPoint.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
||||
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
|
||||
#endif
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
#//!\name Constructors
|
||||
|
||||
QhullHyperplane::
|
||||
QhullHyperplane(const Qhull &q)
|
||||
: hyperplane_coordinates(0)
|
||||
, qh_qh(q.qh())
|
||||
, hyperplane_offset(0.0)
|
||||
, hyperplane_dimension(0)
|
||||
{
|
||||
}
|
||||
|
||||
QhullHyperplane::
|
||||
QhullHyperplane(const Qhull &q, int hyperplaneDimension, coordT *c, coordT hyperplaneOffset)
|
||||
: hyperplane_coordinates(c)
|
||||
, qh_qh(q.qh())
|
||||
, hyperplane_offset(hyperplaneOffset)
|
||||
, hyperplane_dimension(hyperplaneDimension)
|
||||
{
|
||||
}
|
||||
|
||||
#//!\name Conversions
|
||||
|
||||
// See qt-qhull.cpp for QList conversions
|
||||
|
||||
#ifndef QHULL_NO_STL
|
||||
std::vector<coordT> QhullHyperplane::
|
||||
toStdVector() const
|
||||
{
|
||||
QhullHyperplaneIterator i(*this);
|
||||
std::vector<coordT> fs;
|
||||
while(i.hasNext()){
|
||||
fs.push_back(i.next());
|
||||
}
|
||||
fs.push_back(hyperplane_offset);
|
||||
return fs;
|
||||
}//toStdVector
|
||||
#endif //QHULL_NO_STL
|
||||
|
||||
#//!\name GetSet
|
||||
|
||||
//! Return true if equal
|
||||
//! If qh_qh defined, tests qh.distanceEpsilon and qh.angleEpsilon
|
||||
//! otherwise, tests equal coordinates and offset
|
||||
bool QhullHyperplane::
|
||||
operator==(const QhullHyperplane &other) const
|
||||
{
|
||||
if(hyperplane_dimension!=other.hyperplane_dimension || !hyperplane_coordinates || !other.hyperplane_coordinates){
|
||||
return false;
|
||||
}
|
||||
double d= fabs(hyperplane_offset-other.hyperplane_offset);
|
||||
if(d > (qh_qh ? qh_qh->distanceEpsilon() : 0.0)){
|
||||
return false;
|
||||
}
|
||||
double angle= hyperplaneAngle(other);
|
||||
|
||||
double a= fabs(angle-1.0);
|
||||
if(a > (qh_qh ? qh_qh->angleEpsilon() : 0.0)){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}//operator==
|
||||
|
||||
#//!\name Methods
|
||||
|
||||
//! Return distance from point to hyperplane.
|
||||
//! If greater than zero, the point is above the facet (i.e., outside).
|
||||
// qh_distplane [geom_r.c], QhullFacet::distance, and QhullHyperplane::distance are copies
|
||||
// Does not support RANDOMdist or logging
|
||||
double QhullHyperplane::
|
||||
distance(const QhullPoint &p) const
|
||||
{
|
||||
const coordT *point= p.coordinates();
|
||||
int dim= p.dimension();
|
||||
QHULL_ASSERT(dim==dimension());
|
||||
const coordT *normal= coordinates();
|
||||
double dist;
|
||||
|
||||
switch (dim){
|
||||
case 2:
|
||||
dist= offset() + point[0] * normal[0] + point[1] * normal[1];
|
||||
break;
|
||||
case 3:
|
||||
dist= offset() + point[0] * normal[0] + point[1] * normal[1] + point[2] * normal[2];
|
||||
break;
|
||||
case 4:
|
||||
dist= offset()+point[0]*normal[0]+point[1]*normal[1]+point[2]*normal[2]+point[3]*normal[3];
|
||||
break;
|
||||
case 5:
|
||||
dist= offset()+point[0]*normal[0]+point[1]*normal[1]+point[2]*normal[2]+point[3]*normal[3]+point[4]*normal[4];
|
||||
break;
|
||||
case 6:
|
||||
dist= offset()+point[0]*normal[0]+point[1]*normal[1]+point[2]*normal[2]+point[3]*normal[3]+point[4]*normal[4]+point[5]*normal[5];
|
||||
break;
|
||||
case 7:
|
||||
dist= offset()+point[0]*normal[0]+point[1]*normal[1]+point[2]*normal[2]+point[3]*normal[3]+point[4]*normal[4]+point[5]*normal[5]+point[6]*normal[6];
|
||||
break;
|
||||
case 8:
|
||||
dist= offset()+point[0]*normal[0]+point[1]*normal[1]+point[2]*normal[2]+point[3]*normal[3]+point[4]*normal[4]+point[5]*normal[5]+point[6]*normal[6]+point[7]*normal[7];
|
||||
break;
|
||||
default:
|
||||
dist= offset();
|
||||
for(int k=dim; k--; ){
|
||||
dist += *point++ * *normal++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return dist;
|
||||
}//distance
|
||||
|
||||
double QhullHyperplane::
|
||||
hyperplaneAngle(const QhullHyperplane &other) const
|
||||
{
|
||||
volatile realT result= 0.0;
|
||||
QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
|
||||
result= qh_getangle(qh_qh, hyperplane_coordinates, other.hyperplane_coordinates);
|
||||
}
|
||||
qh_qh->NOerrexit= true;
|
||||
qh_qh->maybeThrowQhullMessage(QH_TRY_status);
|
||||
return result;
|
||||
}//hyperplaneAngle
|
||||
|
||||
double QhullHyperplane::
|
||||
norm() const {
|
||||
double d= 0.0;
|
||||
const coordT *c= coordinates();
|
||||
for(int k=dimension(); k--; ){
|
||||
d += *c * *c;
|
||||
++c;
|
||||
}
|
||||
return sqrt(d);
|
||||
}//norm
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
#//!\name Global functions
|
||||
|
||||
using std::ostream;
|
||||
using orgQhull::QhullHyperplane;
|
||||
|
||||
#//!\name GetSet<<
|
||||
|
||||
ostream &
|
||||
operator<<(ostream &os, const QhullHyperplane &p)
|
||||
{
|
||||
os << p.print("");
|
||||
return os;
|
||||
}
|
||||
|
||||
ostream &
|
||||
operator<<(ostream &os, const QhullHyperplane::PrintHyperplane &pr)
|
||||
{
|
||||
os << pr.print_message;
|
||||
QhullHyperplane p= *pr.hyperplane;
|
||||
const realT *c= p.coordinates();
|
||||
for(int k=p.dimension(); k--; ){
|
||||
realT r= *c++;
|
||||
os << " " << r; // QH11010 FIX: %8.4g qh_REAL_1
|
||||
}
|
||||
os << pr.hyperplane_offset_message << " " << p.offset();
|
||||
os << std::endl;
|
||||
return os;
|
||||
}//PrintHyperplane
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2009-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/QhullHyperplane.h#4 $$Change: 3008 $
|
||||
** $DateTime: 2020/07/30 13:54:27 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QHHYPERPLANE_H
|
||||
#define QHHYPERPLANE_H
|
||||
|
||||
#include "libqhull_r/qhull_ra.h"
|
||||
#include "libqhullcpp/QhullError.h"
|
||||
#include "libqhullcpp/QhullIterator.h"
|
||||
#include "libqhullcpp/QhullQh.h"
|
||||
|
||||
#include <ostream>
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
#//!\name Used here
|
||||
class Qhull;
|
||||
class QhullPoint;
|
||||
|
||||
#//!\name Defined here
|
||||
class QhullHyperplane; //!< QhullHyperplane is a pointer to the normal vector, an offset from the origin, and dimension
|
||||
class QhullHyperplaneIterator; //!< Java-style iterator for QhullHyperplane coordinates
|
||||
|
||||
class QhullHyperplane { // Similar to QhullPoint
|
||||
public:
|
||||
#//!\name Subtypes
|
||||
typedef const coordT * iterator;
|
||||
typedef const coordT * const_iterator;
|
||||
typedef QhullHyperplane::iterator Iterator;
|
||||
typedef QhullHyperplane::const_iterator ConstIterator;
|
||||
|
||||
private:
|
||||
#//!\name Fields
|
||||
coordT * hyperplane_coordinates; //!< Normal to hyperplane. facetT.normal is normalized to 1.0
|
||||
QhullQh * qh_qh; //!< qhT for distanceEpsilon() in operator==
|
||||
coordT hyperplane_offset; //!< Distance from hyperplane to origin
|
||||
int hyperplane_dimension; //!< Dimension of hyperplane
|
||||
|
||||
#//!\name Construct
|
||||
public:
|
||||
QhullHyperplane() : hyperplane_coordinates(0), qh_qh(0), hyperplane_offset(0.0), hyperplane_dimension(0) {}
|
||||
explicit QhullHyperplane(const Qhull &q);
|
||||
QhullHyperplane(const Qhull &q, int hyperplaneDimension, coordT *c, coordT hyperplaneOffset);
|
||||
explicit QhullHyperplane(QhullQh *qqh) : hyperplane_coordinates(0), qh_qh(qqh), hyperplane_offset(0.0), hyperplane_dimension(0) {}
|
||||
QhullHyperplane(QhullQh *qqh, int hyperplaneDimension, coordT *c, coordT hyperplaneOffset) : hyperplane_coordinates(c), qh_qh(qqh), hyperplane_offset(hyperplaneOffset), hyperplane_dimension(hyperplaneDimension) {}
|
||||
// Creates an alias. Does not copy the hyperplane's coordinates. Needed for return by value and parameter passing.
|
||||
QhullHyperplane(const QhullHyperplane &other) : hyperplane_coordinates(other.hyperplane_coordinates), qh_qh(other.qh_qh), hyperplane_offset(other.hyperplane_offset), hyperplane_dimension(other.hyperplane_dimension) {}
|
||||
// Creates an alias. Does not copy the hyperplane's coordinates. Needed for vector<QhullHyperplane>
|
||||
QhullHyperplane & operator=(const QhullHyperplane &other) { hyperplane_coordinates= other.hyperplane_coordinates; qh_qh= other.qh_qh; hyperplane_offset= other.hyperplane_offset; hyperplane_dimension= other.hyperplane_dimension; return *this; }
|
||||
~QhullHyperplane() {}
|
||||
|
||||
#//!\name Conversions --
|
||||
//! Includes offset at end
|
||||
#ifndef QHULL_NO_STL
|
||||
std::vector<coordT> toStdVector() const;
|
||||
#endif //QHULL_NO_STL
|
||||
#ifdef QHULL_USES_QT
|
||||
QList<coordT> toQList() const;
|
||||
#endif //QHULL_USES_QT
|
||||
|
||||
#//!\name GetSet
|
||||
public:
|
||||
const coordT * coordinates() const { return hyperplane_coordinates; }
|
||||
coordT * coordinates() { return hyperplane_coordinates; }
|
||||
void defineAs(int hyperplaneDimension, coordT *c, coordT hyperplaneOffset) { QHULL_ASSERT(hyperplaneDimension>=0); hyperplane_coordinates= c; hyperplane_dimension= hyperplaneDimension; hyperplane_offset= hyperplaneOffset; }
|
||||
//! Creates an alias to other using the same qh_qh
|
||||
void defineAs(QhullHyperplane &other) { hyperplane_coordinates= other.coordinates(); hyperplane_dimension= other.dimension(); hyperplane_offset= other.offset(); }
|
||||
int dimension() const { return hyperplane_dimension; }
|
||||
bool isValid() const { return hyperplane_coordinates!=0 && hyperplane_dimension>0; }
|
||||
coordT offset() const { return hyperplane_offset; }
|
||||
bool operator==(const QhullHyperplane &other) const;
|
||||
bool operator!=(const QhullHyperplane &other) const { return !operator==(other); }
|
||||
const coordT & operator[](int idx) const { QHULL_ASSERT(idx>=0 && idx<hyperplane_dimension); return *(hyperplane_coordinates+idx); }
|
||||
coordT & operator[](int idx) { QHULL_ASSERT(idx>=0 && idx<hyperplane_dimension); return *(hyperplane_coordinates+idx); }
|
||||
void setCoordinates(coordT *c) { hyperplane_coordinates= c; }
|
||||
void setDimension(int hyperplaneDimension) { hyperplane_dimension= hyperplaneDimension; }
|
||||
void setOffset(coordT hyperplaneOffset) { hyperplane_offset= hyperplaneOffset; }
|
||||
|
||||
#//!\name iterator
|
||||
iterator begin() { return hyperplane_coordinates; }
|
||||
const_iterator begin() const { return hyperplane_coordinates; }
|
||||
const_iterator constBegin() const { return hyperplane_coordinates; }
|
||||
const_iterator constEnd() const { return hyperplane_coordinates+hyperplane_dimension; }
|
||||
int count() { return hyperplane_dimension; }
|
||||
iterator end() { return hyperplane_coordinates+hyperplane_dimension; }
|
||||
const_iterator end() const { return hyperplane_coordinates+hyperplane_dimension; }
|
||||
size_t size() { return static_cast<size_t>(hyperplane_dimension); }
|
||||
|
||||
#//!\name Methods
|
||||
double distance(const QhullPoint &p) const;
|
||||
double hyperplaneAngle(const QhullHyperplane &other) const;
|
||||
double norm() const;
|
||||
|
||||
#//!\name IO
|
||||
struct PrintHyperplane{
|
||||
const QhullHyperplane *hyperplane;
|
||||
const char * print_message; //!< non-null message
|
||||
const char * hyperplane_offset_message; //!< non-null message
|
||||
PrintHyperplane(const char *message, const char *offsetMessage, const QhullHyperplane &p) : hyperplane(&p), print_message(message), hyperplane_offset_message(offsetMessage) {}
|
||||
};//PrintHyperplane
|
||||
PrintHyperplane print(const char *message) const { return PrintHyperplane(message, "", *this); }
|
||||
PrintHyperplane print(const char *message, const char *offsetMessage) const { return PrintHyperplane(message, offsetMessage, *this); }
|
||||
|
||||
};//QhullHyperplane
|
||||
|
||||
//! QhullHyperplaneIterator is a Java-style iterator for QhullHyperplane coordinates
|
||||
QHULL_DECLARE_SEQUENTIAL_ITERATOR(QhullHyperplane, coordT)
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
#//!\name Global
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullHyperplane::PrintHyperplane &pr);
|
||||
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullHyperplane &p);
|
||||
|
||||
#endif // QHHYPERPLANE_H
|
||||
|
||||
@@ -0,0 +1,174 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/QhullIterator.h#4 $$Change: 3001 $
|
||||
** $DateTime: 2020/07/24 20:43:28 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QHULLITERATOR_H
|
||||
#define QHULLITERATOR_H
|
||||
|
||||
#include "libqhull_r/qhull_ra.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
#//!\name Defined here
|
||||
//! Only QHULL_DECLARE_SEQUENTIAL_ITERATOR is used in libqhullcpp. The others need further development
|
||||
//! QHULL_DECLARE_SEQUENTIAL_ITERATOR(C) -- Declare a Java-style iterator
|
||||
//! QHULL_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(C) -- Declare a mutable Java-style iterator
|
||||
//! QHULL_DECLARE_SET_ITERATOR(C) -- Declare a set iterator
|
||||
//! QHULL_DECLARE_MUTABLE_SET_ITERATOR(C) -- Declare a mutable set iterator
|
||||
//! Derived from Qt/core/tools/qiterator.h and qset_r.h/FOREACHsetelement_()
|
||||
|
||||
//! Stores C as done in Qt's Q_DECLARE_SEQUENTIAL_ITERATOR. Allows use with temporaries.
|
||||
//! Do not use for containers with deep-copy semantics (e.g., STL::vector)
|
||||
// C::const_iterator is an STL-style iterator that returns T&
|
||||
#define QHULL_DECLARE_SEQUENTIAL_ITERATOR(C, T) \
|
||||
\
|
||||
class C##Iterator \
|
||||
{ \
|
||||
typedef C::const_iterator const_iterator; \
|
||||
C c; \
|
||||
const_iterator i; \
|
||||
public: \
|
||||
inline C##Iterator(const C &container) \
|
||||
: c(container), i(c.constBegin()) {} \
|
||||
inline C##Iterator &operator=(const C &container) \
|
||||
{ c= container; i= c.constBegin(); return *this; } \
|
||||
inline void toFront() { i= c.constBegin(); } \
|
||||
inline void toBack() { i= c.constEnd(); } \
|
||||
inline bool hasNext() const { return i != c.constEnd(); } \
|
||||
inline const T &next() { return *i++; } \
|
||||
inline const T &peekNext() const { return *i; } \
|
||||
inline bool hasPrevious() const { return i != c.constBegin(); } \
|
||||
inline const T &previous() { return *--i; } \
|
||||
inline const T &peekPrevious() const { const_iterator p= i; return *--p; } \
|
||||
inline bool findNext(const T &t) \
|
||||
{ while (i != c.constEnd()) if (*i++ == t) return true; return false; } \
|
||||
inline bool findPrevious(const T &t) \
|
||||
{ while (i != c.constBegin()) if (*(--i) == t) return true; \
|
||||
return false; } \
|
||||
};//C##Iterator
|
||||
|
||||
// Remove setShareable() from Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR
|
||||
// Uses QHULL_ASSERT (assert.h)
|
||||
// Duplicated in MutablePointIterator without insert or remove
|
||||
// Not used in libqhullcpp. See Coordinates.h
|
||||
#define QHULL_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(C, T) \
|
||||
class Mutable##C##Iterator \
|
||||
{ \
|
||||
typedef C::iterator iterator; \
|
||||
typedef C::const_iterator const_iterator; \
|
||||
C *c; \
|
||||
iterator i, n; \
|
||||
inline bool item_exists() const { return const_iterator(n) != c->constEnd(); } \
|
||||
public: \
|
||||
inline Mutable##C##Iterator(C &container) \
|
||||
: c(&container) \
|
||||
{ i= c->begin(); n= c->end(); } \
|
||||
inline ~Mutable##C##Iterator() \
|
||||
{} \
|
||||
inline Mutable##C##Iterator &operator=(C &container) \
|
||||
{ c= &container; \
|
||||
i= c->begin(); n= c->end(); return *this; } \
|
||||
inline void toFront() { i= c->begin(); n= c->end(); } \
|
||||
inline void toBack() { i= c->end(); n= i; } \
|
||||
inline bool hasNext() const { return c->constEnd() != const_iterator(i); } \
|
||||
inline T &next() { n= i++; return *n; } \
|
||||
inline T &peekNext() const { return *i; } \
|
||||
inline bool hasPrevious() const { return c->constBegin() != const_iterator(i); } \
|
||||
inline T &previous() { n= --i; return *n; } \
|
||||
inline T &peekPrevious() const { iterator p= i; return *--p; } \
|
||||
inline void remove() \
|
||||
{ if (c->constEnd() != const_iterator(n)) { i= c->erase(n); n= c->end(); } } \
|
||||
inline void setValue(const T &t) const { if (c->constEnd() != const_iterator(n)) *n= t; } \
|
||||
inline T &value() { QHULL_ASSERT(item_exists()); return *n; } \
|
||||
inline const T &value() const { QHULL_ASSERT(item_exists()); return *n; } \
|
||||
inline void insert(const T &t) { n= i= c->insert(i, t); ++i; } \
|
||||
inline bool findNext(const T &t) \
|
||||
{ while (c->constEnd() != const_iterator(n= i)) if (*i++ == t) return true; return false; } \
|
||||
inline bool findPrevious(const T &t) \
|
||||
{ while (c->constBegin() != const_iterator(i)) if (*(n= --i) == t) return true; \
|
||||
n= c->end(); return false; } \
|
||||
};//Mutable##C##Iterator
|
||||
|
||||
// Not used in libqhullcpp.
|
||||
#define QHULL_DECLARE_SET_ITERATOR(C) \
|
||||
\
|
||||
template <class T> \
|
||||
class Qhull##C##Iterator \
|
||||
{ \
|
||||
typedef typename Qhull##C<T>::const_iterator const_iterator; \
|
||||
Qhull##C<T> c; \
|
||||
const_iterator i; \
|
||||
public: \
|
||||
inline Qhull##C##Iterator(const Qhull##C<T> &container) \
|
||||
: c(container), i(c.constBegin()) {} \
|
||||
inline Qhull##C##Iterator &operator=(const Qhull##C<T> &container) \
|
||||
{ c= container; i= c.constBegin(); return *this; } \
|
||||
inline void toFront() { i= c.constBegin(); } \
|
||||
inline void toBack() { i= c.constEnd(); } \
|
||||
inline bool hasNext() const { return i != c.constEnd(); } \
|
||||
inline const T &next() { return *i++; } \
|
||||
inline const T &peekNext() const { return *i; } \
|
||||
inline bool hasPrevious() const { return i != c.constBegin(); } \
|
||||
inline const T &previous() { return *--i; } \
|
||||
inline const T &peekPrevious() const { const_iterator p= i; return *--p; } \
|
||||
inline bool findNext(const T &t) \
|
||||
{ while (i != c.constEnd()) if (*i++ == t) return true; return false; } \
|
||||
inline bool findPrevious(const T &t) \
|
||||
{ while (i != c.constBegin()) if (*(--i) == t) return true; \
|
||||
return false; } \
|
||||
};//Qhull##C##Iterator
|
||||
|
||||
// Not used in libqhullcpp.
|
||||
#define QHULL_DECLARE_MUTABLE_SET_ITERATOR(C) \
|
||||
\
|
||||
template <class T> \
|
||||
class QhullMutable##C##Iterator \
|
||||
{ \
|
||||
typedef typename Qhull##C::iterator iterator; \
|
||||
typedef typename Qhull##C::const_iterator const_iterator; \
|
||||
Qhull##C *c; \
|
||||
iterator i, n; \
|
||||
inline bool item_exists() const { return const_iterator(n) != c->constEnd(); } \
|
||||
public: \
|
||||
inline Mutable##C##Iterator(Qhull##C &container) \
|
||||
: c(&container) \
|
||||
{ c->setSharable(false); i= c->begin(); n= c->end(); } \
|
||||
inline ~Mutable##C##Iterator() \
|
||||
{ c->setSharable(true); } \
|
||||
inline Mutable##C##Iterator &operator=(Qhull##C &container) \
|
||||
{ c->setSharable(true); c= &container; c->setSharable(false); \
|
||||
i= c->begin(); n= c->end(); return *this; } \
|
||||
inline void toFront() { i= c->begin(); n= c->end(); } \
|
||||
inline void toBack() { i= c->end(); n= i; } \
|
||||
inline bool hasNext() const { return c->constEnd() != const_iterator(i); } \
|
||||
inline T &next() { n= i++; return *n; } \
|
||||
inline T &peekNext() const { return *i; } \
|
||||
inline bool hasPrevious() const { return c->constBegin() != const_iterator(i); } \
|
||||
inline T &previous() { n= --i; return *n; } \
|
||||
inline T &peekPrevious() const { iterator p= i; return *--p; } \
|
||||
inline void remove() \
|
||||
{ if (c->constEnd() != const_iterator(n)) { i= c->erase(n); n= c->end(); } } \
|
||||
inline void setValue(const T &t) const { if (c->constEnd() != const_iterator(n)) *n= t; } \
|
||||
inline T &value() { Q_ASSERT(item_exists()); return *n; } \
|
||||
inline const T &value() const { Q_ASSERT(item_exists()); return *n; } \
|
||||
inline void insert(const T &t) { n= i= c->insert(i, t); ++i; } \
|
||||
inline bool findNext(const T &t) \
|
||||
{ while (c->constEnd() != const_iterator(n= i)) if (*i++ == t) return true; return false; } \
|
||||
inline bool findPrevious(const T &t) \
|
||||
{ while (c->constBegin() != const_iterator(i)) if (*(n= --i) == t) return true; \
|
||||
n= c->end(); return false; } \
|
||||
};//QhullMutable##C##Iterator
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
#endif // QHULLITERATOR_H
|
||||
|
||||
@@ -0,0 +1,390 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/QhullLinkedList.h#7 $$Change: 3396 $
|
||||
** $DateTime: 2023/01/02 16:59:48 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QHULLLINKEDLIST_H
|
||||
#define QHULLLINKEDLIST_H
|
||||
|
||||
#include "libqhull_r/qhull_ra.h"
|
||||
#include "libqhullcpp/QhullError.h"
|
||||
|
||||
#include <cstddef> // ptrdiff_t, size_t
|
||||
|
||||
#ifdef QHULL_USES_QT
|
||||
#include <QtCore/QList>
|
||||
#endif
|
||||
|
||||
#ifndef QHULL_NO_STL
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
#endif
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
#//!\name Defined here
|
||||
//! QhullLinkedList<T> -- A linked list modeled on QLinkedList.
|
||||
//! T is an opaque type with T(B *b), b=t.getBaseT(), t=t.next(), and t=t.prev(). The end node is a sentinel.
|
||||
//! QhullQh/qhT owns the contents.
|
||||
//! QhullLinkedList does not define erase(), clear(), removeFirst(), removeLast(), pop_back(), pop_front(), fromStdList()
|
||||
//! Derived from Qt/core/tools/qlinkedlist.h and libqhull_r.h/FORALLfacets_()
|
||||
//! QhullLinkedList<T>::const_iterator -- STL-style iterator
|
||||
//! QhullLinkedList<T>::iterator -- STL-style iterator
|
||||
//! QhullLinkedListIterator<T> -- Java-style iterator
|
||||
//! Derived from Qt/core/tools/qiterator.h
|
||||
//! Works with Qt's foreach keyword [Qt/src/corelib/global/qglobal.h]
|
||||
|
||||
template <typename T>
|
||||
class QhullLinkedList
|
||||
{
|
||||
#//!\name Defined here
|
||||
public:
|
||||
class const_iterator;
|
||||
class iterator;
|
||||
typedef const_iterator ConstIterator;
|
||||
typedef iterator Iterator;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef countT size_type;
|
||||
typedef T value_type;
|
||||
typedef const value_type *const_pointer;
|
||||
typedef const value_type &const_reference;
|
||||
typedef value_type *pointer;
|
||||
typedef value_type &reference;
|
||||
|
||||
#//!\name Fields
|
||||
private:
|
||||
T begin_node;
|
||||
T end_node; //! Sentinel node at end of list
|
||||
|
||||
#//!\name Constructors
|
||||
public:
|
||||
|
||||
QhullLinkedList(T b, T e) : begin_node(b), end_node(e) {}
|
||||
//! Copy constructor copies begin_node and end_node, but not the list elements. Needed for return by value and parameter passing.
|
||||
|
||||
QhullLinkedList(const QhullLinkedList<T> &other) : begin_node(other.begin_node), end_node(other.end_node) {}
|
||||
//! Copy assignment copies begin_node and end_node, but not the list elements.
|
||||
QhullLinkedList & operator=(const QhullLinkedList &other) { begin_node= other.begin_node; end_node= other.end_node; return *this; }
|
||||
~QhullLinkedList() {}
|
||||
|
||||
private:
|
||||
//!disabled since a sentinel must be allocated as the private type
|
||||
QhullLinkedList() {}
|
||||
|
||||
public:
|
||||
|
||||
#//!\name Conversions
|
||||
#ifndef QHULL_NO_STL
|
||||
std::vector<T> toStdVector() const;
|
||||
#endif
|
||||
#ifdef QHULL_USES_QT
|
||||
QList<T> toQList() const;
|
||||
#endif
|
||||
|
||||
#//!\name GetSet
|
||||
countT count() const;
|
||||
//count(t) under #//!\name Search
|
||||
bool isEmpty() const { return (begin_node==end_node); }
|
||||
bool operator==(const QhullLinkedList<T> &o) const;
|
||||
bool operator!=(const QhullLinkedList<T> &o) const { return !operator==(o); }
|
||||
size_t size() const { return count(); }
|
||||
|
||||
#//!\name Element access
|
||||
//! For back() and last(), return T instead of T& (T is computed)
|
||||
const T back() const { return last(); }
|
||||
T back() { return last(); }
|
||||
const T & first() const { QHULL_ASSERT(!isEmpty()); return begin_node; }
|
||||
T & first() { QHULL_ASSERT(!isEmpty()); return begin_node; }
|
||||
const T & front() const { return first(); }
|
||||
T & front() { return first(); }
|
||||
const T last() const { QHULL_ASSERT(!isEmpty()); return *--end(); }
|
||||
T last() { QHULL_ASSERT(!isEmpty()); return *--end(); }
|
||||
|
||||
#//!\name Modify -- Allocation of opaque types not implemented.
|
||||
|
||||
#//!\name Search
|
||||
bool contains(const T &t) const;
|
||||
countT count(const T &t) const;
|
||||
|
||||
#//!\name Iterator
|
||||
iterator begin() { return begin_node; }
|
||||
const_iterator begin() const { return begin_node; }
|
||||
const_iterator constBegin() const { return begin_node; }
|
||||
const_iterator constEnd() const { return end_node; }
|
||||
iterator end() { return end_node; }
|
||||
const_iterator end() const { return end_node; }
|
||||
|
||||
class iterator {
|
||||
|
||||
private:
|
||||
T i;
|
||||
friend class const_iterator;
|
||||
|
||||
public:
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
typedef T value_type;
|
||||
typedef value_type *pointer;
|
||||
typedef value_type &reference;
|
||||
typedef ptrdiff_t difference_type;
|
||||
|
||||
iterator() : i() {}
|
||||
iterator(const T &t) : i(t) {} //!< Automatic conversion to iterator
|
||||
iterator(const iterator &o) : i(o.i) {}
|
||||
iterator & operator=(const iterator &o) { i= o.i; return *this; }
|
||||
|
||||
const T & operator*() const { return i; }
|
||||
T & operator*() { return i; }
|
||||
// Do not define operator[]
|
||||
const T * operator->() const { return &i; }
|
||||
T * operator->() { return &i; }
|
||||
bool operator==(const iterator &o) const { return i == o.i; }
|
||||
bool operator!=(const iterator &o) const { return !operator==(o); }
|
||||
bool operator==(const const_iterator &o) const { return i==reinterpret_cast<const iterator &>(o).i; }
|
||||
bool operator!=(const const_iterator &o) const { return !operator==(o); }
|
||||
iterator & operator++() { i= i.next(); return *this; }
|
||||
iterator operator++(int) { iterator o= i; i= i.next(); return o; }
|
||||
iterator & operator--() { i= i.previous(); return *this; }
|
||||
iterator operator--(int) { iterator o= i; i= i.previous(); return o; }
|
||||
iterator operator+(int j) const;
|
||||
iterator operator-(int j) const { return operator+(-j); }
|
||||
iterator & operator+=(int j) { return (*this= *this + j); }
|
||||
iterator & operator-=(int j) { return (*this= *this - j); }
|
||||
};//QhullLinkedList::iterator
|
||||
|
||||
class const_iterator {
|
||||
|
||||
private:
|
||||
T i;
|
||||
|
||||
public:
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
typedef T value_type;
|
||||
typedef const value_type *pointer;
|
||||
typedef const value_type &reference;
|
||||
typedef ptrdiff_t difference_type;
|
||||
|
||||
const_iterator() : i() {}
|
||||
const_iterator(const T &t) : i(t) {} //!< Automatic conversion to const_iterator
|
||||
const_iterator(const iterator &o) : i(o.i) {}
|
||||
const_iterator(const const_iterator &o) : i(o.i) {}
|
||||
const_iterator &operator=(const const_iterator &o) { i= o.i; return *this; }
|
||||
|
||||
const T & operator*() const { return i; }
|
||||
const T * operator->() const { return &i; }
|
||||
bool operator==(const const_iterator &o) const { return i == o.i; }
|
||||
bool operator!=(const const_iterator &o) const { return !operator==(o); }
|
||||
// No comparisons or iterator diff
|
||||
const_iterator &operator++() { i= i.next(); return *this; }
|
||||
const_iterator operator++(int) { const_iterator o= i; i= i.next(); return o; }
|
||||
const_iterator &operator--() { i= i.previous(); return *this; }
|
||||
const_iterator operator--(int) { const_iterator o= i; i= i.previous(); return o; }
|
||||
const_iterator operator+(int j) const;
|
||||
const_iterator operator-(int j) const { return operator+(-j); }
|
||||
const_iterator &operator+=(int j) { return (*this= *this + j); }
|
||||
const_iterator &operator-=(int j) { return (*this= *this - j); }
|
||||
};//QhullLinkedList::const_iterator
|
||||
|
||||
};//QhullLinkedList
|
||||
|
||||
template <typename T>
|
||||
class QhullLinkedListIterator // QH11016 FIX: define QhullMutableLinkedListIterator
|
||||
{
|
||||
typedef typename QhullLinkedList<T>::const_iterator const_iterator;
|
||||
QhullLinkedList<T> c;
|
||||
const_iterator i;
|
||||
|
||||
public:
|
||||
QhullLinkedListIterator(const QhullLinkedList<T> &container) : c(container), i(c.constBegin()) {}
|
||||
QhullLinkedListIterator & operator=(const QhullLinkedList<T> &container) { c= container; i= c.constBegin(); return *this; }
|
||||
bool findNext(const T &t);
|
||||
bool findPrevious(const T &t);
|
||||
bool hasNext() const { return i != c.constEnd(); }
|
||||
bool hasPrevious() const { return i != c.constBegin(); }
|
||||
T next() { return *i++; }
|
||||
T peekNext() const { return *i; }
|
||||
T peekPrevious() const { const_iterator p= i; return *--p; }
|
||||
T previous() { return *--i; }
|
||||
void toFront() { i= c.constBegin(); }
|
||||
void toBack() { i= c.constEnd(); }
|
||||
};//QhullLinkedListIterator
|
||||
|
||||
#//!\name == Definitions =========================================
|
||||
|
||||
#//!\name Conversion
|
||||
|
||||
#ifndef QHULL_NO_STL
|
||||
template <typename T>
|
||||
std::vector<T> QhullLinkedList<T>::
|
||||
toStdVector() const
|
||||
{
|
||||
std::vector<T> tmp;
|
||||
std::copy(constBegin(), constEnd(), std::back_inserter(tmp));
|
||||
return tmp;
|
||||
}//toStdVector
|
||||
#endif
|
||||
|
||||
#ifdef QHULL_USES_QT
|
||||
template <typename T>
|
||||
QList<T> QhullLinkedList<T>::
|
||||
toQList() const
|
||||
{
|
||||
QhullLinkedListIterator<T> i(*this);
|
||||
QList<T> ls;
|
||||
while(i.hasNext()){
|
||||
ls.append(i.next());
|
||||
}
|
||||
return ls;
|
||||
}//toQList
|
||||
#endif
|
||||
|
||||
#//!\name GetSet
|
||||
|
||||
template <typename T>
|
||||
countT QhullLinkedList<T>::
|
||||
count() const
|
||||
{
|
||||
const_iterator i= begin_node;
|
||||
countT c= 0;
|
||||
while(i != end_node){
|
||||
c++;
|
||||
i++;
|
||||
}
|
||||
return c;
|
||||
}//count
|
||||
|
||||
#//!\name Search
|
||||
|
||||
template <typename T>
|
||||
bool QhullLinkedList<T>::
|
||||
contains(const T &t) const
|
||||
{
|
||||
const_iterator i= begin_node;
|
||||
while(i != end_node){
|
||||
if(i==t){
|
||||
return true;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return false;
|
||||
}//contains
|
||||
|
||||
template <typename T>
|
||||
countT QhullLinkedList<T>::
|
||||
count(const T &t) const
|
||||
{
|
||||
const_iterator i= begin_node;
|
||||
countT c= 0;
|
||||
while(i != end_node){
|
||||
if(i==t){
|
||||
c++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return c;
|
||||
}//count
|
||||
|
||||
template <typename T>
|
||||
bool QhullLinkedList<T>::
|
||||
operator==(const QhullLinkedList<T> &l) const
|
||||
{
|
||||
if(begin_node==l.begin_node){
|
||||
return (end_node==l.end_node);
|
||||
}
|
||||
T i= begin_node;
|
||||
T il= l.begin_node;
|
||||
while(i != end_node){
|
||||
if(i != il){
|
||||
return false;
|
||||
}
|
||||
i= static_cast<T>(i.next());
|
||||
il= static_cast<T>(il.next());
|
||||
}
|
||||
if(il != l.end_node){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}//operator==
|
||||
|
||||
#//!\name Iterator
|
||||
|
||||
template <typename T>
|
||||
typename QhullLinkedList<T>::iterator QhullLinkedList<T>::iterator::
|
||||
operator+(int j) const
|
||||
{
|
||||
T n= i;
|
||||
if(j>0){
|
||||
while(j--){
|
||||
n= n.next();
|
||||
}
|
||||
}else{
|
||||
while(j++){
|
||||
n= n.previous();
|
||||
}
|
||||
}
|
||||
return iterator(n);
|
||||
}//operator+
|
||||
|
||||
template <typename T>
|
||||
typename QhullLinkedList<T>::const_iterator QhullLinkedList<T>::const_iterator::
|
||||
operator+(int j) const
|
||||
{
|
||||
T n= i;
|
||||
if(j>0){
|
||||
while(j--){
|
||||
n= n.next();
|
||||
}
|
||||
}else{
|
||||
while(j++){
|
||||
n= n.previous();
|
||||
}
|
||||
}
|
||||
return const_iterator(n);
|
||||
}//operator+
|
||||
|
||||
#//!\name QhullLinkedListIterator
|
||||
|
||||
template <typename T>
|
||||
bool QhullLinkedListIterator<T>::
|
||||
findNext(const T &t)
|
||||
{
|
||||
while(i != c->constEnd()){
|
||||
if(*i++ == t){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}//findNext
|
||||
|
||||
template <typename T>
|
||||
bool QhullLinkedListIterator<T>::
|
||||
findPrevious(const T &t)
|
||||
{
|
||||
while(i!=c->constBegin()){
|
||||
if(*(--i)==t){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}//findNext
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
#//!\name Global
|
||||
|
||||
template <typename T>
|
||||
std::ostream &
|
||||
operator<<(std::ostream &os, const orgQhull::QhullLinkedList<T> &qs)
|
||||
{
|
||||
typename orgQhull::QhullLinkedList<T>::const_iterator i;
|
||||
for(i= qs.begin(); i != qs.end(); ++i){
|
||||
os << *i;
|
||||
}
|
||||
return os;
|
||||
}//operator<<
|
||||
|
||||
#endif // QHULLLINKEDLIST_H
|
||||
|
||||
@@ -0,0 +1,199 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2009-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/QhullPoint.cpp#4 $$Change: 2953 $
|
||||
** $DateTime: 2020/05/21 22:05:32 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "libqhullcpp/QhullPoint.h"
|
||||
|
||||
#include "libqhullcpp/QhullError.h"
|
||||
#include "libqhullcpp/Qhull.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
|
||||
#endif
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
#//!\name Constructors
|
||||
|
||||
|
||||
QhullPoint::
|
||||
QhullPoint(const Qhull &q)
|
||||
: point_coordinates(0)
|
||||
, qh_qh(q.qh())
|
||||
, point_dimension(q.hullDimension())
|
||||
{
|
||||
}//QhullPoint
|
||||
|
||||
QhullPoint::
|
||||
QhullPoint(const Qhull &q, coordT *c)
|
||||
: point_coordinates(c)
|
||||
, qh_qh(q.qh())
|
||||
, point_dimension(q.hullDimension())
|
||||
{
|
||||
QHULL_ASSERT(q.hullDimension()>0);
|
||||
}//QhullPoint dim, coordT
|
||||
|
||||
QhullPoint::
|
||||
QhullPoint(const Qhull &q, int pointDimension, coordT *c)
|
||||
: point_coordinates(c)
|
||||
, qh_qh(q.qh())
|
||||
, point_dimension(pointDimension)
|
||||
{
|
||||
}//QhullPoint dim, coordT
|
||||
|
||||
//! QhullPoint of Coordinates with point_dimension==c.count()
|
||||
QhullPoint::
|
||||
QhullPoint(const Qhull &q, Coordinates &c)
|
||||
: point_coordinates(c.data())
|
||||
, qh_qh(q.qh())
|
||||
, point_dimension(c.count())
|
||||
{
|
||||
}//QhullPoint Coordinates
|
||||
|
||||
#//!\name Conversions
|
||||
|
||||
// See qt-qhull.cpp for QList conversion
|
||||
|
||||
#ifndef QHULL_NO_STL
|
||||
std::vector<coordT> QhullPoint::
|
||||
toStdVector() const
|
||||
{
|
||||
QhullPointIterator i(*this);
|
||||
std::vector<coordT> vs;
|
||||
while(i.hasNext()){
|
||||
vs.push_back(i.next());
|
||||
}
|
||||
return vs;
|
||||
}//toStdVector
|
||||
#endif //QHULL_NO_STL
|
||||
|
||||
#//!\name GetSet
|
||||
|
||||
//! QhullPoint is equal if it has the same address and dimension
|
||||
//! If !qh_qh, returns true if dimension and coordinates are equal
|
||||
//! If qh_qh, returns true if the distance between points is less than qh_qh->distanceEpsilon()
|
||||
//!\todo Compares distance with distance-to-hyperplane (distanceEpsilon). Is that correct?
|
||||
bool QhullPoint::
|
||||
operator==(const QhullPoint &other) const
|
||||
{
|
||||
if(point_dimension!=other.point_dimension){
|
||||
return false;
|
||||
}
|
||||
const coordT *c= point_coordinates;
|
||||
const coordT *c2= other.point_coordinates;
|
||||
if(c==c2){
|
||||
return true;
|
||||
}
|
||||
if(!c || !c2){
|
||||
return false;
|
||||
}
|
||||
if(!qh_qh || qh_qh->hull_dim==0){
|
||||
for(int k= point_dimension; k--; ){
|
||||
if(*c++ != *c2++){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
double dist2= 0.0;
|
||||
for(int k= point_dimension; k--; ){
|
||||
double diff= *c++ - *c2++;
|
||||
dist2 += diff*diff;
|
||||
}
|
||||
dist2= sqrt(dist2);
|
||||
return (dist2 < qh_qh->distanceEpsilon());
|
||||
}//operator==
|
||||
|
||||
#//!\name Methods
|
||||
|
||||
//! Return distance between two points.
|
||||
double QhullPoint::
|
||||
distance(const QhullPoint &p) const
|
||||
{
|
||||
const coordT *c= point_coordinates;
|
||||
const coordT *c2= p.point_coordinates;
|
||||
int dim= point_dimension;
|
||||
if(dim!=p.point_dimension){
|
||||
throw QhullError(10075, "QhullPoint error: Expecting dimension %d for distance(). Got %d", dim, p.point_dimension);
|
||||
}
|
||||
if(!c || !c2){
|
||||
throw QhullError(10076, "QhullPoint error: Cannot compute distance() for undefined point");
|
||||
}
|
||||
double dist;
|
||||
|
||||
switch(dim){
|
||||
case 2:
|
||||
dist= (c[0]-c2[0])*(c[0]-c2[0]) + (c[1]-c2[1])*(c[1]-c2[1]);
|
||||
break;
|
||||
case 3:
|
||||
dist= (c[0]-c2[0])*(c[0]-c2[0]) + (c[1]-c2[1])*(c[1]-c2[1]) + (c[2]-c2[2])*(c[2]-c2[2]);
|
||||
break;
|
||||
case 4:
|
||||
dist= (c[0]-c2[0])*(c[0]-c2[0]) + (c[1]-c2[1])*(c[1]-c2[1]) + (c[2]-c2[2])*(c[2]-c2[2]) + (c[3]-c2[3])*(c[3]-c2[3]);
|
||||
break;
|
||||
case 5:
|
||||
dist= (c[0]-c2[0])*(c[0]-c2[0]) + (c[1]-c2[1])*(c[1]-c2[1]) + (c[2]-c2[2])*(c[2]-c2[2]) + (c[3]-c2[3])*(c[3]-c2[3]) + (c[4]-c2[4])*(c[4]-c2[4]);
|
||||
break;
|
||||
case 6:
|
||||
dist= (c[0]-c2[0])*(c[0]-c2[0]) + (c[1]-c2[1])*(c[1]-c2[1]) + (c[2]-c2[2])*(c[2]-c2[2]) + (c[3]-c2[3])*(c[3]-c2[3]) + (c[4]-c2[4])*(c[4]-c2[4]) + (c[5]-c2[5])*(c[5]-c2[5]);
|
||||
break;
|
||||
case 7:
|
||||
dist= (c[0]-c2[0])*(c[0]-c2[0]) + (c[1]-c2[1])*(c[1]-c2[1]) + (c[2]-c2[2])*(c[2]-c2[2]) + (c[3]-c2[3])*(c[3]-c2[3]) + (c[4]-c2[4])*(c[4]-c2[4]) + (c[5]-c2[5])*(c[5]-c2[5]) + (c[6]-c2[6])*(c[6]-c2[6]);
|
||||
break;
|
||||
case 8:
|
||||
dist= (c[0]-c2[0])*(c[0]-c2[0]) + (c[1]-c2[1])*(c[1]-c2[1]) + (c[2]-c2[2])*(c[2]-c2[2]) + (c[3]-c2[3])*(c[3]-c2[3]) + (c[4]-c2[4])*(c[4]-c2[4]) + (c[5]-c2[5])*(c[5]-c2[5]) + (c[6]-c2[6])*(c[6]-c2[6]) + (c[7]-c2[7])*(c[7]-c2[7]);
|
||||
break;
|
||||
default:
|
||||
dist= 0.0;
|
||||
for(int k=dim; k--; ){
|
||||
dist += (*c - *c2) * (*c - *c2);
|
||||
++c;
|
||||
++c2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return sqrt(dist);
|
||||
}//distance
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
#//!\name Global functions
|
||||
|
||||
using std::ostream;
|
||||
using orgQhull::QhullPoint;
|
||||
|
||||
//! Same as qh_printpointid [io.c]
|
||||
ostream &
|
||||
operator<<(ostream &os, const QhullPoint::PrintPoint &pr)
|
||||
{
|
||||
QhullPoint p= *pr.point;
|
||||
countT i= p.id();
|
||||
if(pr.point_message){
|
||||
if(*pr.point_message){
|
||||
os << pr.point_message << " ";
|
||||
}
|
||||
if(pr.with_identifier && (i!=qh_IDunknown) && (i!=qh_IDnone)){
|
||||
os << "p" << i << ": ";
|
||||
}
|
||||
}
|
||||
const realT *c= p.coordinates();
|
||||
for(int k=p.dimension(); k--; ){
|
||||
realT r= *c++;
|
||||
os << " " << r; // QH11010 FIX: %8.4g qh_REAL_1
|
||||
}
|
||||
os << std::endl;
|
||||
return os;
|
||||
}//printPoint
|
||||
|
||||
ostream &
|
||||
operator<<(ostream &os, const QhullPoint &p)
|
||||
{
|
||||
os << p.print("");
|
||||
return os;
|
||||
}//operator<<
|
||||
@@ -0,0 +1,138 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2009-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/QhullPoint.h#5 $$Change: 3008 $
|
||||
** $DateTime: 2020/07/30 13:54:27 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QHPOINT_H
|
||||
#define QHPOINT_H
|
||||
|
||||
#include "libqhull_r/qhull_ra.h"
|
||||
#include "libqhullcpp/QhullError.h"
|
||||
#include "libqhullcpp/QhullIterator.h"
|
||||
#include "libqhullcpp/QhullQh.h"
|
||||
#include "libqhullcpp/Coordinates.h"
|
||||
|
||||
#include <ostream>
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
#//!\name Defined here
|
||||
class QhullPoint; //!< QhullPoint is a pointer to coordinates and dimension
|
||||
class QhullPointIterator; //!< Java-style iterator for QhullPoint coordinates
|
||||
|
||||
#//!\name Used here
|
||||
class Qhull;
|
||||
|
||||
//! A QhullPoint is a dimension and an array of coordinates.
|
||||
//! With Qhull/QhullQh, a QhullPoint has an identifier. Point equality is relative to qh.distanceEpsilon
|
||||
class QhullPoint {
|
||||
|
||||
#//!\name Iterators
|
||||
public:
|
||||
typedef coordT * base_type; // for QhullPointSet
|
||||
typedef const coordT * iterator;
|
||||
typedef const coordT * const_iterator;
|
||||
typedef QhullPoint::iterator Iterator;
|
||||
typedef QhullPoint::const_iterator ConstIterator;
|
||||
|
||||
#//!\name Fields
|
||||
protected: // For QhullPoints::iterator, QhullPoints::const_iterator
|
||||
coordT * point_coordinates; //!< Pointer to first coordinate, 0 if undefined
|
||||
QhullQh * qh_qh; //!< qhT for this instance of Qhull. 0 if undefined.
|
||||
//!< operator==() returns true if points within sqrt(qh_qh->distanceEpsilon())
|
||||
//!< If !qh_qh, id() is -3, and operator==() requires equal coordinates
|
||||
int point_dimension; //!< Default dimension is qh_qh->hull_dim
|
||||
public:
|
||||
|
||||
#//!\name Constructors
|
||||
//! QhullPoint, PointCoordinates, and QhullPoints have similar constructors
|
||||
//! If Qhull/QhullQh is not initialized, then QhullPoint.dimension() is zero unless explicitly set
|
||||
//! Cannot define QhullPoints(int pointDimension) since it is ambiguous with QhullPoints(QhullQh *qqh)
|
||||
QhullPoint() : point_coordinates(0), qh_qh(0), point_dimension(0) {}
|
||||
QhullPoint(int pointDimension, coordT *c) : point_coordinates(c), qh_qh(0), point_dimension(pointDimension) { QHULL_ASSERT(pointDimension>0); }
|
||||
explicit QhullPoint(const Qhull &q);
|
||||
QhullPoint(const Qhull &q, coordT *c);
|
||||
QhullPoint(const Qhull &q, Coordinates &c);
|
||||
QhullPoint(const Qhull &q, int pointDimension, coordT *c);
|
||||
explicit QhullPoint(QhullQh *qqh) : point_coordinates(0), qh_qh(qqh), point_dimension(qqh->hull_dim) {}
|
||||
QhullPoint(QhullQh *qqh, coordT *c) : point_coordinates(c), qh_qh(qqh), point_dimension(qqh->hull_dim) { QHULL_ASSERT(qqh->hull_dim>0); }
|
||||
QhullPoint(QhullQh *qqh, Coordinates &c) : point_coordinates(c.data()), qh_qh(qqh), point_dimension(c.count()) {}
|
||||
QhullPoint(QhullQh *qqh, int pointDimension, coordT *c) : point_coordinates(c), qh_qh(qqh), point_dimension(pointDimension) {}
|
||||
//! Creates an alias. Does not make a deep copy of the point. Needed for return by value and parameter passing.
|
||||
QhullPoint(const QhullPoint &other) : point_coordinates(other.point_coordinates), qh_qh(other.qh_qh), point_dimension(other.point_dimension) {}
|
||||
//! Creates an alias. Does not make a deep copy of the point. Needed for vector<QhullPoint>
|
||||
QhullPoint & operator=(const QhullPoint &other) { point_coordinates= other.point_coordinates; qh_qh= other.qh_qh; point_dimension= other.point_dimension; return *this; }
|
||||
~QhullPoint() {}
|
||||
|
||||
|
||||
#//!\name Conversions
|
||||
|
||||
#ifndef QHULL_NO_STL
|
||||
std::vector<coordT> toStdVector() const;
|
||||
#endif //QHULL_NO_STL
|
||||
#ifdef QHULL_USES_QT
|
||||
QList<coordT> toQList() const;
|
||||
#endif //QHULL_USES_QT
|
||||
|
||||
#//!\name GetSet
|
||||
public:
|
||||
const coordT * coordinates() const { return point_coordinates; } //!< 0 if undefined
|
||||
coordT * coordinates() { return point_coordinates; } //!< 0 if undefined
|
||||
void defineAs(coordT *c) { QHULL_ASSERT(point_dimension>0); point_coordinates= c; }
|
||||
void defineAs(int pointDimension, coordT *c) { QHULL_ASSERT(pointDimension>=0); point_coordinates= c; point_dimension= pointDimension; }
|
||||
void defineAs(QhullPoint &other) { point_coordinates= other.point_coordinates; qh_qh= other.qh_qh; point_dimension= other.point_dimension; }
|
||||
int dimension() const { return point_dimension; }
|
||||
coordT * getBaseT() const { return point_coordinates; } // for QhullPointSet
|
||||
countT id() const { return qh_pointid(qh_qh, point_coordinates); } // NOerrors
|
||||
bool isValid() const { return (point_coordinates!=0 && point_dimension>0); }
|
||||
bool operator==(const QhullPoint &other) const;
|
||||
bool operator!=(const QhullPoint &other) const { return ! operator==(other); }
|
||||
const coordT & operator[](int idx) const { QHULL_ASSERT(point_coordinates!=0 && idx>=0 && idx<point_dimension); return *(point_coordinates+idx); } //!< 0 to hull_dim-1
|
||||
coordT & operator[](int idx) { QHULL_ASSERT(point_coordinates!=0 && idx>=0 && idx<point_dimension); return *(point_coordinates+idx); } //!< 0 to hull_dim-1
|
||||
QhullQh * qh() { return qh_qh; }
|
||||
void setCoordinates(coordT *c) { point_coordinates= c; }
|
||||
void setDimension(int pointDimension) { point_dimension= pointDimension; }
|
||||
|
||||
#//!\name foreach
|
||||
iterator begin() { return point_coordinates; }
|
||||
const_iterator begin() const { return point_coordinates; }
|
||||
const_iterator constBegin() const { return point_coordinates; }
|
||||
const_iterator constEnd() const { return (point_coordinates ? point_coordinates+point_dimension : 0); }
|
||||
int count() { return (point_coordinates ? point_dimension : 0); }
|
||||
iterator end() { return (point_coordinates ? point_coordinates+point_dimension : 0); }
|
||||
const_iterator end() const { return (point_coordinates ? point_coordinates+point_dimension : 0); }
|
||||
size_t size() { return static_cast<size_t>(point_coordinates ? point_dimension : 0); }
|
||||
|
||||
#//!\name Methods
|
||||
void advancePoint(countT idx) { if(point_coordinates) { point_coordinates += idx*point_dimension; } }
|
||||
double distance(const QhullPoint &p) const;
|
||||
|
||||
#//!\name IO
|
||||
|
||||
struct PrintPoint{
|
||||
const QhullPoint *point;
|
||||
const char * point_message;
|
||||
bool with_identifier;
|
||||
PrintPoint(const char *message, bool withIdentifier, const QhullPoint &p) : point(&p), point_message(message), with_identifier(withIdentifier) {}
|
||||
};//PrintPoint
|
||||
PrintPoint print(const char *message) const { return PrintPoint(message, false, *this); }
|
||||
PrintPoint printWithIdentifier(const char *message) const { return PrintPoint(message, true, *this); }
|
||||
|
||||
};//QhullPoint
|
||||
|
||||
//! QhullPointIterator is a Java-style iterator for QhullPoint coordinates
|
||||
//! QhullPointIterator may be used on temporary results. It copies the coordinates pointer in QhullPoint
|
||||
QHULL_DECLARE_SEQUENTIAL_ITERATOR(QhullPoint, coordT)
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
#//!\name Global
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullPoint::PrintPoint &pr);
|
||||
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullPoint &p);
|
||||
|
||||
#endif // QHPOINT_H
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2009-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/QhullPointSet.cpp#2 $$Change: 2953 $
|
||||
** $DateTime: 2020/05/21 22:05:32 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "libqhullcpp/QhullPointSet.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
|
||||
#endif
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
// Implemented via QhullSet.h
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
#//!\name Global functions
|
||||
|
||||
using std::endl;
|
||||
using std::ostream;
|
||||
using orgQhull::QhullPoint;
|
||||
using orgQhull::QhullPointSet;
|
||||
using orgQhull::QhullPointSetIterator;
|
||||
|
||||
ostream &
|
||||
operator<<(ostream &os, const QhullPointSet::PrintIdentifiers &pr)
|
||||
{
|
||||
os << pr.print_message;
|
||||
const QhullPointSet s= *pr.point_set;
|
||||
QhullPointSetIterator i(s);
|
||||
while(i.hasNext()){
|
||||
if(i.hasPrevious()){
|
||||
os << " ";
|
||||
}
|
||||
const QhullPoint point= i.next();
|
||||
countT id= point.id();
|
||||
os << "p" << id;
|
||||
|
||||
}
|
||||
os << endl;
|
||||
return os;
|
||||
}//PrintIdentifiers
|
||||
|
||||
ostream &
|
||||
operator<<(ostream &os, const QhullPointSet::PrintPointSet &pr)
|
||||
{
|
||||
os << pr.print_message;
|
||||
const QhullPointSet s= *pr.point_set;
|
||||
for(QhullPointSet::const_iterator i=s.begin(); i != s.end(); ++i){
|
||||
const QhullPoint point= *i;
|
||||
os << point;
|
||||
}
|
||||
return os;
|
||||
}//printPointSet
|
||||
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2009-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/QhullPointSet.h#3 $$Change: 3001 $
|
||||
** $DateTime: 2020/07/24 20:43:28 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QHULLPOINTSET_H
|
||||
#define QHULLPOINTSET_H
|
||||
|
||||
#include "libqhull_r/qhull_ra.h"
|
||||
#include "libqhullcpp/QhullSet.h"
|
||||
#include "libqhullcpp/QhullPoint.h"
|
||||
|
||||
#include <ostream>
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
#//!\name Used here
|
||||
class Qhull;
|
||||
class QhullPoint;
|
||||
|
||||
#//!\name Defined here
|
||||
//! QhullPointSet -- a set of coordinate pointers with input dimension
|
||||
//! Includes const_iterator and iterator
|
||||
class QhullPointSet;
|
||||
|
||||
//! QhullPointSetIterator is a Java-style iterator for QhullPoint in a QhullPointSet
|
||||
//! QhullPointSetIterator may be used on temporary results. It copies the pointers in QhullPointSet
|
||||
typedef QhullSetIterator<QhullPoint> QhullPointSetIterator;
|
||||
|
||||
class QhullPointSet : public QhullSet<QhullPoint> {
|
||||
|
||||
private:
|
||||
#//!\name Fields
|
||||
// no fields
|
||||
public:
|
||||
|
||||
#//!\name Construct
|
||||
QhullPointSet(const Qhull &q, setT *s) : QhullSet<QhullPoint>(q, s) {}
|
||||
//Conversion from setT* is not type-safe. Implicit conversion for void* to T
|
||||
QhullPointSet(QhullQh *qqh, setT *s) : QhullSet<QhullPoint>(qqh, s) {}
|
||||
//Copy constructor copies pointer but not contents. Needed for return by value and parameter passing.
|
||||
QhullPointSet(const QhullPointSet &other) : QhullSet<QhullPoint>(other) {}
|
||||
//!Assignment copies pointers but not contents.
|
||||
QhullPointSet & operator=(const QhullPointSet &other) { QhullSet<QhullPoint>::operator=(other); return *this; }
|
||||
~QhullPointSet() {}
|
||||
|
||||
//!Default constructor disabled.
|
||||
private:
|
||||
QhullPointSet();
|
||||
public:
|
||||
|
||||
#//!\name IO
|
||||
struct PrintIdentifiers{
|
||||
const QhullPointSet *point_set;
|
||||
const char * print_message; //!< non-null message
|
||||
PrintIdentifiers(const char *message, const QhullPointSet *s) : point_set(s), print_message(message) {}
|
||||
};//PrintIdentifiers
|
||||
PrintIdentifiers printIdentifiers(const char *message) const { return PrintIdentifiers(message, this); }
|
||||
|
||||
struct PrintPointSet{
|
||||
const QhullPointSet *point_set;
|
||||
const char * print_message; //!< non-null message
|
||||
PrintPointSet(const char *message, const QhullPointSet &s) : point_set(&s), print_message(message) {}
|
||||
};//PrintPointSet
|
||||
PrintPointSet print(const char *message) const { return PrintPointSet(message, *this); }
|
||||
|
||||
};//QhullPointSet
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
#//!\name Global
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullPointSet::PrintIdentifiers &pr);
|
||||
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullPointSet::PrintPointSet &pr);
|
||||
|
||||
#endif // QHULLPOINTSET_H
|
||||
@@ -0,0 +1,320 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2009-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/QhullPoints.cpp#5 $$Change: 3001 $
|
||||
** $DateTime: 2020/07/24 20:43:28 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "libqhullcpp/QhullPoints.h"
|
||||
|
||||
#include "libqhullcpp/Qhull.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#ifndef QHULL_NO_STL
|
||||
#include <vector>
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
|
||||
#endif
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
#//!\name Constructors
|
||||
|
||||
QhullPoints::
|
||||
QhullPoints(const Qhull &q)
|
||||
: point_first(0)
|
||||
, point_end(0)
|
||||
, qh_qh(q.qh())
|
||||
, point_dimension(q.hullDimension())
|
||||
{
|
||||
}//QhullPoints Qhull
|
||||
|
||||
QhullPoints::
|
||||
QhullPoints(const Qhull &q, countT coordinateCount2, coordT *c)
|
||||
: point_first(c)
|
||||
, point_end(c+coordinateCount2)
|
||||
, qh_qh(q.qh())
|
||||
, point_dimension(q.hullDimension())
|
||||
{
|
||||
QHULL_ASSERT(q.hullDimension());
|
||||
QHULL_ASSERT(coordinateCount2>=0);
|
||||
}//QhullPoints Qhull dim
|
||||
|
||||
QhullPoints::
|
||||
QhullPoints(const Qhull &q, int pointDimension, countT coordinateCount2, coordT *c)
|
||||
: point_first(c)
|
||||
, point_end(c+coordinateCount2)
|
||||
, qh_qh(q.qh())
|
||||
, point_dimension(pointDimension)
|
||||
{
|
||||
QHULL_ASSERT(pointDimension>=0);
|
||||
QHULL_ASSERT(coordinateCount2>=0);
|
||||
}//QhullPoints Qhull dim coordT
|
||||
|
||||
QhullPoints::
|
||||
QhullPoints(QhullQh *qqh, int pointDimension, countT coordinateCount2, coordT *c)
|
||||
: point_first(c)
|
||||
, point_end(c+coordinateCount2)
|
||||
, qh_qh(qqh)
|
||||
, point_dimension(pointDimension)
|
||||
{
|
||||
QHULL_ASSERT(pointDimension>=0);
|
||||
QHULL_ASSERT(coordinateCount2>=0);
|
||||
}//QhullPoints QhullQh dim coordT
|
||||
|
||||
#//!\name Conversions
|
||||
// See qt-qhull.cpp for QList conversion
|
||||
|
||||
#ifndef QHULL_NO_STL
|
||||
std::vector<QhullPoint> QhullPoints::
|
||||
toStdVector() const
|
||||
{
|
||||
QhullPointsIterator i(*this);
|
||||
std::vector<QhullPoint> vs;
|
||||
while(i.hasNext()){
|
||||
vs.push_back(i.next());
|
||||
}
|
||||
return vs;
|
||||
}//toStdVector
|
||||
#endif //QHULL_NO_STL
|
||||
|
||||
#//!\name GetSet
|
||||
|
||||
countT QhullPoints::
|
||||
extraCoordinatesCount() const
|
||||
{
|
||||
if(point_dimension>0){
|
||||
return (point_end-point_first) % point_dimension; /* must be less than point_dimension */
|
||||
}
|
||||
return 0;
|
||||
}//extraCoordinatesCount
|
||||
|
||||
//! QhullPoints is equal if the same address, or if the coordinates are identical
|
||||
//! Use QhullPoint.operator==() for DISTround equality
|
||||
bool QhullPoints::
|
||||
operator==(const QhullPoints &other) const
|
||||
{
|
||||
if((point_end-point_first) != (other.point_end-other.point_first)){
|
||||
return false;
|
||||
}
|
||||
if(point_dimension!=other.point_dimension){
|
||||
return false;
|
||||
}
|
||||
if(point_first==other.point_first){
|
||||
return true;
|
||||
}
|
||||
if(!qh_qh || qh_qh->hull_dim==0){
|
||||
const coordT *c= point_first;
|
||||
const coordT *c2= other.point_first;
|
||||
while(c<point_end){
|
||||
if(*c++!=*c2++){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
const_iterator i= begin();
|
||||
const_iterator i2= other.begin();
|
||||
while(i<end()){
|
||||
if(*i++!=*i2++){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}//operator==
|
||||
|
||||
//! Reset QhullPoints to QhullQh and its hullDimension()
|
||||
//! Does not free up old qh_qh
|
||||
void QhullPoints::
|
||||
resetQhullQh(QhullQh *qqh)
|
||||
{
|
||||
qh_qh= qqh;
|
||||
point_dimension= (qqh ? qqh->hull_dim : 0);
|
||||
point_first= 0;
|
||||
point_end= 0;
|
||||
}//resetQhullQh
|
||||
|
||||
QhullPoint QhullPoints::
|
||||
value(countT idx) const
|
||||
{
|
||||
QhullPoint p(qh_qh);
|
||||
if(idx>=0 && idx<count()){
|
||||
p.defineAs(point_dimension, point_first+idx*point_dimension);
|
||||
}
|
||||
return p;
|
||||
}//value
|
||||
|
||||
QhullPoint QhullPoints::
|
||||
value(countT idx, QhullPoint &defaultValue) const
|
||||
{
|
||||
QhullPoint p(qh_qh);
|
||||
if(idx>=0 && idx<count()){
|
||||
p.defineAs(point_dimension, point_first+idx*point_dimension);
|
||||
}else{
|
||||
p.defineAs(defaultValue);
|
||||
}
|
||||
return p;
|
||||
}//value
|
||||
|
||||
#//!\name Methods
|
||||
|
||||
bool QhullPoints::
|
||||
contains(const QhullPoint &t) const
|
||||
{
|
||||
const_iterator i= begin();
|
||||
while(i != end()){
|
||||
if(*i==t){
|
||||
return true;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return false;
|
||||
}//contains
|
||||
|
||||
countT QhullPoints::
|
||||
count(const QhullPoint &t) const
|
||||
{
|
||||
countT n= 0;
|
||||
const_iterator i= begin();
|
||||
while(i != end()){
|
||||
if(*i==t){
|
||||
++n;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return n;
|
||||
}//count
|
||||
|
||||
countT QhullPoints::
|
||||
indexOf(const coordT *pointCoordinates) const
|
||||
{
|
||||
if(!includesCoordinates(pointCoordinates) || point_dimension==0){
|
||||
return -1;
|
||||
}
|
||||
size_t offset= pointCoordinates-point_first;
|
||||
countT idx= static_cast<countT>(offset/point_dimension);
|
||||
countT extra= offset % point_dimension; /* must be less than point_dimension */
|
||||
if(extra!=0){
|
||||
throw QhullError(10066, "Qhull error: coordinates %x are not at point boundary (extra %d at index %d)", extra, idx, 0.0, pointCoordinates);
|
||||
}
|
||||
return idx;
|
||||
}//indexOf coordT
|
||||
|
||||
countT QhullPoints::
|
||||
indexOf(const coordT *pointCoordinates, int noThrow) const
|
||||
{
|
||||
size_t extra= 0;
|
||||
if(noThrow){
|
||||
if(!includesCoordinates(pointCoordinates) || point_dimension==0){
|
||||
return -1;
|
||||
}
|
||||
extra= (pointCoordinates-point_first) % point_dimension;
|
||||
}
|
||||
return indexOf(pointCoordinates-extra);
|
||||
}//indexOf coordT noThrow
|
||||
|
||||
countT QhullPoints::
|
||||
indexOf(const QhullPoint &t) const
|
||||
{
|
||||
countT j=0;
|
||||
const_iterator i= begin();
|
||||
while(i!=end()){
|
||||
if(*i==t){
|
||||
return j;
|
||||
}
|
||||
++i;
|
||||
++j;
|
||||
}
|
||||
return -1;
|
||||
}//indexOf
|
||||
|
||||
countT QhullPoints::
|
||||
lastIndexOf(const QhullPoint &t) const
|
||||
{
|
||||
countT j= count();
|
||||
const_iterator i= end();
|
||||
while(i != begin()){
|
||||
--i;
|
||||
--j;
|
||||
if(*i==t){
|
||||
return j;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}//lastIndexOf
|
||||
|
||||
QhullPoints QhullPoints::
|
||||
mid(countT idx, countT length) const
|
||||
{
|
||||
countT n= count();
|
||||
if(idx<0 || idx>=n){
|
||||
n= 0;
|
||||
}else if(length<0 || idx+length>=n){
|
||||
n -= idx;
|
||||
}else{
|
||||
n -= idx+length;
|
||||
}
|
||||
return QhullPoints(qh_qh, point_dimension, n*point_dimension, point_first+idx*point_dimension);
|
||||
}//mid
|
||||
|
||||
#//!\name QhullPointsIterator
|
||||
|
||||
bool QhullPointsIterator::
|
||||
findNext(const QhullPoint &p)
|
||||
{
|
||||
while(i!=ps.constEnd()){
|
||||
if(*i++ == p){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}//findNext
|
||||
|
||||
bool QhullPointsIterator::
|
||||
findPrevious(const QhullPoint &p)
|
||||
{
|
||||
while(i!=ps.constBegin()){
|
||||
if(*--i == p){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}//findPrevious
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
#//!\name Global functions
|
||||
|
||||
using std::ostream;
|
||||
using orgQhull::QhullPoint;
|
||||
using orgQhull::QhullPoints;
|
||||
using orgQhull::QhullPointsIterator;
|
||||
|
||||
ostream &
|
||||
operator<<(ostream &os, const QhullPoints &p)
|
||||
{
|
||||
QhullPointsIterator i(p);
|
||||
while(i.hasNext()){
|
||||
os << i.next();
|
||||
}
|
||||
return os;
|
||||
}//operator<<QhullPoints
|
||||
|
||||
ostream &
|
||||
operator<<(ostream &os, const QhullPoints::PrintPoints &pr)
|
||||
{
|
||||
os << pr.point_message;
|
||||
QhullPoints ps= *pr.points;
|
||||
for(QhullPoints::iterator i=ps.begin(); i!=ps.end(); ++i){
|
||||
QhullPoint p= *i;
|
||||
if(pr.with_identifier){
|
||||
os << p.printWithIdentifier("");
|
||||
}else{
|
||||
os << p.print("");
|
||||
}
|
||||
}
|
||||
return os;
|
||||
}//<<PrintPoints
|
||||
@@ -0,0 +1,268 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2009-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/QhullPoints.h#6 $$Change: 3001 $
|
||||
** $DateTime: 2020/07/24 20:43:28 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QHULLPOINTS_H
|
||||
#define QHULLPOINTS_H
|
||||
|
||||
#include "libqhull_r/qhull_ra.h"
|
||||
#include "libqhullcpp/QhullPoint.h"
|
||||
|
||||
#include <cstddef> // ptrdiff_t, size_t
|
||||
#include <ostream>
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
#//!\name Defined here
|
||||
class QhullPoints; //!< One or more points Coordinate pointers with dimension and iterators
|
||||
class QhullPointsIterator; //!< Java-style iterator
|
||||
|
||||
//! QhullPoints are an array of QhullPoint as pointers into an array of coordinates.
|
||||
//! For Qhull/QhullQh, QhullPoints must use hull_dim. Can change QhullPoint to input_dim if needed for Delaunay input site
|
||||
class QhullPoints {
|
||||
|
||||
private:
|
||||
#//!\name Fields
|
||||
coordT * point_first; //!< First coordinate of an array of points of point_dimension
|
||||
coordT * point_end; //!< End of point coordinates (end>=first). Trailing coordinates ignored
|
||||
QhullQh * qh_qh; //!< Maybe initialized NULL to allow ownership by RboxPoints
|
||||
//!< qh_qh used for QhullPoint() and qh_qh->hull_dim in constructor
|
||||
int point_dimension; //!< Dimension, >=0
|
||||
|
||||
public:
|
||||
#//!\name Subtypes
|
||||
class const_iterator;
|
||||
class iterator;
|
||||
typedef QhullPoints::const_iterator ConstIterator;
|
||||
typedef QhullPoints::iterator Iterator;
|
||||
|
||||
#//!\name Construct
|
||||
//! QhullPoint, PointCoordinates, and QhullPoints have similar constructors
|
||||
//! If Qhull/QhullQh is not initialized, then QhullPoints.dimension() is zero unless explicitly set
|
||||
//! Cannot define QhullPoints(int pointDimension) since it is ambiguous with QhullPoints(QhullQh *qqh)
|
||||
QhullPoints() : point_first(0), point_end(0), qh_qh(0), point_dimension(0) { }
|
||||
QhullPoints(int pointDimension, countT coordinateCount2, coordT *c) : point_first(c), point_end(c+coordinateCount2), qh_qh(0), point_dimension(pointDimension) { QHULL_ASSERT(pointDimension>=0); }
|
||||
explicit QhullPoints(const Qhull &q);
|
||||
QhullPoints(const Qhull &q, countT coordinateCount2, coordT *c);
|
||||
QhullPoints(const Qhull &q, int pointDimension, countT coordinateCount2, coordT *c);
|
||||
explicit QhullPoints(QhullQh *qqh) : point_first(0), point_end(0), qh_qh(qqh), point_dimension(qqh ? qqh->hull_dim : 0) { }
|
||||
QhullPoints(QhullQh *qqh, countT coordinateCount2, coordT *c) : point_first(c), point_end(c+coordinateCount2), qh_qh(qqh), point_dimension(qqh ? qqh->hull_dim : 0) { QHULL_ASSERT(qqh && qqh->hull_dim>0); }
|
||||
QhullPoints(QhullQh *qqh, int pointDimension, countT coordinateCount2, coordT *c);
|
||||
//! Copy constructor copies pointers but not contents. Needed for return by value and parameter passing.
|
||||
QhullPoints(const QhullPoints &other) : point_first(other.point_first), point_end(other.point_end), qh_qh(other.qh_qh), point_dimension(other.point_dimension) {}
|
||||
QhullPoints & operator=(const QhullPoints &other) { point_first= other.point_first; point_end= other.point_end; qh_qh= other.qh_qh; point_dimension= other.point_dimension; return *this; }
|
||||
~QhullPoints() {}
|
||||
|
||||
public:
|
||||
|
||||
#//!\name Conversion
|
||||
|
||||
#ifndef QHULL_NO_STL
|
||||
std::vector<QhullPoint> toStdVector() const;
|
||||
#endif //QHULL_NO_STL
|
||||
#ifdef QHULL_USES_QT
|
||||
QList<QhullPoint> toQList() const;
|
||||
#endif //QHULL_USES_QT
|
||||
|
||||
#//!\name GetSet
|
||||
// Constructs QhullPoint. Cannot return reference.
|
||||
const QhullPoint at(countT idx) const { /* point_first==0 caught by point_end assert */ coordT *p= point_first+idx*point_dimension; QHULL_ASSERT(p<point_end); return QhullPoint(qh_qh, point_dimension, p); }
|
||||
// Constructs QhullPoint. Cannot return reference.
|
||||
const QhullPoint back() const { return last(); }
|
||||
QhullPoint back() { return last(); }
|
||||
ConstIterator begin() const { return ConstIterator(*this); }
|
||||
Iterator begin() { return Iterator(*this); }
|
||||
ConstIterator constBegin() const { return ConstIterator(*this); }
|
||||
const coordT * constData() const { return point_first; }
|
||||
ConstIterator constEnd() const { return ConstIterator(qh_qh, point_dimension, point_end); }
|
||||
coordT * coordinates() const { return point_first; }
|
||||
countT coordinateCount() const { return static_cast<countT>(point_end-point_first); } // WARN64
|
||||
countT count() const { return static_cast<countT>(size()); } // WARN64
|
||||
const coordT * data() const { return point_first; }
|
||||
coordT * data() { return point_first; }
|
||||
void defineAs(int pointDimension, countT coordinatesCount, coordT *c) { QHULL_ASSERT(pointDimension>=0 && coordinatesCount>=0 && c!=0); point_first= c; point_end= c+coordinatesCount; point_dimension= pointDimension; }
|
||||
void defineAs(countT coordinatesCount, coordT *c) { QHULL_ASSERT((point_dimension>0 && coordinatesCount>=0 && c!=0) || (c==0 && coordinatesCount==0)); point_first= c; point_end= c+coordinatesCount; }
|
||||
void defineAs(const QhullPoints &other) { point_first= other.point_first; point_end= other.point_end; qh_qh= other.qh_qh; point_dimension= other.point_dimension; }
|
||||
int dimension() const { return point_dimension; }
|
||||
ConstIterator end() const { return ConstIterator(qh_qh, point_dimension, point_end); }
|
||||
Iterator end() { return Iterator(qh_qh, point_dimension, point_end); }
|
||||
coordT * extraCoordinates() const { return (extraCoordinatesCount() ? (point_end-extraCoordinatesCount()) : 0); }
|
||||
countT extraCoordinatesCount() const; // WARN64
|
||||
// Constructs QhullPoint. Cannot return reference.
|
||||
const QhullPoint first() const { return QhullPoint(qh_qh, point_dimension, point_first); }
|
||||
QhullPoint first() { return QhullPoint(qh_qh, point_dimension, point_first); }
|
||||
// Constructs QhullPoint. Cannot return reference.
|
||||
const QhullPoint front() const { return first(); }
|
||||
QhullPoint front() { return first(); }
|
||||
bool includesCoordinates(const coordT *c) const { return (c>=point_first && c<point_end); }
|
||||
bool isEmpty() const { return (point_end==point_first || point_dimension==0); }
|
||||
// Constructs QhullPoint. Cannot return reference.
|
||||
const QhullPoint last() const { QHULL_ASSERT(point_first!=0); return QhullPoint(qh_qh, point_dimension, point_end - point_dimension); }
|
||||
QhullPoint last() { QHULL_ASSERT(point_first!=0); return QhullPoint(qh_qh, point_dimension, point_end - point_dimension); }
|
||||
bool operator==(const QhullPoints &other) const;
|
||||
bool operator!=(const QhullPoints &other) const { return (! operator==(other)); }
|
||||
QhullPoint operator[](countT idx) const { return at(idx); }
|
||||
QhullQh * qh() const { return qh_qh; }
|
||||
void resetQhullQh(QhullQh *qqh);
|
||||
void setDimension(int d) { point_dimension= d; }
|
||||
size_t size() const { return (point_dimension ? (point_end-point_first)/point_dimension : 0); }
|
||||
QhullPoint value(countT idx) const;
|
||||
QhullPoint value(countT idx, QhullPoint &defaultValue) const;
|
||||
|
||||
#//!\name Methods
|
||||
bool contains(const QhullPoint &t) const;
|
||||
countT count(const QhullPoint &t) const;
|
||||
countT indexOf(const coordT *pointCoordinates) const;
|
||||
countT indexOf(const coordT *pointCoordinates, int noThrow) const;
|
||||
countT indexOf(const QhullPoint &t) const;
|
||||
countT lastIndexOf(const QhullPoint &t) const;
|
||||
//! Returns a subset of the points, not a copy
|
||||
QhullPoints mid(countT idx, countT length= -1) const;
|
||||
|
||||
#//!\name QhullPoints::iterator
|
||||
// Modeled on qlist.h w/o QT_STRICT_ITERATORS
|
||||
// before const_iterator for conversion with comparison operators
|
||||
// See: QhullSet.h
|
||||
class iterator : public QhullPoint {
|
||||
|
||||
public:
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
typedef QhullPoint value_type;
|
||||
typedef value_type * pointer;
|
||||
typedef value_type & reference;
|
||||
typedef ptrdiff_t difference_type;
|
||||
|
||||
explicit iterator(const QhullPoints &ps) : QhullPoint(ps.qh(), ps.dimension(), ps.coordinates()) {}
|
||||
iterator(const int pointDimension, coordT *c): QhullPoint(pointDimension, c) {}
|
||||
iterator(const Qhull &q, coordT *c): QhullPoint(q, c) {}
|
||||
iterator(const Qhull &q, int pointDimension, coordT *c): QhullPoint(q, pointDimension, c) {}
|
||||
iterator(QhullQh *qqh, coordT *c): QhullPoint(qqh, c) {}
|
||||
iterator(QhullQh *qqh, int pointDimension, coordT *c): QhullPoint(qqh, pointDimension, c) {}
|
||||
iterator(const iterator &other): QhullPoint(*other) {}
|
||||
iterator & operator=(const iterator &other) { defineAs( const_cast<iterator &>(other)); return *this; }
|
||||
|
||||
// Need 'const QhullPoint' to maintain const
|
||||
const QhullPoint & operator*() const { return *this; }
|
||||
QhullPoint & operator*() { return *this; }
|
||||
const QhullPoint * operator->() const { return this; }
|
||||
QhullPoint * operator->() { return this; }
|
||||
// value instead of reference since advancePoint() modifies self
|
||||
QhullPoint operator[](countT idx) const { QhullPoint result= *this; result.advancePoint(idx); return result; }
|
||||
bool operator==(const iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return (point_coordinates==o.point_coordinates && point_dimension==o.point_dimension); }
|
||||
bool operator!=(const iterator &o) const { return (! operator==(o)); }
|
||||
bool operator<(const iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return point_coordinates < o.point_coordinates; }
|
||||
bool operator<=(const iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return point_coordinates <= o.point_coordinates; }
|
||||
bool operator>(const iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return point_coordinates > o.point_coordinates; }
|
||||
bool operator>=(const iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return point_coordinates >= o.point_coordinates; }
|
||||
// reinterpret_cast to break circular dependency
|
||||
bool operator==(const QhullPoints::const_iterator &o) const { QHULL_ASSERT(qh_qh==reinterpret_cast<const iterator &>(o).qh_qh); return (point_coordinates==reinterpret_cast<const iterator &>(o).point_coordinates && point_dimension==reinterpret_cast<const iterator &>(o).point_dimension); }
|
||||
bool operator!=(const QhullPoints::const_iterator &o) const { return (! operator==(reinterpret_cast<const iterator &>(o))); }
|
||||
bool operator<(const QhullPoints::const_iterator &o) const { QHULL_ASSERT(qh_qh==reinterpret_cast<const iterator &>(o).qh_qh); return point_coordinates < reinterpret_cast<const iterator &>(o).point_coordinates; }
|
||||
bool operator<=(const QhullPoints::const_iterator &o) const { QHULL_ASSERT(qh_qh==reinterpret_cast<const iterator &>(o).qh_qh); return point_coordinates <= reinterpret_cast<const iterator &>(o).point_coordinates; }
|
||||
bool operator>(const QhullPoints::const_iterator &o) const { QHULL_ASSERT(qh_qh==reinterpret_cast<const iterator &>(o).qh_qh); return point_coordinates > reinterpret_cast<const iterator &>(o).point_coordinates; }
|
||||
bool operator>=(const QhullPoints::const_iterator &o) const { QHULL_ASSERT(qh_qh==reinterpret_cast<const iterator &>(o).qh_qh); return point_coordinates >= reinterpret_cast<const iterator &>(o).point_coordinates; }
|
||||
iterator & operator++() { advancePoint(1); return *this; }
|
||||
iterator operator++(int) { iterator n= *this; operator++(); return iterator(n); }
|
||||
iterator & operator--() { advancePoint(-1); return *this; }
|
||||
iterator operator--(int) { iterator n= *this; operator--(); return iterator(n); }
|
||||
iterator & operator+=(countT idx) { advancePoint(idx); return *this; }
|
||||
iterator & operator-=(countT idx) { advancePoint(-idx); return *this; }
|
||||
iterator operator+(countT idx) const { iterator n= *this; n.advancePoint(idx); return n; }
|
||||
iterator operator-(countT idx) const { iterator n= *this; n.advancePoint(-idx); return n; }
|
||||
difference_type operator-(iterator o) const { QHULL_ASSERT(qh_qh==o.qh_qh && point_dimension==o.point_dimension); return (point_dimension ? (point_coordinates-o.point_coordinates)/point_dimension : 0); }
|
||||
};//QhullPoints::iterator
|
||||
|
||||
#//!\name QhullPoints::const_iterator
|
||||
//!\todo QH11018 FIX: const_iterator same as iterator. SHould have a common definition
|
||||
class const_iterator : public QhullPoint {
|
||||
|
||||
public:
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
typedef QhullPoint value_type;
|
||||
typedef const value_type * pointer;
|
||||
typedef const value_type & reference;
|
||||
typedef ptrdiff_t difference_type;
|
||||
|
||||
const_iterator(const QhullPoints::iterator &o) : QhullPoint(*o) {}
|
||||
explicit const_iterator(const QhullPoints &ps) : QhullPoint(ps.qh(), ps.dimension(), ps.coordinates()) {}
|
||||
const_iterator(const int pointDimension, coordT *c): QhullPoint(pointDimension, c) {}
|
||||
const_iterator(const Qhull &q, coordT *c): QhullPoint(q, c) {}
|
||||
const_iterator(const Qhull &q, int pointDimension, coordT *c): QhullPoint(q, pointDimension, c) {}
|
||||
const_iterator(QhullQh *qqh, coordT *c): QhullPoint(qqh, c) {}
|
||||
const_iterator(QhullQh *qqh, int pointDimension, coordT *c): QhullPoint(qqh, pointDimension, c) {}
|
||||
const_iterator(const const_iterator &o) : QhullPoint(*o) {}
|
||||
const_iterator &operator=(const const_iterator &o) { defineAs(const_cast<const_iterator &>(o)); return *this; }
|
||||
|
||||
// value/non-const since advancePoint(1), etc. modifies self
|
||||
const QhullPoint & operator*() const { return *this; }
|
||||
const QhullPoint * operator->() const { return this; }
|
||||
// value instead of reference since advancePoint() modifies self
|
||||
const QhullPoint operator[](countT idx) const { QhullPoint n= *this; n.advancePoint(idx); return n; }
|
||||
bool operator==(const const_iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return (point_coordinates == o.point_coordinates && point_dimension==o.point_dimension); }
|
||||
bool operator!=(const const_iterator &o) const { return (! operator==(o)); }
|
||||
bool operator<(const const_iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return (point_coordinates < o.point_coordinates); }
|
||||
bool operator<=(const const_iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return (point_coordinates <= o.point_coordinates); }
|
||||
bool operator>(const const_iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return (point_coordinates > o.point_coordinates); }
|
||||
bool operator>=(const const_iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return (point_coordinates >= o.point_coordinates); }
|
||||
const_iterator &operator++() { advancePoint(1); return *this; }
|
||||
const_iterator operator++(int) { const_iterator n= *this; operator++(); return const_iterator(n); }
|
||||
const_iterator &operator--() { advancePoint(-1); return *this; }
|
||||
const_iterator operator--(int) { const_iterator n= *this; operator--(); return const_iterator(n); }
|
||||
const_iterator &operator+=(countT idx) { advancePoint(idx); return *this; }
|
||||
const_iterator &operator-=(countT idx) { advancePoint(-idx); return *this; }
|
||||
const_iterator operator+(countT idx) const { const_iterator n= *this; n.advancePoint(idx); return n; }
|
||||
const_iterator operator-(countT idx) const { const_iterator n= *this; n.advancePoint(-idx); return n; }
|
||||
difference_type operator-(const_iterator o) const { QHULL_ASSERT(qh_qh==o.qh_qh && point_dimension==o.point_dimension); return (point_dimension ? (point_coordinates-o.point_coordinates)/point_dimension : 0); }
|
||||
};//QhullPoints::const_iterator
|
||||
|
||||
#//!\name IO
|
||||
struct PrintPoints{
|
||||
const QhullPoints *points;
|
||||
const char * point_message;
|
||||
bool with_identifier;
|
||||
PrintPoints(const char *message, bool withIdentifier, const QhullPoints &ps) : points(&ps), point_message(message), with_identifier(withIdentifier) {}
|
||||
};//PrintPoints
|
||||
PrintPoints print(const char *message) const { return PrintPoints(message, false, *this); }
|
||||
PrintPoints printWithIdentifier(const char *message) const { return PrintPoints(message, true, *this); }
|
||||
};//QhullPoints
|
||||
|
||||
|
||||
//! QhullPointsIterator is a Java-style iterator. It may be used on temporary results. It copies the pointers in QhullPoints
|
||||
//! Did not use QHULL_DECLARE_SEQUENTIAL_ITERATOR because next(),etc cannot return a reference to a temporary
|
||||
class QhullPointsIterator
|
||||
{
|
||||
typedef QhullPoints::const_iterator const_iterator;
|
||||
|
||||
#//!\name Fields
|
||||
private:
|
||||
QhullPoints ps;
|
||||
const_iterator i;
|
||||
|
||||
public:
|
||||
QhullPointsIterator(const QhullPoints &other) : ps(other), i(ps.constBegin()) {}
|
||||
QhullPointsIterator &operator=(const QhullPoints &other) { ps= other; i= ps.constBegin(); return *this; }
|
||||
|
||||
bool findNext(const QhullPoint &t);
|
||||
bool findPrevious(const QhullPoint &t);
|
||||
bool hasNext() const { return i != ps.constEnd(); }
|
||||
bool hasPrevious() const { return i != ps.constBegin(); }
|
||||
QhullPoint next() { return *i++; }
|
||||
QhullPoint peekNext() const { return *i; }
|
||||
QhullPoint peekPrevious() const { const_iterator p= i; return *--p; }
|
||||
QhullPoint previous() { return *--i; }
|
||||
void toBack() { i= ps.constEnd(); }
|
||||
void toFront() { i= ps.constBegin(); }
|
||||
};//QhullPointsIterator
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
#//!\name Global
|
||||
|
||||
std::ostream & operator<<(std::ostream &os, const orgQhull::QhullPoints &p);
|
||||
std::ostream & operator<<(std::ostream &os, const orgQhull::QhullPoints::PrintPoints &pr);
|
||||
|
||||
#endif // QHULLPOINTS_H
|
||||
@@ -0,0 +1,188 @@
|
||||
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/QhullQh.cpp#7 $$Change: 3009 $
|
||||
** $DateTime: 2020/07/30 19:25:22 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#//! QhullQh -- Qhull's global data structure, qhT, as a C++ class
|
||||
|
||||
|
||||
#include "libqhullcpp/QhullQh.h"
|
||||
|
||||
#include "libqhullcpp/QhullError.h"
|
||||
#include "libqhullcpp/QhullStat.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
using std::cerr;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using std::ostream;
|
||||
|
||||
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
|
||||
#pragma warning( disable : 4611) // interaction between '_setjmp' and C++ object destruction is non-portable
|
||||
#pragma warning( disable : 4996) // function was declared deprecated(strcpy, localtime, etc.)
|
||||
#endif
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
#//!\name Global variables
|
||||
const double QhullQh::
|
||||
default_factor_epsilon= 1.0;
|
||||
|
||||
#//!\name Constructor, destructor, etc.
|
||||
|
||||
//! Derived from qh_new_qhull[user.c]
|
||||
QhullQh::
|
||||
QhullQh()
|
||||
: qhull_status(qh_ERRnone)
|
||||
, qhull_message()
|
||||
, error_stream(0)
|
||||
, output_stream(0)
|
||||
, factor_epsilon(QhullQh::default_factor_epsilon)
|
||||
, use_output_stream(false)
|
||||
{
|
||||
// NOerrors: TRY_QHULL_ not needed since these routines do not call qh_errexit()
|
||||
qh_meminit(this, NULL);
|
||||
qh_initstatistics(this);
|
||||
qh_initqhull_start2(this, NULL, NULL, qh_FILEstderr); // Initialize qhT
|
||||
this->ISqhullQh= True;
|
||||
}//QhullQh
|
||||
|
||||
QhullQh::
|
||||
~QhullQh()
|
||||
{
|
||||
checkAndFreeQhullMemory();
|
||||
}//~QhullQh
|
||||
|
||||
#//!\name Methods
|
||||
|
||||
//! Check memory for internal consistency
|
||||
//! Free global memory used by qh_initbuild and qh_buildhull
|
||||
//! Zero the qhT data structure, except for memory (qhmemT) and statistics (qhstatT)
|
||||
//! Check and free short memory (e.g., facetT)
|
||||
//! Zero the qhmemT data structure
|
||||
void QhullQh::
|
||||
checkAndFreeQhullMemory()
|
||||
{
|
||||
#ifdef qh_NOmem
|
||||
qh_freeqhull(this, qh_ALL);
|
||||
#else
|
||||
qh_memcheck(this);
|
||||
qh_freeqhull(this, !qh_ALL);
|
||||
countT curlong;
|
||||
countT totlong;
|
||||
qh_memfreeshort(this, &curlong, &totlong);
|
||||
if(curlong || totlong)
|
||||
throw QhullError(10026, "Qhull error: qhull did not free %d bytes of long memory (%d pieces).", totlong, curlong);
|
||||
#endif
|
||||
}//checkAndFreeQhullMemory
|
||||
|
||||
#//!\name Messaging
|
||||
|
||||
void QhullQh::
|
||||
appendQhullMessage(const string &s)
|
||||
{
|
||||
if(output_stream && use_output_stream && this->USEstdout){
|
||||
*output_stream << s;
|
||||
}else if(error_stream){
|
||||
*error_stream << s;
|
||||
}else{
|
||||
qhull_message += s;
|
||||
}
|
||||
}//appendQhullMessage
|
||||
|
||||
//! clearQhullMessage does not throw errors (~Qhull)
|
||||
void QhullQh::
|
||||
clearQhullMessage()
|
||||
{
|
||||
qhull_status= qh_ERRnone;
|
||||
qhull_message.clear();
|
||||
RoadError::clearGlobalLog();
|
||||
}//clearQhullMessage
|
||||
|
||||
//! hasQhullMessage does not throw errors (~Qhull)
|
||||
bool QhullQh::
|
||||
hasQhullMessage() const
|
||||
{
|
||||
return (!qhull_message.empty() || qhull_status!=qh_ERRnone);
|
||||
// QH11006 FIX: inconsistent usage with Rbox. hasRboxMessage just tests rbox_status. No appendRboxMessage()
|
||||
}
|
||||
|
||||
void QhullQh::
|
||||
maybeThrowQhullMessage(int exitCode)
|
||||
{
|
||||
if(!NOerrexit){
|
||||
if(qhull_message.size()>0){
|
||||
qhull_message.append("\n");
|
||||
}
|
||||
if(exitCode || qhull_status==qh_ERRnone){
|
||||
qhull_status= 10073;
|
||||
}else{
|
||||
qhull_message.append("QH10073: ");
|
||||
}
|
||||
qhull_message.append("Cannot call maybeThrowQhullMessage() from QH_TRY_(). Or missing 'qh->NOerrexit=true;' after QH_TRY_(){...}.");
|
||||
}
|
||||
if(qhull_status==qh_ERRnone){
|
||||
qhull_status= exitCode;
|
||||
}
|
||||
if(qhull_status!=qh_ERRnone){
|
||||
QhullError e(qhull_status, qhull_message);
|
||||
clearQhullMessage();
|
||||
throw e; // QH11007 FIX: copy constructor is expensive if logging
|
||||
}
|
||||
}//maybeThrowQhullMessage
|
||||
|
||||
void QhullQh::
|
||||
maybeThrowQhullMessage(int exitCode, int noThrow) throw()
|
||||
{
|
||||
QHULL_UNUSED(noThrow);
|
||||
|
||||
if(qhull_status==qh_ERRnone){
|
||||
qhull_status= exitCode;
|
||||
}
|
||||
if(qhull_status!=qh_ERRnone){
|
||||
QhullError e(qhull_status, qhull_message);
|
||||
e.logErrorLastResort();
|
||||
}
|
||||
}//maybeThrowQhullMessage
|
||||
|
||||
//! qhullMessage does not throw errors (~Qhull)
|
||||
std::string QhullQh::
|
||||
qhullMessage() const
|
||||
{
|
||||
if(qhull_message.empty() && qhull_status!=qh_ERRnone){
|
||||
return "qhull: no message for error. Check cerr or error stream\n";
|
||||
}else{
|
||||
return qhull_message;
|
||||
}
|
||||
}//qhullMessage
|
||||
|
||||
int QhullQh::
|
||||
qhullStatus() const
|
||||
{
|
||||
return qhull_status;
|
||||
}//qhullStatus
|
||||
|
||||
void QhullQh::
|
||||
setErrorStream(ostream *os)
|
||||
{
|
||||
error_stream= os;
|
||||
}//setErrorStream
|
||||
|
||||
//! Updates use_output_stream
|
||||
void QhullQh::
|
||||
setOutputStream(ostream *os)
|
||||
{
|
||||
output_stream= os;
|
||||
use_output_stream= (os!=0);
|
||||
}//setOutputStream
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/QhullQh.h#3 $$Change: 2963 $
|
||||
** $DateTime: 2020/06/03 19:31:01 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QHULLQH_H
|
||||
#define QHULLQH_H
|
||||
|
||||
#include "libqhull_r/qhull_ra.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
|
||||
#pragma warning( disable : 4611) /* interaction between '_setjmp' and C++ object destruction is non-portable */
|
||||
/* setjmp should not be implemented with 'catch' */
|
||||
#endif
|
||||
|
||||
//! Use QH_TRY_ or QH_TRY_NOTHROW_ to call a libqhull_r routine that may invoke qh_errexit()
|
||||
//! QH_TRY_(qh){...} qh->NOerrexit=true;
|
||||
//! No object creation -- longjmp() skips object destructors
|
||||
//! To test for error when done -- qh->maybeThrowQhullMessage(QH_TRY_status);
|
||||
//! Use the same compiler for QH_TRY_, libqhullcpp, and libqhull_r. setjmp() is not portable between compilers.
|
||||
|
||||
#define QH_TRY_ERROR 10071
|
||||
|
||||
#define QH_TRY_(qh) \
|
||||
int QH_TRY_status; \
|
||||
if(qh->NOerrexit){ \
|
||||
qh->NOerrexit= False; \
|
||||
QH_TRY_status= setjmp(qh->errexit); \
|
||||
}else{ \
|
||||
throw QhullError(QH_TRY_ERROR, "Cannot invoke QH_TRY_() from inside a QH_TRY_. Or missing 'qh->NOerrexit=true' after previously called QH_TRY_(qh){...}"); \
|
||||
} \
|
||||
if(!QH_TRY_status)
|
||||
|
||||
#define QH_TRY_NO_THROW_(qh) \
|
||||
int QH_TRY_status; \
|
||||
if(qh->NOerrexit){ \
|
||||
qh->NOerrexit= False; \
|
||||
QH_TRY_status= setjmp(qh->errexit); \
|
||||
}else{ \
|
||||
QH_TRY_status= QH_TRY_ERROR; \
|
||||
} \
|
||||
if(!QH_TRY_status)
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
#//!\name Defined here
|
||||
//! QhullQh -- Qhull's global data structure, qhT, as a C++ class
|
||||
class QhullQh;
|
||||
|
||||
//! POD type equivalent to qhT. No virtual members
|
||||
class QhullQh : public qhT {
|
||||
|
||||
#//!\name Constants
|
||||
|
||||
#//!\name Fields
|
||||
private:
|
||||
int qhull_status; //!< qh_ERRnone if valid
|
||||
std::string qhull_message; //!< Returned messages from libqhull_r
|
||||
std::ostream * error_stream; //!< overrides errorMessage, use appendQhullMessage()
|
||||
std::ostream * output_stream; //!< send output to stream
|
||||
double factor_epsilon; //!< Factor to increase ANGLEround and DISTround for hyperplane equality
|
||||
bool use_output_stream; //!< True if using output_stream
|
||||
|
||||
//! modified by qh_fprintf in QhullUser.cpp
|
||||
friend void ::qh_fprintf(qhT *qh, FILE *fp, int msgcode, const char *fmt, ... );
|
||||
|
||||
static const double default_factor_epsilon; //!< Default factor_epsilon is 1.0, never updated
|
||||
|
||||
#//!\name Constructors
|
||||
public:
|
||||
QhullQh();
|
||||
~QhullQh();
|
||||
private:
|
||||
//!disable copy constructor and assignment
|
||||
QhullQh(const QhullQh &);
|
||||
QhullQh & operator=(const QhullQh &);
|
||||
public:
|
||||
|
||||
#//!\name GetSet
|
||||
double factorEpsilon() const { return factor_epsilon; }
|
||||
void setFactorEpsilon(double a) { factor_epsilon= a; }
|
||||
void disableOutputStream() { use_output_stream= false; }
|
||||
void enableOutputStream() { use_output_stream= true; }
|
||||
|
||||
#//!\name Messaging
|
||||
void appendQhullMessage(const std::string &s);
|
||||
void clearQhullMessage();
|
||||
std::string qhullMessage() const;
|
||||
bool hasOutputStream() const { return use_output_stream; }
|
||||
bool hasQhullMessage() const;
|
||||
void maybeThrowQhullMessage(int exitCode);
|
||||
void maybeThrowQhullMessage(int exitCode, int noThrow) throw();
|
||||
int qhullStatus() const;
|
||||
void setErrorStream(std::ostream *os);
|
||||
void setOutputStream(std::ostream *os);
|
||||
|
||||
#//!\name Methods
|
||||
double angleEpsilon() const { return this->ANGLEround*factor_epsilon; } //!< Epsilon for hyperplane angle equality
|
||||
void checkAndFreeQhullMemory();
|
||||
double distanceEpsilon() const { return this->DISTround*factor_epsilon; } //!< Epsilon for distance to hyperplane
|
||||
|
||||
};//class QhullQh
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
#endif // QHULLQH_H
|
||||
@@ -0,0 +1,136 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/QhullRidge.cpp#2 $$Change: 2953 $
|
||||
** $DateTime: 2020/05/21 22:05:32 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#//! QhullRidge -- Qhull's ridge structure, ridgeT, as a C++ class
|
||||
|
||||
#include "libqhullcpp/QhullRidge.h"
|
||||
|
||||
#include "libqhullcpp/QhullSets.h"
|
||||
#include "libqhullcpp/QhullVertex.h"
|
||||
#include "libqhullcpp/Qhull.h"
|
||||
|
||||
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
|
||||
#pragma warning( disable : 4611) // interaction between '_setjmp' and C++ object destruction is non-portable
|
||||
#pragma warning( disable : 4996) // function was declared deprecated(strcpy, localtime, etc.)
|
||||
#endif
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
#//!\name Class objects
|
||||
ridgeT QhullRidge::
|
||||
s_empty_ridge= {NULL,NULL,NULL,0, // must match ridgeT -Wmissing-field-initializers
|
||||
false,false,false,false,false,false,false};
|
||||
|
||||
#//!\name Constructors
|
||||
|
||||
QhullRidge::QhullRidge(const Qhull &q)
|
||||
: qh_ridge(&s_empty_ridge)
|
||||
, qh_qh(q.qh())
|
||||
{
|
||||
}//Default
|
||||
|
||||
QhullRidge::QhullRidge(const Qhull &q, ridgeT *r)
|
||||
: qh_ridge(r ? r : &s_empty_ridge)
|
||||
, qh_qh(q.qh())
|
||||
{
|
||||
}//ridgeT
|
||||
|
||||
#//!\name foreach
|
||||
|
||||
//! Return True if nextRidge3d
|
||||
//! Simplicial facets may have incomplete ridgeSets
|
||||
//! Does not use qh_errexit()
|
||||
bool QhullRidge::
|
||||
hasNextRidge3d(const QhullFacet &f) const
|
||||
{
|
||||
if(!qh_qh){
|
||||
return false;
|
||||
}
|
||||
vertexT *v= 0;
|
||||
// Does not call qh_errexit(), TRY_QHULL_ not needed
|
||||
ridgeT *ridge= qh_nextridge3d(getRidgeT(), f.getFacetT(), &v);
|
||||
return (ridge!=0);
|
||||
}//hasNextRidge3d
|
||||
|
||||
//! Return next ridge and optional vertex for a 3d facet and ridge
|
||||
//! Does not use qh_errexit()
|
||||
QhullRidge QhullRidge::
|
||||
nextRidge3d(const QhullFacet &f, QhullVertex *nextVertex) const
|
||||
{
|
||||
vertexT *v= 0;
|
||||
ridgeT *ridge= 0;
|
||||
if(qh_qh){
|
||||
// Does not call qh_errexit(), TRY_QHULL_ not needed
|
||||
ridge= qh_nextridge3d(getRidgeT(), f.getFacetT(), &v);
|
||||
if(!ridge){
|
||||
throw QhullError(10030, "Qhull error nextRidge3d: missing next ridge for facet %d ridge %d. Does facet contain ridge?", f.id(), id());
|
||||
}
|
||||
}
|
||||
if(nextVertex!=0){
|
||||
*nextVertex= QhullVertex(qh_qh, v);
|
||||
}
|
||||
return QhullRidge(qh_qh, ridge);
|
||||
}//nextRidge3d
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
#//!\name Global functions
|
||||
|
||||
using std::endl;
|
||||
using std::ostream;
|
||||
using orgQhull::QhullRidge;
|
||||
using orgQhull::QhullVertex;
|
||||
|
||||
ostream &
|
||||
operator<<(ostream &os, const QhullRidge &r)
|
||||
{
|
||||
os << r.print("");
|
||||
return os;
|
||||
}//<< QhullRidge
|
||||
|
||||
//! Duplicate of qh_printridge [io_r.c]
|
||||
ostream &
|
||||
operator<<(ostream &os, const QhullRidge::PrintRidge &pr)
|
||||
{
|
||||
if(*pr.print_message){
|
||||
os << pr.print_message << " ";
|
||||
}else{
|
||||
os << " - ";
|
||||
}
|
||||
QhullRidge r= *pr.ridge;
|
||||
os << "r" << r.id();
|
||||
if(r.getRidgeT()->tested){
|
||||
os << " tested";
|
||||
}
|
||||
if(r.getRidgeT()->nonconvex){
|
||||
os << " nonconvex";
|
||||
}
|
||||
if(r.getRidgeT()->mergevertex){
|
||||
os << " mergevertex";
|
||||
}
|
||||
if(r.getRidgeT()->mergevertex2){
|
||||
os << " mergevertex2";
|
||||
}
|
||||
if(r.getRidgeT()->simplicialtop){
|
||||
os << " simplicialtop";
|
||||
}
|
||||
if(r.getRidgeT()->simplicialbot){
|
||||
os << " simplicialbot";
|
||||
}
|
||||
os << endl;
|
||||
os << r.vertices().print(" vertices:");
|
||||
if(r.getRidgeT()->top && r.getRidgeT()->bottom){
|
||||
os << " between f" << r.topFacet().id() << " and f" << r.bottomFacet().id() << endl;
|
||||
}else if(r.getRidgeT()->top){
|
||||
os << " top f" << r.topFacet().id() << endl;
|
||||
}else if(r.getRidgeT()->bottom){
|
||||
os << " bottom f" << r.bottomFacet().id() << endl;
|
||||
}
|
||||
|
||||
return os;
|
||||
}//<< PrintRidge
|
||||
@@ -0,0 +1,118 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/QhullRidge.h#4 $$Change: 3001 $
|
||||
** $DateTime: 2020/07/24 20:43:28 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QHULLRIDGE_H
|
||||
#define QHULLRIDGE_H
|
||||
|
||||
#include "libqhull_r/qhull_ra.h"
|
||||
#include "libqhullcpp/QhullSet.h"
|
||||
#include "libqhullcpp/QhullVertex.h"
|
||||
#include "libqhullcpp/QhullVertexSet.h"
|
||||
#include "libqhullcpp/QhullFacet.h"
|
||||
|
||||
#include <ostream>
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
#//!\name Used here
|
||||
class Qhull;
|
||||
class QhullVertex;
|
||||
class QhullVertexSet;
|
||||
class QhullFacet;
|
||||
|
||||
#//!\name Defined here
|
||||
//! QhullRidge -- Qhull's ridge structure, ridgeT [libqhull.h], as a C++ class
|
||||
class QhullRidge;
|
||||
|
||||
typedef QhullSet<QhullRidge> QhullRidgeSet;
|
||||
|
||||
//! QhullRidgeSetIterator is a Java-style iterator for QhullRidge in a QhullRidgeSet
|
||||
//! QhullRidgeSetIterator may be used on temporary results. It copies the pointers in QhullRidgeSet
|
||||
//! Use QhullSets.h to avoid circular references to QhullRidgeSet and QhullRidgeSetIterator
|
||||
typedef QhullSetIterator<QhullRidge> QhullRidgeSetIterator;
|
||||
|
||||
/************************
|
||||
a ridge is hull_dim-1 simplex between two neighboring facets. If the
|
||||
facets are non-simplicial, there may be more than one ridge between
|
||||
two facets. E.G. a 4-d hypercube has two triangles between each pair
|
||||
of neighboring facets.
|
||||
|
||||
topological information:
|
||||
vertices a set of vertices
|
||||
top,bottom neighboring facets with orientation
|
||||
|
||||
geometric information:
|
||||
tested True if ridge is clearly convex
|
||||
nonconvex True if ridge is non-convex
|
||||
*/
|
||||
|
||||
class QhullRidge {
|
||||
|
||||
#//!\name Defined here
|
||||
public:
|
||||
typedef ridgeT * base_type; // for QhullRidgeSet
|
||||
|
||||
#//!\name Fields
|
||||
private:
|
||||
ridgeT * qh_ridge; //!< Corresponding ridgeT, never 0
|
||||
QhullQh * qh_qh; //!< QhullQh/qhT for ridgeT, may be 0
|
||||
|
||||
#//!\name Class objects
|
||||
static ridgeT s_empty_ridge;
|
||||
|
||||
public:
|
||||
#//!\name Constants
|
||||
|
||||
#//!\name Constructors
|
||||
QhullRidge() : qh_ridge(&s_empty_ridge), qh_qh(0) {}
|
||||
explicit QhullRidge(const Qhull &q);
|
||||
QhullRidge(const Qhull &q, ridgeT *r);
|
||||
explicit QhullRidge(QhullQh *qqh) : qh_ridge(&s_empty_ridge), qh_qh(qqh) {}
|
||||
QhullRidge(QhullQh *qqh, ridgeT *r) : qh_ridge(r ? r : &s_empty_ridge), qh_qh(qqh) {}
|
||||
// Creates an alias. Does not copy QhullRidge. Needed for return by value and parameter passing
|
||||
QhullRidge(const QhullRidge &other) : qh_ridge(other.qh_ridge), qh_qh(other.qh_qh) {}
|
||||
// Creates an alias. Does not copy QhullRidge. Needed for vector<QhullRidge>
|
||||
QhullRidge & operator=(const QhullRidge &other) { qh_ridge= other.qh_ridge; qh_qh= other.qh_qh; return *this; }
|
||||
~QhullRidge() {}
|
||||
|
||||
#//!\name GetSet
|
||||
QhullFacet bottomFacet() const { return QhullFacet(qh_qh, qh_ridge->bottom); }
|
||||
int dimension() const { return ((qh_qh && qh_qh->hull_dim) ? qh_qh->hull_dim-1 : 0); }
|
||||
ridgeT * getBaseT() const { return getRidgeT(); } //!< For QhullSet<QhullRidge>
|
||||
ridgeT * getRidgeT() const { return qh_ridge; }
|
||||
countT id() const { return qh_ridge->id; }
|
||||
bool isValid() const { return (qh_qh && qh_ridge != &s_empty_ridge); }
|
||||
bool operator==(const QhullRidge &other) const { return qh_ridge==other.qh_ridge; }
|
||||
bool operator!=(const QhullRidge &other) const { return !operator==(other); }
|
||||
QhullFacet otherFacet(const QhullFacet &f) const { return QhullFacet(qh_qh, (qh_ridge->top==f.getFacetT() ? qh_ridge->bottom : qh_ridge->top)); }
|
||||
QhullQh * qh() const { return qh_qh; }
|
||||
void setRidgeT(QhullQh *qqh, ridgeT *ridge) { qh_qh= qqh; qh_ridge= ridge; }
|
||||
QhullFacet topFacet() const { return QhullFacet(qh_qh, qh_ridge->top); }
|
||||
|
||||
#//!\name foreach
|
||||
bool hasNextRidge3d(const QhullFacet &f) const;
|
||||
QhullRidge nextRidge3d(const QhullFacet &f) const { return nextRidge3d(f, 0); }
|
||||
QhullRidge nextRidge3d(const QhullFacet &f, QhullVertex *nextVertex) const;
|
||||
QhullVertexSet vertices() const { return QhullVertexSet(qh_qh, qh_ridge->vertices); }
|
||||
|
||||
#//!\name IO
|
||||
|
||||
struct PrintRidge{
|
||||
const QhullRidge *ridge;
|
||||
const char * print_message; //!< non-null message
|
||||
PrintRidge(const char *message, const QhullRidge &r) : ridge(&r), print_message(message) {}
|
||||
};//PrintRidge
|
||||
PrintRidge print(const char* message) const { return PrintRidge(message, *this); }
|
||||
};//class QhullRidge
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullRidge &r);
|
||||
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullRidge::PrintRidge &pr);
|
||||
|
||||
#endif // QHULLRIDGE_H
|
||||
@@ -0,0 +1,62 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/QhullSet.cpp#4 $$Change: 3009 $
|
||||
** $DateTime: 2020/07/30 19:25:22 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#//! QhullSet -- Qhull's set structure, setT, as a C++ class
|
||||
|
||||
#include "libqhullcpp/QhullSet.h"
|
||||
|
||||
#include "libqhullcpp/Qhull.h"
|
||||
#include "libqhullcpp/QhullError.h"
|
||||
|
||||
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
|
||||
#endif
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
#//!\name Class objects
|
||||
|
||||
setT QhullSetBase::
|
||||
s_empty_set;
|
||||
|
||||
#//!\name Constructors
|
||||
|
||||
QhullSetBase::
|
||||
QhullSetBase(const Qhull &q, setT *s)
|
||||
: qh_set(s ? s : &s_empty_set)
|
||||
, qh_qh(q.qh())
|
||||
{
|
||||
}
|
||||
|
||||
#//!\name Class methods
|
||||
|
||||
// Same code for qh_setsize [qset_r.c] and QhullSetBase::count [static]
|
||||
countT QhullSetBase::
|
||||
count(const setT *set)
|
||||
{
|
||||
countT size;
|
||||
const setelemT *sizep;
|
||||
|
||||
if(!set){
|
||||
return(0);
|
||||
}
|
||||
sizep= SETsizeaddr_(set);
|
||||
if((size= sizep->i)){
|
||||
size--;
|
||||
if(size > set->maxsize){
|
||||
// QH11022 FIX: How to add additional output to a error? -- qh_setprint(qhmem.ferr, "set: ", set);
|
||||
throw QhullError(10032, "QhullSet internal error: current set size %d is greater than maximum size %d\n",
|
||||
size, set->maxsize);
|
||||
}
|
||||
}else{
|
||||
size= set->maxsize;
|
||||
}
|
||||
return size;
|
||||
}//count
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
@@ -0,0 +1,464 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/QhullSet.h#6 $$Change: 3396 $
|
||||
** $DateTime: 2023/01/02 16:59:48 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QhullSet_H
|
||||
#define QhullSet_H
|
||||
|
||||
#include "libqhull_r/qhull_ra.h"
|
||||
#include "libqhullcpp/QhullError.h"
|
||||
#include "libqhullcpp/QhullQh.h"
|
||||
|
||||
#include <cstddef> // ptrdiff_t, size_t
|
||||
|
||||
#ifndef QHULL_NO_STL
|
||||
#include <vector>
|
||||
#endif
|
||||
|
||||
#ifdef QHULL_USES_QT
|
||||
#include <QtCore/QList>
|
||||
#endif
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
#//!\name Used here
|
||||
class Qhull;
|
||||
|
||||
#//!\name Defined here
|
||||
class QhullSetBase; //! Base class for QhullSet<T>
|
||||
//! QhullSet<T> defined below
|
||||
//! QhullSetIterator<T> defined below
|
||||
//! \see QhullPointSet, QhullLinkedList<T>
|
||||
|
||||
//! QhullSetBase is a wrapper for Qhull's setT of void* pointers
|
||||
//! \see libqhull_r/qset.h
|
||||
class QhullSetBase {
|
||||
|
||||
private:
|
||||
#//!\name Fields --
|
||||
setT * qh_set;
|
||||
QhullQh * qh_qh; //! Provides access to setT memory allocator
|
||||
|
||||
#//!\name Class objects
|
||||
static setT s_empty_set; //! Used if setT* is NULL
|
||||
|
||||
public:
|
||||
#//!\name Constructors
|
||||
QhullSetBase(const Qhull &q, setT *s);
|
||||
QhullSetBase(QhullQh *qqh, setT *s) : qh_set(s ? s : &s_empty_set), qh_qh(qqh) {}
|
||||
//! Copy constructor copies the pointer but not the set. Needed for return by value and parameter passing.
|
||||
QhullSetBase(const QhullSetBase &other) : qh_set(other.qh_set), qh_qh(other.qh_qh) {}
|
||||
QhullSetBase & operator=(const QhullSetBase &other) { qh_set= other.qh_set; qh_qh= other.qh_qh; return *this; }
|
||||
~QhullSetBase() {}
|
||||
|
||||
private:
|
||||
//!disabled since memory allocation for QhullSet not defined
|
||||
QhullSetBase() : qh_set(NULL), qh_qh(NULL) {}
|
||||
public:
|
||||
|
||||
#//!\name GetSet
|
||||
countT count() const { return QhullSetBase::count(qh_set); }
|
||||
void defineAs(setT *s) { qh_set= s ? s : &s_empty_set; } //!< Not type-safe since setT may contain any type
|
||||
void forceEmpty() { qh_set= &s_empty_set; }
|
||||
setT * getSetT() const { return qh_set; }
|
||||
bool isEmpty() const { return SETempty_(qh_set); }
|
||||
QhullQh * qh() const { return qh_qh; }
|
||||
setT ** referenceSetT() { return &qh_set; }
|
||||
size_t size() const { return QhullSetBase::count(qh_set); }
|
||||
|
||||
#//!\name Element
|
||||
protected:
|
||||
void ** beginPointer() const { return &qh_set->e[0].p; }
|
||||
void ** elementPointer(countT idx) const { QHULL_ASSERT(idx>=0 && idx<qh_set->maxsize); return &SETelem_(qh_set, idx); }
|
||||
//! Always points to 0
|
||||
void ** endPointer() const { return qh_setendpointer(qh_set); }
|
||||
|
||||
#//!\name Class methods
|
||||
public:
|
||||
static countT count(const setT *set);
|
||||
//s may be null
|
||||
static bool isEmpty(const setT *s) { return SETempty_(s); }
|
||||
};//QhullSetBase
|
||||
|
||||
|
||||
//! QhullSet<T> -- A read-only wrapper to Qhull's collection class, setT.
|
||||
//! QhullSet is similar to STL's <vector> and Qt's QVector
|
||||
//! QhullSet is unrelated to STL and Qt's set and map types (e.g., QSet and QMap)
|
||||
//! T is a Qhull type that defines 'base_type' and getBaseT() (e.g., QhullFacet with base_type 'facetT *'
|
||||
//! A QhullSet does not own its contents -- erase(), clear(), removeFirst(), removeLast(), pop_back(), pop_front(), fromStdList() not defined
|
||||
//! QhullSetIterator is faster than STL-style iterator/const_iterator
|
||||
//! Qhull's FOREACHelement_() [qset_r.h] maybe more efficient than QhullSet. It uses a NULL terminator instead of an end pointer. STL requires an end pointer.
|
||||
//! Derived from QhullLinkedList.h and Qt/core/tools/qlist.h w/o QT_STRICT_ITERATORS
|
||||
template <typename T>
|
||||
class QhullSet : public QhullSetBase {
|
||||
|
||||
private:
|
||||
#//!\name Fields -- see QhullSetBase
|
||||
|
||||
#//!\name Class objects
|
||||
static setT s_empty_set; //! Workaround for no setT allocator. Used if setT* is NULL
|
||||
|
||||
public:
|
||||
#//!\name Defined here
|
||||
class iterator;
|
||||
class const_iterator;
|
||||
typedef typename QhullSet<T>::iterator Iterator;
|
||||
typedef typename QhullSet<T>::const_iterator ConstIterator;
|
||||
|
||||
#//!\name Constructors
|
||||
QhullSet(const Qhull &q, setT *s) : QhullSetBase(q, s) { }
|
||||
QhullSet(QhullQh *qqh, setT *s) : QhullSetBase(qqh, s) { }
|
||||
//Conversion from setT* is not type-safe. Implicit conversion for void* to T
|
||||
//Copy constructor copies pointer but not contents. Needed for return by value.
|
||||
QhullSet(const QhullSet &other) : QhullSetBase(other) {}
|
||||
QhullSet<T> & operator=(const QhullSet &other) { QhullSetBase::operator=(other); return *this; }
|
||||
~QhullSet() {}
|
||||
|
||||
private:
|
||||
//!Disable default constructor. See QhullSetBase
|
||||
QhullSet();
|
||||
public:
|
||||
|
||||
#//!\name Conversion
|
||||
|
||||
#ifndef QHULL_NO_STL
|
||||
std::vector<T> toStdVector() const;
|
||||
#endif
|
||||
#ifdef QHULL_USES_QT
|
||||
QList<T> toQList() const;
|
||||
#endif
|
||||
|
||||
#//!\name GetSet -- see QhullSetBase for count(), empty(), isEmpty(), size()
|
||||
using QhullSetBase::count;
|
||||
using QhullSetBase::isEmpty;
|
||||
// operator== defined for QhullSets of the same type
|
||||
bool operator==(const QhullSet &other) const { return qh_setequal(getSetT(), other.getSetT()); }
|
||||
bool operator!=(const QhullSet &other) const { return !operator==(other); }
|
||||
|
||||
#//!\name Element access
|
||||
// Constructs T. Cannot return reference.
|
||||
const T at(countT idx) const { return operator[](idx); }
|
||||
// Constructs T. Cannot return reference.
|
||||
const T back() const { return last(); }
|
||||
T back() { return last(); }
|
||||
//! end element is NULL
|
||||
const typename T::base_type * constData() const { return reinterpret_cast<const typename T::base_type *>(beginPointer()); }
|
||||
typename T::base_type * data() { return reinterpret_cast<typename T::base_type *>(beginPointer()); }
|
||||
const typename T::base_type *data() const { return reinterpret_cast<const typename T::base_type *>(beginPointer()); }
|
||||
typename T::base_type * endData() { return reinterpret_cast<typename T::base_type *>(endPointer()); }
|
||||
const typename T::base_type * endData() const { return reinterpret_cast<const typename T::base_type *>(endPointer()); }
|
||||
// Constructs T. Cannot return reference.
|
||||
const T first() const { QHULL_ASSERT(!isEmpty()); return T(qh(), *data()); }
|
||||
T first() { QHULL_ASSERT(!isEmpty()); return T(qh(), *data()); }
|
||||
// Constructs T. Cannot return reference.
|
||||
const T front() const { return first(); }
|
||||
T front() { return first(); }
|
||||
// Constructs T. Cannot return reference.
|
||||
const T last() const { QHULL_ASSERT(!isEmpty()); return T(qh(), *(endData()-1)); }
|
||||
T last() { QHULL_ASSERT(!isEmpty()); return T(qh(), *(endData()-1)); }
|
||||
// mid() not available. No setT constructor
|
||||
// Constructs T. Cannot return reference.
|
||||
const T operator[](countT idx) const { const typename T::base_type *p= reinterpret_cast<typename T::base_type *>(elementPointer(idx)); QHULL_ASSERT(idx>=0 && p < endData()); return T(qh(), *p); }
|
||||
T operator[](countT idx) { typename T::base_type *p= reinterpret_cast<typename T::base_type *>(elementPointer(idx)); QHULL_ASSERT(idx>=0 && p < endData()); return T(qh(), *p); }
|
||||
const T second() const { return operator[](1); }
|
||||
T second() { return operator[](1); }
|
||||
T value(countT idx) const;
|
||||
T value(countT idx, const T &defaultValue) const;
|
||||
|
||||
#//!\name Read-write -- Not available, no setT constructor
|
||||
|
||||
#//!\name iterator
|
||||
iterator begin() { return iterator(qh(), reinterpret_cast<typename T::base_type *>(beginPointer())); }
|
||||
const_iterator begin() const { return const_iterator(qh(), data()); }
|
||||
const_iterator constBegin() const { return const_iterator(qh(), data()); }
|
||||
const_iterator constEnd() const { return const_iterator(qh(), endData()); }
|
||||
iterator end() { return iterator(qh(), endData()); }
|
||||
const_iterator end() const { return const_iterator(qh(), endData()); }
|
||||
|
||||
#//!\name Search
|
||||
bool contains(const T &t) const;
|
||||
countT count(const T &t) const;
|
||||
countT indexOf(const T &t) const { /* no qh_qh */ return qh_setindex(getSetT(), t.getBaseT()); }
|
||||
countT lastIndexOf(const T &t) const;
|
||||
|
||||
// before const_iterator for conversion with comparison operators
|
||||
class iterator {
|
||||
friend class const_iterator;
|
||||
private:
|
||||
typename T::base_type * i; // e.g., facetT**, first for debugger
|
||||
QhullQh * qh_qh;
|
||||
|
||||
public:
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
typedef T value_type;
|
||||
|
||||
iterator(QhullQh *qqh, typename T::base_type *p) : i(p), qh_qh(qqh) {}
|
||||
iterator(const iterator &o) : i(o.i), qh_qh(o.qh_qh) {}
|
||||
iterator & operator=(const iterator &o) { i= o.i; qh_qh= o.qh_qh; return *this; }
|
||||
|
||||
// Constructs T. Cannot return reference.
|
||||
T operator*() const { return T(qh_qh, *i); }
|
||||
//operator->() n/a, value-type
|
||||
// Constructs T. Cannot return reference.
|
||||
T operator[](countT idx) const { return T(qh_qh, *(i+idx)); } //!< No error checking
|
||||
bool operator==(const iterator &o) const { return i == o.i; }
|
||||
bool operator!=(const iterator &o) const { return !operator==(o); }
|
||||
bool operator==(const const_iterator &o) const { return (i==reinterpret_cast<const iterator &>(o).i); }
|
||||
bool operator!=(const const_iterator &o) const { return !operator==(o); }
|
||||
|
||||
//! Assumes same point set
|
||||
countT operator-(const iterator &o) const { return static_cast<countT>(i-o.i); } //WARN64
|
||||
bool operator>(const iterator &o) const { return i>o.i; }
|
||||
bool operator<=(const iterator &o) const { return !operator>(o); }
|
||||
bool operator<(const iterator &o) const { return i<o.i; }
|
||||
bool operator>=(const iterator &o) const { return !operator<(o); }
|
||||
bool operator>(const const_iterator &o) const { return (i > reinterpret_cast<const iterator &>(o).i); }
|
||||
bool operator<=(const const_iterator &o) const { return !operator>(o); }
|
||||
bool operator<(const const_iterator &o) const { return (i < reinterpret_cast<const iterator &>(o).i); }
|
||||
bool operator>=(const const_iterator &o) const { return !operator<(o); }
|
||||
|
||||
//! No error checking
|
||||
iterator & operator++() { ++i; return *this; }
|
||||
iterator operator++(int) { iterator o= *this; ++i; return o; }
|
||||
iterator & operator--() { --i; return *this; }
|
||||
iterator operator--(int) { iterator o= *this; --i; return o; }
|
||||
iterator operator+(countT j) const { return iterator(qh_qh, i+j); }
|
||||
iterator operator-(countT j) const { return operator+(-j); }
|
||||
iterator & operator+=(countT j) { i += j; return *this; }
|
||||
iterator & operator-=(countT j) { i -= j; return *this; }
|
||||
};//QhullPointSet::iterator
|
||||
|
||||
class const_iterator {
|
||||
private:
|
||||
const typename T::base_type * i; // e.g., const facetT**, first for debugger
|
||||
QhullQh * qh_qh;
|
||||
|
||||
public:
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
typedef T value_type;
|
||||
|
||||
const_iterator(QhullQh *qqh, const typename T::base_type * p) : i(p), qh_qh(qqh) {}
|
||||
const_iterator(const const_iterator &o) : i(o.i), qh_qh(o.qh_qh) {}
|
||||
const_iterator(const iterator &o) : i(o.i), qh_qh(o.qh_qh) {}
|
||||
const_iterator &operator=(const const_iterator &o) { i= o.i; qh_qh= o.qh_qh; return *this; }
|
||||
|
||||
// Constructs T. Cannot return reference. Retaining 'const T' return type for consistency with QList/QVector
|
||||
const T operator*() const { return T(qh_qh, *i); }
|
||||
const T operator[](countT idx) const { return T(qh_qh, *(i+idx)); } //!< No error checking
|
||||
//operator->() n/a, value-type
|
||||
bool operator==(const const_iterator &o) const { return i == o.i; }
|
||||
bool operator!=(const const_iterator &o) const { return !operator==(o); }
|
||||
|
||||
//! Assumes same point set
|
||||
countT operator-(const const_iterator &o) { return static_cast<countT>(i-o.i); } //WARN64
|
||||
bool operator>(const const_iterator &o) const { return i>o.i; }
|
||||
bool operator<=(const const_iterator &o) const { return !operator>(o); }
|
||||
bool operator<(const const_iterator &o) const { return i<o.i; }
|
||||
bool operator>=(const const_iterator &o) const { return !operator<(o); }
|
||||
|
||||
//!< No error checking
|
||||
const_iterator &operator++() { ++i; return *this; }
|
||||
const_iterator operator++(int) { const_iterator o= *this; ++i; return o; }
|
||||
const_iterator &operator--() { --i; return *this; }
|
||||
const_iterator operator--(int) { const_iterator o= *this; --i; return o; }
|
||||
const_iterator operator+(int j) const { return const_iterator(qh_qh, i+j); }
|
||||
const_iterator operator-(int j) const { return operator+(-j); }
|
||||
const_iterator &operator+=(int j) { i += j; return *this; }
|
||||
const_iterator &operator-=(int j) { i -= j; return *this; }
|
||||
};//QhullPointSet::const_iterator
|
||||
|
||||
};//class QhullSet
|
||||
|
||||
|
||||
//! QhullSetIterator is a Java-style iterator. It may be used on temporary results.
|
||||
//! QhullSetIterator copies the qh_set and qh_qh pointers in QhullSetBase
|
||||
//! Faster then iterator/const_iterator due to T::base_type
|
||||
template <typename T>
|
||||
class QhullSetIterator {
|
||||
|
||||
#//!\name Subtypes
|
||||
typedef typename QhullSet<T>::const_iterator const_iterator;
|
||||
|
||||
private:
|
||||
#//!\name Fields
|
||||
const typename T::base_type * i; // e.g., facetT**, first for debugger
|
||||
const typename T::base_type * begin_i; // must be initialized after i
|
||||
const typename T::base_type * end_i;
|
||||
QhullQh * qh_qh;
|
||||
|
||||
public:
|
||||
#//!\name Constructors
|
||||
QhullSetIterator(const QhullSet<T> &s) : i(s.data()), begin_i(i), end_i(s.endData()), qh_qh(s.qh()) {}
|
||||
QhullSetIterator(const QhullSetIterator<T> &o) : i(o.i), begin_i(o.begin_i), end_i(o.end_i), qh_qh(o.qh_qh) {}
|
||||
QhullSetIterator &operator=(const QhullSetIterator &o) { i= o.i; begin_i= o.begin_i; end_i= o.end_i; qh_qh= o.qh_qh; return *this; }
|
||||
|
||||
#//!\name ReadOnly
|
||||
countT countRemaining() { return static_cast<countT>(end_i-i); } // WARN64
|
||||
|
||||
#//!\name Search
|
||||
bool findNext(const T &t);
|
||||
bool findPrevious(const T &t);
|
||||
|
||||
#//!\name Foreach
|
||||
bool hasNext() const { return i != end_i; }
|
||||
bool hasPrevious() const { return i != begin_i; }
|
||||
T next() { return T(qh_qh, *i++); }
|
||||
T peekNext() const { return T(qh_qh, *i); }
|
||||
T peekPrevious() const { const typename T::base_type *p= i; return T(qh_qh, *--p); }
|
||||
T previous() { return T(qh_qh, *--i); }
|
||||
void toBack() { i= end_i; }
|
||||
void toFront() { i= begin_i; }
|
||||
};//class QhullSetIterator
|
||||
|
||||
#//!\name == Definitions =========================================
|
||||
|
||||
#//!\name Conversions
|
||||
|
||||
// See qt-qhull.cpp for QList conversion
|
||||
|
||||
#ifndef QHULL_NO_STL
|
||||
template <typename T>
|
||||
std::vector<T> QhullSet<T>::
|
||||
toStdVector() const
|
||||
{
|
||||
typename QhullSet<T>::const_iterator i= begin();
|
||||
typename QhullSet<T>::const_iterator e= end();
|
||||
std::vector<T> vs;
|
||||
while(i!=e){
|
||||
vs.push_back(*i++);
|
||||
}
|
||||
return vs;
|
||||
}//toStdVector
|
||||
#endif //QHULL_NO_STL
|
||||
|
||||
#ifdef QHULL_USES_QT
|
||||
template <typename T>
|
||||
QList<T> QhullSet<T>::
|
||||
toQList() const
|
||||
{
|
||||
typename QhullSet<T>::const_iterator i= begin();
|
||||
typename QhullSet<T>::const_iterator e= end();
|
||||
QList<T> vs;
|
||||
while(i!=e){
|
||||
vs.append(*i++);
|
||||
}
|
||||
return vs;
|
||||
}//toQList
|
||||
#endif
|
||||
|
||||
#//!\name Element
|
||||
|
||||
template <typename T>
|
||||
T QhullSet<T>::
|
||||
value(countT idx) const
|
||||
{
|
||||
// Avoid call to qh_setsize() and assert in elementPointer()
|
||||
const typename T::base_type *p= reinterpret_cast<const typename T::base_type *>(&SETelem_(getSetT(), idx));
|
||||
return (idx>=0 && p<endData()) ? T(qh(), *p) : T(qh());
|
||||
}//value
|
||||
|
||||
template <typename T>
|
||||
T QhullSet<T>::
|
||||
value(countT idx, const T &defaultValue) const
|
||||
{
|
||||
// Avoid call to qh_setsize() and assert in elementPointer()
|
||||
const typename T::base_type *p= reinterpret_cast<const typename T::base_type *>(&SETelem_(getSetT(), idx));
|
||||
return (idx>=0 && p<endData() ? T(qh(), *p) : defaultValue);
|
||||
}//value
|
||||
|
||||
#//!\name Search
|
||||
|
||||
template <typename T>
|
||||
bool QhullSet<T>::
|
||||
contains(const T &t) const
|
||||
{
|
||||
setT *s= getSetT();
|
||||
void *p= t.getBaseT(); // contains() is not inline for better error reporting
|
||||
int result= qh_setin(s, p);
|
||||
return result!=0;
|
||||
}//contains
|
||||
|
||||
template <typename T>
|
||||
countT QhullSet<T>::
|
||||
count(const T &t) const
|
||||
{
|
||||
countT n= 0;
|
||||
const typename T::base_type *i= data();
|
||||
const typename T::base_type *e= endData();
|
||||
typename T::base_type p= t.getBaseT();
|
||||
while(i<e){
|
||||
if(*i==p){
|
||||
n++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return n;
|
||||
}//count
|
||||
|
||||
template <typename T>
|
||||
countT QhullSet<T>::
|
||||
lastIndexOf(const T &t) const
|
||||
{
|
||||
const typename T::base_type *b= data();
|
||||
const typename T::base_type *i= endData();
|
||||
typename T::base_type p= t.getBaseT();
|
||||
while(--i>=b){
|
||||
if(*i==p){
|
||||
break;
|
||||
}
|
||||
}
|
||||
return static_cast<countT>(i-b); // WARN64
|
||||
}//lastIndexOf
|
||||
|
||||
#//!\name QhullSetIterator
|
||||
|
||||
template <typename T>
|
||||
bool QhullSetIterator<T>::
|
||||
findNext(const T &t)
|
||||
{
|
||||
typename T::base_type p= t.getBaseT();
|
||||
while(i!=end_i){
|
||||
if(*(++i)==p){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}//findNext
|
||||
|
||||
template <typename T>
|
||||
bool QhullSetIterator<T>::
|
||||
findPrevious(const T &t)
|
||||
{
|
||||
typename T::base_type p= t.getBaseT();
|
||||
while(i!=begin_i){
|
||||
if(*(--i)==p){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}//findPrevious
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
|
||||
#//!\name == Global namespace =========================================
|
||||
|
||||
template <typename T>
|
||||
std::ostream &
|
||||
operator<<(std::ostream &os, const orgQhull::QhullSet<T> &qs)
|
||||
{
|
||||
const typename T::base_type *i= qs.data();
|
||||
const typename T::base_type *e= qs.endData();
|
||||
while(i!=e){
|
||||
os << T(qs.qh(), *i++);
|
||||
}
|
||||
return os;
|
||||
}//operator<<
|
||||
|
||||
#endif // QhullSet_H
|
||||
@@ -0,0 +1,27 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/QhullSets.h#2 $$Change: 2953 $
|
||||
** $DateTime: 2020/05/21 22:05:32 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QHULLSETS_H
|
||||
#define QHULLSETS_H
|
||||
|
||||
#include "libqhullcpp/QhullSet.h"
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
//See: QhullFacetSet.h
|
||||
//See: QhullPointSet.h
|
||||
//See: QhullVertexSet.h
|
||||
|
||||
// Avoid circular references between QhullFacet, QhullRidge, and QhullVertex
|
||||
class QhullRidge;
|
||||
typedef QhullSet<QhullRidge> QhullRidgeSet;
|
||||
typedef QhullSetIterator<QhullRidge> QhullRidgeSetIterator;
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
#endif // QHULLSETS_H
|
||||
@@ -0,0 +1,42 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/QhullStat.cpp#2 $$Change: 2953 $
|
||||
** $DateTime: 2020/05/21 22:05:32 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#//! QhullStat -- Qhull's global data structure, statT, as a C++ class
|
||||
|
||||
#include "libqhullcpp/QhullStat.h"
|
||||
|
||||
#include "libqhullcpp/QhullError.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
using std::cerr;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using std::ostream;
|
||||
|
||||
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
|
||||
#endif
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
#//!\name Constructor, destructor, etc.
|
||||
|
||||
//! If qh_QHpointer==0, invoke with placement new on qh_stat;
|
||||
QhullStat::
|
||||
QhullStat()
|
||||
{
|
||||
}//QhullStat
|
||||
|
||||
QhullStat::
|
||||
~QhullStat()
|
||||
{
|
||||
}//~QhullStat
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/QhullStat.h#2 $$Change: 2953 $
|
||||
** $DateTime: 2020/05/21 22:05:32 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QHULLSTAT_H
|
||||
#define QHULLSTAT_H
|
||||
|
||||
#include "libqhull_r/qhull_ra.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
#//!\name defined here
|
||||
//! QhullStat -- Qhull's statistics, qhstatT, as a C++ class
|
||||
//! Statistics defined with zzdef_() control Qhull's behavior, summarize its result, and report precision problems.
|
||||
class QhullStat;
|
||||
|
||||
class QhullStat : public qhstatT {
|
||||
|
||||
private:
|
||||
#//!\name Fields (empty) -- POD type equivalent to qhstatT. No data or virtual members
|
||||
|
||||
public:
|
||||
#//!\name Constants
|
||||
|
||||
#//!\name class methods
|
||||
|
||||
#//!\name constructor, assignment, destructor, invariant
|
||||
QhullStat();
|
||||
~QhullStat();
|
||||
|
||||
private:
|
||||
//!disable copy constructor and assignment
|
||||
QhullStat(const QhullStat &);
|
||||
QhullStat & operator=(const QhullStat &);
|
||||
public:
|
||||
|
||||
#//!\name Access
|
||||
};//class QhullStat
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
#endif // QHULLSTAT_H
|
||||
@@ -0,0 +1,248 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/QhullUser.cpp#11 $$Change: 3396 $
|
||||
** $DateTime: 2023/01/02 16:59:48 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "libqhullcpp/QhullUser.h"
|
||||
|
||||
#include "libqhullcpp/QhullError.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <stdint.h>
|
||||
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using std::istream;
|
||||
using std::ostream;
|
||||
using std::ostringstream;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using std::ws;
|
||||
|
||||
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
|
||||
#pragma warning( disable : 4996) // function was declared deprecated(strcpy, localtime, etc.)
|
||||
#if _MSC_VER <= 1600
|
||||
#define snprintf sprintf_s
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace orgQhull{
|
||||
|
||||
#//! QhullUser -- user-defined interface to qhull via qh_fprintf
|
||||
|
||||
|
||||
#//!\name Constructors
|
||||
QhullUser::
|
||||
QhullUser(QhullQh *qqh)
|
||||
: qh_qh(qqh)
|
||||
, previous_user(NULL)
|
||||
, doubles_vector()
|
||||
, ints_vector()
|
||||
, fprintf_ints()
|
||||
, fprintf_doubles()
|
||||
, fprintf_codes()
|
||||
, fprintf_strings()
|
||||
, num_facets(0)
|
||||
, num_neighbors(0)
|
||||
, num_numbers(0)
|
||||
, num_points(0)
|
||||
, num_results(0)
|
||||
, num_ridges(0)
|
||||
, num_vectors(0)
|
||||
, num_vertices(0)
|
||||
, qhull_dim(0)
|
||||
, delaunay_dim(0)
|
||||
{
|
||||
previous_user= qh()->cpp_user;
|
||||
qh()->cpp_user= NULL;
|
||||
captureOn();
|
||||
}//constructor
|
||||
|
||||
QhullUser::
|
||||
~QhullUser()
|
||||
{
|
||||
captureOff();
|
||||
qh()->cpp_user= previous_user;
|
||||
}//destructor
|
||||
|
||||
#//!\name Get/Set
|
||||
|
||||
//! Clear working fields of QhullUser
|
||||
//! Retains qh_qh and previous_user as initialized
|
||||
//! Updates qhull_dim from qh_qh (does not change)
|
||||
//! Updates delaunay_dim if qh_qh.ISdelaunay
|
||||
void QhullUser::
|
||||
clear()
|
||||
{
|
||||
doubles_vector.clear();
|
||||
ints_vector.clear();
|
||||
fprintf_ints.clear();
|
||||
fprintf_doubles.clear();
|
||||
fprintf_codes.clear();
|
||||
fprintf_strings.clear();
|
||||
num_facets= 0;
|
||||
num_neighbors= 0;
|
||||
num_numbers= 0;
|
||||
num_points= 0;
|
||||
num_results= 0;
|
||||
num_ridges= 0;
|
||||
num_vectors= 0;
|
||||
num_vertices= 0;
|
||||
}//clear
|
||||
|
||||
#//!\name Methods
|
||||
|
||||
void QhullUser::
|
||||
captureOff()
|
||||
{
|
||||
if(qh()->cpp_user==NULL){
|
||||
throw QhullError(10080, "Qhull error: QhullUser::captureOn not call before QhullUser::captureOff for QhullUser 0x%llx", 0, 0, 0.0, this);
|
||||
}
|
||||
if(qh()->cpp_user!=this){
|
||||
throw QhullError(10081, "Qhull error: conflicting QhullUser (0x%llx) for QhullUser::captureOff(). Does not match 'this' (0x...%X)", int(0xffff&(intptr_t)this), 0, 0.0, qh()->cpp_user);
|
||||
}
|
||||
qh()->cpp_user= NULL;
|
||||
}//captureOff
|
||||
|
||||
void QhullUser::
|
||||
captureOn()
|
||||
{
|
||||
if(qh()->cpp_user){
|
||||
throw QhullError(10079, "Qhull error: conflicting user of cpp_user for QhullUser::captureOn() or corrupted qh_qh 0x%llx", 0, 0, 0.0, qh());
|
||||
}
|
||||
qh()->cpp_user= this;
|
||||
}//captureOn
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
#//!\name Global functions
|
||||
|
||||
/*-<a href="qh-user.htm#TOC"
|
||||
>-------------------------------</a><a name="qh_fprintf">-</a>
|
||||
|
||||
qh_fprintf(qh, fp, msgcode, format, list of args )
|
||||
replacement for qh_fprintf in userprintf_r.c, which replaces fprintf for Qhull
|
||||
qh.ISqhullQh must be true, indicating that qh a subclass of QhullQh
|
||||
qh.cpp_user is an optional QhullUser for trapped MSG_OUTPUT calls
|
||||
fp may be NULL
|
||||
otherwise behaves the same as qh_fprintf in userprintf_r.c
|
||||
|
||||
returns:
|
||||
sets qhullQh->qhull_status if msgcode is error 6000..6999
|
||||
....sets qh.last_errcode if error reported
|
||||
....if qh.cpp_user defined, records results of 'qhull v Fi Fo'
|
||||
See "qvoronoi-fifo" in user_eg3_r.cpp for an example
|
||||
|
||||
|
||||
notes:
|
||||
Only called from libqhull_r
|
||||
A similar technique is used by RboxPoints and qh_fprintf_rbox
|
||||
Do not throw errors from here. Use qh_errexit;
|
||||
fgets() is not trapped like fprintf(), QH11008 FIX: how do users handle input? A callback?
|
||||
*/
|
||||
extern "C"
|
||||
|
||||
//! Custom qh_fprintf for transferring Qhull output from io_r.c to QhullUser and QhullQh
|
||||
//! Identify msgcodes with Qhull option 'Ta'
|
||||
//! A similar technique is used by RboxPoints with a custom qh_fprintf_rbox
|
||||
void qh_fprintf(qhT *qh, FILE* fp, int msgcode, const char *fmt, ... ){
|
||||
va_list args;
|
||||
int last_errcode;
|
||||
|
||||
using namespace orgQhull;
|
||||
|
||||
if(qh==NULL || !qh->ISqhullQh){
|
||||
qh_fprintf_stderr(10025, "Qhull error: qh_fprintf in QhullUser.cpp called from a Qhull instance without QhullQh defined\n");
|
||||
last_errcode= 10025;
|
||||
qh_exit(last_errcode);
|
||||
}
|
||||
va_start(args, fmt);
|
||||
if(msgcode>=MSG_OUTPUT && qh->cpp_user){
|
||||
QhullUser *out= reinterpret_cast<QhullUser *>(qh->cpp_user);
|
||||
bool isOut= false;
|
||||
switch (msgcode){
|
||||
case 9231: /* printvdiagram, totcount (ignored) */
|
||||
out->setNumResults(va_arg(args, int));
|
||||
isOut= true;
|
||||
break;
|
||||
case 9271: /* qh_printvnorm, count, pointId, pointId, hyperplane */
|
||||
out->appendInt(va_arg(args, int));
|
||||
out->appendInt(va_arg(args, int));
|
||||
out->appendInt(va_arg(args, int));
|
||||
out->appendAndClearInts();
|
||||
isOut= true;
|
||||
break;
|
||||
case 9272:
|
||||
case 9273:
|
||||
out->appendDouble(va_arg(args, double));
|
||||
isOut= true;
|
||||
break;
|
||||
case 9274:
|
||||
out->appendAndClearDoubles();
|
||||
isOut= true;
|
||||
break;
|
||||
default:
|
||||
// do nothing
|
||||
break;
|
||||
}
|
||||
if(isOut){
|
||||
out->appendCode(msgcode);
|
||||
va_end(args);
|
||||
return;
|
||||
}
|
||||
}/*MSG_OUTPUT, cpp_user*/
|
||||
|
||||
QhullQh *qhullQh= static_cast<QhullQh *>(qh);
|
||||
char newMessage[MSG_MAXLEN];
|
||||
int msgLen= 0;
|
||||
if((qh && qh->ANNOTATEoutput) || msgcode < MSG_TRACE4){
|
||||
msgLen= snprintf(newMessage, sizeof(newMessage), "[QH%.4d]", msgcode);
|
||||
}else if(msgcode>=MSG_ERROR && msgcode < MSG_STDERR){
|
||||
msgLen= snprintf(newMessage, sizeof(newMessage), "QH%.4d ", msgcode);
|
||||
}
|
||||
if(msgLen>=0 && msgLen < (int)sizeof(newMessage)){
|
||||
vsnprintf(newMessage + msgLen, sizeof(newMessage) - msgLen, fmt, args);
|
||||
}
|
||||
if(msgcode < MSG_OUTPUT || fp == qh_FILEstderr){
|
||||
if(msgcode>=MSG_ERROR && msgcode < MSG_WARNING){
|
||||
qh->last_errcode= msgcode;
|
||||
if(qhullQh->qhull_status < MSG_ERROR || qhullQh->qhull_status>=MSG_WARNING){
|
||||
qhullQh->qhull_status= msgcode;
|
||||
}
|
||||
}
|
||||
qhullQh->appendQhullMessage(newMessage);
|
||||
}else if(qhullQh->output_stream && qhullQh->use_output_stream){
|
||||
*qhullQh->output_stream << newMessage;
|
||||
if(qh->FLUSHprint){
|
||||
qhullQh->output_stream->flush();
|
||||
}
|
||||
}else{
|
||||
qhullQh->appendQhullMessage(newMessage);
|
||||
}
|
||||
va_end(args);
|
||||
|
||||
/* Place debugging traps here. Use with trace option 'Tn'
|
||||
Set qh.tracefacet_id, qh.traceridge_id, and/or qh.tracevertex_id in global_r.c
|
||||
*/
|
||||
if(False){ /* in production skip test for debugging traps */
|
||||
facetT *neighbor, **neighborp;
|
||||
if(qh->tracefacet && qh->tracefacet->tested){
|
||||
if(qh_setsize(qh, qh->tracefacet->neighbors) < qh->hull_dim)
|
||||
qh_errexit(qh, qh_ERRdebug, qh->tracefacet, qh->traceridge);
|
||||
FOREACHneighbor_(qh->tracefacet){
|
||||
if(neighbor != qh_DUPLICATEridge && neighbor != qh_MERGEridge && neighbor->visible)
|
||||
qh_errexit2(qh, qh_ERRdebug, qh->tracefacet, neighbor);
|
||||
}
|
||||
}
|
||||
if(qh->traceridge && qh->traceridge->top->id == 234342223){
|
||||
qh_errexit(qh, qh_ERRdebug, qh->tracefacet, qh->traceridge);
|
||||
}
|
||||
if(qh->tracevertex && qh_setsize(qh, qh->tracevertex->neighbors) > 3434334){
|
||||
qh_errexit(qh, qh_ERRdebug, qh->tracefacet, qh->traceridge);
|
||||
}
|
||||
}
|
||||
} /* qh_fprintf */
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/QhullUser.h#7 $$Change: 3010 $
|
||||
** $DateTime: 2020/07/30 22:14:11 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QhullUser_H
|
||||
#define QhullUser_H
|
||||
|
||||
#include "libqhull_r/qhull_ra.h"
|
||||
#include "libqhullcpp/QhullPoint.h"
|
||||
#include "libqhullcpp/PointCoordinates.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <istream>
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
|
||||
namespace orgQhull{
|
||||
|
||||
#//!\name Defined here
|
||||
//! QhullUser -- custom C++ interfaces into Qhull (via qh_fprintf)
|
||||
class QhullUser;
|
||||
// qh_fprintf is defined below. It replaces libqhull_r/userprintf_r.c
|
||||
|
||||
#//!\name Used here
|
||||
class QhullQh;
|
||||
|
||||
class QhullUser{
|
||||
|
||||
private:
|
||||
#//!\name Fields
|
||||
QhullQh * qh_qh; //!< QhullQh/qhT for access to libqhull_r
|
||||
void * previous_user; //!< previous qh.cpp_user, restored on deconstruction
|
||||
std::vector<std::vector<double> > doubles_vector; //! vectors for capturing ints and doubles
|
||||
std::vector<std::vector<int> > ints_vector;
|
||||
std::vector<int> fprintf_ints;
|
||||
std::vector<double> fprintf_doubles;
|
||||
std::vector<int> fprintf_codes;
|
||||
std::vector<std::string> fprintf_strings;
|
||||
int num_facets;
|
||||
int num_neighbors;
|
||||
int num_numbers;
|
||||
int num_points;
|
||||
int num_results;
|
||||
int num_ridges;
|
||||
int num_vectors;
|
||||
int num_vertices;
|
||||
int qhull_dim;
|
||||
int delaunay_dim; //! ints for capturing fprintf fields
|
||||
|
||||
public:
|
||||
#//!\name Construct
|
||||
QhullUser(QhullQh *qqh);
|
||||
~QhullUser();
|
||||
private: // Disable default constructor, copy constructor, and assignment
|
||||
QhullUser();
|
||||
QhullUser(const QhullUser &);
|
||||
QhullUser & operator=(const QhullUser &);
|
||||
private:
|
||||
|
||||
public:
|
||||
#//!\name GetSet
|
||||
void appendCode(int msgCode) { fprintf_codes.push_back(msgCode); }
|
||||
void appendDouble(double a) { fprintf_doubles.push_back(a); }
|
||||
void appendInt(int i) { fprintf_ints.push_back(i); }
|
||||
void appendAndClearDoubles() { doubles_vector.push_back(fprintf_doubles); fprintf_doubles.clear(); }
|
||||
void appendAndClearInts() { ints_vector.push_back(fprintf_ints); fprintf_ints.clear(); }
|
||||
void clear();
|
||||
void clearDoubles() { fprintf_doubles.clear(); }
|
||||
void clearDoublesVector() { doubles_vector.clear(); }
|
||||
void clearInts() { fprintf_ints.clear(); }
|
||||
void clearIntsVector() { ints_vector.clear(); }
|
||||
const std::vector<int> &codes() const { return fprintf_codes; }
|
||||
int delaunayDim() const { return delaunay_dim; }
|
||||
const std::vector<std::vector<double> > &doublesVector() const { return doubles_vector; }
|
||||
const std::vector<double> &doubles() const { return fprintf_doubles; }
|
||||
int firstCode() const { return (fprintf_codes.size() == 0 ? -1 : fprintf_codes[0]); }
|
||||
const std::vector<int> &ints() const { return fprintf_ints; }
|
||||
const std::vector<std::vector<int> > &intsVector() const { return ints_vector; }
|
||||
int numDoubles() const { return (int)doubles_vector.size(); }
|
||||
int numFacets() const { return num_facets; }
|
||||
int numInts() const { return (int)ints_vector.size(); }
|
||||
int numNeighbors() const { return num_neighbors; }
|
||||
int numNumbers() const { return num_numbers; }
|
||||
int numPoints() const { return num_points; }
|
||||
int numResults() const { return num_results; }
|
||||
int numRidges() const { return num_ridges; }
|
||||
int numVectors() const { return num_vectors; }
|
||||
int numVertices() const { return num_vertices; }
|
||||
QhullQh * qh() const { return qh_qh; }
|
||||
int qhullDim() const { return qhull_dim; }
|
||||
void setDelaunayDim(int i) { delaunay_dim= i; }
|
||||
void setNumFacets(int i) { num_facets= i; }
|
||||
void setNumResults(int i) { num_results= i; }
|
||||
void setNumRidges(int i) { num_ridges= i; }
|
||||
void setNumNeighbors(int i) { num_neighbors= i; }
|
||||
void setNumNumbers(int i) { num_numbers= i; }
|
||||
void setNumPoints(int i) { num_points= i; }
|
||||
void setNumVectors(int i) { num_vectors= i; }
|
||||
void setNumVertices(int i) { num_vertices= i; }
|
||||
void setQhullDim(int i) { qhull_dim= i; }
|
||||
|
||||
#//!\name Methods
|
||||
void captureOn();
|
||||
void captureOff();
|
||||
};//class QhullUser
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
#endif // QhullUser_H
|
||||
@@ -0,0 +1,126 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/QhullVertex.cpp#4 $$Change: 3001 $
|
||||
** $DateTime: 2020/07/24 20:43:28 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#//! QhullVertex -- Qhull's vertex structure, vertexT, as a C++ class
|
||||
|
||||
#include "libqhullcpp/QhullVertex.h"
|
||||
|
||||
#include "libqhullcpp/Qhull.h"
|
||||
#include "libqhullcpp/QhullPoint.h"
|
||||
#include "libqhullcpp/QhullFacetSet.h"
|
||||
#include "libqhullcpp/QhullFacet.h"
|
||||
|
||||
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
|
||||
#pragma warning( disable : 4611) // interaction between '_setjmp' and C++ object destruction is non-portable
|
||||
#pragma warning( disable : 4996) // function was declared deprecated(strcpy, localtime, etc.)
|
||||
#endif
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
#//!\name Class objects
|
||||
vertexT QhullVertex::
|
||||
s_empty_vertex= {NULL,NULL,NULL,NULL,0,0, // must match vertexT -Wmissing-field-initializers
|
||||
false,false,false,false,false,false};
|
||||
|
||||
#//!\name Constructors
|
||||
|
||||
QhullVertex::QhullVertex(const Qhull &q)
|
||||
: qh_vertex(&s_empty_vertex)
|
||||
, qh_qh(q.qh())
|
||||
{
|
||||
}//Default
|
||||
|
||||
QhullVertex::QhullVertex(const Qhull &q, vertexT *v)
|
||||
: qh_vertex(v ? v : &s_empty_vertex)
|
||||
, qh_qh(q.qh())
|
||||
{
|
||||
}//vertexT
|
||||
|
||||
QhullVertex::QhullVertex(const QhullVertex &other)
|
||||
: qh_vertex(other.qh_vertex)
|
||||
, qh_qh(other.qh_qh)
|
||||
{
|
||||
}//copy constructor
|
||||
|
||||
#//!\name foreach
|
||||
|
||||
//! Return neighboring facets for a vertex
|
||||
//! If neither merging nor Voronoi diagram, requires Qhull::defineVertexNeighborFacets() beforehand.
|
||||
QhullFacetSet QhullVertex::
|
||||
neighborFacets() const
|
||||
{
|
||||
if(!neighborFacetsDefined()){
|
||||
throw QhullError(10034, "Qhull error: neighboring facets of vertex %d not defined. Please call Qhull::defineVertexNeighborFacets() beforehand.", id());
|
||||
}
|
||||
return QhullFacetSet(qh_qh, qh_vertex->neighbors);
|
||||
}//neighborFacets
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
#//!\name Global functions
|
||||
|
||||
using std::endl;
|
||||
using std::ostream;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using orgQhull::QhullPoint;
|
||||
using orgQhull::QhullFacet;
|
||||
using orgQhull::QhullFacetSet;
|
||||
using orgQhull::QhullFacetSetIterator;
|
||||
using orgQhull::QhullVertex;
|
||||
|
||||
//! Duplicate of qh_printvertex [io_r.c]
|
||||
ostream &
|
||||
operator<<(ostream &os, const QhullVertex::PrintVertex &pr)
|
||||
{
|
||||
QhullVertex v= *pr.vertex;
|
||||
QhullPoint p= v.point();
|
||||
if(*pr.print_message){
|
||||
os << pr.print_message << " ";
|
||||
}else{
|
||||
os << "- ";
|
||||
}
|
||||
os << "p" << p.id() << " (v" << v.id() << "): ";
|
||||
const realT *c= p.coordinates();
|
||||
for(int k= p.dimension(); k--; ){
|
||||
os << " " << *c++; // QH11010 FIX: %5.2g
|
||||
}
|
||||
if(v.getVertexT()->deleted){
|
||||
os << " deleted";
|
||||
}
|
||||
if(v.getVertexT()->delridge){
|
||||
os << " delridge";
|
||||
}
|
||||
if(v.getVertexT()->newfacet){
|
||||
os << " newfacet";
|
||||
}
|
||||
if(v.getVertexT()->seen && v.qh()->IStracing){
|
||||
os << " seen";
|
||||
}
|
||||
if(v.getVertexT()->seen2 && v.qh()->IStracing){
|
||||
os << " seen2";
|
||||
}
|
||||
os << endl;
|
||||
if(v.neighborFacetsDefined()){
|
||||
QhullFacetSetIterator i= v.neighborFacets();
|
||||
if(i.hasNext()){
|
||||
os << " neighborFacets:";
|
||||
countT count= 0;
|
||||
while(i.hasNext()){
|
||||
if(++count % 100 == 0){
|
||||
os << endl << " ";
|
||||
}
|
||||
QhullFacet f= i.next();
|
||||
os << " f" << f.id();
|
||||
}
|
||||
os << endl;
|
||||
}
|
||||
}
|
||||
return os;
|
||||
}//<< PrintVertex
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/QhullVertex.h#4 $$Change: 3001 $
|
||||
** $DateTime: 2020/07/24 20:43:28 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QHULLVERTEX_H
|
||||
#define QHULLVERTEX_H
|
||||
|
||||
#include "libqhull_r/qhull_ra.h"
|
||||
#include "libqhullcpp/QhullPoint.h"
|
||||
#include "libqhullcpp/QhullLinkedList.h"
|
||||
#include "libqhullcpp/QhullSet.h"
|
||||
|
||||
#include <ostream>
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
#//!\name Used here
|
||||
class QhullFacetSet;
|
||||
|
||||
#//!\name Defined here
|
||||
//! QhullVertex -- Qhull's vertex structure, vertexT [libqhull_r.h], as a C++ class
|
||||
class QhullVertex;
|
||||
typedef QhullLinkedList<QhullVertex> QhullVertexList;
|
||||
typedef QhullLinkedListIterator<QhullVertex> QhullVertexListIterator;
|
||||
|
||||
|
||||
/*********************
|
||||
topological information:
|
||||
next,previous doubly-linked list of all vertices
|
||||
neighborFacets set of adjacent facets (only if qh.VERTEXneighbors)
|
||||
|
||||
geometric information:
|
||||
point array of DIM coordinates
|
||||
*/
|
||||
|
||||
class QhullVertex {
|
||||
|
||||
#//!\name Defined here
|
||||
public:
|
||||
typedef vertexT * base_type; // for QhullVertexSet
|
||||
|
||||
private:
|
||||
#//!\name Fields
|
||||
vertexT * qh_vertex; //!< Corresponding vertexT, never 0
|
||||
QhullQh * qh_qh; //!< QhullQh/qhT for vertexT, may be 0
|
||||
|
||||
#//!\name Class objects
|
||||
static vertexT s_empty_vertex; // needed for shallow copy
|
||||
|
||||
public:
|
||||
#//!\name Constants
|
||||
|
||||
#//!\name Constructors
|
||||
QhullVertex() : qh_vertex(&s_empty_vertex), qh_qh(0) {}
|
||||
explicit QhullVertex(const Qhull &q);
|
||||
QhullVertex(const Qhull &q, vertexT *v);
|
||||
explicit QhullVertex(QhullQh *qqh) : qh_vertex(&s_empty_vertex), qh_qh(qqh) {}
|
||||
QhullVertex(QhullQh *qqh, vertexT *v) : qh_vertex(v ? v : &s_empty_vertex), qh_qh(qqh) {}
|
||||
// Creates an alias. Does not copy QhullVertex. Needed for return by value and parameter passing
|
||||
QhullVertex(const QhullVertex &other);
|
||||
// Creates an alias. Does not copy QhullVertex. Needed for vector<QhullVertex>
|
||||
QhullVertex & operator=(const QhullVertex &other) { qh_vertex= other.qh_vertex; qh_qh= other.qh_qh; return *this; }
|
||||
~QhullVertex() {}
|
||||
|
||||
#//!\name GetSet
|
||||
int dimension() const { return (qh_qh ? qh_qh->hull_dim : 0); }
|
||||
vertexT * getBaseT() const { return getVertexT(); } //!< For QhullSet<QhullVertex>
|
||||
vertexT * getVertexT() const { return qh_vertex; }
|
||||
bool hasNext() const { return (qh_vertex->next != NULL && qh_vertex->next != qh_qh->vertex_tail); }
|
||||
bool hasPrevious() const { return (qh_vertex->previous != NULL); }
|
||||
countT id() const { return qh_vertex->id; }
|
||||
bool isValid() const { return (qh_qh && qh_vertex != &s_empty_vertex); }
|
||||
//! True if defineVertexNeighborFacets() already called. Auotomatically set for facet merging, Voronoi diagrams
|
||||
bool neighborFacetsDefined() const { return qh_vertex->neighbors != 0; }
|
||||
QhullVertex next() const { return QhullVertex(qh_qh, qh_vertex->next); }
|
||||
bool operator==(const QhullVertex &other) const { return qh_vertex==other.qh_vertex; }
|
||||
bool operator!=(const QhullVertex &other) const { return !operator==(other); }
|
||||
QhullPoint point() const { return QhullPoint(qh_qh, qh_vertex->point); }
|
||||
QhullVertex previous() const { return QhullVertex(qh_qh, qh_vertex->previous); }
|
||||
QhullQh * qh() const { return qh_qh; }
|
||||
void setVertexT(QhullQh *qqh, vertexT *vertex) { qh_qh= qqh; qh_vertex= vertex; }
|
||||
|
||||
#//!\name foreach
|
||||
//See also QhullVertexList
|
||||
QhullFacetSet neighborFacets() const;
|
||||
|
||||
#//!\name IO
|
||||
struct PrintVertex{
|
||||
const QhullVertex *vertex;
|
||||
const char * print_message; //!< non-null message
|
||||
PrintVertex(const char *message, const QhullVertex &v) : vertex(&v), print_message(message) {}
|
||||
};//PrintVertex
|
||||
PrintVertex print(const char *message) const { return PrintVertex(message, *this); }
|
||||
};//class QhullVertex
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
#//!\name GLobal
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullVertex::PrintVertex &pr);
|
||||
inline std::ostream &operator<<(std::ostream &os, const orgQhull::QhullVertex &v) { os << v.print(""); return os; }
|
||||
|
||||
#endif // QHULLVERTEX_H
|
||||
@@ -0,0 +1,162 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2009-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/QhullVertexSet.cpp#4 $$Change: 3396 $
|
||||
** $DateTime: 2023/01/02 16:59:48 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#//! QhullVertexSet -- Qhull's linked Vertexs, as a C++ class
|
||||
|
||||
#include "libqhullcpp/QhullVertexSet.h"
|
||||
|
||||
#include "libqhullcpp/QhullVertex.h"
|
||||
#include "libqhullcpp/QhullPoint.h"
|
||||
#include "libqhullcpp/QhullRidge.h"
|
||||
#include "libqhullcpp/QhullVertex.h"
|
||||
#include "libqhullcpp/Qhull.h"
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
|
||||
#pragma warning( disable : 4611) /* interaction between '_setjmp' and C++ object destruction is non-portable */
|
||||
/* setjmp should not be implemented with 'catch' */
|
||||
#endif
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
QhullVertexSet::
|
||||
QhullVertexSet(const Qhull &q, facetT *facetlist, setT *facetset, bool allfacets)
|
||||
: QhullSet<QhullVertex>(q.qh(), 0)
|
||||
, qhsettemp_defined(false)
|
||||
{
|
||||
QH_TRY_(q.qh()){ // no object creation -- destructors skipped on longjmp()
|
||||
setT *vertices= qh_facetvertices(q.qh(), facetlist, facetset, allfacets);
|
||||
defineAs(vertices);
|
||||
qhsettemp_defined= true;
|
||||
}
|
||||
q.qh()->NOerrexit= true;
|
||||
q.qh()->maybeThrowQhullMessage(QH_TRY_status);
|
||||
}//QhullVertexSet facetlist facetset
|
||||
|
||||
//! Return temporary QhullVertexSet of vertices for a list and/or a set of facets
|
||||
//! Sets qhsettemp_defined (disallows copy constructor and assignment to prevent double-free)
|
||||
QhullVertexSet::
|
||||
QhullVertexSet(QhullQh *qqh, facetT *facetlist, setT *facetset, bool allfacets)
|
||||
: QhullSet<QhullVertex>(qqh, 0)
|
||||
, qhsettemp_defined(false)
|
||||
{
|
||||
QH_TRY_(qh()){ // no object creation -- destructors skipped on longjmp()
|
||||
setT *vertices= qh_facetvertices(qh(), facetlist, facetset, allfacets);
|
||||
defineAs(vertices);
|
||||
qhsettemp_defined= true;
|
||||
}
|
||||
qh()->NOerrexit= true;
|
||||
qh()->maybeThrowQhullMessage(QH_TRY_status);
|
||||
}//QhullVertexSet facetlist facetset
|
||||
|
||||
//! Copy constructor for argument passing and returning a result
|
||||
//! Only copies a pointer to the set.
|
||||
//! Throws an error if qhsettemp_defined, otherwise have a double-free
|
||||
//!\todo Convert QhullVertexSet to a shared pointer with reference counting
|
||||
QhullVertexSet::
|
||||
QhullVertexSet(const QhullVertexSet &other)
|
||||
: QhullSet<QhullVertex>(other)
|
||||
, qhsettemp_defined(false)
|
||||
{
|
||||
if(other.qhsettemp_defined){
|
||||
throw QhullError(10077, "QhullVertexSet: Cannot use copy constructor since qhsettemp_defined (e.g., QhullVertexSet for a set and/or list of QhFacet). Contains %d vertices", other.count());
|
||||
}
|
||||
}//copy constructor
|
||||
|
||||
//! Copy assignment only copies a pointer to the set.
|
||||
//! Throws an error if qhsettemp_defined, otherwise have a double-free
|
||||
QhullVertexSet & QhullVertexSet::
|
||||
operator=(const QhullVertexSet &other)
|
||||
{
|
||||
QhullSet<QhullVertex>::operator=(other);
|
||||
qhsettemp_defined= false;
|
||||
if(other.qhsettemp_defined){
|
||||
throw QhullError(10078, "QhullVertexSet: Cannot use copy constructor since qhsettemp_defined (e.g., QhullVertexSet for a set and/or list of QhFacet). Contains %d vertices", other.count());
|
||||
}
|
||||
return *this;
|
||||
}//assignment
|
||||
|
||||
void QhullVertexSet::
|
||||
freeQhSetTemp()
|
||||
{
|
||||
if(qhsettemp_defined){
|
||||
qhsettemp_defined= false;
|
||||
QH_TRY_(qh()){ // no object creation -- destructors skipped on longjmp()
|
||||
qh_settempfree(qh(), referenceSetT()); // errors if not top of tempstack or if qhmem corrupted
|
||||
}
|
||||
qh()->NOerrexit= true;
|
||||
qh()->maybeThrowQhullMessage(QH_TRY_status, QhullError::NOthrow);
|
||||
}
|
||||
}//freeQhSetTemp
|
||||
|
||||
QhullVertexSet::
|
||||
~QhullVertexSet()
|
||||
{
|
||||
freeQhSetTemp();
|
||||
}//~QhullVertexSet
|
||||
|
||||
#ifndef QHULL_NO_STL
|
||||
std::vector<QhullVertex> QhullVertexSet::
|
||||
toStdVector() const
|
||||
{
|
||||
QhullSetIterator<QhullVertex> i(*this);
|
||||
std::vector<QhullVertex> vs;
|
||||
while(i.hasNext()){
|
||||
QhullVertex v= i.next();
|
||||
vs.push_back(v);
|
||||
}
|
||||
return vs;
|
||||
}//toStdVector
|
||||
#endif //QHULL_NO_STL
|
||||
|
||||
#//!\name Class functions
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
#//!\name Global functions
|
||||
|
||||
using std::endl;
|
||||
using std::ostream;
|
||||
using orgQhull::QhullPoint;
|
||||
using orgQhull::QhullVertex;
|
||||
using orgQhull::QhullVertexSet;
|
||||
using orgQhull::QhullVertexSetIterator;
|
||||
|
||||
//! Print Vertex identifiers to stream. Space prefix. From qh_printVertexheader [io_r.c]
|
||||
ostream &
|
||||
operator<<(ostream &os, const QhullVertexSet::PrintIdentifiers &pr)
|
||||
{
|
||||
os << pr.print_message;
|
||||
for(QhullVertexSet::const_iterator i= pr.vertex_set->begin(); i!=pr.vertex_set->end(); ++i){
|
||||
const QhullVertex v= *i;
|
||||
os << " v" << v.id();
|
||||
}
|
||||
os << endl;
|
||||
return os;
|
||||
}//<<QhullVertexSet::PrintIdentifiers
|
||||
|
||||
//! Duplicate of printvertices [io_r.c]
|
||||
ostream &
|
||||
operator<<(ostream &os, const QhullVertexSet::PrintVertexSet &pr){
|
||||
|
||||
os << pr.print_message;
|
||||
const QhullVertexSet *vs= pr.vertex_set;
|
||||
QhullVertexSetIterator i= *vs;
|
||||
while(i.hasNext()){
|
||||
const QhullVertex v= i.next();
|
||||
const QhullPoint p= v.point();
|
||||
os << " p" << p.id() << "(v" << v.id() << ")";
|
||||
}
|
||||
os << endl;
|
||||
|
||||
return os;
|
||||
}//<< PrintVertexSet
|
||||
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2009-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/QhullVertexSet.h#4 $$Change: 3001 $
|
||||
** $DateTime: 2020/07/24 20:43:28 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QHULLVERTEXSET_H
|
||||
#define QHULLVERTEXSET_H
|
||||
|
||||
#include "libqhullcpp/QhullFacetList.h"
|
||||
#include "libqhullcpp/QhullSet.h"
|
||||
#include "libqhullcpp/QhullVertex.h"
|
||||
|
||||
#include <ostream>
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
#//!\name Used here
|
||||
|
||||
#//!\name Defined here
|
||||
//! QhullVertexSet -- a set of QhullVertex, as a C++ class.
|
||||
//! See Qhull
|
||||
class QhullVertexSet;
|
||||
|
||||
//! QhullVertexSetIterator is a Java-style iterator for QhullVertex in a QhullVertexSet
|
||||
//! QhullVertexSetIterator may be used on temporary results. It copies the pointers in QhullVertexSet
|
||||
typedef QhullSetIterator<QhullVertex> QhullVertexSetIterator;
|
||||
|
||||
class QhullVertexSet : public QhullSet<QhullVertex> {
|
||||
|
||||
private:
|
||||
#//!\name Fields
|
||||
bool qhsettemp_defined; //! Set was allocated with qh_settemp()
|
||||
|
||||
public:
|
||||
#//!\name Constructor
|
||||
QhullVertexSet(const Qhull &q, setT *s) : QhullSet<QhullVertex>(q, s), qhsettemp_defined(false) {}
|
||||
QhullVertexSet(const Qhull &q, facetT *facetlist, setT *facetset, bool allfacets);
|
||||
//Conversion from setT* is not type-safe. Implicit conversion for void* to T
|
||||
QhullVertexSet(QhullQh *qqh, setT *s) : QhullSet<QhullVertex>(qqh, s), qhsettemp_defined(false) {}
|
||||
QhullVertexSet(QhullQh *qqh, facetT *facetlist, setT *facetset, bool allfacets);
|
||||
//Copy constructor and assignment copies pointer but not contents. Throws error if qhsettemp_defined. Needed for return by value.
|
||||
QhullVertexSet(const QhullVertexSet &other);
|
||||
QhullVertexSet & operator=(const QhullVertexSet &other);
|
||||
~QhullVertexSet();
|
||||
|
||||
private: //!Default constructor disabled. Will implement allocation later
|
||||
QhullVertexSet();
|
||||
public:
|
||||
|
||||
#//!\name Destructor
|
||||
void freeQhSetTemp();
|
||||
|
||||
#//!\name Conversion
|
||||
#ifndef QHULL_NO_STL
|
||||
std::vector<QhullVertex> toStdVector() const;
|
||||
#endif //QHULL_NO_STL
|
||||
#ifdef QHULL_USES_QT
|
||||
QList<QhullVertex> toQList() const;
|
||||
#endif //QHULL_USES_QT
|
||||
|
||||
#//!\name Methods
|
||||
|
||||
#//!\name IO
|
||||
struct PrintVertexSet{
|
||||
const QhullVertexSet *vertex_set;
|
||||
const char * print_message; //!< non-null message
|
||||
|
||||
PrintVertexSet(const char *message, const QhullVertexSet *s) : vertex_set(s), print_message(message) {}
|
||||
};//PrintVertexSet
|
||||
const PrintVertexSet print(const char *message) const { return PrintVertexSet(message, this); }
|
||||
|
||||
struct PrintIdentifiers{
|
||||
const QhullVertexSet *vertex_set;
|
||||
const char * print_message; //!< non-null message
|
||||
PrintIdentifiers(const char *message, const QhullVertexSet *s) : vertex_set(s), print_message(message) {}
|
||||
};//PrintIdentifiers
|
||||
PrintIdentifiers printIdentifiers(const char *message) const { return PrintIdentifiers(message, this); }
|
||||
|
||||
};//class QhullVertexSet
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
#//!\name Global
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullVertexSet::PrintVertexSet &pr);
|
||||
std::ostream &operator<<(std::ostream &os, const orgQhull::QhullVertexSet::PrintIdentifiers &p);
|
||||
inline std::ostream &operator<<(std::ostream &os, const orgQhull::QhullVertexSet &vs) { os << vs.print(""); return os; }
|
||||
|
||||
#endif // QHULLVERTEXSET_H
|
||||
@@ -0,0 +1,249 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/RboxPoints.cpp#8 $$Change: 2965 $
|
||||
** $DateTime: 2020/06/04 15:37:41 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "libqhullcpp/RboxPoints.h"
|
||||
|
||||
#include "libqhullcpp/QhullError.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using std::istream;
|
||||
using std::ostream;
|
||||
using std::ostringstream;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using std::ws;
|
||||
|
||||
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
|
||||
#pragma warning( disable : 4996) // function was declared deprecated(strcpy, localtime, etc.)
|
||||
#endif
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
#//! RboxPoints -- generate random PointCoordinates for qhull (rbox)
|
||||
|
||||
|
||||
#//!\name Constructors
|
||||
RboxPoints::
|
||||
RboxPoints()
|
||||
: PointCoordinates("rbox")
|
||||
, rbox_new_count(0)
|
||||
, rbox_status(qh_ERRnone)
|
||||
, rbox_message()
|
||||
{
|
||||
allocateQhullQh();
|
||||
}
|
||||
|
||||
//! Allocate and generate points according to rboxCommand
|
||||
//! For rbox commands, see http://www.qhull.org/html/rbox.htm or html/rbox.htm
|
||||
//! Same as appendPoints()
|
||||
RboxPoints::
|
||||
RboxPoints(const char *rboxCommand)
|
||||
: PointCoordinates("rbox")
|
||||
, rbox_new_count(0)
|
||||
, rbox_status(qh_ERRnone)
|
||||
, rbox_message()
|
||||
{
|
||||
allocateQhullQh();
|
||||
// rbox arguments added to comment() via qh_rboxpoints > qh_fprintf_rbox
|
||||
appendPoints(rboxCommand);
|
||||
}
|
||||
|
||||
RboxPoints::
|
||||
~RboxPoints()
|
||||
{
|
||||
delete qh();
|
||||
resetQhullQh(0);
|
||||
}
|
||||
|
||||
// RboxPoints and qh_rboxpoints has several fields in qhT (rbox_errexit..cpp_object)
|
||||
// It shares last_random with qh_rand and qh_srand
|
||||
// The other fields are unused
|
||||
void RboxPoints::
|
||||
allocateQhullQh()
|
||||
{
|
||||
QHULL_LIB_CHECK /* Check for compatible library */
|
||||
resetQhullQh(new QhullQh);
|
||||
}//allocateQhullQh
|
||||
|
||||
#//!\name Messaging
|
||||
|
||||
void RboxPoints::
|
||||
clearRboxMessage()
|
||||
{
|
||||
rbox_status= qh_ERRnone;
|
||||
rbox_message.clear();
|
||||
}//clearRboxMessage
|
||||
|
||||
std::string RboxPoints::
|
||||
rboxMessage() const
|
||||
{
|
||||
if(rbox_status!=qh_ERRnone){
|
||||
return rbox_message;
|
||||
}
|
||||
if(isEmpty()){
|
||||
return "rbox warning: no points generated\n";
|
||||
}
|
||||
return "rbox: OK\n";
|
||||
}//rboxMessage
|
||||
|
||||
int RboxPoints::
|
||||
rboxStatus() const
|
||||
{
|
||||
return rbox_status;
|
||||
}
|
||||
|
||||
bool RboxPoints::
|
||||
hasRboxMessage() const
|
||||
{
|
||||
return (rbox_status!=qh_ERRnone);
|
||||
}
|
||||
|
||||
#//!\name Methods
|
||||
|
||||
//! Appends points as defined by rboxCommand
|
||||
//! If dimension previously defined, adds " Ddim" to rboxCommand
|
||||
//! Appends rboxCommand to comment
|
||||
//! For rbox commands, see http://www.qhull.org/html/rbox.htm or html/rbox.htm
|
||||
void RboxPoints::
|
||||
appendPoints(const char *rboxCommand)
|
||||
{
|
||||
string s("rbox ");
|
||||
int dim= dimension(); // QhullPoints
|
||||
s += rboxCommand;
|
||||
if(dim==0){
|
||||
if(*rboxCommand=='D'){
|
||||
char *endDim= NULL;
|
||||
dim= (int)strtol(rboxCommand+1, &endDim, 10);
|
||||
if(*endDim=='\0' && dim>0){
|
||||
setDimension(dim);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}else if(dim!=3){
|
||||
char dimStr[20]; // max dim is 200 (MAXdim)
|
||||
sprintf(dimStr, " D%d", dim);
|
||||
s += dimStr;
|
||||
}
|
||||
char *command= const_cast<char*>(s.c_str());
|
||||
if(qh()->cpp_object){
|
||||
throw QhullError(10001, "Qhull error: conflicting user of cpp_object for RboxPoints::appendPoints() or corrupted qh_qh");
|
||||
}
|
||||
if(extraCoordinatesCount()!=0){
|
||||
throw QhullError(10067, "Qhull error: Extra coordinates (%d) prior to calling RboxPoints::appendPoints. Was %s", extraCoordinatesCount(), 0, 0.0, comment().c_str());
|
||||
}
|
||||
countT previousCount= count();
|
||||
qh()->cpp_object= this; // for qh_fprintf_rbox()
|
||||
int status= qh_rboxpoints(qh(), command);
|
||||
qh()->cpp_object= 0;
|
||||
if(rbox_status==qh_ERRnone){
|
||||
rbox_status= status;
|
||||
}
|
||||
if(rbox_status!=qh_ERRnone){
|
||||
throw QhullError(rbox_status, rbox_message);
|
||||
}
|
||||
if(extraCoordinatesCount()!=0){
|
||||
throw QhullError(10002, "Qhull error: extra coordinates (%d) for PointCoordinates (%x)", extraCoordinatesCount(), 0, 0.0, coordinates());
|
||||
}
|
||||
if(previousCount+newCount()!=count()){
|
||||
throw QhullError(10068, "Qhull error: rbox specified %d points but got %d points for command '%s'", newCount(), count()-previousCount, 0.0, comment().c_str());
|
||||
}
|
||||
}//appendPoints
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
#//!\name Global functions
|
||||
|
||||
/*-<a href="qh-user.htm#TOC"
|
||||
>-------------------------------</a><a name="qh_fprintf_rbox">-</a>
|
||||
|
||||
qh_fprintf_rbox(qh, fp, msgcode, format, list of args )
|
||||
fp is ignored (replaces qh_fprintf_rbox() in userprintf_rbox.c)
|
||||
cpp_object == RboxPoints
|
||||
|
||||
notes:
|
||||
only called from qh_rboxpoints()
|
||||
sets rbox_status to msgcode if error 6000..6999
|
||||
same as fprintf() and Qhull.qh_fprintf()
|
||||
fgets() is not trapped like fprintf()
|
||||
Do not throw errors from here. Use qh_errexit_rbox;
|
||||
A similar technique can be used for qh_fprintf to capture all of its output
|
||||
*/
|
||||
extern "C"
|
||||
|
||||
void qh_fprintf_rbox(qhT *qh, FILE*, int msgcode, const char *fmt, ... ) {
|
||||
va_list args;
|
||||
|
||||
using namespace orgQhull;
|
||||
|
||||
if(!qh->cpp_object){
|
||||
fprintf(stderr, "QH10072 Qhull internal error (qh_fprintf_rbox): qh.cpp_object not defined. Exit program\n");
|
||||
qh_errexit_rbox(qh, 72);
|
||||
/* never returns */
|
||||
}
|
||||
RboxPoints *out= reinterpret_cast<RboxPoints *>(qh->cpp_object);
|
||||
va_start(args, fmt);
|
||||
if(msgcode<MSG_OUTPUT){
|
||||
char newMessage[MSG_MAXLEN];
|
||||
// RoadError provides the message tag
|
||||
vsnprintf(newMessage, sizeof(newMessage), fmt, args);
|
||||
out->rbox_message += newMessage;
|
||||
if(out->rbox_status<MSG_ERROR || out->rbox_status>=MSG_STDERR){
|
||||
out->rbox_status= msgcode;
|
||||
}
|
||||
va_end(args);
|
||||
return;
|
||||
}
|
||||
switch(msgcode){
|
||||
case 9391:
|
||||
case 9392:
|
||||
out->rbox_message += "QH10010 Qhull input error (RboxPoints): options 'h', 'n' not supported.\n";
|
||||
qh_errexit_rbox(qh, 10);
|
||||
/* never returns */
|
||||
break;
|
||||
case 9393: // QH11026 FIX: countT vs. int
|
||||
{
|
||||
int dimension= va_arg(args, int);
|
||||
string command(va_arg(args, char*));
|
||||
countT count= va_arg(args, countT);
|
||||
out->setDimension(dimension);
|
||||
out->appendComment(" \"");
|
||||
out->appendComment(command.substr(command.find(' ')+1));
|
||||
out->appendComment("\"");
|
||||
out->setNewCount(count);
|
||||
out->reservePoints();
|
||||
}
|
||||
break;
|
||||
case 9407:
|
||||
*out << va_arg(args, int);
|
||||
// fall through
|
||||
case 9405:
|
||||
*out << va_arg(args, int);
|
||||
// fall through
|
||||
case 9403:
|
||||
*out << va_arg(args, int);
|
||||
break;
|
||||
case 9408:
|
||||
*out << va_arg(args, double);
|
||||
// fall through
|
||||
case 9406:
|
||||
*out << va_arg(args, double);
|
||||
// fall through
|
||||
case 9404:
|
||||
*out << va_arg(args, double);
|
||||
break;
|
||||
default:
|
||||
// do nothing
|
||||
break;
|
||||
}
|
||||
va_end(args);
|
||||
} /* qh_fprintf_rbox */
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/RboxPoints.h#2 $$Change: 2953 $
|
||||
** $DateTime: 2020/05/21 22:05:32 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef RBOXPOINTS_H
|
||||
#define RBOXPOINTS_H
|
||||
|
||||
#include "libqhull_r/qhull_ra.h"
|
||||
#include "libqhullcpp/QhullPoint.h"
|
||||
#include "libqhullcpp/PointCoordinates.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <istream>
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
#//!\name Defined here
|
||||
//! RboxPoints -- generate random PointCoordinates for Qhull
|
||||
class RboxPoints;
|
||||
|
||||
class RboxPoints : public PointCoordinates {
|
||||
|
||||
private:
|
||||
#//!\name Fields and friends
|
||||
//! PointCoordinates.qh() is owned by RboxPoints
|
||||
countT rbox_new_count; //! Number of points for PointCoordinates
|
||||
int rbox_status; //! error status from rboxpoints. qh_ERRnone if none.
|
||||
std::string rbox_message; //! stderr from rboxpoints
|
||||
|
||||
// '::' is required for friend references
|
||||
friend void ::qh_fprintf_rbox(qhT *qh, FILE *fp, int msgcode, const char *fmt, ... );
|
||||
|
||||
public:
|
||||
#//!\name Construct
|
||||
RboxPoints();
|
||||
explicit RboxPoints(const char *rboxCommand);
|
||||
~RboxPoints();
|
||||
private: // Disable copy constructor and assignment. RboxPoints owns QhullQh.
|
||||
RboxPoints(const RboxPoints &);
|
||||
RboxPoints &operator=(const RboxPoints &);
|
||||
private:
|
||||
void allocateQhullQh();
|
||||
|
||||
public:
|
||||
#//!\name GetSet
|
||||
void clearRboxMessage();
|
||||
countT newCount() const { return rbox_new_count; }
|
||||
std::string rboxMessage() const;
|
||||
int rboxStatus() const;
|
||||
bool hasRboxMessage() const;
|
||||
void setNewCount(countT pointCount) { QHULL_ASSERT(pointCount>=0); rbox_new_count= pointCount; }
|
||||
|
||||
#//!\name Modify
|
||||
void appendPoints(const char* rboxCommand);
|
||||
using PointCoordinates::appendPoints;
|
||||
void reservePoints() { reserveCoordinates((count()+newCount())*dimension()); }
|
||||
};//class RboxPoints
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
#endif // RBOXPOINTS_H
|
||||
@@ -0,0 +1,158 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/RoadError.cpp#4 $$Change: 2953 $
|
||||
** $DateTime: 2020/05/21 22:05:32 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#//! RoadError -- All exceptions thrown by Qhull are RoadErrors
|
||||
#//! Do not throw RoadError's from destructors. Use e.logError() instead.
|
||||
|
||||
#include "libqhullcpp/RoadError.h"
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
using std::cerr;
|
||||
using std::cout;
|
||||
using std::string;
|
||||
|
||||
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
|
||||
#endif
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
#//!\name Class fields
|
||||
|
||||
//! Identifies error messages from Qhull and Road for web searches.
|
||||
//! See QhullError.h#QHULLlastError and user.h#MSG_ERROR
|
||||
const char * RoadError::
|
||||
ROADtag= "QH";
|
||||
|
||||
std::ostringstream RoadError::
|
||||
global_log;
|
||||
|
||||
#//!\name Constructor
|
||||
|
||||
RoadError::
|
||||
RoadError()
|
||||
: error_code(0)
|
||||
, log_event()
|
||||
, error_message()
|
||||
{ }
|
||||
|
||||
RoadError::
|
||||
RoadError(const RoadError &other)
|
||||
: error_code(other.error_code)
|
||||
, log_event(other.log_event)
|
||||
, error_message(other.error_message)
|
||||
{
|
||||
}//copy construct
|
||||
|
||||
RoadError::
|
||||
RoadError(int code, const std::string &message)
|
||||
: error_code(code)
|
||||
, log_event(message.c_str())
|
||||
, error_message(log_event.toString(ROADtag, error_code))
|
||||
{
|
||||
log_event.cstr_1= error_message.c_str(); // overwrites initial value
|
||||
}
|
||||
|
||||
RoadError::
|
||||
RoadError(int code, const char *fmt)
|
||||
: error_code(code)
|
||||
, log_event(fmt)
|
||||
, error_message()
|
||||
{ }
|
||||
|
||||
RoadError::
|
||||
RoadError(int code, const char *fmt, int d)
|
||||
: error_code(code)
|
||||
, log_event(fmt, d)
|
||||
, error_message()
|
||||
{ }
|
||||
|
||||
RoadError::
|
||||
RoadError(int code, const char *fmt, int d, int d2)
|
||||
: error_code(code)
|
||||
, log_event(fmt, d, d2)
|
||||
, error_message()
|
||||
{ }
|
||||
|
||||
RoadError::
|
||||
RoadError(int code, const char *fmt, int d, int d2, float f)
|
||||
: error_code(code)
|
||||
, log_event(fmt, d, d2, f)
|
||||
, error_message()
|
||||
{ }
|
||||
|
||||
RoadError::
|
||||
RoadError(int code, const char *fmt, int d, int d2, float f, const char *s)
|
||||
: error_code(code)
|
||||
, log_event(fmt, d, d2, f, s)
|
||||
, error_message(log_event.toString(ROADtag, code)) // char * may go out of scope
|
||||
{ }
|
||||
|
||||
RoadError::
|
||||
RoadError(int code, const char *fmt, int d, int d2, float f, const void *x)
|
||||
: error_code(code)
|
||||
, log_event(fmt, d, d2, f, x)
|
||||
, error_message()
|
||||
{ }
|
||||
|
||||
RoadError::
|
||||
RoadError(int code, const char *fmt, int d, int d2, float f, int i)
|
||||
: error_code(code)
|
||||
, log_event(fmt, d, d2, f, i)
|
||||
, error_message()
|
||||
{ }
|
||||
|
||||
RoadError::
|
||||
RoadError(int code, const char *fmt, int d, int d2, float f, long long i)
|
||||
: error_code(code)
|
||||
, log_event(fmt, d, d2, f, i)
|
||||
, error_message()
|
||||
{ }
|
||||
|
||||
RoadError::
|
||||
RoadError(int code, const char *fmt, int d, int d2, float f, double e)
|
||||
: error_code(code)
|
||||
, log_event(fmt, d, d2, f, e)
|
||||
, error_message()
|
||||
{ }
|
||||
|
||||
RoadError & RoadError::
|
||||
operator=(const RoadError &other)
|
||||
{
|
||||
error_code= other.error_code;
|
||||
error_message= other.error_message;
|
||||
log_event= other.log_event;
|
||||
return *this;
|
||||
}//operator=
|
||||
|
||||
#//!\name Virtual
|
||||
const char * RoadError::
|
||||
what() const throw()
|
||||
{
|
||||
if(error_message.empty()){
|
||||
error_message= log_event.toString(ROADtag, error_code);
|
||||
}
|
||||
return error_message.c_str();
|
||||
}//what
|
||||
|
||||
#//!\name Updates
|
||||
|
||||
//! Log error instead of throwing it.
|
||||
//! Not reentrant, so avoid using it if possible
|
||||
//!\todo Redesign with a thread-local stream or a reentrant ostringstream
|
||||
void RoadError::
|
||||
logErrorLastResort() const
|
||||
{
|
||||
global_log << what() << endl;
|
||||
}//logError
|
||||
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/RoadError.h#8 $$Change: 3396 $
|
||||
** $DateTime: 2023/01/02 16:59:48 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef ROADERROR_H
|
||||
#define ROADERROR_H
|
||||
|
||||
#include "libqhull_r/user_r.h" /* for QHULL_CRTDBG */
|
||||
#include "libqhullcpp/RoadLogEvent.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
using std::endl;
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
#//!\name Defined here
|
||||
//! RoadError -- Report and log errors
|
||||
//! See discussion in Saylan, G., "Practical C++ error handling in hybrid environments," Dr. Dobb's Journal, p. 50-55, March 2007.
|
||||
//! He uses an auto_ptr to track a stringstream. It constructs a string on the fly. RoadError uses the copy constructor to transform RoadLogEvent into a string
|
||||
class RoadError;
|
||||
|
||||
class RoadError : public std::exception {
|
||||
|
||||
private:
|
||||
#//!\name Fields
|
||||
int error_code; //! Non-zero code (not logged), maybe returned as program status
|
||||
RoadLogEvent log_event; //! Format string w/ arguments
|
||||
mutable std::string error_message; //! Formatted error message. Must be after log_event.
|
||||
|
||||
#//!\name Class fields
|
||||
static const char * ROADtag;
|
||||
static std::ostringstream global_log; //!< May be replaced with any ostream object
|
||||
//!< Not reentrant -- only used by RoadError::logErrorLastResort()
|
||||
|
||||
public:
|
||||
#//!\name Constants
|
||||
|
||||
#//!\name Constructors
|
||||
RoadError();
|
||||
RoadError(const RoadError &other); //! Called on throw, generates error_message
|
||||
RoadError(int code, const std::string &message);
|
||||
RoadError(int code, const char *fmt);
|
||||
RoadError(int code, const char *fmt, int d);
|
||||
RoadError(int code, const char *fmt, int d, int d2);
|
||||
RoadError(int code, const char *fmt, int d, int d2, float f);
|
||||
RoadError(int code, const char *fmt, int d, int d2, float f, const char *s);
|
||||
RoadError(int code, const char *fmt, int d, int d2, float f, const void *x);
|
||||
RoadError(int code, const char *fmt, int d, int d2, float f, int i);
|
||||
RoadError(int code, const char *fmt, int d, int d2, float f, long long i);
|
||||
RoadError(int code, const char *fmt, int d, int d2, float f, double e);
|
||||
|
||||
RoadError & operator=(const RoadError &other);
|
||||
~RoadError() throw() {}
|
||||
|
||||
#//!\name Class methods
|
||||
|
||||
static void clearGlobalLog() { global_log.seekp(0); }
|
||||
static bool emptyGlobalLog() { return global_log.tellp()<=0; }
|
||||
static std::string stringGlobalLog() { return global_log.str(); }
|
||||
|
||||
#//!\name Virtual
|
||||
virtual const char *what() const throw();
|
||||
|
||||
#//!\name GetSet
|
||||
bool isValid() const { return log_event.isValid(); }
|
||||
int errorCode() const { return error_code; }
|
||||
// QH11021 FIX: should RoadError provide errorMessage(). Currently what()
|
||||
RoadLogEvent roadLogEvent() const { return log_event; }
|
||||
|
||||
#//!\name Update
|
||||
void logErrorLastResort() const;
|
||||
};//class RoadError
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
#//!\name Global
|
||||
|
||||
inline std::ostream & operator<<(std::ostream &os, const orgQhull::RoadError &e) { return os << e.what(); }
|
||||
|
||||
#endif // ROADERROR_H
|
||||
@@ -0,0 +1,129 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/RoadLogEvent.cpp#3 $$Change: 2961 $
|
||||
** $Date: 2020/06/01 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#//! RoadLogEvent -- All exceptions thrown by Qhull are RoadErrors
|
||||
|
||||
#include "libqhullcpp/RoadLogEvent.h"
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::ostringstream;
|
||||
using std::string;
|
||||
|
||||
#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
|
||||
#endif
|
||||
|
||||
namespace orgQhull{
|
||||
|
||||
#//!\name Conversion
|
||||
string RoadLogEvent::
|
||||
toString(const char *tag, int code) const
|
||||
{
|
||||
ostringstream os;
|
||||
size_t n= 0;
|
||||
if(tag && code){
|
||||
n= strlen(tag);
|
||||
if(format_string && strlen(format_string)>n+1 && isdigit(format_string[n+1]) && (strncmp(format_string, tag, n)==0 || strncmp(format_string+1, tag, n) == 0)){
|
||||
// format_string already starts with tag and a code, e.g., QH6024 qhull input error, or [QH1049] qh_addpoint...
|
||||
}else{
|
||||
os << tag << code;
|
||||
if(format_string && *format_string!='\0'){
|
||||
os << " ";
|
||||
}
|
||||
}
|
||||
}
|
||||
if(format_string==NULL || *format_string=='\0'){
|
||||
return os.str();
|
||||
}
|
||||
const char *s= format_string;
|
||||
int dCount= 0; // Count of %d
|
||||
int fCount= 0; // Count of %f
|
||||
char extraCode= '\0';
|
||||
while(*s){
|
||||
if(*s!='%'){
|
||||
os << *s++;
|
||||
}else{
|
||||
char c= *++s;
|
||||
s++;
|
||||
switch(c){
|
||||
case 'd':
|
||||
if(++dCount>2){
|
||||
os << " ERROR_three_%d_in_format ";
|
||||
}else if(dCount==2){
|
||||
os << int_2;
|
||||
}else{
|
||||
os << int_1;
|
||||
}
|
||||
break;
|
||||
case 'e':
|
||||
if(firstExtraCode(os, c, &extraCode)){
|
||||
os << double_1;
|
||||
}
|
||||
break;
|
||||
case 'f':
|
||||
if(++fCount>1){
|
||||
os << " ERROR_two_%f_in_format ";
|
||||
}else{
|
||||
os << float_1;
|
||||
}
|
||||
break;
|
||||
case 'i':
|
||||
if(firstExtraCode(os, c, &extraCode)){
|
||||
os << int64_1;
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
if(firstExtraCode(os, c, &extraCode)){
|
||||
os << cstr_1;
|
||||
}
|
||||
break;
|
||||
case 'u':
|
||||
if(firstExtraCode(os, c, &extraCode)){
|
||||
os << "0x" << std::hex << int64_1 << std::dec;
|
||||
}
|
||||
break;
|
||||
case 'x':
|
||||
if(firstExtraCode(os, c, &extraCode)){
|
||||
os << void_1;
|
||||
}
|
||||
break;
|
||||
case '%':
|
||||
os << c;
|
||||
break;
|
||||
default:
|
||||
os << " ERROR_%" << c << "_not_defined_in_format";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(s[-1]!='\n'){
|
||||
os << endl;
|
||||
}
|
||||
return os.str();
|
||||
}//toString
|
||||
|
||||
#//!\name Class helpers (static)
|
||||
|
||||
//! True if this char is the first extra code
|
||||
bool RoadLogEvent::
|
||||
firstExtraCode(std::ostream &os, char c, char *extraCode){
|
||||
if(*extraCode){
|
||||
os << " ERROR_%" << *extraCode << "_and_%" << c << "_in_format ";
|
||||
return false;
|
||||
}
|
||||
*extraCode= c;
|
||||
return true;
|
||||
}//firstExtraCode
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/RoadLogEvent.h#3 $$Change: 2953 $
|
||||
** $DateTime: 2020/05/21 22:05:32 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef ROADLOGEVENT_H
|
||||
#define ROADLOGEVENT_H
|
||||
|
||||
#include <ostream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
#//!\name Defined here
|
||||
//! RoadLogEvent -- Record an event for the RoadLog
|
||||
struct RoadLogEvent;
|
||||
|
||||
struct RoadLogEvent {
|
||||
|
||||
public:
|
||||
#//!\name Fields
|
||||
const char * format_string; //! Format string (a literal with format codes, for logging)
|
||||
int int_1; //! Integer argument (%d, for logging)
|
||||
int int_2; //! Integer argument (%d, for logging)
|
||||
float float_1; //! Float argument (%f, for logging)
|
||||
union { //! One additional argument (for logging)
|
||||
const char *cstr_1; //! Cstr argument (%s) -- type checked at construct-time
|
||||
const void *void_1; //! Void* argument (%x) -- Use upper-case codes for object types
|
||||
long long int64_1; //! signed int64 (%i). Ambiguous if unsigned is also defined.
|
||||
double double_1; //! Double argument (%e)
|
||||
};
|
||||
|
||||
#//!\name Constants
|
||||
|
||||
#//!\name Constructors
|
||||
RoadLogEvent() : format_string(NULL), int_1(0), int_2(0), float_1(0), int64_1(0) {}
|
||||
explicit RoadLogEvent(const char *fmt) : format_string(fmt), int_1(0), int_2(0), float_1(0), int64_1(0) {}
|
||||
RoadLogEvent(const char *fmt, int d) : format_string(fmt), int_1(d), int_2(0), float_1(0), int64_1(0) {}
|
||||
RoadLogEvent(const char *fmt, int d, int d2) : format_string(fmt), int_1(d), int_2(d2), float_1(0), int64_1(0) {}
|
||||
RoadLogEvent(const char *fmt, int d, int d2, float f) : format_string(fmt), int_1(d), int_2(d2), float_1(f), int64_1(0) {}
|
||||
RoadLogEvent(const char *fmt, int d, int d2, float f, const char *s) : format_string(fmt), int_1(d), int_2(d2), float_1(f), cstr_1(s) {}
|
||||
RoadLogEvent(const char *fmt, int d, int d2, float f, const void *x) : format_string(fmt), int_1(d), int_2(d2), float_1(f), void_1(x) {}
|
||||
RoadLogEvent(const char *fmt, int d, int d2, float f, int i) : format_string(fmt), int_1(d), int_2(d2), float_1(f), int64_1(i) {}
|
||||
RoadLogEvent(const char *fmt, int d, int d2, float f, long long i) : format_string(fmt), int_1(d), int_2(d2), float_1(f), int64_1(i) {}
|
||||
RoadLogEvent(const char *fmt, int d, int d2, float f, double g) : format_string(fmt), int_1(d), int_2(d2), float_1(f), double_1(g) {}
|
||||
~RoadLogEvent() {}
|
||||
//! Default copy constructor and assignment
|
||||
|
||||
#//!\name GetSet
|
||||
bool isValid() const { return format_string!=NULL; }
|
||||
int int1() const { return int_1; }
|
||||
int int2() const { return int_2; }
|
||||
float float1() const { return float_1; }
|
||||
const char * format() const { return format_string; }
|
||||
const char * cstr1() const { return cstr_1; }
|
||||
const void * void1() const { return void_1; }
|
||||
long long int64() const { return int64_1; }
|
||||
double double1() const { return double_1; }
|
||||
|
||||
#//!\name Conversion
|
||||
|
||||
std::string toString(const char* tag, int code) const;
|
||||
|
||||
private:
|
||||
#//!\name Class helpers
|
||||
static bool firstExtraCode(std::ostream &os, char c, char *extraCode);
|
||||
|
||||
|
||||
};//class RoadLogEvent
|
||||
|
||||
}//namespace orgQhull
|
||||
|
||||
#endif // ROADLOGEVENT_H
|
||||
@@ -0,0 +1,67 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2008-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/functionObjects.h#2 $$Change: 2953 $
|
||||
** $DateTime: 2020/05/21 22:05:32 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QHFUNCTIONOBJECTS_H
|
||||
#define QHFUNCTIONOBJECTS_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
#//!\name Defined here
|
||||
|
||||
//! Sum of absolute values of the elements in a container
|
||||
class AbsoluteSumOf;
|
||||
//! Sum of the elements in a container
|
||||
class SumOf;
|
||||
//! Sum of squares of the elements in a container
|
||||
class SumSquaresOf;
|
||||
|
||||
#//!\name Class
|
||||
|
||||
//! Absolute sum of the elements in a container
|
||||
class AbsoluteSumOf
|
||||
{
|
||||
private:
|
||||
double sum;
|
||||
public:
|
||||
inline AbsoluteSumOf() : sum(0.0) {}
|
||||
inline void operator()(double v) { sum += fabs(v); }
|
||||
inline operator double() { return sum; }
|
||||
};//AbsoluteSumOf
|
||||
|
||||
//! Sum of the elements in a container
|
||||
class SumOf
|
||||
{
|
||||
private:
|
||||
double sum;
|
||||
public:
|
||||
inline SumOf() : sum(0.0) {}
|
||||
inline void operator()(double v) { sum += v; }
|
||||
inline operator double() { return sum; }
|
||||
};//SumOf
|
||||
|
||||
|
||||
//! Sum of squares of the elements in a container
|
||||
class SumSquaresOf
|
||||
{
|
||||
private:
|
||||
double sum;
|
||||
public:
|
||||
inline SumSquaresOf() : sum(0.0) {}
|
||||
inline void operator()(double v) { sum += v*v; }
|
||||
inline operator double() { return sum; }
|
||||
};//SumSquaresOf
|
||||
|
||||
|
||||
}//orgQhull
|
||||
|
||||
|
||||
#endif //QHFUNCTIONOBJECTS_H
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
# -------------------------------------------------
|
||||
# libqhullcpp.pro -- Qt project for Qhull cpp shared library
|
||||
#
|
||||
# It uses reentrant Qhull
|
||||
# -------------------------------------------------
|
||||
|
||||
include(../qhull-warn.pri)
|
||||
|
||||
DESTDIR = ../../lib
|
||||
TEMPLATE = lib
|
||||
# Do not create libqhullcpp as a shared library. Qhull C++ classes may change layout and size.
|
||||
CONFIG += staticlib warn_on
|
||||
CONFIG -= qt rtti
|
||||
build_pass:CONFIG(debug, debug|release):{
|
||||
TARGET = qhullcpp_d
|
||||
OBJECTS_DIR = Debug
|
||||
}else:build_pass:CONFIG(release, debug|release):{
|
||||
TARGET = qhullcpp
|
||||
OBJECTS_DIR = Release
|
||||
}
|
||||
MOC_DIR = moc
|
||||
|
||||
INCLUDEPATH += ../../src
|
||||
INCLUDEPATH += $$PWD # for MOC_DIR
|
||||
|
||||
CONFIG += qhull_warn_shadow qhull_warn_conversion
|
||||
|
||||
SOURCES += ../libqhullcpp/Coordinates.cpp
|
||||
SOURCES += ../libqhullcpp/PointCoordinates.cpp
|
||||
SOURCES += ../libqhullcpp/Qhull.cpp
|
||||
SOURCES += ../libqhullcpp/QhullFacet.cpp
|
||||
SOURCES += ../libqhullcpp/QhullFacetList.cpp
|
||||
SOURCES += ../libqhullcpp/QhullFacetSet.cpp
|
||||
SOURCES += ../libqhullcpp/QhullHyperplane.cpp
|
||||
SOURCES += ../libqhullcpp/QhullPoint.cpp
|
||||
SOURCES += ../libqhullcpp/QhullPoints.cpp
|
||||
SOURCES += ../libqhullcpp/QhullPointSet.cpp
|
||||
SOURCES += ../libqhullcpp/QhullQh.cpp
|
||||
SOURCES += ../libqhullcpp/QhullRidge.cpp
|
||||
SOURCES += ../libqhullcpp/QhullSet.cpp
|
||||
SOURCES += ../libqhullcpp/QhullStat.cpp
|
||||
SOURCES += ../libqhullcpp/QhullUser.cpp
|
||||
SOURCES += ../libqhullcpp/QhullVertex.cpp
|
||||
SOURCES += ../libqhullcpp/QhullVertexSet.cpp
|
||||
SOURCES += ../libqhullcpp/RboxPoints.cpp
|
||||
SOURCES += ../libqhullcpp/RoadError.cpp
|
||||
SOURCES += ../libqhullcpp/RoadLogEvent.cpp
|
||||
|
||||
HEADERS += ../libqhullcpp/Coordinates.h
|
||||
HEADERS += ../libqhullcpp/functionObjects.h
|
||||
HEADERS += ../libqhullcpp/PointCoordinates.h
|
||||
HEADERS += ../libqhullcpp/Qhull.h
|
||||
HEADERS += ../libqhullcpp/QhullError.h
|
||||
HEADERS += ../libqhullcpp/QhullFacet.h
|
||||
HEADERS += ../libqhullcpp/QhullFacetList.h
|
||||
HEADERS += ../libqhullcpp/QhullFacetSet.h
|
||||
HEADERS += ../libqhullcpp/QhullHyperplane.h
|
||||
HEADERS += ../libqhullcpp/QhullIterator.h
|
||||
HEADERS += ../libqhullcpp/QhullLinkedList.h
|
||||
HEADERS += ../libqhullcpp/QhullPoint.h
|
||||
HEADERS += ../libqhullcpp/QhullPoints.h
|
||||
HEADERS += ../libqhullcpp/QhullPointSet.h
|
||||
HEADERS += ../libqhullcpp/QhullQh.h
|
||||
HEADERS += ../libqhullcpp/QhullRidge.h
|
||||
HEADERS += ../libqhullcpp/QhullSet.h
|
||||
HEADERS += ../libqhullcpp/QhullSets.h
|
||||
HEADERS += ../libqhullcpp/QhullStat.h
|
||||
HEADERS += ../libqhullcpp/QhullUser.h
|
||||
HEADERS += ../libqhullcpp/QhullVertex.h
|
||||
HEADERS += ../libqhullcpp/QhullVertexSet.h
|
||||
HEADERS += ../libqhullcpp/RboxPoints.h
|
||||
HEADERS += ../libqhullcpp/RoadError.h
|
||||
HEADERS += ../libqhullcpp/RoadLogEvent.h
|
||||
@@ -0,0 +1,130 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2009-2020 C.B. Barber. All rights reserved.
|
||||
** $Id: //main/2019/qhull/src/libqhullcpp/qt-qhull.cpp#7 $$Change: 3032 $
|
||||
** $DateTime: 2020/09/01 17:08:51 $$Author: bbarber $
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QList>
|
||||
#include "qhulltest/RoadTest.h"
|
||||
|
||||
#ifndef QHULL_USES_QT
|
||||
#define QHULL_USES_QT 1
|
||||
#endif
|
||||
|
||||
#include "Coordinates.h"
|
||||
#include "QhullFacetList.h"
|
||||
#include "QhullFacetSet.h"
|
||||
#include "QhullHyperplane.h"
|
||||
#include "QhullPoint.h"
|
||||
#include "QhullPoints.h"
|
||||
#include "QhullPointSet.h"
|
||||
#include "QhullVertex.h"
|
||||
#include "QhullVertexSet.h"
|
||||
|
||||
namespace orgQhull {
|
||||
|
||||
#//!\name Conversions
|
||||
|
||||
QList<coordT> Coordinates::
|
||||
toQList() const
|
||||
{
|
||||
QList<coordT> cs;
|
||||
for(int i= 0; i<count(); ++i){
|
||||
coordT a= at(i);
|
||||
cs.append(a);
|
||||
}
|
||||
return cs;
|
||||
}//toQList
|
||||
|
||||
QList<QhullFacet> QhullFacetList::
|
||||
toQList() const
|
||||
{
|
||||
QhullLinkedListIterator<QhullFacet> i(*this);
|
||||
QList<QhullFacet> vs;
|
||||
while(i.hasNext()){
|
||||
QhullFacet f= i.next();
|
||||
if(isSelectAll() || f.isGood()){
|
||||
vs.append(f);
|
||||
}
|
||||
}
|
||||
return vs;
|
||||
}//toQList
|
||||
|
||||
//! Same as PrintVertices
|
||||
QList<QhullVertex> QhullFacetList::
|
||||
vertices_toQList() const
|
||||
{
|
||||
QList<QhullVertex> vs;
|
||||
QhullVertexSet qvs(qh(), first().getFacetT(), nullptr, isSelectAll());
|
||||
for(QhullVertexSet::iterator i=qvs.begin(); i!=qvs.end(); ++i){
|
||||
vs.push_back(*i);
|
||||
}
|
||||
return vs;
|
||||
}//vertices_toQList
|
||||
|
||||
QList<QhullFacet> QhullFacetSet::
|
||||
toQList() const
|
||||
{
|
||||
QhullSetIterator<QhullFacet> i(*this);
|
||||
QList<QhullFacet> vs;
|
||||
while(i.hasNext()){
|
||||
QhullFacet f= i.next();
|
||||
if(isSelectAll() || f.isGood()){
|
||||
vs.append(f);
|
||||
}
|
||||
}
|
||||
return vs;
|
||||
}//toQList
|
||||
|
||||
#ifdef QHULL_USES_QT
|
||||
QList<coordT> QhullHyperplane::
|
||||
toQList() const
|
||||
{
|
||||
QhullHyperplaneIterator i(*this);
|
||||
QList<coordT> fs;
|
||||
while(i.hasNext()){
|
||||
fs.append(i.next());
|
||||
}
|
||||
fs.append(hyperplane_offset);
|
||||
return fs;
|
||||
}//toQList
|
||||
#endif //QHULL_USES_QT
|
||||
|
||||
QList<coordT> QhullPoint::
|
||||
toQList() const
|
||||
{
|
||||
QhullPointIterator i(*this);
|
||||
QList<coordT> vs;
|
||||
while(i.hasNext()){
|
||||
vs.append(i.next());
|
||||
}
|
||||
return vs;
|
||||
}//toQList
|
||||
|
||||
QList<QhullPoint> QhullPoints::
|
||||
toQList() const
|
||||
{
|
||||
QhullPointsIterator i(*this);
|
||||
QList<QhullPoint> vs;
|
||||
while(i.hasNext()){
|
||||
vs.append(i.next());
|
||||
}
|
||||
return vs;
|
||||
}//toQList
|
||||
|
||||
/******
|
||||
QList<QhullPoint> QhullPointSet::
|
||||
toQList() const
|
||||
{
|
||||
QhullPointSetIterator i(*this);
|
||||
QList<QhullPoint> vs;
|
||||
while(i.hasNext()){
|
||||
vs.append(i.next());
|
||||
}
|
||||
return vs;
|
||||
}//toQList
|
||||
*/
|
||||
}//orgQhull
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
/*<html><pre> -<a href="qh-user_r.htm"
|
||||
>-------------------------------</a><a name="TOP">-</a>
|
||||
|
||||
usermem_r-cpp.cpp
|
||||
|
||||
Redefine qh_exit() as 'throw std::runtime_error("QH10003 ...")'
|
||||
|
||||
This file is not included in the Qhull builds.
|
||||
|
||||
qhull_r calls qh_exit() when qh_errexit() is not available. For example,
|
||||
it calls qh_exit() if you linked the wrong qhull library.
|
||||
|
||||
The C++ interface avoids most of the calls to qh_exit().
|
||||
|
||||
If needed, include usermem_r-cpp.o before libqhullstatic_r.a. You may need to
|
||||
override duplicate symbol errors (e.g. /FORCE:MULTIPLE for DevStudio). It
|
||||
may produce a warning about throwing an error from C code.
|
||||
*/
|
||||
|
||||
extern "C" {
|
||||
void qh_exit(int exitcode);
|
||||
}
|
||||
|
||||
#include <stdexcept>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*-<a href="qh-user_r.htm#TOC"
|
||||
>-------------------------------</a><a name="qh_exit">-</a>
|
||||
|
||||
qh_exit( exitcode )
|
||||
exit program
|
||||
|
||||
notes:
|
||||
same as exit()
|
||||
*/
|
||||
void qh_exit(int exitcode) {
|
||||
exitcode= exitcode;
|
||||
throw std::runtime_error("QH10003 Qhull error. See stderr or errfile.");
|
||||
} /* exit */
|
||||
|
||||
/*-<a href="qh-user_r.htm#TOC"
|
||||
>-------------------------------</a><a name="qh_fprintf_stderr">-</a>
|
||||
|
||||
qh_fprintf_stderr( msgcode, format, list of args )
|
||||
fprintf to stderr with msgcode (non-zero)
|
||||
|
||||
notes:
|
||||
qh_fprintf_stderr() is called when qh->ferr is not defined, usually due to an initialization error
|
||||
|
||||
It is typically followed by qh_errexit().
|
||||
|
||||
Redefine this function to avoid using stderr
|
||||
|
||||
Use qh_fprintf [userprintf_r.c] for normal printing
|
||||
*/
|
||||
void qh_fprintf_stderr(int msgcode, const char *fmt, ... ) {
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
if(msgcode)
|
||||
fprintf(stderr, "QH%.4d ", msgcode);
|
||||
vfprintf(stderr, fmt, args);
|
||||
va_end(args);
|
||||
} /* fprintf_stderr */
|
||||
|
||||
/*-<a href="qh-user_r.htm#TOC"
|
||||
>-------------------------------</a><a name="qh_free">-</a>
|
||||
|
||||
qh_free(qhT *qh, mem )
|
||||
free memory
|
||||
|
||||
notes:
|
||||
same as free()
|
||||
No calls to qh_errexit()
|
||||
*/
|
||||
void qh_free(void *mem) {
|
||||
free(mem);
|
||||
} /* free */
|
||||
|
||||
/*-<a href="qh-user_r.htm#TOC"
|
||||
>-------------------------------</a><a name="qh_malloc">-</a>
|
||||
|
||||
qh_malloc( mem )
|
||||
allocate memory
|
||||
|
||||
notes:
|
||||
same as malloc()
|
||||
*/
|
||||
void *qh_malloc(size_t size) {
|
||||
return malloc(size);
|
||||
} /* malloc */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user