Corrections of facet below location process.

This commit is contained in:
Miguel Granados 2002-04-24 15:50:49 +00:00
parent a55e4001ae
commit 1a62b08ff2
6 changed files with 186 additions and 126 deletions

View File

@ -11,4 +11,5 @@ Nef_3 Package: TODO
- Find all intersections between two SNC's.
- Binary operations
- Extended kernel with infimaximal box
- Define endpoint of segments used for ray shoting to be in the
infimaximal box.

View File

@ -47,6 +47,8 @@
#define _DEBUG 43
#include <CGAL/Nef_3/debug.h>
#define IMMN 999999
CGAL_BEGIN_NAMESPACE
template < class Node, class Object, class DClass>
@ -296,84 +298,105 @@ public:
volumes. \precond |categorize_facet_cycles_and_creating_facets()| was
called before.}*/
Volume_handle determine_volume( const SFace_handle f,
const std::vector<Vertex_handle>& MinimalVertex,
const Shell_number_hash& Shell ) const {
Vertex_handle v_min = MinimalVertex[Shell[f]];
Volume_handle determine_volume( SFace_handle sf,
const std::vector< Vertex_handle>& MinimalVertex,
const Shell_number_hash& Shell ) const {
Vertex_handle v_min = MinimalVertex[Shell[sf]];
Halffacet_handle f_below = get_facet_below(v_min);
if ( f_below == Halffacet_handle())
// return volumes_begin(); //qualifiers discarded?
return Base(*this).volumes_begin();
Volume_handle c = volume(f_below);
if(c != Volume_handle())
if( c != Volume_handle()) {
TRACE( "Volume " << &*c << " hit ");
TRACEN("(Shell #" << Shell[adjacent_sface(f_below)] << ")");
return c;
SFace_handle sf = sface(f_below);
c = determine_volume(sf, MinimalVertex, Shell);
link_as_inner_shell(sf, c);
}
SFace_handle sf_below = adjacent_sface(f_below);
TRACEN( "Shell not assigned to a volume hit ");
TRACEN( "(Inner shell #" << Shell[sf] << ")");
c = determine_volume( sf_below, MinimalVertex, Shell);
link_as_inner_shell( sf_below, c);
return c;
}
Halffacet_handle get_facet_below(const Vertex_handle vi) const {
// Segment_3 s(point(v), point(vertices_begin())), // qualifiers discarded?
Segment_3 s(point(vi), point(Base(*this).vertices_begin())),
so(s.opposite());
Object_handle closest;
Vertex_handle v;
Halfedge_handle e;
Halffacet_handle f;
CGAL_forall_vertices(v,*sncp()) {
SFace_iterator sf = v->sfaces_begin();
if (sf != 0 && volume(sf) != Volume_handle()
&& contains_internally(s,point(v))) {
shorten(s,point(v));
closest = Object_handle(v);
Halffacet_handle get_visible_facet( Vertex_handle v, Sphere_point p) const {
TRACEN( "Locating " << p <<" in " << point(v));
SM_point_locator L(v);
SObject_handle o = L.locate(p);
SFace_const_handle sf;
CGAL_assertion( assign( sf, o));
assign( sf, o);
SFace_cycle_const_iterator fc;
CGAL_forall_sface_cycles_of( fc, sf) {
SHalfedge_handle se;
if ( assign( se, fc) ) {
TRACEN( "adjacent facet found.");
return facet(twin(se));
}
}
CGAL_forall_edges(e,*sncp()) {
Point_3 q;
SFace_handle sf = sface(e);
if (sf != SFace_handle() && volume(sf) != Volume_handle()
&& do_intersect(s,e,q) ) {
shorten(s,q);
closest = Object_handle(e);
}
}
CGAL_forall_halffacets(f,*sncp()) {
Point_3 q;
SFace_handle sf = sface(f);
if (sf != SFace_handle() && volume(sf) != Volume_handle()
&& do_intersect(s,f,q) ) {
shorten(s,q);
closest = Object_handle(f);
}
}
if( assign(closest, v) ) {
SHalfedge_handle se = v->shalfedges_begin();
if( se != SHalfedge_handle() )
return facet(se);
SHalfloop_handle sl = v->shalfloop();
if( sl != SHalfloop_handle() )
return facet(sl);
CGAL_assertion_msg(0, "Empty local map.");
}
else if( assign( closest, e ) ) {
SM_decorator SD(vertex(e));
CGAL_assertion( SD.first_out_edge(e) != SHalfedge_handle() );
return facet(SD.first_out_edge(e));
}
else if( assign( closest, f ) )
return f;
else
TRACEN("no facet below found");
TRACEN( "no adjacent facet found.");
return Halffacet_handle();
}
/* following 4 functions were copied from SNC_point_locator.h */
void shorten(Segment_3& s, const Point_3& p) const
{ s = Segment_3(s.source(),p); }
Halffacet_handle get_facet_below( Vertex_handle vi) const {
Segment_3 s(point(vi), Point_3( 0, 0, -IMMN));
/* TODO: replace IMMN constant for a real infimaximal number */
TRACEN( "Shoting ray " << s);
Halffacet_handle f_below;
Vertex_handle v;
CGAL_forall_vertices( v, *sncp()) {
if ( contains_internally( s, point(v))) {
TRACEN("ray hit vertex case");
Sphere_point sp(point(vi)-point(v));
Halffacet_handle f_visible = get_visible_facet(v, sp);
if ( f_visible != Halffacet_handle()) {
shorten( s, point(v));
f_below = f_visible;
}
}
}
Halfedge_handle e;
CGAL_forall_edges( e, *sncp()) {
Point_3 q;
if ( do_intersect( s, e, q) ) { // internally only?
TRACEN("ray hit edge case");
v = vertex(e);
Sphere_point sp(point(vi)-point(v));
Halffacet_handle f_visible = get_visible_facet(v, sp);
if ( f_visible != Halffacet_handle()) {
shorten( s, q);
f_below = f_visible;
}
}
}
Halffacet_handle f;
CGAL_forall_halffacets( f, *sncp()) { // internally only?
Point_3 q;
if ( do_intersect( s, f, q) ) {
TRACEN("ray hit facet case");
Halffacet_cycle_iterator fc(f->facet_cycles_begin());
CGAL_assertion( fc != f->facet_cycles_end());
SHalfedge_handle se;
CGAL_assertion( assign( se, fc) );
v = vertex(se);
Sphere_point sp(point(vi)-point(v));
Halffacet_handle f_visible = get_visible_facet(v, sp);
if ( f_visible != Halffacet_handle()) {
shorten( s, q);
f_below = f_visible;
}
}
}
return f_below;
}
bool contains_internally(const Segment_3& s, const Point_3& p) const
{ if(!s.has_on(p))
void shorten(Segment_3& s, const Point_3& p) const {
s = Segment_3( s.source(), p);
}
bool contains_internally(const Segment_3& s, const Point_3& p) const {
if(!s.has_on(p))
return false;
Comparison_result r1 = compare_xyz(s.source(),p);
Comparison_result r2 = compare_xyz(s.target(),p);
@ -405,23 +428,22 @@ public:
const Segment_3& r,
Point_3& p) const
{
if(s.is_degenerate() || r.is_degenerate())
if ( s.is_degenerate() || r.is_degenerate())
return false;
/* at least one of the segments is degenerate so
there is not internal intersection */
if(orientation(s.source(),s.target(),r.source(),r.target()) != COPLANAR)
if ( orientation(s.source(),s.target(),r.source(),r.target()) != COPLANAR)
return false;
/* the segments doesn't define a plane */
if(collinear(s.source(),s.target(),r.source()) &&
collinear(s.source(),s.target(),r.target()) )
if ( collinear(s.source(),s.target(),r.source()) &&
collinear(s.source(),s.target(),r.target()) )
return false;
/* the segments are collinear */
Line_3 ls(s), lr(r);
if(ls.direction() == lr.direction() ||
ls.direction() == -lr.direction() )
if ( ls.direction() == lr.direction() ||
ls.direction() == -lr.direction() )
return false;
/* the segments are parallel */
Oriented_side os1, os2;
Vector_3 vs(s.direction()), vr(r.direction()), vt(cross_product(vs, vr)),
ws(cross_product(vt, vs)), wr(cross_product(vt, vr));
@ -439,13 +461,12 @@ public:
os2 = hr.oriented_side(s.target());
if(os1 != opposite(os2))
return false;
Object o = intersection(hs, lr);
CGAL_assertion(assign(p,o));
/* since line(s) and line(r) are not parallel they intersects in only
one point */
assign(p,o);
if( !contains_internally(s, p) || !contains_internally(r, p) )
if ( !contains_internally(s, p) || !contains_internally(r, p) )
return false;
return true;
}
@ -455,31 +476,36 @@ public:
Halffacet_handle f,
Point_3& p) const {
Plane_3 h(plane(f));
// TRACEN("intersecting "<<Line_3(s)<<" "<<h);
Object o = intersection(h, Line_3(s));
if ( !CGAL::assign(p,o) )
return false;
Oriented_side os1 = h.oriented_side(s.source());
Oriented_side os2 = h.oriented_side(s.target());
// TRACEN("source side: "<<os1<<", target side: "<<os2);
if (os1 != opposite(os2))
return false;
TRACEN( "Point in facet result = "<<locate_point_in_halffacet(p, f));
return (locate_point_in_halffacet(p, f) == CGAL::ON_BOUNDED_SIDE);
}
Bounded_side locate_point_in_halffacet( const Point_3& p,
const Halffacet_handle& f) const {
typedef Project_halfedge_point< SHalfedge, const Point_3, SNC_decorator>
Project;
typedef Iterator_project< SHalfedge_handle, Project,
const Point_3, const Point_3*> Circulator;
typedef Project_halfedge_point
< SHalfedge, const Point_3, SNC_decorator> Project;
typedef Iterator_project
< SHalfedge_handle, Project, const Point_3, const Point_3*> Circulator;
typedef Container_from_circulator<Circulator> Container;
Plane_3 h(plane(f));
CGAL_assertion(h.has_on(p));
Halffacet_cycle_iterator fc = f->facet_cycles_begin();
SHalfedge_handle e;
Bounded_side outer_bound_pos;
if ( assign(e,fc) ) {
Circulator first(e), beyond(e);
outer_bound_pos = bounded_side_3(first, beyond, p, h);
} else
Container pts(Circulator(e));
outer_bound_pos = bounded_side_3(pts.begin(), pts.end(), p, h);
}
else
CGAL_assertion_msg(0, "facet's first cycle is a SHalfloop?");
if( outer_bound_pos != CGAL::ON_BOUNDED_SIDE )
return outer_bound_pos;
@ -498,10 +524,14 @@ public:
inner_bound_pos = CGAL::ON_BOUNDARY;
else
inner_bound_pos = CGAL::ON_UNBOUNDED_SIDE;
} else if ( assign(e,fc) ) {
Circulator first(e), beyond(e);
inner_bound_pos = bounded_side_3(first, beyond, p, h.opposite());
} else CGAL_assertion_msg(0, "Damn wrong handle.");
}
else if ( assign(e,fc) ) {
Container pts(Circulator(e));
inner_bound_pos = bounded_side_3(pts.begin(), pts.end(), p,
h.opposite());
}
else
CGAL_assertion_msg(0, "Damn wrong handle.");
if( inner_bound_pos != CGAL::ON_UNBOUNDED_SIDE )
return opposite(inner_bound_pos);
/* At this point the point p belongs to relative interior of the facet's
@ -805,30 +835,34 @@ create_volumes() const
}
Volume_handle outer_volume = sncp()->new_volume();
//link_as_outer_shell( SFace_handle(), outer_volume); // dummy outer shell
for (unsigned i = 0; i < MinimalVertex.size(); ++i) {
TRACEN("minimal vertex "<<i<<" "<<point(MinimalVertex[i]));
Vertex_handle v = MinimalVertex[i];
TRACEN("Shell #"<<i<<" minimal vertex: "<<point(v));
if(true) { // v is not a bounding box vertex, TODO
bool create_shell = false;
SM_point_locator D(v);
SObject_handle o = D.locate(Sphere_point(-1,0,0));
SFace_const_handle sfc;
if( !assign(sfc, o)) {
TRACEN( "outer shell (no sface case)? #" << i);
TRACEN( "Shell #"<<i<<" is outer candidate (sface not hit case)");
create_shell = true;
}
else {
TRACEN( "outer shell (sface case)? #" << i);
if( Shell[sfc] != i)
if( Shell[sfc] != i) {
TRACEN( "Shell #"<<i<<" is outer candidate (sface hit case)");
create_shell = true;
}
}
if ( create_shell ) {
SFace_handle f = EntrySFace[i];
TRACEN( "closed shell? " << Closed[f]);
CGAL_assertion( Shell[EntrySFace[i]] == i );
TRACEN( "is outer shell #" << i <<" closed? " << Closed[f]);
if( Closed[f] ) {
Volume_handle c = sncp()->new_volume();
link_as_outer_shell(f, c );
TRACEN( "Shell #" << i <<" linked as outer shell ("<<
(c == volume(f))<<")");
}
}
}
@ -837,6 +871,7 @@ create_volumes() const
CGAL_forall_sfaces(f,*sncp()) {
if ( volume(f) != Volume_handle() )
continue;
TRACEN( "Inner shell #" << Shell[f] <<" visited");
Volume_handle c = determine_volume( f, MinimalVertex, Shell );
link_as_inner_shell( f, c );
}

View File

@ -36,6 +36,10 @@
#include <CGAL/Nef_3/SNC_iteration.h>
#include <CGAL/Nef_3/SNC_SM_decorator.h>
#undef _DEBUG
#define _DEBUG 13
#include <CGAL/Nef_3/debug.h>
CGAL_BEGIN_NAMESPACE
template <typename SNC_structure_>
@ -96,17 +100,17 @@ public:
SNC_decorator(SNC_structure& W) : sncp_(&W) {}
SNC_structure* sncp() const { return sncp_; }
Vertex_handle vertex(const Halfedge_handle e) const
Vertex_handle vertex( Halfedge_handle e) const
{ return e->center_vertex_; }
Halfedge_handle twin(const Halfedge_handle e) const
Halfedge_handle twin( Halfedge_handle e) const
{ return e->twin_; }
Vertex_handle source(const Halfedge_handle e) const
Vertex_handle source( Halfedge_handle e) const
{ return e->center_vertex_; }
Vertex_handle target(const Halfedge_handle e) const
Vertex_handle target( Halfedge_handle e) const
{ return source(twin(e)); }
SFace_handle sface(const Halfedge_handle e) const
SFace_handle sface( Halfedge_handle e) const
{ return e->incident_sface_; }
SFace_const_handle sface(const Halfedge_const_handle e) const
SFace_const_handle sface( Halfedge_const_handle e) const
{ return e->incident_sface_; }
/* SVertex queries*/
@ -150,15 +154,15 @@ public:
std::string res(os.str()); os.freeze(0); return res;
}
SHalfloop_handle twin(const SHalfloop_handle l) const
SHalfloop_handle twin( SHalfloop_handle l) const
{ return l->twin_; }
Halffacet_handle facet(const SHalfloop_handle l) const
Halffacet_handle facet( SHalfloop_handle l) const
{ return l->incident_facet_; }
Vertex_handle vertex(const SHalfloop_handle l) const
Vertex_handle vertex( SHalfloop_handle l) const
{ return l->incident_sface_->center_vertex_; }
SFace_handle sface(const SHalfloop_handle l) const
SFace_handle sface( SHalfloop_handle l) const
{ return l->incident_sface_; }
SFace_const_handle sface(const SHalfloop_const_handle l) const
SFace_const_handle sface( SHalfloop_const_handle l) const
{ return l->incident_sface_; }
/* SHalfloop queries */
@ -171,23 +175,24 @@ public:
Halffacet_handle twin(Halffacet_handle f) const
{ return f->twin_; }
Volume_handle volume(Halffacet_handle f) const
{ return f->volume_; }
SFace_handle sface(Halffacet_handle f) const {
Halffacet_cycle_iterator fc(f->facet_cycles_begin());
CGAL_assertion( fc != f->facet_cycles_end() );
SHalfedge_handle e;
SHalfloop_handle l;
if ( assign(e, fc) ) {
SHalfedge_around_facet_circulator se(e);
CGAL_assertion( se != 0 );
return sface(se);
} else if ( assign(l, fc) ) {
return sface(l);
} else CGAL_assertion_msg(0, "Damn wrong handle.");
return SFace_handle(); // never reached
}
{ return f->volume_; }
/* Halffacet queries */
SFace_handle adjacent_sface(Halffacet_handle f) const {
Halffacet_cycle_iterator fc(f->facet_cycles_begin());
CGAL_assertion( fc != f->facet_cycles_end());
SHalfedge_handle se;
if ( assign(se, fc) ) {
CGAL_assertion( facet(se) == f);
CGAL_assertion( sface(se) != SFace_handle());
CGAL_assertion( volume(sface(twin(se))) == volume(f));
return sface(twin(se));
}
else
CGAL_assertion_msg( 0, "Facet outer cycle entry point"
"is not an SHalfedge? ");
return SFace_handle(); // never reached
}
// attributes::
Point_3& point(Vertex_handle v) const
@ -273,33 +278,41 @@ public:
Volume_handle c;
Shell_volume_setter(const SNC_decorator& Di, Volume_handle& ci)
: D(Di), c(ci) {}
void visit(SFace_handle h) { D.set_volume(h, c); }
void visit(SFace_handle h) {
// TRACEN("volume assigned to SFace "<<&*h);
D.set_volume(h, c);
}
void visit(Vertex_handle h) { /* empty */ }
void visit(Halfedge_handle h) { /* empty */ }
void visit(Halffacet_handle h ) { D.set_volume(h, c); }
void visit(Halffacet_handle h ) {
// TRACEN("volume assigned to Halffacet "<<&*h);
D.set_volume(h, c);
}
void set_volume(Volume_handle ci) { c = ci; }
};
void link_as_outer_shell( SFace_handle f, Volume_handle c ) const {
CGAL_assertion(c->shell_entry_objects_.size() == 0);
Shell_volume_setter Setter(*this, c);
// TRACEN("Setting volume pointer to shell items...");
visit_shell_objects( f, Setter );
// TRACEN("Done");
TRACEN("Volume "<<&*c<<", outer shell "<<&*f);
store_boundary_object( f, c );
}
void link_as_inner_shell( SFace_handle f, Volume_handle c ) const {
// CGAL_assertion(c->shell_entry_objects_.size() > 0);
// the bounding infimaximal box is not yet stored so its entry objects
// list could be empty
//CGAL_assertion(c->shell_entry_objects_.size() > 0);
Shell_volume_setter Setter(*this, c);
visit_shell_objects( f, Setter );
TRACEN("Volume "<<&*c<<", inner shell "<<&*f);
store_boundary_object( f, c );
}
void set_volume(Halffacet_handle& h, Volume_handle& c) const
{ h->volume_ = c; }
void set_volume(SFace_handle& h, Volume_handle& c) const
{ h->incident_volume_ = c; }
void set_volume(Halffacet_handle h, Volume_handle c) const
{ h->volume_ = c; CGAL_assertion(h->volume_ == c); }
void set_volume(SFace_handle h, Volume_handle c) const
{ h->incident_volume_ = c; CGAL_assertion(h->incident_volume_ == c); }
template <typename Visitor>
void visit_shell_objects(SFace_handle f, Visitor& V) const;

View File

@ -42,6 +42,7 @@ CGAL_BEGIN_NAMESPACE
template <typename K, typename M> class SNC_items;
template <typename I> class SNC_structure;
template <typename R> class SNC_decorator;
template <typename R> class SNC_constructor;
template <typename R> class SNC_io_parser;
template <typename R> class SNC_SM_decorator;
template <typename R> class SNC_SM_const_decorator;
@ -79,6 +80,7 @@ public:
friend class SNC_structure<Items>;
friend class SNC_decorator<Refs>;
friend class SNC_io_parser<Refs>;
friend class SNC_constructor<Refs>;
friend class SNC_SM_decorator<Refs>;
friend class SNC_SM_const_decorator<Refs>;
typedef typename Refs::SVertex_iterator SVertex_iterator;
@ -297,6 +299,7 @@ public:
friend class SNC_structure<Items>;
friend class SNC_decorator<Refs>;
friend class SNC_io_parser<Refs>;
friend class SNC_constructor<Refs>;
friend class SNC_SM_decorator<Refs>;
friend class SNC_SM_const_decorator<Refs>;
typedef typename Refs::Vertex_handle Vertex_handle;
@ -376,6 +379,7 @@ public:
friend class SNC_structure<Items>;
friend class SNC_decorator<Refs>;
friend class SNC_io_parser<Refs>;
friend class SNC_constructor<Refs>;
friend class SNC_SM_decorator<Refs>;
friend class SNC_SM_const_decorator<Refs>;
friend class SNC_FM_decorator<Refs>;
@ -451,6 +455,7 @@ public:
friend class SNC_structure<Items>;
friend class SNC_decorator<Refs>;
friend class SNC_io_parser<Refs>;
friend class SNC_constructor<Refs>;
friend class SNC_SM_decorator<Refs>;
friend class SNC_SM_const_decorator<Refs>;
typedef typename Refs::Object_handle Object_handle;
@ -516,6 +521,7 @@ public:
friend class SNC_structure<Items>;
friend class SNC_decorator<Refs>;
friend class SNC_io_parser<Refs>;
friend class SNC_constructor<Refs>;
friend class SNC_SM_decorator<Refs>;
friend class SNC_SM_const_decorator<Refs>;
friend class move_shalfedge_around_svertex<SHalfedge_handle>;
@ -615,6 +621,7 @@ public:
friend class SNC_structure<Items>;
friend class SNC_decorator<Refs>;
friend class SNC_io_parser<Refs>;
friend class SNC_constructor<Refs>;
friend class SNC_SM_decorator<Refs>;
friend class SNC_SM_const_decorator<Refs>;
friend class Self::Vertex<Refs>;
@ -682,6 +689,7 @@ public:
friend class SNC_structure<Items>;
friend class SNC_decorator<Refs>;
friend class SNC_io_parser<Refs>;
friend class SNC_constructor<Refs>;
friend class SNC_SM_decorator<Refs>;
friend class SNC_SM_const_decorator<Refs>;
typedef typename Refs::Vertex_handle Vertex_handle;

View File

@ -34,6 +34,7 @@
#include <CGAL/basic.h>
#include <CGAL/Polygon_2_algorithms.h>
#include <CGAL/Iterator_project.h>
#include <vector>
CGAL_BEGIN_NAMESPACE
@ -63,6 +64,8 @@ Bounded_side bounded_side_3(ForwardIterator first,
typedef typename R::Direction_3 Direction_3;
typedef typename R::Plane_3 Plane_3;
CGAL_assertion( !is_empty_range(first, last));
if(plane == Plane_3()) {
ForwardIterator p(first);
Point_3 p0(*(p++));

View File

@ -1,4 +1,4 @@
#define CGAL_P2NEF3_USE_SM_OVERLAY
//#define CGAL_P2NEF3_USE_SM_OVERLAY
// ============================================================================
//
// Copyright (c) 1997-2002 The CGAL Consortium