This repository has been archived on 2023-10-09. You can view files and clone it, but cannot push or open issues or pull requests.
Files
blender-archive/source/blender/bmesh/tools/bmesh_triangulate.c

169 lines
5.3 KiB
C

/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/** \file
* \ingroup bmesh
*
* Triangulate.
*/
#include "DNA_modifier_types.h" /* for MOD_TRIANGULATE_NGON_BEAUTY only */
#include "MEM_guardedalloc.h"
#include "BLI_alloca.h"
#include "BLI_heap.h"
#include "BLI_linklist.h"
#include "BLI_memarena.h"
#include "BLI_utildefines.h"
/* only for defines */
#include "BLI_polyfill_2d.h"
#include "BLI_polyfill_2d_beautify.h"
#include "bmesh.h"
#include "bmesh_triangulate.h" /* own include */
/**
* a version of #BM_face_triangulate that maps to #BMOpSlot
*/
static void bm_face_triangulate_mapping(BMesh *bm,
BMFace *face,
const int quad_method,
const int ngon_method,
const bool use_tag,
BMOperator *op,
BMOpSlot *slot_facemap_out,
BMOpSlot *slot_facemap_double_out,
MemArena *pf_arena,
/* use for MOD_TRIANGULATE_NGON_BEAUTY only! */
struct Heap *pf_heap)
{
int faces_array_tot = face->len - 3;
BMFace **faces_array = BLI_array_alloca(faces_array, faces_array_tot);
LinkNode *faces_double = NULL;
BLI_assert(face->len > 3);
BM_face_triangulate(bm,
face,
faces_array,
&faces_array_tot,
NULL,
NULL,
&faces_double,
quad_method,
ngon_method,
use_tag,
pf_arena,
pf_heap);
if (faces_array_tot) {
int i;
BMO_slot_map_elem_insert(op, slot_facemap_out, face, face);
for (i = 0; i < faces_array_tot; i++) {
BMO_slot_map_elem_insert(op, slot_facemap_out, faces_array[i], face);
}
while (faces_double) {
LinkNode *next = faces_double->next;
BMO_slot_map_elem_insert(op, slot_facemap_double_out, faces_double->link, face);
MEM_freeN(faces_double);
faces_double = next;
}
}
}
void BM_mesh_triangulate(BMesh *bm,
const int quad_method,
const int ngon_method,
const int min_vertices,
const bool tag_only,
BMOperator *op,
BMOpSlot *slot_facemap_out,
BMOpSlot *slot_facemap_double_out)
{
BMIter iter;
BMFace *face;
MemArena *pf_arena;
Heap *pf_heap;
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);
}
else {
pf_heap = NULL;
}
if (slot_facemap_out) {
/* same as below but call: bm_face_triangulate_mapping() */
BM_ITER_MESH (face, &iter, bm, BM_FACES_OF_MESH) {
if (face->len >= min_vertices) {
if (tag_only == false || BM_elem_flag_test(face, BM_ELEM_TAG)) {
bm_face_triangulate_mapping(bm,
face,
quad_method,
ngon_method,
tag_only,
op,
slot_facemap_out,
slot_facemap_double_out,
pf_arena,
pf_heap);
}
}
}
}
else {
LinkNode *faces_double = NULL;
BM_ITER_MESH (face, &iter, bm, BM_FACES_OF_MESH) {
if (face->len >= min_vertices) {
if (tag_only == false || BM_elem_flag_test(face, BM_ELEM_TAG)) {
BM_face_triangulate(bm,
face,
NULL,
NULL,
NULL,
NULL,
&faces_double,
quad_method,
ngon_method,
tag_only,
pf_arena,
pf_heap);
}
}
}
while (faces_double) {
LinkNode *next = faces_double->next;
BM_face_kill(bm, faces_double->link);
MEM_freeN(faces_double);
faces_double = next;
}
}
BLI_memarena_free(pf_arena);
if (ngon_method == MOD_TRIANGULATE_NGON_BEAUTY) {
BLI_heap_free(pf_heap, NULL);
}
}