4
* ***** BEGIN GPL LICENSE BLOCK *****
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version 2
9
* of the License, or (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software Foundation,
18
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
* The Original Code is Copyright (C) Blender Foundation
21
* All rights reserved.
23
* Contributor(s): Daniel Genrich
25
* ***** END GPL LICENSE BLOCK *****
2
* ***** BEGIN GPL LICENSE BLOCK *****
4
* This program is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU General Public License
6
* as published by the Free Software Foundation; either version 2
7
* of the License, or (at your option) any later version.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software Foundation,
16
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
* The Original Code is Copyright (C) Blender Foundation
19
* All rights reserved.
21
* Contributor(s): Daniel Genrich
23
* ***** END GPL LICENSE BLOCK *****
26
/** \file blender/blenkernel/intern/cloth.c
28
31
#include "MEM_guardedalloc.h"
33
#include "DNA_cloth_types.h"
34
#include "DNA_scene_types.h"
35
#include "DNA_object_types.h"
36
#include "DNA_meshdata_types.h"
38
#include "BLI_utildefines.h"
40
#include "BLI_edgehash.h"
41
#include "BLI_utildefines.h"
42
#include "BLI_linklist.h"
44
#include "BLF_translation.h"
30
46
#include "BKE_cdderivedmesh.h"
31
47
#include "BKE_cloth.h"
32
48
#include "BKE_effect.h"
33
49
#include "BKE_global.h"
34
50
#include "BKE_modifier.h"
35
51
#include "BKE_pointcache.h"
36
#include "BKE_utildefines.h"
39
54
void tstart ( void )
205
219
cloth = clmd->clothObject;
210
224
verts = cloth->verts;
211
225
mfaces = cloth->mfaces;
213
227
// in the moment, return zero if no faces there
228
if (!cloth->numfaces)
217
231
// create quadtree with k=26
218
232
bvhtree = BLI_bvhtree_new(cloth->numfaces, epsilon, 4, 26);
221
for(i = 0; i < cloth->numfaces; i++, mfaces++)
235
for (i = 0; i < cloth->numfaces; i++, mfaces++)
223
VECCOPY(&co[0*3], verts[mfaces->v1].xold);
224
VECCOPY(&co[1*3], verts[mfaces->v2].xold);
225
VECCOPY(&co[2*3], verts[mfaces->v3].xold);
237
copy_v3_v3(&co[0*3], verts[mfaces->v1].xold);
238
copy_v3_v3(&co[1*3], verts[mfaces->v2].xold);
239
copy_v3_v3(&co[2*3], verts[mfaces->v3].xold);
228
VECCOPY(&co[3*3], verts[mfaces->v4].xold);
242
copy_v3_v3(&co[3*3], verts[mfaces->v4].xold);
230
244
BLI_bvhtree_insert(bvhtree, i, co, (mfaces->v4 ? 4 : 3));
246
260
float co[12], co_moving[12];
252
266
mfaces = cloth->mfaces;
254
268
// update vertex position in bvh tree
257
for(i = 0; i < cloth->numfaces; i++, mfaces++)
271
for (i = 0; i < cloth->numfaces; i++, mfaces++)
259
VECCOPY(&co[0*3], verts[mfaces->v1].txold);
260
VECCOPY(&co[1*3], verts[mfaces->v2].txold);
261
VECCOPY(&co[2*3], verts[mfaces->v3].txold);
273
copy_v3_v3(&co[0*3], verts[mfaces->v1].txold);
274
copy_v3_v3(&co[1*3], verts[mfaces->v2].txold);
275
copy_v3_v3(&co[2*3], verts[mfaces->v3].txold);
264
VECCOPY(&co[3*3], verts[mfaces->v4].txold);
278
copy_v3_v3(&co[3*3], verts[mfaces->v4].txold);
266
280
// copy new locations into array
269
283
// update moving positions
270
VECCOPY(&co_moving[0*3], verts[mfaces->v1].tx);
271
VECCOPY(&co_moving[1*3], verts[mfaces->v2].tx);
272
VECCOPY(&co_moving[2*3], verts[mfaces->v3].tx);
284
copy_v3_v3(&co_moving[0*3], verts[mfaces->v1].tx);
285
copy_v3_v3(&co_moving[1*3], verts[mfaces->v2].tx);
286
copy_v3_v3(&co_moving[2*3], verts[mfaces->v3].tx);
275
VECCOPY(&co_moving[3*3], verts[mfaces->v4].tx);
289
copy_v3_v3(&co_moving[3*3], verts[mfaces->v4].tx);
277
291
ret = BLI_bvhtree_update_node(bvhtree, i, co, co_moving, (mfaces->v4 ? 4 : 3));
281
294
ret = BLI_bvhtree_update_node(bvhtree, i, co, NULL, (mfaces->v4 ? 4 : 3));
284
297
// check if tree is already full
300
313
float co[12], co_moving[12];
306
319
mfaces = cloth->mfaces;
308
321
// update vertex position in bvh tree
311
for(i = 0; i < cloth->numverts; i++, verts++)
324
for (i = 0; i < cloth->numverts; i++, verts++)
313
VECCOPY(&co[0*3], verts->txold);
326
copy_v3_v3(&co[0*3], verts->txold);
315
328
// copy new locations into array
318
331
// update moving positions
319
VECCOPY(&co_moving[0*3], verts->tx);
332
copy_v3_v3(&co_moving[0*3], verts->tx);
321
334
ret = BLI_bvhtree_update_node(bvhtree, i, co, co_moving, 1);
325
337
ret = BLI_bvhtree_update_node(bvhtree, i, co, NULL, 1);
328
340
// check if tree is already full
415
430
/************************************************
416
431
* clothModifier_do - main simulation function
417
432
************************************************/
418
DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc)
433
void clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, DerivedMesh *dm, float (*vertexCos)[3])
421
435
PointCache *cache;
424
int framedelta, framenr, startframe, endframe;
438
int framenr, startframe, endframe;
425
439
int cache_result;
427
441
clmd->scene= scene; /* nice to pass on later :) */
428
442
framenr= (int)scene->r.cfra;
429
443
cache= clmd->point_cache;
430
result = CDDM_copy(dm);
432
445
BKE_ptcache_id_from_cloth(&pid, ob, clmd);
433
446
BKE_ptcache_id_time(&pid, scene, framenr, &startframe, &endframe, ×cale);
434
447
clmd->sim_parms->timescale= timescale;
437
BKE_ptcache_invalidate(cache);
441
if(clmd->sim_parms->reset || (framenr == (startframe - clmd->sim_parms->preroll)))
449
if (clmd->sim_parms->reset ||
450
(framenr == (startframe - clmd->sim_parms->preroll) && clmd->sim_parms->preroll != 0) ||
451
(clmd->clothObject && dm->getNumVerts(dm) != clmd->clothObject->numverts))
443
453
clmd->sim_parms->reset = 0;
444
454
cache->flag |= PTCACHE_OUTDATED;
446
456
BKE_ptcache_validate(cache, 0);
447
457
cache->last_exact= 0;
448
458
cache->flag &= ~PTCACHE_REDO_NEEDED;
452
/* verify we still have the same number of vertices, if not do nothing.
453
* note that this should only happen if the number of vertices changes
454
* during an animation due to a preceding modifier, this should not
455
* happen because of object changes! */
456
if(clmd->clothObject) {
457
if(result->getNumVerts(result) != clmd->clothObject->numverts) {
458
BKE_ptcache_invalidate(cache);
463
462
// unused in the moment, calculated separately in implicit.c
464
463
clmd->sim_parms->dt = clmd->sim_parms->timescale / clmd->sim_parms->stepsPerFrame;
466
465
/* handle continuous simulation with the play button */
467
if(BKE_ptcache_get_continue_physics() || ((clmd->sim_parms->preroll > 0) && (framenr > startframe - clmd->sim_parms->preroll) && (framenr < startframe))) {
466
if (BKE_ptcache_get_continue_physics() || ((clmd->sim_parms->preroll > 0) && (framenr > startframe - clmd->sim_parms->preroll) && (framenr < startframe))) {
468
467
BKE_ptcache_invalidate(cache);
470
469
/* do simulation */
471
if(!do_init_cloth(ob, clmd, result, framenr))
474
do_step_cloth(ob, clmd, result, framenr);
475
cloth_to_object(ob, clmd, result);
470
if (!do_init_cloth(ob, clmd, dm, framenr))
473
do_step_cloth(ob, clmd, dm, framenr);
474
cloth_to_object(ob, clmd, vertexCos);
476
clmd->clothObject->last_frame= framenr;
480
481
/* simulation is only active during a specific period */
481
if(framenr < startframe) {
482
if (framenr < startframe) {
482
483
BKE_ptcache_invalidate(cache);
485
else if(framenr > endframe) {
486
else if (framenr > endframe) {
486
487
framenr= endframe;
489
if(cache->flag & PTCACHE_SIMULATION_VALID)
490
framedelta= framenr - cache->simframe;
494
490
/* initialize simulation data if it didn't exist already */
495
if(!do_init_cloth(ob, clmd, result, framenr))
491
if (!do_init_cloth(ob, clmd, dm, framenr))
498
if((framenr == startframe) && (clmd->sim_parms->preroll == 0)) {
494
if ((framenr == startframe) && (clmd->sim_parms->preroll == 0)) {
499
495
BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
500
do_init_cloth(ob, clmd, result, framenr);
496
do_init_cloth(ob, clmd, dm, framenr);
501
497
BKE_ptcache_validate(cache, framenr);
502
498
cache->flag &= ~PTCACHE_REDO_NEEDED;
499
clmd->clothObject->last_frame= framenr;
506
503
/* try to read from cache */
507
cache_result = BKE_ptcache_read_cache(&pid, (float)framenr, scene->r.frs_sec);
504
cache_result = BKE_ptcache_read(&pid, (float)framenr+scene->r.subframe);
509
if(cache_result == PTCACHE_READ_EXACT || cache_result == PTCACHE_READ_INTERPOLATED) {
506
if (cache_result == PTCACHE_READ_EXACT || cache_result == PTCACHE_READ_INTERPOLATED) {
510
507
implicit_set_positions(clmd);
511
cloth_to_object (ob, clmd, result);
508
cloth_to_object (ob, clmd, vertexCos);
513
510
BKE_ptcache_validate(cache, framenr);
515
if(cache_result == PTCACHE_READ_INTERPOLATED && cache->flag & PTCACHE_REDO_NEEDED)
516
BKE_ptcache_write_cache(&pid, framenr);
512
if (cache_result == PTCACHE_READ_INTERPOLATED && cache->flag & PTCACHE_REDO_NEEDED)
513
BKE_ptcache_write(&pid, framenr);
515
clmd->clothObject->last_frame= framenr;
520
else if(cache_result==PTCACHE_READ_OLD) {
519
else if (cache_result==PTCACHE_READ_OLD) {
521
520
implicit_set_positions(clmd);
523
else if( /*ob->id.lib ||*/ (cache->flag & PTCACHE_BAKED)) { /* 2.4x disabled lib, but this can be used in some cases, testing further - campbell */
522
else if ( /*ob->id.lib ||*/ (cache->flag & PTCACHE_BAKED)) { /* 2.4x disabled lib, but this can be used in some cases, testing further - campbell */
524
523
/* if baked and nothing in cache, do nothing */
525
524
BKE_ptcache_invalidate(cache);
528
if (framenr!=clmd->clothObject->last_frame+1)
529
531
/* if on second frame, write cache for first frame */
530
if(cache->simframe == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0))
531
BKE_ptcache_write_cache(&pid, startframe);
532
if (cache->simframe == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0))
533
BKE_ptcache_write(&pid, startframe);
533
535
clmd->sim_parms->timescale *= framenr - cache->simframe;
535
537
/* do simulation */
536
538
BKE_ptcache_validate(cache, framenr);
538
if(!do_step_cloth(ob, clmd, result, framenr)) {
540
if (!do_step_cloth(ob, clmd, dm, framenr)) {
539
541
BKE_ptcache_invalidate(cache);
542
BKE_ptcache_write_cache(&pid, framenr);
544
cloth_to_object (ob, clmd, result);
544
BKE_ptcache_write(&pid, framenr);
546
cloth_to_object (ob, clmd, vertexCos);
547
clmd->clothObject->last_frame= framenr;
550
void cloth_free_modifier ( Object *ob, ClothModifierData *clmd )
551
void cloth_free_modifier(ClothModifierData *clmd )
552
553
Cloth *cloth = NULL;
1045
1040
Cloth *cloth = clmd->clothObject;
1046
1041
ClothSpring *spring = NULL, *tspring = NULL, *tspring2 = NULL;
1047
1042
unsigned int struct_springs = 0, shear_springs=0, bend_springs = 0;
1049
int numverts = dm->getNumVerts ( dm );
1050
int numedges = dm->getNumEdges ( dm );
1051
int numfaces = dm->getNumFaces ( dm );
1052
MEdge *medge = CDDM_get_edges ( dm );
1053
MFace *mface = CDDM_get_faces ( dm );
1044
unsigned int numverts = (unsigned int)dm->getNumVerts ( dm );
1045
unsigned int numedges = (unsigned int)dm->getNumEdges ( dm );
1046
unsigned int numfaces = (unsigned int)dm->getNumTessFaces ( dm );
1047
MEdge *medge = dm->getEdgeArray ( dm );
1048
MFace *mface = dm->getTessFaceArray ( dm );
1054
1049
int index2 = 0; // our second vertex index
1055
1050
LinkNode **edgelist = NULL;
1056
1051
EdgeHash *edgehash = NULL;
1057
1052
LinkNode *search = NULL, *search2 = NULL;
1060
1054
// error handling
1061
1055
if ( numedges==0 )