From d6da4ce5b403e461928b1ca45ffe229b8f965c87 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Wed, 25 May 2016 17:19:12 +0200 Subject: [PATCH] Add the subsubsection in the documentation --- Mesh_3/doc/Mesh_3/Mesh_3.txt | 41 +++++++++ Mesh_3/doc/Mesh_3/examples.txt | 1 + .../Mesh_3/mesh_3D_image_with_features.cpp | 83 ++++++++++--------- 3 files changed, 87 insertions(+), 38 deletions(-) diff --git a/Mesh_3/doc/Mesh_3/Mesh_3.txt b/Mesh_3/doc/Mesh_3/Mesh_3.txt index aee8eff8f90..0720a1209f6 100644 --- a/Mesh_3/doc/Mesh_3/Mesh_3.txt +++ b/Mesh_3/doc/Mesh_3/Mesh_3.txt @@ -708,6 +708,47 @@ domain. We add by hand the intersection of the spheres as a sharp feature. View of a 3D mesh with sharp features generated from two intersected implicit spheres. On the left, one can see the mesh without feature preservation, and on the right the mesh with feature preservation. \cgalFigureEnd +\subsubsection Mesh_3DomainsFromSegmented3DImagesWithFeatures Domains from Segmented 3D Images, with 1D Features + +The example \ref Mesh_3/mesh_3D_image_with_features.cpp is a modification +of \ref Mesh_3/mesh_3D_image.cpp. That example shows how to generate a mesh +from a 3D labeled image (also known as "a segmented image"), that has 2D +surfaces that intersect the box that corresponds to boundary of the +image. The intersection of the 2D surface with the box of the image is +composed of 1D curves, and must be defined as 1D-features in the domain. + +The first modification is the type of the mesh domain. Instead of being +`Labeled_image_mesh_domain_3`, it is a +`Mesh_domain_with_polyline_features_3` templated by a +`Labeled_image_mesh_domain_3`. + +\snippet Mesh_3/mesh_3D_image_with_features.cpp Domain definition + +Then, in the `%main` function, after the `%domain` object has been created, +a dedicated function computes the 1D-features, and add them to the domain. + +\snippet Mesh_3/mesh_3D_image_with_features.cpp Call add_1D_features + +The function template `%add_1D_features` is defined in the example file. It +uses non-documented code from %CGAL, that should be copy-paste in any +user-code willing to use similar code. It uses the undocumented function +template `%CGAL::polylines_to_protect` that computes the 1D-features that +correspond to the intersection of the box of the image with the surfaces +defined by the image. At the same time, a few other polylines are added as +1D-features, to protect 1D curves in the inside of the image. Then, the +method `CGAL::Mesh_domain_with_polyline_features_3::add_features` is called +twice to add the computes 1D-features to the mesh domain. + +\snippet Mesh_3/mesh_3D_image_with_features.cpp Add 1D features + +In the meshing criteria, if 1D features are added to the domain, it is very +important to define the parameter `edge_size` of the criteria class +`Mesh_criteria_3`, as follows. + +\snippet Mesh_3/mesh_3D_image_with_features.cpp Mesh criteria + +The rest of the example is similar to \ref Mesh_3/mesh_3D_image.cpp. + \subsection Mesh_3TuningMeshOptimization Tuning Mesh Optimization \anchor Mesh_3_subsection_examples_optimization diff --git a/Mesh_3/doc/Mesh_3/examples.txt b/Mesh_3/doc/Mesh_3/examples.txt index e542b02035e..52a684feabe 100644 --- a/Mesh_3/doc/Mesh_3/examples.txt +++ b/Mesh_3/doc/Mesh_3/examples.txt @@ -1,6 +1,7 @@ /*! \example Mesh_3/implicit_functions.cpp \example Mesh_3/mesh_3D_image.cpp +\example Mesh_3/mesh_3D_image_with_features.cpp \example Mesh_3/mesh_3D_image_variable_size.cpp \example Mesh_3/mesh_implicit_domains.cpp \example Mesh_3/mesh_implicit_domains_2.cpp diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_features.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_features.cpp index f0fca23b122..4292d2a257a 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_features.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_features.cpp @@ -1,25 +1,23 @@ -#include +#include +#include #include #include #include -#include -#include #include #include -#include // undocumented header +/// [Domain definition] +#include +#include +#include -#include -#include - -#include "read_polylines.h" - -// Domain typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef CGAL::Labeled_image_mesh_domain_3 Image_domain; typedef CGAL::Mesh_domain_with_polyline_features_3 Mesh_domain; +/// [Domain definition] + #ifdef CGAL_CONCURRENT_MESH_3 typedef CGAL::Parallel_tag Concurrency_tag; #else @@ -34,31 +32,43 @@ typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Criteria typedef CGAL::Mesh_criteria_3 Mesh_criteria; -typedef K::Point_3 Point_3; -typedef Mesh_domain::Image_word_type Word_type; // that is `unsigned char` - // To avoid verbose function and named parameters call using namespace CGAL::parameters; +/// [Add 1D features] +#include "read_polylines.h" +#include // undocumented header + // Protect the intersection of the object with the box of the image, // by declaring 1D-features. Note that `CGAL::polylines_to_protect` is // not documented. -template -void add_1D_features(const CGAL::Image_3& image, +bool add_1D_features(const CGAL::Image_3& image, Mesh_domain& domain, - Polyline_iterator begin, - Polyline_iterator end) + const char* lines_fname) { - std::vector > polylines_on_bbox; - CGAL::polylines_to_protect(image, polylines_on_bbox, - begin, end); - domain.add_features(polylines_on_bbox.begin(), polylines_on_bbox.end()); + typedef K::Point_3 Point_3; + typedef Mesh_domain::Image_word_type Word_type; // that is `unsigned char` - // It is very important that the polylines passed in the range - // [begin, end[ contain only polylines in the inside of the box of the - // image. - domain.add_features(begin, end); + std::vector > features_inside; + if(!read_polylines(lines_fname, features_inside)) // see file "read_polylines.h" + { + std::cerr << "Error: Cannot read file " << lines_fname << std::endl; + return false; + } + + std::vector > polylines_on_bbox; + CGAL::polylines_to_protect(image, polylines_on_bbox, + features_inside.begin(), + features_inside.end()); + + domain.add_features(polylines_on_bbox.begin(), polylines_on_bbox.end()); + + // It is very important that the polylines from the file `lines_fname` + // contain only polylines in the inside of the box of the image. + domain.add_features(features_inside.begin(), features_inside.end()); + return true; } +/// [Add 1D features] int main(int argc, char* argv[]) { @@ -70,25 +80,22 @@ int main(int argc, char* argv[]) return EXIT_FAILURE; } - const char* lines_fname = (argc>2)?argv[2]:"data/420.polylines.txt"; - std::vector > features_inside; - if(!read_polylines(lines_fname, features_inside)) // see file "read_polylines.h" - { - std::cerr << "Error: Cannot read file " << lines_fname << std::endl; - return EXIT_FAILURE; - } - // Domain Mesh_domain domain(image); - // Declare 1D-features, see above - add_1D_features(image, domain, - features_inside.begin(), features_inside.end()); + /// Declare 1D-features, see above [Call add_1D_features] + const char* lines_fname = (argc>2)?argv[2]:"data/420.polylines.txt"; - // Mesh criteria - Mesh_criteria criteria(edge_size=6, // `edge_size` is needed with 1D-features + if(!add_1D_features(image, domain, lines_fname)) { + return EXIT_FAILURE; + } + /// [Call add_1D_features] + + /// Note that `edge_size` is needed with 1D-features [Mesh criteria] + Mesh_criteria criteria(edge_size=6, facet_angle=30, facet_size=6, facet_distance=4, cell_radius_edge_ratio=3, cell_size=8); + /// [Mesh criteria] // Meshing C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria);