Blender  V3.3
subdiv_mesh.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2018 Blender Foundation. All rights reserved. */
3 
8 #include "atomic_ops.h"
9 
10 #include "DNA_key_types.h"
11 #include "DNA_mesh_types.h"
12 #include "DNA_meshdata_types.h"
13 
14 #include "BLI_alloca.h"
15 #include "BLI_bitmap.h"
16 #include "BLI_math_vector.h"
17 
18 #include "BKE_customdata.h"
19 #include "BKE_key.h"
20 #include "BKE_mesh.h"
21 #include "BKE_subdiv.h"
22 #include "BKE_subdiv_eval.h"
23 #include "BKE_subdiv_foreach.h"
24 #include "BKE_subdiv_mesh.h"
25 
26 #include "MEM_guardedalloc.h"
27 
28 /* -------------------------------------------------------------------- */
32 typedef struct SubdivMeshContext {
34  const Mesh *coarse_mesh;
37  /* Cached custom data arrays for faster access. */
42  /* UV layers interpolation. */
45  /* Original coordinates (ORCO) interpolation. */
46  float (*orco)[3];
48  /* Per-subdivided vertex counter of averaged values. */
52 
54 {
55  Mesh *subdiv_mesh = ctx->subdiv_mesh;
57  for (int layer_index = 0; layer_index < ctx->num_uv_layers; layer_index++) {
58  ctx->uv_layers[layer_index] = CustomData_get_layer_n(
59  &subdiv_mesh->ldata, CD_MLOOPUV, layer_index);
60  }
61 }
62 
64 {
65  Mesh *subdiv_mesh = ctx->subdiv_mesh;
66  /* Pointers to original indices layers. */
71  /* UV layers interpolation. */
73  /* Orco interpolation. */
74  ctx->orco = CustomData_get_layer(&subdiv_mesh->vdata, CD_ORCO);
75  ctx->cloth_orco = CustomData_get_layer(&subdiv_mesh->vdata, CD_CLOTH_ORCO);
76 }
77 
78 static void subdiv_mesh_prepare_accumulator(SubdivMeshContext *ctx, int num_vertices)
79 {
80  if (!ctx->have_displacement) {
81  return;
82  }
84  num_vertices, sizeof(*ctx->accumulated_counters), "subdiv accumulated counters");
85 }
86 
88 {
90 }
91 
94 /* -------------------------------------------------------------------- */
98 typedef struct LoopsOfPtex {
99  /* First loop of the ptex, starts at ptex (0, 0) and goes in u direction. */
101  /* Last loop of the ptex, starts at ptex (0, 0) and goes in v direction. */
102  const MLoop *last_loop;
103  /* For quad coarse faces only. */
107 
108 static void loops_of_ptex_get(const SubdivMeshContext *ctx,
109  LoopsOfPtex *loops_of_ptex,
110  const MPoly *coarse_poly,
111  const int ptex_of_poly_index)
112 {
113  const MLoop *coarse_mloop = ctx->coarse_mesh->mloop;
114  const int first_ptex_loop_index = coarse_poly->loopstart + ptex_of_poly_index;
115  /* Loop which look in the (opposite) V direction of the current
116  * ptex face.
117  *
118  * TODO(sergey): Get rid of using module on every iteration. */
119  const int last_ptex_loop_index = coarse_poly->loopstart +
120  (ptex_of_poly_index + coarse_poly->totloop - 1) %
121  coarse_poly->totloop;
122  loops_of_ptex->first_loop = &coarse_mloop[first_ptex_loop_index];
123  loops_of_ptex->last_loop = &coarse_mloop[last_ptex_loop_index];
124  if (coarse_poly->totloop == 4) {
125  loops_of_ptex->second_loop = loops_of_ptex->first_loop + 1;
126  loops_of_ptex->third_loop = loops_of_ptex->first_loop + 2;
127  }
128  else {
129  loops_of_ptex->second_loop = NULL;
130  loops_of_ptex->third_loop = NULL;
131  }
132 }
133 
136 /* -------------------------------------------------------------------- */
140 /* TODO(sergey): Somehow de-duplicate with loops storage, without too much
141  * exception cases all over the code. */
142 
143 typedef struct VerticesForInterpolation {
144  /* This field points to a vertex data which is to be used for interpolation.
145  * The idea is to avoid unnecessary allocations for regular faces, where
146  * we can simply use corner vertices. */
148  /* Vertices data calculated for ptex corners. There are always 4 elements
149  * in this custom data, aligned the following way:
150  *
151  * index 0 -> uv (0, 0)
152  * index 1 -> uv (0, 1)
153  * index 2 -> uv (1, 1)
154  * index 3 -> uv (1, 0)
155  *
156  * Is allocated for non-regular faces (triangles and n-gons). */
159  /* Indices within vertex_data to interpolate for. The indices are aligned
160  * with uv coordinates in a similar way as indices in loop_data_storage. */
163 
165  VerticesForInterpolation *vertex_interpolation,
166  const MPoly *coarse_poly)
167 {
168  const Mesh *coarse_mesh = ctx->coarse_mesh;
169  const MLoop *coarse_mloop = coarse_mesh->mloop;
170  if (coarse_poly->totloop == 4) {
171  vertex_interpolation->vertex_data = &coarse_mesh->vdata;
172  vertex_interpolation->vertex_indices[0] = coarse_mloop[coarse_poly->loopstart + 0].v;
173  vertex_interpolation->vertex_indices[1] = coarse_mloop[coarse_poly->loopstart + 1].v;
174  vertex_interpolation->vertex_indices[2] = coarse_mloop[coarse_poly->loopstart + 2].v;
175  vertex_interpolation->vertex_indices[3] = coarse_mloop[coarse_poly->loopstart + 3].v;
176  vertex_interpolation->vertex_data_storage_allocated = false;
177  }
178  else {
179  vertex_interpolation->vertex_data = &vertex_interpolation->vertex_data_storage;
180  /* Allocate storage for loops corresponding to ptex corners. */
182  &vertex_interpolation->vertex_data_storage,
184  CD_CALLOC,
185  4);
186  /* Initialize indices. */
187  vertex_interpolation->vertex_indices[0] = 0;
188  vertex_interpolation->vertex_indices[1] = 1;
189  vertex_interpolation->vertex_indices[2] = 2;
190  vertex_interpolation->vertex_indices[3] = 3;
191  vertex_interpolation->vertex_data_storage_allocated = true;
192  /* Interpolate center of poly right away, it stays unchanged for all
193  * ptex faces. */
194  const float weight = 1.0f / (float)coarse_poly->totloop;
195  float *weights = BLI_array_alloca(weights, coarse_poly->totloop);
196  int *indices = BLI_array_alloca(indices, coarse_poly->totloop);
197  for (int i = 0; i < coarse_poly->totloop; i++) {
198  weights[i] = weight;
199  indices[i] = coarse_mloop[coarse_poly->loopstart + i].v;
200  }
201  CustomData_interp(&coarse_mesh->vdata,
202  &vertex_interpolation->vertex_data_storage,
203  indices,
204  weights,
205  NULL,
206  coarse_poly->totloop,
207  2);
208  }
209 }
210 
212  VerticesForInterpolation *vertex_interpolation,
213  const MPoly *coarse_poly,
214  const int corner)
215 {
216  if (coarse_poly->totloop == 4) {
217  /* Nothing to do, all indices and data is already assigned. */
218  }
219  else {
220  const CustomData *vertex_data = &ctx->coarse_mesh->vdata;
221  const Mesh *coarse_mesh = ctx->coarse_mesh;
222  const MLoop *coarse_mloop = coarse_mesh->mloop;
223  LoopsOfPtex loops_of_ptex;
224  loops_of_ptex_get(ctx, &loops_of_ptex, coarse_poly, corner);
225  /* Ptex face corner corresponds to a poly loop with same index. */
226  CustomData_copy_data(vertex_data,
227  &vertex_interpolation->vertex_data_storage,
228  coarse_mloop[coarse_poly->loopstart + corner].v,
229  0,
230  1);
231  /* Interpolate remaining ptex face corners, which hits loops
232  * middle points.
233  *
234  * TODO(sergey): Re-use one of interpolation results from previous
235  * iteration. */
236  const float weights[2] = {0.5f, 0.5f};
237  const int first_loop_index = loops_of_ptex.first_loop - coarse_mloop;
238  const int last_loop_index = loops_of_ptex.last_loop - coarse_mloop;
239  const int first_indices[2] = {
240  coarse_mloop[first_loop_index].v,
241  coarse_mloop[coarse_poly->loopstart +
242  (first_loop_index - coarse_poly->loopstart + 1) % coarse_poly->totloop]
243  .v};
244  const int last_indices[2] = {
245  coarse_mloop[first_loop_index].v,
246  coarse_mloop[last_loop_index].v,
247  };
248  CustomData_interp(vertex_data,
249  &vertex_interpolation->vertex_data_storage,
250  first_indices,
251  weights,
252  NULL,
253  2,
254  1);
255  CustomData_interp(vertex_data,
256  &vertex_interpolation->vertex_data_storage,
257  last_indices,
258  weights,
259  NULL,
260  2,
261  3);
262  }
263 }
264 
265 static void vertex_interpolation_end(VerticesForInterpolation *vertex_interpolation)
266 {
267  if (vertex_interpolation->vertex_data_storage_allocated) {
268  CustomData_free(&vertex_interpolation->vertex_data_storage, 4);
269  }
270 }
271 
274 /* -------------------------------------------------------------------- */
278 typedef struct LoopsForInterpolation {
279  /* This field points to a loop data which is to be used for interpolation.
280  * The idea is to avoid unnecessary allocations for regular faces, where
281  * we can simply interpolate corner vertices. */
283  /* Loops data calculated for ptex corners. There are always 4 elements
284  * in this custom data, aligned the following way:
285  *
286  * index 0 -> uv (0, 0)
287  * index 1 -> uv (0, 1)
288  * index 2 -> uv (1, 1)
289  * index 3 -> uv (1, 0)
290  *
291  * Is allocated for non-regular faces (triangles and n-gons). */
294  /* Infices within loop_data to interpolate for. The indices are aligned with
295  * uv coordinates in a similar way as indices in loop_data_storage. */
296  int loop_indices[4];
298 
300  LoopsForInterpolation *loop_interpolation,
301  const MPoly *coarse_poly)
302 {
303  const Mesh *coarse_mesh = ctx->coarse_mesh;
304  if (coarse_poly->totloop == 4) {
305  loop_interpolation->loop_data = &coarse_mesh->ldata;
306  loop_interpolation->loop_indices[0] = coarse_poly->loopstart + 0;
307  loop_interpolation->loop_indices[1] = coarse_poly->loopstart + 1;
308  loop_interpolation->loop_indices[2] = coarse_poly->loopstart + 2;
309  loop_interpolation->loop_indices[3] = coarse_poly->loopstart + 3;
310  loop_interpolation->loop_data_storage_allocated = false;
311  }
312  else {
313  loop_interpolation->loop_data = &loop_interpolation->loop_data_storage;
314  /* Allocate storage for loops corresponding to ptex corners. */
316  &loop_interpolation->loop_data_storage,
318  CD_CALLOC,
319  4);
320  /* Initialize indices. */
321  loop_interpolation->loop_indices[0] = 0;
322  loop_interpolation->loop_indices[1] = 1;
323  loop_interpolation->loop_indices[2] = 2;
324  loop_interpolation->loop_indices[3] = 3;
325  loop_interpolation->loop_data_storage_allocated = true;
326  /* Interpolate center of poly right away, it stays unchanged for all
327  * ptex faces. */
328  const float weight = 1.0f / (float)coarse_poly->totloop;
329  float *weights = BLI_array_alloca(weights, coarse_poly->totloop);
330  int *indices = BLI_array_alloca(indices, coarse_poly->totloop);
331  for (int i = 0; i < coarse_poly->totloop; i++) {
332  weights[i] = weight;
333  indices[i] = coarse_poly->loopstart + i;
334  }
335  CustomData_interp(&coarse_mesh->ldata,
336  &loop_interpolation->loop_data_storage,
337  indices,
338  weights,
339  NULL,
340  coarse_poly->totloop,
341  2);
342  }
343 }
344 
346  LoopsForInterpolation *loop_interpolation,
347  const MPoly *coarse_poly,
348  const int corner)
349 {
350  if (coarse_poly->totloop == 4) {
351  /* Nothing to do, all indices and data is already assigned. */
352  }
353  else {
354  const CustomData *loop_data = &ctx->coarse_mesh->ldata;
355  const Mesh *coarse_mesh = ctx->coarse_mesh;
356  const MLoop *coarse_mloop = coarse_mesh->mloop;
357  LoopsOfPtex loops_of_ptex;
358  loops_of_ptex_get(ctx, &loops_of_ptex, coarse_poly, corner);
359  /* Ptex face corner corresponds to a poly loop with same index. */
360  CustomData_free_elem(&loop_interpolation->loop_data_storage, 0, 1);
362  loop_data, &loop_interpolation->loop_data_storage, coarse_poly->loopstart + corner, 0, 1);
363  /* Interpolate remaining ptex face corners, which hits loops
364  * middle points.
365  *
366  * TODO(sergey): Re-use one of interpolation results from previous
367  * iteration. */
368  const float weights[2] = {0.5f, 0.5f};
369  const int base_loop_index = coarse_poly->loopstart;
370  const int first_loop_index = loops_of_ptex.first_loop - coarse_mloop;
371  const int second_loop_index = base_loop_index +
372  (first_loop_index - base_loop_index + 1) % coarse_poly->totloop;
373  const int first_indices[2] = {first_loop_index, second_loop_index};
374  const int last_indices[2] = {
375  loops_of_ptex.last_loop - coarse_mloop,
376  loops_of_ptex.first_loop - coarse_mloop,
377  };
379  loop_data, &loop_interpolation->loop_data_storage, first_indices, weights, NULL, 2, 1);
381  loop_data, &loop_interpolation->loop_data_storage, last_indices, weights, NULL, 2, 3);
382  }
383 }
384 
385 static void loop_interpolation_end(LoopsForInterpolation *loop_interpolation)
386 {
387  if (loop_interpolation->loop_data_storage_allocated) {
388  CustomData_free(&loop_interpolation->loop_data_storage, 4);
389  }
390 }
391 
394 /* -------------------------------------------------------------------- */
398 typedef struct SubdivMeshTLS {
403 
409 
410 static void subdiv_mesh_tls_free(void *tls_v)
411 {
412  SubdivMeshTLS *tls = tls_v;
415  }
418  }
419 }
420 
423 /* -------------------------------------------------------------------- */
428  const int ptex_face_index,
429  const float u,
430  const float v,
431  const int subdiv_vertex_index)
432 {
433  if (ctx->orco || ctx->cloth_orco) {
434  float vertex_data[6];
435  BKE_subdiv_eval_vertex_data(ctx->subdiv, ptex_face_index, u, v, vertex_data);
436 
437  if (ctx->orco) {
438  copy_v3_v3(ctx->orco[subdiv_vertex_index], vertex_data);
439  if (ctx->cloth_orco) {
440  copy_v3_v3(ctx->cloth_orco[subdiv_vertex_index], vertex_data + 3);
441  }
442  }
443  else if (ctx->cloth_orco) {
444  copy_v3_v3(ctx->cloth_orco[subdiv_vertex_index], vertex_data);
445  }
446  }
447 }
448 
451 /* -------------------------------------------------------------------- */
456  const int ptex_face_index,
457  const float u,
458  const float v,
459  MVert *subdiv_vert)
460 {
461  /* Accumulate displacement. */
462  Subdiv *subdiv = ctx->subdiv;
463  const int subdiv_vertex_index = subdiv_vert - ctx->subdiv_mesh->mvert;
464  float dummy_P[3], dPdu[3], dPdv[3], D[3];
465  BKE_subdiv_eval_limit_point_and_derivatives(subdiv, ptex_face_index, u, v, dummy_P, dPdu, dPdv);
466 
467  /* NOTE: The subdivided mesh is allocated in this module, and its vertices are kept at zero
468  * locations as a default calloc(). */
469  BKE_subdiv_eval_displacement(subdiv, ptex_face_index, u, v, dPdu, dPdv, D);
470  add_v3_v3(subdiv_vert->co, D);
471 
472  if (ctx->accumulated_counters) {
473  ++ctx->accumulated_counters[subdiv_vertex_index];
474  }
475 }
476 
479 /* -------------------------------------------------------------------- */
483 static bool subdiv_mesh_topology_info(const SubdivForeachContext *foreach_context,
484  const int num_vertices,
485  const int num_edges,
486  const int num_loops,
487  const int num_polygons,
488  const int *UNUSED(subdiv_polygon_offset))
489 {
490  /* Multi-resolution grid data will be applied or become invalid after subdivision,
491  * so don't try to preserve it and use memory. */
493  mask.lmask &= ~CD_MASK_MULTIRES_GRIDS;
494 
495  SubdivMeshContext *subdiv_context = foreach_context->user_data;
497  subdiv_context->coarse_mesh, num_vertices, num_edges, 0, num_loops, num_polygons, mask);
499  subdiv_mesh_prepare_accumulator(subdiv_context, num_vertices);
501  subdiv_context->subdiv_mesh->runtime.subsurf_face_dot_tags = BLI_BITMAP_NEW(num_vertices,
502  __func__);
503  return true;
504 }
505 
508 /* -------------------------------------------------------------------- */
513  const MVert *coarse_vertex,
514  MVert *subdiv_vertex)
515 {
516  const Mesh *coarse_mesh = ctx->coarse_mesh;
517  Mesh *subdiv_mesh = ctx->subdiv_mesh;
518  const int coarse_vertex_index = coarse_vertex - coarse_mesh->mvert;
519  const int subdiv_vertex_index = subdiv_vertex - subdiv_mesh->mvert;
521  &coarse_mesh->vdata, &ctx->subdiv_mesh->vdata, coarse_vertex_index, subdiv_vertex_index, 1);
522 }
523 
525  MVert *subdiv_vertex,
526  const VerticesForInterpolation *vertex_interpolation,
527  const float u,
528  const float v)
529 {
530  const int subdiv_vertex_index = subdiv_vertex - ctx->subdiv_mesh->mvert;
531  const float weights[4] = {(1.0f - u) * (1.0f - v), u * (1.0f - v), u * v, (1.0f - u) * v};
532  CustomData_interp(vertex_interpolation->vertex_data,
533  &ctx->subdiv_mesh->vdata,
534  vertex_interpolation->vertex_indices,
535  weights,
536  NULL,
537  4,
538  subdiv_vertex_index);
539  if (ctx->vert_origindex != NULL) {
540  ctx->vert_origindex[subdiv_vertex_index] = ORIGINDEX_NONE;
541  }
542 }
543 
545  const int ptex_face_index,
546  const float u,
547  const float v,
548  const MVert *coarse_vert,
549  MVert *subdiv_vert)
550 {
551  const int subdiv_vertex_index = subdiv_vert - ctx->subdiv_mesh->mvert;
552  /* Displacement is accumulated in subdiv vertex position.
553  * Needs to be backed up before copying data from original vertex. */
554  float D[3] = {0.0f, 0.0f, 0.0f};
555  if (ctx->have_displacement) {
556  const float inv_num_accumulated = 1.0f / ctx->accumulated_counters[subdiv_vertex_index];
557  copy_v3_v3(D, subdiv_vert->co);
558  mul_v3_fl(D, inv_num_accumulated);
559  }
560  /* Copy custom data and evaluate position. */
561  subdiv_vertex_data_copy(ctx, coarse_vert, subdiv_vert);
562  BKE_subdiv_eval_limit_point(ctx->subdiv, ptex_face_index, u, v, subdiv_vert->co);
563  /* Apply displacement. */
564  add_v3_v3(subdiv_vert->co, D);
565  /* Evaluate undeformed texture coordinate. */
566  subdiv_vertex_orco_evaluate(ctx, ptex_face_index, u, v, subdiv_vertex_index);
567  /* Remove facedot flag. This can happen if there is more than one subsurf modifier. */
568  BLI_BITMAP_DISABLE(ctx->subdiv_mesh->runtime.subsurf_face_dot_tags, subdiv_vertex_index);
569 }
570 
572  const SubdivMeshContext *ctx,
573  const int ptex_face_index,
574  const float u,
575  const float v,
576  VerticesForInterpolation *vertex_interpolation,
577  MVert *subdiv_vert)
578 {
579  const int subdiv_vertex_index = subdiv_vert - ctx->subdiv_mesh->mvert;
580  /* Displacement is accumulated in subdiv vertex position.
581  * Needs to be backed up before copying data from original vertex. */
582  float D[3] = {0.0f, 0.0f, 0.0f};
583  if (ctx->have_displacement) {
584  const float inv_num_accumulated = 1.0f / ctx->accumulated_counters[subdiv_vertex_index];
585  copy_v3_v3(D, subdiv_vert->co);
586  mul_v3_fl(D, inv_num_accumulated);
587  }
588  /* Interpolate custom data and evaluate position. */
589  subdiv_vertex_data_interpolate(ctx, subdiv_vert, vertex_interpolation, u, v);
590  BKE_subdiv_eval_limit_point(ctx->subdiv, ptex_face_index, u, v, subdiv_vert->co);
591  /* Apply displacement. */
592  add_v3_v3(subdiv_vert->co, D);
593  /* Evaluate undeformed texture coordinate. */
594  subdiv_vertex_orco_evaluate(ctx, ptex_face_index, u, v, subdiv_vertex_index);
595 }
596 
598  const SubdivForeachContext *foreach_context,
599  void *UNUSED(tls),
600  const int ptex_face_index,
601  const float u,
602  const float v,
603  const int subdiv_vertex_index)
604 {
605  SubdivMeshContext *ctx = foreach_context->user_data;
606  Mesh *subdiv_mesh = ctx->subdiv_mesh;
607  MVert *subdiv_mvert = subdiv_mesh->mvert;
608  MVert *subdiv_vert = &subdiv_mvert[subdiv_vertex_index];
609  subdiv_accumulate_vertex_displacement(ctx, ptex_face_index, u, v, subdiv_vert);
610 }
611 
613  const SubdivForeachContext *foreach_context,
614  void *tls,
615  const int ptex_face_index,
616  const float u,
617  const float v,
618  const int UNUSED(coarse_vertex_index),
619  const int UNUSED(coarse_poly_index),
620  const int UNUSED(coarse_corner),
621  const int subdiv_vertex_index)
622 {
624  foreach_context, tls, ptex_face_index, u, v, subdiv_vertex_index);
625 }
626 
628  void *tls,
629  const int ptex_face_index,
630  const float u,
631  const float v,
632  const int UNUSED(coarse_edge_index),
633  const int UNUSED(coarse_poly_index),
634  const int UNUSED(coarse_corner),
635  const int subdiv_vertex_index)
636 {
638  foreach_context, tls, ptex_face_index, u, v, subdiv_vertex_index);
639 }
640 
641 static void subdiv_mesh_vertex_corner(const SubdivForeachContext *foreach_context,
642  void *UNUSED(tls),
643  const int ptex_face_index,
644  const float u,
645  const float v,
646  const int coarse_vertex_index,
647  const int UNUSED(coarse_poly_index),
648  const int UNUSED(coarse_corner),
649  const int subdiv_vertex_index)
650 {
651  BLI_assert(coarse_vertex_index != ORIGINDEX_NONE);
652  SubdivMeshContext *ctx = foreach_context->user_data;
653  const Mesh *coarse_mesh = ctx->coarse_mesh;
654  const MVert *coarse_mvert = coarse_mesh->mvert;
655  Mesh *subdiv_mesh = ctx->subdiv_mesh;
656  MVert *subdiv_mvert = subdiv_mesh->mvert;
657  const MVert *coarse_vert = &coarse_mvert[coarse_vertex_index];
658  MVert *subdiv_vert = &subdiv_mvert[subdiv_vertex_index];
660  ctx, ptex_face_index, u, v, coarse_vert, subdiv_vert);
661 }
662 
664  SubdivMeshTLS *tls,
665  const MPoly *coarse_poly,
666  const int coarse_corner)
667 {
668  /* Check whether we've moved to another corner or polygon. */
670  if (tls->vertex_interpolation_coarse_poly != coarse_poly ||
671  tls->vertex_interpolation_coarse_corner != coarse_corner) {
674  }
675  }
676  /* Initialize the interpolation. */
678  vertex_interpolation_init(ctx, &tls->vertex_interpolation, coarse_poly);
679  }
680  /* Update it for a new corner if needed. */
682  tls->vertex_interpolation_coarse_corner != coarse_corner) {
683  vertex_interpolation_from_corner(ctx, &tls->vertex_interpolation, coarse_poly, coarse_corner);
684  }
685  /* Store settings used for the current state of interpolator. */
687  tls->vertex_interpolation_coarse_poly = coarse_poly;
688  tls->vertex_interpolation_coarse_corner = coarse_corner;
689 }
690 
691 static void subdiv_mesh_vertex_edge(const SubdivForeachContext *foreach_context,
692  void *tls_v,
693  const int ptex_face_index,
694  const float u,
695  const float v,
696  const int UNUSED(coarse_edge_index),
697  const int coarse_poly_index,
698  const int coarse_corner,
699  const int subdiv_vertex_index)
700 {
701  SubdivMeshContext *ctx = foreach_context->user_data;
702  SubdivMeshTLS *tls = tls_v;
703  const Mesh *coarse_mesh = ctx->coarse_mesh;
704  const MPoly *coarse_mpoly = coarse_mesh->mpoly;
705  const MPoly *coarse_poly = &coarse_mpoly[coarse_poly_index];
706  Mesh *subdiv_mesh = ctx->subdiv_mesh;
707  MVert *subdiv_mvert = subdiv_mesh->mvert;
708  MVert *subdiv_vert = &subdiv_mvert[subdiv_vertex_index];
709  subdiv_mesh_ensure_vertex_interpolation(ctx, tls, coarse_poly, coarse_corner);
711  ctx, ptex_face_index, u, v, &tls->vertex_interpolation, subdiv_vert);
712 }
713 
714 static bool subdiv_mesh_is_center_vertex(const MPoly *coarse_poly, const float u, const float v)
715 {
716  if (coarse_poly->totloop == 4) {
717  if (u == 0.5f && v == 0.5f) {
718  return true;
719  }
720  }
721  else {
722  if (u == 1.0f && v == 1.0f) {
723  return true;
724  }
725  }
726  return false;
727 }
728 
729 static void subdiv_mesh_tag_center_vertex(const MPoly *coarse_poly,
730  const int subdiv_vertex_index,
731  const float u,
732  const float v,
733  Mesh *subdiv_mesh)
734 {
735  if (subdiv_mesh_is_center_vertex(coarse_poly, u, v)) {
736  BLI_BITMAP_ENABLE(subdiv_mesh->runtime.subsurf_face_dot_tags, subdiv_vertex_index);
737  }
738 }
739 
740 static void subdiv_mesh_vertex_inner(const SubdivForeachContext *foreach_context,
741  void *tls_v,
742  const int ptex_face_index,
743  const float u,
744  const float v,
745  const int coarse_poly_index,
746  const int coarse_corner,
747  const int subdiv_vertex_index)
748 {
749  SubdivMeshContext *ctx = foreach_context->user_data;
750  SubdivMeshTLS *tls = tls_v;
751  Subdiv *subdiv = ctx->subdiv;
752  const Mesh *coarse_mesh = ctx->coarse_mesh;
753  const MPoly *coarse_mpoly = coarse_mesh->mpoly;
754  const MPoly *coarse_poly = &coarse_mpoly[coarse_poly_index];
755  Mesh *subdiv_mesh = ctx->subdiv_mesh;
756  MVert *subdiv_mvert = subdiv_mesh->mvert;
757  MVert *subdiv_vert = &subdiv_mvert[subdiv_vertex_index];
758  subdiv_mesh_ensure_vertex_interpolation(ctx, tls, coarse_poly, coarse_corner);
759  subdiv_vertex_data_interpolate(ctx, subdiv_vert, &tls->vertex_interpolation, u, v);
760  BKE_subdiv_eval_final_point(subdiv, ptex_face_index, u, v, subdiv_vert->co);
761  subdiv_mesh_tag_center_vertex(coarse_poly, subdiv_vertex_index, u, v, subdiv_mesh);
762  subdiv_vertex_orco_evaluate(ctx, ptex_face_index, u, v, subdiv_vertex_index);
763 }
764 
767 /* -------------------------------------------------------------------- */
772  MEdge *subdiv_edge,
773  const MEdge *coarse_edge)
774 {
775  const int subdiv_edge_index = subdiv_edge - ctx->subdiv_mesh->medge;
776  if (coarse_edge == NULL) {
777  subdiv_edge->crease = 0;
778  subdiv_edge->bweight = 0;
779  subdiv_edge->flag = 0;
780  if (!ctx->settings->use_optimal_display) {
781  subdiv_edge->flag |= ME_EDGERENDER;
782  }
783  if (ctx->edge_origindex != NULL) {
784  ctx->edge_origindex[subdiv_edge_index] = ORIGINDEX_NONE;
785  }
786  return;
787  }
788  const int coarse_edge_index = coarse_edge - ctx->coarse_mesh->medge;
790  &ctx->coarse_mesh->edata, &ctx->subdiv_mesh->edata, coarse_edge_index, subdiv_edge_index, 1);
791  subdiv_edge->flag |= ME_EDGERENDER;
792 }
793 
794 static void subdiv_mesh_edge(const SubdivForeachContext *foreach_context,
795  void *UNUSED(tls),
796  const int coarse_edge_index,
797  const int subdiv_edge_index,
798  const bool UNUSED(is_loose),
799  const int subdiv_v1,
800  const int subdiv_v2)
801 {
802  SubdivMeshContext *ctx = foreach_context->user_data;
803  Mesh *subdiv_mesh = ctx->subdiv_mesh;
804  MEdge *subdiv_medge = subdiv_mesh->medge;
805  MEdge *subdiv_edge = &subdiv_medge[subdiv_edge_index];
806  const MEdge *coarse_edge = NULL;
807  if (coarse_edge_index != ORIGINDEX_NONE) {
808  const Mesh *coarse_mesh = ctx->coarse_mesh;
809  const MEdge *coarse_medge = coarse_mesh->medge;
810  coarse_edge = &coarse_medge[coarse_edge_index];
811  }
812  subdiv_copy_edge_data(ctx, subdiv_edge, coarse_edge);
813  subdiv_edge->v1 = subdiv_v1;
814  subdiv_edge->v2 = subdiv_v2;
815 }
816 
819 /* -------------------------------------------------------------------- */
824  MLoop *subdiv_loop,
825  const LoopsForInterpolation *loop_interpolation,
826  const float u,
827  const float v)
828 {
829  const int subdiv_loop_index = subdiv_loop - ctx->subdiv_mesh->mloop;
830  const float weights[4] = {(1.0f - u) * (1.0f - v), u * (1.0f - v), u * v, (1.0f - u) * v};
831  CustomData_interp(loop_interpolation->loop_data,
832  &ctx->subdiv_mesh->ldata,
833  loop_interpolation->loop_indices,
834  weights,
835  NULL,
836  4,
837  subdiv_loop_index);
838  /* TODO(sergey): Set ORIGINDEX. */
839 }
840 
842  MLoop *subdiv_loop,
843  const int ptex_face_index,
844  const float u,
845  const float v)
846 {
847  if (ctx->num_uv_layers == 0) {
848  return;
849  }
850  Subdiv *subdiv = ctx->subdiv;
851  const int mloop_index = subdiv_loop - ctx->subdiv_mesh->mloop;
852  for (int layer_index = 0; layer_index < ctx->num_uv_layers; layer_index++) {
853  MLoopUV *subdiv_loopuv = &ctx->uv_layers[layer_index][mloop_index];
854  BKE_subdiv_eval_face_varying(subdiv, layer_index, ptex_face_index, u, v, subdiv_loopuv->uv);
855  }
856 }
857 
859  SubdivMeshTLS *tls,
860  const MPoly *coarse_poly,
861  const int coarse_corner)
862 {
863  /* Check whether we've moved to another corner or polygon. */
865  if (tls->loop_interpolation_coarse_poly != coarse_poly ||
866  tls->loop_interpolation_coarse_corner != coarse_corner) {
868  tls->loop_interpolation_initialized = false;
869  }
870  }
871  /* Initialize the interpolation. */
872  if (!tls->loop_interpolation_initialized) {
873  loop_interpolation_init(ctx, &tls->loop_interpolation, coarse_poly);
874  }
875  /* Update it for a new corner if needed. */
876  if (!tls->loop_interpolation_initialized ||
877  tls->loop_interpolation_coarse_corner != coarse_corner) {
878  loop_interpolation_from_corner(ctx, &tls->loop_interpolation, coarse_poly, coarse_corner);
879  }
880  /* Store settings used for the current state of interpolator. */
881  tls->loop_interpolation_initialized = true;
882  tls->loop_interpolation_coarse_poly = coarse_poly;
883  tls->loop_interpolation_coarse_corner = coarse_corner;
884 }
885 
886 static void subdiv_mesh_loop(const SubdivForeachContext *foreach_context,
887  void *tls_v,
888  const int ptex_face_index,
889  const float u,
890  const float v,
891  const int UNUSED(coarse_loop_index),
892  const int coarse_poly_index,
893  const int coarse_corner,
894  const int subdiv_loop_index,
895  const int subdiv_vertex_index,
896  const int subdiv_edge_index)
897 {
898  SubdivMeshContext *ctx = foreach_context->user_data;
899  SubdivMeshTLS *tls = tls_v;
900  const Mesh *coarse_mesh = ctx->coarse_mesh;
901  const MPoly *coarse_mpoly = coarse_mesh->mpoly;
902  const MPoly *coarse_poly = &coarse_mpoly[coarse_poly_index];
903  Mesh *subdiv_mesh = ctx->subdiv_mesh;
904  MLoop *subdiv_mloop = subdiv_mesh->mloop;
905  MLoop *subdiv_loop = &subdiv_mloop[subdiv_loop_index];
906  subdiv_mesh_ensure_loop_interpolation(ctx, tls, coarse_poly, coarse_corner);
907  subdiv_interpolate_loop_data(ctx, subdiv_loop, &tls->loop_interpolation, u, v);
908  subdiv_eval_uv_layer(ctx, subdiv_loop, ptex_face_index, u, v);
909  subdiv_loop->v = subdiv_vertex_index;
910  subdiv_loop->e = subdiv_edge_index;
911 }
912 
915 /* -------------------------------------------------------------------- */
920  MPoly *subdiv_poly,
921  const MPoly *coarse_poly)
922 {
923  const int coarse_poly_index = coarse_poly - ctx->coarse_mesh->mpoly;
924  const int subdiv_poly_index = subdiv_poly - ctx->subdiv_mesh->mpoly;
926  &ctx->coarse_mesh->pdata, &ctx->subdiv_mesh->pdata, coarse_poly_index, subdiv_poly_index, 1);
927 }
928 
929 static void subdiv_mesh_poly(const SubdivForeachContext *foreach_context,
930  void *UNUSED(tls),
931  const int coarse_poly_index,
932  const int subdiv_poly_index,
933  const int start_loop_index,
934  const int num_loops)
935 {
936  BLI_assert(coarse_poly_index != ORIGINDEX_NONE);
937  SubdivMeshContext *ctx = foreach_context->user_data;
938  const Mesh *coarse_mesh = ctx->coarse_mesh;
939  const MPoly *coarse_mpoly = coarse_mesh->mpoly;
940  const MPoly *coarse_poly = &coarse_mpoly[coarse_poly_index];
941  Mesh *subdiv_mesh = ctx->subdiv_mesh;
942  MPoly *subdiv_mpoly = subdiv_mesh->mpoly;
943  MPoly *subdiv_poly = &subdiv_mpoly[subdiv_poly_index];
944  subdiv_copy_poly_data(ctx, subdiv_poly, coarse_poly);
945  subdiv_poly->loopstart = start_loop_index;
946  subdiv_poly->totloop = num_loops;
947 }
948 
951 /* -------------------------------------------------------------------- */
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 Mesh *coarse_mesh,
974  const MEdge *edge,
975  const MEdge *neighbors[2])
976 {
977  const MEdge *coarse_medge = coarse_mesh->medge;
978  neighbors[0] = NULL;
979  neighbors[1] = NULL;
980  int neighbor_counters[2] = {0, 0};
981  for (int edge_index = 0; edge_index < coarse_mesh->totedge; edge_index++) {
982  const MEdge *current_edge = &coarse_medge[edge_index];
983  if (current_edge == edge) {
984  continue;
985  }
986  if (ELEM(edge->v1, current_edge->v1, current_edge->v2)) {
987  neighbors[0] = current_edge;
988  ++neighbor_counters[0];
989  }
990  if (ELEM(edge->v2, current_edge->v1, current_edge->v2)) {
991  neighbors[1] = current_edge;
992  ++neighbor_counters[1];
993  }
994  }
995  /* Vertices which has more than one neighbor are considered infinitely
996  * sharp. This is also how topology factory treats vertices of a surface
997  * which are adjacent to a loose edge. */
998  if (neighbor_counters[0] > 1) {
999  neighbors[0] = NULL;
1000  }
1001  if (neighbor_counters[1] > 1) {
1002  neighbors[1] = NULL;
1003  }
1004 }
1005 
1006 static void points_for_loose_edges_interpolation_get(const Mesh *coarse_mesh,
1007  const MEdge *coarse_edge,
1008  const MEdge *neighbors[2],
1009  float points_r[4][3])
1010 {
1011  const MVert *coarse_mvert = coarse_mesh->mvert;
1012  /* Middle points corresponds to the edge. */
1013  copy_v3_v3(points_r[1], coarse_mvert[coarse_edge->v1].co);
1014  copy_v3_v3(points_r[2], coarse_mvert[coarse_edge->v2].co);
1015  /* Start point, duplicate from edge start if no neighbor. */
1016  if (neighbors[0] != NULL) {
1017  if (neighbors[0]->v1 == coarse_edge->v1) {
1018  copy_v3_v3(points_r[0], coarse_mvert[neighbors[0]->v2].co);
1019  }
1020  else {
1021  copy_v3_v3(points_r[0], coarse_mvert[neighbors[0]->v1].co);
1022  }
1023  }
1024  else {
1025  sub_v3_v3v3(points_r[0], points_r[1], points_r[2]);
1026  add_v3_v3(points_r[0], points_r[1]);
1027  }
1028  /* End point, duplicate from edge end if no neighbor. */
1029  if (neighbors[1] != NULL) {
1030  if (neighbors[1]->v1 == coarse_edge->v2) {
1031  copy_v3_v3(points_r[3], coarse_mvert[neighbors[1]->v2].co);
1032  }
1033  else {
1034  copy_v3_v3(points_r[3], coarse_mvert[neighbors[1]->v1].co);
1035  }
1036  }
1037  else {
1038  sub_v3_v3v3(points_r[3], points_r[2], points_r[1]);
1039  add_v3_v3(points_r[3], points_r[2]);
1040  }
1041 }
1042 
1044  const MEdge *coarse_edge,
1045  const bool is_simple,
1046  const float u,
1047  float pos_r[3])
1048 {
1049  if (is_simple) {
1050  const MVert *coarse_mvert = coarse_mesh->mvert;
1051  const MVert *vert_1 = &coarse_mvert[coarse_edge->v1];
1052  const MVert *vert_2 = &coarse_mvert[coarse_edge->v2];
1053  interp_v3_v3v3(pos_r, vert_1->co, vert_2->co, u);
1054  }
1055  else {
1056  /* Find neighbors of the coarse edge. */
1057  const MEdge *neighbors[2];
1058  find_edge_neighbors(coarse_mesh, coarse_edge, neighbors);
1059  float points[4][3];
1060  points_for_loose_edges_interpolation_get(coarse_mesh, coarse_edge, neighbors, points);
1061  float weights[4];
1063  interp_v3_v3v3v3v3(pos_r, points[0], points[1], points[2], points[3], weights);
1064  }
1065 }
1066 
1068  const MEdge *coarse_edge,
1069  const float u,
1070  const int subdiv_vertex_index)
1071 {
1072  const Mesh *coarse_mesh = ctx->coarse_mesh;
1073  Mesh *subdiv_mesh = ctx->subdiv_mesh;
1074  /* This is never used for end-points (which are copied from the original). */
1075  BLI_assert(u > 0.0f);
1076  BLI_assert(u < 1.0f);
1077  const float interpolation_weights[2] = {1.0f - u, u};
1078  const int coarse_vertex_indices[2] = {coarse_edge->v1, coarse_edge->v2};
1079  CustomData_interp(&coarse_mesh->vdata,
1080  &subdiv_mesh->vdata,
1081  coarse_vertex_indices,
1082  interpolation_weights,
1083  NULL,
1084  2,
1085  subdiv_vertex_index);
1086  if (ctx->vert_origindex != NULL) {
1087  ctx->vert_origindex[subdiv_vertex_index] = ORIGINDEX_NONE;
1088  }
1089 }
1090 
1091 static void subdiv_mesh_vertex_of_loose_edge(const struct SubdivForeachContext *foreach_context,
1092  void *UNUSED(tls),
1093  const int coarse_edge_index,
1094  const float u,
1095  const int subdiv_vertex_index)
1096 {
1097  SubdivMeshContext *ctx = foreach_context->user_data;
1098  const Mesh *coarse_mesh = ctx->coarse_mesh;
1099  const MEdge *coarse_edge = &coarse_mesh->medge[coarse_edge_index];
1100  Mesh *subdiv_mesh = ctx->subdiv_mesh;
1101  MVert *subdiv_mvert = subdiv_mesh->mvert;
1102  const bool is_simple = ctx->subdiv->settings.is_simple;
1103  /* Interpolate custom data when not an end point.
1104  * This data has already been copied from the original vertex by #subdiv_mesh_vertex_loose. */
1105  if (!ELEM(u, 0.0, 1.0)) {
1106  subdiv_mesh_vertex_of_loose_edge_interpolate(ctx, coarse_edge, u, subdiv_vertex_index);
1107  }
1108  /* Interpolate coordinate. */
1109  MVert *subdiv_vertex = &subdiv_mvert[subdiv_vertex_index];
1111  coarse_mesh, coarse_edge, is_simple, u, subdiv_vertex->co);
1112  /* Reset flags and such. */
1113  subdiv_vertex->flag = 0;
1114  /* TODO(sergey): This matches old behavior, but we can as well interpolate
1115  * it. Maybe even using vertex varying attributes. */
1116  subdiv_vertex->bweight = 0.0f;
1117 }
1118 
1121 /* -------------------------------------------------------------------- */
1125 static void setup_foreach_callbacks(const SubdivMeshContext *subdiv_context,
1126  SubdivForeachContext *foreach_context)
1127 {
1128  memset(foreach_context, 0, sizeof(*foreach_context));
1129  /* General information. */
1130  foreach_context->topology_info = subdiv_mesh_topology_info;
1131  /* Every boundary geometry. Used for displacement averaging. */
1132  if (subdiv_context->have_displacement) {
1135  }
1136  foreach_context->vertex_corner = subdiv_mesh_vertex_corner;
1137  foreach_context->vertex_edge = subdiv_mesh_vertex_edge;
1138  foreach_context->vertex_inner = subdiv_mesh_vertex_inner;
1139  foreach_context->edge = subdiv_mesh_edge;
1140  foreach_context->loop = subdiv_mesh_loop;
1141  foreach_context->poly = subdiv_mesh_poly;
1142  foreach_context->vertex_loose = subdiv_mesh_vertex_loose;
1144  foreach_context->user_data_tls_free = subdiv_mesh_tls_free;
1145 }
1146 
1149 /* -------------------------------------------------------------------- */
1154  const SubdivToMeshSettings *settings,
1155  const Mesh *coarse_mesh)
1156 {
1158  /* Make sure evaluator is up to date with possible new topology, and that
1159  * it is refined for the new positions of coarse vertices. */
1161  subdiv, coarse_mesh, NULL, SUBDIV_EVALUATOR_TYPE_CPU, NULL)) {
1162  /* This could happen in two situations:
1163  * - OpenSubdiv is disabled.
1164  * - Something totally bad happened, and OpenSubdiv rejected our
1165  * topology.
1166  * In either way, we can't safely continue. */
1167  if (coarse_mesh->totpoly) {
1169  return NULL;
1170  }
1171  }
1172  /* Initialize subdivision mesh creation context. */
1173  SubdivMeshContext subdiv_context = {0};
1174  subdiv_context.settings = settings;
1175  subdiv_context.coarse_mesh = coarse_mesh;
1176  subdiv_context.subdiv = subdiv;
1177  subdiv_context.have_displacement = (subdiv->displacement_evaluator != NULL);
1178  /* Multi-threaded traversal/evaluation. */
1180  SubdivForeachContext foreach_context;
1181  setup_foreach_callbacks(&subdiv_context, &foreach_context);
1182  SubdivMeshTLS tls = {0};
1183  foreach_context.user_data = &subdiv_context;
1184  foreach_context.user_data_tls_size = sizeof(SubdivMeshTLS);
1185  foreach_context.user_data_tls = &tls;
1186  BKE_subdiv_foreach_subdiv_geometry(subdiv, &foreach_context, settings, coarse_mesh);
1188  Mesh *result = subdiv_context.subdiv_mesh;
1189  // BKE_mesh_validate(result, true, true);
1191  /* Using normals from the limit surface gives different results than Blender's vertex normal
1192  * calculation. Since vertex normals are supposed to be a consistent cache, don't bother
1193  * calculating them here. The work may have been pointless anyway if the mesh is deformed or
1194  * changed afterwards. */
1196  /* Free used memory. */
1197  subdiv_mesh_context_free(&subdiv_context);
1198  return result;
1199 }
1200 
typedef float(TangentPoint)[2]
CustomData interface, see also DNA_customdata_types.h.
const CustomData_MeshMasks CD_MASK_EVERYTHING
Definition: customdata.cc:2101
void CustomData_free(struct CustomData *data, int totelem)
Definition: customdata.cc:2373
int CustomData_number_of_layers(const struct CustomData *data, int type)
@ CD_CALLOC
void CustomData_copy(const struct CustomData *source, struct CustomData *dest, eCustomDataMask mask, eCDAllocType alloctype, int totelem)
void CustomData_interp(const struct CustomData *source, struct CustomData *dest, const int *src_indices, const float *weights, const float *sub_weights, int count, int dest_index)
#define ORIGINDEX_NONE
void * CustomData_get_layer_n(const struct CustomData *data, int type, int n)
void * CustomData_get_layer(const struct CustomData *data, int type)
void CustomData_free_elem(struct CustomData *data, int index, int count)
Definition: customdata.cc:3206
void CustomData_copy_data(const struct CustomData *source, struct CustomData *dest, int source_index, int dest_index, int count)
void key_curve_position_weights(float t, float data[4], int type)
Definition: key.c:336
bool BKE_mesh_poly_normals_are_dirty(const struct Mesh *mesh)
bool BKE_mesh_vertex_normals_are_dirty(const struct Mesh *mesh)
struct Mesh * BKE_mesh_new_nomain_from_template_ex(const struct Mesh *me_src, int verts_len, int edges_len, int tessface_len, int loops_len, int polys_len, struct CustomData_MeshMasks mask)
@ SUBDIV_STATS_SUBDIV_TO_MESH_GEOMETRY
Definition: BKE_subdiv.h:78
@ SUBDIV_STATS_SUBDIV_TO_MESH
Definition: BKE_subdiv.h:77
void BKE_subdiv_stats_end(SubdivStats *stats, eSubdivStatsValue value)
Definition: subdiv_stats.c:31
void BKE_subdiv_stats_begin(SubdivStats *stats, eSubdivStatsValue value)
Definition: subdiv_stats.c:26
@ SUBDIV_EVALUATOR_TYPE_CPU
void BKE_subdiv_eval_vertex_data(struct Subdiv *subdiv, const int ptex_face_index, const float u, const float v, float r_vertex_data[])
Definition: subdiv_eval.c:333
void BKE_subdiv_eval_displacement(struct Subdiv *subdiv, int ptex_face_index, float u, float v, const float dPdu[3], const float dPdv[3], float r_D[3])
Definition: subdiv_eval.c:350
void BKE_subdiv_eval_final_point(struct Subdiv *subdiv, int ptex_face_index, float u, float v, float r_P[3])
Definition: subdiv_eval.c:366
void BKE_subdiv_eval_limit_point(struct Subdiv *subdiv, int ptex_face_index, float u, float v, float r_P[3])
Definition: subdiv_eval.c:280
void BKE_subdiv_eval_face_varying(struct Subdiv *subdiv, int face_varying_channel, int ptex_face_index, float u, float v, float r_face_varying[2])
Definition: subdiv_eval.c:339
bool BKE_subdiv_eval_begin_from_mesh(struct Subdiv *subdiv, const struct Mesh *mesh, const float(*coarse_vertex_cos)[3], eSubdivEvaluatorType evaluator_type, struct OpenSubdiv_EvaluatorCache *evaluator_cache)
void BKE_subdiv_eval_limit_point_and_derivatives(struct Subdiv *subdiv, int ptex_face_index, float u, float v, float r_P[3], float r_dPdu[3], float r_dPdv[3])
Definition: subdiv_eval.c:286
bool BKE_subdiv_foreach_subdiv_geometry(struct Subdiv *subdiv, const struct SubdivForeachContext *context, const struct SubdivToMeshSettings *mesh_settings, const struct Mesh *coarse_mesh)
#define BLI_array_alloca(arr, realsize)
Definition: BLI_alloca.h:22
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define BLI_BITMAP_NEW(_num, _alloc_string)
Definition: BLI_bitmap.h:40
#define BLI_BITMAP_ENABLE(_bitmap, _index)
Definition: BLI_bitmap.h:81
#define BLI_BITMAP_DISABLE(_bitmap, _index)
Definition: BLI_bitmap.h:88
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
void interp_v3_v3v3(float r[3], const float a[3], const float b[3], float t)
Definition: math_vector.c:29
void interp_v3_v3v3v3v3(float p[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3], const float w[4])
Definition: math_vector.c:168
MINLINE void add_v3_v3(float r[3], const float a[3])
#define UNUSED(x)
#define ELEM(...)
@ CD_ORIGINDEX
@ CD_CLOTH_ORCO
@ CD_MLOOPUV
#define CD_MASK_MULTIRES_GRIDS
#define MAX_MTFACE
@ KEY_BSPLINE
@ ME_EDGERENDER
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble v1
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
Provides wrapper around system-specific atomic primitives, and some extensions (faked-atomic operatio...
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert * v
ccl_gpu_kernel_postfix int ccl_global int * indices
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:32
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
Definition: math_float4.h:513
const CustomData * loop_data
Definition: subdiv_mesh.c:282
CustomData loop_data_storage
Definition: subdiv_mesh.c:292
const MLoop * third_loop
Definition: subdiv_mesh.c:105
const MLoop * second_loop
Definition: subdiv_mesh.c:104
const MLoop * last_loop
Definition: subdiv_mesh.c:102
const MLoop * first_loop
Definition: subdiv_mesh.c:100
unsigned int v1
unsigned int v2
unsigned int e
unsigned int v
float co[3]
uint32_t * subsurf_face_dot_tags
struct MEdge * medge
CustomData vdata
struct MVert * mvert
int totedge
struct MLoop * mloop
Mesh_Runtime runtime
CustomData pdata
int totpoly
CustomData edata
struct MPoly * mpoly
CustomData ldata
SubdivForeachVertexFromEdgeCb vertex_every_edge
SubdivForeachPolygonCb poly
SubdivForeachTopologyInformationCb topology_info
SubdivForeachLooseCb vertex_loose
SubdivForeachVertexInnerCb vertex_inner
SubdivForeachVertexOfLooseEdgeCb vertex_of_loose_edge
SubdivForeachEdgeCb edge
void(* user_data_tls_free)(void *tls)
SubdivForeachVertexFromEdgeCb vertex_edge
SubdivForeachVertexFromCornerCb vertex_corner
SubdivForeachVertexFromCornerCb vertex_every_corner
SubdivForeachLoopCb loop
const Mesh * coarse_mesh
Definition: subdiv_mesh.c:34
int * accumulated_counters
Definition: subdiv_mesh.c:49
const SubdivToMeshSettings * settings
Definition: subdiv_mesh.c:33
MLoopUV * uv_layers[MAX_MTFACE]
Definition: subdiv_mesh.c:44
float(* cloth_orco)[3]
Definition: subdiv_mesh.c:47
float(* orco)[3]
Definition: subdiv_mesh.c:46
const MPoly * loop_interpolation_coarse_poly
Definition: subdiv_mesh.c:406
VerticesForInterpolation vertex_interpolation
Definition: subdiv_mesh.c:400
int loop_interpolation_coarse_corner
Definition: subdiv_mesh.c:407
bool loop_interpolation_initialized
Definition: subdiv_mesh.c:404
bool vertex_interpolation_initialized
Definition: subdiv_mesh.c:399
const MPoly * vertex_interpolation_coarse_poly
Definition: subdiv_mesh.c:401
int vertex_interpolation_coarse_corner
Definition: subdiv_mesh.c:402
LoopsForInterpolation loop_interpolation
Definition: subdiv_mesh.c:405
SubdivSettings settings
Definition: BKE_subdiv.h:160
SubdivStats stats
Definition: BKE_subdiv.h:170
struct SubdivDisplacement * displacement_evaluator
Definition: BKE_subdiv.h:168
CustomData vertex_data_storage
Definition: subdiv_mesh.c:157
const CustomData * vertex_data
Definition: subdiv_mesh.c:147
static void points_for_loose_edges_interpolation_get(const Mesh *coarse_mesh, const MEdge *coarse_edge, const MEdge *neighbors[2], float points_r[4][3])
Definition: subdiv_mesh.c:1006
static void subdiv_vertex_data_interpolate(const SubdivMeshContext *ctx, MVert *subdiv_vertex, const VerticesForInterpolation *vertex_interpolation, const float u, const float v)
Definition: subdiv_mesh.c:524
static void subdiv_mesh_loop(const SubdivForeachContext *foreach_context, void *tls_v, const int ptex_face_index, const float u, const float v, const int UNUSED(coarse_loop_index), const int coarse_poly_index, const int coarse_corner, const int subdiv_loop_index, const int subdiv_vertex_index, const int subdiv_edge_index)
Definition: subdiv_mesh.c:886
static void loop_interpolation_init(const SubdivMeshContext *ctx, LoopsForInterpolation *loop_interpolation, const MPoly *coarse_poly)
Definition: subdiv_mesh.c:299
static void subdiv_mesh_vertex_corner(const SubdivForeachContext *foreach_context, void *UNUSED(tls), const int ptex_face_index, const float u, const float v, const int coarse_vertex_index, const int UNUSED(coarse_poly_index), const int UNUSED(coarse_corner), const int subdiv_vertex_index)
Definition: subdiv_mesh.c:641
static void evaluate_vertex_and_apply_displacement_copy(const SubdivMeshContext *ctx, const int ptex_face_index, const float u, const float v, const MVert *coarse_vert, MVert *subdiv_vert)
Definition: subdiv_mesh.c:544
static void subdiv_mesh_vertex_displacement_every_edge(const SubdivForeachContext *foreach_context, void *tls, const int ptex_face_index, const float u, const float v, const int UNUSED(coarse_edge_index), const int UNUSED(coarse_poly_index), const int UNUSED(coarse_corner), const int subdiv_vertex_index)
Definition: subdiv_mesh.c:627
struct SubdivMeshTLS SubdivMeshTLS
static void subdiv_mesh_tag_center_vertex(const MPoly *coarse_poly, const int subdiv_vertex_index, const float u, const float v, Mesh *subdiv_mesh)
Definition: subdiv_mesh.c:729
static void subdiv_mesh_vertex_of_loose_edge(const struct SubdivForeachContext *foreach_context, void *UNUSED(tls), const int coarse_edge_index, const float u, const int subdiv_vertex_index)
Definition: subdiv_mesh.c:1091
static void loops_of_ptex_get(const SubdivMeshContext *ctx, LoopsOfPtex *loops_of_ptex, const MPoly *coarse_poly, const int ptex_of_poly_index)
Definition: subdiv_mesh.c:108
static void vertex_interpolation_from_corner(const SubdivMeshContext *ctx, VerticesForInterpolation *vertex_interpolation, const MPoly *coarse_poly, const int corner)
Definition: subdiv_mesh.c:211
struct VerticesForInterpolation VerticesForInterpolation
static void subdiv_copy_poly_data(const SubdivMeshContext *ctx, MPoly *subdiv_poly, const MPoly *coarse_poly)
Definition: subdiv_mesh.c:919
void BKE_subdiv_mesh_interpolate_position_on_edge(const Mesh *coarse_mesh, const MEdge *coarse_edge, const bool is_simple, const float u, float pos_r[3])
Definition: subdiv_mesh.c:1043
static void subdiv_mesh_context_free(SubdivMeshContext *ctx)
Definition: subdiv_mesh.c:87
static bool subdiv_mesh_is_center_vertex(const MPoly *coarse_poly, const float u, const float v)
Definition: subdiv_mesh.c:714
static void loop_interpolation_end(LoopsForInterpolation *loop_interpolation)
Definition: subdiv_mesh.c:385
struct LoopsOfPtex LoopsOfPtex
static bool subdiv_mesh_topology_info(const SubdivForeachContext *foreach_context, const int num_vertices, const int num_edges, const int num_loops, const int num_polygons, const int *UNUSED(subdiv_polygon_offset))
Definition: subdiv_mesh.c:483
static void subdiv_interpolate_loop_data(const SubdivMeshContext *ctx, MLoop *subdiv_loop, const LoopsForInterpolation *loop_interpolation, const float u, const float v)
Definition: subdiv_mesh.c:823
static void setup_foreach_callbacks(const SubdivMeshContext *subdiv_context, SubdivForeachContext *foreach_context)
Definition: subdiv_mesh.c:1125
static void subdiv_mesh_ensure_vertex_interpolation(SubdivMeshContext *ctx, SubdivMeshTLS *tls, const MPoly *coarse_poly, const int coarse_corner)
Definition: subdiv_mesh.c:663
static void subdiv_mesh_tls_free(void *tls_v)
Definition: subdiv_mesh.c:410
static void subdiv_vertex_data_copy(const SubdivMeshContext *ctx, const MVert *coarse_vertex, MVert *subdiv_vertex)
Definition: subdiv_mesh.c:512
static void subdiv_accumulate_vertex_displacement(SubdivMeshContext *ctx, const int ptex_face_index, const float u, const float v, MVert *subdiv_vert)
Definition: subdiv_mesh.c:455
static void subdiv_eval_uv_layer(SubdivMeshContext *ctx, MLoop *subdiv_loop, const int ptex_face_index, const float u, const float v)
Definition: subdiv_mesh.c:841
static void subdiv_mesh_vertex_of_loose_edge_interpolate(SubdivMeshContext *ctx, const MEdge *coarse_edge, const float u, const int subdiv_vertex_index)
Definition: subdiv_mesh.c:1067
static void subdiv_mesh_ctx_cache_custom_data_layers(SubdivMeshContext *ctx)
Definition: subdiv_mesh.c:63
static void subdiv_mesh_vertex_displacement_every_corner(const SubdivForeachContext *foreach_context, void *tls, const int ptex_face_index, const float u, const float v, const int UNUSED(coarse_vertex_index), const int UNUSED(coarse_poly_index), const int UNUSED(coarse_corner), const int subdiv_vertex_index)
Definition: subdiv_mesh.c:612
static void vertex_interpolation_end(VerticesForInterpolation *vertex_interpolation)
Definition: subdiv_mesh.c:265
static void evaluate_vertex_and_apply_displacement_interpolate(const SubdivMeshContext *ctx, const int ptex_face_index, const float u, const float v, VerticesForInterpolation *vertex_interpolation, MVert *subdiv_vert)
Definition: subdiv_mesh.c:571
static void subdiv_mesh_poly(const SubdivForeachContext *foreach_context, void *UNUSED(tls), const int coarse_poly_index, const int subdiv_poly_index, const int start_loop_index, const int num_loops)
Definition: subdiv_mesh.c:929
struct SubdivMeshContext SubdivMeshContext
static void subdiv_mesh_vertex_inner(const SubdivForeachContext *foreach_context, void *tls_v, const int ptex_face_index, const float u, const float v, const int coarse_poly_index, const int coarse_corner, const int subdiv_vertex_index)
Definition: subdiv_mesh.c:740
static void subdiv_copy_edge_data(SubdivMeshContext *ctx, MEdge *subdiv_edge, const MEdge *coarse_edge)
Definition: subdiv_mesh.c:771
static void subdiv_mesh_vertex_edge(const SubdivForeachContext *foreach_context, void *tls_v, const int ptex_face_index, const float u, const float v, const int UNUSED(coarse_edge_index), const int coarse_poly_index, const int coarse_corner, const int subdiv_vertex_index)
Definition: subdiv_mesh.c:691
static void vertex_interpolation_init(const SubdivMeshContext *ctx, VerticesForInterpolation *vertex_interpolation, const MPoly *coarse_poly)
Definition: subdiv_mesh.c:164
Mesh * BKE_subdiv_to_mesh(Subdiv *subdiv, const SubdivToMeshSettings *settings, const Mesh *coarse_mesh)
Definition: subdiv_mesh.c:1153
static void subdiv_mesh_vertex_displacement_every_corner_or_edge(const SubdivForeachContext *foreach_context, void *UNUSED(tls), const int ptex_face_index, const float u, const float v, const int subdiv_vertex_index)
Definition: subdiv_mesh.c:597
static void subdiv_mesh_edge(const SubdivForeachContext *foreach_context, void *UNUSED(tls), const int coarse_edge_index, const int subdiv_edge_index, const bool UNUSED(is_loose), const int subdiv_v1, const int subdiv_v2)
Definition: subdiv_mesh.c:794
static void loop_interpolation_from_corner(const SubdivMeshContext *ctx, LoopsForInterpolation *loop_interpolation, const MPoly *coarse_poly, const int corner)
Definition: subdiv_mesh.c:345
struct LoopsForInterpolation LoopsForInterpolation
static void subdiv_mesh_ctx_cache_uv_layers(SubdivMeshContext *ctx)
Definition: subdiv_mesh.c:53
static void subdiv_vertex_orco_evaluate(const SubdivMeshContext *ctx, const int ptex_face_index, const float u, const float v, const int subdiv_vertex_index)
Definition: subdiv_mesh.c:427
static void subdiv_mesh_vertex_loose(const SubdivForeachContext *foreach_context, void *UNUSED(tls), const int coarse_vertex_index, const int subdiv_vertex_index)
Definition: subdiv_mesh.c:955
static void subdiv_mesh_ensure_loop_interpolation(SubdivMeshContext *ctx, SubdivMeshTLS *tls, const MPoly *coarse_poly, const int coarse_corner)
Definition: subdiv_mesh.c:858
static void subdiv_mesh_prepare_accumulator(SubdivMeshContext *ctx, int num_vertices)
Definition: subdiv_mesh.c:78
static void find_edge_neighbors(const Mesh *coarse_mesh, const MEdge *edge, const MEdge *neighbors[2])
Definition: subdiv_mesh.c:973
BLI_INLINE float D(const float *data, const int res[3], int x, int y, int z)
Definition: voxel.c:13