Skip to content

Commit

Permalink
Kinetic Shape Partition (#7198)
Browse files Browse the repository at this point in the history
PR for Kinetic Partitioning and Reconstruction feature.

* Affected package(s): Kinetic Partitioning and Reconstruction
* Issue(s) solved (if any): 
* Feature/Small Feature (if any):
[link](https://cgal.geometryfactory.com/CGAL/Members/wiki/Features/Kinetic_Shape_Partition_3)
* Link to compiled documentation:
[link](https://cgal.github.io/7198/v0/Manual/packages.html#PkgKineticSpacePartition)
* License and copyright ownership:  GeometryFactory/Inria

**TODO:**
- [x] check branch size (for @sloriot)
  • Loading branch information
sloriot authored May 26, 2024
2 parents 132b932 + 279ddde commit 596fa09
Show file tree
Hide file tree
Showing 117 changed files with 14,085 additions and 8 deletions.
174 changes: 167 additions & 7 deletions BGL/include/CGAL/boost/graph/alpha_expansion_graphcut.h
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,7 @@ double alpha_expansion_graphcut (const InputGraph& input_graph,
std::size_t number_of_labels = get(vertex_label_cost_map, *(vertices(input_graph).first)).size();

bool success;
bool full_loop = false;
do {
success = false;

Expand Down Expand Up @@ -644,6 +645,8 @@ double alpha_expansion_graphcut (const InputGraph& input_graph,
#ifdef CGAL_SEGMENTATION_BENCH_GRAPHCUT
cut_time += timer.time();
#endif
if (full_loop && flow >= min_cut)
continue;

if(min_cut - flow <= flow * tolerance) {
continue;
Expand All @@ -656,18 +659,158 @@ double alpha_expansion_graphcut (const InputGraph& input_graph,
std::size_t vertex_i = get (vertex_index_map, vd);
alpha_expansion.update(vertex_label_map, inserted_vertices, vd, vertex_i, alpha);
}
}
full_loop = true;
} while (success);

#ifdef CGAL_SEGMENTATION_BENCH_GRAPHCUT
CGAL_TRACE_STREAM << "vertex creation time: " << vertex_creation_time <<
std::endl;
CGAL_TRACE_STREAM << "edge creation time: " << edge_creation_time << std::endl;
CGAL_TRACE_STREAM << "max flow algorithm time: " << cut_time << std::endl;
#endif

return min_cut;
}


template <typename InputGraph,
typename EdgeCostMap,
typename VertexLabelCostMap,
typename VertexLabelMap,
typename NamedParameters>
double min_cut(const InputGraph& input_graph,
EdgeCostMap edge_cost_map,
VertexLabelCostMap vertex_label_cost_map,
VertexLabelMap vertex_label_map,
const NamedParameters& np)
{
using parameters::choose_parameter;
using parameters::get_parameter;

typedef boost::graph_traits<InputGraph> GT;
typedef typename GT::edge_descriptor input_edge_descriptor;
typedef typename GT::vertex_descriptor input_vertex_descriptor;

typedef typename GetInitializedVertexIndexMap<InputGraph, NamedParameters>::type VertexIndexMap;
VertexIndexMap vertex_index_map = CGAL::get_initialized_vertex_index_map(input_graph, np);

typedef typename GetImplementationTag<NamedParameters>::type Impl_tag;

// select implementation
typedef typename std::conditional
<std::is_same<Impl_tag, Alpha_expansion_boost_adjacency_list_tag>::value,
Alpha_expansion_boost_adjacency_list_impl,
typename std::conditional
<std::is_same<Impl_tag, Alpha_expansion_boost_compressed_sparse_row_tag>::value,
Alpha_expansion_boost_compressed_sparse_row_impl,
Alpha_expansion_MaxFlow_impl>::type>::type
Alpha_expansion;

typedef typename Alpha_expansion::Vertex_descriptor Vertex_descriptor;

Alpha_expansion graph;

double min_cut = (std::numeric_limits<double>::max)();

#ifdef CGAL_SEGMENTATION_BENCH_GRAPHCUT
double vertex_creation_time, edge_creation_time, cut_time;
vertex_creation_time = edge_creation_time = cut_time = 0.0;
#endif

std::vector<Vertex_descriptor> inserted_vertices;
inserted_vertices.resize(num_vertices(input_graph));

graph.clear_graph();

#ifdef CGAL_SEGMENTATION_BENCH_GRAPHCUT
Timer timer;
timer.start();
#endif

// For E-Data
// add every input vertex as a vertex to the graph, put edges to source & sink vertices
for (input_vertex_descriptor vd : CGAL::make_range(vertices(input_graph)))
{
std::size_t vertex_i = get(vertex_index_map, vd);
Vertex_descriptor new_vertex = graph.add_vertex();
inserted_vertices[vertex_i] = new_vertex;

double source_weight = get(vertex_label_cost_map, vd)[0];
double sink_weight = get(vertex_label_cost_map, vd)[0];

graph.add_tweight(new_vertex, source_weight, sink_weight);
}
#ifdef CGAL_SEGMENTATION_BENCH_GRAPHCUT
vertex_creation_time += timer.time();
timer.reset();
#endif

// For E-Smooth
// add edge between every vertex,
for (input_edge_descriptor ed : CGAL::make_range(edges(input_graph)))
{
input_vertex_descriptor vd1 = source(ed, input_graph);
input_vertex_descriptor vd2 = target(ed, input_graph);
std::size_t idx1 = get(vertex_index_map, vd1);
std::size_t idx2 = get(vertex_index_map, vd2);

double weight = get(edge_cost_map, ed);

Vertex_descriptor v1 = inserted_vertices[idx1],
v2 = inserted_vertices[idx2];

graph.add_edge(v1, v2, weight, weight);
}
} while(success);

#ifdef CGAL_SEGMENTATION_BENCH_GRAPHCUT
CGAL_TRACE_STREAM << "vertex creation time: " << vertex_creation_time <<
std::endl;
CGAL_TRACE_STREAM << "edge creation time: " << edge_creation_time << std::endl;
CGAL_TRACE_STREAM << "max flow algorithm time: " << cut_time << std::endl;
edge_creation_time += timer.time();
#endif

return min_cut;
}
graph.init_vertices();

#ifdef CGAL_SEGMENTATION_BENCH_GRAPHCUT
timer.reset();
#endif

min_cut = graph.max_flow();

#ifdef CGAL_SEGMENTATION_BENCH_GRAPHCUT
cut_time += timer.time();
#endif

/*
//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);
graph.update(vertex_label_map, inserted_vertices, vd, vertex_i, alpha);
}*/

#ifdef CGAL_SEGMENTATION_BENCH_GRAPHCUT
CGAL_TRACE_STREAM << "vertex creation time: " << vertex_creation_time <<
std::endl;
CGAL_TRACE_STREAM << "edge creation time: " << edge_creation_time << std::endl;
CGAL_TRACE_STREAM << "max flow algorithm time: " << cut_time << std::endl;
#endif

return min_cut;
}

/// \cond SKIP_IN_MANUAL

Expand Down Expand Up @@ -701,6 +844,23 @@ double alpha_expansion_graphcut (const std::vector<std::pair<std::size_t, std::s
CGAL::parameters::vertex_index_map (graph.vertex_index_map()).
implementation_tag (AlphaExpansionImplementationTag()));
}

template <typename AlphaExpansionImplementationTag>
double min_cut(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,
std::vector<std::size_t>& labels,
const AlphaExpansionImplementationTag&)
{
internal::Alpha_expansion_old_API_wrapper_graph graph(edges, edge_costs, cost_matrix, labels);

return min_cut(graph,
graph.edge_cost_map(),
graph.vertex_label_cost_map(),
graph.vertex_label_map(),
CGAL::parameters::vertex_index_map(graph.vertex_index_map()).
implementation_tag(AlphaExpansionImplementationTag()));
}
/// \endcond

}//namespace CGAL
Expand Down
12 changes: 12 additions & 0 deletions Documentation/doc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,18 @@ endif()
find_package(Doxygen REQUIRED)
find_package(Python3 REQUIRED COMPONENTS Interpreter)

if (NOT Python3_EXECUTABLE)
message(FATAL_ERROR "Cannot build the documentation without Python3!")
return()
endif()

message(STATUS ${Python3_EXECUTABLE})

if(NOT DOXYGEN_FOUND)
message(WARNING "Cannot build the documentation without Doxygen!")
return()
endif()

#starting from cmake 3.9 the usage of DOXYGEN_EXECUTABLE is deprecated
if(TARGET Doxygen::doxygen)
get_property(
Expand Down
1 change: 1 addition & 0 deletions Documentation/doc/Documentation/packages.txt
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@
\package_listing{Scale_space_reconstruction_3}
\package_listing{Advancing_front_surface_reconstruction}
\package_listing{Polygonal_surface_reconstruction}
\package_listing{Kinetic_space_partition}
\package_listing{Optimal_transportation_reconstruction_2}

\cgalPackageSection{PartGeometryProcessing,Geometry Processing}
Expand Down
19 changes: 19 additions & 0 deletions Documentation/doc/biblio/geom.bib
Original file line number Diff line number Diff line change
Expand Up @@ -151974,6 +151974,25 @@ @inproceedings{schnabel2007efficient
organization={Wiley Online Library}
}

@article{bauchet2020kinetic,
author = {Bauchet, Jean-Philippe and Lafarge, Florent},
title = {Kinetic Shape Reconstruction},
journal = "ACM Transactions on Graphics",
year = {2020},
issue_date = {October 2020},
publisher = {Association for Computing Machinery},
address = {New York, NY, USA},
volume = {39},
number = {5},
issn = {0730-0301},
url = {https://doi.org/10.1145/3376918},
doi = {10.1145/3376918},
month = {jun},
articleno = {156},
numpages = {14},
keywords = {polygonal surface mesh, Surface reconstruction, kinetic framework, surface approximation}
}

@article{levismooth,
title={Smooth Rotation Enhanced As-Rigid-As-Possible Mesh Animation},
author={Levi, Zohar and Gotsman, Craig},
Expand Down
54 changes: 54 additions & 0 deletions Installation/include/CGAL/license/Kinetic_space_partition.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright (c) 2016 GeometryFactory SARL (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org)
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s) : Andreas Fabri
//
// Warning: this file is generated, see include/CGAL/license/README.md

#ifndef CGAL_LICENSE_KINETIC_SPACE_PARTITION_H
#define CGAL_LICENSE_KINETIC_SPACE_PARTITION_H

#include <CGAL/config.h>
#include <CGAL/license.h>

#ifdef CGAL_KINETIC_SPACE_PARTITION_COMMERCIAL_LICENSE

# if CGAL_KINETIC_SPACE_PARTITION_COMMERCIAL_LICENSE < CGAL_RELEASE_DATE

# if defined(CGAL_LICENSE_WARNING)

CGAL_pragma_warning("Your commercial license for CGAL does not cover "
"this release of the Kinetic Space Partition package.")
# endif

# ifdef CGAL_LICENSE_ERROR
# error "Your commercial license for CGAL does not cover this release \
of the Kinetic Space Partition package. \
You get this error, as you defined CGAL_LICENSE_ERROR."
# endif // CGAL_LICENSE_ERROR
# endif // CGAL_KINETIC_SPACE_PARTITION_COMMERCIAL_LICENSE < CGAL_RELEASE_DATE
#else // no CGAL_KINETIC_SPACE_PARTITION_COMMERCIAL_LICENSE
# if defined(CGAL_LICENSE_WARNING)
CGAL_pragma_warning("\nThe macro CGAL_KINETIC_SPACE_PARTITION_COMMERCIAL_LICENSE is not defined."
"\nYou use the CGAL Kinetic Space Partition package under "
"the terms of the GPLv3+.")
# endif // CGAL_LICENSE_WARNING
# ifdef CGAL_LICENSE_ERROR
# error "The macro CGAL_KINETIC_SPACE_PARTITION_COMMERCIAL_LICENSE is not defined.\
You use the CGAL Kinetic Space Partition package under the terms of \
the GPLv3+. You get this error, as you defined CGAL_LICENSE_ERROR."
# endif // CGAL_LICENSE_ERROR
#endif // no CGAL_KINETIC_SPACE_PARTITION_COMMERCIAL_LICENSE
#endif // CGAL_LICENSE_KINETIC_SPACE_PARTITION_H
1 change: 1 addition & 0 deletions Installation/include/CGAL/license/gpl_package_list.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Inscribed_areas Inscribed Areas
Interpolation 2D and Surface Function Interpolation
Interval_skip_list Interval Skip List
Jet_fitting_3 Estimation of Local Differential Properties of Point-Sampled Surfaces
Kinetic_space_partition Kinetic Space Partition
Matrix_search Monotone and Sorted Matrix Search
Mesh_2 2D Conforming Triangulations and Meshes
Mesh_3 3D Mesh Generation
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright (c) 2023 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) : Sven Oesau, Florent Lafarge, Dmitry Anisimov, Simon Giraudot

/*!
\ingroup PkgKineticSpacePartitionConcepts
\cgalConcept
The concept `KineticLCCFaceAttribute` refines `CellAttribute` to store additional information for each face related to its associated input polygon.
\cgalHasModelsBegin
\cgalHasModelsBare{\link CGAL::Cell_attribute `Cell_attribute<LCC, CGAL::Kinetic_space_partition_3::Linear_cell_complex_min_items::Face_attribute>`\endlink}
\cgalHasModelsEnd
\sa `CGAL::Kinetic_space_partition_3`
\sa `LinearCellComplexItems`
*/

struct KineticLCCFaceAttribute {
/// \name Access Members
/// @{
/// 3D plane type compatible with `Kinetic_space_partition_3::Intersection_kernel`
typedef unspecified_type Plane_3;
/// Stores the index of the input polygon the provided that support plane of this face. Negative numbers correspond to the values defined in the enum `Kinetic_space_partition_3::Face_support`.
int input_polygon_index;
/// Support plane of the face derived from the corresponding input polygon or from octree nodes used for subdivision.
Plane_3 plane;
/// Does this face overlap with the corresponding input polygon.
bool part_of_initial_polygon;
/// @}
};
Loading

0 comments on commit 596fa09

Please sign in to comment.