mirror of https://github.com/CGAL/cgal
WIP: operations almost all working in regular cases
This commit is contained in:
parent
683d783cdd
commit
aaf05585b5
|
|
@ -1317,6 +1317,72 @@ flip_edge(typename boost::graph_traits<Graph>::halfedge_descriptor h,
|
|||
set_halfedge(foh,oh,g);
|
||||
}
|
||||
|
||||
/// \todo document me
|
||||
template <typename Graph>
|
||||
void shift_source (typename boost::graph_traits<Graph>::halfedge_descriptor h,
|
||||
Graph& g)
|
||||
{
|
||||
typedef typename boost::graph_traits<Graph> Traits;
|
||||
typedef typename Traits::halfedge_descriptor halfedge_descriptor;
|
||||
typedef typename Traits::vertex_descriptor vertex_descriptor;
|
||||
typedef typename Traits::face_descriptor face_descriptor;
|
||||
|
||||
|
||||
halfedge_descriptor hp = prev (h, g);
|
||||
halfedge_descriptor ho = opposite (h, g);
|
||||
halfedge_descriptor hon = next (ho, g);
|
||||
halfedge_descriptor hpp = prev (hp, g);
|
||||
vertex_descriptor vppt = target (hpp, g);
|
||||
|
||||
face_descriptor f = face (h, g);
|
||||
face_descriptor fo = face (ho, g);
|
||||
|
||||
CGAL_assertion (f != Traits::null_face());
|
||||
CGAL_assertion (fo != Traits::null_face());
|
||||
|
||||
if (halfedge (f, g) == hp)
|
||||
set_halfedge (f, h, g);
|
||||
|
||||
set_next (ho, hp, g);
|
||||
set_next (hp, hon, g);
|
||||
set_next (hpp, h, g);
|
||||
set_target (ho, vppt, g);
|
||||
set_face (hp, fo, g);
|
||||
}
|
||||
|
||||
/// \todo document me
|
||||
template <typename Graph>
|
||||
void shift_target (typename boost::graph_traits<Graph>::halfedge_descriptor h,
|
||||
Graph& g)
|
||||
{
|
||||
typedef typename boost::graph_traits<Graph> Traits;
|
||||
typedef typename Traits::halfedge_descriptor halfedge_descriptor;
|
||||
typedef typename Traits::vertex_descriptor vertex_descriptor;
|
||||
typedef typename Traits::face_descriptor face_descriptor;
|
||||
|
||||
halfedge_descriptor hn = next (h, g);
|
||||
halfedge_descriptor ho = opposite (h, g);
|
||||
halfedge_descriptor hop = prev (ho, g);
|
||||
halfedge_descriptor hnn = next (hn, g);
|
||||
vertex_descriptor vnt = target (hn, g);
|
||||
|
||||
face_descriptor f = face (h, g);
|
||||
face_descriptor fo = face (ho, g);
|
||||
|
||||
CGAL_assertion (f != Traits::null_face());
|
||||
CGAL_assertion (fo != Traits::null_face());
|
||||
|
||||
if (halfedge (f, g) == hn)
|
||||
set_halfedge (f, h, g);
|
||||
|
||||
set_next (hop, hn, g);
|
||||
set_next (hn, ho, g);
|
||||
set_next (h, hnn, g);
|
||||
set_target (h, vnt, g);
|
||||
set_face (hn, fo, g);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \returns `true` if `e` satisfies the *link condition* \cgalCite{degn-tpec-98}, which guarantees that the surface is also 2-manifold after the edge collapse.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
|
||||
#define CGAL_KSR_VERBOSE_LEVEL 3
|
||||
#define CGAL_KSR_VERBOSE_LEVEL 4
|
||||
#include <CGAL/Kinetic_shape_reconstruction_3.h>
|
||||
|
||||
#include <CGAL/IO/PLY_reader.h>
|
||||
|
|
|
|||
|
|
@ -53,6 +53,26 @@ void dump_intersection_edges (const DS& data, const std::string& tag = std::stri
|
|||
out << "2 " << data.segment_3 (iedge) << std::endl;
|
||||
}
|
||||
|
||||
template <typename DS>
|
||||
void dump_segmented_edges (const DS& data, const std::string& tag = std::string())
|
||||
{
|
||||
std::vector<std::ofstream*> out;
|
||||
for (KSR::size_t i = 0; i < data.nb_intersection_lines(); ++ i)
|
||||
{
|
||||
std::string filename = (tag != std::string() ? tag + "_" : "") + "intersection_line_" + std::to_string(i) + ".polylines.txt";
|
||||
out.push_back (new std::ofstream (filename));
|
||||
out.back()->precision(18);
|
||||
}
|
||||
|
||||
for (const typename DS::IEdge& iedge : data.iedges())
|
||||
{
|
||||
CGAL_assertion (data.line_idx(iedge) != KSR::no_element());
|
||||
*(out[data.line_idx(iedge)]) << "2 " << data.segment_3 (iedge) << std::endl;
|
||||
}
|
||||
for (std::ofstream* o : out)
|
||||
delete o;
|
||||
}
|
||||
|
||||
template <typename DS>
|
||||
void dump_constrained_edges (const DS& data, const std::string& tag = std::string())
|
||||
{
|
||||
|
|
@ -84,53 +104,53 @@ void dump_polygons (const DS& data, const std::string& tag = std::string())
|
|||
Uchar_map bbox_green = bbox_mesh.template add_property_map<typename Mesh::Face_index, unsigned char>("green", 0).first;
|
||||
Uchar_map bbox_blue = bbox_mesh.template add_property_map<typename Mesh::Face_index, unsigned char>("blue", 0).first;
|
||||
|
||||
KSR::size_t bbox_nb_vertices = 0;
|
||||
KSR::size_t nb_vertices = 0;
|
||||
|
||||
KSR::vector<typename Mesh::Vertex_index> vertices;
|
||||
KSR::vector<typename Mesh::Vertex_index> map_vertices;
|
||||
|
||||
for (KSR::size_t i = 0; i < data.number_of_support_planes(); ++ i)
|
||||
{
|
||||
if (data.is_bbox_support_plane(i))
|
||||
{
|
||||
KSR::size_t new_vertices = 0;
|
||||
map_vertices.clear();
|
||||
for (typename DS::PVertex pvertex : data.pvertices(i))
|
||||
{
|
||||
bbox_mesh.add_vertex (data.point_3(pvertex));
|
||||
++ new_vertices;
|
||||
if (map_vertices.size() <= pvertex.second)
|
||||
map_vertices.resize (pvertex.second + 1);
|
||||
map_vertices[pvertex.second] = bbox_mesh.add_vertex (data.point_3(pvertex));
|
||||
}
|
||||
|
||||
for (typename DS::PFace pface : data.pfaces(i))
|
||||
{
|
||||
vertices.clear();
|
||||
for(typename DS::PVertex pvertex : data.pvertices_of_pface(pface))
|
||||
vertices.push_back (typename Mesh::Vertex_index(KSR::size_t(pvertex.second) + bbox_nb_vertices));
|
||||
vertices.push_back (map_vertices[pvertex.second]);
|
||||
|
||||
typename Mesh::Face_index face = bbox_mesh.add_face (vertices);
|
||||
std::tie (bbox_red[face], bbox_green[face], bbox_blue[face])
|
||||
= get_idx_color ((i+1) * (pface.second+1));
|
||||
}
|
||||
bbox_nb_vertices += new_vertices;
|
||||
}
|
||||
else
|
||||
{
|
||||
KSR::size_t new_vertices = 0;
|
||||
map_vertices.clear();
|
||||
for (typename DS::PVertex pvertex : data.pvertices(i))
|
||||
{
|
||||
mesh.add_vertex (data.point_3 (pvertex));
|
||||
++ new_vertices;
|
||||
if (map_vertices.size() <= pvertex.second)
|
||||
map_vertices.resize (pvertex.second + 1);
|
||||
map_vertices[pvertex.second] = mesh.add_vertex (data.point_3 (pvertex));
|
||||
}
|
||||
|
||||
for (typename DS::PFace pface : data.pfaces(i))
|
||||
{
|
||||
vertices.clear();
|
||||
|
||||
for(typename DS::PVertex pvertex : data.pvertices_of_pface(pface))
|
||||
vertices.push_back (typename Mesh::Vertex_index(KSR::size_t(pvertex.second) + nb_vertices));
|
||||
|
||||
vertices.push_back (map_vertices[pvertex.second]);
|
||||
|
||||
typename Mesh::Face_index face = mesh.add_face (vertices);
|
||||
std::tie (red[face], green[face], blue[face])
|
||||
= get_idx_color (i * (pface.second+1));
|
||||
}
|
||||
nb_vertices += new_vertices;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -139,7 +159,7 @@ void dump_polygons (const DS& data, const std::string& tag = std::string())
|
|||
CGAL::set_binary_mode (out);
|
||||
CGAL::write_ply(out, mesh);
|
||||
|
||||
#if 1
|
||||
#if 0
|
||||
std::string bbox_filename = (tag != std::string() ? tag + "_" : "") + "bbox_polygons.ply";
|
||||
std::ofstream bbox_out (bbox_filename);
|
||||
CGAL::set_binary_mode (bbox_out);
|
||||
|
|
@ -148,19 +168,57 @@ void dump_polygons (const DS& data, const std::string& tag = std::string())
|
|||
|
||||
}
|
||||
|
||||
template <typename DS>
|
||||
void dump_polygon_borders (const DS& data, const std::string& tag = std::string())
|
||||
{
|
||||
std::string filename = (tag != std::string() ? tag + "_" : "") + "polygon_borders.polylines.txt";
|
||||
std::ofstream out (filename);
|
||||
|
||||
for (KSR::size_t i = 6; i < data.number_of_support_planes(); ++ i)
|
||||
for (const typename DS::PEdge pedge : data.pedges(i))
|
||||
out << "2 " << data.segment_3 (pedge) << std::endl;
|
||||
}
|
||||
|
||||
template <typename DS, typename Event>
|
||||
void dump_event (const DS& data, const Event& ev, const std::string& tag = std::string())
|
||||
{
|
||||
std::string lfilename = (tag != std::string() ? tag + "_" : "") + "event_line.polylines.txt";
|
||||
std::ofstream lout (lfilename);
|
||||
lout.precision(18);
|
||||
if (ev.is_pvertex_to_pvertex())
|
||||
{
|
||||
std::string vfilename = (tag != std::string() ? tag + "_" : "") + "event_pvertex.xyz";
|
||||
std::ofstream vout (vfilename);
|
||||
vout.precision(18);
|
||||
vout << data.point_3 (ev.pvertex()) << std::endl;
|
||||
|
||||
// TODO
|
||||
std::string ofilename = (tag != std::string() ? tag + "_" : "") + "event_pother.xyz";
|
||||
std::ofstream oout (ofilename);
|
||||
oout.precision(18);
|
||||
oout << data.point_3 (ev.pother()) << std::endl;
|
||||
}
|
||||
else if (ev.is_pvertex_to_iedge())
|
||||
{
|
||||
std::string lfilename = (tag != std::string() ? tag + "_" : "") + "event_iedge.polylines.txt";
|
||||
std::ofstream lout (lfilename);
|
||||
lout.precision(18);
|
||||
lout << "2 " << data.segment_3 (ev.iedge()) << std::endl;
|
||||
|
||||
std::string vfilename = (tag != std::string() ? tag + "_" : "") + "event_pvertex.xyz";
|
||||
std::ofstream vout (vfilename);
|
||||
vout.precision(18);
|
||||
vout << data.point_3 (ev.pvertex());
|
||||
}
|
||||
else if (ev.is_pvertex_to_ivertex())
|
||||
{
|
||||
std::string vfilename = (tag != std::string() ? tag + "_" : "") + "event_pvertex.xyz";
|
||||
std::ofstream vout (vfilename);
|
||||
vout.precision(18);
|
||||
vout << data.point_3 (ev.pvertex()) << std::endl;
|
||||
|
||||
std::string ofilename = (tag != std::string() ? tag + "_" : "") + "event_ivertex.xyz";
|
||||
std::ofstream oout (ofilename);
|
||||
oout.precision(18);
|
||||
oout << data.point_3 (ev.ivertex()) << std::endl;
|
||||
}
|
||||
|
||||
std::string vfilename = (tag != std::string() ? tag + "_" : "") + "event_vertex.xyz";
|
||||
std::ofstream vout (vfilename);
|
||||
vout.precision(18);
|
||||
// vout << data.point_of_vertex(ev.vertex_idx()) << std::endl;
|
||||
}
|
||||
|
||||
template <typename DS>
|
||||
|
|
@ -168,10 +226,12 @@ void dump (const DS& data, const std::string& tag = std::string())
|
|||
{
|
||||
dump_intersection_edges (data, tag);
|
||||
dump_constrained_edges (data, tag);
|
||||
dump_polygon_borders (data, tag);
|
||||
dump_polygons (data, tag);
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace KSR_3
|
||||
} // namespace CGAL
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -48,40 +48,94 @@ public:
|
|||
|
||||
typedef Event_queue<Data> Queue;
|
||||
friend Queue;
|
||||
|
||||
enum Type
|
||||
{
|
||||
FREE_VERTEX_TO_INTERSECTION_EDGE,
|
||||
CONSTRAINED_VERTEX_TO_FREE_VERTEX,
|
||||
CONSTRAINED_VERTEX_TO_INTERSECTION_VERTEX,
|
||||
CONSTRAINED_VERTEX_TO_CONSTRAINED_VERTEX,
|
||||
EDGE_TO_INTERSECTION_EDGE
|
||||
};
|
||||
|
||||
|
||||
private:
|
||||
|
||||
PVertex m_pvertex;
|
||||
|
||||
PVertex m_pother;
|
||||
IEdge m_iedge;
|
||||
IVertex m_ivertex;
|
||||
|
||||
FT m_time;
|
||||
|
||||
public:
|
||||
|
||||
Event () { }
|
||||
Event ()
|
||||
: m_pvertex (Data::null_pvertex())
|
||||
, m_pother (Data::null_pvertex())
|
||||
, m_iedge (Data::null_iedge())
|
||||
, m_ivertex (Data::null_ivertex())
|
||||
, m_time (0)
|
||||
{ }
|
||||
|
||||
Event (PVertex pvertex, PVertex pother, FT time)
|
||||
: m_pvertex (pvertex)
|
||||
, m_pother (pother)
|
||||
, m_iedge (Data::null_iedge())
|
||||
, m_ivertex (Data::null_ivertex())
|
||||
, m_time (time)
|
||||
{ }
|
||||
|
||||
Event (PVertex pvertex, IEdge iedge, FT time)
|
||||
: m_pvertex (pvertex)
|
||||
, m_iedge (iedge), m_time (time)
|
||||
, m_pother (Data::null_pvertex())
|
||||
, m_iedge (iedge)
|
||||
, m_ivertex (Data::null_ivertex())
|
||||
, m_time (time)
|
||||
{ }
|
||||
|
||||
Event (PVertex pvertex, IVertex ivertex, FT time)
|
||||
: m_pvertex (pvertex)
|
||||
, m_pother (Data::null_pvertex())
|
||||
, m_iedge (Data::null_iedge())
|
||||
, m_ivertex (ivertex)
|
||||
, m_time (time)
|
||||
{ }
|
||||
|
||||
Event (PVertex pvertex, PVertex pother, IVertex ivertex, FT time)
|
||||
: m_pvertex (pvertex)
|
||||
, m_pother (pother)
|
||||
, m_iedge (Data::null_iedge())
|
||||
, m_ivertex (ivertex)
|
||||
, m_time (time)
|
||||
{ }
|
||||
|
||||
PVertex pvertex() const { return m_pvertex; }
|
||||
PVertex pother() const { return m_pother; }
|
||||
IEdge iedge() const { return m_iedge; }
|
||||
IVertex ivertex() const { return m_ivertex; }
|
||||
FT time() const { return m_time; }
|
||||
|
||||
bool is_pvertex_to_pvertex() const { return (m_pother != Data::null_pvertex()); }
|
||||
bool is_pvertex_to_iedge() const { return (m_iedge != Data::null_iedge()); }
|
||||
|
||||
bool is_pvertex_to_ivertex() const { return (m_pother == Data::null_pvertex()
|
||||
&& m_ivertex != Data::null_ivertex()); }
|
||||
bool is_pvertices_to_ivertex() const { return (m_pother != Data::null_pvertex()
|
||||
&& m_ivertex != Data::null_ivertex()); }
|
||||
|
||||
friend std::ostream& operator<< (std::ostream& os, const Event& ev)
|
||||
{
|
||||
os << "Event at t=" << ev.m_time << " between vertex ("
|
||||
<< ev.m_pvertex.first << ":" << ev.m_pvertex.second
|
||||
<< ") and intersection edge " << ev.m_iedge;
|
||||
if (ev.is_pvertex_to_pvertex())
|
||||
os << "Event at t=" << ev.m_time << " between PVertex("
|
||||
<< ev.m_pvertex.first << ":" << ev.m_pvertex.second
|
||||
<< ") and PVertex(" << ev.m_pother.first << ":" << ev.m_pother.second << ")";
|
||||
else if (ev.is_pvertex_to_iedge())
|
||||
os << "Event at t=" << ev.m_time << " between PVertex("
|
||||
<< ev.m_pvertex.first << ":" << ev.m_pvertex.second
|
||||
<< ") and IEdge" << ev.m_iedge;
|
||||
else if (ev.is_pvertex_to_ivertex())
|
||||
os << "Event at t=" << ev.m_time << " between PVertex("
|
||||
<< ev.m_pvertex.first << ":" << ev.m_pvertex.second
|
||||
<< ") and IVertex(" << ev.m_ivertex << ")";
|
||||
else if (ev.is_pvertices_to_ivertex())
|
||||
os << "Event at t=" << ev.m_time << " between PVertex("
|
||||
<< ev.m_pvertex.first << ":" << ev.m_pvertex.second
|
||||
<< "), PVertex(" << ev.m_pother.first << ":" << ev.m_pother.second
|
||||
<< " and IVertex(" << ev.m_ivertex << ")";
|
||||
else
|
||||
os << "Invalid event at t=" << ev.m_time;
|
||||
return os;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -59,15 +59,19 @@ private:
|
|||
boost::multi_index::ordered_non_unique
|
||||
<boost::multi_index::member<Event, FT, &Event::m_time> >,
|
||||
boost::multi_index::ordered_non_unique
|
||||
<boost::multi_index::member<Event, PVertex, &Event::m_pvertex> >
|
||||
<boost::multi_index::member<Event, PVertex, &Event::m_pvertex> >,
|
||||
boost::multi_index::ordered_non_unique
|
||||
<boost::multi_index::member<Event, PVertex, &Event::m_pother> >
|
||||
>
|
||||
> Queue;
|
||||
|
||||
typedef typename Queue::iterator Queue_iterator;
|
||||
typedef typename Queue::template nth_index<0>::type Queue_by_time;
|
||||
typedef typename Queue_by_time::iterator Queue_by_time_iterator;
|
||||
typedef typename Queue::template nth_index<1>::type Queue_by_event_idx;
|
||||
typedef typename Queue_by_event_idx::iterator Queue_by_event_idx_iterator;
|
||||
typedef typename Queue::template nth_index<1>::type Queue_by_pvertex_idx;
|
||||
typedef typename Queue_by_pvertex_idx::iterator Queue_by_pvertex_idx_iterator;
|
||||
typedef typename Queue::template nth_index<2>::type Queue_by_pother_idx;
|
||||
typedef typename Queue_by_pother_idx::iterator Queue_by_pother_idx_iterator;
|
||||
|
||||
Queue m_queue;
|
||||
|
||||
|
|
@ -80,13 +84,16 @@ public:
|
|||
|
||||
void push (const Event& ev)
|
||||
{
|
||||
CGAL_KSR_CERR(4) << "**** Pushing " << ev << std::endl;
|
||||
m_queue.insert (ev);
|
||||
}
|
||||
|
||||
const Queue_by_time& queue_by_time() const { return m_queue.template get<0>(); }
|
||||
const Queue_by_event_idx& queue_by_event_idx() const { return m_queue.template get<1>(); }
|
||||
const Queue_by_pvertex_idx& queue_by_pvertex_idx() const { return m_queue.template get<1>(); }
|
||||
const Queue_by_pother_idx& queue_by_pother_idx() const { return m_queue.template get<2>(); }
|
||||
Queue_by_time& queue_by_time() { return m_queue.template get<0>(); }
|
||||
Queue_by_event_idx& queue_by_event_idx() { return m_queue.template get<1>(); }
|
||||
Queue_by_pvertex_idx& queue_by_pvertex_idx() { return m_queue.template get<1>(); }
|
||||
Queue_by_pother_idx& queue_by_pother_idx() { return m_queue.template get<2>(); }
|
||||
|
||||
Event pop ()
|
||||
{
|
||||
|
|
@ -102,23 +109,28 @@ public:
|
|||
std::cerr << e << std::endl;
|
||||
}
|
||||
|
||||
void erase_vertex_events (KSR::size_t support_plane_idx, PVertex pvertex)
|
||||
void erase_vertex_events (PVertex pvertex)
|
||||
{
|
||||
std::pair<Queue_by_event_idx_iterator, Queue_by_event_idx_iterator>
|
||||
range = queue_by_event_idx().equal_range(pvertex);
|
||||
queue_by_event_idx().erase (range.first, range.second);
|
||||
{
|
||||
std::pair<Queue_by_pvertex_idx_iterator, Queue_by_pvertex_idx_iterator>
|
||||
range = queue_by_pvertex_idx().equal_range(pvertex);
|
||||
|
||||
for (const auto& ev : CGAL::make_range(range))
|
||||
CGAL_KSR_CERR(4) << "**** Erasing " << ev << std::endl;
|
||||
|
||||
queue_by_pvertex_idx().erase (range.first, range.second);
|
||||
}
|
||||
{
|
||||
std::pair<Queue_by_pother_idx_iterator, Queue_by_pother_idx_iterator>
|
||||
range = queue_by_pother_idx().equal_range(pvertex);
|
||||
|
||||
for (const auto& ev : CGAL::make_range(range))
|
||||
CGAL_KSR_CERR(4) << "**** Erasing " << ev << std::endl;
|
||||
|
||||
queue_by_pother_idx().erase (range.first, range.second);
|
||||
}
|
||||
}
|
||||
|
||||
void erase_vertex_events (KSR::size_t support_plane_idx, PVertex pvertex,
|
||||
KSR::vector<Event>& events)
|
||||
{
|
||||
std::pair<Queue_by_event_idx_iterator, Queue_by_event_idx_iterator>
|
||||
range = queue_by_event_idx().equal_range(pvertex);
|
||||
|
||||
std::copy (range.first, range.second, std::back_inserter (events));
|
||||
queue_by_event_idx().erase (range.first, range.second);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -51,14 +51,19 @@ public:
|
|||
struct Vertex_property
|
||||
{
|
||||
Point_3 point;
|
||||
bool active;
|
||||
|
||||
Vertex_property () { }
|
||||
Vertex_property (const Point_3& point) : point (point) { }
|
||||
Vertex_property () : active(true) { }
|
||||
Vertex_property (const Point_3& point) : point (point), active(true) { }
|
||||
};
|
||||
|
||||
struct Edge_property
|
||||
{
|
||||
KSR::size_t line;
|
||||
KSR::Idx_set planes;
|
||||
bool active;
|
||||
|
||||
Edge_property() : line (KSR::no_element()), active(true) { }
|
||||
};
|
||||
|
||||
typedef boost::adjacency_list <boost::setS,
|
||||
|
|
@ -79,12 +84,13 @@ public:
|
|||
private:
|
||||
|
||||
Graph m_graph;
|
||||
KSR::size_t m_nb_lines;
|
||||
std::map<Point_3, Vertex_descriptor> m_map_points;
|
||||
std::map<KSR::Idx_vector, Vertex_descriptor> m_map_vertices;
|
||||
|
||||
public:
|
||||
|
||||
Intersection_graph() { }
|
||||
Intersection_graph() : m_nb_lines(0) { }
|
||||
|
||||
static Vertex_descriptor null_ivertex()
|
||||
{ return boost::graph_traits<Graph>::null_vertex(); }
|
||||
|
|
@ -121,6 +127,9 @@ public:
|
|||
return std::make_pair (iter->second, inserted);
|
||||
}
|
||||
|
||||
KSR::size_t add_line() { return (m_nb_lines ++); }
|
||||
KSR::size_t nb_lines() const { return m_nb_lines; }
|
||||
|
||||
std::pair<Edge_descriptor, bool> add_edge (const Vertex_descriptor& source, const Vertex_descriptor& target,
|
||||
KSR::size_t support_plane_idx)
|
||||
{
|
||||
|
|
@ -144,6 +153,13 @@ public:
|
|||
return add_edge (add_vertex (source).first, add_vertex (target).first);
|
||||
}
|
||||
|
||||
void set_line (const Edge_descriptor& edge, KSR::size_t line_idx)
|
||||
{
|
||||
m_graph[edge].line = line_idx;
|
||||
}
|
||||
|
||||
KSR::size_t line (const Edge_descriptor& edge) const { return m_graph[edge].line; }
|
||||
|
||||
std::pair<Edge_descriptor, Edge_descriptor>
|
||||
split_edge (const Edge_descriptor& edge, const Vertex_descriptor& vertex)
|
||||
{
|
||||
|
|
@ -210,6 +226,11 @@ public:
|
|||
return Line_3 (m_graph[source (edge, m_graph)].point,
|
||||
m_graph[target (edge, m_graph)].point);
|
||||
}
|
||||
|
||||
bool is_active (const Vertex_descriptor& vertex) const { return m_graph[vertex].active; }
|
||||
bool& is_active (const Vertex_descriptor& vertex) { return m_graph[vertex].active; }
|
||||
bool is_active (const Edge_descriptor& edge) const { return m_graph[edge].active; }
|
||||
bool& is_active (const Edge_descriptor& edge) { return m_graph[edge].active; }
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ public:
|
|||
|
||||
Polygon_splitter (Data& data) : m_data (data) { }
|
||||
|
||||
void split_support_plane (KSR::size_t support_plane_idx)
|
||||
void split_support_plane (KSR::size_t support_plane_idx, unsigned int k)
|
||||
{
|
||||
// First, insert polygons
|
||||
for (PVertex pvertex : m_data.pvertices(support_plane_idx))
|
||||
|
|
@ -254,9 +254,11 @@ public:
|
|||
}
|
||||
while (current != edge);
|
||||
|
||||
PFace pface = m_data.add_pface (support_plane_idx, new_vertices);
|
||||
PFace pface = m_data.add_pface (new_vertices);
|
||||
CGAL_assertion (pface != PFace());
|
||||
|
||||
m_data.k(pface) = k;
|
||||
|
||||
std::size_t original_idx = 0;
|
||||
if (original_faces.size() != 1)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -65,8 +65,10 @@ public:
|
|||
typedef typename Mesh::template Property_map<Vertex_index, Vector_2> V_vector_map;
|
||||
typedef typename Mesh::template Property_map<Vertex_index, IVertex> V_ivertex_map;
|
||||
typedef typename Mesh::template Property_map<Vertex_index, IEdge> V_iedge_map;
|
||||
typedef typename Mesh::template Property_map<Vertex_index, bool> V_bool_map;
|
||||
typedef typename Mesh::template Property_map<Edge_index, IEdge> E_iedge_map;
|
||||
typedef typename Mesh::template Property_map<Face_index, KSR::size_t> F_index_map;
|
||||
typedef typename Mesh::template Property_map<Face_index, unsigned int> F_uint_map;
|
||||
|
||||
|
||||
private:
|
||||
|
|
@ -78,8 +80,10 @@ private:
|
|||
V_vector_map direction;
|
||||
V_ivertex_map v_ivertex_map;
|
||||
V_iedge_map v_iedge_map;
|
||||
V_bool_map v_active_map;
|
||||
E_iedge_map e_iedge_map;
|
||||
F_index_map input;
|
||||
F_index_map input_map;
|
||||
F_uint_map k_map;
|
||||
std::set<IEdge> iedges;
|
||||
};
|
||||
|
||||
|
|
@ -114,12 +118,14 @@ public:
|
|||
("v:ivertex", Intersection_graph::null_ivertex()).first;
|
||||
m_data->v_iedge_map = m_data->mesh.template add_property_map<Vertex_index, IEdge>
|
||||
("v:iedge", Intersection_graph::null_iedge()).first;
|
||||
m_data->v_active_map = m_data->mesh.template add_property_map<Vertex_index, bool>
|
||||
("v:active", true).first;
|
||||
m_data->e_iedge_map = m_data->mesh.template add_property_map<Edge_index, IEdge>
|
||||
("e:iedge", Intersection_graph::null_iedge()).first;
|
||||
|
||||
bool okay;
|
||||
std::tie (m_data->input, okay) = m_data->mesh.template add_property_map<Face_index, KSR::size_t>("f:input", KSR::no_element());
|
||||
CGAL_assertion(okay);
|
||||
m_data->input_map = m_data->mesh.template add_property_map<Face_index, KSR::size_t>
|
||||
("f:input", KSR::no_element()).first;
|
||||
m_data->k_map = m_data->mesh.template add_property_map<Face_index, unsigned int>
|
||||
("f:k", 0).first;
|
||||
}
|
||||
|
||||
const Plane_3& plane() const { return m_data->plane; }
|
||||
|
|
@ -127,6 +133,39 @@ public:
|
|||
const Mesh& mesh() const { return m_data->mesh; }
|
||||
Mesh& mesh() { return m_data->mesh; }
|
||||
|
||||
void set_point (const Vertex_index& vertex_index, const Point_2& point)
|
||||
{
|
||||
m_data->mesh.point(vertex_index) = point;
|
||||
}
|
||||
|
||||
Vertex_index prev (const Vertex_index& vertex_index) const
|
||||
{
|
||||
return m_data->mesh.source(m_data->mesh.halfedge(vertex_index));
|
||||
}
|
||||
Vertex_index next (const Vertex_index& vertex_index) const
|
||||
{
|
||||
return m_data->mesh.target(m_data->mesh.next(m_data->mesh.halfedge(vertex_index)));
|
||||
}
|
||||
|
||||
Face_index face (const Vertex_index& vertex_index) const
|
||||
{
|
||||
Face_index out = m_data->mesh.face (m_data->mesh.halfedge(vertex_index));
|
||||
if (out == Face_index())
|
||||
out = m_data->mesh.face (m_data->mesh.opposite(m_data->mesh.halfedge(vertex_index)));
|
||||
CGAL_assertion (out != Face_index());
|
||||
return out;
|
||||
}
|
||||
|
||||
std::pair<Face_index, Face_index> faces (const Vertex_index& vertex_index) const
|
||||
{
|
||||
for (Halfedge_index hi : halfedges_around_target (halfedge(vertex_index, m_data->mesh), m_data->mesh))
|
||||
if (has_iedge (m_data->mesh.edge(hi)))
|
||||
return std::make_pair (m_data->mesh.face (hi),
|
||||
m_data->mesh.face (m_data->mesh.opposite(hi)));
|
||||
CGAL_assertion_msg (false, "No constrained edge found");
|
||||
return std::make_pair (Face_index(), Face_index());
|
||||
}
|
||||
|
||||
Point_2 point_2 (const Vertex_index& vertex_index, FT time) const
|
||||
{ return m_data->mesh.point(vertex_index) + time * m_data->direction[vertex_index]; }
|
||||
|
||||
|
|
@ -146,7 +185,7 @@ public:
|
|||
}
|
||||
|
||||
void set_iedge (const Vertex_index& a, const Vertex_index& b,
|
||||
const IEdge& iedge) const
|
||||
const IEdge& iedge) const
|
||||
{
|
||||
Halfedge_index hi = m_data->mesh.halfedge (a, b);
|
||||
CGAL_assertion (hi != Halfedge_index());
|
||||
|
|
@ -161,11 +200,17 @@ public:
|
|||
}
|
||||
|
||||
void set_iedge (const Vertex_index& vertex,
|
||||
const IEdge& iedge) const
|
||||
const IEdge& iedge) const
|
||||
{
|
||||
m_data->v_iedge_map[vertex] = iedge;
|
||||
}
|
||||
|
||||
void set_iedge (const Edge_index& edge,
|
||||
const IEdge& iedge) const
|
||||
{
|
||||
m_data->e_iedge_map[edge] = iedge;
|
||||
}
|
||||
|
||||
const IEdge& iedge (const Edge_index& edge_index) const
|
||||
{
|
||||
return m_data->e_iedge_map[edge_index];
|
||||
|
|
@ -176,6 +221,11 @@ public:
|
|||
return m_data->v_iedge_map[vertex_index];
|
||||
}
|
||||
|
||||
const IVertex& ivertex (const Vertex_index& vertex_index) const
|
||||
{
|
||||
return m_data->v_ivertex_map[vertex_index];
|
||||
}
|
||||
|
||||
bool has_iedge (const Edge_index& edge_index) const
|
||||
{
|
||||
return (m_data->e_iedge_map[edge_index] != Intersection_graph::null_iedge());
|
||||
|
|
@ -184,15 +234,25 @@ public:
|
|||
{
|
||||
return (m_data->v_iedge_map[vertex_index] != Intersection_graph::null_iedge());
|
||||
}
|
||||
bool has_ivertex (const Vertex_index& vertex_index) const
|
||||
{
|
||||
return (m_data->v_ivertex_map[vertex_index] != Intersection_graph::null_ivertex());
|
||||
}
|
||||
|
||||
const Vector_2& direction (const Vertex_index& vertex_index) const { return m_data->direction[vertex_index]; }
|
||||
Vector_2& direction (const Vertex_index& vertex_index) { return m_data->direction[vertex_index]; }
|
||||
FT speed (const Vertex_index& vertex_index) const
|
||||
{ return CGAL::approximate_sqrt (m_data->direction[vertex_index].squared_length()); }
|
||||
|
||||
const KSR::size_t& input (const Face_index& face_index) const { return m_data->input[face_index]; }
|
||||
KSR::size_t& input (const Face_index& face_index) { return m_data->input[face_index]; }
|
||||
const KSR::size_t& input (const Face_index& face_index) const { return m_data->input_map[face_index]; }
|
||||
KSR::size_t& input (const Face_index& face_index) { return m_data->input_map[face_index]; }
|
||||
|
||||
const unsigned int& k (const Face_index& face_index) const { return m_data->k_map[face_index]; }
|
||||
unsigned int& k (const Face_index& face_index) { return m_data->k_map[face_index]; }
|
||||
|
||||
bool is_active (const Vertex_index& vertex_index) const { return m_data->v_active_map[vertex_index]; }
|
||||
void set_active (const Vertex_index& vertex_index, bool value) { m_data->v_active_map[vertex_index] = value; }
|
||||
|
||||
bool is_frozen (const Vertex_index& vertex_index) const
|
||||
{
|
||||
return (m_data->direction[vertex_index] == CGAL::NULL_VECTOR);
|
||||
|
|
@ -239,7 +299,7 @@ public:
|
|||
}
|
||||
|
||||
Face_index fi = m_data->mesh.add_face (vertices);
|
||||
m_data->input[fi] = KSR::no_element();
|
||||
m_data->input_map[fi] = KSR::no_element();
|
||||
|
||||
return vertices;
|
||||
}
|
||||
|
|
@ -257,17 +317,14 @@ public:
|
|||
}
|
||||
|
||||
Face_index fi = m_data->mesh.add_face (vertices);
|
||||
m_data->input[fi] = input_idx;
|
||||
m_data->input_map[fi] = input_idx;
|
||||
|
||||
return KSR::size_t(fi);
|
||||
}
|
||||
|
||||
Edge_index edge (const Vertex_index& v0, const Vertex_index& v1)
|
||||
{
|
||||
for (Halfedge_index hi : halfedges_around_target (halfedge(v0, m_data->mesh), m_data->mesh))
|
||||
if (target(hi, m_data->mesh) == v1)
|
||||
return m_data->mesh.edge(hi);
|
||||
return Edge_index();
|
||||
return m_data->mesh.edge (m_data->mesh.halfedge (v0, v1));
|
||||
}
|
||||
|
||||
Edge_index add_edge (const Vertex_index& v0, const Vertex_index& v1,
|
||||
|
|
@ -283,9 +340,32 @@ public:
|
|||
return m_data->mesh.add_vertex(point);
|
||||
}
|
||||
|
||||
Vertex_index split_edge (const Edge_index& ei)
|
||||
Vertex_index duplicate_vertex (const Vertex_index& v)
|
||||
{
|
||||
return m_data->mesh.target (CGAL::Euler::split_edge (m_data->mesh.halfedge (ei), m_data->mesh));
|
||||
Vertex_index vi = m_data->mesh.add_vertex (m_data->mesh.point(v));
|
||||
m_data->direction[vi] = m_data->direction[v];
|
||||
m_data->v_ivertex_map[vi] = m_data->v_ivertex_map[v];
|
||||
m_data->v_iedge_map[vi] = m_data->v_iedge_map[v];
|
||||
return vi;
|
||||
}
|
||||
|
||||
void remove_vertex (const Vertex_index& v)
|
||||
{
|
||||
m_data->mesh.remove_vertex(v);
|
||||
}
|
||||
|
||||
Edge_index split_vertex (const Vertex_index& ei)
|
||||
{
|
||||
return m_data->mesh.edge
|
||||
(CGAL::Euler::split_vertex (m_data->mesh.halfedge (ei),
|
||||
m_data->mesh.opposite(m_data->mesh.next(m_data->mesh.halfedge (ei))),
|
||||
m_data->mesh));
|
||||
}
|
||||
|
||||
Vertex_index split_edge (const Vertex_index& v0, const Vertex_index& v1)
|
||||
{
|
||||
return m_data->mesh.target
|
||||
(CGAL::Euler::split_edge (m_data->mesh.halfedge (v0, v1), m_data->mesh));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -115,8 +115,10 @@ public:
|
|||
KSR_3::dump (m_data, "init");
|
||||
|
||||
CGAL_assertion(check_integrity(true));
|
||||
make_polygons_intersection_free();
|
||||
make_polygons_intersection_free(k);
|
||||
CGAL_assertion(check_integrity(true));
|
||||
|
||||
KSR_3::dump_segmented_edges (m_data, "init");
|
||||
|
||||
KSR_3::dump (m_data, "intersected");
|
||||
|
||||
|
|
@ -129,7 +131,7 @@ public:
|
|||
m_min_time = m_max_time;
|
||||
m_max_time += time_step;
|
||||
|
||||
CGAL_assertion(check_integrity(true));
|
||||
// CGAL_assertion(check_integrity(true));
|
||||
++ iter;
|
||||
}
|
||||
exit(0);
|
||||
|
|
@ -151,7 +153,7 @@ public:
|
|||
if (!m_data.mesh_is_valid(i))
|
||||
{
|
||||
if (verbose)
|
||||
std::cerr << "ERROR: Mesh " << i << "is invalid" << std::endl;
|
||||
std::cerr << "ERROR: Mesh " << i << " is invalid" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -161,8 +163,8 @@ public:
|
|||
{
|
||||
if (verbose)
|
||||
std::cerr << "ERROR: Support_plane[" << i
|
||||
<< "] is intersected by IEdge[" << iedge
|
||||
<< "] which claims it does not intersect it" << std::endl;
|
||||
<< "] is intersected by " << m_data.str(iedge)
|
||||
<< " which claims it does not intersect it" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -175,8 +177,8 @@ public:
|
|||
== m_data.iedges(support_plane_idx).end())
|
||||
{
|
||||
if (verbose)
|
||||
std::cerr << "ERROR: IEdge[" << iedge
|
||||
<< "] intersects Support_plane[" << support_plane_idx
|
||||
std::cerr << "ERROR: " << m_data.str(iedge)
|
||||
<< " intersects Support_plane[" << support_plane_idx
|
||||
<< "] which claims it's not intersected by it" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
|
@ -250,7 +252,7 @@ private:
|
|||
CGAL_assertion (m_data.iedges().size() == 12);
|
||||
}
|
||||
|
||||
void make_polygons_intersection_free()
|
||||
void make_polygons_intersection_free (unsigned int k)
|
||||
{
|
||||
// First, generate all transverse intersection lines
|
||||
typedef std::map<KSR::Idx_set, std::pair<IVertex, IVertex> > Map;
|
||||
|
|
@ -324,7 +326,7 @@ private:
|
|||
for (KSR::size_t i = 0; i < m_data.number_of_support_planes(); ++ i)
|
||||
{
|
||||
KSR_3::Polygon_splitter<GeomTraits> splitter (m_data);
|
||||
splitter.split_support_plane (i);
|
||||
splitter.split_support_plane (i, k);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -338,68 +340,14 @@ private:
|
|||
|
||||
for (KSR::size_t i = 0; i < m_data.number_of_support_planes(); ++ i)
|
||||
{
|
||||
// To get random access, copy in vector (suboptimal to do this
|
||||
// all the time, maybe this should be done once and for all and
|
||||
// replace the set)
|
||||
KSR::vector<IEdge> iedges;
|
||||
iedges.reserve (m_data.iedges(i).size());
|
||||
std::copy (m_data.iedges(i).begin(),
|
||||
m_data.iedges(i).end(),
|
||||
std::back_inserter(iedges));
|
||||
|
||||
// Precompute segments and bboxes
|
||||
KSR::vector<Segment_2> segments_2;
|
||||
segments_2.reserve (iedges.size());
|
||||
KSR::vector<CGAL::Bbox_2> segment_bboxes;
|
||||
segment_bboxes.reserve (iedges.size());
|
||||
for (const IEdge& iedge : iedges)
|
||||
{
|
||||
segments_2.push_back (m_data.segment_2 (i, iedge));
|
||||
segment_bboxes.push_back (segments_2.back().bbox());
|
||||
}
|
||||
init_search_structures (i, iedges, segments_2, segment_bboxes);
|
||||
|
||||
for (const PVertex& pvertex : m_data.pvertices(i))
|
||||
{
|
||||
if (m_data.is_frozen(pvertex))
|
||||
continue;
|
||||
|
||||
still_running = true;
|
||||
|
||||
if (m_data.has_iedge(pvertex)) // Constrained vertex
|
||||
{
|
||||
// Test left and right vertices on mesh face
|
||||
|
||||
// Test end-vertices of intersection edge
|
||||
}
|
||||
else // Unconstrained vertex
|
||||
{
|
||||
// Test all intersection edges
|
||||
|
||||
Segment_2 si (m_data.point_2 (pvertex, m_min_time),
|
||||
m_data.point_2 (pvertex, m_max_time));
|
||||
CGAL::Bbox_2 si_bbox = si.bbox();
|
||||
|
||||
for (std::size_t j = 0; j < iedges.size(); ++ j)
|
||||
{
|
||||
const IEdge& iedge = iedges[j];
|
||||
|
||||
if (m_data.iedge(pvertex) == iedge)
|
||||
continue;
|
||||
|
||||
if (!CGAL::do_overlap (si_bbox, segment_bboxes[j]))
|
||||
continue;
|
||||
|
||||
Point_2 point;
|
||||
if (!KSR::intersection_2 (si, segments_2[j], point))
|
||||
continue;
|
||||
|
||||
FT dist = CGAL::approximate_sqrt (CGAL::squared_distance (m_data.point_2 (pvertex, m_min_time), point));
|
||||
FT time = dist / m_data.speed(pvertex);
|
||||
|
||||
m_queue.push (Event (pvertex, iedge, m_min_time + time));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (compute_events_of_vertex (pvertex, iedges, segments_2, segment_bboxes))
|
||||
still_running = true;
|
||||
}
|
||||
|
||||
m_data.update_positions(m_min_time);
|
||||
|
|
@ -407,6 +355,118 @@ private:
|
|||
return still_running;
|
||||
}
|
||||
|
||||
void init_search_structures (KSR::size_t i,
|
||||
KSR::vector<IEdge>& iedges,
|
||||
KSR::vector<Segment_2>& segments_2,
|
||||
KSR::vector<CGAL::Bbox_2>& segment_bboxes)
|
||||
{
|
||||
// To get random access, copy in vector (suboptimal to do this
|
||||
// all the time, maybe this should be done once and for all and
|
||||
// replace the set)
|
||||
iedges.reserve (m_data.iedges(i).size());
|
||||
std::copy (m_data.iedges(i).begin(),
|
||||
m_data.iedges(i).end(),
|
||||
std::back_inserter(iedges));
|
||||
|
||||
// Precompute segments and bboxes
|
||||
segments_2.reserve (iedges.size());
|
||||
segment_bboxes.reserve (iedges.size());
|
||||
for (const IEdge& iedge : iedges)
|
||||
{
|
||||
segments_2.push_back (m_data.segment_2 (i, iedge));
|
||||
segment_bboxes.push_back (segments_2.back().bbox());
|
||||
}
|
||||
}
|
||||
|
||||
bool compute_events_of_vertex (const PVertex& pvertex,
|
||||
const KSR::vector<IEdge>& iedges,
|
||||
const KSR::vector<Segment_2>& segments_2,
|
||||
const KSR::vector<CGAL::Bbox_2>& segment_bboxes)
|
||||
{
|
||||
if (m_data.is_frozen(pvertex))
|
||||
return false;
|
||||
|
||||
Segment_2 sv (m_data.point_2 (pvertex, m_min_time),
|
||||
m_data.point_2 (pvertex, m_max_time));
|
||||
CGAL::Bbox_2 sv_bbox = sv.bbox();
|
||||
|
||||
if (m_data.has_iedge(pvertex)) // Constrained vertex
|
||||
{
|
||||
// Test left and right vertices on mesh face
|
||||
PVertex prev;
|
||||
PVertex next;
|
||||
std::tie (prev, next) = m_data.prev_and_next (pvertex);
|
||||
|
||||
for (const PVertex& pother : { prev, next })
|
||||
{
|
||||
if (pother == Data::null_pvertex()
|
||||
|| !m_data.is_active(pother)
|
||||
|| m_data.has_iedge (pother))
|
||||
continue;
|
||||
|
||||
Segment_2 so (m_data.point_2 (pother, m_min_time),
|
||||
m_data.point_2 (pother, m_max_time));
|
||||
CGAL::Bbox_2 so_bbox = so.bbox();
|
||||
|
||||
if (!do_overlap (sv_bbox, so_bbox))
|
||||
continue;
|
||||
|
||||
Point_2 point;
|
||||
if (!KSR::intersection_2 (sv, so, point))
|
||||
continue;
|
||||
|
||||
FT dist = CGAL::approximate_sqrt (CGAL::squared_distance (sv.source(), point));
|
||||
FT time = dist / m_data.speed(pvertex);
|
||||
|
||||
m_queue.push (Event (pvertex, pother, m_min_time + time));
|
||||
}
|
||||
|
||||
// Test end-vertices of intersection edge
|
||||
IEdge iedge = m_data.iedge(pvertex);
|
||||
for (const IVertex& ivertex : { m_data.source(iedge), m_data.target(iedge) })
|
||||
{
|
||||
if (!m_data.is_active(ivertex))
|
||||
continue;
|
||||
Point_2 pi = m_data.to_2d (pvertex.first, ivertex);
|
||||
if (sv.to_vector() * Vector_2 (sv.source(), pi) < 0)
|
||||
continue;
|
||||
|
||||
FT dist = CGAL::approximate_sqrt(CGAL::squared_distance (sv.source(), pi));
|
||||
FT time = dist / m_data.speed(pvertex);
|
||||
|
||||
if (time < m_max_time - m_min_time)
|
||||
m_queue.push (Event (pvertex, ivertex, m_min_time + time));
|
||||
}
|
||||
}
|
||||
else // Unconstrained vertex
|
||||
{
|
||||
// Test all intersection edges
|
||||
for (std::size_t j = 0; j < iedges.size(); ++ j)
|
||||
{
|
||||
const IEdge& iedge = iedges[j];
|
||||
|
||||
if (m_data.iedge(pvertex) == iedge)
|
||||
continue;
|
||||
if (!m_data.is_active(iedge))
|
||||
continue;
|
||||
|
||||
if (!CGAL::do_overlap (sv_bbox, segment_bboxes[j]))
|
||||
continue;
|
||||
|
||||
Point_2 point;
|
||||
if (!KSR::intersection_2 (sv, segments_2[j], point))
|
||||
continue;
|
||||
|
||||
FT dist = CGAL::approximate_sqrt (CGAL::squared_distance (m_data.point_2 (pvertex, m_min_time), point));
|
||||
FT time = dist / m_data.speed(pvertex);
|
||||
|
||||
m_queue.push (Event (pvertex, iedge, m_min_time + time));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void run()
|
||||
{
|
||||
CGAL_KSR_CERR(1) << "Unstacking queue" << std::endl;
|
||||
|
|
@ -421,10 +481,6 @@ private:
|
|||
|
||||
FT current_time = ev.time();
|
||||
|
||||
m_data.update_positions (current_time);
|
||||
|
||||
CGAL_KSR_CERR(2) << "* Applying " << iter << ": " << ev << std::endl;
|
||||
|
||||
if (iter < 10)
|
||||
{
|
||||
dump (m_data, "iter_0" + std::to_string(iter));
|
||||
|
|
@ -436,10 +492,20 @@ private:
|
|||
dump_event (m_data, ev, "iter_" + std::to_string(iter));
|
||||
}
|
||||
|
||||
m_data.update_positions (current_time);
|
||||
|
||||
CGAL_KSR_CERR(2) << "* Applying " << iter << ": " << ev << std::endl;
|
||||
|
||||
m_data.update_positions (current_time + 0.01);
|
||||
dump (m_data, "shifted_" + std::to_string(iter));
|
||||
m_data.update_positions (current_time);
|
||||
|
||||
++ iter;
|
||||
|
||||
if (iter == 5)
|
||||
if (iter == 27)
|
||||
{
|
||||
exit(0);
|
||||
}
|
||||
|
||||
apply(ev);
|
||||
|
||||
|
|
@ -450,95 +516,110 @@ private:
|
|||
void apply (const Event& ev)
|
||||
{
|
||||
PVertex pvertex = ev.pvertex();
|
||||
IEdge iedge = ev.iedge();
|
||||
|
||||
}
|
||||
|
||||
#if 0
|
||||
void transfer_events (KSR::size_t old_vertex, KSR::size_t new_vertex)
|
||||
{
|
||||
CGAL_KSR_CERR(3) << "** Transfering events of vertex " << old_vertex << " to " << new_vertex << std::endl;
|
||||
|
||||
KSR::vector<Event> events;
|
||||
m_queue.erase_vertex_events (old_vertex, events);
|
||||
|
||||
for (Event& ev : events)
|
||||
if (ev.is_pvertex_to_pvertex())
|
||||
{
|
||||
ev.vertex_idx() = new_vertex;
|
||||
CGAL_KSR_CERR(4) << "**** - Pushing " << ev << std::endl;
|
||||
m_queue.push (ev);
|
||||
PVertex pother = ev.pother();
|
||||
|
||||
remove_events (pvertex);
|
||||
remove_events (pother);
|
||||
|
||||
CGAL_assertion (m_data.has_iedge(pvertex));
|
||||
|
||||
if (m_data.has_iedge(pother)) // Two constrained vertices meet
|
||||
{
|
||||
CGAL_assertion_msg (false, "TODO: two constrained");
|
||||
}
|
||||
else // One constrained vertex meets a free vertex
|
||||
{
|
||||
m_data.transfer_vertex (pvertex, pother);
|
||||
compute_events_of_vertices (std::array<PVertex,2>{pvertex, pother});
|
||||
}
|
||||
}
|
||||
else if (ev.is_pvertex_to_iedge())
|
||||
{
|
||||
remove_events (pvertex);
|
||||
|
||||
IEdge iedge = ev.iedge();
|
||||
|
||||
PFace pface = m_data.pface_of_pvertex (pvertex);
|
||||
bool collision, bbox_reached;
|
||||
std::tie (collision, bbox_reached)
|
||||
= m_data.collision_occured (pvertex, iedge);
|
||||
if (collision && m_data.k(pface) > 1)
|
||||
m_data.k(pface) --;
|
||||
if (bbox_reached)
|
||||
m_data.k(pface) = 1;
|
||||
|
||||
if (m_data.k(pface) == 1) // Polygon stops
|
||||
{
|
||||
PVertex pvnew = m_data.crop_polygon (pvertex, iedge);
|
||||
compute_events_of_vertices (std::array<PVertex,2>{pvertex, pvnew});
|
||||
}
|
||||
else // Polygon continues beyond the edge
|
||||
{
|
||||
std::array<PVertex, 3> pvnew = m_data.propagate_polygon (pvertex, iedge);
|
||||
compute_events_of_vertices (std::array<PVertex,3>{pvnew[0], pvnew[1], pvnew[2]});
|
||||
}
|
||||
}
|
||||
else if (ev.is_pvertex_to_ivertex())
|
||||
{
|
||||
// first, let's gather all vertices that will get merged
|
||||
std::vector<PVertex> pvertices
|
||||
= m_data.pvertices_around_ivertex (ev.pvertex(), ev.ivertex());
|
||||
|
||||
CGAL_assertion_msg (pvertices.size() > 1, "Isolated PVertex reaching an IVertex");
|
||||
|
||||
std::cerr << "Found " << pvertices.size() << " pvertices ready to be merged" << std::endl;
|
||||
|
||||
// Remove associated events
|
||||
for (const PVertex pvertex : pvertices)
|
||||
remove_events (pvertex);
|
||||
|
||||
// Merge them and get the newly created vertices
|
||||
std::vector<PVertex> new_pvertices
|
||||
= m_data.merge_pvertices_on_ivertex (pvertices, ev.ivertex());
|
||||
|
||||
// And compute new events
|
||||
compute_events_of_vertices (new_pvertices);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
CGAL_assertion_msg (false, "Event is invalid");
|
||||
}
|
||||
}
|
||||
|
||||
void update_events (KSR::size_t vertex_idx)
|
||||
void remove_events (const PVertex& pvertex)
|
||||
{
|
||||
remove_events (vertex_idx);
|
||||
compute_new_events (vertex_idx);
|
||||
m_queue.erase_vertex_events (pvertex);
|
||||
}
|
||||
|
||||
void remove_events (KSR::size_t vertex_idx)
|
||||
template <typename PVertexRange>
|
||||
void compute_events_of_vertices (const PVertexRange& pvertices)
|
||||
{
|
||||
CGAL_KSR_CERR(3) << "** Removing events of vertex " << vertex_idx << std::endl;
|
||||
m_queue.erase_vertex_events (vertex_idx);
|
||||
}
|
||||
|
||||
void compute_new_events (KSR::size_t vertex_idx)
|
||||
{
|
||||
const Vertex& vertex = m_data.vertex (vertex_idx);
|
||||
if (vertex.is_frozen())
|
||||
return;
|
||||
|
||||
CGAL_KSR_CERR(3) << "** Computing new events of vertex " << vertex_idx << std::endl;
|
||||
|
||||
FT current_time = m_data.current_time();
|
||||
// TODO
|
||||
m_min_time = m_data.current_time();
|
||||
|
||||
m_data.update_positions(m_max_time);
|
||||
|
||||
KSR::size_t support_plane_idx = m_data.polygon_of_vertex(vertex_idx).support_plane_idx();
|
||||
const Support_plane& support_plane = m_data.support_plane(support_plane_idx);
|
||||
|
||||
// Precompute segments and bboxes
|
||||
KSR::vector<IEdge> iedges;
|
||||
KSR::vector<Segment_2> segments_2;
|
||||
segments_2.reserve (support_plane.intersection_lines_idx().size());
|
||||
KSR::vector<CGAL::Bbox_2> segment_bboxes;
|
||||
segment_bboxes.reserve (support_plane.intersection_lines_idx().size());
|
||||
for (KSR::size_t intersection_line_idx : support_plane.intersection_lines_idx())
|
||||
{
|
||||
segments_2.push_back (m_data.segment_of_intersection_line_on_support_plane (intersection_line_idx, support_plane_idx));
|
||||
segment_bboxes.push_back (segments_2.back().bbox());
|
||||
}
|
||||
init_search_structures (pvertices.front().first, iedges, segments_2, segment_bboxes);
|
||||
|
||||
for (const PVertex& pvertex : pvertices)
|
||||
m_data.deactivate(pvertex);
|
||||
|
||||
Segment_2 si (vertex.point (current_time), vertex.point (m_max_time));
|
||||
CGAL::Bbox_2 si_bbox = si.bbox();
|
||||
|
||||
for (std::size_t j = 0; j < segments_2.size(); ++ j)
|
||||
{
|
||||
KSR::size_t intersection_line_idx = support_plane.intersection_lines_idx()[j];
|
||||
|
||||
if (m_data.intersection_line_idx_of_vertex(vertex_idx) == intersection_line_idx)
|
||||
continue;
|
||||
|
||||
if (!CGAL::do_overlap (si_bbox, segment_bboxes[j]))
|
||||
continue;
|
||||
|
||||
Point_2 point;
|
||||
if (!KSR::intersection_2 (si, segments_2[j], point))
|
||||
continue;
|
||||
|
||||
FT dist = CGAL::approximate_sqrt (CGAL::squared_distance (vertex.point (current_time), point));
|
||||
FT time = dist / vertex.speed();
|
||||
|
||||
m_queue.push (Event (vertex_idx, intersection_line_idx, current_time + time));
|
||||
}
|
||||
|
||||
m_data.update_positions(current_time);
|
||||
for (const PVertex& pvertex : pvertices)
|
||||
compute_events_of_vertex (pvertex, iedges, segments_2, segment_bboxes);
|
||||
|
||||
for (const PVertex& pvertex : pvertices)
|
||||
m_data.activate(pvertex);
|
||||
|
||||
m_data.update_positions(m_min_time);
|
||||
}
|
||||
|
||||
void get_meta_neighbors (KSR::vector<KSR::vector<KSR::size_t> >& neighbors) const
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -473,7 +473,7 @@ private: //-------------------------------------------------- connectivity types
|
|||
/// \sa `Halfedge_connectivity`, `Face_connectivity`
|
||||
struct Vertex_connectivity
|
||||
{
|
||||
/// an incoming halfedge per vertex (it will be a border halfedge for border vertices)
|
||||
/// an incoming halfedge per vlertex (it will be a border halfedge for border vertices)
|
||||
Halfedge_index halfedge_;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue