Merge branch 'master' into blender2.8
[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                  */
390                 const float weights[2] = {0.5f, 0.5f};
391                 const int first_indices[2] = {
392                         loops_of_ptex.first_loop - coarse_mloop,
393                         (loops_of_ptex.first_loop + 1 - coarse_mloop) %
394                                 coarse_poly->totloop};
395                 const int last_indices[2] = {
396                         loops_of_ptex.last_loop - coarse_mloop,
397                         loops_of_ptex.first_loop - coarse_mloop};
398                 CustomData_interp(loop_data,
399                                   &loop_interpolation->loop_data_storage,
400                                   first_indices,
401                                   weights, NULL,
402                                   2,
403                                   1);
404                 CustomData_interp(loop_data,
405                                   &loop_interpolation->loop_data_storage,
406                                   last_indices,
407                                   weights, NULL,
408                                   2,
409                                   3);
410         }
411 }
412
413 static void loop_interpolation_end(LoopsForInterpolation *loop_interpolation)
414 {
415         if (loop_interpolation->loop_data_storage_allocated) {
416                 CustomData_free(&loop_interpolation->loop_data_storage, 4);
417         }
418 }
419
420 /* =============================================================================
421  * TLS.
422  */
423
424 typedef struct SubdivMeshTLS {
425         bool vertex_interpolation_initialized;
426         VerticesForInterpolation vertex_interpolation;
427         const MPoly *vertex_interpolation_coarse_poly;
428         int vertex_interpolation_coarse_corner;
429
430         bool loop_interpolation_initialized;
431         LoopsForInterpolation loop_interpolation;
432         const MPoly *loop_interpolation_coarse_poly;
433         int loop_interpolation_coarse_corner;
434 } SubdivMeshTLS;
435
436 static void subdiv_mesh_tls_free(void *tls_v)
437 {
438         SubdivMeshTLS *tls = tls_v;
439         if (tls->vertex_interpolation_initialized) {
440                 vertex_interpolation_end(&tls->vertex_interpolation);
441         }
442         if (tls->loop_interpolation_initialized) {
443                 loop_interpolation_end(&tls->loop_interpolation);
444         }
445 }
446
447 /* =============================================================================
448  * Evaluation helper functions.
449  */
450
451 static void eval_final_point_and_vertex_normal(
452         Subdiv *subdiv,
453         const int ptex_face_index,
454         const float u, const float v,
455         float r_P[3], short r_N[3])
456 {
457         if (subdiv->displacement_evaluator == NULL) {
458                 BKE_subdiv_eval_limit_point_and_short_normal(
459                         subdiv, ptex_face_index, u, v, r_P, r_N);
460         }
461         else {
462                 BKE_subdiv_eval_final_point(
463                         subdiv, ptex_face_index, u, v, r_P);
464         }
465 }
466
467 /* =============================================================================
468  * Displacement helpers
469  */
470
471 static void subdiv_accumulate_vertex_displacement(
472         Subdiv *subdiv,
473         const int ptex_face_index,
474         const float u, const float v,
475         MVert *subdiv_vert)
476 {
477         float dummy_P[3], dPdu[3], dPdv[3], D[3];
478         BKE_subdiv_eval_limit_point_and_derivatives(
479                 subdiv, ptex_face_index, u, v, dummy_P, dPdu, dPdv);
480         BKE_subdiv_eval_displacement(subdiv,
481                                      ptex_face_index, u, v,
482                                      dPdu, dPdv,
483                                      D);
484         add_v3_v3(subdiv_vert->co, D);
485         if (subdiv_vert->flag & ME_VERT_TMP_TAG) {
486                 mul_v3_fl(subdiv_vert->co, 0.5f);
487         }
488         subdiv_vert->flag |= ME_VERT_TMP_TAG;
489 }
490
491 /* =============================================================================
492  * Callbacks.
493  */
494
495 static bool subdiv_mesh_topology_info(
496         const SubdivForeachContext *foreach_context,
497         const int num_vertices,
498         const int num_edges,
499         const int num_loops,
500         const int num_polygons)
501 {
502         SubdivMeshContext *subdiv_context = foreach_context->user_data;
503         subdiv_context->subdiv_mesh = BKE_mesh_new_nomain_from_template(
504                 subdiv_context->coarse_mesh,
505                 num_vertices,
506                 num_edges,
507                 0,
508                 num_loops,
509                 num_polygons);
510         subdiv_mesh_ctx_cache_custom_data_layers(subdiv_context);
511         return true;
512 }
513
514 /* =============================================================================
515  * Vertex subdivision process.
516  */
517
518 static void subdiv_vertex_data_copy(
519         const SubdivMeshContext *ctx,
520         const MVert *coarse_vertex,
521         MVert *subdiv_vertex)
522 {
523         const Mesh *coarse_mesh = ctx->coarse_mesh;
524         Mesh *subdiv_mesh = ctx->subdiv_mesh;
525         const int coarse_vertex_index = coarse_vertex - coarse_mesh->mvert;
526         const int subdiv_vertex_index = subdiv_vertex - subdiv_mesh->mvert;
527         subdiv_vertex->flag &= ~ME_VERT_TMP_TAG;
528         CustomData_copy_data(&coarse_mesh->vdata,
529                              &ctx->subdiv_mesh->vdata,
530                              coarse_vertex_index,
531                              subdiv_vertex_index,
532                              1);
533 }
534
535 static void subdiv_vertex_data_interpolate(
536         const SubdivMeshContext *ctx,
537         MVert *subdiv_vertex,
538         const VerticesForInterpolation *vertex_interpolation,
539         const float u, const float v)
540 {
541         const int subdiv_vertex_index = subdiv_vertex - ctx->subdiv_mesh->mvert;
542         const float weights[4] = {(1.0f - u) * (1.0f - v),
543                                   u * (1.0f - v),
544                                   u * v,
545                                   (1.0f - u) * v};
546         subdiv_vertex->flag &= ~ME_VERT_TMP_TAG;
547         CustomData_interp(vertex_interpolation->vertex_data,
548                           &ctx->subdiv_mesh->vdata,
549                           vertex_interpolation->vertex_indices,
550                           weights, NULL,
551                           4,
552                           subdiv_vertex_index);
553         if (ctx->vert_origindex != NULL) {
554                 ctx->vert_origindex[subdiv_vertex_index] = ORIGINDEX_NONE;
555         }
556 }
557
558 static void evaluate_vertex_and_apply_displacement_copy(
559         const SubdivMeshContext *ctx,
560         const int ptex_face_index,
561         const float u, const float v,
562         const MVert *coarse_vert,
563         MVert *subdiv_vert)
564 {
565         /* Displacement is accumulated in subdiv vertex position.
566          * need to back it up before copying data from original vertex.
567          */
568         float D[3];
569         copy_v3_v3(D, subdiv_vert->co);
570         subdiv_vertex_data_copy(ctx, coarse_vert, subdiv_vert);
571         BKE_subdiv_eval_limit_point_and_short_normal(
572                 ctx->subdiv,
573                 ptex_face_index,
574                 u, v,
575                 subdiv_vert->co, subdiv_vert->no);
576         /* Apply displacement. */
577         add_v3_v3(subdiv_vert->co, D);
578 }
579
580 static void evaluate_vertex_and_apply_displacement_interpolate(
581         const SubdivMeshContext *ctx,
582         const int ptex_face_index,
583         const float u, const float v,
584         VerticesForInterpolation *vertex_interpolation,
585         MVert *subdiv_vert)
586 {
587         /* Displacement is accumulated in subdiv vertex position.
588          * need to back it up before copying data from original vertex.
589          */
590         float D[3];
591         copy_v3_v3(D, subdiv_vert->co);
592         subdiv_vertex_data_interpolate(ctx,
593                                        subdiv_vert,
594                                        vertex_interpolation,
595                                        u, v);
596         BKE_subdiv_eval_limit_point_and_short_normal(
597                 ctx->subdiv,
598                 ptex_face_index,
599                 u, v,
600                 subdiv_vert->co, subdiv_vert->no);
601         /* Apply displacement. */
602         add_v3_v3(subdiv_vert->co, D);
603 }
604
605 static void subdiv_mesh_vertex_every_corner_or_edge(
606         const SubdivForeachContext *foreach_context,
607         void *UNUSED(tls),
608         const int ptex_face_index,
609         const float u, const float v,
610         const int subdiv_vertex_index)
611 {
612         SubdivMeshContext *ctx = foreach_context->user_data;
613         Subdiv *subdiv = ctx->subdiv;
614         Mesh *subdiv_mesh = ctx->subdiv_mesh;
615         MVert *subdiv_mvert = subdiv_mesh->mvert;
616         MVert *subdiv_vert = &subdiv_mvert[subdiv_vertex_index];
617         subdiv_accumulate_vertex_displacement(
618                 subdiv, ptex_face_index, u, v, subdiv_vert);
619 }
620
621 static void subdiv_mesh_vertex_every_corner(
622         const SubdivForeachContext *foreach_context,
623         void *tls,
624         const int ptex_face_index,
625         const float u, const float v,
626         const int UNUSED(coarse_vertex_index),
627         const int UNUSED(coarse_poly_index),
628         const int UNUSED(coarse_corner),
629         const int subdiv_vertex_index)
630 {
631         subdiv_mesh_vertex_every_corner_or_edge(
632                 foreach_context, tls, ptex_face_index, u, v, subdiv_vertex_index);
633 }
634
635 static void subdiv_mesh_vertex_every_edge(
636         const SubdivForeachContext *foreach_context,
637         void *tls,
638         const int ptex_face_index,
639         const float u, const float v,
640         const int UNUSED(coarse_edge_index),
641         const int UNUSED(coarse_poly_index),
642         const int UNUSED(coarse_corner),
643         const int subdiv_vertex_index)
644 {
645         subdiv_mesh_vertex_every_corner_or_edge(
646                 foreach_context, tls, ptex_face_index, u, v, subdiv_vertex_index);
647 }
648
649 static void subdiv_mesh_vertex_corner(
650         const SubdivForeachContext *foreach_context,
651         void *UNUSED(tls),
652         const int ptex_face_index,
653         const float u, const float v,
654         const int coarse_vertex_index,
655         const int UNUSED(coarse_poly_index),
656         const int UNUSED(coarse_corner),
657         const int subdiv_vertex_index)
658 {
659         BLI_assert(coarse_vertex_index != ORIGINDEX_NONE);
660         SubdivMeshContext *ctx = foreach_context->user_data;
661         const Mesh *coarse_mesh = ctx->coarse_mesh;
662         const MVert *coarse_mvert = coarse_mesh->mvert;
663         Mesh *subdiv_mesh = ctx->subdiv_mesh;
664         MVert *subdiv_mvert = subdiv_mesh->mvert;
665         const MVert *coarse_vert = &coarse_mvert[coarse_vertex_index];
666         MVert *subdiv_vert = &subdiv_mvert[subdiv_vertex_index];
667         evaluate_vertex_and_apply_displacement_copy(
668                 ctx, ptex_face_index, u, v, coarse_vert, subdiv_vert);
669 }
670
671 static void subdiv_mesh_ensure_vertex_interpolation(
672         SubdivMeshContext *ctx,
673         SubdivMeshTLS *tls,
674         const MPoly *coarse_poly,
675         const int coarse_corner)
676 {
677         /* Check whether we've moved to another corner or polygon. */
678         if (tls->vertex_interpolation_initialized) {
679                 if (tls->vertex_interpolation_coarse_poly != coarse_poly ||
680                     tls->vertex_interpolation_coarse_corner != coarse_corner)
681                 {
682                         vertex_interpolation_end(&tls->vertex_interpolation);
683                         tls->vertex_interpolation_initialized = false;
684                 }
685         }
686         /* Initialize the interpolation. */
687         if (!tls->vertex_interpolation_initialized) {
688                 vertex_interpolation_init(ctx, &tls->vertex_interpolation, coarse_poly);
689         }
690         /* Update it for a new corner if needed. */
691         if (!tls->vertex_interpolation_initialized ||
692             tls->vertex_interpolation_coarse_corner != coarse_corner)
693         {
694                 vertex_interpolation_from_corner(
695                         ctx, &tls->vertex_interpolation, coarse_poly, coarse_corner);
696         }
697         /* Store settings used for the current state of interpolator. */
698         tls->vertex_interpolation_initialized = true;
699         tls->vertex_interpolation_coarse_poly = coarse_poly;
700         tls->vertex_interpolation_coarse_corner = coarse_corner;
701 }
702
703 static void subdiv_mesh_vertex_edge(
704         const SubdivForeachContext *foreach_context,
705         void *tls_v,
706         const int ptex_face_index,
707         const float u, const float v,
708         const int UNUSED(coarse_edge_index),
709         const int coarse_poly_index,
710         const int coarse_corner,
711         const int subdiv_vertex_index)
712 {
713         SubdivMeshContext *ctx = foreach_context->user_data;
714         SubdivMeshTLS *tls = tls_v;
715         const Mesh *coarse_mesh = ctx->coarse_mesh;
716         const MPoly *coarse_mpoly = coarse_mesh->mpoly;
717         const MPoly *coarse_poly = &coarse_mpoly[coarse_poly_index];
718         Mesh *subdiv_mesh = ctx->subdiv_mesh;
719         MVert *subdiv_mvert = subdiv_mesh->mvert;
720         MVert *subdiv_vert = &subdiv_mvert[subdiv_vertex_index];
721         subdiv_mesh_ensure_vertex_interpolation(
722                 ctx, tls, coarse_poly, coarse_corner);
723         evaluate_vertex_and_apply_displacement_interpolate(
724                 ctx,
725                 ptex_face_index, u, v,
726                 &tls->vertex_interpolation,
727                 subdiv_vert);
728 }
729
730 static void subdiv_mesh_vertex_inner(
731         const SubdivForeachContext *foreach_context,
732         void *tls_v,
733         const int ptex_face_index,
734         const float u, const float v,
735         const int coarse_poly_index,
736         const int coarse_corner,
737         const int subdiv_vertex_index)
738 {
739         SubdivMeshContext *ctx = foreach_context->user_data;
740         SubdivMeshTLS *tls = tls_v;
741         Subdiv *subdiv = ctx->subdiv;
742         const Mesh *coarse_mesh = ctx->coarse_mesh;
743         const MPoly *coarse_mpoly = coarse_mesh->mpoly;
744         const MPoly *coarse_poly = &coarse_mpoly[coarse_poly_index];
745         Mesh *subdiv_mesh = ctx->subdiv_mesh;
746         MVert *subdiv_mvert = subdiv_mesh->mvert;
747         MVert *subdiv_vert = &subdiv_mvert[subdiv_vertex_index];
748         subdiv_mesh_ensure_vertex_interpolation(
749                 ctx, tls, coarse_poly, coarse_corner);
750         subdiv_vertex_data_interpolate(
751                 ctx, subdiv_vert, &tls->vertex_interpolation, u, v);
752         eval_final_point_and_vertex_normal(
753                 subdiv, ptex_face_index, u, v, subdiv_vert->co, subdiv_vert->no);
754 }
755
756 /* =============================================================================
757  * Edge subdivision process.
758  */
759
760 static void subdiv_copy_edge_data(
761         SubdivMeshContext *ctx,
762         MEdge *subdiv_edge,
763         const MEdge *coarse_edge)
764 {
765         const int subdiv_edge_index = subdiv_edge - ctx->subdiv_mesh->medge;
766         if (coarse_edge == NULL) {
767                 subdiv_edge->crease = 0;
768                 subdiv_edge->bweight = 0;
769                 subdiv_edge->flag = 0;
770                 if (!ctx->settings->use_optimal_display) {
771                         subdiv_edge->flag |= ME_EDGERENDER;
772                 }
773                 if (ctx->edge_origindex != NULL) {
774                         ctx->edge_origindex[subdiv_edge_index] = ORIGINDEX_NONE;
775                 }
776                 return;
777         }
778         const int coarse_edge_index = coarse_edge - ctx->coarse_mesh->medge;
779         CustomData_copy_data(&ctx->coarse_mesh->edata,
780                              &ctx->subdiv_mesh->edata,
781                              coarse_edge_index,
782                              subdiv_edge_index,
783                              1);
784         subdiv_edge->flag |= ME_EDGERENDER;
785 }
786
787 static void subdiv_mesh_edge(
788         const SubdivForeachContext *foreach_context,
789         void *UNUSED(tls),
790         const int coarse_edge_index,
791         const int subdiv_edge_index,
792         const int subdiv_v1, const int subdiv_v2)
793 {
794         SubdivMeshContext *ctx = foreach_context->user_data;
795         Mesh *subdiv_mesh = ctx->subdiv_mesh;
796         MEdge *subdiv_medge = subdiv_mesh->medge;
797         MEdge *subdiv_edge = &subdiv_medge[subdiv_edge_index];
798         const MEdge *coarse_edge = NULL;
799         if (coarse_edge_index != ORIGINDEX_NONE) {
800                 const Mesh *coarse_mesh = ctx->coarse_mesh;
801                 const MEdge *coarse_medge = coarse_mesh->medge;
802                 coarse_edge = &coarse_medge[coarse_edge_index];
803         }
804         subdiv_copy_edge_data(ctx, subdiv_edge, coarse_edge);
805         subdiv_edge->v1 = subdiv_v1;
806         subdiv_edge->v2 = subdiv_v2;
807 }
808
809 /* =============================================================================
810  * Loops creation/interpolation.
811  */
812
813 static void subdiv_interpolate_loop_data(
814         const SubdivMeshContext *ctx,
815         MLoop *subdiv_loop,
816         const LoopsForInterpolation *loop_interpolation,
817         const float u, const float v)
818 {
819         const int subdiv_loop_index = subdiv_loop - ctx->subdiv_mesh->mloop;
820         const float weights[4] = {(1.0f - u) * (1.0f - v),
821                                   u * (1.0f - v),
822                                   u * v,
823                                   (1.0f - u) * v};
824         CustomData_interp(loop_interpolation->loop_data,
825                           &ctx->subdiv_mesh->ldata,
826                           loop_interpolation->loop_indices,
827                           weights, NULL,
828                           4,
829                           subdiv_loop_index);
830         /* TODO(sergey): Set ORIGINDEX. */
831 }
832
833 static void subdiv_eval_uv_layer(SubdivMeshContext *ctx,
834                                  MLoop *subdiv_loop,
835                                  const int ptex_face_index,
836                                  const float u, const float v)
837 {
838         if (ctx->num_uv_layers == 0) {
839                 return;
840         }
841         Subdiv *subdiv = ctx->subdiv;
842         const int mloop_index = subdiv_loop - ctx->subdiv_mesh->mloop;
843         for (int layer_index = 0; layer_index < ctx->num_uv_layers; layer_index++) {
844                 MLoopUV *subdiv_loopuv = &ctx->uv_layers[layer_index][mloop_index];
845                 BKE_subdiv_eval_face_varying(subdiv,
846                                              layer_index,
847                                              ptex_face_index,
848                                              u, v,
849                                              subdiv_loopuv->uv);
850         }
851 }
852
853 static void subdiv_mesh_ensure_loop_interpolation(
854         SubdivMeshContext *ctx,
855         SubdivMeshTLS *tls,
856         const MPoly *coarse_poly,
857         const int coarse_corner)
858 {
859         /* Check whether we've moved to another corner or polygon. */
860         if (tls->loop_interpolation_initialized) {
861                 if (tls->loop_interpolation_coarse_poly != coarse_poly ||
862                     tls->loop_interpolation_coarse_corner != coarse_corner)
863                 {
864                         loop_interpolation_end(&tls->loop_interpolation);
865                         tls->loop_interpolation_initialized = false;
866                 }
867         }
868         /* Initialize the interpolation. */
869         if (!tls->loop_interpolation_initialized) {
870                 loop_interpolation_init(ctx, &tls->loop_interpolation, coarse_poly);
871         }
872         /* Update it for a new corner if needed. */
873         if (!tls->loop_interpolation_initialized ||
874             tls->loop_interpolation_coarse_corner != coarse_corner)
875         {
876                 loop_interpolation_from_corner(
877                         ctx, &tls->loop_interpolation, coarse_poly, coarse_corner);
878         }
879         /* Store settings used for the current state of interpolator. */
880         tls->loop_interpolation_initialized = true;
881         tls->loop_interpolation_coarse_poly = coarse_poly;
882         tls->loop_interpolation_coarse_corner = coarse_corner;
883 }
884
885 static void subdiv_mesh_loop(
886         const SubdivForeachContext *foreach_context,
887         void *tls_v,
888         const int ptex_face_index,
889         const float u, const float v,
890         const int UNUSED(coarse_loop_index),
891         const int coarse_poly_index,
892         const int coarse_corner,
893         const int subdiv_loop_index,
894         const int subdiv_vertex_index, const int subdiv_edge_index)
895 {
896         SubdivMeshContext *ctx = foreach_context->user_data;
897         SubdivMeshTLS *tls = tls_v;
898         const Mesh *coarse_mesh = ctx->coarse_mesh;
899         const MPoly *coarse_mpoly = coarse_mesh->mpoly;
900         const MPoly *coarse_poly = &coarse_mpoly[coarse_poly_index];
901         Mesh *subdiv_mesh = ctx->subdiv_mesh;
902         MLoop *subdiv_mloop = subdiv_mesh->mloop;
903         MLoop *subdiv_loop = &subdiv_mloop[subdiv_loop_index];
904         subdiv_mesh_ensure_loop_interpolation(
905                 ctx, tls, coarse_poly, coarse_corner);
906         subdiv_interpolate_loop_data(
907                 ctx, subdiv_loop, &tls->loop_interpolation, u, v);
908         subdiv_eval_uv_layer(ctx, subdiv_loop, ptex_face_index, u, v);
909         subdiv_loop->v = subdiv_vertex_index;
910         subdiv_loop->e = subdiv_edge_index;
911 }
912
913 /* =============================================================================
914  * Polygons subdivision process.
915  */
916
917 static void subdiv_copy_poly_data(const SubdivMeshContext *ctx,
918                                   MPoly *subdiv_poly,
919                                   const MPoly *coarse_poly)
920 {
921         const int coarse_poly_index = coarse_poly - ctx->coarse_mesh->mpoly;
922         const int subdiv_poly_index = subdiv_poly - ctx->subdiv_mesh->mpoly;
923         CustomData_copy_data(&ctx->coarse_mesh->pdata,
924                              &ctx->subdiv_mesh->pdata,
925                              coarse_poly_index,
926                              subdiv_poly_index,
927                              1);
928 }
929
930 static void subdiv_mesh_poly(
931         const SubdivForeachContext *foreach_context,
932         void *UNUSED(tls),
933         const int coarse_poly_index,
934         const int subdiv_poly_index,
935         const int start_loop_index, const int num_loops)
936 {
937         BLI_assert(coarse_poly_index != ORIGINDEX_NONE);
938         SubdivMeshContext *ctx = foreach_context->user_data;
939         const Mesh *coarse_mesh = ctx->coarse_mesh;
940         const MPoly *coarse_mpoly = coarse_mesh->mpoly;
941         const MPoly *coarse_poly = &coarse_mpoly[coarse_poly_index];
942         Mesh *subdiv_mesh = ctx->subdiv_mesh;
943         MPoly *subdiv_mpoly = subdiv_mesh->mpoly;
944         MPoly *subdiv_poly = &subdiv_mpoly[subdiv_poly_index];
945         subdiv_copy_poly_data(ctx, subdiv_poly, coarse_poly);
946         subdiv_poly->loopstart = start_loop_index;
947         subdiv_poly->totloop = num_loops;
948 }
949
950 /* =============================================================================
951  * Loose elements subdivision process.
952  */
953
954 static void subdiv_mesh_vertex_loose(
955         const SubdivForeachContext *foreach_context,
956         void *UNUSED(tls),
957         const int coarse_vertex_index,
958         const int subdiv_vertex_index)
959 {
960         SubdivMeshContext *ctx = foreach_context->user_data;
961         const Mesh *coarse_mesh = ctx->coarse_mesh;
962         const MVert *coarse_mvert = coarse_mesh->mvert;
963         const MVert *coarse_vertex = &coarse_mvert[coarse_vertex_index];
964         Mesh *subdiv_mesh = ctx->subdiv_mesh;
965         MVert *subdiv_mvert = subdiv_mesh->mvert;
966         MVert *subdiv_vertex = &subdiv_mvert[subdiv_vertex_index];
967         subdiv_vertex_data_copy(ctx, coarse_vertex, subdiv_vertex);
968 }
969
970 /* Get neighbor edges of the given one.
971  * - neighbors[0] is an edge adjacent to edge->v1.
972  * - neighbors[1] is an edge adjacent to edge->v1.
973  */
974 static void find_edge_neighbors(const SubdivMeshContext *ctx,
975                                 const MEdge *edge,
976                                 const MEdge *neighbors[2])
977 {
978         const Mesh *coarse_mesh = ctx->coarse_mesh;
979         const MEdge *coarse_medge = coarse_mesh->medge;
980         neighbors[0] = NULL;
981         neighbors[1] = NULL;
982         for (int edge_index = 0; edge_index < coarse_mesh->totedge; edge_index++) {
983                 const MEdge *current_edge = &coarse_medge[edge_index];
984                 if (current_edge == edge) {
985                         continue;
986                 }
987                 if (ELEM(edge->v1, current_edge->v1, current_edge->v2)) {
988                         neighbors[0] = current_edge;
989                 }
990                 if (ELEM(edge->v2, current_edge->v1, current_edge->v2)) {
991                         neighbors[1] = current_edge;
992                 }
993         }
994 }
995
996 static void points_for_loose_edges_interpolation_get(
997         SubdivMeshContext *ctx,
998         const MEdge *coarse_edge,
999         const MEdge *neighbors[2],
1000         float points_r[4][3])
1001 {
1002         const Mesh *coarse_mesh = ctx->coarse_mesh;
1003         const MVert *coarse_mvert = coarse_mesh->mvert;
1004         /* Middle points corresponds to the edge. */
1005         copy_v3_v3(points_r[1], coarse_mvert[coarse_edge->v1].co);
1006         copy_v3_v3(points_r[2], coarse_mvert[coarse_edge->v2].co);
1007         /* Start point, duplicate from edge start if no neighbor. */
1008         if (neighbors[0] != NULL) {
1009                 if (neighbors[0]->v1 == coarse_edge->v1) {
1010                         copy_v3_v3(points_r[0], coarse_mvert[neighbors[0]->v2].co);
1011                 }
1012                 else {
1013                         copy_v3_v3(points_r[0], coarse_mvert[neighbors[0]->v1].co);
1014                 }
1015         }
1016         else {
1017                 sub_v3_v3v3(points_r[0], points_r[1], points_r[2]);
1018                 add_v3_v3(points_r[0], points_r[1]);
1019         }
1020         /* End point, duplicate from edge end if no neighbor. */
1021         if (neighbors[1] != NULL) {
1022                 if (neighbors[1]->v1 == coarse_edge->v2) {
1023                         copy_v3_v3(points_r[3], coarse_mvert[neighbors[1]->v2].co);
1024                 }
1025                 else {
1026                         copy_v3_v3(points_r[3], coarse_mvert[neighbors[1]->v1].co);
1027                 }
1028         }
1029         else {
1030                 sub_v3_v3v3(points_r[3], points_r[2], points_r[1]);
1031                 add_v3_v3(points_r[3], points_r[2]);
1032         }
1033 }
1034
1035 static void subdiv_mesh_vertex_of_loose_edge_interpolate(
1036         SubdivMeshContext *ctx,
1037         const MEdge *coarse_edge,
1038         const float u,
1039         const int subdiv_vertex_index)
1040 {
1041         const Mesh *coarse_mesh = ctx->coarse_mesh;
1042         Mesh *subdiv_mesh = ctx->subdiv_mesh;
1043         if (u == 0.0f) {
1044                 CustomData_copy_data(&coarse_mesh->vdata,
1045                                      &subdiv_mesh->vdata,
1046                                      coarse_edge->v1,
1047                                      subdiv_vertex_index,
1048                                      1);
1049         }
1050         else if (u == 1.0f) {
1051                 CustomData_copy_data(&coarse_mesh->vdata,
1052                                      &subdiv_mesh->vdata,
1053                                      coarse_edge->v2,
1054                                      subdiv_vertex_index,
1055                                      1);
1056         }
1057         else {
1058                 BLI_assert(u > 0.0f);
1059                 BLI_assert(u < 1.0f);
1060                 const float interpolation_weights[2] = {1.0f - u, u};
1061                 const int coarse_vertex_indices[2] = {coarse_edge->v1, coarse_edge->v2};
1062                 CustomData_interp(&coarse_mesh->vdata,
1063                                   &subdiv_mesh->vdata,
1064                                   coarse_vertex_indices,
1065                                   interpolation_weights, NULL,
1066                                   2, subdiv_vertex_index);
1067         }
1068 }
1069
1070 static void subdiv_mesh_vertex_of_loose_edge(
1071         const struct SubdivForeachContext *foreach_context,
1072         void *UNUSED(tls),
1073         const int coarse_edge_index,
1074         const float u,
1075         const int subdiv_vertex_index)
1076 {
1077         SubdivMeshContext *ctx = foreach_context->user_data;
1078         const Mesh *coarse_mesh = ctx->coarse_mesh;
1079         const MEdge *coarse_edge = &coarse_mesh->medge[coarse_edge_index];
1080         Mesh *subdiv_mesh = ctx->subdiv_mesh;
1081         MVert *subdiv_mvert = subdiv_mesh->mvert;
1082         /* Find neighbors of the current loose edge. */
1083         const MEdge *neighbors[2];
1084         find_edge_neighbors(ctx, coarse_edge, neighbors);
1085         /* Get points for b-spline interpolation. */
1086         float points[4][3];
1087         points_for_loose_edges_interpolation_get(
1088                 ctx, coarse_edge, neighbors, points);
1089         /* Perform interpolation. */
1090         float weights[4];
1091         key_curve_position_weights(u, weights, KEY_BSPLINE);
1092
1093         /* Interpolate custom data. */
1094         subdiv_mesh_vertex_of_loose_edge_interpolate(
1095                 ctx, coarse_edge, u, subdiv_vertex_index);
1096         /* Initialize  */
1097         MVert *subdiv_vertex = &subdiv_mvert[subdiv_vertex_index];
1098         interp_v3_v3v3v3v3(subdiv_vertex->co,
1099                            points[0],
1100                            points[1],
1101                            points[2],
1102                            points[3],
1103                            weights);
1104         /* Reset flags and such. */
1105         subdiv_vertex->flag = 0;
1106         /* TODO(sergey): This matches old behavior, but we can as well interpolate
1107          * it. Maybe even using vertex varying attributes. */
1108         subdiv_vertex->bweight = 0.0f;
1109         /* Reset normal, initialize it in a similar way as edit mode does for a
1110          * vertices adjacent to a loose edges. */
1111         normal_float_to_short_v3(subdiv_vertex->no, subdiv_vertex->co);
1112 }
1113
1114 /* =============================================================================
1115  * Initialization.
1116  */
1117
1118 static void setup_foreach_callbacks(SubdivForeachContext *foreach_context,
1119                                     const Subdiv *subdiv)
1120 {
1121         memset(foreach_context, 0, sizeof(*foreach_context));
1122         /* General information. */
1123         foreach_context->topology_info = subdiv_mesh_topology_info;
1124         /* Every boundary geometry. Used for dispalcement averaging. */
1125         if (subdiv->displacement_evaluator != NULL) {
1126                 foreach_context->vertex_every_corner = subdiv_mesh_vertex_every_corner;
1127                 foreach_context->vertex_every_edge = subdiv_mesh_vertex_every_edge;
1128         }
1129         else {
1130                 foreach_context->vertex_every_corner = NULL;
1131                 foreach_context->vertex_every_edge = NULL;
1132         }
1133         foreach_context->vertex_corner = subdiv_mesh_vertex_corner;
1134         foreach_context->vertex_edge = subdiv_mesh_vertex_edge;
1135         foreach_context->vertex_inner = subdiv_mesh_vertex_inner;
1136         foreach_context->edge = subdiv_mesh_edge;
1137         foreach_context->loop = subdiv_mesh_loop;
1138         foreach_context->poly = subdiv_mesh_poly;
1139         foreach_context->vertex_loose = subdiv_mesh_vertex_loose;
1140         foreach_context->vertex_of_loose_edge = subdiv_mesh_vertex_of_loose_edge;
1141         foreach_context->user_data_tls_free = subdiv_mesh_tls_free;
1142 }
1143
1144 /* =============================================================================
1145  * Public entry point.
1146  */
1147
1148 Mesh *BKE_subdiv_to_mesh(
1149         Subdiv *subdiv,
1150         const SubdivToMeshSettings *settings,
1151         const Mesh *coarse_mesh)
1152 {
1153         BKE_subdiv_stats_begin(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_MESH);
1154         /* Make sure evaluator is up to date with possible new topology, and that
1155          * is is refined for the new positions of coarse vertices.
1156          */
1157         if (!BKE_subdiv_eval_update_from_mesh(subdiv, coarse_mesh)) {
1158                 /* This could happen in two situations:
1159                  * - OpenSubdiv is disabled.
1160                  * - Something totally bad happened, and OpenSubdiv rejected our
1161                  *   topology.
1162                  * In either way, we can't safely continue.
1163                  */
1164                 if (coarse_mesh->totpoly) {
1165                         BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_MESH);
1166                         return NULL;
1167                 }
1168         }
1169         /* Initialize subdivion mesh creation context/ */
1170         SubdivMeshContext subdiv_context = {0};
1171         subdiv_context.settings = settings;
1172         subdiv_context.coarse_mesh = coarse_mesh;
1173         subdiv_context.subdiv = subdiv;
1174         /* Multi-threaded traversal/evaluation. */
1175         BKE_subdiv_stats_begin(&subdiv->stats,
1176                                SUBDIV_STATS_SUBDIV_TO_MESH_GEOMETRY);
1177         SubdivForeachContext foreach_context;
1178         setup_foreach_callbacks(&foreach_context, subdiv);
1179         SubdivMeshTLS tls = {0};
1180         foreach_context.user_data = &subdiv_context;
1181         foreach_context.user_data_tls_size = sizeof(SubdivMeshTLS);
1182         foreach_context.user_data_tls = &tls;
1183         BKE_subdiv_foreach_subdiv_geometry(subdiv,
1184                                            &foreach_context,
1185                                            settings,
1186                                            coarse_mesh);
1187         BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_MESH_GEOMETRY);
1188         Mesh *result = subdiv_context.subdiv_mesh;
1189         // BKE_mesh_validate(result, true, true);
1190         BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_MESH);
1191         if (subdiv->displacement_evaluator != NULL) {
1192                 result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
1193         }
1194         return result;
1195 }