Changeset View
Changeset View
Standalone View
Standalone View
source/blender/bmesh/tools/bmesh_triangulate.c
| Show All 21 Lines | |||||
| /** \file blender/bmesh/tools/bmesh_triangulate.c | /** \file blender/bmesh/tools/bmesh_triangulate.c | ||||
| * \ingroup bmesh | * \ingroup bmesh | ||||
| * | * | ||||
| * Triangulate. | * Triangulate. | ||||
| * | * | ||||
| */ | */ | ||||
| #include "DNA_modifier_types.h" /* for MOD_TRIANGULATE_NGON_BEAUTY only */ | |||||
| #include "MEM_guardedalloc.h" | #include "MEM_guardedalloc.h" | ||||
| #include "BLI_utildefines.h" | #include "BLI_utildefines.h" | ||||
| #include "BLI_alloca.h" | #include "BLI_alloca.h" | ||||
| #include "BLI_memarena.h" | #include "BLI_memarena.h" | ||||
| #include "BLI_listbase.h" | #include "BLI_listbase.h" | ||||
| #include "BLI_polyfill2d.h" /* only for define */ | #include "BLI_heap.h" | ||||
| #include "BLI_edgehash.h" | |||||
| /* only for defines */ | |||||
| #include "BLI_polyfill2d.h" | |||||
| #include "BLI_polyfill2d_beautify.h" | |||||
| #include "bmesh.h" | #include "bmesh.h" | ||||
| #include "bmesh_triangulate.h" /* own include */ | #include "bmesh_triangulate.h" /* own include */ | ||||
| /** | /** | ||||
| * a version of #BM_face_triangulate that maps to #BMOpSlot | * a version of #BM_face_triangulate that maps to #BMOpSlot | ||||
| */ | */ | ||||
| static void bm_face_triangulate_mapping( | static void bm_face_triangulate_mapping( | ||||
| BMesh *bm, BMFace *face, | BMesh *bm, BMFace *face, | ||||
| const int quad_method, const int ngon_method, | const int quad_method, const int ngon_method, | ||||
| const bool use_tag, | const bool use_tag, | ||||
| BMOperator *op, BMOpSlot *slot_facemap_out, | BMOperator *op, BMOpSlot *slot_facemap_out, | ||||
| MemArena *pf_arena) | MemArena *pf_arena, | ||||
| /* use for MOD_TRIANGULATE_NGON_BEAUTY only! */ | |||||
| struct Heap *pf_heap, struct EdgeHash *pf_ehash) | |||||
| { | { | ||||
| int faces_array_tot = face->len - 3; | int faces_array_tot = face->len - 3; | ||||
| BMFace **faces_array = BLI_array_alloca(faces_array, faces_array_tot); | BMFace **faces_array = BLI_array_alloca(faces_array, faces_array_tot); | ||||
| BLI_assert(face->len > 3); | BLI_assert(face->len > 3); | ||||
| BM_face_triangulate( | BM_face_triangulate( | ||||
| bm, face, faces_array, &faces_array_tot, | bm, face, faces_array, &faces_array_tot, | ||||
| quad_method, ngon_method, use_tag, | quad_method, ngon_method, use_tag, | ||||
| pf_arena); | pf_arena, | ||||
| pf_heap, pf_ehash); | |||||
| if (faces_array_tot) { | if (faces_array_tot) { | ||||
| int i; | int i; | ||||
| BMO_slot_map_elem_insert(op, slot_facemap_out, face, face); | BMO_slot_map_elem_insert(op, slot_facemap_out, face, face); | ||||
| for (i = 0; i < faces_array_tot; i++) { | for (i = 0; i < faces_array_tot; i++) { | ||||
| BMO_slot_map_elem_insert(op, slot_facemap_out, faces_array[i], face); | BMO_slot_map_elem_insert(op, slot_facemap_out, faces_array[i], face); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| void BM_mesh_triangulate( | void BM_mesh_triangulate( | ||||
| BMesh *bm, const int quad_method, const int ngon_method, const bool tag_only, | BMesh *bm, const int quad_method, const int ngon_method, const bool tag_only, | ||||
| BMOperator *op, BMOpSlot *slot_facemap_out) | BMOperator *op, BMOpSlot *slot_facemap_out) | ||||
| { | { | ||||
| BMIter iter; | BMIter iter; | ||||
| BMFace *face; | BMFace *face; | ||||
| MemArena *pf_arena; | MemArena *pf_arena; | ||||
| Heap *pf_heap; | |||||
| EdgeHash *pf_ehash; | |||||
| pf_arena = BLI_memarena_new(BLI_POLYFILL_ARENA_SIZE, __func__); | pf_arena = BLI_memarena_new(BLI_POLYFILL_ARENA_SIZE, __func__); | ||||
| if (ngon_method == MOD_TRIANGULATE_NGON_BEAUTY) { | |||||
| pf_heap = BLI_heap_new_ex(BLI_POLYFILL_ALLOC_NGON_RESERVE); | |||||
| pf_ehash = BLI_edgehash_new_ex(__func__, BLI_POLYFILL_ALLOC_NGON_RESERVE); | |||||
| } | |||||
| if (slot_facemap_out) { | if (slot_facemap_out) { | ||||
| /* same as below but call: bm_face_triangulate_mapping() */ | /* same as below but call: bm_face_triangulate_mapping() */ | ||||
| BM_ITER_MESH (face, &iter, bm, BM_FACES_OF_MESH) { | BM_ITER_MESH (face, &iter, bm, BM_FACES_OF_MESH) { | ||||
| if (face->len > 3) { | if (face->len > 3) { | ||||
| if (tag_only == false || BM_elem_flag_test(face, BM_ELEM_TAG)) { | if (tag_only == false || BM_elem_flag_test(face, BM_ELEM_TAG)) { | ||||
| bm_face_triangulate_mapping( | bm_face_triangulate_mapping( | ||||
| bm, face, quad_method, | bm, face, quad_method, ngon_method, tag_only, | ||||
| ngon_method, tag_only, | |||||
| op, slot_facemap_out, | op, slot_facemap_out, | ||||
| pf_arena); | |||||
| pf_arena, | |||||
| pf_heap, pf_ehash); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| BM_ITER_MESH (face, &iter, bm, BM_FACES_OF_MESH) { | BM_ITER_MESH (face, &iter, bm, BM_FACES_OF_MESH) { | ||||
| if (face->len > 3) { | if (face->len > 3) { | ||||
| if (tag_only == false || BM_elem_flag_test(face, BM_ELEM_TAG)) { | if (tag_only == false || BM_elem_flag_test(face, BM_ELEM_TAG)) { | ||||
| BM_face_triangulate( | BM_face_triangulate( | ||||
| bm, face, NULL, NULL, | bm, face, NULL, NULL, quad_method, ngon_method, tag_only, | ||||
| quad_method, ngon_method, tag_only, | pf_arena, | ||||
| pf_arena); | pf_heap, pf_ehash); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| BLI_memarena_free(pf_arena); | BLI_memarena_free(pf_arena); | ||||
| if (ngon_method == MOD_TRIANGULATE_NGON_BEAUTY) { | |||||
| BLI_heap_free(pf_heap, NULL); | |||||
| BLI_edgehash_free(pf_ehash, NULL); | |||||
| } | |||||
| } | } | ||||