Blender  V2.93
shrinkwrap.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include <float.h>
25 #include <math.h>
26 #include <memory.h>
27 #include <stdio.h>
28 #include <string.h>
29 #include <time.h>
30 
31 #include "DNA_mesh_types.h"
32 #include "DNA_meshdata_types.h"
33 #include "DNA_modifier_types.h"
34 #include "DNA_object_types.h"
35 
36 #include "BLI_math.h"
37 #include "BLI_math_solvers.h"
38 #include "BLI_task.h"
39 #include "BLI_utildefines.h"
40 
41 #include "BKE_DerivedMesh.h"
42 #include "BKE_cdderivedmesh.h"
43 #include "BKE_context.h"
44 #include "BKE_lattice.h"
45 #include "BKE_lib_id.h"
46 #include "BKE_modifier.h"
47 #include "BKE_shrinkwrap.h"
48 
49 #include "BKE_deform.h"
50 #include "BKE_editmesh.h"
51 #include "BKE_mesh.h" /* for OMP limits. */
52 #include "BKE_mesh_runtime.h"
53 #include "BKE_mesh_wrapper.h"
54 #include "BKE_subsurf.h"
55 
56 #include "DEG_depsgraph_query.h"
57 
58 #include "MEM_guardedalloc.h"
59 
60 #include "BLI_strict_flags.h"
61 
62 /* for timing... */
63 #if 0
64 # include "PIL_time_utildefines.h"
65 #else
66 # define TIMEIT_BENCH(expr, id) (expr)
67 #endif
68 
69 /* Util macros */
70 #define OUT_OF_MEMORY() ((void)printf("Shrinkwrap: Out of memory\n"))
71 
72 typedef struct ShrinkwrapCalcData {
73  ShrinkwrapModifierData *smd; /* shrinkwrap modifier data */
74 
75  struct Object *ob; /* object we are applying shrinkwrap to */
76 
77  struct MVert *vert; /* Array of verts being projected (to fetch normals or other data) */
78  float (*vertexCos)[3]; /* vertexs being shrinkwraped */
79  int numVerts;
80 
81  struct MDeformVert *dvert; /* Pointer to mdeform array */
82  int vgroup; /* Vertex group num */
83  bool invert_vgroup; /* invert vertex group influence */
84 
85  struct Mesh *target; /* mesh we are shrinking to */
86  struct SpaceTransform local2target; /* transform to move between local and target space */
87  struct ShrinkwrapTreeData *tree; /* mesh BVH tree data */
88 
89  struct Object *aux_target;
90 
91  float keepDist; /* Distance to keep above target surface (units are in local space) */
93 
94 typedef struct ShrinkwrapCalcCBData {
96 
99 
100  float *proj_axis;
103 
104 /* Checks if the modifier needs target normals with these settings. */
105 bool BKE_shrinkwrap_needs_normals(int shrinkType, int shrinkMode)
106 {
107  return (shrinkType == MOD_SHRINKWRAP_TARGET_PROJECT) ||
108  (shrinkType != MOD_SHRINKWRAP_NEAREST_VERTEX &&
109  shrinkMode == MOD_SHRINKWRAP_ABOVE_SURFACE);
110 }
111 
112 /* Initializes the mesh data structure from the given mesh and settings. */
114  ShrinkwrapTreeData *data, Mesh *mesh, int shrinkType, int shrinkMode, bool force_normals)
115 {
116  memset(data, 0, sizeof(*data));
117 
118  if (mesh == NULL) {
119  return false;
120  }
121 
122  /* We could create a BVH tree from the edit mesh,
123  * however accessing normals from the face/loop normals gets more involved.
124  * Convert mesh data since this isn't typically used in edit-mode. */
126 
127  if (mesh->totvert <= 0) {
128  return false;
129  }
130 
131  data->mesh = mesh;
132 
133  if (shrinkType == MOD_SHRINKWRAP_NEAREST_VERTEX) {
135 
136  return data->bvh != NULL;
137  }
138 
139  if (mesh->totpoly <= 0) {
140  return false;
141  }
142 
144 
145  if (data->bvh == NULL) {
146  return false;
147  }
148 
149  if (force_normals || BKE_shrinkwrap_needs_normals(shrinkType, shrinkMode)) {
150  data->pnors = CustomData_get_layer(&mesh->pdata, CD_NORMAL);
151  if ((mesh->flag & ME_AUTOSMOOTH) != 0) {
153  }
154  }
155 
156  if (shrinkType == MOD_SHRINKWRAP_TARGET_PROJECT) {
157  data->boundary = mesh->runtime.shrinkwrap_data;
158  }
159 
160  return true;
161 }
162 
163 /* Frees the tree data if necessary. */
165 {
166  free_bvhtree_from_mesh(&data->treeData);
167 }
168 
169 /* Free boundary data for target project */
171 {
173 
174  if (data != NULL) {
175  MEM_freeN((void *)data->edge_is_boundary);
176  MEM_freeN((void *)data->looptri_has_boundary);
177  MEM_freeN((void *)data->vert_boundary_id);
178  MEM_freeN((void *)data->boundary_verts);
179 
180  MEM_freeN(data);
181  }
182 
184 }
185 
186 /* Accumulate edge for average boundary edge direction. */
188  signed char *status,
189  int index,
190  const float edge_dir[3],
191  signed char side)
192 {
193  BLI_assert(index >= 0);
194  float *direction = vdata[index].direction;
195 
196  /* Invert the direction vector if either:
197  * - This is the second edge and both edges have the vertex as start or end.
198  * - For third and above, if it points in the wrong direction.
199  */
200  if (status[index] >= 0 ? status[index] == side : dot_v3v3(direction, edge_dir) < 0) {
201  sub_v3_v3(direction, edge_dir);
202  }
203  else {
204  add_v3_v3(direction, edge_dir);
205  }
206 
207  status[index] = (status[index] == 0) ? side : -1;
208 }
209 
211 {
212  const MLoop *mloop = mesh->mloop;
213  const MEdge *medge = mesh->medge;
214  const MVert *mvert = mesh->mvert;
215 
216  /* Count faces per edge (up to 2). */
217  char *edge_mode = MEM_calloc_arrayN((size_t)mesh->totedge, sizeof(char), __func__);
218 
219  for (int i = 0; i < mesh->totloop; i++) {
220  unsigned int eidx = mloop[i].e;
221 
222  if (edge_mode[eidx] < 2) {
223  edge_mode[eidx]++;
224  }
225  }
226 
227  /* Build the boundary edge bitmask. */
229  "ShrinkwrapBoundaryData::edge_is_boundary");
230  unsigned int num_boundary_edges = 0;
231 
232  for (int i = 0; i < mesh->totedge; i++) {
233  edge_mode[i] = (edge_mode[i] == 1);
234 
235  if (edge_mode[i]) {
237  num_boundary_edges++;
238  }
239  }
240 
241  /* If no boundary, return NULL. */
242  if (num_boundary_edges == 0) {
244  MEM_freeN(edge_mode);
245  return NULL;
246  }
247 
248  /* Allocate the data object. */
250  "ShrinkwrapBoundaryData");
251 
252  data->edge_is_boundary = edge_is_boundary;
253 
254  /* Build the boundary looptri bitmask. */
255  const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(mesh);
256  int totlooptri = BKE_mesh_runtime_looptri_len(mesh);
257 
259  "ShrinkwrapBoundaryData::looptri_is_boundary");
260 
261  for (int i = 0; i < totlooptri; i++) {
262  int edges[3];
263  BKE_mesh_looptri_get_real_edges(mesh, &mlooptri[i], edges);
264 
265  for (int j = 0; j < 3; j++) {
266  if (edges[j] >= 0 && edge_mode[edges[j]]) {
268  break;
269  }
270  }
271  }
272 
273  data->looptri_has_boundary = looptri_has_boundary;
274 
275  /* Find boundary vertices and build a mapping table for compact storage of data. */
277  (size_t)mesh->totvert, sizeof(int), "ShrinkwrapBoundaryData::vert_boundary_id");
278 
279  for (int i = 0; i < mesh->totedge; i++) {
280  if (edge_mode[i]) {
281  const MEdge *edge = &medge[i];
282 
283  vert_boundary_id[edge->v1] = 1;
284  vert_boundary_id[edge->v2] = 1;
285  }
286  }
287 
288  unsigned int num_boundary_verts = 0;
289 
290  for (int i = 0; i < mesh->totvert; i++) {
291  vert_boundary_id[i] = (vert_boundary_id[i] != 0) ? (int)num_boundary_verts++ : -1;
292  }
293 
294  data->vert_boundary_id = vert_boundary_id;
295  data->num_boundary_verts = num_boundary_verts;
296 
297  /* Compute average directions. */
299  num_boundary_verts, sizeof(*boundary_verts), "ShrinkwrapBoundaryData::boundary_verts");
300 
301  signed char *vert_status = MEM_calloc_arrayN(num_boundary_verts, sizeof(char), __func__);
302 
303  for (int i = 0; i < mesh->totedge; i++) {
304  if (edge_mode[i]) {
305  const MEdge *edge = &medge[i];
306 
307  float dir[3];
308  sub_v3_v3v3(dir, mvert[edge->v2].co, mvert[edge->v1].co);
309  normalize_v3(dir);
310 
311  merge_vert_dir(boundary_verts, vert_status, vert_boundary_id[edge->v1], dir, 1);
312  merge_vert_dir(boundary_verts, vert_status, vert_boundary_id[edge->v2], dir, 2);
313  }
314  }
315 
316  MEM_freeN(vert_status);
317 
318  /* Finalize average direction and compute normal. */
319  for (int i = 0; i < mesh->totvert; i++) {
320  int bidx = vert_boundary_id[i];
321 
322  if (bidx >= 0) {
324  float no[3], tmp[3];
325 
326  normalize_v3(vdata->direction);
327 
329  cross_v3_v3v3(tmp, no, vdata->direction);
330  cross_v3_v3v3(vdata->normal_plane, tmp, no);
331  normalize_v3(vdata->normal_plane);
332  }
333  }
334 
335  data->boundary_verts = boundary_verts;
336 
337  MEM_freeN(edge_mode);
338  return data;
339 }
340 
342 {
344 
346 }
347 
354 static void shrinkwrap_calc_nearest_vertex_cb_ex(void *__restrict userdata,
355  const int i,
356  const TaskParallelTLS *__restrict tls)
357 {
358  ShrinkwrapCalcCBData *data = userdata;
359 
360  ShrinkwrapCalcData *calc = data->calc;
361  BVHTreeFromMesh *treeData = &data->tree->treeData;
362  BVHTreeNearest *nearest = tls->userdata_chunk;
363 
364  float *co = calc->vertexCos[i];
365  float tmp_co[3];
366  float weight = BKE_defvert_array_find_weight_safe(calc->dvert, i, calc->vgroup);
367 
368  if (calc->invert_vgroup) {
369  weight = 1.0f - weight;
370  }
371 
372  if (weight == 0.0f) {
373  return;
374  }
375 
376  /* Convert the vertex to tree coordinates */
377  if (calc->vert) {
378  copy_v3_v3(tmp_co, calc->vert[i].co);
379  }
380  else {
381  copy_v3_v3(tmp_co, co);
382  }
383  BLI_space_transform_apply(&calc->local2target, tmp_co);
384 
385  /* Use local proximity heuristics (to reduce the nearest search)
386  *
387  * If we already had an hit before.. we assume this vertex is going to have a close hit to that
388  * other vertex so we can initiate the "nearest.dist" with the expected value to that last hit.
389  * This will lead in pruning of the search tree. */
390  if (nearest->index != -1) {
391  nearest->dist_sq = len_squared_v3v3(tmp_co, nearest->co);
392  }
393  else {
394  nearest->dist_sq = FLT_MAX;
395  }
396 
397  BLI_bvhtree_find_nearest(treeData->tree, tmp_co, nearest, treeData->nearest_callback, treeData);
398 
399  /* Found the nearest vertex */
400  if (nearest->index != -1) {
401  /* Adjusting the vertex weight,
402  * so that after interpolating it keeps a certain distance from the nearest position */
403  if (nearest->dist_sq > FLT_EPSILON) {
404  const float dist = sqrtf(nearest->dist_sq);
405  weight *= (dist - calc->keepDist) / dist;
406  }
407 
408  /* Convert the coordinates back to mesh coordinates */
409  copy_v3_v3(tmp_co, nearest->co);
411 
412  interp_v3_v3v3(co, co, tmp_co, weight); /* linear interpolation */
413  }
414 }
415 
417 {
419 
420  /* Setup nearest */
421  nearest.index = -1;
422  nearest.dist_sq = FLT_MAX;
423 
425  .calc = calc,
426  .tree = calc->tree,
427  };
428  TaskParallelSettings settings;
430  settings.use_threading = (calc->numVerts > BKE_MESH_OMP_LIMIT);
431  settings.userdata_chunk = &nearest;
432  settings.userdata_chunk_size = sizeof(nearest);
434  0, calc->numVerts, &data, shrinkwrap_calc_nearest_vertex_cb_ex, &settings);
435 }
436 
437 /*
438  * This function raycast a single vertex and updates the hit if the "hit" is considered valid.
439  * Returns true if "hit" was updated.
440  * Opts control whether an hit is valid or not
441  * Supported options are:
442  * - MOD_SHRINKWRAP_CULL_TARGET_FRONTFACE (front faces hits are ignored)
443  * - MOD_SHRINKWRAP_CULL_TARGET_BACKFACE (back faces hits are ignored)
444  */
446  const float vert[3],
447  const float dir[3],
448  const float ray_radius,
449  const SpaceTransform *transf,
451  BVHTreeRayHit *hit)
452 {
453  /* don't use this because this dist value could be incompatible
454  * this value used by the callback for comparing previous/new dist values.
455  * also, at the moment there is no need to have a corrected 'dist' value */
456  // #define USE_DIST_CORRECT
457 
458  float tmp_co[3], tmp_no[3];
459  const float *co, *no;
460  BVHTreeRayHit hit_tmp;
461 
462  /* Copy from hit (we need to convert hit rays from one space coordinates to the other */
463  memcpy(&hit_tmp, hit, sizeof(hit_tmp));
464 
465  /* Apply space transform (TODO readjust dist) */
466  if (transf) {
467  copy_v3_v3(tmp_co, vert);
468  BLI_space_transform_apply(transf, tmp_co);
469  co = tmp_co;
470 
471  copy_v3_v3(tmp_no, dir);
472  BLI_space_transform_apply_normal(transf, tmp_no);
473  no = tmp_no;
474 
475 #ifdef USE_DIST_CORRECT
476  hit_tmp.dist *= mat4_to_scale(((SpaceTransform *)transf)->local2target);
477 #endif
478  }
479  else {
480  co = vert;
481  no = dir;
482  }
483 
484  hit_tmp.index = -1;
485 
487  tree->bvh, co, no, ray_radius, &hit_tmp, tree->treeData.raycast_callback, &tree->treeData);
488 
489  if (hit_tmp.index != -1) {
490  /* invert the normal first so face culling works on rotated objects */
491  if (transf) {
492  BLI_space_transform_invert_normal(transf, hit_tmp.no);
493  }
494 
496  /* apply backface */
497  const float dot = dot_v3v3(dir, hit_tmp.no);
498  if (((options & MOD_SHRINKWRAP_CULL_TARGET_FRONTFACE) && dot <= 0.0f) ||
500  return false; /* Ignore hit */
501  }
502  }
503 
504  if (transf) {
505  /* Inverting space transform (TODO make coeherent with the initial dist readjust) */
506  BLI_space_transform_invert(transf, hit_tmp.co);
507 #ifdef USE_DIST_CORRECT
508  hit_tmp.dist = len_v3v3(vert, hit_tmp.co);
509 #endif
510  }
511 
512  BLI_assert(hit_tmp.dist <= hit->dist);
513 
514  memcpy(hit, &hit_tmp, sizeof(hit_tmp));
515  return true;
516  }
517  return false;
518 }
519 
520 static void shrinkwrap_calc_normal_projection_cb_ex(void *__restrict userdata,
521  const int i,
522  const TaskParallelTLS *__restrict tls)
523 {
524  ShrinkwrapCalcCBData *data = userdata;
525 
526  ShrinkwrapCalcData *calc = data->calc;
527  ShrinkwrapTreeData *tree = data->tree;
528  ShrinkwrapTreeData *aux_tree = data->aux_tree;
529 
530  float *proj_axis = data->proj_axis;
531  SpaceTransform *local2aux = data->local2aux;
532 
533  BVHTreeRayHit *hit = tls->userdata_chunk;
534 
535  const float proj_limit_squared = calc->smd->projLimit * calc->smd->projLimit;
536  float *co = calc->vertexCos[i];
537  float tmp_co[3], tmp_no[3];
538  float weight = BKE_defvert_array_find_weight_safe(calc->dvert, i, calc->vgroup);
539 
540  if (calc->invert_vgroup) {
541  weight = 1.0f - weight;
542  }
543 
544  if (weight == 0.0f) {
545  return;
546  }
547 
548  if (calc->vert != NULL && calc->smd->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL) {
549  /* calc->vert contains verts from evaluated mesh. */
550  /* These coordinates are deformed by vertexCos only for normal projection
551  * (to get correct normals) for other cases calc->verts contains undeformed coordinates and
552  * vertexCos should be used */
553  copy_v3_v3(tmp_co, calc->vert[i].co);
554  normal_short_to_float_v3(tmp_no, calc->vert[i].no);
555  }
556  else {
557  copy_v3_v3(tmp_co, co);
558  copy_v3_v3(tmp_no, proj_axis);
559  }
560 
561  hit->index = -1;
562 
563  /* TODO: we should use FLT_MAX here, but sweepsphere code isn't prepared for that */
564  hit->dist = BVH_RAYCAST_DIST_MAX;
565 
566  bool is_aux = false;
567 
568  /* Project over positive direction of axis */
570  if (aux_tree) {
571  if (BKE_shrinkwrap_project_normal(0, tmp_co, tmp_no, 0.0, local2aux, aux_tree, hit)) {
572  is_aux = true;
573  }
574  }
575 
577  calc->smd->shrinkOpts, tmp_co, tmp_no, 0.0, &calc->local2target, tree, hit)) {
578  is_aux = false;
579  }
580  }
581 
582  /* Project over negative direction of axis */
584  float inv_no[3];
585  negate_v3_v3(inv_no, tmp_no);
586 
587  char options = calc->smd->shrinkOpts;
588 
592  }
593 
594  if (aux_tree) {
595  if (BKE_shrinkwrap_project_normal(0, tmp_co, inv_no, 0.0, local2aux, aux_tree, hit)) {
596  is_aux = true;
597  }
598  }
599 
601  options, tmp_co, inv_no, 0.0, &calc->local2target, tree, hit)) {
602  is_aux = false;
603  }
604  }
605 
606  /* don't set the initial dist (which is more efficient),
607  * because its calculated in the targets space, we want the dist in our own space */
608  if (proj_limit_squared != 0.0f) {
609  if (hit->index != -1 && len_squared_v3v3(hit->co, co) > proj_limit_squared) {
610  hit->index = -1;
611  }
612  }
613 
614  if (hit->index != -1) {
615  if (is_aux) {
617  local2aux,
618  calc->smd->shrinkMode,
619  hit->index,
620  hit->co,
621  hit->no,
622  calc->keepDist,
623  tmp_co,
624  hit->co);
625  }
626  else {
628  &calc->local2target,
629  calc->smd->shrinkMode,
630  hit->index,
631  hit->co,
632  hit->no,
633  calc->keepDist,
634  tmp_co,
635  hit->co);
636  }
637 
638  interp_v3_v3v3(co, co, hit->co, weight);
639  }
640 }
641 
643 {
644  /* Options about projection direction */
645  float proj_axis[3] = {0.0f, 0.0f, 0.0f};
646 
647  /* Raycast and tree stuff */
648 
652  BVHTreeRayHit hit;
653 
654  /* auxiliary target */
655  Mesh *auxMesh = NULL;
656  ShrinkwrapTreeData *aux_tree = NULL;
657  ShrinkwrapTreeData aux_tree_stack;
658  SpaceTransform local2aux;
659 
660  /* If the user doesn't allows to project in any direction of projection axis
661  * then there's nothing todo. */
662  if ((calc->smd->shrinkOpts &
664  return;
665  }
666 
667  /* Prepare data to retrieve the direction in which we should project each vertex */
669  if (calc->vert == NULL) {
670  return;
671  }
672  }
673  else {
674  /* The code supports any axis that is a combination of X,Y,Z
675  * although currently UI only allows to set the 3 different axis */
677  proj_axis[0] = 1.0f;
678  }
680  proj_axis[1] = 1.0f;
681  }
683  proj_axis[2] = 1.0f;
684  }
685 
686  normalize_v3(proj_axis);
687 
688  /* Invalid projection direction */
689  if (len_squared_v3(proj_axis) < FLT_EPSILON) {
690  return;
691  }
692  }
693 
694  if (calc->aux_target) {
696  if (!auxMesh) {
697  return;
698  }
699  BLI_SPACE_TRANSFORM_SETUP(&local2aux, calc->ob, calc->aux_target);
700  }
701 
703  &aux_tree_stack, auxMesh, calc->smd->shrinkType, calc->smd->shrinkMode, false)) {
704  aux_tree = &aux_tree_stack;
705  }
706 
707  /* After successfully build the trees, start projection vertices. */
709  .calc = calc,
710  .tree = calc->tree,
711  .aux_tree = aux_tree,
712  .proj_axis = proj_axis,
713  .local2aux = &local2aux,
714  };
715  TaskParallelSettings settings;
717  settings.use_threading = (calc->numVerts > BKE_MESH_OMP_LIMIT);
718  settings.userdata_chunk = &hit;
719  settings.userdata_chunk_size = sizeof(hit);
721  0, calc->numVerts, &data, shrinkwrap_calc_normal_projection_cb_ex, &settings);
722 
723  /* free data structures */
724  if (aux_tree) {
725  BKE_shrinkwrap_free_tree(aux_tree);
726  }
727 }
728 
729 /*
730  * Shrinkwrap Target Surface Project mode
731  *
732  * It uses Newton's method to find a surface location with its
733  * smooth normal pointing at the original point.
734  *
735  * The equation system on barycentric weights and normal multiplier:
736  *
737  * (w0*V0 + w1*V1 + w2*V2) + l * (w0*N0 + w1*N1 + w2*N2) - CO = 0
738  * w0 + w1 + w2 = 1
739  *
740  * The actual solution vector is [ w0, w1, l ], with w2 eliminated.
741  */
742 
743 //#define TRACE_TARGET_PROJECT
744 
745 typedef struct TargetProjectTriData {
746  const float **vtri_co;
747  const float (*vtri_no)[3];
748  const float *point_co;
749 
750  float n0_minus_n2[3], n1_minus_n2[3];
751  float c0_minus_c2[3], c1_minus_c2[3];
752 
753  /* Current interpolated position and normal. */
754  float co_interp[3], no_interp[3];
756 
757 /* Computes the deviation of the equation system from goal. */
758 static void target_project_tri_deviation(void *userdata, const float x[3], float r_delta[3])
759 {
760  TargetProjectTriData *data = userdata;
761 
762  const float w[3] = {x[0], x[1], 1.0f - x[0] - x[1]};
763  interp_v3_v3v3v3(data->co_interp, data->vtri_co[0], data->vtri_co[1], data->vtri_co[2], w);
764  interp_v3_v3v3v3(data->no_interp, data->vtri_no[0], data->vtri_no[1], data->vtri_no[2], w);
765 
766  madd_v3_v3v3fl(r_delta, data->co_interp, data->no_interp, x[2]);
767  sub_v3_v3(r_delta, data->point_co);
768 }
769 
770 /* Computes the Jacobian matrix of the equation system. */
771 static void target_project_tri_jacobian(void *userdata, const float x[3], float r_jacobian[3][3])
772 {
773  TargetProjectTriData *data = userdata;
774 
775  madd_v3_v3v3fl(r_jacobian[0], data->c0_minus_c2, data->n0_minus_n2, x[2]);
776  madd_v3_v3v3fl(r_jacobian[1], data->c1_minus_c2, data->n1_minus_n2, x[2]);
777 
778  copy_v3_v3(r_jacobian[2], data->vtri_no[2]);
779  madd_v3_v3fl(r_jacobian[2], data->n0_minus_n2, x[0]);
780  madd_v3_v3fl(r_jacobian[2], data->n1_minus_n2, x[1]);
781 }
782 
783 /* Clamp barycentric weights to the triangle. */
784 static void target_project_tri_clamp(float x[3])
785 {
786  if (x[0] < 0.0f) {
787  x[0] = 0.0f;
788  }
789  if (x[1] < 0.0f) {
790  x[1] = 0.0f;
791  }
792  if (x[0] + x[1] > 1.0f) {
793  x[0] = x[0] / (x[0] + x[1]);
794  x[1] = 1.0f - x[0];
795  }
796 }
797 
798 /* Correct the Newton's method step to keep the coordinates within the triangle. */
799 static bool target_project_tri_correct(void *UNUSED(userdata),
800  const float x[3],
801  float step[3],
802  float x_next[3])
803 {
804  /* Insignificant correction threshold */
805  const float epsilon = 1e-5f;
806  /* Dot product threshold for checking if step is 'clearly' pointing outside. */
807  const float dir_epsilon = 0.5f;
808  bool fixed = false, locked = false;
809 
810  /* The barycentric coordinate domain is a triangle bounded by
811  * the X and Y axes, plus the x+y=1 diagonal. First, clamp the
812  * movement against the diagonal. Note that step is subtracted. */
813  float sum = x[0] + x[1];
814  float sstep = -(step[0] + step[1]);
815 
816  if (sum + sstep > 1.0f) {
817  float ldist = 1.0f - sum;
818 
819  /* If already at the boundary, slide along it. */
820  if (ldist < epsilon * (float)M_SQRT2) {
821  float step_len = len_v2(step);
822 
823  /* Abort if the solution is clearly outside the domain. */
824  if (step_len > epsilon && sstep > step_len * dir_epsilon * (float)M_SQRT2) {
825  return false;
826  }
827 
828  /* Project the new position onto the diagonal. */
829  add_v2_fl(step, (sum + sstep - 1.0f) * 0.5f);
830  fixed = locked = true;
831  }
832  else {
833  /* Scale a significant step down to arrive at the boundary. */
834  mul_v3_fl(step, ldist / sstep);
835  fixed = true;
836  }
837  }
838 
839  /* Weight 0 and 1 boundary checks - along axis. */
840  for (int i = 0; i < 2; i++) {
841  if (step[i] > x[i]) {
842  /* If already at the boundary, slide along it. */
843  if (x[i] < epsilon) {
844  float step_len = len_v2(step);
845 
846  /* Abort if the solution is clearly outside the domain. */
847  if (step_len > epsilon && (locked || step[i] > step_len * dir_epsilon)) {
848  return false;
849  }
850 
851  /* Reset precision errors to stay at the boundary. */
852  step[i] = x[i];
853  fixed = true;
854  }
855  else {
856  /* Scale a significant step down to arrive at the boundary. */
857  mul_v3_fl(step, x[i] / step[i]);
858  fixed = true;
859  }
860  }
861  }
862 
863  /* Recompute and clamp the new coordinates after step correction. */
864  if (fixed) {
865  sub_v3_v3v3(x_next, x, step);
866  target_project_tri_clamp(x_next);
867  }
868 
869  return true;
870 }
871 
872 static bool target_project_solve_point_tri(const float *vtri_co[3],
873  const float vtri_no[3][3],
874  const float point_co[3],
875  const float hit_co[3],
876  float hit_dist_sq,
877  float r_hit_co[3],
878  float r_hit_no[3])
879 {
880  float x[3], tmp[3];
881  float dist = sqrtf(hit_dist_sq);
882  float magnitude_estimate = dist + len_manhattan_v3(vtri_co[0]) + len_manhattan_v3(vtri_co[1]) +
883  len_manhattan_v3(vtri_co[2]);
884  float epsilon = magnitude_estimate * 1.0e-6f;
885 
886  /* Initial solution vector: barycentric weights plus distance along normal. */
887  interp_weights_tri_v3(x, UNPACK3(vtri_co), hit_co);
888 
889  interp_v3_v3v3v3(r_hit_no, UNPACK3(vtri_no), x);
890  sub_v3_v3v3(tmp, point_co, hit_co);
891 
892  x[2] = (dot_v3v3(tmp, r_hit_no) < 0) ? -dist : dist;
893 
894  /* Solve the equations iteratively. */
895  TargetProjectTriData tri_data = {
896  .vtri_co = vtri_co,
897  .vtri_no = vtri_no,
898  .point_co = point_co,
899  };
900 
901  sub_v3_v3v3(tri_data.n0_minus_n2, vtri_no[0], vtri_no[2]);
902  sub_v3_v3v3(tri_data.n1_minus_n2, vtri_no[1], vtri_no[2]);
903  sub_v3_v3v3(tri_data.c0_minus_c2, vtri_co[0], vtri_co[2]);
904  sub_v3_v3v3(tri_data.c1_minus_c2, vtri_co[1], vtri_co[2]);
905 
907 
908 #ifdef TRACE_TARGET_PROJECT
909  const bool trace = true;
910 #else
911  const bool trace = false;
912 #endif
913 
917  &tri_data,
918  epsilon,
919  20,
920  trace,
921  x,
922  x);
923 
924  if (ok) {
925  copy_v3_v3(r_hit_co, tri_data.co_interp);
926  copy_v3_v3(r_hit_no, tri_data.no_interp);
927 
928  return true;
929  }
930 
931  return false;
932 }
933 
934 static bool update_hit(BVHTreeNearest *nearest,
935  int index,
936  const float co[3],
937  const float hit_co[3],
938  const float hit_no[3])
939 {
940  float dist_sq = len_squared_v3v3(hit_co, co);
941 
942  if (dist_sq < nearest->dist_sq) {
943 #ifdef TRACE_TARGET_PROJECT
944  printf(
945  "#=#=#> %d (%.3f,%.3f,%.3f) %g < %g\n", index, UNPACK3(hit_co), dist_sq, nearest->dist_sq);
946 #endif
947  nearest->index = index;
948  nearest->dist_sq = dist_sq;
949  copy_v3_v3(nearest->co, hit_co);
950  normalize_v3_v3(nearest->no, hit_no);
951  return true;
952  }
953 
954  return false;
955 }
956 
957 /* Target projection on a non-manifold boundary edge -
958  * treats it like an infinitely thin cylinder. */
960  int index,
961  const float co[3],
962  BVHTreeNearest *nearest,
963  int eidx)
964 {
965  const BVHTreeFromMesh *data = &tree->treeData;
966  const MEdge *edge = &tree->mesh->medge[eidx];
967  const float *vedge_co[2] = {data->vert[edge->v1].co, data->vert[edge->v2].co};
968 
969 #ifdef TRACE_TARGET_PROJECT
970  printf("EDGE %d (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)\n",
971  eidx,
972  UNPACK3(vedge_co[0]),
973  UNPACK3(vedge_co[1]));
974 #endif
975 
976  /* Retrieve boundary vertex IDs */
977  const int *vert_boundary_id = tree->boundary->vert_boundary_id;
978  int bid1 = vert_boundary_id[edge->v1], bid2 = vert_boundary_id[edge->v2];
979 
980  if (bid1 < 0 || bid2 < 0) {
981  return;
982  }
983 
984  /* Retrieve boundary vertex normals and align them to direction. */
985  const ShrinkwrapBoundaryVertData *boundary_verts = tree->boundary->boundary_verts;
986  float vedge_dir[2][3], dir[3];
987 
988  copy_v3_v3(vedge_dir[0], boundary_verts[bid1].normal_plane);
989  copy_v3_v3(vedge_dir[1], boundary_verts[bid2].normal_plane);
990 
991  sub_v3_v3v3(dir, vedge_co[1], vedge_co[0]);
992 
993  if (dot_v3v3(boundary_verts[bid1].direction, dir) < 0) {
994  negate_v3(vedge_dir[0]);
995  }
996  if (dot_v3v3(boundary_verts[bid2].direction, dir) < 0) {
997  negate_v3(vedge_dir[1]);
998  }
999 
1000  /* Solve a quadratic equation: lerp(d0,d1,x) * (co - lerp(v0,v1,x)) = 0 */
1001  float d0v0 = dot_v3v3(vedge_dir[0], vedge_co[0]), d0v1 = dot_v3v3(vedge_dir[0], vedge_co[1]);
1002  float d1v0 = dot_v3v3(vedge_dir[1], vedge_co[0]), d1v1 = dot_v3v3(vedge_dir[1], vedge_co[1]);
1003  float d0co = dot_v3v3(vedge_dir[0], co);
1004 
1005  float a = d0v1 - d0v0 + d1v0 - d1v1;
1006  float b = 2 * d0v0 - d0v1 - d0co - d1v0 + dot_v3v3(vedge_dir[1], co);
1007  float c = d0co - d0v0;
1008  float det = b * b - 4 * a * c;
1009 
1010  if (det >= 0) {
1011  const float epsilon = 1e-6f;
1012  float sdet = sqrtf(det);
1013  float hit_co[3], hit_no[3];
1014 
1015  for (int i = (det > 0 ? 2 : 0); i >= 0; i -= 2) {
1016  float x = (-b + ((float)i - 1) * sdet) / (2 * a);
1017 
1018  if (x >= -epsilon && x <= 1.0f + epsilon) {
1019  CLAMP(x, 0, 1);
1020 
1021  float vedge_no[2][3];
1022  normal_short_to_float_v3(vedge_no[0], data->vert[edge->v1].no);
1023  normal_short_to_float_v3(vedge_no[1], data->vert[edge->v2].no);
1024 
1025  interp_v3_v3v3(hit_co, vedge_co[0], vedge_co[1], x);
1026  interp_v3_v3v3(hit_no, vedge_no[0], vedge_no[1], x);
1027 
1028  update_hit(nearest, index, co, hit_co, hit_no);
1029  }
1030  }
1031  }
1032 }
1033 
1034 /* Target normal projection BVH callback - based on mesh_looptri_nearest_point. */
1035 static void mesh_looptri_target_project(void *userdata,
1036  int index,
1037  const float co[3],
1038  BVHTreeNearest *nearest)
1039 {
1040  const ShrinkwrapTreeData *tree = (ShrinkwrapTreeData *)userdata;
1041  const BVHTreeFromMesh *data = &tree->treeData;
1042  const MLoopTri *lt = &data->looptri[index];
1043  const MLoop *loop[3] = {
1044  &data->loop[lt->tri[0]], &data->loop[lt->tri[1]], &data->loop[lt->tri[2]]};
1045  const MVert *vtri[3] = {
1046  &data->vert[loop[0]->v], &data->vert[loop[1]->v], &data->vert[loop[2]->v]};
1047  const float *vtri_co[3] = {vtri[0]->co, vtri[1]->co, vtri[2]->co};
1048  float raw_hit_co[3], hit_co[3], hit_no[3], dist_sq, vtri_no[3][3];
1049 
1050  /* First find the closest point and bail out if it's worse than the current solution. */
1051  closest_on_tri_to_point_v3(raw_hit_co, co, UNPACK3(vtri_co));
1052  dist_sq = len_squared_v3v3(co, raw_hit_co);
1053 
1054 #ifdef TRACE_TARGET_PROJECT
1055  printf("TRIANGLE %d (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f) %g %g\n",
1056  index,
1057  UNPACK3(vtri_co[0]),
1058  UNPACK3(vtri_co[1]),
1059  UNPACK3(vtri_co[2]),
1060  dist_sq,
1061  nearest->dist_sq);
1062 #endif
1063 
1064  if (dist_sq >= nearest->dist_sq) {
1065  return;
1066  }
1067 
1068  /* Decode normals */
1069  normal_short_to_float_v3(vtri_no[0], vtri[0]->no);
1070  normal_short_to_float_v3(vtri_no[1], vtri[1]->no);
1071  normal_short_to_float_v3(vtri_no[2], vtri[2]->no);
1072 
1073  /* Solve the equations for the triangle */
1074  if (target_project_solve_point_tri(vtri_co, vtri_no, co, raw_hit_co, dist_sq, hit_co, hit_no)) {
1075  update_hit(nearest, index, co, hit_co, hit_no);
1076  }
1077  /* Boundary edges */
1078  else if (tree->boundary && BLI_BITMAP_TEST(tree->boundary->looptri_has_boundary, index)) {
1079  const BLI_bitmap *is_boundary = tree->boundary->edge_is_boundary;
1080  int edges[3];
1081 
1082  BKE_mesh_looptri_get_real_edges(tree->mesh, lt, edges);
1083 
1084  for (int i = 0; i < 3; i++) {
1085  if (edges[i] >= 0 && BLI_BITMAP_TEST(is_boundary, edges[i])) {
1086  target_project_edge(tree, index, co, nearest, edges[i]);
1087  }
1088  }
1089  }
1090 }
1091 
1092 /*
1093  * Maps the point to the nearest surface, either by simple nearest, or by target normal projection.
1094  */
1096  BVHTreeNearest *nearest,
1097  float co[3],
1098  int type)
1099 {
1100  BVHTreeFromMesh *treeData = &tree->treeData;
1101 
1103 #ifdef TRACE_TARGET_PROJECT
1104  printf("\n====== TARGET PROJECT START ======\n");
1105 #endif
1106 
1109 
1110 #ifdef TRACE_TARGET_PROJECT
1111  printf("====== TARGET PROJECT END: %d %g ======\n\n", nearest->index, nearest->dist_sq);
1112 #endif
1113 
1114  if (nearest->index < 0) {
1115  /* fallback to simple nearest */
1116  BLI_bvhtree_find_nearest(tree->bvh, co, nearest, treeData->nearest_callback, treeData);
1117  }
1118  }
1119  else {
1120  BLI_bvhtree_find_nearest(tree->bvh, co, nearest, treeData->nearest_callback, treeData);
1121  }
1122 }
1123 
1124 /*
1125  * Shrinkwrap moving vertexs to the nearest surface point on the target
1126  *
1127  * it builds a BVHTree from the target mesh and then performs a
1128  * NN matches for each vertex
1129  */
1130 static void shrinkwrap_calc_nearest_surface_point_cb_ex(void *__restrict userdata,
1131  const int i,
1132  const TaskParallelTLS *__restrict tls)
1133 {
1134  ShrinkwrapCalcCBData *data = userdata;
1135 
1136  ShrinkwrapCalcData *calc = data->calc;
1137  BVHTreeNearest *nearest = tls->userdata_chunk;
1138 
1139  float *co = calc->vertexCos[i];
1140  float tmp_co[3];
1141  float weight = BKE_defvert_array_find_weight_safe(calc->dvert, i, calc->vgroup);
1142 
1143  if (calc->invert_vgroup) {
1144  weight = 1.0f - weight;
1145  }
1146 
1147  if (weight == 0.0f) {
1148  return;
1149  }
1150 
1151  /* Convert the vertex to tree coordinates */
1152  if (calc->vert) {
1153  copy_v3_v3(tmp_co, calc->vert[i].co);
1154  }
1155  else {
1156  copy_v3_v3(tmp_co, co);
1157  }
1158  BLI_space_transform_apply(&calc->local2target, tmp_co);
1159 
1160  /* Use local proximity heuristics (to reduce the nearest search)
1161  *
1162  * If we already had an hit before.. we assume this vertex is going to have a close hit to that
1163  * other vertex so we can initiate the "nearest.dist" with the expected value to that last hit.
1164  * This will lead in pruning of the search tree. */
1165  if (nearest->index != -1) {
1167  /* Heuristic doesn't work because of additional restrictions. */
1168  nearest->index = -1;
1169  nearest->dist_sq = FLT_MAX;
1170  }
1171  else {
1172  nearest->dist_sq = len_squared_v3v3(tmp_co, nearest->co);
1173  }
1174  }
1175  else {
1176  nearest->dist_sq = FLT_MAX;
1177  }
1178 
1179  BKE_shrinkwrap_find_nearest_surface(data->tree, nearest, tmp_co, calc->smd->shrinkType);
1180 
1181  /* Found the nearest vertex */
1182  if (nearest->index != -1) {
1184  NULL,
1185  calc->smd->shrinkMode,
1186  nearest->index,
1187  nearest->co,
1188  nearest->no,
1189  calc->keepDist,
1190  tmp_co,
1191  tmp_co);
1192 
1193  /* Convert the coordinates back to mesh coordinates */
1194  BLI_space_transform_invert(&calc->local2target, tmp_co);
1195  interp_v3_v3v3(co, co, tmp_co, weight); /* linear interpolation */
1196  }
1197 }
1198 
1207  const struct SpaceTransform *transform,
1208  int looptri_idx,
1209  const float hit_co[3],
1210  const float hit_no[3],
1211  float r_no[3])
1212 {
1213  const BVHTreeFromMesh *treeData = &tree->treeData;
1214  const MLoopTri *tri = &treeData->looptri[looptri_idx];
1215 
1216  /* Interpolate smooth normals if enabled. */
1217  if ((tree->mesh->mpoly[tri->poly].flag & ME_SMOOTH) != 0) {
1218  const MVert *verts[] = {
1219  &treeData->vert[treeData->loop[tri->tri[0]].v],
1220  &treeData->vert[treeData->loop[tri->tri[1]].v],
1221  &treeData->vert[treeData->loop[tri->tri[2]].v],
1222  };
1223  float w[3], no[3][3], tmp_co[3];
1224 
1225  /* Custom and auto smooth split normals. */
1226  if (tree->clnors) {
1227  copy_v3_v3(no[0], tree->clnors[tri->tri[0]]);
1228  copy_v3_v3(no[1], tree->clnors[tri->tri[1]]);
1229  copy_v3_v3(no[2], tree->clnors[tri->tri[2]]);
1230  }
1231  /* Ordinary vertex normals. */
1232  else {
1233  normal_short_to_float_v3(no[0], verts[0]->no);
1234  normal_short_to_float_v3(no[1], verts[1]->no);
1235  normal_short_to_float_v3(no[2], verts[2]->no);
1236  }
1237 
1238  /* Barycentric weights from hit point. */
1239  copy_v3_v3(tmp_co, hit_co);
1240 
1241  if (transform) {
1243  }
1244 
1245  interp_weights_tri_v3(w, verts[0]->co, verts[1]->co, verts[2]->co, tmp_co);
1246 
1247  /* Interpolate using weights. */
1248  interp_v3_v3v3v3(r_no, no[0], no[1], no[2], w);
1249 
1250  if (transform) {
1252  }
1253  else {
1254  normalize_v3(r_no);
1255  }
1256  }
1257  /* Use the polygon normal if flat. */
1258  else if (tree->pnors != NULL) {
1259  copy_v3_v3(r_no, tree->pnors[tri->poly]);
1260  }
1261  /* Finally fallback to the looptri normal. */
1262  else {
1263  copy_v3_v3(r_no, hit_no);
1264  }
1265 }
1266 
1267 /* Helper for MOD_SHRINKWRAP_INSIDE, MOD_SHRINKWRAP_OUTSIDE and MOD_SHRINKWRAP_OUTSIDE_SURFACE. */
1268 static void shrinkwrap_snap_with_side(float r_point_co[3],
1269  const float point_co[3],
1270  const float hit_co[3],
1271  const float hit_no[3],
1272  float goal_dist,
1273  float forcesign,
1274  bool forcesnap)
1275 {
1276  float delta[3];
1277  sub_v3_v3v3(delta, point_co, hit_co);
1278 
1279  float dist = len_v3(delta);
1280 
1281  /* If exactly on the surface, push out along normal */
1282  if (dist < FLT_EPSILON) {
1283  if (forcesnap || goal_dist > 0) {
1284  madd_v3_v3v3fl(r_point_co, hit_co, hit_no, goal_dist * forcesign);
1285  }
1286  else {
1287  copy_v3_v3(r_point_co, hit_co);
1288  }
1289  }
1290  /* Move to the correct side if needed */
1291  else {
1292  float dsign = signf(dot_v3v3(delta, hit_no));
1293 
1294  if (forcesign == 0.0f) {
1295  forcesign = dsign;
1296  }
1297 
1298  /* If on the wrong side or too close, move to correct */
1299  if (forcesnap || dsign * dist * forcesign < goal_dist) {
1300  mul_v3_fl(delta, dsign / dist);
1301 
1302  /* At very small distance, blend in the hit normal to stabilize math. */
1303  float dist_epsilon = (fabsf(goal_dist) + len_manhattan_v3(hit_co)) * 1e-4f;
1304 
1305  if (dist < dist_epsilon) {
1306 #ifdef TRACE_TARGET_PROJECT
1307  printf("zero_factor %g = %g / %g\n", dist / dist_epsilon, dist, dist_epsilon);
1308 #endif
1309 
1310  interp_v3_v3v3(delta, hit_no, delta, dist / dist_epsilon);
1311  }
1312 
1313  madd_v3_v3v3fl(r_point_co, hit_co, delta, goal_dist * forcesign);
1314  }
1315  else {
1316  copy_v3_v3(r_point_co, point_co);
1317  }
1318  }
1319 }
1320 
1329  const struct SpaceTransform *transform,
1330  int mode,
1331  int hit_idx,
1332  const float hit_co[3],
1333  const float hit_no[3],
1334  float goal_dist,
1335  const float point_co[3],
1336  float r_point_co[3])
1337 {
1338  float tmp[3];
1339 
1340  switch (mode) {
1341  /* Offsets along the line between point_co and hit_co. */
1343  if (goal_dist != 0) {
1344  shrinkwrap_snap_with_side(r_point_co, point_co, hit_co, hit_no, goal_dist, 0, true);
1345  }
1346  else {
1347  copy_v3_v3(r_point_co, hit_co);
1348  }
1349  break;
1350 
1351  case MOD_SHRINKWRAP_INSIDE:
1352  shrinkwrap_snap_with_side(r_point_co, point_co, hit_co, hit_no, goal_dist, -1, false);
1353  break;
1354 
1356  shrinkwrap_snap_with_side(r_point_co, point_co, hit_co, hit_no, goal_dist, +1, false);
1357  break;
1358 
1360  if (goal_dist != 0) {
1361  shrinkwrap_snap_with_side(r_point_co, point_co, hit_co, hit_no, goal_dist, +1, true);
1362  }
1363  else {
1364  copy_v3_v3(r_point_co, hit_co);
1365  }
1366  break;
1367 
1368  /* Offsets along the normal */
1370  if (goal_dist != 0) {
1371  BKE_shrinkwrap_compute_smooth_normal(tree, transform, hit_idx, hit_co, hit_no, tmp);
1372  madd_v3_v3v3fl(r_point_co, hit_co, tmp, goal_dist);
1373  }
1374  else {
1375  copy_v3_v3(r_point_co, hit_co);
1376  }
1377  break;
1378 
1379  default:
1380  printf("Unknown Shrinkwrap surface snap mode: %d\n", mode);
1381  copy_v3_v3(r_point_co, hit_co);
1382  }
1383 }
1384 
1386 {
1388 
1389  /* Setup nearest */
1390  nearest.index = -1;
1391  nearest.dist_sq = FLT_MAX;
1392 
1393  /* Find the nearest vertex */
1395  .calc = calc,
1396  .tree = calc->tree,
1397  };
1398  TaskParallelSettings settings;
1400  settings.use_threading = (calc->numVerts > BKE_MESH_OMP_LIMIT);
1401  settings.userdata_chunk = &nearest;
1402  settings.userdata_chunk_size = sizeof(nearest);
1405 }
1406 
1407 /* Main shrinkwrap function */
1409  const ModifierEvalContext *ctx,
1410  struct Scene *scene,
1411  Object *ob,
1412  Mesh *mesh,
1413  MDeformVert *dvert,
1414  const int defgrp_index,
1415  float (*vertexCos)[3],
1416  int numVerts)
1417 {
1418 
1419  DerivedMesh *ss_mesh = NULL;
1421 
1422  /* remove loop dependencies on derived meshes (TODO should this be done elsewhere?) */
1423  if (smd->target == ob) {
1424  smd->target = NULL;
1425  }
1426  if (smd->auxTarget == ob) {
1427  smd->auxTarget = NULL;
1428  }
1429 
1430  /* Configure Shrinkwrap calc data */
1431  calc.smd = smd;
1432  calc.ob = ob;
1433  calc.numVerts = numVerts;
1434  calc.vertexCos = vertexCos;
1435  calc.dvert = dvert;
1436  calc.vgroup = defgrp_index;
1438 
1439  if (smd->target != NULL) {
1440  Object *ob_target = DEG_get_evaluated_object(ctx->depsgraph, smd->target);
1442 
1443  /* TODO there might be several "bugs" with non-uniform scales matrices
1444  * because it will no longer be nearest surface, not sphere projection
1445  * because space has been deformed */
1446  BLI_SPACE_TRANSFORM_SETUP(&calc.local2target, ob, ob_target);
1447 
1448  /* TODO: smd->keepDist is in global units.. must change to local */
1449  calc.keepDist = smd->keepDist;
1450  }
1452 
1453  if (mesh != NULL && smd->shrinkType == MOD_SHRINKWRAP_PROJECT) {
1454  /* Setup arrays to get vertexs positions, normals and deform weights */
1455  calc.vert = mesh->mvert;
1456 
1457  /* Using vertexs positions/normals as if a subsurface was applied */
1458  if (smd->subsurfLevels) {
1459  SubsurfModifierData ssmd = {{NULL}};
1460  ssmd.subdivType = ME_CC_SUBSURF; /* catmull clark */
1461  ssmd.levels = smd->subsurfLevels; /* levels */
1462 
1463  /* TODO to be moved to Mesh once we are done with changes in subsurf code. */
1465 
1467  dm, &ssmd, scene, NULL, (ob->mode & OB_MODE_EDIT) ? SUBSURF_IN_EDIT_MODE : 0);
1468 
1469  if (ss_mesh) {
1470  calc.vert = ss_mesh->getVertDataArray(ss_mesh, CD_MVERT);
1471  if (calc.vert) {
1472  /* TRICKY: this code assumes subsurface will have the transformed original vertices
1473  * in their original order at the end of the vert array. */
1474  calc.vert = calc.vert + ss_mesh->getNumVerts(ss_mesh) - dm->getNumVerts(dm);
1475  }
1476  }
1477 
1478  /* Just to make sure we are not leaving any memory behind */
1479  BLI_assert(ssmd.emCache == NULL);
1480  BLI_assert(ssmd.mCache == NULL);
1481 
1482  dm->release(dm);
1483  }
1484  }
1485 
1486  /* Projecting target defined - lets work! */
1488 
1489  if (BKE_shrinkwrap_init_tree(&tree, calc.target, smd->shrinkType, smd->shrinkMode, false)) {
1490  calc.tree = &tree;
1491 
1492  switch (smd->shrinkType) {
1495  TIMEIT_BENCH(shrinkwrap_calc_nearest_surface_point(&calc), deform_surface);
1496  break;
1497 
1499  TIMEIT_BENCH(shrinkwrap_calc_normal_projection(&calc), deform_project);
1500  break;
1501 
1503  TIMEIT_BENCH(shrinkwrap_calc_nearest_vertex(&calc), deform_vertex);
1504  break;
1505  }
1506 
1508  }
1509 
1510  /* free memory */
1511  if (ss_mesh) {
1512  ss_mesh->release(ss_mesh);
1513  }
1514 }
1515 
1517  Object *ob_source,
1518  Object *ob_target)
1519 {
1521  struct Scene *sce = CTX_data_scene(C);
1522  ShrinkwrapModifierData ssmd = {{0}};
1523  ModifierEvalContext ctx = {depsgraph, ob_source, 0};
1524  int totvert;
1525 
1526  ssmd.target = ob_target;
1529  ssmd.keepDist = 0.0f;
1530 
1531  Mesh *src_me = ob_source->data;
1532  float(*vertexCos)[3] = BKE_mesh_vert_coords_alloc(src_me, &totvert);
1533 
1534  shrinkwrapModifier_deform(&ssmd, &ctx, sce, ob_source, src_me, NULL, -1, vertexCos, totvert);
1535 
1536  BKE_mesh_vert_coords_apply(src_me, vertexCos);
1537 
1538  MEM_freeN(vertexCos);
1539 }
1540 
1541 void BKE_shrinkwrap_remesh_target_project(Mesh *src_me, Mesh *target_me, Object *ob_target)
1542 {
1543  ShrinkwrapModifierData ssmd = {{0}};
1544  int totvert;
1545 
1546  ssmd.target = ob_target;
1550  ssmd.keepDist = 0.0f;
1551 
1552  /* Tolerance value to prevent artifacts on sharp edges of a mesh.
1553  * This constant and based on experimenting with different values. */
1554  const float projLimitTolerance = 5.0f;
1555  ssmd.projLimit = target_me->remesh_voxel_size * projLimitTolerance;
1556 
1557  float(*vertexCos)[3] = BKE_mesh_vert_coords_alloc(src_me, &totvert);
1558 
1560 
1561  calc.smd = &ssmd;
1562  calc.numVerts = src_me->totvert;
1563  calc.vertexCos = vertexCos;
1564  calc.vgroup = -1;
1565  calc.target = target_me;
1566  calc.keepDist = ssmd.keepDist;
1567  calc.vert = src_me->mvert;
1568  BLI_SPACE_TRANSFORM_SETUP(&calc.local2target, ob_target, ob_target);
1569 
1571  if (BKE_shrinkwrap_init_tree(&tree, calc.target, ssmd.shrinkType, ssmd.shrinkMode, false)) {
1572  calc.tree = &tree;
1573  TIMEIT_BENCH(shrinkwrap_calc_normal_projection(&calc), deform_project);
1575  }
1576 
1577  BKE_mesh_vert_coords_apply(src_me, vertexCos);
1578 
1579  MEM_freeN(vertexCos);
1580 }
typedef float(TangentPoint)[2]
BVHTree * BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data, struct Mesh *mesh, const BVHCacheType bvh_cache_type, const int tree_type)
Definition: bvhutils.c:1413
void free_bvhtree_from_mesh(struct BVHTreeFromMesh *data)
Definition: bvhutils.c:1701
@ BVHTREE_FROM_LOOPTRI
Definition: BKE_bvhutils.h:93
@ BVHTREE_FROM_VERTS
Definition: BKE_bvhutils.h:90
struct DerivedMesh * CDDM_from_mesh(struct Mesh *mesh)
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
struct Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Definition: context.c:1401
void * CustomData_get_layer(const struct CustomData *data, int type)
support for deformation groups and hooks.
float BKE_defvert_array_find_weight_safe(const struct MDeformVert *dvert, const int index, const int defgroup)
Definition: deform.c:645
#define BKE_MESH_OMP_LIMIT
Definition: BKE_mesh.h:67
void BKE_mesh_vert_coords_apply(struct Mesh *mesh, const float(*vert_coords)[3])
Definition: mesh.c:1755
void BKE_mesh_looptri_get_real_edges(const struct Mesh *mesh, const struct MLoopTri *looptri, int r_edges[3])
float(* BKE_mesh_vert_coords_alloc(const struct Mesh *mesh, int *r_vert_len))[3]
const struct MLoopTri * BKE_mesh_runtime_looptri_ensure(struct Mesh *mesh)
Definition: mesh_runtime.c:155
int BKE_mesh_runtime_looptri_len(const struct Mesh *mesh)
void BKE_mesh_wrapper_ensure_mdata(struct Mesh *me)
Definition: mesh_wrapper.c:98
struct Mesh * BKE_modifier_get_evaluated_mesh_from_evaluated_object(struct Object *ob_eval, const bool get_cage_mesh)
#define NULL_BVHTreeNearest
#define NULL_ShrinkwrapCalcData
struct DerivedMesh * subsurf_make_derived_from_derived(struct DerivedMesh *dm, struct SubsurfModifierData *smd, const struct Scene *scene, float(*vertCos)[3], SubsurfFlags flags)
Definition: subsurf_ccg.c:2343
@ SUBSURF_IN_EDIT_MODE
Definition: BKE_subsurf.h:55
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define BLI_BITMAP_TEST(_bitmap, _index)
Definition: BLI_bitmap.h:63
#define BLI_BITMAP_ENABLE(_bitmap, _index)
Definition: BLI_bitmap.h:78
#define BLI_BITMAP_NEW(_tot, _alloc_string)
Definition: BLI_bitmap.h:50
unsigned int BLI_bitmap
Definition: BLI_bitmap.h:32
@ BVH_NEAREST_OPTIMAL_ORDER
Definition: BLI_kdopbvh.h:98
#define BVH_RAYCAST_DIST_MAX
Definition: BLI_kdopbvh.h:105
int BLI_bvhtree_find_nearest_ex(BVHTree *tree, const float co[3], BVHTreeNearest *nearest, BVHTree_NearestPointCallback callback, void *userdata, int flag)
Definition: BLI_kdopbvh.c:1605
int BLI_bvhtree_ray_cast(BVHTree *tree, const float co[3], const float dir[3], float radius, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata)
Definition: BLI_kdopbvh.c:1984
int BLI_bvhtree_find_nearest(BVHTree *tree, const float co[3], BVHTreeNearest *nearest, BVHTree_NearestPointCallback callback, void *userdata)
Definition: BLI_kdopbvh.c:1654
#define M_SQRT2
Definition: BLI_math_base.h:47
MINLINE float signf(float f)
void interp_weights_tri_v3(float w[3], const float v1[3], const float v2[3], const float v3[3], const float co[3])
Definition: math_geom.c:3831
void closest_on_tri_to_point_v3(float r[3], const float p[3], const float v1[3], const float v2[3], const float v3[3])
Definition: math_geom.c:1023
void BLI_space_transform_apply_normal(const struct SpaceTransform *data, float no[3])
void BLI_space_transform_apply(const struct SpaceTransform *data, float co[3])
float mat4_to_scale(const float M[4][4])
Definition: math_matrix.c:2196
void BLI_space_transform_invert_normal(const struct SpaceTransform *data, float no[3])
void BLI_space_transform_invert(const struct SpaceTransform *data, float co[3])
#define BLI_SPACE_TRANSFORM_SETUP(data, local, target)
bool BLI_newton3d_solve(Newton3D_DeltaFunc func_delta, Newton3D_JacobianFunc func_jacobian, Newton3D_CorrectionFunc func_correction, void *userdata, float epsilon, int max_iterations, bool trace, const float x_init[3], float result[3])
Solve a generic f(x) = 0 equation using Newton's method.
Definition: math_solvers.c:212
void interp_v3_v3v3(float r[3], const float a[3], const float b[3], const float t)
Definition: math_vector.c:49
MINLINE float len_squared_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE float normalize_v3(float r[3])
MINLINE void sub_v3_v3(float r[3], const float a[3])
void interp_v3_v3v3v3(float p[3], const float v1[3], const float v2[3], const float v3[3], const float w[3])
Definition: math_vector.c:191
MINLINE float len_squared_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void normal_short_to_float_v3(float r[3], const short n[3])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void negate_v3_v3(float r[3], const float a[3])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void add_v2_fl(float r[2], float f)
MINLINE void negate_v3(float r[3])
MINLINE float normalize_v3_v3(float r[3], const float a[3])
MINLINE float len_manhattan_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void madd_v3_v3v3fl(float r[3], const float a[3], const float b[3], float f)
MINLINE float len_v2(const float a[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void add_v3_v3(float r[3], const float a[3])
MINLINE float len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
Strict compiler flags for areas of code we want to ensure don't do conversions without us knowing abo...
void BLI_task_parallel_range(const int start, const int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
Definition: task_range.cc:110
BLI_INLINE void BLI_parallel_range_settings_defaults(TaskParallelSettings *settings)
Definition: BLI_task.h:231
#define UNUSED(x)
#define UNPACK3(a)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
struct Object * DEG_get_evaluated_object(const struct Depsgraph *depsgraph, struct Object *object)
@ CD_MVERT
@ ME_CC_SUBSURF
@ ME_AUTOSMOOTH
@ ME_SMOOTH
@ MOD_SHRINKWRAP_ON_SURFACE
@ MOD_SHRINKWRAP_OUTSIDE
@ MOD_SHRINKWRAP_INSIDE
@ MOD_SHRINKWRAP_ABOVE_SURFACE
@ MOD_SHRINKWRAP_OUTSIDE_SURFACE
#define MOD_SHRINKWRAP_CULL_TARGET_MASK
@ MOD_SHRINKWRAP_PROJECT_OVER_X_AXIS
@ MOD_SHRINKWRAP_PROJECT_OVER_Y_AXIS
@ MOD_SHRINKWRAP_PROJECT_OVER_Z_AXIS
@ MOD_SHRINKWRAP_PROJECT_OVER_NORMAL
@ MOD_SHRINKWRAP_TARGET_PROJECT
@ MOD_SHRINKWRAP_NEAREST_VERTEX
@ MOD_SHRINKWRAP_PROJECT
@ MOD_SHRINKWRAP_NEAREST_SURFACE
@ MOD_SHRINKWRAP_PROJECT_ALLOW_POS_DIR
@ MOD_SHRINKWRAP_CULL_TARGET_FRONTFACE
@ MOD_SHRINKWRAP_PROJECT_ALLOW_NEG_DIR
@ MOD_SHRINKWRAP_CULL_TARGET_BACKFACE
@ MOD_SHRINKWRAP_INVERT_VGROUP
@ MOD_SHRINKWRAP_INVERT_CULL_TARGET
@ OB_MODE_EDIT
Object is a sort of wrapper for general info.
_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 type
Read Guarded memory(de)allocation.
Group RGB to Bright Vector Camera CLAMP
Utility defines for timing/benchmarks.
#define C
Definition: RandGen.cpp:39
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
static T sum(const btAlignedObjectArray< T > &items)
CCL_NAMESPACE_BEGIN struct Options options
Scene scene
const Depsgraph * depsgraph
void * tree
static float verts[][3]
#define fabsf(x)
#define sqrtf(x)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:46
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
static unsigned c
Definition: RandGen.cpp:97
static unsigned a[3]
Definition: RandGen.cpp:92
static double epsilon
struct ShrinkwrapCalcData ShrinkwrapCalcData
static void target_project_edge(const ShrinkwrapTreeData *tree, int index, const float co[3], BVHTreeNearest *nearest, int eidx)
Definition: shrinkwrap.c:959
static void target_project_tri_clamp(float x[3])
Definition: shrinkwrap.c:784
static bool target_project_solve_point_tri(const float *vtri_co[3], const float vtri_no[3][3], const float point_co[3], const float hit_co[3], float hit_dist_sq, float r_hit_co[3], float r_hit_no[3])
Definition: shrinkwrap.c:872
void BKE_shrinkwrap_free_tree(ShrinkwrapTreeData *data)
Definition: shrinkwrap.c:164
static void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc)
Definition: shrinkwrap.c:416
static ShrinkwrapBoundaryData * shrinkwrap_build_boundary_data(struct Mesh *mesh)
Definition: shrinkwrap.c:210
struct ShrinkwrapCalcCBData ShrinkwrapCalcCBData
static void mesh_looptri_target_project(void *userdata, int index, const float co[3], BVHTreeNearest *nearest)
Definition: shrinkwrap.c:1035
void BKE_shrinkwrap_find_nearest_surface(struct ShrinkwrapTreeData *tree, BVHTreeNearest *nearest, float co[3], int type)
Definition: shrinkwrap.c:1095
static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc)
Definition: shrinkwrap.c:1385
static bool update_hit(BVHTreeNearest *nearest, int index, const float co[3], const float hit_co[3], const float hit_no[3])
Definition: shrinkwrap.c:934
static void shrinkwrap_snap_with_side(float r_point_co[3], const float point_co[3], const float hit_co[3], const float hit_no[3], float goal_dist, float forcesign, bool forcesnap)
Definition: shrinkwrap.c:1268
bool BKE_shrinkwrap_project_normal(char options, const float vert[3], const float dir[3], const float ray_radius, const SpaceTransform *transf, ShrinkwrapTreeData *tree, BVHTreeRayHit *hit)
Definition: shrinkwrap.c:445
static void target_project_tri_deviation(void *userdata, const float x[3], float r_delta[3])
Definition: shrinkwrap.c:758
static void merge_vert_dir(ShrinkwrapBoundaryVertData *vdata, signed char *status, int index, const float edge_dir[3], signed char side)
Definition: shrinkwrap.c:187
static void shrinkwrap_calc_nearest_vertex_cb_ex(void *__restrict userdata, const int i, const TaskParallelTLS *__restrict tls)
Definition: shrinkwrap.c:354
struct TargetProjectTriData TargetProjectTriData
void BKE_shrinkwrap_mesh_nearest_surface_deform(struct bContext *C, Object *ob_source, Object *ob_target)
Definition: shrinkwrap.c:1516
static void shrinkwrap_calc_normal_projection_cb_ex(void *__restrict userdata, const int i, const TaskParallelTLS *__restrict tls)
Definition: shrinkwrap.c:520
void BKE_shrinkwrap_remesh_target_project(Mesh *src_me, Mesh *target_me, Object *ob_target)
Definition: shrinkwrap.c:1541
void BKE_shrinkwrap_compute_smooth_normal(const struct ShrinkwrapTreeData *tree, const struct SpaceTransform *transform, int looptri_idx, const float hit_co[3], const float hit_no[3], float r_no[3])
Definition: shrinkwrap.c:1206
#define TIMEIT_BENCH(expr, id)
Definition: shrinkwrap.c:66
bool BKE_shrinkwrap_needs_normals(int shrinkType, int shrinkMode)
Definition: shrinkwrap.c:105
void BKE_shrinkwrap_compute_boundary_data(struct Mesh *mesh)
Definition: shrinkwrap.c:341
static void target_project_tri_jacobian(void *userdata, const float x[3], float r_jacobian[3][3])
Definition: shrinkwrap.c:771
bool BKE_shrinkwrap_init_tree(ShrinkwrapTreeData *data, Mesh *mesh, int shrinkType, int shrinkMode, bool force_normals)
Definition: shrinkwrap.c:113
void BKE_shrinkwrap_discard_boundary_data(struct Mesh *mesh)
Definition: shrinkwrap.c:170
void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, const ModifierEvalContext *ctx, struct Scene *scene, Object *ob, Mesh *mesh, MDeformVert *dvert, const int defgrp_index, float(*vertexCos)[3], int numVerts)
Definition: shrinkwrap.c:1408
static bool target_project_tri_correct(void *UNUSED(userdata), const float x[3], float step[3], float x_next[3])
Definition: shrinkwrap.c:799
static void shrinkwrap_calc_nearest_surface_point_cb_ex(void *__restrict userdata, const int i, const TaskParallelTLS *__restrict tls)
Definition: shrinkwrap.c:1130
static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc)
Definition: shrinkwrap.c:642
void BKE_shrinkwrap_snap_point_to_surface(const struct ShrinkwrapTreeData *tree, const struct SpaceTransform *transform, int mode, int hit_idx, const float hit_co[3], const float hit_no[3], float goal_dist, const float point_co[3], float r_point_co[3])
Definition: shrinkwrap.c:1328
const struct MLoop * loop
Definition: BKE_bvhutils.h:76
struct BVHTree * tree
Definition: BKE_bvhutils.h:66
const struct MVert * vert
Definition: BKE_bvhutils.h:73
BVHTree_NearestPointCallback nearest_callback
Definition: BKE_bvhutils.h:69
const struct MLoopTri * looptri
Definition: BKE_bvhutils.h:77
float co[3]
Definition: BLI_kdopbvh.h:59
float no[3]
Definition: BLI_kdopbvh.h:62
float co[3]
Definition: BLI_kdopbvh.h:84
float no[3]
Definition: BLI_kdopbvh.h:86
void *(* getVertDataArray)(DerivedMesh *dm, int type)
int(* getNumVerts)(DerivedMesh *dm)
void(* release)(DerivedMesh *dm)
unsigned int v1
unsigned int v2
unsigned int poly
unsigned int tri[3]
unsigned int e
unsigned int v
float co[3]
short no[3]
struct ShrinkwrapBoundaryData * shrinkwrap_data
struct MEdge * medge
struct CustomData pdata ldata
struct MVert * mvert
float remesh_voxel_size
int totedge
int totvert
short flag
struct MLoop * mloop
Mesh_Runtime runtime
int totpoly
int totloop
struct Depsgraph * depsgraph
Definition: BKE_modifier.h:153
void * data
const int * vert_boundary_id
const ShrinkwrapBoundaryVertData * boundary_verts
const BLI_bitmap * looptri_has_boundary
const BLI_bitmap * edge_is_boundary
unsigned int num_boundary_verts
SpaceTransform * local2aux
Definition: shrinkwrap.c:101
ShrinkwrapTreeData * tree
Definition: shrinkwrap.c:97
ShrinkwrapCalcData * calc
Definition: shrinkwrap.c:95
ShrinkwrapTreeData * aux_tree
Definition: shrinkwrap.c:98
struct SpaceTransform local2target
Definition: shrinkwrap.c:86
float(* vertexCos)[3]
Definition: shrinkwrap.c:78
struct ShrinkwrapTreeData * tree
Definition: shrinkwrap.c:87
struct MVert * vert
Definition: shrinkwrap.c:77
struct Object * aux_target
Definition: shrinkwrap.c:89
ShrinkwrapModifierData * smd
Definition: shrinkwrap.c:73
struct MDeformVert * dvert
Definition: shrinkwrap.c:81
struct Mesh * target
Definition: shrinkwrap.c:85
struct Object * ob
Definition: shrinkwrap.c:75
const float ** vtri_co
Definition: shrinkwrap.c:746
const float * point_co
Definition: shrinkwrap.c:748
const float(* vtri_no)[3]
Definition: shrinkwrap.c:747
size_t userdata_chunk_size
Definition: BLI_task.h:150