mirror of https://github.com/CGAL/cgal
1251 lines
44 KiB
C++
1251 lines
44 KiB
C++
#ifndef CGAL_NEF_GAUSIAN_MAP
|
|
#define CGAL_NEF_GAUSIAN_MAP
|
|
|
|
#include <CGAL/Nef_S2/SM_items.h>
|
|
#include <CGAL/Nef_S2/Sphere_map.h>
|
|
#include <CGAL/Nef_S2/Sphere_geometry.h>
|
|
#include <CGAL/Nef_S2/SM_decorator.h>
|
|
#include <CGAL/Nef_S2/SM_io_parser.h>
|
|
#include <CGAL/Nef_polyhedron_S2.h>
|
|
#include <CGAL/Nef_S2/PointMark.h>
|
|
|
|
#include <CGAL/IO/Qt_widget_Nef_S2.h>
|
|
#include <qapplication.h>
|
|
|
|
#undef CGAL_NEF_DEBUG
|
|
#define CGAL_NEF_DEBUG 223
|
|
#include <CGAL/Nef_2/debug.h>
|
|
|
|
CGAL_BEGIN_NAMESPACE
|
|
|
|
|
|
template <class K, class Mark_ = PointMark<K> >
|
|
class Gausian_map :
|
|
public CGAL::SM_decorator<CGAL::Sphere_map<CGAL::Sphere_geometry<K>,
|
|
CGAL::SM_items, Mark_> > {
|
|
|
|
typedef K Kernel;
|
|
typedef CGAL::Sphere_geometry<K> Sphere_kernel;
|
|
typedef typename Kernel::Point_3 Point_3;
|
|
typedef typename Kernel::Vector_3 Vector_3;
|
|
typedef Mark_ Mark;
|
|
typedef CGAL::Sphere_map<Sphere_kernel,
|
|
CGAL::SM_items, Mark> Sphere_map;
|
|
typedef CGAL::SM_decorator<Sphere_map> SM_decorator;
|
|
typedef SM_decorator Base;
|
|
typedef CGAL::SM_overlayer<SM_decorator> SM_overlayer;
|
|
typedef typename Sphere_kernel::Sphere_circle Sphere_circle;
|
|
public:
|
|
typedef typename Sphere_map::SVertex_handle SVertex_handle;
|
|
typedef typename Sphere_map::SHalfedge_handle SHalfedge_handle;
|
|
typedef typename Sphere_map::SFace_handle SFace_handle;
|
|
typedef typename Sphere_map::SFace_iterator SFace_iterator;
|
|
typedef typename Sphere_map::SHalfedge_iterator SHalfedge_iterator;
|
|
typedef typename Sphere_map::SVertex_iterator SVertex_iterator;
|
|
typedef typename Sphere_map::SVertex_const_iterator SVertex_const_iterator;
|
|
typedef typename Sphere_map::SVertex_const_handle SVertex_const_handle;
|
|
typedef typename Sphere_map::SFace_cycle_iterator SFace_cycle_iterator;
|
|
typedef typename Sphere_map::SHalfedge_around_svertex_circulator
|
|
SHalfedge_around_svertex_circulator;
|
|
typedef typename Sphere_map::SHalfedge_around_sface_circulator
|
|
SHalfedge_around_sface_circulator;
|
|
typedef typename Sphere_map::SHalfedge_around_sface_const_circulator
|
|
SHalfedge_around_sface_const_circulator;
|
|
|
|
typedef typename Sphere_map::Object_handle Object_handle;
|
|
|
|
template<typename Nef_polyhedron_3>
|
|
class SVertex_creator2 {
|
|
|
|
typedef typename Nef_polyhedron_3::Vertex_const_handle Vertex_const_handle;
|
|
typedef typename Nef_polyhedron_3::Halffacet_const_handle Halffacet_const_handle;
|
|
typedef typename Nef_polyhedron_3::Halfedge_const_handle Halfedge_const_handle;
|
|
typedef typename Nef_polyhedron_3::SHalfedge_const_handle SHalfedge_const_handle;
|
|
typedef typename Nef_polyhedron_3::SHalfloop_const_handle SHalfloop_const_handle;
|
|
typedef typename Nef_polyhedron_3::SFace_const_handle SFace_const_handle;
|
|
|
|
typedef CGAL::Unique_hash_map<Halffacet_const_handle, SVertex_handle> Facet2SVertex_hash;
|
|
|
|
SM_decorator SM;
|
|
Facet2SVertex_hash& Facet2SVertex;
|
|
|
|
public:
|
|
SVertex_creator2(Sphere_map* smap, Facet2SVertex_hash& F2SV)
|
|
: SM(smap), Facet2SVertex(F2SV) {}
|
|
|
|
void visit(Vertex_const_handle v) {}
|
|
void visit(Halfedge_const_handle e) {}
|
|
void visit(SHalfedge_const_handle se) {}
|
|
void visit(SHalfloop_const_handle sl) {}
|
|
void visit(SFace_const_handle sf) {}
|
|
void visit(Halffacet_const_handle f) {
|
|
|
|
CGAL_NEF_TRACEN( "SVertex_creator2 " << f->twin()->plane() );
|
|
SVertex_handle sv
|
|
(SM.new_svertex(normalized(f->twin()->plane().orthogonal_vector())));
|
|
sv->mark() = Mark(Point_3(0,0,0), f->mark());
|
|
Facet2SVertex[f] = sv;
|
|
}
|
|
|
|
};
|
|
|
|
template<typename Nef_polyhedron_3>
|
|
class SVertex_creator {
|
|
|
|
typedef typename Nef_polyhedron_3::Vertex_const_handle Vertex_const_handle;
|
|
typedef typename Nef_polyhedron_3::Halffacet_const_handle Halffacet_const_handle;
|
|
typedef typename Nef_polyhedron_3::Halfedge_const_handle Halfedge_const_handle;
|
|
typedef typename Nef_polyhedron_3::SHalfedge_const_handle SHalfedge_const_handle;
|
|
typedef typename Nef_polyhedron_3::SHalfloop_const_handle SHalfloop_const_handle;
|
|
typedef typename Nef_polyhedron_3::SFace_const_handle SFace_const_handle;
|
|
|
|
typedef typename Nef_polyhedron_3::Halffacet_cycle_const_iterator
|
|
Halffacet_cycle_const_iterator;
|
|
typedef typename Nef_polyhedron_3::SHalfedge_around_facet_const_circulator
|
|
SHalfedge_around_facet_const_circulator;
|
|
|
|
typedef typename Nef_polyhedron_3::Point_3 Point_3;
|
|
typedef typename Nef_polyhedron_3::Sphere_point Sphere_point;
|
|
|
|
typedef CGAL::Unique_hash_map<Halffacet_const_handle, SVertex_handle> Facet2SVertex_hash;
|
|
typedef CGAL::Unique_hash_map<Halffacet_const_handle, bool> Facet2bool_hash;
|
|
typedef CGAL::Unique_hash_map<Vertex_const_handle, bool> Vertex2bool_hash;
|
|
typedef CGAL::Unique_hash_map<Halfedge_const_handle, bool> Edge2bool_hash;
|
|
typedef CGAL::Unique_hash_map<SHalfedge_const_handle, SHalfedge_const_handle> SEdge2SEdge_hash;
|
|
typedef CGAL::Unique_hash_map<SFace_const_handle, bool> SFace2bool_hash;
|
|
|
|
SM_decorator SM;
|
|
Facet2SVertex_hash& Facet2SVertex;
|
|
Facet2bool_hash& omit_facet;
|
|
SEdge2SEdge_hash& next;
|
|
Vertex2bool_hash& omit_vertex;
|
|
Edge2bool_hash& omit_edge;
|
|
SFace2bool_hash& Shell;
|
|
|
|
public:
|
|
SVertex_creator(Sphere_map* smap, Facet2SVertex_hash& F2SV, Facet2bool_hash& F2b, SEdge2SEdge_hash& SE2SE, Vertex2bool_hash& V2b, Edge2bool_hash& E2b, SFace2bool_hash& SHELL)
|
|
: SM(smap), Facet2SVertex(F2SV), omit_facet(F2b), next(SE2SE), omit_vertex(V2b), omit_edge(E2b), Shell(SHELL) {}
|
|
|
|
private:
|
|
bool svertex_exists(Sphere_point sp, SVertex_handle& sv) {
|
|
SVertex_iterator svi;
|
|
sp = normalized(sp);
|
|
CGAL_forall_svertices(svi, SM) {
|
|
if(svi->point() == sp) {
|
|
sv = svi;
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public:
|
|
void visit(Vertex_const_handle v) { CGAL_NEF_TRACEN( "Vertices " << v->point() );}
|
|
void visit(Halfedge_const_handle e) {}
|
|
void visit(SHalfedge_const_handle se) {}
|
|
void visit(SHalfloop_const_handle sl) {}
|
|
void visit(SFace_const_handle sf) {
|
|
|
|
typename Nef_polyhedron_3::SHalfedge_const_handle sec = sf->sface_cycles_begin();
|
|
|
|
int circles = 1;
|
|
Sphere_circle first, current;
|
|
first = current = sec->circle();
|
|
CGAL_NEF_TRACEN( "first+current:" << first << "+" << current );
|
|
typename Nef_polyhedron_3::SHalfedge_around_sface_const_circulator sfc(sec), send(sfc);
|
|
CGAL_For_all(sfc, send) {
|
|
CGAL_NEF_TRACEN( "sedge->cirlce() " << sfc->circle() );
|
|
if(sfc->circle() != current) {
|
|
if(sfc->circle() != first)
|
|
++circles;
|
|
current = sfc->circle();
|
|
}
|
|
}
|
|
|
|
CGAL_NEF_TRACEN( "first+current:" << first << "+" << current );
|
|
CGAL_NEF_TRACEN( "circles " << circles );
|
|
|
|
if(circles < 3)
|
|
omit_vertex[sf->center_vertex()] = true;
|
|
}
|
|
|
|
void visit(Halffacet_const_handle f) {
|
|
|
|
CGAL_NEF_TRACEN( "SVertex_creator " << f->twin()->plane() );
|
|
|
|
Halffacet_cycle_const_iterator fc = f->twin()->facet_cycles_begin();
|
|
SHalfedge_const_handle se(fc);
|
|
SHalfedge_around_facet_const_circulator hc(se), hend(hc);
|
|
|
|
bool verge_found(false);
|
|
CGAL_For_all(hc,hend) {
|
|
Point_3 p(hc->source()->source()->point());
|
|
CGAL_NEF_TRACEN(" hc " << CGAL::to_double(p.hx()) <<
|
|
" " << CGAL::to_double(p.hy()) <<
|
|
" " << CGAL::to_double(p.hz()));
|
|
CGAL_NEF_TRACEN(" hc->snext()->circle() " << normalized(hc->snext()->circle()));
|
|
if(normalized(hc->snext()->circle()) == normalized(hc->circle())) {
|
|
next[hc] = hc->snext();
|
|
CGAL_NEF_TRACEN( "set next " << hc->source()->source()->point() << ":"
|
|
<< hc->source()->point() << "->" << hc->twin()->source()->point() << " | "
|
|
<< hc->snext()->source()->point() << "->" << hc->snext()->twin()->source()->point() );
|
|
omit_edge[hc->twin()->source()] = omit_edge[hc->twin()->source()->twin()] = true;
|
|
} else
|
|
verge_found = true;
|
|
}
|
|
|
|
if(!verge_found) {
|
|
omit_facet[f] = true;
|
|
return;
|
|
}
|
|
|
|
SVertex_handle sv;
|
|
if(!svertex_exists(f->twin()->plane().orthogonal_vector(), sv)) {
|
|
sv = SM.new_svertex(f->twin()->plane().orthogonal_vector());
|
|
sv->point() = normalized(sv->point());
|
|
sv->mark() = Mark(Point_3(0,0,0), f->mark());
|
|
} else {
|
|
omit_facet[f] = true;
|
|
if(sv->mark().boolean() && !f->mark())
|
|
sv->mark().set_boolean(false);
|
|
CGAL_NEF_TRACEN("omit facet " << f->plane());
|
|
}
|
|
Facet2SVertex[f] = sv;
|
|
}
|
|
};
|
|
|
|
template<typename Nef_polyhedron_3>
|
|
class SEdge_creator2 {
|
|
|
|
typedef typename Nef_polyhedron_3::Vertex_const_handle Vertex_const_handle;
|
|
typedef typename Nef_polyhedron_3::Halffacet_const_handle Halffacet_const_handle;
|
|
typedef typename Nef_polyhedron_3::Halfedge_const_handle Halfedge_const_handle;
|
|
typedef typename Nef_polyhedron_3::SHalfedge_const_handle SHalfedge_const_handle;
|
|
typedef typename Nef_polyhedron_3::SHalfloop_const_handle SHalfloop_const_handle;
|
|
typedef typename Nef_polyhedron_3::SFace_const_handle SFace_const_handle;
|
|
|
|
typedef typename SM_decorator::SHalfedge_around_svertex_circulator
|
|
SHalfedge_around_svertex_circulator;
|
|
|
|
typedef typename Nef_polyhedron_3::Halffacet_cycle_const_iterator
|
|
Halffacet_cycle_const_iterator;
|
|
typedef typename Nef_polyhedron_3::SHalfedge_around_facet_const_circulator
|
|
SHalfedge_around_facet_const_circulator;
|
|
|
|
typedef CGAL::Unique_hash_map<Halfedge_const_handle, SHalfedge_handle> Edge2SEdge_hash;
|
|
typedef CGAL::Unique_hash_map<Halffacet_const_handle, SVertex_handle> Facet2SVertex_hash;
|
|
|
|
SM_decorator SM;
|
|
Edge2SEdge_hash& Edge2SEdge;
|
|
Facet2SVertex_hash& Facet2SVertex;
|
|
|
|
public:
|
|
SEdge_creator2(Sphere_map* smap, Edge2SEdge_hash& E2SE, Facet2SVertex_hash& F2SV)
|
|
: SM(smap), Edge2SEdge(E2SE), Facet2SVertex(F2SV) {}
|
|
|
|
public:
|
|
void visit(Vertex_const_handle v) {}
|
|
void visit(Halfedge_const_handle e) {}
|
|
void visit(SHalfedge_const_handle se) {}
|
|
void visit(SHalfloop_const_handle sl) {}
|
|
void visit(SFace_const_handle sf) {}
|
|
|
|
void visit(Halffacet_const_handle f) {
|
|
|
|
CGAL_NEF_TRACEN( "SEdge_creator2 " << f->twin()->plane() );
|
|
Halffacet_cycle_const_iterator fc = f->twin()->facet_cycles_begin();
|
|
SHalfedge_const_handle sef(fc);
|
|
SHalfedge_around_facet_const_circulator hc(sef), hend(hc);
|
|
|
|
CGAL_For_all(hc, hend) {
|
|
if(hc->sprev()->facet()->plane() ==
|
|
hc->facet()->plane())
|
|
continue;
|
|
SHalfedge_handle thetwin;
|
|
Halfedge_const_handle e(hc->source()->twin());
|
|
SHalfedge_handle set = Edge2SEdge[e];
|
|
if(set == SHalfedge_handle()) {
|
|
thetwin = SM.new_shalfedge_pair_at_source(Facet2SVertex[f],1);
|
|
CGAL_NEF_TRACEN("add stub " << Facet2SVertex[f]->point()
|
|
<< "->" << hc->twin()->snext()->facet()->plane().orthogonal_vector());
|
|
} else {
|
|
SM.link_as_target_and_append(Facet2SVertex[f], set);
|
|
set->mark() = set->twin()->mark() = Mark(Point_3(0,0,0), e->mark());
|
|
set->circle() = Sphere_circle(set->source()->point(), set->twin()->source()->point());
|
|
set->twin()->circle() = set->circle().opposite();
|
|
thetwin = set->twin();
|
|
CGAL_NEF_TRACEN("complete edge " << set->source()->point()
|
|
<< "->" << set->twin()->source()->point());
|
|
}
|
|
Edge2SEdge[hc->source()] = thetwin;
|
|
}
|
|
// CGAL::SM_io_parser<SM_decorator> O(std::cerr,SM);
|
|
// O.print();
|
|
}
|
|
};
|
|
|
|
template<typename Nef_polyhedron_3>
|
|
class SEdge_creator {
|
|
|
|
typedef typename Nef_polyhedron_3::Vertex_const_handle Vertex_const_handle;
|
|
typedef typename Nef_polyhedron_3::Halffacet_const_handle Halffacet_const_handle;
|
|
typedef typename Nef_polyhedron_3::Halfedge_const_handle Halfedge_const_handle;
|
|
typedef typename Nef_polyhedron_3::SHalfedge_const_handle SHalfedge_const_handle;
|
|
typedef typename Nef_polyhedron_3::SHalfloop_const_handle SHalfloop_const_handle;
|
|
typedef typename Nef_polyhedron_3::SFace_const_handle SFace_const_handle;
|
|
|
|
typedef typename SM_decorator::SHalfedge_around_svertex_circulator
|
|
SHalfedge_around_svertex_circulator;
|
|
|
|
typedef typename Nef_polyhedron_3::Halffacet_cycle_const_iterator
|
|
Halffacet_cycle_const_iterator;
|
|
typedef typename Nef_polyhedron_3::SHalfedge_around_facet_const_circulator
|
|
SHalfedge_around_facet_const_circulator;
|
|
|
|
typedef typename Nef_polyhedron_3::Sphere_point Sphere_point;
|
|
|
|
typedef CGAL::Unique_hash_map<Halfedge_const_handle, SHalfedge_handle> Edge2SEdge_hash;
|
|
typedef CGAL::Unique_hash_map<Halffacet_const_handle, SVertex_handle> Facet2SVertex_hash;
|
|
typedef CGAL::Unique_hash_map<Halffacet_const_handle, bool> Facet2bool_hash;
|
|
typedef CGAL::Unique_hash_map<Halfedge_const_handle, bool> Edge2bool_hash;
|
|
typedef CGAL::Unique_hash_map<SHalfedge_const_handle, SHalfedge_const_handle> SEdge2SEdge_hash;
|
|
|
|
SM_decorator SM;
|
|
Edge2SEdge_hash& Edge2SEdge;
|
|
Facet2SVertex_hash& Facet2SVertex;
|
|
SEdge2SEdge_hash& next;
|
|
Facet2bool_hash& omit_facet;
|
|
Edge2bool_hash& omit_edge;
|
|
|
|
public:
|
|
SEdge_creator(Sphere_map* smap, Edge2SEdge_hash& E2SE, Facet2SVertex_hash& F2SV, SEdge2SEdge_hash& SE2SE, Facet2bool_hash& F2b, Edge2bool_hash& E2b)
|
|
: SM(smap), Edge2SEdge(E2SE), Facet2SVertex(F2SV), next(SE2SE), omit_facet(F2b), omit_edge(E2b) {}
|
|
|
|
public:
|
|
void visit(Vertex_const_handle v) {}
|
|
void visit(Halfedge_const_handle e) {}
|
|
void visit(SHalfedge_const_handle se) {}
|
|
void visit(SHalfloop_const_handle sl) {}
|
|
void visit(SFace_const_handle sf) {}
|
|
|
|
void visit(Halffacet_const_handle f) {
|
|
|
|
if(omit_facet[f]) {
|
|
CGAL_NEF_TRACEN( "omit facet " <<
|
|
normalized(Sphere_point(f->twin()->plane().orthogonal_vector())));
|
|
return;
|
|
}
|
|
|
|
CGAL_NEF_TRACEN( "SEdge_creator " <<
|
|
normalized(Sphere_point(f->twin()->plane().orthogonal_vector())));
|
|
Halffacet_cycle_const_iterator fc = f->twin()->facet_cycles_begin();
|
|
SHalfedge_const_handle se(fc);
|
|
SHalfedge_around_facet_const_circulator hc(se), hend(hc);
|
|
|
|
|
|
while(hc->snext()->circle() == hc->circle()) ++hc;
|
|
CGAL_NEF_TRACEN("verge " << hc->circle() <<
|
|
" " << hc->snext()->circle());
|
|
// Found first edge such that next is not defined
|
|
Halfedge_const_handle last = hc->twin()->source();
|
|
do {
|
|
++hc;
|
|
while(next[hc]!=SHalfedge_const_handle()) hc = next[hc];
|
|
} while(normalized(hc->twin()->source()->point()) ==
|
|
normalized(last->point()));
|
|
last = hc->twin()->source();
|
|
// now last has a good value
|
|
Halfedge_const_handle etwin;
|
|
do {
|
|
++hc;
|
|
etwin = hc->source();
|
|
while(next[hc]!=SHalfedge_const_handle()) hc = next[hc];
|
|
} while(normalized(hc->twin()->source()->point()) ==
|
|
normalized(last->point()));
|
|
// hc is now one interesting corner further than last
|
|
hend = hc;
|
|
|
|
|
|
SHalfedge_handle thetwin;
|
|
do {
|
|
/// CGAL_NEF_TRACEN( "edge " << hc->source()->source()->point()
|
|
// << ":" << hc->source()->point() );
|
|
Halfedge_const_handle e = hc->twin()->source();
|
|
CGAL_NEF_TRACEN(" check next " << &*next[hc]);
|
|
CGAL_NEF_TRACEN(" check plane " << hc->facet()->plane());
|
|
if(normalized(e->point()) != normalized(last->point())) {
|
|
Edge2SEdge[etwin] = thetwin;
|
|
SHalfedge_handle set = Edge2SEdge[e];
|
|
if(set == SHalfedge_handle()) {
|
|
thetwin = SM.new_shalfedge_pair_at_source(Facet2SVertex[f],1);
|
|
CGAL_NEF_TRACEN("add stub " << Facet2SVertex[f]->point()
|
|
<< "->" <<
|
|
normalized(Sphere_point(hc->snext()->facet()->plane().orthogonal_vector())));
|
|
} else {
|
|
SM.link_as_target_and_append(Facet2SVertex[f], set);
|
|
set->mark() = set->twin()->mark() = Mark(Point_3(0,0,0), e->mark());
|
|
set->circle() = Sphere_circle(set->source()->point(), set->twin()->source()->point());
|
|
set->twin()->circle() = set->circle().opposite();
|
|
thetwin = set->twin();
|
|
CGAL_NEF_TRACEN("complete edge " << set->source()->point()
|
|
<< "->" << set->twin()->source()->point());
|
|
}
|
|
last = hc->twin()->source();
|
|
} else CGAL_NEF_TRACEN( "omit " );
|
|
|
|
++hc;
|
|
etwin = hc->source();
|
|
while(next[hc]!=SHalfedge_const_handle()) hc = next[hc];
|
|
} while(hc!=hend);
|
|
Edge2SEdge[etwin] = thetwin;
|
|
|
|
// CGAL::SM_io_parser<SM_decorator> O(std::cerr,SM);
|
|
// O.print();
|
|
|
|
|
|
/*
|
|
do {
|
|
if(!omit_edge[hc->source()]) {
|
|
CGAL_NEF_TRACEN( "edge " << hc->source()->source()->point()
|
|
<< ":" << hc->source()->point() );
|
|
|
|
Halfedge_const_handle e = hc->source();
|
|
SHalfedge_handle set = Edge2SEdge[e->twin()];
|
|
if(set == SHalfedge_handle())
|
|
Edge2SEdge[e] = SM.new_shalfedge_pair_at_source(Facet2SVertex[f],1);
|
|
else {
|
|
SM.link_as_target_and_append(Facet2SVertex[f], set);
|
|
set->mark() = set->twin()->mark() = Mark(Point_3(0,0,0));
|
|
set->circle() = Sphere_circle(set->source()->point(), set->twin()->source()->point());
|
|
set->twin()->circle() = set->circle().opposite();
|
|
Edge2SEdge[e] = set->twin();
|
|
}
|
|
} else {
|
|
CGAL_NEF_TRACEN( "omit edge " << hc->source()->source()->point()
|
|
<< ":" << hc->source()->point() );
|
|
}
|
|
++hc;
|
|
} while(hc != hend);
|
|
*/
|
|
|
|
}
|
|
};
|
|
|
|
template<typename Nef_polyhedron_3>
|
|
class SFace_creator2 {
|
|
|
|
typedef typename Nef_polyhedron_3::Vertex_const_handle Vertex_const_handle;
|
|
typedef typename Nef_polyhedron_3::Halffacet_const_handle Halffacet_const_handle;
|
|
typedef typename Nef_polyhedron_3::Halfedge_const_handle Halfedge_const_handle;
|
|
typedef typename Nef_polyhedron_3::SHalfedge_const_handle SHalfedge_const_handle;
|
|
typedef typename Nef_polyhedron_3::SHalfloop_const_handle SHalfloop_const_handle;
|
|
typedef typename Nef_polyhedron_3::SFace_const_handle SFace_const_handle;
|
|
|
|
typedef typename Nef_polyhedron_3::SFace_cycle_const_iterator SFace_cycle_const_iterator;
|
|
|
|
typedef CGAL::Unique_hash_map<Halfedge_const_handle, SHalfedge_handle> Edge2SEdge_hash;
|
|
|
|
SM_decorator SM;
|
|
Edge2SEdge_hash& Edge2SEdge;
|
|
|
|
public:
|
|
SFace_creator2(Sphere_map* smap, Edge2SEdge_hash& E2SE) :
|
|
SM(smap), Edge2SEdge(E2SE) {}
|
|
|
|
void visit(Halfedge_const_handle e) {}
|
|
void visit(SHalfedge_const_handle se) {}
|
|
void visit(SHalfloop_const_handle sl) {}
|
|
void visit(Halffacet_const_handle f) {}
|
|
void visit(Vertex_const_handle v) {}
|
|
|
|
void visit(SFace_const_handle sf) {
|
|
CGAL_NEF_TRACEN( "SFace_creator2 " << sf->center_vertex()->point() );
|
|
|
|
// CGAL::SM_io_parser<SM_decorator> O(std::cerr,SM);
|
|
// O.print();
|
|
|
|
SFace_cycle_const_iterator sfc(sf->sface_cycles_begin());
|
|
CGAL_assertion(sfc.is_shalfedge());
|
|
SHalfedge_const_handle sef(sfc);
|
|
Halfedge_const_handle e(sef->source());
|
|
SHalfedge_around_sface_circulator
|
|
sec(Edge2SEdge[e]), send(sec);
|
|
CGAL_For_all(sec, send)
|
|
if(sec->source()->point() ==
|
|
sec->twin()->source()->point())
|
|
return;
|
|
SFace_handle sf_new = SM.new_sface();
|
|
sf_new->mark() = Mark(sf->center_vertex()->point(),
|
|
sf->center_vertex()->mark());
|
|
SM.link_as_face_cycle(sec,sf_new);
|
|
}
|
|
};
|
|
|
|
template<typename Nef_polyhedron_3>
|
|
class SFace_creator {
|
|
|
|
typedef typename Nef_polyhedron_3::Vertex_const_handle Vertex_const_handle;
|
|
typedef typename Nef_polyhedron_3::Halffacet_const_handle Halffacet_const_handle;
|
|
typedef typename Nef_polyhedron_3::Halfedge_const_handle Halfedge_const_handle;
|
|
typedef typename Nef_polyhedron_3::SHalfedge_const_handle SHalfedge_const_handle;
|
|
typedef typename Nef_polyhedron_3::SHalfloop_const_handle SHalfloop_const_handle;
|
|
typedef typename Nef_polyhedron_3::SFace_const_handle SFace_const_handle;
|
|
|
|
typedef CGAL::Unique_hash_map<Halfedge_const_handle, SHalfedge_handle> Edge2SEdge_hash;
|
|
typedef CGAL::Unique_hash_map<Vertex_const_handle, bool> Vertex2bool_hash;
|
|
typedef CGAL::Unique_hash_map<SFace_const_handle, bool> SFace2bool_hash;
|
|
|
|
const Nef_polyhedron_3& N3;
|
|
SM_decorator SM;
|
|
Edge2SEdge_hash& Edge2SEdge;
|
|
Vertex2bool_hash& omit_vertex;
|
|
SFace2bool_hash& Shell;
|
|
|
|
public:
|
|
SFace_creator(const Nef_polyhedron_3& N, Sphere_map* smap, Edge2SEdge_hash& E2SE, Vertex2bool_hash& V2b, SFace2bool_hash SHELL) :
|
|
N3(N), SM(smap), Edge2SEdge(E2SE), omit_vertex(V2b), Shell(SHELL) {}
|
|
|
|
void visit(Halfedge_const_handle e) {}
|
|
void visit(SHalfedge_const_handle se) {}
|
|
void visit(SHalfloop_const_handle sl) {}
|
|
void visit(SFace_const_handle sf) {}
|
|
void visit(Halffacet_const_handle f) {}
|
|
|
|
void visit(Vertex_const_handle v) {
|
|
|
|
CGAL_NEF_TRACEN( "SFace_creator " << v->point() );
|
|
|
|
if(omit_vertex[v]) {
|
|
CGAL_NEF_TRACEN("omit " << v->point() );
|
|
return;
|
|
}
|
|
|
|
typename Nef_polyhedron_3::Nef_polyhedron_S2 SD(N3.get_sphere_map(v));
|
|
|
|
/*
|
|
typename Nef_polyhedron_3::SFace_const_iterator sf = SD.sfaces_begin();
|
|
while(sf != SD.sfaces_end() && !Shell[sf]) ++sf;
|
|
CGAL_assertion(sf != SD.sfaces_end());
|
|
*/
|
|
|
|
typename Nef_polyhedron_3::Halfedge_const_iterator ei(SD.svertices_begin());
|
|
SHalfedge_handle se = Edge2SEdge[ei];
|
|
while(se == SHalfedge_handle()) {
|
|
++ei;
|
|
se = Edge2SEdge[ei];
|
|
}
|
|
|
|
CGAL_assertion(ei != SD.svertices_end());
|
|
|
|
SFace_handle sf_new = SM.new_sface();
|
|
sf_new->mark() = Mark(v->point(), v->mark());
|
|
SM.link_as_face_cycle(se,sf_new);
|
|
}
|
|
};
|
|
|
|
struct VECTOR_ADDITION {
|
|
Mark operator()(const Mark& b1, const Mark& b2) const {
|
|
return b1+b2;
|
|
}
|
|
};
|
|
|
|
Object_handle top;
|
|
Object_handle bottom;
|
|
|
|
void locate_top_and_bottom() {
|
|
std::vector<SFace_iterator> topSF;
|
|
std::vector<SFace_iterator> bottomSF;
|
|
SFace_iterator sfi = this->sfaces_begin();
|
|
topSF.push_back(sfi);
|
|
bottomSF.push_back(sfi);
|
|
|
|
Comparison_result cr;
|
|
for(++sfi;sfi != this->sfaces_end(); ++sfi) {
|
|
cr = compare_z(sfi->mark(), (*topSF.begin())->mark());
|
|
if(cr != CGAL::SMALLER) {
|
|
if(cr == CGAL::LARGER)
|
|
topSF.clear();
|
|
topSF.push_back(sfi);
|
|
}
|
|
cr = compare_z(sfi->mark(), (*bottomSF.begin())->mark());
|
|
if(cr != CGAL::LARGER) {
|
|
if(cr == CGAL::SMALLER)
|
|
bottomSF.clear();
|
|
bottomSF.push_back(sfi);
|
|
}
|
|
}
|
|
|
|
SFace_handle sf(topSF.front());
|
|
if(topSF.size()==1)
|
|
top = Object_handle(SFace_const_handle(sf));
|
|
else {
|
|
SHalfedge_handle se(sf->sface_cycles_begin());
|
|
SHalfedge_around_sface_circulator sfc(se), sfend(sfc);
|
|
|
|
if(topSF.size()==2) {
|
|
while(sfc->circle().c()!=0) {
|
|
++sfc;
|
|
CGAL_assertion(sfc != sfend);
|
|
}
|
|
top = Object_handle(SHalfedge_const_handle(sfc));
|
|
} else {
|
|
CGAL_assertion(topSF.size() > 0);
|
|
while(sfc->source()->point().hx()!=0 ||
|
|
sfc->source()->point().hy()!=0 ||
|
|
sfc->source()->point().hz()<=0) {
|
|
++sfc;
|
|
CGAL_assertion(sfc != sfend);
|
|
}
|
|
top = Object_handle(SVertex_const_handle(sfc->source()));
|
|
}
|
|
}
|
|
|
|
sf = bottomSF.front();
|
|
if(bottomSF.size()==1)
|
|
bottom = Object_handle(SFace_const_handle(sf));
|
|
else {
|
|
SHalfedge_handle se(sf->sface_cycles_begin());
|
|
SHalfedge_around_sface_circulator sfc(se), sfend(sfc);
|
|
|
|
if(bottomSF.size()==2) {
|
|
while(sfc->circle().c()!=0) {
|
|
++sfc;
|
|
CGAL_assertion(sfc != sfend);
|
|
}
|
|
bottom = Object_handle(SHalfedge_const_handle(sfc));
|
|
} else {
|
|
CGAL_assertion(bottomSF.size() > 0);
|
|
while(sfc->source()->point().hx()!=0 ||
|
|
sfc->source()->point().hy()!=0 ||
|
|
sfc->source()->point().hz()>=0) {
|
|
++sfc;
|
|
CGAL_assertion(sfc != sfend);
|
|
}
|
|
bottom = Object_handle(SVertex_const_handle(sfc->source()));
|
|
}
|
|
}
|
|
}
|
|
|
|
void erase_redundant_vertices() {
|
|
|
|
std::cerr << "erase redundant vertices " << std::endl;
|
|
|
|
/*
|
|
SVertex_iterator svi;
|
|
CGAL_forall_svertices(svi, *this) {
|
|
bool erase(true);
|
|
SHalfedge_around_svertex_circulator
|
|
svc(svi->out_sedge()), send(svc);
|
|
CGAL_For_all(svc, send) {
|
|
if(svc->incident_sface() != SFace_handle() ||
|
|
svc->twin()->incident_sface() != SFace_handle()) {
|
|
erase = false;
|
|
break;
|
|
}
|
|
}
|
|
if(!erase) continue;
|
|
SHalfedge_handle se(svi->out_sedge());
|
|
while(se->twin()->snext() != se) {
|
|
SHalfedge_handle se_next(se->twin()->snext());
|
|
delete_edge_pair(se);
|
|
se = se_next;
|
|
}
|
|
delete_edge_pair(se);
|
|
delete_vertex_only(svi);
|
|
}
|
|
*/
|
|
|
|
std::list<SHalfedge_handle> redundant;
|
|
SHalfedge_iterator sei;
|
|
CGAL_forall_sedges(sei, *this) {
|
|
if(sei->source()->point() ==
|
|
sei->twin()->source()->point()) {
|
|
redundant.push_back(sei);
|
|
}
|
|
}
|
|
|
|
CGAL::Unique_hash_map<SHalfedge_handle, bool> erased(false);
|
|
typename std::list<SHalfedge_handle>::iterator ri;
|
|
for(ri = redundant.begin(); ri != redundant.end(); ++ri) {
|
|
if(erased[(*ri)]) continue;
|
|
|
|
// CGAL::SM_io_parser<SM_decorator> O(std::cerr, *this);
|
|
// O.print();
|
|
|
|
SVertex_handle src((*ri)->source());
|
|
SVertex_handle tgt((*ri)->twin()->source());
|
|
|
|
std::cerr << "erase " << src->point() << std::endl;
|
|
std::cerr << &*src << " " << &*tgt << std::endl;
|
|
|
|
SHalfedge_handle prev((*ri)->sprev());
|
|
SHalfedge_handle next((*ri)->snext());
|
|
|
|
std::cerr << "prev " << &*prev->source()
|
|
<< "->" << &*prev->twin()->source() << std::endl;
|
|
std::cerr << "next " << &*next->source()
|
|
<< "->" << &*next->twin()->source() << std::endl;
|
|
|
|
if(prev->source() ==
|
|
next->twin()->source()) {
|
|
std::cerr << "delete before" << std::endl;
|
|
SHalfedge_handle sein;
|
|
SHalfedge_handle se_cas(next->twin()->snext());
|
|
SFace_handle sf(next->twin()->incident_sface());
|
|
if(sf != SFace_handle()) {
|
|
std::cerr << "not null " << std::endl;
|
|
SFace_cycle_iterator sfci(sf->sface_cycles_begin());
|
|
CGAL_assertion(sfci.is_shalfedge());
|
|
sein = sfci;
|
|
undo_sm_boundary_object(sein, sf);
|
|
sein = next->twin()->sprev();
|
|
std::cerr << "sein " << sein->source()->point()
|
|
<< "->" << sein->twin()->source()->point()
|
|
<< std::endl;
|
|
}
|
|
erased[next] = erased[next->twin()] = true;
|
|
delete_edge_pair(next);
|
|
next = se_cas;
|
|
if(sf != SFace_handle()) {
|
|
// CGAL::SM_io_parser<SM_decorator> Oy(std::cerr, *this);
|
|
// Oy.print();
|
|
std::cerr << "sein " << sein->source()->point()
|
|
<< "->" << sein->twin()->source()->point()
|
|
<< std::endl;
|
|
link_as_face_cycle(sein, sf);
|
|
}
|
|
}
|
|
|
|
std::cerr << "prev " << &*prev->source()
|
|
<< "->" << &*prev->twin()->source() << std::endl;
|
|
std::cerr << "next " << &*next->source()
|
|
<< "->" << &*next->twin()->source() << std::endl;
|
|
|
|
prev->snext() = next;
|
|
next->sprev() = prev;
|
|
|
|
// CGAL::SM_io_parser<SM_decorator> Ox(std::cerr, *this);
|
|
// Ox.print();
|
|
|
|
SHalfedge_handle tprev((*ri)->twin()->sprev());
|
|
SHalfedge_handle tnext((*ri)->twin()->snext());
|
|
if(tprev->source() ==
|
|
tnext->twin()->source()) {
|
|
std::cerr << "delete twin" << std::endl;
|
|
SHalfedge_handle sein;
|
|
SHalfedge_handle se_cap(tprev->twin()->sprev());
|
|
SFace_handle sf(tprev->twin()->incident_sface());
|
|
if(sf != SFace_handle()) {
|
|
SFace_cycle_iterator sfci(sf->sface_cycles_begin());
|
|
CGAL_assertion(sfci.is_shalfedge());
|
|
sein=sfci;
|
|
undo_sm_boundary_object(sein, sf);
|
|
sein = tprev->twin()->snext();
|
|
}
|
|
erased[tprev] = erased[tprev->twin()] = true;
|
|
delete_edge_pair(tprev);
|
|
tprev = se_cap;
|
|
if(sf != SFace_handle())
|
|
link_as_face_cycle(sein, sf);
|
|
}
|
|
tprev->snext() = tnext;
|
|
tnext->sprev() = tprev;
|
|
|
|
std::cerr << "tprev " << &*tprev->source()
|
|
<< "->" << &*tprev->twin()->source() << std::endl;
|
|
std::cerr << "tnext " << &*tnext->source()
|
|
<< "->" << &*tnext->twin()->source() << std::endl;
|
|
|
|
while(next != tnext) {
|
|
std::cerr << "next " << &*next->source()
|
|
<< "->" << &*next->twin()->source() << std::endl;
|
|
SHalfedge_handle se_cas(next->twin()->snext());
|
|
next->source() = src;
|
|
next = se_cas;
|
|
}
|
|
delete_edge_pair_only(*ri);
|
|
delete_vertex_only(tgt);
|
|
}
|
|
}
|
|
|
|
public:
|
|
Gausian_map() : Base(new Sphere_map) {}
|
|
|
|
template<typename NK, typename Items>
|
|
Gausian_map(const CGAL::Nef_polyhedron_3<NK, Items>& N3,
|
|
typename CGAL::Nef_polyhedron_3<NK, Items>::Volume_const_iterator c) : Base(new Sphere_map) {
|
|
|
|
typedef CGAL::Nef_polyhedron_3<NK, Items> Nef_polyhedron_3;
|
|
typedef typename Nef_polyhedron_3::Vertex_const_iterator
|
|
Vertex_const_iterator;
|
|
typedef typename Nef_polyhedron_3::Halffacet_const_iterator
|
|
Halffacet_const_iterator;
|
|
typedef typename Nef_polyhedron_3::Halffacet_cycle_const_iterator
|
|
Halffacet_cycle_const_iterator;
|
|
typedef typename Nef_polyhedron_3::SHalfedge_around_facet_const_circulator
|
|
SHalfedge_around_facet_const_circulator;
|
|
typedef typename Nef_polyhedron_3::Vertex_const_handle
|
|
Vertex_const_handle;
|
|
typedef typename Nef_polyhedron_3::Volume_const_handle
|
|
Volume_const_handle;
|
|
typedef typename Nef_polyhedron_3::Halfedge_const_handle
|
|
Halfedge_const_handle;
|
|
typedef typename Nef_polyhedron_3::Halffacet_const_handle
|
|
Halffacet_const_handle;
|
|
typedef typename Nef_polyhedron_3::SHalfedge_const_handle
|
|
SHalfedge_const_handle;
|
|
typedef typename Nef_polyhedron_3::SFace_const_handle
|
|
SFace_const_handle;
|
|
|
|
Unique_hash_map<Halffacet_const_handle, SVertex_handle> Facet2SVertex;
|
|
Unique_hash_map<Halfedge_const_handle, SHalfedge_handle> Edge2SEdge;
|
|
Unique_hash_map<Halffacet_const_handle, bool> Facet2bool;
|
|
Unique_hash_map<Vertex_const_handle, bool> Vertex2bool(false);
|
|
Unique_hash_map<Halfedge_const_handle, bool> Edge2bool(false);
|
|
Unique_hash_map<SHalfedge_const_handle, SHalfedge_const_handle> SEdge2SEdge;
|
|
Unique_hash_map<SFace_const_handle, bool> Shell(false);
|
|
|
|
SFace_const_handle sf = c->shells_begin();
|
|
|
|
SVertex_creator<Nef_polyhedron_3> create_svertices(this->sphere_map(), Facet2SVertex, Facet2bool, SEdge2SEdge, Vertex2bool, Edge2bool, Shell);
|
|
SEdge_creator<Nef_polyhedron_3> create_sedges(this->sphere_map(), Edge2SEdge, Facet2SVertex, SEdge2SEdge, Facet2bool, Edge2bool);
|
|
// Facet2SVertex_completer<Nef_polyhedron_3> complete_Facet2SVertex(Facet2SVertex);
|
|
SFace_creator<Nef_polyhedron_3> create_sfaces(N3, this->sphere_map(), Edge2SEdge, Vertex2bool, Shell);
|
|
|
|
/*
|
|
SVertex_creator2<Nef_polyhedron_3> create_svertices(this->sphere_map(), Facet2SVertex);
|
|
SEdge_creator2<Nef_polyhedron_3> create_sedges(this->sphere_map(), Edge2SEdge, Facet2SVertex);
|
|
SFace_creator2<Nef_polyhedron_3> create_sfaces(this->sphere_map(), Edge2SEdge);
|
|
*/
|
|
|
|
N3.visit_shell_objects(sf, create_svertices);
|
|
N3.visit_shell_objects(sf, create_sedges);
|
|
// N3.visit_shell_objects(sf, complete_Facet2SVertex);
|
|
N3.visit_shell_objects(sf, create_sfaces);
|
|
// erase_redundant_vertices();
|
|
|
|
// CGAL::SM_io_parser<SM_decorator> O(std::cerr,*this);
|
|
// O.print();
|
|
}
|
|
|
|
template<typename NK>
|
|
Gausian_map(const CGAL::Nef_polyhedron_3<NK>& N3) : Base(new Sphere_map) {
|
|
|
|
typedef CGAL::Nef_polyhedron_3<NK> Nef_polyhedron_3;
|
|
typedef typename Nef_polyhedron_3::Vertex_const_iterator
|
|
Vertex_const_iterator;
|
|
typedef typename Nef_polyhedron_3::Halffacet_const_iterator
|
|
Halffacet_const_iterator;
|
|
typedef typename Nef_polyhedron_3::Halffacet_cycle_const_iterator
|
|
Halffacet_cycle_const_iterator;
|
|
typedef typename Nef_polyhedron_3::SHalfedge_around_facet_const_circulator
|
|
SHalfedge_around_facet_const_circulator;
|
|
typedef typename Nef_polyhedron_3::Volume_const_handle
|
|
Volume_const_handle;
|
|
typedef typename Nef_polyhedron_3::Halfedge_const_handle
|
|
Halfedge_const_handle;
|
|
typedef typename Nef_polyhedron_3::Halffacet_const_handle
|
|
Halffacet_const_handle;
|
|
typedef typename Nef_polyhedron_3::SHalfedge_const_handle
|
|
SHalfedge_const_handle;
|
|
|
|
Unique_hash_map<Halffacet_const_handle, SVertex_handle> Facet2SVertex;
|
|
Unique_hash_map<Halfedge_const_handle, SHalfedge_handle> Edge2SEdge;
|
|
|
|
Volume_const_handle c(--N3.volumes_end());
|
|
|
|
Halffacet_const_iterator f;
|
|
CGAL_forall_halffacets(f,N3) {
|
|
if(f->incident_volume() != c) continue;
|
|
SVertex_handle sv = new_svertex(f->twin()->plane().orthogonal_vector());
|
|
sv->mark() = Mark(Point_3(0,0,0), f->mark());
|
|
Facet2SVertex[f] = sv;
|
|
}
|
|
|
|
CGAL_forall_halffacets(f,N3) {
|
|
if(f->incident_volume() != c) continue;
|
|
Halffacet_cycle_const_iterator fc = f->twin()->facet_cycles_begin();
|
|
SHalfedge_const_handle se(fc);
|
|
SHalfedge_around_facet_const_circulator hc(se), hend(hc);
|
|
do {
|
|
Halfedge_const_handle e = hc->source();
|
|
SHalfedge_handle set = Edge2SEdge[e->twin()];
|
|
if(set == SHalfedge_handle())
|
|
Edge2SEdge[e] = new_shalfedge_pair_at_source(Facet2SVertex[f],1);
|
|
else {
|
|
link_as_target_and_append(Facet2SVertex[f], set);
|
|
set->mark() = set->twin()->mark() = Mark(Point_3(0,0,0), e->mark());
|
|
set->circle() = Sphere_circle(set->source()->point(), set->twin()->source()->point());
|
|
set->twin()->circle() = set->circle().opposite();
|
|
Edge2SEdge[e] = set->twin();
|
|
}
|
|
++hc;
|
|
} while(hc != hend);
|
|
}
|
|
|
|
Vertex_const_iterator v;
|
|
CGAL_forall_vertices(v,N3) {
|
|
|
|
// CGAL::SM_io_parser<SM_decorator> O(std::cerr,*this);
|
|
// O.print();
|
|
|
|
typename Nef_polyhedron_3::Nef_polyhedron_S2 SD(N3.get_sphere_map(v));
|
|
Halfedge_const_handle e(SD.svertices_begin());
|
|
SHalfedge_handle se = Edge2SEdge[e];
|
|
SFace_handle sf = this->new_sface();
|
|
sf->mark() = Mark(v->point(), v->mark());
|
|
link_as_face_cycle(se,sf);
|
|
}
|
|
}
|
|
|
|
template<typename PK>
|
|
Gausian_map(const CGAL::Polyhedron_3<PK>& P, bool closed = true)
|
|
: Base(new Sphere_map) {
|
|
|
|
typedef CGAL::Polyhedron_3<PK> Polyhedron_3;
|
|
typedef typename Polyhedron_3::Vertex_const_iterator
|
|
Vertex_const_iterator;
|
|
typedef typename Polyhedron_3::Facet_const_iterator
|
|
Facet_const_iterator;
|
|
typedef typename Polyhedron_3::Halfedge_around_facet_const_circulator
|
|
Halfedge_around_facet_const_circulator;
|
|
typedef typename Polyhedron_3::Halfedge_const_handle
|
|
Halfedge_const_handle;
|
|
typedef typename Polyhedron_3::Facet_const_handle
|
|
Facet_const_handle;
|
|
|
|
Unique_hash_map<Facet_const_handle, SVertex_handle> Facet2SVertex;
|
|
Unique_hash_map<Halfedge_const_handle, SHalfedge_handle> Edge2SEdge;
|
|
|
|
Facet_const_iterator f;
|
|
for(f = P.facets_begin(); f != P.facets_end(); ++f) {
|
|
SVertex_handle sv = new_svertex(f->plane().orthogonal_vector());
|
|
sv->mark() = Mark(Point_3(0,0,0), closed);
|
|
Facet2SVertex[f] = sv;
|
|
}
|
|
|
|
for(f = P.facets_begin(); f != P.facets_end(); ++f) {
|
|
Halfedge_around_facet_const_circulator hc(f->facet_begin()),hend(hc);
|
|
do {
|
|
Halfedge_const_handle e = hc;
|
|
SHalfedge_handle set = Edge2SEdge[e->opposite()];
|
|
if(set == SHalfedge_handle())
|
|
Edge2SEdge[e] = new_shalfedge_pair_at_source(Facet2SVertex[f],1);
|
|
else {
|
|
link_as_target_and_append(Facet2SVertex[f], set,1);
|
|
set->mark() = set->twin()->mark() = Mark(Point_3(0,0,0), closed);
|
|
set->circle() = Sphere_circle(set->source()->point(), set->twin()->source()->point());
|
|
set->twin()->circle() = set->circle().opposite();
|
|
Edge2SEdge[e] = set->twin();
|
|
}
|
|
++hc;
|
|
} while(hc != hend);
|
|
}
|
|
|
|
Vertex_const_iterator v;
|
|
for(v = P.vertices_begin(); v != P.vertices_end(); ++v) {
|
|
Halfedge_const_handle e(v->halfedge());
|
|
SHalfedge_handle se = Edge2SEdge[e];
|
|
SFace_handle sf = this->new_sface();
|
|
sf->mark() = Mark(v->point(), closed);
|
|
link_as_face_cycle(se,sf);
|
|
}
|
|
}
|
|
|
|
/*
|
|
Gausian_map(Halffacet_const_handle f) {
|
|
SVertex_handle
|
|
sv1(new_svertex(CGAL::ORIGIN +
|
|
f->plane()->orthogonal_vector())),
|
|
sv2(new_svertex(-(sv1->point())));
|
|
|
|
sv1->mark() = sv1->mark() =
|
|
Mark(Point_3(0,0,0), f->mark());
|
|
|
|
SHalfedge_around_facet_const_circulator
|
|
sfc(f->facet_cycles_begin()), send(sfc);
|
|
|
|
SHalfedge_handle se1 = new_shalfedge_pair(sv1, sv2);
|
|
Point_3 orth(sfc->twin()->source()->point());
|
|
se1->circle() = Sphere_circle(orth.hx(),
|
|
orth.hy(),
|
|
orth.hz());
|
|
se1->twin()->circle() = se1->circle().antipode();
|
|
se1->mark() = se1->twin()->mark() =
|
|
Mark(Point_3(0,0,0), sfc->twin()->source()->mark());
|
|
|
|
SHalfedge_handle se_prev(se1);
|
|
|
|
CGAL_For_all(++sfc, send) {
|
|
SHalfedge_handle
|
|
se(new_shalfedge_pair(se_prev, se_prev->twin(),
|
|
AFTER, BEFORE));
|
|
Point_3 orth(sfc->twin()->source()->point());
|
|
se->circle() = Sphere_circle(orth.hx(),
|
|
orth.hy(),
|
|
orth.hz());
|
|
se->twin()->circle() = se->circle().antipode();
|
|
se->mark() = se->twin()->mark() =
|
|
Mark(Point_3(0,0,0), sfc->twin()->source()->mark());
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
Gausian_map(Halfedge_const_handle e) {
|
|
SHalfloop_handle sl = new_shalfloop_pair();
|
|
Point_3 p = e->source()->point();
|
|
sl->circle() = Sphere_circle(p.hx(), p.hy(), p.hz());
|
|
sl->mark() = Mark(Point_3(0,0,0), e->mark());
|
|
|
|
SFace_handle sf1 = new_sface();
|
|
SFace_handle sf2 = new_sface();
|
|
sf1->mark() = Mark(p, e->source()->mark());
|
|
sf2->mark() = Mark(e->twin()->source()->point(),
|
|
e->twin()->source()->mark());
|
|
|
|
link_as_loop(sl, sf1);
|
|
link_as_loop(sl->twin, sf2);
|
|
}
|
|
|
|
Gausian_map(Vertex_const_handle v) {
|
|
SFace_handle sf = new_sface();
|
|
sf->mark() = Mark(v->point(), v->mark());
|
|
}
|
|
*/
|
|
|
|
void simplify() {
|
|
CGAL_NEF_TRACEN("simplify");
|
|
|
|
typedef typename CGAL::Union_find<SFace_handle>::handle Union_find_handle;
|
|
CGAL::Unique_hash_map< SFace_handle, Union_find_handle> Pitem(NULL);
|
|
CGAL::Union_find< SFace_handle> UF;
|
|
|
|
SFace_iterator f;
|
|
CGAL_forall_sfaces(f,*this) {
|
|
Pitem[f] = UF.make_set(f);
|
|
clear_face_cycle_entries(f);
|
|
}
|
|
|
|
SHalfedge_iterator e;
|
|
for(e = this->shalfedges_begin();
|
|
e != this->shalfedges_end();
|
|
++e) {
|
|
|
|
if (e->is_twin() ) continue;
|
|
CGAL_NEF_TRACEN("can simplify ? " << PH(e));
|
|
CGAL_NEF_TRACEN(e->mark() << " " << e->incident_sface()->mark()
|
|
<< " " << e->twin()->incident_sface()->mark());
|
|
if (e->incident_sface()->mark() ==
|
|
e->twin()->incident_sface()->mark()) {
|
|
CGAL_NEF_TRACEN("deleting "<<PH(e));
|
|
if ( !UF.same_set(Pitem[e->incident_sface()],
|
|
Pitem[e->twin()->incident_sface()]) ) {
|
|
|
|
UF.unify_sets( Pitem[e->incident_sface()],
|
|
Pitem[e->twin()->incident_sface()] );
|
|
CGAL_NEF_TRACEN("unioning disjoint faces");
|
|
}
|
|
|
|
CGAL_NEF_TRACEN("is_closed_at_source " << is_closed_at_source(e) <<
|
|
" " << is_closed_at_source(e->twin()));
|
|
delete_edge_pair(e);
|
|
}
|
|
}
|
|
|
|
CGAL::Unique_hash_map<SHalfedge_handle,bool> linked(false);
|
|
for (e = this->shalfedges_begin(); e != this->shalfedges_end(); ++e) {
|
|
if ( linked[e] ) continue;
|
|
SHalfedge_around_sface_circulator hfc(e),hend(hfc);
|
|
SFace_handle f = *(UF.find( Pitem[e->incident_sface()]));
|
|
CGAL_For_all(hfc,hend) { set_face(hfc,f); linked[hfc]=true; }
|
|
store_sm_boundary_object(e,f);
|
|
}
|
|
|
|
SVertex_iterator v;
|
|
for(v = this->svertices_begin(); v != this->svertices_end(); ++v) {
|
|
if ( is_isolated(v) ) {
|
|
delete_vertex_only(v);
|
|
continue;
|
|
}
|
|
if ( has_outdeg_two(v)) {
|
|
merge_edge_pairs_at_target(first_out_edge(v)->sprev());
|
|
}
|
|
}
|
|
|
|
for (f = this->sfaces_begin(); f != this->sfaces_end(); ++f) {
|
|
Union_find_handle pit = Pitem[f];
|
|
if ( UF.find(pit) != pit ) {
|
|
CGAL_NEF_TRACEN("delete face " << &*f);
|
|
delete_face_only(f);
|
|
}
|
|
}
|
|
}
|
|
|
|
void minkowski_sum(const Gausian_map& G1, const Gausian_map& G2) {
|
|
// CGAL_NEF_SETDTHREAD(131);
|
|
SM_overlayer O(this->sphere_map());
|
|
#ifdef CGAL_NEF3_TIMER_OVERLAY
|
|
CGAL::Timer t;
|
|
t.start();
|
|
#endif // CGAL_NEF3_TIMER_OVERLAY
|
|
O.subdivide(G1.sphere_map(), G2.sphere_map(), true);
|
|
#ifdef CGAL_NEF3_TIMER_OVERLAY
|
|
t.stop();
|
|
std::cout << "Runtime_overlay " << t.time() << std::endl;
|
|
#endif // CGAL_NEF3_TIMER_OVERLAY
|
|
VECTOR_ADDITION va;
|
|
O.select(va);
|
|
simplify();
|
|
}
|
|
|
|
Object_handle get_top() {
|
|
return top;
|
|
}
|
|
Object_handle get_bottom() {
|
|
return bottom;
|
|
}
|
|
|
|
Object_handle locate_top() {
|
|
std::vector<SFace_iterator> topSF;
|
|
SFace_iterator sfi = this->sfaces_begin();
|
|
topSF.push_back(sfi);
|
|
|
|
Comparison_result cr;
|
|
for(++sfi;sfi != this->sfaces_end(); ++sfi) {
|
|
cr = compare_z(sfi->mark(), (*topSF.begin())->mark());
|
|
if(cr != CGAL::SMALLER) {
|
|
if(cr == CGAL::LARGER)
|
|
topSF.clear();
|
|
topSF.push_back(sfi);
|
|
}
|
|
}
|
|
|
|
SFace_handle sf(topSF.front());
|
|
if(topSF.size()==1)
|
|
return Object_handle(SFace_const_handle(sf));
|
|
else {
|
|
SHalfedge_handle se(sf->sface_cycles_begin());
|
|
SHalfedge_around_sface_circulator sfc(se), sfend(sfc);
|
|
|
|
if(topSF.size()==2) {
|
|
while(sfc->circle().c()!=0) {
|
|
++sfc;
|
|
CGAL_assertion(sfc != sfend);
|
|
}
|
|
return Object_handle(SHalfedge_const_handle(sfc));
|
|
} else {
|
|
CGAL_assertion(topSF.size() > 0);
|
|
while(sfc->source()->point().hx()!=0 ||
|
|
sfc->source()->point().hy()!=0 ||
|
|
sfc->source()->point().hz()<=0) {
|
|
++sfc;
|
|
CGAL_assertion(sfc != sfend);
|
|
}
|
|
return Object_handle(SVertex_const_handle(sfc->source()));
|
|
}
|
|
}
|
|
CGAL_error_msg("line should not be executed");
|
|
return Object_handle();
|
|
}
|
|
|
|
Object_handle locate_bottom() {
|
|
std::vector<SFace_iterator> bottomSF;
|
|
SFace_iterator sfi = this->sfaces_begin();
|
|
bottomSF.push_back(sfi);
|
|
|
|
Comparison_result cr;
|
|
for(++sfi;sfi != this->sfaces_end(); ++sfi) {
|
|
cr = compare_z(sfi->mark(), (*bottomSF.begin())->mark());
|
|
if(cr != CGAL::LARGER) {
|
|
if(cr == CGAL::SMALLER)
|
|
bottomSF.clear();
|
|
bottomSF.push_back(sfi);
|
|
}
|
|
}
|
|
|
|
SFace_handle sf(bottomSF.front());
|
|
if(bottomSF.size()==1)
|
|
return Object_handle(SFace_const_handle(sf));
|
|
else {
|
|
SHalfedge_handle se(sf->sface_cycles_begin());
|
|
SHalfedge_around_sface_circulator sfc(se), sfend(sfc);
|
|
|
|
if(bottomSF.size()==2) {
|
|
while(sfc->circle().c()!=0) {
|
|
++sfc;
|
|
CGAL_assertion(sfc != sfend);
|
|
}
|
|
return Object_handle(SHalfedge_const_handle(sfc));
|
|
} else {
|
|
CGAL_assertion(bottomSF.size() > 0);
|
|
while(sfc->source()->point().hx()!=0 ||
|
|
sfc->source()->point().hy()!=0 ||
|
|
sfc->source()->point().hz()>=0) {
|
|
++sfc;
|
|
CGAL_assertion(sfc != sfend);
|
|
}
|
|
return Object_handle(SVertex_const_handle(sfc->source()));
|
|
}
|
|
}
|
|
CGAL_error_msg("line should not be executed");
|
|
return Object_handle();
|
|
}
|
|
|
|
void dump() const {
|
|
SM_io_parser<Base>::dump(*this,std::cerr);
|
|
}
|
|
|
|
void visualize() {
|
|
int argc=1;
|
|
char* argv[argc];
|
|
argv[0] = "Gaussian Map Viewer";
|
|
|
|
typedef typename CGAL::Nef_polyhedron_S2<K,CGAL::SM_items,Mark> Nef_polyhedron_S2;
|
|
Nef_polyhedron_S2 NS2(*this->sphere_map());
|
|
|
|
QApplication a(argc, argv);
|
|
CGAL::Qt_widget_Nef_S2<Nef_polyhedron_S2>* w =
|
|
new CGAL::Qt_widget_Nef_S2<Nef_polyhedron_S2>(NS2);
|
|
a.setMainWidget(w);
|
|
w->show();
|
|
a.exec();
|
|
}
|
|
};
|
|
|
|
template<typename Kernel>
|
|
std::ostream& operator<<(std::ostream& out, const CGAL::Gausian_map<Kernel>& G) {
|
|
out << "OFF" << std::endl;
|
|
out << G.number_of_sfaces() << " " << G.number_of_svertices() << " 0" << std::endl;
|
|
|
|
typedef typename CGAL::Gausian_map<Kernel>::SFace_const_iterator SFace_const_iterator;
|
|
CGAL::Unique_hash_map<SFace_const_iterator, int> SFace2int;
|
|
|
|
int i=0;
|
|
SFace_const_iterator sf;
|
|
CGAL_forall_sfaces(sf, G) {
|
|
SFace2int[sf] = i++;
|
|
out << CGAL::to_double(sf->mark().x()) << " "
|
|
<< CGAL::to_double(sf->mark().y()) << " "
|
|
<< CGAL::to_double(sf->mark().z()) << std::endl;
|
|
}
|
|
|
|
typename CGAL::Gausian_map<Kernel>::SVertex_const_iterator sv;
|
|
CGAL_forall_svertices(sv,G) {
|
|
typename CGAL::Gausian_map<Kernel>::SHalfedge_around_svertex_const_circulator
|
|
svc(G.first_out_edge(sv)),
|
|
svc1(svc),
|
|
svend(svc);
|
|
out << std::distance(++svc1,svend)+1;
|
|
CGAL_For_all(svc,svend)
|
|
out << " " << SFace2int[svc->incident_sface()];
|
|
out << std::endl;
|
|
}
|
|
|
|
return out;
|
|
}
|
|
|
|
CGAL_END_NAMESPACE
|
|
#endif // CGAL_NEF_GAUSIAN_MAP
|