This repository has been archived on 2023-10-09. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
blender-archive/source/blender/modifiers/intern/MOD_triangulate.cc
Hans Goudey 7ca651d182 Mesh: Remove unnecessary edge draw flag
As described in #95966, replace the `ME_EDGEDRAW` flag with a bit
vector in mesh runtime data. Currently the the flag is only ever set
to false for the "optimal display" feature of the subdivision surface
modifier. When creating an "original" mesh in the main data-base,
the flag is always supposed to be true.

The bit vector is now created by the modifier only as necessary, and
is cleared for topology-changing operations. This fixes incorrect
interpolation of the flag as noted in #104376. Generally it isn't
possible to interpolate it through topology-changing operations.

After this, only the seam status needs to be removed from edges before
we can replace them with the generic `int2` type (or something similar)
and reduce memory usage by 1/3.

Related:
- 10131a6f62
- 145839aa42

In the future `BM_ELEM_DRAW` could be removed as well. Currently it is
used and aliased by other defines in some non-obvious ways though.

Pull Request #104417
2023-02-09 15:56:05 +01:00

169 lines
4.8 KiB
C++

/* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup modifiers
*/
#include <cstring>
#include "MEM_guardedalloc.h"
#include "BLI_utildefines.h"
#include "BLT_translation.h"
#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_screen_types.h"
#include "BKE_context.h"
#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_screen.h"
#include "UI_interface.h"
#include "UI_resources.h"
#include "RNA_access.h"
#include "RNA_prototypes.h"
#include "bmesh.h"
#include "bmesh_tools.h"
#include "MOD_modifiertypes.h"
#include "MOD_ui_common.h"
static Mesh *triangulate_mesh(Mesh *mesh,
const int quad_method,
const int ngon_method,
const int min_vertices,
const int flag)
{
Mesh *result;
BMesh *bm;
CustomData_MeshMasks cd_mask_extra{};
cd_mask_extra.vmask = CD_MASK_ORIGINDEX;
cd_mask_extra.emask = CD_MASK_ORIGINDEX;
cd_mask_extra.pmask = CD_MASK_ORIGINDEX;
bool keep_clnors = (flag & MOD_TRIANGULATE_KEEP_CUSTOMLOOP_NORMALS) != 0;
if (keep_clnors) {
BKE_mesh_calc_normals_split(mesh);
/* We need that one to 'survive' to/from BMesh conversions. */
CustomData_clear_layer_flag(&mesh->ldata, CD_NORMAL, CD_FLAG_TEMPORARY);
cd_mask_extra.lmask |= CD_MASK_NORMAL;
}
BMeshCreateParams bmesh_create_params{};
BMeshFromMeshParams bmesh_from_mesh_params{};
bmesh_from_mesh_params.calc_face_normal = true;
bmesh_from_mesh_params.calc_vert_normal = false;
bmesh_from_mesh_params.cd_mask_extra = cd_mask_extra;
bm = BKE_mesh_to_bmesh_ex(mesh, &bmesh_create_params, &bmesh_from_mesh_params);
BM_mesh_triangulate(
bm, quad_method, ngon_method, min_vertices, false, nullptr, nullptr, nullptr);
result = BKE_mesh_from_bmesh_for_eval_nomain(bm, &cd_mask_extra, mesh);
BM_mesh_free(bm);
if (keep_clnors) {
float(*lnors)[3] = static_cast<float(*)[3]>(
CustomData_get_layer_for_write(&result->ldata, CD_NORMAL, result->totloop));
BLI_assert(lnors != nullptr);
BKE_mesh_set_custom_normals(result, lnors);
/* Do some cleanup, we do not want those temp data to stay around. */
CustomData_set_layer_flag(&mesh->ldata, CD_NORMAL, CD_FLAG_TEMPORARY);
CustomData_set_layer_flag(&result->ldata, CD_NORMAL, CD_FLAG_TEMPORARY);
}
return result;
}
static void initData(ModifierData *md)
{
TriangulateModifierData *tmd = (TriangulateModifierData *)md;
BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(tmd, modifier));
MEMCPY_STRUCT_AFTER(tmd, DNA_struct_default_get(TriangulateModifierData), modifier);
/* Enable in editmode by default */
md->mode |= eModifierMode_Editmode;
}
static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext * /*ctx*/, Mesh *mesh)
{
TriangulateModifierData *tmd = (TriangulateModifierData *)md;
Mesh *result;
if (!(result = triangulate_mesh(
mesh, tmd->quad_method, tmd->ngon_method, tmd->min_vertices, tmd->flag))) {
return mesh;
}
return result;
}
static void panel_draw(const bContext * /*C*/, Panel *panel)
{
uiLayout *layout = panel->layout;
PointerRNA ob_ptr;
PointerRNA *ptr = modifier_panel_get_property_pointers(panel, &ob_ptr);
uiLayoutSetPropSep(layout, true);
uiItemR(layout, ptr, "quad_method", 0, nullptr, ICON_NONE);
uiItemR(layout, ptr, "ngon_method", 0, nullptr, ICON_NONE);
uiItemR(layout, ptr, "min_vertices", 0, nullptr, ICON_NONE);
uiItemR(layout, ptr, "keep_custom_normals", 0, nullptr, ICON_NONE);
modifier_panel_end(layout, ptr);
}
static void panelRegister(ARegionType *region_type)
{
modifier_panel_register(region_type, eModifierType_Triangulate, panel_draw);
}
ModifierTypeInfo modifierType_Triangulate = {
/*name*/ N_("Triangulate"),
/*structName*/ "TriangulateModifierData",
/*structSize*/ sizeof(TriangulateModifierData),
/*srna*/ &RNA_TriangulateModifier,
/*type*/ eModifierTypeType_Constructive,
/*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode |
eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_EnableInEditmode |
eModifierTypeFlag_AcceptsCVs,
/*icon*/ ICON_MOD_TRIANGULATE,
/*copyData*/ BKE_modifier_copydata_generic,
/*deformVerts*/ nullptr,
/*deformMatrices*/ nullptr,
/*deformVertsEM*/ nullptr,
/*deformMatricesEM*/ nullptr,
/*modifyMesh*/ modifyMesh,
/*modifyGeometrySet*/ nullptr,
/*initData*/ initData,
/*requiredDataMask*/ nullptr, // requiredDataMask,
/*freeData*/ nullptr,
/*isDisabled*/ nullptr,
/*updateDepsgraph*/ nullptr,
/*dependsOnTime*/ nullptr,
/*dependsOnNormals*/ nullptr,
/*foreachIDLink*/ nullptr,
/*foreachTexLink*/ nullptr,
/*freeRuntimeData*/ nullptr,
/*panelRegister*/ panelRegister,
/*blendWrite*/ nullptr,
/*blendRead*/ nullptr,
};