Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2010-10-28 14:12:57 +0400
committerCampbell Barton <ideasman42@gmail.com>2010-10-28 14:12:57 +0400
commitb7c8df231bd04b17b1e7b9965d247b7b62fa06d2 (patch)
treee2b07d00b7b33466b106baafc5495d7e8d85bcee /source
parentab404a0f6643b2fe09744a20bcfb3f448082240d (diff)
partial bugfix [#24425] Blender 2.54 Beta crashes when starting rendering
Fix for one of the causes of crashing. Applying armature deform wasn't thread safe since the pose bones had deform data written into them when deforming a mesh. This fixes crashing immediately, on every render for me but blender still crashes calculating the subsurf sometimes.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/intern/armature.c101
-rw-r--r--source/blender/makesdna/DNA_action_types.h13
2 files changed, 64 insertions, 50 deletions
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index b44bf751a8a..3bec79eb352 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -577,7 +577,13 @@ Mat4 *b_bone_spline_setup(bPoseChannel *pchan, int rest)
/* ************ Armature Deform ******************* */
-static void pchan_b_bone_defmats(bPoseChannel *pchan, int use_quaternion)
+typedef struct bPoseChanDeform {
+ Mat4 *b_bone_mats;
+ DualQuat *dual_quat;
+ DualQuat *b_bone_dual_quats;
+} bPoseChanDeform;
+
+static void pchan_b_bone_defmats(bPoseChannel *pchan, bPoseChanDeform *pdef_info, int use_quaternion)
{
Bone *bone= pchan->bone;
Mat4 *b_bone= b_bone_spline_setup(pchan, 0);
@@ -589,11 +595,11 @@ static void pchan_b_bone_defmats(bPoseChannel *pchan, int use_quaternion)
/* allocate b_bone matrices and dual quats */
b_bone_mats= MEM_mallocN((1+bone->segments)*sizeof(Mat4), "BBone defmats");
- pchan->b_bone_mats= b_bone_mats;
+ pdef_info->b_bone_mats= b_bone_mats;
if(use_quaternion) {
b_bone_dual_quats= MEM_mallocN((bone->segments)*sizeof(DualQuat), "BBone dqs");
- pchan->b_bone_dual_quats= b_bone_dual_quats;
+ pdef_info->b_bone_dual_quats= b_bone_dual_quats;
}
/* first matrix is the inverse arm_mat, to bring points in local bone space
@@ -618,9 +624,9 @@ static void pchan_b_bone_defmats(bPoseChannel *pchan, int use_quaternion)
}
}
-static void b_bone_deform(bPoseChannel *pchan, Bone *bone, float *co, DualQuat *dq, float defmat[][3])
+static void b_bone_deform(bPoseChanDeform *pdef_info, Bone *bone, float *co, DualQuat *dq, float defmat[][3])
{
- Mat4 *b_bone= pchan->b_bone_mats;
+ Mat4 *b_bone= pdef_info->b_bone_mats;
float (*mat)[4]= b_bone[0].mat;
float segment, y;
int a;
@@ -637,7 +643,7 @@ static void b_bone_deform(bPoseChannel *pchan, Bone *bone, float *co, DualQuat *
CLAMP(a, 0, bone->segments-1);
if(dq) {
- copy_dq_dq(dq, &((DualQuat*)pchan->b_bone_dual_quats)[a]);
+ copy_dq_dq(dq, &(pdef_info->b_bone_dual_quats)[a]);
}
else {
mul_m4_v3(b_bone[a+1].mat, co);
@@ -711,7 +717,7 @@ static void pchan_deform_mat_add(bPoseChannel *pchan, float weight, float bbonem
add_m3_m3m3(mat, mat, wmat);
}
-static float dist_bone_deform(bPoseChannel *pchan, float *vec, DualQuat *dq, float mat[][3], float *co)
+static float dist_bone_deform(bPoseChannel *pchan, bPoseChanDeform *pdef_info, float *vec, DualQuat *dq, float mat[][3], float *co)
{
Bone *bone= pchan->bone;
float fac, contrib=0.0;
@@ -732,7 +738,7 @@ static float dist_bone_deform(bPoseChannel *pchan, float *vec, DualQuat *dq, flo
if(vec) {
if(bone->segments>1)
// applies on cop and bbonemat
- b_bone_deform(pchan, bone, cop, NULL, (mat)?bbonemat:NULL);
+ b_bone_deform(pdef_info, bone, cop, NULL, (mat)?bbonemat:NULL);
else
mul_m4_v3(pchan->chan_mat, cop);
@@ -745,11 +751,11 @@ static float dist_bone_deform(bPoseChannel *pchan, float *vec, DualQuat *dq, flo
}
else {
if(bone->segments>1) {
- b_bone_deform(pchan, bone, cop, &bbonedq, NULL);
+ b_bone_deform(pdef_info, bone, cop, &bbonedq, NULL);
add_weighted_dq_dq(dq, &bbonedq, fac);
}
else
- add_weighted_dq_dq(dq, pchan->dual_quat, fac);
+ add_weighted_dq_dq(dq, pdef_info->dual_quat, fac);
}
}
}
@@ -757,7 +763,7 @@ static float dist_bone_deform(bPoseChannel *pchan, float *vec, DualQuat *dq, flo
return contrib;
}
-static void pchan_bone_deform(bPoseChannel *pchan, float weight, float *vec, DualQuat *dq, float mat[][3], float *co, float *contrib)
+static void pchan_bone_deform(bPoseChannel *pchan, bPoseChanDeform *pdef_info, float weight, float *vec, DualQuat *dq, float mat[][3], float *co, float *contrib)
{
float cop[3], bbonemat[3][3];
DualQuat bbonedq;
@@ -770,7 +776,7 @@ static void pchan_bone_deform(bPoseChannel *pchan, float weight, float *vec, Dua
if(vec) {
if(pchan->bone->segments>1)
// applies on cop and bbonemat
- b_bone_deform(pchan, pchan->bone, cop, NULL, (mat)?bbonemat:NULL);
+ b_bone_deform(pdef_info, pchan->bone, cop, NULL, (mat)?bbonemat:NULL);
else
mul_m4_v3(pchan->chan_mat, cop);
@@ -783,11 +789,11 @@ static void pchan_bone_deform(bPoseChannel *pchan, float weight, float *vec, Dua
}
else {
if(pchan->bone->segments>1) {
- b_bone_deform(pchan, pchan->bone, cop, &bbonedq, NULL);
+ b_bone_deform(pdef_info, pchan->bone, cop, &bbonedq, NULL);
add_weighted_dq_dq(dq, &bbonedq, weight);
}
else
- add_weighted_dq_dq(dq, pchan->dual_quat, weight);
+ add_weighted_dq_dq(dq, pdef_info->dual_quat, weight);
}
(*contrib)+=weight;
@@ -798,8 +804,11 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
int numVerts, int deformflag,
float (*prevCos)[3], const char *defgrp_name)
{
+ bPoseChanDeform *pdef_info_array;
+ bPoseChanDeform *pdef_info= NULL;
bArmature *arm= armOb->data;
bPoseChannel *pchan, **defnrToPC = NULL;
+ int *defnrToPCIndex= NULL;
MDeformVert *dverts = NULL;
bDeformGroup *dg;
DualQuat *dualquats= NULL;
@@ -823,20 +832,24 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
/* bone defmats are already in the channels, chan_mat */
/* initialize B_bone matrices and dual quaternions */
+ totchan= BLI_countlist(&armOb->pose->chanbase);
+
if(use_quaternion) {
- totchan= BLI_countlist(&armOb->pose->chanbase);
dualquats= MEM_callocN(sizeof(DualQuat)*totchan, "dualquats");
}
+
+ pdef_info_array= MEM_callocN(sizeof(bPoseChanDeform)*totchan, "bPoseChanDeform");
totchan= 0;
- for(pchan = armOb->pose->chanbase.first; pchan; pchan = pchan->next) {
+ pdef_info= pdef_info_array;
+ for(pchan= armOb->pose->chanbase.first; pchan; pchan= pchan->next, pdef_info++) {
if(!(pchan->bone->flag & BONE_NO_DEFORM)) {
if(pchan->bone->segments > 1)
- pchan_b_bone_defmats(pchan, use_quaternion);
+ pchan_b_bone_defmats(pchan, pdef_info, use_quaternion);
if(use_quaternion) {
- pchan->dual_quat= &dualquats[totchan++];
- mat4_to_dquat( pchan->dual_quat,pchan->bone->arm_mat, pchan->chan_mat);
+ pdef_info->dual_quat= &dualquats[totchan++];
+ mat4_to_dquat( pdef_info->dual_quat,pchan->bone->arm_mat, pchan->chan_mat);
}
}
}
@@ -872,15 +885,19 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
else if(dverts) use_dverts = 1;
if(use_dverts) {
- defnrToPC = MEM_callocN(sizeof(*defnrToPC) * numGroups,
- "defnrToBone");
+ defnrToPC = MEM_callocN(sizeof(*defnrToPC) * numGroups, "defnrToBone");
+ defnrToPCIndex = MEM_callocN(sizeof(*defnrToPCIndex) * numGroups, "defnrToIndex");
for(i = 0, dg = target->defbase.first; dg;
i++, dg = dg->next) {
defnrToPC[i] = get_pose_channel(armOb->pose, dg->name);
/* exclude non-deforming bones */
if(defnrToPC[i]) {
- if(defnrToPC[i]->bone->flag & BONE_NO_DEFORM)
+ if(defnrToPC[i]->bone->flag & BONE_NO_DEFORM) {
defnrToPC[i]= NULL;
+ }
+ else {
+ defnrToPCIndex[i]= BLI_findindex(&armOb->pose->chanbase, defnrToPC[i]);
+ }
}
}
}
@@ -951,10 +968,10 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
for(j = 0; j < dvert->totweight; j++){
int index = dvert->dw[j].def_nr;
- pchan = index < numGroups?defnrToPC[index]:NULL;
- if(pchan) {
+ if(index < numGroups && (pchan= defnrToPC[index])) {
float weight = dvert->dw[j].weight;
- Bone *bone = pchan->bone;
+ Bone *bone= pchan->bone;
+ pdef_info= pdef_info_array + defnrToPCIndex[index];
deformed = 1;
@@ -965,25 +982,27 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
bone->rad_tail,
bone->dist);
}
- pchan_bone_deform(pchan, weight, vec, dq, smat, co, &contrib);
+ pchan_bone_deform(pchan, pdef_info, weight, vec, dq, smat, co, &contrib);
}
}
/* if there are vertexgroups but not groups with bones
* (like for softbody groups)
*/
if(deformed == 0 && use_envelope) {
- for(pchan = armOb->pose->chanbase.first; pchan;
- pchan = pchan->next) {
+ pdef_info= pdef_info_array;
+ for(pchan= armOb->pose->chanbase.first; pchan;
+ pchan= pchan->next, pdef_info++) {
if(!(pchan->bone->flag & BONE_NO_DEFORM))
- contrib += dist_bone_deform(pchan, vec, dq, smat, co);
+ contrib += dist_bone_deform(pchan, pdef_info, vec, dq, smat, co);
}
}
}
else if(use_envelope) {
+ pdef_info= pdef_info_array;
for(pchan = armOb->pose->chanbase.first; pchan;
- pchan = pchan->next) {
+ pchan = pchan->next, pdef_info++) {
if(!(pchan->bone->flag & BONE_NO_DEFORM))
- contrib += dist_bone_deform(pchan, vec, dq, smat, co);
+ contrib += dist_bone_deform(pchan, pdef_info, vec, dq, smat, co);
}
}
@@ -1039,20 +1058,20 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
if(dualquats) MEM_freeN(dualquats);
if(defnrToPC) MEM_freeN(defnrToPC);
-
+ if(defnrToPCIndex) MEM_freeN(defnrToPCIndex);
+
/* free B_bone matrices */
- for(pchan = armOb->pose->chanbase.first; pchan; pchan = pchan->next) {
- if(pchan->b_bone_mats) {
- MEM_freeN(pchan->b_bone_mats);
- pchan->b_bone_mats = NULL;
+ pdef_info= pdef_info_array;
+ for(pchan = armOb->pose->chanbase.first; pchan; pchan = pchan->next, pdef_info++) {
+ if(pdef_info->b_bone_mats) {
+ MEM_freeN(pdef_info->b_bone_mats);
}
- if(pchan->b_bone_dual_quats) {
- MEM_freeN(pchan->b_bone_dual_quats);
- pchan->b_bone_dual_quats = NULL;
+ if(pdef_info->b_bone_dual_quats) {
+ MEM_freeN(pdef_info->b_bone_dual_quats);
}
-
- pchan->dual_quat = NULL;
}
+
+ MEM_freeN(pdef_info_array);
}
/* ************ END Armature Deform ******************* */
diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h
index f7bbf9235ab..6f6e4978cfc 100644
--- a/source/blender/makesdna/DNA_action_types.h
+++ b/source/blender/makesdna/DNA_action_types.h
@@ -203,12 +203,10 @@ typedef struct bPoseChannel {
struct bPoseChannel *child; /* set on read file or rebuild pose, the 'ik' child, for b-bones */
struct ListBase iktree; /* only while evaluating pose */
- /* only while deform, stores precalculated b_bone deform mats,
- dual quaternions */
- void *b_bone_mats;
- void *dual_quat;
- void *b_bone_dual_quats;
-
+ bMotionPath *mpath; /* motion path cache for this bone */
+ struct Object *custom; /* draws custom object instead of default bone shape */
+ struct bPoseChannel *custom_tx; /* odd feature, display with another bones transform. needed in rare cases for advanced rigs, since the alternative is highly complicated - campbell */
+
/* transforms - written in by actions or transform */
float loc[3];
float size[3];
@@ -234,9 +232,6 @@ typedef struct bPoseChannel {
float iklinweight; /* weight of joint stretch constraint */
float *path; /* totpath x 3 x float */ // XXX depreceated... old animation system (armature only viz)
- bMotionPath *mpath; /* motion path cache for this bone */
- struct Object *custom; /* draws custom object instead of default bone shape */
- struct bPoseChannel *custom_tx; /* odd feature, display with another bones transform. needed in rare cases for advanced rigs, since the alternative is highly complicated - campbell */
} bPoseChannel;