Blender  V2.93
mesh_wrapper.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
35 #include "MEM_guardedalloc.h"
36 
37 #include "DNA_mesh_types.h"
38 #include "DNA_meshdata_types.h"
39 #include "DNA_object_types.h"
40 
41 #include "BLI_ghash.h"
42 #include "BLI_math.h"
43 #include "BLI_threads.h"
44 #include "BLI_utildefines.h"
45 
46 #include "BKE_editmesh.h"
47 #include "BKE_editmesh_cache.h"
48 #include "BKE_lib_id.h"
49 #include "BKE_mesh.h"
50 #include "BKE_mesh_runtime.h"
51 #include "BKE_mesh_wrapper.h"
52 
53 #include "DEG_depsgraph.h"
54 
56  const CustomData_MeshMasks *cd_mask_extra,
57  const float (*vert_coords)[3],
58  const Mesh *me_settings)
59 {
61  BKE_mesh_copy_settings(me, me_settings);
63 
65  if (cd_mask_extra) {
66  me->runtime.cd_mask_extra = *cd_mask_extra;
67  }
68 
69  /* Use edit-mesh directly where possible. */
70  me->runtime.is_original = true;
71  me->edit_mesh = MEM_dupallocN(em);
72 
73 /* Make sure, we crash if these are ever used. */
74 #ifdef DEBUG
75  me->totvert = INT_MAX;
76  me->totedge = INT_MAX;
77  me->totpoly = INT_MAX;
78  me->totloop = INT_MAX;
79 #else
80  me->totvert = 0;
81  me->totedge = 0;
82  me->totpoly = 0;
83  me->totloop = 0;
84 #endif
85 
86  EditMeshData *edit_data = me->runtime.edit_data;
87  edit_data->vertexCos = vert_coords;
88  return me;
89 }
90 
92  const CustomData_MeshMasks *cd_mask_extra,
93  const Mesh *me_settings)
94 {
95  return BKE_mesh_wrapper_from_editmesh_with_coords(em, cd_mask_extra, NULL, me_settings);
96 }
97 
99 {
100  ThreadMutex *mesh_eval_mutex = (ThreadMutex *)me->runtime.eval_mutex;
101  BLI_mutex_lock(mesh_eval_mutex);
102 
104  BLI_mutex_unlock(mesh_eval_mutex);
105  return;
106  }
107 
108  const eMeshWrapperType geom_type_orig = me->runtime.wrapper_type;
110 
111  switch (geom_type_orig) {
112  case ME_WRAPPER_TYPE_MDATA: {
113  break; /* Quiet warning. */
114  }
115  case ME_WRAPPER_TYPE_BMESH: {
116  me->totvert = 0;
117  me->totedge = 0;
118  me->totpoly = 0;
119  me->totloop = 0;
120 
121  BLI_assert(me->edit_mesh != NULL);
123 
124  BMEditMesh *em = me->edit_mesh;
126 
127  EditMeshData *edit_data = me->runtime.edit_data;
128  if (edit_data->vertexCos) {
129  BKE_mesh_vert_coords_apply(me, edit_data->vertexCos);
130  me->runtime.is_original = false;
131  }
132  break;
133  }
134  }
135 
136  if (me->runtime.wrapper_type_finalize) {
138  }
139 
140  BLI_mutex_unlock(mesh_eval_mutex);
141 }
142 
143 bool BKE_mesh_wrapper_minmax(const Mesh *me, float min[3], float max[3])
144 {
145  switch ((eMeshWrapperType)me->runtime.wrapper_type) {
149  return BKE_mesh_minmax(me, min, max);
150  }
152  return false;
153 }
154 
155 /* -------------------------------------------------------------------- */
160  float (*vert_coords)[3],
161  int vert_coords_len)
162 {
163  switch ((eMeshWrapperType)me->runtime.wrapper_type) {
164  case ME_WRAPPER_TYPE_BMESH: {
165  BMesh *bm = me->edit_mesh->bm;
166  BLI_assert(vert_coords_len <= bm->totvert);
167  EditMeshData *edit_data = me->runtime.edit_data;
168  if (edit_data->vertexCos != NULL) {
169  for (int i = 0; i < vert_coords_len; i++) {
170  copy_v3_v3(vert_coords[i], edit_data->vertexCos[i]);
171  }
172  }
173  else {
174  BMIter iter;
175  BMVert *v;
176  int i;
177  BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
178  copy_v3_v3(vert_coords[i], v->co);
179  }
180  }
181  return;
182  }
183  case ME_WRAPPER_TYPE_MDATA: {
184  BLI_assert(vert_coords_len <= me->totvert);
185  const MVert *mvert = me->mvert;
186  for (int i = 0; i < vert_coords_len; i++) {
187  copy_v3_v3(vert_coords[i], mvert[i].co);
188  }
189  return;
190  }
191  }
193 }
194 
196  float (*vert_coords)[3],
197  int vert_coords_len,
198  const float mat[4][4])
199 {
200  switch ((eMeshWrapperType)me->runtime.wrapper_type) {
201  case ME_WRAPPER_TYPE_BMESH: {
202  BMesh *bm = me->edit_mesh->bm;
203  BLI_assert(vert_coords_len == bm->totvert);
204  EditMeshData *edit_data = me->runtime.edit_data;
205  if (edit_data->vertexCos != NULL) {
206  for (int i = 0; i < vert_coords_len; i++) {
207  mul_v3_m4v3(vert_coords[i], mat, edit_data->vertexCos[i]);
208  }
209  }
210  else {
211  BMIter iter;
212  BMVert *v;
213  int i;
214  BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
215  mul_v3_m4v3(vert_coords[i], mat, v->co);
216  }
217  }
218  return;
219  }
220  case ME_WRAPPER_TYPE_MDATA: {
221  BLI_assert(vert_coords_len == me->totvert);
222  const MVert *mvert = me->mvert;
223  for (int i = 0; i < vert_coords_len; i++) {
224  mul_v3_m4v3(vert_coords[i], mat, mvert[i].co);
225  }
226  return;
227  }
228  }
230 }
231 
234 /* -------------------------------------------------------------------- */
239 {
240  switch ((eMeshWrapperType)me->runtime.wrapper_type) {
242  return me->edit_mesh->bm->totvert;
244  return me->totvert;
245  }
247  return -1;
248 }
249 
251 {
252  switch ((eMeshWrapperType)me->runtime.wrapper_type) {
254  return me->edit_mesh->bm->totedge;
256  return me->totedge;
257  }
259  return -1;
260 }
261 
263 {
264  switch ((eMeshWrapperType)me->runtime.wrapper_type) {
266  return me->edit_mesh->bm->totloop;
268  return me->totloop;
269  }
271  return -1;
272 }
273 
275 {
276  switch ((eMeshWrapperType)me->runtime.wrapper_type) {
278  return me->edit_mesh->bm->totface;
280  return me->totpoly;
281  }
283  return -1;
284 }
285 
bool BKE_editmesh_cache_calc_minmax(struct BMEditMesh *em, struct EditMeshData *emd, float min[3], float max[3])
void * BKE_id_new_nomain(const short type, const char *name)
Definition: lib_id.c:1196
void BKE_mesh_vert_coords_apply(struct Mesh *mesh, const float(*vert_coords)[3])
Definition: mesh.c:1755
void BKE_mesh_wrapper_deferred_finalize(struct Mesh *me_eval, const CustomData_MeshMasks *cd_mask_finalize)
Definition: DerivedMesh.cc:878
bool BKE_mesh_minmax(const struct Mesh *me, float r_min[3], float r_max[3])
void BKE_mesh_copy_settings(struct Mesh *me_dst, const struct Mesh *me_src)
bool BKE_mesh_runtime_ensure_edit_data(struct Mesh *mesh)
Definition: mesh_runtime.c:188
#define BLI_assert_unreachable()
Definition: BLI_assert.h:96
#define BLI_assert(a)
Definition: BLI_assert.h:58
void mul_v3_m4v3(float r[3], const float M[4][4], const float v[3])
Definition: math_matrix.c:742
MINLINE void copy_v3_v3(float r[3], const float a[3])
void BLI_mutex_lock(ThreadMutex *mutex)
Definition: threads.cc:401
void BLI_mutex_unlock(ThreadMutex *mutex)
Definition: threads.cc:406
pthread_mutex_t ThreadMutex
Definition: BLI_threads.h:83
@ ID_ME
Definition: DNA_ID_enums.h:60
eMeshWrapperType
@ ME_WRAPPER_TYPE_MDATA
@ ME_WRAPPER_TYPE_BMESH
Object is a sort of wrapper for general info.
Read Guarded memory(de)allocation.
#define BM_ITER_MESH_INDEX(ele, iter, bm, itype, indexvar)
@ BM_VERTS_OF_MESH
ATTR_WARN_UNUSED_RESULT BMesh * bm
void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *cd_mask_extra)
ATTR_WARN_UNUSED_RESULT const BMVert * v
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:42
int BKE_mesh_wrapper_edge_len(const Mesh *me)
Definition: mesh_wrapper.c:250
int BKE_mesh_wrapper_loop_len(const Mesh *me)
Definition: mesh_wrapper.c:262
int BKE_mesh_wrapper_poly_len(const Mesh *me)
Definition: mesh_wrapper.c:274
Mesh * BKE_mesh_wrapper_from_editmesh(BMEditMesh *em, const CustomData_MeshMasks *cd_mask_extra, const Mesh *me_settings)
Definition: mesh_wrapper.c:91
bool BKE_mesh_wrapper_minmax(const Mesh *me, float min[3], float max[3])
Definition: mesh_wrapper.c:143
Mesh * BKE_mesh_wrapper_from_editmesh_with_coords(BMEditMesh *em, const CustomData_MeshMasks *cd_mask_extra, const float(*vert_coords)[3], const Mesh *me_settings)
Definition: mesh_wrapper.c:55
void BKE_mesh_wrapper_ensure_mdata(Mesh *me)
Definition: mesh_wrapper.c:98
void BKE_mesh_wrapper_vert_coords_copy_with_mat4(const Mesh *me, float(*vert_coords)[3], int vert_coords_len, const float mat[4][4])
Definition: mesh_wrapper.c:195
int BKE_mesh_wrapper_vert_len(const Mesh *me)
Definition: mesh_wrapper.c:238
void BKE_mesh_wrapper_vert_coords_copy(const Mesh *me, float(*vert_coords)[3], int vert_coords_len)
Definition: mesh_wrapper.c:159
#define min(a, b)
Definition: sort.c:51
struct BMesh * bm
Definition: BKE_editmesh.h:52
float co[3]
Definition: bmesh_class.h:99
int totvert
Definition: bmesh_class.h:297
int totedge
Definition: bmesh_class.h:297
int totloop
Definition: bmesh_class.h:297
int totface
Definition: bmesh_class.h:297
const float(* vertexCos)[3]
struct EditMeshData * edit_data
CustomData_MeshMasks cd_mask_extra
char wrapper_type_finalize
void * eval_mutex
struct BMEditMesh * edit_mesh
struct MVert * mvert
int totedge
int totvert
Mesh_Runtime runtime
int totpoly
int totloop
float max