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>2012-01-17 21:08:32 +0400
committerCampbell Barton <ideasman42@gmail.com>2012-01-17 21:08:32 +0400
commit47b9f5d8f83e330342fd22c5b56b2623bde06d8c (patch)
tree0446fc03fdfbc2d34c1fbfb1c80bb7ccae286675 /source
parentb805334cc283ea0126f81078830a3d6dcea97e40 (diff)
parenta8081c1d2bb9115833493b011bb93d6c08112b2d (diff)
svn merge ^/trunk/blender -r43443:43461
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_armature.h4
-rw-r--r--source/blender/blenkernel/BKE_array_mallocn.h85
-rw-r--r--source/blender/blenkernel/CMakeLists.txt1
-rw-r--r--source/blender/blenkernel/intern/armature.c332
-rw-r--r--source/blender/editors/interface/interface_regions.c30
-rw-r--r--source/blender/editors/mesh/loopcut.c7
-rw-r--r--source/blender/editors/space_info/info_ops.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_snap.c15
-rw-r--r--source/blender/editors/transform/transform_conversions.c71
-rw-r--r--source/blender/makesrna/intern/rna_ui.c2
-rw-r--r--source/blender/python/intern/bpy_interface.c5
-rw-r--r--source/creator/CMakeLists.txt3
12 files changed, 285 insertions, 272 deletions
diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h
index b301b7cf03b..a89bfbd50b1 100644
--- a/source/blender/blenkernel/BKE_armature.h
+++ b/source/blender/blenkernel/BKE_armature.h
@@ -114,6 +114,10 @@ void pchan_apply_mat4(struct bPoseChannel *pchan, float mat[][4], short use_coma
void pchan_to_mat4(struct bPoseChannel *pchan, float chan_mat[4][4]);
void pchan_calc_mat(struct bPoseChannel *pchan);
+/* Get the "pchan to pose" transform matrix. These matrices apply the effects of
+ * HINGE/NO_SCALE/NO_LOCAL_LOCATION options over the pchan loc/rot/scale transformations. */
+void pchan_to_pose_mat(struct bPoseChannel *pchan, float rotscale_mat[][4], float loc_mat[][4]);
+
/* Rotation Mode Conversions - Used for PoseChannels + Objects... */
void BKE_rotMode_change_values(float quat[4], float eul[3], float axis[3], float *angle, short oldMode, short newMode);
diff --git a/source/blender/blenkernel/BKE_array_mallocn.h b/source/blender/blenkernel/BKE_array_mallocn.h
deleted file mode 100644
index 0f312360521..00000000000
--- a/source/blender/blenkernel/BKE_array_mallocn.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#ifndef BKE_ARRAY_MALLOCN_H
-#define BKE_ARRAY_MALLOCN_H
-
-/** \file BKE_array_mallocn.h
- * \ingroup bke
- * \brief little array macro library.
- */
-
-/* example of usage:
- *
- * int *arr = NULL;
- * V_DECLARE(arr);
- * int i;
- *
- * for (i=0; i<10; i++) {
- * V_GROW(arr);
- * arr[i] = something;
- * }
- * V_FREE(arr);
- *
- * arrays are buffered, using double-buffering (so on each reallocation,
- * the array size is doubled). supposedly this should give good Big Oh
- * behaviour, though it may not be the best in practice.
- */
-
-#define V_DECLARE(vec) int _##vec##_count=0; void *_##vec##_tmp
-
-/* in the future, I plan on having V_DECLARE allocate stack memory it'll
- * use at first, and switch over to heap when it needs more. that'll mess
- * up cases where you'd want to use this API to build a dynamic list for
- * non-local use, so all such cases should use this macro.*/
-#define V_DYNDECLARE(vec) V_DECLARE(vec)
-
-/*this returns the entire size of the array, including any buffering.*/
-#define V_SIZE(vec) ((signed int)((vec)==NULL ? 0 : MEM_allocN_len(vec) / sizeof(*vec)))
-
-/*this returns the logical size of the array, not including buffering.*/
-#define V_COUNT(vec) _##vec##_count
-
-/*grow the array by one. zeroes the new elements.*/
-#define V_GROW(vec) \
- V_SIZE(vec) > _##vec##_count ? _##vec##_count++ : \
- ((_##vec##_tmp = MEM_callocN(sizeof(*vec)*(_##vec##_count*2+2), #vec " " __FILE__ " ")),\
- (void)(vec && memcpy(_##vec##_tmp, vec, sizeof(*vec) * _##vec##_count)),\
- (void)(vec && (MEM_freeN(vec),1)),\
- (vec = _##vec##_tmp),\
- _##vec##_count++)
-
-#define V_FREE(vec) if (vec) MEM_freeN(vec);
-
-/*resets the logical size of an array to zero, but doesn't
- free the memory.*/
-#define V_RESET(vec) _##vec##_count=0
-
-/*set the count of the array*/
-#define V_SETCOUNT(vec, count) _##vec##_count = (count)
-
-#endif // BKE_ARRAY_MALLOCN_H
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index ce021e7dbc7..dc93885c05c 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -158,7 +158,6 @@ set(SRC
BKE_anim.h
BKE_animsys.h
BKE_armature.h
- BKE_array_mallocn.h
BKE_blender.h
BKE_bmesh.h
BKE_bmeshCustomData.h
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index ae04b7760c2..4f83bcf7e7f 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -590,7 +590,7 @@ Mat4 *b_bone_spline_setup(bPoseChannel *pchan, int rest)
/* ************ Armature Deform ******************* */
typedef struct bPoseChanDeform {
- Mat4 *b_bone_mats;
+ Mat4 *b_bone_mats;
DualQuat *dual_quat;
DualQuat *b_bone_dual_quats;
} bPoseChanDeform;
@@ -1123,66 +1123,183 @@ void armature_loc_world_to_pose(Object *ob, float *inloc, float *outloc)
copy_v3_v3(outloc, nLocMat[3]);
}
-/* Convert Pose-Space Matrix to Bone-Space Matrix
- * NOTE: this cannot be used to convert to pose-space transforms of the supplied
- * pose-channel into its local space (i.e. 'visual'-keyframing)
+/* Construct the matrices (rot/scale and loc) to apply the PoseChannels into the armature (object) space.
+ * I.e. (roughly) the "pose_mat(b-1) * yoffs(b-1) * d_root(b) * bone_mat(b)" in the
+ * pose_mat(b)= pose_mat(b-1) * yoffs(b-1) * d_root(b) * bone_mat(b) * chan_mat(b)
+ * ...function.
+ *
+ * This allows to get the transformations of a bone in its object space, *before* constraints (and IK)
+ * get applied (used by pose evaluation code).
+ * And reverse: to find pchan transformations needed to place a bone at a given loc/rot/scale
+ * in object space (used by interactive transform, and snapping code).
+ *
+ * Note that, with the HINGE/NO_SCALE/NO_LOCAL_LOCATION options, the location matrix
+ * will differ from the rotation/scale matrix...
+ *
+ * NOTE: This cannot be used to convert to pose-space transforms of the supplied
+ * pose-channel into its local space (i.e. 'visual'-keyframing).
+ * (note: I don't understand that, so I keep it :p --mont29).
*/
-void armature_mat_pose_to_bone(bPoseChannel *pchan, float inmat[][4], float outmat[][4])
+void pchan_to_pose_mat(bPoseChannel *pchan, float rotscale_mat[][4], float loc_mat[][4])
{
- float pc_trans[4][4], inv_trans[4][4];
- float pc_posemat[4][4], inv_posemat[4][4];
- float pose_mat[4][4];
-
- /* paranoia: prevent crashes with no pose-channel supplied */
- if (pchan==NULL) return;
-
- /* default flag */
- if((pchan->bone->flag & BONE_NO_LOCAL_LOCATION)==0) {
- /* get the inverse matrix of the pchan's transforms */
- switch(pchan->rotmode) {
- case ROT_MODE_QUAT:
- loc_quat_size_to_mat4(pc_trans, pchan->loc, pchan->quat, pchan->size);
- break;
- case ROT_MODE_AXISANGLE:
- loc_axisangle_size_to_mat4(pc_trans, pchan->loc, pchan->rotAxis, pchan->rotAngle, pchan->size);
- break;
- default: /* euler */
- loc_eul_size_to_mat4(pc_trans, pchan->loc, pchan->eul, pchan->size);
+ Bone *bone, *parbone;
+ bPoseChannel *parchan;
+
+ /* set up variables for quicker access below */
+ bone= pchan->bone;
+ parbone= bone->parent;
+ parchan= pchan->parent;
+
+ if(parchan) {
+ float offs_bone[4][4]; /* yoffs(b-1) + root(b) + bonemat(b). */
+
+ /* Bone transform itself. */
+ copy_m4_m3(offs_bone, bone->bone_mat);
+
+ /* The bone's root offset (is in the parent's coordinate system). */
+ copy_v3_v3(offs_bone[3], bone->head);
+
+ /* Get the length translation of parent (length along y axis). */
+ offs_bone[3][1]+= parbone->length;
+
+ /* Compose the rotscale matrix for this bone. */
+ if((bone->flag & BONE_HINGE) && (bone->flag & BONE_NO_SCALE)) {
+ /* Parent rest rotation and scale. */
+ mult_m4_m4m4(rotscale_mat, parbone->arm_mat, offs_bone);
}
+ else if(bone->flag & BONE_HINGE) {
+ /* Parent rest rotation and pose scale. */
+ float tmat[4][4], tscale[3];
- copy_m4_m4(pose_mat, pchan->pose_mat);
- }
- else {
- /* local location, this is not default, different calculation
- * note: only tested for location with pose bone snapping.
- * If this is not useful in other cases the BONE_NO_LOCAL_LOCATION
- * case may have to be split into its own function. */
- unit_m4(pc_trans);
- copy_v3_v3(pc_trans[3], pchan->loc);
+ /* Extract the scale of the parent pose matrix. */
+ mat4_to_size(tscale, parchan->pose_mat);
+ size_to_mat4(tmat, tscale);
+
+ /* Applies the parent pose scale to the rest matrix. */
+ mult_m4_m4m4(tmat, tmat, parbone->arm_mat);
+
+ mult_m4_m4m4(rotscale_mat, tmat, offs_bone);
+ }
+ else if(bone->flag & BONE_NO_SCALE) {
+ /* Parent pose rotation and rest scale (i.e. no scaling). */
+ float tmat[4][4];
+ copy_m4_m4(tmat, parchan->pose_mat);
+ normalize_m4(tmat);
+ mult_m4_m4m4(rotscale_mat, tmat, offs_bone);
+ }
+ else
+ mult_m4_m4m4(rotscale_mat, parchan->pose_mat, offs_bone);
+
+# if 1
+ /* Compose the loc matrix for this bone. */
+ /* NOTE: That version deos not modify bone's loc when HINGE/NO_SCALE options are set. */
- /* use parents rotation/scale space + own absolute position */
- if(pchan->parent) copy_m4_m4(pose_mat, pchan->parent->pose_mat);
- else unit_m4(pose_mat);
+ /* In this case, use the object's space *orientation*. */
+ if(bone->flag & BONE_NO_LOCAL_LOCATION) {
+ /* XXX I'm sure that code can be simplified! */
+ float bone_loc[4][4], bone_rotscale[3][3], tmat4[4][4], tmat3[3][3];
+ unit_m4(bone_loc);
+ unit_m4(loc_mat);
+ unit_m4(tmat4);
+
+ mul_v3_m4v3(bone_loc[3], parchan->pose_mat, offs_bone[3]);
+
+ unit_m3(bone_rotscale);
+ copy_m3_m4(tmat3, parchan->pose_mat);
+ mul_m3_m3m3(bone_rotscale, tmat3, bone_rotscale);
+
+ copy_m4_m3(tmat4, bone_rotscale);
+ mult_m4_m4m4(loc_mat, bone_loc, tmat4);
+ }
+ /* Those flags do not affect position, use plain parent transform space! */
+ else if(bone->flag & (BONE_HINGE|BONE_NO_SCALE)) {
+ mult_m4_m4m4(loc_mat, parchan->pose_mat, offs_bone);
+ }
+ /* Else (i.e. default, usual case), just use the same matrix for rotation/scaling, and location. */
+ else
+ copy_m4_m4(loc_mat, rotscale_mat);
+# endif
+# if 0
+ /* Compose the loc matrix for this bone. */
+ /* NOTE: That version modifies bone's loc when HINGE/NO_SCALE options are set. */
+
+ /* In these cases we need to compute location separately */
+ if(bone->flag & (BONE_HINGE|BONE_NO_SCALE|BONE_NO_LOCAL_LOCATION)) {
+ float bone_loc[4][4], bone_rotscale[3][3], tmat4[4][4], tmat3[3][3];
+ unit_m4(bone_loc);
+ unit_m4(loc_mat);
+ unit_m4(tmat4);
+
+ mul_v3_m4v3(bone_loc[3], parchan->pose_mat, offs_bone[3]);
+
+ /* "No local location" is not transformed by bone matrix. */
+ /* This only affects orientations (rotations), as scale is always 1.0 here. */
+ if(bone->flag & BONE_NO_LOCAL_LOCATION)
+ unit_m3(bone_rotscale);
+ else
+ /* We could also use bone->bone_mat directly, here... */
+ copy_m3_m4(bone_rotscale, offs_bone);
+
+ if(bone->flag & BONE_HINGE) {
+ copy_m3_m4(tmat3, parbone->arm_mat);
+ /* for hinge-only, we use armature *rotation*, but pose mat *scale*! */
+ if(!(bone->flag & BONE_NO_SCALE)) {
+ float size[3], tsmat[3][3];
+ mat4_to_size(size, parchan->pose_mat);
+ size_to_mat3(tsmat, size);
+ mul_m3_m3m3(tmat3, tsmat, tmat3);
+ }
+ mul_m3_m3m3(bone_rotscale, tmat3, bone_rotscale);
+ }
+ else if(bone->flag & BONE_NO_SCALE) {
+ /* For no-scale only, normalized parent pose mat is enough! */
+ copy_m3_m4(tmat3, parchan->pose_mat);
+ normalize_m3(tmat3);
+ mul_m3_m3m3(bone_rotscale, tmat3, bone_rotscale);
+ }
+ /* NO_LOCAL_LOCATION only. */
+ else {
+ copy_m3_m4(tmat3, parchan->pose_mat);
+ mul_m3_m3m3(bone_rotscale, tmat3, bone_rotscale);
+ }
- copy_v3_v3(pose_mat[3], pchan->pose_mat[3]);
+ copy_m4_m3(tmat4, bone_rotscale);
+ mult_m4_m4m4(loc_mat, bone_loc, tmat4);
+ }
+ /* Else, just use the same matrix for rotation/scaling, and location. */
+ else
+ copy_m4_m4(loc_mat, rotscale_mat);
+# endif
}
+ /* Root bones. */
+ else {
+ /* Rotation/scaling. */
+ copy_m4_m4(rotscale_mat, pchan->bone->arm_mat);
+ /* Translation. */
+ if(pchan->bone->flag & BONE_NO_LOCAL_LOCATION) {
+ /* Translation of arm_mat, without the rotation. */
+ unit_m4(loc_mat);
+ copy_v3_v3(loc_mat[3], pchan->bone->arm_mat[3]);
+ }
+ else
+ copy_m4_m4(loc_mat, rotscale_mat);
+ }
+}
+
+/* Convert Pose-Space Matrix to Bone-Space Matrix.
+ * NOTE: this cannot be used to convert to pose-space transforms of the supplied
+ * pose-channel into its local space (i.e. 'visual'-keyframing)
+ */
+void armature_mat_pose_to_bone(bPoseChannel *pchan, float inmat[][4], float outmat[][4])
+{
+ float rotscale_mat[4][4], loc_mat[4][4];
+ pchan_to_pose_mat(pchan, rotscale_mat, loc_mat);
+ invert_m4(rotscale_mat);
+ invert_m4(loc_mat);
- invert_m4_m4(inv_trans, pc_trans);
-
- /* Remove the pchan's transforms from it's pose_mat.
- * This should leave behind the effects of restpose +
- * parenting + constraints
- */
- mult_m4_m4m4(pc_posemat, pose_mat, inv_trans);
-
- /* get the inverse of the leftovers so that we can remove
- * that component from the supplied matrix
- */
- invert_m4_m4(inv_posemat, pc_posemat);
-
- /* get the new matrix */
- mult_m4_m4m4(outmat, inv_posemat, inmat);
+ mult_m4_m4m4(outmat, rotscale_mat, inmat);
+ mul_v3_m4v3(outmat[3], loc_mat, inmat[3]);
}
/* Convert Pose-Space Location to Bone-Space Location
@@ -2263,98 +2380,30 @@ void where_is_pose_bone_tail(bPoseChannel *pchan)
*/
void where_is_pose_bone(Scene *scene, Object *ob, bPoseChannel *pchan, float ctime, int do_extra)
{
- Bone *bone, *parbone;
- bPoseChannel *parchan;
- float vec[3];
-
- /* set up variables for quicker access below */
- bone= pchan->bone;
- parbone= bone->parent;
- parchan= pchan->parent;
-
- /* this gives a chan_mat with actions (ipos) results */
- if(do_extra) pchan_calc_mat(pchan);
- else unit_m4(pchan->chan_mat);
+ /* This gives a chan_mat with actions (ipos) results. */
+ if(do_extra)
+ pchan_calc_mat(pchan);
+ else
+ unit_m4(pchan->chan_mat);
- /* construct the posemat based on PoseChannels, that we do before applying constraints */
+ /* Construct the posemat based on PoseChannels, that we do before applying constraints. */
/* pose_mat(b)= pose_mat(b-1) * yoffs(b-1) * d_root(b) * bone_mat(b) * chan_mat(b) */
-
- if(parchan) {
- float offs_bone[4][4]; // yoffs(b-1) + root(b) + bonemat(b)
-
- /* bone transform itself */
- copy_m4_m3(offs_bone, bone->bone_mat);
-
- /* The bone's root offset (is in the parent's coordinate system) */
- copy_v3_v3(offs_bone[3], bone->head);
-
- /* Get the length translation of parent (length along y axis) */
- offs_bone[3][1]+= parbone->length;
-
- /* Compose the matrix for this bone */
- if((bone->flag & BONE_HINGE) && (bone->flag & BONE_NO_SCALE)) { // uses restposition rotation, but actual position
- float tmat[4][4];
- /* the rotation of the parent restposition */
- copy_m4_m4(tmat, parbone->arm_mat);
- mul_serie_m4(pchan->pose_mat, tmat, offs_bone, pchan->chan_mat, NULL, NULL, NULL, NULL, NULL);
- }
- else if(bone->flag & BONE_HINGE) { // same as above but apply parent scale
- float tmat[4][4];
-
- /* apply the parent matrix scale */
- float tsmat[4][4], tscale[3];
-
- /* the rotation of the parent restposition */
- copy_m4_m4(tmat, parbone->arm_mat);
-
- /* extract the scale of the parent matrix */
- mat4_to_size(tscale, parchan->pose_mat);
- size_to_mat4(tsmat, tscale);
- mult_m4_m4m4(tmat, tsmat, tmat);
-
- mul_serie_m4(pchan->pose_mat, tmat, offs_bone, pchan->chan_mat, NULL, NULL, NULL, NULL, NULL);
- }
- else if(bone->flag & BONE_NO_SCALE) {
- float orthmat[4][4];
-
- /* do transform, with an ortho-parent matrix */
- copy_m4_m4(orthmat, parchan->pose_mat);
- normalize_m4(orthmat);
- mul_serie_m4(pchan->pose_mat, orthmat, offs_bone, pchan->chan_mat, NULL, NULL, NULL, NULL, NULL);
- }
- else
- mul_serie_m4(pchan->pose_mat, parchan->pose_mat, offs_bone, pchan->chan_mat, NULL, NULL, NULL, NULL, NULL);
-
- /* in these cases we need to compute location separately */
- if(bone->flag & (BONE_HINGE|BONE_NO_SCALE|BONE_NO_LOCAL_LOCATION)) {
- float bone_loc[3], chan_loc[3];
-
- mul_v3_m4v3(bone_loc, parchan->pose_mat, offs_bone[3]);
- copy_v3_v3(chan_loc, pchan->chan_mat[3]);
-
- /* no local location is not transformed by bone matrix */
- if(!(bone->flag & BONE_NO_LOCAL_LOCATION))
- mul_mat3_m4_v3(offs_bone, chan_loc);
-
- /* for hinge we use armature instead of pose mat */
- if(bone->flag & BONE_HINGE) mul_mat3_m4_v3(parbone->arm_mat, chan_loc);
- else mul_mat3_m4_v3(parchan->pose_mat, chan_loc);
-
- add_v3_v3v3(pchan->pose_mat[3], bone_loc, chan_loc);
- }
- }
- else {
- mult_m4_m4m4(pchan->pose_mat, bone->arm_mat, pchan->chan_mat);
-
- /* optional location without arm_mat rotation */
- if(bone->flag & BONE_NO_LOCAL_LOCATION)
- add_v3_v3v3(pchan->pose_mat[3], bone->arm_mat[3], pchan->chan_mat[3]);
-
- /* only rootbones get the cyclic offset (unless user doesn't want that) */
- if ((bone->flag & BONE_NO_CYCLICOFFSET) == 0)
+ {
+ float rotscale_mat[4][4], loc_mat[4][4];
+ pchan_to_pose_mat(pchan, rotscale_mat, loc_mat);
+ /* Rotation and scale. */
+ mult_m4_m4m4(pchan->pose_mat, rotscale_mat, pchan->chan_mat);
+ /* Location. */
+ mul_v3_m4v3(pchan->pose_mat[3], loc_mat, pchan->chan_mat[3]);
+ }
+
+ /* Only rootbones get the cyclic offset (unless user doesn't want that). */
+ /* XXX That could be a problem for snapping and other "reverse transform" features... */
+ if(!pchan->parent) {
+ if((pchan->bone->flag & BONE_NO_CYCLICOFFSET) == 0)
add_v3_v3(pchan->pose_mat[3], ob->pose->cyclic_offset);
}
-
+
if(do_extra) {
#if 0 /* XXX OLD ANIMSYS, NLASTRIPS ARE NO LONGER USED */
@@ -2365,6 +2414,7 @@ void where_is_pose_bone(Scene *scene, Object *ob, bPoseChannel *pchan, float cti
/* Do constraints */
if (pchan->constraints.first) {
bConstraintOb *cob;
+ float vec[3];
/* make a copy of location of PoseChannel for later */
copy_v3_v3(vec, pchan->pose_mat[3]);
@@ -2388,7 +2438,7 @@ void where_is_pose_bone(Scene *scene, Object *ob, bPoseChannel *pchan, float cti
}
}
}
-
+
/* calculate head */
copy_v3_v3(pchan->pose_head, pchan->pose_mat[3]);
/* calculate tail */
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index 0c5aed83c1b..c3cbb9dbe5f 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -1611,6 +1611,7 @@ static void ui_block_func_MENUSTR(bContext *UNUSED(C), uiLayout *layout, void *a
MenuEntry *entry;
const char *instr= arg_str;
int columns, rows, a, b;
+ int column_start= 0, column_end= 0;
uiBlockSetFlag(block, UI_BLOCK_MOVEMOUSE_QUIT);
@@ -1654,17 +1655,30 @@ static void ui_block_func_MENUSTR(bContext *UNUSED(C), uiLayout *layout, void *a
/* create items */
split= uiLayoutSplit(layout, 0, 0);
- for(a=0, b=0; a<md->nitems; a++, b++) {
+ for(a=0; a<md->nitems; a++) {
+ if(a == column_end) {
+ /* start new column, and find out where it ends in advance, so we
+ can flip the order of items properly per column */
+ column_start= a;
+ column_end= md->nitems;
+
+ for(b=a+1; b<md->nitems; b++) {
+ entry= &md->items[b];
+
+ /* new column on N rows or on separation label */
+ if(((b-a) % rows == 0) || (entry->sepr && entry->str[0])) {
+ column_end = b;
+ break;
+ }
+ }
+
+ column= uiLayoutColumn(split, 0);
+ }
+
if(block->flag & UI_BLOCK_NO_FLIP)
entry= &md->items[a];
else
- entry= &md->items[md->nitems-a-1];
-
- /* new column on N rows or on separation label */
- if((b % rows == 0) || (entry->sepr && entry->str[0])) {
- column= uiLayoutColumn(split, 0);
- b= 0;
- }
+ entry= &md->items[column_start + column_end-1-a];
if(entry->sepr) {
uiItemL(column, entry->str, entry->icon);
diff --git a/source/blender/editors/mesh/loopcut.c b/source/blender/editors/mesh/loopcut.c
index cfe260541c8..3205a1032f5 100644
--- a/source/blender/editors/mesh/loopcut.c
+++ b/source/blender/editors/mesh/loopcut.c
@@ -46,10 +46,10 @@
#include "PIL_time.h"
+#include "BLI_array.h"
#include "BLI_blenlib.h"
#include "BLI_dynstr.h" /*for WM_operator_pystring */
#include "BLI_editVert.h"
-#include "BLI_array.h"
#include "BLI_utildefines.h"
#include "BKE_blender.h"
@@ -59,7 +59,6 @@
#include "BKE_modifier.h"
#include "BKE_report.h"
#include "BKE_scene.h"
-#include "BKE_array_mallocn.h"
#include "BKE_tessmesh.h"
#include "BKE_depsgraph.h"
@@ -268,8 +267,8 @@ static void edgering_sel(tringselOpData *lcd, int previewlines, int select)
co[1][2] = (v[1][1]->co[2] - v[1][0]->co[2])*(i/((float)previewlines+1))+v[1][0]->co[2];
BLI_array_growone(edges);
- VECCOPY(edges[tot][0], co[0]);
- VECCOPY(edges[tot][1], co[1]);
+ copy_v3_v3(edges[tot][0], co[0]);
+ copy_v3_v3(edges[tot][1], co[1]);
tot++;
}
}
diff --git a/source/blender/editors/space_info/info_ops.c b/source/blender/editors/space_info/info_ops.c
index 2090b4eae0a..87f9a5d65aa 100644
--- a/source/blender/editors/space_info/info_ops.c
+++ b/source/blender/editors/space_info/info_ops.c
@@ -124,7 +124,7 @@ static const EnumPropertyItem unpack_all_method_items[] = {
{PF_USE_ORIGINAL, "USE_ORIGINAL", 0, "Use files in original location (create when necessary)", ""},
{PF_WRITE_ORIGINAL, "WRITE_ORIGINAL", 0, "Write files to original location (overwrite existing files)", ""},
{PF_KEEP, "KEEP", 0, "Disable AutoPack, keep all packed files", ""},
- {PF_ASK, "ASK", 0, "Ask for each file", ""},
+ /* {PF_ASK, "ASK", 0, "Ask for each file", ""}, */
{0, NULL, 0, NULL, NULL}};
static int unpack_all_exec(bContext *C, wmOperator *op)
diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c
index 1ee0c03d5e5..2e8ddbbede4 100644
--- a/source/blender/editors/space_view3d/view3d_snap.c
+++ b/source/blender/editors/space_view3d/view3d_snap.c
@@ -564,7 +564,6 @@ static int snap_sel_to_grid(bContext *C, wmOperator *UNUSED(op))
if(pchan->bone->layer & arm->layer) {
if((pchan->bone->flag & BONE_CONNECTED)==0) {
float nLoc[3];
- float inv_restmat[4][4];
/* get nearest grid point to snap to */
copy_v3_v3(nLoc, pchan->pose_mat[3]);
@@ -576,9 +575,8 @@ static int snap_sel_to_grid(bContext *C, wmOperator *UNUSED(op))
/* Back in object space... */
mul_m4_v3(ob->imat, vec);
- /* get location of grid point in *rest* bone-space */
- invert_m4_m4(inv_restmat, pchan->bone->arm_mat);
- mul_m4_v3(inv_restmat, vec);
+ /* Get location of grid point in pose space. */
+ armature_loc_pose_to_bone(pchan, vec, vec);
/* adjust location */
if ((pchan->protectflag & OB_LOCK_LOCX)==0)
@@ -701,12 +699,9 @@ static int snap_sel_to_curs(bContext *C, wmOperator *UNUSED(op))
if(pchan->bone->flag & BONE_SELECTED) {
if(pchan->bone->layer & arm->layer) {
if((pchan->bone->flag & BONE_CONNECTED)==0) {
- float inv_restmat[4][4];
-
- /* get location of cursor in *rest* bone-space */
- invert_m4_m4(inv_restmat, pchan->bone->arm_mat);
- mul_m4_v3(inv_restmat, vec);
-
+ /* Get position in pchan (pose) space. */
+ armature_loc_pose_to_bone(pchan, vec, vec);
+
/* copy new position */
if ((pchan->protectflag & OB_LOCK_LOCX)==0)
pchan->loc[0]= vec[0];
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index a506c1a902c..8581a43eb41 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -523,7 +523,7 @@ static short apply_targetless_ik(Object *ob)
static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, TransData *td)
{
Bone *bone= pchan->bone;
- float pmat[3][3], omat[3][3], bmat[3][3];
+ float pmat[3][3], omat[3][3];
float cmat[3][3], tmat[3][3];
float vec[3];
@@ -577,39 +577,71 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr
copy_qt_qt(td->ext->iquat, pchan->quat);
}
td->ext->rotOrder= pchan->rotmode;
-
+
/* proper way to get parent transform + own transform + constraints transform */
copy_m3_m4(omat, ob->obmat);
+ /* New code, using "generic" pchan_to_pose_mat(). */
+ {
+ float rotscale_mat[4][4], loc_mat[4][4];
+
+ pchan_to_pose_mat(pchan, rotscale_mat, loc_mat);
+ if (t->mode == TFM_TRANSLATION)
+ copy_m3_m4(pmat, loc_mat);
+ else
+ copy_m3_m4(pmat, rotscale_mat);
+
+ if (constraints_list_needinv(t, &pchan->constraints)) {
+ copy_m3_m4(tmat, pchan->constinv);
+ invert_m3_m3(cmat, tmat);
+ mul_serie_m3(td->mtx, pmat, omat, cmat, NULL,NULL,NULL,NULL,NULL);
+ }
+ else
+ mul_serie_m3(td->mtx, pmat, omat, NULL, NULL,NULL,NULL,NULL,NULL);
+ }
+
+ /* XXX Old code. Will remove it later. */
+#if 0
if (ELEM(t->mode, TFM_TRANSLATION, TFM_RESIZE) && (pchan->bone->flag & BONE_NO_LOCAL_LOCATION))
unit_m3(bmat);
else
copy_m3_m3(bmat, pchan->bone->bone_mat);
if (pchan->parent) {
- if(pchan->bone->flag & BONE_HINGE)
+ if(pchan->bone->flag & BONE_HINGE) {
copy_m3_m4(pmat, pchan->parent->bone->arm_mat);
- else
+ if(!(pchan->bone->flag & BONE_NO_SCALE)) {
+ float tsize[3], tsmat[3][3];
+ mat4_to_size(tsize, pchan->parent->pose_mat);
+ size_to_mat3(tsmat, tsize);
+ mul_m3_m3m3(pmat, tsmat, pmat);
+ }
+ }
+ else {
copy_m3_m4(pmat, pchan->parent->pose_mat);
+ if(pchan->bone->flag & BONE_NO_SCALE)
+ normalize_m3(pmat);
+ }
if (constraints_list_needinv(t, &pchan->constraints)) {
copy_m3_m4(tmat, pchan->constinv);
invert_m3_m3(cmat, tmat);
- mul_serie_m3(td->mtx, bmat, pmat, omat, cmat, NULL,NULL,NULL,NULL); // dang mulserie swaps args
+ mul_serie_m3(td->mtx, bmat, pmat, omat, cmat, NULL,NULL,NULL,NULL);
}
else
- mul_serie_m3(td->mtx, bmat, pmat, omat, NULL,NULL,NULL,NULL,NULL); // dang mulserie swaps args
+ mul_serie_m3(td->mtx, bmat, pmat, omat, NULL,NULL,NULL,NULL,NULL);
}
else {
if (constraints_list_needinv(t, &pchan->constraints)) {
copy_m3_m4(tmat, pchan->constinv);
invert_m3_m3(cmat, tmat);
- mul_serie_m3(td->mtx, bmat, omat, cmat, NULL,NULL,NULL,NULL,NULL); // dang mulserie swaps args
+ mul_serie_m3(td->mtx, bmat, omat, cmat, NULL,NULL,NULL,NULL,NULL);
}
else
- mul_m3_m3m3(td->mtx, omat, bmat); // Mat3MulMat3 has swapped args!
+ mul_m3_m3m3(td->mtx, omat, bmat);
}
+# endif
invert_m3_m3(td->smtx, td->mtx);
@@ -2325,6 +2357,18 @@ void flushTransSeq(TransInfo *t)
seq_prev= seq;
}
+
+ if (ELEM(t->mode, TFM_SEQ_SLIDE, TFM_TIME_TRANSLATE)) { /* originally TFM_TIME_EXTEND, transform changes */
+ /* Special annoying case here, need to calc metas with TFM_TIME_EXTEND only */
+ seq= seqbasep->first;
+
+ while(seq) {
+ if (seq->type == SEQ_META && seq->flag & SELECT)
+ calc_sequence(t->scene, seq);
+ seq= seq->next;
+ }
+ }
+
/* need to do the overlap check in a new loop otherwise adjacent strips
* will not be updated and we'll get false positives */
seq_prev= NULL;
@@ -2344,17 +2388,6 @@ void flushTransSeq(TransInfo *t)
}
seq_prev= seq;
}
-
- if (t->mode == TFM_SEQ_SLIDE) { /* originally TFM_TIME_EXTEND, transform changes */
- /* Special annoying case here, need to calc metas with TFM_TIME_EXTEND only */
- seq= seqbasep->first;
-
- while(seq) {
- if (seq->type == SEQ_META && seq->flag & SELECT)
- calc_sequence(t->scene, seq);
- seq= seq->next;
- }
- }
}
/* ********************* UV ****************** */
diff --git a/source/blender/makesrna/intern/rna_ui.c b/source/blender/makesrna/intern/rna_ui.c
index be0fec41aa1..8e3178a6298 100644
--- a/source/blender/makesrna/intern/rna_ui.c
+++ b/source/blender/makesrna/intern/rna_ui.c
@@ -823,7 +823,7 @@ static void rna_def_menu(BlenderRNA *brna)
"class name is \"OBJECT_MT_hello\", and bl_idname is not set by the "
"script, then bl_idname = \"OBJECT_MT_hello\")");
- prop= RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE);
+ prop= RNA_def_property(srna, "bl_label", PROP_STRING, PROP_TRANSLATE);
RNA_def_property_string_sdna(prop, NULL, "type->label");
RNA_def_property_flag(prop, PROP_REGISTER);
RNA_def_property_ui_text(prop, "Label", "The menu label");
diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c
index 6c961d8e6a8..72c072c13d5 100644
--- a/source/blender/python/intern/bpy_interface.c
+++ b/source/blender/python/intern/bpy_interface.c
@@ -267,9 +267,10 @@ void BPY_python_start(int argc, const char **argv)
pyrna_alloc_types();
+#ifndef WITH_PYTHON_MODULE
+ /* py module runs atexit when bpy is freed */
BPY_atexit_register(); /* this can init any time */
-#ifndef WITH_PYTHON_MODULE
py_tstate = PyGILState_GetThisThreadState();
PyEval_ReleaseThread(py_tstate);
#endif
@@ -288,7 +289,9 @@ void BPY_python_end(void)
bpy_intern_string_exit();
+#ifndef WITH_PYTHON_MODULE
BPY_atexit_unregister(); /* without this we get recursive calls to WM_exit */
+#endif
Py_Finalize();
diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt
index 56612822887..b91080fa56e 100644
--- a/source/creator/CMakeLists.txt
+++ b/source/creator/CMakeLists.txt
@@ -629,10 +629,11 @@ elseif(APPLE)
)
# python
- if(WITH_PYTHON)
+ if(WITH_PYTHON AND NOT WITH_PYTHON_MODULE)
# the python zip is first extract as part of the build process,
# and then later installed as part of make install. this is much
# quicker, and means we can easily exclude files on copy
+ # Not needed for PYTHON_MODULE or WEB_PLUGIN due uses Pyhon framework
add_custom_target(
extractpyzip
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/python)