Files
test/source/blender/bmesh/tools/bmesh_triangulate.cc
Philipp Oeser 8b3beeee82 Fix #124836: Triangulate modifier changed behavior with custom normals
This reverts commit f3c32a36bc and the two followups.

The commit caused issues with both the operator and the modifier.

The operator could be fixed, for the modifier this needs deeper
investigation (see #124836 for a bit more info on this).

Until a better solution is found it is just better to go back to
previous behavior.

Reintroduces  #103562 for now

Pull Request: https://projects.blender.org/blender/blender/pulls/125499
2024-07-28 10:27:29 +02:00

157 lines
4.7 KiB
C++

/* SPDX-FileCopyrightText: 2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \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.hh"
#include "bmesh_triangulate.hh" /* 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! */
Heap *pf_heap)
{
int faces_array_tot = face->len - 3;
BMFace **faces_array = BLI_array_alloca(faces_array, faces_array_tot);
LinkNode *faces_double = nullptr;
BLI_assert(face->len > 3);
BM_face_triangulate(bm,
face,
faces_array,
&faces_array_tot,
nullptr,
nullptr,
&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 = nullptr;
}
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 = nullptr;
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,
nullptr,
nullptr,
nullptr,
nullptr,
&faces_double,
quad_method,
ngon_method,
tag_only,
pf_arena,
pf_heap);
}
}
}
while (faces_double) {
LinkNode *next = faces_double->next;
BM_face_kill(bm, static_cast<BMFace *>(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, nullptr);
}
}