Replaced get_data() and set_data() with get_env_data() and set_env_data() to avoid clashes with other extensions of the Dcel;

This commit is contained in:
Efi Fogel 2024-01-30 00:59:19 +02:00
parent afff35cbdd
commit b25a697fd6
6 changed files with 995 additions and 1563 deletions

View File

@ -8,8 +8,9 @@
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
// //
// //
// Author(s) : Michal Meyerovitch <gorgymic@post.tau.ac.il> // Author(s) : Michal Meyerovitch <gorgymic@post.tau.ac.il>
// Baruch Zukerman <baruchzu@post.tau.ac.il> // Baruch Zukerman <baruchzu@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
#ifndef CGAL_ENVELOPE_OVERLAY_2_H #ifndef CGAL_ENVELOPE_OVERLAY_2_H
#define CGAL_ENVELOPE_OVERLAY_2_H #define CGAL_ENVELOPE_OVERLAY_2_H
@ -17,40 +18,38 @@
#include <CGAL/license/Envelope_3.h> #include <CGAL/license/Envelope_3.h>
#include <iostream>
#include <CGAL/Arr_overlay_2.h> #include <CGAL/Arr_overlay_2.h>
#include <CGAL/Envelope_3/Envelope_overlay_functor.h> #include <CGAL/Envelope_3/Envelope_overlay_functor.h>
#include <iostream>
namespace CGAL { namespace CGAL {
template <class MinimizationDiagram_2, template <typename MinimizationDiagram_2,
class OverlayFunctor = Envelope_overlay_functor<MinimizationDiagram_2> > typename OverlayFunctor =
class Envelope_overlay_2 Envelope_overlay_functor<MinimizationDiagram_2>>
{ class Envelope_overlay_2 {
public: public:
typedef MinimizationDiagram_2 Minimization_diagram_2; using Minimization_diagram_2 = MinimizationDiagram_2;
typedef typename Minimization_diagram_2::Face_handle Face_handle; using Face_handle = typename Minimization_diagram_2::Face_handle;
typedef typename Minimization_diagram_2::Face_iterator Face_iterator; using Face_iterator = typename Minimization_diagram_2::Face_iterator;
typedef typename Minimization_diagram_2::Vertex_handle Vertex_handle; using Vertex_handle = typename Minimization_diagram_2::Vertex_handle;
typedef typename Minimization_diagram_2::Vertex_iterator Vertex_iterator; using Vertex_iterator = typename Minimization_diagram_2::Vertex_iterator;
typedef typename Minimization_diagram_2::Halfedge_handle Halfedge_handle; using Halfedge_handle = typename Minimization_diagram_2::Halfedge_handle;
typedef typename Minimization_diagram_2::Halfedge_iterator Halfedge_iterator; using Halfedge_iterator = typename Minimization_diagram_2::Halfedge_iterator;
using Overlay_functor = OverlayFunctor;
typedef OverlayFunctor Overlay_functor;
protected: protected:
typedef typename Minimization_diagram_2::Geometry_traits_2 Traits; using Traits = typename Minimization_diagram_2::Geometry_traits_2;
typedef typename Traits::Xy_monotone_surface_3 Xy_monotone_surface_3; using Xy_monotone_surface_3 = typename Traits::Xy_monotone_surface_3;
public: public:
void operator()(Minimization_diagram_2& md1, Minimization_diagram_2& md2,
void operator()(Minimization_diagram_2& md1, Minimization_diagram_2& result) {
Minimization_diagram_2& md2,
Minimization_diagram_2& result)
{
CGAL_assertion(md1.is_valid()); CGAL_assertion(md1.is_valid());
CGAL_assertion(md2.is_valid()); CGAL_assertion(md2.is_valid());
@ -60,9 +59,7 @@ public:
CGAL_assertion_code(post_test_assertions(result)); CGAL_assertion_code(post_test_assertions(result));
} }
public: public:
/* /*
void print_face(Face_handle fh) void print_face(Face_handle fh)
{ {
@ -72,7 +69,7 @@ public:
{ {
std::cout << " #data= " << fh->number_of_data_objects(); std::cout << " #data= " << fh->number_of_data_objects();
if (fh->number_of_data_objects() > 0) if (fh->number_of_data_objects() > 0)
std::cout << " data= " << fh->get_data(); std::cout << " data= " << fh->get_env_data();
} }
if (fh->get_aux_is_set(0)) if (fh->get_aux_is_set(0))
@ -114,7 +111,7 @@ public:
{ {
std::cout << " #data= " << vh->number_of_data_objects(); std::cout << " #data= " << vh->number_of_data_objects();
if (vh->number_of_data_objects() > 0) if (vh->number_of_data_objects() > 0)
std::cout << " data= " << vh->get_data(); std::cout << " data= " << vh->get_env_data();
} }
if (vh->get_aux_is_set(0)) if (vh->get_aux_is_set(0))
@ -146,7 +143,7 @@ public:
{ {
std::cout << " #data= " << hh->number_of_data_objects(); std::cout << " #data= " << hh->number_of_data_objects();
if (hh->number_of_data_objects() > 0) if (hh->number_of_data_objects() > 0)
std::cout << " data= " << hh->get_data(); std::cout << " data= " << hh->get_env_data();
} }
@ -169,75 +166,68 @@ public:
} }
*/ */
void post_test_assertions(Minimization_diagram_2& md) void post_test_assertions(Minimization_diagram_2& md) {
{
// check that all data is filled in result // check that all data is filled in result
Face_iterator fi = md.faces_begin(); for (auto fi = md.faces_begin(); fi != md.faces_end(); ++fi) {
for(; fi != md.faces_end(); ++fi)
{
Face_handle fh = fi; Face_handle fh = fi;
CGAL_assertion_msg(fh->get_aux_is_set(0), "data from md1 on face is not set"); CGAL_assertion_msg(fh->get_aux_is_set(0),
CGAL_assertion_msg(fh->get_aux_is_set(1), "data from md2 on face is not set"); "data from md1 on face is not set");
CGAL_assertion_msg(fh->get_aux_is_set(1),
"data from md2 on face is not set");
} }
Halfedge_iterator hi = md.halfedges_begin(); for (auto hi = md.halfedges_begin(); hi != md.halfedges_end(); ++hi) {
for(; hi != md.halfedges_end(); ++hi)
{
Halfedge_handle hh = hi; Halfedge_handle hh = hi;
CGAL_assertion_msg(hh->get_aux_is_set(0), "data from md1 on halfedge is not set"); CGAL_assertion_msg(hh->get_aux_is_set(0),
CGAL_assertion_msg(hh->get_aux_is_set(1), "data from md2 on halfedge is not set"); "data from md1 on halfedge is not set");
CGAL_assertion_msg(hh->get_aux_is_set(1),
"data from md2 on halfedge is not set");
} }
Vertex_iterator vi = md.vertices_begin(); for (auto vi = md.vertices_begin(); vi != md.vertices_end(); ++vi) {
for(; vi != md.vertices_end(); ++vi)
{
Vertex_handle vh = vi; Vertex_handle vh = vi;
CGAL_assertion_msg(vh->get_aux_is_set(0), "data from md1 on vertex is not set"); CGAL_assertion_msg(vh->get_aux_is_set(0),
CGAL_assertion_msg(vh->get_aux_is_set(1), "data from md2 on vertex is not set"); "data from md1 on vertex is not set");
CGAL_assertion_msg(vh->get_aux_is_set(1),
"data from md2 on vertex is not set");
} }
} }
protected: protected:
// helper methods // helper methods
template <class FeatureHandle> template <typename FeatureHandle>
Xy_monotone_surface_3 get_aux_data(FeatureHandle fh, unsigned int id) Xy_monotone_surface_3 get_aux_data(FeatureHandle fh, unsigned int id) {
{
const Object& o = fh->get_aux_source(id); const Object& o = fh->get_aux_source(id);
Xy_monotone_surface_3 data; Xy_monotone_surface_3 data;
Halfedge_handle h; Halfedge_handle h;
Vertex_handle v; Vertex_handle v;
Face_handle f; Face_handle f;
if (assign(v, o)) if (assign(v, o)) data = v->get_env_data();
data = v->get_data(); else if (assign(h, o)) data = h->get_env_data();
else if (assign(h, o)) else {
data = h->get_data(); CGAL_assertion(assign(f, o));
else
{
CGAL_assertion(assign(f, o));
assign(f, o); assign(f, o);
data = f->get_data(); data = f->get_env_data();
} }
return data; return data;
} }
template <class FeatureHandle>
int get_number_of_aux_data_objects(FeatureHandle fh, unsigned int id) template <typename FeatureHandle>
{ int get_number_of_aux_data_objects(FeatureHandle fh, unsigned int id) {
const Object& o = fh->get_aux_source(id); const Object& o = fh->get_aux_source(id);
int data; int data;
Halfedge_handle h; Halfedge_handle h;
Vertex_handle v; Vertex_handle v;
Face_handle f; Face_handle f;
if (assign(v, o)) if (assign(v, o)) data = v->number_of_data_objects();
data = v->number_of_data_objects(); else if (assign(h, o)) data = h->number_of_data_objects();
else if (assign(h, o)) else {
data = h->number_of_data_objects(); CGAL_assertion(assign(f, o));
else
{
CGAL_assertion(assign(f, o));
assign(f, o); assign(f, o);
data = f->number_of_data_objects(); data = f->number_of_data_objects();
} }
return data; return data;
} }

View File

@ -8,18 +8,12 @@
// $Name: $ // $Name: $
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
// //
// Author(s) : Michal Meyerovitch <gorgymic@post.tau.ac.il> // Author(s) : Michal Meyerovitch <gorgymic@post.tau.ac.il>
// Efi Fogel <efifogel@gmail.com>
#ifndef CGAL_ENVELOPE_TEST_3_H #ifndef CGAL_ENVELOPE_TEST_3_H
#define CGAL_ENVELOPE_TEST_3_H #define CGAL_ENVELOPE_TEST_3_H
#include <CGAL/Envelope_3/Envelope_base.h>
#include "Envelope_test_overlay_functor.h"
#include <CGAL/Envelope_3/Envelope_overlay_2.h>
#include <CGAL/Arr_walk_along_line_point_location.h>
#include <CGAL/enum.h>
#include <iostream> #include <iostream>
#include <cassert> #include <cassert>
#include <list> #include <list>
@ -27,128 +21,123 @@
#include <vector> #include <vector>
#include <map> #include <map>
#include <CGAL/Envelope_3/Envelope_base.h>
#include "Envelope_test_overlay_functor.h"
#include <CGAL/Envelope_3/Envelope_overlay_2.h>
#include <CGAL/Arr_walk_along_line_point_location.h>
#include <CGAL/enum.h>
//#define CGAL_DEBUG_ENVELOPE_TEST_3 //#define CGAL_DEBUG_ENVELOPE_TEST_3
// this is a very trivial and not efficient algorithm for computing the lower envelope // this is a very trivial and not efficient algorithm for computing the lower
// of general surfaces in 3d, used for testing. // envelope of general surfaces in 3d, used for testing.
// The algorithm projects the surfaces on the plane, and projects all the intersections // The algorithm projects the surfaces on the plane, and projects all the
// between surfaces, to get an arrangement that is a partition of the real envelope. // intersections between surfaces, to get an arrangement that is a partition of
// Then it computes for each part in the arrangement the surfaces on the envelope over it // the real envelope.
// by comparing them all. // Then it computes for each part in the arrangement the surfaces on the
// envelope over it by comparing them all.
namespace CGAL { namespace CGAL {
template <class EnvelopeTraits_3, class MinimizationDiagram_2> template <typename EnvelopeTraits_3, typename MinimizationDiagram_2>
class Envelope_test_3 class Envelope_test_3 {
{
public: public:
typedef EnvelopeTraits_3 Traits; using Traits = EnvelopeTraits_3;
typedef typename Traits::Surface_3 Surface_3; using Minimization_diagram_2 = MinimizationDiagram_2;
typedef typename Traits::Xy_monotone_surface_3 Xy_monotone_surface_3;
typedef MinimizationDiagram_2 Minimization_diagram_2; private:
typedef typename Minimization_diagram_2::Point_2 Point_2; using Md2 = Minimization_diagram_2;
typedef typename Minimization_diagram_2::X_monotone_curve_2 X_monotone_curve_2;
typedef typename Traits::Curve_2 Curve_2; public:
using Surface_3 = typename Traits::Surface_3;
using Xy_monotone_surface_3 = typename Traits::Xy_monotone_surface_3;
using Point_2 = typename Md2::Point_2;
using X_monotone_curve_2 = typename Md2::X_monotone_curve_2;
using Curve_2 = typename Traits::Curve_2;
protected: protected:
using Overlay_functor = Envelope_test_overlay_functor<Md2>;
using Overlay_2 = Envelope_overlay_2<Md2, Overlay_functor>;
typedef Envelope_test_overlay_functor<Minimization_diagram_2> Overlay_functor; using Md_point_location = Arr_walk_along_line_point_location<Md2>;
typedef Envelope_overlay_2<Minimization_diagram_2, Overlay_functor> Overlay_2;
typedef Arr_walk_along_line_point_location<Minimization_diagram_2> Md_point_location; using Halfedge_const_iterator = typename Md2::Halfedge_const_iterator;
using Halfedge_const_handle = typename Md2::Halfedge_const_handle;
using Halfedge_handle = typename Md2::Halfedge_handle;
using Halfedge_iterator = typename Md2::Halfedge_iterator;
using Vertex_const_handle = typename Md2::Vertex_const_handle;
using Vertex_handle = typename Md2::Vertex_handle;
using Vertex_iterator = typename Md2::Vertex_iterator;
using Face_handle = typename Md2::Face_handle;
using Face_const_iterator = typename Md2::Face_const_iterator;
using Face_const_handle = typename Md2::Face_const_handle;
using Face_iterator = typename Md2::Face_iterator;
using Ccb_halfedge_circulator = typename Md2::Ccb_halfedge_circulator;
using Hole_iterator = typename Md2::Inner_ccb_iterator;
using Face_data_iterator = typename Md2::Dcel::Face_data_iterator;
typedef typename Minimization_diagram_2::Halfedge_const_iterator Halfedge_const_iterator; using Multiplicity = typename EnvelopeTraits_3::Multiplicity;
typedef typename Minimization_diagram_2::Halfedge_const_handle Halfedge_const_handle; using Intersection_curve = std::pair<X_monotone_curve_2, Multiplicity>;
typedef typename Minimization_diagram_2::Halfedge_handle Halfedge_handle;
typedef typename Minimization_diagram_2::Halfedge_iterator Halfedge_iterator;
typedef typename Minimization_diagram_2::Vertex_const_handle Vertex_const_handle;
typedef typename Minimization_diagram_2::Vertex_handle Vertex_handle;
typedef typename Minimization_diagram_2::Vertex_iterator Vertex_iterator;
typedef typename Minimization_diagram_2::Face_handle Face_handle;
typedef typename Minimization_diagram_2::Face_const_iterator Face_const_iterator;
typedef typename Minimization_diagram_2::Face_const_handle Face_const_handle;
typedef typename Minimization_diagram_2::Face_iterator Face_iterator;
typedef typename Minimization_diagram_2::Ccb_halfedge_circulator Ccb_halfedge_circulator;
typedef typename Minimization_diagram_2::Inner_ccb_iterator Hole_iterator;
typedef typename Minimization_diagram_2::Dcel::Face_data_iterator Face_data_iterator;
typedef std::pair<X_monotone_curve_2,
typename EnvelopeTraits_3::Multiplicity> Intersection_curve;
public: public:
// c'tor // c'tor
Envelope_test_3() Envelope_test_3() {}
{
}
// virtual destructor. // virtual destructor.
virtual ~Envelope_test_3(){} virtual ~Envelope_test_3(){}
template <class SurfaceIterator> template <class SurfaceIterator>
void construct_lu_envelope(SurfaceIterator begin, void construct_lu_envelope(SurfaceIterator begin, SurfaceIterator end,
SurfaceIterator end, Minimization_diagram_2& result) {
Minimization_diagram_2 &result) if (begin == end) return; // result is empty
{
if (begin == end)
{
return; // result is empty
}
std::vector<Xy_monotone_surface_3> surfaces; std::vector<Xy_monotone_surface_3> surfaces;
SurfaceIterator si = begin; for (auto si = begin; si != end; ++si) surfaces.push_back(*si);
for(; si != end; ++si)
{
surfaces.push_back(*si);
}
Md_point_location pl(result); Md_point_location pl(result);
std::size_t number_of_surfaces = surfaces.size(); std::size_t number_of_surfaces = surfaces.size();
std::size_t j;
std::list<X_monotone_curve_2> curves_col; std::list<X_monotone_curve_2> curves_col;
std::list<Point_2> points_col; std::list<Point_2> points_col;
typename std::list<Curve_2>::iterator boundary_it; typename std::list<Curve_2>::iterator boundary_it;
for(std::size_t i=0; i<number_of_surfaces; ++i) for (std::size_t i = 0; i < number_of_surfaces; ++i) {
{ Xy_monotone_surface_3& cur_surface = surfaces[i];
Xy_monotone_surface_3 &cur_surface = surfaces[i]; // first insert all the projected curves of the boundary of the current
// first insert all the projected curves of the boundary of the current surface // surface collect the curve in this list, and use sweepline at the end
// collect the curve in this list, and use sweepline at the end
typedef std::pair<X_monotone_curve_2, Oriented_side> Boundary_xcurve; typedef std::pair<X_monotone_curve_2, Oriented_side> Boundary_xcurve;
std::list<std::variant<Boundary_xcurve, Point_2>> boundary_list; std::list<std::variant<Boundary_xcurve, Point_2>> boundary_list;
traits.construct_projected_boundary_2_object()(cur_surface, std::back_inserter(boundary_list)); auto ctr_proj_bnd = traits.construct_projected_boundary_2_object();
for(auto boundary_it = boundary_list.begin(); ctr_proj_bnd(cur_surface, std::back_inserter(boundary_list));
boundary_it != boundary_list.end(); for (auto boundary_it = boundary_list.begin();
++boundary_it) boundary_it != boundary_list.end(); ++boundary_it) {
{ const auto* boundary_cv = std::get_if<Boundary_xcurve>(&(*boundary_it));
const Boundary_xcurve* boundary_cv = std::get_if<Boundary_xcurve>(&(*boundary_it));
assert(boundary_cv!=nullptr); assert(boundary_cv!=nullptr);
curves_col.push_back(boundary_cv->first); curves_col.push_back(boundary_cv->first);
} }
// second, intersect it with all surfaces before it // second, intersect it with all surfaces before it
for(j=0; j<i; ++j) for (std::size_t j = 0; j < i; ++j) {
{
Xy_monotone_surface_3& prev_surface = surfaces[j]; Xy_monotone_surface_3& prev_surface = surfaces[j];
std::vector<std::variant<Intersection_curve,Point_2>> inter_objs; std::vector<std::variant<Intersection_curve,Point_2>> inter_objs;
traits.construct_projected_intersections_2_object()(cur_surface, prev_surface, std::back_inserter(inter_objs)); traits.construct_projected_intersections_2_object()(cur_surface, prev_surface, std::back_inserter(inter_objs));
// we collect all intersections and use sweep to insert them // we collect all intersections and use sweep to insert them
for(std::size_t k=0; k<inter_objs.size(); ++k) for (std::size_t k = 0; k < inter_objs.size(); ++k) {
{ if (const Point_2* point = std::get_if<Point_2>(&inter_objs[k])) {
if (const Point_2* point = std::get_if<Point_2>(&inter_objs[k]))
{
#ifdef CGAL_DEBUG_ENVELOPE_TEST_3 #ifdef CGAL_DEBUG_ENVELOPE_TEST_3
std::cout << "intersection between surfaces is a point: " << point << std::endl; std::cout << "intersection between surfaces is a point: "
<< point << std::endl;
#endif #endif
//insert_vertex(result, point, pl); //insert_vertex(result, point, pl);
points_col.push_back(*point); points_col.push_back(*point);
} }
else if (const Intersection_curve* curve = std::get_if<Intersection_curve>(&inter_objs[k])) else if (const auto* curve =
{ std::get_if<Intersection_curve>(&inter_objs[k])) {
curves_col.push_back(curve->first); curves_col.push_back(curve->first);
/*#ifdef CGAL_DEBUG_ENVELOPE_TEST_3 /*#ifdef CGAL_DEBUG_ENVELOPE_TEST_3
std::cout << "intersection between surfaces is a curve: " << curve.first << std::endl; std::cout << "intersection between surfaces is a curve: " << curve.first << std::endl;
@ -165,10 +154,7 @@ public:
}*/ }*/
//insert(result, curve.first, pl); //insert(result, curve.first, pl);
} }
else else assert_msg(false, "wrong intersection type");
{
assert_msg(false, "wrong intersection type");
}
} }
} }
} }
@ -176,8 +162,7 @@ public:
// insert the curves // insert the curves
insert(result, curves_col.begin(), curves_col.end()); insert(result, curves_col.begin(), curves_col.end());
// insert the points // insert the points
typename std::list<Point_2>::iterator pit = points_col.begin(); for (auto pit = points_col.begin(); pit != points_col.end(); ++pit)
for(; pit != points_col.end(); ++pit)
insert_point(result, *pit, pl); insert_point(result, *pit, pl);
m_result = &result; m_result = &result;
@ -185,52 +170,48 @@ public:
// now, foreach vertex, edge and face, we should determine which surfaces are minimal over it. // now, foreach vertex, edge and face, we should determine which surfaces are minimal over it.
// update vertices' data // update vertices' data
Vertex_iterator vi = result.vertices_begin(); for (auto vi = result.vertices_begin(); vi != result.vertices_end(); ++vi) {
for(; vi != result.vertices_end(); ++vi)
{
Vertex_handle vh = vi; Vertex_handle vh = vi;
// first we find the surfaces that are defined over the vertex // first we find the surfaces that are defined over the vertex
std::list<Xy_monotone_surface_3> defined_surfaces; std::list<Xy_monotone_surface_3> defined_surfaces;
typename Traits::Is_defined_over is_defined_over = traits.is_defined_over_object(); auto is_defined_over = traits.is_defined_over_object();
for(std::size_t i=0; i<number_of_surfaces; ++i) for (std::size_t i = 0; i < number_of_surfaces; ++i)
if (is_defined_over(vh->point(), surfaces[i])) if (is_defined_over(vh->point(), surfaces[i]))
defined_surfaces.push_back(surfaces[i]); defined_surfaces.push_back(surfaces[i]);
// now compare them over the vertex // now compare them over the vertex
set_minimum_over_vertex(vh, defined_surfaces.begin(), defined_surfaces.end()); set_minimum_over_vertex(vh, defined_surfaces.begin(),
defined_surfaces.end());
} }
// update edges' data // update edges' data
Halfedge_iterator hi = result.halfedges_begin(); for (auto hi = result.halfedges_begin(); hi != result.halfedges_end();
for(; hi != result.halfedges_end(); ++hi, ++hi) ++hi, ++hi) {
{
Halfedge_handle hh = hi; Halfedge_handle hh = hi;
// first we find the surfaces that are defined over the edge // first we find the surfaces that are defined over the edge
std::list<Xy_monotone_surface_3> defined_surfaces; std::list<Xy_monotone_surface_3> defined_surfaces;
for(std::size_t i=0; i<number_of_surfaces; ++i) for (std::size_t i = 0; i < number_of_surfaces; ++i)
if (is_surface_defined_over_edge(hh, surfaces[i])) if (is_surface_defined_over_edge(hh, surfaces[i]))
defined_surfaces.push_back(surfaces[i]); defined_surfaces.push_back(surfaces[i]);
// now compare them over the edge // now compare them over the edge
set_minimum_over_edge(hh, defined_surfaces.begin(), defined_surfaces.end()); set_minimum_over_edge(hh, defined_surfaces.begin(),
defined_surfaces.end());
} }
// update faces' data // update faces' data
// init current face for caching of computation // init current face for caching of computation
current_face = Face_handle(); current_face = Face_handle();
for (auto fi = result.faces_begin(); fi != result.faces_end(); ++fi) {
Face_iterator fi;
for (fi = result.faces_begin(); fi != result.faces_end(); ++fi)
{
#ifdef CGAL_DEBUG_ENVELOPE_TEST_3 #ifdef CGAL_DEBUG_ENVELOPE_TEST_3
std::cout << "deal with face" << std::endl; std::cout << "deal with face" << std::endl;
#endif #endif
Face_handle fh = fi; Face_handle fh = fi;
// first we find the surfaces that are defined over the face // first we find the surfaces that are defined over the face
std::list<Xy_monotone_surface_3> defined_surfaces; std::list<Xy_monotone_surface_3> defined_surfaces;
for (std::size_t i=0; i<number_of_surfaces; ++i) for (std::size_t i = 0; i < number_of_surfaces; ++i)
if (is_surface_defined_over_face(fh, surfaces[i])) if (is_surface_defined_over_face(fh, surfaces[i]))
defined_surfaces.push_back(surfaces[i]); defined_surfaces.push_back(surfaces[i]);
@ -240,8 +221,7 @@ public:
} }
} }
/*! /*! compare the 2 envelopes by overlaying them, and then comparing the
* compare the 2 envelopes by overlaying them, and then comparing the
* surfaces over the faces of the result map. * surfaces over the faces of the result map.
* *
* \todo The overlay compares the data using assertions. This should be * \todo The overlay compares the data using assertions. This should be
@ -249,37 +229,31 @@ public:
* determine that the 2 diagrams differ, we cannot simply remove the * determine that the 2 diagrams differ, we cannot simply remove the
* assertions. One option is to generate an exception and catch it. * assertions. One option is to generate an exception and catch it.
*/ */
bool compare_diagrams(Minimization_diagram_2 &test_env, bool compare_diagrams(Minimization_diagram_2& test_env,
Minimization_diagram_2 &env) Minimization_diagram_2& env) {
{
Minimization_diagram_2 overlay_map; Minimization_diagram_2 overlay_map;
overlay(test_env, env, overlay_map); overlay(test_env, env, overlay_map);
return true; return true;
} }
protected: protected:
// fill the vertex with the surface on the envelope // fill the vertex with the surface on the envelope
// all the surfaces are known to be defined over the vertex' point // all the surfaces are known to be defined over the vertex' point
template <class SurfaceIterator> template <typename SurfaceIterator>
void set_minimum_over_vertex(const Vertex_handle& v, void set_minimum_over_vertex(const Vertex_handle& v,
SurfaceIterator begin, SurfaceIterator end) SurfaceIterator begin, SurfaceIterator end) {
{ if (begin == end) v->set_no_data();
if (begin == end) else {
v->set_no_data(); auto si = begin;
else
{
SurfaceIterator si = begin;
// we set the first surface as the minimum, and then compare all the others // we set the first surface as the minimum, and then compare all the others
v->set_data(*si); v->set_env_data(*si);
++si; ++si;
for(; si != end; ++si) for (; si != end; ++si) {
{ Comparison_result cr =
Comparison_result cr = traits.compare_z_at_xy_3_object()(v->point(), v->get_data(), *si); traits.compare_z_at_xy_3_object()(v->point(), v->get_env_data(), *si);
if (cr == EQUAL) if (cr == EQUAL) v->add_data(*si);
v->add_data(*si); // this erases all surfaces from vertex's list
else if (cr == LARGER) else if (cr == LARGER) v->set_env_data(*si);
v->set_data(*si); // this erases all surfaces from vertex's list
// else - new surface has no affect on the envelope // else - new surface has no affect on the envelope
} }
} }
@ -287,58 +261,53 @@ protected:
// fill the edge with the surface on the envelope // fill the edge with the surface on the envelope
// all the surfaces are known to be defined over the edge's curve // all the surfaces are known to be defined over the edge's curve
template <class SurfaceIterator> template <typename SurfaceIterator>
void set_minimum_over_edge(const Halfedge_handle& h, SurfaceIterator begin, SurfaceIterator end) void set_minimum_over_edge(const Halfedge_handle& h, SurfaceIterator begin,
{ SurfaceIterator end) {
if (begin == end) if (begin == end) h->set_no_data();
h->set_no_data(); else {
else if (h != current_edge) compute_point_in_current_edge(h);
{
if (h != current_edge)
compute_point_in_current_edge(h);
SurfaceIterator si = begin; auto si = begin;
// we set the first surface as the minimum, and then compare all the others // we set the first surface as the minimum, and then compare all the others
h->set_data(*si); h->set_env_data(*si);
++si; ++si;
for(; si != end; ++si) for (; si != end; ++si) {
{ Comparison_result cr =
Comparison_result cr = traits.compare_z_at_xy_3_object()(current_point_inside_edge, traits.compare_z_at_xy_3_object()(current_point_inside_edge,
h->get_data(), *si); h->get_env_data(), *si);
if (cr == EQUAL) if (cr == EQUAL) h->add_data(*si);
h->add_data(*si); // this erases all surfaces from halfedge's list
else if (cr == LARGER) else if (cr == LARGER) h->set_env_data(*si);
h->set_data(*si); // this erases all surfaces from halfedge's list
// else - new surface has no affect on the envelope // else - new surface has no affect on the envelope
} }
// set twin's data // set twin's data
h->twin()->set_data(h->begin_data(), h->end_data()); h->twin()->set_env_data(h->begin_data(), h->end_data());
} }
} }
// fill the face with the surface on the envelope // fill the face with the surface on the envelope
// the surfaces are known to not intersect inside the face // the surfaces are known to not intersect inside the face
// (but might intersect on its edges) // (but might intersect on its edges)
template <class SurfaceIterator> template <typename SurfaceIterator>
void set_minimum_over_face(const Face_handle& face, SurfaceIterator begin, SurfaceIterator end) void set_minimum_over_face(const Face_handle& face, SurfaceIterator begin,
{ SurfaceIterator end) {
if (face->is_unbounded() || begin == end) if (face->is_unbounded() || begin == end) {
{ // a special case - no surface over the unbounded face, and when there
// a special case - no surface over the unbounded face, and when there are no surfaces at all // are no surfaces at all
face->set_no_data(); face->set_no_data();
} }
else else {
{ auto si = begin;
SurfaceIterator si = begin;
// we set the first surface as the minimum, and then compare all the others // we set the first surface as the minimum, and then compare all the others
face->set_data(*si); face->set_env_data(*si);
++si; ++si;
for(; si != end; ++si) for (; si != end; ++si) {
{ Comparison_result cr =
Comparison_result cr = compare_surfaces_over_face(face, face->get_data(), *si); compare_surfaces_over_face(face, face->get_env_data(), *si);
if (cr == EQUAL) if (cr == EQUAL) face->add_data(*si);
face->add_data(*si); // this erases all surfaces from face's list
else if (cr == LARGER) else if (cr == LARGER) face->set_env_data(*si);
face->set_data(*si); // this erases all surfaces from face's list
// else - new surface has no affect on the envelope // else - new surface has no affect on the envelope
} }
} }
@ -349,14 +318,13 @@ protected:
// LARGER if the second surface is closer to the envelope // LARGER if the second surface is closer to the envelope
// EQUAL otherwise // EQUAL otherwise
// this is version 2 which uses a calculated point inside the face // this is version 2 which uses a calculated point inside the face
Comparison_result compare_surfaces_over_face(const Face_handle& face, Comparison_result
const Xy_monotone_surface_3 &surf1, compare_surfaces_over_face(const Face_handle& face,
const Xy_monotone_surface_3& surf2) const Xy_monotone_surface_3& surf1,
{ const Xy_monotone_surface_3& surf2) {
assert(!face->is_unbounded()); assert(!face->is_unbounded());
Comparison_result cur_res; Comparison_result cur_res;
if (face != current_face) if (face != current_face) compute_point_in_current_face(face);
compute_point_in_current_face(face);
cur_res = traits.compare_z_at_xy_3_object()(current_point,surf1,surf2); cur_res = traits.compare_z_at_xy_3_object()(current_point,surf1,surf2);
@ -368,27 +336,24 @@ protected:
} }
// check if the surface is defines over the edge // check if the surface is defines over the edge
bool is_surface_defined_over_edge(const Halfedge_handle& h, Xy_monotone_surface_3 &surf) bool is_surface_defined_over_edge(const Halfedge_handle& h,
{ Xy_monotone_surface_3& surf) {
// check it over a point inside the edge's curve // check it over a point inside the edge's curve
if (h != current_edge) if (h != current_edge) compute_point_in_current_edge(h);
compute_point_in_current_edge(h);
bool result = traits.is_defined_over_object()(current_point_inside_edge, surf); auto def_over_obj = traits.is_defined_over_object();
bool result = def_over_obj(current_point_inside_edge, surf);
return result; return result;
} }
// check if the surface is defines over the face // check if the surface is defines over the face
// this is version checks the point inside the face // this is version checks the point inside the face
bool is_surface_defined_over_face(const Face_handle& face, bool is_surface_defined_over_face(const Face_handle& face,
Xy_monotone_surface_3 &surf) Xy_monotone_surface_3& surf) {
{
// we always have bounded surfaces // we always have bounded surfaces
if (face->is_unbounded()) if (face->is_unbounded()) return false;
return false;
if (face != current_face) if (face != current_face) compute_point_in_current_face(face);
compute_point_in_current_face(face);
bool result = traits.is_defined_over_object()(current_point,surf); bool result = traits.is_defined_over_object()(current_point,surf);
@ -396,9 +361,9 @@ protected:
} }
// compute a point inside the face of the arranegement // compute a point inside the face of the arranegement
Point_2 compute_point_inside_face(Minimization_diagram_2 &env, Face_handle face) Point_2 compute_point_inside_face(Minimization_diagram_2& env,
{ Face_handle face) {
assert(!face->is_unbounded()); assert(! face->is_unbounded());
#ifdef CGAL_DEBUG_ENVELOPE_TEST_3 #ifdef CGAL_DEBUG_ENVELOPE_TEST_3
std::cout << "in compute point inside face" << std::endl; std::cout << "in compute point inside face" << std::endl;
@ -409,8 +374,7 @@ protected:
Ccb_halfedge_circulator hec_begin = hec; Ccb_halfedge_circulator hec_begin = hec;
bool found = false; bool found = false;
do { do {
if (!traits.is_vertical_2_object()(hec->curve())) if (!traits.is_vertical_2_object()(hec->curve())) {
{
found = true; found = true;
continue; continue;
} }
@ -433,7 +397,7 @@ protected:
// if (traits.compare_x(found_hh->source()->point(), found_hh->target()->point()) == LARGER) // if (traits.compare_x(found_hh->source()->point(), found_hh->target()->point()) == LARGER)
// shoot_up = false; // shoot_up = false;
if (traits.equal_2_object()(found_hh->source()->point(), if (traits.equal_2_object()(found_hh->source()->point(),
traits.construct_max_vertex_2_object()(found_hh->curve()))) traits.construct_max_vertex_2_object()(found_hh->curve())))
shoot_up = false; shoot_up = false;
Md_point_location pl(env); Md_point_location pl(env);
@ -443,21 +407,14 @@ protected:
Point_2 shoot_target; Point_2 shoot_target;
if (shoot_up) if (shoot_up) shoot_obj = pl.ray_shoot_up(shoot_source);
shoot_obj = pl.ray_shoot_up(shoot_source); else shoot_obj = pl.ray_shoot_down(shoot_source);
else
shoot_obj = pl.ray_shoot_down(shoot_source);
if (assign(shoot_hh, shoot_obj)) if (assign(shoot_hh, shoot_obj))
{
shoot_target = traits.vertical_ray_shoot_2(shoot_source, shoot_hh->curve()); shoot_target = traits.vertical_ray_shoot_2(shoot_source, shoot_hh->curve());
}
else if (assign(shoot_vh, shoot_obj)) else if (assign(shoot_vh, shoot_obj))
{
shoot_target = (env.non_const_handle(shoot_vh))->point(); shoot_target = (env.non_const_handle(shoot_vh))->point();
} else CGAL_error(); // it cannot be the unbounded face
else
CGAL_error(); // it cannot be the unbounded face
Point_2 res_point = traits.construct_middle_point(shoot_source, shoot_target); Point_2 res_point = traits.construct_middle_point(shoot_source, shoot_target);
@ -471,37 +428,34 @@ protected:
assert(test_fh == face); assert(test_fh == face);
#endif #endif
return res_point; return res_point;
} }
// compute a point inside the face saved in current_face // compute a point inside the face saved in current_face
// and put the result into current_point // and put the result into current_point
void compute_point_in_current_face(Face_handle face) void compute_point_in_current_face(Face_handle face) {
{
current_face = face; current_face = face;
current_point = compute_point_inside_face(*m_result, current_face); current_point = compute_point_inside_face(*m_result, current_face);
} }
// compute a point inside the edge saved in current_edge // compute a point inside the edge saved in current_edge
// and put the result into current_point_inside_edge // and put the result into current_point_inside_edge
void compute_point_in_current_edge(Halfedge_handle h) void compute_point_in_current_edge(Halfedge_handle h) {
{
current_edge = h; current_edge = h;
current_point_inside_edge = traits.construct_middle_point(h->curve()); current_point_inside_edge = traits.construct_middle_point(h->curve());
} }
protected: protected:
Overlay_2 overlay; Overlay_2 overlay;
Traits traits; Traits traits;
Minimization_diagram_2 *m_result; Minimization_diagram_2* m_result;
Face_handle current_face; Face_handle current_face;
Point_2 current_point; Point_2 current_point;
Halfedge_handle current_edge; Halfedge_handle current_edge;
Point_2 current_point_inside_edge; Point_2 current_point_inside_edge;
}; };
} //namespace CGAL } //namespace CGAL

View File

@ -8,7 +8,8 @@
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
// //
// //
// Author(s) : Michal Meyerovitch <gorgymic@post.tau.ac.il> // Author(s) : Michal Meyerovitch <gorgymic@post.tau.ac.il>
// Efi Fogel <efif@post.tau.ac.il>
#ifndef ENVELOPE_TEST_OVERLAY_FUNCTOR_H #ifndef ENVELOPE_TEST_OVERLAY_FUNCTOR_H
#define ENVELOPE_TEST_OVERLAY_FUNCTOR_H #define ENVELOPE_TEST_OVERLAY_FUNCTOR_H
@ -28,104 +29,87 @@ namespace CGAL {
// this overlay functor compares the data over the 2 features that create new // this overlay functor compares the data over the 2 features that create new
// features in the new map // features in the new map
template <class MinimizationDiagram_2> template <typename MinimizationDiagram_2>
class Envelope_test_overlay_functor class Envelope_test_overlay_functor {
{
public: public:
typedef MinimizationDiagram_2 Minimization_diagram_2; using Minimization_diagram_2 = MinimizationDiagram_2;
typedef typename Minimization_diagram_2::Face_const_handle Face_handle1; private:
typedef typename Minimization_diagram_2::Face_const_handle Face_handle2; using Md2 = Minimization_diagram_2;
typedef typename Minimization_diagram_2::Vertex_const_handle Vertex_handle1; public:
typedef typename Minimization_diagram_2::Vertex_const_handle Vertex_handle2; using Face_handle1 = typename Md2::Face_const_handle;
using Face_handle2 = typename Md2::Face_const_handle;
typedef typename Minimization_diagram_2::Halfedge_const_handle Halfedge_handle1; using Vertex_handle1 = typename Md2::Vertex_const_handle;
typedef typename Minimization_diagram_2::Halfedge_const_handle Halfedge_handle2; using Vertex_handle2 = typename Md2::Vertex_const_handle;
typedef typename Minimization_diagram_2::Face_handle Res_face_handle; using Halfedge_handle1 = typename Md2::Halfedge_const_handle;
typedef typename Minimization_diagram_2::Halfedge_handle Res_halfedge_handle; using Halfedge_handle2 = typename Md2::Halfedge_const_handle;
typedef typename Minimization_diagram_2::Vertex_handle Res_vertex_handle;
using Res_face_handle = typename Md2::Face_handle;
using Res_halfedge_handle = typename Md2::Halfedge_handle;
using Res_vertex_handle = typename Md2::Vertex_handle;
Envelope_test_overlay_functor(Minimization_diagram_2& , Envelope_test_overlay_functor(Md2&, Md2&, Md2&) {}
Minimization_diagram_2& ,
Minimization_diagram_2& )
{}
void create_face (Face_handle1 f1, Face_handle2 f2, Res_face_handle res_f) void create_face (Face_handle1 f1, Face_handle2 f2, Res_face_handle res_f) {
{
res_f->set_aux_source(0, f1); res_f->set_aux_source(0, f1);
res_f->set_aux_source(1, f2); res_f->set_aux_source(1, f2);
assert_msg(f1->is_equal_data(f2->begin_data(), f2->end_data()), assert_msg(f1->is_equal_data(f2->begin_data(), f2->end_data()),
"data different over face"); "data different over face");
} }
void create_vertex(Halfedge_handle1 h1, void create_vertex(Halfedge_handle1 h1, Halfedge_handle2 h2,
Halfedge_handle2 h2, Res_vertex_handle res_v) {
Res_vertex_handle res_v)
{
res_v->set_aux_source(0, h1); res_v->set_aux_source(0, h1);
res_v->set_aux_source(1, h2); res_v->set_aux_source(1, h2);
assert_msg(h1->is_equal_data(h2->begin_data(), h2->end_data()), assert_msg(h1->is_equal_data(h2->begin_data(), h2->end_data()),
"data different over vertex"); "data different over vertex");
} }
void create_vertex(Vertex_handle1 v1, void create_vertex(Vertex_handle1 v1, Vertex_handle2 v2,
Vertex_handle2 v2, Res_vertex_handle res_v) {
Res_vertex_handle res_v)
{
res_v->set_aux_source(0, v1); res_v->set_aux_source(0, v1);
res_v->set_aux_source(1, v2); res_v->set_aux_source(1, v2);
assert_msg(v1->is_equal_data(v2->begin_data(), v2->end_data()), assert_msg(v1->is_equal_data(v2->begin_data(), v2->end_data()),
"data different over vertex"); "data different over vertex");
} }
void create_vertex(Vertex_handle1 v1, void create_vertex(Vertex_handle1 v1, Halfedge_handle2 h2,
Halfedge_handle2 h2, Res_vertex_handle res_v) {
Res_vertex_handle res_v)
{
res_v->set_aux_source(0, v1); res_v->set_aux_source(0, v1);
res_v->set_aux_source(1, h2); res_v->set_aux_source(1, h2);
assert_msg(v1->is_equal_data(h2->begin_data(), h2->end_data()), assert_msg(v1->is_equal_data(h2->begin_data(), h2->end_data()),
"data different over vertex"); "data different over vertex");
} }
void create_vertex(Halfedge_handle1 h1, void create_vertex(Halfedge_handle1 h1, Vertex_handle2 v2,
Vertex_handle2 v2, Res_vertex_handle res_v) {
Res_vertex_handle res_v)
{
res_v->set_aux_source(0, h1); res_v->set_aux_source(0, h1);
res_v->set_aux_source(1, v2); res_v->set_aux_source(1, v2);
assert_msg(h1->is_equal_data(v2->begin_data(), v2->end_data()), assert_msg(h1->is_equal_data(v2->begin_data(), v2->end_data()),
"data different over vertex"); "data different over vertex");
} }
void create_vertex(Face_handle1 f1, void create_vertex(Face_handle1 f1, Vertex_handle2 v2,
Vertex_handle2 v2, Res_vertex_handle res_v) {
Res_vertex_handle res_v)
{
res_v->set_aux_source(0, f1); res_v->set_aux_source(0, f1);
res_v->set_aux_source(1, v2); res_v->set_aux_source(1, v2);
assert_msg(f1->is_equal_data(v2->begin_data(), v2->end_data()), assert_msg(f1->is_equal_data(v2->begin_data(), v2->end_data()),
"data different over vertex"); "data different over vertex");
} }
void create_vertex(Vertex_handle1 v1, void create_vertex(Vertex_handle1 v1, Face_handle2 f2,
Face_handle2 f2, Res_vertex_handle res_v) {
Res_vertex_handle res_v)
{
res_v->set_aux_source(0, v1); res_v->set_aux_source(0, v1);
res_v->set_aux_source(1, f2); res_v->set_aux_source(1, f2);
assert_msg(v1->is_equal_data(f2->begin_data(), f2->end_data()), assert_msg(v1->is_equal_data(f2->begin_data(), f2->end_data()),
"data different over vertex"); "data different over vertex");
} }
void create_edge(Halfedge_handle1 h1, void create_edge(Halfedge_handle1 h1, Halfedge_handle2 h2,
Halfedge_handle2 h2, Res_halfedge_handle res_h) {
Res_halfedge_handle res_h)
{
res_h->set_aux_source(0, h1); res_h->set_aux_source(0, h1);
res_h->set_aux_source(1, h2); res_h->set_aux_source(1, h2);
@ -136,10 +120,8 @@ public:
"data different over edge"); "data different over edge");
} }
void create_edge(Halfedge_handle1 h1, void create_edge(Halfedge_handle1 h1, Face_handle2 f2,
Face_handle2 f2, Res_halfedge_handle res_h) {
Res_halfedge_handle res_h)
{
res_h->set_aux_source(0, h1); res_h->set_aux_source(0, h1);
res_h->set_aux_source(1, f2); res_h->set_aux_source(1, f2);
@ -150,10 +132,8 @@ public:
"data different over edge"); "data different over edge");
} }
void create_edge(Face_handle1 f1, void create_edge(Face_handle1 f1, Halfedge_handle2 h2,
Halfedge_handle2 h2, Res_halfedge_handle res_h) {
Res_halfedge_handle res_h)
{
res_h->set_aux_source(0, f1); res_h->set_aux_source(0, f1);
res_h->set_aux_source(1, h2); res_h->set_aux_source(1, h2);
@ -169,5 +149,3 @@ public:
} //namespace CGAL } //namespace CGAL
#endif #endif

View File

@ -8,17 +8,12 @@
// $Name: $ // $Name: $
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
// //
// Author(s) : Michal Meyerovitch <gorgymic@post.tau.ac.il> // Author(s) : Michal Meyerovitch <gorgymic@post.tau.ac.il>
// Efi Fogel <efifogel@gmail.com>
#ifndef CGAL_ENVELOPE_TRIANGLES_TEST_3_H #ifndef CGAL_ENVELOPE_TRIANGLES_TEST_3_H
#define CGAL_ENVELOPE_TRIANGLES_TEST_3_H #define CGAL_ENVELOPE_TRIANGLES_TEST_3_H
#include "Envelope_test_overlay_functor.h"
#include <CGAL/Envelope_3/Envelope_overlay_2.h>
#include <CGAL/Arr_walk_along_line_point_location.h>
#include <CGAL/enum.h>
#include <iostream> #include <iostream>
#include <cassert> #include <cassert>
#include <list> #include <list>
@ -26,6 +21,11 @@
#include <vector> #include <vector>
#include <map> #include <map>
#include "Envelope_test_overlay_functor.h"
#include <CGAL/Envelope_3/Envelope_overlay_2.h>
#include <CGAL/Arr_walk_along_line_point_location.h>
#include <CGAL/enum.h>
//#define CGAL_DEBUG_ENVELOPE_TRIANGLES_TEST_3 //#define CGAL_DEBUG_ENVELOPE_TRIANGLES_TEST_3
// this is a very trivial and not efficient algorithm for computing the lower // this is a very trivial and not efficient algorithm for computing the lower
@ -38,59 +38,47 @@
namespace CGAL { namespace CGAL {
template <class EnvelopeTraits_3, class MinimizationDiagram_2> template <typename EnvelopeTraits_3, typename MinimizationDiagram_2>
class Envelope_triangles_test_3 { class Envelope_triangles_test_3 {
public: public:
typedef EnvelopeTraits_3 Traits; using Traits = EnvelopeTraits_3;
typedef typename Traits::Surface_3 Surface_3; using Minimization_diagram_2 = MinimizationDiagram_2;
typedef typename Traits::Xy_monotone_surface_3 Xy_monotone_surface_3;
typedef MinimizationDiagram_2 Minimization_diagram_2; private:
typedef typename Minimization_diagram_2::Point_2 Point_2; using Md2 = Minimization_diagram_2;
typedef typename Minimization_diagram_2::X_monotone_curve_2
X_monotone_curve_2; public:
typedef typename Traits::Curve_2 Curve_2; using Surface_3 = typename Traits::Surface_3;
using Xy_monotone_surface_3 = typename Traits::Xy_monotone_surface_3;
using Point_2 = typename Md2::Point_2;
using X_monotone_curve_2 = typename Md2::X_monotone_curve_2;
using Curve_2 = typename Traits::Curve_2;
protected: protected:
typedef Envelope_test_overlay_functor<Minimization_diagram_2> using Overlay_functor = Envelope_test_overlay_functor<Md2>;
Overlay_functor; using Overlay_2 = Envelope_overlay_2<Md2, Overlay_functor>;
typedef Envelope_overlay_2<Minimization_diagram_2, Overlay_functor>
Overlay_2;
typedef Arr_walk_along_line_point_location<Minimization_diagram_2> using Md2_point_location = Arr_walk_along_line_point_location<Md2>;
Md_point_location;
typedef typename Minimization_diagram_2::Halfedge_const_iterator using Halfedge_const_iterator = typename Md2::Halfedge_const_iterator;
Halfedge_const_iterator; using Halfedge_const_handle = typename Md2::Halfedge_const_handle;
typedef typename Minimization_diagram_2::Halfedge_const_handle using Halfedge_handle = typename Md2::Halfedge_handle;
Halfedge_const_handle; using Halfedge_iterator = typename Md2::Halfedge_iterator;
typedef typename Minimization_diagram_2::Halfedge_handle using Vertex_const_handle = typename Md2::Vertex_const_handle;
Halfedge_handle; using Vertex_handle = typename Md2::Vertex_handle;
typedef typename Minimization_diagram_2::Halfedge_iterator using Vertex_iterator = typename Md2::Vertex_iterator;
Halfedge_iterator; using Face_handle = typename Md2::Face_handle;
typedef typename Minimization_diagram_2::Vertex_const_handle using Face_const_iterator = typename Md2::Face_const_iterator;
Vertex_const_handle; using Face_const_handle = typename Md2::Face_const_handle;
typedef typename Minimization_diagram_2::Vertex_handle using Face_iterator = typename Md2::Face_iterator;
Vertex_handle; using Ccb_halfedge_circulator = typename Md2::Ccb_halfedge_circulator;
typedef typename Minimization_diagram_2::Vertex_iterator using Hole_iterator = typename Md2::Inner_ccb_iterator;
Vertex_iterator;
typedef typename Minimization_diagram_2::Face_handle Face_handle;
typedef typename Minimization_diagram_2::Face_const_iterator
Face_const_iterator;
typedef typename Minimization_diagram_2::Face_const_handle
Face_const_handle;
typedef typename Minimization_diagram_2::Face_iterator
Face_iterator;
typedef typename Minimization_diagram_2::Ccb_halfedge_circulator
Ccb_halfedge_circulator;
typedef typename Minimization_diagram_2::Inner_ccb_iterator
Hole_iterator;
typedef typename Minimization_diagram_2::Dcel::Face_data_iterator using Face_data_iterator = typename Md2::Dcel::Face_data_iterator;
Face_data_iterator;
typedef std::pair<X_monotone_curve_2, typename EnvelopeTraits_3::Multiplicity> using Multiplicity = typename EnvelopeTraits_3::Multiplicity;
Intersection_curve; using Intersection_curve = std::pair<X_monotone_curve_2, Multiplicity>;
public: public:
// c'tor // c'tor
@ -99,27 +87,22 @@ public:
// virtual destructor. // virtual destructor.
virtual ~Envelope_triangles_test_3() { } virtual ~Envelope_triangles_test_3() { }
template <class SurfaceIterator> template <typename SurfaceIterator>
void construct_lu_envelope(SurfaceIterator begin, SurfaceIterator end, void construct_lu_envelope(SurfaceIterator begin, SurfaceIterator end,
Minimization_diagram_2 &result) Minimization_diagram_2& result) {
{ if (begin == end) return; // result is empty
if (begin == end)
return; // result is empty
std::vector<Xy_monotone_surface_3> surfaces; std::vector<Xy_monotone_surface_3> surfaces;
SurfaceIterator si = begin; for (auto si = begin; si != end; ++si) surfaces.push_back(*si);
for (; si != end; ++si)
surfaces.push_back(*si);
Md_point_location pl(result); Md2_point_location pl(result);
std::size_t number_of_surfaces = surfaces.size(); std::size_t number_of_surfaces = surfaces.size();
std::list<X_monotone_curve_2> curves_col; std::list<X_monotone_curve_2> curves_col;
std::list<Point_2> points_col; std::list<Point_2> points_col;
for(std::size_t i=0; i<number_of_surfaces; ++i) for (std::size_t i = 0; i < number_of_surfaces; ++i) {
{ Xy_monotone_surface_3& cur_surface = surfaces[i];
Xy_monotone_surface_3 &cur_surface = surfaces[i];
// first insert all the projected curves of the boundary of the current // first insert all the projected curves of the boundary of the current
// surface // surface
@ -134,7 +117,7 @@ public:
traits.construct_projected_boundary_2_object() traits.construct_projected_boundary_2_object()
(cur_surface, std::back_inserter(boundary_list)); (cur_surface, std::back_inserter(boundary_list));
for (auto bit = boundary_list.begin(); bit != boundary_list.end(); ++bit) { for (auto bit = boundary_list.begin(); bit != boundary_list.end(); ++bit) {
const Boundary_xcurve* boundary_cv = std::get_if<Boundary_xcurve>(&(*bit)); const auto* boundary_cv = std::get_if<Boundary_xcurve>(&(*bit));
assert(boundary_cv!=nullptr); assert(boundary_cv!=nullptr);
curves_col.push_back(boundary_cv->first); curves_col.push_back(boundary_cv->first);
} }
@ -147,8 +130,7 @@ public:
(cur_surface, prev_surface, std::back_inserter(inter_objs)); (cur_surface, prev_surface, std::back_inserter(inter_objs));
// we collect all intersections and use sweep to insert them // we collect all intersections and use sweep to insert them
for(std::size_t k=0; k<inter_objs.size(); ++k) for(std::size_t k=0; k<inter_objs.size(); ++k) {
{
if (const Point_2* point = std::get_if<Point_2>(&inter_objs[k])) { if (const Point_2* point = std::get_if<Point_2>(&inter_objs[k])) {
#ifdef CGAL_DEBUG_ENVELOPE_TRIANGLES_TEST_3 #ifdef CGAL_DEBUG_ENVELOPE_TRIANGLES_TEST_3
std::cout << "intersection between surfaces is a point: " std::cout << "intersection between surfaces is a point: "
@ -157,7 +139,8 @@ public:
//insert_vertex(result, point, pl); //insert_vertex(result, point, pl);
points_col.push_back(*point); points_col.push_back(*point);
} }
else if (const Intersection_curve* curve = std::get_if<Intersection_curve>(&inter_objs[k])) { else if (const auto* curve =
std::get_if<Intersection_curve>(&inter_objs[k])) {
#ifdef CGAL_DEBUG_ENVELOPE_TRIANGLES_TEST_3 #ifdef CGAL_DEBUG_ENVELOPE_TRIANGLES_TEST_3
std::cout << "intersection between surfaces is a curve: " std::cout << "intersection between surfaces is a curve: "
<< curve.first << std::endl; << curve.first << std::endl;
@ -165,26 +148,22 @@ public:
curves_col.push_back(curve->first); curves_col.push_back(curve->first);
//insert(result, curve.first, pl); //insert(result, curve.first, pl);
} }
else else assert_msg(false, "wrong intersection type");
{
assert_msg(false, "wrong intersection type");
}
} }
} }
} }
#ifdef CGAL_DEBUG_ENVELOPE_TRIANGLES_TEST_3 #ifdef CGAL_DEBUG_ENVELOPE_TRIANGLES_TEST_3
std::cout << "inserting the curves: " << std::endl; std::cout << "inserting the curves: " << std::endl;
typename std::list<Curve_2>::iterator curves_it = curves_col.begin(); for(auto curves_it = curves_col.begin(); curves_it != curves_col.end();
for(; curves_it != curves_col.end(); ++curves_it) ++curves_it)
std::cout << *curves_it << std::endl; std::cout << *curves_it << std::endl;
#endif #endif
// insert the curves // insert the curves
insert(result, curves_col.begin(), curves_col.end()); insert(result, curves_col.begin(), curves_col.end());
// insert the points // insert the points
typename std::list<Point_2>::iterator pit = points_col.begin(); for (auto pit = points_col.begin(); pit != points_col.end(); ++pit)
for (; pit != points_col.end(); ++pit)
insert_point(result, *pit, pl); insert_point(result, *pit, pl);
m_result = &result; m_result = &result;
@ -193,8 +172,7 @@ public:
// are minimal over it. // are minimal over it.
// update vertices' data // update vertices' data
Vertex_iterator vi = result.vertices_begin(); for (auto vi = result.vertices_begin(); vi != result.vertices_end(); ++vi) {
for (; vi != result.vertices_end(); ++vi) {
Vertex_handle vh = vi; Vertex_handle vh = vi;
// first we find the surfaces that are defined over the vertex // first we find the surfaces that are defined over the vertex
std::list<Xy_monotone_surface_3> defined_surfaces; std::list<Xy_monotone_surface_3> defined_surfaces;
@ -210,8 +188,8 @@ public:
} }
// update edges' data // update edges' data
Halfedge_iterator hi = result.halfedges_begin(); for (auto hi = result.halfedges_begin(); hi != result.halfedges_end();
for (; hi != result.halfedges_end(); ++hi, ++hi) { ++hi, ++hi) {
Halfedge_handle hh = hi; Halfedge_handle hh = hi;
// first we find the surfaces that are defined over the edge // first we find the surfaces that are defined over the edge
std::list<Xy_monotone_surface_3> defined_surfaces; std::list<Xy_monotone_surface_3> defined_surfaces;
@ -229,12 +207,11 @@ public:
// init current face for caching of computation // init current face for caching of computation
current_face = Face_handle(); current_face = Face_handle();
Face_iterator fi; for (auto fi = result.faces_begin(); fi != result.faces_end(); ++fi) {
for (fi = result.faces_begin(); fi != result.faces_end(); ++fi) {
Face_handle fh = fi; Face_handle fh = fi;
// first we find the surfaces that are defined over the face // first we find the surfaces that are defined over the face
std::list<Xy_monotone_surface_3> defined_surfaces; std::list<Xy_monotone_surface_3> defined_surfaces;
for(std::size_t i=0; i<number_of_surfaces; ++i) for (std::size_t i = 0; i < number_of_surfaces; ++i)
if (is_surface_defined_over_face(fh, surfaces[i])) if (is_surface_defined_over_face(fh, surfaces[i]))
defined_surfaces.push_back(surfaces[i]); defined_surfaces.push_back(surfaces[i]);
@ -247,17 +224,15 @@ public:
// test1 // test1
// compare the 2 envelopes by computing a point inside each face of test_env // compare the 2 envelopes by computing a point inside each face of test_env
// locating it in env, and comparing the above surfaces // locating it in env, and comparing the above surfaces
bool compare_lu_envelopes_test1(Minimization_diagram_2 &test_env, bool compare_lu_envelopes_test1(Minimization_diagram_2& test_env,
Minimization_diagram_2 &env) Minimization_diagram_2& env) {
{
// foreach face in the test envelope, compute a point inside the face, // foreach face in the test envelope, compute a point inside the face,
// locate it in the other envelope and compare the surfaces over the 2 faces // locate it in the other envelope and compare the surfaces over the 2 faces
Md_point_location pl(env); Md2_point_location pl(env);
Face_iterator fi = test_env.faces_begin();
bool eq, result = true; bool eq, result = true;
for (; fi != test_env.faces_end(); ++fi) { for (auto fi = test_env.faces_begin(); fi != test_env.faces_end(); ++fi) {
Face_handle fh = fi; Face_handle fh = fi;
if (!fh->is_unbounded()) { if (! fh->is_unbounded()) {
Point_2 inside_test = compute_point_inside_face(test_env, fh); Point_2 inside_test = compute_point_inside_face(test_env, fh);
auto pl_obj = pl.locate(inside_test); auto pl_obj = pl.locate(inside_test);
// faces of env must contain the faces of test // faces of env must contain the faces of test
@ -275,10 +250,9 @@ public:
// compare the 2 envelopes by overlaying them, and then comparing the // compare the 2 envelopes by overlaying them, and then comparing the
// surfaces over the faces of the result map // surfaces over the faces of the result map
// if faces_only = false we also compare the data over the edges & vertices // if faces_only = false we also compare the data over the edges & vertices
bool compare_lu_envelopes_test2(Minimization_diagram_2 &test_env, bool compare_lu_envelopes_test2(Minimization_diagram_2& test_env,
Minimization_diagram_2 &env, Minimization_diagram_2& env,
bool /* faces_only */ = true) bool /* faces_only */ = true) {
{
Minimization_diagram_2 overlay_map; Minimization_diagram_2 overlay_map;
// overlay the 2 maps, the overlay test functor does all the comparisons // overlay the 2 maps, the overlay test functor does all the comparisons
overlay(test_env, env, overlay_map); overlay(test_env, env, overlay_map);
@ -286,27 +260,23 @@ public:
} }
protected: protected:
// fill the vertex with the surface on the envelope // fill the vertex with the surface on the envelope
// all the surfaces are known to be defined over the vertex' point // all the surfaces are known to be defined over the vertex' point
template <class SurfaceIterator> template <typename SurfaceIterator>
void set_minimum_over_vertex(Vertex_handle v, SurfaceIterator begin, void set_minimum_over_vertex(Vertex_handle v, SurfaceIterator begin,
SurfaceIterator end) SurfaceIterator end) {
{ if (begin == end) v->set_no_data();
if (begin == end)
v->set_no_data();
else { else {
SurfaceIterator si = begin; auto si = begin;
// we set the first surface as the minimum, and then compare all the others // we set the first surface as the minimum, and then compare all the others
v->set_data(*si); v->set_env_data(*si);
++si; ++si;
for (; si != end; ++si) { for (; si != end; ++si) {
Comparison_result cr = Comparison_result cr =
traits.compare_z_at_xy_3_object()(v->point(), v->get_data(), *si); traits.compare_z_at_xy_3_object()(v->point(), v->get_env_data(), *si);
if (cr == EQUAL) if (cr == EQUAL) v->add_data(*si);
v->add_data(*si); // this erases all surfaces from vertex's list
else if (cr == LARGER) else if (cr == LARGER) v->set_env_data(*si);
v->set_data(*si); // this erases all surfaces from vertex's list
// else - new surface has no affect on the envelope // else - new surface has no affect on the envelope
} }
} }
@ -314,59 +284,53 @@ protected:
// fill the edge with the surface on the envelope // fill the edge with the surface on the envelope
// all the surfaces are known to be defined over the edge's curve // all the surfaces are known to be defined over the edge's curve
template <class SurfaceIterator> template <typename SurfaceIterator>
void set_minimum_over_edge(const Halfedge_handle& h, SurfaceIterator begin, void set_minimum_over_edge(const Halfedge_handle& h, SurfaceIterator begin,
SurfaceIterator end) SurfaceIterator end) {
{ if (begin == end) h->set_no_data();
if (begin == end)
h->set_no_data();
else { else {
if (h != current_edge) if (h != current_edge) compute_point_in_current_edge(h);
compute_point_in_current_edge(h);
SurfaceIterator si = begin; auto si = begin;
// we set the first surface as the minimum, and then compare all the others // we set the first surface as the minimum, and then compare all the others
h->set_data(*si); h->set_env_data(*si);
++si; ++si;
for (; si != end; ++si) { for (; si != end; ++si) {
Comparison_result cr = Comparison_result cr =
traits.compare_z_at_xy_3_object()(current_point_inside_edge, traits.compare_z_at_xy_3_object()(current_point_inside_edge,
h->get_data(), *si); h->get_env_data(), *si);
if (cr == EQUAL) if (cr == EQUAL) h->add_data(*si);
h->add_data(*si); // this erases all surfaces from halfedge's list
else if (cr == LARGER) else if (cr == LARGER) h->set_env_data(*si);
h->set_data(*si); // this erases all surfaces from halfedge's list
// else - new surface has no affect on the envelope // else - new surface has no affect on the envelope
} }
// set twin's data // set twin's data
h->twin()->set_data(h->begin_data(), h->end_data()); h->twin()->set_env_data(h->begin_data(), h->end_data());
} }
} }
// fill the face with the surface on the envelope // fill the face with the surface on the envelope
// the surfaces are known to not intersect inside the face // the surfaces are known to not intersect inside the face
// (but might intersect on its edges) // (but might intersect on its edges)
template <class SurfaceIterator> template <typename SurfaceIterator>
void set_minimum_over_face(Face_handle face, SurfaceIterator begin, void set_minimum_over_face(Face_handle face, SurfaceIterator begin,
SurfaceIterator end) SurfaceIterator end) {
{
if (face->is_unbounded() || begin == end) { if (face->is_unbounded() || begin == end) {
// a special case - no surface over the unbounded face, and when there // a special case - no surface over the unbounded face, and when there
// are no surfaces at all // are no surfaces at all
face->set_no_data(); face->set_no_data();
} }
else { else {
SurfaceIterator si = begin; auto si = begin;
// we set the first surface as the minimum, and then compare all the // we set the first surface as the minimum, and then compare all the
// others // others
face->set_data(*si); face->set_env_data(*si);
++si; ++si;
for (; si != end; ++si) { for (; si != end; ++si) {
Comparison_result cr = Comparison_result cr =
compare_surfaces_over_face(face, face->get_data(), *si); compare_surfaces_over_face(face, face->get_env_data(), *si);
if (cr == EQUAL) if (cr == EQUAL) face->add_data(*si);
face->add_data(*si); // this erases all surfaces from face's list
else if (cr == LARGER) else if (cr == LARGER) face->set_env_data(*si);
face->set_data(*si); // this erases all surfaces from face's list
// else - new surface has no affect on the envelope // else - new surface has no affect on the envelope
} }
} }
@ -379,8 +343,7 @@ protected:
Comparison_result Comparison_result
compare_surfaces_over_face(Face_handle face, compare_surfaces_over_face(Face_handle face,
const Xy_monotone_surface_3& surf1, const Xy_monotone_surface_3& surf1,
const Xy_monotone_surface_3& surf2) const Xy_monotone_surface_3& surf2) {
{
Comparison_result result2 = Comparison_result result2 =
compare_surfaces_over_face_v2(face, surf1, surf2); compare_surfaces_over_face_v2(face, surf1, surf2);
@ -407,8 +370,7 @@ protected:
Comparison_result Comparison_result
compare_surfaces_over_face_v1(const Face_handle& face, compare_surfaces_over_face_v1(const Face_handle& face,
const Xy_monotone_surface_3& surf1, const Xy_monotone_surface_3& surf1,
const Xy_monotone_surface_3& surf2) const Xy_monotone_surface_3& surf2) {
{
// TODO: this works for triangles, but not for general surfaces // TODO: this works for triangles, but not for general surfaces
// in the general case, should use surface_compare_on_right and // in the general case, should use surface_compare_on_right and
@ -416,7 +378,7 @@ protected:
// we iterate over the vertices of the face, and look for one that the // we iterate over the vertices of the face, and look for one that the
// surfaces are not equal above it. (if doesn't exist, then the surfaces // surfaces are not equal above it. (if doesn't exist, then the surfaces
// overlap) // overlap)
assert(!face->is_unbounded()); assert(! face->is_unbounded());
Comparison_result cur_res; Comparison_result cur_res;
Ccb_halfedge_circulator hec = face->outer_ccb(); Ccb_halfedge_circulator hec = face->outer_ccb();
Ccb_halfedge_circulator hec_begin = hec; Ccb_halfedge_circulator hec_begin = hec;
@ -448,10 +410,9 @@ protected:
// this version also works only for linear surfaces // this version also works only for linear surfaces
Comparison_result Comparison_result
compare_surfaces_over_face_v2(const Face_handle& face, compare_surfaces_over_face_v2(const Face_handle& face,
const Xy_monotone_surface_3 &surf1, const Xy_monotone_surface_3& surf1,
const Xy_monotone_surface_3& surf2) const Xy_monotone_surface_3& surf2) {
{ assert(! face->is_unbounded());
assert(!face->is_unbounded());
Comparison_result cur_res; Comparison_result cur_res;
if (face != current_face) if (face != current_face)
compute_point_in_current_face(face); compute_point_in_current_face(face);
@ -468,11 +429,9 @@ protected:
// check if the surface is defines over the edge // check if the surface is defines over the edge
bool is_surface_defined_over_edge(const Halfedge_handle& h, bool is_surface_defined_over_edge(const Halfedge_handle& h,
Xy_monotone_surface_3 &surf) Xy_monotone_surface_3& surf) {
{
// check it over a point inside the edge's curve // check it over a point inside the edge's curve
if (h != current_edge) if (h != current_edge) compute_point_in_current_edge(h);
compute_point_in_current_edge(h);
bool result = bool result =
traits.is_defined_over_object()(current_point_inside_edge, surf); traits.is_defined_over_object()(current_point_inside_edge, surf);
@ -481,11 +440,10 @@ protected:
// check if the surface is defines over the face // check if the surface is defines over the face
bool is_surface_defined_over_face(const Face_handle& face, bool is_surface_defined_over_face(const Face_handle& face,
Xy_monotone_surface_3 &surf) Xy_monotone_surface_3& surf)
{ {
// we always have bounded surfaces // we always have bounded surfaces
if (face->is_unbounded()) if (face->is_unbounded()) return false;
return false;
bool result2 = is_surface_defined_over_face_v2(face, surf); bool result2 = is_surface_defined_over_face_v2(face, surf);
@ -505,16 +463,14 @@ protected:
// check if the surface is defines over the face // check if the surface is defines over the face
// this is version 1 which check all the vertices of the face // this is version 1 which check all the vertices of the face
bool is_surface_defined_over_face_v1(const Face_handle& face, bool is_surface_defined_over_face_v1(const Face_handle& face,
Xy_monotone_surface_3 &surf) Xy_monotone_surface_3& surf) {
{
// for now, we go over all the vertices of the face // for now, we go over all the vertices of the face
typename Traits::Is_defined_over is_defined_over = auto is_defined_over = traits.is_defined_over_object();
traits.is_defined_over_object();
// check vertices on the outer ccb // check vertices on the outer ccb
bool result = true; bool result = true;
if (!face->is_unbounded()) { if (! face->is_unbounded()) {
Ccb_halfedge_circulator hec = face->outer_ccb(); Ccb_halfedge_circulator hec = face->outer_ccb();
Ccb_halfedge_circulator hec_begin = hec; Ccb_halfedge_circulator hec_begin = hec;
do { do {
@ -522,7 +478,7 @@ protected:
bool tmp_result = is_defined_over(target_2,surf); bool tmp_result = is_defined_over(target_2,surf);
#ifdef CGAL_DEBUG_ENVELOPE_TRIANGLES_TEST_3 #ifdef CGAL_DEBUG_ENVELOPE_TRIANGLES_TEST_3
std::cout << "is define over returned " << tmp_result << std::endl; std::cout << "is define over returned " << tmp_result << std::endl;
#endif #endif
result &= tmp_result; result &= tmp_result;
@ -530,8 +486,7 @@ protected:
} while(hec != hec_begin && result); } while(hec != hec_begin && result);
} }
if (result == false) if (result == false) return result;
return result;
// check vertices on holes boundary // check vertices on holes boundary
Hole_iterator hi; Hole_iterator hi;
@ -549,8 +504,7 @@ protected:
result &= tmp_result; result &= tmp_result;
hec++; hec++;
} while(hec != hec_begin && result); } while(hec != hec_begin && result);
if (result == false) if (result == false) return result;
return result;
} }
return result; return result;
@ -559,8 +513,7 @@ protected:
// check if the surface is defines over the face // check if the surface is defines over the face
// this is version 2 which check the point inside the face // this is version 2 which check the point inside the face
bool is_surface_defined_over_face_v2(const Face_handle& face, bool is_surface_defined_over_face_v2(const Face_handle& face,
Xy_monotone_surface_3 &surf) Xy_monotone_surface_3& surf) {
{
if (face != current_face) if (face != current_face)
compute_point_in_current_face(face); compute_point_in_current_face(face);
@ -570,10 +523,9 @@ protected:
} }
// compute a point inside the face of the arranegement // compute a point inside the face of the arranegement
Point_2 compute_point_inside_face(Minimization_diagram_2 &env, Point_2 compute_point_inside_face(Minimization_diagram_2& env,
Face_handle face) Face_handle face) {
{ assert(! face->is_unbounded());
assert(!face->is_unbounded());
#ifdef CGAL_DEBUG_ENVELOPE_TRIANGLES_TEST_3 #ifdef CGAL_DEBUG_ENVELOPE_TRIANGLES_TEST_3
std::cout << "in compute point inside face" << std::endl; std::cout << "in compute point inside face" << std::endl;
@ -584,7 +536,7 @@ protected:
Ccb_halfedge_circulator hec_begin = hec; Ccb_halfedge_circulator hec_begin = hec;
bool found = false; bool found = false;
do { do {
if (!traits.is_vertical_2_object()(hec->curve())) { if (! traits.is_vertical_2_object()(hec->curve())) {
found = true; found = true;
continue; continue;
} }
@ -611,17 +563,15 @@ protected:
(found_hh->curve()))) (found_hh->curve())))
shoot_up = false; shoot_up = false;
Md_point_location pl(env); Md2_point_location pl(env);
Object shoot_obj; Object shoot_obj;
Halfedge_const_handle shoot_hh; Halfedge_const_handle shoot_hh;
Vertex_const_handle shoot_vh; Vertex_const_handle shoot_vh;
Point_2 shoot_target; Point_2 shoot_target;
if (shoot_up) if (shoot_up) shoot_obj = pl.ray_shoot_up(shoot_source);
shoot_obj = pl.ray_shoot_up(shoot_source); else shoot_obj = pl.ray_shoot_down(shoot_source);
else
shoot_obj = pl.ray_shoot_down(shoot_source);
if (assign(shoot_hh, shoot_obj)) { if (assign(shoot_hh, shoot_obj)) {
shoot_target = shoot_target =
@ -630,8 +580,7 @@ protected:
else if (assign(shoot_vh, shoot_obj)) { else if (assign(shoot_vh, shoot_obj)) {
shoot_target = (env.non_const_handle(shoot_vh))->point(); shoot_target = (env.non_const_handle(shoot_vh))->point();
} }
else else CGAL_error(); // it cannot be the unbounded face
CGAL_error(); // it cannot be the unbounded face
Point_2 res_point = Point_2 res_point =
traits.construct_middle_point(shoot_source, shoot_target); traits.construct_middle_point(shoot_source, shoot_target);
@ -652,16 +601,14 @@ protected:
// compute a point inside the face saved in current_face // compute a point inside the face saved in current_face
// and put the result into current_point // and put the result into current_point
void compute_point_in_current_face(Face_handle face) void compute_point_in_current_face(Face_handle face) {
{
current_face = face; current_face = face;
current_point = compute_point_inside_face(*m_result, current_face); current_point = compute_point_inside_face(*m_result, current_face);
} }
// compute a point inside the edge saved in current_edge // compute a point inside the edge saved in current_edge
// and put the result into current_point_inside_edge // and put the result into current_point_inside_edge
void compute_point_in_current_edge(Halfedge_handle h) void compute_point_in_current_edge(Halfedge_handle h) {
{
current_edge = h; current_edge = h;
current_point_inside_edge = traits.construct_middle_point(h->curve()); current_point_inside_edge = traits.construct_middle_point(h->curve());
} }