This commit is contained in:
Guillaume Damiand 2022-05-05 19:07:24 +02:00
parent 2ad0872613
commit f5e3ea281f
3 changed files with 37 additions and 37 deletions

View File

@ -308,9 +308,9 @@ Several functions allow to create specific configurations of darts into a combin
It is often necessary to mark darts, for example to retrieve in <I>O(1)</I> if a given dart was already processed during a specific algorithm, for example, iteration over a given range. Users can also mark specific parts of a combinatorial map (for example mark all the darts belonging to objects having specific semantics). To answer these needs, a `GenericMap` has a certain number of Boolean marks (fixed by the constant \link GenericMap::NB_MARKS `NB_MARKS`\endlink). When one wants to use a Boolean mark, the following methods are available (with `cm` an instance of a combinatorial map):
<ul>
<li> get a new free mark: `size_type m = cm.`\link GenericMap::get_new_mark `get_new_mark()`\endlink (throws the exception Exception_no_more_available_mark if no mark is available);
<li> set mark `m` for a given dart `d0`: `cm.`\link GenericMap::mark `mark(dh0,m)`\endlink;
<li> unset mark `m` for a given dart `d0`: `cm.`\link GenericMap::unmark `unmark(dh0,m)`\endlink;
<li> test if a given dart `d0` is marked for `m`: `cm.`\link GenericMap::is_marked `is_marked(dh0,m)`\endlink;
<li> set mark `m` for a given dart `d0`: `cm.`\link GenericMap::mark `mark(d0,m)`\endlink;
<li> unset mark `m` for a given dart `d0`: `cm.`\link GenericMap::unmark `unmark(d0,m)`\endlink;
<li> test if a given dart `d0` is marked for `m`: `cm.`\link GenericMap::is_marked `is_marked(d0,m)`\endlink;
<li> unmark all the darts of `cm` for `m`: `cm.`\link GenericMap::unmark_all `unmark_all(m)`\endlink;
<li> negate mark `m` of all the darts of `cm`: `cm.`\link GenericMap::negate_mark `negate_mark(m)`\endlink. All the marked darts become unmarked and all the unmarked darts become marked;
<li> free mark `m`: `cm.`\link GenericMap::free_mark `free_mark(m)`\endlink. This method unmarks all the darts of `cm` for `m` before freeing it.
@ -349,7 +349,7 @@ Reciprocally, unlinking a given dart <I>d0</I> by \f$ \beta_i\f$, with 2 \f$ \le
Example of 3-sew operation. Left: A 3D combinatorial map containing two volumes that are not connected, with 2-attributes. Each attribute contains a color in RGB format, and there are four 2-cells associated with attributes. Associations between darts and attributes are drawn with red segments. Right: The 3D combinatorial map obtained as result of \link CombinatorialMap::sew `sew<3>(1,5)`\endlink (or \link CombinatorialMap::sew `sew<3>(2,8)`\endlink, or \link CombinatorialMap::sew `sew<3>(3,7)`\endlink, or \link CombinatorialMap::sew `sew<3>(4,6)`\endlink). Darts (1,5), (2,8), (3,7) and (4,6) are linked together by \f$ \beta_3\f$. The two 2-cells <I>c1</I>={1,2,3,4} and <I>c2</I>={5,6,7,8} are merged after the sew into the 2-cell {1,2,3,4,5,6,7,8}. We are in the case where the two attributes are non `nullptr`, thus the first one is kept, and all the darts of <I>c2</I> are associated with the first attribute.
\cgalFigureEnd
The \link CombinatorialMap::sew `sew<i>(dh1,dh2)`\endlink method consists mainly to link two by two several darts by \f$ \beta_i\f$. This operation is possible only if there is a bijection <I>f</I> between all the darts of the orbit <I>D1</I>=\f$ \langle{}\f$\f$ \beta_1\f$,...,\f$ \beta_{i-2}\f$,\f$ \beta_{i+2}\f$,...,\f$ \beta_d\f$\f$ \rangle{}\f$(<I>d1</I>) and <I>D2</I>=\f$ \langle{}\f$\f$ \beta_1\f$,...,\f$ \beta_{i-2}\f$,\f$ \beta_{i+2}\f$,..., \f$ \beta_d\f$\f$ \rangle{}\f$(<I>d2</I>) satisfying: <I>f</I>(<I>d1</I>)=<I>d2</I>, and for all <I>e</I>\f$ \in \f$ <I>D1</I>, for all <I>j</I>\f$ \in \f${1,..., i-2,i+2,...,<I>d</I>}, <I>f</I>(\f$ \beta_j\f$(<I>e</I>))=\f$ \beta_j^{-1}\f$(<I>f</I>(<I>e</I>)). Intuitively, this condition ensures the validity of the combinatorial map by verifying that condition discussed in Section \ref sseccombimapvalidity "Combinatorial Map Properties" will be satisfied after the operation. This condition can be tested by using the method \link CombinatorialMap::is_sewable `is_sewable<i>(dh1,dh2)`\endlink. For example, the function \link CombinatorialMap::is_sewable `is_sewable<3>`\endlink would return `false` if we tried to 3-sew a triangular facet with a quad facet. Note that given two darts <I>d1</I> and <I>d2</I>, if there is such a bijection, it is uniquely defined. So giving the two darts as arguments of the \link CombinatorialMap::sew `sew<i>`\endlink is enough to retrieve all the pairs of darts to link. If such a bijection exists, the \link CombinatorialMap::sew `sew<i>(dh1,dh2)`\endlink operation consists only in linking by \f$ \beta_i\f$ each couple of darts <I>d3</I> and <I>d4</I> such that <I>d3</I>=<I>f</I>(<I>d4</I>).
The \link CombinatorialMap::sew `sew<i>(d1,d2)`\endlink method consists mainly to link two by two several darts by \f$ \beta_i\f$. This operation is possible only if there is a bijection <I>f</I> between all the darts of the orbit <I>D1</I>=\f$ \langle{}\f$\f$ \beta_1\f$,...,\f$ \beta_{i-2}\f$,\f$ \beta_{i+2}\f$,...,\f$ \beta_d\f$\f$ \rangle{}\f$(<I>d1</I>) and <I>D2</I>=\f$ \langle{}\f$\f$ \beta_1\f$,...,\f$ \beta_{i-2}\f$,\f$ \beta_{i+2}\f$,..., \f$ \beta_d\f$\f$ \rangle{}\f$(<I>d2</I>) satisfying: <I>f</I>(<I>d1</I>)=<I>d2</I>, and for all <I>e</I>\f$ \in \f$ <I>D1</I>, for all <I>j</I>\f$ \in \f${1,..., i-2,i+2,...,<I>d</I>}, <I>f</I>(\f$ \beta_j\f$(<I>e</I>))=\f$ \beta_j^{-1}\f$(<I>f</I>(<I>e</I>)). Intuitively, this condition ensures the validity of the combinatorial map by verifying that condition discussed in Section \ref sseccombimapvalidity "Combinatorial Map Properties" will be satisfied after the operation. This condition can be tested by using the method \link CombinatorialMap::is_sewable `is_sewable<i>(d1,d2)`\endlink. For example, the function \link CombinatorialMap::is_sewable `is_sewable<3>`\endlink would return `false` if we tried to 3-sew a triangular facet with a quad facet. Note that given two darts <I>d1</I> and <I>d2</I>, if there is such a bijection, it is uniquely defined. So giving the two darts as arguments of the \link CombinatorialMap::sew `sew<i>`\endlink is enough to retrieve all the pairs of darts to link. If such a bijection exists, the \link CombinatorialMap::sew `sew<i>(d1,d2)`\endlink operation consists only in linking by \f$ \beta_i\f$ each couple of darts <I>d3</I> and <I>d4</I> such that <I>d3</I>=<I>f</I>(<I>d4</I>).
In addition, the sew operation updates the associations between darts and non void attributes in order to guarantee that all the darts belonging to a given cell are associated with the same attribute (which is a condition of combinatorial map validity). For each couple of <I>j</I>-cells <I>c1</I> and <I>c2</I> that are merged into one <I>j</I>-cell during the sew, we have to update the two associated attributes <I>attr1</I> and <I>attr2</I>. If both are `nullptr`, there is nothing to do. If one is `nullptr` and the other not, we only associate the non `nullptr` attribute to all the darts of the resulting cell. When the two attributes are non `nullptr`, we first apply functor \link CellAttribute::On_merge `On_merge`\endlink on the two attributes <I>attr1</I> and <I>attr2</I> (see Section \ref ssecattributes "Cell Attributes"). Then, we associate the attribute <I>attr1</I> to all darts of the resulting <I>j</I>-cell. Finally, attribute <I>attr2</I> is removed from the combinatorial map.
@ -357,18 +357,18 @@ Note that when the two attributes are non `nullptr`, the first one is kept. But
For example, in \cgalFigureRef{fig_cmap_example_3d_sew}, we want to 3-sew the two initial volumes. \link CombinatorialMap::sew `sew<3>(1,5)`\endlink links by \f$ \beta_3\f$ the pairs of darts (1,5), (2,8), (3,7) and (4,6), thus the combinatorial map obtained is valid. 2-attributes are updated so that all the darts belonging to the 2-cell containing dart 1 become associated to the same 2-attribute after the operation.
Similarly, \link CombinatorialMap::unsew `unsew<i>(dh0)`\endlink operation unlinks \f$ \beta_i\f$ for all the darts in the orbit \f$ \langle{}\f$\f$ \beta_1\f$,..., \f$ \beta_{i-2}\f$,\f$ \beta_{i+2}\f$,...,\f$ \beta_d\f$\f$ \rangle{}\f$(<I>d0</I>), and thus guarantees to obtain a valid combinatorial map. This operation is possible for any non <I>i</I>-free dart.
Similarly, \link CombinatorialMap::unsew `unsew<i>(d0)`\endlink operation unlinks \f$ \beta_i\f$ for all the darts in the orbit \f$ \langle{}\f$\f$ \beta_1\f$,..., \f$ \beta_{i-2}\f$,\f$ \beta_{i+2}\f$,...,\f$ \beta_d\f$\f$ \rangle{}\f$(<I>d0</I>), and thus guarantees to obtain a valid combinatorial map. This operation is possible for any non <I>i</I>-free dart.
As for the sew operations, attributes are updated to guarantee that two darts belonging to two different <I>j</I>-cells are associated to two different <I>j</I>-attributes. If the unsew operation splits a <I>j</I>-cell <I>c</I> in two <I>j</I>-cells <I>c1</I> and <I>c2</I>, and if <I>c</I> is associated to a <I>j</I>-attribute <I>attr1</I>, then this attribute is duplicated into <I>attr2</I>, and all the darts belonging to <I>c2</I> are associated with this new attribute. Finally, we call the functor \link CellAttribute::On_split `On_split`\endlink on the two attributes <I>attr1</I> and <I>attr2</I> (see Section \ref ssecattributes "Cell Attributes").
Let us consider the combinatorial map given in \cgalFigureRef{fig_cmap_example_3d_sew} (Right). If we call \link CombinatorialMap::unsew `unsew<3>(2)`\endlink, we obtain the combinatorial map in \cgalFigureRef{fig_cmap_example_3d_sew} (Left) (except for the color of the attribute associated to the 2-cell {5,6,7,8} which would be <TT>#00ff00</TT>). The \link CombinatorialMap::unsew `unsew<3>`\endlink operation has duplicated the 2-attribute associated to the 2-cell {1,2,3,4,5,6,7,8} since this 2-cell is split in two after the unsew operation.
\cgalAdvancedBegin
If one wants to modify a combinatorial map <I>manually</I>, it is possible to switch off the updating between darts and attributes by calling \link GenericMap::set_automatic_attributes_management `set_automatic_attributes_management(false)`\endlink before to call \link CombinatorialMap::sew `sew<i>(dh1,dh2)`\endlink and \link CombinatorialMap::unsew `unsew<i>(dh0)`\endlink. In these cases, the combinatorial map obtained may be no longer valid due to incorrect associations between darts and attributes. A call later to \link GenericMap::set_automatic_attributes_management `set_automatic_attributes_management(true)`\endlink will correct the invalid non void attributes.
If one wants to modify a combinatorial map <I>manually</I>, it is possible to switch off the updating between darts and attributes by calling \link GenericMap::set_automatic_attributes_management `set_automatic_attributes_management(false)`\endlink before to call \link CombinatorialMap::sew `sew<i>(d1,d2)`\endlink and \link CombinatorialMap::unsew `unsew<i>(d0)`\endlink. In these cases, the combinatorial map obtained may be no longer valid due to incorrect associations between darts and attributes. A call later to \link GenericMap::set_automatic_attributes_management `set_automatic_attributes_management(true)`\endlink will correct the invalid non void attributes.
In \cgalFigureRef{fig_cmap_example_3d_sew} (Left), if we call \link CombinatorialMap::sew `sew<3>(1,5)`\endlink, the resulting combinatorial map is similar to the combinatorial map of \cgalFigureRef{fig_cmap_example_3d_sew} (Right) (we have linked by \f$ \beta_3\f$ the pairs of darts (1,5), (2,8), (3,7) and (4,6)), but associations between darts and attributes are not valid. Indeed, we have kept the four initial attributes and all the associations between darts and attributes, thus two darts belonging to the same 2-cell (for example darts 1 and 5) are associated with two different attributes.
We can also use the \link CombinatorialMap::link_beta `link_beta<i>(dh1,dh2)`\endlink which links `d1` and `d2` by \f$ \beta_i\f$ without modifying the other links. Association between darts and attributes are only modified for darts `d1` and `d2`, and similarly as for \link CombinatorialMap::sew `sew<i>`\endlink, this updating can be avoided by calling \link GenericMap::set_automatic_attributes_management `set_automatic_attributes_management(false)`\endlink before to call \link CombinatorialMap::link_beta `link_beta<i>(dh1,dh2)`\endlink. Lastly, we can use \link CombinatorialMap::unlink_beta `unlink_beta<i>(dh0)`\endlink to unlink `d0` for \f$ \beta_i\f$. In this last case, there is no modification of association between darts and attributes.
We can also use the \link CombinatorialMap::link_beta `link_beta<i>(d1,d2)`\endlink which links `d1` and `d2` by \f$ \beta_i\f$ without modifying the other links. Association between darts and attributes are only modified for darts `d1` and `d2`, and similarly as for \link CombinatorialMap::sew `sew<i>`\endlink, this updating can be avoided by calling \link GenericMap::set_automatic_attributes_management `set_automatic_attributes_management(false)`\endlink before to call \link CombinatorialMap::link_beta `link_beta<i>(d1,d2)`\endlink. Lastly, we can use \link CombinatorialMap::unlink_beta `unlink_beta<i>(d0)`\endlink to unlink `d0` for \f$ \beta_i\f$. In this last case, there is no modification of association between darts and attributes.
In \cgalFigureRef{fig_cmap_example_3d_sew} (Left), if we call \link CombinatorialMap::link_beta `link_beta<3>(1,5)`\endlink, in the resulting combinatorial map we have now \f$ \beta_3\f$(1)=5 and \f$ \beta_3\f$(5)=1. This combinatorial map is no longer valid (for example dart 2 is 3-free and we should have \f$ \beta_3\f$(2)=8).
\cgalAdvancedEnd
@ -377,7 +377,7 @@ In \cgalFigureRef{fig_cmap_example_3d_sew} (Left), if we call \link Combinatoria
The following high level operations are defined. All these methods ensure that given a valid combinatorial map and a possible operation, the modified combinatorial map is also valid.
The first one is `cm.`\link GenericMap::remove_cell `remove_cell<i>(dh0)`\endlink which modifies the combinatorial map to remove the <I>i</I>-cell containing dart `d0`, with 0 \f$ \leq \f$ <I>i</I>\f$ \leq \f$ <I>d</I>. This operation is possible if <I>i</I>=<I>d</I> or if the given <I>i</I>-cell is incident to at most two <I>(i+1)</I>-cells which can be tested thanks to `cm.`\link GenericMap::is_removable `is_removable<i>(dh0)`\endlink. If the removed <I>i</I>-cell was incident to two different <I>(i+1)</I>-cells, these two cells are merged into one <I>(i+1)</I>-cell. In this case, the \link CellAttribute::On_merge `On_merge`\endlink functor is called if two <I>(i+1)</I>-attributes are associated to the two <I>(i+1)</I>-cells. If the <I>i</I>-cell is associated with a non void attribute, it is removed from the combinatorial map (see three examples on \cgalFigureRef{fig_cmap_insert_vertex}, \cgalFigureRef{fig_cmap_insert_edge} and \cgalFigureRef{fig_cmap_insert_facet}).
The first one is `cm.`\link GenericMap::remove_cell `remove_cell<i>(d0)`\endlink which modifies the combinatorial map to remove the <I>i</I>-cell containing dart `d0`, with 0 \f$ \leq \f$ <I>i</I>\f$ \leq \f$ <I>d</I>. This operation is possible if <I>i</I>=<I>d</I> or if the given <I>i</I>-cell is incident to at most two <I>(i+1)</I>-cells which can be tested thanks to `cm.`\link GenericMap::is_removable `is_removable<i>(d0)`\endlink. If the removed <I>i</I>-cell was incident to two different <I>(i+1)</I>-cells, these two cells are merged into one <I>(i+1)</I>-cell. In this case, the \link CellAttribute::On_merge `On_merge`\endlink functor is called if two <I>(i+1)</I>-attributes are associated to the two <I>(i+1)</I>-cells. If the <I>i</I>-cell is associated with a non void attribute, it is removed from the combinatorial map (see three examples on \cgalFigureRef{fig_cmap_insert_vertex}, \cgalFigureRef{fig_cmap_insert_edge} and \cgalFigureRef{fig_cmap_insert_facet}).
\cgalFigureBegin{fig_cmap_insert_vertex,cmap_insert_vertex.svg}
Example of \link GenericMap::insert_cell_0_in_cell_1 `insert_cell_0_in_cell_1`\endlink and \link GenericMap::remove_cell `remove_cell<0>`\endlink operations. Left: Initial combinatorial map. Right: After the insertion of a 0-cell in the 1-cell containing dart `d1`. Now if we remove the 0-cell containing dart `d2`, we obtain the initial combinatorial map.
@ -385,21 +385,21 @@ Example of \link GenericMap::insert_cell_0_in_cell_1 `insert_cell_0_in_cell_1`\e
The inverse operation of the removal is the insertion operation. Several versions exist, sharing a common principle. They consist in adding a new <I>i</I>-cell <em>inside</em> an existing <I>j</I>-cell, <I>i</I>\f$ <\f$<I>j</I>, by splitting the <I>j</I>-cell into several <I>j</I>-cells. Contrary to `remove_cell<i>`, is it not possible to define a unique `insert_cell_i_in_cell_j<i,j>` function because parameters are different depending on `i` and `j`.
`cm.`\link GenericMap::insert_cell_0_in_cell_1 `insert_cell_0_in_cell_1(dh0)`\endlink adds a 0-cell in the 1-cell containing dart `d0`. The 1-cell is split in two. This operation is possible if `d0`\f$ \in \f$ \link GenericMap::darts `cm.darts()`\endlink (see example on \cgalFigureRef{fig_cmap_insert_vertex}).
`cm.`\link GenericMap::insert_cell_0_in_cell_1 `insert_cell_0_in_cell_1(d0)`\endlink adds a 0-cell in the 1-cell containing dart `d0`. The 1-cell is split in two. This operation is possible if `d0`\f$ \in \f$ \link GenericMap::darts `cm.darts()`\endlink (see example on \cgalFigureRef{fig_cmap_insert_vertex}).
`cm.`\link GenericMap::insert_cell_0_in_cell_2 `insert_cell_0_in_cell_2(dh0)`\endlink adds a 0-cell in the 2-cell containing dart `d0`. The 2-cell is split in triangles, one for each initial edge of the facet. This operation is possible if `d0`\f$ \in \f$ \link GenericMap::darts `cm.darts()`\endlink (see example on \cgalFigureRef{fig_cmap_triangulation}).
`cm.`\link GenericMap::insert_cell_0_in_cell_2 `insert_cell_0_in_cell_2(d0)`\endlink adds a 0-cell in the 2-cell containing dart `d0`. The 2-cell is split in triangles, one for each initial edge of the facet. This operation is possible if `d0`\f$ \in \f$ \link GenericMap::darts `cm.darts()`\endlink (see example on \cgalFigureRef{fig_cmap_triangulation}).
\cgalFigureBegin{fig_cmap_triangulation,cmap_triangulation.svg}
Example of \link GenericMap::insert_cell_0_in_cell_2 `insert_cell_0_in_cell_2`\endlink operation.
\cgalFigureEnd
`cm.`\link GenericMap::insert_cell_1_in_cell_2 `insert_cell_1_in_cell_2(dh1,dh2)`\endlink adds a 1-cell in the 2-cell containing darts `d1` and `d2`, between the two 0-cells containing darts `d1` and `d2`. The 2-cell is split in two. This operation is possible if <I>d1</I>\f$ \in \f$ \f$ \langle{}\f$\f$ \beta_1\f$\f$ \rangle{}\f$(<I>d2</I>) which can be tested thanks to `cm.`\link GenericMap::is_insertable_cell_1_in_cell_2 `is_insertable_cell_1_in_cell_2(dh1,dh2)`\endlink. In the example on \cgalFigureRef{fig_cmap_insert_edge}, it is possible to insert an edge between darts <I>d2</I> and <I>d3</I>, but it is not possible to insert an edge between <I>d1</I> and <I>d3</I>.
`cm.`\link GenericMap::insert_cell_1_in_cell_2 `insert_cell_1_in_cell_2(d1,d2)`\endlink adds a 1-cell in the 2-cell containing darts `d1` and `d2`, between the two 0-cells containing darts `d1` and `d2`. The 2-cell is split in two. This operation is possible if <I>d1</I>\f$ \in \f$ \f$ \langle{}\f$\f$ \beta_1\f$\f$ \rangle{}\f$(<I>d2</I>) which can be tested thanks to `cm.`\link GenericMap::is_insertable_cell_1_in_cell_2 `is_insertable_cell_1_in_cell_2(d1,d2)`\endlink. In the example on \cgalFigureRef{fig_cmap_insert_edge}, it is possible to insert an edge between darts <I>d2</I> and <I>d3</I>, but it is not possible to insert an edge between <I>d1</I> and <I>d3</I>.
\cgalFigureBegin{fig_cmap_insert_edge,cmap_insert_edge.svg}
Example of \link GenericMap::insert_cell_1_in_cell_2 `insert_cell_1_in_cell_2`\endlink and \link GenericMap::remove_cell `remove_cell<1>`\endlink operations. Left: Initial combinatorial map. Right: After the insertion of two 1-cells: a first one between the two 0-cells containing darts `d2` and `d3`, and a second one incident to the 0-cell containing dart `d1`. Now if we remove the two 1-cells containing darts `d4` and `d5`, we obtain the initial combinatorial map.
\cgalFigureEnd
`cm.`\link GenericMap::insert_dangling_cell_1_in_cell_2 `insert_dangling_cell_1_in_cell_2(dh0)`\endlink adds a 1-cell in the 2-cell containing dart `d0`, the 1-cell being attached by only one of its vertex to the 0-cell containing dart `d0`. This operation is possible if `d0`\f$ \in \f$ \link GenericMap::darts `cm.darts()`\endlink.
`cm.`\link GenericMap::insert_dangling_cell_1_in_cell_2 `insert_dangling_cell_1_in_cell_2(d0)`\endlink adds a 1-cell in the 2-cell containing dart `d0`, the 1-cell being attached by only one of its vertex to the 0-cell containing dart `d0`. This operation is possible if `d0`\f$ \in \f$ \link GenericMap::darts `cm.darts()`\endlink.
`cm.`\link GenericMap::insert_cell_2_in_cell_3 `insert_cell_2_in_cell_3(itbegin,itend)`\endlink adds a 2-cell in the 3-cell containing all the darts between `itbegin` and `itend`, along the path of 1-cells containing darts in [`itbegin`,`itend`). The 3-cell is split in two. This operation is possible if all the darts in [`itbegin`,`itend`) form a closed path inside a same 3-cell which can be tested thanks to `cm.`\link GenericMap::is_insertable_cell_2_in_cell_3 `is_insertable_cell_2_in_cell_3(itbegin,itend)`\endlink (see example on \cgalFigureRef{fig_cmap_insert_facet}).
@ -416,7 +416,7 @@ If \link GenericMap::set_automatic_attributes_management `set_automatic_attribut
\subsection ssecexample3DCM A 3D Combinatorial Map
In this example, a 3-dimensional combinatorial map is constructed. Two combinatorial tetrahedra are created, then the numbers of cells of the combinatorial map are displayed, and the validity of the combinatorial map is checked. Then, we illustrate the use of ranges to iterate over specific darts. The first loop enumerates all the darts of the first tetrahedron by using the range \link GenericMap::Dart_of_orbit_range `Dart_of_orbit_range<1,2>`\endlink, and the second loop enumerates all the darts of the facet containing dart `dh2` by using the range \link GenericMap::Dart_of_orbit_range `Dart_of_orbit_range<1>`\endlink.
In this example, a 3-dimensional combinatorial map is constructed. Two combinatorial tetrahedra are created, then the numbers of cells of the combinatorial map are displayed, and the validity of the combinatorial map is checked. Then, we illustrate the use of ranges to iterate over specific darts. The first loop enumerates all the darts of the first tetrahedron by using the range \link GenericMap::Dart_of_orbit_range `Dart_of_orbit_range<1,2>`\endlink, and the second loop enumerates all the darts of the facet containing dart `d2` by using the range \link GenericMap::Dart_of_orbit_range `Dart_of_orbit_range<1>`\endlink.
\cgalExample{Combinatorial_map/map_3_simple_example.cpp}
@ -424,18 +424,18 @@ The output is:
\verbatim
#Darts=24, #0-cells=8, #1-cells=12, #2-cells=8, #3-cells=2, #ccs=2, valid=1
Number of darts of the first tetrahedron: 12
Number of darts of the facet containing dh2: 3
Number of darts of the facet containing d2: 3
\endverbatim
which gives the number of darts of the combinatorial map, the numbers of different cells, the number of connected components, and finally a Boolean showing the validity of the combinatorial map (a tetrahedron is made up of 12 darts because there are 3 darts per facet and there are 4 facets).
Note the creation in the for loops of the two instances of \link GenericMap::Dart_of_orbit_range `Dart_of_orbit_range`\endlink::`const_iterator`: `it` is the current iterator, and `itend` an iterator to the end of the range. Having `itend` avoids calling \link GenericMap::darts_of_orbit `cm.darts_of_orbit<1,2>(dh1)`\endlink`.end()` again and again as in the following example (which is a bad solution):
Note the creation in the for loops of the two instances of \link GenericMap::Dart_of_orbit_range `Dart_of_orbit_range`\endlink::`const_iterator`: `it` is the current iterator, and `itend` an iterator to the end of the range. Having `itend` avoids calling \link GenericMap::darts_of_orbit `cm.darts_of_orbit<1,2>(d1)`\endlink`.end()` again and again as in the following example (which is a bad solution):
\code{.cpp}
for (CMap_3::Dart_of_orbit_range<1,2>::const_iterator
it(cm.darts_of_orbit<1,2>(dh1).begin());
it!=cm.darts_of_orbit<1,2>(dh1).end()); ++it)
it(cm.darts_of_orbit<1,2>(d1).begin());
it!=cm.darts_of_orbit<1,2>(d1).end()); ++it)
{...}
\endcode

View File

@ -307,9 +307,9 @@ Several functions allow to create specific configurations of darts into a genera
It is often necessary to mark darts, for example to retrieve in <I>O(1)</I> if a given dart was already processed during a specific algorithm, for example, iteration over a given range. Users can also mark specific parts of a generalized map (for example mark all the darts belonging to objects having specific semantics). To answer these needs, a `GeneralizedMap` has a certain number of Boolean marks (fixed by the constant \link GenericMap::NB_MARKS `NB_MARKS`\endlink). When one wants to use a Boolean mark, the following methods are available (with `gm` an instance of a generalized map):
<ul>
<li> get a new free mark: `size_type m = gm.`\link GenericMap::get_new_mark `get_new_mark()`\endlink (throws the exception Exception_no_more_available_mark if no mark is available);
<li> set mark `m` for a given dart `d0`: `gm.`\link GenericMap::mark `mark(dh0,m)`\endlink;
<li> unset mark `m` for a given dart `d0`: `gm.`\link GenericMap::unmark `unmark(dh0,m)`\endlink;
<li> test if a given dart `d0` is marked for `m`: `gm.`\link GenericMap::is_marked `is_marked(dh0,m)`\endlink;
<li> set mark `m` for a given dart `d0`: `gm.`\link GenericMap::mark `mark(d0,m)`\endlink;
<li> unset mark `m` for a given dart `d0`: `gm.`\link GenericMap::unmark `unmark(d0,m)`\endlink;
<li> test if a given dart `d0` is marked for `m`: `gm.`\link GenericMap::is_marked `is_marked(d0,m)`\endlink;
<li> unmark all the darts of `gm` for `m`: `gm.`\link GenericMap::unmark_all `unmark_all(m)`\endlink;
<li> negate mark `m` of all the darts of `gm`: `gm.`\link GenericMap::negate_mark `negate_mark(m)`\endlink. All the marked darts become unmarked and all the unmarked darts become marked;
<li> free mark `m`: `gm.`\link GenericMap::free_mark `free_mark(m)`\endlink. This method unmarks all the darts of `gm` for `m` before freeing it.
@ -348,7 +348,7 @@ Reciprocally, unlinking a given dart <I>d0</I> by \f$ \alpha_i\f$, with 0 \f$ \l
Example of 3-sew operation. Left: A 3D generalized map containing two volumes that are not connected, with 2-attributes. Each attribute contains a color in RGB format, and there are four 2-cells associated with attributes. Associations between darts and attributes are drawn with red segments. Right: The 3D generalized map obtained as result of \link GeneralizedMap::sew `sew<3>(1,a)`\endlink (or \link GeneralizedMap::sew `sew<3>(2,b)`\endlink ... or \link GeneralizedMap::sew `sew<3>(8,h)`\endlink). Darts (1,a), ..., (8,h) are linked together by \f$ \alpha_3\f$. The two 2-cells <I>c1</I>={1,...,8} and <I>c2</I>={a,...,h} are merged after the sew into the 2-cell {1,...,8,a,...,h}. We are in the case where the two attributes are non `nullptr`, thus the first one is kept, and all the darts of <I>c2</I> are associated with the first attribute.
\cgalFigureEnd
The \link GeneralizedMap::sew `sew<i>(dh1,dh2)`\endlink method consists mainly to link two by two several darts by \f$ \alpha_i\f$. This operation is possible only if there is a bijection <I>f</I> between all the darts of the orbit <I>D1</I>=\f$ \langle{}\f$\f$ \alpha_1\f$,...,\f$ \alpha_{i-2}\f$,\f$ \alpha_{i+2}\f$,...,\f$ \alpha_d\f$\f$ \rangle{}\f$(<I>d1</I>) and <I>D2</I>=\f$ \langle{}\f$\f$ \alpha_1\f$,...,\f$ \alpha_{i-2}\f$,\f$ \alpha_{i+2}\f$,..., \f$ \alpha_d\f$\f$ \rangle{}\f$(<I>d2</I>) satisfying: <I>f</I>(<I>d1</I>)=<I>d2</I>, and for all <I>e</I> \f$ \in \f$ <I>D1</I>, for all <I>j</I> \f$ \in \f$ {1,..., i-2,i+2,...,<I>d</I>}, <I>f</I>(\f$ \alpha_j\f$(<I>e</I>))=\f$ \alpha_j^{-1}\f$(<I>f</I>(<I>e</I>)). Intuitively, this condition ensures the validity of the generalized map by verifying that condition discussed in Section \ref ssecgenmapvalidity "Generalized Map Properties" will be satisfied after the operation. This condition can be tested by using the method \link GeneralizedMap::is_sewable `is_sewable<i>(dh1,dh2)`\endlink. For example, the function \link GeneralizedMap::is_sewable `is_sewable<3>`\endlink would return `false` if we tried to 3-sew a triangular facet with a quad facet. Note that given two darts <I>d1</I> and <I>d2</I>, if there is such a bijection, it is uniquely defined. So giving the two darts as arguments of the \link GeneralizedMap::sew `sew<i>`\endlink is enough to retrieve all the pairs of darts to link. If such a bijection exists, the \link GeneralizedMap::sew `sew<i>(dh1,dh2)`\endlink operation consists only in linking by \f$ \alpha_i\f$ each couple of darts <I>d3</I> and <I>d4</I> such that <I>d3</I>=<I>f</I>(<I>d4</I>).
The \link GeneralizedMap::sew `sew<i>(d1,d2)`\endlink method consists mainly to link two by two several darts by \f$ \alpha_i\f$. This operation is possible only if there is a bijection <I>f</I> between all the darts of the orbit <I>D1</I>=\f$ \langle{}\f$\f$ \alpha_1\f$,...,\f$ \alpha_{i-2}\f$,\f$ \alpha_{i+2}\f$,...,\f$ \alpha_d\f$\f$ \rangle{}\f$(<I>d1</I>) and <I>D2</I>=\f$ \langle{}\f$\f$ \alpha_1\f$,...,\f$ \alpha_{i-2}\f$,\f$ \alpha_{i+2}\f$,..., \f$ \alpha_d\f$\f$ \rangle{}\f$(<I>d2</I>) satisfying: <I>f</I>(<I>d1</I>)=<I>d2</I>, and for all <I>e</I> \f$ \in \f$ <I>D1</I>, for all <I>j</I> \f$ \in \f$ {1,..., i-2,i+2,...,<I>d</I>}, <I>f</I>(\f$ \alpha_j\f$(<I>e</I>))=\f$ \alpha_j^{-1}\f$(<I>f</I>(<I>e</I>)). Intuitively, this condition ensures the validity of the generalized map by verifying that condition discussed in Section \ref ssecgenmapvalidity "Generalized Map Properties" will be satisfied after the operation. This condition can be tested by using the method \link GeneralizedMap::is_sewable `is_sewable<i>(d1,d2)`\endlink. For example, the function \link GeneralizedMap::is_sewable `is_sewable<3>`\endlink would return `false` if we tried to 3-sew a triangular facet with a quad facet. Note that given two darts <I>d1</I> and <I>d2</I>, if there is such a bijection, it is uniquely defined. So giving the two darts as arguments of the \link GeneralizedMap::sew `sew<i>`\endlink is enough to retrieve all the pairs of darts to link. If such a bijection exists, the \link GeneralizedMap::sew `sew<i>(d1,d2)`\endlink operation consists only in linking by \f$ \alpha_i\f$ each couple of darts <I>d3</I> and <I>d4</I> such that <I>d3</I>=<I>f</I>(<I>d4</I>).
In addition, the sew operation updates the associations between darts and non void attributes in order to guarantee that all the darts belonging to a given cell are associated with the same attribute (which is a condition of generalized map validity). For each couple of <I>j</I>-cells <I>c1</I> and <I>c2</I> that are merged into one <I>j</I>-cell during the sew, we have to update the two associated attributes <I>attr1</I> and <I>attr2</I>. If both are `nullptr`, there is nothing to do. If one is `nullptr` and the other not, we only associate the non `nullptr` attribute to all the darts of the resulting cell. When the two attributes are non `nullptr`, we first apply functor \link CellAttribute::On_merge `On_merge`\endlink on the two attributes <I>attr1</I> and <I>attr2</I> (see Section \ref ssecattributesgmap "Cell Attributes"). Then, we associate the attribute <I>attr1</I> to all darts of the resulting <I>j</I>-cell. Finally, attribute <I>attr2</I> is removed from the generalized map.
@ -356,18 +356,18 @@ Note that when the two attributes are non `nullptr`, the first one is kept. But
For example, in \cgalFigureRef{fig_gmap_example_3d_sew}, we want to 3-sew the two initial volumes. \link GeneralizedMap::sew `sew<3>(1,a)`\endlink links by \f$ \alpha_3\f$ the pairs of darts (1,a), ..., (8,g), thus the generalized map obtained is valid. 2-attributes are updated so that all the darts belonging to the 2-cell containing dart 1 become associated to the same 2-attribute after the operation.
Similarly, \link GeneralizedMap::unsew `unsew<i>(dh0)`\endlink operation unlinks \f$ \alpha_i\f$ for all the darts in the orbit \f$ \langle{}\f$\f$ \alpha_1\f$,..., \f$ \alpha_{i-2}\f$,\f$ \alpha_{i+2}\f$,...,\f$ \alpha_d\f$\f$ \rangle{}\f$(<I>d0</I>), and thus guarantees to obtain a valid generalized map. This operation is possible for any non <I>i</I>-free dart.
Similarly, \link GeneralizedMap::unsew `unsew<i>(d0)`\endlink operation unlinks \f$ \alpha_i\f$ for all the darts in the orbit \f$ \langle{}\f$\f$ \alpha_1\f$,..., \f$ \alpha_{i-2}\f$,\f$ \alpha_{i+2}\f$,...,\f$ \alpha_d\f$\f$ \rangle{}\f$(<I>d0</I>), and thus guarantees to obtain a valid generalized map. This operation is possible for any non <I>i</I>-free dart.
As for the sew operations, attributes are updated to guarantee that two darts belonging to two different <I>j</I>-cells are associated to two different <I>j</I>-attributes. If the unsew operation splits a <I>j</I>-cell <I>c</I> in two <I>j</I>-cells <I>c1</I> and <I>c2</I>, and if <I>c</I> is associated to a <I>j</I>-attribute <I>attr1</I>, then this attribute is duplicated into <I>attr2</I>, and all the darts belonging to <I>c2</I> are associated with this new attribute. Finally, we call the functor \link CellAttribute::On_split `On_split`\endlink on the two attributes <I>attr1</I> and <I>attr2</I> (see Section \ref ssecattributesgmap "Cell Attributes").
Let us consider the generalized map given in \cgalFigureRef{fig_gmap_example_3d_sew} (Right). If we call \link GeneralizedMap::unsew `unsew<3>(1)`\endlink, we obtain the generalized map in \cgalFigureRef{fig_gmap_example_3d_sew} (Left) (except for the color of the attribute associated to the 2-cell {a,...,g} which would be <TT>#00ff00</TT>). The \link GeneralizedMap::unsew `unsew<3>`\endlink operation has duplicated the 2-attribute associated to the initial 2-cell {1,...,8,a,...,g} since this 2-cell is split in two after the unsew operation.
\cgalAdvancedBegin
If one wants to modify a generalized map <I>manually</I>, it is possible to switch off the updating between darts and attributes by calling \link GenericMap::set_automatic_attributes_management `set_automatic_attributes_management(false)`\endlink before to call \link GeneralizedMap::sew `sew<i>(dh1,dh2)`\endlink and \link GeneralizedMap::unsew `unsew<i>(dh0)`\endlink. In these cases, the generalized map obtained may be no longer valid due to incorrect associations between darts and attributes. A call later to \link GenericMap::set_automatic_attributes_management `set_automatic_attributes_management(true)`\endlink will correct the invalid non void attributes.
If one wants to modify a generalized map <I>manually</I>, it is possible to switch off the updating between darts and attributes by calling \link GenericMap::set_automatic_attributes_management `set_automatic_attributes_management(false)`\endlink before to call \link GeneralizedMap::sew `sew<i>(d1,d2)`\endlink and \link GeneralizedMap::unsew `unsew<i>(d0)`\endlink. In these cases, the generalized map obtained may be no longer valid due to incorrect associations between darts and attributes. A call later to \link GenericMap::set_automatic_attributes_management `set_automatic_attributes_management(true)`\endlink will correct the invalid non void attributes.
In \cgalFigureRef{fig_gmap_example_3d_sew} (Left), if we call \link GeneralizedMap::sew `sew<3>(1,5)`\endlink, the resulting generalized map is similar to the generalized map of \cgalFigureRef{fig_gmap_example_3d_sew} (Right) (we have linked by \f$ \alpha_3\f$ the pairs of darts (1,a), ..., (8,g), but associations between darts and attributes are not valid. Indeed, we have kept the four initial attributes and all the associations between darts and attributes, thus two darts belonging to the same 2-cell (for example darts 1 and a) are associated with two different attributes.
We can also use the \link GeneralizedMap::link_alpha `link_alpha<i>(dh1,dh2)`\endlink which links `d1` and `d2` by \f$ \alpha_i\f$ without modifying the other links. Association between darts and attributes are only modified for darts `d1` and `d2`, and similarly as for \link GeneralizedMap::sew `sew<i>`\endlink, this updating can be avoided by calling \link GenericMap::set_automatic_attributes_management `set_automatic_attributes_management(false)`\endlink before to call \link GeneralizedMap::link_alpha `link_alpha<i>(dh1,dh2)`\endlink. Lastly, we can use \link GeneralizedMap::unlink_alpha `unlink_alpha<i>(dh0)`\endlink to unlink `d0` for \f$ \alpha_i\f$. In this last case, there is no modification of association between darts and attributes.
We can also use the \link GeneralizedMap::link_alpha `link_alpha<i>(d1,d2)`\endlink which links `d1` and `d2` by \f$ \alpha_i\f$ without modifying the other links. Association between darts and attributes are only modified for darts `d1` and `d2`, and similarly as for \link GeneralizedMap::sew `sew<i>`\endlink, this updating can be avoided by calling \link GenericMap::set_automatic_attributes_management `set_automatic_attributes_management(false)`\endlink before to call \link GeneralizedMap::link_alpha `link_alpha<i>(d1,d2)`\endlink. Lastly, we can use \link GeneralizedMap::unlink_alpha `unlink_alpha<i>(d0)`\endlink to unlink `d0` for \f$ \alpha_i\f$. In this last case, there is no modification of association between darts and attributes.
In \cgalFigureRef{fig_gmap_example_3d_sew} (Left), if we call \link GeneralizedMap::link_alpha `link_alpha<3>(1,a)`\endlink, in the resulting generalized map we have now \f$ \alpha_3\f$(1)=a and \f$ \alpha_3\f$(a)=1. This generalized map is no longer valid (for example dart 2 is 3-free and we should have \f$ \alpha_3\f$(2)=b).
\cgalAdvancedEnd
@ -382,7 +382,7 @@ Illustration of the use of the 2-sew operation to construct a non-orientable gen
The following high level operations are defined. All these methods ensure that given a valid generalized map and a possible operation, the modified generalized map is also valid.
The first one is `gm`.\link GenericMap::remove_cell `remove_cell<i>(dh0)`\endlink which modifies the generalized map to remove the <I>i</I>-cell containing dart `d0`, with 0 \f$ \leq \f$ <I>i</I> \f$ \leq \f$ <I>d</I>. This operation is possible if <I>i</I>=<I>d</I> or if the given <I>i</I>-cell is incident to at most two <I>(i+1)</I>-cells which can be tested thanks to `gm.`\link GenericMap::is_removable `is_removable<i>(dh0)`\endlink. If the removed <I>i</I>-cell was incident to two different <I>(i+1)</I>-cells, these two cells are merged into one <I>(i+1)</I>-cell. In this case, the \link CellAttribute::On_merge `On_merge`\endlink functor is called if two <I>(i+1)</I>-attributes are associated to the two <I>(i+1)</I>-cells. If the <I>i</I>-cell is associated with a non void attribute, it is removed from the generalized map (see three examples on \cgalFigureRef{fig_gmap_insert_vertex}, \cgalFigureRef{fig_gmap_insert_edge} and \cgalFigureRef{fig_gmap_insert_facet}).
The first one is `gm`.\link GenericMap::remove_cell `remove_cell<i>(d0)`\endlink which modifies the generalized map to remove the <I>i</I>-cell containing dart `d0`, with 0 \f$ \leq \f$ <I>i</I> \f$ \leq \f$ <I>d</I>. This operation is possible if <I>i</I>=<I>d</I> or if the given <I>i</I>-cell is incident to at most two <I>(i+1)</I>-cells which can be tested thanks to `gm.`\link GenericMap::is_removable `is_removable<i>(d0)`\endlink. If the removed <I>i</I>-cell was incident to two different <I>(i+1)</I>-cells, these two cells are merged into one <I>(i+1)</I>-cell. In this case, the \link CellAttribute::On_merge `On_merge`\endlink functor is called if two <I>(i+1)</I>-attributes are associated to the two <I>(i+1)</I>-cells. If the <I>i</I>-cell is associated with a non void attribute, it is removed from the generalized map (see three examples on \cgalFigureRef{fig_gmap_insert_vertex}, \cgalFigureRef{fig_gmap_insert_edge} and \cgalFigureRef{fig_gmap_insert_facet}).
\cgalFigureBegin{fig_gmap_insert_vertex,gmap_insert_vertex.svg}
@ -391,21 +391,21 @@ Example of \link GenericMap::insert_cell_0_in_cell_1 `insert_cell_0_in_cell_1`\e
The inverse operation of the removal is the insertion operation. Several versions exist, sharing a common principle. They consist in adding a new <I>i</I>-cell <em>inside</em> an existing <I>j</I>-cell, <I>i</I> \f$ < \f$<I>j</I>, by splitting the <I>j</I>-cell into several <I>j</I>-cells. Contrary to `remove_cell<i>`, is it not possible to define a unique `insert_cell_i_in_cell_j<i,j>` function because parameters are different depending on `i` and `j`.
`gm.`\link GenericMap::insert_cell_0_in_cell_1 `insert_cell_0_in_cell_1(dh0)`\endlink adds a 0-cell in the 1-cell containing dart `d0`. The 1-cell is split in two. This operation is possible if `d0` \f$ \in \f$ \link GenericMap::darts `gm.darts()`\endlink (see example on \cgalFigureRef{fig_gmap_insert_vertex}).
`gm.`\link GenericMap::insert_cell_0_in_cell_1 `insert_cell_0_in_cell_1(d0)`\endlink adds a 0-cell in the 1-cell containing dart `d0`. The 1-cell is split in two. This operation is possible if `d0` \f$ \in \f$ \link GenericMap::darts `gm.darts()`\endlink (see example on \cgalFigureRef{fig_gmap_insert_vertex}).
`gm.`\link GenericMap::insert_cell_0_in_cell_2 `insert_cell_0_in_cell_2(dh0)`\endlink adds a 0-cell in the 2-cell containing dart `d0`. The 2-cell is split in triangles, one for each initial edge of the facet. This operation is possible if `d0` \f$ \in \f$ \link GenericMap::darts `gm.darts()`\endlink (see example on \cgalFigureRef{fig_gmap_triangulation}).
`gm.`\link GenericMap::insert_cell_0_in_cell_2 `insert_cell_0_in_cell_2(d0)`\endlink adds a 0-cell in the 2-cell containing dart `d0`. The 2-cell is split in triangles, one for each initial edge of the facet. This operation is possible if `d0` \f$ \in \f$ \link GenericMap::darts `gm.darts()`\endlink (see example on \cgalFigureRef{fig_gmap_triangulation}).
\cgalFigureBegin{fig_gmap_triangulation,gmap_triangulation.svg}
Example of \link GenericMap::insert_cell_0_in_cell_2 `insert_cell_0_in_cell_2`\endlink operation.
\cgalFigureEnd
`gm.`\link GenericMap::insert_cell_1_in_cell_2 `insert_cell_1_in_cell_2(dh1,dh2)`\endlink adds a 1-cell in the 2-cell containing darts `d1` and `d2`, between the two 0-cells containing darts `d1` and `d2`. The 2-cell is split in two. This operation is possible if <I>d1</I> \f$ \in \f$ \f$ \langle{}\f$\f$ \alpha_0, \alpha_1\f$\f$ \rangle{}\f$(<I>d2</I>) which can be tested thanks to `gm.`\link GenericMap::is_insertable_cell_1_in_cell_2 `is_insertable_cell_1_in_cell_2(dh1,dh2)`\endlink. In the example on \cgalFigureRef{fig_gmap_insert_edge}, it is possible to insert an edge between darts <I>d2</I> and <I>d3</I>, but it is not possible to insert an edge between <I>d1</I> and <I>d3</I>.
`gm.`\link GenericMap::insert_cell_1_in_cell_2 `insert_cell_1_in_cell_2(d1,d2)`\endlink adds a 1-cell in the 2-cell containing darts `d1` and `d2`, between the two 0-cells containing darts `d1` and `d2`. The 2-cell is split in two. This operation is possible if <I>d1</I> \f$ \in \f$ \f$ \langle{}\f$\f$ \alpha_0, \alpha_1\f$\f$ \rangle{}\f$(<I>d2</I>) which can be tested thanks to `gm.`\link GenericMap::is_insertable_cell_1_in_cell_2 `is_insertable_cell_1_in_cell_2(d1,d2)`\endlink. In the example on \cgalFigureRef{fig_gmap_insert_edge}, it is possible to insert an edge between darts <I>d2</I> and <I>d3</I>, but it is not possible to insert an edge between <I>d1</I> and <I>d3</I>.
\cgalFigureBegin{fig_gmap_insert_edge,gmap_insert_edge.svg}
Example of \link GenericMap::insert_cell_1_in_cell_2 `insert_cell_1_in_cell_2`\endlink and \link GenericMap::remove_cell `remove_cell<1>`\endlink operations. Left: Initial generalized map. Right: After the insertion of two 1-cells: a first one between the two 0-cells containing darts `d2` and `d3`, and a second one incident to the 0-cell containing dart `d1`. Now if we remove the two 1-cells containing darts `d4` and `d5`, we obtain the initial generalized map.
\cgalFigureEnd
`gm.`\link GenericMap::insert_dangling_cell_1_in_cell_2 `insert_dangling_cell_1_in_cell_2(dh0)`\endlink adds a 1-cell in the 2-cell containing dart `d0`, the 1-cell being attached by only one of its vertex to the 0-cell containing dart `d0`. This operation is possible if `d0` \f$ \in \f$ \link GenericMap::darts `gm.darts()`\endlink.
`gm.`\link GenericMap::insert_dangling_cell_1_in_cell_2 `insert_dangling_cell_1_in_cell_2(d0)`\endlink adds a 1-cell in the 2-cell containing dart `d0`, the 1-cell being attached by only one of its vertex to the 0-cell containing dart `d0`. This operation is possible if `d0` \f$ \in \f$ \link GenericMap::darts `gm.darts()`\endlink.
`gm.`\link GenericMap::insert_cell_2_in_cell_3 `insert_cell_2_in_cell_3(itbegin,itend)`\endlink adds a 2-cell in the 3-cell containing all the darts between `itbegin` and `itend`, along the path of 1-cells containing darts in [`itbegin`,`itend`). The 3-cell is split in two. This operation is possible if all the darts in [`itbegin`,`itend`) form a closed path inside a same 3-cell which can be tested thanks to `gm.`\link GenericMap::is_insertable_cell_2_in_cell_3 `is_insertable_cell_2_in_cell_3(itbegin,itend)`\endlink (see example on \cgalFigureRef{fig_gmap_insert_facet}).
@ -425,7 +425,7 @@ If \link GenericMap::set_automatic_attributes_management `set_automatic_attribut
\subsection ssecexample3DGM A 3D Generalized Map
In this example, a 3-dimensional generalized map is constructed. Two combinatorial tetrahedra are created, then the numbers of cells of the generalized map are displayed, and the validity of the generalized map is checked. Then, we illustrate the use of ranges to iterate over specific darts. The first loop enumerates all the darts of the first tetrahedron by using the range \link GenericMap::Dart_of_orbit_range `Dart_of_orbit_range<0,1,2>`\endlink, and the second loop enumerates all the darts of the facet containing dart `dh2` by using the range \link GenericMap::Dart_of_orbit_range `Dart_of_orbit_range<0,1>`\endlink.
In this example, a 3-dimensional generalized map is constructed. Two combinatorial tetrahedra are created, then the numbers of cells of the generalized map are displayed, and the validity of the generalized map is checked. Then, we illustrate the use of ranges to iterate over specific darts. The first loop enumerates all the darts of the first tetrahedron by using the range \link GenericMap::Dart_of_orbit_range `Dart_of_orbit_range<0,1,2>`\endlink, and the second loop enumerates all the darts of the facet containing dart `d2` by using the range \link GenericMap::Dart_of_orbit_range `Dart_of_orbit_range<0,1>`\endlink.
\cgalExample{Generalized_map/gmap_3_simple_example.cpp}
@ -438,13 +438,13 @@ Number of darts of the face incident to d1: 6
which gives the number of darts of the generalized map, the numbers of different cells, the number of connected components, a Boolean showing if the generalized map is orientable or not and finally a Boolean showing the validity of the generalized map (a tetrahedron is made up of 48 darts because there are 12 darts per facet and there are 4 facets).
Note the creation in the for loops of the two instances of \link GenericMap::Dart_of_orbit_range `Dart_of_orbit_range`\endlink::`const_iterator`: `it` is the current iterator, and `itend` an iterator to the end of the range. Having `itend` avoids calling \link GenericMap::darts_of_orbit `gm.darts_of_orbit<0,1,2>(dh1)`\endlink`.end()` again and again as in the following example (which is a bad solution):
Note the creation in the for loops of the two instances of \link GenericMap::Dart_of_orbit_range `Dart_of_orbit_range`\endlink::`const_iterator`: `it` is the current iterator, and `itend` an iterator to the end of the range. Having `itend` avoids calling \link GenericMap::darts_of_orbit `gm.darts_of_orbit<0,1,2>(d1)`\endlink`.end()` again and again as in the following example (which is a bad solution):
\code{.cpp}
for (GMap_3::Dart_of_orbit_range<0,1,2>::const_iterator
it(gm.darts_of_orbit<0,1,2>(dh1).begin());
it!=gm.darts_of_orbit<0,1,2>(dh1).end()); ++it)
it(gm.darts_of_orbit<0,1,2>(d1).begin());
it!=gm.darts_of_orbit<0,1,2>(d1).end()); ++it)
{...}
\endcode

View File

@ -114,22 +114,22 @@ Lastly, the function \link ::import_from_plane_graph `import_from_plane_graph(lc
\subsection Linear_cell_complexModificationOperations Modification Operations
\anchor ssecmodifop
Some methods are defined in `LinearCellComplex` to modify a linear cell complex and update the vertex attributes. In the following, we denote by `dh0`, `dh1`, `dh2` the dart handles for the darts `d0`, `d1`, `d2`, respectively. That is `d0 == *dh0`.
Some methods are defined in `LinearCellComplex` to modify a linear cell complex and update the vertex attributes. \tred{In the following, we denote by `d0`, `d1`, `d2` for three dart descriptors.}
\cgalFigureBegin{fig_lcc_insert_vertex,lcc_insert_vertex.svg}
Example of \link LinearCellComplex::insert_barycenter_in_cell `insert_barycenter_in_cell<1>`\endlink and `remove_cell<0>` operations. <B>Left</B>: Initial linear cell complex. <B>Right</B>: After the insertion of a point in the barycenter of the 1-cell containing dart <I>d1</I>. Now if we remove the 0-cell containing dart <I>d2</I>, we obtain a linear cell complex isomorphic to the initial one.
\cgalFigureEnd
\link LinearCellComplex::insert_barycenter_in_cell `lcc.insert_barycenter_in_cell<unsigned int i>(dh0)`\endlink adds the barycenter of the <I>i</I>-cell containing dart `d0`. This operation is possible if `d0`\f$ \in\f$\link GenericMap::darts `lcc.darts()`\endlink (see examples on \cgalFigureRef{fig_lcc_insert_vertex} and \cgalFigureRef{fig_lcc_triangulation}).
\link LinearCellComplex::insert_barycenter_in_cell `lcc.insert_barycenter_in_cell<unsigned int i>(d0)`\endlink adds the barycenter of the <I>i</I>-cell containing dart `d0`. This operation is possible if `d0`\f$ \in\f$\link GenericMap::darts `lcc.darts()`\endlink (see examples on \cgalFigureRef{fig_lcc_insert_vertex} and \cgalFigureRef{fig_lcc_triangulation}).
\link LinearCellComplex::insert_point_in_cell `lcc.insert_point_in_cell<unsigned int i>(dh0,p)`\endlink is an operation similar to the previous operation, the only difference being that the coordinates of the new point are here given by `p` instead of being computed as the barycenter of the <I>i</I>-cell. Currently, these two operations are only defined for `i=1` to insert a point in an edge, or `i=2` to insert a point in a facet.
\link LinearCellComplex::insert_point_in_cell `lcc.insert_point_in_cell<unsigned int i>(d0,p)`\endlink is an operation similar to the previous operation, the only difference being that the coordinates of the new point are here given by `p` instead of being computed as the barycenter of the <I>i</I>-cell. Currently, these two operations are only defined for `i=1` to insert a point in an edge, or `i=2` to insert a point in a facet.
\cgalFigureBegin{fig_lcc_triangulation,lcc_triangulation.svg}
Examples of \link LinearCellComplex::insert_barycenter_in_cell `insert_barycenter_in_cell<2>`\endlink operation.
\cgalFigureEnd
\link LinearCellComplex::insert_dangling_cell_1_in_cell_2 `lcc.insert_dangling_cell_1_in_cell_2(dh0,p)`\endlink adds a 1-cell in the 2-cell containing dart `d0`, the 1-cell being attached by only one of its vertex to the 0-cell containing dart `d0`. The second vertex of the new edge is associated with a new 0-attribute containing a copy of `p` as point. This operation is possible if `d0`\f$ \in\f$\link GenericMap::darts `lcc.darts()`\endlink (see example on \cgalFigureRef{fig_lcc_insert_edge}).
\link LinearCellComplex::insert_dangling_cell_1_in_cell_2 `lcc.insert_dangling_cell_1_in_cell_2(d0,p)`\endlink adds a 1-cell in the 2-cell containing dart `d0`, the 1-cell being attached by only one of its vertex to the 0-cell containing dart `d0`. The second vertex of the new edge is associated with a new 0-attribute containing a copy of `p` as point. This operation is possible if `d0`\f$ \in\f$\link GenericMap::darts `lcc.darts()`\endlink (see example on \cgalFigureRef{fig_lcc_insert_edge}).
\cgalFigureBegin{fig_lcc_insert_edge,lcc_insert_edge.svg}
Example of \link LinearCellComplex::insert_dangling_cell_1_in_cell_2 `insert_dangling_cell_1_in_cell_2`\endlink, `insert_cell_1_in_cell_2` and `remove_cell<1>` operations. <B>Left</B>: Initial linear cell complex. <B>Right</B>: After the insertion of a dangling 1-cell in the 2-cell containing dart <I>d1</I>, and of a 1-cell in the 2-cell containing dart <I>d2</I>. Now if we remove the 1-cells containing dart <I>d4</I> and <I>d5</I>, we obtain a linear cell complex isomorphic to the initial one.