diff --git a/Kinetic_space_partition/include/CGAL/KSP_2/Data_structure.h b/Kinetic_space_partition/include/CGAL/KSP_2/Data_structure.h deleted file mode 100644 index f6a2c9f78d67..000000000000 --- a/Kinetic_space_partition/include/CGAL/KSP_2/Data_structure.h +++ /dev/null @@ -1,669 +0,0 @@ -// Copyright (c) 2019 GeometryFactory Sarl (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial -// -// -// Author(s) : Simon Giraudot - -#ifndef CGAL_KSP_2_DATA_STRUCTURE_H -#define CGAL_KSP_2_DATA_STRUCTURE_H - -#include - -#include -#include -#include -#include - -#include - -namespace CGAL { -namespace KSP_2 { -namespace internal { - -template -class Data_structure { -public: - - typedef GeomTraits Kernel; - typedef typename Kernel::FT FT; - typedef typename Kernel::Point_2 Point_2; - typedef typename Kernel::Vector_2 Vector_2; - typedef typename Kernel::Ray_2 Ray_2; - typedef typename Kernel::Line_2 Line_2; - typedef typename Kernel::Segment_2 Segment_2; - - typedef Support_line Support_line_DS; - - typedef CGAL::KSP_2::internal::Vertex Vertex; - typedef CGAL::KSP_2::internal::Segment Segment; - typedef CGAL::KSP_2::internal::Meta_vertex Meta_vertex; - - typedef std::vector Support_lines; - typedef std::vector Segments; - typedef std::vector Vertices; - - typedef std::vector Meta_vertices; - -private: - - // Main data structure - Support_lines m_support_lines; - Segments m_segments; - Vertices m_vertices; - - Meta_vertices m_meta_vertices; - - // Helping data structures - std::map m_meta_map; - - FT m_current_time; - -public: - - Data_structure() - : m_current_time(0) - { } - - void print() const - { - for (std::size_t i = 0; i < m_support_lines.size(); ++i) - { - std::cerr << "* Support_line[" << i << "]" << std::endl; - - for (std::size_t segment_idx : m_support_lines[i].segments_idx()) - { - std::cerr << "** Segment[" << segment_idx << "]" << std::endl; - std::cerr << "*** Vertex[" << segment(segment_idx).source_idx() << "]" << std::endl; - std::cerr << "*** Vertex[" << segment(segment_idx).target_idx() << "]" << std::endl; - } - } - } - - const FT& current_time() const { return m_current_time; } - - std::size_t number_of_vertices() const { return m_vertices.size(); } - const Vertex& vertex(std::size_t idx) const { return m_vertices[idx]; } - Vertex& vertex(std::size_t idx) { return m_vertices[idx]; } - - std::size_t number_of_segments() const { return m_segments.size(); } - const Segment& segment(std::size_t idx) const { return m_segments[idx]; } - Segment& segment(std::size_t idx) { return m_segments[idx]; } - - std::size_t number_of_support_lines() const { return m_support_lines.size(); } - const Support_line_DS& support_line(std::size_t idx) const { return m_support_lines[idx]; } - Support_line_DS& support_line(std::size_t idx) { return m_support_lines[idx]; } - - std::size_t number_of_meta_vertices() const { return m_meta_vertices.size(); } - const Meta_vertex& meta_vertex(std::size_t idx) const { return m_meta_vertices[idx]; } - Meta_vertex& meta_vertex(std::size_t idx) { return m_meta_vertices[idx]; } - - std::string segment_str(std::size_t segment_idx) const - { - return "Segment[" + std::to_string(segment_idx) - + " from " + (segment(segment_idx).input_idx() == std::size_t(-1) ? - "bbox" : std::to_string(segment(segment_idx).input_idx())) - + "](v" + std::to_string(segment(segment_idx).source_idx()) - + "->v" + std::to_string(segment(segment_idx).target_idx()) - + ")"; - } - std::string vertex_str(std::size_t vertex_idx) const - { - return "Vertex[" + std::to_string(vertex_idx) + "]"; - } - - // Vertex/idx -> Point_2 - inline Point_2 point_of_vertex(const Vertex& vertex, FT time) const - { - return support_line_of_vertex(vertex).to_2d(vertex.point(time)); - } - inline Point_2 point_of_vertex(std::size_t vertex_idx, FT time) const - { - return point_of_vertex(m_vertices[vertex_idx], time); - } - inline Point_2 point_of_vertex(const Vertex& vertex) const - { - return point_of_vertex(vertex, m_current_time); - } - inline Point_2 point_of_vertex(std::size_t vertex_idx) const - { - return point_of_vertex(vertex_idx, m_current_time); - } - - // Vertex/idx -> Vector_2 - inline Vector_2 direction_of_vertex(const Vertex& vertex) const - { - return Vector_2(support_line_of_vertex(vertex).to_2d(vertex.point(m_current_time)), - support_line_of_vertex(vertex).to_2d(vertex.point(m_current_time) + vertex.direction())); - } - inline Vector_2 direction_of_vertex(std::size_t vertex_idx) const - { - return direction_of_vertex(m_vertices[vertex_idx]); - } - - // Vertex/idx -> Segment - inline const Segment& segment_of_vertex(const Vertex& vertex) const - { - return m_segments[vertex.segment_idx()]; - } - inline Segment& segment_of_vertex(const Vertex& vertex) - { - return m_segments[vertex.segment_idx()]; - } - inline const Segment& segment_of_vertex(std::size_t vertex_idx) const - { - return segment_of_vertex(m_vertices[vertex_idx]); - } - inline Segment& segment_of_vertex(std::size_t vertex_idx) - { - return segment_of_vertex(m_vertices[vertex_idx]); - } - - // Segment/idx -> source Vertex - inline const Vertex& source_of_segment(const Segment& segment) const - { - return m_vertices[segment.source_idx()]; - } - inline Vertex& source_of_segment(const Segment& segment) - { - return m_vertices[segment.source_idx()]; - } - inline const Vertex& source_of_segment(std::size_t segment_idx) const - { - return source_of_segment(m_segments[segment_idx]); - } - inline Vertex& source_of_segment(std::size_t segment_idx) - { - return source_of_segment(m_segments[segment_idx]); - } - - // Segment/idx -> target Vertex - inline const Vertex& target_of_segment(const Segment& segment) const - { - return m_vertices[segment.target_idx()]; - } - inline Vertex& target_of_segment(const Segment& segment) - { - return m_vertices[segment.target_idx()]; - } - inline const Vertex& target_of_segment(std::size_t segment_idx) const - { - return target_of_segment(m_segments[segment_idx]); - } - inline Vertex& target_of_segment(std::size_t segment_idx) - { - return target_of_segment(m_segments[segment_idx]); - } - - - // idx -> opposite Vertex - inline const Vertex& opposite_vertex(std::size_t vertex_idx) const - { - const Segment& segment = segment_of_vertex(vertex_idx); - - CGAL_assertion(segment.source_idx() == vertex_idx - || segment.target_idx() == vertex_idx); - - return (segment.source_idx() == vertex_idx ? - m_vertices[segment.target_idx()] : - m_vertices[segment.source_idx()]); - } - - - // Segment/idx -> Support_line - inline const Support_line_DS& support_line_of_segment(const Segment& segment) const - { - return m_support_lines[segment.support_line_idx()]; - } - inline Support_line_DS& support_line_of_segment(const Segment& segment) - { - return m_support_lines[segment.support_line_idx()]; - } - inline const Support_line_DS& support_line_of_segment(std::size_t segment_idx) const - { - return support_line_of_segment(m_segments[segment_idx]); - } - inline Support_line_DS& support_line_of_segment(std::size_t segment_idx) - { - return support_line_of_segment(m_segments[segment_idx]); - } - - // Vertex/idx -> Support_line - inline const Support_line_DS& support_line_of_vertex(const Vertex& vertex) const - { - return support_line_of_segment(vertex.segment_idx()); - } - inline Support_line_DS& support_line_of_vertex(const Vertex& vertex) - { - return support_line_of_segment(vertex.segment_idx()); - } - inline const Support_line_DS& support_line_of_vertex(std::size_t vertex_idx) const - { - return support_line_of_vertex(m_vertices[vertex_idx]); - } - inline Support_line_DS& support_line_of_vertex(std::size_t vertex_idx) - { - return support_line_of_vertex(m_vertices[vertex_idx]); - } - - // Vertex/idx -> Meta_vertex - inline const Meta_vertex& meta_vertex_of_vertex(const Vertex& vertex) const - { - return m_meta_vertices[vertex.meta_vertex_idx()]; - } - inline Meta_vertex& meta_vertex_of_vertex(const Vertex& vertex) - { - return m_meta_vertices[vertex.meta_vertex_idx()]; - } - inline const Meta_vertex& meta_vertex_of_vertex(std::size_t vertex_idx) const - { - return meta_vertex_of_vertex(m_vertices[vertex_idx]); - } - inline Meta_vertex& meta_vertex_of_vertex(std::size_t vertex_idx) - { - return meta_vertex_of_vertex(m_vertices[vertex_idx]); - } - - bool has_meta_vertex(const Vertex& vertex) const - { - return vertex.meta_vertex_idx() != std::size_t(-1); - } - bool has_meta_vertex(std::size_t vertex_idx) const - { - return has_meta_vertex(m_vertices[vertex_idx]); - } - - FT position_of_meta_vertex_on_support_line(std::size_t meta_vertex_idx, std::size_t support_line_idx) const - { - return support_line(support_line_idx).to_1d(meta_vertex(meta_vertex_idx).point()); - } - - inline bool meta_vertex_exists(const Point_2& point) const - { - return m_meta_map.find(point) != m_meta_map.end(); - } - - void get_vertices_of_meta_vertex(std::size_t meta_vertex_idx, - std::vector& vertices_idx) const - { - const Meta_vertex& meta_vertex = m_meta_vertices[meta_vertex_idx]; - for (std::size_t support_line_idx : meta_vertex.support_lines_idx()) - { - const Support_line_DS& support_line = m_support_lines[support_line_idx]; - for (std::size_t segment_idx : support_line.segments_idx()) - { - const Segment& segment = m_segments[segment_idx]; - for (std::size_t vertex_idx : { segment.source_idx(), segment.target_idx() }) - if (m_vertices[vertex_idx].meta_vertex_idx() == meta_vertex_idx) - vertices_idx.push_back(vertex_idx); - } - } - } - - inline CGAL::Bbox_2 bbox(const Vertex& vertex) const - { - return point_of_vertex(vertex).bbox(); - } - inline CGAL::Bbox_2 bbox(const Support_line_DS& support_line) const - { - return std::accumulate(support_line.segments_idx().begin(), support_line.segments_idx().end(), - CGAL::Bbox_2(), - [&](const CGAL::Bbox_2& bbox_2, const std::size_t& segment_idx) -> CGAL::Bbox_2 - { - return bbox_2 - + bbox(source_of_segment(segment_idx)) - + bbox(target_of_segment(segment_idx)); - }); - } - - bool is_segment_frozen(std::size_t segment_idx) const - { - return (source_of_segment(segment_idx).is_frozen() && target_of_segment(segment_idx).is_frozen()); - } - - // idx -> Segment_2 - Segment_2 segment_2(std::size_t segment_idx) const - { - const Segment& segment = m_segments[segment_idx]; - const Support_line_DS& support_line = m_support_lines[segment.support_line_idx()]; - const Vertex& source = m_vertices[segment.source_idx()]; - const Vertex& target = m_vertices[segment.target_idx()]; - - return Segment_2(support_line.to_2d(source.point(m_current_time)), support_line.to_2d(target.point(m_current_time))); - } - - bool is_bbox_support_line(std::size_t support_line_idx) const - { - return support_line_idx < 4; - } - - bool is_bbox_segment(std::size_t segment_idx) const - { - return is_bbox_support_line(segment(segment_idx).support_line_idx()); - } - - bool is_bbox_meta_vertex(std::size_t meta_vertex_idx) const - { - for (std::size_t support_line_idx : meta_vertex(meta_vertex_idx).support_lines_idx()) - if (is_bbox_support_line(support_line_idx)) - return true; - return false; - } - - bool is_bbox_meta_edge(std::size_t source_idx, std::size_t target_idx) const - { - std::size_t common_line_idx = std::size_t(-1); - - for (std::size_t support_line_idx : meta_vertex(source_idx).support_lines_idx()) - if (m_meta_vertices[target_idx].support_lines_idx().find(support_line_idx) - != m_meta_vertices[target_idx].support_lines_idx().end()) - { - common_line_idx = support_line_idx; - break; - } - - CGAL_assertion(common_line_idx != std::size_t(-1)); - - return is_bbox_support_line(common_line_idx); - } - - bool is_meta_vertex_active(std::size_t meta_vertex_idx) const - { - for (std::size_t support_line_idx : meta_vertex(meta_vertex_idx).support_lines_idx()) - for (std::size_t segment_idx : support_line(support_line_idx).segments_idx()) - for (std::size_t vertex_idx : { segment(segment_idx).source_idx(), segment(segment_idx).target_idx() }) - if (vertex(vertex_idx).meta_vertex_idx() == meta_vertex_idx) - return true; - return false; - } - - bool is_meta_vertex_intersection(std::size_t meta_vertex_idx) const - { - bool found_one = false; - - for (std::size_t support_line_idx : meta_vertex(meta_vertex_idx).support_lines_idx()) - { - bool broken = false; - for (std::size_t segment_idx : support_line(support_line_idx).segments_idx()) - { - for (std::size_t vertex_idx : { segment(segment_idx).source_idx(), segment(segment_idx).target_idx() }) - { - if (vertex(vertex_idx).meta_vertex_idx() == meta_vertex_idx) - { - if (found_one) - return true; - found_one = true; - broken = true; - break; - } - } - if (broken) - break; - } - } - return false; - } - - bool is_meta_vertex_deadend_of_vertex(std::size_t meta_vertex_idx, std::size_t vertex_idx) const - { - return meta_vertex(meta_vertex_idx).is_deadend_of(segment_of_vertex(vertex_idx).support_line_idx()); - } - - void make_meta_vertex_deadend_of_vertex(std::size_t meta_vertex_idx, std::size_t vertex_idx) - { - meta_vertex(meta_vertex_idx).make_deadend_of(segment_of_vertex(vertex_idx).support_line_idx()); - } - - void make_meta_vertex_no_longer_deadend_of_vertex(std::size_t meta_vertex_idx, std::size_t vertex_idx) - { - meta_vertex(meta_vertex_idx).make_no_longer_deadend_of(segment_of_vertex(vertex_idx).support_line_idx()); - } - - std::size_t add_support_line(const Segment_2& segment) - { - m_support_lines.push_back(Support_line_DS(segment)); - return std::size_t(m_support_lines.size() - 1); - } - - Segment& add_segment(const Segment_2 segment, std::size_t input_idx = std::size_t(-1)) - { - // Check if support line exists first - Support_line_DS new_support_line(segment); - std::size_t support_line_idx = std::size_t(-1); - for (std::size_t i = 0; i < number_of_support_lines(); ++i) - if (new_support_line == support_line(i)) - { - support_line_idx = i; - break; - } - - if (support_line_idx == std::size_t(-1)) - { - support_line_idx = number_of_support_lines(); - m_support_lines.push_back(new_support_line); - - if (input_idx == std::size_t(-1)) - { - m_support_lines.back().minimum() = m_support_lines.back().to_1d(segment.source()); - m_support_lines.back().maximum() = m_support_lines.back().to_1d(segment.target()); - } - else - { - FT max_negative = -(std::numeric_limits::max)(); - FT min_positive = (std::numeric_limits::max)(); - - for (std::size_t i = 0; i < 4; ++i) - { - Point_2 point; - if (!KSP::internal::intersection(m_support_lines[i].line(), m_support_lines.back().line(), point)) - continue; - - FT position = m_support_lines.back().to_1d(point); - if (position < 0 && position > max_negative) - max_negative = position; - if (position > 0 && position < min_positive) - min_positive = position; - } - - CGAL_assertion(max_negative != -(std::numeric_limits::max)() - && min_positive != -(std::numeric_limits::min)()); - - m_support_lines.back().minimum() = max_negative; - m_support_lines.back().maximum() = min_positive; - } - } - else - support_line(support_line_idx).connected_components()++; - - - std::size_t segment_idx = m_segments.size(); - m_segments.push_back(Segment(input_idx, support_line_idx)); - m_support_lines[support_line_idx].segments_idx().push_back(segment_idx); - - std::size_t source_idx = m_vertices.size(); - m_vertices.push_back(Vertex(m_support_lines[support_line_idx].to_1d(segment.source()), - segment_idx)); - std::size_t target_idx = m_vertices.size(); - m_vertices.push_back(Vertex(m_support_lines[support_line_idx].to_1d(segment.target()), - segment_idx)); - - // Keep segment ordered - if (m_vertices[source_idx].point(0) > m_vertices[target_idx].point(0)) - std::swap(source_idx, target_idx); - - m_segments[segment_idx].source_idx() = source_idx; - m_segments[segment_idx].target_idx() = target_idx; - return m_segments.back(); - } - - std::size_t add_meta_vertex(const Point_2& point, - std::size_t support_line_idx_0, - std::size_t support_line_idx_1 = std::size_t(-1)) - { - // Avoid several points almost equal - Point_2 p(1e-10 * std::floor(CGAL::to_double(point.x()) / 1e-10), - 1e-10 * std::floor(CGAL::to_double(point.y()) / 1e-10)); - - typename std::map::iterator iter; - bool inserted = false; - std::tie(iter, inserted) = m_meta_map.insert(std::make_pair(p, number_of_meta_vertices())); - if (inserted) - m_meta_vertices.push_back(Meta_vertex(p)); - - std::size_t meta_vertex_idx = iter->second; - - for (std::size_t support_line_idx : { support_line_idx_0, support_line_idx_1 }) - { - if (support_line_idx != std::size_t(-1)) - { - meta_vertex(meta_vertex_idx).support_lines_idx().insert(support_line_idx); - - if (std::find(support_line(support_line_idx).meta_vertices_idx().begin(), - support_line(support_line_idx).meta_vertices_idx().end(), - meta_vertex_idx) == support_line(support_line_idx).meta_vertices_idx().end()) - support_line(support_line_idx).meta_vertices_idx().push_back(meta_vertex_idx); - } - } - - // Special case = meta vertex is deadend of one line - if (support_line_idx_1 == std::size_t(-1)) - { - meta_vertex(meta_vertex_idx).make_deadend_of(support_line_idx_0); - } - - return meta_vertex_idx; - } - - void attach_vertex_to_meta_vertex(std::size_t vertex_idx, std::size_t meta_vertex_idx) - { - CGAL_assertion(!has_meta_vertex(vertex_idx)); - CGAL_assertion_msg(meta_vertex(meta_vertex_idx).support_lines_idx().find - (segment_of_vertex(vertex_idx).support_line_idx()) - != meta_vertex(meta_vertex_idx).support_lines_idx().end(), - "Trying to attach a vertex to a meta vertex not on its support line"); - vertex(vertex_idx).meta_vertex_idx() = meta_vertex_idx; - } - - void cut_segment(std::size_t segment_idx, std::size_t meta_vertex_idx) - { - std::vector vec(1, meta_vertex_idx); - cut_segment(segment_idx, vec); - } - - void cut_segment(std::size_t segment_idx, std::vector& meta_vertices_idx) - { - Segment& segment = m_segments[segment_idx]; - std::size_t input_idx = segment.input_idx(); - std::size_t support_line_idx = segment.support_line_idx(); - // std::size_t source_idx = segment.source_idx(); - std::size_t target_idx = segment.target_idx(); - - Support_line_DS& support_line = support_line_of_segment(segment_idx); - - std::sort(meta_vertices_idx.begin(), meta_vertices_idx.end(), - [&](const std::size_t& a, - const std::size_t& b) -> bool - { - return (position_of_meta_vertex_on_support_line(a, support_line_idx) - < position_of_meta_vertex_on_support_line(b, support_line_idx)); - }); - - // Attach to existing endpoint - std::size_t new_target_idx = m_vertices.size(); - m_vertices.push_back(Vertex(position_of_meta_vertex_on_support_line(meta_vertices_idx.front(), - support_line_idx))); - m_vertices[new_target_idx].segment_idx() = segment_idx; - segment.target_idx() = new_target_idx; - attach_vertex_to_meta_vertex(new_target_idx, meta_vertices_idx.front()); - - // Create new segments - for (std::size_t i = 0; i < meta_vertices_idx.size() - 1; ++i) - { - std::size_t sidx = m_segments.size(); - m_segments.push_back(Segment(input_idx, support_line_idx)); - support_line.segments_idx().push_back(sidx); - - std::size_t source_idx = m_vertices.size(); - m_vertices.push_back(Vertex(position_of_meta_vertex_on_support_line(meta_vertices_idx[i], - support_line_idx))); - m_vertices[source_idx].segment_idx() = sidx; - m_segments[sidx].source_idx() = source_idx; - attach_vertex_to_meta_vertex(source_idx, meta_vertices_idx[i]); - - std::size_t target_idx = m_vertices.size(); - m_vertices.push_back(Vertex(position_of_meta_vertex_on_support_line(meta_vertices_idx[i + 1], - support_line_idx))); - m_vertices[target_idx].segment_idx() = sidx; - m_segments[sidx].target_idx() = target_idx; - attach_vertex_to_meta_vertex(source_idx, meta_vertices_idx[i + 1]); - } - - // Create final segment and attach to existing endpoint - std::size_t sidx = m_segments.size(); - m_segments.push_back(Segment(input_idx, support_line_idx)); - support_line.segments_idx().push_back(sidx); - - std::size_t new_source_idx = m_vertices.size(); - m_vertices.push_back(Vertex(position_of_meta_vertex_on_support_line(meta_vertices_idx.back(), - support_line_idx))); - m_vertices[new_source_idx].segment_idx() = sidx; - m_segments[sidx].source_idx() = new_source_idx; - attach_vertex_to_meta_vertex(new_source_idx, meta_vertices_idx.back()); - - m_vertices[target_idx].segment_idx() = sidx; - m_segments[sidx].target_idx() = target_idx; - } - - std::size_t propagate_segment(std::size_t vertex_idx) - { - // Create a new segment - std::size_t segment_idx = m_segments.size(); - m_segments.push_back(Segment(segment_of_vertex(vertex_idx).input_idx(), - segment_of_vertex(vertex_idx).support_line_idx())); - support_line_of_vertex(vertex_idx).segments_idx().push_back(segment_idx); - - // Create new vertices - std::size_t source_idx = m_vertices.size(); - m_vertices.push_back(Vertex(m_vertices[vertex_idx])); - std::size_t target_idx = m_vertices.size(); - m_vertices.push_back(Vertex(m_vertices[vertex_idx])); - - // Connect segments and vertices - m_segments[segment_idx].source_idx() = source_idx; - m_segments[segment_idx].target_idx() = target_idx; - m_vertices[source_idx].segment_idx() = segment_idx; - m_vertices[target_idx].segment_idx() = segment_idx; - - CGAL_assertion(m_vertices[vertex_idx].direction() != 0); - - // Keep vertices ordered on the segment - if (m_vertices[vertex_idx].direction() < 0) - std::swap(source_idx, target_idx); - - // Freeze one end - m_vertices[source_idx].freeze(m_current_time); - - // Release other end - m_vertices[target_idx].meta_vertex_idx() = std::size_t(-1); - - return target_idx; - } - - void update_positions(FT time) - { - m_current_time = time; - } - -}; - -} // namespace internal -} // namespace KSP_2 -} // namespace CGAL - - -#endif // CGAL_KSP_2_DATA_STRUCTURE_H diff --git a/Kinetic_space_partition/include/CGAL/KSP_2/Event.h b/Kinetic_space_partition/include/CGAL/KSP_2/Event.h deleted file mode 100644 index 796b4756ccf1..000000000000 --- a/Kinetic_space_partition/include/CGAL/KSP_2/Event.h +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) 2019 GeometryFactory Sarl (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial -// -// -// Author(s) : Simon Giraudot - -#ifndef CGAL_KSP_2_EVENT_H -#define CGAL_KSP_2_EVENT_H - -#include - -#include - -namespace CGAL { -namespace KSP_2 { -namespace internal { - -template -class Event_queue; - -template -class Event -{ -public: - typedef GeomTraits Kernel; - typedef typename Kernel::FT FT; - typedef typename Kernel::Point_2 Point_2; - - typedef Event_queue Queue; - friend Queue; - -private: - - std::size_t m_vertex_idx; - std::size_t m_meta_vertex_idx; - FT m_time; - -public: - - Event() { } - - Event(std::size_t vertex_idx, std::size_t meta_vertex_idx, FT time) - : m_vertex_idx(vertex_idx), m_meta_vertex_idx(meta_vertex_idx), m_time(time) - { } - - const std::size_t& vertex_idx() const { return m_vertex_idx; } - std::size_t& vertex_idx() { return m_vertex_idx; } - const std::size_t& meta_vertex_idx() const { return m_meta_vertex_idx; } - std::size_t& meta_vertex_idx() { return m_meta_vertex_idx; } - - FT time() const { return m_time; } - - friend std::ostream& operator<< (std::ostream& os, const Event& ev) - { - os << "Event at t=" << ev.m_time << " between vertex " << ev.m_vertex_idx - << " and meta vertex " << ev.m_meta_vertex_idx; - return os; - } - -}; - -} // namespace internal -} // namespace KSP_2 -} // namespace CGAL - - -#endif // CGAL_KSP_2_EVENT_H diff --git a/Kinetic_space_partition/include/CGAL/KSP_2/Event_queue.h b/Kinetic_space_partition/include/CGAL/KSP_2/Event_queue.h deleted file mode 100644 index b75d4be4dc39..000000000000 --- a/Kinetic_space_partition/include/CGAL/KSP_2/Event_queue.h +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (c) 2019 GeometryFactory Sarl (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial -// -// -// Author(s) : Simon Giraudot - -#ifndef CGAL_KSP_2_EVENT_QUEUE_H -#define CGAL_KSP_2_EVENT_QUEUE_H - -#include - -#include -#include - -#include -#include -#include -#include - -namespace CGAL { -namespace KSP_2 { -namespace internal { - -template -class Event_queue -{ -public: - typedef GeomTraits Kernel; - typedef typename Kernel::FT FT; - - typedef CGAL::KSP_2::internal::Event Event; - -private: - - typedef boost::multi_index_container - >, - boost::multi_index::ordered_non_unique - > - > - > 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; - - Queue m_queue; - -public: - - Event_queue() { } - - bool empty() const { return m_queue.empty(); } - std::size_t size() const { return m_queue.size(); } - - void push(const Event& ev) - { - 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>(); } - 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>(); } - - Event pop() - { - Queue_iterator iter = queue_by_time().begin(); - Event out = *iter; - m_queue.erase(iter); - return out; - } - - void print() const - { - for (const Event& e : m_queue) - std::cerr << e << std::endl; - } - - void erase_vertex_events(std::size_t vertex_idx, std::vector& events) - { - std::pair - range = queue_by_event_idx().equal_range(vertex_idx); - - std::copy(range.first, range.second, std::back_inserter(events)); - queue_by_event_idx().erase(range.first, range.second); - } - -}; - -} // namespace internal -} // namespace KSP_2 -} // namespace CGAL - - -#endif // CGAL_KSP_2_EVENT_QUEUE_H diff --git a/Kinetic_space_partition/include/CGAL/KSP_2/Meta_vertex.h b/Kinetic_space_partition/include/CGAL/KSP_2/Meta_vertex.h deleted file mode 100644 index 6713beeb95b8..000000000000 --- a/Kinetic_space_partition/include/CGAL/KSP_2/Meta_vertex.h +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (c) 2019 GeometryFactory Sarl (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial -// -// -// Author(s) : Simon Giraudot - -#ifndef CGAL_KSP_2_META_VERTEX_H -#define CGAL_KSP_2_META_VERTEX_H - -#include - -#include -#include - -namespace CGAL { -namespace KSP_2 { -namespace internal { - -template -class Meta_vertex -{ -private: - - Point_2 m_point; - std::set m_support_lines_idx; - - std::set m_deadends; - -public: - - Meta_vertex() { } - - Meta_vertex(const Point_2& point) : m_point(point) { } - - const Point_2& point() const { return m_point; } - - const std::set& support_lines_idx() const { return m_support_lines_idx; } - std::set& support_lines_idx() { return m_support_lines_idx; } - - void make_deadend_of(std::size_t support_line_idx) - { - m_deadends.insert(support_line_idx); - } - - bool is_deadend_of(std::size_t support_line_idx) const - { - return m_deadends.find(support_line_idx) != m_deadends.end(); - } - - void make_no_longer_deadend_of(std::size_t support_line_idx) - { - m_deadends.erase(support_line_idx); - } - - -}; - -} // namespace internal -} // namespace KSP_2 -} // namespace CGAL - - -#endif // CGAL_KSP_2_META_VERTEX_H diff --git a/Kinetic_space_partition/include/CGAL/KSP_2/Segment.h b/Kinetic_space_partition/include/CGAL/KSP_2/Segment.h deleted file mode 100644 index 63b0bea99d35..000000000000 --- a/Kinetic_space_partition/include/CGAL/KSP_2/Segment.h +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2019 GeometryFactory Sarl (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial -// -// -// Author(s) : Simon Giraudot - -#ifndef CGAL_KSP_2_SEGMENT_H -#define CGAL_KSP_2_SEGMENT_H - -#include - -namespace CGAL { -namespace KSP_2 { -namespace internal { - -class Segment -{ -private: - - std::size_t m_input_idx; - std::size_t m_source_idx; - std::size_t m_target_idx; - std::size_t m_support_line_idx; - -public: - - Segment() { } - - Segment(std::size_t input_idx, std::size_t support_line_idx) - : m_input_idx(input_idx), m_support_line_idx(support_line_idx) { } - - const std::size_t& input_idx() const { return m_input_idx; } - std::size_t& input_idx() { return m_input_idx; } - const std::size_t& source_idx() const { return m_source_idx; } - std::size_t& source_idx() { return m_source_idx; } - const std::size_t& target_idx() const { return m_target_idx; } - std::size_t& target_idx() { return m_target_idx; } - const std::size_t& support_line_idx() const { return m_support_line_idx; } - std::size_t& support_line_idx() { return m_support_line_idx; } -}; - -} // namespace internal -} // namespace KSP_2 -} // namespace CGAL - - -#endif // CGAL_KSP_2_POLYGON_H diff --git a/Kinetic_space_partition/include/CGAL/KSP_2/Support_line.h b/Kinetic_space_partition/include/CGAL/KSP_2/Support_line.h deleted file mode 100644 index 2b755952c1bd..000000000000 --- a/Kinetic_space_partition/include/CGAL/KSP_2/Support_line.h +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright (c) 2019 GeometryFactory Sarl (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial -// -// -// Author(s) : Simon Giraudot - -#ifndef CGAL_KSP_2_SUPPORT_LINE_H -#define CGAL_KSP_2_SUPPORT_LINE_H - -#include - -#include -#include - -namespace CGAL { -namespace KSP_2 { -namespace internal { - -template -class Support_line -{ -public: - typedef GeomTraits Kernel; - typedef typename Kernel::FT FT; - typedef typename Kernel::Point_2 Point_2; - typedef typename Kernel::Vector_2 Vector_2; - typedef typename Kernel::Line_2 Line_2; - typedef typename Kernel::Segment_2 Segment_2; - -private: - - Point_2 m_origin; - Vector_2 m_vector; - std::vector m_segments_idx; - std::vector m_meta_vertices_idx; - FT m_minimum; - FT m_maximum; - std::size_t m_connected_components; - -public: - - Support_line() { } - - Support_line(const Segment_2& segment) - : m_minimum((std::numeric_limits::max)()) - , m_maximum(-(std::numeric_limits::max)()) - , m_connected_components(1) - { - m_origin = CGAL::midpoint(segment.source(), segment.target()); - m_vector = KSP::internal::normalize(Vector_2(segment.source(), segment.target())); - } - - Line_2 line() const { return Line_2(m_origin, m_vector); } - - const Point_2& origin() const { return m_origin; } - const Vector_2& vector() const { return m_vector; } - - const FT& minimum() const { return m_minimum; } - FT& minimum() { return m_minimum; } - const FT& maximum() const { return m_maximum; } - FT& maximum() { return m_maximum; } - - const std::size_t& connected_components() const { return m_connected_components; } - std::size_t& connected_components() { return m_connected_components; } - - CGAL::Bbox_2 bbox() const - { - Point_2 pmin = to_2d(m_minimum); - Point_2 pmax = to_2d(m_maximum); - return pmin.bbox() + pmax.bbox(); - } - - Segment_2 segment_2() const - { - return Segment_2(to_2d(m_minimum), to_2d(m_maximum)); - } - - const std::vector& segments_idx() const { return m_segments_idx; } - std::vector& segments_idx() { return m_segments_idx; } - - const std::vector& meta_vertices_idx() const { return m_meta_vertices_idx; } - std::vector& meta_vertices_idx() { return m_meta_vertices_idx; } - - FT to_1d(const Point_2& point) const - { - return m_vector * Vector_2(m_origin, point); - } - - Point_2 to_2d(const FT& point) const { return m_origin + point * m_vector; } - -}; - -template -bool operator== (const Support_line& a, const Support_line& b) -{ - const typename Kernel::Vector_2& va = a.vector(); - const typename Kernel::Vector_2& vb = b.vector(); - - if (CGAL::abs(va * vb) < 0.99999) - return false; - - return (CGAL::approximate_sqrt(CGAL::squared_distance(b.origin(), a.line())) < 1e-10); -} - - -#if 0 -template <> -bool operator== -(const Support_line& a, - const Support_line& b) -{ - return (a.line() == b.line()); -} -#endif - -} // namespace internal -} // namespace KSP_2 -} // namespace CGAL - - -#endif // CGAL_KSP_2_SUPPORT_LINE_H diff --git a/Kinetic_space_partition/include/CGAL/KSP_2/Vertex.h b/Kinetic_space_partition/include/CGAL/KSP_2/Vertex.h deleted file mode 100644 index cc8a74eb824c..000000000000 --- a/Kinetic_space_partition/include/CGAL/KSP_2/Vertex.h +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright (c) 2019 GeometryFactory Sarl (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial -// -// -// Author(s) : Simon Giraudot - -#ifndef CGAL_KSP_2_VERTEX_H -#define CGAL_KSP_2_VERTEX_H - -#include - -#include - -namespace CGAL { -namespace KSP_2 { -namespace internal { - -template -class Vertex -{ -private: - - FT m_point; - FT m_direction; - std::size_t m_segment_idx; - unsigned int m_remaining_intersections; - std::size_t m_meta_vertex_idx; - -public: - - Vertex() { } - - Vertex(FT point, - std::size_t segment_idx = std::size_t(-1), - unsigned int remaining_intersections = 0) - : m_point(point) - , m_direction(0) - , m_segment_idx(segment_idx) - , m_remaining_intersections(remaining_intersections) - , m_meta_vertex_idx(std::size_t(-1)) - { - } - - const std::size_t& segment_idx() const { return m_segment_idx; } - std::size_t& segment_idx() { return m_segment_idx; } - - FT point(FT time) const { return m_point + time * m_direction; } - const FT& direction() const { return m_direction; } - FT& direction() { return m_direction; } - FT speed() const { return CGAL::abs(m_direction); } - - const unsigned int& remaining_intersections() const { return m_remaining_intersections; } - unsigned int& remaining_intersections() { return m_remaining_intersections; } - - const std::size_t& meta_vertex_idx() const { return m_meta_vertex_idx; } - std::size_t& meta_vertex_idx() { return m_meta_vertex_idx; } - - bool is_frozen() const { return (m_direction == FT(0)); } - void freeze(FT time) - { - m_point = m_point + time * m_direction; - m_direction = FT(0); - m_remaining_intersections = 0; - } - - friend std::ostream& operator<< (std::ostream& os, const Vertex& vertex) - { - os << "vertex(" << vertex.m_point << "," << vertex.m_direction << ") on segment " << vertex.m_segment_idx - << " and meta vertex " << vertex.meta_vertex_idx() << " with " - << vertex.m_remaining_intersections << " remaining intersection(s)"; - return os; - } - -}; - -} // namespace internal -} // namespace KSP_2 -} // namespace CGAL - -#endif // CGAL_KSP_2_VERTEX_H diff --git a/Kinetic_space_partition/include/CGAL/Kinetic_space_partition_2.h b/Kinetic_space_partition/include/CGAL/Kinetic_space_partition_2.h deleted file mode 100644 index 1e20990db081..000000000000 --- a/Kinetic_space_partition/include/CGAL/Kinetic_space_partition_2.h +++ /dev/null @@ -1,970 +0,0 @@ -// Copyright (c) 2019 GeometryFactory Sarl (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial -// -// -// Author(s) : Simon Giraudot - -#ifndef CGAL_KINETIC_SPACE_PARTITION_2_H -#define CGAL_KINETIC_SPACE_PARTITION_2_H - -#include - -#include - -#include -#include -#include - -#include -#include - -#include - -namespace CGAL -{ - -template -class Kinetic_space_partition_2 -{ -public: - - typedef GeomTraits Kernel; - typedef typename Kernel::FT FT; - typedef typename Kernel::Point_2 Point_2; - typedef typename Kernel::Segment_2 Segment_2; - typedef typename Kernel::Direction_2 Direction_2; - typedef typename Kernel::Line_2 Line_2; - typedef typename Kernel::Ray_2 Ray_2; - typedef typename Kernel::Vector_2 Vector_2; - - typedef KSP_2::internal::Data_structure Data; - typedef typename Data::Support_line_DS Support_line_DS; - typedef typename Data::Segment Segment; - typedef typename Data::Vertex Vertex; - - typedef typename Data::Meta_vertex Meta_vertex; - - typedef KSP_2::internal::Event Event; - typedef KSP_2::internal::Event_queue Event_queue; - -private: - - Data m_data; - Event_queue m_queue; - -public: - - Kinetic_space_partition_2() {} - - template - void partition (const SegmentRange& segments, SegmentMap segment_map, - unsigned int k = 2, FT enlarge_bbox_ratio = 1.1) - { - CGAL::Bbox_2 bbox; - for (const auto& vt : segments) - { - const Segment_2& segment = get (segment_map, vt); - bbox += segment.bbox(); - } - - add_bbox_as_segments (bbox, enlarge_bbox_ratio); - - // Add input as segments - std::size_t segment_idx = 0; - for (const typename SegmentRange::const_iterator::value_type& vt : segments) - { - Segment& segment = m_data.add_segment (get (segment_map, vt), segment_idx); - initialize_vertices_directions (segment, k); - ++ segment_idx; - } - - FT time_step = CGAL::approximate_sqrt(CGAL::squared_distance(Point_2 (bbox.xmin(), bbox.ymin()), - Point_2 (bbox.xmax(), bbox.ymax()))); - - time_step /= 50; - - make_segments_intersection_free(); - - CGAL_assertion(check_integrity(true)); - - -// m_data.print(); - - - FT min_time = 0; - while (initialize_queue(min_time, min_time + time_step)) - { - run(); - min_time += time_step; - } - - // Prepare output by sorting segments along support lines; - for (std::size_t i = 0; i < m_data.number_of_support_lines(); ++ i) - { - Support_line_DS& support_line = m_data.support_line(i); - std::sort (support_line.segments_idx().begin(), support_line.segments_idx().end(), - [&](const std::size_t& a, const std::size_t& b) -> bool - { - return (m_data.source_of_segment(a).point(m_data.current_time()) - < m_data.source_of_segment(b).point(m_data.current_time())); - }); - } - } - - bool check_integrity(bool verbose = false) const - { - for (std::size_t i = 0; i < m_data.number_of_support_lines(); ++ i) - { - const Support_line_DS& support_line = m_data.support_line(i); - for (std::size_t s : support_line.segments_idx()) - { - if (s == std::size_t(-1)) - { - if (verbose) - std::cerr << "ERROR: Support_line[" << i - << "] supports Segment[-1]" << std::endl; - return false; - } - const Segment& segment = m_data.segment(s); - if (segment.support_line_idx() != i) - { - if (verbose) - std::cerr << "ERROR: Support_line[" << i - << "] supports Segment[" << s - << "] which claims to be supported by Support_line[" << segment.support_line_idx() - << "]" << std::endl; - return false; - } - } - - for (std::size_t mv : support_line.meta_vertices_idx()) - { - if (std::find(m_data.meta_vertex(mv).support_lines_idx().begin(), - m_data.meta_vertex(mv).support_lines_idx().end(), - i) == m_data.meta_vertex(mv).support_lines_idx().end()) - { - if (verbose) - std::cerr << "ERROR: Support_line[" << i - << "] contains Meta_vertex[" << mv - << "] which claims it's not contained by it" << std::endl; - return false; - } - } - } - - for (std::size_t i = 0; i < m_data.number_of_segments(); ++ i) - { - const Segment& segment = m_data.segment(i); - - if (segment.source_idx() == std::size_t(-1)) - { - if (verbose) - std::cerr << "ERROR: Segment[" << i - << "] has source Vertex[-1]" << std::endl; - return false; - } - if (segment.target_idx() == std::size_t(-1)) - { - if (verbose) - std::cerr << "ERROR: Segment[" << i - << "] has source Vertex[-1]" << std::endl; - return false; - } - if (segment.support_line_idx() == std::size_t(-1)) - { - if (verbose) - std::cerr << "ERROR: Segment[" << i - << "] has support line Support_line[-1]" << std::endl; - return false; - } - if (m_data.source_of_segment(segment).segment_idx() != i) - { - if (verbose) - std::cerr << "ERROR: Segment[" << i - << "] has source Vertex[" << segment.source_idx() - << "] which claims to belong to Segment[" << m_data.source_of_segment(segment).segment_idx() - << "]" << std::endl; - return false; - } - if (m_data.target_of_segment(segment).segment_idx() != i) - { - if (verbose) - std::cerr << "ERROR: Segment[" << i - << "] has target Vertex[" << segment.target_idx() - << "] which claims to belong to Segment[" << m_data.target_of_segment(segment).segment_idx() - << "]" << std::endl; - return false; - } - if (segment.source_idx() == segment.target_idx()) - { - if (verbose) - std::cerr << "ERROR: Segment[" << i - << "] has Vertex[" << segment.source_idx() - << "] acting both as source and target" << std::endl; - return false; - } - if (m_data.source_of_segment(segment).meta_vertex_idx() != std::size_t(-1) - && m_data.target_of_segment(segment).meta_vertex_idx() != std::size_t(-1) - && m_data.source_of_segment(segment).meta_vertex_idx() == m_data.target_of_segment(segment).meta_vertex_idx()) - { - if (verbose) - std::cerr << "ERROR: Segment[" << i - << "] joins Vertex[" << segment.source_idx() - << "] to Vertex[" << segment.target_idx() - << "] which have the same meta vertex Meta_vertex[" - << m_data.source_of_segment(segment).meta_vertex_idx() << "]" << std::endl; - return false; - } - if (m_data.source_of_segment(segment).point(m_data.current_time()) - == m_data.target_of_segment(segment).point(m_data.current_time())) - { - if (verbose) - std::cerr << "ERROR: Segment[" << i - << "] joins Vertex[" << segment.source_idx() - << "] to Vertex[" << segment.target_idx() - << "] which represent the same point " - << m_data.point_of_vertex(m_data.source_of_segment(segment)) << std::endl; - return false; - } - if (m_data.source_of_segment(segment).point(m_data.current_time()) - > m_data.target_of_segment(segment).point(m_data.current_time())) - { - if (verbose) - std::cerr << "ERROR: Segment[" << i - << "] joins Vertex[" << segment.source_idx() - << "] to Vertex[" << segment.target_idx() - << "] which are wrongly ordered" << std::endl; - std::cerr << m_data.source_of_segment(segment).point(m_data.current_time()) - << " " << m_data.target_of_segment(segment).point(m_data.current_time()) << std::endl; - return false; - } - - if (std::find(m_data.support_line_of_segment(segment).segments_idx().begin(), - m_data.support_line_of_segment(segment).segments_idx().end(), - i) == m_data.support_line_of_segment(segment).segments_idx().end()) - { - if (verbose) - std::cerr << "ERROR: Segment[" << i - << "] has support line Support_line[" << segment.support_line_idx() - << "] which claims it does not support it" << std::endl; - return false; - } - } - - for (std::size_t i = 0; i < m_data.number_of_vertices(); ++ i) - { - const Vertex& vertex = m_data.vertex(i); - - if (vertex.segment_idx() == std::size_t(-1)) - { - if (verbose) - std::cerr << "ERROR: Vertex[" << i - << "] is on Segment[-1]" << std::endl; - return false; - } - // if (vertex.meta_vertex_idx() == std::size_t(-1)) - // { - // if (verbose) - // std::cerr << "ERROR: Vertex[" << i - // << "] has meta vertex Meta_vertex[-1]" << std::endl; - // return false; - // } - if (m_data.segment_of_vertex(vertex).source_idx() != i - && m_data.segment_of_vertex(vertex).target_idx() != i) - { - if (verbose) - std::cerr << "ERROR: Vertex[" << i - << "] is on Segment[" << vertex.segment_idx() - << "] but is neither source nor vertex of it" << std::endl; - return false; - } - - } - - for (std::size_t i = 0; i < m_data.number_of_meta_vertices(); ++ i) - { - const Meta_vertex& meta_vertex = m_data.meta_vertex(i); - - for (std::size_t sl : meta_vertex.support_lines_idx()) - { - if (std::find(m_data.support_line(sl).meta_vertices_idx().begin(), - m_data.support_line(sl).meta_vertices_idx().end(), - i) == m_data.support_line(sl).meta_vertices_idx().end()) - { - if (verbose) - std::cerr << "ERROR: Meta_vertex[" << i - << "] contains Support_line[" << sl - << "] which claims it's not contained by it" << std::endl; - return false; - } - } - } - - return true; - } - - template - OutputIterator output_partition_edges_to_segment_soup (OutputIterator output) const - { - std::vector > neighbors - (m_data.number_of_meta_vertices()); - get_meta_neighbors (neighbors); - - for (std::size_t i = 0; i < m_data.number_of_meta_vertices(); ++ i) - for (std::size_t j = 0; j < neighbors[i].size(); ++ j) - *(output ++) = Segment_2 (m_data.meta_vertex(i).point(), - m_data.meta_vertex(neighbors[i][j]).point()); - - return output; - } - - template - OutputIterator output_raw_partition_edges_to_segment_soup (OutputIterator output) const - { - for (std::size_t i = 0; i < m_data.number_of_segments(); ++ i) - *(output ++) = m_data.segment_2(i); - - return output; - } - - template - void output_partition_cells_to_polygon_soup (VertexOutputIterator vertices, - FacetOutputIterator /* facets */) const - { - for (std::size_t i = 0; i < m_data.number_of_meta_vertices(); ++ i) - *(vertices ++) = m_data.meta_vertex(i).point(); - } - - template - bool output_partition_cells_to_face_graph (MutableFaceGraph& mesh) const - { - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - typedef typename boost::graph_traits::edge_descriptor edge_descriptor; - typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - typedef typename boost::graph_traits::face_descriptor face_descriptor; - - static_assert((CGAL::graph_has_property::value)); - typedef typename property_map_selector::type VPMap; - VPMap vpm = get_property_map(boost::vertex_point, mesh); - - std::vector > neighbors (m_data.number_of_meta_vertices()); - get_meta_neighbors (neighbors); - - std::vector map_v2v (m_data.number_of_meta_vertices(), - boost::graph_traits::null_vertex()); - - std::map, halfedge_descriptor> hdesc; - std::set is_border_halfedge; - for (std::size_t i = 0; i < m_data.number_of_meta_vertices(); ++ i) - for (std::size_t j = 0; j < neighbors[i].size(); ++ j) - { - std::size_t source = i; - std::size_t target = neighbors[i][j]; - if (source > target) - continue; - - if (map_v2v[source] == boost::graph_traits::null_vertex()) - { - map_v2v[source] = add_vertex(mesh); - put (vpm, map_v2v[source], m_data.meta_vertex(source).point()); - } - vertex_descriptor v0 = map_v2v[source]; - - if (map_v2v[target] == boost::graph_traits::null_vertex()) - { - map_v2v[target] = add_vertex(mesh); - put (vpm, map_v2v[target], m_data.meta_vertex(target).point()); - } - vertex_descriptor v1 = map_v2v[target]; - - edge_descriptor ed = add_edge(mesh); - - halfedge_descriptor hd = halfedge(ed, mesh); - set_target(hd, v1, mesh); - halfedge_descriptor opp_hd = opposite(hd, mesh); - set_target(opp_hd, v0, mesh); - set_halfedge(v1, hd, mesh); - set_halfedge(v0, opp_hd, mesh); - - if (m_data.is_bbox_meta_edge(source, target)) - { - is_border_halfedge.insert(hd); - is_border_halfedge.insert(opp_hd); - } - - hdesc.insert (std::make_pair (std::make_pair (source, target), hd)); - hdesc.insert (std::make_pair (std::make_pair (target, source), opp_hd)); - } - - //std::cout << "* Found " << is_border_halfedge.size() << " border halfedges" << std::endl; - - for (std::size_t i = 0; i < m_data.number_of_meta_vertices(); ++ i) - { - if (map_v2v[i] == boost::graph_traits::null_vertex()) - continue; - - const Meta_vertex& meta_vertex = m_data.meta_vertex(i); - - std::vector& incident_meta_vertices = neighbors[i]; - - std::sort (incident_meta_vertices.begin(), incident_meta_vertices.end(), - [&](const std::size_t& a, const std::size_t& b) -> bool - { - return (Direction_2 (Segment_2 (meta_vertex.point(), m_data.meta_vertex(a).point())) - > Direction_2 (Segment_2 (meta_vertex.point(), m_data.meta_vertex(b).point()))); - }); - - for (std::size_t j = 0; j < incident_meta_vertices.size(); ++ j) - { - std::pair key0 - = std::make_pair (incident_meta_vertices[j], i); - std::pair key1 - = std::make_pair (incident_meta_vertices[(j+1)%incident_meta_vertices.size()], i); - - CGAL_assertion (hdesc.find(key0) != hdesc.end()); - CGAL_assertion (hdesc.find(key1) != hdesc.end()); - - halfedge_descriptor h0 = hdesc[key0]; - halfedge_descriptor h1 = hdesc[key1]; - set_next (h0, opposite(h1,mesh),mesh); - } - } - - // Creating Faces - for (halfedge_descriptor hd : halfedges(mesh)) - set_face (hd, boost::graph_traits::null_face(), mesh); - - std::unordered_set visited; - bool found_border_face = false; - for (halfedge_descriptor halfedge : halfedges(mesh)) - { - if (!visited.insert(halfedge).second) - continue; - - // First check if it is border face - halfedge_descriptor hd = halfedge; - halfedge_descriptor end = hd; - - bool border = true; - - if (found_border_face) - border = false; - else - { - do - { - // Border face only has border halfedges, as soon as we find one - // non-border edge, we're done - if (is_border_halfedge.find(hd) - == is_border_halfedge.end()) - { - border = false; - break; - } - hd = next(hd, mesh); - } - while (hd != end); - - hd = halfedge; - } - - if (border) - { - found_border_face = true; - end = hd; - do - { - visited.insert(hd); - hd = next(hd, mesh); - } - while (hd != end); - continue; - } - - face_descriptor fd = add_face(mesh); - set_halfedge(fd, hd, mesh); - - end = hd; - do - { - set_face(hd, fd, mesh); - visited.insert(hd); - hd = next(hd, mesh); - } - while (hd != end); - - } - - return is_valid_face_graph(mesh); - } - - - -private: - - void add_bbox_as_segments (const CGAL::Bbox_2& bbox, FT ratio) - { - FT xmed = (bbox.xmin() + bbox.xmax()) / 2.; - FT ymed = (bbox.ymin() + bbox.ymax()) / 2.; - FT dx = (bbox.xmax() - bbox.xmin()) / 2.; - FT dy = (bbox.ymax() - bbox.ymin()) / 2.; - - FT xmin = xmed - ratio * dx; - FT xmax = xmed + ratio * dx; - FT ymin = ymed - ratio * dy; - FT ymax = ymed + ratio * dy; - - std::array bbox_points - = { Point_2 (xmin, ymin), - Point_2 (xmin, ymax), - Point_2 (xmax, ymin), - Point_2 (xmax, ymax) }; - - // line 0 vertex[0] vertex[1] - m_data.add_segment (Segment_2 (bbox_points[0], bbox_points[1])); - // line 1 vertex[2] vertex[3] - m_data.add_segment (Segment_2 (bbox_points[1], bbox_points[3])); - // line 2 vertex[4] vertex[5] - m_data.add_segment (Segment_2 (bbox_points[3], bbox_points[2])); - // line 3 vertex[6] vertex[7] - m_data.add_segment (Segment_2 (bbox_points[2], bbox_points[0])); - - m_data.add_meta_vertex (bbox_points[0], 0, 3); - m_data.attach_vertex_to_meta_vertex (0, 0); - m_data.attach_vertex_to_meta_vertex (7, 0); - - m_data.add_meta_vertex (bbox_points[1], 0, 1); - m_data.attach_vertex_to_meta_vertex (1, 1); - m_data.attach_vertex_to_meta_vertex (2, 1); - - m_data.add_meta_vertex (bbox_points[2], 2, 3); - m_data.attach_vertex_to_meta_vertex (5, 2); - m_data.attach_vertex_to_meta_vertex (6, 2); - - m_data.add_meta_vertex (bbox_points[3], 1, 2); - m_data.attach_vertex_to_meta_vertex (3, 3); - m_data.attach_vertex_to_meta_vertex (4, 3); - - } - - void initialize_vertices_directions (Segment& segment, unsigned int k) - { - const Support_line_DS& support_line = m_data.support_line_of_segment (segment); - - Vertex& source = m_data.source_of_segment (segment); - Vertex& target = m_data.target_of_segment (segment); - - source.remaining_intersections() = k; - target.remaining_intersections() = k; - - Point_2 psource = m_data.point_of_vertex(source); - Point_2 ptarget = m_data.point_of_vertex(target); - - if (Vector_2 (psource, ptarget) * support_line.line().to_vector() > 0.) - { - source.direction() = -1; - target.direction() = 1; - } - else - { - source.direction() = 1; - target.direction() = -1; - } - } - - struct Box_with_idx : public CGAL::Box_intersection_d::Box_d - { - typedef CGAL::Box_intersection_d::Box_d Base; - std::size_t idx; - - Box_with_idx () { } - - Box_with_idx (const Bbox_2& bbox, std::size_t idx) - : Base(bbox), idx(idx) - { } - }; - - void make_segments_intersection_free() - { - std::vector > todo; - - std::vector segments_2; - segments_2.reserve (m_data.number_of_segments()); - std::vector boxes; - boxes.reserve (m_data.number_of_segments()); - for (std::size_t i = 0; i < m_data.number_of_segments(); ++ i) - { - segments_2.push_back (m_data.segment_2(i)); - boxes.push_back (Box_with_idx (segments_2.back().bbox(), i)); - } - - CGAL::box_self_intersection_d - (boxes.begin() + 4, boxes.end(), - [&](const Box_with_idx& a, const Box_with_idx& b) -> void - { - std::size_t segment_idx_a = a.idx; - std::size_t segment_idx_b = b.idx; - - CGAL_assertion (segment_idx_a != segment_idx_b); - - CGAL_assertion (m_data.segment(segment_idx_a).support_line_idx() - != m_data.segment(segment_idx_b).support_line_idx()); - - Point_2 point; - if (!KSP::internal::intersection(segments_2[segment_idx_a], segments_2[segment_idx_b], point)) - return; - - todo.push_back (std::make_tuple (point, - m_data.segment(segment_idx_a).support_line_idx(), - m_data.segment(segment_idx_b).support_line_idx())); - }); - - std::vector new_meta_vertices; - - for (const std::tuple& t : todo) - new_meta_vertices.push_back (m_data.add_meta_vertex (get<0>(t), get<1>(t), get<2>(t))); - - for (std::size_t meta_vertex_idx : new_meta_vertices) - { - for (std::size_t support_line_idx : m_data.meta_vertex(meta_vertex_idx).support_lines_idx()) - { - FT position = m_data.position_of_meta_vertex_on_support_line (meta_vertex_idx, support_line_idx); - for (std::size_t segment_idx : m_data.support_line(support_line_idx).segments_idx()) - { - if (m_data.source_of_segment(segment_idx).point(0) < position - && position < m_data.target_of_segment(segment_idx).point(0)) - { - m_data.cut_segment (segment_idx, meta_vertex_idx); - break; - } - } - } - } - } - - bool initialize_queue(FT min_time, FT max_time) - { - m_data.update_positions(max_time); - - bool still_running = false; - - // First, create all new meta vertices at line-line intersections - // that happened between min_time and max_time - std::vector new_meta_vertices; - - // Precompute segments and bboxes - std::vector segments_2; - segments_2.reserve (m_data.number_of_segments()); - std::vector segment_bboxes; - segment_bboxes.reserve (m_data.number_of_segments()); - for (std::size_t i = 0; i < m_data.number_of_segments(); ++ i) - { - segments_2.push_back (m_data.segment_2(i)); - segment_bboxes.push_back (segments_2.back().bbox()); - } - std::vector support_line_bboxes; - support_line_bboxes.reserve (m_data.number_of_support_lines()); - for (std::size_t i = 0; i < m_data.number_of_support_lines(); ++ i) - support_line_bboxes.push_back - (std::accumulate (m_data.support_line(i).segments_idx().begin(), - m_data.support_line(i).segments_idx().end(), - CGAL::Bbox_2(), - [&](const CGAL::Bbox_2& b, const std::size_t& segment_idx) -> CGAL::Bbox_2 - { - return b + segment_bboxes[segment_idx]; - })); - - - for (std::size_t i = 0; i < m_data.number_of_vertices(); ++ i) - { - const Vertex& vertex = m_data.vertex(i); - if (vertex.is_frozen()) - continue; - - still_running = true; - - Segment_2 si (m_data.support_line_of_vertex(vertex).to_2d(vertex.point(min_time)), - m_data.point_of_vertex(vertex)); - CGAL::Bbox_2 si_bbox = si.bbox(); - - for (std::size_t j = 0; j < m_data.number_of_support_lines(); ++ j) - { - if (m_data.segment_of_vertex(vertex).support_line_idx() == j) - continue; - - const Support_line_DS& support_line = m_data.support_line(j); - - if (!CGAL::do_overlap(si_bbox, support_line_bboxes[j])) - continue; - - for (std::size_t segment_idx : support_line.segments_idx()) - { - if (!CGAL::do_overlap(si_bbox, segment_bboxes[segment_idx])) - continue; - - Point_2 point; - if (!KSP::internal::intersection(si, segments_2[segment_idx], point)) - continue; - - Support_line_DS& sli = m_data.support_line_of_vertex(vertex); - FT dist = CGAL::approximate_sqrt (CGAL::squared_distance (sli.to_2d(vertex.point(0)), point)); - FT time = dist / vertex.speed(); - - if (time > min_time) - { - new_meta_vertices.push_back (m_data.add_meta_vertex - (point, j, - m_data.segment_of_vertex(vertex).support_line_idx())); - break; - } - } - } - } - - // Make sure structure stays correct - m_data.update_positions(min_time); - for (std::size_t meta_vertex_idx : new_meta_vertices) - { - for (std::size_t support_line_idx : m_data.meta_vertex(meta_vertex_idx).support_lines_idx()) - { - FT position = m_data.position_of_meta_vertex_on_support_line (meta_vertex_idx, support_line_idx); - for (std::size_t segment_idx : m_data.support_line(support_line_idx).segments_idx()) - { - if (m_data.source_of_segment(segment_idx).point(min_time) < position - && position < m_data.target_of_segment(segment_idx).point(min_time) - && !(m_data.source_of_segment(segment_idx).meta_vertex_idx() == meta_vertex_idx - || m_data.target_of_segment(segment_idx).meta_vertex_idx() == meta_vertex_idx)) - { - m_data.cut_segment (segment_idx, meta_vertex_idx); - break; - } - } - } - } - - // Second, create all new meta vertices at internal line - // intersection between two colinear segments - for (std::size_t i = 0; i < m_data.number_of_support_lines(); ++ i) - { - Support_line_DS& support_line = m_data.support_line(i); - if (support_line.connected_components() < 2) - continue; - - bool active_vertices = false; - - std::vector vertices_idx; - vertices_idx.reserve (support_line.segments_idx().size() * 2); - for (std::size_t segment_idx : support_line.segments_idx()) - { - for (std::size_t vertex_idx : { m_data.segment(segment_idx).source_idx(), - m_data.segment(segment_idx).target_idx() }) - { - vertices_idx.push_back (vertex_idx); - if (!m_data.vertex(vertex_idx).is_frozen()) - active_vertices = true; - } - } - - if (!active_vertices) - { - support_line.connected_components() = 1; - continue; - } - - std::sort (vertices_idx.begin(), vertices_idx.end(), - [&](const std::size_t& a, const std::size_t& b) -> bool - { return m_data.vertex(a).point(m_data.current_time()) - < m_data.vertex(b).point(m_data.current_time()); }); - - for (std::size_t j = 1; j < vertices_idx.size() - 2; ++ j) - { - const Vertex& a = m_data.vertex (vertices_idx[j]); - const Vertex& b = m_data.vertex (vertices_idx[j+1]); - if (a.segment_idx() == b.segment_idx()) - continue; - if (a.is_frozen() || b.is_frozen()) - continue; - - if (a.direction() < 0 || b.direction() > 0) - continue; - - FT time_to_collision = (b.point(m_data.current_time()) - a.point(m_data.current_time())) / 2.; - - if (time_to_collision < (max_time-min_time)) - { - Point_2 point_a = support_line.to_2d(a.point(min_time + time_to_collision)); - Point_2 point_b = support_line.to_2d(b.point(min_time + time_to_collision)); - Point_2 point = CGAL::midpoint (point_a, point_b); - - /* std::size_t meta_vertex_idx = */ m_data.add_meta_vertex (point, i); - } - } - } - - // Then compute events along the lines - - for (std::size_t i = 0; i < m_data.number_of_support_lines(); ++ i) - { - Support_line_DS& support_line = m_data.support_line(i); - - for (std::size_t segment_idx : support_line.segments_idx()) - { - const Segment& segment = m_data.segment(segment_idx); - - for (std::size_t vertex_idx : { segment.source_idx() , segment.target_idx() }) - { - const Vertex& vertex = m_data.vertex(vertex_idx); - if (vertex.is_frozen()) - continue; - - FT beginning = vertex.point(min_time); - FT end = vertex.point(max_time); - - auto last_element - = std::partition (support_line.meta_vertices_idx().begin(), - support_line.meta_vertices_idx().end(), - [&](const std::size_t meta_vertex_idx) -> bool - { - FT position = m_data.position_of_meta_vertex_on_support_line - (meta_vertex_idx, i); - return (((beginning < position) && (position <= end)) - || ((end <= position) && (position < beginning))); - }); - - for (auto it = support_line.meta_vertices_idx().begin(); it != last_element; ++ it) - m_queue.push (Event (vertex_idx, *it, - min_time + CGAL::abs(beginning - - m_data.position_of_meta_vertex_on_support_line - (*it, i)))); - } - - } - } - - return still_running; - } - - void run() - { - // static int iter = 0; - - while (!m_queue.empty()) - { - Event ev = m_queue.pop(); - - FT current_time = ev.time(); - - m_data.update_positions (current_time); - - apply(ev); - } - } - - void apply (const Event& ev) - { - bool is_meta_vertex_active = m_data.is_meta_vertex_active (ev.meta_vertex_idx()); - - // First, attach vertex to meta vertex - m_data.attach_vertex_to_meta_vertex (ev.vertex_idx(), ev.meta_vertex_idx()); - - // Then, check if vertex should be propagated behind - // -> if bbox is reached, we don't propagate - if (m_data.is_bbox_meta_vertex (ev.meta_vertex_idx())) - m_data.vertex(ev.vertex_idx()).remaining_intersections() = 0; - - // -> special case for parallel lines, if deadend is reached, we don't propagate - if (m_data.is_meta_vertex_deadend_of_vertex (ev.meta_vertex_idx(), ev.vertex_idx())) - { - m_data.vertex(ev.vertex_idx()).remaining_intersections() = 0; - } - - // -> if the number of K intersections is reached, we don't propagate - if (is_meta_vertex_active && m_data.vertex(ev.vertex_idx()).remaining_intersections() != 0) - m_data.vertex(ev.vertex_idx()).remaining_intersections() --; - - // If there are still intersections to be made, propagate - std::size_t new_vertex_idx = std::size_t(-1); - if (m_data.vertex(ev.vertex_idx()).remaining_intersections() != 0) - new_vertex_idx = m_data.propagate_segment (ev.vertex_idx()); - else - m_data.make_meta_vertex_deadend_of_vertex (ev.meta_vertex_idx(), ev.vertex_idx()); - - redistribute_vertex_events (ev.vertex_idx(), new_vertex_idx); - - m_data.vertex(ev.vertex_idx()).freeze(m_data.current_time()); - } - - void redistribute_vertex_events (std::size_t old_vertex, std::size_t new_vertex) - { - std::vector events; - m_queue.erase_vertex_events (old_vertex, events); - - if (new_vertex != std::size_t(-1)) - for (Event& ev : events) - { - ev.vertex_idx() = new_vertex; - m_queue.push (ev); - } - else - for (Event& ev : events) - if (m_data.is_meta_vertex_deadend_of_vertex (ev.meta_vertex_idx(), ev.vertex_idx())) - { - m_data.make_meta_vertex_no_longer_deadend_of_vertex (ev.meta_vertex_idx(), ev.vertex_idx()); - } - } - - void get_meta_neighbors (std::vector >& neighbors) const - { - for (std::size_t i = 0; i < m_data.number_of_support_lines(); ++ i) - { - const Support_line_DS& support_line = m_data.support_line(i); - - CGAL_assertion (support_line.meta_vertices_idx().size() > 1); - - std::size_t beginning = std::size_t(-1); - std::size_t end = std::size_t(-1); - - for (std::size_t segment_idx : support_line.segments_idx()) - { - // New segment - if (beginning == std::size_t(-1)) - { - beginning = m_data.source_of_segment(segment_idx).meta_vertex_idx(); - end = m_data.target_of_segment(segment_idx).meta_vertex_idx(); - } - else - { - // New segment is directly connected and no other line - // crossed the meta vertex: ignore meta vertex - if (end == m_data.source_of_segment(segment_idx).meta_vertex_idx() - && !m_data.is_meta_vertex_intersection (end)) - end = m_data.target_of_segment(segment_idx).meta_vertex_idx(); - // Otherwise, add a vertex and output the segment - else - { - neighbors[beginning].push_back (end); - neighbors[end].push_back (beginning); - beginning = m_data.source_of_segment(segment_idx).meta_vertex_idx(); - end = m_data.target_of_segment(segment_idx).meta_vertex_idx(); - } - } - } - neighbors[beginning].push_back (end); - neighbors[end].push_back (beginning); - } - } - -}; - - - -} // namespace CGAL - - -#endif // CGAL_KINETIC_SPACE_PARTITION_2_H diff --git a/Kinetic_space_partition/test/Kinetic_space_partition/CMakeLists.txt b/Kinetic_space_partition/test/Kinetic_space_partition/CMakeLists.txt index 05c1f28d63b0..e062c2063392 100644 --- a/Kinetic_space_partition/test/Kinetic_space_partition/CMakeLists.txt +++ b/Kinetic_space_partition/test/Kinetic_space_partition/CMakeLists.txt @@ -13,7 +13,7 @@ if(Eigen3_FOUND) message(STATUS "Found Eigen") include(CGAL_Eigen_support) - set(targets kinetic_2d_stress_test issue8198 kinetic_3d_test_all) + set(targets kinetic_3d_test_all) foreach(target ${targets}) create_single_source_cgal_program("${target}.cpp") diff --git a/Kinetic_space_partition/test/Kinetic_space_partition/issue8198.cpp b/Kinetic_space_partition/test/Kinetic_space_partition/issue8198.cpp deleted file mode 100644 index ea3cfca7befb..000000000000 --- a/Kinetic_space_partition/test/Kinetic_space_partition/issue8198.cpp +++ /dev/null @@ -1,312 +0,0 @@ -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -using SC = CGAL::Simple_cartesian; -using EPECK = CGAL::Exact_predicates_exact_constructions_kernel; -using EPICK = CGAL::Exact_predicates_inexact_constructions_kernel; -using EPECK_to_EPICK = CGAL::Cartesian_converter; - -using FT = typename EPECK::FT; -using Point_2 = typename EPECK::Point_2; -using Vector_2 = typename EPECK::Vector_2; -using Segment_2 = typename EPECK::Segment_2; -using Transform = CGAL::Aff_transformation_2; - -using Random = CGAL::Random; -using Mesh = CGAL::Surface_mesh; - -using Exact_reconstruction = CGAL::Kinetic_space_partition_2; -using Inexact_reconstruction = CGAL::Kinetic_space_partition_2; - -Random cgal_rand; - -#define OUTPUT_FILES - -void add_regular_case( - std::vector& segments) { - - const std::size_t size_before = segments.size(); - segments.push_back(Segment_2(Point_2(0.0, 1), Point_2(0.0, 3))); - segments.push_back(Segment_2(Point_2(0.0, 5), Point_2(0.0, 7))); - segments.push_back(Segment_2(Point_2(4.0, 1), Point_2(4.0, 3))); - segments.push_back(Segment_2(Point_2(4.0, 6), Point_2(4.0, 7))); - segments.push_back(Segment_2(Point_2(1.0, 0), Point_2(3.0, 0))); - segments.push_back(Segment_2(Point_2(2.0, 4), Point_2(3.0, 4))); - segments.push_back(Segment_2(Point_2(1.2, 8), Point_2(2.5, 8))); - - // Random rotation. - const double sine = cgal_rand.get_double(-1, 1); - const double cosine = CGAL::sqrt(1.0 - sine * sine); - - Transform rotate(CGAL::Rotation(), sine, cosine); - Transform scale(CGAL::Scaling(), cgal_rand.get_double(0.1, 10)); - Transform translate(CGAL::Translation(), Vector_2( - cgal_rand.get_double(-5, 5), cgal_rand.get_double(-5, 5))); - Transform transform = scale * rotate * translate; - - for (std::size_t i = size_before; i < segments.size(); ++i) { - const auto source = transform.transform(segments[i].source()); - const auto target = transform.transform(segments[i].target()); - segments[i] = Segment_2(source, target); - } -} - -void add_star_case( - std::vector& segments, - std::size_t star_branches) { - - const std::size_t size_before = segments.size(); - Segment_2 base(Point_2(0, 1), Point_2(0, 3)); - - for (std::size_t i = 0; i < star_branches; ++i) { - const double angle = 2.0 * CGAL_PI * (i / double(star_branches)); - Transform rotate(CGAL::Rotation(), std::sin(angle), std::cos(angle)); - segments.push_back(Segment_2( - rotate.transform(base.source()), - rotate.transform(base.target()))); - } - - // Random rotation. - const double sine = cgal_rand.get_double(-1.1); - const double cosine = CGAL::sqrt(1.0 - sine * sine); - Transform rotate(CGAL::Rotation(), sine, cosine); - Transform scale(CGAL::Scaling(), cgal_rand.get_double(0.1, 10)); - Transform translate(CGAL::Translation(), Vector_2( - cgal_rand.get_double(-5, 5), cgal_rand.get_double(-5, 5))); - Transform transform = scale * rotate * translate; - - for (std::size_t i = size_before; i < segments.size(); ++i) { - const auto source = transform.transform(segments[i].source()); - const auto target = transform.transform(segments[i].target()); - segments[i] = Segment_2(source, target); - } -} - -template -void get_segments_from_exact( - const std::vector&, - std::vector&) { - abort(); -} - -template<> -void get_segments_from_exact( - const std::vector& exact_segments, - std::vector& segments) { - - segments.reserve(exact_segments.size()); - std::copy(exact_segments.begin(), exact_segments.end(), std::back_inserter(segments)); -} - -template<> -void get_segments_from_exact( - const std::vector& exact_segments, - std::vector& segments) { - - static EPECK_to_EPICK e2e; - segments.reserve(exact_segments.size()); - std::transform(exact_segments.begin(), exact_segments.end(), - std::back_inserter(segments), - [&](const Segment_2& segment) -> typename EPICK::Segment_2 { - return e2e(segment); - }); -} - -template -void test_segments( - std::string test_name, - const std::vector& exact_segments, - unsigned int k) { - - CGAL::Real_timer t; - t.start(); - - std::vector segments; - get_segments_from_exact(exact_segments, segments); - - CGAL::Kinetic_space_partition_2 ksp; - ksp.partition(segments, CGAL::Identity_property_map(), k, 2); - segments.clear(); - ksp.output_partition_edges_to_segment_soup(std::back_inserter(segments)); - -#ifdef OUTPUT_FILES - std::ofstream output_file( - test_name + (std::is_same::value ? "_exact" : "_inexact") + "_output.polylines.txt"); - for (const auto& s : segments) { - output_file << "2 " << s.source() << " 0 " << s.target() << " 0" << std::endl; - } -#endif - - if (!ksp.check_integrity(true)) { - std::cerr << "ERROR: Integrity of reconstruction failed!" << std::endl; - return; - } - - CGAL::Surface_mesh mesh; - if (ksp.output_partition_cells_to_face_graph(mesh)) { -#ifdef OUTPUT_FILES - std::ofstream output_shapes_file( - test_name + (std::is_same::value ? "_exact" : "_inexact") + "_faces.ply"); - output_shapes_file - << "ply" << std::endl - << "format ascii 1.0" << std::endl - << "element vertex " << mesh.number_of_vertices() << std::endl - << "property double x" << std::endl - << "property double y" << std::endl - << "property double z" << std::endl - << "element face " << mesh.number_of_faces() << std::endl - << "property list uchar int vertex_index" << std::endl - << "property uchar red" << std::endl - << "property uchar green" << std::endl - << "property uchar blue" << std::endl - << "end_header" << std::endl; - - for (const auto& vindex : vertices(mesh)) { - output_shapes_file << mesh.point(vindex) << " 0" << std::endl; - } - for (const auto& findex : faces(mesh)) { - output_shapes_file << degree(findex, mesh); - for (const auto& hindex : CGAL::halfedges_around_face(halfedge(findex, mesh), mesh)) { - output_shapes_file << " " << int(target(hindex,mesh)); - } - output_shapes_file - << " " << cgal_rand.get_int(64,192) - << " " << cgal_rand.get_int(64,192) - << " " << cgal_rand.get_int(64,192) << std::endl; - } -#endif - } - else { - std::cerr << "ERROR: Invalid face graph!" << std::endl; - } - - t.stop(); - std::cerr - << " -> " - << (std::is_same::value ? "exact " : "inexact ") - << "stress test " << test_name << " done in " << t.time() << " seconds" << std::endl; -} - -void stress_test( - std::string test_name, - std::size_t nb_random_lines, - std::size_t nb_regular_boxes, - std::size_t nb_stars, - std::size_t star_branches, - unsigned int k) { - - cgal_rand = CGAL::Random(0); - - std::cerr << "[Stress test " << test_name << "]" << std::endl; - std::vector exact_segments; - - for (std::size_t i = 0; i < nb_regular_boxes; ++i) { - add_regular_case(exact_segments); - } - - for (std::size_t i = 0; i < nb_stars; ++i) { - add_star_case(exact_segments, star_branches); - } - - CGAL::Bbox_2 bbox(0, 0, 5, 5); - if (!exact_segments.empty()) { - for (const Segment_2& segment : exact_segments) { - bbox = bbox + segment.bbox(); - } - } - - Point_2 pmin(bbox.xmin(), bbox.ymin()); - Point_2 pmax(bbox.xmax(), bbox.ymax()); - double seg_size = CGAL::to_double(FT(0.1) * - CGAL::approximate_sqrt(CGAL::squared_distance(pmin, pmax))); - - for (std::size_t i = 0; i < nb_random_lines; ++i) { - - Point_2 source( - cgal_rand.get_double(bbox.xmin(), bbox.xmax()), - cgal_rand.get_double(bbox.ymin(), bbox.ymax())); - Vector_2 vec( - cgal_rand.get_double(-seg_size, seg_size), - cgal_rand.get_double(-seg_size, seg_size)); - Point_2 target = source + vec; - exact_segments.push_back(Segment_2(source, target)); - } - -#ifdef OUTPUT_FILES - std::ofstream input_file(test_name + "_input.polylines.txt"); - for (const Segment_2& s : exact_segments) { - input_file << "2 " << s.source() << " 0 " << s.target() << " 0" << std::endl; - } -#endif - - exact_segments.clear(); -exact_segments.push_back(Segment_2(Point_2( 2.44818 , 3.57048 ), Point_2( 1.39451 , 5.39643 ))); -exact_segments.push_back(Segment_2(Point_2( 0.340843 , 7.22239 ), Point_2( -0.712823 , 9.04835 ))); -exact_segments.push_back(Segment_2(Point_2( 92.528 , 27.2597 ), Point_2( 96.4776 , 33.6026 ))); - -#ifdef OUTPUT_FILES -std::ofstream output_file( - test_name + "_exact" + "_output.polylines.txt"); -output_file << "2 2.44818 3.57048 0 1.39451 5.39643 0" << std::endl; -output_file << "2 0.340843 7.22239 0 -0.712823 9.04835 0" << std::endl; -output_file << "2 92.528 27.2597 0 96.4776 33.6026 0" << std::endl; -output_file.close(); -#endif - - - -#ifdef TEST_EPECK - if (exact_segments.size() < 500) { - test_segments(test_name, exact_segments, k); - } - else { - std::cerr << " -> skipping exact test to avoid overly long running time (too many segments)" << std::endl; - } -#endif - -#if true - test_segments(test_name, exact_segments, k); -#endif -} - -int main(const int /* argc */, const char** /* argv */) { - - CGAL::get_default_random() = CGAL::Random(0); - - CGAL::Real_timer t; - t.start(); - - //~ stress_test("01_30_random_lines", 30, 0, 0, 0, 2); - //~ stress_test("02_300_random_lines", 300, 0, 0, 0, 2); - //~ stress_test("03_300_random_lines_k_10", 300, 0, 0, 0, 10); -//~ #if true - //~ stress_test("04_3000_random_lines", 3000, 0, 0, 0, 2); - //~ stress_test("05_3000_random_lines_k_3", 3000, 0, 0, 0, 3); -//~ #endif - - //~ stress_test("06_regular_case", 0, 1, 0, 0, 2); - //~ stress_test("07_multi_regular_case", 0, 5, 0, 0, 2); - //~ stress_test("08_multi_regular_case_and_random_lines", 30, 5, 0, 0, 2); - //~ stress_test("09_big_multi_regular_case_and_random_lines", 100, 30, 0, 0, 4); - - //~ stress_test("10_cross", 0, 0, 1, 4, 2); - //~ stress_test("11_star", 0, 0, 1, 6, 2); - //~ stress_test("12_multiple_stars", 0, 0, 5, 12, 2); - //~ stress_test("13_stars_and_regular", 0, 5, 5, 12, 3); - //~ stress_test("14_everything", 100, 30, 5, 12, 2); -#if true - stress_test("15_mayhem", 3000, 100, 10, 20, 4); -#endif - - t.stop(); - std::cerr << "All tests done in " << t.time() << " seconds!" << std::endl; - return EXIT_SUCCESS; -} diff --git a/Kinetic_space_partition/test/Kinetic_space_partition/kinetic_2d_stress_test.cpp b/Kinetic_space_partition/test/Kinetic_space_partition/kinetic_2d_stress_test.cpp deleted file mode 100644 index eda1b4b090f9..000000000000 --- a/Kinetic_space_partition/test/Kinetic_space_partition/kinetic_2d_stress_test.cpp +++ /dev/null @@ -1,292 +0,0 @@ -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -using SC = CGAL::Simple_cartesian; -using EPECK = CGAL::Exact_predicates_exact_constructions_kernel; -using EPICK = CGAL::Exact_predicates_inexact_constructions_kernel; -using EPECK_to_EPICK = CGAL::Cartesian_converter; - -using FT = typename EPECK::FT; -using Point_2 = typename EPECK::Point_2; -using Vector_2 = typename EPECK::Vector_2; -using Segment_2 = typename EPECK::Segment_2; -using Transform = CGAL::Aff_transformation_2; - -using Random = CGAL::Random; -using Mesh = CGAL::Surface_mesh; - -using Exact_reconstruction = CGAL::Kinetic_space_partition_2; -using Inexact_reconstruction = CGAL::Kinetic_space_partition_2; - -Random cgal_rand; - -void add_regular_case( - std::vector& segments) { - - const std::size_t size_before = segments.size(); - segments.push_back(Segment_2(Point_2(0.0, 1), Point_2(0.0, 3))); - segments.push_back(Segment_2(Point_2(0.0, 5), Point_2(0.0, 7))); - segments.push_back(Segment_2(Point_2(4.0, 1), Point_2(4.0, 3))); - segments.push_back(Segment_2(Point_2(4.0, 6), Point_2(4.0, 7))); - segments.push_back(Segment_2(Point_2(1.0, 0), Point_2(3.0, 0))); - segments.push_back(Segment_2(Point_2(2.0, 4), Point_2(3.0, 4))); - segments.push_back(Segment_2(Point_2(1.2, 8), Point_2(2.5, 8))); - - // Random rotation. - const double sine = cgal_rand.get_double(-1, 1); - const double cosine = CGAL::sqrt(1.0 - sine * sine); - - Transform rotate(CGAL::Rotation(), sine, cosine); - Transform scale(CGAL::Scaling(), cgal_rand.get_double(0.1, 10)); - Transform translate(CGAL::Translation(), Vector_2( - cgal_rand.get_double(-5, 5), cgal_rand.get_double(-5, 5))); - Transform transform = scale * rotate * translate; - - for (std::size_t i = size_before; i < segments.size(); ++i) { - const auto source = transform.transform(segments[i].source()); - const auto target = transform.transform(segments[i].target()); - segments[i] = Segment_2(source, target); - } -} - -void add_star_case( - std::vector& segments, - std::size_t star_branches) { - - const std::size_t size_before = segments.size(); - Segment_2 base(Point_2(0, 1), Point_2(0, 3)); - - for (std::size_t i = 0; i < star_branches; ++i) { - const double angle = 2.0 * CGAL_PI * (i / double(star_branches)); - Transform rotate(CGAL::Rotation(), std::sin(angle), std::cos(angle)); - segments.push_back(Segment_2( - rotate.transform(base.source()), - rotate.transform(base.target()))); - } - - // Random rotation. - const double sine = cgal_rand.get_double(-1.1); - const double cosine = CGAL::sqrt(1.0 - sine * sine); - Transform rotate(CGAL::Rotation(), sine, cosine); - Transform scale(CGAL::Scaling(), cgal_rand.get_double(0.1, 10)); - Transform translate(CGAL::Translation(), Vector_2( - cgal_rand.get_double(-5, 5), cgal_rand.get_double(-5, 5))); - Transform transform = scale * rotate * translate; - - for (std::size_t i = size_before; i < segments.size(); ++i) { - const auto source = transform.transform(segments[i].source()); - const auto target = transform.transform(segments[i].target()); - segments[i] = Segment_2(source, target); - } -} - -template -void get_segments_from_exact( - const std::vector&, - std::vector&) { - abort(); -} - -template<> -void get_segments_from_exact( - const std::vector& exact_segments, - std::vector& segments) { - - segments.reserve(exact_segments.size()); - std::copy(exact_segments.begin(), exact_segments.end(), std::back_inserter(segments)); -} - -template<> -void get_segments_from_exact( - const std::vector& exact_segments, - std::vector& segments) { - - static EPECK_to_EPICK e2e; - segments.reserve(exact_segments.size()); - std::transform(exact_segments.begin(), exact_segments.end(), - std::back_inserter(segments), - [&](const Segment_2& segment) -> typename EPICK::Segment_2 { - return e2e(segment); - }); -} - -template -void test_segments( - std::string test_name, - const std::vector& exact_segments, - unsigned int k) { - - CGAL::Real_timer t; - t.start(); - - std::vector segments; - get_segments_from_exact(exact_segments, segments); - - CGAL::Kinetic_space_partition_2 ksp; - ksp.partition(segments, CGAL::Identity_property_map(), k, 2); - segments.clear(); - ksp.output_partition_edges_to_segment_soup(std::back_inserter(segments)); - -#ifdef OUTPUT_FILES - std::ofstream output_file( - test_name + (std::is_same::value ? "_exact" : "_inexact") + "_output.polylines.txt"); - for (const auto& s : segments) { - output_file << "2 " << s.source() << " 0 " << s.target() << " 0" << std::endl; - } -#endif - - if (!ksp.check_integrity(true)) { - std::cerr << "ERROR: Integrity of reconstruction failed!" << std::endl; - return; - } - - CGAL::Surface_mesh mesh; - if (ksp.output_partition_cells_to_face_graph(mesh)) { -#ifdef OUTPUT_FILES - std::ofstream output_shapes_file( - test_name + (std::is_same::value ? "_exact" : "_inexact") + "_faces.ply"); - output_shapes_file - << "ply" << std::endl - << "format ascii 1.0" << std::endl - << "element vertex " << mesh.number_of_vertices() << std::endl - << "property double x" << std::endl - << "property double y" << std::endl - << "property double z" << std::endl - << "element face " << mesh.number_of_faces() << std::endl - << "property list uchar int vertex_index" << std::endl - << "property uchar red" << std::endl - << "property uchar green" << std::endl - << "property uchar blue" << std::endl - << "end_header" << std::endl; - - for (const auto& vindex : vertices(mesh)) { - output_shapes_file << mesh.point(vindex) << " 0" << std::endl; - } - for (const auto& findex : faces(mesh)) { - output_shapes_file << degree(findex, mesh); - for (const auto& hindex : CGAL::halfedges_around_face(halfedge(findex, mesh), mesh)) { - output_shapes_file << " " << int(target(hindex,mesh)); - } - output_shapes_file - << " " << cgal_rand.get_int(64,192) - << " " << cgal_rand.get_int(64,192) - << " " << cgal_rand.get_int(64,192) << std::endl; - } -#endif - } - else { - std::cerr << "ERROR: Invalid face graph!" << std::endl; - } - - t.stop(); - std::cerr - << " -> " - << (std::is_same::value ? "exact " : "inexact ") - << "stress test " << test_name << " done in " << t.time() << " seconds" << std::endl; -} - -void stress_test( - std::string test_name, - std::size_t nb_random_lines, - std::size_t nb_regular_boxes, - std::size_t nb_stars, - std::size_t star_branches, - std::size_t k) { - - cgal_rand = CGAL::Random(0); - - std::cerr << "[Stress test " << test_name << "]" << std::endl; - std::vector exact_segments; - - for (std::size_t i = 0; i < nb_regular_boxes; ++i) { - add_regular_case(exact_segments); - } - - for (std::size_t i = 0; i < nb_stars; ++i) { - add_star_case(exact_segments, star_branches); - } - - CGAL::Bbox_2 bbox(0, 0, 5, 5); - if (!exact_segments.empty()) { - for (const Segment_2& segment : exact_segments) { - bbox = bbox + segment.bbox(); - } - } - - Point_2 pmin(bbox.xmin(), bbox.ymin()); - Point_2 pmax(bbox.xmax(), bbox.ymax()); - double seg_size = CGAL::to_double(FT(0.1) * - CGAL::approximate_sqrt(CGAL::squared_distance(pmin, pmax))); - - for (std::size_t i = 0; i < nb_random_lines; ++i) { - - Point_2 source( - cgal_rand.get_double(bbox.xmin(), bbox.xmax()), - cgal_rand.get_double(bbox.ymin(), bbox.ymax())); - Vector_2 vec( - cgal_rand.get_double(-seg_size, seg_size), - cgal_rand.get_double(-seg_size, seg_size)); - Point_2 target = source + vec; - exact_segments.push_back(Segment_2(source, target)); - } - -#ifdef OUTPUT_FILES - std::ofstream input_file(test_name + "_input.polylines.txt"); - for (const Segment_2& s : exact_segments) { - input_file << "2 " << s.source() << " 0 " << s.target() << " 0" << std::endl; - } -#endif - -#ifdef TEST_EPECK - if (exact_segments.size() < 500) { - test_segments(test_name, exact_segments, k); - } - else { - std::cerr << " -> skipping exact test to avoid overly long running time (too many segments)" << std::endl; - } -#endif - -#if true - test_segments(test_name, exact_segments, k); -#endif -} - -int main(const int /* argc */, const char** /* argv */) { - - CGAL::Real_timer t; - t.start(); - - stress_test("01_30_random_lines", 30, 0, 0, 0, 2); - stress_test("02_300_random_lines", 300, 0, 0, 0, 2); - stress_test("03_300_random_lines_k_10", 300, 0, 0, 0, 10); -#if true - stress_test("04_3000_random_lines", 3000, 0, 0, 0, 2); - stress_test("05_3000_random_lines_k_3", 3000, 0, 0, 0, 3); -#endif - - stress_test("06_regular_case", 0, 1, 0, 0, 2); - stress_test("07_multi_regular_case", 0, 5, 0, 0, 2); - stress_test("08_multi_regular_case_and_random_lines", 30, 5, 0, 0, 2); - stress_test("09_big_multi_regular_case_and_random_lines", 100, 30, 0, 0, 4); - - stress_test("10_cross", 0, 0, 1, 4, 2); - stress_test("11_star", 0, 0, 1, 6, 2); - stress_test("12_multiple_stars", 0, 0, 5, 12, 2); - stress_test("13_stars_and_regular", 0, 5, 5, 12, 3); - stress_test("14_everything", 100, 30, 5, 12, 2); -#if true - stress_test("15_mayhem", 3000, 100, 10, 20, 4); -#endif - - t.stop(); - std::cerr << "All tests done in " << t.time() << " seconds!" << std::endl; - return EXIT_SUCCESS; -}