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