Blender  V3.3
sculpt_cloth.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2020 Blender Foundation. All rights reserved. */
3 
8 #include "MEM_guardedalloc.h"
9 
10 #include "BLI_blenlib.h"
11 #include "BLI_dial_2d.h"
12 #include "BLI_edgehash.h"
13 #include "BLI_gsqueue.h"
14 #include "BLI_hash.h"
15 #include "BLI_math.h"
16 #include "BLI_task.h"
17 #include "BLI_utildefines.h"
18 
19 #include "BLT_translation.h"
20 
21 #include "DNA_brush_types.h"
22 #include "DNA_customdata_types.h"
23 #include "DNA_mesh_types.h"
24 #include "DNA_meshdata_types.h"
25 #include "DNA_node_types.h"
26 #include "DNA_object_types.h"
27 #include "DNA_scene_types.h"
28 
29 #include "BKE_brush.h"
30 #include "BKE_bvhutils.h"
31 #include "BKE_ccg.h"
32 #include "BKE_collision.h"
33 #include "BKE_colortools.h"
34 #include "BKE_context.h"
35 #include "BKE_image.h"
36 #include "BKE_kelvinlet.h"
37 #include "BKE_key.h"
38 #include "BKE_lib_id.h"
39 #include "BKE_main.h"
40 #include "BKE_mesh.h"
41 #include "BKE_mesh_mapping.h"
42 #include "BKE_mesh_mirror.h"
43 #include "BKE_modifier.h"
44 #include "BKE_multires.h"
45 #include "BKE_node.h"
46 #include "BKE_object.h"
47 #include "BKE_paint.h"
48 #include "BKE_particle.h"
49 #include "BKE_pbvh.h"
50 #include "BKE_pointcache.h"
51 #include "BKE_report.h"
52 #include "BKE_scene.h"
53 #include "BKE_screen.h"
54 #include "BKE_subdiv_ccg.h"
55 #include "BKE_subsurf.h"
56 
57 #include "DEG_depsgraph.h"
58 #include "DEG_depsgraph_query.h"
59 
60 #include "WM_api.h"
61 #include "WM_message.h"
62 #include "WM_toolsystem.h"
63 #include "WM_types.h"
64 
65 #include "ED_object.h"
66 #include "ED_screen.h"
67 #include "ED_sculpt.h"
68 #include "ED_view3d.h"
69 #include "paint_intern.h"
70 #include "sculpt_intern.h"
71 
72 #include "RNA_access.h"
73 #include "RNA_define.h"
74 
75 #include "GPU_immediate.h"
76 #include "GPU_immediate_util.h"
77 #include "GPU_matrix.h"
78 #include "GPU_state.h"
79 
80 #include "UI_interface.h"
81 #include "UI_resources.h"
82 
83 #include "bmesh.h"
84 #include "bmesh_tools.h"
85 
86 #include <math.h>
87 #include <stdlib.h>
88 #include <string.h>
89 
91  const Brush *brush,
92  float r_location[3])
93 {
94  if (!ss->cache || !brush) {
95  zero_v3(r_location);
96  return;
97  }
98 
100  copy_v3_v3(r_location, ss->cache->initial_location);
101  return;
102  }
103  copy_v3_v3(r_location, ss->cache->location);
104 }
105 
107  Brush *brush,
108  int *r_totnode)
109 {
110  BLI_assert(ss->cache);
112  PBVHNode **nodes = NULL;
113 
114  switch (brush->cloth_simulation_area_type) {
117  .ss = ss,
118  .radius_squared = square_f(ss->cache->initial_radius * (1.0 + brush->cloth_sim_limit)),
119  .original = false,
120  .ignore_fully_ineffective = false,
121  .center = ss->cache->initial_location,
122  };
123  BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, r_totnode);
124  } break;
126  BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, r_totnode);
127  break;
130  .ss = ss,
131  .radius_squared = square_f(ss->cache->radius * (1.0 + brush->cloth_sim_limit)),
132  .original = false,
133  .ignore_fully_ineffective = false,
134  .center = ss->cache->location,
135  };
136  BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, r_totnode);
137  } break;
138  }
139 
140  return nodes;
141 }
142 
143 static float cloth_brush_simulation_falloff_get(const Brush *brush,
144  const float radius,
145  const float location[3],
146  const float co[3])
147 {
148  if (brush->sculpt_tool != SCULPT_TOOL_CLOTH) {
149  /* All brushes that are not the cloth brush do not use simulation areas. */
150  return 1.0f;
151  }
152 
153  /* Global simulation does not have any falloff as the entire mesh is being simulated. */
155  return 1.0f;
156  }
157 
158  const float distance = len_v3v3(location, co);
159  const float limit = radius + (radius * brush->cloth_sim_limit);
160  const float falloff = radius + (radius * brush->cloth_sim_limit * brush->cloth_sim_falloff);
161 
162  if (distance > limit) {
163  /* Outside the limits. */
164  return 0.0f;
165  }
166  if (distance < falloff) {
167  /* Before the falloff area. */
168  return 1.0f;
169  }
170  /* Do a smooth-step transition inside the falloff area. */
171  float p = 1.0f - ((distance - falloff) / (limit - falloff));
172  return 3.0f * p * p - 2.0f * p * p * p;
173 }
174 
175 #define CLOTH_LENGTH_CONSTRAINTS_BLOCK 100000
176 #define CLOTH_SIMULATION_ITERATIONS 5
177 
178 #define CLOTH_SOLVER_DISPLACEMENT_FACTOR 0.6f
179 #define CLOTH_MAX_CONSTRAINTS_PER_VERTEX 1024
180 #define CLOTH_SIMULATION_TIME_STEP 0.01f
181 #define CLOTH_DEFORMATION_SNAKEHOOK_STRENGTH 0.35f
182 #define CLOTH_DEFORMATION_TARGET_STRENGTH 0.01f
183 #define CLOTH_DEFORMATION_GRAB_STRENGTH 0.1f
184 
186  const int v1,
187  const int v2)
188 {
189  return BLI_edgeset_haskey(cloth_sim->created_length_constraints, v1, v2);
190 }
191 
193 {
194  if (cloth_sim->tot_length_constraints >= cloth_sim->capacity_length_constraints) {
196  cloth_sim->length_constraints = MEM_reallocN_id(cloth_sim->length_constraints,
197  cloth_sim->capacity_length_constraints *
199  "length constraints");
200  }
201 }
202 
204  SculptClothSimulation *cloth_sim,
205  const int node_index,
206  const int v1,
207  const int v2,
208  const bool use_persistent)
209 {
210  SculptClothLengthConstraint *length_constraint =
211  &cloth_sim->length_constraints[cloth_sim->tot_length_constraints];
212 
213  length_constraint->elem_index_a = v1;
214  length_constraint->elem_index_b = v2;
215 
216  length_constraint->node = node_index;
217 
218  length_constraint->elem_position_a = cloth_sim->pos[v1];
219  length_constraint->elem_position_b = cloth_sim->pos[v2];
220 
221  length_constraint->type = SCULPT_CLOTH_CONSTRAINT_STRUCTURAL;
222 
223  if (use_persistent) {
224  length_constraint->length = len_v3v3(SCULPT_vertex_persistent_co_get(ss, v1),
226  }
227  else {
228  length_constraint->length = len_v3v3(SCULPT_vertex_co_get(ss, v1),
229  SCULPT_vertex_co_get(ss, v2));
230  }
231  length_constraint->strength = 1.0f;
232 
233  cloth_sim->tot_length_constraints++;
234 
235  /* Reallocation if the array capacity is exceeded. */
237 
238  /* Add the constraint to the #GSet to avoid creating it again. */
240 }
241 
243  const int node_index,
244  const int v,
245  const float strength)
246 {
247  SculptClothLengthConstraint *length_constraint =
248  &cloth_sim->length_constraints[cloth_sim->tot_length_constraints];
249 
250  length_constraint->elem_index_a = v;
251  length_constraint->elem_index_b = v;
252 
253  length_constraint->node = node_index;
254 
255  length_constraint->elem_position_a = cloth_sim->pos[v];
256  length_constraint->elem_position_b = cloth_sim->softbody_pos[v];
257 
258  length_constraint->type = SCULPT_CLOTH_CONSTRAINT_SOFTBODY;
259 
260  length_constraint->length = 0.0f;
261  length_constraint->strength = strength;
262 
263  cloth_sim->tot_length_constraints++;
264 
265  /* Reallocation if the array capacity is exceeded. */
267 }
268 
270  const int node_index,
271  const int v,
272  const float strength)
273 {
274  SculptClothLengthConstraint *length_constraint =
275  &cloth_sim->length_constraints[cloth_sim->tot_length_constraints];
276 
277  length_constraint->elem_index_a = v;
278  length_constraint->elem_index_b = v;
279 
280  length_constraint->node = node_index;
281 
282  length_constraint->elem_position_a = cloth_sim->pos[v];
283  length_constraint->elem_position_b = cloth_sim->init_pos[v];
284 
285  length_constraint->type = SCULPT_CLOTH_CONSTRAINT_PIN;
286 
287  length_constraint->length = 0.0f;
288  length_constraint->strength = strength;
289 
290  cloth_sim->tot_length_constraints++;
291 
292  /* Reallocation if the array capacity is exceeded. */
294 }
295 
297  const int node_index,
298  const int v,
299  const float strength)
300 {
301  SculptClothLengthConstraint *length_constraint =
302  &cloth_sim->length_constraints[cloth_sim->tot_length_constraints];
303 
304  length_constraint->elem_index_a = v;
305  length_constraint->elem_index_b = v;
306 
307  length_constraint->node = node_index;
308 
309  length_constraint->type = SCULPT_CLOTH_CONSTRAINT_DEFORMATION;
310 
311  length_constraint->elem_position_a = cloth_sim->pos[v];
312  length_constraint->elem_position_b = cloth_sim->deformation_pos[v];
313 
314  length_constraint->length = 0.0f;
315  length_constraint->strength = strength;
316 
317  cloth_sim->tot_length_constraints++;
318 
319  /* Reallocation if the array capacity is exceeded. */
321 }
322 
324  void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls))
325 {
326  SculptThreadedTaskData *data = userdata;
327  SculptSession *ss = data->ob->sculpt;
328  const Brush *brush = data->brush;
329  PBVHNode *node = data->nodes[n];
330 
331  const int node_index = POINTER_AS_INT(BLI_ghash_lookup(data->cloth_sim->node_state_index, node));
332  if (data->cloth_sim->node_state[node_index] != SCULPT_CLOTH_NODE_UNINITIALIZED) {
333  /* The simulation already contains constraints for this node. */
334  return;
335  }
336 
337  PBVHVertexIter vd;
338 
339  const bool pin_simulation_boundary = ss->cache != NULL && brush != NULL &&
343 
344  const bool use_persistent = brush != NULL && brush->flag & BRUSH_PERSISTENT;
345 
346  /* Brush can be NULL in tools that use the solver without relying of constraints with deformation
347  * positions. */
348  const bool cloth_is_deform_brush = ss->cache != NULL && brush != NULL &&
350 
351  const bool use_falloff_plane = brush->cloth_force_falloff_type ==
353  float radius_squared = 0.0f;
354  if (cloth_is_deform_brush) {
355  radius_squared = ss->cache->initial_radius * ss->cache->initial_radius;
356  }
357 
358  /* Only limit the constraint creation to a radius when the simulation is local. */
359  const float cloth_sim_radius_squared = brush->cloth_simulation_area_type ==
361  data->cloth_sim_radius * data->cloth_sim_radius :
362  FLT_MAX;
363 
365  const float len_squared = len_squared_v3v3(vd.co, data->cloth_sim_initial_location);
366  if (len_squared < cloth_sim_radius_squared) {
367 
369  int build_indices[CLOTH_MAX_CONSTRAINTS_PER_VERTEX];
370  int tot_indices = 0;
371  build_indices[tot_indices] = vd.index;
372  tot_indices++;
374  build_indices[tot_indices] = ni.index;
375  tot_indices++;
376  }
378 
379  if (data->cloth_sim->softbody_strength > 0.0f) {
380  cloth_brush_add_softbody_constraint(data->cloth_sim, node_index, vd.index, 1.0f);
381  }
382 
383  /* As we don't know the order of the neighbor vertices, we create all possible combinations
384  * between the neighbor and the original vertex as length constraints. */
385  /* This results on a pattern that contains structural, shear and bending constraints for all
386  * vertices, but constraints are repeated taking more memory than necessary. */
387 
388  for (int c_i = 0; c_i < tot_indices; c_i++) {
389  for (int c_j = 0; c_j < tot_indices; c_j++) {
390  if (c_i != c_j && !cloth_brush_sim_has_length_constraint(
391  data->cloth_sim, build_indices[c_i], build_indices[c_j])) {
393  data->cloth_sim,
394  node_index,
395  build_indices[c_i],
396  build_indices[c_j],
397  use_persistent);
398  }
399  }
400  }
401  }
402 
403  if (brush && brush->sculpt_tool == SCULPT_TOOL_CLOTH) {
404  /* The cloth brush works by applying forces in most of its modes, but some of them require
405  * deformation coordinates to make the simulation stable. */
407  if (use_falloff_plane) {
408  /* With plane falloff the strength of the constraints is set when applying the
409  * deformation forces. */
411  data->cloth_sim, node_index, vd.index, CLOTH_DEFORMATION_GRAB_STRENGTH);
412  }
413  else if (len_squared < radius_squared) {
414  /* With radial falloff deformation constraints are created with different strengths and
415  * only inside the radius of the brush. */
416  const float fade = BKE_brush_curve_strength(
417  brush, sqrtf(len_squared), ss->cache->radius);
419  data->cloth_sim, node_index, vd.index, fade * CLOTH_DEFORMATION_GRAB_STRENGTH);
420  }
421  }
423  /* Cloth Snake Hook creates deformation constraint with fixed strength because the strength
424  * is controlled per iteration using cloth_sim->deformation_strength. */
426  data->cloth_sim, node_index, vd.index, CLOTH_DEFORMATION_SNAKEHOOK_STRENGTH);
427  }
428  }
429  else if (data->cloth_sim->deformation_pos) {
430  /* Any other tool that target the cloth simulation handle the falloff in
431  * their own code when modifying the deformation coordinates of the simulation, so
432  * deformation constraints are created with a fixed strength for all vertices. */
434  data->cloth_sim, node_index, vd.index, CLOTH_DEFORMATION_TARGET_STRENGTH);
435  }
436 
437  if (pin_simulation_boundary) {
438  const float sim_falloff = cloth_brush_simulation_falloff_get(
439  brush, ss->cache->initial_radius, ss->cache->location, vd.co);
440  /* Vertex is inside the area of the simulation without any falloff applied. */
441  if (sim_falloff < 1.0f) {
442  /* Create constraints with more strength the closer the vertex is to the simulation
443  * boundary. */
444  cloth_brush_add_pin_constraint(data->cloth_sim, node_index, vd.index, 1.0f - sim_falloff);
445  }
446  }
447  }
449 }
450 
452  SculptClothSimulation *cloth_sim,
453  const float force[3],
454  const int vertex_index)
455 {
456  madd_v3_v3fl(cloth_sim->acceleration[vertex_index], force, 1.0f / cloth_sim->mass);
457 }
458 
459 static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata,
460  const int n,
461  const TaskParallelTLS *__restrict tls)
462 {
463  SculptThreadedTaskData *data = userdata;
464  SculptSession *ss = data->ob->sculpt;
465  const Brush *brush = data->brush;
466  SculptClothSimulation *cloth_sim = ss->cache->cloth_sim;
467  const float *offset = data->offset;
468  const float *grab_delta = data->grab_delta;
469  float(*imat)[4] = data->mat;
470 
471  const bool use_falloff_plane = brush->cloth_force_falloff_type ==
473 
474  PBVHVertexIter vd;
475  const float bstrength = ss->cache->bstrength;
476 
477  SculptBrushTest test;
479  ss, &test, data->brush->falloff_shape);
480  const int thread_id = BLI_task_parallel_thread_id(tls);
481 
482  /* For Pinch Perpendicular Deform Type. */
483  float x_object_space[3];
484  float z_object_space[3];
486  normalize_v3_v3(x_object_space, imat[0]);
487  normalize_v3_v3(z_object_space, imat[2]);
488  }
489 
490  /* For Plane Force Falloff. */
491  float deform_plane[4];
492  float plane_normal[3];
493  if (use_falloff_plane) {
494  normalize_v3_v3(plane_normal, grab_delta);
495  plane_from_point_normal_v3(deform_plane, data->area_co, plane_normal);
496  }
497 
498  /* Gravity */
499  float gravity[3] = {0.0f};
500  if (ss->cache->supports_gravity) {
501  madd_v3_v3fl(gravity, ss->cache->gravity_direction, -data->sd->gravity_factor);
502  }
503 
504  BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
505  float force[3];
506  float sim_location[3];
507  cloth_brush_simulation_location_get(ss, brush, sim_location);
508  const float sim_factor = cloth_brush_simulation_falloff_get(
509  brush, ss->cache->radius, sim_location, cloth_sim->init_pos[vd.index]);
510 
511  float current_vertex_location[3];
513  copy_v3_v3(current_vertex_location, ss->cache->cloth_sim->init_pos[vd.index]);
514  }
515  else {
516  copy_v3_v3(current_vertex_location, vd.co);
517  }
518 
519  /* Apply gravity in the entire simulation area. */
520  float vertex_gravity[3];
521  mul_v3_v3fl(vertex_gravity, gravity, sim_factor);
522  cloth_brush_apply_force_to_vertex(ss, ss->cache->cloth_sim, vertex_gravity, vd.index);
523 
524  /* When using the plane falloff mode the falloff is not constrained by the brush radius. */
525  if (!sculpt_brush_test_sq_fn(&test, current_vertex_location) && !use_falloff_plane) {
526  continue;
527  }
528 
529  float dist = sqrtf(test.dist);
530 
531  if (use_falloff_plane) {
532  dist = dist_to_plane_v3(current_vertex_location, deform_plane);
533  }
534 
535  const float fade = sim_factor * bstrength *
537  brush,
538  current_vertex_location,
539  dist,
540  vd.no,
541  vd.fno,
542  vd.mask ? *vd.mask : 0.0f,
543  vd.index,
544  thread_id);
545 
546  float brush_disp[3];
547 
548  switch (brush->cloth_deform_type) {
550  sub_v3_v3v3(brush_disp, ss->cache->location, ss->cache->last_location);
551  normalize_v3(brush_disp);
552  mul_v3_v3fl(force, brush_disp, fade);
553  break;
555  /* Invert the fade to push inwards. */
556  mul_v3_v3fl(force, offset, -fade);
557  break;
559  madd_v3_v3v3fl(cloth_sim->deformation_pos[vd.index],
560  cloth_sim->init_pos[vd.index],
562  fade);
563  if (use_falloff_plane) {
564  cloth_sim->deformation_strength[vd.index] = clamp_f(fade, 0.0f, 1.0f);
565  }
566  else {
567  cloth_sim->deformation_strength[vd.index] = 1.0f;
568  }
569  zero_v3(force);
570  break;
572  copy_v3_v3(cloth_sim->deformation_pos[vd.index], cloth_sim->pos[vd.index]);
574  cloth_sim->deformation_strength[vd.index] = fade;
575  zero_v3(force);
576  break;
578  if (use_falloff_plane) {
579  float distance = dist_signed_to_plane_v3(vd.co, deform_plane);
580  copy_v3_v3(brush_disp, plane_normal);
581  mul_v3_fl(brush_disp, -distance);
582  }
583  else {
584  sub_v3_v3v3(brush_disp, ss->cache->location, vd.co);
585  }
586  normalize_v3(brush_disp);
587  mul_v3_v3fl(force, brush_disp, fade);
588  break;
590  float disp_center[3];
591  float x_disp[3];
592  float z_disp[3];
593  sub_v3_v3v3(disp_center, ss->cache->location, vd.co);
594  normalize_v3(disp_center);
595  mul_v3_v3fl(x_disp, x_object_space, dot_v3v3(disp_center, x_object_space));
596  mul_v3_v3fl(z_disp, z_object_space, dot_v3v3(disp_center, z_object_space));
597  add_v3_v3v3(disp_center, x_disp, z_disp);
598  mul_v3_v3fl(force, disp_center, fade);
599  } break;
601  mul_v3_v3fl(force, vd.no ? vd.no : vd.fno, fade);
602  break;
604  cloth_sim->length_constraint_tweak[vd.index] += fade * 0.1f;
605  zero_v3(force);
606  break;
607  }
608 
610  }
612 }
613 
615 {
616  ListBase *cache = NULL;
618  ob,
621  if (STREQ(object->id.name, ob->id.name)) {
622  continue;
623  }
624 
627  if (!cmd) {
628  continue;
629  }
630 
631  if (!cmd->bvhtree) {
632  continue;
633  }
634  if (cache == NULL) {
635  cache = MEM_callocN(sizeof(ListBase), "ColliderCache array");
636  }
637 
638  ColliderCache *col = MEM_callocN(sizeof(ColliderCache), "ColliderCache");
639  col->ob = ob;
640  col->collmd = cmd;
641  collision_move_object(cmd, 1.0, 0.0, true);
642  BLI_addtail(cache, col);
643  }
645  return cache;
646 }
647 
648 typedef struct ClothBrushCollision {
652 
653 static void cloth_brush_collision_cb(void *userdata,
654  int index,
655  const BVHTreeRay *ray,
656  BVHTreeRayHit *hit)
657 {
659  CollisionModifierData *col_data = col->col_data;
660  MVertTri *verttri = &col_data->tri[index];
661  MVert *mverts = col_data->x;
662  float *tri[3], no[3], co[3];
663 
664  tri[0] = mverts[verttri->tri[0]].co;
665  tri[1] = mverts[verttri->tri[1]].co;
666  tri[2] = mverts[verttri->tri[2]].co;
667  float dist = 0.0f;
668 
669  bool tri_hit = isect_ray_tri_watertight_v3(
670  ray->origin, &col->isect_precalc, UNPACK3(tri), &dist, NULL);
671  normal_tri_v3(no, UNPACK3(tri));
672  madd_v3_v3v3fl(co, ray->origin, ray->direction, dist);
673 
674  if (tri_hit && dist < hit->dist) {
675  hit->index = index;
676  hit->dist = dist;
677 
678  copy_v3_v3(hit->co, co);
679  copy_v3_v3(hit->no, no);
680  }
681 }
682 
684  SculptClothSimulation *cloth_sim,
685  const int i)
686 {
687  const int raycast_flag = BVH_RAYCAST_DEFAULT & ~(BVH_RAYCAST_WATERTIGHT);
688 
689  ColliderCache *collider_cache;
690  BVHTreeRayHit hit;
691 
692  float obmat_inv[4][4];
693  invert_m4_m4(obmat_inv, object->obmat);
694 
695  for (collider_cache = cloth_sim->collider_list->first; collider_cache;
696  collider_cache = collider_cache->next) {
697  float ray_start[3], ray_normal[3];
698  float pos_world_space[3], prev_pos_world_space[3];
699 
700  mul_v3_m4v3(pos_world_space, object->obmat, cloth_sim->pos[i]);
701  mul_v3_m4v3(prev_pos_world_space, object->obmat, cloth_sim->last_iteration_pos[i]);
702  sub_v3_v3v3(ray_normal, pos_world_space, prev_pos_world_space);
703  copy_v3_v3(ray_start, prev_pos_world_space);
704  hit.index = -1;
705  hit.dist = len_v3(ray_normal);
706  normalize_v3(ray_normal);
707 
709  CollisionModifierData *collmd = collider_cache->collmd;
710  col.col_data = collmd;
711  isect_ray_tri_watertight_v3_precalc(&col.isect_precalc, ray_normal);
712 
714  ray_start,
715  ray_normal,
716  0.3f,
717  &hit,
719  &col,
720  raycast_flag);
721 
722  if (hit.index == -1) {
723  continue;
724  }
725 
726  float collision_disp[3];
727  float movement_disp[3];
728  mul_v3_v3fl(collision_disp, hit.no, 0.005f);
729  sub_v3_v3v3(movement_disp, pos_world_space, prev_pos_world_space);
730  float friction_plane[4];
731  float pos_on_friction_plane[3];
732  plane_from_point_normal_v3(friction_plane, hit.co, hit.no);
733  closest_to_plane_v3(pos_on_friction_plane, friction_plane, pos_world_space);
734  sub_v3_v3v3(movement_disp, pos_on_friction_plane, hit.co);
735 
736  /* TODO(pablodp606): This can be exposed in a brush/filter property as friction. */
737  mul_v3_fl(movement_disp, 0.35f);
738 
739  copy_v3_v3(cloth_sim->pos[i], hit.co);
740  add_v3_v3(cloth_sim->pos[i], movement_disp);
741  add_v3_v3(cloth_sim->pos[i], collision_disp);
742  mul_v3_m4v3(cloth_sim->pos[i], obmat_inv, cloth_sim->pos[i]);
743  }
744 }
745 
747  void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls))
748 {
749  SculptThreadedTaskData *data = userdata;
750  SculptSession *ss = data->ob->sculpt;
751  const Brush *brush = data->brush;
752 
753  PBVHNode *node = data->nodes[n];
754  PBVHVertexIter vd;
755  SculptClothSimulation *cloth_sim = data->cloth_sim;
756  const float time_step = data->cloth_time_step;
757 
758  const int node_index = POINTER_AS_INT(BLI_ghash_lookup(data->cloth_sim->node_state_index, node));
759  if (data->cloth_sim->node_state[node_index] != SCULPT_CLOTH_NODE_ACTIVE) {
760  return;
761  }
762 
764 
765  BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
766  float sim_location[3];
767  cloth_brush_simulation_location_get(ss, brush, sim_location);
768  const float sim_factor =
770  brush, ss->cache->radius, sim_location, cloth_sim->init_pos[vd.index]) :
771  1.0f;
772  if (sim_factor <= 0.0f) {
773  continue;
774  }
775 
776  int i = vd.index;
777  float temp[3];
778  copy_v3_v3(temp, cloth_sim->pos[i]);
779 
780  mul_v3_fl(cloth_sim->acceleration[i], time_step);
781 
782  float pos_diff[3];
783  sub_v3_v3v3(pos_diff, cloth_sim->pos[i], cloth_sim->prev_pos[i]);
784  mul_v3_fl(pos_diff, (1.0f - cloth_sim->damping) * sim_factor);
785 
786  const float mask_v = (1.0f - (vd.mask ? *vd.mask : 0.0f)) *
787  SCULPT_automasking_factor_get(automasking, ss, vd.index);
788 
789  madd_v3_v3fl(cloth_sim->pos[i], pos_diff, mask_v);
790  madd_v3_v3fl(cloth_sim->pos[i], cloth_sim->acceleration[i], mask_v);
791 
792  if (cloth_sim->collider_list != NULL) {
793  cloth_brush_solve_collision(data->ob, cloth_sim, i);
794  }
795 
796  copy_v3_v3(cloth_sim->last_iteration_pos[i], cloth_sim->pos[i]);
797 
798  copy_v3_v3(cloth_sim->prev_pos[i], temp);
799  copy_v3_v3(cloth_sim->last_iteration_pos[i], cloth_sim->pos[i]);
800  copy_v3_fl(cloth_sim->acceleration[i], 0.0f);
801 
802  copy_v3_v3(vd.co, cloth_sim->pos[vd.index]);
803 
804  if (vd.mvert) {
806  }
807  }
809 
810  /* Disable the simulation on this node, it needs to be enabled again to continue. */
811  cloth_sim->node_state[node_index] = SCULPT_CLOTH_NODE_INACTIVE;
812 }
813 
815  Brush *brush,
816  SculptClothSimulation *cloth_sim)
817 {
818 
820 
821  for (int constraint_it = 0; constraint_it < CLOTH_SIMULATION_ITERATIONS; constraint_it++) {
822  for (int i = 0; i < cloth_sim->tot_length_constraints; i++) {
823  const SculptClothLengthConstraint *constraint = &cloth_sim->length_constraints[i];
824 
825  if (cloth_sim->node_state[constraint->node] != SCULPT_CLOTH_NODE_ACTIVE) {
826  /* Skip all constraints that were created for inactive nodes. */
827  continue;
828  }
829 
830  const int v1 = constraint->elem_index_a;
831  const int v2 = constraint->elem_index_b;
832 
833  float v1_to_v2[3];
834  sub_v3_v3v3(v1_to_v2, constraint->elem_position_b, constraint->elem_position_a);
835  const float current_distance = len_v3(v1_to_v2);
836  float correction_vector[3];
837  float correction_vector_half[3];
838 
839  const float constraint_distance = constraint->length +
840  (cloth_sim->length_constraint_tweak[v1] * 0.5f) +
841  (cloth_sim->length_constraint_tweak[v2] * 0.5f);
842 
843  if (current_distance > 0.0f) {
844  mul_v3_v3fl(correction_vector,
845  v1_to_v2,
847  (1.0f - (constraint_distance / current_distance)));
848  }
849  else {
850  mul_v3_v3fl(correction_vector, v1_to_v2, CLOTH_SOLVER_DISPLACEMENT_FACTOR);
851  }
852 
853  mul_v3_v3fl(correction_vector_half, correction_vector, 0.5f);
854 
855  const float mask_v1 = (1.0f - SCULPT_vertex_mask_get(ss, v1)) *
856  SCULPT_automasking_factor_get(automasking, ss, v1);
857  const float mask_v2 = (1.0f - SCULPT_vertex_mask_get(ss, v2)) *
858  SCULPT_automasking_factor_get(automasking, ss, v2);
859 
860  float sim_location[3];
861  cloth_brush_simulation_location_get(ss, brush, sim_location);
862 
863  const float sim_factor_v1 = ss->cache ?
865  ss->cache->radius,
866  sim_location,
867  cloth_sim->init_pos[v1]) :
868  1.0f;
869  const float sim_factor_v2 = ss->cache ?
871  ss->cache->radius,
872  sim_location,
873  cloth_sim->init_pos[v2]) :
874  1.0f;
875 
876  float deformation_strength = 1.0f;
877  if (constraint->type == SCULPT_CLOTH_CONSTRAINT_DEFORMATION) {
878  deformation_strength = (cloth_sim->deformation_strength[v1] +
879  cloth_sim->deformation_strength[v2]) *
880  0.5f;
881  }
882 
883  if (constraint->type == SCULPT_CLOTH_CONSTRAINT_SOFTBODY) {
884  const float softbody_plasticity = brush ? brush->cloth_constraint_softbody_strength : 0.0f;
885  madd_v3_v3fl(cloth_sim->pos[v1],
886  correction_vector_half,
887  1.0f * mask_v1 * sim_factor_v1 * constraint->strength * softbody_plasticity);
888  madd_v3_v3fl(cloth_sim->softbody_pos[v1],
889  correction_vector_half,
890  -1.0f * mask_v1 * sim_factor_v1 * constraint->strength *
891  (1.0f - softbody_plasticity));
892  }
893  else {
894  madd_v3_v3fl(cloth_sim->pos[v1],
895  correction_vector_half,
896  1.0f * mask_v1 * sim_factor_v1 * constraint->strength * deformation_strength);
897  if (v1 != v2) {
898  madd_v3_v3fl(cloth_sim->pos[v2],
899  correction_vector_half,
900  -1.0f * mask_v2 * sim_factor_v2 * constraint->strength *
901  deformation_strength);
902  }
903  }
904  }
905  }
906 }
907 
909  Sculpt *sd, Object *ob, SculptClothSimulation *cloth_sim, PBVHNode **nodes, int totnode)
910 {
911  SculptSession *ss = ob->sculpt;
912  Brush *brush = BKE_paint_brush(&sd->paint);
913 
914  /* Update the constraints. */
915  cloth_brush_satisfy_constraints(ss, brush, cloth_sim);
916 
917  /* Solve the simulation and write the final step to the mesh. */
918  SculptThreadedTaskData solve_simulation_data = {
919  .sd = sd,
920  .ob = ob,
921  .brush = brush,
922  .nodes = nodes,
923  .cloth_time_step = CLOTH_SIMULATION_TIME_STEP,
924  .cloth_sim = cloth_sim,
925  };
926 
927  TaskParallelSettings settings;
928  BKE_pbvh_parallel_range_settings(&settings, true, totnode);
930  0, totnode, &solve_simulation_data, do_cloth_brush_solve_simulation_task_cb_ex, &settings);
931 }
932 
933 static void cloth_brush_apply_brush_foces(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
934 {
935  SculptSession *ss = ob->sculpt;
936  Brush *brush = BKE_paint_brush(&sd->paint);
937 
938  float grab_delta[3];
939  float mat[4][4];
940  float area_no[3];
941  float area_co[3];
942  float imat[4][4];
943  float offset[3];
944 
945  SculptThreadedTaskData apply_forces_data = {
946  .sd = sd,
947  .ob = ob,
948  .brush = brush,
949  .nodes = nodes,
950  .area_no = area_no,
951  .area_co = area_co,
952  .mat = imat,
953  };
954 
956 
957  /* Initialize the grab delta. */
958  copy_v3_v3(grab_delta, ss->cache->grab_delta_symmetry);
959  normalize_v3(grab_delta);
960 
961  apply_forces_data.grab_delta = grab_delta;
962 
964  return;
965  }
966 
967  /* Calculate push offset. */
968 
971  mul_v3_v3(offset, ss->cache->scale);
972  mul_v3_fl(offset, 2.0f);
973 
974  apply_forces_data.offset = offset;
975  }
976 
979  SCULPT_calc_brush_plane(sd, ob, nodes, totnode, area_no, area_co);
980 
981  /* Initialize stroke local space matrix. */
982  cross_v3_v3v3(mat[0], area_no, ss->cache->grab_delta_symmetry);
983  mat[0][3] = 0.0f;
984  cross_v3_v3v3(mat[1], area_no, mat[0]);
985  mat[1][3] = 0.0f;
986  copy_v3_v3(mat[2], area_no);
987  mat[2][3] = 0.0f;
988  copy_v3_v3(mat[3], ss->cache->location);
989  mat[3][3] = 1.0f;
990  normalize_m4(mat);
991 
992  apply_forces_data.area_co = area_co;
993  apply_forces_data.area_no = area_no;
994  apply_forces_data.mat = mat;
995 
996  /* Update matrix for the cursor preview. */
997  if (ss->cache->mirror_symmetry_pass == 0) {
998  copy_m4_m4(ss->cache->stroke_local_mat, mat);
999  }
1000  }
1001 
1003  /* Set the deformation strength to 0. Brushes will initialize the strength in the required
1004  * area. */
1005  const int totverts = SCULPT_vertex_count_get(ss);
1006  for (int i = 0; i < totverts; i++) {
1007  ss->cache->cloth_sim->deformation_strength[i] = 0.0f;
1008  }
1009  }
1010 
1011  TaskParallelSettings settings;
1012  BKE_pbvh_parallel_range_settings(&settings, true, totnode);
1014  0, totnode, &apply_forces_data, do_cloth_brush_apply_forces_task_cb_ex, &settings);
1015 }
1016 
1017 /* Allocates nodes state and initializes them to Uninitialized, so constraints can be created for
1018  * them. */
1020  SculptClothSimulation *cloth_sim)
1021 {
1022  PBVHNode **nodes;
1023  int totnode;
1024  BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
1025 
1026  cloth_sim->node_state = MEM_malloc_arrayN(
1027  totnode, sizeof(eSculptClothNodeSimState), "node sim state");
1028  cloth_sim->node_state_index = BLI_ghash_ptr_new("node sim state indices");
1029  for (int i = 0; i < totnode; i++) {
1031  BLI_ghash_insert(cloth_sim->node_state_index, nodes[i], POINTER_FROM_INT(i));
1032  }
1033  MEM_SAFE_FREE(nodes);
1034 }
1035 
1037  const float cloth_mass,
1038  const float cloth_damping,
1039  const float cloth_softbody_strength,
1040  const bool use_collisions,
1041  const bool needs_deform_coords)
1042 {
1043  SculptSession *ss = ob->sculpt;
1044  const int totverts = SCULPT_vertex_count_get(ss);
1045  SculptClothSimulation *cloth_sim;
1046 
1047  cloth_sim = MEM_callocN(sizeof(SculptClothSimulation), "cloth constraints");
1048 
1051  "cloth length constraints");
1053 
1054  cloth_sim->acceleration = MEM_calloc_arrayN(
1055  totverts, sizeof(float[3]), "cloth sim acceleration");
1056  cloth_sim->pos = MEM_calloc_arrayN(totverts, sizeof(float[3]), "cloth sim pos");
1057  cloth_sim->prev_pos = MEM_calloc_arrayN(totverts, sizeof(float[3]), "cloth sim prev pos");
1059  totverts, sizeof(float[3]), "cloth sim last iteration pos");
1060  cloth_sim->init_pos = MEM_calloc_arrayN(totverts, sizeof(float[3]), "cloth sim init pos");
1062  totverts, sizeof(float), "cloth sim length tweak");
1063 
1064  if (needs_deform_coords) {
1065  cloth_sim->deformation_pos = MEM_calloc_arrayN(
1066  totverts, sizeof(float[3]), "cloth sim deformation positions");
1068  totverts, sizeof(float), "cloth sim deformation strength");
1069  }
1070 
1071  if (cloth_softbody_strength > 0.0f) {
1072  cloth_sim->softbody_pos = MEM_calloc_arrayN(
1073  totverts, sizeof(float[3]), "cloth sim softbody pos");
1074  }
1075 
1076  cloth_sim->mass = cloth_mass;
1077  cloth_sim->damping = cloth_damping;
1078  cloth_sim->softbody_strength = cloth_softbody_strength;
1079 
1080  if (use_collisions) {
1082  }
1083 
1085 
1086  return cloth_sim;
1087 }
1088 
1090  Sculpt *sd,
1091  Object *ob,
1092  PBVHNode **nodes,
1093  int totnode,
1094  SculptClothSimulation *cloth_sim,
1095  /* Cannot be `const`, because it is assigned to a `non-const` variable.
1096  * NOLINTNEXTLINE: readability-non-const-parameter. */
1097  float initial_location[3],
1098  const float radius)
1099 {
1100  Brush *brush = BKE_paint_brush(&sd->paint);
1101 
1102  /* TODO: Multi-threaded needs to be disabled for this task until implementing the optimization of
1103  * storing the constraints per node. */
1104  /* Currently all constrains are added to the same global array which can't be accessed from
1105  * different threads. */
1106  TaskParallelSettings settings;
1107  BKE_pbvh_parallel_range_settings(&settings, false, totnode);
1108 
1109  cloth_sim->created_length_constraints = BLI_edgeset_new("created length constraints");
1110 
1111  SculptThreadedTaskData build_constraints_data = {
1112  .sd = sd,
1113  .ob = ob,
1114  .brush = brush,
1115  .nodes = nodes,
1116  .cloth_sim = cloth_sim,
1117  .cloth_sim_initial_location = initial_location,
1118  .cloth_sim_radius = radius,
1119  };
1121  0, totnode, &build_constraints_data, do_cloth_brush_build_constraints_task_cb_ex, &settings);
1122 
1124 }
1125 
1127 {
1128  const int totverts = SCULPT_vertex_count_get(ss);
1129  const bool has_deformation_pos = cloth_sim->deformation_pos != NULL;
1130  const bool has_softbody_pos = cloth_sim->softbody_pos != NULL;
1131  for (int i = 0; i < totverts; i++) {
1132  copy_v3_v3(cloth_sim->last_iteration_pos[i], SCULPT_vertex_co_get(ss, i));
1133  copy_v3_v3(cloth_sim->init_pos[i], SCULPT_vertex_co_get(ss, i));
1134  copy_v3_v3(cloth_sim->prev_pos[i], SCULPT_vertex_co_get(ss, i));
1135  if (has_deformation_pos) {
1136  copy_v3_v3(cloth_sim->deformation_pos[i], SCULPT_vertex_co_get(ss, i));
1137  cloth_sim->deformation_strength[i] = 1.0f;
1138  }
1139  if (has_softbody_pos) {
1140  copy_v3_v3(cloth_sim->softbody_pos[i], SCULPT_vertex_co_get(ss, i));
1141  }
1142  }
1143 }
1144 
1146 {
1147  const int totverts = SCULPT_vertex_count_get(ss);
1148  for (int i = 0; i < totverts; i++) {
1149  copy_v3_v3(cloth_sim->pos[i], SCULPT_vertex_co_get(ss, i));
1150  }
1151 }
1152 
1154  PBVHNode **nodes,
1155  int totnode)
1156 {
1157  /* Activate the nodes inside the simulation area. */
1158  for (int n = 0; n < totnode; n++) {
1159  const int node_index = POINTER_AS_INT(BLI_ghash_lookup(cloth_sim->node_state_index, nodes[n]));
1160  cloth_sim->node_state[node_index] = SCULPT_CLOTH_NODE_ACTIVE;
1161  }
1162 }
1163 
1165  Object *ob,
1166  PBVHNode **nodes,
1167  int totnode)
1168 {
1169  SculptSession *ss = ob->sculpt;
1170  Brush *brush = BKE_paint_brush(&sd->paint);
1171  const float radius = ss->cache->initial_radius;
1172  const float limit = radius + (radius * brush->cloth_sim_limit);
1173  float sim_location[3];
1174  cloth_brush_simulation_location_get(ss, brush, sim_location);
1176  sd, ob, nodes, totnode, ss->cache->cloth_sim, sim_location, limit);
1177 }
1178 
1179 void SCULPT_do_cloth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
1180 {
1181  SculptSession *ss = ob->sculpt;
1182  Brush *brush = BKE_paint_brush(&sd->paint);
1183 
1184  /* Brushes that use anchored strokes and restore the mesh can't rely on symmetry passes and steps
1185  * count as it is always the first step, so the simulation needs to be created when it does not
1186  * exist for this stroke. */
1188 
1189  /* The simulation structure only needs to be created on the first symmetry pass. */
1192  ob,
1193  brush->cloth_mass,
1194  brush->cloth_damping,
1196  (brush->flag2 & BRUSH_CLOTH_USE_COLLISION),
1199  }
1200 
1202  /* When using simulation a fixed local simulation area, constraints are created only using
1203  * the initial stroke position and initial radius (per symmetry pass) instead of per node.
1204  * This allows to skip unnecessary constraints that will never be simulated, making the
1205  * solver faster. When the simulation starts for a node, the node gets activated and all its
1206  * constraints are considered final. As the same node can be included inside the brush radius
1207  * from multiple symmetry passes, the cloth brush can't activate the node for simulation yet
1208  * as this will cause the ensure constraints function to skip the node in the next symmetry
1209  * passes. It needs to build the constraints here and skip simulating the first step, so all
1210  * passes can add their constraints to all affected nodes. */
1212  }
1213  /* The first step of a symmetry pass is never simulated as deformation modes need valid delta
1214  * for brush tip alignment. */
1215  return;
1216  }
1217 
1218  /* Ensure the constraints for the nodes. */
1220 
1221  /* Store the initial state in the simulation. */
1223 
1224  /* Enable the nodes that should be simulated. */
1225  SCULPT_cloth_sim_activate_nodes(ss->cache->cloth_sim, nodes, totnode);
1226 
1227  /* Apply forces to the vertices. */
1228  cloth_brush_apply_brush_foces(sd, ob, nodes, totnode);
1229 
1230  /* Update and write the simulation to the nodes. */
1231  SCULPT_cloth_brush_do_simulation_step(sd, ob, ss->cache->cloth_sim, nodes, totnode);
1232 }
1233 
1235 {
1236  MEM_SAFE_FREE(cloth_sim->pos);
1237  MEM_SAFE_FREE(cloth_sim->last_iteration_pos);
1238  MEM_SAFE_FREE(cloth_sim->prev_pos);
1239  MEM_SAFE_FREE(cloth_sim->acceleration);
1240  MEM_SAFE_FREE(cloth_sim->length_constraints);
1242  MEM_SAFE_FREE(cloth_sim->deformation_pos);
1243  MEM_SAFE_FREE(cloth_sim->softbody_pos);
1244  MEM_SAFE_FREE(cloth_sim->init_pos);
1245  MEM_SAFE_FREE(cloth_sim->deformation_strength);
1246  MEM_SAFE_FREE(cloth_sim->node_state);
1247  BLI_ghash_free(cloth_sim->node_state_index, NULL, NULL);
1248  if (cloth_sim->collider_list) {
1250  }
1251  MEM_SAFE_FREE(cloth_sim);
1252 }
1253 
1255  const Brush *brush,
1256  const float location[3],
1257  const float normal[3],
1258  const float rds,
1259  const float line_width,
1260  const float outline_col[3],
1261  const float alpha)
1262 {
1263  float cursor_trans[4][4], cursor_rot[4][4];
1264  const float z_axis[4] = {0.0f, 0.0f, 1.0f, 0.0f};
1265  float quat[4];
1266  unit_m4(cursor_trans);
1267  translate_m4(cursor_trans, location[0], location[1], location[2]);
1268  rotation_between_vecs_to_quat(quat, z_axis, normal);
1269  quat_to_mat4(cursor_rot, quat);
1270  GPU_matrix_push();
1271  GPU_matrix_mul(cursor_trans);
1272  GPU_matrix_mul(cursor_rot);
1273 
1274  GPU_line_width(line_width);
1275  immUniformColor3fvAlpha(outline_col, alpha * 0.5f);
1277  gpuattr, 0, 0, rds + (rds * brush->cloth_sim_limit * brush->cloth_sim_falloff), 320);
1278  immUniformColor3fvAlpha(outline_col, alpha * 0.7f);
1279  imm_draw_circle_wire_3d(gpuattr, 0, 0, rds + rds * brush->cloth_sim_limit, 80);
1280  GPU_matrix_pop();
1281 }
1282 
1284  SculptSession *ss,
1285  const float outline_col[3],
1286  float outline_alpha)
1287 {
1288  float local_mat[4][4];
1289  copy_m4_m4(local_mat, ss->cache->stroke_local_mat);
1290 
1292  add_v3_v3v3(local_mat[3], ss->cache->true_location, ss->cache->grab_delta);
1293  }
1294 
1295  GPU_matrix_mul(local_mat);
1296 
1297  const float dist = ss->cache->radius;
1298  const float arrow_x = ss->cache->radius * 0.2f;
1299  const float arrow_y = ss->cache->radius * 0.1f;
1300 
1301  immUniformColor3fvAlpha(outline_col, outline_alpha);
1302  GPU_line_width(2.0f);
1304  immVertex3f(gpuattr, dist, 0.0f, 0.0f);
1305  immVertex3f(gpuattr, -dist, 0.0f, 0.0f);
1306  immEnd();
1307 
1308  immBegin(GPU_PRIM_TRIS, 6);
1309  immVertex3f(gpuattr, dist, 0.0f, 0.0f);
1310  immVertex3f(gpuattr, dist - arrow_x, arrow_y, 0.0f);
1311  immVertex3f(gpuattr, dist - arrow_x, -arrow_y, 0.0f);
1312 
1313  immVertex3f(gpuattr, -dist, 0.0f, 0.0f);
1314  immVertex3f(gpuattr, -dist + arrow_x, arrow_y, 0.0f);
1315  immVertex3f(gpuattr, -dist + arrow_x, -arrow_y, 0.0f);
1316 
1317  immEnd();
1318 }
1319 
1320 /* Cloth Filter. */
1321 
1329 
1331  {CLOTH_FILTER_GRAVITY, "GRAVITY", 0, "Gravity", "Applies gravity to the simulation"},
1332  {CLOTH_FILTER_INFLATE, "INFLATE", 0, "Inflate", "Inflates the cloth"},
1333  {CLOTH_FILTER_EXPAND, "EXPAND", 0, "Expand", "Expands the cloth's dimensions"},
1334  {CLOTH_FILTER_PINCH, "PINCH", 0, "Pinch", "Pulls the cloth to the cursor's start position"},
1336  "SCALE",
1337  0,
1338  "Scale",
1339  "Scales the mesh as a soft body using the origin of the object as scale"},
1340  {0, NULL, 0, NULL, NULL},
1341 };
1342 
1345  "LOCAL",
1346  0,
1347  "Local",
1348  "Use the local axis to limit the force and set the gravity direction"},
1350  "WORLD",
1351  0,
1352  "World",
1353  "Use the global axis to limit the force and set the gravity direction"},
1355  "VIEW",
1356  0,
1357  "View",
1358  "Use the view axis to limit the force and set the gravity direction"},
1359  {0, NULL, 0, NULL, NULL},
1360 };
1361 
1367 
1369  {CLOTH_FILTER_FORCE_X, "X", 0, "X", "Apply force in the X axis"},
1370  {CLOTH_FILTER_FORCE_Y, "Y", 0, "Y", "Apply force in the Y axis"},
1371  {CLOTH_FILTER_FORCE_Z, "Z", 0, "Z", "Apply force in the Z axis"},
1372  {0, NULL, 0, NULL, NULL},
1373 };
1374 
1376 {
1377  return ELEM(filter_type, CLOTH_FILTER_SCALE);
1378 }
1379 
1380 static void cloth_filter_apply_displacement_to_deform_co(const int v_index,
1381  const float disp[3],
1382  FilterCache *filter_cache)
1383 {
1384  float final_disp[3];
1385  copy_v3_v3(final_disp, disp);
1386  SCULPT_filter_zero_disabled_axis_components(final_disp, filter_cache);
1387  add_v3_v3v3(filter_cache->cloth_sim->deformation_pos[v_index],
1388  filter_cache->cloth_sim->init_pos[v_index],
1389  final_disp);
1390 }
1391 
1392 static void cloth_filter_apply_forces_to_vertices(const int v_index,
1393  const float force[3],
1394  const float gravity[3],
1395  FilterCache *filter_cache)
1396 {
1397  float final_force[3];
1398  copy_v3_v3(final_force, force);
1399  SCULPT_filter_zero_disabled_axis_components(final_force, filter_cache);
1400  add_v3_v3(final_force, gravity);
1401  cloth_brush_apply_force_to_vertex(NULL, filter_cache->cloth_sim, final_force, v_index);
1402 }
1403 
1404 static void cloth_filter_apply_forces_task_cb(void *__restrict userdata,
1405  const int i,
1406  const TaskParallelTLS *__restrict UNUSED(tls))
1407 {
1408  SculptThreadedTaskData *data = userdata;
1409  Sculpt *sd = data->sd;
1410  SculptSession *ss = data->ob->sculpt;
1411  PBVHNode *node = data->nodes[i];
1412 
1413  SculptClothSimulation *cloth_sim = ss->filter_cache->cloth_sim;
1414 
1415  const eSculptClothFilterType filter_type = data->filter_type;
1416  const bool is_deformation_filter = cloth_filter_is_deformation_filter(filter_type);
1417 
1418  float sculpt_gravity[3] = {0.0f};
1419  if (sd->gravity_object) {
1420  copy_v3_v3(sculpt_gravity, sd->gravity_object->obmat[2]);
1421  }
1422  else {
1423  sculpt_gravity[2] = -1.0f;
1424  }
1425  mul_v3_fl(sculpt_gravity, sd->gravity_factor * data->filter_strength);
1426 
1427  PBVHVertexIter vd;
1429  float fade = vd.mask ? *vd.mask : 0.0f;
1431  fade = 1.0f - fade;
1432  float force[3] = {0.0f, 0.0f, 0.0f};
1433  float disp[3], temp[3], transform[3][3];
1434 
1437  continue;
1438  }
1439  }
1440 
1441  switch (filter_type) {
1442  case CLOTH_FILTER_GRAVITY:
1444  /* When using the view orientation apply gravity in the -Y axis, this way objects will
1445  * fall down instead of backwards. */
1446  force[1] = -data->filter_strength * fade;
1447  }
1448  else {
1449  force[2] = -data->filter_strength * fade;
1450  }
1452  break;
1453  case CLOTH_FILTER_INFLATE: {
1454  float normal[3];
1456  mul_v3_v3fl(force, normal, fade * data->filter_strength);
1457  } break;
1458  case CLOTH_FILTER_EXPAND:
1459  cloth_sim->length_constraint_tweak[vd.index] += fade * data->filter_strength * 0.01f;
1460  zero_v3(force);
1461  break;
1462  case CLOTH_FILTER_PINCH:
1464  normalize_v3(force);
1465  mul_v3_fl(force, fade * data->filter_strength);
1466  break;
1467  case CLOTH_FILTER_SCALE:
1468  unit_m3(transform);
1469  scale_m3_fl(transform, 1.0f + (fade * data->filter_strength));
1470  copy_v3_v3(temp, cloth_sim->init_pos[vd.index]);
1471  mul_m3_v3(transform, temp);
1472  sub_v3_v3v3(disp, temp, cloth_sim->init_pos[vd.index]);
1473  zero_v3(force);
1474 
1475  break;
1476  }
1477 
1478  if (is_deformation_filter) {
1480  }
1481  else {
1482  cloth_filter_apply_forces_to_vertices(vd.index, force, sculpt_gravity, ss->filter_cache);
1483  }
1484  }
1486 
1488 }
1489 
1490 static int sculpt_cloth_filter_modal(bContext *C, wmOperator *op, const wmEvent *event)
1491 {
1494  SculptSession *ss = ob->sculpt;
1496  int filter_type = RNA_enum_get(op->ptr, "type");
1497  float filter_strength = RNA_float_get(op->ptr, "strength");
1498 
1499  if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
1503  return OPERATOR_FINISHED;
1504  }
1505 
1506  if (event->type != MOUSEMOVE) {
1507  return OPERATOR_RUNNING_MODAL;
1508  }
1509 
1510  const float len = event->prev_press_xy[0] - event->xy[0];
1511  filter_strength = filter_strength * -len * 0.001f * UI_DPI_FAC;
1512 
1514 
1515  BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);
1516 
1517  const int totverts = SCULPT_vertex_count_get(ss);
1518 
1519  for (int i = 0; i < totverts; i++) {
1521  }
1522 
1524  .sd = sd,
1525  .ob = ob,
1526  .nodes = ss->filter_cache->nodes,
1527  .filter_type = filter_type,
1528  .filter_strength = filter_strength,
1529  };
1530 
1531  TaskParallelSettings settings;
1532  BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode);
1535 
1536  /* Activate all nodes. */
1539 
1540  /* Update and write the simulation to the nodes. */
1542  sd, ob, ss->filter_cache->cloth_sim, ss->filter_cache->nodes, ss->filter_cache->totnode);
1543 
1544  if (ss->deform_modifiers_active || ss->shapekey_active) {
1545  SCULPT_flush_stroke_deform(sd, ob, true);
1546  }
1548  return OPERATOR_RUNNING_MODAL;
1549 }
1550 
1551 static int sculpt_cloth_filter_invoke(bContext *C, wmOperator *op, const wmEvent *event)
1552 {
1556  SculptSession *ss = ob->sculpt;
1557 
1558  const eSculptClothFilterType filter_type = RNA_enum_get(op->ptr, "type");
1559 
1560  /* Update the active vertex */
1561  float mval_fl[2] = {UNPACK2(event->mval)};
1563  SCULPT_cursor_geometry_info_update(C, &sgi, mval_fl, false);
1564 
1566 
1567  /* Needs mask data to be available as it is used when solving the constraints. */
1568  BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);
1569 
1570  SCULPT_undo_push_begin(ob, "Cloth filter");
1572 
1574 
1575  const float cloth_mass = RNA_float_get(op->ptr, "cloth_mass");
1576  const float cloth_damping = RNA_float_get(op->ptr, "cloth_damping");
1577  const bool use_collisions = RNA_boolean_get(op->ptr, "use_collisions");
1579  ob,
1580  cloth_mass,
1581  cloth_damping,
1582  0.0f,
1583  use_collisions,
1584  cloth_filter_is_deformation_filter(filter_type));
1585 
1587 
1589 
1590  float origin[3] = {0.0f, 0.0f, 0.0f};
1592  ob,
1593  ss->filter_cache->nodes,
1594  ss->filter_cache->totnode,
1595  ss->filter_cache->cloth_sim,
1596  origin,
1597  FLT_MAX);
1598 
1599  const bool use_face_sets = RNA_boolean_get(op->ptr, "use_face_sets");
1600  if (use_face_sets) {
1602  }
1603  else {
1605  }
1606 
1607  const int force_axis = RNA_enum_get(op->ptr, "force_axis");
1608  ss->filter_cache->enabled_force_axis[0] = force_axis & CLOTH_FILTER_FORCE_X;
1609  ss->filter_cache->enabled_force_axis[1] = force_axis & CLOTH_FILTER_FORCE_Y;
1610  ss->filter_cache->enabled_force_axis[2] = force_axis & CLOTH_FILTER_FORCE_Z;
1611 
1612  SculptFilterOrientation orientation = RNA_enum_get(op->ptr, "orientation");
1613  ss->filter_cache->orientation = orientation;
1614 
1616  return OPERATOR_RUNNING_MODAL;
1617 }
1618 
1620 {
1621  /* Identifiers. */
1622  ot->name = "Filter Cloth";
1623  ot->idname = "SCULPT_OT_cloth_filter";
1624  ot->description = "Applies a cloth simulation deformation to the entire mesh";
1625 
1626  /* API callbacks. */
1630 
1632 
1633  /* RNA. */
1634  RNA_def_enum(ot->srna,
1635  "type",
1638  "Filter Type",
1639  "Operation that is going to be applied to the mesh");
1640  RNA_def_float(
1641  ot->srna, "strength", 1.0f, -10.0f, 10.0f, "Strength", "Filter strength", -10.0f, 10.0f);
1643  "force_axis",
1646  "Force Axis",
1647  "Apply the force in the selected axis");
1648  RNA_def_enum(ot->srna,
1649  "orientation",
1652  "Orientation",
1653  "Orientation of the axis to limit the filter force");
1655  "cloth_mass",
1656  1.0f,
1657  0.0f,
1658  2.0f,
1659  "Cloth Mass",
1660  "Mass of each simulation particle",
1661  0.0f,
1662  1.0f);
1664  "cloth_damping",
1665  0.0f,
1666  0.0f,
1667  1.0f,
1668  "Cloth Damping",
1669  "How much the applied forces are propagated through the cloth",
1670  0.0f,
1671  1.0f);
1673  "use_face_sets",
1674  false,
1675  "Use Face Sets",
1676  "Apply the filter only to the Face Set under the cursor");
1678  "use_collisions",
1679  false,
1680  "Use Collisions",
1681  "Collide with other collider objects in the scene");
1682 }
typedef float(TangentPoint)[2]
float BKE_brush_curve_strength(const struct Brush *br, float p, float len)
void BKE_collider_cache_free(struct ListBase **colliders)
Definition: collision.c:1359
void collision_move_object(struct CollisionModifierData *collmd, float step, float prevstep, bool moving_bvh)
Definition: collision.c:65
void BKE_curvemapping_init(struct CurveMapping *cumap)
Definition: colortools.c:1235
struct Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
Definition: context.c:1528
struct Object * CTX_data_active_object(const bContext *C)
Definition: context.c:1353
struct Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Definition: context.c:1505
struct ToolSettings * CTX_data_tool_settings(const bContext *C)
Definition: context.c:1282
struct ModifierData * BKE_modifiers_findby_type(const struct Object *ob, ModifierType type)
General operations, lookup, etc. for blender objects.
void BKE_sculpt_update_object_for_edit(struct Depsgraph *depsgraph, struct Object *ob_orig, bool need_pmap, bool need_mask, bool is_paint_tool)
Definition: paint.c:1914
eSculptClothNodeSimState
Definition: BKE_paint.h:305
@ SCULPT_CLOTH_NODE_UNINITIALIZED
Definition: BKE_paint.h:307
@ SCULPT_CLOTH_NODE_ACTIVE
Definition: BKE_paint.h:313
@ SCULPT_CLOTH_NODE_INACTIVE
Definition: BKE_paint.h:310
struct Brush * BKE_paint_brush(struct Paint *paint)
Definition: paint.c:607
#define SCULPT_FACE_SET_NONE
Definition: BKE_paint.h:267
@ SCULPT_CLOTH_CONSTRAINT_DEFORMATION
Definition: BKE_paint.h:321
@ SCULPT_CLOTH_CONSTRAINT_PIN
Definition: BKE_paint.h:326
@ SCULPT_CLOTH_CONSTRAINT_SOFTBODY
Definition: BKE_paint.h:324
@ SCULPT_CLOTH_CONSTRAINT_STRUCTURAL
Definition: BKE_paint.h:318
A BVH for high poly meshes.
void BKE_pbvh_node_mark_update(PBVHNode *node)
Definition: pbvh.c:1869
#define BKE_pbvh_vertex_iter_begin(pbvh, node, vi, mode)
Definition: BKE_pbvh.h:439
#define BKE_pbvh_vertex_iter_end
Definition: BKE_pbvh.h:509
void BKE_pbvh_vert_tag_update_normal(PBVH *pbvh, int index)
Definition: pbvh.c:1967
#define PBVH_ITER_UNIQUE
Definition: BKE_pbvh.h:391
void BKE_pbvh_parallel_range_settings(struct TaskParallelSettings *settings, bool use_threading, int totnode)
Definition: pbvh.c:3211
void BKE_pbvh_search_gather(PBVH *pbvh, BKE_pbvh_SearchCallback scb, void *search_data, PBVHNode ***array, int *tot)
Definition: pbvh.c:838
#define BLI_assert(a)
Definition: BLI_assert.h:46
bool BLI_edgeset_haskey(const EdgeSet *es, unsigned int v0, unsigned int v1) ATTR_WARN_UNUSED_RESULT
Definition: edgehash.c:513
bool BLI_edgeset_add(EdgeSet *es, unsigned int v0, unsigned int v1)
Definition: edgehash.c:484
void BLI_edgeset_free(EdgeSet *es)
Definition: edgehash.c:441
EdgeSet * BLI_edgeset_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition: edgehash.c:436
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:734
void BLI_ghash_insert(GHash *gh, void *key, void *val)
Definition: BLI_ghash.c:710
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:863
GHash * BLI_ghash_ptr_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
#define BVH_RAYCAST_DEFAULT
Definition: BLI_kdopbvh.h:88
@ BVH_RAYCAST_WATERTIGHT
Definition: BLI_kdopbvh.h:86
int BLI_bvhtree_ray_cast_ex(BVHTree *tree, const float co[3], const float dir[3], float radius, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata, int flag)
Definition: BLI_kdopbvh.c:1897
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
MINLINE float clamp_f(float value, float min, float max)
MINLINE float square_f(float a)
void plane_from_point_normal_v3(float r_plane[4], const float plane_co[3], const float plane_no[3])
Definition: math_geom.c:209
void isect_ray_tri_watertight_v3_precalc(struct IsectRayPrecalc *isect_precalc, const float ray_direction[3])
Definition: math_geom.c:1784
float dist_to_plane_v3(const float p[3], const float plane[4])
Definition: math_geom.c:468
bool isect_ray_tri_watertight_v3(const float ray_origin[3], const struct IsectRayPrecalc *isect_precalc, const float v0[3], const float v1[3], const float v2[3], float *r_dist, float r_uv[2])
Definition: math_geom.c:1811
float dist_signed_to_plane_v3(const float p[3], const float plane[4])
Definition: math_geom.c:461
void closest_to_plane_v3(float r_close[3], const float plane[4], const float pt[3])
Definition: math_geom.c:401
float normal_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3])
Definition: math_geom.c:33
void mul_m3_v3(const float M[3][3], float r[3])
Definition: math_matrix.c:926
void unit_m3(float m[3][3])
Definition: math_matrix.c:40
void scale_m3_fl(float R[3][3], float scale)
Definition: math_matrix.c:2289
void unit_m4(float m[4][4])
Definition: rct.c:1090
void translate_m4(float mat[4][4], float tx, float ty, float tz)
Definition: math_matrix.c:2318
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1287
void copy_m4_m4(float m1[4][4], const float m2[4][4])
Definition: math_matrix.c:77
void mul_v3_m4v3(float r[3], const float M[4][4], const float v[3])
Definition: math_matrix.c:739
void normalize_m4(float R[4][4]) ATTR_NONNULL()
Definition: math_matrix.c:1945
void rotation_between_vecs_to_quat(float q[4], const float v1[3], const float v2[3])
void quat_to_mat4(float mat[4][4], const float q[4])
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 mul_v3_v3(float r[3], const float a[3])
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 mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE bool is_zero_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE float normalize_v3_v3(float r[3], const float a[3])
MINLINE void copy_v3_fl(float r[3], float f)
MINLINE void madd_v3_v3v3fl(float r[3], const float a[3], const float b[3], float f)
MINLINE void zero_v3(float r[3])
MINLINE void mul_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void add_v3_v3(float r[3], const float a[3])
MINLINE float len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
unsigned int uint
Definition: BLI_sys_types.h:67
void BLI_task_parallel_range(int start, int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
Definition: task_range.cc:94
int BLI_task_parallel_thread_id(const TaskParallelTLS *tls)
#define UNPACK2(a)
#define POINTER_FROM_INT(i)
#define UNUSED(x)
#define POINTER_AS_INT(i)
#define UNPACK3(a)
#define ELEM(...)
#define STREQ(a, b)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
#define DEG_OBJECT_ITER_END
#define DEG_OBJECT_ITER_BEGIN(graph_, instance_, flag_)
@ DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY
@ DEG_ITER_OBJECT_FLAG_VISIBLE
@ DEG_ITER_OBJECT_FLAG_DUPLI
@ BRUSH_PERSISTENT
@ BRUSH_CLOTH_DEFORM_DRAG
@ BRUSH_CLOTH_DEFORM_EXPAND
@ BRUSH_CLOTH_DEFORM_GRAB
@ BRUSH_CLOTH_DEFORM_PINCH_POINT
@ BRUSH_CLOTH_DEFORM_PUSH
@ BRUSH_CLOTH_DEFORM_INFLATE
@ BRUSH_CLOTH_DEFORM_SNAKE_HOOK
@ BRUSH_CLOTH_DEFORM_PINCH_PERPENDICULAR
@ SCULPT_TOOL_CLOTH
@ BRUSH_CLOTH_PIN_SIMULATION_BOUNDARY
@ BRUSH_CLOTH_USE_COLLISION
@ BRUSH_CLOTH_FORCE_FALLOFF_PLANE
@ BRUSH_CLOTH_SIMULATION_AREA_LOCAL
@ BRUSH_CLOTH_SIMULATION_AREA_DYNAMIC
@ BRUSH_CLOTH_SIMULATION_AREA_GLOBAL
@ eModifierType_Collision
Object is a sort of wrapper for general info.
@ OPERATOR_FINISHED
@ OPERATOR_RUNNING_MODAL
void immVertex3f(uint attr_id, float x, float y, float z)
void immBegin(GPUPrimType, uint vertex_len)
void immUniformColor3fvAlpha(const float rgb[3], float a)
void immEnd(void)
void imm_draw_circle_wire_3d(uint pos, float x, float y, float radius, int nsegments)
void imm_draw_circle_dashed_3d(uint pos, float x, float y, float radius, int nsegments)
_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
void GPU_matrix_pop(void)
Definition: gpu_matrix.cc:126
#define GPU_matrix_mul(x)
Definition: GPU_matrix.h:224
void GPU_matrix_push(void)
Definition: gpu_matrix.cc:119
@ GPU_PRIM_LINES
Definition: GPU_primitive.h:20
@ GPU_PRIM_TRIS
Definition: GPU_primitive.h:21
void GPU_line_width(float width)
Definition: gpu_state.cc:158
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
#define C
Definition: RandGen.cpp:25
#define UI_DPI_FAC
Definition: UI_interface.h:305
@ KM_RELEASE
Definition: WM_types.h:268
@ OPTYPE_UNDO
Definition: WM_types.h:148
@ OPTYPE_REGISTER
Definition: WM_types.h:146
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
OperationNode * node
const Depsgraph * depsgraph
int len
Definition: draw_manager.c:108
uint col
IconTextureDrawCall normal
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:34
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:32
void *(* MEM_reallocN_id)(void *vmemh, size_t len, const char *str)
Definition: mallocn.c:29
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
ccl_device_inline float len_squared(const float3 a)
Definition: math_float3.h:423
#define sqrtf(x)
Definition: metal/compat.h:243
T distance(const T &a, const T &b)
CCL_NAMESPACE_BEGIN ccl_device float fade(float t)
Definition: noise.h:15
float RNA_float_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4957
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4863
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:5004
PropertyRNA * RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, float default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
Definition: rna_define.c:3836
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, bool default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3493
PropertyRNA * RNA_def_enum_flag(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3806
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3783
const float * SCULPT_vertex_co_get(SculptSession *ss, int index)
Definition: sculpt.c:125
int SCULPT_vertex_count_get(SculptSession *ss)
Definition: sculpt.c:111
bool SCULPT_cursor_geometry_info_update(bContext *C, SculptCursorGeometryInfo *out, const float mval[2], bool use_sampled_normal)
Definition: sculpt.c:4835
bool SCULPT_vertex_has_face_set(SculptSession *ss, int index, int face_set)
Definition: sculpt.c:533
SculptBrushTestFn SCULPT_brush_test_init_with_falloff_shape(SculptSession *ss, SculptBrushTest *test, char falloff_shape)
Definition: sculpt.c:1686
float SCULPT_brush_strength_factor(SculptSession *ss, const Brush *br, const float brush_point[3], const float len, const float vno[3], const float fno[3], const float mask, const int vertex_index, const int thread_id)
Definition: sculpt.c:2370
const float * SCULPT_active_vertex_co_get(SculptSession *ss)
Definition: sculpt.c:279
void SCULPT_vertex_random_access_ensure(SculptSession *ss)
Definition: sculpt.c:103
void SCULPT_flush_update_done(const bContext *C, Object *ob, SculptUpdateType update_flags)
Definition: sculpt.c:5212
bool SCULPT_search_sphere_cb(PBVHNode *node, void *data_v)
Definition: sculpt.c:2467
void SCULPT_flush_update_step(bContext *C, SculptUpdateType update_flags)
Definition: sculpt.c:5144
void SCULPT_vertex_normal_get(SculptSession *ss, int index, float no[3])
Definition: sculpt.c:171
bool SCULPT_mode_poll(bContext *C)
Definition: sculpt.c:3957
bool SCULPT_stroke_is_first_brush_step_of_symmetry_pass(StrokeCache *cache)
Definition: sculpt.c:918
float SCULPT_vertex_mask_get(SculptSession *ss, int index)
Definition: sculpt.c:248
void SCULPT_calc_brush_plane(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float r_area_no[3], float r_area_co[3])
Definition: sculpt.c:2901
void SCULPT_flush_stroke_deform(Sculpt *sd, Object *ob, bool is_proxy_used)
Definition: sculpt.c:3719
bool SCULPT_stroke_is_first_brush_step(StrokeCache *cache)
Definition: sculpt.c:912
const float * SCULPT_vertex_persistent_co_get(SculptSession *ss, int index)
Definition: sculpt.c:193
int SCULPT_active_face_set_get(SculptSession *ss)
Definition: sculpt.c:325
float SCULPT_automasking_factor_get(AutomaskingCache *automasking, SculptSession *ss, int vert)
AutomaskingCache * SCULPT_automasking_cache_init(Sculpt *sd, Brush *brush, Object *ob)
AutomaskingCache * SCULPT_automasking_active_cache_get(SculptSession *ss)
static int sculpt_cloth_filter_modal(bContext *C, wmOperator *op, const wmEvent *event)
void SCULPT_cloth_brush_ensure_nodes_constraints(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, SculptClothSimulation *cloth_sim, float initial_location[3], const float radius)
static void cloth_brush_reallocate_constraints(SculptClothSimulation *cloth_sim)
Definition: sculpt_cloth.c:192
static void cloth_brush_satisfy_constraints(SculptSession *ss, Brush *brush, SculptClothSimulation *cloth_sim)
Definition: sculpt_cloth.c:814
PBVHNode ** SCULPT_cloth_brush_affected_nodes_gather(SculptSession *ss, Brush *brush, int *r_totnode)
Definition: sculpt_cloth.c:106
void SCULPT_cloth_simulation_limits_draw(const uint gpuattr, const Brush *brush, const float location[3], const float normal[3], const float rds, const float line_width, const float outline_col[3], const float alpha)
static void cloth_brush_add_softbody_constraint(SculptClothSimulation *cloth_sim, const int node_index, const int v, const float strength)
Definition: sculpt_cloth.c:242
void SCULPT_cloth_sim_activate_nodes(SculptClothSimulation *cloth_sim, PBVHNode **nodes, int totnode)
SculptClothSimulation * SCULPT_cloth_brush_simulation_create(Object *ob, const float cloth_mass, const float cloth_damping, const float cloth_softbody_strength, const bool use_collisions, const bool needs_deform_coords)
static bool cloth_brush_sim_has_length_constraint(SculptClothSimulation *cloth_sim, const int v1, const int v2)
Definition: sculpt_cloth.c:185
static void cloth_brush_simulation_location_get(SculptSession *ss, const Brush *brush, float r_location[3])
Definition: sculpt_cloth.c:90
static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls)
Definition: sculpt_cloth.c:459
enum eSculpClothFilterType eSculptClothFilterType
eClothFilterForceAxis
@ CLOTH_FILTER_FORCE_Z
@ CLOTH_FILTER_FORCE_X
@ CLOTH_FILTER_FORCE_Y
static EnumPropertyItem prop_cloth_filter_force_axis_items[]
static void cloth_brush_add_pin_constraint(SculptClothSimulation *cloth_sim, const int node_index, const int v, const float strength)
Definition: sculpt_cloth.c:269
eSculpClothFilterType
@ CLOTH_FILTER_SCALE
@ CLOTH_FILTER_GRAVITY
@ CLOTH_FILTER_INFLATE
@ CLOTH_FILTER_EXPAND
@ CLOTH_FILTER_PINCH
static void cloth_filter_apply_forces_to_vertices(const int v_index, const float force[3], const float gravity[3], FilterCache *filter_cache)
static void cloth_brush_collision_cb(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
Definition: sculpt_cloth.c:653
#define CLOTH_SOLVER_DISPLACEMENT_FACTOR
Definition: sculpt_cloth.c:178
#define CLOTH_MAX_CONSTRAINTS_PER_VERTEX
Definition: sculpt_cloth.c:179
static void cloth_filter_apply_forces_task_cb(void *__restrict userdata, const int i, const TaskParallelTLS *__restrict UNUSED(tls))
#define CLOTH_LENGTH_CONSTRAINTS_BLOCK
Definition: sculpt_cloth.c:175
static EnumPropertyItem prop_cloth_filter_type[]
static void do_cloth_brush_solve_simulation_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls))
Definition: sculpt_cloth.c:746
#define CLOTH_DEFORMATION_SNAKEHOOK_STRENGTH
Definition: sculpt_cloth.c:181
static void cloth_brush_solve_collision(Object *object, SculptClothSimulation *cloth_sim, const int i)
Definition: sculpt_cloth.c:683
void SCULPT_cloth_simulation_free(struct SculptClothSimulation *cloth_sim)
void SCULPT_cloth_brush_store_simulation_state(SculptSession *ss, SculptClothSimulation *cloth_sim)
static int sculpt_cloth_filter_invoke(bContext *C, wmOperator *op, const wmEvent *event)
#define CLOTH_DEFORMATION_GRAB_STRENGTH
Definition: sculpt_cloth.c:183
static void cloth_sim_initialize_default_node_state(SculptSession *ss, SculptClothSimulation *cloth_sim)
static void cloth_brush_add_deformation_constraint(SculptClothSimulation *cloth_sim, const int node_index, const int v, const float strength)
Definition: sculpt_cloth.c:296
void SCULPT_cloth_brush_do_simulation_step(Sculpt *sd, Object *ob, SculptClothSimulation *cloth_sim, PBVHNode **nodes, int totnode)
Definition: sculpt_cloth.c:908
static void cloth_brush_add_length_constraint(SculptSession *ss, SculptClothSimulation *cloth_sim, const int node_index, const int v1, const int v2, const bool use_persistent)
Definition: sculpt_cloth.c:203
static ListBase * cloth_brush_collider_cache_create(Object *object, Depsgraph *depsgraph)
Definition: sculpt_cloth.c:614
static bool cloth_filter_is_deformation_filter(eSculptClothFilterType filter_type)
void SCULPT_OT_cloth_filter(struct wmOperatorType *ot)
static EnumPropertyItem prop_cloth_filter_orientation_items[]
static void cloth_filter_apply_displacement_to_deform_co(const int v_index, const float disp[3], FilterCache *filter_cache)
#define CLOTH_DEFORMATION_TARGET_STRENGTH
Definition: sculpt_cloth.c:182
static void cloth_brush_apply_brush_foces(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
Definition: sculpt_cloth.c:933
static float cloth_brush_simulation_falloff_get(const Brush *brush, const float radius, const float location[3], const float co[3])
Definition: sculpt_cloth.c:143
void SCULPT_cloth_brush_simulation_init(SculptSession *ss, SculptClothSimulation *cloth_sim)
void SCULPT_do_cloth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
void SCULPT_cloth_plane_falloff_preview_draw(const uint gpuattr, SculptSession *ss, const float outline_col[3], float outline_alpha)
#define CLOTH_SIMULATION_ITERATIONS
Definition: sculpt_cloth.c:176
static void cloth_brush_apply_force_to_vertex(SculptSession *UNUSED(ss), SculptClothSimulation *cloth_sim, const float force[3], const int vertex_index)
Definition: sculpt_cloth.c:451
static void sculpt_cloth_ensure_constraints_in_simulation_area(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
#define CLOTH_SIMULATION_TIME_STEP
Definition: sculpt_cloth.c:180
struct ClothBrushCollision ClothBrushCollision
static void do_cloth_brush_build_constraints_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls))
Definition: sculpt_cloth.c:323
void SCULPT_filter_zero_disabled_axis_components(float r_v[3], struct FilterCache *filter_cache)
void SCULPT_filter_to_object_space(float r_v[3], struct FilterCache *filter_cache)
void SCULPT_filter_cache_init(bContext *C, Object *ob, Sculpt *sd, const int undo_type)
void SCULPT_filter_cache_free(SculptSession *ss)
void SCULPT_undo_push_begin(struct Object *ob, const char *name)
Definition: sculpt_undo.c:1545
void SCULPT_undo_push_end(struct Object *ob)
Definition: sculpt_undo.c:1575
#define SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN(ss, v_index, neighbor_iterator)
BLI_INLINE bool SCULPT_is_cloth_deform_brush(const Brush *brush)
SculptFilterOrientation
@ SCULPT_FILTER_ORIENTATION_WORLD
@ SCULPT_FILTER_ORIENTATION_VIEW
@ SCULPT_FILTER_ORIENTATION_LOCAL
bool(* SculptBrushTestFn)(SculptBrushTest *test, const float co[3])
@ SCULPT_UPDATE_COORDS
Definition: sculpt_intern.h:45
#define SCULPT_VERTEX_NEIGHBORS_ITER_END(neighbor_iterator)
@ SCULPT_UNDO_COORDS
float co[3]
Definition: BLI_kdopbvh.h:68
float no[3]
Definition: BLI_kdopbvh.h:70
float origin[3]
Definition: BLI_kdopbvh.h:54
float direction[3]
Definition: BLI_kdopbvh.h:56
float cloth_mass
int cloth_deform_type
float cloth_sim_falloff
struct CurveMapping * curve
float cloth_sim_limit
char sculpt_tool
int cloth_simulation_area_type
float cloth_constraint_softbody_strength
int cloth_force_falloff_type
float cloth_damping
CollisionModifierData * col_data
Definition: sculpt_cloth.c:649
struct IsectRayPrecalc isect_precalc
Definition: sculpt_cloth.c:650
struct CollisionModifierData * collmd
struct ColliderCache * next
struct BVHTree * bvhtree
AutomaskingCache * automasking
SculptFilterOrientation orientation
float cloth_sim_pinch_point[3]
PBVHNode ** nodes
SculptClothSimulation * cloth_sim
bool enabled_force_axis[3]
char name[66]
Definition: DNA_ID.h:378
void * first
Definition: DNA_listBase.h:31
unsigned int tri[3]
float co[3]
float obmat[4][4]
struct SculptSession * sculpt
struct MVert * mvert
Definition: BKE_pbvh.h:428
float * co
Definition: BKE_pbvh.h:430
float * fno
Definition: BKE_pbvh.h:432
float * no
Definition: BKE_pbvh.h:431
float * mask
Definition: BKE_pbvh.h:433
eSculptClothConstraintType type
Definition: BKE_paint.h:349
float * deformation_strength
Definition: BKE_paint.h:363
struct EdgeSet * created_length_constraints
Definition: BKE_paint.h:355
float(* init_pos)[3]
Definition: BKE_paint.h:371
float(* prev_pos)[3]
Definition: BKE_paint.h:373
float(* softbody_pos)[3]
Definition: BKE_paint.h:372
float(* acceleration)[3]
Definition: BKE_paint.h:369
struct ListBase * collider_list
Definition: BKE_paint.h:376
struct GHash * node_state_index
Definition: BKE_paint.h:380
float(* deformation_pos)[3]
Definition: BKE_paint.h:362
eSculptClothNodeSimState * node_state
Definition: BKE_paint.h:381
SculptClothLengthConstraint * length_constraints
Definition: BKE_paint.h:353
float(* last_iteration_pos)[3]
Definition: BKE_paint.h:374
float * length_constraint_tweak
Definition: BKE_paint.h:357
struct Depsgraph * depsgraph
Definition: BKE_paint.h:495
struct KeyBlock * shapekey_active
Definition: BKE_paint.h:505
struct StrokeCache * cache
Definition: BKE_paint.h:563
struct FilterCache * filter_cache
Definition: BKE_paint.h:564
struct PBVH * pbvh
Definition: BKE_paint.h:550
bool deform_modifiers_active
Definition: BKE_paint.h:555
struct Sculpt * sd
struct Object * gravity_object
Paint paint
float gravity_factor
float true_location[3]
float initial_radius
const struct Brush * brush
float scale[3]
float initial_location[3]
float last_location[3]
int mirror_symmetry_pass
float sculpt_normal_symm[3]
float grab_delta_symmetry[3]
float location[3]
float stroke_local_mat[4][4]
struct SculptClothSimulation * cloth_sim
float gravity_direction[3]
bool supports_gravity
float grab_delta[3]
short val
Definition: WM_types.h:680
int mval[2]
Definition: WM_types.h:684
short type
Definition: WM_types.h:678
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:919
const char * name
Definition: WM_types.h:888
int(* modal)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:935
const char * idname
Definition: WM_types.h:890
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:943
struct StructRNA * srna
Definition: WM_types.h:969
const char * description
Definition: WM_types.h:893
PropertyRNA * prop
Definition: WM_types.h:981
struct PointerRNA * ptr
wmEventHandler_Op * WM_event_add_modal_handler(bContext *C, wmOperator *op)
@ MOUSEMOVE
@ LEFTMOUSE
wmOperatorType * ot
Definition: wm_files.c:3479