[Bf-blender-cvs] [26a8237cd70] soc-2020-soft-body: I think I fixed all of the copy and save errors

mattoverby noreply at git.blender.org
Thu Aug 20 01:15:33 CEST 2020


Commit: 26a8237cd7001c74be8bce088561ed7ba570c8eb
Author: mattoverby
Date:   Wed Aug 19 18:07:25 2020 -0500
Branches: soc-2020-soft-body
https://developer.blender.org/rB26a8237cd7001c74be8bce088561ed7ba570c8eb

I think I fixed all of the copy and save errors

===================================================================

M	intern/softbody/admmpd_api.h
M	source/blender/blenkernel/BKE_softbody.h
M	source/blender/blenkernel/intern/object.c
M	source/blender/blenkernel/intern/softbody.c
M	source/blender/blenloader/intern/readfile.c
M	source/blender/blenloader/intern/writefile.c
M	source/blender/makesdna/DNA_object_force_types.h

===================================================================

diff --git a/intern/softbody/admmpd_api.h b/intern/softbody/admmpd_api.h
index 599bb523012..fe9a4e0aacd 100644
--- a/intern/softbody/admmpd_api.h
+++ b/intern/softbody/admmpd_api.h
@@ -32,15 +32,21 @@ extern "C" {
 #include "DNA_scene_types.h"
 
 typedef struct ADMMPDInterfaceData {
-    char last_error[256]; // last error message
-    struct ADMMPDInternalData *idata; // internal data
+    /* So that ADMMPD data can be stored in a linked list. */
+    struct ADMMPDInterfaceData *next, *prev;
+    /* The name of the object that uses this data. */
+    char name[MAX_ID_NAME];
+    /* If API returns 0, error stored here. */
+    char last_error[256];
+    /* internal data is NULL until update_mesh or update_solver. */
+    struct ADMMPDInternalData *idata;
 } ADMMPDInterfaceData;
 
-// Frees ADMMPDInternalData
+/* Frees ADMMPDInternalData */
 void admmpd_dealloc(ADMMPDInterfaceData*);
 
-// Standalone function to compute embedding lattice
-// but without the embedding info (for visual debugging)
+/* Standalone function to compute embedding lattice
+* but without the embedding info (for visual debugging) */
 void admmpd_compute_lattice(
     int subdiv,
     float *in_verts, int in_nv,
@@ -48,34 +54,34 @@ void admmpd_compute_lattice(
     float **out_verts, int *out_nv,
     unsigned int **out_tets, int *out_nt);
 
-// Test if the mesh topology has changed in a way that requires re-initialization.
-// Returns 0 (no update needed) or 1 (needs update)
+/* Test if the mesh topology has changed in a way that requires re-initialization.
+* Returns 0 (no update needed) or 1 (needs update) */
 int admmpd_mesh_needs_update(ADMMPDInterfaceData*, Object*);
 
-// Initialize the mesh.
-// The SoftBody object's (ob->soft) bpoint array is also updated.
-// Returns 1 on success, 0 on failure, -1 on warning
+/* Initialize the mesh.
+* The SoftBody object's (ob->soft) bpoint array is also updated.
+* Returns 1 on success, 0 on failure, -1 on warning */
 int admmpd_update_mesh(ADMMPDInterfaceData*, Object*, float (*vertexCos)[3]);
 
-// Test if certain parameter changes require re-initialization.
-// Returns 0 (no update needed) or 1 (needs update)
+/* Test if certain parameter changes require re-initialization.
+* Returns 0 (no update needed) or 1 (needs update) */
 int admmpd_solver_needs_update(ADMMPDInterfaceData*, Scene*, Object*);
 
-// Initialize solver variables.
-// Returns 1 on success, 0 on failure, -1 on warning
+/* Initialize solver variables.
+* Returns 1 on success, 0 on failure, -1 on warning */
 int admmpd_update_solver(ADMMPDInterfaceData*, Scene*, Object*, float (*vertexCos)[3]);
 
-// Copies BodyPoint data (from SoftBody)
-// to internal vertex position and velocity
+/* Copies BodyPoint data (from SoftBody)
+* to internal vertex position and velocity */
 void admmpd_copy_from_object(ADMMPDInterfaceData*, Object*);
 
-// Copies ADMM-PD data to SoftBody::bpoint and vertexCos.
-// If vertexCos is NULL, it is ignored.
+/* Copies ADMM-PD data to SoftBody::bpoint and vertexCos.
+* If vertexCos is NULL, it is ignored. */
 void admmpd_copy_to_object(ADMMPDInterfaceData*, Object*, float (*vertexCos)[3]);
 
-// Sets the obstacle data for collisions.
-// Update obstacles has a different interface because of the
-// complexity of grabbing obstacle mesh data. We'll leave that in softbody.c
+/* Sets the obstacle data for collisions.
+* Update obstacles has a different interface because of the
+* complexity of grabbing obstacle mesh data. We'll leave that in softbody.c */
 void admmpd_update_obstacles(
     ADMMPDInterfaceData*,
     float *in_verts_0,
@@ -84,8 +90,8 @@ void admmpd_update_obstacles(
     unsigned int *in_faces,
     int nf);
 
-// Performs a time step. Object and vertexCos are not changed.
-// Returns 1 on success, 0 on failure, -1 on warning
+/* Performs a time step. Object and vertexCos are not changed.
+* Returns 1 on success, 0 on failure, -1 on warning */
 int admmpd_solve(ADMMPDInterfaceData*, Object*, float (*vertexCos)[3]);
 
 #ifdef __cplusplus
diff --git a/source/blender/blenkernel/BKE_softbody.h b/source/blender/blenkernel/BKE_softbody.h
index fb377302c7a..0e76774a0de 100644
--- a/source/blender/blenkernel/BKE_softbody.h
+++ b/source/blender/blenkernel/BKE_softbody.h
@@ -50,6 +50,9 @@ typedef struct BodyPoint {
 /* allocates and initializes general main data */
 extern struct SoftBody *sbNew(struct Scene *scene);
 
+/* copies custom solver data from src to dest */
+extern void sbCustomCopy(struct Object *dest, struct Object *src);
+
 /* reads custom structs for file i/o */
 extern void sbCustomRead(struct Object *ob);
 
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 15ad653e6f8..214c8ca8d8b 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -1395,7 +1395,6 @@ Object *BKE_object_add_for_data(
 
 void BKE_object_copy_softbody(struct Object *ob_dst, const struct Object *ob_src, const int flag)
 {
-
   SoftBody *sb = ob_src->soft;
   SoftBody *sbn;
   bool tagged_no_main = ob_dst->id.tag & LIB_TAG_NO_MAIN;
@@ -1408,6 +1407,8 @@ void BKE_object_copy_softbody(struct Object *ob_dst, const struct Object *ob_src
 
   sbn = MEM_dupallocN(sb);
 
+  sbCustomCopy(ob_dst,ob_src);
+
   if ((flag & LIB_ID_COPY_CACHES) == 0) {
     sbn->totspring = sbn->totpoint = 0;
     sbn->bpoint = NULL;
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index bca2af1fb18..6d9b005dea0 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -3128,7 +3128,7 @@ SoftBody *sbNew(Scene *scene)
   SoftBody *sb;
   sb = MEM_callocN(sizeof(SoftBody), "softbody");
 
-  sb->solver_mode = SOLVER_MODE_LEGACY;  // SOLVER_MODE_ADMMPD;
+  sb->solver_mode = SOLVER_MODE_LEGACY;
   sb->admmpd_mesh_mode = 0;              // embedded
   sb->admmpd_substeps = 1;
   sb->admmpd_max_admm_iters = 20;
@@ -3148,7 +3148,7 @@ SoftBody *sbNew(Scene *scene)
   sb->admmpd_maxthreads = -1;
   sb->admmpd_loglevel = 1;   // low
   sb->admmpd_linsolver = 1;  // PCG
-  sb->admmpd = MEM_callocN(sizeof(ADMMPDInterfaceData), "SoftBody_admmpd");
+  //sb->admmpd = MEM_callocN(sizeof(ADMMPDInterfaceData), "SoftBody_ADMMPD");
 
   sb->mediafrict = 0.5f;
   sb->nodemass = 1.0f;
@@ -3189,6 +3189,7 @@ SoftBody *sbNew(Scene *scene)
 
   sb->shared = MEM_callocN(sizeof(*sb->shared), "SoftBody_Shared");
   sb->shared->pointcache = BKE_ptcache_add(&sb->shared->ptcaches);
+  sb->shared->admmpd_list = MEM_callocN(sizeof(ListBase), "SoftBody_ADMMPD_List");
 
   if (!sb->effector_weights) {
     sb->effector_weights = BKE_effector_add_weights(NULL);
@@ -3209,15 +3210,28 @@ void sbFree(Object *ob)
 
   free_softbody_intern(sb);
 
+  /* Only free shared data on non-CoW copies */
   if ((ob->id.tag & LIB_TAG_NO_MAIN) == 0) {
 
-    if (sb->admmpd) {
-      admmpd_dealloc(sb->admmpd);
-      MEM_freeN(sb->admmpd);
-      sb->admmpd = NULL;
+    /* Clear the ADMMPD linked list. Because the linked
+    * list pointer is copied to all soft body objects, we
+    * want to be careful not to free twice. */
+    {
+      ADMMPDInterfaceData *admmpd;
+      int cleared_admmpd_list = 0;
+      while ((admmpd = BLI_pophead(sb->shared->admmpd_list))) {
+        cleared_admmpd_list = 1;
+        if (admmpd != NULL) {
+          admmpd_dealloc(admmpd);
+          MEM_freeN(admmpd);
+        }
+      }
+      if (cleared_admmpd_list) {
+        MEM_freeN(sb->shared->admmpd_list);
+        sb->shared->admmpd_list = NULL;
+      }
     }
 
-    /* Only free shared data on non-CoW copies */
     BKE_ptcache_free_list(&sb->shared->ptcaches);
     sb->shared->pointcache = NULL;
     MEM_freeN(sb->shared);
@@ -3572,7 +3586,8 @@ static void update_collider_admmpd(Depsgraph *depsgraph,
   if (!sb) {
     return;
   }
-  if (!sb->admmpd) {
+  ADMMPDInterfaceData *admmpd = NULL;//sb->admmpd;//sb->shared->admmpd;
+  if (!admmpd) {
     return;
   }
 
@@ -3635,7 +3650,7 @@ static void update_collider_admmpd(Depsgraph *depsgraph,
   }
 
   // Update via API
-  admmpd_update_obstacles(sb->admmpd, obs_v0, obs_v1, tot_verts, obs_faces, tot_faces);
+  admmpd_update_obstacles(admmpd, obs_v0, obs_v1, tot_verts, obs_faces, tot_faces);
 
   // Cleanup
   MEM_freeN(obs_v0);
@@ -3644,6 +3659,57 @@ static void update_collider_admmpd(Depsgraph *depsgraph,
   BKE_collision_objects_free(objects);
 }
 
+static inline ADMMPDInterfaceData* get_admmpd_for_object(Object *ob)
+{
+  SoftBody *sb = ob->soft;
+  if (!sb) {
+    return NULL;
+  }
+  int found = 0;
+  int num_list = 0;
+  ADMMPDInterfaceData *admmpd = sb->shared->admmpd_list->first;
+  while (admmpd != NULL) {
+      if (strcmp(admmpd->name,ob->id.name)==0) {
+        found = 1;
+        break;
+      }
+      admmpd = admmpd->next;
+      num_list++;
+  }
+  if (!found) {
+    return NULL;
+  }
+  return admmpd;
+}
+
+void sbCustomCopy(Object *dest, Object *src)
+{
+  (void)(src);
+  SoftBody *sb_dest = dest->soft;
+  if (!sb_dest) {
+    CLOG_ERROR(&LOG, "No softbody in sbCustomCopy");
+    return;
+  }
+  if (!sb_dest->shared) {
+    CLOG_ERROR(&LOG, "No shared in sbCustomCopy");
+    return;
+  }
+
+  /* This can happen on readfile: */
+  if (!sb_dest->shared->admmpd_list) {
+    sb_dest->shared->admmpd_list = MEM_callocN(sizeof(ListBase), "SoftBody_ADMMPD_List");
+  }
+
+  /* Create ADMM-PD data for this object if it does not already exist. */
+  ADMMPDInterfaceData *admmpd = get_admmpd_for_object(dest);
+  if (admmpd==NULL) {
+    admmpd = MEM_callocN(sizeof(ADMMPDInterfaceData), "ADMMPD");
+    strcpy(admmpd->name, dest->id.name);
+    BLI_addtail(sb_dest->shared->admmpd_list, admmpd);
+  }
+}
+
+
 void sbCustomRead(struct Object *ob)
 {
   SoftBody *sb = ob->soft;
@@ -3653,7 +3719,7 @@ void sbCustomRead(struct Object *ob)
 
   // ADMM-PD data is not currently written to file.
   // Instead, we'll create new data when a .blend file is loaded.
-  sb->admmpd = MEM_callocN(sizeof(ADMMPDInterfaceData), "SoftBody_admmpd");
+  //sb->admmpd = MEM_callocN(sizeof(ADMMPDInterfaceData), "SoftBody_admmpd");
 }
 
 /* simulates one step. framenr is in frames */
@@ -3670,9 +3736,12 @@ void sbObject

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list