Cleanup: style, use braces for blenkernel
[blender.git] / source / blender / blenkernel / intern / mesh_runtime.c
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  * The Original Code is Copyright (C) 2005 Blender Foundation.
17  * All rights reserved.
18  */
19
20 /** \file
21  * \ingroup bke
22  */
23
24 #include "atomic_ops.h"
25
26 #include "MEM_guardedalloc.h"
27
28 #include "DNA_mesh_types.h"
29 #include "DNA_meshdata_types.h"
30 #include "DNA_object_types.h"
31
32 #include "BLI_math_geom.h"
33 #include "BLI_threads.h"
34
35 #include "BKE_bvhutils.h"
36 #include "BKE_mesh.h"
37 #include "BKE_mesh_runtime.h"
38 #include "BKE_subdiv_ccg.h"
39 #include "BKE_shrinkwrap.h"
40
41 /* -------------------------------------------------------------------- */
42 /** \name Mesh Runtime Struct Utils
43  * \{ */
44
45 static ThreadRWMutex loops_cache_lock = PTHREAD_RWLOCK_INITIALIZER;
46
47 /**
48  * Default values defined at read time.
49  */
50 void BKE_mesh_runtime_reset(Mesh *mesh)
51 {
52   memset(&mesh->runtime, 0, sizeof(mesh->runtime));
53 }
54
55 /* Clear all pointers which we don't want to be shared on copying the datablock.
56  * However, keep all the flags which defines what the mesh is (for example, that
57  * it's deformed only, or that its custom data layers are out of date.) */
58 void BKE_mesh_runtime_reset_on_copy(Mesh *mesh, const int UNUSED(flag))
59 {
60   Mesh_Runtime *runtime = &mesh->runtime;
61
62   runtime->edit_data = NULL;
63   runtime->batch_cache = NULL;
64   runtime->subdiv_ccg = NULL;
65   memset(&runtime->looptris, 0, sizeof(runtime->looptris));
66   runtime->bvh_cache = NULL;
67   runtime->shrinkwrap_data = NULL;
68 }
69
70 void BKE_mesh_runtime_clear_cache(Mesh *mesh)
71 {
72   BKE_mesh_runtime_clear_geometry(mesh);
73   BKE_mesh_batch_cache_free(mesh);
74   BKE_mesh_runtime_clear_edit_data(mesh);
75 }
76
77 /* This is a ported copy of DM_ensure_looptri_data(dm) */
78 /**
79  * Ensure the array is large enough
80  *
81  * \note This function must always be thread-protected by caller. It should only be used by internal code.
82  */
83 static void mesh_ensure_looptri_data(Mesh *mesh)
84 {
85   const unsigned int totpoly = mesh->totpoly;
86   const int looptris_len = poly_to_tri_count(totpoly, mesh->totloop);
87
88   BLI_assert(mesh->runtime.looptris.array_wip == NULL);
89
90   SWAP(MLoopTri *, mesh->runtime.looptris.array, mesh->runtime.looptris.array_wip);
91
92   if ((looptris_len > mesh->runtime.looptris.len_alloc) ||
93       (looptris_len < mesh->runtime.looptris.len_alloc * 2) || (totpoly == 0)) {
94     MEM_SAFE_FREE(mesh->runtime.looptris.array_wip);
95     mesh->runtime.looptris.len_alloc = 0;
96     mesh->runtime.looptris.len = 0;
97   }
98
99   if (totpoly) {
100     if (mesh->runtime.looptris.array_wip == NULL) {
101       mesh->runtime.looptris.array_wip = MEM_malloc_arrayN(
102           looptris_len, sizeof(*mesh->runtime.looptris.array_wip), __func__);
103       mesh->runtime.looptris.len_alloc = looptris_len;
104     }
105
106     mesh->runtime.looptris.len = looptris_len;
107   }
108 }
109
110 /* This is a ported copy of CDDM_recalc_looptri(dm). */
111 void BKE_mesh_runtime_looptri_recalc(Mesh *mesh)
112 {
113   mesh_ensure_looptri_data(mesh);
114   BLI_assert(mesh->totpoly == 0 || mesh->runtime.looptris.array_wip != NULL);
115
116   BKE_mesh_recalc_looptri(mesh->mloop,
117                           mesh->mpoly,
118                           mesh->mvert,
119                           mesh->totloop,
120                           mesh->totpoly,
121                           mesh->runtime.looptris.array_wip);
122
123   BLI_assert(mesh->runtime.looptris.array == NULL);
124   atomic_cas_ptr((void **)&mesh->runtime.looptris.array,
125                  mesh->runtime.looptris.array,
126                  mesh->runtime.looptris.array_wip);
127   mesh->runtime.looptris.array_wip = NULL;
128 }
129
130 /* This is a ported copy of dm_getNumLoopTri(dm). */
131 int BKE_mesh_runtime_looptri_len(const Mesh *mesh)
132 {
133   const int looptri_len = poly_to_tri_count(mesh->totpoly, mesh->totloop);
134   BLI_assert(ELEM(mesh->runtime.looptris.len, 0, looptri_len));
135   return looptri_len;
136 }
137
138 /* This is a ported copy of dm_getLoopTriArray(dm). */
139 const MLoopTri *BKE_mesh_runtime_looptri_ensure(Mesh *mesh)
140 {
141   MLoopTri *looptri;
142
143   BLI_rw_mutex_lock(&loops_cache_lock, THREAD_LOCK_READ);
144   looptri = mesh->runtime.looptris.array;
145   BLI_rw_mutex_unlock(&loops_cache_lock);
146
147   if (looptri != NULL) {
148     BLI_assert(BKE_mesh_runtime_looptri_len(mesh) == mesh->runtime.looptris.len);
149   }
150   else {
151     BLI_rw_mutex_lock(&loops_cache_lock, THREAD_LOCK_WRITE);
152     /* We need to ensure array is still NULL inside mutex-protected code, some other thread might have already
153      * recomputed those looptris. */
154     if (mesh->runtime.looptris.array == NULL) {
155       BKE_mesh_runtime_looptri_recalc(mesh);
156     }
157     looptri = mesh->runtime.looptris.array;
158     BLI_rw_mutex_unlock(&loops_cache_lock);
159   }
160   return looptri;
161 }
162
163 /* This is a copy of DM_verttri_from_looptri(). */
164 void BKE_mesh_runtime_verttri_from_looptri(MVertTri *r_verttri,
165                                            const MLoop *mloop,
166                                            const MLoopTri *looptri,
167                                            int looptri_num)
168 {
169   int i;
170   for (i = 0; i < looptri_num; i++) {
171     r_verttri[i].tri[0] = mloop[looptri[i].tri[0]].v;
172     r_verttri[i].tri[1] = mloop[looptri[i].tri[1]].v;
173     r_verttri[i].tri[2] = mloop[looptri[i].tri[2]].v;
174   }
175 }
176
177 bool BKE_mesh_runtime_ensure_edit_data(struct Mesh *mesh)
178 {
179   if (mesh->runtime.edit_data != NULL) {
180     return false;
181   }
182
183   mesh->runtime.edit_data = MEM_callocN(sizeof(EditMeshData), "EditMeshData");
184   return true;
185 }
186
187 bool BKE_mesh_runtime_clear_edit_data(Mesh *mesh)
188 {
189   if (mesh->runtime.edit_data == NULL) {
190     return false;
191   }
192
193   if (mesh->runtime.edit_data->polyCos != NULL) {
194     MEM_freeN((void *)mesh->runtime.edit_data->polyCos);
195   }
196   if (mesh->runtime.edit_data->polyNos != NULL) {
197     MEM_freeN((void *)mesh->runtime.edit_data->polyNos);
198   }
199   if (mesh->runtime.edit_data->vertexCos != NULL) {
200     MEM_freeN((void *)mesh->runtime.edit_data->vertexCos);
201   }
202   if (mesh->runtime.edit_data->vertexNos != NULL) {
203     MEM_freeN((void *)mesh->runtime.edit_data->vertexNos);
204   }
205
206   MEM_SAFE_FREE(mesh->runtime.edit_data);
207   return true;
208 }
209
210 void BKE_mesh_runtime_clear_geometry(Mesh *mesh)
211 {
212   bvhcache_free(&mesh->runtime.bvh_cache);
213   MEM_SAFE_FREE(mesh->runtime.looptris.array);
214   /* TODO(sergey): Does this really belong here? */
215   if (mesh->runtime.subdiv_ccg != NULL) {
216     BKE_subdiv_ccg_destroy(mesh->runtime.subdiv_ccg);
217     mesh->runtime.subdiv_ccg = NULL;
218   }
219   BKE_shrinkwrap_discard_boundary_data(mesh);
220 }
221
222 /** \} */
223
224 /* -------------------------------------------------------------------- */
225 /** \name Mesh Batch Cache Callbacks
226  * \{ */
227
228 /* Draw Engine */
229 void (*BKE_mesh_batch_cache_dirty_tag_cb)(Mesh *me, int mode) = NULL;
230 void (*BKE_mesh_batch_cache_free_cb)(Mesh *me) = NULL;
231
232 void BKE_mesh_batch_cache_dirty_tag(Mesh *me, int mode)
233 {
234   if (me->runtime.batch_cache) {
235     BKE_mesh_batch_cache_dirty_tag_cb(me, mode);
236   }
237 }
238 void BKE_mesh_batch_cache_free(Mesh *me)
239 {
240   if (me->runtime.batch_cache) {
241     BKE_mesh_batch_cache_free_cb(me);
242   }
243 }
244
245 /** \} */
246
247 /** \name Mesh runtime debug helpers.
248  * \{ */
249 /* evaluated mesh info printing function,
250  * to help track down differences output */
251
252 #ifndef NDEBUG
253 #  include "BLI_dynstr.h"
254
255 static void mesh_runtime_debug_info_layers(DynStr *dynstr, CustomData *cd)
256 {
257   int type;
258
259   for (type = 0; type < CD_NUMTYPES; type++) {
260     if (CustomData_has_layer(cd, type)) {
261       /* note: doesn't account for multiple layers */
262       const char *name = CustomData_layertype_name(type);
263       const int size = CustomData_sizeof(type);
264       const void *pt = CustomData_get_layer(cd, type);
265       const int pt_size = pt ? (int)(MEM_allocN_len(pt) / size) : 0;
266       const char *structname;
267       int structnum;
268       CustomData_file_write_info(type, &structname, &structnum);
269       BLI_dynstr_appendf(
270           dynstr,
271           "        dict(name='%s', struct='%s', type=%d, ptr='%p', elem=%d, length=%d),\n",
272           name,
273           structname,
274           type,
275           (const void *)pt,
276           size,
277           pt_size);
278     }
279   }
280 }
281
282 char *BKE_mesh_runtime_debug_info(Mesh *me_eval)
283 {
284   DynStr *dynstr = BLI_dynstr_new();
285   char *ret;
286
287   BLI_dynstr_append(dynstr, "{\n");
288   BLI_dynstr_appendf(dynstr, "    'ptr': '%p',\n", (void *)me_eval);
289 #  if 0
290   const char *tstr;
291   switch (me_eval->type) {
292     case DM_TYPE_CDDM:
293       tstr = "DM_TYPE_CDDM";
294       break;
295     case DM_TYPE_CCGDM:
296       tstr = "DM_TYPE_CCGDM";
297       break;
298     default:
299       tstr = "UNKNOWN";
300       break;
301   }
302   BLI_dynstr_appendf(dynstr, "    'type': '%s',\n", tstr);
303 #  endif
304   BLI_dynstr_appendf(dynstr, "    'totvert': %d,\n", me_eval->totvert);
305   BLI_dynstr_appendf(dynstr, "    'totedge': %d,\n", me_eval->totedge);
306   BLI_dynstr_appendf(dynstr, "    'totface': %d,\n", me_eval->totface);
307   BLI_dynstr_appendf(dynstr, "    'totpoly': %d,\n", me_eval->totpoly);
308   BLI_dynstr_appendf(dynstr, "    'deformed_only': %d,\n", me_eval->runtime.deformed_only);
309
310   BLI_dynstr_append(dynstr, "    'vertexLayers': (\n");
311   mesh_runtime_debug_info_layers(dynstr, &me_eval->vdata);
312   BLI_dynstr_append(dynstr, "    ),\n");
313
314   BLI_dynstr_append(dynstr, "    'edgeLayers': (\n");
315   mesh_runtime_debug_info_layers(dynstr, &me_eval->edata);
316   BLI_dynstr_append(dynstr, "    ),\n");
317
318   BLI_dynstr_append(dynstr, "    'loopLayers': (\n");
319   mesh_runtime_debug_info_layers(dynstr, &me_eval->ldata);
320   BLI_dynstr_append(dynstr, "    ),\n");
321
322   BLI_dynstr_append(dynstr, "    'polyLayers': (\n");
323   mesh_runtime_debug_info_layers(dynstr, &me_eval->pdata);
324   BLI_dynstr_append(dynstr, "    ),\n");
325
326   BLI_dynstr_append(dynstr, "    'tessFaceLayers': (\n");
327   mesh_runtime_debug_info_layers(dynstr, &me_eval->fdata);
328   BLI_dynstr_append(dynstr, "    ),\n");
329
330   BLI_dynstr_append(dynstr, "}\n");
331
332   ret = BLI_dynstr_get_cstring(dynstr);
333   BLI_dynstr_free(dynstr);
334   return ret;
335 }
336
337 void BKE_mesh_runtime_debug_print(Mesh *me_eval)
338 {
339   char *str = BKE_mesh_runtime_debug_info(me_eval);
340   puts(str);
341   fflush(stdout);
342   MEM_freeN(str);
343 }
344
345 /* XXX Should go in customdata file? */
346 void BKE_mesh_runtime_debug_print_cdlayers(CustomData *data)
347 {
348   int i;
349   const CustomDataLayer *layer;
350
351   printf("{\n");
352
353   for (i = 0, layer = data->layers; i < data->totlayer; i++, layer++) {
354
355     const char *name = CustomData_layertype_name(layer->type);
356     const int size = CustomData_sizeof(layer->type);
357     const char *structname;
358     int structnum;
359     CustomData_file_write_info(layer->type, &structname, &structnum);
360     printf("        dict(name='%s', struct='%s', type=%d, ptr='%p', elem=%d, length=%d),\n",
361            name,
362            structname,
363            layer->type,
364            (const void *)layer->data,
365            size,
366            (int)(MEM_allocN_len(layer->data) / size));
367   }
368
369   printf("}\n");
370 }
371
372 bool BKE_mesh_runtime_is_valid(Mesh *me_eval)
373 {
374   const bool do_verbose = true;
375   const bool do_fixes = false;
376
377   bool is_valid = true;
378   bool changed = true;
379
380   if (do_verbose) {
381     printf("MESH: %s\n", me_eval->id.name + 2);
382   }
383
384   is_valid &= BKE_mesh_validate_all_customdata(
385       &me_eval->vdata,
386       me_eval->totvert,
387       &me_eval->edata,
388       me_eval->totedge,
389       &me_eval->ldata,
390       me_eval->totloop,
391       &me_eval->pdata,
392       me_eval->totpoly,
393       false, /* setting mask here isn't useful, gives false positives */
394       do_verbose,
395       do_fixes,
396       &changed);
397
398   is_valid &= BKE_mesh_validate_arrays(me_eval,
399                                        me_eval->mvert,
400                                        me_eval->totvert,
401                                        me_eval->medge,
402                                        me_eval->totedge,
403                                        me_eval->mface,
404                                        me_eval->totface,
405                                        me_eval->mloop,
406                                        me_eval->totloop,
407                                        me_eval->mpoly,
408                                        me_eval->totpoly,
409                                        me_eval->dvert,
410                                        do_verbose,
411                                        do_fixes,
412                                        &changed);
413
414   BLI_assert(changed == false);
415
416   return is_valid;
417 }
418
419 #endif /* NDEBUG */
420
421 /** \} */