mirror of https://github.com/CGAL/cgal
parent
4b87b331e7
commit
ddb155fb94
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in New Issue