Merge branch 'blender2.7'
[blender.git] / source / blender / blenkernel / intern / subdiv_mesh.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2018 by Blender Foundation.
19  * All rights reserved.
20  *
21  * Contributor(s): Sergey Sharybin.
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  */
25
26 /** \file blender/blenkernel/intern/subdiv_mesh.c
27  *  \ingroup bke
28  */
29
30 #include "BKE_subdiv_mesh.h"
31
32 #include "atomic_ops.h"
33
34 #include "DNA_mesh_types.h"
35 #include "DNA_meshdata_types.h"
36 #include "DNA_key_types.h"
37
38 #include "BLI_alloca.h"
39 #include "BLI_bitmap.h"
40 #include "BLI_math_vector.h"
41 #include "BLI_task.h"
42
43 #include "BKE_mesh.h"
44 #include "BKE_key.h"
45 #include "BKE_subdiv.h"
46 #include "BKE_subdiv_eval.h"
47 #include "BKE_subdiv_foreach.h"
48
49 #include "MEM_guardedalloc.h"
50
51 /* =============================================================================
52  * Subdivision context.
53  */
54
55 typedef struct SubdivMeshContext {
56         const SubdivToMeshSettings *settings;
57         const Mesh *coarse_mesh;
58         Subdiv *subdiv;
59         Mesh *subdiv_mesh;
60         /* Cached custom data arrays for fastter access. */
61         int *vert_origindex;
62         int *edge_origindex;
63         int *loop_origindex;
64         int *poly_origindex;
65         /* UV layers interpolation. */
66         int num_uv_layers;
67         MLoopUV *uv_layers[MAX_MTFACE];
68 } SubdivMeshContext;
69
70 static void subdiv_mesh_ctx_cache_uv_layers(SubdivMeshContext *ctx)
71 {
72         Mesh *subdiv_mesh = ctx->subdiv_mesh;
73         ctx->num_uv_layers =
74                 CustomData_number_of_layers(&subdiv_mesh->ldata, CD_MLOOPUV);
75         for (int layer_index = 0; layer_index < ctx->num_uv_layers; ++layer_index) {
76                 ctx->uv_layers[layer_index] = CustomData_get_layer_n(
77                         &subdiv_mesh->ldata, CD_MLOOPUV, layer_index);
78         }
79 }
80
81 static void subdiv_mesh_ctx_cache_custom_data_layers(SubdivMeshContext *ctx)
82 {
83         Mesh *subdiv_mesh = ctx->subdiv_mesh;
84         /* Pointers to original indices layers. */
85         ctx->vert_origindex = CustomData_get_layer(
86                 &subdiv_mesh->vdata, CD_ORIGINDEX);
87         ctx->edge_origindex = CustomData_get_layer(
88                 &subdiv_mesh->edata, CD_ORIGINDEX);
89         ctx->loop_origindex = CustomData_get_layer(
90                 &subdiv_mesh->ldata, CD_ORIGINDEX);
91         ctx->poly_origindex = CustomData_get_layer(
92                 &subdiv_mesh->pdata, CD_ORIGINDEX);
93         /* UV layers interpolation. */
94         subdiv_mesh_ctx_cache_uv_layers(ctx);
95 }
96
97 /* =============================================================================
98  * Loop custom data copy helpers.
99  */
100
101 typedef struct LoopsOfPtex {
102         /* First loop of the ptex, starts at ptex (0, 0) and goes in u direction. */
103         const MLoop *first_loop;
104         /* Last loop of the ptex, starts at ptex (0, 0) and goes in v direction. */
105         const MLoop *last_loop;
106         /* For quad coarse faces only. */
107         const MLoop *second_loop;
108         const MLoop *third_loop;
109 } LoopsOfPtex;
110
111 static void loops_of_ptex_get(
112         const SubdivMeshContext *ctx,
113         LoopsOfPtex *loops_of_ptex,
114         const MPoly *coarse_poly,
115         const int ptex_of_poly_index)
116 {
117         const MLoop *coarse_mloop = ctx->coarse_mesh->mloop;
118         const int first_ptex_loop_index =
119                 coarse_poly->loopstart + ptex_of_poly_index;
120         /* Loop which look in the (opposite) V direction of the current
121          * ptex face.
122          *
123          * TODO(sergey): Get rid of using module on every iteration.
124          */
125         const int last_ptex_loop_index =
126                 coarse_poly->loopstart +
127                 (ptex_of_poly_index + coarse_poly->totloop - 1) %
128                         coarse_poly->totloop;
129         loops_of_ptex->first_loop = &coarse_mloop[first_ptex_loop_index];
130         loops_of_ptex->last_loop = &coarse_mloop[last_ptex_loop_index];
131         if (coarse_poly->totloop == 4) {
132                 loops_of_ptex->second_loop = loops_of_ptex->first_loop + 1;
133                 loops_of_ptex->third_loop = loops_of_ptex->first_loop + 2;
134         }
135         else {
136                 loops_of_ptex->second_loop = NULL;
137                 loops_of_ptex->third_loop = NULL;
138         }
139 }
140
141 /* =============================================================================
142  * Vertex custom data interpolation helpers.
143  */
144
145 /* TODO(sergey): Somehow de-duplicate with loops storage, without too much
146  * exception cases all over the code.
147  */
148
149 typedef struct VerticesForInterpolation {
150         /* This field points to a vertex data which is to be used for interpolation.
151          * The idea is to avoid unnecessary allocations for regular faces, where
152          * we can simply
153          */
154         const CustomData *vertex_data;
155         /* Vertices data calculated for ptex corners. There are always 4 elements
156          * in this custom data, aligned the following way:
157          *
158          *   index 0 -> uv (0, 0)
159          *   index 1 -> uv (0, 1)
160          *   index 2 -> uv (1, 1)
161          *   index 3 -> uv (1, 0)
162          *
163          * Is allocated for non-regular faces (triangles and n-gons).
164          */
165         CustomData vertex_data_storage;
166         bool vertex_data_storage_allocated;
167         /* Infices within vertex_data to interpolate for. The indices are aligned
168          * with uv coordinates in a similar way as indices in loop_data_storage.
169          */
170         int vertex_indices[4];
171 } VerticesForInterpolation;
172
173 static void vertex_interpolation_init(
174         const SubdivMeshContext *ctx,
175         VerticesForInterpolation *vertex_interpolation,
176         const MPoly *coarse_poly)
177 {
178         const Mesh *coarse_mesh = ctx->coarse_mesh;
179         const MLoop *coarse_mloop = coarse_mesh->mloop;
180         if (coarse_poly->totloop == 4) {
181                 vertex_interpolation->vertex_data = &coarse_mesh->vdata;
182                 vertex_interpolation->vertex_indices[0] =
183                         coarse_mloop[coarse_poly->loopstart + 0].v;
184                 vertex_interpolation->vertex_indices[1] =
185                         coarse_mloop[coarse_poly->loopstart + 1].v;
186                 vertex_interpolation->vertex_indices[2] =
187                         coarse_mloop[coarse_poly->loopstart + 2].v;
188                 vertex_interpolation->vertex_indices[3] =
189                         coarse_mloop[coarse_poly->loopstart + 3].v;
190                 vertex_interpolation->vertex_data_storage_allocated = false;
191         }
192         else {
193                 vertex_interpolation->vertex_data =
194                         &vertex_interpolation->vertex_data_storage;
195                 /* Allocate storage for loops corresponding to ptex corners. */
196                 CustomData_copy(&ctx->coarse_mesh->vdata,
197                                 &vertex_interpolation->vertex_data_storage,
198                                 CD_MASK_EVERYTHING,
199                                 CD_CALLOC,
200                                 4);
201                 /* Initialize indices. */
202                 vertex_interpolation->vertex_indices[0] = 0;
203                 vertex_interpolation->vertex_indices[1] = 1;
204                 vertex_interpolation->vertex_indices[2] = 2;
205                 vertex_interpolation->vertex_indices[3] = 3;
206                 vertex_interpolation->vertex_data_storage_allocated = true;
207                 /* Interpolate center of poly right away, it stays unchanged for all
208                  * ptex faces.
209                  */
210                 const float weight = 1.0f / (float)coarse_poly->totloop;
211                 float *weights = BLI_array_alloca(weights, coarse_poly->totloop);
212                 int *indices = BLI_array_alloca(indices, coarse_poly->totloop);
213                 for (int i = 0; i < coarse_poly->totloop; ++i) {
214                         weights[i] = weight;
215                         indices[i] = coarse_mloop[coarse_poly->loopstart + i].v;
216                 }
217                 CustomData_interp(&coarse_mesh->vdata,
218                                   &vertex_interpolation->vertex_data_storage,
219                                   indices,
220                                   weights, NULL,
221                                   coarse_poly->totloop,
222                                   2);
223         }
224 }
225
226 static void vertex_interpolation_from_corner(
227         const SubdivMeshContext *ctx,
228         VerticesForInterpolation *vertex_interpolation,
229         const MPoly *coarse_poly,
230         const int corner)
231 {
232         if (coarse_poly->totloop == 4) {
233                 /* Nothing to do, all indices and data is already assigned. */
234         }
235         else {
236                 const CustomData *vertex_data = &ctx->coarse_mesh->vdata;
237                 const Mesh *coarse_mesh = ctx->coarse_mesh;
238                 const MLoop *coarse_mloop = coarse_mesh->mloop;
239                 LoopsOfPtex loops_of_ptex;
240                 loops_of_ptex_get(ctx, &loops_of_ptex, coarse_poly, corner);
241                 /* Ptex face corner corresponds to a poly loop with same index. */
242                 CustomData_copy_data(
243                         vertex_data,
244                         &vertex_interpolation->vertex_data_storage,
245                         coarse_mloop[coarse_poly->loopstart + corner].v,
246                         0,
247                         1);
248                 /* Interpolate remaining ptex face corners, which hits loops
249                  * middle points.
250                  *
251                  * TODO(sergey): Re-use one of interpolation results from previous
252                  * iteration.
253                  */
254                 const float weights[2] = {0.5f, 0.5f};
255                 const int first_loop_index = loops_of_ptex.first_loop - coarse_mloop;
256                 const int last_loop_index = loops_of_ptex.last_loop - coarse_mloop;
257                 const int first_indices[2] = {
258                         coarse_mloop[first_loop_index].v,
259                         coarse_mloop[coarse_poly->loopstart +
260                                 (first_loop_index - coarse_poly->loopstart + 1) %
261                                         coarse_poly->totloop].v};
262                 const int last_indices[2] = {coarse_mloop[first_loop_index].v,
263                                              coarse_mloop[last_loop_index].v};
264                 CustomData_interp(vertex_data,
265                                   &vertex_interpolation->vertex_data_storage,
266                                   first_indices,
267                                   weights, NULL,
268                                   2,
269                                   1);
270                 CustomData_interp(vertex_data,
271                                   &vertex_interpolation->vertex_data_storage,
272                                   last_indices,
273                                   weights, NULL,
274                                   2,
275                                   3);
276         }
277 }
278
279 static void vertex_interpolation_end(
280         VerticesForInterpolation *vertex_interpolation)
281 {
282         if (vertex_interpolation->vertex_data_storage_allocated) {
283                 CustomData_free(&vertex_interpolation->vertex_data_storage, 4);
284         }
285 }
286
287 /* =============================================================================
288  * Loop custom data interpolation helpers.
289  */
290
291 typedef struct LoopsForInterpolation {
292  /* This field points to a loop data which is to be used for interpolation.
293          * The idea is to avoid unnecessary allocations for regular faces, where
294          * we can simply
295          */
296         const CustomData *loop_data;
297         /* Loops data calculated for ptex corners. There are always 4 elements
298          * in this custom data, aligned the following way:
299          *
300          *   index 0 -> uv (0, 0)
301          *   index 1 -> uv (0, 1)
302          *   index 2 -> uv (1, 1)
303          *   index 3 -> uv (1, 0)
304          *
305          * Is allocated for non-regular faces (triangles and n-gons).
306          */
307         CustomData loop_data_storage;
308         bool loop_data_storage_allocated;
309         /* Infices within loop_data to interpolate for. The indices are aligned with
310          * uv coordinates in a similar way as indices in loop_data_storage.
311          */
312         int loop_indices[4];
313 } LoopsForInterpolation;
314
315 static void loop_interpolation_init(
316         const SubdivMeshContext *ctx,
317         LoopsForInterpolation *loop_interpolation,
318         const MPoly *coarse_poly)
319 {
320         const Mesh *coarse_mesh = ctx->coarse_mesh;
321         if (coarse_poly->totloop == 4) {
322                 loop_interpolation->loop_data = &coarse_mesh->ldata;
323                 loop_interpolation->loop_indices[0] = coarse_poly->loopstart + 0;
324                 loop_interpolation->loop_indices[1] = coarse_poly->loopstart + 1;
325                 loop_interpolation->loop_indices[2] = coarse_poly->loopstart + 2;
326                 loop_interpolation->loop_indices[3] = coarse_poly->loopstart + 3;
327                 loop_interpolation->loop_data_storage_allocated = false;
328         }
329         else {
330                 loop_interpolation->loop_data = &loop_interpolation->loop_data_storage;
331                 /* Allocate storage for loops corresponding to ptex corners. */
332                 CustomData_copy(&ctx->coarse_mesh->ldata,
333                                 &loop_interpolation->loop_data_storage,
334                                 CD_MASK_EVERYTHING,
335                                 CD_CALLOC,
336                                 4);
337                 /* Initialize indices. */
338                 loop_interpolation->loop_indices[0] = 0;
339                 loop_interpolation->loop_indices[1] = 1;
340                 loop_interpolation->loop_indices[2] = 2;
341                 loop_interpolation->loop_indices[3] = 3;
342                 loop_interpolation->loop_data_storage_allocated = true;
343                 /* Interpolate center of poly right away, it stays unchanged for all
344                  * ptex faces.
345                  */
346                 const float weight = 1.0f / (float)coarse_poly->totloop;
347                 float *weights = BLI_array_alloca(weights, coarse_poly->totloop);
348                 int *indices = BLI_array_alloca(indices, coarse_poly->totloop);
349                 for (int i = 0; i < coarse_poly->totloop; ++i) {
350                         weights[i] = weight;
351                         indices[i] = coarse_poly->loopstart + i;
352                 }
353                 CustomData_interp(&coarse_mesh->ldata,
354                                   &loop_interpolation->loop_data_storage,
355                                   indices,
356                                   weights, NULL,
357                                   coarse_poly->totloop,
358                                   2);
359         }
360 }
361
362 static void loop_interpolation_from_corner(
363         const SubdivMeshContext *ctx,
364         LoopsForInterpolation *loop_interpolation,
365         const MPoly *coarse_poly,
366         const int corner)
367 {
368         if (coarse_poly->totloop == 4) {
369                 /* Nothing to do, all indices and data is already assigned. */
370         }
371         else {
372                 const CustomData *loop_data = &ctx->coarse_mesh->ldata;
373                 const Mesh *coarse_mesh = ctx->coarse_mesh;
374                 const MLoop *coarse_mloop = coarse_mesh->mloop;
375                 LoopsOfPtex loops_of_ptex;
376                 loops_of_ptex_get(ctx, &loops_of_ptex, coarse_poly, corner);
377                 /* Ptex face corner corresponds to a poly loop with same index. */
378                 CustomData_free_elem(&loop_interpolation->loop_data_storage, 0, 1);
379                 CustomData_copy_data(loop_data,
380                                      &loop_interpolation->loop_data_storage,
381                                      coarse_poly->loopstart + corner,
382                                      0,
383                                      1);
384                 /* Interpolate remaining ptex face corners, which hits loops
385                  * middle points.
386                  *
387                  * TODO(sergey): Re-use one of interpolation results from previous
388                  * iteration. */
389                 const float weights[2] = {0.5f, 0.5f};
390                 const int base_loop_index = coarse_poly->loopstart;
391                 const int first_loop_index = loops_of_ptex.first_loop - coarse_mloop;
392                 const int second_loop_index =
393                         base_loop_index +
394                         (first_loop_index - base_loop_index + 1) % coarse_poly->totloop;
395                 const int first_indices[2] = {first_loop_index, second_loop_index};
396                 const int last_indices[2] = {
397                         loops_of_ptex.last_loop - coarse_mloop,
398                         loops_of_ptex.first_loop - coarse_mloop};
399                 CustomData_interp(loop_data,
400                                   &loop_interpolation->loop_data_storage,
401                                   first_indices,
402                                   weights, NULL,
403                                   2,
404                                   1);
405                 CustomData_interp(loop_data,
406                                   &loop_interpolation->loop_data_storage,
407                                   last_indices,
408                                   weights, NULL,
409                                   2,
410                                   3);
411         }
412 }
413
414 static void loop_interpolation_end(LoopsForInterpolation *loop_interpolation)
415 {
416         if (loop_interpolation->loop_data_storage_allocated) {
417                 CustomData_free(&loop_interpolation->loop_data_storage, 4);
418         }
419 }
420
421 /* =============================================================================
422  * TLS.
423  */
424
425 typedef struct SubdivMeshTLS {
426         bool vertex_interpolation_initialized;
427         VerticesForInterpolation vertex_interpolation;
428         const MPoly *vertex_interpolation_coarse_poly;
429         int vertex_interpolation_coarse_corner;
430
431         bool loop_interpolation_initialized;
432         LoopsForInterpolation loop_interpolation;
433         const MPoly *loop_interpolation_coarse_poly;
434         int loop_interpolation_coarse_corner;
435 } SubdivMeshTLS;
436
437 static void subdiv_mesh_tls_free(void *tls_v)
438 {
439         SubdivMeshTLS *tls = tls_v;
440         if (tls->vertex_interpolation_initialized) {
441                 vertex_interpolation_end(&tls->vertex_interpolation);
442         }
443         if (tls->loop_interpolation_initialized) {
444                 loop_interpolation_end(&tls->loop_interpolation);
445         }
446 }
447
448 /* =============================================================================
449  * Evaluation helper functions.
450  */
451
452 static void eval_final_point_and_vertex_normal(
453         Subdiv *subdiv,
454         const int ptex_face_index,
455         const float u, const float v,
456         float r_P[3], short r_N[3])
457 {
458         if (subdiv->displacement_evaluator == NULL) {
459                 BKE_subdiv_eval_limit_point_and_short_normal(
460                         subdiv, ptex_face_index, u, v, r_P, r_N);
461         }
462         else {
463                 BKE_subdiv_eval_final_point(
464                         subdiv, ptex_face_index, u, v, r_P);
465         }
466 }
467
468 /* =============================================================================
469  * Displacement helpers
470  */
471
472 static void subdiv_accumulate_vertex_displacement(
473         Subdiv *subdiv,
474         const int ptex_face_index,
475         const float u, const float v,
476         MVert *subdiv_vert)
477 {
478         float dummy_P[3], dPdu[3], dPdv[3], D[3];
479         BKE_subdiv_eval_limit_point_and_derivatives(
480                 subdiv, ptex_face_index, u, v, dummy_P, dPdu, dPdv);
481         BKE_subdiv_eval_displacement(subdiv,
482                                      ptex_face_index, u, v,
483                                      dPdu, dPdv,
484                                      D);
485         add_v3_v3(subdiv_vert->co, D);
486         if (subdiv_vert->flag & ME_VERT_TMP_TAG) {
487                 mul_v3_fl(subdiv_vert->co, 0.5f);
488         }
489         subdiv_vert->flag |= ME_VERT_TMP_TAG;
490 }
491
492 /* =============================================================================
493  * Callbacks.
494  */
495
496 static bool subdiv_mesh_topology_info(
497         const SubdivForeachContext *foreach_context,
498         const int num_vertices,
499         const int num_edges,
500         const int num_loops,
501         const int num_polygons)
502 {
503         SubdivMeshContext *subdiv_context = foreach_context->user_data;
504         subdiv_context->subdiv_mesh = BKE_mesh_new_nomain_from_template(
505                 subdiv_context->coarse_mesh,
506                 num_vertices,
507                 num_edges,
508                 0,
509                 num_loops,
510                 num_polygons);
511         subdiv_mesh_ctx_cache_custom_data_layers(subdiv_context);
512         return true;
513 }
514
515 /* =============================================================================
516  * Vertex subdivision process.
517  */
518
519 static void subdiv_vertex_data_copy(
520         const SubdivMeshContext *ctx,
521         const MVert *coarse_vertex,
522         MVert *subdiv_vertex)
523 {
524         const Mesh *coarse_mesh = ctx->coarse_mesh;
525         Mesh *subdiv_mesh = ctx->subdiv_mesh;
526         const int coarse_vertex_index = coarse_vertex - coarse_mesh->mvert;
527         const int subdiv_vertex_index = subdiv_vertex - subdiv_mesh->mvert;
528         subdiv_vertex->flag &= ~ME_VERT_TMP_TAG;
529         CustomData_copy_data(&coarse_mesh->vdata,
530                              &ctx->subdiv_mesh->vdata,
531                              coarse_vertex_index,
532                              subdiv_vertex_index,
533                              1);
534 }
535
536 static void subdiv_vertex_data_interpolate(
537         const SubdivMeshContext *ctx,
538         MVert *subdiv_vertex,
539         const VerticesForInterpolation *vertex_interpolation,
540         const float u, const float v)
541 {
542         const int subdiv_vertex_index = subdiv_vertex - ctx->subdiv_mesh->mvert;
543         const float weights[4] = {(1.0f - u) * (1.0f - v),
544                                   u * (1.0f - v),
545                                   u * v,
546                                   (1.0f - u) * v};
547         subdiv_vertex->flag &= ~ME_VERT_TMP_TAG;
548         CustomData_interp(vertex_interpolation->vertex_data,
549                           &ctx->subdiv_mesh->vdata,
550                           vertex_interpolation->vertex_indices,
551                           weights, NULL,
552                           4,
553                           subdiv_vertex_index);
554         if (ctx->vert_origindex != NULL) {
555                 ctx->vert_origindex[subdiv_vertex_index] = ORIGINDEX_NONE;
556         }
557 }
558
559 static void evaluate_vertex_and_apply_displacement_copy(
560         const SubdivMeshContext *ctx,
561         const int ptex_face_index,
562         const float u, const float v,
563         const MVert *coarse_vert,
564         MVert *subdiv_vert)
565 {
566         /* Displacement is accumulated in subdiv vertex position.
567          * need to back it up before copying data from original vertex.
568          */
569         float D[3];
570         copy_v3_v3(D, subdiv_vert->co);
571         subdiv_vertex_data_copy(ctx, coarse_vert, subdiv_vert);
572         BKE_subdiv_eval_limit_point_and_short_normal(
573                 ctx->subdiv,
574                 ptex_face_index,
575                 u, v,
576                 subdiv_vert->co, subdiv_vert->no);
577         /* Apply displacement. */
578         add_v3_v3(subdiv_vert->co, D);
579 }
580
581 static void evaluate_vertex_and_apply_displacement_interpolate(
582         const SubdivMeshContext *ctx,
583         const int ptex_face_index,
584         const float u, const float v,
585         VerticesForInterpolation *vertex_interpolation,
586         MVert *subdiv_vert)
587 {
588         /* Displacement is accumulated in subdiv vertex position.
589          * need to back it up before copying data from original vertex.
590          */
591         float D[3];
592         copy_v3_v3(D, subdiv_vert->co);
593         subdiv_vertex_data_interpolate(ctx,
594                                        subdiv_vert,
595                                        vertex_interpolation,
596                                        u, v);
597         BKE_subdiv_eval_limit_point_and_short_normal(
598                 ctx->subdiv,
599                 ptex_face_index,
600                 u, v,
601                 subdiv_vert->co, subdiv_vert->no);
602         /* Apply displacement. */
603         add_v3_v3(subdiv_vert->co, D);
604 }
605
606 static void subdiv_mesh_vertex_every_corner_or_edge(
607         const SubdivForeachContext *foreach_context,
608         void *UNUSED(tls),
609         const int ptex_face_index,
610         const float u, const float v,
611         const int subdiv_vertex_index)
612 {
613         SubdivMeshContext *ctx = foreach_context->user_data;
614         Subdiv *subdiv = ctx->subdiv;
615         Mesh *subdiv_mesh = ctx->subdiv_mesh;
616         MVert *subdiv_mvert = subdiv_mesh->mvert;
617         MVert *subdiv_vert = &subdiv_mvert[subdiv_vertex_index];
618         subdiv_accumulate_vertex_displacement(
619                 subdiv, ptex_face_index, u, v, subdiv_vert);
620 }
621
622 static void subdiv_mesh_vertex_every_corner(
623         const SubdivForeachContext *foreach_context,
624         void *tls,
625         const int ptex_face_index,
626         const float u, const float v,
627         const int UNUSED(coarse_vertex_index),
628         const int UNUSED(coarse_poly_index),
629         const int UNUSED(coarse_corner),
630         const int subdiv_vertex_index)
631 {
632         subdiv_mesh_vertex_every_corner_or_edge(
633                 foreach_context, tls, ptex_face_index, u, v, subdiv_vertex_index);
634 }
635
636 static void subdiv_mesh_vertex_every_edge(
637         const SubdivForeachContext *foreach_context,
638         void *tls,
639         const int ptex_face_index,
640         const float u, const float v,
641         const int UNUSED(coarse_edge_index),
642         const int UNUSED(coarse_poly_index),
643         const int UNUSED(coarse_corner),
644         const int subdiv_vertex_index)
645 {
646         subdiv_mesh_vertex_every_corner_or_edge(
647                 foreach_context, tls, ptex_face_index, u, v, subdiv_vertex_index);
648 }
649
650 static void subdiv_mesh_vertex_corner(
651         const SubdivForeachContext *foreach_context,
652         void *UNUSED(tls),
653         const int ptex_face_index,
654         const float u, const float v,
655         const int coarse_vertex_index,
656         const int UNUSED(coarse_poly_index),
657         const int UNUSED(coarse_corner),
658         const int subdiv_vertex_index)
659 {
660         BLI_assert(coarse_vertex_index != ORIGINDEX_NONE);
661         SubdivMeshContext *ctx = foreach_context->user_data;
662         const Mesh *coarse_mesh = ctx->coarse_mesh;
663         const MVert *coarse_mvert = coarse_mesh->mvert;
664         Mesh *subdiv_mesh = ctx->subdiv_mesh;
665         MVert *subdiv_mvert = subdiv_mesh->mvert;
666         const MVert *coarse_vert = &coarse_mvert[coarse_vertex_index];
667         MVert *subdiv_vert = &subdiv_mvert[subdiv_vertex_index];
668         evaluate_vertex_and_apply_displacement_copy(
669                 ctx, ptex_face_index, u, v, coarse_vert, subdiv_vert);
670 }
671
672 static void subdiv_mesh_ensure_vertex_interpolation(
673         SubdivMeshContext *ctx,
674         SubdivMeshTLS *tls,
675         const MPoly *coarse_poly,
676         const int coarse_corner)
677 {
678         /* Check whether we've moved to another corner or polygon. */
679         if (tls->vertex_interpolation_initialized) {
680                 if (tls->vertex_interpolation_coarse_poly != coarse_poly ||
681                     tls->vertex_interpolation_coarse_corner != coarse_corner)
682                 {
683                         vertex_interpolation_end(&tls->vertex_interpolation);
684                         tls->vertex_interpolation_initialized = false;
685                 }
686         }
687         /* Initialize the interpolation. */
688         if (!tls->vertex_interpolation_initialized) {
689                 vertex_interpolation_init(ctx, &tls->vertex_interpolation, coarse_poly);
690         }
691         /* Update it for a new corner if needed. */
692         if (!tls->vertex_interpolation_initialized ||
693             tls->vertex_interpolation_coarse_corner != coarse_corner)
694         {
695                 vertex_interpolation_from_corner(
696                         ctx, &tls->vertex_interpolation, coarse_poly, coarse_corner);
697         }
698         /* Store settings used for the current state of interpolator. */
699         tls->vertex_interpolation_initialized = true;
700         tls->vertex_interpolation_coarse_poly = coarse_poly;
701         tls->vertex_interpolation_coarse_corner = coarse_corner;
702 }
703
704 static void subdiv_mesh_vertex_edge(
705         const SubdivForeachContext *foreach_context,
706         void *tls_v,
707         const int ptex_face_index,
708         const float u, const float v,
709         const int UNUSED(coarse_edge_index),
710         const int coarse_poly_index,
711         const int coarse_corner,
712         const int subdiv_vertex_index)
713 {
714         SubdivMeshContext *ctx = foreach_context->user_data;
715         SubdivMeshTLS *tls = tls_v;
716         const Mesh *coarse_mesh = ctx->coarse_mesh;
717         const MPoly *coarse_mpoly = coarse_mesh->mpoly;
718         const MPoly *coarse_poly = &coarse_mpoly[coarse_poly_index];
719         Mesh *subdiv_mesh = ctx->subdiv_mesh;
720         MVert *subdiv_mvert = subdiv_mesh->mvert;
721         MVert *subdiv_vert = &subdiv_mvert[subdiv_vertex_index];
722         subdiv_mesh_ensure_vertex_interpolation(
723                 ctx, tls, coarse_poly, coarse_corner);
724         evaluate_vertex_and_apply_displacement_interpolate(
725                 ctx,
726                 ptex_face_index, u, v,
727                 &tls->vertex_interpolation,
728                 subdiv_vert);
729 }
730
731 static void subdiv_mesh_vertex_inner(
732         const SubdivForeachContext *foreach_context,
733         void *tls_v,
734         const int ptex_face_index,
735         const float u, const float v,
736         const int coarse_poly_index,
737         const int coarse_corner,
738         const int subdiv_vertex_index)
739 {
740         SubdivMeshContext *ctx = foreach_context->user_data;
741         SubdivMeshTLS *tls = tls_v;
742         Subdiv *subdiv = ctx->subdiv;
743         const Mesh *coarse_mesh = ctx->coarse_mesh;
744         const MPoly *coarse_mpoly = coarse_mesh->mpoly;
745         const MPoly *coarse_poly = &coarse_mpoly[coarse_poly_index];
746         Mesh *subdiv_mesh = ctx->subdiv_mesh;
747         MVert *subdiv_mvert = subdiv_mesh->mvert;
748         MVert *subdiv_vert = &subdiv_mvert[subdiv_vertex_index];
749         subdiv_mesh_ensure_vertex_interpolation(
750                 ctx, tls, coarse_poly, coarse_corner);
751         subdiv_vertex_data_interpolate(
752                 ctx, subdiv_vert, &tls->vertex_interpolation, u, v);
753         eval_final_point_and_vertex_normal(
754                 subdiv, ptex_face_index, u, v, subdiv_vert->co, subdiv_vert->no);
755 }
756
757 /* =============================================================================
758  * Edge subdivision process.
759  */
760
761 static void subdiv_copy_edge_data(
762         SubdivMeshContext *ctx,
763         MEdge *subdiv_edge,
764         const MEdge *coarse_edge)
765 {
766         const int subdiv_edge_index = subdiv_edge - ctx->subdiv_mesh->medge;
767         if (coarse_edge == NULL) {
768                 subdiv_edge->crease = 0;
769                 subdiv_edge->bweight = 0;
770                 subdiv_edge->flag = 0;
771                 if (!ctx->settings->use_optimal_display) {
772                         subdiv_edge->flag |= ME_EDGERENDER;
773                 }
774                 if (ctx->edge_origindex != NULL) {
775                         ctx->edge_origindex[subdiv_edge_index] = ORIGINDEX_NONE;
776                 }
777                 return;
778         }
779         const int coarse_edge_index = coarse_edge - ctx->coarse_mesh->medge;
780         CustomData_copy_data(&ctx->coarse_mesh->edata,
781                              &ctx->subdiv_mesh->edata,
782                              coarse_edge_index,
783                              subdiv_edge_index,
784                              1);
785         subdiv_edge->flag |= ME_EDGERENDER;
786 }
787
788 static void subdiv_mesh_edge(
789         const SubdivForeachContext *foreach_context,
790         void *UNUSED(tls),
791         const int coarse_edge_index,
792         const int subdiv_edge_index,
793         const int subdiv_v1, const int subdiv_v2)
794 {
795         SubdivMeshContext *ctx = foreach_context->user_data;
796         Mesh *subdiv_mesh = ctx->subdiv_mesh;
797         MEdge *subdiv_medge = subdiv_mesh->medge;
798         MEdge *subdiv_edge = &subdiv_medge[subdiv_edge_index];
799         const MEdge *coarse_edge = NULL;
800         if (coarse_edge_index != ORIGINDEX_NONE) {
801                 const Mesh *coarse_mesh = ctx->coarse_mesh;
802                 const MEdge *coarse_medge = coarse_mesh->medge;
803                 coarse_edge = &coarse_medge[coarse_edge_index];
804         }
805         subdiv_copy_edge_data(ctx, subdiv_edge, coarse_edge);
806         subdiv_edge->v1 = subdiv_v1;
807         subdiv_edge->v2 = subdiv_v2;
808 }
809
810 /* =============================================================================
811  * Loops creation/interpolation.
812  */
813
814 static void subdiv_interpolate_loop_data(
815         const SubdivMeshContext *ctx,
816         MLoop *subdiv_loop,
817         const LoopsForInterpolation *loop_interpolation,
818         const float u, const float v)
819 {
820         const int subdiv_loop_index = subdiv_loop - ctx->subdiv_mesh->mloop;
821         const float weights[4] = {(1.0f - u) * (1.0f - v),
822                                   u * (1.0f - v),
823                                   u * v,
824                                   (1.0f - u) * v};
825         CustomData_interp(loop_interpolation->loop_data,
826                           &ctx->subdiv_mesh->ldata,
827                           loop_interpolation->loop_indices,
828                           weights, NULL,
829                           4,
830                           subdiv_loop_index);
831         /* TODO(sergey): Set ORIGINDEX. */
832 }
833
834 static void subdiv_eval_uv_layer(SubdivMeshContext *ctx,
835                                  MLoop *subdiv_loop,
836                                  const int ptex_face_index,
837                                  const float u, const float v)
838 {
839         if (ctx->num_uv_layers == 0) {
840                 return;
841         }
842         Subdiv *subdiv = ctx->subdiv;
843         const int mloop_index = subdiv_loop - ctx->subdiv_mesh->mloop;
844         for (int layer_index = 0; layer_index < ctx->num_uv_layers; layer_index++) {
845                 MLoopUV *subdiv_loopuv = &ctx->uv_layers[layer_index][mloop_index];
846                 BKE_subdiv_eval_face_varying(subdiv,
847                                              layer_index,
848                                              ptex_face_index,
849                                              u, v,
850                                              subdiv_loopuv->uv);
851         }
852 }
853
854 static void subdiv_mesh_ensure_loop_interpolation(
855         SubdivMeshContext *ctx,
856         SubdivMeshTLS *tls,
857         const MPoly *coarse_poly,
858         const int coarse_corner)
859 {
860         /* Check whether we've moved to another corner or polygon. */
861         if (tls->loop_interpolation_initialized) {
862                 if (tls->loop_interpolation_coarse_poly != coarse_poly ||
863                     tls->loop_interpolation_coarse_corner != coarse_corner)
864                 {
865                         loop_interpolation_end(&tls->loop_interpolation);
866                         tls->loop_interpolation_initialized = false;
867                 }
868         }
869         /* Initialize the interpolation. */
870         if (!tls->loop_interpolation_initialized) {
871                 loop_interpolation_init(ctx, &tls->loop_interpolation, coarse_poly);
872         }
873         /* Update it for a new corner if needed. */
874         if (!tls->loop_interpolation_initialized ||
875             tls->loop_interpolation_coarse_corner != coarse_corner)
876         {
877                 loop_interpolation_from_corner(
878                         ctx, &tls->loop_interpolation, coarse_poly, coarse_corner);
879         }
880         /* Store settings used for the current state of interpolator. */
881         tls->loop_interpolation_initialized = true;
882         tls->loop_interpolation_coarse_poly = coarse_poly;
883         tls->loop_interpolation_coarse_corner = coarse_corner;
884 }
885
886 static void subdiv_mesh_loop(
887         const SubdivForeachContext *foreach_context,
888         void *tls_v,
889         const int ptex_face_index,
890         const float u, const float v,
891         const int UNUSED(coarse_loop_index),
892         const int coarse_poly_index,
893         const int coarse_corner,
894         const int subdiv_loop_index,
895         const int subdiv_vertex_index, const int subdiv_edge_index)
896 {
897         SubdivMeshContext *ctx = foreach_context->user_data;
898         SubdivMeshTLS *tls = tls_v;
899         const Mesh *coarse_mesh = ctx->coarse_mesh;
900         const MPoly *coarse_mpoly = coarse_mesh->mpoly;
901         const MPoly *coarse_poly = &coarse_mpoly[coarse_poly_index];
902         Mesh *subdiv_mesh = ctx->subdiv_mesh;
903         MLoop *subdiv_mloop = subdiv_mesh->mloop;
904         MLoop *subdiv_loop = &subdiv_mloop[subdiv_loop_index];
905         subdiv_mesh_ensure_loop_interpolation(
906                 ctx, tls, coarse_poly, coarse_corner);
907         subdiv_interpolate_loop_data(
908                 ctx, subdiv_loop, &tls->loop_interpolation, u, v);
909         subdiv_eval_uv_layer(ctx, subdiv_loop, ptex_face_index, u, v);
910         subdiv_loop->v = subdiv_vertex_index;
911         subdiv_loop->e = subdiv_edge_index;
912 }
913
914 /* =============================================================================
915  * Polygons subdivision process.
916  */
917
918 static void subdiv_copy_poly_data(const SubdivMeshContext *ctx,
919                                   MPoly *subdiv_poly,
920                                   const MPoly *coarse_poly)
921 {
922         const int coarse_poly_index = coarse_poly - ctx->coarse_mesh->mpoly;
923         const int subdiv_poly_index = subdiv_poly - ctx->subdiv_mesh->mpoly;
924         CustomData_copy_data(&ctx->coarse_mesh->pdata,
925                              &ctx->subdiv_mesh->pdata,
926                              coarse_poly_index,
927                              subdiv_poly_index,
928                              1);
929 }
930
931 static void subdiv_mesh_poly(
932         const SubdivForeachContext *foreach_context,
933         void *UNUSED(tls),
934         const int coarse_poly_index,
935         const int subdiv_poly_index,
936         const int start_loop_index, const int num_loops)
937 {
938         BLI_assert(coarse_poly_index != ORIGINDEX_NONE);
939         SubdivMeshContext *ctx = foreach_context->user_data;
940         const Mesh *coarse_mesh = ctx->coarse_mesh;
941         const MPoly *coarse_mpoly = coarse_mesh->mpoly;
942         const MPoly *coarse_poly = &coarse_mpoly[coarse_poly_index];
943         Mesh *subdiv_mesh = ctx->subdiv_mesh;
944         MPoly *subdiv_mpoly = subdiv_mesh->mpoly;
945         MPoly *subdiv_poly = &subdiv_mpoly[subdiv_poly_index];
946         subdiv_copy_poly_data(ctx, subdiv_poly, coarse_poly);
947         subdiv_poly->loopstart = start_loop_index;
948         subdiv_poly->totloop = num_loops;
949 }
950
951 /* =============================================================================
952  * Loose elements subdivision process.
953  */
954
955 static void subdiv_mesh_vertex_loose(
956         const SubdivForeachContext *foreach_context,
957         void *UNUSED(tls),
958         const int coarse_vertex_index,
959         const int subdiv_vertex_index)
960 {
961         SubdivMeshContext *ctx = foreach_context->user_data;
962         const Mesh *coarse_mesh = ctx->coarse_mesh;
963         const MVert *coarse_mvert = coarse_mesh->mvert;
964         const MVert *coarse_vertex = &coarse_mvert[coarse_vertex_index];
965         Mesh *subdiv_mesh = ctx->subdiv_mesh;
966         MVert *subdiv_mvert = subdiv_mesh->mvert;
967         MVert *subdiv_vertex = &subdiv_mvert[subdiv_vertex_index];
968         subdiv_vertex_data_copy(ctx, coarse_vertex, subdiv_vertex);
969 }
970
971 /* Get neighbor edges of the given one.
972  * - neighbors[0] is an edge adjacent to edge->v1.
973  * - neighbors[1] is an edge adjacent to edge->v1.
974  */
975 static void find_edge_neighbors(const SubdivMeshContext *ctx,
976                                 const MEdge *edge,
977                                 const MEdge *neighbors[2])
978 {
979         const Mesh *coarse_mesh = ctx->coarse_mesh;
980         const MEdge *coarse_medge = coarse_mesh->medge;
981         neighbors[0] = NULL;
982         neighbors[1] = NULL;
983         for (int edge_index = 0; edge_index < coarse_mesh->totedge; edge_index++) {
984                 const MEdge *current_edge = &coarse_medge[edge_index];
985                 if (current_edge == edge) {
986                         continue;
987                 }
988                 if (ELEM(edge->v1, current_edge->v1, current_edge->v2)) {
989                         neighbors[0] = current_edge;
990                 }
991                 if (ELEM(edge->v2, current_edge->v1, current_edge->v2)) {
992                         neighbors[1] = current_edge;
993                 }
994         }
995 }
996
997 static void points_for_loose_edges_interpolation_get(
998         SubdivMeshContext *ctx,
999         const MEdge *coarse_edge,
1000         const MEdge *neighbors[2],
1001         float points_r[4][3])
1002 {
1003         const Mesh *coarse_mesh = ctx->coarse_mesh;
1004         const MVert *coarse_mvert = coarse_mesh->mvert;
1005         /* Middle points corresponds to the edge. */
1006         copy_v3_v3(points_r[1], coarse_mvert[coarse_edge->v1].co);
1007         copy_v3_v3(points_r[2], coarse_mvert[coarse_edge->v2].co);
1008         /* Start point, duplicate from edge start if no neighbor. */
1009         if (neighbors[0] != NULL) {
1010                 if (neighbors[0]->v1 == coarse_edge->v1) {
1011                         copy_v3_v3(points_r[0], coarse_mvert[neighbors[0]->v2].co);
1012                 }
1013                 else {
1014                         copy_v3_v3(points_r[0], coarse_mvert[neighbors[0]->v1].co);
1015                 }
1016         }
1017         else {
1018                 sub_v3_v3v3(points_r[0], points_r[1], points_r[2]);
1019                 add_v3_v3(points_r[0], points_r[1]);
1020         }
1021         /* End point, duplicate from edge end if no neighbor. */
1022         if (neighbors[1] != NULL) {
1023                 if (neighbors[1]->v1 == coarse_edge->v2) {
1024                         copy_v3_v3(points_r[3], coarse_mvert[neighbors[1]->v2].co);
1025                 }
1026                 else {
1027                         copy_v3_v3(points_r[3], coarse_mvert[neighbors[1]->v1].co);
1028                 }
1029         }
1030         else {
1031                 sub_v3_v3v3(points_r[3], points_r[2], points_r[1]);
1032                 add_v3_v3(points_r[3], points_r[2]);
1033         }
1034 }
1035
1036 static void subdiv_mesh_vertex_of_loose_edge_interpolate(
1037         SubdivMeshContext *ctx,
1038         const MEdge *coarse_edge,
1039         const float u,
1040         const int subdiv_vertex_index)
1041 {
1042         const Mesh *coarse_mesh = ctx->coarse_mesh;
1043         Mesh *subdiv_mesh = ctx->subdiv_mesh;
1044         if (u == 0.0f) {
1045                 CustomData_copy_data(&coarse_mesh->vdata,
1046                                      &subdiv_mesh->vdata,
1047                                      coarse_edge->v1,
1048                                      subdiv_vertex_index,
1049                                      1);
1050         }
1051         else if (u == 1.0f) {
1052                 CustomData_copy_data(&coarse_mesh->vdata,
1053                                      &subdiv_mesh->vdata,
1054                                      coarse_edge->v2,
1055                                      subdiv_vertex_index,
1056                                      1);
1057         }
1058         else {
1059                 BLI_assert(u > 0.0f);
1060                 BLI_assert(u < 1.0f);
1061                 const float interpolation_weights[2] = {1.0f - u, u};
1062                 const int coarse_vertex_indices[2] = {coarse_edge->v1, coarse_edge->v2};
1063                 CustomData_interp(&coarse_mesh->vdata,
1064                                   &subdiv_mesh->vdata,
1065                                   coarse_vertex_indices,
1066                                   interpolation_weights, NULL,
1067                                   2, subdiv_vertex_index);
1068         }
1069 }
1070
1071 static void subdiv_mesh_vertex_of_loose_edge(
1072         const struct SubdivForeachContext *foreach_context,
1073         void *UNUSED(tls),
1074         const int coarse_edge_index,
1075         const float u,
1076         const int subdiv_vertex_index)
1077 {
1078         SubdivMeshContext *ctx = foreach_context->user_data;
1079         const Mesh *coarse_mesh = ctx->coarse_mesh;
1080         const MEdge *coarse_edge = &coarse_mesh->medge[coarse_edge_index];
1081         Mesh *subdiv_mesh = ctx->subdiv_mesh;
1082         MVert *subdiv_mvert = subdiv_mesh->mvert;
1083         /* Find neighbors of the current loose edge. */
1084         const MEdge *neighbors[2];
1085         find_edge_neighbors(ctx, coarse_edge, neighbors);
1086         /* Get points for b-spline interpolation. */
1087         float points[4][3];
1088         points_for_loose_edges_interpolation_get(
1089                 ctx, coarse_edge, neighbors, points);
1090         /* Perform interpolation. */
1091         float weights[4];
1092         key_curve_position_weights(u, weights, KEY_BSPLINE);
1093
1094         /* Interpolate custom data. */
1095         subdiv_mesh_vertex_of_loose_edge_interpolate(
1096                 ctx, coarse_edge, u, subdiv_vertex_index);
1097         /* Initialize  */
1098         MVert *subdiv_vertex = &subdiv_mvert[subdiv_vertex_index];
1099         interp_v3_v3v3v3v3(subdiv_vertex->co,
1100                            points[0],
1101                            points[1],
1102                            points[2],
1103                            points[3],
1104                            weights);
1105         /* Reset flags and such. */
1106         subdiv_vertex->flag = 0;
1107         /* TODO(sergey): This matches old behavior, but we can as well interpolate
1108          * it. Maybe even using vertex varying attributes. */
1109         subdiv_vertex->bweight = 0.0f;
1110         /* Reset normal, initialize it in a similar way as edit mode does for a
1111          * vertices adjacent to a loose edges. */
1112         normal_float_to_short_v3(subdiv_vertex->no, subdiv_vertex->co);
1113 }
1114
1115 /* =============================================================================
1116  * Initialization.
1117  */
1118
1119 static void setup_foreach_callbacks(SubdivForeachContext *foreach_context,
1120                                     const Subdiv *subdiv)
1121 {
1122         memset(foreach_context, 0, sizeof(*foreach_context));
1123         /* General information. */
1124         foreach_context->topology_info = subdiv_mesh_topology_info;
1125         /* Every boundary geometry. Used for dispalcement averaging. */
1126         if (subdiv->displacement_evaluator != NULL) {
1127                 foreach_context->vertex_every_corner = subdiv_mesh_vertex_every_corner;
1128                 foreach_context->vertex_every_edge = subdiv_mesh_vertex_every_edge;
1129         }
1130         else {
1131                 foreach_context->vertex_every_corner = NULL;
1132                 foreach_context->vertex_every_edge = NULL;
1133         }
1134         foreach_context->vertex_corner = subdiv_mesh_vertex_corner;
1135         foreach_context->vertex_edge = subdiv_mesh_vertex_edge;
1136         foreach_context->vertex_inner = subdiv_mesh_vertex_inner;
1137         foreach_context->edge = subdiv_mesh_edge;
1138         foreach_context->loop = subdiv_mesh_loop;
1139         foreach_context->poly = subdiv_mesh_poly;
1140         foreach_context->vertex_loose = subdiv_mesh_vertex_loose;
1141         foreach_context->vertex_of_loose_edge = subdiv_mesh_vertex_of_loose_edge;
1142         foreach_context->user_data_tls_free = subdiv_mesh_tls_free;
1143 }
1144
1145 /* =============================================================================
1146  * Public entry point.
1147  */
1148
1149 Mesh *BKE_subdiv_to_mesh(
1150         Subdiv *subdiv,
1151         const SubdivToMeshSettings *settings,
1152         const Mesh *coarse_mesh)
1153 {
1154         BKE_subdiv_stats_begin(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_MESH);
1155         /* Make sure evaluator is up to date with possible new topology, and that
1156          * is is refined for the new positions of coarse vertices.
1157          */
1158         if (!BKE_subdiv_eval_update_from_mesh(subdiv, coarse_mesh)) {
1159                 /* This could happen in two situations:
1160                  * - OpenSubdiv is disabled.
1161                  * - Something totally bad happened, and OpenSubdiv rejected our
1162                  *   topology.
1163                  * In either way, we can't safely continue.
1164                  */
1165                 if (coarse_mesh->totpoly) {
1166                         BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_MESH);
1167                         return NULL;
1168                 }
1169         }
1170         /* Initialize subdivion mesh creation context/ */
1171         SubdivMeshContext subdiv_context = {0};
1172         subdiv_context.settings = settings;
1173         subdiv_context.coarse_mesh = coarse_mesh;
1174         subdiv_context.subdiv = subdiv;
1175         /* Multi-threaded traversal/evaluation. */
1176         BKE_subdiv_stats_begin(&subdiv->stats,
1177                                SUBDIV_STATS_SUBDIV_TO_MESH_GEOMETRY);
1178         SubdivForeachContext foreach_context;
1179         setup_foreach_callbacks(&foreach_context, subdiv);
1180         SubdivMeshTLS tls = {0};
1181         foreach_context.user_data = &subdiv_context;
1182         foreach_context.user_data_tls_size = sizeof(SubdivMeshTLS);
1183         foreach_context.user_data_tls = &tls;
1184         BKE_subdiv_foreach_subdiv_geometry(subdiv,
1185                                            &foreach_context,
1186                                            settings,
1187                                            coarse_mesh);
1188         BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_MESH_GEOMETRY);
1189         Mesh *result = subdiv_context.subdiv_mesh;
1190         // BKE_mesh_validate(result, true, true);
1191         BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_MESH);
1192         if (subdiv->displacement_evaluator != NULL) {
1193                 result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
1194         }
1195         return result;
1196 }