mirror of https://github.com/CGAL/cgal
2158 lines
73 KiB
C++
2158 lines
73 KiB
C++
// Copyright (c) 1997-2002 Max-Planck-Institute Saarbruecken (Germany).
|
|
// All rights reserved.
|
|
//
|
|
// This file is part of CGAL (www.cgal.org).
|
|
//
|
|
// $URL$
|
|
// $Id$
|
|
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
|
//
|
|
//
|
|
// Author(s) : Michael Seel <seel@mpi-sb.mpg.de>
|
|
// Miguel Granados <granados@mpi-sb.mpg.de>
|
|
// Susan Hert <hert@mpi-sb.mpg.de>
|
|
// Lutz Kettner <kettner@mpi-sb.mpg.de>
|
|
// Peter Hachenberger <hachenberger@mpi-sb.mpg.de>
|
|
#ifndef CGAL_SNC_CONSTRUCTOR_H
|
|
#define CGAL_SNC_CONSTRUCTOR_H
|
|
|
|
#include <CGAL/license/Nef_3.h>
|
|
|
|
|
|
#include <CGAL/function_objects.h>
|
|
#include <CGAL/Circulator_project.h>
|
|
#include <CGAL/Nef_S2/Normalizing.h>
|
|
#include <CGAL/Nef_3/bounded_side_3.h>
|
|
#include <CGAL/Nef_3/Pluecker_line_3.h>
|
|
#include <CGAL/Nef_3/SNC_const_decorator.h>
|
|
#include <CGAL/Nef_3/SNC_SM_overlayer.h>
|
|
#include <CGAL/Nef_S2/SM_point_locator.h>
|
|
#include <CGAL/Nef_3/SNC_halfedge_key.h>
|
|
#include <CGAL/Nef_3/SNC_sphere_map.h>
|
|
#include <CGAL/Nef_3/SNC_structure.h>
|
|
#include <CGAL/Nef_3/SNC_intersection.h>
|
|
#ifdef SM_VISUALIZOR
|
|
#include <CGAL/Nef_3/SNC_SM_visualizor.h>
|
|
#endif // SM_VISUALIZOR
|
|
#include <map>
|
|
#include <list>
|
|
#undef CGAL_NEF_DEBUG
|
|
#define CGAL_NEF_DEBUG 43
|
|
#include <CGAL/Nef_2/debug.h>
|
|
|
|
namespace CGAL {
|
|
|
|
template <typename Infi_box, typename Vertex_handle>
|
|
struct Frame_point_lt {
|
|
|
|
Frame_point_lt() {}
|
|
bool operator()(Vertex_handle v1, Vertex_handle v2) const {
|
|
if(v1->point() != v2->point())
|
|
return CGAL::lexicographically_xyz_smaller(v1->point(),v2->point());
|
|
if(!Infi_box::is_complex_facet_infibox_intersection(*v1) &&
|
|
Infi_box::is_complex_facet_infibox_intersection(*v2))
|
|
return true;
|
|
return false;
|
|
}
|
|
};
|
|
|
|
template <typename T>
|
|
struct circle_lt {
|
|
|
|
int m_max;
|
|
typedef typename T::Point_3 Point_3;
|
|
typedef typename T::RT RT;
|
|
|
|
circle_lt(int m) :m_max(m) {};
|
|
bool operator()(const Point_3& p1, const Point_3& p2) const {
|
|
|
|
const Quotient<RT> zero(RT(0));
|
|
Quotient<RT> x[2];
|
|
Quotient<RT> y[2];
|
|
|
|
switch(m_max) {
|
|
case 0:
|
|
x[0] = p1.y();
|
|
y[0] = p1.z();
|
|
x[1] = p2.y();
|
|
y[1] = p2.z();
|
|
break;
|
|
case 1:
|
|
x[0] = p1.x();
|
|
y[0] = p1.z();
|
|
x[1] = p2.x();
|
|
y[1] = p2.z();
|
|
break;
|
|
case 2:
|
|
x[0] = p1.x();
|
|
y[0] = p1.y();
|
|
x[1] = p2.x();
|
|
y[1] = p2.y();
|
|
break;
|
|
}
|
|
|
|
if(y[0] >= zero) {
|
|
if(y[1] < zero) return false;
|
|
if(x[0] != x[1]) return (x[0]<x[1]);
|
|
if(x[0] > zero) return (y[0]>y[1]);
|
|
else return (y[0]<y[1]);
|
|
}
|
|
else {
|
|
if(y[1] >= zero) return true;
|
|
if(x[0]!=x[1]) return(x[0]>x[1]);
|
|
if(x[0] > zero) return (y[0]>y[1]);
|
|
else return (y[0]<y[1]);
|
|
}
|
|
CGAL_error_msg( "control should not reach this line");
|
|
return false;
|
|
}
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// SNC_constructor
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/*{\Manpage{SNC_constructor}{SNC}{overlay functionality}{O}}*/
|
|
|
|
template <typename Items, typename SNC_structure_>
|
|
class SNC_constructor_base : public SNC_decorator<SNC_structure_>
|
|
{
|
|
public:
|
|
typedef SNC_structure_ SNC_structure;
|
|
typedef typename SNC_structure::Infi_box Infi_box;
|
|
typedef typename SNC_structure_::Sphere_kernel Sphere_kernel;
|
|
typedef typename Infi_box::Standard_kernel Standard_kernel;
|
|
typedef typename Standard_kernel::Point_3 Standard_point_3;
|
|
typedef typename SNC_structure_::Kernel Kernel;
|
|
typedef typename Kernel::RT RT;
|
|
typedef typename Infi_box::NT NT;
|
|
typedef CGAL::SNC_constructor_base<Items, SNC_structure> Self;
|
|
typedef CGAL::SNC_decorator<SNC_structure> SNC_decorator;
|
|
typedef typename CGAL::SNC_const_decorator<SNC_structure> SNC_const_decorator;
|
|
typedef CGAL::SNC_intersection<SNC_structure> SNC_intersection;
|
|
|
|
typedef typename SNC_structure::Sphere_map Sphere_map;
|
|
typedef CGAL::SM_decorator<Sphere_map> SM_decorator;
|
|
typedef CGAL::SNC_SM_overlayer<Items, SM_decorator> SM_overlayer;
|
|
typedef CGAL::SM_const_decorator<Sphere_map> SM_const_decorator;
|
|
typedef CGAL::SM_point_locator<SM_decorator> SM_point_locator;
|
|
|
|
typedef typename SNC_structure::Vertex_iterator Vertex_iterator;
|
|
typedef typename SNC_structure::Halfedge_iterator Halfedge_iterator;
|
|
typedef typename SNC_structure::Halffacet_iterator Halffacet_iterator;
|
|
|
|
typedef typename SNC_structure::Vertex_handle Vertex_handle;
|
|
typedef typename SNC_structure::Halfedge_handle Halfedge_handle;
|
|
typedef typename SNC_structure::Halffacet_handle Halffacet_handle;
|
|
typedef typename SNC_structure::Volume_handle Volume_handle;
|
|
|
|
typedef typename SNC_structure::Vertex_const_handle Vertex_const_handle;
|
|
typedef typename SNC_structure::Halfedge_const_handle Halfedge_const_handle;
|
|
typedef typename SNC_structure::Halffacet_const_handle Halffacet_const_handle;
|
|
typedef typename SNC_structure::Halffacet_const_iterator Halffacet_const_iterator;
|
|
|
|
typedef typename SNC_structure::SVertex_iterator SVertex_iterator;
|
|
typedef typename SNC_structure::SHalfedge_iterator SHalfedge_iterator;
|
|
typedef typename SNC_structure::SFace_iterator SFace_iterator;
|
|
typedef typename SNC_structure::SHalfloop_iterator SHalfloop_iterator;
|
|
|
|
typedef typename SNC_structure::SVertex_handle SVertex_handle;
|
|
typedef typename SNC_structure::SHalfedge_handle SHalfedge_handle;
|
|
typedef typename SNC_structure::SFace_handle SFace_handle;
|
|
typedef typename SNC_structure::SHalfloop_handle SHalfloop_handle;
|
|
|
|
typedef typename SNC_structure::SVertex_const_handle SVertex_const_handle;
|
|
typedef typename SNC_structure::SHalfedge_const_handle SHalfedge_const_handle;
|
|
typedef typename SNC_structure::SHalfloop_const_handle SHalfloop_const_handle;
|
|
typedef typename SNC_structure::SFace_const_handle SFace_const_handle;
|
|
|
|
typedef typename SNC_structure::SHalfedge_around_facet_circulator
|
|
SHalfedge_around_facet_circulator;
|
|
typedef typename SNC_structure::SHalfedge_around_facet_const_circulator
|
|
SHalfedge_around_facet_const_circulator;
|
|
typedef typename SNC_structure::SFace_cycle_iterator SFace_cycle_iterator;
|
|
typedef typename SNC_structure::SFace_cycle_const_iterator SFace_cycle_const_iterator;
|
|
typedef typename SNC_structure::Halffacet_cycle_iterator Halffacet_cycle_iterator;
|
|
typedef typename SNC_structure::Halffacet_cycle_const_iterator Halffacet_cycle_const_iterator;
|
|
|
|
typedef typename SNC_structure::Point_3 Point_3;
|
|
typedef typename SNC_structure::Vector_3 Vector_3;
|
|
typedef typename SNC_structure::Segment_3 Segment_3;
|
|
typedef typename SNC_structure::Plane_3 Plane_3;
|
|
typedef typename SNC_structure::Aff_transformation_3 Aff_transformation_3;
|
|
|
|
typedef typename SNC_structure::Sphere_point Sphere_point;
|
|
typedef typename SNC_structure::Sphere_segment Sphere_segment;
|
|
typedef typename SNC_structure::Sphere_circle Sphere_circle;
|
|
|
|
typedef typename SNC_structure::Mark Mark;
|
|
|
|
typedef typename SM_decorator::SHalfedge_around_svertex_circulator
|
|
SHalfedge_around_svertex_circulator;
|
|
typedef typename SM_decorator::SHalfedge_around_sface_circulator
|
|
SHalfedge_around_sface_circulator;
|
|
typedef typename SM_const_decorator::SHalfedge_around_svertex_const_circulator
|
|
SHalfedge_around_svertex_const_circulator;
|
|
|
|
using SNC_decorator::is_standard;
|
|
|
|
enum{NORMAL, CORNER, DEGENERATE};
|
|
|
|
SNC_constructor_base( SNC_structure& W) : SNC_decorator(W) {}
|
|
/*{\Mcreate makes |\Mvar| a decorator of |W|.}*/
|
|
|
|
private:
|
|
int compute_index(NT a, NT b) const {
|
|
int i = 0;
|
|
if(a > 0) ++i;
|
|
if(b > 0) i+=2;
|
|
return i;
|
|
}
|
|
|
|
public:
|
|
|
|
Vertex_handle
|
|
create_extended_box_corner(NT x, NT y, NT z,
|
|
bool space,
|
|
bool boundary
|
|
#ifdef CGAL_NEF_INDEXED_ITEMS
|
|
, int base
|
|
#endif
|
|
) const {
|
|
|
|
CGAL_assertion(CGAL_NTS abs(x) == CGAL_NTS abs(y) &&
|
|
CGAL_NTS abs(y) == CGAL_NTS abs(z));
|
|
|
|
CGAL_assertion(boundary == true);
|
|
|
|
CGAL_NEF_TRACEN(" constructing box corner on "<<Point_3(x,y,z)<<"...");
|
|
Point_3 p = Infi_box::create_extended_point(x,y,z);
|
|
Vertex_handle v = this->sncp()->new_vertex(p , boundary);
|
|
CGAL_NEF_TRACEN( v->point());
|
|
SM_decorator SD(&*v);
|
|
const NT zero(0);
|
|
Sphere_point sp[] = { Sphere_point(NT(-x), zero, zero),
|
|
Sphere_point(zero, NT(-y), zero),
|
|
Sphere_point(zero, zero, NT(-z)) };
|
|
|
|
/* create box vertices */
|
|
SVertex_handle sv[3];
|
|
for(int vi=0; vi<3; ++vi) {
|
|
sv[vi] = SD.new_svertex(sp[vi]);
|
|
sv[vi]->mark() = boundary;
|
|
}
|
|
|
|
#ifdef CGAL_NEF_INDEXED_ITEMS
|
|
sv[0]->set_index(base+compute_index(y,z));
|
|
sv[1]->set_index(base+4+compute_index(x,z));
|
|
sv[2]->set_index(base+8+compute_index(x,y));
|
|
#endif
|
|
|
|
/* create facet's edge uses */
|
|
// Sphere_segment ss[3];
|
|
SHalfedge_handle she[3];
|
|
for(int si=0; si<3; ++si)
|
|
she[si] = SD.new_shalfedge_pair(sv[si], sv[(si+1)%3]);
|
|
|
|
for(int i=0; i<3;++i) {
|
|
she[i]->circle() =
|
|
Sphere_circle(Plane_3(sp[i],sp[(i+1)%3],Point_3(0,0,0)));
|
|
she[i]->twin()->circle() = she[i]->circle().opposite();
|
|
she[i]->mark() = she[i]->twin()->mark() = boundary;
|
|
}
|
|
|
|
#ifdef CGAL_NEF_INDEXED_ITEMS
|
|
int bit = she[0]->circle().c()>0?0:1;
|
|
int idx = base + (z>0?0:2);
|
|
she[0]->set_index(idx+bit);
|
|
she[0]->twin()->set_index(idx+1-bit);
|
|
bit = she[1]->circle().a()>0?0:1;
|
|
idx = base + 4 + (x>0?0:2);
|
|
she[1]->set_index(idx+bit);
|
|
she[1]->twin()->set_index(idx+1-bit);
|
|
bit = she[2]->circle().b()>0?0:1;
|
|
idx = base + 8 + (y>0?0:2);
|
|
she[2]->set_index(idx+bit);
|
|
she[2]->twin()->set_index(idx+1-bit);
|
|
#endif
|
|
|
|
/* create facets */
|
|
SFace_handle fi = SD.new_sface();
|
|
SFace_handle fe = SD.new_sface();
|
|
SD.link_as_face_cycle(she[0], fi);
|
|
SD.link_as_face_cycle(she[0]->twin(), fe);
|
|
|
|
Sphere_point p1 = she[0]->source()->point();
|
|
Sphere_point p2 = she[0]->twin()->source()->point();
|
|
Sphere_point p3 = she[0]->snext()->twin()->source()->point();
|
|
if ( spherical_orientation(p1,p2,p3) > 0 ) {
|
|
fi->mark() = space;
|
|
fe->mark() = 0;
|
|
}
|
|
else {
|
|
fi->mark() = 0;
|
|
fe->mark() = space;
|
|
}
|
|
|
|
return v;
|
|
}
|
|
|
|
/*{\Mop produces the sphere map representing thp,e box corner in
|
|
direction $(x,y,z)$.}*/
|
|
|
|
template<typename Forward_iterator>
|
|
SHalfedge_handle add_outer_sedge_cycle(Vertex_handle v,
|
|
Forward_iterator start,
|
|
Forward_iterator end,
|
|
bool orient) {
|
|
|
|
CGAL_assertion(start!=end);
|
|
|
|
v->mark() = true;
|
|
SM_decorator SD(&*v);
|
|
|
|
Forward_iterator si;
|
|
for(si=start; si!=end; ++si)
|
|
SD.new_svertex(*si);
|
|
|
|
SHalfedge_handle se,se_prev;
|
|
std::list<SHalfedge_handle> se_list;
|
|
SVertex_iterator sv(SD.svertices_begin()), sv_next(sv);
|
|
for(;sv!=SD.svertices_end();++sv) {
|
|
++sv_next;
|
|
sv->mark()=true;
|
|
if(sv_next==SD.svertices_end()) sv_next=SD.svertices_begin();
|
|
se=SD.new_shalfedge_pair(sv,sv_next);
|
|
se_list.push_back(se);
|
|
se->mark() = se->twin()->mark() = true;
|
|
if(sv!=SD.svertices_begin()) {
|
|
se->sprev() = se_prev;
|
|
se_prev->snext() = se;
|
|
se->twin()->snext() = se_prev->twin();
|
|
se_prev->twin()->sprev() = se->twin();
|
|
}
|
|
se_prev = se;
|
|
}
|
|
|
|
se=*se_list.begin();
|
|
se->sprev() = se_prev;
|
|
se_prev->snext() = se;
|
|
se->twin()->snext() = se_prev->twin();
|
|
se_prev->twin()->sprev() = se->twin();
|
|
|
|
typename std::list<SHalfedge_handle>::iterator seli;
|
|
for(seli=se_list.begin();seli!=se_list.end();++seli) {
|
|
se = *seli;
|
|
se->circle() = Sphere_circle(se->source()->point(), se->snext()->source()->point());
|
|
if(orient && seli==se_list.begin())
|
|
se->circle() = Sphere_circle(se->snext()->source()->point(), se->source()->point());
|
|
se->circle() = normalized(se->circle());
|
|
se->twin()->circle() = se->circle().opposite();
|
|
}
|
|
|
|
SFace_handle sfa = SD.new_sface();
|
|
SFace_handle sfi = SD.new_sface();
|
|
|
|
sfi->mark()=true;
|
|
sfa->mark()=false;
|
|
|
|
se=*se_list.begin();
|
|
SD.link_as_face_cycle(se,sfi);
|
|
SD.link_as_face_cycle(se->twin(),sfa);
|
|
|
|
return se;
|
|
}
|
|
|
|
template<typename Forward_iterator>
|
|
SHalfedge_handle add_inner_sedge_cycle(Vertex_handle v,
|
|
Forward_iterator start,
|
|
Forward_iterator end,
|
|
bool orient, bool camera) {
|
|
CGAL_assertion(start!=end);
|
|
|
|
v->mark() = true;
|
|
SM_decorator SD(&*v);
|
|
|
|
Forward_iterator si;
|
|
std::list<SVertex_handle> sv_list;
|
|
for(si=start; si!=end; ++si)
|
|
sv_list.push_back(SD.new_svertex(*si));
|
|
|
|
SHalfedge_handle se, se_prev;
|
|
typename std::list<SVertex_handle>::iterator
|
|
sv(sv_list.begin()), sv_next(sv);
|
|
std::list<SHalfedge_handle> se_list;
|
|
|
|
for(;sv!=sv_list.end();++sv) {
|
|
++sv_next;
|
|
(*sv)->mark()=true;
|
|
if(sv_next==sv_list.end()) sv_next=sv_list.begin();
|
|
se=SD.new_shalfedge_pair(*sv,*sv_next);
|
|
se_list.push_back(se);
|
|
se->mark() = se->twin()->mark() = true;
|
|
if(sv!=sv_list.begin()) {
|
|
se->prev() = se_prev;
|
|
se_prev->next() = se;
|
|
se->twin()->next() = se_prev->twin();
|
|
se_prev->twin()->prev() = se->twin();
|
|
}
|
|
se_prev = se;
|
|
}
|
|
|
|
se=*se_list.begin();
|
|
se->prev() = se_prev;
|
|
se_prev->next() = se;
|
|
se->twin()->next() = se_prev->twin();
|
|
se_prev->twin()->prev() = se->twin();
|
|
|
|
typename std::list<SHalfedge_handle>::iterator seli;
|
|
for(seli=se_list.begin();seli!=se_list.end();++seli) {
|
|
se = *seli;
|
|
se->circle() = Sphere_circle(se->source()->point(), se->snext()->source()->point());
|
|
if(orient && seli==se_list.begin())
|
|
se->circle() = Sphere_circle(se->snext()->source()->point(), se->source()->point());
|
|
se->circle() = normalized(se->circle());
|
|
se->twin()->circle() = se->circle().opposite();
|
|
}
|
|
|
|
SFace_handle sfa,sfi;
|
|
if(camera) {
|
|
sfa = ++SD.sfaces_begin();
|
|
sfi = SD.new_sface();
|
|
sfi->mark()=false;
|
|
} else {
|
|
sfa = SD.new_sface();
|
|
sfi = SD.new_sface();
|
|
sfa->mark()=true;
|
|
sfi->mark()=false;
|
|
}
|
|
|
|
se=*se_list.begin();
|
|
SD.link_as_face_cycle(se,sfi);
|
|
SD.link_as_face_cycle(se->twin(),sfa);
|
|
|
|
return se;
|
|
}
|
|
|
|
Vertex_handle create_for_infibox_overlay(Vertex_const_handle vin) const {
|
|
|
|
Unique_hash_map<SHalfedge_handle, Mark> mark_of_right_sface;
|
|
|
|
Vertex_handle v = this->sncp()->new_vertex(vin->point(), vin->mark());
|
|
SM_decorator D(&*v);
|
|
SM_const_decorator E(&*vin);
|
|
|
|
SVertex_const_handle e;
|
|
CGAL_forall_svertices(e, E)
|
|
if(!Infi_box::is_edge_on_infibox(e))
|
|
break;
|
|
|
|
Sphere_point ps = e->point();
|
|
ps = normalized(ps);
|
|
SVertex_handle v1 = D.new_svertex(ps);
|
|
SVertex_handle v2 = D.new_svertex(ps.antipode());
|
|
CGAL_NEF_TRACEN("new svertex 1 " << ps);
|
|
CGAL_NEF_TRACEN("new svertex 2 " << ps.antipode());
|
|
v1->mark() = v2->mark() = e->mark();
|
|
CGAL_NEF_TRACEN("svertex 1 " << ps << " has mark " << v1->mark());
|
|
CGAL_NEF_TRACEN("svertex 2 " << ps.antipode() << " has mark " << v2->mark());
|
|
|
|
if(E.is_isolated(e)) {
|
|
CGAL_NEF_TRACEN("edge is isolated");
|
|
SFace_handle f = D.new_sface();
|
|
f->mark() = e->incident_sface()->mark();
|
|
D.link_as_isolated_vertex(v1, f);
|
|
D.link_as_isolated_vertex(v2, f);
|
|
}
|
|
else {
|
|
CGAL_NEF_TRACEN("edge is not isolated");
|
|
SHalfedge_handle se;
|
|
SFace_handle sf;
|
|
|
|
SHalfedge_around_svertex_const_circulator ec(E.out_edges(e)), ee(ec);
|
|
CGAL_For_all(ec,ee) {
|
|
Sphere_segment seg(ec->source()->point(),
|
|
ec->source()->point().antipode(),
|
|
ec->circle());
|
|
se = D.new_shalfedge_pair(v1, v2);
|
|
se->mark() = se->twin()->mark() = ec->mark();
|
|
mark_of_right_sface[se] = ec->incident_sface()->mark();
|
|
se->circle() = ec->circle();
|
|
se->twin()->circle() = se->circle().opposite();
|
|
}
|
|
|
|
SHalfedge_around_svertex_circulator ec2(D.out_edges(v1)), ee2(ec2);
|
|
CGAL_For_all(ec2,ee2) {
|
|
sf = D.new_sface();
|
|
sf->mark() = mark_of_right_sface[ec2];
|
|
D.link_as_face_cycle(SHalfedge_handle(ec2),sf);
|
|
}
|
|
}
|
|
|
|
return v;
|
|
}
|
|
|
|
Vertex_handle create_from_plane(const Plane_3& pl, const Point_3& p,
|
|
const Mark& bnd,
|
|
const Mark& in, const Mark& out) const {
|
|
Vertex_handle v = this->sncp()->new_vertex( p, bnd);
|
|
v->point() = p;
|
|
Sphere_circle c(pl); // circle through origin parallel to h
|
|
SM_decorator D(&*v);
|
|
SHalfloop_handle l = D.new_shalfloop_pair();
|
|
SFace_handle f1 = D.new_sface(), f2 = D.new_sface();
|
|
D.link_as_loop(l,f1);
|
|
D.link_as_loop(l->twin(),f2);
|
|
|
|
l->circle() = c;
|
|
l->twin()->circle() = c.opposite();
|
|
f1->mark() = out;
|
|
f2->mark() = in;
|
|
l->mark() = l->twin()->mark() = bnd;
|
|
return v;
|
|
}
|
|
|
|
Vertex_handle create_from_point_on_infibox_facet(const Point_3& p) const {
|
|
|
|
CGAL_assertion(!Infi_box::is_standard(p));
|
|
if(Infi_box::x_on_box(p)) {
|
|
if(p.hx() > 0)
|
|
return create_from_plane(Plane_3(1,0,0,1), p, 1, 1, 0);
|
|
else
|
|
return create_from_plane(Plane_3(-1,0,0,1), p, 1, 1, 0);
|
|
}
|
|
if(Infi_box::y_on_box(p)) {
|
|
if(p.hy() > 0)
|
|
return create_from_plane(Plane_3(0,1,0,1), p, 1, 1, 0);
|
|
else
|
|
return create_from_plane(Plane_3(0,-1,0,1), p, 1, 1, 0);
|
|
}
|
|
if(Infi_box::z_on_box(p)) {
|
|
if(p.hz() > 0)
|
|
return create_from_plane(Plane_3(0,0,1,1), p, 1, 1, 0);
|
|
else
|
|
return create_from_plane(Plane_3(0,0,-1,1), p, 1, 1, 0);
|
|
}
|
|
CGAL_error_msg( "something is wrong");
|
|
return Vertex_handle();
|
|
}
|
|
|
|
Vertex_handle create_from_point_on_infibox_edge(const Point_3& p) const {
|
|
|
|
Sphere_point sp;
|
|
Sphere_circle c1,c2;
|
|
|
|
if(!Infi_box::x_on_box(p)) {
|
|
sp = Sphere_point(1,0,0);
|
|
c1 = (p.hy() < RT(0)) ? Sphere_circle(0,-1,0) : Sphere_circle(0,1,0);
|
|
c2 = (p.hz() < RT(0)) ? Sphere_circle(0,0,-1) : Sphere_circle(0,0,1);
|
|
} else if(!Infi_box::y_on_box(p)) {
|
|
sp = Sphere_point(0,1,0);
|
|
c1 = (p.hx() < RT(0)) ? Sphere_circle(-1,0,0) : Sphere_circle(1,0,0);
|
|
c2 = (p.hz() < RT(0)) ? Sphere_circle(0,0,-1) : Sphere_circle(0,0,1);
|
|
} else if(!Infi_box::z_on_box(p)) {
|
|
sp = Sphere_point(0,0,1);
|
|
c1 = (p.hx() < RT(0)) ? Sphere_circle(-1,0,0) : Sphere_circle(1,0,0);
|
|
c2 = (p.hy() < RT(0)) ? Sphere_circle(0,-1,0) : Sphere_circle(0,1,0);
|
|
} else
|
|
CGAL_error_msg( "line of code shall not be reached");
|
|
|
|
Vertex_handle v = this->sncp()->new_vertex( p, true);
|
|
SM_decorator D(&*v);
|
|
SVertex_handle v1 = D.new_svertex(sp);
|
|
SVertex_handle v2 = D.new_svertex(sp.antipode());
|
|
SHalfedge_handle e1 = D.new_shalfedge_pair(v1,v2);
|
|
SHalfedge_handle e2 = D.new_shalfedge_pair(v1,v2);
|
|
SFace_handle f1 = D.new_sface();
|
|
SFace_handle f2 = D.new_sface();
|
|
v1->mark() = v2->mark() =
|
|
e1->mark() = e1->twin()->mark() =
|
|
e2->mark() = e2->twin()->mark() = true;
|
|
f1->mark() = false;
|
|
f2->mark() = true;
|
|
D.link_as_face_cycle(e1,f1);
|
|
D.link_as_face_cycle(e2,f2);
|
|
e1->circle() = c1;
|
|
e1->twin()->circle() = c1.opposite();
|
|
e1->snext()->circle() = c2;
|
|
e1->snext()->twin()->circle() = c2.opposite();
|
|
|
|
return v;
|
|
}
|
|
|
|
Vertex_handle create_from_point_on_infibox_vertex(const Point_3& p) const {
|
|
|
|
typedef typename Infi_box::Standard_point Standard_point;
|
|
Standard_point ps(Infi_box::standard_point(p,1));
|
|
return create_extended_box_corner(ps.hx(),
|
|
ps.hy(),
|
|
ps.hz(),true,true);
|
|
}
|
|
|
|
Vertex_handle create_from_facet(Halffacet_const_handle f,
|
|
const Point_3& p) {
|
|
return create_from_plane(f->plane(), p,
|
|
f->mark(),
|
|
f->twin()->incident_volume()->mark(),
|
|
f->incident_volume()->mark());
|
|
}
|
|
|
|
/*{\Mop produces the sphere map at point $p$ representing the local
|
|
view of $f$. \precond $p$ is part of $f$.}*/
|
|
|
|
Vertex_handle create_from_edge(Halfedge_const_handle e,
|
|
const Point_3& p) {
|
|
// typedef typename CGAL::SNC_const_decorator<SNC_structure> SNC_const_decorator;
|
|
|
|
// CGAL_assertion(SNC_const_decorator::segment(e).has_on(p));
|
|
Vertex_handle v = this->sncp()->new_vertex( p, e->mark());
|
|
SM_decorator D(&*v);
|
|
SM_const_decorator E(&*e->source());
|
|
Sphere_point ps = e->point();
|
|
SVertex_handle v1 = D.new_svertex(ps);
|
|
SVertex_handle v2 = D.new_svertex(ps.antipode());
|
|
v1->mark() = v2->mark() = e->mark();
|
|
|
|
bool first = true;
|
|
|
|
// CGAL_NEF_SETDTHREAD(19*43*131);
|
|
|
|
SHalfedge_const_handle ceee;
|
|
CGAL_NEF_TRACEN("---------------------" << e->center_vertex()->point());
|
|
CGAL_forall_shalfedges(ceee,E)
|
|
CGAL_NEF_TRACEN("|" << ceee->circle() <<
|
|
"|" << ceee->mark() <<
|
|
" " << ceee->incident_sface()->mark());
|
|
CGAL_NEF_TRACEN(" ");
|
|
|
|
if(E.is_isolated(e)) {
|
|
SFace_handle f = D.new_sface();
|
|
D.link_as_isolated_vertex(v1,f);
|
|
D.link_as_isolated_vertex(v2,f);
|
|
f->mark() = e->incident_sface()->mark();
|
|
}
|
|
|
|
SHalfedge_around_svertex_const_circulator
|
|
ec1(e->out_sedge()), ee(ec1);
|
|
SHalfedge_handle e1,e2;
|
|
CGAL_For_all(ec1,ee) {
|
|
if (first) e1 = D.new_shalfedge_pair(v1,v2);
|
|
else e1 = D.new_shalfedge_pair(e1, e2, SM_decorator::AFTER,
|
|
SM_decorator::BEFORE);
|
|
e2 = e1->twin();
|
|
first = false;
|
|
}
|
|
|
|
SHalfedge_handle eee;
|
|
CGAL_forall_shalfedges(eee,D)
|
|
CGAL_NEF_TRACEN("|" << eee->circle());
|
|
CGAL_NEF_TRACEN(" ");
|
|
|
|
ec1 = e->out_sedge();
|
|
SHalfedge_around_svertex_circulator ec2(v1->out_sedge());
|
|
CGAL_For_all(ec1,ee) {
|
|
CGAL_NEF_TRACEN("|" << ec1->circle() <<
|
|
"|" << ec1->mark() <<
|
|
" " << ec1->incident_sface()->mark());
|
|
ec2->mark() = ec2->twin()->mark() = ec1->mark();
|
|
ec2->circle() = ec1->circle();
|
|
ec2->twin()->circle() = ec1->twin()->circle();
|
|
SFace_handle f = D.new_sface();
|
|
D.link_as_face_cycle(ec2,f);
|
|
f->mark() = ec1->incident_sface()->mark();
|
|
++ec2;
|
|
}
|
|
|
|
CGAL_NEF_TRACEN(" ");
|
|
CGAL_NEF_TRACEN("new vertex ");
|
|
|
|
CGAL_forall_svertices(v1, D) {
|
|
CGAL_NEF_TRACE("|" << v1->point() << "|" << v1->mark());
|
|
CGAL_NEF_TRACEN(" ");
|
|
}
|
|
CGAL_NEF_TRACEN(" ");
|
|
|
|
CGAL_forall_shalfedges(eee,D)
|
|
CGAL_NEF_TRACEN("|" << eee->circle() <<
|
|
"|" << eee->mark() <<
|
|
" " << eee->incident_sface()->mark());
|
|
CGAL_NEF_TRACEN("---------------------");
|
|
|
|
return v;
|
|
}
|
|
|
|
/*{\Mop produces the sphere map at point $p$ representing the local
|
|
view of $e$. \precond $p$ is part of $e$.}*/
|
|
|
|
Vertex_handle clone_SM( Vertex_const_handle vin) {
|
|
|
|
#ifdef CGAL_NEF3_TIMER_SPHERE_SWEEPS
|
|
++number_of_clones;
|
|
#endif
|
|
|
|
CGAL::Unique_hash_map<SVertex_const_handle, SVertex_handle> VM;
|
|
CGAL::Unique_hash_map<SHalfedge_const_handle, SHalfedge_handle> EM;
|
|
CGAL::Unique_hash_map<SHalfloop_const_handle, SHalfloop_handle> LM;
|
|
CGAL::Unique_hash_map<SFace_const_handle, SFace_handle> FM;
|
|
|
|
SM_const_decorator E(&*vin);
|
|
Vertex_handle vout = this->sncp()->new_vertex(vin->point(), vin->mark());
|
|
SM_decorator D(&*vout);
|
|
|
|
SVertex_const_handle sv;
|
|
CGAL_forall_svertices(sv, E) {
|
|
VM[sv] = D.new_svertex(sv->point());
|
|
}
|
|
|
|
SHalfedge_const_handle se;
|
|
CGAL_forall_sedges(se, E) {
|
|
EM[se] = D.new_shalfedge_pair();
|
|
EM[se->twin()] = EM[se]->twin();
|
|
}
|
|
|
|
SFace_const_handle sf;
|
|
CGAL_forall_sfaces(sf, E)
|
|
FM[sf] = D.new_sface();
|
|
|
|
SHalfloop_handle sl;
|
|
if(E.has_shalfloop()) {
|
|
sl = LM[E.shalfloop()] = D.new_shalfloop_pair();
|
|
LM[E.shalfloop()->twin()] = sl->twin();
|
|
D.set_face(sl, FM[E.shalfloop()->incident_sface()]);
|
|
D.set_face(sl->twin(), FM[E.shalfloop()->twin()->incident_sface()]);
|
|
sl->circle() = E.shalfloop()->circle();
|
|
sl->twin()->circle() = E.shalfloop()->twin()->circle();
|
|
sl->mark() = sl->twin()->mark() = E.shalfloop()->mark();
|
|
}
|
|
|
|
CGAL_forall_svertices(sv, E) {
|
|
D.set_first_out_edge(VM[sv], EM[E.first_out_edge(sv)]);
|
|
D.set_face(VM[sv], FM[sv->incident_sface()]);
|
|
VM[sv]->mark() = sv->mark();
|
|
}
|
|
|
|
CGAL_forall_shalfedges(se, E) {
|
|
EM[se]->mark() = EM[se]->twin()->mark() = se->mark();
|
|
D.set_source(EM[se], VM[se->source()]);
|
|
D.set_prev(EM[se], EM[se->sprev()]);
|
|
D.set_next(EM[se], EM[se->snext()]);
|
|
D.set_face(EM[se], FM[se->incident_sface()]);
|
|
EM[se]->circle() = se->circle();
|
|
}
|
|
|
|
CGAL_forall_sfaces(sf, E) {
|
|
FM[sf]->mark() = sf->mark();
|
|
SFace_cycle_const_iterator sfc;
|
|
for(sfc = sf->sface_cycles_begin(); sfc != sf->sface_cycles_end(); ++sfc) {
|
|
if(sfc.is_svertex())
|
|
D.store_sm_boundary_object(VM[SVertex_const_handle(sfc)], FM[sf]);
|
|
else if(sfc.is_shalfedge())
|
|
D.store_sm_boundary_object(EM[SHalfedge_const_handle(sfc)], FM[sf]);
|
|
else if(sfc.is_shalfloop())
|
|
D.store_sm_boundary_object(LM[SHalfloop_const_handle(sfc)], FM[sf]);
|
|
else CGAL_error_msg("damn wrong handle.");
|
|
}
|
|
}
|
|
|
|
return vout;
|
|
}
|
|
|
|
template<typename Selection, typename Association>
|
|
Sphere_map* create_edge_facet_overlay( Halfedge_const_handle e,
|
|
Halffacet_const_handle f,
|
|
const Point_3& p,
|
|
const Selection& BOP, bool inv,
|
|
Association& ) {
|
|
|
|
#ifdef CGAL_NEF3_TIMER_SPHERE_SWEEPS
|
|
++number_of_edge_facet_overlays;
|
|
#endif
|
|
|
|
CGAL_NEF_TRACEN("edge facet overlay " << p);
|
|
|
|
Unique_hash_map<SHalfedge_handle, Mark> mark_of_right_sface;
|
|
|
|
SM_decorator D(&*this->sncp()->new_vertex(p, BOP(e->mark(), f->mark())));
|
|
SM_const_decorator E(&*e->source());
|
|
|
|
Sphere_point ps = e->point();
|
|
ps = normalized(ps);
|
|
SVertex_handle v1 = D.new_svertex(ps);
|
|
SVertex_handle v2 = D.new_svertex(ps.antipode());
|
|
|
|
CGAL_NEF_TRACEN("new svertex 1 " << ps);
|
|
CGAL_NEF_TRACEN("new svertex 2 " << ps.antipode());
|
|
Halffacet_const_handle faces_p(f);
|
|
Vector_3 vec(ps-CGAL::ORIGIN);
|
|
if(faces_p->plane().oriented_side(p+vec) == ON_NEGATIVE_SIDE)
|
|
faces_p = faces_p->twin();
|
|
v1->mark() = BOP(e->mark(), faces_p->incident_volume()->mark(), inv);
|
|
v2->mark() = BOP(e->mark(), faces_p->twin()->incident_volume()->mark(), inv);
|
|
CGAL_NEF_TRACEN("svertex 1 " << ps << " has mark " << v1->mark());
|
|
CGAL_NEF_TRACEN("svertex 2 " << ps.antipode() << " has mark " << v2->mark());
|
|
|
|
if(E.is_isolated(e)) {
|
|
CGAL_NEF_TRACEN("edge is isolated");
|
|
Mark mf1 = BOP(e->incident_sface()->mark(), faces_p->incident_volume()->mark(), inv);
|
|
Mark mf2 = BOP(e->incident_sface()->mark(), faces_p->twin()->incident_volume()->mark(), inv);
|
|
Mark ml = BOP(e->incident_sface()->mark(), faces_p->mark(), inv);
|
|
|
|
SFace_handle f1 = D.new_sface();
|
|
D.link_as_isolated_vertex(v1, f1);
|
|
f1->mark() = mf1;
|
|
|
|
if(mf1 == mf2 && mf1 == ml) {
|
|
D.link_as_isolated_vertex(v2, f1);
|
|
}
|
|
else {
|
|
SHalfloop_handle l = D.new_shalfloop_pair();
|
|
SFace_handle f2 = D.new_sface();
|
|
D.link_as_isolated_vertex(v2, f2);
|
|
D.link_as_loop(l,f1);
|
|
D.link_as_loop(l->twin(),f2);
|
|
l->circle() = Sphere_circle(faces_p->plane());
|
|
l->twin()->circle() = l->circle().opposite();
|
|
f2->mark() = mf2;
|
|
l->mark() = l->twin()->mark() = ml;
|
|
}
|
|
}
|
|
else {
|
|
CGAL_NEF_TRACEN("edge is not isolated");
|
|
SVertex_handle sv;
|
|
SHalfedge_handle se1;
|
|
SHalfedge_handle se2;
|
|
SFace_handle sf;
|
|
Sphere_circle c(f->plane());
|
|
|
|
SHalfedge_handle next_edge;
|
|
SHalfedge_around_svertex_const_circulator ec(E.out_edges(e)), ee(ec);
|
|
CGAL_For_all(ec,ee) {
|
|
Sphere_segment seg(ec->source()->point(),
|
|
ec->source()->point().antipode(),
|
|
ec->circle());
|
|
Sphere_point sp(intersection(c, seg.sphere_circle()));
|
|
CGAL_NEF_TRACEN(seg <<" has_on " << sp);
|
|
if(!seg.has_on_after_intersection(sp))
|
|
sp = sp.antipode();
|
|
sv = D.new_svertex(sp);
|
|
CGAL_NEF_TRACEN("new svertex 3 " << normalized(sp));
|
|
sv->mark() = BOP(ec->mark(), f->mark(), inv);
|
|
se1 = D.new_shalfedge_pair(v1, sv);
|
|
if(next_edge == SHalfedge_handle())
|
|
se2 = D.new_shalfedge_pair(sv, v2);
|
|
else
|
|
se2 = D.new_shalfedge_pair(sv, next_edge, -1);
|
|
next_edge = se2->twin();
|
|
se1->mark() = se1->twin()->mark() = BOP(ec->mark(), faces_p->incident_volume()->mark(), inv);
|
|
se2->mark() = se2->twin()->mark() = BOP(ec->mark(), faces_p->twin()->incident_volume()->mark(), inv);
|
|
mark_of_right_sface[se1] = ec->incident_sface()->mark();
|
|
se1->circle() = se2->circle() = ec->circle();
|
|
se1->twin()->circle() = se2->twin()->circle() = se1->circle().opposite();
|
|
}
|
|
|
|
SHalfedge_around_svertex_circulator ec2(D.out_edges(v1)), ee2(ec2);
|
|
CGAL_For_all(ec2,ee2) {
|
|
SHalfedge_around_svertex_circulator en(ec2);
|
|
++en;
|
|
se1 = D.new_shalfedge_pair(ec2->twin(), en->twin(), -1, 1);
|
|
CGAL_NEF_TRACEN("new edge pair " << ec2->twin()->source()->vector() <<
|
|
" -> " << en->twin()->source()->vector());
|
|
se1->circle() = Sphere_circle(faces_p->plane());
|
|
se1->twin()->circle() = se1->circle().opposite();
|
|
se1->mark() = se1->twin()->mark() = BOP(mark_of_right_sface[ec2], faces_p->mark(), inv);
|
|
|
|
sf = D.new_sface();
|
|
sf->mark() = BOP(mark_of_right_sface[ec2], faces_p->incident_volume()->mark(), inv);
|
|
D.link_as_face_cycle(se1,sf);
|
|
sf = D.new_sface();
|
|
sf->mark() = BOP(mark_of_right_sface[ec2], faces_p->twin()->incident_volume()->mark(), inv);
|
|
D.link_as_face_cycle(se1->twin(),sf);
|
|
}
|
|
}
|
|
|
|
return D.sphere_map();
|
|
}
|
|
|
|
public:
|
|
Point_3 get_transformed_coords_of_vertex(const Point_3& p,
|
|
const std::list<Point_3>& segs1,
|
|
const std::list<Point_3>& segs2) {
|
|
CGAL_assertion(!segs1.empty() && !segs2.empty());
|
|
|
|
int side_of_point=1;
|
|
RT max = p.hx();
|
|
if(CGAL_NTS abs(p.hy()) > CGAL_NTS abs(max)) {
|
|
max = p.hy();
|
|
side_of_point=2;
|
|
}
|
|
if(CGAL_NTS abs(p.hz()) > CGAL_NTS abs(max)) {
|
|
max = p.hz();
|
|
side_of_point=3;
|
|
}
|
|
if(max < RT(0))
|
|
side_of_point = -side_of_point;
|
|
|
|
typename std::list<Point_3>::const_iterator s1,s2,t1,t2;
|
|
s1 = Infi_box::segment_on_side(side_of_point, segs1);
|
|
t1 = s1;
|
|
++t1;
|
|
if(t1 == segs1.end()) t1=segs1.begin();
|
|
s2 = Infi_box::segment_on_side(side_of_point, segs2);
|
|
t2 = s2;
|
|
++t2;
|
|
if(t2 == segs2.end()) t2=segs2.begin();
|
|
|
|
Point_3 ip;
|
|
bool flag = SNC_intersection::does_intersect_internally(Segment_3(*s1,*t1),Segment_3(*s2,*t2),ip);
|
|
if(!flag) {
|
|
if(*s1 == *s2) return normalized(*s1);
|
|
else if(*s1 == *t2) return normalized(*s1);
|
|
else if(*t1 == *s2) return normalized(*t1);
|
|
else if(*t1 == *t2) return normalized(*t1);
|
|
}
|
|
return normalized(ip);
|
|
}
|
|
|
|
Point_3 transform_point_on_infibox(const Point_3& p,
|
|
const Aff_transformation_3& aff) {
|
|
|
|
Point_3 res(p.transform(aff));
|
|
res = normalized(p);
|
|
RT hw(CGAL_NTS abs(res.hx()));
|
|
if(CGAL_NTS abs(res.hy()) > hw) hw = CGAL_NTS abs(res.hy());
|
|
if(CGAL_NTS abs(res.hz()) > hw) hw = CGAL_NTS abs(res.hz());
|
|
CGAL_assertion(hw.degree() == 1);
|
|
CGAL_assertion(hw[0] == 0);
|
|
return Point_3(res.hx(), res.hy(), res.hz(), hw(1));
|
|
}
|
|
|
|
bool erase_redundant_vertices() {
|
|
|
|
std::list<Vertex_handle> redundant_points;
|
|
Vertex_iterator v;
|
|
CGAL_forall_vertices(v, *this->sncp())
|
|
if(!is_standard(v))
|
|
redundant_points.push_back(v);
|
|
|
|
redundant_points.sort(Frame_point_lt<Infi_box,Vertex_handle>());
|
|
|
|
typename std::list<Vertex_handle>::iterator vi, vinext;
|
|
for(vi = redundant_points.begin(); vi != redundant_points.end(); ++vi) {
|
|
vinext = vi;
|
|
++vinext;
|
|
if(vinext == redundant_points.end()) break;
|
|
if((*vi)->point() == (*vinext)->point()) {
|
|
CGAL_assertion(!Infi_box::is_complex_facet_infibox_intersection(**vi));
|
|
this->sncp()->delete_vertex(*vi);
|
|
}
|
|
}
|
|
|
|
NT eval(Infi_box::compute_evaluation_constant_for_halfedge_pairup(*this->sncp()));
|
|
CGAL_NEF_TRACEN("eval at " << eval);
|
|
|
|
bool res;
|
|
do {
|
|
|
|
res = false;
|
|
typedef Halfedge_key< Point_3, Halfedge_handle>
|
|
Halfedge_key;
|
|
typedef Halfedge_key_lt< Point_3, Halfedge_handle, SNC_decorator>
|
|
Halfedge_key_lt;
|
|
typedef std::list<Halfedge_key> Halfedge_list;
|
|
|
|
typedef typename Standard_kernel::Kernel_tag Kernel_tag;
|
|
typedef CGAL::Pluecker_line_3<Kernel_tag,Standard_kernel> Pluecker_line_3;
|
|
typedef CGAL::Pluecker_line_lt Pluecker_line_lt;
|
|
typedef std::map< Pluecker_line_3, Halfedge_list, Pluecker_line_lt>
|
|
Pluecker_line_map;
|
|
|
|
Unique_hash_map<Vertex_handle, bool> erase_vertex(false);
|
|
std::list<Point_3> recreate;
|
|
|
|
SNC_decorator D(*this);
|
|
Pluecker_line_map M2;
|
|
Pluecker_line_map M3;
|
|
Pluecker_line_map M4;
|
|
|
|
Halfedge_iterator e;
|
|
CGAL_forall_halfedges(e,*this->sncp()) {
|
|
Point_3 p = e->source()->point();
|
|
Point_3 q = p + e->vector();
|
|
Standard_point_3 sp = Infi_box::standard_point(p,eval);
|
|
Standard_point_3 sq = Infi_box::standard_point(q,eval);
|
|
Pluecker_line_3 l( sp, sq);
|
|
|
|
int inverted;
|
|
l = categorize( l, inverted);
|
|
|
|
CGAL_NEF_TRACEN(" segment("<<p<<", "<<q<<")"<<
|
|
" direction("<<e->vector()<<")"<<
|
|
" line("<<l<<")"<<" inverted="<<inverted);
|
|
|
|
if(Infi_box::is_edge_on_infibox(e)) {
|
|
if(Infi_box::is_type4(e))
|
|
M4[l].push_back(Halfedge_key(p,inverted,e));
|
|
else
|
|
if(Infi_box::is_type3(e))
|
|
M3[l].push_back(Halfedge_key(p,inverted,e));
|
|
else
|
|
M2[l].push_back(Halfedge_key(p,inverted,e));
|
|
}
|
|
}
|
|
|
|
typename Pluecker_line_map::iterator it;
|
|
|
|
CGAL_forall_iterators(it,M4) {
|
|
CGAL_NEF_TRACEN("search opposite4 "<<it->first);
|
|
it->second.sort(Halfedge_key_lt());
|
|
typename Halfedge_list::iterator itl;
|
|
CGAL_forall_iterators(itl,it->second) {
|
|
Halfedge_handle e1 = itl->e;
|
|
CGAL_NEF_TRACE(" " << e1->source()->point() << " -> ");
|
|
++itl;
|
|
if(itl == it->second.end()) {
|
|
erase_vertex[e1->source()] = true;
|
|
break;
|
|
}
|
|
Halfedge_handle e2 = itl->e;
|
|
CGAL_NEF_TRACE(e2->source()->point());
|
|
if(normalized(e1->point())!=normalized(e2->point().antipode())) {
|
|
erase_vertex[e1->source()] = true;
|
|
--itl;
|
|
CGAL_NEF_TRACE(" failed ");
|
|
}
|
|
CGAL_NEF_TRACEN("");
|
|
}
|
|
CGAL_NEF_TRACEN("");
|
|
CGAL_NEF_TRACEN("");
|
|
}
|
|
|
|
CGAL_forall_iterators(it,M3) {
|
|
CGAL_NEF_TRACEN("search opposite3 "<<it->first);
|
|
it->second.sort(Halfedge_key_lt());
|
|
typename Halfedge_list::iterator itl;
|
|
CGAL_forall_iterators(itl,it->second) {
|
|
Halfedge_handle e1 = itl->e;
|
|
CGAL_NEF_TRACE(" " << e1->source()->point() << " -> ");
|
|
++itl;
|
|
if(itl == it->second.end()) {
|
|
erase_vertex[e1->source()] = true;
|
|
break;
|
|
}
|
|
Halfedge_handle e2 = itl->e;
|
|
CGAL_NEF_TRACE(e2->source()->point());
|
|
if(normalized(e1->point())!=normalized(e2->point().antipode())) {
|
|
erase_vertex[e1->source()] = true;
|
|
--itl;
|
|
CGAL_NEF_TRACE(" failed ");
|
|
}
|
|
CGAL_NEF_TRACEN("");
|
|
}
|
|
CGAL_NEF_TRACEN("");
|
|
CGAL_NEF_TRACEN("");
|
|
}
|
|
|
|
CGAL_forall_iterators(it,M2) {
|
|
CGAL_NEF_TRACEN("search opposite2 "<<it->first);
|
|
it->second.sort(Halfedge_key_lt());
|
|
typename Halfedge_list::iterator itl;
|
|
CGAL_forall_iterators(itl,it->second) {
|
|
Halfedge_handle e1 = itl->e;
|
|
CGAL_NEF_TRACE(" " << e1->source()->point() << " -> ");
|
|
++itl;
|
|
if(itl == it->second.end()) {
|
|
erase_vertex[e1->source()] = true;
|
|
break;
|
|
}
|
|
Halfedge_handle e2 = itl->e;
|
|
CGAL_NEF_TRACE(e2->source()->point());
|
|
if(normalized(e1->point())!=normalized(e2->point().antipode())) {
|
|
erase_vertex[e1->source()] = true;
|
|
--itl;
|
|
CGAL_NEF_TRACE(" failed ");
|
|
}
|
|
CGAL_NEF_TRACEN("");
|
|
}
|
|
CGAL_NEF_TRACEN("");
|
|
CGAL_NEF_TRACEN("");
|
|
}
|
|
|
|
std::vector<Vertex_iterator> vertices_to_delete ;
|
|
Vertex_iterator v;
|
|
CGAL_forall_vertices(v, *this->sncp()) {
|
|
if(erase_vertex[v]) {
|
|
CGAL_NEF_TRACEN("erase " << v->point());
|
|
if(Infi_box::is_infibox_corner(v->point()))
|
|
recreate.push_back(v->point());
|
|
vertices_to_delete.push_back(v);
|
|
res = true;
|
|
}
|
|
}
|
|
|
|
for( typename std::vector<Vertex_iterator>::iterator vit = vertices_to_delete.begin()
|
|
; vit != vertices_to_delete.end()
|
|
; ++ vit
|
|
)
|
|
this->sncp()->delete_vertex(*vit);
|
|
|
|
|
|
typename std::list<Point_3>::const_iterator pi;
|
|
for(pi = recreate.begin(); pi != recreate.end(); ++pi)
|
|
create_from_point_on_infibox_vertex(*pi);
|
|
|
|
} while(res);
|
|
|
|
return res;
|
|
}
|
|
|
|
std::list<Point_3> find_points_of_box_with_plane(const Plane_3& h) {
|
|
Vector_3 orth = h.orthogonal_vector();
|
|
|
|
NT orth_coords[3];
|
|
orth_coords[0] = orth.hx()[0];
|
|
orth_coords[1] = orth.hy()[0];
|
|
orth_coords[2] = orth.hz()[0];
|
|
|
|
int add_corners = 0;
|
|
while(orth_coords[add_corners] == 0){
|
|
CGAL_assertion(add_corners < 2);
|
|
++add_corners;
|
|
}
|
|
|
|
std::list<Point_3> points;
|
|
for(int dir=0; dir<3;++dir) {
|
|
|
|
NT cnst[3] = { 0, 0, 0 };
|
|
cnst[dir] = -h.d()[0];
|
|
|
|
NT cross[4][4];
|
|
cross[0][dir] = -orth_coords[(dir+1)%3]-orth_coords[(dir+2)%3];
|
|
cross[1][dir] = orth_coords[(dir+1)%3]-orth_coords[(dir+2)%3];
|
|
cross[2][dir] = orth_coords[(dir+1)%3]+orth_coords[(dir+2)%3];
|
|
cross[3][dir] = -orth_coords[(dir+1)%3]+orth_coords[(dir+2)%3];
|
|
|
|
for(int i=0;i<4;++i)
|
|
cross[i][3] = orth_coords[dir];
|
|
|
|
cross[0][(dir+1)%3] = cross[3][(dir+1)%3] = orth_coords[dir];
|
|
cross[1][(dir+1)%3] = cross[2][(dir+1)%3] = -orth_coords[dir];
|
|
|
|
cross[0][(dir+2)%3] = cross[1][(dir+2)%3] = orth_coords[dir];
|
|
cross[2][(dir+2)%3] = cross[3][(dir+2)%3] = -orth_coords[dir];
|
|
|
|
for(int i=0; i<4; ++i)
|
|
if(CGAL_NTS abs(RT(cnst[dir],cross[i][dir])) <
|
|
CGAL_NTS abs(RT(0,orth_coords[dir])) ||
|
|
(CGAL_NTS abs(RT(cnst[dir],cross[i][dir])) ==
|
|
CGAL_NTS abs(RT(0,orth_coords[dir])) &&
|
|
dir == add_corners))
|
|
|
|
points.push_back(Point_3(RT(cnst[0], cross[i][0]),
|
|
RT(cnst[1], cross[i][1]),
|
|
RT(cnst[2], cross[i][2]),
|
|
RT(cross[i][3])));
|
|
}
|
|
|
|
for(int i=0;i<3;++i)
|
|
orth_coords[i] = CGAL_NTS abs(orth_coords[i]);
|
|
|
|
int max = 0;
|
|
if(orth_coords[1] > orth_coords[0])
|
|
max = 1;
|
|
if(orth_coords[2] > orth_coords[max])
|
|
max = 2;
|
|
|
|
int min = 0;
|
|
if(orth_coords[1] < orth_coords[0])
|
|
min = 1;
|
|
if(orth_coords[2] < orth_coords[min])
|
|
min = 2;
|
|
|
|
points.sort(circle_lt<Kernel>(max));
|
|
|
|
typename std::list<Point_3>::const_iterator p;
|
|
for(p=points.begin();p!=points.end();++p)
|
|
CGAL_NEF_TRACEN(*p);
|
|
|
|
return points;
|
|
}
|
|
|
|
std::list<Point_3> find_facet_infibox_intersections(Halffacet_handle fi,
|
|
std::list<Point_3> points) {
|
|
|
|
// points is a list of the required points, but with the inverse transformation applied
|
|
|
|
std::list<Point_3> res;
|
|
Halffacet_cycle_iterator fc = fi->facet_cycles_begin();
|
|
CGAL_assertion(fc.is_shalfedge());
|
|
SHalfedge_handle sh(fc);
|
|
SHalfedge_around_facet_circulator fcc(sh), fend(fcc);
|
|
CGAL_For_all(fcc,fend) {
|
|
Point_3 src(fcc->source()->source()->point());
|
|
Point_3 trg(fcc->source()->twin()->source()->point());
|
|
typename std::list<Point_3>::iterator pi,pprev;
|
|
pi = points.begin();
|
|
while(pi != points.end()) {
|
|
*pi = normalized(*pi);
|
|
CGAL_NEF_TRACEN(src << "->" << trg << " has on " << *pi << src.x() << " : " );
|
|
CGAL_NEF_TRACEN((src.x()-pi->x() <= 0) << "|" << (src.y()-pi->y() <= 0) << "|" << (src.z()-pi->z() <= 0) );
|
|
CGAL_NEF_TRACEN((pi->x()-trg.x() <= 0) << "|" << (pi->y()-trg.y() <= 0) << "|" << (pi->z()-trg.z() <= 0) );
|
|
if(( (src.x()-pi->x() <= 0 && pi->x()-trg.x() <= 0) ||
|
|
(src.x()-pi->x() >= 0 && pi->x()-trg.x() >= 0)) &&
|
|
((src.y()-pi->y() <= 0 && pi->y()-trg.y() <= 0) ||
|
|
(src.y()-pi->y() >= 0 && pi->y()-trg.y() >= 0)) &&
|
|
((src.z()-pi->z() <= 0 && pi->z()-trg.z() <= 0) ||
|
|
(src.z()-pi->z() >= 0 && pi->z()-trg.z() >= 0))) {
|
|
pprev = pi;
|
|
++pi;
|
|
res.push_back(*pprev);
|
|
points.erase(pprev);
|
|
}
|
|
else {
|
|
++pi;
|
|
}
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
|
|
std::list<Vertex_handle>
|
|
create_vertices_on_infibox(const Plane_3& h, const std::list<Point_3> points,
|
|
const Mark& bnd, const Mark& inside, const Mark& outside) {
|
|
std::list<Vertex_handle> res;
|
|
NT orth_coords[3];
|
|
int min,max;
|
|
Infi_box::compute_min_max(h,orth_coords,min,max);
|
|
|
|
typename std::list<Point_3>::const_iterator p,prev,next;
|
|
for(p=points.begin();p!=points.end();++p){
|
|
|
|
if(p==points.begin()) prev = --points.end();
|
|
else { prev = p; prev--;}
|
|
if(p==--points.end()) next=points.begin();
|
|
else {next = p; ++next;}
|
|
CGAL_NEF_TRACEN("points " << *prev << " " << *p << " " << *next);
|
|
|
|
Vector_3 v= *prev - *p;
|
|
Sphere_point sp1(v);
|
|
sp1 = normalized(sp1);
|
|
CGAL_assertion(Infi_box::degree(sp1.hx()) == 0);
|
|
CGAL_assertion(Infi_box::degree(sp1.hy()) == 0);
|
|
CGAL_assertion(Infi_box::degree(sp1.hz()) == 0);
|
|
CGAL_assertion(Infi_box::degree(sp1.hw()) == 0);
|
|
|
|
v= *next - *p;
|
|
Sphere_point sp2(v);
|
|
sp2 = normalized(sp2);
|
|
CGAL_assertion(Infi_box::degree(sp2.hx()) == 0);
|
|
CGAL_assertion(Infi_box::degree(sp2.hy()) == 0);
|
|
CGAL_assertion(Infi_box::degree(sp2.hz()) == 0);
|
|
CGAL_assertion(Infi_box::degree(sp2.hw()) == 0);
|
|
|
|
CGAL_NEF_TRACEN("sps " << sp1 << " " << sp2);
|
|
CGAL_NEF_TRACEN(orth_coords[min] << "|" <<
|
|
orth_coords[(min+1)%3] << "|" <<
|
|
orth_coords[(min+2)%3]);
|
|
|
|
if(orth_coords[min]==0 && orth_coords[(min+1)%3] ==
|
|
orth_coords[(min+2)%3] && h.d() == 0)
|
|
res.push_back(create_degenerate_corner_frame_point(*p,sp1,sp2,min,max,h,bnd,inside,outside));
|
|
else if(CGAL_NTS abs(p->hx()) == CGAL_NTS abs(p->hy()) &&
|
|
CGAL_NTS abs(p->hz()) == CGAL_NTS abs(p->hy()))
|
|
res.push_back(create_corner_frame_point(*p,sp1,sp2,max,h,bnd,inside,outside));
|
|
else
|
|
res.push_back(create_frame_point(*p,sp1,sp2,h,bnd,inside,outside));
|
|
}
|
|
return res;
|
|
}
|
|
|
|
void create_vertices_for_halfspace
|
|
(const Plane_3& h, const Mark& boundary)
|
|
{
|
|
std::list<Point_3> points(find_points_of_box_with_plane(h));
|
|
|
|
NT orth_coords[3];
|
|
int min,max;
|
|
Infi_box::compute_min_max(h,orth_coords,min,max);
|
|
Mark inside = orth_coords[max] < 0;
|
|
|
|
#ifdef CGAL_NEF_INDEXED_ITEMS
|
|
int base = Index_generator::get_unique_index();
|
|
for(int i=0; i<3; ++i)
|
|
Index_generator::get_unique_index();
|
|
int plus = 0;
|
|
#endif
|
|
|
|
typename std::list<Point_3>::const_iterator p,prev,next;
|
|
for(p=points.begin();p!=points.end();++p){
|
|
|
|
if(p==points.begin()) prev = --points.end();
|
|
else { prev = p; prev--;}
|
|
if(p==--points.end()) next=points.begin();
|
|
else {next = p; ++next;}
|
|
CGAL_NEF_TRACEN("points " << *prev << " " << *p << " " << *next);
|
|
|
|
Vector_3 v= *prev - *p;
|
|
Sphere_point sp1(v);
|
|
sp1 = normalized(sp1);
|
|
CGAL_assertion(Infi_box::degree(sp1.hx()) == 0);
|
|
CGAL_assertion(Infi_box::degree(sp1.hy()) == 0);
|
|
CGAL_assertion(Infi_box::degree(sp1.hz()) == 0);
|
|
CGAL_assertion(Infi_box::degree(sp1.hw()) == 0);
|
|
|
|
v= *next - *p;
|
|
Sphere_point sp2(v);
|
|
sp2 = normalized(sp2);
|
|
CGAL_assertion(Infi_box::degree(sp2.hx()) == 0);
|
|
CGAL_assertion(Infi_box::degree(sp2.hy()) == 0);
|
|
CGAL_assertion(Infi_box::degree(sp2.hz()) == 0);
|
|
CGAL_assertion(Infi_box::degree(sp2.hw()) == 0);
|
|
|
|
#ifdef CGAL_NEF_INDEXED_ITEMS
|
|
create_halfspace_vertex(*p,sp1,sp2,h,boundary,
|
|
inside, !inside,
|
|
base, plus);
|
|
#else
|
|
create_halfspace_vertex(*p,sp1,sp2,h,boundary,
|
|
inside, !inside);
|
|
#endif
|
|
|
|
}
|
|
}
|
|
|
|
void create_vertices_of_box_with_plane(const Plane_3& h, bool b) {
|
|
// CGAL_NEF_SETDTHREAD(19*43*11);
|
|
|
|
std::list<Point_3> points(find_points_of_box_with_plane(h));
|
|
create_vertices_on_infibox(h,points,b,true,false);
|
|
|
|
#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
|
|
|
|
RT sum= h.a()+h.b()+h.c();
|
|
if(h.d()!=0 || sum!= 0) {
|
|
CGAL_NEF_TRACEN(sum);
|
|
create_extended_box_corner
|
|
( 1, 1, 1, (sum<0 || (sum == 0 && h.d()<0)), true
|
|
#ifdef CGAL_NEF_INDEXED_ITEMS
|
|
, base
|
|
#endif
|
|
);
|
|
}
|
|
sum=-h.a()+h.b()+h.c();
|
|
if(h.d()!=0 || sum!= 0) {
|
|
CGAL_NEF_TRACEN(sum);
|
|
create_extended_box_corner
|
|
(-1, 1, 1, (sum<0 || (sum == 0 && h.d()<0)), true
|
|
#ifdef CGAL_NEF_INDEXED_ITEMS
|
|
, base
|
|
#endif
|
|
);
|
|
}
|
|
sum= h.a()-h.b()+h.c();
|
|
if(h.d()!=0 || sum!= 0) {
|
|
CGAL_NEF_TRACEN(sum);
|
|
create_extended_box_corner
|
|
( 1,-1, 1, (sum<0 || (sum == 0 && h.d()<0)), true
|
|
#ifdef CGAL_NEF_INDEXED_ITEMS
|
|
, base
|
|
#endif
|
|
);
|
|
}
|
|
sum=-h.a()-h.b()+h.c();
|
|
if(h.d()!=0 || sum!= 0) {
|
|
CGAL_NEF_TRACEN(sum);
|
|
create_extended_box_corner
|
|
(-1,-1, 1, (sum<0 || (sum == 0 && h.d()<0)), true
|
|
#ifdef CGAL_NEF_INDEXED_ITEMS
|
|
, base
|
|
#endif
|
|
);
|
|
}
|
|
sum= h.a()+h.b()-h.c();
|
|
if(h.d()!=0 || sum!= 0) {
|
|
CGAL_NEF_TRACEN(sum);
|
|
create_extended_box_corner
|
|
( 1, 1,-1, (sum<0 || (sum == 0 && h.d()<0)), true
|
|
#ifdef CGAL_NEF_INDEXED_ITEMS
|
|
, base
|
|
#endif
|
|
);
|
|
}
|
|
sum=-h.a()+h.b()-h.c();
|
|
if(h.d()!=0 || sum!= 0) {
|
|
CGAL_NEF_TRACEN(sum);
|
|
create_extended_box_corner
|
|
(-1, 1,-1, (sum<0 || (sum == 0 && h.d()<0)), true
|
|
#ifdef CGAL_NEF_INDEXED_ITEMS
|
|
, base
|
|
#endif
|
|
);
|
|
}
|
|
sum= h.a()-h.b()-h.c();
|
|
if(h.d()!=0 || sum!= 0) {
|
|
CGAL_NEF_TRACEN(sum);
|
|
create_extended_box_corner
|
|
( 1,-1,-1, (sum<0 || (sum == 0 && h.d()<0)), true
|
|
#ifdef CGAL_NEF_INDEXED_ITEMS
|
|
, base
|
|
#endif
|
|
);
|
|
}
|
|
sum=-h.a()-h.b()-h.c();
|
|
if(h.d()!=0 || sum!= 0) {
|
|
CGAL_NEF_TRACEN(sum);
|
|
create_extended_box_corner
|
|
(-1,-1,-1, (sum<0 || (sum == 0 && h.d()<0)), true
|
|
#ifdef CGAL_NEF_INDEXED_ITEMS
|
|
, base
|
|
#endif
|
|
);
|
|
}
|
|
}
|
|
|
|
Vertex_handle create_halfspace_vertex
|
|
(const Point_3& p, const Point_3& sp0, const Point_3& sp1,
|
|
const Plane_3& h, const Mark& boundary,
|
|
const Mark& inside, const Mark& outside
|
|
#ifdef CGAL_NEF_INDEXED_ITEMS
|
|
, int base, int& plus
|
|
#endif
|
|
) const
|
|
{
|
|
// Question: why can this be a const fucnction??
|
|
|
|
if(h.d() == 0) {
|
|
CGAL_assertion(CGAL_NTS abs(p.hy()) !=
|
|
CGAL_NTS abs(p.hx()) ||
|
|
CGAL_NTS abs(p.hz()) !=
|
|
CGAL_NTS abs(p.hx()));
|
|
}
|
|
|
|
Vertex_handle v=
|
|
this->sncp()->new_vertex(normalized(p), boundary);
|
|
SM_decorator SD(&*v);
|
|
|
|
std::vector<SVertex_handle> sv(2);
|
|
sv[0] = SD.new_svertex(sp0);
|
|
sv[1] = SD.new_svertex(sp1);
|
|
sv[0]->mark() = sv[1]->mark() = boundary;
|
|
|
|
SHalfedge_handle se =
|
|
SD.new_shalfedge_pair(sv[0], sv[1]);
|
|
se->circle() =
|
|
Sphere_circle(Plane_3(sp0, sp1, Point_3(0,0,0)));
|
|
se->twin()->circle() = se->circle().opposite();
|
|
se->mark() = se->twin()->mark() = boundary;
|
|
|
|
SHalfedge_handle se2 =
|
|
SD.new_shalfedge_pair(sv[0], sv[1]);
|
|
se2->circle() = se->twin()->circle();
|
|
se2->twin()->circle() = se->circle();
|
|
se2->mark() = se2->twin()->mark() = boundary;
|
|
|
|
#ifdef CGAL_NEF_INDEXED_ITEMS
|
|
sv[0]->set_index(base+plus);
|
|
plus = (plus+1) % 4;
|
|
sv[1]->set_index(base+plus);
|
|
se->set_index(base);
|
|
se->twin()->set_index(base+1);
|
|
#endif
|
|
|
|
SFace_handle sf0 = SD.new_sface();
|
|
SFace_handle sf1 = SD.new_sface();
|
|
sf0->mark()= inside;
|
|
sf1->mark()= outside;
|
|
|
|
SD.link_as_face_cycle(se,sf0);
|
|
SD.link_as_face_cycle(se->twin(),sf1);
|
|
|
|
return v;
|
|
}
|
|
|
|
Vertex_handle
|
|
create_frame_point(Point_3 p, Point_3 sp1, Point_3 sp2, Plane_3 h,
|
|
const Mark& boundary, const Mark& inside, const Mark& outside) const
|
|
{
|
|
if(h.d() == 0) {
|
|
CGAL_assertion(CGAL_NTS abs(p.hy()) != CGAL_NTS abs(p.hx()) ||
|
|
CGAL_NTS abs(p.hz()) != CGAL_NTS abs(p.hx()));
|
|
}
|
|
|
|
int max = 0;
|
|
if(CGAL_NTS abs(p.hx()) > CGAL_NTS abs(p.hy()))
|
|
max = 1;
|
|
if(CGAL_NTS abs(p.hx()) > CGAL_NTS abs(p.hz()))
|
|
max = 2;
|
|
|
|
CGAL_NEF_TRACEN("create frame point ");
|
|
|
|
CGAL_NEF_TRACEN("create spoints");
|
|
Sphere_point SP[4];
|
|
switch(max) {
|
|
case 0: SP[2] = Sphere_point(1,0,0); break;
|
|
case 1: SP[2] = Sphere_point(0,1,0); break;
|
|
case 2: SP[2] = Sphere_point(0,0,1); break;
|
|
default: CGAL_error_msg("wrong value");
|
|
}
|
|
|
|
SP[1]=sp1;
|
|
SP[0]=sp2;
|
|
|
|
if (spherical_orientation(SP[0],SP[1],SP[2]) < 0) {
|
|
SP[3] = SP[2];
|
|
SP[2] = CGAL::ORIGIN-SP[3];
|
|
}
|
|
else
|
|
SP[3] = CGAL::ORIGIN-SP[2];
|
|
|
|
RT delta = h.a()*SP[2].hx()+h.b()*SP[2].hy()+h.c()*SP[2].hz();
|
|
CGAL_assertion(delta !=0);
|
|
Mark swtch = (delta < 0);
|
|
Mark fmark0 = (swtch && inside) || (!swtch && !inside);
|
|
Mark fmark1 = (swtch && outside) || (!swtch && !outside);
|
|
|
|
return create_SM_on_infibox(p, SP, 4, boundary, fmark0, fmark1);
|
|
}
|
|
|
|
Vertex_handle
|
|
create_corner_frame_point(Point_3 p, Point_3 sp1, Point_3 sp2,
|
|
int max, Plane_3 h,
|
|
const Mark& boundary, const Mark& inside, const Mark& outside) const {
|
|
CGAL_assertion(h.d() == 0);
|
|
|
|
Vector_3 vec = h.orthogonal_vector();
|
|
|
|
CGAL_assertion(CGAL_NTS abs(vec.hx()) != CGAL_NTS abs(vec.hy()) &&
|
|
CGAL_NTS abs(vec.hy()) != CGAL_NTS abs(vec.hz()) &&
|
|
CGAL_NTS abs(vec.hx()) != CGAL_NTS abs(vec.hz()));
|
|
|
|
CGAL_assertion(vec.hx() + vec.hy() == vec.hz() ||
|
|
vec.hx() + vec.hz() == vec.hy() ||
|
|
vec.hy() + vec.hz() == vec.hx());
|
|
|
|
CGAL_NEF_TRACEN("create corner frame point ");
|
|
|
|
RT vp[3] = {
|
|
static_cast<RT>(-p.hx()[1]),
|
|
static_cast<RT>(-p.hy()[1]),
|
|
static_cast<RT>(-p.hz()[1]) };
|
|
|
|
CGAL_NEF_TRACEN("create spoints");
|
|
Sphere_point SP[5];
|
|
switch(max) {
|
|
case 0:
|
|
SP[3] = Sphere_point(0,vp[1],0);
|
|
SP[2]= Sphere_point(0,0,vp[2]);
|
|
SP[4] = Sphere_point(vp[0],0,0);
|
|
break;
|
|
case 1:
|
|
SP[3] = Sphere_point(vp[0],0,0);
|
|
SP[2]= Sphere_point(0,0,vp[2]);
|
|
SP[4] = Sphere_point(0,vp[1],0);
|
|
break;
|
|
case 2:
|
|
SP[3] = Sphere_point(vp[0],0,0);
|
|
SP[2]= Sphere_point(0,vp[1],0);
|
|
SP[4] = Sphere_point(0,0,vp[2]);
|
|
break;
|
|
default: CGAL_error_msg("wrong value");
|
|
}
|
|
|
|
if (spherical_orientation(SP[3],Sphere_point(sp1),Sphere_point(sp2)) > 0) {
|
|
SP[0] = sp1;
|
|
SP[1] = sp2;
|
|
}
|
|
else {
|
|
SP[0] = sp2;
|
|
SP[1] = sp1;
|
|
}
|
|
|
|
if (spherical_orientation(SP[2],SP[3],SP[0]) < 0) {
|
|
Sphere_point sx = SP[2];
|
|
SP[2] = SP[3];
|
|
SP[3] = sx;
|
|
}
|
|
|
|
RT delta = h.a()*SP[4].hx()+h.b()*SP[4].hy()+h.c()*SP[4].hz();
|
|
CGAL_assertion(delta !=0);
|
|
Mark swtch = (delta > 0);
|
|
Mark fmark0 = (swtch && inside) || (!swtch && !inside);
|
|
Mark fmark1 = (swtch && outside) || (!swtch && !outside);
|
|
|
|
return create_SM_on_infibox(p, SP, 5, boundary, fmark0, fmark1);
|
|
}
|
|
|
|
|
|
Vertex_handle
|
|
create_degenerate_corner_frame_point(Point_3 p, Point_3 sp1,Point_3 sp2,
|
|
int min,int max, Plane_3 h,
|
|
const Mark& boundary,
|
|
const Mark& inside, const Mark& outside)const {
|
|
CGAL_assertion(h.d() == 0);
|
|
|
|
Vector_3 vec = h.orthogonal_vector();
|
|
|
|
CGAL_assertion(
|
|
(CGAL_NTS abs(vec.hx()) == CGAL_NTS abs(vec.hy()) && vec.hz() == 0) ||
|
|
(CGAL_NTS abs(vec.hy()) == CGAL_NTS abs(vec.hz()) && vec.hx() == 0) ||
|
|
(CGAL_NTS abs(vec.hx()) == CGAL_NTS abs(vec.hz()) && vec.hy() == 0));
|
|
|
|
RT vp[3] = {
|
|
static_cast<RT>(-p.hx()[1]),
|
|
static_cast<RT>(-p.hy()[1]),
|
|
static_cast<RT>(-p.hz()[1]) };
|
|
|
|
CGAL_NEF_TRACEN("create degenerate corner frame point ");
|
|
|
|
CGAL_NEF_TRACEN("create spoints");
|
|
Sphere_point SP[4];
|
|
|
|
switch(max) {
|
|
case 0: SP[2] = Sphere_point(vp[0],0,0); break; // plane(x,x,0), plane(x,0,x)
|
|
case 1: SP[2] = Sphere_point(0,vp[1],0); break; // plane(0,x,x)
|
|
default: CGAL_error_msg("wrong value \"max\"");
|
|
}
|
|
|
|
switch(min+max) {
|
|
case 1: SP[3] = Sphere_point(0,0,vp[2]); break; // plane(0,x,x), plane(x,0,x)
|
|
case 2: SP[3] = Sphere_point(0,vp[1],0); break; // plane(x,x,0)
|
|
default: CGAL_error_msg("wrong value \"min+max\"");
|
|
}
|
|
|
|
if (spherical_orientation(SP[2],Sphere_point(sp1),Sphere_point(sp2)) > 0) {
|
|
SP[0] = sp1;
|
|
SP[1] = sp2;
|
|
}
|
|
else {
|
|
SP[0] = sp2;
|
|
SP[1] = sp1;
|
|
}
|
|
|
|
RT delta = h.a()*SP[2].hx()+h.b()*SP[2].hy()+h.c()*SP[2].hz();
|
|
CGAL_assertion(delta !=0);
|
|
Mark swtch = (delta < 0);
|
|
Mark fmark0 = (swtch && inside) || (!swtch && !inside);
|
|
Mark fmark1 = (swtch && outside) || (!swtch && !outside);
|
|
|
|
return create_SM_on_infibox(p, SP, 4, boundary, fmark0, fmark1);
|
|
}
|
|
|
|
|
|
|
|
Vertex_handle
|
|
create_SM_on_infibox(const Point_3& center, Sphere_point* SP,
|
|
int size, const Mark& boundary,
|
|
const Mark& fmark0, const Mark& fmark1) const {
|
|
Vertex_handle v=this->sncp()->new_vertex(normalized(center), boundary);
|
|
SM_decorator SD(&*v);
|
|
|
|
CGAL_NEF_TRACEN("create_SM_on_infibox: center = " << center);
|
|
|
|
CGAL_NEF_TRACEN("create svertices");
|
|
std::vector<SVertex_handle> sv(size);
|
|
CGAL_NEF_TRACEN("create_SM_on_infibox: size = " << size);
|
|
for(int i=0; i<size; ++i) {
|
|
CGAL_NEF_TRACEN(" SP["<< i << "]=" << SP[i]);
|
|
sv[i] = SD.new_svertex(SP[i]);
|
|
sv[i]->mark() = (i < 2 ? boundary : 1);
|
|
}
|
|
|
|
CGAL_NEF_TRACEN("create sedges");
|
|
std::vector<SHalfedge_handle> she(size+1);
|
|
for(int si=0; si<size-1;++si) {
|
|
she[si]=SD.new_shalfedge_pair(sv[si], sv[(si+1)%(size-1)]);
|
|
she[si]->circle()=
|
|
Sphere_circle(Plane_3(SP[si],SP[(si+1)%(size-1)],Point_3(0,0,0)));
|
|
she[si]->twin()->circle() = she[si]->circle().opposite();
|
|
she[si]->mark() = she[si]->twin()->mark() = (si == 0 ? boundary : 1);
|
|
}
|
|
|
|
she[size-1] = SD.new_shalfedge_pair(she[0], sv[size-1], -1);
|
|
CGAL_assertion(she[size-1]->snext() == she[size-1]->twin());
|
|
CGAL_assertion(she[size-1]->twin()->sprev() == she[size-1]);
|
|
CGAL_assertion(she[size-1]->twin()->sprev()->twin() == she[size-1]->twin());
|
|
|
|
she[size] = SD.new_shalfedge_pair(she[size-1]->twin(), she[0]->twin(), 1, 1);
|
|
|
|
CGAL_assertion(she[0]->snext() == she[1]);
|
|
CGAL_assertion(she[1]->snext() == she[2]);
|
|
if(size == 4)
|
|
CGAL_assertion(she[2]->snext() == she[0]);
|
|
else {
|
|
CGAL_assertion(she[2]->snext() == she[3]);
|
|
CGAL_assertion(she[3]->snext() == she[0]);
|
|
}
|
|
|
|
CGAL_assertion(she[0]->twin()->snext() == she[size-1]);
|
|
CGAL_assertion(she[size-1]->snext() == she[size]);
|
|
CGAL_assertion(she[size]->snext() == she[0]->twin());
|
|
|
|
CGAL_assertion(she[4]->twin()->snext() == she[3]->twin());
|
|
CGAL_assertion(she[3]->twin()->snext() == she[2]->twin());
|
|
CGAL_assertion(she[2]->twin()->snext() == she[1]->twin());
|
|
if(size == 4)
|
|
CGAL_assertion(she[1]->twin()->snext() == she[4]->twin());
|
|
else {
|
|
CGAL_assertion(she[5]->twin()->snext() == she[4]->twin());
|
|
CGAL_assertion(she[1]->twin()->snext() == she[5]->twin());
|
|
}
|
|
|
|
she[size-1]->circle()= Sphere_circle(Plane_3(SP[0],SP[size-1],Point_3(0,0,0)));
|
|
she[size-1]->twin()->circle() = she[size-1]->circle().opposite();
|
|
she[size-1]->mark() = she[size-1]->twin()->mark() = 1;
|
|
|
|
she[size]->circle()= Sphere_circle(Plane_3(SP[size-1],SP[1],Point_3(0,0,0)));
|
|
she[size]->twin()->circle() = she[size]->circle().opposite();
|
|
she[size]->mark() = she[size]->twin()->mark() = 1;
|
|
|
|
CGAL_NEF_TRACEN("create sfaces");
|
|
SFace_handle sf[3];
|
|
for(int i=0; i<3; ++i)
|
|
sf[i] = SD.new_sface();
|
|
sf[0]->mark()= fmark0;
|
|
sf[1]->mark()= fmark1;
|
|
sf[2]->mark()=0;
|
|
|
|
SD.link_as_face_cycle(she[0],sf[0]);
|
|
SD.link_as_face_cycle(she[0]->twin(),sf[1]);
|
|
SD.link_as_face_cycle(she[1]->twin(),sf[2]);
|
|
|
|
return v;
|
|
}
|
|
|
|
void correct_infibox_sface_marks() {
|
|
Vertex_iterator v;
|
|
CGAL_forall_vertices(v,*this->sncp()) {
|
|
if(is_standard(v) || Infi_box::is_infibox_corner(v->point())) continue;
|
|
SM_decorator SD(&*v);
|
|
SFace_iterator sf;
|
|
CGAL_forall_sfaces(sf, SD)
|
|
sf->volume()->mark() = sf->mark();
|
|
}
|
|
CGAL_forall_vertices(v,*this->sncp()) {
|
|
if(is_standard(v) || !Infi_box::is_infibox_corner(v->point())) continue;
|
|
SM_decorator SD(&*v);
|
|
SFace_iterator sf;
|
|
CGAL_forall_sfaces(sf, SD)
|
|
sf->mark() = sf->volume()->mark();
|
|
}
|
|
}
|
|
|
|
void create_facets_and_volumes_of_halfspace(const Plane_3& h) {
|
|
SHalfedge_handle se =
|
|
this->sncp()->vertices_begin()->shalfedges_begin();
|
|
Halffacet_handle f =
|
|
this->sncp()->new_halffacet_pair(h);
|
|
Volume_handle c0 =
|
|
this->sncp()->new_volume();
|
|
Volume_handle c1 =
|
|
this->sncp()->new_volume();
|
|
|
|
link_as_facet_cycle(se, f->twin());
|
|
link_as_facet_cycle(se->twin(), f);
|
|
f->mark() = f->twin()->mark() = se->mark();
|
|
store_boundary_object(se->incident_sface(), c0);
|
|
store_boundary_object(se->twin()->incident_sface(), c1);
|
|
c0->mark() = se->twin()->incident_sface()->mark();
|
|
c1->mark() = se->incident_sface()->mark();
|
|
f->incident_volume() = c1;
|
|
f->twin()->incident_volume() = c0;
|
|
|
|
SHalfedge_around_facet_circulator
|
|
sfc(se), send(sfc);
|
|
CGAL_For_all(sfc, send) {
|
|
sfc->incident_sface()->volume() = c1;
|
|
sfc->twin()->incident_sface()->volume() = c0;
|
|
}
|
|
|
|
SNC_io_parser<SNC_structure>::dump(*this->sncp(), std::cerr);
|
|
}
|
|
|
|
void correct_infibox_sedge_marks() {
|
|
SHalfedge_iterator se;
|
|
Vertex_iterator v;
|
|
CGAL_forall_vertices(v,*this->sncp()) {
|
|
if(is_standard(v)) continue;
|
|
SM_decorator SD(&*v);
|
|
CGAL_forall_shalfedges(se,SD)
|
|
if(Infi_box::is_sedge_on_infibox(se)) {
|
|
se->mark() = true;
|
|
se->source()->mark() = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
void assign_indices() {}
|
|
|
|
}; // SNC_constructor_base<SNC>
|
|
|
|
template <typename Items, typename SNC_structure_>
|
|
class SNC_constructor : public SNC_constructor_base<Items, SNC_structure_>
|
|
{
|
|
public:
|
|
SNC_constructor( SNC_structure_& W)
|
|
: SNC_constructor_base<Items, SNC_structure_>(W)
|
|
{}
|
|
|
|
};
|
|
|
|
|
|
|
|
template<typename SNC_structure_>
|
|
class SNC_constructor<SNC_indexed_items, SNC_structure_>
|
|
: public SNC_constructor_base<int, SNC_structure_> {
|
|
|
|
typedef SNC_structure_ SNC_structure;
|
|
typedef SNC_constructor_base<int, SNC_structure> Base;
|
|
typedef typename SNC_structure::Sphere_map Sphere_map;
|
|
typedef CGAL::SM_const_decorator<Sphere_map> SM_const_decorator;
|
|
typedef CGAL::SM_decorator<Sphere_map> SM_decorator;
|
|
|
|
public:
|
|
typedef typename SNC_structure::SVertex_iterator SVertex_iterator;
|
|
typedef typename SNC_structure::Halfedge_iterator Halfedge_iterator;
|
|
typedef typename SNC_structure::Halffacet_iterator Halffacet_iterator;
|
|
|
|
typedef typename SNC_structure::Vertex_handle Vertex_handle;
|
|
typedef typename SNC_structure::Halfedge_handle Halfedge_handle;
|
|
typedef typename SNC_structure::Halffacet_handle Halffacet_handle;
|
|
|
|
typedef typename SNC_structure::Vertex_const_handle Vertex_const_handle;
|
|
typedef typename SNC_structure::Halfedge_const_handle Halfedge_const_handle;
|
|
typedef typename SNC_structure::Halffacet_const_handle Halffacet_const_handle;
|
|
typedef typename SNC_structure::SVertex_const_handle SVertex_const_handle;
|
|
typedef typename SNC_structure::SHalfedge_const_handle SHalfedge_const_handle;
|
|
typedef typename SNC_structure::SHalfloop_const_handle SHalfloop_const_handle;
|
|
typedef typename SNC_structure::SFace_const_handle SFace_const_handle;
|
|
|
|
typedef typename SNC_structure::SVertex_handle SVertex_handle;
|
|
typedef typename SNC_structure::SHalfedge_handle SHalfedge_handle;
|
|
typedef typename SNC_structure::SFace_handle SFace_handle;
|
|
typedef typename SNC_structure::SHalfloop_handle SHalfloop_handle;
|
|
|
|
typedef typename SNC_structure::SHalfedge_around_facet_circulator
|
|
SHalfedge_around_facet_circulator;
|
|
typedef typename SNC_structure::SHalfedge_around_facet_const_circulator
|
|
SHalfedge_around_facet_const_circulator;
|
|
typedef typename SNC_structure::SHalfedge_around_svertex_circulator
|
|
SHalfedge_around_svertex_circulator;
|
|
typedef typename SNC_structure::SHalfedge_around_svertex_const_circulator
|
|
SHalfedge_around_svertex_const_circulator;
|
|
typedef typename SNC_structure::SFace_cycle_const_iterator SFace_cycle_const_iterator;
|
|
typedef typename SNC_structure::Halffacet_cycle_iterator Halffacet_cycle_iterator;
|
|
typedef typename SNC_structure::Halffacet_cycle_const_iterator Halffacet_cycle_const_iterator;
|
|
|
|
typedef typename SNC_structure::Point_3 Point_3;
|
|
typedef typename SNC_structure::Vector_3 Vector_3;
|
|
|
|
typedef typename SNC_structure::Sphere_point Sphere_point;
|
|
typedef typename SNC_structure::Sphere_segment Sphere_segment;
|
|
typedef typename SNC_structure::Sphere_circle Sphere_circle;
|
|
|
|
typedef typename SNC_structure::Mark Mark;
|
|
|
|
using Base::create_from_plane;
|
|
|
|
public:
|
|
SNC_constructor( SNC_structure& W) : Base(W) {}
|
|
|
|
Vertex_handle create_from_facet(Halffacet_const_handle f,
|
|
const Point_3& p) {
|
|
|
|
Vertex_handle v = create_from_plane(f->plane(), p,
|
|
f->mark(),
|
|
f->twin()->incident_volume()->mark(),
|
|
f->incident_volume()->mark());
|
|
|
|
v->shalfloop()->set_index_facet(f->twin());
|
|
v->shalfloop()->twin()->set_index_facet(f);
|
|
|
|
SHalfedge_const_handle se = f->twin()->facet_cycles_begin();
|
|
CGAL_assertion(v->shalfloop()->circle() == se->circle());
|
|
v->shalfloop()->set_index(se->get_index());
|
|
v->shalfloop()->twin()->set_index(se->twin()->get_index());
|
|
return v;
|
|
}
|
|
|
|
|
|
Vertex_handle create_from_edge(Halfedge_const_handle e,
|
|
const Point_3& p) {
|
|
|
|
Vertex_handle v = Base::create_from_edge(e,p);
|
|
SVertex_iterator sv = v->svertices_begin();
|
|
|
|
SHalfedge_around_svertex_const_circulator
|
|
ec1(e->out_sedge()), ee(ec1);
|
|
SHalfedge_around_svertex_circulator
|
|
ec2(sv->out_sedge());
|
|
CGAL_For_all(ec1,ee) {
|
|
ec2->set_index_facet(ec1->facet());
|
|
ec2->twin()->set_index_facet(ec1->twin()->facet());
|
|
ec2->set_index(ec1->get_index());
|
|
ec2->twin()->set_index(ec1->twin()->get_index());
|
|
++ec2;
|
|
}
|
|
|
|
sv->set_index(e->get_index());
|
|
++sv;
|
|
sv->set_index(e->get_index());
|
|
|
|
return v;
|
|
}
|
|
|
|
Vertex_handle clone_SM( Vertex_const_handle vin) {
|
|
|
|
#ifdef CGAL_NEF3_TIMER_SPHERE_SWEEPS
|
|
++number_of_clones;
|
|
#endif
|
|
|
|
CGAL::Unique_hash_map<SVertex_const_handle, SVertex_handle> VM;
|
|
CGAL::Unique_hash_map<SHalfedge_const_handle, SHalfedge_handle> EM;
|
|
CGAL::Unique_hash_map<SHalfloop_const_handle, SHalfloop_handle> LM;
|
|
CGAL::Unique_hash_map<SFace_const_handle, SFace_handle> FM;
|
|
|
|
SM_const_decorator E(&*vin);
|
|
Vertex_handle vout = this->sncp()->new_vertex(vin->point(), vin->mark());
|
|
SM_decorator D(&*vout);
|
|
|
|
SVertex_const_handle sv;
|
|
CGAL_forall_svertices(sv, E) {
|
|
VM[sv] = D.new_svertex(sv->point());
|
|
VM[sv]->set_index(sv->get_index());
|
|
}
|
|
|
|
SHalfedge_const_handle se;
|
|
CGAL_forall_sedges(se, E) {
|
|
EM[se] = D.new_shalfedge_pair();
|
|
EM[se->twin()] = EM[se]->twin();
|
|
EM[se]->set_index(se->get_index());
|
|
EM[se->twin()]->set_index(se->twin()->get_index());
|
|
}
|
|
|
|
SFace_const_handle sf;
|
|
CGAL_forall_sfaces(sf, E)
|
|
FM[sf] = D.new_sface();
|
|
|
|
SHalfloop_handle sl;
|
|
if(E.has_shalfloop()) {
|
|
sl = LM[E.shalfloop()] = D.new_shalfloop_pair();
|
|
LM[E.shalfloop()->twin()] = sl->twin();
|
|
D.set_face(sl, FM[E.shalfloop()->incident_sface()]);
|
|
D.set_face(sl->twin(), FM[E.shalfloop()->twin()->incident_sface()]);
|
|
sl->circle() = E.shalfloop()->circle();
|
|
sl->twin()->circle() = E.shalfloop()->twin()->circle();
|
|
sl->mark() = sl->twin()->mark() = E.shalfloop()->mark();
|
|
sl->set_index(E.shalfloop()->get_index());
|
|
sl->twin()->set_index(E.shalfloop()->twin()->get_index());
|
|
}
|
|
|
|
CGAL_forall_svertices(sv, E) {
|
|
D.set_first_out_edge(VM[sv], EM[E.first_out_edge(sv)]);
|
|
D.set_face(VM[sv], FM[sv->incident_sface()]);
|
|
VM[sv]->mark() = sv->mark();
|
|
}
|
|
|
|
CGAL_forall_shalfedges(se, E) {
|
|
EM[se]->mark() = EM[se]->twin()->mark() = se->mark();
|
|
D.set_source(EM[se], VM[se->source()]);
|
|
D.set_prev(EM[se], EM[se->sprev()]);
|
|
D.set_next(EM[se], EM[se->snext()]);
|
|
D.set_face(EM[se], FM[se->incident_sface()]);
|
|
EM[se]->circle() = se->circle();
|
|
}
|
|
|
|
CGAL_forall_sfaces(sf, E) {
|
|
FM[sf]->mark() = sf->mark();
|
|
SFace_cycle_const_iterator sfc;
|
|
for(sfc = sf->sface_cycles_begin(); sfc != sf->sface_cycles_end(); ++sfc) {
|
|
if(sfc.is_svertex())
|
|
D.store_sm_boundary_object(VM[SVertex_const_handle(sfc)], FM[sf]);
|
|
else if(sfc.is_shalfedge())
|
|
D.store_sm_boundary_object(EM[SHalfedge_const_handle(sfc)], FM[sf]);
|
|
else if(sfc.is_shalfloop())
|
|
D.store_sm_boundary_object(LM[SHalfloop_const_handle(sfc)], FM[sf]);
|
|
else CGAL_error_msg("damn wrong handle.");
|
|
}
|
|
}
|
|
|
|
return vout;
|
|
}
|
|
|
|
template<typename Selection, typename Association>
|
|
Sphere_map* create_edge_facet_overlay( Halfedge_const_handle e,
|
|
Halffacet_const_handle f,
|
|
const Point_3& p,
|
|
const Selection& BOP, bool inv,
|
|
Association& A) {
|
|
|
|
#ifdef CGAL_NEF3_TIMER_SPHERE_SWEEPS
|
|
++number_of_edge_facet_overlays;
|
|
#endif
|
|
|
|
CGAL_NEF_TRACEN("edge facet overlay " << p);
|
|
|
|
Unique_hash_map<SHalfedge_handle, Mark> mark_of_right_sface;
|
|
|
|
SM_decorator D(&*this->sncp()->new_vertex(p, BOP(e->mark(), f->mark())));
|
|
SM_const_decorator E(&*e->source());
|
|
|
|
Sphere_point ps = e->point();
|
|
ps = normalized(ps);
|
|
SVertex_handle v1 = D.new_svertex(ps);
|
|
SVertex_handle v2 = D.new_svertex(ps.antipode());
|
|
v1->set_index(e->get_index());
|
|
v2->set_index(e->get_index());
|
|
|
|
CGAL_NEF_TRACEN("new svertex 1 " << ps);
|
|
CGAL_NEF_TRACEN("new svertex 2 " << ps.antipode());
|
|
Halffacet_const_handle faces_p(f);
|
|
Vector_3 vec(ps-CGAL::ORIGIN);
|
|
if(faces_p->plane().oriented_side(p+vec) == ON_NEGATIVE_SIDE)
|
|
faces_p = faces_p->twin();
|
|
v1->mark() = BOP(e->mark(), faces_p->incident_volume()->mark(), inv);
|
|
v2->mark() = BOP(e->mark(), faces_p->twin()->incident_volume()->mark(), inv);
|
|
CGAL_NEF_TRACEN("svertex 1 " << ps << " has mark " << v1->mark());
|
|
CGAL_NEF_TRACEN("svertex 2 " << ps.antipode() << " has mark " << v2->mark());
|
|
|
|
if(E.is_isolated(e)) {
|
|
CGAL_NEF_TRACEN("edge is isolated");
|
|
Mark mf1 = BOP(e->incident_sface()->mark(), faces_p->incident_volume()->mark(), inv);
|
|
Mark mf2 = BOP(e->incident_sface()->mark(), faces_p->twin()->incident_volume()->mark(), inv);
|
|
Mark ml = BOP(e->incident_sface()->mark(), faces_p->mark(), inv);
|
|
|
|
SFace_handle f1 = D.new_sface();
|
|
D.link_as_isolated_vertex(v1, f1);
|
|
f1->mark() = mf1;
|
|
|
|
if(mf1 == mf2 && mf1 == ml) {
|
|
D.link_as_isolated_vertex(v2, f1);
|
|
}
|
|
else {
|
|
SHalfloop_handle l = D.new_shalfloop_pair();
|
|
SFace_handle f2 = D.new_sface();
|
|
D.link_as_isolated_vertex(v2, f2);
|
|
D.link_as_loop(l,f1);
|
|
D.link_as_loop(l->twin(),f2);
|
|
l->circle() = Sphere_circle(CGAL::ORIGIN,faces_p->plane());
|
|
l->twin()->circle() = l->circle().opposite();
|
|
f2->mark() = mf2;
|
|
l->mark() = l->twin()->mark() = ml;
|
|
Halffacet_cycle_const_iterator fci = faces_p->facet_cycles_begin();
|
|
SHalfedge_around_facet_const_circulator sea(fci);
|
|
l->set_index(sea->twin()->get_index());
|
|
l->twin()->set_index(sea->get_index());
|
|
}
|
|
}
|
|
else {
|
|
CGAL_NEF_TRACEN("edge is not isolated");
|
|
SVertex_handle sv;
|
|
SHalfedge_handle se1;
|
|
SHalfedge_handle se2;
|
|
SFace_handle sf;
|
|
Sphere_circle c(CGAL::ORIGIN,f->plane());
|
|
|
|
SHalfedge_handle next_edge;
|
|
SHalfedge_around_svertex_const_circulator ec(E.out_edges(e)), ee(ec);
|
|
CGAL_For_all(ec,ee) {
|
|
Sphere_segment seg(ec->source()->point(),
|
|
ec->source()->point().antipode(),
|
|
ec->circle());
|
|
Sphere_point sp(intersection(c, seg.sphere_circle()));
|
|
CGAL_NEF_TRACEN(seg <<" has_on " << sp);
|
|
if(!seg.has_on_after_intersection(sp))
|
|
sp = sp.antipode();
|
|
sv = D.new_svertex(sp);
|
|
CGAL_NEF_TRACEN("new svertex 3 " << normalized(sp));
|
|
sv->mark() = BOP(ec->mark(), f->mark(), inv);
|
|
Halffacet_const_handle f1, f2;
|
|
if(inv) {
|
|
f1 = f;
|
|
f2 = ec->facet();
|
|
} else {
|
|
f1 = ec->facet();
|
|
f2 = f;
|
|
}
|
|
if(f1->is_twin()) f1 = f1->twin();
|
|
if(f2->is_twin()) f2 = f2->twin();
|
|
A.hash_facet_pair(sv, f1, f2);
|
|
|
|
se1 = D.new_shalfedge_pair(v1, sv);
|
|
if(next_edge == SHalfedge_handle())
|
|
se2 = D.new_shalfedge_pair(sv, v2);
|
|
else
|
|
se2 = D.new_shalfedge_pair(sv, next_edge, -1);
|
|
next_edge = se2->twin();
|
|
se1->mark() = se1->twin()->mark() = BOP(ec->mark(), faces_p->incident_volume()->mark(), inv);
|
|
se2->mark() = se2->twin()->mark() = BOP(ec->mark(), faces_p->twin()->incident_volume()->mark(), inv);
|
|
mark_of_right_sface[se1] = ec->incident_sface()->mark();
|
|
se1->circle() = se2->circle() = ec->circle();
|
|
se1->twin()->circle() = se2->twin()->circle() = se1->circle().opposite();
|
|
se1->set_index(ec->get_index());
|
|
se2->set_index(ec->get_index());
|
|
se1->twin()->set_index(ec->twin()->get_index());
|
|
se2->twin()->set_index(ec->twin()->get_index());
|
|
}
|
|
|
|
SHalfedge_around_svertex_circulator ec2(D.out_edges(v1)), ee2(ec2);
|
|
CGAL_For_all(ec2,ee2) {
|
|
SHalfedge_around_svertex_circulator en(ec2);
|
|
++en;
|
|
se1 = D.new_shalfedge_pair(ec2->twin(), en->twin(), -1, 1);
|
|
CGAL_NEF_TRACEN("new edge pair " << ec2->twin()->source()->vector() <<
|
|
" -> " << en->twin()->source()->vector());
|
|
se1->circle() = Sphere_circle(CGAL::ORIGIN,faces_p->plane());
|
|
se1->twin()->circle() = se1->circle().opposite();
|
|
se1->mark() = se1->twin()->mark() = BOP(mark_of_right_sface[ec2], faces_p->mark(), inv);
|
|
|
|
Halffacet_cycle_const_iterator fci = faces_p->facet_cycles_begin();
|
|
SHalfedge_around_facet_const_circulator sea(fci);
|
|
se1->set_index(sea->twin()->get_index());
|
|
se1->twin()->set_index(sea->get_index());
|
|
|
|
sf = D.new_sface();
|
|
sf->mark() = BOP(mark_of_right_sface[ec2], faces_p->incident_volume()->mark(), inv);
|
|
D.link_as_face_cycle(se1,sf);
|
|
sf = D.new_sface();
|
|
sf->mark() = BOP(mark_of_right_sface[ec2], faces_p->twin()->incident_volume()->mark(), inv);
|
|
D.link_as_face_cycle(se1->twin(),sf);
|
|
}
|
|
}
|
|
|
|
return D.sphere_map();
|
|
}
|
|
|
|
void assign_indices() {
|
|
|
|
Halfedge_iterator e;
|
|
CGAL_forall_edges(e, *this->sncp()) {
|
|
e->twin()->set_index(e->new_index());
|
|
}
|
|
|
|
Halffacet_iterator f;
|
|
CGAL_forall_halffacets(f, *this->sncp()) {
|
|
Halffacet_cycle_iterator fci(f->facet_cycles_begin());
|
|
SHalfedge_handle se(fci);
|
|
int index(se->new_index());
|
|
for(; fci != f->facet_cycles_end(); ++fci) {
|
|
if(fci.is_shalfedge()) {
|
|
SHalfedge_around_facet_circulator c1(fci), c2(c1);
|
|
CGAL_For_all(c1,c2) {
|
|
c1->set_index(index);
|
|
}
|
|
} else if(fci.is_shalfloop()) {
|
|
SHalfloop_handle sl(fci);
|
|
sl->set_index(index);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
} //namespace CGAL
|
|
#endif //CGAL_SNC_CONSTRUCTOR_H
|