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