mirror of https://github.com/CGAL/cgal
Merge pull request #5699 from GilesBathgate/Nef_3-snc_decorator_deduplication-GilesBathgate
Remove duplicate code in SNC_const_decorator/SNC_decorator
This commit is contained in:
commit
142fac63b5
|
|
@ -142,8 +142,8 @@ public:
|
||||||
{ return Segment_3(e->source()->point(),
|
{ return Segment_3(e->source()->point(),
|
||||||
e->twin()->source()->point()); }
|
e->twin()->source()->point()); }
|
||||||
|
|
||||||
template <typename Visitor>
|
template <typename Visitor, typename Traits = Self::Decorator_traits>
|
||||||
void visit_shell_objects(SFace_const_handle f, Visitor& V) const;
|
void visit_shell_objects(typename Traits::SFace_handle f, Visitor& V) const;
|
||||||
|
|
||||||
Vertex_const_iterator vertices_begin() const {
|
Vertex_const_iterator vertices_begin() const {
|
||||||
return this->sncp()->vertices_begin(); }
|
return this->sncp()->vertices_begin(); }
|
||||||
|
|
@ -237,10 +237,9 @@ public:
|
||||||
Infi_box::set_size_of_infimaximal_box(size);
|
Infi_box::set_size_of_infimaximal_box(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef CGAL::SM_point_locator<SM_const_decorator> SM_point_locator;
|
template <typename Traits = Self::Decorator_traits>
|
||||||
|
typename Traits::Halffacet_handle get_visible_facet( const typename Traits::Vertex_handle v,
|
||||||
Halffacet_const_handle get_visible_facet( const Vertex_const_handle v,
|
const Ray_3& ray) const
|
||||||
const Ray_3& ray) const
|
|
||||||
/*{\Mop when one shoot a ray |ray| in order to find the facet below to
|
/*{\Mop when one shoot a ray |ray| in order to find the facet below to
|
||||||
an object, and vertex |v| is hit, we need to choose one of the facets
|
an object, and vertex |v| is hit, we need to choose one of the facets
|
||||||
in the adjacency list of |v| such that it could be 'seen' from the
|
in the adjacency list of |v| such that it could be 'seen' from the
|
||||||
|
|
@ -248,9 +247,17 @@ public:
|
||||||
locating the sphere facet |sf| pierced by |ray| and taking the adjacent
|
locating the sphere facet |sf| pierced by |ray| and taking the adjacent
|
||||||
facet to one of the sphere segments on the boundary of |sf|.
|
facet to one of the sphere segments on the boundary of |sf|.
|
||||||
\precondition |ray| target is on |v| and the intersection between
|
\precondition |ray| target is on |v| and the intersection between
|
||||||
|ray| and the 2-skeleton incident to v is empty. }*/ {
|
|ray| and the 2-skeleton incident to v is empty. }*/
|
||||||
|
{
|
||||||
|
|
||||||
Halffacet_const_handle f_visible;
|
typedef typename Traits::Halffacet_handle Halffacet_handle;
|
||||||
|
typedef typename Traits::SFace_handle SFace_handle;
|
||||||
|
typedef typename Traits::SHalfedge_handle SHalfedge_handle;
|
||||||
|
typedef typename Traits::SFace_cycle_iterator SFace_cycle_iterator;
|
||||||
|
typedef typename Traits::SHalfloop_handle SHalfloop_handle;
|
||||||
|
typedef CGAL::SM_point_locator<typename Traits::SM_decorator> SM_point_locator;
|
||||||
|
|
||||||
|
Halffacet_handle f_visible;
|
||||||
CGAL_assertion( ray.source() != v->point());
|
CGAL_assertion( ray.source() != v->point());
|
||||||
CGAL_assertion( ray.has_on(v->point()));
|
CGAL_assertion( ray.has_on(v->point()));
|
||||||
Sphere_point sp(ray.source() - v->point());
|
Sphere_point sp(ray.source() - v->point());
|
||||||
|
|
@ -264,28 +271,21 @@ public:
|
||||||
SM_point_locator L(&*v);
|
SM_point_locator L(&*v);
|
||||||
Object_handle o = L.locate(sp);
|
Object_handle o = L.locate(sp);
|
||||||
|
|
||||||
SFace_const_handle sf;
|
SFace_handle sf;
|
||||||
if(!CGAL::assign(sf,o)) {
|
if(!CGAL::assign(sf,o)) {
|
||||||
SHalfedge_const_handle se;
|
|
||||||
if(CGAL::assign(se,o))
|
|
||||||
std::cerr << "on sedge " << PH(se)
|
|
||||||
<< " on facet " << se->facet()->plane() << std::endl;
|
|
||||||
SVertex_const_handle sv;
|
|
||||||
if(CGAL::assign(sv,o))
|
|
||||||
std::cerr << "on svertex " << sv->point() << std::endl;
|
|
||||||
CGAL_error_msg( "it is not possible to decide which one is a visible facet (if any)");
|
CGAL_error_msg( "it is not possible to decide which one is a visible facet (if any)");
|
||||||
return Halffacet_const_handle();
|
return Halffacet_handle();
|
||||||
}
|
}
|
||||||
|
|
||||||
SFace_cycle_const_iterator fc = sf->sface_cycles_begin(),
|
SFace_cycle_iterator fc = sf->sface_cycles_begin(),
|
||||||
fce = sf->sface_cycles_end();
|
fce = sf->sface_cycles_end();
|
||||||
if( is_empty_range( fc, fce)) {
|
if( is_empty_range( fc, fce)) {
|
||||||
CGAL_NEF_TRACEN( "no adjacent facet found.");
|
CGAL_NEF_TRACEN( "no adjacent facet found.");
|
||||||
f_visible = Halffacet_const_handle();
|
f_visible = Halffacet_handle();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (fc.is_shalfedge()) {
|
if (fc.is_shalfedge()) {
|
||||||
SHalfedge_const_handle se(fc);
|
SHalfedge_handle se(fc);
|
||||||
CGAL_NEF_TRACEN( "adjacent facet found (SEdges cycle).");
|
CGAL_NEF_TRACEN( "adjacent facet found (SEdges cycle).");
|
||||||
CGAL_NEF_TRACEN("se"<<PH(se));
|
CGAL_NEF_TRACEN("se"<<PH(se));
|
||||||
CGAL_NEF_TRACEN(se->facet()->plane() <<"/"<<
|
CGAL_NEF_TRACEN(se->facet()->plane() <<"/"<<
|
||||||
|
|
@ -295,8 +295,7 @@ public:
|
||||||
CGAL_NEF_TRACEN("f_visible"<< f_visible->plane());
|
CGAL_NEF_TRACEN("f_visible"<< f_visible->plane());
|
||||||
}
|
}
|
||||||
else if (fc.is_shalfloop()) {
|
else if (fc.is_shalfloop()) {
|
||||||
SHalfloop_const_handle sl(fc);
|
SHalfloop_handle sl(fc);
|
||||||
SM_const_decorator SD;
|
|
||||||
CGAL_NEF_TRACEN( "adjacent facet found (SHalfloop cycle)."<< sl->circle()
|
CGAL_NEF_TRACEN( "adjacent facet found (SHalfloop cycle)."<< sl->circle()
|
||||||
<< " with facet "<< sl->facet()->plane());
|
<< " with facet "<< sl->facet()->plane());
|
||||||
f_visible = sl->twin()->facet();
|
f_visible = sl->twin()->facet();
|
||||||
|
|
@ -309,7 +308,7 @@ public:
|
||||||
++fc; while( fc != fce) { CGAL_assertion( fc.is_svertex()); ++fc; }
|
++fc; while( fc != fce) { CGAL_assertion( fc.is_svertex()); ++fc; }
|
||||||
CGAL_NEF_TRACEN( "no adjacent facets were found (but incident edge(s)).");
|
CGAL_NEF_TRACEN( "no adjacent facets were found (but incident edge(s)).");
|
||||||
#endif
|
#endif
|
||||||
f_visible = Halffacet_const_handle();
|
f_visible = Halffacet_handle();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
CGAL_error_msg("Damn wrong handle");
|
CGAL_error_msg("Damn wrong handle");
|
||||||
|
|
@ -317,17 +316,22 @@ public:
|
||||||
return f_visible;
|
return f_visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
Halffacet_const_handle get_visible_facet( const Halfedge_const_handle e,
|
template <typename Traits = Self::Decorator_traits>
|
||||||
const Ray_3& ray) const {
|
typename Traits::Halffacet_handle get_visible_facet( const typename Traits::Halfedge_handle e,
|
||||||
|
const Ray_3& ray) const
|
||||||
//{\Mop when one shoot a ray |ray| in order to find the facet below to
|
//{\Mop when one shoot a ray |ray| in order to find the facet below to
|
||||||
// an object, and an edge |e| is hit, we need to choose one of the two
|
// an object, and an edge |e| is hit, we need to choose one of the two
|
||||||
// facets in the adjacency list of |e| that could be 'seen' from the
|
// facets in the adjacency list of |e| that could be 'seen' from the
|
||||||
// piercing point of the |ray| on the local (virtual) view of |e|
|
// piercing point of the |ray| on the local (virtual) view of |e|
|
||||||
// \precondition |ray| target belongs to |e|. }
|
// \precondition |ray| target belongs to |e|. }
|
||||||
|
{
|
||||||
|
typedef typename Traits::SM_decorator SM_decorator;
|
||||||
|
typedef typename Traits::Halffacet_handle Halffacet_handle;
|
||||||
|
typedef typename Traits::SHalfedge_around_svertex_circulator SHalfedge_around_svertex_circulator;
|
||||||
|
|
||||||
SM_const_decorator SD(&*e->source());
|
SM_decorator SD(&*e->source());
|
||||||
if( SD.is_isolated(e))
|
if( SD.is_isolated(e))
|
||||||
return Halffacet_const_handle();
|
return Halffacet_handle();
|
||||||
|
|
||||||
// We search for the plane in the adjacency list of e, which is closest
|
// We search for the plane in the adjacency list of e, which is closest
|
||||||
// to the ray. The cross product of the direction of e and the orthogonal
|
// to the ray. The cross product of the direction of e and the orthogonal
|
||||||
|
|
@ -335,8 +339,8 @@ public:
|
||||||
// and orthogonal to e, pointing inside of the facet.
|
// and orthogonal to e, pointing inside of the facet.
|
||||||
|
|
||||||
Vector_3 ev(segment(e).to_vector()), rv(ray.to_vector());
|
Vector_3 ev(segment(e).to_vector()), rv(ray.to_vector());
|
||||||
SHalfedge_around_svertex_const_circulator sh(SD.first_out_edge(e));
|
SHalfedge_around_svertex_circulator sh(SD.first_out_edge(e));
|
||||||
Halffacet_const_handle res = sh->facet();
|
Halffacet_handle res = sh->facet();
|
||||||
Vector_3 vec0(cross_product(ev,res->plane().orthogonal_vector()));
|
Vector_3 vec0(cross_product(ev,res->plane().orthogonal_vector()));
|
||||||
/* // probably incorrect assertion
|
/* // probably incorrect assertion
|
||||||
CGAL_assertion_code
|
CGAL_assertion_code
|
||||||
|
|
@ -345,7 +349,7 @@ public:
|
||||||
SD.circle(sh)));
|
SD.circle(sh)));
|
||||||
CGAL_assertion( _ess.has_on(vec0));
|
CGAL_assertion( _ess.has_on(vec0));
|
||||||
*/
|
*/
|
||||||
SHalfedge_around_svertex_const_circulator send(sh);
|
SHalfedge_around_svertex_circulator send(sh);
|
||||||
CGAL_NEF_TRACEN("initial face candidate "<< res->plane()<<" with vector "<<vec0);
|
CGAL_NEF_TRACEN("initial face candidate "<< res->plane()<<" with vector "<<vec0);
|
||||||
|
|
||||||
// We compare the vectors vec0/vec1 of the facets. The one that is nearest
|
// We compare the vectors vec0/vec1 of the facets. The one that is nearest
|
||||||
|
|
@ -395,16 +399,19 @@ public:
|
||||||
return res; // never reached
|
return res; // never reached
|
||||||
}
|
}
|
||||||
|
|
||||||
Halffacet_const_handle get_visible_facet(Halffacet_const_handle f,
|
template <typename Traits = Self::Decorator_traits>
|
||||||
const Ray_3& ray) const
|
typename Traits::Halffacet_handle get_visible_facet( const typename Traits::Halffacet_handle f,
|
||||||
|
const Ray_3& ray) const
|
||||||
/*{\Mop when one shoot a ray |ray| in order to find the facet below to
|
/*{\Mop when one shoot a ray |ray| in order to find the facet below to
|
||||||
an object, and a facet |f| is hit, we need to choose the right facet
|
an object, and a facet |f| is hit, we need to choose the right facet
|
||||||
from the halffacet pair |f| that could be 'seen' from the
|
from the halffacet pair |f| that could be 'seen' from the
|
||||||
piercing point of the |ray| on the local (virtual) view of |f|.
|
piercing point of the |ray| on the local (virtual) view of |f|.
|
||||||
\precondition |ray| target belongs to |f| and the intersection between
|
\precondition |ray| target belongs to |f| and the intersection between
|
||||||
|ray| and is not coplanar with |f|. }*/ {
|
|ray| and is not coplanar with |f|. }*/
|
||||||
|
{
|
||||||
|
typedef typename Traits::Halffacet_handle Halffacet_handle;
|
||||||
|
|
||||||
Halffacet_const_handle f_visible = f;
|
Halffacet_handle f_visible = f;
|
||||||
if( f_visible->plane().has_on_negative_side(ray.source()))
|
if( f_visible->plane().has_on_negative_side(ray.source()))
|
||||||
f_visible = f_visible->twin();
|
f_visible = f_visible->twin();
|
||||||
CGAL_assertion( f_visible->plane().has_on_positive_side(ray.source()));
|
CGAL_assertion( f_visible->plane().has_on_positive_side(ray.source()));
|
||||||
|
|
@ -429,84 +436,116 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* visiting shell objects:
|
||||||
|
|
||||||
|
Objects are marked as done, when placed in the output list. We have
|
||||||
|
to maintain a stack of sface candidates (the spherical rubber sectors
|
||||||
|
that provide connectivity at the local graphs of vertices) and facet
|
||||||
|
candiates (the plane pieces in three space also providing
|
||||||
|
connectivity). Note that we have to take care about the orientation of
|
||||||
|
sobjects and facets. We have to take care that (1) the search along
|
||||||
|
the shell extends along the whole shell structure (2) does not visit
|
||||||
|
any object twice, and (3) all 3-space objects have to be reported and
|
||||||
|
this also just once.
|
||||||
|
|
||||||
|
The facets and sfaces are marked |done| when they are put into their
|
||||||
|
corresponding queues thus each such object is visited exactly once
|
||||||
|
when taken out of the queue.
|
||||||
|
|
||||||
|
When an sface |sf| is taken out of the queue |SFaceCandiates| its
|
||||||
|
boundary structure is examined and all 2-skeleton objects (vertices
|
||||||
|
and edges of 3-space) that are incident to the volume represented by
|
||||||
|
|sf| are reported. Facets are reported when they are taken out of
|
||||||
|
|FacetCandiates|.
|
||||||
|
|
||||||
|
*/
|
||||||
template <typename EW>
|
template <typename EW>
|
||||||
template <typename Visitor>
|
template <typename Visitor, typename Traits>
|
||||||
void SNC_const_decorator<EW>::
|
void SNC_const_decorator<EW>::
|
||||||
visit_shell_objects(SFace_const_handle f, Visitor& V) const
|
visit_shell_objects(typename Traits::SFace_handle f, Visitor& V) const
|
||||||
{
|
{
|
||||||
std::list<SFace_const_handle> SFaceCandidates;
|
typedef typename Traits::Halffacet_cycle_iterator Halffacet_cycle_iterator;
|
||||||
std::list<Halffacet_const_handle> FacetCandidates;
|
typedef typename Traits::Halffacet_handle Halffacet_handle;
|
||||||
CGAL::Unique_hash_map<SFace_const_handle,bool> DoneSF(false);
|
typedef typename Traits::SFace_cycle_iterator SFace_cycle_iterator;
|
||||||
CGAL::Unique_hash_map<Vertex_const_handle,bool> DoneV(false);
|
typedef typename Traits::SFace_handle SFace_handle;
|
||||||
CGAL::Unique_hash_map<SVertex_const_handle,bool> DoneSV(false);
|
typedef typename Traits::SHalfedge_around_facet_circulator SHalfedge_around_facet_circulator;
|
||||||
CGAL::Unique_hash_map<Halffacet_const_handle,bool> DoneF(false);
|
typedef typename Traits::SHalfedge_around_sface_circulator SHalfedge_around_sface_circulator;
|
||||||
SFaceCandidates.push_back(f); DoneSF[f] = true;
|
typedef typename Traits::SHalfedge_handle SHalfedge_handle;
|
||||||
|
typedef typename Traits::SHalfloop_handle SHalfloop_handle;
|
||||||
|
typedef typename Traits::SM_decorator SM_decorator;
|
||||||
|
typedef typename Traits::SVertex_handle SVertex_handle;
|
||||||
|
|
||||||
|
std::list<SFace_handle> SFaceCandidates;
|
||||||
|
std::list<Halffacet_handle> FacetCandidates;
|
||||||
|
CGAL::Generic_handle_map<bool> Done(false);
|
||||||
|
|
||||||
|
SFaceCandidates.push_back(f); Done[f] = true;
|
||||||
while ( true ) {
|
while ( true ) {
|
||||||
if ( SFaceCandidates.empty() && FacetCandidates.empty() ) break;
|
if ( SFaceCandidates.empty() && FacetCandidates.empty() ) break;
|
||||||
if ( !FacetCandidates.empty() ) {
|
if ( !FacetCandidates.empty() ) {
|
||||||
Halffacet_const_handle f = *FacetCandidates.begin();
|
Halffacet_handle f = *FacetCandidates.begin();
|
||||||
FacetCandidates.pop_front();
|
FacetCandidates.pop_front();
|
||||||
V.visit(f); // report facet
|
V.visit(f); // report facet
|
||||||
Halffacet_cycle_const_iterator fc;
|
Halffacet_cycle_iterator fc;
|
||||||
CGAL_forall_facet_cycles_of(fc,f) {
|
CGAL_forall_facet_cycles_of(fc,f) {
|
||||||
if (fc.is_shalfedge() ) {
|
if (fc.is_shalfedge() ) {
|
||||||
SHalfedge_const_handle e(fc);
|
SHalfedge_handle e(fc);
|
||||||
SHalfedge_const_handle she;
|
SHalfedge_handle she;
|
||||||
SHalfedge_around_facet_const_circulator ec(e),ee(e);
|
SHalfedge_around_facet_circulator ec(e),ee(e);
|
||||||
CGAL_For_all(ec,ee) { she = ec->twin();
|
CGAL_For_all(ec,ee) { she = ec->twin();
|
||||||
if ( DoneSF[she->incident_sface()] ) continue;
|
if ( Done[she->incident_sface()] ) continue;
|
||||||
SFaceCandidates.push_back(she->incident_sface());
|
SFaceCandidates.push_back(she->incident_sface());
|
||||||
DoneSF[she->incident_sface()] = true;
|
Done[she->incident_sface()] = true;
|
||||||
}
|
}
|
||||||
} else if (fc.is_shalfloop() ) {
|
} else if (fc.is_shalfloop() ) {
|
||||||
SHalfloop_const_handle l(fc);
|
SHalfloop_handle l(fc);
|
||||||
SHalfloop_const_handle ll = l->twin();
|
SHalfloop_handle ll = l->twin();
|
||||||
if ( DoneSF[ll->incident_sface()] ) continue;
|
if ( Done[ll->incident_sface()] ) continue;
|
||||||
SFaceCandidates.push_back(ll->incident_sface());
|
SFaceCandidates.push_back(ll->incident_sface());
|
||||||
DoneSF[ll->incident_sface()] = true;
|
Done[ll->incident_sface()] = true;
|
||||||
} else CGAL_error_msg("Damn wrong handle.");
|
} else CGAL_error_msg("Damn wrong handle.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( !SFaceCandidates.empty() ) {
|
if ( !SFaceCandidates.empty() ) {
|
||||||
SFace_const_handle sf = *SFaceCandidates.begin();
|
SFace_handle sf = *SFaceCandidates.begin();
|
||||||
SFaceCandidates.pop_front();
|
SFaceCandidates.pop_front();
|
||||||
V.visit(sf);
|
V.visit(sf);
|
||||||
if ( !DoneV[sf->center_vertex()] )
|
if ( !Done[sf->center_vertex()] )
|
||||||
V.visit(sf->center_vertex()); // report vertex
|
V.visit(sf->center_vertex()); // report vertex
|
||||||
DoneV[sf->center_vertex()] = true;
|
Done[sf->center_vertex()] = true;
|
||||||
// SVertex_const_handle sv;
|
// SVertex_const_handle sv;
|
||||||
SM_const_decorator SD(&*sf->center_vertex());
|
SM_decorator SD(&*sf->center_vertex());
|
||||||
/*
|
/*
|
||||||
CGAL_forall_svertices(sv,SD){
|
CGAL_forall_svertices(sv,SD){
|
||||||
if(SD.is_isolated(sv) && !DoneSV[sv])
|
if(SD.is_isolated(sv) && !DoneSV[sv])
|
||||||
V.visit(sv);
|
V.visit(sv);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
SFace_cycle_const_iterator fc;
|
SFace_cycle_iterator fc;
|
||||||
CGAL_forall_sface_cycles_of(fc,sf) {
|
CGAL_forall_sface_cycles_of(fc,sf) {
|
||||||
if (fc.is_shalfedge() ) {
|
if (fc.is_shalfedge() ) {
|
||||||
SHalfedge_const_handle e(fc);
|
SHalfedge_handle e(fc);
|
||||||
SHalfedge_around_sface_const_circulator ec(e),ee(e);
|
SHalfedge_around_sface_circulator ec(e),ee(e);
|
||||||
CGAL_For_all(ec,ee) {
|
CGAL_For_all(ec,ee) {
|
||||||
V.visit(SHalfedge_const_handle(ec));
|
V.visit(SHalfedge_handle(ec));
|
||||||
SVertex_const_handle vv = ec->twin()->source();
|
SVertex_handle vv = ec->twin()->source();
|
||||||
if ( !SD.is_isolated(vv) && !DoneSV[vv] ) {
|
if ( !SD.is_isolated(vv) && !Done[vv] ) {
|
||||||
V.visit(vv); // report edge
|
V.visit(vv); // report edge
|
||||||
DoneSV[vv] = DoneSV[vv->twin()] = true;
|
Done[vv] = Done[vv->twin()] = true;
|
||||||
}
|
}
|
||||||
Halffacet_const_handle f = ec->twin()->facet();
|
Halffacet_handle f = ec->twin()->facet();
|
||||||
if ( DoneF[f] ) continue;
|
if ( Done[f] ) continue;
|
||||||
FacetCandidates.push_back(f); DoneF[f] = true;
|
FacetCandidates.push_back(f); Done[f] = true;
|
||||||
}
|
}
|
||||||
} else if (fc.is_svertex() ) {
|
} else if (fc.is_svertex() ) {
|
||||||
SVertex_const_handle v(fc);
|
SVertex_handle v(fc);
|
||||||
if ( DoneSV[v] ) continue;
|
if ( Done[v] ) continue;
|
||||||
V.visit(v); // report edge
|
V.visit(v); // report edge
|
||||||
V.visit(v->twin());
|
V.visit(v->twin());
|
||||||
DoneSV[v] = DoneSV[v->twin()] = true;
|
Done[v] = Done[v->twin()] = true;
|
||||||
CGAL_assertion(SD.is_isolated(v));
|
CGAL_assertion(SD.is_isolated(v));
|
||||||
SFaceCandidates.push_back(v->twin()->incident_sface());
|
SFaceCandidates.push_back(v->twin()->incident_sface());
|
||||||
DoneSF[v->twin()->incident_sface()]=true;
|
Done[v->twin()->incident_sface()]=true;
|
||||||
// note that v is isolated, thus twin(v) is isolated too
|
// note that v is isolated, thus twin(v) is isolated too
|
||||||
// SM_const_decorator SD;
|
// SM_const_decorator SD;
|
||||||
// SFace_const_handle fo;
|
// SFace_const_handle fo;
|
||||||
|
|
@ -518,11 +557,11 @@ visit_shell_objects(SFace_const_handle f, Visitor& V) const
|
||||||
fo = v->twin()->incident_sface();
|
fo = v->twin()->incident_sface();
|
||||||
*/
|
*/
|
||||||
} else if (fc.is_shalfloop() ) {
|
} else if (fc.is_shalfloop() ) {
|
||||||
SHalfloop_const_handle l(fc);
|
SHalfloop_handle l(fc);
|
||||||
V.visit(l);
|
V.visit(l);
|
||||||
Halffacet_const_handle f = l->twin()->facet();
|
Halffacet_handle f = l->twin()->facet();
|
||||||
if ( DoneF[f] ) continue;
|
if ( Done[f] ) continue;
|
||||||
FacetCandidates.push_back(f); DoneF[f] = true;
|
FacetCandidates.push_back(f); Done[f] = true;
|
||||||
} else CGAL_error_msg("Damn wrong handle.");
|
} else CGAL_error_msg("Damn wrong handle.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -344,170 +344,15 @@ class SNC_decorator : public SNC_const_decorator<Map> {
|
||||||
|
|
||||||
Halffacet_handle get_visible_facet( const Vertex_handle v,
|
Halffacet_handle get_visible_facet( const Vertex_handle v,
|
||||||
const Ray_3& ray) const
|
const Ray_3& ray) const
|
||||||
/*{\Mop when one shoot a ray |ray| in order to find the facet below to
|
{ return Base::template get_visible_facet<Decorator_traits>(v, ray); }
|
||||||
an object, and vertex |v| is hit, we need to choose one of the facets
|
|
||||||
in the adjacency list of |v| such that it could be 'seen' from the
|
|
||||||
piercing point of the |ray| on the sphere map on |v|. We make it just
|
|
||||||
locating the sphere facet |sf| pierced by |ray| and taking the adjacent
|
|
||||||
facet to one of the sphere segments on the boundary of |sf|.
|
|
||||||
\precondition |ray| target is on |v| and the intersection between
|
|
||||||
|ray| and the 2-skeleton incident to v is empty. }*/ {
|
|
||||||
|
|
||||||
Halffacet_handle f_visible;
|
|
||||||
CGAL_assertion( ray.source() != v->point());
|
|
||||||
CGAL_assertion( ray.has_on(v->point()));
|
|
||||||
Sphere_point sp(ray.source() - v->point());
|
|
||||||
CGAL_NEF_TRACEN( "Locating "<<sp <<" in "<< v->point());
|
|
||||||
CGAL_assertion(Infi_box::degree(sp.hx()) < 2 &&
|
|
||||||
Infi_box::degree(sp.hy()) < 2 &&
|
|
||||||
Infi_box::degree(sp.hz()) < 2 &&
|
|
||||||
Infi_box::degree(sp.hw()) == 0);
|
|
||||||
sp = Infi_box::simplify(sp);
|
|
||||||
CGAL_NEF_TRACEN( "Locating "<<sp <<" in "<< v->point());
|
|
||||||
SM_point_locator L(&*v);
|
|
||||||
Object_handle o = L.locate(sp);
|
|
||||||
|
|
||||||
SFace_handle sf;
|
|
||||||
if(!CGAL::assign(sf,o)) {
|
|
||||||
CGAL_error_msg( "it is not possible to decide which one is a visible facet (if any)");
|
|
||||||
return Halffacet_handle();
|
|
||||||
}
|
|
||||||
|
|
||||||
SFace_cycle_iterator fc = sf->sface_cycles_begin(),
|
|
||||||
fce = sf->sface_cycles_end();
|
|
||||||
if( is_empty_range( fc, fce)) {
|
|
||||||
CGAL_NEF_TRACEN( "no adjacent facet found.");
|
|
||||||
f_visible = Halffacet_handle();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if ( fc.is_shalfedge()) {
|
|
||||||
SHalfedge_handle se(fc);
|
|
||||||
CGAL_NEF_TRACEN( "adjacent facet found (SEdges cycle).");
|
|
||||||
CGAL_NEF_TRACEN("se"<<PH(se));
|
|
||||||
CGAL_NEF_TRACEN(se->facet()->plane() <<"/"<<
|
|
||||||
se->snext()->facet()->plane() <<"/"<<
|
|
||||||
se->snext()->snext()->facet()->plane());
|
|
||||||
f_visible = se->twin()->facet();
|
|
||||||
CGAL_NEF_TRACEN("f_visible"<<f_visible->plane());
|
|
||||||
}
|
|
||||||
else if ( fc.is_shalfloop()) {
|
|
||||||
SHalfloop_handle sl(fc);
|
|
||||||
CGAL_NEF_TRACEN( "adjacent facet found (SHalfloop cycle)."<< sl->circle()
|
|
||||||
<< " with facet "<<sl->facet()->plane());
|
|
||||||
f_visible = sl->twin()->facet();
|
|
||||||
CGAL_NEF_TRACEN("f_visible"<<f_visible->plane());
|
|
||||||
}
|
|
||||||
else if(fc.is_svertex()) {
|
|
||||||
#ifdef CGAL_NEF_DEBUG
|
|
||||||
// TODO: is there any warranty that the outter facet cycle enty point is always at first
|
|
||||||
// in the cycles list?
|
|
||||||
++fc; while( fc != fce) { CGAL_assertion( fc.is_svertex()); ++fc; }
|
|
||||||
#endif
|
|
||||||
CGAL_NEF_TRACEN( "no adjacent facets were found (but incident edge(s)).");
|
|
||||||
f_visible = Halffacet_handle();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
CGAL_error_msg("Damn wrong handle");
|
|
||||||
}
|
|
||||||
return f_visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
Halffacet_handle get_visible_facet( const Halfedge_handle e,
|
Halffacet_handle get_visible_facet( const Halfedge_handle e,
|
||||||
const Ray_3& ray) const {
|
const Ray_3& ray) const
|
||||||
//{\Mop when one shoot a ray |ray| in order to find the facet below to
|
{ return Base::template get_visible_facet<Decorator_traits>(e, ray); }
|
||||||
// an object, and an edge |e| is hit, we need to choose one of the two
|
|
||||||
// facets in the adjacency list of |e| that could be 'seen' from the
|
|
||||||
// piercing point of the |ray| on the local (virtual) view of |e|
|
|
||||||
// \precondition |ray| target belongs to |e|. }
|
|
||||||
|
|
||||||
SM_decorator SD(&*e->source());
|
|
||||||
if( SD.is_isolated(e))
|
|
||||||
return Halffacet_handle();
|
|
||||||
|
|
||||||
// We search for the plane in the adjacency list of e, which is closest
|
|
||||||
// to the ray. The cross product of the direction of e and the orthogonal
|
|
||||||
// vector of a plane gives us a vector vec0/vec1 on the plane of the facet
|
|
||||||
// and orthogonal to e, pointing inside of the facet.
|
|
||||||
|
|
||||||
Vector_3 ev(segment(e).to_vector()), rv(ray.to_vector());
|
|
||||||
SHalfedge_around_svertex_circulator sh(SD.first_out_edge(e));
|
|
||||||
Halffacet_handle res = sh->facet();
|
|
||||||
Vector_3 vec0(cross_product(ev,res->plane().orthogonal_vector()));
|
|
||||||
/* // probably incorrect assertion
|
|
||||||
CGAL_assertion_code
|
|
||||||
(Sphere_segment _ess( sh->source()->source()->point(),
|
|
||||||
sh->next()->source()->source()->point(),
|
|
||||||
sh->circle());
|
|
||||||
CGAL_assertion( _ess.has_on(vec0));
|
|
||||||
*/
|
|
||||||
SHalfedge_around_svertex_circulator send(sh);
|
|
||||||
CGAL_NEF_TRACEN("initial face candidate "<< res->plane()<<" with vector "<<vec0);
|
|
||||||
|
|
||||||
// We compare the vectors vec0/vec1 of the facets. The one that is nearest
|
|
||||||
// to pointing in the opposite direction of the ray, is chosen. The
|
|
||||||
// respective facet is the nearest to the ray.
|
|
||||||
|
|
||||||
sh++;
|
|
||||||
CGAL_For_all(sh,send) {
|
|
||||||
Vector_3 vec1(cross_product(ev,sh->facet()->plane().orthogonal_vector()));
|
|
||||||
CGAL_NEF_TRACEN("test face candidate "<< sh->facet()->plane()<<" with vector "<<vec1);
|
|
||||||
FT sk0(rv*vec0), sk1(rv*vec1);
|
|
||||||
if(sk0<=FT(0) && sk1>=FT(0))
|
|
||||||
continue;
|
|
||||||
if(sk0>=FT(0) && sk1<=FT(0)) {
|
|
||||||
res = sh->facet();
|
|
||||||
vec0 = vec1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We have to comapare the two skalar products sk0 and sk1. Therefore
|
|
||||||
// we have to normalize the input vectors vec0 and vec1, which means
|
|
||||||
// that we have to divide them by their lengths len0 and len1.
|
|
||||||
// To cicumvent irrational numbers, we sqaure the whole inequality.
|
|
||||||
|
|
||||||
FT len0 = vec0.x()*vec0.x()+vec0.y()*vec0.y()+vec0.z()*vec0.z();
|
|
||||||
FT len1 = vec1.x()*vec1.x()+vec1.y()*vec1.y()+vec1.z()*vec1.z();
|
|
||||||
FT diff = len0*sk1*sk1 - len1*sk0*sk0;
|
|
||||||
|
|
||||||
// if sk0<0 (and therefore sk1<0) both vectors point in a good direction.
|
|
||||||
// Therefore we take the one pointing more in the good direction.
|
|
||||||
// if sk0>0 (and therefore sk1>0) both vectors point in a bad direction.
|
|
||||||
// Therefore we take the one pointing less in the bad direction.
|
|
||||||
|
|
||||||
if((sk0>FT(0) && diff<FT(0)) || (sk0<FT(0) && diff>FT(0))) {
|
|
||||||
res = sh->facet();
|
|
||||||
vec0 = vec1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We have to check which of the two halffacet is visible from
|
|
||||||
// the ray.
|
|
||||||
|
|
||||||
if(rv*res->plane().orthogonal_vector() > FT(0))
|
|
||||||
res = res->twin();
|
|
||||||
|
|
||||||
CGAL_NEF_TRACEN("return "<<res->plane());
|
|
||||||
return res; // never reached
|
|
||||||
}
|
|
||||||
|
|
||||||
Halffacet_handle get_visible_facet( const Halffacet_handle f,
|
Halffacet_handle get_visible_facet( const Halffacet_handle f,
|
||||||
const Ray_3& ray) const
|
const Ray_3& ray) const
|
||||||
/*{\Mop when one shoot a ray |ray| in order to find the facet below to
|
{ return Base::template get_visible_facet<Decorator_traits>(f, ray); }
|
||||||
an object, and a facet |f| is hit, we need to choose the right facet
|
|
||||||
from the halffacet pair |f| that could be 'seen' from the
|
|
||||||
piercing point of the |ray| on the local (virtual) view of |f|.
|
|
||||||
\precondition |ray| target belongs to |f| and the intersection between
|
|
||||||
|ray| and is not coplanar with |f|. }*/ {
|
|
||||||
|
|
||||||
CGAL_NEF_TRACEN("get visible facet " << ray << ", " << f->plane()
|
|
||||||
<< " has on source " << f->plane().has_on(ray.source()));
|
|
||||||
Halffacet_handle f_visible = f;
|
|
||||||
// CGAL_assertion( !f_visible->plane().has_on(ray.source()));
|
|
||||||
if( f_visible->plane().has_on_negative_side(ray.source()))
|
|
||||||
f_visible = f->twin();
|
|
||||||
CGAL_assertion( f_visible->plane().has_on_positive_side(ray.source()));
|
|
||||||
return f_visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool is_valid( bool verb = false, int level = 0) {
|
bool is_valid( bool verb = false, int level = 0) {
|
||||||
|
|
@ -703,7 +548,8 @@ class SNC_decorator : public SNC_const_decorator<Map> {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Visitor>
|
template <typename Visitor>
|
||||||
void visit_shell_objects(SFace_handle f, Visitor& V) const;
|
void visit_shell_objects(SFace_handle f, Visitor& V) const
|
||||||
|
{ Base::template visit_shell_objects<Visitor,Decorator_traits>(f, V); }
|
||||||
|
|
||||||
Vertex_iterator vertices_begin() { return sncp()->vertices_begin(); }
|
Vertex_iterator vertices_begin() { return sncp()->vertices_begin(); }
|
||||||
Vertex_iterator vertices_end() { return sncp()->vertices_end(); }
|
Vertex_iterator vertices_end() { return sncp()->vertices_end(); }
|
||||||
|
|
@ -729,146 +575,14 @@ class SNC_decorator : public SNC_const_decorator<Map> {
|
||||||
return c->shells_end();
|
return c->shells_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
Size_type number_of_vertices() const
|
using Base::number_of_vertices;
|
||||||
{ return sncp()->number_of_vertices(); }
|
using Base::number_of_halfedges;
|
||||||
Size_type number_of_halfedges() const
|
using Base::number_of_edges;
|
||||||
{ return sncp()->number_of_halfedges(); }
|
using Base::number_of_halffacets;
|
||||||
Size_type number_of_edges() const
|
using Base::number_of_facets;
|
||||||
{ return sncp()->number_of_edges(); }
|
using Base::number_of_volumes;
|
||||||
Size_type number_of_halffacets() const
|
|
||||||
{ return sncp()->number_of_halffacets();}
|
|
||||||
Size_type number_of_facets() const
|
|
||||||
{ return sncp()->number_of_facets();}
|
|
||||||
Size_type number_of_volumes() const
|
|
||||||
{ return sncp()->number_of_volumes();}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* visiting shell objects:
|
|
||||||
|
|
||||||
Objects are marked as done, when placed in the output list. We have
|
|
||||||
to maintain a stack of sface candidates (the spherical rubber sectors
|
|
||||||
that provide connectivity at the local graphs of vertices) and facet
|
|
||||||
candiates (the plane pieces in three space also providing
|
|
||||||
connectivity). Note that we have to take care about the orientation of
|
|
||||||
sobjects and facets. We have to take care that (1) the search along
|
|
||||||
the shell extends along the whole shell structure (2) does not visit
|
|
||||||
any object twice, and (3) all 3-space objects have to be reported and
|
|
||||||
this also just once.
|
|
||||||
|
|
||||||
The facets and sfaces are marked |done| when they are put into their
|
|
||||||
corresponding queues thus each such object is visited exactly once
|
|
||||||
when taken out of the queue.
|
|
||||||
|
|
||||||
When an sface |sf| is taken out of the queue |SFaceCandiates| its
|
|
||||||
boundary structure is examined and all 2-skeleton objects (vertices
|
|
||||||
and edges of 3-space) that are incident to the volume represented by
|
|
||||||
|sf| are reported. Facets are reported when they are taken out of
|
|
||||||
|FacetCandiates|.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
template <typename EW>
|
|
||||||
template <typename Visitor>
|
|
||||||
void SNC_decorator<EW>::
|
|
||||||
visit_shell_objects(SFace_handle f, Visitor& V) const
|
|
||||||
{
|
|
||||||
typedef typename SM_decorator::SHalfedge_around_sface_circulator
|
|
||||||
SHalfedge_around_sface_circulator;
|
|
||||||
std::list<SFace_handle> SFaceCandidates;
|
|
||||||
std::list<Halffacet_handle> FacetCandidates;
|
|
||||||
CGAL::Generic_handle_map<bool> Done(false);
|
|
||||||
SFaceCandidates.push_back(f); Done[f] = true;
|
|
||||||
while ( true ) {
|
|
||||||
if ( SFaceCandidates.empty() && FacetCandidates.empty() ) break;
|
|
||||||
if ( !FacetCandidates.empty() ) {
|
|
||||||
Halffacet_handle f = *FacetCandidates.begin();
|
|
||||||
FacetCandidates.pop_front();
|
|
||||||
V.visit(f); // report facet
|
|
||||||
Halffacet_cycle_iterator fc;
|
|
||||||
CGAL_forall_facet_cycles_of(fc,f) {
|
|
||||||
if (fc.is_shalfedge() ) {
|
|
||||||
SHalfedge_handle e(fc);
|
|
||||||
SHalfedge_around_facet_circulator ec(e),ee(e);
|
|
||||||
CGAL_For_all(ec,ee) { e = ec->twin();
|
|
||||||
if ( Done[e->incident_sface()] ) continue;
|
|
||||||
SFaceCandidates.push_back(e->incident_sface());
|
|
||||||
Done[e->incident_sface()] = true;
|
|
||||||
}
|
|
||||||
} else if (fc.is_shalfloop()) {
|
|
||||||
SHalfloop_handle l(fc);
|
|
||||||
l = l->twin();
|
|
||||||
if ( Done[l->incident_sface()] ) continue;
|
|
||||||
SFaceCandidates.push_back(l->incident_sface());
|
|
||||||
Done[l->incident_sface()] = true;
|
|
||||||
} else CGAL_error_msg("Damn wrong handle.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( !SFaceCandidates.empty() ) {
|
|
||||||
SFace_handle sf = *SFaceCandidates.begin();
|
|
||||||
SFaceCandidates.pop_front();
|
|
||||||
V.visit(sf); // report sface
|
|
||||||
if ( !Done[sf->center_vertex()] )
|
|
||||||
V.visit(sf->center_vertex()); // report vertex
|
|
||||||
Done[sf->center_vertex()] = true;
|
|
||||||
// SVertex_handle sv;
|
|
||||||
SM_decorator SD(&*sf->center_vertex());
|
|
||||||
/*
|
|
||||||
CGAL_forall_svertices(sv,SD){
|
|
||||||
if(SD.is_isolated(sv) && !Done[sv])
|
|
||||||
V.visit(sv);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
SFace_cycle_iterator fc;
|
|
||||||
CGAL_forall_sface_cycles_of(fc,sf) {
|
|
||||||
if ( fc.is_shalfedge() ) {
|
|
||||||
SHalfedge_handle e(fc);
|
|
||||||
SHalfedge_around_sface_circulator ec(e),ee(e);
|
|
||||||
CGAL_For_all(ec,ee) {
|
|
||||||
V.visit(SHalfedge_handle(ec));
|
|
||||||
SVertex_handle v = ec->twin()->source();
|
|
||||||
if ( !SD.is_isolated(v) && !Done[v] ) {
|
|
||||||
V.visit(v); // report edge
|
|
||||||
Done[v] = Done[v->twin()] = true;
|
|
||||||
}
|
|
||||||
Halffacet_handle f = ec->twin()->facet();
|
|
||||||
if ( Done[f] ) continue;
|
|
||||||
FacetCandidates.push_back(f); Done[f] = true;
|
|
||||||
}
|
|
||||||
} else if ( fc.is_svertex() ) {
|
|
||||||
SVertex_handle v(fc);
|
|
||||||
if ( Done[v] ) continue;
|
|
||||||
V.visit(v); // report edge
|
|
||||||
V.visit(v->twin());
|
|
||||||
Done[v] = Done[v->twin()] = true;
|
|
||||||
CGAL_assertion(SD.is_isolated(v));
|
|
||||||
SFaceCandidates.push_back(v->twin()->incident_sface());
|
|
||||||
Done[v->twin()->incident_sface()]=true;
|
|
||||||
// note that v is isolated, thus v->twin() is isolated too
|
|
||||||
// SM_decorator SD;
|
|
||||||
// SFace_handle fo;
|
|
||||||
// fo = v->twin()->incident_sface();
|
|
||||||
/*
|
|
||||||
if(SD.is_isolated(v))
|
|
||||||
fo = v->source()->sfaces_begin();
|
|
||||||
else
|
|
||||||
fo = v->twin()->incident_sface();
|
|
||||||
*/
|
|
||||||
// if ( Done[fo] ) continue;
|
|
||||||
// SFaceCandidates.push_back(fo); Done[fo] = true;
|
|
||||||
} else if (fc.is_shalfloop()) {
|
|
||||||
SHalfloop_handle l(fc);
|
|
||||||
V.visit(l);
|
|
||||||
Halffacet_handle f = l->twin()->facet();
|
|
||||||
if ( Done[f] ) continue;
|
|
||||||
FacetCandidates.push_back(f); Done[f] = true;
|
|
||||||
} else CGAL_error_msg("Damn wrong handle.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} //namespace CGAL
|
} //namespace CGAL
|
||||||
#endif //CGAL_SNC_DECORATOR_H
|
#endif //CGAL_SNC_DECORATOR_H
|
||||||
|
|
|
||||||
|
|
@ -37,11 +37,11 @@ public:
|
||||||
|
|
||||||
template <class H>
|
template <class H>
|
||||||
const I& operator[](H h) const
|
const I& operator[](H h) const
|
||||||
{ return Base::operator[](&*h); }
|
{ return Base::operator[]((void*)&*h); }
|
||||||
|
|
||||||
template <class H>
|
template <class H>
|
||||||
I& operator[](H h)
|
I& operator[](H h)
|
||||||
{ return Base::operator[](&*h); }
|
{ return Base::operator[]((void*)&*h); }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue