Blender V5.0
editmesh.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2005 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include "MEM_guardedalloc.h"
10
11#include "DNA_mesh_types.h"
12#include "DNA_object_types.h"
13
14#include "BLI_bitmap.h"
15#include "BLI_math_geom.h"
16#include "BLI_math_vector.h"
17
18#include "BKE_customdata.hh"
19#include "BKE_editmesh.hh"
20#include "BKE_mesh.hh"
21#include "BKE_mesh_iterators.hh"
22#include "BKE_mesh_runtime.hh"
23#include "BKE_mesh_wrapper.hh"
24#include "BKE_object.hh"
25
27
28using blender::Array;
29using blender::float3;
30using blender::Span;
31
33{
34 BMEditMesh *em = MEM_new<BMEditMesh>(__func__);
35 em->bm = bm;
36 return em;
37}
38
40{
41 BMEditMesh *em_copy = MEM_new<BMEditMesh>(__func__);
42 *em_copy = *em;
43
44 em_copy->bm = BM_mesh_copy(em->bm);
45
46 /* The tessellation is NOT calculated on the copy here,
47 * because currently all the callers of this function use
48 * it to make a backup copy of the #BMEditMesh to restore
49 * it in the case of errors in an operation. For performance reasons,
50 * in that case it makes more sense to do the
51 * tessellation only when/if that copy ends up getting used. */
52 em_copy->looptris = {};
53
54 /* Copy various settings. */
55 em_copy->selectmode = em->selectmode;
56 em_copy->mat_nr = em->mat_nr;
57
58 return em_copy;
59}
60
62{
63 BLI_assert(ob->type == OB_MESH);
64 return ((Mesh *)ob->data)->runtime->edit_mesh.get();
65}
66
67bool BKE_editmesh_eval_orig_map_available(const Mesh &mesh_eval, const Mesh *mesh_orig)
68{
69 if (!mesh_orig) {
70 return false;
71 }
72 if (&mesh_eval == mesh_orig) {
73 return true;
74 }
75 if (mesh_eval.runtime->edit_mesh) {
76 return mesh_eval.runtime->edit_mesh == mesh_orig->runtime->edit_mesh;
77 }
78 return false;
79}
80
87
94
96{
97 BMeshCalcTessellation_Params looptris_params{};
98 looptris_params.face_normals = true;
99 BKE_editmesh_looptris_calc_ex(em, &looptris_params);
100 BMeshNormalsUpdate_Params normals_params{};
101 normals_params.face_normals = false;
102 BM_mesh_normals_update_ex(em->bm, &normals_params);
103}
104
114
116{
117 BMeshCalcTessellation_Params looptris_params{};
118 looptris_params.face_normals = false;
119 BKE_editmesh_looptris_calc_with_partial_ex(em, bmpinfo, &looptris_params);
120}
121
123{
124 BMeshCalcTessellation_Params looptris_params{};
125 looptris_params.face_normals = true;
126 BKE_editmesh_looptris_calc_with_partial_ex(em, bmpinfo, &looptris_params);
127 BMeshNormalsUpdate_Params normals_params{};
128 normals_params.face_normals = false;
129 BM_mesh_normals_update_with_partial_ex(em->bm, bmpinfo, &normals_params);
130}
131
133{
134 em->looptris = {};
135
136 if (em->bm) {
137 BM_mesh_free(em->bm);
138 }
139}
140
146
147static void cage_mapped_verts_callback(void *user_data,
148 int index,
149 const float co[3],
150 const float /*no*/[3])
151{
152 CageUserData *data = static_cast<CageUserData *>(user_data);
153
154 if ((index >= 0 && index < data->totvert) && !BLI_BITMAP_TEST(data->visit_bitmap, index)) {
155 BLI_BITMAP_ENABLE(data->visit_bitmap, index);
156 copy_v3_v3(data->positions_cage[index], co);
157 }
158}
159
161 BMEditMesh *em,
162 Scene *scene,
163 Object *ob)
164{
166 Array<float3> positions_cage(em->bm->totvert);
167
168 /* When initializing cage verts, we only want the first cage coordinate for each vertex,
169 * so that e.g. mirror or array use original vertex coordinates and not mirrored or duplicate. */
170 BLI_bitmap *visit_bitmap = BLI_BITMAP_NEW(em->bm->totvert, __func__);
171
173 data.totvert = em->bm->totvert;
174 data.positions_cage = positions_cage;
175 data.visit_bitmap = visit_bitmap;
176
178
179 MEM_freeN(visit_bitmap);
180
181 return positions_cage;
182}
183
185 Depsgraph *depsgraph, BMEditMesh *em, Scene *scene, Object *ob, Array<float3> &r_alloc)
186{
187
188 const Object *object_eval = DEG_get_evaluated(depsgraph, ob);
189 const Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(object_eval);
190 const Mesh *mesh_cage = BKE_object_get_editmesh_eval_cage(ob);
191
192 Span<float3> vert_positions;
193 if (mesh_cage && mesh_cage->runtime->deformed_only) {
195 /* Deformed, and we have deformed coords already. */
196 vert_positions = BKE_mesh_wrapper_vert_coords(mesh_cage);
197 }
198 else if ((editmesh_eval_final != nullptr) &&
199 (editmesh_eval_final->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH))
200 {
201 /* If this is an edit-mesh type, leave nullptr as we can use the vertex coords. */
202
203 /* If this is not empty, it's value should be assigned to `vert_positions`
204 * however the `mesh_cage` check above should handle this case. */
205 BLI_assert(BKE_mesh_wrapper_vert_coords(mesh_cage).is_empty());
206 }
207 else {
208 /* Constructive modifiers have been used, we need to allocate coordinates. */
209 r_alloc = BKE_editmesh_vert_coords_alloc(depsgraph, em, scene, ob);
210 return r_alloc.as_span();
211 }
212 return vert_positions;
213}
214
219
CustomData interface, see also DNA_customdata_types.h.
const CustomData_MeshMasks CD_MASK_BAREMESH
@ MESH_FOREACH_NOP
void BKE_mesh_foreach_mapped_vert(const Mesh *mesh, void(*func)(void *user_data, int index, const float co[3], const float no[3]), void *user_data, MeshForeachFlag flag)
@ ME_WRAPPER_TYPE_BMESH
blender::Span< blender::float3 > BKE_mesh_wrapper_vert_coords(const Mesh *mesh)
int BKE_mesh_wrapper_vert_len(const Mesh *mesh)
General operations, lookup, etc. for blender objects.
const Mesh * BKE_object_get_editmesh_eval_cage(const Object *object)
const Mesh * BKE_object_get_editmesh_eval_final(const Object *object)
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_BITMAP_NEW(_num, _alloc_string)
Definition BLI_bitmap.h:37
#define BLI_BITMAP_TEST(_bitmap, _index)
Definition BLI_bitmap.h:61
#define BLI_BITMAP_ENABLE(_bitmap, _index)
Definition BLI_bitmap.h:78
unsigned int BLI_bitmap
Definition BLI_bitmap.h:13
MINLINE int poly_to_tri_count(int poly_count, int corner_count)
MINLINE void copy_v3_v3(float r[3], const float a[3])
T * DEG_get_evaluated(const Depsgraph *depsgraph, T *id)
Object is a sort of wrapper for general info.
@ OB_MESH
Read Guarded memory(de)allocation.
BMesh * BM_mesh_copy(BMesh *bm_old)
BMesh const char void * data
BMesh * bm
void BM_mesh_free(BMesh *bm)
BMesh Free Mesh.
Array< float3 > BM_mesh_vert_coords_alloc(BMesh *bm)
void BM_lnorspace_update(BMesh *bm)
void BM_mesh_normals_update_ex(BMesh *bm, const BMeshNormalsUpdate_Params *params)
BMesh Compute Normals.
void BM_mesh_normals_update_with_partial_ex(BMesh *, const BMPartialUpdate *bmpinfo, const BMeshNormalsUpdate_Params *params)
void BM_mesh_calc_tessellation_with_partial_ex(BMesh *bm, MutableSpan< std::array< BMLoop *, 3 > > looptris, const BMPartialUpdate *bmpinfo, const BMeshCalcTessellation_Params *params)
void BM_mesh_calc_tessellation_ex(BMesh *bm, MutableSpan< std::array< BMLoop *, 3 > > looptris, const BMeshCalcTessellation_Params *params)
BPy_StructRNA * depsgraph
int64_t size() const
Definition BLI_array.hh:256
void reinitialize(const int64_t new_size)
Definition BLI_array.hh:419
bool is_empty() const
Definition BLI_array.hh:264
Span< T > as_span() const
Definition BLI_array.hh:243
void BKE_editmesh_free_data(BMEditMesh *em)
Definition editmesh.cc:132
BMEditMesh * BKE_editmesh_from_object(Object *ob)
Return the BMEditMesh for a given object.
Definition editmesh.cc:61
BMEditMesh * BKE_editmesh_create(BMesh *bm)
Definition editmesh.cc:32
void BKE_editmesh_looptris_and_normals_calc_with_partial(BMEditMesh *em, BMPartialUpdate *bmpinfo)
Definition editmesh.cc:122
void BKE_editmesh_looptris_calc_with_partial_ex(BMEditMesh *em, BMPartialUpdate *bmpinfo, const BMeshCalcTessellation_Params *params)
Definition editmesh.cc:105
Span< float3 > BKE_editmesh_vert_coords_when_deformed(Depsgraph *depsgraph, BMEditMesh *em, Scene *scene, Object *ob, Array< float3 > &r_alloc)
Definition editmesh.cc:184
void BKE_editmesh_looptris_calc(BMEditMesh *em)
Definition editmesh.cc:88
void BKE_editmesh_looptris_calc_ex(BMEditMesh *em, const BMeshCalcTessellation_Params *params)
Definition editmesh.cc:81
void BKE_editmesh_looptris_and_normals_calc(BMEditMesh *em)
Definition editmesh.cc:95
void BKE_editmesh_lnorspace_update(BMEditMesh *em)
Definition editmesh.cc:220
BMEditMesh * BKE_editmesh_copy(BMEditMesh *em)
Definition editmesh.cc:39
bool BKE_editmesh_eval_orig_map_available(const Mesh &mesh_eval, const Mesh *mesh_orig)
Definition editmesh.cc:67
static void cage_mapped_verts_callback(void *user_data, int index, const float co[3], const float[3])
Definition editmesh.cc:147
Array< float3 > BKE_editmesh_vert_coords_alloc(Depsgraph *depsgraph, BMEditMesh *em, Scene *scene, Object *ob)
Definition editmesh.cc:160
void BKE_editmesh_looptris_calc_with_partial(BMEditMesh *em, BMPartialUpdate *bmpinfo)
Definition editmesh.cc:115
Array< float3 > BKE_editmesh_vert_coords_alloc_orco(BMEditMesh *em)
Definition editmesh.cc:215
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
Mesh * editbmesh_get_eval_cage(Depsgraph *depsgraph, const Scene *scene, Object *obedit, BMEditMesh *em, const CustomData_MeshMasks *dataMask)
VecBase< float, 3 > float3
short selectmode
blender::Array< std::array< BMLoop *, 3 > > looptris
int totvert
int totloop
int totface
blender::MutableSpan< float3 > positions_cage
Definition editmesh.cc:143
BLI_bitmap * visit_bitmap
Definition editmesh.cc:144
MeshRuntimeHandle * runtime