Merge branch 'master' into blender2.8
[blender.git] / source / blender / blenkernel / intern / softbody.c
index 880a47b3256eede8be06649b2db63ab2c8a13928..f4986f7dabae3544ad5b77aeecea212069d7fac6 100644 (file)
@@ -63,6 +63,8 @@ variables on the UI for now
 #include "DNA_curve_types.h"
 #include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
+#include "DNA_object_force.h"
+#include "DNA_group_types.h"
 
 #include "BLI_math.h"
 #include "BLI_utildefines.h"
@@ -75,13 +77,11 @@ variables on the UI for now
 #include "BKE_global.h"
 #include "BKE_modifier.h"
 #include "BKE_softbody.h"
-#include "BKE_pointcache.h"
 #include "BKE_deform.h"
 #include "BKE_mesh.h"
 #include "BKE_scene.h"
 
 #include  "PIL_time.h"
-// #include  "ONL_opennl.h" remove linking to ONL for now
 
 /* callbacks for errors and interrupts and some goo */
 static int (*SB_localInterruptCallBack)(void) = NULL;
@@ -142,11 +142,6 @@ typedef struct  SB_thread_context {
                int tot;
 } SB_thread_context;
 
-#define NLF_BUILD  1
-#if 0
-#  define NLF_SOLVE  2
-#endif
-
 #define MID_PRESERVE 1
 
 #define SOFTGOALSNAP  0.999f
@@ -502,59 +497,98 @@ static void ccd_mesh_free(ccd_Mesh *ccdm)
        }
 }
 
-static void ccd_build_deflector_hash(Scene *scene, Object *vertexowner, GHash *hash)
+static void ccd_build_deflector_hash_single(GHash *hash, Object *ob)
+{
+       /* only with deflecting set */
+       if (ob->pd && ob->pd->deflect) {
+               void **val_p;
+               if (!BLI_ghash_ensure_p(hash, ob, &val_p)) {
+                       ccd_Mesh *ccdmesh = ccd_mesh_make(ob);
+                       *val_p = ccdmesh;
+               }
+       }
+}
+
+/**
+ * \note group overrides scene when not NULL.
+ */
+static void ccd_build_deflector_hash(Scene *scene, Group *group, Object *vertexowner, GHash *hash)
 {
-       Base *base= scene->base.first;
        Object *ob;
 
        if (!hash) return;
-       while (base) {
-               /*Only proceed for mesh object in same layer */
-               if (base->object->type==OB_MESH && (base->lay & vertexowner->lay)) {
-                       ob= base->object;
-                       if ((vertexowner) && (ob == vertexowner)) {
-                               /* if vertexowner is given  we don't want to check collision with owner object */
-                               base = base->next;
+
+       if (group) {
+               /* Explicit collision group */
+               for (GroupObject *go = group->gobject.first; go; go = go->next) {
+                       ob = go->ob;
+
+                       if (ob == vertexowner || ob->type != OB_MESH)
                                continue;
-                       }
 
-                       /*+++ only with deflecting set */
-                       if (ob->pd && ob->pd->deflect && BLI_ghash_lookup(hash, ob) == NULL) {
-                               ccd_Mesh *ccdmesh = ccd_mesh_make(ob);
-                               BLI_ghash_insert(hash, ob, ccdmesh);
-                       }/*--- only with deflecting set */
+                       ccd_build_deflector_hash_single(hash, ob);
+               }
+       }
+       else {
+               for (Base *base = scene->base.first; base; base = base->next) {
+                       /*Only proceed for mesh object in same layer */
+                       if (base->object->type == OB_MESH && (base->lay & vertexowner->lay)) {
+                               ob= base->object;
+                               if ((vertexowner) && (ob == vertexowner)) {
+                                       /* if vertexowner is given  we don't want to check collision with owner object */
+                                       continue;
+                               }
+
+                               ccd_build_deflector_hash_single(hash, ob);
+                       }
+               }
+       }
+}
 
-               }/* mesh && layer*/
-               base = base->next;
-       } /* while (base) */
+static void ccd_update_deflector_hash_single(GHash *hash, Object *ob)
+{
+       if (ob->pd && ob->pd->deflect) {
+               ccd_Mesh *ccdmesh = BLI_ghash_lookup(hash, ob);
+               if (ccdmesh) {
+                       ccd_mesh_update(ob, ccdmesh);
+               }
+       }
 }
 
-static void ccd_update_deflector_hash(Scene *scene, Object *vertexowner, GHash *hash)
+/**
+ * \note group overrides scene when not NULL.
+ */
+static void ccd_update_deflector_hash(Scene *scene, Group *group, Object *vertexowner, GHash *hash)
 {
-       Base *base= scene->base.first;
        Object *ob;
 
        if ((!hash) || (!vertexowner)) return;
-       while (base) {
-               /*Only proceed for mesh object in same layer */
-               if (base->object->type==OB_MESH && (base->lay & vertexowner->lay)) {
-                       ob= base->object;
-                       if (ob == vertexowner) {
-                               /* if vertexowner is given  we don't want to check collision with owner object */
-                               base = base->next;
+
+       if (group) {
+               /* Explicit collision group */
+               for (GroupObject *go = group->gobject.first; go; go = go->next) {
+                       ob = go->ob;
+
+                       if (ob == vertexowner || ob->type != OB_MESH)
                                continue;
-                       }
 
-                       /*+++ only with deflecting set */
-                       if (ob->pd && ob->pd->deflect) {
-                               ccd_Mesh *ccdmesh = BLI_ghash_lookup(hash, ob);
-                               if (ccdmesh)
-                                       ccd_mesh_update(ob, ccdmesh);
-                       }/*--- only with deflecting set */
+                       ccd_update_deflector_hash_single(hash, ob);
+               }
+       }
+       else {
+               for (Base *base = scene->base.first; base; base = base->next) {
+                       /*Only proceed for mesh object in same layer */
+                       if (base->object->type == OB_MESH && (base->lay & vertexowner->lay)) {
+                               ob= base->object;
+                               if (ob == vertexowner) {
+                                       /* if vertexowner is given  we don't want to check collision with owner object */
+                                       continue;
+                               }
 
-               }/* mesh && layer*/
-               base = base->next;
-       } /* while (base) */
+                               ccd_update_deflector_hash_single(hash, ob);
+                       }
+               }
+       }
 }
 
 
@@ -940,22 +974,32 @@ static void free_softbody_intern(SoftBody *sb)
 
 /* +++ dependency information functions*/
 
-static int are_there_deflectors(Scene *scene, unsigned int layer)
+/**
+ * \note group overrides scene when not NULL.
+ */
+static bool are_there_deflectors(Scene *scene, Group *group, unsigned int layer)
 {
-       Base *base;
-
-       for (base = scene->base.first; base; base= base->next) {
-               if ( (base->lay & layer) && base->object->pd) {
-                       if (base->object->pd->deflect)
+       if (group) {
+               for (GroupObject *go = group->gobject.first; go; go = go->next) {
+                       if (go->ob->pd && go->ob->pd->deflect)
                                return 1;
                }
        }
+       else {
+               for (Base *base = scene->base.first; base; base= base->next) {
+                       if ( (base->lay & layer) && base->object->pd) {
+                               if (base->object->pd->deflect)
+                                       return 1;
+                       }
+               }
+       }
+
        return 0;
 }
 
-static int query_external_colliders(Scene *scene, Object *me)
+static int query_external_colliders(Scene *scene, Group *group, Object *me)
 {
-       return(are_there_deflectors(scene, me->lay));
+       return(are_there_deflectors(scene, group, me->lay));
 }
 /* --- dependency information functions*/
 
@@ -1219,9 +1263,9 @@ static int sb_detect_face_collisionCached(float face_v1[3], float face_v2[3], fl
                                        sub_v3_v3v3(edge2, nv3, nv2);
                                        cross_v3_v3v3(d_nvect, edge2, edge1);
                                        normalize_v3(d_nvect);
-                                       if (isect_line_tri_v3(nv1, nv2, face_v1, face_v2, face_v3, &t, NULL) ||
-                                           isect_line_tri_v3(nv2, nv3, face_v1, face_v2, face_v3, &t, NULL) ||
-                                           isect_line_tri_v3(nv3, nv1, face_v1, face_v2, face_v3, &t, NULL) )
+                                       if (isect_line_segment_tri_v3(nv1, nv2, face_v1, face_v2, face_v3, &t, NULL) ||
+                                           isect_line_segment_tri_v3(nv2, nv3, face_v1, face_v2, face_v3, &t, NULL) ||
+                                           isect_line_segment_tri_v3(nv3, nv1, face_v1, face_v2, face_v3, &t, NULL) )
                                        {
                                                madd_v3_v3fl(force, d_nvect, -0.5f);
                                                *damp=tune*ob->pd->pdef_sbdamp;
@@ -1402,7 +1446,7 @@ static int sb_detect_edge_collisionCached(float edge_v1[3], float edge_v2[3], fl
 
                                        cross_v3_v3v3(d_nvect, edge2, edge1);
                                        normalize_v3(d_nvect);
-                                       if ( isect_line_tri_v3(edge_v1, edge_v2, nv1, nv2, nv3, &t, NULL)) {
+                                       if (isect_line_segment_tri_v3(edge_v1, edge_v2, nv1, nv2, nv3, &t, NULL)) {
                                                float v1[3], v2[3];
                                                float intrusiondepth, i1, i2;
                                                sub_v3_v3v3(v1, edge_v1, nv2);
@@ -1505,7 +1549,7 @@ static void scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow)
        SoftBody *sb = ob->soft;
        ListBase *do_effector = NULL;
 
-       do_effector = pdInitEffectors(scene, ob, NULL, sb->effector_weights, true);
+       do_effector = pdInitEffectors(scene, ob, sb->effector_weights, true);
        _scan_for_ext_spring_forces(scene, ob, timenow, 0, sb->totspring, do_effector);
        pdEndEffectors(&do_effector);
 }
@@ -1525,7 +1569,7 @@ static void sb_sfesf_threads_run(Scene *scene, struct Object *ob, float timenow,
        int i, totthread, left, dec;
        int lowsprings =100; /* wild guess .. may increase with better thread management 'above' or even be UI option sb->spawn_cf_threads_nopts */
 
-       do_effector= pdInitEffectors(scene, ob, NULL, ob->soft->effector_weights, true);
+       do_effector= pdInitEffectors(scene, ob, ob->soft->effector_weights, true);
 
        /* figure the number of threads while preventing pretty pointless threading overhead */
        totthread= BKE_scene_num_threads(scene);
@@ -1816,14 +1860,14 @@ static void dfdx_spring(int ia, int ic, int op, float dir[3], float L, float len
                        for (j=0;j<3;j++) {
                                delta_ij = (i==j ? (1.0f): (0.0f));
                                m=factor*(dir[i]*dir[j] + (1-L/len)*(delta_ij - dir[i]*dir[j]));
-                               nlMatrixAdd(ia+i, op+ic+j, m);
+                               EIG_linear_solver_matrix_add(ia+i, op+ic+j, m);
                        }
        }
        else {
                for (i=0;i<3;i++)
                        for (j=0;j<3;j++) {
                                m=factor*dir[i]*dir[j];
-                               nlMatrixAdd(ia+i, op+ic+j, m);
+                               EIG_linear_solver_matrix_add(ia+i, op+ic+j, m);
                        }
        }
 }
@@ -1832,16 +1876,16 @@ static void dfdx_spring(int ia, int ic, int op, float dir[3], float L, float len
 static void dfdx_goal(int ia, int ic, int op, float factor)
 {
        int i;
-       for (i=0;i<3;i++) nlMatrixAdd(ia+i, op+ic+i, factor);
+       for (i=0;i<3;i++) EIG_linear_solver_matrix_add(ia+i, op+ic+i, factor);
 }
 
 static void dfdv_goal(int ia, int ic, float factor)
 {
        int i;
-       for (i=0;i<3;i++) nlMatrixAdd(ia+i, ic+i, factor);
+       for (i=0;i<3;i++) EIG_linear_solver_matrix_add(ia+i, ic+i, factor);
 }
 */
-static void sb_spring_force(Object *ob, int bpi, BodySpring *bs, float iks, float UNUSED(forcetime), int nl_flags)
+static void sb_spring_force(Object *ob, int bpi, BodySpring *bs, float iks, float UNUSED(forcetime))
 {
        SoftBody *sb= ob->soft; /* is supposed to be there */
        BodyPoint  *bp1, *bp2;
@@ -1915,23 +1959,6 @@ static void sb_spring_force(Object *ob, int bpi, BodySpring *bs, float iks, floa
        projvel = dot_v3v3(dir, dvel);
        kd     *= absvel * projvel;
        madd_v3_v3fl(bp1->force, dir, -kd);
-
-       /* do jacobian stuff if needed */
-       if (nl_flags & NLF_BUILD) {
-               //int op =3*sb->totpoint;
-               //float mvel = -forcetime*kd;
-               //float mpos = -forcetime*forcefactor;
-               /* depending on my pos */
-               // dfdx_spring(ia, ia, op, dir, bs->len, distance, -mpos);
-               /* depending on my vel */
-               // dfdv_goal(ia, ia, mvel); // well that ignores geometie
-               if (bp2->goal < SOFTGOALSNAP) {  /* omit this bp when it snaps */
-                       /* depending on other pos */
-                       // dfdx_spring(ia, ic, op, dir, bs->len, distance, mpos);
-                       /* depending on other vel */
-                       // dfdv_goal(ia, ia, -mvel); // well that ignores geometie
-               }
-       }
 }
 
 
@@ -2131,8 +2158,8 @@ static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, Object *ob, flo
                                                                bp->choke = bs->cf;
 
                                                }
-                                               // sb_spring_force(Object *ob, int bpi, BodySpring *bs, float iks, float forcetime, int nl_flags)
-                                               sb_spring_force(ob, ilast-bb, bs, iks, forcetime, 0);
+                                               // sb_spring_force(Object *ob, int bpi, BodySpring *bs, float iks, float forcetime)
+                                               sb_spring_force(ob, ilast-bb, bs, iks, forcetime);
                                        }/* loop springs */
                                }/* existing spring list */
                        }/*any edges*/
@@ -2204,7 +2231,7 @@ static void sb_cf_threads_run(Scene *scene, Object *ob, float forcetime, float t
        MEM_freeN(sb_threads);
 }
 
-static void softbody_calc_forcesEx(Scene *scene, Object *ob, float forcetime, float timenow, int UNUSED(nl_flags))
+static void softbody_calc_forcesEx(Scene *scene, Object *ob, float forcetime, float timenow)
 {
 /* rule we never alter free variables :bp->vec bp->pos in here !
  * this will ruin adaptive stepsize AKA heun! (BM)
@@ -2220,7 +2247,7 @@ static void softbody_calc_forcesEx(Scene *scene, Object *ob, float forcetime, fl
        /* gravity = sb->grav * sb_grav_force_scale(ob); */ /* UNUSED */
 
        /* check conditions for various options */
-       do_deflector= query_external_colliders(scene, ob);
+       do_deflector= query_external_colliders(scene, sb->collision_group, ob);
        /* do_selfcollision=((ob->softflag & OB_SB_EDGES) && (sb->bspring)&& (ob->softflag & OB_SB_SELF)); */ /* UNUSED */
        do_springcollision=do_deflector && (ob->softflag & OB_SB_EDGES) &&(ob->softflag & OB_SB_EDGECOLL);
        do_aero=((sb->aeroedge)&& (ob->softflag & OB_SB_EDGES));
@@ -2229,10 +2256,10 @@ static void softbody_calc_forcesEx(Scene *scene, Object *ob, float forcetime, fl
        /* bproot= sb->bpoint; */ /* need this for proper spring addressing */ /* UNUSED */
 
        if (do_springcollision || do_aero)
-       sb_sfesf_threads_run(scene, ob, timenow, sb->totspring, NULL);
+               sb_sfesf_threads_run(scene, ob, timenow, sb->totspring, NULL);
 
        /* after spring scan because it uses Effoctors too */
-       do_effector= pdInitEffectors(scene, ob, NULL, sb->effector_weights, true);
+       do_effector= pdInitEffectors(scene, ob, sb->effector_weights, true);
 
        if (do_deflector) {
                float defforce[3];
@@ -2249,11 +2276,11 @@ static void softbody_calc_forcesEx(Scene *scene, Object *ob, float forcetime, fl
 }
 
 
-static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, float timenow, int nl_flags)
+static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, float timenow)
 {
        /* redirection to the new threaded Version */
        if (!(G.debug_value & 0x10)) { // 16
-               softbody_calc_forcesEx(scene, ob, forcetime, timenow, nl_flags);
+               softbody_calc_forcesEx(scene, ob, forcetime, timenow);
                return;
        }
        else {
@@ -2266,7 +2293,7 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
                .. keeping G.debug_value==17 0x11 option for old files 'needing' the bug*/
 
                /* rule we never alter free variables :bp->vec bp->pos in here !
-               * this will ruin adaptive stepsize AKA heun! (BM)
+                * this will ruin adaptive stepsize AKA heun! (BM)
                */
                SoftBody *sb= ob->soft; /* is supposed to be there */
                BodyPoint  *bp;
@@ -2276,18 +2303,7 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
                float iks, ks, kd, gravity[3] = {0.0f, 0.0f, 0.0f};
                float fieldfactor = -1.0f, windfactor  = 0.25f;
                float tune = sb->ballstiff;
-               int a, b,  do_deflector, do_selfcollision, do_springcollision, do_aero;
-
-
-               /* jacobian
-               NLboolean success;
-
-               if (nl_flags) {
-               nlBegin(NL_SYSTEM);
-               nlBegin(NL_MATRIX);
-               }
-               */
-
+               int do_deflector, do_selfcollision, do_springcollision, do_aero;
 
                if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) {
                        copy_v3_v3(gravity, scene->physics_settings.gravity);
@@ -2295,7 +2311,7 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
                }
 
                /* check conditions for various options */
-               do_deflector= query_external_colliders(scene, ob);
+               do_deflector= query_external_colliders(scene, sb->collision_group, ob);
                do_selfcollision=((ob->softflag & OB_SB_EDGES) && (sb->bspring)&& (ob->softflag & OB_SB_SELF));
                do_springcollision=do_deflector && (ob->softflag & OB_SB_EDGES) &&(ob->softflag & OB_SB_EDGECOLL);
                do_aero=((sb->aeroedge)&& (ob->softflag & OB_SB_EDGES));
@@ -2305,36 +2321,17 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
 
                if (do_springcollision || do_aero)  scan_for_ext_spring_forces(scene, ob, timenow);
                /* after spring scan because it uses Effoctors too */
-               do_effector= pdInitEffectors(scene, ob, NULL, ob->soft->effector_weights, true);
+               do_effector= pdInitEffectors(scene, ob, ob->soft->effector_weights, true);
 
                if (do_deflector) {
                        float defforce[3];
                        do_deflector = sb_detect_aabb_collisionCached(defforce, ob->lay, ob, timenow);
                }
 
-               for (a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
+               bp = sb->bpoint;
+               for (int a = sb->totpoint; a > 0; a--, bp++) {
                        /* clear forces  accumulator */
                        bp->force[0] = bp->force[1] = bp->force[2] = 0.0;
-                       if (nl_flags & NLF_BUILD) {
-                               //int ia =3*(sb->totpoint-a);
-                               //int op =3*sb->totpoint;
-                               /* dF/dV = v */
-                               /* jacobioan
-                               nlMatrixAdd(op+ia, ia, -forcetime);
-                               nlMatrixAdd(op+ia+1, ia+1, -forcetime);
-                               nlMatrixAdd(op+ia+2, ia+2, -forcetime);
-
-                               nlMatrixAdd(ia, ia, 1);
-                               nlMatrixAdd(ia+1, ia+1, 1);
-                               nlMatrixAdd(ia+2, ia+2, 1);
-
-                               nlMatrixAdd(op+ia, op+ia, 1);
-                               nlMatrixAdd(op+ia+1, op+ia+1, 1);
-                               nlMatrixAdd(op+ia+2, op+ia+2, 1);
-                               */
-
-
-                       }
 
                        /* naive ball self collision */
                        /* needs to be done if goal snaps or not */
@@ -2377,30 +2374,6 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
                                                        madd_v3_v3fl(bp->force, def, f * (1.0f - sb->balldamp));
                                                        madd_v3_v3fl(bp->force, dvel, sb->balldamp);
 
-                                                       if (nl_flags & NLF_BUILD) {
-                                                               //int ia =3*(sb->totpoint-a);
-                                                               //int ic =3*(sb->totpoint-c);
-                                                               //int op =3*sb->totpoint;
-                                                               //float mvel = forcetime*sb->nodemass*sb->balldamp;
-                                                               //float mpos = forcetime*tune*(1.0f-sb->balldamp);
-                                                               /*some quick and dirty entries to the jacobian*/
-                                                               //dfdx_goal(ia, ia, op, mpos);
-                                                               //dfdv_goal(ia, ia, mvel);
-                                                               /* exploit force(a, b) == -force(b, a) part1/2 */
-                                                               //dfdx_goal(ic, ic, op, mpos);
-                                                               //dfdv_goal(ic, ic, mvel);
-
-
-                                                               /*TODO sit down an X-out the true jacobian entries*/
-                                                               /*well does not make to much sense because the eigenvalues
-                                                               of the jacobian go negative; and negative eigenvalues
-                                                               on a complex iterative system z(n+1)=A * z(n)
-                                                               give imaginary roots in the charcateristic polynom
-                                                               --> solutions that to z(t)=u(t)* exp ( i omega t) --> oscilations we don't want here
-                                                               where u(t) is a unknown amplitude function (worst case rising fast)
-                                                               */
-                                                       }
-
                                                        /* exploit force(a, b) == -force(b, a) part2/2 */
                                                        sub_v3_v3v3(dvel, velcenter, obp->vec);
                                                        mul_v3_fl(dvel, (_final_mass(ob, bp)+_final_mass(ob, obp))/2.0f);
@@ -2426,14 +2399,6 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
                                        bp->force[1]+= -ks*(auxvect[1]);
                                        bp->force[2]+= -ks*(auxvect[2]);
 
-                                       if (nl_flags & NLF_BUILD) {
-                                               //int ia =3*(sb->totpoint-a);
-                                               //int op =3*(sb->totpoint);
-                                               /* depending on my pos */
-                                               //dfdx_goal(ia, ia, op, ks*forcetime);
-                                       }
-
-
                                        /* calulate damping forces generated by goals*/
                                        sub_v3_v3v3(velgoal, bp->origS, bp->origE);
                                        kd = sb->goalfrict * sb_fric_force_scale(ob);
@@ -2443,12 +2408,6 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
                                                bp->force[0]-= kd * (auxvect[0]);
                                                bp->force[1]-= kd * (auxvect[1]);
                                                bp->force[2]-= kd * (auxvect[2]);
-                                               if (nl_flags & NLF_BUILD) {
-                                                       //int ia =3*(sb->totpoint-a);
-                                                       normalize_v3(auxvect);
-                                                       /* depending on my vel */
-                                                       //dfdv_goal(ia, ia, kd*forcetime);
-                                               }
 
                                        }
                                        else {
@@ -2493,15 +2452,6 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
                                        bp->force[1]-= bp->vec[1]*kd;
                                        bp->force[2]-= bp->vec[2]*kd;
                                        /* friction in media done */
-                                       if (nl_flags & NLF_BUILD) {
-                                               //int ia =3*(sb->totpoint-a);
-                                               /* da/dv =  */
-
-                                               //                                      nlMatrixAdd(ia, ia, forcetime*kd);
-                                               //                                      nlMatrixAdd(ia+1, ia+1, forcetime*kd);
-                                               //                                      nlMatrixAdd(ia+2, ia+2, forcetime*kd);
-                                       }
-
                                }
                                /* +++cached collision targets */
                                bp->choke = 0.0f;
@@ -2512,7 +2462,7 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
                                        kd = 1.0f;
 
                                        if (sb_deflect_face(ob, bp->pos, facenormal, defforce, &cf, timenow, vel, &intrusion)) {
-                                               if ((!nl_flags)&&(intrusion < 0.0f)) {
+                                               if (intrusion < 0.0f) {
                                                        if (G.debug_value & 0x01) { // 17 we did check for bit 0x10 before
                                                                /*fixing bug [17428] this forces adaptive step size to tiny steps
                                                                in some situations .. keeping G.debug_value==17 option for old files 'needing' the bug
@@ -2542,13 +2492,6 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
                                                        madd_v3_v3fl(bp->force, cfforce, -cf * 50.0f);
                                                }
                                                madd_v3_v3fl(bp->force, defforce, kd);
-                                               if (nl_flags & NLF_BUILD) {
-                                                       // int ia =3*(sb->totpoint-a);
-                                                       // int op =3*sb->totpoint;
-                                                       //dfdx_goal(ia, ia, op, mpos); // don't do unless you know
-                                                       //dfdv_goal(ia, ia, -cf);
-
-                                               }
 
                                        }
 
@@ -2558,7 +2501,7 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
                                /* +++springs */
                                if (ob->softflag & OB_SB_EDGES) {
                                        if (sb->bspring) { /* spring list exists at all ? */
-                                               for (b=bp->nofsprings;b>0;b--) {
+                                               for (int b = bp->nofsprings; b > 0; b--) {
                                                        bs = sb->bspring + bp->springs[b-1];
                                                        if (do_springcollision || do_aero) {
                                                                add_v3_v3(bp->force, bs->ext_force);
@@ -2566,9 +2509,9 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
                                                                        bp->choke = bs->cf;
 
                                                        }
-                                                       // sb_spring_force(Object *ob, int bpi, BodySpring *bs, float iks, float forcetime, int nl_flags)
+                                                       // sb_spring_force(Object *ob, int bpi, BodySpring *bs, float iks, float forcetime)
                                                        // rather remove nl_falgs from code .. will make things a lot cleaner
-                                                       sb_spring_force(ob, sb->totpoint-a, bs, iks, forcetime, 0);
+                                                       sb_spring_force(ob, sb->totpoint-a, bs, iks, forcetime);
                                                }/* loop springs */
                                        }/* existing spring list */
                                }/*any edges*/
@@ -2579,76 +2522,6 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
 
                /* finally add forces caused by face collision */
                if (ob->softflag & OB_SB_FACECOLL) scan_for_ext_face_forces(ob, timenow);
-
-               /* finish matrix and solve */
-#if (0) // remove onl linking for now .. still i am not sure .. the jacobian can be useful .. so keep that BM
-               if (nl_flags & NLF_SOLVE) {
-                       //double sct, sst=PIL_check_seconds_timer();
-                       for (a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
-                               int iv =3*(sb->totpoint-a);
-                               int ip =3*(2*sb->totpoint-a);
-                               int n;
-                               for (n=0;n<3;n++) {nlRightHandSideSet(0, iv+n, bp->force[0+n]);}
-                               for (n=0;n<3;n++) {nlRightHandSideSet(0, ip+n, bp->vec[0+n]);}
-                       }
-                       nlEnd(NL_MATRIX);
-                       nlEnd(NL_SYSTEM);
-
-                       if ((G.debug_value == 32) && (nl_flags & NLF_BUILD)) {
-                               printf("####MEE#####\n");
-                               nlPrintMatrix();
-                       }
-
-                       success= nlSolveAdvanced(NULL, 1);
-
-                       // nlPrintMatrix(); /* for debug purpose .. anyhow cropping B vector looks like working */
-                       if (success) {
-                               float f;
-                               int index =0;
-                               /* for debug purpose .. anyhow cropping B vector looks like working */
-                               if (G.debug_value ==32)
-                                       for (a=2*sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
-                                               f=nlGetVariable(0, index);
-                                               printf("(%f ", f);index++;
-                                               f=nlGetVariable(0, index);
-                                               printf("%f ", f);index++;
-                                               f=nlGetVariable(0, index);
-                                               printf("%f)", f);index++;
-                                       }
-
-                                       index =0;
-                                       for (a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
-                                               f=nlGetVariable(0, index);
-                                               bp->impdv[0] = f; index++;
-                                               f=nlGetVariable(0, index);
-                                               bp->impdv[1] = f; index++;
-                                               f=nlGetVariable(0, index);
-                                               bp->impdv[2] = f; index++;
-                                       }
-                                       /*
-                                       for (a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
-                                       f=nlGetVariable(0, index);
-                                       bp->impdx[0] = f; index++;
-                                       f=nlGetVariable(0, index);
-                                       bp->impdx[1] = f; index++;
-                                       f=nlGetVariable(0, index);
-                                       bp->impdx[2] = f; index++;
-                                       }
-                                       */
-                       }
-                       else {
-                               printf("Matrix inversion failed\n");
-                               for (a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
-                                       copy_v3_v3(bp->impdv, bp->force);
-                               }
-
-                       }
-
-                       //sct=PIL_check_seconds_timer();
-                       //if (sct-sst > 0.01f) printf(" implicit solver time %f %s \r", sct-sst, ob->id.name);
-               }
-               /* cleanup */
-#endif
                pdEndEffectors(&do_effector);
        }
 }
@@ -3450,8 +3323,6 @@ SoftBody *sbNew(Scene *scene)
        sb->shearstiff = 1.0f;
        sb->solverflags |= SBSO_OLDERR;
 
-       sb->pointcache = BKE_ptcache_add(&sb->ptcaches);
-
        if (!sb->effector_weights)
                sb->effector_weights = BKE_add_effector_weights(NULL);
 
@@ -3464,8 +3335,6 @@ SoftBody *sbNew(Scene *scene)
 void sbFree(SoftBody *sb)
 {
        free_softbody_intern(sb);
-       BKE_ptcache_free_list(&sb->ptcaches);
-       sb->pointcache = NULL;
        if (sb->effector_weights)
                MEM_freeN(sb->effector_weights);
        MEM_freeN(sb);
@@ -3649,11 +3518,11 @@ static void softbody_step(Scene *scene, Object *ob, SoftBody *sb, float dtime)
         */
        if (dtime < 0 || dtime > 10.5f) return;
 
-       ccd_update_deflector_hash(scene, ob, sb->scratch->colliderhash);
+       ccd_update_deflector_hash(scene, sb->collision_group, ob, sb->scratch->colliderhash);
 
        if (sb->scratch->needstobuildcollider) {
-               if (query_external_colliders(scene, ob)) {
-                       ccd_build_deflector_hash(scene, ob, sb->scratch->colliderhash);
+               if (query_external_colliders(scene, sb->collision_group, ob)) {
+                       ccd_build_deflector_hash(scene, sb->collision_group, ob, sb->scratch->colliderhash);
                }
                sb->scratch->needstobuildcollider=0;
        }
@@ -3683,12 +3552,12 @@ static void softbody_step(Scene *scene, Object *ob, SoftBody *sb, float dtime)
 
                        sb->scratch->flag &= ~SBF_DOFUZZY;
                        /* do predictive euler step */
-                       softbody_calc_forces(scene, ob, forcetime, timedone/dtime, 0);
+                       softbody_calc_forces(scene, ob, forcetime, timedone/dtime);
 
                        softbody_apply_forces(ob, forcetime, 1, NULL, mid_flags);
 
                        /* crop new slope values to do averaged slope step */
-                       softbody_calc_forces(scene, ob, forcetime, timedone/dtime, 0);
+                       softbody_calc_forces(scene, ob, forcetime, timedone/dtime);
 
                        softbody_apply_forces(ob, forcetime, 2, &err, mid_flags);
                        softbody_apply_goalsnap(ob);
@@ -3772,30 +3641,17 @@ static void softbody_step(Scene *scene, Object *ob, SoftBody *sb, float dtime)
 void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], int numVerts)
 {
        SoftBody *sb= ob->soft;
-       PointCache *cache;
-       PTCacheID pid;
-       float dtime, timescale;
-       int framedelta, framenr, startframe, endframe;
-       int cache_result;
-
-       cache= sb->pointcache;
-
-       framenr= (int)cfra;
-       framedelta= framenr - cache->simframe;
-
-       BKE_ptcache_id_from_softbody(&pid, ob, sb);
-       BKE_ptcache_id_time(&pid, scene, framenr, &startframe, &endframe, &timescale);
+       float dtime, timescale = 1.0f;
+       int framedelta = 1, framenr = (int)cfra, startframe = scene->r.sfra, endframe = scene->r.efra;
 
        /* check for changes in mesh, should only happen in case the mesh
         * structure changes during an animation */
        if (sb->bpoint && numVerts != sb->totpoint) {
-               BKE_ptcache_invalidate(cache);
                return;
        }
 
        /* clamp frame ranges */
        if (framenr < startframe) {
-               BKE_ptcache_invalidate(cache);
                return;
        }
        else if (framenr > endframe) {
@@ -3832,50 +3688,17 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i
                return;
        }
        if (framenr == startframe) {
-               BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
-
                /* first frame, no simulation to do, just set the positions */
                softbody_update_positions(ob, sb, vertexCos, numVerts);
 
-               BKE_ptcache_validate(cache, framenr);
-               cache->flag &= ~PTCACHE_REDO_NEEDED;
-
                sb->last_frame = framenr;
 
                return;
        }
 
-       /* try to read from cache */
-       cache_result = BKE_ptcache_read(&pid, (float)framenr+scene->r.subframe);
-
-       if (cache_result == PTCACHE_READ_EXACT || cache_result == PTCACHE_READ_INTERPOLATED) {
-               softbody_to_object(ob, vertexCos, numVerts, sb->local);
-
-               BKE_ptcache_validate(cache, framenr);
-
-               if (cache_result == PTCACHE_READ_INTERPOLATED && cache->flag & PTCACHE_REDO_NEEDED)
-                       BKE_ptcache_write(&pid, framenr);
-
-               sb->last_frame = framenr;
-
-               return;
-       }
-       else if (cache_result==PTCACHE_READ_OLD) {
-               ; /* do nothing */
-       }
-       else if (/*ob->id.lib || */(cache->flag & PTCACHE_BAKED)) { /* "library linking & pointcaches" has to be solved properly at some point */
-               /* if baked and nothing in cache, do nothing */
-               BKE_ptcache_invalidate(cache);
-               return;
-       }
-
        if (framenr!=sb->last_frame+1)
                return;
 
-       /* if on second frame, write cache for first frame */
-       if (cache->simframe == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0))
-               BKE_ptcache_write(&pid, startframe);
-
        softbody_update_positions(ob, sb, vertexCos, numVerts);
 
        /* checking time: */
@@ -3886,9 +3709,6 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i
 
        softbody_to_object(ob, vertexCos, numVerts, 0);
 
-       BKE_ptcache_validate(cache, framenr);
-       BKE_ptcache_write(&pid, framenr);
-
        sb->last_frame = framenr;
 }