diff --git a/Curved_kernel_via_analysis_2/include/CGAL/Arr_surfaces_intersecting_dupin_cyclide_traits_2.h b/Curved_kernel_via_analysis_2/include/CGAL/Arr_surfaces_intersecting_dupin_cyclide_traits_2.h index 3ed44aa7cf8..f6da5e30816 100644 --- a/Curved_kernel_via_analysis_2/include/CGAL/Arr_surfaces_intersecting_dupin_cyclide_traits_2.h +++ b/Curved_kernel_via_analysis_2/include/CGAL/Arr_surfaces_intersecting_dupin_cyclide_traits_2.h @@ -28,11 +28,12 @@ #include #include +#include #include #include -#ifdef CGAL_CKvA_COMPILE_RENDERER +#ifdef CGAL_CKVA_COMPILE_RENDERER #include #endif @@ -864,17 +865,20 @@ public: //! itself typedef Dupin_cyclide_point_2 Self; - //! point approximation - typedef typename CGAL::Cartesian< double >::Point_3 Approximation_3; + //! our lovely cyclide + typedef typename ASiDC_traits_2::Dupin_cyclide_3 Dupin_cyclide_3; - //! types needed to replicate constructors + //! types needed to replicate constructors typedef typename Base::Curve_analysis_2 Curve_analysis_2; typedef typename Base::X_coordinate_1 X_coordinate_1; typedef typename Base::Rep Rep; - //! for visualization + //! for parameterization typedef CGAL::Polynomial< double > Poly_double_1; typedef CGAL::Polynomial< Poly_double_1 > Poly_double_2; + + typedef CGAL::Fourtuple< double > Point_double_4; + //!\name replicates all constructors of the base (stupid solution) //! see base type constructors for detailed description @@ -917,70 +921,97 @@ public: //!\name visualization & approximation //!@{ -#ifdef CGAL_CKvA_COMPILE_RENDERER +#ifdef CGAL_CKVA_COMPILE_RENDERER //! sets up rendering window \c bbox and resolution static void setup_renderer(CGAL::Bbox_2 bbox, int res_w, int res_h) { Curve_renderer_facade< ASiDC_traits_2 >::setup(bbox, res_w, res_h); } //! sets up cyclide parameterization equations - static void setup_parameterization( - const typename ASiDC_traits_2::Dupin_cyclide_3& base_surf) { + static void setup_parameterization(const Dupin_cyclide_3& base_surf) { - parametrize_poly(0, CGAL::to_double(base_surf.x_param())); - parametrize_poly(1, CGAL::to_double(base_surf.y_param())); - parametrize_poly(2, CGAL::to_double(base_surf.z_param())); - parametrize_poly(3, CGAL::to_double(base_surf.w_param())); + param_surface(&base_surf); + param_tube_circle(&base_surf); + param_outer_circle(&base_surf); + param_pole(&base_surf); } //! get / set parameterization polynomial with index \c idx (0..3) - static const Poly_double_2& parametrize_poly(unsigned idx, - const boost::optional< Poly_double_2 >& ref = boost::none) { + static const Poly_double_2 *param_surface( + const Dupin_cyclide_3* base_surf = NULL) { + static Poly_double_2 _param[4]; // x, y, z, w respectively - - CGAL_precondition(idx < 4); - if(ref) - _param[idx] = *ref; - return _param[idx]; + if(base_surf != NULL) + _param[0] = CGAL::to_double(base_surf->x_param()), + _param[1] = CGAL::to_double(base_surf->y_param()), + _param[2] = CGAL::to_double(base_surf->z_param()), + _param[3] = CGAL::to_double(base_surf->w_param()); + + return _param; } + static const Poly_double_1 *param_tube_circle( + const Dupin_cyclide_3* base_surf = NULL) { + + static Poly_double_1 _param[4]; // see above + if(base_surf != NULL) +// make_transform_iterator ? + _param[0] = CGAL::to_double(base_surf->tube_circle()[0]), + _param[1] = CGAL::to_double(base_surf->tube_circle()[1]), + _param[2] = CGAL::to_double(base_surf->tube_circle()[2]), + _param[3] = CGAL::to_double(base_surf->tube_circle()[3]); + return _param; + } + + static const Poly_double_1 *param_outer_circle( + const Dupin_cyclide_3* base_surf = NULL) { + + static Poly_double_1 _param[4]; // see above + if(base_surf != NULL) + _param[0] = CGAL::to_double(base_surf->outer_circle()[0]), + _param[1] = CGAL::to_double(base_surf->outer_circle()[1]), + _param[2] = CGAL::to_double(base_surf->outer_circle()[2]), + _param[3] = CGAL::to_double(base_surf->outer_circle()[3]); + return _param; + } + + static const Point_double_4& param_pole( + const Dupin_cyclide_3* base_surf = NULL) { + + static Point_double_4 _pole; + if(base_surf != NULL) + _pole.e0 = CGAL::to_double(base_surf->pole().e0), + _pole.e1 = CGAL::to_double(base_surf->pole().e1), + _pole.e2 = CGAL::to_double(base_surf->pole().e2), + _pole.e3 = CGAL::to_double(base_surf->pole().e3); + return _pole; + } + /*!\brief * computes approximation of a point * * returns \c false if the point does not fall within the drawing window + * \c Coord_3 must be constructible from a triple of doubles */ - bool compute_approximation(Approximation_3& result) const { + template < class Coord_3 > + bool compute_approximation(Coord_3& result) const { typedef Curve_renderer_facade< ASiDC_traits_2 > Facade; - typename Facade::Coord_2 cc; - + + CGAL::Twotuple< double > cc; if(!Facade::instance().draw(*this, cc)) return false; // bad luck - Poly_double_2 px = parametrize_poly(0), py = parametrize_poly(1), - pz = parametrize_poly(2), pw = parametrize_poly(3); - - CGAL::Bbox_2 bbox; - int res_w, res_h; - Facade::instance().get_resolution(res_w, res_h); - Facade::instance().get_window(bbox); - // gotcha !! - double lx = bbox.xmax() - bbox.xmin(), ly = bbox.ymax() - bbox.ymin(); - double s = bbox.xmin() + (double)cc.x * lx / res_w, - t = bbox.ymin() + (double)cc.y * ly / res_h; - - double x0, y0, z0, w0 = NiX::substitute_xy(pw, s, t); - if(std::abs(w0) < 1e-17) - return false; - - x0 = NiX::substitute_xy(px, s, t) / w0; - y0 = NiX::substitute_xy(py, s, t) / w0; - z0 = NiX::substitute_xy(pz, s, t) / w0; - - result = Approximation_3(x0, y0, z0); + const Poly_double_2* params = param_surface(); + double x0 = NiX::substitute_xy(params[0], cc.e0, cc.e1), + y0 = NiX::substitute_xy(params[1], cc.e0, cc.e1), + z0 = NiX::substitute_xy(params[2], cc.e0, cc.e1), + invw0 = 1.0 / NiX::substitute_xy(params[3], cc.e0, cc.e1); + + result = Coord_3(x0*invw0, y0*invw0, z0*invw0); return true; } -#endif // CGAL_CKvA_COMPILE_RENDERER +#endif // CGAL_CKVA_COMPILE_RENDERER //!@} friend class CGALi::Arc_2; @@ -1005,7 +1036,7 @@ public: typedef typename ASiDC_traits_2::Point_2 Point_2; //! point approximation - typedef typename CGAL::Cartesian< double >::Point_3 Approximation_3; + //typedef typename CGAL::Cartesian< double >::Point_3 Approximation_3; //! types needed to replicate constructors typedef typename Base::Curve_analysis_2 Curve_analysis_2; @@ -1093,70 +1124,9 @@ public: //!\name visualization & approximation //!@{ -#ifdef CGAL_CKvA_COMPILE_RENDERER +#ifdef CGAL_CKVA_COMPILE_RENDERER - /*!\brief - * computes arc's approximation using preset window and resolution - * - * @note: call Dupin_cyclide_point_2::setup_renderer() and - * setup_parameterization() before computing approximation - */ - template - OutputIterator compute_approximation(OutputIterator oi) const { - - typedef Curve_renderer_facade< ASiDC_traits_2 > Facade; - typedef typename Facade::Coord_vec_2 Coord_vec_2; - typedef typename Facade::Coord_2 Coord_2; - - std::list points; - std::pair end_points; - - Facade::instance().draw(*this, points, end_points); - if(points.empty()) - return oi; - - CGAL::Bbox_2 bbox; - int res_w, res_h; - Facade::instance().get_resolution(res_w, res_h); - Facade::instance().get_window(bbox); - - Poly_double_2 px = Point_2::parametrize_poly(0), - py = Point_2::parametrize_poly(1), - pz = Point_2::parametrize_poly(2), - pw = Point_2::parametrize_poly(3); - - double pixw = (bbox.xmax() - bbox.xmin()) / res_w, - pixh = (bbox.ymax() - bbox.ymin()) / res_h; - typename std::list::const_iterator lit = points.begin(); - while(lit != points.end()) { - - const Coord_vec_2& tmp = *lit++; - typename Coord_vec_2::const_iterator cit; - int xprev = -1, yprev = -1; - for(cit = tmp.begin(); cit != tmp.end(); cit++) { - - if(xprev == cit->x && yprev == cit->y) - continue; // don't push duplicate points - xprev = cit->x, yprev = cit->y; - double s = bbox.xmin() + (double)xprev * pixw, - t = bbox.ymin() + (double)yprev * pixh; - -// std::cerr << "x = " << cit->x << "; y = " << cit->y << -// "; x0 = " << x0 << "; y0 = " << y0 << std::endl; - double x0, y0, z0, w0 = NiX::substitute_xy(pw, s, t); - if(std::abs(w0) < 1e-17) - continue; - - x0 = NiX::substitute_xy(px, s, t) / w0; - y0 = NiX::substitute_xy(py, s, t) / w0; - z0 = NiX::substitute_xy(pz, s, t) / w0; - *oi++ = Approximation_3(x0, y0, z0); - } - } - return oi; - } - -#endif // CGAL_CKvA_COMPILE_RENDERER +#endif //!@} diff --git a/Curved_kernel_via_analysis_2/include/CGAL/Curved_kernel_via_analysis_2/Curve_renderer_facade.h b/Curved_kernel_via_analysis_2/include/CGAL/Curved_kernel_via_analysis_2/Curve_renderer_facade.h index f1240a52824..1b8e64a5feb 100644 --- a/Curved_kernel_via_analysis_2/include/CGAL/Curved_kernel_via_analysis_2/Curve_renderer_facade.h +++ b/Curved_kernel_via_analysis_2/include/CGAL/Curved_kernel_via_analysis_2/Curve_renderer_facade.h @@ -56,6 +56,7 @@ #include #include +#include #include #include @@ -69,23 +70,20 @@ class Curve_renderer_interface; * represents a single curve renderer instance with usual parameter set to * speed up rendering of several objects supported by the same curve * - * @warning not recommended to use for multi-threaded applications + * @warning not recommended to use in multi-threaded applications */ template class Curve_renderer_facade { Curve_renderer_facade() { // private constructor + } public: typedef CGAL::Interval_nt Interval_double; typedef Curve_renderer_interface Curve_renderer; - - typedef typename Curve_renderer::Coord_vec_2 Coord_vec_2; - - typedef typename Curve_renderer::Coord_2 Coord_2; + Interval_double > Curve_renderer; static Curve_renderer& instance() { static Curve_renderer _this; @@ -95,9 +93,9 @@ public: static void setup(const CGAL::Bbox_2& bbox, int res_w, int res_h) { int _w, _h; CGAL::Bbox_2 tmp; - instance().get_resolution(_w, _h); - instance().get_window(tmp); - + CORE::CORE_init(2); + CORE::setDefaultPrecision(70, CORE::extLong::getPosInfty()); + instance().get_setup_parameters(&tmp, _w, _h); if(bbox != tmp || res_w != _w || res_h != _h) { instance().setup(bbox, res_w, res_h); } @@ -130,12 +128,6 @@ public: typedef typename Curved_kernel_via_analysis_2::Curve_kernel_2 Curve_kernel_2; - //! approximation coordinates - typedef CGALi::Coord_2 Coord_2; - - //! vector of coordinates - typedef CGALi::Coord_vec_2 Coord_vec_2; - //! exact rational number type typedef typename ::CGAL::Get_arithmetic_kernel< typename Curve_kernel_2::Coefficient>::Arithmetic_kernel @@ -216,12 +208,11 @@ public: //! \name Public methods and properties //!@{ - inline void get_window(CGAL::Bbox_2& bbox) { - return renderer().get_window(bbox); - } - - inline void get_resolution(int& res_w, int& res_h) { - return renderer().get_resolution(res_w, res_h); + //!@note pass null-pointer for \c pbox parameter if you don't need + //! the drawing window + inline void get_setup_parameters(CGAL::Bbox_2 *pbox, int& res_w, + int& res_h) { + return renderer().get_setup_parameters(pbox, res_w, res_h); } /*!\brief @@ -241,51 +232,55 @@ public: /*!\brief * rasterizes an x-monotone curve \c arc * - * returns a list of sequences of pixel coordinates in \c points and - * end-point coordinats in \c end_points + * outputs the list of sequences of pixel coordinates as objects of type + * \c Coord_2 to the output iterator \c pts , end-point coordinates are + * returned as a two-tuple \c end_pts + * + * \c Container must support \c push_back and \c clear operations + * + * \c Coord_2 must be constructible from a pair of integers / doubles + * depending on the renderer type */ - inline void draw(const Arc_2& arc, std::list& points, - std::pair& end_points) - { + template < class Coord_2, template < class > class Container > + inline void draw(const Arc_2& arc, Container< std::vector >& pts, + CGAL::Twotuple< Coord_2 >& end_pts) { + #ifndef CGAL_CKVA_DUMMY_RENDERER + Bbox_2 bbox; + int res_w, res_h; try { - renderer().draw(arc, points, end_points); + renderer().draw(arc, pts, end_pts); } catch(CGALi::Insufficient_rasterize_precision_exception) { std::cerr << "Switching to multi-precision arithmetic" << std::endl; #ifdef CGAL_CKVA_USE_MULTIPREC_ARITHMETIC - Bbox_2 bbox; - int res_w, res_h; - if(::boost::is_same::Is_exact, - CGAL::Tag_true>::value) + if(::boost::is_same:: + Is_exact, CGAL::Tag_true>::value) goto Lexit; - - get_window(bbox); - get_resolution(res_w, res_h); + + get_setup_parameters(&bbox, res_w, res_h); bigfloat_renderer().setup(bbox, res_w, res_h); try { - points.clear(); - bigfloat_renderer().draw(arc, points, end_points); + pts.clear(); + bigfloat_renderer().draw(arc, pts, end_pts); return; } catch(CGALi::Insufficient_rasterize_precision_exception) { std::cerr << "Switching to exact arithmetic" << std::endl; #ifdef CGAL_CKVA_USE_RATIONAL_ARITHMETIC - Bbox_2 bbox; - int res_w, res_h; - if(::boost::is_same::Is_exact, - CGAL::Tag_true>::value) + + if(::boost::is_same< + typename Algebraic_structure_traits< Float >::Is_exact, + CGAL::Tag_true>::value) goto Lexit; - get_window(bbox); - get_resolution(res_w, res_h); + get_setup_parameters(&bbox, res_w, res_h); exact_renderer().setup(bbox, res_w, res_h); - try { - points.clear(); - exact_renderer().draw(arc, points, end_points); + pts.clear(); + exact_renderer().draw(arc, pts, end_pts); return; } catch(CGALi::Insufficient_rasterize_precision_exception) { @@ -299,8 +294,9 @@ Lexit: std::cerr << "Sorry, this does not work even with exact " std::cerr << "polynomial: " << renderer().curve().polynomial_2() << std::endl; - renderer().get_window(bbox); - std::cerr << "window: " << bbox << std::endl; + renderer().get_setup_parameters(&bbox, res_w, res_h); + std::cerr << "window: " << bbox << "; resolution: " << + res_w << " x " << res_h << std::endl; #endif // CGAL_CKVA_USE_MULTIPREC_ARITHMETIC } @@ -308,9 +304,14 @@ Lexit: std::cerr << "Sorry, this does not work even with exact " } /*!\brief - * rasterizes a point on curve + * rasterizes a point on curve, returns point coordinates as objects of + * type \c Coord_2 which are constructible from a pair of ints / doubles + * + * retunrs \c false if point lies outside the window or cannot be + * rasterized due to precision problems */ - bool draw(const Point_2& point, CGALi::Coord_2& coord) { + template < class Coord_2 > + bool draw(const Point_2& point, Coord_2& coord) { #ifndef CGAL_CKVA_DUMMY_RENDERER try { return renderer().draw(point, coord); @@ -327,8 +328,6 @@ Lexit: std::cerr << "Sorry, this does not work even with exact " //!@} }; // Curve_renderer_interface - - CGAL_END_NAMESPACE #endif // CGAL_CKVA_CURVE_RENDERER_FACADE_H diff --git a/Curved_kernel_via_analysis_2/include/CGAL/Curved_kernel_via_analysis_2/gfx/Curve_renderer_2.h b/Curved_kernel_via_analysis_2/include/CGAL/Curved_kernel_via_analysis_2/gfx/Curve_renderer_2.h index 1343908c946..db687214bc9 100644 --- a/Curved_kernel_via_analysis_2/include/CGAL/Curved_kernel_via_analysis_2/gfx/Curve_renderer_2.h +++ b/Curved_kernel_via_analysis_2/include/CGAL/Curved_kernel_via_analysis_2/gfx/Curve_renderer_2.h @@ -64,7 +64,40 @@ CGAL_BEGIN_NAMESPACE // refine factor for clip-points #define CGAL_REFINE_CLIP_POINTS 1000 -#endif // CGAL_CURVE_RENDERER_DEFS +// refine threshold for double point approximation +#define CGAL_REFINE_DOUBLE_APPROX 1e-10 + +#ifdef CGAL_CKVA_RENDER_WITH_REFINEMENT +//!@note: points are drawn in any case even if they are outside the window +#warning approximation of curve arcs in coincide mode is not reliable ! \ + and also does not work with CORE::BigFloat (due to bug in it) + + #define CGAL_CKVA_STORE_COORDS(container, pixel) \ + container.push_back(Coord_2(pixel.xv, pixel.yv)); +#else + #define CGAL_CKVA_STORE_COORDS(container, pixel) \ + container.push_back(Coord_2(pixel.x, pixel.y)); +#endif + +#endif // CGAL_CURVE_RENDERER_DEFS + +namespace { +// map from box sides to subpixel numbers (for h/v directions) +// these are old versions +static const int HV_SUBPIX_MAP[][4] = { + {1,3,0,2}, // right(0) + {3,2,1,0}, // top(1) + {2,0,3,1}, // left(2) + {0,1,2,3} // bottom(3) +}; + +static const int D_SUBPIX_MAP[][4] = { + {3,1,2,0}, // dir = 0 + {2,3,0,1}, // dir = 1 + {0,2,1,3}, // dir = 2 + {1,0,3,2} // dir = 3 +}; +} // anonymous namespace /*! * \brief The class template \c Curve_renderer_2 and its associate functions. @@ -190,16 +223,16 @@ private: Renderer_traits::MAX_SUBDIVISION_LEVEL; //! pixel instance type - typedef CGALi::Pixel_2_templ Pixel_2; + typedef CGALi::Pixel_2_ Pixel_2; //! seed point instance type - typedef CGALi::Seed_point_templ Seed_point; + typedef CGALi::Seed_point_ Seed_point; //! support for multiple seed points typedef std::stack Seed_stack; //! map container element's type for maintaining a list of cache instances typedef std::pair LRU_entry; //! a range of x-coordinates to define bottom/top clip points - typedef CGALi::Clip_point_templ + typedef CGALi::Clip_point_ Clip_point_entry; //! a container of bottom/top clip points typedef std::vector Clip_points; @@ -224,18 +257,13 @@ private: //!@} public: - //! \name constructor + //! \name public methods //!@{ //! default constructor: a curve segment is undefined Curve_renderer_2() : cache_id(-1), initialized(false), one(1) { setup(Bbox_2(-1.0, -1.0, 1.0, 1.0), 640, 480); } - - //!@} -public: - //! \name public methods - //!@{ //! sets up drawing window and pixel resolution void setup(const Bbox_2& bbox_, int res_w_, int res_h_) { @@ -251,60 +279,25 @@ public: return *support; } - //! \brief returns the drawing window - void get_window(Bbox_2& bbox_) const { - bbox_ = engine.window; - } - - //! \brief returns the pixel resolution - void get_resolution(int& res_w_, int& res_h_) const { + //! \brief returns the drawing window and resolution + void get_setup_parameters(CGAL::Bbox_2 *pbox, int& res_w_, + int& res_h_) const { + if(pbox != NULL) + *pbox = engine.window; res_w_ = engine.res_w; res_h_ = engine.res_h; } - - //! \brief the main rendering procedure for curve arcs - //! returns a sequence of integer pixel coordinates \c points - //! - //! An exception \c Insufficient_rasterize_precision_exception is - //! thrown whenever the precision of currently used NT is not enough - //! to correctly render a curve arc. The exception has to be caught - //! outside the renderer to switch to a higher-precision arithmetic - void draw(const Arc_2& arc, std::list& points, - std::pair& end_points); - /*!\brief - * overloaded version to rasterize points on curves - */ - bool draw(const Point_2& pt, CGALi::Coord_2& coord); - + //! destructor + ~Curve_renderer_2() { + cache_list.clear(); + } + //!@} private: //! \name Private methods //!@{ - //! \brief switches to another cache instance depending on the - //! supporting curve of a segment - void select_cache_entry(const Arc_2& arc); - - //! \brief draws a piece of a semgment from pix_1 to pix_2 - void draw_lump(CGALi::Coord_vec_2& points, int& last_x, int arcno, - const Pixel_2& pix_1, const Pixel_2& pix_2); - - //! \brief copmutes an isolating interval for y-coordinate of an end-point, - //! uses caching if possible - Rational get_endpoint_y(const Arc_2& arc, const Rational& x, - CGAL::Arr_curve_end end, bool is_clipped); - - //! \brief returns whether a polynomial has zero over an interval, - //! we are not interested in concrete values - //! - //! a bit mask \c check indicates which boundaries are to be computed - //! 0th bit - of a polynomial itself (0th derivative, default) - //! 1st bit - of the first derivative (sets \c first_der flag) - //! 2nd bit - of the second derivative - bool get_range_1(int var, const NT& lower, const NT& upper, const NT& key, - const Poly_1& poly, int check = 1); - //! \brief advances pixel's coordinates by given increments void advance_pixel(Pixel_2& pix, int new_dir) { @@ -321,12 +314,6 @@ private: pix.sub_x = x&pow; pix.sub_y = y&pow; } -// int taken = CGALi::DIR_TAKEN_MAP[new_dir]; -// if(taken != -1&&taken!=direction_taken) { -// Gfx_OUT("ERROR: direction reversed at pixel: " << -// pix << " new_dir = " << new_dir << std::endl); -// throw -1; -// } } //! computes pixel coordinates from rational point @@ -335,12 +322,15 @@ private: { Rational p_x = (x - engine.x_min_r) / engine.pixel_w_r, p_y = (y - engine.y_min_r) / engine.pixel_h_r; + +#ifdef CGAL_CKVA_RENDER_WITH_REFINEMENT + pix.xv = CGAL::to_double(x); + pix.yv = CGAL::to_double(y); +#endif pix.x = static_cast(std::floor(CGAL::to_double(p_x))); - pix.y = static_cast(std::floor(CGAL::to_double(p_y))); - + pix.y = static_cast(std::floor(CGAL::to_double(p_y))); + if(ppix_x != NULL && ppix_y != NULL) { -// NiX::simplify(p_x); -// NiX::simplify(p_y); *ppix_x = p_x; *ppix_y = p_y; } @@ -351,79 +341,7 @@ private: while(ubound_y(xy) - lbound_y(xy) >= bound) refine_y(xy); } - - //! returns h/v boundaries for 8-pixel neighbourhood - void get_boundaries(int var, const Pixel_2& pix, Stripe& stripe); - - //! returns univariate polynomials (depending on subdivision level cache - //! might be used) - void get_polynomials(int var, Stripe& stripe); - - //! checks 8-pixel neighbourhood of a pixel, returns \c true if - //! only one curve branch intersects pixel's neighbourhood, \c dir - //! defines backward direction, \c new_dir is a new tracking direction - bool test_neighbourhood(const Pixel_2& pix, int dir, int& new_dir, - int step_x = 2, int step_y = 2); - -//#ifdef Gfx_DEBUG_PRINT - // debug only! - void dump_neighbourhood(const Pixel_2& pix); -//#else -// #define dump_neighbourhood ((void)0) -//#endif - - //! returns a subpixel which is crossed by the curve branch, subpixels - //! are tested w.r.t. preferred direction (only for h/v directions) - int get_subpixel_hv(const Pixel_2& pix, int pref_dir); - - //! the same for diagonal directions - int get_subpixel_diag(const Pixel_2& pix, int pref_dir); - - //! recursively subdivides pixel into 4 subpixels, returns a new tracking - //! direction - bool subdivide(Pixel_2& pix, int dir, int& new_dir); - - //! returns the starting witness pixel and two directions from it - bool get_seed_point(const Rational& seed, int arcno, Pixel_2& start, - int *dir, int *b_taken, bool& b_coincide); - - //! tests whether a polynomial has only one root over an interval - bool recursive_check(int var, const NT& beg, const NT& end, - const NT& key, const Poly_1& poly, int depth = 0); - - //! if success returns two directions among 8, where a curve branch - //! crosses the pixel's neighbourhood - bool test_pixel(const Pixel_2& pix, int *dir, int *b_taken, - bool& b_coincide); - - //! computes an isolating box of an end-point - bool get_isolating_box(const Rational& x_s, const Rational& y_s, - Pixel_2& res); - - //! returns true if \c pix is encompassed into one of isolating rectangles - //! (stopping criteria) - bool is_isolated_pixel(const Pixel_2& pix); - - //! computes clip points on top and bottom window boundaries - void horizontal_clip(); - - //! refines an algebraic point w.r.t. certain criteria - void refine_alg_point(Rational& l, Rational& r, const Poly_dst_1& poly, - const Rational& criteria, int mode=0); - - //! computes bottom and top horizontal clip-points of a segment - void segment_clip_points(const Rational& x_lower, const Rational& x_upper, - const Rational& y_lower, const Rational& y_upper, - const Rational& y_clip, const Poly_dst_1& poly, int arcno, - Clip_points& clip_points, index_vector& clip_indices); - -public: - //! destructor - ~Curve_renderer_2() - { - cache_list.clear(); - } - + //!@} private: //! \name Private properties @@ -460,15 +378,25 @@ private: int direction_taken; //! stores a direction taken from the seed point //! during tracking, if it's possible to determine //! 0 - towards lower point, 1 - towards upper - //!@} -}; // class Curve_renderer_2<> +//!@} +//!\name public methods +//!@{ -//! \brief main rasterization procedure, takes coordinates of event points and -//! the arc number and draws a curve segment -template -void Curve_renderer_2::draw( - const Arc_2& arc, std::list& points, - std::pair& end_points) +public: + +/*!\brief + * main rendering procedure for curve arcs + * returns a list of sequences of coordinates as objects of type \c Coord_2 + * which must be constructible from a pair of ints / doubles + * + * An exception \c Insufficient_rasterize_precision_exception is + * thrown whenever the precision of currently used NT is not enough + * to correctly render a curve arc. The exception has to be caught + * outside the renderer to switch to a higher-precision arithmetic + */ +template < class Coord_2, template < class > class Container > +void draw(const Arc_2& arc, Container< std::vector < Coord_2 > >& points, + CGAL::Twotuple< Coord_2 >& end_points) { if(!initialized) return; @@ -488,18 +416,9 @@ void Curve_renderer_2::draw( //!@todo: should be adapted for other boundary types if(loc_p1 != CGAL::ARR_LEFT_BOUNDARY) { const X_coordinate_1& x0 = arc.curve_end_x(CGAL::ARR_MIN_END); - - //while(x0.high() - x0.low() > engine.pixel_w_r/CGAL_REFINE_X) - // x0.refine(); - //lower = p1.finite().high(); - //if(!p1.finite().is_rational()&&!seg.is_vertical()) - // arcno_p1 = seg.arcno(); - while(ubound_x(x0) - lbound_x(x0) > engine.pixel_w_r/CGAL_REFINE_X) refine_x(x0); - lower = ubound_x(x0); -// NiX::simplify(lower); } else lower = engine.x_min_r; @@ -512,9 +431,7 @@ void Curve_renderer_2::draw( const X_coordinate_1& x0 = arc.curve_end_x(CGAL::ARR_MAX_END); while(ubound_x(x0) - lbound_x(x0) > engine.pixel_w_r/CGAL_REFINE_X) refine_x(x0); - upper = lbound_x(x0); -// NiX::simplify(upper); } else upper = engine.x_max_r; @@ -524,10 +441,12 @@ void Curve_renderer_2::draw( if(lower < engine.x_min_r) { lower = engine.x_min_r; clip_src = true; + loc_p1 = CGAL::ARR_INTERIOR; } if(upper > engine.x_max_r) { upper = engine.x_max_r; clip_tgt = true; + loc_p2 = CGAL::ARR_INTERIOR; } Rational height_r = (engine.y_max_r-engine.y_min_r)*2; @@ -563,9 +482,6 @@ void Curve_renderer_2::draw( infty_tgt = false; y_upper = get_endpoint_y(arc, upper, CGAL::ARR_MAX_END, clip_tgt); } - -// NiX::simplify(y_lower); -// NiX::simplify(y_upper); Pixel_2 pix_1, pix_2; Gfx_OUT("lower: " << CGAL::to_double(lower) << "; upper: " << @@ -575,26 +491,35 @@ void Curve_renderer_2::draw( get_pixel_coords(lower, y_lower, pix_1); get_pixel_coords(upper, y_upper, pix_2); - end_points.first.x = (clip_src ? engine.res_w+4 : pix_1.x); - end_points.first.y = pix_1.y; - end_points.second.x = (clip_tgt ? engine.res_w+4 : pix_2.x); - end_points.second.y = pix_2.y; + //(clip_src ? engine.res_w+4 : pix_1.x); + //(clip_tgt ? engine.res_w+4 : pix_2.x); +#ifdef CGAL_CKVA_RENDER_WITH_REFINEMENT + end_points.e0 = Coord_2(pix_1.xv, pix_1.yv); + end_points.e1 = Coord_2(pix_2.xv, pix_2.yv); +#else + end_points.e0 = Coord_2(pix_1.x, pix_1.y); + end_points.e1 = Coord_2(pix_2.x, pix_2.y); +#endif Gfx_OUT("lower pix: (" << pix_1.x << "; " << pix_1.y << ") upper pix: (" << pix_2.x << "; " << pix_2.y << ") pixel_w: " << engine.pixel_w << " pixel_h: " << engine.pixel_h << std::endl); - CGALi::Coord_vec_2 rev_points; + std::vector< Coord_2 > rev_points; // reserve at least enough space for arc's x-length rev_points.reserve(CGAL_ABS(pix_2.x - pix_1.x)); +#ifndef CGAL_CKVA_RENDER_WITH_REFINEMENT if(arc.is_vertical()) { - rev_points.push_back(CGALi::Coord_2(pix_1.x, pix_1.y)); - rev_points.push_back(CGALi::Coord_2(pix_2.x, pix_2.y)); + CGAL_CKVA_STORE_COORDS(rev_points, pix_1); + CGAL_CKVA_STORE_COORDS(rev_points, pix_2); points.push_back(rev_points); return; } +//!@todo no need to draw arc completely to obtain the refinement: just +//! loop over all pixels and collect the points +#endif // !CGAL_CKVA_RENDER_WITH_REFINEMENT if(!clip_pts_computed) { Gfx_OUT("computing clip points\n"); @@ -642,27 +567,28 @@ void Curve_renderer_2::draw( branches_coincide = false; // make a small tolerance - bool pt1_inside = (pix_1.y >= 0 && pix_1.y < engine.res_h), - pt2_inside = (pix_2.y >= 0 && pix_2.y < engine.res_h); + bool pt1_inside = (pix_1.y >= -1 && pix_1.y <= engine.res_h), + pt2_inside = (pix_2.y >= -1 && pix_2.y <= engine.res_h); //TODO: use Event1_info::multiplicity(i) - to gather information about roots ? if(seg_pts.size() == 1 && pt1_inside && pt2_inside) seg_pts.clear(); - + // easy case: no clip-points found if(seg_pts.size() == 0) { - if(!pt1_inside&&!pt2_inside) { + if(!pt1_inside && !pt2_inside) { Gfx_OUT("segment is outside\n"); return; } /// WARNING: if x-interval is small while y coordinates are far away from /// the window, we can get into the troubles.. - if(0){//pix_2.x - pix_1.x <= 1) {// it goes away right here - rev_points.push_back(CGALi::Coord_2(pix_1.x,pix_1.y)); - rev_points.push_back(CGALi::Coord_2(pix_2.x,pix_2.y)); + /*if(pix_2.x - pix_1.x <= 1) {// it goes away right here + rev_points.push_back(Coord_2(pix_1.x ,pix_1.y)); + rev_points.push_back(Coord_2(pix_2.x, pix_2.y)); points.push_back(rev_points); return; - } + } */ + Gfx_OUT("NO clip points\n"); mid = (lower + upper)/2; // NiX::simplify(mid); @@ -710,14 +636,17 @@ void Curve_renderer_2::draw( pclip = &btm_clip[idx]; ppoly = &btm_poly; y_clip = engine.y_min_r; + Gfx_OUT("bottom clip-point: ["); } else { // top points pclip = &top_clip[idx]; ppoly = &top_poly; y_clip = engine.y_max_r; + Gfx_OUT("up clip-point: ["); } l = pclip->left; r = pclip->right; - + Gfx_OUT(CGAL::to_double(l) << "; " << CGAL::to_double(r) << "\n"); + if(last_x != -engine.res_w) { // compute screen coordinates of a pixel Rational last_pt = engine.x_min_r + static_cast(last_x)* engine.pixel_w_r; @@ -743,7 +672,7 @@ void Curve_renderer_2::draw( } pix_beg = pix_1; get_pixel_coords(l, y_clip, pix_end); - + } else if(it == eend - 1 && pt2_inside) { Gfx_OUT("starting point is near the right end-point\n"); @@ -763,7 +692,7 @@ void Curve_renderer_2::draw( } pix_end = pix_2; get_pixel_coords(r, y_clip, pix_beg); - + } else { Gfx_OUT("starting point is between clip-points\n"); it++; @@ -779,28 +708,29 @@ void Curve_renderer_2::draw( 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); - + engine.y_min_r, pix_end); if(CGAL_ABS(ptmp->left - l) <= engine.pixel_w_r*2) { Xy_coordinate_2 xy(X_coordinate_1(pt), *support, arc.arcno()); refine_xy(xy, engine.pixel_h_r/CGAL_REFINE_Y); mid = ubound_y(xy); - rev_points.push_back(CGALi::Coord_2(pix_beg.x, pix_beg.y)); + CGAL_CKVA_STORE_COORDS(rev_points, pix_beg); get_pixel_coords(pt, mid, pix_beg); straight_segment = true; } } - +#ifndef CGAL_CKVA_RENDER_WITH_REFINEMENT if(straight_segment) { Gfx_OUT("straight subsegment found\n"); - rev_points.push_back(CGALi::Coord_2(pix_beg.x, pix_beg.y)); - rev_points.push_back(CGALi::Coord_2(pix_end.x, pix_end.y)); + CGAL_CKVA_STORE_COORDS(rev_points, pix_beg); + CGAL_CKVA_STORE_COORDS(rev_points, pix_end); + points.push_back(rev_points); it++; continue; } +#endif // !CGAL_CKVA_RENDER_WITH_REFINEMENT if(!get_seed_point(pt, arc.arcno(), start, dir, b_taken, b_coincide)) { @@ -824,13 +754,59 @@ void Curve_renderer_2::draw( isolated_h.level = -1u;*/ } +/*!\brief + * overloaded version to rasterize distinct points on curves + * + * \return \c false indicating that the point lies outside the drawing window + * \c true in case the point coordinates were successfully computed + */ +template < class Coord_2 > +bool draw(const Point_2& pt, Coord_2& coord) { + + Gfx_OUT("rasterizing point: " << pt << std::endl); + + const X_coordinate_1& x0 = pt.x(); + while(ubound_x(x0) - lbound_x(x0) > engine.pixel_w_r/2) + refine_x(x0); + + Rational x_s = lbound_x(x0), y_s; +//#ifndef CGAL_CKVA_RENDER_WITH_REFINEMENT + if(x_s < engine.x_min_r || x_s > engine.x_max_r) + return false; +//#endif + + Xy_coordinate_2 xy(x0, pt.curve(), pt.arcno()); + refine_xy(xy, engine.pixel_h_r / CGAL_REFINE_X); + y_s = ubound_y(xy); + + Pixel_2 pix; + get_pixel_coords(x_s, y_s, pix); +//#ifndef CGAL_CKVA_RENDER_WITH_REFINEMENT + if(pix.x < 0 || pix.x >= engine.res_w || pix.y < 0 || + pix.y >= engine.res_h) + return false; +//#endif + +#ifdef CGAL_CKVA_RENDER_WITH_REFINEMENT + coord = Coord_2(pix.xv, pix.yv); +#else + coord = Coord_2(pix.x, pix.y); +#endif + + return true; +} + +//!@} +private: +//!\name private methods +//!@{ + //! draws a segment's piece from pix_1 to pix_2, the starting pixel is taken //! from the seed point stack -template -void Curve_renderer_2::draw_lump( - CGALi::Coord_vec_2& rev_points, int& last_x, int arcno, - const Pixel_2& pix_1, const Pixel_2& pix_2) -{ +template < class Coord_2 > +void draw_lump(std::vector< Coord_2 >& rev_points, int& last_x, int arcno, + const Pixel_2& pix_1, const Pixel_2& pix_2) { + Pixel_2 start, pix, witness, prev_pix, stored_pix, stored_prev; int back_dir, new_dir, stored_dir, dir[2], b_taken[2], ux, uy; bool b_coincide, failed; @@ -846,25 +822,28 @@ void Curve_renderer_2::draw_lump( last_x = -engine.res_w; if(pix_1_close && pix_2_close) { // suppress drawing of trivial segments - rev_points.push_back(CGALi::Coord_2(pix_1.x,pix_1.y)); - rev_points.push_back(CGALi::Coord_2(pix_2.x,pix_2.y)); + CGAL_CKVA_STORE_COORDS(rev_points, pix_1); + CGAL_CKVA_STORE_COORDS(rev_points, pix_2); return; } - CGALi::Coord_vec_2 points; + std::vector< Coord_2 > points; // reserve a list of point coordinates points.reserve(CGAL_ABS(pix_2.x - pix_1.x)); direction_taken = -1; bool overstep = (pix_1_close||pix_2_close); bool ready = false; + while(!s_stack.empty()) { + current_seed = s_stack.top(); s_stack.pop(); branches_coincide = current_seed.branches_coincide; if(direction_taken == -1) direction_taken = current_seed.direction_taken; + witness = current_seed.start; pix = witness; current_level = witness.level; @@ -877,25 +856,23 @@ void Curve_renderer_2::draw_lump( stored_prev = pix; // store result in a list or reversed list depending on the orientation - CGALi::Coord_vec_2 *ppoints = (current_seed.orient == 0 ? - &rev_points : &points); + std::vector< Coord_2 > & ppoints = (direction_taken == 0 ? + rev_points : points); Gfx_OUT("continuing from a seed point: " << witness << "; back_dir: " << back_dir << " direction_taken: " << direction_taken << std::endl); bool is_exit = false; while(1) { -// #ifdef CGAL_CKVA_SYNCHRONOUS_CANCEL -// pthread_testcancel(); // this is a cancellation point -// #endif - if(pix.x < 0 || pix.x > engine.res_w || pix.y < -CGAL_WINDOW_ENLARGE|| pix.y > engine.res_h + CGAL_WINDOW_ENLARGE) { branches_coincide = false; break; } - ppoints->push_back(CGALi::Coord_2(pix.x, pix.y)); - + + CGAL_CKVA_STORE_COORDS(ppoints, pix); + +#ifndef CGAL_CKVA_RENDER_WITH_REFINEMENT if((direction_taken == 0 && pix.x <= pix_1.x) || (direction_taken == 1 && pix.x >= pix_2.x)) { //Gfx_OUT("STOP: reached end-point x-coordinate\n"); @@ -903,21 +880,21 @@ void Curve_renderer_2::draw_lump( is_exit = true; break; } +#endif // !CGAL_CKVA_RENDER_WITH_REFINEMENT bool set_ready = false; if(CGAL_ABS(pix.x - pix_1.x) <= 1 && CGAL_ABS(pix.y - pix_1.y) <= 1) { - if(!overstep||ready) { - pix.x = pix_1.x; - pix.y = pix_1.y; + if(!overstep || ready) { + pix = pix_1; branches_coincide = false; break; } set_ready = true; } + if(CGAL_ABS(pix.x - pix_2.x) <= 1 && CGAL_ABS(pix.y - pix_2.y) <= 1) { - if(!overstep||ready) { - pix.x = pix_2.x; - pix.y = pix_2.y; + if(!overstep || ready) { + pix = pix_2; branches_coincide = false; break; } @@ -925,6 +902,7 @@ void Curve_renderer_2::draw_lump( } if(set_ready) ready = true; + if(!test_neighbourhood(pix, back_dir, new_dir)) { ux = pix.x; uy = pix.y; @@ -941,6 +919,7 @@ void Curve_renderer_2::draw_lump( pix = witness; prev_pix = witness; } + stored_dir = -1; failed = false; while(ux == pix.x && uy == pix.y) { @@ -953,6 +932,7 @@ void Curve_renderer_2::draw_lump( stored_dir = back_dir; stored_prev = prev_pix; } + if(!test_neighbourhood(pix, back_dir, new_dir)) { if(stored_dir != -1) { pix = stored_pix; @@ -969,7 +949,7 @@ void Curve_renderer_2::draw_lump( } //Gfx_OUT(pix << " dir = " << new_dir << std::endl); prev_pix = pix; - advance_pixel(pix,new_dir); + advance_pixel(pix, new_dir); if(is_isolated_pixel(pix)) { branches_coincide = false; is_exit = true; @@ -979,6 +959,7 @@ void Curve_renderer_2::draw_lump( } if(is_exit) break; + stored_dir = back_dir; witness = pix; pix.level = 0; @@ -988,7 +969,7 @@ void Curve_renderer_2::draw_lump( } else { ux = pix.x; uy = pix.y; - advance_pixel(pix,new_dir); + advance_pixel(pix, new_dir); witness = pix; } back_dir = (new_dir+4)&7; @@ -1006,8 +987,7 @@ void Curve_renderer_2::draw_lump( Gfx_OUT("New seed point required at: " << pix << std::endl); if(!get_seed_point(engine.x_min_r+pix.x*engine.pixel_w_r, arcno, - start, dir, - b_taken, b_coincide)) { + start, dir, b_taken, b_coincide)) { std::cerr << " wrong seed point found " << std::endl; throw CGALi::Insufficient_rasterize_precision_exception(); } @@ -1018,6 +998,7 @@ void Curve_renderer_2::draw_lump( b_taken[0] = CGALi::DIR_TAKEN_MAP[dir[0]]; b_taken[1] = CGALi::DIR_TAKEN_MAP[dir[1]]; + if(b_taken[0] != -1) new_dir = dir[b_taken[0] != direction_taken ? 0: 1]; else if(b_taken[1] != -1) @@ -1027,98 +1008,53 @@ void Curve_renderer_2::draw_lump( dir[0] << " " << dir[1] << std::endl; throw CGALi::Insufficient_rasterize_precision_exception(); } - s_stack.push(Seed_point(start,new_dir, current_seed.orient, - direction_taken, b_coincide)); + + s_stack.push(Seed_point(start, new_dir, direction_taken, b_coincide)); continue; + } else if(is_exit) { -Lexit: if(direction_taken==0) { - pix.x = pix_1.x; - pix.y = pix_1.y; - } else if(direction_taken==1) { - pix.x = pix_2.x; - pix.y = pix_2.y; - } +Lexit: + pix = (direction_taken == 0 ? pix_1 : pix_2); } - ppoints->push_back(CGALi::Coord_2(pix.x, pix.y)); + + //!@note: this can cause missing end-points !! + //! if they proceeded by pt1/2_inside (-1 or res_h+1) + //if(pix.y >= 0 && pix.y < engine.res_h) + CGAL_CKVA_STORE_COORDS(ppoints, pix); // we were tracing in --> direction: store the pixel where we stopped if(direction_taken == 1) last_x = pix.x; + if(direction_taken != -1) direction_taken = 1 - direction_taken; ready = false; - } + + } // while(!s_stack.empty()) std::reverse(rev_points.begin(), rev_points.end()); + +// std::cerr << "reversed pts list:\n"; +// for(cvit = rev_points.begin(); cvit != rev_points.end(); cvit++) { +// std::cerr << cvit->x << "; " << cvit->y << "\n"; +// } +// std::cerr << "--------------normal pts list:\n"; +// for(cvit = points.begin(); cvit != points.end(); cvit++) { +// std::cerr << cvit->x << "; " << cvit->y << "\n"; +// } +// std::cerr << "==========================end\n"; // resize rev_points to accomodate the size of points vector unsigned rsize = rev_points.size(); rev_points.resize(rsize + points.size()); std::copy(points.begin(), points.end(), rev_points.begin() + rsize); } -/*!\brief - * overloaded version to rasterize distinct points on curves - * - * \return \c false indicating that the point lies outside the drawing window - * \c true in case the point coordinates were successfully computed - */ -template -bool Curve_renderer_2::draw( - const Point_2& pt, CGALi::Coord_2& coord) { -Gfx_OUT("refining x-range\n"); - const X_coordinate_1& x0 = pt.x(); - while(ubound_x(x0) - lbound_x(x0) > engine.pixel_w_r/2) - refine_x(x0); - - Rational x_s = lbound_x(x0), y_s; - if(x_s < engine.x_min_r || x_s > engine.x_max_r) - return false; - - Xy_coordinate_2 xy(x0, pt.curve(), pt.arcno()); -Gfx_OUT("refining y-range\n"); - refine_xy(xy, engine.pixel_h_r / CGAL_REFINE_X); - - /*typename Curve_analysis_2::Internal_curve_2::Event1_info - event = pt.curve()._internal_curve().event_info_at_x(pt.x()); - event.refine_to(pt.arcno(), engine.pixel_h_r/CGAL_REFINE_X); - y_s = event.lower_boundary(pt.arcno());*/ -Gfx_OUT("obtaining lower bounds"); - y_s = ubound_y(xy); - - Pixel_2 pix; - get_pixel_coords(x_s, y_s, pix); - if(pix.x < 0 || pix.x >= engine.res_w || pix.y < 0 || - pix.y >= engine.res_h) - return false; - - coord.x = pix.x; - coord.y = pix.y; - return true; -} - -namespace CGALi -{ -// map from box sides to subpixel numbers (for h/v directions) -// these are old versions -static const int HV_SUBPIX_MAP[][4] = { - {1,3,0,2}, // right(0) - {3,2,1,0}, // top(1) - {2,0,3,1}, // left(2) - {0,1,2,3}}; // bottom(3) -static const int D_SUBPIX_MAP[][4] = { - {3,1,2,0}, // dir = 0 - {2,3,0,1}, // dir = 1 - {0,2,1,3}, // dir = 2 - {1,0,3,2}}; // dir = 3 -} // namespace CGALi //! recursively subdivides pixel into 4 subpixels, returns a new tracking //! direction -template -bool Curve_renderer_2::subdivide( - Pixel_2& pix, int back_dir, int& new_dir) -{ +bool subdivide(Pixel_2& pix, int back_dir, int& new_dir) { + //Gfx_OUT("\n\nSubdivision of a pixel" << pix << " with back_dir = " << //back_dir << std::endl); NT inv = NT(1) / NT(one << pix.level); @@ -1141,14 +1077,14 @@ bool Curve_renderer_2::subdivide( if(branches_coincide) return false; - if(back_dir&1) { // diagonal direction + if(back_dir & 1) { // diagonal direction idx = get_subpixel_diag(pix,pref_dir); if(idx == -1) { std::cerr << "wrong diag subpixel: " << pix << " direction: " << pref_dir << std::endl; throw CGALi::Insufficient_rasterize_precision_exception(); } - idx = CGALi::D_SUBPIX_MAP[pref_dir][idx]; + idx = D_SUBPIX_MAP[pref_dir][idx]; } else { idx = get_subpixel_hv(pix,pref_dir); @@ -1157,7 +1093,7 @@ bool Curve_renderer_2::subdivide( pref_dir << std::endl; throw CGALi::Insufficient_rasterize_precision_exception(); } - idx = CGALi::HV_SUBPIX_MAP[pref_dir][idx]; + idx = HV_SUBPIX_MAP[pref_dir][idx]; } pix.level++; @@ -1178,11 +1114,9 @@ bool Curve_renderer_2::subdivide( } //! returns a "seed" point of a segment and two possible directions from it -template -bool Curve_renderer_2::get_seed_point( - const Rational& seed, int arcno, Pixel_2& start, int *dir, - int *b_taken, bool& b_coincide) -{ +bool get_seed_point(const Rational& seed, int arcno, Pixel_2& start, int *dir, + int *b_taken, bool& b_coincide) { + Rational x_s = seed, y_s; Xy_coordinate_2 xy(X_coordinate_1(seed), *support, arcno); @@ -1242,19 +1176,12 @@ bool Curve_renderer_2::get_seed_point( if(lvl > CGAL_REFINE_Y) { refine_xy(xy, engine.pixel_h_r/(lvl*2)); y_s = ubound_y(xy); -// event.refine_to(arcno, engine.pixel_h_r/(lvl*2)); - // y_s = event.upper_boundary(arcno); - - y_seed = (y_s - engine.y_min_r)/engine.pixel_h_r; -// NiX::simplify(y_seed); + y_seed = (y_s - engine.y_min_r)/engine.pixel_h_r; } start.sub_x = rat2integer((x_seed - start.x)*lvl); start.sub_y = rat2integer((y_seed - start.y)*lvl); - /*if(start.sub_x >= lvl || start.sub_x < 0 || - start.sub_y >= lvl || start.sub_y < 0) - Gfx_OUT << "bad subpixel found" << std::endl;*/ - + if(start.sub_x < 0) start.sub_x = 0; start.sub_x &= (lvl-1); @@ -1349,8 +1276,8 @@ bool Curve_renderer_2::get_seed_point( } else if(t1 == -1) b_taken[1] = 1 - b_taken[0]; - s_stack.push(Seed_point(start, dir[0], 1, b_taken[0], b_coincide)); - s_stack.push(Seed_point(start, dir[1], 0, b_taken[1], b_coincide)); + s_stack.push(Seed_point(start, dir[0], b_taken[0], b_coincide)); + s_stack.push(Seed_point(start, dir[1], b_taken[1], b_coincide)); } if(b_coincide) Gfx_DETAILED_OUT("seed point with coincide branches found" << @@ -1360,9 +1287,7 @@ bool Curve_renderer_2::get_seed_point( //! checks whether only one curve branch crosses the pixel, required to //! compute a starting witness pixel -template -bool Curve_renderer_2::test_pixel( - const Pixel_2& pix, int *dir, int *b_taken, bool& b_coincide) +bool test_pixel(const Pixel_2& pix, int *dir, int *b_taken, bool& b_coincide) { Stripe box[2]; // 0 - left-right stripe, 1 - bottom-top stripe NT lvl = NT(one << pix.level), inv = NT(1) / lvl; @@ -1616,8 +1541,7 @@ bool Curve_renderer_2::test_pixel( return true;*/ } -template -void Curve_renderer_2::horizontal_clip() +void horizontal_clip() { typedef typename CGAL::Fraction_traits F_traits; typename F_traits::Numerator_type num; @@ -1664,15 +1588,11 @@ void Curve_renderer_2::horizontal_clip() } // low_pix, up_pix and y_clip define segment end-points in pixel space -template -void Curve_renderer_2::segment_clip_points( - const Rational& x_lower, const Rational& x_upper, +void segment_clip_points(const Rational& x_lower, const Rational& x_upper, const Rational& y_lower, const Rational& y_upper, const Rational& y_clip, const Poly_dst_1& poly, int arcno, - Clip_points& clip_points, index_vector& clip_indices) -{ - //typename Curve_analysis_2::Internal_curve_2::Event1_info event; - + Clip_points& clip_points, index_vector& clip_indices) { + int n_arcs, i, j = 0; typename Clip_points::iterator it = clip_points.begin(); Rational low, high, d, l, r; @@ -1685,20 +1605,7 @@ void Curve_renderer_2::segment_clip_points( if(r > x_lower && l < x_upper) { X_coordinate_1 alpha = (l == r ? X_coordinate_1(r) : X_coordinate_1(poly, l, r)); -// if(l == r) -// Gfx_DETAILED_OUT("checking rational clip-point\n "); -// else { -// Gfx_DETAILED_OUT("checking [" << l << "; " << r << -// "] clip-point; poly = " << poly << -// "; support: " << support->polynomial_2() << " \n\n"); -// -// if(!CGAL::CGALi::is_square_free(poly)) -// std::cerr << "polynomial is not square-free!\n"; -// -// if(poly.sign_at(l) == poly.sign_at(r)) -// std::cerr << "signs are the same!!\n\n"; -// } - + // need precise comparisons in case of tight boundaries if(l < x_lower && alpha.compare(x_lower) != ::CGAL::LARGER) { it++; j++; @@ -1709,8 +1616,6 @@ void Curve_renderer_2::segment_clip_points( continue; } if(it->arcno == -1) { -// event = support->_internal_curve().event_info_at_x( -// alpha); Status_line_1 sline = support->status_line_for_x(alpha); n_arcs = sline.number_of_events(); for(i = 0; i < n_arcs; i++) { @@ -1756,13 +1661,11 @@ void Curve_renderer_2::segment_clip_points( } } -// mode = 0: criteria specifies the length of the refined interval -// mode = 1: criteria specifies a point that must be lie outside the interval -template -void Curve_renderer_2::refine_alg_point( - Rational& l, Rational& r, const Poly_dst_1& poly, - const Rational& criteria, int mode) -{ +//! mode = 0: criteria specifies the length of the refined interval +//! mode = 1: criteria specifies a point that must be lie outside the interval +void refine_alg_point(Rational& l, Rational& r, const Poly_dst_1& poly, + const Rational& criteria, int mode = 0) { + CGAL::Sign eval_l, eval_m; Rational mid; eval_l = poly.sign_at(l); @@ -1773,7 +1676,6 @@ void Curve_renderer_2::refine_alg_point( } else if(l > criteria || r < criteria) break; mid = (l+r)/2; -// NiX::simplify(mid); eval_m = poly.sign_at(mid); if(eval_m == CGAL::EQUAL) l = r = mid; @@ -1785,10 +1687,8 @@ void Curve_renderer_2::refine_alg_point( } //! recursively checks whether only one curve branch crosses a line segment -template -bool Curve_renderer_2::recursive_check( - int var, const NT& beg_, const NT& end_, const NT& key, const Poly_1& poly, - int depth) +bool recursive_check(int var, const NT& beg_, const NT& end_, + const NT& key, const Poly_1& poly, int depth = 0) { // if polynomial is linear/quadratic and there is sign-change over interval // => only one curve branch is guaranteed @@ -1832,10 +1732,8 @@ bool Curve_renderer_2::recursive_check( } //! computes lower/upper boundaries for pixel's neighbourhood -template -void Curve_renderer_2::get_boundaries( - int var, const Pixel_2& pix, Stripe& stripe) -{ +void get_boundaries(int var, const Pixel_2& pix, Stripe& stripe) { + int level = pix.level, val = pix.y; Integer sub = pix.sub_y, cur_sub; if(var == CGAL_Y_RANGE) { @@ -1868,22 +1766,22 @@ void Curve_renderer_2::get_boundaries( } //! shortcut to get precached polynomials -template - void Curve_renderer_2::get_polynomials( - int var, Stripe& stripe) -{ +inline void get_polynomials(int var, Stripe& stripe) { engine.get_precached_poly(var, stripe.key[1], stripe.level[1], stripe.poly[1]); engine.get_precached_poly(var, stripe.key[0], stripe.level[0], stripe.poly[0]); } -//! \brief checks 8-pixel neighbourhood of a pixel, returns \c true if -//! only one curve branch intersects pixel's neighbourhood, \c dir -//! defines backward direction, \c new_dir is a new tracking direction -template -bool Curve_renderer_2::test_neighbourhood( - const Pixel_2& pix, int dir, int& new_dir, int step_x, int step_y) +/*! + * checks 8-pixel neighbourhood of a pixel, returns \c true if + * only one curve branch intersects pixel's neighbourhood, \c dir + * defines backward direction, \c new_dir is a new tracking direction + * + * if \c CGAL_CKVA_RENDER_WITH_REFINEMENT is set, in case of success \c pix + * receives double approximations of intersection point + */ +bool test_neighbourhood(Pixel_2& pix, int dir, int& new_dir) { NT lvl = NT(one << pix.level); NT inv = NT(1.0) / lvl; @@ -2101,8 +1999,6 @@ bool Curve_renderer_2::test_neighbourhood( if(!set_coincide && f_der && !recursive_check(var,lower,lower+inv, box[ibox].key[ikey], box[ibox].poly[ikey])) { - //Gfx_DETAILED_OUT("first derivative presented" << std::endl); - if(!branches_coincide && (current_level < CGAL_COINCIDE_LEVEL))//||direction_taken == -1)) return false; @@ -2111,8 +2007,9 @@ bool Curve_renderer_2::test_neighbourhood( std::endl); set_coincide = true; } + int taken = CGALi::DIR_TAKEN_MAP[new_dir]; - if(taken != -1&&taken != direction_taken) { + if(taken != -1 && taken != direction_taken) { Gfx_DETAILED_OUT("\nERROR: wrong direction " << new_dir << " at pixel: " << pix << "; back_dir = " << back_dir << "; taken = " << @@ -2124,20 +2021,92 @@ bool Curve_renderer_2::test_neighbourhood( else return false; } - if(set_coincide) + if(set_coincide) { branches_coincide = true; +#ifdef CGAL_CKVA_RENDER_WITH_REFINEMENT + std::cerr << "WARNING: unreliable approximation in coincide mode\n"; + + NT x = lower + inv/2, y = box[ibox].key[ikey]; // take median + make_exact(x); + if(var == CGAL_Y_RANGE) + std::swap(x, y); + + pix.xv = CGAL::to_double(engine.x_min + x*engine.pixel_w); + pix.yv = CGAL::to_double(engine.y_min + y*engine.pixel_h); +#endif + } +#ifdef CGAL_CKVA_RENDER_WITH_REFINEMENT + else + compute_double_approx(var, lower, lower+inv, box[ibox].key[ikey], + box[ibox].poly[ikey], pix); +#endif return true; } +#ifdef CGAL_CKVA_RENDER_WITH_REFINEMENT +void compute_double_approx(int var, const NT& l_, const NT& r_, + const NT& key, const Poly_1& poly, Pixel_2& pix) { -//! \brief returns whether a polynomial has zero at a given interval, + NT l(l_), r(r_); + if(l > r) { + l = r_; + r = l_; + } + + int eval1, eval2, mid_eval; + NT threshold(CGAL_REFINE_DOUBLE_APPROX); + eval1 = engine.evaluate_generic(var, l, key, poly); + if(eval1 == 0) + goto Lexit; + + eval2 = engine.evaluate_generic(var, r, key, poly); + if(eval2 == 0) { + l = r; + goto Lexit; + } + + if(eval1 == eval2) { + std::cerr << "ERROR: no sign change in compute_double_approx\n"; + l = (l+r)/NT(2); + make_exact(l); + goto Lexit; + } + + while((r - l) > threshold) { + NT mid = (l + r) / NT(2); + make_exact(mid); + //Gfx_DETAILED_OUT("current approx: " << (r - l) << "; threshold = " << threshold << "\n"); + //Gfx_DETAILED_OUT("l = " << l << "; r = " << r << "; mid = " << mid << "\n"); + mid_eval = engine.evaluate_generic(var, mid, key, poly); + if(mid_eval == 0) { + l = r = mid; + break; + } + if(mid_eval == eval1) + l = mid; + else + r = mid; + } +Lexit: + NT x = l, y = key; + if(var == CGAL_Y_RANGE) { + x = key; + y = l; + } + pix.xv = CGAL::to_double(engine.x_min + x*engine.pixel_w); + pix.yv = CGAL::to_double(engine.y_min + y*engine.pixel_h); +} +#endif // CGAL_CKVA_RENDER_WITH_REFINEMENT + +//! \brief returns whether a polynomial has zero over an interval, //! we are not interested in concrete values //! -//! if \t der_check is set a range for the first derivative is also computed -template -inline bool Curve_renderer_2:: - get_range_1(int var, const NT& lower, const NT& upper, const NT& key, - const Poly_1& poly, int check) +//! a bit mask \c check indicates which boundaries are to be computed +//! 0th bit - of a polynomial itself (0th derivative, default) +//! 1st bit - of the first derivative (sets \c first_der flag) +//! 2nd bit - of the second derivative +inline bool get_range_1(int var, const NT& lower, const NT& upper, + const NT& key, const Poly_1& poly, int check = 1) { bool res = engine.get_range_QF_1(var, lower, upper, key, poly, check); //engine.get_range_MAA_1(var, lower, upper, key, poly, check); @@ -2146,34 +2115,24 @@ inline bool Curve_renderer_2:: //! \brief copmutes an isolating interval for y-coordinate of an end-point, //! uses caching if possible -template -typename Curve_renderer_2::Rational -Curve_renderer_2::get_endpoint_y( - const Arc_2& arc, const Rational& x, CGAL::Arr_curve_end end, - bool is_clipped) { +Rational get_endpoint_y(const Arc_2& arc, const Rational& x, + CGAL::Arr_curve_end end, bool is_clipped) { -// typename Curve_analysis_2::Internal_curve_2::Event1_info event; int arcno; Xy_coordinate_2 xy; if(arc.location(end) != CGAL::ARR_LEFT_BOUNDARY && arc.location(end) != CGAL::ARR_RIGHT_BOUNDARY && !is_clipped) { - //event = arc.curve_end(end).curve()._internal_curve(). - // event_info_at_x(arc.curve_end_x(end)); arcno = arc.curve_end(end).arcno(); xy = Xy_coordinate_2(arc.curve_end_x(end), arc.curve_end(end).curve(), arcno); } else { - //sline = support->status_line_for_x(X_coordinate_1(x)); - //event = support->_internal_curve().event_info_at_x( - // X_coordinate_1(x)); arcno = arc.arcno(); xy = Xy_coordinate_2(X_coordinate_1(x), *support, arcno); } // refine the y-interval until its size is smaller than the pixel size ////////////////////////// CHANGED REFINE_Y by REFINE_X - //event.refine_to(arcno, engine.pixel_h_r/CGAL_REFINE_X); refine_xy(xy, engine.pixel_h_r/CGAL_REFINE_X); ////////////////////////// CHANGED REFINE_Y by REFINE_X return ubound_y(xy);//event.upper_boundary(arcno); @@ -2181,10 +2140,8 @@ Curve_renderer_2::get_endpoint_y( //! \brief switches to a certain cache instance depending on currently used //! algebraic curve -template -void Curve_renderer_2::select_cache_entry( - const Arc_2& arc) -{ +void select_cache_entry(const Arc_2& arc) { + typename boost::multi_index::nth_index::type& idx = cache_list.get<1>(); typename boost::multi_index::nth_index_iterator::type @@ -2225,9 +2182,7 @@ void Curve_renderer_2::select_cache_entry( //! subpixels are chosen with the priority \c dir which defines a preferred //! direction, i.e. right(0), top(1), left(2) or bottom(3) this is only for h/v //! directions -template -int Curve_renderer_2::get_subpixel_hv( - const Pixel_2& pix, int dir) +int get_subpixel_hv(const Pixel_2& pix, int dir) { Poly_1 box[4]; NT inv = NT(1) / NT(one << pix.level), inv_2; @@ -2298,9 +2253,7 @@ int Curve_renderer_2::get_subpixel_hv( //! \brief the same for diagonal directions //! //! preferred direction: NE(0), NW(1), SW(2), SE(3) -template -int Curve_renderer_2::get_subpixel_diag( - const Pixel_2& pix, int dir) +int get_subpixel_diag(const Pixel_2& pix, int dir) { Poly_1 box[4]; NT inv = NT(1) / NT(one << pix.level); @@ -2377,9 +2330,7 @@ int Curve_renderer_2::get_subpixel_diag( //! attempts to find an isolating box for an end-point whose upper/lower //! boundaries do not intersect with a curve -template -bool Curve_renderer_2::get_isolating_box( - const Rational& x_s, const Rational& y_s, Pixel_2& res) +bool get_isolating_box(const Rational& x_s, const Rational& y_s, Pixel_2& res) { Integer lvl = one; Rational x_seed, y_seed; @@ -2442,11 +2393,7 @@ bool Curve_renderer_2::get_isolating_box( //! returns true if \c pix is encompassed into one of isolating rectangles //! (stopping criteria) -template -inline bool -Curve_renderer_2::is_isolated_pixel( - const Pixel_2& pix) -{ +inline bool is_isolated_pixel(const Pixel_2& pix) { /*Integer sub_x; if(isolated_l.level != -1u&&isolated_l.y == pix.y&&isolated_l.x == pix.x&& pix.level >= isolated_l.level) { @@ -2465,10 +2412,8 @@ Curve_renderer_2::is_isolated_pixel( #ifdef Gfx_DEBUG_PRINT // DEBUG ONLY -template -void Curve_renderer_2::dump_neighbourhood( - const Pixel_2& pix) -{ +void dump_neighbourhood(const Pixel_2& pix) { + CGAL::set_mode(std::cerr, CGAL::IO::PRETTY); CGAL::set_mode(std::cout, CGAL::IO::PRETTY); @@ -2653,6 +2598,9 @@ void Curve_renderer_2::dump_neighbourhood( } #endif +//!@} +}; // class Curve_renderer_2<> + //!@} CGAL_END_NAMESPACE diff --git a/Curved_kernel_via_analysis_2/include/CGAL/Curved_kernel_via_analysis_2/gfx/Curve_renderer_internals.h b/Curved_kernel_via_analysis_2/include/CGAL/Curved_kernel_via_analysis_2/gfx/Curve_renderer_internals.h index 925aa78ef58..ee809e3c4f4 100644 --- a/Curved_kernel_via_analysis_2/include/CGAL/Curved_kernel_via_analysis_2/gfx/Curve_renderer_internals.h +++ b/Curved_kernel_via_analysis_2/include/CGAL/Curved_kernel_via_analysis_2/gfx/Curve_renderer_internals.h @@ -82,45 +82,61 @@ static const int DIR_TAKEN_MAP[] = {1, 1, -1, 0, 0, 0, -1, 1}; template -struct Pixel_2_templ +struct Pixel_2_ { int x, y; // pixel coordinates relative to the drawing area unsigned level; // subdivision level: 0 - for pixels, // 1 - for 1/2 pixels, and so on) +#ifdef CGAL_CKVA_RENDER_WITH_REFINEMENT + double xv, yv; // double approximation of curve-pixel intersection point +#endif + Integer sub_x, sub_y; // subpixel coordinates relative to pixel's boundary // (always 0 for pixels) - bool operator ==(const Pixel_2_templ& pix) const - { + + Pixel_2_& operator =(const Pixel_2_& pix) { +#ifdef CGAL_CKVA_RENDER_WITH_REFINEMENT + memcpy(this, &pix, sizeof(int)*3 + sizeof(double)*2); +#else + memcpy(this, &pix, sizeof(int)*3); +#endif + sub_x = pix.sub_x; + sub_y = pix.sub_y; + return *this; + } + + bool operator ==(const Pixel_2_& pix) const { if(memcmp(this, &pix, sizeof(int)*3)) return false; - return (sub_x==pix.sub_x&&sub_y==pix.sub_y); + return (sub_x == pix.sub_x && sub_y == pix.sub_y); } }; // structure describing the seed point and backward direction, support for // multiple seed points template -struct Seed_point_templ +struct Seed_point_ { - Seed_point_templ() + Seed_point_() { } - Seed_point_templ(const Pixel_2_templ& start_, int dir_, - int orient_, int taken_, bool coincide_) : start(start_), - back_dir(dir_), orient(orient_), direction_taken(taken_), + + Seed_point_(const Pixel_2_& start_, int dir_, + int taken_, bool coincide_) : start(start_), + back_dir(dir_), direction_taken(taken_), branches_coincide(coincide_) { } - Pixel_2_templ start; // starting pixel + + Pixel_2_ start; // starting pixel int back_dir; // backward direction - int orient; // 0 - push_back, 1 - push_front int direction_taken; bool branches_coincide; }; template -struct Clip_point_templ // describes a bottom/top clip point +struct Clip_point_ // describes a bottom/top clip point { - Clip_point_templ() { } - Clip_point_templ(Rational left_, Rational right_, int arcno_=-1) : + Clip_point_() { } + Clip_point_(Rational left_, Rational right_, int arcno_=-1) : left(left_), right(right_), arcno(arcno_) { } Rational left, right; // isolating interval boundaries int arcno; // arcno of a segment this point belongs to @@ -128,7 +144,7 @@ struct Clip_point_templ // describes a bottom/top clip point }; template -std::ostream& operator <<(std::ostream& os, const Pixel_2_templ& pix) +std::ostream& operator <<(std::ostream& os, const Pixel_2_& pix) { os << " (" << pix.x << "/" << pix.sub_x << "; " << pix.y << "/" << pix.sub_y << ") level = " << pix.level; @@ -140,17 +156,6 @@ std::ostream& operator <<(std::ostream& os, const Pixel_2_templ& pix) class Insufficient_rasterize_precision_exception { }; -struct Coord_2 { - - Coord_2() { - } - Coord_2(int x_, int y_) : x(x_), y(y_) { - } - int x, y; -}; - -typedef std::vector Coord_vec_2; - /*! \brief defines class \c Curve_renderer_internals * * provides an interface to low-level range analysis and polynomials evaluation @@ -502,9 +507,9 @@ bool Curve_renderer_internals::setup( res_w = res_w_; res_h = res_h_; - if(x_min >= x_max||y_min >= y_max||res_w < 5||res_h < 5||res_w > 1024|| - res_h > 1024) { - Gfx_OUT("Incorrect setup parameters" << std::endl); + if(x_min >= x_max||y_min >= y_max||res_w < 4||res_h < 4||res_w > 2048|| + res_h > 2048) { + std::cerr << "Incorrect setup parameters" << std::endl; return false; } @@ -515,8 +520,6 @@ bool Curve_renderer_internals::setup( pixel_w_r = (x_max_r - x_min_r) / res_w; pixel_h_r = (y_max_r - y_min_r) / res_h; -// NiX::simplify(pixel_w_r); -// NiX::simplify(pixel_h_r); pixel_w = rat2float(pixel_w_r); pixel_h = rat2float(pixel_h_r); @@ -863,10 +866,6 @@ int Curve_renderer_internals::evaluate_generic( } else c1 = y_min + c*pixel_h; - if(show_dump) { - //Gfx_OUT("evaluate " << poly << " at: " << c1 << "\n"); - } - if(!not_cached) { hash_key.first = x_min + x*pixel_w; hash_key.second = y_min + y*pixel_h; diff --git a/Curved_kernel_via_analysis_2/include/CGAL/IO/Qt_widget_Curve_renderer_2.h b/Curved_kernel_via_analysis_2/include/CGAL/IO/Qt_widget_Curve_renderer_2.h index c6c5d2be2b3..ffeeeae1edf 100644 --- a/Curved_kernel_via_analysis_2/include/CGAL/IO/Qt_widget_Curve_renderer_2.h +++ b/Curved_kernel_via_analysis_2/include/CGAL/IO/Qt_widget_Curve_renderer_2.h @@ -29,15 +29,16 @@ CGAL_BEGIN_NAMESPACE * outputs a curve arc to \c Qt_widget */ template -Qt_widget& operator << (Qt_widget& ws, const typename CKvA_2::Arc_2& arc) { +Qt_widget& operator << (Qt_widget& ws, const CGALi::Arc_2< CKvA_2 >& arc) { typedef Curve_renderer_facade Facade; - typedef typename Facade::Coord_vec_2 Coord_vec_2; - typedef typename Facade::Coord_2 Coord_2; + typedef CGAL::Twotuple< int > Coord_2; + typedef std::vector< Coord_2 > Coord_vec_2; + + CGAL::Twotuple< Coord_2 > end_points; std::list points; - std::pair end_points; - + Facade::setup(CGAL::Bbox_2(ws.x_min(), ws.y_min(), ws.x_max(), ws.y_max()), ws.width(), ws.height()); @@ -48,6 +49,8 @@ Qt_widget& operator << (Qt_widget& ws, const typename CKvA_2::Arc_2& arc) { QPainter *ppnt = &ws.get_painter(); int height = ws.height(); + // std::cerr << ws.width() << " and " << ws.height() << "\n"; + typename std::list::const_iterator lit = points.begin(); while(lit != points.end()) { @@ -55,15 +58,18 @@ Qt_widget& operator << (Qt_widget& ws, const typename CKvA_2::Arc_2& arc) { typename Coord_vec_2::const_iterator vit = vec.begin(); if(vec.size() == 2) { - ppnt->moveTo(vit->x, height - vit->y); + ppnt->moveTo(vit->e0, height - vit->e1); vit++; - ppnt->lineTo(vit->x, height - vit->y); + ppnt->lineTo(vit->e0, height - vit->e1); } else { - ppnt->moveTo(vit->x, height - vit->y); + ppnt->moveTo(vit->e0, height - vit->e1); + //std::cerr << "(" << vit->e0 << "; " << vit->e1 << "\n"; while(vit != vec.end()) { - ppnt->lineTo(vit->x, height - vit->y); + ppnt->lineTo(vit->e0, height - vit->e1); vit++; + //if(vit != vec.end()) + //std::cerr << "(" << vit->e0 << "; " << vit->e1 << "\n"; } } lit++; @@ -72,9 +78,8 @@ Qt_widget& operator << (Qt_widget& ws, const typename CKvA_2::Arc_2& arc) { QPen old_pen = ppnt->pen(); ppnt->setPen(QPen(Qt::NoPen)); // avoid drawing outlines // draw with the current brush attributes - ppnt->drawEllipse(end_points.first.x-3,height-end_points.first.y-3, 6, 6); - ppnt->drawEllipse(end_points.second.x-3,height-end_points.second.y-3, - 6, 6); + ppnt->drawEllipse(end_points.e0.e0-3,height-end_points.e0.e1-3, 6, 6); + ppnt->drawEllipse(end_points.e1.e0-3,height-end_points.e1.e1-3, 6, 6); ppnt->setPen(old_pen); return ws; @@ -84,11 +89,11 @@ Qt_widget& operator << (Qt_widget& ws, const typename CKvA_2::Arc_2& arc) { * outputs a curve point to \c Qt_widget */ template -Qt_widget& operator << (Qt_widget& ws, const typename CKvA_2::Point_2& pt) { +Qt_widget& operator << (Qt_widget& ws, const CGALi::Point_2< CKvA_2 >& pt) { typedef Curve_renderer_facade Facade; - typename Facade::Coord_2 coord; + CGAL::Twotuple< int > coord; Facade::setup(CGAL::Bbox_2(ws.x_min(), ws.y_min(), ws.x_max(), ws.y_max()), ws.width(), ws.height()); diff --git a/Curved_kernel_via_analysis_2/include/CGAL/Quadrical_kernel_via_analysis_2.h b/Curved_kernel_via_analysis_2/include/CGAL/Quadrical_kernel_via_analysis_2.h index a51524abbe2..6fe1cc73c8f 100644 --- a/Curved_kernel_via_analysis_2/include/CGAL/Quadrical_kernel_via_analysis_2.h +++ b/Curved_kernel_via_analysis_2/include/CGAL/Quadrical_kernel_via_analysis_2.h @@ -29,7 +29,7 @@ #include #include -#ifdef CGAL_CKvA_COMPILE_RENDERER +#ifdef CGAL_CKVA_COMPILE_RENDERER #include #endif @@ -195,7 +195,7 @@ public: //!\name approximation & visualization //!@{ -#ifdef CGAL_CKvA_COMPILE_RENDERER +#ifdef CGAL_CKVA_COMPILE_RENDERER //! sets up rendering window \c bbox and resolution \c res_w by \c res_h static void setup_renderer(CGAL::Bbox_2 bbox, int res_w, int res_h) { @@ -261,7 +261,7 @@ public: result = Approximation_3(x0, y0, compute_z(ppt, this->sheet())); return true; } -#endif // CGAL_CKvA_COMPILE_RENDERER +#endif // CGAL_CKVA_COMPILE_RENDERER //!@} //! for constructint points @@ -585,7 +585,7 @@ public: //!\name visualization //!@{ -#ifdef CGAL_CKvA_COMPILE_RENDERER +#ifdef CGAL_CKVA_COMPILE_RENDERER @@ -645,7 +645,7 @@ public: } -#endif // CGAL_CKvA_COMPILE_RENDERER +#endif // CGAL_CKVA_COMPILE_RENDERER //!@} // friends