Merging r58475 through r58700 from trunk into soc-2013-depsgraph_mt
[blender.git] / source / blender / bmesh / tools / bmesh_triangulate.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor(s): Joseph Eagar
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  */
22
23 /** \file blender/bmesh/tools/bmesh_triangulate.c
24  *  \ingroup bmesh
25  *
26  * Triangulate.
27  *
28  */
29
30 #include "MEM_guardedalloc.h"
31
32 #include "BLI_utildefines.h"
33 #include "BLI_alloca.h"
34
35 #include "bmesh.h"
36
37 #include "bmesh_triangulate.h"  /* own include */
38
39 /**
40  * a version of #BM_face_triangulate that maps to #BMOpSlot
41  */
42 static void bm_face_triangulate_mapping(BMesh *bm, BMFace *face, const bool use_beauty, const bool use_tag,
43                                         BMOperator *op, BMOpSlot *slot_facemap_out)
44 {
45         const int faces_array_tot = face->len - 3;
46         BMFace  **faces_array = BLI_array_alloca(faces_array, faces_array_tot);
47         BLI_assert(face->len > 3);
48
49         BM_face_triangulate(bm, face, faces_array, use_beauty, use_tag);
50
51         if (faces_array) {
52                 int i;
53                 BMO_slot_map_elem_insert(op, slot_facemap_out, face, face);
54                 for (i = 0; i < faces_array_tot; i++) {
55                         BMO_slot_map_elem_insert(op, slot_facemap_out, faces_array[i], face);
56                 }
57         }
58 }
59
60
61 void BM_mesh_triangulate(BMesh *bm, const bool use_beauty, const bool tag_only,
62                          BMOperator *op, BMOpSlot *slot_facemap_out)
63 {
64         BMIter iter;
65         BMFace *face;
66
67         if (slot_facemap_out) {
68                 /* same as below but call: bm_face_triangulate_mapping() */
69                 BM_ITER_MESH (face, &iter, bm, BM_FACES_OF_MESH) {
70                         if (face->len > 3) {
71                                 if (tag_only == false || BM_elem_flag_test(face, BM_ELEM_TAG)) {
72                                         bm_face_triangulate_mapping(bm, face, use_beauty, tag_only,
73                                                                     op, slot_facemap_out);
74                                 }
75                         }
76                 }
77         }
78         else {
79                 BM_ITER_MESH (face, &iter, bm, BM_FACES_OF_MESH) {
80                         if (face->len > 3) {
81                                 if (tag_only == false || BM_elem_flag_test(face, BM_ELEM_TAG)) {
82                                         BM_face_triangulate(bm, face, NULL, use_beauty, tag_only);
83                                 }
84                         }
85                 }
86         }
87 }