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