mirror of https://github.com/CGAL/cgal
Merge remote-tracking branch 'origin/Kinetic_shape_reconstruction-new_package-soesau' into Kinetic_surface_reconstruction-new_package-soesau
originally: Author: Sven Oesau <sven.oesau@geometryfactory.com> Date: Thu Jan 11 16:13:43 2024 +0100
This commit is contained in:
commit
393c73a039
|
|
@ -85,18 +85,18 @@ Impact of parameters on the reconstruction of the rotated lans model.\n From lef
|
||||||
\subsection ksrBasicExample Basic Example
|
\subsection ksrBasicExample Basic Example
|
||||||
This minimal example shows the import of a simple synthetic point cloud and an reconstruction using mostly default parameters.
|
This minimal example shows the import of a simple synthetic point cloud and an reconstruction using mostly default parameters.
|
||||||
|
|
||||||
\cgalExample{Kinetic_surface_reconstruction/ksr_basic.cpp}
|
\cgalExample{Kinetic_surface_reconstruction/basic.cpp}
|
||||||
|
|
||||||
\subsection ksrBuildingExample Building Example
|
\subsection ksrBuildingExample Building Example
|
||||||
This example shows the import of an acquired point cloud of a building and a reconstruction using a common choice of parameters for building reconstruction. The input point cloud is reoriented to be axis-aligned and regularization is used to simplify the detected shapes before reconstruction.
|
This example shows the import of an acquired point cloud of a building and a reconstruction using a common choice of parameters for building reconstruction. The input point cloud is reoriented to be axis-aligned and regularization is used to simplify the detected shapes before reconstruction.
|
||||||
The actual reconstruction method is actually fast. To avoid running the full shape detection and kinetic partition just to try different values for beta, several reconstructions are performed and exported into ply format.
|
The actual reconstruction method is actually fast. To avoid running the full shape detection and kinetic partition just to try different values for beta, several reconstructions are performed and exported into ply format.
|
||||||
|
|
||||||
\cgalExample{Kinetic_surface_reconstruction/ksr_building.cpp}
|
\cgalExample{Kinetic_surface_reconstruction/building.cpp}
|
||||||
|
|
||||||
\subsection ksrParametersExample Parameters Example
|
\subsection ksrParametersExample Parameters Example
|
||||||
This example provides a command line version of the kinetic surface reconstruction allowing to configure the input point cloud filename and most parameters.
|
This example provides a command line version of the kinetic surface reconstruction allowing to configure the input point cloud filename and most parameters.
|
||||||
|
|
||||||
\cgalExample{Kinetic_surface_reconstruction/ksr_parameters.cpp}
|
\cgalExample{Kinetic_surface_reconstruction/parameters.cpp}
|
||||||
|
|
||||||
\section ksrPerformance Performance
|
\section ksrPerformance Performance
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*!
|
/*!
|
||||||
\example Kinetic_surface_reconstruction/ksr_basic.cpp
|
\example Kinetic_surface_reconstruction/basic.cpp
|
||||||
\example Kinetic_surface_reconstruction/ksr_building.cpp
|
\example Kinetic_surface_reconstruction/building.cpp
|
||||||
\example Kinetic_surface_reconstruction/ksr_parameters.cpp
|
\example Kinetic_surface_reconstruction/parameters.cpp
|
||||||
*/
|
*/
|
||||||
|
|
@ -13,7 +13,7 @@ if(Eigen3_FOUND)
|
||||||
message(STATUS "Found Eigen")
|
message(STATUS "Found Eigen")
|
||||||
include(CGAL_Eigen_support)
|
include(CGAL_Eigen_support)
|
||||||
|
|
||||||
set(targets ksr_basic ksr_building ksr_parameters)
|
set(targets basic building parameters)
|
||||||
|
|
||||||
foreach(target ${targets})
|
foreach(target ${targets})
|
||||||
create_single_source_cgal_program("${target}.cpp")
|
create_single_source_cgal_program("${target}.cpp")
|
||||||
|
|
|
||||||
|
|
@ -135,7 +135,7 @@ int main(const int argc, const char** argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parameters.min_region_size == 0)
|
if (parameters.min_region_size == 0)
|
||||||
parameters.min_region_size = static_cast<std::atomic_size_t>(point_set.size() * 0.01);
|
parameters.min_region_size = point_set.size() * 0.01;
|
||||||
|
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
std::cout << "--- INPUT STATS: " << std::endl;
|
std::cout << "--- INPUT STATS: " << std::endl;
|
||||||
|
|
@ -115,8 +115,8 @@ namespace KSR_3 {
|
||||||
std::size_t sum_outside = 0;
|
std::size_t sum_outside = 0;
|
||||||
|
|
||||||
for (std::size_t i = 6; i < cost_matrix[0].size(); i++) {
|
for (std::size_t i = 6; i < cost_matrix[0].size(); i++) {
|
||||||
sum_inside += static_cast<std::size_t>(cost_matrix[0][i]);
|
sum_inside += cost_matrix[0][i];
|
||||||
sum_outside += static_cast<std::size_t>(cost_matrix[1][i]);
|
sum_outside += cost_matrix[1][i];
|
||||||
min = (std::min<double>)(cost_matrix[0][i], min);
|
min = (std::min<double>)(cost_matrix[0][i], min);
|
||||||
min = (std::min<double>)(cost_matrix[1][i], min);
|
min = (std::min<double>)(cost_matrix[1][i], min);
|
||||||
max = (std::max<double>)(cost_matrix[0][i], max);
|
max = (std::max<double>)(cost_matrix[0][i], max);
|
||||||
|
|
|
||||||
|
|
@ -673,7 +673,7 @@ private:
|
||||||
write_face(m_lcc.dart_descriptor(*it), "face_wo_volume.ply");
|
write_face(m_lcc.dart_descriptor(*it), "face_wo_volume.ply");
|
||||||
}
|
}
|
||||||
|
|
||||||
int first = static_cast<int>(m_lcc.template info<3>(m_lcc.dart_descriptor(*it)).volume_id);
|
int first = m_lcc.template info<3>(m_lcc.dart_descriptor(*it)).volume_id;
|
||||||
auto& inf1 = m_lcc.template info<3>(m_lcc.dart_descriptor(*it++));
|
auto& inf1 = m_lcc.template info<3>(m_lcc.dart_descriptor(*it++));
|
||||||
|
|
||||||
auto inf2 = inf1;
|
auto inf2 = inf1;
|
||||||
|
|
@ -682,7 +682,7 @@ private:
|
||||||
|
|
||||||
int second;
|
int second;
|
||||||
if (n.size() == 2 && it != n.end())
|
if (n.size() == 2 && it != n.end())
|
||||||
second = static_cast<int>(m_lcc.template info<3>(m_lcc.dart_descriptor(*it)).volume_id);
|
second = m_lcc.template info<3>(m_lcc.dart_descriptor(*it)).volume_id;
|
||||||
|
|
||||||
if (n.size() == 2 && it != n.end())
|
if (n.size() == 2 && it != n.end())
|
||||||
m_face_neighbors_lcc[i] = std::make_pair(first + 6, m_lcc.template info<3>(m_lcc.dart_descriptor(*it)).volume_id + 6);
|
m_face_neighbors_lcc[i] = std::make_pair(first + 6, m_lcc.template info<3>(m_lcc.dart_descriptor(*it)).volume_id + 6);
|
||||||
|
|
@ -710,8 +710,8 @@ private:
|
||||||
|
|
||||||
std::size_t max_inside = 0, max_outside = 0;
|
std::size_t max_inside = 0, max_outside = 0;
|
||||||
for (std::size_t i = 0; i < m_volumes.size(); i++) {
|
for (std::size_t i = 0; i < m_volumes.size(); i++) {
|
||||||
max_inside = (std::max<std::size_t>)(static_cast<std::size_t>(m_cost_matrix[0][i + 6]), max_inside);
|
max_inside = (std::max<double>)(m_cost_matrix[0][i + 6], max_inside);
|
||||||
max_outside = (std::max<std::size_t>)(static_cast<std::size_t>(m_cost_matrix[1][i + 6]), max_outside);
|
max_outside = (std::max<double>)(m_cost_matrix[1][i + 6], max_outside);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dump volumes colored by votes
|
// Dump volumes colored by votes
|
||||||
|
|
@ -1123,7 +1123,7 @@ private:
|
||||||
|
|
||||||
//write_face(cur_fdh, std::to_string(region) + "-inside-" + std::to_string(cur_fa) + ".ply");
|
//write_face(cur_fdh, std::to_string(region) + "-inside-" + std::to_string(cur_fa) + ".ply");
|
||||||
|
|
||||||
region_index[cur_fa] = static_cast<int>(region);
|
region_index[cur_fa] = region;
|
||||||
|
|
||||||
Dart_descriptor n = cur_fdh;
|
Dart_descriptor n = cur_fdh;
|
||||||
std::vector<Point_3> f;
|
std::vector<Point_3> f;
|
||||||
|
|
@ -1311,16 +1311,16 @@ private:
|
||||||
|
|
||||||
std::size_t num_vertices = 0;
|
std::size_t num_vertices = 0;
|
||||||
|
|
||||||
for (int i = 0; i < polygons.size(); i++) {
|
for (std::size_t i = 0; i < polygons.size(); i++) {
|
||||||
num_vertices += polygons[i].size();
|
num_vertices += polygons[i].size();
|
||||||
for (int j = 0; j < polygons[i].size(); j++) {
|
for (std::size_t j = 0; j < polygons[i].size(); j++) {
|
||||||
vertices.push_back(cdt.insert(pl.to_2d(m_lcc.point(m_lcc.template dart_of_attribute<0>(polygons[i][j])))));
|
vertices.push_back(cdt.insert(pl.to_2d(m_lcc.point(m_lcc.dart_of_attribute<0>(polygons[i][j])))));
|
||||||
auto it = va2vh.insert(std::make_pair(polygons[i][j], vertices.size() - 1));
|
auto it = va2vh.insert(std::make_pair(polygons[i][j], vertices.size() - 1));
|
||||||
CGAL_assertion(it.second);
|
CGAL_assertion(it.second);
|
||||||
|
|
||||||
vertices.back()->info().i = i;
|
vertices.back()->info().i = i;
|
||||||
vertices.back()->info().j = j;
|
vertices.back()->info().j = j;
|
||||||
vertices.back()->info().p = pl.to_2d(m_lcc.point(m_lcc.template dart_of_attribute<0>(polygons[i][j])));
|
vertices.back()->info().p = pl.to_2d(m_lcc.point(m_lcc.dart_of_attribute<0>(polygons[i][j])));
|
||||||
vertices.back()->info().dh = polygons[i][j];
|
vertices.back()->info().dh = polygons[i][j];
|
||||||
|
|
||||||
if (j >= 1)
|
if (j >= 1)
|
||||||
|
|
@ -1417,6 +1417,8 @@ private:
|
||||||
Face_attribute& fa = m_lcc.attribute<2>(dh);
|
Face_attribute& fa = m_lcc.attribute<2>(dh);
|
||||||
auto& finfo = m_lcc.info_of_attribute<2>(fa);
|
auto& finfo = m_lcc.info_of_attribute<2>(fa);
|
||||||
|
|
||||||
|
From_exact from_exact;
|
||||||
|
|
||||||
typename LCC::Dart_descriptor dh2 = m_lcc.beta<2>(dh);
|
typename LCC::Dart_descriptor dh2 = m_lcc.beta<2>(dh);
|
||||||
|
|
||||||
std::size_t idx = 1;
|
std::size_t idx = 1;
|
||||||
|
|
@ -1446,6 +1448,8 @@ private:
|
||||||
void collect_border(typename LCC::Dart_descriptor dh, std::vector<bool>& processed, std::vector<std::vector<std::size_t> >& borders) {
|
void collect_border(typename LCC::Dart_descriptor dh, std::vector<bool>& processed, std::vector<std::vector<std::size_t> >& borders) {
|
||||||
processed[dh] = true;
|
processed[dh] = true;
|
||||||
|
|
||||||
|
From_exact from_exact;
|
||||||
|
|
||||||
if (!m_labels[m_lcc.info<3>(dh).volume_id + 6] == 1)
|
if (!m_labels[m_lcc.info<3>(dh).volume_id + 6] == 1)
|
||||||
std::cout << "collect_border called on dart of outside volume, dh " << dh << " volume_id " << m_lcc.info<3>(dh).volume_id << std::endl;
|
std::cout << "collect_border called on dart of outside volume, dh " << dh << " volume_id " << m_lcc.info<3>(dh).volume_id << std::endl;
|
||||||
|
|
||||||
|
|
@ -1515,6 +1519,7 @@ private:
|
||||||
//borders contains Attribute<0> handles casted to std::size_t
|
//borders contains Attribute<0> handles casted to std::size_t
|
||||||
std::vector<bool> processed(m_lcc.number_of_darts(), false);
|
std::vector<bool> processed(m_lcc.number_of_darts(), false);
|
||||||
|
|
||||||
|
From_exact from_exact;
|
||||||
borders_per_region.resize(region_index.size());
|
borders_per_region.resize(region_index.size());
|
||||||
|
|
||||||
for (std::size_t i = 0;i<region_index.size();i++) {
|
for (std::size_t i = 0;i<region_index.size();i++) {
|
||||||
|
|
@ -1871,7 +1876,7 @@ private:
|
||||||
FT bbox_max[] = { -(std::numeric_limits<FT>::max)(), -(std::numeric_limits<FT>::max)(), -(std::numeric_limits<FT>::max)() };
|
FT bbox_max[] = { -(std::numeric_limits<FT>::max)(), -(std::numeric_limits<FT>::max)(), -(std::numeric_limits<FT>::max)() };
|
||||||
for (const auto& p : m_points) {
|
for (const auto& p : m_points) {
|
||||||
const auto& point = get(m_point_map, p);
|
const auto& point = get(m_point_map, p);
|
||||||
for (int i = 0; i < 3; i++) {
|
for (std::size_t i = 0; i < 3; i++) {
|
||||||
bbox_min[i] = (std::min)(point[i], bbox_min[i]);
|
bbox_min[i] = (std::min)(point[i], bbox_min[i]);
|
||||||
bbox_max[i] = (std::max)(point[i], bbox_max[i]);
|
bbox_max[i] = (std::max)(point[i], bbox_max[i]);
|
||||||
}
|
}
|
||||||
|
|
@ -2078,7 +2083,7 @@ private:
|
||||||
// 3 ymax
|
// 3 ymax
|
||||||
// 4 xmin
|
// 4 xmin
|
||||||
// 5 zmax
|
// 5 zmax
|
||||||
const double force = static_cast<double>(m_total_inliers * 3);
|
const std::size_t force = m_total_inliers * 3;
|
||||||
// 0 - cost for labelled as outside
|
// 0 - cost for labelled as outside
|
||||||
cost_matrix[0][0] = 0;
|
cost_matrix[0][0] = 0;
|
||||||
cost_matrix[0][1] = 0;
|
cost_matrix[0][1] = 0;
|
||||||
|
|
@ -2094,7 +2099,7 @@ private:
|
||||||
cost_matrix[1][4] = 0;
|
cost_matrix[1][4] = 0;
|
||||||
cost_matrix[1][5] = 0;
|
cost_matrix[1][5] = 0;
|
||||||
|
|
||||||
if (m_ground_polygon_index != static_cast<std::size_t>(-1) && ground) {
|
if (m_ground_polygon_index != -1 && ground) {
|
||||||
if (m_verbose)
|
if (m_verbose)
|
||||||
std::cout << "using estimated ground plane for reconstruction" << std::endl;
|
std::cout << "using estimated ground plane for reconstruction" << std::endl;
|
||||||
cost_matrix[0][0] = force;
|
cost_matrix[0][0] = force;
|
||||||
|
|
|
||||||
|
|
@ -73,8 +73,8 @@ struct Orthtree_traits_polygons : public Orthtree_traits_3_base<GeomTraits>
|
||||||
|
|
||||||
for (const std::pair<std::size_t, Node_data_element> &p : m_polygons) {
|
for (const std::pair<std::size_t, Node_data_element> &p : m_polygons) {
|
||||||
const Node_data_element& poly = p.second;
|
const Node_data_element& poly = p.second;
|
||||||
for (int i = 0; i < poly.size(); i++)
|
for (std::size_t i = 0; i < poly.size(); i++)
|
||||||
for (int d = 0; d < Dimension::value; d++) {
|
for (std::size_t d = 0; d < Dimension::value; d++) {
|
||||||
bbox_min[d] = (std::min)(bbox_min[d], poly[i][d]);
|
bbox_min[d] = (std::min)(bbox_min[d], poly[i][d]);
|
||||||
bbox_max[d] = (std::max)(bbox_max[d], poly[i][d]);
|
bbox_max[d] = (std::max)(bbox_max[d], poly[i][d]);
|
||||||
}
|
}
|
||||||
|
|
@ -106,13 +106,13 @@ struct Orthtree_traits_polygons : public Orthtree_traits_3_base<GeomTraits>
|
||||||
Node_data_element lower, upper;
|
Node_data_element lower, upper;
|
||||||
const Node_data_element& poly = p.second;
|
const Node_data_element& poly = p.second;
|
||||||
|
|
||||||
FT last = poly.back()[static_cast<int>(dimension)];
|
FT last = poly.back()[dimension];
|
||||||
bool last_lower = (last <= mid);
|
bool last_lower = (last <= mid);
|
||||||
bool last_upper = (mid <= last);
|
bool last_upper = (mid <= last);
|
||||||
std::size_t last_index = poly.size() - 1;
|
std::size_t last_index = poly.size() - 1;
|
||||||
|
|
||||||
for (std::size_t i = 0; i < poly.size(); i++) {
|
for (std::size_t i = 0; i < poly.size(); i++) {
|
||||||
FT d = poly[i][static_cast<int>(dimension)];
|
FT d = poly[i][dimension];
|
||||||
bool clower = d <= mid;
|
bool clower = d <= mid;
|
||||||
bool cupper = mid <= d;
|
bool cupper = mid <= d;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -492,14 +492,14 @@ public:
|
||||||
auto unused_end = unused_begin;
|
auto unused_end = unused_begin;
|
||||||
|
|
||||||
// Determine if the group fits
|
// Determine if the group fits
|
||||||
if (std::distance(unused_begin, m_active_indices.end()) >= static_cast<int>(n))
|
if (std::distance(unused_begin, m_active_indices.end()) >= n)
|
||||||
unused_end = std::find_if(
|
unused_end = std::find_if(
|
||||||
unused_begin, (std::min)(unused_begin + n, m_active_indices.end()),
|
unused_begin, (std::min)(unused_begin + n, m_active_indices.end()),
|
||||||
[](bool used) { return used; }
|
[](bool used) { return used; }
|
||||||
);
|
);
|
||||||
|
|
||||||
// If the discovered range was large enough
|
// If the discovered range was large enough
|
||||||
if (std::distance(unused_begin, unused_end) >= static_cast<int>(n)) {
|
if (std::distance(unused_begin, unused_end) >= n) {
|
||||||
|
|
||||||
// Mark the indices as used, and reset the properties of each of them
|
// Mark the indices as used, and reset the properties of each of them
|
||||||
// todo: it would be better to provide a function to set a range
|
// todo: it would be better to provide a function to set a range
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue