mirror of https://github.com/CGAL/cgal
267 lines
7.5 KiB
C++
267 lines
7.5 KiB
C++
// Copyright (c) 2005 INRIA Sophia-Antipolis (France)
|
|
// All rights reserved.
|
|
//
|
|
// Authors : Sylvain Pion <Sylvain.Pion@sophia.inria.fr>
|
|
//
|
|
// Partially supported by the IST Programme of the EU as a Shared-cost
|
|
// RTD (FET Open) Project under Contract No IST-2000-26473
|
|
// (ECG - Effective Computational Geometry for Curves and Surfaces)
|
|
// and a STREP (FET Open) Project under Contract No IST-006413
|
|
// (ACS -- Algorithms for Complex Shapes)
|
|
|
|
// file : include/CGAL/Circular_arc_traits_tracer.h
|
|
|
|
#ifndef CGAL_CURVED_KERNEL_CIRCULAR_ARC_TRAITS_TRACER_H
|
|
#define CGAL_CURVED_KERNEL_CIRCULAR_ARC_TRAITS_TRACER_H
|
|
|
|
#include <CGAL/basic.h>
|
|
#include <cassert>
|
|
#include <CGAL/Profile_counter.h>
|
|
|
|
namespace CGAL {
|
|
|
|
/// Wrapper around a traits class for Arrangement which just forwards the
|
|
/// calls to its nested traits, and prints debug info for each argument and
|
|
/// return value. Compiling with -DCGAL_PROFILE dumps the number of calls
|
|
/// to each predicate at the end of the program.
|
|
|
|
// to get better profiles for the traits interface :
|
|
#ifndef CGAL_NO_INLINE
|
|
# define CGAL_NO_INLINE __attribute__((__noinline__))
|
|
//#define CGAL_NO_INLINE
|
|
#endif
|
|
|
|
// FIXME : should it be the responsibility of the tracer
|
|
// to add the Debug_id stuff ?
|
|
template < typename Traits, int debug_level = 2 >
|
|
class Circular_arc_traits_tracer
|
|
: public Traits
|
|
{
|
|
|
|
typedef Circular_arc_traits_tracer<Traits, debug_level> Self;
|
|
|
|
// debug_level :
|
|
// 0 = no debug messages
|
|
// 1 = important messages
|
|
// 2 = maybe important messages
|
|
// 3 = all calls
|
|
|
|
// Traits traits;
|
|
|
|
mutable int nested_level; /// for detection of nested calls
|
|
mutable int call_number; /// identifies the call number
|
|
|
|
// FIXME : transform these macros into member functions ?
|
|
#define CGAL_DEBUG(level, args) if (level <= debug_level) \
|
|
{ std::cout << "Call #" << t->call_number++ << " " << CGAL_PRETTY_FUNCTION \
|
|
<< " ( " << args << " )"; \
|
|
if (t->nested_level != 0) \
|
|
std::cout << " [ nested level " << t->nested_level << " ]"; \
|
|
++t->nested_level; \
|
|
std::cout << std::endl; }
|
|
|
|
#define CGAL_DEBUG_RET(level, args) if (level <= debug_level) \
|
|
{ std::cout << " returns : " << args; \
|
|
--t->nested_level; \
|
|
if (t->nested_level != 0) \
|
|
std::cout << " [ nested level " << t->nested_level << " ]"; \
|
|
std::cout << std::endl; }
|
|
|
|
public:
|
|
|
|
typedef typename Traits::Kernel Kernel;
|
|
typedef typename Traits::Curve_2 Curve_2;
|
|
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
|
|
|
|
typedef typename Traits::Point Point;
|
|
typedef typename Traits::Point_2 Point_2;
|
|
|
|
typedef typename Kernel::Circle_2 Circle;
|
|
typedef typename Kernel::Circular_arc_2 Circular_arc;
|
|
|
|
typedef typename Traits::Has_left_category Has_left_category;
|
|
typedef typename Traits::Has_merge_category Has_merge_category;
|
|
|
|
const Traits & traits () const
|
|
{ return static_cast<const Traits &>(*this); }
|
|
|
|
Circular_arc_traits_tracer(const Traits &t = Traits())
|
|
: Traits(t), nested_level(0), call_number(0) {}
|
|
|
|
struct Compare_x_2 {
|
|
|
|
Compare_x_2(const Self *tt) :t(tt) {}
|
|
|
|
const Self *t;
|
|
|
|
CGAL::Comparison_result
|
|
CGAL_NO_INLINE
|
|
operator()(const Point_2 &p, const Point_2 &q) const
|
|
{
|
|
CGAL_PROFILER(__FUNCTION__);
|
|
CGAL_DEBUG(2, p.id() << ", " << q.id());
|
|
CGAL::Comparison_result ret = t->traits().compare_x_2_object()(p, q);
|
|
CGAL_DEBUG_RET(2, ret);
|
|
return ret;
|
|
}
|
|
};
|
|
|
|
Compare_x_2
|
|
compare_x_2_object() const
|
|
{ return Compare_x_2(this); }
|
|
|
|
struct Compare_y_2 {
|
|
|
|
Compare_y_2(const Self *tt) :t(tt) {}
|
|
|
|
const Self *t;
|
|
|
|
CGAL::Comparison_result
|
|
CGAL_NO_INLINE
|
|
operator()(const Point_2 &p, const Point_2 &q) const
|
|
{
|
|
CGAL_PROFILER(__FUNCTION__);
|
|
CGAL_DEBUG(2, p.id() << ", " << q.id());
|
|
CGAL::Comparison_result ret = t->traits().compare_y_2_object()(p, q);
|
|
CGAL_DEBUG_RET(2, ret);
|
|
return ret;
|
|
}
|
|
};
|
|
|
|
Compare_y_2
|
|
compare_y_2_object() const
|
|
{ return Compare_y_2(this); }
|
|
|
|
struct Equal_2 {
|
|
|
|
Equal_2(const Self *tt) :t(tt) {}
|
|
|
|
const Self *t;
|
|
|
|
bool
|
|
CGAL_NO_INLINE
|
|
operator()(const Point_2 &p, const Point_2 &q) const
|
|
{
|
|
CGAL_PROFILER(__FUNCTION__);
|
|
CGAL_DEBUG(2, p.id() << ", " << q.id());
|
|
bool ret = t->traits().equal_2_object()(p, q);
|
|
CGAL_DEBUG_RET(2, ret);
|
|
return ret;
|
|
}
|
|
|
|
bool
|
|
CGAL_NO_INLINE
|
|
operator()(const Circular_arc &a1, const Circular_arc &a2) const
|
|
{
|
|
CGAL_PROFILER(__FUNCTION__);
|
|
CGAL_DEBUG(2, a1.id() << ", " << a2.id());
|
|
bool ret = t->traits().equal_2_object()(a1, a2);
|
|
CGAL_DEBUG_RET(2, ret);
|
|
return ret;
|
|
}
|
|
};
|
|
|
|
Equal_2
|
|
equal_2_object() const
|
|
{ return Equal_2(this); }
|
|
|
|
struct Intersect_2 {
|
|
|
|
Intersect_2(const Self *tt) :t(tt) {}
|
|
|
|
const Self *t;
|
|
|
|
template < class OutputIterator >
|
|
OutputIterator
|
|
CGAL_NO_INLINE
|
|
operator()(const Circle & c1, const Circle & c2,
|
|
OutputIterator res) const
|
|
{
|
|
CGAL_PROFILER(__FUNCTION__);
|
|
CGAL_DEBUG(2, c1.id() << ", " << c2.id());
|
|
std::vector<CGAL::Object> ret;
|
|
t->traits().intersect_2_object()(c1, c2,
|
|
std::back_inserter(ret));
|
|
|
|
if (2 <= debug_level)
|
|
{
|
|
std::cout << " returns : ";
|
|
for(int i=0; i<ret.size(); ++i) {
|
|
//Point_2 p;
|
|
//Circular_arc c;
|
|
//std::pair<Point_2, int> pp;
|
|
if (const Point_2 *p = CGAL::object_cast<Point_2>(&ret[i])) {
|
|
std::cout << *p << " ";
|
|
}
|
|
else if (const Circular_arc *c = CGAL::object_cast<Circular_arc>(&ret[i])) {
|
|
std::cout << *c << " ";
|
|
}
|
|
else if (const std::pair<Point_2, int> *pp = CGAL::object_cast<std::pair<Point_2, int> >(&ret[i])) {
|
|
std::cout << " pair ( " << pp->first << " ; " <<
|
|
pp->second << " ) ";
|
|
}
|
|
else {
|
|
std::cout << " [ something else ? ] ";
|
|
}
|
|
}
|
|
--nested_level;
|
|
if (nested_level != 0)
|
|
std::cout << " [ nested level " << nested_level << " ]";
|
|
std::cout << std::endl;
|
|
}
|
|
|
|
return std::copy(ret.begin(), ret.end(), res);
|
|
}
|
|
|
|
template < class OutputIterator >
|
|
OutputIterator
|
|
CGAL_NO_INLINE
|
|
operator()(const Circular_arc & c1, const Circular_arc & c2,
|
|
OutputIterator res) const
|
|
{
|
|
CGAL_PROFILER(__FUNCTION__);
|
|
CGAL_DEBUG(2, c1.id() << ", " << c2.id());
|
|
std::vector<CGAL::Object> ret;
|
|
t->traits().intersect_2_object()(c1, c2, std::back_inserter(ret));
|
|
|
|
if (2 <= debug_level)
|
|
{
|
|
std::cout << " returns : ";
|
|
for(unsigned i=0; i<ret.size(); ++i) {
|
|
// Point_2 p;
|
|
// Circular_arc c;
|
|
// std::pair<Point_2, unsigned> pp;
|
|
if (const Point_2 *p = CGAL::object_cast<Point_2>(&ret[i])) {
|
|
std::cout << *p << " ";
|
|
}
|
|
else if (const Circular_arc *c = CGAL::object_cast<Circular_arc>(&ret[i])) {
|
|
std::cout << *c << " ";
|
|
}
|
|
else if (const std::pair<Point_2, unsigned> *pp = CGAL::object_cast<std::pair<Point_2, unsigned> > (&ret[i])) {
|
|
std::cout << " pair ( " << pp->first << " ; " <<
|
|
pp->second << " ) ";
|
|
}
|
|
else {
|
|
std::cout << " [ something else ? ] ";
|
|
}
|
|
}
|
|
--t->nested_level;
|
|
if (t->nested_level != 0)
|
|
std::cout << " [ nested level " << t->nested_level << " ]";
|
|
std::cout << std::endl;
|
|
}
|
|
|
|
return std::copy(ret.begin(), ret.end(), res);
|
|
}
|
|
};
|
|
|
|
Intersect_2
|
|
intersect_2_object() const
|
|
{ return Intersect_2(this); }
|
|
|
|
};
|
|
|
|
} // namespace CGAL
|
|
|
|
#endif // CGAL_CURVED_KERNEL_CIRCULAR_ARC_TRAITS_TRACER_H
|