diff options
author | Campbell Barton <ideasman42@gmail.com> | 2018-06-17 18:10:19 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2018-06-17 18:10:19 +0300 |
commit | 06a1a66a9b6f120867d3bbebe3928744ec8e3495 (patch) | |
tree | 42e827a3cf58eb76474e479206b02a8d97dd3bf7 /source/blender/blenkernel/intern/cloth.c | |
parent | 61d27db35967710421ab92748e09624db068258d (diff) | |
parent | a24b4e6090057479796e914bc603119b12f6ca06 (diff) |
Merge branch 'master' into blender2.8
Diffstat (limited to 'source/blender/blenkernel/intern/cloth.c')
-rw-r--r-- | source/blender/blenkernel/intern/cloth.c | 210 |
1 files changed, 105 insertions, 105 deletions
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index cc1c7260cbc..c5d9472ca4b 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -80,7 +80,7 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, Mesh *mesh ); * 2. fill object with standard values or with the GUI settings if given */ void cloth_init(ClothModifierData *clmd ) -{ +{ /* Initialize our new data structure to reasonable values. */ clmd->sim_parms->gravity[0] = 0.0; clmd->sim_parms->gravity[1] = 0.0; @@ -91,7 +91,7 @@ void cloth_init(ClothModifierData *clmd ) clmd->sim_parms->bending = 0.5; clmd->sim_parms->max_bend = 0.5; clmd->sim_parms->bending_damping = 0.5; - clmd->sim_parms->Cdis = 5.0; + clmd->sim_parms->Cdis = 5.0; clmd->sim_parms->Cvi = 1.0; clmd->sim_parms->mass = 0.3f; clmd->sim_parms->stepsPerFrame = 5; @@ -107,7 +107,7 @@ void cloth_init(ClothModifierData *clmd ) clmd->sim_parms->time_scale = 1.0f; /* multiplies cloth speed */ clmd->sim_parms->reset = 0; clmd->sim_parms->vel_damping = 1.0f; /* 1.0 = no damping, 0.0 = fully dampened */ - + clmd->coll_parms->self_friction = 5.0; clmd->coll_parms->friction = 5.0; clmd->coll_parms->loop_count = 2; @@ -155,27 +155,27 @@ static BVHTree *bvhselftree_build_from_cloth (ClothModifierData *clmd, float eps if (!cloth) return NULL; - + verts = cloth->verts; - + /* in the moment, return zero if no faces there */ if (!cloth->mvert_num) return NULL; - + /* create quadtree with k=26 */ bvhtree = BLI_bvhtree_new(cloth->mvert_num, epsilon, 4, 6); - + /* fill tree */ for (i = 0; i < cloth->mvert_num; i++, verts++) { const float *co; co = verts->xold; - + BLI_bvhtree_insert(bvhtree, i, co, 1); } - + /* balance tree */ BLI_bvhtree_balance(bvhtree); - + return bvhtree; } @@ -194,10 +194,10 @@ static BVHTree *bvhtree_build_from_cloth (ClothModifierData *clmd, float epsilon if (!cloth) return NULL; - + verts = cloth->verts; vt = cloth->tri; - + /* in the moment, return zero if no faces there */ if (!cloth->tri_num) return NULL; @@ -218,23 +218,23 @@ static BVHTree *bvhtree_build_from_cloth (ClothModifierData *clmd, float epsilon /* balance tree */ BLI_bvhtree_balance(bvhtree); - + return bvhtree; } void bvhtree_update_from_cloth(ClothModifierData *clmd, bool moving) -{ +{ unsigned int i = 0; Cloth *cloth = clmd->clothObject; BVHTree *bvhtree = cloth->bvhtree; ClothVertex *verts = cloth->verts; const MVertTri *vt; - + if (!bvhtree) return; - + vt = cloth->tri; - + /* update vertex position in bvh tree */ if (verts && vt) { for (i = 0; i < cloth->tri_num; i++, vt++) { @@ -257,25 +257,25 @@ void bvhtree_update_from_cloth(ClothModifierData *clmd, bool moving) else { ret = BLI_bvhtree_update_node(bvhtree, i, co[0], NULL, 3); } - + /* check if tree is already full */ if (ret == false) { break; } } - + BLI_bvhtree_update_tree(bvhtree); } } void bvhselftree_update_from_cloth(ClothModifierData *clmd, bool moving) -{ +{ unsigned int i = 0; Cloth *cloth = clmd->clothObject; BVHTree *bvhtree = cloth->bvhselftree; ClothVertex *verts = cloth->verts; const MVertTri *vt; - + if (!bvhtree) return; @@ -304,7 +304,7 @@ void bvhselftree_update_from_cloth(ClothModifierData *clmd, bool moving) break; } } - + BLI_bvhtree_update_tree(bvhtree); } } @@ -312,13 +312,13 @@ void bvhselftree_update_from_cloth(ClothModifierData *clmd, bool moving) void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr) { PTCacheID pid; - + BKE_ptcache_id_from_cloth(&pid, ob, clmd); // don't do anything as long as we're in editmode! if (pid.cache->edit && ob->mode & OB_MODE_PARTICLE_EDIT) return; - + BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_AFTER, framenr); } @@ -335,13 +335,13 @@ static int do_init_cloth(Object *ob, ClothModifierData *clmd, Mesh *result, int modifier_setError(&(clmd->modifier), "Can't initialize cloth"); return 0; } - + if (clmd->clothObject == NULL) { BKE_ptcache_invalidate(cache); modifier_setError(&(clmd->modifier), "Null cloth object"); return 0; } - + BKE_cloth_solver_set_positions(clmd); clmd->clothObject->last_frame= MINFRAME-1; @@ -387,7 +387,7 @@ static int do_step_cloth(struct Depsgraph *depsgraph, Object *ob, ClothModifierD cloth_update_spring_lengths ( clmd, result ); cloth_update_springs( clmd ); - + // TIMEIT_START(cloth_step) /* call the solver. */ @@ -398,7 +398,7 @@ static int do_step_cloth(struct Depsgraph *depsgraph, Object *ob, ClothModifierD pdEndEffectors(&effectors); // printf ( "%f\n", ( float ) tval() ); - + return ret; } @@ -429,7 +429,7 @@ void clothModifier_do(ClothModifierData *clmd, struct Depsgraph *depsgraph, Scen cache->last_exact= 0; cache->flag &= ~PTCACHE_REDO_NEEDED; } - + // unused in the moment, calculated separately in implicit.c clmd->sim_parms->dt = clmd->sim_parms->timescale / clmd->sim_parms->stepsPerFrame; @@ -507,13 +507,13 @@ void clothModifier_do(ClothModifierData *clmd, struct Depsgraph *depsgraph, Scen void cloth_free_modifier(ClothModifierData *clmd ) { Cloth *cloth = NULL; - + if ( !clmd ) return; cloth = clmd->clothObject; - + if ( cloth ) { BPH_cloth_solver_free(clmd); @@ -529,12 +529,12 @@ void cloth_free_modifier(ClothModifierData *clmd ) LinkNode *search = cloth->springs; while (search) { ClothSpring *spring = search->link; - + MEM_freeN ( spring ); search = search->next; } BLI_linklist_free(cloth->springs, NULL); - + cloth->springs = NULL; } @@ -544,7 +544,7 @@ void cloth_free_modifier(ClothModifierData *clmd ) // free BVH collision tree if ( cloth->bvhtree ) BLI_bvhtree_free ( cloth->bvhtree ); - + if ( cloth->bvhselftree ) BLI_bvhtree_free ( cloth->bvhselftree ); @@ -554,8 +554,8 @@ void cloth_free_modifier(ClothModifierData *clmd ) if (cloth->edgeset) BLI_edgeset_free(cloth->edgeset); - - + + /* if (clmd->clothObject->facemarks) MEM_freeN(clmd->clothObject->facemarks); @@ -571,12 +571,12 @@ void cloth_free_modifier_extern(ClothModifierData *clmd ) Cloth *cloth = NULL; if (G.debug_value > 0) printf("cloth_free_modifier_extern\n"); - + if ( !clmd ) return; cloth = clmd->clothObject; - + if ( cloth ) { if (G.debug_value > 0) printf("cloth_free_modifier_extern in\n"); @@ -610,7 +610,7 @@ void cloth_free_modifier_extern(ClothModifierData *clmd ) // free BVH collision tree if ( cloth->bvhtree ) BLI_bvhtree_free ( cloth->bvhtree ); - + if ( cloth->bvhselftree ) BLI_bvhtree_free ( cloth->bvhselftree ); @@ -660,11 +660,11 @@ static void cloth_to_object (Object *ob, ClothModifierData *clmd, float (*verte int cloth_uses_vgroup(ClothModifierData *clmd) { - return (((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING ) || + return (((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING ) || (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) || (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SEW) || - (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF)) && - ((clmd->sim_parms->vgroup_mass>0) || + (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF)) && + ((clmd->sim_parms->vgroup_mass>0) || (clmd->sim_parms->vgroup_struct>0)|| (clmd->sim_parms->vgroup_bend>0) || (clmd->sim_parms->vgroup_shrink>0) || @@ -693,7 +693,7 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, Mesh *mesh ) mvert_num = mesh->totvert; verts = clothObj->verts; - + if (cloth_uses_vgroup(clmd)) { for (i = 0; i < mvert_num; i++, verts++) { @@ -717,21 +717,21 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, Mesh *mesh ) verts->goal = dvert->dw [j].weight; /* goalfac= 1.0f; */ /* UNUSED */ - + // Kicking goal factor to simplify things...who uses that anyway? // ABS ( clmd->sim_parms->maxgoal - clmd->sim_parms->mingoal ); - + verts->goal = pow4f(verts->goal); if ( verts->goal >= SOFTGOALSNAP ) verts->flags |= CLOTH_VERT_FLAG_PINNED; } - + if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING ) { if ( dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_struct-1)) { verts->struct_stiff = dvert->dw [j].weight; verts->shear_stiff = dvert->dw [j].weight; } - + if ( dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_bend-1)) { verts->bend_stiff = dvert->dw [j].weight; } @@ -786,7 +786,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, Mesh *mesh, fl Cloth *cloth = NULL; float maxdist = 0; - // If we have a clothObject, free it. + // If we have a clothObject, free it. if ( clmd->clothObject != NULL ) { cloth_free_modifier ( clmd ); if (G.debug_value > 0) @@ -837,9 +837,9 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, Mesh *mesh, fl else copy_v3_v3(verts->xrest, verts->x); } - + /* no GUI interface yet */ - verts->mass = clmd->sim_parms->mass; + verts->mass = clmd->sim_parms->mass; verts->impulse_count = 0; if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) @@ -859,7 +859,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, Mesh *mesh, fl verts->impulse_count = 0; copy_v3_v3 ( verts->impulse, tnull ); } - + // apply / set vertex groups // has to be happen before springs are build! cloth_apply_vgroup (clmd, mesh); @@ -870,19 +870,19 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, Mesh *mesh, fl printf("cloth_free_modifier cloth_build_springs\n"); return 0; } - + // init our solver BPH_cloth_solver_init(ob, clmd); - + if (!first) BKE_cloth_solver_set_positions(clmd); clmd->clothObject->bvhtree = bvhtree_build_from_cloth ( clmd, MAX2(clmd->coll_parms->epsilon, clmd->coll_parms->distance_repel) ); - + for (i = 0; i < mesh->totvert; i++) { maxdist = MAX2(maxdist, clmd->coll_parms->selfepsilon* ( cloth->verts[i].avg_spring_len*2.0f)); } - + clmd->clothObject->bvhselftree = bvhselftree_build_from_cloth ( clmd, maxdist ); return 1; @@ -958,17 +958,17 @@ static void cloth_free_errorsprings(Cloth *cloth, LinkNodePair *edgelist) LinkNode *search = cloth->springs; while (search) { ClothSpring *spring = search->link; - + MEM_freeN ( spring ); search = search->next; } BLI_linklist_free(cloth->springs, NULL); - + cloth->springs = NULL; } cloth_free_edgelist(edgelist, cloth->mvert_num); - + if (cloth->edgeset) { BLI_edgeset_free(cloth->edgeset); cloth->edgeset = NULL; @@ -981,10 +981,10 @@ static void cloth_hair_update_bending_targets(ClothModifierData *clmd) LinkNode *search = NULL; float hair_frame[3][3], dir_old[3], dir_new[3]; int prev_mn; /* to find hair chains */ - + if (!clmd->hairdata) return; - + /* XXX Note: we need to propagate frames from the root up, * but structural hair springs are stored in reverse order. * The bending springs however are then inserted in the same @@ -992,17 +992,17 @@ static void cloth_hair_update_bending_targets(ClothModifierData *clmd) * This messy situation can be resolved when solver data is * generated directly from a dedicated hair system. */ - + prev_mn = -1; for (search = cloth->springs; search; search = search->next) { ClothSpring *spring = search->link; ClothHairData *hair_ij, *hair_kl; bool is_root = spring->kl != prev_mn; - + if (spring->type != CLOTH_SPRING_TYPE_BENDING_ANG) { continue; } - + hair_ij = &clmd->hairdata[spring->ij]; hair_kl = &clmd->hairdata[spring->kl]; if (is_root) { @@ -1013,39 +1013,39 @@ static void cloth_hair_update_bending_targets(ClothModifierData *clmd) */ copy_v3_v3(dir_new, hair_frame[2]); } - + copy_v3_v3(dir_old, dir_new); sub_v3_v3v3(dir_new, cloth->verts[spring->mn].x, cloth->verts[spring->kl].x); normalize_v3(dir_new); - + #if 0 if (clmd->debug_data && (spring->ij == 0 || spring->ij == 1)) { float a[3], b[3]; - + copy_v3_v3(a, cloth->verts[spring->kl].x); // BKE_sim_debug_data_add_dot(clmd->debug_data, cloth_vert ? cloth_vert->x : key->co, 1, 1, 0, "frames", 8246, p, k); - + mul_v3_v3fl(b, hair_frame[0], clmd->sim_parms->avg_spring_len); BKE_sim_debug_data_add_vector(clmd->debug_data, a, b, 1, 0, 0, "frames", 8247, spring->kl, spring->mn); - + mul_v3_v3fl(b, hair_frame[1], clmd->sim_parms->avg_spring_len); BKE_sim_debug_data_add_vector(clmd->debug_data, a, b, 0, 1, 0, "frames", 8248, spring->kl, spring->mn); - + mul_v3_v3fl(b, hair_frame[2], clmd->sim_parms->avg_spring_len); BKE_sim_debug_data_add_vector(clmd->debug_data, a, b, 0, 0, 1, "frames", 8249, spring->kl, spring->mn); } #endif - + /* get local targets for kl/mn vertices by putting rest targets into the current frame, * then multiply with the rest length to get the actual goals */ - + mul_v3_m3v3(spring->target, hair_frame, hair_kl->rest_target); mul_v3_fl(spring->target, spring->restlen); - + /* move frame to next hair segment */ cloth_parallel_transport_hair_frame(hair_frame, dir_old, dir_new); - + prev_mn = spring->mn; } } @@ -1056,10 +1056,10 @@ static void cloth_hair_update_bending_rest_targets(ClothModifierData *clmd) LinkNode *search = NULL; float hair_frame[3][3], dir_old[3], dir_new[3]; int prev_mn; /* to find hair roots */ - + if (!clmd->hairdata) return; - + /* XXX Note: we need to propagate frames from the root up, * but structural hair springs are stored in reverse order. * The bending springs however are then inserted in the same @@ -1067,17 +1067,17 @@ static void cloth_hair_update_bending_rest_targets(ClothModifierData *clmd) * This messy situation can be resolved when solver data is * generated directly from a dedicated hair system. */ - + prev_mn = -1; for (search = cloth->springs; search; search = search->next) { ClothSpring *spring = search->link; ClothHairData *hair_ij, *hair_kl; bool is_root = spring->kl != prev_mn; - + if (spring->type != CLOTH_SPRING_TYPE_BENDING_ANG) { continue; } - + hair_ij = &clmd->hairdata[spring->ij]; hair_kl = &clmd->hairdata[spring->kl]; if (is_root) { @@ -1088,18 +1088,18 @@ static void cloth_hair_update_bending_rest_targets(ClothModifierData *clmd) */ copy_v3_v3(dir_new, hair_frame[2]); } - + copy_v3_v3(dir_old, dir_new); sub_v3_v3v3(dir_new, cloth->verts[spring->mn].xrest, cloth->verts[spring->kl].xrest); normalize_v3(dir_new); - + /* dir expressed in the hair frame defines the rest target direction */ copy_v3_v3(hair_kl->rest_target, dir_new); mul_transposed_m3_v3(hair_frame, hair_kl->rest_target); - + /* move frame to next hair segment */ cloth_parallel_transport_hair_frame(hair_frame, dir_old, dir_new); - + prev_mn = spring->mn; } } @@ -1148,10 +1148,10 @@ static void cloth_update_springs( ClothModifierData *clmd ) spring->flags |= CLOTH_SPRING_FLAG_DEACTIVATE; } } - + search = search->next; } - + cloth_hair_update_bending_targets(clmd); } @@ -1243,10 +1243,10 @@ BLI_INLINE void madd_m3_m3fl(float r[3][3], float m[3][3], float f) void cloth_parallel_transport_hair_frame(float mat[3][3], const float dir_old[3], const float dir_new[3]) { float rot[3][3]; - + /* rotation between segments */ rotation_between_vecs_to_mat3(rot, dir_old, dir_new); - + /* rotate the frame */ mul_m3_m3m3(mat, rot, mat); } @@ -1268,7 +1268,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, Mesh *mesh ) LinkNodePair *edgelist; EdgeSet *edgeset = NULL; LinkNode *search = NULL, *search2 = NULL; - + // error handling if ( numedges==0 ) return 0; @@ -1282,7 +1282,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, Mesh *mesh ) cloth->edgeset = NULL; edgelist = MEM_callocN(sizeof(*edgelist) * mvert_num, "cloth_edgelist_alloc" ); - + if (!edgelist) return 0; @@ -1314,7 +1314,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, Mesh *mesh ) spring->flags = 0; struct_springs++; - + BLI_linklist_prepend ( &cloth->springs, spring ); } else { @@ -1325,7 +1325,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, Mesh *mesh ) if (struct_springs_real > 0) clmd->sim_parms->avg_spring_len /= struct_springs_real; - + for (i = 0; i < mvert_num; i++) { if (cloth->verts[i].spring_count > 0) cloth->verts[i].avg_spring_len = cloth->verts[i].avg_spring_len * 0.49f / ((float)cloth->verts[i].spring_count); @@ -1415,15 +1415,15 @@ static int cloth_build_springs ( ClothModifierData *clmd, Mesh *mesh ) while (search && search2) { tspring = search->link; tspring2 = search2->link; - + if (tspring->ij == tspring2->kl) { spring = (ClothSpring *)MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" ); - + if (!spring) { cloth_free_errorsprings(cloth, edgelist); return 0; } - + spring->ij = tspring2->ij; spring->kl = tspring->ij; spring->mn = tspring->kl; @@ -1431,10 +1431,10 @@ static int cloth_build_springs ( ClothModifierData *clmd, Mesh *mesh ) spring->type = CLOTH_SPRING_TYPE_BENDING_ANG; spring->stiffness = (cloth->verts[spring->kl].bend_stiff + cloth->verts[spring->ij].bend_stiff) / 2.0f; bend_springs++; - + BLI_linklist_prepend ( &cloth->springs, spring ); } - + search = search->next; search2 = search2->next; } @@ -1452,33 +1452,33 @@ static int cloth_build_springs ( ClothModifierData *clmd, Mesh *mesh ) while (search && search2) { tspring = search->link; tspring2 = search2->link; - + if (tspring->ij == tspring2->kl) { spring = (ClothSpring *)MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" ); - + if (!spring) { cloth_free_errorsprings(cloth, edgelist); return 0; } - + spring->ij = tspring2->ij; spring->kl = tspring->kl; spring->restlen = len_v3v3(cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest); spring->type = CLOTH_SPRING_TYPE_BENDING; spring->stiffness = (cloth->verts[spring->kl].bend_stiff + cloth->verts[spring->ij].bend_stiff) / 2.0f; bend_springs++; - + BLI_linklist_prepend ( &cloth->springs, spring ); } - + search = search->next; search2 = search2->next; } } - + cloth_hair_update_bending_rest_targets(clmd); } - + /* note: the edges may already exist so run reinsert */ /* insert other near springs in edgeset AFTER bending springs are calculated (for selfcolls) */ @@ -1492,10 +1492,10 @@ static int cloth_build_springs ( ClothModifierData *clmd, Mesh *mesh ) BLI_edgeset_add(edgeset, mloop[mpoly[i].loopstart + 1].v, mloop[mpoly[i].loopstart + 3].v); } } - - + + cloth->numsprings = struct_springs + shear_springs + bend_springs; - + cloth_free_edgelist(edgelist, mvert_num); #if 0 |