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

View File

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

View File

@ -8,7 +8,8 @@
// 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
#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
// features in the new map
template <class MinimizationDiagram_2>
class Envelope_test_overlay_functor
{
template <typename MinimizationDiagram_2>
class Envelope_test_overlay_functor {
public:
typedef MinimizationDiagram_2 Minimization_diagram_2;
using Minimization_diagram_2 = MinimizationDiagram_2;
typedef typename Minimization_diagram_2::Face_const_handle Face_handle1;
typedef typename Minimization_diagram_2::Face_const_handle Face_handle2;
private:
using Md2 = Minimization_diagram_2;
typedef typename Minimization_diagram_2::Vertex_const_handle Vertex_handle1;
typedef typename Minimization_diagram_2::Vertex_const_handle Vertex_handle2;
public:
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;
typedef typename Minimization_diagram_2::Halfedge_const_handle Halfedge_handle2;
using Vertex_handle1 = typename Md2::Vertex_const_handle;
using Vertex_handle2 = typename Md2::Vertex_const_handle;
typedef typename Minimization_diagram_2::Face_handle Res_face_handle;
typedef typename Minimization_diagram_2::Halfedge_handle Res_halfedge_handle;
typedef typename Minimization_diagram_2::Vertex_handle Res_vertex_handle;
using Halfedge_handle1 = typename Md2::Halfedge_const_handle;
using Halfedge_handle2 = typename Md2::Halfedge_const_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& ,
Minimization_diagram_2& ,
Minimization_diagram_2& )
{}
Envelope_test_overlay_functor(Md2&, Md2&, Md2&) {}
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(1, f2);
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,
Halfedge_handle2 h2,
Res_vertex_handle res_v)
{
void create_vertex(Halfedge_handle1 h1, Halfedge_handle2 h2,
Res_vertex_handle res_v) {
res_v->set_aux_source(0, h1);
res_v->set_aux_source(1, h2);
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,
Vertex_handle2 v2,
Res_vertex_handle res_v)
{
void create_vertex(Vertex_handle1 v1, Vertex_handle2 v2,
Res_vertex_handle res_v) {
res_v->set_aux_source(0, v1);
res_v->set_aux_source(1, v2);
assert_msg(v1->is_equal_data(v2->begin_data(), v2->end_data()),
"data different over vertex");
}
void create_vertex(Vertex_handle1 v1,
Halfedge_handle2 h2,
Res_vertex_handle res_v)
{
void create_vertex(Vertex_handle1 v1, Halfedge_handle2 h2,
Res_vertex_handle res_v) {
res_v->set_aux_source(0, v1);
res_v->set_aux_source(1, h2);
assert_msg(v1->is_equal_data(h2->begin_data(), h2->end_data()),
"data different over vertex");
}
void create_vertex(Halfedge_handle1 h1,
Vertex_handle2 v2,
Res_vertex_handle res_v)
{
void create_vertex(Halfedge_handle1 h1, Vertex_handle2 v2,
Res_vertex_handle res_v) {
res_v->set_aux_source(0, h1);
res_v->set_aux_source(1, v2);
assert_msg(h1->is_equal_data(v2->begin_data(), v2->end_data()),
"data different over vertex");
}
void create_vertex(Face_handle1 f1,
Vertex_handle2 v2,
Res_vertex_handle res_v)
{
void create_vertex(Face_handle1 f1, Vertex_handle2 v2,
Res_vertex_handle res_v) {
res_v->set_aux_source(0, f1);
res_v->set_aux_source(1, v2);
assert_msg(f1->is_equal_data(v2->begin_data(), v2->end_data()),
"data different over vertex");
}
void create_vertex(Vertex_handle1 v1,
Face_handle2 f2,
Res_vertex_handle res_v)
{
void create_vertex(Vertex_handle1 v1, Face_handle2 f2,
Res_vertex_handle res_v) {
res_v->set_aux_source(0, v1);
res_v->set_aux_source(1, f2);
assert_msg(v1->is_equal_data(f2->begin_data(), f2->end_data()),
"data different over vertex");
}
void create_edge(Halfedge_handle1 h1,
Halfedge_handle2 h2,
Res_halfedge_handle res_h)
{
void create_edge(Halfedge_handle1 h1, Halfedge_handle2 h2,
Res_halfedge_handle res_h) {
res_h->set_aux_source(0, h1);
res_h->set_aux_source(1, h2);
@ -136,10 +120,8 @@ public:
"data different over edge");
}
void create_edge(Halfedge_handle1 h1,
Face_handle2 f2,
Res_halfedge_handle res_h)
{
void create_edge(Halfedge_handle1 h1, Face_handle2 f2,
Res_halfedge_handle res_h) {
res_h->set_aux_source(0, h1);
res_h->set_aux_source(1, f2);
@ -150,10 +132,8 @@ public:
"data different over edge");
}
void create_edge(Face_handle1 f1,
Halfedge_handle2 h2,
Res_halfedge_handle res_h)
{
void create_edge(Face_handle1 f1, Halfedge_handle2 h2,
Res_halfedge_handle res_h) {
res_h->set_aux_source(0, f1);
res_h->set_aux_source(1, h2);
@ -169,5 +149,3 @@ public:
} //namespace CGAL
#endif

View File

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