[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