mirror of https://github.com/CGAL/cgal
added internal region growing traits and polyline graph based on segments
This commit is contained in:
parent
35648ab3d6
commit
8cc513e935
|
|
@ -20,7 +20,7 @@ if(TARGET CGAL::Eigen3_support)
|
|||
create_single_source_cgal_program("region_growing_on_point_set_2.cpp")
|
||||
create_single_source_cgal_program("region_growing_on_point_set_3.cpp")
|
||||
create_single_source_cgal_program("region_growing_on_polygon_mesh.cpp")
|
||||
# create_single_source_cgal_program("region_growing_on_polyline_graph.cpp")
|
||||
create_single_source_cgal_program("region_growing_on_polyline_graph.cpp")
|
||||
create_single_source_cgal_program("region_growing_on_polyline.cpp")
|
||||
create_single_source_cgal_program("region_growing_with_custom_classes.cpp")
|
||||
create_single_source_cgal_program("shape_detection_basic_deprecated.cpp")
|
||||
|
|
@ -34,7 +34,7 @@ if(TARGET CGAL::Eigen3_support)
|
|||
region_growing_on_point_set_2
|
||||
region_growing_on_point_set_3
|
||||
region_growing_on_polygon_mesh
|
||||
# region_growing_on_polyline_graph
|
||||
region_growing_on_polyline_graph
|
||||
region_growing_on_polyline
|
||||
region_growing_with_custom_classes
|
||||
shape_detection_basic_deprecated)
|
||||
|
|
|
|||
|
|
@ -132,6 +132,104 @@ void save_point_regions_3(
|
|||
out.close();
|
||||
}
|
||||
|
||||
template<typename Kernel, typename Input_range, typename Segment_map>
|
||||
void save_segment_regions_2(
|
||||
const Input_range& input_range,
|
||||
const std::vector< std::vector<std::size_t> >& regions,
|
||||
const std::string fullpath,
|
||||
const Segment_map segment_map = Segment_map()) {
|
||||
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
using Color = std::array<unsigned char, 3>;
|
||||
using Point_with_color = std::pair<Point_3, Color>;
|
||||
using PLY_Point_map = CGAL::First_of_pair_property_map<Point_with_color>;
|
||||
using PLY_Color_map = CGAL::Second_of_pair_property_map<Point_with_color>;
|
||||
|
||||
std::vector<Point_with_color> pwc;
|
||||
srand(static_cast<unsigned int>(time(NULL)));
|
||||
|
||||
// Iterate through all regions.
|
||||
for (const auto& region : regions) {
|
||||
|
||||
// Generate a random color.
|
||||
const Color color =
|
||||
CGAL::make_array(
|
||||
static_cast<unsigned char>(rand() % 256),
|
||||
static_cast<unsigned char>(rand() % 256),
|
||||
static_cast<unsigned char>(rand() % 256));
|
||||
|
||||
// Iterate through all region items.
|
||||
for (const auto index : region) {
|
||||
const auto& key = *(input_range.begin() + index);
|
||||
const auto& segment = get(segment_map, key);
|
||||
const auto& s = segment.source();
|
||||
const auto& t = segment.target();
|
||||
pwc.push_back(std::make_pair(Point_3(s.x(), s.y(), 0), color));
|
||||
pwc.push_back(std::make_pair(Point_3(t.x(), t.y(), 0), color));
|
||||
}
|
||||
}
|
||||
|
||||
std::ofstream out(fullpath);
|
||||
CGAL::set_ascii_mode(out);
|
||||
CGAL::write_PLY_with_properties(
|
||||
out, pwc,
|
||||
CGAL::make_ply_point_writer(PLY_Point_map()),
|
||||
std::make_tuple(
|
||||
PLY_Color_map(),
|
||||
CGAL::PLY_property<unsigned char>("red"),
|
||||
CGAL::PLY_property<unsigned char>("green"),
|
||||
CGAL::PLY_property<unsigned char>("blue")));
|
||||
out.close();
|
||||
}
|
||||
|
||||
template<typename Kernel, typename Input_range, typename Segment_map>
|
||||
void save_segment_regions_3(
|
||||
const Input_range& input_range,
|
||||
const std::vector< std::vector<std::size_t> >& regions,
|
||||
const std::string fullpath,
|
||||
const Segment_map segment_map = Segment_map()) {
|
||||
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
using Color = std::array<unsigned char, 3>;
|
||||
using Point_with_color = std::pair<Point_3, Color>;
|
||||
using PLY_Point_map = CGAL::First_of_pair_property_map<Point_with_color>;
|
||||
using PLY_Color_map = CGAL::Second_of_pair_property_map<Point_with_color>;
|
||||
|
||||
std::vector<Point_with_color> pwc;
|
||||
srand(static_cast<unsigned int>(time(NULL)));
|
||||
|
||||
// Iterate through all regions.
|
||||
for (const auto& region : regions) {
|
||||
|
||||
// Generate a random color.
|
||||
const Color color =
|
||||
CGAL::make_array(
|
||||
static_cast<unsigned char>(rand() % 256),
|
||||
static_cast<unsigned char>(rand() % 256),
|
||||
static_cast<unsigned char>(rand() % 256));
|
||||
|
||||
// Iterate through all region items.
|
||||
for (const auto index : region) {
|
||||
const auto& key = *(input_range.begin() + index);
|
||||
const auto& segment = get(segment_map, key);
|
||||
pwc.push_back(std::make_pair(segment.source(), color));
|
||||
pwc.push_back(std::make_pair(segment.target(), color));
|
||||
}
|
||||
}
|
||||
|
||||
std::ofstream out(fullpath);
|
||||
CGAL::set_ascii_mode(out);
|
||||
CGAL::write_PLY_with_properties(
|
||||
out, pwc,
|
||||
CGAL::make_ply_point_writer(PLY_Point_map()),
|
||||
std::make_tuple(
|
||||
PLY_Color_map(),
|
||||
CGAL::PLY_property<unsigned char>("red"),
|
||||
CGAL::PLY_property<unsigned char>("green"),
|
||||
CGAL::PLY_property<unsigned char>("blue")));
|
||||
out.close();
|
||||
}
|
||||
|
||||
// Define an insert iterator.
|
||||
template<
|
||||
typename Input_range,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,96 @@
|
|||
#include <CGAL/IO/PLY.h>
|
||||
#include <CGAL/IO/OFF.h>
|
||||
#include <CGAL/Surface_mesh.h>
|
||||
#include <CGAL/Shape_detection/Region_growing/Region_growing.h>
|
||||
#include <CGAL/Shape_detection/Region_growing/Region_growing_on_segment_set.h>
|
||||
#include <CGAL/Shape_detection/Region_growing/Region_growing_on_polygon_mesh.h>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include "include/utils.h"
|
||||
|
||||
// Typedefs.
|
||||
using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel;
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
|
||||
using Surface_mesh = CGAL::Surface_mesh<Point_3>;
|
||||
using Face_range = typename Surface_mesh::Face_range;
|
||||
using Edge_range = typename Surface_mesh::Edge_range;
|
||||
|
||||
using One_ring_query = CGAL::Shape_detection::Polygon_mesh::One_ring_neighbor_query<Surface_mesh>;
|
||||
using Plane_region = CGAL::Shape_detection::Polygon_mesh::Least_squares_plane_fit_region<Kernel, Surface_mesh>;
|
||||
using RG_planes = CGAL::Shape_detection::Region_growing<Face_range, One_ring_query, Plane_region>;
|
||||
|
||||
using Vertex_to_point_map = typename Plane_region::Vertex_to_point_map;
|
||||
|
||||
using Polyline_graph = CGAL::Shape_detection::Polygon_mesh::Polyline_graph<Kernel, Surface_mesh>;
|
||||
using Segment_range = typename Polyline_graph::Segment_range;
|
||||
using Segment_map = typename Polyline_graph::Segment_map;
|
||||
|
||||
// using Line_region = CGAL::Shape_detection::Segment_set::Least_squares_line_fit_region<Kernel, Segment_range, Segment_map>;
|
||||
// using Line_sorting = CGAL::Shape_detection::Segment_set::Least_squares_line_fit_sorting<Kernel, Segment_range, Polyline_graph, Segment_map>;
|
||||
// using RG_lines = CGAL::Shape_detection::Region_growing<Segment_range, Polyline_graph, Line_region, typename Line_sorting::Seed_map>;
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
// Load data either from a local folder or a user-provided file.
|
||||
const std::string input_filename = (argc > 1 ? argv[1] : "data/am.off");
|
||||
std::ifstream in_off(input_filename);
|
||||
std::ifstream in_ply(input_filename);
|
||||
CGAL::set_ascii_mode(in_off);
|
||||
CGAL::set_ascii_mode(in_ply);
|
||||
|
||||
Surface_mesh surface_mesh;
|
||||
if (CGAL::read_OFF(in_off, surface_mesh)) { in_off.close();
|
||||
} else if (CGAL::read_PLY(in_ply, surface_mesh)) { in_ply.close();
|
||||
} else {
|
||||
std::cerr << "ERROR: cannot read the input file!" << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
const Face_range face_range = faces(surface_mesh);
|
||||
const Edge_range edge_range = edges(surface_mesh);
|
||||
std::cout << "- number of input faces: " << face_range.size() << std::endl;
|
||||
std::cout << "- number of input edges: " << edge_range.size() << std::endl;
|
||||
assert(face_range.size() == 7320);
|
||||
assert(edge_range.size() == 10980);
|
||||
|
||||
const Vertex_to_point_map vertex_to_point_map(
|
||||
get(CGAL::vertex_point, surface_mesh));
|
||||
|
||||
// Find planar regions.
|
||||
One_ring_query one_ring_query(surface_mesh);
|
||||
Plane_region plane_region(surface_mesh,
|
||||
CGAL::parameters::all_default(), vertex_to_point_map);
|
||||
RG_planes rg_planes(face_range, one_ring_query, plane_region);
|
||||
|
||||
std::vector< std::vector<std::size_t> > regions;
|
||||
rg_planes.detect(std::back_inserter(regions));
|
||||
std::cout << "- number of found planar regions: " << regions.size() << std::endl;
|
||||
assert(regions.size() == 9);
|
||||
|
||||
std::string fullpath = (argc > 2 ? argv[2] : "regions_sm.ply");
|
||||
utils::save_polygon_mesh_regions(surface_mesh, regions, fullpath);
|
||||
|
||||
// Find linear regions.
|
||||
Polyline_graph pgraph(surface_mesh, regions, vertex_to_point_map);
|
||||
const auto& segment_range = pgraph.segment_range();
|
||||
std::cout << "* number of extracted segments: " << segment_range.size() << std::endl;
|
||||
|
||||
// Line_region line_region(
|
||||
// segment_range, CGAL::parameters::all_default(), pgraph.segment_map());
|
||||
// Line_sorting line_sorting(
|
||||
// segment_range, pgraph, pgraph.segment_map());
|
||||
// line_sorting.sort();
|
||||
|
||||
// RG_lines rg_lines(
|
||||
// segment_range, pgraph, line_region, line_sorting.seed_map());
|
||||
|
||||
// std::vector< std::vector<std::size_t> > subregions;
|
||||
// rg_lines.detect(std::back_inserter(subregions));
|
||||
// std::cout << "- number of found linear regions: " << subregions.size() << std::endl;
|
||||
// assert(subregions.size() == 21);
|
||||
|
||||
// fullpath = (argc > 2 ? argv[2] : "subregions_sm.ply");
|
||||
// utils::save_segment_regions_3<Kernel, Segment_range, Segment_map>(
|
||||
// segment_range, subregions, fullpath, pgraph.segment_map());
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
@ -16,19 +16,9 @@
|
|||
|
||||
#include <CGAL/license/Shape_detection.h>
|
||||
|
||||
// STL includes.
|
||||
#include <typeinfo>
|
||||
#include <type_traits>
|
||||
|
||||
// Boost includes.
|
||||
#include <CGAL/boost/graph/named_params_helper.h>
|
||||
#include <CGAL/boost/iterator/counting_iterator.hpp>
|
||||
#include <CGAL/boost/graph/Named_function_parameters.h>
|
||||
|
||||
// CGAL includes.
|
||||
#include <CGAL/Kd_tree.h>
|
||||
#include <CGAL/Splitters.h>
|
||||
#include <CGAL/assertions.h>
|
||||
#include <CGAL/Search_traits_2.h>
|
||||
#include <CGAL/Search_traits_3.h>
|
||||
#include <CGAL/Search_traits_adapter.h>
|
||||
|
|
|
|||
|
|
@ -16,10 +16,6 @@
|
|||
|
||||
#include <CGAL/license/Shape_detection.h>
|
||||
|
||||
// Boost includes.
|
||||
#include <CGAL/boost/graph/named_params_helper.h>
|
||||
#include <CGAL/boost/graph/Named_function_parameters.h>
|
||||
|
||||
// Internal includes.
|
||||
#include <CGAL/Shape_detection/Region_growing/internal/utils.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
#include <CGAL/license/Shape_detection.h>
|
||||
|
||||
// Internal includes.
|
||||
#include <CGAL/Shape_detection/Region_growing/internal/utils.h>
|
||||
#include <CGAL/Shape_detection/Region_growing/internal/property_map.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
|
|
|||
|
|
@ -16,10 +16,6 @@
|
|||
|
||||
#include <CGAL/license/Shape_detection.h>
|
||||
|
||||
// Boost includes.
|
||||
#include <CGAL/boost/graph/named_params_helper.h>
|
||||
#include <CGAL/boost/graph/Named_function_parameters.h>
|
||||
|
||||
// Internal includes.
|
||||
#include <CGAL/Shape_detection/Region_growing/internal/utils.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
#include <CGAL/license/Shape_detection.h>
|
||||
|
||||
// Internal includes.
|
||||
#include <CGAL/Shape_detection/Region_growing/internal/utils.h>
|
||||
#include <CGAL/Shape_detection/Region_growing/internal/property_map.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
|
|
|||
|
|
@ -16,19 +16,9 @@
|
|||
|
||||
#include <CGAL/license/Shape_detection.h>
|
||||
|
||||
// STL includes.
|
||||
#include <typeinfo>
|
||||
#include <type_traits>
|
||||
|
||||
// Boost includes.
|
||||
#include <CGAL/boost/graph/named_params_helper.h>
|
||||
#include <CGAL/boost/iterator/counting_iterator.hpp>
|
||||
#include <CGAL/boost/graph/Named_function_parameters.h>
|
||||
|
||||
// CGAL includes.
|
||||
#include <CGAL/Kd_tree.h>
|
||||
#include <CGAL/Splitters.h>
|
||||
#include <CGAL/assertions.h>
|
||||
#include <CGAL/Fuzzy_sphere.h>
|
||||
#include <CGAL/Search_traits_2.h>
|
||||
#include <CGAL/Search_traits_3.h>
|
||||
|
|
|
|||
|
|
@ -16,10 +16,6 @@
|
|||
|
||||
#include <CGAL/license/Shape_detection.h>
|
||||
|
||||
// Boost includes.
|
||||
#include <CGAL/boost/graph/named_params_helper.h>
|
||||
#include <CGAL/boost/graph/Named_function_parameters.h>
|
||||
|
||||
// Internal includes.
|
||||
#include <CGAL/Shape_detection/Region_growing/internal/utils.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
#include <CGAL/license/Shape_detection.h>
|
||||
|
||||
// Internal includes.
|
||||
#include <CGAL/Shape_detection/Region_growing/internal/utils.h>
|
||||
#include <CGAL/Shape_detection/Region_growing/internal/property_map.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
|
|
|||
|
|
@ -16,15 +16,6 @@
|
|||
|
||||
#include <CGAL/license/Shape_detection.h>
|
||||
|
||||
// Boost includes.
|
||||
#include <boost/graph/properties.hpp>
|
||||
#include <boost/graph/graph_traits.hpp>
|
||||
|
||||
// Face graph includes.
|
||||
#include <CGAL/boost/graph/iterator.h>
|
||||
#include <CGAL/boost/graph/graph_traits_Surface_mesh.h>
|
||||
#include <CGAL/boost/graph/graph_traits_Polyhedron_3.h>
|
||||
|
||||
// Internal includes.
|
||||
#include <CGAL/Shape_detection/Region_growing/internal/property_map.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,209 @@
|
|||
// Copyright (c) 2020 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) : Dmitry Anisimov
|
||||
//
|
||||
|
||||
#ifndef CGAL_SHAPE_DETECTION_REGION_GROWING_POLYGON_MESH_POLYLINE_GRAPH_H
|
||||
#define CGAL_SHAPE_DETECTION_REGION_GROWING_POLYGON_MESH_POLYLINE_GRAPH_H
|
||||
|
||||
#include <CGAL/license/Shape_detection.h>
|
||||
|
||||
// Internal includes.
|
||||
#include <CGAL/Shape_detection/Region_growing/internal/property_map.h>
|
||||
|
||||
namespace CGAL {
|
||||
namespace Shape_detection {
|
||||
namespace Polygon_mesh {
|
||||
|
||||
template<
|
||||
typename GeomTraits,
|
||||
typename PolygonMesh,
|
||||
typename FaceRange = typename PolygonMesh::Face_range,
|
||||
typename EdgeRange = typename PolygonMesh::Edge_range,
|
||||
typename VertexToPointMap = typename boost::property_map<PolygonMesh, CGAL::vertex_point_t>::type>
|
||||
class Polyline_graph {
|
||||
|
||||
private:
|
||||
struct PEdge {
|
||||
std::size_t index = std::size_t(-1);
|
||||
std::set<std::size_t> neighbors;
|
||||
std::vector<std::size_t> regions;
|
||||
};
|
||||
|
||||
public:
|
||||
using Traits = GeomTraits;
|
||||
using Face_graph = PolygonMesh;
|
||||
using Face_range = FaceRange;
|
||||
using Edge_range = EdgeRange;
|
||||
using Vertex_to_point_map = VertexToPointMap;
|
||||
|
||||
using Segment_range = std::vector<PEdge>;
|
||||
using Segment_map = internal::Polyline_graph_segment_map<PEdge, Face_graph, Edge_range, Vertex_to_point_map>;
|
||||
|
||||
private:
|
||||
using Face_to_region_map = internal::Item_to_region_index_map;
|
||||
using Face_to_index_map = internal::Item_to_index_property_map<Face_range>;
|
||||
using Edge_to_index_map = internal::Item_to_index_property_map<Edge_range>;
|
||||
|
||||
public:
|
||||
Polyline_graph(
|
||||
const PolygonMesh& pmesh,
|
||||
const std::vector< std::vector<std::size_t> >& regions,
|
||||
const VertexToPointMap vertex_to_point_map) :
|
||||
m_face_graph(pmesh),
|
||||
m_regions(regions),
|
||||
m_face_range(faces(m_face_graph)),
|
||||
m_edge_range(edges(m_face_graph)),
|
||||
m_vertex_to_point_map(vertex_to_point_map),
|
||||
m_face_to_region_map(m_face_range, regions),
|
||||
m_face_to_index_map(m_face_range),
|
||||
m_edge_to_index_map(m_edge_range),
|
||||
m_segment_map(m_face_graph, m_edge_range, m_vertex_to_point_map) {
|
||||
|
||||
CGAL_precondition(m_face_range.size() > 0);
|
||||
CGAL_precondition(m_edge_range.size() > 0);
|
||||
CGAL_precondition(regions.size() > 0);
|
||||
build_graph();
|
||||
}
|
||||
|
||||
void build_graph() {
|
||||
|
||||
clear();
|
||||
int r1 = -1, r2 = -1;
|
||||
std::vector<std::size_t> pedge_map(
|
||||
m_edge_range.size(), std::size_t(-1));
|
||||
for (const auto& edge : m_edge_range) {
|
||||
std::tie(r1, r2) = get_regions(edge);
|
||||
if (r1 == r2) continue;
|
||||
add_graph_edge(edge, r1, r2, pedge_map);
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < m_pedges.size(); ++i) {
|
||||
auto& pedge = m_pedges[i];
|
||||
|
||||
CGAL_precondition(pedge.regions.size() == 2);
|
||||
CGAL_precondition(pedge.regions[0] != pedge.regions[1]);
|
||||
CGAL_precondition(pedge.index != std::size_t(-1));
|
||||
CGAL_precondition(pedge.index < m_edge_range.size());
|
||||
|
||||
const auto& edge = *(m_edge_range.begin() + pedge.index);
|
||||
const auto s = source(edge, m_face_graph);
|
||||
const auto t = target(edge, m_face_graph);
|
||||
|
||||
add_vertex_neighbors(s, i, pedge_map, pedge.neighbors);
|
||||
add_vertex_neighbors(t, i, pedge_map, pedge.neighbors);
|
||||
}
|
||||
}
|
||||
|
||||
void operator()(
|
||||
const std::size_t query_index,
|
||||
std::vector<std::size_t>& neighbors) const {
|
||||
|
||||
neighbors.clear();
|
||||
CGAL_precondition(query_index < m_pedges.size());
|
||||
const auto& pedge = m_pedges[query_index];
|
||||
for (const std::size_t neighbor : pedge.neighbors)
|
||||
neighbors.push_back(neighbor);
|
||||
}
|
||||
|
||||
const Segment_range& segment_range() const {
|
||||
return m_pedges;
|
||||
}
|
||||
|
||||
const Segment_map& segment_map() const {
|
||||
return m_segment_map;
|
||||
}
|
||||
|
||||
void clear() {
|
||||
m_pedges.clear();
|
||||
}
|
||||
|
||||
void release_memory() {
|
||||
m_pedges.shrink_to_fit();
|
||||
}
|
||||
|
||||
private:
|
||||
const Face_graph& m_face_graph;
|
||||
const std::vector< std::vector<std::size_t> >& m_regions;
|
||||
const Face_range m_face_range;
|
||||
const Edge_range m_edge_range;
|
||||
const Vertex_to_point_map m_vertex_to_point_map;
|
||||
const Face_to_region_map m_face_to_region_map;
|
||||
const Face_to_index_map m_face_to_index_map;
|
||||
const Edge_to_index_map m_edge_to_index_map;
|
||||
const Segment_map m_segment_map;
|
||||
Segment_range m_pedges;
|
||||
|
||||
template<typename EdgeType>
|
||||
std::pair<int, int> get_regions(const EdgeType& edge) const {
|
||||
|
||||
const auto hedge1 = halfedge(edge, m_face_graph);
|
||||
const auto hedge2 = opposite(hedge1, m_face_graph);
|
||||
|
||||
const auto face1 = face(hedge1, m_face_graph);
|
||||
const auto face2 = face(hedge2, m_face_graph);
|
||||
|
||||
const std::size_t fi1 = get(m_face_to_index_map, face1);
|
||||
const std::size_t fi2 = get(m_face_to_index_map, face2);
|
||||
CGAL_precondition(fi1 != fi2);
|
||||
|
||||
int r1 = -1, r2 = -1;
|
||||
if (fi1 != std::size_t(-1))
|
||||
r1 = get(m_face_to_region_map, fi1);
|
||||
if (fi2 != std::size_t(-1))
|
||||
r2 = get(m_face_to_region_map, fi2);
|
||||
return std::make_pair(r1, r2);
|
||||
}
|
||||
|
||||
template<typename EdgeType>
|
||||
void add_graph_edge(
|
||||
const EdgeType& edge, const int region1, const int region2,
|
||||
std::vector<std::size_t>& pedge_map) {
|
||||
|
||||
PEdge pedge;
|
||||
CGAL_precondition(region1 != region2);
|
||||
const std::size_t edge_index = get(m_edge_to_index_map, edge);
|
||||
CGAL_precondition(edge_index != std::size_t(-1));
|
||||
pedge.index = edge_index;
|
||||
pedge.regions.push_back(region1);
|
||||
pedge.regions.push_back(region2);
|
||||
CGAL_precondition(pedge.index < pedge_map.size());
|
||||
pedge_map[pedge.index] = m_pedges.size();
|
||||
m_pedges.push_back(pedge);
|
||||
}
|
||||
|
||||
template<typename VertexType>
|
||||
void add_vertex_neighbors(
|
||||
const VertexType& vertex, const std::size_t curr_pe,
|
||||
const std::vector<std::size_t>& pedge_map,
|
||||
std::set<std::size_t>& neighbors) const {
|
||||
|
||||
const auto query_hedge = halfedge(vertex, m_face_graph);
|
||||
const auto hedges = halfedges_around_target(query_hedge, m_face_graph);
|
||||
CGAL_precondition(hedges.size() > 0);
|
||||
for (const auto& hedge : hedges) {
|
||||
const auto e = edge(hedge, m_face_graph);
|
||||
const std::size_t ei = get(m_edge_to_index_map, e);
|
||||
CGAL_precondition(ei < pedge_map.size());
|
||||
const std::size_t pe = pedge_map[ei];
|
||||
if (pe == std::size_t(-1)) continue;
|
||||
if (pe == curr_pe) continue;
|
||||
CGAL_precondition(pe < m_pedges.size());
|
||||
neighbors.insert(pe);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Polygon_mesh
|
||||
} // namespace Shape_detection
|
||||
} // namespace CGAL
|
||||
|
||||
#endif // CGAL_SHAPE_DETECTION_REGION_GROWING_POLYGON_MESH_POLYLINE_GRAPH_H
|
||||
|
|
@ -16,12 +16,8 @@
|
|||
|
||||
#include <CGAL/license/Shape_detection.h>
|
||||
|
||||
// Boost includes.
|
||||
#include <CGAL/boost/graph/named_params_helper.h>
|
||||
#include <CGAL/boost/graph/Named_function_parameters.h>
|
||||
|
||||
// Internal includes.
|
||||
#include <CGAL/Shape_detection/Region_growing/internal/utils.h>
|
||||
#include <CGAL/Shape_detection/Region_growing/internal/region_growing_traits.h>
|
||||
|
||||
namespace CGAL {
|
||||
namespace Shape_detection {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
#include <CGAL/license/Shape_detection.h>
|
||||
|
||||
// Internal includes.
|
||||
#include <CGAL/Shape_detection/Region_growing/internal/utils.h>
|
||||
#include <CGAL/Shape_detection/Region_growing/internal/property_map.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@
|
|||
#include <CGAL/boost/graph/Named_function_parameters.h>
|
||||
|
||||
// Internal includes.
|
||||
#include <CGAL/Shape_detection/Region_growing/internal/utils.h>
|
||||
#include <CGAL/Shape_detection/Region_growing/internal/property_map.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
|
@ -29,7 +28,6 @@ namespace Shape_detection {
|
|||
namespace internal {
|
||||
|
||||
template<
|
||||
typename GeomTraits,
|
||||
typename PolygonMesh,
|
||||
typename FaceRange = typename PolygonMesh::Face_range,
|
||||
typename VertexRange = typename PolygonMesh::Vertex_range,
|
||||
|
|
@ -44,14 +42,13 @@ namespace internal {
|
|||
};
|
||||
|
||||
public:
|
||||
using Traits = GeomTraits;
|
||||
using Face_graph = PolygonMesh;
|
||||
using Face_range = FaceRange;
|
||||
using Vertex_range = VertexRange;
|
||||
using Vertex_to_point_map = VertexToPointMap;
|
||||
|
||||
using PVertex_range = std::vector<PVertex>;
|
||||
using Point_map = internal::Polyline_graph_point_map<PVertex, Vertex_range, Vertex_to_point_map>;
|
||||
using Point_range = std::vector<PVertex>;
|
||||
using Point_map = internal::Polyline_graph_point_map<PVertex, Vertex_range, Vertex_to_point_map>;
|
||||
|
||||
private:
|
||||
using Face_to_region_map = internal::Item_to_region_index_map;
|
||||
|
|
@ -75,33 +72,20 @@ namespace internal {
|
|||
|
||||
CGAL_precondition(m_face_range.size() > 0);
|
||||
CGAL_precondition(m_vertex_range.size() > 0);
|
||||
CGAL_precondition(regions.size() > 0);
|
||||
build_graph();
|
||||
}
|
||||
|
||||
void build_graph() {
|
||||
|
||||
clear();
|
||||
std::vector<std::size_t> vertex_map(
|
||||
int r1 = -1, r2 = -1;
|
||||
std::vector<std::size_t> pvertex_map(
|
||||
m_vertex_range.size(), std::size_t(-1));
|
||||
for (const auto& edge : edges(m_face_graph)) {
|
||||
const auto hedge1 = halfedge(edge, m_face_graph);
|
||||
const auto hedge2 = opposite(hedge1, m_face_graph);
|
||||
|
||||
const auto face1 = face(hedge1, m_face_graph);
|
||||
const auto face2 = face(hedge2, m_face_graph);
|
||||
|
||||
const std::size_t fi1 = get(m_face_to_index_map, face1);
|
||||
const std::size_t fi2 = get(m_face_to_index_map, face2);
|
||||
CGAL_precondition(fi1 != fi2);
|
||||
|
||||
int r1 = -1, r2 = -1;
|
||||
if (fi1 != std::size_t(-1))
|
||||
r1 = get(m_face_to_region_map, fi1);
|
||||
if (fi2 != std::size_t(-1))
|
||||
r2 = get(m_face_to_region_map, fi2);
|
||||
std::tie(r1, r2) = get_regions(edge);
|
||||
if (r1 == r2) continue;
|
||||
CGAL_precondition(r1 != r2);
|
||||
add_graph_edge(edge, r1, r2, vertex_map);
|
||||
add_graph_edge(edge, r1, r2, pvertex_map);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -110,14 +94,14 @@ namespace internal {
|
|||
std::vector<std::size_t>& neighbors) const {
|
||||
|
||||
neighbors.clear();
|
||||
CGAL_precondition(query_index < m_vertices.size());
|
||||
const auto& vertex = m_vertices[query_index];
|
||||
for (const std::size_t neighbor : vertex.neighbors)
|
||||
CGAL_precondition(query_index < m_pvertices.size());
|
||||
const auto& pvertex = m_pvertices[query_index];
|
||||
for (const std::size_t neighbor : pvertex.neighbors)
|
||||
neighbors.push_back(neighbor);
|
||||
}
|
||||
|
||||
const PVertex_range& pvertex_range() const {
|
||||
return m_vertices;
|
||||
const Point_range& point_range() const {
|
||||
return m_pvertices;
|
||||
}
|
||||
|
||||
const Point_map& point_map() const {
|
||||
|
|
@ -125,7 +109,11 @@ namespace internal {
|
|||
}
|
||||
|
||||
void clear() {
|
||||
m_vertices.clear();
|
||||
m_pvertices.clear();
|
||||
}
|
||||
|
||||
void release_memory() {
|
||||
m_pvertices.shrink_to_fit();
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -138,12 +126,33 @@ namespace internal {
|
|||
const Face_to_index_map m_face_to_index_map;
|
||||
const Vertex_to_index_map m_vertex_to_index_map;
|
||||
const Point_map m_point_map;
|
||||
PVertex_range m_vertices;
|
||||
Point_range m_pvertices;
|
||||
|
||||
template<typename EdgeType>
|
||||
std::pair<int, int> get_regions(const EdgeType& edge) const {
|
||||
|
||||
const auto hedge1 = halfedge(edge, m_face_graph);
|
||||
const auto hedge2 = opposite(hedge1, m_face_graph);
|
||||
|
||||
const auto face1 = face(hedge1, m_face_graph);
|
||||
const auto face2 = face(hedge2, m_face_graph);
|
||||
|
||||
const std::size_t fi1 = get(m_face_to_index_map, face1);
|
||||
const std::size_t fi2 = get(m_face_to_index_map, face2);
|
||||
CGAL_precondition(fi1 != fi2);
|
||||
|
||||
int r1 = -1, r2 = -1;
|
||||
if (fi1 != std::size_t(-1))
|
||||
r1 = get(m_face_to_region_map, fi1);
|
||||
if (fi2 != std::size_t(-1))
|
||||
r2 = get(m_face_to_region_map, fi2);
|
||||
return std::make_pair(r1, r2);
|
||||
}
|
||||
|
||||
template<typename EdgeType>
|
||||
void add_graph_edge(
|
||||
const EdgeType& edge, const int region1, const int region2,
|
||||
std::vector<std::size_t>& vertex_map) {
|
||||
std::vector<std::size_t>& pvertex_map) {
|
||||
|
||||
const auto s = source(edge, m_face_graph);
|
||||
const auto t = target(edge, m_face_graph);
|
||||
|
|
@ -155,36 +164,39 @@ namespace internal {
|
|||
CGAL_precondition(vsource != vtarget);
|
||||
CGAL_precondition(region1 != region2);
|
||||
CGAL_precondition(
|
||||
vertex_map.size() == m_vertex_range.size());
|
||||
pvertex_map.size() == m_vertex_range.size());
|
||||
|
||||
CGAL_precondition(vsource < vertex_map.size());
|
||||
if (vertex_map[vsource] == std::size_t(-1)) { // add new vertex
|
||||
vertex_map[vsource] = m_vertices.size();
|
||||
m_vertices.push_back(PVertex());
|
||||
m_vertices.back().index = vsource;
|
||||
CGAL_precondition(vsource < pvertex_map.size());
|
||||
if (pvertex_map[vsource] == std::size_t(-1)) { // add new pvertex
|
||||
pvertex_map[vsource] = m_pvertices.size();
|
||||
m_pvertices.push_back(PVertex());
|
||||
m_pvertices.back().index = vsource;
|
||||
}
|
||||
|
||||
CGAL_precondition(vtarget < vertex_map.size());
|
||||
if (vertex_map[vtarget] == std::size_t(-1)) { // add new vertex
|
||||
vertex_map[vtarget] = m_vertices.size();
|
||||
m_vertices.push_back(PVertex());
|
||||
m_vertices.back().index = vtarget;
|
||||
CGAL_precondition(vtarget < pvertex_map.size());
|
||||
if (pvertex_map[vtarget] == std::size_t(-1)) { // add new pvertex
|
||||
pvertex_map[vtarget] = m_pvertices.size();
|
||||
m_pvertices.push_back(PVertex());
|
||||
m_pvertices.back().index = vtarget;
|
||||
}
|
||||
|
||||
// Update vertex info.
|
||||
const std::size_t v1 = vertex_map[vsource];
|
||||
const std::size_t v2 = vertex_map[vtarget];
|
||||
CGAL_precondition(v1 != std::size_t(-1) && v1 < m_vertices.size());
|
||||
CGAL_precondition(v2 != std::size_t(-1) && v2 < m_vertices.size());
|
||||
// Update pvertex info.
|
||||
const std::size_t pv1 = pvertex_map[vsource];
|
||||
const std::size_t pv2 = pvertex_map[vtarget];
|
||||
|
||||
auto& vertex1 = m_vertices[v1];
|
||||
auto& vertex2 = m_vertices[v2];
|
||||
vertex1.neighbors.insert(v2);
|
||||
vertex2.neighbors.insert(v1);
|
||||
vertex1.regions.insert(region1);
|
||||
vertex1.regions.insert(region2);
|
||||
vertex2.regions.insert(region1);
|
||||
vertex2.regions.insert(region2);
|
||||
CGAL_precondition(pv1 != std::size_t(-1) && pv1 < m_pvertices.size());
|
||||
CGAL_precondition(pv2 != std::size_t(-1) && pv2 < m_pvertices.size());
|
||||
|
||||
auto& pvertex1 = m_pvertices[pv1];
|
||||
auto& pvertex2 = m_pvertices[pv2];
|
||||
|
||||
pvertex1.neighbors.insert(pv2);
|
||||
pvertex1.regions.insert(region1);
|
||||
pvertex1.regions.insert(region2);
|
||||
|
||||
pvertex2.neighbors.insert(pv1);
|
||||
pvertex2.regions.insert(region1);
|
||||
pvertex2.regions.insert(region2);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,9 @@
|
|||
#include <CGAL/assertions.h>
|
||||
#include <CGAL/property_map.h>
|
||||
|
||||
// Internal includes.
|
||||
#include <CGAL/Shape_detection/Region_growing/internal/region_growing_traits.h>
|
||||
|
||||
namespace CGAL {
|
||||
namespace Shape_detection {
|
||||
namespace internal {
|
||||
|
|
@ -210,6 +213,60 @@ namespace internal {
|
|||
const Vertex_to_point_map& m_vertex_to_point_map;
|
||||
};
|
||||
|
||||
template<
|
||||
typename KeyType,
|
||||
typename FaceGraph,
|
||||
typename EdgeRange,
|
||||
typename VertexToPointMap>
|
||||
class Polyline_graph_segment_map {
|
||||
|
||||
public:
|
||||
using Key_type = KeyType;
|
||||
using Face_graph = FaceGraph;
|
||||
using Edge_range = EdgeRange;
|
||||
using Vertex_to_point_map = VertexToPointMap;
|
||||
|
||||
using Point_type = typename Vertex_to_point_map::value_type;
|
||||
using Traits = typename Kernel_traits<Point_type>::Kernel;
|
||||
using RG_traits = typename std::conditional<
|
||||
std::is_same<typename Traits::Point_2, Point_type>::value,
|
||||
internal::Polyline_graph_traits_2<Traits>,
|
||||
internal::Polyline_graph_traits_3<Traits> >::type;
|
||||
|
||||
using value_type = typename RG_traits::Segment;
|
||||
using reference = value_type;
|
||||
using key_type = Key_type;
|
||||
using category = boost::readable_property_map_tag;
|
||||
|
||||
Polyline_graph_segment_map(
|
||||
const Face_graph& face_graph,
|
||||
const Edge_range& edge_range,
|
||||
const Vertex_to_point_map& vertex_to_point_map) :
|
||||
m_face_graph(face_graph),
|
||||
m_edge_range(edge_range),
|
||||
m_vertex_to_point_map(vertex_to_point_map)
|
||||
{ }
|
||||
|
||||
reference operator[](const key_type& edge) const {
|
||||
CGAL_precondition(edge.index < m_edge_range.size());
|
||||
const auto& key = *(m_edge_range.begin() + edge.index);
|
||||
const auto& s = get(m_vertex_to_point_map, source(key, m_face_graph));
|
||||
const auto& t = get(m_vertex_to_point_map, target(key, m_face_graph));
|
||||
const auto construct_segment = RG_traits().construct_segment();
|
||||
return construct_segment(s, t);
|
||||
}
|
||||
|
||||
friend inline reference get(
|
||||
const Polyline_graph_segment_map& pgraph_map, const key_type& key) {
|
||||
return pgraph_map[key];
|
||||
}
|
||||
|
||||
private:
|
||||
const Face_graph& m_face_graph;
|
||||
const Edge_range& m_edge_range;
|
||||
const Vertex_to_point_map& m_vertex_to_point_map;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace Shape_detection
|
||||
} // namespace CGAL
|
||||
|
|
|
|||
|
|
@ -0,0 +1,125 @@
|
|||
// Copyright (c) 2020 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) : Dmitry Anisimov
|
||||
//
|
||||
|
||||
#ifndef CGAL_SHAPE_DETECTION_REGION_GROWING_INTERNAL_TRAITS_H
|
||||
#define CGAL_SHAPE_DETECTION_REGION_GROWING_INTERNAL_TRAITS_H
|
||||
|
||||
#include <CGAL/license/Shape_detection.h>
|
||||
|
||||
// STL includes.
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <type_traits>
|
||||
|
||||
// CGAL includes.
|
||||
#include <CGAL/assertions.h>
|
||||
#include <CGAL/number_utils.h>
|
||||
|
||||
// Internal includes.
|
||||
#include <CGAL/Shape_detection/Region_growing/internal/utils.h>
|
||||
|
||||
namespace CGAL {
|
||||
namespace Shape_detection {
|
||||
namespace internal {
|
||||
|
||||
template<typename GeomTraits>
|
||||
struct Polyline_graph_traits_2 {
|
||||
using Segment = typename GeomTraits::Segment_2;
|
||||
using Construct_segment = typename GeomTraits::Construct_segment_2;
|
||||
decltype(auto) construct_segment_object() const {
|
||||
return GeomTraits().compute_segment_2_object();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename GeomTraits>
|
||||
struct Polyline_graph_traits_3 {
|
||||
using Segment = typename GeomTraits::Segment_3;
|
||||
using Construct_segment = typename GeomTraits::Construct_segment_3;
|
||||
decltype(auto) construct_segment_object() const {
|
||||
return GeomTraits().compute_segment_3_object();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename GeomTraits>
|
||||
struct Polyline_traits_2 {
|
||||
using Point = typename GeomTraits::Point_2;
|
||||
using Vector = typename GeomTraits::Vector_2;
|
||||
using Line = typename GeomTraits::Line_2;
|
||||
|
||||
using Compute_squared_length = typename GeomTraits::Compute_squared_length_2;
|
||||
using Compute_squared_distance = typename GeomTraits::Compute_squared_distance_2;
|
||||
using Compute_scalar_product = typename GeomTraits::Compute_scalar_product_2;
|
||||
|
||||
const GeomTraits m_traits;
|
||||
Polyline_traits_2(const GeomTraits& traits) :
|
||||
m_traits(traits)
|
||||
{ }
|
||||
|
||||
decltype(auto) compute_squared_length_object() const {
|
||||
return m_traits.compute_squared_length_2_object();
|
||||
}
|
||||
decltype(auto) compute_squared_distance_object() const {
|
||||
return m_traits.compute_squared_distance_2_object();
|
||||
}
|
||||
decltype(auto) compute_scalar_product_object() const {
|
||||
return m_traits.compute_scalar_product_2_object();
|
||||
}
|
||||
|
||||
template<typename InputRange, typename PointMap>
|
||||
decltype(auto) create_line_from_points(
|
||||
const InputRange& input_range, const PointMap point_map,
|
||||
const std::vector<std::size_t>& region) const {
|
||||
return internal::create_line_from_points_2<GeomTraits>(
|
||||
input_range, point_map, region);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename GeomTraits>
|
||||
struct Polyline_traits_3 {
|
||||
using Point = typename GeomTraits::Point_3;
|
||||
using Vector = typename GeomTraits::Vector_3;
|
||||
using Line = typename GeomTraits::Line_3;
|
||||
|
||||
using Compute_squared_length = typename GeomTraits::Compute_squared_length_3;
|
||||
using Compute_squared_distance = typename GeomTraits::Compute_squared_distance_3;
|
||||
using Compute_scalar_product = typename GeomTraits::Compute_scalar_product_3;
|
||||
|
||||
const GeomTraits m_traits;
|
||||
Polyline_traits_3(const GeomTraits& traits) :
|
||||
m_traits(traits)
|
||||
{ }
|
||||
|
||||
decltype(auto) compute_squared_length_object() const {
|
||||
return m_traits.compute_squared_length_3_object();
|
||||
}
|
||||
decltype(auto) compute_squared_distance_object() const {
|
||||
return m_traits.compute_squared_distance_3_object();
|
||||
}
|
||||
decltype(auto) compute_scalar_product_object() const {
|
||||
return m_traits.compute_scalar_product_3_object();
|
||||
}
|
||||
|
||||
template<typename InputRange, typename PointMap>
|
||||
decltype(auto) create_line_from_points(
|
||||
const InputRange& input_range, const PointMap point_map,
|
||||
const std::vector<std::size_t>& region) const {
|
||||
return internal::create_line_from_points_3<GeomTraits>(
|
||||
input_range, point_map, region);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace Shape_detection
|
||||
} // namespace CGAL
|
||||
|
||||
#endif // CGAL_SHAPE_DETECTION_REGION_GROWING_INTERNAL_TRAITS_H
|
||||
|
|
@ -22,12 +22,17 @@
|
|||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <type_traits>
|
||||
#include <typeinfo>
|
||||
|
||||
// Boost headers.
|
||||
#include <boost/mpl/has_xxx.hpp>
|
||||
#include <boost/graph/properties.hpp>
|
||||
#include <boost/graph/graph_traits.hpp>
|
||||
|
||||
// Named parameters.
|
||||
#include <CGAL/boost/graph/named_params_helper.h>
|
||||
#include <CGAL/boost/graph/Named_function_parameters.h>
|
||||
|
||||
// Face graph includes.
|
||||
#include <CGAL/Iterator_range.h>
|
||||
#include <CGAL/HalfedgeDS_vector.h>
|
||||
|
|
@ -42,6 +47,7 @@
|
|||
#include <CGAL/Eigen_diagonalize_traits.h>
|
||||
#include <CGAL/linear_least_squares_fitting_2.h>
|
||||
#include <CGAL/linear_least_squares_fitting_3.h>
|
||||
#include <CGAL/boost/iterator/counting_iterator.hpp>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
|
@ -315,74 +321,6 @@ namespace internal {
|
|||
return std::make_pair(plane, static_cast<FT>(score));
|
||||
}
|
||||
|
||||
template<typename GeomTraits>
|
||||
struct Polyline_traits_2 {
|
||||
using Point = typename GeomTraits::Point_2;
|
||||
using Vector = typename GeomTraits::Vector_2;
|
||||
using Line = typename GeomTraits::Line_2;
|
||||
|
||||
using Compute_squared_length = typename GeomTraits::Compute_squared_length_2;
|
||||
using Compute_squared_distance = typename GeomTraits::Compute_squared_distance_2;
|
||||
using Compute_scalar_product = typename GeomTraits::Compute_scalar_product_2;
|
||||
|
||||
const GeomTraits m_traits;
|
||||
Polyline_traits_2(const GeomTraits& traits) :
|
||||
m_traits(traits)
|
||||
{ }
|
||||
|
||||
decltype(auto) compute_squared_length_object() const {
|
||||
return m_traits.compute_squared_length_2_object();
|
||||
}
|
||||
decltype(auto) compute_squared_distance_object() const {
|
||||
return m_traits.compute_squared_distance_2_object();
|
||||
}
|
||||
decltype(auto) compute_scalar_product_object() const {
|
||||
return m_traits.compute_scalar_product_2_object();
|
||||
}
|
||||
|
||||
template<typename InputRange, typename PointMap>
|
||||
decltype(auto) create_line_from_points(
|
||||
const InputRange& input_range, const PointMap point_map,
|
||||
const std::vector<std::size_t>& region) const {
|
||||
return internal::create_line_from_points_2<GeomTraits>(
|
||||
input_range, point_map, region);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename GeomTraits>
|
||||
struct Polyline_traits_3 {
|
||||
using Point = typename GeomTraits::Point_3;
|
||||
using Vector = typename GeomTraits::Vector_3;
|
||||
using Line = typename GeomTraits::Line_3;
|
||||
|
||||
using Compute_squared_length = typename GeomTraits::Compute_squared_length_3;
|
||||
using Compute_squared_distance = typename GeomTraits::Compute_squared_distance_3;
|
||||
using Compute_scalar_product = typename GeomTraits::Compute_scalar_product_3;
|
||||
|
||||
const GeomTraits m_traits;
|
||||
Polyline_traits_3(const GeomTraits& traits) :
|
||||
m_traits(traits)
|
||||
{ }
|
||||
|
||||
decltype(auto) compute_squared_length_object() const {
|
||||
return m_traits.compute_squared_length_3_object();
|
||||
}
|
||||
decltype(auto) compute_squared_distance_object() const {
|
||||
return m_traits.compute_squared_distance_3_object();
|
||||
}
|
||||
decltype(auto) compute_scalar_product_object() const {
|
||||
return m_traits.compute_scalar_product_3_object();
|
||||
}
|
||||
|
||||
template<typename InputRange, typename PointMap>
|
||||
decltype(auto) create_line_from_points(
|
||||
const InputRange& input_range, const PointMap point_map,
|
||||
const std::vector<std::size_t>& region) const {
|
||||
return internal::create_line_from_points_3<GeomTraits>(
|
||||
input_range, point_map, region);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace Shape_detection
|
||||
} // namespace CGAL
|
||||
|
|
|
|||
|
|
@ -20,22 +20,20 @@
|
|||
#include <CGAL/Shape_detection/Region_growing/internal/Polyline_graph.h>
|
||||
#include "../../examples/Shape_detection/include/utils.h"
|
||||
|
||||
namespace SD = CGAL::Shape_detection;
|
||||
using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel;
|
||||
|
||||
using FT = typename Kernel::FT;
|
||||
namespace SD = CGAL::Shape_detection;
|
||||
using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel;
|
||||
using Point_3 = typename Kernel::Point_3;
|
||||
|
||||
using Surface_mesh = CGAL::Surface_mesh<Point_3>;
|
||||
using Polyline_graph = CGAL::Shape_detection::internal::Polyline_graph_points<Kernel, Surface_mesh>;
|
||||
using Polyline_graph = CGAL::Shape_detection::internal::Polyline_graph_points<Surface_mesh>;
|
||||
|
||||
using Vertex_to_point_map = typename Polyline_graph::Vertex_to_point_map;
|
||||
using PVertex_range = typename Polyline_graph::PVertex_range;
|
||||
using Point_range = typename Polyline_graph::Point_range;
|
||||
using Point_map = typename Polyline_graph::Point_map;
|
||||
|
||||
using Region_type = CGAL::Shape_detection::Polyline::Least_squares_line_fit_region<Kernel, PVertex_range, Point_map>;
|
||||
using Sorting = CGAL::Shape_detection::Polyline::Least_squares_line_fit_sorting<Kernel, PVertex_range, Polyline_graph, Point_map>;
|
||||
using Region_growing = CGAL::Shape_detection::Region_growing<PVertex_range, Polyline_graph, Region_type, typename Sorting::Seed_map>;
|
||||
using Region_type = CGAL::Shape_detection::Polyline::Least_squares_line_fit_region<Kernel, Point_range, Point_map>;
|
||||
using Sorting = CGAL::Shape_detection::Polyline::Least_squares_line_fit_sorting<Kernel, Point_range, Polyline_graph, Point_map>;
|
||||
using Region_growing = CGAL::Shape_detection::Region_growing<Point_range, Polyline_graph, Region_type, typename Sorting::Seed_map>;
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
|
|
@ -58,31 +56,32 @@ int main(int argc, char *argv[]) {
|
|||
// std::cout << "- num regions: " << regions.size() << std::endl;
|
||||
assert(regions.size() == 9);
|
||||
|
||||
std::string fullpath = (argc > 2 ? argv[2] : "regions_sm.ply");
|
||||
utils::save_polygon_mesh_regions(surface_mesh, regions, fullpath);
|
||||
// std::string fullpath = (argc > 2 ? argv[2] : "regions_sm.ply");
|
||||
// utils::save_polygon_mesh_regions(surface_mesh, regions, fullpath);
|
||||
|
||||
const Vertex_to_point_map vertex_to_point_map(
|
||||
get(CGAL::vertex_point, surface_mesh));
|
||||
|
||||
Polyline_graph pgraph(surface_mesh, regions, vertex_to_point_map);
|
||||
const auto& pvertices = pgraph.pvertex_range();
|
||||
const auto& point_range = pgraph.point_range();
|
||||
// std::cout << "- num extracted points: " << point_range.size() << std::endl;
|
||||
|
||||
Region_type region_type(
|
||||
pvertices, CGAL::parameters::all_default(), pgraph.point_map());
|
||||
Sorting sorting(pvertices, pgraph, pgraph.point_map());
|
||||
point_range, CGAL::parameters::all_default(), pgraph.point_map());
|
||||
Sorting sorting(point_range, pgraph, pgraph.point_map());
|
||||
sorting.sort();
|
||||
|
||||
Region_growing region_growing(
|
||||
pvertices, pgraph, region_type, sorting.seed_map());
|
||||
point_range, pgraph, region_type, sorting.seed_map());
|
||||
|
||||
std::vector< std::vector<std::size_t> > subregions;
|
||||
region_growing.detect(std::back_inserter(subregions));
|
||||
// std::cout << "- num subregions: " << subregions.size() << std::endl;
|
||||
assert(subregions.size() == 21);
|
||||
|
||||
fullpath = (argc > 2 ? argv[2] : "subregions_sm.ply");
|
||||
utils::save_point_regions_3<Kernel, PVertex_range, Point_map>(
|
||||
pvertices, subregions, fullpath, pgraph.point_map());
|
||||
// fullpath = (argc > 2 ? argv[2] : "subregions_sm.ply");
|
||||
// utils::save_point_regions_3<Kernel, Point_range, Point_map>(
|
||||
// point_range, subregions, fullpath, pgraph.point_map());
|
||||
|
||||
std::cout << "rg_pgraph, epick_test_success: " << true << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
|
|
|
|||
Loading…
Reference in New Issue