diff options
112 files changed, 5973 insertions, 9284 deletions
diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h index 2f3af8ca103..5b8c8c1a929 100644 --- a/source/blender/blenkernel/BKE_action.h +++ b/source/blender/blenkernel/BKE_action.h @@ -28,9 +28,7 @@ * 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. + * Contributor(s): Full recode, Ton Roosendaal, Crete 2005 * * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ @@ -55,25 +53,16 @@ struct Object; extern "C" { #endif -/** - * Allocate a new pose channel on the heap and binary copy the - * contents of the src pose channel. - */ -struct bPoseChannel *copy_pose_channel(const struct bPoseChannel *src); - + /** * Removes and deallocates all channels from a pose. * Does not free the pose itself. */ -void clear_pose(struct bPose *pose); - -/* Sets the value of a pose channel */ -struct bPoseChannel *set_pose_channel(struct bPose *pose, - struct bPoseChannel *chan); +void free_pose_channels(struct bPose *pose); /** * Allocate a new pose on the heap, and copy the src pose and it's channels - * into the new pose. *dst is set to the newly allocated structure. + * into the new pose. *dst is set to the newly allocated structure, and assumed to be NULL. */ void copy_pose(struct bPose **dst, struct bPose *src, int copyconstraints); @@ -104,6 +93,9 @@ struct bPoseChannel *get_pose_channel(const struct bPose *pose, struct bPoseChannel *verify_pose_channel(struct bPose* pose, const char* name); +/* sets constraint flags */ +void update_pose_constraint_flags(struct bPose *pose); + /** * Allocate a new bAction on the heap and copy * the contents of src into it. If src is NULL NULL is returned. @@ -119,31 +111,12 @@ float calc_action_start(const struct bAction *act); float calc_action_end(const struct bAction *act); /** - * Evaluate the pose from the given action. - * If the pose does not exist, a new one is created. - * Some deep calls into blender are made here. + * Set the pose channels from the given action. */ -void get_pose_from_action(struct bPose **pose, struct bAction *act, +void extract_pose_from_action(struct bPose *pose, struct bAction *act, float ctime); /** - * I think this duplicates the src into *pose. - * If the pose does not exist, a new one is created. - * If the pose does not contain channels from src - * new channels are created. - */ -void get_pose_from_pose(struct bPose **pose, const struct bPose *src); - -void clear_pose_constraint_status(struct Object *ob); - -/** - * Blends the common subset of channels from dst and src. - * and writes result to dst. - */ -void blend_poses(struct bPose *dst, const struct bPose *src, - float srcweight, short mode); - -/** * Iterate through the action channels of the action * and return the channel with the given name. * Returns NULL if no channel. @@ -151,30 +124,20 @@ void blend_poses(struct bPose *dst, const struct bPose *src, struct bActionChannel *get_named_actionchannel(struct bAction *act, const char *name); +// exported for game engine +void blend_poses(struct bPose *dst, const struct bPose *src, float srcweight, short mode); +void extract_pose_from_pose(struct bPose *pose, const struct bPose *src); + + #ifdef __cplusplus }; #endif +/* nla strip flag */ enum { POSE_BLEND = 0, POSE_ADD }; -enum { - POSE_KEY = 0x10000000, - POSE_LOC = 0x00000001, - POSE_ROT = 0x00000002, - POSE_SIZE = 0x00000004, - POSE_UNUSED1 = 0x00000008, - POSE_UNUSED2 = 0x00000010, - POSE_UNUSED3 = 0x00000020, - POSE_UNUSED4 = 0x00000040, - POSE_UNUSED5 = 0x00000080, - POSE_OBMAT = 0x00000100, - POSE_PARMAT = 0x00000200, - PCHAN_DONE = 0x00000400, - PCHAN_TRANS_UPDATE = 0x00000800 -}; - #endif diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h index 1f9725a4f41..3b924b56c47 100644 --- a/source/blender/blenkernel/BKE_armature.h +++ b/source/blender/blenkernel/BKE_armature.h @@ -38,6 +38,8 @@ struct Bone; struct Main; struct bArmature; struct bPose; +struct bPoseChannel; +struct bConstraint; struct Object; struct MDeformVert; struct Mesh; @@ -46,10 +48,12 @@ struct ListBase; typedef struct PoseChain { - struct PoseChain *next, *prev; - struct Bone *root; - struct Bone *target; + struct PoseChain *next, *prev; // hurms + struct bPoseChannel **pchanchain; + struct bConstraint *con; + struct Bone *root, *target; struct bPose *pose; + int totchannel; float goal[3]; float tolerance; int iterations; @@ -68,42 +72,27 @@ void unlink_armature(struct bArmature *arm); void free_armature(struct bArmature *arm); void make_local_armature(struct bArmature *arm); struct bArmature *copy_armature(struct bArmature *arm); -void apply_pose_armature (struct bArmature* arm, struct bPose* pose, int doit); + void calc_armature_deform (struct Object *ob, float *co, int index); -int verify_boneptr (struct bArmature *arm, struct Bone *tBone); + void init_armature_deform(struct Object *parent, struct Object *ob); struct bArmature* get_armature (struct Object* ob); struct Bone *get_named_bone (struct bArmature *arm, const char *name); -struct Bone *get_indexed_bone (struct bArmature *arm, int index); -void make_displists_by_armature (struct Object *ob); -void calc_bone_deform (struct Bone *bone, float weight, float *vec, float *co, float *contrib); +struct Bone *get_indexed_bone (struct Object *ob, int index); + float dist_to_bone (float vec[3], float b1[3], float b2[3]); -void where_is_armature_time (struct Object *ob, float ctime); -void where_is_armature (struct Object *ob); -void where_is_bone1_time (struct Object *ob, struct Bone *bone, float ctime); - -/* Handy bone matrix functions */ -void bone_to_mat4(struct Bone *bone, float mat[][4]); -void bone_to_mat3(struct Bone *bone, float mat[][3]); -void make_boneMatrixvr (float outmatrix[][4],float delta[3], float roll); -void make_boneMatrix (float outmatrix[][4], struct Bone *bone); -void get_bone_root_pos (struct Bone* bone, float vec[3], int posed); -void get_bone_tip_pos (struct Bone* bone, float vec[3], int posed); -float get_bone_length (struct Bone *bone); +void where_is_armature (struct bArmature *arm); +void where_is_armature_bone(struct Bone *bone, struct Bone *prevbone); +void armature_rebuild_pose(struct Object *ob, struct bArmature *arm); +void where_is_pose (struct Object *ob); + void get_objectspace_bone_matrix (struct Bone* bone, float M_accumulatedMatrix[][4], int root, int posed); -void precalc_bone_irestmat (struct Bone *bone); -void precalc_armature_posemats (struct bArmature *arm); -void precalc_bonelist_irestmats (struct ListBase* bonelist); -void apply_bonemat(struct Bone *bone); +void vec_roll_to_mat3(float *vec, float roll, float mat[][3]); -/* void make_armatureParentMatrices (struct bArmature *arm); */ -void precalc_bone_defmat (struct Bone *bone); -void rebuild_bone_parent_matrix (struct Bone *bone); /* Animation functions */ -void where_is_bone_time (struct Object *ob, struct Bone *bone, float ctime); -void where_is_bone (struct Object *ob, struct Bone *bone); + struct PoseChain *ik_chain_to_posechain (struct Object *ob, struct Bone *bone); void solve_posechain (PoseChain *chain); void free_posechain (PoseChain *chain); diff --git a/source/blender/blenkernel/BKE_constraint.h b/source/blender/blenkernel/BKE_constraint.h index cc2e5498fb4..8fdc63bef60 100644 --- a/source/blender/blenkernel/BKE_constraint.h +++ b/source/blender/blenkernel/BKE_constraint.h @@ -50,9 +50,7 @@ void *copy_constraint_channels (ListBase *dst, ListBase *src); struct bConstraintChannel *clone_constraint_channels (struct ListBase *dst, struct ListBase *src, struct bConstraintChannel *oldact); void relink_constraints (struct ListBase *list); void free_constraint_data (struct bConstraint *con); -void clear_object_constraint_status (struct Object *ob); -void clear_all_constraints(void); -void rebuild_all_armature_displists(void); + void do_constraint_channels (struct ListBase *conbase, struct ListBase *chanbase, float ctime); short get_constraint_target_matrix (struct bConstraint *con, short ownertype, void *ownerdata, float mat[][4], float size[3], float time); struct bConstraintChannel *find_constraint_channel (ListBase *list, const char *name); @@ -61,7 +59,9 @@ void free_constraint_channels (ListBase *chanbase); /* Gemeric functions */ char constraint_has_target (struct bConstraint *con); -struct Object *get_constraint_target(struct bConstraint *con); +struct Object *get_constraint_target(struct bConstraint *con, char **subtarget); +void set_constraint_target(struct bConstraint *con, struct Object *ob); + /* Constraint target/owner types */ #define TARGET_OBJECT 1 // string is "" diff --git a/source/blender/blenkernel/BKE_depsgraph.h b/source/blender/blenkernel/BKE_depsgraph.h index 06eea7a5e98..0c592364d72 100644 --- a/source/blender/blenkernel/BKE_depsgraph.h +++ b/source/blender/blenkernel/BKE_depsgraph.h @@ -40,31 +40,26 @@ struct DagNodeQueue; struct DagForest; struct DagNode; -typedef enum { - DAG_RL_SCENE = 1, - DAG_RL_DATA = 2, - DAG_RL_PARENT = 4, - DAG_RL_TRACK = 8, - DAG_RL_PATH = 16, - DAG_RL_CONSTRAINT = 32, - DAG_RL_HOOK = 64, - DAG_RL_DATA_CONSTRAINT = 128, - DAG_NO_RELATION = 256 -} dag_rel_type; - - -typedef enum { - DAG_RL_SCENE_MASK = 1, - DAG_RL_DATA_MASK = 2, - DAG_RL_PARENT_MASK = 4, - DAG_RL_TRACK_MASK = 8, - DAG_RL_PATH_MASK = 16, - DAG_RL_CONSTRAINT_MASK = 32, - DAG_RL_HOOK_MASK = 64, - DAG_RL_DATA_CONSTRAINT_MASK = 128, - DAG_RL_ALL_BUT_DATA_MASK = 253, - DAG_RL_ALL_MASK = 255 -} dag_rel_type_mask; +/* **** DAG relation types *** */ + + /* scene link to object */ +#define DAG_RL_SCENE 1 + /* object link to data */ +#define DAG_RL_DATA 2 + + /* object changes object (parent, track, constraints) */ +#define DAG_RL_OB_OB 4 + /* object changes obdata (hooks, constraints) */ +#define DAG_RL_OB_DATA 8 + /* data changes object (vertex parent) */ +#define DAG_RL_DATA_OB 16 + /* data changes data (deformers) */ +#define DAG_RL_DATA_DATA 32 + +#define DAG_NO_RELATION 64 +#define DAG_RL_ALL 63 +#define DAG_RL_ALL_BUT_DATA 61 + typedef void (*graph_action_func)(void * ob, void **data); @@ -91,13 +86,19 @@ int pre_and_post_source_DFS(struct DagForest *dag, short mask, struct DagNode *s struct DagNodeQueue *get_obparents(struct DagForest *dag, void *ob); struct DagNodeQueue *get_first_ancestors(struct DagForest *dag, void *ob); struct DagNodeQueue *get_all_childs(struct DagForest *dag, void *ob); // -dag_rel_type are_obs_related(struct DagForest *dag, void *ob1, void *ob2); +short are_obs_related(struct DagForest *dag, void *ob1, void *ob2); int is_acyclic(struct DagForest *dag); // //int get_cycles(struct DagForest *dag, struct DagNodeQueue **queues, int *count); // -void topo_sort_baselist(struct Scene *sce); void boundbox_deps(void); void draw_all_deps(void); +/* ********** API *************** */ + +void DAG_scene_sort(struct Scene *sce); +void DAG_scene_update_flags(struct Scene *sce, unsigned int lay); +void DAG_scene_flush_update(struct Scene *sce); +void DAG_object_flush_update(struct Scene *sce, struct Object *ob, short flag); +void DAG_pose_sort(struct Object *ob); #endif diff --git a/source/blender/blenkernel/BKE_displist.h b/source/blender/blenkernel/BKE_displist.h index ca08b5454a3..0a79d8e8daa 100644 --- a/source/blender/blenkernel/BKE_displist.h +++ b/source/blender/blenkernel/BKE_displist.h @@ -148,7 +148,6 @@ void freefastshade(void); void boundbox_displist(struct Object *ob); void imagestodisplist(void); void reshadeall_displist(void); -void test_all_displists(void); void filldisplist(struct ListBase *dispbase, struct ListBase *to); #endif diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h index 848f82c78b5..211280fae71 100644 --- a/source/blender/blenkernel/BKE_global.h +++ b/source/blender/blenkernel/BKE_global.h @@ -88,7 +88,7 @@ typedef struct Global { char ima[160], sce[160], lib[160]; /* totals */ - short totobj, totlamp, totobjsel, totcurve, totmesh, totmat; + short totobj, totlamp, totobjsel, totcurve, totmesh, totbone, totbonesel; int totvert, totedge, totface, totvertsel, totedgesel, totfacesel; short machine, afbreek, moving, colact, zbuf; diff --git a/source/blender/blenkernel/BKE_ika.h b/source/blender/blenkernel/BKE_ika.h deleted file mode 100644 index 93856c31374..00000000000 --- a/source/blender/blenkernel/BKE_ika.h +++ /dev/null @@ -1,60 +0,0 @@ -/** - * blenlib/BKE_ika.h (mar-2001 nzc) - * - * $Id$ - * - * ***** BEGIN GPL/BL DUAL 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. The Blender - * Foundation also sells licenses for use in proprietary software under - * the Blender License. See http://www.blender.org/BL/ for information - * about this. - * - * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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/BL DUAL LICENSE BLOCK ***** - */ -#ifndef BKE_IKA_H -#define BKE_IKA_H - -struct Ika; -struct Limb; -struct Object; - -void unlink_ika(struct Ika *ika); -void free_ika(struct Ika *ika); -struct Ika *add_ika(void); -struct Ika *copy_ika(struct Ika *ika); -void make_local_ika(struct Ika *ika); -int count_limbs(struct Object *ob); -void calc_limb(struct Limb *li); -void calc_ika(struct Ika *ika, struct Limb *li); -void init_defstate_ika(struct Object *ob); -void itterate_limb(struct Ika *ika, struct Limb *li); -void rotate_ika(struct Object *ob, struct Ika *ika); -void rotate_ika_xy(struct Object *ob, struct Ika *ika); -void itterate_ika(struct Object *ob); -void do_all_ikas(void); -void do_all_visible_ikas(void); -void init_skel_deform(struct Object *par, struct Object *ob); -void calc_skel_deform(struct Ika *ika, float *co); - -#endif - diff --git a/source/blender/blenkernel/BKE_ipo.h b/source/blender/blenkernel/BKE_ipo.h index c25163063cc..e0c7fd787bb 100644 --- a/source/blender/blenkernel/BKE_ipo.h +++ b/source/blender/blenkernel/BKE_ipo.h @@ -82,7 +82,7 @@ void do_mat_ipo(struct Material *ma); void do_ob_ipo(struct Object *ob); void do_seq_ipo(struct Sequence *seq); int has_ipo_code(struct Ipo *ipo, int code); -void do_all_ipos(void); +void do_all_data_ipos(void); int calc_ipo_spec(struct Ipo *ipo, int adrcode, float *ctime); void clear_delta_obipo(struct Ipo *ipo); void add_to_cfra_elem(struct ListBase *lb, struct BezTriple *bezt); diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h index 481c08cee69..b46f02cf81b 100644 --- a/source/blender/blenkernel/BKE_key.h +++ b/source/blender/blenkernel/BKE_key.h @@ -62,9 +62,10 @@ void do_cu_key(struct Curve *cu, struct KeyBlock **k, float *t); void do_rel_cu_key(struct Curve *cu, float ctime); void do_curve_key(struct Curve *cu); void do_latt_key(struct Lattice *lt); -void do_all_keys(void); void do_ob_key(struct Object *ob); void do_spec_key(struct Key *key); - + +void unlock_all_keys(void); + #endif diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h index 058ac3f0a28..9a37f91a023 100644 --- a/source/blender/blenkernel/BKE_main.h +++ b/source/blender/blenkernel/BKE_main.h @@ -59,7 +59,6 @@ typedef struct Main { ListBase mat; ListBase tex; ListBase image; - ListBase ika; ListBase wave; ListBase latt; ListBase lamp; diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index 775b2057551..1fadaa161eb 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -88,13 +88,15 @@ int during_scriptlink(void); void where_is_object_time(struct Object *ob, float ctime); void where_is_object(struct Object *ob); void where_is_object_simul(struct Object *ob); -void what_does_parent1(struct Object *par, int partype, int par1, int par2, int par3); + void what_does_parent(struct Object *ob); struct BoundBox *unit_boundbox(void); void minmax_object(struct Object *ob, float *min, float *max); void solve_tracking (struct Object *ob, float targetmat[][4]); void solve_constraints (struct Object *ob, short obtype, void *obdata, float ctime); +void object_handle_update(struct Object *ob); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index 538912a1f40..1313ad251e7 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -57,12 +57,14 @@ struct QuicktimeCodecData; void free_avicodecdata(struct AviCodecData *acd); void free_qtcodecdata(struct QuicktimeCodecData *acd); + void free_scene(struct Scene *me); struct Scene *add_scene(char *name); int object_in_scene(struct Object *ob, struct Scene *sce); -void sort_baselist(struct Scene *sce); + void set_scene_bg(struct Scene *sce); void set_scene_name(char *name); + int next_object(int val, struct Base **base, struct Object **ob); struct Object *scene_find_camera(struct Scene *sc); @@ -70,5 +72,7 @@ struct Base *scene_add_base(struct Scene *sce, struct Object *ob); void scene_deselect_all(struct Scene *sce); void scene_select_base(struct Scene *sce, struct Base *selbase); +void scene_update_for_newframe(struct Scene *sce, unsigned int lay); + #endif diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript index 0b6bf520bc4..a30c6488e05 100644 --- a/source/blender/blenkernel/SConscript +++ b/source/blender/blenkernel/SConscript @@ -12,7 +12,6 @@ source_files = ['intern/constraint.c', 'intern/sca.c', 'intern/world.c', 'intern/curve.c', - 'intern/ika.c', 'intern/mball.c', 'intern/scene.c', 'intern/writeavi.c', diff --git a/source/blender/blenkernel/depsgraph_private.h b/source/blender/blenkernel/depsgraph_private.h index d6d74f75bb6..6b29de2d5b4 100644 --- a/source/blender/blenkernel/depsgraph_private.h +++ b/source/blender/blenkernel/depsgraph_private.h @@ -51,8 +51,9 @@ enum { typedef struct DagAdjList { struct DagNode *node; - dag_rel_type type; - int count; // number of identical arcs + short type; + int count; // number of identical arcs + unsigned int lay; // for flushing redraw/rebuild events struct DagAdjList *next; } DagAdjList; @@ -64,7 +65,9 @@ typedef struct DagNode float x, y, k; void * ob; void * first_ancestor; - int ancestor_count; + int ancestor_count; + int lay; // accumulated layers of its relations + itself + int lasttime; // if lasttime != DagForest->time, this node was not evaluated yet for flushing int BFS_dist; // BFS distance int DFS_dist; // DFS distance int DFS_dvtm; // DFS discovery time @@ -93,6 +96,7 @@ typedef struct DagForest ListBase DagNode; int numNodes; int is_acyclic; + int time; // for flushing/tagging, compare with node->lasttime } DagForest; @@ -112,7 +116,7 @@ DagNode * dag_find_node (DagForest *forest,void * fob); DagNode * dag_add_node (DagForest *forest,void * fob); DagNode * dag_get_node (DagForest *forest,void * fob); DagNode * dag_get_sub_node (DagForest *forest,void * fob); -void dag_add_relation(DagForest *forest, DagNode *fob1, DagNode *fob2, dag_rel_type rel); +void dag_add_relation(DagForest *forest, DagNode *fob1, DagNode *fob2, short rel); void graph_bfs(void); diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 4b1f47707af..911df2a5998 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -23,9 +23,7 @@ * 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. + * Contributor(s): Full recode, Ton Roosendaal, Crete 2005 * * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ @@ -39,50 +37,141 @@ #include <stdlib.h> /* for NULL */ #include "MEM_guardedalloc.h" -#include "BLI_arithb.h" -#include "BLI_blenlib.h" -#include "BKE_action.h" -#include "BKE_global.h" -#include "BKE_main.h" -#include "BKE_utildefines.h" - -#include "DNA_object_types.h" -#include "DNA_ipo_types.h" -#include "DNA_curve_types.h" -#include "DNA_scene_types.h" #include "DNA_action_types.h" +#include "DNA_armature_types.h" +#include "DNA_constraint_types.h" +#include "DNA_curve_types.h" +#include "DNA_ipo_types.h" #include "DNA_nla_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "BKE_action.h" +#include "BKE_anim.h" +#include "BKE_armature.h" #include "BKE_blender.h" +#include "BKE_constraint.h" +#include "BKE_global.h" #include "BKE_ipo.h" -#include "BKE_object.h" #include "BKE_library.h" -#include "BKE_anim.h" -#include "BKE_armature.h" +#include "BKE_main.h" +#include "BKE_object.h" +#include "BKE_utildefines.h" + +#include "BLI_arithb.h" +#include "BLI_blenlib.h" #include "nla.h" -#include "BKE_constraint.h" -#include "DNA_constraint_types.h" +/* *********************** NOTE ON POSE AND ACTION ********************** -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif + - Pose is the local (object level) component of armature. The current + object pose is saved in files, and (will be) is presorted for dependency + - Actions have fewer (or other) channels, and write data to a Pose + - Currently ob->pose data is controlled in where_is_pose only. The (recalc) + event system takes care of calling that + - The NLA system (here too) uses Poses as interpolation format for Actions + - Therefore we assume poses to be static, and duplicates of poses have channels in + same order, for quick interpolation reasons + + ****************************** (ton) ************************************ */ + +/* ***************** Library data level operations on action ************** */ + +void make_local_action(bAction *act) +{ + Object *ob; + bAction *actn; + int local=0, lib=0; + + if(act->id.lib==0) return; + if(act->id.us==1) { + act->id.lib= 0; + act->id.flag= LIB_LOCAL; + new_id(0, (ID *)act, 0); + return; + } + + ob= G.main->object.first; + while(ob) { + if(ob->action==act) { + if(ob->id.lib) lib= 1; + else local= 1; + } + ob= ob->id.next; + } + + if(local && lib==0) { + act->id.lib= 0; + act->id.flag= LIB_LOCAL; + new_id(0, (ID *)act, 0); + } + else if(local && lib) { + actn= copy_action(act); + actn->id.us= 0; + + ob= G.main->object.first; + while(ob) { + if(ob->action==act) { + + if(ob->id.lib==0) { + ob->action = actn; + ob->activecon = NULL; + actn->id.us++; + act->id.us--; + } + } + ob= ob->id.next; + } + } +} -/* Local function prototypes */ -static void do_pose_constraint_channels(bPose *pose, bAction *act, - float ctime); +void free_action(bAction *act) +{ + bActionChannel *chan; + + /* Free channels */ + for (chan=act->chanbase.first; chan; chan=chan->next){ + if (chan->ipo) + chan->ipo->id.us--; + free_constraint_channels(&chan->constraintChannels); + } + + if (act->chanbase.first) + BLI_freelistN (&act->chanbase); +} + +bAction* copy_action(bAction *src) +{ + bAction *dst = NULL; + bActionChannel *dchan, *schan; + + if(!src) return NULL; + + dst= copy_libblock(src); + duplicatelist(&(dst->chanbase), &(src->chanbase)); + + for (dchan=dst->chanbase.first, schan=src->chanbase.first; dchan; dchan=dchan->next, schan=schan->next){ + dchan->ipo = copy_ipo(dchan->ipo); + copy_constraint_channels(&dchan->constraintChannels, &schan->constraintChannels); + } + dst->id.flag |= LIB_FAKEUSER; + dst->id.us++; + return dst; +} + -static void rest_pose(bPose *pose, int clearflag); -/* Implementation */ +/* ************************ Pose channels *************** */ bPoseChannel *get_pose_channel(const bPose *pose, const char *name) { bPoseChannel *chan; + if(pose==NULL) return NULL; + for (chan=pose->chanbase.first; chan; chan=chan->next){ if (!strcmp (chan->name, name)) return chan; @@ -91,70 +180,132 @@ bPoseChannel *get_pose_channel(const bPose *pose, const char *name) return NULL; } -static void rest_pose(bPose *pose, int clearflag) +/* Use with care, not on Armature poses but for temporal ones */ +/* (currently used for action constraints and in rebuild_pose) */ +bPoseChannel *verify_pose_channel(bPose* pose, const char* name) { bPoseChannel *chan; - int i; + + if (!pose){ + return NULL; + } + + /* See if this channel exists */ + for (chan=pose->chanbase.first; chan; chan=chan->next){ + if (!strcmp (name, chan->name)) + return chan; + } + + /* If not, create it and add it */ + chan = MEM_callocN(sizeof(bPoseChannel), "verifyPoseChannel"); + + strcpy (chan->name, name); + /* init vars to prevent mat errors */ + chan->quat[0] = 1.0F; + chan->size[0] = chan->size[1] = chan->size[2] = 1.0F; + Mat3One(chan->ik_mat); + + BLI_addtail (&pose->chanbase, chan); + + return chan; +} - if (!pose) + +/* dst should be freed already, makes entire duplicate */ +void copy_pose(bPose **dst, bPose *src, int copycon) +{ + bPose *outPose; + bPoseChannel *pchan; + ListBase listb; + + if (!src){ + *dst=NULL; return; + } + + outPose= MEM_callocN(sizeof(bPose), "pose"); + + duplicatelist (&outPose->chanbase, &src->chanbase); + + if (copycon) { + for (pchan=outPose->chanbase.first; pchan; pchan=pchan->next) { + copy_constraints(&listb, &pchan->constraints); // copy_constraints NULLs listb + pchan->constraints= listb; + } + } + + *dst=outPose; +} - for (chan=pose->chanbase.first; chan; chan=chan->next){ - for (i=0; i<3; i++){ - chan->loc[i]=0.0; - chan->quat[i+1]=0.0; - chan->size[i]=1.0; +void free_pose_channels(bPose *pose) +{ + bPoseChannel *chan; + + if (pose->chanbase.first){ + for (chan = pose->chanbase.first; chan; chan=chan->next){ + free_constraints(&chan->constraints); } - chan->quat[0]=1.0; - if (clearflag) - chan->flag =0; + BLI_freelistN (&pose->chanbase); } } -#ifdef __NLA_BLENDCON -static void blend_constraints(ListBase *dst, const ListBase *src, - float srcweight, short mode) +static void copy_pose_channel_data(bPoseChannel *pchan, const bPoseChannel *chan) { - bConstraint *dcon; - const bConstraint *scon; - float dstweight = 0; + VECCOPY(pchan->loc, chan->loc); + VECCOPY(pchan->size, chan->size); + QUATCOPY(pchan->quat, chan->quat); + pchan->flag= chan->flag; +} - switch (mode){ - case POSE_BLEND: - dstweight = 1.0F - srcweight; - break; - case POSE_ADD: - dstweight = 1.0F; - break; +/* checks for IK constraint, can do more constraints flags later */ +/* pose should be entirely OK */ +void update_pose_constraint_flags(bPose *pose) +{ + bPoseChannel *pchan; + bConstraint *con; + + /* clear */ + for (pchan = pose->chanbase.first; pchan; pchan=pchan->next) { + pchan->constflag= 0; } - - /* Blend constraints */ - for (dcon=dst->first; dcon; dcon=dcon->next){ - for (scon = src->first; scon; scon=scon->next){ - if (!strcmp(scon->name, dcon->name)) - break; + /* detect */ + for (pchan = pose->chanbase.first; pchan; pchan=pchan->next) { + for(con= pchan->constraints.first; con; con= con->next) { + if(con->type==CONSTRAINT_TYPE_KINEMATIC) { + pchan->constflag |= PCHAN_HAS_IK; + } + else pchan->constflag |= PCHAN_HAS_CONST; } - - if (scon){ - dcon->enforce = (dcon->enforce*dstweight) + (scon->enforce*srcweight); - if (mode == POSE_BLEND) - dcon->enforce/=2.0; - - if (dcon->enforce>1.0) - dcon->enforce=1.0; - if (dcon->enforce<0.0) - dcon->enforce=0.0; + } +} - } + +/* ************************ END Pose channels *************** */ + +bActionChannel *get_named_actionchannel(bAction *act, const char *name) +{ + bActionChannel *chan; + + if (!act) + return NULL; + + for (chan = act->chanbase.first; chan; chan=chan->next){ + if (!strcmp (chan->name, name)) + return chan; } + + return NULL; } -#endif +/* ************************ Blending with NLA *************** */ + + +/* Only allowed for Poses with identical channels */ void blend_poses(bPose *dst, const bPose *src, float srcweight, short mode) { bPoseChannel *dchan; const bPoseChannel *schan; - float dquat[4], squat[4]; //, mat[3][3]; + float dquat[4], squat[4]; float dstweight; int i; @@ -169,67 +320,35 @@ void blend_poses(bPose *dst, const bPose *src, float srcweight, short mode) dstweight = 1.0F; } - for (dchan = dst->chanbase.first; dchan; dchan=dchan->next){ - schan = get_pose_channel(src, dchan->name); - if (schan){ - if (schan->flag & (POSE_ROT|POSE_LOC|POSE_SIZE)){ - - /* Convert both quats to matrices and then back again. - * This prevents interpolation problems - * This sucks because it is slow and stupid - */ - - //QuatToMat3(dchan->quat, mat); - //Mat3ToQuat(mat, dquat); - //QuatToMat3(schan->quat, mat); - //Mat3ToQuat(mat, squat); + schan= src->chanbase.first; + for (dchan = dst->chanbase.first; dchan; dchan=dchan->next, schan= schan->next){ + if (schan->flag & (POSE_ROT|POSE_LOC|POSE_SIZE)) { + + /* replaced quat->matrix->quat conversion with decent quaternion interpol (ton) */ + + /* Do the transformation blend */ + if (schan->flag & POSE_ROT) { + QUATCOPY(dquat, dchan->quat); + QUATCOPY(squat, schan->quat); + if(mode==POSE_BLEND) + QuatInterpol(dchan->quat, dquat, squat, srcweight); + else + QuatAdd(dchan->quat, dquat, squat, srcweight); - /* replaced quat->matrix->quat conversion with decent quaternion interpol (ton) */ - /* Do the transformation blend */ - if (schan->flag & POSE_ROT) { - QUATCOPY(dquat, dchan->quat); - QUATCOPY(squat, schan->quat); - if(mode==POSE_BLEND) - QuatInterpol(dchan->quat, dquat, squat, srcweight); - else - QuatAdd(dchan->quat, dquat, squat, srcweight); - NormalQuat (dchan->quat); - } + NormalQuat (dchan->quat); + } - for (i=0; i<3; i++){ - if (schan->flag & POSE_LOC) - dchan->loc[i] = (dchan->loc[i]*dstweight) + (schan->loc[i]*srcweight); - if (schan->flag & POSE_SIZE) - dchan->size[i] = 1.0f + ((dchan->size[i]-1.0f)*dstweight) + ((schan->size[i]-1.0f)*srcweight); - //if (schan->flag & POSE_ROT) - // dchan->quat[i+1] = (dquat[i+1]*dstweight) + (squat[i+1]*srcweight); - } - - /* Do one more iteration for the quaternions only and normalize the quaternion if needed */ - //if (schan->flag & POSE_ROT) - // dchan->quat[0] = 1.0f + ((dquat[0]-1.0f)*dstweight) + ((squat[0]-1.0f)*srcweight); - //if (mode==POSE_BLEND) - // NormalQuat (dchan->quat); - - dchan->flag |= schan->flag; + for (i=0; i<3; i++){ + if (schan->flag & POSE_LOC) + dchan->loc[i] = (dchan->loc[i]*dstweight) + (schan->loc[i]*srcweight); + if (schan->flag & POSE_SIZE) + dchan->size[i] = 1.0f + ((dchan->size[i]-1.0f)*dstweight) + ((schan->size[i]-1.0f)*srcweight); } + dchan->flag |= schan->flag; } } } -void clear_pose_constraint_status(Object *ob) -{ - bPoseChannel *chan; - - if (!ob) - return; - if (!ob->pose) - return; - - for (chan = ob->pose->chanbase.first; chan; chan=chan->next){ - chan->flag &= ~PCHAN_DONE; - } -} float calc_action_start(const bAction *act) { @@ -291,59 +410,60 @@ float calc_action_end(const bAction *act) return size; } -bPoseChannel *verify_pose_channel(bPose* pose, const char* name) +/* Copy the data from the action-pose (src) into the pose */ +/* both args are assumed to be valid */ +/* exported to game engine */ +void extract_pose_from_pose(bPose *pose, const bPose *src) { - bPoseChannel *chan; - - if (!pose){ - return NULL; - } + const bPoseChannel *schan; + bPoseChannel *pchan= pose->chanbase.first; - /* See if this channel exists */ - for (chan=pose->chanbase.first; chan; chan=chan->next){ - if (!strcmp (name, chan->name)) - return chan; + for (schan=src->chanbase.first; schan; schan=schan->next, pchan= pchan->next) { + copy_pose_channel_data(pchan, schan); } - - /* If not, create it and add it */ - chan = MEM_callocN(sizeof(bPoseChannel), "verifyPoseChannel"); - - strcpy (chan->name, name); - chan->loc[0] = chan->loc[1] = chan->loc[2] = 0.0F; - chan->quat[1] = chan->quat[2] = chan->quat[3] = 0.0F; - chan->quat[0] = 1.0F; - chan->size[0] = chan->size[1] = chan->size[2] = 1.0F; - - chan->flag |= POSE_ROT|POSE_SIZE|POSE_LOC; - - BLI_addtail (&pose->chanbase, chan); - - return chan; } -void get_pose_from_pose(bPose **pose, const bPose *src) +/* seems to be disabled... (ton) */ +#ifdef __NLA_BLENDCON +static void blend_constraints(ListBase *dst, const ListBase *src, + float srcweight, short mode) { - const bPoseChannel *pchan; - bPoseChannel *newchan; - - if (!src) - return; - if (!pose) - return; - - /* If there is no pose, create one */ - if (!*pose){ - *pose=MEM_callocN (sizeof(bPose), "pose"); + bConstraint *dcon; + const bConstraint *scon; + float dstweight = 0; + + switch (mode){ + case POSE_BLEND: + dstweight = 1.0F - srcweight; + break; + case POSE_ADD: + dstweight = 1.0F; + break; } - - /* Copy the data from the action into the pose */ - for (pchan=src->chanbase.first; pchan; pchan=pchan->next){ - newchan = copy_pose_channel(pchan); - verify_pose_channel(*pose, pchan->name); - set_pose_channel(*pose, newchan); + + /* Blend constraints */ + for (dcon=dst->first; dcon; dcon=dcon->next){ + for (scon = src->first; scon; scon=scon->next){ + if (!strcmp(scon->name, dcon->name)) + break; + } + + if (scon){ + dcon->enforce = (dcon->enforce*dstweight) + (scon->enforce*srcweight); + if (mode == POSE_BLEND) + dcon->enforce/=2.0; + + if (dcon->enforce>1.0) + dcon->enforce=1.0; + if (dcon->enforce<0.0) + dcon->enforce=0.0; + + } } } +#endif +/* seems to be disabled... (ton) */ #ifdef __NLA_BLENDCON static void get_constraint_influence_from_pose(bPose *dst, bPose *src) { @@ -364,72 +484,76 @@ static void get_constraint_influence_from_pose(bPose *dst, bPose *src) } #endif -/* If the pose does not exist, a new one is created */ - -void get_pose_from_action(bPose **pose, bAction *act, float ctime) +/* Pose should exist, can have any number of channels too (used for constraint) */ +void extract_pose_from_action(bPose *pose, bAction *act, float ctime) { bActionChannel *achan; bPoseChannel *pchan; Ipo *ipo; - IpoCurve *curve; - if (!act) return; if (!pose) return; - /* If there is no pose, create one */ - if (!*pose){ - *pose=MEM_callocN (sizeof(bPose), "pose"); - } - /* Copy the data from the action into the pose */ for (achan=act->chanbase.first; achan; achan=achan->next){ - act->achan= achan; + act->achan= achan; // for ipos ipo = achan->ipo; - if (ipo){ - pchan=MEM_callocN (sizeof(bPoseChannel), "gpfa_poseChannel"); - strcpy (pchan->name, achan->name); - - act->pchan=pchan; - /* Evaluates and sets the internal ipo value */ - calc_ipo(ipo, ctime); - - /* Set the pchan flags */ - for (curve = achan->ipo->curve.first; curve; curve=curve->next){ - /* Skip empty curves */ - if (!curve->totvert) - continue; - - switch (curve->adrcode){ - case AC_QUAT_X: - case AC_QUAT_Y: - case AC_QUAT_Z: - case AC_QUAT_W: - pchan->flag |= POSE_ROT; - break; - case AC_LOC_X: - case AC_LOC_Y: - case AC_LOC_Z: - pchan->flag |= POSE_LOC; - break; - case AC_SIZE_X: - case AC_SIZE_Y: - case AC_SIZE_Z: - pchan->flag |= POSE_SIZE; - break; - } + if (ipo) { + pchan= get_pose_channel(pose, achan->name); + if(pchan) { + act->pchan= pchan; // for ipos + + /* Evaluates and sets the internal ipo value */ + calc_ipo(ipo, ctime); + + /* This call also sets the pchan flags */ + execute_ipo((ID*)act, achan->ipo); } + } + } +} - execute_ipo((ID*)act, achan->ipo); - - set_pose_channel(*pose, pchan); +/* for do_all_actions, clears the pose */ +static void rest_pose(bPose *pose, int clearflag) +{ + bPoseChannel *chan; + int i; + + if (!pose) + return; + + for (chan=pose->chanbase.first; chan; chan=chan->next){ + for (i=0; i<3; i++){ + chan->loc[i]=0.0; + chan->quat[i+1]=0.0; + chan->size[i]=1.0; } + chan->quat[0]=1.0; + if (clearflag) + chan->flag =0; + } +} + +/* do constraint channels = execute the ipos */ +static void do_pose_constraint_channels(bPose *pose, bAction *act, float ctime) +{ + bPoseChannel *pchan; + bActionChannel *achan; + + if (!pose || !act) + return; + + for (pchan=pose->chanbase.first; pchan; pchan=pchan->next){ + achan=get_named_actionchannel(act, pchan->name); + if (achan) + do_constraint_channels(&pchan->constraints, &achan->constraintChannels, ctime); } } + void do_all_actions(Object *only_this) { Base *base; @@ -440,9 +564,11 @@ void do_all_actions(Object *only_this) int doit; float striptime, frametime, length, actlength; float blendfac, stripframe; - int set; + //printf("do all actions disabled\n"); + //return; + /* NEW: current scene ob ipo's */ base= G.scene->base.first; set= 0; @@ -453,150 +579,154 @@ void do_all_actions(Object *only_this) else ob = base->object; /* Retrieve data from the NLA */ - if(ob->type==OB_ARMATURE){ + if(ob->type==OB_ARMATURE && ob->pose) { + bArmature *arm= ob->data; - doit=0; - - /* Clear pose */ - if (apose){ - clear_pose(apose); - MEM_freeN(apose); - } - /* Clear pose */ - if (tpose){ - clear_pose(tpose); - MEM_freeN(tpose); + if(arm->flag & ARM_NO_ACTION) { // no action set while transform + ; } + else { + doit=0; - copy_pose(&apose, ob->pose, 1); - copy_pose(&tpose, ob->pose, 1); - rest_pose(apose, 1); - - if (ob->nlastrips.first){ - rest_pose(ob->pose, 0); - } + /* Clear pose */ + if (apose){ + free_pose_channels(apose); + MEM_freeN(apose); + } + /* Clear pose */ + if (tpose){ + free_pose_channels(tpose); + MEM_freeN(tpose); + } - for (strip=ob->nlastrips.first; strip; strip=strip->next){ - doit = 0; - if (strip->act){ - - /* Determine if the current frame is within the strip's range */ - length = strip->end-strip->start; - actlength = strip->actend-strip->actstart; - striptime = (G.scene->r.cfra-(strip->start)) / length; - stripframe = (G.scene->r.cfra-(strip->start)) ; - - - if (striptime>=0.0){ - - rest_pose(tpose, 1); - - /* Handle path */ - if (strip->flag & ACTSTRIP_USESTRIDE){ - if (ob->parent && ob->parent->type==OB_CURVE){ - Curve *cu = ob->parent->data; - float ctime, pdist; - - if (cu->flag & CU_PATH){ - /* Ensure we have a valid path */ - if(cu->path==0 || cu->path->data==0) calc_curvepath(ob->parent); - - /* Find the position on the path */ - ctime= bsystem_time(ob, ob->parent, (float)G.scene->r.cfra, 0.0); - - if(calc_ipo_spec(cu->ipo, CU_SPEED, &ctime)==0) { - ctime /= cu->pathlen; - CLAMP(ctime, 0.0, 1.0); + copy_pose(&apose, ob->pose, 1); + copy_pose(&tpose, ob->pose, 1); + rest_pose(apose, 1); + + if (ob->nlastrips.first){ + rest_pose(ob->pose, 0); + } + + for (strip=ob->nlastrips.first; strip; strip=strip->next){ + doit = 0; + if (strip->act){ + + /* Determine if the current frame is within the strip's range */ + length = strip->end-strip->start; + actlength = strip->actend-strip->actstart; + striptime = (G.scene->r.cfra-(strip->start)) / length; + stripframe = (G.scene->r.cfra-(strip->start)) ; + + + if (striptime>=0.0){ + + rest_pose(tpose, 1); + + /* Handle path */ + if (strip->flag & ACTSTRIP_USESTRIDE){ + if (ob->parent && ob->parent->type==OB_CURVE){ + Curve *cu = ob->parent->data; + float ctime, pdist; + + if (cu->flag & CU_PATH){ + /* Ensure we have a valid path */ + if(cu->path==NULL || cu->path->data==NULL) printf("action path error\n"); + else { + + /* Find the position on the path */ + ctime= bsystem_time(ob, ob->parent, (float)G.scene->r.cfra, 0.0); + + if(calc_ipo_spec(cu->ipo, CU_SPEED, &ctime)==0) { + ctime /= cu->pathlen; + CLAMP(ctime, 0.0, 1.0); + } + pdist = ctime*cu->path->totdist; + + if (strip->stridelen) + striptime = pdist / strip->stridelen; + else + striptime = 0; + + striptime = (float)fmod (striptime, 1.0); + + frametime = (striptime * actlength) + strip->actstart; + extract_pose_from_action (tpose, strip->act, bsystem_time(ob, 0, frametime, 0.0)); + #ifdef __NLA_BLENDCON + do_pose_constraint_channels(tpose, strip->act, bsystem_time(ob, 0, frametime, 0.0)); + #endif + doit=1; + } } - pdist = ctime*cu->path->totdist; - - if (strip->stridelen) - striptime = pdist / strip->stridelen; - else - striptime = 0; - - striptime = (float)fmod (striptime, 1.0); - - frametime = (striptime * actlength) + strip->actstart; - get_pose_from_action (&tpose, strip->act, bsystem_time(ob, 0, frametime, 0.0)); -#ifdef __NLA_BLENDCON - do_pose_constraint_channels(tpose, strip->act, bsystem_time(ob, 0, frametime, 0.0)); -#endif - doit=1; } } - } - /* Handle repeat */ - - else if (striptime < 1.0){ - /* Mod to repeat */ - striptime*=strip->repeat; - striptime = (float)fmod (striptime, 1.0); - - frametime = (striptime * actlength) + strip->actstart; - get_pose_from_action (&tpose, strip->act, bsystem_time(ob, 0, frametime, 0.0)); -#ifdef __NLA_BLENDCON - do_pose_constraint_channels(tpose, strip->act, bsystem_time(ob, 0, frametime, 0.0)); -#endif - doit=1; - } - /* Handle extend */ - else{ - if (strip->flag & ACTSTRIP_HOLDLASTFRAME){ - striptime = 1.0; + /* Handle repeat */ + + else if (striptime < 1.0){ + /* Mod to repeat */ + striptime*=strip->repeat; + striptime = (float)fmod (striptime, 1.0); + frametime = (striptime * actlength) + strip->actstart; - get_pose_from_action (&tpose, strip->act, bsystem_time(ob, 0, frametime, 0.0)); -#ifdef __NLA_BLENDCON + extract_pose_from_action (tpose, strip->act, bsystem_time(ob, 0, frametime, 0.0)); + #ifdef __NLA_BLENDCON do_pose_constraint_channels(tpose, strip->act, bsystem_time(ob, 0, frametime, 0.0)); -#endif + #endif doit=1; } - } + /* Handle extend */ + else{ + if (strip->flag & ACTSTRIP_HOLDLASTFRAME){ + striptime = 1.0; + frametime = (striptime * actlength) + strip->actstart; + extract_pose_from_action (tpose, strip->act, bsystem_time(ob, 0, frametime, 0.0)); + #ifdef __NLA_BLENDCON + do_pose_constraint_channels(tpose, strip->act, bsystem_time(ob, 0, frametime, 0.0)); + #endif + doit=1; + } + } - /* Handle blendin & blendout */ - if (doit){ - /* Handle blendin */ + /* Handle blendin & blendout */ + if (doit){ + /* Handle blendin */ - if (strip->blendin>0.0 && stripframe<=strip->blendin && G.scene->r.cfra>=strip->start){ - blendfac = stripframe/strip->blendin; - } - else if (strip->blendout>0.0 && stripframe>=(length-strip->blendout) && G.scene->r.cfra<=strip->end){ - blendfac = (length-stripframe)/(strip->blendout); + if (strip->blendin>0.0 && stripframe<=strip->blendin && G.scene->r.cfra>=strip->start){ + blendfac = stripframe/strip->blendin; + } + else if (strip->blendout>0.0 && stripframe>=(length-strip->blendout) && G.scene->r.cfra<=strip->end){ + blendfac = (length-stripframe)/(strip->blendout); + } + else + blendfac = 1; + + /* Blend this pose with the accumulated pose */ + blend_poses (apose, tpose, blendfac, strip->mode); + #ifdef __NLA_BLENDCON + blend_constraints(&apose->chanbase, &tpose->chanbase, blendfac, strip->mode); + #endif } - else - blendfac = 1; - - /* Blend this pose with the accumulated pose */ - blend_poses (apose, tpose, blendfac, strip->mode); -#ifdef __NLA_BLENDCON - blend_constraints(&apose->chanbase, &tpose->chanbase, blendfac, strip->mode); -#endif + } + if (apose){ + extract_pose_from_pose(ob->pose, apose); + #ifdef __NLA_BLENDCON + get_constraint_influence_from_pose(ob->pose, apose); + #endif } - } - if (apose){ - get_pose_from_pose(&ob->pose, apose); -#ifdef __NLA_BLENDCON - get_constraint_influence_from_pose(ob->pose, apose); -#endif } + } + + /* Do local action (always overrides the nla actions) */ + /* At the moment, only constraint ipos on the local action have any effect */ + if(ob->action) { + extract_pose_from_action (ob->pose, ob->action, bsystem_time(ob, 0, (float) G.scene->r.cfra, 0.0)); + do_pose_constraint_channels(ob->pose, ob->action, bsystem_time(ob, 0, (float) G.scene->r.cfra, 0.0)); + doit = 1; + } } - - /* Do local action (always overrides the nla actions) */ - /* At the moment, only constraint ipos on the local action have any effect */ - if(ob->action) { - get_pose_from_action (&ob->pose, ob->action, bsystem_time(ob, 0, (float) G.scene->r.cfra, 0.0)); - do_pose_constraint_channels(ob->pose, ob->action, bsystem_time(ob, 0, (float) G.scene->r.cfra, 0.0)); - doit = 1; - } - - if (doit) - apply_pose_armature(get_armature(ob), ob->pose, 1); - - } - + } if(only_this) break; base= base->next; @@ -608,222 +738,15 @@ void do_all_actions(Object *only_this) } if (apose){ - clear_pose(apose); + free_pose_channels(apose); MEM_freeN(apose); apose = NULL; } if (tpose){ - clear_pose(tpose); + free_pose_channels(tpose); MEM_freeN(tpose); apose = NULL; } } -static void do_pose_constraint_channels(bPose *pose, bAction *act, float ctime) -{ - bPoseChannel *pchan; - bActionChannel *achan; - - if (!pose || !act) - return; - - for (pchan=pose->chanbase.first; pchan; pchan=pchan->next){ - achan=get_named_actionchannel(act, pchan->name); - if (achan) - do_constraint_channels(&pchan->constraints, &achan->constraintChannels, ctime); - } -} - -bActionChannel *get_named_actionchannel(bAction *act, const char *name) -{ - bActionChannel *chan; - - if (!act) - return NULL; - - for (chan = act->chanbase.first; chan; chan=chan->next){ - if (!strcmp (chan->name, name)) - return chan; - } - - return NULL; -} - -void clear_pose(bPose *pose) -{ - bPoseChannel *chan; - - if (pose->chanbase.first){ - for (chan = pose->chanbase.first; chan; chan=chan->next){ - free_constraints(&chan->constraints); - } - BLI_freelistN (&pose->chanbase); - } -} - -void make_local_action(bAction *act) -{ - Object *ob; - bAction *actn; - int local=0, lib=0; - - if(act->id.lib==0) return; - if(act->id.us==1) { - act->id.lib= 0; - act->id.flag= LIB_LOCAL; - new_id(0, (ID *)act, 0); - return; - } - - ob= G.main->object.first; - while(ob) { - if(ob->action==act) { - if(ob->id.lib) lib= 1; - else local= 1; - } - ob= ob->id.next; - } - - if(local && lib==0) { - act->id.lib= 0; - act->id.flag= LIB_LOCAL; - new_id(0, (ID *)act, 0); - } - else if(local && lib) { - actn= copy_action(act); - actn->id.us= 0; - - ob= G.main->object.first; - while(ob) { - if(ob->action==act) { - - if(ob->id.lib==0) { - ob->action = actn; - ob->activecon = NULL; - actn->id.us++; - act->id.us--; - } - } - ob= ob->id.next; - } - } -} - - -void free_action(bAction *act) -{ - bActionChannel *chan; - - /* Free channels */ - for (chan=act->chanbase.first; chan; chan=chan->next){ - if (chan->ipo) - chan->ipo->id.us--; - free_constraint_channels(&chan->constraintChannels); - } - - if (act->chanbase.first) - BLI_freelistN (&act->chanbase); -} - -bAction* copy_action(bAction *src) -{ - bAction *dst = NULL; - bActionChannel *dchan, *schan; - - if(!src) return NULL; - - dst= copy_libblock(src); - duplicatelist(&(dst->chanbase), &(src->chanbase)); - - for (dchan=dst->chanbase.first, schan=src->chanbase.first; dchan; dchan=dchan->next, schan=schan->next){ - dchan->ipo = copy_ipo(dchan->ipo); - copy_constraint_channels(&dchan->constraintChannels, &schan->constraintChannels); - } - dst->id.flag |= LIB_FAKEUSER; - dst->id.us++; - return dst; -} - -bPoseChannel *copy_pose_channel(const bPoseChannel* src) -{ - bPoseChannel *dst; - - if (!src) - return NULL; - - dst = MEM_callocN (sizeof(bPoseChannel), "copyPoseChannel"); - memcpy (dst, src, sizeof(bPoseChannel)); - dst->prev=dst->next=NULL; - - return dst; -} - -void copy_pose(bPose **dst, bPose *src, int copycon) -{ - bPose *outPose; - bPose * inPose; - bPoseChannel *newChan; - bPoseChannel *curChan; - - inPose = src; - - if (!inPose){ - *dst=NULL; - return; - } - - outPose=MEM_callocN(sizeof(bPose), "pose"); - - for (curChan=inPose->chanbase.first; curChan; curChan=curChan->next){ - newChan=MEM_callocN(sizeof(bPoseChannel), "copyposePoseChannel"); - - strcpy (newChan->name, curChan->name); - newChan->flag=curChan->flag; - - memcpy (newChan->loc, curChan->loc, sizeof (curChan->loc)); - memcpy (newChan->size, curChan->size, sizeof (curChan->size)); - memcpy (newChan->quat, curChan->quat, sizeof (curChan->quat)); - Mat4CpyMat4 (newChan->obmat, (void *)curChan->obmat); - - BLI_addtail (&outPose->chanbase, newChan); - if (copycon){ - copy_constraints(&newChan->constraints, &curChan->constraints); - } - } - - *dst=outPose; -} - -bPoseChannel *set_pose_channel(bPose *pose, bPoseChannel *chan) -{ - /* chan is no longer valid for the calling function. - and should not be used by that function after calling - this one - */ - bPoseChannel *curChan; - - /* Determine if an equivalent channel exists already */ - for (curChan=pose->chanbase.first; curChan; curChan=curChan->next){ - if (!strcmp (curChan->name, chan->name)){ - if (chan->flag & POSE_ROT) - memcpy (curChan->quat, chan->quat, sizeof(chan->quat)); - if (chan->flag & POSE_SIZE) - memcpy (curChan->size, chan->size, sizeof(chan->size)); - if (chan->flag & POSE_LOC) - memcpy (curChan->loc, chan->loc, sizeof(chan->loc)); - if (chan->flag & PCHAN_DONE) - Mat4CpyMat4 (curChan->obmat, chan->obmat); - - curChan->flag |= chan->flag; - MEM_freeN (chan); - return curChan; - } - } - - MEM_freeN (chan); - return NULL; - /* If an equivalent channel doesn't exist, then don't bother setting it. */ -} - - diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index f92294df3d1..9ff8abf0f2a 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -89,7 +89,7 @@ void calc_curvepath(Object *ob) /* in a path vertices are with equal differences: path->len = number of verts */ /* NOW WITH BEVELCURVE!!! */ - if(ob==0 || ob->type != OB_CURVE) return; + if(ob==NULL || ob->type != OB_CURVE) return; cu= ob->data; if(ob==G.obedit) nu= editNurb.first; else nu= cu->nurb.first; @@ -98,10 +98,6 @@ void calc_curvepath(Object *ob) cu->path= NULL; bl= cu->bev.first; - if(bl==NULL) { - makeDispList(ob); - bl= cu->bev.first; - } if(bl==NULL) return; cu->path=path= MEM_callocN(sizeof(Path), "path"); @@ -213,11 +209,10 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir) /* returns OK float data[4]; int cycl=0, s0, s1, s2, s3; - if(ob==0 || ob->type != OB_CURVE) return 0; + if(ob==NULL || ob->type != OB_CURVE) return 0; cu= ob->data; - if(cu->path==0 || cu->path->data==0) { - calc_curvepath(ob); - if(cu->path==0 || cu->path->data==0) return 0; + if(cu->path==NULL || cu->path->data==NULL) { + printf("no path!\n"); } path= cu->path; fp= path->data; @@ -242,7 +237,8 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir) /* returns OK p2= fp + 4*s2; p3= fp + 4*s3; - if(cu->flag & CU_FOLLOW) { + /* note, commented out for follow constraint */ + //if(cu->flag & CU_FOLLOW) { set_afgeleide_four_ipo(1.0f-fac, data, KEY_BSPLINE); @@ -254,7 +250,7 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir) /* returns OK dir[0]= -dir[0]; dir[1]= -dir[1]; dir[2]= -dir[2]; - } + //} nu= cu->nurb.first; diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 1f96b48df9b..61122610e50 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -6,10 +6,7 @@ * 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. The Blender - * Foundation also sells licenses for use in proprietary software under - * the Blender License. See http://www.blender.org/BL/ for information - * about this. + * 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 @@ -23,9 +20,7 @@ * 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. + * Contributor(s): Full recode, Ton Roosendaal, Crete 2005 * * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ @@ -50,6 +45,7 @@ #include "DNA_view3d_types.h" #include "DNA_constraint_types.h" +#include "BKE_depsgraph.h" #include "BKE_displist.h" #include "BKE_global.h" #include "BKE_main.h" @@ -71,77 +67,192 @@ #include <config.h> #endif -/* Function prototypes */ - -static void apply_pose_bonechildren (Bone* bone, bPose* pose, int doit); -static Bone *get_named_bone_bonechildren (Bone *bone, const char *name); -static Bone *get_indexed_bone_bonechildren (Bone *bone, int *index); -/*void make_bone_parent_matrix (Bone* bone);*/ -static void copy_bonechildren (Bone* newBone, Bone* oldBone); -static void calc_armature_deform_bonechildren (Bone *bone, float *vec, float *co, float *contrib, float obmat[][4]); -static int verify_boneptr_children (Bone *cBone, Bone *tBone); -static void where_is_bonelist_time (Object *ob, ListBase *base, float ctime); -static Bone *get_last_ik_bone (Bone *bone); -static void precalc_bonelist_posemats(ListBase *bonelist, float parlen); - -/* Globals */ +/* ugly Globals */ static float g_premat[4][4]; static float g_postmat[4][4]; static MDeformVert *g_dverts; static ListBase *g_defbase; -static bArmature *g_defarm; +static Object *g_deform; -/* Functions */ +/* **************** Generic Functions, data level *************** */ + +bArmature *get_armature(Object *ob) +{ + if(ob==NULL) return NULL; + if(ob->type==OB_ARMATURE) return ob->data; + else return NULL; +} -float get_bone_length (Bone *bone) +bArmature *add_armature() { - float result[3]; + bArmature *arm; + + arm= alloc_libblock (&G.main->armature, ID_AR, "Armature"); + return arm; +} - VecSubf (result, bone->tail, bone->head); - return (float)sqrt(result[0]*result[0] + result[1]*result[1] + result[2]*result[2]); +void free_boneChildren(Bone *bone) +{ + Bone *child; + + if (bone) { + + child=bone->childbase.first; + if (child){ + while (child){ + free_boneChildren (child); + child=child->next; + } + BLI_freelistN (&bone->childbase); + } + } } -void apply_bonemat(Bone *bone) +void free_bones (bArmature *arm) { - float mat[3][3], imat[3][3], tmat[3][3]; + Bone *bone; + /* Free children (if any) */ + bone= arm->bonebase.first; + if (bone) { + while (bone){ + free_boneChildren (bone); + bone=bone->next; + } + } + - if(!bone) + BLI_freelistN(&arm->bonebase); +} + +void free_armature(bArmature *arm) +{ + if (arm) { + /* unlink_armature(arm);*/ + free_bones(arm); + } +} + +void make_local_armature(bArmature *arm) +{ + int local=0, lib=0; + Object *ob; + bArmature *newArm; + + if (arm->id.lib==0) return; + if (arm->id.us==1) { + arm->id.lib= 0; + arm->id.flag= LIB_LOCAL; + new_id(0, (ID*)arm, 0); + return; + } + + if(local && lib==0) { + arm->id.lib= 0; + arm->id.flag= LIB_LOCAL; + new_id(0, (ID *)arm, 0); + } + else if(local && lib) { + newArm= copy_armature(arm); + newArm->id.us= 0; + + ob= G.main->object.first; + while(ob) { + if(ob->data==arm) { + + if(ob->id.lib==0) { + ob->data= newArm; + newArm->id.us++; + arm->id.us--; + } + } + ob= ob->id.next; + } + } +} - Mat3CpyMat4(mat, bone->obmat); +static void copy_bonechildren (Bone* newBone, Bone* oldBone) +{ + Bone *curBone, *newChildBone; - VECCOPY(bone->loc, bone->obmat[3]); + /* Copy this bone's list*/ + duplicatelist (&newBone->childbase, &oldBone->childbase); + + /* For each child in the list, update it's children*/ + newChildBone=newBone->childbase.first; + for (curBone=oldBone->childbase.first;curBone;curBone=curBone->next){ + newChildBone->parent=newBone; + copy_bonechildren(newChildBone,curBone); + newChildBone=newChildBone->next; + } +} + +bArmature *copy_armature(bArmature *arm) +{ + bArmature *newArm; + Bone *oldBone, *newBone; + + newArm= copy_libblock (arm); + duplicatelist(&newArm->bonebase, &arm->bonebase); + + /* Duplicate the childrens' lists*/ + newBone=newArm->bonebase.first; + for (oldBone=arm->bonebase.first;oldBone;oldBone=oldBone->next){ + newBone->parent=NULL; + copy_bonechildren (newBone, oldBone); + newBone=newBone->next; + }; - Mat3ToQuat(mat, bone->quat); - QuatToMat3(bone->quat, tmat); + return newArm; +} - Mat3Inv(imat, tmat); +static Bone *get_named_bone_bonechildren (Bone *bone, const char *name) +{ + Bone *curBone, *rbone; - Mat3MulMat3(tmat, imat, mat); + if (!strcmp (bone->name, name)) + return bone; - bone->size[0]= tmat[0][0]; - bone->size[1]= tmat[1][1]; - bone->size[2]= tmat[2][2]; + for (curBone=bone->childbase.first; curBone; curBone=curBone->next){ + rbone=get_named_bone_bonechildren (curBone, name); + if (rbone) + return rbone; + } + + return NULL; +} + +Bone *get_named_bone (bArmature *arm, const char *name) +/* + Walk the list until the bone is found + */ +{ + Bone *bone=NULL, *curBone; + + if (!arm) return NULL; + + for (curBone=arm->bonebase.first; curBone; curBone=curBone->next){ + bone = get_named_bone_bonechildren (curBone, name); + if (bone) + return bone; + } + + return bone; } +/* ****************** Game Blender functions, called by engine ************** */ + void GB_build_mats (float parmat[][4], float obmat[][4], float premat[][4], float postmat[][4]) { float obinv[4][4]; -#if 0 - Mat4Invert(obinv, obmat); - Mat4CpyMat4(premat, obmat); - Mat4MulMat4(postmat, parmat, obinv); - Mat4Invert (postmat, premat); -#else Mat4Invert(obinv, obmat); Mat4CpyMat4(premat, obmat); Mat4MulMat4(postmat, parmat, obinv); Mat4Invert (premat, postmat); -#endif } void GB_init_armature_deform(ListBase *defbase, float premat[][4], float postmat[][4]) @@ -176,7 +287,7 @@ void GB_calc_armature_deform (float *co, MDeformVert *dvert) for (i=0; i<dvert->totweight; i++){ bone = dvert->dw[i].data; - if (bone) calc_bone_deform (bone, dvert->dw[i].weight, vec, co, &contrib); +// if (bone) calc_bone_deform (bone, dvert->dw[i].weight, vec, co, &contrib); } if (contrib){ @@ -189,207 +300,13 @@ void GB_calc_armature_deform (float *co, MDeformVert *dvert) Mat4MulVecfl(g_postmat, co); } -static Bone *get_last_ik_bone (Bone *bone) -{ - Bone *curBone; - - for (curBone = bone->childbase.first; curBone; curBone=curBone->next){ - if (curBone->flag & BONE_IK_TOPARENT){ - return get_last_ik_bone (curBone); - } - } - - return bone; -} - -#if 0 -static Bone *get_first_ik_bone (Bone *bone) -{ - Bone *curBone; - - for (curBone = bone; curBone; curBone=curBone->parent){ - if (!bone->parent) - return curBone; - if (!bone->flag & BONE_IK_TOPARENT) - return curBone; - } - - return bone; -/* for (curBone = bone->childbase.first; curBone; curBone=curBone->next){ - if (curBone->flag & BONE_IK_TOPARENT){ - return get_last_ik_bone (curBone); - } - } -*/ - return bone; - -} -#endif - -void where_is_bone(Object *ob, Bone *bone) -{ - where_is_bone_time (ob, bone, G.scene->r.cfra); -} - -void where_is_bone_time (Object *ob, Bone *bone, float ctime) -{ - where_is_bone1_time (ob, get_last_ik_bone(bone), ctime); -} - -void rebuild_bone_parent_matrix (Bone *bone) -{ - if (!bone) - return; - - if (bone->parent) - rebuild_bone_parent_matrix(bone->parent); - - /* Get the parent inverse */ - if (bone->parent) - Mat4MulMat4(bone->parmat, bone->parent->obmat, bone->parent->parmat); - else - Mat4One (bone->parmat); - -} -void where_is_bone1_time (Object *ob, Bone *bone, float ctime) -/* Assumes the pose has already been retrieved from the action */ -/* Also assumes where_is_object has been called for owner */ -{ - bPose *pose; - bPoseChannel *chan; - bArmature *arm; - float imat[4][4]; - float totmat[4][4]; - Object conOb; - - pose = ob->pose; - if (!pose) - return; - - arm = get_armature(ob); - - /* Ensure there is a channel for this bone*/ - chan = verify_pose_channel (pose, bone->name); - if (!chan) return; - -#if 1 - /* If 1 attempt to use pose caching features */ - /* Bail out if we've been recalced recently */ - if (chan->flag & PCHAN_DONE){ - Mat4CpyMat4 (bone->obmat, chan->obmat); - if (bone->parent){ - if ((bone->flag & BONE_IK_TOPARENT)) - where_is_bone1_time (ob, bone->parent, ctime); - else - where_is_bone_time (ob, bone->parent, ctime); - } - return; - } - else - chan->flag |= PCHAN_DONE; -#endif - -#if 1 - /* Ensure parents have been evaluated */ - if (bone->parent){ - if ((bone->flag & BONE_IK_TOPARENT)) - where_is_bone1_time (ob, bone->parent, ctime); - else - where_is_bone_time (ob, bone->parent, ctime); - } - -#endif - - if (arm){ - if ((arm->flag & ARM_RESTPOS) || ((G.obedit && (ob->data == G.obedit->data)))){ - Mat4One (bone->obmat); - Mat4One (chan->obmat); - return; - } - } - - /* If the bone has been flagged as 'no calc', let's not - * bother calculating it. - */ - if (bone->flag & BONE_NOCALC) { - return; - } - - if (bone->flag & BONE_IK_TOPARENT){ - bone->loc[0]=bone->loc[1]=bone->loc[2]=0.0F; - } - bone_to_mat4(bone, bone->obmat); - - /* Do constraints */ - // clear_workob(); - - memset(&conOb, 0, sizeof(Object)); - conOb.size[0]= conOb.size[1]= conOb.size[2]= 1.0; - - /* Collect the constraints from the pose */ - conOb.constraints.first = chan->constraints.first; - conOb.constraints.last = chan->constraints.last; - - /* Totmat takes bone's obmat to worldspace */ - - { - float parmat[4][4]; - float temp[4][4]; - - Mat4CpyMat4 (temp, bone->obmat); - Mat4One (bone->obmat); - get_objectspace_bone_matrix(bone, parmat, 1, 1); - Mat4CpyMat4 (bone->obmat, temp); - Mat4MulMat4 (totmat, parmat, ob->obmat); - } - - /* Build a workob to pass the bone to the constraint solver */ - conOb.data = ob->data; - conOb.type = ob->type; - conOb.parent = ob; - conOb.trackflag = ob->trackflag; - conOb.upflag = ob->upflag; - - VECCOPY(conOb.size, bone->size); - - Mat4MulMat4 (conOb.obmat, bone->obmat, totmat); - - /* Solve */ - solve_constraints (&conOb, TARGET_BONE, (void*)bone, ctime); - - { - float parmat[4][4]; - float temp[4][4]; - - Mat4CpyMat4 (temp, bone->obmat); - Mat4One (bone->obmat); - get_objectspace_bone_matrix(bone, parmat, 1, 1); - Mat4CpyMat4 (bone->obmat, temp); - Mat4MulMat4 (totmat, parmat, ob->obmat); - } - - VECCOPY(bone->size, conOb.size); - - /* Take out of worldspace */ - Mat4Invert (imat, totmat); - Mat4MulMat4 (bone->obmat, conOb.obmat, imat); - Mat4CpyMat4 (chan->obmat, bone->obmat); - -} - - -bArmature *get_armature(Object *ob) -{ - if(ob==NULL) return NULL; - if(ob->type==OB_ARMATURE) return ob->data; - else return NULL; -} +/* ****************** END Game Blender functions, called by engine ************** */ +/* ************ Armature Deform ******************* */ void init_armature_deform(Object *parent, Object *ob) { bArmature *arm; bDeformGroup *dg; - Bone *curBone; MDeformVert *dvert; int totverts; float obinv[4][4]; @@ -399,18 +316,8 @@ void init_armature_deform(Object *parent, Object *ob) if (!arm) return; - if (ob) - where_is_object (ob); - -#if 1 - apply_pose_armature (arm, parent->pose, 1); /* Hopefully doit parameter can be set to 0 in future */ - where_is_armature (parent); -#else - apply_pose_armature (arm, parent->pose, 0); -#endif - g_defbase = &ob->defbase; - g_defarm = arm; + g_deform = parent; Mat4Invert(obinv, ob->obmat); Mat4CpyMat4(g_premat, ob->obmat); @@ -428,17 +335,12 @@ void init_armature_deform(Object *parent, Object *ob) totverts=0; } - /* Precalc bone defmats */ - precalc_armature_posemats (arm); - - for (curBone=arm->bonebase.first; curBone; curBone=curBone->next){ - precalc_bone_defmat(curBone); - } + /* bone defmats are already in the channels, chan_mat */ - /* Validate bone data in bDeformGroups */ + /* Validate channel data in bDeformGroups */ for (dg=g_defbase->first; dg; dg=dg->next) - dg->data = (void*)get_named_bone(arm, dg->name); + dg->data = (void*)get_pose_channel(parent->pose, dg->name); if (g_dverts){ for (j=0; j<totverts; j++){ @@ -456,114 +358,6 @@ void init_armature_deform(Object *parent, Object *ob) } } -void get_bone_root_pos (Bone* bone, float vec[3], int posed) -{ - Bone *curBone; - float mat[4][4]; - - get_objectspace_bone_matrix(bone, mat, 1, posed); - VECCOPY (vec, mat[3]); - return; - - rebuild_bone_parent_matrix(bone); - if (posed){ - - get_objectspace_bone_matrix(bone, mat, 1, posed); - VECCOPY (vec, mat[3]); - } - else { - vec[0]=vec[1]=vec[2]=0.0F; - for (curBone=bone; curBone; curBone=curBone->parent){ - if (curBone==bone) - VecAddf (vec, vec, curBone->head); - else - VecAddf (vec, vec, curBone->tail); - } - } -} - -void get_bone_tip_pos (Bone* bone, float vec[3], int posed) -{ - Bone *curBone; - float mat[4][4], tmat[4][4], rmat[4][4], bmat[4][4], fmat[4][4]; - - get_objectspace_bone_matrix(bone, mat, 0, posed); - VECCOPY (vec, mat[3]); - return; - - rebuild_bone_parent_matrix(bone); - if (posed){ - - Mat4One (mat); - - for (curBone = bone; curBone; curBone=curBone->parent){ - Mat4One (bmat); - /* [BMAT] This bone's offset */ - VECCOPY (bmat[3], curBone->head); - if (curBone==bone){ - Mat4One (tmat); - VecSubf (tmat[3], curBone->tail, curBone->head); - Mat4MulMat4 (bmat, tmat, curBone->obmat); - VecAddf (bmat[3], bmat[3], curBone->head); - } - else - VecAddf (bmat[3], bmat[3], curBone->obmat[3]); // Test - - /* [RMAT] Parent's bone length = parent rotmat * bone length */ - if (curBone->parent){ - Mat4One (tmat); - VecSubf (tmat[3], curBone->parent->tail, curBone->parent->head); - Mat4MulMat4 (rmat, tmat, curBone->parent->obmat); - VecSubf (rmat[3], rmat[3], curBone->parent->obmat[3]); - } - else - Mat4One (rmat); - - Mat4MulSerie (fmat, rmat, bmat, mat, 0, 0, 0, 0, 0); - Mat4CpyMat4 (mat, fmat); - } - - VECCOPY (vec, mat[3]); - } - else{ - vec[0]=vec[1]=vec[2]=0.0F; - for (curBone=bone; curBone; curBone=curBone->parent){ - VecAddf (vec, vec, curBone->tail); - } - } -} - -int verify_boneptr (bArmature *arm, Bone *bone) -{ - /* Ensures that a given bone exists in an armature */ - Bone *curBone; - - if (!arm) - return 0; - - for (curBone=arm->bonebase.first; curBone; curBone=curBone->next){ - if (verify_boneptr_children (curBone, bone)) - return 1; - } - - return 0; -} - -static int verify_boneptr_children (Bone *cBone, Bone *tBone) -{ - Bone *curBone; - - if (cBone == tBone) - return 1; - - for (curBone=cBone->childbase.first; curBone; curBone=curBone->next){ - if (verify_boneptr_children (curBone, tBone)) - return 1; - } - return 0; -} - - float dist_to_bone (float vec[3], float b1[3], float b2[3]) { /* float dist=0; */ @@ -592,137 +386,41 @@ float dist_to_bone (float vec[3], float b1[3], float b2[3]) else { return (hsqr - (a*a)); } - - } -static void calc_armature_deform_bonechildren (Bone *bone, float *vec, float *co, float *contrib, float obmat[][4]) +static float calc_armature_deform_bone(Bone *bone, bPoseChannel *pchan, float *vec, float *co) { - Bone *curBone; - float root[3]; - float tip[3]; float dist, fac, ifac; float cop[3]; - float bdsqr; - - - get_bone_root_pos (bone, root, 0); - get_bone_tip_pos (bone, tip, 0); + float bdsqr, contrib=0.0; bdsqr = bone->dist*bone->dist; VECCOPY (cop, co); - dist = dist_to_bone(cop, root, tip); + dist = dist_to_bone(cop, bone->arm_head, bone->arm_tail); if ((dist) <= bdsqr){ fac = (dist)/bdsqr; ifac = 1.0F-fac; ifac*=bone->weight; - - if (!vec) - (*contrib) +=ifac; - else{ - ifac*=(1.0F/(*contrib)); + contrib= ifac; + if(contrib>0.0) { VECCOPY (cop, co); - Mat4MulVecfl(bone->defmat, cop); + Mat4MulVecfl(pchan->chan_mat, cop); VecSubf (cop, cop, co); // Make this a delta from the base position cop[0]*=ifac; cop[1]*=ifac; cop[2]*=ifac; VecAddf (vec, vec, cop); - - } - } - -// calc_bone_deform (bone, bone->weight, vec, co, contrib, obmat); - for (curBone = bone->childbase.first; curBone; curBone=curBone->next) - calc_armature_deform_bonechildren (curBone, vec, co, contrib, obmat); -} - -void precalc_bone_irestmat (Bone *bone) -{ - float restmat[4][4]; - - get_objectspace_bone_matrix(bone, restmat, 1, 0); - Mat4Invert (bone->irestmat, restmat); -} - -static void precalc_bonelist_posemats(ListBase *bonelist, float parlen) -{ - Bone *curBone; - float length; - float T_parlen[4][4]; - float T_root[4][4]; - float M_obmat[4][4]; - float R_bmat[4][4]; - float M_accumulatedMatrix[4][4]; - float delta[3]; - - for (curBone = bonelist->first; curBone; curBone=curBone->next){ - - /* Get the length translation (length along y axis) */ - length = get_bone_length(curBone); - - /* Get the bone's root offset (in the parent's coordinate system) */ - Mat4One (T_root); - VECCOPY (T_root[3], curBone->head); - - /* Compose the restmat */ - VecSubf(delta, curBone->tail, curBone->head); - make_boneMatrixvr(R_bmat, delta, curBone->roll); - - /* Retrieve the obmat (user transformation) */ - Mat4CpyMat4 (M_obmat, curBone->obmat); - - /* Compose the accumulated matrix (i.e. parent matrix * parent translation ) */ - if (curBone->parent){ - Mat4One (T_parlen); - T_parlen[3][1] = parlen; - Mat4MulMat4 (M_accumulatedMatrix, T_parlen, curBone->parent->posemat); } - else - Mat4One (M_accumulatedMatrix); - - /* Compose the matrix for this bone */ - Mat4MulSerie (curBone->posemat, M_accumulatedMatrix, T_root, R_bmat, M_obmat, NULL, NULL, NULL, NULL); - - precalc_bonelist_posemats(&curBone->childbase, length); } -} - -void precalc_armature_posemats (bArmature *arm) -{ - precalc_bonelist_posemats(&arm->bonebase, 0.0); -} - -void precalc_bone_defmat (Bone *bone) -{ - Bone *curBone; -#if 0 - float restmat[4][4]; - float posemat[4][4]; - float imat[4][4]; - /* Store restmat and restmat inverse - Calculate once when leaving editmode */ - /* Store all bones' posemats - Do when applied */ - - /* EXPENSIVE! Don't do this! */ - get_objectspace_bone_matrix(bone, restmat, 1, 0); - get_objectspace_bone_matrix(bone, posemat, 1, 1); - Mat4Invert (imat, restmat); - Mat4MulMat4 (bone->defmat, imat, posemat); - /* /EXPENSIVE */ -#else - Mat4MulMat4 (bone->defmat, bone->irestmat, bone->posemat); -#endif - for (curBone = bone->childbase.first; curBone; curBone=curBone->next){ - precalc_bone_defmat(curBone); - } + return contrib; } -void calc_bone_deform (Bone *bone, float weight, float *vec, float *co, float *contrib) +void calc_bone_deform (bPoseChannel *pchan, float weight, float *vec, float *co, float *contrib) { float cop[3]; @@ -731,7 +429,7 @@ void calc_bone_deform (Bone *bone, float weight, float *vec, float *co, float *c VECCOPY (cop, co); - Mat4MulVecfl(bone->defmat, cop); + Mat4MulVecfl(pchan->chan_mat, cop); vec[0]+=(cop[0]-co[0])*weight; vec[1]+=(cop[1]-co[1])*weight; @@ -742,540 +440,638 @@ void calc_bone_deform (Bone *bone, float weight, float *vec, float *co, float *c void calc_armature_deform (Object *ob, float *co, int index) { - bArmature *arm; - Bone *bone; - Bone *curBone; + bPoseChannel *pchan; + MDeformVert *dvert = g_dverts+index; float vec[3]; - float contrib=0; + float contrib=0.0; int i; - MDeformVert *dvert = g_dverts+index; - arm=g_defarm; vec[0]=vec[1]=vec[2]=0; /* Apply the object's matrix */ Mat4MulVecfl(g_premat, co); + /* using deform vertex groups */ if (g_dverts){ + for (i=0; i<dvert->totweight; i++){ - bone = dvert->dw[i].data; - if (bone) calc_bone_deform (bone, dvert->dw[i].weight, vec, co, &contrib); + pchan = (bPoseChannel *)dvert->dw[i].data; + if (pchan) calc_bone_deform (pchan, dvert->dw[i].weight, vec, co, &contrib); } + } + else { /* or use bone distances */ + Bone *bone; - if (contrib){ - vec[0]/=contrib; - vec[1]/=contrib; - vec[2]/=contrib; + for(pchan= g_deform->pose->chanbase.first; pchan; pchan= pchan->next) { + bone= pchan->bone; + if(bone) { + contrib+= calc_armature_deform_bone(bone, pchan, vec, co); + } } - VecAddf (co, vec, co); - Mat4MulVecfl(g_postmat, co); - return; - } - - // Count the number of interested bones - for (curBone = arm->bonebase.first; curBone; curBone=curBone->next) - calc_armature_deform_bonechildren (curBone, NULL, co, &contrib, ob->obmat); - - // Do the deformation - for (curBone = arm->bonebase.first; curBone; curBone=curBone->next) - calc_armature_deform_bonechildren (curBone, vec, co, &contrib, ob->obmat); + } + if (contrib>0.0){ + vec[0]/=contrib; + vec[1]/=contrib; + vec[2]/=contrib; + } VecAddf (co, vec, co); Mat4MulVecfl(g_postmat, co); } -void apply_pose_armature (bArmature* arm, bPose* pose, int doit) -{ - Bone *curBone; - for (curBone = arm->bonebase.first; curBone; curBone=curBone->next){ - apply_pose_bonechildren (curBone, pose, doit); - } -} +/* ************ END Armature Deform ******************* */ -void where_is_armature (Object *ob) +void get_objectspace_bone_matrix (struct Bone* bone, float M_accumulatedMatrix[][4], int root, int posed) { - where_is_object (ob); - where_is_armature_time(ob, (float)G.scene->r.cfra); + Mat4CpyMat4(M_accumulatedMatrix, bone->arm_mat); } -void where_is_armature_time (Object *ob, float ctime) +#if 0 +/* IK in the sense of; connected directly */ +static Bone *get_last_ik_bone (Bone *bone) { - bArmature *arm; - - arm = get_armature(ob); - if (!arm) - return; + Bone *curBone; + + for (curBone = bone->childbase.first; curBone; curBone=curBone->next){ + if (curBone->flag & BONE_IK_TOPARENT){ + return get_last_ik_bone (curBone); + } + } + + return bone; +} - where_is_bonelist_time (ob, &arm->bonebase, ctime); +#endif -} +/* **************** The new & simple (but OK!) armature evaluation ********* */ -static void where_is_bonelist_time (Object *ob, ListBase *base, float ctime) -{ - Bone *curBone; +/* ****************** And how it works! **************************************** - for (curBone=base->first; curBone; curBone=curBone->next){ - if (!curBone->childbase.first) - where_is_bone1_time (ob, curBone, ctime); + This is the bone transformation trick; they're hierarchical so each bone(b) + is in the coord system of bone(b-1): - where_is_bonelist_time(ob, &curBone->childbase, ctime); - } -} -static void apply_pose_bonechildren (Bone* bone, bPose* pose, int doit) -{ - Bone *curBone; - bPoseChannel *chan; + arm_mat(b)= arm_mat(b-1) * yoffs(b-1) * d_root(b) * bone_mat(b) + + -> yoffs is just the y axis translation in parent's coord system + -> d_root is the translation of the bone root, also in parent's coord system - if (!pose){ - - bone->dsize[0]=bone->dsize[1]=bone->dsize[2]=1.0F; - bone->size[0]=bone->size[1]=bone->size[2]=1.0F; + pose_mat(b)= pose_mat(b-1) * yoffs(b-1) * d_root(b) * bone_mat(b) * chan_mat(b) - bone->dquat[0]=bone->dquat[1]=bone->dquat[2]=bone->dquat[3]=0; - bone->quat[0]=bone->quat[1]=bone->quat[2]=bone->quat[3]=0.0F; - - bone->dloc[0]=bone->dloc[1]=bone->dloc[2]=0.0F; - bone->loc[0]=bone->loc[1]=bone->loc[2]=0.0F; - } + we then - in init deform - store the deform in chan_mat, such that: - // Ensure there is a channel for this bone - chan = verify_pose_channel (pose, bone->name); + pose_mat(b)= arm_mat(b) * chan_mat(b) + + *************************************************************************** */ - /* Only do this crazy stuff if the no calc flag - * is cleared for this bone. - */ - if (chan && (~bone->flag & BONE_NOCALC)) { - if (chan->flag & POSE_LOC) - memcpy (bone->loc, chan->loc, sizeof (bone->loc)); - if (chan->flag & POSE_SIZE) - memcpy (bone->size, chan->size, sizeof (bone->size)); - if (chan->flag & POSE_ROT) - memcpy (bone->quat, chan->quat, sizeof (bone->quat)); - - if (doit){ - bone_to_mat4(bone, bone->obmat); - } - else{ - Mat4CpyMat4 (bone->obmat, chan->obmat); - } - } - - for (curBone = bone->childbase.first; curBone; curBone=curBone->next){ - apply_pose_bonechildren (curBone, pose, doit); - } -} -void make_boneMatrixvr (float outmatrix[][4],float delta[3], float roll) /* Calculates the rest matrix of a bone based On its vector and a roll around that vector */ +void vec_roll_to_mat3(float *vec, float roll, float mat[][3]) { - float nor[3],axis[3],target[3]={0,1,0}; + float nor[3], axis[3], target[3]={0,1,0}; float theta; - float rMatrix[3][3], bMatrix[3][3], fMatrix[3][3]; - - VECCOPY (nor,delta); + float rMatrix[3][3], bMatrix[3][3]; + + VECCOPY (nor, vec); Normalise (nor); - + /* Find Axis & Amount for bone matrix*/ Crossf (axis,target,nor); - + if (Inpf(axis,axis) > 0.0000000000001) { /* if nor is *not* a multiple of target ... */ Normalise (axis); theta=(float) acos (Inpf (target,nor)); - + /* Make Bone matrix*/ VecRotToMat3(axis, theta, bMatrix); } else { /* if nor is a multiple of target ... */ float updown; - + /* point same direction, or opposite? */ updown = ( Inpf (target,nor) > 0 ) ? 1.0 : -1.0; - + /* I think this should work ... */ bMatrix[0][0]=updown; bMatrix[0][1]=0.0; bMatrix[0][2]=0.0; bMatrix[1][0]=0.0; bMatrix[1][1]=updown; bMatrix[1][2]=0.0; bMatrix[2][0]=0.0; bMatrix[2][1]=0.0; bMatrix[2][2]=1.0; } - + /* Make Roll matrix*/ VecRotToMat3(nor, roll, rMatrix); /* Combine and output result*/ - Mat3MulMat3 (fMatrix,rMatrix,bMatrix); - Mat4CpyMat3 (outmatrix,fMatrix); + Mat3MulMat3 (mat, rMatrix, bMatrix); } -void make_boneMatrix (float outmatrix[][4], Bone *bone) -/* Calculates the rest matrix of a bone based - On its vector and a roll around that vector */ + +/* recursive part, calculates restposition of entire tree of children */ +/* used by exiting editmode too */ +void where_is_armature_bone(Bone *bone, Bone *prevbone) { - float delta[3]; - float parmat[4][4], imat[4][4], obmat[4][4]; + float vec[3]; + + /* Bone Space */ + VecSubf (vec, bone->tail, bone->head); + vec_roll_to_mat3(vec, bone->roll, bone->bone_mat); - if (bone->parent){ - VecSubf (delta, bone->parent->tail, bone->parent->head); - make_boneMatrixvr(parmat, delta, bone->parent->roll); + bone->length= VecLenf(bone->head, bone->tail); + + if(prevbone) { + float offs_bone[4][4]; // yoffs(b-1) + root(b) + bonemat(b) + + /* bone transform itself */ + Mat4CpyMat3(offs_bone, bone->bone_mat); + + /* The bone's root offset (is in the parent's coordinate system) */ + VECCOPY(offs_bone[3], bone->head); + + /* Get the length translation of parent (length along y axis) */ + offs_bone[3][1]+= prevbone->length; + + /* Compose the matrix for this bone */ + Mat4MulMat4(bone->arm_mat, offs_bone, prevbone->arm_mat); } - else{ - Mat4One (parmat); + else { + Mat4CpyMat3(bone->arm_mat, bone->bone_mat); + VECCOPY(bone->arm_mat[3], bone->head); } - - Mat4Invert (imat, parmat); - VecSubf (delta, bone->tail, bone->head); - make_boneMatrixvr(obmat, delta, bone->roll); - - Mat4MulMat4(outmatrix, obmat, imat); - + /* head */ + VECCOPY(bone->arm_head, bone->arm_mat[3]); + /* tail is in current local coord system */ + VECCOPY(vec, bone->arm_mat[1]); + VecMulf(vec, bone->length); + VecAddf(bone->arm_tail, bone->arm_head, vec); + + /* and the kiddies */ + prevbone= bone; + for(bone= bone->childbase.first; bone; bone= bone->next) { + where_is_armature_bone(bone, prevbone); + } } - -bArmature *add_armature() +/* updates vectors and matrices on rest-position level, only needed + after editing armature itself, now only on reading file */ +void where_is_armature (bArmature *arm) { - bArmature *arm; - - arm= alloc_libblock (&G.main->armature, ID_AR, "Armature"); - - if(arm) { - + Bone *bone; + /* hierarchical from root to children */ + for(bone= arm->bonebase.first; bone; bone= bone->next) { + where_is_armature_bone(bone, NULL); } - return arm; } +static int rebuild_pose_bone(bPose *pose, Bone *bone, bPoseChannel *parchan, int depth, int counter) +{ + bPoseChannel *pchan = verify_pose_channel (pose, bone->name); // verify checks and/or adds -void free_boneChildren(Bone *bone) -{ - Bone *child; - - if (bone) { - - child=bone->childbase.first; - if (child){ - while (child){ - free_boneChildren (child); - child=child->next; - } - BLI_freelistN (&bone->childbase); - } + pchan->bone= bone; + pchan->parent= parchan; + pchan->depth= depth; + counter++; + + for(bone= bone->childbase.first; bone; bone= bone->next) { + counter= rebuild_pose_bone(pose, bone, pchan, depth+1, counter); } + + return counter; } -void free_bones (bArmature *arm) +/* only after leave editmode, but also for validating older files */ +/* NOTE: pose->flag is set for it */ +void armature_rebuild_pose(Object *ob, bArmature *arm) { Bone *bone; - /* Free children (if any) */ - bone= arm->bonebase.first; - if (bone) { - while (bone){ - free_boneChildren (bone); - bone=bone->next; + bPose *pose; + bPoseChannel *pchan, *next; + int counter=0; + + /* only done here */ + if(ob->pose==NULL) ob->pose= MEM_callocN(sizeof(bPose), "new pose"); + pose= ob->pose; + + /* first step, check if all channels are there, also sets depth */ + for(bone= arm->bonebase.first; bone; bone= bone->next) { + counter= rebuild_pose_bone(pose, bone, NULL, 0, counter); + } + /* sort channels on dependency order, so we can walk the channel list */ + + /* and a check for garbage */ + for(pchan= pose->chanbase.first; pchan; pchan= next) { + next= pchan->next; + if(pchan->bone==NULL) { + BLI_freelinkN(&pose->chanbase, pchan); // constraints? } } + //printf("rebuild pose, %d bones\n", counter); + if(counter<2) return; + update_pose_constraint_flags(ob->pose); // for IK detection for example - BLI_freelistN(&arm->bonebase); + /* the sorting */ + DAG_pose_sort(ob); + + ob->pose->flag &= ~POSE_RECALC; } -void free_armature(bArmature *arm) -{ - if (arm) { -/* unlink_armature(arm);*/ - free_bones(arm); - } -} -void make_local_armature(bArmature *arm) -{ - int local=0, lib=0; - Object *ob; - bArmature *newArm; +/* ********************** THE IK SOLVER ******************* */ - if (arm->id.lib==0) - return; - if (arm->id.us==1) { - arm->id.lib= 0; - arm->id.flag= LIB_LOCAL; - new_id(0, (ID*)arm, 0); - return; - } - if(local && lib==0) { - arm->id.lib= 0; - arm->id.flag= LIB_LOCAL; - new_id(0, (ID *)arm, 0); +/* allocates PoseChain, and links that to root bone/channel */ +/* note; if we got this working, it can become static too? */ +static void initialize_posechain(struct Object *ob, bPoseChannel *pchan_tip) +{ + bPoseChannel *curchan, *pchan_root=NULL, *chanlist[256]; + PoseChain *chain; + bConstraint *con; + bKinematicConstraint *data; + int a, segcount= 0; + + /* find IK constraint, and validate it */ + for(con= pchan_tip->constraints.first; con; con= con->next) { + if(con->type==CONSTRAINT_TYPE_KINEMATIC) break; } - else if(local && lib) { - newArm= copy_armature(arm); - newArm->id.us= 0; - - ob= G.main->object.first; - while(ob) { - if(ob->data==arm) { - - if(ob->id.lib==0) { - ob->data= newArm; - newArm->id.us++; - arm->id.us--; - } - } - ob= ob->id.next; + if(con==NULL) return; + if(con->flag & CONSTRAINT_DISABLE) return; // not sure... + + data=(bKinematicConstraint*)con->data; + if(data->tar==NULL) return; + + /* Find the chain's root & count the segments needed */ + for (curchan = pchan_tip; curchan; curchan=curchan->parent){ + pchan_root = curchan; + /* tip is not in the chain */ + if (curchan!=pchan_tip){ + chanlist[segcount]=curchan; + segcount++; } + if(segcount>255) break; // also weak + + if (!(curchan->bone->flag & BONE_IK_TOPARENT)) + break; + } + if (!segcount) return; + + /* setup the chain data */ + chain = MEM_callocN(sizeof(PoseChain), "posechain"); + chain->totchannel= segcount; + chain->solver = IK_CreateChain(); + chain->con= con; + + chain->iterations = data->iterations; + chain->tolerance = data->tolerance; + + chain->pchanchain= MEM_callocN(segcount*sizeof(void *), "channel chain"); + for(a=0; a<segcount; a++) { + chain->pchanchain[a]= chanlist[segcount-a-1]; } + + /* AND! link the chain to the root */ + BLI_addtail(&pchan_root->chain, chain); } -static void copy_bonechildren (Bone* newBone, Bone* oldBone) +/* called from within the core where_is_pose loop, all animsystems and constraints +were executed & assigned. Now as last we do an IK pass */ +static void execute_posechain(Object *ob, PoseChain *chain) { - Bone *curBone, *newChildBone; - - /* Copy this bone's list*/ - duplicatelist (&newBone->childbase, &oldBone->childbase); - - /* For each child in the list, update it's children*/ - newChildBone=newBone->childbase.first; - for (curBone=oldBone->childbase.first;curBone;curBone=curBone->next){ - newChildBone->parent=newBone; - copy_bonechildren(newChildBone,curBone); - newChildBone=newChildBone->next; + IK_Segment_Extern *segs; + bPoseChannel *pchan; + float R_parmat[3][3]; + float iR_parmat[3][3]; + float R_bonemat[3][3]; + float rootmat[4][4], imat[4][4]; + float size[3]; + int curseg; + + /* first set the goal inverse transform, assuming the root of chain was done ok! */ + pchan= chain->pchanchain[0]; + Mat4One(rootmat); + VECCOPY(rootmat[3], pchan->pose_head); + + Mat4MulMat4 (imat, rootmat, ob->obmat); + Mat4Invert (chain->goalinv, imat); + + /* and set and transform goal */ + get_constraint_target_matrix(chain->con, TARGET_BONE, NULL, rootmat, size, 1.0); // 1.0=ctime + VECCOPY (chain->goal, rootmat[3]); + Mat4MulVecfl (chain->goalinv, chain->goal); + + /* Now we construct the IK segments */ + segs = MEM_callocN (sizeof(IK_Segment_Extern)*chain->totchannel, "iksegments"); + + for (curseg=0; curseg<chain->totchannel; curseg++){ + + pchan= chain->pchanchain[curseg]; + + /* Get the matrix that transforms from prevbone into this bone */ + Mat3CpyMat4(R_bonemat, pchan->pose_mat); + + if (pchan->parent && (pchan->bone->flag & BONE_IK_TOPARENT)) { + Mat3CpyMat4(R_parmat, pchan->parent->pose_mat); + } + else + Mat3One (R_parmat); + + Mat3Inv(iR_parmat, R_parmat); + + /* Mult and Copy the matrix into the basis and transpose (IK lib likes it) */ + Mat3MulMat3((void *)segs[curseg].basis, iR_parmat, R_bonemat); + Mat3Transp((void *)segs[curseg].basis); + + /* Fill out the IK segment */ + segs[curseg].length = pchan->bone->length; } + + /* Solve the chain */ + + IK_LoadChain(chain->solver, segs, chain->totchannel); + + IK_SolveChain(chain->solver, chain->goal, chain->tolerance, + chain->iterations, 0.1f, chain->solver->segments); + + + /* not yet free! */ } -bArmature *copy_armature(bArmature *arm) -{ - bArmature *newArm; - Bone *oldBone, *newBone; - newArm= copy_libblock (arm); - duplicatelist(&newArm->bonebase, &arm->bonebase); +/* ********************** THE POSE SOLVER ******************* */ - /* Duplicate the childrens' lists*/ - newBone=newArm->bonebase.first; - for (oldBone=arm->bonebase.first;oldBone;oldBone=oldBone->next){ - newBone->parent=NULL; - copy_bonechildren (newBone, oldBone); - newBone=newBone->next; - }; - return newArm; -} - - -void bone_to_mat3(Bone *bone, float mat[][3]) /* no parent */ +/* loc/rot/size to mat4 */ +static void chan_calc_mat(bPoseChannel *chan) { float smat[3][3]; float rmat[3][3]; -/* float q1[4], vec[3];*/ - - /* size */ -/* if(bone->ipo) { - vec[0]= bone->size[0]+bone->dsize[0]; - vec[1]= bone->size[1]+bone->dsize[1]; - vec[2]= bone->size[2]+bone->dsize[2]; - SizeToMat3(vec, smat); - } - else -*/ { - SizeToMat3(bone->size, smat); - } - - /* rot */ - /*if(bone->flag & BONE_QUATROT) { - if(bone->ipo) { - QuatMul(q1, bone->quat, bone->dquat); - QuatToMat3(q1, rmat); - } - else - */ { - NormalQuat(bone->quat); - QuatToMat3(bone->quat, rmat); - } -/* } -*/ - Mat3MulMat3(mat, rmat, smat); -} - -void bone_to_mat4(Bone *bone, float mat[][4]) -{ float tmat[3][3]; - bone_to_mat3(bone, tmat); + SizeToMat3(chan->size, smat); + + NormalQuat(chan->quat); + QuatToMat3(chan->quat, rmat); - Mat4CpyMat3(mat, tmat); + Mat3MulMat3(tmat, rmat, smat); - VECCOPY(mat[3], bone->loc); -// VecAddf(mat[3], mat[3], bone->loc); -/* if(bone->ipo) { - mat[3][0]+= bone->dloc[0]; - mat[3][1]+= bone->dloc[1]; - mat[3][2]+= bone->dloc[2]; + Mat4CpyMat3(chan->chan_mat, tmat); + + /* prevent action channels breaking chains */ + if (!(chan->bone->flag & BONE_IK_TOPARENT)) { + VECCOPY(chan->chan_mat[3], chan->loc); } -*/ + } -Bone *get_indexed_bone (bArmature *arm, int index) -/* - Walk the list until the index is reached -*/ +/* transform from bone(b) to bone(b+1), store in chan_mat */ +static void make_dmats(bPoseChannel *pchan) { - Bone *bone=NULL, *curBone; - int ref=index; - - if (!arm) - return NULL; - - for (curBone=arm->bonebase.first; curBone; curBone=curBone->next){ - bone = get_indexed_bone_bonechildren (curBone, &ref); - if (bone) - return bone; + if (pchan->parent) { + float iR_parmat[4][4]; + Mat4Invert(iR_parmat, pchan->parent->pose_mat); + Mat4MulMat4(pchan->chan_mat, pchan->pose_mat, iR_parmat); // delta mat } - - return bone; + else Mat4CpyMat4(pchan->chan_mat, pchan->pose_mat); } -Bone *get_named_bone (bArmature *arm, const char *name) -/* - Walk the list until the bone is found -*/ +/* applies IK matrix to pchan, IK is done separated */ +/* formula: pose_mat(b) = pose_mat(b-1) * diffmat(b-1, b) * ik_mat(b) */ +/* to make this work, the diffmats have to be precalculated! Stored in chan_mat */ +static void where_is_ik_bone(bPoseChannel *pchan, float ik_mat[][3]) // nr = to detect if this is first bone { - Bone *bone=NULL, *curBone; - - if (!arm) return NULL; + float vec[3], ikmat[4][4]; + + Mat4CpyMat3(ikmat, ik_mat); + + if (pchan->parent) + Mat4MulSerie(pchan->pose_mat, pchan->parent->pose_mat, pchan->chan_mat, ikmat, NULL, NULL, NULL, NULL, NULL); + else + Mat4MulMat4(pchan->pose_mat, ikmat, pchan->chan_mat); - for (curBone=arm->bonebase.first; curBone; curBone=curBone->next){ - bone = get_named_bone_bonechildren (curBone, name); - if (bone) - return bone; - } + /* calculate head */ + VECCOPY(pchan->pose_head, pchan->pose_mat[3]); + /* calculate tail */ + VECCOPY(vec, pchan->pose_mat[1]); + VecMulf(vec, pchan->bone->length); + VecAddf(pchan->pose_tail, pchan->pose_head, vec); - return bone; + pchan->flag |= POSE_DONE; } -static Bone *get_indexed_bone_bonechildren (Bone *bone, int *index) +/* The main armature solver, does all constraints excluding IK */ +/* pchan is validated, as having bone and parent pointer */ +static void where_is_pose_bone(Object *ob, bPoseChannel *pchan) { - Bone *curBone, *rbone; - - if (!*index) - return bone; - - (*index)--; - - for (curBone=bone->childbase.first; curBone; curBone=curBone->next){ - rbone=get_indexed_bone_bonechildren (curBone, index); - if (rbone) - return rbone; + Bone *bone, *parbone; + bPoseChannel *parchan; + float vec[3], ctime= 1.0; // ctime todo + + /* 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 */ + chan_calc_mat(pchan); + + /* 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 */ + Mat4CpyMat3(offs_bone, bone->bone_mat); + + /* The bone's root offset (is in the parent's coordinate system) */ + VECCOPY(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 */ + Mat4MulSerie(pchan->pose_mat, parchan->pose_mat, offs_bone, pchan->chan_mat, NULL, NULL, NULL, NULL, NULL); } - - return NULL; + else + Mat4MulMat4(pchan->pose_mat, pchan->chan_mat, bone->arm_mat); + + + /* Do constraints */ + if(pchan->constraints.first) { + static Object conOb; + static int initialized= 0; + + /* Build a workob to pass the bone to the constraint solver */ + if(initialized==0) { + memset(&conOb, 0, sizeof(Object)); + initialized= 1; + } + conOb.size[0]= conOb.size[1]= conOb.size[2]= 1.0; + conOb.data = ob->data; + conOb.type = ob->type; + conOb.parent = ob; // ik solver retrieves the armature that way !?!?!?! + conOb.pose= ob->pose; // needed for retrieving pchan + conOb.trackflag = ob->trackflag; + conOb.upflag = ob->upflag; + + /* Collect the constraints from the pose (listbase copy) */ + conOb.constraints = pchan->constraints; + + /* conOb.obmat takes bone to worldspace */ + Mat4MulMat4 (conOb.obmat, pchan->pose_mat, ob->obmat); + + //VECCOPY(conOb.size, pchan->size); // stretchto constraint + + /* Solve */ + solve_constraints (&conOb, TARGET_BONE, (void*)bone, ctime); // ctime doesnt alter objects + + //VECCOPY(bone->size, conOb.size); // stretchto constraint + + /* Take out of worldspace */ + Mat4MulMat4 (pchan->pose_mat, conOb.obmat, ob->imat); + } + + /* calculate head */ + VECCOPY(pchan->pose_head, pchan->pose_mat[3]); + /* calculate tail */ + VECCOPY(vec, pchan->pose_mat[1]); + VecMulf(vec, bone->length); + VecAddf(pchan->pose_tail, pchan->pose_head, vec); + } -static Bone *get_named_bone_bonechildren (Bone *bone, const char *name) +/* This only reads anim data from channels, and writes to channels */ +/* This is the only function adding poses */ +void where_is_pose (Object *ob) { - Bone *curBone, *rbone; - - if (!strcmp (bone->name, name)) - return bone; + bArmature *arm; + Bone *bone; + bPoseChannel *pchan, *next; + float imat[4][4]; +// float ctime= (float)G.scene->r.cfra; /* time only applies constraint location on curve path (now) */ - for (curBone=bone->childbase.first; curBone; curBone=curBone->next){ - rbone=get_named_bone_bonechildren (curBone, name); - if (rbone) - return rbone; + arm = get_armature(ob); + + if(arm==NULL) return; + if(ob->pose==NULL || (ob->pose->flag & POSE_RECALC)) + armature_rebuild_pose(ob, arm); + +// printf("re-evaluate pose %s\n", ob->id.name); + + /* In restposition we read the data from the bones */ + if(arm->flag & ARM_RESTPOS) { + + for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { + bone= pchan->bone; + if(bone) { + Mat4CpyMat4(pchan->pose_mat, bone->arm_mat); + VECCOPY(pchan->pose_head, bone->arm_head); + VECCOPY(pchan->pose_tail, pchan->pose_head); + } + } } - - return NULL; -} - -void make_displists_by_armature (Object *ob) -{ - Base *base; - - if (ob){ - if (ob->type != OB_ARMATURE) return; - for (base= G.scene->base.first; base; base= base->next){ - if ((ob==base->object->parent) && (base->lay & G.scene->lay)) - if ((base->object->partype==PARSKEL) || (base->object->type==OB_MBALL)) - makeDispList(base->object); + else { + Mat4Invert(ob->imat, ob->obmat); // imat is needed + +//#if 0 + /* 1. construct the PoseChains, clear flags */ + for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { + pchan->flag &= ~POSE_DONE; + if(pchan->constflag & PCHAN_HAS_IK) // flag is set on editing constraints + initialize_posechain(ob, pchan); // will attach it to root! + } + + /* 2. the main loop, channels are already hierarchical sorted from root to children */ + for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { + if(!(pchan->flag & POSE_DONE)) { + /* 3. if we find an IK root, we handle it separated */ + if(pchan->chain.first) { + while(pchan->chain.first) { + PoseChain *chain= pchan->chain.first; + int a; + + /* 4. walk over the chain for regular solving */ + for(a=0; a<chain->totchannel; a++) { + if(!(chain->pchanchain[a]->flag & POSE_DONE)) // successive chains can set the flag + where_is_pose_bone(ob, chain->pchanchain[a]); + } + /* 5. execute the IK solver */ + execute_posechain(ob, chain); // calculates 3x3 difference matrices + /* 6. apply the differences to the channels, we calculate the original differences first */ + for(a=0; a<chain->totchannel; a++) + make_dmats(chain->pchanchain[a]); + for(a=0; a<chain->totchannel; a++) + where_is_ik_bone(chain->pchanchain[a], (void *)chain->solver->segments[a].basis_change); + // (sets POSE_DONE) + + /* 6. and free */ + BLI_remlink(&pchan->chain, chain); + free_posechain(chain); + } + } + else where_is_pose_bone(ob, pchan); + } } +//#endif } -/* -(ton) changed this; now a free displist is sufficient, drawobject.c will make disp -(ton) changed it back... doesnt work yet, do it after release -*/ - -} - -void get_objectspace_bone_matrix (struct Bone* bone, float M_accumulatedMatrix[][4], int root, int posed) -/* Gets matrix that transforms the bone to object space */ -/* This function is also used to compute the orientation of the bone for display */ -{ - Bone *curBone; - - Bone *bonelist[256]; - int bonecount=0, i; - Mat4One (M_accumulatedMatrix); - - /* Build a list of bones from tip to root */ - for (curBone=bone; curBone; curBone=curBone->parent){ - bonelist[bonecount] = curBone; - bonecount++; +#if 0 + doconstraints= 1; + for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { + where_is_pose_bone(ob, pchan); } + doconstraints= 0; + for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { + where_is_pose_bone(ob, pchan); + pchan->flag &= ~POSE_IK_MAT; + } +#endif + + /* calculating deform matrices */ + for(pchan= ob->pose->chanbase.first; pchan; pchan= next) { + next= pchan->next; + + if(pchan->bone) { + Mat4Invert(imat, pchan->bone->arm_mat); + Mat4MulMat4(pchan->chan_mat, imat, pchan->pose_mat); + } + } +} - /* Count through the inverted list (i.e. iterate from root to tip)*/ - for (i=0; i<bonecount; i++){ - float T_root[4][4]; - float T_len[4][4]; - float R_bmat[4][4]; - float M_obmat[4][4]; - float M_boneMatrix[4][4]; - float delta[3]; - - curBone = bonelist[bonecount-i-1]; - - /* Get the length translation (length along y axis) */ - Mat4One (T_len); - T_len[3][1] = get_bone_length(curBone); - - if ((curBone == bone) && (root)) - Mat4One (T_len); - - /* Get the bone's root offset (in the parent's coordinate system) */ - Mat4One (T_root); - VECCOPY (T_root[3], curBone->head); - - /* Compose the restmat */ - VecSubf(delta, curBone->tail, curBone->head); - make_boneMatrixvr(R_bmat, delta, curBone->roll); +/* *************** helper for selection code ****************** */ - /* Retrieve the obmat (user transformation) */ - if (posed) - Mat4CpyMat4 (M_obmat, curBone->obmat); - else - Mat4One (M_obmat); - /* Compose the matrix for this bone */ -#if 0 - Mat4MulSerie (M_boneMatrix, M_accumulatedMatrix, T_root, M_obmat, R_bmat, T_len, NULL, NULL, NULL); -#else - Mat4MulSerie (M_boneMatrix, M_accumulatedMatrix, T_root, R_bmat, M_obmat, T_len, NULL, NULL, NULL); -#endif - Mat4CpyMat4 (M_accumulatedMatrix, M_boneMatrix); +Bone *get_indexed_bone (Object *ob, int index) +/* + Now using pose channel +*/ +{ + bPoseChannel *pchan; + int a= 0; + + if(ob->pose==NULL) return NULL; + + for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next, a++) { + if(a==index) return pchan->bone; } + return NULL; +} -} +/* *********************** Inverse Kinematics ************* */ +#if 0 void solve_posechain (PoseChain *chain) { float goal[3]; int i; Bone *curBone; - float M_obmat[4][4]; - float M_basischange[4][4]; +// float M_obmat[4][4]; +// float M_basischange[4][4]; bPoseChannel *chan; if (!chain->solver) return; @@ -1290,7 +1086,6 @@ void solve_posechain (PoseChain *chain) VECCOPY (goal, chain->goal); Mat4MulVecfl (chain->goalinv, goal); - /* Solve the chain */ IK_SolveChain(chain->solver, @@ -1302,30 +1097,41 @@ void solve_posechain (PoseChain *chain) /* Copy the results back into the bones */ for (i = chain->solver->num_segments-1, curBone=chain->target->parent; i>=0; i--, curBone=curBone->parent){ - +// for (i = 0; i<chain->solver->num_segments; i++) { + //curBone= bonelist[i]; + /* Retrieve the delta rotation from the solver */ - Mat4One(M_basischange); - Mat4CpyMat3(M_basischange, (void *)chain->solver->segments[i].basis_change); //basis_change = array[9] - - +// Mat4One(M_basischange); +// Mat4CpyMat3(M_basischange, (void *)chain->solver->segments[i].basis_change); //basis_change = array[9] +// printmatrix3(curBone->name, (void *)chain->solver->segments[i].basis_change); /** * Multiply the bone's usertransform by the * basis change to get the new usertransform */ - Mat4CpyMat4 (M_obmat, curBone->obmat); - Mat4MulMat4 (curBone->obmat, M_basischange, M_obmat); - + //Mat4CpyMat4 (M_obmat, curBone->obmat); + //Mat4MulMat4 (curBone->obmat, M_basischange, M_obmat); + /* store in channel itself */ + + chan= get_pose_channel(chain->pose, curBone->name); + Mat3CpyMat3 (chan->ik_mat, (void *)chain->solver->segments[i].basis_change); + chan->flag |= POSE_IK_MAT; + /* Store the solve results on the childrens' channels */ - for (chan = chain->pose->chanbase.first; chan; chan=chan->next){ - if (!strcmp (chan->name, curBone->name)){ - Mat4CpyMat4 (chan->obmat, curBone->obmat); - break; - } - } - + //for (chan = chain->pose->chanbase.first; chan; chan=chan->next){ + // if (!strcmp (chan->name, curBone->name)){ + // Mat4CpyMat4 (chan->obmat, curBone->obmat); + // break; + // } + //} } + /* WARNING! REMOVE LATER !!! */ + /* flag chain target to recalculate too */ + chan= get_pose_channel(chain->pose, chain->target->name); + Mat3One(chan->ik_mat); + chan->flag |= POSE_IK_MAT; } +#endif void free_posechain (PoseChain *chain) { @@ -1334,9 +1140,13 @@ void free_posechain (PoseChain *chain) chain->solver->segments = NULL; IK_FreeChain(chain->solver); } - MEM_freeN (chain); + if(chain->pchanchain) MEM_freeN(chain->pchanchain); + MEM_freeN(chain); } +#if 0 +/* actually; bones to IK_solver data */ +/* Object is its own Armature object */ PoseChain *ik_chain_to_posechain (Object *ob, Bone *bone) { IK_Segment_Extern *segs; @@ -1344,15 +1154,16 @@ PoseChain *ik_chain_to_posechain (Object *ob, Bone *bone) Bone *curBone, *rootBone; int segcount, curseg, icurseg; float imat[4][4]; + bPoseChannel *pchan; Bone *bonelist[256]; float rootmat[4][4]; - float bonespace[4][4]; +// float bonespace[4][4]; /** * Some interesting variables in this function: * * Bone->obmat Bone's user transformation; - * It is initialized in where_is_bone1_time + * It is initialized in where_is_b one1_time * * rootmat Bone's coordinate system, computed by * get_objectspace_bone_matrix. Takes all @@ -1395,27 +1206,29 @@ PoseChain *ik_chain_to_posechain (Object *ob, Bone *bone) /* Allocate some IK segments */ segs = MEM_callocN (sizeof(IK_Segment_Extern)*segcount, "iksegments"); - + //printf("segcount %d\n", segcount); /** * Remove the offset from the first bone in the chain and take the target to chainspace */ - - get_objectspace_bone_matrix(rootBone, bonespace, 1, 1); - Mat4One (rootmat); - VECCOPY (rootmat[3], bonespace[3]); + //get_objectspace_bone_matrix(rootBone, bonespace, 1, 1); + //Mat4One (rootmat); + //VECCOPY (rootmat[3], bonespace[3]); + pchan= get_pose_channel(ob->pose, rootBone->name); + Mat4One(rootmat); + VECCOPY(rootmat[3], pchan->pose_head); /* Take the target to bonespace */ + /* (ton) I think it's the matrix to take a world coordinate into "chainspace" */ Mat4MulMat4 (imat, rootmat, ob->obmat); Mat4Invert (chain->goalinv, imat); - /** * Build matrices from the root to the tip * We count backwards through the bone list (which is sorted tip to root) * and forwards through the ik_segment list */ - + /* that we're going to recode! (ton) */ for (curseg = segcount-1; curseg>=0; curseg--){ float M_basismat[4][4]; float R_parmat[4][4]; @@ -1428,11 +1241,16 @@ PoseChain *ik_chain_to_posechain (Object *ob, Bone *bone) /* Get the basis matrix */ Mat4One (R_parmat); - get_objectspace_bone_matrix(curBone, R_bonemat, 1, 1); + //get_objectspace_bone_matrix(curBone, R_bonemat, 1, 1); + //R_bonemat[3][0]=R_bonemat[3][1]=R_bonemat[3][2]=0.0F; + pchan= get_pose_channel(ob->pose, curBone->name); + Mat4CpyMat4(R_bonemat, pchan->pose_mat); R_bonemat[3][0]=R_bonemat[3][1]=R_bonemat[3][2]=0.0F; - if (curBone->parent && (curBone->flag & BONE_IK_TOPARENT)){ - get_objectspace_bone_matrix(curBone->parent, R_parmat, 1, 1); + if (curBone->parent && (curBone->flag & BONE_IK_TOPARENT)) { + //get_objectspace_bone_matrix(curBone->parent, R_parmat, 1, 1); + Mat4CpyMat4(R_parmat, pchan->parent->pose_mat); + R_parmat[3][0]=R_parmat[3][1]=R_parmat[3][2]=0.0F; } @@ -1444,25 +1262,13 @@ PoseChain *ik_chain_to_posechain (Object *ob, Bone *bone) Mat3Transp((void *)segs[icurseg].basis); /* Fill out the IK segment */ - segs[icurseg].length = get_bone_length(curBone); + segs[icurseg].length = VecLenf(curBone->head, curBone->tail); - }; + } IK_LoadChain(chain->solver, segs, segcount); + return chain; } - - -void precalc_bonelist_irestmats (ListBase* bonelist) -{ - Bone *curbone; - - if (!bonelist) - return; - - for (curbone = bonelist->first; curbone; curbone=curbone->next){ - precalc_bone_irestmat(curbone); - precalc_bonelist_irestmats(&curbone->childbase); - } -} +#endif diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 2b7a5b446e5..b0f84d8d844 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -392,15 +392,6 @@ static void setup_app_data(BlendFileData *bfd, char *filename) } } - /* few DispLists, but do text_to_curve */ - // this should be removed!!! But first a better displist system (ton) - for (ob= G.main->object.first; ob; ob= ob->id.next) { - if(ob->type==OB_FONT) { - Curve *cu= ob->data; - if(cu->nurb.first==0) text_to_curve(ob, 0); - } - } - if (!G.background) { setscreen(G.curscreen); } diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index dff98c87a6f..f373c7f9062 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -73,9 +73,178 @@ void Mat4BlendMat4(float [][4], float [][4], float [][4], float ); /* Local function prototypes */ -/* Functions */ +/* ********************* Data level ****************** */ -char constraint_has_target (bConstraint *con) { +void free_constraint_data (bConstraint *con) +{ + if (con->data){ + switch (con->type){ + default: + break; + }; + + MEM_freeN (con->data); + } +} + +void free_constraints (ListBase *conlist) +{ + bConstraint *con; + + /* Do any specific freeing */ + for (con=conlist->first; con; con=con->next) + { + free_constraint_data (con); + }; + + /* Free the whole list */ + BLI_freelistN(conlist); +} + +void free_constraint_channels (ListBase *chanbase) +{ + bConstraintChannel *chan; + + for (chan=chanbase->first; chan; chan=chan->next) + { + if (chan->ipo){ + chan->ipo->id.us--; + } + } + + BLI_freelistN(chanbase); +} + +void relink_constraints (struct ListBase *list) +{ + bConstraint *con; + + for (con = list->first; con; con=con->next){ + switch (con->type){ + case CONSTRAINT_TYPE_KINEMATIC: + { + bKinematicConstraint *data; + data = con->data; + + ID_NEW(data->tar); + } + break; + case CONSTRAINT_TYPE_NULL: + { + } + break; + case CONSTRAINT_TYPE_TRACKTO: + { + bTrackToConstraint *data; + data = con->data; + + ID_NEW(data->tar); + } + break; + case CONSTRAINT_TYPE_LOCKTRACK: + { + bLockTrackConstraint *data; + data = con->data; + + ID_NEW(data->tar); + } + break; + case CONSTRAINT_TYPE_ACTION: + { + bActionConstraint *data; + data = con->data; + + ID_NEW(data->tar); + } + break; + case CONSTRAINT_TYPE_LOCLIKE: + { + bLocateLikeConstraint *data; + data = con->data; + + ID_NEW(data->tar); + } + break; + case CONSTRAINT_TYPE_ROTLIKE: + { + bRotateLikeConstraint *data; + data = con->data; + + ID_NEW(data->tar); + } + break; + case CONSTRAINT_TYPE_FOLLOWPATH: + { + bFollowPathConstraint *data; + data = con->data; + + ID_NEW(data->tar); + } + break; + case CONSTRAINT_TYPE_STRETCHTO: + { + bStretchToConstraint *data; + data = con->data; + + ID_NEW(data->tar); + } + break; + + } + } +} + +void *copy_constraint_channels (ListBase *dst, ListBase *src) +{ + bConstraintChannel *dchan, *schan; + bConstraintChannel *newact=NULL; + + dst->first=dst->last=NULL; + duplicatelist(dst, src); + + for (dchan=dst->first, schan=src->first; dchan; dchan=dchan->next, schan=schan->next){ + dchan->ipo = copy_ipo(schan->ipo); + } + + return newact; +} + +bConstraintChannel *clone_constraint_channels (ListBase *dst, ListBase *src, bConstraintChannel *oldact) +{ + bConstraintChannel *dchan, *schan; + bConstraintChannel *newact=NULL; + + dst->first=dst->last=NULL; + duplicatelist(dst, src); + + for (dchan=dst->first, schan=src->first; dchan; dchan=dchan->next, schan=schan->next){ + id_us_plus((ID *)dchan->ipo); + if (schan==oldact) + newact=dchan; + } + + return newact; +} + +void copy_constraints (ListBase *dst, ListBase *src) +{ + bConstraint *con; + + dst->first= dst->last= NULL; + + duplicatelist (dst, src); + + for (con = dst->first; con; con=con->next) { + con->data = MEM_dupallocN (con->data); + /* removed a whole lot of useless code here (ton) */ + } +} + + +/* **************** Editor Functions **************** */ + +char constraint_has_target (bConstraint *con) +{ switch (con->type){ case CONSTRAINT_TYPE_TRACKTO: { @@ -137,7 +306,7 @@ char constraint_has_target (bConstraint *con) { return 0; } -Object *get_constraint_target(bConstraint *con) +Object *get_constraint_target(bConstraint *con, char **subtarget) { /* * If the target for this constraint is target, return a pointer @@ -147,48 +316,56 @@ Object *get_constraint_target(bConstraint *con) case CONSTRAINT_TYPE_ACTION: { bActionConstraint *data = con->data; + *subtarget= data->subtarget; return data->tar; } break; case CONSTRAINT_TYPE_LOCLIKE: { bLocateLikeConstraint *data = con->data; + *subtarget= data->subtarget; return data->tar; } break; case CONSTRAINT_TYPE_ROTLIKE: { bRotateLikeConstraint *data = con->data; + *subtarget= data->subtarget; return data->tar; } break; case CONSTRAINT_TYPE_KINEMATIC: { bKinematicConstraint *data = con->data; + *subtarget= data->subtarget; return data->tar; } break; case CONSTRAINT_TYPE_TRACKTO: { bTrackToConstraint *data = con->data; + *subtarget= data->subtarget; return data->tar; } break; case CONSTRAINT_TYPE_LOCKTRACK: { bLockTrackConstraint *data = con->data; + *subtarget= data->subtarget; return data->tar; } break; case CONSTRAINT_TYPE_FOLLOWPATH: { bFollowPathConstraint *data = con->data; + *subtarget= NULL; return data->tar; } break; case CONSTRAINT_TYPE_STRETCHTO: { bStretchToConstraint *data = con->data; + *subtarget= data->subtarget; return (data->tar); } break; @@ -197,7 +374,65 @@ Object *get_constraint_target(bConstraint *con) return NULL; } -void unique_constraint_name (bConstraint *con, ListBase *list){ +void set_constraint_target(bConstraint *con, Object *ob) +{ + /* + * Set the target for this constraint + */ + switch (con->type) { + case CONSTRAINT_TYPE_ACTION: + { + bActionConstraint *data = con->data; + data->tar= ob; + } + break; + case CONSTRAINT_TYPE_LOCLIKE: + { + bLocateLikeConstraint *data = con->data; + data->tar= ob; + } + break; + case CONSTRAINT_TYPE_ROTLIKE: + { + bRotateLikeConstraint *data = con->data; + data->tar= ob; + } + break; + case CONSTRAINT_TYPE_KINEMATIC: + { + bKinematicConstraint *data = con->data; + data->tar= ob; + } + break; + case CONSTRAINT_TYPE_TRACKTO: + { + bTrackToConstraint *data = con->data; + data->tar= ob; + } + break; + case CONSTRAINT_TYPE_LOCKTRACK: + { + bLockTrackConstraint *data = con->data; + data->tar= ob; + } + break; + case CONSTRAINT_TYPE_FOLLOWPATH: + { + bFollowPathConstraint *data = con->data; + data->tar= ob; + } + break; + case CONSTRAINT_TYPE_STRETCHTO: + { + bStretchToConstraint *data = con->data; + data->tar= ob; + } + break; + } +} + +void unique_constraint_name (bConstraint *con, ListBase *list) +{ char tempname[64]; int number; char *dot; @@ -241,9 +476,9 @@ void unique_constraint_name (bConstraint *con, ListBase *list){ } } -void *new_constraint_data (short type) +void *new_constraint_data (short type) { - void *result; + void *result; switch (type){ case CONSTRAINT_TYPE_KINEMATIC: @@ -252,7 +487,7 @@ void *new_constraint_data (short type) data = MEM_callocN(sizeof(bKinematicConstraint), "kinematicConstraint"); data->tolerance = (float)0.001; - data->iterations = 500; + data->iterations = 50; result = data; } @@ -344,23 +579,27 @@ void *new_constraint_data (short type) return result; } -bConstraintChannel *find_constraint_channel (ListBase *list, const char *name){ +bConstraintChannel *find_constraint_channel (ListBase *list, const char *name) +{ bConstraintChannel *chan; - for (chan = list->first; chan; chan=chan->next){ - if (!strcmp(name, chan->name)){ + for (chan = list->first; chan; chan=chan->next) { + if (!strcmp(name, chan->name)) { return chan; } } return NULL; } +/* ***************** Evaluating ********************* */ + +/* does ipos only */ void do_constraint_channels (ListBase *conbase, ListBase *chanbase, float ctime) { bConstraint *con; bConstraintChannel *chan; - IpoCurve *icu; - + IpoCurve *icu=NULL; + for (con=conbase->first; con; con=con->next){ chan = find_constraint_channel(chanbase, con->name); if (chan && chan->ipo){ @@ -421,94 +660,33 @@ void Mat4BlendMat4(float out[][4], float dst[][4], float src[][4], float srcweig static void constraint_target_to_mat4 (Object *ob, const char *substring, float mat[][4], float size[3], float ctime) { - /* Update the location of the target object */ - //where_is_object_time (ob, ctime); - /* Case OBJECT */ - if (!strlen(substring)){ + if (!strlen(substring)) { Mat4CpyMat4 (mat, ob->obmat); - VECCOPY (size, ob->size); - return; + VECCOPY (size, ob->size); // whats this for, hack! (ton) } - /* Case BONE */ else { - bArmature *arm; - Bone *bone; - float bmat[4][4]; + bPoseChannel *pchan; float bsize[3]={1, 1, 1}; - arm = get_armature(ob); - - /** - * Locate the bone (if there is one) - * Ensures that the bone's transformation is fully constrained - * (Cyclical relationships are disallowed elsewhere) - */ - bone = get_named_bone(arm, substring); - if (bone){ - where_is_bone_time(ob, bone, ctime); - get_objectspace_bone_matrix(bone, bmat, 1, 1); - VECCOPY(bsize, bone->size); + pchan = get_pose_channel(ob->pose, substring); + if (pchan){ + /** + * Multiply the objectspace bonematrix by the skeletons's global + * transform to obtain the worldspace transformation of the target + */ + Mat4MulMat4 (mat, pchan->pose_mat, ob->obmat); } else - Mat4One (bmat); - - /** - * Multiply the objectspace bonematrix by the skeletons's global - * transform to obtain the worldspace transformation of the target - */ - VECCOPY(size, bsize); - Mat4MulMat4 (mat, bmat, ob->obmat); - - return; - } -} - -void clear_object_constraint_status (Object *ob) -{ - bConstraint *con; + Mat4CpyMat4 (mat, ob->obmat); - if (!ob) return; - - /* Clear the object's constraints */ - for (con = ob->constraints.first; con; con=con->next){ - con->flag &= ~CONSTRAINT_DONE; - } - - /* Clear the object's subdata constraints */ - switch (ob->type){ - case OB_ARMATURE: - { - clear_pose_constraint_status (ob); - } - break; - default: - break; - } -} - -void clear_all_constraints(void) -{ - Base *base; - - /* Clear the constraint "done" flags -- this must be done - * before displists are calculated for objects that are - * deformed by armatures */ - for (base = G.scene->base.first; base; base=base->next){ - clear_object_constraint_status(base->object); - } -} - -void rebuild_all_armature_displists(void) { - Base *base; - - for (base = G.scene->base.first; base; base=base->next){ - clear_object_constraint_status(base->object); - make_displists_by_armature(base->object); + VECCOPY(size, bsize); // whats this for, hack! (ton) } } +/* called during solve_constraints */ +/* also for make_parent, to find correct inverse of "follow path" */ short get_constraint_target_matrix (bConstraint *con, short ownertype, void* ownerdata, float mat[][4], float size[3], float ctime) { short valid=0; @@ -531,13 +709,11 @@ short get_constraint_target_matrix (bConstraint *con, short ownertype, void* own float s,t; Bone *curBone; Bone tbone; - int i; +// int i; curBone = (Bone*)ownerdata; if (data->tar){ - /* Update the location of the target object */ - where_is_object_time (data->tar, ctime); constraint_target_to_mat4(data->tar, data->subtarget, tempmat, size, ctime); valid=1; } @@ -582,26 +758,26 @@ short get_constraint_target_matrix (bConstraint *con, short ownertype, void* own pose = MEM_callocN(sizeof(bPose), "pose"); verify_pose_channel(pose, curBone->name); - get_pose_from_action (&pose, data->act, t); + extract_pose_from_action (pose, data->act, t); /* Find the appropriate channel */ pchan = get_pose_channel(pose, curBone->name); if (pchan){ memset(&tbone, 0x00, sizeof(Bone)); - VECCOPY (tbone.loc, pchan->loc); - VECCOPY (tbone.size, pchan->size); - for (i=0; i<4; i++) - tbone.quat[i]=pchan->quat[i]; - - bone_to_mat4(&tbone, mat); +// VECCOPY (tbone.loc, pchan->loc); +// VECCOPY (tbone.size, pchan->size); +// for (i=0; i<4; i++) +// tbone.quat[i]=pchan->quat[i]; +// +// bone_to_mat4(&tbone, mat); } else{ Mat4One(mat); } /* Clean up */ - clear_pose(pose); + free_pose_channels(pose); MEM_freeN(pose); } @@ -612,8 +788,6 @@ short get_constraint_target_matrix (bConstraint *con, short ownertype, void* own bLocateLikeConstraint *data = (bLocateLikeConstraint*)con->data; if (data->tar){ - /* Update the location of the target object */ - where_is_object_time (data->tar, ctime); constraint_target_to_mat4(data->tar, data->subtarget, mat, size, ctime); valid=1; } @@ -627,8 +801,6 @@ short get_constraint_target_matrix (bConstraint *con, short ownertype, void* own data = (bRotateLikeConstraint*)con->data; if (data->tar){ - /* Update the location of the target object */ - where_is_object_time (data->tar, ctime); constraint_target_to_mat4(data->tar, data->subtarget, mat, size, ctime); valid=1; } @@ -642,9 +814,6 @@ short get_constraint_target_matrix (bConstraint *con, short ownertype, void* own data = (bTrackToConstraint*)con->data; if (data->tar){ - // Refresh the object if it isn't a constraint loop - if (!(con->flag & CONSTRAINT_NOREFRESH)) - where_is_object_time (data->tar, ctime); constraint_target_to_mat4(data->tar, data->subtarget, mat, size, ctime); valid=1; } @@ -654,12 +823,10 @@ short get_constraint_target_matrix (bConstraint *con, short ownertype, void* own break; case CONSTRAINT_TYPE_KINEMATIC: { - bTrackToConstraint *data; - data = (bTrackToConstraint*)con->data; + bKinematicConstraint *data; + data = (bKinematicConstraint*)con->data; if (data->tar){ - /* Update the location of the target object */ - where_is_object_time (data->tar, ctime); constraint_target_to_mat4(data->tar, data->subtarget, mat, size, ctime); valid=1; } @@ -673,10 +840,6 @@ short get_constraint_target_matrix (bConstraint *con, short ownertype, void* own data = (bLockTrackConstraint*)con->data; if (data->tar){ - // Refresh the object if it isn't a constraint loop - if (!(con->flag & CONSTRAINT_NOREFRESH)) - where_is_object_time (data->tar, ctime); - constraint_target_to_mat4(data->tar, data->subtarget, mat, size, ctime); valid=1; } @@ -690,33 +853,17 @@ short get_constraint_target_matrix (bConstraint *con, short ownertype, void* own data = (bFollowPathConstraint*)con->data; if (data->tar){ - short OldFlag; Curve *cu; float q[4], vec[4], dir[3], *quat, x1, totmat[4][4]; float curvetime; - where_is_object_time (data->tar, ctime); - Mat4One (totmat); Mat4One (mat); cu= data->tar->data; - OldFlag = cu->flag; - - if(data->followflag) { - if(!(cu->flag & CU_FOLLOW)) cu->flag += CU_FOLLOW; - } - else { - if(cu->flag & CU_FOLLOW) cu->flag -= CU_FOLLOW; - } - - if(!(cu->flag & CU_PATH)) cu->flag += CU_PATH; - - if(cu->path==NULL) - calc_curvepath(data->tar); - else if (cu->path->data==NULL) - calc_curvepath(data->tar); + /* note; when creating constraints that follow path, the curve gets the CU_PATH set now, + currently for paths to work it needs to go through the bevlist/displist system (ton) */ if(cu->path && cu->path->data) { curvetime= bsystem_time(data->tar, data->tar->parent, (float)ctime, 0.0) - data->offset; @@ -746,7 +893,6 @@ short get_constraint_target_matrix (bConstraint *con, short ownertype, void* own Mat4MulSerie(mat, data->tar->obmat, totmat, NULL, NULL, NULL, NULL, NULL, NULL); } } - cu->flag = OldFlag; valid=1; } else @@ -759,7 +905,6 @@ short get_constraint_target_matrix (bConstraint *con, short ownertype, void* own data = (bStretchToConstraint*)con->data; if (data->tar){ - where_is_object_time (data->tar, ctime); constraint_target_to_mat4(data->tar, data->subtarget, mat, size, ctime); valid = 1; } @@ -776,209 +921,10 @@ short get_constraint_target_matrix (bConstraint *con, short ownertype, void* own return valid; } -void relink_constraints (struct ListBase *list) -{ - bConstraint *con; - - for (con = list->first; con; con=con->next){ - switch (con->type){ - case CONSTRAINT_TYPE_KINEMATIC: - { - bKinematicConstraint *data; - data = con->data; - - ID_NEW(data->tar); - } - break; - case CONSTRAINT_TYPE_NULL: - { - } - break; - case CONSTRAINT_TYPE_TRACKTO: - { - bTrackToConstraint *data; - data = con->data; - - ID_NEW(data->tar); - } - break; - case CONSTRAINT_TYPE_LOCKTRACK: - { - bLockTrackConstraint *data; - data = con->data; - - ID_NEW(data->tar); - } - break; - case CONSTRAINT_TYPE_ACTION: - { - bActionConstraint *data; - data = con->data; - - ID_NEW(data->tar); - } - break; - case CONSTRAINT_TYPE_LOCLIKE: - { - bLocateLikeConstraint *data; - data = con->data; - - ID_NEW(data->tar); - } - break; - case CONSTRAINT_TYPE_ROTLIKE: - { - bRotateLikeConstraint *data; - data = con->data; - - ID_NEW(data->tar); - } - break; - case CONSTRAINT_TYPE_FOLLOWPATH: - { - bFollowPathConstraint *data; - data = con->data; - - ID_NEW(data->tar); - } - break; - case CONSTRAINT_TYPE_STRETCHTO: - { - bStretchToConstraint *data; - data = con->data; - - ID_NEW(data->tar); - } - break; - - } - } -} - -void *copy_constraint_channels (ListBase *dst, ListBase *src) -{ - bConstraintChannel *dchan, *schan; - bConstraintChannel *newact=NULL; - - dst->first=dst->last=NULL; - duplicatelist(dst, src); - - for (dchan=dst->first, schan=src->first; dchan; dchan=dchan->next, schan=schan->next){ - dchan->ipo = copy_ipo(schan->ipo); - } - - return newact; -} - -bConstraintChannel *clone_constraint_channels (ListBase *dst, ListBase *src, bConstraintChannel *oldact) -{ - bConstraintChannel *dchan, *schan; - bConstraintChannel *newact=NULL; - - dst->first=dst->last=NULL; - duplicatelist(dst, src); - - for (dchan=dst->first, schan=src->first; dchan; dchan=dchan->next, schan=schan->next){ - id_us_plus((ID *)dchan->ipo); - if (schan==oldact) - newact=dchan; - } - - return newact; -} - -void copy_constraints (ListBase *dst, ListBase *src) -{ - bConstraint *con; - - dst->first=dst->last=NULL; - - duplicatelist (dst, src); - - /* Update specific data */ - if (!dst->first) - return; - - for (con = dst->first; con; con=con->next){ - switch (con->type){ - case CONSTRAINT_TYPE_ACTION: - { - bActionConstraint *data; - - con->data = MEM_dupallocN (con->data); - data = (bActionConstraint*) con->data; - } - break; - case CONSTRAINT_TYPE_LOCLIKE: - { - bLocateLikeConstraint *data; - - con->data = MEM_dupallocN (con->data); - data = (bLocateLikeConstraint*) con->data; - } - break; - case CONSTRAINT_TYPE_ROTLIKE: - { - bRotateLikeConstraint *data; - - con->data = MEM_dupallocN (con->data); - data = (bRotateLikeConstraint*) con->data; - } - break; - case CONSTRAINT_TYPE_NULL: - { - con->data = NULL; - } - break; - case CONSTRAINT_TYPE_TRACKTO: - { - bTrackToConstraint *data; - - con->data = MEM_dupallocN (con->data); - data = (bTrackToConstraint*) con->data; - } - break; - case CONSTRAINT_TYPE_LOCKTRACK: - { - bLockTrackConstraint *data; - - con->data = MEM_dupallocN (con->data); - data = (bLockTrackConstraint*) con->data; - } - break; - case CONSTRAINT_TYPE_KINEMATIC: - { - bKinematicConstraint *data; - - con->data = MEM_dupallocN (con->data); - data = (bKinematicConstraint*) con->data; - } - break; - case CONSTRAINT_TYPE_FOLLOWPATH: - { - bFollowPathConstraint *data; - - con->data = MEM_dupallocN (con->data); - data = (bFollowPathConstraint*) con->data; - } - break; - case CONSTRAINT_TYPE_STRETCHTO: - { - bStretchToConstraint *data; - - con->data = MEM_dupallocN (con->data); - data = (bStretchToConstraint*) con->data; - } - break; - default: - con->data = MEM_dupallocN (con->data); - break; - } - } -} +/* only called during solve_constraints */ +/* bone constraints create a fake object to work on, then ob is a workob */ void evaluate_constraint (bConstraint *constraint, Object *ob, short ownertype, void *ownerdata, float targetmat[][4]) -/* ob is likely to be a workob */ { float M_oldmat[4][4]; float M_identity[4][4]; @@ -988,11 +934,6 @@ void evaluate_constraint (bConstraint *constraint, Object *ob, short ownertype, Mat4One (M_identity); - /* We've already been calculated */ - if (constraint->flag & CONSTRAINT_DONE){ - return; - } - switch (constraint->type){ case CONSTRAINT_TYPE_ACTION: { @@ -1088,6 +1029,7 @@ void evaluate_constraint (bConstraint *constraint, Object *ob, short ownertype, break; case CONSTRAINT_TYPE_KINEMATIC: { +#if 0 bKinematicConstraint *data; float imat[4][4]; float temp[4][4]; @@ -1111,15 +1053,19 @@ void evaluate_constraint (bConstraint *constraint, Object *ob, short ownertype, chain->tolerance = data->tolerance; - { + if(0) { + bPoseChannel *pchan= get_pose_channel(armob->pose, curBone->name); float parmat[4][4]; /* Take the obmat to objectspace */ - Mat4CpyMat4 (temp, curBone->obmat); - Mat4One (curBone->obmat); - get_objectspace_bone_matrix(curBone, parmat, 1, 1); - Mat4CpyMat4 (curBone->obmat, temp); - Mat4MulMat4 (totmat, parmat, ob->parent->obmat); + +// Mat4CpyMat4 (temp, curBone->obmat); +// Mat4One (curBone->obmat); +// get_objectspace_bone_matrix(curBone, parmat, 1, 1); + Mat4CpyMat4(parmat, pchan->pose_mat); + +// Mat4CpyMat4 (curBone->obmat, temp); + Mat4MulMat4 (totmat, parmat, armob->obmat); Mat4Invert (imat, totmat); @@ -1131,26 +1077,31 @@ void evaluate_constraint (bConstraint *constraint, Object *ob, short ownertype, /* Solve it */ if (chain->solver){ VECCOPY (chain->goal, targetmat[3]); - solve_posechain(chain); + solve_posechain(chain); // applies to bones/channels } free_posechain(chain); - { + if(0) { float parmat[4][4]; + bPoseChannel *pchan= get_pose_channel(armob->pose, curBone->name); /* Take the obmat to worldspace */ - Mat4CpyMat4 (temp, curBone->obmat); - Mat4One (curBone->obmat); - get_objectspace_bone_matrix(curBone, parmat, 1, 1); - Mat4CpyMat4 (curBone->obmat, temp); - Mat4MulMat4 (totmat, parmat, ob->parent->obmat); +// Mat4CpyMat4 (temp, curBone->obmat); +// Mat4One (curBone->obmat); + +// get_objectspace_bone_matrix(curBone, parmat, 1, 1); + Mat4CpyMat4(parmat, pchan->pose_mat); + +// Mat4CpyMat4 (curBone->obmat, temp); + Mat4MulMat4 (totmat, parmat, armob->obmat); Mat4CpyMat4 (temp, ob->obmat); Mat4MulMat4 (ob->obmat, temp, totmat); } } +#endif } break; case CONSTRAINT_TYPE_LOCKTRACK: @@ -1481,7 +1432,7 @@ void evaluate_constraint (bConstraint *constraint, Object *ob, short ownertype, data=(bFollowPathConstraint*)constraint->data; if (data->tar) { - + // weird, this is needed? doesnt work for workob (ton) object_to_mat4(ob, obmat); Mat4MulSerie(ob->obmat, targetmat, obmat, NULL, NULL, NULL, NULL, NULL, NULL); @@ -1617,45 +1568,4 @@ void evaluate_constraint (bConstraint *constraint, Object *ob, short ownertype, printf ("Error: Unknown constraint type\n"); break; } - -} - -void free_constraint_data (bConstraint *con) -{ - if (con->data){ - switch (con->type){ - default: - break; - }; - - MEM_freeN (con->data); - } -} - -void free_constraints (ListBase *conlist) -{ - bConstraint *con; - - /* Do any specific freeing */ - for (con=conlist->first; con; con=con->next) - { - free_constraint_data (con); - }; - - /* Free the whole list */ - BLI_freelistN(conlist); -} - -void free_constraint_channels (ListBase *chanbase) -{ - bConstraintChannel *chan; - - for (chan=chanbase->first; chan; chan=chan->next) - { - if (chan->ipo){ - chan->ipo->id.us--; - } - } - - BLI_freelistN(chanbase); } diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c index 226a1d602b7..7fe0ec626a4 100644 --- a/source/blender/blenkernel/intern/deform.c +++ b/source/blender/blenkernel/intern/deform.c @@ -54,6 +54,7 @@ #include "BKE_displist.h" #include "BKE_effect.h" #include "BKE_global.h" +#include "BKE_key.h" #include "BKE_lattice.h" #include "BKE_object.h" #include "BKE_softbody.h" @@ -237,6 +238,8 @@ int mesh_modifier(Object *ob, char mode) MVert *mv; int a, done=0; + do_mesh_key(me); + /* conditions if it's needed */ if(ob->hooks.first); else if(ob->effect.first); // weak... particles too @@ -322,6 +325,8 @@ int curve_modifier(Object *ob, char mode) BPoint *bp; int a, index, done= 0; + do_curve_key(cu); + /* conditions if it's needed */ if(ob->hooks.first); else if(ob->parent && ob->partype==PARSKEL); @@ -390,6 +395,8 @@ int lattice_modifier(Object *ob, char mode) BPoint *bp; int a, index, done= 0; + do_latt_key(lt); + /* conditions if it's needed */ if(ob->hooks.first); else if(ob->parent && ob->partype==PARSKEL); diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 668b18c0913..9f0501d54fc 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -41,17 +41,25 @@ #include "BLI_blenlib.h" #include "BLI_arithb.h" +#include "DNA_action_types.h" +#include "DNA_armature_types.h" +#include "DNA_curve_types.h" #include "DNA_ID.h" +#include "DNA_effect_types.h" +#include "DNA_lattice_types.h" +#include "DNA_mesh_types.h" #include "DNA_object_types.h" +#include "DNA_object_force.h" #include "DNA_oops_types.h" #include "DNA_scene_types.h" -#include "DNA_action_types.h" #include "DNA_screen_types.h" #include "DNA_space_types.h" #include "DNA_view2d_types.h" -#include "BKE_utildefines.h" +#include "BKE_action.h" #include "BKE_global.h" +#include "BKE_mball.h" +#include "BKE_utildefines.h" #include "MEM_guardedalloc.h" #include "blendef.h" @@ -272,18 +280,16 @@ int queue_count(struct DagNodeQueue *queue){ DagForest * dag_init() { DagForest *forest; - - forest = MEM_mallocN(sizeof(DagForest),"DAG root"); - forest->DagNode.first = NULL; - forest->DagNode.last = NULL; - forest->numNodes = 0; + /* use callocN to init all zero */ + forest = MEM_callocN(sizeof(DagForest),"DAG root"); return forest; } -struct DagForest *build_dag(struct Scene *sce, short mask) +struct DagForest *build_dag(struct Scene *sce, short mask) { Base *base; Object *ob; + bConstraint *con; DagNode * node; DagNode * node2; DagNode * node3; @@ -299,130 +305,126 @@ struct DagForest *build_dag(struct Scene *sce, short mask) sce->theDag = dag; } - // add base node for scene. scene is always the first node in DAG + /* add base node for scene. scene is always the first node in DAG */ scenenode = dag_add_node(dag, sce); - /* targets in object struct yet to be added. should even they ? - struct Ipo *ipo; - ListBase nlastrips; - ListBase hooks; - */ - - - base = sce->base.first; - while(base) { // add all objects in any case + for(base = sce->base.first; base; base= base->next) { int addtoroot = 1; ob= (Object *) base->object; node = dag_get_node(dag,ob); - if ((ob->data) && (mask&DAG_RL_DATA_MASK)) { + if ((ob->data) && (mask&DAG_RL_DATA)) { node2 = dag_get_node(dag,ob->data); dag_add_relation(dag,node,node2,DAG_RL_DATA); node2->first_ancestor = ob; node2->ancestor_count += 1; - if ((ob->type == OB_ARMATURE) && (mask&DAG_RL_DATA_CONSTRAINT_MASK)) { // add armature constraints to datas - if (ob->pose){ - bPoseChannel *pchan; - bConstraint *con; - Object * target; - - for (pchan = ob->pose->chanbase.first; pchan; pchan=pchan->next){ - for (con = pchan->constraints.first; con; con=con->next){ - if (constraint_has_target(con)) { - target = get_constraint_target(con); - if (strcmp(target->id.name, ob->id.name) != 0) { - //fprintf(stderr,"armature target :%s \n", target->id.name); - node3 = dag_get_node(dag,target); - dag_add_relation(dag,node3,node2,DAG_RL_CONSTRAINT); - } - } - } - } - } - } - if ((ob->hooks.first) && (mask&DAG_RL_HOOK)) { - ObHook *hook; + } + if (ob->type == OB_ARMATURE) { + if (ob->pose){ + bPoseChannel *pchan; + bConstraint *con; + Object * target; + char *subtarget; - for(hook= ob->hooks.first; hook; hook= hook->next) { - if(hook->parent) { - node3 = dag_get_node(dag,hook->parent); - dag_add_relation(dag,node3,node2,DAG_RL_HOOK); - } - } - } - } else { // add armature constraints to object itself - if ((ob->type == OB_ARMATURE) && (mask&DAG_RL_DATA_CONSTRAINT_MASK)) { - if (ob->pose){ - bPoseChannel *pchan; - bConstraint *con; - Object * target; - - for (pchan = ob->pose->chanbase.first; pchan; pchan=pchan->next){ - for (con = pchan->constraints.first; con; con=con->next){ - if (constraint_has_target(con)) { - target = get_constraint_target(con); - if (strcmp(target->id.name, ob->id.name) != 0) { - //fprintf(stderr,"armature target :%s \n", target->id.name); - node3 = dag_get_node(dag,target); - dag_add_relation(dag,node3,node,DAG_RL_CONSTRAINT); - } + for (pchan = ob->pose->chanbase.first; pchan; pchan=pchan->next){ + for (con = pchan->constraints.first; con; con=con->next){ + if (constraint_has_target(con)) { + target = get_constraint_target(con, &subtarget); + if (target!=ob) { + // fprintf(stderr,"armature %s target :%s \n", ob->id.name, target->id.name); + node3 = dag_get_node(dag, target); + + dag_add_relation(dag,node3,node,DAG_RL_OB_DATA); + } } } } } - if ((ob->hooks.first) && (mask&DAG_RL_HOOK)) { - ObHook *hook; - - for(hook= ob->hooks.first; hook; hook= hook->next) { - if(hook->parent) { - node3 = dag_get_node(dag,hook->parent); - dag_add_relation(dag,node3,node,DAG_RL_HOOK); - } + } + if (ob->hooks.first) { + ObHook *hook; + + for(hook= ob->hooks.first; hook; hook= hook->next) { + if(hook->parent) { + node3 = dag_get_node(dag,hook->parent); + dag_add_relation(dag,node3,node,DAG_RL_OB_DATA); } - } + } } - - if ((ob->parent) && (mask&DAG_RL_PARENT_MASK)){ + if (ob->parent) { node2 = dag_get_node(dag,ob->parent); - dag_add_relation(dag,node2,node,DAG_RL_PARENT); + + switch(ob->partype) { + case PARSKEL: + dag_add_relation(dag,node2,node,DAG_RL_DATA_DATA|DAG_RL_OB_OB); + break; + case PARVERT1: case PARVERT3: case PARBONE: + dag_add_relation(dag,node2,node,DAG_RL_DATA_OB|DAG_RL_OB_OB); + break; + default: + if(ob->parent->type==OB_LATTICE) + dag_add_relation(dag,node2,node,DAG_RL_DATA_DATA|DAG_RL_OB_OB); + else if(ob->parent->type==OB_CURVE) { + Curve *cu= ob->parent->data; + if(cu->flag & CU_PATH) + dag_add_relation(dag,node2,node,DAG_RL_DATA_OB|DAG_RL_OB_OB); + else + dag_add_relation(dag,node2,node,DAG_RL_OB_OB); + } + else + dag_add_relation(dag,node2,node,DAG_RL_OB_OB); + } addtoroot = 0; } - if ((ob->track) && (mask&DAG_RL_TRACK_MASK)){ + if (ob->track) { node2 = dag_get_node(dag,ob->track); - dag_add_relation(dag,node2,node,DAG_RL_TRACK); + dag_add_relation(dag,node2,node,DAG_RL_OB_OB); addtoroot = 0; - } - if ((ob->path) && (mask&DAG_RL_PATH_MASK)){ - node2 = dag_get_node(dag,ob->track); - dag_add_relation(dag,node2,node,DAG_RL_PATH); - addtoroot = 0; - + if (ob->type==OB_MBALL) { + Object *mom= find_basis_mball(ob); + if(mom!=ob) { + node2 = dag_get_node(dag, mom); + dag_add_relation(dag,node,node2,DAG_RL_DATA_DATA|DAG_RL_OB_DATA); // mom depends on children! + } } - - /* Count constraints */ - if (mask & DAG_RL_CONSTRAINT_MASK) { - bConstraint *con; - for (con = ob->constraints.first; con; con=con->next){ - if (constraint_has_target(con)) { - node2 = dag_get_node(dag,get_constraint_target(con)); - dag_add_relation(dag,node2,node,DAG_RL_CONSTRAINT); - addtoroot = 0; - - } + else if (ob->type==OB_CURVE) { + Curve *cu= ob->data; + if(cu->bevobj) { + node2 = dag_get_node(dag, cu->bevobj); + dag_add_relation(dag,node2,node,DAG_RL_DATA_DATA|DAG_RL_OB_DATA); } - } + if(cu->taperobj) { + node2 = dag_get_node(dag, cu->taperobj); + dag_add_relation(dag,node2,node,DAG_RL_DATA_DATA|DAG_RL_OB_DATA); + } + } + else if(ob->type==OB_FONT) { + Curve *cu= ob->data; + if(cu->textoncurve) { + node2 = dag_get_node(dag, cu->textoncurve); + dag_add_relation(dag,node2,node,DAG_RL_DATA_DATA|DAG_RL_OB_DATA); + } + } + for (con = ob->constraints.first; con; con=con->next){ + if (constraint_has_target(con)) { + char *str; + node2 = dag_get_node(dag, get_constraint_target(con, &str)); + if(con->type==CONSTRAINT_TYPE_FOLLOWPATH) + dag_add_relation(dag, node2, node, DAG_RL_DATA_OB|DAG_RL_OB_OB); + else + dag_add_relation(dag, node2, node, DAG_RL_OB_OB); + addtoroot = 0; + } + } if (addtoroot == 1 ) dag_add_relation(dag,scenenode,node,DAG_RL_SCENE); - - addtoroot = 1; - base= base->next; } // cycle detection and solving @@ -458,18 +460,20 @@ void free_forest(DagForest *Dag) DagNode * dag_find_node (DagForest *forest,void * fob) { - DagNode *node = forest->DagNode.first; - - while (node) { - if (node->ob == fob) - return node; - node = node->next; - } - return NULL; + DagNode *node = forest->DagNode.first; + + while (node) { + if (node->ob == fob) + return node; + node = node->next; + } + return NULL; } +static int ugly_hack_sorry= 1; // prevent type check + /* no checking of existance, use dag_find_node first or dag_get_node */ -DagNode * dag_add_node (DagForest *forest,void * fob) +DagNode * dag_add_node (DagForest *forest, void * fob) { DagNode *node; @@ -486,7 +490,7 @@ DagNode * dag_add_node (DagForest *forest,void * fob) node->first_ancestor = NULL; node->ancestor_count = 0; - node->type = GS(((ID *) fob)->name); + if(ugly_hack_sorry) node->type = GS(((ID *) fob)->name); // sorry, done for pose sorting if (forest->numNodes) { ((DagNode *) forest->DagNode.last)->next = node; forest->DagNode.last = node; @@ -540,7 +544,7 @@ DagNode * dag_get_sub_node (DagForest *forest,void * fob) return node; } -void dag_add_relation(DagForest *forest, DagNode *fob1, DagNode *fob2, dag_rel_type rel) +void dag_add_relation(DagForest *forest, DagNode *fob1, DagNode *fob2, short rel) { DagAdjList *itA = fob1->child; @@ -846,6 +850,7 @@ DagNodeQueue * graph_dfs(void) return(retqueue); } +/* unused */ int pre_and_post_DFS(DagForest *dag, short mask, graph_action_func pre_func, graph_action_func post_func, void **data) { DagNode *node; @@ -933,84 +938,6 @@ int pre_and_post_source_DFS(DagForest *dag, short mask, DagNode *source, graph_a return(retval); } -// sort the base list on place -void topo_sort_baselist(struct Scene *sce){ - DagNode *node; - DagNodeQueue *nqueue; - DagAdjList *itA; - int time; - int skip = 0; - ListBase tempbase; - Base *base; - - tempbase.first= tempbase.last= 0; - - build_dag(sce,DAG_RL_ALL_BUT_DATA_MASK); - - nqueue = queue_create(DAGQUEUEALLOC); - - node = sce->theDag->DagNode.first; - while(node) { - node->color = DAG_WHITE; - node = node->next; - } - - time = 1; - - node = sce->theDag->DagNode.first; - - node->color = DAG_GRAY; - time++; - push_stack(nqueue,node); - - while(nqueue->count) { - - skip = 0; - node = get_top_node_queue(nqueue); - - itA = node->child; - while(itA != NULL) { - if((itA->node->color == DAG_WHITE) ) { - itA->node->DFS_dvtm = time; - itA->node->color = DAG_GRAY; - - time++; - push_stack(nqueue,itA->node); - skip = 1; - break; - } - itA = itA->next; - } - - if (!skip) { - if (node) { - node = pop_queue(nqueue); - if (node->ob == sce) // we are done - break ; - node->color = DAG_BLACK; - - time++; - base = sce->base.first; - while (base->object != node->ob) - base = base->next; - BLI_remlink(&sce->base,base); - BLI_addhead(&tempbase,base); - } - } - } - - // temporal correction for circular dependancies - base = sce->base.first; - while (base) { - BLI_remlink(&sce->base,base); - BLI_addhead(&tempbase,base); - base = sce->base.first; - } - - sce->base = tempbase; - queue_delete(nqueue); -} - // used to get the obs owning a datablock struct DagNodeQueue *get_obparents(struct DagForest *dag, void *ob) @@ -1020,7 +947,10 @@ struct DagNodeQueue *get_obparents(struct DagForest *dag, void *ob) DagAdjList *itA; node = dag_find_node(dag,ob); - if (node->ancestor_count == 1) { // simple case + if(node==NULL) { + return NULL; + } + else if (node->ancestor_count == 1) { // simple case nqueue = queue_create(1); push_queue(nqueue,node); } else { // need to go over the whole dag for adj list @@ -1082,7 +1012,7 @@ struct DagNodeQueue *get_all_childs(struct DagForest *dag, void *ob) int skip = 0; nqueue = queue_create(DAGQUEUEALLOC); - retqueue = queue_create(MainDag->numNodes); + retqueue = queue_create(dag->numNodes); // was MainDag... why? (ton) node = dag->DagNode.first; while(node) { @@ -1092,45 +1022,47 @@ struct DagNodeQueue *get_all_childs(struct DagForest *dag, void *ob) time = 1; - node = dag_find_node(dag,ob); - - node->color = DAG_GRAY; - time++; - push_stack(nqueue,node); - - while(nqueue->count) { + node = dag_find_node(dag,ob); // could be done in loop above (ton) + if(node) { // can be null for newly added objects - skip = 0; - node = get_top_node_queue(nqueue); - - itA = node->child; - while(itA != NULL) { - if((itA->node->color == DAG_WHITE) ) { - itA->node->DFS_dvtm = time; - itA->node->color = DAG_GRAY; - - time++; - push_stack(nqueue,itA->node); - skip = 1; - break; - } - itA = itA->next; - } + node->color = DAG_GRAY; + time++; + push_stack(nqueue,node); - if (!skip) { - node = pop_queue(nqueue); - node->color = DAG_BLACK; + while(nqueue->count) { - time++; - push_stack(retqueue,node); + skip = 0; + node = get_top_node_queue(nqueue); + + itA = node->child; + while(itA != NULL) { + if((itA->node->color == DAG_WHITE) ) { + itA->node->DFS_dvtm = time; + itA->node->color = DAG_GRAY; + + time++; + push_stack(nqueue,itA->node); + skip = 1; + break; + } + itA = itA->next; + } + + if (!skip) { + node = pop_queue(nqueue); + node->color = DAG_BLACK; + + time++; + push_stack(retqueue,node); + } } } - queue_delete(nqueue); return(retqueue); } -dag_rel_type are_obs_related(struct DagForest *dag, void *ob1, void *ob2) { +/* unused */ +short are_obs_related(struct DagForest *dag, void *ob1, void *ob2) { DagNode * node; DagAdjList *itA; @@ -1211,4 +1143,434 @@ void graph_print_adj_list(void) } } +/* ************************ API *********************** */ + +/* sort the base list on dependency order */ +void DAG_scene_sort(struct Scene *sce) +{ + DagNode *node; + DagNodeQueue *nqueue; + DagAdjList *itA; + int time; + int skip = 0; + ListBase tempbase; + Base *base; + + tempbase.first= tempbase.last= NULL; + + build_dag(sce, DAG_RL_ALL_BUT_DATA); + + nqueue = queue_create(DAGQUEUEALLOC); + + node = sce->theDag->DagNode.first; + while(node) { + node->color = DAG_WHITE; + node = node->next; + } + + time = 1; + + node = sce->theDag->DagNode.first; + + node->color = DAG_GRAY; + time++; + push_stack(nqueue,node); + + while(nqueue->count) { + + skip = 0; + node = get_top_node_queue(nqueue); + + itA = node->child; + while(itA != NULL) { + if((itA->node->color == DAG_WHITE) ) { + itA->node->DFS_dvtm = time; + itA->node->color = DAG_GRAY; + + time++; + push_stack(nqueue,itA->node); + skip = 1; + break; + } + itA = itA->next; + } + + if (!skip) { + if (node) { + node = pop_queue(nqueue); + if (node->ob == sce) // we are done + break ; + node->color = DAG_BLACK; + + time++; + base = sce->base.first; + while (base->object != node->ob) + base = base->next; + BLI_remlink(&sce->base,base); + BLI_addhead(&tempbase,base); + } + } + } + + // temporal correction for circular dependancies + base = sce->base.first; + while (base) { + BLI_remlink(&sce->base,base); + BLI_addhead(&tempbase,base); + //if(G.f & G_DEBUG) + printf("cyclic %s\n", base->object->id.name); + base = sce->base.first; + } + + sce->base = tempbase; + queue_delete(nqueue); + + if(G.f & G_DEBUG) { + printf("\nordered\n"); + for(base = sce->base.first; base; base= base->next) { + printf(" %s\n", base->object->id.name); + } + } +} + +/* node was checked to have lasttime != curtime and is if type ID_OB */ +static void flush_update_node(DagNode *node, unsigned int layer, int curtime) +{ + DagAdjList *itA; + Object *ob, *obc; + int oldflag, changed=0; + unsigned int all_layer; + + node->lasttime= curtime; + + ob= node->ob; + if(ob->recalc & OB_RECALC) { + all_layer= ob->lay; + /* got an object node that changes, now check relations */ + for(itA = node->child; itA; itA= itA->next) { + all_layer |= itA->lay; + /* the relationship is visible */ + if(itA->lay & layer) { + if(itA->node->type==ID_OB) { + obc= itA->node->ob; + oldflag= obc->recalc; + + /* got a ob->obc relation, now check if flag needs flush */ + if(ob->recalc & OB_RECALC_OB) { + if(itA->type & DAG_RL_OB_OB) { + //printf("ob %s changes ob %s\n", ob->id.name, obc->id.name); + obc->recalc |= OB_RECALC_OB; + } + if(itA->type & DAG_RL_OB_DATA) { + //printf("ob %s changes obdata %s\n", ob->id.name, obc->id.name); + obc->recalc |= OB_RECALC_DATA; + } + } + if(ob->recalc & OB_RECALC_DATA) { + if(itA->type & DAG_RL_DATA_OB) { + //printf("obdata %s changes ob %s\n", ob->id.name, obc->id.name); + obc->recalc |= OB_RECALC_OB; + } + if(itA->type & DAG_RL_DATA_DATA) { + //printf("obdata %s changes obdata %s\n", ob->id.name, obc->id.name); + obc->recalc |= OB_RECALC_DATA; + } + } + if(oldflag!=obc->recalc) changed= 1; + } + } + } + /* even nicer, we can clear recalc flags... but we don't for armatures, these can have poses that need pointer checks (read old file issue) */ + if(ob->type!=OB_ARMATURE) + if((all_layer & layer)==0) + ob->recalc &= ~OB_RECALC; + } + else{ + /* Object has not RECALC flag */ + /* check case where child changes and parent forcing obdata to change */ + /* could merge this in with loop above... (ton) */ + for(itA = node->child; itA; itA= itA->next) { + /* the relationship is visible */ + if(itA->lay & layer) { + if(itA->node->type==ID_OB) { + obc= itA->node->ob; + /* child moves */ + if((obc->recalc & OB_RECALC)==OB_RECALC_OB) { + /* parent has deforming info */ + if(itA->type & (DAG_RL_OB_DATA|DAG_RL_DATA_DATA)) { + // printf("parent %s changes ob %s\n", ob->id.name, obc->id.name); + obc->recalc |= OB_RECALC_DATA; + } + } + } + } + } + } + /* we only go deeper if node not checked or something changed */ + for(itA = node->child; itA; itA= itA->next) { + if(changed || itA->node->lasttime!=curtime) + flush_update_node(itA->node, layer, curtime); + } +} + +/* node was checked to have lasttime != curtime , and is of type ID_OB */ +static unsigned int flush_layer_node(DagNode *node, int curtime) +{ + DagAdjList *itA; + + node->lasttime= curtime; + node->lay= ((Object *)node->ob)->lay; + + for(itA = node->child; itA; itA= itA->next) { + if(itA->node->type==ID_OB) { + if(itA->node->lasttime!=curtime) { + itA->lay= flush_layer_node(itA->node, curtime); // lay is only set once for each relation + //printf("layer %d for relation %s to %s\n", itA->lay, ((Object *)node->ob)->id.name, ((Object *)itA->node->ob)->id.name); + } + else itA->lay= itA->node->lay; + + node->lay |= itA->lay; + } + } + + return node->lay; +} + +/* flushes all recalc flags in objects down the dependency tree */ +void DAG_scene_flush_update(Scene *sce) +{ + DagNode *firstnode; + DagAdjList *itA; + int lasttime; + + firstnode= sce->theDag->DagNode.first; // always scene node + + /* first we flush the layer flags */ + sce->theDag->time++; // so we know which nodes were accessed + lasttime= sce->theDag->time; + for(itA = firstnode->child; itA; itA= itA->next) { + if(itA->node->lasttime!=lasttime && itA->node->type==ID_OB) + flush_layer_node(itA->node, lasttime); + } + + /* then we use the relationships + layer info to flush update events */ + sce->theDag->time++; // so we know which nodes were accessed + lasttime= sce->theDag->time; + for(itA = firstnode->child; itA; itA= itA->next) { + if(itA->node->lasttime!=lasttime && itA->node->type==ID_OB) + flush_update_node(itA->node, sce->lay, lasttime); + } +} + +/* flag all objects that need recalc, for changes in time for example */ +void DAG_scene_update_flags(Scene *sce, unsigned int lay) +{ + Base *base; + Object *ob; + + /* set ob flags where animated systems are */ + for(base= sce->base.first; base; base= base->next) { + + /* now if DagNode were part of base, the node->lay could be checked... */ + /* we do all now, since the scene_flush checks layers */ + //if((base->lay & lay)) { + ob= base->object; + + if(ob->ipo) ob->recalc |= OB_RECALC_OB; + else if(ob->constraints.first) ob->recalc |= OB_RECALC_OB; + else if(ob->scriptlink.totscript) ob->recalc |= OB_RECALC_OB; + else if(ob->parent) { + if(ob->parent->type==OB_CURVE) ob->recalc |= OB_RECALC_OB; + } + + if(ob->action) ob->recalc |= OB_RECALC_DATA; + else if(ob->nlastrips.first) ob->recalc |= OB_RECALC_DATA; + else if(ob->softflag & OB_SB_ENABLE) ob->recalc |= OB_RECALC_DATA; + else { + Mesh *me; + Curve *cu; + Lattice *lt; + + switch(ob->type) { + case OB_MESH: + me= ob->data; + if(me->key) ob->recalc |= OB_RECALC_DATA; + else if(ob->effect.first) { + Effect *eff= ob->effect.first; + if(eff->type==EFF_WAVE) ob->recalc |= OB_RECALC_DATA; + } + break; + case OB_CURVE: + case OB_SURF: + cu= ob->data; + if(cu->key) ob->recalc |= OB_RECALC_DATA; + break; + case OB_LATTICE: + lt= ob->data; + if(lt->key) ob->recalc |= OB_RECALC_DATA; + break; + } + } + //} + } + DAG_scene_flush_update(sce); +} + +/* flag this object and all its relations to recalc */ +/* if you need to do more objects, tag object yourself and + use DAG_scene_flush_update() in end */ +void DAG_object_flush_update(Scene *sce, Object *ob, short flag) +{ + Base *base; + + if(ob==NULL) return; + ob->recalc |= flag; + + /* all users of this ob->data should be checked */ + if(flag & OB_RECALC_DATA) { + ID *id= ob->data; + if(id && id->us>1) { + for (base= sce->base.first; base; base= base->next) { + if (ob->data==base->object->data) { + base->object->recalc |= OB_RECALC_DATA; + } + } + } + } + + DAG_scene_flush_update(sce); +} + +/* ******************* DAG FOR ARMATURE POSE ***************** */ + +/* we assume its an armature with pose */ +void DAG_pose_sort(Object *ob) +{ + bPose *pose= ob->pose; + bPoseChannel *pchan; + bConstraint *con; + DagNode *node; + DagNode *node2, *node3; + DagNode *rootnode; + DagForest *dag; + DagNodeQueue *nqueue; + DagAdjList *itA; + ListBase tempbase; + int skip = 0; + + dag = dag_init(); + ugly_hack_sorry= 0; // no ID structs + + rootnode = dag_add_node(dag, NULL); // node->ob becomes NULL + + /* we add the hierarchy and the constraints */ + for(pchan = pose->chanbase.first; pchan; pchan= pchan->next) { + int addtoroot = 1; + + node = dag_get_node(dag, pchan); + + if(pchan->parent) { + node2 = dag_get_node(dag, pchan->parent); + dag_add_relation(dag, node2, node, 0); + addtoroot = 0; + } + for (con = pchan->constraints.first; con; con=con->next){ + if (constraint_has_target(con)) { + char *subtarget; + Object *target = get_constraint_target(con, &subtarget); + + if (target==ob && subtarget) { + bPoseChannel *target= get_pose_channel(ob->pose, subtarget); + if(target) { + node2= dag_get_node(dag, target); + dag_add_relation(dag, node2, node, 0); + + if(con->type==CONSTRAINT_TYPE_KINEMATIC) { + bPoseChannel *par= pchan->parent; + + while(par) { + node3= dag_get_node(dag, par); + dag_add_relation(dag, node2, node3, 0); + + if(par->bone->flag & BONE_IK_TOPARENT) + par= par->parent; + else break; + } + } + } + } + } + } + if (addtoroot == 1 ) + dag_add_relation(dag, rootnode, node, 0); + } + + /* now we try to sort... */ + tempbase.first= tempbase.last= NULL; + + nqueue = queue_create(DAGQUEUEALLOC); + + /* tag nodes unchecked */ + for(node = dag->DagNode.first; node; node= node->next) + node->color = DAG_WHITE; + + node = dag->DagNode.first; + + node->color = DAG_GRAY; + push_stack(nqueue, node); + + while(nqueue->count) { + + skip = 0; + node = get_top_node_queue(nqueue); + + itA = node->child; + while(itA != NULL) { + if((itA->node->color == DAG_WHITE) ) { + itA->node->color = DAG_GRAY; + push_stack(nqueue,itA->node); + skip = 1; + break; + } + itA = itA->next; + } + + if (!skip) { + if (node) { + node = pop_queue(nqueue); + if (node->ob == NULL) // we are done + break ; + node->color = DAG_BLACK; + + /* put node in new list */ + BLI_remlink(&pose->chanbase, node->ob); + BLI_addhead(&tempbase, node->ob); + } + } + } + + // temporal correction for circular dependancies + while(pose->chanbase.first) { + pchan= pose->chanbase.first; + BLI_remlink(&pose->chanbase, pchan); + BLI_addhead(&tempbase, pchan); + + printf("cyclic %s\n", pchan->name); + } + + pose->chanbase = tempbase; + queue_delete(nqueue); + +// printf("\nordered\n"); +// for(pchan = pose->chanbase.first; pchan; pchan= pchan->next) { +// printf(" %s\n", pchan->name); +// } + + free_forest( dag ); + MEM_freeN( dag ); + + ugly_hack_sorry= 1; +} + + diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 3e4c670dd04..b2876260c15 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -238,24 +238,6 @@ void freedisplist(ListBase *lb) } } -static void freedisplist_object(Object *ob) -{ - freedisplist(&ob->disp); - - if(ob->type==OB_MESH) { - Mesh *me= ob->data; - freedisplist(&me->disp); - if (me->derived) { - me->derived->release(me->derived); - me->derived = NULL; - } - } - else if(ob->type==OB_CURVE || ob->type==OB_SURF || ob->type==OB_FONT) { - Curve *cu= ob->data; - freedisplist(&cu->disp); - } -} - DispList *find_displist_create(ListBase *lb, int type) { DispList *dl; @@ -1661,12 +1643,12 @@ void makeDispList(Object *ob) if (ob!=G.obedit) mesh_modifier(ob, 'e'); } else if(ob->type==OB_MBALL) { - ob= find_basis_mball(ob); + if(ob==find_basis_mball(ob)) { + metaball_polygonize(ob); + tex_space_mball(ob); - metaball_polygonize(ob); - tex_space_mball(ob); - - object_deform(ob); + object_deform(ob); + } } else if(ob->type==OB_SURF) { @@ -1760,6 +1742,7 @@ void makeDispList(Object *ob) if(ob!=G.obedit) object_deform(ob); } else if ELEM(ob->type, OB_CURVE, OB_FONT) { + int obedit= (G.obedit && G.obedit->data==ob->data); draw= ob->dt; cu= ob->data; @@ -1767,21 +1750,23 @@ void makeDispList(Object *ob) if(dl_onlyzero && dispbase->first) return; freedisplist(dispbase); + BLI_freelistN(&(cu->bev)); + if(cu->path) free_path(cu->path); - cu->path= 0; + cu->path= NULL; - BLI_freelistN(&(cu->bev)); + if(ob->type==OB_FONT) text_to_curve(ob, 0); - if(ob!=G.obedit) curve_modifier(ob, 's'); + if(!obedit) curve_modifier(ob, 's'); - if(ob==G.obedit) { + if(obedit) { if(ob->type==OB_CURVE) curve_to_displist(&editNurb, dispbase); else curve_to_displist(&cu->nurb, dispbase); - if(cu->flag & CU_PATH) makeBevelList(ob); + makeBevelList(ob); // always needed, so calc_curvepath() can work } else if(cu->ext1==0.0 && cu->ext2==0.0 && cu->bevobj==NULL && cu->width==1.0) { curve_to_displist(&cu->nurb, dispbase); - if(cu->flag & CU_PATH) makeBevelList(ob); + makeBevelList(ob); // always needed, so calc_curvepath() can work } else { @@ -1893,10 +1878,12 @@ void makeDispList(Object *ob) freedisplist(&dlbev); } } + if(cu->flag & CU_PATH) calc_curvepath(ob); - if(ob!=G.obedit) curve_modifier(ob, 'e'); - if(ob!=G.obedit) object_deform(ob); - + if(!obedit) { + curve_modifier(ob, 'e'); + object_deform(ob); + } tex_space_curve(cu); } @@ -2203,142 +2190,6 @@ void imagestodisplist(void) allqueue(REDRAWVIEW3D, 0); } -/* on frame change */ -/* new method: only frees displists, and relies on - drawobject.c & convertscene.c to build it when needed -*/ -void test_all_displists(void) -{ - Base *base; - Object *ob; - unsigned int lay; - int makedisp, freedisp; - - /* background */ - lay= G.scene->lay; - - /* clear flags, we use them because parent->parents are evaluated too */ - base= G.scene->base.first; - while(base) { - if(base->lay & lay) { - base->object->flag &= ~(BA_DISP_UPDATE|BA_WHERE_UPDATE); - } - if(base->next==0 && G.scene->set && base==G.scene->base.last) base= G.scene->set->base.first; - else base= base->next; - } - - base= G.scene->base.first; - while(base) { - if(base->lay & lay) { - ob= base->object; - makedisp= freedisp= 0; - - if(ob->type==OB_MBALL && (ob->ipo || ob->parent)) { - // find metaball object holding the displist - // WARNING: if more metaballs have IPO's the displist - // is recalculated to often... do we free the displist - // and rely on the drawobject.c to build it again when needed - - if(ob->disp.first == NULL) { - ob= find_basis_mball(ob); - } - makedisp= 1; - } - else if(ob->parent) { - - if (ob->parent->type == OB_LATTICE) - freedisp= 1; - else if ((ob->parent->type==OB_ARMATURE) && (ob->partype == PARSKEL)) - makedisp= 1; - else if(ob->softflag & OB_SB_ENABLE) - makedisp= 1; - else if ((ob->parent->type==OB_CURVE) && (ob->partype == PARSKEL)) - freedisp= 1; - else if(ob->partype==PARVERT1 || ob->partype==PARVERT3) { - if(ob->parent->parent) - ob->parent->flag |= BA_DISP_UPDATE; - else if(ob->parent->effect.first) // stupid test for wave - ob->parent->flag |= BA_DISP_UPDATE; - } - } - - if(ob->hooks.first) { - ObHook *hook; - for(hook= ob->hooks.first; hook; hook= hook->next) { - if(hook->parent) - freedisp= 1; - break; - } - } - - if(ob->softflag & OB_SB_ENABLE) freedisplist_object(ob); - /* warn, ob pointer changed in case of OB_MALL */ - - if ELEM(ob->type, OB_CURVE, OB_SURF) { - if(ob!=G.obedit) { - Curve *cu= ob->data; - - if(cu->key ) makedisp= 1; - if(cu->bevobj) { - Curve *cu1= cu->bevobj->data; - if(cu1->key ) freedisp= 1; - } - if(cu->taperobj) { - Curve *cu1= cu->taperobj->data; - if(cu1->key ) freedisp= 1; - } - } - } - else if(ob->type==OB_FONT) { - Curve *cu= ob->data; - if(cu->textoncurve) { - if( ((Curve *)cu->textoncurve->data)->key ) { - text_to_curve(ob, 0); - freedisp= 1; - } - } - } - else if(ob->type==OB_MESH) { - if(ob->effect.first) { - Effect *eff= ob->effect.first; - while(eff) { - if(eff->type==EFF_WAVE) { - freedisp= 1; - break; - } - eff= eff->next; - } - } - if(ob!=G.obedit) { - if(( ((Mesh *)(ob->data))->key )) - freedisp= 1; - } - } - if(freedisp) ob->flag |= BA_WHERE_UPDATE; - if(makedisp) ob->flag |= BA_DISP_UPDATE; - } - if(base->next==0 && G.scene->set && base==G.scene->base.last) base= G.scene->set->base.first; - else base= base->next; - } - - /* going over the flags to free or make displists */ - base= G.scene->base.first; - while(base) { - if(base->lay & lay) { - ob= base->object; - if(ob->flag & BA_DISP_UPDATE) { - where_is_object(ob); - makeDispList(ob); - } - else if(ob->flag & BA_WHERE_UPDATE) freedisplist_object(ob); - } - if(base->next==0 && G.scene->set && base==G.scene->base.last) base= G.scene->set->base.first; - else base= base->next; - } - -} - - void boundbox_displist(Object *ob) { BoundBox *bb=0; diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index dc2594079f2..aca3d38a98e 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -1314,7 +1314,7 @@ void build_particle_system(Object *ob) do_ob_key(par); if(par->type==OB_ARMATURE) { do_all_actions(par); // only does this object actions - clear_object_constraint_status(par); // mysterious call, otherwise do_actions doesnt work??? +// clear_object_constraint_status(par); // mysterious call, otherwise do_actions doesnt work??? } par= par->parent; } @@ -1394,7 +1394,7 @@ void build_particle_system(Object *ob) if(par->type==OB_ARMATURE) { do_all_actions(par); // only does this object actions - clear_object_constraint_status(par); // mysterious call, otherwise do_actions doesnt work??? +// clear_object_constraint_status(par); // mysterious call, otherwise do_actions doesnt work??? } par= par->parent; } diff --git a/source/blender/blenkernel/intern/exotic.c b/source/blender/blenkernel/intern/exotic.c index a371edcf954..b49143ff48f 100644 --- a/source/blender/blenkernel/intern/exotic.c +++ b/source/blender/blenkernel/intern/exotic.c @@ -1028,7 +1028,6 @@ static void read_videoscape_nurbs(char *str) } } fclose(fp); - makeDispList(ob); } static void read_videoscape(char *str) diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c index 5305dfb56ec..61869e47040 100644 --- a/source/blender/blenkernel/intern/font.c +++ b/source/blender/blenkernel/intern/font.c @@ -510,8 +510,6 @@ struct chartrans *text_to_curve(Object *ob, int mode) ct++; } - - cu->lines= 1; ct= chartransdata; for (i= 0; i<=slen; i++, mem++, ct++) { @@ -562,7 +560,7 @@ struct chartrans *text_to_curve(Object *ob, int mode) oldflag= cucu->flag; cucu->flag |= (CU_PATH+CU_FOLLOW); - if(cucu->path==0) calc_curvepath(cu->textoncurve); + if(cucu->path==NULL) makeDispList(cu->textoncurve); if(cucu->path) { diff --git a/source/blender/blenkernel/intern/ika.c b/source/blender/blenkernel/intern/ika.c deleted file mode 100644 index 32903590043..00000000000 --- a/source/blender/blenkernel/intern/ika.c +++ /dev/null @@ -1,596 +0,0 @@ - -/* ika.c - * - * - * $Id$ - * - * ***** BEGIN GPL/BL DUAL 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. The Blender - * Foundation also sells licenses for use in proprietary software under - * the Blender License. See http://www.blender.org/BL/ for information - * about this. - * - * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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/BL DUAL LICENSE BLOCK ***** - */ - -#include <math.h> -#include <stdlib.h> - -#include "MEM_guardedalloc.h" - -/* types */ -#include "DNA_ika_types.h" -#include "DNA_object_types.h" -#include "DNA_scene_types.h" -#include "DNA_view3d_types.h" - -#include "BLI_blenlib.h" -#include "BLI_arithb.h" -/* functions */ -#include "BKE_blender.h" -#include "BKE_library.h" -#include "BKE_global.h" -#include "BKE_main.h" -#include "BKE_object.h" -#include "BKE_ika.h" - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -/* Let's go! */ -#define TOLER 0.000076 -#define CLAMP(a, b, c) if((a)<(b)) (a)=(b); else if((a)>(c)) (a)=(c) - - -void unlink_ika(Ika *ika) -{ - - -} - -/* do not free Ika itself */ -void free_ika(Ika *ika) -{ - - /* unimplemented!!! */ - unlink_ika(ika); - - BLI_freelistN(&ika->limbbase); - - if(ika->def) MEM_freeN(ika->def); -} - -Ika *add_ika() -{ - Ika *ika; - - ika= alloc_libblock(&G.main->ika, ID_IK, "Ika"); - ika->flag = IK_GRABEFF | IK_XYCONSTRAINT; - - ika->xyconstraint= 0.5f; - ika->mem= 0.3f; - ika->iter= 6; - - return ika; -} - -Ika *copy_ika(Ika *ika) -{ - Ika *ikan; - - ikan= copy_libblock(ika); - - duplicatelist(&ikan->limbbase, &ika->limbbase); - - ikan->def= MEM_dupallocN(ikan->def); - - return ikan; -} - -void make_local_ika(Ika *ika) -{ - Object *ob; - Ika *ikan; - int local=0, lib=0; - - /* - only lib users: dont do - * - only local users: set flag - * - mixed: copy - */ - - if(ika->id.lib==0) return; - if(ika->id.us==1) { - ika->id.lib= 0; - ika->id.flag= LIB_LOCAL; - new_id(0, (ID *)ika, 0); - return; - } - - ob= G.main->object.first; - while(ob) { - if(ob->data==ika) { - if(ob->id.lib) lib= 1; - else local= 1; - } - ob= ob->id.next; - } - - if(local && lib==0) { - ika->id.lib= 0; - ika->id.flag= LIB_LOCAL; - new_id(0, (ID *)ika, 0); - } - else if(local && lib) { - ikan= copy_ika(ika); - ikan->id.us= 0; - - ob= G.main->object.first; - while(ob) { - if(ob->data==ika) { - - if(ob->id.lib==0) { - ob->data= ikan; - ikan->id.us++; - ika->id.us--; - } - } - ob= ob->id.next; - } - } -} - -int count_limbs(Object *ob) -{ - int tot=0; - Ika *ika; - Limb *li; - - if(ob->type!=OB_IKA) return 0; - ika= ob->data; - - li= ika->limbbase.first; - while(li) { - tot++; - li= li->next; - } - return tot; -} - -/* ************************************************** */ - - -/* using eff[ ] and len and alpha */ -void calc_limb(Limb *li) -{ - Limb *prev= li; - float vec[2], alpha= 0.0; - - /* alpha from 'parents' */ - while( (prev=prev->prev) ) { - alpha+= prev->alpha; - } - - if(li->prev) { - vec[0]= -li->prev->eff[0]; - vec[1]= -li->prev->eff[1]; - } - else vec[0]= vec[1]= 0.0; - - vec[0]+= li->eff[0]; - vec[1]+= li->eff[1]; - - li->alpha= (float)atan2(vec[1], vec[0]) - alpha; - li->len= (float)sqrt(vec[0]*vec[0] + vec[1]*vec[1]); - -} - -/* using len and alpha the endpoints are calculated */ -void calc_ika(Ika *ika, Limb *li) -{ - float alpha=0.0, co, si; - - if(li) { - Limb *prev= li; - while((prev=prev->prev)) { - alpha+= prev->alpha; - } - } - else li= ika->limbbase.first; - - while(li) { - if(li->alpha != li->alpha) li->alpha= 0.0f; /* NaN patch */ - - alpha+= li->alpha; - - co= (float)cos(alpha); - si= (float)sin(alpha); - - li->eff[0]= co*li->len; - li->eff[1]= si*li->len; - - if(li->prev) { - li->eff[0]+= li->prev->eff[0]; - li->eff[1]+= li->prev->eff[1]; - } - - if(li->next==0) { - ika->eff[0]= li->eff[0]; - ika->eff[1]= li->eff[1]; - } - - li= li->next; - } -} - -void init_defstate_ika(Object *ob) -{ - Ika *ika; - Limb *li; - - ika= ob->data; - ika->totx= 0.0; - ika->toty= 0.0; - li= ika->limbbase.first; - - calc_ika(ika, 0); /* correct endpoints */ - - while(li) { - li->alphao= li->alpha; - li->leno= li->len; - - li= li->next; - } - ika->eff[2]= 0.0; - VecMat4MulVecfl(ika->effg, ob->obmat, ika->eff); -} - -void itterate_limb(Ika *ika, Limb *li) -{ - float da, n1[2], n2[2], len1, len2; - - if(li->prev) { - n1[0]= ika->eff[0] - li->prev->eff[0]; - n1[1]= ika->eff[1] - li->prev->eff[1]; - n2[0]= ika->effn[0] - li->prev->eff[0]; - n2[1]= ika->effn[1] - li->prev->eff[1]; - } - else { - n1[0]= ika->eff[0]; - n1[1]= ika->eff[1]; - n2[0]= ika->effn[0]; - n2[1]= ika->effn[1]; - } - len1= (float)sqrt(n1[0]*n1[0] + n1[1]*n1[1]); - len2= (float)sqrt(n2[0]*n2[0] + n2[1]*n2[1]); - - da= (1.0f-li->fac)*saacos( (n1[0]*n2[0]+n1[1]*n2[1])/(len1*len2) ); - - if(n1[0]*n2[1] < n1[1]*n2[0]) da= -da; - - li->alpha+= da; - -} - -void rotate_ika(Object *ob, Ika *ika) -{ - Limb *li; - float len2, da, n1[2], n2[2]; - - /* rotate back */ - euler_rot(ob->rot, -ika->toty, 'y'); - ika->toty= 0.0; - - where_is_object(ob); - - Mat4Invert(ob->imat, ob->obmat); - VecMat4MulVecfl(ika->effn, ob->imat, ika->effg); - - li= ika->limbbase.last; - if(li==0) return; - - n1[0]= ika->eff[0]; - n2[0]= ika->effn[0]; - n2[1]= ika->effn[2]; - - len2= (float)sqrt(n2[0]*n2[0] + n2[1]*n2[1]); - - if(len2>TOLER) { - da= (n2[0])/(len2); - if(n1[0]<0.0) da= -da; - - /* when the x component is almost zero, this can happen */ - if(da<=-1.0+TOLER || da>=1.0) ; - else { - - da= saacos( da ); - if(n1[0]*n2[1] > 0.0) da= -da; - - euler_rot(ob->rot, da, 'y'); - ika->toty= da; - } - } -} - -void rotate_ika_xy(Object *ob, Ika *ika) -{ - Limb *li; - float ang, da, n1[3], n2[3], axis[3], quat[4]; - - /* rotate back */ - euler_rot(ob->rot, -ika->toty, 'y'); - euler_rot(ob->rot, -ika->totx, 'x'); - - where_is_object(ob); - - Mat4Invert(ob->imat, ob->obmat); - VecMat4MulVecfl(ika->effn, ob->imat, ika->effg); - - li= ika->limbbase.last; - if(li==0) return; - - /* ika->eff = old situation */ - /* ika->effn = desired situation */ - - *(n1)= *(ika->effn); - *(n1+1)= *(ika->effn+1); - *(n1+2)= 0.0; - - *(n2)= *(ika->effn); - *(n2+1)= *(ika->effn+1); - *(n2+2)= *(ika->effn+2); - - Normalise(n1); - Normalise(n2); - - ang= n1[0]*n2[0] + n1[1]*n2[1] + n1[2]*n2[2]; - ang= saacos(ang); - - if(ang<-0.0000001 || ang>0.00000001) { - Crossf(axis, n1, n2); - Normalise(axis); - quat[0]= (float)cos(0.5*ang); - da= (float)sin(0.5*ang); - quat[1]= da*axis[0]; - quat[2]= da*axis[1]; - quat[3]= da*axis[2]; - - QuatToEul(quat, axis); - - ika->totx= axis[0]; - CLAMP(ika->totx, -ika->xyconstraint, ika->xyconstraint); - ika->toty= axis[1]; - CLAMP(ika->toty, -ika->xyconstraint, ika->xyconstraint); - } - - euler_rot(ob->rot, ika->totx, 'x'); - euler_rot(ob->rot, ika->toty, 'y'); -} - -void itterate_ika(Object *ob) -{ - Ika *ika; - Limb *li; - int it = 0; - - ika= ob->data; - if((ika->flag & IK_GRABEFF)==0) return; - - disable_where_script(1); - /* memory: handle large steps in time */ - it= abs(ika->lastfra - G.scene->r.cfra); - ika->lastfra= G.scene->r.cfra; - if(it>10) { - - /* one itteration extra */ - itterate_ika(ob); - } - else { - li= ika->limbbase.first; - while(li) { - li->alpha= (1.0f-ika->mem)*li->alpha + ika->mem*li->alphao; - li= li->next; - } - } - calc_ika(ika, 0); - - /* effector has parent? */ - if(ika->parent) { - - if(ika->partype==PAROBJECT) { - if(ika->parent->ctime != (float) G.scene->r.cfra) where_is_object(ika->parent); - *(ika->effg)= *(ika->parent->obmat[3]); - *(ika->effg+1)= *(ika->parent->obmat[3]+1); - *(ika->effg+2)= *(ika->parent->obmat[3]+2); - } - else { - what_does_parent1(ika->parent, ika->partype, ika->par1, 0, 0); - *(ika->effg)= *(workob.obmat[3]); - *(ika->effg+1)= *(workob.obmat[3]+1); - *(ika->effg+2)= *(workob.obmat[3]+2); - } - } - - - /* rotate y-as correctly */ - if(ika->flag & IK_XYCONSTRAINT) - rotate_ika_xy(ob, ika); - else - rotate_ika(ob, ika); - - it= ika->iter; - while(it--) { - - where_is_object(ob); - Mat4Invert(ob->imat, ob->obmat); - VecMat4MulVecfl(ika->effn, ob->imat, ika->effg); - /* forward orfer: to do the first limbs as well */ - li= ika->limbbase.first; - while(li) { - - itterate_limb(ika, li); - - /* zet je calc_ika() buiten deze lus: lange kettingen instabiel */ - calc_ika(ika, li); - - li= li->next; - } - - where_is_object(ob); - Mat4Invert(ob->imat, ob->obmat); - VecMat4MulVecfl(ika->effn, ob->imat, ika->effg); - - /* backward */ - li= ika->limbbase.last; - while(li) { - - itterate_limb(ika, li); - - /* when you put calc_ika() outside this loop: long chains get instable */ - calc_ika(ika, li); - - li= li->prev; - } - } - - disable_where_script(0); -} - - -void do_all_ikas() -{ - Base *base = 0; - - base= G.scene->base.first; - while(base) { - - if(base->object->type==OB_IKA) itterate_ika(base->object); - - base= base->next; - } -} - -void do_all_visible_ikas() -{ - Base *base = 0; - - base= G.scene->base.first; - while(base) { - if(base->lay & G.scene->lay) { - if(base->object->type==OB_IKA) itterate_ika(base->object); - } - base= base->next; - } -} - -/* ******************** DEFORM ************************ */ - - -void init_skel_deform(Object *par, Object *ob) -{ - Deform *def; - Ika *ika; - int a; - - /* deform: - * - * ob_vec * ob_obmat * def_imat (weight fie) * def_obmat * ob_imat = ob_vec' - * - * <----- premat ----> <---- postmat ----> - */ - - if(par->type!=OB_IKA) return; - - Mat4Invert(ob->imat, ob->obmat); - - ika= par->data; - a= ika->totdef; - def= ika->def; - while(a--) { - - what_does_parent1(def->ob, def->partype, def->par1, def->par2, def->par3); - - Mat4MulMat4(def->premat, ob->obmat, def->imat); - Mat4MulMat4(def->postmat, workob.obmat, ob->imat); - - def++; - } -} - - -void calc_skel_deform(Ika *ika, float *co) -{ - Deform *def; - int a; - float totw=0.0, weight, fac, len, vec[3], totvec[3]; - - def= ika->def; - if(def==0) return; - a= ika->totdef; - totvec[0]=totvec[1]=totvec[2]= 0.0; - - while(a--) { - - VecMat4MulVecfl(vec, def->premat, co); - - len= (float)sqrt(vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2]); - - if(def->vec[0]==0.0f) len= 2.0f*len; - else len= len + (float)sqrt( (vec[0]+def->vec[0])*(vec[0]+def->vec[0]) + vec[1]*vec[1] + vec[2]*vec[2]); - - /* def->vec[0]= len limb */ - - weight= 1.0f/(0.001f+len); - weight*= weight; - weight*= weight; - weight*= def->fac; - - len -= def->vec[0]; - - if(def->dist != 0.0) { - if(len >= def->dist) { - weight= 0.0; - } - else { - fac= (def->dist - len)/def->dist; - weight*= fac; - } - } - if(weight > 0.0) { - Mat4MulVecfl(def->postmat, vec); - - VecMulf(vec, weight); - VecAddf(totvec, totvec, vec); - - totw+= weight; - } - def++; - } - - if(totw==0.0) return; - - co[0]= totvec[0]/totw; - co[1]= totvec[1]/totw; - co[2]= totvec[2]/totw; - -} diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index 25c23b8480b..a03eb0e35c4 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -41,22 +41,21 @@ #include "MEM_guardedalloc.h" -#include "DNA_ika_types.h" -#include "DNA_sequence_types.h" +#include "DNA_action_types.h" +#include "DNA_curve_types.h" #include "DNA_camera_types.h" -#include "DNA_sound_types.h" #include "DNA_lamp_types.h" -#include "DNA_view3d_types.h" +#include "DNA_ipo_types.h" #include "DNA_key_types.h" -#include "DNA_scene_types.h" -#include "DNA_texture_types.h" #include "DNA_material_types.h" +#include "DNA_mesh_types.h" #include "DNA_object_types.h" #include "DNA_object_force.h" -#include "DNA_mesh_types.h" -#include "DNA_curve_types.h" -#include "DNA_ipo_types.h" -#include "DNA_action_types.h" +#include "DNA_sequence_types.h" +#include "DNA_scene_types.h" +#include "DNA_sound_types.h" +#include "DNA_texture_types.h" +#include "DNA_view3d_types.h" #include "BLI_blenlib.h" #include "BLI_arithb.h" @@ -64,15 +63,16 @@ #include "BKE_bad_level_calls.h" #include "BKE_utildefines.h" -#include "BKE_main.h" -#include "BKE_global.h" -#include "BKE_library.h" -#include "BKE_curve.h" -#include "BKE_object.h" +#include "BKE_action.h" #include "BKE_blender.h" -#include "BKE_ipo.h" +#include "BKE_curve.h" #include "BKE_constraint.h" +#include "BKE_global.h" +#include "BKE_ipo.h" +#include "BKE_library.h" +#include "BKE_main.h" #include "BKE_mesh.h" +#include "BKE_object.h" #define SMALL -1.0e-10 @@ -89,7 +89,7 @@ int ob_ar[OB_TOTIPO]= { OB_LOC_X, OB_LOC_Y, OB_LOC_Z, OB_DLOC_X, OB_DLOC_Y, OB_DLOC_Z, OB_ROT_X, OB_ROT_Y, OB_ROT_Z, OB_DROT_X, OB_DROT_Y, OB_DROT_Z, OB_SIZE_X, OB_SIZE_Y, OB_SIZE_Z, OB_DSIZE_X, OB_DSIZE_Y, OB_DSIZE_Z, - OB_LAY, OB_TIME, OB_EFF_X, OB_EFF_Y, OB_EFF_Z, OB_COL_A, + OB_LAY, OB_TIME, OB_COL_R, OB_COL_G, OB_COL_B, OB_COL_A, OB_PD_FSTR, OB_PD_FFALL, OB_PD_SDAMP, OB_PD_RDAMP, OB_PD_PERM }; @@ -1080,25 +1080,45 @@ void *get_ipo_poin(ID *id, IpoCurve *icu, int *type) return NULL; switch (icu->adrcode){ case AC_QUAT_W: - poin= &(pchan->quat[0]); break; + poin= &(pchan->quat[0]); + pchan->flag |= POSE_ROT; + break; case AC_QUAT_X: - poin= &(pchan->quat[1]); break; + poin= &(pchan->quat[1]); + pchan->flag |= POSE_ROT; + break; case AC_QUAT_Y: - poin= &(pchan->quat[2]); break; + poin= &(pchan->quat[2]); + pchan->flag |= POSE_ROT; + break; case AC_QUAT_Z: - poin= &(pchan->quat[3]); break; + poin= &(pchan->quat[3]); + pchan->flag |= POSE_ROT; + break; case AC_LOC_X: - poin= &(pchan->loc[0]); break; + poin= &(pchan->loc[0]); + pchan->flag |= POSE_LOC; + break; case AC_LOC_Y: - poin= &(pchan->loc[1]); break; + poin= &(pchan->loc[1]); + pchan->flag |= POSE_LOC; + break; case AC_LOC_Z: - poin= &(pchan->loc[2]); break; + poin= &(pchan->loc[2]); + pchan->flag |= POSE_LOC; + break; case AC_SIZE_X: - poin= &(pchan->size[0]); break; + poin= &(pchan->size[0]); + pchan->flag |= POSE_SIZE; + break; case AC_SIZE_Y: - poin= &(pchan->size[1]); break; + poin= &(pchan->size[1]); + pchan->flag |= POSE_SIZE; + break; case AC_SIZE_Z: - poin= &(pchan->size[2]); break; + poin= &(pchan->size[2]); + pchan->flag |= POSE_SIZE; + break; }; } @@ -1800,9 +1820,8 @@ int has_ipo_code(Ipo *ipo, int code) return 0; } -void do_all_ipos() +void do_all_data_ipos() { - Base *base; Material *ma; Tex *tex; World *wo; @@ -1813,7 +1832,6 @@ void do_all_ipos() Sequence *seq; Editing *ed; float ctime; - int set; ctime= frame_to_float(G.scene->r.cfra); @@ -1825,27 +1843,6 @@ void do_all_ipos() ipo= ipo->id.next; } - /* NEW: current scene ob ipo's */ - base= G.scene->base.first; - set= 0; - while(base) { - - /* Do object ipos */ - do_constraint_channels(&base->object->constraints, &base->object->constraintChannels, ctime); - - if(base->object->ipo) { - /* do per object ipo the calc_ipo: because of possible timeoffs */ - do_ob_ipo(base->object); - if(base->object->type==OB_MBALL) where_is_object(base->object); - } - base= base->next; - - if(base==0 && set==0 && G.scene->set) { - set= 1; - base= G.scene->set->base.first; - } - } - tex= G.main->tex.first; while(tex) { if(tex->ipo) execute_ipo((ID *)tex, tex->ipo); @@ -1882,39 +1879,14 @@ void do_all_ipos() snd= snd->id.next; } - /*just in case of... WATCH IT: 2x */ - base= G.scene->base.first; - while(base) { - - /* only update layer when an ipo */ - if( has_ipo_code(base->object->ipo, OB_LAY) ) { - base->lay= base->object->lay; - } - - base= base->next; - } - - /* just in case...*/ - if(G.scene->set) { - base= G.scene->set->base.first; - while(base) { - - /* only update layer when an ipo */ - if( has_ipo_code(base->object->ipo, OB_LAY) ) { - base->lay= base->object->lay; - } - - base= base->next; - } - } - - /* intrr: process FAC Ipos used as volume envelopes */ + /* process FAC Ipos used as volume envelopes */ ed= G.scene->ed; if (ed) { seq= ed->seqbasep->first; while(seq) { - if ((seq->type == SEQ_SOUND) && (seq->ipo) - &&(seq->startdisp<=G.scene->r.cfra+2) && (seq->enddisp>G.scene->r.cfra)) do_seq_ipo(seq); + if ((seq->type == SEQ_SOUND) && (seq->ipo) && + (seq->startdisp<=G.scene->r.cfra+2) && (seq->enddisp>G.scene->r.cfra)) + do_seq_ipo(seq); seq= seq->next; } } diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index 3b54072bd12..966eadeb2d5 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -897,8 +897,6 @@ void do_key(int start, int end, int tot, char *poin, Key *key, KeyBlock **k, flo } } - - void do_mesh_key(Mesh *me) { KeyBlock *k[4]; @@ -906,8 +904,9 @@ void do_mesh_key(Mesh *me) int a, flag = 0, step; if(me->totvert==0) return; - if(me->key==0) return; - if(me->key->block.first==0) return; + if(me->key==NULL) return; + if(me->key->flag & KEY_LOCKED) return; + if(me->key->block.first==NULL) return; if(me->key->slurph && me->key->type!=KEY_RELATIVE ) { delta= me->key->slurph; @@ -981,6 +980,7 @@ void do_cu_key(Curve *cu, KeyBlock **k, float *t) tot= count_curveverts(&cu->nurb); nu= cu->nurb.first; a= 0; + while(nu) { if(nu->bp) { @@ -1051,8 +1051,9 @@ void do_curve_key(Curve *cu) tot= count_curveverts(&cu->nurb); if(tot==0) return; - if(cu->key==0) return; - if(cu->key->block.first==0) return; + if(cu->key==NULL) return; + if(cu->key->flag & KEY_LOCKED) return; + if(cu->key->block.first==NULL) return; if(cu->key->slurph) { delta= cu->key->slurph; @@ -1117,9 +1118,10 @@ void do_latt_key(Lattice *lt) float delta, cfra, ctime, t[4]; int a, tot, flag; - if(lt->key==0) return; + if(lt->key==NULL) return; + if(lt->key->flag & KEY_LOCKED) return; if(lt->key->block.first==0) return; - + tot= lt->pntsu*lt->pntsv*lt->pntsw; if(lt->key->slurph) { @@ -1172,21 +1174,14 @@ void do_latt_key(Lattice *lt) } - -void do_all_keys() +/* going to be removed */ +void unlock_all_keys() { Key *key; - int idcode; key= G.main->key.first; while(key) { - if(key->from) { - idcode= GS(key->from->name); - - if(idcode==ID_ME) do_mesh_key( (Mesh *)key->from); - else if(idcode==ID_CU) do_curve_key( (Curve *)key->from); - else if(idcode==ID_LT) do_latt_key( (Lattice *)key->from); - } + key->flag &= ~KEY_LOCKED; key= key->id.next; } } diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index 3da60f99826..db5dee45d5d 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -51,7 +51,6 @@ #include "DNA_lattice_types.h" #include "DNA_curve_types.h" #include "DNA_key_types.h" -#include "DNA_ika_types.h" #include "BKE_anim.h" #include "BKE_armature.h" @@ -59,7 +58,6 @@ #include "BKE_deform.h" #include "BKE_displist.h" #include "BKE_global.h" -#include "BKE_ika.h" #include "BKE_key.h" #include "BKE_lattice.h" #include "BKE_library.h" diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 27d87ce9117..63524c47592 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -56,7 +56,6 @@ #include "DNA_meta_types.h" #include "DNA_material_types.h" #include "DNA_texture_types.h" -#include "DNA_ika_types.h" #include "DNA_image_types.h" #include "DNA_wave_types.h" #include "DNA_lamp_types.h" @@ -91,7 +90,6 @@ #include "BKE_texture.h" #include "BKE_scene.h" #include "BKE_image.h" -#include "BKE_ika.h" #include "BKE_ipo.h" #include "BKE_key.h" #include "BKE_world.h" @@ -149,8 +147,6 @@ ListBase *wich_libbase(Main *mainlib, short type) return &(mainlib->tex); case ID_IM: return &(mainlib->image); - case ID_IK: - return &(mainlib->ika); case ID_WV: return &(mainlib->wave); case ID_LT: @@ -209,26 +205,26 @@ int set_listbasepointers(Main *main, ListBase **lb) lb[8]= &(main->mesh); lb[9]= &(main->curve); lb[10]= &(main->mball); - lb[11]= &(main->ika); - lb[12]= &(main->wave); - lb[13]= &(main->latt); - lb[14]= &(main->lamp); - lb[15]= &(main->camera); - - lb[16]= &(main->world); - lb[17]= &(main->screen); - lb[18]= &(main->object); - lb[19]= &(main->scene); - lb[20]= &(main->library); - lb[21]= &(main->text); - lb[22]= &(main->sound); - lb[23]= &(main->group); - - lb[24]= samples; - lb[25]= &(main->script); - lb[26]=0; - - return 26; + + lb[11]= &(main->wave); + lb[12]= &(main->latt); + lb[13]= &(main->lamp); + lb[14]= &(main->camera); + + lb[15]= &(main->world); + lb[16]= &(main->screen); + lb[17]= &(main->object); + lb[18]= &(main->scene); + lb[19]= &(main->library); + lb[20]= &(main->text); + lb[21]= &(main->sound); + lb[22]= &(main->group); + + lb[23]= samples; + lb[24]= &(main->script); + lb[25]= NULL; + + return 25; } /* *********** ALLOC AND FREE ***************** @@ -273,9 +269,6 @@ static ID *alloc_libblock_notest(short type) case ID_IM: id= MEM_callocN(sizeof(Image), "image"); break; - case ID_IK: - id= MEM_callocN(sizeof(Ika), "ika"); - break; case ID_WV: id= MEM_callocN(sizeof(Wave), "wave"); break; @@ -421,9 +414,6 @@ void free_libblock(ListBase *lb, void *idv) case ID_IM: free_image((Image *)id); break; - case ID_IK: - free_ika((Ika *)id); - break; case ID_WV: /* free_wave(id); */ break; diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index bc3290aa0d4..3d7fba62b0b 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -737,7 +737,7 @@ void delete_material_index() if(ob->type==OB_MESH) { Mesh *me= get_mesh(ob); mesh_delete_material_index(me, actcol-1); - makeDispList(ob); + freedisplist(&ob->disp); } else if ELEM(ob->type, OB_CURVE, OB_SURF) { cu= ob->data; @@ -750,6 +750,6 @@ void delete_material_index() } nu= nu->next; } - makeDispList(ob); + freedisplist(&ob->disp); } } diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index fdb08813765..68aa863d22c 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -48,7 +48,6 @@ #include "DNA_constraint_types.h" #include "DNA_curve_types.h" #include "DNA_group_types.h" -#include "DNA_ika_types.h" #include "DNA_ipo_types.h" #include "DNA_lamp_types.h" #include "DNA_lattice_types.h" @@ -81,24 +80,24 @@ #include "BKE_main.h" #include "BKE_global.h" -#include "BKE_object.h" +#include "BKE_anim.h" #include "BKE_blender.h" -#include "BKE_screen.h" +#include "BKE_constraint.h" +#include "BKE_curve.h" +#include "BKE_displist.h" +#include "BKE_effect.h" +#include "BKE_group.h" #include "BKE_ipo.h" -#include "BKE_ika.h" +#include "BKE_key.h" +#include "BKE_lattice.h" #include "BKE_library.h" #include "BKE_mesh.h" -#include "BKE_curve.h" #include "BKE_mball.h" -#include "BKE_effect.h" -#include "BKE_sca.h" -#include "BKE_displist.h" +#include "BKE_object.h" #include "BKE_property.h" -#include "BKE_anim.h" -#include "BKE_group.h" -#include "BKE_lattice.h" -#include "BKE_constraint.h" +#include "BKE_sca.h" #include "BKE_scene.h" +#include "BKE_screen.h" #include "BKE_softbody.h" #include "BPY_extern.h" @@ -201,7 +200,7 @@ void free_object(Object *ob) if(ob->defbase.first) BLI_freelistN(&ob->defbase); if(ob->pose) { - clear_pose(ob->pose); + free_pose_channels(ob->pose); MEM_freeN(ob->pose); } free_effects(&ob->effect); @@ -237,8 +236,10 @@ void unlink_object(Object *ob) Tex *tex; ObHook *hook; Group *group; + bConstraint *con; int a; - + char *str; + unlink_controllers(&ob->controllers); unlink_actuators(&ob->actuators); @@ -246,37 +247,48 @@ void unlink_object(Object *ob) obt= G.main->object.first; while(obt) { if(obt->id.lib==NULL) { + if(obt->parent==ob) { obt->parent= NULL; - if(ob->type==OB_LATTICE) freedisplist(&obt->disp); + obt->recalc |= OB_RECALC; } - if(obt->track==ob) obt->track= NULL; + + if(obt->track==ob) { + obt->track= NULL; + obt->recalc |= OB_RECALC_OB; + } + for(hook=obt->hooks.first; hook; hook= hook->next) { - if(hook->parent==ob) hook->parent= NULL; + if(hook->parent==ob) { + hook->parent= NULL; + obt->recalc |= OB_RECALC; + } } + if ELEM(obt->type, OB_CURVE, OB_FONT) { cu= obt->data; - if(cu->bevobj==ob) cu->bevobj= NULL; - if(cu->taperobj==ob) cu->taperobj= NULL; - if(cu->textoncurve==ob) cu->textoncurve= NULL; - } - if(obt->type==OB_IKA) { - Ika *ika= obt->data; - Deform *def= ika->def; - - if(ika->parent==ob) ika->parent= NULL; - a= ika->totdef; - while(a--) { - if(def->ob==ob) { - ika->totdef= 0; - MEM_freeN(ika->def); - ika->def= NULL; - break; - } - def++; + if(cu->bevobj==ob) { + cu->bevobj= NULL; + obt->recalc |= OB_RECALC; + } + if(cu->taperobj==ob) { + cu->taperobj= NULL; + obt->recalc |= OB_RECALC; + } + if(cu->textoncurve==ob) { + cu->textoncurve= NULL; + obt->recalc |= OB_RECALC; } } + sca_remove_ob_poin(obt, ob); + + for (con = obt->constraints.first; con; con=con->next) { + if(ob==get_constraint_target(con, &str)) { + set_constraint_target(con, NULL); + obt->recalc |= OB_RECALC_OB; + } + } } obt= obt->id.next; } @@ -625,7 +637,6 @@ static void *add_obdata_from_type(int type) case OB_MBALL: return add_mball(); case OB_CAMERA: return add_camera(); case OB_LAMP: G.totlamp++; return add_lamp(); - case OB_IKA: return add_ika(); case OB_LATTICE: return add_lattice(); case OB_WAVE: return add_wave(); case OB_ARMATURE: return add_armature(); @@ -646,7 +657,6 @@ static char *get_obdata_defname(int type) case OB_MBALL: return "Mball"; case OB_CAMERA: return "Camera"; case OB_LAMP: return "Lamp"; - case OB_IKA: return "Ika"; case OB_LATTICE: return "Lattice"; case OB_WAVE: return "Wave"; case OB_ARMATURE: return "Armature"; @@ -721,7 +731,8 @@ Object *add_object(int type) base= scene_add_base(G.scene, ob); scene_select_base(G.scene, base); - + ob->recalc |= OB_RECALC; + return ob; } @@ -1071,57 +1082,31 @@ void ob_parcurve(Object *ob, Object *par, float mat[][4]) void ob_parbone(Object *ob, Object *par, float mat[][4]) { - Bone *bone; + bPoseChannel *pchan; bArmature *arm; - - Mat4One(mat); + float vec[3]; + arm=get_armature(par); - if (!arm) + if (!arm) { + Mat4One(mat); return; - + } + /* Make sure the bone is still valid */ - bone = get_named_bone(arm, ob->parsubstr); - if (!bone){ + pchan= get_pose_channel(par->pose, ob->parsubstr); + if (!pchan){ printf ("Lost bone %s\n", ob->parsubstr); + Mat4One(mat); return; } - apply_pose_armature(arm, par->pose, 1); /* Hopefully can set doit parameter in the future */ - where_is_bone (par, bone); + /* get bone transform */ + Mat4CpyMat4(mat, pchan->pose_mat); - /* Translate by negative bone */ - get_objectspace_bone_matrix(bone, mat, 0, 1); - -} - -void ob_parlimb(Object *ob, Object *par, float mat[][4]) -{ - Ika *ika; - Limb *li; - float ang=0.0; - int cur=0; - - /* in local ob space */ - Mat4One(mat); - - ika= par->data; - li= ika->limbbase.first; - while(li) { - ang+= li->alpha; - if(cur==ob->par1 || li->next==0) break; - - cur++; - li= li->next; - } - - mat[0][0]= (float)cos(ang); - mat[1][0]= (float)-sin(ang); - mat[0][1]= (float)sin(ang); - mat[1][1]= (float)cos(ang); - - mat[3][0]= li->eff[0]; - mat[3][1]= li->eff[1]; - + /* but for backwards compatibility, the child has to move to the tail */ + VECCOPY(vec, mat[1]); + VecMulf(vec, pchan->bone->length); + VecAddf(mat[3], mat[3], vec); } void give_parvert(Object *par, int nr, float *vec) @@ -1141,7 +1126,7 @@ void give_parvert(Object *par, int nr, float *vec) vec[0]=vec[1]=vec[2]= 0.0; if(par->type==OB_MESH) { - if(par==G.obedit) { + if(G.obedit && (par->data==G.obedit->data)) { if(nr >= G.totvert) nr= 0; count= 0; @@ -1209,20 +1194,6 @@ void give_parvert(Object *par, int nr, float *vec) } } - else if(par->type==OB_IKA) { - Ika *ika= par->data; - Limb *li= ika->limbbase.first; - int cur= 1; - if(nr) { - while(li) { - if(cur==nr || li->next==0) break; - cur++; - li= li->next; - } - vec[0]= li->eff[0]; - vec[1]= li->eff[1]; - } - } else return; } @@ -1309,13 +1280,9 @@ void where_is_object_time(Object *ob, float ctime) calc_ipo(ob->ipo, stime); execute_ipo((ID *)ob, ob->ipo); - } - } - - - if(ob->type==OB_IKA) { - Ika *ika= ob->data; - if(ika->parent) where_is_object_time(ika->parent, ctime); + } + /* do constraint ipos ... what the heck is a channel for! */ + do_constraint_channels(&ob->constraints, &ob->constraintChannels, ctime); } if(ob->parent) { @@ -1323,6 +1290,7 @@ void where_is_object_time(Object *ob, float ctime) if(ob->ipoflag & OB_OFFS_PARENT) ctime-= ob->sf; + /* hurms, code below conflicts with depgraph... (ton) */ pop= 0; if(no_parent_ipo==0 && ctime != par->ctime) { @@ -1410,11 +1378,6 @@ static void solve_parenting (Object *ob, Object *par, float slowmat[][4], int si Mat4MulSerie(totmat, par->obmat, tmat, NULL, NULL, NULL, NULL, NULL, NULL); break; - case PARLIMB: - ob_parlimb(ob, par, tmat); - Mat4MulSerie(totmat, par->obmat, tmat, - NULL, NULL, NULL, NULL, NULL, NULL); - break; case PARVERT1: Mat4One(totmat); @@ -1569,24 +1532,29 @@ void solve_constraints (Object *ob, short obtype, void *obdata, float ctime) float smat[3][3], rmat[3][3], mat[3][3]; float enf; - for (con = ob->constraints.first; con; con=con->next){ + for (con = ob->constraints.first; con; con=con->next) { + // inverse kinematics is solved seperate + if (con->type==CONSTRAINT_TYPE_KINEMATIC) continue; + /* Clear accumulators if necessary*/ - if (clear){ - clear=0; - a=0; - tot=0; + if (clear) { + clear= 0; + a= 0; + tot= 0; memset(aquat, 0, sizeof(float)*4); memset(aloc, 0, sizeof(float)*3); memset(asize, 0, sizeof(float)*3); } /* Check this constraint only if it has some enforcement */ - if (!(con->flag & CONSTRAINT_DISABLE)) - { - if (con->enforce==0) + if (!(con->flag & CONSTRAINT_DISABLE)) { + /* weird code was here (ton) + if (con->enforce==0.0) enf = 0.001f; enf = con->enforce; - + */ + enf = con->enforce; + /* Get the targetmat */ get_constraint_target_matrix(con, obtype, obdata, tmat, size, ctime); @@ -1598,10 +1566,10 @@ void solve_constraints (Object *ob, short obtype, void *obdata, float ctime) Mat3CpyMat4(mat, focusmat); Mat3ToSize(mat, size); - a+=enf; + a+= enf; tot++; - for(i=0; i<3; i++){ + for(i=0; i<3; i++) { aquat[i+1]+=(quat[i+1]) * enf; aloc[i]+=(loc[i]) * enf; asize[i]+=(size[i]-1.0f) * enf; @@ -1612,16 +1580,15 @@ void solve_constraints (Object *ob, short obtype, void *obdata, float ctime) /* If the next constraint is not the same type (or there isn't one), * then evaluate the accumulator & request a clear */ - if ((!con->next)||(con->next && con->next->type!=con->type)) - { - clear=1; + if ((!con->next)||(con->next && con->next->type!=con->type)) { + clear= 1; Mat4CpyMat4(oldmat, ob->obmat); /* If we have several inputs, do a blend of them */ - if (tot){ - if (tot>1){ - if (a){ - for (i=0; i<3; i++){ + if (tot) { + if (tot>1) { + if (a) { + for (i=0; i<3; i++) { asize[i]=1.0f + (asize[i]/(a)); aloc[i]=(aloc[i]/a); } @@ -1639,14 +1606,14 @@ void solve_constraints (Object *ob, short obtype, void *obdata, float ctime) } /* If we only have one, blend with the current obmat */ - else{ + else { float solution[4][4]; float delta[4][4]; float imat[4][4]; float identity[4][4]; float worldmat[4][4]; - if (con->type!=CONSTRAINT_TYPE_KINEMATIC){ + if (con->type!=CONSTRAINT_TYPE_KINEMATIC) { /* If we're not an IK constraint, solve the constraint then blend it to the previous one */ evaluate_constraint(con, ob, obtype, obdata, lastmat); @@ -1665,7 +1632,7 @@ void solve_constraints (Object *ob, short obtype, void *obdata, float ctime) } else{ /* Interpolate the target between the chain's unconstrained endpoint and the effector loc */ - if (obtype==TARGET_BONE){ + if (obtype==TARGET_BONE) { get_objectspace_bone_matrix(obdata, oldmat, 1, 1); Mat4MulMat4(worldmat, oldmat, ob->parent->obmat); @@ -1681,28 +1648,7 @@ void solve_constraints (Object *ob, short obtype, void *obdata, float ctime) } } -void what_does_parent1(Object *par, int partype, int par1, int par2, int par3) -{ - - clear_workob(); - Mat4One(workob.parentinv); - workob.parent= par; - if(par) - workob.track= par->track; /* WATCH IT: THATS NOT NICE CODE */ - workob.partype= partype; - workob.par1= par1; - workob.par2= par2; - workob.par3= par3; - - if (par){ - workob.constraints.first = par->constraints.first; - workob.constraints.last = par->constraints.last; - } - - where_is_object(&workob); -} - - +/* for calculation of the inverse parent transform, only used for editor */ void what_does_parent(Object *ob) { @@ -1800,4 +1746,32 @@ void minmax_object(Object *ob, float *min, float *max) } } +/* the main object update call, for object matrix, constraints, keys and displist (modifiers) */ +/* requires flags to be set! */ +void object_handle_update(Object *ob) +{ + if(ob->recalc & OB_RECALC) { + + if(ob->recalc & OB_RECALC_OB) where_is_object(ob); + + if(ob->recalc & OB_RECALC_DATA) { + + /* includes all keys and modifiers */ + if(ob->type && ob->type<OB_LAMP) { +// printf("recalcdata %s\n", ob->id.name+2); + makeDispList(ob); + } + else if(ob->type==OB_ARMATURE) { + /* this actually only happens for reading old files... */ + if(ob->pose==NULL || (ob->pose->flag & POSE_RECALC)) + armature_rebuild_pose(ob, ob->data); + do_all_actions(ob); + where_is_pose(ob); + } + } + + ob->recalc &= ~OB_RECALC; + } +} + diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 5d73b24e8bb..255cdba9f6d 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -46,46 +46,39 @@ #endif #include "MEM_guardedalloc.h" -#include "nla.h" /* for __NLA : IMPORTANT Do not delete me yet! */ -#ifdef __NLA /* for __NLA : IMPORTANT Do not delete me yet! */ -#include "DNA_armature_types.h" /* for __NLA : IMPORTANT Do not delete me yet! */ -#include "BKE_armature.h" /* for __NLA : IMPORTANT Do not delete me yet! */ -#include "BKE_action.h" /* for __NLA : IMPORTANT Do not delete me yet! */ -#endif /* for __NLA : IMPORTANT Do not delete me yet! */ - +#include "DNA_armature_types.h" #include "DNA_constraint_types.h" -#include "DNA_scene_types.h" -#include "DNA_object_types.h" -#include "DNA_scriptlink_types.h" -#include "DNA_meta_types.h" -#include "DNA_ika_types.h" +#include "DNA_curve_types.h" +#include "DNA_group_types.h" #include "DNA_lamp_types.h" #include "DNA_material_types.h" -#include "DNA_group_types.h" -#include "DNA_curve_types.h" +#include "DNA_meta_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_scriptlink_types.h" #include "DNA_userdef_types.h" -#include "BLI_blenlib.h" - -#include "BKE_bad_level_calls.h" -#include "BKE_utildefines.h" - -#include "BKE_global.h" -#include "BKE_main.h" +#include "BKE_action.h" #include "BKE_anim.h" +#include "BKE_armature.h" +#include "BKE_bad_level_calls.h" #include "BKE_constraint.h" - +#include "BKE_depsgraph.h" +#include "BKE_global.h" +#include "BKE_ipo.h" +#include "BKE_key.h" #include "BKE_library.h" - +#include "BKE_main.h" +#include "BKE_object.h" #include "BKE_scene.h" #include "BKE_world.h" -#include "BKE_ipo.h" -#include "BKE_ika.h" -#include "BKE_key.h" +#include "BKE_utildefines.h" #include "BPY_extern.h" -#include "BKE_depsgraph.h" +#include "BLI_blenlib.h" + +#include "nla.h" #ifdef WIN32 #else @@ -222,95 +215,6 @@ int object_in_scene(Object *ob, Scene *sce) return 0; } -void sort_baselist(Scene *sce) -{ - topo_sort_baselist(sce); -} - -#if 0 -void old_sort_baselist(Scene *sce) -{ - /* in order of parent and track */ - ListBase tempbase, noparentbase, notyetbase; - Base *base, *test=NULL; - Object *par; - int doit, domore= 0, lastdomore=1; - - /* keep same order when nothing has changed! */ - - while(domore!=lastdomore) { - - lastdomore= domore; - domore= 0; - tempbase.first= tempbase.last= 0; - noparentbase.first= noparentbase.last= 0; - notyetbase.first= notyetbase.last= 0; - - while( (base= sce->base.first) ) { - BLI_remlink(&sce->base, base); - - par= 0; - if(base->object->type==OB_IKA) { - Ika *ika= base->object->data; - par= ika->parent; - } - - if(par || base->object->parent || base->object->track) { - - doit= 0; - if(base->object->parent) doit++; - if(base->object->track) doit++; - - /* Count constraints */ - { - bConstraint *con; - for (con = base->object->constraints.first; con; con=con->next){ - if (constraint_has_target(con)) - doit++; - } - } - - if(par) doit++; - - test= tempbase.first; - while(test) { - - if(test->object==base->object->parent) doit--; - if(test->object==base->object->track) doit--; - if(test->object==par) doit--; - - /* Decrement constraints */ - { - bConstraint *con; - for (con = base->object->constraints.first; con; con=con->next){ - if (test->object == get_constraint_target(con) && test->object!=base->object) - doit--; - } - } - - if(doit==0) break; - test= test->next; - } - - if(test) BLI_insertlink(&tempbase, test, base); - else { - BLI_addhead(&tempbase, base); - domore++; - } - - } - else BLI_addtail(&noparentbase, base); - - } - sce->base= noparentbase; - addlisttolist(&sce->base, &tempbase); - addlisttolist(&sce->base, ¬yetbase); - - } - -} -#endif - void set_scene_bg(Scene *sce) { Base *base; @@ -340,37 +244,34 @@ void set_scene_bg(Scene *sce) } /* sort baselist */ - sort_baselist(sce); + DAG_scene_sort(sce); /* copy layers and flags from bases to objects */ base= G.scene->base.first; while(base) { - - base->object->lay= base->lay; + ob= base->object; + ob->lay= base->lay; /* group patch... */ - base->flag &= ~OB_FROMGROUP; - flag= base->object->flag & OB_FROMGROUP; + base->flag &= ~(OB_FROMGROUP); + flag= ob->flag & (OB_FROMGROUP); base->flag |= flag; - base->object->flag= base->flag; + ob->flag= base->flag; + ob->recalc= OB_RECALC; - base->object->ctime= -1234567.0; /* force ipo to be calculated later */ + ob->ctime= -1234567.0; /* force ipo to be calculated later */ base= base->next; } - - do_all_ipos(); /* layers/materials */ - + // full update + scene_update_for_newframe(sce, sce->lay); + /* do we need FRAMECHANGED in set_scene? */ - if (G.f & G_DOSCRIPTLINKS) BPY_do_all_scripts(SCRIPT_FRAMECHANGED); +// if (G.f & G_DOSCRIPTLINKS) BPY_do_all_scripts(SCRIPT_FRAMECHANGED); - do_all_keys(); -#ifdef __NLA - do_all_actions(NULL); - rebuild_all_armature_displists(); -#endif - do_all_ikas(); +// do_all_keys(); +// do_all_actions(NULL); } @@ -518,3 +419,41 @@ void scene_select_base(Scene *sce, Base *selbase) sce->basact= selbase; } + +/* applies changes right away */ +void scene_update_for_newframe(Scene *sce, unsigned int lay) +{ + Base *base; + int setcount=0; + + /* object ipos are calculated in where_is_object */ + do_all_data_ipos(); + + if (G.f & G_DOSCRIPTLINKS) BPY_do_all_scripts(SCRIPT_FRAMECHANGED); + +// do_all_actions(NULL); + /* so nice, better do it twice */ +// do_all_actions(NULL); + + /* if keys were activated, disable the locks */ + unlock_all_keys(); + + /* for time being; sets otherwise can be cyclic */ + while(sce && setcount<2) { + if(sce->theDag==NULL) + DAG_scene_sort(sce); + + DAG_scene_update_flags(sce, lay); // only stuff that moves + + for(base= sce->base.first; base; base= base->next) { + object_handle_update(base->object); // bke_object.h + + /* only update layer when an ipo */ + if(base->object->ipo && has_ipo_code(base->object->ipo, OB_LAY) ) { + base->lay= base->object->lay; + } + } + sce= sce->set; + setcount++; + } +} diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c index ee8cba2329d..182bbe2f1a1 100644 --- a/source/blender/blenloader/intern/readblenentry.c +++ b/source/blender/blenloader/intern/readblenentry.c @@ -85,7 +85,6 @@ static IDType idtypes[]= { { ID_CU, "Curve", IDTYPE_FLAGS_ISLINKABLE}, { ID_GR, "Group", 0}, { ID_ID, "ID", 0}, - { ID_IK, "Ika", IDTYPE_FLAGS_ISLINKABLE}, { ID_IM, "Image", IDTYPE_FLAGS_ISLINKABLE}, { ID_IP, "Ipo", IDTYPE_FLAGS_ISLINKABLE}, { ID_KE, "Key", 0}, diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index a44c1228c79..661a520832f 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -71,7 +71,6 @@ #include "DNA_fileglobal_types.h" #include "DNA_group_types.h" #include "DNA_ipo_types.h" -#include "DNA_ika_types.h" #include "DNA_image_types.h" #include "DNA_key_types.h" #include "DNA_lattice_types.h" @@ -108,11 +107,12 @@ #include "BKE_bad_level_calls.h" // for reopen_text build_seqar (from WHILE_SEQ) open_plugin_seq set_rects_butspace check_imasel_copy -#include "BKE_armature.h" // for precalc_bonelist_irestmats #include "BKE_action.h" +#include "BKE_armature.h" #include "BKE_constraint.h" #include "BKE_curve.h" #include "BKE_deform.h" +#include "BKE_depsgraph.h" #include "BKE_effect.h" // for give_parteff #include "BKE_global.h" // for G #include "BKE_property.h" // for get_property @@ -1240,42 +1240,6 @@ static void direct_link_scriptlink(FileData *fd, ScriptLink *slink) } } -/* ************ READ IKA ***************** */ - -static void lib_link_ika(FileData *fd, Main *main) -{ - Ika *ika; - int a; - Deform *def; - - ika= main->ika.first; - while(ika) { - if(ika->id.flag & LIB_NEEDLINK) { - - ika->parent= newlibadr(fd, ika->id.lib, ika->parent); - - a= ika->totdef; - def= ika->def; - while(a--) { - def->ob= newlibadr(fd, ika->id.lib, def->ob); - def++; - } - ika->id.flag -= LIB_NEEDLINK; - } - ika= ika->id.next; - } -} - -static void direct_link_ika(FileData *fd, Ika *ika) -{ - link_list(fd, &ika->limbbase); - - ika->def= newdataadr(fd, ika->def); - - /* error from V.138 and older */ - if(ika->def==0) ika->totdef= 0; -} - /* ************ READ ARMATURE ***************** */ static void lib_link_nlastrips(FileData *fd, ID *id, ListBase *striplist) @@ -1285,7 +1249,7 @@ static void lib_link_nlastrips(FileData *fd, ID *id, ListBase *striplist) for (strip=striplist->first; strip; strip=strip->next){ strip->act = newlibadr_us(fd, id->lib, strip->act); strip->ipo = newlibadr(fd, id->lib, strip->ipo); - }; + } } static void lib_link_constraint_channels(FileData *fd, ID *id, ListBase *chanbase) @@ -1302,7 +1266,8 @@ static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist) bConstraint *con; for (con = conlist->first; con; con=con->next) { - /* patch for error introduced by changing constraints (dunno how) */ + /* patch for error introduced by changing constraints (dunno how) */ + /* if con->data type changes, dna cannot resolve the pointer! (ton) */ if(con->data==NULL) { con->type= CONSTRAINT_TYPE_NULL; } @@ -1386,35 +1351,31 @@ static void direct_link_constraints(FileData *fd, ListBase *lb) link_list(fd, lb); for (cons=lb->first; cons; cons=cons->next) { cons->data = newdataadr(fd, cons->data); - switch (cons->type) { - default: - break; - } - // Link data } } +/* unused */ static void lib_link_bone(FileData *fd, ID *id, Bone *bone) { - Bone *curBone; - -// lib_link_constraints(fd, id, &bone->constraints); +// Bone *curBone; - for (curBone=bone->childbase.first; curBone; curBone=curBone->next) { - lib_link_bone(fd, id, curBone); - } +// for (curBone=bone->childbase.first; curBone; curBone=curBone->next) { +// lib_link_bone(fd, id, curBone); +// } } -static void lib_link_pose(FileData *fd, ID *id, bPose *pose) +static void lib_link_pose(FileData *fd, Object *ob, bPose *pose) { bPoseChannel *chan; - + bArmature *arm= ob->data; if (!pose) return; for (chan = pose->chanbase.first; chan; chan=chan->next) { - lib_link_constraints(fd, id, &chan->constraints); + lib_link_constraints(fd, (ID *)ob, &chan->constraints); + // hurms... loop in a loop, but yah... later... (ton) + chan->bone= get_named_bone(arm, chan->name); } } @@ -1430,9 +1391,9 @@ static void lib_link_armature(FileData *fd, Main *main) arm->id.flag -= LIB_NEEDLINK; } - for (bone=arm->bonebase.first; bone; bone=bone->next) { - lib_link_bone(fd, &arm->id, bone); - } +// for (bone=arm->bonebase.first; bone; bone=bone->next) { +// lib_link_bone(fd, &arm->id, bone); +// } arm= arm->id.next; } @@ -2188,7 +2149,7 @@ static void lib_link_object(FileData *fd, Main *main) /* if id.us==0 a new base will be created later on */ /* WARNING! Also check expand_object(), should reflect the stuff below. */ - lib_link_pose(fd, &ob->id, ob->pose); + lib_link_pose(fd, ob, ob->pose); lib_link_constraints(fd, &ob->id, &ob->constraints); lib_link_nlastrips(fd, &ob->id, &ob->nlastrips); lib_link_constraint_channels(fd, &ob->id, &ob->constraintChannels); @@ -2302,6 +2263,8 @@ static void direct_link_pose(FileData *fd, bPose *pose) { link_list(fd, &pose->chanbase); for (chan = pose->chanbase.first; chan; chan=chan->next) { + chan->bone= NULL; + chan->parent= newdataadr(fd, chan->parent); direct_link_constraints(fd, &chan->constraints); } @@ -3224,9 +3187,6 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID case ID_LT: direct_link_latt(fd, (Lattice *)id); break; - case ID_IK: - direct_link_ika(fd, (Ika *)id); - break; case ID_WO: direct_link_world(fd, (World *)id); break; @@ -3313,9 +3273,9 @@ static int map_223_keybd_code_to_224_keybd_code(int code) } } -static void do_versions(Main *main) +static void do_versions(FileData *fd, Main *main) { - /* watch it: pointers from libdata have not been converted */ + /* WATCH IT!!!: pointers from libdata have not been converted */ if(main->versionfile == 100) { /* tex->extend and tex->imageflag have changed: */ @@ -3524,23 +3484,9 @@ static void do_versions(Main *main) if(main->versionfile <= 165) { Mesh *me= main->mesh.first; TFace *tface; - Ika *ika= main->ika.first; - Deform *def; int nr; char *cp; - while(ika) { - ika->xyconstraint= .5; - - def= ika->def; - nr= ika->totdef; - while(nr--) { - if(def->fac==0.0) def->fac= 1.0; - def++; - } - ika= ika->id.next; - } - while(me) { if(me->tface) { nr= me->totface; @@ -4021,12 +3967,6 @@ static void do_versions(Main *main) ob = ob->id.next; } - /* Precalculate rest position matrices for old armatures. -rvo - */ - for (arm= main->armature.first; arm; arm= arm->id.next) { - precalc_bonelist_irestmats (&arm->bonebase); - } - /* Began using alpha component of vertex colors, but * old file vertex colors are undefined, reset them * to be fully opaque. -zr @@ -4129,17 +4069,6 @@ static void do_versions(Main *main) sound->packedfile = NULL; } } - - /* Clear some (now) unused pose flags */ - for (ob=main->object.first; ob; ob=ob->id.next){ - if (ob->pose){ - bPoseChannel *pchan; - for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next){ - pchan->flag &= ~(POSE_UNUSED1|POSE_UNUSED2|POSE_UNUSED3|POSE_UNUSED4|POSE_UNUSED5); - } - } - } - /* Make sure that old subsurf meshes don't have zero subdivision level for rendering */ for (me=main->mesh.first; me; me=me->id.next){ if ((me->flag & ME_SUBSURF) && (me->subdivr==0)) @@ -4761,7 +4690,33 @@ static void do_versions(Main *main) } } } + if(main->versionfile <= 237) { + bArmature *arm; + bPoseChannel *pchan; + Object *ob; + + // armature recode checks + for(arm= main->armature.first; arm; arm= arm->id.next) { + where_is_armature(arm); + } + for(ob= main->object.first; ob; ob= ob->id.next) { + // btw. armature_rebuild_pose is further only called on leave editmode + if(ob->pose) { + ob->pose->flag |= POSE_RECALC; + ob->recalc |= OB_RECALC; + + /* initialize for IK caching. we check for zero, so new saved files go fine */ + pchan= ob->pose->chanbase.first; + if(pchan && pchan->ik_mat[0][0]==0.0 && pchan->ik_mat[0][1]==0.0 && pchan->ik_mat[0][2]==0.0) { + for(; pchan; pchan= pchan->next) + Mat3One(pchan->ik_mat); + } + } + } + } + /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ + /* don't forget to set version number in blender.c! */ } @@ -4780,7 +4735,6 @@ static void lib_link_all(FileData *fd, Main *main) lib_link_world(fd, main); lib_link_lamp(fd, main); lib_link_latt(fd, main); - lib_link_ika(fd, main); lib_link_text(fd, main); lib_link_camera(fd, main); lib_link_sound(fd, main); @@ -4861,7 +4815,7 @@ BlendFileData *blo_read_file_internal(FileData *fd, BlendReadError *error_r) } /* before read_libraries */ - do_versions(bfd->main); + do_versions(fd, bfd->main); read_libraries(fd, &fd->mainlist); blo_join_main(&fd->mainlist); @@ -5142,8 +5096,6 @@ static void expand_bones(FileData *fd, Main *mainvar, Bone *bone) { Bone *curBone; -// expand_constraints(fd, main, &bone->constraints); - for (curBone = bone->childbase.first; curBone; curBone=curBone->next) { expand_bones(fd, mainvar, curBone); } @@ -5522,6 +5474,8 @@ void BLO_script_library_append(BlendHandle *bh, char *dir, char *name, int idcod G.main= mainlist.first; lib_link_all(fd, G.main); + + DAG_scene_sort(G.scene); } /* append to G.scene */ @@ -5647,7 +5601,7 @@ void BLO_library_append(SpaceFile *sfile, char *dir, int idcode) /* restore the 'last loaded filename' */ BLI_strncpy(G.sce, filename, sizeof(filename)); - + DAG_scene_sort(G.scene); } /* ************* READ LIBRARY ************** */ @@ -5764,10 +5718,10 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) /* some mains still have to be read, then * versionfile is still zero! */ - if(mainptr->versionfile) do_versions(mainptr); + if(mainptr->versionfile) do_versions(mainptr->curlib->filedata, mainptr); if(mainptr->curlib->filedata) blo_freefiledata(mainptr->curlib->filedata); - mainptr->curlib->filedata= 0; + mainptr->curlib->filedata= NULL; mainptr= mainptr->next; } diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 2b87df727ec..b1e86f7ad85 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -110,7 +110,6 @@ Important to know is that 'streaming' has been added to files, for Blender Publi #include "DNA_effect_types.h" #include "DNA_group_types.h" #include "DNA_image_types.h" -#include "DNA_ika_types.h" #include "DNA_ipo_types.h" #include "DNA_fileglobal_types.h" #include "DNA_key_types.h" @@ -1052,30 +1051,6 @@ static void write_lattices(WriteData *wd, ListBase *idbase) } } -static void write_ikas(WriteData *wd, ListBase *idbase) -{ - Ika *ika; - Limb *li; - - ika= idbase->first; - while(ika) { - if(ika->id.us>0 || wd->current) { - /* write LibData */ - writestruct(wd, ID_IK, "Ika", 1, ika); - - /* direct data */ - li= ika->limbbase.first; - while(li) { - writestruct(wd, DATA, "Limb", 1, li); - li= li->next; - } - - writestruct(wd, DATA, "Deform", ika->totdef, ika->def); - } - ika= ika->id.next; - } -} - static void write_scenes(WriteData *wd, ListBase *scebase) { Scene *sce; @@ -1565,7 +1540,6 @@ static int write_file_handle(int handle, MemFile *compare, MemFile *current, int write_cameras (wd, &G.main->camera); write_lamps (wd, &G.main->lamp); write_lattices (wd, &G.main->latt); - write_ikas (wd, &G.main->ika); write_vfonts (wd, &G.main->vfont); write_ipos (wd, &G.main->ipo); write_keys (wd, &G.main->key); diff --git a/source/blender/include/BDR_editcurve.h b/source/blender/include/BDR_editcurve.h index 18b5d1a53d0..461eaa81318 100644 --- a/source/blender/include/BDR_editcurve.h +++ b/source/blender/include/BDR_editcurve.h @@ -92,7 +92,6 @@ void add_primitiveNurb(int type); void clear_tilt(void); void clever_numbuts_curve(void); int bezt_compare (const void *e1, const void *e2); -void curve_changes_other_objects(struct Object *ob); extern void undo_push_curve(char *name); diff --git a/source/blender/include/BDR_editobject.h b/source/blender/include/BDR_editobject.h index 5d2a6f48e9a..f67fc40ec4d 100644 --- a/source/blender/include/BDR_editobject.h +++ b/source/blender/include/BDR_editobject.h @@ -53,8 +53,6 @@ void make_vertex_parent(void); int test_parent_loop(struct Object *par, struct Object *ob); void make_parent(void); -void make_displists_by_parent(struct Object *ob); - void exit_editmode(int freedata); void check_editmode(int type); void enter_editmode(void); @@ -106,8 +104,6 @@ void select_select_keys(void); int vergbaseco(const void *a1, const void *a2); void auto_timeoffs(void); void texspace_edit(void); -void first_base(void); -void make_displists_by_obdata(void *obdata); void flip_subdivison(struct Object *ob, int); void mirrormenu(void); diff --git a/source/blender/include/BIF_butspace.h b/source/blender/include/BIF_butspace.h index 437e0a2791d..0b2997f3317 100644 --- a/source/blender/include/BIF_butspace.h +++ b/source/blender/include/BIF_butspace.h @@ -43,7 +43,7 @@ extern void do_butspace(unsigned short event); extern void redraw_test_buttons(struct Object *new); /* buttons_editing.c */ -extern void rename_bone_ext(char *oldname, char *newname); +extern void validate_editbonebutton_cb(void *bonev, void *namev); /* buts->mainb old */ diff --git a/source/blender/include/BIF_editarmature.h b/source/blender/include/BIF_editarmature.h index df6d74cd036..77472ede8cf 100644 --- a/source/blender/include/BIF_editarmature.h +++ b/source/blender/include/BIF_editarmature.h @@ -45,7 +45,6 @@ typedef struct EditBone void *temp; /* Used to store temporary data */ char name[32]; - char oldname[32]; float roll; /* Roll along axis. We'll ultimately use the axis/angle method for determining the transformation matrix of the bone. The axis is tail-head while roll provides the angle. Refer to Graphics @@ -56,8 +55,6 @@ typedef struct EditBone /* All joints are considered to have zero rotation with respect to their parents. Therefore any rotations specified during the animation are automatically relative to the bones' rest positions*/ - short sHead[2]; - short sTail[2]; int flag; int parNr; /* Used for retrieving values from the menu system */ @@ -67,12 +64,7 @@ typedef struct EditBone for pose element, rather than trying to use the existing transObject system? */ - float dist, weight; - float loc[3], dloc[3]; - float size[3], dsize[3]; - float rot[3], drot[3]; - float quat[4], dquat[4]; - float obmat[4][4]; + float dist, weight, length; short boneclass; @@ -85,8 +77,7 @@ void add_primitiveArmature(int type); void apply_rot_armature (struct Object *ob, float mat[3][3]); void clear_armature(struct Object *ob, char mode); -void clever_numbuts_armature (void); -void clever_numbuts_posearmature (void); + void delete_armature(void); void deselectall_armature(void); void deselectall_posearmature (int test); @@ -97,6 +88,8 @@ void join_armature(void); void load_editArmature(void); char* make_bone_menu(struct bArmature *arm); void make_bone_parent(void); +void clear_bone_parent(void); + void make_editArmature(void); void make_trans_bones (char mode); void mousepose_armature(void); @@ -109,7 +102,7 @@ void unique_editbone_name (char* name); void attach_bone_to_parent(EditBone *bone); void attach_bone_to_parent_cb(void *bonev, void *arg2_unused); -struct Bone *get_first_selected_bone (void); + void auto_align_armature(void); void create_vgroups_from_armature(Object *ob, Object *par); @@ -123,9 +116,15 @@ int ik_chain_looper(Object *ob, struct Bone *bone, void *data, int (*bone_func)(Object *, struct Bone *, void *)); int is_delay_deform(void); -#define BONESEL_TIP 0x08000000 -#define BONESEL_ROOT 0x04000000 -#define BONESEL_BONE (BONESEL_TIP|BONESEL_ROOT) +void undo_push_armature(char *name); +void armature_bone_rename(struct bArmature *arm, char *oldname, char *newname); + + +#define BONESEL_ROOT 0x02000000 +#define BONESEL_TIP 0x04000000 +#define BONESEL_BONE 0x08000000 +#define BONESEL_ANY (BONESEL_TIP|BONESEL_ROOT|BONESEL_BONE) + #define BONESEL_NOSEL 0x80000000 /* Indicates a negative number */ #endif diff --git a/source/blender/include/BIF_editconstraint.h b/source/blender/include/BIF_editconstraint.h index 8d983fe32e0..af7765cf1b2 100644 --- a/source/blender/include/BIF_editconstraint.h +++ b/source/blender/include/BIF_editconstraint.h @@ -54,8 +54,8 @@ void add_constraint_to_object(struct bConstraint *con, struct Object *ob); void add_constraint_to_client(struct bConstraint *con); struct ListBase *get_constraint_client_channels (int forcevalid); struct ListBase *get_constraint_client(char *name, short *clienttype, void** clientdata); -int test_constraints (struct Object *owner, const char *substring, int disable); -void test_scene_constraints (void); + +void object_test_constraints(struct Object *owner); char *get_con_subtarget_name(struct bConstraint *constraint, struct Object *target); diff --git a/source/blender/include/BIF_editfont.h b/source/blender/include/BIF_editfont.h index aa52c87e461..372630da8e2 100644 --- a/source/blender/include/BIF_editfont.h +++ b/source/blender/include/BIF_editfont.h @@ -50,7 +50,6 @@ void txt_export_to_objects(struct Text *text); void undo_push_font(char *); void load_3dtext_fs(char *); void add_lorem(void); -void text_makedisplist(struct Object *ob); /** * @attention The argument is discarded. It is there for diff --git a/source/blender/include/BIF_editika.h b/source/blender/include/BIF_editika.h deleted file mode 100644 index 9160d7e4baf..00000000000 --- a/source/blender/include/BIF_editika.h +++ /dev/null @@ -1,39 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL/BL DUAL 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. The Blender - * Foundation also sells licenses for use in proprietary software under - * the Blender License. See http://www.blender.org/BL/ for information - * about this. - * - * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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/BL DUAL LICENSE BLOCK ***** - */ - -struct Object; -void draw_ika(struct Object *ob, int sel); -void draw_ika_nrs(struct Object *ob, int type); -int extrude_ika(struct Object *ob, int add); -void delete_skeleton(void); -void make_skeleton(void); - diff --git a/source/blender/include/BIF_outliner.h b/source/blender/include/BIF_outliner.h index f306cdbb1b2..448a6be5884 100644 --- a/source/blender/include/BIF_outliner.h +++ b/source/blender/include/BIF_outliner.h @@ -63,6 +63,8 @@ typedef struct TreeElement { #define TSE_HOOKS_BASE 9 #define TSE_HOOK 10 #define TSE_SCRIPT_BASE 11 +#define TSE_POSE_BASE 12 +#define TSE_POSE_CHANNEL 13 /* button events */ #define OL_NAMEBUTTON 1 diff --git a/source/blender/include/BIF_poseobject.h b/source/blender/include/BIF_poseobject.h index 872584edfe9..9859a2598ed 100644 --- a/source/blender/include/BIF_poseobject.h +++ b/source/blender/include/BIF_poseobject.h @@ -39,15 +39,10 @@ void enter_posemode(void); /** - * Provides the current object the opportunity to specify - * which channels to key in the current pose (if any). - * If an object provides its own filter, it must clear - * then POSE_KEY flags of unwanted channels, as well as - * setting the flags for desired channels. - * - * Default behaviour is to key all channels. - */ -void filter_pose_keys(void); +* If bones are selected, it sets the flags +*/ +struct Object; +void set_pose_keys(struct Object *ob); /** * Deactivates posemode @@ -55,11 +50,7 @@ void filter_pose_keys(void); */ void exit_posemode(int freedata); -/** - * Removes unreferenced pose channels from an object - * @param ob Object to check - */ -void collect_pose_garbage(struct Object *ob); +void pose_special_editmenu(void); #endif diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h index 8cc6ad4519d..5ebdd4d5a1a 100644 --- a/source/blender/include/butspace.h +++ b/source/blender/include/butspace.h @@ -137,6 +137,8 @@ void test_idbutton_cb(void *namev, void *arg2_unused); #define B_ARMATUREPANEL1 1009 #define B_ARMATUREPANEL2 1010 #define B_OBJECTPANELPARENT 1011 +#define B_OBJECTPANEL 1012 +#define B_ARMATUREPANEL3 1013 /* *********************** */ #define B_LAMPBUTS 1200 @@ -300,6 +302,7 @@ enum { /* *********************** */ #define B_COMMONEDITBUTS 2049 +#define B_CHANGEDEP 2002 #define B_MATWICH 2003 #define B_MATNEW 2004 #define B_MATDEL 2005 @@ -405,10 +408,7 @@ enum { #define B_STYLETOSEL 2212 /* *********************** */ -#define B_IKABUTS 2400 -#define B_IKASETREF 2301 -#define B_IKARECALC 2302 /* *********************** */ #define B_CAMBUTS 2500 diff --git a/source/blender/include/transform.h b/source/blender/include/transform.h index c7c6ceb3cc3..69e9f1d919c 100755 --- a/source/blender/include/transform.h +++ b/source/blender/include/transform.h @@ -246,9 +246,9 @@ int PushPull(TransInfo *t, short mval[2]); void initCrease(TransInfo *t); int Crease(TransInfo *t, short mval[2]); -/* exported from transform.c */ +/*********************** transform_conversions.c ********** */ struct ListBase; -void count_bone_select(TransInfo *t, struct ListBase *lb, int *counter); +void count_bone_select(TransInfo *t, struct ListBase *lb, int do_it); /*********************** exported from transform_manipulator.c ********** */ struct ScrArea; @@ -260,7 +260,7 @@ void createTransData(TransInfo *t); void sort_trans_data_dist(TransInfo *t); void clear_trans_object_base_flags(void); void add_tdi_poin(float *poin, float *old, float delta); -void special_aftertrans_update(char mode, int flip, short canceled, int keyflags); +void special_aftertrans_update(char mode, int flip, short canceled); /*********************** Constraints *****************************/ void getConstraintMatrix(TransInfo *t); diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h index 94c9bcf5d88..9e4480431e3 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -28,9 +28,7 @@ * 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. + * Contributor(s): Full recode, Ton Roosendaal, Crete 2005 * * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ @@ -44,22 +42,40 @@ #include "DNA_view2d_types.h" struct SpaceLink; +struct ListBase; + +/* PoseChannel stores the results of Actions (ipos) and transform information + with respect to the restposition of Armature bones */ -typedef struct bPoseChannel{ +typedef struct bPoseChannel { struct bPoseChannel *next, *prev; ListBase constraints; - int flag; - float loc[3]; - float size[3]; - float quat[4]; - float obmat[4][4]; char name[32]; /* Channels need longer names than normal blender objects */ - int reserved1; + short flag; /* dynamic, for detecting transform changes */ + short constflag; /* for quick detecting which constraints affect this channel */ + int depth; /* dependency sorting help */ + + struct Bone *bone; /* set on read file or rebuild pose */ + struct bPoseChannel *parent; /* set on read file or rebuild pose */ + struct ListBase chain; /* only while evaluating pose */ + + float loc[3]; /* written in by actions or transform */ + float size[3]; + float quat[4]; + + float chan_mat[4][4]; /* matrix result of loc/quat/size , and where we put deform in, see next line */ + float pose_mat[4][4]; /* constraints accumulate here. in the end, pose_mat = bone->arm_mat * chan_mat */ + float ik_mat[3][3]; /* for itterative IK */ + + float pose_head[3]; /* actually pose_mat[3] */ + float pose_tail[3]; /* also used for drawing help lines... */ + int pad; } bPoseChannel; typedef struct bPose{ ListBase chanbase; + int flag, pad; } bPose; typedef struct bActionChannel { @@ -100,5 +116,31 @@ typedef struct SpaceAction { #define ACHAN_SELECTED 0x00000001 #define ACHAN_HILIGHTED 0x00000002 +/* Pose->flag */ + +#define POSE_RECALC 1 + +/* PoseChannel (transform) flags */ +enum { + POSE_LOC = 0x0001, + POSE_ROT = 0x0002, + POSE_SIZE = 0x0004, + POSE_IK_MAT = 0x0008, + POSE_UNUSED2 = 0x0010, + POSE_UNUSED3 = 0x0020, + POSE_UNUSED4 = 0x0040, + POSE_UNUSED5 = 0x0080, + POSE_OBMAT = 0x0100, + POSE_PARMAT = 0x0200, + POSE_DONE = 0x0400, + POSE_KEY = 0x1000 +}; + +/* Pose Channel constflag (constraint) */ +#define PCHAN_HAS_IK 1 +#define PCHAN_HAS_TRACK 2 +#define PCHAN_HAS_CONST 4 + + #endif diff --git a/source/blender/makesdna/DNA_armature_types.h b/source/blender/makesdna/DNA_armature_types.h index 5124716bc51..07633090902 100644 --- a/source/blender/makesdna/DNA_armature_types.h +++ b/source/blender/makesdna/DNA_armature_types.h @@ -23,9 +23,7 @@ * 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. + * Contributor(s): Full recode, Ton Roosendaal, Crete 2005 * * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ @@ -36,35 +34,37 @@ #include "DNA_listBase.h" #include "DNA_ID.h" +/* this system works on different transformation space levels; + +1) Bone Space; with each Bone having own (0,0,0) origin +2) Armature Space; the rest position, in Object space, Bones Spaces are applied hierarchical +3) Pose Space; the animation position, in Object space +4) World Space; Object matrix applied to Pose or Armature space + +*/ + typedef struct Bone { struct Bone *next, *prev; /* Next/prev elements within this list */ struct Bone *parent; /* Parent (ik parent if appropriate flag is set */ ListBase childbase; /* Children */ - char name[32]; /* Name of the bone - must be unique within the armature */ + char name[32]; /* Name of the bone - must be unique within the armature */ - float roll; - float head[3]; /* Orientation & length are implicit now */ - float tail[3]; /* head/tail represents rest state */ + float roll, length; /* */ + float head[3]; + float tail[3]; /* head/tail and roll in Bone Space */ + float bone_mat[3][3]; /* rotation derived from head/tail/roll */ + int flag; - - /* Transformation data used for posing: - The same information stored by other - blenderObjects - */ - - float dist, weight; - float loc[3], dloc[3]; - float size[3], dsize[3]; - float quat[4], dquat[4]; - float obmat[4][4]; - float parmat[4][4]; - float defmat[4][4]; - float irestmat[4][4]; /* Cached inverse of rest matrix (objectspace)*/ - float posemat[4][4]; /* Cached pose matrix (objectspace)*/ + + float arm_head[3]; + float arm_tail[3]; /* head/tail and roll in Armature Space (rest pos) */ + float arm_mat[4][4]; /* matrix: (bonemat(b)+head(b))*arm_mat(b-1), rest pos*/ + + float dist, weight; /* dist for non-deformgroup deforms */ + + float size[3]; /* patch for upward compat, UNUSED! */ short boneclass; - short filler1; - short filler2; - short filler3; + short pad1; }Bone; typedef struct bArmature { @@ -77,58 +77,46 @@ typedef struct bArmature { int res3; }bArmature; -enum { - ARM_RESTPOSBIT = 0, - ARM_DRAWXRAYBIT, - ARM_DRAWAXESBIT, - ARM_DRAWNAMESBIT, - ARM_POSEBIT, - ARM_EDITBIT, - ARM_DELAYBIT -}; +/* armature->flag */ +#define ARM_RESTPOSBIT 0 +#define ARM_DRAWXRAYBIT 1 +#define ARM_DRAWAXESBIT 2 +#define ARM_DRAWNAMESBIT 3 +#define ARM_POSEBIT 4 +#define ARM_EDITBIT 5 +#define ARM_DELAYBIT 6 +/* dont use bit 7, was saved in files to disable stuff */ +#define ARM_NO_ACTIONBIT 8 + +/* armature->flag */ +#define ARM_RESTPOS 0x0001 +#define ARM_DRAWXRAY 0x0002 +#define ARM_DRAWAXES 0x0004 +#define ARM_DRAWNAMES 0x0008 +#define ARM_POSEMODE 0x0010 +#define ARM_EDITMODE 0x0020 +#define ARM_DELAYDEFORM 0x0040 +#define ARM_DONT_USE 0x0080 +#define ARM_NO_ACTION 0x0100 + +/* bone->flag */ +#define BONE_SELECTED 1 +#define BONE_ROOTSEL 2 +#define BONE_TIPSEL 4 + /* Used instead of BONE_SELECTED during transform */ +#define BONE_TRANSFORM 8 +#define BONE_IK_TOPARENT 16 + /* 32 used to be quatrot, was always set in files, do not reuse unless you clear it always */ +#define BONE_HIDDEN 64 + /* For detecting cyclic dependancies */ +#define BONE_DONE 128 + /* active is on mouse clicks only */ +#define BONE_ACTIVE 256 + +/* bone->flag bits */ +#define BONE_IK_TOPARENTBIT 4 +#define BONE_HIDDENBIT 6 -enum { - ARM_RESTPOS = 0x00000001, - ARM_DRAWXRAY = 0x00000002, - ARM_DRAWAXES = 0x00000004, - ARM_DRAWNAMES = 0x00000008, - ARM_POSEMODE = 0x00000010, - ARM_EDITMODE = 0x00000020, - ARM_DELAYDEFORM = 0x00000040 -}; - -enum { - BONE_SELECTED = 0x00000001, - BONE_ROOTSEL = 0x00000002, - BONE_TIPSEL = 0x00000004, - - BONE_HILIGHTED = 0x00000008, - BONE_IK_TOPARENT= 0x00000010, - BONE_QUATROT = 0x00000020, - BONE_HIDDEN = 0x00000040, - - BONE_DONE = 0x00000080, /* For detecting cyclic dependancies */ - - BONE_ISEMPTY = 0x00000100, - BONE_ISMUSCLE = 0x00000200, - BONE_NOCALC = 0x00000400 /* Don't calculate bone - * transformation, when flagged - * (note: this is a temporary flag) - */ -}; - -enum { - BONE_SELECTEDBIT = 0, - BONE_HEADSELBIT, - BONE_TAILSELBIT, - BONE_HILIGHTEDBIT, - BONE_IK_TOPARENTBIT, - BONE_QUATROTBIT, - BONE_HIDDENBIT, - BONE_ISEMPTYBIT, - BONE_ISMUSCLEBIT, - BONE_NOCALCBIT -}; enum { BONE_SKINNABLE = 0, diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h index 06a7844b785..d7e4e97dce1 100644 --- a/source/blender/makesdna/DNA_constraint_types.h +++ b/source/blender/makesdna/DNA_constraint_types.h @@ -50,7 +50,6 @@ typedef struct bConstraintChannel{ typedef struct bConstraint{ struct bConstraint *next, *prev; void *data; /* Constraint data (a valid constraint type) */ - Ipo *ipo; /* Constraint ipo */ char type; /* Constraint type */ char otype; /* Old type - for menu callbacks */ short flag; /* Flag */ @@ -179,7 +178,7 @@ typedef struct bStretchToConstraint{ #define CONSTRAINT_DONE 0x00000002 #define CONSTRAINT_DISABLE 0x00000004 #define CONSTRAINT_LOOPTESTED 0x00000008 -#define CONSTRAINT_NOREFRESH 0x00000010 + #define CONSTRAINT_EXPAND_BIT 0 #define CONSTRAINT_DONE_BIT 1 diff --git a/source/blender/makesdna/DNA_ika_types.h b/source/blender/makesdna/DNA_ika_types.h deleted file mode 100644 index 2ddbc4ed4a3..00000000000 --- a/source/blender/makesdna/DNA_ika_types.h +++ /dev/null @@ -1,93 +0,0 @@ -/** - * blenlib/DNA_ika_types.h (mar-2001 nzc) - * - * Old ika types. These have been superceded by Reevan's stuff - * (armatures and bones) - * - * Can be removed! (ton) - * - * $Id$ - * - * ***** BEGIN GPL/BL DUAL 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. The Blender - * Foundation also sells licenses for use in proprietary software under - * the Blender License. See http://www.blender.org/BL/ for information - * about this. - * - * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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/BL DUAL LICENSE BLOCK ***** - */ -#ifndef DNA_IKA_TYPES_H -#define DNA_IKA_TYPES_H - -#include "DNA_listBase.h" -#include "DNA_ID.h" - -struct Object; -struct Ipo; - -typedef struct Deform { - struct Object *ob; - short flag, partype; - int par1, par2, par3; /* can be vertexnrs */ - float imat[4][4], premat[4][4], postmat[4][4]; - float vec[3]; /* when partype==LIMB, for distfunc */ - float fac, dist, pad; - -} Deform; - -typedef struct Limb { - struct Limb *next, *prev; - - float len, leno, fac, alpha, alphao, pad; - float eff[2]; - -} Limb; - -typedef struct Ika { - ID id; - - short partype, flag, iter, lastfra; - - ListBase limbbase; - float eff[3], effg[3], effn[3]; - float mem, slow, toty, totx, xyconstraint; - - struct Ipo *ipo; - struct Object *parent; - int par1, par2, par3; - - int totdef; - Deform *def; - - int def_scroll; - int limb_scroll; -} Ika; - -/* these defines are used for working with ikas*/ - -/* ika.flag: */ -#define IK_GRABEFF 1 -#define IK_XYCONSTRAINT 2 - -#endif - diff --git a/source/blender/makesdna/DNA_ipo_types.h b/source/blender/makesdna/DNA_ipo_types.h index 5dccadb00ab..352a2589c14 100644 --- a/source/blender/makesdna/DNA_ipo_types.h +++ b/source/blender/makesdna/DNA_ipo_types.h @@ -59,7 +59,6 @@ typedef short IPO_Channel; #define TOB_IPO 1 #define TOB_IPODROT 2 -#define TOB_IKA 4 /* disptype */ #define IPO_DISPDEGR 1 @@ -96,10 +95,6 @@ typedef short IPO_Channel; #define OB_TIME 20 -#define OB_EFF_X 21 -#define OB_EFF_Y 22 -#define OB_EFF_Z 23 - #define OB_COL_R 21 #define OB_COL_G 22 #define OB_COL_B 23 diff --git a/source/blender/makesdna/DNA_key_types.h b/source/blender/makesdna/DNA_key_types.h index 9bdbc2fbeed..7f4d4125cb5 100644 --- a/source/blender/makesdna/DNA_key_types.h +++ b/source/blender/makesdna/DNA_key_types.h @@ -70,14 +70,18 @@ typedef struct Key { short type, totkey; short slurph, actkey; + short flag, pad1; + int pad2; } Key; /* **************** KEY ********************* */ -/* type */ +/* key->type */ #define KEY_NORMAL 0 #define KEY_RELATIVE 1 +/* key->flag */ +#define KEY_LOCKED 1 /* keyblock->type */ #define KEY_LINEAR 0 diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index ea49d73cd04..92665f1804a 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -176,7 +176,8 @@ typedef struct Object { * bit 15: Always ignore activity culling */ int gameflag2; - short softflag, dummy; /* temporal stuff softbody experiment */ + short softflag; /* softboday settings */ + short recalc; /* dependency flag */ float anisotropicFriction[3]; ListBase constraints; @@ -232,19 +233,18 @@ extern Object workob; #define OB_LAMP 10 #define OB_CAMERA 11 -#define OB_IKA 20 #define OB_WAVE 21 #define OB_LATTICE 22 /* 23 and 24 are for life and sector (old file compat.) */ #define OB_ARMATURE 25 -/* partype: eerste 5 bits: type */ +/* partype: first 4 bits: type */ #define PARTYPE 15 #define PAROBJECT 0 #define PARCURVE 1 #define PARKEY 2 -#define PARLIMB 3 + #define PARSKEL 4 #define PARVERT1 5 #define PARVERT3 6 @@ -313,12 +313,13 @@ extern Object workob; /* also needed for base!!!!! or rather, thy interfere....*/ /* base->flag and ob->flag */ -#define BA_WASSEL 2 -#define BA_PARSEL 4 -#define BA_WHERE_UPDATE 8 -#define BA_DISP_UPDATE 16 +#define BA_WAS_SEL 2 +#define BA_HAS_RECALC_OB 4 +#define BA_HAS_RECALC_DATA 8 + #define BA_DO_IPO 32 #define OB_GONNA_MOVE 32 + #define BA_FROMSET 128 #define OB_DO_IMAT 256 #define OB_FROMDUPLI 512 @@ -327,6 +328,12 @@ extern Object workob; #define OB_FROMGROUP 4096 #define OB_POSEMODE 8192 +/* ob->recalc (flag bits!) */ +#define OB_RECALC_OB 1 +#define OB_RECALC_DATA 2 +#define OB_RECALC 3 + + /* ob->gameflag */ #define OB_DYNAMIC 1 #define OB_CHILD 2 diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c index b550d18bdb2..200639cd402 100644 --- a/source/blender/makesdna/intern/makesdna.c +++ b/source/blender/makesdna/intern/makesdna.c @@ -110,7 +110,6 @@ char *includefiles[] = { "DNA_fileglobal_types.h", "DNA_sequence_types.h", "DNA_effect_types.h", - "DNA_ika_types.h", "DNA_oops_types.h", "DNA_property_types.h", "DNA_sensor_types.h", @@ -1123,7 +1122,6 @@ int main(int argc, char ** argv) #include "DNA_fileglobal_types.h" #include "DNA_sequence_types.h" #include "DNA_effect_types.h" -#include "DNA_ika_types.h" #include "DNA_oops_types.h" #include "DNA_property_types.h" #include "DNA_sensor_types.h" diff --git a/source/blender/python/api2_2x/Armature.c b/source/blender/python/api2_2x/Armature.c index a1c0e5eea9a..422016b93fe 100644 --- a/source/blender/python/api2_2x/Armature.c +++ b/source/blender/python/api2_2x/Armature.c @@ -610,9 +610,9 @@ static PyObject *Armature_addBone( BPy_Armature * self, PyObject * args ) //rebuild_bone_parent_matrix(py_bone->bone); - precalc_bonelist_irestmats( &self->armature->bonebase ); - precalc_armature_posemats( self->armature ); - precalc_bone_defmat( py_bone->bone ); + //precalc_bonelist_irestmats( &self->armature->bonebase ); + //precalc_armature_posemats( self->armature ); + //precalc_bone_defmat( py_bone->bone ); Py_INCREF( Py_None ); return Py_None; diff --git a/source/blender/python/api2_2x/Bone.c b/source/blender/python/api2_2x/Bone.c index 686b791a846..7c96a02d595 100644 --- a/source/blender/python/api2_2x/Bone.c +++ b/source/blender/python/api2_2x/Bone.c @@ -91,12 +91,14 @@ static PyObject *Bone_setName( BPy_Bone * self, PyObject * args ); static PyObject *Bone_setRoll( BPy_Bone * self, PyObject * args ); static PyObject *Bone_setHead( BPy_Bone * self, PyObject * args ); static PyObject *Bone_setTail( BPy_Bone * self, PyObject * args ); + // note; this can only be done as POSE operation static PyObject *Bone_setLoc( BPy_Bone * self, PyObject * args ); static PyObject *Bone_setSize( BPy_Bone * self, PyObject * args ); static PyObject *Bone_setQuat( BPy_Bone * self, PyObject * args ); +static PyObject *Bone_setPose( BPy_Bone * self, PyObject * args ); + static PyObject *Bone_setParent( BPy_Bone * self, PyObject * args ); static PyObject *Bone_setWeight( BPy_Bone * self, PyObject * args ); -static PyObject *Bone_setPose( BPy_Bone * self, PyObject * args ); static PyObject *Bone_setBoneclass( BPy_Bone * self, PyObject * args ); static PyObject *Bone_getRestMatrix( BPy_Bone * self, PyObject * args ); @@ -261,7 +263,7 @@ static int updatePyBone( BPy_Bone * self ) BLI_strncpy( self->parent, parent_str, strlen( parent_str ) + 1 ); } - +#if 0 for( x = 0; x < 3; x++ ) { self->head->vec[x] = self->bone->head[x]; self->tail->vec[x] = self->bone->tail[x]; @@ -288,6 +290,7 @@ static int updatePyBone( BPy_Bone * self ) self->bone->posemat[x][y]; } } +#endif return 1; } } @@ -315,27 +318,27 @@ int updateBoneData( BPy_Bone * self, Bone * parent ) for( x = 0; x < 3; x++ ) { self->bone->head[x] = self->head->vec[x]; self->bone->tail[x] = self->tail->vec[x]; - self->bone->loc[x] = self->loc->vec[x]; - self->bone->dloc[x] = self->dloc->vec[x]; - self->bone->size[x] = self->size->vec[x]; - self->bone->dsize[x] = self->dsize->vec[x]; +// self->bone->loc[x] = self->loc->vec[x]; +// self->bone->dloc[x] = self->dloc->vec[x]; +// self->bone->size[x] = self->size->vec[x]; +// self->bone->dsize[x] = self->dsize->vec[x]; } for( x = 0; x < 4; x++ ) { - self->bone->quat[x] = self->quat->quat[x]; - self->bone->dquat[x] = self->dquat->quat[x]; +// self->bone->quat[x] = self->quat->quat[x]; +// self->bone->dquat[x] = self->dquat->quat[x]; } for( x = 0; x < 4; x++ ) { for( y = 0; y < 4; y++ ) { - self->bone->obmat[x][y] = - self->obmat->matrix[x][y]; - self->bone->parmat[x][y] = - self->parmat->matrix[x][y]; - self->bone->defmat[x][y] = - self->defmat->matrix[x][y]; - self->bone->irestmat[x][y] = - self->irestmat->matrix[x][y]; - self->bone->posemat[x][y] = - self->posemat->matrix[x][y]; +// self->bone->obmat[x][y] = +// self->obmat->matrix[x][y]; +// self->bone->parmat[x][y] = +// self->parmat->matrix[x][y]; +// self->bone->defmat[x][y] = +// self->defmat->matrix[x][y]; +// self->bone->irestmat[x][y] = +// self->irestmat->matrix[x][y]; +// self->bone->posemat[x][y] = +// self->posemat->matrix[x][y]; } } return 1; @@ -828,9 +831,10 @@ static PyObject *Bone_getLoc( BPy_Bone * self ) //use bone datastruct attr = newVectorObject( PyMem_Malloc( 3 * sizeof( float ) ), 3 ); - ( ( VectorObject * ) attr )->vec[0] = self->bone->loc[0]; - ( ( VectorObject * ) attr )->vec[1] = self->bone->loc[1]; - ( ( VectorObject * ) attr )->vec[2] = self->bone->loc[2]; + +// ( ( VectorObject * ) attr )->vec[0] = self->bone->loc[0]; +// ( ( VectorObject * ) attr )->vec[1] = self->bone->loc[1]; +// ( ( VectorObject * ) attr )->vec[2] = self->bone->loc[2]; } if( attr ) return attr; @@ -856,9 +860,9 @@ static PyObject *Bone_getSize( BPy_Bone * self ) //use bone datastruct attr = newVectorObject( PyMem_Malloc( 3 * sizeof( float ) ), 3 ); - ( ( VectorObject * ) attr )->vec[0] = self->bone->size[0]; - ( ( VectorObject * ) attr )->vec[1] = self->bone->size[1]; - ( ( VectorObject * ) attr )->vec[2] = self->bone->size[2]; +// ( ( VectorObject * ) attr )->vec[0] = self->bone->size[0]; +// ( ( VectorObject * ) attr )->vec[1] = self->bone->size[1]; +// ( ( VectorObject * ) attr )->vec[2] = self->bone->size[2]; } if( attr ) return attr; @@ -885,10 +889,10 @@ static PyObject *Bone_getQuat( BPy_Bone * self ) //use bone datastruct attr = newQuaternionObject( PyMem_Malloc ( 4 * sizeof( float ) ) ); - ( ( QuaternionObject * ) attr )->quat[0] = self->bone->quat[0]; - ( ( QuaternionObject * ) attr )->quat[1] = self->bone->quat[1]; - ( ( QuaternionObject * ) attr )->quat[2] = self->bone->quat[2]; - ( ( QuaternionObject * ) attr )->quat[3] = self->bone->quat[3]; +// ( ( QuaternionObject * ) attr )->quat[0] = self->bone->quat[0]; +// ( ( QuaternionObject * ) attr )->quat[1] = self->bone->quat[1]; +// ( ( QuaternionObject * ) attr )->quat[2] = self->bone->quat[2]; +// ( ( QuaternionObject * ) attr )->quat[3] = self->bone->quat[3]; } return attr; @@ -1095,9 +1099,9 @@ static PyObject *Bone_setLoc( BPy_Bone * self, PyObject * args ) self->loc->vec[2] = f3; } else { //use bone datastruct - self->bone->loc[0] = f1; - self->bone->loc[1] = f2; - self->bone->loc[2] = f3; +// self->bone->loc[0] = f1; +// self->bone->loc[1] = f2; +// self->bone->loc[2] = f3; } return EXPP_incr_ret( Py_None ); } @@ -1124,9 +1128,9 @@ static PyObject *Bone_setSize( BPy_Bone * self, PyObject * args ) self->size->vec[2] = f3; } else { //use bone datastruct - self->bone->size[0] = f1; - self->bone->size[1] = f2; - self->bone->size[2] = f3; +// self->bone->size[0] = f1; +// self->bone->size[1] = f2; +// self->bone->size[2] = f3; } return EXPP_incr_ret( Py_None ); } @@ -1168,10 +1172,10 @@ static PyObject *Bone_setQuat( BPy_Bone * self, PyObject * args ) self->quat->quat[3] = f4; } else { //use bone datastruct - self->bone->quat[0] = f1; - self->bone->quat[1] = f2; - self->bone->quat[2] = f3; - self->bone->quat[3] = f4; +// self->bone->quat[0] = f1; +// self->bone->quat[1] = f2; +// self->bone->quat[2] = f3; +// self->bone->quat[3] = f4; } return EXPP_incr_ret( Py_None ); } @@ -1543,19 +1547,22 @@ static PyObject *Bone_setPose( BPy_Bone * self, PyObject * args ) object->pose = MEM_callocN( sizeof( bPose ), "Pose" ); //if bone does have a channel create one - verify_pose_channel( object->pose, self->bone->name ); + // do not use anymore! (ton) + chan= verify_pose_channel( object->pose, self->bone->name ); + //create temp Pose Channel - chan = MEM_callocN( sizeof( bPoseChannel ), "PoseChannel" ); + // chan = MEM_callocN( sizeof( bPoseChannel ), "PoseChannel" ); //set the variables for this pose - memcpy( chan->loc, self->bone->loc, sizeof( chan->loc ) ); - memcpy( chan->quat, self->bone->quat, sizeof( chan->quat ) ); - memcpy( chan->size, self->bone->size, sizeof( chan->size ) ); +// memcpy( chan->loc, self->bone->loc, sizeof( chan->loc ) ); +// memcpy( chan->quat, self->bone->quat, sizeof( chan->quat ) ); +// memcpy( chan->size, self->bone->size, sizeof( chan->size ) ); strcpy( chan->name, self->bone->name ); chan->flag |= flagValue; //set it to the channel - setChan = set_pose_channel( object->pose, chan ); + // setChan = set_pose_channel( object->pose, chan ); //frees unlinked pose/bone channels from object - collect_pose_garbage( object ); +/* note; changing an Armature requires building poses again, consult me! (ton) */ + // collect_pose_garbage( object ); //create an action if one not already assigned to object if( !py_action && !object->action ) { @@ -1600,8 +1607,8 @@ static PyObject *Bone_setPose( BPy_Bone * self, PyObject * args ) //rebuild ipos remake_action_ipos( object->action ); - //rebuild displists - rebuild_all_armature_displists( ); + //signal to rebuild displists (new! added by ton) + object->recalc |= OB_RECALC_DATA; } return EXPP_incr_ret( Py_None ); } @@ -1667,6 +1674,11 @@ static PyObject *Bone_hasIK( BPy_Bone * self ) } //--------------- BPy_Bone.getRestMatrix()------------------------- + +/* we now got BoneSpace, ArmatureSpace, PoseSpace, WorldSpace. + check DNA_armature.h, only read from data itself, dont use evil calls + that evaluate animation system anymore (ton) */ + static PyObject *Bone_getRestMatrix( BPy_Bone * self, PyObject * args ) { char *local = "worldspace"; @@ -1691,8 +1703,8 @@ static PyObject *Bone_getRestMatrix( BPy_Bone * self, PyObject * args ) //use python vars if( BLI_streq( local, worldspace ) ) { VecSubf( delta, self->tail->vec, self->head->vec ); - make_boneMatrixvr( (float ( * )[4]) *( ( MatrixObject * ) matrix )-> - matrix, delta, self->roll ); +// make_boneMatrixvr( (float ( * )[4]) *( ( MatrixObject * ) matrix )-> +// matrix, delta, self->roll ); } else if( BLI_streq( local, bonespace ) ) { return ( EXPP_ReturnPyObjError( PyExc_AttributeError, "bone not yet linked to an armature....'" ) ); @@ -1706,12 +1718,13 @@ static PyObject *Bone_getRestMatrix( BPy_Bone * self, PyObject * args ) 1 ); } else if( BLI_streq( local, bonespace ) ) { VecSubf( delta, self->bone->tail, self->bone->head ); - make_boneMatrixvr( (float ( * )[4]) *( ( MatrixObject * ) matrix )-> - matrix, delta, self->bone->roll ); +// make_boneMatrixvr( (float ( * )[4]) *( ( MatrixObject * ) matrix )-> +// matrix, delta, self->bone->roll ); if( self->bone->parent ) { - get_bone_root_pos( self->bone, root, 1 ); - get_bone_root_pos( self->bone->parent, p_root, - 1 ); + +// get_bone_root_pos( self->bone, root, 1 ); +// get_bone_root_pos( self->bone->parent, p_root, +// 1 ); VecSubf( delta, root, p_root ); VECCOPY( ( ( MatrixObject * ) matrix )-> matrix[3], delta ); diff --git a/source/blender/python/api2_2x/Object.c b/source/blender/python/api2_2x/Object.c index 40412520797..67a94a8b4fd 100644 --- a/source/blender/python/api2_2x/Object.c +++ b/source/blender/python/api2_2x/Object.c @@ -46,15 +46,15 @@ #include "DNA_object_force.h" #include <DNA_property_types.h> -#include <BSE_edit.h> - +#include <BKE_depsgraph.h> +#include <BKE_font.h> #include <BKE_property.h> #include <BKE_mball.h> -#include <BKE_font.h> #include <BKE_softbody.h> #include <BIF_editview.h> #include <BSE_editipo.h> +#include <BSE_edit.h> #include "Ipo.h" #include "Lattice.h" @@ -581,7 +581,6 @@ PyObject *M_Object_New( PyObject * self, PyObject * args ) type = OB_CURVE; else if (strcmp (str_type, "Text") == 0) type = OB_FONT; -/* else if (strcmp (str_type, "Ika") == 0) type = OB_IKA; */ else if( strcmp( str_type, "Lamp" ) == 0 ) type = OB_LAMP; else if( strcmp( str_type, "Lattice" ) == 0 ) @@ -865,7 +864,7 @@ static PyObject *Object_clrParent( BPy_Object * self, PyObject * args ) } if( !fast ) { - sort_baselist( G.scene ); + DAG_scene_sort( G.scene ); } Py_INCREF( Py_None ); @@ -891,7 +890,7 @@ static PyObject *Object_clearTrack( BPy_Object * self, PyObject * args ) } if( !fast ) { - sort_baselist( G.scene ); + DAG_scene_sort( G.scene ); } Py_INCREF( Py_None ); @@ -941,10 +940,6 @@ int EXPP_add_obdata( struct Object *object ) case OB_FONT: object->data = add_curve(OB_FONT); break; - case OB_IKA: - object->data = add_ika(); - object->dt = OB_WIRE; - break; case OB_WAVE: object->data = add_wave(); break; @@ -1290,8 +1285,6 @@ static PyObject *Object_getType( BPy_Object * self ) return ( Py_BuildValue( "s", "Empty" ) ); case OB_FONT: return ( Py_BuildValue( "s", "Text" ) ); - case OB_IKA: - return ( Py_BuildValue( "s", "Ika" ) ); case OB_LAMP: return ( Py_BuildValue( "s", "Lamp" ) ); case OB_LATTICE: @@ -1597,7 +1590,7 @@ static PyObject *Object_makeParent( BPy_Object * self, PyObject * args ) } if( !fast ) { - sort_baselist( G.scene ); + DAG_scene_sort( G.scene ); } // We don't need the child object anymore. Py_DECREF (py_child); @@ -1984,7 +1977,7 @@ static PyObject *Object_makeTrack( BPy_Object * self, PyObject * args ) ob->track = tracked->object; if( !fast ) - sort_baselist( G.scene ); + DAG_scene_sort( G.scene ); return EXPP_incr_ret( Py_None ); } @@ -2414,7 +2407,6 @@ static void Object_dealloc( BPy_Object * obj ) static PyObject *Object_getAttr( BPy_Object * obj, char *name ) { struct Object *object; - struct Ika *ika; object = obj->object; if( StringEqual( name, "LocX" ) ) @@ -2475,25 +2467,7 @@ static PyObject *Object_getAttr( BPy_Object * obj, char *name ) return ( Py_BuildValue ( "fff", object->dsize[0], object->dsize[1], object->dsize[2] ) ); - /* no IKA anymore, I think we can remove this. (theeth) - if( strncmp( name, "Eff", 3 ) == 0 ) { - if( ( object->type == OB_IKA ) && ( object->data != NULL ) ) { - ika = object->data; - switch ( name[3] ) { - case 'X': - return ( PyFloat_FromDouble( ika->effg[0] ) ); - case 'Y': - return ( PyFloat_FromDouble( ika->effg[1] ) ); - case 'Z': - return ( PyFloat_FromDouble( ika->effg[2] ) ); - default: - // Do we need to display a sensible error message here? - return ( NULL ); - } - } - return ( NULL ); - } - */ + /* accept both Layer (old, for compatibility) and Layers */ if( strncmp( name, "Layer", 5 ) == 0) return ( PyInt_FromLong( object->lay ) ); @@ -2612,7 +2586,6 @@ static int Object_setAttr( BPy_Object * obj, char *name, PyObject * value ) { PyObject *valtuple, *result=NULL; struct Object *object; - struct Ika *ika; object = obj->object; @@ -2682,6 +2655,7 @@ static int Object_setAttr( BPy_Object * obj, char *name, PyObject * value ) return ( !PyArg_ParseTuple ( value, "fff", &( object->dsize[0] ), &( object->dsize[1] ), &( object->dsize[2] ) ) ); + if( StringEqual( name, "DupSta" ) ) return ( !PyArg_Parse( value, "h", &( object->dupsta ) ) ); diff --git a/source/blender/python/api2_2x/Object.h b/source/blender/python/api2_2x/Object.h index c1b3025a386..0c629f325ce 100644 --- a/source/blender/python/api2_2x/Object.h +++ b/source/blender/python/api2_2x/Object.h @@ -52,7 +52,6 @@ #include <DNA_armature_types.h> #include <DNA_action_types.h> #include <DNA_ID.h> -#include <DNA_ika_types.h> #include <DNA_listBase.h> #include <DNA_scene_types.h> #include <DNA_userdef_types.h> diff --git a/source/blender/python/api2_2x/Scene.c b/source/blender/python/api2_2x/Scene.c index 4b65aa72321..b9ae673ffb1 100644 --- a/source/blender/python/api2_2x/Scene.c +++ b/source/blender/python/api2_2x/Scene.c @@ -31,19 +31,26 @@ * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ -#include <BKE_main.h> +#include <MEM_guardedalloc.h> /* for MEM_callocN */ + +#include <DNA_screen_types.h> /* SPACE_VIEW3D, SPACE_SEQ */ +#include <DNA_scriptlink_types.h> + +#include <BKE_depsgraph.h> #include <BKE_global.h> -#include <BKE_scene.h> #include <BKE_library.h> +#include <BKE_main.h> +#include <BKE_scene.h> + #include <BLI_blenlib.h> + #include <BSE_drawview.h> /* for play_anim */ #include <BSE_headerbuttons.h> /* for copy_scene */ + #include <BIF_drawscene.h> /* for set_scene */ #include <BIF_space.h> /* for copy_view3d_lock() */ #include <BIF_screen.h> /* curarea */ -#include <DNA_screen_types.h> /* SPACE_VIEW3D, SPACE_SEQ */ -#include <DNA_scriptlink_types.h> -#include <MEM_guardedalloc.h> /* for MEM_callocN */ + #include <mydevice.h> /* for #define REDRAW */ #include "Object.h" @@ -141,7 +148,7 @@ static PyMethodDef BPy_Scene_methods[] = { {"update", ( PyCFunction ) Scene_update, METH_VARARGS, "(full = 0) - Update scene self.\n" "full = 0: sort the base list of objects." - "full = 1: full update -- also regroups, does ipos, ikas, keys"}, + "full = 1: full update -- also regroups, does ipos, keys"}, {"link", ( PyCFunction ) Scene_link, METH_VARARGS, "(obj) - Link Object obj to this scene"}, {"unlink", ( PyCFunction ) Scene_unlink, METH_VARARGS, @@ -702,12 +709,12 @@ static PyObject *Scene_update( BPy_Scene * self, PyObject * args ) return EXPP_ReturnPyObjError( PyExc_TypeError, "expected nothing or int (0 or 1) argument" ); -/* Under certain circunstances, sort_baselist *here* can crash Blender. +/* Under certain circunstances, DAG_scene_sort *here* can crash Blender. * A "RuntimeError: max recursion limit" happens when a scriptlink * on frame change has scene.update(1). * Investigate better how to avoid this. */ if( !full ) - sort_baselist( scene ); + DAG_scene_sort( scene ); else if( full == 1 ) set_scene_bg( scene ); @@ -716,7 +723,7 @@ static PyObject *Scene_update( BPy_Scene * self, PyObject * args ) return EXPP_ReturnPyObjError( PyExc_ValueError, "in method scene.update(full), full should be:\n" "0: to only sort scene elements (old behavior); or\n" - "1: for a full update (regroups, does ipos, ikas, keys, etc.)" ); + "1: for a full update (regroups, does ipos, keys, etc.)" ); Py_INCREF( Py_None ); return Py_None; diff --git a/source/blender/python/api2_2x/doc/Object.py b/source/blender/python/api2_2x/doc/Object.py index 1247aa576e8..797382af0de 100644 --- a/source/blender/python/api2_2x/doc/Object.py +++ b/source/blender/python/api2_2x/doc/Object.py @@ -137,9 +137,6 @@ class Object: @ivar dSizeY: The delta Y size of the object. @ivar dSizeZ: The delta Z size of the object. @ivar dsize: The delta (X,Y,Z) size of the object. - @ivar EffX: The X effector coordinate of the object. Only applies to IKA. - @ivar EffY: The Y effector coordinate of the object. Only applies to IKA. - @ivar EffZ: The Z effector coordinate of the object. Only applies to IKA. @type Layers: integer (bitmask) @ivar Layers: The object layers (also check the newer attribute L{layers<Object.Object.layers>}). This value is a bitmask with at diff --git a/source/blender/python/api2_2x/doc/Scene.py b/source/blender/python/api2_2x/doc/Scene.py index 8314c2beaa7..d871cc714ba 100644 --- a/source/blender/python/api2_2x/doc/Scene.py +++ b/source/blender/python/api2_2x/doc/Scene.py @@ -158,7 +158,7 @@ class Scene: @type full: int @param full: A bool to control the level of updating: - 0: sort the base list of objects. - - 1: sort and also regroup, do ipos, ikas, keys, script links, etc. + - 1: sort and also regroup, do ipos, keys, script links, etc. @warn: When in doubt, try with I{full = 0} first, since it is faster. The "full" update is a recent addition to this method. """ diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c index 0306c97c67e..e59b66b950c 100644 --- a/source/blender/render/intern/source/initrender.c +++ b/source/blender/render/intern/source/initrender.c @@ -66,7 +66,6 @@ #include "BKE_image.h" #include "BKE_ipo.h" #include "BKE_key.h" -#include "BKE_ika.h" #include "BKE_action.h" #include "BKE_writeavi.h" #include "BKE_scene.h" @@ -1492,10 +1491,9 @@ void RE_animrender(struct View3D *ogl_render_view3d) /* restore time */ if(R.r.mode & (R_FIELDS|R_MBLUR)) { - do_all_ipos(); - do_all_keys(); - do_all_actions(NULL); - do_all_ikas(); +// do_all_ipos(); +// do_all_keys(); +// do_all_actions(NULL); } if (0) { diff --git a/source/blender/renderconverter/intern/convertBlenderScene.c b/source/blender/renderconverter/intern/convertBlenderScene.c index f9dc2263829..f9fde65d281 100644 --- a/source/blender/renderconverter/intern/convertBlenderScene.c +++ b/source/blender/renderconverter/intern/convertBlenderScene.c @@ -58,7 +58,6 @@ #include "DNA_material_types.h" #include "DNA_curve_types.h" #include "DNA_effect_types.h" -#include "DNA_ika_types.h" #include "DNA_lamp_types.h" #include "DNA_lattice_types.h" #include "DNA_mesh_types.h" @@ -82,7 +81,6 @@ #include "BKE_global.h" #include "BKE_key.h" #include "BKE_ipo.h" -#include "BKE_ika.h" #include "BKE_lattice.h" #include "BKE_material.h" #include "BKE_main.h" @@ -1876,7 +1874,7 @@ static void init_render_surf(Object *ob) } } - if(ob->parent && (ob->parent->type==OB_IKA || ob->parent->type==OB_LATTICE)) need_orco= 1; + if(ob->parent && (ob->parent->type==OB_LATTICE)) need_orco= 1; if(cu->orco==0 && need_orco) make_orco_surf(cu); orco= cu->orco; @@ -1944,21 +1942,6 @@ static void init_render_surf(Object *ob) } } - if(ob->parent && ob->parent->type==OB_IKA) { - Ika *ika= ob->parent->data; - - init_skel_deform(ob->parent, ob); - dl= displist.first; - while(dl) { - - fp= dl->verts; - len= dl->nr*dl->parts; - for(a=0; a<len; a++, fp+=3) calc_skel_deform(ika, fp); - - dl= dl->next; - } - } - dl= displist.first; /* walk along displaylist and create rendervertices/-faces */ while(dl) { @@ -2216,7 +2199,6 @@ static void init_render_surf(Object *ob) static void init_render_curve(Object *ob) { extern Material defmaterial; // initrender.c - Ika *ika=0; Lattice *lt=0; Curve *cu; VertRen *ver; @@ -2314,12 +2296,6 @@ static void init_render_curve(Object *ob) need_orco= 1; } - if(ob->parent && ob->parent->type==OB_IKA) { - ika= ob->parent->data; - init_skel_deform(ob->parent, ob); - need_orco= 1; - } - if(ob->parent && ob->parent->type==OB_ARMATURE) { init_armature_deform(ob->parent, ob); need_orco= 1; @@ -2390,7 +2366,6 @@ static void init_render_curve(Object *ob) ver= RE_findOrAddVert(R.totvert++); if(lt) calc_latt_deform(fp); - else if(ika) calc_skel_deform(ika, fp); VECCOPY(ver->co, fp); MTC_Mat4MulVecfl(mat, ver->co); @@ -2937,62 +2912,12 @@ void RE_rotateBlenderScene(void) R.totvlak=R.totvert=R.totlamp=R.tothalo= 0; - do_all_ipos(); - if (G.f & G_DOSCRIPTLINKS) BPY_do_all_scripts(SCRIPT_FRAMECHANGED); - do_all_keys(); -#ifdef __NLA - do_all_actions(NULL); - rebuild_all_armature_displists(); - /* so nice, better do it twice */ - do_all_actions(NULL); - rebuild_all_armature_displists(); -#endif - do_all_ikas(); - test_all_displists(); - - /* not really neat forcing of calc_ipo and where_is */ - ob= G.main->object.first; - while(ob) { - ob->ctime= -123.456; - ob= ob->id.next; - } - - /* because of optimal calculation tracking/lattices/etc: and extra where_is_ob here */ - - base= G.scene->base.first; - while(base) { - ob= base->object; - - clear_object_constraint_status(ob); - - if (ob->type==OB_ARMATURE) - where_is_armature (ob); - else - where_is_object(ob); - - if(ob->disp.first==NULL) { - /* check for need for displist (it's zero when parent, key, or hook changed) */ - /* this part was added to mimic drawing code better, will be solved with dep graph! (ton) */ - /* added note; this is also needed for curves, for example, deformed with hooks */ - if(ob->parent && ob->partype==PARSKEL) makeDispList(ob); - else if(ob->parent && ob->parent->type==OB_LATTICE) makeDispList(ob); - else if(ob->hooks.first) makeDispList(ob); - else if(ob->softflag & OB_SB_ENABLE) makeDispList(ob); - - if(ob->type==OB_MESH) { - Mesh *me= ob->data; - if(me->disp.first==NULL && (me->flag&ME_SUBSURF)) makeDispList(ob); - else if(ob->effect.first) { // as last check - Effect *eff= ob->effect.first; - if(eff->type==EFF_WAVE) makeDispList(ob); - } - } - } - - - if(base->next==0 && G.scene->set && base==G.scene->base.last) base= G.scene->set->base.first; - else base= base->next; - } + /* in localview, lamps are using normal layers, objects only local bits */ + if(G.scene->lay & 0xFF000000) lay= G.scene->lay & 0xFF000000; + else lay= G.scene->lay; + + /* applies changes fully */ + scene_update_for_newframe(G.scene, lay); MTC_Mat4CpyMat4(R.viewinv, G.scene->camera->obmat); MTC_Mat4Ortho(R.viewinv); @@ -3032,10 +2957,6 @@ void RE_rotateBlenderScene(void) ob= ob->id.next; } - /* in localview, lamps are using normal layers, objects only local bits */ - if(G.scene->lay & 0xFF000000) lay= G.scene->lay & 0xFF000000; - else lay= G.scene->lay; - sce= G.scene; base= G.scene->base.first; @@ -3060,7 +2981,7 @@ void RE_rotateBlenderScene(void) } } else { - where_is_object(ob); + where_is_object(ob); // too many? we got depgraph now... (ton) if( (base->lay & lay) || (ob->type==OB_LAMP && (base->lay & G.scene->lay)) ) { @@ -3094,7 +3015,7 @@ void RE_rotateBlenderScene(void) Curve *cu; cu= obd->data; - if(cu->disp.first==0) { + if(cu->disp.first==NULL) { obd->flag &= ~OB_FROMDUPLI; makeDispList(obd); obd->flag |= OB_FROMDUPLI; diff --git a/source/blender/src/SConscript b/source/blender/src/SConscript index 806b7ef067e..bd235adb980 100644 --- a/source/blender/src/SConscript +++ b/source/blender/src/SConscript @@ -47,7 +47,6 @@ source_files = ['B.blend.c', 'editface.c', 'editfont.c', 'editgroup.c', - 'editika.c', 'editimasel.c', 'editipo.c', 'editkey.c', diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 67568b256a7..e07b0d2118b 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -57,7 +57,6 @@ #include "DNA_curve_types.h" #include "DNA_effect_types.h" #include "DNA_group_types.h" -#include "DNA_ika_types.h" #include "DNA_image_types.h" #include "DNA_key_types.h" #include "DNA_lamp_types.h" @@ -77,10 +76,12 @@ #include "DNA_world_types.h" #include "DNA_packedFile_types.h" +#include "BKE_depsgraph.h" #include "BKE_global.h" -#include "BKE_main.h" #include "BKE_library.h" +#include "BKE_main.h" #include "BKE_packedFile.h" +#include "BKE_scene.h" #include "BLI_blenlib.h" #include "BLI_arithb.h" @@ -120,7 +121,6 @@ #include "BKE_DerivedMesh.h" #include "BKE_effect.h" #include "BKE_font.h" -#include "BKE_ika.h" #include "BKE_image.h" #include "BKE_ipo.h" #include "BKE_lattice.h" @@ -168,7 +168,6 @@ extern ListBase editNurb; /* *************************** static functions prototypes ****************** */ -void validate_editbonebutton(EditBone *); VFont *exist_vfont(char *str); /* *************************** MESH DECIMATE ******************************** */ @@ -383,10 +382,7 @@ static void decimate_apply(void) free_editMesh(G.editMesh); G.obedit= NULL; tex_space_mesh(me); - - if (mesh_uses_displist(me)) { - makeDispList(ob); - } + BIF_undo_push("Apply decimation"); } else error("Not a decimated Mesh"); @@ -481,13 +477,11 @@ void do_common_editbuts(unsigned short event) // old name, is a mix of object an } else if (G.obedit->type == OB_FONT) { if (mat_to_sel()) { - text_to_curve(G.obedit, 0); - text_makedisplist(G.obedit); allqueue(REDRAWVIEW3D, 0); } } allqueue(REDRAWVIEW3D_Z, 0); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); BIF_undo_push("Assign material index"); } break; @@ -635,7 +629,11 @@ void do_common_editbuts(unsigned short event) // old name, is a mix of object an else BIF_undo_push("Set Solid"); break; - + case B_CHANGEDEP: + DAG_scene_sort(G.scene); // makes new dag + ob= OBACT; + if(ob) ob->recalc |= OB_RECALC; + break; default: if(event>=B_OBLAY && event<=B_OBLAY+31) { local= BASACT->lay & 0xFF000000; @@ -867,8 +865,7 @@ static void load_buts_vfont(char *name) break; } - text_to_curve(OBACT, 0); - makeDispList(OBACT); + DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA); BIF_undo_push("Load vector font"); allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWBUTSEDIT, 0); @@ -887,15 +884,13 @@ void do_fontbuts(unsigned short event) switch(event) { case B_MAKEFONT: - text_to_curve(ob, 0); - makeDispList(ob); + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); break; case B_STYLETOSEL: if (style_to_sel()) { - text_to_curve(ob, 0); - text_makedisplist(ob); + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); } allqueue(REDRAWBUTSEDIT, 0); @@ -963,8 +958,7 @@ void do_fontbuts(unsigned short event) if ((G.fileflags & G_AUTOPACK) == 0) { if (unpackVFont(cu->vfont, PF_ASK) == RET_OK) { - text_to_curve(ob, 0); - makeDispList(ob); + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); } } @@ -997,6 +991,7 @@ void do_fontbuts(unsigned short event) vf= give_vfontpointer(G.buts->texnr); if(vf) { id_us_plus((ID *)vf); + switch(cu->curinfo.flag & CU_STYLE) { case CU_BOLD: cu->vfontb->id.us--; @@ -1015,8 +1010,8 @@ void do_fontbuts(unsigned short event) cu->vfont= vf; break; } - text_to_curve(ob, 0); - makeDispList(ob); + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + BIF_undo_push("Set vector font"); allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWBUTSEDIT, 0); @@ -1031,8 +1026,8 @@ void do_fontbuts(unsigned short event) cu->textoncurve= 0; allqueue(REDRAWBUTSEDIT, 0); } - text_to_curve(ob, 0); - makeDispList(ob); + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + allqueue(REDRAWVIEW3D, 0); } } } @@ -1130,7 +1125,6 @@ void do_curvebuts(unsigned short event) { extern Nurb *lastnu; extern ListBase editNurb; /* from editcurve */ - Base *base; Object *ob; Curve *cu; Nurb *nu; @@ -1147,7 +1141,7 @@ void do_curvebuts(unsigned short event) case B_CONVERTNURB: if(G.obedit) { setsplinetype(event-B_CONVERTPOLY); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); } break; @@ -1176,14 +1170,14 @@ void do_curvebuts(unsigned short event) } nu= nu->next; } - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); } break; case B_SETWEIGHT: if(G.obedit) { weightflagNurb(1, editbutweight, 0); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); } break; @@ -1218,34 +1212,22 @@ void do_curvebuts(unsigned short event) } makeknots(nu, 2, nu->flagv>>1); } - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); } break; case B_SUBSURFTYPE: /* Icky, find better system */ - if(ob->type==OB_MESH && G.obedit && ob->data==G.obedit->data) { - if(G.editMesh->derived) { - G.editMesh->derived->release(G.editMesh->derived); - G.editMesh->derived= NULL; - } - } + //if(ob->type==OB_MESH && G.obedit && ob->data==G.obedit->data) { + // if(G.editMesh->derived) { + // G.editMesh->derived->release(G.editMesh->derived); + // G.editMesh->derived= NULL; + // } + //} /* fallthrough */ case B_MAKEDISP: if(G.vd) { - if(ob->type==OB_FONT) text_to_curve(ob, 0); - makeDispList(ob); - if(ob!=G.obedit) { // subsurf with linked dupli will crash - /* we need signal to send to other users of same data to recalc... */ - base= FIRSTBASE; - while(base) { - if(base->lay & G.vd->lay) { - if(base->object->data==ob->data && base->object!=ob) - makeDispList(base->object); - } - base= base->next; - } - } + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWINFO, 1); /* 1, because header->win==0! */ } @@ -1255,13 +1237,11 @@ void do_curvebuts(unsigned short event) subdivideNurb(); break; case B_SPINNURB: - /* bad bad bad!!! use brackets!!! In case you wondered: - {==,!=} goes before & goes before || */ if( (G.obedit==NULL) || (G.obedit->type!=OB_SURF) || (G.vd==NULL) || ((G.obedit->lay & G.vd->lay) == 0) ) return; spinNurb(0, 0); countall(); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); break; case B_CU3D: /* allow 3D curve */ @@ -1285,7 +1265,7 @@ void do_curvebuts(unsigned short event) nu= nu->next; } } - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); break; case B_SETRESOLU: @@ -1299,9 +1279,8 @@ void do_curvebuts(unsigned short event) nu= nu->next; } } - else if(ob->type==OB_FONT) text_to_curve(ob, 0); - makeDispList(ob); + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); break; @@ -1440,8 +1419,8 @@ static void editing_panel_curve_type(Object *ob, Curve *cu) uiDefButF(block, NUM, B_MAKEDISP, "Ext1:", 760,70,150,19, &cu->ext1, 0.0, 5.0, 10, 0, "Extrude depth"); uiDefButF(block, NUM, B_MAKEDISP, "Ext2:", 760,50,150,19, &cu->ext2, 0.0, 2.0, 1, 0, "Extrude beveling depth"); uiDefButS(block, NUM, B_MAKEDISP, "BevResol:", 760,30,150,19, &cu->bevresol, 0.0, 10.0, 0, 0, "Amount of bevels"); - uiDefIDPoinBut(block, test_obcurpoin_but, B_MAKEDISP, "BevOb:", 760,10,150,19, &cu->bevobj, "Curve object name that defines the bevel shape"); - uiDefIDPoinBut(block, test_obcurpoin_but, B_MAKEDISP, "TaperOb:", 760,-10,150,19, &cu->taperobj, "Curve object name that defines the taper (width)"); + uiDefIDPoinBut(block, test_obcurpoin_but, B_CHANGEDEP, "BevOb:", 760,10,150,19, &cu->bevobj, "Curve object name that defines the bevel shape"); + uiDefIDPoinBut(block, test_obcurpoin_but, B_CHANGEDEP, "TaperOb:", 760,-10,150,19, &cu->taperobj, "Curve object name that defines the taper (width)"); uiBlockBeginAlign(block); uiBlockSetCol(block, TH_BUT_SETTING1); @@ -1540,7 +1519,7 @@ void do_mballbuts(unsigned short event) { switch(event) { case B_RECALCMBALL: - makeDispList(OBACT); + DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); break; } @@ -1637,7 +1616,7 @@ void do_latticebuts(unsigned short event) lt= ob->data; if(lt->flag & LT_OUTSIDE) outside_lattice(lt); - make_displists_by_parent(ob); + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); @@ -1774,148 +1753,28 @@ static void build_bonestring (char *string, EditBone *bone) MEM_freeN(qsort_ptr); } -static void constraint_ebone_name_fix(ListBase *conlist, EditBone *eBone) +/* assumes armature editmode */ +/* exported to drawview.c via BIF_butspace.h */ +void validate_editbonebutton_cb(void *bonev, void *namev) { - - bConstraint *curcon; - char *subtarget; - - for (curcon = conlist->first; curcon; curcon=curcon->next){ - subtarget = get_con_subtarget_name(curcon, G.obedit); - if (subtarget) - if (!strcmp(subtarget,eBone->oldname) ) - strcpy(subtarget, eBone->name); - } -} - -// called in outliner too... -void validate_editbonebutton(EditBone *eBone) -{ - EditBone *prev; - bAction *act=NULL; - bActionChannel *chan; - Base *base; - bPose *pose; - bPoseChannel *pchan; - - /* Separate the bone from the G.edbo */ - prev=eBone->prev; - BLI_remlink (&G.edbo, eBone); - - /* Validate the name */ - unique_editbone_name (eBone->name); - - /* Re-insert the bone */ - if (prev) - BLI_insertlink(&G.edbo, prev, eBone); - else - BLI_addhead (&G.edbo, eBone); - - /* Rename *action* channel if necessary */ - if (G.obedit) - act = G.obedit->action; - - if (act && !act->id.lib){ - /* Find the appropriate channel - */ - for (chan = act->chanbase.first; chan; chan=chan->next){ - if (!strcmp (chan->name, eBone->oldname)){ - strcpy (chan->name, eBone->name); - } - } - allqueue(REDRAWACTION, 0); - } - - /* Rename the *pose* channel, if it exists (thus making sure - * that the constraints are still valid) - */ - pose = G.obedit->pose; - if (pose) { - pchan = get_pose_channel(pose, eBone->oldname); - if (pchan) { - strcpy (pchan->name, eBone->name); - } - } - - /* Update the parenting info of any users */ - /* Yes, I know this is the worst thing you have ever seen. */ - - for (base = G.scene->base.first; base; base=base->next){ - Object *ob = base->object; - ListBase *conlist; - - /* See if an object is parented to this armature */ - if (ob->parent && ob->partype==PARBONE && - (ob->parent->type==OB_ARMATURE) && - (ob->parent->data == G.obedit->data)){ - if (!strcmp(ob->parsubstr, eBone->oldname)) - strcpy(ob->parsubstr, eBone->name); - } - - /* Update any constraints to use the new bone name */ - conlist = &ob->constraints; - constraint_ebone_name_fix(conlist, eBone); - - switch (ob->type){ - case OB_ARMATURE: - if (ob->pose){ - for (pchan = ob->pose->chanbase.first; pchan; - pchan=pchan->next){ - conlist = &pchan->constraints; - constraint_ebone_name_fix(conlist, eBone); - } - } - break; - default: - break; - } - - } - - exit_editmode(0); /* To ensure new names make it to the edit armature */ - -} - -static void validate_editbonebutton_cb(void *bonev, void *arg2_unused) -{ - EditBone *curBone= bonev; - validate_editbonebutton(curBone); -} - -/* called from outliner now, can be used for buttons in posemode too */ -/* current Armature should be active Object */ -/* after this function, the Bones in Armature are re-allocced! */ -void rename_bone_ext(char *oldname, char *newname) -{ - EditBone *ebone; - int temp_editmode= 0; - - /* since the naming functions work only on editArmature, we have to... */ - if(G.obedit!=OBACT) exit_editmode(2); - if(G.obedit==NULL) { - G.obedit= OBACT; - make_editArmature(); - temp_editmode= 1; - } + EditBone *eBone= bonev; + char oldname[32], newname[32]; - /* now find the eBone with oldname */ - for(ebone= G.edbo.first; ebone; ebone= ebone->next) - if(strcmp(ebone->name, oldname)==0) break; - - if(ebone) { - strcpy(ebone->oldname, oldname); - strcpy(ebone->name, newname); - validate_editbonebutton(ebone); // does exit_editmode... tsk, so armature bones pointers are invalid now - } - if(temp_editmode) exit_editmode(2); + /* need to be on the stack */ + BLI_strncpy(newname, eBone->name, 32); + BLI_strncpy(oldname, (char *)namev, 32); + /* restore */ + BLI_strncpy(eBone->name, oldname, 32); + armature_bone_rename(G.obedit->data, oldname, newname); // editarmature.c + allqueue(REDRAWALL, 0); } - -static void armature_rest_pos_func(void *notused1, void *notused2) +static void armature_rest_pos_func(void *pointer1, void *pointer2) { - clear_object_constraint_status(OBACT); - make_displists_by_armature(OBACT); + Object *ob= pointer1; + + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); } static void editing_panel_armature_type(Object *ob, bArmature *arm) @@ -1930,7 +1789,7 @@ static void editing_panel_armature_type(Object *ob, bArmature *arm) but = uiDefButI(block, TOG|BIT|ARM_RESTPOSBIT,REDRAWVIEW3D, "Rest Pos", bx,by,97,20, &arm->flag, 0, 0, 0, 0, "Disable all animation for this object"); - uiButSetFunc(but, armature_rest_pos_func, NULL, NULL); + uiButSetFunc(but, armature_rest_pos_func, ob, arm); uiBlockBeginAlign(block); uiDefButI(block, TOG|BIT|ARM_DRAWAXESBIT,REDRAWVIEW3D, "Draw Axes", bx,by-46,97,20, &arm->flag, 0, 0, 0, 0, "Draw bone axes"); @@ -1969,7 +1828,6 @@ static void editing_panel_armature_bones(Object *ob, bArmature *arm) uiDefButI(block, TOG|BIT|BONE_HIDDENBIT, REDRAWVIEW3D, "Hide", bx-55,by,45,18, &curBone->flag, 0, 0, 0, 0, "Toggles display of this bone in posemode"); /* Bone naming button */ - strcpy (curBone->oldname, curBone->name); but=uiDefBut(block, TEX, REDRAWVIEW3D, "BO:", bx-10,by,117,18, &curBone->name, 0, 24, 0, 0, "Change the bone name"); uiButSetFunc(but, validate_editbonebutton_cb, curBone, NULL); @@ -1980,6 +1838,7 @@ static void editing_panel_armature_bones(Object *ob, bArmature *arm) curBone->parNr = editbone_to_parnr(curBone->parent); but = uiDefButI(block, MENU,REDRAWVIEW3D, boneString, bx+180,by,120,18, &curBone->parNr, 0.0, 0.0, 0.0, 0.0, "Parent"); + /* last arg NULL means button will put old string there */ uiButSetFunc(but, parnr_to_editbone_cb, curBone, NULL); MEM_freeN(boneString); @@ -2098,7 +1957,7 @@ void do_meshbuts(unsigned short event) if(me->medge) MEM_freeN(me->medge); me->medge= NULL; me->totedge= 0; - makeDispList(ob); + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); allqueue(REDRAWBUTSEDIT, 0); allqueue(REDRAWVIEW3D, 0); break; diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index b5fe441ae0e..f494edc7b06 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -45,6 +45,7 @@ #include "DNA_space_types.h" #include "DNA_scene_types.h" +#include "BKE_action.h" #include "BKE_global.h" #include "BKE_main.h" #include "BKE_library.h" @@ -87,7 +88,6 @@ #include "DNA_curve_types.h" #include "DNA_effect_types.h" #include "DNA_group_types.h" -#include "DNA_ika_types.h" #include "DNA_image_types.h" #include "DNA_key_types.h" #include "DNA_lamp_types.h" @@ -110,10 +110,10 @@ #include "BKE_armature.h" #include "BKE_constraint.h" #include "BKE_curve.h" +#include "BKE_depsgraph.h" #include "BKE_displist.h" #include "BKE_effect.h" #include "BKE_font.h" -#include "BKE_ika.h" #include "BKE_image.h" #include "BKE_ipo.h" #include "BKE_lattice.h" @@ -408,7 +408,7 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s uiBlockSetEmboss(block, UI_EMBOSSN); - but = uiDefIconBut(block, BUT, B_CONSTRAINT_REDRAW, ICON_X, *xco+262, *yco, 19, 19, list, 0.0, 0.0, 0.0, 0.0, "Delete constraint"); + but = uiDefIconBut(block, BUT, B_CONSTRAINT_DEL, ICON_X, *xco+262, *yco, 19, 19, list, 0.0, 0.0, 0.0, 0.0, "Delete constraint"); uiButSetFunc(but, del_constraint_func, con, list); uiBlockSetEmboss(block, UI_EMBOSSX); @@ -797,29 +797,22 @@ static uiBlock *add_constraintmenu(void *arg_unused) void do_constraintbuts(unsigned short event) { + Object *ob= OBACT; + + object_test_constraints(ob); + switch(event) { case B_CONSTRAINT_CHANGENAME: - break; case B_CONSTRAINT_TEST: - test_scene_constraints(); - allqueue (REDRAWVIEW3D, 0); - allqueue (REDRAWBUTSOBJECT, 0); - break; case B_CONSTRAINT_REDRAW: - test_scene_constraints(); - allqueue (REDRAWVIEW3D, 0); - allqueue (REDRAWBUTSOBJECT, 0); - break; - case B_CONSTRAINT_CHANGETARGET: - test_scene_constraints(); - allqueue (REDRAWVIEW3D, 0); - allqueue (REDRAWBUTSOBJECT, 0); - break; case B_CONSTRAINT_CHANGETYPE: - test_scene_constraints(); - allqueue (REDRAWVIEW3D, 0); - allqueue (REDRAWBUTSOBJECT, 0); + break; // no handling + + case B_CONSTRAINT_DEL: + case B_CONSTRAINT_CHANGETARGET: + DAG_scene_sort(G.scene); break; + case B_CONSTRAINT_ADD_NULL: { bConstraint *con; @@ -827,10 +820,7 @@ void do_constraintbuts(unsigned short event) con = add_new_constraint(CONSTRAINT_TYPE_NULL); add_constraint_to_client(con); - test_scene_constraints(); BIF_undo_push("Add constraint"); - allqueue (REDRAWVIEW3D, 0); - allqueue (REDRAWBUTSOBJECT, 0); } break; case B_CONSTRAINT_ADD_KINEMATIC: @@ -840,10 +830,7 @@ void do_constraintbuts(unsigned short event) con = add_new_constraint(CONSTRAINT_TYPE_KINEMATIC); add_constraint_to_client(con); - test_scene_constraints(); BIF_undo_push("Add constraint"); - allqueue (REDRAWVIEW3D, 0); - allqueue (REDRAWBUTSOBJECT, 0); } break; case B_CONSTRAINT_ADD_TRACKTO: @@ -853,10 +840,7 @@ void do_constraintbuts(unsigned short event) con = add_new_constraint(CONSTRAINT_TYPE_TRACKTO); add_constraint_to_client(con); - test_scene_constraints(); BIF_undo_push("Add constraint"); - allqueue (REDRAWVIEW3D, 0); - allqueue (REDRAWBUTSOBJECT, 0); } break; case B_CONSTRAINT_ADD_ROTLIKE: @@ -866,10 +850,7 @@ void do_constraintbuts(unsigned short event) con = add_new_constraint(CONSTRAINT_TYPE_ROTLIKE); add_constraint_to_client(con); - test_scene_constraints(); BIF_undo_push("Add constraint"); - allqueue (REDRAWVIEW3D, 0); - allqueue (REDRAWBUTSOBJECT, 0); } break; case B_CONSTRAINT_ADD_LOCLIKE: @@ -879,10 +860,7 @@ void do_constraintbuts(unsigned short event) con = add_new_constraint(CONSTRAINT_TYPE_LOCLIKE); add_constraint_to_client(con); - test_scene_constraints(); BIF_undo_push("Add constraint"); - allqueue (REDRAWVIEW3D, 0); - allqueue (REDRAWBUTSOBJECT, 0); } break; case B_CONSTRAINT_ADD_ACTION: @@ -892,10 +870,7 @@ void do_constraintbuts(unsigned short event) con = add_new_constraint(CONSTRAINT_TYPE_ACTION); add_constraint_to_client(con); - test_scene_constraints(); BIF_undo_push("Add constraint"); - allqueue (REDRAWVIEW3D, 0); - allqueue (REDRAWBUTSOBJECT, 0); } break; case B_CONSTRAINT_ADD_LOCKTRACK: @@ -905,10 +880,7 @@ void do_constraintbuts(unsigned short event) con = add_new_constraint(CONSTRAINT_TYPE_LOCKTRACK); add_constraint_to_client(con); - test_scene_constraints(); BIF_undo_push("Add constraint"); - allqueue (REDRAWVIEW3D, 0); - allqueue (REDRAWBUTSOBJECT, 0); } break; case B_CONSTRAINT_ADD_FOLLOWPATH: @@ -918,9 +890,6 @@ void do_constraintbuts(unsigned short event) con = add_new_constraint(CONSTRAINT_TYPE_FOLLOWPATH); add_constraint_to_client(con); - test_scene_constraints(); - allqueue (REDRAWVIEW3D, 0); - allqueue (REDRAWBUTSOBJECT, 0); } break; case B_CONSTRAINT_ADD_STRETCHTO: @@ -929,24 +898,21 @@ void do_constraintbuts(unsigned short event) con = add_new_constraint(CONSTRAINT_TYPE_STRETCHTO); add_constraint_to_client(con); - test_scene_constraints(); BIF_undo_push("Add constraint"); - allqueue(REDRAWVIEW3D,0); - allqueue(REDRAWBUTSOBJECT,0); } break; - case B_CONSTRAINT_DEL: - test_scene_constraints(); - allqueue (REDRAWVIEW3D, 0); - allqueue (REDRAWBUTSOBJECT, 0); - break; default: break; } - clear_object_constraint_status(OBACT); - make_displists_by_armature (OBACT); + if(ob->pose) update_pose_constraint_flags(ob->pose); + + if(ob->type==OB_ARMATURE) DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + else DAG_object_flush_update(G.scene, ob, OB_RECALC_OB); + + allqueue (REDRAWVIEW3D, 0); + allqueue (REDRAWBUTSOBJECT, 0); } static void object_panel_constraint(void) @@ -1164,7 +1130,7 @@ void do_object_panels(unsigned short event) switch(event) { case B_TRACKBUTS: ob= OBACT; - if(ob && ob->parent && ob->parent->type==OB_CURVE) freedisplist(&ob->disp); + DAG_object_flush_update(G.scene, ob, OB_RECALC_OB); allqueue(REDRAWVIEW3D, 0); break; case B_DEL_HOOK: @@ -1203,7 +1169,7 @@ void do_object_panels(unsigned short event) } break; case B_RECALCPATH: - calc_curvepath(OBACT); + DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); break; case B_PRINTSPEED: @@ -1237,7 +1203,7 @@ void do_object_panels(unsigned short event) allqueue(REDRAWIPO, 0); break; case B_CURVECHECK: - curve_changes_other_objects(OBACT); + DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); break; diff --git a/source/blender/src/buttons_script.c b/source/blender/src/buttons_script.c index 54cbe328a4e..78041a2e5a3 100644 --- a/source/blender/src/buttons_script.c +++ b/source/blender/src/buttons_script.c @@ -48,7 +48,6 @@ #include "DNA_effect_types.h" #include "DNA_group_types.h" #include "DNA_ID.h" -#include "DNA_ika_types.h" #include "DNA_image_types.h" #include "DNA_key_types.h" #include "DNA_lamp_types.h" @@ -75,7 +74,6 @@ #include "BKE_displist.h" #include "BKE_effect.h" #include "BKE_font.h" -#include "BKE_ika.h" #include "BKE_image.h" #include "BKE_ipo.h" #include "BKE_lattice.h" diff --git a/source/blender/src/drawdeps.c b/source/blender/src/drawdeps.c index 82da5ac7fb7..5942173bda4 100644 --- a/source/blender/src/drawdeps.c +++ b/source/blender/src/drawdeps.c @@ -112,20 +112,16 @@ static unsigned int get_line_color(DagAdjList *child) return 0x00000; case DAG_RL_DATA : return 0xFF0000; - case DAG_RL_PARENT : + case DAG_RL_OB_OB : return 0x00FF00; - case DAG_RL_TRACK : + case DAG_RL_OB_DATA : return 0xFFFF00; - case DAG_RL_PATH : + case DAG_RL_DATA_OB : return 0x000000; - case DAG_RL_CONSTRAINT : - return 0x0000FF; - case DAG_RL_HOOK : - return 0x00FFFF; - case DAG_RL_DATA_CONSTRAINT : + case DAG_RL_DATA_DATA : return 0x0000FF; default : - return 0x0000FF; + return 0xFF00FF; } //return 0x00000; } @@ -225,7 +221,6 @@ int build_deps(short mask) Object *ob = NULL; DagNode * node = NULL; DagNode * node2 = NULL ; - DagNode * node3 = NULL; DagNode * scenenode; DagForest *dag; @@ -270,117 +265,22 @@ DagNode * scenenode; while(base) { // add all objects in any case int addtoroot = 1; -// graph_print_adj_list(); -ob= (Object *) base->object; + // graph_print_adj_list(); + ob= (Object *) base->object; node = dag_get_node(dag,ob); - if ((ob->data) && (mask&DAG_RL_DATA_MASK)) { + if ((ob->data) && (mask&DAG_RL_DATA)) { node2 = dag_get_node(dag,ob->data); dag_add_relation(dag,node,node2,DAG_RL_DATA); node2->first_ancestor = ob; node2->ancestor_count += 1; - if ((ob->type == OB_ARMATURE) && (mask&DAG_RL_DATA_CONSTRAINT_MASK)) { // add armature constraints to datas - if (ob->pose){ - bPoseChannel *pchan; - bConstraint *con; - Object * target; - - for (pchan = ob->pose->chanbase.first; pchan; pchan=pchan->next){ - for (con = pchan->constraints.first; con; con=con->next){ - if (constraint_has_target(con)) { - target = get_constraint_target(con); - if (strcmp(target->id.name, ob->id.name) != 0) { - //fprintf(stderr,"armature target :%s \n", target->id.name); - node3 = dag_get_node(dag,target); - dag_add_relation(dag,node3,node2,DAG_RL_CONSTRAINT); - } - } - } - } - } - } - - if (ob->hooks.first) { - ObHook *hook; - - for(hook= ob->hooks.first; hook; hook= hook->next) { - if(hook->parent) { - node3 = dag_get_node(dag,hook->parent); - dag_add_relation(dag,node3,node2,DAG_RL_HOOK); - } - } - } - } else { // add armature constraints to object itself - if ((ob->type == OB_ARMATURE) && (mask&DAG_RL_DATA_CONSTRAINT_MASK)) { - if (ob->pose){ - bPoseChannel *pchan; - bConstraint *con; - Object * target; - - for (pchan = ob->pose->chanbase.first; pchan; pchan=pchan->next){ - for (con = pchan->constraints.first; con; con=con->next){ - if (constraint_has_target(con)) { - target = get_constraint_target(con); - if (strcmp(target->id.name, ob->id.name) != 0) { - //fprintf(stderr,"armature target :%s \n", target->id.name); - node3 = dag_get_node(dag,target); - dag_add_relation(dag,node3,node,DAG_RL_CONSTRAINT); - } - } - } - } - } - } - if (ob->hooks.first) { - ObHook *hook; - - for(hook= ob->hooks.first; hook; hook= hook->next) { - if(hook->parent) { - node3 = dag_get_node(dag,hook->parent); - dag_add_relation(dag,node3,node,DAG_RL_HOOK); - } - } - } - } - - if ((ob->parent) && (mask&DAG_RL_PARENT_MASK)){ - node2 = dag_get_node(dag,ob->parent); - dag_add_relation(dag,node2,node,DAG_RL_PARENT); - addtoroot = 0; - } - if ((ob->track) && (mask&DAG_RL_TRACK_MASK)){ - node2 = dag_get_node(dag,ob->track); - dag_add_relation(dag,node2,node,DAG_RL_TRACK); - addtoroot = 0; - - } - if ((ob->path) && (mask&DAG_RL_PATH_MASK)){ - node2 = dag_get_node(dag,ob->track); - dag_add_relation(dag,node2,node,DAG_RL_PATH); - addtoroot = 0; - - } - - /* Count constraints */ - if (mask & DAG_RL_CONSTRAINT_MASK) { - bConstraint *con; - for (con = ob->constraints.first; con; con=con->next){ - if (constraint_has_target(con)) { - node2 = dag_get_node(dag,get_constraint_target(con)); - dag_add_relation(dag,node2,node,DAG_RL_CONSTRAINT); - addtoroot = 0; - - } - } - } - + } if (addtoroot == 1 ) dag_add_relation(dag,scenenode,node,DAG_RL_SCENE); - - addtoroot = 1; + base= base->next; } diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c index d0d1707c162..65550172aec 100644 --- a/source/blender/src/drawobject.c +++ b/source/blender/src/drawobject.c @@ -91,7 +91,6 @@ #include "BIF_screen.h" #include "BIF_space.h" #include "BIF_editarmature.h" -#include "BIF_editika.h" #include "BIF_editmesh.h" #include "BIF_glutil.h" #include "BIF_resources.h" @@ -3409,7 +3408,6 @@ void draw_object(Base *base) static int warning_recursive= 0; int sel, drawtype, colindex= 0, ipoflag; short dt, dtx, zbufoff= 0; - Material *ma; float vec1[3], vec2[3]; int i, selstart, selend; SelBox *sb; @@ -3418,7 +3416,7 @@ void draw_object(Base *base) ob= base->object; /* draw keys? */ - if(base==(G.scene->basact) || (base->flag & (SELECT+BA_WASSEL))) { + if(base==(G.scene->basact) || (base->flag & (SELECT+BA_WAS_SEL))) { if(warning_recursive==0 && ob!=G.obedit) { if(ob->ipo && ob->ipo->showkey && (ob->ipoflag & OB_DRAWKEY)) { float temp[7][3]; @@ -3497,24 +3495,24 @@ void draw_object(Base *base) if((G.f & G_PICKSEL) == 0) { project_short(ob->obmat[3], &base->sx); - if((G.moving & G_TRANSFORM_OBJ) && (base->flag & (SELECT+BA_PARSEL))) BIF_ThemeColor(TH_TRANSFORM); + if((G.moving & G_TRANSFORM_OBJ) && (base->flag & (SELECT+BA_WAS_SEL))) BIF_ThemeColor(TH_TRANSFORM); else { BIF_ThemeColor(TH_WIRE); if((G.scene->basact)==base) { - if(base->flag & (SELECT+BA_WASSEL)) BIF_ThemeColor(TH_ACTIVE); + if(base->flag & (SELECT+BA_WAS_SEL)) BIF_ThemeColor(TH_ACTIVE); } else { - if(base->flag & (SELECT+BA_WASSEL)) BIF_ThemeColor(TH_SELECT); + if(base->flag & (SELECT+BA_WAS_SEL)) BIF_ThemeColor(TH_SELECT); } // no theme yet if(ob->id.lib) { - if(base->flag & (SELECT+BA_WASSEL)) colindex = 4; + if(base->flag & (SELECT+BA_WAS_SEL)) colindex = 4; else colindex = 3; } else if(warning_recursive==1) { - if(base->flag & (SELECT+BA_WASSEL)) colindex = 7; + if(base->flag & (SELECT+BA_WAS_SEL)) colindex = 7; else colindex = 6; } @@ -3581,7 +3579,7 @@ void draw_object(Base *base) draw_mesh_object(ob, dt); dtx &= ~OB_DRAWWIRE; // mesh draws wire itself - { + if(G.obedit!=ob && warning_recursive==0) { PartEff *paf = give_parteff(ob); if(paf) { diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c index fa32f2debde..fcbe2028300 100644 --- a/source/blender/src/drawview.c +++ b/source/blender/src/drawview.c @@ -80,8 +80,8 @@ #include "BKE_constraint.h" #include "BKE_curve.h" #include "BKE_displist.h" +#include "BKE_depsgraph.h" #include "BKE_global.h" -#include "BKE_ika.h" #include "BKE_lattice.h" #include "BKE_library.h" #include "BKE_image.h" @@ -1326,49 +1326,86 @@ static void v3d_editvertex_buts(uiBlock *block, Object *ob, float lim) } } +/* assumes armature active */ +static void validate_bonebutton_cb(void *bonev, void *namev) +{ + Object *ob= OBACT; + + if(ob && ob->type==OB_ARMATURE) { + Bone *bone= bonev; + char oldname[32], newname[32]; + + /* need to be on the stack */ + BLI_strncpy(newname, bone->name, 32); + BLI_strncpy(oldname, (char *)namev, 32); + /* restore */ + BLI_strncpy(bone->name, oldname, 32); + + armature_bone_rename(ob->data, oldname, newname); // editarmature.c + allqueue(REDRAWALL, 0); + } +} + + static void v3d_posearmature_buts(uiBlock *block, Object *ob, float lim) { + uiBut *but; bArmature *arm; + bPoseChannel *pchan; Bone *bone; arm = get_armature(OBACT); - if (!arm) - return; + if (!arm || !ob->pose) return; - bone = get_first_selected_bone(); - - if (!bone) - return; - uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_ARMATUREPANEL2, "QuatX:", 10, 120, 140, 19, bone->quat+1, -100.0, 100.0, 10, 3, ""); - uiDefButF(block, NUM, B_ARMATUREPANEL2, "QuatZ:", 10, 100, 140, 19, bone->quat+3, -100.0, 100.0, 10, 3, ""); + for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { + bone = pchan->bone; + if(bone && (bone->flag & BONE_ACTIVE)) break; + } + if (!pchan) return; + + but= uiDefBut(block, TEX, B_DIFF, "Bone:", 160, 140, 140, 19, bone->name, 1, 31, 0, 0, ""); + uiButSetFunc(but, validate_bonebutton_cb, bone, NULL); + + QuatToEul(pchan->quat, ob_eul); + ob_eul[0]*= 180.0/M_PI; + ob_eul[1]*= 180.0/M_PI; + ob_eul[2]*= 180.0/M_PI; + uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_ARMATUREPANEL2, "QuatY:", 160, 120, 140, 19, bone->quat+2, -100.0, 100.0, 10, 3, ""); - uiDefButF(block, NUM, B_ARMATUREPANEL2, "QuatW:", 160, 100, 140, 19, bone->quat, -100.0, 100.0, 10, 3, ""); + uiDefButF(block, NUM, B_ARMATUREPANEL2, "LocX:", 10, 140, 140, 19, pchan->loc, -lim, lim, 100, 3, ""); + uiDefButF(block, NUM, B_ARMATUREPANEL2, "LocY:", 10, 120, 140, 19, pchan->loc+1, -lim, lim, 100, 3, ""); + uiDefButF(block, NUM, B_ARMATUREPANEL2, "locZ:", 10, 100, 140, 19, pchan->loc+2, -lim, lim, 100, 3, ""); + uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_ARMATUREPANEL2, "LocX:", 10, 70, 140, 19, bone->loc, -lim, lim, 100, 3, ""); - uiDefButF(block, NUM, B_ARMATUREPANEL2, "LocY:", 10, 50, 140, 19, bone->loc+1, -lim, lim, 100, 3, ""); - uiDefButF(block, NUM, B_ARMATUREPANEL2, "locZ:", 10, 30, 140, 19, bone->loc+2, -lim, lim, 100, 3, ""); + uiDefButF(block, NUM, B_ARMATUREPANEL3, "RotX:", 10, 70, 140, 19, ob_eul, -1000.0, 1000.0, 100, 3, ""); + uiDefButF(block, NUM, B_ARMATUREPANEL3, "RotY:", 10, 50, 140, 19, ob_eul+1, -1000.0, 1000.0, 100, 3, ""); + uiDefButF(block, NUM, B_ARMATUREPANEL3, "RotZ:", 10, 30, 140, 19, ob_eul+2, -1000.0, 1000.0, 100, 3, ""); + uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_ARMATUREPANEL2, "SizeX:", 160, 70, 140, 19, bone->size, -lim, lim, 10, 3, ""); - uiDefButF(block, NUM, B_ARMATUREPANEL2, "SizeY:", 160, 50, 140, 19, bone->size+1, -lim, lim, 10, 3, ""); - uiDefButF(block, NUM, B_ARMATUREPANEL2, "SizeZ:", 160, 30, 140, 19, bone->size+2, -lim, lim, 10, 3, ""); + uiDefButF(block, NUM, B_ARMATUREPANEL2, "SizeX:", 160, 70, 140, 19, pchan->size, -lim, lim, 10, 3, ""); + uiDefButF(block, NUM, B_ARMATUREPANEL2, "SizeY:", 160, 50, 140, 19, pchan->size+1, -lim, lim, 10, 3, ""); + uiDefButF(block, NUM, B_ARMATUREPANEL2, "SizeZ:", 160, 30, 140, 19, pchan->size+2, -lim, lim, 10, 3, ""); uiBlockEndAlign(block); } static void v3d_editarmature_buts(uiBlock *block, Object *ob, float lim) { EditBone *ebone; + uiBut *but; ebone= G.edbo.first; for (ebone = G.edbo.first; ebone; ebone=ebone->next){ - if (ebone->flag & BONE_SELECTED) + if (ebone->flag & BONE_ACTIVE) break; } if (!ebone) return; + + but= uiDefBut(block, TEX, B_DIFF, "Bone:", 160, 140, 140, 19, ebone->name, 1, 31, 0, 0, ""); + uiButSetFunc(but, validate_editbonebutton_cb, ebone, NULL); + uiBlockBeginAlign(block); uiDefButF(block, NUM, B_ARMATUREPANEL1, "RootX:", 10, 70, 140, 19, ebone->head, -lim, lim, 100, 3, ""); uiDefButF(block, NUM, B_ARMATUREPANEL1, "RootY:", 10, 50, 140, 19, ebone->head+1, -lim, lim, 100, 3, ""); @@ -1467,12 +1504,18 @@ void do_viewbuts(unsigned short event) if (vd->bgpic) view3d_change_bgpic_tex(vd, NULL); break; + + case B_OBJECTPANEL: + DAG_object_flush_update(G.scene, ob, OB_RECALC_OB); + allqueue(REDRAWVIEW3D, 1); + break; case B_OBJECTPANELROT: if(ob) { ob->rot[0]= M_PI*ob_eul[0]/180.0; ob->rot[1]= M_PI*ob_eul[1]/180.0; ob->rot[2]= M_PI*ob_eul[2]/180.0; + DAG_object_flush_update(G.scene, ob, OB_RECALC_OB); allqueue(REDRAWVIEW3D, 1); } break; @@ -1480,7 +1523,7 @@ void do_viewbuts(unsigned short event) case B_OBJECTPANELMEDIAN: if(ob) { v3d_editvertex_buts(NULL, ob, 1.0); - makeDispList(ob); + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 1); } break; @@ -1488,7 +1531,11 @@ void do_viewbuts(unsigned short event) if(ob) { if( test_parent_loop(ob->parent, ob) ) ob->parent= NULL; - allqueue(REDRAWVIEW3D, 1); + else { + DAG_scene_sort(G.scene); + DAG_object_flush_update(G.scene, ob, OB_RECALC_OB); + allqueue(REDRAWVIEW3D, 1); + } } break; @@ -1498,7 +1545,7 @@ void do_viewbuts(unsigned short event) ebone= G.edbo.first; for (ebone = G.edbo.first; ebone; ebone=ebone->next){ - if (ebone->flag & BONE_SELECTED) break; + if (ebone->flag & BONE_ACTIVE) break; } if (ebone) { ebone->roll= M_PI*ob_eul[0]/180.0; @@ -1517,35 +1564,33 @@ void do_viewbuts(unsigned short event) } } break; - case B_ARMATUREPANEL2: + case B_ARMATUREPANEL3: // rotate button on channel { - bPoseChannel *chan; bArmature *arm; + bPoseChannel *pchan; Bone *bone; - + arm = get_armature(OBACT); - if (!arm) return; - bone = get_first_selected_bone(); - - if (!bone) return; - - /* This is similar to code in special_trans_update */ - - if (!G.obpose->pose) G.obpose->pose= MEM_callocN(sizeof(bPose), "pose"); - chan = MEM_callocN (sizeof (bPoseChannel), "transPoseChannel"); - - chan->flag |= POSE_LOC|POSE_ROT|POSE_SIZE; - memcpy (chan->loc, bone->loc, sizeof (chan->loc)); - memcpy (chan->quat, bone->quat, sizeof (chan->quat)); - memcpy (chan->size, bone->size, sizeof (chan->size)); - strcpy (chan->name, bone->name); + if (!arm || !ob->pose) return; + + for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { + bone = pchan->bone; + if(bone && (bone->flag & BONE_ACTIVE)) break; + } + if (!pchan) return; - set_pose_channel (G.obpose->pose, chan); - - rebuild_all_armature_displists(); - + ob_eul[0]*= M_PI/180.0; + ob_eul[1]*= M_PI/180.0; + ob_eul[2]*= M_PI/180.0; + EulToQuat(ob_eul, pchan->quat); + } + /* no break, pass on */ + case B_ARMATUREPANEL2: + { + DAG_object_flush_update(G.scene, G.obpose, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 1); } + break; } } @@ -1597,9 +1642,9 @@ static void view3d_panel_object(short cntrl) // VIEW3D_HANDLER_OBJECT } else { uiBlockBeginAlign(block); - uiDefButF(block, NUM, REDRAWVIEW3D, "LocX:", 10, 140, 140, 19, &(ob->loc[0]), -lim, lim, 100, 3, ""); - uiDefButF(block, NUM, REDRAWVIEW3D, "LocY:", 10, 120, 140, 19, &(ob->loc[1]), -lim, lim, 100, 3, ""); - uiDefButF(block, NUM, REDRAWVIEW3D, "LocZ:", 10, 100, 140, 19, &(ob->loc[2]), -lim, lim, 100, 3, ""); + uiDefButF(block, NUM, B_OBJECTPANEL, "LocX:", 10, 140, 140, 19, &(ob->loc[0]), -lim, lim, 100, 3, ""); + uiDefButF(block, NUM, B_OBJECTPANEL, "LocY:", 10, 120, 140, 19, &(ob->loc[1]), -lim, lim, 100, 3, ""); + uiDefButF(block, NUM, B_OBJECTPANEL, "LocZ:", 10, 100, 140, 19, &(ob->loc[2]), -lim, lim, 100, 3, ""); ob_eul[0]= 180.0*ob->rot[0]/M_PI; ob_eul[1]= 180.0*ob->rot[1]/M_PI; @@ -1610,9 +1655,9 @@ static void view3d_panel_object(short cntrl) // VIEW3D_HANDLER_OBJECT uiDefButF(block, NUM, B_OBJECTPANELROT, "RotY:", 10, 50, 140, 19, &(ob_eul[1]), -lim, lim, 1000, 3, ""); uiDefButF(block, NUM, B_OBJECTPANELROT, "RotZ:", 10, 30, 140, 19, &(ob_eul[2]), -lim, lim, 1000, 3, ""); uiBlockBeginAlign(block); - uiDefButF(block, NUM, REDRAWVIEW3D, "SizeX:", 160, 70, 140, 19, &(ob->size[0]), -lim, lim, 10, 3, ""); - uiDefButF(block, NUM, REDRAWVIEW3D, "SizeY:", 160, 50, 140, 19, &(ob->size[1]), -lim, lim, 10, 3, ""); - uiDefButF(block, NUM, REDRAWVIEW3D, "SizeZ:", 160, 30, 140, 19, &(ob->size[2]), -lim, lim, 10, 3, ""); + uiDefButF(block, NUM, B_OBJECTPANEL, "SizeX:", 160, 70, 140, 19, &(ob->size[0]), -lim, lim, 10, 3, ""); + uiDefButF(block, NUM, B_OBJECTPANEL, "SizeY:", 160, 50, 140, 19, &(ob->size[1]), -lim, lim, 10, 3, ""); + uiDefButF(block, NUM, B_OBJECTPANEL, "SizeZ:", 160, 30, 140, 19, &(ob->size[2]), -lim, lim, 10, 3, ""); uiBlockEndAlign(block); } uiClearButLock(); @@ -1797,17 +1842,18 @@ static void view3d_blockhandlers(ScrArea *sa) void drawview3dspace(ScrArea *sa, void *spacedata) { + View3D *v3d= spacedata; Base *base; Object *ob; setwinmatrixview3d(0); /* 0= no pick rect */ setviewmatrixview3d(); - Mat4MulMat4(G.vd->persmat, G.vd->viewmat, curarea->winmat); - Mat4Invert(G.vd->persinv, G.vd->persmat); - Mat4Invert(G.vd->viewinv, G.vd->viewmat); + Mat4MulMat4(v3d->persmat, v3d->viewmat, curarea->winmat); + Mat4Invert(v3d->persinv, v3d->persmat); + Mat4Invert(v3d->viewinv, v3d->viewmat); - if(G.vd->drawtype > OB_WIRE) { + if(v3d->drawtype > OB_WIRE) { G.zbuf= TRUE; glEnable(GL_DEPTH_TEST); if(G.f & G_SIMULATION) { @@ -1829,40 +1875,32 @@ void drawview3dspace(ScrArea *sa, void *spacedata) glClear(GL_COLOR_BUFFER_BIT); } - myloadmatrix(G.vd->viewmat); + myloadmatrix(v3d->viewmat); persp(PERSP_STORE); // store correct view for persp(PERSP_VIEW) calls // needs to be done always, gridview is adjusted in drawgrid() now - G.vd->gridview= G.vd->grid; + v3d->gridview= v3d->grid; - if(G.vd->view==0 || G.vd->persp!=0) { + if(v3d->view==0 || v3d->persp!=0) { drawfloor(); - if(G.vd->persp==2) { + if(v3d->persp==2) { if(G.scene->world) { if(G.scene->world->mode & WO_STARS) { RE_make_stars(star_stuff_init_func, star_stuff_vertex_func, star_stuff_term_func); } } - if(G.vd->flag & V3D_DISPBGPIC) draw_bgpic(); + if(v3d->flag & V3D_DISPBGPIC) draw_bgpic(); } } else { drawgrid(); - if(G.vd->flag & V3D_DISPBGPIC) { + if(v3d->flag & V3D_DISPBGPIC) { draw_bgpic(); } } -#if 0 - /* Lets be a little more selective about when and where we do this, - * or else armatures/poses/displists get recalculated all of the - * time - */ - clear_all_constraints(); -#endif - /* draw set first */ if(G.scene->set) { @@ -1871,9 +1909,11 @@ void drawview3dspace(ScrArea *sa, void *spacedata) base= G.scene->set->base.first; while(base) { - if(G.vd->lay & base->lay) { - where_is_object(base->object); + + if(v3d->lay & base->lay) { + object_handle_update(base->object); + cpack(0x404040); draw_object(base); @@ -1901,20 +1941,17 @@ void drawview3dspace(ScrArea *sa, void *spacedata) G.f &= ~G_PICKSEL; } - /* first calculate positions, we do this in separate loop to make sure displists - (mball, deform, etc) are recaluclated based on correct object (parent/children) positions - */ - base= G.scene->base.first; - while(base) { - if(G.vd->lay & base->lay) where_is_object(base->object); - base= base->next; + /* update all objects, ipos, matrices, displists, etc. Flags set by depgraph or manual */ + for(base= G.scene->base.first; base; base= base->next) { + if(base->lay & v3d->lay) + object_handle_update(base->object); // bke_object.h } /* then draw not selected and the duplis, but skip editmode object */ base= G.scene->base.first; while(base) { - if(G.vd->lay & base->lay) { + if(v3d->lay & base->lay) { /* dupli drawing temporal off here */ if(FALSE && base->object->transflag & OB_DUPLI) { @@ -1953,7 +1990,7 @@ void drawview3dspace(ScrArea *sa, void *spacedata) base= G.scene->base.first; while(base) { - if(G.vd->lay & base->lay) { + if(v3d->lay & base->lay) { if (base->object==G.obedit || ( base->flag & SELECT) ) draw_object(base); } @@ -1970,7 +2007,7 @@ void drawview3dspace(ScrArea *sa, void *spacedata) base= G.scene->base.first; while(base) { - if(G.vd->lay & base->lay) { + if(v3d->lay & base->lay) { if(base->object->transflag & OB_DUPLI) { extern ListBase duplilist; Base tbase; @@ -1996,7 +2033,7 @@ void drawview3dspace(ScrArea *sa, void *spacedata) base= base->next; } - if(G.scene->radio) RAD_drawall(G.vd->drawtype>=OB_SOLID); + if(G.scene->radio) RAD_drawall(v3d->drawtype>=OB_SOLID); BIF_draw_manipulator(sa); @@ -2007,7 +2044,7 @@ void drawview3dspace(ScrArea *sa, void *spacedata) persp(PERSP_WIN); // set ortho - if(G.vd->persp>1) drawviewborder(); + if(v3d->persp>1) drawviewborder(); drawcursor(); draw_view_icon(); @@ -2018,20 +2055,20 @@ void drawview3dspace(ScrArea *sa, void *spacedata) /* it is important to end a view in a transform compatible with buttons */ - bwin_scalematrix(sa->win, G.vd->blockscale, G.vd->blockscale, G.vd->blockscale); + bwin_scalematrix(sa->win, v3d->blockscale, v3d->blockscale, v3d->blockscale); view3d_blockhandlers(sa); curarea->win_swap= WIN_BACK_OK; if(G.f & (G_VERTEXPAINT|G_FACESELECT|G_TEXTUREPAINT|G_WEIGHTPAINT)) { - G.vd->flag |= V3D_NEEDBACKBUFDRAW; + v3d->flag |= V3D_NEEDBACKBUFDRAW; addafterqueue(curarea->win, BACKBUFDRAW, 1); } // test for backbuf select - if(G.obedit && G.vd->drawtype>OB_WIRE && (G.vd->flag & V3D_ZBUF_SELECT)) { + if(G.obedit && v3d->drawtype>OB_WIRE && (v3d->flag & V3D_ZBUF_SELECT)) { extern int afterqtest(short win, unsigned short evt); //editscreen.c - G.vd->flag |= V3D_NEEDBACKBUFDRAW; + v3d->flag |= V3D_NEEDBACKBUFDRAW; if(afterqtest(curarea->win, BACKBUFDRAW)==0) { addafterqueue(curarea->win, BACKBUFDRAW, 1); } @@ -2093,21 +2130,7 @@ void drawview3d_render(struct View3D *v3d) /* abuse! to make sure it doesnt draw the helpstuff */ G.f |= G_SIMULATION; - clear_all_constraints(); - do_all_ipos(); - if (G.f & G_DOSCRIPTLINKS) BPY_do_all_scripts(SCRIPT_FRAMECHANGED); - do_all_keys(); - do_all_actions(NULL); - do_all_ikas(); - - test_all_displists(); - - /* not really nice forcing of calc_ipo and where_is */ - ob= G.main->object.first; - while(ob) { - ob->ctime= -123.456; - ob= ob->id.next; - } + update_for_newframe_muted(); /* first draw set */ if(G.scene->set) { @@ -2147,8 +2170,6 @@ void drawview3d_render(struct View3D *v3d) G.f &= ~G_PICKSEL; } - clear_all_constraints(); - /* first not selected and duplis */ base= G.scene->base.first; while(base) { @@ -2156,7 +2177,6 @@ void drawview3d_render(struct View3D *v3d) if(v3d->lay & base->lay) { if ELEM3(base->object->type, OB_LAMP, OB_CAMERA, OB_LATTICE); else { - where_is_object(base->object); if(base->object->transflag & OB_DUPLI) { extern ListBase duplilist; @@ -2256,15 +2276,10 @@ void inner_play_anim_loop(int init, int mode) set_timecursor(CFRA); //clear_all_constraints(); - //do_all_ipos(); - //BPY_do_all_scripts(SCRIPT_FRAMECHANGED); - //do_all_keys(); //do_all_actions(NULL); - //do_all_ikas(); + update_for_newframe_muted(); - //test_all_displists(); - sa= G.curscreen->areabase.first; while(sa) { if(sa==oldsa) { @@ -2302,7 +2317,6 @@ void inner_play_anim_loop(int init, int mode) * - 3: all view3d and seq areas, no replay */ int play_anim(int mode) { - Base *base; ScrArea *sa, *oldsa; int cfraont; unsigned short event=0; @@ -2364,21 +2378,6 @@ int play_anim(int mode) if(event==SPACEKEY); else CFRA= cfraont; - - clear_all_constraints(); - do_all_ipos(); - do_all_keys(); - do_all_actions(NULL); - - if(G.vd) { - /* set all objects on current frame... test_all_displists() needs it */ - base= G.scene->base.first; - while(base) { - if(G.vd->lay & base->lay) where_is_object(base->object); - base= base->next; - } - test_all_displists(); - } audiostream_stop(); @@ -2388,7 +2387,6 @@ int play_anim(int mode) sa= G.curscreen->areabase.first; while(sa) { if( (mode && sa->spacetype==SPACE_VIEW3D) || sa==curarea) addqueue(sa->win, REDRAW, 1); - sa= sa->next; } @@ -2397,7 +2395,8 @@ int play_anim(int mode) allqueue(REDRAWIPO, 0); allqueue(REDRAWNLA, 0); allqueue (REDRAWACTION, 0); - /* for the time being */ + + /* restore for cfra */ update_for_newframe_muted(); waitcursor(0); diff --git a/source/blender/src/edit.c b/source/blender/src/edit.c index def75b4c6c1..652d16e55e1 100644 --- a/source/blender/src/edit.c +++ b/source/blender/src/edit.c @@ -70,6 +70,7 @@ #include "BKE_armature.h" #include "BKE_anim.h" #include "BKE_curve.h" +#include "BKE_depsgraph.h" #include "BKE_displist.h" #include "BKE_global.h" #include "BKE_ipo.h" @@ -526,8 +527,8 @@ void count_object(Object *ob, int sel) G.totcurve++; tot=totf= 0; cu= ob->data; - if(cu->disp.first==0) makeDispList(ob); - count_displist( &cu->disp, &tot, &totf); + if(cu->disp.first) + count_displist( &cu->disp, &tot, &totf); G.totvert+= tot; G.totface+= totf; if(sel) { @@ -565,7 +566,7 @@ void countall() int a; G.totvert= G.totvertsel= G.totedge= G.totedgesel= G.totfacesel= G.totface= G.totobj= - G.totmesh= G.totlamp= G.totcurve= G.totobjsel= 0; + G.totmesh= G.totlamp= G.totcurve= G.totobjsel= G.totbone= G.totbonesel= 0; if(G.obedit) { @@ -590,6 +591,7 @@ void countall() } else if (G.obedit->type==OB_ARMATURE){ for (ebo=G.edbo.first;ebo;ebo=ebo->next){ + G.totbone++; /* Sync selection to parent for ik children */ if ((ebo->flag & BONE_IK_TOPARENT) && ebo->parent){ @@ -610,15 +612,14 @@ void countall() else ebo->flag &= ~BONE_SELECTED; + if(ebo->flag & BONE_SELECTED) G.totbonesel++; + // If this is an IK child and it's parent is being moved, remove our root if ((ebo->flag & BONE_IK_TOPARENT)&& (ebo->flag & BONE_ROOTSEL) && ebo->parent && (ebo->parent->flag & BONE_TIPSEL)){ G.totvertsel--; } G.totvert+=2; - G.totface++; - - } } else if ELEM3(G.obedit->type, OB_CURVE, OB_SURF, OB_FONT) { @@ -672,6 +673,17 @@ void countall() allqueue(REDRAWINFO, 1); /* 1, because header->win==0! */ return; } + else if(G.obpose) { + if(G.obpose->pose) { + bPoseChannel *pchan; + for(pchan= G.obpose->pose->chanbase.first; pchan; pchan= pchan->next) { + G.totbone++; + if(pchan->bone && (pchan->bone->flag & BONE_SELECTED)) G.totbonesel++; + } + } + allqueue(REDRAWINFO, 1); /* 1, because header->win==0! */ + return; + } else if(G.f & (G_FACESELECT + G_VERTEXPAINT + G_TEXTUREPAINT +G_WEIGHTPAINT)) { me= get_mesh((G.scene->basact) ? (G.scene->basact->object) : 0); if(me) { @@ -718,90 +730,24 @@ void countall() static TransVert *transvmain=NULL; static int tottrans= 0; -/* selected things moved, and might need update in displists */ -static void update_select_dependency(void) -{ - Base *base; - Object *ob; - for(base= (G.scene->base.first); base; base= base->next) { - ob= base->object; - if(ob->hooks.first) { - ObHook *hook= ob->hooks.first; - while(hook) { - if(hook->parent && (hook->parent->flag & SELECT)) freedisplist(&ob->disp); - hook= hook->next; - } - } - } - -} - -static void calc_trans_verts(void) +/* copied from editobject.c, now uses (almost) proper depgraph */ +static void special_transvert_update(void) { - extern ListBase editNurb; - - if (ELEM(G.obedit->type, OB_MESH, OB_MBALL)) - makeDispList(G.obedit); - else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) { - Nurb *nu= editNurb.first; - while(nu) { - test2DNurb(nu); - testhandlesNurb(nu); /* test for bezier too */ - nu= nu->next; - } - makeDispList(G.obedit); - } -} - -static int pose_flags_reset_done(Object *ob) { - /* Clear the constraint done status for every pose channe; - * that has been flagged as needing constant updating - */ - bPoseChannel *chan; - int numreset = 0; - - if (ob->pose) { - for (chan = ob->pose->chanbase.first; chan; chan=chan->next){ - if (chan->flag & PCHAN_TRANS_UPDATE) { - chan->flag &= ~PCHAN_DONE; - numreset++; - } - - } - } - return numreset; -} - - -/* copied from editobject.c, should be replaced with proper depgraph */ -static void special_trans_update(void) -{ - Base *base; - Curve *cu; - IpoCurve *icu; if(G.obedit) { + + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); + if(G.obedit->type==OB_MESH) { recalc_editnormals(); // does face centers too } - if(G.obedit->type==OB_CURVE) { - cu= G.obedit->data; - - makeBevelList(G.obedit); // might be needed for deform - calc_curvepath(G.obedit); - - base= FIRSTBASE; - while(base) { - if(base->lay & G.vd->lay) { - if(base->object->parent==G.obedit && base->object->partype==PARSKEL) - makeDispList(base->object); - else if(base->object->type==OB_CURVE) { - Curve *cu= base->object->data; - if(G.obedit==cu->bevobj || G.obedit==cu->taperobj) - makeDispList(base->object); - } - } - base= base->next; + else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) { + extern ListBase editNurb; + Nurb *nu= editNurb.first; + while(nu) { + test2DNurb(nu); + testhandlesNurb(nu); /* test for bezier too */ + nu= nu->next; } } else if(G.obedit->type==OB_ARMATURE){ @@ -823,75 +769,9 @@ static void special_trans_update(void) } } else if(G.obedit->type==OB_LATTICE) { - if(editLatt->flag & LT_OUTSIDE) outside_lattice(editLatt); - - base= FIRSTBASE; - while(base) { - if(base->lay & G.vd->lay) { - if(base->object->parent==G.obedit) { - makeDispList(base->object); - } - } - base= base->next; - } } } - else { - base= FIRSTBASE; - while(base) { - if(base->flag & BA_DO_IPO) { - - base->object->ctime= -1234567.0; - - icu= base->object->ipo->curve.first; - while(icu) { - calchandles_ipocurve(icu); - icu= icu->next; - } - - } - if(base->object->partype & PARSLOW) { - base->object->partype -= PARSLOW; - where_is_object(base->object); - base->object->partype |= PARSLOW; - } - else if(base->flag & BA_WHERE_UPDATE) { - where_is_object(base->object); - } - - base= base->next; - } - - base= FIRSTBASE; - while(base) { - - if(base->flag & BA_DISP_UPDATE) makeDispList(base->object); - - base= base->next; - } - - } - - base= FIRSTBASE; - while(base) { - if (pose_flags_reset_done(base->object)) { - if (!is_delay_deform()) - make_displists_by_armature(base->object); - } - - base= base->next; - } - -#if 1 - if (G.obpose && G.obpose->type == OB_ARMATURE) - clear_pose_constraint_status(G.obpose); - - if (!is_delay_deform()) make_displists_by_armature(G.obpose); -#endif - - if(G.vd->drawtype == OB_SHADED) reshadeall_displist(); - } /* copied from editobject.c, needs to be replaced with new transform code still */ @@ -1133,8 +1013,6 @@ static void make_trans_verts(float *min, float *max, int mode) } - - void snap_sel_to_grid() { extern float originmat[3][3]; /* object.c */ @@ -1147,80 +1025,76 @@ void snap_sel_to_grid() gridf= G.vd->gridview; - if(G.obedit) { - tottrans= 0; - -#ifdef __NLA - if ELEM6(G.obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL) make_trans_verts(bmat[0], bmat[1], 0); -#else - if ELEM5(G.obedit->type, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL) make_trans_verts(bmat[0], bmat[1], 0); -#endif - if(tottrans==0) return; + if(G.obedit) { + tottrans= 0; + + if ELEM6(G.obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL) + make_trans_verts(bmat[0], bmat[1], 0); + if(tottrans==0) return; - Mat3CpyMat4(bmat, G.obedit->obmat); - Mat3Inv(imat, bmat); + Mat3CpyMat4(bmat, G.obedit->obmat); + Mat3Inv(imat, bmat); - tv= transvmain; - for(a=0; a<tottrans; a++, tv++) { + tv= transvmain; + for(a=0; a<tottrans; a++, tv++) { - VECCOPY(vec, tv->loc); - Mat3MulVecfl(bmat, vec); - VecAddf(vec, vec, G.obedit->obmat[3]); - vec[0]= G.vd->gridview*floor(.5+ vec[0]/gridf); - vec[1]= G.vd->gridview*floor(.5+ vec[1]/gridf); - vec[2]= G.vd->gridview*floor(.5+ vec[2]/gridf); - VecSubf(vec, vec, G.obedit->obmat[3]); + VECCOPY(vec, tv->loc); + Mat3MulVecfl(bmat, vec); + VecAddf(vec, vec, G.obedit->obmat[3]); + vec[0]= G.vd->gridview*floor(.5+ vec[0]/gridf); + vec[1]= G.vd->gridview*floor(.5+ vec[1]/gridf); + vec[2]= G.vd->gridview*floor(.5+ vec[2]/gridf); + VecSubf(vec, vec, G.obedit->obmat[3]); - Mat3MulVecfl(imat, vec); - VECCOPY(tv->loc, vec); + Mat3MulVecfl(imat, vec); + VECCOPY(tv->loc, vec); - } + } - MEM_freeN(transvmain); - transvmain= 0; - - calc_trans_verts(); // does test2d, makedisplist too */ + MEM_freeN(transvmain); + transvmain= 0; + + special_transvert_update(); - special_trans_update(); + allqueue(REDRAWVIEW3D, 0); + return; + } - allqueue(REDRAWVIEW3D, 0); - return; - } -#ifdef __NLA - if (G.obpose){ - allqueue(REDRAWVIEW3D, 0); - return; - } -#endif - base= (G.scene->base.first); - while(base) { - if( ( ((base)->flag & SELECT) && ((base)->lay & G.vd->lay) && ((base)->object->id.lib==0))) { - ob= base->object; + if (G.obpose){ + allqueue(REDRAWVIEW3D, 0); + return; + } - vec[0]= -ob->obmat[3][0]+G.vd->gridview*floor(.5+ ob->obmat[3][0]/gridf); - vec[1]= -ob->obmat[3][1]+G.vd->gridview*floor(.5+ ob->obmat[3][1]/gridf); - vec[2]= -ob->obmat[3][2]+G.vd->gridview*floor(.5+ ob->obmat[3][2]/gridf); + base= (G.scene->base.first); + while(base) { + if( ( ((base)->flag & SELECT) && ((base)->lay & G.vd->lay) && ((base)->object->id.lib==0))) { + ob= base->object; + ob->recalc |= OB_RECALC_OB; + + vec[0]= -ob->obmat[3][0]+G.vd->gridview*floor(.5+ ob->obmat[3][0]/gridf); + vec[1]= -ob->obmat[3][1]+G.vd->gridview*floor(.5+ ob->obmat[3][1]/gridf); + vec[2]= -ob->obmat[3][2]+G.vd->gridview*floor(.5+ ob->obmat[3][2]/gridf); - if(ob->parent) { - where_is_object(ob); + if(ob->parent) { + where_is_object(ob); - Mat3Inv(imat, originmat); - Mat3MulVecfl(imat, vec); - ob->loc[0]+= vec[0]; - ob->loc[1]+= vec[1]; - ob->loc[2]+= vec[2]; - } - else { - ob->loc[0]+= vec[0]; - ob->loc[1]+= vec[1]; - ob->loc[2]+= vec[2]; - } + Mat3Inv(imat, originmat); + Mat3MulVecfl(imat, vec); + ob->loc[0]+= vec[0]; + ob->loc[1]+= vec[1]; + ob->loc[2]+= vec[2]; + } + else { + ob->loc[0]+= vec[0]; + ob->loc[1]+= vec[1]; + ob->loc[2]+= vec[2]; } - - base= base->next; } - update_select_dependency(); - allqueue(REDRAWVIEW3D, 0); + + base= base->next; + } + DAG_scene_flush_update(G.scene); + allqueue(REDRAWVIEW3D, 0); } void snap_sel_to_curs() @@ -1234,77 +1108,71 @@ void snap_sel_to_curs() curs= give_cursor(); - if(G.obedit) { - tottrans= 0; -#ifdef __NLA - if ELEM6(G.obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL) make_trans_verts(bmat[0], bmat[1], 0); -#else - if ELEM5(G.obedit->type, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL) make_trans_verts(bmat[0], bmat[1], 0); -#endif - if(tottrans==0) return; - - Mat3CpyMat4(bmat, G.obedit->obmat); - Mat3Inv(imat, bmat); + if(G.obedit) { + tottrans= 0; - tv= transvmain; - for(a=0; a<tottrans; a++, tv++) { + if ELEM6(G.obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL) + make_trans_verts(bmat[0], bmat[1], 0); + if(tottrans==0) return; + Mat3CpyMat4(bmat, G.obedit->obmat); + Mat3Inv(imat, bmat); - vec[0]= curs[0]-G.obedit->obmat[3][0]; - vec[1]= curs[1]-G.obedit->obmat[3][1]; - vec[2]= curs[2]-G.obedit->obmat[3][2]; + tv= transvmain; + for(a=0; a<tottrans; a++, tv++) { + vec[0]= curs[0]-G.obedit->obmat[3][0]; + vec[1]= curs[1]-G.obedit->obmat[3][1]; + vec[2]= curs[2]-G.obedit->obmat[3][2]; - Mat3MulVecfl(imat, vec); - VECCOPY(tv->loc, vec); - - } - MEM_freeN(transvmain); - transvmain= 0; + Mat3MulVecfl(imat, vec); + VECCOPY(tv->loc, vec); - calc_trans_verts(); // does test2d, makedisplist too */ + } + MEM_freeN(transvmain); + transvmain= 0; - special_trans_update(); + special_transvert_update(); - allqueue(REDRAWVIEW3D, 0); - return; - } -#ifdef __NLA - if (G.obpose){ - allqueue(REDRAWVIEW3D, 0); - return; - } -#endif - base= (G.scene->base.first); - while(base) { - if( ( ((base)->flag & SELECT) && ((base)->lay & G.vd->lay) && ((base)->object->id.lib==0))) { - ob= base->object; + allqueue(REDRAWVIEW3D, 0); + return; + } - vec[0]= -ob->obmat[3][0] + curs[0]; - vec[1]= -ob->obmat[3][1] + curs[1]; - vec[2]= -ob->obmat[3][2] + curs[2]; + if (G.obpose){ + allqueue(REDRAWVIEW3D, 0); + return; + } + base= (G.scene->base.first); + while(base) { + if( ( ((base)->flag & SELECT) && ((base)->lay & G.vd->lay) && ((base)->object->id.lib==0))) { + ob= base->object; + ob->recalc |= OB_RECALC_OB; + + vec[0]= -ob->obmat[3][0] + curs[0]; + vec[1]= -ob->obmat[3][1] + curs[1]; + vec[2]= -ob->obmat[3][2] + curs[2]; - if(ob->parent) { - where_is_object(ob); + if(ob->parent) { + where_is_object(ob); - Mat3Inv(imat, originmat); - Mat3MulVecfl(imat, vec); - ob->loc[0]+= vec[0]; - ob->loc[1]+= vec[1]; - ob->loc[2]+= vec[2]; - } - else { - ob->loc[0]+= vec[0]; - ob->loc[1]+= vec[1]; - ob->loc[2]+= vec[2]; - } + Mat3Inv(imat, originmat); + Mat3MulVecfl(imat, vec); + ob->loc[0]+= vec[0]; + ob->loc[1]+= vec[1]; + ob->loc[2]+= vec[2]; + } + else { + ob->loc[0]+= vec[0]; + ob->loc[1]+= vec[1]; + ob->loc[2]+= vec[2]; } - - base= base->next; } - update_select_dependency(); - allqueue(REDRAWVIEW3D, 0); + + base= base->next; + } + DAG_scene_flush_update(G.scene); + allqueue(REDRAWVIEW3D, 0); } void snap_curs_to_grid() @@ -1335,28 +1203,50 @@ void snap_curs_to_sel() INIT_MINMAX(min, max); centroid[0]= centroid[1]= centroid[2]= 0.0; - if(G.obedit) { - tottrans=0; -#ifdef __NLA - if ELEM6(G.obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL) make_trans_verts(bmat[0], bmat[1], 0); -#else - if ELEM5(G.obedit->type, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL) make_trans_verts(bmat[0], bmat[1], 0); -#endif - if(tottrans==0) return; + if(G.obedit) { + tottrans=0; + + if ELEM6(G.obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL) + make_trans_verts(bmat[0], bmat[1], 0); + if(tottrans==0) return; + + Mat3CpyMat4(bmat, G.obedit->obmat); - Mat3CpyMat4(bmat, G.obedit->obmat); + tv= transvmain; + for(a=0; a<tottrans; a++, tv++) { + VECCOPY(vec, tv->loc); + Mat3MulVecfl(bmat, vec); + VecAddf(vec, vec, G.obedit->obmat[3]); + VecAddf(centroid, centroid, vec); + DO_MINMAX(vec, min, max); + } - tv= transvmain; - for(a=0; a<tottrans; a++, tv++) { - VECCOPY(vec, tv->loc); - Mat3MulVecfl(bmat, vec); - VecAddf(vec, vec, G.obedit->obmat[3]); + if(G.vd->around==V3D_CENTROID) { + VecMulf(centroid, 1.0/(float)tottrans); + VECCOPY(curs, centroid); + } + else { + curs[0]= (min[0]+max[0])/2; + curs[1]= (min[1]+max[1])/2; + curs[2]= (min[2]+max[2])/2; + } + MEM_freeN(transvmain); + transvmain= 0; + } + else { + base= (G.scene->base.first); + while(base) { + if(((base)->flag & SELECT) && ((base)->lay & G.vd->lay) ) { + VECCOPY(vec, base->object->obmat[3]); VecAddf(centroid, centroid, vec); DO_MINMAX(vec, min, max); + count++; } - + base= base->next; + } + if(count) { if(G.vd->around==V3D_CENTROID) { - VecMulf(centroid, 1.0/(float)tottrans); + VecMulf(centroid, 1.0/(float)count); VECCOPY(curs, centroid); } else { @@ -1364,33 +1254,9 @@ void snap_curs_to_sel() curs[1]= (min[1]+max[1])/2; curs[2]= (min[2]+max[2])/2; } - MEM_freeN(transvmain); - transvmain= 0; } - else { - base= (G.scene->base.first); - while(base) { - if(((base)->flag & SELECT) && ((base)->lay & G.vd->lay) ) { - VECCOPY(vec, base->object->obmat[3]); - VecAddf(centroid, centroid, vec); - DO_MINMAX(vec, min, max); - count++; - } - base= base->next; - } - if(count) { - if(G.vd->around==V3D_CENTROID) { - VecMulf(centroid, 1.0/(float)count); - VECCOPY(curs, centroid); - } - else { - curs[0]= (min[0]+max[0])/2; - curs[1]= (min[1]+max[1])/2; - curs[2]= (min[2]+max[2])/2; - } - } - } - allqueue(REDRAWVIEW3D, 0); + } + allqueue(REDRAWVIEW3D, 0); } void snap_curs_to_firstsel() @@ -1406,60 +1272,58 @@ void snap_curs_to_firstsel() INIT_MINMAX(min, max); centroid[0]= centroid[1]= centroid[2]= 0.0; - if(G.obedit) { - tottrans=0; -#ifdef __NLA - if ELEM6(G.obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL) make_trans_verts(bmat[0], bmat[1], 0); -#else - if ELEM5(G.obedit->type, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL) make_trans_verts(bmat[0], bmat[1], 0); -#endif - if(tottrans==0) return; + if(G.obedit) { + tottrans=0; - Mat3CpyMat4(bmat, G.obedit->obmat); + if ELEM6(G.obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL) + make_trans_verts(bmat[0], bmat[1], 0); + if(tottrans==0) return; - tv= transvmain; - VECCOPY(vec, tv->loc); - /*Mat3MulVecfl(bmat, vec); - VecAddf(vec, vec, G.obedit->obmat[3]); - VecAddf(centroid, centroid, vec); - DO_MINMAX(vec, min, max);*/ + Mat3CpyMat4(bmat, G.obedit->obmat); - if(G.vd->around==V3D_CENTROID) { - VecMulf(vec, 1.0/(float)tottrans); - VECCOPY(curs, vec); - } - else { - curs[0]= vec[0]; - curs[1]= vec[1]; - curs[2]= vec[2]; - } - MEM_freeN(transvmain); - transvmain= 0; + tv= transvmain; + VECCOPY(vec, tv->loc); + /*Mat3MulVecfl(bmat, vec); + VecAddf(vec, vec, G.obedit->obmat[3]); + VecAddf(centroid, centroid, vec); + DO_MINMAX(vec, min, max);*/ + + if(G.vd->around==V3D_CENTROID) { + VecMulf(vec, 1.0/(float)tottrans); + VECCOPY(curs, vec); } else { - base= (G.scene->base.first); - while(base) { - if(((base)->flag & SELECT) && ((base)->lay & G.vd->lay) ) { - VECCOPY(vec, base->object->obmat[3]); - VecAddf(centroid, centroid, vec); - DO_MINMAX(vec, min, max); - count++; - } - base= base->next; + curs[0]= vec[0]; + curs[1]= vec[1]; + curs[2]= vec[2]; + } + MEM_freeN(transvmain); + transvmain= 0; + } + else { + base= (G.scene->base.first); + while(base) { + if(((base)->flag & SELECT) && ((base)->lay & G.vd->lay) ) { + VECCOPY(vec, base->object->obmat[3]); + VecAddf(centroid, centroid, vec); + DO_MINMAX(vec, min, max); + count++; } - if(count) { - if(G.vd->around==V3D_CENTROID) { - VecMulf(centroid, 1.0/(float)count); - VECCOPY(curs, centroid); - } - else { - curs[0]= (min[0]+max[0])/2; - curs[1]= (min[1]+max[1])/2; - curs[2]= (min[2]+max[2])/2; - } + base= base->next; + } + if(count) { + if(G.vd->around==V3D_CENTROID) { + VecMulf(centroid, 1.0/(float)count); + VECCOPY(curs, centroid); + } + else { + curs[0]= (min[0]+max[0])/2; + curs[1]= (min[1]+max[1])/2; + curs[2]= (min[2]+max[2])/2; } } - allqueue(REDRAWVIEW3D, 0); + } + allqueue(REDRAWVIEW3D, 0); } void snap_to_center() @@ -1471,35 +1335,58 @@ void snap_to_center() float snaploc[3], imat[3][3], bmat[3][3], vec[3], min[3], max[3], centroid[3]; int count, a; - -/*calculate the snaplocation (centerpoint) */ + /*calculate the snaplocation (centerpoint) */ count= 0; INIT_MINMAX(min, max); centroid[0]= centroid[1]= centroid[2]= 0.0; - if(G.obedit) { - tottrans= 0; -#ifdef __NLA - if ELEM6(G.obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL) make_trans_verts(bmat[0], bmat[1], 0); -#else - if ELEM5(G.obedit->type, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL) make_trans_verts(bmat[0], bmat[1], 0); -#endif - if(tottrans==0) return; + if(G.obedit) { + tottrans= 0; + + if ELEM6(G.obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL) + make_trans_verts(bmat[0], bmat[1], 0); + if(tottrans==0) return; - Mat3CpyMat4(bmat, G.obedit->obmat); - Mat3Inv(imat, bmat); + Mat3CpyMat4(bmat, G.obedit->obmat); + Mat3Inv(imat, bmat); + + tv= transvmain; + for(a=0; a<tottrans; a++, tv++) { + VECCOPY(vec, tv->loc); + Mat3MulVecfl(bmat, vec); + VecAddf(vec, vec, G.obedit->obmat[3]); + VecAddf(centroid, centroid, vec); + DO_MINMAX(vec, min, max); + } + + if(G.vd->around==V3D_CENTROID) { + VecMulf(centroid, 1.0/(float)tottrans); + VECCOPY(snaploc, centroid); + } + else { + snaploc[0]= (min[0]+max[0])/2; + snaploc[1]= (min[1]+max[1])/2; + snaploc[2]= (min[2]+max[2])/2; + } + + MEM_freeN(transvmain); + transvmain= 0; - tv= transvmain; - for(a=0; a<tottrans; a++, tv++) { - VECCOPY(vec, tv->loc); - Mat3MulVecfl(bmat, vec); - VecAddf(vec, vec, G.obedit->obmat[3]); + } + else { + base= (G.scene->base.first); + while(base) { + if(((base)->flag & SELECT) && ((base)->lay & G.vd->lay) ) { + VECCOPY(vec, base->object->obmat[3]); VecAddf(centroid, centroid, vec); DO_MINMAX(vec, min, max); + count++; } - + base= base->next; + } + if(count) { if(G.vd->around==V3D_CENTROID) { - VecMulf(centroid, 1.0/(float)tottrans); + VecMulf(centroid, 1.0/(float)count); VECCOPY(snaploc, centroid); } else { @@ -1507,109 +1394,74 @@ void snap_to_center() snaploc[1]= (min[1]+max[1])/2; snaploc[2]= (min[2]+max[2])/2; } - - MEM_freeN(transvmain); - transvmain= 0; - - } - else { - base= (G.scene->base.first); - while(base) { - if(((base)->flag & SELECT) && ((base)->lay & G.vd->lay) ) { - VECCOPY(vec, base->object->obmat[3]); - VecAddf(centroid, centroid, vec); - DO_MINMAX(vec, min, max); - count++; - } - base= base->next; - } - if(count) { - if(G.vd->around==V3D_CENTROID) { - VecMulf(centroid, 1.0/(float)count); - VECCOPY(snaploc, centroid); - } - else { - snaploc[0]= (min[0]+max[0])/2; - snaploc[1]= (min[1]+max[1])/2; - snaploc[2]= (min[2]+max[2])/2; - } - } } + } + /* Snap the selection to the snaplocation (duh!) */ + if(G.obedit) { + tottrans= 0; -/* Snap the selection to the snaplocation (duh!) */ - - if(G.obedit) { - tottrans= 0; -#ifdef __NLA - if ELEM6(G.obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL) make_trans_verts(bmat[0], bmat[1], 0); -#else - if ELEM5(G.obedit->type, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL) make_trans_verts(bmat[0], bmat[1], 0); -#endif - if(tottrans==0) return; - - Mat3CpyMat4(bmat, G.obedit->obmat); - Mat3Inv(imat, bmat); - - tv= transvmain; - for(a=0; a<tottrans; a++, tv++) { - - - vec[0]= snaploc[0]-G.obedit->obmat[3][0]; - vec[1]= snaploc[1]-G.obedit->obmat[3][1]; - vec[2]= snaploc[2]-G.obedit->obmat[3][2]; + if ELEM6(G.obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL) + make_trans_verts(bmat[0], bmat[1], 0); + if(tottrans==0) return; + Mat3CpyMat4(bmat, G.obedit->obmat); + Mat3Inv(imat, bmat); - Mat3MulVecfl(imat, vec); - VECCOPY(tv->loc, vec); + tv= transvmain; + for(a=0; a<tottrans; a++, tv++) { - } - MEM_freeN(transvmain); - transvmain= 0; + vec[0]= snaploc[0]-G.obedit->obmat[3][0]; + vec[1]= snaploc[1]-G.obedit->obmat[3][1]; + vec[2]= snaploc[2]-G.obedit->obmat[3][2]; - if ELEM4(G.obedit->type, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL) makeDispList(G.obedit); + Mat3MulVecfl(imat, vec); + VECCOPY(tv->loc, vec); + } + MEM_freeN(transvmain); + transvmain= 0; - special_trans_update(); + special_transvert_update(); - allqueue(REDRAWVIEW3D, 0); - return; - } -#ifdef __NLA - if (G.obpose){ - allqueue(REDRAWVIEW3D, 0); - return; - } -#endif - base= (G.scene->base.first); - while(base) { - if( ( ((base)->flag & SELECT) && ((base)->lay & G.vd->lay) && ((base)->object->id.lib==0))) { - ob= base->object; + allqueue(REDRAWVIEW3D, 0); + return; + } - vec[0]= -ob->obmat[3][0] + snaploc[0]; - vec[1]= -ob->obmat[3][1] + snaploc[1]; - vec[2]= -ob->obmat[3][2] + snaploc[2]; + if (G.obpose){ + allqueue(REDRAWVIEW3D, 0); + return; + } + base= (G.scene->base.first); + while(base) { + if( ( ((base)->flag & SELECT) && ((base)->lay & G.vd->lay) && ((base)->object->id.lib==0))) { + ob= base->object; + ob->recalc |= OB_RECALC_OB; + + vec[0]= -ob->obmat[3][0] + snaploc[0]; + vec[1]= -ob->obmat[3][1] + snaploc[1]; + vec[2]= -ob->obmat[3][2] + snaploc[2]; - if(ob->parent) { - where_is_object(ob); + if(ob->parent) { + where_is_object(ob); - Mat3Inv(imat, originmat); - Mat3MulVecfl(imat, vec); - ob->loc[0]+= vec[0]; - ob->loc[1]+= vec[1]; - ob->loc[2]+= vec[2]; - } - else { - ob->loc[0]+= vec[0]; - ob->loc[1]+= vec[1]; - ob->loc[2]+= vec[2]; - } + Mat3Inv(imat, originmat); + Mat3MulVecfl(imat, vec); + ob->loc[0]+= vec[0]; + ob->loc[1]+= vec[1]; + ob->loc[2]+= vec[2]; + } + else { + ob->loc[0]+= vec[0]; + ob->loc[1]+= vec[1]; + ob->loc[2]+= vec[2]; } - - base= base->next; } - update_select_dependency(); - allqueue(REDRAWVIEW3D, 0); + + base= base->next; + } + DAG_scene_flush_update(G.scene); + allqueue(REDRAWVIEW3D, 0); } @@ -1714,11 +1566,8 @@ void minmax_verts(float *min, float *max) int a; tottrans=0; -#ifdef __NLA - if ELEM5(G.obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE) make_trans_verts(bmat[0], bmat[1], 0); -#else - if ELEM4(G.obedit->type, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE) make_trans_verts(bmat[0], bmat[1], 0); -#endif + if ELEM5(G.obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE) + make_trans_verts(bmat[0], bmat[1], 0); if(tottrans==0) return; Mat3CpyMat4(bmat, G.obedit->obmat); diff --git a/source/blender/src/editaction.c b/source/blender/src/editaction.c index 3db1407b4c9..8754549dd59 100644 --- a/source/blender/src/editaction.c +++ b/source/blender/src/editaction.c @@ -61,7 +61,7 @@ #include "BKE_armature.h" #include "BKE_constraint.h" #include "BKE_curve.h" -#include "BKE_displist.h" +#include "BKE_depsgraph.h" #include "BKE_global.h" #include "BKE_ipo.h" #include "BKE_key.h" @@ -166,10 +166,11 @@ bAction* bake_action_with_client (bAction *act, Object *armob, float tolerance) return NULL; } - if (!arm){ + if (!arm || armob->pose==NULL){ error ("Select an armature before baking"); return NULL; } + /* Get a new action */ result = add_empty_action(); @@ -191,10 +192,9 @@ bAction* bake_action_with_client (bAction *act, Object *armob, float tolerance) G.scene->r.cfra = curframe; /* Apply the object ipo */ - get_pose_from_action(&armob->pose, act, curframe); - apply_pose_armature(arm, armob->pose, 1); - clear_object_constraint_status(armob); - where_is_armature_time(armob, curframe); + extract_pose_from_action(armob->pose, act, curframe); + +// where_is_armature_time(armob, curframe); /* For each channel: set quats and locs if channel is a bone */ for (pchan=armob->pose->chanbase.first; pchan; pchan=pchan->next){ @@ -206,9 +206,9 @@ bAction* bake_action_with_client (bAction *act, Object *armob, float tolerance) VECCOPY(tmp_loc, pchan->loc); VECCOPY(tmp_size, pchan->size); - Mat4ToQuat(pchan->obmat, pchan->quat); - Mat4ToSize(pchan->obmat, pchan->size); - VECCOPY(pchan->loc, pchan->obmat[3]); +// Mat4ToQuat(pchan->obmat, pchan->quat); +// Mat4ToSize(pchan->obmat, pchan->size); +// VECCOPY(pchan->loc, pchan->obmat[3]); /* Apply to keys */ set_action_key_time (result, pchan, AC_QUAT_X, 1, curframe); @@ -309,8 +309,7 @@ static void remake_meshaction_ipos(Ipo *ipo) static void meshkey_do_redraw(Key *key) { remake_meshaction_ipos(key->ipo); - do_all_ipos(); - do_spec_key(key); + do_spec_key(key); allspace(REMAKEIPO, 0); allqueue(REDRAWACTION, 0); @@ -794,8 +793,9 @@ void set_exprap_action(int mode) void free_posebuf(void) { - if (g_posebuf){ - clear_pose(g_posebuf); + if (g_posebuf) { + // was copied without constraints + BLI_freelistN (&g_posebuf->chanbase); MEM_freeN (g_posebuf); } g_posebuf=NULL; @@ -813,7 +813,7 @@ void copy_posebuf (void) return; } - filter_pose_keys(); + set_pose_keys(ob); // sets chan->flag to POSE_KEY if bone selected copy_pose(&g_posebuf, ob->pose, 0); } @@ -934,13 +934,14 @@ static void flip_name (char *name) sprintf (name, "%s%s%s", prefix, replace, suffix); } -void paste_posebuf (int flip){ +void paste_posebuf (int flip) +{ Object *ob; - bPoseChannel *temp, *chan; + bPoseChannel *chan, *pchan; float eul[4]; - Base *base; - int newchan = 0; - + int newchan = 0; + char name[32]; + ob=G.obpose; if (!ob) return; @@ -950,44 +951,54 @@ void paste_posebuf (int flip){ return; }; - collect_pose_garbage(ob); - /* Safely merge all of the channels in this pose into any existing pose */ if (ob->pose){ for (chan=g_posebuf->chanbase.first; chan; chan=chan->next){ - if (chan->flag & POSE_KEY){ - temp = copy_pose_channel (chan); - if (flip){ - flip_name (temp->name); - temp->loc[0]*=-1; - - QuatToEul(temp->quat, eul); - eul[1]*=-1; - eul[2]*=-1; - EulToQuat(eul, temp->quat); - } + if (chan->flag & POSE_KEY) { + BLI_strncpy(name, chan->name, sizeof(name)); + if (flip) + flip_name (name); + + /* only copy when channel exists, poses are not meant to add random channels to anymore */ + pchan= get_pose_channel(ob->pose, name); + + if(pchan) { + /* only loc rot size */ + /* only copies transform info for the pose */ + VECCOPY(pchan->loc, chan->loc); + VECCOPY(pchan->size, chan->size); + QUATCOPY(pchan->quat, chan->quat); + pchan->flag= chan->flag; + + if (flip){ + pchan->loc[0]*= -1; - temp = set_pose_channel (ob->pose, temp); - - if (G.flags & G_RECORDKEYS){ - /* Set keys on pose */ - if (chan->flag & POSE_ROT){ - set_action_key(ob->action, temp, AC_QUAT_X, newchan); - set_action_key(ob->action, temp, AC_QUAT_Y, newchan); - set_action_key(ob->action, temp, AC_QUAT_Z, newchan); - set_action_key(ob->action, temp, AC_QUAT_W, newchan); - }; - if (chan->flag & POSE_SIZE){ - set_action_key(ob->action, temp, AC_SIZE_X, newchan); - set_action_key(ob->action, temp, AC_SIZE_Y, newchan); - set_action_key(ob->action, temp, AC_SIZE_Z, newchan); - }; - if (chan->flag & POSE_LOC){ - set_action_key(ob->action, temp, AC_LOC_X, newchan); - set_action_key(ob->action, temp, AC_LOC_Y, newchan); - set_action_key(ob->action, temp, AC_LOC_Z, newchan); - }; + QuatToEul(pchan->quat, eul); + eul[1]*= -1; + eul[2]*= -1; + EulToQuat(eul, pchan->quat); + } + + if (G.flags & G_RECORDKEYS){ + /* Set keys on pose */ + if (chan->flag & POSE_ROT){ + set_action_key(ob->action, pchan, AC_QUAT_X, newchan); + set_action_key(ob->action, pchan, AC_QUAT_Y, newchan); + set_action_key(ob->action, pchan, AC_QUAT_Z, newchan); + set_action_key(ob->action, pchan, AC_QUAT_W, newchan); + } + if (chan->flag & POSE_SIZE){ + set_action_key(ob->action, pchan, AC_SIZE_X, newchan); + set_action_key(ob->action, pchan, AC_SIZE_Y, newchan); + set_action_key(ob->action, pchan, AC_SIZE_Z, newchan); + } + if (chan->flag & POSE_LOC){ + set_action_key(ob->action, pchan, AC_LOC_X, newchan); + set_action_key(ob->action, pchan, AC_LOC_Y, newchan); + set_action_key(ob->action, pchan, AC_LOC_Z, newchan); + } + } } } } @@ -1001,14 +1012,8 @@ void paste_posebuf (int flip){ } /* Update deformation children */ - if (G.obpose->type == OB_ARMATURE){ - for (base= FIRSTBASE; base; base= base->next){ - if (G.obpose==base->object->parent){ - if (base->object->partype==PARSKEL) - makeDispList(base->object); - } - } - } + DAG_object_flush_update(G.scene, G.obpose, OB_RECALC_DATA); + BIF_undo_push("Paste Action Pose"); } } @@ -1028,6 +1033,7 @@ static void set_action_key_time (bAction *act, bPoseChannel *chan, int adrcode, if (!chan) return; + /* See if this action channel exists already */ for (achan=act->chanbase.first; achan; achan=achan->next){ if (!strcmp (chan->name, achan->name)) diff --git a/source/blender/src/editarmature.c b/source/blender/src/editarmature.c index 74b8350b6a9..2105a9588c5 100644 --- a/source/blender/src/editarmature.c +++ b/source/blender/src/editarmature.c @@ -46,6 +46,7 @@ #include "DNA_action_types.h" #include "DNA_armature_types.h" #include "DNA_constraint_types.h" +#include "DNA_ID.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_object_types.h" @@ -58,27 +59,30 @@ #include "BLI_arithb.h" #include "BLI_editVert.h" -#include "BKE_utildefines.h" #include "BKE_action.h" #include "BKE_armature.h" #include "BKE_constraint.h" +#include "BKE_deform.h" +#include "BKE_depsgraph.h" #include "BKE_global.h" +#include "BKE_main.h" #include "BKE_object.h" #include "BKE_subsurf.h" -#include "BKE_deform.h" +#include "BKE_utildefines.h" +#include "BIF_editmode_undo.h" +#include "BIF_editdeform.h" +#include "BIF_editarmature.h" +#include "BIF_editconstraint.h" #include "BIF_gl.h" #include "BIF_graphics.h" #include "BIF_interface.h" +#include "BIF_poseobject.h" +#include "BIF_mywindow.h" #include "BIF_resources.h" #include "BIF_screen.h" #include "BIF_space.h" #include "BIF_toolbox.h" -#include "BIF_editarmature.h" -#include "BIF_editconstraint.h" -#include "BIF_poseobject.h" -#include "BIF_mywindow.h" -#include "BIF_editdeform.h" #include "BIF_transform.h" #include "BDR_editobject.h" @@ -97,60 +101,217 @@ /* >>>>> FIXME: ARG! Colours should be defined in a header somewhere! */ /* Note, these came from drawobject.c They really should be in a nice header file somewhere */ +#define B_YELLOW_A 0xBBFFFF #define B_YELLOW 0x77FFFF #define B_PURPLE 0xFF70FF +#define B_CYAN_A 0xFFFF88 #define B_CYAN 0xFFFF00 -#define B_AQUA 0xFFBB55 /* 0xFF8833*/ +#define B_AQUA 0xFFBB55 extern float centre[3], centroid[3]; /* Originally defined in editobject.c */ /* Macros */ #define TEST_EDITARMATURE {if(G.obedit==0) return; if( (G.vd->lay & G.obedit->lay)==0 ) return;} -/* Local Function Prototypes */ -static void editbones_to_armature (ListBase *bones, Object *ob); - -static void fix_bonelist_roll (ListBase *bonelist, ListBase *editbonelist); -static int select_bonechildren_by_name (struct Bone *bone, char *name, int select); - -static void draw_boneverti (float x, float y, float z, float size, int flag); -static void draw_bone (int armflag, int boneflag, unsigned int id, char *name, float length); -static void draw_bonechildren (struct Bone *bone, int flag, unsigned int *index); -static void add_bone_input (struct Object *ob); -static void make_boneList(struct ListBase* list, struct ListBase *bones, struct EditBone *parent); -static void make_bone_menu_children (struct Bone *bone, char *str, int *index); -static void delete_bone(struct EditBone* exBone); -static void clear_armature_children (struct Bone *bone, struct bPose *pose, char mode); - -static int count_bones (struct bArmature *arm, int flagmask, int allbones); -static int count_bonechildren (struct Bone *bone, int incount, int flagmask, int allbones); -static void deselect_bonechildren (Object *ob, struct Bone *bone, int mode); -static void selectconnected_posebonechildren (struct Bone *bone); +/* **************** tools on Editmode Armature **************** */ -static int editbone_name_exists (char* name); +/* converts Bones to EditBone list, used for tools as well */ +static void make_boneList(ListBase* list, ListBase *bones, EditBone *parent) +{ + EditBone *eBone; + Bone *curBone; + float delta[3]; + float premat[3][3]; + float postmat[3][3]; + float imat[3][3]; + float difmat[3][3]; + + for (curBone=bones->first; curBone; curBone=curBone->next){ + eBone= MEM_callocN(sizeof(EditBone), "make_editbone"); + + /* Copy relevant data from bone to eBone */ + eBone->parent=parent; + strcpy (eBone->name, curBone->name); + eBone->flag = curBone->flag; + + /* fix selection flags */ + if(eBone->flag & BONE_SELECTED) { + eBone->flag |= BONE_TIPSEL; + if(eBone->parent && (eBone->flag & BONE_IK_TOPARENT)) + eBone->parent->flag |= BONE_TIPSEL; + else + eBone->flag |= BONE_ROOTSEL; + } + + VECCOPY(eBone->head, curBone->arm_head); + VECCOPY(eBone->tail, curBone->arm_tail); + + eBone->roll= 0.0; + + /* roll fixing */ + VecSubf (delta, eBone->tail, eBone->head); + vec_roll_to_mat3(delta, 0.0, postmat); + + Mat3CpyMat4(premat, curBone->arm_mat); + + Mat3Inv(imat, postmat); + Mat3MulMat3(difmat, imat, premat); + + eBone->roll = atan(difmat[2][0]/difmat[2][2]); + if (difmat[0][0]<0.0) eBone->roll +=M_PI; + + /* rest of stuff copy */ + eBone->length= curBone->length; + eBone->dist= curBone->dist; + eBone->weight= curBone->weight; + eBone->boneclass = curBone->boneclass; + + BLI_addtail (list, eBone); + + /* Add children if necessary */ + if (curBone->childbase.first) + make_boneList (list, &curBone->childbase, eBone); + } +} -static void *get_nearest_bone (int findunsel); -static EditBone * get_nearest_editbonepoint (int findunsel, int *selmask); +/* nasty stuff for converting roll in editbones into bones */ +/* also sets restposition in armature (arm_mat) */ +static void fix_bonelist_roll (ListBase *bonelist, ListBase *editbonelist) +{ + Bone *curBone; + EditBone *ebone; + float premat[3][3]; + float postmat[3][3]; + float difmat[3][3]; + float imat[3][3]; + float delta[3]; + + for (curBone=bonelist->first; curBone; curBone=curBone->next) { + /* sets local matrix and arm_mat (restpos) */ + where_is_armature_bone(curBone, curBone->parent); + + /* Find the associated editbone */ + for (ebone = editbonelist->first; ebone; ebone=ebone->next) + if ((Bone*)ebone->temp == curBone) + break; + + if (ebone) { + /* Get the ebone premat */ + VecSubf (delta, ebone->tail, ebone->head); + vec_roll_to_mat3(delta, ebone->roll, premat); + + /* Get the bone postmat */ + Mat3CpyMat4(postmat, curBone->arm_mat); -static Bone *get_first_selected_bonechildren (Bone *bone); + Mat3Inv(imat, premat); + Mat3MulMat3(difmat, imat, postmat); +#if 0 + printf ("Bone %s\n", curBone->name); + printmatrix4 ("premat", premat); + printmatrix4 ("postmat", postmat); + printmatrix4 ("difmat", difmat); + printf ("Roll = %f\n", (-atan(difmat[2][0]/difmat[2][2]) * (180.0/M_PI))); +#endif + curBone->roll = -atan(difmat[2][0]/difmat[2][2]); + + if (difmat[0][0]<0.0) curBone->roll +=M_PI; + + /* and set restposition again */ + where_is_armature_bone(curBone, curBone->parent); + } + fix_bonelist_roll (&curBone->childbase, editbonelist); + } +} -static EditBone *get_named_editbone(char *name); -static void update_dup_subtarget(EditBone *dupBone); -static int bone_skinnable(Object *ob, Bone *bone, void *data); -static int add_defgroup_unique_bone(Object *ob, Bone *bone, void *data); -static int dgroup_skinnable(Object *ob, Bone *bone, void *data); -static void add_verts_to_closest_dgroup(Object *ob, Object *par); -static int hide_selected_pose_bone(Object *ob, Bone *bone, void *ptr); -static int hide_unselected_pose_bone(Object *ob, Bone *bone, void *ptr); -static int show_pose_bone(Object *ob, Bone *bone, void *ptr); +/* converts the editbones back to the armature */ +static void editbones_to_armature (ListBase *list, Object *ob) +{ + bArmature *arm; + EditBone *eBone; + Bone *newBone; + Object *obt; + + arm = get_armature(ob); + if (!list) return; + if (!arm) return; + + /* armature bones */ + free_bones(arm); + + /* Copy the bones from the editData into the armature */ + for (eBone=list->first;eBone;eBone=eBone->next){ + newBone= MEM_callocN (sizeof(Bone), "bone"); + eBone->temp= newBone; /* Associate the real Bones with the EditBones */ + + strcpy (newBone->name, eBone->name); + memcpy (newBone->head, eBone->head, sizeof(float)*3); + memcpy (newBone->tail, eBone->tail, sizeof(float)*3); + newBone->flag= eBone->flag; + newBone->roll = 0.0f; + + newBone->weight = eBone->weight; + newBone->dist = eBone->dist; + newBone->boneclass = eBone->boneclass; + + } + + /* Fix parenting in a separate pass to ensure ebone->bone connections + are valid at this point */ + for (eBone=list->first;eBone;eBone=eBone->next) { + newBone= (Bone*) eBone->temp; + if (eBone->parent){ + newBone->parent=(Bone*) eBone->parent->temp; + BLI_addtail (&newBone->parent->childbase,newBone); + + { + float M_boneRest[3][3]; + float M_parentRest[3][3]; + float iM_parentRest[3][3]; + float delta[3]; + + /* Get the parent's matrix (rotation only) */ + VecSubf (delta, eBone->parent->tail, eBone->parent->head); + vec_roll_to_mat3(delta, eBone->parent->roll, M_parentRest); + + /* Get this bone's matrix (rotation only) */ + VecSubf (delta, eBone->tail, eBone->head); + vec_roll_to_mat3(delta, eBone->roll, M_boneRest); + + /* Invert the parent matrix */ + Mat3Inv(iM_parentRest, M_parentRest); + + /* Get the new head and tail */ + VecSubf (newBone->head, eBone->head, eBone->parent->tail); + VecSubf (newBone->tail, eBone->tail, eBone->parent->tail); -/* Functions */ + Mat3MulVecfl(iM_parentRest, newBone->head); + Mat3MulVecfl(iM_parentRest, newBone->tail); + } + } + /* ...otherwise add this bone to the armature's bonebase */ + else + BLI_addtail (&arm->bonebase,newBone); + } + + /* Make a pass through the new armature to fix rolling */ + /* also builds restposition again (like where_is_armature) */ + fix_bonelist_roll (&arm->bonebase, list); + + /* so all users of this armature should get rebuilt */ + for(obt= G.main->object.first; obt; obt= obt->id.next) { + if(obt->data==arm) + armature_rebuild_pose(obt, arm); + } + + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); +} -void apply_rot_armature (Object *ob, float mat[3][3]){ +void apply_rot_armature (Object *ob, float mat[3][3]) +{ ListBase list; EditBone *ebone; bArmature *arm; @@ -166,47 +327,42 @@ void apply_rot_armature (Object *ob, float mat[3][3]){ /* Do the rotations */ for (ebone = list.first; ebone; ebone=ebone->next){ - { - /* Fixme: This is essentially duplicated from join_armature */ - + /* Yah, later... :) (ton) */ float premat[4][4]; float postmat[4][4]; float difmat[4][4]; float imat[4][4]; - float temp[4][4]; + float temp[3][3]; float delta[3]; float rmat[4][4]; Mat4CpyMat3 (rmat, mat); + /* Get the premat */ VecSubf (delta, ebone->tail, ebone->head); - make_boneMatrixvr(temp, delta, ebone->roll); - Mat4MulMat4 (premat, temp, rmat); + vec_roll_to_mat3(delta, ebone->roll, temp); + + Mat4MulMat34 (premat, temp, rmat); Mat4MulVecfl(rmat, ebone->head); Mat4MulVecfl(rmat, ebone->tail); /* Get the postmat */ VecSubf (delta, ebone->tail, ebone->head); - make_boneMatrixvr(postmat, delta, ebone->roll); + vec_roll_to_mat3(delta, ebone->roll, temp); + Mat4CpyMat3(postmat, temp); /* Find the roll */ Mat4Invert (imat, premat); Mat4MulMat4 (difmat, postmat, imat); -#if 0 - printmatrix4 ("Difmat", difmat); -#endif ebone->roll -=atan(difmat[2][0]/difmat[2][2]); - if (difmat[0][0]<0) - ebone->roll +=M_PI; + if (difmat[0][0]<0) ebone->roll +=M_PI; } - - } /* Turn the list into an armature */ @@ -216,146 +372,187 @@ void apply_rot_armature (Object *ob, float mat[3][3]){ if (list.first){ BLI_freelistN (&list); } - } - - -static Bone *get_first_selected_bonechildren (Bone *bone) -{ - Bone *curbone, *result; - - if (bone->flag & BONE_SELECTED) - return bone; - - for (curbone = bone->childbase.first; curbone; curbone=curbone->next){ - result = get_first_selected_bonechildren(curbone); - if (result) - return result; - }; - - return NULL; -} - -Bone *get_first_selected_bone (void) +void join_armature(void) { - Bone *curbone, *result; - bArmature *arm; - - arm = get_armature(OBACT); - if (!arm) - return NULL; + Object *ob; + Base *base, *nextbase; + ListBase eblist; + EditBone *curbone, *next; + float mat[4][4], imat[4][4]; + + /* Ensure we're not in editmode and that the active object is an armature*/ + if(G.obedit) return; + + ob= OBACT; + if(ob->type!=OB_ARMATURE) return; + + /* Make sure the user wants to continue*/ + if(okee("Join selected armatures")==0) return; + + /* Put the active armature into editmode and join the bones from the other one*/ +#if 1 + enter_editmode(); +#else + baselist.first=baselist.last=0; + make_boneList(&baselist, &((bArmature*)ob->data)->bonebase, NULL); +#endif + + for (base=FIRSTBASE; base; base=nextbase) { + nextbase = base->next; + if (TESTBASE(base)){ + if ((base->object->type==OB_ARMATURE) && (base->object!=ob)){ + /* Make a list of editbones */ + eblist.first=eblist.last= NULL; + make_boneList (&eblist, &((bArmature*)base->object->data)->bonebase,NULL); + /* Find the difference matrix */ + Mat4Invert(imat, ob->obmat); + Mat4MulMat4(mat, base->object->obmat, imat); + + /* Copy bones from the object to the edit armature */ + for (curbone=eblist.first; curbone; curbone=next){ + next = curbone->next; - for (curbone = arm->bonebase.first; curbone; curbone=curbone->next){ - result = get_first_selected_bonechildren(curbone); - if (result) - return result; + unique_editbone_name (curbone->name); + + /* Transform the bone */ + { + float premat[4][4]; + float postmat[4][4]; + float difmat[4][4]; + float imat[4][4]; + float temp[3][3]; + float delta[3]; + + /* Get the premat */ + VecSubf (delta, curbone->tail, curbone->head); + vec_roll_to_mat3(delta, curbone->roll, temp); + + Mat4MulMat34 (premat, temp, mat); + + Mat4MulVecfl(mat, curbone->head); + Mat4MulVecfl(mat, curbone->tail); + + /* Get the postmat */ + VecSubf (delta, curbone->tail, curbone->head); + vec_roll_to_mat3(delta, curbone->roll, temp); + Mat4CpyMat3(postmat, temp); + + /* Find the roll */ + Mat4Invert (imat, premat); + Mat4MulMat4 (difmat, postmat, imat); + + curbone->roll -=atan(difmat[2][0]/difmat[2][2]); + + if (difmat[0][0]<0) + curbone->roll +=M_PI; + + } +#if 1 + BLI_remlink(&eblist, curbone); + BLI_addtail(&G.edbo, curbone); +#else + BLI_remlink(&eblist, curbone); + BLI_addtail(&baselist, curbone); +#endif + } + + free_and_unlink_base(base); + } + } } + +#if 1 + exit_editmode(1); +#else + editbones_to_armature(&baselist, ob); + if (baselist.first){ + BLI_freelistN (&baselist); + } +#endif + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWOOPS, 0); - return NULL; } -void clever_numbuts_posearmature (void) +/* **************** END tools on Editmode Armature **************** */ +/* **************** PoseMode & EditMode *************************** */ + +/* used by posemode as well editmode */ +static void * get_nearest_bone (int findunsel) { - /* heh -- 'clever numbuts'! */ - bArmature *arm; + void *firstunSel=NULL, *data; + unsigned int buffer[MAXPICKBUF]; + short hits; + int i, takeNext=0; + int sel; + unsigned int hitresult; Bone *bone; - bPoseChannel *chan; - - arm = get_armature(OBACT); - if (!arm) - return; - - bone = get_first_selected_bone(); - - if (!bone) - return; - - add_numbut(0, NUM|FLO, "Loc X:", -G.vd->far, G.vd->far, bone->loc, 0); - add_numbut(1, NUM|FLO, "Loc Y:", -G.vd->far, G.vd->far, bone->loc+1, 0); - add_numbut(2, NUM|FLO, "Loc Z:", -G.vd->far, G.vd->far, bone->loc+2, 0); - - add_numbut(3, NUM|FLO, "Quat X:", -G.vd->far, G.vd->far, bone->quat, 0); - add_numbut(4, NUM|FLO, "Quat Y:", -G.vd->far, G.vd->far, bone->quat+1, 0); - add_numbut(5, NUM|FLO, "Quat Z:", -G.vd->far, G.vd->far, bone->quat+2, 0); - add_numbut(6, NUM|FLO, "Quat W:", -G.vd->far, G.vd->far, bone->quat+3, 0); - - add_numbut(7, NUM|FLO, "Size X:", -G.vd->far, G.vd->far, bone->size, 0); - add_numbut(8, NUM|FLO, "Size Y:", -G.vd->far, G.vd->far, bone->size+1, 0); - add_numbut(9, NUM|FLO, "Size Z:", -G.vd->far, G.vd->far, bone->size+2, 0); - - do_clever_numbuts("Active Bone", 10, REDRAW); - - /* This is similar to code in special_trans_update */ - - if (!G.obpose->pose) G.obpose->pose= MEM_callocN(sizeof(bPose), "pose"); - chan = MEM_callocN (sizeof (bPoseChannel), "transPoseChannel"); - - chan->flag |= POSE_LOC|POSE_ROT|POSE_SIZE; - memcpy (chan->loc, bone->loc, sizeof (chan->loc)); - memcpy (chan->quat, bone->quat, sizeof (chan->quat)); - memcpy (chan->size, bone->size, sizeof (chan->size)); - strcpy (chan->name, bone->name); + EditBone *ebone; - set_pose_channel (G.obpose->pose, chan); + persp(PERSP_VIEW); -} - -void clever_numbuts_armature (void) -{ - EditBone *ebone, *child; + glInitNames(); + hits= selectprojektie(buffer, 0, 0, 0, 0); - ebone= G.edbo.first; - - for (ebone = G.edbo.first; ebone; ebone=ebone->next){ - if (ebone->flag & BONE_SELECTED) - break; - } - - if (!ebone) - return; - - add_numbut(0, NUM|FLO, "Root X:", -G.vd->far, G.vd->far, ebone->head, 0); - add_numbut(1, NUM|FLO, "Root Y:", -G.vd->far, G.vd->far, ebone->head+1, 0); - add_numbut(2, NUM|FLO, "Root Z:", -G.vd->far, G.vd->far, ebone->head+2, 0); - - add_numbut(3, NUM|FLO, "Tip X:", -G.vd->far, G.vd->far, ebone->tail, 0); - add_numbut(4, NUM|FLO, "Tip Y:", -G.vd->far, G.vd->far, ebone->tail+1, 0); - add_numbut(5, NUM|FLO, "Tip Z:", -G.vd->far, G.vd->far, ebone->tail+2, 0); - - /* Convert roll to degrees */ - ebone->roll *= (180.0F/M_PI); - add_numbut(6, NUM|FLO, "Roll:", -G.vd->far, G.vd->far, &ebone->roll, 0); - - do_clever_numbuts("Active Bone", 7, REDRAW); - - /* Convert roll to radians */ - ebone->roll /= (180.0F/M_PI); - - // Update our parent - if (ebone->parent && ebone->flag & BONE_IK_TOPARENT){ - VECCOPY (ebone->parent->tail, ebone->head); - } - - // Update our children if necessary - for (child = G.edbo.first; child; child=child->next){ - if (child->parent == ebone && child->flag & BONE_IK_TOPARENT){ - VECCOPY (child->head, ebone->tail); + /* See if there are any selected bones in this group */ + if (hits){ + for (i=0; i< hits; i++){ + hitresult = buffer[3+(i*4)]; + if (!(hitresult & BONESEL_NOSEL)){ + + /* Determine which points are selected */ + hitresult &= ~(BONESEL_ANY); + + /* Determine what the current bone is */ + if (!G.obedit){ + bone = get_indexed_bone(OBACT, hitresult); + if (findunsel) + sel = (bone->flag & BONE_SELECTED); + else + sel = !(bone->flag & BONE_SELECTED); + data = bone; + } + else{ + ebone = BLI_findlink(&G.edbo, hitresult); + if (findunsel) + sel = (ebone->flag & BONE_SELECTED); + else + sel = !(ebone->flag & BONE_SELECTED); + + data = ebone; + } + + if (sel) + takeNext=1; + else{ + if (!firstunSel) + firstunSel=data; + if (takeNext) + return data; + } + } + } + + if (firstunSel) + return firstunSel; + + else{ + + if (G.obedit) + return BLI_findlink(&G.edbo, buffer[3] & ~(BONESEL_ANY)); + else + return get_indexed_bone(OBACT, buffer[3] & ~(BONESEL_ANY)); } } + + return NULL; } -void select_bone_by_name (bArmature *arm, char *name, int select) -{ - Bone *bone; - if (!arm) - return; - - for (bone=arm->bonebase.first; bone; bone=bone->next) - if (select_bonechildren_by_name (bone, name, select)) - break; -} +/* **************** END PoseMode & EditMode *************************** */ +/* **************** Posemode stuff ********************** */ static int select_bonechildren_by_name (Bone *bone, char *name, int select) { @@ -376,77 +573,51 @@ static int select_bonechildren_by_name (Bone *bone, char *name, int select) return 0; } -void selectconnected_armature(void) + +/* called in editction.c */ +void select_bone_by_name (bArmature *arm, char *name, int select) { - EditBone *bone, *curBone, *next; + Bone *bone; + + if (!arm) + return; + + for (bone=arm->bonebase.first; bone; bone=bone->next) + if (select_bonechildren_by_name (bone, name, select)) + break; +} +static void selectconnected_posebonechildren (Bone *bone) +{ + Bone *curBone; + + if (!(bone->flag & BONE_IK_TOPARENT)) + return; + + select_actionchannel_by_name (G.obpose->action, bone->name, !(G.qual & LR_SHIFTKEY)); + if (G.qual & LR_SHIFTKEY) - bone= get_nearest_bone(0); + bone->flag &= ~BONE_SELECTED; else - bone= get_nearest_bone(1); - - if (!bone) - return; - - /* Select parents */ - for (curBone=bone; curBone; curBone=next){ - if (G.qual & LR_SHIFTKEY){ - curBone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL); - } - else{ - curBone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL); - } - - if (curBone->flag & BONE_IK_TOPARENT) - next=curBone->parent; - else - next=NULL; - } - - /* Select children */ - while (bone){ - for (curBone=G.edbo.first; curBone; curBone=next){ - next = curBone->next; - if (curBone->parent == bone){ - if (curBone->flag & BONE_IK_TOPARENT){ - if (G.qual & LR_SHIFTKEY) - curBone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL); - else - curBone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL); - bone=curBone; - break; - } - else{ - bone=NULL; - break; - } - } - } - if (!curBone) - bone=NULL; - + bone->flag |= BONE_SELECTED; + + for (curBone=bone->childbase.first; curBone; curBone=curBone->next){ + selectconnected_posebonechildren (curBone); } - - countall(); - allqueue (REDRAWVIEW3D, 0); - allqueue (REDRAWBUTSEDIT, 0); - allqueue(REDRAWBUTSOBJECT, 0); - allqueue(REDRAWOOPS, 0); - } void selectconnected_posearmature(void) { Bone *bone, *curBone, *next; - + if (G.qual & LR_SHIFTKEY) bone= get_nearest_bone(0); else bone = get_nearest_bone(1); - + if (!bone) return; - + /* Select parents */ for (curBone=bone; curBone; curBone=next){ select_actionchannel_by_name (G.obpose->action, curBone->name, !(G.qual & LR_SHIFTKEY)); @@ -454,46 +625,77 @@ void selectconnected_posearmature(void) curBone->flag &= ~BONE_SELECTED; else curBone->flag |= BONE_SELECTED; - + if (curBone->flag & BONE_IK_TOPARENT) next=curBone->parent; else next=NULL; } - + /* Select children */ for (curBone=bone->childbase.first; curBone; curBone=next){ selectconnected_posebonechildren (curBone); } - countall(); + countall(); // flushes selection! + allqueue (REDRAWVIEW3D, 0); allqueue(REDRAWBUTSEDIT, 0); allqueue(REDRAWBUTSOBJECT, 0); allqueue (REDRAWACTION, 0); allqueue(REDRAWOOPS, 0); -} - -static void selectconnected_posebonechildren (Bone *bone) -{ - Bone *curBone; - - if (!(bone->flag & BONE_IK_TOPARENT)) - return; - - select_actionchannel_by_name (G.obpose->action, bone->name, !(G.qual & LR_SHIFTKEY)); + BIF_undo_push("Select connected"); - if (G.qual & LR_SHIFTKEY) - bone->flag &= ~BONE_SELECTED; - else - bone->flag |= BONE_SELECTED; +} +static int count_bonechildren (Bone *bone, int incount, int flagmask, int allbones){ + + Bone *curBone; + + if (!bone) + return incount; + + if (bone->flag & flagmask || flagmask == 0xFFFFFFFF){ + incount++; + if (!allbones) + return incount; + } + for (curBone=bone->childbase.first; curBone; curBone=curBone->next){ - selectconnected_posebonechildren (curBone); + incount=count_bonechildren (curBone, incount, flagmask, allbones); } + + return incount; } +static int count_bones (bArmature *arm, int flagmask, int allbones) +{ + int count=0; + Bone *curBone; + + if (!arm) + return 0; + + for (curBone=arm->bonebase.first; curBone; curBone=curBone->next){ + count = count_bonechildren (curBone, count, flagmask, allbones); + } + + return count; + +} + +static void make_bone_menu_children (Bone *bone, char *str, int *index) +{ + Bone *curBone; + + sprintf (str, "%s|%s%%x%d", str, bone->name, *index); + (*index) ++; + + for (curBone=bone->childbase.first; curBone; curBone=curBone->next) + make_bone_menu_children (curBone, str, index); +} +/* called in editobject.c */ char *make_bone_menu (bArmature *arm) { char *menustr=NULL; @@ -501,217 +703,166 @@ char *make_bone_menu (bArmature *arm) int size; int index=0; - + // Count the bones size = (count_bones (arm, 0xFFFFFFFF, 1)*48) + 256; menustr = MEM_callocN(size, "bonemenu"); - + sprintf (menustr, "Select Bone%%t"); - + for (curBone=arm->bonebase.first; curBone; curBone=curBone->next){ make_bone_menu_children (curBone, menustr, &index); } - + return menustr; } -static void make_bone_menu_children (Bone *bone, char *str, int *index) -{ - Bone *curBone; - sprintf (str, "%s|%s%%x%d", str, bone->name, *index); - (*index) ++; +/* **************** END Posemode stuff ********************** */ +/* **************** EditMode stuff ********************** */ - for (curBone=bone->childbase.first; curBone; curBone=curBone->next) - make_bone_menu_children (curBone, str, index); -} - -void free_editArmature(void) +/* called in space.c */ +void selectconnected_armature(void) { + EditBone *bone, *curBone, *next; - /* Clear the editbones list */ - if (G.edbo.first){ - BLI_freelistN (&G.edbo); - } -} - -static EditBone * get_nearest_editbonepoint (int findunsel, int *selmask){ - EditBone *ebone; - unsigned int buffer[MAXPICKBUF]; - short hits; - int i, takeNext=0; - int sel; - unsigned int hitresult, hitbone, firstunSel=-1; - - persp(PERSP_VIEW); + if (G.qual & LR_SHIFTKEY) + bone= get_nearest_bone(0); + else + bone= get_nearest_bone(1); - glInitNames(); - hits= selectprojektie(buffer, 0, 0, 0, 0); + if (!bone) + return; - /* See if there are any selected bones in this group */ - if (hits){ - for (i=0; i< hits; i++){ - hitresult = buffer[3+(i*4)]; - if (!(hitresult&BONESEL_NOSEL)){ + /* Select parents */ + for (curBone=bone; curBone; curBone=next){ + if (G.qual & LR_SHIFTKEY){ + curBone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL); + } + else{ + curBone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL); + } - /* Determine which points are selected */ - hitbone = hitresult & ~(BONESEL_ROOT|BONESEL_TIP); + if (curBone->flag & BONE_IK_TOPARENT) + next=curBone->parent; + else + next=NULL; + } - /* Determine what the current bone is */ - ebone = BLI_findlink(&G.edbo, hitbone); - - /* See if it is selected */ - sel = 0; - if ((hitresult & (BONESEL_TIP|BONESEL_ROOT)) == (BONESEL_TIP|BONESEL_ROOT)) - sel = (ebone->flag & (BONE_TIPSEL| BONE_ROOTSEL)) == (BONE_TIPSEL|BONE_ROOTSEL) ? 1 : 0; - else if (hitresult & BONESEL_TIP) - sel |= ebone->flag & BONE_TIPSEL; - else if (hitresult & BONESEL_ROOT) - sel |= ebone->flag & BONE_ROOTSEL; - if (!findunsel) - sel = !sel; - - if (sel) - takeNext=1; - else{ - if (firstunSel == -1) - firstunSel = hitresult; - if (takeNext){ - *selmask =0; - if (hitresult & BONESEL_ROOT) - *selmask |= BONE_ROOTSEL; - if (hitresult & BONESEL_TIP) - *selmask |= BONE_TIPSEL; - return ebone; - } + /* Select children */ + while (bone){ + for (curBone=G.edbo.first; curBone; curBone=next){ + next = curBone->next; + if (curBone->parent == bone){ + if (curBone->flag & BONE_IK_TOPARENT){ + if (G.qual & LR_SHIFTKEY) + curBone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL); + else + curBone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL); + bone=curBone; + break; + } + else{ + bone=NULL; + break; } } } + if (!curBone) + bone=NULL; - if (firstunSel != -1){ - *selmask = 0; - if (firstunSel & BONESEL_ROOT) - *selmask |= BONE_ROOTSEL; - if (firstunSel & BONESEL_TIP) - *selmask |= BONE_TIPSEL; - return BLI_findlink(&G.edbo, firstunSel & ~(BONESEL_ROOT|BONESEL_TIP)); - } -#if 1 - else{ - *selmask = 0; - if (buffer[3] & BONESEL_ROOT) - *selmask |= BONE_ROOTSEL; - if (buffer[3] & BONESEL_TIP) - *selmask |= BONE_TIPSEL; -#if 1 - return BLI_findlink(&G.edbo, buffer[3] & ~(BONESEL_ROOT|BONESEL_TIP)); -#else - return NULL; -#endif - } -#endif } - *selmask = 0; - return NULL; + countall(); // flushes selection! + + allqueue (REDRAWVIEW3D, 0); + allqueue (REDRAWBUTSEDIT, 0); + allqueue(REDRAWBUTSOBJECT, 0); + allqueue(REDRAWOOPS, 0); + + BIF_undo_push("Select connected"); + } -static void * get_nearest_bone (int findunsel){ - void *firstunSel=NULL, *data; - unsigned int buffer[MAXPICKBUF]; - short hits; - int i, takeNext=0; - int sel; - unsigned int hitresult; - Bone *bone; +/* does bones and points */ +/* note that BONE ROOT only gets drawn for root bones (or without IK) */ +static EditBone * get_nearest_editbonepoint (int findunsel, int *selmask) +{ EditBone *ebone; + unsigned int buffer[MAXPICKBUF]; + unsigned int hitresult, besthitresult=BONESEL_NOSEL; + int i, mindep= 4; + short hits; persp(PERSP_VIEW); glInitNames(); hits= selectprojektie(buffer, 0, 0, 0, 0); - /* See if there are any selected bones in this group */ - if (hits){ - for (i=0; i< hits; i++){ - hitresult = buffer[3+(i*4)]; - if (!(hitresult&BONESEL_NOSEL)){ - - /* Determine which points are selected */ - hitresult &= ~(BONESEL_ROOT|BONESEL_TIP); - - /* Determine what the current bone is */ - if (!G.obedit){ - bone = get_indexed_bone(OBACT->data, hitresult); - if (findunsel) - sel = (bone->flag & BONE_SELECTED); - else - sel = !(bone->flag & BONE_SELECTED); - data = bone; - } - else{ - ebone = BLI_findlink(&G.edbo, hitresult); - if (findunsel) - sel = (ebone->flag & BONE_SELECTED); - else - sel = !(ebone->flag & BONE_SELECTED); + if (hits) { + + if(hits==1) { + if (!(buffer[3] & BONESEL_NOSEL)) + besthitresult= buffer[3]; + } + else { + for (i=0; i< hits; i++) { + hitresult= buffer[3+(i*4)]; + if (!(hitresult & BONESEL_NOSEL)) { + int dep; - data = ebone; - } - - if (sel) - takeNext=1; - else{ - if (!firstunSel) - firstunSel=data; - if (takeNext) - return data; + ebone = BLI_findlink(&G.edbo, hitresult & ~BONESEL_ANY); + + /* clicks on bone points get advantage */ + if( hitresult & (BONESEL_ROOT|BONESEL_TIP)) { + /* but also the unselected one */ + if(findunsel) { + if( (hitresult & BONESEL_ROOT) && (ebone->flag & BONE_ROOTSEL)==0) + dep= 1; + else if( (hitresult & BONESEL_TIP) && (ebone->flag & BONE_TIPSEL)==0) + dep= 1; + else + dep= 2; + } + else dep= 2; + } + else { + /* bone found */ + if(findunsel) { + if((ebone->flag & BONE_SELECTED)==0) + dep= 2; + else + dep= 3; + } + else dep= 3; + } + if(dep < mindep) { + mindep= dep; + besthitresult= hitresult; + } } } } - - if (firstunSel) - return firstunSel; -#if 1 - else{ -#if 1 - if (G.obedit) - return BLI_findlink(&G.edbo, buffer[3] & ~(BONESEL_ROOT|BONESEL_TIP)); - else - return get_indexed_bone(OBACT->data, buffer[3] & ~(BONESEL_ROOT|BONESEL_TIP)); -#else - return NULL; -#endif + + if (!(besthitresult & BONESEL_NOSEL)) { + + ebone= BLI_findlink(&G.edbo, besthitresult & ~BONESEL_ANY); + + *selmask = 0; + if (besthitresult & BONESEL_ROOT) + *selmask |= BONE_ROOTSEL; + if (besthitresult & BONESEL_TIP) + *selmask |= BONE_TIPSEL; + if (besthitresult & BONESEL_BONE) + *selmask |= BONE_SELECTED; + return ebone; } -#endif } - + *selmask = 0; return NULL; } -void delete_armature(void) -{ - EditBone *curBone, *next; - - TEST_EDITARMATURE; - if(okee("Erase selected bone")==0) return; - - for (curBone=G.edbo.first;curBone;curBone=next){ - next=curBone->next; - if (curBone->flag&BONE_SELECTED) - delete_bone(curBone); - } - - - allqueue(REDRAWVIEW3D, 0); - allqueue(REDRAWBUTSEDIT, 0); - allqueue(REDRAWBUTSOBJECT, 0); - allqueue(REDRAWOOPS, 0); - countall(); -} - - static void delete_bone(EditBone* exBone) { EditBone *curBone; @@ -735,60 +886,140 @@ static void delete_bone(EditBone* exBone) } } } - - - allqueue(REDRAWBUTSOBJECT, 0); - allqueue(REDRAWBUTSEDIT, 0); - allqueue(REDRAWBUTSOBJECT, 0); - allqueue(REDRAWOOPS, 0); - BLI_freelinkN (&G.edbo,exBone); } -void remake_editArmature(void) +/* only editmode! */ +void delete_armature(void) { - if(okee("Reload original data")==0) return; + EditBone *curBone, *next; + + TEST_EDITARMATURE; + if(okee("Erase selected bone(s)")==0) return; + + for (curBone=G.edbo.first;curBone;curBone=next){ + next=curBone->next; + if (curBone->flag&BONE_SELECTED) + delete_bone(curBone); + } + - make_editArmature(); allqueue(REDRAWVIEW3D, 0); - allqueue(REDRAWOOPS, 0); - allqueue(REDRAWBUTSHEAD, 0); allqueue(REDRAWBUTSEDIT, 0); allqueue(REDRAWBUTSOBJECT, 0); + allqueue(REDRAWOOPS, 0); + countall(); // flushes selection! + + BIF_undo_push("Delete bone(s)"); } +/* editmode version */ void mouse_armature(void) { - EditBone* nearBone = NULL; + EditBone *nearBone = NULL, *ebone; int selmask; - nearBone=get_nearest_editbonepoint(1, &selmask); - - if (nearBone){ - if ((G.qual & LR_SHIFTKEY) && (nearBone->flag & selmask)) - nearBone->flag &= ~selmask; - else - nearBone->flag |= selmask; - - if (!(G.qual & LR_SHIFTKEY)){ + nearBone= get_nearest_editbonepoint(1, &selmask); + if (nearBone) { + + if (!(G.qual & LR_SHIFTKEY)) { + nearBone->flag |= BONE_TIPSEL; // fake, but deselectall toggles deselectall_armature(); - nearBone->flag |= selmask; } + + /* by definition the non-root non-IK bones have no root point drawn, + so a root selection needs to be delivered to the parent tip, + countall() (bad location) flushes these flags */ + + if(selmask & BONE_SELECTED) { + if(nearBone->parent && (nearBone->flag & BONE_IK_TOPARENT)) { + /* click in a chain */ + if(G.qual & LR_SHIFTKEY) { + /* hold shift inverts this bone's selection */ + if(nearBone->flag & BONE_SELECTED) { + /* deselect this bone */ + nearBone->flag &= ~(BONE_TIPSEL|BONE_SELECTED); + /* only deselect parent tip if it is not selected */ + if(!(nearBone->parent->flag & BONE_SELECTED)) + nearBone->parent->flag &= ~BONE_TIPSEL; + } + else { + /* select this bone */ + nearBone->flag |= BONE_TIPSEL; + nearBone->parent->flag |= BONE_TIPSEL; + } + } + else { + /* select this bone */ + nearBone->flag |= BONE_TIPSEL; + nearBone->parent->flag |= BONE_TIPSEL; + } + } + else { + if(G.qual & LR_SHIFTKEY) { + /* hold shift inverts this bone's selection */ + if(nearBone->flag & BONE_SELECTED) + nearBone->flag &= ~(BONE_TIPSEL|BONE_ROOTSEL); + else + nearBone->flag |= (BONE_TIPSEL|BONE_ROOTSEL); + } + else nearBone->flag |= (BONE_TIPSEL|BONE_ROOTSEL); + } + } + else { + if ((G.qual & LR_SHIFTKEY) && (nearBone->flag & selmask)) + nearBone->flag &= ~selmask; + else + nearBone->flag |= selmask; + } + + countall(); // flushes selection! + + if(nearBone) { + /* then now check for active status */ + for (ebone=G.edbo.first;ebone;ebone=ebone->next) ebone->flag &= ~BONE_ACTIVE; + if(nearBone->flag & BONE_SELECTED) nearBone->flag |= BONE_ACTIVE; + } + allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWBUTSEDIT, 0); allqueue(REDRAWBUTSOBJECT, 0); allqueue(REDRAWOOPS, 0); - }; - countall(); + } + rightmouse_transform(); } +void free_editArmature(void) +{ + + /* Clear the editbones list */ + if (G.edbo.first){ + BLI_freelistN (&G.edbo); + } +} + +void remake_editArmature(void) +{ + if(okee("Reload original data")==0) return; + + make_editArmature(); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWOOPS, 0); + allqueue(REDRAWBUTSHEAD, 0); + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWBUTSOBJECT, 0); + +// BIF_undo_push("Delete bone"); + +} + +/* Put object in EditMode */ void make_editArmature(void) { bArmature *arm; - if (G.obedit==0) - return; + if (G.obedit==0) return; free_editArmature(); @@ -799,376 +1030,415 @@ void make_editArmature(void) make_boneList (&G.edbo, &arm->bonebase,NULL); } -static void editbones_to_armature (ListBase *list, Object *ob) +/* put EditMode back in Object */ +void load_editArmature(void) { - bArmature *arm; - EditBone *eBone; - Bone *newBone; - - arm = get_armature(ob); - if (!list) - return; - if (!arm) - return; + bArmature *arm; - free_bones(arm); + arm= get_armature(G.obedit); + if (!arm) return; + editbones_to_armature(&G.edbo, G.obedit); +} - /* Copy the bones from the editData into the armature*/ - for (eBone=list->first;eBone;eBone=eBone->next){ - newBone=MEM_callocN (sizeof(Bone), "bone"); - eBone->temp= newBone; /* Associate the real Bones with the EditBones */ - - strcpy (newBone->name, eBone->name); - memcpy (newBone->head, eBone->head, sizeof(float)*3); - memcpy (newBone->tail, eBone->tail, sizeof(float)*3); - newBone->flag=eBone->flag &~(BONE_SELECTED|BONE_HILIGHTED); -// newBone->roll=eBone->roll; - newBone->roll = 0.0F; - - /* >>>>> FIXME: This isn't a very good system: a lot of - pointless copying involved. To be investigated - once things are working better. - */ - - newBone->weight = eBone->weight; - newBone->dist = eBone->dist; - newBone->boneclass = eBone->boneclass; - - memcpy (newBone->loc, eBone->loc, sizeof(eBone->loc)); - memcpy (newBone->dloc, eBone->dloc, sizeof(eBone->dloc)); -/* memcpy (newBone->orig, eBone->orig, sizeof(eBone->orig));*/ - memcpy (newBone->size, eBone->size, sizeof(eBone->size)); - memcpy (newBone->dsize, eBone->dsize, sizeof(eBone->dsize)); - memcpy (newBone->quat, eBone->quat, sizeof(eBone->quat)); - memcpy (newBone->dquat, eBone->dquat, sizeof(eBone->dquat)); - memcpy (newBone->obmat, eBone->obmat, sizeof(eBone->obmat)); - } - - /* Fix parenting in a separate pass to ensure ebone->bone connections - are valid at this point */ - for (eBone=list->first;eBone;eBone=eBone->next){ - newBone= (Bone*) eBone->temp; - if (eBone->parent){ - newBone->parent=(Bone*) eBone->parent->temp; - BLI_addtail (&newBone->parent->childbase,newBone); - - { - float M_boneRest[4][4]; - float M_parentRest[4][4]; - float iM_parentRest[4][4]; - float delta[3]; - - /* Get the parent's global matrix (rotation only)*/ - VecSubf (delta, eBone->parent->tail, eBone->parent->head); - make_boneMatrixvr(M_parentRest, delta, eBone->parent->roll); - - /* Get this bone's global matrix (rotation only)*/ - VecSubf (delta, eBone->tail, eBone->head); - make_boneMatrixvr(M_boneRest, delta, eBone->roll); - - /* Invert the parent matrix */ - Mat4Invert (iM_parentRest, M_parentRest); - - /* Get the new head and tail */ - VecSubf (newBone->head, eBone->head, eBone->parent->tail); - VecSubf (newBone->tail, eBone->tail, eBone->parent->tail); - Mat4MulVecfl(iM_parentRest, newBone->head); - Mat4MulVecfl(iM_parentRest, newBone->tail); +void deselectall_armature(void) +/* Actually, it toggles selection, deselecting +everything if anything is selected */ +{ + EditBone *eBone; + int sel=1; + + /* Determine if there are any selected bones + And therefore whether we are selecting or deselecting */ + for (eBone=G.edbo.first;eBone;eBone=eBone->next){ + if (eBone->flag & (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL)){ + sel=0; + break; + }; + }; + + /* Set the flags */ + for (eBone=G.edbo.first;eBone;eBone=eBone->next){ + if (sel) + eBone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); + else + eBone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL | BONE_ACTIVE); + }; + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWBUTSOBJECT, 0); + allqueue(REDRAWOOPS, 0); + + countall(); // flushes selection! +} - } - +void auto_align_armature(void) +/* Sets the roll value of selected bones so that their zaxes point upwards */ +{ + EditBone *ebone; + float xaxis[3]={1.0, 0.0, 0.0}, yaxis[3], zaxis[3]={0.0, 0.0, 1.0}; + float targetmat[3][3], imat[3][3]; + float curmat[3][3], diffmat[3][3]; + float delta[3]; + + for (ebone = G.edbo.first; ebone; ebone=ebone->next){ + if (ebone->flag & BONE_SELECTED){ + /* Find the current bone matrix */ + VecSubf(delta, ebone->tail, ebone->head); + vec_roll_to_mat3(delta, 0.0, curmat); + + /* Make new matrix based on y axis & z-up */ + VECCOPY (yaxis, curmat[1]); + + Mat3One(targetmat); + VECCOPY (targetmat[0], xaxis); + VECCOPY (targetmat[1], yaxis); + VECCOPY (targetmat[2], zaxis); + Mat3Ortho(targetmat); + + /* Find the difference between the two matrices */ + Mat3Inv(imat, targetmat); + Mat3MulMat3(diffmat, imat, curmat); + + ebone->roll = atan(diffmat[2][0]/diffmat[2][2]); + } - /* ...otherwise add this bone to the armature's bonebase */ - else - BLI_addtail (&arm->bonebase,newBone); } - - /* Make a pass through the new armature to fix rolling */ - fix_bonelist_roll (&arm->bonebase, list); - /* Get rid of pose channels that may have belonged to deleted bones */ - collect_pose_garbage(ob); - /* Ensure all bones have channels */ - apply_pose_armature(arm, ob->pose, 0); - - /* Calculate and cache the inverse restposition matrices (needed for deformation)*/ - precalc_bonelist_irestmats(&arm->bonebase); } +/* **************** undo for armatures ************** */ -void load_editArmature(void) +static void undoBones_to_editBones(void *lbv) { - bArmature *arm; - - arm=get_armature(G.obedit); - if (!arm) - return; + ListBase *lb= lbv; + EditBone *ebo, *newebo; -#if 1 - editbones_to_armature(&G.edbo, G.obedit); -#else - free_bones(arm); + BLI_freelistN(&G.edbo); + /* copy */ + for(ebo= lb->first; ebo; ebo= ebo->next) { + newebo= MEM_dupallocN(ebo); + ebo->temp= newebo; + BLI_addtail(&G.edbo, newebo); + } + + /* set pointers */ + for(newebo= G.edbo.first; newebo; newebo= newebo->next) { + if(newebo->parent) newebo->parent= newebo->parent->temp; + } + /* be sure they dont hang ever */ + for(newebo= G.edbo.first; newebo; newebo= newebo->next) { + newebo->temp= NULL; + } +} - /* Copy the bones from the editData into the armature*/ - for (eBone=G.edbo.first;eBone;eBone=eBone->next){ - newBone=MEM_callocN (sizeof(Bone), "bone"); - eBone->temp= newBone; /* Associate the real Bones with the EditBones */ - - strcpy (newBone->name, eBone->name); - memcpy (newBone->head, eBone->head, sizeof(float)*3); - memcpy (newBone->tail, eBone->tail, sizeof(float)*3); - newBone->flag=eBone->flag &~(BONE_SELECTED|BONE_HILIGHTED); - // newBone->roll=eBone->roll; - newBone->roll = 0.0F; - - /* >>>>> FIXME: This isn't a very good system: a lot of - pointless copying involved. To be investigated - once things are working better. - */ - - newBone->weight = eBone->weight; - newBone->dist = eBone->dist; - newBone->boneclass = eBone->boneclass; - - memcpy (newBone->loc, eBone->loc, sizeof(eBone->loc)); - memcpy (newBone->dloc, eBone->dloc, sizeof(eBone->dloc)); -/* memcpy (newBone->orig, eBone->orig, sizeof(eBone->orig));*/ - memcpy (newBone->size, eBone->size, sizeof(eBone->size)); - memcpy (newBone->dsize, eBone->dsize, sizeof(eBone->dsize)); - memcpy (newBone->quat, eBone->quat, sizeof(eBone->quat)); - memcpy (newBone->dquat, eBone->dquat, sizeof(eBone->dquat)); - memcpy (newBone->obmat, eBone->obmat, sizeof(eBone->obmat)); +static void *editBones_to_undoBones(void) +{ + ListBase *lb; + EditBone *ebo, *newebo; + + lb= MEM_callocN(sizeof(ListBase), "listbase undo"); + + /* copy */ + for(ebo= G.edbo.first; ebo; ebo= ebo->next) { + newebo= MEM_dupallocN(ebo); + ebo->temp= newebo; + BLI_addtail(lb, newebo); + } + + /* set pointers */ + for(newebo= lb->first; newebo; newebo= newebo->next) { + if(newebo->parent) newebo->parent= newebo->parent->temp; } + + return lb; +} - /* Fix parenting in a separate pass to ensure ebone->bone connections - are valid at this point */ - for (eBone=G.edbo.first;eBone;eBone=eBone->next){ - newBone= (Bone*) eBone->temp; - if (eBone->parent){ - newBone->parent=(Bone*) eBone->parent->temp; - BLI_addtail (&newBone->parent->childbase,newBone); +static void free_undoBones(void *lbv) +{ + ListBase *lb= lbv; + + BLI_freelistN(lb); + MEM_freeN(lb); +} - { - float M_boneRest[4][4]; - float M_parentRest[4][4]; - float M_relativeBone[4][4]; - float iM_parentRest[4][4]; - float delta[3]; - - /* Get the parent's global matrix (rotation only)*/ - VecSubf (delta, eBone->parent->tail, eBone->parent->head); - make_boneMatrixvr(M_parentRest, delta, eBone->parent->roll); +/* and this is all the undo system needs to know */ +void undo_push_armature(char *name) +{ + undo_editmode_push(name, free_undoBones, undoBones_to_editBones, editBones_to_undoBones); +} - /* Get this bone's global matrix (rotation only)*/ - VecSubf (delta, eBone->tail, eBone->head); - make_boneMatrixvr(M_boneRest, delta, eBone->roll); - /* Invert the parent matrix */ - Mat4Invert (iM_parentRest, M_parentRest); - /* Get the new head and tail */ - VecSubf (newBone->head, eBone->head, eBone->parent->tail); - VecSubf (newBone->tail, eBone->tail, eBone->parent->tail); +/* **************** END EditMode stuff ********************** */ +/* *************** Armature drawing ******************* */ - Mat4MulVecfl(iM_parentRest, newBone->head); - Mat4MulVecfl(iM_parentRest, newBone->tail); +static void draw_bonevert(void) +{ + static GLuint displist=0; - - } - - } - /* ...otherwise add this bone to the armature's bonebase */ - else - BLI_addtail (&arm->bonebase,newBone); + if(displist==0) { + GLUquadricObj *qobj; + + displist= glGenLists(1); + glNewList(displist, GL_COMPILE_AND_EXECUTE); + + glPushMatrix(); + + qobj = gluNewQuadric(); + gluQuadricDrawStyle(qobj, GLU_SILHOUETTE); + gluDisk( qobj, 0.0, 0.05, 16, 1); + + glRotatef (90, 0, 1, 0); + gluDisk( qobj, 0.0, 0.05, 16, 1); + + glRotatef (90, 1, 0, 0); + gluDisk( qobj, 0.0, 0.05, 16, 1); + + gluDeleteQuadric(qobj); + + glPopMatrix(); + glEndList(); } - - /* Make a pass through the new armature to fix rolling */ - fix_bonelist_roll (&arm->bonebase, &G.edbo); - - /* Get rid of pose channels that may have belonged to deleted bones */ - collect_pose_garbage(G.obedit); -#endif + else glCallList(displist); } -static void fix_bonelist_roll (ListBase *bonelist, ListBase *editbonelist) +static void draw_bone_octahedral() { - Bone *curBone; - EditBone *ebone; - - for (curBone=bonelist->first; curBone; curBone=curBone->next){ + static GLuint displist=0; + + if(displist==0) { + float vec[6][3]; - /* Fix this bone's roll */ -#if 1 - { - float premat[4][4]; - float postmat[4][4]; - float difmat[4][4]; - float imat[4][4]; - float delta[3]; + displist= glGenLists(1); + glNewList(displist, GL_COMPILE_AND_EXECUTE); - /* Find the associated editbone */ - for (ebone = editbonelist->first; ebone; ebone=ebone->next) - if ((Bone*)ebone->temp == curBone) - break; - - if (ebone){ - /* Get the premat */ - VecSubf (delta, ebone->tail, ebone->head); - make_boneMatrixvr(premat, delta, ebone->roll); - - /* Get the postmat */ - get_objectspace_bone_matrix(curBone, postmat, 1, 0); - postmat[3][0]=postmat[3][1]=postmat[3][2]=0.0F; -#if 1 - Mat4Invert (imat, premat); - Mat4MulMat4 (difmat, postmat, imat); -#else - Mat4Invert (imat, postmat); - Mat4MulMat4 (difmat, premat, imat); -#endif -#if 0 - printf ("Bone %s\n", curBone->name); - printmatrix4 ("premat", premat); - printmatrix4 ("postmat", postmat); - printmatrix4 ("difmat", difmat); - printf ("Roll = %f\n", (-atan(difmat[2][0]/difmat[2][2]) * (180.0/M_PI))); -#endif - curBone->roll = -atan(difmat[2][0]/difmat[2][2]); - - if (difmat[0][0]<0) - curBone->roll +=M_PI; - - } - } -#endif + vec[0][0]= vec[0][1]= vec[0][2]= 0.0; + vec[5][0]= vec[5][2]= 0.0; vec[5][1]= 1.0; - fix_bonelist_roll (&curBone->childbase, editbonelist); + vec[1][0]= 0.1; vec[1][2]= 0.1; vec[1][1]= 0.1; + vec[2][0]= 0.1; vec[2][2]= -0.1; vec[2][1]= 0.1; + vec[3][0]= -0.1; vec[3][2]= -0.1; vec[3][1]= 0.1; + vec[4][0]= -0.1; vec[4][2]= 0.1; vec[4][1]= 0.1; + + /* Section 1, sides */ + glBegin(GL_LINE_LOOP); + glVertex3fv(vec[0]); + glVertex3fv(vec[1]); + glVertex3fv(vec[5]); + glVertex3fv(vec[3]); + glVertex3fv(vec[0]); + glVertex3fv(vec[4]); + glVertex3fv(vec[5]); + glVertex3fv(vec[2]); + glEnd(); + + /* Section 1, square */ + glBegin(GL_LINE_LOOP); + glVertex3fv(vec[1]); + glVertex3fv(vec[2]); + glVertex3fv(vec[3]); + glVertex3fv(vec[4]); + glEnd(); + + glEndList(); } -} + else glCallList(displist); +} -void make_bone_parent(void) +static void draw_bone_solid_octahedral(void) { -/* error ("Bone Parenting not yet implemented"); */ - return; -} - -static void make_boneList(ListBase* list, ListBase *bones, EditBone *parent) -{ - EditBone *eBone; - Bone *curBone; + static GLuint displist=0; - for (curBone=bones->first; curBone; curBone=curBone->next){ - eBone=MEM_callocN(sizeof(EditBone),"make_editbone"); + if(displist==0) { + float vec[6][3]; + + displist= glGenLists(1); + glNewList(displist, GL_COMPILE_AND_EXECUTE); + + vec[0][0]= vec[0][1]= vec[0][2]= 0.0; + vec[5][0]= vec[5][2]= 0.0; vec[5][1]= 1.0; + + vec[1][0]= 0.1; vec[1][2]= 0.1; vec[1][1]= 0.1; + vec[2][0]= 0.1; vec[2][2]= -0.1; vec[2][1]= 0.1; + vec[3][0]= -0.1; vec[3][2]= -0.1; vec[3][1]= 0.1; + vec[4][0]= -0.1; vec[4][2]= 0.1; vec[4][1]= 0.1; - /* Copy relevant data from bone to eBone */ - eBone->parent=parent; - strcpy (eBone->name, curBone->name); - eBone->flag = curBone->flag & ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL); - - /* Print bone matrix before and after */ - - get_bone_root_pos(curBone, eBone->head, 0); - get_bone_tip_pos(curBone, eBone->tail, 0); -// eBone->roll=curBone->roll; - eBone->roll=0; - -#if 1 - { - float delta[3]; - float premat[4][4]; - float postmat[4][4]; - float imat[4][4]; - float difmat[4][4]; - - VecSubf (delta, eBone->tail, eBone->head); - make_boneMatrixvr(postmat, delta, eBone->roll); - - get_objectspace_bone_matrix(curBone, premat, 1, 0); - -#if 0 - Mat4Invert (imat, premat); - Mat4MulMat4 (difmat, postmat, imat); -#else - Mat4Invert (imat, postmat); - Mat4MulMat4 (difmat, premat, imat); -#endif -#if 0 - printf ("Bone %s\n", curBone->name); - printmatrix4 ("diffmat", difmat); - printf ("Roll : atan of %f / %f = %f\n", difmat[2][0], difmat[2][2], (float)atan(difmat[2][0]/difmat[2][2])*(180.0F/M_PI)); -#endif - eBone->roll = atan(difmat[2][0]/difmat[2][2]); - - if (difmat[0][0]<0) - eBone->roll +=M_PI; - } -#endif - eBone->dist= curBone->dist; - eBone->weight= curBone->weight; - eBone->boneclass = curBone->boneclass; - memcpy (eBone->loc, curBone->loc, sizeof(curBone->loc)); - memcpy (eBone->dloc, curBone->dloc, sizeof(curBone->dloc)); - /* memcpy (eBone->orig, curBone->orig, sizeof(curBone->orig));*/ - memcpy (eBone->size, curBone->size, sizeof(curBone->size)); - memcpy (eBone->dsize, curBone->dsize, sizeof(curBone->dsize)); - memcpy (eBone->quat, curBone->quat, sizeof(curBone->quat)); - memcpy (eBone->dquat, curBone->dquat, sizeof(curBone->dquat)); - memcpy (eBone->obmat, curBone->obmat, sizeof(curBone->obmat)); + glBegin(GL_TRIANGLES); + /* bottom */ + glVertex3fv(vec[0]);glVertex3fv(vec[1]);glVertex3fv(vec[2]); + + glVertex3fv(vec[0]);glVertex3fv(vec[2]);glVertex3fv(vec[3]); + + glVertex3fv(vec[0]);glVertex3fv(vec[3]);glVertex3fv(vec[4]); - BLI_addtail (list, eBone); + glVertex3fv(vec[0]);glVertex3fv(vec[4]);glVertex3fv(vec[1]); + /* top */ + glVertex3fv(vec[5]);glVertex3fv(vec[1]);glVertex3fv(vec[2]); - /* Add children if necessary */ - if (curBone->childbase.first) - make_boneList (list, &curBone->childbase, eBone); + glVertex3fv(vec[5]);glVertex3fv(vec[2]);glVertex3fv(vec[3]); + + glVertex3fv(vec[5]);glVertex3fv(vec[3]);glVertex3fv(vec[4]); + + glVertex3fv(vec[5]);glVertex3fv(vec[4]);glVertex3fv(vec[1]); + + glEnd(); + + glEndList(); } - + else glCallList(displist); +} -} -#if 0 -static EditVert* add_armatureVert (float *loc) +static void draw_bone (int armflag, int boneflag, int constflag, unsigned int id, char *name, float length) { - EditMesh *em = G.editMesh; - EditVert* vert=NULL; - - vert = MEM_callocN (sizeof (EditVert), "armaturevert"); - if (vert){ - VECCOPY (vert->co, loc); - BLI_addtail (&em->verts,vert); + float pointsize; + + /* Draw a 3d octahedral bone, we use normalized space based on length, + for glDisplayLists */ + + /* pointsize todo! */ + pointsize = length; + if (length<0.1) + pointsize=0.1; + + glScalef(length, length, length); + + if (id!=-1) glLoadName((GLuint) id ); + + /* Draw root point if we have no IK parent */ + if (!(boneflag & BONE_IK_TOPARENT)){ + if (id != -1) + glLoadName (id | BONESEL_ROOT); + + if (armflag & ARM_EDITMODE) { + if (boneflag & BONE_ROOTSEL) cpack (B_YELLOW); + else cpack (B_PURPLE); + } + draw_bonevert(); + } + + /* Draw tip point (for selection only ) */ + + if (id != -1) + glLoadName (id | BONESEL_TIP); + + if (armflag & ARM_EDITMODE) { + if (boneflag & BONE_TIPSEL) cpack (B_YELLOW); + else cpack (B_PURPLE); + } + + glTranslatef(0.0, 1.0, 0.0); + draw_bonevert(); + + /* Draw additional axes */ + if (armflag & ARM_DRAWAXES){ + drawaxes(0.25f); + } + + glTranslatef(0.0, -1.0, 0.0); + + if (id != -1) { + if (armflag & ARM_POSEMODE) + glLoadName((GLuint) id); + else{ + glLoadName ((GLuint) id|BONESEL_BONE); + } + } + + /* colors */ + if (armflag & ARM_EDITMODE){ + if (boneflag & BONE_ACTIVE) cpack (B_YELLOW_A); + else if (boneflag & BONE_SELECTED) cpack (B_YELLOW); + else cpack (B_PURPLE); + } + else if (armflag & ARM_POSEMODE){ + + if(constflag) { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + if(constflag & PCHAN_HAS_IK) glColor4ub(255, 255, 0, 50); + else glColor4ub(0, 255, 120, 50); + draw_bone_solid_octahedral(); + glDisable(GL_BLEND); + } + + if (boneflag & BONE_ACTIVE) cpack (B_CYAN_A); + else if (boneflag & BONE_SELECTED) cpack (B_CYAN); + else cpack (B_AQUA); + } + draw_bone_octahedral(); + + /* Draw the bone name */ + if (armflag & ARM_DRAWNAMES) { + // patch for several 3d cards (IBM mostly) that crash on glSelect with text drawing + if((G.f & G_PICKSEL) == 0) { + glRasterPos3f(0, 0.5, 0); + BMF_DrawString(G.font, " "); + BMF_DrawString(G.font, name); + } } - - return vert; - } -static EditVert* get_armatureVert (float *loc) -{ - EditMesh *em = G.editMesh; - EditVert* vert; - for (vert=em->verts.first;vert;vert=vert->next){ - if ((vert->co[0]==loc[0])&&(vert->co[1]==loc[1])&&(vert->co[2]==loc[2])){ - return (vert); +/* assumes object is Armature with pose */ +static void draw_pose_channels(Object *ob) +{ + bPoseChannel *pchan; + Bone *bone; + bArmature *arm= ob->data; + short flag; + int index= -1; + + if (arm->flag & ARM_POSEMODE) index= 0; + + for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { + bone= pchan->bone; + if(bone) { + + // Draw a line from our root to the parent's tip + if (bone->parent && !(bone->flag & (BONE_IK_TOPARENT|BONE_HIDDEN)) ){ + + if (arm->flag & ARM_POSEMODE) glLoadName (-1); + + setlinestyle(3); + glBegin(GL_LINES); + glVertex3fv(pchan->pose_head); + glVertex3fv(pchan->parent->pose_tail); + glEnd(); + setlinestyle(0); + } + if(!(bone->flag & BONE_HIDDEN)) { + glPushMatrix(); + glMultMatrixf(pchan->pose_mat); + + if (index!= -1) { // set color for points */ + if (bone->flag & BONE_ACTIVE) cpack (B_CYAN_A); + else if (bone->flag & BONE_SELECTED) cpack (B_CYAN); + else cpack (B_AQUA); + } + /* catch exception for bone with hidden parent */ + flag= bone->flag; + if(bone->parent && (bone->parent->flag & BONE_HIDDEN)) + bone->flag &= ~BONE_IK_TOPARENT; + + draw_bone(arm->flag, flag, pchan->constflag, index, bone->name, bone->length); + + glPopMatrix(); + } + if (index!= -1) index++; } } - - return add_armatureVert (loc); + } -#endif +/* called from drawobject.c */ void draw_armature(Object *ob) { bArmature *arm; - Bone *bone; - EditBone *eBone; - unsigned int index; - float delta[3],offset[3]; - float bmat[4][4]; - float length; if (ob==NULL) return; @@ -1184,17 +1454,17 @@ void draw_armature(Object *ob) /* If we're in editmode, draw the Global edit data */ if(ob==G.obedit || (G.obedit && ob->data==G.obedit->data)) { - cpack (0x000000); + EditBone *eBone; + unsigned int index; + float delta[3],offset[3]; + float mat[3][3], bmat[4][4]; + float length; + cpack (0); - arm->flag |= ARM_EDITMODE; + if(ob==G.obedit) arm->flag |= ARM_EDITMODE; for (eBone=G.edbo.first, index=0; eBone; eBone=eBone->next, index++){ - if (ob==G.obedit){ - // if ((eBone->flag&(BONE_TIPSEL | BONE_ROOTSEL))==(BONE_TIPSEL|BONE_ROOTSEL)) - // cpack (B_YELLOW); - // else - cpack (B_PURPLE); - } - else cpack (0x000000); + if (ob==G.obedit) cpack (B_PURPLE); + else cpack (0); glPushMatrix(); @@ -1208,13 +1478,16 @@ void draw_armature(Object *ob) delta[2]=eBone->tail[2]-eBone->head[2]; length = sqrt (delta[0]*delta[0] + delta[1]*delta[1] +delta[2]*delta[2]); - - make_boneMatrixvr(bmat, delta, eBone->roll); + + vec_roll_to_mat3(delta, eBone->roll, mat); + Mat4CpyMat3(bmat, mat); + glMultMatrixf (bmat); - draw_bone (arm->flag, eBone->flag, index, eBone->name, length); + draw_bone (arm->flag, eBone->flag, 0, index, eBone->name, length); glPopMatrix(); - if (eBone->parent){ + + if (eBone->parent) { glLoadName (-1); setlinestyle(3); @@ -1225,46 +1498,29 @@ void draw_armature(Object *ob) setlinestyle(0); } - }; + } arm->flag &= ~ARM_EDITMODE; cpack (B_YELLOW); } else{ - /* Draw hierarchical bone list (non-edit data) */ - - /* Ensure we're using the mose recent pose */ - if (!ob->pose) - ob->pose=MEM_callocN (sizeof(bPose), "pose"); - -#if 1 /* Activate if there are problems with action lag */ - apply_pose_armature(arm, ob->pose, 0); - where_is_armature (ob); -#endif + /* Draw Pose */ + if(ob->pose) { + if (G.obpose == ob) arm->flag |= ARM_POSEMODE; + draw_pose_channels(ob); + arm->flag &= ~ARM_POSEMODE; + } - if (G.obpose == ob){ - arm->flag |= ARM_POSEMODE; #if 0 /* Depreciated interactive ik goal drawing */ - if (arm->chainbase.first){ - glPushMatrix(); - glTranslatef(((PoseChain*)arm->chainbase.first)->goal[0], - ((PoseChain*)arm->chainbase.first)->goal[1], - ((PoseChain*)arm->chainbase.first)->goal[2]); - drawaxes(1.0); - glPopMatrix(); - } + if (arm->chainbase.first){ + glPushMatrix(); + glTranslatef(((PoseChain*)arm->chainbase.first)->goal[0], + ((PoseChain*)arm->chainbase.first)->goal[1], + ((PoseChain*)arm->chainbase.first)->goal[2]); + drawaxes(1.0); + glPopMatrix(); + } #endif - } - index = 0; - for (bone=arm->bonebase.first; bone; bone=bone->next) { - glPushMatrix(); - draw_bonechildren(bone, arm->flag, &index); - glPopMatrix(); - if (arm->flag & ARM_POSEMODE) - cpack (B_CYAN); - } - - arm->flag &= ~ARM_POSEMODE; } if (arm->flag & ARM_DRAWXRAY) { @@ -1272,286 +1528,8 @@ void draw_armature(Object *ob) } } -static void draw_boneverti (float x, float y, float z, float size, int flag) -{ - GLUquadricObj *qobj; - - size*=0.05; - -/* - Ultimately dots should be drawn in screenspace - For now we'll just draw them any old way. -*/ - glPushMatrix(); - - glTranslatef(x, y, z); - - qobj = gluNewQuadric(); - gluQuadricDrawStyle(qobj, GLU_SILHOUETTE); - gluPartialDisk( qobj, 0, 1.0F*size, 32, 1, 360.0, 360.0); - - glRotatef (90, 0, 1, 0); - gluPartialDisk( qobj, 0, 1.0F*size, 32, 1, 360.0, 360.0); - - glRotatef (90, 1, 0, 0); - gluPartialDisk( qobj, 0, 1.0F*size, 32, 1, 360.0, 360.0); - - gluDeleteQuadric(qobj); - - glPopMatrix(); -} - -static void draw_bonechildren (Bone *bone, int flag, unsigned int *index) -{ - Bone *cbone; - float delta[3]; - float length; - float M_objectspacemat[4][4]; - - if (bone==NULL) return; - - if (flag & ARM_POSEMODE){ - if (bone->flag & BONE_SELECTED) - cpack (B_CYAN); - else - cpack (B_AQUA); - } - - // Draw a line from our root to the parent's tip - if (bone->parent && !(bone->flag & (BONE_IK_TOPARENT|BONE_HIDDEN)) ){ - float childMat[4][4]; - float boneMat[4][4]; - float tip[3], root[3]; - get_objectspace_bone_matrix(bone->parent, boneMat, 0, 1); - get_objectspace_bone_matrix(bone, childMat, 1, 1); - - VECCOPY (tip, boneMat[3]); - VECCOPY (root, childMat[3]); - - if (flag & ARM_POSEMODE) - glLoadName (-1); - setlinestyle(3); - glBegin(GL_LINES); - glVertex3fv(tip); - glVertex3fv(root); - glEnd(); - setlinestyle(0); - } - - - /* Draw this bone in objectspace */ - delta[0]=bone->tail[0]-bone->head[0]; - delta[1]=bone->tail[1]-bone->head[1]; - delta[2]=bone->tail[2]-bone->head[2]; - length = sqrt (delta[0]*delta[0] + delta[1]*delta[1] + delta[2]*delta[2] ); - - /* Incorporates offset, rest rotation, user rotation and parent coordinates*/ - get_objectspace_bone_matrix(bone, M_objectspacemat, 1, 1); - - if (!(bone->flag & BONE_HIDDEN)){ - glPushMatrix(); - glMultMatrixf(M_objectspacemat); - - - if (flag & ARM_POSEMODE) - draw_bone(flag, (bone->parent && bone->parent->flag & BONE_HIDDEN) ? (bone->flag & ~BONE_IK_TOPARENT) : (bone->flag), *index, bone->name, length); - else - draw_bone(flag, (bone->parent && bone->parent->flag & BONE_HIDDEN) ? (bone->flag & ~BONE_IK_TOPARENT) : (bone->flag), -1, bone->name, length); - glPopMatrix(); - } - (*index)++; - - /* Draw the children */ - for (cbone= bone->childbase.first; cbone; cbone=cbone->next){ - draw_bonechildren (cbone, flag, index); - } -} - -static void draw_bone (int armflag, int boneflag, unsigned int id, char *name, float length) -{ - float vec[2]; - float bulge; - float pointsize; - /* - FIXME: This routine should probably draw the bones in screenspace using - the projected start & end points of the transformed bone - */ - - pointsize = length; - if (pointsize<0.1) - pointsize=0.1; - - /* Draw a 3d octahedral bone */ - - bulge=length*0.1; - - if (id!=-1) - glLoadName((GLuint) id ); - - glPushMatrix(); - - /* Draw root point if we have no IK parent */ - if (!(boneflag & BONE_IK_TOPARENT)){ - if (id != -1) - glLoadName (id | BONESEL_ROOT); - if (armflag & ARM_EDITMODE){ - if (boneflag & BONE_ROOTSEL) - cpack (B_YELLOW); - else - cpack (B_PURPLE); - } - draw_boneverti (0, 0, 0, pointsize, 0); - } - - /* Draw tip point (for selection only )*/ - - if (id != -1) - glLoadName (id | BONESEL_TIP); - - if (armflag & ARM_EDITMODE){ - if (boneflag & BONE_TIPSEL) - cpack (B_YELLOW); - else - cpack (B_PURPLE); - } - - draw_boneverti (0, length, 0, pointsize, 0); - - if (id != -1){ - if (armflag & ARM_POSEMODE) - glLoadName((GLuint) id); - else{ -#if 1 /* Bones not selectable in editmode */ - glLoadName((GLuint) -1); -#else - glLoadName ((GLuint) id|BONESEL_TIP|BONESEL_ROOT); -#endif - } - } - - - if (armflag & ARM_EDITMODE){ - if (boneflag & BONE_SELECTED) - cpack (B_YELLOW); - else - cpack (B_PURPLE); - } - - /* Draw additional axes */ - if (armflag & ARM_DRAWAXES){ - drawaxes(length*0.25F); - } - - /* Section 1*/ - glBegin(GL_LINE_STRIP); - vec[0]= vec[1]= 0; - glVertex2fv(vec); - - vec[0]= -bulge; vec[1]= bulge; - glVertex2fv(vec); - - vec[0]= 0; vec[1]= length; - glVertex2fv(vec); - - vec[0]= bulge; vec[1]= bulge; - glVertex2fv(vec); - - vec[0]= 0; vec[1]= 0; - glVertex2fv(vec); - glEnd(); - - /* Section 2*/ - glRotatef(90,0,1,0); - glBegin(GL_LINE_STRIP); - vec[0]= vec[1]= 0; - glVertex2fv(vec); - - vec[0]= -bulge; vec[1]= bulge; - glVertex2fv(vec); - - vec[0]= 0; vec[1]= length; - glVertex2fv(vec); - - vec[0]= bulge; vec[1]= bulge; - glVertex2fv(vec); - - vec[0]= 0; vec[1]= 0; - glVertex2fv(vec); - glEnd(); - - /* Square*/ - glTranslatef (0,bulge,0); - glRotatef(45,0,1,0); - glRotatef(90,1,0,0); - glBegin(GL_LINE_STRIP); - - vec[0]= -bulge*.707;vec[1]=-bulge*.707; - glVertex2fv(vec); - - vec[0]= bulge*.707;vec[1]= -bulge*.707; - glVertex2fv(vec); - - vec[0]= bulge*.707;vec[1]= bulge*.707; - glVertex2fv(vec); - - vec[0]= -bulge*.707;vec[1]= bulge*.707; - glVertex2fv(vec); - - vec[0]= vec[1]= -bulge*.707; - glVertex2fv(vec); - glEnd(); - - - glPopMatrix(); - - /* Draw the bone name */ - if (armflag & ARM_DRAWNAMES) { - // patch for several 3d cards (IBM mostly) that crash on glSelect with text drawing - if((G.f & G_PICKSEL) == 0) { - glRasterPos3f(0, length/2.0, 0); - BMF_DrawString(G.font, " "); - BMF_DrawString(G.font, name); - } - } -} - - - -void add_primitiveArmature(int type) -{ - if(G.scene->id.lib) return; - - /* this function also comes from an info window */ - if ELEM(curarea->spacetype, SPACE_VIEW3D, SPACE_INFO); else return; - if(G.vd==NULL) return; - - G.f &= ~(G_VERTEXPAINT+G_FACESELECT+G_TEXTUREPAINT+G_WEIGHTPAINT); - setcursor_space(SPACE_VIEW3D, CURSOR_STD); - - check_editmode(OB_ARMATURE); - - /* If we're not the "obedit", make a new object and enter editmode */ - if(G.obedit==NULL) { - add_object(OB_ARMATURE); - base_init_from_view3d(BASACT, G.vd); - G.obedit= BASACT->object; - - where_is_object(G.obedit); - - make_editArmature(); - setcursor_space(SPACE_VIEW3D, CURSOR_EDIT); - } - - switch (type){ - default: - add_bone_input (G.obedit); - break; - }; - - countall(); - - allqueue(REDRAWALL, 0); -} +/* *************** END Armature drawing ******************* */ +/* *************** Adding stuff in editmode *************** */ static void add_bone_input (Object *ob) /* @@ -1562,8 +1540,8 @@ static void add_bone_input (Object *ob) child of the previous bone. Pressing ESC cancels the current bone and leaves bone adding mode. - -*/ + + */ { float *cursLoc, cent[3], dx, dy; float mat[3][3], curs[3], cmat[3][3], imat[3][3], rmat[4][4], itmat[4][4]; @@ -1611,39 +1589,38 @@ static void add_bone_input (Object *ob) strcpy (bone->name,"Bone"); unique_editbone_name (bone->name); - + BLI_addtail(&G.edbo, bone); - - bone->flag |= BONE_QUATROT; + bone->flag |= (BONE_SELECTED); deselectall_armature(); - bone->flag |= BONE_SELECTED|BONE_HILIGHTED|BONE_TIPSEL|BONE_ROOTSEL; + bone->flag |= BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL; bone->weight= 1.0F; bone->dist= 1.0F; bone->boneclass = BONE_SKINNABLE; - + /* Project cursor center to screenspace. */ getmouseco_areawin(mval); xo= mvalo[0]= mval[0]; yo= mvalo[1]= mval[1]; window_to_3d(dvecp, xo, yo); drawall= 2; - + while (1) { - + getmouseco_areawin(mval); window_to_3d(dvec, mval[0], mval[1]); - + scale=1000; - + dx= ((float)mval[0]-(float)xo)*scale; dy= ((float)mval[1]-(float)yo)*scale; - + /* Calc bone length*/ lengths= sqrt((dx*dx)+(dy*dy)); length = sqrt(((dvec[0]-dvecp[0])*(dvec[0]-dvecp[0]))+((dvec[1]-dvecp[1])*(dvec[1]-dvecp[1]))+((dvec[2]-dvecp[2])*(dvec[2]-dvecp[2]))); - + /* Find rotation around screen normal */ if (lengths>0.0F) { angle= acos(dy/lengths); @@ -1671,7 +1648,7 @@ static void add_bone_input (Object *ob) rmat[3][3]= 1.0F; /* Rotate object's inversemat by the bone's rotation - to get the coordinate space of the bone */ + to get the coordinate space of the bone */ Mat4CpyMat3 (itmat, imat); Mat4MulMat4 (restmat, rmat, itmat); @@ -1688,13 +1665,9 @@ static void add_bone_input (Object *ob) /* IF we're a child of something, add the parents' translates */ /* Offset of child is new cursor*/ - + VECCOPY (newEnd,bone->tail); newEnd[3]=1; - - /* Set the bone's transformations */ - Mat4One (bone->obmat); - bone->size[0]=bone->size[1]=bone->size[2]=1.0F; - + /* only draw if... */ if(drawall) { drawall--; // draw twice to have 2 identical buffers @@ -1711,25 +1684,25 @@ static void add_bone_input (Object *ob) event= extern_qread(&val); if(val) { switch(event) { - case ESCKEY: - case RIGHTMOUSE: - BLI_freelinkN (&G.edbo,bone); - afbreek=1; - addbones=0; - break; - case LEFTMOUSE: - case MIDDLEMOUSE: - case SPACEKEY: - case RETKEY: - afbreek= 1; - - Mat4MulVec4fl (G.obedit->obmat,newEnd); - - curs[0]=newEnd[0]; - curs[1]=newEnd[1]; - curs[2]=newEnd[2]; - addbones++; - break; + case ESCKEY: + case RIGHTMOUSE: + BLI_freelinkN (&G.edbo,bone); + afbreek=1; + addbones=0; + break; + case LEFTMOUSE: + case MIDDLEMOUSE: + case SPACEKEY: + case RETKEY: + afbreek= 1; + + Mat4MulVec4fl (G.obedit->obmat,newEnd); + + curs[0]=newEnd[0]; + curs[1]=newEnd[1]; + curs[2]=newEnd[2]; + addbones++; + break; } /* End of case*/ } /* End of if (val)*/ if(afbreek) break; @@ -1739,11 +1712,52 @@ static void add_bone_input (Object *ob) }/* End of positioning loop (while)*/ } /* End of bone adding loop*/ - countall(); + countall(); // flushes selection! G.moving= 0; } +void add_primitiveArmature(int type) +{ + if(G.scene->id.lib) return; + + /* this function also comes from an info window */ + if ELEM(curarea->spacetype, SPACE_VIEW3D, SPACE_INFO); else return; + if(G.vd==NULL) return; + + G.f &= ~(G_VERTEXPAINT+G_FACESELECT+G_TEXTUREPAINT+G_WEIGHTPAINT); + setcursor_space(SPACE_VIEW3D, CURSOR_STD); + + check_editmode(OB_ARMATURE); + + /* If we're not the "obedit", make a new object and enter editmode */ + if(G.obedit==NULL) { + add_object(OB_ARMATURE); + base_init_from_view3d(BASACT, G.vd); + G.obedit= BASACT->object; + + where_is_object(G.obedit); + + make_editArmature(); + setcursor_space(SPACE_VIEW3D, CURSOR_EDIT); + } + + switch (type){ + default: + add_bone_input (G.obedit); + break; + }; + + countall(); // flushes selection! + + allqueue(REDRAWALL, 0); + BIF_undo_push("Add primitive"); +} + +/* *************** END Adding stuff in editmode *************** */ +/* *************** Tools in editmode *********** */ + +/* the "IK" button in editbuttons */ void attach_bone_to_parent_cb(void *bonev, void *arg2_unused) { EditBone *curBone= bonev; @@ -1761,10 +1775,9 @@ void attach_bone_to_parent(EditBone *bone) */ for (curbone = G.edbo.first; curbone; curbone=curbone->next){ if (curbone!=bone){ - if (curbone->parent && - (curbone->parent == bone->parent) && + if (curbone->parent && (curbone->parent == bone->parent) && (curbone->flag & BONE_IK_TOPARENT)) - curbone->flag &= ~BONE_IK_TOPARENT; + curbone->flag &= ~BONE_IK_TOPARENT; } } @@ -1773,157 +1786,122 @@ void attach_bone_to_parent(EditBone *bone) } } -void deselectall_armature(void) -/* Actually, it toggles selection, deselecting - everything if anything is selected */ +void make_bone_parent(void) { - EditBone *eBone; - int sel=1; + EditBone *ebone; + float offset[3]; + short val; + val= pupmenu("Make Parent%t|Connected%x1|Keep Offset%x2"); - /* Determine if there are any selected bones - And therefore whether we are selecting or deselecting */ - for (eBone=G.edbo.first;eBone;eBone=eBone->next){ - if (eBone->flag & (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL)){ - sel=0; - break; - }; - }; + if(val<1) return; - /* Set the flags */ - for (eBone=G.edbo.first;eBone;eBone=eBone->next){ - if (sel) - eBone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); - else - eBone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); - }; - allqueue(REDRAWVIEW3D, 0); - allqueue(REDRAWBUTSEDIT, 0); - allqueue(REDRAWBUTSOBJECT, 0); - allqueue(REDRAWOOPS, 0); - countall(); + /* find active */ + for (ebone = G.edbo.first; ebone; ebone=ebone->next) + if(ebone->flag & BONE_ACTIVE) break; + if(ebone) { + EditBone *actbone= ebone, *selbone= NULL; + + /* find selected */ + for (ebone = G.edbo.first; ebone; ebone=ebone->next) { + if(ebone->flag & BONE_SELECTED) { + if(ebone!=actbone) { + if(selbone==NULL) selbone= ebone; + else { + error("Need one active and one selected bone"); + return; + } + } + } + } + if(selbone==NULL) error("Need one active and one selected bone"); + else { + /* if selbone had a parent we clear parent tip */ + if(selbone->parent && (selbone->flag & BONE_IK_TOPARENT)) + selbone->parent->flag &= ~(BONE_TIPSEL); + + selbone->parent= actbone; + + /* in actbone tree we cannot have a loop */ + for(ebone= actbone->parent; ebone; ebone= ebone->parent) { + if(ebone->parent==selbone) { + ebone->parent= NULL; + ebone->flag &= ~BONE_IK_TOPARENT; + } + } + + if(val==1) { // connected + selbone->flag |= BONE_IK_TOPARENT; + VecSubf(offset, actbone->tail, selbone->head); + + VECCOPY(selbone->head, actbone->tail); + VecAddf(selbone->tail, selbone->tail, offset); + + // offset for all its children + for (ebone = G.edbo.first; ebone; ebone=ebone->next) { + EditBone *par; + for(par= ebone->parent; par; par= par->parent) { + if(par==selbone) { + VecAddf(ebone->head, ebone->head, offset); + VecAddf(ebone->tail, ebone->tail, offset); + break; + } + } + } + } + else { + selbone->flag &= ~BONE_IK_TOPARENT; + } + + countall(); // checks selection + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWOOPS, 0); + } + } + return; } -void join_armature(void) +void clear_bone_parent(void) { + EditBone *ebone; + short val; - Object *ob; - Base *base, *nextbase; - ListBase eblist; - EditBone *curbone, *next; - float mat[4][4], imat[4][4]; - - /* Ensure we're not in editmode and that the active object is an armature*/ - if(G.obedit) return; - - ob= OBACT; - if(ob->type!=OB_ARMATURE) return; - - /* Make sure the user wants to continue*/ - if(okee("Join selected armatures")==0) return; - - /* Put the active armature into editmode and join the bones from the other one*/ -#if 1 - enter_editmode(); -#else - baselist.first=baselist.last=0; - make_boneList(&baselist, &((bArmature*)ob->data)->bonebase, NULL); -#endif + val= pupmenu("Clear Parent%t|Clear Parent%x1|Disconnect IK%x2"); - for (base=FIRSTBASE; base; base=nextbase) { - nextbase = base->next; - if (TESTBASE(base)){ - if ((base->object->type==OB_ARMATURE) && (base->object!=ob)){ - /* Make a list of editbones */ - eblist.first=eblist.last=0; - make_boneList (&eblist, &((bArmature*)base->object->data)->bonebase,NULL); - /* Find the difference matrix */ - Mat4Invert(imat, ob->obmat); - Mat4MulMat4(mat, base->object->obmat, imat); + if(val<1) return; + for (ebone = G.edbo.first; ebone; ebone=ebone->next) { + if(ebone->flag & BONE_SELECTED) { + if(ebone->parent) { + /* for nice selection */ + ebone->parent->flag &= ~(BONE_TIPSEL); - /* Copy bones from the object to the edit armature */ - for (curbone=eblist.first; curbone; curbone=next){ - next = curbone->next; - - /* Blank out tranformation data */ - curbone->loc[0]=curbone->loc[1]=curbone->loc[2]=0.0F; - curbone->size[0]=curbone->size[1]=curbone->size[2]=1.0F; - curbone->quat[0]=curbone->quat[1]=curbone->quat[2]=curbone->quat[3]=0.0F; - - unique_editbone_name (curbone->name); - - /* Transform the bone */ - { - float premat[4][4]; - float postmat[4][4]; - float difmat[4][4]; - float imat[4][4]; - float temp[4][4]; - float delta[3]; - - /* Get the premat */ - VecSubf (delta, curbone->tail, curbone->head); - make_boneMatrixvr(temp, delta, curbone->roll); - Mat4MulMat4 (premat, temp, mat); - - Mat4MulVecfl(mat, curbone->head); - Mat4MulVecfl(mat, curbone->tail); - - /* Get the postmat */ - VecSubf (delta, curbone->tail, curbone->head); - make_boneMatrixvr(postmat, delta, curbone->roll); - - /* Find the roll */ - Mat4Invert (imat, premat); - Mat4MulMat4 (difmat, postmat, imat); - - curbone->roll -=atan(difmat[2][0]/difmat[2][2]); - - if (difmat[0][0]<0) - curbone->roll +=M_PI; - - } -#if 1 - BLI_remlink(&eblist, curbone); - BLI_addtail(&G.edbo, curbone); -#else - BLI_remlink(&eblist, curbone); - BLI_addtail(&baselist, curbone); -#endif - } + if(val==1) ebone->parent= NULL; + ebone->flag &= ~BONE_IK_TOPARENT; - free_and_unlink_base(base); } } } - -#if 1 - exit_editmode(1); -#else - editbones_to_armature(&baselist, ob); - if (baselist.first){ - BLI_freelistN (&baselist); - } -#endif + countall(); // checks selection allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSEDIT, 0); allqueue(REDRAWOOPS, 0); - } + - -static int editbone_name_exists (char *name){ +static EditBone *editbone_name_exists (char *name) +{ EditBone *eBone; for (eBone=G.edbo.first; eBone; eBone=eBone->next){ if (!strcmp (name, eBone->name)) - return 1; + return eBone; } - - return 0; - + return NULL; } -void unique_editbone_name (char *name){ +void unique_editbone_name (char *name) +{ char tempname[64]; int number; char *dot; @@ -1964,13 +1942,10 @@ void extrude_armature(void) VECCOPY (newbone->tail, newbone->head); newbone->parent = curbone; newbone->flag = BONE_TIPSEL; - newbone->flag |= BONE_QUATROT; newbone->weight= curbone->weight; newbone->dist= curbone->dist; newbone->boneclass= curbone->boneclass; - Mat4One(newbone->obmat); - /* See if there are any ik children of the parent */ for (partest = G.edbo.first; partest; partest=partest->next){ if ((partest->parent == curbone) && (partest->flag & BONE_IK_TOPARENT)) @@ -1995,10 +1970,11 @@ void extrude_armature(void) } /* Transform the endpoints */ - countall(); + countall(); // flushes selection! BIF_TransformSetUndo("Extrude"); initTransform(TFM_TRANSLATION, CTX_NO_PET); Transform(); + allqueue(REDRAWBUTSEDIT, 0); allqueue(REDRAWBUTSOBJECT, 0); allqueue(REDRAWOOPS, 0); @@ -2006,59 +1982,9 @@ void extrude_armature(void) void addvert_armature(void) { -/* - I haven't decided if it will be possible to add bones in this way. - For the moment, we'll use Extrude, or explicit parenting. - */ -} - - -static EditBone *get_named_editbone(char *name) -{ - EditBone *eBone; - - if (name) - for (eBone=G.edbo.first; eBone; eBone=eBone->next){ - if (!strcmp (name, eBone->name)) - return eBone; - } - - return NULL; + /* the ctrl-click method */ } -static void update_dup_subtarget(EditBone *dupBone) -{ - /* If an edit bone has been duplicated, lets - * update it's constraints if the subtarget - * they point to has also been duplicated - */ - EditBone *oldtarget, *newtarget; - bPoseChannel *chan; - bConstraint *curcon; - ListBase *conlist; - char *subname; - - - if ( (chan = verify_pose_channel(OBACT->pose, dupBone->name)) ) - if ( (conlist = &chan->constraints) ) - for (curcon = conlist->first; curcon; curcon=curcon->next) { - /* does this constraint have a subtarget in - * this armature? - */ - subname = get_con_subtarget_name(curcon, G.obedit); - oldtarget = get_named_editbone(subname); - if (oldtarget) - /* was the subtarget bone duplicated too? If - * so, update the constraint to point at the - * duplicate of the old subtarget. - */ - if (oldtarget->flag & BONE_SELECTED){ - newtarget = (EditBone*) oldtarget->temp; - strcpy(subname, newtarget->name); - } - } - -} void adduplicate_armature(void) { @@ -2066,7 +1992,7 @@ void adduplicate_armature(void) EditBone *curBone; EditBone *firstDup=NULL; /* The beginning of the duplicated bones in the edbo list */ - countall(); + countall(); // flushes selection! /* Find the selected bones and duplicate them as needed */ for (curBone=G.edbo.first; curBone && curBone!=firstDup; curBone=curBone->next){ @@ -2078,11 +2004,6 @@ void adduplicate_armature(void) /* Copy data from old bone to new bone */ memcpy (eBone, curBone, sizeof(EditBone)); - /* Blank out tranformation data */ - eBone->loc[0]=eBone->loc[1]=eBone->loc[2]=0.0F; - eBone->size[0]=eBone->size[1]=eBone->size[2]=1.0F; - eBone->quat[0]=eBone->quat[1]=eBone->quat[2]=eBone->quat[3]=0.0F; - curBone->temp = eBone; eBone->temp = curBone; @@ -2094,23 +2015,7 @@ void adduplicate_armature(void) /* Lets duplicate the list of constraits that the * current bone has. */ - if (OBACT->pose) { - bPoseChannel *chanold, *channew; - ListBase *listold, *listnew; - - chanold = verify_pose_channel (OBACT->pose, curBone->name); - if (chanold) { - listold = &chanold->constraints; - if (listold){ - channew = - verify_pose_channel(OBACT->pose, eBone->name); - if (channew) { - listnew = &channew->constraints; - copy_constraints (listnew, listold); - } - } - } - } + /* temporal removed (ton) */ } } @@ -2150,7 +2055,7 @@ void adduplicate_armature(void) /* Lets try to fix any constraint subtargets that might have been duplicated */ - update_dup_subtarget(eBone); + /* temporal removed (ton) */ } } @@ -2158,103 +2063,97 @@ void adduplicate_armature(void) /* Deselect the old bones and select the new ones */ for (curBone=G.edbo.first; curBone && curBone!=firstDup; curBone=curBone->next){ - curBone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); + curBone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL | BONE_ACTIVE); } BIF_TransformSetUndo("Add Duplicate"); initTransform(TFM_TRANSLATION, CTX_NO_PET); Transform(); + allqueue(REDRAWBUTSEDIT, 0); allqueue(REDRAWBUTSOBJECT, 0); allqueue(REDRAWOOPS, 0); } -/* - * - * POSING FUNCTIONS: Maybe move these to a separate file at some point - * - * - */ +/* ***************** Pose tools ********************* */ - -void clear_armature(Object *ob, char mode){ - Bone *curBone; +void clear_armature(Object *ob, char mode) +{ + bPoseChannel *pchan; bArmature *arm; arm=get_armature(ob); if (!arm) return; - - for (curBone=arm->bonebase.first; curBone; curBone=curBone->next){ - clear_armature_children (curBone, ob->pose, mode); - } - - where_is_armature (ob); - -} - -static void clear_armature_children (Bone *bone, bPose *pose, char mode){ - Bone *curBone; - bPoseChannel *chan; - if (!bone) - return; - chan = verify_pose_channel (pose, bone->name); - - if (!chan) - return; - - if (bone->flag & BONE_SELECTED){ - switch (mode){ - case 'r': - chan->quat[1]=chan->quat[2]=chan->quat[3]=0.0F; chan->quat[0]=1.0F; - break; - case 'g': - chan->loc[0]=chan->loc[1]=chan->loc[2]=0.0F; - break; - case 's': - chan->size[0]=chan->size[1]=chan->size[2]=1.0F; - break; - + for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { + if(pchan->bone && (pchan->bone->flag & BONE_SELECTED)) { + switch (mode){ + case 'r': + pchan->quat[1]=pchan->quat[2]=pchan->quat[3]=0.0F; pchan->quat[0]=1.0F; + break; + case 'g': + pchan->loc[0]=pchan->loc[1]=pchan->loc[2]=0.0F; + break; + case 's': + pchan->size[0]=pchan->size[1]=pchan->size[2]=1.0F; + break; + + } } } - for (curBone=bone->childbase.first; curBone; curBone=curBone->next){ - clear_armature_children (curBone, pose, mode); - } + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); +} +/* helper for function below */ +static int clear_active_flag(Object *ob, Bone *bone, void *data) +{ + bone->flag &= ~BONE_ACTIVE; + return 0; } -void mousepose_armature(void) /* Handles right-clicking for selection of bones in armature pose modes. -*/ + */ +void mousepose_armature(void) { - Bone *nearBone; + Bone *nearBone; - if (!G.obpose) - return; + if (!G.obpose) return; nearBone = get_nearest_bone(1); - if (nearBone){ + if (nearBone) { if (!(G.qual & LR_SHIFTKEY)){ deselectall_posearmature(0); - nearBone->flag|=BONE_SELECTED; + nearBone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL|BONE_ACTIVE); select_actionchannel_by_name(G.obpose->action, nearBone->name, 1); } else { - if (nearBone->flag & BONE_SELECTED){ - nearBone->flag &= ~BONE_SELECTED; - select_actionchannel_by_name(G.obpose->action, nearBone->name, 0); + if (nearBone->flag & BONE_SELECTED) { + /* if not active, we make it active */ + if((nearBone->flag & BONE_ACTIVE)==0) { + bArmature *arm= G.obpose->data; + bone_looper(G.obpose, arm->bonebase.first, NULL, clear_active_flag); + + nearBone->flag |= BONE_ACTIVE; + } + else { + nearBone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL|BONE_ACTIVE); + select_actionchannel_by_name(G.obpose->action, nearBone->name, 0); + } } else{ - nearBone->flag |= BONE_SELECTED; + bArmature *arm= G.obpose->data; + bone_looper(G.obpose, arm->bonebase.first, NULL, clear_active_flag); + + nearBone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL|BONE_ACTIVE); select_actionchannel_by_name(G.obpose->action, nearBone->name, 1); } - }; + } } allqueue(REDRAWVIEW3D, 0); @@ -2268,42 +2167,6 @@ void mousepose_armature(void) } -static int count_bones (bArmature *arm, int flagmask, int allbones) -{ - int count=0; - Bone *curBone; - - if (!arm) - return 0; - - for (curBone=arm->bonebase.first; curBone; curBone=curBone->next){ - count = count_bonechildren (curBone, count, flagmask, allbones); - } - - return count; - -} - -static int count_bonechildren (Bone *bone, int incount, int flagmask, int allbones){ - - Bone *curBone; - - if (!bone) - return incount; - - if (bone->flag & flagmask || flagmask == 0xFFFFFFFF){ - incount++; - if (!allbones) - return incount; - } - - for (curBone=bone->childbase.first; curBone; curBone=curBone->next){ - incount=count_bonechildren (curBone, incount, flagmask, allbones); - } - - return incount; -} - static void deselect_bonechildren (Object *ob, Bone *bone, int mode) { @@ -2313,9 +2176,9 @@ static void deselect_bonechildren (Object *ob, Bone *bone, int mode) return; if (mode==0) - bone->flag &= ~BONE_SELECTED; + bone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL|BONE_ACTIVE); else if (!(bone->flag & BONE_HIDDEN)) - bone->flag |= BONE_SELECTED; + bone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL); select_actionchannel_by_name(ob->action, bone->name, mode); @@ -2325,7 +2188,8 @@ static void deselect_bonechildren (Object *ob, Bone *bone, int mode) } -void deselectall_posearmature (int test){ +void deselectall_posearmature (int test) +{ Object *ob= OBACT; int selectmode = 0; Bone* curBone; @@ -2351,43 +2215,10 @@ void deselectall_posearmature (int test){ } -void auto_align_armature(void) -/* Sets the roll value of selected bones so that their zaxes point upwards */ -{ - EditBone *ebone; - float xaxis[3]={1.0, 0.0, 0.0}, yaxis[3], zaxis[3]={0.0, 0.0, 1.0}; - float targetmat[4][4], imat[4][4]; - float curmat[4][4], diffmat[4][4]; - float delta[3]; - - for (ebone = G.edbo.first; ebone; ebone=ebone->next){ - if (ebone->flag & BONE_SELECTED){ - /* Find the current bone matrix */ - VecSubf(delta, ebone->tail, ebone->head); - make_boneMatrixvr (curmat, delta, 0.0); - - /* Make new matrix based on y axis & z-up */ - VECCOPY (yaxis, curmat[1]); - - Mat4One(targetmat); - VECCOPY (targetmat[0], xaxis); - VECCOPY (targetmat[1], yaxis); - VECCOPY (targetmat[2], zaxis); - Mat4Ortho(targetmat); - - /* Find the difference between the two matrices */ - - Mat4Invert (imat, targetmat); - Mat4MulMat4(diffmat, curmat, imat); - - ebone->roll = atan(diffmat[2][0]/diffmat[2][2]); - - } - } -} int bone_looper(Object *ob, Bone *bone, void *data, - int (*bone_func)(Object *, Bone *, void *)) { + int (*bone_func)(Object *, Bone *, void *)) +{ /* We want to apply the function bone_func to every bone * in an armature -- feed bone_looper the first bone and @@ -2418,7 +2249,8 @@ int bone_looper(Object *ob, Bone *bone, void *data, } int ik_chain_looper(Object *ob, Bone *bone, void *data, - int (*bone_func)(Object *, Bone *, void *)) { + int (*bone_func)(Object *, Bone *, void *)) +{ /* We want to apply the function bone_func to every bone * in an ik chain -- feed ikchain_looper a bone in the chain and @@ -2491,7 +2323,8 @@ static int bone_skinnable(Object *ob, Bone *bone, void *data) return 0; } -static int add_defgroup_unique_bone(Object *ob, Bone *bone, void *data) { +static int add_defgroup_unique_bone(Object *ob, Bone *bone, void *data) +{ /* This group creates a vertex group to ob that has the * same name as bone (provided the bone is skinnable). * If such a vertex group aleady exist the routine exits. @@ -2505,7 +2338,8 @@ static int add_defgroup_unique_bone(Object *ob, Bone *bone, void *data) { return 0; } -static int dgroup_skinnable(Object *ob, Bone *bone, void *data) { +static int dgroup_skinnable(Object *ob, Bone *bone, void *data) +{ /* Bones that are not of boneclass BONE_UNSKINNABLE * are regarded to be "skinnable" and are eligible for * auto-skinning. @@ -2643,12 +2477,12 @@ static void add_verts_to_closest_dgroup(Object *ob, Object *par) /* get the root of the bone in global coords */ - get_bone_root_pos (bone, root, 0); - Mat4MulVecfl(par->obmat, root); + VECCOPY(root, bone->arm_head); + Mat4MulVecfl(par->obmat, root); /* get the tip of the bone in global coords */ - get_bone_tip_pos (bone, tip, 0); + VECCOPY(tip, bone->arm_tail); Mat4MulVecfl(par->obmat, tip); /* store the distance from the bone to @@ -2752,7 +2586,8 @@ void create_vgroups_from_armature(Object *ob, Object *par) } } -static int hide_selected_pose_bone(Object *ob, Bone *bone, void *ptr) { +static int hide_selected_pose_bone(Object *ob, Bone *bone, void *ptr) +{ if (bone->flag & BONE_SELECTED) { bone->flag |= BONE_HIDDEN; bone->flag &= ~BONE_SELECTED; @@ -2760,7 +2595,8 @@ static int hide_selected_pose_bone(Object *ob, Bone *bone, void *ptr) { return 0; } -void hide_selected_pose_bones(void) { +void hide_selected_pose_bones(void) +{ bArmature *arm; arm=get_armature (G.obpose); @@ -2774,14 +2610,16 @@ void hide_selected_pose_bones(void) { force_draw(1); } -static int hide_unselected_pose_bone(Object *ob, Bone *bone, void *ptr) { +static int hide_unselected_pose_bone(Object *ob, Bone *bone, void *ptr) +{ if (~bone->flag & BONE_SELECTED) { bone->flag |= BONE_HIDDEN; } return 0; } -void hide_unselected_pose_bones(void) { +void hide_unselected_pose_bones(void) +{ bArmature *arm; arm=get_armature (G.obpose); @@ -2795,7 +2633,8 @@ void hide_unselected_pose_bones(void) { force_draw(1); } -static int show_pose_bone(Object *ob, Bone *bone, void *ptr) { +static int show_pose_bone(Object *ob, Bone *bone, void *ptr) +{ if (bone->flag & BONE_HIDDEN) { bone->flag &= ~BONE_HIDDEN; bone->flag |= BONE_SELECTED; @@ -2804,7 +2643,8 @@ static int show_pose_bone(Object *ob, Bone *bone, void *ptr) { return 0; } -void show_all_pose_bones(void) { +void show_all_pose_bones(void) +{ bArmature *arm; arm=get_armature (G.obpose); @@ -2829,3 +2669,137 @@ int is_delay_deform(void) return (arm->flag & ARM_DELAYDEFORM); } + +/* ************* RENAMING DISASTERS ************ */ + +void unique_bone_name (bArmature *arm, char *name) +{ + char tempname[64]; + int number; + char *dot; + + if (get_named_bone(arm, name)) { + /* Strip off the suffix */ + dot=strchr(name, '.'); + if (dot) + *dot=0; + + for (number = 1; number <=999; number++){ + sprintf (tempname, "%s.%03d", name, number); + if (!get_named_bone(arm, tempname)){ + strcpy (name, tempname); + return; + } + } + } +} + +#define MAXBONENAME 32 +/* helper call for below */ +static void constraint_bone_name_fix(Object *ob, ListBase *conlist, char *oldname, char *newname) +{ + bConstraint *curcon; + char *subtarget; + + for (curcon = conlist->first; curcon; curcon=curcon->next){ + subtarget = get_con_subtarget_name(curcon, ob); + if (subtarget) + if (!strcmp(subtarget, oldname) ) + BLI_strncpy(subtarget, newname, MAXBONENAME); + } +} + +/* called by UI for renaming a bone */ +/* warning: make sure the original bone was not renamed yet! */ +/* seems messy, but thats what you get with not using pointers but channel names :) */ +void armature_bone_rename(bArmature *arm, char *oldname, char *newnamep) +{ + Object *ob; + char newname[MAXBONENAME]; + + /* we alter newname string... so make copy */ + BLI_strncpy(newname, newnamep, MAXBONENAME); + + /* now check if we're in editmode, we need to find the unique name */ + if(G.obedit && G.obedit->data==arm) { + EditBone *eBone; + + eBone= editbone_name_exists(oldname); + if(eBone) { + unique_editbone_name (newname); + BLI_strncpy(eBone->name, newname, MAXBONENAME); + } + else return; + } + else { + Bone *bone= get_named_bone (arm, oldname); + + if(bone) { + unique_bone_name (arm, newname); + BLI_strncpy(bone->name, newname, MAXBONENAME); + } + else return; + } + + /* do entire dbase */ + for(ob= G.main->object.first; ob; ob= ob->id.next) { + /* we have the object using the armature */ + if(arm==ob->data) { + Object *cob; + bAction *act; + bActionChannel *chan; + + /* Rename action channel if necessary */ + act = ob->action; + if (act && !act->id.lib){ + /* Find the appropriate channel */ + chan= get_named_actionchannel(act, oldname); + if(chan) BLI_strncpy(chan->name, newname, MAXBONENAME); + } + + /* Rename the pose channel, if it exists */ + if (ob->pose) { + bPoseChannel *pchan = get_pose_channel(ob->pose, oldname); + if (pchan) { + BLI_strncpy (pchan->name, newname, MAXBONENAME); + } + } + + /* and actually do the NLA too */ + /* (todo) */ + + /* Update any object constraints to use the new bone name */ + for(cob= G.main->object.first; cob; cob= cob->id.next) { + if(cob->constraints.first) + constraint_bone_name_fix(ob, &cob->constraints, oldname, newname); + if (cob->pose) { + bPoseChannel *pchan; + for (pchan = cob->pose->chanbase.first; pchan; pchan=pchan->next) { + constraint_bone_name_fix(ob, &pchan->constraints, oldname, newname); + } + } + } + + } + + /* See if an object is parented to this armature */ + if (ob->parent && (ob->parent->data == arm)) { + if(ob->partype==PARBONE) { + /* bone name in object */ + if (!strcmp(ob->parsubstr, oldname)) + BLI_strncpy(ob->parsubstr, newname, MAXBONENAME); + } + else if(ob->partype==PARSKEL) { + bDeformGroup *dg; + /* bone name in defgroup */ + for (dg=ob->defbase.first; dg; dg=dg->next) { + if(!strcmp(dg->name, oldname)) + BLI_strncpy(dg->name, newname, MAXBONENAME); + } + } + } + } +} + + + diff --git a/source/blender/src/editconstraint.c b/source/blender/src/editconstraint.c index c23ab26f57b..4a6ee3f7682 100644 --- a/source/blender/src/editconstraint.c +++ b/source/blender/src/editconstraint.c @@ -64,626 +64,30 @@ #include "blendef.h" #include "nla.h" -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -static short add_constraint_element (Object *owner, const char *substring, Object *parent, const char *parentstring); -static short detect_constraint_loop (Object *owner, const char* substring, int disable, char type); -static void test_bonelist_constraints (Object *owner, ListBase *list); -static void clear_object_constraint_loop_flags(Object *ob); -//static int is_child_of(struct Object *owner, struct Object *parent); -//static int is_bonechild_of(struct Bone *bone, struct Bone *parent); -static int is_child_of_ex(Object *owner, const char *ownersubstr, Object *parent, const char *parsubstr); - -ListBase g_conBase; -const char *g_conString; -Object *g_conObj; - - -static int is_child_of_ex(Object *owner, const char *ownersubstr, Object *parent, const char *parsubstr) +/* called by buttons to find a bone to display/edit values for */ +static bPoseChannel *get_active_posechannel (void) { - Object *curob; - Bone *bone = NULL; - Bone *parbone= NULL; - - curob=owner; - - /* If this is a bone */ - if (strlen(ownersubstr)) - bone = get_named_bone(get_armature(owner->parent), ownersubstr); + Object *ob= OBACT; + bPoseChannel *pchan; + bArmature *arm; - if (strlen(parsubstr)) - parbone = get_named_bone(get_armature(parent), parsubstr); - - - /* Traverse the scene graph */ - while (curob && !bone){ - switch (curob->partype){ - case PARBONE: - if (strlen(parsubstr)){ - bone = get_named_bone(get_armature(curob->parent), curob->parsubstr); - break; - } - /* The break is supposed to be missing */ - default: - if (curob==parent){ - if (parbone) - return 0; - else - return 1; - } - } - curob=curob->parent; - } - - - /* Descend into the armature scene graph */ - while (bone){ - if (bone==parbone) - return 1; - bone=bone->parent; - } - - return 0; -} -/* -static int is_child_of(Object *owner, Object *parent) -{ - Object *curpar; - - for (curpar = owner->parent; curpar; curpar=curpar->parent){ - if (curpar==parent) - return 1; - } - - return 0; -} - - -static int is_bonechild_of(Bone *bone, Bone *parent) -{ - Bone *curpar; - - if (!bone) - return 0; - - for (curpar = bone->parent; curpar; curpar=curpar->parent){ - if (curpar==parent) - return 1; - } - return 0; -} -*/ -static short add_constraint_element (Object *owner, const char *substring, Object *parent, const char *parentstring) -{ + arm = get_armature(OBACT); + if (!arm) + return NULL; - if (!owner) - return 0; - - /* See if this is the original object */ - if (parent == owner){ - if (!strcmp (parentstring, substring)) - return 1; - } - - if (owner == g_conObj){ - if (!strcmp (g_conString, substring)) - return 1; - } - - /* See if this is a child of the adding object */ - if (parent){ -// if (is_child_of (owner, parent)) - if (is_child_of_ex (owner, substring, parent, parentstring)) - return 1; - /* Parent is a bone */ -/* if ((owner==parent) && (owner->type == OB_ARMATURE)){ - if (strlen (substring) && strlen(parentstring)){ - if (is_bonechild_of(get_named_bone(owner->data, substring), get_named_bone(parent->data, parentstring))) - return 1; - } - } - */ + /* find for active */ + for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { + if(pchan->bone && (pchan->bone->flag & BONE_ACTIVE)) + return pchan; } - return 0; -} - -static void test_bonelist_constraints (Object *owner, ListBase *list) -{ - Bone *bone; - Base *base1; - - - for (bone = list->first; bone; bone=bone->next){ - for (base1 = G.scene->base.first; base1; base1=base1->next){ - clear_object_constraint_loop_flags(base1->object); - } - test_constraints(owner, bone->name, 1); - test_bonelist_constraints (owner, &bone->childbase); - } -} - - -static void clear_object_constraint_loop_flags(Object *ob) -{ - bConstraint *con; - - if (!ob) - return; - - /* Test object constraints */ - for (con = ob->constraints.first; con; con=con->next){ - con->flag &= ~CONSTRAINT_LOOPTESTED; - } - - switch (ob->type){ - case OB_ARMATURE: - if (ob->pose){ - bPoseChannel *pchan; - for (pchan = ob->pose->chanbase.first; pchan; pchan=pchan->next){ - for (con = pchan->constraints.first; con; con=con->next){ - con->flag &= ~CONSTRAINT_LOOPTESTED; - } - } - } - break; - default: - break; - } -} -void test_scene_constraints (void) -{ - Base *base, *base1; - -/* Clear the "done" flags of all constraints */ - - for (base = G.scene->base.first; base; base=base->next){ - clear_object_constraint_loop_flags(base->object); - } - - /* Test all constraints */ - for (base = G.scene->base.first; base; base=base->next){ - /* Test the object */ - - for (base1 = G.scene->base.first; base1; base1=base1->next) - clear_object_constraint_loop_flags(base1->object); - - - test_constraints (base->object, "", 1); - - /* Test the subobject constraints */ - switch (base->object->type){ - case OB_ARMATURE: - { - bArmature *arm; - arm = get_armature(base->object); - if (arm) - test_bonelist_constraints (base->object, &arm->bonebase); - } - break; - default: - break; - } - - - } + return NULL; } -int test_constraints (Object *owner, const char *substring, int disable) -{ -/* init_constraint_elements();*/ - g_conObj = owner; - g_conString = substring; - - if (detect_constraint_loop (owner, substring, disable, 0)) - return 1; - else - return 0; - -/* free_constraint_elements(); */ -} - -static short detect_constraint_loop (Object *owner, const char* substring, int disable, char typefrom) -{ - - bConstraint *curcon; - ListBase *conlist; - int type; - int result = 0; - - if (!owner) - return result; - - /* Check parents */ - /* Get the constraint list for this object */ - - if (strlen (substring)){ - switch (owner->type){ - case OB_ARMATURE: - type = TARGET_BONE; - break; - default: - type = TARGET_OBJECT; - break; - } - } - else - type = TARGET_OBJECT; - - - switch (type){ - case TARGET_OBJECT: - conlist = &owner->constraints; - /* Check parents */ -#if 0 - if (owner->parent && (ELEM (owner->partype, PAROBJECT, PARBONE))){ - if (add_constraint_element (owner->parent, "", NULL, NULL)){ - return 1; - } - /* if (detect_constraint_loop (owner->parent, "", disable)){ - return 1; - } - */ - } - /* Check tracking */ - if (owner->track && (ELEM (owner->partype, PAROBJECT, PARBONE))){ - if (add_constraint_element (owner->track, "", NULL, NULL)){ - return 1; - } - /* if (detect_constraint_loop (owner->track, "", disable)){ - return 1; - } - */ - } -#else - if (owner->parent && (owner->partype==PAROBJECT)) - if (add_constraint_element (owner->parent, "", NULL, NULL)) - return 1; - - if (owner->parent && (owner->partype==PARBONE)) - if (add_constraint_element (owner->parent, owner->parsubstr, NULL, NULL)) - return 1; - - /* Check tracking */ - if (owner->track) - if (add_constraint_element (owner->track, "", NULL, NULL)) - return 1; -#endif - - break; - case TARGET_BONE: - { - Bone *bone; - bPoseChannel *chan; - - bone = get_named_bone(((bArmature*)owner->data), substring); - chan = get_pose_channel (owner->pose, substring); - if (bone){ - conlist = &chan->constraints; - if (bone->parent){ - if (add_constraint_element (owner, bone->parent->name, NULL, NULL)) - return 1; - if (detect_constraint_loop (owner, bone->parent->name, disable, 0)) - return 1; - } - else{ - if (add_constraint_element (owner, "", NULL, NULL)) - return 1; - if (detect_constraint_loop (owner, "", disable, 0)) - return 1; - } - } - else - conlist = NULL; - } - break; - default: - conlist = NULL; - break; - } - - /* Cycle constraints */ - if (conlist){ - for (curcon = conlist->first; curcon; curcon=curcon->next){ - - /* Clear the disable flag */ - - if (curcon->flag & CONSTRAINT_LOOPTESTED){ - return 0; - } - else { - curcon->flag &= ~CONSTRAINT_DISABLE; - curcon->flag |= CONSTRAINT_LOOPTESTED; - switch (curcon->type){ - case CONSTRAINT_TYPE_ACTION: - { - bActionConstraint *data = curcon->data; - - if (!exist_object(data->tar)){ - data->tar = NULL; - break; - } - - if ( (data->tar == owner) && - (!get_named_bone(get_armature(owner), - data->subtarget))) { - curcon->flag |= CONSTRAINT_DISABLE; - result = 1; - break; - } - if (add_constraint_element (data->tar, data->subtarget, owner, substring)){ - curcon->flag |= CONSTRAINT_DISABLE; - result = 1; - break; - // return 1; - } - if (detect_constraint_loop (data->tar, data->subtarget, disable, CONSTRAINT_TYPE_ACTION)){ - curcon->flag |= CONSTRAINT_DISABLE; - result = 1; - break; - // return 1; - } - } - break; - case CONSTRAINT_TYPE_LOCLIKE: - { - bLocateLikeConstraint *data = curcon->data; - - if (!exist_object(data->tar)){ - data->tar = NULL; - break; - } - - if ( (data->tar == owner) && - (!get_named_bone(get_armature(owner), - data->subtarget))) { - curcon->flag |= CONSTRAINT_DISABLE; - result = 1; - break; - } - if (add_constraint_element (data->tar, data->subtarget, owner, substring)){ - curcon->flag |= CONSTRAINT_DISABLE; - result = 1; - break; - // return 1; - } - if (detect_constraint_loop (data->tar, data->subtarget, disable, CONSTRAINT_TYPE_LOCLIKE)){ - curcon->flag |= CONSTRAINT_DISABLE; - result = 1; - break; - // return 1; - } - } - break; - case CONSTRAINT_TYPE_ROTLIKE: - { - bRotateLikeConstraint *data = curcon->data; - - if (!exist_object(data->tar)){ - data->tar = NULL; - break; - } - - if ( (data->tar == owner) && - (!get_named_bone(get_armature(owner), - data->subtarget))) { - curcon->flag |= CONSTRAINT_DISABLE; - result = 1; - break; - } - if (add_constraint_element (data->tar, data->subtarget, owner, substring)){ - curcon->flag |= CONSTRAINT_DISABLE; - result = 1; - break; - // return 1; - } - if (detect_constraint_loop (data->tar, data->subtarget, disable, CONSTRAINT_TYPE_ROTLIKE)){ - curcon->flag |= CONSTRAINT_DISABLE; - result = 1; - break; - // return 1; - } - } - break; - case CONSTRAINT_TYPE_KINEMATIC: - { - bKinematicConstraint *data = curcon->data; - if (!exist_object(data->tar)){ - data->tar = NULL; - break; - } - - if ( (data->tar == owner) && - (!get_named_bone(get_armature(owner), - data->subtarget))) { - curcon->flag |= CONSTRAINT_DISABLE; - result = 1; - break; - } - if (add_constraint_element (data->tar, data->subtarget, owner, substring)){ - curcon->flag |= CONSTRAINT_DISABLE; - result = 1; - break; - // return 1; - } - if (detect_constraint_loop (data->tar, data->subtarget, disable, CONSTRAINT_TYPE_KINEMATIC)){ - curcon->flag |= CONSTRAINT_DISABLE; - result = 1; - break; - // return 1; - } - } - break; - case CONSTRAINT_TYPE_TRACKTO: - { - bTrackToConstraint *data = curcon->data; - if (!exist_object(data->tar)) { - data->tar = NULL; - break; - } - - if ( (data->tar == owner) && - (!get_named_bone(get_armature(owner), - data->subtarget))) { - curcon->flag |= CONSTRAINT_DISABLE; - result = 1; - break; - } - if (typefrom != CONSTRAINT_TYPE_TRACKTO && typefrom != CONSTRAINT_TYPE_LOCKTRACK){ - if (add_constraint_element (data->tar, data->subtarget, owner, substring)){ - curcon->flag |= CONSTRAINT_DISABLE; - result = 1; - break; - // return 1; - } - } - else { - curcon->flag |= CONSTRAINT_NOREFRESH; - } - - if (detect_constraint_loop (data->tar, data->subtarget, disable, CONSTRAINT_TYPE_TRACKTO)){ - curcon->flag |= CONSTRAINT_DISABLE; - result = 1; - break; - // return 1; - } - if (data->reserved2==data->reserved1){ - curcon->flag |= CONSTRAINT_DISABLE; - result = 1; - break; - // return 1; - } - if (data->reserved2+3==data->reserved1){ - curcon->flag |= CONSTRAINT_DISABLE; - result = 1; - break; - // return 1; - } - } - break; - case CONSTRAINT_TYPE_LOCKTRACK: - { - bLockTrackConstraint *data = curcon->data; - - if (!exist_object(data->tar)){ - data->tar = NULL; - break; - } - - if ( (data->tar == owner) && - (!get_named_bone(get_armature(owner), - data->subtarget))) { - curcon->flag |= CONSTRAINT_DISABLE; - result = 1; - break; - } - if (typefrom != CONSTRAINT_TYPE_TRACKTO && typefrom != CONSTRAINT_TYPE_LOCKTRACK){ - if (add_constraint_element (data->tar, data->subtarget, owner, substring)){ - curcon->flag |= CONSTRAINT_DISABLE; - result = 1; - break; - // return 1; - } - } - else { - curcon->flag |= CONSTRAINT_NOREFRESH; - } - - if (detect_constraint_loop (data->tar, data->subtarget, disable, CONSTRAINT_TYPE_LOCKTRACK)){ - curcon->flag |= CONSTRAINT_DISABLE; - result = 1; - break; - // return 1; - } - if (data->lockflag==data->trackflag){ - curcon->flag |= CONSTRAINT_DISABLE; - result = 1; - break; - // return 1; - } - if (data->lockflag+3==data->trackflag){ - curcon->flag |= CONSTRAINT_DISABLE; - result = 1; - break; - // return 1; - } - } - break; - case CONSTRAINT_TYPE_STRETCHTO: - { - bStretchToConstraint *data = curcon->data; - - if (!exist_object(data->tar)){ - data->tar = NULL; - break; - } - - if ( (data->tar == owner) && - (!get_named_bone(get_armature(owner), - data->subtarget))) { - curcon->flag |= CONSTRAINT_DISABLE; - result = 1; - break; - } - if (detect_constraint_loop (data->tar, data->subtarget, disable, CONSTRAINT_TYPE_LOCKTRACK)){ - curcon->flag |= CONSTRAINT_DISABLE; - result = 1; - break; - // return 1; - } - } - break; - case CONSTRAINT_TYPE_FOLLOWPATH: - { - bFollowPathConstraint *data = curcon->data; - - if (!exist_object(data->tar)){ - data->tar = NULL; - break; - } - if (data->tar->type != OB_CURVE){ - data->tar = NULL; - break; - } - if (add_constraint_element (data->tar, "", owner, substring)){ - curcon->flag |= CONSTRAINT_DISABLE; - result = 1; - break; - // return 1; - } - if (detect_constraint_loop (data->tar, "", disable, CONSTRAINT_TYPE_FOLLOWPATH)){ - curcon->flag |= CONSTRAINT_DISABLE; - result = 1; - break; - // return 1; - } - if (data->upflag==data->trackflag){ - curcon->flag |= CONSTRAINT_DISABLE; - result = 1; - break; - // return 1; - } - if (data->upflag+3==data->trackflag){ - curcon->flag |= CONSTRAINT_DISABLE; - result = 1; - break; - // return 1; - } - } - break; - } - } - } - } - - return result; -} ListBase *get_constraint_client_channels (int forcevalid) { - Object *ob; char ipstr[64]; @@ -698,10 +102,10 @@ ListBase *get_constraint_client_channels (int forcevalid) case OB_ARMATURE: { bActionChannel *achan; - Bone *bone; + bPoseChannel *pchan; - bone = get_first_selected_bone(); - if (!bone) break; + pchan = get_active_posechannel(); + if (!pchan) break; /* Make sure we have an action */ if (!G.obpose->action){ @@ -712,14 +116,14 @@ ListBase *get_constraint_client_channels (int forcevalid) } /* Make sure we have an actionchannel */ - achan = get_named_actionchannel(G.obpose->action, bone->name); + achan = get_named_actionchannel(G.obpose->action, pchan->name); if (!achan){ if (!forcevalid) return NULL; achan = MEM_callocN (sizeof(bActionChannel), "actionChannel"); - strcpy (achan->name, bone->name); + strcpy (achan->name, pchan->name); sprintf (ipstr, "%s.%s", G.obpose->action->id.name+2, achan->name); ipstr[23]=0; achan->ipo= add_ipo(ipstr, ID_AC); @@ -760,25 +164,20 @@ ListBase *get_constraint_client(char *name, short *clientType, void **clientdata switch (G.obpose->type){ case OB_ARMATURE: { - Bone *bone; + bPoseChannel *pchan; - bone = get_first_selected_bone(); - if (!bone) break; + pchan = get_active_posechannel(); + if (!pchan) break; - { - bPoseChannel *chan; - - /* Is the bone the client? */ - if (clientType) - *clientType = TARGET_BONE; - if (clientdata) - *clientdata = bone; - if (name) - sprintf (name, "%s>>%s", name, bone->name); - chan = verify_pose_channel(G.obpose->pose, bone->name); - list = &chan->constraints; - - } + /* Is the bone the client? */ + if (clientType) + *clientType = TARGET_BONE; + if (clientdata) + *clientdata = pchan->bone; + if (name) + sprintf (name, "%s>>%s", name, pchan->name); + + list = &pchan->constraints; } break; } @@ -906,3 +305,241 @@ char *get_con_subtarget_name(bConstraint *constraint, Object *target) return NULL; } +/* checks validity of object pointers, and NULLs, + if Bone doesnt exist it sets the CONSTRAINT_DISABLE flag */ +static void test_constraints (Object *owner, const char* substring) +{ + + bConstraint *curcon; + ListBase *conlist= NULL; + int type; + + if (owner==NULL) return; + + /* Check parents */ + /* Get the constraint list for this object */ + + if (strlen (substring)){ + switch (owner->type){ + case OB_ARMATURE: + type = TARGET_BONE; + break; + default: + type = TARGET_OBJECT; + break; + } + } + else + type = TARGET_OBJECT; + + + switch (type){ + case TARGET_OBJECT: + conlist = &owner->constraints; + break; + case TARGET_BONE: + { + Bone *bone; + bPoseChannel *chan; + + bone = get_named_bone(((bArmature*)owner->data), substring); + chan = get_pose_channel (owner->pose, substring); + if (bone && chan){ + conlist = &chan->constraints; + } + } + break; + } + + /* Cycle constraints */ + if (conlist){ + for (curcon = conlist->first; curcon; curcon=curcon->next){ + curcon->flag &= ~CONSTRAINT_DISABLE; + + switch (curcon->type){ + case CONSTRAINT_TYPE_ACTION: + { + bActionConstraint *data = curcon->data; + + if (!exist_object(data->tar)){ + data->tar = NULL; + break; + } + + if ( (data->tar == owner) && + (!get_named_bone(get_armature(owner), + data->subtarget))) { + curcon->flag |= CONSTRAINT_DISABLE; + break; + } + } + break; + case CONSTRAINT_TYPE_LOCLIKE: + { + bLocateLikeConstraint *data = curcon->data; + + if (!exist_object(data->tar)){ + data->tar = NULL; + break; + } + + if ( (data->tar == owner) && + (!get_named_bone(get_armature(owner), + data->subtarget))) { + curcon->flag |= CONSTRAINT_DISABLE; + break; + } + } + break; + case CONSTRAINT_TYPE_ROTLIKE: + { + bRotateLikeConstraint *data = curcon->data; + + if (!exist_object(data->tar)){ + data->tar = NULL; + break; + } + + if ( (data->tar == owner) && + (!get_named_bone(get_armature(owner), + data->subtarget))) { + curcon->flag |= CONSTRAINT_DISABLE; + break; + } + } + break; + case CONSTRAINT_TYPE_KINEMATIC: + { + bKinematicConstraint *data = curcon->data; + if (!exist_object(data->tar)){ + data->tar = NULL; + break; + } + + if ( (data->tar == owner) && + (!get_named_bone(get_armature(owner), + data->subtarget))) { + curcon->flag |= CONSTRAINT_DISABLE; + break; + } + } + break; + case CONSTRAINT_TYPE_TRACKTO: + { + bTrackToConstraint *data = curcon->data; + if (!exist_object(data->tar)) { + data->tar = NULL; + break; + } + + if ( (data->tar == owner) && + (!get_named_bone(get_armature(owner), + data->subtarget))) { + curcon->flag |= CONSTRAINT_DISABLE; + break; + } + if (data->reserved2==data->reserved1){ + curcon->flag |= CONSTRAINT_DISABLE; + break; + } + if (data->reserved2+3==data->reserved1){ + curcon->flag |= CONSTRAINT_DISABLE; + break; + } + } + break; + case CONSTRAINT_TYPE_LOCKTRACK: + { + bLockTrackConstraint *data = curcon->data; + + if (!exist_object(data->tar)){ + data->tar = NULL; + break; + } + + if ( (data->tar == owner) && + (!get_named_bone(get_armature(owner), + data->subtarget))) { + curcon->flag |= CONSTRAINT_DISABLE; + break; + } + + if (data->lockflag==data->trackflag){ + curcon->flag |= CONSTRAINT_DISABLE; + break; + } + if (data->lockflag+3==data->trackflag){ + curcon->flag |= CONSTRAINT_DISABLE; + break; + } + } + break; + case CONSTRAINT_TYPE_STRETCHTO: + { + bStretchToConstraint *data = curcon->data; + + if (!exist_object(data->tar)){ + data->tar = NULL; + break; + } + + if ( (data->tar == owner) && + (!get_named_bone(get_armature(owner), + data->subtarget))) { + curcon->flag |= CONSTRAINT_DISABLE; + break; + } + } + break; + case CONSTRAINT_TYPE_FOLLOWPATH: + { + bFollowPathConstraint *data = curcon->data; + + if (!exist_object(data->tar)){ + data->tar = NULL; + break; + } + if (data->tar->type != OB_CURVE){ + data->tar = NULL; + break; + } + if (data->upflag==data->trackflag){ + curcon->flag |= CONSTRAINT_DISABLE; + break; + } + if (data->upflag+3==data->trackflag){ + curcon->flag |= CONSTRAINT_DISABLE; + break; + } + } + break; + } + } + } +} + +static void test_bonelist_constraints (Object *owner, ListBase *list) +{ + Bone *bone; + + for (bone = list->first; bone; bone=bone->next) { + + test_constraints(owner, bone->name); + test_bonelist_constraints (owner, &bone->childbase); + } +} + +void object_test_constraints (Object *owner) +{ + test_constraints(owner, ""); + + if(owner->type==OB_ARMATURE) { + bArmature *arm; + arm = get_armature(owner); + if (arm) + test_bonelist_constraints (owner, &arm->bonebase); + } + +} + + diff --git a/source/blender/src/editcurve.c b/source/blender/src/editcurve.c index d07053e8987..41533e7f6f0 100644 --- a/source/blender/src/editcurve.c +++ b/source/blender/src/editcurve.c @@ -64,7 +64,7 @@ #include "BKE_utildefines.h" #include "BKE_library.h" #include "BKE_ipo.h" -#include "BKE_displist.h" +#include "BKE_depsgraph.h" #include "BKE_curve.h" #include "BKE_global.h" #include "BKE_object.h" @@ -275,7 +275,7 @@ void load_editNurb() /* when amount of vertices differs, becomes unpredictable a bit */ /* vertex -> vertex copy! */ - if(actkey) key_to_curve(actkey, cu, &cu->nurb); + if(actkey) showkeypos(cu->key, actkey); } else { freeNurblist(&(cu->nurb)); @@ -334,7 +334,6 @@ void make_editNurb() key_to_curve(actkey, cu, &editNurb); } } - makeDispList(G.obedit); } else G.obedit= NULL; @@ -425,9 +424,8 @@ void separate_nurb() editNurb= editnurbo; G.obedit= 0; /* displists behave different in edit mode */ - makeDispList(OBACT); /* this is the separated one */ - - curve_changes_other_objects(oldob); + DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA); /* this is the separated one */ + DAG_object_flush_update(G.scene, oldob, OB_RECALC_DATA); /* this is the separated one */ G.obedit= oldob; BASACT= oldbase; @@ -1028,8 +1026,7 @@ void switchdirectionNurb2(void) nu= nu->next; } - makeDispList(G.obedit); - curve_changes_other_objects(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); BIF_undo_push("Switch direction"); @@ -1220,7 +1217,7 @@ void hideNurb(int swap) nu= nu->next; } - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); countall(); allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWBUTSEDIT, 0); @@ -1265,7 +1262,7 @@ void revealNurb() nu= nu->next; } - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); countall(); allqueue(REDRAWVIEW3D, 0); BIF_undo_push("Reveal"); @@ -1690,8 +1687,7 @@ void subdivideNurb() } - makeDispList(G.obedit); - curve_changes_other_objects(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); countall(); allqueue(REDRAWVIEW3D, 0); @@ -2288,8 +2284,7 @@ void merge_nurb() countall(); lastnu= NULL; - makeDispList(G.obedit); - curve_changes_other_objects(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWBUTSEDIT, 0); @@ -2446,8 +2441,7 @@ void addsegment_nurb() lastnu= NULL; /* for selected */ - makeDispList(G.obedit); - curve_changes_other_objects(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); countall(); allqueue(REDRAWVIEW3D, 0); @@ -2653,24 +2647,6 @@ void spinNurb(float *dvec, short mode) BIF_undo_push("Spin"); } -void curve_changes_other_objects(Object *ob) -{ - Base *base= FIRSTBASE; - while(base) { - if(base->lay & G.vd->lay) { - if(base->object->parent==ob && base->object->partype==PARSKEL) - freedisplist(&base->object->disp); - - if(base->object->type==OB_CURVE) { - Curve *cu= base->object->data; - if(ob==cu->bevobj || ob==cu->taperobj) - makeDispList(base->object); - } - } - base= base->next; - } -} - void addvert_Nurb(int mode) { Nurb *nu; @@ -2793,7 +2769,7 @@ void addvert_Nurb(int mode) } test2DNurb(nu); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); countall(); allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWBUTSEDIT, 0); @@ -2807,7 +2783,6 @@ void addvert_Nurb(int mode) if(mode!='e') { /* dependencies with other objects, should become event */ - curve_changes_other_objects(G.obedit); BIF_undo_push("Add vertex"); } @@ -2836,7 +2811,7 @@ void extrude_nurb() ok= extrudeflagNurb(1); /* '1'= flag */ if(ok) { - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); countall(); BIF_TransformSetUndo("Extrude"); initTransform(TFM_TRANSLATION, CTX_NO_PET); @@ -2951,8 +2926,7 @@ void makecyclicNurb() } nu= nu->next; } - makeDispList(G.obedit); - curve_changes_other_objects(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); BIF_undo_push("Cyclic"); } @@ -3094,7 +3068,7 @@ void delNurb() else freeNurblist(&editNurb); countall(); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWBUTSEDIT, 0); BIF_undo_push("Delete"); @@ -3211,7 +3185,7 @@ void delNurb() bezt2= bezt+(nu->pntsu-1); if( (bezt2->f1 & 1) || (bezt2->f2 & 1) || (bezt2->f3 & 1) ) { nu->flagu--; - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWBUTSEDIT, 0); BIF_undo_push("Delete"); @@ -3238,7 +3212,7 @@ void delNurb() bp2= bp+(nu->pntsu-1); if( bp2->f1 & 1 ) { nu->flagu--; - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWBUTSEDIT, 0); BIF_undo_push("Delete"); @@ -3339,8 +3313,7 @@ void delNurb() } countall(); - makeDispList(G.obedit); - curve_changes_other_objects(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWBUTSEDIT, 0); @@ -3897,8 +3870,7 @@ void add_primitiveCurve(int stype) nu= addNurbprim(type, stype, newname); /* 2D */ BLI_addtail(&editNurb, nu); - makeDispList(G.obedit); - curve_changes_other_objects(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); countall(); allqueue(REDRAWALL, 0); @@ -3933,7 +3905,7 @@ void add_primitiveNurb(int type) nu= addNurbprim(4, type, newname); BLI_addtail(&editNurb,nu); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); countall(); allqueue(REDRAWALL, 0); diff --git a/source/blender/src/editfont.c b/source/blender/src/editfont.c index 347376181b8..ec627fb9f1d 100644 --- a/source/blender/src/editfont.c +++ b/source/blender/src/editfont.c @@ -58,7 +58,7 @@ #include "DNA_text_types.h" #include "DNA_view3d_types.h" -#include "BKE_displist.h" +#include "BKE_depsgraph.h" #include "BKE_font.h" #include "BKE_object.h" #include "BKE_global.h" @@ -273,8 +273,7 @@ void add_lorem(void) insert_into_textbuf(cu, '\n'); insert_into_textbuf(cu, '\n'); - text_to_curve(G.obedit, 0); - text_makedisplist(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); } @@ -292,8 +291,7 @@ void load_3dtext_fs(char *file) } fclose(fp); - text_to_curve(G.obedit, 0); - text_makedisplist(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); } @@ -452,17 +450,6 @@ void txt_export_to_objects(struct Text *text) allqueue(REDRAWVIEW3D, 0); } - -void text_makedisplist(Object *ob) -{ - Base *base; - // free displists of other users... - for(base= G.scene->base.first; base; base= base->next) { - if(base->object->data==ob->data) freedisplist(&base->object->disp); - } - makeDispList(ob); -} - static short next_word(Curve *cu) { short s; @@ -847,6 +834,7 @@ void do_textedit(unsigned short event, short val, char _ascii) } } if(doit || cursmove) { + if (cu->pos) cu->curinfo = textbufinfo[cu->pos-1]; if (G.obedit->totcol>0) { G.obedit->actcol = textbufinfo[cu->pos-1].mat_nr; @@ -855,11 +843,12 @@ void do_textedit(unsigned short event, short val, char _ascii) text_to_curve(G.obedit, cursmove); if (cursmove && (G.qual & LR_SHIFTKEY)) { cu->selend = cu->pos; - text_to_curve(G.obedit, FO_SELCHANGE); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); } if(cursmove==0) { - text_makedisplist(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); } + BIF_undo_push("Textedit"); allqueue(REDRAWVIEW3D, 0); } @@ -911,8 +900,7 @@ void paste_editText(void) doit = 1; } if(doit) { - text_to_curve(G.obedit, 0); - text_makedisplist(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); BIF_undo_push("Paste text"); } @@ -939,8 +927,7 @@ void make_editText(void) if(cu->pos>cu->len) cu->pos= cu->len; - text_to_curve(G.obedit, 0); - text_makedisplist(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); textediting= 1; BIF_undo_push("Original"); @@ -978,7 +965,7 @@ void load_editText(void) textediting= 0; - text_makedisplist(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); } @@ -994,10 +981,9 @@ void remake_editText(void) cu->len= strlen(textbuf); if(cu->pos>cu->len) cu->pos= cu->len; - text_to_curve(G.obedit, 0); - text_makedisplist(G.obedit); - + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); + BIF_undo_push("Reload"); } @@ -1076,9 +1062,7 @@ void to_upper(void) str++; } } - text_to_curve(G.obedit, 0); - text_makedisplist(G.obedit); - + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); BIF_undo_push("To upper"); } @@ -1094,10 +1078,10 @@ static void undoFont_to_editFont(void *strv) strncpy(textbuf, str+2, MAXTEXT); cu->pos= *((short *)str); cu->len= strlen(textbuf); + memcpy(textbufinfo, str+2+cu->len+1, cu->len*sizeof(CharInfo)); cu->selstart = cu->selend = 0; - text_to_curve(G.obedit, 0); - text_makedisplist(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); } diff --git a/source/blender/src/editika.c b/source/blender/src/editika.c deleted file mode 100644 index 645d1e805a4..00000000000 --- a/source/blender/src/editika.c +++ /dev/null @@ -1,429 +0,0 @@ -/** - * ------------------------------------------------------------ - * This is the old 'Ika' system of Blender (until 2.14) - * it should be removed entirely from the tree, so I'll also leave comments - * not translated... (ton) - * ------------------------------------------------------------ - * - * $Id$ - * - * ***** BEGIN GPL/BL DUAL 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. The Blender - * Foundation also sells licenses for use in proprietary software under - * the Blender License. See http://www.blender.org/BL/ for information - * about this. - * - * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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/BL DUAL LICENSE BLOCK ***** - */ - -#include <math.h> - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "MEM_guardedalloc.h" - -#include "BMF_Api.h" - -#include "BLI_blenlib.h" -#include "BLI_arithb.h" - -#include "DNA_object_types.h" -#include "DNA_screen_types.h" -#include "DNA_scene_types.h" -#include "DNA_ika_types.h" -#include "DNA_view3d_types.h" - -#include "BKE_utildefines.h" -#include "BKE_object.h" -#include "BKE_ika.h" -#include "BKE_global.h" -#include "BKE_displist.h" - -#include "BIF_gl.h" -#include "BIF_toolbox.h" -#include "BIF_mywindow.h" -#include "BIF_screen.h" -#include "BIF_space.h" -#include "BIF_editika.h" - -#include "BSE_view.h" -#include "BSE_drawview.h" - -#include "mydevice.h" -#include "blendef.h" - -static void draw_limb(Limb *li, float small) -{ - float vec[2]; - - glRotatef(( li->alpha*180.0/M_PI), 0.0, 0.0, 1.0); - - { GLUquadricObj *qobj = gluNewQuadric(); - gluQuadricDrawStyle(qobj, GLU_SILHOUETTE); - gluPartialDisk( qobj, small, small, 32, 1, 180.0, 180.0); - gluDeleteQuadric(qobj); - }; - - vec[0]= 0.0; vec[1]= small; - glBegin(GL_LINE_STRIP); - glVertex2fv(vec); - vec[0]= li->len; vec[1]= 0.0; - glVertex2fv(vec); - vec[0]= 0.0; vec[1]= -small; - glVertex2fv(vec); - glEnd(); - - small*= 0.25; - - if(li->next) circf(li->len, 0.0, small); - else circf(li->len, 0.0, small); - - glTranslatef(li->len, 0.0, 0.0); -} - -void draw_ika(Object *ob, int sel) -{ - Ika *ika; - Limb *li; - float col[4]; - float small= 0.15; - - ika= ob->data; - li= ika->limbbase.first; - if(li==0) return; - - /* we zijn al in objectspace */ - glPushMatrix(); - - glGetFloatv(GL_CURRENT_COLOR, col); - - if((ika->flag & IK_GRABEFF)==0) { - if(sel) cpack(0xFFFF); - circf(0.0, 0.0, 0.05*li->len); - - glColor3f(col[0], col[1], col[2]); - } - - while(li) { - small= 0.10*li->len; - draw_limb(li, small); - li= li->next; - } - - if(ika->flag & IK_GRABEFF) { - if(sel) { - if(ika->def) cpack(0xFFFF00); - else cpack(0xFFFF); - } - circf(0.0, 0.0, 0.25*small); - glColor3f(col[0], col[1], col[2]); - } - - glPopMatrix(); -} - -/* type 0: verts, type 1: limbs */ -void draw_ika_nrs(Object *ob, int type) -{ - Ika *ika; - Limb *li; - int nr=0; - char str[12]; - - if(curarea->spacetype!=SPACE_VIEW3D) return; - mywinset(curarea->win); - - glDrawBuffer(GL_FRONT); - myloadmatrix(G.vd->viewmat); - mymultmatrix(ob->obmat); - - ika= ob->data; - li= ika->limbbase.first; - - /* we zijn al in objectspace */ - glPushMatrix(); - cpack(0xFFFFFF); - - if(type==0) { - sprintf(str, " %d", nr++); - glRasterPos3f(0.0, 0.0, 0.0); - BMF_DrawString(G.font, str); - - while(li) { - - glRotatef(( li->alpha*180.0/M_PI), 0.0, 0.0, 1.0); - glTranslatef(li->len, 0.0, 0.0); - sprintf(str, " %d", nr++); - glRasterPos3f(0.0, 0.0, 0.0); - BMF_DrawString(G.font, str); - - li= li->next; - } - } - else { - while(li) { - - glRotatef(( li->alpha*180.0/M_PI), 0.0, 0.0, 1.0); - glTranslatef( 0.7*li->len, 0.0, 0.0); - sprintf(str, " %d", nr++); - glRasterPos3f(0.0, 0.0, 0.0); - BMF_DrawString(G.font, str); - glTranslatef( 0.3*li->len, 0.0, 0.0); - - li= li->next; - } - - } - - glDrawBuffer(GL_BACK); - glPopMatrix(); -} - - - -int extrude_ika(Object *ob, int add) -{ - Ika *ika; - Limb *li; - float dvec[3], dvecp[3], oldeul[3], mat[3][3], imat[3][3]; - int firsttime= 1; - unsigned short event = 0; - short val, afbreek=0, mval[2], xo, yo; - - /* init */ - VECCOPY(oldeul, ob->rot); - initgrabz(ob->obmat[3][0], ob->obmat[3][1], ob->obmat[3][2]); - - Mat3CpyMat4(mat, ob->obmat); - Mat3Inv(imat, mat); - - getmouseco_areawin(mval); - xo= mval[0]; - yo= mval[1]; - - /* het laatste punt van de ika */ - ika= ob->data; - - if(add) { - /* een erbij: */ - li= MEM_callocN(sizeof(Limb), "limb"); - BLI_addtail(&ika->limbbase, li); - if(li->prev) { - li->eff[0]= li->prev->eff[0]; - li->eff[1]= li->prev->eff[1]; - } - li->eff[0]+= 0.5; - } - li= ika->limbbase.last; - if(li==0) return 0; - - while(TRUE) { - - getmouseco_areawin(mval); - if(mval[0]!=xo || mval[1]!=yo || firsttime) { - firsttime= 0; - - window_to_3d(dvec, mval[0]-xo, mval[1]-yo); - VECCOPY(dvecp, dvec); - - /* apply */ - Mat3MulVecfl(imat, dvecp); - li->eff[0]+= dvecp[0]; - li->eff[1]+= dvecp[1]; - - calc_limb(li); - - if(li->prev==0) { - VECCOPY(ob->rot, oldeul); - euler_rot(ob->rot, li->alpha, 'z'); - li->alpha= li->alphao= 0.0; - } - - xo= mval[0]; - yo= mval[1]; - - force_draw(1); - } - - while(qtest()) { - event= extern_qread(&val); - if(val) { - switch(event) { - case ESCKEY: - case LEFTMOUSE: - case MIDDLEMOUSE: - case SPACEKEY: - case RETKEY: - afbreek= 1; - break; - } - } - if(afbreek) break; - } - - if(afbreek) break; - } - - if(event==ESCKEY) { - if(ika->limbbase.first!=ika->limbbase.last) { - li= ika->limbbase.last; - BLI_remlink(&ika->limbbase, li); - MEM_freeN(li); - } - } - else if(add) init_defstate_ika(ob); - - allqueue(REDRAWVIEW3D, 0); - - if(event==LEFTMOUSE) return 0; - return 1; -} - -void delete_skeleton(void) -{ - Object *ob; - Ika *ika; - - ob= OBACT; - if(ob==0 || ob->type!=OB_IKA || (ob->flag & SELECT)==0) return; - - ika= ob->data; - - if(!ika->def) return; - if(!okee("Delete Skeleton")) return; - - if(ika->def) MEM_freeN(ika->def); - ika->def= 0; - ika->totdef= 0; - - allqueue(REDRAWVIEW3D, 0); -} - -static void copy_deform(int tot, Deform *defbase, Deform *def) -{ - /* defbase is the old one, *def is new. When they match, - the deform data is copied */ - - while(tot--) { - if(defbase->ob==def->ob && defbase->par1==def->par1) { - def->fac= defbase->fac; - def->dist= defbase->dist; - return; - } - defbase++; - } -} - -void make_skeleton(void) -{ - Object *ob; - Base *base; - Ika *ika; - Deform *def, *defbase; - Limb *li; - int a, totdef=0; - - ob= OBACT; - if(ob==0 || ob->type!=OB_IKA || (ob->flag & SELECT)==0) return; - - if(!okee("Make Skeleton")) return; - - ika= ob->data; - - /* per selected ob, per limb, de obmat en imat berekenen */ - - base= FIRSTBASE; - while(base) { - if TESTBASE(base) { - if(base->object->type==OB_IKA) totdef+= count_limbs(base->object); - else totdef++; - } - base= base->next; - } - - if(totdef==0) { - error("Nothing selected"); - return; - } - - def=defbase= MEM_callocN(totdef*sizeof(Deform), "deform"); - - base= FIRSTBASE; - while(base) { - if TESTBASE(base) { - - if(base->object->type==OB_IKA) { - - li= ( (Ika *)(base->object->data) )->limbbase.first; - a= 0; - while(li) { - what_does_parent1(base->object, PARLIMB, a, 0, 0); - def->ob= base->object; - def->partype= PARLIMB; - def->par1= a; - - Mat4Invert(def->imat, workob.obmat); - def->vec[0]= li->len; - def->fac= 1.0; - - copy_deform(ika->totdef, ika->def, def); - - def++; - a++; - li= li->next; - } - } - else { - what_does_parent1(base->object, PAROBJECT, 0, 0, 0); - def->ob= base->object; - def->partype= PAROBJECT; - - def->vec[0]= 0.0; - def->fac= 1.0; - def->dist= 0.0; - - copy_deform(ika->totdef, ika->def, def); - - Mat4Invert(def->imat, workob.obmat); - def++; - } - } - base= base->next; - } - - if(ika->def) MEM_freeN(ika->def); - ika->def= defbase; - ika->totdef= totdef; - - /* Recalculate the deformation on any object - * that was parented to the old skeleton. - */ - for (base= FIRSTBASE; base; base= base->next) - if (base->object->parent==ob) - makeDispList(base->object); - - allqueue(REDRAWVIEW3D, 0); - allqueue(REDRAWBUTSEDIT, 0); -} diff --git a/source/blender/src/editipo.c b/source/blender/src/editipo.c index 228b170cc18..d2647534016 100644 --- a/source/blender/src/editipo.c +++ b/source/blender/src/editipo.c @@ -64,7 +64,6 @@ #include "DNA_camera_types.h" #include "DNA_curve_types.h" #include "DNA_group_types.h" -#include "DNA_ika_types.h" #include "DNA_ipo_types.h" #include "DNA_key_types.h" #include "DNA_lamp_types.h" @@ -80,17 +79,16 @@ #include "DNA_view3d_types.h" #include "DNA_world_types.h" -#include "BKE_utildefines.h" #include "BKE_action.h" #include "BKE_anim.h" -#include "BKE_material.h" -#include "BKE_texture.h" -#include "BKE_ipo.h" -#include "BKE_key.h" -#include "BKE_ika.h" -#include "BKE_displist.h" +#include "BKE_depsgraph.h" #include "BKE_global.h" #include "BKE_group.h" +#include "BKE_ipo.h" +#include "BKE_key.h" +#include "BKE_material.h" +#include "BKE_texture.h" +#include "BKE_utildefines.h" #include "BIF_butspace.h" #include "BIF_editkey.h" @@ -145,7 +143,7 @@ char *ob_ic_names[OB_TOTNAM] = { "LocX", "LocY", "LocZ", "dLocX", "dLocY", "dLoc "SizeX", "SizeY", "SizeZ", "dSizeX", "dSizeY", "dSizeZ", "Layer", "Time", "ColR", "ColG", "ColB", "ColA", "FStreng", "FFall", "RDamp", "Damping", "Perm" }; -char *obeff_ic_names[3] = { "EffX", "EffY", "EffZ" }; + char *co_ic_names[CO_TOTNAM] = { "Inf" }; char *mtex_ic_names[TEX_TOTNAM] = { "OfsX", "OfsY", "OfsZ", "SizeX", "SizeY", "SizeZ", "texR", "texG", "texB", "DefVar", "Col", "Nor", "Var", @@ -217,11 +215,8 @@ char *getname_co_ei(int nr) char *getname_ob_ei(int nr, int colipo) { - if(!colipo && (nr>=OB_EFF_X && nr <=OB_EFF_Z)) { - return obeff_ic_names[nr-OB_EFF_X]; - } else { - if(nr>=OB_LOC_X && nr <= OB_PD_PERM) return ob_ic_names[nr-1]; - } + if(nr>=OB_LOC_X && nr <= OB_PD_PERM) return ob_ic_names[nr-1]; + return ic_name_empty[0]; } @@ -467,7 +462,7 @@ void editipo_changed(SpaceIpo *si, int doredraw) if(si->blocktype==ID_OB) { Object *ob= (Object *)si->from; - if(ob && ob->type==OB_IKA) itterate_ika(ob); + if(ob) DAG_object_flush_update(G.scene, ob, OB_RECALC_OB); allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWNLA, 0); } @@ -489,10 +484,11 @@ void editipo_changed(SpaceIpo *si, int doredraw) } else if(si->blocktype==ID_KE) { do_spec_key((Key *)si->from); + DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); } else if(si->blocktype==ID_CU) { - calc_curvepath(OBACT); + DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); } } @@ -3871,7 +3867,6 @@ void common_insertkey() else if(ob->type==OB_LATTICE) strcat(menustr, "| %x6|Lattice%x7"); else if(ob->type==OB_CURVE) strcat(menustr, "| %x6|Curve%x7"); else if(ob->type==OB_SURF) strcat(menustr, "| %x6|Surface%x7"); - else if(ob->type==OB_IKA) strcat(menustr, "| %x6|Effector%x8"); if(ob->flag & OB_FROMGROUP) strcat(menustr, "| %x6|Entire Group%x10"); } @@ -3911,8 +3906,6 @@ void common_insertkey() act=ob->action; pose=ob->pose; - collect_pose_garbage(ob); - if (!act){ act= G.obpose->action=add_empty_action(); /* this sets the non-pinned open ipowindow(s) to show the action curve */ @@ -3931,7 +3924,7 @@ void common_insertkey() error ("Can't key libactions"); return; } - filter_pose_keys (); + set_pose_keys(ob); // sets chan->flag to POSE_KEY if bone selected for (chan=pose->chanbase.first; chan; chan=chan->next) { if (chan->flag & POSE_KEY){ @@ -3963,10 +3956,11 @@ void common_insertkey() } } } - remake_action_ipos(act); } + DAG_object_flush_update(G.scene, G.obpose, OB_RECALC_DATA); + allqueue(REDRAWIPO, 0); allqueue(REDRAWACTION, 0); allqueue(REDRAWNLA, 0); @@ -4008,15 +4002,6 @@ void common_insertkey() insertkey(id, OB_LAY); base->object->lay= tlay; } - if(event==8) { - /* a patch, can be removed (old ika) */ - Ika *ika= ob->data; - VecMat4MulVecfl(ika->effg, ob->obmat, ika->effn); - - insertkey(id, OB_EFF_X); - insertkey(id, OB_EFF_Y); - insertkey(id, OB_EFF_Z); - } } base= base->next; } @@ -4847,8 +4832,7 @@ void transform_ipo(int mode) force_draw_plus(SPACE_BUTS, 0); } else if(G.sipo->blocktype==ID_KE) { - do_ob_key(OBACT); - makeDispList(OBACT); + DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA); force_draw_plus(SPACE_VIEW3D, 0); } else if(G.sipo->blocktype==ID_AC) { @@ -4859,9 +4843,13 @@ void transform_ipo(int mode) Base *base= FIRSTBASE; while(base) { - if(base->object->ipo==G.sipo->ipo) do_ob_ipo(base->object); + if(base->object->ipo==G.sipo->ipo) { + do_ob_ipo(base->object); + base->object->recalc |= OB_RECALC_OB; + } base= base->next; } + DAG_scene_flush_update(G.scene); force_draw_plus(SPACE_VIEW3D, 0); } else force_draw(0); @@ -5020,6 +5008,7 @@ void ipo_record() EditIpo *ei, *ei1=0, *ei2=0; ScrArea *sa, *oldarea; Ipo *ipo; + Object *ob; void *poin; double swaptime; float or1, or2 = 0.0, fac, *data1, *data2; @@ -5037,7 +5026,8 @@ void ipo_record() ipo= get_ipo(G.sipo->from, G.sipo->blocktype, 1); /* 1= make */ if(G.sipo) G.sipo->ipo= ipo; - + + ob= OBACT; /* find the curves... */ ei= G.sipo->editipo; @@ -5105,7 +5095,8 @@ void ipo_record() waitcursor(1); tottime= 0.0; - swaptime= G.scene->r.framelen; + swaptime= 1.0/(float)G.scene->r.frs_sec; + cfrao= CFRA; cfra=efra= SFRA; sfra= EFRA; @@ -5122,15 +5113,14 @@ void ipo_record() /* do ipo: first all, then the specific ones */ if(anim==2) { - do_all_ipos(); - do_all_keys(); + do_ob_ipo(ob); + do_ob_key(ob); } ei1->icu->curval= or1 + fac*(mval[0]-xn); if(ei2) ei2->icu->curval= or2 + fac*(mval[1]-yn); do_ipo_nocalc(G.sipo->ipo); - do_all_visible_ikas(); if(G.qual & LR_CTRLKEY) { sprintf(str, "Recording... %d\n", cfra); @@ -5142,8 +5132,9 @@ void ipo_record() } else sprintf(str, "Mouse Recording. Use Ctrl to start. LeftMouse or Space to end"); - do_ob_key(OBACT); - + do_ob_key(ob); + ob->recalc |= OB_RECALC; + headerprint(str); if(sa) scrarea_do_windraw(sa); diff --git a/source/blender/src/editkey.c b/source/blender/src/editkey.c index 5fd73e2b3c5..e610de992df 100644 --- a/source/blender/src/editkey.c +++ b/source/blender/src/editkey.c @@ -59,16 +59,16 @@ #include "DNA_lattice_types.h" #include "DNA_scene_types.h" -#include "BKE_utildefines.h" #include "BKE_anim.h" #include "BKE_curve.h" +#include "BKE_depsgraph.h" #include "BKE_global.h" #include "BKE_ipo.h" #include "BKE_key.h" #include "BKE_library.h" #include "BKE_main.h" #include "BKE_object.h" -#include "BKE_displist.h" +#include "BKE_utildefines.h" #include "BIF_editkey.h" #include "BIF_editview.h" @@ -148,21 +148,22 @@ static BezTriple *get_bezt_icu_time(IpoCurve *icu, float *frame, float *val) { return bezt; } -static void rvk_slider_func(void *voidkey, void *voidkeynum) { +static void rvk_slider_func(void *voidkey, void *voidkeynum) +{ /* the callback for the rvk sliders ... copies the * value from the temporary array into a bezier at the * right frame on the right ipo curve (creating both the * ipo curve and the bezier if needed). */ - int *keynum = (int *) voidkeynum; - Key *key = (Key *) voidkey; - float cfra, rvkval; IpoCurve *icu=NULL; BezTriple *bezt=NULL; + Key *key = (Key *) voidkey; + float cfra, rvkval; + int *keynum = (int *) voidkeynum; cfra = frame_to_float(CFRA); - icu = get_key_icu(key, *keynum); + icu = get_key_icu(key, *keynum); if (icu) { /* if the ipocurve exists, try to get a bezier @@ -194,27 +195,12 @@ static void rvk_slider_func(void *voidkey, void *voidkeynum) { sort_time_ipocurve(icu); testhandles_ipocurve(icu); - do_all_ipos(); + key->flag &= ~KEY_LOCKED; + do_ipo(key->ipo); do_spec_key(key); - /* if I'm deformed by a lattice, update my - * displists - */ - makeDispList(OBACT); - - /* if I'm a lattice, update the displists of - * my children - */ - if (OBACT->type==OB_LATTICE ) { - Base *base; - - base= FIRSTBASE; - while(base) { - if (base->object->parent == OBACT) { - makeDispList(base->object); - } - base= base->next; - } - } + + DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA); + allqueue (REDRAWVIEW3D, 0); allqueue (REDRAWACTION, 0); allqueue (REDRAWNLA, 0); @@ -681,33 +667,31 @@ void showkeypos(Key *key, KeyBlock *kb) /* from ipo */ ob= OBACT; - if(ob==0) return; + if(ob==NULL) return; if(key == give_current_key(ob)) { + key->flag |= KEY_LOCKED; // prevents it from calculated + if(ob->type==OB_MESH) { me= ob->data; cp_key(0, me->totvert, me->totvert, (char *)me->mvert->co, me->key, kb, 0); - - make_displists_by_obdata(me); } else if(ob->type==OB_LATTICE) { lt= ob->data; tot= lt->pntsu*lt->pntsv*lt->pntsw; cp_key(0, tot, tot, (char *)lt->def->vec, lt->key, kb, 0); - - make_displists_by_parent(ob); } else if ELEM(ob->type, OB_CURVE, OB_SURF) { cu= ob->data; tot= count_curveverts(&cu->nurb); cp_cu_key(cu, kb, 0, tot); - - make_displists_by_obdata(cu); } + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + allqueue(REDRAWVIEW3D, 0); } } @@ -764,7 +748,10 @@ void delete_key(void) free_libblock_us(&(G.main->key), key); scrarea_queue_headredraw(curarea); /* ipo remove too */ } - else do_spec_key(key); + else { + key->flag &= ~KEY_LOCKED; + do_spec_key(key); + } allqueue(REDRAWVIEW3D, 0); scrarea_queue_winredraw(curarea); @@ -869,6 +856,7 @@ void move_keys(void) } sort_keys(key); + key->flag &= ~KEY_LOCKED; do_spec_key(key); /* for boundbox */ diff --git a/source/blender/src/editlattice.c b/source/blender/src/editlattice.c index 53e2b88c824..9566c0cb40a 100644 --- a/source/blender/src/editlattice.c +++ b/source/blender/src/editlattice.c @@ -52,7 +52,7 @@ #include "DNA_view3d_types.h" #include "BKE_key.h" -#include "BKE_displist.h" +#include "BKE_depsgraph.h" #include "BKE_lattice.h" #include "BKE_global.h" #include "BKE_utildefines.h" @@ -170,7 +170,7 @@ void load_editLatt(void) bp++; } - if(actkey) do_spec_key(lt->key); + if(actkey) showkeypos(lt->key, actkey); } else { @@ -300,21 +300,9 @@ void mouse_lattice(void) static void undoLatt_to_editLatt(void *defv) { - Base *base; int a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw; memcpy(editLatt->def, defv, a*sizeof(BPoint)); - - base= FIRSTBASE; - while(base) { - if(base->lay & G.vd->lay) { - if(base->object->parent==G.obedit) { - makeDispList(base->object); - } - } - base= base->next; - } - allqueue(REDRAWVIEW3D, 0); } static void *editLatt_to_undoLatt(void) diff --git a/source/blender/src/editmball.c b/source/blender/src/editmball.c index 62f4a85358b..50511a1f94f 100644 --- a/source/blender/src/editmball.c +++ b/source/blender/src/editmball.c @@ -48,7 +48,7 @@ #include "DNA_view3d_types.h" #include "BKE_utildefines.h" -#include "BKE_displist.h" +#include "BKE_depsgraph.h" #include "BKE_global.h" #include "BKE_object.h" @@ -137,8 +137,8 @@ void add_primitiveMball(int dummy_argument) base_init_from_view3d(BASACT, G.vd); G.obedit= BASACT->object; - where_is_object(G.obedit); - + where_is_object(G.obedit); // need now, for imat + make_editMball(); setcursor_space(SPACE_VIEW3D, CURSOR_EDIT); } @@ -180,37 +180,38 @@ void add_primitiveMball(int dummy_argument) ml->s= 2.0; ml->flag= SELECT | MB_SCALE_RAD; - switch(dummy_argument) { - case 1: - ml->type = MB_BALL; - ml->expx= ml->expy= ml->expz= 1.0; - break; - case 2: - ml->type = MB_TUBE; - ml->expx= ml->expy= ml->expz= 1.0; - break; - case 3: - ml->type = MB_PLANE; - ml->expx= ml->expy= ml->expz= 1.0; - break; - case 4: - ml->type = MB_ELIPSOID; - ml->expx= 1.2f; - ml->expy= 0.8f; - ml->expz= 1.0; - break; - case 5: - ml->type = MB_CUBE; - ml->expx= ml->expy= ml->expz= 1.0; - break; - default: - break; - } + switch(dummy_argument) { + case 1: + ml->type = MB_BALL; + ml->expx= ml->expy= ml->expz= 1.0; + break; + case 2: + ml->type = MB_TUBE; + ml->expx= ml->expy= ml->expz= 1.0; + break; + case 3: + ml->type = MB_PLANE; + ml->expx= ml->expy= ml->expz= 1.0; + break; + case 4: + ml->type = MB_ELIPSOID; + ml->expx= 1.2f; + ml->expy= 0.8f; + ml->expz= 1.0; + break; + case 5: + ml->type = MB_CUBE; + ml->expx= ml->expy= ml->expz= 1.0; + break; + default: + break; + } lastelem= ml; + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); // added ball can influence others + allqueue(REDRAWALL, 0); - makeDispList(G.obedit); BIF_undo_push("Add MetaElem"); } @@ -336,7 +337,8 @@ void delete_mball() ml= next; } - makeDispList(G.obedit); + DAG_scene_sort(G.scene); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWBUTSEDIT, 0); @@ -443,7 +445,7 @@ void hide_mball(char hide) ml= ml->next; } - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWBUTSEDIT, 0); @@ -462,7 +464,7 @@ void reveal_mball(void) ml= ml->next; } - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWBUTSEDIT, 0); diff --git a/source/blender/src/editmesh.c b/source/blender/src/editmesh.c index 269ad0df488..4d49f248143 100644 --- a/source/blender/src/editmesh.c +++ b/source/blender/src/editmesh.c @@ -60,17 +60,17 @@ #include "BLI_editVert.h" #include "BLI_dynstr.h" -#include "BKE_utildefines.h" -#include "BKE_key.h" -#include "BKE_object.h" -#include "BKE_displist.h" #include "BKE_DerivedMesh.h" +#include "BKE_depsgraph.h" #include "BKE_global.h" +#include "BKE_key.h" #include "BKE_library.h" #include "BKE_main.h" #include "BKE_material.h" #include "BKE_mesh.h" +#include "BKE_object.h" #include "BKE_texture.h" +#include "BKE_utildefines.h" #include "BIF_editkey.h" #include "BIF_editmesh.h" @@ -645,8 +645,6 @@ void make_editMesh() EditEdge *eed; int tot, a; - if(G.obedit==NULL) return; - /* because of reload */ free_editMesh(G.editMesh); @@ -798,8 +796,6 @@ void make_editMesh() countall(); - if (mesh_uses_displist(me)) makeDispList(G.obedit); - waitcursor(0); } @@ -1239,8 +1235,9 @@ void load_editMesh(void) } if(oldverts) MEM_freeN(oldverts); - - if(actkey) do_spec_key(me->key); + + /* forces update */ + if(actkey) showkeypos(me->key, actkey); /* to be sure: clear ->vn pointers */ eve= em->verts.first; @@ -1249,18 +1246,16 @@ void load_editMesh(void) eve= eve->next; } - /* remake softbody, clear deform or shade displists of all users */ + /* remake softbody of all users */ if(me->id.us>1) { Base *base; for(base= G.scene->base.first; base; base= base->next) { if(base->object->data==me) { base->object->softflag |= OB_SB_REDO; - freedisplist(&base->object->disp); + base->object->recalc |= OB_RECALC_DATA; } } } - /* we do make displist here for dependencies (like particles) */ - if (mesh_uses_displist(me)) makeDispList(G.obedit); /* sticky */ if(me->msticky) { @@ -1279,7 +1274,7 @@ void remake_editMesh(void) { make_editMesh(); allqueue(REDRAWVIEW3D, 0); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); BIF_undo_push("Undo all changes"); } @@ -1431,7 +1426,7 @@ void separate_mesh(void) countall(); allqueue(REDRAWVIEW3D, 0); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); } @@ -1602,7 +1597,7 @@ void separate_mesh_loose(void) waitcursor(0); countall(); allqueue(REDRAWVIEW3D, 0); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); } /* ******************************************** */ diff --git a/source/blender/src/editmesh_add.c b/source/blender/src/editmesh_add.c index 962444a29ef..f8518fc4a90 100644 --- a/source/blender/src/editmesh_add.c +++ b/source/blender/src/editmesh_add.c @@ -53,7 +53,7 @@ #include "BLI_arithb.h" #include "BLI_editVert.h" -#include "BKE_displist.h" +#include "BKE_depsgraph.h" #include "BKE_global.h" #include "BKE_library.h" #include "BKE_mesh.h" @@ -159,7 +159,7 @@ void addvert_mesh(void) BIF_undo_push("Add vertex"); allqueue(REDRAWVIEW3D, 0); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); while(get_mbut()&R_MOUSE); @@ -190,7 +190,7 @@ static void make_fgon(void) } allqueue(REDRAWVIEW3D, 0); EM_fgon_flags(); // redo flags and indices for fgons - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); BIF_undo_push("Clear FGon"); return; } @@ -273,7 +273,7 @@ static void make_fgon(void) EM_fgon_flags(); // redo flags and indices for fgons allqueue(REDRAWVIEW3D, 0); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); BIF_undo_push("Make FGon"); } } @@ -352,7 +352,7 @@ void addedgeface_mesh(void) BIF_undo_push("Add edge"); allqueue(REDRAWVIEW3D, 0); countall(); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); return; } else if(amount > 4) { @@ -423,7 +423,7 @@ void addedgeface_mesh(void) countall(); allqueue(REDRAWVIEW3D, 0); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); } @@ -850,7 +850,7 @@ void add_primitiveMesh(int type) allqueue(REDRAWINFO, 1); /* 1, because header->win==0! */ allqueue(REDRAWALL, 0); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); /* if a new object was created, it stores it in Mesh, for reload original data and undo */ if(newob) load_editMesh(); diff --git a/source/blender/src/editmesh_mods.c b/source/blender/src/editmesh_mods.c index 3e19cd0bc18..8229f55449f 100644 --- a/source/blender/src/editmesh_mods.c +++ b/source/blender/src/editmesh_mods.c @@ -63,6 +63,7 @@ editmesh_mods.c, UI level access, no geometry changes #include "BLI_rand.h" #include "BKE_displist.h" +#include "BKE_depsgraph.h" #include "BKE_DerivedMesh.h" #include "BKE_global.h" #include "BKE_mesh.h" @@ -1275,7 +1276,7 @@ void hide_mesh(int swap) } allqueue(REDRAWVIEW3D, 0); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); BIF_undo_push("Hide"); } @@ -1314,7 +1315,7 @@ void reveal_mesh(void) EM_selectmode_flush(); allqueue(REDRAWVIEW3D, 0); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); BIF_undo_push("Reveal"); } @@ -1920,7 +1921,7 @@ void righthandfaces(int select) /* makes faces righthand turning */ recalc_editnormals(); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); waitcursor(0); } @@ -2145,7 +2146,7 @@ void vertexsmooth(void) recalc_editnormals(); allqueue(REDRAWVIEW3D, 0); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); BIF_undo_push("Vertex Smooth"); } @@ -2192,7 +2193,7 @@ void vertexnoise(void) recalc_editnormals(); allqueue(REDRAWVIEW3D, 0); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); BIF_undo_push("Vertex Noise"); } @@ -2256,7 +2257,7 @@ void vertices_to_sphere(void) recalc_editnormals(); allqueue(REDRAWVIEW3D, 0); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); BIF_undo_push("To Sphere"); } diff --git a/source/blender/src/editmesh_tools.c b/source/blender/src/editmesh_tools.c index da7d86d3af8..07521a7fcfd 100644 --- a/source/blender/src/editmesh_tools.c +++ b/source/blender/src/editmesh_tools.c @@ -60,7 +60,7 @@ editmesh_tool.c: UI called tools for editmesh, geometry changes here, otherwise #include "BLI_editVert.h" #include "BLI_rand.h" -#include "BKE_displist.h" +#include "BKE_depsgraph.h" #include "BKE_global.h" #include "BKE_library.h" #include "BKE_mesh.h" @@ -616,7 +616,7 @@ void split_mesh(void) countall(); allqueue(REDRAWVIEW3D, 0); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); BIF_undo_push("Split"); } @@ -655,7 +655,7 @@ void extrude_repeat_mesh(int steps, float offs) EM_fgon_flags(); countall(); allqueue(REDRAWVIEW3D, 0); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); waitcursor(0); BIF_undo_push("Extrude Repeat"); @@ -746,7 +746,7 @@ void spin_mesh(int steps,int degr,float *dvec, int mode) countall(); recalc_editnormals(); allqueue(REDRAWVIEW3D, 0); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); if(dvec==NULL) BIF_undo_push("Spin"); } @@ -1002,7 +1002,7 @@ void delete_mesh(void) countall(); allqueue(REDRAWVIEW3D, 0); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); BIF_undo_push(str); } @@ -1094,7 +1094,7 @@ void fill_mesh(void) EM_select_flush(); countall(); allqueue(REDRAWVIEW3D, 0); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); BIF_undo_push("Fill"); } @@ -1957,7 +1957,7 @@ void subdivideflag(int flag, float rad, int beauty) countall(); allqueue(REDRAWVIEW3D, 0); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); } static int count_selected_edges(EditEdge *ed) @@ -2370,7 +2370,7 @@ void beauty_fill(void) EM_select_flush(); allqueue(REDRAWVIEW3D, 0); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); BIF_undo_push("Beauty Fill"); } @@ -2464,7 +2464,7 @@ void join_triangles(void) MEM_freeN(efaar); allqueue(REDRAWVIEW3D, 0); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); BIF_undo_push("Convert Triangles to Quads"); } @@ -2575,7 +2575,7 @@ void edge_flip(void) MEM_freeN(efaar); allqueue(REDRAWVIEW3D, 0); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); BIF_undo_push("Flip Triangle Edges"); } @@ -3029,7 +3029,7 @@ void edge_rotate_selected(int dir) EM_select_flush(); allqueue(REDRAWVIEW3D, 0); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); BIF_undo_push("Rotate Edge"); } @@ -3716,7 +3716,7 @@ static void bevel_mesh(float bsize, int allfaces) waitcursor(0); countall(); allqueue(REDRAWVIEW3D, 0); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); removedoublesflag(1, limit); diff --git a/source/blender/src/editmode_undo.c b/source/blender/src/editmode_undo.c index e2c23688736..765a2d312f7 100644 --- a/source/blender/src/editmode_undo.c +++ b/source/blender/src/editmode_undo.c @@ -48,7 +48,7 @@ #include "DNA_scene_types.h" #include "DNA_userdef_types.h" -#include "BKE_displist.h" +#include "BKE_depsgraph.h" #include "BKE_global.h" #include "BKE_object.h" @@ -243,10 +243,7 @@ void undo_editmode_step(int step) } } - makeDispList(G.obedit); - // type specific redraw events... - if(G.obedit->type==OB_CURVE) curve_changes_other_objects(G.obedit); - + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWBUTSEDIT, 0); allqueue(REDRAWIMAGE, 0); diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c index b528092aa92..ec9d65aa149 100644 --- a/source/blender/src/editobject.c +++ b/source/blender/src/editobject.c @@ -62,7 +62,6 @@ #include "DNA_constraint_types.h" #include "DNA_curve_types.h" #include "DNA_effect_types.h" -#include "DNA_ika_types.h" #include "DNA_image_types.h" #include "DNA_ipo_types.h" #include "DNA_key_types.h" @@ -88,20 +87,19 @@ #include "BLI_editVert.h" #include "BLI_ghash.h" -#include "BKE_constraint.h" #include "BKE_action.h" -#include "BKE_armature.h" -#include "BKE_utildefines.h" #include "BKE_anim.h" +#include "BKE_armature.h" +#include "BKE_constraint.h" #include "BKE_blender.h" #include "BKE_booleanops.h" #include "BKE_curve.h" #include "BKE_displist.h" +#include "BKE_depsgraph.h" #include "BKE_DerivedMesh.h" #include "BKE_effect.h" #include "BKE_font.h" #include "BKE_global.h" -#include "BKE_ika.h" #include "BKE_ipo.h" #include "BKE_key.h" #include "BKE_lattice.h" @@ -132,7 +130,6 @@ #include "BIF_editconstraint.h" #include "BIF_editdeform.h" #include "BIF_editfont.h" -#include "BIF_editika.h" #include "BIF_editlattice.h" #include "BIF_editmesh.h" #include "BIF_editoops.h" @@ -205,6 +202,8 @@ void add_object_draw(int type) /* for toolbox or menus, only non-editmode stuff deselect_all_area_oops(); set_select_flag_oops(); + + DAG_scene_sort(G.scene); allqueue(REDRAWINFO, 1); /* 1, because header->win==0! */ } @@ -226,7 +225,7 @@ void add_objectLamp(short type) allqueue(REDRAWALL, 0); } -// really bad, doesnt do constraints, that has been coded in test_scene_constraints(); +/* note: now unlinks constraints as well */ void free_and_unlink_base(Base *base) { if (base==BASACT) @@ -266,10 +265,8 @@ void delete_obj(int ok) if(islamp && G.vd->drawtype==OB_SHADED) reshadeall_displist(); - test_scene_constraints(); // do because of delete obj - - allqueue(REDRAWVIEW3D, 0); redraw_test_buttons(OBACT); + allqueue(REDRAWVIEW3D, 0); allqueue (REDRAWACTION, 0); allqueue(REDRAWIPO, 0); allqueue(REDRAWDATASELECT, 0); @@ -277,6 +274,8 @@ void delete_obj(int ok) allqueue(REDRAWACTION, 0); allqueue(REDRAWNLA, 0); + DAG_scene_sort(G.scene); + BIF_undo_push("Delete object(s)"); } @@ -655,6 +654,8 @@ void add_hook(void) allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWBUTSOBJECT, 0); + DAG_scene_sort(G.scene); + BIF_undo_push("Add hook"); } @@ -686,7 +687,8 @@ void make_track(void) data = con->data; data->tar = BASACT->object; - + base->object->recalc |= OB_RECALC; + /* Lamp and Camera track differently by default */ if (base->object->type == OB_LAMP || base->object->type == OB_CAMERA) { data->reserved1 = TRACK_nZ; @@ -699,9 +701,6 @@ void make_track(void) base= base->next; } - test_scene_constraints(); - allqueue(REDRAWVIEW3D, 0); - sort_baselist(G.scene); } else if (mode == 2){ bConstraint *con; @@ -716,7 +715,8 @@ void make_track(void) data = con->data; data->tar = BASACT->object; - + base->object->recalc |= OB_RECALC; + /* Lamp and Camera track differently by default */ if (base->object->type == OB_LAMP || base->object->type == OB_CAMERA) { data->trackflag = TRACK_nZ; @@ -729,27 +729,24 @@ void make_track(void) base= base->next; } - test_scene_constraints(); - allqueue(REDRAWVIEW3D, 0); - sort_baselist(G.scene); } else if (mode == 3){ base= FIRSTBASE; while(base) { if TESTBASELIB(base) { if(base!=BASACT) { - base->object->track= BASACT->object; + base->object->recalc |= OB_RECALC; } } base= base->next; } - - test_scene_constraints(); - allqueue(REDRAWVIEW3D, 0); - allqueue(REDRAWOOPS, 0); - sort_baselist(G.scene); } + + allqueue(REDRAWOOPS, 0); + allqueue(REDRAWVIEW3D, 0); + DAG_scene_sort(G.scene); + BIF_undo_push("Make Track"); } @@ -798,32 +795,27 @@ void clear_parent(void) base= FIRSTBASE; while(base) { if TESTBASELIB(base) { - par= 0; + par= NULL; if(mode==1 || mode==2) { - if(base->object->type==OB_IKA) { - Ika *ika= base->object->data; - ika->parent= 0; - } par= base->object->parent; - base->object->parent= 0; - + base->object->parent= NULL; + base->object->recalc |= OB_RECALC_OB; + if(mode==2) { - base->object->track= 0; + base->object->track= NULL; apply_obmat(base->object); } } else if(mode==3) { Mat4One(base->object->parentinv); - } - - if(par) { - makeDispList(base->object); // just always..., checks are not available well (ton) + base->object->recalc |= OB_RECALC_OB; } } base= base->next; } - test_scene_constraints(); + DAG_scene_sort(G.scene); + DAG_scene_flush_update(G.scene); allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWOOPS, 0); @@ -845,15 +837,17 @@ void clear_track(void) base= FIRSTBASE; while(base) { if TESTBASELIB(base) { - base->object->track= 0; - + base->object->track= NULL; + base->object->recalc |= OB_RECALC; + if(mode==2) { apply_obmat(base->object); } } base= base->next; } - test_scene_constraints(); + + DAG_scene_sort(G.scene); allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWOOPS, 0); @@ -881,10 +875,6 @@ void clear_object(char mode) switch (G.obpose->type){ case OB_ARMATURE: clear_armature (G.obpose, mode); -#if 1 - clear_pose_constraint_status(G.obpose); - make_displists_by_armature (G.obpose); -#endif break; } @@ -928,15 +918,14 @@ void clear_object(char mode) } } - if(ob->parent && ob->partype==PARSKEL) - freedisplist(&ob->disp); - else if(ob->hooks.first) - freedisplist(&ob->disp); + ob->recalc |= OB_RECALC_OB; + } base= base->next; } allqueue(REDRAWVIEW3D, 0); + DAG_scene_flush_update(G.scene); BIF_undo_push(str); } @@ -1048,7 +1037,9 @@ void make_vertex_parent(void) while(base) { if TESTBASELIB(base) { if(base!=BASACT) { + ob= base->object; + ob->recalc |= OB_RECALC; par= BASACT->object->parent; while(par) { @@ -1087,6 +1078,7 @@ void make_vertex_parent(void) } allqueue(REDRAWVIEW3D, 0); + DAG_scene_sort(G.scene); // BIF_undo_push(str); not, conflicts with editmode undo... } @@ -1097,13 +1089,6 @@ int test_parent_loop(Object *par, Object *ob) if(par==0) return 0; if(ob == par) return 1; - if(par->type==OB_IKA) { - Ika *ika= par->data; - - if( ob == ika->parent ) return 1; - if( test_parent_loop(ika->parent, ob) ) return 1; - } - return test_parent_loop(par->parent, ob); } @@ -1112,7 +1097,7 @@ void make_parent(void) { Base *base; Object *par; - short qual, mode=0, limbnr=0, effchild=0; + short qual, mode=0; char *bonestr=NULL; Bone *bone=NULL; int bonenr; @@ -1132,17 +1117,27 @@ void make_parent(void) bConstraint *con; bFollowPathConstraint *data; - mode= pupmenu("Make Parent %t|Normal Parent %x1|Follow Path %x2|Curve Deform %x3"); + mode= pupmenu("Make Parent %t|Normal Parent %x1|Follow Path %x2|Curve Deform %x3|Path Constraint %x4"); if(mode<=0){ return; } else if(mode==1) { mode= PAROBJECT; } + else if(mode==2) { + Curve *cu= par->data; + + mode= PAROBJECT; + if((cu->flag & CU_PATH)==0) { + cu->flag |= CU_PATH|CU_FOLLOW; + makeDispList(par); // force creation of path data + } + else cu->flag |= CU_FOLLOW; + } else if(mode==3) { mode= PARSKEL; } - else if(mode==2) { + else if(mode==4) { base= FIRSTBASE; while(base) { @@ -1169,9 +1164,8 @@ void make_parent(void) base= base->next; } - test_scene_constraints(); allqueue(REDRAWVIEW3D, 0); - sort_baselist(G.scene); + DAG_scene_sort(G.scene); BIF_undo_push("make Parent"); return; } @@ -1212,8 +1206,7 @@ void make_parent(void) return; } - apply_pose_armature(get_armature(par), par->pose, 0); - bone=get_indexed_bone(get_armature(par), bonenr); + bone=get_indexed_bone(par, bonenr); if (!bone){ // error ("Invalid bone!"); allqueue(REDRAWVIEW3D, 0); @@ -1241,31 +1234,13 @@ void make_parent(void) } else if(okee("Make parent")==0) return; - /* test effchild */ - base= FIRSTBASE; - while(base) { - if TESTBASELIB(base) { - if(base->object->type==OB_IKA && base->object != par) { - if(effchild==0) { - if(okee("Effector as Child")) effchild= 1; - else effchild= 2; - } - } - } - if(effchild) break; - base= base->next; - } - /* now we'll clearparentandkeeptransform all objects */ base= FIRSTBASE; while(base) { if TESTBASELIB(base) { if(base!=BASACT && base->object->parent) { - if(base->object->type==OB_IKA && effchild==1); - else { - base->object->parent= 0; - apply_obmat(base->object); - } + base->object->parent= NULL; + apply_obmat(base->object); } } base= base->next; @@ -1273,6 +1248,7 @@ void make_parent(void) } } + par->recalc |= OB_RECALC_OB; base= FIRSTBASE; while(base) { @@ -1284,13 +1260,11 @@ void make_parent(void) } else { + base->object->recalc |= OB_RECALC_OB; + /* the ifs below are horrible code (ton) */ - if(par->type==OB_IKA){ - base->object->partype= mode; - base->object->par1= limbnr; - } - else if (par->type==OB_ARMATURE){ + if (par->type==OB_ARMATURE){ base->object->partype= mode; if (bone) strcpy (base->object->parsubstr, bone->name); @@ -1308,6 +1282,7 @@ void make_parent(void) base->object->partype= PAROBJECT; } } + base->object->parent= par; /* calculate inverse parent matrix? */ @@ -1335,11 +1310,9 @@ void make_parent(void) Mat4Invert(base->object->parentinv, workob.obmat); } - if(par->type==OB_LATTICE) makeDispList(base->object); - if(par->type==OB_CURVE && mode==PARSKEL) makeDispList(base->object); if(par->type==OB_ARMATURE && mode == PARSKEL){ verify_defgroups(base->object); - makeDispList(base->object); + base->object->recalc |= OB_RECALC_DATA; } } } @@ -1349,9 +1322,9 @@ void make_parent(void) allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWOOPS, 0); - test_scene_constraints(); - sort_baselist(G.scene); - + DAG_scene_sort(G.scene); + DAG_scene_flush_update(G.scene); + BIF_undo_push("make Parent"); } @@ -1360,7 +1333,6 @@ void enter_editmode(void) { Base *base; Object *ob; - Ika *ika; ID *id; Mesh *me; int ok= 0; @@ -1406,20 +1378,6 @@ void enter_editmode(void) make_editArmature(); allqueue (REDRAWVIEW3D,0); } - else if(ob->type==OB_IKA) { /* grab type */ - base= FIRSTBASE; - while(base) { - if TESTBASE(base) { - if(base->object->type==OB_IKA) { - ika= base->object->data; - if(ika->flag & IK_GRABEFF) ika->flag &= ~IK_GRABEFF; - else ika->flag |= IK_GRABEFF; - } - } - base= base->next; - } - allqueue(REDRAWVIEW3D, 0); - } else if(ob->type==OB_FONT) { cu= ob->data; if ((cu->flag & CU_FAST)==0) { @@ -1462,27 +1420,21 @@ void enter_editmode(void) setcursor_space(SPACE_VIEW3D, CURSOR_EDIT); allqueue(REDRAWVIEW3D, 1); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); + } - else G.obedit= 0; + else G.obedit= NULL; if (G.obpose) exit_posemode (1); - scrarea_queue_headredraw(curarea); -} - -void make_displists_by_parent(Object *ob) { - Base *base; - for (base= FIRSTBASE; base; base= base->next) - if (ob==base->object->parent) - makeDispList(base->object); + scrarea_queue_headredraw(curarea); } void exit_editmode(int freedata) /* freedata==0 at render, 1= freedata, 2= do undo buffer too */ { - Base *base, *oldbase; + Base *oldbase; Object *ob; - Curve *cu; if(G.obedit==NULL) return; @@ -1495,7 +1447,7 @@ void exit_editmode(int freedata) /* freedata==0 at render, 1= freedata, 2= do un error("Too many vertices"); return; } - load_editMesh(); /* makes new displist */ + load_editMesh(); if(freedata) free_editMesh(G.editMesh); @@ -1530,7 +1482,7 @@ void exit_editmode(int freedata) /* freedata==0 at render, 1= freedata, 2= do un ob= G.obedit; - /* displist make is different in editmode */ + /* for example; displist make is different in editmode */ if(freedata) G.obedit= NULL; /* total remake of softbody data */ @@ -1543,35 +1495,11 @@ void exit_editmode(int freedata) /* freedata==0 at render, 1= freedata, 2= do un } else sbObjectToSoftbody(ob); } - makeDispList(ob); - - /* has this influence at other objects? */ - if(ob->type==OB_CURVE) { - - /* test if ob is use as bevelcurve r textoncurve */ - base= FIRSTBASE; - while(base) { - if ELEM(base->object->type, OB_CURVE, OB_FONT) { - cu= base->object->data; - - if(cu->textoncurve==ob) { - text_to_curve(base->object, 0); - makeDispList(base->object); - } - if(cu->bevobj==ob || cu->taperobj==ob) { - makeDispList(base->object); - } - } - base= base->next; - } - - } - else if(ob->type==OB_LATTICE) { - make_displists_by_parent(ob); - } + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + // evil HACK! if ((ob->type == OB_FONT) && (freedata)) { - cu= ob->data; + Curve *cu= ob->data; if ((cu->flag & CU_FAST)==0) { oldbase = BASACT; BASACT->flag &= ~SELECT; @@ -1753,13 +1681,8 @@ void docentre(int centremode) ob= ob->id.next; } } - - /* displist of all users, also this one */ - makeDispList(base->object); - /* DO: check all users... */ tex_space_mesh(me); - } else if ELEM(base->object->type, OB_CURVE, OB_SURF) { @@ -1824,10 +1747,8 @@ void docentre(int centremode) } if(G.obedit) { - makeDispList(G.obedit); break; } - else makeDispList(base->object); } else if(base->object->type==OB_FONT) { @@ -1842,18 +1763,17 @@ void docentre(int centremode) /* not really ok, do this better once! */ cu->xof /= cu->fsize; cu->yof /= cu->fsize; - - text_to_curve(base->object, 0); - makeDispList(base->object); - + allqueue(REDRAWBUTSEDIT, 0); } + base->object->recalc |= OB_RECALC_DATA; } } base= base->next; } allqueue(REDRAWVIEW3D, 0); + DAG_scene_flush_update(G.scene); BIF_undo_push("Do Centre"); } @@ -1957,7 +1877,10 @@ void special_editmenu(void) int nr,ret; short randfac; - if(G.obedit==0) { + if(G.obpose) { + pose_special_editmenu(); + } + else if(G.obedit==0) { if(G.f & G_FACESELECT) { Mesh *me= get_mesh(OBACT); TFace *tface; @@ -2124,7 +2047,7 @@ void special_editmenu(void) break; } - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); if(nr>0) waitcursor(0); @@ -2141,6 +2064,8 @@ void special_editmenu(void) switchdirectionNurb2(); break; } + + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); } countall(); @@ -2295,7 +2220,7 @@ void convertmenu(void) cu= ob->data; dl= cu->disp.first; - if(dl==0) makeDispList(ob); + if(dl==0) makeDispList(ob); // force creation nurbs_to_mesh(ob); /* also does users */ @@ -2350,8 +2275,6 @@ void convertmenu(void) basedel = NULL; } - test_scene_constraints(); // always call after delete object - countall(); allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWOOPS, 0); @@ -2375,7 +2298,7 @@ void flip_subdivison(Object *ob, int level) allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWOOPS, 0); allqueue(REDRAWBUTSEDIT, 0); - makeDispList(ob); + makeDispList(ob); // no dependency? BIF_undo_push("Switch subsurf on/off"); } @@ -2551,6 +2474,7 @@ void copy_attr(short event) while(base) { if(base != BASACT) { if(TESTBASELIB(base)) { + base->object->recalc |= OB_RECALC_OB; if(event==1) { /* loc */ VECCOPY(base->object->loc, ob->loc); @@ -2569,7 +2493,7 @@ void copy_attr(short event) else if(event==4) { /* drawtype */ base->object->dt= ob->dt; base->object->dtx= ob->dtx; - } + } else if(event==5) { /* time offs */ base->object->sf= ob->sf; } @@ -2630,11 +2554,13 @@ void copy_attr(short event) if(cu1->vfontbi) cu1->vfontbi->id.us--; cu1->vfontbi= cu->vfontbi; id_us_plus((ID *)cu1->vfontbi); - text_to_curve(base->object, 0); + + text_to_curve(base->object, 0); // needed? + strcpy(cu1->family, cu->family); - makeDispList(base->object); + base->object->recalc |= OB_RECALC_DATA; } } else if(event==19) { /* bevel settings */ @@ -2650,7 +2576,7 @@ void copy_attr(short event) cu1->ext1= cu->ext1; cu1->ext2= cu->ext2; - makeDispList(base->object); + base->object->recalc |= OB_RECALC_DATA; } } else if(event==20) { /* particle settings */ @@ -2688,7 +2614,7 @@ void copy_attr(short event) targetme->subsurftype = sourceme->subsurftype; targetme->subdiv= sourceme->subdiv; targetme->subdivr= sourceme->subdivr; - makeDispList(base->object); + base->object->recalc |= OB_RECALC_DATA; } } else if(event==22) { @@ -2717,6 +2643,8 @@ void copy_attr(short event) } allqueue(REDRAWVIEW3D, 0); + DAG_scene_flush_update(G.scene); + if(event==20) { allqueue(REDRAWBUTSOBJECT, 0); } @@ -3474,9 +3402,7 @@ void single_obdata_users(int flag) Object *ob; Lamp *la; Curve *cu; - Ika *ika; Camera *cam; - Deform *def; Base *base; Mesh *me; ID *id; @@ -3516,7 +3442,6 @@ void single_obdata_users(int flag) ob->data= cu= copy_curve(ob->data); ID_NEW(cu->bevobj); ID_NEW(cu->taperobj); - makeDispList(ob); break; case OB_LATTICE: ob->data= copy_lattice(ob->data); @@ -3524,21 +3449,6 @@ void single_obdata_users(int flag) case OB_ARMATURE: ob->data=copy_armature(ob->data); break; - case OB_IKA: - /* this never occurs? IK is always single user */ - ob->data= ika= copy_ika(ob->data); - ID_NEW(ika->parent); - - if(ika->totdef) { - a= ika->totdef; - def= ika->def; - while(a--) { - ID_NEW(def->ob); - def++; - } - } - - break; default: printf("ERROR single_obdata_users: %s\n", id->name); error("Read console"); @@ -3997,6 +3907,7 @@ void adduplicate(int noTrans) ob= base->object; obn= copy_object(ob); + obn->recalc |= OB_RECALC_OB; basen= MEM_mallocN(sizeof(Base), "duplibase"); *basen= *base; @@ -4067,7 +3978,6 @@ void adduplicate(int noTrans) ID_NEW_US2(obn->data ) else { obn->data= copy_curve(obn->data); - makeDispList(ob); didit= 1; } id->us--; @@ -4078,7 +3988,6 @@ void adduplicate(int noTrans) ID_NEW_US2( obn->data ) else { obn->data= copy_curve(obn->data); - makeDispList(ob); didit= 1; } id->us--; @@ -4089,7 +3998,6 @@ void adduplicate(int noTrans) ID_NEW_US2( obn->data ) else { obn->data= copy_curve(obn->data); - makeDispList(ob); didit= 1; } id->us--; @@ -4135,11 +4043,6 @@ void adduplicate(int noTrans) else obn->data= copy_camera(obn->data); id->us--; break; - case OB_IKA: - ID_NEW_US2(obn->data ) - else obn->data= copy_ika(obn->data); - id->us--; - break; } if(dupflag & USER_DUP_MAT) { @@ -4218,7 +4121,8 @@ void adduplicate(int noTrans) } } - sort_baselist(G.scene); + DAG_scene_sort(G.scene); + DAG_scene_flush_update(G.scene); set_sca_new_poins(); clear_id_newpoins(); @@ -4587,40 +4491,9 @@ void texspace_edit(void) } } -void first_base(void) -{ - /* inserts selected Bases in beginning of list, sometimes useful for operation order */ - Base *base, *next; - - if(okee("Make first base")==0) return; - - base= FIRSTBASE; - while(base) { - next= base->next; - - if(base->flag & SELECT) { - BLI_remlink(&G.scene->base, base); - BLI_addtail(&G.scene->base, base); - } - - base= next; - } - -} - -void make_displists_by_obdata(void *obdata) { - Base *base; - - for (base= FIRSTBASE; base; base= base->next) - if (obdata==base->object->data) - makeDispList(base->object); -} - /* ******************************************************************** */ /* Mirror function in Edit Mode */ - - void mirrormenu(void) { short mode = 0; diff --git a/source/blender/src/editview.c b/source/blender/src/editview.c index 22d738fbafd..c3f9f5e3243 100644 --- a/source/blender/src/editview.c +++ b/source/blender/src/editview.c @@ -1249,14 +1249,14 @@ void borderselect(void) index = buffer[(4*a)+3]; if (val==LEFTMOUSE){ if (index != -1){ - bone = get_indexed_bone(G.obpose->data, index &~(BONESEL_TIP|BONESEL_ROOT)); + bone = get_indexed_bone(G.obpose, index &~(BONESEL_TIP|BONESEL_ROOT)); bone->flag |= BONE_SELECTED; select_actionchannel_by_name(G.obpose->action, bone->name, 1); } } else{ if (index != -1){ - bone = get_indexed_bone(G.obpose->data, index &~(BONESEL_TIP|BONESEL_ROOT)); + bone = get_indexed_bone(G.obpose, index &~(BONESEL_TIP|BONESEL_ROOT)); bone->flag &= ~BONE_SELECTED; select_actionchannel_by_name(G.obpose->action, bone->name, 0); } @@ -1438,20 +1438,20 @@ void borderselect(void) for (a=0; a<hits; a++){ index = buffer[(4*a)+3]; if (val==LEFTMOUSE){ - if (index!=-1){ - ebone = BLI_findlink(&G.edbo, index & ~(BONESEL_TIP|BONESEL_ROOT)); - if (index & BONESEL_TIP) + if (index!=-1) { + ebone = BLI_findlink(&G.edbo, index & ~(BONESEL_ANY)); + if (index & (BONESEL_TIP|BONESEL_BONE)) ebone->flag |= BONE_TIPSEL; - if (index & BONESEL_ROOT) + if (index & (BONESEL_ROOT|BONESEL_BONE)) ebone->flag |= BONE_ROOTSEL; } } else{ if (index!=-1){ - ebone = BLI_findlink(&G.edbo, index & ~(BONESEL_TIP|BONESEL_ROOT)); - if (index & BONESEL_TIP) + ebone = BLI_findlink(&G.edbo, index & ~(BONESEL_ANY)); + if (index & (BONESEL_TIP|BONESEL_BONE)) ebone->flag &= ~BONE_TIPSEL; - if (index & BONESEL_ROOT) + if (index & (BONESEL_ROOT|BONESEL_BONE)) ebone->flag &= ~BONE_ROOTSEL; } } diff --git a/source/blender/src/filesel.c b/source/blender/src/filesel.c index 929b8a93228..b2a2360b9e5 100644 --- a/source/blender/src/filesel.c +++ b/source/blender/src/filesel.c @@ -78,7 +78,6 @@ #include "BKE_utildefines.h" #include "BKE_global.h" #include "BKE_main.h" -#include "BKE_displist.h" #include "BKE_library.h" #include "BKE_curve.h" #include "BKE_font.h" @@ -2202,24 +2201,14 @@ static void do_library_append(SpaceFile *sfile) BLO_library_append(sfile, dir, idcode); - /* DISPLISTS */ + /* DISPLISTS? */ ob= G.main->object.first; - set_displist_onlyzero(1); while(ob) { if(ob->id.lib) { - if(ob->type==OB_FONT) { - Curve *cu= ob->data; - if(cu->nurb.first==0) text_to_curve(ob, 0); - } - makeDispList(ob); - } - else if(ob->type==OB_MESH && ob->parent && ob->parent->type==OB_LATTICE ) { - makeDispList(ob); + ob->recalc |= OB_RECALC; } - ob= ob->id.next; } - set_displist_onlyzero(0); /* in sfile->dir is the whole lib name */ strcpy(G.lib, sfile->dir); @@ -2394,7 +2383,7 @@ void main_to_filelist(SpaceFile *sfile) if( sfile->dir[0]==0) { /* make directories */ - sfile->totfile= 22; + sfile->totfile= 21; sfile->filelist= (struct direntry *)malloc(sfile->totfile * sizeof(struct direntry)); for(a=0; a<sfile->totfile; a++) { @@ -2412,18 +2401,17 @@ void main_to_filelist(SpaceFile *sfile) sfile->filelist[7].relname= BLI_strdup("Material"); sfile->filelist[8].relname= BLI_strdup("Texture"); sfile->filelist[9].relname= BLI_strdup("Image"); - sfile->filelist[10].relname= BLI_strdup("Ika"); - sfile->filelist[11].relname= BLI_strdup("Wave"); - sfile->filelist[12].relname= BLI_strdup("Lattice"); - sfile->filelist[13].relname= BLI_strdup("Lamp"); - sfile->filelist[14].relname= BLI_strdup("Camera"); - sfile->filelist[15].relname= BLI_strdup("Ipo"); - sfile->filelist[16].relname= BLI_strdup("World"); - sfile->filelist[17].relname= BLI_strdup("Screen"); - sfile->filelist[18].relname= BLI_strdup("VFont"); - sfile->filelist[19].relname= BLI_strdup("Text"); - sfile->filelist[20].relname= BLI_strdup("Armature"); - sfile->filelist[21].relname= BLI_strdup("Action"); + sfile->filelist[10].relname= BLI_strdup("Wave"); + sfile->filelist[11].relname= BLI_strdup("Lattice"); + sfile->filelist[12].relname= BLI_strdup("Lamp"); + sfile->filelist[13].relname= BLI_strdup("Camera"); + sfile->filelist[14].relname= BLI_strdup("Ipo"); + sfile->filelist[15].relname= BLI_strdup("World"); + sfile->filelist[16].relname= BLI_strdup("Screen"); + sfile->filelist[17].relname= BLI_strdup("VFont"); + sfile->filelist[18].relname= BLI_strdup("Text"); + sfile->filelist[19].relname= BLI_strdup("Armature"); + sfile->filelist[20].relname= BLI_strdup("Action"); qsort(sfile->filelist, sfile->totfile, sizeof(struct direntry), compare_name); } else { diff --git a/source/blender/src/header_action.c b/source/blender/src/header_action.c index b0e2f2a70d6..b918cb9f60b 100644 --- a/source/blender/src/header_action.c +++ b/source/blender/src/header_action.c @@ -43,15 +43,15 @@ #include <config.h> #endif -#include "DNA_ID.h" #include "DNA_action_types.h" +#include "DNA_curve_types.h" +#include "DNA_ID.h" #include "DNA_ipo_types.h" +#include "DNA_key_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "DNA_space_types.h" -#include "DNA_key_types.h" -#include "DNA_curve_types.h" #include "BIF_interface.h" #include "BIF_resources.h" @@ -60,10 +60,11 @@ #include "BIF_editaction.h" #include "BKE_action.h" +#include "BKE_armature.h" +#include "BKE_constraint.h" +#include "BKE_depsgraph.h" #include "BKE_global.h" #include "BKE_main.h" -#include "BKE_constraint.h" -#include "BKE_armature.h" #include "BKE_utildefines.h" #include "BSE_drawipo.h" @@ -104,10 +105,11 @@ void do_action_buttons(unsigned short event) { + Object *ob= OBACT; switch(event){ case B_ACTBAKE: - bake_action_with_client (G.saction->action, OBACT, 0.01); + bake_action_with_client (G.saction->action, ob, 0.01); break; case B_ACTCONT: set_exprap_action(IPO_HORIZ); @@ -159,14 +161,12 @@ void do_action_buttons(unsigned short event) break; case B_ACTPASTE: paste_posebuf(0); - clear_object_constraint_status(OBACT); - make_displists_by_armature(OBACT); + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 1); break; case B_ACTPASTEFLIP: paste_posebuf(1); - clear_object_constraint_status(OBACT); - make_displists_by_armature(OBACT); + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 1); break; diff --git a/source/blender/src/header_info.c b/source/blender/src/header_info.c index ac55a630a71..d2c41417f88 100644 --- a/source/blender/src/header_info.c +++ b/source/blender/src/header_info.c @@ -306,10 +306,9 @@ Scene *copy_scene(Scene *sce, int level) id_us_plus((ID *)scen->world); id_us_plus((ID *)scen->set); - scen->ed= 0; - scen->radio= 0; + scen->ed= NULL; + scen->radio= NULL; scen->theDag= NULL; - scen->dagisvalid= 0; obase= sce->base.first; base= scen->base.first; @@ -1787,11 +1786,19 @@ static void info_text(int x, int y) sprintf(infostr,"Fa:%d-%d | Mem:%.2fM ", G.totfacesel, G.totface, (mem_in_use>>10)/1024.0); } + else if(G.obedit->type==OB_ARMATURE) { + sprintf(infostr,"Ve:%d-%d | Bo:%d-%d | Mem:%.2fM ", + G.totvertsel, G.totvert, G.totbonesel, G.totbone, (mem_in_use>>10)/1024.0); + } else { sprintf(infostr,"Ve:%d-%d | Mem:%.2fM ", G.totvertsel, G.totvert, (mem_in_use>>10)/1024.0); } } + else if(G.obpose) { + sprintf(infostr,"Bo:%d-%d | Mem:%.2fM ", + G.totbonesel, G.totbone, (mem_in_use>>10)/1024.0); + } else { sprintf(infostr,"Ve:%d | Fa:%d | Ob:%d-%d | La:%d | Mem:%.2fM | Time:%s | ", G.totvert, G.totface, G.totobj, G.totobjsel, G.totlamp, (mem_in_use>>10)/1024.0, info_time_str); diff --git a/source/blender/src/header_view3d.c b/source/blender/src/header_view3d.c index d5a0636bf3e..18dfa9e6d13 100644 --- a/source/blender/src/header_view3d.c +++ b/source/blender/src/header_view3d.c @@ -60,6 +60,7 @@ #include "BKE_library.h" #include "BKE_curve.h" +#include "BKE_depsgraph.h" #include "BKE_displist.h" #include "BKE_effect.h" #include "BKE_global.h" @@ -2189,7 +2190,7 @@ static void do_view3d_edit_mesh_facesmenu(void *arg, int event) convert_to_triface(0); allqueue(REDRAWVIEW3D, 0); countall(); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); break; case 3: /* Tris to Quads */ join_triangles(); @@ -2498,15 +2499,15 @@ static void do_view3d_edit_curve_controlpointsmenu(void *arg, int event) break; case 2: /* Free */ sethandlesNurb(3); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); break; case 3: /* vector */ sethandlesNurb(2); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); break; case 4: /* smooth */ sethandlesNurb(1); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); break; case 5: /* make vertex parent */ make_parent(); @@ -2640,7 +2641,7 @@ static void do_view3d_edit_curvemenu(void *arg, int event) break; case 7: /* toggle cyclic */ makecyclicNurb(); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); break; case 8: /* delete */ delete_context_selected(); @@ -3977,6 +3978,9 @@ void do_view3d_buttons(short event) scrarea_queue_winredraw(curarea); countall(); + + /* new layers might need unflushed events events */ + DAG_scene_update_flags(G.scene, G.vd->lay); // tags all that moves and flushes allqueue(REDRAWOOPS, 0); } diff --git a/source/blender/src/headerbuttons.c b/source/blender/src/headerbuttons.c index 095e40b1f15..242b544fd73 100644 --- a/source/blender/src/headerbuttons.c +++ b/source/blender/src/headerbuttons.c @@ -92,11 +92,10 @@ #include "BKE_armature.h" #include "BKE_blender.h" #include "BKE_curve.h" -#include "BKE_displist.h" +#include "BKE_depsgraph.h" #include "BKE_exotic.h" #include "BKE_global.h" #include "BKE_image.h" -#include "BKE_ika.h" #include "BKE_ipo.h" #include "BKE_key.h" #include "BKE_lattice.h" @@ -489,42 +488,19 @@ int std_libbuttons(uiBlock *block, short xco, short yco, } - +/* results in fully updated anim system */ static void do_update_for_newframe(int mute, int events) { extern void audiostream_scrub(unsigned int frame); /* seqaudio.c */ ScrArea *sa; if(events) { - allqueue(REDRAWVIEW3D, 0); - allqueue(REDRAWACTION,0); - allqueue(REDRAWNLA,0); - allqueue(REDRAWIPO, 0); - allqueue(REDRAWINFO, 1); - allqueue(REDRAWSEQ, 1); - allqueue(REDRAWSOUND, 1); - allqueue(REDRAWTIME, 1); - allqueue(REDRAWBUTSHEAD, 0); - allqueue(REDRAWBUTSSHADING, 0); - allqueue(REDRAWBUTSOBJECT, 0); + allqueue(REDRAWALL, 0); } - /* layers/materials, object ipos are calculted in where_is_object (too) */ - do_all_ipos(); - if (G.f & G_DOSCRIPTLINKS) BPY_do_all_scripts(SCRIPT_FRAMECHANGED); - clear_all_constraints(); - do_all_keys(); - - do_all_actions(NULL); - rebuild_all_armature_displists(); - /* so nice, better do it twice */ - do_all_actions(NULL); - rebuild_all_armature_displists(); - - do_all_ikas(); - - test_all_displists(); - + /* this one applies changes */ + scene_update_for_newframe(G.scene, G.vd->lay); /* BKE_scene.h */ + /* manipulators like updates too */ for(sa=G.curscreen->areabase.first; sa; sa=sa->next) { if(sa->spacetype==SPACE_VIEW3D) { @@ -728,12 +704,11 @@ void do_global_buttons(unsigned short event) if( GS(idtest->name)==ID_CU ) { test_curve_type(ob); - allqueue(REDRAWBUTSEDIT, 0); - makeDispList(ob); } - else if( ob->type==OB_MESH ) { - makeDispList(ob); + else if( ob->type==OB_ARMATURE) { + armature_rebuild_pose(ob, ob->data); } + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); allqueue(REDRAWBUTSEDIT, 0); allqueue(REDRAWVIEW3D, 0); @@ -1637,8 +1612,8 @@ void do_global_buttons(unsigned short event) * can require it to be updated because its * basis might have changed... -zr */ - if (OBACT && OBACT->type==OB_MBALL) - makeDispList(OBACT); + if (ob && ob->type==OB_MBALL) + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); /* redraw because name has changed: new pup */ scrarea_queue_headredraw(curarea); @@ -1901,7 +1876,7 @@ void do_global_buttons2(short event) if(okee("Single user")) { ob->data= copy_curve(cu); cu->id.us--; - makeDispList(ob); + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); if(ob==G.obedit) allqueue(REDRAWVIEW3D, 0); } } @@ -1914,7 +1889,7 @@ void do_global_buttons2(short event) if(okee("Make local")) { make_local_curve(cu); make_local_key( cu->key ); - makeDispList(ob); + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); } } } diff --git a/source/blender/src/interface.c b/source/blender/src/interface.c index fd29a9dbedc..5c4843e8664 100644 --- a/source/blender/src/interface.c +++ b/source/blender/src/interface.c @@ -1564,8 +1564,13 @@ static int ui_do_but_TEX(uiBut *but) but->pos= -1; but->flag &= ~UI_SELECT; - uibut_do_func(but); - + if(dev!=ESCKEY) { + /* give butfunc the original text too */ + /* feature used for bone renaming, channels, etc */ + if(but->func_arg2==NULL) but->func_arg2= backstr; + uibut_do_func(but); + } + ui_check_but(but); ui_draw_but(but); diff --git a/source/blender/src/meshtools.c b/source/blender/src/meshtools.c index 7bd0c785b22..99bce8531d7 100644 --- a/source/blender/src/meshtools.c +++ b/source/blender/src/meshtools.c @@ -65,7 +65,7 @@ void sort_faces(void); #include "BLI_blenlib.h" #include "BLI_arithb.h" -#include "BKE_displist.h" +#include "BKE_depsgraph.h" #include "BKE_global.h" #include "BKE_library.h" #include "BKE_main.h" @@ -437,11 +437,10 @@ void join_mesh(void) enter_editmode(); exit_editmode(1); // freedata, but no undo - test_scene_constraints(); // always call after delete object (stupid!) - allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWBUTSSHADING, 0); - makeDispList(ob); + DAG_scene_sort(G.scene); + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); BIF_undo_push("Join Mesh"); } @@ -817,7 +816,7 @@ void sort_faces(void) MEM_freeN(index); allqueue(REDRAWVIEW3D, 0); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); } diff --git a/source/blender/src/outliner.c b/source/blender/src/outliner.c index 1baff512174..0264921af90 100644 --- a/source/blender/src/outliner.c +++ b/source/blender/src/outliner.c @@ -59,6 +59,8 @@ #include "BLI_blenlib.h" +#include "BKE_constraint.h" +#include "BKE_depsgraph.h" #include "BKE_global.h" #include "BKE_library.h" #include "BKE_main.h" @@ -405,7 +407,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i int a= 0; tenla->name= "Scripts"; for (a=0; a<sce->scriptlink.totscript; a++) { - outliner_add_element(soops, &tenla->subtree, sce->scriptlink.scripts[a], te, 0, 0); + outliner_add_element(soops, &tenla->subtree, sce->scriptlink.scripts[a], tenla, 0, 0); } } } @@ -422,20 +424,79 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i outliner_add_element(soops, &te->subtree, ob->mat[a], te, 0, a); if(ob->constraints.first) { + Object *target; bConstraint *con; TreeElement *ten; TreeElement *tenla= outliner_add_element(soops, &te->subtree, ob, te, TSE_CONSTRAINT_BASE, 0); int a= 0; + char *str; tenla->name= "Constraints"; for(con= ob->constraints.first; con; con= con->next, a++) { ten= outliner_add_element(soops, &tenla->subtree, ob, tenla, TSE_CONSTRAINT, a); - ten->name= con->name; + target= get_constraint_target(con, &str); + if(str && str[0]) ten->name= str; + else if(target) ten->name= target->id.name+2; + else ten->name= con->name; ten->directdata= con; - outliner_add_element(soops, &ten->subtree, con->ipo, ten, 0, 0); /* possible add all other types links? */ } } + if(ob->pose && ob!=G.obedit) { + bPoseChannel *pchan; + TreeElement *ten; + TreeElement *tenla= outliner_add_element(soops, &te->subtree, ob, te, TSE_POSE_BASE, 0); + int a= 0; + + tenla->name= "Pose"; + for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next, a++) { + ten= outliner_add_element(soops, &tenla->subtree, ob, tenla, TSE_POSE_CHANNEL, a); + ten->name= pchan->name; + ten->directdata= pchan; + pchan->prev= (bPoseChannel *)ten; + + if(pchan->constraints.first) { + Object *target; + bConstraint *con; + TreeElement *ten1; + TreeElement *tenla1= outliner_add_element(soops, &ten->subtree, ob, ten, TSE_CONSTRAINT_BASE, 0); + int a= 0; + char *str; + + tenla1->name= "Constraints"; + for(con= pchan->constraints.first; con; con= con->next, a++) { + ten1= outliner_add_element(soops, &tenla1->subtree, ob, tenla1, TSE_CONSTRAINT, a); + target= get_constraint_target(con, &str); + if(str && str[0]) ten1->name= str; + else if(target) ten1->name= target->id.name+2; + else ten1->name= con->name; + ten1->directdata= con; + /* possible add all other types links? */ + } + } + } + /* make hierarchy */ + ten= tenla->subtree.first; + while(ten) { + TreeElement *nten= ten->next, *par; + tselem= TREESTORE(ten); + if(tselem->type==TSE_POSE_CHANNEL) { + pchan= (bPoseChannel *)ten->directdata; + if(pchan->parent) { + BLI_remlink(&tenla->subtree, ten); + par= (TreeElement *)pchan->parent->prev; + BLI_addtail(&par->subtree, ten); + } + } + ten= nten; + } + /* restore prev pointers */ + for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { + if(pchan->next) pchan->next->prev= pchan; + else if(pchan==ob->pose->chanbase.first) pchan->prev= NULL; + } + } + if(ob->hooks.first) { ObHook *hook; TreeElement *ten; @@ -466,7 +527,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i int a= 0; tenla->name= "Scripts"; - for (a=0; a<ob->scriptlink.totscript; a++) { + for (a=0; a<ob->scriptlink.totscript; a++) { /* ** */ outliner_add_element(soops, &tenla->subtree, ob->scriptlink.scripts[a], te, 0, 0); } } @@ -597,7 +658,6 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i } ten= nten; } - } else { Bone *curBone; @@ -1186,6 +1246,29 @@ static int tree_element_active_bone(TreeElement *te, TreeStoreElem *tselem, int return 0; } +static int tree_element_active_posechannel(TreeElement *te, TreeStoreElem *tselem, int set) +{ + Object *ob= (Object *)tselem->id; + bPoseChannel *pchan= te->directdata; + + if(set) { + if(G.qual & LR_SHIFTKEY); + else deselectall_posearmature(0); + pchan->bone->flag |= BONE_SELECTED|BONE_ACTIVE; + + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWOOPS, 0); + allqueue(REDRAWACTION, 0); + } + else { + if(ob==OBACT && ob->pose) { + if (pchan->bone->flag & BONE_SELECTED) return 1; + } + } + return 0; +} + + /* ebones only draw in editmode armature */ static int tree_element_active_ebone(TreeElement *te, TreeStoreElem *tselem, int set) { @@ -1254,6 +1337,21 @@ static int tree_element_active(SpaceOops *soops, TreeElement *te, int set) return 0; } +static int tree_element_active_pose(TreeElement *te, TreeStoreElem *tselem, int set) +{ + Object *ob= (Object *)tselem->id; + + if(set) { + if(G.obedit) exit_editmode(2); + if(G.obpose) exit_posemode(1); + else enter_posemode(); + } + else { + if(ob==G.obpose) return 1; + } + return 0; +} + /* generic call for non-id data to make/check active in UI */ static int tree_element_type_active(SpaceOops *soops, TreeElement *te, TreeStoreElem *tselem, int set) { @@ -1271,6 +1369,12 @@ static int tree_element_type_active(SpaceOops *soops, TreeElement *te, TreeStore if(set) tree_element_active_object(soops, te); else if(tselem->id==(ID *)OBACT) return 1; break; + case TSE_POSE_BASE: + return tree_element_active_pose(te, tselem, set); + break; + case TSE_POSE_CHANNEL: + return tree_element_active_posechannel(te, tselem, set); + break; } return 0; } @@ -1328,7 +1432,7 @@ static int do_outliner_mouse_event(SpaceOops *soops, TreeElement *te, short even set_scene((Scene *)tselem->id); } } - else if(ELEM4(te->idcode, ID_ME, ID_CU, ID_MB, ID_LT)) { + else if(ELEM5(te->idcode, ID_ME, ID_CU, ID_MB, ID_LT, ID_AR)) { if(G.obpose) exit_posemode(1); if(G.obedit) exit_editmode(2); else { @@ -1336,11 +1440,6 @@ static int do_outliner_mouse_event(SpaceOops *soops, TreeElement *te, short even extern_set_butspace(F9KEY); } } - else if(te->idcode==ID_AR) { - if(G.obedit) exit_editmode(2); - if(G.obpose) exit_posemode(1); - else enter_posemode(); - } else { // rest of types tree_element_active(soops, te, 1); } @@ -1739,11 +1838,11 @@ void outliner_operation_menu(ScrArea *sa) } else if(event==4) { outliner_do_object_operation(soops, &soops->tree, object_delete_cb); + DAG_scene_sort(G.scene); str= "Delete Objects"; } countall(); - test_scene_constraints(); // for delete BIF_undo_push(str); allqueue(REDRAWALL, 0); // yah... to be sure :) @@ -1809,6 +1908,10 @@ static void tselem_draw_icon(TreeStoreElem *tselem) BIF_draw_icon(ICON_OBJECT); break; case TSE_SCRIPT_BASE: BIF_draw_icon(ICON_TEXT); break; + case TSE_POSE_BASE: + BIF_draw_icon(ICON_ARMATURE_DEHLT); break; + case TSE_POSE_CHANNEL: + BIF_draw_icon(ICON_WPAINT_DEHLT); break; default: BIF_draw_icon(ICON_DOT); break; } @@ -1840,7 +1943,7 @@ static void tselem_draw_icon(TreeStoreElem *tselem) case ID_SO: BIF_draw_icon(ICON_SPEAKER); break; case ID_AR: - BIF_draw_icon(ICON_ARMATURE_DEHLT); break; + BIF_draw_icon(ICON_WPAINT_DEHLT); break; case ID_CA: BIF_draw_icon(ICON_CAMERA_DEHLT); break; case ID_KE: @@ -1873,7 +1976,6 @@ static void outliner_draw_iconrow(SpaceOops *soops, ListBase *lb, int level, int active= 0; if(tselem->type==0) { if(te->idcode==ID_OB) active= (OBACT==(Object *)tselem->id); - else if(G.obpose && G.obpose->data==tselem->id) active= 1; else if(G.obedit && G.obedit->data==tselem->id) active= 1; else active= tree_element_active(soops, te, 0); } @@ -1937,10 +2039,6 @@ static void outliner_draw_tree_element(SpaceOops *soops, TreeElement *te, int st glColor4ubv(col); } } - else if(G.obpose && G.obpose->data==tselem->id) { - glColor4ub(255, 255, 255, 100); - active= 2; - } else if(G.obedit && G.obedit->data==tselem->id) { glColor4ub(255, 255, 255, 100); active= 2; @@ -2125,11 +2223,9 @@ static void outliner_back(SpaceOops *soops) } } -static char bone_newname[40]; // temp storage for bone rename, bones are 32 max. - -static void namebutton_cb(void *voidp, void *arg2_unused) +static void namebutton_cb(void *soopsp, void *oldnamep) { - SpaceOops *soops= voidp; + SpaceOops *soops= soopsp; TreeStore *ts= soops->treestore; TreeStoreElem *tselem; int a; @@ -2154,9 +2250,13 @@ static void namebutton_cb(void *voidp, void *arg2_unused) break; case TSE_EBONE: if(G.obedit && G.obedit->data==(ID *)tselem->id) { - extern void validate_editbonebutton(EditBone *); EditBone *ebone= te->directdata; - validate_editbonebutton(ebone); + char newname[32]; + + /* restore bone name */ + BLI_strncpy(newname, ebone->name, 32); + BLI_strncpy(ebone->name, oldnamep, 32); + armature_bone_rename(G.obedit->data, oldnamep, newname); } allqueue(REDRAWOOPS, 0); allqueue(REDRAWVIEW3D, 1); @@ -2165,11 +2265,12 @@ static void namebutton_cb(void *voidp, void *arg2_unused) case TSE_BONE: { Bone *bone= te->directdata; - // always make current object active - tree_element_active_object(soops, te); + char newname[32]; - // dangerous call, it re-allocs the Armature bones, exits editmode too - rename_bone_ext(bone->name, bone_newname); + /* restore bone name */ + BLI_strncpy(newname, bone->name, 32); + BLI_strncpy(bone->name, oldnamep, 32); + armature_bone_rename((bArmature *)tselem->id, oldnamep, newname); } allqueue(REDRAWOOPS, 0); allqueue(REDRAWVIEW3D, 1); @@ -2196,11 +2297,8 @@ static void outliner_buttons(uiBlock *block, SpaceOops *soops, ListBase *lb) tselem= TREESTORE(te); if(tselem->flag & TSE_TEXTBUT) { - // darn bones have complex renaming conventions... cannot edit name itself in button if(tselem->type==TSE_BONE) { - strncpy(bone_newname, te->name, 32); // bone_newname is global - te->name= bone_newname; - len= 24; + len= 32; } else len= 19; diff --git a/source/blender/src/poseobject.c b/source/blender/src/poseobject.c index c5cf36f70fe..4954244dc4a 100644 --- a/source/blender/src/poseobject.c +++ b/source/blender/src/poseobject.c @@ -42,6 +42,7 @@ #include "DNA_action_types.h" #include "DNA_armature_types.h" +#include "DNA_constraint_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" @@ -49,11 +50,13 @@ #include "BKE_action.h" #include "BKE_armature.h" +#include "BKE_constraint.h" #include "BKE_global.h" #include "BKE_displist.h" #include "BIF_gl.h" #include "BIF_graphics.h" +#include "BIF_interface.h" #include "BIF_space.h" #include "BIF_toolbox.h" #include "BIF_screen.h" @@ -66,36 +69,6 @@ #include "mydevice.h" #include "blendef.h" -static void armature_filter_pose_keys (bPose *pose, bArmature* arm); -static void armature_bonechildren_filter_pose_keys (bPose *pose, Bone *bone); - -void collect_pose_garbage(Object *ob) -{ - bPoseChannel *pchan, *next; - Bone *bone; - - if (!ob) - return; - - if (!ob->pose) - return; - - switch (ob->type){ - case OB_ARMATURE: - /* Remove unused pose channels */ - for (pchan = ob->pose->chanbase.first; pchan; pchan=next){ - next=pchan->next; - bone = get_named_bone(ob->data, pchan->name); - if (!bone) - BLI_freelinkN(&ob->pose->chanbase, pchan); - } - break; - default: - break; - } - -} - void enter_posemode(void) { Base *base; @@ -104,11 +77,11 @@ void enter_posemode(void) if(G.scene->id.lib) return; base= BASACT; - if(base==0) return; + if(base==NULL) return; if((base->lay & G.vd->lay)==0) return; ob= base->object; - if(ob->data==0) return; + if(ob->data==NULL) return; if (ob->id.lib){ error ("Can't pose libdata"); @@ -118,7 +91,7 @@ void enter_posemode(void) switch (ob->type){ case OB_ARMATURE: arm= get_armature(ob); - if( arm==0 ) return; + if( arm==NULL ) return; G.obpose= ob; ob->flag |= OB_POSEMODE; @@ -139,71 +112,23 @@ void enter_posemode(void) } -void filter_pose_keys (void) +void set_pose_keys (Object *ob) { - - - Object *ob; bPoseChannel *chan; - ob=G.obpose; - if (!ob) - return; - - switch (ob->type){ - case OB_ARMATURE: - armature_filter_pose_keys (ob->pose, (bArmature*)ob->data); - break; - default: - if (ob->pose){ - for (chan=ob->pose->chanbase.first; chan; chan=chan->next){ - chan->flag |= POSE_KEY; + if (ob->pose){ + for (chan=ob->pose->chanbase.first; chan; chan=chan->next){ + Bone *bone= chan->bone; + if(bone && (bone->flag & BONE_SELECTED)) { + chan->flag |= POSE_KEY; + } + else { + chan->flag &= ~POSE_KEY; } } - break; } } -static void armature_filter_pose_keys (bPose *pose, bArmature *arm) -{ - Bone *bone; - - if (!pose) - return; - if (!arm) - return; - - for (bone=arm->bonebase.first; bone; bone=bone->next){ - armature_bonechildren_filter_pose_keys (pose, bone); - } -} - -static void armature_bonechildren_filter_pose_keys (bPose *pose, Bone *bone) -{ - Bone *curbone; - bPoseChannel *chan; - - if (!bone) - return; - - for (chan=pose->chanbase.first; chan; chan=chan->next){ - if (BLI_streq(chan->name, bone->name)) - break; - } - - if (chan){ - if (bone->flag & BONE_SELECTED){ - chan->flag |= POSE_KEY; - } - else { - chan->flag &= ~POSE_KEY; - } - } - - for (curbone=bone->childbase.first; curbone; curbone=curbone->next){ - armature_bonechildren_filter_pose_keys (pose, curbone); - } -} void exit_posemode (int freedata) { @@ -235,3 +160,33 @@ void exit_posemode (int freedata) scrarea_queue_headredraw(curarea); } + +void pose_special_editmenu(void) +{ + bPoseChannel *pchan; + short nr; + + for(pchan= G.obpose->pose->chanbase.first; pchan; pchan= pchan->next) + if(pchan->bone->flag & BONE_ACTIVE) break; + if(pchan==NULL) return; + + nr= pupmenu("Specials%t|Select constraint target%x1"); + if(nr==1) { + bConstraint *con; + + for(con= pchan->constraints.first; con; con= con->next) { + char *subtarget; + Object *ob= get_constraint_target(con, &subtarget); + + if(ob==G.obpose) { + if(subtarget) { + pchan= get_pose_channel(G.obpose->pose, subtarget); + pchan->bone->flag |= BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL; + } + } + } + allqueue(REDRAWVIEW3D, 0); + } +} + + diff --git a/source/blender/src/renderwin.c b/source/blender/src/renderwin.c index a87f3863ec3..ae5c3b6c00e 100644 --- a/source/blender/src/renderwin.c +++ b/source/blender/src/renderwin.c @@ -680,7 +680,15 @@ static void renderwin_init_display_cb(void) else { window_raise(render_win->win); window_make_active(render_win->win); - mywinset(2); // to assign scissor/viewport again in mywindow.c. is hackish yes + + mywinset(2); // to assign scissor/viewport again in mywindow.c. is hackish yes, but otherwise it draws in header of button for ogl header + { + rcti win_rct; + win_rct.xmin= win_rct.ymin= 0; + window_get_size(render_win->win, &win_rct.xmax, &win_rct.ymax); + win_rct.ymax-= RW_HEADERY; + glaDefine2DArea(&win_rct); + } } renderwin_reset_view(render_win); diff --git a/source/blender/src/space.c b/source/blender/src/space.c index 0f5351ea612..7e2cc16e77b 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -70,6 +70,7 @@ #include "BKE_blender.h" #include "BKE_curve.h" +#include "BKE_depsgraph.h" #include "BKE_displist.h" #include "BKE_global.h" #include "BKE_ipo.h" @@ -86,7 +87,6 @@ #include "BIF_drawscript.h" #include "BIF_editarmature.h" #include "BIF_editfont.h" -#include "BIF_editika.h" #include "BIF_editkey.h" #include "BIF_editlattice.h" #include "BIF_editmesh.h" @@ -643,6 +643,8 @@ void BIF_undo_push(char *str) undo_push_mball(str); else if (G.obedit->type==OB_LATTICE) undo_push_lattice(str); + else if (G.obedit->type==OB_ARMATURE) + undo_push_armature(str); } else { if(U.uiflag & USER_GLOBALUNDO) @@ -653,7 +655,7 @@ void BIF_undo_push(char *str) void BIF_undo(void) { if(G.obedit) { - if ELEM6(G.obedit->type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL, OB_LATTICE) + if ELEM7(G.obedit->type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL, OB_LATTICE, OB_ARMATURE) undo_editmode_step(1); } else { @@ -671,7 +673,7 @@ void BIF_undo(void) void BIF_redo(void) { if(G.obedit) { - if ELEM6(G.obedit->type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL, OB_LATTICE) + if ELEM7(G.obedit->type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL, OB_LATTICE, OB_ARMATURE) undo_editmode_step(-1); } else { @@ -689,7 +691,7 @@ void BIF_redo(void) void BIF_undo_menu(void) { if(G.obedit) { - if ELEM6(G.obedit->type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL, OB_LATTICE) + if ELEM7(G.obedit->type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL, OB_LATTICE, OB_ARMATURE) undo_editmode_menu(); allqueue(REDRAWALL, 0); } @@ -1156,7 +1158,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt) } else if((G.obedit) && ELEM(G.obedit->type, OB_CURVE, OB_SURF) ) { makecyclicNurb(); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); } else if((G.qual==0)){ @@ -1203,11 +1205,6 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt) else if(G.obedit->type==OB_ARMATURE) extrude_armature(); } - else { - ob= OBACT; - if(ob && ob->type==OB_IKA) if(okee("extrude IKA")) - extrude_ika(ob, 1); - } } else if (G.qual==LR_CTRLKEY) { if(G.obedit && G.obedit->type==OB_MESH) @@ -1295,7 +1292,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt) else if((G.qual==0)) sethandlesNurb(3); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); BIF_undo_push("Handle change"); allqueue(REDRAWVIEW3D, 0); } @@ -1368,9 +1365,6 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt) else select_select_keys(); } - else if(G.qual==LR_CTRLKEY) - make_skeleton(); -/* else if(G.qual & LR_ALTKEY) delete_skeleton(); */ else if (G.qual==0) set_ob_ipoflags(); } @@ -1413,7 +1407,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt) if(G.qual==LR_ALTKEY) { if(G.obedit->type==OB_MESH) { mergemenu(); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); } } else if((G.qual==0) || (G.qual==LR_CTRLKEY)) { @@ -1496,8 +1490,14 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt) case PKEY: if(G.obedit) { - if(G.qual==LR_CTRLKEY || G.qual==(LR_SHIFTKEY|LR_CTRLKEY)) - make_parent(); + if(G.qual==LR_CTRLKEY || G.qual==(LR_SHIFTKEY|LR_CTRLKEY)) { + if(G.obedit->type==OB_ARMATURE) + make_bone_parent(); + else + make_parent(); + } + else if(G.qual==LR_ALTKEY && G.obedit->type==OB_ARMATURE) + clear_bone_parent(); else if((G.qual==0) && G.obedit->type==OB_MESH) separatemenu(); else if ((G.qual==0) && ELEM(G.obedit->type, OB_CURVE, OB_SURF)) @@ -1609,7 +1609,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt) convert_to_triface(0); allqueue(REDRAWVIEW3D, 0); countall(); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); } if (G.obedit->type==OB_CURVE) { if (G.qual==LR_ALTKEY) { @@ -1637,9 +1637,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt) if(G.obedit->type==OB_MESH) { if(G.qual==0) BIF_undo(); else BIF_redo(); } - else if(G.obedit->type==OB_ARMATURE) - remake_editArmature(); - else if ELEM4(G.obedit->type, OB_CURVE, OB_SURF, OB_MBALL, OB_LATTICE) { + else if ELEM5(G.obedit->type, OB_CURVE, OB_SURF, OB_MBALL, OB_LATTICE, OB_ARMATURE) { if(G.qual==0) BIF_undo(); else BIF_redo(); } } @@ -1672,7 +1670,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt) if(G.obedit) { if(G.obedit->type==OB_CURVE) { sethandlesNurb(2); - makeDispList(G.obedit); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); BIF_undo_push("Handle change"); } @@ -4565,16 +4563,7 @@ void allqueue(unsigned short event, short val) sa= G.curscreen->areabase.first; while(sa) { -//#ifdef NAN_DEP_GRAPH - /* dependency check.maybe not final pos */ - if (sa->spacetype==SPACE_VIEW3D) { - if (G.scene->dagisvalid == 0) { -// fprintf(stderr,"building dag \n"); - G.scene->theDag = build_dag(G.scene, DAG_RL_ALL_BUT_DATA_MASK); - G.scene->dagisvalid = 1; - } - } -//#endif + if(event==REDRAWALL) { scrarea_queue_winredraw(sa); scrarea_queue_headredraw(sa); diff --git a/source/blender/src/toets.c b/source/blender/src/toets.c index 5cc23d6914b..fde39edf640 100644 --- a/source/blender/src/toets.c +++ b/source/blender/src/toets.c @@ -60,10 +60,10 @@ #include "BKE_action.h" #include "BKE_anim.h" #include "BKE_blender.h" +#include "BKE_depsgraph.h" #include "BKE_displist.h" #include "BKE_global.h" #include "BKE_ipo.h" -#include "BKE_ika.h" #include "BKE_key.h" #include "BKE_scene.h" #include "BKE_utildefines.h" @@ -408,11 +408,7 @@ void persptoetsen(unsigned short event) } else if(event==PAD9) { countall(); - do_all_ipos(); - do_all_keys(); - do_all_actions(NULL); - do_all_ikas(); - test_all_displists(); + update_for_newframe(); reset_slowparents(); /* editobject.c */ } @@ -986,9 +982,6 @@ int blenderqread(unsigned short event, short val) if(textspace==0 && textediting==0) { if(G.qual==LR_CTRLKEY) { if(okee("Erase all")) { - strcpy(G.sce, BLI_gethome()); - strcat(G.sce, "/untitled.blend"); - BLI_clean(G.sce); if( BIF_read_homefile()==0) error("No file ~/.B.blend"); } return 0; diff --git a/source/blender/src/transform.c b/source/blender/src/transform.c index 8f5a0407487..ab732f9eb1a 100755 --- a/source/blender/src/transform.c +++ b/source/blender/src/transform.c @@ -46,13 +46,29 @@ #include "MEM_guardedalloc.h" -#include "DNA_listBase.h" -#include "DNA_userdef_types.h" -#include "DNA_scene_types.h" /* PET modes */ -#include "DNA_screen_types.h" /* area dimensions */ +#include "DNA_action_types.h" +#include "DNA_armature_types.h" +#include "DNA_camera_types.h" +#include "DNA_constraint_types.h" +#include "DNA_curve_types.h" +#include "DNA_effect_types.h" +#include "DNA_image_types.h" +#include "DNA_ipo_types.h" +#include "DNA_key_types.h" +#include "DNA_lamp_types.h" +#include "DNA_lattice_types.h" +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_meta_types.h" #include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_texture_types.h" #include "DNA_view3d_types.h" -#include "DNA_ipo_types.h" /* some silly ipo flag */ +#include "DNA_world_types.h" +#include "DNA_userdef_types.h" +#include "DNA_property_types.h" +#include "DNA_vfont_types.h" #include "BIF_editview.h" /* arrows_move_cursor */ #include "BIF_screen.h" @@ -69,6 +85,8 @@ #include "BLI_arithb.h" +#include "BDR_editobject.h" + #include "PIL_time.h" #include "blendef.h" @@ -195,7 +213,7 @@ void checkFirstTime() { } static void transformEvent(unsigned short event, short val) { - float mati[3][3] = {1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f}; + float mati[3][3] = {{1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}}; char cmode = constraintModeToChar(&Trans); if (val) { @@ -517,7 +535,7 @@ void Transform() selectConstraint(&Trans); if (Trans.transform) { - Trans.transform(&Trans, mval); + Trans.transform(&Trans, mval); // calls recalcData() } Trans.redraw = 0; } @@ -534,7 +552,7 @@ void Transform() /* handle restoring objects and Undo */ if(Trans.state == TRANS_CANCEL) { - restoreTransObjects(&Trans); + restoreTransObjects(&Trans); // calls recalcData() if(Trans.undostr) BIF_undo_push(Trans.undostr); } else { @@ -552,9 +570,9 @@ void Transform() if(Trans.mode==TFM_RESIZE) cmode= 's'; else if(Trans.mode==TFM_ROTATION) cmode= 'r'; - /* aftertrans does displists, ipos and action channels */ - /* 7 = keyflags, meaning do loc/rot/scale ipos. Not sure if I like the old method to detect what changed (ton) */ - special_aftertrans_update(cmode, 0, (short)(Trans.state == TRANS_CANCEL), 7); + + /* aftertrans does insert ipos and action channels */ + special_aftertrans_update(cmode, 0, (short)(Trans.state == TRANS_CANCEL)); if(G.obedit==NULL && G.obpose==NULL) clear_trans_object_base_flags(); @@ -718,7 +736,7 @@ void ManipulatorTransform() else if(Trans.mode==TFM_ROTATION) cmode= 'r'; /* aftertrans does displists, ipos and action channels */ /* 7 = keyflags, meaning do loc/rot/scale ipos. Not sure if I like the old method to detect what changed (ton) */ - special_aftertrans_update(cmode, 0, (short)(Trans.state == TRANS_CANCEL), 7); + special_aftertrans_update(cmode, 0, (short)(Trans.state == TRANS_CANCEL)); if(G.obedit==NULL && G.obpose==NULL) clear_trans_object_base_flags(); diff --git a/source/blender/src/transform_constraints.c b/source/blender/src/transform_constraints.c index 3714b48fd40..b6ef7a8bf21 100755 --- a/source/blender/src/transform_constraints.c +++ b/source/blender/src/transform_constraints.c @@ -43,6 +43,21 @@ #include <io.h> #endif +#include "MEM_guardedalloc.h" + +#include "DNA_action_types.h" +#include "DNA_armature_types.h" +#include "DNA_camera_types.h" +#include "DNA_curve_types.h" +#include "DNA_effect_types.h" +#include "DNA_image_types.h" +#include "DNA_ipo_types.h" +#include "DNA_key_types.h" +#include "DNA_lamp_types.h" +#include "DNA_lattice_types.h" +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_meta_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c index bb966028222..a50a8430c0f 100755 --- a/source/blender/src/transform_conversions.c +++ b/source/blender/src/transform_conversions.c @@ -51,7 +51,6 @@ #include "DNA_camera_types.h" #include "DNA_curve_types.h" #include "DNA_effect_types.h" -#include "DNA_ika_types.h" #include "DNA_image_types.h" #include "DNA_ipo_types.h" #include "DNA_key_types.h" @@ -90,6 +89,7 @@ #include "BKE_blender.h" #include "BKE_curve.h" #include "BKE_constraint.h" +#include "BKE_depsgraph.h" #include "BKE_displist.h" #include "BKE_effect.h" #include "BKE_font.h" @@ -112,7 +112,6 @@ #include "BLI_arithb.h" #include "BLI_editVert.h" -#include "BLI_ghash.h" #include "PIL_time.h" @@ -125,10 +124,6 @@ extern ListBase editelems; #include "transform.h" -/* local protos */ -static void figure_bone_nocalc(Object *ob); -static void figure_pose_updating(void); - /* ************************** Functions *************************** */ @@ -379,70 +374,132 @@ static void createTransEdge(TransInfo *t) { /* ********************* pose mode ************* */ -/* callback, make sure it's identical structured as next one */ -/* also used to count for manipulator */ -void count_bone_select(TransInfo *t, ListBase *lb, int *counter) +/* recursive, make sure it's identical structured as next one */ +/* only counts the parent selection, and tags transform flag */ +/* exported for manipulator */ +void count_bone_select(TransInfo *t, ListBase *lb, int do_it) { Bone *bone; - int deeper= 1; + int do_next=do_it; for(bone= lb->first; bone; bone= bone->next) { - if (bone->flag & BONE_SELECTED) { - /* We don't let IK children get "grabbed" */ - /* ALERT! abusive global Trans here */ - if ( (t->mode!=TFM_TRANSLATION) || (bone->flag & BONE_IK_TOPARENT)==0 ) { - (*counter)++; - deeper= 0; // no transform on children if one parent bone is selected + bone->flag &= ~BONE_TRANSFORM; + if(do_it) { + if (bone->flag & BONE_SELECTED) { + /* We don't let IK children get "grabbed" */ + if ( (t->mode!=TFM_TRANSLATION) || (bone->flag & BONE_IK_TOPARENT)==0 ) { + bone->flag |= BONE_TRANSFORM; + t->total++; + do_next= 0; // no transform on children if one parent bone is selected + } } - else deeper= 1; } - if(deeper) count_bone_select(t, &bone->childbase, counter); + count_bone_select(t, &bone->childbase, do_next); } } -/* recursive */ -static void add_pose_transdata(TransInfo *t, ListBase *lb, Object *ob, TransData **tdp) +static void get_weird_bone_matrix (struct Bone* bone, float M_accumulatedMatrix[][4], int root, int posed) +/* Gets matrix that transforms the bone to object space */ +/* This function is also used to compute the orientation of the bone for display */ { - Bone *bone; - TransData *td; + Bone *curBone; + + Bone *bonelist[256]; + int bonecount=0, i; + + Mat4One (M_accumulatedMatrix); + + /* Build a list of bones from tip to root */ + for (curBone=bone; curBone; curBone=curBone->parent){ + bonelist[bonecount] = curBone; + bonecount++; + } + + /* Count through the inverted list (i.e. iterate from root to tip)*/ + for (i=0; i<bonecount; i++){ + float T_root[4][4]; + float T_len[4][4]; + float R_bmat[4][4]; + float M_obmat[4][4]; + float M_boneMatrix[4][4]; + float delta[3]; + + curBone = bonelist[bonecount-i-1]; + + /* Get the length translation (length along y axis) */ + Mat4One (T_len); + T_len[3][1] = (curBone->length); + + if ((curBone == bone) && (root)) + Mat4One (T_len); + + /* Get the bone's root offset (in the parent's coordinate system) */ + Mat4One (T_root); + VECCOPY (T_root[3], curBone->head); + + /* Compose the restmat */ + VecSubf(delta, curBone->tail, curBone->head); + Mat4CpyMat3(R_bmat, curBone->bone_mat); + + /* Retrieve the obmat (user transformation) */ + if (bone!=curBone) { + bPoseChannel *pchan= get_pose_channel(G.obpose->pose, curBone->name); + Mat4CpyMat4 (M_obmat, pchan->chan_mat); + } + else + Mat4One (M_obmat); + + /* Compose the matrix for this bone */ +#if 0 + Mat4MulSerie (M_boneMatrix, M_accumulatedMatrix, T_root, M_obmat, R_bmat, T_len, NULL, NULL, NULL); +#else + Mat4MulSerie (M_boneMatrix, M_accumulatedMatrix, T_root, R_bmat, M_obmat, T_len, NULL, NULL, NULL); +#endif + Mat4CpyMat4 (M_accumulatedMatrix, M_boneMatrix); + } + + +} + +static int add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, TransData *td) +{ + Bone *bone= pchan->bone; float parmat[4][4], tempmat[4][4]; - float tempobmat[4][4]; +// float tempobmat[4][4]; float vec[3]; - int deeper= 1; - - for(bone= lb->first; bone; bone= bone->next) { - if (bone->flag & BONE_SELECTED) { + + if(bone) { + if (bone->flag & BONE_TRANSFORM) { /* We don't let IK children get "grabbed" */ - /* ALERT! abusive global Trans here */ if ( (t->mode!=TFM_TRANSLATION) || (bone->flag & BONE_IK_TOPARENT)==0 ) { - td= *tdp; - - get_bone_root_pos (bone, vec, 1); - - //VecAddf (centroid, centroid, vec); + VECCOPY(vec, pchan->pose_mat[3]); VECCOPY(td->center, vec); td->ob = ob; td->flag= TD_SELECTED|TD_USEQUAT; - td->loc = bone->loc; - VECCOPY(td->iloc, bone->loc); + td->loc = pchan->loc; + VECCOPY(td->iloc, pchan->loc); td->ext->rot= NULL; - td->ext->quat= bone->quat; - td->ext->size= bone->size; + td->ext->quat= pchan->quat; + td->ext->size= pchan->size; td->ext->bone= bone; // FIXME: Dangerous - QUATCOPY(td->ext->iquat, bone->quat); - VECCOPY(td->ext->isize, bone->size); + QUATCOPY(td->ext->iquat, pchan->quat); + VECCOPY(td->ext->isize, pchan->size); /* Get the matrix of this bone minus the usertransform */ - Mat4CpyMat4 (tempobmat, bone->obmat); - Mat4One (bone->obmat); - get_objectspace_bone_matrix(bone, tempmat, 1, 1); - Mat4CpyMat4 (bone->obmat, tempobmat); - - Mat4MulMat4 (parmat, tempmat, ob->obmat); /* Original */ +// Mat4CpyMat4 (tempobmat, bone->obmat); +// Mat4One (bone->obmat); + get_weird_bone_matrix(pchan->bone, tempmat, 1, 1); + Mat4MulMat4 (parmat, tempmat, ob->obmat); +// Mat4CpyMat4 (bone->obmat, tempobmat); + +// if(pchan->parent) +// Mat4MulMat4 (parmat, pchan->parent->pose_mat, ob->obmat); +// else +// Mat4CpyMat4 (parmat, ob->obmat); Mat3CpyMat4 (td->mtx, parmat); Mat3Inv (td->smtx, td->mtx); @@ -450,25 +507,24 @@ static void add_pose_transdata(TransInfo *t, ListBase *lb, Object *ob, TransData Mat3CpyMat3(td->axismtx, td->mtx); Mat3Ortho(td->axismtx); - (*tdp)++; - deeper= 0; + return 1; } - else deeper= 1; } - if(deeper) add_pose_transdata(t, &bone->childbase, ob, tdp); } + return 0; } static void createTransPose(TransInfo *t) { bArmature *arm; + bPoseChannel *pchan; TransData *td; TransDataExtension *tdx; int i; /* check validity of state */ arm=get_armature (G.obpose); - if (arm==NULL) return; + if (arm==NULL || G.obpose->pose==NULL) return; if (arm->flag & ARM_RESTPOS){ notice ("Transformation not possible while Rest Position is enabled"); @@ -476,25 +532,17 @@ static void createTransPose(TransInfo *t) } if (!(G.obpose->lay & G.vd->lay)) return; - /* copied from old code, no idea. we let linker solve it for now */ - { - /* figure out which bones need calculating */ - figure_bone_nocalc(G.obpose); - figure_pose_updating(); - } - - /* copied from old code, no idea... (ton) */ - apply_pose_armature(arm, G.obpose->pose, 0); - where_is_armature (G.obpose); - /* count total */ - count_bone_select(t, &arm->bonebase, &t->total); + count_bone_select(t, &arm->bonebase, 1); if(t->total==0 && t->mode==TFM_TRANSLATION) { t->mode= TFM_ROTATION; - count_bone_select(t, &arm->bonebase, &t->total); + count_bone_select(t, &arm->bonebase, 1); } if(t->total==0) return; + + /* since we need to be able to insert keys, no actions should be assigned */ + arm->flag |= ARM_NO_ACTION; /* init trans data */ td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransPoseBone"); @@ -504,9 +552,13 @@ static void createTransPose(TransInfo *t) td->tdi = NULL; td->val = NULL; } - /* recursive fill trans data */ + + /* use pose channels to fill trans data */ td= t->data; - add_pose_transdata(t, &arm->bonebase, G.obpose, &td); + for(pchan= G.obpose->pose->chanbase.first; pchan; pchan= pchan->next) { + if( add_pose_transdata(t, pchan, G.obpose, td) ) td++; + } + if(td != (t->data+t->total)) printf("Bone selection count error\n"); } @@ -1223,6 +1275,8 @@ static void ObjectToTransData(TransData *td, Object *ob) Mat3CpyMat4(td->axismtx, ob->obmat); Mat3Ortho(td->axismtx); + /* then why are constraints and track disabled here? + they dont alter loc/rot/size itself (ton) */ cfirst = ob->constraints.first; clast = ob->constraints.last; ob->constraints.first=ob->constraints.last=NULL; @@ -1270,36 +1324,6 @@ static void ObjectToTransData(TransData *td, Object *ob) } } -/* only used in function below, stuff to be removed */ -static Object *is_a_parent_selected_int(Object *startob, Object *ob, GHash *done_hash) -{ - if (ob!=startob && TESTBASE(ob)) - return ob; - - if (BLI_ghash_haskey(done_hash, ob)) - return NULL; - else - BLI_ghash_insert(done_hash, ob, NULL); - - if (ob->parent) { - Object *par= is_a_parent_selected_int(startob, ob->parent, done_hash); - if (par) - return par; - } - return NULL; -} - -/* only used in function below, stuff to be removed */ -static Object *is_a_parent_selected(Object *ob) -{ - GHash *gh= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp); - Object *res= is_a_parent_selected_int(ob, ob, gh); - BLI_ghash_free(gh, NULL, NULL); - - return res; -} - - /* sets flags in Bases to define whether they take part in transform */ /* it deselects Bases, so we have to call the clear function always after */ @@ -1307,98 +1331,45 @@ static void set_trans_object_base_flags(TransInfo *t) { /* if Base selected and has parent selected: - base->flag= BA_WASSEL+BA_PARSEL - if base not selected and parent selected: - base->flag= BA_PARSEL + base->flag= BA_WAS_SEL */ - GHash *object_to_base_hash= NULL; Base *base; - /* moved to start of function, it is needed for hooks now too */ - if (!object_to_base_hash) { - Base *b; - object_to_base_hash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp); - - for (b= FIRSTBASE; b; b= b->next) - BLI_ghash_insert(object_to_base_hash, b->object, b); - } - /* makes sure base flags and object flags are identical */ copy_baseflags(); for (base= FIRSTBASE; base; base= base->next) { - base->flag &= ~(BA_PARSEL+BA_WASSEL); + base->flag &= ~BA_WAS_SEL; - if( (base->lay & G.vd->lay) && base->object->id.lib==0) { + if(TESTBASELIB(base)) { Object *ob= base->object; - Object *parsel= is_a_parent_selected(ob); - - /* parentkey here? */ + Object *parsel= ob->parent; - if(parsel) { - if(base->flag & SELECT) { - base->flag &= ~SELECT; - base->flag |= (BA_PARSEL+BA_WASSEL); - } - else base->flag |= BA_PARSEL; - } - - if(t->mode==TFM_TRANSLATION) { - if(ob->track && TESTBASE(ob->track) && (base->flag & SELECT)==0) - base->flag |= BA_PARSEL; + /* if parent selected, deselect */ + while(parsel) { + if(parsel->flag & SELECT) break; + parsel= parsel->parent; } - /* updates? */ - if(ob->hooks.first) { - Base *b; - ObHook *hook= ob->hooks.first; - - while(hook) { - if(hook->parent) { - Object *parsel= is_a_parent_selected(hook->parent); - - b= BLI_ghash_lookup(object_to_base_hash, hook->parent); - if(parsel || ((base->flag | b->flag) & (SELECT | BA_PARSEL)) ) { - base->flag |= BA_DISP_UPDATE; - } - } - hook= hook->next; - } - } - - if(ob->parent && ob->parent->type==OB_LATTICE) - if(ob->parent->hooks.first) base->flag |= BA_DISP_UPDATE; - - if(base->flag & (SELECT | BA_PARSEL)) { - - base->flag |= BA_WHERE_UPDATE; - - if(ob->parent) { - if(ob->parent->type==OB_LATTICE) base->flag |= BA_DISP_UPDATE; - else if(ob->partype==PARSKEL) { - if ELEM3(ob->parent->type, OB_IKA, OB_CURVE, OB_ARMATURE) - base->flag |= BA_DISP_UPDATE; - } - } - if(ob->track) { - ; - } - - if( give_parteff(ob) ) base->flag |= BA_DISP_UPDATE; - - if(ob->type==OB_MBALL) { - Base *b; - - b= BLI_ghash_lookup(object_to_base_hash, find_basis_mball(ob)); - b->flag |= BA_DISP_UPDATE; - } + if(parsel) { + base->flag &= ~SELECT; + base->flag |= BA_WAS_SEL; } + /* used for flush, depgraph will change recalcs if needed :) */ + ob->recalc |= OB_RECALC_OB; } } + /* all recalc flags get flushed */ + DAG_scene_flush_update(G.scene); - if (object_to_base_hash) - BLI_ghash_free(object_to_base_hash, NULL, NULL); - + /* and we store them temporal in base (only used for transform code) */ + /* this because after doing updates, the object->recalc is cleared */ + for (base= FIRSTBASE; base; base= base->next) { + if(base->object->recalc & OB_RECALC_OB) + base->flag |= BA_HAS_RECALC_OB; + if(base->object->recalc & OB_RECALC_DATA) + base->flag |= BA_HAS_RECALC_DATA; + } } void clear_trans_object_base_flags(void) @@ -1407,463 +1378,27 @@ void clear_trans_object_base_flags(void) base= FIRSTBASE; while(base) { - if(base->flag & BA_WASSEL) base->flag |= SELECT; - base->flag &= ~(BA_PARSEL+BA_WASSEL); - - base->flag &= ~(BA_DISP_UPDATE+BA_WHERE_UPDATE+BA_DO_IPO); - - /* pose here? */ - if (base->object->pose) { - Object *ob= base->object; - bPoseChannel *chan; - for (chan = ob->pose->chanbase.first; chan; chan=chan->next) { - chan->flag &= ~PCHAN_TRANS_UPDATE; - } - } + if(base->flag & BA_WAS_SEL) base->flag |= SELECT; + base->flag &= ~(BA_WAS_SEL|BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA|BA_DO_IPO); base= base->next; } - copy_baseflags(); } -/* ******************************************************************************** */ -/* ************** TOTALLY #@#! CODE FROM PAST TRANSFORM FOR POSEMODE ************** */ -/* ******************************************************************************** */ - - -static int is_ob_constraint_target(Object *ob, ListBase *conlist) { - /* Is this object the target of a constraint in this list? - */ - - bConstraint *con; - - for (con=conlist->first; con; con=con->next) - { - if (get_constraint_target(con) == ob) - return 1; - } - return 0; - -} - -static int clear_bone_nocalc(Object *ob, Bone *bone, void *ptr) { - /* When we aren't transform()-ing, we'll want to turn off - * the no calc flag for bone bone in case the frame changes, - * or something - */ - bone->flag &= ~BONE_NOCALC; - - return 0; -} - - -static int set_bone_nocalc(Object *ob, Bone *bone, void *ptr) { - /* Calculating bone transformation makes thins slow ... - * lets set the no calc flag for a bone by default - */ - bone->flag |= BONE_NOCALC; - - return 0; -} - -static int selected_bone_docalc(Object *ob, Bone *bone, void *ptr) { - /* Let's clear the no calc flag for selected bones. - * This function always returns 1 for non-no calc bones - * (a.k.a., the 'do calc' bones) so that the bone_looper - * will count these - */ - if (bone->flag & BONE_NOCALC) { - if ( (bone->flag & BONE_SELECTED) ) { - bone->flag &= ~BONE_NOCALC; - return 1; - } - - } - else { - return 1; - } - return 0; -} - -static Bone *get_parent_bone_docalc(Bone *bone) { - Bone *parBone; - - for (parBone = bone->parent; parBone; parBone=parBone->parent) - if (~parBone->flag & BONE_NOCALC) - return parBone; - - return NULL; -} - -static int is_bone_parent(Bone *childBone, Bone *parBone) { - Bone *currBone; - - for (currBone = childBone->parent; currBone; currBone=currBone->parent) - if (currBone == parBone) - return 1; - - return 0; -} - -static void figure_bone_nocalc_constraint(Bone *conbone, bConstraint *con, - Object *ob, bArmature *arm) { - /* If this bone has a constraint with a subtarget that has - * the nocalc flag cleared, then we better clear the no calc flag - * on this bone too (and the whole IK chain if this is an IK - * constraint). - * - * Conversly, if this bone has an IK constraint and the root of - * the chain has the no calc flag cleared, we had best clear that - * flag for the whole chain. - */ - Bone *subtarbone; - Bone *parBone; - char *subtar; - - subtar = get_con_subtarget_name(con, ob); - - if (subtar) { - if ( (subtarbone = get_named_bone(arm, subtar)) ) { - if ( (~subtarbone->flag & BONE_NOCALC) || - (get_parent_bone_docalc(subtarbone)) ) { - if (con->type == CONSTRAINT_TYPE_KINEMATIC) - /* IK target is flaged for updating, so we - * must update the whole chain. - */ - ik_chain_looper(ob, conbone, NULL, - clear_bone_nocalc); - else - /* Constraint target is flagged for - * updating, so we update this bone only - */ - conbone->flag &= ~BONE_NOCALC; - } - else { - if ( (parBone = get_parent_bone_docalc(conbone)) ) { - /* a parent is flagged for updating */ - if (!is_bone_parent(subtarbone, parBone)) { - /* if the subtarget is also a child of - * this bone, we needn't worry, other - * wise, we have to update - */ - if (con->type == CONSTRAINT_TYPE_KINEMATIC) - ik_chain_looper(ob, conbone, NULL, - clear_bone_nocalc); - else - conbone->flag &= ~BONE_NOCALC; - } - } - - } - } - } - else { - /* no subtarget ... target is regular object */ - if ( (parBone = get_parent_bone_docalc(conbone)) ) { - /* parent is flagged for updating ... since - * the target will never move (not a bone) - * we had better update this bone/chain - */ - if (con->type == CONSTRAINT_TYPE_KINEMATIC) - ik_chain_looper(ob, conbone, NULL, - clear_bone_nocalc); - else - conbone->flag &= ~BONE_NOCALC; - } - } - -} - -static void figure_bone_nocalc_core(Object *ob, bArmature *arm) { - /* Let's figure out which bones need to be recalculated, - * and which don't. Calculations are based on which bones - * are selected, and the constraints that love them. - */ - bPoseChannel *chan; - bConstraint *con; - Bone *conbone; - - int numbones, oldnumbones, iterations; - - oldnumbones = -1; - numbones = 0; - iterations = 0; - - /* O.K., lets loop until we don't clear any more no calc bones - */ - while (oldnumbones != numbones) { - /* I wonder if this will ever get executed? */ - if ( (++iterations) == 1000) { - printf("figurin' nocalc is talking too long\n"); - break; - } - - oldnumbones = numbones; - - /* clear no calc for selected bones and count */ - numbones = bone_looper(ob, arm->bonebase.first, NULL, - selected_bone_docalc); - - if (ob->pose) { - for (chan = ob->pose->chanbase.first; chan; chan=chan->next){ - conbone = get_named_bone(arm, chan->name); - if (conbone) { - for (con = chan->constraints.first; con; con=con->next) { - figure_bone_nocalc_constraint(conbone, con, ob, arm); - } - } - } - } - } -} - -static void figure_bone_nocalc(Object *ob) -{ - /* Let's figure out which bones need to be recalculated, - * and which don't. Calculations are based on which bones - * are selected, and the constraints that love them. - */ - bArmature *arm; - - arm = get_armature(ob); - if (!arm) return; - - if (arm->flag & ARM_RESTPOS) return; - - /* Set no calc for all bones - */ - bone_looper(ob, arm->bonebase.first, NULL, - set_bone_nocalc); - - figure_bone_nocalc_core(ob, arm); -} - -static int bone_nocalc2chan_trans_update(Object *ob, Bone *bone, void *ptr) { - /* Set PCHAN_TRANS_UPDATE for channels with bones that don't have - * the no calc flag set ... I hate this. - */ - bPoseChannel *chan; - - if (~bone->flag & BONE_NOCALC) { - chan = get_pose_channel(ob->pose, bone->name); - if (chan) chan->flag |= PCHAN_TRANS_UPDATE; - } - else { - /* reset this thing too */ - bone->flag &= ~BONE_NOCALC; - } - - return 0; -} - -static void clear_gonna_move(void) { - Base *base; - - /* clear the gonna move flag */ - for (base= FIRSTBASE; base; base= base->next) { - base->object->flag &= ~OB_GONNA_MOVE; - } -} - -static int is_parent_gonna_move(Object *ob) { - if ( (ob->parent) && - (ob->parent->flag & OB_GONNA_MOVE) ) { - return 1; - } - return 0; -} - -static int is_constraint_target_gonna_move(Object *ob) { - Object *tarOb; - bConstraint *con; - bPoseChannel *chan; - - for (con = ob->constraints.first; con; con=con->next) { - if ( (tarOb = get_constraint_target(con)) ) { - if (tarOb->flag & OB_GONNA_MOVE ) - return 1; - } - } - - if (ob->pose) { - for (chan = ob->pose->chanbase.first; chan; chan=chan->next){ - for (con = chan->constraints.first; con; con=con->next) { - if ( (tarOb = get_constraint_target(con)) ) { - if (tarOb->flag & OB_GONNA_MOVE ) - return 1; - } - } - } - } - - return 0; -} - -static void flag_moving_objects(void) { - Base *base; - int numgonnamove = 0, oldnumgonnamove = -1; - - clear_gonna_move(); - - /* the 'well ordering principle' guarantees convergence (honest) - */ - while (numgonnamove != oldnumgonnamove) { - oldnumgonnamove = numgonnamove; - numgonnamove = 0; - for (base= FIRSTBASE; base; base= base->next) { - if (base->object->flag & OB_GONNA_MOVE) { - ++numgonnamove; - } - else if (base->flag & SELECT) { - base->object->flag |= OB_GONNA_MOVE; - ++numgonnamove; - } - else if (is_parent_gonna_move(base->object)) { - base->object->flag |= OB_GONNA_MOVE; - ++numgonnamove; - } - else if (is_constraint_target_gonna_move(base->object)) { - base->object->flag |= OB_GONNA_MOVE; - ++numgonnamove; - } - } - } - -} - -static int pose_do_update_flag(Object *ob) { - /* Figure out which pose channels need constant updating. - * Well use the bone BONE_NOCALC bit to do some temporary - * flagging (so we can reuse code), which will later be - * converted to a value for a channel... I hate this. - */ - Base *base; - bPoseChannel *chan; - int do_update = 0; - bArmature *arm; - - arm = get_armature(ob); - if (!arm) return 0; - - /* initialize */ - bone_looper(ob, arm->bonebase.first, NULL, - set_bone_nocalc); - - if (ob->pose) { - for (chan = ob->pose->chanbase.first; chan; chan=chan->next){ - if (chan->constraints.first) { - for (base= FIRSTBASE; base; base= base->next) { - if (is_ob_constraint_target(base->object, - &chan->constraints)) { - if( (base->object->flag & OB_GONNA_MOVE) || - (ob->flag & OB_GONNA_MOVE)) { - Bone *bone; - /* If this armature is selected, or if the - * object that is the target of a constraint - * is selected, then lets constantly update - * this pose channel. - */ - bone = get_named_bone(ob->data, chan->name); - if (bone) { - bone->flag &= ~BONE_NOCALC; - ++do_update; - } - } - } - } - } - } - } - - if (do_update) { - figure_bone_nocalc_core(ob, arm); - } - - bone_looper(ob, arm->bonebase.first, NULL, - bone_nocalc2chan_trans_update); - - return do_update; -} - -/* this is a confusing call, it also does the constraint update flags, but was not used... - hopefully transform refactor will take care better of it (ton) */ -static void figure_pose_updating(void) -{ - Base *base; - - flag_moving_objects(); - - for (base= FIRSTBASE; base; base= base->next) { - /* Recalculate the pose if necessary, regardless of - * whether the layer is visible or not. - */ - if (pose_do_update_flag(base->object)) { - base->flag |= BA_WHERE_UPDATE; - } - else if(base->object->flag & OB_GONNA_MOVE) { - /* if position updates, deform info could change too */ - if(base->object->hooks.first) base->flag |= BA_DISP_UPDATE; - else if(base->object->parent) { - if(base->object->parent->type==OB_LATTICE || base->object->partype==PARSKEL) - base->flag |= BA_DISP_UPDATE; - } - } - } - -} - - -/* copied from old transform, will be replaced with proper depgraph code (ton) */ -static void clear_bone_nocalc_ob(Object *ob) { - /* Let's clear no calc for all of the bones in the whole darn armature - */ - bArmature *arm; - arm = get_armature(ob); - if (arm) { - bone_looper(ob, arm->bonebase.first, NULL, - clear_bone_nocalc); - } - -} - - -/* ******************************************************************************** */ -/* ************ END, TOTALLY #@#! CODE FROM PAST TRANSFORM FOR POSEMODE *********** */ -/* ******************************************************************************** */ - -/* copied from old transform, will be replaced with proper depgraph code (ton) */ -void special_aftertrans_update(char mode, int flip, short canceled, int keyflags) +/* inserting keys, refresh ipo-keys, softbody, redraw events... (ton) */ +void special_aftertrans_update(char mode, int flip, short canceled) { Object *ob; Base *base; - MetaBall *mb; - Curve *cu; - int doit,redrawipo=0; - - - /* displaylists etc. */ + int redrawipo=0; - if(G.obedit) { - if(G.obedit->type==OB_MBALL) { - mb= G.obedit->data; - if(mb->flag != MB_UPDATE_ALWAYS) makeDispList(G.obedit); - } - else if(G.obedit->type==OB_MESH) { - if(flip) flip_editnormals(); - - recalc_editnormals(); - } - } - else if (G.obpose){ + if (G.obpose){ + bArmature *arm= G.obpose->data; bAction *act; bPose *pose; bPoseChannel *pchan; - - /* we had better clear the no calc flags on the bones - * ... else things won't look too good when changing - * frames, etc. - */ - clear_bone_nocalc_ob(G.obpose); + + arm->flag &= ~ARM_NO_ACTION; if ((G.flags & G_RECORDKEYS) && !canceled){ act=G.obpose->action; @@ -1872,123 +1407,56 @@ void special_aftertrans_update(char mode, int flip, short canceled, int keyflags if (!act) act=G.obpose->action=add_empty_action(); - collect_pose_garbage(G.obpose); - filter_pose_keys (); + set_pose_keys(G.obpose); // sets chan->flag to POSE_KEY is bone selected for (pchan=pose->chanbase.first; pchan; pchan=pchan->next){ if (pchan->flag & POSE_KEY){ - if (keyflags){ - set_action_key(act, pchan, AC_QUAT_X, 1); - set_action_key(act, pchan, AC_QUAT_Y, 1); - set_action_key(act, pchan, AC_QUAT_Z, 1); - set_action_key(act, pchan, AC_QUAT_W, 1); - } - if (keyflags){ - set_action_key(act, pchan, AC_SIZE_X, 1); - set_action_key(act, pchan, AC_SIZE_Y, 1); - set_action_key(act, pchan, AC_SIZE_Z, 1); - } - if (keyflags){ - set_action_key(act, pchan, AC_LOC_X, 1); - set_action_key(act, pchan, AC_LOC_Y, 1); - set_action_key(act, pchan, AC_LOC_Z, 1); - } + + set_action_key(act, pchan, AC_QUAT_X, 1); + set_action_key(act, pchan, AC_QUAT_Y, 1); + set_action_key(act, pchan, AC_QUAT_Z, 1); + set_action_key(act, pchan, AC_QUAT_W, 1); + + set_action_key(act, pchan, AC_SIZE_X, 1); + set_action_key(act, pchan, AC_SIZE_Y, 1); + set_action_key(act, pchan, AC_SIZE_Z, 1); + + set_action_key(act, pchan, AC_LOC_X, 1); + set_action_key(act, pchan, AC_LOC_Y, 1); + set_action_key(act, pchan, AC_LOC_Z, 1); } } - remake_action_ipos (act); allspace(REMAKEIPO, 0); allqueue(REDRAWACTION, 0); allqueue(REDRAWIPO, 0); allqueue(REDRAWNLA, 0); } - if (!canceled && is_delay_deform()){ - clear_pose_constraint_status(G.obpose); - make_displists_by_armature(G.obpose); - } - + DAG_object_flush_update(G.scene, G.obpose, OB_RECALC_DATA); } else { base= FIRSTBASE; while(base) { - ob= base->object; - - if(base->flag & BA_WHERE_UPDATE) { - - where_is_object(ob); - - if(ob->type==OB_ARMATURE && canceled) { - /* Unfortunately, sometimes when you escape - * a transform on an object that is the - * target of an IK constraint on an armature - * bone, the rotations are not restored - * correctly on the bones in the IK chain. - * There is probably a nice, elegant way to fix - * this using transdata, but this system is so - * darn confusing that we'll do it this brute - * force way instead: - */ - clear_pose_constraint_status(ob); - make_displists_by_armature(ob); - } - } - if(base->flag & BA_DISP_UPDATE) { - if(ob->type==OB_MBALL) { - mb= ob->data; - if(mb->flag != MB_UPDATE_ALWAYS || G.obedit == NULL) makeDispList(ob); - } - if( give_parteff(ob) ) build_particle_system(ob); - } if(base->flag & BA_DO_IPO) redrawipo= 1; - - if(mode=='s' && ob->type==OB_FONT) { - doit= 0; - cu= ob->data; - - if(cu->bevobj && (cu->bevobj->flag & SELECT) ) doit= 1; - else if(cu->taperobj && (cu->taperobj->flag & SELECT) ) doit= 1; - else if(cu->textoncurve) { - if(cu->textoncurve->flag & SELECT) doit= 1; - else if(ob->flag & SELECT) doit= 1; - } - - if(doit) { - text_to_curve(ob, 0); - makeDispList(ob); - } - } - if(mode=='s' && ob->type==OB_CURVE) { - doit= 0; - cu= ob->data; - - if(cu->bevobj && (cu->bevobj->flag & SELECT) ) - makeDispList(ob); - else if(cu->taperobj && (cu->taperobj->flag & SELECT) ) - makeDispList(ob); - } - + ob= base->object; + if(ob->softflag & OB_SB_ENABLE) sbObjectReset(ob); - where_is_object(ob); /* always do, for track etc. */ - /* Set autokey if necessary */ if ((G.flags & G_RECORDKEYS) && (!canceled) && (base->flag & SELECT)){ - if (keyflags){ - insertkey(&base->object->id, OB_ROT_X); - insertkey(&base->object->id, OB_ROT_Y); - insertkey(&base->object->id, OB_ROT_Z); - } - if (keyflags){ - insertkey(&base->object->id, OB_LOC_X); - insertkey(&base->object->id, OB_LOC_Y); - insertkey(&base->object->id, OB_LOC_Z); - } - if (keyflags){ - insertkey(&base->object->id, OB_SIZE_X); - insertkey(&base->object->id, OB_SIZE_Y); - insertkey(&base->object->id, OB_SIZE_Z); - } + + insertkey(&base->object->id, OB_ROT_X); + insertkey(&base->object->id, OB_ROT_Y); + insertkey(&base->object->id, OB_ROT_Z); + + insertkey(&base->object->id, OB_LOC_X); + insertkey(&base->object->id, OB_LOC_Y); + insertkey(&base->object->id, OB_LOC_Z); + + insertkey(&base->object->id, OB_SIZE_X); + insertkey(&base->object->id, OB_SIZE_Y); + insertkey(&base->object->id, OB_SIZE_Z); remake_object_ipos (ob); allqueue(REDRAWIPO, 0); @@ -2008,14 +1476,13 @@ void special_aftertrans_update(char mode, int flip, short canceled, int keyflags allqueue(REDRAWIPO, 0); } + reset_slowparents(); + + /* note; should actually only be done for all objects when a lamp is moved... (ton) */ if(G.vd->drawtype == OB_SHADED) reshadeall_displist(); } - - - - static void createTransObject(TransInfo *t) { TransData *td = NULL; @@ -2025,9 +1492,6 @@ static void createTransObject(TransInfo *t) IpoKey *ik; ListBase elems; - /* hackish... but we have to do it somewhere */ - reset_slowparents(); - set_trans_object_base_flags(t); { @@ -2036,7 +1500,7 @@ static void createTransObject(TransInfo *t) * of the armature don't work outside of posemode * (and yes, I know it's confusing ...). */ - figure_pose_updating(); + //figure_pose_updating(); } /* count */ @@ -2086,7 +1550,7 @@ static void createTransObject(TransInfo *t) float cfraont; int ipoflag; - base->flag |= BA_DO_IPO+BA_WASSEL; + base->flag |= BA_DO_IPO+BA_WAS_SEL; base->flag &= ~SELECT; cfraont= CFRA; diff --git a/source/blender/src/transform_generics.c b/source/blender/src/transform_generics.c index 438f7864cf3..5fbd3028c60 100755 --- a/source/blender/src/transform_generics.c +++ b/source/blender/src/transform_generics.c @@ -51,7 +51,6 @@ #include "DNA_camera_types.h" #include "DNA_curve_types.h" #include "DNA_effect_types.h" -#include "DNA_ika_types.h" #include "DNA_image_types.h" #include "DNA_ipo_types.h" #include "DNA_key_types.h" @@ -85,7 +84,9 @@ #include "BKE_anim.h" #include "BKE_armature.h" #include "BKE_curve.h" +#include "BKE_depsgraph.h" #include "BKE_displist.h" +#include "BKE_depsgraph.h" #include "BKE_global.h" #include "BKE_ipo.h" #include "BKE_lattice.h" @@ -140,99 +141,34 @@ void getViewVector(float coord[3], float vec[3]) { /* ************************** GENERICS **************************** */ -static int pose_flags_reset_done(Object *ob) { - /* Clear the constraint done status for every pose channe; - * that has been flagged as needing constant updating - */ - bPoseChannel *chan; - int numreset = 0; - - if (ob->pose) { - for (chan = ob->pose->chanbase.first; chan; chan=chan->next){ - if (chan->flag & PCHAN_TRANS_UPDATE) { - chan->flag &= ~PCHAN_DONE; - numreset++; - } - - } - } - return numreset; -} - - /* called for objects updating while transform acts, once per redraw */ void recalcData(TransInfo *t) { Base *base; if(G.obpose) { - TransData *td= t->data; - bPoseChannel *chan; - int i; - - if (!G.obpose->pose) G.obpose->pose= MEM_callocN(sizeof(bPose), "pose"); - - /* Make channels for the transforming bones (in posemode) */ - for (i=0; i<t->total; i++, td++) { - chan = MEM_callocN (sizeof (bPoseChannel), "transPoseChannel"); - - if (t->mode == TFM_ROTATION || t->mode == TFM_TRACKBALL) { - chan->flag |= POSE_ROT; - memcpy (chan->quat, td->ext->quat, sizeof (chan->quat)); - } - if (t->mode == TFM_TRANSLATION) { - chan->flag |= POSE_LOC; - memcpy (chan->loc, td->loc, sizeof (chan->loc)); - } - if (t->mode == TFM_RESIZE) { - chan->flag |= POSE_SIZE; - memcpy (chan->size, td->ext->size, sizeof (chan->size)); - } - - strcpy (chan->name, ((Bone*) td->ext->bone)->name); - - set_pose_channel (G.obpose->pose, chan); - - } - - clear_pose_constraint_status(G.obpose); - - if (!is_delay_deform()) make_displists_by_armature(G.obpose); - + if (!is_delay_deform()) + DAG_object_flush_update(G.scene, G.obpose, OB_RECALC_DATA); /* sets recalc flags */ + } else if (G.obedit) { + if (G.obedit->type == OB_MESH) { + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); /* sets recalc flags */ + recalc_editnormals(); - makeDispList(G.obedit); } else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) { + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); /* sets recalc flags */ + Nurb *nu= editNurb.first; while(nu) { test2DNurb(nu); testhandlesNurb(nu); /* test for bezier too */ nu= nu->next; } - makeDispList(G.obedit); - - makeBevelList(G.obedit); // might be needed for deform - calc_curvepath(G.obedit); - - // deform, bevel, taper - base= FIRSTBASE; - while(base) { - if(base->lay & G.vd->lay) { - if(base->object->parent==G.obedit && base->object->partype==PARSKEL) - makeDispList(base->object); - else if(base->object->type==OB_CURVE) { - Curve *cu= base->object->data; - if(G.obedit==cu->bevobj || G.obedit==cu->taperobj) - makeDispList(base->object); - } - } - base= base->next; - } } - else if(G.obedit->type==OB_ARMATURE){ + else if(G.obedit->type==OB_ARMATURE){ /* no recalc flag, does pose */ EditBone *ebo; /* Ensure all bones are correctly adjusted */ @@ -251,27 +187,23 @@ void recalcData(TransInfo *t) } } else if(G.obedit->type==OB_LATTICE) { + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); /* sets recalc flags */ if(editLatt->flag & LT_OUTSIDE) outside_lattice(editLatt); - - base= FIRSTBASE; - while(base) { - if(base->lay & G.vd->lay) { - if(base->object->parent==G.obedit) { - makeDispList(base->object); - } - } - base= base->next; - } } - else if (G.obedit->type == OB_MBALL) { - makeDispList(G.obedit); - } } else { base= FIRSTBASE; while(base) { + /* this flag is from depgraph, was stored in nitialize phase, handled in drawview.c */ + if(base->flag & BA_HAS_RECALC_OB) + base->object->recalc |= OB_RECALC_OB; + if(base->flag & BA_HAS_RECALC_DATA) + base->object->recalc |= OB_RECALC_DATA; + + /* thanks to ob->ctime usage, ipos are not called in where_is_object, + unless we edit ipokeys */ if(base->flag & BA_DO_IPO) { if(base->object->ipo) { IpoCurve *icu; @@ -285,45 +217,11 @@ void recalcData(TransInfo *t) } } } - if(base->object->partype & PARSLOW) { - base->object->partype -= PARSLOW; - where_is_object(base->object); - base->object->partype |= PARSLOW; - } - else if(base->flag & BA_WHERE_UPDATE) { - where_is_object(base->object); - } base= base->next; } - - base= FIRSTBASE; - while(base) { - - if(base->flag & BA_DISP_UPDATE) makeDispList(base->object); - - base= base->next; - } } - /* ugly stuff for posemode, copied from old system */ - base= FIRSTBASE; - while(base) { - - if (pose_flags_reset_done(base->object)) { - if (!is_delay_deform()) - make_displists_by_armature(base->object); - } - - base= base->next; - } - - if (G.obpose && G.obpose->type == OB_ARMATURE) - clear_pose_constraint_status(G.obpose); - - if (!is_delay_deform()) make_displists_by_armature(G.obpose); - - /* update shaded drawmode while transform */ if(G.vd->drawtype == OB_SHADED) reshadeall_displist(); diff --git a/source/blender/src/transform_manipulator.c b/source/blender/src/transform_manipulator.c index e06fa1aa37e..ecabe7e4add 100644 --- a/source/blender/src/transform_manipulator.c +++ b/source/blender/src/transform_manipulator.c @@ -47,6 +47,7 @@ #include "MEM_guardedalloc.h" #include "DNA_armature_types.h" +#include "DNA_action_types.h" #include "DNA_curve_types.h" #include "DNA_lattice_types.h" #include "DNA_mesh_types.h" @@ -132,35 +133,21 @@ static void calc_tw_center(float *co) VecAddf(twcent, twcent, co); } -/* callback */ -static void stats_pose(ListBase *lb, float *normal, float *plane) +/* for pose mode */ +static void stats_pose(bPoseChannel *pchan, float *normal, float *plane) { - Bone *bone; - float vec[3], mat[4][4]; - - for(bone= lb->first; bone; bone= bone->next) { - if (bone->flag & BONE_SELECTED) { - /* We don't let IK children get "grabbed" */ - /* ALERT! abusive global Trans here */ - if ( (Trans.mode!=TFM_TRANSLATION) || (bone->flag & BONE_IK_TOPARENT)==0 ) { - - get_bone_root_pos (bone, vec, 1); - - calc_tw_center(vec); - where_is_bone(G.obpose, bone); - get_objectspace_bone_matrix(bone, mat, 1, 1); // points in negative Y o_O - - VecAddf(normal, normal, mat[2]); - VecAddf(plane, plane, mat[1]); + Bone *bone= pchan->bone; + + if(bone) { + if (bone->flag & BONE_TRANSFORM) { + calc_tw_center(pchan->pose_head); - return; // see above function - } + VecAddf(normal, normal, pchan->pose_mat[2]); + VecAddf(plane, plane, pchan->pose_mat[1]); } - stats_pose(&bone->childbase, normal, plane); } } - /* centroid, boundbox, of selection */ /* returns total items selected */ int calc_manipulator_stats(ScrArea *sa) @@ -346,18 +333,22 @@ int calc_manipulator_stats(ScrArea *sa) } else if(G.obpose) { bArmature *arm= G.obpose->data; + bPoseChannel *pchan; ob= G.obpose; if((ob->lay & G.vd->lay)==0) return 0; Trans.mode= TFM_ROTATION; // mislead counting bones... bah - /* count total */ - count_bone_select(&Trans, &arm->bonebase, &totsel); + /* count total, we use same method as transform will do */ + Trans.total= 0; + count_bone_select(&Trans, &arm->bonebase, 1); + totsel= Trans.total; if(totsel) { - /* recursive get stats */ - stats_pose(&arm->bonebase, normal, plane); - + /* use channels to get stats */ + for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { + stats_pose(pchan, normal, plane); + } //VecMulf(normal, -1.0); VecMulf(plane, -1.0); diff --git a/source/blender/src/vpaint.c b/source/blender/src/vpaint.c index 8f08ababb9b..b85010ce646 100644 --- a/source/blender/src/vpaint.c +++ b/source/blender/src/vpaint.c @@ -274,7 +274,6 @@ void make_vertexcol() /* single ob */ freedisplist(&(ob->disp)); - allqueue(REDRAWBUTSEDIT, 0); allqueue(REDRAWVIEW3D, 0); } @@ -794,7 +793,6 @@ void weight_paint(void) extern float editbutvweight; DispList *dl; - if((G.f & G_WEIGHTPAINT)==0) return; if(G.obedit) return; if(G.obpose) return; diff --git a/source/blender/yafray/intern/yafray_Render.h b/source/blender/yafray/intern/yafray_Render.h index 92125ec6bd2..8d9086d03cc 100644 --- a/source/blender/yafray/intern/yafray_Render.h +++ b/source/blender/yafray/intern/yafray_Render.h @@ -15,7 +15,6 @@ extern "C" { #include "DNA_curve_types.h" #include "DNA_effect_types.h" #include "DNA_group_types.h" -#include "DNA_ika_types.h" #include "DNA_image_types.h" #include "DNA_key_types.h" #include "DNA_lamp_types.h" diff --git a/source/gameengine/Converter/BL_ActionActuator.cpp b/source/gameengine/Converter/BL_ActionActuator.cpp index 22ee2371e8c..7f870e368bd 100644 --- a/source/gameengine/Converter/BL_ActionActuator.cpp +++ b/source/gameengine/Converter/BL_ActionActuator.cpp @@ -59,18 +59,18 @@ BL_ActionActuator::~BL_ActionActuator() { if (m_pose) { - clear_pose(m_pose); +// clear_pose(m_pose); MEM_freeN(m_pose); m_pose = NULL; }; if (m_userpose){ - clear_pose(m_userpose); +// clear_pose(m_userpose); MEM_freeN(m_userpose); m_userpose=NULL; } if (m_blendpose) { - clear_pose(m_blendpose); +// clear_pose(m_blendpose); MEM_freeN(m_blendpose); m_blendpose = NULL; }; @@ -363,12 +363,12 @@ bool BL_ActionActuator::Update(double curtime, bool frame) obj->GetPose(&m_pose); /* Override the necessary channels with ones from the action */ - get_pose_from_action(&m_pose, m_action, m_localtime); + extract_pose_from_action(m_pose, m_action, m_localtime); /* Perform the user override (if any) */ if (m_userpose){ - get_pose_from_pose(&m_pose, m_userpose); - clear_pose(m_userpose); + extract_pose_from_pose(m_pose, m_userpose); +// clear_pose(m_userpose); MEM_freeN(m_userpose); m_userpose = NULL; } @@ -847,10 +847,8 @@ PyObject* BL_ActionActuator::PySetChannel(PyObject* self, { /* DO IT HERE */ - bPoseChannel *pchan; + bPoseChannel *pchan= verify_pose_channel(m_userpose, string); - pchan = (bPoseChannel*) MEM_callocN(sizeof(bPoseChannel), "userChannel"); - strcpy(pchan->name, string); Mat4ToQuat(matrix, pchan->quat); Mat4ToSize(matrix, pchan->size); VECCOPY (pchan->loc, matrix[3]); @@ -860,9 +858,6 @@ PyObject* BL_ActionActuator::PySetChannel(PyObject* self, if (!m_userpose){ m_userpose = (bPose*)MEM_callocN(sizeof(bPose), "userPose"); } - - verify_pose_channel(m_userpose, string); - set_pose_channel(m_userpose, pchan); } Py_INCREF(Py_None); diff --git a/source/gameengine/Converter/BL_ArmatureObject.cpp b/source/gameengine/Converter/BL_ArmatureObject.cpp index 82f97fe9c18..2db6e079c31 100644 --- a/source/gameengine/Converter/BL_ArmatureObject.cpp +++ b/source/gameengine/Converter/BL_ArmatureObject.cpp @@ -68,7 +68,7 @@ void BL_ArmatureObject::ProcessReplica(BL_ArmatureObject *replica) BL_ArmatureObject::~BL_ArmatureObject() { if (m_mrdPose){ - clear_pose(m_mrdPose); +// clear_pose(m_mrdPose); MEM_freeN(m_mrdPose); } } @@ -76,11 +76,11 @@ BL_ArmatureObject::~BL_ArmatureObject() void BL_ArmatureObject::ApplyPose() { if (m_pose){ - apply_pose_armature(GetArmature(), m_pose, 1); +// apply_pose_armature(GetArmature(), m_pose, 1); if (!m_mrdPose) copy_pose (&m_mrdPose, m_pose, 0); else - get_pose_from_pose(&m_mrdPose, m_pose); + extract_pose_from_pose(m_mrdPose, m_pose); } } @@ -126,7 +126,7 @@ void BL_ArmatureObject::GetPose(bPose **pose) if (!*pose) copy_pose(pose, m_pose, 0); else - get_pose_from_pose(pose, m_pose); + extract_pose_from_pose(*pose, m_pose); } @@ -142,7 +142,7 @@ void BL_ArmatureObject::GetMRDPose(bPose **pose) if (!*pose) copy_pose(pose, m_mrdPose, 0); else - get_pose_from_pose(pose, m_mrdPose); + extract_pose_from_pose(*pose, m_mrdPose); } @@ -158,9 +158,12 @@ double BL_ArmatureObject::GetLastFrame() bool BL_ArmatureObject::GetBoneMatrix(Bone* bone, MT_Matrix4x4& matrix) const { - MT_assert(verify_boneptr((bArmature*) GetArmature(), bone) && "Bone is not part of this armature."); + // ton hack + bPoseChannel *pchan= get_pose_channel(m_pose, bone->name); + +// MT_assert(verify_boneptr((bArmature*) GetArmature(), bone) && "Bone is not part of this armature."); - matrix.setValue(&bone->posemat[0][0]); + matrix.setValue(&pchan->pose_mat[0][0]); return true; } diff --git a/source/gameengine/Converter/BL_SkinDeformer.cpp b/source/gameengine/Converter/BL_SkinDeformer.cpp index d985f424f9a..ee608c7af96 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.cpp +++ b/source/gameengine/Converter/BL_SkinDeformer.cpp @@ -151,9 +151,10 @@ void BL_SkinDeformer::Update(void) /* Do all of the posing necessary */ GB_init_armature_deform (m_defbase, m_premat, m_postmat); m_armobj->ApplyPose(); - precalc_armature_posemats (m_armobj->GetArmature()); - for (Bone *curBone=(Bone*)m_armobj->GetArmature()->bonebase.first; curBone; curBone=(Bone*)curBone->next) - precalc_bone_defmat(curBone); +// precalc_armature_posemats (m_armobj->GetArmature()); +// for (Bone *curBone=(Bone*)m_armobj->GetArmature()->bonebase.first; curBone; curBone=(Bone*)curBone->next) +// precalc_bone_defmat(curBone); +// note: where_is_pose() does it all... VerifyStorage(); diff --git a/source/nan_definitions.mk b/source/nan_definitions.mk index a01aa0c77e3..c5543a8134a 100644 --- a/source/nan_definitions.mk +++ b/source/nan_definitions.mk @@ -139,7 +139,7 @@ endif export ID = $(shell whoami) export HOST = $(shell hostname -s) - export PY_FRAMEWORK = 1 +# export PY_FRAMEWORK = 1 ifdef PY_FRAMEWORK export NAN_PYTHON ?= /System/Library/Frameworks/Python.framework/Versions/2.3 @@ -164,7 +164,7 @@ endif export NAN_GETTEXT ?= $(LCGDIR)/gettext export NAN_SDL ?= $(LCGDIR)/sdl export NAN_SDLCFLAGS ?= -I$(NAN_SDL)/include - export NAN_SDLLIBS ?= $(NAN_SDL)/lib/libSDL.a -framework Cocoa -framework IOKit + export NAN_SDLLIBS ?= $(NAN_SDL)/lib/libSDL.a -framework Cocoa -framework IOKit # Uncomment the following line to use Mozilla inplace of netscape # CPPFLAGS +=-DMOZ_NOT_NET |