Merge remote-tracking branch 'cgal/master' into gsoc2023-aos_sphere_demo-denizdiktas

This commit is contained in:
Efi Fogel 2024-04-15 19:11:21 +03:00
commit 89bfe4ba91
537 changed files with 17761 additions and 12800 deletions

View File

@ -12,15 +12,15 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: REUSE version
uses: fsfe/reuse-action@v2
uses: fsfe/reuse-action@v3
with:
args: --version
- name: REUSE lint
uses: fsfe/reuse-action@v2
uses: fsfe/reuse-action@v3
with:
args: --include-submodules lint
- name: REUSE SPDX SBOM
uses: fsfe/reuse-action@v2
uses: fsfe/reuse-action@v3
with:
args: spdx
- name: install dependencies
@ -30,6 +30,6 @@ jobs:
mkdir -p ./release
cmake -DDESTINATION=./release -DCGAL_VERSION=9.9 -P ./Scripts/developer_scripts/cgal_create_release_with_cmake.cmake
- name: REUSE lint release tarball
uses: fsfe/reuse-action@v2
uses: fsfe/reuse-action@v3
with:
args: --root ./release/CGAL-9.9 --include-submodules lint

View File

@ -2,6 +2,7 @@ Advancing_front_surface_reconstruction
Algebraic_foundations
Arithmetic_kernel
BGL
CGAL_Core
Cartesian_kernel
Circulator
Distance_2
@ -22,7 +23,6 @@ Number_types
Polyhedron
Profiling_tools
Property_map
Random_numbers
STL_Extension
Spatial_sorting
Stream_support

View File

@ -53,7 +53,7 @@ struct Rational_traits_base<Rational, true>
{
private:
typedef Fraction_traits<Rational> FT;
typedef typename FT::Decompose Decomose;
typedef typename FT::Decompose Decompose;
typedef typename FT::Compose Compose;
public:
@ -61,13 +61,13 @@ public:
RT numerator (const Rational& r) const {
RT num,den;
Decomose()(r,num,den);
Decompose()(r,num,den);
return num;
}
RT denominator (const Rational& r) const {
RT num,den;
Decomose()(r,num,den);
Decompose()(r,num,den);
return den;
}

View File

@ -303,7 +303,7 @@ public:
Integer alpha_num = Integer(1), int log_denom = 1
) : alpha_num_(alpha_num),
beta_num_((Integer(1) << log_denom) - alpha_num),
half_((log_denom > 0) ? (Integer(1) << log_denom-1) : 0),
half_((log_denom > 0) ? Integer(Integer(1) << log_denom-1) : 0),
log_denom_(log_denom)
{
CGAL_precondition(log_denom_ >= 0);

View File

@ -206,7 +206,7 @@ polynomial_power_to_bernstein_approx(
std::vector<Integer> f(n+1);
polynomial_affine_transform_approx_log_denom(
first, beyond, f.begin(),
upper_num - lower_num, lower_num, log_denom,
Integer(upper_num - lower_num), lower_num, log_denom,
p+q,
approx, log, logl
);

View File

@ -27,31 +27,10 @@
#include <vector>
#if CGAL_USE_CORE
namespace CORE { class BigInt; }
#endif
namespace CGAL {
namespace internal {
#if CGAL_USE_CORE
// bugfix for CORE by Michael Kerber
// why is there a specialized function for CORE?
inline CORE::BigInt shift_integer_by(CORE::BigInt x, long shift){
if( shift > 0 ){
while(shift>63) {
x = (x >> 63);
shift-=63;
}
x = (x >> shift);
}else{
// add 0 bits
x = (x << -shift);
}
return x;
}
#endif
template <class Shiftable>
Shiftable shift_integer_by(Shiftable x, long shift){

View File

@ -68,9 +68,9 @@ private:
Polynomial poly_;
int number_of_real_roots_;
IT* numerator;
IT* denominator_exponent;
bool* is_exact;
std::vector<IT> numerator;
std::vector<IT> denominator_exponent;
std::vector<bool> is_exact;
IT LEFT,SCALE,DENOM;
bool is_strong_;
int k;
@ -91,9 +91,9 @@ public:
k(kk),
interval_given(false) {
numerator = new IT[CGAL::degree(P)];
denominator_exponent = new IT[CGAL::degree(P)];
is_exact = new bool[CGAL::degree(P)];
numerator.resize(CGAL::degree(P));
denominator_exponent.resize(CGAL::degree(P));
is_exact.resize(CGAL::degree(P));
number_of_real_roots_ = 0;
if(CGAL::degree(P) == 0)
{
@ -116,9 +116,9 @@ public:
k(kk),
interval_given(true) {
numerator = new IT[CGAL::degree(P)];
denominator_exponent = new IT[CGAL::degree(P)];
is_exact = new bool[CGAL::degree(P)];
numerator.resize(CGAL::degree(P));
denominator_exponent.resize(CGAL::degree(P));
is_exact.resize(CGAL::degree(P));
number_of_real_roots_ = 0;
if(CGAL::degree(P) == 0)
{
@ -153,9 +153,9 @@ public:
k(D.k),
interval_given(D.interval_given) {
numerator = new IT[CGAL::degree(poly_)];
denominator_exponent = new IT[CGAL::degree(poly_)];
is_exact = new bool[CGAL::degree(poly_)];
numerator.resize(CGAL::degree(poly_));
denominator_exponent.resize(CGAL::degree(poly_));
is_exact.resize(CGAL::degree(poly_));
for(int i=0; i<number_of_real_roots(); i++)
{
numerator[i] = D.numerator[i];
@ -166,9 +166,6 @@ public:
// destructor
~Descartes() {
delete[] numerator;
delete[] denominator_exponent;
delete[] is_exact;
}
public: // functions

View File

@ -327,7 +327,7 @@ public:
long operator()( CORE::BigFloat x ) const {
CGAL_precondition(!CGAL::zero_in(x));
x = CGAL::abs(x);
return CORE::floorLg(x.m()-x.err())+x.exp()*CORE::CHUNK_BIT;
return CORE::floorLg(CORE::BigInt(x.m()-x.err()))+x.exp()*CORE::CHUNK_BIT;
}
};
@ -337,7 +337,7 @@ public:
// (already commented out in EXACUS)...
// NiX_precond(!(NiX::in_zero(x) && NiX::singleton(x)));
x = CGAL::abs(x);
return CORE::ceilLg(x.m()+x.err())+x.exp()*CORE::CHUNK_BIT;
return CORE::ceilLg(CORE::BigInt(x.m()+x.err()))+x.exp()*CORE::CHUNK_BIT;
}
};

View File

@ -220,7 +220,7 @@ simple_bound_between(const Algebraic_real& a,
final_mantissa = final_mantissa << 1;
final_mantissa++;
y_log--;
x_m = x_m==0 ? 0 : x_m & ((Integer(1) << x_log) - 1); //x_m - CGAL::ipower(Integer(2),x_log);
x_m = x_m==0 ? 0 : Integer(x_m & ((Integer(1) << x_log) - 1)); //x_m - CGAL::ipower(Integer(2),x_log);
x_log = x_m==0 ? -1 : CGAL::internal::floor_log2_abs(x_m);
}
final_mantissa = final_mantissa << 1;

View File

@ -1,6 +1,7 @@
Algebraic_foundations
Algebraic_kernel_for_circles
Arithmetic_kernel
CGAL_Core
Filtered_kernel
Installation
Interval_support

View File

@ -1,6 +1,7 @@
Algebraic_foundations
Algebraic_kernel_for_spheres
Arithmetic_kernel
CGAL_Core
Filtered_kernel
Installation
Interval_support

View File

@ -1,6 +1,7 @@
Algebraic_foundations
Alpha_shapes_2
Arithmetic_kernel
CGAL_Core
Cartesian_kernel
Hash_map
Homogeneous_kernel

View File

@ -1,6 +1,7 @@
Algebraic_foundations
Alpha_shapes_3
Arithmetic_kernel
CGAL_Core
Cartesian_kernel
Circulator
Filtered_kernel

View File

@ -1153,15 +1153,17 @@ private:
if(!is_positive(alpha) || !is_positive(offset))
{
#ifdef CGAL_AW3_DEBUG
std::cerr << "Error: invalid input parameters: " << alpha << " and" << offset << std::endl;
std::cerr << "Error: invalid input parameters: " << alpha << " and " << offset << std::endl;
#endif
return false;
}
#ifdef CGAL_AW3_DEBUG
if(refining && alpha > m_alpha)
std::cerr << "Warning: refining with an alpha greater than the last iteration's!" << std::endl;
if(refining && offset != m_offset)
std::cerr << "Warning: refining with a different offset value!" << std::endl;
#endif
m_alpha = FT(alpha);
m_sq_alpha = square(m_alpha);

View File

@ -4,6 +4,7 @@ Alpha_wrap_3
Arithmetic_kernel
BGL
Box_intersection_d
CGAL_Core
Cartesian_kernel
Circulator
Distance_2

View File

@ -19,6 +19,10 @@
#ifdef CGAL_USE_BOOST_MP
#ifdef CGAL_USE_CORE
#include <CGAL/CORE_arithmetic_kernel.h>
#endif
//Currently already included in boost_mp.h
//#include <boost/multiprecision/cpp_int.hpp>
//#ifdef CGAL_USE_GMP
@ -26,20 +30,29 @@
//#endif
// FIXME: the could be several kernels based on Boost.Multiprecision.
namespace CGAL {
/** \ingroup CGAL_Arithmetic_kernel
* \brief The Boost.Multiprecision set of exact number types
*/
#if !defined(CGAL_USE_CORE) || defined(CGAL_CORE_USE_GMP_BACKEND)
struct BOOST_cpp_arithmetic_kernel : internal::Arithmetic_kernel_base {
typedef boost::multiprecision::cpp_int Integer;
typedef boost::multiprecision::cpp_rational Rational;
};
#else
typedef CORE_arithmetic_kernel BOOST_cpp_arithmetic_kernel;
#endif
#ifdef CGAL_USE_GMP
#if !defined(CGAL_USE_CORE) || !defined(CGAL_CORE_USE_GMP_BACKEND)
struct BOOST_gmp_arithmetic_kernel : internal::Arithmetic_kernel_base {
typedef boost::multiprecision::mpz_int Integer;
typedef boost::multiprecision::mpq_rational Rational;
};
#else
typedef CORE_arithmetic_kernel BOOST_gmp_arithmetic_kernel;
#endif
#endif
template <class T1, class T2, class T3, class T4, class T5>

View File

@ -55,14 +55,6 @@ public:
};
template <>
struct Get_arithmetic_kernel<CORE::BigInt>{
typedef CORE_arithmetic_kernel Arithmetic_kernel;
};
template <>
struct Get_arithmetic_kernel<CORE::BigRat>{
typedef CORE_arithmetic_kernel Arithmetic_kernel;
};
template <>
struct Get_arithmetic_kernel<CORE::Expr>{
typedef CORE_arithmetic_kernel Arithmetic_kernel;
@ -74,6 +66,8 @@ struct Get_arithmetic_kernel<CORE::BigFloat>{
} //namespace CGAL
#include <CGAL/BOOST_MP_arithmetic_kernel.h>
#endif // CGAL_USE_CORE
#endif // CGAL_CORE_ARITHMETIC_KERNEL_H

View File

@ -202,7 +202,7 @@ operator()(const Point_2& p, const X_monotone_curve_2& curve) const {
auto points = painterOstream.getPointsList(curve);
QPoint p_viewport =
view->mapFromScene(QPointF{p.x().doubleValue(), p.y().doubleValue()});
view->mapFromScene(QPointF{CGAL::to_double(p.x()), CGAL::to_double(p.y())});
double min_dist = (std::numeric_limits<double>::max)();
for (auto& vec : points) {

View File

@ -17,36 +17,63 @@
#ifndef CGAL_DRAW_ARRANGEMENT_2_H
#define CGAL_DRAW_ARRANGEMENT_2_H
#include <CGAL/Qt/Basic_viewer_qt.h>
#include <CGAL/Qt/Basic_viewer.h>
#ifdef DOXYGEN_RUNNING
namespace CGAL {
/*! \ingroup PkgArrangementOnSurface2Draw
*
* opens a new window and draws `arr`, an instance of the `CGAL::Arrangement_2`
* class template. A call to this function is blocking; that is, the program
* continues only after the user closes the window. This function requires
* `CGAL_Qt6`, and is only available if the macro `CGAL_USE_BASIC_VIEWER` is
* defined. Linking with the cmake target `CGAL::CGAL_Basic_viewer` will link
* with `CGAL_Qt6` and add the definition `CGAL_USE_BASIC_VIEWER`.
*
* \tparam GeometryTraits_2 a geometry traits type, a model of a 2D arrangement
* traits concept. At this point it must be an instance of either
* `CGAL::Arr_segment_traits_2` or `CGAL::Arr_conic_traits_2`.
*
* \tparam Dcel the \dcel type, a model of the `ArrangementDcel` concept.
*
* \param arr the 2D arrangement to draw.
* \param title the window title.
*
* \sa `ArrangementDcel`
* \sa `ArrangementTraits_2`
opens a new window and draws `arr`, an instance of the `CGAL::Arrangement_2` class template. Parameters of the drawing are taken from the optional graphics scene options parameter.
A call to this function blocks the execution of the program until the drawing window is closed. This function requires `CGAL_Qt6`, and is only available if the macro `CGAL_USE_BASIC_VIEWER` is defined.
Linking with the cmake target `CGAL::CGAL_Basic_viewer` will link with `CGAL_Qt6` and add the definition `CGAL_USE_BASIC_VIEWER`.
\tparam GeometryTraits_2 a geometry traits type, a model of a 2D arrangement traits concept. At this point it must be an instance of either `CGAL::Arr_segment_traits_2` or `CGAL::Arr_conic_traits_2`.
\tparam Dcel the \dcel type, a model of the `ArrangementDcel` concept.
\tparam GSOptions a model of `GraphicsSceneOptions` concept.
\param arr the 2D arrangement to draw.
\param gso the graphics scene options parameter.
\sa `ArrangementDcel`
\sa `ArrangementTraits_2`
*/
template <typename GeometryTraits_2, typename Dcel, typename GSOptions>
void draw(const Arrangement_2<GeometryTraits_2, Dcel>& arr, const GSOptions& gso);
/*! \ingroup PkgArrangementOnSurface2Draw
A shortcut to `CGAL::draw(arr, Graphics_scene_options{})`.
*/
template <typename GeometryTraits_2, typename Dcel>
void draw(const Arrangement_2<GeometryTraits_2, Dcel>& arr);
/*! \ingroup PkgArrangementOnSurface2Draw
adds the vertices, edges and faces of `arr` into the given graphic scene `gs`. Parameters of the cells are taken from the optional graphics scene options parameter `gso`. Note that `gs` is not cleared before being filled (to enable to draw several data structures in the same basic viewer).
\tparam GeometryTraits_2 a geometry traits type, a model of a 2D arrangement traits concept. At this point it must be an instance of either `CGAL::Arr_segment_traits_2` or `CGAL::Arr_conic_traits_2`.
\tparam Dcel the \dcel type, a model of the `ArrangementDcel` concept.
\tparam GSOptions a model of `GraphicsSceneOptions` concept.
\param arr the 2D arrangement to draw.
\param gs the graphic scene to fill.
\param gso the graphics scene options parameter.
*/
template <typename GeometryTraits_2, typename Dcel, typename GSOptions>
void add_to_graphics_scene(const Arrangement_2<GeometryTraits_2, Dcel>& arr,
CGAL::Graphics_scene& gs, const GSOptions& gso);
/*! \ingroup PkgArrangementOnSurface2Draw
A shortcut to `CGAL::add_to_graphics_scene(arr, gs, Graphics_scene_options{})`.
*/
template <typename GeometryTraits_2, typename Dcel>
void draw(const Arrangement_2<GeometryTraits_2, Dcel>& arr,
const char* title = "2D Arrangement Basic Viewer");
void add_to_graphics_scene(const Arrangement_2<GeometryTraits_2, Dcel>& arr,
CGAL::Graphics_scene& gs);
} /* namespace CGAL */

View File

@ -100,13 +100,24 @@ int main() {
<< arr.number_of_faces() << std::endl;
std::size_t id(0);
CGAL::draw(arr, [&] (Arrangement_2::Face_const_handle) -> CGAL::IO::Color {
float h = 360.0f * id++ / arr.number_of_faces();
float s = 0.5;
float v = 0.5;
auto [r, g, b] = hsv_to_rgb(h, s, v);
return CGAL::IO::Color(r,g,b);
}, "hsv colors", true);
return EXIT_SUCCESS;
CGAL::Graphics_scene_options<Arrangement_2,
typename Arrangement_2::Vertex_const_handle,
typename Arrangement_2::Halfedge_const_handle,
typename Arrangement_2::Face_const_handle> gso;
gso.colored_face=[](const Arrangement_2&, Arrangement_2::Face_const_handle) -> bool
{ return true; };
gso.face_color=[&id](const Arrangement_2& arr, Arrangement_2::Face_const_handle) -> CGAL::IO::Color
{
float h = 360.0f * id++ / arr.number_of_faces();
float s = 0.5;
float v = 0.5;
auto [r, g, b] = hsv_to_rgb(h, s, v);
return CGAL::IO::Color(r,g,b);
};
CGAL::draw(arr, gso, "hsv colors");
return EXIT_SUCCESS;
}

View File

@ -3316,9 +3316,9 @@ public:
// sqrt((r - s)^2 + t^2)
//
const int or_fact = (cv.orientation() == CLOCKWISE) ? -1 : 1;
const Algebraic r = m_nt_traits->convert(or_fact * cv.r());
const Algebraic s = m_nt_traits->convert(or_fact * cv.s());
const Algebraic t = m_nt_traits->convert(or_fact * cv.t());
const Algebraic r = m_nt_traits->convert(Integer(or_fact * cv.r()));
const Algebraic s = m_nt_traits->convert(Integer(or_fact * cv.s()));
const Algebraic t = m_nt_traits->convert(Integer(or_fact * cv.t()));
const Algebraic cos_2phi = (r - s) / m_nt_traits->sqrt((r-s)*(r-s) + t*t);
const Algebraic zero = 0;
const Algebraic one = 1;
@ -3363,8 +3363,8 @@ public:
// 4*r*s - t^2 4*r*s - t^2
//
// The denominator (4*r*s - t^2) must be negative for hyperbolas.
const Algebraic u = m_nt_traits->convert(or_fact * cv.u());
const Algebraic v = m_nt_traits->convert(or_fact * cv.v());
const Algebraic u = m_nt_traits->convert(Integer(or_fact * cv.u()));
const Algebraic v = m_nt_traits->convert(Integer(or_fact * cv.v()));
const Algebraic det = 4*r*s - t*t;
Algebraic x0, y0;
@ -3803,9 +3803,9 @@ public:
auto u = cv.u();
auto v = cv.v();
auto w = cv.w();
Algebraic* xs_end = m_nt_traits->solve_quadratic_equation(t*t - four*r*s,
two*t*v - four*s*u,
v*v - four*s*w,
Algebraic* xs_end = m_nt_traits->solve_quadratic_equation(Integer(t*t - four*r*s),
Integer(two*t*v - four*s*u),
Integer(v*v - four*s*w),
xs);
auto n_xs = static_cast<int>(xs_end - xs);
@ -3816,15 +3816,15 @@ public:
if (CGAL::sign(cv.t()) == ZERO) {
// The two vertical tangency points have the same y coordinate:
ys[0] = m_nt_traits->convert(-v) / m_nt_traits->convert(two*s);
ys[0] = m_nt_traits->convert(Integer(- v)) / m_nt_traits->convert(Integer(two * s));
n_ys = 1;
}
else {
ys_end = m_nt_traits->solve_quadratic_equation(four*r*s*s - s*t*t,
four*r*s*v - two*s*t*u,
r*v*v - t*u*v +
t*t*w,
ys_end = m_nt_traits->solve_quadratic_equation(Integer(four*r*s*s - s*t*t),
Integer(four*r*s*v - two*s*t*u),
Integer((r*v*v - t*u*v) + (t*t*w)),
ys);
n_ys = static_cast<int>(ys_end - ys);
}
@ -3837,7 +3837,7 @@ public:
}
else {
for (int j = 0; j < n_ys; ++j) {
if (CGAL::compare(m_nt_traits->convert(two*s) * ys[j],
if (CGAL::compare(m_nt_traits->convert(Integer(two*s)) * ys[j],
-(m_nt_traits->convert(t) * xs[i] +
m_nt_traits->convert(v))) == EQUAL)
{
@ -3904,10 +3904,11 @@ public:
auto u = cv.u();
auto v = cv.v();
auto w = cv.w();
Algebraic* ys_end = m_nt_traits->solve_quadratic_equation(t*t - four*r*s,
two*t*u - four*r*v,
u*u - four*r*w,
ys);
Algebraic* ys_end = m_nt_traits->template
solve_quadratic_equation<Integer>(t*t - four*r*s,
two*t*u - four*r*v,
u*u - four*r*w,
ys);
auto n = static_cast<int>(ys_end - ys);
// Compute the x coordinates and construct the horizontal tangency points.
@ -3915,7 +3916,7 @@ public:
// Having computed y, x is the single solution to the quadratic equation
// above, and since its discriminant is 0, x is simply given by:
Algebraic x = -(m_nt_traits->convert(t)*ys[i] + m_nt_traits->convert(u)) /
m_nt_traits->convert(two*r);
m_nt_traits->convert(Integer(two*r));
ps[i] = Point_2(x, ys[i]);
}

View File

@ -1430,8 +1430,8 @@ protected:
{
// Actually compare the slopes.
const bool swap_res = (sign_denom1 != sign_denom2);
const CoordNT A = (cv.y0() - y0())*p.x() + (y0()*cv.x0() - cv.y0()*x0());
const CoordNT B = (cv.x0() - x0())*p.y();
const CoordNT A = NT(cv.y0() - y0())*p.x() + (y0()*cv.x0() - cv.y0()*x0());
const CoordNT B = NT(cv.x0() - x0())*p.y();
slope_res = CGAL::compare (A, B);

View File

@ -1110,9 +1110,9 @@ protected:
//
Nt_traits nt_traits;
const int or_fact = (m_orient == CLOCKWISE) ? -1 : 1;
const Algebraic r = nt_traits.convert(or_fact * m_r);
const Algebraic s = nt_traits.convert(or_fact * m_s);
const Algebraic t = nt_traits.convert(or_fact * m_t);
const Algebraic r = nt_traits.convert(Integer(or_fact * m_r));
const Algebraic s = nt_traits.convert(Integer(or_fact * m_s));
const Algebraic t = nt_traits.convert(Integer(or_fact * m_t));
const Algebraic cos_2phi = (r - s) / nt_traits.sqrt((r-s)*(r-s) + t*t);
const Algebraic zero = 0;
const Algebraic one = 1;
@ -1158,8 +1158,8 @@ protected:
// 4*r*s - t^2 4*r*s - t^2
//
// The denominator (4*r*s - t^2) must be negative for hyperbolas.
const Algebraic u = nt_traits.convert(or_fact * m_u);
const Algebraic v = nt_traits.convert(or_fact * m_v);
const Algebraic u = nt_traits.convert(Integer(or_fact * m_u));
const Algebraic v = nt_traits.convert(Integer(or_fact * m_v));
const Algebraic det = 4*r*s - t*t;
Algebraic x0, y0;

View File

@ -64,8 +64,9 @@ int compute_resultant_roots(const Nt_traits& nt_traits,
}
// Act according to the degree of the first conic curve.
const typename Nt_traits::Integer two = 2;
typename Nt_traits::Integer c[5];
typedef typename Nt_traits::Integer Integer;
const Integer two = 2;
Integer c[5];
unsigned int degree = 4;
typename Nt_traits::Algebraic* xs_end;
@ -73,7 +74,7 @@ int compute_resultant_roots(const Nt_traits& nt_traits,
// The first curve has no quadratic coefficients, and represents a line.
if (CGAL::sign (v1) == ZERO) {
// The first line is u1*x + w1 = 0, therefore:
xs[0] = nt_traits.convert(-w1) / nt_traits.convert(u1);
xs[0] = nt_traits.convert(Integer(- w1)) / nt_traits.convert(u1);
return 1;
}
@ -87,7 +88,7 @@ int compute_resultant_roots(const Nt_traits& nt_traits,
// Return if the two lines are parallel
if (CGAL::sign (c[1]) == ZERO) return 0;
xs[0] = nt_traits.convert(-c[0]) / nt_traits.convert(c[1]);
xs[0] = nt_traits.convert(Integer(- c[0])) / nt_traits.convert(c[1]);
return 1;
}

View File

@ -225,10 +225,11 @@ public:
if (CGAL::compare(
CGAL::width(y_bfi),
CGAL::lower(CGAL::abs(y_bfi)) * eps)
== SMALLER)
== SMALLER){
return std::make_pair(
Bound(CGAL::lower(y_bfi)),
Bound(CGAL::upper(y_bfi)));
}
}
else precision*=2;
}
@ -287,10 +288,11 @@ private:
if (CGAL::zero_in(y_denom_bfi) == false)
{
BFI y_bfi(y_numer_bfi/y_denom_bfi);
if (CGAL::width(y_bfi) < eps )
if (CGAL::width(y_bfi) < eps ){
return std::make_pair(
Bound(CGAL::lower(y_bfi)),
Bound(CGAL::upper(y_bfi)));
}
}
else precision*=2;

View File

@ -106,7 +106,7 @@ public:
ix1 = scaled_x1.BigIntValue();
ix2 = scaled_x2.BigIntValue();
if (CORE::abs (ix2 - ix1) > one)
if (CGAL::abs (ix2 - ix1) > one)
break;
// Scale the values by a factor of 2.
@ -179,9 +179,9 @@ public:
temp_gcd = numer_gcd;
denom_lcm *= denom;
denom_lcm /= CORE::gcd (temp_lcm, denom);
denom_lcm /= CGAL::gcd (temp_lcm, denom);
numer_gcd = CORE::gcd (temp_gcd, numer);
numer_gcd = CGAL::gcd (temp_gcd, numer);
}
++q_iter;
@ -246,8 +246,8 @@ public:
if (sign_disc == ZERO)
{
// We have one real root with mutliplicity 2.
*oi = -Algebraic (b) / Algebraic (2*a);
// We have one real root with multiplicity 2.
*oi = -Algebraic (b) / Algebraic (NT(2*a));
++oi;
}
else if (sign_disc == POSITIVE)
@ -255,7 +255,7 @@ public:
// We have two distinct real roots. We return them in ascending order.
const Algebraic sqrt_disc = CGAL::sqrt (Algebraic (disc));
const Algebraic alg_b = b;
const Algebraic alg_2a = 2*a;
const Algebraic alg_2a = NT(2*a);
if (sign_a == POSITIVE)
{
@ -334,7 +334,7 @@ public:
temp_lcm = denom_lcm;
denom_lcm *= denom;
denom_lcm /= CORE::gcd (temp_lcm, denom);
denom_lcm /= CGAL::gcd (temp_lcm, denom);
}
index--;

View File

@ -865,7 +865,7 @@ void draw(const Arc_2& arc,
get_pixel_coords(l, y_clip, pix_beg);
get_pixel_coords(ptmp->left, it->second ? engine.y_max_r :
engine.y_min_r, pix_end);
if(CGAL_ABS(ptmp->left - l) <= engine.pixel_w_r*2) {
if(CGAL_ABS(Rational(ptmp->left - l)) <= engine.pixel_w_r*2) {
Coordinate_2 xy(Coordinate_1(pt), *support, arc.arcno());
Rational _;

View File

@ -695,7 +695,7 @@ bool get_range_QF_1(int var, const NT& l_, const NT& r_, const NT& key,
while(der_it != der_begin) {
--der_it;
e1 = xsum_abs * e1 + CGAL_ABS(x1 * z1);
e1 = xsum_abs * e1 + CGAL_ABS(NT(x1 * z1));
z1 = x0*z1 + x1*y1;
y1 = y1*x0 + x1*y0;
y0 = x0*y0 + extract(*cache_it)*(*der_it);
@ -726,7 +726,7 @@ bool get_range_QF_1(int var, const NT& l_, const NT& r_, const NT& key,
NT y0 = extract(*cache_it), y1(0), z1(0), e1(0);
while(cache_it != begin) {
--cache_it;
e1 = xsum_abs * e1 + CGAL_ABS(x1*z1);
e1 = xsum_abs * e1 + CGAL_ABS(NT(x1*z1));
z1 = x0*z1 + x1*y1;
y1 = y1*x0 + x1*y0;
y0 = x0*y0 + extract(*cache_it);

View File

@ -336,7 +336,7 @@ struct Curve_renderer_traits<CGAL::Interval_nt<true>, CORE::BigRat > :
//! Specialization for \c CORE::BigFloat
template <>
struct Curve_renderer_traits<CORE::BigFloat, class CORE::BigRat>
struct Curve_renderer_traits<CORE::BigFloat, CORE::BigRat>
: public Curve_renderer_traits_base<CORE::BigFloat, CORE::BigInt,
CORE::BigRat> {
@ -347,7 +347,7 @@ struct Curve_renderer_traits<CORE::BigFloat, class CORE::BigRat>
typedef Integer result_type;
Integer operator()(const Rational& x) const {
return x.BigIntValue();
return numerator(x)/denominator(x);
}
};
@ -400,7 +400,7 @@ struct Curve_renderer_traits<CORE::BigRat, CORE::BigRat> :
typedef Integer result_type;
Integer operator()(const Rational& x) const {
return x.BigIntValue();
return numerator(x)/denominator(x);
}
};
@ -409,9 +409,7 @@ struct Curve_renderer_traits<CORE::BigRat, CORE::BigRat> :
typedef std::size_t result_type;
inline result_type operator()(const Float& key) const {
const CORE::BigRatRep& rep = key.getRep();
std::size_t ret = reinterpret_cast<std::size_t>(&rep);
return ret;
return std::hash<Float>()(key);
}
};
};

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,7 @@ Algebraic_kernel_d
Arithmetic_kernel
Arrangement_on_surface_2
BGL
Basic_viewer
CGAL_Core
Cartesian_kernel
Circular_kernel_2
@ -10,7 +11,6 @@ Circulator
Distance_2
Distance_3
Filtered_kernel
GraphicsView
HalfedgeDS
Hash_map
Homogeneous_kernel

View File

@ -928,7 +928,7 @@ endfunction()
#---------------------------------------------------------------------#
function(test_polycurve_conic_traits)
# echo polycurve test starting
if(CGAL_DISABLE_GMP)
if(NOT CGAL_Core_FOUND)
MESSAGE(STATUS "test_polycurve_conic_traits requires CORE and will not be executed")
return()
endif()
@ -994,7 +994,7 @@ endfunction()
# polycurve bezier traits
#---------------------------------------------------------------------#
function(test_polycurve_bezier_traits)
if(CGAL_DISABLE_GMP)
if(NOT CGAL_Core_FOUND)
MESSAGE(STATUS "test_polycurve_bezier_traits requires CORE and will not be executed")
return()
endif()
@ -1110,7 +1110,7 @@ endfunction()
# conic traits
#---------------------------------------------------------------------#
function(test_conic_traits)
if(CGAL_DISABLE_GMP)
if(NOT CGAL_Core_FOUND)
MESSAGE(STATUS "test_conic_traits requires CORE and will not be executed")
return()
endif()
@ -1254,7 +1254,7 @@ endfunction()
# bezier traits
#---------------------------------------------------------------------#
function(test_bezier_traits)
if(CGAL_DISABLE_GMP)
if(NOT CGAL_Core_FOUND)
MESSAGE(STATUS "test_bezier_traits requires CORE and will not be executed")
return()
endif()
@ -1301,7 +1301,7 @@ endfunction()
# rational arc traits
#---------------------------------------------------------------------#
function(test_rational_arc_traits)
if(CGAL_DISABLE_GMP)
if(NOT CGAL_Core_FOUND)
MESSAGE(STATUS "test_rational_arc_traits requires CORE and will not be executed")
return()
endif()
@ -1382,7 +1382,7 @@ endfunction()
#---------------------------------------------------------------------#
function(test_algebraic_traits_core)
#TODO: Adapt
if(CGAL_DISABLE_GMP)
if(NOT CGAL_Core_FOUND)
MESSAGE(STATUS "test_algebraic_traits_core requires CORE and will not be executed")
return()
endif()

View File

@ -7,18 +7,18 @@
# We need the bezier curve (not polycurve) to contruct a bezier point.
#
# Point ID: 0
r c 4 0 0 500 200 100 200 900 0 0.5
r c 4 0 0 500 200 100 200 900 0 1/2
# Point ID: 1
r c 4 900 0 1200 600 1500 400 900 600 0.3
r c 4 900 0 1200 600 1500 400 900 600 3/10
# Point id: 2
r c 4 0 0 100 200 500 200 900 0 0.0
r c 4 0 0 100 200 500 200 900 0 0
# Point id: 3
r c 4 900 0 1200 300 1500 400 2000 450 1.0
r c 4 900 0 1200 300 1500 400 2000 450 1
# Point id: 4
r c 4 2000 450 2100 300 2200 200 2300 450 0.0
r c 4 2000 450 2100 300 2200 200 2300 450 0
# Point id: 5
r c 4 2300 450 2500 500 2800 600 3000 450 1.0
r c 4 2300 450 2500 500 2800 600 3000 450 1
# Point id: 6
r c 4 0 0 100 200 500 200 900 0 0.0
r c 4 0 0 100 200 500 200 900 0 0
# Point id: 7
r c 4 2300 450 2500 500 2800 600 3000 450 1.0
r c 4 2300 450 2500 500 2800 600 3000 450 1

View File

@ -510,11 +510,12 @@ Dynamic property tags, such as `dynamic_vertex_property_t`, are a generalization
value type of the dynamic property map, and a default value.
`boost::property_map<G,T>::%type` is used to obtain the
type of the dynamic property map for a graph of type `G`, for a
dynamic property tag `T`. This type must be default constructible and assignable.
dynamic property tag `T`. This type must be assignable, and if no
default is provided it must be default constructible.
As for ordinary properties, the function `%get()` is overloaded and
serves for retrieving a property map for a given graph and dynamic
property tag, as well as for retrieving a value for a given key and
property map.
property map. The default value is provided as third parameter.
The following example shows how to attach a `string` property to vertices and
a `double` value to the halfedges of a graph.

View File

@ -34,6 +34,7 @@ ALIASES += "bgllink{1}=<a href=\"http://www.boost.org/libs/graph/doc/\1.html\">
EXTRACT_ALL=NO
HIDE_UNDOC_MEMBERS = YES
HIDE_UNDOC_CLASSES = YES
WARN_IF_INCOMPLETE_DOC = NO
# macros to be used inside the code
ALIASES += "cgalAssociatedTypesBegin=<dl class=\"params\"><dt>Associated Types</dt><dd> <table class=\"params\">"

View File

@ -449,6 +449,9 @@ the requirement for traversal of all faces in a graph.
/// \defgroup PkgBGLHelperFct Helper Functions
/// \ingroup PkgBGLRef
/// \defgroup PkgBGLGeneratorFct Generator Functions
/// \ingroup PkgBGLRef
/// \defgroup PkgBGLIterators Iterators and Circulators
/// \ingroup PkgBGLRef
@ -520,7 +523,14 @@ by attaching and initializing external IDs to the elements of the graph.
Generic convenience functions for testing if an edge is a border edge, if a mesh is triangular,
for conversion between models of different `FaceGraph` concepts, etc.
Most functions are in the header file `<CGAL/boost/graph/helpers.h>`
All functions are in the header file `<CGAL/boost/graph/helpers.h>`
*/
/*!
\addtogroup PkgBGLGeneratorrFct
Generic convenience functions for generating meshes such as a triangle, a quad, or a grid.
All functions are in the header file `<CGAL/boost/graph/generators.h>`
*/
/*!
@ -667,6 +677,7 @@ user might encounter.
- `CGAL::is_valid_face_graph()`
- `CGAL::is_valid_polygon_mesh()`
\cgalCRPSection{Generator Functions}
- `CGAL::is_tetrahedron()`
- `CGAL::is_hexahedron()`
- `CGAL::make_triangle()`

View File

@ -2,7 +2,7 @@
#include <CGAL/Surface_mesh.h>
#include <CGAL/boost/graph/selection.h>
#include <CGAL/boost/graph/IO/OFF.h>
#include <CGAL/Random.h>
#include <fstream>
#include <iostream>

View File

@ -4,6 +4,7 @@
#include <CGAL/boost/graph/Graph_with_descriptor_with_graph.h>
#include <CGAL/boost/graph/helpers.h>
#include <CGAL/boost/graph/Euler_operations.h>
#include <CGAL/boost/graph/generators.h>
#include <fstream>

View File

@ -1,5 +1,6 @@
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/boost/graph/generators.h>
#include <CGAL/boost/graph/io.h>

View File

@ -19,23 +19,15 @@
#include <CGAL/Random.h>
#include <CGAL/function_objects.h>
#include <CGAL/Named_function_parameters.h>
#include <CGAL/boost/graph/named_params_helper.h>
#include <CGAL/boost/graph/copy_face_graph.h>
#include <array>
#include <iterator>
#include <vector>
namespace CGAL {
namespace Euler {
// Some forward declaration to break the helpers.h > generators.h > Euler_operations.h cycle
template< typename Graph>
void fill_hole(typename boost::graph_traits<Graph>::halfedge_descriptor h,
Graph& g);
template<typename Graph , typename VertexRange >
typename boost::graph_traits<Graph>::face_descriptor add_face(const VertexRange& vr,
Graph& g);
} // namespace Euler
namespace internal {
@ -126,7 +118,7 @@ random_face_in_mesh(const Graph& g, CGAL::Random& rnd = get_default_random())
} // namespace internal
/**
* \ingroup PkgBGLHelperFct
* \ingroup PkgBGLGeneratorFct
*
* \brief creates an isolated triangle
* with its vertices initialized to `p0`, `p1` and `p2`, and adds it to the graph `g`.
@ -256,7 +248,7 @@ struct Default_grid_maker
} // namespace internal
/**
* \ingroup PkgBGLHelperFct
* \ingroup PkgBGLGeneratorFct
*
* \brief creates an isolated quad with
* its vertices initialized to `p0`, `p1`, `p2`, and `p3`, and adds it to the graph `g`.
@ -287,17 +279,35 @@ make_quad(const P& p0, const P& p1, const P& p2, const P& p3, Graph& g)
}
/**
* \ingroup PkgBGLHelperFct
* \ingroup PkgBGLGeneratorFct
* \brief creates an isolated hexahedron
* with its vertices initialized to `p0`, `p1`, ...\ , and `p7`, and adds it to the graph `g`.
* \image html hexahedron.png
* \image latex hexahedron.png
* \returns the halfedge that has the target vertex associated with `p0`, in the face with the vertices with the points `p0`, `p1`, `p2`, and `p3`.
* \returns the halfedge that has the target vertex associated with `p0`,
* in the face with the vertices with the points `p0`, `p1`, `p2`, and `p3`
* (or `p0`, `p2` and `p3` when `do_not_triangulate` is set to `false`).
*
* \tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
* \param np an optional sequence of \ref bgl_namedparameters "Named Parameters"
* among the ones listed below
* \cgalNamedParamsBegin
* \cgalParamNBegin{do_not_triangulate_faces}
* \cgalParamDescription{a Boolean used to specify whether the hexadron's faces
* should be triangulated or not.
* The default value is `true`, and faces are not triangulated.}
* \cgalParamDefault{true}
* \cgalParamNEnd
* \cgalNamedParamsEnd
**/
template<typename Graph, typename P>
template<typename P,
typename Graph,
typename NamedParameters = parameters::Default_named_parameters>
typename boost::graph_traits<Graph>::halfedge_descriptor
make_hexahedron(const P& p0, const P& p1, const P& p2, const P& p3,
const P& p4, const P& p5, const P& p6, const P& p7, Graph& g)
const P& p4, const P& p5, const P& p6, const P& p7,
Graph& g,
const NamedParameters& np = parameters::default_values())
{
typedef typename boost::graph_traits<Graph> Traits;
typedef typename Traits::halfedge_descriptor halfedge_descriptor;
@ -306,6 +316,9 @@ make_hexahedron(const P& p0, const P& p1, const P& p2, const P& p3,
typedef typename boost::property_map<Graph,vertex_point_t>::type Point_property_map;
Point_property_map ppmap = get(CGAL::vertex_point, g);
const bool triangulate = !parameters::choose_parameter(
parameters::get_parameter(np, internal_np::do_not_triangulate_faces), true);
vertex_descriptor v0, v1, v2, v3, v4, v5, v6, v7;
v0 = add_vertex(g);
v1 = add_vertex(g);
@ -326,6 +339,14 @@ make_hexahedron(const P& p0, const P& p1, const P& p2, const P& p3,
halfedge_descriptor ht = internal::make_quad(v4, v5, v6, v7, g);
halfedge_descriptor hb = prev(internal::make_quad(v0, v3, v2, v1, g), g);
std::array<halfedge_descriptor, 6> he_faces;
if(triangulate)
{
he_faces[0] = hb;
he_faces[1] = ht;
}
for(int i=0; i <4; ++i)
{
halfedge_descriptor h = halfedge(add_edge(g), g);
@ -342,14 +363,72 @@ make_hexahedron(const P& p0, const P& p1, const P& p2, const P& p3,
for(int i=0; i <4; ++i)
{
Euler::fill_hole(opposite(hb, g), g);
if(triangulate)
he_faces[i+2] = opposite(hb, g);
hb = next(hb, g);
}
if(triangulate)
{
for (halfedge_descriptor hi : he_faces)
{
halfedge_descriptor nnhi = next(next(hi, g), g);
Euler::split_face(hi, nnhi, g);
}
}
return next(next(hb, g), g);
}
/**
* \ingroup PkgBGLHelperFct
* \ingroup PkgBGLGeneratorFct
* \brief creates an isolated hexahedron
* equivalent to `c`, and adds it to the graph `g`.
* \returns the halfedge that has the target vertex associated with `c.min()`,
* aligned with x-axis,
* in the bottom face of the cuboid.
*
* \tparam IsoCuboid a model of `IsoCuboid_3`
* \tparam Graph a model of `MutableFaceGraph`
* \tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
*
* \param c the iso-cuboid describing the geometry of the hexahedron
* \param g the graph to which the hexahedron will be appended
* \param np an optional sequence of \ref bgl_namedparameters "Named Parameters"
* among the ones listed below
* \cgalNamedParamsBegin
* \cgalParamNBegin{do_not_triangulate_faces}
* \cgalParamDescription{a Boolean used to specify whether the hexadron's faces
* should be triangulated or not.
* The default value is `true`, and faces are not triangulated.}
* \cgalParamDefault{true}
* \cgalParamNEnd
* \cgalParamNBegin{geom_traits}
* \cgalParamDescription{an instance of a geometric traits class model of `Kernel`.}
* \cgalParamNEnd
* \cgalNamedParamsEnd
**/
template<typename IsoCuboid,
typename Graph,
typename NamedParameters = parameters::Default_named_parameters>
typename boost::graph_traits<Graph>::halfedge_descriptor
make_hexahedron(const IsoCuboid& c,
Graph& g,
const NamedParameters& np = parameters::default_values())
{
using GT = typename GetGeomTraits<Graph, NamedParameters>::type;
GT gt = parameters::choose_parameter<GT>(
parameters::get_parameter(np, internal_np::geom_traits));
typename GT::Construct_vertex_3 v = gt.construct_vertex_3_object();
return CGAL::make_hexahedron(v(c, 0), v(c, 1), v(c, 2), v(c, 3),
v(c, 4), v(c, 5), v(c, 6), v(c, 7),
g,
np);
}
/**
* \ingroup PkgBGLGeneratorFct
* \brief creates an isolated tetrahedron
* with its vertices initialized to `p0`, `p1`, `p2`, and `p3`, and adds it to the graph `g`.
* \image html tetrahedron.png
@ -447,7 +526,7 @@ make_tetrahedron(const P& p0, const P& p1, const P& p2, const P& p3, Graph& g)
}
/**
* \ingroup PkgBGLHelperFct
* \ingroup PkgBGLGeneratorFct
*
* \brief creates a triangulated regular prism, outward oriented,
* having `nb_vertices` vertices in each of its bases and adds it to the graph `g`.
@ -547,7 +626,7 @@ make_regular_prism(typename boost::graph_traits<Graph>::vertices_size_type nb_ve
}
/**
* \ingroup PkgBGLHelperFct
* \ingroup PkgBGLGeneratorFct
* \brief creates a pyramid, outward oriented, having `nb_vertices` vertices in its base and adds it to the graph `g`.
*
* If `center` is `(0, 0, 0)`, then the first point of the base is `(radius, 0, 0)`
@ -635,7 +714,7 @@ make_pyramid(typename boost::graph_traits<Graph>::vertices_size_type nb_vertices
}
/**
* \ingroup PkgBGLHelperFct
* \ingroup PkgBGLGeneratorFct
*
* \brief creates an icosahedron, outward oriented, centered in `center` and adds it to the graph `g`.
*
@ -730,7 +809,7 @@ make_icosahedron(Graph& g,
}
/*!
* \ingroup PkgBGLHelperFct
* \ingroup PkgBGLGeneratorFct
*
* \brief creates a row major ordered grid with `i` cells along the width and `j` cells
* along the height and adds it to the graph `g`.

View File

@ -1081,8 +1081,5 @@ int halfedge_index_in_face(typename boost::graph_traits<Graph>::halfedge_descrip
} // namespace CGAL
// Here at the bottom because helpers.h must include generators (for backward compatibility reasons),
// and Euler_operations.h needs helpers.h
#include <CGAL/boost/graph/generators.h>
#endif // CGAL_BOOST_GRAPH_HELPERS_H

View File

@ -1,4 +1,4 @@
// Copyright (c) 2018-2020 GeometryFactory (France)
// Copyright (c) 2018-2022 GeometryFactory (France)
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
@ -9,199 +9,151 @@
//
// Author(s) : Guillaume Damiand <guillaume.damiand@liris.cnrs.fr>
// Laurent Rineau <laurent.rineau@cgal.org>
// Mostafa Ashraf <mostaphaashraf1996@gmail.com>
#ifndef CGAL_DRAW_FACE_GRAPH_H
#define CGAL_DRAW_FACE_GRAPH_H
#ifdef CGAL_USE_BASIC_VIEWER
#include <CGAL/Graphics_scene.h>
#include <CGAL/Graphics_scene_options.h>
#include <CGAL/Dynamic_property_map.h>
#include <CGAL/Random.h>
#include <CGAL/boost/graph/helpers.h>
namespace CGAL {
// Default color functor; user can change it to have its own face color
struct DefaultColorFunctorFaceGraph
namespace draw_function_for_FG {
template <typename FG, typename GSOptions>
void compute_elements(const FG &fg,
CGAL::Graphics_scene &graphics_scene,
const GSOptions &gs_options)
{
template<typename Graph>
CGAL::IO::Color operator()(const Graph& /*g*/,
typename boost::graph_traits<Graph>::face_descriptor /*f*/) const
using Point=typename boost::property_map_value<FG, CGAL::vertex_point_t>::type;
using Kernel = typename CGAL::Kernel_traits<Point>::Kernel;
using Vector = typename Kernel::Vector_3;
auto vnormals = get(CGAL::dynamic_vertex_property_t<Vector>(), fg);
auto point_pmap = get(CGAL::vertex_point, fg);
for (auto v : vertices(fg))
{
return get_random_color(CGAL::get_default_random());
}
// edges and vertices are black by default
template<typename Graph>
CGAL::IO::Color operator()(const Graph& /*g*/,
typename boost::graph_traits<Graph>::edge_descriptor /*e*/) const
{
return IO::black();
}
template<typename Graph>
CGAL::IO::Color operator()(const Graph& /*g*/,
typename boost::graph_traits<Graph>::vertex_descriptor /*v*/) const
{
return IO::black();
}
};
class SimpleFaceGraphViewerQt : public Basic_viewer_qt
{
using Base = Basic_viewer_qt;
public:
SimpleFaceGraphViewerQt(QWidget* parent) :
Base(parent, "", false, true, true, true, false),
m_compute_elements_impl([]{})
{
}
/// Construct the viewer.
/// @param g the face graph to view
/// @param title the title of the window
/// @param anofaces if true, do not draw faces (faces are not computed; this can be
/// useful for very big objects where this time could be long)
template <typename Graph>
SimpleFaceGraphViewerQt(QWidget* parent,
const Graph& g,
const char* title="Basic Face Graph Viewer",
bool anofaces=false) :
SimpleFaceGraphViewerQt(parent, g, title, anofaces, DefaultColorFunctorFaceGraph())
{
}
template <typename Graph, typename ColorFunctor>
SimpleFaceGraphViewerQt(QWidget* parent,
const Graph& g,
const char* title,
bool anofaces,
ColorFunctor fcolor) :
// First draw: no vertex; edges, faces; mono-color; inverse normal
Base(parent, title, false, true, true, true, false),
m_compute_elements_impl(compute_elements_functor(g, anofaces, fcolor))
{
}
void init() override {
compute_elements();
Base::init();
}
void compute_elements() {
m_compute_elements_impl();
}
template <typename Graph, typename ColorFunctor>
void set_face_graph(const Graph& g,
bool anofaces,
ColorFunctor fcolor) {
m_compute_elements_impl = compute_elements_functor(g, anofaces, fcolor);
}
template <typename Graph, typename ColorFunctor>
void set_face_graph(const Graph& g,
bool anofaces=false) {
set_mesh(g, anofaces, DefaultColorFunctorFaceGraph());
}
protected:
template <typename Graph, typename ColorFunctor>
std::function<void()>
compute_elements_functor(const Graph& g,
bool anofaces,
ColorFunctor fcolor)
{
using Point = typename boost::property_map_value<Graph, CGAL::vertex_point_t>::type;
using Kernel = typename CGAL::Kernel_traits<Point>::Kernel;
using Vector = typename Kernel::Vector_3;
auto vnormals = get(CGAL::dynamic_vertex_property_t<Vector>(), g);
auto point_pmap = get(CGAL::vertex_point, g);
for (auto v : vertices(g))
Vector n(NULL_VECTOR);
int i = 0;
for (auto h : halfedges_around_target(halfedge(v, fg), fg))
{
Vector n(NULL_VECTOR);
int i=0;
for (auto h : halfedges_around_target(halfedge(v, g), g))
if (!is_border(h, fg))
{
if (!is_border(h, g))
Vector ni = CGAL::cross_product(
Vector(get(point_pmap, source(h, fg)),
get(point_pmap, target(h, fg))),
Vector(get(point_pmap, target(h, fg)),
get(point_pmap, target(next(h, fg), fg))));
if (ni!=NULL_VECTOR)
{
Vector ni = CGAL::cross_product(
Vector(get(point_pmap, source(h, g)), get(point_pmap, target(h, g))),
Vector(get(point_pmap, target(h, g)), get(point_pmap, target(next(h, g), g))));
if (ni != NULL_VECTOR)
{
n+=ni;
++i;
}
n += ni;
++i;
}
}
put(vnormals, v, n/i);
}
// This function return a lambda expression, type-erased in a
// `std::function<void()>` object.
return [this, &g, vnormals, anofaces, fcolor, point_pmap]()
{
this->clear();
if (!anofaces)
{
for (auto fh: faces(g))
{
const CGAL::IO::Color& c = fcolor(g, fh);
face_begin(c);
auto hd=halfedge(fh, g);
const auto first_hd = hd;
do
{
auto v = source(hd, g);
add_point_in_face(get(point_pmap, v), get(vnormals, v));
hd=next(hd, g);
}
while(hd!=first_hd);
face_end();
}
}
for (auto e: edges(g))
{
const CGAL::IO::Color& c = fcolor(g, e);
add_segment(get(point_pmap, source(halfedge(e, g), g)),
get(point_pmap, target(halfedge(e, g), g)),
c);
}
for (auto v: vertices(g))
{
const CGAL::IO::Color& c = fcolor(g, v);
this->add_point(get(point_pmap, v), c);
}
};
put(vnormals, v, n / i);
}
void keyPressEvent(QKeyEvent *e) override
if (gs_options.are_faces_enabled())
{
// Test key pressed:
// const ::Qt::KeyboardModifiers modifiers = e->modifiers();
// if ((e->key()==Qt::Key_PageUp) && (modifiers==Qt::NoButton)) { ... }
// Call: * compute_elements() if the model changed, followed by
// * redraw() if some viewing parameters changed that implies some
// modifications of the buffers
// (eg. type of normal, color/mono)
// * update() just to update the drawing
// Call the base method to process others/classicals key
Base::keyPressEvent(e);
for (auto fh : faces(fg))
{
if (fh != boost::graph_traits<FG>::null_face() && // face exists
gs_options.draw_face(fg, fh)) // face is drawn
{
if(gs_options.colored_face(fg, fh)) // face is colored
{ graphics_scene.face_begin(gs_options.face_color(fg, fh)); }
else
{ graphics_scene.face_begin(); }
auto hd = halfedge(fh, fg);
const auto first_hd = hd;
do
{
auto v = source(hd, fg);
graphics_scene.add_point_in_face(get(point_pmap, v), get(vnormals, v));
hd = next(hd, fg);
}
while (hd != first_hd);
graphics_scene.face_end();
}
}
}
protected:
std::function<void()> m_compute_elements_impl;
};
if(gs_options.are_edges_enabled())
{
for (auto e : edges(fg))
{
if(gs_options.colored_edge(fg, e)) // edge is colored
{
graphics_scene.add_segment(get(point_pmap, source(halfedge(e, fg), fg)),
get(point_pmap, target(halfedge(e, fg), fg)),
gs_options.edge_color(fg, e));
}
else
{
graphics_scene.add_segment(get(point_pmap, source(halfedge(e, fg), fg)),
get(point_pmap, target(halfedge(e, fg), fg)));
}
}
}
if(gs_options.are_vertices_enabled())
{
for (auto v : vertices(fg))
{
if(gs_options.colored_vertex(fg, v)) // vertex is colored
{
graphics_scene.add_point(get(point_pmap, v),
gs_options.vertex_color(fg, v));
}
else
{
graphics_scene.add_point(get(point_pmap, v));
}
}
}
}
} // draw_function_for_FG
template <class FG, class GSOptions>
void add_to_graphics_scene_for_fg(const FG &fg,
CGAL::Graphics_scene &graphics_scene,
const GSOptions &gs_options)
{
draw_function_for_FG::compute_elements(fg, graphics_scene, gs_options);
}
template <class FG>
void add_to_graphics_scene_for_fg(const FG &fg,
CGAL::Graphics_scene &graphics_scene)
{
Graphics_scene_options<FG,
typename boost::graph_traits<FG>::vertex_descriptor,
typename boost::graph_traits<FG>::edge_descriptor,
typename boost::graph_traits<FG>::face_descriptor>
gs_options;
gs_options.colored_face = [](const FG&,
typename boost::graph_traits<FG>::face_descriptor) -> bool
{ return true; };
gs_options.face_color = [] (const FG&,
typename boost::graph_traits<FG>::face_descriptor fh) -> CGAL::IO::Color
{
if (fh==boost::graph_traits<FG>::null_face())
{ return CGAL::IO::Color(100, 125, 200); }
return get_random_color(CGAL::get_default_random());
};
add_to_graphics_scene_for_fg(fg, graphics_scene, gs_options);
}
} // End namespace CGAL
#endif // CGAL_USE_BASIC_VIEWER
#endif // CGAL_DRAW_SURFACE_MESH_H

View File

@ -2,7 +2,7 @@
#include <iostream>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/boost/graph/helpers.h>
#include <CGAL/boost/graph/generators.h>
typedef CGAL::Exact_predicates_exact_constructions_kernel K;
typedef K::Point_3 Point_3;

View File

@ -1,6 +1,7 @@
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/boost/graph/Euler_operations.h>
#include <CGAL/boost/graph/generators.h>
typedef CGAL::Simple_cartesian<double> K;
typedef K::Point_3 Point_3;

View File

@ -2,6 +2,7 @@
#include "test_Prefix.h"
#include <boost/range/distance.hpp>
#include <CGAL/boost/graph/Euler_operations.h>
#include <CGAL/boost/graph/generators.h>
#include <CGAL/IO/OFF.h>
#include <CGAL/Polygon_mesh_processing/border.h>

View File

@ -2,6 +2,7 @@
#include <CGAL/boost/graph/Face_filtered_graph.h>
#include <CGAL/boost/graph/named_params_helper.h>
#include <CGAL/Polygon_mesh_processing/connected_components.h>
#include <CGAL/boost/graph/generators.h>
#include <CGAL/use.h>
#include "test_Prefix.h"

View File

@ -1,6 +1,7 @@
#include <CGAL/Surface_mesh.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/boost/graph/Euler_operations.h>
#include <CGAL/boost/graph/generators.h>
#include <vector>
#include <iostream>

View File

@ -2,6 +2,7 @@ Algebraic_foundations
Arithmetic_kernel
BGL
Barycentric_coordinates_2
CGAL_Core
Cartesian_kernel
Circulator
Distance_2
@ -20,7 +21,6 @@ Number_types
Polygon
Profiling_tools
Property_map
Random_numbers
STL_Extension
Spatial_sorting
Stream_support

View File

@ -0,0 +1,173 @@
namespace CGAL {
/*!
\mainpage User Manual
\anchor Chapter_Basic_viewer
\anchor ChapterBasicViewer
\author Guillaume Damiand and Mostafa Ashraf
\cgalAutoToc
<!-- /////////////////////////////////////////////////////////////////////////////// -->
\section BV_Intro Introduction
The basic viewer package provides interactive visualization for most \cgal packages, such as
\ref PkgArrangementOnSurface2Ref "2D Arrangements",
\ref PkgBooleanSetOperations2Ref "2D Boolean Set",
\ref PkgLinearCellComplexRef "Linear cell complex",
\ref PkgNef3Ref "3D Nef",
\ref PkgPeriodic2Triangulation2Ref "2D Periodic Triangulations",
\ref PkgPointSet3Ref "3D Point Set",
\ref PkgPolygon2Ref "2D Polygon",
\ref PkgPolyhedronRef "3D Polyhedral Surface",
\ref PkgStraightSkeleton2Ref "2D Straight Skeleton",
\ref PkgSurface_mesh "Surface Mesh",
\ref PkgTriangulation2Ref "2D Triangulation",
\ref PkgTriangulation3Ref "3D Triangulation",
\ref PkgVoronoiDiagram2Ref "2D Voronoi Diagram",
and more.
The most simple use case of the basic viewer is the call of the global `draw()` function. There is one draw function for each \cgal package. Such a call opens a new interactive window showing the given model and allowing to navigate in the scene, show or hide some specific cells, show the interior of the model if any, etc.
The drawing can be tuned using `Graphics_scene_options`, for example to change the color of some cells or hide some cells.
More complex usage can be achieved by using the `Graphics_scene` class. Different \cgal data structures can be added in a same `Graphics_scene` allowing to visualize them simultaneously in a same window. Like for the draw function, the drawing parameters can be tuned thanks to the `Graphics_scene_options`.
Two classes are based on \qt.
- `CGAL::Qt::Basic_viewer` is a \qt widget that inherits from `QGLViewer` (libQGLViewer is an open source C++ library based on \qt that eases the creation of OpenGL 3D viewers).
- `CGAL::Qt::QApplication_and_basic_viewer` which regroups a `Qt::QApplication` and a `CGAL::Qt::Basic_viewer`.
<!-- /////////////////////////////////////////////////////////////////////////////// -->
\section BV_SoftwareDesign Software Design
The diagram in \cgalFigureRef{fig_basic_viewer_diagram_class} shows the main classes and functions of this package.
\cgalFigureBegin{fig_basic_viewer_diagram_class,basic_viewer_diagramme_class.svg}
UML diagram of the classes and functions of the package (only partial representation).
\cgalFigureEnd
<!-- /////////////////////////////////////////////////////////////////////////////// -->
\section BV_BasicUsage Basic Usage: The Global Draw Functions
A first simple solution provided to draw the different data structures of \cgal is the global `draw()` function. This function is templated by the type of the data structure to draw. The following example shows how it can be used.
\cgalExample{Basic_viewer/draw_lcc.cpp}
This example creates a 3D linear cell complex of a hexahedron, and draws it. The result is shown in the following figure.
\cgalFigureBegin{basic_viewer_ex1,lcc_draw.png}
Example of drawing of a 3D LCC.
\cgalFigureEnd
Users can interact with the viewer using some specific keys or mouse interactions. Pressing key 'h' makes pop up a help window showing the different shortcuts and mouse interactions. The main functionalities of the viewer are:
<ul>
<li> Versatile Rendering:
The viewer supports the rendering of various geometric elements, such as points, edges, faces, rays, and lines.
Different rendering modes, including mono and colored representation, are available for these elements.</li>
<li> Camera Control:
The viewer allows users to move the camera, switch between 2D and 3D viewing modes, adjusting the camera accordingly.
Camera settings, such as orthographic or perspective projection, can be configured based on the dimension of the scene.</li>
<li> User Interaction:
Users can interact with the viewer through keyboard inputs, enabling them to control rendering options, toggle the display of elements, and adjust visual parameters.
Key presses are mapped to specific actions, such as toggling the clipping plane, changing rendering modes, adjusting the size of elements, and modifying ambient light color.</li>
<li> Clipping Plane:
The viewer includes support for a clipping plane, enabling users to selectively render parts of the scene.
The clipping plane can be toggled on and off, and its rendering style can be modified (solid, wireframe, etc.).</li>
</ul>
\subsection BV_GraphicSceneOptions Tuning with Graphics Scene Options
There is one specialization of each draw function that takes graphics scene options as additional parameter, allowing to tune the drawing.
The `Graphics_scene_options` class provides a set of options and customization parameters for rendering geometric structures in a graphics scene. Its main purpose is to allow users to control the visual appearance of various cells such as vertices, edges, faces, and volumes in a graphical representation of a given data structure.
The following example shows how to use graphics scene options to tune the drawing of a surface mesh. We define our own class `My_graphics_scene_options` that inherits from `Graphics_scene_options` to get all the default parameters. In this class, we only override the two methods `colored_vertex` and `vertex_color` to draw all vertices in color, and chose randomly green or blue colors for one out of two vertices.
\cgalExample{Basic_viewer/draw_surface_mesh_vcolor.cpp}
The result of this example can be shown in \cgalFigureRef{basic_viewer_ex2}.
\cgalFigureBegin{basic_viewer_ex2,draw_surface_mesh_vcolor.png}
Example of tuned drawing of a 3D surface mesh where some vertex colors are changed.
\cgalFigureEnd
The drawing options can depend on the cells. In the following example the color of each face depends on its height.
\cgalExample{Basic_viewer/draw_surface_mesh_height.cpp}
The result of this example is shown in \cgalFigureRef{basic_viewer_ex3}.
\cgalFigureBegin{basic_viewer_ex3,draw_surface_height.png}
Example of mesh drawing with a color for each face computed depending on its height.
\cgalFigureEnd
<!-- /////////////////////////////////////////////////////////////////////////////// -->
\section BV_GraphicsScene The Graphics Scene
It is possible to do more advanced visualizations by using the class `Graphics_scene`. It is a container class for various geometric elements, such as points, segments, rays, lines, faces and texts. It provides several methods to add elements, possibly with individual colors. Things are a little bit different for faces. You must call `face_begin()` to start a new face (possibly with a color), add all the points in the face by using `add_point_in_face()`, and call `face_end()` to finish the face. Note that the given polygonal face is internally triangulated.
This class also stores the normal of the faces (computed automatically), and possibly the normal of the vertices that can be provided by the users.
Users can either fill directly a `Graphics_scene` using these methods, or by using a global function `add_to_graphics_scene()` that fills the scene using all the geometric elements of a given \cgal data structure. Like for the draw functions, there is an overload of `add_to_graphics_scene()` for each \cgal package.
A `Graphics_scene` can be drawn using the basic viewer thanks to the `draw_graphics_scene()` function.
The following example shows in a same viewer both a `Point_set_3` and a `Polyhedron_3`. Note that, like the draw functions, each `add_to_graphics_scene()` can use an optional `Graphics_scene_options` as parameter allowing to tune the drawing of the given data structure. In the example, we change the color of all vertices of the point set.
\cgalExample{Basic_viewer/draw_mesh_and_points.cpp}
The result of this example is shown in \cgalFigureRef{basic_viewer_ex4} where we can see in green the original points of the point cloud, superposed with the polyhedron surface reconstructed by the Poisson surface reconstruction method.
\cgalFigureBegin{basic_viewer_ex4,draw_mesh_and_points.png}
Example of drawing of a point cloud and a polyhedron in a same viewer.
\cgalFigureEnd
<!-- /////////////////////////////////////////////////////////////////////////////// -->
\section BV_BasicViewer The Basic Viewer Class
The class `CGAL::Qt::Basic_viewer` is a \qt widget that inherits from `QGLViewer` and mainly stores a `Graphics_scene` and allows to visualize it and interact with the scene. Since this class is a \qt widget, it can be used into more complex \qt code to create more advanced demos.
In the following example, we create two graphics scenes, one filled with a point cloud, a second one filled with the polyhedral surface reconstructed by the Poisson surface reconstruction method. Then, we create two basic viewers associated with these two scenes. The two basic viewers are added into a \qt layout allowing to visualize the two scenes side by side.
\cgalExample{Basic_viewer/draw_several_windows.cpp}
The result of this example is shown in \cgalFigureRef{basic_viewer_ex5}.
\cgalFigureBegin{basic_viewer_ex5,draw_several_windows.png}
Example of drawing of two `Basic_viewer` side by side.
\cgalFigureEnd
<!-- /////////////////////////////////////////////////////////////////////////////// -->
\section BV_Interactions Adding Interaction
In the previous examples, the models are only drawn once and there is no interaction with the user to update the drawing.
It is possible to define such interactions thanks to the class `CGAL::Qt::QApplication_and_basic_viewer`. In this class, you can define your own function that is called automatically by the viewer when a user presses a key. This can be used to change some parameters and update the drawing accordingly.
We illustrate this possibility in the following example that shows a surface mesh, while coloring the small faces in red. To do so, we use our own graphics scene options than change the color of a face depending on its size. A face is considered small if its size is below a certain threshold. This threshold can be updated by the user, pressing key 'I' to increase it and 'D' to decrease it. This is done in the key pressed function defined in the `QApplication_and_basic_viewer`. When the threshold changes, the graphics scene is recomputed to take the modification of the size threshold into account.
\cgalExample{Basic_viewer/draw_surface_mesh_small_faces.cpp}
The result of this example is shown in \cgalFigureRef{basic_viewer_ex6}, showing to the left the initial drawing of the 3D model, and to the right the same model after having changed the size threshold.
\cgalFigureBegin{basic_viewer_ex6,draw_surface_mesh_small_faces.png}
Two examples of drawing of a mesh with small faces in red. <B>Left</B>: With the initial threshold. <B>Right</B>: After having increased the threshold.
\cgalFigureEnd
<!-- /////////////////////////////////////////////////////////////////////////////// -->
\section BV_Design Design and Implementation History
This package was started by Mostafa Ashraf during his 2022 GSoC project. Guillaume Damiand, who mentored the project, reworked large parts of the package, wrote examples and the manual.
*/
} /* namespace CGAL */

View File

@ -0,0 +1,107 @@
namespace CGAL {
/*!
\ingroup PkgBasicViewerClasses
The class `Graphics_scene` stores points, segments, triangles, rays, and lines. Elements can be added, possibly with associated colors. Non triangular faces can be directly added and are triangulated internally.
*/
class Graphics_scene {
public:
/// adds the given point in the scene.
/// \tparam KPoint a model of `Kernel::Point_2`, `Kernel::Point_3`, `Kernel::WeightedPoint_2` or `Kernel::WeightedPoint_3`.
template <typename KPoint>
void add_point(const KPoint &p);
/// adds the given colored point in the scene.
/// \tparam KPoint a model of `Kernel::Point_2`, `Kernel::Point_3`, `Kernel::WeightedPoint_2` or `Kernel::WeightedPoint_3`.
template <typename KPoint>
void add_point(const KPoint &p, const CGAL::IO::Color &color);
/// adds the given segment in the scene.
/// \tparam KPoint a model of `Kernel::Point_2`, `Kernel::Point_3`, `Kernel::WeightedPoint_2` or `Kernel::WeightedPoint_3`.
template <typename KPoint>
void add_segment(const KPoint &p1, const KPoint &p2);
/// adds the given colored segment in the scene.
/// \tparam KPoint a model of `Kernel::Point_2`, `Kernel::Point_3`, `Kernel::WeightedPoint_2` or `Kernel::WeightedPoint_3`.
template <typename KPoint>
void add_segment(const KPoint &p1, const KPoint &p2,
const CGAL::IO::Color &color);
/// adds the given ray in the scene: a half line starting from `p` and having `v` as direction.
/// \tparam KPoint a model of `Kernel::Point_2`, `Kernel::Point_3`, `Kernel::WeightedPoint_2` or `Kernel::WeightedPoint_3`.
/// \tparam KVector a model of `Kernel::Vector_2` or `Kernel::Vector_3`.
template <typename KPoint, typename KVector>
void add_ray(const KPoint &p, const KVector &v);
/// adds the given colored ray in the scene: a half line starting from `p` and having `v` as direction.
/// \tparam KPoint a model of `Kernel::Point_2`, `Kernel::Point_3`, `Kernel::WeightedPoint_2` or `Kernel::WeightedPoint_3`.
/// \tparam KVector a model of `Kernel::Vector_2` or `Kernel::Vector_3`.
template <typename KPoint, typename KVector>
void add_ray(const KPoint &p, const KVector &v,
const CGAL::IO::Color &color);
/// adds the given line in the scene, defined by `p` and `v` as direction.
/// \tparam KPoint a model of `Kernel::Point_2`, `Kernel::Point_3`, `Kernel::WeightedPoint_2` or `Kernel::WeightedPoint_3`.
/// \tparam KVector a model of `Kernel::Vector_2` or `Kernel::Vector_3`.
template <typename KPoint, typename KVector>
void add_line(const KPoint &p, const KVector &v);
/// adds the given colored line in the scene, defined by `p` and `v` as direction.
/// \tparam KPoint a model of `Kernel::Point_2`, `Kernel::Point_3`, `Kernel::WeightedPoint_2` or `Kernel::WeightedPoint_3`.
/// \tparam KVector a model of `Kernel::Vector_2` or `Kernel::Vector_3`.
template <typename KPoint, typename KVector>
void add_line(const KPoint &p, const KVector &v,
const CGAL::IO::Color &color);
/// starts a new face.
void face_begin();
/// starts a new colored face.
void face_begin(const CGAL::IO::Color &color);
/// return `true` iff a face is started.
bool a_face_started() const;
/// adds the given point in the current face.
/// @pre `a_face_started()`
/// \tparam KPoint a model of `Kernel::Point_2`, `Kernel::Point_3`, `Kernel::WeightedPoint_2` or `Kernel::WeightedPoint_3`.
template <typename KPoint> bool add_point_in_face(const KPoint &kp);
/// adds the given point in the current face, having the vertex normal.
/// @pre `a_face_started()`
/// \tparam KPoint a model of `Kernel::Point_2`, `Kernel::Point_3`, `Kernel::WeightedPoint_2` or `Kernel::WeightedPoint_3`.
/// \tparam KVector a model of `Kernel::Vector_2` or `Kernel::Vector_3`.
template <typename KPoint, typename KVector>
bool add_point_in_face(const KPoint &kp, const KVector &p_normal);
/// ends the current face.
/// @pre `a_face_started()`
void face_end();
/// adds the given text at the given position in the scene.
/// \tparam KPoint a model of `Kernel::Point_2`, `Kernel::Point_3`, `Kernel::WeightedPoint_2` or `Kernel::WeightedPoint_3`.
template <typename KPoint>
void add_text(const KPoint &kp, const char *txt);
/// adds the given text at the given position in the scene.
/// \tparam KPoint a model of `Kernel::Point_2`, `Kernel::Point_3`, `Kernel::WeightedPoint_2` or `Kernel::WeightedPoint_3`.
template <typename KPoint>
void add_text(const KPoint &kp, const std::string &txt);
/// returns `true` iff the scene has no element.
bool empty() const;
/// clears the scene, i.e., removes all points, segments, triangles, and text.
void clear();
/// returns the bounding box of all the elements in the scene.
const CGAL::Bbox_3& bounding_box() const;
/// returns `true` if the scene is in 2D, i.e., lies on the XY or XZ or YZ plane.
bool is_two_dimensional() const;
};
} // namespace CGAL

View File

@ -0,0 +1,37 @@
namespace CGAL {
/*!
\ingroup PkgBasicViewerClasses
The class `Graphics_scene_options` is used to tune the way that the cells of a given data structure of \cgal are considered.
The different `std::function` can be modified to change for example the behavior of the drawing.
`VolumeDescriptor` can be `void` for data structures that do not represent volumes.
This class is a model of `GraphicsSceneOptions` when `VolumeDescriptor` is `void`, or a model of `GraphicsSceneOptionsWithVolumes` otherwise (`VolumeDescriptor` non `void`).
\tparam DS a data structure of \cgal.
\tparam VertexDescriptor a descriptor of vertices of `DS`.
\tparam EdgeDescriptor a descriptor of edges of `DS`.
\tparam FaceDescriptor a descriptor of faces of `DS`.
\tparam VolumeDescriptor a descriptor of volumes of `DS`. `void` by default.
\cgalModels{GraphicsSceneOptions or GraphicsSceneOptionsWithVolumes}
*/
template <typename DS,
typename VertexDescriptor,
typename EdgeDescriptor,
typename FaceDescriptor,
typename VolumeDescriptor=void>
struct Graphics_scene_options
{
public:
typedef VertexDescriptor vertex_descriptor;
typedef EdgeDescriptor edge_descriptor;
typedef FaceDescriptor face_descriptor;
typedef VolumeDescriptor volume_descriptor;
};
} // End namespace CGAL

View File

@ -0,0 +1,177 @@
namespace CGAL {
namespace Qt {
//------------------------------------------------------------------------------
/*!
\ingroup PkgBasicViewerClasses
The class `Basic_viewer` is a Qt widget based on `QGLViewer` that allows to visualize 3D elements: points, segments, triangles, rays and lines. This class stores a reference to a `Graphics_scene`. Elements are added through the scene. This class requires `CGAL_Qt6`, and is only available if the macro `CGAL_USE_BASIC_VIEWER` is defined. Linking with the cmake target `CGAL::CGAL_Basic_viewer` will link with `CGAL_Qt6` and add the definition `CGAL_USE_BASIC_VIEWER`.
CGAL::QGLViewer is our internal fork of <a href="https://github.com/GillesDebunne/libQGLViewer">QGLViewer class</a> which is <em>A versatile 3D OpenGL viewer based on QOpenGLWidget</em>.
*/
class Basic_viewer : public CGAL::QGLViewer
{
public:
/// Constructor given a pointer on a `QWidget` (can be a `nullptr`) and a `Graphics_scene`.
/// `title` will be the title of the window.
Basic_viewer(QWidget* parent,
const Graphics_scene& scene,
const char* title="");
/// enables or disables the drawing of vertices.
void draw_vertices(bool b);
/// enables or disables the drawing of edges.
void draw_edges(bool b);
/// enables or disables the drawing of rays.
void draw_rays(bool b);
/// enables or disables the drawing of lines.
void draw_lines(bool b);
/// enables or disables the drawing of faces.
void draw_faces(bool b);
/// enables or disables the use of only one color (if `b` is `true`) or the use of multiple colors (if `b` is `false`).
void use_mono_color(bool b);
/// enables or disables the drawing of texts.
void draw_text(bool b);
/// sets the color used for vertices in mono color mode.
void vertices_mono_color(const CGAL::IO::Color& c);
/// sets the color used for edges in mono color mode.
void edges_mono_color(const CGAL::IO::Color& c);
/// sets the color used for rays in mono color mode.
void rays_mono_color(const CGAL::IO::Color& c);
/// sets the color used for lines in mono color mode.
void lines_mono_color(const CGAL::IO::Color& c);
/// sets the color used for faces in mono color mode.
void faces_mono_color(const CGAL::IO::Color& c);
/// toggles the drawing of vertices.
void toggle_draw_vertices();
/// toggles the drawing of edges.
void toggle_draw_edges();
/// toggles the drawing of rays.
void toggle_draw_rays();
/// toggles the drawing of lines.
void toggle_draw_lines();
/// toggles the drawing of faces.
void toggle_draw_faces();
/// toggles the use of mono color mode.
void toggle_use_mono_color();
/// toggles the drawing of text.
void toggle_draw_text();
/// returns `true` if vertices are drawn.
bool draw_vertices() const;
/// returns `true` if edges are drawn.
bool draw_edges() const;
/// returns `true` if rays are drawn.
bool draw_rays() const;
/// returns `true` if lines are drawn.
bool draw_lines() const;
/// returns `true` if faces are drawn.
bool draw_faces() const;
/// returns `true` if mono color mode is used.
bool use_mono_color() const;
/// returns `true` if normals are reversed.
bool reverse_normal() const;
/// returns `true` if text are drawn.
bool draw_text() const;
/// returns the mono color used for vertices.
const CGAL::IO::Color& vertices_mono_color() const;
/// returns the mono color used for edges.
const CGAL::IO::Color& edges_mono_color() const;
/// returns the mono color used for rays.
const CGAL::IO::Color& rays_mono_color() const;
/// returns the mono color used for lines.
const CGAL::IO::Color& lines_mono_color() const;
/// returns the mono color used for faces.
const CGAL::IO::Color& faces_mono_color() const;
/// returns `true` if the clipping plane is enabled.
bool clipping_plane_enabled() const;
/// returns the clipping plane when it is enabled.
CGAL::Exact_predicates_inexact_constructions_kernel::Plane_3 clipping_plane() const;
/// returns the graphics scene of the viewer.
const Graphics_scene& graphics_scene() const;
/// reverses all normals of vertices and faces.
void reverse_all_normals();
/// draws the viewer without recomputing all internal buffers.
virtual void draw();
/// redraws the viewer, i.e., recompute all internal buffers and update the window.
virtual void redraw();
/// Function called when a key is pressed. Users can define their own function in order
/// to add specific behavior.
std::function<bool(QKeyEvent *, CGAL::Qt::Basic_viewer *)> on_key_pressed;
};
//------------------------------------------------------------------------------
/*!
\ingroup PkgBasicViewerClasses
The class `QApplication_and_basic_viewer` regroups a `Basic_viewer` and Qt `QApplication`. The `QApplication` is created in the constructor, but started by the `run()` method. This allows for example users to modify the `on_key_pressed` method of the `Basic_viewer` to define their own behavior.
This class requires `CGAL_Qt6`, and is only available if the macro `CGAL_USE_BASIC_VIEWER` is defined. Linking with the cmake target `CGAL::CGAL_Basic_viewer` will link with `CGAL_Qt6` and add the definition `CGAL_USE_BASIC_VIEWER`.
*/
class QApplication_and_basic_viewer
{
public:
/// Constructor given a `Graphics_scene` and possibly a title.
QApplication_and_basic_viewer(const CGAL::Graphics_scene& gs,
const char* title="CGAL Basic Viewer");
/// runs the `QApplication`, i.e., open the Qt window. A call to this method is blocking, that is the program continues as soon as the user closes the window.
void run();
/// returns a reference to the `Basic_viewer` associated with this.
Basic_viewer& basic_viewer();
};
} // End namespace Qt
//------------------------------------------------------------------------------
/*!
\ingroup PkgBasicViewerClasses
opens a new window and draws the given `Graphics_scene` (which must have been filled before). `title` will be the title of the window. A call to this method is blocking, that is the program continues as soon as the user closes the window. This function requires `CGAL_Qt6`, and is only available if the macro `CGAL_USE_BASIC_VIEWER` is defined. Linking with the cmake target `CGAL::CGAL_Basic_viewer` will link with `CGAL_Qt6` and add the definition CGAL_USE_BASIC_VIEWER.
*/
void draw_graphics_scene(const Graphics_scene& graphic_scene,
const char *title="CGAL Basic Viewer")
{}
} // End namespace CGAL

View File

@ -0,0 +1,128 @@
/*!
\ingroup PkgBasicViewerConcepts
The concept `GraphicsSceneOptions` defines data and methods used to tune the way that the cells of a given data structure of \cgal are considered for drawing or to be added into a graphics scene.
The different `std::function` can be modified to change for example the behavior of the drawing.
\cgalHasModelsBegin
\cgalHasModelsBare{\link CGAL::Graphics_scene_options `CGAL::Graphics_scene_options<DS, VertexDescriptor, EdgeDescriptor, FaceDescriptor>`\endlink}
\cgalHasModelsEnd
*/
class GraphicsSceneOptions
{
public:
/*!
A data structure of \cgal.
*/
typedef unspecified_type DS;
/*!
A descriptor of vertices of `DS`
*/
typedef unspecified_type vertex_descriptor;
/*!
A descriptor of edges of `DS`
*/
typedef unspecified_type edge_descriptor;
/*!
A descriptor of faces of `DS`
*/
typedef unspecified_type face_descriptor;
/// `std::function` that returns `true` if the given vertex must be ignored, `false` otherwise.
/// Returns `false` by default.
std::function<bool(const DS &, vertex_descriptor)> ignore_vertex;
/// `std::function` that returns `true` if the given edge must be ignored, `false` otherwise.
/// Returns `true` by default.
std::function<bool(const DS &, edge_descriptor)> ignore_edge;
/// `std::function` that returns `true` if the given face must be ignored, `false` otherwise.
/// Returns `true` by default.
std::function<bool(const DS &, face_descriptor)> ignore_face;
/// `std::function` that returns `true` if the given vertex is colored, `false` otherwise.
/// Returns `false` by default.
/// For non colored vertices, this is the role of the user of a graphic scene to decide which color must be used (cf. for example `Basic_viewer`, `vertices_mono_color`).
std::function<bool(const DS &, vertex_descriptor)> is_vertex_colored;
/// `std::function` that returns `true` if the given edge is colored, `false` otherwise.
/// For non colored edges, this is the role of the user of a graphic scene to decide which color must be used (cf. for example `Basic_viewer`, `edges_mono_color`).
/// Returns `false` by default.
std::function<bool(const DS &, edge_descriptor)> is_edge_colored;
/// `std::function` that returns `true` if the given face is colored, `false` otherwise.
/// For non colored faces, this is the role of the user of a graphic scene to decide which color must be used (cf. for example `Basic_viewer`, `faces_mono_color`).
/// Returns `false` by default.
std::function<bool(const DS &, face_descriptor)> is_face_colored;
/// `std::function` that returns `true` if the given face is in wireframe, `false` otherwise.
/// Returns `false` by default.
std::function<bool(const DS &, face_descriptor)> is_face_wireframe;
/// `std::function` that returns the color of the given vertex.
/// `nullptr` by default.
std::function<CGAL::IO::Color(const DS &, vertex_descriptor)> vertex_color;
/// `std::function` that returns the color of the given edge.
/// `nullptr` by default.
std::function<CGAL::IO::Color(const DS &, edge_descriptor)> edge_color;
/// `std::function` that returns the color of the given face.
/// `nullptr` by default.
std::function<CGAL::IO::Color(const DS &, face_descriptor)> face_color;
/// ignores all vertices when `b` is `true`; otherwise ignores only vertices for which `ignore_vertex()` returns `true`.
void ignore_all_vertices(bool b);
/// ignores all edges when `b` is `true`; otherwise ignores only edges for which `ignore_edge()` returns `true`.
void ignore_all_edges(bool b);
/// ignores all faces when `b` is `true`; otherwise ignores only faces for which `ignore_face()` returns `true`.
void ignore_all_faces(bool b);
};
/*!
\ingroup PkgBasicViewerConcepts
\cgalConcept
The concept `GraphicsSceneOptionsWithVolumes` extends the concept `GraphicsSceneOptions` to deal with data structures that represent volumes.
\cgalRefines{GraphicsSceneOptions}
\cgalHasModelsBegin
\cgalHasModelsBare{\link CGAL::Graphics_scene_options `CGAL::Graphics_scene_options<DS, VertexDescriptor, EdgeDescriptor, FaceDescriptor, VolumeDescriptor>`\endlink}
\cgalHasModelsEnd
*/
class GraphicsSceneOptionsWithVolumes
{
public:
/*!
%A descriptor of volumes of `DS`.
*/
typedef unspecified_type volume_descriptor;
/// `std::function` that returns `true` if the given volume must be ignored, `false` otherwise.
/// Returns `false` by default.
std::function<bool(const DS &, volume_descriptor)> ignore_volume;
/// `std::function` that returns `true` if the given volume is colored, `false` otherwise.
/// For non colored volumes, this is the role of the user of a graphic scene to decide which color must be used (cf. for example `Basic_viewer`, `faces_mono_color`).
/// Returns `false` by default.
std::function<bool(const DS &, volume_descriptor)> is_volume_colored;
/// `std::function` that returns `true` if the given volume is in wireframe, `false` otherwise.
/// Returns `false` by default.
std::function<bool(const DS &, volume_descriptor)> is_volume_wireframe;
/// `std::function` that returns the color of the given volume, i.e. the color of all the faces of this volume.
/// `nullptr` by default.
std::function<CGAL::IO::Color(const DS &, volume_descriptor)> volume_color;
/// ignores all volumes when `b` is `true`; otherwise ignore only volumes for which `ignore_volume()` returns `true`.
void ignore_all_volumes(bool b);
};

View File

@ -0,0 +1,5 @@
@INCLUDE = ${CGAL_DOC_PACKAGE_DEFAULTS}
PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - CGAL Basic Viewer"
EXAMPLE_PATH += ${CGAL_Surface_mesh_EXAMPLE_DIR}

View File

@ -0,0 +1,83 @@
/// \defgroup PkgBasicViewerRef Basic Viewer Reference
/// \defgroup PkgBasicViewerConcepts Concepts
/// \ingroup PkgBasicViewerRef
/// \defgroup PkgBasicViewerClasses Classes
/// \ingroup PkgBasicViewerRef
/*!
\addtogroup PkgBasicViewerRef
\cgalPkgDescriptionBegin{Basic Viewer,PkgBasicViewer}
\cgalPkgPicture{basic_viewer_logo.png}
\cgalPkgSummaryBegin
\cgalPkgAuthor{Guillaume Damiand and Mostafa Ashraf}
\cgalPkgDesc{This package provides interactive visualization for most \cgal packages.
First, the function `draw()` is provided for each data structure.
Several data structures can be added to a same graphics scene and visualized simultaneously.
Rendering can be controlled (color, point size, etc.).
Finally a \qt widget is provided that can be integrated in the GUI of a user application.}
\cgalPkgManuals{Chapter_Basic_viewer,PkgBasicViewerRef}
\cgalPkgSummaryEnd
\cgalPkgShortInfoBegin
\cgalPkgSince{6.0}
\cgalPkgBib{cgal:d-bv}
\cgalPkgLicense{\ref licensesLGPL "LGPL"}
\cgalPkgShortInfoEnd
\cgalPkgDescriptionEnd
\cgalClassifedRefPages
\cgalCRPSection{Concepts}
- `GraphicsSceneOptions`
- `GraphicsSceneOptionsWithVolumes`
\cgalCRPSection{Classes}
- `CGAL::Qt::Basic_viewer`
- `CGAL::Graphics_scene`
- `CGAL::Graphics_scene_options<DS, VertexDescriptor, EdgeDescriptor, FaceDescriptor, VolumeDescriptor>`
- `CGAL::Qt::QApplication_and_basic_viewer`
\cgalCRPSubsection{Draw a Graphics Scene}
- `CGAL::draw_graphics_scene()`
\cgalCRPSubsection{Draw for Different Packages}
- `CGAL::Arrangement_2` \link PkgArrangementOnSurface2Draw CGAL::draw<ARR>() \endlink
- `CGAL::Constrained_triangulation_2` \link PkgDrawTriangulation2 CGAL::draw<CT2>() \endlink
- `CGAL::Linear_cell_complex_for_combinatorial_map` \link PkgDrawLinearCellComplex CGAL::draw<LCC>() \endlink
- `CGAL::Linear_cell_complex_for_generalized_map` \link PkgDrawLinearCellComplex CGAL::draw<LCC>() \endlink
- `CGAL::Nef_polyhedron_3` \link PkgDrawNef3 CGAL::draw<Nef3>() \endlink
- `CGAL::Periodic_2_triangulation_2` \link PkgDrawPeriodic2Triangulation2 CGAL::draw<P2T2>() \endlink
- `CGAL::Point_set_3` \link PkgDrawPointSet3D CGAL::draw<PS>() \endlink
- `CGAL::Polygon_2` \link PkgDrawPolygon2 CGAL::draw<P2>() \endlink
- `CGAL::Polygon_set_2` \link PkgDrawPolygonSet2 CGAL::draw<PS>() \endlink
- `CGAL::Polygon_with_holes_2` \link PkgDrawPolygonWithHoles2 CGAL::draw<PH2>() \endlink
- `CGAL::Polyhedron_3` \link PkgDrawPolyhedron CGAL::draw<POLY>() \endlink
- `CGAL::Surface_mesh` \link PkgDrawSurfaceMesh CGAL::draw<SM>() \endlink
- `CGAL::Surface_mesh_topology` \link PkgDrawFaceGraphWithPaths CGAL::draw<SMT>() \endlink
- `CGAL::Triangulation_2` \link PkgDrawTriangulation2 CGAL::draw<T2>() \endlink
- `CGAL::Triangulation_3` \link PkgDrawTriangulation3 CGAL::draw<T3>() \endlink
- `CGAL::Voronoi_diagram_2` \link PkgDrawVoronoiDiagram2 CGAL::draw<V2>() \endlink
\cgalCRPSubsection{Fill Graphics Scene for Different Packages}
- `CGAL::Arrangement_2` \link PkgArrangementOnSurface2Draw CGAL::add_to_graphics_scene<ARR>() \endlink
- `CGAL::Constrained_triangulation_2` \link PkgDrawTriangulation2 CGAL::add_to_graphics_scene<CT2>() \endlink
- `CGAL::Linear_cell_complex_for_combinatorial_map` \link PkgDrawLinearCellComplex CGAL::add_to_graphics_scene<LCC>() \endlink
- `CGAL::Linear_cell_complex_for_generalized_map` \link PkgDrawLinearCellComplex CGAL::add_to_graphics_scene<LCC>() \endlink
- `CGAL::Nef_polyhedron_3` \link PkgDrawNef3 CGAL::add_to_graphics_scene<Nef3>() \endlink
- `CGAL::Periodic_2_triangulation_2` \link PkgDrawPeriodic2Triangulation2 CGAL::add_to_graphics_scene<P2T2>() \endlink
- `CGAL::Point_set_3` \link PkgDrawPointSet3D CGAL::add_to_graphics_scene<PS>() \endlink
- `CGAL::Polygon_2` \link PkgDrawPolygon2 CGAL::add_to_graphics_scene<P2>() \endlink
- `CGAL::Polygon_set_2` \link PkgDrawPolygonSet2 CGAL::add_to_graphics_scene<PS>() \endlink
- `CGAL::Polygon_with_holes_2` \link PkgDrawPolygonWithHoles2 CGAL::add_to_graphics_scene<PH2>() \endlink
- `CGAL::Polyhedron_3` \link PkgDrawPolyhedron CGAL::add_to_graphics_scene<POLY>() \endlink
- `CGAL::Surface_mesh` \link PkgDrawSurfaceMesh CGAL::add_to_graphics_scene<SM>() \endlink
- `CGAL::Surface_mesh_topology` \link PkgDrawFaceGraphWithPaths CGAL::add_to_graphics_scene<SMT>() \endlink
- `CGAL::Triangulation_2` \link PkgDrawTriangulation2 CGAL::add_to_graphics_scene<T2>() \endlink
- `CGAL::Triangulation_3` \link PkgDrawTriangulation3 CGAL::add_to_graphics_scene<T3>() \endlink
- `CGAL::Voronoi_diagram_2` \link PkgDrawVoronoiDiagram2 CGAL::add_to_graphics_scene<V2>() \endlink
*/

View File

@ -0,0 +1,16 @@
Manual
Boolean_set_operations_2
Linear_cell_complex
Nef_3
Periodic_2_triangulation_2
Point_set_3
Polygon
Polyhedron
Straight_skeleton_2
Surface_mesh
Surface_mesh_topology
Triangulation_2
Triangulation_3
Voronoi_diagram_2
Kernel_23
Arrangement_on_surface_2

View File

@ -0,0 +1,8 @@
/*!
\example Basic_viewer/draw_lcc.cpp
\example Basic_viewer/draw_mesh_and_points.cpp
\example Basic_viewer/draw_several_windows.cpp
\example Basic_viewer/draw_surface_mesh_small_faces.cpp
\example Basic_viewer/draw_surface_mesh_height.cpp
\example Basic_viewer/draw_surface_mesh_vcolor.cpp
*/

View File

@ -0,0 +1,530 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Creator: fig2dev Version 3.2.8 -->
<!-- CreationDate: 2022-05-05 19:05:07 -->
<!-- Magnification: 1.05 -->
<svg
width="541.81927pt"
height="360.14355pt"
viewBox="3588 5001 8596.4836 5695.9546"
version="1.1"
id="svg58"
sodipodi:docname="basic_viewer_diagramme_class.svg"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs62" />
<sodipodi:namedview
id="namedview60"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:document-units="pt"
showgrid="false"
inkscape:zoom="0.62947469"
inkscape:cx="453.55278"
inkscape:cy="92.934633"
inkscape:window-width="1920"
inkscape:window-height="1016"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="g56"
fit-margin-top="2"
fit-margin-left="2"
fit-margin-right="2"
fit-margin-bottom="2" />
<g
fill="none"
id="g56"
transform="translate(-78.839594,-95.293061)">
<!-- Line -->
<polyline
points=" 8767,8032 11121,8032"
stroke="#000000"
stroke-width="8px"
id="polyline2"
transform="matrix(1.2650893,0,0,1,-7207.9957,-2499.9188)" />
<!-- Line -->
<polyline
points=" 8767,8442 11121,8442"
stroke="#000000"
stroke-width="8px"
id="polyline4"
transform="matrix(1.2650893,0,0,1,-7207.9957,-2833.1034)" />
<!-- Line -->
<rect
x="3884.8591"
y="5124.895"
width="2985.0176"
height="1619.5436"
stroke="#000000"
stroke-width="11.6285px"
id="rect6" />
<!-- Line -->
<!-- Line -->
<!-- Line -->
<!-- Line -->
<polyline
points=" 3600,7623 7539,7623"
stroke="#000000"
stroke-width="8px"
id="polyline14"
transform="matrix(0.85616562,0,0,1,620.19716,800.9418)" />
<!-- Line -->
<polyline
points=" 3600,8288 7539,8288"
stroke="#000000"
stroke-width="8px"
id="polyline16"
transform="matrix(0.85616562,0,0,1,620.19716,205.96854)" />
<!-- Line -->
<rect
x="3703.8889"
y="8016.6836"
width="3369.4456"
height="2747.6394"
stroke="#000000"
stroke-width="10.6348px"
id="rect18" />
<!-- Line -->
<!-- Line -->
<!-- Line -->
<!-- Line -->
<!-- Text -->
<!-- Text -->
<text
xml:space="preserve"
x="4156.0391"
y="5409.6846"
fill="#000000"
font-family="Times"
font-style="normal"
font-weight="bold"
font-size="216px"
text-anchor="start"
id="text30">Basic_viewer</text>
<!-- Text -->
<!-- Text -->
<!-- Text -->
<!-- Text -->
<text
xml:space="preserve"
x="4009.3933"
y="8321.9365"
fill="#000000"
font-family="Times"
font-style="normal"
font-weight="bold"
font-size="216px"
text-anchor="start"
id="text38"
style="font-style:normal;font-weight:bold;font-size:216px;font-family:Times;text-anchor:start;fill:#000000"><tspan
sodipodi:role="line"
id="tspan2148"
x="4009.3933"
y="8321.9365">Graphics_scene</tspan></text>
<!-- Text -->
<text
xml:space="preserve"
x="3768.7371"
y="8751.333"
fill="#000000"
font-family="Times"
font-style="normal"
font-weight="bold"
font-size="168px"
text-anchor="start"
id="text40"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:168px;font-family:Times;-inkscape-font-specification:'Times, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-anchor:start;fill:#000000"><tspan
sodipodi:role="line"
id="tspan7344"
x="3768.7371"
y="8751.333">+ void add_point(apoint)</tspan></text>
<!-- Text -->
<text
xml:space="preserve"
x="3768.7371"
y="8989.0332"
fill="#000000"
font-family="Times"
font-style="normal"
font-weight="bold"
font-size="168px"
text-anchor="start"
id="text42"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:168px;font-family:Times;-inkscape-font-specification:'Times, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-anchor:start;fill:#000000"><tspan
sodipodi:role="line"
id="tspan7324"
x="3768.7371"
y="8989.0332">+ void add_point(apoint, acolor)</tspan></text>
<!-- Text -->
<!-- Text -->
<!-- Line -->
<!-- Line -->
<!-- Text -->
<!-- Text -->
<text
xml:space="preserve"
x="3768.7371"
y="9464.3486"
fill="#000000"
font-family="Times"
font-style="normal"
font-weight="bold"
font-size="168px"
text-anchor="start"
id="text42-5"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:168px;font-family:Times;-inkscape-font-specification:'Times, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-anchor:start;fill:#000000"><tspan
sodipodi:role="line"
id="tspan7324-2"
x="3768.7371"
y="9464.3486">+ void add_segment(apoint1, apoint2, acolor)</tspan></text>
<text
xml:space="preserve"
x="3768.7371"
y="9226.6484"
fill="#000000"
font-family="Times"
font-style="normal"
font-weight="bold"
font-size="168px"
text-anchor="start"
id="text9538-6"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:168px;font-family:Times;-inkscape-font-specification:'Times, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-anchor:start;fill:#000000"><tspan
sodipodi:role="line"
id="tspan9536-5"
x="3768.7371"
y="9226.6484">+ void add_segment(apoint1, apoint2)</tspan></text>
<text
xml:space="preserve"
x="3768.7371"
y="9939.749"
fill="#000000"
font-family="Times"
font-style="normal"
font-weight="bold"
font-size="168px"
text-anchor="start"
id="text42-8"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:168px;font-family:Times;-inkscape-font-specification:'Times, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-anchor:start;fill:#000000"><tspan
sodipodi:role="line"
id="tspan7324-7"
x="3768.7371"
y="9939.749">+ void face_begin(acolor)</tspan></text>
<text
xml:space="preserve"
x="3768.7371"
y="10177.532"
fill="#000000"
font-family="Times"
font-style="normal"
font-weight="bold"
font-size="168px"
text-anchor="start"
id="text9538-9"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:168px;font-family:Times;-inkscape-font-specification:'Times, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-anchor:start;fill:#000000"><tspan
sodipodi:role="line"
id="tspan9536-6"
x="3768.7371"
y="10177.532">+ void add_point_in_face(apoint)</tspan></text>
<text
xml:space="preserve"
x="3768.7371"
y="9702.0488"
fill="#000000"
font-family="Times"
font-style="normal"
font-weight="bold"
font-size="168px"
text-anchor="start"
id="text42-8-0"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:168px;font-family:Times;-inkscape-font-specification:'Times, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-anchor:start;fill:#000000"><tspan
sodipodi:role="line"
id="tspan7324-7-4"
x="3768.7371"
y="9702.0488">+ void face_begin()</tspan></text>
<text
xml:space="preserve"
x="3768.7371"
y="10418.341"
fill="#000000"
font-family="Times"
font-style="normal"
font-weight="bold"
font-size="168px"
text-anchor="start"
id="text42-8-0-1"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:168px;font-family:Times;-inkscape-font-specification:'Times, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-anchor:start;fill:#000000"><tspan
sodipodi:role="line"
id="tspan7324-7-4-0"
x="3768.7371"
y="10418.341">+ void face_end()</tspan></text>
<text
xml:space="preserve"
x="3767.3931"
y="10623.868"
fill="#000000"
font-family="Times"
font-style="normal"
font-weight="bold"
font-size="168px"
text-anchor="start"
id="text42-8-0-1-4"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:168px;font-family:Times;-inkscape-font-specification:'Times, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-anchor:start;fill:#000000"><tspan
sodipodi:role="line"
id="tspan7324-7-4-0-8"
x="3767.3931"
y="10623.868">...</tspan></text>
<text
xml:space="preserve"
x="3956.3384"
y="5791.0234"
fill="#000000"
font-family="Times"
font-style="normal"
font-weight="bold"
font-size="168px"
text-anchor="start"
id="text40-5"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:168px;font-family:Times;-inkscape-font-specification:'Times, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-anchor:start;fill:#000000"><tspan
sodipodi:role="line"
x="3956.3384"
y="5791.0234"
id="tspan47993">+ Basic_viewer (QWidget *parent, </tspan><tspan
sodipodi:role="line"
x="3956.3384"
y="6001.0234"
id="tspan52579"> const Graphics_scene &amp;scene)</tspan><tspan
sodipodi:role="line"
x="3956.3384"
y="6211.0234"
id="tspan47991">+ void draw()</tspan><tspan
sodipodi:role="line"
x="3956.3384"
y="6421.0234"
id="tspan57880">+ void redraw()</tspan><tspan
sodipodi:role="line"
x="3956.3384"
y="6631.0234"
id="tspan33081">...</tspan><tspan
sodipodi:role="line"
x="3956.3384"
y="6841.0234"
id="tspan57882" /></text>
<polyline
points=" 7949,8186 8767,8186"
stroke="#000000"
stroke-width="15px"
id="polyline22-9"
transform="rotate(90,7123.8213,6350.0005)" />
<polyline
points=" 7538,8183 7770,8083 7962,8175 7759,8283"
fill="#000000"
stroke="#000000"
stroke-width="8px"
id="polyline24-2"
transform="rotate(90,7124.8213,6338.0005)" />
<text
xml:space="preserve"
x="5433.3027"
y="7344.6426"
fill="#000000"
font-family="Times"
font-style="normal"
font-weight="normal"
font-size="168px"
text-anchor="start"
id="text44-9">1</text>
<polyline
points=" 8767,8032 11121,8032"
stroke="#000000"
stroke-width="8px"
id="polyline2-8"
transform="matrix(1.3689538,0,0,1,-3024.9589,-2462.3583)" />
<polyline
points=" 8767,8442 11121,8442"
stroke="#000000"
stroke-width="8px"
id="polyline4-3"
transform="matrix(1.3689538,0,0,1,-3024.9589,-2795.5429)" />
<rect
x="8978.1094"
y="5161.9849"
width="3231.1121"
height="1366.4115"
stroke="#000000"
stroke-width="11.1127px"
id="rect6-8" />
<text
xml:space="preserve"
x="9106.8584"
y="5447.2471"
fill="#000000"
font-family="Times"
font-style="normal"
font-weight="bold"
font-size="216px"
text-anchor="start"
id="text30-0">QApplication_and_basic_viewer</text>
<text
xml:space="preserve"
x="9049.9512"
y="5828.5859"
fill="#000000"
font-family="Times"
font-style="normal"
font-weight="bold"
font-size="168px"
text-anchor="start"
id="text40-5-4"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:168px;font-family:Times;-inkscape-font-specification:'Times, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-anchor:start;fill:#000000"><tspan
sodipodi:role="line"
x="9049.9512"
y="5828.5859"
id="tspan47993-0">+ QApplication_and_basic_viewer </tspan><tspan
sodipodi:role="line"
x="9049.9512"
y="6038.5859"
id="tspan52579-9"> (const Graphics_scene &amp;scene)</tspan><tspan
sodipodi:role="line"
x="9049.9512"
y="6248.5859"
id="tspan47991-1">+ void run()</tspan><tspan
sodipodi:role="line"
x="9049.9512"
y="6458.5859"
id="tspan57880-9">+ Basic_viewer &amp; basic_viewer ()</tspan><tspan
sodipodi:role="line"
x="9049.9512"
y="6668.5859"
id="tspan57882-6" /></text>
<polyline
points=" 7538,8183 7770,8083 7962,8175 7759,8283"
fill="#000000"
stroke="#000000"
stroke-width="8px"
id="polyline24-5"
transform="translate(1014.6591,-2528.5429)" />
<polyline
points=" 7949,8186 8767,8186"
stroke="#000000"
stroke-width="15px"
id="polyline22-2"
transform="matrix(2.0441703,0,0,1,-9368.5817,-2531.5429)" />
<text
xml:space="preserve"
x="8708.2236"
y="5420.084"
fill="#000000"
font-family="Times"
font-style="normal"
font-weight="normal"
font-size="168px"
text-anchor="start"
id="text44-9-9">1</text>
<text
xml:space="preserve"
x="7613.1177"
y="8591.8506"
fill="#000000"
font-family="Times"
font-style="normal"
font-weight="bold"
font-size="168px"
text-anchor="start"
id="text42-7"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:168px;font-family:Times;-inkscape-font-specification:'Times, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-anchor:start;fill:#000000"><tspan
sodipodi:role="line"
id="tspan7324-4"
x="7613.1177"
y="8591.8506">void draw_graphics_scene(const Graphics_scene&amp; gs)</tspan></text>
<text
xml:space="preserve"
x="7613.1177"
y="7146.8569"
fill="#000000"
font-family="Times"
font-style="normal"
font-weight="bold"
font-size="168px"
text-anchor="start"
id="text42-3"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:168px;font-family:Times;-inkscape-font-specification:'Times, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-anchor:start;fill:#000000"><tspan
sodipodi:role="line"
id="tspan7324-1"
x="7613.1177"
y="7146.8569">void draw(const DS&amp; ds)</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:475.979px;line-height:125%;font-family:'Times New Roman';-inkscape-font-specification:'Times New Roman';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:11.8995px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="9215.251"
y="8059.1812"
id="text63405"><tspan
sodipodi:role="line"
id="tspan63403"
style="stroke-width:11.8995px"
x="9215.251"
y="8059.1812"></tspan></text>
<text
xml:space="preserve"
x="7613.1177"
y="7505.7114"
fill="#000000"
font-family="Times"
font-style="normal"
font-weight="bold"
font-size="168px"
text-anchor="start"
id="text42-3-2"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:168px;font-family:Times;-inkscape-font-specification:'Times, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-anchor:start;fill:#000000"><tspan
sodipodi:role="line"
id="tspan7324-1-6"
x="7613.1177"
y="7505.7114">void draw(const DS&amp; ds, const Graphics_scene_option&amp; gso)</tspan></text>
<text
xml:space="preserve"
x="7613.1177"
y="7867.7578"
fill="#000000"
font-family="Times"
font-style="normal"
font-weight="bold"
font-size="168px"
text-anchor="start"
id="text42-3-1"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:168px;font-family:Times;-inkscape-font-specification:'Times, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-anchor:start;fill:#000000"><tspan
sodipodi:role="line"
id="tspan7324-1-2"
x="7613.1177"
y="7867.7578">void add_to_graphics_scene(const DS&amp; ds, Graphics_scene&amp; gs)</tspan></text>
<text
xml:space="preserve"
x="7616.6455"
y="8124.8047"
fill="#000000"
font-family="Times"
font-style="normal"
font-weight="bold"
font-size="168px"
text-anchor="start"
id="text42-3-1-8"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:168px;font-family:Times;-inkscape-font-specification:'Times, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-anchor:start;fill:#000000"><tspan
sodipodi:role="line"
id="tspan7324-1-2-8"
x="7616.6455"
y="8124.8047">void add_to_graphics_scene(const DS&amp; ds, Graphics_scene&amp; gs, </tspan><tspan
sodipodi:role="line"
x="7616.6455"
y="8334.8047"
id="tspan92018"> const Graphics_scene_option&amp; gso)</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

View File

@ -0,0 +1,41 @@
# Created by the script cgal_create_cmake_script
# This is the CMake script for compiling a CGAL application.
#/!\ /!\
#/!\ /!\
# Used in /CGAL/Documentation/doc/Documentation/Developer_manual/create_and_use_a_cmakelist.txt.
# Careful when modifying
cmake_minimum_required(VERSION 3.1...3.23)
project(Basic_viewer_Examples)
#CGAL_Qt6 is needed for the drawing.
find_package(CGAL REQUIRED OPTIONAL_COMPONENTS Qt6)
find_package(Eigen3 3.1.0)
include(CGAL_Eigen3_support)
create_single_source_cgal_program("draw_lcc.cpp")
create_single_source_cgal_program("draw_mesh_and_points.cpp")
create_single_source_cgal_program("draw_several_windows.cpp")
create_single_source_cgal_program("draw_surface_mesh_height.cpp")
create_single_source_cgal_program("draw_surface_mesh_small_faces.cpp")
create_single_source_cgal_program("draw_surface_mesh_vcolor.cpp")
if(CGAL_Qt6_FOUND)
#link it with the required CGAL libraries
target_link_libraries(draw_lcc PUBLIC CGAL::CGAL_Basic_viewer)
target_link_libraries(draw_mesh_and_points PUBLIC CGAL::CGAL_Basic_viewer)
target_link_libraries(draw_several_windows PUBLIC CGAL::CGAL_Basic_viewer)
target_link_libraries(draw_surface_mesh_height PUBLIC CGAL::CGAL_Basic_viewer)
target_link_libraries(draw_surface_mesh_small_faces PUBLIC CGAL::CGAL_Basic_viewer)
target_link_libraries(draw_surface_mesh_vcolor PUBLIC CGAL::CGAL_Basic_viewer)
else()
message("CGAL_Qt6 not configured: examples that require Qt will not be compiled.")
endif()
if(TARGET CGAL::Eigen3_support)
target_link_libraries(draw_mesh_and_points PUBLIC CGAL::Eigen3_support)
target_link_libraries(draw_several_windows PUBLIC CGAL::Eigen3_support)
endif()
#end of the file

View File

@ -0,0 +1,17 @@
#include <CGAL/Linear_cell_complex_for_combinatorial_map.h>
#include <CGAL/draw_linear_cell_complex.h>
using LCC=CGAL::Linear_cell_complex_for_combinatorial_map<3>;
using Point=LCC::Point;
int main()
{
LCC lcc;
lcc.make_hexahedron(Point(0,0,0), Point(5,0,0),
Point(5,5,0), Point(0,5,0),
Point(0,5,4), Point(0,0,4),
Point(5,0,4), Point(5,5,4));
CGAL::draw(lcc);
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,67 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/poisson_surface_reconstruction.h>
#include <CGAL/IO/read_points.h>
#include <CGAL/draw_polyhedron.h>
#include <CGAL/draw_point_set_3.h>
#include <CGAL/Graphics_scene_options.h>
#include <CGAL/Qt/Basic_viewer.h>
#include <vector>
#include <iostream>
using Kernel=CGAL::Exact_predicates_inexact_constructions_kernel;
using Point=Kernel::Point_3;
using Vector=Kernel::Vector_3;
using Pwn=std::pair<Point, Vector>;
using Polyhedron=CGAL::Polyhedron_3<Kernel>;
using PS3=CGAL::Point_set_3<Point>;
struct Graphics_scene_options_green_points:
public CGAL::Graphics_scene_options<PS3, typename PS3::const_iterator,
typename PS3::const_iterator,
typename PS3::const_iterator>
{
bool colored_vertex(const PS3&, typename PS3::const_iterator) const
{ return true; }
CGAL::IO::Color vertex_color(const PS3&, typename PS3::const_iterator) const
{ return CGAL::IO::Color(0,220,0); }
};
int main(void)
{
std::vector<Pwn> points;
if(!CGAL::IO::read_points(CGAL::data_file_path("points_3/kitten.xyz"), std::back_inserter(points),
CGAL::parameters::point_map(CGAL::First_of_pair_property_map<Pwn>())
.normal_map(CGAL::Second_of_pair_property_map<Pwn>())))
{
std::cerr << "Error: cannot read input file " << CGAL::data_file_path("points_3/kitten.xyz") << std::endl;
return EXIT_FAILURE;
}
Polyhedron output_mesh;
double average_spacing = CGAL::compute_average_spacing<CGAL::Sequential_tag>
(points, 6, CGAL::parameters::point_map(CGAL::First_of_pair_property_map<Pwn>()));
if (CGAL::poisson_surface_reconstruction_delaunay
(points.begin(), points.end(),
CGAL::First_of_pair_property_map<Pwn>(),
CGAL::Second_of_pair_property_map<Pwn>(),
output_mesh, average_spacing))
{
PS3 point_set;
for(Pwn& it: points)
{ point_set.insert(it.first); }
CGAL::Graphics_scene scene;
CGAL::add_to_graphics_scene(point_set, scene, Graphics_scene_options_green_points());
CGAL::add_to_graphics_scene(output_mesh, scene);
CGAL::draw_graphics_scene(scene);
}
else
{ return EXIT_FAILURE; }
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,91 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/poisson_surface_reconstruction.h>
#include <CGAL/IO/read_points.h>
#include <CGAL/draw_polyhedron.h>
#include <CGAL/draw_point_set_3.h>
#include <CGAL/Graphics_scene_options.h>
#include <CGAL/Qt/Basic_viewer.h>
#ifdef CGAL_USE_BASIC_VIEWER
#include <QMainWindow>
#endif
#include <vector>
#include <iostream>
using Kernel=CGAL::Exact_predicates_inexact_constructions_kernel;
using Point=Kernel::Point_3;
using Vector=Kernel::Vector_3;
using Pwn=std::pair<Point, Vector>;
using Polyhedron=CGAL::Polyhedron_3<Kernel>;
using PS3=CGAL::Point_set_3<Point>;
int main(void)
{
/// (1) Some CGAL code that create data structures and fill two Graphics_scene.
std::vector<Pwn> points;
if(!CGAL::IO::read_points(CGAL::data_file_path("points_3/kitten.xyz"), std::back_inserter(points),
CGAL::parameters::point_map(CGAL::First_of_pair_property_map<Pwn>())
.normal_map(CGAL::Second_of_pair_property_map<Pwn>())))
{
std::cerr << "Error: cannot read input file " << CGAL::data_file_path("points_3/kitten.xyz") << std::endl;
return EXIT_FAILURE;
}
Polyhedron output_mesh;
double average_spacing = CGAL::compute_average_spacing<CGAL::Sequential_tag>
(points, 6, CGAL::parameters::point_map(CGAL::First_of_pair_property_map<Pwn>()));
if (!CGAL::poisson_surface_reconstruction_delaunay
(points.begin(), points.end(),
CGAL::First_of_pair_property_map<Pwn>(),
CGAL::Second_of_pair_property_map<Pwn>(),
output_mesh, average_spacing))
{ return EXIT_FAILURE; }
PS3 point_set;
for(Pwn& it: points)
{ point_set.insert(it.first); }
CGAL::Graphics_scene scene1, scene2;
CGAL::add_to_graphics_scene(point_set, scene1);
CGAL::add_to_graphics_scene(output_mesh, scene2);
/// (2) Qt code that create windows, add them in a layout, and create app.
#ifdef CGAL_USE_BASIC_VIEWER
#if defined(CGAL_TEST_SUITE)
bool cgal_test_suite=true;
#else
bool cgal_test_suite=qEnvironmentVariableIsSet("CGAL_TEST_SUITE");
#endif
if (cgal_test_suite) { return EXIT_SUCCESS; }
int argc=1;
const char* argv[2]={"Draw several windows example","\0"};
QApplication app(argc,const_cast<char**>(argv));
QMainWindow* mainWindow=new QMainWindow;
QWidget *centralWidget = new QWidget(mainWindow);
QHBoxLayout* layout = new QHBoxLayout(mainWindow);
CGAL::Qt::Basic_viewer bv1(mainWindow, scene1);
CGAL::Qt::Basic_viewer bv2(mainWindow, scene2);
bv1.draw_vertices(true);
layout->addWidget(&bv1);
layout->addWidget(&bv2);
centralWidget->setLayout(layout);
mainWindow->setCentralWidget(centralWidget);
mainWindow->show();
app.exec();
#endif
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,67 @@
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/draw_surface_mesh.h>
#include <CGAL/Graphics_scene_options.h>
#include <iostream>
typedef CGAL::Simple_cartesian<double> Kernel;
typedef Kernel::Point_3 Point;
typedef CGAL::Surface_mesh<Point> Mesh;
struct Colored_faces_given_height:
public CGAL::Graphics_scene_options<Mesh,
typename Mesh::Vertex_index,
typename Mesh::Edge_index,
typename Mesh::Face_index>
{
Colored_faces_given_height(const Mesh& sm)
{
if(sm.is_empty()) return;
double m_min_y=0., m_max_y=0.;
bool first=true;
for(typename Mesh::Vertex_index vi: sm.vertices())
{
if(first)
{ m_min_y=sm.point(vi).y(); m_max_y=m_min_y; first=false; }
else
{
m_min_y=(std::min)(m_min_y, sm.point(vi).y());
m_max_y=(std::max)(m_max_y, sm.point(vi).y());
}
}
this->colored_face=[](const Mesh &, typename Mesh::Face_index)->bool { return true; };
this->face_color=[m_min_y, m_max_y]
(const Mesh& sm, typename Mesh::Face_index fi)->CGAL::IO::Color
{
double res=0.;
std::size_t n=0;
for(typename Mesh::Vertex_index vi: vertices_around_face(sm.halfedge(fi), sm))
{
res+=sm.point(vi).y();
++n;
}
// Random color depending on the "height" of the facet
CGAL::Random random(static_cast<unsigned int>(30*((res/n)-m_min_y)/(m_max_y-m_min_y)));
return CGAL::get_random_color(random);
};
}
};
int main(int argc, char* argv[])
{
const std::string filename = (argc>1) ? argv[1] : CGAL::data_file_path("meshes/elephant.off");
Mesh sm;
if(!CGAL::IO::read_polygon_mesh(filename, sm))
{
std::cerr << "Invalid input file: " << filename << std::endl;
return EXIT_FAILURE;
}
CGAL::draw(sm, Colored_faces_given_height(sm));
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,158 @@
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/Polygon_mesh_processing/measure.h>
#include <CGAL/Polygon_mesh_processing/triangulate_faces.h>
#include <iostream>
#include <string>
#include <cassert>
#include <CGAL/draw_surface_mesh.h>
typedef CGAL::Simple_cartesian<double> K;
typedef CGAL::Surface_mesh<K::Point_3> Mesh;
typedef Mesh::Vertex_index vertex_descriptor;
typedef Mesh::Face_index face_descriptor;
typedef K::FT FT;
template<class SM>
struct Graphics_scene_options_small_faces:
public CGAL::Graphics_scene_options<SM,
typename boost::graph_traits<SM>::vertex_descriptor,
typename boost::graph_traits<SM>::edge_descriptor,
typename boost::graph_traits<SM>::face_descriptor>
{
using Base=CGAL::Graphics_scene_options<SM,
typename boost::graph_traits<SM>::vertex_descriptor,
typename boost::graph_traits<SM>::edge_descriptor,
typename boost::graph_traits<SM>::face_descriptor>;
Graphics_scene_options_small_faces(const SM& sm): Base(), m_sm(sm)
{
typename SM::template Property_map<face_descriptor, FT> faces_size;
boost::tie(faces_size, m_with_size)=sm.template property_map<face_descriptor, FT>("f:size");
if(!m_with_size)
{ return; }
m_min_size=faces_size[*(sm.faces().begin())];
m_max_size=m_min_size;
FT cur_size;
for (typename SM::Face_range::iterator f=sm.faces().begin(); f!=sm.faces().end(); ++f)
{
cur_size=faces_size[*f];
if (cur_size<m_min_size) m_min_size=cur_size;
if (cur_size>m_max_size) m_max_size=cur_size;
}
this->face_color=[=](const SM& sm,
typename boost::graph_traits<SM>::face_descriptor fh) -> CGAL::IO::Color
{ return this->get_face_color(sm, fh); };
this->colored_face = [](const SM&,
typename boost::graph_traits<SM>::face_descriptor) -> bool
{ return true; };
}
CGAL::IO::Color get_face_color(const SM& sm,
typename boost::graph_traits<SM>::face_descriptor fh)
{
// Default color of faces
CGAL::IO::Color c(75,160,255);
if(!m_with_size) { return c; }
// Compare the size of the face with the % m_threshold
bool exist;
typename SM::template Property_map<face_descriptor, FT> faces_size;
boost::tie(faces_size, exist)=sm.template property_map<face_descriptor, FT>("f:size");
assert(exist);
// If the face is small, color it in red.
if (get(faces_size, fh)<m_min_size+((m_max_size-m_min_size)/(100-m_threshold)))
{ return CGAL::IO::Color(255,20,20); }
return c; // Default color
}
const SM& m_sm;
bool m_with_size;
FT m_min_size, m_max_size;
unsigned int m_threshold=85; // 85%
};
int main(int argc, char* argv[])
{
const std::string filename = (argc>1) ? argv[1] : CGAL::data_file_path("meshes/elephant.off");
Mesh sm;
if(!CGAL::IO::read_polygon_mesh(filename, sm))
{
std::cerr << "Invalid input file: " << filename << std::endl;
return EXIT_FAILURE;
}
CGAL::Polygon_mesh_processing::triangulate_faces(sm);
Mesh::Property_map<face_descriptor, FT> faces_size;
bool created;
boost::tie(faces_size, created)=sm.add_property_map<face_descriptor, FT>("f:size",0.);
assert(created);
for(face_descriptor fd : sm.faces())
{ faces_size[fd]=CGAL::Polygon_mesh_processing::face_area(fd, sm); }
Graphics_scene_options_small_faces gsosm(sm);
CGAL::Graphics_scene gs;
add_to_graphics_scene(sm, gs, gsosm);
#ifdef CGAL_USE_BASIC_VIEWER
CGAL::Qt::QApplication_and_basic_viewer app(gs, "Small faces");
if(app)
{
app.basic_viewer().on_key_pressed=
[&sm, &gsosm, &gs] (QKeyEvent* e, CGAL::Qt::Basic_viewer* basic_viewer) -> bool
{
const ::Qt::KeyboardModifiers modifiers = e->modifiers();
if ((e->key() == ::Qt::Key_I) && (modifiers == ::Qt::NoButton))
{
gsosm.m_threshold+=5;
if(gsosm.m_threshold>100) { gsosm.m_threshold=100; }
basic_viewer->displayMessage
(QString("Small faces threshold=%1.").arg(gsosm.m_threshold));
gs.clear();
add_to_graphics_scene(sm, gs, gsosm);
basic_viewer->redraw();
}
else if ((e->key() == ::Qt::Key_D) && (modifiers == ::Qt::NoButton))
{
if(gsosm.m_threshold<5) { gsosm.m_threshold=0; }
else { gsosm.m_threshold-=5; }
basic_viewer->displayMessage
(QString("Small faces threshold=%1.").arg(gsosm.m_threshold));
gs.clear();
add_to_graphics_scene(sm, gs, gsosm);
basic_viewer->redraw();
}
else
{
// Return false will call the base method to process others/classicals key
return false;
}
return true;
};
// Here we add shortcut descriptions
app.basic_viewer().setKeyDescription(::Qt::Key_I, "Increase threshold for small faces");
app.basic_viewer().setKeyDescription(::Qt::Key_D, "Decrease threshold for small faces");
// Then we run the app
app.run();
}
#endif
sm.remove_property_map(faces_size);
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,51 @@
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/draw_surface_mesh.h>
#include <CGAL/Graphics_scene_options.h>
#include <fstream>
using Kernel=CGAL::Simple_cartesian<double>;
using Point=Kernel::Point_3;
using Mesh=CGAL::Surface_mesh<Point>;
// Inherit from CGAL::Graphics_scene_options to get all the default values.
struct My_graphics_scene_options:
public CGAL::Graphics_scene_options<Mesh,
typename boost::graph_traits<Mesh>::vertex_descriptor,
typename boost::graph_traits<Mesh>::edge_descriptor,
typename boost::graph_traits<Mesh>::face_descriptor>
{
// All vertices are colored.
bool colored_vertex(const Mesh&,
typename boost::graph_traits<Mesh>::vertex_descriptor) const
{ return true; }
// Change the color of vertices randomly.
CGAL::IO::Color vertex_color(const Mesh&,
typename boost::graph_traits<Mesh>::vertex_descriptor) const
{
static bool v_green=true;
v_green=!v_green;
if(v_green) // 1 vertex out of two green (randomly)
{ return CGAL::IO::Color(0,220,0); }
else // the others are blue
{ return CGAL::IO::Color(0,0,220); }
}
};
int main(int argc, char* argv[])
{
const std::string filename = (argc>1) ? argv[1] : CGAL::data_file_path("meshes/elephant.off");
Mesh sm;
if(!CGAL::IO::read_polygon_mesh(filename, sm))
{
std::cerr << "Invalid input file: " << filename << std::endl;
return EXIT_FAILURE;
}
// Draw the mesh using the new graphics scene option.
CGAL::draw(sm, My_graphics_scene_options());
return EXIT_SUCCESS;
}

View File

@ -10,8 +10,8 @@
//
// Author(s) : Guillaume Damiand <guillaume.damiand@liris.cnrs.fr>
#ifndef CGAL_VBO_BUFFER_FILLER_H
#define CGAL_VBO_BUFFER_FILLER_H
#ifndef CGAL_BUFFER_FOR_VAO_H
#define CGAL_BUFFER_FOR_VAO_H
#include <CGAL/license/GraphicsView.h>
@ -125,13 +125,43 @@ namespace internal
static const typename Local_kernel::Ray_2& get_local_ray(const typename Local_kernel::Ray_2& r)
{ return r; }
};
template<typename CDT>
void mark_domains(CDT& tri,
typename CDT::Face_handle start, int index,
std::queue<typename CDT::Edge>& border)
{
if (start->info().m_nesting_level!=-1) return;
std::queue<typename CDT::Face_handle> queue;
queue.push(start);
while (!queue.empty())
{
auto fh=queue.front();
queue.pop();
if (fh->info().m_nesting_level==-1)
{
fh->info().m_nesting_level=index;
for (int i = 0; i < 3; i++)
{
typename CDT::Edge e(fh,i);
auto n = fh->neighbor(i);
if (n->info().m_nesting_level==-1)
{
if (tri.is_constrained(e)) { border.push(e); }
else { queue.push(n); }
}
}
}
}
}
} // End namespace internal
//------------------------------------------------------------------------------
template<typename BufferType=float, typename IndexType=std::size_t>
class Buffer_for_vao
{
public:
using BufferType=float;
using IndexType=std::size_t;
typedef CGAL::Exact_predicates_inexact_constructions_kernel Local_kernel;
typedef Local_kernel::Point_3 Local_point;
typedef Local_kernel::Vector_3 Local_vector;
@ -163,6 +193,7 @@ public:
if (m_index_buffer!=nullptr) { m_index_buffer->clear(); }
if (m_flat_normal_buffer!=nullptr) { m_flat_normal_buffer->clear(); }
if (m_gouraud_normal_buffer!=nullptr) { m_gouraud_normal_buffer->clear(); }
if (m_bb!=nullptr) { (*m_bb)=CGAL::Bbox_3(); }
m_zero_x=true;
m_zero_y=true;
@ -203,11 +234,10 @@ public:
bool has_zero_z() const
{ return m_zero_z; }
void negate_normals()
void negate_normals() const
{
m_inverse_normal=!m_inverse_normal;
for (std::vector<BufferType>*array=m_flat_normal_buffer; array!=nullptr;
array=(array==m_gouraud_normal_buffer?nullptr:m_gouraud_normal_buffer))
for (std::vector<BufferType>*array: {m_flat_normal_buffer, m_gouraud_normal_buffer})
{
for (std::size_t i=0; i<array->size(); ++i)
{ (*array)[i]=-(*array)[i]; }
@ -458,31 +488,31 @@ public:
/// adds `kp` coordinates to `buffer`
template<typename KPoint>
static void add_point_in_buffer(const KPoint& kp, std::vector<float>& buffer)
static void add_point_in_buffer(const KPoint& kp, std::vector<BufferType>& buffer)
{
Local_point p=get_local_point(kp);
buffer.push_back(static_cast<float>(p.x()));
buffer.push_back(static_cast<float>(p.y()));
buffer.push_back(static_cast<float>(p.z()));
buffer.push_back(static_cast<BufferType>(p.x()));
buffer.push_back(static_cast<BufferType>(p.y()));
buffer.push_back(static_cast<BufferType>(p.z()));
}
/// adds `kv` coordinates to `buffer`
template<typename KVector>
static void add_normal_in_buffer(const KVector& kv, std::vector<float>& buffer,
static void add_normal_in_buffer(const KVector& kv, std::vector<BufferType>& buffer,
bool inverse_normal=false)
{
Local_vector n=(inverse_normal?-get_local_vector(kv):get_local_vector(kv));
buffer.push_back(static_cast<float>(n.x()));
buffer.push_back(static_cast<float>(n.y()));
buffer.push_back(static_cast<float>(n.z()));
buffer.push_back(static_cast<BufferType>(n.x()));
buffer.push_back(static_cast<BufferType>(n.y()));
buffer.push_back(static_cast<BufferType>(n.z()));
}
///adds `acolor` RGB components to `buffer`
static void add_color_in_buffer(const CGAL::IO::Color& acolor, std::vector<float>& buffer)
static void add_color_in_buffer(const CGAL::IO::Color& acolor, std::vector<BufferType>& buffer)
{
buffer.push_back((float)acolor.red()/(float)255);
buffer.push_back((float)acolor.green()/(float)255);
buffer.push_back((float)acolor.blue()/(float)255);
buffer.push_back((BufferType)acolor.red()/(BufferType)255);
buffer.push_back((BufferType)acolor.green()/(BufferType)255);
buffer.push_back((BufferType)acolor.blue()/(BufferType)255);
}
/// @return true iff the points of 'facet' form a convex face
@ -737,62 +767,20 @@ protected:
{ cdt.insert_constraint(previous, first); }
}
// (2) We mark all external triangles
// (2.1) We initialize is_external and is_process values
// (2.1) We initialize nesting_level
for(typename CDT::All_faces_iterator fit = cdt.all_faces_begin(),
fitend = cdt.all_faces_end(); fit!=fitend; ++fit)
{
fit->info().is_external = true;
fit->info().is_process = false;
}
// (2.2) We check if the facet is external or internal
std::queue<typename CDT::Face_handle> face_queue, faces_internal;
if (cdt.infinite_vertex()->face()!=nullptr)
{
typename CDT::Face_circulator
incident_faces(cdt.infinite_vertex()), end_incident_faces(incident_faces);
do
{ face_queue.push(incident_faces); }
while(++incident_faces!=end_incident_faces);
}
// std::cout<<"# faces PUSHED "<<face_queue.size()<<std::endl;
while(!face_queue.empty())
{
typename CDT::Face_handle fh=face_queue.front();
face_queue.pop();
if(!fh->info().is_process)
{
fh->info().is_process=true;
for(int i=0; i<3; ++i)
{
if(!cdt.is_constrained(std::make_pair(fh, i)))
{
if (fh->neighbor(i)!=nullptr)
{ face_queue.push(fh->neighbor(i)); }
}
else
{ faces_internal.push(fh->neighbor(i)); }
}
}
}
{ fit->info().m_nesting_level=-1; }
while(!faces_internal.empty())
std::queue<typename CDT::Edge> border;
internal::mark_domains(cdt, cdt.infinite_face(), 0, border);
while(!border.empty())
{
typename CDT::Face_handle fh=faces_internal.front();
faces_internal.pop();
if(!fh->info().is_process)
{
fh->info().is_process = true;
fh->info().is_external = false;
for(unsigned int i=0; i<3; ++i)
{
if(!cdt.is_constrained(std::make_pair(fh, i)))
{
if (fh->neighbor(i)!=nullptr)
{ faces_internal.push(fh->neighbor(i)); }
}
}
}
auto e=border.front();
border.pop();
auto n=e.first->neighbor(e.second);
if (n->info().m_nesting_level==-1)
{ internal::mark_domains(cdt, n, e.first->info().m_nesting_level+1, border); }
}
// (3) Now we iterates on the internal faces to add the vertices
@ -800,7 +788,7 @@ protected:
for(typename CDT::Finite_faces_iterator ffit=cdt.finite_faces_begin(),
ffitend = cdt.finite_faces_end(); ffit!=ffitend; ++ffit)
{
if(!ffit->info().is_external)
if(ffit->info().in_domain())
{
for(unsigned int i=0; i<3; ++i)
{
@ -882,9 +870,8 @@ protected:
struct Face_info
{
bool exist_edge[3];
bool is_external;
bool is_process;
int m_nesting_level=-1;
bool in_domain() { return m_nesting_level%2==1; }
};
typedef CGAL::Projection_traits_3<CGAL::Exact_predicates_inexact_constructions_kernel> P_traits;
@ -899,8 +886,8 @@ protected:
std::vector<BufferType>* m_pos_buffer;
std::vector<IndexType>* m_index_buffer;
std::vector<BufferType>* m_color_buffer;
std::vector<BufferType>* m_flat_normal_buffer;
std::vector<BufferType>* m_gouraud_normal_buffer;
mutable std::vector<BufferType>* m_flat_normal_buffer;
mutable std::vector<BufferType>* m_gouraud_normal_buffer;
CGAL::Bbox_3* m_bb;
@ -908,7 +895,7 @@ protected:
bool m_zero_y; /// True iff all points have y==0
bool m_zero_z; /// True iff all points have z==0
bool m_inverse_normal;
mutable bool m_inverse_normal;
// Local variables, used when we started a new face.g
bool m_face_started;
@ -923,4 +910,4 @@ protected:
} // End namespace CGAL
#endif // CGAL_VBO_BUFFER_FILLER_H
#endif // CGAL_BUFFER_FOR_VAO_H

View File

@ -0,0 +1,436 @@
// Copyright (c) 2022 GeometryFactory Sarl (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s): Guillaume Damiand <guillaume.damiand@liris.cnrs.fr>
// Mostafa Ashraf <mostaphaashraf1996@gmail.com>
#ifndef CGAL_GRAPHICS_SCENE_H
#define CGAL_GRAPHICS_SCENE_H
// TODO #include <CGAL/license/GraphicsView.h>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <tuple>
#include <vector>
#include <CGAL/Cartesian_converter.h>
#include <CGAL/Constrained_Delaunay_triangulation_2.h>
#include <CGAL/Constrained_triangulation_plus_2.h>
#include <CGAL/IO/Color.h>
#include <CGAL/Projection_traits_3.h>
#include <CGAL/Triangulation_face_base_with_info_2.h>
#include <CGAL/Triangulation_vertex_base_with_info_2.h>
#include <CGAL/assertions.h>
#include <CGAL/Random.h>
#include <cstdlib>
#include <CGAL/Buffer_for_vao.h>
namespace CGAL {
//------------------------------------------------------------------------------
inline CGAL::IO::Color get_random_color(CGAL::Random& random)
{
CGAL::IO::Color res;
do
{
res=CGAL::IO::Color(random.get_int(0,256),
random.get_int(0,256),
random.get_int(0,256));
}
while(res.red()==255 && res.green()==255 && res.blue()==255);
return res;
}
//------------------------------------------------------------------------------
// This class is responsible for dealing with available CGAL data structures and
// handling buffers.
class Graphics_scene
{
public:
using BufferType=float;
typedef CGAL::Exact_predicates_inexact_constructions_kernel Local_kernel;
typedef Local_kernel::Point_3 Local_point;
typedef Local_kernel::Vector_3 Local_vector;
Graphics_scene()
: m_buffer_for_mono_points(&arrays[POS_MONO_POINTS], nullptr,
&m_bounding_box, nullptr, nullptr, nullptr),
m_buffer_for_colored_points(&arrays[POS_COLORED_POINTS], nullptr,
&m_bounding_box, &arrays[COLOR_POINTS],
nullptr, nullptr),
m_buffer_for_mono_segments(&arrays[POS_MONO_SEGMENTS], nullptr,
&m_bounding_box, nullptr, nullptr, nullptr),
m_buffer_for_colored_segments(&arrays[POS_COLORED_SEGMENTS], nullptr,
&m_bounding_box, &arrays[COLOR_SEGMENTS],
nullptr, nullptr),
m_buffer_for_mono_rays(&arrays[POS_MONO_RAYS], nullptr, &m_bounding_box,
nullptr, nullptr),
m_buffer_for_colored_rays(&arrays[POS_COLORED_RAYS], nullptr,
&m_bounding_box, &arrays[COLOR_RAYS], nullptr,
nullptr),
m_buffer_for_mono_lines(&arrays[POS_MONO_RAYS], nullptr,
&m_bounding_box, nullptr, nullptr),
m_buffer_for_colored_lines(&arrays[POS_COLORED_LINES], nullptr,
&m_bounding_box, &arrays[COLOR_LINES],
nullptr, nullptr),
m_buffer_for_mono_faces(
&arrays[POS_MONO_FACES], nullptr, &m_bounding_box, nullptr,
&arrays[FLAT_NORMAL_MONO_FACES], &arrays[SMOOTH_NORMAL_MONO_FACES]),
m_buffer_for_colored_faces(&arrays[POS_COLORED_FACES], nullptr,
&m_bounding_box, &arrays[COLOR_FACES],
&arrays[FLAT_NORMAL_COLORED_FACES],
&arrays[SMOOTH_NORMAL_COLORED_FACES])
{}
const Buffer_for_vao &get_buffer_for_mono_points() const
{ return m_buffer_for_mono_points; }
const Buffer_for_vao &get_buffer_for_colored_points() const
{ return m_buffer_for_colored_points; }
const Buffer_for_vao &get_buffer_for_mono_segments() const
{ return m_buffer_for_mono_segments; }
const Buffer_for_vao &get_buffer_for_colored_segments() const
{ return m_buffer_for_colored_segments; }
const Buffer_for_vao &get_buffer_for_mono_rays() const
{ return m_buffer_for_mono_rays; }
const Buffer_for_vao &get_buffer_for_colored_rays() const
{ return m_buffer_for_colored_rays; }
const Buffer_for_vao &get_buffer_for_mono_lines() const
{ return m_buffer_for_mono_lines; }
const Buffer_for_vao &get_buffer_for_colored_lines() const
{ return m_buffer_for_colored_lines; }
const Buffer_for_vao &get_buffer_for_mono_faces() const
{ return m_buffer_for_mono_faces; }
const Buffer_for_vao &get_buffer_for_colored_faces() const
{ return m_buffer_for_colored_faces; }
const CGAL::Bbox_3 &bounding_box() const { return m_bounding_box; }
const std::vector<BufferType> &get_array_of_index(int index) const
{ assert(index<LAST_INDEX); return arrays[index]; }
int get_size_of_index(int index) const
{ return static_cast<int>(arrays[index].size()*sizeof(BufferType)); }
unsigned int number_of_elements(int index) const
{ return static_cast<unsigned int>(arrays[index].size()/3); }
void initiate_bounding_box(const CGAL::Bbox_3& new_bounding_box)
{ m_bounding_box = new_bounding_box; }
void update_bounding_box(const CGAL::Bbox_3 &box) { m_bounding_box+=box; }
template <typename KPoint, typename KVector>
void update_bounding_box_for_ray(const KPoint &p, const KVector &v)
{
Local_point lp = get_local_point(p);
Local_vector lv = get_local_vector(v);
update_bounding_box((lp + lv).bbox());
}
template <typename KPoint, typename KVector>
void update_bounding_box_for_line(const KPoint &p, const KVector &v,
const KVector &pv)
{
Local_point lp = get_local_point(p);
Local_vector lv = get_local_vector(v);
Local_vector lpv = get_local_vector(pv);
update_bounding_box(lp.bbox() + (lp + lv).bbox() + (lp + lpv).bbox());
}
void reverse_all_normals() const
{
m_buffer_for_mono_faces.negate_normals();
m_buffer_for_colored_faces.negate_normals();
}
template <typename KPoint> void add_point(const KPoint &p)
{ m_buffer_for_mono_points.add_point(p); }
template <typename KPoint>
void add_point(const KPoint &p, const CGAL::IO::Color &acolor)
{ m_buffer_for_colored_points.add_point(p, acolor); }
template <typename KPoint>
void add_segment(const KPoint &p1, const KPoint &p2)
{ m_buffer_for_mono_segments.add_segment(p1, p2); }
template <typename KPoint>
void add_segment(const KPoint &p1, const KPoint &p2,
const CGAL::IO::Color &acolor)
{ m_buffer_for_colored_segments.add_segment(p1, p2, acolor); }
template <typename KPoint, typename KVector>
void add_ray(const KPoint &p, const KVector &v)
{
double bigNumber = 1e30;
m_buffer_for_mono_rays.add_ray_segment(p, (p + (bigNumber)*v));
}
template <typename KPoint, typename KVector>
void add_ray(const KPoint &p, const KVector &v,
const CGAL::IO::Color &acolor)
{
double bigNumber = 1e30;
m_buffer_for_colored_rays.add_ray_segment(p, (p + (bigNumber)*v), acolor);
}
template <typename KPoint, typename KVector>
void add_line(const KPoint &p, const KVector &v)
{
double bigNumber = 1e30;
m_buffer_for_mono_lines.add_line_segment((p - (bigNumber)*v),
(p + (bigNumber)*v));
}
template <typename KPoint, typename KVector>
void add_line(const KPoint &p, const KVector &v,
const CGAL::IO::Color &acolor)
{
double bigNumber = 1e30;
m_buffer_for_colored_lines.add_line_segment((p - (bigNumber)*v),
(p + (bigNumber)*v), acolor);
}
template <typename KPoint> bool add_point_in_face(const KPoint &kp)
{
if (m_buffer_for_mono_faces.is_a_face_started())
{ return m_buffer_for_mono_faces.add_point_in_face(kp); }
else if (m_buffer_for_colored_faces.is_a_face_started())
{ return m_buffer_for_colored_faces.add_point_in_face(kp); }
return false;
}
template <typename KPoint, typename KVector>
bool add_point_in_face(const KPoint &kp, const KVector &p_normal)
{
if (m_buffer_for_mono_faces.is_a_face_started())
{ return m_buffer_for_mono_faces.add_point_in_face(kp, p_normal); }
else if (m_buffer_for_colored_faces.is_a_face_started())
{ return m_buffer_for_colored_faces.add_point_in_face(kp, p_normal); }
return false;
}
bool a_face_started() const
{
return m_buffer_for_mono_faces.is_a_face_started() ||
m_buffer_for_colored_faces.is_a_face_started();
}
void face_begin()
{
if (a_face_started())
{
std::cerr
<< "You cannot start a new face before to finish the previous one."
<< std::endl;
}
else
{ m_buffer_for_mono_faces.face_begin(); }
}
void face_begin(const CGAL::IO::Color &acolor)
{
if (a_face_started())
{
std::cerr
<< "You cannot start a new face before to finish the previous one."
<< std::endl;
}
else
{ m_buffer_for_colored_faces.face_begin(acolor); }
}
void face_end()
{
if (m_buffer_for_mono_faces.is_a_face_started())
{ m_buffer_for_mono_faces.face_end(); }
else if (m_buffer_for_colored_faces.is_a_face_started())
{ m_buffer_for_colored_faces.face_end(); }
}
template <typename KPoint>
void add_text(const KPoint &kp, const std::string &txt)
{
Local_point p = get_local_point(kp);
m_texts.push_back(std::make_tuple(p, txt));
}
template <typename KPoint>
void add_text(const KPoint &kp, const char *txt)
{ add_text(kp, std::string(txt)); }
bool empty() const
{
return (m_buffer_for_mono_points.is_empty() &&
m_buffer_for_colored_points.is_empty() &&
m_buffer_for_mono_segments.is_empty() &&
m_buffer_for_colored_segments.is_empty() &&
m_buffer_for_mono_rays.is_empty() &&
m_buffer_for_colored_rays.is_empty() &&
m_buffer_for_mono_lines.is_empty() &&
m_buffer_for_colored_lines.is_empty() &&
m_buffer_for_mono_faces.is_empty() &&
m_buffer_for_colored_faces.is_empty());
}
bool has_zero_x() const
{
return m_buffer_for_mono_points.has_zero_x() &&
m_buffer_for_colored_points.has_zero_x() &&
m_buffer_for_mono_segments.has_zero_x() &&
m_buffer_for_colored_segments.has_zero_x() &&
m_buffer_for_mono_faces.has_zero_x() &&
m_buffer_for_colored_faces.has_zero_x() &&
m_buffer_for_mono_rays.has_zero_x() &&
m_buffer_for_colored_rays.has_zero_x() &&
m_buffer_for_mono_lines.has_zero_x() &&
m_buffer_for_colored_lines.has_zero_x();
}
bool has_zero_y() const
{
return m_buffer_for_mono_points.has_zero_y() &&
m_buffer_for_colored_points.has_zero_y() &&
m_buffer_for_mono_segments.has_zero_y() &&
m_buffer_for_colored_segments.has_zero_y() &&
m_buffer_for_mono_faces.has_zero_y() &&
m_buffer_for_colored_faces.has_zero_y() &&
m_buffer_for_mono_rays.has_zero_y() &&
m_buffer_for_colored_rays.has_zero_y() &&
m_buffer_for_mono_lines.has_zero_y() &&
m_buffer_for_colored_lines.has_zero_y();
}
bool has_zero_z() const
{
return m_buffer_for_mono_points.has_zero_z() &&
m_buffer_for_colored_points.has_zero_z() &&
m_buffer_for_mono_segments.has_zero_z() &&
m_buffer_for_colored_segments.has_zero_z() &&
m_buffer_for_mono_faces.has_zero_z() &&
m_buffer_for_colored_faces.has_zero_z() &&
m_buffer_for_mono_rays.has_zero_z() &&
m_buffer_for_colored_rays.has_zero_z() &&
m_buffer_for_mono_lines.has_zero_z() &&
m_buffer_for_colored_lines.has_zero_z();
}
// Returns true if the data structure lies on a XY or XZ or YZ plane
bool is_two_dimensional() const
{
return (!empty() && (has_zero_x() || has_zero_y() || has_zero_z()));
}
void clear()
{
m_buffer_for_mono_points.clear();
m_buffer_for_colored_points.clear();
m_buffer_for_mono_segments.clear();
m_buffer_for_colored_segments.clear();
m_buffer_for_mono_rays.clear();
m_buffer_for_colored_rays.clear();
m_buffer_for_mono_lines.clear();
m_buffer_for_colored_lines.clear();
m_buffer_for_mono_faces.clear();
m_buffer_for_colored_faces.clear();
m_texts.clear();
m_bounding_box=CGAL::Bbox_3();
}
template <typename KPoint>
static Local_point get_local_point(const KPoint &p)
{
return internal::Geom_utils<typename CGAL::Kernel_traits<KPoint>::Kernel,
Local_kernel>::get_local_point(p);
}
template <typename KVector>
static Local_vector get_local_vector(const KVector &v)
{
return internal::Geom_utils<typename CGAL::Kernel_traits<KVector>::Kernel,
Local_kernel>::get_local_vector(v);
}
void m_texts_clear()
{ m_texts.clear(); }
std::size_t m_texts_size() const
{ return m_texts.size(); }
const std::vector<std::tuple<Local_point, std::string>>& get_m_texts() const
{ return m_texts; }
public:
// The following enum gives the indices of different elements of arrays
// vectors.
enum Buffers {
BEGIN_POS = 0,
POS_MONO_POINTS = BEGIN_POS,
POS_COLORED_POINTS,
POS_MONO_SEGMENTS,
POS_COLORED_SEGMENTS,
POS_MONO_RAYS,
POS_COLORED_RAYS,
POS_MONO_LINES,
POS_COLORED_LINES,
POS_MONO_FACES,
POS_COLORED_FACES,
END_POS,
BEGIN_COLOR = END_POS,
COLOR_POINTS = BEGIN_COLOR,
COLOR_SEGMENTS,
COLOR_RAYS,
COLOR_LINES,
COLOR_FACES,
END_COLOR,
BEGIN_NORMAL = END_COLOR,
SMOOTH_NORMAL_MONO_FACES = BEGIN_NORMAL,
FLAT_NORMAL_MONO_FACES,
SMOOTH_NORMAL_COLORED_FACES,
FLAT_NORMAL_COLORED_FACES,
END_NORMAL,
LAST_INDEX = END_NORMAL
};
protected:
Buffer_for_vao m_buffer_for_mono_points;
Buffer_for_vao m_buffer_for_colored_points;
Buffer_for_vao m_buffer_for_mono_segments;
Buffer_for_vao m_buffer_for_colored_segments;
Buffer_for_vao m_buffer_for_mono_rays;
Buffer_for_vao m_buffer_for_colored_rays;
Buffer_for_vao m_buffer_for_mono_lines;
Buffer_for_vao m_buffer_for_colored_lines;
Buffer_for_vao m_buffer_for_mono_faces;
Buffer_for_vao m_buffer_for_colored_faces;
std::vector<std::tuple<Local_point, std::string>> m_texts;
std::vector<BufferType> arrays[LAST_INDEX];
CGAL::Bbox_3 m_bounding_box;
};
} // namespace CGAL
#endif // CGAL_GRAPHICS_SCENE_H

View File

@ -0,0 +1,127 @@
// Copyright (c) 2022 GeometryFactory Sarl (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s): Guillaume Damiand <guillaume.damiand@liris.cnrs.fr>
// Mostafa Ashraf <mostaphaashraf1996@gmail.com>
#ifndef CGAL_GRAPHICS_SCENE_OPTIONS_H
#define CGAL_GRAPHICS_SCENE_OPTIONS_H
#include <CGAL/license/GraphicsView.h>
#include <CGAL/IO/Color.h>
#include <functional>
namespace CGAL {
template <typename DS,
typename VertexDescriptor,
typename EdgeDescriptor,
typename FaceDescriptor,
typename VolumeDescriptor=void>
struct Graphics_scene_options;
// Drawing functor for a 2D combinatorial data structure
// (with vertices, edges and faces)
template <typename DS,
typename VertexDescriptor,
typename EdgeDescriptor,
typename FaceDescriptor>
struct Graphics_scene_options<DS, VertexDescriptor, EdgeDescriptor, FaceDescriptor, void>
{
typedef VertexDescriptor vertex_descriptor;
typedef EdgeDescriptor edge_descriptor;
typedef FaceDescriptor face_descriptor;
Graphics_scene_options(): m_enabled_vertices(true),
m_enabled_edges(true),
m_enabled_faces(true)
{
draw_vertex=[](const DS &, vertex_descriptor)->bool { return true; };
draw_edge=[](const DS &, edge_descriptor)->bool { return true; };
draw_face=[](const DS &, face_descriptor)->bool { return true; };
colored_vertex=[](const DS &, vertex_descriptor)->bool { return false; };
colored_edge=[](const DS &, edge_descriptor)->bool { return false; };
colored_face=[](const DS &, face_descriptor)->bool { return false; };
face_wireframe=[](const DS &, face_descriptor)->bool { return false; };
}
// The seven following functions should not be null
std::function<bool(const DS &, vertex_descriptor)> draw_vertex;
std::function<bool(const DS &, edge_descriptor)> draw_edge;
std::function<bool(const DS &, face_descriptor)> draw_face;
std::function<bool(const DS &, vertex_descriptor)> colored_vertex;
std::function<bool(const DS &, edge_descriptor)> colored_edge;
std::function<bool(const DS &, face_descriptor)> colored_face;
std::function<bool(const DS &, face_descriptor)> face_wireframe;
// These functions must be non null if the corresponding colored_XXX function
// returns true.
std::function<CGAL::IO::Color(const DS &, vertex_descriptor)> vertex_color;
std::function<CGAL::IO::Color(const DS &, edge_descriptor)> edge_color;
std::function<CGAL::IO::Color(const DS &, face_descriptor)> face_color;
void disable_vertices() { m_enabled_vertices=false; }
void enable_vertices() { m_enabled_vertices=true; }
bool are_vertices_enabled() const { return m_enabled_vertices; }
void disable_edges() { m_enabled_edges=false; }
void enable_edges() { m_enabled_edges=true; }
bool are_edges_enabled() const { return m_enabled_edges; }
void disable_faces() { m_enabled_faces=false; }
void enable_faces() { m_enabled_faces=true; }
bool are_faces_enabled() const { return m_enabled_faces; }
protected:
bool m_enabled_vertices, m_enabled_edges, m_enabled_faces;
};
// Drawing functor for a 3D combinatorial data structure
// (with vertices, edges, faces and volumes)
template <typename DS,
typename VertexDescriptor,
typename EdgeDescriptor,
typename FaceDescriptor,
typename VolumeDescriptor>
struct Graphics_scene_options:
public Graphics_scene_options<DS, VertexDescriptor, EdgeDescriptor, FaceDescriptor>
{
typedef VertexDescriptor vertex_descriptor;
typedef EdgeDescriptor edge_descriptor;
typedef FaceDescriptor face_descriptor;
typedef VolumeDescriptor volume_descriptor;
Graphics_scene_options() : m_enabled_volumes(true)
{
draw_volume=[](const DS &, volume_descriptor)->bool { return true; };
colored_volume=[](const DS &, volume_descriptor)->bool { return false; };
volume_wireframe=[](const DS &, volume_descriptor)->bool { return false; };
}
std::function<bool(const DS &, volume_descriptor)> draw_volume;
std::function<bool(const DS &, volume_descriptor)> colored_volume;
std::function<bool(const DS &, volume_descriptor)> volume_wireframe;
std::function<CGAL::IO::Color(const DS &, volume_descriptor)> volume_color;
void disable_volumes() { m_enabled_volumes=false; }
void enable_volumes() { m_enabled_volumes=true; }
bool are_volumes_enabled() const { return m_enabled_volumes; }
protected:
bool m_enabled_volumes;
};
} // End namespace CGAL
#endif // CGAL_GRAPHICS_SCENE_OPTIONS_H

View File

@ -0,0 +1,29 @@
Algebraic_foundations
Arithmetic_kernel
BGL
Basic_viewer
Cartesian_kernel
Circulator
Distance_2
Distance_3
Filtered_kernel
Hash_map
Homogeneous_kernel
Installation
Intersections_2
Intersections_3
Interval_support
Kernel_23
Kernel_d
Modular_arithmetic
Number_types
Polygon
Profiling_tools
Property_map
Random_numbers
STL_Extension
Spatial_sorting
Stream_support
TDS_2
Triangulation_2
CGAL_Core

View File

@ -0,0 +1 @@
Basic viewer

View File

@ -0,0 +1 @@
GPL (v3 or later)

View File

@ -0,0 +1,3 @@
Implementation of basic viewers.
A basic viewer allows to visualize a data structure of CGAL.

View File

@ -0,0 +1 @@
Guillaume Damiand

View File

@ -3,13 +3,94 @@ namespace CGAL {
/*!
\ingroup PkgDrawPolygonSet2
opens a new window and draws `aps`, an instance of the `CGAL::Polygon_set_2` class. A call to this function is blocking, that is the program continues as soon as the user closes the window. This function requires `CGAL_Qt6`, and is only available if the macro `CGAL_USE_BASIC_VIEWER` is defined.
Linking with the cmake target `CGAL::CGAL_Basic_viewer` will link with `CGAL_Qt6` and add the definition `CGAL_USE_BASIC_VIEWER`.
\tparam PS an instance of the `CGAL::Polygon_set_2` class.
\param aps the polygon set to draw.
The class `Graphics_scene_options_polygon_set_2` defines data and methods used to tune the way that the cells of a `Polygon_set_2` are considered for drawing or to be added into a graphics scene.
This class is a model of `GraphicsSceneOptionsPolygonSet2`.
\tparam DS a `CGAL::Polygon_set_2`.
\tparam VertexDescriptor a descriptor of vertices of `DS`.
\tparam EdgeDescriptor a descriptor of edges of `DS`.
\tparam FaceDescriptor a descriptor of faces of `DS`.
\cgalModels{GraphicsSceneOptionsPolygonSet2}
*/
template<class PS>
void draw(const PS& aps);
template <typename DS,
typename VertexDescriptor,
typename EdgeDescriptor,
typename FaceDescriptor>
struct Graphics_scene_options_polygon_set_2: public CGAL::Graphics_scene_options<DS, VertexDescriptor, EdgeDescriptor, FaceDescriptor>
{};
/*!
\ingroup PkgDrawPolygonSet2
opens a new window and draws a 2D polygon set. Parameters of the drawing are taken from the optional graphics scene options parameter.
A call to this function blocks the execution of the program until the drawing window is closed. This function requires `CGAL_Qt6`, and is only available if the macro `CGAL_USE_BASIC_VIEWER` is defined.
Linking with the cmake target `CGAL::CGAL_Basic_viewer` will link with `CGAL_Qt6` and add the definition `CGAL_USE_BASIC_VIEWER`.
\tparam PS2 which must be an instanciation of a `CGAL::Polygon_set_2<...>`.
\tparam GSOptions a model of `GraphicsSceneOptionsPolygonSet2` concept.
\param ps2 the polygon set to draw.
\param gso the graphics scene options parameter.
\cgalAdvancedBegin
The real declaration of this function template is:
<code>
template<class T, class C, class D, class GSOptions>
void CGAL::draw(const CGAL::Polygon_set_2<T, C, D>& ps2, const GSOptions& gso);
</code>
\cgalAdvancedEnd
*/
template<class PS2, class GSOptions>
void draw(const PS2& ps2, const GSOptions& gso);
/*!
\ingroup PkgDrawPolygonSet2
A shortcut to `CGAL::draw(ps2, Graphics_scene_options_polygon_set_2{})`.
*/
template<class PS2>
void draw(const PS2& ps2);
/*!
\ingroup PkgDrawPolygonSet2
adds the vertices, edges and faces of `ps2` into the given graphic scene `gs`. Parameters of the cells are taken from the optional graphics scene options parameter `gso`. Note that `gs` is not cleared before being filled (to enable to draw several data structures in the same basic viewer).
\tparam PS2 which must be an instanciation of a `CGAL::Polygon_set_2<...>`.
\tparam GSOptions a model of `GraphicsSceneOptionsPolygonSet2` concept.
\param ps2 the polygon set to draw.
\param gs the graphic scene to fill.
\param gso the graphics scene options parameter.
\cgalAdvancedBegin
The real declaration of this function template is:
<code>
template<class T, class C, class D, class GSOptions>
void CGAL::add_to_graphics_scene(const CGAL::Polygon_set_2<T, C, D>& ps2, CGAL::Graphics_scene& gs, const GSOptions& gso);
</code>
\cgalAdvancedEnd
*/
template<class PS2, class GSOptions>
void add_to_graphics_scene(const PS2& ps2,
CGAL::Graphics_scene& gs,
const GSOptions& gso);
/*!
\ingroup PkgDrawPolygonSet2
A shortcut to `CGAL::add_to_graphics_scene(ps2, gs, Graphics_scene_options_polygon_set_2{})`.
*/
template<class PS2>
void add_to_graphics_scene(const PS2& ps2,
CGAL::Graphics_scene& gs);
} /* end namespace CGAL */

View File

@ -0,0 +1,38 @@
/*!
\ingroup PkgBooleanSetOperations2Concepts
The concept `GraphicsSceneOptionsPolygonSet2` defines data and methods used to tune the way that the cells of a `Polygon_set_2` are considered for drawing or to be added into a graphics scene.
\cgalRefines{GraphicsSceneOptions}
\cgalHasModelsBegin
\cgalHasModelsBare{\link CGAL::Graphics_scene_options_polygon_set_2 `CGAL::Graphics_scene_options_polygon_set_2<DS, VertexDescriptor, EdgeDescriptor, FaceDescriptor>`\endlink}
\cgalHasModelsEnd
*/
class GraphicsSceneOptionsPolygonSet2
{
public:
/// returns the color of the unbounded face.
const CGAL::IO::Color& unbounded_face_color() const;
/// sets the color of the unbounded face to `c`.
void unbounded_face_color(const CGAL::IO::Color& c);
/// returns `true` if the unbounded face must be drawn, `false` otherwise.
/// Returns `false` by default.
bool draw_unbounded() const;
/// sets the draw of unbounded face to `b`.
void draw_unbounded(bool b);
/// toggles the draw unbounded face value.
void toggle_draw_unbounded();
/// returns the height of the box used to draw the unbounded face.
int height() const;
/// returns the width of the box used to draw the unbounded face.
int width() const;
/// sets the height of the box used to draw the unbounded face to `i`.
void height(int i);
/// sets the width of the box used to draw the unbounded face to `i`.
void width(int i);
};

View File

@ -69,6 +69,8 @@ containment predicates.
- \link boolean_connect_holes `CGAL::connect_holes()` \endlink
\cgalCRPSection{Draw a Polygon_set_2}
- \link PkgDrawPolygonSet2 CGAL::draw<PS>() \endlink
- \link PkgDrawPolygonSet2 CGAL::draw<PS>() \endlink
- `GraphicsSceneOptionsPolygonSet2`
- `CGAL::Graphics_scene_options_polygon_set_2`
*/

View File

@ -19,40 +19,159 @@
#include <CGAL/license/Boolean_set_operations_2.h>
#include <CGAL/Qt/Basic_viewer_qt.h>
#ifdef DOXYGEN_RUNNING
namespace CGAL {
/*!
* \ingroup PkgDrawPolygonSet2
*
* opens a new window and draws `aps`, an instance of the `CGAL::Polygon_set_2`
* class. A call to this function is blocking, that is the program continues as
* soon as the user closes the window. This function requires `CGAL_Qt6`, and is
* only available if the macro `CGAL_USE_BASIC_VIEWER` is defined. Linking with
* the cmake target `CGAL::CGAL_Basic_viewer` will link with `CGAL_Qt6` and add
* the definition `CGAL_USE_BASIC_VIEWER`.
* \tparam PS an instance of the `CGAL::Polygon_set_2` class.
* \param aps the polygon set to draw.
*/
template<class PS>
void draw(const PS& aps);
} /* namespace CGAL */
#endif
#ifdef CGAL_USE_BASIC_VIEWER
#include <CGAL/Qt/init_ogl_context.h>
#include <CGAL/Qt/Basic_viewer.h>
#include <CGAL/Graphics_scene.h>
#include <CGAL/Graphics_scene_options.h>
#include <CGAL/Polygon_set_2.h>
namespace CGAL {
template <typename PolygonSet_2>
class Polygon_set_2_basic_viewer_qt : public Basic_viewer_qt {
using Base = Basic_viewer_qt;
template <typename DS,
typename VertexDescriptor,
typename EdgeDescriptor,
typename FaceDescriptor>
struct Graphics_scene_options_polygon_set_2 :
public CGAL::Graphics_scene_options<DS, VertexDescriptor, EdgeDescriptor, FaceDescriptor>
{
void unbounded_face_color(const CGAL::IO::Color& c)
{ m_unbounded_face_color=c; }
const CGAL::IO::Color& unbounded_face_color() const
{ return m_unbounded_face_color; }
bool draw_unbounded() const
{ return m_draw_unbounded; }
void draw_unbounded(bool b)
{ m_draw_unbounded=b; }
void toggle_draw_unbounded()
{ m_draw_unbounded=!m_draw_unbounded; }
int height() const
{ return m_height; }
int width() const
{ return m_width; }
void height(int i)
{ m_height=i; }
void width(int i)
{ m_width=i; }
protected:
bool m_draw_unbounded=true;
CGAL::IO::Color m_unbounded_face_color=CGAL::IO::Color(75,160,255);
int m_width=0, m_height=0;
};
namespace draw_function_for_boolean_set_2 {
template <typename PS2, class GSOptions>
void compute_loop(const typename PS2::Polygon_2& p, bool hole,
CGAL::Graphics_scene& gs,
const GSOptions& gso)
{
if (gso.are_faces_enabled() && hole)
{ gs.add_point_in_face(p.vertex(p.size()-1)); }
auto prev = p.vertices_begin();
auto it = prev;
// First vertex
if (gso.are_vertices_enabled() && gso.draw_vertex(p, it))
{
if(gso.colored_vertex(p, it))
{ gs.add_point(*it, gso.vertex_color(p, it)); }
else
{ gs.add_point(*it); }
}
if (gso.are_faces_enabled())
{ gs.add_point_in_face(*it); }
// Other vertices
for (++it; it!=p.vertices_end(); ++it)
{
if (gso.are_vertices_enabled() && gso.draw_vertex(p, it))
{ // Add point
if(gso.colored_vertex(p, it))
{ gs.add_point(*it, gso.vertex_color(p, it)); }
else
{ gs.add_point(*it); }
}
if (gso.are_edges_enabled() && gso.draw_edge(p, prev))
{ // Add segment with previous point
if(gso.colored_edge(p, prev))
{ gs.add_segment(*prev, *it, gso.edge_color(p, prev)); }
else
{ gs.add_segment(*prev, *it); }
}
if (gso.are_faces_enabled())
{ gs.add_point_in_face(*it); } // add point in face
prev = it;
}
// Last segment (between last and first point)
if (gso.are_edges_enabled() && gso.draw_edge(p, prev))
{
if(gso.colored_edge(p, prev))
{ gs.add_segment(*prev, *(p.vertices_begin()), gso.edge_color(p, prev)); }
else
{ gs.add_segment(*prev, *(p.vertices_begin())); }
}
}
/// Compute the elements of a polygon with holes.
template <typename PWH, class GSOptions>
void compute_elements(const PWH& pwh,
CGAL::Graphics_scene& gs,
const GSOptions& gso)
{
if (!gso.draw_unbounded() && pwh.outer_boundary().is_empty()) return;
if (gso.are_faces_enabled())
{ gs.face_begin(gso.unbounded_face_color()); }
using Pnt=typename PWH::Polygon_2::Point_2;
const Pnt* point_in_face=nullptr;
if (pwh.outer_boundary().is_empty())
{
if(gso.width()!=0 && gso.height()!=0)
{
typename PWH::Polygon_2 pgn;
pgn.push_back(Pnt(-gso.width(), -gso.height()));
pgn.push_back(Pnt(gso.width(), -gso.height()));
pgn.push_back(Pnt(gso.width(), gso.height()));
pgn.push_back(Pnt(-gso.width(), gso.height()));
draw_function_for_boolean_set_2::compute_loop<PWH>(pgn, false, gs, gso);
point_in_face = &(pgn.vertex(pgn.size()-1));
}
}
else
{
const auto& outer_boundary = pwh.outer_boundary();
draw_function_for_boolean_set_2::compute_loop<PWH>(outer_boundary, false, gs, gso);
point_in_face = &(outer_boundary.vertex(outer_boundary.size()-1));
}
for (auto it = pwh.holes_begin(); it != pwh.holes_end(); ++it)
{
draw_function_for_boolean_set_2::compute_loop<PWH>(*it, true, gs, gso);
if (gso.are_faces_enabled() && point_in_face && point_in_face!=nullptr)
{ gs.add_point_in_face(*point_in_face); }
}
if (gso.are_faces_enabled())
{ gs.face_end(); }
}
} // End namespace draw_function_for_boolean_set_2
#ifdef CGAL_USE_BASIC_VIEWER
template <typename PolygonSet_2, typename GSOptions>
class Polygon_set_2_basic_viewer_qt : public Basic_viewer
{
using Base = Basic_viewer;
using Ps = PolygonSet_2;
using Pwh = typename Ps::Polygon_with_holes_2;
using Pgn = typename Ps::Polygon_2;
@ -60,13 +179,15 @@ class Polygon_set_2_basic_viewer_qt : public Basic_viewer_qt {
public:
Polygon_set_2_basic_viewer_qt(QWidget* parent, const Ps& ps,
const char* title = "Basic Polygon_set_2 Viewer",
bool draw_unbounded = false,
bool draw_vertices = false) :
Base(parent, title, draw_vertices),
GSOptions& gs_options,
const char* title = "Basic Polygon_set_2 Viewer") :
Base(parent, graphics_scene, title),
m_ps(ps),
m_draw_unbounded(draw_unbounded)
gso(gs_options)
{
gso.width(CGAL_BASIC_VIEWER_INIT_SIZE_X);
gso.height(CGAL_BASIC_VIEWER_INIT_SIZE_Y);
if (ps.is_empty()) return;
// mimic the computation of Camera::pixelGLRatio()
@ -74,37 +195,39 @@ public:
CGAL::qglviewer::Vec minv(bbox.xmin(), bbox.ymin(), 0);
CGAL::qglviewer::Vec maxv(bbox.xmax(), bbox.ymax(), 0);
auto diameter = (maxv - minv).norm();
m_pixel_ratio = diameter / m_height;
m_pixel_ratio = diameter / gso.height();
}
/*! Intercept the resizing of the window.
*/
virtual void resizeGL(int width, int height) {
CGAL::QGLViewer::resizeGL(width, height);
m_width = width;
m_height = height;
gso.width(width);
gso.height(height);
CGAL::qglviewer::Vec p;
auto ratio = camera()->pixelGLRatio(p);
if (ratio != m_pixel_ratio) {
auto ratio = this->camera()->pixelGLRatio(p);
if (ratio != m_pixel_ratio)
{
m_pixel_ratio = ratio;
add_elements();
}
}
/*! Compute the elements of a polygon set.
*/
virtual void add_elements() {
clear();
std::vector<Pwh> pwhs;
m_ps.polygons_with_holes(std::back_inserter(pwhs));
for (const auto& pwh : pwhs) add_elements(pwh);
}
/*! Obtain the pixel ratio.
*/
double pixel_ratio() const { return m_pixel_ratio; }
/*! Compute the elements of a polygon set.
*/
virtual void add_elements()
{
graphics_scene.clear();
std::vector<Pwh> pwhs;
m_ps.polygons_with_holes(std::back_inserter(pwhs));
for (const auto& pwh : pwhs)
{ draw_function_for_boolean_set_2::compute_elements(pwh, graphics_scene, gso); }
}
/*! Compute the bounding box.
*/
CGAL::Bbox_2 bounding_box() {
@ -122,64 +245,7 @@ public:
return bbox;
}
protected:
/*! Compute the elements of a polygon with holes.
*/
void add_elements(const Pwh& pwh) {
if (! m_draw_unbounded && pwh.outer_boundary().is_empty()) return;
CGAL::IO::Color c(75,160,255);
face_begin(c);
const Pnt* point_in_face;
if (pwh.outer_boundary().is_empty()) {
Pgn pgn;
pgn.push_back(Pnt(-m_width, -m_height));
pgn.push_back(Pnt(m_width, -m_height));
pgn.push_back(Pnt(m_width, m_height));
pgn.push_back(Pnt(-m_width, m_height));
compute_loop(pgn, false);
point_in_face = &(pgn.vertex(pgn.size()-1));
}
else {
const auto& outer_boundary = pwh.outer_boundary();
compute_loop(outer_boundary, false);
point_in_face = &(outer_boundary.vertex(outer_boundary.size()-1));
}
for (auto it = pwh.holes_begin(); it != pwh.holes_end(); ++it) {
compute_loop(*it, true);
add_point_in_face(*point_in_face);
}
face_end();
}
void compute_loop(const Pgn& p, bool hole) {
if (hole) add_point_in_face(p.vertex(p.size()-1));
auto prev = p.vertices_begin();
auto it = prev;
add_point(*it);
add_point_in_face(*it);
for (++it; it != p.vertices_end(); ++it) {
add_point(*it); // add vertex
add_segment(*prev, *it); // add segment with previous point
add_point_in_face(*it); // add point in face
prev = it;
}
// Add the last segment between the last point and the first one
add_segment(*prev, *(p.vertices_begin()));
}
private:
//! The window width in pixels.
int m_width = CGAL_BASIC_VIEWER_INIT_SIZE_X;
//! The window height in pixels.
int m_height = CGAL_BASIC_VIEWER_INIT_SIZE_Y;
//! The ratio between pixel and opengl units (in world coordinate system).
double m_pixel_ratio = 1;
@ -188,14 +254,39 @@ private:
//! Indicates whether to draw unbounded polygons with holes.
bool m_draw_unbounded = false;
Graphics_scene graphics_scene;
GSOptions& gso;
};
// Specialization of draw function.
#endif // CGAL_USE_BASIC_VIEWER
#define CGAL_PS2_TYPE CGAL::Polygon_set_2<T, C, D>
// Specializations of add_to_graphics_scene function
template<class T, class C, class D, class GSOptions>
void add_to_graphics_scene(const CGAL_PS2_TYPE& ap2,
CGAL::Graphics_scene& graphics_scene,
const GSOptions& gso)
{ draw_function_for_boolean_set_2::compute_elements(ap2, graphics_scene, gso); }
template<class T, class C, class D>
void draw(const CGAL::Polygon_set_2<T, C, D>& ps,
const char* title = "Polygon_set_2 Basic Viewer",
bool draw_vertices = false,
bool draw_unbounded = false)
void add_to_graphics_scene(const CGAL_PS2_TYPE& ap2,
CGAL::Graphics_scene &graphics_scene)
{
CGAL::Graphics_scene_options_polygon_set_2<typename CGAL_PS2_TYPE::Polygon_2,
typename CGAL_PS2_TYPE::Vertex_const_iterator,
typename CGAL_PS2_TYPE::Vertex_const_iterator,
void*> gso;
draw_function_for_boolean_set_2::compute_elements(ap2, graphics_scene, gso);
}
#ifdef CGAL_USE_BASIC_VIEWER
// Specialization of draw function.
template<class T, class C, class D, class GSOptions>
void draw(const CGAL_PS2_TYPE& ps, GSOptions& gso,
const char* title = "Polygon_set_2 Basic Viewer")
{
#if defined(CGAL_TEST_SUITE)
bool cgal_test_suite = true;
@ -203,22 +294,35 @@ void draw(const CGAL::Polygon_set_2<T, C, D>& ps,
bool cgal_test_suite = qEnvironmentVariableIsSet("CGAL_TEST_SUITE");
#endif
if (! cgal_test_suite) {
if (! cgal_test_suite)
{
using Ps = CGAL::Polygon_set_2<T, C, D>;
using Viewer = Polygon_set_2_basic_viewer_qt<Ps>;
using Viewer = Polygon_set_2_basic_viewer_qt<Ps, GSOptions>;
CGAL::Qt::init_ogl_context(4,3);
int argc = 1;
const char* argv[2] = {"t2_viewer", nullptr};
QApplication app(argc, const_cast<char**>(argv));
Viewer mainwindow(app.activeWindow(), ps, title, draw_unbounded, draw_vertices);
mainwindow.add_elements();
mainwindow.show();
Viewer basic_viewer(app.activeWindow(), ps, gso, title);
basic_viewer.show();
app.exec();
}
}
} // End namespace CGAL
template<class T, class C, class D>
void draw(const CGAL_PS2_TYPE& ps,
const char* title = "Polygon_set_2 Basic Viewer")
{
CGAL::Graphics_scene_options_polygon_set_2<typename CGAL_PS2_TYPE::Polygon_2,
typename CGAL_PS2_TYPE::Polygon_2::Vertex_const_iterator,
typename CGAL_PS2_TYPE::Polygon_2::Vertex_const_iterator,
void*> gso;
draw(ps, gso, title);
}
#endif // CGAL_USE_BASIC_VIEWER
#undef CGAL_PS2_TYPE
} // End namespace CGAL
#endif // CGAL_DRAW_POLYGON_SET_2_H

View File

@ -1,14 +1,16 @@
Algebraic_foundations
Arithmetic_kernel
Arrangement_on_surface_2
BGL
Basic_viewer
Boolean_set_operations_2
CGAL_Core
Cartesian_kernel
Circular_kernel_2
Circulator
Distance_2
Distance_3
Filtered_kernel
GraphicsView
HalfedgeDS
Hash_map
Homogeneous_kernel
@ -22,7 +24,12 @@ Modular_arithmetic
Number_types
Polygon
Profiling_tools
Property_map
Random_numbers
STL_Extension
Spatial_sorting
Stream_support
Surface_sweep_2
TDS_2
Triangulation_2
Union_find

View File

@ -9,4 +9,5 @@ if(NOT CGAL_Core_FOUND)
return()
endif()
create_single_source_cgal_program("zero-one.cpp")
create_single_source_cgal_program("delaunay.cpp")

View File

@ -0,0 +1,32 @@
#include <CGAL/CORE_Expr.h>
typedef CORE::Expr Real;
int main()
{
Real r(3.14);
CGAL::is_zero(r);
CGAL::is_one(r);
r = CGAL::sqrt(r);
CGAL::is_zero(r);
CGAL::is_one(r);
r = r * r;
CGAL::is_zero(r);
CGAL::is_one(r);
r = r - r;
CGAL::is_zero(r);
return 0;
}

View File

@ -59,7 +59,7 @@ public:
/// constructor for <tt>const char* </tt>(default base = 10)
BigFloat(const char* s) : RCBigFloat(new BigFloatRep(s)) {}
/// constructor for <tt>std::string</tt>(default base = 10)
BigFloat(const std::string& s) : RCBigFloat(new BigFloatRep(s)) {}
BigFloat(const std::string& s) : RCBigFloat(new BigFloatRep(s.c_str())) {}
/// constructor for <tt>int</tt> and <tt>long</tt>
// This is a hack because in Sturm, we need to approximate any
@ -106,6 +106,9 @@ public:
explicit BigFloat(BigFloatRep* r, bool) : RCBigFloat(r) {
}
operator BigRat() const {
return this->BigRatValue();
}
//@}
@ -510,32 +513,6 @@ inline long minStar(long m, long n) {
}
/// \name Functions for Compatibility with BigInt (needed by Poly, Curves)
//@{
/// isDivisible(a,b) = "is a divisible by b"
/** Assuming that a and b are in coanonized forms.
Defined to be true if mantissa(b) | mantissa(a) &&
exp(b) = min*(exp(b), exp(a)).
* This concepts assume a and b are exact BigFloats.
*/
inline bool isDivisible(const BigFloat& a, const BigFloat& b) {
// assert: a and b are exact BigFloats.
if (sign(a.m()) == 0) return true;
if (sign(b.m()) == 0) return false;
unsigned long bin_a = getBinExpo(a.m());
unsigned long bin_b = getBinExpo(b.m());
BigInt m_a = a.m() >> bin_a;
BigInt m_b = b.m() >> bin_b;
long e_a = bin_a + BigFloatRep::bits(a.exp());
long e_b = bin_b + BigFloatRep::bits(b.exp());
long dx = minStar(e_a, e_b);
return isDivisible(m_a, m_b) && (dx == e_b);
}
inline bool isDivisible(double x, double y) {
//Are these exact?
return isDivisible(BigFloat(x), BigFloat(y));
}
/// div_exact(x,y) returns the BigFloat quotient of x divided by y
/** This is defined only if isDivisible(x,y).
@ -548,7 +525,6 @@ inline bool isDivisible(double x, double y) {
// normalizing it then we get zero.
inline BigFloat div_exact(const BigFloat& x, const BigFloat& y) {
BigInt z;
CGAL_assertion (isDivisible(x,y));
unsigned long bin_x = getBinExpo(x.m());
unsigned long bin_y = getBinExpo(y.m());
@ -615,15 +591,20 @@ inline BigFloat gcd(const BigFloat& a, const BigFloat& b) {
//}//
// constructor BigRat from BigFloat
inline BigRat::BigRat(const BigFloat& f) : RCBigRat(new BigRatRep()){
*this = f.BigRatValue();
inline double doubleValue(const BigFloat& bf)
{
return bf.doubleValue();
}
inline long longValue(const BigFloat& bf)
{
return bf.longValue();
}
} //namespace CORE
#ifdef CGAL_HEADER_ONLY
#include <CGAL/CORE/BigFloat_impl.h>
#include <CGAL/CORE/CoreIO_impl.h>
#endif // CGAL_HEADER_ONLY
#include <CGAL/enable_warnings.h>

View File

@ -317,7 +317,7 @@ inline void BigFloatRep::eliminateTrailingZeroes() {
// builtin functions
inline extLong BigFloatRep::lMSB() const {
if (!isZeroIn())
return extLong(floorLg(abs(m) - err)) + bits(exp);
return extLong(floorLg(BigInt(abs(m) - err))) + bits(exp);
else
return extLong(CORE_negInfty);
}
@ -327,7 +327,7 @@ inline extLong BigFloatRep::lMSB() const {
* Not well-defined if zero is in the interval.
*/
inline extLong BigFloatRep::uMSB() const {
return extLong(floorLg(abs(m) + err)) + bits(exp);
return extLong(floorLg(BigInt(abs(m) + err))) + bits(exp);
}
inline extLong BigFloatRep::MSB() const {

View File

@ -194,8 +194,7 @@ void BigFloatRep :: truncM(const BigFloatRep& B, const extLong& r, const extLong
err = 2;
exp = B.exp + t;
} else // t < chunkCeil(clLg(B.err))
core_error(std::string("BigFloat error: truncM called with stricter")
+ "precision than current error.", __FILE__, __LINE__, true);
CGAL_error_msg("BigFloat error: truncM called with stricter precision than current error.");
} else {// B.m == 0
long t = chunkFloor(- a.asLong()) - B.exp;
@ -204,8 +203,7 @@ void BigFloatRep :: truncM(const BigFloatRep& B, const extLong& r, const extLong
err = 1;
exp = B.exp + t;
} else // t < chunkCeil(clLg(B.err))
core_error(std::string("BigFloat error: truncM called with stricter")
+ "precision than current error.", __FILE__, __LINE__, true);
CGAL_error_msg("BigFloat error: truncM called with stricter precision than current error.");
}
}
@ -216,7 +214,7 @@ CGAL_INLINE_FUNCTION
void BigFloatRep::approx(const BigFloatRep& B,
const extLong& r, const extLong& a) {
if (B.err) {
if (1 + clLg(B.err) <= bitLength(B.m))
if (static_cast<std::size_t>(1 + clLg(B.err)) <= bitLength(B.m))
truncM(B, r + 1, a);
else // 1 + clLg(B.err) > lg(B.m)
truncM(B, CORE_posInfty, a);
@ -258,7 +256,7 @@ void BigFloatRep::div(const BigInt& N, const BigInt& D,
exp = 0;
}
} else // D == 0
core_error( "BigFloat error: zero divisor.", __FILE__, __LINE__, true);
CGAL_error_msg( "BigFloat error: zero divisor.");
// Call normalization globally -- IP 10/9/98
normal();
@ -455,6 +453,7 @@ void BigFloatRep::centerize(const BigFloatRep& a, const BigFloatRep& b) {
// Zilin & Vikram, 08/24/04
// err = 1 + longValue(chunkShift(r.m, r.exp - exp));
BigInt E = chunkShift(r.m, r.exp - exp);
E = abs(E);
bigNormal(E);
}
@ -538,8 +537,7 @@ void BigFloatRep :: div(const BigFloatRep& x, const BigFloatRep& y,
bigNormal(bigErr);
}
} else {// y.m <= y.err
core_error("BigFloat error: possible zero divisor.",
__FILE__, __LINE__, true);
CGAL_error_msg("BigFloat error: possible zero divisor.");
}
// Call normalization globally -- IP 10/9/98
@ -734,8 +732,7 @@ void BigFloatRep::sqrt(const BigFloatRep& x, const extLong& a, const BigFloat& A
} // end of case with error in mantissa
}//else
} else
core_error("BigFloat error: squareroot called with negative operand.",
__FILE__, __LINE__, true);
CGAL_error_msg("BigFloat error: squareroot called with negative operand.");
} //sqrt with initial approximation
// compareMExp(x)
@ -822,8 +819,7 @@ BigFloatRep::toDecimal(unsigned int width, bool Scientific) const {
if (err > 0 && err >= abs(m)) {
// if err is larger than mantissa, sign and significant values
// can not be determined.
core_error("BigFloat error: Error is too big!",
__FILE__, __LINE__, false);
CGAL_CORE_warning_msg(true, "BigFloat error: Error is too big!");
decOut.rep = "0.0e0"; // error is too big
decOut.isScientific = false;
decOut.noSignificant = 0;
@ -869,7 +865,7 @@ BigFloatRep::toDecimal(unsigned int width, bool Scientific) const {
M <<= e2; // M = x * 2^(e2)
}
std::string decRep = M.get_str();
std::string decRep = M.convert_to<std::string>();
// Determine the "significant part" of this string, i.e. the part which
// is guaranteed to be correct in the presence of error,
// except that the last digit which might be subject to +/- 1.
@ -1003,8 +999,7 @@ void BigFloatRep :: fromString(const char *str, extLong prec ) {
// NOTE: prec defaults to get_static_defBigFloatInputDigits() (see BigFloat.h)
// check that prec is not INFTY
if (prec.isInfty())
core_error("BigFloat error: infinite precision not allowed",
__FILE__, __LINE__, true);
CGAL_error_msg("BigFloat error: infinite precision not allowed");
const char *e = strchr(str, 'e');
int dot = 0;

View File

@ -24,448 +24,113 @@
#ifndef _CORE_BIGINT_H_
#define _CORE_BIGINT_H_
#include <CGAL/CORE/Gmp.h>
#include <CGAL/boost_mp_type.h>
#include <CGAL/CORE/RefCount.h>
#include <CGAL/CORE/MemoryPool.h>
#include <string>
#if !(defined(CGAL_CORE_USE_BOOST_BACKEND) && BOOST_VERSION > 107900 && defined(CGAL_USE_BOOST_MP)) && !defined(CGAL_DISABLE_GMP)
#define CGAL_CORE_USE_GMP_BACKEND 1
#endif
namespace CORE {
#ifdef CGAL_CORE_USE_GMP_BACKEND
typedef boost::multiprecision::mpz_int BigInt;
#else
typedef boost::multiprecision::cpp_int BigInt;
#endif
class BigIntRep : public RCRepImpl<BigIntRep> {
public:
BigIntRep() {
mpz_init(mp);
}
// Note : should the copy-ctor be allowed at all ? [Sylvain Pion]
BigIntRep(const BigIntRep& z) : RCRepImpl<BigIntRep>() {
mpz_init_set(mp, z.mp);
}
BigIntRep(signed char c) {
mpz_init_set_si(mp, c);
}
BigIntRep(unsigned char c) {
mpz_init_set_ui(mp, c);
}
BigIntRep(signed int i) {
mpz_init_set_si(mp, i);
}
BigIntRep(unsigned int i) {
mpz_init_set_ui(mp, i);
}
BigIntRep(signed short int s) {
mpz_init_set_si(mp, s);
}
BigIntRep(unsigned short int s) {
mpz_init_set_ui(mp, s);
}
BigIntRep(signed long int l) {
mpz_init_set_si(mp, l);
}
BigIntRep(unsigned long int l) {
mpz_init_set_ui(mp, l);
}
BigIntRep(float f) {
mpz_init_set_d(mp, f);
}
BigIntRep(double d) {
mpz_init_set_d(mp, d);
}
BigIntRep(const char* s, int base=0) {
mpz_init_set_str(mp, s, base);
}
BigIntRep(const std::string& s, int base=0) {
mpz_init_set_str(mp, s.c_str(), base);
}
explicit BigIntRep(mpz_srcptr z) {
mpz_init_set(mp, z);
}
~BigIntRep() {
mpz_clear(mp);
}
CGAL_CORE_EXPORT CORE_NEW(BigIntRep)
CGAL_CORE_EXPORT CORE_DELETE(BigIntRep)
mpz_srcptr get_mp() const {
return mp;
}
mpz_ptr get_mp() {
return mp;
}
private:
mpz_t mp;
};
typedef RCImpl<BigIntRep> RCBigInt;
class CGAL_CORE_EXPORT BigInt : public RCBigInt {
public:
/// \name Constructors
//@{
/// default constructor
BigInt() : RCBigInt(new BigIntRep()) {}
/// constructor for <tt>signed char</tt>
BigInt(signed char x) : RCBigInt(new BigIntRep(x)) {}
/// constructor for <tt>unsigned char</tt>
BigInt(unsigned char x) : RCBigInt(new BigIntRep(x)) {}
/// constructor for <tt>signed short int</tt>
BigInt(signed short int x) : RCBigInt(new BigIntRep(x)) {}
/// constructor for <tt>unsigned short int</tt>
BigInt(unsigned short int x) : RCBigInt(new BigIntRep(x)) {}
/// constructor for <tt>signed int</tt>
BigInt(signed int x) : RCBigInt(new BigIntRep(x)) {}
/// constructor for <tt>unsigned int</tt>
BigInt(unsigned int x) : RCBigInt(new BigIntRep(x)) {}
/// constructor for <tt>signed long int</tt>
BigInt(signed long int x) : RCBigInt(new BigIntRep(x)) {}
/// constructor for <tt>unsigned long int</tt>
BigInt(unsigned long int x) : RCBigInt(new BigIntRep(x)) {}
/// constructor for <tt>float</tt>
BigInt(float x) : RCBigInt(new BigIntRep(x)) {}
/// constructor for <tt>double</tt>
BigInt(double x) : RCBigInt(new BigIntRep(x)) {}
/// constructor for <tt>const char*</tt> with base
BigInt(const char* s, int base=0) : RCBigInt(new BigIntRep(s, base)) {}
/// constructor for <tt>std::string</tt> with base
BigInt(const std::string& s, int base=0) : RCBigInt(new BigIntRep(s, base)) {}
/// constructor for <tt>mpz_srcptr</tt>
explicit BigInt(mpz_srcptr z) : RCBigInt(new BigIntRep(z)) {}
//@}
/// \name Copy-Assignment-Destructor
//@{
/// copy constructor
BigInt(const BigInt& rhs) : RCBigInt(rhs) {
rep->incRef();
}
/// assignment operator
BigInt& operator=(const BigInt& rhs) {
if (this != &rhs) {
rep->decRef();
rep = rhs.rep;
rep->incRef();
}
return *this;
}
/// destructor
~BigInt() {
rep->decRef();
}
//@}
/// \name Overloaded operators
//@{
BigInt& operator +=(const BigInt& rhs) {
makeCopy();
mpz_add(get_mp(), get_mp(), rhs.get_mp());
return *this;
}
BigInt& operator -=(const BigInt& rhs) {
makeCopy();
mpz_sub(get_mp(), get_mp(), rhs.get_mp());
return *this;
}
BigInt& operator *=(const BigInt& rhs) {
makeCopy();
mpz_mul(get_mp(), get_mp(), rhs.get_mp());
return *this;
}
BigInt& operator /=(const BigInt& rhs) {
makeCopy();
mpz_tdiv_q(get_mp(), get_mp(), rhs.get_mp());
return *this;
}
BigInt& operator %=(const BigInt& rhs) {
makeCopy();
mpz_tdiv_r(get_mp(), get_mp(), rhs.get_mp());
return *this;
}
BigInt& operator &=(const BigInt& rhs) {
makeCopy();
mpz_and(get_mp(), get_mp(), rhs.get_mp());
return *this;
}
BigInt& operator |=(const BigInt& rhs) {
makeCopy();
mpz_ior(get_mp(), get_mp(), rhs.get_mp());
return *this;
}
BigInt& operator ^=(const BigInt& rhs) {
makeCopy();
mpz_xor(get_mp(), get_mp(), rhs.get_mp());
return *this;
}
BigInt& operator <<=(unsigned long ul) {
makeCopy();
mpz_mul_2exp(get_mp(), get_mp(), ul);
return *this;
}
BigInt& operator >>=(unsigned long ul) {
makeCopy();
mpz_tdiv_q_2exp(get_mp(), get_mp(), ul);
return *this;
}
//@}
/// \name unary, increment, decrement operators
//@{
BigInt operator+() const {
return BigInt(*this);
}
BigInt operator-() const {
BigInt r;
mpz_neg(r.get_mp(), get_mp());
return r;
}
BigInt& operator++() {
makeCopy();
mpz_add_ui(get_mp(), get_mp(), 1);
return *this;
}
BigInt& operator--() {
makeCopy();
mpz_sub_ui(get_mp(), get_mp(), 1);
return *this;
}
BigInt operator++(int) {
BigInt r(*this);
++(*this);
return r;
}
BigInt operator--(int) {
BigInt r(*this);
--(*this);
return r;
}
//@}
/// \name Helper Functions
//@{
/// Has Exact Division
static bool hasExactDivision() {
return false;
}
/// get mpz pointer (const)
mpz_srcptr get_mp() const {
return rep->get_mp();
}
/// get mpz pointer
mpz_ptr get_mp() {
return rep->get_mp();
}
//@}
/// \name String Conversion Functions
//@{
/// set value from <tt>const char*</tt>
int set_str(const char* s, int base = 0) {
makeCopy();
return mpz_set_str(get_mp(), s, base);
}
/// convert to <tt>std::string</tt>
std::string get_str(int base = 10) const {
int n = mpz_sizeinbase (get_mp(), base) + 2;
char *buffer = new char[n];
mpz_get_str(buffer, base, get_mp());
std::string result(buffer);
delete [] buffer;
return result;
}
//@}
/// \name Conversion Functions
//@{
/// intValue
int intValue() const {
return static_cast<int>(mpz_get_si(get_mp()));
}
/// longValue
long longValue() const {
return mpz_get_si(get_mp());
}
/// ulongValue
unsigned long ulongValue() const {
return mpz_get_ui(get_mp());
}
/// doubleValue
double doubleValue() const {
return mpz_get_d(get_mp());
}
//@}
};
inline BigInt operator+(const BigInt& a, const BigInt& b) {
BigInt r;
mpz_add(r.get_mp(), a.get_mp(), b.get_mp());
return r;
}
inline BigInt operator-(const BigInt& a, const BigInt& b) {
BigInt r;
mpz_sub(r.get_mp(), a.get_mp(), b.get_mp());
return r;
}
inline BigInt operator*(const BigInt& a, const BigInt& b) {
BigInt r;
mpz_mul(r.get_mp(), a.get_mp(), b.get_mp());
return r;
}
inline BigInt operator/(const BigInt& a, const BigInt& b) {
BigInt r;
mpz_tdiv_q(r.get_mp(), a.get_mp(), b.get_mp());
return r;
}
inline BigInt operator%(const BigInt& a, const BigInt& b) {
BigInt r;
mpz_tdiv_r(r.get_mp(), a.get_mp(), b.get_mp());
return r;
}
inline BigInt operator&(const BigInt& a, const BigInt& b) {
BigInt r;
mpz_and(r.get_mp(), a.get_mp(), b.get_mp());
return r;
}
inline BigInt operator|(const BigInt& a, const BigInt& b) {
BigInt r;
mpz_ior(r.get_mp(), a.get_mp(), b.get_mp());
return r;
}
inline BigInt operator^(const BigInt& a, const BigInt& b) {
BigInt r;
mpz_xor(r.get_mp(), a.get_mp(), b.get_mp());
return r;
}
inline BigInt operator<<(const BigInt& a, unsigned long ul) {
BigInt r;
mpz_mul_2exp(r.get_mp(), a.get_mp(), ul);
return r;
}
inline BigInt operator>>(const BigInt& a, unsigned long ul) {
BigInt r;
mpz_tdiv_q_2exp(r.get_mp(), a.get_mp(), ul);
return r;
}
inline int cmp(const BigInt& x, const BigInt& y) {
return mpz_cmp(x.get_mp(), y.get_mp());
}
inline bool operator==(const BigInt& a, const BigInt& b) {
return cmp(a, b) == 0;
}
inline bool operator!=(const BigInt& a, const BigInt& b) {
return cmp(a, b) != 0;
}
inline bool operator>=(const BigInt& a, const BigInt& b) {
return cmp(a, b) >= 0;
}
inline bool operator>(const BigInt& a, const BigInt& b) {
return cmp(a, b) > 0;
}
inline bool operator<=(const BigInt& a, const BigInt& b) {
return cmp(a, b) <= 0;
}
inline bool operator<(const BigInt& a, const BigInt& b) {
return cmp(a, b) < 0;
return x.compare(y);
}
inline std::ostream& operator<<(std::ostream& o, const BigInt& x) {
//return CORE::operator<<(o, x.get_mp());
return CORE::io_write(o, x.get_mp());
}
inline std::istream& operator>>(std::istream& i, BigInt& x) {
x.makeCopy();
//return CORE::operator>>(i, x.get_mp());
return CORE::io_read(i, x.get_mp());
}
/// sign
inline int sign(const BigInt& a) {
return mpz_sgn(a.get_mp());
}
/// abs
inline BigInt abs(const BigInt& a) {
BigInt r;
mpz_abs(r.get_mp(), a.get_mp());
return r;
}
/// neg
inline BigInt neg(const BigInt& a) {
BigInt r;
mpz_neg(r.get_mp(), a.get_mp());
return r;
}
/// negate
inline void negate(BigInt& a) {
a.makeCopy();
mpz_neg(a.get_mp(), a.get_mp());
}
/// cmpabs
inline int cmpabs(const BigInt& a, const BigInt& b) {
return mpz_cmpabs(a.get_mp(), b.get_mp());
}
inline int set_str(BigInt& a, const char* s) {
a = BigInt(s);
return 0; // should be -1 if not correct in the base (we ignore)
}
/// \name Conversion Functions
//@{
/// longValue
/// longValue
inline long longValue(const BigInt& a) {
return a.longValue();
return a.convert_to<long>();
}
/// ulongValue
inline unsigned long ulongValue(const BigInt& a) {
return a.ulongValue();
}
/// doubleValue
/// doubleValue
inline double doubleValue(const BigInt& a) {
return a.doubleValue();
return a.convert_to<double>();
}
//@}
/// \name File I/O Functions
//@{
/// read from file
void readFromFile(BigInt& z, std::istream& in, long maxLength = 0);
/// write to file
void writeToFile(const BigInt& z, std::ostream& in, int base=10, int charsPerLine=80);
//@}
/// \name Misc Functions
//@{
/// isEven
/// isEven
inline bool isEven(const BigInt& z) {
return mpz_even_p(z.get_mp());
return bit_test(z,0) == 0;
}
/// isOdd
inline bool isOdd(const BigInt& z) {
return mpz_odd_p(z.get_mp());
return bit_test(z,0) == 1;
}
/// get exponent of power 2
inline unsigned long getBinExpo(const BigInt& z) {
return mpz_scan1(z.get_mp(), 0);
}
/// get exponent of power k
inline void getKaryExpo(const BigInt& z, BigInt& m, int& e, unsigned long k) {
mpz_t f;
mpz_init_set_ui(f, k);
m.makeCopy();
e = mpz_remove(m.get_mp(), z.get_mp(), f);
mpz_clear(f);
}
/// divisible(x,y) = "x | y"
inline bool isDivisible(const BigInt& x, const BigInt& y) {
return mpz_divisible_p(x.get_mp(), y.get_mp()) != 0;
BigInt q, r;
divide_qr(x, y, q, r);
return r.is_zero();
}
inline bool isDivisible(int x, int y) {
return x % y == 0;
}
inline bool isDivisible(long x, long y) {
return x % y == 0;
}
/// exact div
/// get exponent of power 2
inline std::size_t getBinExpo(const BigInt& z) {
if (z.is_zero()) {
return (std::numeric_limits<std::size_t>::max)();
}
return lsb(abs(z));
}
// bit length
inline std::size_t bitLength(const BigInt& a){
if (a.is_zero()) {
return 0;
}
return msb(abs(a))+1;
}
/// floorLg -- floor of log_2(a)
/** Convention: a=0, floorLg(a) returns -1.
* This makes sense for integer a.
*/
inline long floorLg(const BigInt& a) {
assert(std::size_t((std::numeric_limits<long>::max)()) > bitLength(a));
return (sign(a) == 0) ? (-1) : static_cast<long>(bitLength(a)-1);
}
/// div_rem
inline void div_rem(BigInt& q, BigInt& r, const BigInt& a, const BigInt& b) {
divide_qr(a, b, q, r);
}
/// ulongValue
inline unsigned long ulongValue(const BigInt& a) {
assert(a >= BigInt(0));
return a.convert_to<unsigned long>();
}
/// exact div
inline void divexact(BigInt& z, const BigInt& x, const BigInt& y) {
z.makeCopy();
mpz_divexact(z.get_mp(), x.get_mp(), y.get_mp());
BigInt r;
divide_qr(x, y, z, r ); // was void mpz_divexact (mpz_t q, const mpz_t n, const mpz_t d) Is this faster?
assert(r.is_zero());
}
// Chee (1/12/2004) The definition of div_exact(x,y) next
// ensure that in Polynomials<NT> works with both NT=BigInt and NT=int:
inline BigInt div_exact(const BigInt& x, const BigInt& y) {
@ -473,50 +138,19 @@ inline BigInt div_exact(const BigInt& x, const BigInt& y) {
divexact(z, x, y); // z is set to x/y;
return z;
}
inline int div_exact(int x, int y) {
return x/y; // precondition: isDivisible(x,y)
}
inline long div_exact(long x, long y) {
return x/y; // precondition: isDivisible(x,y)
}
/// gcd
inline BigInt gcd(const BigInt& a, const BigInt& b) {
BigInt r;
mpz_gcd(r.get_mp(), a.get_mp(), b.get_mp());
return r;
}
/// div_rem
inline void div_rem(BigInt& q, BigInt& r, const BigInt& a, const BigInt& b) {
q.makeCopy();
r.makeCopy();
mpz_tdiv_qr(q.get_mp(), r.get_mp(), a.get_mp(), b.get_mp());
}
/// power
inline void power(BigInt& c, const BigInt& a, unsigned long ul) {
c.makeCopy();
mpz_pow_ui(c.get_mp(), a.get_mp(), ul);
inline BigInt gcd(const BigInt& a, const BigInt& b){
return boost::multiprecision::gcd(a,b);
}
// pow
inline BigInt pow(const BigInt& a, unsigned long ui) {
BigInt r;
power(r, a, ui);
return r;
}
// bit length
inline int bitLength(const BigInt& a) {
return mpz_sizeinbase(a.get_mp(), 2);
}
/// floorLg -- floor of log_2(a)
/** Convention: a=0, floorLg(a) returns -1.
* This makes sense for integer a.
*/
inline long floorLg(const BigInt& a) {
return (sign(a) == 0) ? (-1) : (bitLength(a)-1);
}
/// ceilLg -- ceiling of log_2(a) where a=BigInt, int or long
/** Convention: a=0, ceilLg(a) returns -1.
* This makes sense for integer a.
@ -524,20 +158,45 @@ inline long floorLg(const BigInt& a) {
inline long ceilLg(const BigInt& a) {
if (sign(a) == 0)
return -1;
unsigned long len = bitLength(a);
return (mpz_scan1(a.get_mp(), 0) == len-1) ? (len-1) : len;
assert(std::size_t((std::numeric_limits<long>::max)()) > bitLength(a));
std::size_t len = static_cast<long>(bitLength(a));
return (lsb(abs(a)) == len - 1) ? (static_cast<long>(len) - 1) : static_cast<long>(len);
}
inline long ceilLg(long a) { // need this for Polynomial<long>
return ceilLg(BigInt(a));
}
inline long ceilLg(int a) { // need this for Polynomial<int>
return ceilLg(BigInt(a));
}
//@}
/// negate
inline void negate(BigInt& a) {
a= - a;
}
/// get exponent of power k
inline void getKaryExpo(const BigInt& z, BigInt& m, int& e, unsigned long uk) {
BigInt k(uk), q, r;
e = 0;
m = z;
for(;;) {
divide_qr(m, k, q, r);
if (!r.is_zero()) break;
m = q;
++e;
}
}
inline void power(BigInt& c, const BigInt& a, unsigned long ul) {
c = pow(a, ul);
}
} // namespace CORE
} //namespace CORE
#endif // _CORE_BIGINT_H_

View File

@ -28,354 +28,35 @@
#include <CGAL/CORE/BigInt.h>
namespace CORE {
#ifdef CGAL_CORE_USE_GMP_BACKEND
typedef boost::multiprecision::mpq_rational BigRat;
#else
typedef boost::multiprecision::cpp_rational BigRat;
#endif
class BigRatRep : public RCRepImpl<BigRatRep> {
public:
BigRatRep() {
mpq_init(mp);
}
// Note : should the copy-ctor be allowed at all ? [Sylvain Pion]
BigRatRep(const BigRatRep& z) : RCRepImpl<BigRatRep>() {
mpq_init(mp);
mpq_set(mp, z.mp);
}
BigRatRep(signed char c) {
mpq_init(mp);
mpq_set_si(mp, c, 1);
}
BigRatRep(unsigned char c) {
mpq_init(mp);
mpq_set_ui(mp, c, 1);
}
BigRatRep(signed int i) {
mpq_init(mp);
mpq_set_si(mp, i, 1);
}
BigRatRep(unsigned int i) {
mpq_init(mp);
mpq_set_ui(mp, i, 1);
}
BigRatRep(signed short int s) {
mpq_init(mp);
mpq_set_si(mp, s, 1);
}
BigRatRep(unsigned short int s) {
mpq_init(mp);
mpq_set_ui(mp, s, 1);
}
BigRatRep(signed long int l) {
mpq_init(mp);
mpq_set_si(mp, l, 1);
}
BigRatRep(unsigned long int l) {
mpq_init(mp);
mpq_set_ui(mp, l, 1);
}
BigRatRep(float f) {
mpq_init(mp);
mpq_set_d(mp, f);
}
BigRatRep(double d) {
mpq_init(mp);
mpq_set_d(mp, d);
}
BigRatRep(const char* s) {
mpq_init(mp);
mpq_set_str(mp, s, 0);
}
BigRatRep(const std::string& s) {
mpq_init(mp);
mpq_set_str(mp, s.c_str(), 0);
}
explicit BigRatRep(mpq_srcptr q) {
mpq_init(mp);
mpq_set(mp, q);
}
BigRatRep(mpz_srcptr z) {
mpq_init(mp);
mpq_set_z(mp, z);
}
BigRatRep(mpz_srcptr n, mpz_srcptr d) {
mpq_init(mp);
mpz_set(mpq_numref(mp), n);
mpz_set(mpq_denref(mp), d);
mpq_canonicalize(mp);
}
~BigRatRep() {
mpq_clear(mp);
inline BigInt numerator(const BigRat& q)
{
return boost::multiprecision::numerator(q);
}
CGAL_CORE_EXPORT CORE_NEW(BigRatRep)
CGAL_CORE_EXPORT CORE_DELETE(BigRatRep)
mpq_srcptr get_mp() const {
return mp;
}
mpq_ptr get_mp() {
return mp;
}
private:
mpq_t mp;
}; //BigRatRep
class BigFloat;
typedef RCImpl<BigRatRep> RCBigRat;
class BigRat : public RCBigRat {
public:
/// \name Constructors
//@{
/// default constructor
BigRat() : RCBigRat(new BigRatRep()) {}
/// constructor for <tt>signed char</tt>
BigRat(signed char x) : RCBigRat(new BigRatRep(x)) {}
/// constructor for <tt>unsigned char</tt>
BigRat(unsigned char x) : RCBigRat(new BigRatRep(x)) {}
/// constructor for <tt>signed short int</tt>
BigRat(signed short int x) : RCBigRat(new BigRatRep(x)) {}
/// constructor for <tt>unsigned short int</tt>
BigRat(unsigned short int x) : RCBigRat(new BigRatRep(x)) {}
/// constructor for <tt>signed int</tt>
BigRat(signed int x) : RCBigRat(new BigRatRep(x)) {}
/// constructor for <tt>unsigned int</tt>
BigRat(unsigned int x) : RCBigRat(new BigRatRep(x)) {}
/// constructor for <tt>signed long int</tt>
BigRat(signed long int x) : RCBigRat(new BigRatRep(x)) {}
/// constructor for <tt>unsigned long int</tt>
BigRat(unsigned long int x) : RCBigRat(new BigRatRep(x)) {}
/// constructor for <tt>float</tt>
BigRat(float x) : RCBigRat(new BigRatRep(x)) {}
/// constructor for <tt>double</tt>
BigRat(double x) : RCBigRat(new BigRatRep(x)) {}
/// constructor for <tt>const char*</tt> with base
BigRat(const char* s) : RCBigRat(new BigRatRep(s)) {}
/// constructor for <tt>std::string</tt> with base
BigRat(const std::string& s) : RCBigRat(new BigRatRep(s)) {}
/// constructor for <tt>mpq_srcptr</tt>
explicit BigRat(mpq_srcptr z) : RCBigRat(new BigRatRep(z)) {}
/// constructor for <tt>BigInt</tt>
BigRat(const BigInt& z) : RCBigRat(new BigRatRep(z.get_mp())) {}
/// constructor for two <tt>BigInts</tt>
BigRat(const BigInt& n, const BigInt& d)
: RCBigRat(new BigRatRep(n.get_mp(), d.get_mp())) {}
/// constructor for <tt>BigFloat</tt>
BigRat(const BigFloat&);
//@}
/// \name Copy-Assignment-Destructor
//@{
/// copy constructor
BigRat(const BigRat& rhs) : RCBigRat(rhs) {
rep->incRef();
}
/// assignment operator
BigRat& operator=(const BigRat& rhs) {
if (this != &rhs) {
rep->decRef();
rep = rhs.rep;
rep->incRef();
}
return *this;
}
/// destructor
~BigRat() {
rep->decRef();
}
//@}
/// \name Overloaded operators
//@{
BigRat& operator +=(const BigRat& rhs) {
makeCopy();
mpq_add(get_mp(), get_mp(), rhs.get_mp());
return *this;
}
BigRat& operator -=(const BigRat& rhs) {
makeCopy();
mpq_sub(get_mp(), get_mp(), rhs.get_mp());
return *this;
}
BigRat& operator *=(const BigRat& rhs) {
makeCopy();
mpq_mul(get_mp(), get_mp(), rhs.get_mp());
return *this;
}
BigRat& operator /=(const BigRat& rhs) {
makeCopy();
mpq_div(get_mp(), get_mp(), rhs.get_mp());
return *this;
}
BigRat& operator <<=(unsigned long ul) {
makeCopy();
mpq_mul_2exp(get_mp(), get_mp(), ul);
return *this;
}
BigRat& operator >>=(unsigned long ul) {
makeCopy();
mpq_div_2exp(get_mp(), get_mp(), ul);
return *this;
}
//@}
/// \name div2, unary, increment, decrement operators
//@{
/// exact division by 2 (this method is provided for compatibility)
BigRat div2() const {
BigRat r; BigRat t(2); // probably not most efficient way
mpq_div(r.get_mp(), get_mp(), t.get_mp());
return r;
}
BigRat operator+() const {
return BigRat(*this);
}
BigRat operator-() const {
BigRat r;
mpq_neg(r.get_mp(), get_mp());
return r;
}
BigRat& operator++() {
makeCopy();
mpz_add(get_num_mp(),get_num_mp(),get_den_mp());
return *this;
}
BigRat& operator--() {
makeCopy();
mpz_sub(get_num_mp(),get_num_mp(),get_den_mp());
return *this;
}
BigRat operator++(int) {
BigRat r(*this);
++(*this);
return r;
}
BigRat operator--(int) {
BigRat r(*this);
--(*this);
return r;
}
//@}
/// \name Helper Functions
//@{
/// Canonicalize
void canonicalize() {
makeCopy();
mpq_canonicalize(get_mp());
}
/// Has Exact Division
static bool hasExactDivision() {
return true;
inline BigInt denominator(const BigRat& q)
{
return boost::multiprecision::denominator(q);
}
/// return mpz pointer of numerator (const)
mpz_srcptr get_num_mp() const {
return mpq_numref(get_mp());
}
/// return mpz pointer of numerator
mpz_ptr get_num_mp() {
return mpq_numref(get_mp());
}
/// return mpz pointer of denominator
mpz_srcptr get_den_mp() const {
return mpq_denref(get_mp());
}
/// return mpz pointer of denominator
mpz_ptr get_den_mp() {
return mpq_denref(get_mp());
}
/// get mpq pointer (const)
mpq_srcptr get_mp() const {
return rep->get_mp();
}
/// get mpq pointer
mpq_ptr get_mp() {
return rep->get_mp();
}
//@}
/// \name String Conversion Functions
//@{
/// set value from <tt>const char*</tt>
int set_str(const char* s, int base = 0) {
makeCopy();
return mpq_set_str(get_mp(), s, base);
}
/// convert to <tt>std::string</tt>
std::string get_str(int base = 10) const {
int n = mpz_sizeinbase(mpq_numref(get_mp()), base) + mpz_sizeinbase(mpq_denref(get_mp()), base)+ 3;
char *buffer = new char[n];
mpq_get_str(buffer, base, get_mp());
std::string result(buffer);
delete [] buffer;
return result;
}
//@}
/// \name Conversion Functions
//@{
/// intValue
int intValue() const {
return static_cast<int>(doubleValue());
}
/// longValue
long longValue() const {
return static_cast<long>(doubleValue());
}
/// doubleValue
double doubleValue() const {
return mpq_get_d(get_mp());
}
/// BigIntValue
BigInt BigIntValue() const {
BigInt r;
mpz_tdiv_q(r.get_mp(), get_num_mp(), get_den_mp());
return r;
}
//@}
}; //BigRat class
inline BigRat operator+(const BigRat& a, const BigRat& b) {
BigRat r;
mpq_add(r.get_mp(), a.get_mp(), b.get_mp());
return r;
}
inline BigRat operator-(const BigRat& a, const BigRat& b) {
BigRat r;
mpq_sub(r.get_mp(), a.get_mp(), b.get_mp());
return r;
}
inline BigRat operator*(const BigRat& a, const BigRat& b) {
BigRat r;
mpq_mul(r.get_mp(), a.get_mp(), b.get_mp());
return r;
}
inline BigRat operator/(const BigRat& a, const BigRat& b) {
BigRat r;
mpq_div(r.get_mp(), a.get_mp(), b.get_mp());
return r;
}
// Chee (3/19/2004):
// Chee (3/19/2004):
// The following definitions of div_exact(x,y) and gcd(x,y)
// ensures that in Polynomial<NT>
/// divisible(x,y) = "x | y"
inline BigRat div_exact(const BigRat& x, const BigRat& y) {
BigRat z;
mpq_div(z.get_mp(), x.get_mp(), y.get_mp());
return z;
}
/// numerator
inline BigInt numerator(const BigRat& a) {
return BigInt(a.get_num_mp());
}
/// denominator
inline BigInt denominator(const BigRat& a) {
return BigInt(a.get_den_mp());
}
inline BigRat div_exact(const BigRat& x, const BigRat& y) {
BigRat z = x / y;
return z;
}
inline BigRat gcd(const BigRat& x, const BigRat& y) {
// return BigRat(1); // Remark: we may want replace this by
inline BigRat gcd(const BigRat& x , const BigRat& y)
{
// return BigRat(1); // Remark: we may want replace this by
// the definition of gcd of a quotient field
// of a UFD [Yap's book, Chap.3]
//Here is one possible definition: gcd of x and y is just the
@ -384,98 +65,17 @@ inline BigRat gcd(const BigRat& x, const BigRat& y) {
BigInt n = gcd(numerator(x), numerator(y));
BigInt d = gcd(denominator(x), denominator(y));
return BigRat(n,d);
}
}
// Chee: 8/8/2004: need isDivisible to compile Polynomial<BigRat>
// A trivial implementation is to return true always. But this
// caused tPolyRat to fail.
// So we follow the definition of
// Expr::isDivisible(e1, e2) which checks if e1/e2 is an integer.
inline bool isInteger(const BigRat& x) {
return BigInt(x.get_den_mp()) == 1;
}
inline bool isDivisible(const BigRat& x, const BigRat& y) {
BigRat r;
mpq_div(r.get_mp(), x.get_mp(), y.get_mp());
return isInteger(r);
}
inline BigRat operator<<(const BigRat& a, unsigned long ul) {
BigRat r;
mpq_mul_2exp(r.get_mp(), a.get_mp(), ul);
return r;
}
inline BigRat operator>>(const BigRat& a, unsigned long ul) {
BigRat r;
mpq_div_2exp(r.get_mp(), a.get_mp(), ul);
/// BigIntValue
inline BigInt BigIntValue(const BigRat& br)
{
BigInt r, rem;
divide_qr(numerator(br), denominator(br), r, rem);
return r;
}
inline int cmp(const BigRat& x, const BigRat& y) {
return mpq_cmp(x.get_mp(), y.get_mp());
}
inline bool operator==(const BigRat& a, const BigRat& b) {
return cmp(a, b) == 0;
}
inline bool operator!=(const BigRat& a, const BigRat& b) {
return cmp(a, b) != 0;
}
inline bool operator>=(const BigRat& a, const BigRat& b) {
return cmp(a, b) >= 0;
}
inline bool operator>(const BigRat& a, const BigRat& b) {
return cmp(a, b) > 0;
}
inline bool operator<=(const BigRat& a, const BigRat& b) {
return cmp(a, b) <= 0;
}
inline bool operator<(const BigRat& a, const BigRat& b) {
return cmp(a, b) < 0;
}
inline std::ostream& operator<<(std::ostream& o, const BigRat& x) {
//return CORE::operator<<(o, x.get_mp());
return CORE::io_write(o, x.get_mp());
}
inline std::istream& operator>>(std::istream& i, BigRat& x) {
x.makeCopy();
//return CORE::operator>>(i, x.get_mp());
return CORE::io_read(i, x.get_mp());
}
/// sign
inline int sign(const BigRat& a) {
return mpq_sgn(a.get_mp());
}
/// abs
inline BigRat abs(const BigRat& a) {
BigRat r;
mpq_abs(r.get_mp(), a.get_mp());
return r;
}
/// neg
inline BigRat neg(const BigRat& a) {
BigRat r;
mpq_neg(r.get_mp(), a.get_mp());
return r;
}
/// div2
inline BigRat div2(const BigRat& a) {
BigRat r(a);
return r.div2();
}
/// longValue
inline long longValue(const BigRat& a) {
return a.longValue();
}
/// doubleValue
inline double doubleValue(const BigRat& a) {
return a.doubleValue();
}
/// return BigInt value
inline BigInt BigIntValue(const BigRat& a) {
return a.BigIntValue();
}
} // namespace CORE
} //namespace CORE
#endif // _CORE_BIGRAT_H_

View File

@ -29,4 +29,13 @@
#include <CGAL/export/CORE.h>
#ifdef CGAL_TEST_SUITE
// disabled for the testsuite to avoid `w`
#define CGAL_CORE_warning_msg(X ,Y)
// if (!(X)) CGAL_error_msg(Y)
#else
#define CGAL_CORE_warning_msg(X ,Y) CGAL_warning_msg(X ,Y)
#endif
#endif // _CORE_CONFIG_H_

View File

@ -156,12 +156,6 @@ CGAL_CORE_EXPORT double IntMantissa(double d);
// (See CORE_PATH/progs/ieee/frexp.cpp for details)
CGAL_CORE_EXPORT int IntExponent(double d);
/// Writes out an error or warning message in the local file CORE_DIAGFILE
/** If last argument (err) is TRUE, then this is considered an error
* (not just warning). In this case, the message is also printed in
* std::cerr, using std::perror().
* */
CGAL_CORE_EXPORT void core_error(std::string msg, std::string file, int lineno, bool err);
/// This is for debugging messages
inline void core_debug(std::string msg){

View File

@ -31,7 +31,6 @@
#include <CGAL/use.h>
#include <CGAL/CORE/CoreAux.h>
#include <CGAL/gmp.h>
namespace CORE {
@ -157,30 +156,5 @@ int IntExponent(double d) {
return e-53;
}
/// 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) {
std::cerr << (std::string("CORE ERROR") + " (file " + file + ", line "
+ std::to_string(lineno) +"):" + msg + "\n").c_str();
std::exit(1); //Note: do not call abort()
}
}
} //namespace CORE

View File

@ -1,479 +0,0 @@
/****************************************************************************
* Core Library Version 1.7, August 2004
* Copyright (c) 1995-2004 Exact Computation Project
* All rights reserved.
*
* This file is part of CGAL (www.cgal.org).
*
* File: CoreIO.cpp
*
* Written by
* Zilin Du <zilin@cs.nyu.edu>
* Chee Yap <yap@cs.nyu.edu>
*
* WWW URL: https://cs.nyu.edu/exact/
* Email: exact@cs.nyu.edu
*
* $URL$
* $Id$
* SPDX-License-Identifier: LGPL-3.0-or-later
***************************************************************************/
#ifndef _COREIO_IMPL_H_
#define _COREIO_IMPL_H_
#ifdef CGAL_HEADER_ONLY
#define CGAL_INLINE_FUNCTION inline
#else
#define CGAL_INLINE_FUNCTION
#endif
#include <CGAL/CORE/BigFloatRep.h>
#include <CGAL/CORE/BigFloat.h>
#include <CGAL/CORE/BigInt.h>
namespace CORE {
CGAL_INLINE_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_INLINE_FUNCTION
void core_io_memory_handler(char *t, const char *f, const char *m) {
if (t == nullptr) {
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_INLINE_FUNCTION
void allocate (char * &s, int old_size, int new_size) {
if (old_size > new_size)
old_size = new_size;
if (s == nullptr)
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_INLINE_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_INLINE_FUNCTION
int skip_comment_line (std::istream & in) {
char c;
do {
in.get(c);
while ( c == '#' ) {
do {
in.get(c);
} while ( c != '\n' );
in.get(c);
}
} while (c == ' ' || c == '\t' || c == '\n');
if (in.eof())
core_io_error_handler("CoreIO::read_from_file()","unexpected end of file.");
in.putback(c);
return c;
}
// skips '\\' followed by '\n'
CGAL_INLINE_FUNCTION
char skip_backslash_new_line (std::istream & in) {
char c;
in.get(c);
while (c == '\\') {
in.get(c);
if (c == '\n')
in.get(c);
else
core_io_error_handler("CoreIO::operator>>", "\\ must be immediately followed by new line.");
}
return c;
}
CGAL_INLINE_FUNCTION
void read_string(std::istream& in, char* &buffer, int sz) {
char c;
int pos=0;
skip_comment_line(in);
while ( in.get(c) ) {
if ( c == ' ' || c == '\t' || c == '\n' || c == '#')
break;
else
append_char(buffer, sz, pos++, c);
}
append_char(buffer, sz, pos, '\0');
}
CGAL_INLINE_FUNCTION
void read_base_number(std::istream& in, BigInt& m, long length, long maxBits) {
char *buffer;
int size, offset;
int base;
bool is_negate;
char c;
int pos = 0;
skip_comment_line(in);
// read sign
in.get(c);
if (c == '-') {
is_negate = true;
in.get(c);
} else
is_negate = false;
// read base and compute digits
if (c == '0') {
in.get(c);
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; i++) {
c=skip_backslash_new_line(in);
if(in.eof()){
break;
}
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 necessary
if (offset > 0 && base != 10) {
m <<= offset;
}
if (is_negate)
negate(m);
}
CGAL_INLINE_FUNCTION
void write_base_number(std::ostream& out, char* buffer, std::size_t 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 (std::size_t 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 absolute value string
char* buffer = new char[mpz_sizeinbase(c.get_mp(), base) + 2];
mpz_get_str(buffer, base, c.get_mp());
std::size_t 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 absolute value string
char* buffer = new char[mpz_sizeinbase(c.get_mp(), base) + 2];
mpz_get_str(buffer, base, c.get_mp());
std::size_t 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

@ -72,9 +72,7 @@ public:
Expr(float f) : RCExpr(nullptr) { // check for valid numbers
// (i.e., not infinite and not NaN)
if (! CGAL_CORE_finite(f)) {
core_error(" ERROR : constructed an invalid float! ", __FILE__, __LINE__, false);
if (get_static_AbortFlag())
abort();
CGAL_error_msg("ERROR : constructed an invalid float! ");
get_static_InvalidFlag() = -1;
}
rep = new ConstDoubleRep(f);
@ -83,9 +81,7 @@ public:
Expr(double d) : RCExpr(nullptr) { // check for valid numbers
// (i.e., not infinite and not NaN)
if (! CGAL_CORE_finite(d)) {
core_error(" ERROR : constructed an invalid double! ", __FILE__, __LINE__, false);
if (get_static_AbortFlag())
abort();
CGAL_error_msg("ERROR : constructed an invalid double! ");
get_static_InvalidFlag() = -2;
}
rep = new ConstDoubleRep(d);
@ -95,6 +91,14 @@ public:
Expr(const BigInt& I) : RCExpr(new ConstRealRep(Real(I))) {}
/// constructor for <tt>BigRat</tt>
Expr(const BigRat& R) : RCExpr(new ConstRealRep(Real(R))) {}
/// constructor from expression template
template <class TmplExpr,
class = std::enable_if_t<
boost::multiprecision::is_number_expression<TmplExpr>::value> >
Expr(const TmplExpr& R)
: RCExpr(new ConstRealRep(Real(
std::conditional_t<boost::multiprecision::number_category<TmplExpr>::value == boost::multiprecision::number_kind_integer,
BigInt, BigRat>(R)))) {}
/// constructor for <tt>BigFloat</tt>
Expr(const BigFloat& F) : RCExpr(new ConstRealRep(Real(F))) {}
@ -173,9 +177,7 @@ public:
/// /= operator
Expr& operator/=(const Expr& e) {
if ((e.rep)->getSign() == 0) {
core_error(" ERROR : division by zero ! ",__FILE__, __LINE__, false);
if (get_static_AbortFlag())
abort();
CGAL_error_msg("ERROR : division by zero ! ");
get_static_InvalidFlag() = -3;
}
*this = new DivRep(rep, e.rep);
@ -376,9 +378,7 @@ inline Expr operator*(const Expr& e1, const Expr& e2) {
/// division
inline Expr operator/(const Expr& e1, const Expr& e2) {
if (e2.sign() == 0) {
core_error(" ERROR : division by zero ! ", __FILE__, __LINE__, false);
if (get_static_AbortFlag())
abort();
CGAL_error_msg("ERROR : division by zero ! ");
get_static_InvalidFlag() = -4;
}
return Expr(new DivRep(e1.Rep(), e2.Rep()));
@ -479,9 +479,7 @@ inline bool isDivisible(const Expr& e1, const Expr& e2) {
/// square root
inline Expr sqrt(const Expr& e) {
if (e.sign() < 0) {
core_error(" ERROR : sqrt of negative value ! ", __FILE__, __LINE__, false);
if (get_static_AbortFlag())
abort();
CGAL_error_msg("ERROR : sqrt of negative value ! ");
get_static_InvalidFlag() = -5;
}
return Expr(new SqrtRep(e.Rep()));

View File

@ -564,9 +564,7 @@ public:
I = ss.isolateRoot(n);
// check whether n-th root exists
if (I.first == 1 && I.second == 0) {
core_error("CORE ERROR! root index out of bound",
__FILE__, __LINE__, true);
abort();
CGAL_error_msg("CORE ERROR! root index out of bound");
}
// test if the root isolated in I is 0:
if ((I.first == 0)&&(I.second == 0))
@ -583,9 +581,7 @@ public:
ss.isolateRoots(I.first, I.second, v);
I = v.front();
if (v.size() != 1) {
core_error("CORE ERROR! non-isolating interval",
__FILE__, __LINE__, true);
abort();
CGAL_error_msg("CORE ERROR! non-isolating interval");
}
ffVal = computeFilteredValue(); // Chee: this line seems unnecessary
}
@ -1092,8 +1088,7 @@ void AddSubRep<Operator>::computeExactFlags() {
uMSB() = newValue.uMSB(); // chen: to get tighers value.
sign() = newValue.sign();
} else if (lowBound.isInfty()) {//check if rootbound is too big
core_error("AddSubRep:root bound has exceeded the maximum size\n \
but we still cannot decide zero.\n", __FILE__, __LINE__, false);
CGAL_CORE_warning_msg(false, "AddSubRep:root bound has exceeded the maximum size but we still cannot decide zero.");
} else { // Op(first, second) == 0
lMSB() = CORE_negInfty;
sign() = 0;
@ -1186,8 +1181,7 @@ void AddSubRep<Operator>::computeExactFlags() {
//8/9/01, Chee: implement escape precision here:
if (i> get_static_EscapePrec()) {
get_static_EscapePrecFlag() = -i.asLong();//negative means EscapePrec is used
core_error("Escape precision triggered at",
__FILE__, __LINE__, false);
CGAL_CORE_warning_msg(false, "Escape precision triggered");
if (get_static_EscapePrecWarning())
std::cout<< "Escape Precision triggered at "
<< get_static_EscapePrec() << " bits" << std::endl;
@ -1204,8 +1198,7 @@ void AddSubRep<Operator>::computeExactFlags() {
#endif
if (sign() == 0 && ua .isInfty()) {
core_error("AddSubRep: root bound has exceeded the maximum size\n \
but we still cannot decide zero.\n", __FILE__, __LINE__, true);
CGAL_error_msg("AddSubRep: root bound has exceeded the maximum size but we still cannot decide zero.");
} // if (sign == 0 && ua .isInfty())
}// else do progressive
}
@ -1236,8 +1229,7 @@ void AddSubRep<Operator>::computeApproxValue(const extLong& relPrec,
{
std::ostringstream oss;
oss << "CORE WARNING: a huge lMSB in AddSubRep: " << lMSB();
core_error(oss.str(),
__FILE__, __LINE__, false);
CGAL_CORE_warning_msg(false, oss.str().c_str());
}
extLong rf = first->uMSB()-lMSB()+relPrec+EXTLONG_FOUR; // 2 better

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