Blender V4.3
cloth.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include "MEM_guardedalloc.h"
10
11#include "DNA_cloth_types.h"
12#include "DNA_mesh_types.h"
13#include "DNA_meshdata_types.h"
14#include "DNA_object_types.h"
15#include "DNA_scene_types.h"
16
17#include "BLI_linklist.h"
18#include "BLI_math_geom.h"
19#include "BLI_math_matrix.h"
20#include "BLI_math_rotation.h"
21#include "BLI_math_vector.h"
22#include "BLI_rand.h"
23#include "BLI_utildefines.h"
24
25#include "DEG_depsgraph.hh"
27
28#include "BKE_bvhutils.hh"
29#include "BKE_cloth.hh"
30#include "BKE_customdata.hh"
31#include "BKE_effect.h"
32#include "BKE_global.hh"
33#include "BKE_lib_id.hh"
34#include "BKE_mesh.hh"
35#include "BKE_modifier.hh"
36#include "BKE_pointcache.h"
37
38#include "SIM_mass_spring.h"
39
40// #include "BLI_time.h" /* timing for debug prints */
41
42/* ********** cloth engine ******* */
43/* Prototypes for internal functions.
44 */
45static void cloth_to_object(Object *ob, ClothModifierData *clmd, float (*vertexCos)[3]);
46static void cloth_from_mesh(ClothModifierData *clmd, const Object *ob, Mesh *mesh);
47static bool cloth_from_object(
48 Object *ob, ClothModifierData *clmd, Mesh *mesh, float framenr, int first);
50static void cloth_update_verts(Object *ob, ClothModifierData *clmd, Mesh *mesh);
51static void cloth_update_spring_lengths(ClothModifierData *clmd, Mesh *mesh);
52static bool cloth_build_springs(ClothModifierData *clmd, Mesh *mesh);
53static void cloth_apply_vgroup(ClothModifierData *clmd, Mesh *mesh);
54
60
61/******************************************************************************
62 *
63 * External interface called by modifier.cc clothModifier functions.
64 *
65 ******************************************************************************/
66
68{
69 if (!clmd) {
70 return nullptr;
71 }
72
73 Cloth *cloth = clmd->clothObject;
74
75 if (!cloth) {
76 return nullptr;
77 }
78
79 ClothVertex *verts = cloth->verts;
80 const blender::int3 *vert_tris = cloth->vert_tris;
81
82 /* in the moment, return zero if no faces there */
83 if (!cloth->primitive_num) {
84 return nullptr;
85 }
86
87 /* Create quad-tree with k=26. */
88 BVHTree *bvhtree = BLI_bvhtree_new(cloth->primitive_num, epsilon, 4, 26);
89
90 /* fill tree */
91 if (clmd->hairdata == nullptr) {
92 for (int i = 0; i < cloth->primitive_num; i++) {
93 float co[3][3];
94
95 copy_v3_v3(co[0], verts[vert_tris[i][0]].xold);
96 copy_v3_v3(co[1], verts[vert_tris[i][1]].xold);
97 copy_v3_v3(co[2], verts[vert_tris[i][2]].xold);
98
99 BLI_bvhtree_insert(bvhtree, i, co[0], 3);
100 }
101 }
102 else {
103 const blender::int2 *edges = cloth->edges;
104
105 for (int i = 0; i < cloth->primitive_num; i++) {
106 float co[2][3];
107
108 copy_v3_v3(co[0], verts[edges[i][0]].xold);
109 copy_v3_v3(co[1], verts[edges[i][1]].xold);
110
111 BLI_bvhtree_insert(bvhtree, i, co[0], 2);
112 }
113 }
114
115 /* balance tree */
116 BLI_bvhtree_balance(bvhtree);
117
118 return bvhtree;
119}
120
122{
123 uint i = 0;
124 Cloth *cloth = clmd->clothObject;
125 BVHTree *bvhtree;
126 ClothVertex *verts = cloth->verts;
127
128 BLI_assert(!(clmd->hairdata != nullptr && self));
129
130 if (self) {
131 bvhtree = cloth->bvhselftree;
132 }
133 else {
134 bvhtree = cloth->bvhtree;
135 }
136
137 if (!bvhtree) {
138 return;
139 }
140
141 const blender::int3 *vert_tris = cloth->vert_tris;
142
143 /* update vertex position in bvh tree */
144 if (clmd->hairdata == nullptr) {
145 if (verts && vert_tris) {
146 for (i = 0; i < cloth->primitive_num; i++) {
147 float co[3][3], co_moving[3][3];
148 bool ret;
149
150 /* copy new locations into array */
151 if (moving) {
152 copy_v3_v3(co[0], verts[vert_tris[i][0]].txold);
153 copy_v3_v3(co[1], verts[vert_tris[i][1]].txold);
154 copy_v3_v3(co[2], verts[vert_tris[i][2]].txold);
155
156 /* update moving positions */
157 copy_v3_v3(co_moving[0], verts[vert_tris[i][0]].tx);
158 copy_v3_v3(co_moving[1], verts[vert_tris[i][1]].tx);
159 copy_v3_v3(co_moving[2], verts[vert_tris[i][2]].tx);
160
161 ret = BLI_bvhtree_update_node(bvhtree, i, co[0], co_moving[0], 3);
162 }
163 else {
164 copy_v3_v3(co[0], verts[vert_tris[i][0]].tx);
165 copy_v3_v3(co[1], verts[vert_tris[i][1]].tx);
166 copy_v3_v3(co[2], verts[vert_tris[i][2]].tx);
167
168 ret = BLI_bvhtree_update_node(bvhtree, i, co[0], nullptr, 3);
169 }
170
171 /* check if tree is already full */
172 if (ret == false) {
173 break;
174 }
175 }
176
178 }
179 }
180 else {
181 if (verts) {
182 const blender::int2 *edges = reinterpret_cast<const blender::int2 *>(cloth->edges);
183
184 for (i = 0; i < cloth->primitive_num; i++) {
185 float co[2][3];
186
187 copy_v3_v3(co[0], verts[edges[i][0]].tx);
188 copy_v3_v3(co[1], verts[edges[i][1]].tx);
189
190 if (!BLI_bvhtree_update_node(bvhtree, i, co[0], nullptr, 2)) {
191 break;
192 }
193 }
194
196 }
197 }
198}
199
200void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr)
201{
202 PTCacheID pid;
203
204 BKE_ptcache_id_from_cloth(&pid, ob, clmd);
205
206 /* don't do anything as long as we're in editmode! */
207 if (pid.cache->edit && ob->mode & OB_MODE_PARTICLE_EDIT) {
208 return;
209 }
210
212}
213
214static bool do_init_cloth(Object *ob, ClothModifierData *clmd, Mesh *result, int framenr)
215{
216 PointCache *cache;
217
218 cache = clmd->point_cache;
219
220 /* initialize simulation data if it didn't exist already */
221 if (clmd->clothObject == nullptr) {
222 if (!cloth_from_object(ob, clmd, result, framenr, 1)) {
224 BKE_modifier_set_error(ob, &(clmd->modifier), "Can't initialize cloth");
225 return false;
226 }
227
228 if (clmd->clothObject == nullptr) {
230 BKE_modifier_set_error(ob, &(clmd->modifier), "Null cloth object");
231 return false;
232 }
233
235
236 ClothSimSettings *parms = clmd->sim_parms;
239 {
241 }
242
243 clmd->clothObject->last_frame = MINFRAME - 1;
244 clmd->sim_parms->dt = 1.0f / clmd->sim_parms->stepsPerFrame;
245 }
246
247 return true;
248}
249
250static int do_step_cloth(
251 Depsgraph *depsgraph, Object *ob, ClothModifierData *clmd, Mesh *result, int framenr)
252{
253 using namespace blender;
254 /* simulate 1 frame forward */
255 ClothVertex *verts = nullptr;
256 Cloth *cloth;
257 ListBase *effectors = nullptr;
258 uint i = 0;
259 int ret = 0;
260 bool vert_mass_changed = false;
261
262 cloth = clmd->clothObject;
263 verts = cloth->verts;
264 const Span<float3> positions = result->vert_positions();
265 vert_mass_changed = verts->mass != clmd->sim_parms->mass;
266
267 /* force any pinned verts to their constrained location. */
268 for (i = 0; i < clmd->clothObject->mvert_num; i++, verts++) {
269 /* save the previous position. */
270 copy_v3_v3(verts->xold, verts->xconst);
271 copy_v3_v3(verts->txold, verts->x);
272
273 /* Get the current position. */
274 copy_v3_v3(verts->xconst, positions[i]);
275 mul_m4_v3(ob->object_to_world().ptr(), verts->xconst);
276
277 if (vert_mass_changed) {
278 verts->mass = clmd->sim_parms->mass;
279 SIM_mass_spring_set_implicit_vertex_mass(cloth->implicit, i, verts->mass);
280 }
281 }
282
283 effectors = BKE_effectors_create(
284 depsgraph, ob, nullptr, clmd->sim_parms->effector_weights, false);
285
287 cloth_update_verts(ob, clmd, result);
288 }
289
290 /* Support for dynamic vertex groups, changing from frame to frame */
291 cloth_apply_vgroup(clmd, result);
292
294 (clmd->sim_parms->vgroup_shrink > 0) || (clmd->sim_parms->shrink_min != 0.0f))
295 {
296 cloth_update_spring_lengths(clmd, result);
297 }
298
300
301 // TIMEIT_START(cloth_step)
302
303 /* call the solver. */
304 ret = SIM_cloth_solve(depsgraph, ob, framenr, clmd, effectors);
305
306 // TIMEIT_END(cloth_step)
307
308 BKE_effectors_free(effectors);
309
310 // printf ( "%f\n", ( float ) tval() );
311
312 return ret;
313}
314
315/************************************************
316 * clothModifier_do - main simulation function
317 ************************************************/
318
320 Depsgraph *depsgraph,
321 Scene *scene,
322 Object *ob,
323 Mesh *mesh,
324 float (*vertexCos)[3])
325{
326 PointCache *cache;
327 PTCacheID pid;
328 float timescale;
329 int framenr, startframe, endframe;
330 int cache_result;
331
332 framenr = DEG_get_ctime(depsgraph);
333 cache = clmd->point_cache;
334
335 BKE_ptcache_id_from_cloth(&pid, ob, clmd);
336 BKE_ptcache_id_time(&pid, scene, framenr, &startframe, &endframe, &timescale);
337 clmd->sim_parms->timescale = timescale * clmd->sim_parms->time_scale;
338
339 if (clmd->sim_parms->reset ||
340 (clmd->clothObject && mesh->verts_num != clmd->clothObject->mvert_num))
341 {
342 clmd->sim_parms->reset = 0;
343 cache->flag |= PTCACHE_OUTDATED;
345 BKE_ptcache_validate(cache, 0);
346 cache->last_exact = 0;
347 cache->flag &= ~PTCACHE_REDO_NEEDED;
348 }
349
350 /* simulation is only active during a specific period */
351 if (framenr < startframe) {
353 return;
354 }
355 if (framenr > endframe) {
356 framenr = endframe;
357 }
358
359 /* initialize simulation data if it didn't exist already */
360 if (!do_init_cloth(ob, clmd, mesh, framenr)) {
361 return;
362 }
363
364 if (framenr == startframe) {
366 do_init_cloth(ob, clmd, mesh, framenr);
367 BKE_ptcache_validate(cache, framenr);
368 cache->flag &= ~PTCACHE_REDO_NEEDED;
369 clmd->clothObject->last_frame = framenr;
370 return;
371 }
372
373 /* Since implicit sharing is introduced, mesh data can be moved to other places.
374 * Therefore some fields in simulation data need to be updated accordingly */
375 clmd->clothObject->edges = mesh->edges().data();
376
377 /* try to read from cache */
378 bool can_simulate = (framenr == clmd->clothObject->last_frame + 1) &&
379 !(cache->flag & PTCACHE_BAKED);
380
381 cache_result = BKE_ptcache_read(&pid, float(framenr) + scene->r.subframe, can_simulate);
382
383 if (cache_result == PTCACHE_READ_EXACT || cache_result == PTCACHE_READ_INTERPOLATED ||
384 (!can_simulate && cache_result == PTCACHE_READ_OLD))
385 {
387 cloth_to_object(ob, clmd, vertexCos);
388
389 BKE_ptcache_validate(cache, framenr);
390
391 if (cache_result == PTCACHE_READ_INTERPOLATED && cache->flag & PTCACHE_REDO_NEEDED) {
392 BKE_ptcache_write(&pid, framenr);
393 }
394
395 clmd->clothObject->last_frame = framenr;
396
397 return;
398 }
399 if (cache_result == PTCACHE_READ_OLD) {
401 }
402 else if (
403 /* 2.4x disabled lib, but this can be used in some cases, testing further - campbell */
404 /*ob->id.lib ||*/ (cache->flag & PTCACHE_BAKED))
405 {
406 /* if baked and nothing in cache, do nothing */
408 return;
409 }
410
411 /* if on second frame, write cache for first frame */
412 if (cache->simframe == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact == 0))
413 {
414 BKE_ptcache_write(&pid, startframe);
415 }
416
417 clmd->sim_parms->timescale *= framenr - cache->simframe;
418
419 /* do simulation */
420 BKE_ptcache_validate(cache, framenr);
421
422 if (!do_step_cloth(depsgraph, ob, clmd, mesh, framenr)) {
424 }
425 else {
426 BKE_ptcache_write(&pid, framenr);
427 }
428
429 cloth_to_object(ob, clmd, vertexCos);
430 clmd->clothObject->last_frame = framenr;
431}
432
434{
435 Cloth *cloth = nullptr;
436
437 if (!clmd) {
438 return;
439 }
440
441 cloth = clmd->clothObject;
442
443 if (cloth) {
445
446 /* Free the verts. */
447 MEM_SAFE_FREE(cloth->verts);
448 cloth->mvert_num = 0;
449
450 /* Free the springs. */
451 if (cloth->springs != nullptr) {
452 LinkNode *search = cloth->springs;
453 while (search) {
454 ClothSpring *spring = static_cast<ClothSpring *>(search->link);
455
456 MEM_SAFE_FREE(spring->pa);
457 MEM_SAFE_FREE(spring->pb);
458
459 MEM_freeN(spring);
460 search = search->next;
461 }
462 BLI_linklist_free(cloth->springs, nullptr);
463
464 cloth->springs = nullptr;
465 }
466
467 cloth->springs = nullptr;
468 cloth->numsprings = 0;
469
470 /* free BVH collision tree */
471 if (cloth->bvhtree) {
472 BLI_bvhtree_free(cloth->bvhtree);
473 }
474
475 if (cloth->bvhselftree && cloth->bvhselftree != cloth->bvhtree) {
476 BLI_bvhtree_free(cloth->bvhselftree);
477 }
478
479 /* we save our faces for collision objects */
480 if (cloth->vert_tris) {
481 MEM_freeN(cloth->vert_tris);
482 }
483
484#if 0
485 if (clmd->clothObject->facemarks) {
486 MEM_freeN(clmd->clothObject->facemarks);
487 }
488#endif
489 MEM_delete(cloth);
490 clmd->clothObject = nullptr;
491 }
492}
493
495{
496 Cloth *cloth = nullptr;
497 if (G.debug & G_DEBUG_SIMDATA) {
498 printf("cloth_free_modifier_extern\n");
499 }
500
501 if (!clmd) {
502 return;
503 }
504
505 cloth = clmd->clothObject;
506
507 if (cloth) {
508 if (G.debug & G_DEBUG_SIMDATA) {
509 printf("cloth_free_modifier_extern in\n");
510 }
511
513
514 /* Free the verts. */
515 MEM_SAFE_FREE(cloth->verts);
516 cloth->mvert_num = 0;
517
518 /* Free the springs. */
519 if (cloth->springs != nullptr) {
520 LinkNode *search = cloth->springs;
521 while (search) {
522 ClothSpring *spring = static_cast<ClothSpring *>(search->link);
523
524 MEM_SAFE_FREE(spring->pa);
525 MEM_SAFE_FREE(spring->pb);
526
527 MEM_freeN(spring);
528 search = search->next;
529 }
530 BLI_linklist_free(cloth->springs, nullptr);
531
532 cloth->springs = nullptr;
533 }
534
535 cloth->springs = nullptr;
536 cloth->numsprings = 0;
537
538 /* free BVH collision tree */
539 if (cloth->bvhtree) {
540 BLI_bvhtree_free(cloth->bvhtree);
541 }
542
543 if (cloth->bvhselftree && cloth->bvhselftree != cloth->bvhtree) {
544 BLI_bvhtree_free(cloth->bvhselftree);
545 }
546
547 /* we save our faces for collision objects */
548 if (cloth->vert_tris) {
549 MEM_freeN(cloth->vert_tris);
550 }
551
552#if 0
553 if (clmd->clothObject->facemarks) {
554 MEM_freeN(clmd->clothObject->facemarks);
555 }
556#endif
557 MEM_delete(cloth);
558 clmd->clothObject = nullptr;
559 }
560}
561
562/******************************************************************************
563 *
564 * Internal functions.
565 *
566 ******************************************************************************/
567
571static void cloth_to_object(Object *ob, ClothModifierData *clmd, float (*vertexCos)[3])
572{
573 uint i = 0;
574 Cloth *cloth = clmd->clothObject;
575
576 if (clmd->clothObject) {
577 /* Inverse matrix is not up to date. */
578 invert_m4_m4(ob->runtime->world_to_object.ptr(), ob->object_to_world().ptr());
579
580 for (i = 0; i < cloth->mvert_num; i++) {
581 copy_v3_v3(vertexCos[i], cloth->verts[i].x);
582 mul_m4_v3(ob->world_to_object().ptr(), vertexCos[i]); /* cloth is in global coords */
583 }
584 }
585}
586
588{
589 return (((clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF) &&
590 (clmd->coll_parms->vgroup_selfcol > 0)) ||
592 (clmd->coll_parms->vgroup_objcol > 0)) ||
593 (clmd->sim_parms->vgroup_pressure > 0) || (clmd->sim_parms->vgroup_struct > 0) ||
594 (clmd->sim_parms->vgroup_bend > 0) || (clmd->sim_parms->vgroup_shrink > 0) ||
595 (clmd->sim_parms->vgroup_intern > 0) || (clmd->sim_parms->vgroup_mass > 0) ||
596 (clmd->sim_parms->vgroup_shear > 0));
597}
598
603{
604 if (!clmd || !mesh) {
605 return;
606 }
607
608 int mvert_num = mesh->verts_num;
609
611
612 const blender::Span<MDeformVert> dverts = mesh->deform_verts();
613
614 if (cloth_uses_vgroup(clmd)) {
615 for (int i = 0; i < mvert_num; i++, verts++) {
616
617 /* Reset Goal values to standard */
618 if (clmd->sim_parms->vgroup_mass > 0) {
619 verts->goal = clmd->sim_parms->defgoal;
620 }
621 else {
622 verts->goal = 0.0f;
623 }
624
625 /* Compute base cloth shrink weight */
626 verts->shrink_factor = 0.0f;
627
628 /* Reset vertex flags */
631
632 if (!dverts.is_empty()) {
633 const MDeformVert *dvert = &dverts[i];
634 for (int j = 0; j < dvert->totweight; j++) {
635 if (dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_mass - 1)) {
636 verts->goal = dvert->dw[j].weight;
637
638 // goalfac = 1.0f; /* UNUSED */
639
640 /* Kicking goal factor to simplify things...who uses that anyway? */
641 // ABS (clmd->sim_parms->maxgoal - clmd->sim_parms->mingoal);
642
643 verts->goal = pow4f(verts->goal);
644 if (verts->goal >= SOFTGOALSNAP) {
646 }
647 }
648
649 if (dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_struct - 1)) {
650 verts->struct_stiff = dvert->dw[j].weight;
651 }
652
653 if (dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_shear - 1)) {
654 verts->shear_stiff = dvert->dw[j].weight;
655 }
656
657 if (dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_bend - 1)) {
658 verts->bend_stiff = dvert->dw[j].weight;
659 }
660
661 if (dvert->dw[j].def_nr == (clmd->coll_parms->vgroup_selfcol - 1)) {
662 if (dvert->dw[j].weight > 0.0f) {
664 }
665 }
666
667 if (dvert->dw[j].def_nr == (clmd->coll_parms->vgroup_objcol - 1)) {
668 if (dvert->dw[j].weight > 0.0f) {
670 }
671 }
672
673 if (dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_shrink - 1)) {
674 /* Used for linear interpolation between min and max
675 * shrink factor based on weight. */
676 verts->shrink_factor = dvert->dw[j].weight;
677 }
678
679 if (dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_intern - 1)) {
680 /* Used to define the stiffness weight on the internal spring connected to this vertex.
681 */
682 verts->internal_stiff = dvert->dw[j].weight;
683 }
684
685 if (dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_pressure - 1)) {
686 /* Used to define how much the pressure settings should affect the given vertex. */
687 verts->pressure_factor = dvert->dw[j].weight;
688 }
689 }
690 }
691 }
692 }
693}
694
695static float cloth_shrink_factor(ClothModifierData *clmd, ClothVertex *verts, int i1, int i2)
696{
697 /* Linear interpolation between min and max shrink factor based on weight. */
698 float base = 1.0f - clmd->sim_parms->shrink_min;
699 float shrink_factor_delta = clmd->sim_parms->shrink_min - clmd->sim_parms->shrink_max;
700
701 float k1 = base + shrink_factor_delta * verts[i1].shrink_factor;
702 float k2 = base + shrink_factor_delta * verts[i2].shrink_factor;
703
704 /* Use geometrical mean to average two factors since it behaves better
705 * for diagonals when a rectangle transforms into a trapezoid. */
706 return sqrtf(k1 * k2);
707}
708
710 Object *ob, ClothModifierData *clmd, Mesh *mesh, float /*framenr*/, int first)
711{
712 using namespace blender;
713 int i = 0;
714 ClothVertex *verts = nullptr;
715 const float(*shapekey_rest)[3] = nullptr;
716 const float tnull[3] = {0, 0, 0};
717
718 /* If we have a clothObject, free it. */
719 if (clmd->clothObject != nullptr) {
721 if (G.debug & G_DEBUG_SIMDATA) {
722 printf("cloth_free_modifier cloth_from_object\n");
723 }
724 }
725
726 /* Allocate a new cloth object. */
727 clmd->clothObject = MEM_new<Cloth>(__func__);
728 if (clmd->clothObject) {
729 clmd->clothObject->old_solver_type = 255;
730 }
731 else {
732 BKE_modifier_set_error(ob, &(clmd->modifier), "Out of memory on allocating cloth object");
733 return false;
734 }
735
736 /* mesh input objects need Mesh */
737 if (!mesh) {
738 return false;
739 }
740
741 cloth_from_mesh(clmd, ob, mesh);
742
743 /* create springs */
744 clmd->clothObject->springs = nullptr;
745 clmd->clothObject->numsprings = -1;
746
747 if (clmd->sim_parms->shapekey_rest &&
749 {
750 shapekey_rest = static_cast<const float(*)[3]>(
751 CustomData_get_layer(&mesh->vert_data, CD_CLOTH_ORCO));
752 }
753
754 const Span<float3> positions = mesh->vert_positions();
755
756 verts = clmd->clothObject->verts;
757
758 /* set initial values */
759 for (i = 0; i < mesh->verts_num; i++, verts++) {
760 if (first) {
761 copy_v3_v3(verts->x, positions[i]);
762
763 mul_m4_v3(ob->object_to_world().ptr(), verts->x);
764
765 if (shapekey_rest) {
766 copy_v3_v3(verts->xrest, shapekey_rest[i]);
767 mul_m4_v3(ob->object_to_world().ptr(), verts->xrest);
768 }
769 else {
770 copy_v3_v3(verts->xrest, verts->x);
771 }
772 }
773
774 /* no GUI interface yet */
775 verts->mass = clmd->sim_parms->mass;
776 verts->impulse_count = 0;
777
778 if (clmd->sim_parms->vgroup_mass > 0) {
779 verts->goal = clmd->sim_parms->defgoal;
780 }
781 else {
782 verts->goal = 0.0f;
783 }
784
785 verts->shrink_factor = 0.0f;
786
787 verts->flags = 0;
788 copy_v3_v3(verts->xold, verts->x);
789 copy_v3_v3(verts->xconst, verts->x);
790 copy_v3_v3(verts->txold, verts->x);
791 copy_v3_v3(verts->tx, verts->x);
792 mul_v3_fl(verts->v, 0.0f);
793
794 verts->impulse_count = 0;
795 copy_v3_v3(verts->impulse, tnull);
796 }
797
798 /* apply / set vertex groups */
799 /* has to be happen before springs are build! */
800 cloth_apply_vgroup(clmd, mesh);
801
802 if (!cloth_build_springs(clmd, mesh)) {
804 BKE_modifier_set_error(ob, &(clmd->modifier), "Cannot build springs");
805 return false;
806 }
807
808 /* init our solver */
809 SIM_cloth_solver_init(ob, clmd);
810
811 if (!first) {
813 }
814
816
817 if (compare_ff(clmd->coll_parms->selfepsilon, clmd->coll_parms->epsilon, 1e-6f)) {
818 /* Share the BVH tree if the epsilon is the same. */
820 }
821 else {
823 }
824
825 return true;
826}
827
828static void cloth_from_mesh(ClothModifierData *clmd, const Object *ob, Mesh *mesh)
829{
830 const blender::Span<int> corner_verts = mesh->corner_verts();
831 const blender::Span<blender::int3> corner_tris = mesh->corner_tris();
832 const uint mvert_num = mesh->verts_num;
833
834 /* Allocate our vertices. */
835 clmd->clothObject->mvert_num = mvert_num;
836 clmd->clothObject->verts = MEM_cnew_array<ClothVertex>(clmd->clothObject->mvert_num, __func__);
837 if (clmd->clothObject->verts == nullptr) {
839 BKE_modifier_set_error(ob, &(clmd->modifier), "Out of memory on allocating vertices");
840 return;
841 }
842
843 /* save face information */
844 if (clmd->hairdata == nullptr) {
845 clmd->clothObject->primitive_num = corner_tris.size();
846 }
847 else {
848 clmd->clothObject->primitive_num = mesh->edges_num;
849 }
850
851 clmd->clothObject->vert_tris = static_cast<blender::int3 *>(
852 MEM_malloc_arrayN(corner_tris.size(), sizeof(blender::int3), __func__));
853 if (clmd->clothObject->vert_tris == nullptr) {
855 BKE_modifier_set_error(ob, &(clmd->modifier), "Out of memory on allocating triangles");
856 return;
857 }
859 corner_verts, corner_tris, {clmd->clothObject->vert_tris, corner_tris.size()});
860
861 clmd->clothObject->edges = mesh->edges().data();
862
863 /* Free the springs since they can't be correct if the vertices
864 * changed.
865 */
866 if (clmd->clothObject->springs != nullptr) {
868 }
869}
870
871/* -------------------------------------------------------------------- */
876{
877 if (v0 < v1) {
878 spring->ij = v0;
879 spring->kl = v1;
880 }
881 else {
882 spring->ij = v1;
883 spring->kl = v0;
884 }
885}
886
887static void cloth_free_edgelist(LinkNodePair *edgelist, uint mvert_num)
888{
889 if (edgelist) {
890 for (uint i = 0; i < mvert_num; i++) {
891 BLI_linklist_free(edgelist[i].list, nullptr);
892 }
893
894 MEM_freeN(edgelist);
895 }
896}
897
899 LinkNodePair *edgelist,
900 BendSpringRef *spring_ref)
901{
902 if (cloth->springs != nullptr) {
903 LinkNode *search = cloth->springs;
904 while (search) {
905 ClothSpring *spring = static_cast<ClothSpring *>(search->link);
906
907 MEM_SAFE_FREE(spring->pa);
908 MEM_SAFE_FREE(spring->pb);
909
910 MEM_freeN(spring);
911 search = search->next;
912 }
913 BLI_linklist_free(cloth->springs, nullptr);
914
915 cloth->springs = nullptr;
916 }
917
918 cloth_free_edgelist(edgelist, cloth->mvert_num);
919
920 MEM_SAFE_FREE(spring_ref);
921
922 cloth->edgeset.clear_and_shrink();
923}
924
926 ClothVertex *verts, int i, int j, const int *inds, int len, float r_dir[3])
927{
928 float cent[3] = {0};
929 float fact = 1.0f / len;
930
931 for (int x = 0; x < len; x++) {
932 madd_v3_v3fl(cent, verts[inds[x]].xrest, fact);
933 }
934
935 normal_tri_v3(r_dir, verts[i].xrest, verts[j].xrest, cent);
936}
937
939 ClothVertex *verts, int i, int j, int *i_a, int *i_b, int len_a, int len_b)
940{
941 float dir_a[3], dir_b[3];
942 float tmp[3], vec_e[3];
943 float sin, cos;
944
945 /* Poly vectors. */
946 cloth_bend_poly_dir(verts, j, i, i_a, len_a, dir_a);
947 cloth_bend_poly_dir(verts, i, j, i_b, len_b, dir_b);
948
949 /* Edge vector. */
950 sub_v3_v3v3(vec_e, verts[i].xrest, verts[j].xrest);
951 normalize_v3(vec_e);
952
953 /* Compute angle. */
954 cos = dot_v3v3(dir_a, dir_b);
955
956 cross_v3_v3v3(tmp, dir_a, dir_b);
957 sin = dot_v3v3(tmp, vec_e);
958
959 return atan2f(sin, cos);
960}
961
963{
964 Cloth *cloth = clmd->clothObject;
965 LinkNode *search = nullptr;
966 float hair_frame[3][3], dir_old[3], dir_new[3];
967 int prev_mn; /* to find hair chains */
968
969 if (!clmd->hairdata) {
970 return;
971 }
972
973 /* XXX NOTE: we need to propagate frames from the root up,
974 * but structural hair springs are stored in reverse order.
975 * The bending springs however are then inserted in the same
976 * order as vertices again ...
977 * This messy situation can be resolved when solver data is
978 * generated directly from a dedicated hair system.
979 */
980
981 prev_mn = -1;
982 for (search = cloth->springs; search; search = search->next) {
983 ClothSpring *spring = static_cast<ClothSpring *>(search->link);
984 ClothHairData *hair_ij, *hair_kl;
985 bool is_root = spring->kl != prev_mn;
986
987 if (spring->type != CLOTH_SPRING_TYPE_BENDING_HAIR) {
988 continue;
989 }
990
991 hair_ij = &clmd->hairdata[spring->ij];
992 hair_kl = &clmd->hairdata[spring->kl];
993 if (is_root) {
994 /* initial hair frame from root orientation */
995 copy_m3_m3(hair_frame, hair_ij->rot);
996 /* surface normal is the initial direction,
997 * parallel transport then keeps it aligned to the hair direction
998 */
999 copy_v3_v3(dir_new, hair_frame[2]);
1000 }
1001
1002 copy_v3_v3(dir_old, dir_new);
1003 sub_v3_v3v3(dir_new, cloth->verts[spring->mn].x, cloth->verts[spring->kl].x);
1004 normalize_v3(dir_new);
1005
1006 /* get local targets for kl/mn vertices by putting rest targets into the current frame,
1007 * then multiply with the rest length to get the actual goals
1008 */
1009
1010 mul_v3_m3v3(spring->target, hair_frame, hair_kl->rest_target);
1011 mul_v3_fl(spring->target, spring->restlen);
1012
1013 /* move frame to next hair segment */
1014 cloth_parallel_transport_hair_frame(hair_frame, dir_old, dir_new);
1015
1016 prev_mn = spring->mn;
1017 }
1018}
1019
1021{
1022 Cloth *cloth = clmd->clothObject;
1023 LinkNode *search = nullptr;
1024 float hair_frame[3][3], dir_old[3], dir_new[3];
1025 int prev_mn; /* to find hair roots */
1026
1027 if (!clmd->hairdata) {
1028 return;
1029 }
1030
1031 /* XXX NOTE: we need to propagate frames from the root up,
1032 * but structural hair springs are stored in reverse order.
1033 * The bending springs however are then inserted in the same
1034 * order as vertices again ...
1035 * This messy situation can be resolved when solver data is
1036 * generated directly from a dedicated hair system.
1037 */
1038
1039 prev_mn = -1;
1040 for (search = cloth->springs; search; search = search->next) {
1041 ClothSpring *spring = static_cast<ClothSpring *>(search->link);
1042 ClothHairData *hair_ij, *hair_kl;
1043 bool is_root = spring->kl != prev_mn;
1044
1045 if (spring->type != CLOTH_SPRING_TYPE_BENDING_HAIR) {
1046 continue;
1047 }
1048
1049 hair_ij = &clmd->hairdata[spring->ij];
1050 hair_kl = &clmd->hairdata[spring->kl];
1051 if (is_root) {
1052 /* initial hair frame from root orientation */
1053 copy_m3_m3(hair_frame, hair_ij->rot);
1054 /* surface normal is the initial direction,
1055 * parallel transport then keeps it aligned to the hair direction
1056 */
1057 copy_v3_v3(dir_new, hair_frame[2]);
1058 }
1059
1060 copy_v3_v3(dir_old, dir_new);
1061 sub_v3_v3v3(dir_new, cloth->verts[spring->mn].xrest, cloth->verts[spring->kl].xrest);
1062 normalize_v3(dir_new);
1063
1064 /* dir expressed in the hair frame defines the rest target direction */
1065 copy_v3_v3(hair_kl->rest_target, dir_new);
1066 mul_transposed_m3_v3(hair_frame, hair_kl->rest_target);
1067
1068 /* move frame to next hair segment */
1069 cloth_parallel_transport_hair_frame(hair_frame, dir_old, dir_new);
1070
1071 prev_mn = spring->mn;
1072 }
1073}
1074
1075/* update stiffness if vertex group values are changing from frame to frame */
1077{
1078 Cloth *cloth = clmd->clothObject;
1079 LinkNode *search = nullptr;
1080
1081 search = cloth->springs;
1082 while (search) {
1083 ClothSpring *spring = static_cast<ClothSpring *>(search->link);
1084
1085 spring->lin_stiffness = 0.0f;
1086
1088 if (spring->type & CLOTH_SPRING_TYPE_BENDING) {
1089 spring->ang_stiffness = (cloth->verts[spring->kl].bend_stiff +
1090 cloth->verts[spring->ij].bend_stiff) /
1091 2.0f;
1092 }
1093 }
1094
1095 if (spring->type & CLOTH_SPRING_TYPE_STRUCTURAL) {
1096 spring->lin_stiffness = (cloth->verts[spring->kl].struct_stiff +
1097 cloth->verts[spring->ij].struct_stiff) /
1098 2.0f;
1099 }
1100 else if (spring->type & CLOTH_SPRING_TYPE_SHEAR) {
1101 spring->lin_stiffness = (cloth->verts[spring->kl].shear_stiff +
1102 cloth->verts[spring->ij].shear_stiff) /
1103 2.0f;
1104 }
1105 else if (spring->type == CLOTH_SPRING_TYPE_BENDING) {
1106 spring->lin_stiffness = (cloth->verts[spring->kl].bend_stiff +
1107 cloth->verts[spring->ij].bend_stiff) /
1108 2.0f;
1109 }
1110 else if (spring->type & CLOTH_SPRING_TYPE_INTERNAL) {
1111 spring->lin_stiffness = (cloth->verts[spring->kl].internal_stiff +
1112 cloth->verts[spring->ij].internal_stiff) /
1113 2.0f;
1114 }
1115 else if (spring->type == CLOTH_SPRING_TYPE_BENDING_HAIR) {
1116 ClothVertex *v1 = &cloth->verts[spring->ij];
1117 ClothVertex *v2 = &cloth->verts[spring->kl];
1118 if (clmd->hairdata) {
1119 /* copy extra hair data to generic cloth vertices */
1120 v1->bend_stiff = clmd->hairdata[spring->ij].bending_stiffness;
1121 v2->bend_stiff = clmd->hairdata[spring->kl].bending_stiffness;
1122 }
1123 spring->lin_stiffness = (v1->bend_stiff + v2->bend_stiff) / 2.0f;
1124 }
1125 else if (spring->type == CLOTH_SPRING_TYPE_GOAL) {
1126 /* WARNING: Appending NEW goal springs does not work
1127 * because implicit solver would need reset! */
1128
1129 /* Activate / Deactivate existing springs */
1130 if (!(cloth->verts[spring->ij].flags & CLOTH_VERT_FLAG_PINNED) &&
1131 (cloth->verts[spring->ij].goal > ALMOST_ZERO))
1132 {
1133 spring->flags &= ~CLOTH_SPRING_FLAG_DEACTIVATE;
1134 }
1135 else {
1137 }
1138 }
1139
1140 search = search->next;
1141 }
1142
1144}
1145
1146/* Update rest verts, for dynamically deformable cloth */
1147static void cloth_update_verts(Object *ob, ClothModifierData *clmd, Mesh *mesh)
1148{
1149 using namespace blender;
1150 uint i = 0;
1151 const Span<float3> positions = mesh->vert_positions();
1153
1154 /* vertex count is already ensured to match */
1155 for (i = 0; i < mesh->verts_num; i++, verts++) {
1156 copy_v3_v3(verts->xrest, positions[i]);
1157 mul_m4_v3(ob->object_to_world().ptr(), verts->xrest);
1158 }
1159}
1160
1161/* Write rest vert locations to a copy of the mesh. */
1163{
1164 using namespace blender;
1165 Mesh *new_mesh = BKE_mesh_copy_for_eval(*mesh);
1167 MutableSpan<float3> positions = mesh->vert_positions_for_write();
1168
1169 /* vertex count is already ensured to match */
1170 for (const int i : positions.index_range()) {
1171 positions[i] = verts[i].xrest;
1172 }
1173 new_mesh->tag_positions_changed();
1174
1175 return new_mesh;
1176}
1177
1178/* Update spring rest length, for dynamically deformable cloth */
1180{
1181 Cloth *cloth = clmd->clothObject;
1182 LinkNode *search = cloth->springs;
1183 uint struct_springs = 0;
1184 uint i = 0;
1185 uint mvert_num = uint(mesh->verts_num);
1186 float shrink_factor;
1187
1188 clmd->sim_parms->avg_spring_len = 0.0f;
1189
1190 for (i = 0; i < mvert_num; i++) {
1191 cloth->verts[i].avg_spring_len = 0.0f;
1192 }
1193
1194 while (search) {
1195 ClothSpring *spring = static_cast<ClothSpring *>(search->link);
1196
1197 if (spring->type != CLOTH_SPRING_TYPE_SEWING) {
1200 {
1201 shrink_factor = cloth_shrink_factor(clmd, cloth->verts, spring->ij, spring->kl);
1202 }
1203 else {
1204 shrink_factor = 1.0f;
1205 }
1206
1207 spring->restlen = len_v3v3(cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest) *
1208 shrink_factor;
1209
1210 if (spring->type & CLOTH_SPRING_TYPE_BENDING) {
1211 spring->restang = cloth_spring_angle(
1212 cloth->verts, spring->ij, spring->kl, spring->pa, spring->pb, spring->la, spring->lb);
1213 }
1214 }
1215
1216 if (spring->type & CLOTH_SPRING_TYPE_STRUCTURAL) {
1217 clmd->sim_parms->avg_spring_len += spring->restlen;
1218 cloth->verts[spring->ij].avg_spring_len += spring->restlen;
1219 cloth->verts[spring->kl].avg_spring_len += spring->restlen;
1220 struct_springs++;
1221 }
1222
1223 search = search->next;
1224 }
1225
1226 if (struct_springs > 0) {
1227 clmd->sim_parms->avg_spring_len /= struct_springs;
1228 }
1229
1230 for (i = 0; i < mvert_num; i++) {
1231 if (cloth->verts[i].spring_count > 0) {
1232 cloth->verts[i].avg_spring_len = cloth->verts[i].avg_spring_len * 0.49f /
1233 float(cloth->verts[i].spring_count);
1234 }
1235 }
1236}
1237
1238BLI_INLINE void cross_identity_v3(float r[3][3], const float v[3])
1239{
1240 zero_m3(r);
1241 r[0][1] = v[2];
1242 r[0][2] = -v[1];
1243 r[1][0] = -v[2];
1244 r[1][2] = v[0];
1245 r[2][0] = v[1];
1246 r[2][1] = -v[0];
1247}
1248
1249BLI_INLINE void madd_m3_m3fl(float r[3][3], const float m[3][3], float f)
1250{
1251 r[0][0] += m[0][0] * f;
1252 r[0][1] += m[0][1] * f;
1253 r[0][2] += m[0][2] * f;
1254 r[1][0] += m[1][0] * f;
1255 r[1][1] += m[1][1] * f;
1256 r[1][2] += m[1][2] * f;
1257 r[2][0] += m[2][0] * f;
1258 r[2][1] += m[2][1] * f;
1259 r[2][2] += m[2][2] * f;
1260}
1261
1263 const float dir_old[3],
1264 const float dir_new[3])
1265{
1266 float rot[3][3];
1267
1268 /* rotation between segments */
1269 rotation_between_vecs_to_mat3(rot, dir_old, dir_new);
1270
1271 /* rotate the frame */
1272 mul_m3_m3m3(mat, rot, mat);
1273}
1274
1275/* Add a shear and a bend spring between two verts within a face. */
1277 LinkNodePair *edgelist,
1278 const blender::Span<int> corner_verts,
1279 const blender::OffsetIndices<int> faces,
1280 int i,
1281 int j,
1282 int k)
1283{
1284 Cloth *cloth = clmd->clothObject;
1285 ClothSpring *spring;
1286 const int *tmp_corner;
1287 float shrink_factor;
1288 int x, y;
1289
1290 /* Combined shear/bend properties. */
1291 spring = (ClothSpring *)MEM_callocN(sizeof(ClothSpring), "cloth spring");
1292
1293 if (!spring) {
1294 return false;
1295 }
1296
1297 spring_verts_ordered_set(spring, corner_verts[faces[i][j]], corner_verts[faces[i][k]]);
1298
1299 shrink_factor = cloth_shrink_factor(clmd, cloth->verts, spring->ij, spring->kl);
1300 spring->restlen = len_v3v3(cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest) *
1301 shrink_factor;
1302 spring->type |= CLOTH_SPRING_TYPE_SHEAR;
1303 spring->lin_stiffness = (cloth->verts[spring->kl].shear_stiff +
1304 cloth->verts[spring->ij].shear_stiff) /
1305 2.0f;
1306
1307 if (edgelist) {
1308 BLI_linklist_append(&edgelist[spring->ij], spring);
1309 BLI_linklist_append(&edgelist[spring->kl], spring);
1310 }
1311
1312 /* Bending specific properties. */
1315
1316 spring->la = k - j + 1;
1317 spring->lb = faces[i].size() - k + j + 1;
1318
1319 spring->pa = static_cast<int *>(MEM_mallocN(sizeof(*spring->pa) * spring->la, "spring poly"));
1320 if (!spring->pa) {
1321 return false;
1322 }
1323
1324 spring->pb = static_cast<int *>(MEM_mallocN(sizeof(*spring->pb) * spring->lb, "spring poly"));
1325 if (!spring->pb) {
1326 return false;
1327 }
1328
1329 tmp_corner = &corner_verts[faces[i].start()];
1330
1331 for (x = 0; x < spring->la; x++) {
1332 spring->pa[x] = tmp_corner[j + x];
1333 }
1334
1335 for (x = 0; x <= j; x++) {
1336 spring->pb[x] = tmp_corner[x];
1337 }
1338
1339 for (y = k; y < faces[i].size(); x++, y++) {
1340 spring->pb[x] = tmp_corner[y];
1341 }
1342
1343 spring->mn = -1;
1344
1345 spring->restang = cloth_spring_angle(
1346 cloth->verts, spring->ij, spring->kl, spring->pa, spring->pb, spring->la, spring->lb);
1347
1348 spring->ang_stiffness = (cloth->verts[spring->ij].bend_stiff +
1349 cloth->verts[spring->kl].bend_stiff) /
1350 2.0f;
1351 }
1352
1353 BLI_linklist_prepend(&cloth->springs, spring);
1354
1355 return true;
1356}
1357
1358BLI_INLINE bool cloth_bend_set_poly_vert_array(int **poly, int len, const int *corner_verts)
1359{
1360 int *p = static_cast<int *>(MEM_mallocN(sizeof(int) * len, "spring poly"));
1361
1362 if (!p) {
1363 return false;
1364 }
1365
1366 for (int i = 0; i < len; i++) {
1367 p[i] = corner_verts[i];
1368 }
1369
1370 *poly = p;
1371
1372 return true;
1373}
1374
1376 const blender::Span<blender::float3> vert_normals,
1377 uint v_idx,
1378 RNG *rng,
1379 float max_length,
1380 float max_diversion,
1381 bool check_normal,
1382 int *r_tar_v_idx)
1383{
1384 float co[3], no[3], new_co[3];
1385 float radius;
1386
1387 copy_v3_v3(co, treedata->vert_positions[v_idx]);
1388 negate_v3_v3(no, vert_normals[v_idx]);
1389
1390 float vec_len = sin(max_diversion);
1391 float offset[3];
1392
1393 offset[0] = 0.5f - BLI_rng_get_float(rng);
1394 offset[1] = 0.5f - BLI_rng_get_float(rng);
1395 offset[2] = 0.5f - BLI_rng_get_float(rng);
1396
1397 normalize_v3(offset);
1398 mul_v3_fl(offset, vec_len);
1399 add_v3_v3(no, offset);
1400 normalize_v3(no);
1401
1402 /* Nudge the start point so we do not hit it with the ray. */
1403 copy_v3_v3(new_co, no);
1404 mul_v3_fl(new_co, FLT_EPSILON);
1405 add_v3_v3(new_co, co);
1406
1407 radius = 0.0f;
1408 if (max_length == 0.0f) {
1409 max_length = FLT_MAX;
1410 }
1411
1412 BVHTreeRayHit rayhit = {0};
1413 rayhit.index = -1;
1414 rayhit.dist = max_length;
1415
1417 treedata->tree, new_co, no, radius, &rayhit, treedata->raycast_callback, treedata);
1418
1419 int vert_idx = -1;
1420 const int *corner_verts = treedata->corner_verts.data();
1421
1422 if (rayhit.index != -1 && rayhit.dist <= max_length) {
1423 if (check_normal && dot_v3v3(rayhit.no, no) < 0.0f) {
1424 /* We hit a point that points in the same direction as our starting point. */
1425 return false;
1426 }
1427
1428 float min_len = FLT_MAX;
1429 const blender::int3 &tri = treedata->corner_tris[rayhit.index];
1430
1431 for (int i = 0; i < 3; i++) {
1432 int tmp_vert_idx = corner_verts[tri[i]];
1433 if (tmp_vert_idx == v_idx) {
1434 /* We managed to hit ourselves. */
1435 return false;
1436 }
1437
1438 float len = len_v3v3(co, rayhit.co);
1439 if (len < min_len) {
1440 min_len = len;
1441 vert_idx = tmp_vert_idx;
1442 }
1443 }
1444
1445 *r_tar_v_idx = vert_idx;
1446 return true;
1447 }
1448
1449 return false;
1450}
1451
1453{
1454 using namespace blender;
1455 using namespace blender::bke;
1456 Cloth *cloth = clmd->clothObject;
1457 ClothSpring *spring = nullptr, *tspring = nullptr, *tspring2 = nullptr;
1458 uint struct_springs = 0, shear_springs = 0, bend_springs = 0, struct_springs_real = 0;
1459 uint mvert_num = uint(mesh->verts_num);
1460 uint numedges = uint(mesh->edges_num);
1461 uint numface = uint(mesh->faces_num);
1462 float shrink_factor;
1463 const blender::Span<int2> edges = mesh->edges();
1464 const OffsetIndices faces = mesh->faces();
1465 const Span<int> corner_verts = mesh->corner_verts();
1466 const Span<int> corner_edges = mesh->corner_edges();
1467 int index2 = 0; /* our second vertex index */
1468 LinkNodePair *edgelist = nullptr;
1469 LinkNode *search = nullptr, *search2 = nullptr;
1470 BendSpringRef *spring_ref = nullptr;
1471
1472 /* error handling */
1473 if (numedges == 0) {
1474 return false;
1475 }
1476
1477 /* NOTE: handling ownership of springs and edgeset is quite sloppy
1478 * currently they are never initialized but assert just to be sure */
1479 BLI_assert(cloth->springs == nullptr);
1480 BLI_assert(cloth->edgeset.is_empty());
1481
1482 cloth->springs = nullptr;
1483
1485 spring_ref = static_cast<BendSpringRef *>(
1486 MEM_callocN(sizeof(*spring_ref) * numedges, __func__));
1487
1488 if (!spring_ref) {
1489 return false;
1490 }
1491 }
1492 else {
1493 edgelist = static_cast<LinkNodePair *>(MEM_callocN(sizeof(*edgelist) * mvert_num, __func__));
1494
1495 if (!edgelist) {
1496 return false;
1497 }
1498 }
1499
1500 bool use_internal_springs = (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_INTERNAL_SPRINGS);
1501
1502 if (use_internal_springs && numface > 0) {
1503 BVHTreeFromMesh treedata = {nullptr};
1504 int tar_v_idx;
1505 Mesh *tmp_mesh = nullptr;
1506 RNG *rng;
1507
1508 /* If using the rest shape key, it's necessary to make a copy of the mesh. */
1509 if (clmd->sim_parms->shapekey_rest &&
1511 {
1512 tmp_mesh = cloth_make_rest_mesh(clmd, mesh);
1513 }
1514
1515 Set<OrderedEdge> existing_vert_pairs;
1516 BKE_bvhtree_from_mesh_get(&treedata, tmp_mesh ? tmp_mesh : mesh, BVHTREE_FROM_CORNER_TRIS, 2);
1517 rng = BLI_rng_new_srandom(0);
1518
1519 const blender::Span<blender::float3> vert_normals = tmp_mesh ? tmp_mesh->vert_normals() :
1520 mesh->vert_normals();
1521
1522 for (int i = 0; i < mvert_num; i++) {
1524 &treedata,
1525 vert_normals,
1526 i,
1527 rng,
1531 &tar_v_idx))
1532 {
1533 if (existing_vert_pairs.contains({i, tar_v_idx})) {
1534 /* We have already created a spring between these verts! */
1535 continue;
1536 }
1537
1538 existing_vert_pairs.add({i, tar_v_idx});
1539
1540 spring = (ClothSpring *)MEM_callocN(sizeof(ClothSpring), "cloth spring");
1541
1542 if (spring) {
1543 spring_verts_ordered_set(spring, i, tar_v_idx);
1544
1545 shrink_factor = cloth_shrink_factor(clmd, cloth->verts, spring->ij, spring->kl);
1546 spring->restlen = len_v3v3(cloth->verts[spring->kl].xrest,
1547 cloth->verts[spring->ij].xrest) *
1548 shrink_factor;
1549 spring->lin_stiffness = (cloth->verts[spring->kl].internal_stiff +
1550 cloth->verts[spring->ij].internal_stiff) /
1551 2.0f;
1553
1554 spring->flags = 0;
1555
1556 BLI_linklist_prepend(&cloth->springs, spring);
1557
1558 if (spring_ref) {
1559 spring_ref[i].spring = spring;
1560 }
1561 }
1562 else {
1563 cloth_free_errorsprings(cloth, edgelist, spring_ref);
1564 free_bvhtree_from_mesh(&treedata);
1565 if (tmp_mesh) {
1566 BKE_id_free(nullptr, &tmp_mesh->id);
1567 }
1568 BLI_rng_free(rng);
1569 return false;
1570 }
1571 }
1572 }
1573 existing_vert_pairs.clear_and_shrink();
1574 free_bvhtree_from_mesh(&treedata);
1575 if (tmp_mesh) {
1576 BKE_id_free(nullptr, &tmp_mesh->id);
1577 }
1578 BLI_rng_free(rng);
1579 }
1580
1581 clmd->sim_parms->avg_spring_len = 0.0f;
1582 for (int i = 0; i < mvert_num; i++) {
1583 cloth->verts[i].avg_spring_len = 0.0f;
1584 }
1585
1587 /* cloth->sew_edge_graph should not exist before this */
1588 BLI_assert(cloth->sew_edge_graph.is_empty());
1589 }
1590
1591 /* Structural springs. */
1592 const LooseEdgeCache &loose_edges = mesh->loose_edges();
1593 for (int i = 0; i < numedges; i++) {
1594 spring = (ClothSpring *)MEM_callocN(sizeof(ClothSpring), "cloth spring");
1595
1596 if (spring) {
1597 spring_verts_ordered_set(spring, edges[i][0], edges[i][1]);
1598 if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SEW && loose_edges.count > 0 &&
1599 loose_edges.is_loose_bits[i])
1600 {
1601 /* handle sewing (loose edges will be pulled together) */
1602 spring->restlen = 0.0f;
1603 spring->lin_stiffness = 1.0f;
1605
1606 cloth->sew_edge_graph.add({edges[i][0], edges[i][1]});
1607 }
1608 else {
1609 shrink_factor = cloth_shrink_factor(clmd, cloth->verts, spring->ij, spring->kl);
1610 spring->restlen = len_v3v3(cloth->verts[spring->kl].xrest,
1611 cloth->verts[spring->ij].xrest) *
1612 shrink_factor;
1613 spring->lin_stiffness = (cloth->verts[spring->kl].struct_stiff +
1614 cloth->verts[spring->ij].struct_stiff) /
1615 2.0f;
1617
1618 clmd->sim_parms->avg_spring_len += spring->restlen;
1619 cloth->verts[spring->ij].avg_spring_len += spring->restlen;
1620 cloth->verts[spring->kl].avg_spring_len += spring->restlen;
1621 cloth->verts[spring->ij].spring_count++;
1622 cloth->verts[spring->kl].spring_count++;
1623 struct_springs_real++;
1624 }
1625
1626 spring->flags = 0;
1627 struct_springs++;
1628
1629 BLI_linklist_prepend(&cloth->springs, spring);
1630
1631 if (spring_ref) {
1632 spring_ref[i].spring = spring;
1633 }
1634 }
1635 else {
1636 cloth_free_errorsprings(cloth, edgelist, spring_ref);
1637 return false;
1638 }
1639 }
1640
1641 if (struct_springs_real > 0) {
1642 clmd->sim_parms->avg_spring_len /= struct_springs_real;
1643 }
1644
1645 for (int i = 0; i < mvert_num; i++) {
1646 if (cloth->verts[i].spring_count > 0) {
1647 cloth->verts[i].avg_spring_len = cloth->verts[i].avg_spring_len * 0.49f /
1648 float(cloth->verts[i].spring_count);
1649 }
1650 }
1651
1652 cloth->edgeset.reserve(numedges);
1653
1654 if (numface) {
1655 for (int i = 0; i < numface; i++) {
1656 /* Shear springs. */
1657 /* Triangle faces already have shear springs due to structural geometry. */
1658 if (faces[i].size() > 3) {
1659 for (int j = 1; j < faces[i].size() - 1; j++) {
1660 if (j > 1) {
1661 if (cloth_add_shear_bend_spring(clmd, edgelist, corner_verts, faces, i, 0, j)) {
1662 shear_springs++;
1663
1665 bend_springs++;
1666 }
1667 }
1668 else {
1669 cloth_free_errorsprings(cloth, edgelist, spring_ref);
1670 return false;
1671 }
1672 }
1673
1674 for (int k = j + 2; k < faces[i].size(); k++) {
1675 if (cloth_add_shear_bend_spring(clmd, edgelist, corner_verts, faces, i, j, k)) {
1676 shear_springs++;
1677
1679 bend_springs++;
1680 }
1681 }
1682 else {
1683 cloth_free_errorsprings(cloth, edgelist, spring_ref);
1684 return false;
1685 }
1686 }
1687 }
1688 }
1689
1690 /* Angular bending springs along struct springs. */
1692 for (int j = 0; j < faces[i].size(); j++) {
1693 const int edge_i = corner_edges[faces[i][j]];
1694 BendSpringRef *curr_ref = &spring_ref[edge_i];
1695 curr_ref->face++;
1696
1697 /* First poly found for this edge, store poly index. */
1698 if (curr_ref->face == 1) {
1699 curr_ref->index = i;
1700 }
1701 /* Second poly found for this edge, add bending data. */
1702 else if (curr_ref->face == 2) {
1703 spring = curr_ref->spring;
1704
1706
1707 spring->la = faces[curr_ref->index].size();
1708 spring->lb = faces[i].size();
1709
1711 &spring->pa, spring->la, &corner_verts[faces[curr_ref->index].start()]) ||
1713 &spring->pb, spring->lb, &corner_verts[faces[i].start()]))
1714 {
1715 cloth_free_errorsprings(cloth, edgelist, spring_ref);
1716 return false;
1717 }
1718
1719 spring->mn = edge_i;
1720
1721 spring->restang = cloth_spring_angle(cloth->verts,
1722 spring->ij,
1723 spring->kl,
1724 spring->pa,
1725 spring->pb,
1726 spring->la,
1727 spring->lb);
1728
1729 spring->ang_stiffness = (cloth->verts[spring->ij].bend_stiff +
1730 cloth->verts[spring->kl].bend_stiff) /
1731 2.0f;
1732
1733 bend_springs++;
1734 }
1735 /* Third poly found for this edge, remove bending data. */
1736 else if (curr_ref->face == 3) {
1737 spring = curr_ref->spring;
1738
1739 spring->type &= ~CLOTH_SPRING_TYPE_BENDING;
1740 MEM_freeN(spring->pa);
1741 MEM_freeN(spring->pb);
1742 spring->pa = nullptr;
1743 spring->pb = nullptr;
1744
1745 bend_springs--;
1746 }
1747 }
1748 }
1749 }
1750
1751 /* Linear bending springs. */
1753 search2 = cloth->springs;
1754
1755 for (int i = struct_springs; i < struct_springs + shear_springs; i++) {
1756 if (!search2) {
1757 break;
1758 }
1759
1760 tspring2 = static_cast<ClothSpring *>(search2->link);
1761 search = edgelist[tspring2->kl].list;
1762
1763 while (search) {
1764 tspring = static_cast<ClothSpring *>(search->link);
1765 index2 = ((tspring->ij == tspring2->kl) ? (tspring->kl) : (tspring->ij));
1766
1767 /* Check for existing spring. */
1768 /* Check also if start-point is equal to endpoint. */
1769 if ((index2 != tspring2->ij) && !cloth->edgeset.contains({tspring2->ij, index2})) {
1770 spring = (ClothSpring *)MEM_callocN(sizeof(ClothSpring), "cloth spring");
1771
1772 if (!spring) {
1773 cloth_free_errorsprings(cloth, edgelist, spring_ref);
1774 return false;
1775 }
1776
1777 spring_verts_ordered_set(spring, tspring2->ij, index2);
1778 shrink_factor = cloth_shrink_factor(clmd, cloth->verts, spring->ij, spring->kl);
1779 spring->restlen = len_v3v3(cloth->verts[spring->kl].xrest,
1780 cloth->verts[spring->ij].xrest) *
1781 shrink_factor;
1783 spring->lin_stiffness = (cloth->verts[spring->kl].bend_stiff +
1784 cloth->verts[spring->ij].bend_stiff) /
1785 2.0f;
1786 cloth->edgeset.add({spring->ij, spring->kl});
1787 bend_springs++;
1788
1789 BLI_linklist_prepend(&cloth->springs, spring);
1790 }
1791
1792 search = search->next;
1793 }
1794
1795 search2 = search2->next;
1796 }
1797 }
1798 }
1799 else if (struct_springs > 2) {
1800 if (G.debug_value != 1112) {
1801 search = cloth->springs;
1802 search2 = search->next;
1803 while (search && search2) {
1804 tspring = static_cast<ClothSpring *>(search->link);
1805 tspring2 = static_cast<ClothSpring *>(search2->link);
1806
1807 if (tspring->ij == tspring2->kl) {
1808 spring = (ClothSpring *)MEM_callocN(sizeof(ClothSpring), "cloth spring");
1809
1810 if (!spring) {
1811 cloth_free_errorsprings(cloth, edgelist, spring_ref);
1812 return false;
1813 }
1814
1815 spring->ij = tspring2->ij;
1816 spring->kl = tspring->ij;
1817 spring->mn = tspring->kl;
1818 spring->restlen = len_v3v3(cloth->verts[spring->kl].xrest,
1819 cloth->verts[spring->ij].xrest);
1821 spring->lin_stiffness = (cloth->verts[spring->kl].bend_stiff +
1822 cloth->verts[spring->ij].bend_stiff) /
1823 2.0f;
1824 bend_springs++;
1825
1826 BLI_linklist_prepend(&cloth->springs, spring);
1827 }
1828
1829 search = search->next;
1830 search2 = search2->next;
1831 }
1832 }
1833 else {
1834 /* bending springs for hair strands
1835 * The current algorithm only goes through the edges in order of the mesh edges list
1836 * and makes springs between the outer vert of edges sharing a vertex. This works just
1837 * fine for hair, but not for user generated string meshes. This could/should be later
1838 * extended to work with non-ordered edges so that it can be used for general "rope
1839 * dynamics" without the need for the vertices or edges to be ordered through the length
1840 * of the strands. -jahka */
1841 search = cloth->springs;
1842 search2 = search->next;
1843 while (search && search2) {
1844 tspring = static_cast<ClothSpring *>(search->link);
1845 tspring2 = static_cast<ClothSpring *>(search2->link);
1846
1847 if (tspring->ij == tspring2->kl) {
1848 spring = (ClothSpring *)MEM_callocN(sizeof(ClothSpring), "cloth spring");
1849
1850 if (!spring) {
1851 cloth_free_errorsprings(cloth, edgelist, spring_ref);
1852 return false;
1853 }
1854
1855 spring->ij = tspring2->ij;
1856 spring->kl = tspring->kl;
1857 spring->restlen = len_v3v3(cloth->verts[spring->kl].xrest,
1858 cloth->verts[spring->ij].xrest);
1860 spring->lin_stiffness = (cloth->verts[spring->kl].bend_stiff +
1861 cloth->verts[spring->ij].bend_stiff) /
1862 2.0f;
1863 bend_springs++;
1864
1865 BLI_linklist_prepend(&cloth->springs, spring);
1866 }
1867
1868 search = search->next;
1869 search2 = search2->next;
1870 }
1871 }
1872
1874 }
1875
1876 /* NOTE: the edges may already exist so run reinsert. */
1877
1878 /* Insert other near springs in `edgeset` AFTER bending springs are calculated
1879 * (for self-collision). */
1880 for (int i = 0; i < numedges; i++) { /* struct springs */
1881 cloth->edgeset.add({edges[i][0], edges[i][1]});
1882 }
1883
1884 for (int i = 0; i < numface; i++) { /* edge springs */
1885 if (faces[i].size() == 4) {
1886 cloth->edgeset.add({corner_verts[faces[i].start() + 0], corner_verts[faces[i].start() + 2]});
1887 cloth->edgeset.add({corner_verts[faces[i].start() + 1], corner_verts[faces[i].start() + 3]});
1888 }
1889 }
1890
1891 MEM_SAFE_FREE(spring_ref);
1892
1893 cloth->numsprings = struct_springs + shear_springs + bend_springs;
1894
1895 cloth_free_edgelist(edgelist, mvert_num);
1896
1897#if 0
1898 if (G.debug_value > 0) {
1899 printf("avg_len: %f\n", clmd->sim_parms->avg_spring_len);
1900 }
1901#endif
1902
1903 return true;
1904}
1905
void free_bvhtree_from_mesh(BVHTreeFromMesh *data)
Definition bvhutils.cc:1160
BVHTree * BKE_bvhtree_from_mesh_get(BVHTreeFromMesh *data, const Mesh *mesh, BVHCacheType bvh_cache_type, int tree_type)
Definition bvhutils.cc:899
@ BVHTREE_FROM_CORNER_TRIS
@ CLOTH_SPRING_TYPE_SEWING
Definition BKE_cloth.hh:190
@ CLOTH_SPRING_TYPE_SHEAR
Definition BKE_cloth.hh:187
@ CLOTH_SPRING_TYPE_BENDING_HAIR
Definition BKE_cloth.hh:191
@ CLOTH_SPRING_TYPE_STRUCTURAL
Definition BKE_cloth.hh:186
@ CLOTH_SPRING_TYPE_BENDING
Definition BKE_cloth.hh:188
@ CLOTH_SPRING_TYPE_GOAL
Definition BKE_cloth.hh:189
@ CLOTH_SPRING_TYPE_INTERNAL
Definition BKE_cloth.hh:192
@ CLOTH_VERT_FLAG_PINNED
Definition BKE_cloth.hh:38
@ CLOTH_VERT_FLAG_NOSELFCOLL
Definition BKE_cloth.hh:39
@ CLOTH_VERT_FLAG_NOOBJCOLL
Definition BKE_cloth.hh:40
@ CLOTH_SPRING_FLAG_DEACTIVATE
Definition BKE_cloth.hh:197
#define SOFTGOALSNAP
Definition BKE_cloth.hh:30
#define ALMOST_ZERO
Definition BKE_cloth.hh:34
CustomData interface, see also DNA_customdata_types.h.
const void * CustomData_get_layer(const CustomData *data, eCustomDataType type)
void BKE_effectors_free(struct ListBase *lb)
Definition effect.cc:364
struct ListBase * BKE_effectors_create(struct Depsgraph *depsgraph, struct Object *ob_src, struct ParticleSystem *psys_src, struct EffectorWeights *weights, bool use_rotation)
Definition effect.cc:309
@ G_DEBUG_SIMDATA
void BKE_id_free(Main *bmain, void *idv)
Mesh * BKE_mesh_copy_for_eval(const Mesh &source)
void BKE_modifier_set_error(const Object *ob, ModifierData *md, const char *format,...) ATTR_PRINTF_FORMAT(3
void BKE_ptcache_id_time(PTCacheID *pid, struct Scene *scene, float cfra, int *startframe, int *endframe, float *timescale)
#define PTCACHE_CLEAR_AFTER
void BKE_ptcache_validate(struct PointCache *cache, int framenr)
#define PTCACHE_READ_INTERPOLATED
#define PTCACHE_READ_OLD
int BKE_ptcache_read(PTCacheID *pid, float cfra, bool no_extrapolate_old)
void BKE_ptcache_id_clear(PTCacheID *pid, int mode, unsigned int cfra)
void BKE_ptcache_id_from_cloth(PTCacheID *pid, struct Object *ob, struct ClothModifierData *clmd)
int BKE_ptcache_write(PTCacheID *pid, unsigned int cfra)
#define PTCACHE_RESET_OUTDATED
int BKE_ptcache_id_reset(struct Scene *scene, PTCacheID *pid, int mode)
void BKE_ptcache_invalidate(struct PointCache *cache)
#define PTCACHE_READ_EXACT
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_INLINE
BVHTree * BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis)
void BLI_bvhtree_balance(BVHTree *tree)
void BLI_bvhtree_update_tree(BVHTree *tree)
void BLI_bvhtree_free(BVHTree *tree)
void BLI_bvhtree_insert(BVHTree *tree, int index, const float co[3], int numpoints)
bool BLI_bvhtree_update_node(BVHTree *tree, int index, const float co[3], const float co_moving[3], int numpoints)
int BLI_bvhtree_ray_cast(const BVHTree *tree, const float co[3], const float dir[3], float radius, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata)
MINLINE int compare_ff(float a, float b, float max_diff)
MINLINE float pow4f(float x)
float normal_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3])
Definition math_geom.cc:39
void copy_m3_m3(float m1[3][3], const float m2[3][3])
void zero_m3(float m[3][3])
void mul_m4_v3(const float M[4][4], float r[3])
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
void mul_v3_m3v3(float r[3], const float M[3][3], const float a[3])
void mul_transposed_m3_v3(const float M[3][3], float r[3])
void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
void rotation_between_vecs_to_mat3(float m[3][3], const float v1[3], const float v2[3])
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 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 void negate_v3_v3(float r[3], const float a[3])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
MINLINE float normalize_v3(float n[3])
Random number functions.
void BLI_rng_free(struct RNG *rng) ATTR_NONNULL(1)
Definition rand.cc:58
struct RNG * BLI_rng_new_srandom(unsigned int seed)
Definition rand.cc:46
float BLI_rng_get_float(struct RNG *rng) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition rand.cc:93
unsigned int uint
float DEG_get_ctime(const Depsgraph *graph)
@ CLOTH_BENDING_LINEAR
@ CLOTH_BENDING_ANGULAR
@ CLOTH_COLLSETTINGS_FLAG_ENABLED
@ CLOTH_COLLSETTINGS_FLAG_SELF
@ CLOTH_SIMSETTINGS_FLAG_DYNAMIC_BASEMESH
@ CLOTH_SIMSETTINGS_FLAG_INTERNAL_SPRINGS_NORMAL
@ CLOTH_SIMSETTINGS_FLAG_PRESSURE_VOL
@ CLOTH_SIMSETTINGS_FLAG_SEW
@ CLOTH_SIMSETTINGS_FLAG_PRESSURE
@ CLOTH_SIMSETTINGS_FLAG_INTERNAL_SPRINGS
@ CD_CLOTH_ORCO
@ OB_MODE_PARTICLE_EDIT
Object is a sort of wrapper for general info.
@ PTCACHE_BAKED
@ PTCACHE_OUTDATED
@ PTCACHE_REDO_NEEDED
#define MINFRAME
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
void SIM_cloth_solver_free(ClothModifierData *clmd)
int SIM_cloth_solver_init(Object *, ClothModifierData *clmd)
void SIM_cloth_solver_set_volume(ClothModifierData *clmd)
void SIM_mass_spring_set_implicit_vertex_mass(Implicit_Data *data, int index, float mass)
void SIM_cloth_solver_set_positions(ClothModifierData *clmd)
int SIM_cloth_solve(Depsgraph *depsgraph, Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors)
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert * v
PyObject * self
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
constexpr const T * data() const
Definition BLI_span.hh:216
constexpr int64_t size() const
Definition BLI_span.hh:253
constexpr bool is_empty() const
Definition BLI_span.hh:261
static void cloth_update_verts(Object *ob, ClothModifierData *clmd, Mesh *mesh)
Definition cloth.cc:1147
static bool do_init_cloth(Object *ob, ClothModifierData *clmd, Mesh *result, int framenr)
Definition cloth.cc:214
static float cloth_spring_angle(ClothVertex *verts, int i, int j, int *i_a, int *i_b, int len_a, int len_b)
Definition cloth.cc:938
BLI_INLINE void cross_identity_v3(float r[3][3], const float v[3])
Definition cloth.cc:1238
void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr)
Definition cloth.cc:200
static void cloth_apply_vgroup(ClothModifierData *clmd, Mesh *mesh)
Definition cloth.cc:602
BLI_INLINE void cloth_bend_poly_dir(ClothVertex *verts, int i, int j, const int *inds, int len, float r_dir[3])
Definition cloth.cc:925
static bool cloth_build_springs(ClothModifierData *clmd, Mesh *mesh)
Definition cloth.cc:1452
static void cloth_to_object(Object *ob, ClothModifierData *clmd, float(*vertexCos)[3])
Definition cloth.cc:571
static void cloth_free_edgelist(LinkNodePair *edgelist, uint mvert_num)
Definition cloth.cc:887
static bool cloth_add_shear_bend_spring(ClothModifierData *clmd, LinkNodePair *edgelist, const blender::Span< int > corner_verts, const blender::OffsetIndices< int > faces, int i, int j, int k)
Definition cloth.cc:1276
static float cloth_shrink_factor(ClothModifierData *clmd, ClothVertex *verts, int i1, int i2)
Definition cloth.cc:695
static int do_step_cloth(Depsgraph *depsgraph, Object *ob, ClothModifierData *clmd, Mesh *result, int framenr)
Definition cloth.cc:250
static bool cloth_from_object(Object *ob, ClothModifierData *clmd, Mesh *mesh, float framenr, int first)
Definition cloth.cc:709
void clothModifier_do(ClothModifierData *clmd, Depsgraph *depsgraph, Scene *scene, Object *ob, Mesh *mesh, float(*vertexCos)[3])
Definition cloth.cc:319
BLI_INLINE void madd_m3_m3fl(float r[3][3], const float m[3][3], float f)
Definition cloth.cc:1249
static void cloth_hair_update_bending_rest_targets(ClothModifierData *clmd)
Definition cloth.cc:1020
static void cloth_hair_update_bending_targets(ClothModifierData *clmd)
Definition cloth.cc:962
void cloth_free_modifier_extern(ClothModifierData *clmd)
Definition cloth.cc:494
void bvhtree_update_from_cloth(ClothModifierData *clmd, bool moving, bool self)
Definition cloth.cc:121
static Mesh * cloth_make_rest_mesh(ClothModifierData *clmd, Mesh *mesh)
Definition cloth.cc:1162
int cloth_uses_vgroup(ClothModifierData *clmd)
Definition cloth.cc:587
static void cloth_update_springs(ClothModifierData *clmd)
Definition cloth.cc:1076
static bool find_internal_spring_target_vertex(BVHTreeFromMesh *treedata, const blender::Span< blender::float3 > vert_normals, uint v_idx, RNG *rng, float max_length, float max_diversion, bool check_normal, int *r_tar_v_idx)
Definition cloth.cc:1375
void cloth_parallel_transport_hair_frame(float mat[3][3], const float dir_old[3], const float dir_new[3])
Definition cloth.cc:1262
static void cloth_update_spring_lengths(ClothModifierData *clmd, Mesh *mesh)
Definition cloth.cc:1179
BLI_INLINE bool cloth_bend_set_poly_vert_array(int **poly, int len, const int *corner_verts)
Definition cloth.cc:1358
BLI_INLINE void spring_verts_ordered_set(ClothSpring *spring, int v0, int v1)
Definition cloth.cc:875
static void cloth_free_errorsprings(Cloth *cloth, LinkNodePair *edgelist, BendSpringRef *spring_ref)
Definition cloth.cc:898
void cloth_free_modifier(ClothModifierData *clmd)
Definition cloth.cc:433
static void cloth_from_mesh(ClothModifierData *clmd, const Object *ob, Mesh *mesh)
Definition cloth.cc:828
static BVHTree * bvhtree_build_from_cloth(ClothModifierData *clmd, float epsilon)
Definition cloth.cc:67
#define printf
const Depsgraph * depsgraph
#define atan2f(x, y)
#define sqrtf(x)
int len
draw_view in_light_buf[] float
#define rot(x, k)
static float verts[][3]
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
Definition mallocn.cc:45
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
ccl_device_inline float3 cos(float3 v)
#define G(x, y, z)
void vert_tris_from_corner_tris(Span< int > corner_verts, Span< int3 > corner_tris, MutableSpan< int3 > vert_tris)
return ret
#define FLT_MAX
Definition stdcycles.h:14
blender::Span< blender::int3 > corner_tris
BVHTree_RayCastCallback raycast_callback
blender::Span< blender::float3 > vert_positions
blender::Span< int > corner_verts
float co[3]
Definition BLI_kdopbvh.h:69
float no[3]
Definition BLI_kdopbvh.h:71
ClothSpring * spring
Definition cloth.cc:58
float bending_stiffness
Definition BKE_cloth.hh:48
float rest_target[3]
Definition BKE_cloth.hh:46
float rot[3][3]
Definition BKE_cloth.hh:45
struct ClothHairData * hairdata
struct Cloth * clothObject
struct PointCache * point_cache
struct ClothSimSettings * sim_parms
struct ClothCollSettings * coll_parms
struct EffectorWeights * effector_weights
float internal_spring_max_diversion
float ang_stiffness
Definition BKE_cloth.hh:133
float lin_stiffness
Definition BKE_cloth.hh:132
float target[3]
Definition BKE_cloth.hh:137
float restang
Definition BKE_cloth.hh:129
float restlen
Definition BKE_cloth.hh:128
float bend_stiff
Definition BKE_cloth.hh:109
BVHTree * bvhtree
Definition BKE_cloth.hh:77
ClothVertex * verts
Definition BKE_cloth.hh:69
BVHTree * bvhselftree
Definition BKE_cloth.hh:78
unsigned int numsprings
Definition BKE_cloth.hh:71
LinkNode * springs
Definition BKE_cloth.hh:70
unsigned int mvert_num
Definition BKE_cloth.hh:72
unsigned char old_solver_type
Definition BKE_cloth.hh:74
int last_frame
Definition BKE_cloth.hh:82
const blender::int2 * edges
Definition BKE_cloth.hh:85
blender::int3 * vert_tris
Definition BKE_cloth.hh:79
unsigned int primitive_num
Definition BKE_cloth.hh:73
LinkNode * list
void * link
struct LinkNode * next
struct MDeformWeight * dw
unsigned int def_nr
ObjectRuntimeHandle * runtime
struct PointCache * cache
struct PTCacheEdit * edit
Definition rand.cc:33
blender::BitVector is_loose_bits