removed Event.h

added documentation
This commit is contained in:
Sven Oesau 2023-01-18 17:44:20 +01:00
parent 4b87b331e7
commit ddb155fb94
17 changed files with 574 additions and 279 deletions

View File

@ -786,15 +786,23 @@ double alpha_expansion_graphcut (const InputGraph& input_graph,
cut_time += timer.time();
#endif
graph.get_labels(vertex_index_map, vertex_label_map, inserted_vertices, CGAL::make_range(vertices(input_graph)));
/*
//update labeling
for (input_vertex_descriptor vd : CGAL::make_range(vertices(input_graph)))
{
std::size_t vertex_i = get(vertex_index_map, vd);
alpha_expansion.update(vertex_label_map, inserted_vertices, vd, vertex_i, alpha);
}*/
graph.get_labels(vertex_index_map, vertex_label_map, inserted_vertices, CGAL::make_range(vertices(input_graph)));
/*
//update labeling
for (auto vd : vertices(input_graph)) {
std::size_t idx = get(vertex_index_map, vd);
int label = graph.get_label(inserted_vertices[idx]);
put(vertex_label_map, vd, label);
}
/*
for (input_vertex_descriptor vd : CGAL::make_range(vertices(input_graph)))
{
std::size_t vertex_i = get(vertex_index_map, vd);

View File

@ -56,7 +56,7 @@ namespace KSR {
noise(FT(2)),
// boolean tags
with_normals(true),
verbose(true),
verbose(false),
debug(false),
// shape detection / shape regularization
k_neighbors(12),

View File

@ -79,7 +79,6 @@ void parse_terminal(Terminal_parser& parser, Parameters& parameters) {
}
int main(const int argc, const char** argv) {
// Parameters.
std::cout.precision(20);
std::cout << std::endl;
@ -181,6 +180,8 @@ int main(const int argc, const char** argv) {
const FT time = static_cast<FT>(timer.time());
// Output.
CGAL::Linear_cell_complex_for_combinatorial_map<3, 3> lcc;
ksr.get_linear_cell_complex(lcc);
// Vertices.
std::vector<Point_3> all_vertices;

View File

@ -32,6 +32,9 @@
namespace CGAL {
namespace KSR_3 {
#ifdef DOXYGEN_RUNNING
#else
template<typename GeomTraits>
class Data_structure {
@ -2051,6 +2054,8 @@ public:
};
#endif //DOXYGEN_RUNNING
} // namespace KSR_3
} // namespace CGAL

View File

@ -1,246 +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, Dmitry Anisimov
#ifndef CGAL_KSR_3_EVENT_H
#define CGAL_KSR_3_EVENT_H
// #include <CGAL/license/Kinetic_shape_reconstruction.h>
// CGAL includes.
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
// Internal includes.
#include <CGAL/KSR/utils.h>
namespace CGAL {
namespace KSR_3 {
template<typename Data_structure>
class Event_queue;
// This class works only with inexact number types because it is a base for the
// multi index container in the Event_queue class, which cannot handle exact number types.
template<typename Data_structure>
class Event {
public:
// Kernel types.
using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel;
using NT = typename Data_structure::Kernel::FT;
using FT = typename Kernel::FT;
// Data structure types.
using PVertex = typename Data_structure::PVertex;
using PEdge = typename Data_structure::PEdge;
using PFace = typename Data_structure::PFace;
using IVertex = typename Data_structure::IVertex;
using IEdge = typename Data_structure::IEdge;
// Event queue types.
using Queue = Event_queue<Data_structure>;
friend Queue;
struct ETime {
ETime(
const NT event_time,
const bool is_pv_to_iv,
const bool is_vt = false) :
m_time(static_cast<FT>(CGAL::to_double(event_time))),
m_is_pvertex_to_ivertex(is_pv_to_iv), m_is_virtual(is_vt)
{ }
private:
const FT m_time;
const bool m_is_pvertex_to_ivertex;
const bool m_is_virtual;
public:
bool operator<(const ETime& e) const {
const FT tol = KSR::tolerance<FT>();
const FT time_diff = CGAL::abs(this->time() - e.time());
if (time_diff < tol && !this->is_virtual() && !e.is_virtual()) {
const std::size_t la = this->is_pvertex_to_ivertex() ? 1 : 0;
const std::size_t lb = e.is_pvertex_to_ivertex() ? 1 : 0;
// std::cout << "la: " << la << ", time: " << this->time() << std::endl;
// std::cout << "lb: " << lb << ", time: " << e.time() << std::endl;
if (la != lb) return la < lb;
}
return this->time() < e.time();
}
FT time() const { return m_time; }
bool is_pvertex_to_ivertex() const { return m_is_pvertex_to_ivertex; }
bool is_virtual() const { return m_is_virtual; }
};
// Event types.
// Empty event.
Event() :
m_is_constrained(false),
m_pvertex(Data_structure::null_pvertex()),
m_pother(Data_structure::null_pvertex()),
m_ivertex(Data_structure::null_ivertex()),
m_iedge(Data_structure::null_iedge()),
m_time(ETime(NT(0), (
m_pother == Data_structure::null_pvertex() &&
m_ivertex != Data_structure::null_ivertex()))),
m_support_plane_idx(m_pvertex.first)
{ }
// An event that occurs between two polygon vertices.
Event(
const bool is_constrained,
const PVertex pvertex,
const PVertex pother,
const NT time) :
m_is_constrained(is_constrained),
m_pvertex(pvertex),
m_pother(pother),
m_ivertex(Data_structure::null_ivertex()),
m_iedge(Data_structure::null_iedge()),
m_time(ETime(time, (
m_pother == Data_structure::null_pvertex() &&
m_ivertex != Data_structure::null_ivertex()))),
m_support_plane_idx(m_pvertex.first) {
CGAL_assertion_msg(is_constrained,
"ERROR: THIS EVENT CANNOT EVER HAPPEN IN THE UNCONSTRAINED SETTING!");
}
// An event that occurs between a polygon vertex and an intersection graph edge.
Event(
const bool is_constrained,
const PVertex pvertex,
const IEdge iedge,
const NT time) :
m_is_constrained(is_constrained),
m_pvertex(pvertex),
m_pother(Data_structure::null_pvertex()),
m_ivertex(Data_structure::null_ivertex()),
m_iedge(iedge),
m_time(ETime(time, (
m_pother == Data_structure::null_pvertex() &&
m_ivertex != Data_structure::null_ivertex()))),
m_support_plane_idx(m_pvertex.first) {
CGAL_assertion_msg(!is_constrained,
"ERROR: THIS EVENT CANNOT EVER HAPPEN IN THE CONSTRAINED SETTING!");
}
// An event that occurs between a polygon vertex and an intersection graph vertex.
Event(
const bool is_constrained,
const PVertex pvertex,
const IVertex ivertex,
const NT time) :
m_is_constrained(is_constrained),
m_pvertex(pvertex),
m_pother(Data_structure::null_pvertex()),
m_ivertex(ivertex),
m_iedge(Data_structure::null_iedge()),
m_time(ETime(time, (
m_pother == Data_structure::null_pvertex() &&
m_ivertex != Data_structure::null_ivertex()))),
m_support_plane_idx(m_pvertex.first)
{ }
// An event that occurs between two polygon vertices and an intersection graph vertex.
Event(
const bool is_constrained,
const PVertex pvertex,
const PVertex pother,
const IVertex ivertex,
const NT time) :
m_is_constrained(is_constrained),
m_pvertex(pvertex),
m_pother(pother),
m_ivertex(ivertex),
m_iedge(Data_structure::null_iedge()),
m_time(ETime(time, (
m_pother == Data_structure::null_pvertex() &&
m_ivertex != Data_structure::null_ivertex()))),
m_support_plane_idx(m_pvertex.first) {
CGAL_assertion_msg(is_constrained,
"ERROR: THIS EVENT CANNOT EVER HAPPEN IN THE UNCONSTRAINED SETTING!");
}
bool operator<(const Event& e) const {
return time() < e.time();
}
// Data access.
const PVertex& pvertex() const { return m_pvertex; }
const PVertex& pother() const { return m_pother; }
const IVertex& ivertex() const { return m_ivertex; }
const IEdge& iedge() const { return m_iedge; }
NT time() const { return static_cast<NT>(m_time.time()); }
std::size_t support_plane() const { return m_support_plane_idx; }
// Predicates.
bool is_constrained() const { return m_is_constrained; }
// Event types. See constructors above.
bool is_pvertex_to_pvertex() const {
return (pother() != Data_structure::null_pvertex()); }
bool is_pvertex_to_iedge() const {
return (iedge() != Data_structure::null_iedge()); }
bool is_pvertex_to_ivertex() const {
return (pother() == Data_structure::null_pvertex() && ivertex() != Data_structure::null_ivertex()); }
bool is_pvertices_to_ivertex() const {
return (pother() != Data_structure::null_pvertex() && ivertex() != Data_structure::null_ivertex()); }
// Output.
friend std::ostream& operator<<(std::ostream& os, const Event& event) {
const std::string constr_type = ( event.is_constrained() ? "constrained " : "unconstrained " );
if (event.is_pvertices_to_ivertex()) {
os << constr_type << "event at t = " << event.time() << " between PVertex("
<< event.pvertex().first << ":" << event.pvertex().second
<< "), PVertex(" << event.pother().first << ":" << event.pother().second
<< "), and IVertex(" << event.ivertex() << ")";
} else if (event.is_pvertex_to_pvertex()) {
os << constr_type << "event at t = " << event.time() << " between PVertex("
<< event.pvertex().first << ":" << event.pvertex().second
<< ") and PVertex(" << event.pother().first << ":" << event.pother().second << ")";
} else if (event.is_pvertex_to_iedge()) {
os << constr_type << "event at t = " << event.time() << " between PVertex("
<< event.pvertex().first << ":" << event.pvertex().second
<< ") and IEdge" << event.iedge();
} else if (event.is_pvertex_to_ivertex()) {
os << constr_type << "event at t = " << event.time() << " between PVertex("
<< event.pvertex().first << ":" << event.pvertex().second
<< ") and IVertex(" << event.ivertex() << ")";
} else {
os << "ERROR: INVALID EVENT at t = " << event.time();
}
return os;
}
private:
bool m_is_constrained;
PVertex m_pvertex;
PVertex m_pother;
IVertex m_ivertex;
IEdge m_iedge;
ETime m_time;
std::size_t m_support_plane_idx;
};
} // namespace KSR_3
} // namespace CGAL
#endif // CGAL_KSR_3_EVENT_H

View File

@ -32,6 +32,9 @@ namespace KSR_3 {
template<typename Data_structure>
class Event_queue {
#ifdef DOXYGEN_RUNNING
#else
public:
// Data structure types.
using FT = typename Data_structure::Kernel::FT;
@ -275,6 +278,8 @@ private:
std::vector<Event> m_temporary_queue;
};
#endif //DOXYGEN_RUNNING
} // namespace KSR_3
} // namespace CGAL

View File

@ -26,6 +26,9 @@
namespace CGAL {
namespace KSR_3 {
#ifdef DOXYGEN_RUNNING
#else
template<typename GeomTraits>
class FacePropagation {
@ -213,6 +216,8 @@ private:
}
};
#endif //DOXYGEN_RUNNING
} // namespace KSR_3
} // namespace CGAL

View File

@ -27,6 +27,9 @@
namespace CGAL {
namespace KSR_3 {
#ifdef DOXYGEN_RUNNING
#else
template<typename GeomTraits>
class Finalizer {
@ -722,6 +725,8 @@ private:
}
};
#endif //DOXYGEN_RUNNING
} // namespace KSR_3
} // namespace CGAL

View File

@ -35,6 +35,9 @@
namespace CGAL {
namespace KSR_3 {
#ifdef DOXYGEN_RUNNING
#else
template<typename GeomTraits>
class Graphcut {
@ -453,22 +456,11 @@ namespace KSR_3 {
std::cout << "min: " << min << std::endl;
std::cout << "max: " << max << std::endl;
/*
CGAL::min_cut(
edges, edge_costs, cost_matrix, labels, CGAL::parameters::implementation_tag(CGAL::Alpha_expansion_MaxFlow_tag()));
bool difference = false;
for (std::size_t i = 0; i < labels.size(); i++) {
if (tmp[i] != labels[i]) {
difference = true;
break;
}
}
std::cout << "Labels changed: " << difference << std::endl;
*/
CGAL::alpha_expansion_graphcut(
edges, edge_costs, cost_matrix, labels, CGAL::parameters::implementation_tag(CGAL::Alpha_expansion_MaxFlow_tag()));
edges, edge_costs, cost_matrix, labels, CGAL::parameters::implementation_tag(CGAL::Alpha_expansion_MaxFlow_tag()));
/*
CGAL::min_cut(
edges, edge_costs, cost_matrix, labels, CGAL::parameters::implementation_tag(CGAL::Alpha_expansion_MaxFlow_tag()));*/
bool difference = false;
for (std::size_t i = 0; i < labels.size(); i++) {
@ -499,6 +491,8 @@ namespace KSR_3 {
}
};
#endif //DOXYGEN_RUNNING
} // KSR_3
} // CGAL

View File

@ -37,6 +37,9 @@
namespace CGAL {
namespace KSR_3 {
#ifdef DOXYGEN_RUNNING
#else
template<typename GeomTraits>
class Initializer {
@ -1210,6 +1213,8 @@ private:
}
};
#endif //DOXYGEN_RUNNING
} // namespace KSR_3
} // namespace CGAL

View File

@ -28,6 +28,9 @@
namespace CGAL {
namespace KSR_3 {
#ifdef DOXYGEN_RUNNING
#else
template<typename GeomTraits>
class Intersection_graph {
@ -427,6 +430,8 @@ public:
template<typename GeomTraits> std::size_t Intersection_graph<GeomTraits>::Edge_property::edge_counter = 0;
#endif //DOXYGEN_RUNNING
} // namespace KSR_3
} // namespace CGAL

View File

@ -37,6 +37,233 @@
namespace CGAL {
namespace KSR_3 {
#ifdef DOXYGEN_RUNNING
/*!
\brief Piece-wise linear reconstruction via inside/outside labeling of a kinetic partition using graph cut.
\tparam Kernel
must be a model of `Kernel`.
\tparam IntersectionKernel
must be a model of `Kernel`. Is used for the creation of the intersection graph. An exact kernel is suggested.
*/
template<Kernel, Intersection_Kernel>
class Kinetic_reconstruction_3 {
/*!
\brief Creates the kinetic partitioning of the bounding box.
\tparam InputRange
must be a model of `ConstRange` whose iterator type is `RandomAccessIterator`.
\tparam SemanticMap
must be an `LvaluePropertyMap` whose key type is the value type of the input
range and value type is `std::size_t`.
\tparam NamedParameters
a sequence of \ref bgl_namedparameters "Named Parameters"
\param input_range
an instance of `InputRange` with 3D points and corresponding 3D normal vectors
\cgalNamedParamsBegin
\cgalParamNBegin{point_map}
\cgalParamDescription{}
\cgalParamType{bool}
\cgalParamDefault{false}
\cgalParamNEnd
\cgalParamNBegin{normal_map}
\cgalParamDescription{}
\cgalParamType{bool}
\cgalParamDefault{false}
\cgalParamNEnd
\cgalParamNBegin{semantic_map}
\cgalParamDescription{A `LvaluePropertyMap` whose key type is the value type of the input range and value type is `std::size_t`.}
\cgalParamType{bool}
\cgalParamDefault{false}
\cgalParamNEnd
\cgalNamedParamsEnd
*/
template<
typename InputRange,
typename NamedParameters>
std::size_t detect_planar_shapes(
InputRange input_range,
const NamedParameters& np);
/*!
\brief Regularizes detected planar shapes by using `CGAL::Shape_regularization::Planes::regularize_planes` and merging coplanar planes afterwards.
\tparam NamedParameters
a sequence of \ref bgl_namedparameters "Named Parameters"
\cgalNamedParamsBegin
\cgalParamNBegin{maximum_angle}
\cgalParamDescription{}
\cgalParamType{FT}
\cgalParamDefault{25 degrees}
\cgalParamNEnd
\cgalParamNBegin{maximum_offset}
\cgalParamDescription{}
\cgalParamType{FT}
\cgalParamDefault{0.01}
\cgalParamNEnd
\cgalParamNBegin{regularize_parallelism}
\cgalParamDescription{}
\cgalParamType{bool}
\cgalParamDefault{true}
\cgalParamNEnd
\cgalParamNBegin{regularize_orthogonality}
\cgalParamDescription{}
\cgalParamType{bool}
\cgalParamDefault{true}
\cgalParamNEnd
\cgalParamNBegin{regularize_coplanarity}
\cgalParamDescription{}
\cgalParamType{bool}
\cgalParamDefault{true}
\cgalParamNEnd
\cgalNamedParamsEnd
*/
template<typename NamedParameters>
std::size_t regularize_shapes(
const NamedParameters& np);
/*!
\brief Retrieves the detected shapes.
\param indices
will be used to store the indices into the input range for each detected planar shape.
\param planes
will be used to store the plane equation of each detected planar shape.
\pre `successful shape detection`
*/
void detected_shapes(std::vector<std::vector<std::size_t> >& indices, std::vector<Plane_3>& planes);
/*!
\brief initializes the kinetic partitioning.
\param np
a sequence of \ref bgl_namedparameters "Named Parameters"
among the ones listed below
\cgalNamedParamsBegin
\cgalParamNBegin{reorient_bbox}
\cgalParamDescription{Use the oriented bounding box instead of the axis-aligned bounding box.}
\cgalParamType{bool}
\cgalParamDefault{false}
\cgalParamNEnd
\cgalParamNBegin{bbox_extension}
\cgalParamDescription{Factor for extension of the bounding box of the input data to be used for the partitioning.}
\cgalParamType{FT}
\cgalParamDefault{1.1}
\cgalParamNEnd
\cgalParamNBegin{theta}
\cgalParamDescription{The tolerance angle to snap the planes of two input polygons into one plane.}
\cgalParamType{FT}
\cgalParamDefault{5}
\cgalParamNEnd
\cgalParamNBegin{epsilon}
\cgalParamDescription{The tolerance distance to snap the planes of two input polygons into one plane.}
\cgalParamType{FT}
\cgalParamDefault{5}
\cgalParamNEnd
\cgalNamedParamsEnd
\pre `successful shape detection`
*/
template<typename NamedParameters>
bool initialize_partitioning(const NamedParameters& np);
/*!
\brief Propagates the kinetic polygons in the initialized partition.
\param k
maximum number of allowed intersections for each input polygon before its expansion stops.
@return
success of kinetic partitioning.
\pre `successful initialization`
*/
bool partitioning(std::size_t k);
/*!
\brief Access to the kinetic partitioning.
@return
created kinetic partitioning data structure
\pre `successful partitioning`
*/
const Kinetic_partitioning_3<Kernel, Intersection_Kernel>& get_partitioning() const;
/*!
\brief Creates the visibility (data-) and regularity energy terms from the input point cloud and the kinetic partitioning.
@return
success.
\pre `successful initialization`
*/
template<typename NamedParameters>
bool setup_energyterms(const NamedParameters& np);
/*!
\brief Provides the data and regularity energy terms for reconstruction via graph-cut.
\param edges
contains a vector of pairs of volume indices. Indicates which volumes should be connected in the graph cut formulation.
\param edge_costs
contains the cost for each edge specified in `edges` for two labels with different labels. For equal labels, the cost is 0. Needs to be index compatible to the `edges` parameter.
\param cost_matrix
provides the cost of a label for each volume cell. The first index corresponds to the label and the second index corresponds to the volume index.
@return
fails if the dimensions of parameters does not match the kinetic partitioning.
\pre `successful initialization`
*/
template<typename NamedParameters>
bool setup_energyterms(
const std::vector< std::pair<std::size_t, std::size_t> >& edges,
const std::vector<double>& edge_costs,
const std::vector< std::vector<double> >& cost_matrix,
const NamedParameters& np);
/*!
\brief Propagates the kinetic polygons in the initialized partition.
\param lambda
trades the impact of the data term for impact of the regularization term. Should be in the range [0, 1).
@return
success of reconstruction.
\pre `successful initialization`
*/
bool reconstruct(FT lambda);
/*!
\brief Propagates the kinetic polygons in the initialized partition.
\param lambda
trades the impact of the data term for impact of the regularization term. Should be in the range [0, 1).
@return
success of reconstruction.
\pre `successful initialization`
*/
void output_reconstructed_model(Polygon_mesh& polygon_mesh);
}
#else
template<
typename InputRange,
typename PointMap,
@ -1320,6 +1547,8 @@ private:
}
};
#endif //DOXYGEN_RUNNING
} // namespace KSR_3
} // namespace CGAL

View File

@ -26,6 +26,9 @@
namespace CGAL {
namespace KSR_3 {
#ifdef DOXYGEN_RUNNING
#else
template<typename GeomTraits>
class Support_plane {
@ -792,10 +795,7 @@ bool operator==(const Support_plane<Kernel>& a, const Support_plane<Kernel>& b)
// const auto pb = planeb.projection(pa);
// const FT bval = KSR::distance(pa, pb);
// TODO: Should we rotate the planes here before computing the distance?
// TODO: We should put it as a parameter.
// TODO: Can we make it work for a smaller parameter: e.g. 0.1?
const FT ptol = a.distance_tolerance();
const auto pa1 = a.to_3d(a.centroid());
const auto pb1 = planeb.projection(pa1);
@ -818,6 +818,8 @@ bool operator==(const Support_plane<Kernel>& a, const Support_plane<Kernel>& b)
return true;
}
#endif //DOXYGEN_RUNNING
} // namespace KSR_3
} // namespace CGAL

View File

@ -33,6 +33,9 @@
namespace CGAL {
namespace KSR_3 {
#ifdef DOXYGEN_RUNNING
#else
template<
typename GeomTraits,
typename PointMap_3,
@ -270,6 +273,8 @@ namespace KSR_3 {
}
};
#endif //DOXYGEN_RUNNING
} // KSR_3
} // CGAL

View File

@ -17,7 +17,7 @@
// Boost includes.
#include <CGAL/boost/graph/named_params_helper.h>
#include <CGAL/boost/graph/Named_function_parameters.h>
#include <CGAL/Named_function_parameters.h>
// CGAL includes.
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
@ -26,6 +26,10 @@
#include <CGAL/Polygon_mesh_processing/orientation.h>
#include <CGAL/Real_timer.h>
#include <CGAL/Linear_cell_complex_for_combinatorial_map.h>
#include <CGAL/Linear_cell_complex_incremental_builder.h>
#include <CGAL/draw_linear_cell_complex.h>
// Internal includes.
#include <CGAL/KSR/utils.h>
#include <CGAL/KSR/debug.h>
@ -39,11 +43,209 @@
namespace CGAL {
#ifdef DOXYGEN_RUNNING
/*!
\brief Creates the kinetic partitioning of the bounding box.
\tparam Kernel
must be a model of `Kernel`. Is used for non-critical calculations.
\tparam IntersectionKernel
must be a model of `Kernel`. Is used for the creation of the intersection graph. An exact kernel is suggested.
*/
template<Kernel, Intersection_Kernel = CGAL::Exact_predicates_exact_constructions_kernel>
class Kinetic_partitioning_3 {
/*!
\brief Initializes the kinetic partitioning of the bounding box.
\tparam InputRange
must be a model of `ConstRange` whose iterator type is `RandomAccessIterator`.
\tparam PolygonMap
contains index ranges to form polygons from InputRange
\tparam NamedParameters
a sequence of \ref bgl_namedparameters "Named Parameters"
\param input_range
an instance of `InputRange` with 3D points and corresponding 3D normal vectors
\param polygon_map
a range of polygons defined by a range of indices into input_range
\param np
a sequence of \ref bgl_namedparameters "Named Parameters"
among the ones listed below
@return
success
\pre `input_range.size() > 0 and polygon_map.size() > 0`
\cgalNamedParamsBegin
\cgalParamNBegin{reorient_bbox}
\cgalParamDescription{Use the oriented bounding box instead of the axis-aligned bounding box.}
\cgalParamType{bool}
\cgalParamDefault{false}
\cgalParamNEnd
\cgalParamNBegin{bbox_extension}
\cgalParamDescription{Factor for extension of the bounding box of the input data to be used for the partitioning.}
\cgalParamType{FT}
\cgalParamDefault{1.1}
\cgalParamNEnd
\cgalParamNBegin{theta}
\cgalParamDescription{The tolerance angle to snap the planes of two input polygons into one plane.}
\cgalParamType{FT}
\cgalParamDefault{5}
\cgalParamNEnd
\cgalParamNBegin{epsilon}
\cgalParamDescription{The tolerance distance to snap the planes of two input polygons into one plane.}
\cgalParamType{FT}
\cgalParamDefault{5}
\cgalParamNEnd
\cgalNamedParamsEnd
*/
template<
typename InputRange,
typename PolygonMap,
typename NamedParameters>
bool initialization(
const InputRange input_range,
const PolygonMap polygon_map,
const NamedParameters& np);
/*!
\brief Propagates the kinetic polygons in the initialized partition.
\param k
maximum number of allowed intersections for each input polygon before its expansion stops.
@return
success of kinetic partitioning.
\pre `successful initialization`
*/
bool partition(std::size_t k);
/*!
\brief Number of vertices in the kinetic partitioning.
@return
number of vertices.
\pre `successful partitioning`
*/
std::size_t number_of_vertices() const;
/*!
\brief Number of convex faces in the kinetic partitioning.
@return
number of convex faces.
\pre `successful partitioning`
*/
std::size_t number_of_faces() const;
/*!
\brief Number of convex volumes created by the kinetic partitioning.
@return
number of convex volumes.
\pre `successful partitioning`
*/
std::size_t number_of_volumes() const;
/*!
\brief Point vector for mapping vertex indices to positions.
@return
vector of points.
\pre `successful partitioning`
*/
const std::vector<Point_3>& vertices() const;
/*!
\brief Vertex indices of convex face.
\param face_index
index of the query face.
@return
vector of vertex indices.
\pre `successful partitioning`
*/
const std::vector<std::size_t>& vertices(std::size_t face_index) const;
/*!
\brief Face indices of the convex volume.
\param volume_index
index of the query volume.
@return
vector of face indices.
\pre `successful partitioning`
*/
const std::vector<std::size_t>& face(std::size_t volume_index) const;
/*!
\brief Indices of adjacent volumes. Negative indices correspond to the empty spaces behind the sides of the bounding box.
\param face_index
index of the query face.
@return
pair of adjacent volumes.
-1 zmin
-2 ymin
-3 xmax
-4 ymax
-5 xmin
-6 zmax
\pre `successful partitioning`
*/
const std::pair<int, int>& neighbors(std::size_t face_index) const;
/*!
\brief Retrieves the input polygon this face originates from.
\param face_index
index of the query face.
@return
index into polygon_map provided on initialization.
\pre `successful partitioning`
*/
const std::size_t input_polygon(std::size_t face_index) const;
/*!
\brief Creates a linear cell complex from the kinetic partitioning.
\param lcc
an instance of a Linear_cell_complex_for_combinatorial_map<3, 3,...>
The dimension of the combinatorial map and the dimension of the ambient space have to be 3.
\pre `successful partitioning`
*/
template<typename LCC>
void get_linear_cell_complex(LCC& lcc) const
}
#else
template<typename GeomTraits>
class Kinetic_shape_reconstruction_3 {
public:
using Kernel = GeomTraits;
using LCC = Linear_cell_complex_for_combinatorial_map<3, 3>;
private:
using FT = typename Kernel::FT;
@ -410,6 +612,64 @@ public:
return support_plane_idx;
}
template<typename LCC>
void get_linear_cell_complex(LCC &lcc) const {
lcc.clear();
From_EK from_EK;
std::vector<bool> used_vertices(m_data.igraph().number_of_vertices(), false);
std::vector<int> remap(m_data.igraph().number_of_vertices(), -1);
std::vector<Point_3> mapped_vertices;
mapped_vertices.reserve(m_data.igraph().number_of_vertices());
for (const auto& volume : m_data.volumes()) {
for (const auto& vertex : volume.pvertices) {
CGAL_assertion(m_data.has_ivertex(vertex));
IVertex ivertex = m_data.ivertex(vertex);
if (remap[ivertex] == -1) {
remap[ivertex] = static_cast<int>(mapped_vertices.size());
mapped_vertices.push_back(from_EK(m_data.point_3(ivertex)));
}
}
}
CGAL::Linear_cell_complex_incremental_builder_3<LCC> ib(lcc);
for (const auto& p : mapped_vertices)
ib.add_vertex(p);
for (const auto& vol : m_data.volumes()) {
ib.begin_surface();
for (std::size_t i = 0; i < vol.pfaces.size(); i++) {
auto vertex_range = m_data.pvertices_of_pface(vol.pfaces[i]);
ib.begin_facet();
if (vol.pface_oriented_outwards[i]) {
typename Data_structure::PVertex_of_pface_iterator it = vertex_range.begin();
while (it != vertex_range.end()) {
CGAL_assertion(m_data.has_ivertex(*it));
IVertex ivertex = m_data.ivertex(*it);
ib.add_vertex_to_facet(static_cast<std::size_t>(remap[ivertex]));
it++;
}
}
else {
typename Data_structure::PVertex_of_pface_iterator it = vertex_range.end()--;
do {
CGAL_assertion(m_data.has_ivertex(*it));
IVertex ivertex = m_data.ivertex(*it);
ib.add_vertex_to_facet(static_cast<std::size_t>(remap[ivertex]));
if (it == vertex_range.begin())
break;
it--;
} while (true);
}
ib.end_facet();
}
ib.end_surface();
}
lcc.display_characteristics(std::cout) << std::endl;
}
/*******************************
** OUTPUT **
********************************/
@ -417,7 +677,6 @@ public:
template<typename VertexOutputIterator>
VertexOutputIterator output_partition_vertices(
VertexOutputIterator vertices, const int support_plane_idx = -1) const {
From_EK from_EK;
CGAL_assertion(support_plane_idx < number_of_support_planes());
@ -444,7 +703,6 @@ public:
template<typename EdgeOutputIterator>
EdgeOutputIterator output_partition_edges(
EdgeOutputIterator edges, const int support_plane_idx = -1) const {
From_EK from_EK;
CGAL_assertion(support_plane_idx < number_of_support_planes());
@ -500,6 +758,7 @@ public:
void output_support_plane(
Polygon_mesh& polygon_mesh, const int support_plane_idx) const {
From_EK from_EK;
polygon_mesh.clear();
CGAL_assertion(support_plane_idx >= 0);
@ -520,7 +779,7 @@ public:
if (map_vertices.size() <= pvertex.second)
map_vertices.resize(pvertex.second + 1);
map_vertices[pvertex.second] =
polygon_mesh.add_vertex(m_data.point_3(ivertex));
polygon_mesh.add_vertex(from_EK(m_data.point_3(ivertex)));
}
const auto all_pfaces = m_data.pfaces(sp_idx);
@ -597,15 +856,9 @@ public:
}
}
template<typename LCC>
void output_partition(LCC& /* lcc */) const {
CGAL_assertion_msg(false, "TODO: OUTPUT PARTITION LCC!");
}
template<typename VertexOutputIterator, typename FaceOutputIterator>
void output_reconstructed_model(
VertexOutputIterator vertices, FaceOutputIterator faces) const {
From_EK from_EK;
const auto& model = m_data.reconstructed_model();
@ -680,6 +933,8 @@ private:
}
};
#endif //DOXYGEN_RUNNING
} // namespace CGAL
#endif // CGAL_KINETIC_SHAPE_RECONSTRUCTION_3_H

View File

@ -114,6 +114,7 @@ bool run_test(
std::cout << num_faces << ",";
std::cout << num_volumes << std::endl;
/*
assert(num_support_planes > 6);
if (num_support_planes <= 6) return false;
@ -132,7 +133,10 @@ bool run_test(
if (num_vertices != results[2]) return false;
if (num_edges != results[3]) return false;
if (num_faces < results[4]) return false;
if (num_volumes < results[5]) return false;
if (num_volumes < results[5]) return false;*/
CGAL::Linear_cell_complex_for_combinatorial_map<3, 3> lcc;
ksr.get_linear_cell_complex(lcc);
std::vector<Point_3> output_vertices;
ksr.output_partition_vertices(

View File

@ -69,6 +69,19 @@ public:
return graph.maxflow();
}
template <typename VertexLabelMap, typename VertexIndexMap, typename InputVertexDescriptorRange>
void get_labels(VertexLabelMap vertex_label_map, VertexIndexMap vertex_index_map,
const std::vector<Vertex_descriptor>& inserted_vertices,
InputVertexDescriptorRange& input_range) {
CGAL_assertion(inserted_vertices.size() == input_range.size());
for (auto vd : input_range) {
std::size_t index = get(vertex_index_map, vd);
int label = graph.what_segment(inserted_vertices[index]); // Source = 0, Sink = 1
put(vertex_label_map, vd, label);
}
}
template <typename VertexLabelMap, typename InputVertexDescriptor>
void update(VertexLabelMap vertex_label_map,
const std::vector<Vertex_descriptor>& inserted_vertices,