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