1188 lines
37 KiB
C
1188 lines
37 KiB
C
|
// Copyright (c) 1997-2002 Max-Planck-Institute Saarbruecken (Germany).
|
||
|
// All rights reserved.
|
||
|
//
|
||
|
// This file is part of CGAL (www.cgal.org).
|
||
|
//
|
||
|
// $URL: https://github.com/CGAL/cgal/blob/v5.1/Nef_3/include/CGAL/Nef_3/Infimaximal_box.h $
|
||
|
// $Id: Infimaximal_box.h e9d41d7 2020-04-21T10:03:00+02:00 Maxime Gimeno
|
||
|
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||
|
//
|
||
|
//
|
||
|
// Author(s) : Peter Hachenberger <hachenberger@mpi-sb.mpg.de>
|
||
|
|
||
|
#ifndef CGAL_INFIMAXIMAL_BOX_H
|
||
|
#define CGAL_INFIMAXIMAL_BOX_H
|
||
|
|
||
|
#include <CGAL/license/Nef_3.h>
|
||
|
|
||
|
|
||
|
#undef CGAL_NEF_DEBUG
|
||
|
#define CGAL_NEF_DEBUG 191
|
||
|
#include <CGAL/Nef_2/debug.h>
|
||
|
|
||
|
#include <CGAL/Extended_cartesian.h>
|
||
|
#include <CGAL/Extended_homogeneous.h>
|
||
|
|
||
|
#include <CGAL/Nef_3/SNC_intersection.h>
|
||
|
|
||
|
namespace CGAL {
|
||
|
|
||
|
template <class T, class Kernel>
|
||
|
class Infimaximal_box {
|
||
|
|
||
|
public:
|
||
|
typedef typename Kernel::RT NT;
|
||
|
typedef typename Kernel::RT RT;
|
||
|
typedef Kernel Standard_kernel;
|
||
|
typedef typename Kernel::Point_3 Point_3;
|
||
|
typedef typename Kernel::Vector_3 Vector_3;
|
||
|
typedef typename Kernel::Plane_3 Plane_3;
|
||
|
typedef typename Kernel::Ray_3 Ray_3;
|
||
|
typedef typename Kernel::Aff_transformation_3 Aff_transformation_3;
|
||
|
typedef Plane_3 Standard_plane;
|
||
|
typedef Vector_3 Standard_vector;
|
||
|
typedef Point_3 Standard_point;
|
||
|
|
||
|
static bool standard_kernel() {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
static bool extended_kernel() {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
static bool is_standard(const Point_3& ) {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
static bool is_standard(const Plane_3& ) {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
static bool check_point_on_plane(Point_3 p, Plane_3 h) {
|
||
|
return (p.hx()*h.a()+p.hy()*h.b()+p.hz()*h.c()+p.hw()*h.d() == 0);
|
||
|
}
|
||
|
|
||
|
static Point_3 simplify(Point_3& p) {
|
||
|
return p;
|
||
|
}
|
||
|
|
||
|
static Standard_point standard_point(Point_3 p, NT =1) {
|
||
|
return p;
|
||
|
}
|
||
|
|
||
|
static Standard_plane standard_plane(Plane_3 p, NT =1) {
|
||
|
return p;
|
||
|
}
|
||
|
|
||
|
static Standard_vector standard_vector(Vector_3 p) {
|
||
|
return p;
|
||
|
}
|
||
|
|
||
|
static void set_size_of_infimaximal_box(const NT& ) {}
|
||
|
|
||
|
static int degree(const RT& ) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static NT get_coeff(const RT& p, unsigned int ) {
|
||
|
return p;
|
||
|
}
|
||
|
|
||
|
static NT eval_at(const RT& p) {
|
||
|
return p;
|
||
|
}
|
||
|
|
||
|
static bool is_infibox_corner(const Point_3& ) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
template <typename Sphere_map>
|
||
|
static bool is_complex_facet_infibox_intersection(const Sphere_map& ) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
static int type_of_infibox_point(const Point_3& ) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
template <typename SNC_structure>
|
||
|
static typename SNC_structure::Volume_const_handle getNirvana(SNC_structure& snc) {
|
||
|
return snc.volumes_begin();
|
||
|
}
|
||
|
|
||
|
template <typename SNC_structure>
|
||
|
static bool is_beyond_Infibox(typename SNC_structure::SFace_handle ,
|
||
|
SNC_structure& ) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
static bool x_on_box(const Point_3& ) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
static bool y_on_box(const Point_3& ) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
static bool z_on_box(const Point_3& ) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
template<typename SNC_structure>
|
||
|
static NT compute_evaluation_constant_for_halfedge_pairup(const SNC_structure& ) {
|
||
|
return NT(1);
|
||
|
}
|
||
|
|
||
|
static void compute_min_max(const Plane_3& , NT orth_coords[3], int& /* min */, int& /* max */) {
|
||
|
(void)orth_coords;
|
||
|
}
|
||
|
|
||
|
static Point_3 scale_infibox_vertex(const Point_3& ) {
|
||
|
return Point_3();
|
||
|
}
|
||
|
|
||
|
static Point_3 normalize_transformed_vertex(const Point_3& ) {
|
||
|
return Point_3();
|
||
|
}
|
||
|
|
||
|
template <typename SNC_constructor, typename Mark>
|
||
|
static std::list<typename SNC_constructor::Vertex_handle>
|
||
|
create_vertices_on_infibox(SNC_constructor&,
|
||
|
const Plane_3&, const std::list<Point_3>&,
|
||
|
const Mark&, const Mark&, const Mark&) {
|
||
|
// TODO: warning oder assertion einbauen
|
||
|
return std::list<typename SNC_constructor::Vertex_handle>();
|
||
|
}
|
||
|
|
||
|
template <typename SNC_constructor>
|
||
|
static std::list<Point_3> find_points_of_box_with_plane(SNC_constructor&, const Plane_3&) {
|
||
|
return std::list<Point_3>();
|
||
|
}
|
||
|
|
||
|
static typename std::list<Point_3>::const_iterator segment_on_side(int /*side_of_point*/,
|
||
|
const std::list<Point_3>& segs) {
|
||
|
return segs.begin();
|
||
|
}
|
||
|
|
||
|
static Point_3 create_extended_point(NT, NT, NT) {
|
||
|
std::cerr << "function should not be called" << std::endl;
|
||
|
CGAL_error_msg("function should not be called");
|
||
|
return Point_3(0,0,0);
|
||
|
}
|
||
|
|
||
|
static Plane_3 create_extended_plane(NT, NT, NT, NT) {
|
||
|
std::cerr << "function should not be called" << std::endl;
|
||
|
return Plane_3(1,0,0,0);
|
||
|
}
|
||
|
|
||
|
template <typename SNC_decorator, typename Point>
|
||
|
static Ray_3 get_ray(SNC_decorator& , Point& p) {
|
||
|
// return D.point(D.vertex(D.shells_begin(D.volumes_begin())));
|
||
|
return Ray_3(p, Vector_3(-1,0,0));
|
||
|
}
|
||
|
|
||
|
template <typename SNC_constructor_>
|
||
|
static void create_vertices_of_box_with_plane(SNC_constructor_&, const Plane_3&, bool) {
|
||
|
std::cerr << "Constructor not available for this Kernel" << std::endl;
|
||
|
}
|
||
|
|
||
|
template <typename SNC_constructor>
|
||
|
static void initialize_infibox_vertices(SNC_constructor& , bool ) {
|
||
|
}
|
||
|
|
||
|
template <typename SHalfedge_handle>
|
||
|
static bool is_sedge_on_infibox(SHalfedge_handle ) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
template <typename Halfedge_handle>
|
||
|
static bool is_edge_on_infibox(Halfedge_handle ) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
template <typename Vertex_handle>
|
||
|
static bool is_redundant_box_vertex(Vertex_handle ) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
template <typename Halfedge_handle>
|
||
|
static bool is_type4(Halfedge_handle ) {return false;}
|
||
|
|
||
|
template <typename Halfedge_handle>
|
||
|
static bool is_type3(Halfedge_handle ) {return false;}
|
||
|
};
|
||
|
|
||
|
template <class Kernel>
|
||
|
class Infimaximal_box<Tag_true, Kernel> {
|
||
|
|
||
|
public:
|
||
|
typedef typename Kernel::RT RT;
|
||
|
typedef typename Kernel::RT::NT NT;
|
||
|
typedef typename Kernel::Standard_kernel Standard_kernel;
|
||
|
typedef typename Standard_kernel::Point_3 Standard_point;
|
||
|
typedef typename Standard_kernel::Plane_3 Standard_plane;
|
||
|
typedef typename Standard_kernel::Vector_3 Standard_vector;
|
||
|
typedef typename Kernel::Point_3 Point_3;
|
||
|
typedef typename Kernel::Plane_3 Plane_3;
|
||
|
typedef typename Kernel::Vector_3 Vector_3;
|
||
|
typedef typename Kernel::Segment_3 Segment_3;
|
||
|
typedef typename Kernel::Direction_3 Direction_3;
|
||
|
typedef typename Kernel::Aff_transformation_3 Aff_transformation_3;
|
||
|
|
||
|
enum Boundary { EXCLUDED=0, INCLUDED=1 };
|
||
|
|
||
|
static const int RADIUS = 10000000;
|
||
|
|
||
|
static bool standard_kernel() {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
static bool extended_kernel() {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
static bool is_standard(const Point_3& p) {
|
||
|
CGAL_assertion(p.hw().degree()==0);
|
||
|
return (p.hx().degree()==0 && p.hy().degree()==0 && p.hz().degree()==0);
|
||
|
}
|
||
|
|
||
|
static bool is_standard(const Plane_3& p) {
|
||
|
return (p.d().degree() == 0);
|
||
|
}
|
||
|
|
||
|
static int type_of_infibox_point(const Point_3& p) {
|
||
|
int res = 0;
|
||
|
RT W(NT(0),p.hw()[0]);
|
||
|
if(CGAL_NTS abs(p.hx()) == W) ++res;
|
||
|
if(CGAL_NTS abs(p.hy()) == W) ++res;
|
||
|
if(CGAL_NTS abs(p.hz()) == W) ++res;
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
static bool is_infibox_corner(const Point_3& p) {
|
||
|
return type_of_infibox_point(p) == 3;
|
||
|
}
|
||
|
|
||
|
static Point_3 simplify(Point_3& p) {
|
||
|
CGAL_assertion(p.hw().degree() == 0);
|
||
|
int deg = p.hx().degree() > p.hy().degree()
|
||
|
? p.hx().degree()
|
||
|
: p.hy().degree();
|
||
|
deg = p.hz().degree() > deg
|
||
|
? p.hz().degree()
|
||
|
: deg;
|
||
|
return Point_3(p.hx().degree() == deg ? p.hx()[deg] : 0,
|
||
|
p.hy().degree() == deg ? p.hy()[deg] : 0,
|
||
|
p.hz().degree() == deg ? p.hz()[deg] : 0,
|
||
|
p.hw()[0]);
|
||
|
}
|
||
|
|
||
|
static int degree(const RT& p) {
|
||
|
return p.degree();
|
||
|
}
|
||
|
|
||
|
static NT get_coeff(const RT& p, unsigned int i) {
|
||
|
return p[i];
|
||
|
}
|
||
|
|
||
|
static NT eval_at(const RT& p, NT d=RADIUS) {
|
||
|
return p.eval_at(d);
|
||
|
}
|
||
|
|
||
|
static bool check_point_on_plane(Point_3 p, Plane_3 h) {
|
||
|
NT x(p.hx().eval_at(100));
|
||
|
NT y(p.hy().eval_at(100));
|
||
|
NT z(p.hz().eval_at(100));
|
||
|
NT w(p.hw().eval_at(100));
|
||
|
NT a(h.a().eval_at(100));
|
||
|
NT b(h.b().eval_at(100));
|
||
|
NT c(h.c().eval_at(100));
|
||
|
NT d(h.d().eval_at(100));
|
||
|
return (x*a+y*b+z*c+w*d == 0);
|
||
|
}
|
||
|
|
||
|
static Standard_point standard_point(Point_3 p, NT d=1) {
|
||
|
return Standard_point(p.hx().eval_at(d),
|
||
|
p.hy().eval_at(d),
|
||
|
p.hz().eval_at(d),
|
||
|
p.hw().eval_at(1));
|
||
|
}
|
||
|
|
||
|
static Standard_plane standard_plane(Plane_3 p, NT d=1) {
|
||
|
return Standard_plane(p.a().eval_at(1),
|
||
|
p.b().eval_at(1),
|
||
|
p.c().eval_at(1),
|
||
|
p.d().eval_at(d));
|
||
|
}
|
||
|
|
||
|
static Standard_vector standard_vector(Vector_3 p) {
|
||
|
return Standard_vector(p.hx().eval_at(1),
|
||
|
p.hy().eval_at(1),
|
||
|
p.hz().eval_at(1));
|
||
|
}
|
||
|
|
||
|
static void set_size_of_infimaximal_box(NT size) {
|
||
|
RT::infi_maximal_value() = size;
|
||
|
}
|
||
|
|
||
|
static bool x_on_box(const Point_3& p) {
|
||
|
return CGAL_NTS abs(p.hx()) == RT(0,p.hw()[0]);
|
||
|
}
|
||
|
|
||
|
static bool y_on_box(const Point_3& p) {
|
||
|
return CGAL_NTS abs(p.hy()) == RT(0,p.hw()[0]);
|
||
|
}
|
||
|
|
||
|
static bool z_on_box(const Point_3& p) {
|
||
|
return CGAL_NTS abs(p.hz()) == RT(0,p.hw()[0]);
|
||
|
}
|
||
|
|
||
|
static Point_3 create_extended_point(NT x, NT y, NT z) {
|
||
|
return Point_3(RT(0,x), RT(0,y), RT(0,z), RT(1));
|
||
|
}
|
||
|
|
||
|
static Plane_3 create_extended_plane(NT a, NT b, NT c, NT d) {
|
||
|
return Plane_3(a,b,c,RT(0,d));
|
||
|
}
|
||
|
|
||
|
static Point_3 create_extended_point(NT a0,NT a1,NT b0,NT b1,NT c0,NT c1,NT d) {
|
||
|
return Point_3(RT(a0,a1),RT(b0,b1),RT(c0,c1),RT(d));
|
||
|
}
|
||
|
|
||
|
template <typename SNC_structure>
|
||
|
static typename SNC_structure::Volume_handle getNirvana(SNC_structure& snc) {
|
||
|
return ++(snc.volumes_begin());
|
||
|
}
|
||
|
|
||
|
template <typename SNC_structure>
|
||
|
static bool is_beyond_Infibox(typename SNC_structure::SFace_handle sf,
|
||
|
SNC_structure& snc) {
|
||
|
typename SNC_structure::SNC_decorator D(snc);
|
||
|
return (D.volume(sf) == snc.volumes_begin());
|
||
|
}
|
||
|
|
||
|
template <typename SNC_constructor, typename Mark>
|
||
|
static std::list<typename SNC_constructor::Vertex_handle>
|
||
|
create_vertices_on_infibox(SNC_constructor& C,
|
||
|
const Plane_3& h, const std::list<Point_3>& points,
|
||
|
const Mark& bnd, const Mark& inside, const Mark& outside) {
|
||
|
return C.create_vertices_on_infibox(h,points,bnd,inside,outside);
|
||
|
}
|
||
|
|
||
|
template <typename SNC_constructor>
|
||
|
static void create_vertices_of_box_with_plane(SNC_constructor& C, const Plane_3& h, bool b) {
|
||
|
C.create_vertices_of_box_with_plane(h, b);
|
||
|
}
|
||
|
|
||
|
static void compute_min_max(const Plane_3& h, NT orth_coords[3], int& cmin, int& cmax) {
|
||
|
Vector_3 orth = h.orthogonal_vector();
|
||
|
|
||
|
orth_coords[0] = CGAL_NTS abs(orth.hx()[0]);
|
||
|
orth_coords[1] = CGAL_NTS abs(orth.hy()[0]);
|
||
|
orth_coords[2] = CGAL_NTS abs(orth.hz()[0]);
|
||
|
|
||
|
cmax = 0;
|
||
|
if(orth_coords[1] > orth_coords[0])
|
||
|
cmax = 1;
|
||
|
if(orth_coords[2] > orth_coords[cmax])
|
||
|
cmax = 2;
|
||
|
|
||
|
cmin = 0;
|
||
|
if(orth_coords[1] < orth_coords[0])
|
||
|
cmin = 1;
|
||
|
if(orth_coords[2] < orth_coords[cmin])
|
||
|
cmin = 2;
|
||
|
}
|
||
|
|
||
|
template<typename SNC_structure>
|
||
|
static NT compute_evaluation_constant_for_halfedge_pairup(const SNC_structure& snc) {
|
||
|
NT eval = 0;
|
||
|
typename SNC_structure::Vertex_const_iterator v;
|
||
|
CGAL_forall_vertices(v, snc) {
|
||
|
Point_3 p(v->point());
|
||
|
if(p.hx()[0] > eval) eval = p.hx()[0];
|
||
|
if(p.hy()[0] > eval) eval = p.hy()[0];
|
||
|
if(p.hz()[0] > eval) eval = p.hz()[0];
|
||
|
}
|
||
|
eval *= 4;
|
||
|
if(eval == 0) return 1;
|
||
|
return eval;
|
||
|
}
|
||
|
|
||
|
static Point_3 scale_infibox_vertex(const Point_3 pin, const Aff_transformation_3& aff) {
|
||
|
RT lx(pin.hx()[0]);
|
||
|
RT ly(pin.hy()[0]);
|
||
|
RT lz(pin.hz()[0]);
|
||
|
RT hx(pin.hx()-lx);
|
||
|
RT hy(pin.hy()-ly);
|
||
|
RT hz(pin.hz()-lz);
|
||
|
RT hw(pin.hw());
|
||
|
Point_3 p(Point_3(lx,ly,lz,hw).transform(aff));
|
||
|
return Point_3(hx+p.hx(),hy+p.hy(),hz+p.hz(),hw);
|
||
|
}
|
||
|
|
||
|
static Point_3 normalize_transformed_vertex(const Point_3& p) {
|
||
|
int i=0;
|
||
|
if(CGAL_NTS abs(p.hx()) < CGAL_NTS abs(p.hy()))
|
||
|
if(CGAL_NTS abs(p.hy()) < CGAL_NTS abs(p.hz()))
|
||
|
i = 2;
|
||
|
else
|
||
|
i = 1;
|
||
|
else if(CGAL_NTS abs(p.hx()) < CGAL_NTS abs(p.hz()))
|
||
|
i = 2;
|
||
|
|
||
|
switch(i) {
|
||
|
case 0:
|
||
|
CGAL_assertion(p.hx().degree() == 1);
|
||
|
if(p.hx()[1] > 0)
|
||
|
return Point_3(RT(0,p.hx()[1]*p.hw()[0]),
|
||
|
RT(p.hy()[0]*p.hx()[1]-p.hx()[0]*p.hy()(1),p.hy()(1)*p.hw()[0]),
|
||
|
RT(p.hz()[0]*p.hx()[1]-p.hx()[0]*p.hz()(1),p.hz()(1)*p.hw()[0]),
|
||
|
RT(p.hw()[0]*p.hx()[1]));
|
||
|
else
|
||
|
return Point_3(RT(0,-p.hx()[1]*p.hw()[0]),
|
||
|
RT(p.hy()[0]*p.hx()[1]-p.hx()[0]*p.hy()(1),-p.hy()(1)*p.hw()[0]),
|
||
|
RT(p.hz()[0]*p.hx()[1]-p.hx()[0]*p.hz()(1),-p.hz()(1)*p.hw()[0]),
|
||
|
RT(p.hw()[0]*p.hx()[1]));
|
||
|
case 1:
|
||
|
CGAL_assertion(p.hy().degree() == 1);
|
||
|
if(p.hy()[1] > 0)
|
||
|
return Point_3(RT(p.hx()[0]*p.hy()[1]-p.hy()[0]*p.hx()(1),p.hx()(1)*p.hw()[0]),
|
||
|
RT(0,p.hy()[1]*p.hw()[0]),
|
||
|
RT(p.hz()[0]*p.hy()[1]-p.hy()[0]*p.hz()(1),p.hz()(1)*p.hw()[0]),
|
||
|
RT(p.hw()[0]*p.hy()[1]));
|
||
|
else
|
||
|
return Point_3(RT(p.hx()[0]*p.hy()[1]-p.hy()[0]*p.hx()(1),-p.hx()(1)*p.hw()[0]),
|
||
|
RT(0,-p.hy()[1]*p.hw()[0]),
|
||
|
RT(p.hz()[0]*p.hy()[1]-p.hy()[0]*p.hz()(1),-p.hz()(1)*p.hw()[0]),
|
||
|
RT(p.hw()[0]*p.hy()[1]));
|
||
|
case 2:
|
||
|
CGAL_assertion(p.hz().degree() == 1);
|
||
|
if(p.hz()[1] > 0)
|
||
|
return Point_3(RT(p.hx()[0]*p.hz()[1]-p.hz()[0]*p.hx()(1),p.hx()(1)*p.hw()[0]),
|
||
|
RT(p.hy()[0]*p.hz()[1]-p.hz()[0]*p.hy()(1),p.hy()(1)*p.hw()[0]),
|
||
|
RT(0,p.hz()[1]*p.hw()[0]),
|
||
|
RT(p.hw()[0]*p.hz()[1]));
|
||
|
else
|
||
|
return Point_3(RT(p.hx()[0]*p.hz()[1]-p.hz()[0]*p.hx()(1),-p.hx()(1)*p.hw()[0]),
|
||
|
RT(p.hy()[0]*p.hz()[1]-p.hz()[0]*p.hy()(1),-p.hy()(1)*p.hw()[0]),
|
||
|
RT(0,-p.hz()[1]*p.hw()[0]),
|
||
|
RT(p.hw()[0]*p.hz()[1]));
|
||
|
default: CGAL_error_msg( "wrong value");
|
||
|
}
|
||
|
return Point_3();
|
||
|
}
|
||
|
|
||
|
static typename std::list<Point_3>::const_iterator segment_on_side(int side_of_point,
|
||
|
const std::list<Point_3>& segs) {
|
||
|
|
||
|
typename std::list<Point_3>::const_iterator s1,t1;
|
||
|
for(s1 = segs.begin(); s1 != segs.end(); ++s1) {
|
||
|
t1 = s1;
|
||
|
++t1;
|
||
|
if(t1 == segs.end()) t1 = segs.begin();
|
||
|
switch(side_of_point) {
|
||
|
case 1:
|
||
|
if( s1->hx()(1) != s1->hw()) continue;
|
||
|
if( t1->hx()(1) != t1->hw()) continue;
|
||
|
return s1;
|
||
|
case -1:
|
||
|
if(-s1->hx()(1) != s1->hw()) continue;
|
||
|
if(-t1->hx()(1) != t1->hw()) continue;
|
||
|
return s1;
|
||
|
case 2:
|
||
|
if( s1->hy()(1) != s1->hw()) continue;
|
||
|
if( t1->hy()(1) != t1->hw()) continue;
|
||
|
return s1; break;
|
||
|
case -2:
|
||
|
if(-s1->hy()(1) != s1->hw()) continue;
|
||
|
if(-t1->hy()(1) != t1->hw()) continue;
|
||
|
return s1;
|
||
|
case 3:
|
||
|
if( s1->hz()(1) != s1->hw()) continue;
|
||
|
if( t1->hz()(1) != t1->hw()) continue;
|
||
|
return s1;
|
||
|
case -3:
|
||
|
if(-s1->hz()(1) != s1->hw()) continue;
|
||
|
if(-t1->hz()(1) != t1->hw()) continue;
|
||
|
return s1;
|
||
|
default: CGAL_error_msg( "wrong value");
|
||
|
}
|
||
|
}
|
||
|
CGAL_error_msg( "this line of shall not be reached");
|
||
|
return s1;
|
||
|
}
|
||
|
|
||
|
template <typename SNC_constructor>
|
||
|
static void initialize_infibox_vertices(SNC_constructor& C, bool space) {
|
||
|
|
||
|
#ifdef CGAL_NEF_INDEXED_ITEMS
|
||
|
int base = Index_generator::get_unique_index();
|
||
|
for(int i=0; i<11; ++i)
|
||
|
Index_generator::get_unique_index();
|
||
|
#endif
|
||
|
|
||
|
C.create_extended_box_corner( 1, 1, 1, space, true
|
||
|
#ifdef CGAL_NEF_INDEXED_ITEMS
|
||
|
, base
|
||
|
#endif
|
||
|
);
|
||
|
C.create_extended_box_corner(-1, 1, 1, space, true
|
||
|
#ifdef CGAL_NEF_INDEXED_ITEMS
|
||
|
, base
|
||
|
#endif
|
||
|
);
|
||
|
C.create_extended_box_corner( 1,-1, 1, space, true
|
||
|
#ifdef CGAL_NEF_INDEXED_ITEMS
|
||
|
, base
|
||
|
#endif
|
||
|
);
|
||
|
C.create_extended_box_corner(-1,-1, 1, space, true
|
||
|
#ifdef CGAL_NEF_INDEXED_ITEMS
|
||
|
, base
|
||
|
#endif
|
||
|
);
|
||
|
C.create_extended_box_corner( 1, 1,-1, space, true
|
||
|
#ifdef CGAL_NEF_INDEXED_ITEMS
|
||
|
, base
|
||
|
#endif
|
||
|
);
|
||
|
C.create_extended_box_corner(-1, 1,-1, space, true
|
||
|
#ifdef CGAL_NEF_INDEXED_ITEMS
|
||
|
, base
|
||
|
#endif
|
||
|
);
|
||
|
C.create_extended_box_corner( 1,-1,-1, space, true
|
||
|
#ifdef CGAL_NEF_INDEXED_ITEMS
|
||
|
, base
|
||
|
#endif
|
||
|
);
|
||
|
C.create_extended_box_corner(-1,-1,-1, space, true
|
||
|
#ifdef CGAL_NEF_INDEXED_ITEMS
|
||
|
, base
|
||
|
#endif
|
||
|
);
|
||
|
}
|
||
|
|
||
|
template <typename Halfedge_handle>
|
||
|
static bool is_edge_on_infibox(Halfedge_handle e) {
|
||
|
|
||
|
Point_3 p = e->center_vertex()->point();
|
||
|
if(is_standard(p)) return false;
|
||
|
|
||
|
Vector_3 v(e->vector());
|
||
|
CGAL_assertion(p.hw().degree() == 0);
|
||
|
RT Outer(0,CGAL_NTS abs(p.hw()[0]));
|
||
|
|
||
|
// TODO: are these lines really redundant??
|
||
|
if(CGAL_NTS abs(p.hx()) == Outer &&
|
||
|
((p.hx() > 0 && v.hx() > 0)||(p.hx() < 0 && v.hx() < 0))) return false;
|
||
|
if(CGAL_NTS abs(p.hy()) == Outer &&
|
||
|
((p.hy() > 0 && v.hy() > 0)||(p.hy() < 0 && v.hy() < 0))) return false;
|
||
|
if(CGAL_NTS abs(p.hz()) == Outer &&
|
||
|
((p.hz() > 0 && v.hz() > 0)||(p.hz() < 0 && v.hz() < 0))) return false;
|
||
|
|
||
|
if(CGAL_NTS abs(p.hx()) == Outer && v.hx() == 0) return true;
|
||
|
if(CGAL_NTS abs(p.hy()) == Outer && v.hy() == 0) return true;
|
||
|
if(CGAL_NTS abs(p.hz()) == Outer && v.hz() == 0) return true;
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
|
||
|
template <typename SHalfedge_handle>
|
||
|
static bool is_sedge_on_infibox(SHalfedge_handle sh) {
|
||
|
|
||
|
Point_3 p = sh->source()->center_vertex()->point();
|
||
|
CGAL_NEF_TRACEN("Point " << p);
|
||
|
if(is_standard(p)) return false;
|
||
|
|
||
|
CGAL_NEF_TRACEN("Circle " << sh->circle() <<
|
||
|
" has signum " << sign_of(sh->circle()));
|
||
|
CGAL_assertion(p.hw().degree() == 0);
|
||
|
RT R(0,CGAL_NTS abs(p.hw()[0]));
|
||
|
|
||
|
if((sh->circle().a() == 0 && sh->circle().b() == 0
|
||
|
&& CGAL_NTS abs(p.hz())== R) ||
|
||
|
(sh->circle().a() == 0 && sh->circle().c() == 0
|
||
|
&& CGAL_NTS abs(p.hy())== R) ||
|
||
|
(sh->circle().b() == 0 && sh->circle().c() == 0
|
||
|
&& CGAL_NTS abs(p.hx())== R))
|
||
|
if(is_edge_on_infibox(sh->source()) &&
|
||
|
is_edge_on_infibox(sh->twin()->source()))
|
||
|
return true;
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
template <typename Sphere_map>
|
||
|
static bool is_redundant_box_vertex(const Sphere_map& sm) {
|
||
|
if(is_standard(sm.point())) return false;
|
||
|
if(is_infibox_corner(sm.point())) return false;
|
||
|
typename Sphere_map::SVertex_const_iterator svi;
|
||
|
for(svi = sm.svertices_begin();
|
||
|
svi != sm.svertices_end(); ++svi)
|
||
|
if(!is_edge_on_infibox(svi)) {
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
template <typename Sphere_map>
|
||
|
static bool is_complex_facet_infibox_intersection(const Sphere_map& sm) {
|
||
|
|
||
|
typename Sphere_map::SHalfedge_const_iterator sei;
|
||
|
bool found = false;
|
||
|
CGAL_forall_sedges(sei, sm) {
|
||
|
if(!is_sedge_on_infibox(sei)) {
|
||
|
if(found)
|
||
|
return true;
|
||
|
else
|
||
|
found = true;
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
template <typename SNC_constructor>
|
||
|
static std::list<Point_3> find_points_of_box_with_plane(SNC_constructor& C, const Plane_3& h) {
|
||
|
return C.find_points_of_box_with_plane(h);
|
||
|
}
|
||
|
|
||
|
template <typename Halfedge_handle>
|
||
|
static bool is_type4(Halfedge_handle e) {
|
||
|
|
||
|
Point_3 p(e->center_vertex()->point());
|
||
|
Direction_3 d(e->vector());
|
||
|
|
||
|
if((CGAL_NTS abs(p.hx()) == CGAL_NTS abs(p.hw()) ||
|
||
|
d == Direction_3(1,0,0) ||
|
||
|
d == Direction_3(-1,0,0)) &&
|
||
|
(CGAL_NTS abs(p.hy()) == CGAL_NTS abs(p.hw()) ||
|
||
|
d == Direction_3(0,1,0) ||
|
||
|
d == Direction_3(0,-1,0)) &&
|
||
|
(CGAL_NTS abs(p.hz()) == CGAL_NTS abs(p.hw()) ||
|
||
|
d == Direction_3(0,0,1) ||
|
||
|
d == Direction_3(0,0,-1)))
|
||
|
return true;
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
template <typename Halfedge_handle>
|
||
|
static bool is_type3(Halfedge_handle e) {
|
||
|
|
||
|
Point_3 p(e->center_vertex()->point());
|
||
|
Direction_3 d(e->vector());
|
||
|
|
||
|
if(d == Direction_3(1,0,0) || d == Direction_3(-1,0,0)) {
|
||
|
if(CGAL_NTS abs(p.hy()) == CGAL_NTS abs(p.hw()))
|
||
|
return true;
|
||
|
return false;
|
||
|
}
|
||
|
if(d == Direction_3(0,1,0) || d == Direction_3(0,-1,0)) {
|
||
|
if(CGAL_NTS abs(p.hx()) == CGAL_NTS abs(p.hw()))
|
||
|
return true;
|
||
|
return false;
|
||
|
}
|
||
|
if(d == Direction_3(0,0,1) || d == Direction_3(0,0,-1)) {
|
||
|
if(CGAL_NTS abs(p.hy()) == CGAL_NTS abs(p.hw()))
|
||
|
return true;
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
template <typename RT_>
|
||
|
class Infimaximal_box<Tag_true, CGAL::Pseudo_extended_homogeneous<RT_> > {
|
||
|
|
||
|
public:
|
||
|
typedef typename Kernel::RT RT;
|
||
|
typedef typename Kernel::RT::NT NT;
|
||
|
typedef typename Kernel::Standard_kernel Standard_kernel;
|
||
|
typedef typename Standard_kernel::Point_3 Standard_point;
|
||
|
typedef typename Standard_kernel::Plane_3 Standard_plane;
|
||
|
typedef typename Standard_kernel::Vector_3 Standard_vector;
|
||
|
typedef typename Kernel::Point_3 Point_3;
|
||
|
typedef typename Kernel::Plane_3 Plane_3;
|
||
|
typedef typename Kernel::Vector_3 Vector_3;
|
||
|
typedef typename Kernel::Segment_3 Segment_3;
|
||
|
typedef typename Kernel::Direction_3 Direction_3;
|
||
|
typedef typename Kernel::Aff_transformation_3 Aff_transformation_3;
|
||
|
|
||
|
enum Boundary { EXCLUDED=0, INCLUDED=1 };
|
||
|
|
||
|
static const int RADIUS = 10000000;
|
||
|
|
||
|
static bool standard_kernel() {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
static bool extended_kernel() {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
static bool is_standard(const Point_3& p) {
|
||
|
CGAL_assertion(p.hw().degree()==0);
|
||
|
return (p.hx().degree()==0 && p.hy().degree()==0 && p.hz().degree()==0);
|
||
|
}
|
||
|
|
||
|
static bool is_standard(const Plane_3& p) {
|
||
|
return (p.d().degree() == 0);
|
||
|
}
|
||
|
|
||
|
static int type_of_infibox_point(const Point_3& p) {
|
||
|
int res = 0;
|
||
|
RT W(NT(0),p.hw()[0]);
|
||
|
if(CGAL_NTS abs(p.hx()) == W) ++res;
|
||
|
if(CGAL_NTS abs(p.hy()) == W) ++res;
|
||
|
if(CGAL_NTS abs(p.hz()) == W) ++res;
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
static bool is_infibox_corner(const Point_3& p) {
|
||
|
return type_of_infibox_point(p) == 3;
|
||
|
}
|
||
|
|
||
|
static Point_3 simplify(Point_3& p) {
|
||
|
CGAL_assertion(p.hw().degree() == 0);
|
||
|
int deg = p.hx().degree() > p.hy().degree()
|
||
|
? p.hx().degree()
|
||
|
: p.hy().degree();
|
||
|
deg = p.hz().degree() > deg
|
||
|
? p.hz().degree()
|
||
|
: deg;
|
||
|
return Point_3(p.hx().degree() == deg ? p.hx()[deg] : 0,
|
||
|
p.hy().degree() == deg ? p.hy()[deg] : 0,
|
||
|
p.hz().degree() == deg ? p.hz()[deg] : 0,
|
||
|
p.hw()[0]);
|
||
|
}
|
||
|
|
||
|
static int degree(const RT& p) {
|
||
|
return p.degree();
|
||
|
}
|
||
|
|
||
|
static NT get_coeff(const RT& p, unsigned int i) {
|
||
|
return p[i];
|
||
|
}
|
||
|
|
||
|
static NT eval_at(const RT& p, NT d=RADIUS) {
|
||
|
return p.eval_at(d);
|
||
|
}
|
||
|
|
||
|
static bool check_point_on_plane(Point_3 p, Plane_3 h) {
|
||
|
std::cerr << p << ", " << h << std::endl;
|
||
|
|
||
|
NT x(p.hx().eval_at(100));
|
||
|
NT y(p.hy().eval_at(100));
|
||
|
NT z(p.hz().eval_at(100));
|
||
|
NT w(p.hw().eval_at(100));
|
||
|
NT a(h.a().eval_at(100));
|
||
|
NT b(h.b().eval_at(100));
|
||
|
NT c(h.c().eval_at(100));
|
||
|
NT d(h.d().eval_at(100));
|
||
|
return (x*a+y*b+z*c+w*d == 0);
|
||
|
}
|
||
|
|
||
|
static Standard_point standard_point(Point_3 p, NT d=1) {
|
||
|
return Standard_point(p.hx().eval_at(d),
|
||
|
p.hy().eval_at(d),
|
||
|
p.hz().eval_at(d),
|
||
|
p.hw().eval_at(1));
|
||
|
}
|
||
|
|
||
|
static Standard_plane standard_plane(Plane_3 p, NT d=1) {
|
||
|
return Standard_plane(p.a().eval_at(1),
|
||
|
p.b().eval_at(1),
|
||
|
p.c().eval_at(1),
|
||
|
p.d().eval_at(d));
|
||
|
}
|
||
|
|
||
|
static Standard_vector standard_vector(Vector_3 p) {
|
||
|
return Standard_vector(p.hx().eval_at(1),
|
||
|
p.hy().eval_at(1),
|
||
|
p.hz().eval_at(1));
|
||
|
}
|
||
|
|
||
|
static void set_size_of_infimaximal_box(NT size) {
|
||
|
RT::infi_maximal_value() = size;
|
||
|
}
|
||
|
|
||
|
static bool x_on_box(const Point_3& p) {
|
||
|
return CGAL_NTS abs(p.hx()) == RT(0,p.hw()[0]);
|
||
|
}
|
||
|
|
||
|
static bool y_on_box(const Point_3& p) {
|
||
|
return CGAL_NTS abs(p.hy()) == RT(0,p.hw()[0]);
|
||
|
}
|
||
|
|
||
|
static bool z_on_box(const Point_3& p) {
|
||
|
return CGAL_NTS abs(p.hz()) == RT(0,p.hw()[0]);
|
||
|
}
|
||
|
|
||
|
static Point_3 create_extended_point(NT x, NT y, NT z) {
|
||
|
return Point_3(RT(0,x), RT(0,y), RT(0,z), RT(1));
|
||
|
}
|
||
|
|
||
|
static Plane_3 create_extended_plane(NT a, NT b, NT c, NT d) {
|
||
|
return Plane_3(a,b,c,RT(0,d));
|
||
|
}
|
||
|
|
||
|
static Point_3 create_extended_point(NT a0,NT a1,NT b0,NT b1,NT c0,NT c1,NT d) {
|
||
|
return Point_3(RT(a0,a1),RT(b0,b1),RT(c0,c1),RT(d));
|
||
|
}
|
||
|
|
||
|
template <typename SNC_structure>
|
||
|
static typename SNC_structure::Volume_handle getNirvana(SNC_structure& snc) {
|
||
|
return ++(snc.volumes_begin());
|
||
|
}
|
||
|
|
||
|
template <typename SNC_structure>
|
||
|
static bool is_beyond_Infibox(typename SNC_structure::SFace_handle sf,
|
||
|
SNC_structure& snc) {
|
||
|
typename SNC_structure::SNC_decorator D(snc);
|
||
|
return (D.volume(sf) == snc.volumes_begin());
|
||
|
}
|
||
|
|
||
|
template <typename SNC_constructor, typename Mark>
|
||
|
static std::list<typename SNC_constructor::Vertex_handle>
|
||
|
create_vertices_on_infibox(SNC_constructor& C,
|
||
|
const Plane_3& h, const std::list<Point_3>& points,
|
||
|
const Mark& bnd, const Mark& inside, const Mark& outside) {
|
||
|
return C.create_vertices_on_infibox(h,points,bnd,inside,outside);
|
||
|
}
|
||
|
|
||
|
template <typename SNC_constructor>
|
||
|
static void create_vertices_of_box_with_plane(SNC_constructor& C, const Plane_3& h, bool b) {
|
||
|
C.create_vertices_of_box_with_plane(h, b);
|
||
|
}
|
||
|
|
||
|
static void compute_min_max(const Plane_3& h, NT orth_coords[3], int& min, int& max) {
|
||
|
Vector_3 orth = h.orthogonal_vector();
|
||
|
|
||
|
orth_coords[0] = CGAL_NTS abs(orth.hx()[0]);
|
||
|
orth_coords[1] = CGAL_NTS abs(orth.hy()[0]);
|
||
|
orth_coords[2] = CGAL_NTS abs(orth.hz()[0]);
|
||
|
|
||
|
max = 0;
|
||
|
if(orth_coords[1] > orth_coords[0])
|
||
|
max = 1;
|
||
|
if(orth_coords[2] > orth_coords[max])
|
||
|
max = 2;
|
||
|
|
||
|
min = 0;
|
||
|
if(orth_coords[1] < orth_coords[0])
|
||
|
min = 1;
|
||
|
if(orth_coords[2] < orth_coords[min])
|
||
|
min = 2;
|
||
|
}
|
||
|
|
||
|
template<typename SNC_structure>
|
||
|
static NT compute_evaluation_constant_for_halfedge_pairup(const SNC_structure& snc) {
|
||
|
NT eval = 0;
|
||
|
typename SNC_structure::Vertex_const_iterator v;
|
||
|
CGAL_forall_vertices(v, snc) {
|
||
|
Point_3 p(v->point());
|
||
|
if(p.hx()[0] > eval) eval = p.hx()[0];
|
||
|
if(p.hy()[0] > eval) eval = p.hy()[0];
|
||
|
if(p.hz()[0] > eval) eval = p.hz()[0];
|
||
|
}
|
||
|
eval *= 4;
|
||
|
if(eval == 0) return 1;
|
||
|
return eval;
|
||
|
}
|
||
|
|
||
|
static Point_3 scale_infibox_vertex(const Point_3 pin, const Aff_transformation_3& aff) {
|
||
|
RT lx(pin.hx()[0]);
|
||
|
RT ly(pin.hy()[0]);
|
||
|
RT lz(pin.hz()[0]);
|
||
|
RT hx(pin.hx()-lx);
|
||
|
RT hy(pin.hy()-ly);
|
||
|
RT hz(pin.hz()-lz);
|
||
|
RT hw(pin.hw());
|
||
|
Point_3 p(Point_3(lx,ly,lz,hw).transform(aff));
|
||
|
return Point_3(hx+p.hx(),hy+p.hy(),hz+p.hz(),hw);
|
||
|
}
|
||
|
|
||
|
static Point_3 normalize_transformed_vertex(const Point_3& p) {
|
||
|
int i=0;
|
||
|
if(CGAL_NTS abs(p.hx()) < CGAL_NTS abs(p.hy()))
|
||
|
if(CGAL_NTS abs(p.hy()) < CGAL_NTS abs(p.hz()))
|
||
|
i = 2;
|
||
|
else
|
||
|
i = 1;
|
||
|
else if(CGAL_NTS abs(p.hx()) < CGAL_NTS abs(p.hz()))
|
||
|
i = 2;
|
||
|
|
||
|
switch(i) {
|
||
|
case 0:
|
||
|
CGAL_assertion(p.hx().degree() == 1);
|
||
|
if(p.hx()[1] > 0)
|
||
|
return Point_3(RT(0,p.hx()[1]*p.hw()[0]),
|
||
|
RT(p.hy()[0]*p.hx()[1]-p.hx()[0]*p.hy()(1),p.hy()(1)*p.hw()[0]),
|
||
|
RT(p.hz()[0]*p.hx()[1]-p.hx()[0]*p.hz()(1),p.hz()(1)*p.hw()[0]),
|
||
|
RT(p.hw()[0]*p.hx()[1]));
|
||
|
else
|
||
|
return Point_3(RT(0,-p.hx()[1]*p.hw()[0]),
|
||
|
RT(p.hy()[0]*p.hx()[1]-p.hx()[0]*p.hy()(1),-p.hy()(1)*p.hw()[0]),
|
||
|
RT(p.hz()[0]*p.hx()[1]-p.hx()[0]*p.hz()(1),-p.hz()(1)*p.hw()[0]),
|
||
|
RT(p.hw()[0]*p.hx()[1]));
|
||
|
case 1:
|
||
|
CGAL_assertion(p.hy().degree() == 1);
|
||
|
if(p.hy()[1] > 0)
|
||
|
return Point_3(RT(p.hx()[0]*p.hy()[1]-p.hy()[0]*p.hx()(1),p.hx()(1)*p.hw()[0]),
|
||
|
RT(0,p.hy()[1]*p.hw()[0]),
|
||
|
RT(p.hz()[0]*p.hy()[1]-p.hy()[0]*p.hz()(1),p.hz()(1)*p.hw()[0]),
|
||
|
RT(p.hw()[0]*p.hy()[1]));
|
||
|
else
|
||
|
return Point_3(RT(p.hx()[0]*p.hy()[1]-p.hy()[0]*p.hx()(1),-p.hx()(1)*p.hw()[0]),
|
||
|
RT(0,-p.hy()[1]*p.hw()[0]),
|
||
|
RT(p.hz()[0]*p.hy()[1]-p.hy()[0]*p.hz()(1),-p.hz()(1)*p.hw()[0]),
|
||
|
RT(p.hw()[0]*p.hy()[1]));
|
||
|
case 2:
|
||
|
CGAL_assertion(p.hz().degree() == 1);
|
||
|
if(p.hz()[1] > 0)
|
||
|
return Point_3(RT(p.hx()[0]*p.hz()[1]-p.hz()[0]*p.hx()(1),p.hx()(1)*p.hw()[0]),
|
||
|
RT(p.hy()[0]*p.hz()[1]-p.hz()[0]*p.hy()(1),p.hy()(1)*p.hw()[0]),
|
||
|
RT(0,p.hz()[1]*p.hw()[0]),
|
||
|
RT(p.hw()[0]*p.hz()[1]));
|
||
|
else
|
||
|
return Point_3(RT(p.hx()[0]*p.hz()[1]-p.hz()[0]*p.hx()(1),-p.hx()(1)*p.hw()[0]),
|
||
|
RT(p.hy()[0]*p.hz()[1]-p.hz()[0]*p.hy()(1),-p.hy()(1)*p.hw()[0]),
|
||
|
RT(0,-p.hz()[1]*p.hw()[0]),
|
||
|
RT(p.hw()[0]*p.hz()[1]));
|
||
|
default: CGAL_error_msg( "wrong value");
|
||
|
}
|
||
|
return Point_3();
|
||
|
}
|
||
|
|
||
|
static typename std::list<Point_3>::const_iterator segment_on_side(int side_of_point,
|
||
|
const std::list<Point_3>& segs) {
|
||
|
|
||
|
typename std::list<Point_3>::const_iterator s1,t1;
|
||
|
for(s1 = segs.begin(); s1 != segs.end(); ++s1) {
|
||
|
t1 = s1;
|
||
|
++t1;
|
||
|
if(t1 == segs.end()) t1 = segs.begin();
|
||
|
switch(side_of_point) {
|
||
|
case 1:
|
||
|
if( s1->hx()(1) != s1->hw()) continue;
|
||
|
if( t1->hx()(1) != t1->hw()) continue;
|
||
|
return s1;
|
||
|
case -1:
|
||
|
if(-s1->hx()(1) != s1->hw()) continue;
|
||
|
if(-t1->hx()(1) != t1->hw()) continue;
|
||
|
return s1;
|
||
|
case 2:
|
||
|
if( s1->hy()(1) != s1->hw()) continue;
|
||
|
if( t1->hy()(1) != t1->hw()) continue;
|
||
|
return s1; break;
|
||
|
case -2:
|
||
|
if(-s1->hy()(1) != s1->hw()) continue;
|
||
|
if(-t1->hy()(1) != t1->hw()) continue;
|
||
|
return s1;
|
||
|
case 3:
|
||
|
if( s1->hz()(1) != s1->hw()) continue;
|
||
|
if( t1->hz()(1) != t1->hw()) continue;
|
||
|
return s1;
|
||
|
case -3:
|
||
|
if(-s1->hz()(1) != s1->hw()) continue;
|
||
|
if(-t1->hz()(1) != t1->hw()) continue;
|
||
|
return s1;
|
||
|
default: CGAL_error_msg( "wrong value");
|
||
|
}
|
||
|
}
|
||
|
CGAL_error_msg( "this line of shall not be reached");
|
||
|
return s1;
|
||
|
}
|
||
|
|
||
|
template <typename SNC_constructor>
|
||
|
static void initialize_infibox_vertices(SNC_constructor& C, bool space) {
|
||
|
|
||
|
#ifdef CGAL_NEF_INDEXED_ITEMS
|
||
|
int base = Index_generator::get_unique_index();
|
||
|
for(int i=0; i<11; ++i)
|
||
|
Index_generator::get_unique_index();
|
||
|
#endif
|
||
|
|
||
|
C.create_extended_box_corner( 1, 1, 1, space, true
|
||
|
#ifdef CGAL_NEF_INDEXED_ITEMS
|
||
|
, base
|
||
|
#endif
|
||
|
);
|
||
|
C.create_extended_box_corner(-1, 1, 1, space, true
|
||
|
#ifdef CGAL_NEF_INDEXED_ITEMS
|
||
|
, base
|
||
|
#endif
|
||
|
);
|
||
|
C.create_extended_box_corner( 1,-1, 1, space, true
|
||
|
#ifdef CGAL_NEF_INDEXED_ITEMS
|
||
|
, base
|
||
|
#endif
|
||
|
);
|
||
|
C.create_extended_box_corner(-1,-1, 1, space, true
|
||
|
#ifdef CGAL_NEF_INDEXED_ITEMS
|
||
|
, base
|
||
|
#endif
|
||
|
);
|
||
|
C.create_extended_box_corner( 1, 1,-1, space, true
|
||
|
#ifdef CGAL_NEF_INDEXED_ITEMS
|
||
|
, base
|
||
|
#endif
|
||
|
);
|
||
|
C.create_extended_box_corner(-1, 1,-1, space, true
|
||
|
#ifdef CGAL_NEF_INDEXED_ITEMS
|
||
|
, base
|
||
|
#endif
|
||
|
);
|
||
|
C.create_extended_box_corner( 1,-1,-1, space, true
|
||
|
#ifdef CGAL_NEF_INDEXED_ITEMS
|
||
|
, base
|
||
|
#endif
|
||
|
);
|
||
|
C.create_extended_box_corner(-1,-1,-1, space, true
|
||
|
#ifdef CGAL_NEF_INDEXED_ITEMS
|
||
|
, base
|
||
|
#endif
|
||
|
);
|
||
|
}
|
||
|
|
||
|
template <typename Halfedge_handle>
|
||
|
static bool is_edge_on_infibox(Halfedge_handle e) {
|
||
|
|
||
|
Point_3 p = e->center_vertex()->point();
|
||
|
if(is_standard(p)) return false;
|
||
|
|
||
|
Vector_3 v(e->vector());
|
||
|
CGAL_assertion(p.hw().degree() == 0);
|
||
|
RT Outer(0,CGAL_NTS abs(p.hw()[0]));
|
||
|
|
||
|
// TODO: are these lines really redundant??
|
||
|
if(CGAL_NTS abs(p.hx()) == Outer &&
|
||
|
((p.hx() > 0 && v.hx() > 0)||(p.hx() < 0 && v.hx() < 0))) return false;
|
||
|
if(CGAL_NTS abs(p.hy()) == Outer &&
|
||
|
((p.hy() > 0 && v.hy() > 0)||(p.hy() < 0 && v.hy() < 0))) return false;
|
||
|
if(CGAL_NTS abs(p.hz()) == Outer &&
|
||
|
((p.hz() > 0 && v.hz() > 0)||(p.hz() < 0 && v.hz() < 0))) return false;
|
||
|
|
||
|
if(CGAL_NTS abs(p.hx()) == Outer && v.hx() == 0) return true;
|
||
|
if(CGAL_NTS abs(p.hy()) == Outer && v.hy() == 0) return true;
|
||
|
if(CGAL_NTS abs(p.hz()) == Outer && v.hz() == 0) return true;
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
|
||
|
template <typename SHalfedge_handle>
|
||
|
static bool is_sedge_on_infibox(SHalfedge_handle sh) {
|
||
|
|
||
|
Point_3 p = sh->source()->center_vertex()->point();
|
||
|
CGAL_NEF_TRACEN("Point " << p);
|
||
|
if(is_standard(p)) return false;
|
||
|
|
||
|
CGAL_NEF_TRACEN("Circle " << sh->circle() <<
|
||
|
" has signum " << sign_of(sh->circle()));
|
||
|
CGAL_assertion(p.hw().degree() == 0);
|
||
|
RT R(0,CGAL_NTS abs(p.hw()[0]));
|
||
|
|
||
|
if((sh->circle().a() == 0 && sh->circle().b() == 0
|
||
|
&& CGAL_NTS abs(p.hz())== R) ||
|
||
|
(sh->circle().a() == 0 && sh->circle().c() == 0
|
||
|
&& CGAL_NTS abs(p.hy())== R) ||
|
||
|
(sh->circle().b() == 0 && sh->circle().c() == 0
|
||
|
&& CGAL_NTS abs(p.hx())== R))
|
||
|
if(is_edge_on_infibox(sh->source()) &&
|
||
|
is_edge_on_infibox(sh->twin()->source()))
|
||
|
return true;
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
template <typename Sphere_map>
|
||
|
static bool is_redundant_box_vertex(const Sphere_map& sm) {
|
||
|
if(is_standard(sm.point())) return false;
|
||
|
if(is_infibox_corner(sm.point())) return false;
|
||
|
typename Sphere_map::SVertex_const_iterator svi;
|
||
|
for(svi = sm.svertices_begin();
|
||
|
svi != sm.svertices_end(); ++svi)
|
||
|
if(!is_edge_on_infibox(svi)) {
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
template <typename Sphere_map>
|
||
|
static bool is_complex_facet_infibox_intersection(const Sphere_map& sm) {
|
||
|
|
||
|
typename Sphere_map::SHalfedge_const_iterator sei;
|
||
|
bool found = false;
|
||
|
CGAL_forall_sedges(sei, sm) {
|
||
|
if(!is_sedge_on_infibox(sei)) {
|
||
|
if(found)
|
||
|
return true;
|
||
|
else
|
||
|
found = true;
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
template <typename SNC_constructor>
|
||
|
static std::list<Point_3> find_points_of_box_with_plane(SNC_constructor& C, const Plane_3& h) {
|
||
|
return C.find_points_of_box_with_plane(h);
|
||
|
}
|
||
|
|
||
|
template <typename Halfedge_handle>
|
||
|
static bool is_type4(Halfedge_handle e) {
|
||
|
|
||
|
Point_3 p(e->center_vertex()->point());
|
||
|
Direction_3 d(e->vector());
|
||
|
|
||
|
if((CGAL_NTS abs(p.hx()) == CGAL_NTS abs(p.hw()) ||
|
||
|
d == Direction_3(1,0,0) ||
|
||
|
d == Direction_3(-1,0,0)) &&
|
||
|
(CGAL_NTS abs(p.hy()) == CGAL_NTS abs(p.hw()) ||
|
||
|
d == Direction_3(0,1,0) ||
|
||
|
d == Direction_3(0,-1,0)) &&
|
||
|
(CGAL_NTS abs(p.hz()) == CGAL_NTS abs(p.hw()) ||
|
||
|
d == Direction_3(0,0,1) ||
|
||
|
d == Direction_3(0,0,-1)))
|
||
|
return true;
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
template <typename Halfedge_handle>
|
||
|
static bool is_type3(Halfedge_handle e) {
|
||
|
|
||
|
Point_3 p(e->center_vertex()->point());
|
||
|
Direction_3 d(e->vector());
|
||
|
|
||
|
if(d == Direction_3(1,0,0) || d == Direction_3(-1,0,0)) {
|
||
|
if(CGAL_NTS abs(p.hy()) == CGAL_NTS abs(p.hw()))
|
||
|
return true;
|
||
|
return false;
|
||
|
}
|
||
|
if(d == Direction_3(0,1,0) || d == Direction_3(0,-1,0)) {
|
||
|
if(CGAL_NTS abs(p.hx()) == CGAL_NTS abs(p.hw()))
|
||
|
return true;
|
||
|
return false;
|
||
|
}
|
||
|
if(d == Direction_3(0,0,1) || d == Direction_3(0,0,-1)) {
|
||
|
if(CGAL_NTS abs(p.hy()) == CGAL_NTS abs(p.hw()))
|
||
|
return true;
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
};
|
||
|
*/
|
||
|
|
||
|
} //namespace CGAL
|
||
|
#endif // CGAL_INFIMAXIMAL_BOX_H
|