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