Merge branch 'CGAL_headers_only-gdamiand_cjamin-old' into CGAL_headers_only-gdamiand_cjamin

This commit is contained in:
Guillaume Damiand 2015-03-16 14:00:43 +01:00
commit 9c78897ba5
212 changed files with 12285 additions and 9692 deletions

View File

@ -58,7 +58,7 @@ class Min_circle_2 {
Min_circle_2( InputIterator first,
InputIterator last,
bool randomize = false,
Random& random = default_random,
Random& random = get_default_random(),
const Traits& traits = Traits());
Min_circle_2( const Traits& traits = Traits());
@ -302,7 +302,7 @@ class Min_circle_2 {
= false
#endif
,
Random& random = default_random,
Random& random = get_default_random(),
const Traits& traits = Traits())
: tco( traits)
{

View File

@ -57,7 +57,7 @@ class Min_ellipse_2 {
Min_ellipse_2( InputIterator first,
InputIterator last,
bool randomize = false,
Random& random = default_random,
Random& random = get_default_random(),
const Traits& traits = Traits());
Min_ellipse_2( const Traits& traits = Traits());
@ -328,7 +328,7 @@ class Min_ellipse_2 {
= false
#endif
,
Random& random = default_random,
Random& random = get_default_random(),
const Traits& traits = Traits())
: tco( traits)
{

View File

@ -45,7 +45,6 @@ using CGAL::Creator_uniform_2;
using CGAL::Random_points_in_square_2;
using CGAL::Random;
using CGAL::Timer;
using CGAL::default_random;
using CGAL::rectangular_p_center_2;
#ifndef CGAL_PCENTER_NO_OUTPUT
using std::ostream;
@ -108,7 +107,7 @@ public:
Random_p_clusters_2(int n_,
double c_size_,
double r = 1,
Random& rnd = default_random)
Random& rnd = CGAL::get_default_random())
: Base(r - c_size_, rnd),
n(n_),
c_size(c_size_),
@ -163,7 +162,7 @@ main(int argc, char* argv[])
#endif // CGAL_PCENTER_NO_OUTPUT
// generate random seed
random_seed = default_random.get_int(0, (1 << 30));
random_seed = CGAL::get_default_random().get_int(0, (1 << 30));
}
else
random_seed = atoi(argv[2]);

View File

@ -50,7 +50,6 @@ using CGAL::Creator_uniform_2;
using CGAL::Random_points_in_square_2;
using CGAL::Random;
using CGAL::Timer;
using CGAL::default_random;
using CGAL::rectangular_p_center_2;
#ifndef CGAL_PCENTER_NO_OUTPUT
using std::ostream;
@ -110,7 +109,7 @@ public:
Random_p_clusters_2(int n_,
double c_size_,
double r = 1,
Random& rnd = default_random)
Random& rnd = CGAL::get_default_random())
: Base(r - c_size_, rnd),
n(n_),
c_size(c_size_),
@ -165,7 +164,7 @@ main(int argc, char* argv[])
#endif // CGAL_PCENTER_NO_OUTPUT
// generate random seed
random_seed = default_random.get_int(0, (1 << 30));
random_seed = CGAL::get_default_random().get_int(0, (1 << 30));
}
else
random_seed = std::atoi(argv[2]);

View File

@ -73,8 +73,8 @@ void process ()
for ( int i = 0; i < 100; ++i) {
points.push_back
(typename K::Point_2
(CGAL::default_random( 0x100000),
CGAL::default_random( 0x100000),
(CGAL::get_default_random()( 0x100000),
CGAL::get_default_random()( 0x100000),
hom));
}

View File

@ -73,9 +73,9 @@ void process ()
for ( int i = 0; i < 100; ++i) {
points.push_back
(typename K::Point_3
(CGAL::default_random( 0x100000),
CGAL::default_random( 0x100000),
CGAL::default_random( 0x100000),
(CGAL::get_default_random()( 0x100000),
CGAL::get_default_random()( 0x100000),
CGAL::get_default_random()( 0x100000),
hom));
}

View File

@ -75,7 +75,7 @@ void process ()
double hom = 2.0;
for ( i = 0; i < 100; ++i) {
for (j=0; j<d; ++j)
coords[ j] = CGAL::default_random( 0x100000);
coords[ j] = CGAL::get_default_random()( 0x100000);
coords[d] = hom;
points.push_back
(typename K::Point_d(d, coords.begin(), coords.end()));

View File

@ -37,6 +37,13 @@
#include <CGAL/CORE/BigFloatRep.h>
#ifdef CGAL_HEADER_ONLY
#undef CGAL_EXPORT // CJTODO: TEMPORARY
#undef CGAL_CORE_EXPORT
#define CGAL_EXPORT
#define CGAL_CORE_EXPORT
#endif
namespace CORE {
class Expr;
@ -83,8 +90,8 @@ public:
BigFloat(const BigInt& I)
: RCBigFloat(new BigFloatRep(I)) {}
/// constructor for <tt>BigRat</tt>
BigFloat(const BigRat& R, const extLong& r = defRelPrec,
const extLong& a = defAbsPrec)
BigFloat(const BigRat& R, const extLong& r = get_static_defRelPrec(),
const extLong& a = get_static_defAbsPrec())
: RCBigFloat(new BigFloatRep()) {
rep->approx(R, r, a);
}
@ -93,8 +100,8 @@ public:
// know about Expr, but BigFloat has a special role in our system!
// ===============================
/// constructor for <tt>Expr</tt>
explicit BigFloat(const Expr& E, const extLong& r = defRelPrec,
const extLong& a = defAbsPrec);
explicit BigFloat(const Expr& E, const extLong& r = get_static_defRelPrec(),
const extLong& a = get_static_defAbsPrec());
//Dummy
explicit BigFloat(const BigFloat& E, const extLong& ,
@ -161,7 +168,7 @@ public:
/// operator/=
BigFloat& operator/= (const BigFloat& x) {
BigFloat z;
z.rep->div(*rep, *x.rep, defBFdivRelPrec);
z.rep->div(*rep, *x.rep, get_static_defBFdivRelPrec());
*this = z;
return *this;
}
@ -182,11 +189,11 @@ public:
/// \name String Conversion Functions
//@{
/// set value from <tt>const char*</tt> (base = 10)
void fromString(const char* s, const extLong& p=defBigFloatInputDigits) {
void fromString(const char* s, const extLong& p=get_static_defBigFloatInputDigits()) {
rep->fromString(s, p);
}
/// convert to <tt>std::string</tt> (base = 10)
std::string toString(long prec=defBigFloatOutputDigits, bool sci=false) const {
std::string toString(long prec=get_static_defBigFloatOutputDigits(), bool sci=false) const {
return rep->toString(prec, sci);
}
std::string str() const {
@ -435,7 +442,7 @@ inline BigFloat operator* (const BigFloat& x, const BigFloat& y) {
/// operator/
inline BigFloat operator/ (const BigFloat& x, const BigFloat& y) {
BigFloat z;
z.getRep().div(x.getRep(),y.getRep(),defBFdivRelPrec);
z.getRep().div(x.getRep(),y.getRep(),get_static_defBFdivRelPrec());
return z;
}
@ -490,12 +497,12 @@ inline BigFloat power(const BigFloat& x, unsigned long p) {
/// The argument x is an initial approximation.
BigFloat root(const BigFloat&, unsigned long k, const extLong&, const BigFloat&);
inline BigFloat root(const BigFloat& x, unsigned long k) {
return root(x, k, defBFsqrtAbsPrec, x);
return root(x, k, get_static_defBFsqrtAbsPrec(), x);
}
/// sqrt to defAbsPrec:
inline BigFloat sqrt(const BigFloat& x) {
return x.sqrt(defBFsqrtAbsPrec);
return x.sqrt(get_static_defBFsqrtAbsPrec());
}
/// convert an BigFloat Interval to a BigFloat with error bits
@ -625,4 +632,10 @@ inline BigRat::BigRat(const BigFloat& f) : RCBigRat(new BigRatRep()){
*this = f.BigRatValue();
}
} //namespace CORE
#ifdef CGAL_HEADER_ONLY
#include <CGAL/CORE/BigFloat_impl.h>
#include <CGAL/CORE/CoreIO_impl.h>
#endif // CGAL_HEADER_ONLY
#endif // _CORE_BIGFLOAT_H_

View File

@ -40,6 +40,13 @@
#include <CGAL/CORE/CoreDefs.h>
#include <CGAL/CORE/extLong.h>
#ifdef CGAL_HEADER_ONLY
#undef CGAL_EXPORT // CJTODO: TEMPORARY
#undef CGAL_CORE_EXPORT
#define CGAL_EXPORT
#define CGAL_CORE_EXPORT
#endif
namespace CORE {
// forward reference
@ -144,11 +151,11 @@ private:
// conversion
// toString() Joaquin Grech 31/5/2003
std::string toString(long prec=defBigFloatOutputDigits, bool sci=false) const;
std::string toString(long prec=get_static_defBigFloatOutputDigits(), bool sci=false) const;
std::string round(std::string inRep, long& L10, unsigned int width) const;
DecimalOutput toDecimal(unsigned int width=defBigFloatOutputDigits,
DecimalOutput toDecimal(unsigned int width=get_static_defBigFloatOutputDigits(),
bool Scientific=false) const;
void fromString(const char *p, const extLong & prec = defBigFloatInputDigits);
void fromString(const char *p, const extLong & prec = get_static_defBigFloatInputDigits());
void dump() const; //inline
long adjustE(long E, BigInt M, long e) const;

File diff suppressed because it is too large Load Diff

View File

@ -39,6 +39,13 @@
#include <CGAL/CORE/MemoryPool.h>
#include <string>
#ifdef CGAL_HEADER_ONLY
#undef CGAL_EXPORT // CJTODO: TEMPORARY
#undef CGAL_CORE_EXPORT
#define CGAL_EXPORT
#define CGAL_CORE_EXPORT
#endif
namespace CORE {
@ -559,4 +566,9 @@ inline BigInt randomize(const BigInt& a) {
//@}
} //namespace CORE
#ifdef CGAL_HEADER_ONLY
//#include <CGAL/CORE/CoreIO_impl.h>
#endif // CGAL_HEADER_ONLY
#endif // _CORE_BIGINT_H_

View File

@ -39,6 +39,13 @@
#include <fstream>
#include "CGAL/CORE/Impl.h"
#ifdef CGAL_HEADER_ONLY
#undef CGAL_EXPORT // CJTODO: TEMPORARY
#undef CGAL_CORE_EXPORT
#define CGAL_EXPORT
#define CGAL_CORE_EXPORT
#endif
namespace CORE {
#ifndef LONG_BIT // such as in Linux
@ -181,4 +188,9 @@ inline void core_debug(std::string msg){
} //namespace CORE
#ifdef CGAL_HEADER_ONLY
#include <CGAL/CORE/CoreAux_impl.h>
#endif // CGAL_HEADER_ONLY
#endif // _CORE_COREAUX_H_

View File

@ -0,0 +1,229 @@
/****************************************************************************
* Core Library Version 1.7, August 2004
* Copyright (c) 1995-2004 Exact Computation Project
* All rights reserved.
*
* This file is part of CORE (http://cs.nyu.edu/exact/core/).
* You can redistribute it and/or modify it under the terms of the GNU
* General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* Licensees holding a valid commercial license may use this file in
* accordance with the commercial license agreement provided with the
* software.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
*
* File: CoreAux.cpp
* Synopsis:
* Auxiliary routines such as ceiling of log_2, etc.
* they are not specific to any Core classes.
*
* Written by
* Chee Yap <yap@cs.nyu.edu>
* Chen Li <chenli@cs.nyu.edu>
* Zilin Du <zilin@cs.nyu.edu>
*
* WWW URL: http://cs.nyu.edu/exact/
* Email: exact@cs.nyu.edu
*
* $URL$
* $Id$
***************************************************************************/
#ifdef CGAL_HEADER_ONLY
#define CGAL_INLINE_FUNCTION inline
#else
#define CGAL_INLINE_FUNCTION
#endif
#include <CGAL/CORE/CoreAux.h>
#include <gmp.h>
namespace CORE {
////////////////////////////////////////////////////////////
// More useful functions to implement:
//
// To convert digits into bits:
// given X, compute X * log_2(10)
// To convert bits into digits:
// given X, compute X * log_10(2)
//
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// flrLg(x)
// returns floor log base 2 of abs(x)
// CONVENTION lg(0) = -1 (Slight improvement, Zilin/Chee 8/5/02)
////////////////////////////////////////////////////////////
CGAL_INLINE_FUNCTION
int flrLg(long x) {
if (x == LONG_MIN) {
// special treatment as -LONG_MIN would be not representable as "long"
return LONG_BIT - 1;
} else {
// 1 <= |x| <= LONG_MAX
if (x < 0)
x = - x;
int lg = -1;
while (x > 0) {
lg++;
x >>= 1;
}
return lg;
}
}
////////////////////////////////////////////////////////////
// floor log base 2 of unsigned long x
// CONVENTION lg(0) = -1 (Slight improvement, Zilin/Chee 8/5/02)
////////////////////////////////////////////////////////////
CGAL_INLINE_FUNCTION
int flrLg(unsigned long x) {
int lg = -1;
while (x > 0) {
lg++;
x >>= 1;
}
return lg;
}
////////////////////////////////////////////////////////////
// ceiling log base 2 of abs(x)
// CONVENTION lg(0) = -1 (Slight improvement, Zilin/Chee 8/5/02)
////////////////////////////////////////////////////////////
CGAL_INLINE_FUNCTION
int clLg(long x) {
if (x == LONG_MIN)
return LONG_BIT - 1;
if (x < 0)
x = -x; // use absolute value
if (x > (LONG_MAX >> 1)) // the leading data bit is 1
return (LONG_BIT - 1); // exclude the sign bit
if (x >= 2)
return flrLg((unsigned long)((x << 1) - 1));
// SINCE ceilLog_2(x) = floorLog_2(2x-1) for x>=2
if (x == 1)
return 0;
return -1; // x must be 0 here
}
////////////////////////////////////////////////////////////
// ceiling log base 2 of unsigned long x
// CONVENTION lg(0) = -1
////////////////////////////////////////////////////////////
CGAL_INLINE_FUNCTION
int clLg(unsigned long x) {
if (x > (ULONG_MAX >> 1)) // the leading bit is 1
return LONG_BIT;
if (x >= 2)
return flrLg((x << 1) - 1);
// SINCE ceilLog_2(x) = floorLog_2(2x-1) for x>=2.
if (x == 1)
return 0;
return -1; // x must be equal to 0
}
/// gcd for machine type long
/** This is needed when we construct Polynomials with int or long coefficients */
CGAL_INLINE_FUNCTION
long gcd(long m, long n) {
if (m == 0)
return core_abs(n);
if (n == 0)
return core_abs(m);
long p = core_abs(m);
long q = core_abs(n);
if (p<q)
core_swap(p, q);
while (q>0) {
long r = p % q;
p = q;
q = r;
}
return p;
}
// return a gmp_randstate_t structure
CGAL_INLINE_FUNCTION
gmp_randstate_t* getRandstate() {
static gmp_randstate_t rstate;
static bool initialized = false;
if (!initialized) {
gmp_randinit(rstate, GMP_RAND_ALG_DEFAULT, 32L);
initialized = true;
}
return &rstate;
}
// char* core_itoa(int n, char* buffer)
// returns a pointer to the null-terminated string in buffer
// NOTES:
// 0. Buffer size should be 17 bytes (resp., 33 bytes, 65 bytes) on 16-bit
// (resp., 32-bit, 64-bit) machines. Formula: 1+sizeof(int)*8 bytes.
// 1. itoa(...) is available on some stdlib.h, but it is
// not defined by ANSI-C and so not all compilers support it.
// 2. Our use of sprintf(...) to do the job is known to
// be inefficient, but this is hardly critical for our usage.
// 3. A more general program should take a 3rd argument (the radix of
// output number). We assume radix 10.
CGAL_INLINE_FUNCTION
char * core_itoa(int n, char* buffer) {
std::sprintf(buffer, "%d", n);
return buffer;
}
/// implements the "integer mantissa" function
// (See CORE_PATH/progs/ieee/frexp.cpp for details)
CGAL_INLINE_FUNCTION
double IntMantissa(double d) {
int e;
return std::ldexp(std::frexp(d, &e), 53);
}
/// implements the "integer exponent" function
// (See CORE_PATH/progs/ieee/frexp.cpp for details)
CGAL_INLINE_FUNCTION
int IntExponent(double d) {
int e;
std::frexp(d, &e);
return e-53;
}
/// CORE_DIAGFILE is file name for core_error(..) output.
const char* CORE_DIAGFILE = "Core_Diagnostics"; // global file name
/// core_error is the method to write Core Library warning or error messages
/** Both warnings and errors are written to a file called CORE_DIAGFILE.
* But errors are also written on std:cerr (similar to std::perror()).
* */
// Usage: core_error(message, file_with_error, line_number, err_type)
// where err_type=0 means WARNING, error_type=0 means ERROR
CGAL_INLINE_FUNCTION
void core_error(std::string msg, std::string file, int lineno, bool err) {
std::ofstream outFile(CORE_DIAGFILE, std::ios::app); // open to append
if (!outFile) {
// perror("CORE ERROR: cannot open Core Diagnostics file");
std::cerr << "CORE ERROR: can't open Core Diagnostics file"<<std::endl;
std::exit(1); //Note: do not call abort()
}
outFile << "CORE " << (err? "ERROR" : "WARNING")
<< " (at " << file << ": " << lineno << "): "
<< msg << std::endl;
outFile.close();
if (err) {
char buf[65];
// perror((std::string("CORE ERROR") + " (file " + file + ", line "
// + core_itoa(lineno,buf) +"):" + msg + "\n").c_str());
std::cerr << (std::string("CORE ERROR") + " (file " + file + ", line "
+ core_itoa(lineno,buf) +"):" + msg + "\n").c_str();
std::exit(1); //Note: do not call abort()
}
}
} //namespace CORE

View File

@ -40,6 +40,33 @@
#include <CGAL/CORE/extLong.h>
#ifdef CGAL_HEADER_ONLY
#undef CGAL_EXPORT // CJTODO: TEMPORARY
#undef CGAL_CORE_EXPORT
#define CGAL_EXPORT
#define CGAL_CORE_EXPORT
#endif
#ifdef CGAL_HEADER_ONLY
#define CGAL_GLOBAL_STATE_VAR(TYPE, NAME, VALUE) \
inline TYPE & get_static_##NAME() \
{ \
static TYPE NAME = VALUE; \
return NAME; \
}
#else // CGAL_HEADER_ONLY
#define CGAL_GLOBAL_STATE_VAR(TYPE, NAME, VALUE) \
CGAL_EXPORT extern TYPE NAME; \
inline TYPE& get_static_##NAME() \
{ \
return NAME; \
}
#endif // CGAL_HEADER_ONLY
namespace CORE {
//////////////////////////////////////////////////////////////
@ -60,34 +87,34 @@ namespace CORE {
/** The normal behavior is to abort when an invalid expression
* is constructed. This flag can be used to turn off this abort.
* In any case, an error message will be printed */
CGAL_CORE_EXPORT extern bool AbortFlag;
CGAL_GLOBAL_STATE_VAR(bool, AbortFlag, true)
/// Invalid Flag -- initiallly value is non-negative
/** If the Abort Flag is false, then the Invalid flag will be set to
* a negative value whenever an invalid expression is constructed.
* It is the user's responsibility to check this flag and to make
* it non-negative again. */
CGAL_CORE_EXPORT extern int InvalidFlag;
CGAL_GLOBAL_STATE_VAR(int, InvalidFlag, 0)
/// Escape Precision in bits
CGAL_CORE_EXPORT extern extLong EscapePrec;
CGAL_GLOBAL_STATE_VAR(extLong, EscapePrec, CORE_posInfty)
/// current ur when EscapePrec triggered
/** this flag becomes negative when default EscapePrec is applied */
CGAL_CORE_EXPORT extern long EscapePrecFlag;
CGAL_GLOBAL_STATE_VAR(long, EscapePrecFlag, 0)
/// Escape Precision Warning Flag
/** this flag is true by default, and will cause a warning to be printed
when EscapePrec is reached */
CGAL_CORE_EXPORT extern bool EscapePrecWarning;
CGAL_GLOBAL_STATE_VAR(bool, EscapePrecWarning, true)
// These following two values determine the precision of computing
// approximations in Expr.
/// default Relative Precision in bits
CGAL_CORE_EXPORT extern extLong defRelPrec;
CGAL_GLOBAL_STATE_VAR(extLong, defRelPrec, 60)
/// default Absolute Precision in bits
CGAL_CORE_EXPORT extern extLong defAbsPrec;
CGAL_GLOBAL_STATE_VAR(extLong, defAbsPrec, CORE_posInfty)
/// default # of decimal digits for conversion from a BF to string.
/** This value cannot be CORE_INFTY.
@ -97,42 +124,41 @@ CGAL_CORE_EXPORT extern extLong defAbsPrec;
"controls the printout precision of std::cout for BigFloat"
Perhaps, we should merge defOutputDigits and defBigFloatOutputDigits?
*/
CGAL_CORE_EXPORT extern long defBigFloatOutputDigits;
CGAL_GLOBAL_STATE_VAR(long, defBigFloatOutputDigits, 10)
/// default input precision in digits for converting a string to a Real or Expr
/** This value can be CORE_INFTY */
CGAL_CORE_EXPORT extern extLong defInputDigits;
CGAL_GLOBAL_STATE_VAR(extLong, defInputDigits, CORE_posInfty)
/// controls the printout precision of std::cout for Real and Expr
/** This value cannot be CORE_INFTY
See also defBigFloatOutputDigits.
(it really should be an int, as in std::cout.setprecision(int)). */
CGAL_CORE_EXPORT extern long defOutputDigits;
CGAL_GLOBAL_STATE_VAR(long, defOutputDigits, get_static_defBigFloatOutputDigits())
/// default input precision in digits for converting a string to a BigFloat
/** This value cannot be CORE_INFTY. */
CGAL_CORE_EXPORT extern long defBigFloatInputDigits;
CGAL_GLOBAL_STATE_VAR(long, defBigFloatInputDigits, 16)
/// default BigFloat Division Relative Precision
CGAL_CORE_EXPORT extern extLong defBFdivRelPrec;
CGAL_GLOBAL_STATE_VAR(extLong, defBFdivRelPrec, 54)
/// default BigFloat Sqrt Absolute Precision
CGAL_CORE_EXPORT extern extLong defBFsqrtAbsPrec;
CGAL_GLOBAL_STATE_VAR(extLong, defBFsqrtAbsPrec, 54)
//////////////////////////////////////////////////////////////
// Mode parameters: incremental, progressive, filters
//////////////////////////////////////////////////////////////
/// floating point filter flag
CGAL_CORE_EXPORT extern bool fpFilterFlag;
CGAL_GLOBAL_STATE_VAR(bool, fpFilterFlag, true)
/// if true, evaluation of expressions would be incremental
CGAL_CORE_EXPORT extern bool incrementalEvalFlag;
CGAL_GLOBAL_STATE_VAR(bool, incrementalEvalFlag, true)
/// progressive evaluation flag
CGAL_CORE_EXPORT extern bool progressiveEvalFlag;
CGAL_GLOBAL_STATE_VAR(bool, progressiveEvalFlag, true)
/// rational reduction flag
CGAL_CORE_EXPORT extern bool rationalReduceFlag;
CGAL_GLOBAL_STATE_VAR(bool, rationalReduceFlag, false)
/// default initial (bit) precision for AddSub Progressive Evaluation
CGAL_CORE_EXPORT extern long defInitialProgressivePrec;
CGAL_GLOBAL_STATE_VAR(long, defInitialProgressivePrec, 64)
//////////////////////////////////////////////////////////////
// methods for setting global precision parameters
@ -144,87 +170,87 @@ CGAL_CORE_EXPORT extern long defInitialProgressivePrec;
/** It determines the precision to which an Expr evaluates its
(exact, implicit) constant value. */
inline void setDefaultPrecision(const extLong &r, const extLong &a) {
defRelPrec = r;
defAbsPrec = a;
get_static_defRelPrec() = r;
get_static_defAbsPrec() = a;
}
/// set default relative precision
inline extLong setDefaultRelPrecision(const extLong &r) {
extLong old = defRelPrec;
defRelPrec = r;
extLong old = get_static_defRelPrec();
get_static_defRelPrec() = r;
return old;
}
/// set default absolute precision
inline extLong setDefaultAbsPrecision(const extLong &a) {
extLong old = defAbsPrec;
defAbsPrec = a;
extLong old = get_static_defAbsPrec();
get_static_defAbsPrec() = a;
return old;
}
/// set default input digits (for Expr, Real)
/** it controls the absolute error */
inline extLong setDefaultInputDigits(const extLong &d) {
extLong old = defInputDigits;
defInputDigits = d;
extLong old = get_static_defInputDigits();
get_static_defInputDigits() = d;
return old;
}
/// set default output digits (for Expr, Real)
inline long setDefaultOutputDigits(long d = defOutputDigits,
inline long setDefaultOutputDigits(long d = get_static_defOutputDigits(),
std::ostream& o = std::cout) {
long old = defOutputDigits;
defOutputDigits = d;
long old = get_static_defOutputDigits();
get_static_defOutputDigits() = d;
o.precision(d);
return old;
}
/// set default input digits for BigFloat
inline long setDefaultBFInputDigits(long d) {
long old = defBigFloatInputDigits;
defBigFloatInputDigits = d;
long old = get_static_defBigFloatInputDigits();
get_static_defBigFloatInputDigits() = d;
return old;
}
/// set default output digits for BigFloat
inline long setDefaultBFOutputDigits(long d) {
long old = defBigFloatOutputDigits;
defBigFloatOutputDigits = d;
long old = get_static_defBigFloatOutputDigits();
get_static_defBigFloatOutputDigits() = d;
return old;
}
/// turn floating-point filter on/off
inline bool setFpFilterFlag(bool f) {
bool oldf = fpFilterFlag;
fpFilterFlag = f;
bool oldf = get_static_fpFilterFlag();
get_static_fpFilterFlag() = f;
return oldf;
}
/// turn incremental evaluation flag on/off
inline bool setIncrementalEvalFlag(bool f) {
bool oldf = incrementalEvalFlag;
incrementalEvalFlag = f;
bool oldf = get_static_incrementalEvalFlag();
get_static_incrementalEvalFlag() = f;
return oldf;
}
/// turn progressive evaluation flag on/off
inline bool setProgressiveEvalFlag(bool f) {
bool oldf = progressiveEvalFlag;
progressiveEvalFlag = f;
bool oldf = get_static_progressiveEvalFlag();
get_static_progressiveEvalFlag() = f;
return oldf;
}
/// set initial bit precision for progressive evaluation:
inline long setDefInitialProgressivePrec(long n) {
long oldn = defInitialProgressivePrec;
defInitialProgressivePrec = n;
long oldn = get_static_defInitialProgressivePrec();
get_static_defInitialProgressivePrec() = n;
return oldn;
}
/// turn rational reduction flag on/off
inline bool setRationalReduceFlag(bool f) {
bool oldf = rationalReduceFlag;
rationalReduceFlag = f;
bool oldf = get_static_rationalReduceFlag();
get_static_rationalReduceFlag() = f;
return oldf;
}
@ -235,9 +261,9 @@ inline bool setRationalReduceFlag(bool f) {
e.g., overriding the default std::cout precision (most systems
initializes this value to 6) to our own */
inline void CORE_init(long d) {
defAbsPrec = CORE_posInfty;
defOutputDigits = d;
std::setprecision(defOutputDigits);
get_static_defAbsPrec() = CORE_posInfty;
get_static_defOutputDigits() = d;
std::setprecision(get_static_defOutputDigits());
}
/// change to scientific output format
@ -251,4 +277,9 @@ inline void setPositionalFormat(std::ostream& o = std::cout) {
}
} //namespace CORE
#ifdef CGAL_HEADER_ONLY
#include <CGAL/CORE/CoreDefs_impl.h>
#endif // CGAL_HEADER_ONLY
#endif // _CORE_COREDEFS_H_

View File

@ -0,0 +1,170 @@
/****************************************************************************
* Core Library Version 1.7, August 2004
* Copyright (c) 1995-2004 Exact Computation Project
* All rights reserved.
*
* This file is part of CORE (http://cs.nyu.edu/exact/core/).
* You can redistribute it and/or modify it under the terms of the GNU
* General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* Licensees holding a valid commercial license may use this file in
* accordance with the commercial license agreement provided with the
* software.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
*
* File: CoreDefs.cpp
* Synopsis:
* Useful parameters for Core Library which users may change
*
* Written by
* Chee Yap <yap@cs.nyu.edu>
* Chen Li <chenli@cs.nyu.edu>
* Zilin Du <zilin@cs.nyu.edu>
*
* WWW URL: http://cs.nyu.edu/exact/
* Email: exact@cs.nyu.edu
*
* $URL$
* $Id$
***************************************************************************/
#include "CGAL/CORE/CoreDefs.h"
#ifdef CGAL_HEADER_ONLY
#undef CGAL_EXPORT // CJTODO: TEMPORARY
#undef CGAL_CORE_EXPORT
#define CGAL_EXPORT
#define CGAL_CORE_EXPORT
#endif
namespace CORE {
// Default Values
/* ************************************************************
* ERROR FLAGS
* ************************************************************ */
#ifndef CGAL_HEADER_ONLY
/** I/O error flag (Default value 0, indicating no error)
* User's responsibility to check and reset value to 0. */
// This is currently used in geom2d/points2d.cpp for I/O of points
// Note from 2014: does not seem to be used anywhere, and it is not declared
// in CoreDefs.h so it is not accessible
// Left here for compatibilty when CGAL_HEADER_ONLY is not defined
int IOErrorFlag = 0;
/**
* If AbortFlag is true when invalid expression is constructed, system will abort
*/
bool AbortFlag = true;
/**
* InvalidFlag is set to negative whenever an invalid expression is constructed.
* The user has the responsibility to reset to non-negative value.
*/
int InvalidFlag = 0;
/* ************************************************************
* PRECISION PARAMETERS
* ************************************************************ */
/**
* Default BigFloat Division Relative Precision
* -- this is used by BigFloat division when the arguments are error-free.
*/
extLong defBFdivRelPrec = 54;
/**
* Default BigFloat Sqrt Absolute Precision
* -- this is used by BigFloat sqrt when the argument is error-free.
*/
extLong defBFsqrtAbsPrec = 54;
/**
* Escape Precision
* -- we will not compare a number to precision higher than this
* -- if this is infinity, there there is no escape precision */
extLong EscapePrec = CORE_posInfty;
/** this flag becomes negative if the EscapePrec is used. */
long EscapePrecFlag = 0;
/// Escape Precision Warning Flag
/** this flag is true by default, and will cause a warning to be printed
when EscapePrec is reached */
bool EscapePrecWarning = true;
/** The Composite Precision [defAbsPrec, defRelPrec]
* determines the precision to which an Expr evaluates its
* (exact, implicit) constant value. */
/** absolute precision = 2^31 - 1 */
extLong defAbsPrec = CORE_posInfty;
/** default relative precision is 60 relative bits.
* Why 60? We would really like this to be 54, so that the default
* conversion duplicates the IEEE double precision. But it turns out
* (see README file under BUGS), we need 59 to ensure this.
* Chee Yap (7/1/01) */
extLong defRelPrec = 60;
/** number of BigFloat digits to print out */
long defBigFloatOutputDigits = 10;
/** NORMALLY, we like to make this equal to defBigFloatOutputDigits
* 8/3/01, Chee: re-introduced this parameter */
long defOutputDigits = defBigFloatOutputDigits;
/** String Input Precision */
/** Set this to 16 if you want machine precision. This controls the
* absolute error in string decimal inputs to Real or Expr.
* If defInputDigits is finite, then the absolute error will be
* at most 10^{-defInputDigits}. Otherwise, the input is exactly
* represented by some BigFloat or BigRat value. */
extLong defInputDigits = CORE_posInfty;
/** This controls the absolute error in converting from string to BigFloat
* The absolute error will be at most 10^{-defInputDigits} */
long defBigFloatInputDigits = 16;
/* ************************************************************
* EVALUATION FLAGS
* ************************************************************ */
/** Floating Point filter
* true = turn on floating point filter */
bool fpFilterFlag = true;
/** IncrementaL evaluation flag
* incremental evaluation is requested, This means, we try to use previous
* approximate values to improve an approximation */
bool incrementalEvalFlag = true;
/** Progressive evaluation flag
* true = turn on progressive evaluation flag */
bool progressiveEvalFlag = true;
/** Initial progressive evaluation precision
* Used by AddSubRep */
long defInitialProgressivePrec = 64;
/** RATIONAL REDUCTION FLAG
* true = turn on rational reduction */
bool rationalReduceFlag = false;
#endif // CGAL_HEADER_ONLY
} //namespace CORE

View File

@ -0,0 +1,488 @@
/****************************************************************************
* Core Library Version 1.7, August 2004
* Copyright (c) 1995-2004 Exact Computation Project
* All rights reserved.
*
* This file is part of CORE (http://cs.nyu.edu/exact/core/).
* You can redistribute it and/or modify it under the terms of the GNU
* General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* Licensees holding a valid commercial license may use this file in
* accordance with the commercial license agreement provided with the
* software.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
*
* File: CoreIO.cpp
*
* Written by
* Zilin Du <zilin@cs.nyu.edu>
* Chee Yap <yap@cs.nyu.edu>
*
* WWW URL: http://cs.nyu.edu/exact/
* Email: exact@cs.nyu.edu
*
* $URL$
* $Id$
***************************************************************************/
#ifndef _COREIO_IMPL_H_
#define _COREIO_IMPL_H_
#ifdef CGAL_HEADER_ONLY
#define CGAL_INLINE_FUNCTION inline
#else
#define CGAL_INLINE_FUNCTION
#endif
#ifdef CGAL_HEADER_ONLY
#define CGAL_HEADERONLY_STATIC_FUNCTION static
#else
#define CGAL_HEADERONLY_STATIC_FUNCTION
#endif
#include <CGAL/CORE/BigFloatRep.h>
#include <CGAL/CORE/BigFloat.h>
#include <CGAL/CORE/BigInt.h>
namespace CORE {
CGAL_HEADERONLY_STATIC_FUNCTION
void core_io_error_handler(const char *f, const char *m) {
std::cout << "\n error_handler";
std::cout << "::" << f << "::" << m << "\n";
std::cout.flush();
std::abort();
}
CGAL_HEADERONLY_STATIC_FUNCTION
void core_io_memory_handler(char *t, const char *f, const char *m) {
if (t == NULL) {
std::cout << "\n memory_handler";
std::cout << "::" << f << "::" << m;
std::cout << "memory exhausted\n";
std::cout.flush();
std::abort();
}
}
// s has size old_size and will be resized to new_size.
CGAL_HEADERONLY_STATIC_FUNCTION
void allocate (char * &s, int old_size, int new_size) {
if (old_size > new_size)
old_size = new_size;
if (s == NULL)
old_size = 0;
char *t = new char[new_size];
core_io_memory_handler(t, "CoreIO", "allocate::out of memory error");
int i;
for (i = 0; i < old_size; i++)
t[i] = s[i];
delete[] s;
s = t;
}
// appends c to s at position pos.
// sz is the size of s
CGAL_HEADERONLY_STATIC_FUNCTION
void append_char (char * &s, int & sz, int pos, char c) {
if (pos > sz)
core_io_error_handler("CoreIO", "append_char::invalid argument");
if (pos == sz) {
allocate(s, sz, 2*sz);
sz *= 2;
}
s[pos] = c;
}
// skip blanks, tabs, line breaks and comment lines
CGAL_HEADERONLY_STATIC_FUNCTION
int skip_comment_line (std::istream & in) {
int c;
do {
c = in.get();
while ( c == '#' ) {
do {
c = in.get();
} while ( c != '\n' );
c = in.get();
}
} while (c == ' ' || c == '\t' || c == '\n');
if (c == EOF)
core_io_error_handler("CoreIO::read_from_file()","unexpected end of file.");
in.putback(c);
return c;
}
// skips '\\' followed by '\n'
CGAL_HEADERONLY_STATIC_FUNCTION
int skip_backslash_new_line (std::istream & in) {
int c = in.get();
while (c == '\\') {
c = in.get();
if (c == '\n')
c = in.get();
else
core_io_error_handler("CoreIO::operator>>", "\\ must be immediately followed by new line.");
}
return c;
}
CGAL_HEADERONLY_STATIC_FUNCTION
void read_string(std::istream& in, char* &buffer, int sz) {
int c, pos=0;
skip_comment_line(in);
while ( (c = in.get()) != EOF ) {
if ( c == ' ' || c == '\t' || c == '\n' || c == '#')
break;
else
append_char(buffer, sz, pos++, c);
}
append_char(buffer, sz, pos, '\0');
}
CGAL_HEADERONLY_STATIC_FUNCTION
void read_base_number(std::istream& in, BigInt& m, long length, long maxBits) {
char *buffer;
int size, offset;
int base;
bool is_negate;
int c, pos = 0;
skip_comment_line(in);
// read sign
c = in.get();
if (c == '-') {
is_negate = true;
c = in.get();
} else
is_negate = false;
// read base and compute digits
if (c == '0') {
c = in.get();
if (c == 'b') {
base = 2;
size = (maxBits == 0 || maxBits > length) ? length : maxBits;
offset = length - size;
} else if (c == 'x') {
base = 16;
size = (maxBits == 0) ? length : (maxBits+3) >> 2;
size = (size > length) ? length : size;
offset = (length - size) << 2;
} else {
base = 8;
size = (maxBits == 0) ? length : (maxBits+2) / 3;
size = (size > length) ? length : size;
offset = (length - size) * 3;
in.putback(c);
}
} else {
base = 10;
size = (maxBits == 0) ? length : (int)std::ceil(maxBits*std::log(2.0)/std::log(10.0));
size = (size > length) ? length : size;
offset = length - size;
in.putback(c);
}
buffer = new char[size+2];
// read digits
for (int i=0; (i<size)&&((c=skip_backslash_new_line(in)) != EOF ); i++) {
if (c != ' ' && c != '\t' && c != '\n')
append_char(buffer, size, pos++, c);
}
if (base == 10) {
for(int j=0; j<offset; j++)
append_char(buffer, size, pos++, '0');
}
append_char(buffer, size, pos, '\0');
// convert string to bigint.
if (m.set_str(buffer, base) < 0)
core_io_error_handler("CoreIO::read_from_file()","bad big number format.");
delete[] buffer;
// shift left if neccessary
if (offset > 0 && base != 10) {
m <<= offset;
}
if (is_negate)
negate(m);
}
CGAL_HEADERONLY_STATIC_FUNCTION
void write_base_number(std::ostream& out, char* buffer, int length, int base, int charsPerLine) {
// write big number in a format that gmp's mpz_set_str() can
// automatically recognize with argument base = 0.
if (base == 2)
out << "0b";
else if (base == 16)
out << "0x";
else if (base == 8)
out << '0';
// write big number in charsPerLine.
char* start, *end, c;
for (int i=0; i<length; i += charsPerLine) {
start = buffer + i;
if (i + charsPerLine >= length)
out << start;
else {
end = start + charsPerLine;
c = *end;
*end = '\0';
out << start << "\\\n";
*end = c;
}
}
}
CGAL_INLINE_FUNCTION
void readFromFile(BigInt& z, std::istream& in, long maxLength) {
char *buffer;
long length;
// check type name whether it is Integer or not.
buffer = new char[8];
read_string(in, buffer, sizeof(buffer));
if ( std::strcmp(buffer, "Integer") != 0)
core_io_error_handler("BigInt::read_from_file()","type name expected.");
delete[] buffer;
// read the bit length field.
buffer = new char[100];
read_string(in, buffer, sizeof(buffer));
length = std::atol(buffer);
delete[] buffer;
// read bigint
read_base_number(in, z, length, maxLength);
}
CGAL_INLINE_FUNCTION
void writeToFile(const BigInt& z, std::ostream& out, int base, int charsPerLine) {
BigInt c = abs(z);
// get the absoulte value string
char* buffer = new char[mpz_sizeinbase(c.get_mp(), base) + 2];
mpz_get_str(buffer, base, c.get_mp());
int length = std::strlen(buffer);
// write type name of big number and length
//out << "# This is an experimental big number format.\n";
out << "Integer " << length << "\n";
// if bigint is negative, then write an sign '-'.
if ( sign(z) < 0 )
out << '-';
write_base_number(out, buffer, length, base, charsPerLine);
out << "\n";
delete[] buffer;
}
CGAL_INLINE_FUNCTION
void readFromFile(BigFloat& bf, std::istream& in, long maxLength) {
char *buffer;
long length;
long exponent;
BigInt mantissa;
// check type name whether it is Float
buffer = new char[6];
read_string(in, buffer, sizeof(buffer));
if (std::strcmp(buffer, "Float") != 0)
core_io_error_handler("BigFloat::read_from_file()", "type name expected");
delete[] buffer;
// read base (default is 16384)
buffer = new char[8];
read_string(in, buffer, sizeof(buffer));
if (std::strcmp(buffer, "(16384)") != 0)
core_io_error_handler("BigFloat::read_from_file()", "base expected");
delete[] buffer;
// read the bit length field.
buffer = new char[100];
read_string(in, buffer, sizeof(buffer));
length = std::atol(buffer);
delete[] buffer;
// read exponent
buffer = new char[100];
read_string(in, buffer, sizeof(buffer));
exponent = std::atol(buffer);
delete[] buffer;
// read mantissa
read_base_number(in, mantissa, length, maxLength);
// construct BigFloat
bf = BigFloat(mantissa, 0, exponent);
}
CGAL_INLINE_FUNCTION
void writeToFile(const BigFloat& bf, std::ostream& out, int base, int charsPerLine) {
BigInt c(CORE::abs(bf.m()));
// get the absoulte value string
char* buffer = new char[mpz_sizeinbase(c.get_mp(), base) + 2];
mpz_get_str(buffer, base, c.get_mp());
int length = std::strlen(buffer);
// write type name, base, length
//out << "# This is an experimental Big Float format." << std::endl;
out << "Float (16384) " << length << std::endl;
// write exponent
out << bf.exp() << std::endl;
// write mantissa
if ( CORE::sign(bf.m()) < 0 )
out << '-';
write_base_number(out, buffer, length, base, charsPerLine);
out << '\n';
delete[] buffer;
}
/* Underconstruction ----
void BigFloat::read_from_file2(std::istream& in, long maxLength) {
long length = 1024;
char *buffer;
// check type name whether it is Float
buffer = new char[7];
BigInt::read_string(in, buffer, sizeof(buffer));
if (strcmp(buffer, "NFloat") != 0)
core_io_error_handler("BigFloat::read_from_file2()", "type name expected");
delete[] buffer;
// read base (default is 16)
buffer = new char[5];
BigInt::read_string(in, buffer, sizeof(buffer));
if (strcmp(buffer, "(16)") != 0)
core_io_error_handler("BigFloat::read_from_file2()", "base expected");
delete[] buffer;
// read length field
buffer = new char[100];
BigInt::read_string(in, buffer, sizeof(buffer));
// get the length field if it is not null.
if (buffer[0] != '\0') {
length = atol(buffer);
if (maxLength > 0 && length >= maxLength)
length = maxLength;
}
delete[] buffer;
// read exponent
buffer = new char[100];
BigInt::read_string(in, buffer, sizeof(buffer));
long exp16 = atol(buffer);
delete[] buffer;
// read mantissa
buffer = new char[length+2];
//BigInt::read_base_number(in, buffer, length);
BigInt m16(buffer);
delete[] buffer;
// convert to base CHUNK_BIT
exp16 = exp16 - length + 1;
if ( m16.is_negative() )
exp16 ++;
long tmp_exp = exp16 * 4;
long q = tmp_exp / CHUNK_BIT;
long r = tmp_exp % CHUNK_BIT;
if ( r < 0 ) {
r += CHUNK_BIT;
q --;
}
BigInt mantissa = m16 << r;
long exponent = q;
// construct BigFloat
if (--rep->refCount == 0)
delete rep;
rep = new BigFloatRep(mantissa, 0, exponent);
rep->refCount++;
}
// write normal float
// now it assumed to write in hex base, i.e. B=2^4=16
// (note: our default base B=2^(CHUNK_BIT)=2^14=16384
void BigFloat::write_to_file2(std::ostream& out, int base, int charsPerLine) {
// convert to base 16.
long new_base = 4; // 2^4 = 16
long tmp_exp = (rep->exp) * CHUNK_BIT;
long q = tmp_exp / new_base;
long r = tmp_exp % new_base;
std::cout << "CORE_DEBUG: q=" << q << ", r=" << r << std::endl;
if ( r < 0 ) {
r += new_base;
q--;
}
std::cout << "CORE_DEBUG: q=" << q << ", r=" << r << std::endl;
BigInt m16 = (rep->m) << r;
int size = mpz_sizeinbase(m16.I, base) + 2;
std::cout << "size=" << size << std::endl;
char* buffer = new char[size];
int length = bigint_to_string(m16, buffer, base);
std::cout << "length=" << length << std::endl;
long exp16 = q + length - 1;
if ( m16.is_negative() )
exp16 --;
// write type name, base, length
out << "# This is an experimental Big Float format." << std::endl;
out << "NFloat (16) " << length << std::endl;
// write exponent
out << exp16 << std::endl;
// write mantissa
if ( m16.is_negative() ) {
out << '-';
buffer ++;
}
BigInt::write_base_number(out, buffer, length, base, charsPerLine);
out << '\n';
delete[] buffer;
}
*/
} //namespace CORE
#endif // _COREIO_IMPL_H_

View File

@ -36,11 +36,22 @@
* $Id$
***************************************************************************/
// We need to include BigFloat.h here because there is a circular dependency
// between Expr and BigFloat.
#include <CGAL/CORE/BigFloat.h>
#ifndef _CORE_EXPR_H_
#define _CORE_EXPR_H_
#include <CGAL/CORE/ExprRep.h>
#ifdef CGAL_HEADER_ONLY
#undef CGAL_EXPORT // CJTODO: TEMPORARY
#undef CGAL_CORE_EXPORT
#define CGAL_EXPORT
#define CGAL_CORE_EXPORT
#endif
namespace CORE {
/// \class Expr Expr.h
@ -78,9 +89,9 @@ public:
// (i.e., not infinite and not NaN)
if (! CGAL_CORE_finite(f)) {
std::cerr << " ERROR : constructed an invalid float! " << std::endl;
if (AbortFlag)
if (get_static_AbortFlag())
abort();
InvalidFlag = -1;
get_static_InvalidFlag() = -1;
}
rep = new ConstDoubleRep(f);
}
@ -89,9 +100,9 @@ public:
// (i.e., not infinite and not NaN)
if (! CGAL_CORE_finite(d)) {
std::cerr << " ERROR : constructed an invalid double! " << std::endl;
if (AbortFlag)
if (get_static_AbortFlag())
abort();
InvalidFlag = -2;
get_static_InvalidFlag() = -2;
}
rep = new ConstDoubleRep(d);
}
@ -111,11 +122,11 @@ public:
* it is generally recommended that the (String) constructor be used in
* preference to the (double) constructor.
*/
Expr(const char *s, const extLong& p = defInputDigits)
Expr(const char *s, const extLong& p = get_static_defInputDigits())
: RCExpr(new ConstRealRep(Real(s, p))) {}
/// constructor for <tt>std::string</tt>
Expr(const std::string& s, const extLong& p = defInputDigits)
Expr(const std::string& s, const extLong& p = get_static_defInputDigits())
: RCExpr(new ConstRealRep(Real(s, p))) {}
/// constructor for <tt>Real</tt>
@ -179,9 +190,9 @@ public:
Expr& operator/=(const Expr& e) {
if ((e.rep)->getSign() == 0) {
std::cerr << " ERROR : division by zero ! " << std::endl;
if (AbortFlag)
if (get_static_AbortFlag())
abort();
InvalidFlag = -3;
get_static_InvalidFlag() = -3;
}
*this = new DivRep(rep, e.rep);
return *this;
@ -225,12 +236,12 @@ public:
/// \name String Conversion Functions
//@{
/// set value from <tt>const char*</tt>
void fromString(const char* s, const extLong& prec = defInputDigits) {
void fromString(const char* s, const extLong& prec = get_static_defInputDigits()) {
*this = Expr(s, prec);
}
/// convert to <tt>std::string</tt>
/** give decimal string representation */
std::string toString(long prec=defOutputDigits, bool sci=false) const {
std::string toString(long prec=get_static_defOutputDigits(), bool sci=false) const {
return rep->toString(prec, sci);
}
//@}
@ -282,8 +293,8 @@ public:
/** Here is the definition of what this means:
If e is the exact value and ee is the approximate value,
then |e - ee| <= 2^{-a} or |e - ee| <= 2^{-r} |e|. */
const Real & approx(const extLong& relPrec = defRelPrec,
const extLong& absPrec = defAbsPrec) const {
const Real & approx(const extLong& relPrec = get_static_defRelPrec(),
const extLong& absPrec = get_static_defAbsPrec()) const {
return rep->getAppValue(relPrec, absPrec);
}
//@}
@ -355,7 +366,7 @@ inline std::ostream& operator<<(std::ostream& o, const Expr& e) {
/// I/O Stream operator>>
inline std::istream& operator>>(std::istream& i, Expr& e) {
Real rVal;
i >> rVal; // precision is = defInputDigits
i >> rVal; // precision is = get_static_defInputDigits()
if (i)
e = rVal; // only assign when reading is successful.
return i;
@ -382,9 +393,9 @@ inline Expr operator*(const Expr& e1, const Expr& e2) {
inline Expr operator/(const Expr& e1, const Expr& e2) {
if (e2.sign() == 0) {
std::cerr << " ERROR : division by zero ! " << std::endl;
if (AbortFlag)
if (get_static_AbortFlag())
abort();
InvalidFlag = -4;
get_static_InvalidFlag() = -4;
}
return Expr(new DivRep(e1.Rep(), e2.Rep()));
}
@ -485,9 +496,9 @@ inline bool isDivisible(const Expr& e1, const Expr& e2) {
inline Expr sqrt(const Expr& e) {
if (e.sign() < 0) {
std::cerr << " ERROR : sqrt of negative value ! " << std::endl;
if (AbortFlag)
if (get_static_AbortFlag())
abort();
InvalidFlag = -5;
get_static_InvalidFlag() = -5;
}
return Expr(new SqrtRep(e.Rep()));
}
@ -548,4 +559,9 @@ inline Expr radical(const NT& n, int m) {
#include <CGAL/CORE/poly/Poly.tcc>
} //namespace CORE
#ifdef CGAL_HEADER_ONLY
#include <CGAL/CORE/Expr_impl.h>
#endif // CGAL_HEADER_ONLY
#endif // _CORE_EXPR_H_

View File

@ -43,9 +43,16 @@
#include <CGAL/CORE/Filter.h>
#include <CGAL/CORE/poly/Sturm.h>
#ifdef CGAL_HEADER_ONLY
#undef CGAL_EXPORT // CJTODO: TEMPORARY
#undef CGAL_CORE_EXPORT
#define CGAL_EXPORT
#define CGAL_CORE_EXPORT
#endif
namespace CORE {
#ifdef CORE_DEBUG_BOUND
#if defined(CORE_DEBUG_BOUND) && !defined(CGAL_HEADER_ONLY)
// These counters are incremented each time each bound is recognized as equal
// to the best one in computeBound().
extern unsigned int BFMSS_counter;
@ -189,8 +196,8 @@ public:
/// \name Helper Functions
//@{
/// Get the approximate value
CGAL_CORE_EXPORT const Real & getAppValue(const extLong& relPrec = defRelPrec,
const extLong& absPrec = defAbsPrec);
CGAL_CORE_EXPORT const Real & getAppValue(const extLong& relPrec = get_static_defRelPrec(),
const extLong& absPrec = get_static_defAbsPrec());
/// Get the sign.
int getSign();
int getExactSign();
@ -389,8 +396,8 @@ public:
BigFloat BigFloatValue();
/// represent as a string in decimal value
// toString() Joaquin Grech 31/5/2003
std::string toString(long prec=defOutputDigits, bool sci=false) {
return (getAppValue(defRelPrec, defAbsPrec)).toString(prec,sci);
std::string toString(long prec=get_static_defOutputDigits(), bool sci=false) {
return (getAppValue(get_static_defRelPrec(), get_static_defAbsPrec())).toString(prec,sci);
}
//@}
@ -677,7 +684,7 @@ protected:
tc() = ceilLg(ss.seq[0].getTailCoeff());
// no rational reduction
if (rationalReduceFlag)
if (get_static_rationalReduceFlag())
ratFlag() = -1;
flagsComputed() = true;
@ -838,7 +845,12 @@ protected:
/// \brief "functor" class used as parameter to AddSubRep<>
struct Add {
/// name
#ifndef CGAL_HEADER_ONLY
CGAL_CORE_EXPORT static const char* name;
#endif
static const char* get_name() {
return "+";
}
/// unary operator
template <class T>
@ -857,7 +869,12 @@ struct Add {
/// \brief "functor" class used as parameter to AddSubRep<>
struct Sub {
/// name
#ifndef CGAL_HEADER_ONLY
CGAL_CORE_EXPORT static const char* name;
#endif
static const char* get_name() {
return "-";
}
/// unary operator
template <class T>
@ -895,7 +912,7 @@ protected:
void computeApproxValue(const extLong&, const extLong&);
/// return operator in string
const std::string op() const {
return Operator::name;
return Operator::get_name();
}
private:
static Operator Op;
@ -925,7 +942,7 @@ void AddSubRep<Operator>::computeExactFlags() {
reduceTo(second);
sign() = Op(ss);
appValue() = Op(appValue());
if (rationalReduceFlag && ratFlag() > 0)
if (get_static_rationalReduceFlag() && ratFlag() > 0)
*(ratValue()) = Op(*(ratValue()));
return;
} else if (ss == 0) { // second operand is zero
@ -933,7 +950,7 @@ void AddSubRep<Operator>::computeExactFlags() {
return;
}
// rational node
if (rationalReduceFlag) {
if (get_static_rationalReduceFlag()) {
if (first->ratFlag() > 0 && second->ratFlag() > 0) {
BigRat val=Op(*(first->ratValue()), *(second->ratValue()));
reduceToBigRat(val);
@ -1046,7 +1063,7 @@ void AddSubRep<Operator>::computeExactFlags() {
if (lowBound <= EXTLONG_ZERO)
lowBound = EXTLONG_ONE;
if (!progressiveEvalFlag) {
if (!get_static_progressiveEvalFlag()) {
// convert the absolute error requirement "lowBound" to
// a relative error requirement "ur", s.t.
// |x|*2^(-ur) <= 2^(-lowBound).
@ -1085,7 +1102,7 @@ void AddSubRep<Operator>::computeExactFlags() {
// larger than lowBound AND the defaultInitialProgressivePrec,
// so that we do at least one iteration of the for-loop. So:
// i is the variable for iteration.
extLong i = core_min(defInitialProgressivePrec, lowBound.asLong());
extLong i = core_min(get_static_defInitialProgressivePrec(), lowBound.asLong());
extLong ua = lowBound.asLong() + EXTLONG_ONE;
// NOTE: ua is allowed to be CORE_INFTY
@ -1096,7 +1113,7 @@ void AddSubRep<Operator>::computeExactFlags() {
lMSB() = CORE_negInfty;
sign() = 0;
EscapePrecFlag = 0; // reset the Escape Flag
get_static_EscapePrecFlag() = 0; // reset the Escape Flag
// Now we try to determine the real lMSB and sign,
// in case it is not really zero:
@ -1151,22 +1168,22 @@ void AddSubRep<Operator>::computeExactFlags() {
break; // assert -- this must happen in the loop if nonzero!
}
//8/9/01, Chee: implement escape precision here:
if (i> EscapePrec) {
EscapePrecFlag = -i.asLong();//negative means EscapePrec is used
if (i> get_static_EscapePrec()) {
get_static_EscapePrecFlag() = -i.asLong();//negative means EscapePrec is used
core_error("Escape precision triggered at",
__FILE__, __LINE__, false);
if (EscapePrecWarning)
if (get_static_EscapePrecWarning())
std::cout<< "Escape Precision triggered at "
<< EscapePrec << " bits" << std::endl;
<< get_static_EscapePrec() << " bits" << std::endl;
#ifdef CORE_DEBUG
std::cout << "EscapePrecFlags=" << EscapePrecFlag << std::endl;
std::cout << "EscapePrecFlags=" << get_static_EscapePrecFlag() << std::endl;
std::cout << "ua =" << ua << ",lowBound=" << lowBound << std::endl;
#endif
break;
}// if
}// for (long i=1...)
#ifdef CORE_DEBUG_BOUND
#if defined(CORE_DEBUG_BOUND) && !defined(CGAL_HEADER_ONLY)
rootBoundHitCounter++;
#endif

File diff suppressed because it is too large Load Diff

View File

@ -42,6 +42,13 @@
#include <CGAL/CORE/Real.h>
#include <cmath>
#ifdef CGAL_HEADER_ONLY
#undef CGAL_EXPORT // CJTODO: TEMPORARY
#undef CGAL_CORE_EXPORT
#define CGAL_EXPORT
#define CGAL_CORE_EXPORT
#endif
#if !defined CGAL_CFG_NO_CPP0X_ISFINITE
#define CGAL_CORE_finite(x) std::isfinite(x)
#elif defined (_MSC_VER) || defined (__MINGW32__) // add support for MinGW
@ -102,7 +109,7 @@ public:
}
/// check whether the sign (!) of the filtered value is OK
bool isOK() const {
return (fpFilterFlag && // To disable filter
return (get_static_fpFilterFlag() && // To disable filter
CGAL_CORE_finite(fpVal) && // Test for infinite and NaNs
(core_abs(fpVal) >= maxAbs*ind*CORE_EPS));
}

View File

@ -27,6 +27,13 @@
#include <CGAL/CORE/Impl.h>
#include <gmp.h>
#ifdef CGAL_HEADER_ONLY
#undef CGAL_EXPORT // CJTODO: TEMPORARY
#undef CGAL_CORE_EXPORT
#define CGAL_EXPORT
#define CGAL_CORE_EXPORT
#endif
namespace CORE {
CGAL_CORE_EXPORT std::ostream& io_write (std::ostream &, mpz_srcptr);
@ -39,4 +46,9 @@ CGAL_CORE_EXPORT std::istream& io_read (std::istream &, mpq_ptr);
//std::istream& operator>> (std::istream &, mpq_ptr);
} //namespace CORE
#ifdef CGAL_HEADER_ONLY
#include <CGAL/CORE/Gmp_impl.h>
#endif // CGAL_HEADER_ONLY
#endif // _CORE_GMP_H_

View File

@ -0,0 +1,280 @@
/****************************************************************************
* Core Library Version 1.7, August 2004
* Copyright (c) 1995-2004 Exact Computation Project
* All rights reserved.
*
* file: GmpIO.cpp
* Adapted from multi-files under /cxx in GMP's source distribution
*
* Zilin Du, 2003
*
* $URL$
* $Id$
***************************************************************************/
/* Auxiliary functions for C++-style input of GMP types.
Copyright 2001 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3 of the License, or (at your
option) any later version.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
#ifdef CGAL_HEADER_ONLY
#define CGAL_INLINE_FUNCTION inline
#else
#define CGAL_INLINE_FUNCTION
#endif
#include <CGAL/CORE/Gmp.h>
#include <cctype>
#include <iostream>
#include <string>
#include <cstdio>
using namespace std;
namespace CORE {
CGAL_INLINE_FUNCTION
int
__gmp_istream_set_base (istream &i, char &c, bool &zero, bool &showbase)
{
int base;
zero = showbase = false;
switch (i.flags() & ios::basefield)
{
case ios::dec:
base = 10;
break;
case ios::hex:
base = 16;
break;
case ios::oct:
base = 8;
break;
default:
showbase = true; // look for initial "0" or "0x" or "0X"
if (c == '0')
{
if (! i.get(c))
c = 0; // reset or we might loop indefinitely
if (c == 'x' || c == 'X')
{
base = 16;
i.get(c);
}
else
{
base = 8;
zero = true; // if no other digit is read, the "0" counts
}
}
else
base = 10;
break;
}
return base;
}
CGAL_INLINE_FUNCTION
void
__gmp_istream_set_digits (string &s, istream &i, char &c, bool &ok, int base)
{
switch (base)
{
case 10:
while (isdigit(c))
{
ok = true; // at least a valid digit was read
s += c;
if (! i.get(c))
break;
}
break;
case 8:
while (isdigit(c) && c != '8' && c != '9')
{
ok = true; // at least a valid digit was read
s += c;
if (! i.get(c))
break;
}
break;
case 16:
while (isxdigit(c))
{
ok = true; // at least a valid digit was read
s += c;
if (! i.get(c))
break;
}
break;
}
}
CGAL_INLINE_FUNCTION
istream &
//operator>> (istream &i, mpz_ptr z)
io_read (istream &i, mpz_ptr z)
{
int base;
char c = 0;
string s;
bool ok = false, zero, showbase;
i.get(c); // start reading
if (i.flags() & ios::skipws) // skip initial whitespace
while (isspace(c) && i.get(c))
;
if (c == '-' || c == '+') // sign
{
if (c == '-') // mpz_set_str doesn't accept '+'
s = "-";
i.get(c);
}
while (isspace(c) && i.get(c)) // skip whitespace
;
base = __gmp_istream_set_base(i, c, zero, showbase); // select the base
__gmp_istream_set_digits(s, i, c, ok, base); // read the number
if (i.good()) // last character read was non-numeric
i.putback(c);
else if (i.eof() && (ok || zero)) // stopped just before eof
i.clear();
if (ok)
mpz_set_str(z, s.c_str(), base); // extract the number
else if (zero)
mpz_set_ui(z, 0);
else
i.setstate(ios::failbit); // read failed
return i;
}
CGAL_INLINE_FUNCTION
istream &
//operator>> (istream &i, mpq_ptr q)
io_read (istream &i, mpq_ptr q)
{
int base;
char c = 0;
string s;
bool ok = false, zero, showbase;
i.get(c); // start reading
if (i.flags() & ios::skipws) // skip initial whitespace
while (isspace(c) && i.get(c))
;
if (c == '-' || c == '+') // sign
{
if (c == '-')
s = "-";
i.get(c);
}
while (isspace(c) && i.get(c)) // skip whitespace
;
base = __gmp_istream_set_base(i, c, zero, showbase); // select the base
__gmp_istream_set_digits(s, i, c, ok, base); // read the numerator
if (! ok && zero) // the only digit read was "0"
{
base = 10;
s += '0';
ok = true;
}
if (i.flags() & ios::skipws)
while (isspace(c) && i.get(c)) // skip whitespace
;
if (c == '/') // there's a denominator
{
bool zero2 = false;
int base2 = base;
s += '/';
ok = false; // denominator is mandatory
i.get(c);
while (isspace(c) && i.get(c)) // skip whitespace
;
if (showbase) // check base of denominator
base2 = __gmp_istream_set_base(i, c, zero2, showbase);
if (base2 == base || base2 == 10) // read the denominator
__gmp_istream_set_digits(s, i, c, ok, base);
if (! ok && zero2) // the only digit read was "0"
{ // denominator is 0, but that's your business
s += '0';
ok = true;
}
}
if (i.good()) // last character read was non-numeric
i.putback(c);
else if (i.eof() && ok) // stopped just before eof
i.clear();
if (ok)
mpq_set_str(q, s.c_str(), base); // extract the number
else
i.setstate(ios::failbit); // read failed
return i;
}
CGAL_INLINE_FUNCTION
ostream&
//operator<< (ostream &o, mpz_srcptr z)
io_write (ostream &o, mpz_srcptr z)
{
char *str = new char [mpz_sizeinbase(z,10) + 2];
str = mpz_get_str(str, 10, z);
o << str ;
delete[] str;
return o;
}
CGAL_INLINE_FUNCTION
ostream&
//operator<< (ostream &o, mpq_srcptr q)
io_write (ostream &o, mpq_srcptr q)
{
// size according to GMP documentation
char *str = new char [mpz_sizeinbase(mpq_numref(q), 10) +
mpz_sizeinbase (mpq_denref(q), 10) + 3];
str = mpq_get_str(str, 10, q);
o << str ;
delete[] str;
return o;
}
} //namespace CORE

View File

@ -39,6 +39,13 @@
#define _CORE_REAL_H_
#include "RealRep.h"
#ifdef CGAL_HEADER_ONLY
#undef CGAL_EXPORT // CJTODO: TEMPORARY
#undef CGAL_CORE_EXPORT
#define CGAL_EXPORT
#define CGAL_CORE_EXPORT
#endif
namespace CORE {
// class Real
typedef RCImpl<RealRep> RCReal;
@ -57,10 +64,10 @@ public:
Real(const BigInt& I) : RCReal(new RealBigInt(I)) {}
Real(const BigRat& R) : RCReal(new RealBigRat(R)) {}
Real(const BigFloat& F) : RCReal(new RealBigFloat(F)) {}
Real(const char* s, const extLong& prec=defInputDigits) : RCReal(NULL) {
Real(const char* s, const extLong& prec=get_static_defInputDigits()) : RCReal(NULL) {
constructFromString(s, prec);
}
Real(const std::string& s, const extLong& prec=defInputDigits) : RCReal(NULL){
Real(const std::string& s, const extLong& prec=get_static_defInputDigits()) : RCReal(NULL){
constructFromString(s.c_str(), prec);
}
@ -134,12 +141,12 @@ public:
/// \name String Conversion Functions
//@{
/// set value from <tt>const char*</tt>
void fromString(const char* s, const extLong& prec = defInputDigits) {
void fromString(const char* s, const extLong& prec = get_static_defInputDigits()) {
*this = Real(s, prec);
}
/// convert to <tt>std::string</tt>
/** give decimal string representation */
std::string toString(long prec=defOutputDigits, bool sci=false) const {
std::string toString(long prec=get_static_defOutputDigits(), bool sci=false) const {
return rep->toString(prec, sci);
}
//@}
@ -179,7 +186,8 @@ public:
/// \name Aprroximation Function
//@{
/// approximation
Real approx(const extLong& r=defRelPrec, const extLong& a=defAbsPrec) const {
Real approx(const extLong& r=get_static_defRelPrec(),
const extLong& a=get_static_defAbsPrec()) const {
return rep->approx(r, a);
}
//@}
@ -395,7 +403,7 @@ inline Real& Real::operator*=(const Real& rhs) {
return *this;
}
inline Real& Real::operator/=(const Real& rhs) {
*this = real_div::eval(getRep(), rhs.getRep(), defRelPrec);
*this = real_div::eval(getRep(), rhs.getRep(), get_static_defRelPrec());
return *this;
}
@ -413,7 +421,7 @@ inline Real operator*(const Real& x, const Real& y) {
}
// operator/
inline Real operator/(const Real& x, const Real& y) {
return real_div::eval(x.getRep(), y.getRep(), defRelPrec);
return real_div::eval(x.getRep(), y.getRep(), get_static_defRelPrec());
}
// div w/ precision
inline Real Real::div(const Real& x, const extLong& r) const {
@ -478,7 +486,7 @@ inline Real power(const Real& r, unsigned long p) {
}
/// square root
inline Real sqrt(const Real& x) {
return x.sqrt(defAbsPrec);
return x.sqrt(get_static_defAbsPrec());
}
// class Realbase_for (need defined after Real)
@ -493,4 +501,9 @@ inline Real RealLong::operator-() const {
}
} //namespace CORE
#ifdef CGAL_HEADER_ONLY
#include <CGAL/CORE/Real_impl.h>
#endif // CGAL_HEADER_ONLY
#endif // _CORE_REAL_H_

View File

@ -0,0 +1,291 @@
/****************************************************************************
* Core Library Version 1.7, August 2004
* Copyright (c) 1995-2004 Exact Computation Project
* All rights reserved.
*
* This file is part of CORE (http://cs.nyu.edu/exact/core/).
* You can redistribute it and/or modify it under the terms of the GNU
* General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* Licensees holding a valid commercial license may use this file in
* accordance with the commercial license agreement provided with the
* software.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
*
* File: Real.cpp
* Synopsis: The Real class is a superclass for all the number
* systems in the Core Library (int, long, float, double,
* BigInt, BigRat, BigFloat, etc)
*
* Written by
* Koji Ouchi <ouchi@simulation.nyu.edu>
* Chee Yap <yap@cs.nyu.edu>
* Chen Li <chenli@cs.nyu.edu>
* Zilin Du <zilin@cs.nyu.edu>
* Sylvain Pion <pion@cs.nyu.edu>
*
* WWW URL: http://cs.nyu.edu/exact/
* Email: exact@cs.nyu.edu
*
* $URL$
* $Id$
***************************************************************************/
#ifdef CGAL_HEADER_ONLY
#define CGAL_INLINE_FUNCTION inline
#else
#define CGAL_INLINE_FUNCTION
#endif
#include <ctype.h>
#include <CGAL/CORE/Real.h>
#ifdef CGAL_HEADER_ONLY
#include <CGAL/CORE/BigFloat.h> // for FiveTo
#endif
namespace CORE {
CGAL_INLINE_FUNCTION
const Real& Real::getZero() {
static Real Zero(0);
return Zero;
}
CGAL_INLINE_FUNCTION
BigInt floor(const Real& r, Real &sub) {
BigInt f = r.approx(CORE_INFTY, 2).BigIntValue();
sub = r-f;
// Adjustment
if (sub<0)
++sub, --f;
if (sub>=1)
--sub, ++f;
assert(sub >=0 && sub<1);
return f;
}
// pow(r,n) and power(r, n) are the same function
//
CGAL_INLINE_FUNCTION
Real pow(const Real& r, unsigned long n) {
if (n == 0)
return Real(1);
else if (n == 1)
return r;
else {
Real x = r;
while ((n % 2) == 0) { // n is even
x *= x;
n >>= 1;
}
Real u = x;
while (true) {
n >>= 1;
if (n == 0)
return u;
x *= x;
if ((n % 2) == 1) // n is odd
u *= x;
}
//return u; // unreachable
}
}//pow
extern BigInt FiveTo(unsigned long exp);
// Construct Real from String
// Note:
// -- Zilin Du: 06/03/2003
// -- Original it is the code for Real's constructor for "const char*".
// I change it to a function so that two constrcutors can share the code.
// now it is private and no default value.
//
// --Default value of the argument "prec" is get_static_defInputDigits()
// --If prec is CORE_posInfty, then the input is
// read in exactly. Otherwise, we convert to a RealBigFloat
// with absolute error at most 10^{-prec}
// Constructor Real( char *str, extLong& prec)
// is very similar to
// BigFloatRep::fromString( char *str, extLong& prec);
// Differences:
// In BigFloat(str, prec), the value of prec cannot be infinity, and
// it defaults to defBigFloatInputDigits;
// In Real(str, prec), the value of prec is allowed to be infinity, and
// it defaults to defInputDigits.
//
// Why do we have the two versions? It allows us to use the BigFloat class
// directly, without relying on Real class.
CGAL_INLINE_FUNCTION
void Real::constructFromString(const char *str, const extLong& prec )
// NOTE: prec defaults to get_static_defInputDigits() (see Real.h)
{
// 8/8/01, Chee and Zilin: add a new rational string format:
// this format is indicated by the presence of a slash "/"
// Moreover, the value of prec is ignored (basically
// assumed to be infinity).
if (std::strchr(str, '/') != NULL) { // this is a rational number
rep = new RealBigRat(BigRat(str));
return;
}
const char *e = std::strchr(str, 'e');
int dot = 0;
long e10 = 0;
if (e != NULL)
e10 = std::atol(e+1); // e10 is decimal precision of the input string
// i.e., input is A/10^{e10}.
else {
e = str + std::strlen(str);
#ifdef CORE_DEBUG
assert(*e == '\0');
#endif
}
const char *p = str;
if (*p == '-' || *p == '+')
p++;
BigInt m(0);
for (; p < e; p++) {
if (*p == '.') {
dot = 1;
continue;
}
m = m * 10 + (*p - '0');
if (dot)
e10--;
}
long t = (e10 < 0) ? -e10 : e10;
BigInt one(1);
BigInt ten = FiveTo(t) * (one << static_cast<unsigned long>(t));
if (*str == '-')
m = -m;
if (e10 >= 0) {
// convert exactly from integer numbers
m *= ten;
rep = new RealBigInt(m);
} else { // e10 < 0, fractional numbers
// HERE IS WHERE WE USE THE SYSTEM CONSTANT
// get_static_defInputDigits()
// Note: get_static_defInputDigits() should be at least log_2(10).
// We default get_static_defInputDigits() to 4.
//std::cout << "(m,ten)=" << m << "," << ten << std::endl;
BigRat r(m, ten);
if (prec.isInfty()) { // convert exactly! to a big rational
rep = new RealBigRat(r);
} else {
// convert approximately, to a BigFloat within the
// specified precision:
// BigFloat bf(r, CORE_posInfty, prec * lgTenM) ;
BigFloat bf(r, CORE_posInfty, prec * 4) ;
rep = new RealBigFloat(bf);
}
}
}// Real(str, prec)
// The operator >>(i,x) calls the constructor Real(char*)
CGAL_INLINE_FUNCTION
std::istream& operator >>(std::istream& i, Real& x) {
int size = 20;
char *str = new char[size];
char *p = str;
char c;
int d = 0, e = 0, s = 0;
// int done = 0;
// Chen Li: fixed a bug, the original statement is
// for (i.get(c); c == ' '; i.get(c));
// use isspace instead of testing c == ' ', since it must also
// skip tab, catridge/return, etc.
// Change to:
// int status;
do {
i.get(c);
} while (!i.eof() && isspace(c)); /* loop if met end-of-file, or
char read in is white-space. */
// Chen Li,
// original "if (c == EOF) ..." is unsafe since c is of char type and
// EOF is of int tyep with a negative value -1
if (i.eof()) {
i.clear(std::ios::eofbit | std::ios::failbit);
delete [] str;
return i;
}
// the current content in "c" should be the first non-whitespace char
if (c == '-' || c == '+') {
*p++ = c;
i.get(c);
}
for (; isdigit(c) || (!d && c=='.') ||
(!e && c=='e') || (!s && (c=='-' || c=='+')); i.get(c)) {
if (!i) break;
if (!e && (c == '-' || c == '+'))
break;
// Chen Li: put one more rule to prohibite input like
// xxxx.xxxe+xxx.xxx:
if (e && (c == '.'))
break;
if (p - str == size) {
char *t = str;
str = new char[size*2];
std::memcpy(str, t, size);
delete [] t;
p = str + size;
size *= 2;
}
#ifdef CORE_DEBUG
assert((p-str) < size);
#endif
*p++ = c;
if (c == '.')
d = 1;
// Chen Li: fix a bug -- the sign of exponent can not happen before
// the character "e" appears! It must follow the "e' actually.
// if (e || c == '-' || c == '+') s = 1;
if (e)
s = 1;
if (c == 'e')
e = 1;
}
if (!i && !i.eof()) {
delete [] str;
return i;
}
// chenli: make sure that the p is still in the range
if (p - str >= size) {
int len = p - str;
char *t = str;
str = new char[len + 1];
std::memcpy(str, t, len);
delete [] t;
p = str + len;
}
#ifdef CORE_DEBUG
assert(p - str < size);
#endif
*p = '\0';
i.putback(c);
i.clear();
// old: x = Real(str, i.precision()); // use precision of input stream.
x = Real(str); // default precision = get_static_defInputDigits()
delete [] str;
return i;
}//operator >> (std::istream&, Real&)
} //namespace CORE

View File

@ -41,6 +41,13 @@
#include <CGAL/CORE/Impl.h>
#include <CGAL/CORE/CoreAux.h>
#ifdef CGAL_HEADER_ONLY
#undef CGAL_EXPORT // CJTODO: TEMPORARY
#undef CGAL_CORE_EXPORT
#define CGAL_EXPORT
#define CGAL_CORE_EXPORT
#endif
namespace CORE {
#ifndef LONG_MAX
@ -294,4 +301,9 @@ inline bool extLong::isNaN() const {
}
} //namespace CORE
#ifdef CGAL_HEADER_ONLY
#include <CGAL/CORE/extLong_impl.h>
#endif // CGAL_HEADER_ONLY
#endif // _CORE_EXTLONG_H_

View File

@ -0,0 +1,212 @@
/****************************************************************************
* Core Library Version 1.7, August 2004
* Copyright (c) 1995-2004 Exact Computation Project
* All rights reserved.
*
* This file is part of CORE (http://cs.nyu.edu/exact/core/).
* You can redistribute it and/or modify it under the terms of the GNU
* General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* Licensees holding a valid commercial license may use this file in
* accordance with the commercial license agreement provided with the
* software.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
*
* File: extLong.cpp
* Synopsis:
* The class extLong is basically a wrapper around the machine
* type long. It is an important class to provide several
* additional facilities to detect overflows and undefined values.
* Future development includes extensions to level arithmetic
* (i.e., if a number overflows level i, we will go to level i+1).
* Level i representation of a number n is just i iterations
* of log_2 applied to n.
*
* Written by
* Chee Yap <yap@cs.nyu.edu>
* Chen Li <chenli@cs.nyu.edu>
* Zilin Du <zilin@cs.nyu.edu>
* Sylvain Pion <pion@cs.nyu.edu>
*
* WWW URL: http://cs.nyu.edu/exact/
* Email: exact@cs.nyu.edu
*
* $URL$
* $Id$
***************************************************************************/
#ifdef CGAL_HEADER_ONLY
#define CGAL_INLINE_FUNCTION inline
#else
#define CGAL_INLINE_FUNCTION
#endif
#include <CGAL/CORE/extLong.h>
namespace CORE {
CGAL_INLINE_FUNCTION
const extLong& extLong::getNaNLong() {
static extLong NaNLong(true);
return NaNLong;
}
CGAL_INLINE_FUNCTION
const extLong& extLong::getPosInfty() {
static extLong posInfty(EXTLONG_MAX);
return posInfty;
}
CGAL_INLINE_FUNCTION
const extLong& extLong::getNegInfty() {
static extLong negInfty(EXTLONG_MIN);
return negInfty;
}
CGAL_INLINE_FUNCTION
void extLong::add(extLong& z, long x, long y) {
if (x > 0 && y > 0 && x >= EXTLONG_MAX - y) {
z.val = EXTLONG_MAX;
z.flag = 1;
} else if (x < 0 && y < 0 && x <= EXTLONG_MIN - y) {
z.val = EXTLONG_MIN;
z.flag = -1;
} else {
z.val = x + y;
z.flag = 0;
}
}
// arithmetic and assignment operators
CGAL_INLINE_FUNCTION
extLong& extLong::operator+= (const extLong& y) {
if (flag == 2 || y.flag == 2 || (flag * y.flag < 0)) {
#ifdef CORE_DEBUG
if (flag * y.flag < 0) //want a message at the first creation of NaN
core_error("extLong NaN Error in addition.", __FILE__, __LINE__, false);
#endif
*this = CORE_NaNLong;
} else if (flag == 1 || y.flag == 1) { // one of them is +Inf
*this = CORE_posInfty;
} else if (flag == -1 || y.flag == -1) { // one of them is -Inf
*this = CORE_negInfty;
} else { // x and y are normal now
add(*this, val, y.val);
}
return *this;
}
CGAL_INLINE_FUNCTION
extLong& extLong::operator-= (const extLong& y) {
if (flag == 2 || y.flag == 2 || (flag * y.flag > 0)) {
#ifdef CORE_DEBUG
if (flag * y.flag > 0) //want a message at the first creation of NaN
core_error("extLong NaN Error in subtraction.", __FILE__, __LINE__, false);
#endif
*this = CORE_NaNLong;
} else if (flag == 1 || y.flag == -1) {
*this = CORE_posInfty;
} else if (flag == -1 || y.flag == 1) {
*this = CORE_negInfty;
} else {
add(*this, val, -y.val);
}
return *this;
}
CGAL_INLINE_FUNCTION
extLong& extLong::operator*= (const extLong& y) {
if (flag == 2 || y.flag == 2) {
*this = CORE_NaNLong;
} else if ((flag != 0) || (y.flag != 0)) {
if (sign() * y.sign() > 0)
*this = CORE_posInfty;
else
*this = CORE_negInfty;
} else { // flag == 0 and y.flag == 0
double d = double(val) * double(y.val);
long p = val * y.val;
if (std::fabs(d - p) <= std::fabs(d) * relEps) {
val = p;
flag = 0;
} else if (d > EXTLONG_MAX) {
*this = CORE_posInfty;
} else if (d < EXTLONG_MIN) {
*this = CORE_negInfty;
} else {
#ifdef CORE_DEBUG
core_error("extLong NaN Error in multiplication.",__FILE__,__LINE__,false);
#endif
*this = CORE_NaNLong;
}
}
return *this;
}
CGAL_INLINE_FUNCTION
extLong& extLong::operator/= (const extLong& y) {
if (flag==2 || y.flag==2 || ((flag != 0) && (y.flag != 0)) || (y.val == 0)) {
#ifdef CORE_DEBUG
if (y.val == 0)
core_error("extLong NaN Error, Divide by Zero.", __FILE__, __LINE__, false);
else if ((flag !=0) && (y.flag !=0))
core_error("extLong NaN Error, +/-Inf/Inf.", __FILE__, __LINE__, false);
#endif
*this = CORE_NaNLong;
} else if ((flag != 0) || (y.flag != 0)) { // y.flag == 0 now and y != 0
if (sign() * y.sign() > 0)
*this = CORE_posInfty;
else
*this = CORE_negInfty;
} else { // flag == 0 and y.flag == 0
val /= y.val; // no overflow in divisions
flag = 0;
}
return *this;
}
// unary minus
CGAL_INLINE_FUNCTION
extLong extLong::operator- () const {
if (flag == 0)
return extLong(-val);
else if (flag == 1)
return CORE_negInfty;
else if (flag == -1)
return CORE_posInfty;
else // NaN
return CORE_NaNLong;
}
// sign
// You should check "flag" before calling this, otherwise
// you cannot interprete the returned value!
CGAL_INLINE_FUNCTION
int extLong::sign() const {
if (flag == 2)
core_error("NaN Sign can not be determined!", __FILE__, __LINE__, false);
return ((val == 0) ? 0 : ((val > 0) ? 1 : -1));
}
// stream operators
CGAL_INLINE_FUNCTION
std::ostream& operator<< (std::ostream& o, const extLong& x) {
if (x.flag == 1)
o << " infty ";
else if (x.flag == - 1)
o << " tiny ";
else if (x.flag == 2)
o << " NaN ";
else
o << x.val;
return o;
}
} //namespace CORE

View File

@ -205,7 +205,8 @@ public:
/// Polynomial evaluation where the coefficients are approximated first
/// Returns a BigFloat with error that contains the value
BigFloat evalApprox(const BigFloat& f,
const extLong& r=defRelPrec, const extLong& a=defAbsPrec) const;
const extLong& r=get_static_defRelPrec(),
const extLong& a=get_static_defAbsPrec()) const;
/// Polynomial evaluation at a BigFloat value.
/// The returned BigFloat (with error) has the exact sign.
/// In particular, if the value is 0, we return 0.

File diff suppressed because it is too large Load Diff

View File

@ -33,181 +33,9 @@
* $Id$
***************************************************************************/
#include "CGAL/CORE/CoreAux.h"
#include <gmp.h>
#ifndef CGAL_HEADER_ONLY
namespace CORE {
#include <CGAL/CORE/CoreAux.h>
#include <CGAL/CORE/CoreAux_impl.h>
////////////////////////////////////////////////////////////
// More useful functions to implement:
//
// To convert digits into bits:
// given X, compute X * log_2(10)
// To convert bits into digits:
// given X, compute X * log_10(2)
//
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// flrLg(x)
// returns floor log base 2 of abs(x)
// CONVENTION lg(0) = -1 (Slight improvement, Zilin/Chee 8/5/02)
////////////////////////////////////////////////////////////
int flrLg(long x) {
if (x == LONG_MIN) {
// special treatment as -LONG_MIN would be not representable as "long"
return LONG_BIT - 1;
} else {
// 1 <= |x| <= LONG_MAX
if (x < 0)
x = - x;
int lg = -1;
while (x > 0) {
lg++;
x >>= 1;
}
return lg;
}
}
////////////////////////////////////////////////////////////
// floor log base 2 of unsigned long x
// CONVENTION lg(0) = -1 (Slight improvement, Zilin/Chee 8/5/02)
////////////////////////////////////////////////////////////
int flrLg(unsigned long x) {
int lg = -1;
while (x > 0) {
lg++;
x >>= 1;
}
return lg;
}
////////////////////////////////////////////////////////////
// ceiling log base 2 of abs(x)
// CONVENTION lg(0) = -1 (Slight improvement, Zilin/Chee 8/5/02)
////////////////////////////////////////////////////////////
int clLg(long x) {
if (x == LONG_MIN)
return LONG_BIT - 1;
if (x < 0)
x = -x; // use absolute value
if (x > (LONG_MAX >> 1)) // the leading data bit is 1
return (LONG_BIT - 1); // exclude the sign bit
if (x >= 2)
return flrLg((unsigned long)((x << 1) - 1));
// SINCE ceilLog_2(x) = floorLog_2(2x-1) for x>=2
if (x == 1)
return 0;
return -1; // x must be 0 here
}
////////////////////////////////////////////////////////////
// ceiling log base 2 of unsigned long x
// CONVENTION lg(0) = -1
////////////////////////////////////////////////////////////
int clLg(unsigned long x) {
if (x > (ULONG_MAX >> 1)) // the leading bit is 1
return LONG_BIT;
if (x >= 2)
return flrLg((x << 1) - 1);
// SINCE ceilLog_2(x) = floorLog_2(2x-1) for x>=2.
if (x == 1)
return 0;
return -1; // x must be equal to 0
}
/// gcd for machine type long
/** This is needed when we construct Polynomials with int or long coefficients */
long gcd(long m, long n) {
if (m == 0)
return core_abs(n);
if (n == 0)
return core_abs(m);
long p = core_abs(m);
long q = core_abs(n);
if (p<q)
core_swap(p, q);
while (q>0) {
long r = p % q;
p = q;
q = r;
}
return p;
}
// return a gmp_randstate_t structure
gmp_randstate_t* getRandstate() {
static gmp_randstate_t rstate;
static bool initialized = false;
if (!initialized) {
gmp_randinit(rstate, GMP_RAND_ALG_DEFAULT, 32L);
initialized = true;
}
return &rstate;
}
// char* core_itoa(int n, char* buffer)
// returns a pointer to the null-terminated string in buffer
// NOTES:
// 0. Buffer size should be 17 bytes (resp., 33 bytes, 65 bytes) on 16-bit
// (resp., 32-bit, 64-bit) machines. Formula: 1+sizeof(int)*8 bytes.
// 1. itoa(...) is available on some stdlib.h, but it is
// not defined by ANSI-C and so not all compilers support it.
// 2. Our use of sprintf(...) to do the job is known to
// be inefficient, but this is hardly critical for our usage.
// 3. A more general program should take a 3rd argument (the radix of
// output number). We assume radix 10.
char * core_itoa(int n, char* buffer) {
std::sprintf(buffer, "%d", n);
return buffer;
}
/// implements the "integer mantissa" function
// (See CORE_PATH/progs/ieee/frexp.cpp for details)
double IntMantissa(double d) {
int e;
return std::ldexp(std::frexp(d, &e), 53);
}
/// implements the "integer exponent" function
// (See CORE_PATH/progs/ieee/frexp.cpp for details)
int IntExponent(double d) {
int e;
std::frexp(d, &e);
return e-53;
}
/// CORE_DIAGFILE is file name for core_error(..) output.
const char* CORE_DIAGFILE = "Core_Diagnostics"; // global file name
/// core_error is the method to write Core Library warning or error messages
/** Both warnings and errors are written to a file called CORE_DIAGFILE.
* But errors are also written on std:cerr (similar to std::perror()).
* */
// Usage: core_error(message, file_with_error, line_number, err_type)
// where err_type=0 means WARNING, error_type=0 means ERROR
void core_error(std::string msg, std::string file, int lineno, bool err) {
std::ofstream outFile(CORE_DIAGFILE, std::ios::app); // open to append
if (!outFile) {
// perror("CORE ERROR: cannot open Core Diagnostics file");
std::cerr << "CORE ERROR: can't open Core Diagnostics file"<<std::endl;
std::exit(1); //Note: do not call abort()
}
outFile << "CORE " << (err? "ERROR" : "WARNING")
<< " (at " << file << ": " << lineno << "): "
<< msg << std::endl;
outFile.close();
if (err) {
char buf[65];
// perror((std::string("CORE ERROR") + " (file " + file + ", line "
// + core_itoa(lineno,buf) +"):" + msg + "\n").c_str());
std::cerr << (std::string("CORE ERROR") + " (file " + file + ", line "
+ core_itoa(lineno,buf) +"):" + msg + "\n").c_str();
std::exit(1); //Note: do not call abort()
}
}
} //namespace CORE
#endif

View File

@ -32,124 +32,9 @@
* $Id$
***************************************************************************/
#include "CGAL/CORE/CoreDefs.h"
#ifndef CGAL_HEADER_ONLY
namespace CORE {
// Default Values
/* ************************************************************
* ERROR FLAGS
* ************************************************************ */
/** I/O error flag (Default value 0, indicating no error)
* User's responsibility to check and reset value to 0. */
// This is currently used in geom2d/points2d.cpp for I/O of points
int IOErrorFlag = 0;
/**
* If AbortFlag is true when invalid expression is constructed, system will abort
*/
bool AbortFlag = true;
/**
* InvalidFlag is set to negative whenever an invalid expression is constructed.
* The user has the responsibility to reset to non-negative value.
*/
int InvalidFlag = 0;
/* ************************************************************
* PRECISION PARAMETERS
* ************************************************************ */
/**
* Default BigFloat Division Relative Precision
* -- this is used by BigFloat division when the arguments are error-free.
*/
extLong defBFdivRelPrec = 54;
/**
* Default BigFloat Sqrt Absolute Precision
* -- this is used by BigFloat sqrt when the argument is error-free.
*/
extLong defBFsqrtAbsPrec = 54;
/**
* Escape Precision
* -- we will not compare a number to precision higher than this
* -- if this is infinity, there there is no escape precision */
extLong EscapePrec = CORE_posInfty;
/** this flag becomes negative if the EscapePrec is used. */
long EscapePrecFlag = 0;
/// Escape Precision Warning Flag
/** this flag is true by default, and will cause a warning to be printed
when EscapePrec is reached */
bool EscapePrecWarning = true;
/** The Composite Precision [defAbsPrec, defRelPrec]
* determines the precision to which an Expr evaluates its
* (exact, implicit) constant value. */
/** absolute precision = 2^31 - 1 */
extLong defAbsPrec = CORE_posInfty;
/** default relative precision is 60 relative bits.
* Why 60? We would really like this to be 54, so that the default
* conversion duplicates the IEEE double precision. But it turns out
* (see README file under BUGS), we need 59 to ensure this.
* Chee Yap (7/1/01) */
extLong defRelPrec = 60;
/** number of BigFloat digits to print out */
long defBigFloatOutputDigits = 10;
/** NORMALLY, we like to make this equal to defBigFloatOutputDigits
* 8/3/01, Chee: re-introduced this parameter */
long defOutputDigits = defBigFloatOutputDigits;
/** String Input Precision */
/** Set this to 16 if you want machine precision. This controls the
* absolute error in string decimal inputs to Real or Expr.
* If defInputDigits is finite, then the absolute error will be
* at most 10^{-defInputDigits}. Otherwise, the input is exactly
* represented by some BigFloat or BigRat value. */
extLong defInputDigits = CORE_posInfty;
/** This controls the absolute error in converting from string to BigFloat
* The absolute error will be at most 10^{-defInputDigits} */
long defBigFloatInputDigits = 16;
/* ************************************************************
* EVALUATION FLAGS
* ************************************************************ */
/** Floating Point filter
* true = turn on floating point filter */
bool fpFilterFlag = true;
/** IncrementaL evaluation flag
* incremental evaluation is requested, This means, we try to use previous
* approximate values to improve an approximation */
bool incrementalEvalFlag = true;
/** Progressive evaluation flag
* true = turn on progressive evaluation flag */
bool progressiveEvalFlag = true;
/** Initial progressive evaluation precision
* Used by AddSubRep */
long defInitialProgressivePrec = 64;
/** RATIONAL REDUCTION FLAG
* true = turn on rational reduction */
bool rationalReduceFlag = false;
} //namespace CORE
#include <CGAL/CORE/CoreDefs.h>
#include <CGAL/CORE/CoreDefs_impl.h>
#endif

View File

@ -29,430 +29,6 @@
* $Id$
***************************************************************************/
#include <CGAL/CORE/BigFloatRep.h>
#include <CGAL/CORE/BigFloat.h>
namespace CORE {
void core_io_error_handler(const char *f, const char *m) {
std::cout << "\n error_handler";
std::cout << "::" << f << "::" << m << "\n";
std::cout.flush();
std::abort();
}
void core_io_memory_handler(char *t, const char *f, const char *m) {
if (t == NULL) {
std::cout << "\n memory_handler";
std::cout << "::" << f << "::" << m;
std::cout << "memory exhausted\n";
std::cout.flush();
std::abort();
}
}
// s has size old_size and will be resized to new_size.
void allocate (char * &s, int old_size, int new_size) {
if (old_size > new_size)
old_size = new_size;
if (s == NULL)
old_size = 0;
char *t = new char[new_size];
core_io_memory_handler(t, "CoreIO", "allocate::out of memory error");
int i;
for (i = 0; i < old_size; i++)
t[i] = s[i];
delete[] s;
s = t;
}
// appends c to s at position pos.
// sz is the size of s
void append_char (char * &s, int & sz, int pos, char c) {
if (pos > sz)
core_io_error_handler("CoreIO", "append_char::invalid argument");
if (pos == sz) {
allocate(s, sz, 2*sz);
sz *= 2;
}
s[pos] = c;
}
// skip blanks, tabs, line breaks and comment lines
int skip_comment_line (std::istream & in) {
int c;
do {
c = in.get();
while ( c == '#' ) {
do {
c = in.get();
} while ( c != '\n' );
c = in.get();
}
} while (c == ' ' || c == '\t' || c == '\n');
if (c == EOF)
core_io_error_handler("CoreIO::read_from_file()","unexpected end of file.");
in.putback(c);
return c;
}
// skips '\\' followed by '\n'
int skip_backslash_new_line (std::istream & in) {
int c = in.get();
while (c == '\\') {
c = in.get();
if (c == '\n')
c = in.get();
else
core_io_error_handler("CoreIO::operator>>", "\\ must be immediately followed by new line.");
}
return c;
}
void read_string(std::istream& in, char* &buffer, int sz) {
int c, pos=0;
skip_comment_line(in);
while ( (c = in.get()) != EOF ) {
if ( c == ' ' || c == '\t' || c == '\n' || c == '#')
break;
else
append_char(buffer, sz, pos++, c);
}
append_char(buffer, sz, pos, '\0');
}
void read_base_number(std::istream& in, BigInt& m, long length, long maxBits) {
char *buffer;
int size, offset;
int base;
bool is_negate;
int c, pos = 0;
skip_comment_line(in);
// read sign
c = in.get();
if (c == '-') {
is_negate = true;
c = in.get();
} else
is_negate = false;
// read base and compute digits
if (c == '0') {
c = in.get();
if (c == 'b') {
base = 2;
size = (maxBits == 0 || maxBits > length) ? length : maxBits;
offset = length - size;
} else if (c == 'x') {
base = 16;
size = (maxBits == 0) ? length : (maxBits+3) >> 2;
size = (size > length) ? length : size;
offset = (length - size) << 2;
} else {
base = 8;
size = (maxBits == 0) ? length : (maxBits+2) / 3;
size = (size > length) ? length : size;
offset = (length - size) * 3;
in.putback(c);
}
} else {
base = 10;
size = (maxBits == 0) ? length : (int)std::ceil(maxBits*std::log(2.0)/std::log(10.0));
size = (size > length) ? length : size;
offset = length - size;
in.putback(c);
}
buffer = new char[size+2];
// read digits
for (int i=0; (i<size)&&((c=skip_backslash_new_line(in)) != EOF ); i++) {
if (c != ' ' && c != '\t' && c != '\n')
append_char(buffer, size, pos++, c);
}
if (base == 10) {
for(int j=0; j<offset; j++)
append_char(buffer, size, pos++, '0');
}
append_char(buffer, size, pos, '\0');
// convert string to bigint.
if (m.set_str(buffer, base) < 0)
core_io_error_handler("CoreIO::read_from_file()","bad big number format.");
delete[] buffer;
// shift left if neccessary
if (offset > 0 && base != 10) {
m <<= offset;
}
if (is_negate)
negate(m);
}
void write_base_number(std::ostream& out, char* buffer, int length, int base, int charsPerLine) {
// write big number in a format that gmp's mpz_set_str() can
// automatically recognize with argument base = 0.
if (base == 2)
out << "0b";
else if (base == 16)
out << "0x";
else if (base == 8)
out << '0';
// write big number in charsPerLine.
char* start, *end, c;
for (int i=0; i<length; i += charsPerLine) {
start = buffer + i;
if (i + charsPerLine >= length)
out << start;
else {
end = start + charsPerLine;
c = *end;
*end = '\0';
out << start << "\\\n";
*end = c;
}
}
}
void readFromFile(BigInt& z, std::istream& in, long maxLength) {
char *buffer;
long length;
// check type name whether it is Integer or not.
buffer = new char[8];
read_string(in, buffer, sizeof(buffer));
if ( std::strcmp(buffer, "Integer") != 0)
core_io_error_handler("BigInt::read_from_file()","type name expected.");
delete[] buffer;
// read the bit length field.
buffer = new char[100];
read_string(in, buffer, sizeof(buffer));
length = std::atol(buffer);
delete[] buffer;
// read bigint
read_base_number(in, z, length, maxLength);
}
void writeToFile(const BigInt& z, std::ostream& out, int base, int charsPerLine) {
BigInt c = abs(z);
// get the absoulte value string
char* buffer = new char[mpz_sizeinbase(c.get_mp(), base) + 2];
mpz_get_str(buffer, base, c.get_mp());
int length = std::strlen(buffer);
// write type name of big number and length
//out << "# This is an experimental big number format.\n";
out << "Integer " << length << "\n";
// if bigint is negative, then write an sign '-'.
if ( sign(z) < 0 )
out << '-';
write_base_number(out, buffer, length, base, charsPerLine);
out << "\n";
delete[] buffer;
}
void readFromFile(BigFloat& bf, std::istream& in, long maxLength) {
char *buffer;
long length;
long exponent;
BigInt mantissa;
// check type name whether it is Float
buffer = new char[6];
read_string(in, buffer, sizeof(buffer));
if (std::strcmp(buffer, "Float") != 0)
core_io_error_handler("BigFloat::read_from_file()", "type name expected");
delete[] buffer;
// read base (default is 16384)
buffer = new char[8];
read_string(in, buffer, sizeof(buffer));
if (std::strcmp(buffer, "(16384)") != 0)
core_io_error_handler("BigFloat::read_from_file()", "base expected");
delete[] buffer;
// read the bit length field.
buffer = new char[100];
read_string(in, buffer, sizeof(buffer));
length = std::atol(buffer);
delete[] buffer;
// read exponent
buffer = new char[100];
read_string(in, buffer, sizeof(buffer));
exponent = std::atol(buffer);
delete[] buffer;
// read mantissa
read_base_number(in, mantissa, length, maxLength);
// construct BigFloat
bf = BigFloat(mantissa, 0, exponent);
}
void writeToFile(const BigFloat& bf, std::ostream& out, int base, int charsPerLine) {
BigInt c(CORE::abs(bf.m()));
// get the absoulte value string
char* buffer = new char[mpz_sizeinbase(c.get_mp(), base) + 2];
mpz_get_str(buffer, base, c.get_mp());
int length = std::strlen(buffer);
// write type name, base, length
//out << "# This is an experimental Big Float format." << std::endl;
out << "Float (16384) " << length << std::endl;
// write exponent
out << bf.exp() << std::endl;
// write mantissa
if ( CORE::sign(bf.m()) < 0 )
out << '-';
write_base_number(out, buffer, length, base, charsPerLine);
out << '\n';
delete[] buffer;
}
/* Underconstruction ----
void BigFloat::read_from_file2(std::istream& in, long maxLength) {
long length = 1024;
char *buffer;
// check type name whether it is Float
buffer = new char[7];
BigInt::read_string(in, buffer, sizeof(buffer));
if (strcmp(buffer, "NFloat") != 0)
core_io_error_handler("BigFloat::read_from_file2()", "type name expected");
delete[] buffer;
// read base (default is 16)
buffer = new char[5];
BigInt::read_string(in, buffer, sizeof(buffer));
if (strcmp(buffer, "(16)") != 0)
core_io_error_handler("BigFloat::read_from_file2()", "base expected");
delete[] buffer;
// read length field
buffer = new char[100];
BigInt::read_string(in, buffer, sizeof(buffer));
// get the length field if it is not null.
if (buffer[0] != '\0') {
length = atol(buffer);
if (maxLength > 0 && length >= maxLength)
length = maxLength;
}
delete[] buffer;
// read exponent
buffer = new char[100];
BigInt::read_string(in, buffer, sizeof(buffer));
long exp16 = atol(buffer);
delete[] buffer;
// read mantissa
buffer = new char[length+2];
//BigInt::read_base_number(in, buffer, length);
BigInt m16(buffer);
delete[] buffer;
// convert to base CHUNK_BIT
exp16 = exp16 - length + 1;
if ( m16.is_negative() )
exp16 ++;
long tmp_exp = exp16 * 4;
long q = tmp_exp / CHUNK_BIT;
long r = tmp_exp % CHUNK_BIT;
if ( r < 0 ) {
r += CHUNK_BIT;
q --;
}
BigInt mantissa = m16 << r;
long exponent = q;
// construct BigFloat
if (--rep->refCount == 0)
delete rep;
rep = new BigFloatRep(mantissa, 0, exponent);
rep->refCount++;
}
// write normal float
// now it assumed to write in hex base, i.e. B=2^4=16
// (note: our default base B=2^(CHUNK_BIT)=2^14=16384
void BigFloat::write_to_file2(std::ostream& out, int base, int charsPerLine) {
// convert to base 16.
long new_base = 4; // 2^4 = 16
long tmp_exp = (rep->exp) * CHUNK_BIT;
long q = tmp_exp / new_base;
long r = tmp_exp % new_base;
std::cout << "CORE_DEBUG: q=" << q << ", r=" << r << std::endl;
if ( r < 0 ) {
r += new_base;
q--;
}
std::cout << "CORE_DEBUG: q=" << q << ", r=" << r << std::endl;
BigInt m16 = (rep->m) << r;
int size = mpz_sizeinbase(m16.I, base) + 2;
std::cout << "size=" << size << std::endl;
char* buffer = new char[size];
int length = bigint_to_string(m16, buffer, base);
std::cout << "length=" << length << std::endl;
long exp16 = q + length - 1;
if ( m16.is_negative() )
exp16 --;
// write type name, base, length
out << "# This is an experimental Big Float format." << std::endl;
out << "NFloat (16) " << length << std::endl;
// write exponent
out << exp16 << std::endl;
// write mantissa
if ( m16.is_negative() ) {
out << '-';
buffer ++;
}
BigInt::write_base_number(out, buffer, length, base, charsPerLine);
out << '\n';
delete[] buffer;
}
*/
} //namespace CORE
#ifndef CGAL_HEADER_ONLY
#include <CGAL/CORE/CoreIO_impl.h>
#endif

File diff suppressed because it is too large Load Diff

View File

@ -12,257 +12,9 @@
* $Id$
***************************************************************************/
/* Auxiliary functions for C++-style input of GMP types.
Copyright 2001 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3 of the License, or (at your
option) any later version.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
#ifndef CGAL_HEADER_ONLY
#include <CGAL/CORE/Gmp.h>
#include <cctype>
#include <iostream>
#include <string>
#include <cstdio>
#include <CGAL/CORE/Gmp_impl.h>
using namespace std;
namespace CORE {
int
__gmp_istream_set_base (istream &i, char &c, bool &zero, bool &showbase)
{
int base;
zero = showbase = false;
switch (i.flags() & ios::basefield)
{
case ios::dec:
base = 10;
break;
case ios::hex:
base = 16;
break;
case ios::oct:
base = 8;
break;
default:
showbase = true; // look for initial "0" or "0x" or "0X"
if (c == '0')
{
if (! i.get(c))
c = 0; // reset or we might loop indefinitely
if (c == 'x' || c == 'X')
{
base = 16;
i.get(c);
}
else
{
base = 8;
zero = true; // if no other digit is read, the "0" counts
}
}
else
base = 10;
break;
}
return base;
}
void
__gmp_istream_set_digits (string &s, istream &i, char &c, bool &ok, int base)
{
switch (base)
{
case 10:
while (isdigit(c))
{
ok = true; // at least a valid digit was read
s += c;
if (! i.get(c))
break;
}
break;
case 8:
while (isdigit(c) && c != '8' && c != '9')
{
ok = true; // at least a valid digit was read
s += c;
if (! i.get(c))
break;
}
break;
case 16:
while (isxdigit(c))
{
ok = true; // at least a valid digit was read
s += c;
if (! i.get(c))
break;
}
break;
}
}
istream &
//operator>> (istream &i, mpz_ptr z)
io_read (istream &i, mpz_ptr z)
{
int base;
char c = 0;
string s;
bool ok = false, zero, showbase;
i.get(c); // start reading
if (i.flags() & ios::skipws) // skip initial whitespace
while (isspace(c) && i.get(c))
;
if (c == '-' || c == '+') // sign
{
if (c == '-') // mpz_set_str doesn't accept '+'
s = "-";
i.get(c);
}
while (isspace(c) && i.get(c)) // skip whitespace
;
base = __gmp_istream_set_base(i, c, zero, showbase); // select the base
__gmp_istream_set_digits(s, i, c, ok, base); // read the number
if (i.good()) // last character read was non-numeric
i.putback(c);
else if (i.eof() && (ok || zero)) // stopped just before eof
i.clear();
if (ok)
mpz_set_str(z, s.c_str(), base); // extract the number
else if (zero)
mpz_set_ui(z, 0);
else
i.setstate(ios::failbit); // read failed
return i;
}
istream &
//operator>> (istream &i, mpq_ptr q)
io_read (istream &i, mpq_ptr q)
{
int base;
char c = 0;
string s;
bool ok = false, zero, showbase;
i.get(c); // start reading
if (i.flags() & ios::skipws) // skip initial whitespace
while (isspace(c) && i.get(c))
;
if (c == '-' || c == '+') // sign
{
if (c == '-')
s = "-";
i.get(c);
}
while (isspace(c) && i.get(c)) // skip whitespace
;
base = __gmp_istream_set_base(i, c, zero, showbase); // select the base
__gmp_istream_set_digits(s, i, c, ok, base); // read the numerator
if (! ok && zero) // the only digit read was "0"
{
base = 10;
s += '0';
ok = true;
}
if (i.flags() & ios::skipws)
while (isspace(c) && i.get(c)) // skip whitespace
;
if (c == '/') // there's a denominator
{
bool zero2 = false;
int base2 = base;
s += '/';
ok = false; // denominator is mandatory
i.get(c);
while (isspace(c) && i.get(c)) // skip whitespace
;
if (showbase) // check base of denominator
base2 = __gmp_istream_set_base(i, c, zero2, showbase);
if (base2 == base || base2 == 10) // read the denominator
__gmp_istream_set_digits(s, i, c, ok, base);
if (! ok && zero2) // the only digit read was "0"
{ // denominator is 0, but that's your business
s += '0';
ok = true;
}
}
if (i.good()) // last character read was non-numeric
i.putback(c);
else if (i.eof() && ok) // stopped just before eof
i.clear();
if (ok)
mpq_set_str(q, s.c_str(), base); // extract the number
else
i.setstate(ios::failbit); // read failed
return i;
}
ostream&
//operator<< (ostream &o, mpz_srcptr z)
io_write (ostream &o, mpz_srcptr z)
{
char *str = new char [mpz_sizeinbase(z,10) + 2];
str = mpz_get_str(str, 10, z);
o << str ;
delete[] str;
return o;
}
ostream&
//operator<< (ostream &o, mpq_srcptr q)
io_write (ostream &o, mpq_srcptr q)
{
// size according to GMP documentation
char *str = new char [mpz_sizeinbase(mpq_numref(q), 10) +
mpz_sizeinbase (mpq_denref(q), 10) + 3];
str = mpq_get_str(str, 10, q);
o << str ;
delete[] str;
return o;
}
} //namespace CORE
#endif

View File

@ -35,242 +35,9 @@
* $Id$
***************************************************************************/
#include <ctype.h>
#ifndef CGAL_HEADER_ONLY
#include <CGAL/CORE/Real.h>
#include <CGAL/CORE/Real_impl.h>
namespace CORE {
const Real& Real::getZero() {
static Real Zero(0);
return Zero;
}
BigInt floor(const Real& r, Real &sub) {
BigInt f = r.approx(CORE_INFTY, 2).BigIntValue();
sub = r-f;
// Adjustment
if (sub<0)
++sub, --f;
if (sub>=1)
--sub, ++f;
assert(sub >=0 && sub<1);
return f;
}
// pow(r,n) and power(r, n) are the same function
//
Real pow(const Real& r, unsigned long n) {
if (n == 0)
return Real(1);
else if (n == 1)
return r;
else {
Real x = r;
while ((n % 2) == 0) { // n is even
x *= x;
n >>= 1;
}
Real u = x;
while (true) {
n >>= 1;
if (n == 0)
return u;
x *= x;
if ((n % 2) == 1) // n is odd
u *= x;
}
//return u; // unreachable
}
}//pow
extern BigInt FiveTo(unsigned long exp);
// Construct Real from String
// Note:
// -- Zilin Du: 06/03/2003
// -- Original it is the code for Real's constructor for "const char*".
// I change it to a function so that two constrcutors can share the code.
// now it is private and no default value.
//
// --Default value of the argument "prec" is defInputDigits
// --If prec is CORE_posInfty, then the input is
// read in exactly. Otherwise, we convert to a RealBigFloat
// with absolute error at most 10^{-prec}
// Constructor Real( char *str, extLong& prec)
// is very similar to
// BigFloatRep::fromString( char *str, extLong& prec);
// Differences:
// In BigFloat(str, prec), the value of prec cannot be infinity, and
// it defaults to defBigFloatInputDigits;
// In Real(str, prec), the value of prec is allowed to be infinity, and
// it defaults to defInputDigits.
//
// Why do we have the two versions? It allows us to use the BigFloat class
// directly, without relying on Real class.
void Real::constructFromString(const char *str, const extLong& prec )
// NOTE: prec defaults to defInputDigits (see Real.h)
{
// 8/8/01, Chee and Zilin: add a new rational string format:
// this format is indicated by the presence of a slash "/"
// Moreover, the value of prec is ignored (basically
// assumed to be infinity).
if (std::strchr(str, '/') != NULL) { // this is a rational number
rep = new RealBigRat(BigRat(str));
return;
}
const char *e = std::strchr(str, 'e');
int dot = 0;
long e10 = 0;
if (e != NULL)
e10 = std::atol(e+1); // e10 is decimal precision of the input string
// i.e., input is A/10^{e10}.
else {
e = str + std::strlen(str);
#ifdef CORE_DEBUG
assert(*e == '\0');
#endif
}
const char *p = str;
if (*p == '-' || *p == '+')
p++;
BigInt m(0);
for (; p < e; p++) {
if (*p == '.') {
dot = 1;
continue;
}
m = m * 10 + (*p - '0');
if (dot)
e10--;
}
long t = (e10 < 0) ? -e10 : e10;
BigInt one(1);
BigInt ten = FiveTo(t) * (one << static_cast<unsigned long>(t));
if (*str == '-')
m = -m;
if (e10 >= 0) {
// convert exactly from integer numbers
m *= ten;
rep = new RealBigInt(m);
} else { // e10 < 0, fractional numbers
// HERE IS WHERE WE USE THE SYSTEM CONSTANT
// defInputDigits
// Note: defInputDigits should be at least log_2(10).
// We default defInputDigits to 4.
//std::cout << "(m,ten)=" << m << "," << ten << std::endl;
BigRat r(m, ten);
if (prec.isInfty()) { // convert exactly! to a big rational
rep = new RealBigRat(r);
} else {
// convert approximately, to a BigFloat within the
// specified precision:
// BigFloat bf(r, CORE_posInfty, prec * lgTenM) ;
BigFloat bf(r, CORE_posInfty, prec * 4) ;
rep = new RealBigFloat(bf);
}
}
}// Real(str, prec)
// The operator >>(i,x) calls the constructor Real(char*)
std::istream& operator >>(std::istream& i, Real& x) {
int size = 20;
char *str = new char[size];
char *p = str;
char c;
int d = 0, e = 0, s = 0;
// int done = 0;
// Chen Li: fixed a bug, the original statement is
// for (i.get(c); c == ' '; i.get(c));
// use isspace instead of testing c == ' ', since it must also
// skip tab, catridge/return, etc.
// Change to:
// int status;
do {
i.get(c);
} while (!i.eof() && isspace(c)); /* loop if met end-of-file, or
char read in is white-space. */
// Chen Li,
// original "if (c == EOF) ..." is unsafe since c is of char type and
// EOF is of int tyep with a negative value -1
if (i.eof()) {
i.clear(std::ios::eofbit | std::ios::failbit);
delete [] str;
return i;
}
// the current content in "c" should be the first non-whitespace char
if (c == '-' || c == '+') {
*p++ = c;
i.get(c);
}
for (; isdigit(c) || (!d && c=='.') ||
(!e && c=='e') || (!s && (c=='-' || c=='+')); i.get(c)) {
if (!i) break;
if (!e && (c == '-' || c == '+'))
break;
// Chen Li: put one more rule to prohibite input like
// xxxx.xxxe+xxx.xxx:
if (e && (c == '.'))
break;
if (p - str == size) {
char *t = str;
str = new char[size*2];
std::memcpy(str, t, size);
delete [] t;
p = str + size;
size *= 2;
}
#ifdef CORE_DEBUG
assert((p-str) < size);
#endif
*p++ = c;
if (c == '.')
d = 1;
// Chen Li: fix a bug -- the sign of exponent can not happen before
// the character "e" appears! It must follow the "e' actually.
// if (e || c == '-' || c == '+') s = 1;
if (e)
s = 1;
if (c == 'e')
e = 1;
}
if (!i && !i.eof()) {
delete [] str;
return i;
}
// chenli: make sure that the p is still in the range
if (p - str >= size) {
int len = p - str;
char *t = str;
str = new char[len + 1];
std::memcpy(str, t, len);
delete [] t;
p = str + len;
}
#ifdef CORE_DEBUG
assert(p - str < size);
#endif
*p = '\0';
i.putback(c);
i.clear();
// old: x = Real(str, i.precision()); // use precision of input stream.
x = Real(str); // default precision = defInputDigits
delete [] str;
return i;
}//operator >> (std::istream&, Real&)
} //namespace CORE

View File

@ -39,157 +39,9 @@
* $Id$
***************************************************************************/
#ifndef CGAL_HEADER_ONLY
#include <CGAL/CORE/extLong.h>
#include <CGAL/CORE/extLong_impl.h>
namespace CORE {
const extLong& extLong::getNaNLong() {
static extLong NaNLong(true);
return NaNLong;
}
const extLong& extLong::getPosInfty() {
static extLong posInfty(EXTLONG_MAX);
return posInfty;
}
const extLong& extLong::getNegInfty() {
static extLong negInfty(EXTLONG_MIN);
return negInfty;
}
void extLong::add(extLong& z, long x, long y) {
if (x > 0 && y > 0 && x >= EXTLONG_MAX - y) {
z.val = EXTLONG_MAX;
z.flag = 1;
} else if (x < 0 && y < 0 && x <= EXTLONG_MIN - y) {
z.val = EXTLONG_MIN;
z.flag = -1;
} else {
z.val = x + y;
z.flag = 0;
}
}
// arithmetic and assignment operators
extLong& extLong::operator+= (const extLong& y) {
if (flag == 2 || y.flag == 2 || (flag * y.flag < 0)) {
#ifdef CORE_DEBUG
if (flag * y.flag < 0) //want a message at the first creation of NaN
core_error("extLong NaN Error in addition.", __FILE__, __LINE__, false);
#endif
*this = CORE_NaNLong;
} else if (flag == 1 || y.flag == 1) { // one of them is +Inf
*this = CORE_posInfty;
} else if (flag == -1 || y.flag == -1) { // one of them is -Inf
*this = CORE_negInfty;
} else { // x and y are normal now
add(*this, val, y.val);
}
return *this;
}
extLong& extLong::operator-= (const extLong& y) {
if (flag == 2 || y.flag == 2 || (flag * y.flag > 0)) {
#ifdef CORE_DEBUG
if (flag * y.flag > 0) //want a message at the first creation of NaN
core_error("extLong NaN Error in subtraction.", __FILE__, __LINE__, false);
#endif
*this = CORE_NaNLong;
} else if (flag == 1 || y.flag == -1) {
*this = CORE_posInfty;
} else if (flag == -1 || y.flag == 1) {
*this = CORE_negInfty;
} else {
add(*this, val, -y.val);
}
return *this;
}
extLong& extLong::operator*= (const extLong& y) {
if (flag == 2 || y.flag == 2) {
*this = CORE_NaNLong;
} else if ((flag != 0) || (y.flag != 0)) {
if (sign() * y.sign() > 0)
*this = CORE_posInfty;
else
*this = CORE_negInfty;
} else { // flag == 0 and y.flag == 0
double d = double(val) * double(y.val);
long p = val * y.val;
if (std::fabs(d - p) <= std::fabs(d) * relEps) {
val = p;
flag = 0;
} else if (d > EXTLONG_MAX) {
*this = CORE_posInfty;
} else if (d < EXTLONG_MIN) {
*this = CORE_negInfty;
} else {
#ifdef CORE_DEBUG
core_error("extLong NaN Error in multiplication.",__FILE__,__LINE__,false);
#endif
*this = CORE_NaNLong;
}
}
return *this;
}
extLong& extLong::operator/= (const extLong& y) {
if (flag==2 || y.flag==2 || ((flag != 0) && (y.flag != 0)) || (y.val == 0)) {
#ifdef CORE_DEBUG
if (y.val == 0)
core_error("extLong NaN Error, Divide by Zero.", __FILE__, __LINE__, false);
else if ((flag !=0) && (y.flag !=0))
core_error("extLong NaN Error, +/-Inf/Inf.", __FILE__, __LINE__, false);
#endif
*this = CORE_NaNLong;
} else if ((flag != 0) || (y.flag != 0)) { // y.flag == 0 now and y != 0
if (sign() * y.sign() > 0)
*this = CORE_posInfty;
else
*this = CORE_negInfty;
} else { // flag == 0 and y.flag == 0
val /= y.val; // no overflow in divisions
flag = 0;
}
return *this;
}
// unary minus
extLong extLong::operator- () const {
if (flag == 0)
return extLong(-val);
else if (flag == 1)
return CORE_negInfty;
else if (flag == -1)
return CORE_posInfty;
else // NaN
return CORE_NaNLong;
}
// sign
// You should check "flag" before calling this, otherwise
// you cannot interprete the returned value!
int extLong::sign() const {
if (flag == 2)
core_error("NaN Sign can not be determined!", __FILE__, __LINE__, false);
return ((val == 0) ? 0 : ((val > 0) ? 1 : -1));
}
// stream operators
std::ostream& operator<< (std::ostream& o, const extLong& x) {
if (x.flag == 1)
o << " infty ";
else if (x.flag == - 1)
o << " tiny ";
else if (x.flag == 2)
o << " NaN ";
else
o << x.val;
return o;
}
} //namespace CORE

View File

@ -19,820 +19,9 @@
//
// Author(s) : ASCLEPIOS Project (INRIA Sophia-Antipolis), Laurent Rineau
#include <string.h>
#ifndef CGAL_HEADER_ONLY
#include "analyze.h"
#include "analyze_impl.h"
/* compile time endianness */
/* replaced by _getEndianness()
see below
#if (defined (_ALPHA_) || defined (_LINUX_))
#define ARCHITECTURE_ENDIANNESS END_LITTLE
#else
#define ARCHITECTURE_ENDIANNESS END_BIG
#endif
*/
/** Magic header for ANALYZE files written in little endian format */
#define ANALYZE_LE_MAGIC "\000\000\001\134"
/** Magic header for ANALYZE files written in big endian format */
#define ANALYZE_BE_MAGIC "\134\001\000\000"
#define DT_NONE 0
#define DT_UNKNOWN 0 /*Unknown data type*/
#define DT_BINARY 1 /*Binary (1 bit per voxel)*/
#define DT_UNSIGNED_CHAR 2 /*Unsigned character (8 bits per voxel)*/
#define DT_SIGNED_SHORT 4 /*Signed short (16 bits per voxel)*/
#define DT_SIGNED_INT 8 /*Signed integer (32 bits per voxel)*/
#define DT_FLOAT 16 /*Floating point (32 bits per voxel)*/
#define DT_COMPLEX 32 /*Complex (64 bits per voxel; 2 floating point numbers) */
#define DT_DOUBLE 64 /*Double precision (64 bits per voxel)*/
#define DT_RGB 128 /* */
#define DT_ALL 255 /* */
struct header_key /* header_key */
{ /* off + size*/
int sizeof_hdr; /* 0 + 4 */
char data_type[10]; /* 4 + 10 */
char db_name[18]; /* 14 + 18 */
int extents; /* 32 + 4 */
short int session_error; /* 36 + 2 */
char regular; /* 38 + 1 */
char hkey_un0; /* 39 + 1 */
}; /* total=40 */
struct image_dimension /* image_dimension */
{ /* off + size*/
short int dim[8]; /* 0 + 16 */
char vox_units[4]; /* 16 + 4 */
char cal_units[8]; /* 20 + 4 */
short int unused1; /* 24 + 2 */
short int datatype; /* 30 + 2 */
short int bitpix; /* 32 + 2 */
short int dim_un0; /* 34 + 2 */
float pixdim[8]; /* 36 + 32 */
/*
pixdim[] specifies the voxel dimensions:
pixdim[1] - voxel width
pixdim[2] - voxel height
pixdim[3] - interslice distance
..etc
*/
float vox_offset; /* 68 + 4 */
float funused1; /* 72 + 4 */
float funused2; /* 76 + 4 */
float funused3; /* 80 + 4 */
float cal_max; /* 84 + 4 */
float cal_min; /* 88 + 4 */
int compressed; /* 92 + 4 */
int verified; /* 96 + 4 */
int glmax, glmin; /* 100 + 8 */
}; /* total=108 */
struct data_history /* data_history */
{ /* off + size*/
char descrip[80]; /* 0 + 80 */
char aux_file[24]; /* 80 + 24 */
char orient; /* 104 + 1 */
char originator[10]; /* 105 + 10 */
char generated[10]; /* 115 + 10 */
char scannum[10]; /* 125 + 10 */
char patient_id[10]; /* 135 + 10 */
char exp_date[10]; /* 145 + 10 */
char exp_time[10]; /* 155 + 10 */
char hist_un0[3]; /* 165 + 3 */
int views; /* 168 + 4 */
int vols_added; /* 172 + 4 */
int start_field; /* 176 + 4 */
int field_skip; /* 180 + 4 */
int omax,omin; /* 184 + 8 */
int smax,smin; /* 192 + 8 */
};
struct dsr /* dsr */
{ /* off + size*/
struct header_key hk; /* 0 + 40 */
struct image_dimension dime; /* 40 + 108 */
struct data_history hist; /* 148 + 200 */
}; /* total=348 */
/*---------------- _swapLong ------------------------------------------------*/
static void _swapLong( unsigned char *pntr)
{
unsigned char b0, b1, b2, b3;
b0 = *pntr;
b1 = *(pntr+1);
b2 = *(pntr+2);
b3 = *(pntr+3);
*pntr = b3;
*(pntr+1) = b2;
*(pntr+2) = b1;
*(pntr+3) = b0;
}
/*---------------- _swapShort -----------------------------------------------*/
static void _swapShort( unsigned char *pntr)
{
unsigned char b0, b1;
b0 = *pntr;
b1 = *(pntr+1);
*pntr = b1;
*(pntr+1) = b0;
}
/*---------------- _swapAnalyzeHdr ------------------------------------------*/
static void _swapAnalyzeHdr( struct dsr *pntr)
{
_swapLong((unsigned char*) &pntr->hk.sizeof_hdr) ;
_swapLong((unsigned char*) &pntr->hk.extents) ;
_swapShort((unsigned char*) &pntr->hk.session_error) ;
_swapShort((unsigned char*) &pntr->dime.dim[0]) ;
_swapShort((unsigned char*) &pntr->dime.dim[1]) ;
_swapShort((unsigned char*) &pntr->dime.dim[2]) ;
_swapShort((unsigned char*) &pntr->dime.dim[3]) ;
_swapShort((unsigned char*) &pntr->dime.dim[4]) ;
_swapShort((unsigned char*) &pntr->dime.dim[5]) ;
_swapShort((unsigned char*) &pntr->dime.dim[6]) ;
_swapShort((unsigned char*) &pntr->dime.dim[7]) ;
_swapShort((unsigned char*) &pntr->dime.unused1) ;
_swapShort((unsigned char*) &pntr->dime.datatype) ;
_swapShort((unsigned char*) &pntr->dime.bitpix) ;
_swapLong((unsigned char*) &pntr->dime.pixdim[0]) ;
_swapLong((unsigned char*) &pntr->dime.pixdim[1]) ;
_swapLong((unsigned char*) &pntr->dime.pixdim[2]) ;
_swapLong((unsigned char*) &pntr->dime.pixdim[3]) ;
_swapLong((unsigned char*) &pntr->dime.pixdim[4]) ;
_swapLong((unsigned char*) &pntr->dime.pixdim[5]) ;
_swapLong((unsigned char*) &pntr->dime.pixdim[6]) ;
_swapLong((unsigned char*) &pntr->dime.pixdim[7]) ;
_swapLong((unsigned char*) &pntr->dime.vox_offset) ;
_swapLong((unsigned char*) &pntr->dime.funused1) ;
_swapLong((unsigned char*) &pntr->dime.funused2) ;
_swapLong((unsigned char*) &pntr->dime.cal_max) ;
_swapLong((unsigned char*) &pntr->dime.cal_min) ;
_swapLong((unsigned char*) &pntr->dime.compressed) ;
_swapLong((unsigned char*) &pntr->dime.verified) ;
_swapShort((unsigned char*) &pntr->dime.dim_un0) ;
_swapLong((unsigned char*) &pntr->dime.glmax) ;
_swapLong((unsigned char*) &pntr->dime.glmin) ;
}
PTRIMAGE_FORMAT createAnalyzeFormat() {
PTRIMAGE_FORMAT f=(PTRIMAGE_FORMAT) ImageIO_alloc(sizeof(IMAGE_FORMAT));
f->testImageFormat=&testAnalyzeHeader;
f->readImageHeader=&readAnalyzeHeader;
f->writeImage=&writeAnalyze;
strcpy(f->fileExtension,".hdr,.hdr.gz,.img,.img.gz");
strcpy(f->realName,"Analyze");
return f;
}
int testAnalyzeHeader(char *magic,const char *) {
/* opened image is an ANALYZE */
if( !memcmp(magic,ANALYZE_LE_MAGIC,4) ||
!memcmp(magic,ANALYZE_BE_MAGIC,4))
return 0;
else
return -1;
}
int writeAnalyze( char *name, _image* im) {
char *outputName;
int length, extLength=0, res;
length=strlen(name);
outputName= (char *)ImageIO_alloc(length+8);
if ( strncmp( name+length-4, ".hdr", 4 ) == 0 ) {
extLength = 4;
}
else if ( strncmp( name+length-4, ".img", 4 ) == 0 ) {
extLength = 4;
}
else if ( strncmp( name+length-7, ".img.gz", 7 ) == 0 ) {
extLength = 7;
}
else if ( strncmp( name+length-7, ".hdr.gz", 7 ) == 0 ) {
extLength = 7;
}
strncpy( outputName, name, length-extLength );
if ( strncmp( name+length-7, ".hdr.gz", 7 ) == 0 )
strcpy( outputName+length-extLength, ".hdr.gz" );
else
strcpy( outputName+length-extLength, ".hdr" );
_openWriteImage(im, outputName);
if( !im->fd ) {
fprintf(stderr, "writeAnalyze: error: unable to open file \'%s\'\n", outputName);
if ( outputName != NULL ) ImageIO_free( outputName );
return ImageIO_OPENING;
}
res = writeAnalyzeHeader(im);
if ( res < 0 ) {
fprintf(stderr, "writeAnalyze: error: unable to write header of \'%s\'\n",
outputName);
if ( outputName != NULL ) ImageIO_free( outputName );
ImageIO_close( im );
im->fd = NULL;
im->openMode = OM_CLOSE;
return( res );
}
ImageIO_close(im);
strncpy( outputName, name, length-extLength );
if ( strncmp( name+length-3, ".gz", 3 ) == 0 ) {
strcpy( outputName+length-extLength, ".img.gz" );
}
else {
strcpy( outputName+length-extLength, ".img" );
}
_openWriteImage(im, outputName);
if( !im->fd ) {
fprintf(stderr, "writeAnalyze: error: unable to open file \'%s\'\n", outputName);
if ( outputName != NULL ) ImageIO_free( outputName );
return ImageIO_OPENING;
}
res = writeAnalyzeData(im);
if (res < 0) {
fprintf(stderr, "writeAnalyze: error: unable to write data in \'%s\'\n",
outputName );
ImageIO_close( im );
im->fd = NULL;
im->openMode = OM_CLOSE;
return( res );
}
if ( outputName != NULL ) ImageIO_free( outputName );
ImageIO_close( im );
im->fd = NULL;
im->openMode = OM_CLOSE;
return ( res );
}
/*
return:
-1: error
0: success
*/
int _readAnalyzeHeader( _image* im, const char* name,
struct dsr *analyzeHeader )
{
unsigned int i ;
/* compile time endianness */
ENDIANNESS ARCHITECTURE_ENDIANNESS = _getEndianness();
if(im->openMode != OM_CLOSE) {
ImageIO_read( im, analyzeHeader, sizeof(struct dsr) );
if( analyzeHeader->hk.sizeof_hdr == sizeof(struct dsr) )
{
im->endianness = ARCHITECTURE_ENDIANNESS ;
}
else
{
_swapAnalyzeHdr( analyzeHeader );
if( analyzeHeader->hk.sizeof_hdr != sizeof(struct dsr) )
{
fprintf (stderr,
"_readAnalyzeHeader: error: unknown magic (%d)...\n",
analyzeHeader->hk.sizeof_hdr );
return -1;
}
if( ARCHITECTURE_ENDIANNESS == END_LITTLE )
{
im->endianness = END_BIG;
}
else
{
im->endianness = END_LITTLE;
}
}
if ( analyzeHeader->dime.dim[0] > 4 ) {
fprintf (stderr,
"_readAnalyzeHeader: error: dimensionality not supported (%d)...\n",
analyzeHeader->dime.dim[0] );
return -1;
}
im->xdim = analyzeHeader->dime.dim[1];
im->ydim = analyzeHeader->dime.dim[2];
im->zdim = analyzeHeader->dime.dim[3];
/* 0 time-points is a convention for one volume only at MNI */
/* Corrected by X. Pennec following a bug report by Irina Kezele at MNI */
if( analyzeHeader->dime.dim[4] == 0 ){
fprintf (stderr,
"_readAnalyzeHeader: warning: time dimension / number if volume (dim[4]) is 0. Assuming this means 1 (otherwise there would be no image...). \n");
analyzeHeader->dime.dim[4] = 1;
}
/* Analyze doesn't support vector images.
The forth dimension relates to time. */
if( analyzeHeader->dime.dim[4] != 1 )
{
fprintf (stderr,
"_readAnalyzeHeader: error: time dimension not supported (%d)...\n",
analyzeHeader->dime.dim[4] );
return -1;
}
im->vectMode = VM_SCALAR;
im->vx = analyzeHeader->dime.pixdim[1];
im->vy = analyzeHeader->dime.pixdim[2];
im->vz = analyzeHeader->dime.pixdim[3];
if( im->vx == 0.0 ) im->vx = 1.0 ;
if( im->vy == 0.0 ) im->vy = im->vx ;
if( im->vz == 0.0 ) im->vz = im->vy ;
switch(analyzeHeader->dime.datatype)
{
case DT_BINARY:
case DT_UNSIGNED_CHAR:
case DT_SIGNED_SHORT:
case DT_SIGNED_INT:
case DT_FLOAT:
case DT_COMPLEX:
case DT_DOUBLE:
im->vdim = 1;
break ;
case DT_RGB:
im->vdim = 3;
break ;
default:
fprintf (stderr,
"_readAnalyzeHeader: error: data type not supported (%d)...\n",
analyzeHeader->dime.datatype );
return -1;
}
switch(analyzeHeader->dime.datatype)
{
case DT_BINARY:
case DT_UNSIGNED_CHAR:
case DT_SIGNED_SHORT:
case DT_SIGNED_INT:
case DT_RGB:
im->wordKind = WK_FIXED;
break ;
case DT_FLOAT:
case DT_COMPLEX:
case DT_DOUBLE:
im->wordKind = WK_FLOAT;
break ;
default:
fprintf (stderr,
"_readAnalyzeHeader: error: data type not supported (%d)...\n",
analyzeHeader->dime.datatype );
return -1;
}
switch(analyzeHeader->dime.datatype)
{
case DT_BINARY:
case DT_UNSIGNED_CHAR:
case DT_RGB:
im->sign = SGN_UNSIGNED;
break ;
case DT_SIGNED_SHORT:
case DT_SIGNED_INT:
case DT_FLOAT:
case DT_COMPLEX:
case DT_DOUBLE:
im->sign = SGN_SIGNED;
break ;
default:
fprintf (stderr,
"_readAnalyzeHeader: error: data type not supported (%d)...\n",
analyzeHeader->dime.datatype );
return -1;
}
im->wdim = analyzeHeader->dime.bitpix;
if( analyzeHeader->dime.datatype == DT_RGB )
{
im->wdim /= 3 ;
}
if(im->wdim != 8 && im->wdim != 16 && im->wdim != 32 && im->wdim != 64)
{
fprintf (stderr,
"_readAnalyzeHeader: error: pixel size not supported (%d)...\n",
analyzeHeader->dime.bitpix );
return -1;
}
im->wdim >>= 3 ;
/* There are 17 optional data fields
be careful in the allocation
*/
im->nuser = 1 + 17 ;
im->user = (char **) ImageIO_alloc(im->nuser * sizeof(char *));
for ( i=0; i<im->nuser; i++ ) im->user[i] = NULL;
i = 0 ;
im->user[i] = (char *) ImageIO_alloc((strlen("Data lost in the Analyze -> ImageIO conversion:") + 1));
sprintf( im->user[i++], "Data lost in the Analyze -> ImageIO conversion:" );
im->user[i] = (char *) ImageIO_alloc((strlen(" descrip: ") + 1 + strlen(analyzeHeader->hist.descrip) ));
sprintf( im->user[i++], " descrip: %s", analyzeHeader->hist.descrip );
im->user[i] = (char *) ImageIO_alloc((strlen(" aux_file: ") + 1 + strlen(analyzeHeader->hist.descrip) ));
sprintf( im->user[i++], " aux_file: %s", analyzeHeader->hist.descrip );
im->user[i] = (char *) ImageIO_alloc((strlen(" orient: ") + 1+ 2));
sprintf( im->user[i++], " orient: %d", analyzeHeader->hist.orient );
im->user[i] = (char *) ImageIO_alloc((strlen(" originator: ") + 1 + strlen(analyzeHeader->hist.originator) ));
sprintf( im->user[i++], " originator: %s", analyzeHeader->hist.originator );
im->user[i] = (char *) ImageIO_alloc((strlen(" generated: ") + 1 + strlen(analyzeHeader->hist.generated) ));
sprintf( im->user[i++], " generated: %s", analyzeHeader->hist.generated );
im->user[i] = (char *) ImageIO_alloc((strlen(" scannum: ") + 1 + strlen(analyzeHeader->hist.scannum) ));
sprintf( im->user[i++], " scannum: %s", analyzeHeader->hist.scannum );
im->user[i] = (char *) ImageIO_alloc((strlen(" patient_id: ") + 1 + strlen(analyzeHeader->hist.patient_id) ));
sprintf( im->user[i++], " patient_id: %s", analyzeHeader->hist.patient_id );
im->user[i] = (char *) ImageIO_alloc((strlen(" exp_date: ") + 1 + strlen(analyzeHeader->hist.exp_date) ));
sprintf( im->user[i++], " exp_date: %s", analyzeHeader->hist.exp_date );
im->user[i] = (char *) ImageIO_alloc((strlen(" exp_time: ") + 1 + strlen(analyzeHeader->hist.exp_time) ));
sprintf( im->user[i++], " exp_time: %s", analyzeHeader->hist.exp_time );
/* A 32 bit int doesn't print on more than 11 chars */
im->user[i] = (char *) ImageIO_alloc((strlen(" views: ") + 11 + 1));
sprintf( im->user[i++], " views: %d", analyzeHeader->hist.views );
im->user[i] = (char *) ImageIO_alloc((strlen(" vols_added: ") + 11 + 1));
sprintf( im->user[i++], " vols_added: %d", analyzeHeader->hist.vols_added );
im->user[i] = (char *) ImageIO_alloc((strlen(" start_field: ") + 11 + 1));
sprintf( im->user[i++], " start_field: %d", analyzeHeader->hist.start_field );
im->user[i] = (char *) ImageIO_alloc((strlen(" field_skip: ") + 11 + 1));
sprintf( im->user[i++], " field_skip: %d", analyzeHeader->hist.field_skip );
im->user[i] = (char *) ImageIO_alloc((strlen(" omax: ") + 11 + 1));
sprintf( im->user[i++], " omax: %d", analyzeHeader->hist.omax );
im->user[i] = (char *) ImageIO_alloc((strlen(" omin: ") + 11 + 1));
sprintf( im->user[i++], " omin: %d", analyzeHeader->hist.omin );
im->user[i] = (char *) ImageIO_alloc((strlen(" smax: ") + 11 + 1));
sprintf( im->user[i++], " smax: %d", analyzeHeader->hist.smax );
im->user[i] = (char *) ImageIO_alloc((strlen(" smin: ") + 11 + 1));
sprintf( im->user[i++], " smin: %d", analyzeHeader->hist.smin );
/* header is read. close header file and open data file. */
if( name != NULL ) {
int length = strlen(name) ;
char* data_filename = (char *) ImageIO_alloc(length+4) ;
if( strcmp( name+length-4, ".hdr" ) )
{
fprintf (stderr,
"_readAnalyzeHeader: error: file header extension must be .hdr\n");
ImageIO_free( data_filename );
return -1;
}
ImageIO_close(im);
strcpy(data_filename,name);
strcpy(data_filename+length-3, "img.gz");
_openReadImage(im,data_filename);
if(!im->fd) {
strcpy(data_filename,name);
strcpy(data_filename+length-3, "img");
_openReadImage(im,data_filename);
if(!im->fd) {
fprintf(stderr, "_readAnalyzeHeader: error: unable to open data file \'%s\'\n", data_filename);
ImageIO_free( data_filename );
return -1;
}
}
ImageIO_free( data_filename );
}
/* check header validity */
if(im->xdim > 0 && im->ydim > 0 && im->zdim > 0 && im->vdim > 0 &&
im->vx > 0.0 && im->vy > 0.0 && im->vz > 0.0 &&
(im->wordKind == WK_FLOAT || (im->wordKind == WK_FIXED &&
im->sign != SGN_UNKNOWN)) &&
im->endianness != END_UNKNOWN) {
return 0;
}
else return -1;
}
else return -1;
}
int readAnalyzeHeader( const char* name, _image* im)
{
struct dsr analyzeHeader ;
return( _readAnalyzeHeader( im, name, &analyzeHeader ) );
}
int
writeAnalyzeHeader( const _image* im )
{
const char *proc = "writeAnalyzeHeader";
struct dsr hdr;
int i ;
int imin = 0;
int imax = 0;
memset(&hdr,0, sizeof(struct dsr));
for(i=0;i<8;i++) {
hdr.dime.pixdim[i] = 0.0;
}
hdr.dime.vox_offset = 0.0;
hdr.dime.funused1 = 0.0;
hdr.dime.funused2 = 0.0;
hdr.dime.funused3 = 0.0;
hdr.dime.cal_max = 0.0;
hdr.dime.cal_min = 0.0;
hdr.dime.dim[0] = 4;
hdr.dime.dim[1] = im->xdim;
hdr.dime.dim[2] = im->ydim;
hdr.dime.dim[3] = im->zdim;
hdr.dime.dim[4] = 1 ;
if ( im->wordKind == WK_FIXED && im->sign == SGN_UNSIGNED ) {
if( im->wdim == 1 ) {
if ( im->vdim == 1 ) {
hdr.dime.datatype = DT_UNSIGNED_CHAR ;
}
else if ( im->vdim == 3 ) {
hdr.dime.datatype = DT_RGB ;
}
else {
fprintf( stderr, "%s: unsupported image type\n", proc );
return -1;
}
{
unsigned char *buf = (unsigned char *)im->data;
int size = im->xdim * im->ydim * im->zdim * im->vdim;
imin = imax = *buf;
for (i=0; i<size; i++, buf++) {
if ( imax < *buf ) imax = *buf;
if ( imin > *buf ) imin = *buf;
}
}
}
else if ( im->wdim == 2 ) {
if ( im->vdim == 1 ) {
unsigned short int *buf = (unsigned short int*)im->data;
int size = im->xdim * im->ydim *im->zdim;
int i;
imin = imax = *buf;
for (i=0; i<size; i++, buf++) {
if ( imax < *buf ) imax = *buf;
if ( imin > *buf ) imin = *buf;
}
if ( imax < 32768 ) {
hdr.dime.datatype = DT_SIGNED_SHORT ;
}
else {
fprintf( stderr, "%s: conversion from unsigned short to short impossible, max=%d\n", proc, imax );
return -1;
}
}
else {
fprintf( stderr, "%s: unsupported image type\n", proc );
return -1;
}
}
else {
fprintf( stderr, "%s: unsupported image type\n", proc );
return -1;
}
} /* if ( im->wordKind == WK_FIXED && im->sign == SGN_UNSIGNED ) */
else if( im->wordKind == WK_FIXED && im->sign == SGN_SIGNED ) {
if ( im->vdim != 1 ) {
fprintf( stderr, "%s: unsupported image type\n", proc );
return -1;
}
if( im->wdim == 2 ) {
short int *buf = (short int*)im->data;
int size = im->xdim * im->ydim *im->zdim;
int i;
imin = imax = *buf;
for (i=0; i<size; i++, buf++) {
if ( imax < *buf ) imax = *buf;
if ( imin > *buf ) imin = *buf;
}
hdr.dime.datatype = DT_SIGNED_SHORT ;
}
else if( im->wdim == 4 ) {
int *buf = (int*)im->data;
int size = im->xdim * im->ydim *im->zdim;
int i;
imin = imax = *buf;
for (i=0; i<size; i++, buf++) {
if ( imax < *buf ) imax = *buf;
if ( imin > *buf ) imin = *buf;
}
hdr.dime.datatype = DT_SIGNED_INT ;
}
else {
fprintf( stderr, "%s: unsupported image type\n", proc );
return -1;
}
}
else if( im->wordKind == WK_FLOAT ) {
if ( im->vdim != 1 ) {
fprintf( stderr, "%s: unsupported image type\n", proc );
return -1;
}
if( im->wdim == 4 ) {
hdr.dime.datatype = DT_FLOAT ;
}
else if( im->wdim == 8 ) {
hdr.dime.datatype = DT_DOUBLE ;
}
else {
fprintf( stderr, "%s: unsupported image type\n", proc );
return -1;
}
}
else
{
fprintf( stderr, "%s: unsupported image type\n", proc );
return -1;
}
hdr.dime.bitpix = 8*im->wdim*im->vdim ;
hdr.hk.regular = 'r';
hdr.hk.sizeof_hdr = sizeof(struct dsr);
/* this is probably bad and should be changed to the
real values, but I'm too lazy to do it now. AG */
hdr.dime.glmax = 0 ; /* maximum voxel value */
hdr.dime.glmin = 0 ; /* minimum voxel value */
/* corrected GM
*/
hdr.dime.glmax = imax ; /* maximum voxel value */
hdr.dime.glmin = imin ; /* minimum voxel value */
/* Set the voxel dimension fields:
A value of 0.0 for these fields implies that the value is unknown.
Change these values to what is appropriate for your data
or pass additional command line arguments */
hdr.dime.pixdim[1] = (float)im->vx;
hdr.dime.pixdim[2] = (float)im->vy;
hdr.dime.pixdim[3] = (float)im->vz;
/* Assume zero offset in .img file, byte at which pixel
data starts in the image file */
hdr.dime.vox_offset = 0.0;
/* Planar Orientation; */
/* Movie flag OFF: 0 = transverse, 1 = coronal, 2 = sagittal
Movie flag ON: 3 = transverse, 4 = coronal, 5 = sagittal */
hdr.hist.orient = 0;
/* up to 3 characters for the voxels units label; i.e. mm., um., cm. */
strcpy(hdr.dime.vox_units,"mm.");
/* up to 7 characters for the calibration units label; i.e. HU */
strcpy(hdr.dime.cal_units," ");
/* Calibration maximum and minimum values;
values of 0.0 for both fields imply that no
calibration max and min values are used */
hdr.dime.cal_max = 0.0;
hdr.dime.cal_min = 0.0;
if(ImageIO_write(im, &hdr, sizeof(struct dsr)) !=sizeof(struct dsr) )
return -1;
return 1 ;
}
/* Writes the given image body in an already opened file.*/
int writeAnalyzeData(const _image *im) {
unsigned int lineSize = im->wdim * im->xdim * im->vdim ;
unsigned long size = lineSize * im->ydim * im->zdim;
unsigned int nwrt ;
if(im->openMode != OM_CLOSE) {
#ifdef _REVERSE_LINES_IN_ANALYZE_
char* data = (char *)im->data ;
char* buf = data + size - lineSize ;
while( buf >= data )
{
nwrt = ImageIO_write(im, buf, lineSize);
if(nwrt != lineSize) return -1;
buf -= lineSize ;
}
#else
nwrt = ImageIO_write(im, im->data, size);
if(nwrt != size) return -1;
#endif
return 1 ;
}
else return -1;
}
/* Writes the given image body in an already opened file.*/
int printAnalyzeHeader( const char* name )
{
_image *im;
struct dsr analyzeHeader ;
im = _initImage();
_openReadImage(im, name);
if(!im->fd) {
fprintf(stderr, "printAnalyzeHeader: error: unable to open file \'%s\'\n", name);
_freeImage(im);
return -1;
}
if ( _readAnalyzeHeader( im, name, &analyzeHeader ) != 1 ) {
fprintf(stderr, "printAnalyzeHeader: error: unable to read header in file \'%s\'\n", name);
_freeImage(im);
return -1;
}
ImageIO_close(im);
im->fd = NULL;
im->openMode = OM_CLOSE;
_freeImage(im);
return( 1 );
}
#endif // CGAL_HEADER_ONLY

View File

@ -67,5 +67,8 @@ int writeAnalyzeHeader( const _image* im ) ;
*/
int writeAnalyzeData( const _image* im ) ;
#ifdef CGAL_HEADER_ONLY
#include "analyse_impl.h"
#endif // CGAL_HEADER_ONLY
#endif

View File

@ -0,0 +1,848 @@
// Copyright (c) 2005-2008 ASCLEPIOS Project, INRIA Sophia-Antipolis (France)
// All rights reserved.
//
// This file is part of the ImageIO Library, and as been adapted for
// CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the
// GNU Lesser General Public License as published by the Free Software Foundation;
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// These files are provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
//
//
// Author(s) : ASCLEPIOS Project (INRIA Sophia-Antipolis), Laurent Rineau
#ifdef CGAL_HEADER_ONLY
#define CGAL_INLINE_FUNCTION inline
#else
#define CGAL_INLINE_FUNCTION
#endif
/* compile time endianness */
/* replaced by _getEndianness()
see below
#if (defined (_ALPHA_) || defined (_LINUX_))
#define ARCHITECTURE_ENDIANNESS END_LITTLE
#else
#define ARCHITECTURE_ENDIANNESS END_BIG
#endif
*/
/** Magic header for ANALYZE files written in little endian format */
#define ANALYZE_LE_MAGIC "\000\000\001\134"
/** Magic header for ANALYZE files written in big endian format */
#define ANALYZE_BE_MAGIC "\134\001\000\000"
#define DT_NONE 0
#define DT_UNKNOWN 0 /*Unknown data type*/
#define DT_BINARY 1 /*Binary (1 bit per voxel)*/
#define DT_UNSIGNED_CHAR 2 /*Unsigned character (8 bits per voxel)*/
#define DT_SIGNED_SHORT 4 /*Signed short (16 bits per voxel)*/
#define DT_SIGNED_INT 8 /*Signed integer (32 bits per voxel)*/
#define DT_FLOAT 16 /*Floating point (32 bits per voxel)*/
#define DT_COMPLEX 32 /*Complex (64 bits per voxel; 2 floating point numbers) */
#define DT_DOUBLE 64 /*Double precision (64 bits per voxel)*/
#define DT_RGB 128 /* */
#define DT_ALL 255 /* */
struct header_key /* header_key */
{ /* off + size*/
int sizeof_hdr; /* 0 + 4 */
char data_type[10]; /* 4 + 10 */
char db_name[18]; /* 14 + 18 */
int extents; /* 32 + 4 */
short int session_error; /* 36 + 2 */
char regular; /* 38 + 1 */
char hkey_un0; /* 39 + 1 */
}; /* total=40 */
struct image_dimension /* image_dimension */
{ /* off + size*/
short int dim[8]; /* 0 + 16 */
char vox_units[4]; /* 16 + 4 */
char cal_units[8]; /* 20 + 4 */
short int unused1; /* 24 + 2 */
short int datatype; /* 30 + 2 */
short int bitpix; /* 32 + 2 */
short int dim_un0; /* 34 + 2 */
float pixdim[8]; /* 36 + 32 */
/*
pixdim[] specifies the voxel dimensions:
pixdim[1] - voxel width
pixdim[2] - voxel height
pixdim[3] - interslice distance
..etc
*/
float vox_offset; /* 68 + 4 */
float funused1; /* 72 + 4 */
float funused2; /* 76 + 4 */
float funused3; /* 80 + 4 */
float cal_max; /* 84 + 4 */
float cal_min; /* 88 + 4 */
int compressed; /* 92 + 4 */
int verified; /* 96 + 4 */
int glmax, glmin; /* 100 + 8 */
}; /* total=108 */
struct data_history /* data_history */
{ /* off + size*/
char descrip[80]; /* 0 + 80 */
char aux_file[24]; /* 80 + 24 */
char orient; /* 104 + 1 */
char originator[10]; /* 105 + 10 */
char generated[10]; /* 115 + 10 */
char scannum[10]; /* 125 + 10 */
char patient_id[10]; /* 135 + 10 */
char exp_date[10]; /* 145 + 10 */
char exp_time[10]; /* 155 + 10 */
char hist_un0[3]; /* 165 + 3 */
int views; /* 168 + 4 */
int vols_added; /* 172 + 4 */
int start_field; /* 176 + 4 */
int field_skip; /* 180 + 4 */
int omax,omin; /* 184 + 8 */
int smax,smin; /* 192 + 8 */
};
struct dsr /* dsr */
{ /* off + size*/
struct header_key hk; /* 0 + 40 */
struct image_dimension dime; /* 40 + 108 */
struct data_history hist; /* 148 + 200 */
}; /* total=348 */
/*---------------- _swapLong ------------------------------------------------*/
CGAL_INLINE_FUNCTION
static void _swapLong( unsigned char *pntr)
{
unsigned char b0, b1, b2, b3;
b0 = *pntr;
b1 = *(pntr+1);
b2 = *(pntr+2);
b3 = *(pntr+3);
*pntr = b3;
*(pntr+1) = b2;
*(pntr+2) = b1;
*(pntr+3) = b0;
}
/*---------------- _swapShort -----------------------------------------------*/
CGAL_INLINE_FUNCTION
static void _swapShort( unsigned char *pntr)
{
unsigned char b0, b1;
b0 = *pntr;
b1 = *(pntr+1);
*pntr = b1;
*(pntr+1) = b0;
}
/*---------------- _swapAnalyzeHdr ------------------------------------------*/
CGAL_INLINE_FUNCTION
static void _swapAnalyzeHdr( struct dsr *pntr)
{
_swapLong((unsigned char*) &pntr->hk.sizeof_hdr) ;
_swapLong((unsigned char*) &pntr->hk.extents) ;
_swapShort((unsigned char*) &pntr->hk.session_error) ;
_swapShort((unsigned char*) &pntr->dime.dim[0]) ;
_swapShort((unsigned char*) &pntr->dime.dim[1]) ;
_swapShort((unsigned char*) &pntr->dime.dim[2]) ;
_swapShort((unsigned char*) &pntr->dime.dim[3]) ;
_swapShort((unsigned char*) &pntr->dime.dim[4]) ;
_swapShort((unsigned char*) &pntr->dime.dim[5]) ;
_swapShort((unsigned char*) &pntr->dime.dim[6]) ;
_swapShort((unsigned char*) &pntr->dime.dim[7]) ;
_swapShort((unsigned char*) &pntr->dime.unused1) ;
_swapShort((unsigned char*) &pntr->dime.datatype) ;
_swapShort((unsigned char*) &pntr->dime.bitpix) ;
_swapLong((unsigned char*) &pntr->dime.pixdim[0]) ;
_swapLong((unsigned char*) &pntr->dime.pixdim[1]) ;
_swapLong((unsigned char*) &pntr->dime.pixdim[2]) ;
_swapLong((unsigned char*) &pntr->dime.pixdim[3]) ;
_swapLong((unsigned char*) &pntr->dime.pixdim[4]) ;
_swapLong((unsigned char*) &pntr->dime.pixdim[5]) ;
_swapLong((unsigned char*) &pntr->dime.pixdim[6]) ;
_swapLong((unsigned char*) &pntr->dime.pixdim[7]) ;
_swapLong((unsigned char*) &pntr->dime.vox_offset) ;
_swapLong((unsigned char*) &pntr->dime.funused1) ;
_swapLong((unsigned char*) &pntr->dime.funused2) ;
_swapLong((unsigned char*) &pntr->dime.cal_max) ;
_swapLong((unsigned char*) &pntr->dime.cal_min) ;
_swapLong((unsigned char*) &pntr->dime.compressed) ;
_swapLong((unsigned char*) &pntr->dime.verified) ;
_swapShort((unsigned char*) &pntr->dime.dim_un0) ;
_swapLong((unsigned char*) &pntr->dime.glmax) ;
_swapLong((unsigned char*) &pntr->dime.glmin) ;
}
CGAL_INLINE_FUNCTION
PTRIMAGE_FORMAT createAnalyzeFormat() {
PTRIMAGE_FORMAT f=(PTRIMAGE_FORMAT) ImageIO_alloc(sizeof(IMAGE_FORMAT));
f->testImageFormat=&testAnalyzeHeader;
f->readImageHeader=&readAnalyzeHeader;
f->writeImage=&writeAnalyze;
strcpy(f->fileExtension,".hdr,.hdr.gz,.img,.img.gz");
strcpy(f->realName,"Analyze");
return f;
}
CGAL_INLINE_FUNCTION
int testAnalyzeHeader(char *magic,const char *) {
/* opened image is an ANALYZE */
if( !memcmp(magic,ANALYZE_LE_MAGIC,4) ||
!memcmp(magic,ANALYZE_BE_MAGIC,4))
return 0;
else
return -1;
}
CGAL_INLINE_FUNCTION
int writeAnalyze( char *name, _image* im) {
char *outputName;
int length, extLength=0, res;
length=strlen(name);
outputName= (char *)ImageIO_alloc(length+8);
if ( strncmp( name+length-4, ".hdr", 4 ) == 0 ) {
extLength = 4;
}
else if ( strncmp( name+length-4, ".img", 4 ) == 0 ) {
extLength = 4;
}
else if ( strncmp( name+length-7, ".img.gz", 7 ) == 0 ) {
extLength = 7;
}
else if ( strncmp( name+length-7, ".hdr.gz", 7 ) == 0 ) {
extLength = 7;
}
strncpy( outputName, name, length-extLength );
if ( strncmp( name+length-7, ".hdr.gz", 7 ) == 0 )
strcpy( outputName+length-extLength, ".hdr.gz" );
else
strcpy( outputName+length-extLength, ".hdr" );
_openWriteImage(im, outputName);
if( !im->fd ) {
fprintf(stderr, "writeAnalyze: error: unable to open file \'%s\'\n", outputName);
if ( outputName != NULL ) ImageIO_free( outputName );
return ImageIO_OPENING;
}
res = writeAnalyzeHeader(im);
if ( res < 0 ) {
fprintf(stderr, "writeAnalyze: error: unable to write header of \'%s\'\n",
outputName);
if ( outputName != NULL ) ImageIO_free( outputName );
ImageIO_close( im );
im->fd = NULL;
im->openMode = OM_CLOSE;
return( res );
}
ImageIO_close(im);
strncpy( outputName, name, length-extLength );
if ( strncmp( name+length-3, ".gz", 3 ) == 0 ) {
strcpy( outputName+length-extLength, ".img.gz" );
}
else {
strcpy( outputName+length-extLength, ".img" );
}
_openWriteImage(im, outputName);
if( !im->fd ) {
fprintf(stderr, "writeAnalyze: error: unable to open file \'%s\'\n", outputName);
if ( outputName != NULL ) ImageIO_free( outputName );
return ImageIO_OPENING;
}
res = writeAnalyzeData(im);
if (res < 0) {
fprintf(stderr, "writeAnalyze: error: unable to write data in \'%s\'\n",
outputName );
ImageIO_close( im );
im->fd = NULL;
im->openMode = OM_CLOSE;
return( res );
}
if ( outputName != NULL ) ImageIO_free( outputName );
ImageIO_close( im );
im->fd = NULL;
im->openMode = OM_CLOSE;
return ( res );
}
/*
return:
-1: error
0: success
*/
CGAL_INLINE_FUNCTION
int _readAnalyzeHeader( _image* im, const char* name,
struct dsr *analyzeHeader )
{
unsigned int i ;
/* compile time endianness */
ENDIANNESS ARCHITECTURE_ENDIANNESS = _getEndianness();
if(im->openMode != OM_CLOSE) {
ImageIO_read( im, analyzeHeader, sizeof(struct dsr) );
if( analyzeHeader->hk.sizeof_hdr == sizeof(struct dsr) )
{
im->endianness = ARCHITECTURE_ENDIANNESS ;
}
else
{
_swapAnalyzeHdr( analyzeHeader );
if( analyzeHeader->hk.sizeof_hdr != sizeof(struct dsr) )
{
fprintf (stderr,
"_readAnalyzeHeader: error: unknown magic (%d)...\n",
analyzeHeader->hk.sizeof_hdr );
return -1;
}
if( ARCHITECTURE_ENDIANNESS == END_LITTLE )
{
im->endianness = END_BIG;
}
else
{
im->endianness = END_LITTLE;
}
}
if ( analyzeHeader->dime.dim[0] > 4 ) {
fprintf (stderr,
"_readAnalyzeHeader: error: dimensionality not supported (%d)...\n",
analyzeHeader->dime.dim[0] );
return -1;
}
im->xdim = analyzeHeader->dime.dim[1];
im->ydim = analyzeHeader->dime.dim[2];
im->zdim = analyzeHeader->dime.dim[3];
/* 0 time-points is a convention for one volume only at MNI */
/* Corrected by X. Pennec following a bug report by Irina Kezele at MNI */
if( analyzeHeader->dime.dim[4] == 0 ){
fprintf (stderr,
"_readAnalyzeHeader: warning: time dimension / number if volume (dim[4]) is 0. Assuming this means 1 (otherwise there would be no image...). \n");
analyzeHeader->dime.dim[4] = 1;
}
/* Analyze doesn't support vector images.
The forth dimension relates to time. */
if( analyzeHeader->dime.dim[4] != 1 )
{
fprintf (stderr,
"_readAnalyzeHeader: error: time dimension not supported (%d)...\n",
analyzeHeader->dime.dim[4] );
return -1;
}
im->vectMode = VM_SCALAR;
im->vx = analyzeHeader->dime.pixdim[1];
im->vy = analyzeHeader->dime.pixdim[2];
im->vz = analyzeHeader->dime.pixdim[3];
if( im->vx == 0.0 ) im->vx = 1.0 ;
if( im->vy == 0.0 ) im->vy = im->vx ;
if( im->vz == 0.0 ) im->vz = im->vy ;
switch(analyzeHeader->dime.datatype)
{
case DT_BINARY:
case DT_UNSIGNED_CHAR:
case DT_SIGNED_SHORT:
case DT_SIGNED_INT:
case DT_FLOAT:
case DT_COMPLEX:
case DT_DOUBLE:
im->vdim = 1;
break ;
case DT_RGB:
im->vdim = 3;
break ;
default:
fprintf (stderr,
"_readAnalyzeHeader: error: data type not supported (%d)...\n",
analyzeHeader->dime.datatype );
return -1;
}
switch(analyzeHeader->dime.datatype)
{
case DT_BINARY:
case DT_UNSIGNED_CHAR:
case DT_SIGNED_SHORT:
case DT_SIGNED_INT:
case DT_RGB:
im->wordKind = WK_FIXED;
break ;
case DT_FLOAT:
case DT_COMPLEX:
case DT_DOUBLE:
im->wordKind = WK_FLOAT;
break ;
default:
fprintf (stderr,
"_readAnalyzeHeader: error: data type not supported (%d)...\n",
analyzeHeader->dime.datatype );
return -1;
}
switch(analyzeHeader->dime.datatype)
{
case DT_BINARY:
case DT_UNSIGNED_CHAR:
case DT_RGB:
im->sign = SGN_UNSIGNED;
break ;
case DT_SIGNED_SHORT:
case DT_SIGNED_INT:
case DT_FLOAT:
case DT_COMPLEX:
case DT_DOUBLE:
im->sign = SGN_SIGNED;
break ;
default:
fprintf (stderr,
"_readAnalyzeHeader: error: data type not supported (%d)...\n",
analyzeHeader->dime.datatype );
return -1;
}
im->wdim = analyzeHeader->dime.bitpix;
if( analyzeHeader->dime.datatype == DT_RGB )
{
im->wdim /= 3 ;
}
if(im->wdim != 8 && im->wdim != 16 && im->wdim != 32 && im->wdim != 64)
{
fprintf (stderr,
"_readAnalyzeHeader: error: pixel size not supported (%d)...\n",
analyzeHeader->dime.bitpix );
return -1;
}
im->wdim >>= 3 ;
/* There are 17 optional data fields
be careful in the allocation
*/
im->nuser = 1 + 17 ;
im->user = (char **) ImageIO_alloc(im->nuser * sizeof(char *));
for ( i=0; i<im->nuser; i++ ) im->user[i] = NULL;
i = 0 ;
im->user[i] = (char *) ImageIO_alloc((strlen("Data lost in the Analyze -> ImageIO conversion:") + 1));
sprintf( im->user[i++], "Data lost in the Analyze -> ImageIO conversion:" );
im->user[i] = (char *) ImageIO_alloc((strlen(" descrip: ") + 1 + strlen(analyzeHeader->hist.descrip) ));
sprintf( im->user[i++], " descrip: %s", analyzeHeader->hist.descrip );
im->user[i] = (char *) ImageIO_alloc((strlen(" aux_file: ") + 1 + strlen(analyzeHeader->hist.descrip) ));
sprintf( im->user[i++], " aux_file: %s", analyzeHeader->hist.descrip );
im->user[i] = (char *) ImageIO_alloc((strlen(" orient: ") + 1+ 2));
sprintf( im->user[i++], " orient: %d", analyzeHeader->hist.orient );
im->user[i] = (char *) ImageIO_alloc((strlen(" originator: ") + 1 + strlen(analyzeHeader->hist.originator) ));
sprintf( im->user[i++], " originator: %s", analyzeHeader->hist.originator );
im->user[i] = (char *) ImageIO_alloc((strlen(" generated: ") + 1 + strlen(analyzeHeader->hist.generated) ));
sprintf( im->user[i++], " generated: %s", analyzeHeader->hist.generated );
im->user[i] = (char *) ImageIO_alloc((strlen(" scannum: ") + 1 + strlen(analyzeHeader->hist.scannum) ));
sprintf( im->user[i++], " scannum: %s", analyzeHeader->hist.scannum );
im->user[i] = (char *) ImageIO_alloc((strlen(" patient_id: ") + 1 + strlen(analyzeHeader->hist.patient_id) ));
sprintf( im->user[i++], " patient_id: %s", analyzeHeader->hist.patient_id );
im->user[i] = (char *) ImageIO_alloc((strlen(" exp_date: ") + 1 + strlen(analyzeHeader->hist.exp_date) ));
sprintf( im->user[i++], " exp_date: %s", analyzeHeader->hist.exp_date );
im->user[i] = (char *) ImageIO_alloc((strlen(" exp_time: ") + 1 + strlen(analyzeHeader->hist.exp_time) ));
sprintf( im->user[i++], " exp_time: %s", analyzeHeader->hist.exp_time );
/* A 32 bit int doesn't print on more than 11 chars */
im->user[i] = (char *) ImageIO_alloc((strlen(" views: ") + 11 + 1));
sprintf( im->user[i++], " views: %d", analyzeHeader->hist.views );
im->user[i] = (char *) ImageIO_alloc((strlen(" vols_added: ") + 11 + 1));
sprintf( im->user[i++], " vols_added: %d", analyzeHeader->hist.vols_added );
im->user[i] = (char *) ImageIO_alloc((strlen(" start_field: ") + 11 + 1));
sprintf( im->user[i++], " start_field: %d", analyzeHeader->hist.start_field );
im->user[i] = (char *) ImageIO_alloc((strlen(" field_skip: ") + 11 + 1));
sprintf( im->user[i++], " field_skip: %d", analyzeHeader->hist.field_skip );
im->user[i] = (char *) ImageIO_alloc((strlen(" omax: ") + 11 + 1));
sprintf( im->user[i++], " omax: %d", analyzeHeader->hist.omax );
im->user[i] = (char *) ImageIO_alloc((strlen(" omin: ") + 11 + 1));
sprintf( im->user[i++], " omin: %d", analyzeHeader->hist.omin );
im->user[i] = (char *) ImageIO_alloc((strlen(" smax: ") + 11 + 1));
sprintf( im->user[i++], " smax: %d", analyzeHeader->hist.smax );
im->user[i] = (char *) ImageIO_alloc((strlen(" smin: ") + 11 + 1));
sprintf( im->user[i++], " smin: %d", analyzeHeader->hist.smin );
/* header is read. close header file and open data file. */
if( name != NULL ) {
int length = strlen(name) ;
char* data_filename = (char *) ImageIO_alloc(length+4) ;
if( strcmp( name+length-4, ".hdr" ) )
{
fprintf (stderr,
"_readAnalyzeHeader: error: file header extension must be .hdr\n");
ImageIO_free( data_filename );
return -1;
}
ImageIO_close(im);
strcpy(data_filename,name);
strcpy(data_filename+length-3, "img.gz");
_openReadImage(im,data_filename);
if(!im->fd) {
strcpy(data_filename,name);
strcpy(data_filename+length-3, "img");
_openReadImage(im,data_filename);
if(!im->fd) {
fprintf(stderr, "_readAnalyzeHeader: error: unable to open data file \'%s\'\n", data_filename);
ImageIO_free( data_filename );
return -1;
}
}
ImageIO_free( data_filename );
}
/* check header validity */
if(im->xdim > 0 && im->ydim > 0 && im->zdim > 0 && im->vdim > 0 &&
im->vx > 0.0 && im->vy > 0.0 && im->vz > 0.0 &&
(im->wordKind == WK_FLOAT || (im->wordKind == WK_FIXED &&
im->sign != SGN_UNKNOWN)) &&
im->endianness != END_UNKNOWN) {
return 0;
}
else return -1;
}
else return -1;
}
CGAL_INLINE_FUNCTION
int readAnalyzeHeader( const char* name, _image* im)
{
struct dsr analyzeHeader ;
return( _readAnalyzeHeader( im, name, &analyzeHeader ) );
}
CGAL_INLINE_FUNCTION
int
writeAnalyzeHeader( const _image* im )
{
const char *proc = "writeAnalyzeHeader";
struct dsr hdr;
int i ;
int imin = 0;
int imax = 0;
memset(&hdr,0, sizeof(struct dsr));
for(i=0;i<8;i++) {
hdr.dime.pixdim[i] = 0.0;
}
hdr.dime.vox_offset = 0.0;
hdr.dime.funused1 = 0.0;
hdr.dime.funused2 = 0.0;
hdr.dime.funused3 = 0.0;
hdr.dime.cal_max = 0.0;
hdr.dime.cal_min = 0.0;
hdr.dime.dim[0] = 4;
hdr.dime.dim[1] = im->xdim;
hdr.dime.dim[2] = im->ydim;
hdr.dime.dim[3] = im->zdim;
hdr.dime.dim[4] = 1 ;
if ( im->wordKind == WK_FIXED && im->sign == SGN_UNSIGNED ) {
if( im->wdim == 1 ) {
if ( im->vdim == 1 ) {
hdr.dime.datatype = DT_UNSIGNED_CHAR ;
}
else if ( im->vdim == 3 ) {
hdr.dime.datatype = DT_RGB ;
}
else {
fprintf( stderr, "%s: unsupported image type\n", proc );
return -1;
}
{
unsigned char *buf = (unsigned char *)im->data;
int size = im->xdim * im->ydim * im->zdim * im->vdim;
imin = imax = *buf;
for (i=0; i<size; i++, buf++) {
if ( imax < *buf ) imax = *buf;
if ( imin > *buf ) imin = *buf;
}
}
}
else if ( im->wdim == 2 ) {
if ( im->vdim == 1 ) {
unsigned short int *buf = (unsigned short int*)im->data;
int size = im->xdim * im->ydim *im->zdim;
int i;
imin = imax = *buf;
for (i=0; i<size; i++, buf++) {
if ( imax < *buf ) imax = *buf;
if ( imin > *buf ) imin = *buf;
}
if ( imax < 32768 ) {
hdr.dime.datatype = DT_SIGNED_SHORT ;
}
else {
fprintf( stderr, "%s: conversion from unsigned short to short impossible, max=%d\n", proc, imax );
return -1;
}
}
else {
fprintf( stderr, "%s: unsupported image type\n", proc );
return -1;
}
}
else {
fprintf( stderr, "%s: unsupported image type\n", proc );
return -1;
}
} /* if ( im->wordKind == WK_FIXED && im->sign == SGN_UNSIGNED ) */
else if( im->wordKind == WK_FIXED && im->sign == SGN_SIGNED ) {
if ( im->vdim != 1 ) {
fprintf( stderr, "%s: unsupported image type\n", proc );
return -1;
}
if( im->wdim == 2 ) {
short int *buf = (short int*)im->data;
int size = im->xdim * im->ydim *im->zdim;
int i;
imin = imax = *buf;
for (i=0; i<size; i++, buf++) {
if ( imax < *buf ) imax = *buf;
if ( imin > *buf ) imin = *buf;
}
hdr.dime.datatype = DT_SIGNED_SHORT ;
}
else if( im->wdim == 4 ) {
int *buf = (int*)im->data;
int size = im->xdim * im->ydim *im->zdim;
int i;
imin = imax = *buf;
for (i=0; i<size; i++, buf++) {
if ( imax < *buf ) imax = *buf;
if ( imin > *buf ) imin = *buf;
}
hdr.dime.datatype = DT_SIGNED_INT ;
}
else {
fprintf( stderr, "%s: unsupported image type\n", proc );
return -1;
}
}
else if( im->wordKind == WK_FLOAT ) {
if ( im->vdim != 1 ) {
fprintf( stderr, "%s: unsupported image type\n", proc );
return -1;
}
if( im->wdim == 4 ) {
hdr.dime.datatype = DT_FLOAT ;
}
else if( im->wdim == 8 ) {
hdr.dime.datatype = DT_DOUBLE ;
}
else {
fprintf( stderr, "%s: unsupported image type\n", proc );
return -1;
}
}
else
{
fprintf( stderr, "%s: unsupported image type\n", proc );
return -1;
}
hdr.dime.bitpix = 8*im->wdim*im->vdim ;
hdr.hk.regular = 'r';
hdr.hk.sizeof_hdr = sizeof(struct dsr);
/* this is probably bad and should be changed to the
real values, but I'm too lazy to do it now. AG */
hdr.dime.glmax = 0 ; /* maximum voxel value */
hdr.dime.glmin = 0 ; /* minimum voxel value */
/* corrected GM
*/
hdr.dime.glmax = imax ; /* maximum voxel value */
hdr.dime.glmin = imin ; /* minimum voxel value */
/* Set the voxel dimension fields:
A value of 0.0 for these fields implies that the value is unknown.
Change these values to what is appropriate for your data
or pass additional command line arguments */
hdr.dime.pixdim[1] = (float)im->vx;
hdr.dime.pixdim[2] = (float)im->vy;
hdr.dime.pixdim[3] = (float)im->vz;
/* Assume zero offset in .img file, byte at which pixel
data starts in the image file */
hdr.dime.vox_offset = 0.0;
/* Planar Orientation; */
/* Movie flag OFF: 0 = transverse, 1 = coronal, 2 = sagittal
Movie flag ON: 3 = transverse, 4 = coronal, 5 = sagittal */
hdr.hist.orient = 0;
/* up to 3 characters for the voxels units label; i.e. mm., um., cm. */
strcpy(hdr.dime.vox_units,"mm.");
/* up to 7 characters for the calibration units label; i.e. HU */
strcpy(hdr.dime.cal_units," ");
/* Calibration maximum and minimum values;
values of 0.0 for both fields imply that no
calibration max and min values are used */
hdr.dime.cal_max = 0.0;
hdr.dime.cal_min = 0.0;
if(ImageIO_write(im, &hdr, sizeof(struct dsr)) !=sizeof(struct dsr) )
return -1;
return 1 ;
}
/* Writes the given image body in an already opened file.*/
CGAL_INLINE_FUNCTION
int writeAnalyzeData(const _image *im) {
unsigned int lineSize = im->wdim * im->xdim * im->vdim ;
unsigned long size = lineSize * im->ydim * im->zdim;
unsigned int nwrt ;
if(im->openMode != OM_CLOSE) {
#ifdef _REVERSE_LINES_IN_ANALYZE_
char* data = (char *)im->data ;
char* buf = data + size - lineSize ;
while( buf >= data )
{
nwrt = ImageIO_write(im, buf, lineSize);
if(nwrt != lineSize) return -1;
buf -= lineSize ;
}
#else
nwrt = ImageIO_write(im, im->data, size);
if(nwrt != size) return -1;
#endif
return 1 ;
}
else return -1;
}
/* Writes the given image body in an already opened file.*/
CGAL_INLINE_FUNCTION
int printAnalyzeHeader( const char* name )
{
_image *im;
struct dsr analyzeHeader ;
im = _initImage();
_openReadImage(im, name);
if(!im->fd) {
fprintf(stderr, "printAnalyzeHeader: error: unable to open file \'%s\'\n", name);
_freeImage(im);
return -1;
}
if ( _readAnalyzeHeader( im, name, &analyzeHeader ) != 1 ) {
fprintf(stderr, "printAnalyzeHeader: error: unable to read header in file \'%s\'\n", name);
_freeImage(im);
return -1;
}
ImageIO_close(im);
im->fd = NULL;
im->openMode = OM_CLOSE;
_freeImage(im);
return( 1 );
}

View File

@ -124,7 +124,7 @@ int main() {
{
// fill the 2x2x2 image
for(int i = 0; i < 8; ++i) {
data[i] = CGAL::default_random.get_int(0,255);
data[i] = CGAL::get_default_random().get_int(0,255);
}
// test the difference between the two implementations

View File

@ -9,6 +9,8 @@ else()
cmake_minimum_required(VERSION 2.6.2)
endif()
# add_definitions(-DCGAL_HEADER_ONLY)
# option for branch build
option( CGAL_BRANCH_BUILD "Create CGAL from branch" ON)

View File

@ -40,7 +40,7 @@ int main() {
// Use a random permutation to hide the creation history
// of the point set.
std::random_shuffle( points.begin(), points.end(), default_random);
std::random_shuffle( points.begin(), points.end(), get_default_random());
// Check range of values.
for ( Vector::iterator i = points.begin(); i != points.end(); i++){

View File

@ -68,7 +68,7 @@ protected:
public:
typedef Random_generator_base<T> This;
Random_generator_base() : _rnd( default_random) {}
Random_generator_base() : _rnd( CGAL::get_default_random() ) {}
Random_generator_base( double range, Random& rnd)
: Generator_base<T>( range), _rnd( rnd) {}
Random_generator_base( const T& item, double range, Random& rnd)
@ -83,7 +83,7 @@ class Random_double_in_interval : public Random_generator_base<double> {
public:
typedef Random_double_in_interval This;
Random_double_in_interval(double a = 1, Random& rnd = default_random)
Random_double_in_interval(double a = 1, Random& rnd = CGAL::get_default_random())
// g is an input iterator creating points of type `P' uniformly
// distributed in the half-open square with side length a,
// centered around the origin, i.e. \forall p = `*g': -\frac{a}{2}

View File

@ -36,7 +36,7 @@ class Random_points_in_disc_2 : public Random_generator_base<P>{
void generate_point();
public:
typedef Random_points_in_disc_2<P,Creator> This;
Random_points_in_disc_2( double r = 1, Random& rnd = default_random)
Random_points_in_disc_2( double r = 1, Random& rnd = CGAL::get_default_random())
// g is an input iterator creating points of type `P' uniformly
// distributed in the open disc with radius r, i.e. |`*g'| < r .
// Two random numbers are needed from `rnd' for each point.
@ -71,7 +71,7 @@ class Random_points_on_circle_2 : public Random_generator_base<P> {
void generate_point();
public:
typedef Random_points_on_circle_2<P,Creator> This;
Random_points_on_circle_2( double r = 1, Random& rnd = default_random)
Random_points_on_circle_2( double r = 1, Random& rnd = CGAL::get_default_random())
// g is an input iterator creating points of type `P' uniformly
// distributed on the circle with radius r, i.e. |`*g'| == r . A
// single random number is needed from `rnd' for each point.
@ -105,7 +105,7 @@ class Random_points_in_square_2 : public Random_generator_base<P> {
void generate_point();
public:
typedef Random_points_in_square_2<P,Creator> This;
Random_points_in_square_2( double a = 1, Random& rnd = default_random)
Random_points_in_square_2( double a = 1, Random& rnd = CGAL::get_default_random())
// g is an input iterator creating points of type `P' uniformly
// distributed in the half-open square with side length a,
// centered around the origin, i.e. \forall p = `*g': -\frac{a}{2}
@ -141,7 +141,7 @@ class Random_points_on_square_2 : public Random_generator_base<P> {
void generate_point();
public:
typedef Random_points_on_square_2<P,Creator> This;
Random_points_on_square_2( double a = 1, Random& rnd = default_random)
Random_points_on_square_2( double a = 1, Random& rnd = CGAL::get_default_random())
// g is an input iterator creating points of type `P' uniformly
// distributed on the boundary of the square with side length a,
// centered around the origin, i.e. \forall p = `*g': one
@ -194,7 +194,7 @@ class Random_points_in_iso_rectangle_2 : public Random_generator_base<P> {
void generate_point();
public:
typedef Random_points_in_iso_rectangle_2<P,Creator> This;
Random_points_in_iso_rectangle_2( const P&p, const P& q, Random& rnd = default_random)
Random_points_in_iso_rectangle_2( const P&p, const P& q, Random& rnd = CGAL::get_default_random())
: Random_generator_base<P>( 1.0 , rnd)
{
left = (std::min)(to_double(p.x()), to_double(q.x()));
@ -238,7 +238,7 @@ public:
typedef Random_points_on_segment_2<P,Creator> This;
Random_points_on_segment_2( const P& p = P( -1, 0),
const P& q = P( 1, 0),
Random& rnd = default_random)
Random& rnd = CGAL::get_default_random())
// g is an input iterator creating points of type `P' uniformly
// distributed on the segment from p to q except q, i.e. `*g' ==
// \lambda p + (1-\lambda)\, q where 0 <= \lambda < 1 . A single
@ -423,7 +423,7 @@ void perturb_points_2( ForwardIterator first,
double xeps,
double yeps)
{
perturb_points_2( first, last, xeps, yeps, default_random);
perturb_points_2( first, last, xeps, yeps, CGAL::get_default_random());
}
template <class ForwardIterator>
@ -431,7 +431,7 @@ void perturb_points_2( ForwardIterator first,
ForwardIterator last,
double xeps)
{
perturb_points_2( first, last, xeps, xeps, default_random);
perturb_points_2( first, last, xeps, xeps, CGAL::get_default_random());
}
template <class RandomAccessIterator, class OutputIterator, class Creator>
OutputIterator random_collinear_points_2(
@ -489,7 +489,7 @@ OutputIterator random_collinear_points_2(
OutputIterator first2)
{
return random_collinear_points_2( first, last, n, first2,
default_random);
CGAL::get_default_random());
}

View File

@ -36,7 +36,7 @@ class Random_points_in_sphere_3 : public Random_generator_base<P> {
void generate_point();
public:
typedef Random_points_in_sphere_3<P,Creator> This;
Random_points_in_sphere_3( double r = 1, Random& rnd = default_random)
Random_points_in_sphere_3( double r = 1, Random& rnd = CGAL::get_default_random())
// g is an input iterator creating points of type `P' uniformly
// distributed in the open sphere with radius r, i.e. |`*g'| < r .
// Three random numbers are needed from `rnd' for each point
@ -75,7 +75,7 @@ class Random_points_on_sphere_3 : public Random_generator_base<P> {
void generate_point();
public:
typedef Random_points_on_sphere_3<P,Creator> This;
Random_points_on_sphere_3( double r = 1, Random& rnd = default_random)
Random_points_on_sphere_3( double r = 1, Random& rnd = CGAL::get_default_random())
// g is an input iterator creating points of type `P' uniformly
// distributed on the sphere with radius r, i.e. |`*g'| == r . A
// two random numbers are needed from `rnd' for each point.
@ -113,7 +113,7 @@ class Random_points_in_cube_3 : public Random_generator_base<P>{
void generate_point();
public:
typedef Random_points_in_cube_3<P,Creator> This;
Random_points_in_cube_3( double a = 1, Random& rnd = default_random)
Random_points_in_cube_3( double a = 1, Random& rnd = CGAL::get_default_random())
: Random_generator_base<P>( a, rnd) { generate_point(); }
This& operator++() {
generate_point();

View File

@ -35,7 +35,7 @@ class Random_points_in_ball_d : public Random_generator_base<P>{
public:
typedef Random_points_in_ball_d<P> This;
Random_points_in_ball_d( int dim, double a = 1,
Random& rnd = default_random)
Random& rnd = get_default_random())
// g is an input iterator creating points of type `P' uniformly
// distributed in the open sphere with radius r, i.e. |`*g'| < r .
: Random_generator_base<P>( a, rnd), dimension(dim) { generate_point(); }
@ -84,7 +84,7 @@ class Random_points_on_sphere_d : public Random_generator_base<P>{
public:
typedef Random_points_on_sphere_d<P> This;
Random_points_on_sphere_d( int dim, double a = 1,
Random& rnd = default_random)
Random& rnd = get_default_random())
// g is an input iterator creating points of type `P' uniformly
// distributed on the sphere with radius r, i.e. |`*g'| == r .
: Random_generator_base<P>( a, rnd), dimension(dim) { generate_point(); }
@ -129,7 +129,7 @@ class Random_points_in_cube_d : public Random_generator_base<P>{
public:
typedef Random_points_in_cube_d<P> This;
Random_points_in_cube_d( int dim, double a = 1,
Random& rnd = default_random)
Random& rnd = get_default_random())
: Random_generator_base<P>( a, rnd), dimension(dim) { generate_point(); }
This& operator++() {
generate_point();

View File

@ -57,7 +57,7 @@ OutputIterator random_selection( RandomAccessIterator first,
Size n,
OutputIterator result)
{
return random_selection( first, last, n, result, default_random);
return random_selection( first, last, n, result, get_default_random());
}
} //namespace CGAL

View File

@ -97,7 +97,7 @@ void test_point_generators_2() {
perturb_points_2( i1, i2, 10.0);
// Create a random permutation.
std::random_shuffle( points.begin(), points.end(), default_random);
std::random_shuffle( points.begin(), points.end(), get_default_random());
assert( points.size() == 1000);
for ( std::vector<Point_2>::iterator i = points.begin();

View File

@ -25,6 +25,8 @@
#ifndef CGAL_GEOMVIEW_STREAM_H
#define CGAL_GEOMVIEW_STREAM_H
#ifdef CGAL_USE_GEOMVIEW
#include <CGAL/basic.h>
#include <CGAL/Bbox_2.h>
#include <CGAL/Bbox_3.h>
@ -593,4 +595,10 @@ operator>>(Geomview_stream &gv, Point_3<R> &point)
} //namespace CGAL
#ifdef CGAL_HEADER_ONLY
#include <CGAL/IO/Geomview_stream_impl.h>
#endif // CGAL_HEADER_ONLY
#endif // CGAL_USE_GEOMVIEW
#endif // CGAL_GEOMVIEW_STREAM_H

View File

@ -0,0 +1,614 @@
// Copyright (c) 1999-2004
// Utrecht University (The Netherlands),
// ETH Zurich (Switzerland),
// INRIA Sophia-Antipolis (France),
// Max-Planck-Institute Saarbruecken (Germany),
// and Tel-Aviv University (Israel). All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
//
//
// Author(s) : Andreas Fabri, Herve Bronnimann, Sylvain Pion
#ifdef CGAL_USE_GEOMVIEW
#ifdef CGAL_HEADER_ONLY
#define CGAL_INLINE_FUNCTION inline
#else
#define CGAL_INLINE_FUNCTION
#endif
#include <CGAL/basic.h>
#include <sstream>
#include <csignal>
#include <cerrno>
#include <cstring>
#include <cstdlib>
#include <unistd.h>
#include <sys/types.h> // kill() on SunPro requires these 2 #includes.
#include <signal.h>
#include <CGAL/IO/binary_file_io.h>
namespace CGAL {
CGAL_INLINE_FUNCTION
Geomview_stream::Geomview_stream(const Bbox_3 &bbox,
const char *machine,
const char *login)
: bb(bbox), vertex_color(BLACK), edge_color(BLACK), face_color(BLACK),
wired_flag(false), echo_flag(true), raw_flag(false),
trace_flag(false), binary_flag(false),
line_width(1)
{
setup_geomview(machine, login);
frame(bbox);
pickplane(bbox);
set_vertex_radius((bbox.xmax() - bbox.xmin())/100.0);
}
CGAL_INLINE_FUNCTION
Geomview_stream::~Geomview_stream()
{
kill(pid, SIGKILL); // kills geomview
}
CGAL_INLINE_FUNCTION
void Geomview_stream::setup_geomview(const char *machine, const char *login)
{
int pipe_out[2], pipe_in[2];
// Communication between CGAL and geomview should be possible
// in two directions. To achieve this we open two pipes
std::cout << "Starting Geomview..." << std::flush;
if (pipe(pipe_out) < 0) {
CGAL_error_msg( "out pipe failed" );
}
if (pipe(pipe_in) < 0) {
CGAL_error_msg( "in pipe failed" );
}
switch (pid = fork()){
case -1:
CGAL_error_msg( "fork failed" );
case 0: // The child process
close(pipe_out[1]); // does not write to the out pipe,
close(pipe_in[0]); // does not read from the in pipe.
if (dup2(pipe_out[0], 0) != 0)
std::cerr << "Connect pipe to stdin failed." << std::endl;
if (dup2(pipe_in[1], 1) != 1)
std::cerr << "Connect pipe to stdout failed." << std::endl;
if (machine && (std::strlen(machine)>0)) {
std::string s (" rgeomview ");
s += machine;
s += ":0.0";
execlp("rsh", "rsh", machine, "-l", login, s.data(),
static_cast<void *>(NULL)); // cast to stop gcc warning
} else {
execlp("geomview", "geomview", "-c", "-",
static_cast<void *>(NULL)); // cast to stop gcc warning
}
// if we get to this point something went wrong.
std::cerr << "execl geomview failed" << std::endl;
switch(errno) {
case EACCES:
std::cerr << "please check your environment variable PATH"
<< std::endl;
std::cerr << "make sure the file `geomview' is contained in it"
<< std::endl;
std::cerr << "and is executable" << std::endl;
break;
case ELOOP:
std::cerr << "too many links for filename `geomview'" << std::endl;
break;
default:
std::cerr << "error number " << errno << " (check `man execlp')"
<< std::endl;
};
CGAL_error();
default: // The parent process
close(pipe_out[0]); // does not read from the out pipe,
close(pipe_in[1]); // does not write to the in pipe.
in = pipe_in[0];
out = pipe_out[1];
// Necessary to wait a little bit for Geomview,
// otherwise you won't be able to ask for points...
sleep(1);
#if 1
// We want to get rid of the requirement in the CGAL doc about
// (echo "started"). But we want to be backward compatible, that is,
// people who have this echo in their .geomview must still have CGAL
// working, at least for a few public releases.
// So the plan is to send, from CGAL, the command : (echo "CGAL-3D")
// It's the same length as "started", 7.
// Then we read 7 chars from Geomview, and test which string it is.
// If it's "CGAL-3D", then fine, the user doesn't have .geomview with
// the back-compatible echo command.
// In the very long run, we'll be able to get rid of all this code as
// well.
// Maybe we should simply read the pipe, till we find "CGAL-3D" ?
*this << "(echo \"CGAL-3D\")";
char inbuf[10];
std::size_t retread=::read(in, inbuf, 7);
(void)retread;
if (std::strncmp(inbuf, "started", 7) == 0)
{
// std::cerr << "You still have a .geomview file with the\n"
// << "(echo \"started\") command. Note that this is not\n"
// << "compulsory anymore, since CGAL 2.3" << std::endl;
// Then the next one is supposed to be CGAL-3D.
retread=::read(in, inbuf, 7);
(void)retread;
if (std::strncmp(inbuf, "CGAL-3D", 7) != 0)
std::cerr << "Unexpected string from Geomview !" << std::endl;
}
else if (std::strncmp(inbuf, "CGAL-3D", 7) == 0)
{
// std::cerr << "Good, you don't have a .geomview file with the\n"
// << "(echo \"started\") command" << std::endl;
}
else
{
std::cerr << "Unexcepted string from Geomview at initialization!\n"
<< "Going on nevertheless !" << std::endl;
}
#else
// Old original version
char inbuf[10];
// Waits for "started" from the .geomview file.
retread=::read(in, inbuf, 7);
(void)retread;
#endif
std::cout << "done." << std::endl;
(*this) << "(normalization g* none)(bbox-draw g* no)";
}
}
CGAL_INLINE_FUNCTION
void
Geomview_stream::pickplane(const Bbox_3 &bbox)
{
bool bin_bak = set_binary_mode();
(*this) << "(geometry pickplane {QUAD BINARY\n"
<< 1
// here are the four corners
<< bbox.xmin() << bbox.ymin() << bbox.zmin()
<< bbox.xmin() << bbox.ymax() << bbox.zmin()
<< bbox.xmax() << bbox.ymax() << bbox.zmin()
<< bbox.xmax() << bbox.ymin() << bbox.zmin()
// close the text bracket
<< "}) (pickable pickplane no)";
set_ascii_mode(bin_bak);
}
CGAL_INLINE_FUNCTION
void
Geomview_stream::clear()
{
(*this) << "(delete World)";
id.clear();
}
CGAL_INLINE_FUNCTION
void
Geomview_stream::look_recenter()
{
(*this) << "(look-recenter World)";
}
CGAL_INLINE_FUNCTION
Geomview_stream&
Geomview_stream::operator<<(const std::string & s)
{
if ((int)s.length() != ::write(out, s.data(), s.length())) {
CGAL_error_msg( "write problem in the pipe while sending data to geomview" );
}
trace(s);
return *this;
}
CGAL_INLINE_FUNCTION
Geomview_stream&
Geomview_stream::operator<<(int i)
{
// Depending on the mode chosen
if (get_binary_mode()) {
// we write raw binary data to the stream.
int num = i;
I_swap_to_big_endian(num);
std::size_t retwrite=::write(out, (char*)&num, sizeof(num));
(void)retwrite;
trace(i);
} else {
// transform the int in a character sequence and put whitespace around
std::ostringstream str;
str << i << ' ' << std::ends;
*this << str.str().c_str();
}
return *this;
}
CGAL_INLINE_FUNCTION
Geomview_stream&
Geomview_stream::operator<<(unsigned int i)
{
// Depending on the mode chosen
if (get_binary_mode()) {
// we write raw binary data to the stream.
unsigned int num = i;
I_swap_to_big_endian(num);
std::size_t retwrite=::write(out, (char*)&num, sizeof(num));
(void)retwrite;
trace(i);
} else {
// transform the int in a character sequence and put whitespace around
std::ostringstream str;
str << i << ' ' << std::ends;
*this << str.str().c_str();
}
return *this;
}
CGAL_INLINE_FUNCTION
Geomview_stream&
Geomview_stream::operator<<(long i)
{
return operator<<((int) i);
}
CGAL_INLINE_FUNCTION
Geomview_stream&
Geomview_stream::operator<<(unsigned long i)
{
return operator<<((unsigned int) i);
}
CGAL_INLINE_FUNCTION
Geomview_stream&
Geomview_stream::operator<<(double d)
{
float f = d;
if (get_binary_mode()) {
float num = d;
I_swap_to_big_endian(num);
std::size_t retwrite= ::write(out, (char*)&num, sizeof(num));
(void)retwrite;
trace(f);
} else {
// 'copy' the float in a string and append a blank
std::ostringstream str;
str << f << ' ' << std::ends;
*this << str.str().c_str();
}
return *this;
}
CGAL_INLINE_FUNCTION
Geomview_stream&
operator<<(Geomview_stream &gv, const Bbox_2 &bbox)
{
bool ascii_bak = gv.set_ascii_mode();
gv << "(geometry " << gv.get_new_id("Bbox")
<< " {VECT 1 5 0 5 0 ";
// here are the four corners
gv << bbox.xmin() << bbox.ymin() << 0.0
<< bbox.xmin() << bbox.ymax() << 0.0
<< bbox.xmax() << bbox.ymax() << 0.0
<< bbox.xmax() << bbox.ymin() << 0.0
<< bbox.xmin() << bbox.ymin() << 0.0;
// close the text bracket
gv << "})";
gv.set_ascii_mode(ascii_bak);
return gv;
}
CGAL_INLINE_FUNCTION
Geomview_stream&
operator<<(Geomview_stream &gv, const Bbox_3 &bbox)
{
bool ascii_bak = gv.set_ascii_mode();
gv << "(geometry " << gv.get_new_id("Bbox")
<< " {appearance {material {edgecolor "
<< gv.ecr() << gv.ecg() << gv.ecb() << "}}{SKEL 8 4 "
// here are the corners
<< bbox.xmin() << bbox.ymin() << bbox.zmin()
<< bbox.xmin() << bbox.ymax() << bbox.zmin()
<< bbox.xmax() << bbox.ymax() << bbox.zmin()
<< bbox.xmax() << bbox.ymin() << bbox.zmin()
<< bbox.xmax() << bbox.ymin() << bbox.zmax()
<< bbox.xmax() << bbox.ymax() << bbox.zmax()
<< bbox.xmin() << bbox.ymax() << bbox.zmax()
<< bbox.xmin() << bbox.ymin() << bbox.zmax()
<< "10 0 1 2 3 4 5 6 7 0 3\n"
<< "2 1 6\n"
<< "2 2 5\n"
<< "2 4 7\n"
// close the text bracket
<< "}})";
gv.set_ascii_mode(ascii_bak);
return gv;
}
CGAL_INLINE_FUNCTION
void
Geomview_stream::set_bg_color(const Color &c)
{
bool ascii_bak = set_ascii_mode();
*this << "(backcolor \"Camera\" "
<< double(c.r())/255.0
<< double(c.g())/255.0
<< double(c.b())/255.0
<< ")";
set_ascii_mode(ascii_bak);
}
CGAL_INLINE_FUNCTION
Geomview_stream&
Geomview_stream::operator<<(const Color &c)
{
vertex_color = edge_color = face_color = c;
return (*this);
}
CGAL_INLINE_FUNCTION
Color
Geomview_stream::get_vertex_color() const
{
return vertex_color;
}
CGAL_INLINE_FUNCTION
Color
Geomview_stream::get_edge_color() const
{
return edge_color;
}
CGAL_INLINE_FUNCTION
Color
Geomview_stream::get_face_color() const
{
return face_color;
}
CGAL_INLINE_FUNCTION
Color
Geomview_stream::set_vertex_color(const Color &c)
{
Color old = vertex_color;
vertex_color = c;
return old;
}
CGAL_INLINE_FUNCTION
Color
Geomview_stream::set_edge_color(const Color &c)
{
Color old = edge_color;
edge_color = c;
return old;
}
CGAL_INLINE_FUNCTION
Color
Geomview_stream::set_face_color(const Color &c)
{
Color old = face_color;
face_color = c;
return old;
}
CGAL_INLINE_FUNCTION
double
Geomview_stream::vcr() const
{
return double(vertex_color.r())/255.0;
}
CGAL_INLINE_FUNCTION
double
Geomview_stream::vcg() const
{
return double(vertex_color.g())/255.0;
}
CGAL_INLINE_FUNCTION
double
Geomview_stream::vcb() const
{
return double(vertex_color.b())/255.0;
}
CGAL_INLINE_FUNCTION
double
Geomview_stream::ecr() const
{
return double(edge_color.r())/255.0;
}
CGAL_INLINE_FUNCTION
double
Geomview_stream::ecg() const
{
return double(edge_color.g())/255.0;
}
CGAL_INLINE_FUNCTION
double
Geomview_stream::ecb() const
{
return double(edge_color.b())/255.0;
}
CGAL_INLINE_FUNCTION
double
Geomview_stream::fcr() const
{
return double(face_color.r())/255.0;
}
CGAL_INLINE_FUNCTION
double
Geomview_stream::fcg() const
{
return double(face_color.g())/255.0;
}
CGAL_INLINE_FUNCTION
double
Geomview_stream::fcb() const
{
return double(face_color.b())/255.0;
}
CGAL_INLINE_FUNCTION
void
Geomview_stream::frame(const Bbox_3 &bbox)
{
(*this) << bbox << "(look-recenter g0 c0)";
}
CGAL_INLINE_FUNCTION
Geomview_stream&
Geomview_stream::operator>>(char *expr)
{
// Skip whitespaces
do {
std::size_t retread=::read(in, expr, 1);
(void)retread;
} while (expr[0] != '(');
int pcount = 1;
int i = 1;
while (1) {
std::size_t retread=::read(in, &expr[i], 1);
(void)retread;
if (expr[i] == ')'){
pcount--;
} else if (expr[i] == '('){
pcount++;
}
if (pcount == 0){
expr[i+1]='\0';
break; // we encountered a balanced number of parantheses
}
i++;
}
return *this;
}
// Parse a Lisp expression, return a pointer to the beginning of the
// nth subexpression, and terminate it by '\0'.
// It's either a word terminated by ' ' or ')', or a well parenthesed
// expression, or a quoted "string".
CGAL_INLINE_FUNCTION
char*
Geomview_stream::nth(char* s, int count)
{
s++; // skip first character (always a parenthesis)
// Skip "count" words.
for(; count != 0; count--) {
while (*s == ' ') // skip whitespaces
s++;
s++;
while (*s != ' ') // skip a word
s++;
}
while (*s == ' ') // skip whitespaces
s++;
// Now we have the beginning of the searched sub-expression.
int j = 1;
if (*s == '(') // Case of a well-parenthesed expression.
for (int pcount = 1; pcount != 0;) {
if (s[j] == ')') pcount--;
if (s[j] == '(') pcount++;
j++;
}
else if (*s == '"') { // Case of a quoted "string".
while (s[j] != '"')
j++;
j++;
}
else // Case of a word terminated by ' ' or ')'.
while (s[j] != ' ' && s[j] != ')')
j++;
s[j] = '\0';
return s;
}
CGAL_INLINE_FUNCTION
void
Geomview_stream::parse_point(const char* pickpoint,
double &x, double &y, double &z, double &w)
{
std::stringstream ss;
ss << pickpoint << std::ends;
char parenthesis;
ss >> parenthesis >> x >> y >> z >> w;
}
CGAL_INLINE_FUNCTION
std::string
Geomview_stream::get_new_id(const std::string & s)
{
std::ostringstream str;
str << s << id[s]++ << std::ends;
return str.str();
}
} //namespace CGAL
#else
#ifndef CGAL_HEADER_ONLY
// Add a dummy symbol to prevent warnings of empty translation unit.
namespace CGAL {
namespace {
int dummy;
}
} //namespace CGAL
#endif
#endif // CGAL_USE_GEOMVIEW

View File

@ -22,550 +22,9 @@
//
// Author(s) : Andreas Fabri, Herve Bronnimann, Sylvain Pion
#include <CGAL/basic.h>
#ifdef CGAL_USE_GEOMVIEW
#include <sstream>
#include <csignal>
#include <cerrno>
#include <cstring>
#include <cstdlib>
#include <unistd.h>
#include <sys/types.h> // kill() on SunPro requires these 2 #includes.
#include <signal.h>
#ifndef CGAL_HEADER_ONLY
#include <CGAL/IO/Geomview_stream.h>
#include <CGAL/IO/binary_file_io.h>
#include <CGAL/IO/Geomview_stream_impl.h>
namespace CGAL {
Geomview_stream::Geomview_stream(const Bbox_3 &bbox,
const char *machine,
const char *login)
: bb(bbox), vertex_color(BLACK), edge_color(BLACK), face_color(BLACK),
wired_flag(false), echo_flag(true), raw_flag(false),
trace_flag(false), binary_flag(false),
line_width(1)
{
setup_geomview(machine, login);
frame(bbox);
pickplane(bbox);
set_vertex_radius((bbox.xmax() - bbox.xmin())/100.0);
}
Geomview_stream::~Geomview_stream()
{
kill(pid, SIGKILL); // kills geomview
}
void Geomview_stream::setup_geomview(const char *machine, const char *login)
{
int pipe_out[2], pipe_in[2];
// Communication between CGAL and geomview should be possible
// in two directions. To achieve this we open two pipes
std::cout << "Starting Geomview..." << std::flush;
if (pipe(pipe_out) < 0) {
CGAL_error_msg( "out pipe failed" );
}
if (pipe(pipe_in) < 0) {
CGAL_error_msg( "in pipe failed" );
}
switch (pid = fork()){
case -1:
CGAL_error_msg( "fork failed" );
case 0: // The child process
close(pipe_out[1]); // does not write to the out pipe,
close(pipe_in[0]); // does not read from the in pipe.
if (dup2(pipe_out[0], 0) != 0)
std::cerr << "Connect pipe to stdin failed." << std::endl;
if (dup2(pipe_in[1], 1) != 1)
std::cerr << "Connect pipe to stdout failed." << std::endl;
if (machine && (std::strlen(machine)>0)) {
std::string s (" rgeomview ");
s += machine;
s += ":0.0";
execlp("rsh", "rsh", machine, "-l", login, s.data(),
static_cast<void *>(NULL)); // cast to stop gcc warning
} else {
execlp("geomview", "geomview", "-c", "-",
static_cast<void *>(NULL)); // cast to stop gcc warning
}
// if we get to this point something went wrong.
std::cerr << "execl geomview failed" << std::endl;
switch(errno) {
case EACCES:
std::cerr << "please check your environment variable PATH"
<< std::endl;
std::cerr << "make sure the file `geomview' is contained in it"
<< std::endl;
std::cerr << "and is executable" << std::endl;
break;
case ELOOP:
std::cerr << "too many links for filename `geomview'" << std::endl;
break;
default:
std::cerr << "error number " << errno << " (check `man execlp')"
<< std::endl;
};
CGAL_error();
default: // The parent process
close(pipe_out[0]); // does not read from the out pipe,
close(pipe_in[1]); // does not write to the in pipe.
in = pipe_in[0];
out = pipe_out[1];
// Necessary to wait a little bit for Geomview,
// otherwise you won't be able to ask for points...
sleep(1);
#if 1
// We want to get rid of the requirement in the CGAL doc about
// (echo "started"). But we want to be backward compatible, that is,
// people who have this echo in their .geomview must still have CGAL
// working, at least for a few public releases.
// So the plan is to send, from CGAL, the command : (echo "CGAL-3D")
// It's the same length as "started", 7.
// Then we read 7 chars from Geomview, and test which string it is.
// If it's "CGAL-3D", then fine, the user doesn't have .geomview with
// the back-compatible echo command.
// In the very long run, we'll be able to get rid of all this code as
// well.
// Maybe we should simply read the pipe, till we find "CGAL-3D" ?
*this << "(echo \"CGAL-3D\")";
char inbuf[10];
std::size_t retread=::read(in, inbuf, 7);
(void)retread;
if (std::strncmp(inbuf, "started", 7) == 0)
{
// std::cerr << "You still have a .geomview file with the\n"
// << "(echo \"started\") command. Note that this is not\n"
// << "compulsory anymore, since CGAL 2.3" << std::endl;
// Then the next one is supposed to be CGAL-3D.
retread=::read(in, inbuf, 7);
(void)retread;
if (std::strncmp(inbuf, "CGAL-3D", 7) != 0)
std::cerr << "Unexpected string from Geomview !" << std::endl;
}
else if (std::strncmp(inbuf, "CGAL-3D", 7) == 0)
{
// std::cerr << "Good, you don't have a .geomview file with the\n"
// << "(echo \"started\") command" << std::endl;
}
else
{
std::cerr << "Unexcepted string from Geomview at initialization!\n"
<< "Going on nevertheless !" << std::endl;
}
#else
// Old original version
char inbuf[10];
// Waits for "started" from the .geomview file.
retread=::read(in, inbuf, 7);
(void)retread;
#endif
std::cout << "done." << std::endl;
(*this) << "(normalization g* none)(bbox-draw g* no)";
}
}
void
Geomview_stream::pickplane(const Bbox_3 &bbox)
{
bool bin_bak = set_binary_mode();
(*this) << "(geometry pickplane {QUAD BINARY\n"
<< 1
// here are the four corners
<< bbox.xmin() << bbox.ymin() << bbox.zmin()
<< bbox.xmin() << bbox.ymax() << bbox.zmin()
<< bbox.xmax() << bbox.ymax() << bbox.zmin()
<< bbox.xmax() << bbox.ymin() << bbox.zmin()
// close the text bracket
<< "}) (pickable pickplane no)";
set_ascii_mode(bin_bak);
}
void
Geomview_stream::clear()
{
(*this) << "(delete World)";
id.clear();
}
void
Geomview_stream::look_recenter()
{
(*this) << "(look-recenter World)";
}
Geomview_stream&
Geomview_stream::operator<<(const std::string & s)
{
if ((int)s.length() != ::write(out, s.data(), s.length())) {
CGAL_error_msg( "write problem in the pipe while sending data to geomview" );
}
trace(s);
return *this;
}
Geomview_stream&
Geomview_stream::operator<<(int i)
{
// Depending on the mode chosen
if (get_binary_mode()) {
// we write raw binary data to the stream.
int num = i;
I_swap_to_big_endian(num);
std::size_t retwrite=::write(out, (char*)&num, sizeof(num));
(void)retwrite;
trace(i);
} else {
// transform the int in a character sequence and put whitespace around
std::ostringstream str;
str << i << ' ' << std::ends;
*this << str.str().c_str();
}
return *this;
}
Geomview_stream&
Geomview_stream::operator<<(unsigned int i)
{
// Depending on the mode chosen
if (get_binary_mode()) {
// we write raw binary data to the stream.
unsigned int num = i;
I_swap_to_big_endian(num);
std::size_t retwrite=::write(out, (char*)&num, sizeof(num));
(void)retwrite;
trace(i);
} else {
// transform the int in a character sequence and put whitespace around
std::ostringstream str;
str << i << ' ' << std::ends;
*this << str.str().c_str();
}
return *this;
}
Geomview_stream&
Geomview_stream::operator<<(long i)
{
return operator<<((int) i);
}
Geomview_stream&
Geomview_stream::operator<<(unsigned long i)
{
return operator<<((unsigned int) i);
}
Geomview_stream&
Geomview_stream::operator<<(double d)
{
float f = d;
if (get_binary_mode()) {
float num = d;
I_swap_to_big_endian(num);
std::size_t retwrite= ::write(out, (char*)&num, sizeof(num));
(void)retwrite;
trace(f);
} else {
// 'copy' the float in a string and append a blank
std::ostringstream str;
str << f << ' ' << std::ends;
*this << str.str().c_str();
}
return *this;
}
Geomview_stream&
operator<<(Geomview_stream &gv, const Bbox_2 &bbox)
{
bool ascii_bak = gv.set_ascii_mode();
gv << "(geometry " << gv.get_new_id("Bbox")
<< " {VECT 1 5 0 5 0 ";
// here are the four corners
gv << bbox.xmin() << bbox.ymin() << 0.0
<< bbox.xmin() << bbox.ymax() << 0.0
<< bbox.xmax() << bbox.ymax() << 0.0
<< bbox.xmax() << bbox.ymin() << 0.0
<< bbox.xmin() << bbox.ymin() << 0.0;
// close the text bracket
gv << "})";
gv.set_ascii_mode(ascii_bak);
return gv;
}
Geomview_stream&
operator<<(Geomview_stream &gv, const Bbox_3 &bbox)
{
bool ascii_bak = gv.set_ascii_mode();
gv << "(geometry " << gv.get_new_id("Bbox")
<< " {appearance {material {edgecolor "
<< gv.ecr() << gv.ecg() << gv.ecb() << "}}{SKEL 8 4 "
// here are the corners
<< bbox.xmin() << bbox.ymin() << bbox.zmin()
<< bbox.xmin() << bbox.ymax() << bbox.zmin()
<< bbox.xmax() << bbox.ymax() << bbox.zmin()
<< bbox.xmax() << bbox.ymin() << bbox.zmin()
<< bbox.xmax() << bbox.ymin() << bbox.zmax()
<< bbox.xmax() << bbox.ymax() << bbox.zmax()
<< bbox.xmin() << bbox.ymax() << bbox.zmax()
<< bbox.xmin() << bbox.ymin() << bbox.zmax()
<< "10 0 1 2 3 4 5 6 7 0 3\n"
<< "2 1 6\n"
<< "2 2 5\n"
<< "2 4 7\n"
// close the text bracket
<< "}})";
gv.set_ascii_mode(ascii_bak);
return gv;
}
void
Geomview_stream::set_bg_color(const Color &c)
{
bool ascii_bak = set_ascii_mode();
*this << "(backcolor \"Camera\" "
<< double(c.r())/255.0
<< double(c.g())/255.0
<< double(c.b())/255.0
<< ")";
set_ascii_mode(ascii_bak);
}
Geomview_stream&
Geomview_stream::operator<<(const Color &c)
{
vertex_color = edge_color = face_color = c;
return (*this);
}
Color
Geomview_stream::get_vertex_color() const
{
return vertex_color;
}
Color
Geomview_stream::get_edge_color() const
{
return edge_color;
}
Color
Geomview_stream::get_face_color() const
{
return face_color;
}
Color
Geomview_stream::set_vertex_color(const Color &c)
{
Color old = vertex_color;
vertex_color = c;
return old;
}
Color
Geomview_stream::set_edge_color(const Color &c)
{
Color old = edge_color;
edge_color = c;
return old;
}
Color
Geomview_stream::set_face_color(const Color &c)
{
Color old = face_color;
face_color = c;
return old;
}
double
Geomview_stream::vcr() const
{
return double(vertex_color.r())/255.0;
}
double
Geomview_stream::vcg() const
{
return double(vertex_color.g())/255.0;
}
double
Geomview_stream::vcb() const
{
return double(vertex_color.b())/255.0;
}
double
Geomview_stream::ecr() const
{
return double(edge_color.r())/255.0;
}
double
Geomview_stream::ecg() const
{
return double(edge_color.g())/255.0;
}
double
Geomview_stream::ecb() const
{
return double(edge_color.b())/255.0;
}
double
Geomview_stream::fcr() const
{
return double(face_color.r())/255.0;
}
double
Geomview_stream::fcg() const
{
return double(face_color.g())/255.0;
}
double
Geomview_stream::fcb() const
{
return double(face_color.b())/255.0;
}
void
Geomview_stream::frame(const Bbox_3 &bbox)
{
(*this) << bbox << "(look-recenter g0 c0)";
}
Geomview_stream&
Geomview_stream::operator>>(char *expr)
{
// Skip whitespaces
do {
std::size_t retread=::read(in, expr, 1);
(void)retread;
} while (expr[0] != '(');
int pcount = 1;
int i = 1;
while (1) {
std::size_t retread=::read(in, &expr[i], 1);
(void)retread;
if (expr[i] == ')'){
pcount--;
} else if (expr[i] == '('){
pcount++;
}
if (pcount == 0){
expr[i+1]='\0';
break; // we encountered a balanced number of parantheses
}
i++;
}
return *this;
}
// Parse a Lisp expression, return a pointer to the beginning of the
// nth subexpression, and terminate it by '\0'.
// It's either a word terminated by ' ' or ')', or a well parenthesed
// expression, or a quoted "string".
char*
Geomview_stream::nth(char* s, int count)
{
s++; // skip first character (always a parenthesis)
// Skip "count" words.
for(; count != 0; count--) {
while (*s == ' ') // skip whitespaces
s++;
s++;
while (*s != ' ') // skip a word
s++;
}
while (*s == ' ') // skip whitespaces
s++;
// Now we have the beginning of the searched sub-expression.
int j = 1;
if (*s == '(') // Case of a well-parenthesed expression.
for (int pcount = 1; pcount != 0;) {
if (s[j] == ')') pcount--;
if (s[j] == '(') pcount++;
j++;
}
else if (*s == '"') { // Case of a quoted "string".
while (s[j] != '"')
j++;
j++;
}
else // Case of a word terminated by ' ' or ')'.
while (s[j] != ' ' && s[j] != ')')
j++;
s[j] = '\0';
return s;
}
void
Geomview_stream::parse_point(const char* pickpoint,
double &x, double &y, double &z, double &w)
{
std::stringstream ss;
ss << pickpoint << std::ends;
char parenthesis;
ss >> parenthesis >> x >> y >> z >> w;
}
std::string
Geomview_stream::get_new_id(const std::string & s)
{
std::ostringstream str;
str << s << id[s]++ << std::ends;
return str.str();
}
} //namespace CGAL
#else
// Add a dummy symbol to prevent warnings of empty translation unit.
namespace CGAL {
namespace {
int dummy;
}
} //namespace CGAL
#endif // CGAL_USE_GEOMVIEW

View File

@ -125,4 +125,8 @@ protected:
Q_DECLARE_OPERATORS_FOR_FLAGS(CGAL::Qt::DemosMainWindow::Options)
#ifdef CGAL_HEADER_ONLY
#include <CGAL/Qt/DemosMainWindow_impl.h>
#endif // CGAL_HEADER_ONLY
#endif // CGAL_QT_DEMOS_MAIN_WINDOW_H

View File

@ -0,0 +1,436 @@
// Copyright (c) 2008 GeometryFactory Sarl (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
//
//
// Author(s) : Andreas Fabri <Andreas.Fabri@geometryfactory.com>
// Laurent Rineau <Laurent.Rineau@geometryfactory.com>
#ifdef CGAL_HEADER_ONLY
#define CGAL_INLINE_FUNCTION inline
#else
#define CGAL_INLINE_FUNCTION
#endif
#include <CGAL/Qt/GraphicsViewNavigation.h>
#include <QApplication>
#include <QLabel>
#include <QFile>
#include <QFileInfo>
#include <QMenu>
#include <QMenuBar>
#include <QAction>
#include <QMessageBox>
#include <QStatusBar>
#include <QGraphicsView>
#include <QGLWidget>
#include <QTextStream>
#include <QSettings>
#include <QUrl>
#include <QDesktopWidget>
#include <QRegExp>
#include <CGAL/config.h> // needed to get CGAL_VERSION_STR
#include <CGAL/Qt/DemosMainWindow.h>
#include <iostream>
namespace CGAL {
namespace Qt {
CGAL_INLINE_FUNCTION
DemosMainWindow::DemosMainWindow(QWidget * parent, ::Qt::WindowFlags flags)
: QMainWindow(parent, flags),
maxNumRecentFiles(10),
recentFileActs(maxNumRecentFiles)
{
// prepare the QLabel xycoord for inclusion in the statusBar()
xycoord = new QLabel(" -0.00000 , -0.00000 ", this);
xycoord->setAlignment(::Qt::AlignHCenter);
xycoord->setMinimumSize(xycoord->sizeHint());
xycoord->clear();
actionUse_OpenGL = new QAction(this);
actionUse_OpenGL->setObjectName("actionUse_OpenGL");
actionUse_OpenGL->setCheckable(true);
actionUse_OpenGL->setText(tr("Use &OpenGL"));
actionUse_OpenGL->setStatusTip(tr("Make Qt use OpenGL to display the graphical items, instead of its native painting system."));
actionUse_OpenGL->setShortcut(tr("Ctrl+G"));
actionUse_Antialiasing = new QAction(this);
actionUse_Antialiasing->setObjectName("actionUse_Antialiasing");
actionUse_Antialiasing->setCheckable(true);
actionUse_Antialiasing->setText(tr("Use &anti-aliasing"));
actionUse_Antialiasing->setStatusTip(tr("Make Qt use anti-aliasing when displaying the graphical items."));
actionUse_Antialiasing->setShortcut(tr("Ctrl+A"));
actionAboutCGAL = new QAction(this);
actionAboutCGAL->setObjectName("actionAboutCGAL");
actionAboutCGAL->setText(tr("About &CGAL..."));
actionAbout = new QAction(this);
actionAbout->setObjectName("actionAbout");
actionAbout->setText(tr("&About..."));
setAcceptDrops(true);
}
CGAL_INLINE_FUNCTION
void
DemosMainWindow::dragEnterEvent(QDragEnterEvent *event)
{
if (event->mimeData()->hasFormat("text/uri-list"))
event->acceptProposedAction();
}
CGAL_INLINE_FUNCTION
void
DemosMainWindow::dropEvent(QDropEvent *event)
{
Q_FOREACH(QUrl url, event->mimeData()->urls()) {
QString filename = url.toLocalFile();
this->open(filename);
}
event->acceptProposedAction();
}
CGAL_INLINE_FUNCTION
void
DemosMainWindow::addNavigation(QGraphicsView* graphicsView)
{
navigation = new CGAL::Qt::GraphicsViewNavigation();
graphicsView->viewport()->installEventFilter(navigation);
graphicsView->installEventFilter(navigation);
QObject::connect(navigation, SIGNAL(mouseCoordinates(QString)),
xycoord, SLOT(setText(QString)));
view = graphicsView;
}
CGAL_INLINE_FUNCTION
void
DemosMainWindow::setupStatusBar()
{
this->statusBar()->addWidget(new QLabel(this), 1);
this->statusBar()->addWidget(xycoord, 0);
}
CGAL_INLINE_FUNCTION
void
DemosMainWindow::setupOptionsMenu(QMenu* menuOptions)
{
// search for the Options menu
if(!menuOptions) {
menuOptions = getMenu("menuOptions", tr("&Options"));
}
// if not found, then create it
if(!menuOptions) {
menuOptions = new QMenu(this->menuBar());
menuOptions->setTitle(tr("&Options"));
this->menuBar()->addAction(menuOptions->menuAction());
menuOptions->setObjectName("menuOptions");
}
if(!menuOptions->isEmpty()) {
menuOptions->addSeparator();
}
menuOptions->addAction(actionUse_OpenGL);
menuOptions->addAction(actionUse_Antialiasing);
connect(actionUse_Antialiasing, SIGNAL(toggled(bool)),
this, SLOT(setUseAntialiasing(bool)));
connect(actionUse_OpenGL, SIGNAL(toggled(bool)),
this, SLOT(setUseOpenGL(bool)));
actionUse_Antialiasing->setChecked(true);
}
CGAL_INLINE_FUNCTION
void
DemosMainWindow::setUseAntialiasing(bool checked)
{
view->setRenderHint(QPainter::Antialiasing, checked);
#if QT_VERSION >= 0x040300
view->setRenderHint(QPainter::HighQualityAntialiasing, checked);
#endif
statusBar()->showMessage(tr("Antialiasing %1activated").arg(checked?"":"de-"),
1000);
}
CGAL_INLINE_FUNCTION
void
DemosMainWindow::setUseOpenGL(bool checked)
{
if(checked) {
QGLWidget* new_viewport = new QGLWidget;
// Setup the format to allow antialiasing with OpenGL:
// one need to activate the SampleBuffers, if the graphic driver allows
// this.
QGLFormat glformat = new_viewport->format();
glformat.setOption(QGL::SampleBuffers);
new_viewport->setFormat(glformat);
view->setViewport(new_viewport);
}
else {
view->setViewport(new QWidget);
}
statusBar()->showMessage(tr("OpenGL %1activated").arg(checked?"":"de-"),
1000);
view->viewport()->installEventFilter(navigation);
view->setFocus();
}
CGAL_INLINE_FUNCTION
QMenu*
DemosMainWindow::getMenu(QString objectName, QString title)
{
QMenu* menu = NULL;
QString title2 = title;
title2.remove('&');
// search if a menu has objectName()==objectName
menu = this->findChild<QMenu*>(objectName);
// then search if a menu has title()==title
if(menu) {
return menu;
} else {
Q_FOREACH(menu, this->findChildren<QMenu*>()) {
if(menu->title() == title ||
menu->title() == title2) {
return menu;
}
}
}
return NULL;
}
CGAL_INLINE_FUNCTION
void
DemosMainWindow::popupAboutBox(QString title, QString html_resource_name)
{
QFile about_CGAL(html_resource_name);
about_CGAL.open(QIODevice::ReadOnly);
QString about_CGAL_txt = QTextStream(&about_CGAL).readAll();
#ifdef CGAL_VERSION_STR
QString cgal_version(CGAL_VERSION_STR);
# ifdef CGAL_FAKE_PUBLIC_RELEASE
cgal_version.replace(QRegExp("-Ic?.*"), "");
# endif
about_CGAL_txt.replace("<!--CGAL_VERSION-->",
QString(" (version %1)")
.arg(cgal_version));
#endif
QMessageBox mb(QMessageBox::NoIcon,
title,
about_CGAL_txt,
QMessageBox::Ok,
this);
QLabel* mb_label = mb.findChild<QLabel*>("qt_msgbox_label");
if(mb_label) {
mb_label->setTextInteractionFlags(mb_label->textInteractionFlags() |
::Qt::LinksAccessibleByMouse |
::Qt::LinksAccessibleByKeyboard);
}
else {
std::cerr << "Cannot find child \"qt_msgbox_label\" in QMessageBox\n"
<< " with Qt version " << QT_VERSION_STR << "!\n";
}
mb.exec();
}
CGAL_INLINE_FUNCTION
QMenu* DemosMainWindow::getHelpMenu()
{
QMenu* menuHelp = getMenu("menuHelp", tr("&Help"));
if(!menuHelp) {
menuHelp = new QMenu(this->menuBar());
menuHelp->setTitle(tr("&Help"));
this->menuBar()->addAction(menuHelp->menuAction());
menuHelp->setObjectName("menuHelp");
}
return menuHelp;
}
CGAL_INLINE_FUNCTION
void
DemosMainWindow::addAboutCGAL(QMenu* menuHelp)
{
if(!menuHelp) {
menuHelp = getHelpMenu();
}
menuHelp->addAction(actionAboutCGAL);
connect(actionAboutCGAL, SIGNAL(triggered()),
this, SLOT(popupAboutCGAL()));
}
CGAL_INLINE_FUNCTION
void
DemosMainWindow::addAboutDemo(QString htmlResourceName, QMenu* menuHelp)
{
if(!menuHelp) {
menuHelp = getHelpMenu();
}
menuHelp->addAction(actionAbout);
aboutHtmlResource = htmlResourceName;
connect(actionAbout, SIGNAL(triggered()),
this, SLOT(popupAboutDemo()));
}
CGAL_INLINE_FUNCTION
void
DemosMainWindow::popupAboutCGAL()
{
popupAboutBox(tr("About CGAL..."),
":/cgal/help/about_CGAL.html");
}
CGAL_INLINE_FUNCTION
void
DemosMainWindow::popupAboutDemo()
{
popupAboutBox(tr("About the demo..."),
aboutHtmlResource);
}
CGAL_INLINE_FUNCTION
void
DemosMainWindow::setMaxNumberOfRecentFiles(const unsigned int i)
{
maxNumRecentFiles = i;
recentFileActs.resize(maxNumRecentFiles);
}
CGAL_INLINE_FUNCTION
unsigned int
DemosMainWindow::maxNumberOfRecentFiles() const
{
return maxNumRecentFiles;
}
CGAL_INLINE_FUNCTION
void
DemosMainWindow::openRecentFile_aux()
{
QAction *action = qobject_cast<QAction *>(sender());
if (action)
emit openRecentFile(action->data().toString());
}
CGAL_INLINE_FUNCTION
void
DemosMainWindow::addToRecentFiles(QString fileName)
{
QSettings settings;
QStringList files = settings.value("recentFileList").toStringList();
files.removeAll(fileName);
files.prepend(fileName);
while (files.size() > (int)maxNumberOfRecentFiles())
files.removeLast();
settings.setValue("recentFileList", files);
updateRecentFileActions();
}
CGAL_INLINE_FUNCTION
void
DemosMainWindow::addRecentFiles(QMenu* menu, QAction* insertBeforeAction)
{
if(!insertBeforeAction) {
recentFilesSeparator = menu->addSeparator();
}
for (unsigned int i = 0; i < maxNumberOfRecentFiles(); ++i) {
recentFileActs[i] = new QAction(this);
recentFileActs[i]->setVisible(false);
connect(recentFileActs[i], SIGNAL(triggered()),
this, SLOT(openRecentFile_aux()));
if(insertBeforeAction)
menu->insertAction(insertBeforeAction, recentFileActs[i]);
else
menu->addAction(recentFileActs[i]);
}
if(insertBeforeAction) {
recentFilesSeparator = menu->insertSeparator(insertBeforeAction);
}
recentFilesSeparator->setVisible(false);
updateRecentFileActions();
}
CGAL_INLINE_FUNCTION
void
DemosMainWindow::updateRecentFileActions()
{
QSettings settings;
QStringList files = settings.value("recentFileList").toStringList();
int numRecentFiles = qMin(files.size(), (int)this->maxNumberOfRecentFiles());
for (int i = 0; i < numRecentFiles; ++i) {
QString strippedName = QFileInfo(files[i]).fileName();
QString text = tr("&%1 %2").arg(i).arg(strippedName);
recentFileActs[i]->setText(text);
recentFileActs[i]->setData(files[i]);
recentFileActs[i]->setVisible(true);
}
for (unsigned int j = numRecentFiles; j < maxNumberOfRecentFiles(); ++j)
recentFileActs[j]->setVisible(false);
recentFilesSeparator->setVisible(numRecentFiles > 0);
}
CGAL_INLINE_FUNCTION
void DemosMainWindow::writeState(QString groupname)
{
QSettings settings;
settings.beginGroup(groupname);
settings.setValue("size", size());
settings.setValue("pos", pos());
settings.setValue("state", saveState());
settings.endGroup();
}
CGAL_INLINE_FUNCTION
void DemosMainWindow::readState(QString groupname, Options /*what_to_save*/)
{
QSettings settings;
settings.beginGroup(groupname);
resize(settings.value("size", this->size()).toSize());
QDesktopWidget* desktop = qApp->desktop();
QPoint pos = settings.value("pos", this->pos()).toPoint();
if(desktop->availableGeometry(pos).contains(pos)) {
move(pos);
}
QByteArray mainWindowState = settings.value("state").toByteArray();
if(!mainWindowState.isNull()) {
this->restoreState(mainWindowState);
}
settings.endGroup();
}
} // namespace Qt
} // namespace CGAL

View File

@ -69,4 +69,8 @@ private:
} // namespace Qt
} // namespace CGAL
#ifdef CGAL_HEADER_ONLY
#include <CGAL/Qt/GraphicsViewNavigation_impl.h>
#endif // CGAL_HEADER_ONLY
#endif // CGAL_QT_GRAPHICS_VIEW_NAVIGATION_H

View File

@ -0,0 +1,351 @@
// Copyright (c) 2008 GeometryFactory Sarl (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
//
//
// Author(s) : Andreas Fabri <Andreas.Fabri@geometryfactory.com>
// Laurent Rineau <Laurent.Rineau@geometryfactory.com>
#ifdef CGAL_HEADER_ONLY
#define CGAL_INLINE_FUNCTION inline
#else
#define CGAL_INLINE_FUNCTION
#endif
#include <CGAL/Qt/GraphicsViewNavigation.h>
#include <CGAL/Qt/utility.h> // for mapToScene(QGraphicsView*, QRect)
#include <cmath>
#include <iostream>
#include <boost/format.hpp>
#include <QEvent>
#include <QMouseEvent>
#include <QWheelEvent>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsRectItem>
#include <QFlags>
#include <QScrollBar>
namespace CGAL {
namespace Qt {
CGAL_INLINE_FUNCTION
GraphicsViewNavigation::GraphicsViewNavigation()
: rectItem(new QGraphicsRectItem),
dragging(false)
{
QColor rect_color(250, 221, 0);
rect_color.setAlpha(50);
rectItem->setBrush(rect_color);
rect_color.setAlpha(255);
rectItem->setPen(QPen(rect_color, 0, ::Qt::DashLine));
rectItem->hide();
rectItem->setZValue(10000);
}
CGAL_INLINE_FUNCTION
GraphicsViewNavigation::~GraphicsViewNavigation()
{
delete rectItem;
}
CGAL_INLINE_FUNCTION
bool
GraphicsViewNavigation::eventFilter(QObject *obj, QEvent *event)
{
QGraphicsView* v = qobject_cast<QGraphicsView*>(obj);
if(v == NULL) {
QWidget* viewport = qobject_cast<QWidget*>(obj);
if(viewport == NULL) {
return false;
}
v = qobject_cast<QGraphicsView*>(viewport->parent());
if(v == NULL) {
return false;
}
}
switch(event->type())
{
case QEvent::KeyPress: {
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
int offset = 10;
if( (keyEvent->modifiers() & ::Qt::ShiftModifier)
|| (keyEvent->modifiers() & ::Qt::ControlModifier) ) {
offset = 20;
}
switch (keyEvent->key()) {
case ::Qt::Key_Up:
translateView(v, 0, -offset);
break;
case ::Qt::Key_Down:
translateView(v, 0, offset);
break;
case ::Qt::Key_Left:
translateView(v, -offset, 0);
break;
case ::Qt::Key_Right:
translateView(v, offset, 0);
break;
case ::Qt::Key_PageUp:
v->rotate(-6);
break;
case ::Qt::Key_PageDown:
v->rotate(6);
break;
case ::Qt::Key_Plus:
scaleView(v, 1.2);
break;
case ::Qt::Key_Minus:
scaleView(v, 1 / 1.2);
break;
case ::Qt::Key_Control:
cursor_backup = v->cursor();
v->setCursor(::Qt::CrossCursor);
default:
return false;
}
// display_parameters();
return true;
break;
} // end case KeyPress
case QEvent::KeyRelease: {
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
if(keyEvent->key() == ::Qt::Key_Control) {
if(rectItem->isVisible() ) {
dragging = false;
v->scene()->removeItem(rectItem);
rectItem->hide();
}
v->setCursor(cursor_backup);
return true;
}
return false;
break;
} // end case KeyRelease
case QEvent::Wheel: {
QWheelEvent *wheelEvent = static_cast<QWheelEvent*>(event);
if(wheelEvent->orientation() != ::Qt::Vertical) {
return false;
}
double zoom_ratio = 240.0;
if( (wheelEvent->modifiers() & ::Qt::ShiftModifier)
|| (wheelEvent->modifiers() & ::Qt::ControlModifier) ) {
zoom_ratio = 120.0;
}
scaleView(v, pow((double)2, -wheelEvent->delta() / zoom_ratio));
// display_parameters();
return true;
break;
} // end case Wheel
case QEvent::MouseButtonPress: {
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
if( (mouseEvent->modifiers() == (::Qt::ControlModifier | ::Qt::ShiftModifier))
&& mouseEvent->button() == ::Qt::RightButton )
{
QPoint offset = mouseEvent->pos() - v->viewport()->rect().center();
translateView(v, offset.x(), offset.y());
return true;
}
else if( mouseEvent->modifiers() == ::Qt::ControlModifier ) {
if(mouseEvent->button() == ::Qt::LeftButton) {
rect_first_point = v->mapToScene(mouseEvent->pos());
rectItem->setRect(QRectF(rect_first_point, QSizeF(0.,0.)));
rectItem->show();
v->scene()->addItem(rectItem);
return true;
}
else if( mouseEvent->button() == ::Qt::RightButton) {
dragging = true;
dragging_start = v->mapToScene(mouseEvent->pos());
v->setCursor(::Qt::ClosedHandCursor);
return true;
}
}
return false;
break;
} // end case MouseRelease
case QEvent::MouseMove: {
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
QPointF pos = v->mapToScene(mouseEvent->pos());
QString xy = QString(" ") + QString::number(pos.x(),'g', 6) + " , " + QString::number(pos.y(),'g', 6) + " ";
emit mouseCoordinates(xy);
if(rectItem->isVisible()) {
QPointF size = v->mapToScene(mouseEvent->pos());
size = size - rect_first_point;
rectItem->setRect(rect_first_point.x(),
rect_first_point.y(),
size.x(),
size.y());
}
if( dragging )
{
// std::cerr << boost::format("mouseMove: globalpos=(%1%, %2%)\n"
// " pos=(%3%, %4%)\n"
// " sender=%5% (class %6%), parent class %7%\n")
// % mouseEvent->globalPos().x()
// % mouseEvent->globalPos().y()
// % mouseEvent->pos().x()
// % mouseEvent->pos().y()
// % (&*obj)
// % obj->metaObject()->className()
// % obj->parent()->metaObject()->className();
// drag_to(mouseEvent->pos());
}
break;
} // end MouseMove
case QEvent::MouseButtonRelease: {
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
if(rectItem->isVisible() && mouseEvent->button() == ::Qt::LeftButton){
v->setSceneRect(v->sceneRect() | rectItem->rect());
v->fitInView(rectItem->rect(), ::Qt::KeepAspectRatio);
v->scene()->removeItem(rectItem);
rectItem->hide();
return true;
}
else if( mouseEvent->button() == ::Qt::RightButton ) {
if(dragging) {
dragging = false;
drag_to(v, mouseEvent->pos());
v->setCursor(cursor_backup);
return true;
}
}
return false;
break;
} // end MouseRelease
default:
return false;
} // end switch
return false;
}
CGAL_INLINE_FUNCTION
void
GraphicsViewNavigation::scaleView(QGraphicsView* v, qreal scaleFactor)
{
QPointF center = v->mapToScene(v->viewport()->rect().center());
// qreal factor = v->matrix().scale(scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width();
//if (factor < 0.001 || factor > 2000)
// return;
v->scale(scaleFactor, scaleFactor);
QPoint offset = v->mapFromScene(center) - v->viewport()->rect().center();
translateView(v, offset.x(), offset.y());
}
CGAL_INLINE_FUNCTION
void GraphicsViewNavigation::drag_to(QGraphicsView* v, QPoint new_pos)
{
QPoint dragging_start_in_view = v->mapFromScene(dragging_start);
QPoint offset = new_pos - dragging_start_in_view;
// std::cerr << boost::format("drag_to: origin=(%1%, %2%)\n"
// " offset=(%3%, %4%)\n")
// % dragging_start_in_view.x() % dragging_start_in_view.y()
// % offset.x() % offset.y();
translateView(v, -offset.x(), -offset.y());
dragging_start_in_view = v->mapFromScene(dragging_start);
// std::cerr << boost::format(" after=(%1%, %2%)\n")
// % dragging_start_in_view.x() % dragging_start_in_view.y();
}
CGAL_INLINE_FUNCTION
void GraphicsViewNavigation::translateView(QGraphicsView* v, int dx, int dy)
{
if( dx == 0 && dy == 0 ) {
return;
}
int horizontalScrollBarValue = v->horizontalScrollBar()->value();
int verticalScrollBarValue = v->verticalScrollBar()->value();
if( (horizontalScrollBarValue + dx <=
v->horizontalScrollBar()->maximum()) &&
(horizontalScrollBarValue + dx >=
v->horizontalScrollBar()->minimum()) &&
(verticalScrollBarValue + dy <=
v->verticalScrollBar()->maximum()) &&
(verticalScrollBarValue + dy >=
v->verticalScrollBar()->minimum()) )
{
v->horizontalScrollBar()->setValue(horizontalScrollBarValue + dx);
v->verticalScrollBar()->setValue(verticalScrollBarValue + dy);
}
else
{
QRect vp_rect = v->viewport()->rect();
QPointF new_center = v->mapToScene(vp_rect.center() + QPoint(dx, dy));
vp_rect |= vp_rect.translated(dx, dy);
QRectF rect = mapToScene(v, vp_rect);
v->setSceneRect(v->sceneRect() | rect);
v->centerOn(new_center);
// QGraphicsView::centerOn makes rounding errors.
// The following two "if" make them unnoticable when dx==0 or dy==0.
if(dx == 0) {
v->horizontalScrollBar()->setValue(horizontalScrollBarValue);
}
if(dy == 0) {
v->verticalScrollBar()->setValue(verticalScrollBarValue);
}
}
// display_parameters();
}
CGAL_INLINE_FUNCTION
void GraphicsViewNavigation::display_parameters(QGraphicsView* v)
{
std::cerr <<
boost::format("matrix translation=(%1%, %2%)\n"
" rotation=(%3% - %4% )\n"
" (%5% - %6% )\n")
% v->matrix().dx()
% v->matrix().dy()
% v->matrix().m11()
% v->matrix().m12()
% v->matrix().m21()
% v->matrix().m22();
QRect vp_rect = v->viewport()->rect();
QPoint vp_top_left = vp_rect.topLeft();
QPoint vp_bottom_right = vp_rect.bottomRight();
QPointF top_left = v->mapToScene(vp_top_left);
QPointF bottom_right = v->mapToScene(vp_bottom_right);
std::cerr <<
boost::format("view=(%1% - %2%) x (%3% - %4%)\n")
% top_left.x() % bottom_right.x()
% top_left.y() % bottom_right.y();
std::cerr <<
boost::format("viewport=(%1% - %2%) x (%3% - %4%)\n")
% vp_top_left.x() % vp_bottom_right.x()
% vp_top_left.y() % vp_bottom_right.y();
std::cerr <<
boost::format("scrollbars=(%1% <= %2% <= %3%) x (%4% <= %5% <= %6%)\n")
% v->horizontalScrollBar()->minimum()
% v->horizontalScrollBar()->value()
% v->horizontalScrollBar()->maximum()
% v->verticalScrollBar()->minimum()
% v->verticalScrollBar()->value()
% v->verticalScrollBar()->maximum();
}
} // namespace Qt
} // namespace CGAL

View File

@ -34,6 +34,7 @@ class QGraphicsScene;
class QGraphicsSceneMouseEvent;
class QGraphicsItem;
class QGraphicsPathItem;
class QGraphicsLineItem;
class QKeyEvent;
class QEvent;
class QObject;
@ -107,4 +108,8 @@ protected:
} // namespace Qt
} // namespace CGAL
#ifdef CGAL_HEADER_ONLY
#include <CGAL/Qt/GraphicsViewPolylineInput_impl.h>
#endif // CGAL_HEADER_ONLY
#endif // CGAL_QT_GRAPHICS_VIEW_POLYLINE_INPUT_H

View File

@ -0,0 +1,206 @@
// Copyright (c) 2008 GeometryFactory Sarl (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
//
//
// Author(s) : Andreas Fabri <Andreas.Fabri@geometryfactory.com>
// Laurent Rineau <Laurent.Rineau@geometryfactory.com>
#ifdef CGAL_HEADER_ONLY
#define CGAL_INLINE_FUNCTION inline
#else
#define CGAL_INLINE_FUNCTION
#endif
#include <QGraphicsItem>
#include <QGraphicsPathItem>
#include <QGraphicsScene>
#include <QGraphicsSceneMouseEvent>
#include <QPainter>
#include <QPolygonF>
#include <QPainterPath>
#include <QEvent>
#include <QKeyEvent>
namespace CGAL {
namespace Qt {
CGAL_INLINE_FUNCTION
GraphicsViewPolylineInput_non_templated_base::
GraphicsViewPolylineInput_non_templated_base(QObject* parent,
QGraphicsScene* s,
int n,
bool closed)
: GraphicsViewInput(parent), closed_(closed), path_item(NULL), b(NULL), e(NULL), n_(n), scene_(s)
{}
CGAL_INLINE_FUNCTION
bool
GraphicsViewPolylineInput_non_templated_base::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
if( event->modifiers() ){
return false;
}
if( event->button() != ::Qt::RightButton
&& event->button() != ::Qt::LeftButton ){
return false;
}
polygon.push_back(event->scenePos());
if(path_item){
scene_->removeItem(path_item);
delete path_item;
path_item = NULL;
}
if( (event->button() == ::Qt::RightButton) || (polygon.size() == n_) ){
// call the virtual function generate_polygon(), that emit a
// CGAL::Object containing a list of points
generate_polygon();
polygon.clear();
if(b){
scene_->removeItem(b);
delete b;
b = NULL;
}
if(e){
scene_->removeItem(e);
delete e;
e = NULL;
}
return true;
}
if(event->button() == ::Qt::LeftButton){
QPainterPath qpp;
qpp.addPolygon(polygon);
path_item = new QGraphicsPathItem(qpp);
path_item->setPen(QPen(::Qt::red, 0, ::Qt::SolidLine, ::Qt::RoundCap, ::Qt::RoundJoin));
scene_->addItem(path_item);
return true;
}
return false;
}
CGAL_INLINE_FUNCTION
void
GraphicsViewPolylineInput_non_templated_base::rubberbands(const QPointF& p)
{
if(polygon.empty()){
return;
}
if(!b && closed_ ){
b = new QGraphicsLineItem();
b->setPen(QPen(::Qt::red, 0, ::Qt::SolidLine, ::Qt::RoundCap, ::Qt::RoundJoin));
scene_->addItem(b);
}
if( !e){
e = new QGraphicsLineItem();
e->setPen(QPen(::Qt::red, 0, ::Qt::SolidLine, ::Qt::RoundCap, ::Qt::RoundJoin));
scene_->addItem(e);
}
if(closed_){
QLineF bLine(polygon.front(), p);
b->setLine(bLine);
}
QLineF eLine(polygon.back(), p);
e->setLine(eLine);
}
CGAL_INLINE_FUNCTION
void
GraphicsViewPolylineInput_non_templated_base::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
sp = event->scenePos();
rubberbands(sp);
}
CGAL_INLINE_FUNCTION
bool
GraphicsViewPolylineInput_non_templated_base::keyPressEvent ( QKeyEvent * event )
{
if( event->modifiers() )
return false;
switch(event->key())
{
case ::Qt::Key_Delete:
case ::Qt::Key_Escape:
case ::Qt::Key_Backspace:
break;
default:
return false;
}
if(polygon.empty()){
return true;
}
polygon.pop_back();
if(polygon.empty()){
if(b){
scene_->removeItem(b);
delete b;
b = NULL;
}
if(e){
scene_->removeItem(e);
delete e;
e = NULL;
}
return true;
}
if(path_item){
scene_->removeItem(path_item);
delete path_item;
path_item = NULL;
}
QPainterPath qpp;
qpp.addPolygon(polygon);
path_item = new QGraphicsPathItem(qpp);
path_item->setPen(QPen(::Qt::red, 0, ::Qt::SolidLine, ::Qt::RoundCap, ::Qt::RoundJoin));
scene_->addItem(path_item);
rubberbands(sp);
return true;
}
CGAL_INLINE_FUNCTION
bool
GraphicsViewPolylineInput_non_templated_base::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::GraphicsSceneMousePress) {
QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
if(!mousePressEvent(mouseEvent)) {
// standard event processing if mousePressEvent has returned false
return QObject::eventFilter(obj, event);
}
} else if (event->type() == QEvent::GraphicsSceneMouseMove) {
QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
mouseMoveEvent(mouseEvent);
return QObject::eventFilter(obj, event);
} else if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if(!keyPressEvent(keyEvent)) {
return QObject::eventFilter(obj, event);
}
}
// standard event processing if keyPressEvent has returned false
return QObject::eventFilter(obj, event);
}
} // namespace Qt
} // namespace CGAL

View File

@ -43,5 +43,8 @@ CGAL_QT4_EXPORT void traverse_resources(const QString& name,
} // namespace Qt
} // namespace CGAL
#ifdef CGAL_HEADER_ONLY
#include <CGAL/Qt/debug_impl.h>
#endif // CGAL_HEADER_ONLY
#endif // CGAL_QT_DEBUG_H

View File

@ -0,0 +1,60 @@
// Copyright (c) 2008 GeometryFactory Sarl (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
//
//
// Author(s) : Andreas Fabri <Andreas.Fabri@geometryfactory.com>
// Laurent Rineau <Laurent.Rineau@geometryfactory.com>
#ifdef CGAL_HEADER_ONLY
#define CGAL_INLINE_FUNCTION inline
#else
#define CGAL_INLINE_FUNCTION
#endif
#include <CGAL/Qt/debug.h>
#include <QDir>
#include <iostream>
namespace CGAL {
namespace Qt {
CGAL_INLINE_FUNCTION
void traverse_resources(const QString& name, const QString& dirname, int indent)
{
std::cerr << qPrintable(QString(indent, ' '))
<< qPrintable(name);
QString fullname =
dirname.isEmpty() ?
name :
dirname + "/" + name;
QDir dir(fullname);
if(dir.exists()) {
std::cerr << "/\n";
Q_FOREACH(QString path, dir.entryList())
{
traverse_resources(path, fullname, indent + 2);
}
}
else {
std::cerr << "\n";
}
}
} // namesapce Qt
} // namespace CGAL

View File

@ -30,4 +30,8 @@ CGAL_QT4_EXPORT void CGAL_Qt4_init_resources();
// The do{}while(0) trick is used to make that macro value a regular
// statement and not a compound statement.
#ifdef CGAL_HEADER_ONLY
#include <CGAL/Qt/resources_impl.h>
#endif // CGAL_HEADER_ONLY
#endif // CGAL_QT_RESOURCES_H

View File

@ -0,0 +1,37 @@
// Copyright (c) 2011 GeometryFactory Sarl (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
//
//
// Author(s) : Laurent Rineau <Laurent.Rineau@geometryfactory.com>
#ifdef CGAL_HEADER_ONLY
#define CGAL_INLINE_FUNCTION inline
#else
#define CGAL_INLINE_FUNCTION
#endif
#include <QDir>
#include <CGAL/Qt/resources.h>
// cannot use namespaces because of the Q_INIT_RESOURCE macro
CGAL_INLINE_FUNCTION
void CGAL_Qt4_init_resources() {
Q_INIT_RESOURCE(File);
Q_INIT_RESOURCE(Triangulation_2);
Q_INIT_RESOURCE(Input);
Q_INIT_RESOURCE(CGAL);
}

View File

@ -39,4 +39,8 @@ CGAL_QT4_EXPORT QRectF viewportsBbox(const QGraphicsScene*);
} // namespace Qt
} // namespace CGAL
#ifdef CGAL_HEADER_ONLY
#include <CGAL/Qt/utility_impl.h>
#endif // CGAL_HEADER_ONLY
#endif // CGAL_QT_UTILITY_H

View File

@ -0,0 +1,62 @@
// Copyright (c) 2008 GeometryFactory Sarl (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
//
//
// Author(s) : Andreas Fabri <Andreas.Fabri@geometryfactory.com>
// Laurent Rineau <Laurent.Rineau@geometryfactory.com>
#ifdef CGAL_HEADER_ONLY
#define CGAL_INLINE_FUNCTION inline
#else
#define CGAL_INLINE_FUNCTION
#endif
#include <CGAL/Qt/utility.h>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QList>
#include <QPoint>
#include <QPointF>
namespace CGAL {
namespace Qt {
CGAL_INLINE_FUNCTION
QRectF mapToScene(const QGraphicsView* v, const QRect rect)
{
QPointF top_left = v->mapToScene(rect.topLeft());
QPointF size = v->mapToScene(rect.bottomRight());
size -= top_left;
return QRectF(top_left.x(),
top_left.y(),
size.x(),
size.y());
}
CGAL_INLINE_FUNCTION
QRectF viewportsBbox(const QGraphicsScene* scene) {
QRectF rect;
Q_FOREACH(QGraphicsView* view, scene->views())
{
rect |= mapToScene(view, view->viewport()->rect());
}
rect = rect.normalized();
return rect;
}
} // namespace Qt
} // namespace CGAL

View File

@ -19,420 +19,10 @@
// Author(s) : Andreas Fabri <Andreas.Fabri@geometryfactory.com>
// Laurent Rineau <Laurent.Rineau@geometryfactory.com>
#include <CGAL/Qt/GraphicsViewNavigation.h>
#include <QApplication>
#include <QLabel>
#include <QFile>
#include <QFileDialog>
#include <QFileInfo>
#include <QMenu>
#include <QMenuBar>
#include <QAction>
#include <QMessageBox>
#include <QStatusBar>
#include <QGraphicsView>
#include <QGLWidget>
#include <QTextStream>
#include <QSettings>
#include <QUrl>
#include <QDesktopWidget>
#include <QRegExp>
#include <QSvgGenerator>
#ifndef CGAL_HEADER_ONLY
#include <CGAL/config.h> // needed to get CGAL_VERSION_STR
#include <CGAL/Qt/DemosMainWindow.h>
#include <iostream>
#include <CGAL/Qt/DemosMainWindow_impl.h>
namespace CGAL {
namespace Qt {
DemosMainWindow::DemosMainWindow(QWidget * parent, ::Qt::WindowFlags flags)
: QMainWindow(parent, flags),
maxNumRecentFiles(10),
recentFileActs(maxNumRecentFiles)
{
// prepare the QLabel xycoord for inclusion in the statusBar()
xycoord = new QLabel(" -0.00000 , -0.00000 ", this);
xycoord->setAlignment(::Qt::AlignHCenter);
xycoord->setMinimumSize(xycoord->sizeHint());
xycoord->clear();
actionUse_OpenGL = new QAction(this);
actionUse_OpenGL->setObjectName("actionUse_OpenGL");
actionUse_OpenGL->setCheckable(true);
actionUse_OpenGL->setText(tr("Use &OpenGL"));
actionUse_OpenGL->setStatusTip(tr("Make Qt use OpenGL to display the graphical items, instead of its native painting system."));
actionUse_OpenGL->setShortcut(tr("Ctrl+G"));
actionUse_Antialiasing = new QAction(this);
actionUse_Antialiasing->setObjectName("actionUse_Antialiasing");
actionUse_Antialiasing->setCheckable(true);
actionUse_Antialiasing->setText(tr("Use &anti-aliasing"));
actionUse_Antialiasing->setStatusTip(tr("Make Qt use anti-aliasing when displaying the graphical items."));
actionUse_Antialiasing->setShortcut(tr("Ctrl+A"));
actionAboutCGAL = new QAction(this);
actionAboutCGAL->setObjectName("actionAboutCGAL");
actionAboutCGAL->setText(tr("About &CGAL..."));
actionAbout = new QAction(this);
actionAbout->setObjectName("actionAbout");
actionAbout->setText(tr("&About..."));
setAcceptDrops(true);
}
void
DemosMainWindow::dragEnterEvent(QDragEnterEvent *event)
{
if (event->mimeData()->hasFormat("text/uri-list"))
event->acceptProposedAction();
}
void
DemosMainWindow::dropEvent(QDropEvent *event)
{
Q_FOREACH(QUrl url, event->mimeData()->urls()) {
QString filename = url.toLocalFile();
this->open(filename);
}
event->acceptProposedAction();
}
void
DemosMainWindow::addNavigation(QGraphicsView* graphicsView)
{
navigation = new CGAL::Qt::GraphicsViewNavigation();
graphicsView->viewport()->installEventFilter(navigation);
graphicsView->installEventFilter(navigation);
QObject::connect(navigation, SIGNAL(mouseCoordinates(QString)),
xycoord, SLOT(setText(QString)));
view = graphicsView;
}
void
DemosMainWindow::setupStatusBar()
{
this->statusBar()->addWidget(new QLabel(this), 1);
this->statusBar()->addWidget(xycoord, 0);
}
void
DemosMainWindow::setupOptionsMenu(QMenu* menuOptions)
{
// search for the Options menu
if(!menuOptions) {
menuOptions = getMenu("menuOptions", tr("&Options"));
}
// if not found, then create it
if(!menuOptions) {
menuOptions = new QMenu(this->menuBar());
menuOptions->setTitle(tr("&Options"));
this->menuBar()->addAction(menuOptions->menuAction());
menuOptions->setObjectName("menuOptions");
}
if(!menuOptions->isEmpty()) {
menuOptions->addSeparator();
}
menuOptions->addAction(actionUse_OpenGL);
menuOptions->addAction(actionUse_Antialiasing);
connect(actionUse_Antialiasing, SIGNAL(toggled(bool)),
this, SLOT(setUseAntialiasing(bool)));
connect(actionUse_OpenGL, SIGNAL(toggled(bool)),
this, SLOT(setUseOpenGL(bool)));
actionUse_Antialiasing->setChecked(true);
}
void
DemosMainWindow::setupExportSVG(QAction* action, QGraphicsView* view)
{
this->view = view;
connect(action, SIGNAL(triggered(bool)),
this, SLOT(exportSVG()));
}
void DemosMainWindow::exportSVG()
{
QString fileName = QFileDialog::getSaveFileName(this,
tr("Export to SVG"),
".",
tr("SVG (*.svg)\n"));
QSvgGenerator svg;
svg.setFileName(fileName);
svg.setSize(this->view->size());
svg.setViewBox(this->view->sceneRect());
svg.setTitle(tr("%1 drawing").arg(qApp->applicationName()));
svg.setDescription(tr("Generated using %1").arg(qApp->applicationName()));
QPainter painter;
painter.begin(&svg);
this->view->render(&painter);
painter.end();
}
void
DemosMainWindow::setUseAntialiasing(bool checked)
{
view->setRenderHint(QPainter::Antialiasing, checked);
#if QT_VERSION >= 0x040300
view->setRenderHint(QPainter::HighQualityAntialiasing, checked);
#endif
statusBar()->showMessage(tr("Antialiasing %1activated").arg(checked?"":"de-"),
1000);
}
void
DemosMainWindow::setUseOpenGL(bool checked)
{
if(checked) {
QGLWidget* new_viewport = new QGLWidget;
// Setup the format to allow antialiasing with OpenGL:
// one need to activate the SampleBuffers, if the graphic driver allows
// this.
QGLFormat glformat = new_viewport->format();
glformat.setOption(QGL::SampleBuffers);
new_viewport->setFormat(glformat);
view->setViewport(new_viewport);
}
else {
view->setViewport(new QWidget);
}
statusBar()->showMessage(tr("OpenGL %1activated").arg(checked?"":"de-"),
1000);
view->viewport()->installEventFilter(navigation);
view->setFocus();
}
QMenu*
DemosMainWindow::getMenu(QString objectName, QString title)
{
QMenu* menu = NULL;
QString title2 = title;
title2.remove('&');
// search if a menu has objectName()==objectName
menu = this->findChild<QMenu*>(objectName);
// then search if a menu has title()==title
if(menu) {
return menu;
} else {
Q_FOREACH(menu, this->findChildren<QMenu*>()) {
if(menu->title() == title ||
menu->title() == title2) {
return menu;
}
}
}
return NULL;
}
void
DemosMainWindow::popupAboutBox(QString title, QString html_resource_name)
{
QFile about_CGAL(html_resource_name);
about_CGAL.open(QIODevice::ReadOnly);
QString about_CGAL_txt = QTextStream(&about_CGAL).readAll();
#ifdef CGAL_VERSION_STR
QString cgal_version(CGAL_VERSION_STR);
# ifdef CGAL_FAKE_PUBLIC_RELEASE
cgal_version.replace(QRegExp("-Ic?.*"), "");
# endif
about_CGAL_txt.replace("<!--CGAL_VERSION-->",
QString(" (version %1)")
.arg(cgal_version));
#endif
QMessageBox mb(QMessageBox::NoIcon,
title,
about_CGAL_txt,
QMessageBox::Ok,
this);
QLabel* mb_label = mb.findChild<QLabel*>("qt_msgbox_label");
if(mb_label) {
mb_label->setTextInteractionFlags(mb_label->textInteractionFlags() |
::Qt::LinksAccessibleByMouse |
::Qt::LinksAccessibleByKeyboard);
}
else {
std::cerr << "Cannot find child \"qt_msgbox_label\" in QMessageBox\n"
<< " with Qt version " << QT_VERSION_STR << "!\n";
}
mb.exec();
}
QMenu* DemosMainWindow::getHelpMenu()
{
QMenu* menuHelp = getMenu("menuHelp", tr("&Help"));
if(!menuHelp) {
menuHelp = new QMenu(this->menuBar());
menuHelp->setTitle(tr("&Help"));
this->menuBar()->addAction(menuHelp->menuAction());
menuHelp->setObjectName("menuHelp");
}
return menuHelp;
}
void
DemosMainWindow::addAboutCGAL(QMenu* menuHelp)
{
if(!menuHelp) {
menuHelp = getHelpMenu();
}
menuHelp->addAction(actionAboutCGAL);
connect(actionAboutCGAL, SIGNAL(triggered()),
this, SLOT(popupAboutCGAL()));
}
void
DemosMainWindow::addAboutDemo(QString htmlResourceName, QMenu* menuHelp)
{
if(!menuHelp) {
menuHelp = getHelpMenu();
}
menuHelp->addAction(actionAbout);
aboutHtmlResource = htmlResourceName;
connect(actionAbout, SIGNAL(triggered()),
this, SLOT(popupAboutDemo()));
}
void
DemosMainWindow::popupAboutCGAL()
{
popupAboutBox(tr("About CGAL..."),
":/cgal/help/about_CGAL.html");
}
void
DemosMainWindow::popupAboutDemo()
{
popupAboutBox(tr("About the demo..."),
aboutHtmlResource);
}
void
DemosMainWindow::setMaxNumberOfRecentFiles(const unsigned int i)
{
maxNumRecentFiles = i;
recentFileActs.resize(maxNumRecentFiles);
}
unsigned int
DemosMainWindow::maxNumberOfRecentFiles() const
{
return maxNumRecentFiles;
}
void
DemosMainWindow::openRecentFile_aux()
{
QAction *action = qobject_cast<QAction *>(sender());
if (action)
emit openRecentFile(action->data().toString());
}
void
DemosMainWindow::addToRecentFiles(QString fileName)
{
QSettings settings;
QStringList files = settings.value("recentFileList").toStringList();
files.removeAll(fileName);
files.prepend(fileName);
while (files.size() > (int)maxNumberOfRecentFiles())
files.removeLast();
settings.setValue("recentFileList", files);
updateRecentFileActions();
}
void
DemosMainWindow::addRecentFiles(QMenu* menu, QAction* insertBeforeAction)
{
if(!insertBeforeAction) {
recentFilesSeparator = menu->addSeparator();
}
for (unsigned int i = 0; i < maxNumberOfRecentFiles(); ++i) {
recentFileActs[i] = new QAction(this);
recentFileActs[i]->setVisible(false);
connect(recentFileActs[i], SIGNAL(triggered()),
this, SLOT(openRecentFile_aux()));
if(insertBeforeAction)
menu->insertAction(insertBeforeAction, recentFileActs[i]);
else
menu->addAction(recentFileActs[i]);
}
if(insertBeforeAction) {
recentFilesSeparator = menu->insertSeparator(insertBeforeAction);
}
recentFilesSeparator->setVisible(false);
updateRecentFileActions();
}
void
DemosMainWindow::updateRecentFileActions()
{
QSettings settings;
QStringList files = settings.value("recentFileList").toStringList();
int numRecentFiles = qMin(files.size(), (int)this->maxNumberOfRecentFiles());
for (int i = 0; i < numRecentFiles; ++i) {
QString strippedName = QFileInfo(files[i]).fileName();
QString text = tr("&%1 %2").arg(i).arg(strippedName);
recentFileActs[i]->setText(text);
recentFileActs[i]->setData(files[i]);
recentFileActs[i]->setVisible(true);
}
for (unsigned int j = numRecentFiles; j < maxNumberOfRecentFiles(); ++j)
recentFileActs[j]->setVisible(false);
recentFilesSeparator->setVisible(numRecentFiles > 0);
}
void DemosMainWindow::writeState(QString groupname)
{
QSettings settings;
settings.beginGroup(groupname);
settings.setValue("size", size());
settings.setValue("pos", pos());
settings.setValue("state", saveState());
settings.endGroup();
}
void DemosMainWindow::readState(QString groupname, Options /*what_to_save*/)
{
QSettings settings;
settings.beginGroup(groupname);
resize(settings.value("size", this->size()).toSize());
QDesktopWidget* desktop = qApp->desktop();
QPoint pos = settings.value("pos", this->pos()).toPoint();
if(desktop->availableGeometry(pos).contains(pos)) {
move(pos);
}
QByteArray mainWindowState = settings.value("state").toByteArray();
if(!mainWindowState.isNull()) {
this->restoreState(mainWindowState);
}
settings.endGroup();
}
} // namespace Qt
} // namespace CGAL
#endif // CGAL_HEADER_ONLY

View File

@ -19,320 +19,9 @@
// Author(s) : Andreas Fabri <Andreas.Fabri@geometryfactory.com>
// Laurent Rineau <Laurent.Rineau@geometryfactory.com>
#ifndef CGAL_HEADER_ONLY
#include <CGAL/Qt/GraphicsViewNavigation.h>
#include <CGAL/Qt/utility.h> // for mapToScene(QGraphicsView*, QRect)
#include <cmath>
#include <iostream>
#include <boost/format.hpp>
#include <QEvent>
#include <QMouseEvent>
#include <QWheelEvent>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsRectItem>
#include <QFlags>
#include <QScrollBar>
namespace CGAL {
namespace Qt {
GraphicsViewNavigation::GraphicsViewNavigation()
: rectItem(new QGraphicsRectItem),
dragging(false)
{
QColor rect_color(250, 221, 0);
rect_color.setAlpha(50);
rectItem->setBrush(rect_color);
rect_color.setAlpha(255);
rectItem->setPen(QPen(rect_color, 0, ::Qt::DashLine));
rectItem->hide();
rectItem->setZValue(10000);
}
GraphicsViewNavigation::~GraphicsViewNavigation()
{
delete rectItem;
}
bool
GraphicsViewNavigation::eventFilter(QObject *obj, QEvent *event)
{
QGraphicsView* v = qobject_cast<QGraphicsView*>(obj);
if(v == NULL) {
QWidget* viewport = qobject_cast<QWidget*>(obj);
if(viewport == NULL) {
return false;
}
v = qobject_cast<QGraphicsView*>(viewport->parent());
if(v == NULL) {
return false;
}
}
switch(event->type())
{
case QEvent::KeyPress: {
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
int offset = 10;
if( (keyEvent->modifiers() & ::Qt::ShiftModifier)
|| (keyEvent->modifiers() & ::Qt::ControlModifier) ) {
offset = 20;
}
switch (keyEvent->key()) {
case ::Qt::Key_Up:
translateView(v, 0, -offset);
break;
case ::Qt::Key_Down:
translateView(v, 0, offset);
break;
case ::Qt::Key_Left:
translateView(v, -offset, 0);
break;
case ::Qt::Key_Right:
translateView(v, offset, 0);
break;
case ::Qt::Key_PageUp:
v->rotate(-6);
break;
case ::Qt::Key_PageDown:
v->rotate(6);
break;
case ::Qt::Key_Plus:
scaleView(v, 1.2);
break;
case ::Qt::Key_Minus:
scaleView(v, 1 / 1.2);
break;
case ::Qt::Key_Control:
cursor_backup = v->cursor();
v->setCursor(::Qt::CrossCursor);
default:
return false;
}
// display_parameters();
return true;
break;
} // end case KeyPress
case QEvent::KeyRelease: {
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
if(keyEvent->key() == ::Qt::Key_Control) {
if(rectItem->isVisible() ) {
dragging = false;
v->scene()->removeItem(rectItem);
rectItem->hide();
}
v->setCursor(cursor_backup);
return true;
}
return false;
break;
} // end case KeyRelease
case QEvent::Wheel: {
QWheelEvent *wheelEvent = static_cast<QWheelEvent*>(event);
if(wheelEvent->orientation() != ::Qt::Vertical) {
return false;
}
double zoom_ratio = 240.0;
if( (wheelEvent->modifiers() & ::Qt::ShiftModifier)
|| (wheelEvent->modifiers() & ::Qt::ControlModifier) ) {
zoom_ratio = 120.0;
}
scaleView(v, pow((double)2, -wheelEvent->delta() / zoom_ratio));
// display_parameters();
return true;
break;
} // end case Wheel
case QEvent::MouseButtonPress: {
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
if( (mouseEvent->modifiers() == (::Qt::ControlModifier | ::Qt::ShiftModifier))
&& mouseEvent->button() == ::Qt::RightButton )
{
QPoint offset = mouseEvent->pos() - v->viewport()->rect().center();
translateView(v, offset.x(), offset.y());
return true;
}
else if( mouseEvent->modifiers() == ::Qt::ControlModifier ) {
if(mouseEvent->button() == ::Qt::LeftButton) {
rect_first_point = v->mapToScene(mouseEvent->pos());
rectItem->setRect(QRectF(rect_first_point, QSizeF(0.,0.)));
rectItem->show();
v->scene()->addItem(rectItem);
return true;
}
else if( mouseEvent->button() == ::Qt::RightButton) {
dragging = true;
dragging_start = v->mapToScene(mouseEvent->pos());
v->setCursor(::Qt::ClosedHandCursor);
return true;
}
}
return false;
break;
} // end case MouseRelease
case QEvent::MouseMove: {
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
QPointF pos = v->mapToScene(mouseEvent->pos());
QString xy = QString(" ") + QString::number(pos.x(),'g', 6) + " , " + QString::number(pos.y(),'g', 6) + " ";
emit mouseCoordinates(xy);
if(rectItem->isVisible()) {
QPointF size = v->mapToScene(mouseEvent->pos());
size = size - rect_first_point;
rectItem->setRect(rect_first_point.x(),
rect_first_point.y(),
size.x(),
size.y());
}
if( dragging )
{
// std::cerr << boost::format("mouseMove: globalpos=(%1%, %2%)\n"
// " pos=(%3%, %4%)\n"
// " sender=%5% (class %6%), parent class %7%\n")
// % mouseEvent->globalPos().x()
// % mouseEvent->globalPos().y()
// % mouseEvent->pos().x()
// % mouseEvent->pos().y()
// % (&*obj)
// % obj->metaObject()->className()
// % obj->parent()->metaObject()->className();
// drag_to(mouseEvent->pos());
}
break;
} // end MouseMove
case QEvent::MouseButtonRelease: {
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
if(rectItem->isVisible() && mouseEvent->button() == ::Qt::LeftButton){
v->setSceneRect(v->sceneRect() | rectItem->rect());
v->fitInView(rectItem->rect(), ::Qt::KeepAspectRatio);
v->scene()->removeItem(rectItem);
rectItem->hide();
return true;
}
else if( mouseEvent->button() == ::Qt::RightButton ) {
if(dragging) {
dragging = false;
drag_to(v, mouseEvent->pos());
v->setCursor(cursor_backup);
return true;
}
}
return false;
break;
} // end MouseRelease
default:
return false;
} // end switch
return false;
}
void
GraphicsViewNavigation::scaleView(QGraphicsView* v, qreal scaleFactor)
{
QPointF center = v->mapToScene(v->viewport()->rect().center());
// qreal factor = v->matrix().scale(scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width();
//if (factor < 0.001 || factor > 2000)
// return;
v->scale(scaleFactor, scaleFactor);
QPoint offset = v->mapFromScene(center) - v->viewport()->rect().center();
translateView(v, offset.x(), offset.y());
}
void GraphicsViewNavigation::drag_to(QGraphicsView* v, QPoint new_pos)
{
QPoint dragging_start_in_view = v->mapFromScene(dragging_start);
QPoint offset = new_pos - dragging_start_in_view;
// std::cerr << boost::format("drag_to: origin=(%1%, %2%)\n"
// " offset=(%3%, %4%)\n")
// % dragging_start_in_view.x() % dragging_start_in_view.y()
// % offset.x() % offset.y();
translateView(v, -offset.x(), -offset.y());
dragging_start_in_view = v->mapFromScene(dragging_start);
// std::cerr << boost::format(" after=(%1%, %2%)\n")
// % dragging_start_in_view.x() % dragging_start_in_view.y();
}
void GraphicsViewNavigation::translateView(QGraphicsView* v, int dx, int dy)
{
if( dx == 0 && dy == 0 ) {
return;
}
int horizontalScrollBarValue = v->horizontalScrollBar()->value();
int verticalScrollBarValue = v->verticalScrollBar()->value();
if( (horizontalScrollBarValue + dx <=
v->horizontalScrollBar()->maximum()) &&
(horizontalScrollBarValue + dx >=
v->horizontalScrollBar()->minimum()) &&
(verticalScrollBarValue + dy <=
v->verticalScrollBar()->maximum()) &&
(verticalScrollBarValue + dy >=
v->verticalScrollBar()->minimum()) )
{
v->horizontalScrollBar()->setValue(horizontalScrollBarValue + dx);
v->verticalScrollBar()->setValue(verticalScrollBarValue + dy);
}
else
{
QRect vp_rect = v->viewport()->rect();
QPointF new_center = v->mapToScene(vp_rect.center() + QPoint(dx, dy));
vp_rect |= vp_rect.translated(dx, dy);
QRectF rect = mapToScene(v, vp_rect);
v->setSceneRect(v->sceneRect() | rect);
v->centerOn(new_center);
// QGraphicsView::centerOn makes rounding errors.
// The following two "if" make them unnoticable when dx==0 or dy==0.
if(dx == 0) {
v->horizontalScrollBar()->setValue(horizontalScrollBarValue);
}
if(dy == 0) {
v->verticalScrollBar()->setValue(verticalScrollBarValue);
}
}
// display_parameters();
}
void GraphicsViewNavigation::display_parameters(QGraphicsView* v)
{
std::cerr <<
boost::format("matrix translation=(%1%, %2%)\n"
" rotation=(%3% - %4% )\n"
" (%5% - %6% )\n")
% v->matrix().dx()
% v->matrix().dy()
% v->matrix().m11()
% v->matrix().m12()
% v->matrix().m21()
% v->matrix().m22();
QRect vp_rect = v->viewport()->rect();
QPoint vp_top_left = vp_rect.topLeft();
QPoint vp_bottom_right = vp_rect.bottomRight();
QPointF top_left = v->mapToScene(vp_top_left);
QPointF bottom_right = v->mapToScene(vp_bottom_right);
std::cerr <<
boost::format("view=(%1% - %2%) x (%3% - %4%)\n")
% top_left.x() % bottom_right.x()
% top_left.y() % bottom_right.y();
std::cerr <<
boost::format("viewport=(%1% - %2%) x (%3% - %4%)\n")
% vp_top_left.x() % vp_bottom_right.x()
% vp_top_left.y() % vp_bottom_right.y();
std::cerr <<
boost::format("scrollbars=(%1% <= %2% <= %3%) x (%4% <= %5% <= %6%)\n")
% v->horizontalScrollBar()->minimum()
% v->horizontalScrollBar()->value()
% v->horizontalScrollBar()->maximum()
% v->verticalScrollBar()->minimum()
% v->verticalScrollBar()->value()
% v->verticalScrollBar()->maximum();
}
} // namespace Qt
} // namespace CGAL
#include <CGAL/Qt/GraphicsViewNavigation_impl.h>
#endif // CGAL_HEADER_ONLY

View File

@ -19,178 +19,9 @@
// Author(s) : Andreas Fabri <Andreas.Fabri@geometryfactory.com>
// Laurent Rineau <Laurent.Rineau@geometryfactory.com>
#include <QGraphicsItem>
#include <QGraphicsPathItem>
#include <QGraphicsScene>
#include <QGraphicsSceneMouseEvent>
#include <QPainter>
#include <QPolygonF>
#include <QPainterPath>
#include <QEvent>
#include <QKeyEvent>
#ifndef CGAL_HEADER_ONLY
#include <CGAL/Qt/GraphicsViewPolylineInput.h>
#include <CGAL/Qt/GraphicsViewPolylineInput_impl.h>
namespace CGAL {
namespace Qt {
GraphicsViewPolylineInput_non_templated_base::
GraphicsViewPolylineInput_non_templated_base(QObject* parent,
QGraphicsScene* s,
int n,
bool closed)
: GraphicsViewInput(parent), closed_(closed), path_item(NULL), b(NULL), e(NULL), n_(n), scene_(s)
{}
bool
GraphicsViewPolylineInput_non_templated_base::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
if( event->modifiers() ){
return false;
}
if( event->button() != ::Qt::RightButton
&& event->button() != ::Qt::LeftButton ){
return false;
}
polygon.push_back(event->scenePos());
if(path_item){
scene_->removeItem(path_item);
delete path_item;
path_item = NULL;
}
if( (event->button() == ::Qt::RightButton) || (polygon.size() == n_) ){
// call the virtual function generate_polygon(), that emit a
// CGAL::Object containing a list of points
generate_polygon();
polygon.clear();
if(b){
scene_->removeItem(b);
delete b;
b = NULL;
}
if(e){
scene_->removeItem(e);
delete e;
e = NULL;
}
return true;
}
if(event->button() == ::Qt::LeftButton){
QPainterPath qpp;
qpp.addPolygon(polygon);
path_item = new QGraphicsPathItem(qpp);
path_item->setPen(QPen(::Qt::red, 0, ::Qt::SolidLine, ::Qt::RoundCap, ::Qt::RoundJoin));
scene_->addItem(path_item);
return true;
}
return false;
}
void
GraphicsViewPolylineInput_non_templated_base::rubberbands(const QPointF& p)
{
if(polygon.empty()){
return;
}
if(!b && closed_ ){
b = new QGraphicsLineItem();
b->setPen(QPen(::Qt::red, 0, ::Qt::SolidLine, ::Qt::RoundCap, ::Qt::RoundJoin));
scene_->addItem(b);
}
if( !e){
e = new QGraphicsLineItem();
e->setPen(QPen(::Qt::red, 0, ::Qt::SolidLine, ::Qt::RoundCap, ::Qt::RoundJoin));
scene_->addItem(e);
}
if(closed_){
QLineF bLine(polygon.front(), p);
b->setLine(bLine);
}
QLineF eLine(polygon.back(), p);
e->setLine(eLine);
}
void
GraphicsViewPolylineInput_non_templated_base::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
sp = event->scenePos();
rubberbands(sp);
}
bool
GraphicsViewPolylineInput_non_templated_base::keyPressEvent ( QKeyEvent * event )
{
if( event->modifiers() )
return false;
switch(event->key())
{
case ::Qt::Key_Delete:
case ::Qt::Key_Escape:
case ::Qt::Key_Backspace:
break;
default:
return false;
}
if(polygon.empty()){
return true;
}
polygon.pop_back();
if(polygon.empty()){
if(b){
scene_->removeItem(b);
delete b;
b = NULL;
}
if(e){
scene_->removeItem(e);
delete e;
e = NULL;
}
return true;
}
if(path_item){
scene_->removeItem(path_item);
delete path_item;
path_item = NULL;
}
QPainterPath qpp;
qpp.addPolygon(polygon);
path_item = new QGraphicsPathItem(qpp);
path_item->setPen(QPen(::Qt::red, 0, ::Qt::SolidLine, ::Qt::RoundCap, ::Qt::RoundJoin));
scene_->addItem(path_item);
rubberbands(sp);
return true;
}
bool
GraphicsViewPolylineInput_non_templated_base::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::GraphicsSceneMousePress) {
QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
if(!mousePressEvent(mouseEvent)) {
// standard event processing if mousePressEvent has returned false
return QObject::eventFilter(obj, event);
}
} else if (event->type() == QEvent::GraphicsSceneMouseMove) {
QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
mouseMoveEvent(mouseEvent);
return QObject::eventFilter(obj, event);
} else if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if(!keyPressEvent(keyEvent)) {
return QObject::eventFilter(obj, event);
}
}
// standard event processing if keyPressEvent has returned false
return QObject::eventFilter(obj, event);
}
} // namespace Qt
} // namespace CGAL
#endif // CGAL_HEADER_ONLY

View File

@ -19,35 +19,9 @@
// Author(s) : Andreas Fabri <Andreas.Fabri@geometryfactory.com>
// Laurent Rineau <Laurent.Rineau@geometryfactory.com>
#ifndef CGAL_HEADER_ONLY
#include <CGAL/Qt/debug.h>
#include <QDir>
#include <CGAL/Qt/debug_impl.h>
#include <iostream>
namespace CGAL {
namespace Qt {
void traverse_resources(const QString& name, const QString& dirname, int indent)
{
std::cerr << qPrintable(QString(indent, ' '))
<< qPrintable(name);
QString fullname =
dirname.isEmpty() ?
name :
dirname + "/" + name;
QDir dir(fullname);
if(dir.exists()) {
std::cerr << "/\n";
Q_FOREACH(QString path, dir.entryList())
{
traverse_resources(path, fullname, indent + 2);
}
}
else {
std::cerr << "\n";
}
}
} // namesapce Qt
} // namespace CGAL
#endif // CGAL_HEADER_ONLY

View File

@ -18,13 +18,9 @@
//
// Author(s) : Laurent Rineau <Laurent.Rineau@geometryfactory.com>
#include <QDir>
#include <CGAL/Qt/resources.h>
#ifndef CGAL_HEADER_ONLY
// cannot use namespaces because of the Q_INIT_RESOURCE macro
void CGAL_Qt4_init_resources() {
Q_INIT_RESOURCE(File);
Q_INIT_RESOURCE(Triangulation_2);
Q_INIT_RESOURCE(Input);
Q_INIT_RESOURCE(CGAL);
}
#include <CGAL/Qt/resources.h>
#include <CGAL/Qt/resources_impl.h>
#endif // CGAL_HEADER_ONLY

View File

@ -19,36 +19,9 @@
// Author(s) : Andreas Fabri <Andreas.Fabri@geometryfactory.com>
// Laurent Rineau <Laurent.Rineau@geometryfactory.com>
#ifndef CGAL_HEADER_ONLY
#include <CGAL/Qt/utility.h>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QList>
#include <QPoint>
#include <QPointF>
#include <CGAL/Qt/utility_impl.h>
namespace CGAL {
namespace Qt {
QRectF mapToScene(const QGraphicsView* v, const QRect rect)
{
QPointF top_left = v->mapToScene(rect.topLeft());
QPointF size = v->mapToScene(rect.bottomRight());
size -= top_left;
return QRectF(top_left.x(),
top_left.y(),
size.x(),
size.y());
}
QRectF viewportsBbox(const QGraphicsScene* scene) {
QRectF rect;
Q_FOREACH(QGraphicsView* view, scene->views())
{
rect |= mapToScene(view, view->viewport()->rect());
}
rect = rect.normalized();
return rect;
}
} // namespace Qt
} // namespace CGAL
#endif // CGAL_HEADER_ONLY

View File

@ -20,20 +20,29 @@
#ifndef CGAL_EXPORT_HELPERS_H
#define CGAL_EXPORT_HELPERS_H
#if defined(_WIN32) || defined(__CYGWIN__)
# define CGAL_DLL_IMPORT __declspec(dllimport)
# define CGAL_DLL_EXPORT __declspec(dllexport)
# define CGAL_DLL_LOCAL
#else
#if __GNUC__ >= 4
#define CGAL_DLL_IMPORT __attribute__ ((visibility ("default")))
#define CGAL_DLL_EXPORT __attribute__ ((visibility ("default")))
#define CGAL_DLL_LOCAL __attribute__ ((visibility ("hidden")))
#else
#define CGAL_DLL_IMPORT
#define CGAL_DLL_EXPORT
#define CGAL_DLL_LOCAL
#endif
#endif
// CJTODO: uncomment this when everything is ready
/*#ifdef CGAL_HEADER_ONLY
# define CGAL_DLL_IMPORT
# define CGAL_DLL_EXPORT
# define CGAL_DLL_LOCA
#else // !CGAL_HEADER_ONLY*/
# if defined(_WIN32) || defined(__CYGWIN__)
# define CGAL_DLL_IMPORT __declspec(dllimport)
# define CGAL_DLL_EXPORT __declspec(dllexport)
# define CGAL_DLL_LOCAL
# else
#if __GNUC__ >= 4
#define CGAL_DLL_IMPORT __attribute__ ((visibility ("default")))
#define CGAL_DLL_EXPORT __attribute__ ((visibility ("default")))
#define CGAL_DLL_LOCAL __attribute__ ((visibility ("hidden")))
#else
#define CGAL_DLL_IMPORT
#define CGAL_DLL_EXPORT
#define CGAL_DLL_LOCAL
#endif
# endif
//#endif // CGAL_HEADER_ONLY
#endif // CGAL_EXPORT_HELPERS_H

View File

@ -96,4 +96,8 @@ inline bool do_intersect(
} //namespace CGAL
#ifdef CGAL_HEADER_ONLY
#include <CGAL/Bbox_2_Line_2_intersection_impl.h>
#endif // CGAL_HEADER_ONLY
#endif

View File

@ -0,0 +1,210 @@
// Copyright (c) 2000
// Utrecht University (The Netherlands),
// ETH Zurich (Switzerland),
// INRIA Sophia-Antipolis (France),
// Max-Planck-Institute Saarbruecken (Germany),
// and Tel-Aviv University (Israel). All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
//
//
// Author(s) : Geert-Jan Giezeman
#ifdef CGAL_HEADER_ONLY
#define CGAL_INLINE_FUNCTION inline
#else
#define CGAL_INLINE_FUNCTION
#endif
#include <CGAL/Simple_cartesian.h>
typedef CGAL::Simple_cartesian<double> Lcart;
namespace CGAL {
class Bbox_2_Line_2_pair_impl
{
public:
Bbox_2_Line_2_pair_impl() {}
Bbox_2_Line_2_pair_impl(Bbox_2 const &bb, Lcart::Line_2 const &line)
: _bbox(bb), _line(line), _known(false) {}
Bbox_2 _bbox;
Lcart::Line_2 _line;
mutable bool _known;
mutable Bbox_2_Line_2_pair::Intersection_results _result;
mutable double _min, _max;
};
CGAL_INLINE_FUNCTION
Bbox_2_Line_2_pair::~Bbox_2_Line_2_pair()
{
delete pimpl;
}
CGAL_INLINE_FUNCTION
Bbox_2_Line_2_pair::Bbox_2_Line_2_pair()
{
pimpl = new Bbox_2_Line_2_pair_impl;
pimpl->_known = false;
}
CGAL_INLINE_FUNCTION
Bbox_2_Line_2_pair::Bbox_2_Line_2_pair(Bbox_2_Line_2_pair const &o)
{
pimpl = new Bbox_2_Line_2_pair_impl(*o.pimpl);
}
CGAL_INLINE_FUNCTION
Bbox_2_Line_2_pair::Bbox_2_Line_2_pair(
Bbox_2 const &bbox, double line_a, double line_b, double line_c)
{
pimpl = new Bbox_2_Line_2_pair_impl(bbox,
Lcart::Line_2(line_a, line_b, line_c));
}
CGAL_INLINE_FUNCTION
Bbox_2_Line_2_pair &
Bbox_2_Line_2_pair::operator=(Bbox_2_Line_2_pair const &o)
{
*pimpl = *o.pimpl;
return *this;
}
CGAL_INLINE_FUNCTION
Bbox_2_Line_2_pair::Intersection_results
Bbox_2_Line_2_pair::intersection_type() const
{
if (pimpl->_known)
return pimpl->_result;
// The non const this pointer is used to cast away const.
pimpl->_known = true;
const Lcart::Point_2 &ref_point = pimpl->_line.point();
const Lcart::Vector_2 &dir =
pimpl->_line.direction().to_vector();
bool to_infinity = true;
// first on x value
if (dir.x() == 0.0) {
if (ref_point.x() < pimpl->_bbox.xmin()) {
pimpl->_result = NO_INTERSECTION;
return pimpl->_result;
}
if (ref_point.x() > pimpl->_bbox.xmax()) {
pimpl->_result = NO_INTERSECTION;
return pimpl->_result;
}
} else {
double newmin, newmax;
if (dir.x() > 0.0) {
newmin = (pimpl->_bbox.xmin()-ref_point.x())/dir.x();
newmax = (pimpl->_bbox.xmax()-ref_point.x())/dir.x();
} else {
newmin = (pimpl->_bbox.xmax()-ref_point.x())/dir.x();
newmax = (pimpl->_bbox.xmin()-ref_point.x())/dir.x();
}
if (to_infinity) {
pimpl->_min = newmin;
pimpl->_max = newmax;
} else {
if (newmin > pimpl->_min)
pimpl->_min = newmin;
if (newmax < pimpl->_max)
pimpl->_max = newmax;
if (pimpl->_max < pimpl->_min) {
pimpl->_result = NO_INTERSECTION;
return pimpl->_result;
}
}
to_infinity = false;
}
// now on y value
if (dir.y() == 0.0) {
if (ref_point.y() < pimpl->_bbox.ymin()) {
pimpl->_result = NO_INTERSECTION;
return pimpl->_result;
}
if (ref_point.y() > pimpl->_bbox.ymax()) {
pimpl->_result = NO_INTERSECTION;
return pimpl->_result;
}
} else {
double newmin, newmax;
if (dir.y() > 0.0) {
newmin = (pimpl->_bbox.ymin()-ref_point.y())/dir.y();
newmax = (pimpl->_bbox.ymax()-ref_point.y())/dir.y();
} else {
newmin = (pimpl->_bbox.ymax()-ref_point.y())/dir.y();
newmax = (pimpl->_bbox.ymin()-ref_point.y())/dir.y();
}
if (to_infinity) {
pimpl->_min = newmin;
pimpl->_max = newmax;
} else {
if (newmin > pimpl->_min)
pimpl->_min = newmin;
if (newmax < pimpl->_max)
pimpl->_max = newmax;
if (pimpl->_max < pimpl->_min) {
pimpl->_result = NO_INTERSECTION;
return pimpl->_result;
}
}
to_infinity = false;
}
CGAL_kernel_assertion(!to_infinity);
if (pimpl->_max == pimpl->_min) {
pimpl->_result = POINT;
return pimpl->_result;
}
pimpl->_result = SEGMENT;
return pimpl->_result;
}
CGAL_INLINE_FUNCTION
bool
Bbox_2_Line_2_pair::intersection(
double &x1, double &y1, double &x2, double &y2) const
{
if (!pimpl->_known)
intersection_type();
if (pimpl->_result != SEGMENT)
return false;
Lcart::Point_2 p1(pimpl->_line.point()
+ pimpl->_min*pimpl->_line.direction().to_vector());
Lcart::Point_2 p2(pimpl->_line.point()
+ pimpl->_max*pimpl->_line.direction().to_vector());
x1 = p1.x();
y1 = p1.y();
x2 = p2.x();
y2 = p2.y();
return true;
}
CGAL_INLINE_FUNCTION
bool
Bbox_2_Line_2_pair::intersection(
double &x, double &y) const
{
if (!pimpl->_known)
intersection_type();
if (pimpl->_result != POINT)
return false;
Lcart::Point_2 pt(pimpl->_line.point()
+ pimpl->_min*pimpl->_line.direction().to_vector());
x = pt.x();
y = pt.y();
return true;
}
} //namespace CGAL

View File

@ -75,6 +75,8 @@ inline bool do_intersect_ray_2(
}
} //namespace CGAL
#ifdef CGAL_HEADER_ONLY
#include <CGAL/Ray_2_Bbox_2_intersection_impl.h>
#endif // CGAL_HEADER_ONLY
#endif

View File

@ -0,0 +1,208 @@
// Copyright (c) 2000
// Utrecht University (The Netherlands),
// ETH Zurich (Switzerland),
// INRIA Sophia-Antipolis (France),
// Max-Planck-Institute Saarbruecken (Germany),
// and Tel-Aviv University (Israel). All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
//
//
// Author(s) : Geert-Jan Giezeman
#ifdef CGAL_HEADER_ONLY
#define CGAL_INLINE_FUNCTION inline
#else
#define CGAL_INLINE_FUNCTION
#endif
#include <CGAL/Simple_cartesian.h>
typedef CGAL::Simple_cartesian<double> Rcart;
namespace CGAL {
class Bbox_2_Ray_2_pair_impl
{
public:
Bbox_2_Ray_2_pair_impl():_known(false) {}
Bbox_2_Ray_2_pair_impl(Bbox_2 const &bbox, Rcart::Point_2 const &pt,
Rcart::Vector_2 const &dir)
:_box(bbox), _known(false), _ref_point(pt), _dir(dir), _min(0.0) {}
Ray_2< Rcart > _ray;
Bbox_2 _box;
bool _known;
Bbox_2_Ray_2_pair::Intersection_results _result;
Rcart::Point_2 _ref_point;
Rcart::Vector_2 _dir;
double _min, _max;
};
CGAL_INLINE_FUNCTION
Bbox_2_Ray_2_pair::~Bbox_2_Ray_2_pair()
{
delete pimpl;
}
CGAL_INLINE_FUNCTION
Bbox_2_Ray_2_pair::Bbox_2_Ray_2_pair()
{
pimpl = new Bbox_2_Ray_2_pair_impl;
}
CGAL_INLINE_FUNCTION
Bbox_2_Ray_2_pair::Bbox_2_Ray_2_pair(Bbox_2_Ray_2_pair const &o)
{
pimpl = new Bbox_2_Ray_2_pair_impl(*o.pimpl);
}
CGAL_INLINE_FUNCTION
Bbox_2_Ray_2_pair::Bbox_2_Ray_2_pair(
Bbox_2 const &bbox, double x, double y, double dx, double dy)
{
pimpl = new Bbox_2_Ray_2_pair_impl(bbox,
Rcart::Point_2(x,y), Rcart::Vector_2(dx,dy));
}
CGAL_INLINE_FUNCTION
Bbox_2_Ray_2_pair &
Bbox_2_Ray_2_pair::operator=(Bbox_2_Ray_2_pair const &o)
{
*pimpl = *o.pimpl;
return *this;
}
CGAL_INLINE_FUNCTION
Bbox_2_Ray_2_pair::Intersection_results
Bbox_2_Ray_2_pair::intersection_type() const
{
if (pimpl->_known)
return pimpl->_result;
pimpl->_known = true;
bool to_infinity = true;
// first on x value
if (pimpl->_dir.x() == 0.0) {
if (pimpl->_ref_point.x() < pimpl->_box.xmin()) {
pimpl->_result = NO_INTERSECTION;
return pimpl->_result;
}
if (pimpl->_ref_point.x() > pimpl->_box.xmax()) {
pimpl->_result = NO_INTERSECTION;
return pimpl->_result;
}
} else {
double newmin, newmax;
if (pimpl->_dir.x() > 0.0) {
newmin =(pimpl->_box.xmin()-pimpl->_ref_point.x())/pimpl->_dir.x();
newmax =(pimpl->_box.xmax()-pimpl->_ref_point.x())/pimpl->_dir.x();
} else {
newmin =(pimpl->_box.xmax()-pimpl->_ref_point.x())/pimpl->_dir.x();
newmax =(pimpl->_box.xmin()-pimpl->_ref_point.x())/pimpl->_dir.x();
}
if (newmin > pimpl->_min)
pimpl->_min = newmin;
if (to_infinity) {
pimpl->_max = newmax;
} else {
if (newmax < pimpl->_max)
pimpl->_max = newmax;
}
if (pimpl->_max < pimpl->_min){
pimpl->_result = NO_INTERSECTION;
return pimpl->_result;
}
to_infinity = false;
}
// now on y value
if (pimpl->_dir.y() == 0.0) {
if (pimpl->_ref_point.y() < pimpl->_box.ymin()) {
pimpl->_result = NO_INTERSECTION;
return pimpl->_result;
}
if (pimpl->_ref_point.y() > pimpl->_box.ymax()) {
pimpl->_result = NO_INTERSECTION;
return pimpl->_result;
}
} else {
double newmin, newmax;
if (pimpl->_dir.y() > 0.0) {
newmin =(pimpl->_box.ymin()-pimpl->_ref_point.y())/pimpl->_dir.y();
newmax =(pimpl->_box.ymax()-pimpl->_ref_point.y())/pimpl->_dir.y();
} else {
newmin =(pimpl->_box.ymax()-pimpl->_ref_point.y())/pimpl->_dir.y();
newmax =(pimpl->_box.ymin()-pimpl->_ref_point.y())/pimpl->_dir.y();
}
if (newmin > pimpl->_min)
pimpl->_min = newmin;
if (to_infinity) {
pimpl->_max = newmax;
} else {
if (newmax < pimpl->_max)
pimpl->_max = newmax;
}
if (pimpl->_max < pimpl->_min) {
pimpl->_result = NO_INTERSECTION;
return pimpl->_result;
}
to_infinity = false;
}
CGAL_kernel_assertion(!to_infinity);
if (pimpl->_max == pimpl->_min) {
pimpl->_result = POINT;
return pimpl->_result;
}
pimpl->_result = SEGMENT;
return pimpl->_result;
}
CGAL_INLINE_FUNCTION
bool Bbox_2_Ray_2_pair::
intersection(double &x1, double &y1, double &x2, double &y2) const
{
if (!pimpl->_known)
intersection_type();
if (pimpl->_result != SEGMENT)
return false;
Rcart::Point_2 p1(pimpl->_ref_point + pimpl->_min*pimpl->_dir);
Rcart::Point_2 p2(pimpl->_ref_point + pimpl->_max*pimpl->_dir);
x1 = p1.x();
y1 = p1.y();
x2 = p2.x();
y2 = p2.y();
return true;
}
CGAL_INLINE_FUNCTION
bool Bbox_2_Ray_2_pair::intersection(double &x, double &y) const
{
if (!pimpl->_known)
intersection_type();
if (pimpl->_result != POINT)
return false;
Rcart::Point_2 pt = pimpl->_ref_point + pimpl->_min*pimpl->_dir;
x = pt.x();
y = pt.y();
return true;
}
CGAL_INLINE_FUNCTION
bool do_intersect_ray_2(
const Bbox_2 &box, double x, double y, double dx, double dy)
{
Bbox_2_Ray_2_pair pair(box, x, y, dx, dy);
return pair.intersection_type() != Bbox_2_Ray_2_pair::NO_INTERSECTION;
}
} //namespace CGAL

View File

@ -22,346 +22,12 @@
//
// Author(s) : Geert-Jan Giezeman
#ifndef CGAL_HEADER_ONLY
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Bbox_2_Line_2_intersection.h>
#include <CGAL/Bbox_2_Line_2_intersection_impl.h>
#include <CGAL/Ray_2_Bbox_2_intersection.h>
typedef CGAL::Simple_cartesian<double> Rcart;
#include <CGAL/Ray_2_Bbox_2_intersection_impl.h>
namespace CGAL {
class Bbox_2_Line_2_pair_impl
{
public:
Bbox_2_Line_2_pair_impl() {}
Bbox_2_Line_2_pair_impl(Bbox_2 const &bb, Rcart::Line_2 const &line)
: _bbox(bb), _line(line), _known(false) {}
Bbox_2 _bbox;
Rcart::Line_2 _line;
mutable bool _known;
mutable Bbox_2_Line_2_pair::Intersection_results _result;
mutable double _min, _max;
};
Bbox_2_Line_2_pair::~Bbox_2_Line_2_pair()
{
delete pimpl;
}
Bbox_2_Line_2_pair::Bbox_2_Line_2_pair()
{
pimpl = new Bbox_2_Line_2_pair_impl;
pimpl->_known = false;
}
Bbox_2_Line_2_pair::Bbox_2_Line_2_pair(Bbox_2_Line_2_pair const &o)
{
pimpl = new Bbox_2_Line_2_pair_impl(*o.pimpl);
}
Bbox_2_Line_2_pair::Bbox_2_Line_2_pair(
Bbox_2 const &bbox, double line_a, double line_b, double line_c)
{
pimpl = new Bbox_2_Line_2_pair_impl(bbox,
Rcart::Line_2(line_a, line_b, line_c));
}
Bbox_2_Line_2_pair &
Bbox_2_Line_2_pair::operator=(Bbox_2_Line_2_pair const &o)
{
*pimpl = *o.pimpl;
return *this;
}
Bbox_2_Line_2_pair::Intersection_results
Bbox_2_Line_2_pair::intersection_type() const
{
if (pimpl->_known)
return pimpl->_result;
// The non const this pointer is used to cast away const.
pimpl->_known = true;
const Rcart::Point_2 &ref_point = pimpl->_line.point();
const Rcart::Vector_2 &dir =
pimpl->_line.direction().to_vector();
bool to_infinity = true;
// first on x value
if (dir.x() == 0.0) {
if (ref_point.x() < pimpl->_bbox.xmin()) {
pimpl->_result = NO_INTERSECTION;
return pimpl->_result;
}
if (ref_point.x() > pimpl->_bbox.xmax()) {
pimpl->_result = NO_INTERSECTION;
return pimpl->_result;
}
} else {
double newmin, newmax;
if (dir.x() > 0.0) {
newmin = (pimpl->_bbox.xmin()-ref_point.x())/dir.x();
newmax = (pimpl->_bbox.xmax()-ref_point.x())/dir.x();
} else {
newmin = (pimpl->_bbox.xmax()-ref_point.x())/dir.x();
newmax = (pimpl->_bbox.xmin()-ref_point.x())/dir.x();
}
if (to_infinity) {
pimpl->_min = newmin;
pimpl->_max = newmax;
} else {
if (newmin > pimpl->_min)
pimpl->_min = newmin;
if (newmax < pimpl->_max)
pimpl->_max = newmax;
if (pimpl->_max < pimpl->_min) {
pimpl->_result = NO_INTERSECTION;
return pimpl->_result;
}
}
to_infinity = false;
}
// now on y value
if (dir.y() == 0.0) {
if (ref_point.y() < pimpl->_bbox.ymin()) {
pimpl->_result = NO_INTERSECTION;
return pimpl->_result;
}
if (ref_point.y() > pimpl->_bbox.ymax()) {
pimpl->_result = NO_INTERSECTION;
return pimpl->_result;
}
} else {
double newmin, newmax;
if (dir.y() > 0.0) {
newmin = (pimpl->_bbox.ymin()-ref_point.y())/dir.y();
newmax = (pimpl->_bbox.ymax()-ref_point.y())/dir.y();
} else {
newmin = (pimpl->_bbox.ymax()-ref_point.y())/dir.y();
newmax = (pimpl->_bbox.ymin()-ref_point.y())/dir.y();
}
if (to_infinity) {
pimpl->_min = newmin;
pimpl->_max = newmax;
} else {
if (newmin > pimpl->_min)
pimpl->_min = newmin;
if (newmax < pimpl->_max)
pimpl->_max = newmax;
if (pimpl->_max < pimpl->_min) {
pimpl->_result = NO_INTERSECTION;
return pimpl->_result;
}
}
to_infinity = false;
}
CGAL_kernel_assertion(!to_infinity);
if (pimpl->_max == pimpl->_min) {
pimpl->_result = POINT;
return pimpl->_result;
}
pimpl->_result = SEGMENT;
return pimpl->_result;
}
bool
Bbox_2_Line_2_pair::intersection(
double &x1, double &y1, double &x2, double &y2) const
{
if (!pimpl->_known)
intersection_type();
if (pimpl->_result != SEGMENT)
return false;
Rcart::Point_2 p1(pimpl->_line.point()
+ pimpl->_min*pimpl->_line.direction().to_vector());
Rcart::Point_2 p2(pimpl->_line.point()
+ pimpl->_max*pimpl->_line.direction().to_vector());
x1 = p1.x();
y1 = p1.y();
x2 = p2.x();
y2 = p2.y();
return true;
}
bool
Bbox_2_Line_2_pair::intersection(
double &x, double &y) const
{
if (!pimpl->_known)
intersection_type();
if (pimpl->_result != POINT)
return false;
Rcart::Point_2 pt(pimpl->_line.point()
+ pimpl->_min*pimpl->_line.direction().to_vector());
x = pt.x();
y = pt.y();
return true;
}
class Bbox_2_Ray_2_pair_impl
{
public:
Bbox_2_Ray_2_pair_impl():_known(false) {}
Bbox_2_Ray_2_pair_impl(Bbox_2 const &bbox, Rcart::Point_2 const &pt,
Rcart::Vector_2 const &dir)
:_box(bbox), _known(false), _ref_point(pt), _dir(dir), _min(0.0) {}
Ray_2< Rcart > _ray;
Bbox_2 _box;
bool _known;
Bbox_2_Ray_2_pair::Intersection_results _result;
Rcart::Point_2 _ref_point;
Rcart::Vector_2 _dir;
double _min, _max;
};
Bbox_2_Ray_2_pair::~Bbox_2_Ray_2_pair()
{
delete pimpl;
}
Bbox_2_Ray_2_pair::Bbox_2_Ray_2_pair()
{
pimpl = new Bbox_2_Ray_2_pair_impl;
}
Bbox_2_Ray_2_pair::Bbox_2_Ray_2_pair(Bbox_2_Ray_2_pair const &o)
{
pimpl = new Bbox_2_Ray_2_pair_impl(*o.pimpl);
}
Bbox_2_Ray_2_pair::Bbox_2_Ray_2_pair(
Bbox_2 const &bbox, double x, double y, double dx, double dy)
{
pimpl = new Bbox_2_Ray_2_pair_impl(bbox,
Rcart::Point_2(x,y), Rcart::Vector_2(dx,dy));
}
Bbox_2_Ray_2_pair &
Bbox_2_Ray_2_pair::operator=(Bbox_2_Ray_2_pair const &o)
{
*pimpl = *o.pimpl;
return *this;
}
Bbox_2_Ray_2_pair::Intersection_results
Bbox_2_Ray_2_pair::intersection_type() const
{
if (pimpl->_known)
return pimpl->_result;
pimpl->_known = true;
bool to_infinity = true;
// first on x value
if (pimpl->_dir.x() == 0.0) {
if (pimpl->_ref_point.x() < pimpl->_box.xmin()) {
pimpl->_result = NO_INTERSECTION;
return pimpl->_result;
}
if (pimpl->_ref_point.x() > pimpl->_box.xmax()) {
pimpl->_result = NO_INTERSECTION;
return pimpl->_result;
}
} else {
double newmin, newmax;
if (pimpl->_dir.x() > 0.0) {
newmin =(pimpl->_box.xmin()-pimpl->_ref_point.x())/pimpl->_dir.x();
newmax =(pimpl->_box.xmax()-pimpl->_ref_point.x())/pimpl->_dir.x();
} else {
newmin =(pimpl->_box.xmax()-pimpl->_ref_point.x())/pimpl->_dir.x();
newmax =(pimpl->_box.xmin()-pimpl->_ref_point.x())/pimpl->_dir.x();
}
if (newmin > pimpl->_min)
pimpl->_min = newmin;
if (to_infinity) {
pimpl->_max = newmax;
} else {
if (newmax < pimpl->_max)
pimpl->_max = newmax;
}
if (pimpl->_max < pimpl->_min){
pimpl->_result = NO_INTERSECTION;
return pimpl->_result;
}
to_infinity = false;
}
// now on y value
if (pimpl->_dir.y() == 0.0) {
if (pimpl->_ref_point.y() < pimpl->_box.ymin()) {
pimpl->_result = NO_INTERSECTION;
return pimpl->_result;
}
if (pimpl->_ref_point.y() > pimpl->_box.ymax()) {
pimpl->_result = NO_INTERSECTION;
return pimpl->_result;
}
} else {
double newmin, newmax;
if (pimpl->_dir.y() > 0.0) {
newmin =(pimpl->_box.ymin()-pimpl->_ref_point.y())/pimpl->_dir.y();
newmax =(pimpl->_box.ymax()-pimpl->_ref_point.y())/pimpl->_dir.y();
} else {
newmin =(pimpl->_box.ymax()-pimpl->_ref_point.y())/pimpl->_dir.y();
newmax =(pimpl->_box.ymin()-pimpl->_ref_point.y())/pimpl->_dir.y();
}
if (newmin > pimpl->_min)
pimpl->_min = newmin;
if (to_infinity) {
pimpl->_max = newmax;
} else {
if (newmax < pimpl->_max)
pimpl->_max = newmax;
}
if (pimpl->_max < pimpl->_min) {
pimpl->_result = NO_INTERSECTION;
return pimpl->_result;
}
to_infinity = false;
}
CGAL_kernel_assertion(!to_infinity);
if (pimpl->_max == pimpl->_min) {
pimpl->_result = POINT;
return pimpl->_result;
}
pimpl->_result = SEGMENT;
return pimpl->_result;
}
bool Bbox_2_Ray_2_pair::
intersection(double &x1, double &y1, double &x2, double &y2) const
{
if (!pimpl->_known)
intersection_type();
if (pimpl->_result != SEGMENT)
return false;
Rcart::Point_2 p1(pimpl->_ref_point + pimpl->_min*pimpl->_dir);
Rcart::Point_2 p2(pimpl->_ref_point + pimpl->_max*pimpl->_dir);
x1 = p1.x();
y1 = p1.y();
x2 = p2.x();
y2 = p2.y();
return true;
}
bool Bbox_2_Ray_2_pair::intersection(double &x, double &y) const
{
if (!pimpl->_known)
intersection_type();
if (pimpl->_result != POINT)
return false;
Rcart::Point_2 pt = pimpl->_ref_point + pimpl->_min*pimpl->_dir;
x = pt.x();
y = pt.y();
return true;
}
bool do_intersect_ray_2(
const Bbox_2 &box, double x, double y, double dx, double dy)
{
Bbox_2_Ray_2_pair pair(box, x, y, dx, dy);
return pair.intersection_type() != Bbox_2_Ray_2_pair::NO_INTERSECTION;
}
} //namespace CGAL
#endif // CGAL_HEADER_ONLY

View File

@ -166,7 +166,7 @@ inline
std::ostream&
operator<<(std::ostream &os, const Bbox_2 &b)
{
switch(os.iword(IO::mode)) {
switch(get_mode(os)) {
case IO::ASCII :
os << b.xmin() << ' ' << b.ymin() << ' '
<< b.xmax() << ' ' << b.ymax();
@ -191,7 +191,7 @@ operator>>(std::istream &is, Bbox_2 &b)
{
double xmin, ymin, xmax, ymax;
switch(is.iword(IO::mode)) {
switch(get_mode(is)) {
case IO::ASCII :
is >> iformat(xmin) >> iformat(ymin) >> iformat(xmax) >> iformat(ymax);
break;

View File

@ -184,7 +184,7 @@ inline
std::ostream&
operator<<(std::ostream &os, const Bbox_3& b)
{
switch(os.iword(IO::mode))
switch(get_mode(os))
{
case IO::ASCII :
return os << b.xmin() << ' ' << b.ymin() << ' ' << b.zmin()
@ -214,7 +214,7 @@ operator>>(std::istream &is, Bbox_3& b)
{
double xmin, ymin, zmin, xmax, ymax, zmax;
switch(is.iword(IO::mode))
switch(get_mode(is))
{
case IO::ASCII :
is >> iformat(xmin) >> iformat(ymin) >> iformat(zmin)

View File

@ -228,7 +228,7 @@ template <class R >
std::ostream&
insert(std::ostream& os, const Circle_2<R>& c)
{
switch(os.iword(IO::mode)) {
switch(get_mode(os)) {
case IO::ASCII :
os << c.center() << ' ' << c.squared_radius() << ' '
<< static_cast<int>(c.orientation());
@ -271,7 +271,7 @@ extract(std::istream& is, Circle_2<R>& c)
typename R::Point_2 center;
typename R::FT squared_radius;
int o;
switch(is.iword(IO::mode)) {
switch(get_mode(is)) {
case IO::ASCII :
is >> center >> iformat(squared_radius) >> o;
break;

View File

@ -186,7 +186,7 @@ std::ostream&
insert(std::ostream& os, const Direction_2<R>& d, const Cartesian_tag&)
{
typename R::Vector_2 v = d.to_vector();
switch(os.iword(IO::mode)) {
switch(get_mode(os)) {
case IO::ASCII :
return os << v.x() << ' ' << v.y();
case IO::BINARY :
@ -202,7 +202,7 @@ template <class R >
std::ostream&
insert(std::ostream& os, const Direction_2<R>& d, const Homogeneous_tag&)
{
switch(os.iword(IO::mode))
switch(get_mode(os))
{
case IO::ASCII :
return os << d.dx() << ' ' << d.dy();
@ -229,7 +229,7 @@ std::istream&
extract(std::istream& is, Direction_2<R>& d, const Cartesian_tag&)
{
typename R::FT x, y;
switch(is.iword(IO::mode)) {
switch(get_mode(is)) {
case IO::ASCII :
is >> iformat(x) >> iformat(y);
break;
@ -252,7 +252,7 @@ std::istream&
extract(std::istream& is, Direction_2<R>& d, const Homogeneous_tag&)
{
typename R::RT x, y;
switch(is.iword(IO::mode))
switch(get_mode(is))
{
case IO::ASCII :
is >> iformat(x) >> iformat(y);

View File

@ -139,7 +139,7 @@ std::ostream&
insert(std::ostream& os, const Direction_3<R>& d, const Cartesian_tag&)
{
typename R::Vector_3 v = d.to_vector();
switch(os.iword(IO::mode)) {
switch(get_mode(os)) {
case IO::ASCII :
return os << v.x() << ' ' << v.y() << ' ' << v.z();
case IO::BINARY :
@ -157,7 +157,7 @@ template <class R >
std::ostream&
insert(std::ostream& os, const Direction_3<R>& d, const Homogeneous_tag&)
{
switch(os.iword(IO::mode))
switch(get_mode(os))
{
case IO::ASCII :
return os << d.dx() << ' ' << d.dy() << ' ' << d.dz();
@ -186,7 +186,7 @@ std::istream&
extract(std::istream& is, Direction_3<R>& d, const Cartesian_tag&)
{
typename R::FT x, y, z;
switch(is.iword(IO::mode)) {
switch(get_mode(is)) {
case IO::ASCII :
is >> iformat(x) >> iformat(y) >> iformat(z);
break;
@ -210,7 +210,7 @@ std::istream&
extract(std::istream& is, Direction_3<R>& d, const Homogeneous_tag&)
{
typename R::RT x, y, z;
switch(is.iword(IO::mode))
switch(get_mode(is))
{
case IO::ASCII :
is >> iformat(x) >> iformat(y) >> iformat(z);

View File

@ -239,7 +239,7 @@ template < class R >
std::ostream &
operator<<(std::ostream& os, const Iso_cuboid_3<R>& r)
{
switch(os.iword(IO::mode)) {
switch(get_mode(os)) {
case IO::ASCII :
return os << (r.min)() << ' ' << (r.max)();
case IO::BINARY :

View File

@ -230,7 +230,7 @@ template < class R >
std::ostream &
operator<<(std::ostream &os, const Iso_rectangle_2<R> &r)
{
switch(os.iword(IO::mode)) {
switch(get_mode(os)) {
case IO::ASCII :
return os << (r.min)() << ' ' << (r.max)();
case IO::BINARY :

View File

@ -233,7 +233,7 @@ template <class R >
std::ostream&
insert(std::ostream& os, const Line_2<R>& l)
{
switch(os.iword(IO::mode)) {
switch(get_mode(os)) {
case IO::ASCII :
return os << l.a() << ' ' << l.b() << ' ' << l.c();
case IO::BINARY :
@ -260,7 +260,7 @@ std::istream&
extract(std::istream& is, Line_2<R>& l)
{
typename R::RT a, b, c;
switch(is.iword(IO::mode)) {
switch(get_mode(is)) {
case IO::ASCII :
is >> iformat(a) >> iformat(b) >> iformat(c);
break;

View File

@ -145,7 +145,7 @@ template < class R >
std::ostream &
operator<<(std::ostream &os, const Line_3<R> &l)
{
switch(os.iword(IO::mode)) {
switch(get_mode(os)) {
case IO::ASCII :
return os << l.point(0) << ' ' << l.point(1);
case IO::BINARY :

View File

@ -33,13 +33,20 @@ namespace CGAL {
class Origin
{};
CGAL_EXPORT extern const Origin ORIGIN;
class Null_vector
{};
#ifndef CGAL_HEADER_ONLY
CGAL_EXPORT extern const Origin ORIGIN;
CGAL_EXPORT extern const Null_vector NULL_VECTOR;
#endif
} //namespace CGAL
#ifdef CGAL_HEADER_ONLY
#include <CGAL/Origin_impl.h>
#endif // CGAL_HEADER_ONLY
#endif // CGAL_ORIGIN_H

View File

@ -0,0 +1,30 @@
// Copyright (c) 1999
// Utrecht University (The Netherlands),
// ETH Zurich (Switzerland),
// INRIA Sophia-Antipolis (France),
// Max-Planck-Institute Saarbruecken (Germany),
// and Tel-Aviv University (Israel). All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
//
//
// Author(s) : Andreas Fabri, Stefan Schirra
namespace CGAL {
const Origin ORIGIN = Origin();
const Null_vector NULL_VECTOR = Null_vector();
} //namespace CGAL

View File

@ -235,7 +235,7 @@ template < class R >
std::ostream &
operator<<(std::ostream &os, const Plane_3<R> &p)
{
switch(os.iword(IO::mode)) {
switch(get_mode(os)) {
case IO::ASCII :
return os << p.a() << ' ' << p.b() << ' ' << p.c() << ' ' << p.d();
case IO::BINARY :
@ -256,7 +256,7 @@ std::istream &
operator>>(std::istream &is, Plane_3<R> &p)
{
typename R::RT a, b, c, d;
switch(is.iword(IO::mode)) {
switch(get_mode(is)) {
case IO::ASCII :
is >> iformat(a) >> iformat(b) >> iformat(c) >> iformat(d);
break;

View File

@ -169,7 +169,7 @@ template <class R >
std::ostream&
insert(std::ostream& os, const Point_2<R>& p,const Cartesian_tag&)
{
switch(os.iword(IO::mode)) {
switch(get_mode(os)) {
case IO::ASCII :
return os << p.x() << ' ' << p.y();
case IO::BINARY :
@ -185,7 +185,7 @@ template <class R >
std::ostream&
insert(std::ostream& os, const Point_2<R>& p,const Homogeneous_tag&)
{
switch(os.iword(IO::mode))
switch(get_mode(os))
{
case IO::ASCII :
return os << p.hx() << ' ' << p.hy() << ' ' << p.hw();
@ -214,7 +214,7 @@ std::istream&
extract(std::istream& is, Point_2<R>& p, const Cartesian_tag&)
{
typename R::FT x, y;
switch(is.iword(IO::mode)) {
switch(get_mode(is)) {
case IO::ASCII :
is >> iformat(x) >> iformat(y);
break;
@ -238,7 +238,7 @@ std::istream&
extract(std::istream& is, Point_2<R>& p, const Homogeneous_tag&)
{
typename R::RT hx, hy, hw;
switch(is.iword(IO::mode))
switch(get_mode(is))
{
case IO::ASCII :
is >> hx >> hy >> hw;

View File

@ -195,7 +195,7 @@ template <class R >
std::ostream&
insert(std::ostream& os, const Point_3<R>& p,const Cartesian_tag&)
{
switch(os.iword(IO::mode)) {
switch(get_mode(os)) {
case IO::ASCII :
return os << p.x() << ' ' << p.y() << ' ' << p.z();
case IO::BINARY :
@ -213,7 +213,7 @@ template <class R >
std::ostream&
insert(std::ostream& os, const Point_3<R>& p,const Homogeneous_tag&)
{
switch(os.iword(IO::mode))
switch(get_mode(os))
{
case IO::ASCII :
return os << p.hx() << ' ' << p.hy() << ' ' << p.hz() << ' ' << p.hw();
@ -244,7 +244,7 @@ std::istream&
extract(std::istream& is, Point_3<R>& p, const Cartesian_tag&)
{
typename R::FT x, y, z;
switch(is.iword(IO::mode)) {
switch(get_mode(is)) {
case IO::ASCII :
is >> iformat(x) >> iformat(y) >> iformat(z);
break;
@ -269,7 +269,7 @@ std::istream&
extract(std::istream& is, Point_3<R>& p, const Homogeneous_tag&)
{
typename R::RT hx, hy, hz, hw;
switch(is.iword(IO::mode))
switch(get_mode(is))
{
case IO::ASCII :
is >> hx >> hy >> hz >> hw;

View File

@ -207,7 +207,7 @@ template <class R >
std::ostream&
insert(std::ostream& os, const Ray_2<R>& r, const Cartesian_tag&)
{
switch(os.iword(IO::mode)) {
switch(get_mode(os)) {
case IO::ASCII :
return os << r.source() << ' ' << r.second_point();
case IO::BINARY :
@ -221,7 +221,7 @@ template <class R >
std::ostream&
insert(std::ostream& os, const Ray_2<R>& r, const Homogeneous_tag&)
{
switch(os.iword(IO::mode))
switch(get_mode(os))
{
case IO::ASCII :
return os << r.source() << ' ' << r.second_point();

View File

@ -173,7 +173,7 @@ template <class R >
std::ostream&
insert(std::ostream& os, const Ray_3<R>& r, const Cartesian_tag&)
{
switch(os.iword(IO::mode)) {
switch(get_mode(os)) {
case IO::ASCII :
return os << r.start() << ' ' << r.direction();
case IO::BINARY :
@ -187,7 +187,7 @@ template <class R >
std::ostream&
insert(std::ostream& os, const Ray_3<R>& r, const Homogeneous_tag&)
{
switch(os.iword(IO::mode))
switch(get_mode(os))
{
case IO::ASCII :
return os << r.start() << ' ' << r.direction();

View File

@ -282,7 +282,7 @@ template < class R >
std::ostream &
operator<<(std::ostream &os, const Segment_2<R> &s)
{
switch(os.iword(IO::mode)) {
switch(get_mode(os)) {
case IO::ASCII :
return os << s.source() << ' ' << s.target();
case IO::BINARY :

View File

@ -198,7 +198,7 @@ template < class R >
std::ostream &
operator<<(std::ostream &os, const Segment_3<R> &s)
{
switch(os.iword(IO::mode)) {
switch(get_mode(os)) {
case IO::ASCII :
return os << s.source() << ' ' << s.target();
case IO::BINARY :

View File

@ -216,7 +216,7 @@ template <class R >
std::ostream&
insert(std::ostream& os, const Sphere_3<R>& c,const Cartesian_tag&)
{
switch(os.iword(IO::mode)) {
switch(get_mode(os)) {
case IO::ASCII :
os << c.center() << ' ' << c.squared_radius() << ' '
<< static_cast<int>(c.orientation());
@ -248,7 +248,7 @@ template <class R >
std::ostream&
insert(std::ostream& os, const Sphere_3<R>& c, const Homogeneous_tag&)
{
switch(os.iword(IO::mode)) {
switch(get_mode(os)) {
case IO::ASCII :
os << c.center() << ' ' << c.squared_radius() << ' '
<< static_cast<int>(c.orientation());
@ -291,7 +291,7 @@ extract(std::istream& is, Sphere_3<R>& c, const Cartesian_tag&)
typename R::Point_3 center;
typename R::FT squared_radius;
int o=0;
switch(is.iword(IO::mode)) {
switch(get_mode(is)) {
case IO::ASCII :
is >> center >> squared_radius >> o;
break;
@ -318,7 +318,7 @@ extract(std::istream& is, Sphere_3<R>& c, const Homogeneous_tag&)
typename R::Point_3 center;
typename R::FT squared_radius;
int o;
switch(is.iword(IO::mode)) {
switch(get_mode(is)) {
case IO::ASCII :
is >> center >> squared_radius >> o;
break;

View File

@ -155,7 +155,7 @@ template < class R >
std::ostream &
operator<<(std::ostream &os, const Tetrahedron_3<R> &t)
{
switch(os.iword(IO::mode)) {
switch(get_mode(os)) {
case IO::ASCII :
return os << t[0] << ' ' << t[1] << ' ' << t[2] << ' ' << t[3];
case IO::BINARY :

View File

@ -182,7 +182,7 @@ template < class R >
std::ostream &
operator<<(std::ostream &os, const Triangle_2<R> &t)
{
switch(os.iword(IO::mode)) {
switch(get_mode(os)) {
case IO::ASCII :
return os << t[0] << ' ' << t[1] << ' ' << t[2];
case IO::BINARY :

View File

@ -125,7 +125,7 @@ template < class R >
std::ostream &
operator<<(std::ostream &os, const Triangle_3<R> &t)
{
switch(os.iword(IO::mode)) {
switch(get_mode(os)) {
case IO::ASCII :
return os << t[0] << ' ' << t[1] << ' ' << t[2];
case IO::BINARY :

View File

@ -251,7 +251,7 @@ template <class R >
std::ostream&
insert(std::ostream& os, const Vector_2<R>& v, const Cartesian_tag&)
{
switch(os.iword(IO::mode)) {
switch(get_mode(os)) {
case IO::ASCII :
return os << v.x() << ' ' << v.y();
case IO::BINARY :
@ -267,7 +267,7 @@ template <class R >
std::ostream&
insert(std::ostream& os, const Vector_2<R>& v, const Homogeneous_tag&)
{
switch(os.iword(IO::mode))
switch(get_mode(os))
{
case IO::ASCII :
return os << v.hx() << ' ' << v.hy() << ' ' << v.hw();
@ -297,7 +297,7 @@ std::istream&
extract(std::istream& is, Vector_2<R>& v, const Cartesian_tag&)
{
typename R::FT x, y;
switch(is.iword(IO::mode)) {
switch(get_mode(is)) {
case IO::ASCII :
is >> iformat(x) >> iformat(y);
break;
@ -321,7 +321,7 @@ std::istream&
extract(std::istream& is, Vector_2<R>& v, const Homogeneous_tag&)
{
typename R::RT hx, hy, hw;
switch(is.iword(IO::mode))
switch(get_mode(is))
{
case IO::ASCII :
is >> hx >> hy >> hw;

View File

@ -228,7 +228,7 @@ template <class R >
std::ostream&
insert(std::ostream& os, const Vector_3<R>& v, const Cartesian_tag&)
{
switch(os.iword(IO::mode)) {
switch(get_mode(os)) {
case IO::ASCII :
return os << v.x() << ' ' << v.y() << ' ' << v.z();
case IO::BINARY :
@ -246,7 +246,7 @@ template <class R >
std::ostream&
insert(std::ostream& os, const Vector_3<R>& v, const Homogeneous_tag&)
{
switch(os.iword(IO::mode))
switch(get_mode(os))
{
case IO::ASCII :
return os << v.hx() << ' ' << v.hy() << ' ' << v.hz() << ' ' << v.hw();
@ -277,7 +277,7 @@ std::istream&
extract(std::istream& is, Vector_3<R>& v, const Cartesian_tag&)
{
typename R::FT x, y, z;
switch(is.iword(IO::mode)) {
switch(get_mode(is)) {
case IO::ASCII :
is >> iformat(x) >> iformat(y) >> iformat(z);
break;
@ -301,7 +301,7 @@ std::istream&
extract(std::istream& is, Vector_3<R>& v, const Homogeneous_tag&)
{
typename R::RT hx, hy, hz, hw;
switch(is.iword(IO::mode))
switch(get_mode(is))
{
case IO::ASCII :
is >> hx >> hy >> hz >> hw;

View File

@ -36,12 +36,19 @@ class Scaling {};
class Reflection {};
class Identity_transformation {};
CGAL_EXPORT extern const Translation TRANSLATION;
CGAL_EXPORT extern const Rotation ROTATION;
CGAL_EXPORT extern const Scaling SCALING;
CGAL_EXPORT extern const Reflection REFLECTION;
CGAL_EXPORT extern const Identity_transformation IDENTITY;
#ifndef CGAL_HEADER_ONLY
CGAL_EXPORT extern const Translation TRANSLATION;
CGAL_EXPORT extern const Rotation ROTATION;
CGAL_EXPORT extern const Scaling SCALING;
CGAL_EXPORT extern const Reflection REFLECTION;
CGAL_EXPORT extern const Identity_transformation IDENTITY;
#endif
} //namespace CGAL
#ifdef CGAL_HEADER_ONLY
#include <CGAL/aff_transformation_tags_impl.h>
#endif // CGAL_HEADER_ONLY
#endif // CGAL_AFF_TRANSFORMATION_TAGS_H

View File

@ -0,0 +1,33 @@
// Copyright (c) 1999
// Utrecht University (The Netherlands),
// ETH Zurich (Switzerland),
// INRIA Sophia-Antipolis (France),
// Max-Planck-Institute Saarbruecken (Germany),
// and Tel-Aviv University (Israel). All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
//
//
// Author(s) : Andreas Fabri, Stefan Schirra
namespace CGAL {
const Translation TRANSLATION = Translation();
const Rotation ROTATION = Rotation();
const Scaling SCALING = Scaling();
const Reflection REFLECTION = Reflection();
const Identity_transformation IDENTITY = Identity_transformation();
} //namespace CGAL

Some files were not shown because too many files have changed in this diff Show More