Add the subsubsection in the documentation

This commit is contained in:
Laurent Rineau 2016-05-25 17:19:12 +02:00
parent b3bdee456e
commit d6da4ce5b4
3 changed files with 87 additions and 38 deletions

View File

@ -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

View File

@ -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

View File

@ -1,25 +1,23 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <vector>
#include <iostream>
#include <CGAL/Mesh_triangulation_3.h>
#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
#include <CGAL/Mesh_criteria_3.h>
#include <CGAL/Labeled_image_mesh_domain_3.h>
#include <CGAL/Mesh_domain_with_polyline_features_3.h>
#include <CGAL/make_mesh_3.h>
#include <CGAL/Image_3.h>
#include <CGAL/Mesh_3/polylines_to_protect.h> // undocumented header
/// [Domain definition]
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Mesh_domain_with_polyline_features_3.h>
#include <CGAL/Labeled_image_mesh_domain_3.h>
#include <vector>
#include <iostream>
#include "read_polylines.h"
// Domain
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Labeled_image_mesh_domain_3<CGAL::Image_3,K> Image_domain;
typedef CGAL::Mesh_domain_with_polyline_features_3<Image_domain> 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<Tr> C3t3;
// Criteria
typedef CGAL::Mesh_criteria_3<Tr> 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 <CGAL/Mesh_3/polylines_to_protect.h> // 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 <typename Polyline_iterator>
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<std::vector<Point_3> > polylines_on_bbox;
CGAL::polylines_to_protect<Point_3, Word_type>(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<std::vector<Point_3> > 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<std::vector<Point_3> > polylines_on_bbox;
CGAL::polylines_to_protect<Point_3, Word_type>(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<std::vector<Point_3> > 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<C3t3>(domain, criteria);