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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2010-02-28 06:44:15 +0300
committerTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2010-02-28 06:44:15 +0300
commitb21a994076e12804efe49dc35fb698a81f5a33a3 (patch)
treec6630190078ff969b5bbc8eca48235c9833eb73a /source/blender
parent07fdcb1f1b919f1359c6b77d8ae2fe08d7506a48 (diff)
parente51bcbae6230882eb2c5b16974b86a906b398408 (diff)
Merged changes in the trunk up to revision 27178.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/BKE_animsys.h6
-rw-r--r--source/blender/blenkernel/BKE_global.h2
-rw-r--r--source/blender/blenkernel/BKE_image.h3
-rw-r--r--source/blender/blenkernel/BKE_object.h5
-rw-r--r--source/blender/blenkernel/BKE_pointcache.h1
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c6
-rw-r--r--source/blender/blenkernel/intern/armature.c3
-rw-r--r--source/blender/blenkernel/intern/blender.c4
-rw-r--r--source/blender/blenkernel/intern/boids.c12
-rw-r--r--source/blender/blenkernel/intern/cloth.c2
-rw-r--r--source/blender/blenkernel/intern/collision.c18
-rw-r--r--source/blender/blenkernel/intern/constraint.c4
-rw-r--r--source/blender/blenkernel/intern/curve.c1
-rw-r--r--source/blender/blenkernel/intern/fcurve.c43
-rw-r--r--source/blender/blenkernel/intern/image.c101
-rw-r--r--source/blender/blenkernel/intern/implicit.c125
-rw-r--r--source/blender/blenkernel/intern/modifier.c23
-rw-r--r--source/blender/blenkernel/intern/object.c86
-rw-r--r--source/blender/blenkernel/intern/particle_system.c9
-rw-r--r--source/blender/blenkernel/intern/pointcache.c92
-rw-r--r--source/blender/blenkernel/intern/unit.c3
-rw-r--r--source/blender/blenkernel/intern/writeffmpeg.c2
-rw-r--r--source/blender/blenlib/BLI_dynstr.h9
-rw-r--r--source/blender/blenlib/BLI_path_util.h1
-rw-r--r--source/blender/blenlib/CMakeLists.txt2
-rw-r--r--source/blender/blenlib/SConscript2
-rw-r--r--source/blender/blenlib/intern/BLI_bfile.c30
-rw-r--r--source/blender/blenlib/intern/BLI_dynstr.c17
-rw-r--r--source/blender/blenlib/intern/Makefile2
-rw-r--r--source/blender/blenlib/intern/math_rotation.c10
-rw-r--r--source/blender/blenlib/intern/path_util.c100
-rw-r--r--source/blender/blenlib/intern/string.c7
-rw-r--r--source/blender/blenloader/intern/readfile.c20
-rw-r--r--source/blender/blenloader/intern/writefile.c6
-rw-r--r--source/blender/collada/DocumentExporter.cpp4
-rw-r--r--source/blender/editors/animation/anim_markers.c3
-rw-r--r--source/blender/editors/animation/keyingsets.c32
-rw-r--r--source/blender/editors/armature/editarmature_retarget.c4
-rw-r--r--source/blender/editors/armature/poseobject.c77
-rw-r--r--source/blender/editors/include/ED_mesh.h1
-rw-r--r--source/blender/editors/include/ED_numinput.h3
-rw-r--r--source/blender/editors/include/ED_space_api.h1
-rw-r--r--source/blender/editors/interface/interface_handlers.c2
-rw-r--r--source/blender/editors/interface/interface_templates.c22
-rw-r--r--source/blender/editors/mesh/editface.c52
-rw-r--r--source/blender/editors/object/object_ops.c12
-rw-r--r--source/blender/editors/render/Makefile6
-rw-r--r--source/blender/editors/render/SConscript4
-rw-r--r--source/blender/editors/render/render_preview.c24
-rw-r--r--source/blender/editors/space_api/spacetypes.c5
-rw-r--r--source/blender/editors/space_buttons/buttons_ops.c3
-rw-r--r--source/blender/editors/space_console/console_draw.c30
-rw-r--r--source/blender/editors/space_console/console_ops.c85
-rw-r--r--source/blender/editors/space_nla/nla_edit.c38
-rw-r--r--source/blender/editors/space_outliner/outliner.c4
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c90
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c173
-rw-r--r--source/blender/editors/transform/transform.c56
-rw-r--r--source/blender/editors/transform/transform_conversions.c8
-rw-r--r--source/blender/editors/transform/transform_generics.c3
-rw-r--r--source/blender/editors/transform/transform_orientations.c5
-rw-r--r--source/blender/editors/util/numinput.c8
-rw-r--r--source/blender/imbuf/intern/divers.c2
-rw-r--r--source/blender/makesdna/DNA_cloth_types.h3
-rw-r--r--source/blender/makesdna/DNA_scene_types.h1
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h18
-rw-r--r--source/blender/makesdna/DNA_windowmanager_types.h3
-rw-r--r--source/blender/makesrna/RNA_access.h6
-rw-r--r--source/blender/makesrna/RNA_enum_types.h1
-rw-r--r--source/blender/makesrna/intern/rna_access.c38
-rw-r--r--source/blender/makesrna/intern/rna_animation.c1
-rw-r--r--source/blender/makesrna/intern/rna_animation_api.c8
-rw-r--r--source/blender/makesrna/intern/rna_cloth.c6
-rw-r--r--source/blender/makesrna/intern/rna_curve.c14
-rw-r--r--source/blender/makesrna/intern/rna_image_api.c72
-rw-r--r--source/blender/makesrna/intern/rna_lamp.c5
-rw-r--r--source/blender/makesrna/intern/rna_main_api.c53
-rw-r--r--source/blender/makesrna/intern/rna_object.c7
-rw-r--r--source/blender/makesrna/intern/rna_pose.c2
-rw-r--r--source/blender/makesrna/intern/rna_scene.c121
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c65
-rw-r--r--source/blender/python/generic/BGL.c65
-rw-r--r--source/blender/python/generic/BGL.h37
-rw-r--r--source/blender/python/generic/matrix.c93
-rw-r--r--source/blender/python/intern/bpy_driver.c39
-rw-r--r--source/blender/python/intern/bpy_interface.c40
-rw-r--r--source/blender/python/intern/bpy_rna.c391
-rw-r--r--source/blender/python/intern/bpy_rna.h2
-rw-r--r--source/blender/python/intern/bpy_rna_callback.c111
-rw-r--r--source/blender/python/intern/bpy_rna_callback.h29
-rw-r--r--source/blender/render/intern/source/convertblender.c2
-rw-r--r--source/blender/render/intern/source/shadbuf.c3
-rw-r--r--source/blender/render/intern/source/volumetric.c2
-rw-r--r--source/blender/windowmanager/intern/wm.c7
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c28
-rw-r--r--source/blender/windowmanager/intern/wm_files.c4
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c25
98 files changed, 1846 insertions, 974 deletions
diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h
index 2f2fcfcc531..f6950ba07b8 100644
--- a/source/blender/blenkernel/BKE_animsys.h
+++ b/source/blender/blenkernel/BKE_animsys.h
@@ -70,11 +70,11 @@ void BKE_animdata_make_local(struct AnimData *adt);
/* Used to create a new 'custom' KeyingSet for the user, that will be automatically added to the stack */
struct KeyingSet *BKE_keyingset_add(struct ListBase *list, const char name[], short flag, short keyingflag);
-/* Add a destination to a KeyingSet */
-void BKE_keyingset_add_destination(struct KeyingSet *ks, struct ID *id, const char group_name[], const char rna_path[], int array_index, short flag, short groupmode);
+/* Add a path to a KeyingSet */
+void BKE_keyingset_add_path(struct KeyingSet *ks, struct ID *id, const char group_name[], const char rna_path[], int array_index, short flag, short groupmode);
/* Find the destination matching the criteria given */
-struct KS_Path *BKE_keyingset_find_destination(struct KeyingSet *ks, struct ID *id, const char group_name[], const char rna_path[], int array_index, int group_mode);
+struct KS_Path *BKE_keyingset_find_path(struct KeyingSet *ks, struct ID *id, const char group_name[], const char rna_path[], int array_index, int group_mode);
/* Copy all KeyingSets in the given list */
void BKE_keyingsets_copy(struct ListBase *newlist, struct ListBase *list);
diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h
index 3aad5a8c1e4..6084b0cfb73 100644
--- a/source/blender/blenkernel/BKE_global.h
+++ b/source/blender/blenkernel/BKE_global.h
@@ -113,7 +113,7 @@ typedef struct Global {
/* #define G_FACESELECT (1 << 8) use (mesh->editflag & ME_EDIT_PAINT_MASK) */
#define G_DEBUG (1 << 12)
-#define G_DOSCRIPTLINKS (1 << 13)
+#define G_SCRIPT_AUTOEXEC (1 << 13)
/* #define G_NOFROZEN (1 << 17) also removed */
#define G_GREASEPENCIL (1 << 17)
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index 153cf3f300e..6b22b10cf24 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -130,9 +130,6 @@ void BKE_image_assign_ibuf(struct Image *ima, struct ImBuf *ibuf);
/* called on frame change or before render */
void BKE_image_user_calc_frame(struct ImageUser *iuser, int cfra, int fieldnr);
-/* produce image export path */
-int BKE_get_image_export_path(struct Image *im, const char *dest_dir, char *abs, int abs_size, char *rel, int rel_size);
-
/* fix things in ImageUser when new image gets assigned */
void BKE_image_user_new_image(struct Image *ima, struct ImageUser *iuser);
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 703ed118a58..a6a641a3219 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -112,10 +112,13 @@ void boundbox_set_from_min_max(struct BoundBox *bb, float min[3], float max[3]);
struct BoundBox *object_get_boundbox(struct Object *ob);
void object_boundbox_flag(struct Object *ob, int flag, int set);
void minmax_object(struct Object *ob, float *min, float *max);
-void minmax_object_duplis(struct Scene *scene, struct Object *ob, float *min, float *max);
+int minmax_object_duplis(struct Scene *scene, struct Object *ob, float *min, float *max);
void solve_tracking (struct Object *ob, float targetmat[][4]);
int ray_hit_boundbox(struct BoundBox *bb, float ray_start[3], float ray_normal[3]);
+void *object_tfm_backup(struct Object *ob);
+void object_tfm_restore(struct Object *ob, void *obtfm_pt);
+
void object_handle_update(struct Scene *scene, struct Object *ob);
float give_timeoffset(struct Object *ob);
diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h
index b291d9126ee..10550ccdc05 100644
--- a/source/blender/blenkernel/BKE_pointcache.h
+++ b/source/blender/blenkernel/BKE_pointcache.h
@@ -55,6 +55,7 @@
/* File open options, for BKE_ptcache_file_open */
#define PTCACHE_FILE_READ 0
#define PTCACHE_FILE_WRITE 1
+#define PTCACHE_FILE_UPDATE 2
/* PTCacheID types */
#define PTCACHE_TYPE_SOFTBODY 0
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 7b2eea141f2..a880417a111 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -547,7 +547,7 @@ void BKE_all_animdata_fix_paths_rename (char *prefix, char *oldName, char *newNa
/* Find the first path that matches the given criteria */
// TODO: do we want some method to perform partial matches too?
-KS_Path *BKE_keyingset_find_destination (KeyingSet *ks, ID *id, const char group_name[], const char rna_path[], int array_index, int group_mode)
+KS_Path *BKE_keyingset_find_path (KeyingSet *ks, ID *id, const char group_name[], const char rna_path[], int array_index, int group_mode)
{
KS_Path *ksp;
@@ -624,7 +624,7 @@ KeyingSet *BKE_keyingset_add (ListBase *list, const char name[], short flag, sho
/* Add a destination to a KeyingSet. Nothing is returned for now...
* Checks are performed to ensure that destination is appropriate for the KeyingSet in question
*/
-void BKE_keyingset_add_destination (KeyingSet *ks, ID *id, const char group_name[], const char rna_path[], int array_index, short flag, short groupmode)
+void BKE_keyingset_add_path (KeyingSet *ks, ID *id, const char group_name[], const char rna_path[], int array_index, short flag, short groupmode)
{
KS_Path *ksp;
@@ -643,7 +643,7 @@ void BKE_keyingset_add_destination (KeyingSet *ks, ID *id, const char group_name
}
/* don't add if there is already a matching KS_Path in the KeyingSet */
- if (BKE_keyingset_find_destination(ks, id, group_name, rna_path, array_index, groupmode)) {
+ if (BKE_keyingset_find_path(ks, id, group_name, rna_path, array_index, groupmode)) {
if (G.f & G_DEBUG)
printf("ERROR: destination already exists in Keying Set \n");
return;
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 9c1e15b0f77..4903ea84b3d 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -1502,7 +1502,8 @@ void where_is_armature (bArmature *arm)
}
}
-/* if bone layer is protected, copy the data from from->pose */
+/* if bone layer is protected, copy the data from from->pose
+ * when used with linked libraries this copies from the linked pose into the local pose */
static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected)
{
bPose *pose= ob->pose, *frompose= from->pose;
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index 1567ed0f986..171b48af974 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -291,8 +291,6 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, char *filename)
if (G.f & G_SWAP_EXCHANGE) bfd->globalf |= G_SWAP_EXCHANGE;
else bfd->globalf &= ~G_SWAP_EXCHANGE;
- if ((U.flag & USER_DONT_DOSCRIPTLINKS)) bfd->globalf &= ~G_DOSCRIPTLINKS;
-
G.f= bfd->globalf;
if (!G.background) {
@@ -358,7 +356,7 @@ void BKE_userdef_free(void)
BLI_freelistN(&U.uifonts);
BLI_freelistN(&U.themes);
BLI_freelistN(&U.keymaps);
- BLI_freelistN(&U.extensions);
+ BLI_freelistN(&U.addons);
}
/* returns:
diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c
index 89c3da9b3e9..b521ec41cba 100644
--- a/source/blender/blenkernel/intern/boids.c
+++ b/source/blender/blenkernel/intern/boids.c
@@ -162,8 +162,7 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val,
else if(rule->type == eBoidRuleType_Avoid && bpa->data.mode == eBoidMode_Climbing &&
priority > 2.0f * gabr->fear_factor) {
/* detach from surface and try to fly away from danger */
- VECCOPY(efd.vec_to_point, bpa->gravity);
- mul_v3_fl(efd.vec_to_point, -1.0f);
+ negate_v3_v3(efd.vec_to_point, bpa->gravity);
}
VECCOPY(bbd->wanted_co, efd.vec_to_point);
@@ -689,7 +688,7 @@ static int rule_fight(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Parti
if(bpa->data.health/bbd->part->boids->health * bbd->part->boids->aggression < e_strength / f_strength) {
/* decide to flee */
if(closest_dist < fbr->flee_distance * fbr->distance) {
- mul_v3_fl(bbd->wanted_co, -1.0f);
+ negate_v3(bbd->wanted_co);
bbd->wanted_speed = val->max_speed;
}
else { /* wait for better odds */
@@ -1342,9 +1341,8 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
float grav[3];
/* Don't take gravity's strength in to account, */
/* otherwise amount of banking is hard to control. */
- VECCOPY(grav, ground_nor);
- mul_v3_fl(grav, -1.0f);
-
+ negate_v3_v3(grav, ground_nor);
+
project_v3_v3v3(dvec, bpa->data.acc, pa->state.vel);
sub_v3_v3v3(dvec, bpa->data.acc, dvec);
@@ -1387,7 +1385,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
VECCOPY(mat[2], bpa->gravity);
}
- mul_v3_fl(mat[2], -1.0f);
+ negate_v3(mat[2]);
cross_v3_v3v3(mat[1], mat[2], mat[0]);
/* apply rotation */
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index 86591fe784d..855de95572a 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -545,7 +545,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
implicit_set_positions(clmd);
cache->flag |= PTCACHE_SIMULATION_VALID;
}
- else if(ob->id.lib || (cache->flag & PTCACHE_BAKED)) {
+ else if( /*ob->id.lib ||*/ (cache->flag & PTCACHE_BAKED)) { /* 2.4x disabled lib, but this can be used in some cases, testing further - campbell */
/* if baked and nothing in cache, do nothing */
cache->flag &= ~PTCACHE_SIMULATION_VALID;
cache->simframe= 0;
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index b726437a874..b024ba5f4e1 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -1550,8 +1550,8 @@ static int cloth_bvh_objcollisions_resolve ( ClothModifierData * clmd, Collision
// cloth - object collisions
int cloth_bvh_objcollision (Object *ob, ClothModifierData * clmd, float step, float dt )
{
- Cloth *cloth=NULL;
- BVHTree *cloth_bvh=NULL;
+ Cloth *cloth= clmd->clothObject;
+ BVHTree *cloth_bvh= cloth->bvhtree;
int i=0, numfaces = 0, numverts = 0, k, l, j;
int rounds = 0; // result counts applied collisions; ic is for debug output;
ClothVertex *verts = NULL;
@@ -1559,16 +1559,12 @@ int cloth_bvh_objcollision (Object *ob, ClothModifierData * clmd, float step, fl
Object **collobjs = NULL;
int numcollobj = 0;
- if ( ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ ) || ! ( ( ( Cloth * ) clmd->clothObject )->bvhtree ) )
- {
+ if ((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) || cloth_bvh==NULL)
return 0;
- }
- cloth = clmd->clothObject;
verts = cloth->verts;
- cloth_bvh = ( BVHTree * ) cloth->bvhtree;
- numfaces = clmd->clothObject->numfaces;
- numverts = clmd->clothObject->numverts;
+ numfaces = cloth->numfaces;
+ numverts = cloth->numverts;
////////////////////////////////////////////////////////////
// static collisions
@@ -1672,8 +1668,8 @@ int cloth_bvh_objcollision (Object *ob, ClothModifierData * clmd, float step, fl
// collisions = 1;
verts = cloth->verts; // needed for openMP
- numfaces = clmd->clothObject->numfaces;
- numverts = clmd->clothObject->numverts;
+ numfaces = cloth->numfaces;
+ numverts = cloth->numverts;
verts = cloth->verts;
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index c22510a2527..53a07193aa6 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -1947,7 +1947,7 @@ static void pycon_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintT
/* only execute target calculation if allowed */
#ifndef DISABLE_PYTHON
- if (G.f & G_DOSCRIPTLINKS)
+ if (G.f & G_SCRIPT_AUTOEXEC)
BPY_pyconstraint_target(data, ct);
#endif
}
@@ -1963,7 +1963,7 @@ static void pycon_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targ
bPythonConstraint *data= con->data;
/* only evaluate in python if we're allowed to do so */
- if ((G.f & G_DOSCRIPTLINKS)==0) return;
+ if ((G.f & G_SCRIPT_AUTOEXEC)==0) return;
/* currently removed, until I this can be re-implemented for multiple targets */
#if 0
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 9d33bc5ae11..fb27327c3be 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -191,6 +191,7 @@ Curve *copy_curve(Curve *cu)
cun->path= 0;
cun->editnurb= NULL;
+ cun->editfont= NULL;
#if 0 // XXX old animation system
/* single user ipo too */
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index 552c7d0767d..bd29bd55428 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -326,7 +326,7 @@ FCurve *rna_get_fcurve(PointerRNA *ptr, PropertyRNA *prop, int rnaindex, bAction
}
/* threshold for binary-searching keyframes - threshold here should be good enough for now, but should become userpref */
-#define BEZT_BINARYSEARCH_THRESH 0.00001f
+#define BEZT_BINARYSEARCH_THRESH 0.01f /* was 0.00001, but giving errors */
/* Binary search algorithm for finding where to insert BezTriple. (for use by insert_bezt_fcurve)
* Returns the index to insert at (data already at that index will be offset if replace is 0)
@@ -801,13 +801,19 @@ typedef struct DriverVarTypeInfo {
/* ......... */
+static ID *dtar_id_ensure_proxy_from(ID *id)
+{
+ if (id && GS(id->name)==ID_OB && ((Object *)id)->proxy_from)
+ return (ID *)(((Object *)id)->proxy_from);
+ return id;
+}
+
/* Helper function to obtain a value using RNA from the specified source (for evaluating drivers) */
static float dtar_get_prop_val (ChannelDriver *driver, DriverTarget *dtar)
{
PointerRNA id_ptr, ptr;
PropertyRNA *prop;
ID *id;
- char *path;
int index;
float value= 0.0f;
@@ -815,22 +821,22 @@ static float dtar_get_prop_val (ChannelDriver *driver, DriverTarget *dtar)
if ELEM(NULL, driver, dtar)
return 0.0f;
- /* get RNA-pointer for the ID-block given in target */
- RNA_id_pointer_create(dtar->id, &id_ptr);
- id= dtar->id;
- path= dtar->rna_path;
+ id= dtar_id_ensure_proxy_from(dtar->id);
/* error check for missing pointer... */
// TODO: tag the specific target too as having issues
if (id == NULL) {
printf("Error: driver has an invalid target to use \n");
- if (G.f & G_DEBUG) printf("\tpath = %s\n", path);
+ if (G.f & G_DEBUG) printf("\tpath = %s\n", dtar->rna_path);
driver->flag |= DRIVER_FLAG_INVALID;
return 0.0f;
}
+ /* get RNA-pointer for the ID-block given in target */
+ RNA_id_pointer_create(id, &id_ptr);
+
/* get property to read from, and get value as appropriate */
- if (RNA_path_resolve_full(&id_ptr, path, &ptr, &prop, &index)) {
+ if (RNA_path_resolve_full(&id_ptr, dtar->rna_path, &ptr, &prop, &index)) {
switch (RNA_property_type(prop)) {
case PROP_BOOLEAN:
if (RNA_property_array_length(&ptr, prop))
@@ -859,7 +865,7 @@ static float dtar_get_prop_val (ChannelDriver *driver, DriverTarget *dtar)
}
else {
if (G.f & G_DEBUG)
- printf("Driver Evaluation Error: cannot resolve target for %s -> %s \n", id->name, path);
+ printf("Driver Evaluation Error: cannot resolve target for %s -> %s \n", id->name, dtar->rna_path);
driver->flag |= DRIVER_FLAG_INVALID;
return 0.0f;
@@ -871,13 +877,16 @@ static float dtar_get_prop_val (ChannelDriver *driver, DriverTarget *dtar)
/* Helper function to obtain a pointer to a Pose Channel (for evaluating drivers) */
static bPoseChannel *dtar_get_pchan_ptr (ChannelDriver *driver, DriverTarget *dtar)
{
+ ID *id;
/* sanity check */
if ELEM(NULL, driver, dtar)
return NULL;
-
+
+ id= dtar_id_ensure_proxy_from(dtar->id);
+
/* check if the ID here is a valid object */
- if ((dtar->id) && GS(dtar->id->name)) {
- Object *ob= (Object *)dtar->id;
+ if (id && GS(id->name)) {
+ Object *ob= (Object *)id;
/* get pose, and subsequently, posechannel */
return get_pose_channel(ob->pose, dtar->pchan_name);
@@ -947,12 +956,12 @@ static float dvar_eval_locDiff (ChannelDriver *driver, DriverVar *dvar)
DRIVER_TARGETS_USED_LOOPER(dvar)
{
/* get pointer to loc values to store in */
- Object *ob= (Object *)dtar->id;
+ Object *ob= (Object *)dtar_id_ensure_proxy_from(dtar->id);
bPoseChannel *pchan;
float tmp_loc[3];
/* check if this target has valid data */
- if ((ob == NULL) || (GS(dtar->id->name) != ID_OB)) {
+ if ((ob == NULL) || (GS(ob->id.name) != ID_OB)) {
/* invalid target, so will not have enough targets */
driver->flag |= DRIVER_FLAG_INVALID;
return 0.0f;
@@ -1007,14 +1016,14 @@ static float dvar_eval_locDiff (ChannelDriver *driver, DriverVar *dvar)
static float dvar_eval_transChan (ChannelDriver *driver, DriverVar *dvar)
{
DriverTarget *dtar= &dvar->targets[0];
- Object *ob= (Object *)dtar->id;
+ Object *ob= (Object *)dtar_id_ensure_proxy_from(dtar->id);
bPoseChannel *pchan;
float mat[4][4];
float eul[3] = {0.0f,0.0f,0.0f};
short useEulers=0, rotOrder=ROT_MODE_EUL;
/* check if this target has valid data */
- if ((ob == NULL) || (GS(dtar->id->name) != ID_OB)) {
+ if ((ob == NULL) || (GS(ob->id.name) != ID_OB)) {
/* invalid target, so will not have enough targets */
driver->flag |= DRIVER_FLAG_INVALID;
return 0.0f;
@@ -1281,7 +1290,7 @@ ChannelDriver *fcurve_copy_driver (ChannelDriver *driver)
float driver_get_variable_value (ChannelDriver *driver, DriverVar *dvar)
{
DriverVarTypeInfo *dvti;
-
+
/* sanity check */
if (ELEM(NULL, driver, dvar))
return 0.0f;
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index d6edb068fa0..accadb3d434 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -2260,104 +2260,3 @@ void BKE_image_user_calc_frame(ImageUser *iuser, int cfra, int fieldnr)
if(iuser->ok==0) iuser->ok= 1;
}
}
-
-/*
- Produce image export path.
-
- Fails returning 0 if image filename is empty or if destination path
- matches image path (i.e. both are the same file).
-
- Trailing slash in dest_dir is optional.
-
- Logic:
-
- - if an image is "below" current .blend file directory, rebuild the
- same dir structure in dest_dir
-
- For example //textures/foo/bar.png becomes
- [dest_dir]/textures/foo/bar.png.
-
- - if an image is not "below" current .blend file directory,
- disregard it's path and copy it in the same directory where 3D file
- goes.
-
- For example //../foo/bar.png becomes [dest_dir]/bar.png.
-
- This logic will help ensure that all image paths are relative and
- that a user gets his images in one place. It'll also provide
- consistent behaviour across exporters.
- */
-int BKE_get_image_export_path(struct Image *im, const char *dest_dir, char *abs, int abs_size, char *rel, int rel_size)
-{
- char path[FILE_MAX];
- char dir[FILE_MAX];
- char base[FILE_MAX];
- char blend_dir[FILE_MAX]; /* directory, where current .blend file resides */
- char dest_path[FILE_MAX];
- char rel_dir[FILE_MAX];
- int len;
-
- if (abs)
- abs[0]= 0;
-
- if (rel)
- rel[0]= 0;
-
- BLI_split_dirfile_basic(G.sce, blend_dir, NULL);
-
- if (!strlen(im->name)) {
- if (G.f & G_DEBUG) printf("Invalid image type.\n");
- return 0;
- }
-
- BLI_strncpy(path, im->name, sizeof(path));
-
- /* expand "//" in filename and get absolute path */
- BLI_convertstringcode(path, G.sce);
-
- /* get the directory part */
- BLI_split_dirfile_basic(path, dir, base);
-
- len= strlen(blend_dir);
-
- rel_dir[0] = 0;
-
- /* if image is "below" current .blend file directory */
- if (!strncmp(path, blend_dir, len)) {
-
- /* if image is _in_ current .blend file directory */
- if (!strcmp(dir, blend_dir)) {
- BLI_join_dirfile(dest_path, dest_dir, base);
- }
- /* "below" */
- else {
- /* rel = image_path_dir - blend_dir */
- BLI_strncpy(rel_dir, dir + len, sizeof(rel_dir));
-
- BLI_join_dirfile(dest_path, dest_dir, rel_dir);
- BLI_join_dirfile(dest_path, dest_path, base);
- }
-
- }
- /* image is out of current directory */
- else {
- BLI_join_dirfile(dest_path, dest_dir, base);
- }
-
- if (abs)
- BLI_strncpy(abs, dest_path, abs_size);
-
- if (rel) {
- strncat(rel, rel_dir, rel_size);
- strncat(rel, base, rel_size);
- }
-
- /* return 2 if src=dest */
- if (!strcmp(path, dest_path)) {
- if (G.f & G_DEBUG) printf("%s and %s are the same file\n", path, dest_path);
- return 2;
- }
-
- return 1;
-}
-
diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c
index ed3e7348d7e..6912a65886a 100644
--- a/source/blender/blenkernel/intern/implicit.c
+++ b/source/blender/blenkernel/intern/implicit.c
@@ -1408,19 +1408,29 @@ typedef struct HairGridVert {
float velocity[3];
float density;
} HairGridVert;
+#define HAIR_GRID_INDEX(vec, min, max, axis) (int)( (vec[axis] - min[axis]) / (max[axis] - min[axis]) * 9.99f );
/* Smoothing of hair velocities:
* adapted from
Volumetric Methods for Simulation and Rendering of Hair
by Lena Petrovic, Mark Henne and John Anderson
* Pixar Technical Memo #06-08, Pixar Animation Studios
*/
-static void hair_velocity_smoothing(float smoothfac, lfVector *lF, lfVector *lX, lfVector *lV, int numverts)
+static void hair_velocity_smoothing(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVector *lV, int numverts)
{
- /* TODO: this is an initial implementation and should be made much better in due time */
+ /* TODO: This is an initial implementation and should be made much better in due time.
+ * What should at least be implemented is a grid size parameter and a smoothing kernel
+ * for bigger grids.
+ */
/* 10x10x10 grid gives nice initial results */
HairGridVert grid[10][10][10];
+ HairGridVert colg[10][10][10];
+ ListBase *colliders = get_collider_cache(clmd->scene, NULL);
+ ColliderCache *col = NULL;
float gmin[3], gmax[3], density;
+ /* 2.0f is an experimental value that seems to give good results */
+ float smoothfac = 2.0f * clmd->sim_parms->velocity_smooth;
+ float collfac = 2.0f * clmd->sim_parms->collider_friction;
int v = 0;
int i = 0;
int j = 0;
@@ -1439,15 +1449,20 @@ static void hair_velocity_smoothing(float smoothfac, lfVector *lF, lfVector *lX,
grid[i][j][k].velocity[1] = 0.0f;
grid[i][j][k].velocity[2] = 0.0f;
grid[i][j][k].density = 0.0f;
+
+ colg[i][j][k].velocity[0] = 0.0f;
+ colg[i][j][k].velocity[1] = 0.0f;
+ colg[i][j][k].velocity[2] = 0.0f;
+ colg[i][j][k].density = 0.0f;
}
}
}
/* gather velocities & density */
- for(v = 0; v < numverts; v++) {
- i = (int)( (lX[v][0] - gmin[0]) / (gmax[0] - gmin[0]) * 9.99f );
- j = (int)( (lX[v][1] - gmin[1]) / (gmax[1] - gmin[1]) * 9.99f );
- k = (int)( (lX[v][2] - gmin[2]) / (gmax[2] - gmin[2]) * 9.99f );
+ if(smoothfac > 0.0f) for(v = 0; v < numverts; v++) {
+ i = HAIR_GRID_INDEX(lX[v], gmin, gmax, 0);
+ j = HAIR_GRID_INDEX(lX[v], gmin, gmax, 1);
+ k = HAIR_GRID_INDEX(lX[v], gmin, gmax, 2);
grid[i][j][k].velocity[0] += lV[v][0];
grid[i][j][k].velocity[1] += lV[v][1];
@@ -1455,6 +1470,36 @@ static void hair_velocity_smoothing(float smoothfac, lfVector *lF, lfVector *lX,
grid[i][j][k].density += 1.0f;
}
+ /* gather colliders */
+ if(colliders && collfac > 0.0f) for(col = colliders->first; col; col = col->next)
+ {
+ MVert *loc0 = col->collmd->x;
+ MVert *loc1 = col->collmd->xnew;
+ float vel[3];
+
+ for(v=0; v<col->collmd->numverts; v++, loc0++, loc1++) {
+ i = HAIR_GRID_INDEX(loc1->co, gmin, gmax, 0);
+
+ if(i>=0 && i<10) {
+ j = HAIR_GRID_INDEX(loc1->co, gmin, gmax, 1);
+
+ if(j>=0 && j<10) {
+ k = HAIR_GRID_INDEX(loc1->co, gmin, gmax, 2);
+
+ if(k>=0 && k<10) {
+ VECSUB(vel, loc1->co, loc0->co);
+
+ colg[i][j][k].velocity[0] += vel[0];
+ colg[i][j][k].velocity[1] += vel[1];
+ colg[i][j][k].velocity[2] += vel[2];
+ colg[i][j][k].density += 1.0;
+ }
+ }
+ }
+ }
+ }
+
+
/* divide velocity with density */
for(i = 0; i < 10; i++) {
for(j = 0; j < 10; j++) {
@@ -1465,21 +1510,35 @@ static void hair_velocity_smoothing(float smoothfac, lfVector *lF, lfVector *lX,
grid[i][j][k].velocity[1] /= density;
grid[i][j][k].velocity[2] /= density;
}
+
+ density = colg[i][j][k].density;
+ if(density > 0.0f) {
+ colg[i][j][k].velocity[0] /= density;
+ colg[i][j][k].velocity[1] /= density;
+ colg[i][j][k].velocity[2] /= density;
+ }
}
}
}
/* calculate forces */
for(v = 0; v < numverts; v++) {
- i = (int)( (lX[v][0] - gmin[0]) / (gmax[0] - gmin[0]) * 9.99f );
- j = (int)( (lX[v][1] - gmin[1]) / (gmax[1] - gmin[1]) * 9.99f );
- k = (int)( (lX[v][2] - gmin[2]) / (gmax[2] - gmin[2]) * 9.99f );
-
- /* 2.0f is an experimental value that seems to give good results */
- lF[v][0] += 2.0f * smoothfac * (grid[i][j][k].velocity[0] - lV[v][0]);
- lF[v][1] += 2.0f * smoothfac * (grid[i][j][k].velocity[1] - lV[v][1]);
- lF[v][2] += 2.0f * smoothfac * (grid[i][j][k].velocity[2] - lV[v][2]);
+ i = HAIR_GRID_INDEX(lX[v], gmin, gmax, 0);
+ j = HAIR_GRID_INDEX(lX[v], gmin, gmax, 1);
+ k = HAIR_GRID_INDEX(lX[v], gmin, gmax, 2);
+
+ lF[v][0] += smoothfac * (grid[i][j][k].velocity[0] - lV[v][0]);
+ lF[v][1] += smoothfac * (grid[i][j][k].velocity[1] - lV[v][1]);
+ lF[v][2] += smoothfac * (grid[i][j][k].velocity[2] - lV[v][2]);
+
+ if(colg[i][j][k].density > 0.0f) {
+ lF[v][0] += collfac * (colg[i][j][k].velocity[0] - lV[v][0]);
+ lF[v][1] += collfac * (colg[i][j][k].velocity[1] - lV[v][1]);
+ lF[v][2] += collfac * (colg[i][j][k].velocity[2] - lV[v][2]);
+ }
}
+
+ free_collider_cache(&colliders);
}
static void cloth_calc_force(ClothModifierData *clmd, float frame, lfVector *lF, lfVector *lX, lfVector *lV, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, ListBase *effectors, float time, fmatrix3x3 *M)
{
@@ -1508,8 +1567,8 @@ static void cloth_calc_force(ClothModifierData *clmd, float frame, lfVector *lF,
init_lfvector(lF, gravity, numverts);
- if(clmd->sim_parms->velocity_smooth > 0.0f)
- hair_velocity_smoothing(clmd->sim_parms->velocity_smooth, lF, lX, lV, numverts);
+ if(clmd->sim_parms->velocity_smooth > 0.0f || clmd->sim_parms->collider_friction > 0.0f)
+ hair_velocity_smoothing(clmd, lF, lX, lV, numverts);
/* multiply lF with mass matrix
// force = mass * acceleration (in this case: gravity)
@@ -1579,6 +1638,36 @@ static void cloth_calc_force(ClothModifierData *clmd, float frame, lfVector *lF,
VECADDS(lF[mfaces[i].v4], lF[mfaces[i].v4], tmp, factor);
}
}
+
+ /* Hair has only edges */
+ if(cloth->numfaces == 0) {
+ ClothSpring *spring;
+ float edgevec[3]={0,0,0}; //edge vector
+ float edgeunnormal[3]={0,0,0}; // not-normalized-edge normal
+ float tmp[3]={0,0,0};
+ float factor = 0.01;
+
+ search = cloth->springs;
+ while(search) {
+ spring = search->link;
+
+ if(spring->type == CLOTH_SPRING_TYPE_STRUCTURAL) {
+ VECSUB(edgevec, (float*)lX[spring->ij], (float*)lX[spring->kl]);
+
+ project_v3_v3v3(tmp, winvec[spring->ij], edgevec);
+ VECSUB(edgeunnormal, winvec[spring->ij], tmp);
+ /* hair doesn't stretch too much so we can use restlen pretty safely */
+ VECADDS(lF[spring->ij], lF[spring->ij], edgeunnormal, spring->restlen * factor);
+
+ project_v3_v3v3(tmp, winvec[spring->kl], edgevec);
+ VECSUB(edgeunnormal, winvec[spring->kl], tmp);
+ VECADDS(lF[spring->kl], lF[spring->kl], edgeunnormal, spring->restlen * factor);
+ }
+
+ search = search->next;
+ }
+ }
+
del_lfvector(winvec);
}
@@ -1689,8 +1778,8 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
VECCOPY(verts[i].txold, id->X[i]);
}
-
- if(clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED)
+
+ if(clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED && clmd->clothObject->bvhtree)
{
float temp = clmd->sim_parms->stepsPerFrame;
/* not too nice hack, but collisions need this correction -jahka */
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index ff00dc9dc3c..146701f2976 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -353,15 +353,14 @@ static void latticeModifier_updateDepgraph(ModifierData *md, DagForest *forest,
static void modifier_vgroup_cache(ModifierData *md, float (*vertexCos)[3])
{
- md= md->next;
- if(md) {
- if(md->type==eModifierType_Armature) {
- ArmatureModifierData *amd = (ArmatureModifierData*) md;
- if(amd->multi)
- amd->prevCos= MEM_dupallocN(vertexCos);
- }
- /* lattice/mesh modifier too */
+ while((md=md->next) && md->type==eModifierType_Armature) {
+ ArmatureModifierData *amd = (ArmatureModifierData*) md;
+ if(amd->multi && amd->prevCos==NULL)
+ amd->prevCos= MEM_dupallocN(vertexCos);
+ else
+ break;
}
+ /* lattice/mesh modifier too */
}
@@ -4826,9 +4825,15 @@ static void castModifier_deformVerts(
ModifierData *md, Object *ob, DerivedMesh *derivedData,
float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
{
- DerivedMesh *dm = get_dm(md->scene, ob, NULL, derivedData, NULL, 0);
+ DerivedMesh *dm = NULL;
CastModifierData *cmd = (CastModifierData *)md;
+ if (ob->type == OB_MESH) {
+ /* DerivedMesh is used only in case object is MESH */
+ /* so we could optimize modifier applying by skipping DM creation */
+ dm = get_dm(md->scene, ob, NULL, derivedData, NULL, 0);
+ }
+
if (cmd->type == MOD_CAST_TYPE_CUBOID) {
castModifier_cuboid_do(cmd, ob, dm, vertexCos, numVerts);
} else { /* MOD_CAST_TYPE_SPHERE or MOD_CAST_TYPE_CYLINDER */
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 88aaf054aec..46c26524f47 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -2373,27 +2373,97 @@ void minmax_object(Object *ob, float *min, float *max)
}
}
-/* TODO - use dupli objects bounding boxes */
-void minmax_object_duplis(Scene *scene, Object *ob, float *min, float *max)
+int minmax_object_duplis(Scene *scene, Object *ob, float *min, float *max)
{
+ int ok= 0;
if ((ob->transflag & OB_DUPLI)==0) {
- return;
+ return ok;
} else {
ListBase *lb;
DupliObject *dob;
lb= object_duplilist(scene, ob);
for(dob= lb->first; dob; dob= dob->next) {
- if(dob->no_draw);
- else {
- /* should really use bound box of dup object */
- DO_MINMAX(dob->mat[3], min, max);
+ if(dob->no_draw == 0) {
+ BoundBox *bb= object_get_boundbox(dob->ob);
+
+ if(bb) {
+ int i;
+ for(i=0; i<8; i++) {
+ float vec[3];
+ mul_v3_m4v3(vec, dob->mat, bb->vec[i]);
+ DO_MINMAX(vec, min, max);
+ }
+
+ ok= 1;
+ }
}
}
free_object_duplilist(lb); /* does restore */
}
-}
+ return ok;
+}
+
+/* copied from DNA_object_types.h */
+typedef struct ObTfmBack {
+ float loc[3], dloc[3], orig[3];
+ float size[3], dsize[3]; /* scale and delta scale */
+ float rot[3], drot[3]; /* euler rotation */
+ float quat[4], dquat[4]; /* quaternion rotation */
+ float rotAxis[3], drotAxis[3]; /* axis angle rotation - axis part */
+ float rotAngle, drotAngle; /* axis angle rotation - angle part */
+ float obmat[4][4]; /* final worldspace matrix with constraints & animsys applied */
+ float parentinv[4][4]; /* inverse result of parent, so that object doesn't 'stick' to parent */
+ float constinv[4][4]; /* inverse result of constraints. doesn't include effect of parent or object local transform */
+ float imat[4][4]; /* inverse matrix of 'obmat' for during render, old game engine, temporally: ipokeys of transform */
+} ObTfmBack;
+
+void *object_tfm_backup(Object *ob)
+{
+ ObTfmBack *obtfm= MEM_mallocN(sizeof(ObTfmBack), "ObTfmBack");
+ copy_v3_v3(obtfm->loc, ob->loc);
+ copy_v3_v3(obtfm->dloc, ob->dloc);
+ copy_v3_v3(obtfm->orig, ob->orig);
+ copy_v3_v3(obtfm->size, ob->size);
+ copy_v3_v3(obtfm->dsize, ob->dsize);
+ copy_v3_v3(obtfm->rot, ob->rot);
+ copy_v3_v3(obtfm->drot, ob->drot);
+ copy_qt_qt(obtfm->quat, ob->quat);
+ copy_qt_qt(obtfm->dquat, ob->dquat);
+ copy_v3_v3(obtfm->rotAxis, ob->rotAxis);
+ copy_v3_v3(obtfm->drotAxis, ob->drotAxis);
+ obtfm->rotAngle= ob->rotAngle;
+ obtfm->drotAngle= ob->drotAngle;
+ copy_m4_m4(obtfm->obmat, ob->obmat);
+ copy_m4_m4(obtfm->parentinv, ob->parentinv);
+ copy_m4_m4(obtfm->constinv, ob->constinv);
+ copy_m4_m4(obtfm->imat, ob->imat);
+
+ return (void *)obtfm;
+}
+
+void object_tfm_restore(Object *ob, void *obtfm_pt)
+{
+ ObTfmBack *obtfm= (ObTfmBack *)obtfm_pt;
+ copy_v3_v3(ob->loc, obtfm->loc);
+ copy_v3_v3(ob->dloc, obtfm->dloc);
+ copy_v3_v3(ob->orig, obtfm->orig);
+ copy_v3_v3(ob->size, obtfm->size);
+ copy_v3_v3(ob->dsize, obtfm->dsize);
+ copy_v3_v3(ob->rot, obtfm->rot);
+ copy_v3_v3(ob->drot, obtfm->drot);
+ copy_qt_qt(ob->quat, obtfm->quat);
+ copy_qt_qt(ob->dquat, obtfm->dquat);
+ copy_v3_v3(ob->rotAxis, obtfm->rotAxis);
+ copy_v3_v3(ob->drotAxis, obtfm->drotAxis);
+ ob->rotAngle= obtfm->rotAngle;
+ ob->drotAngle= obtfm->drotAngle;
+ copy_m4_m4(ob->obmat, obtfm->obmat);
+ copy_m4_m4(ob->parentinv, obtfm->parentinv);
+ copy_m4_m4(ob->constinv, obtfm->constinv);
+ copy_m4_m4(ob->imat, obtfm->imat);
+}
/* proxy rule: lib_object->proxy_from == the one we borrow from, only set temporal and cleared here */
/* local_object->proxy == pointer to library object, saved in files and read */
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index a4784fc606d..9b1d48ac8c3 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -1056,6 +1056,8 @@ static int psys_threads_init_distribution(ParticleThread *threads, Scene *scene,
cpa->num=-1;
}
}
+ /* dmcache must be updated for parent particles if children from faces is used */
+ psys_calc_dmcache(ob, finaldm, psys);
return 0;
}
@@ -1820,8 +1822,7 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime,
project_v3_v3v3(dvec, r_vel, pa->state.ave);
sub_v3_v3v3(mat[0], pa->state.ave, dvec);
normalize_v3(mat[0]);
- VECCOPY(mat[2], r_vel);
- mul_v3_fl(mat[2], -1.0f);
+ negate_v3_v3(mat[2], r_vel);
normalize_v3(mat[2]);
cross_v3_v3v3(mat[1], mat[2], mat[0]);
@@ -3313,6 +3314,8 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
if(pa->alive==PARS_UNBORN
&& (part->flag & PART_UNBORN || cfra + psys->pointcache->step > pa->time))
reset_particle(sim, pa, dtime, cfra);
+ else if(part->phystype == PART_PHYS_NO)
+ reset_particle(sim, pa, dtime, cfra);
if(dfra>0.0 && ELEM(pa->alive,PARS_ALIVE,PARS_DYING)){
switch(part->phystype){
@@ -3805,7 +3808,7 @@ static void system_step(ParticleSimulationData *sim, float cfra)
pa->alive = PARS_ALIVE;
}
}
- else if(cfra != startframe && (sim->ob->id.lib || (cache->flag & PTCACHE_BAKED))) {
+ else if(cfra != startframe && ( /*sim->ob->id.lib ||*/ (cache->flag & PTCACHE_BAKED))) { /* 2.4x disabled lib, but this can be used in some cases, testing further - campbell */
psys_reset(psys, PSYS_RESET_CACHE_MISS);
psys->cfra=cfra;
psys->recalc = 0;
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 6859aba57c9..b1319a81f5d 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -203,9 +203,9 @@ static int ptcache_write_particle(int index, void *psys_v, void **data)
ParticleData *pa = psys->particles + index;
BoidParticle *boid = (psys->part->phystype == PART_PHYS_BOIDS) ? pa->boid : NULL;
float times[3] = {pa->time, pa->dietime, pa->lifetime};
+ int step = psys->pointcache->step;
if(data[BPHYS_DATA_INDEX]) {
- int step = psys->pointcache->step;
/* No need to store unborn or died particles */
if(pa->time - step > pa->state.time || pa->dietime + step < pa->state.time)
return 0;
@@ -222,7 +222,8 @@ static int ptcache_write_particle(int index, void *psys_v, void **data)
if(boid)
PTCACHE_DATA_FROM(data, BPHYS_DATA_BOIDS, &boid->data);
- return 1;
+ /* return flag 1+1=2 for newly born particles to copy exact birth location to previously cached frame */
+ return 1 + (pa->state.time >= pa->time && pa->prev_state.time <= pa->time);
}
void BKE_ptcache_make_particle_key(ParticleKey *key, int index, void **data, float time)
{
@@ -249,6 +250,10 @@ static void ptcache_read_particle(int index, void *psys_v, void **data, float fr
BKE_ptcache_make_particle_key(&pa->state, 0, data, cfra);
+ /* set frames cached before birth to birth time */
+ if(cfra < pa->time)
+ pa->state.time = pa->time;
+
if(data[BPHYS_DATA_SIZE])
PTCACHE_DATA_TO(data, BPHYS_DATA_SIZE, 0, &pa->size);
@@ -1148,6 +1153,9 @@ static PTCacheFile *ptcache_file_open(PTCacheID *pid, int mode, int cfra)
} else if (mode==PTCACHE_FILE_WRITE) {
BLI_make_existing_file(filename); /* will create the dir if needs be, same as //textures is created */
fp = fopen(filename, "wb");
+ } else if (mode==PTCACHE_FILE_UPDATE) {
+ BLI_make_existing_file(filename);
+ fp = fopen(filename, "rb+");
}
if (!fp)
@@ -1253,6 +1261,18 @@ static void ptcache_file_init_pointers(PTCacheFile *pf)
pf->cur[BPHYS_DATA_BOIDS] = data_types & (1<<BPHYS_DATA_BOIDS) ? &pf->data.boids : NULL;
}
+static void ptcache_file_seek_pointers(int index, PTCacheFile *pf)
+{
+ int i, size=0;
+ int data_types = pf->data_types;
+
+ for(i=0; i<BPHYS_TOT_DATA; i++)
+ size += pf->data_types & (1<<i) ? ptcache_data_size[i] : 0;
+
+ ptcache_file_init_pointers(pf);
+ /* size of default header + data up to index */
+ fseek(pf->fp, 8 + 3*sizeof(int) + index * size, SEEK_SET);
+}
void BKE_ptcache_mem_init_pointers(PTCacheMem *pm)
{
int data_types = pm->data_types;
@@ -1271,6 +1291,14 @@ void BKE_ptcache_mem_incr_pointers(PTCacheMem *pm)
pm->cur[i] = (char*)pm->cur[i] + ptcache_data_size[i];
}
}
+void BKE_ptcache_mem_seek_pointers(int index, PTCacheMem *pm)
+{
+ int data_types = pm->data_types;
+ int i;
+
+ for(i=0; i<BPHYS_TOT_DATA; i++)
+ pm->cur[i] = data_types & (1<<i) ? (char*)pm->data[i] + index * ptcache_data_size[i] : NULL;
+}
static void ptcache_alloc_data(PTCacheMem *pm)
{
int data_types = pm->data_types;
@@ -1453,7 +1481,7 @@ int BKE_ptcache_read_cache(PTCacheID *pid, float cfra, float frs_sec)
else if(pid->read_header(pf2)) {
ptcache_file_init_pointers(pf2);
totpoint2 = pf2->totpoint;
- index2 = pf->data_types & BPHYS_DATA_INDEX ? &pf2->data.index : &i;
+ index2 = pf2->data_types & BPHYS_DATA_INDEX ? &pf2->data.index : &i;
}
}
else {
@@ -1615,7 +1643,7 @@ int BKE_ptcache_read_cache(PTCacheID *pid, float cfra, float frs_sec)
int BKE_ptcache_write_cache(PTCacheID *pid, int cfra)
{
PointCache *cache = pid->cache;
- PTCacheFile *pf= NULL;
+ PTCacheFile *pf= NULL, *pf2= NULL;
int i;
int totpoint = pid->totpoint(pid->calldata);
int add = 0, overwrite = 0;
@@ -1625,7 +1653,7 @@ int BKE_ptcache_write_cache(PTCacheID *pid, int cfra)
return 0;
if(cache->flag & PTCACHE_DISK_CACHE) {
- int efra = cache->endframe;
+ int ofra, efra = cache->endframe;
if(cfra==0)
add = 1;
@@ -1636,7 +1664,6 @@ int BKE_ptcache_write_cache(PTCacheID *pid, int cfra)
add = 1;
}
else {
- int ofra;
/* find last cached frame */
while(efra > cache->startframe && !BKE_ptcache_id_exist(pid, efra))
efra--;
@@ -1679,11 +1706,36 @@ int BKE_ptcache_write_cache(PTCacheID *pid, int cfra)
}
else
for(i=0; i<totpoint; i++) {
- if(pid->write_elem && pid->write_elem(i, pid->calldata, pf->cur))
- if(!ptcache_file_write_data(pf)) {
- ptcache_file_close(pf);
- return 0;
+ if(pid->write_elem) {
+ int write = pid->write_elem(i, pid->calldata, pf->cur);
+ if(write) {
+ if(!ptcache_file_write_data(pf)) {
+ ptcache_file_close(pf);
+ if(pf2) ptcache_file_close(pf2);
+ return 0;
+ }
+ /* newly born particles have to be copied to previous cached frame */
+ else if(overwrite && write == 2) {
+ if(!pf2) {
+ pf2 = ptcache_file_open(pid, PTCACHE_FILE_UPDATE, ofra);
+ if(!pf2) {
+ ptcache_file_close(pf);
+ return 0;
+ }
+ pf2->type = pid->type;
+ pf2->totpoint = totpoint;
+ pf2->data_types = pid->data_types;
+ }
+ ptcache_file_seek_pointers(i, pf2);
+ pid->write_elem(i, pid->calldata, pf2->cur);
+ if(!ptcache_file_write_data(pf2)) {
+ ptcache_file_close(pf);
+ ptcache_file_close(pf2);
+ return 0;
+ }
+ }
}
+ }
}
}
}
@@ -1728,8 +1780,19 @@ int BKE_ptcache_write_cache(PTCacheID *pid, int cfra)
BKE_ptcache_mem_init_pointers(pm);
for(i=0; i<totpoint; i++) {
- if(pid->write_elem && pid->write_elem(i, pid->calldata, pm->cur))
- BKE_ptcache_mem_incr_pointers(pm);
+ if(pid->write_elem) {
+ int write = pid->write_elem(i, pid->calldata, pm->cur);
+ if(write) {
+ BKE_ptcache_mem_incr_pointers(pm);
+
+ /* newly born particles have to be copied to previous cached frame */
+ if(overwrite && write == 2) {
+ pm2 = cache->mem_cache.last;
+ BKE_ptcache_mem_seek_pointers(i, pm2);
+ pid->write_elem(i, pid->calldata, pm2->cur);
+ }
+ }
+ }
}
//ptcache_make_index_array(pm, pid->totpoint(pid->calldata));
@@ -1748,8 +1811,9 @@ int BKE_ptcache_write_cache(PTCacheID *pid, int cfra)
cache->flag |= PTCACHE_FRAMES_SKIPPED;
}
- if(pf)
- ptcache_file_close(pf);
+ if(pf) ptcache_file_close(pf);
+
+ if(pf2) ptcache_file_close(pf2);
BKE_ptcache_update_info(pid);
diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c
index 22dc5a15650..a16c1956cc4 100644
--- a/source/blender/blenkernel/intern/unit.c
+++ b/source/blender/blenkernel/intern/unit.c
@@ -170,7 +170,8 @@ static void unit_dual_convert(double value, bUnitCollection *usys,
{
bUnitDef *unit= unit_best_fit(value, usys, NULL, 1);
- *value_a= floor(value/unit->scalar) * unit->scalar;
+ if(value < 0.0) *value_a= -floor(-value/unit->scalar) * unit->scalar;
+ else *value_a= floor( value/unit->scalar) * unit->scalar;
*value_b= value - (*value_a);
*unit_a= unit;
diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c
index 917ecd044ea..6e94602c0c9 100644
--- a/source/blender/blenkernel/intern/writeffmpeg.c
+++ b/source/blender/blenkernel/intern/writeffmpeg.c
@@ -880,7 +880,7 @@ int append_ffmpeg(RenderData *rd, int frame, int *pixels, int rectx, int recty,
}
}
- write_audio_frames(frame / (((double)rd->frs_sec) / rd->frs_sec_base));
+ write_audio_frames((frame - rd->sfra) / (((double)rd->frs_sec) / rd->frs_sec_base));
return success;
}
diff --git a/source/blender/blenlib/BLI_dynstr.h b/source/blender/blenlib/BLI_dynstr.h
index 8544b451b65..c5158264e72 100644
--- a/source/blender/blenlib/BLI_dynstr.h
+++ b/source/blender/blenlib/BLI_dynstr.h
@@ -60,6 +60,15 @@ DynStr* BLI_dynstr_new (void);
*/
void BLI_dynstr_append (DynStr *ds, const char *cstr);
+/**
+ * Append a length clamped c-string to a DynStr.
+ *
+ * @param ds The DynStr to append to.
+ * @param cstr The c-string to append.
+ * @param len The maximum length of the c-string to copy.
+ */
+void BLI_dynstr_nappend (DynStr *ds, const char *cstr, int len);
+
/**
* Append a c-string to a DynStr, but with formatting like printf.
*
diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h
index 9e494de5379..9b4084aa172 100644
--- a/source/blender/blenlib/BLI_path_util.h
+++ b/source/blender/blenlib/BLI_path_util.h
@@ -59,6 +59,7 @@ void BLI_make_existing_file(char *name);
void BLI_split_dirfile(char *string, char *dir, char *file);
void BLI_split_dirfile_basic(const char *string, char *dir, char *file);
void BLI_join_dirfile(char *string, const char *dir, const char *file);
+int BKE_rebase_path(char *abs, int abs_size, char *rel, int rel_size, const char *base_dir, const char *src_dir, const char *dest_dir);
void BLI_getlastdir(const char* dir, char *last, int maxlen);
int BLI_testextensie(const char *str, const char *ext);
void BLI_uniquename(struct ListBase *list, void *vlink, const char defname[], char delim, short name_offs, short len);
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index b534087f32c..fec5f1803eb 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -28,7 +28,7 @@ FILE(GLOB SRC intern/*.c)
SET(INC
. ../makesdna ../blenkernel ../../../intern/guardedalloc ../include
- ../gpu
+ ../gpu ../../../intern/ghost
${FREETYPE_INCLUDE_DIRS}
${ZLIB_INC}
)
diff --git a/source/blender/blenlib/SConscript b/source/blender/blenlib/SConscript
index df1a096cb99..090094a834d 100644
--- a/source/blender/blenlib/SConscript
+++ b/source/blender/blenlib/SConscript
@@ -4,7 +4,7 @@ Import ('env')
sources = env.Glob('intern/*.c')
cflags=''
-incs = '. ../makesdna ../blenkernel #/intern/guardedalloc ../editors/include ../gpu'
+incs = '. ../makesdna ../blenkernel #/intern/guardedalloc #/intern/ghost ../editors/include ../gpu'
incs += ' ' + env['BF_FREETYPE_INC']
incs += ' ' + env['BF_ZLIB_INC']
defs = ''
diff --git a/source/blender/blenlib/intern/BLI_bfile.c b/source/blender/blenlib/intern/BLI_bfile.c
index 9540b16d2f4..3306283ad3f 100644
--- a/source/blender/blenlib/intern/BLI_bfile.c
+++ b/source/blender/blenlib/intern/BLI_bfile.c
@@ -46,6 +46,8 @@
#include "BLI_storage.h"
#include "BLI_bfile.h"
+#include "GHOST_C-api.h"
+
/* Internal bfile classification flags */
#define BCF_OPEN (0)
#define BCF_FOPEN (1<<0)
@@ -54,6 +56,11 @@
#define BCF_AT_END (1<<3)
#define BCF_DISCARD (1<<4)
+/* Standard files names */
+#define LAST_SESSION_FILE "last-session"
+#define ENVIRONMENT_FILE "environment"
+
+
/* Declaration of internal functions */
void chomp(char* line);
void expand_envvars(char* src, char* dst);
@@ -221,19 +228,6 @@ void BLI_bfile_set_error(BFILE *bfile, int error) {
}
-#if defined(WIN32)
- #define LAST_SESSION_FILE "%HOME%\\Blender\\last-session FIXME FIXME FIXME"
- #define ENVIRONMENT_FILE "FIXME"
- #define SHARED_DIRECTORY "FIXME TOO"
-#elif defined(OSX)
- #define LAST_SESSION_FILE "${HOME}/Library/Application Support/Blender/last-session"
- #define ENVIRONMENT_FILE "${HOME}/Library/Application Support/Blender/${BLENDER_VERSION}/environment"
- #define SHARED_DIRECTORY "/Library/Application Support/Blender"
-#else
- #define LAST_SESSION_FILE "${HOME}/.blender/last-session"
- #define ENVIRONMENT_FILE "${HOME}/.blender/${BLENDER_VERSION}/environment"
- #define SHARED_DIRECTORY "/usr/share/blender"
-#endif
void BLI_bfile_init_vars() {
char file[MAXPATHLEN];
char temp[MAXPATHLEN];
@@ -249,10 +243,12 @@ void BLI_bfile_init_vars() {
if(BLI_exist(temp)) {
BLI_setenv_if_new("BLENDER_SHARE", dirname(bprogname));
} else {
- BLI_setenv_if_new("BLENDER_SHARE", SHARED_DIRECTORY);
+ BLI_setenv_if_new("BLENDER_SHARE", (const char*)GHOST_getSystemDir());
}
- expand_envvars(LAST_SESSION_FILE, file);
+ strcpy(file, (const char*)GHOST_getUserDir());
+ BLI_add_slash(file);
+ strcat(file, LAST_SESSION_FILE);
fp = fopen(file, "r");
/* 1st line, read previous version */
if (fp && (fscanf(fp, "%3c\n", temp) == 1)) {
@@ -283,7 +279,9 @@ void BLI_bfile_init_vars() {
}
/* Load vars from user and system files */
- expand_envvars(ENVIRONMENT_FILE, file);
+ strcpy(file, (const char *)GHOST_getUserDir());
+ BLI_add_slash(file);
+ strcat(file, ENVIRONMENT_FILE);
init_vars_from_file(file);
sprintf(temp, "/%d/environment", BLENDER_VERSION);
BLI_make_file_string("/", file, getenv("BLENDER_SHARE"), temp);
diff --git a/source/blender/blenlib/intern/BLI_dynstr.c b/source/blender/blenlib/intern/BLI_dynstr.c
index 02c7ff2e9e5..4b7b61e64d9 100644
--- a/source/blender/blenlib/intern/BLI_dynstr.c
+++ b/source/blender/blenlib/intern/BLI_dynstr.c
@@ -83,6 +83,23 @@ void BLI_dynstr_append(DynStr *ds, const char *cstr) {
ds->curlen+= cstrlen;
}
+void BLI_dynstr_nappend(DynStr *ds, const char *cstr, int len) {
+ DynStrElem *dse= malloc(sizeof(*dse));
+ int cstrlen= BLI_strnlen(cstr, len);
+
+ dse->str= malloc(cstrlen+1);
+ memcpy(dse->str, cstr, cstrlen);
+ dse->str[cstrlen] = '\0';
+ dse->next= NULL;
+
+ if (!ds->last)
+ ds->last= ds->elems= dse;
+ else
+ ds->last= ds->last->next= dse;
+
+ ds->curlen+= cstrlen;
+}
+
void BLI_dynstr_vappendf(DynStr *ds, const char *format, va_list args)
{
char *message, fixedmessage[256];
diff --git a/source/blender/blenlib/intern/Makefile b/source/blender/blenlib/intern/Makefile
index d8aed3ac0ed..7ef44aff881 100644
--- a/source/blender/blenlib/intern/Makefile
+++ b/source/blender/blenlib/intern/Makefile
@@ -52,6 +52,8 @@ CPPFLAGS += -I$(NAN_ZLIB)/include
CPPFLAGS += -I../../gpu
+CPPFLAGS += -I$(NAN_GHOST)/include
+
ifdef NAN_PTHREADS
CPPFLAGS += -I$(NAN_PTHREADS)/include
endif
diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c
index 8d5684a3ac8..a92f80e35c7 100644
--- a/source/blender/blenlib/intern/math_rotation.c
+++ b/source/blender/blenlib/intern/math_rotation.c
@@ -1333,8 +1333,14 @@ void mat4_to_dquat(DualQuat *dq,float basemat[][4], float mat[][4])
if((determinant_m4(mat) < 0.0f) || len_v3(dscale) > 1e-4) {
/* extract R and S */
- mat4_to_quat(basequat,baseRS);
- quat_to_mat4(baseR,basequat);
+ float tmp[4][4];
+
+ /* extra orthogonalize, to avoid flipping with stretched bones */
+ copy_m4_m4(tmp, baseRS);
+ orthogonalize_m4(tmp, 1);
+ mat4_to_quat(basequat, tmp);
+
+ quat_to_mat4(baseR, basequat);
copy_v3_v3(baseR[3], baseRS[3]);
invert_m4_m4(baseinv, basemat);
diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c
index 1bf321ec1bc..fe43960b770 100644
--- a/source/blender/blenlib/intern/path_util.c
+++ b/source/blender/blenlib/intern/path_util.c
@@ -1320,6 +1320,106 @@ void BLI_join_dirfile(char *string, const char *dir, const char *file)
}
}
+
+/*
+ Produce image export path.
+
+ Fails returning 0 if image filename is empty or if destination path
+ matches image path (i.e. both are the same file).
+
+ Trailing slash in dest_dir is optional.
+
+ Logic:
+
+ - if an image is "below" current .blend file directory, rebuild the
+ same dir structure in dest_dir
+
+ For example //textures/foo/bar.png becomes
+ [dest_dir]/textures/foo/bar.png.
+
+ - if an image is not "below" current .blend file directory,
+ disregard it's path and copy it in the same directory where 3D file
+ goes.
+
+ For example //../foo/bar.png becomes [dest_dir]/bar.png.
+
+ This logic will help ensure that all image paths are relative and
+ that a user gets his images in one place. It'll also provide
+ consistent behaviour across exporters.
+ */
+int BKE_rebase_path(char *abs, int abs_size, char *rel, int rel_size, const char *base_dir, const char *src_dir, const char *dest_dir)
+{
+ char path[FILE_MAX];
+ char dir[FILE_MAX];
+ char base[FILE_MAX];
+ char blend_dir[FILE_MAX]; /* directory, where current .blend file resides */
+ char dest_path[FILE_MAX];
+ char rel_dir[FILE_MAX];
+ int len;
+
+ if (abs)
+ abs[0]= 0;
+
+ if (rel)
+ rel[0]= 0;
+
+ BLI_split_dirfile_basic(base_dir, blend_dir, NULL);
+
+ if (src_dir[0]=='\0')
+ return 0;
+
+ BLI_strncpy(path, src_dir, sizeof(path));
+
+ /* expand "//" in filename and get absolute path */
+ BLI_convertstringcode(path, base_dir);
+
+ /* get the directory part */
+ BLI_split_dirfile_basic(path, dir, base);
+
+ len= strlen(blend_dir);
+
+ rel_dir[0] = 0;
+
+ /* if image is "below" current .blend file directory */
+ if (!strncmp(path, blend_dir, len)) {
+
+ /* if image is _in_ current .blend file directory */
+ if (!strcmp(dir, blend_dir)) {
+ BLI_join_dirfile(dest_path, dest_dir, base);
+ }
+ /* "below" */
+ else {
+ /* rel = image_path_dir - blend_dir */
+ BLI_strncpy(rel_dir, dir + len, sizeof(rel_dir));
+
+ BLI_join_dirfile(dest_path, dest_dir, rel_dir);
+ BLI_join_dirfile(dest_path, dest_path, base);
+ }
+
+ }
+ /* image is out of current directory */
+ else {
+ BLI_join_dirfile(dest_path, dest_dir, base);
+ }
+
+ if (abs)
+ BLI_strncpy(abs, dest_path, abs_size);
+
+ if (rel) {
+ strncat(rel, rel_dir, rel_size);
+ strncat(rel, base, rel_size);
+ }
+
+ /* return 2 if src=dest */
+ if (!strcmp(path, dest_path)) {
+ // if (G.f & G_DEBUG) printf("%s and %s are the same file\n", path, dest_path);
+ return 2;
+ }
+
+ return 1;
+}
+
+
static int add_win32_extension(char *name)
{
int retval = 0;
diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c
index bf2e1d28b3a..dd1d0a3bd4f 100644
--- a/source/blender/blenlib/intern/string.c
+++ b/source/blender/blenlib/intern/string.c
@@ -342,3 +342,10 @@ void BLI_timestr(double _time, char *str)
str[11]=0;
}
+
+/* determine the length of a fixed-size string */
+size_t BLI_strnlen(const char *str, size_t maxlen)
+{
+ const char *end = memchr(str, '\0', maxlen);
+ return end ? (size_t) (end - str) : maxlen;
+}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index a34507d85f2..2c8a8869ddd 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -32,6 +32,7 @@
#include <limits.h>
#include <stdio.h> // for printf fopen fwrite fclose sprintf FILE
#include <stdlib.h> // for getenv atoi
+#include <stddef.h> // for offsetof
#include <fcntl.h> // for open
#include <string.h> // for strrchr strncmp strstr
#include <math.h> // for fabs
@@ -10694,7 +10695,7 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
link_list(fd, &user->themes);
link_list(fd, &user->keymaps);
- link_list(fd, &user->extensions);
+ link_list(fd, &user->addons);
for(keymap=user->keymaps.first; keymap; keymap=keymap->next) {
keymap->modal_items= NULL;
@@ -10887,20 +10888,9 @@ char *bhead_id_name(FileData *fd, BHead *bhead)
static ID *is_yet_read(FileData *fd, Main *mainvar, BHead *bhead)
{
- ListBase *lb;
- char *idname= bhead_id_name(fd, bhead);
-
- lb= wich_libbase(mainvar, GS(idname));
-
- if(lb) {
- ID *id= lb->first;
- while(id) {
- if( strcmp(id->name, idname)==0 )
- return id;
- id= id->next;
- }
- }
- return NULL;
+ const char *idname= bhead_id_name(fd, bhead);
+ /* wich_libbase can be NULL, intentionally not using idname+2 */
+ return BLI_findstring(wich_libbase(mainvar, GS(idname)), idname, offsetof(ID, name));
}
static void expand_doit(FileData *fd, Main *mainvar, void *old)
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 1cd68ec6f04..66815f5316f 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -542,7 +542,7 @@ static void write_userdef(WriteData *wd)
bTheme *btheme;
wmKeyMap *keymap;
wmKeyMapItem *kmi;
- bExtension *bext;
+ bAddon *bext;
writestruct(wd, USER, "UserDef", 1, &U);
@@ -560,8 +560,8 @@ static void write_userdef(WriteData *wd)
}
}
- for(bext= U.extensions.first; bext; bext=bext->next)
- writestruct(wd, DATA, "bExtension", 1, bext);
+ for(bext= U.addons.first; bext; bext=bext->next)
+ writestruct(wd, DATA, "bAddon", 1, bext);
}
static void write_boid_state(WriteData *wd, BoidState *state)
diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp
index 4b35499fb62..3e1898a64d9 100644
--- a/source/blender/collada/DocumentExporter.cpp
+++ b/source/blender/collada/DocumentExporter.cpp
@@ -1435,9 +1435,9 @@ public:
BLI_split_dirfile_basic(mfilename, dir, NULL);
- BKE_get_image_export_path(image, dir, abs, sizeof(abs), rel, sizeof(rel));
+ BKE_rebase_path(abs, sizeof(abs), rel, sizeof(rel), G.sce, image->name, dir);
- if (strlen(abs)) {
+ if (abs[0] != '\0') {
// make absolute source path
BLI_strncpy(src, image->name, sizeof(src));
diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c
index e6280a2556c..efdb9008014 100644
--- a/source/blender/editors/animation/anim_markers.c
+++ b/source/blender/editors/animation/anim_markers.c
@@ -436,6 +436,7 @@ static int ed_marker_move_init(bContext *C, wmOperator *op)
initNumInput(&mm->num);
mm->num.idx_max = 0; /* one axis */
mm->num.flag |= NUM_NO_FRACTION;
+ mm->num.increment = 1.0f;
for (a=0, marker= markers->first; marker; marker= marker->next) {
if (marker->flag & SELECT) {
@@ -617,7 +618,7 @@ static int ed_marker_move_modal(bContext *C, wmOperator *op, wmEvent *evt)
float vec[3];
char str_tx[256];
- if (handleNumInput(&mm->num, evt, 1.0))
+ if (handleNumInput(&mm->num, evt))
{
applyNumInput(&mm->num, vec);
outputNumInput(&mm->num, str_tx);
diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c
index f1d84fb1066..63323a8519d 100644
--- a/source/blender/editors/animation/keyingsets.c
+++ b/source/blender/editors/animation/keyingsets.c
@@ -355,7 +355,7 @@ static int add_keyingset_button_exec (bContext *C, wmOperator *op)
}
/* add path to this setting */
- BKE_keyingset_add_destination(ks, ptr.id.data, NULL, path, index, pflag, KSP_GROUP_KSNAME);
+ BKE_keyingset_add_path(ks, ptr.id.data, NULL, path, index, pflag, KSP_GROUP_KSNAME);
ks->active_path= BLI_countlist(&ks->paths);
success= 1;
@@ -426,7 +426,7 @@ static int remove_keyingset_button_exec (bContext *C, wmOperator *op)
KS_Path *ksp;
/* try to find a path matching this description */
- ksp= BKE_keyingset_find_destination(ks, ptr.id.data, ks->name, path, index, KSP_GROUP_KSNAME);
+ ksp= BKE_keyingset_find_path(ks, ptr.id.data, ks->name, path, index, KSP_GROUP_KSNAME);
if (ksp) {
/* just free it... */
@@ -1162,31 +1162,13 @@ static int keyingset_relative_get_templates (KeyingSet *ks)
return templates;
}
-/* Check if context data is suitable for the given absolute Keying Set */
+/* Check if context data is suitable for the given Keying Set */
short keyingset_context_ok_poll (bContext *C, KeyingSet *ks)
{
- ScrArea *sa= CTX_wm_area(C);
-
- /* data retrieved from context depends on active editor */
- if (sa == NULL) return 0;
-
- switch (sa->spacetype) {
- case SPACE_VIEW3D:
- {
- Object *obact= CTX_data_active_object(C);
-
- /* if in posemode, check if 'pose-channels' requested for in KeyingSet */
- if ((obact && obact->pose) && (obact->mode & OB_MODE_POSE)) {
- /* check for posechannels */
-
- }
- else {
- /* check for selected object */
-
- }
- }
- break;
- }
+ // TODO:
+ // For 'relative' keyingsets (i.e. py-keyingsets), add a call here
+ // which basically gets a listing of all the paths to be used for this
+ // set.
return 1;
diff --git a/source/blender/editors/armature/editarmature_retarget.c b/source/blender/editors/armature/editarmature_retarget.c
index a9be4b346f0..b3960c3cfd5 100644
--- a/source/blender/editors/armature/editarmature_retarget.c
+++ b/source/blender/editors/armature/editarmature_retarget.c
@@ -186,12 +186,12 @@ float rollBoneByQuatAligned(EditBone *bone, float old_up_axis[3], float qrot[4],
if (dot_v3v3(new_up_axis, x_axis) < 0)
{
- mul_v3_fl(x_axis, -1);
+ negate_v3(x_axis);
}
if (dot_v3v3(new_up_axis, z_axis) < 0)
{
- mul_v3_fl(z_axis, -1);
+ negate_v3(z_axis);
}
if (angle_normalized_v3v3(x_axis, new_up_axis) < angle_normalized_v3v3(z_axis, new_up_axis))
diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c
index c49ad2a768a..0170241c6c2 100644
--- a/source/blender/editors/armature/poseobject.c
+++ b/source/blender/editors/armature/poseobject.c
@@ -52,6 +52,7 @@
#include "DNA_userdef_types.h"
#include "BKE_anim.h"
+#include "BKE_idprop.h"
#include "BKE_animsys.h"
#include "BKE_action.h"
#include "BKE_armature.h"
@@ -840,6 +841,15 @@ static bPose *g_posebuf = NULL;
void free_posebuf(void)
{
if (g_posebuf) {
+ bPoseChannel *pchan;
+
+ for (pchan= g_posebuf->chanbase.first; pchan; pchan= pchan->next) {
+ if(pchan->prop) {
+ IDP_FreeProperty(pchan->prop);
+ MEM_freeN(pchan->prop);
+ }
+ }
+
/* was copied without constraints */
BLI_freelistN(&g_posebuf->chanbase);
MEM_freeN(g_posebuf);
@@ -891,7 +901,8 @@ void POSE_OT_copy (wmOperatorType *ot)
/* Pointers to the builtin KeyingSets that we want to use */
static KeyingSet *posePaste_ks_locrotscale = NULL; /* the only keyingset we'll need */
-/* ---- */
+/* transform.h */
+extern void autokeyframe_pose_cb_func(struct bContext *C, struct Scene *scene, struct View3D *v3d, struct Object *ob, int tmode, short targetless_ik);
static int pose_paste_exec (bContext *C, wmOperator *op)
{
@@ -1002,33 +1013,55 @@ static int pose_paste_exec (bContext *C, wmOperator *op)
}
}
- if (autokeyframe_cfra_can_key(scene, &ob->id)) {
- /* Set keys on pose
- * - KeyingSet to use depends on rotation mode
- * (but that's handled by the templates code)
- */
- // TODO: for getting the KeyingSet used, we should really check which channels were affected
- if (posePaste_ks_locrotscale == NULL)
- posePaste_ks_locrotscale= ANIM_builtin_keyingset_get_named(NULL, "LocRotScale");
-
- /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */
- cks.pchan= pchan;
-
- modify_keyframes(scene, &dsources, NULL, posePaste_ks_locrotscale, MODIFYKEY_MODE_INSERT, (float)CFRA);
-
- /* clear any unkeyed tags */
- if (chan->bone)
- chan->bone->flag &= ~BONE_UNKEYED;
+ /* ID property */
+ if(pchan->prop) {
+ IDP_FreeProperty(pchan->prop);
+ MEM_freeN(pchan->prop);
+ pchan->prop= NULL;
}
- else {
- /* add unkeyed tags */
- if (chan->bone)
- chan->bone->flag |= BONE_UNKEYED;
+
+ if(chan->prop) {
+ pchan->prop= IDP_CopyProperty(chan->prop);
+ }
+
+ /* auto key, TODO, fix up this INSERTAVAIL vs all other cases */
+ if (IS_AUTOKEY_FLAG(INSERTAVAIL) == 0) { /* deal with this case later */
+ if (autokeyframe_cfra_can_key(scene, &ob->id)) {
+
+ /* Set keys on pose
+ * - KeyingSet to use depends on rotation mode
+ * (but that's handled by the templates code)
+ */
+ // TODO: for getting the KeyingSet used, we should really check which channels were affected
+ if (posePaste_ks_locrotscale == NULL)
+ posePaste_ks_locrotscale= ANIM_builtin_keyingset_get_named(NULL, "LocRotScale");
+
+ /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */
+ cks.pchan= pchan;
+
+ modify_keyframes(scene, &dsources, NULL, posePaste_ks_locrotscale, MODIFYKEY_MODE_INSERT, (float)CFRA);
+
+ /* clear any unkeyed tags */
+ if (chan->bone)
+ chan->bone->flag &= ~BONE_UNKEYED;
+ }
+ else {
+ /* add unkeyed tags */
+ if (chan->bone)
+ chan->bone->flag |= BONE_UNKEYED;
+ }
}
}
}
}
+ if (IS_AUTOKEY_FLAG(INSERTAVAIL)) {
+ View3D *v3d= CTX_wm_view3d(C);
+ autokeyframe_pose_cb_func(C, scene, v3d, ob, TFM_TRANSLATION, 0);
+ autokeyframe_pose_cb_func(C, scene, v3d, ob, TFM_ROTATION, 0);
+ autokeyframe_pose_cb_func(C, scene, v3d, ob, TFM_TIME_SCALE, 0);
+ }
+
/* Update event for pose and deformation children */
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index 886da0820a2..cc875e5156f 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -178,6 +178,7 @@ int face_select(struct bContext *C, struct Object *ob, short mval[2], int extend
void face_borderselect(struct bContext *C, struct Object *ob, struct rcti *rect, int select, int extend);
void selectall_tface(struct Object *ob, int action);
void select_linked_tfaces(struct bContext *C, struct Object *ob, short mval[2], int mode);
+int minmax_tface(struct Object *ob, float *min, float *max);
/* object_vgroup.c */
diff --git a/source/blender/editors/include/ED_numinput.h b/source/blender/editors/include/ED_numinput.h
index 381131c8b2d..ca5dc4797de 100644
--- a/source/blender/editors/include/ED_numinput.h
+++ b/source/blender/editors/include/ED_numinput.h
@@ -33,6 +33,7 @@ typedef struct NumInput {
char inv[3]; /* If the value is inverted or not */
float val[3]; /* Direct value of the input */
int ctrl[3]; /* Control to indicate what to do with the numbers that are typed */
+ float increment;
} NumInput ;
/* NUMINPUT FLAGS */
@@ -48,7 +49,7 @@ void initNumInput(NumInput *n);
void outputNumInput(NumInput *n, char *str);
short hasNumInput(NumInput *n);
void applyNumInput(NumInput *n, float *vec);
-char handleNumInput(NumInput *n, struct wmEvent *event, float increment);
+char handleNumInput(NumInput *n, struct wmEvent *event);
#define NUM_MODAL_INCREMENT_UP 18
#define NUM_MODAL_INCREMENT_DOWN 19
diff --git a/source/blender/editors/include/ED_space_api.h b/source/blender/editors/include/ED_space_api.h
index 7f2effdd975..3529eddd6d9 100644
--- a/source/blender/editors/include/ED_space_api.h
+++ b/source/blender/editors/include/ED_space_api.h
@@ -69,6 +69,7 @@ void *ED_region_draw_cb_activate(struct ARegionType *,
void *custumdata, int type);
void ED_region_draw_cb_draw(const struct bContext *, struct ARegion *, int);
void ED_region_draw_cb_exit(struct ARegionType *, void *);
+void *ED_region_draw_cb_customdata(void *handle);
#endif /* ED_SPACE_API_H */
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 9624adf4879..0dd8e3d412d 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -4015,7 +4015,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event)
if(event->alt)
ui_but_anim_remove_keyingset(C);
else
- ui_but_anim_remove_keyingset(C);
+ ui_but_anim_add_keyingset(C);
ED_region_tag_redraw(CTX_wm_region(C));
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 4c818f9d0ac..e2804efe040 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -157,16 +157,19 @@ static void id_search_cb(const bContext *C, void *arg_template, char *str, uiSea
{
TemplateID *template= (TemplateID*)arg_template;
ListBase *lb= template->idlb;
- ID *id;
+ ID *id, *id_from= template->ptr.id.data;
int iconid;
+ int flag= RNA_property_flag(template->prop);
/* ID listbase */
for(id= lb->first; id; id= id->next) {
- if(BLI_strcasestr(id->name+2, str)) {
- iconid= ui_id_icon_get((bContext*)C, id, 0);
+ if(!((flag & PROP_ID_SELF_CHECK) && id == id_from)) {
+ if(BLI_strcasestr(id->name+2, str)) {
+ iconid= ui_id_icon_get((bContext*)C, id, 0);
- if(!uiSearchItemAdd(items, id->name+2, id, iconid))
- break;
+ if(!uiSearchItemAdd(items, id->name+2, id, iconid))
+ break;
+ }
}
}
}
@@ -281,6 +284,10 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
memset(&idptr, 0, sizeof(idptr));
RNA_property_pointer_set(&template->ptr, template->prop, idptr);
RNA_property_update(C, &template->ptr, template->prop);
+
+ if(id && CTX_wm_window(C)->eventstate->shift) /* useful hidden functionality, */
+ id->us= 0;
+
break;
case UI_ID_FAKE_USER:
if(id) {
@@ -447,8 +454,11 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
but= uiDefIconButO(block, BUT, unlinkop, WM_OP_INVOKE_REGION_WIN, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
}
else {
- but= uiDefIconBut(block, BUT, 0, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
+ but= uiDefIconBut(block, BUT, 0, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, "Unlink datablock, Shift + Click to force removal on save");
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_DELETE));
+
+ if(RNA_property_flag(template->prop) & PROP_NEVER_NULL)
+ uiButSetFlag(but, UI_BUT_DISABLED);
}
if((idfrom && idfrom->lib))
diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c
index 19eb782884d..e83be1f4f1d 100644
--- a/source/blender/editors/mesh/editface.c
+++ b/source/blender/editors/mesh/editface.c
@@ -450,52 +450,28 @@ void selectswap_tface(Scene *scene)
// XXX notifier! object_tface_flags_changed(OBACT, 0);
}
-int minmax_tface(Scene *scene, float *min, float *max)
+int minmax_tface(Object *ob, float *min, float *max)
{
- Object *ob;
- Mesh *me;
+ Mesh *me= get_mesh(ob);
MFace *mf;
- MTFace *tf;
MVert *mv;
int a, ok=0;
- float vec[3], bmat[3][3];
-
- ob = OBACT;
- if (ob==0) return ok;
- me= get_mesh(ob);
- if(me==0 || me->mtface==0) return ok;
-
- copy_m3_m4(bmat, ob->obmat);
+ float vec[3];
+
+ if(me==NULL)
+ return ok;
mv= me->mvert;
mf= me->mface;
- tf= me->mtface;
- for (a=me->totface; a>0; a--, mf++, tf++) {
- if (mf->flag & ME_HIDE || !(mf->flag & ME_FACE_SEL))
- continue;
-
- VECCOPY(vec, (mv+mf->v1)->co);
- mul_m3_v3(bmat, vec);
- add_v3_v3v3(vec, vec, ob->obmat[3]);
- DO_MINMAX(vec, min, max);
-
- VECCOPY(vec, (mv+mf->v2)->co);
- mul_m3_v3(bmat, vec);
- add_v3_v3v3(vec, vec, ob->obmat[3]);
- DO_MINMAX(vec, min, max);
-
- VECCOPY(vec, (mv+mf->v3)->co);
- mul_m3_v3(bmat, vec);
- add_v3_v3v3(vec, vec, ob->obmat[3]);
- DO_MINMAX(vec, min, max);
-
- if (mf->v4) {
- VECCOPY(vec, (mv+mf->v4)->co);
- mul_m3_v3(bmat, vec);
- add_v3_v3v3(vec, vec, ob->obmat[3]);
- DO_MINMAX(vec, min, max);
+ for (a=me->totface; a>0; a--, mf++) {
+ if ((mf->flag & ME_HIDE || !(mf->flag & ME_FACE_SEL)) == 0) {
+ int i= mf->v4 ? 3:2;
+ do {
+ mul_v3_m4v3(vec, ob->obmat, (mv + (*(&mf->v1 + i)))->co);
+ DO_MINMAX(vec, min, max);
+ } while (i--);
+ ok= 1;
}
- ok= 1;
}
return ok;
}
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index d7ffa1d983b..ab50bd4c37c 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -289,6 +289,18 @@ void ED_keymap_object(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "OBJECT_OT_select_grouped", GKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "OBJECT_OT_select_mirror", MKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
+ kmi= WM_keymap_add_item(keymap, "OBJECT_OT_select_hierarchy", LEFTBRACKETKEY, KM_PRESS, 0, 0);
+ RNA_enum_set_identifier(kmi->ptr, "direction", "PARENT");
+ kmi= WM_keymap_add_item(keymap, "OBJECT_OT_select_hierarchy", LEFTBRACKETKEY, KM_PRESS, KM_SHIFT, 0);
+ RNA_enum_set_identifier(kmi->ptr, "direction", "PARENT");
+ RNA_boolean_set(kmi->ptr, "extend", 1);
+
+ kmi= WM_keymap_add_item(keymap, "OBJECT_OT_select_hierarchy", RIGHTBRACKETKEY, KM_PRESS, 0, 0);
+ RNA_enum_set_identifier(kmi->ptr, "direction", "CHILD");
+ kmi= WM_keymap_add_item(keymap, "OBJECT_OT_select_hierarchy", RIGHTBRACKETKEY, KM_PRESS, KM_SHIFT, 0);
+ RNA_enum_set_identifier(kmi->ptr, "direction", "CHILD");
+ RNA_boolean_set(kmi->ptr, "extend", 1);
+
WM_keymap_verify_item(keymap, "OBJECT_OT_parent_set", PKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_verify_item(keymap, "OBJECT_OT_parent_no_inverse_set", PKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
WM_keymap_verify_item(keymap, "OBJECT_OT_parent_clear", PKEY, KM_PRESS, KM_ALT, 0);
diff --git a/source/blender/editors/render/Makefile b/source/blender/editors/render/Makefile
index ed25f0be02a..85b70172e0a 100644
--- a/source/blender/editors/render/Makefile
+++ b/source/blender/editors/render/Makefile
@@ -54,3 +54,9 @@ CPPFLAGS += -I../../render/extern/include
# own include
CPPFLAGS += -I../include
+
+ifeq ($(OS), darwin)
+ ifeq ($(WITH_BF_OPENMP), true)
+ CPPFLAGS += -DPARALLEL=1
+ endif
+endif
diff --git a/source/blender/editors/render/SConscript b/source/blender/editors/render/SConscript
index cb901be2494..5526194eab4 100644
--- a/source/blender/editors/render/SConscript
+++ b/source/blender/editors/render/SConscript
@@ -24,4 +24,8 @@ if env['WITH_BF_QUICKTIME']:
if env['USE_QTKIT']:
env.Append(CFLAGS=['-DUSE_QTKIT'])
+if env['OURPLATFORM'] == 'darwin':
+ if env['WITH_BF_OPENMP']:
+ env.Append(CFLAGS=['-DPARALLEL=1'])
+
env.BlenderLib ( 'bf_editors_render', sources, Split(incs), [], libtype=['core'], priority=[45])
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index 1563c5a8e1d..aca13fbd66d 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -100,6 +100,13 @@
#define PR_XMAX 200
#define PR_YMAX 195
+#if defined(__APPLE__) && (PARALLEL == 1) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 2)
+/* ************** libgomp (Apple gcc 4.2.1) TLS bug workaround *************** */
+#include <pthread.h>
+extern pthread_key_t gomp_tls_key;
+static void *thread_tls_data;
+#endif
+
/* XXX */
static int qtest() {return 0;}
/* XXX */
@@ -1098,6 +1105,11 @@ static void common_preview_startjob(void *customdata, short *stop, short *do_upd
{
ShaderPreview *sp= customdata;
+#if defined(__APPLE__) && (PARALLEL == 1) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 2)
+ // Workaround for Apple gcc 4.2.1 omp vs background thread bug
+ pthread_setspecific (gomp_tls_key, thread_tls_data);
+#endif
+
if(sp->pr_method == PR_ICON_RENDER)
icon_preview_startjob(customdata, stop, do_update);
else
@@ -1127,7 +1139,12 @@ void ED_preview_icon_job(const bContext *C, void *owner, ID *id, unsigned int *r
WM_jobs_customdata(steve, sp, shader_preview_free);
WM_jobs_timer(steve, 0.1, NC_MATERIAL, NC_MATERIAL);
WM_jobs_callbacks(steve, common_preview_startjob, NULL, NULL);
-
+
+#if defined(__APPLE__) && (PARALLEL == 1) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 2)
+ // Workaround for Apple gcc 4.2.1 omp vs background thread bug
+ thread_tls_data = pthread_getspecific(gomp_tls_key);
+#endif
+
WM_jobs_start(CTX_wm_manager(C), steve);
}
@@ -1154,6 +1171,11 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, M
WM_jobs_timer(steve, 0.1, NC_MATERIAL, NC_MATERIAL);
WM_jobs_callbacks(steve, common_preview_startjob, NULL, shader_preview_updatejob);
+#if defined(__APPLE__) && (PARALLEL == 1) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 2)
+ // Workaround for Apple gcc 4.2.1 omp vs background thread bug
+ thread_tls_data = pthread_getspecific(gomp_tls_key);
+#endif
+
WM_jobs_start(CTX_wm_manager(C), steve);
}
diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c
index 9bfe3213587..a3fe29536a3 100644
--- a/source/blender/editors/space_api/spacetypes.c
+++ b/source/blender/editors/space_api/spacetypes.c
@@ -204,6 +204,11 @@ void ED_region_draw_cb_exit(ARegionType *art, void *handle)
}
}
+void *ED_region_draw_cb_customdata(void *handle)
+{
+ return ((RegionDrawCB *)handle)->customdata;
+}
+
void ED_region_draw_cb_draw(const bContext *C, ARegion *ar, int type)
{
RegionDrawCB *rdc;
diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c
index 3ebb4c61f7b..7b59f6aafa9 100644
--- a/source/blender/editors/space_buttons/buttons_ops.c
+++ b/source/blender/editors/space_buttons/buttons_ops.c
@@ -38,6 +38,8 @@
#include "WM_api.h"
#include "WM_types.h"
+#include "ED_screen.h"
+
#include "RNA_access.h"
#include "RNA_define.h"
@@ -75,6 +77,7 @@ void BUTTONS_OT_toolbox(wmOperatorType *ot)
/* api callbacks */
ot->invoke= toolbox_invoke;
+ ot->poll= ED_operator_buttons_active;
}
/********************** filebrowse operator *********************/
diff --git a/source/blender/editors/space_console/console_draw.c b/source/blender/editors/space_console/console_draw.c
index 16f5f47075e..708089f8f4c 100644
--- a/source/blender/editors/space_console/console_draw.c
+++ b/source/blender/editors/space_console/console_draw.c
@@ -140,9 +140,23 @@ typedef struct ConsoleDrawContext {
static void console_draw_sel(int sel[2], int xy[2], int str_len, int cwidth, int console_width, int lheight)
{
- if(sel[0] < str_len && sel[1] > 0) {
+ if(sel[0] <= str_len && sel[1] >= 0) {
int sta = MAX2(sel[0], 0);
int end = MIN2(sel[1], str_len);
+
+ /* highly confusing but draws correctly */
+ if(sel[0] < 0 || sel[1] > str_len) {
+ if(sel[0] > 0) {
+ end= sta;
+ sta= 0;
+ }
+ if (sel[1] <= str_len) {
+ sta= end;
+ end= str_len;
+ }
+ }
+ /* end confusement */
+
{
glEnable(GL_POLYGON_STIPPLE);
glPolygonStipple(stipple_halftone);
@@ -157,8 +171,8 @@ static void console_draw_sel(int sel[2], int xy[2], int str_len, int cwidth, int
}
}
- sel[0] -= str_len;
- sel[1] -= str_len;
+ sel[0] -= str_len + 1;
+ sel[1] -= str_len + 1;
}
@@ -179,7 +193,7 @@ static int console_draw_string(ConsoleDrawContext *cdc, char *str, int str_len,
int ofs = (int)floor(((float)cdc->mval[0] / (float)cdc->cwidth));
*cdc->pos_pick += MIN2(ofs, str_len);
} else
- *cdc->pos_pick += str_len;
+ *cdc->pos_pick += str_len + 1;
}
}
@@ -190,6 +204,13 @@ static int console_draw_string(ConsoleDrawContext *cdc, char *str, int str_len,
else if (y_next-cdc->lheight < cdc->ymin) {
/* have not reached the drawable area so don't break */
cdc->xy[1]= y_next;
+
+ /* adjust selection even if not drawing */
+ if(cdc->sel[0] != cdc->sel[1]) {
+ cdc->sel[0] -= str_len + 1;
+ cdc->sel[1] -= str_len + 1;
+ }
+
return 1;
}
@@ -314,6 +335,7 @@ static int console_text_main__internal(struct SpaceConsole *sc, struct ARegion *
if(sc->sel_start != sc->sel_end) {
sel[0]= sc->sel_start;
sel[1]= sc->sel_end;
+ // printf("%d %d\n", sel[0], sel[1]);
}
/* text */
diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c
index 44c0b2159d7..763436dd05f 100644
--- a/source/blender/editors/space_console/console_ops.c
+++ b/source/blender/editors/space_console/console_ops.c
@@ -681,23 +681,71 @@ static int copy_exec(bContext *C, wmOperator *op)
char *buf_str;
ConsoleLine *cl;
-
+ int sel[2];
+ int offset= 0;
+
+#if 0
+ /* copy whole file */
for(cl= sc->scrollback.first; cl; cl= cl->next) {
BLI_dynstr_append(buf_dyn, cl->line);
BLI_dynstr_append(buf_dyn, "\n");
}
+#endif
+
+ if(sc->sel_start == sc->sel_end)
+ return OPERATOR_CANCELLED;
+
+
+ for(cl= sc->scrollback.first; cl; cl= cl->next) {
+ offset += cl->len + 1;
+ }
+
+ if(offset==0)
+ return OPERATOR_CANCELLED;
+
+
+ offset -= 1;
+ sel[0]= offset - sc->sel_end;
+ sel[1]= offset - sc->sel_start;
+
+ for(cl= sc->scrollback.first; cl; cl= cl->next) {
+
+ int sta= MAX2(0, sel[0]);
+ int end= MIN2(cl->len, sel[1]);
+
+ if(sel[0] <= cl->len && sel[1] >= 0) {
+ int str_len= cl->len;
+
+ /* highly confusing but draws correctly */
+ if(sel[0] < 0 || sel[1] > str_len) {
+ if(sel[0] > 0) {
+ end= sta;
+ sta= 0;
+ }
+ if (sel[1] <= str_len) {
+ sta= end;
+ end= str_len;
+ }
+ }
+ /* end confusement */
+
+ SWAP(int, sta, end);
+ end= cl->len - end;
+ sta= cl->len - sta;
+
+ if(BLI_dynstr_get_len(buf_dyn))
+ BLI_dynstr_append(buf_dyn, "\n");
+
+ BLI_dynstr_nappend(buf_dyn, cl->line + sta, end - sta);
+ }
+
+ sel[0] -= cl->len + 1;
+ sel[1] -= cl->len + 1;
+ }
buf_str= BLI_dynstr_get_cstring(buf_dyn);
buf_len= BLI_dynstr_get_len(buf_dyn);
BLI_dynstr_free(buf_dyn);
-
- /* hack for selection */
-#if 0
- if(sc->sel_start != sc->sel_end) {
- buf_str[buf_len - sc->sel_start]= '\0';
- WM_clipboard_text_set(buf_str+(buf_len - sc->sel_end), 0);
- }
-#endif
WM_clipboard_text_set(buf_str, 0);
MEM_freeN(buf_str);
@@ -723,11 +771,28 @@ static int paste_exec(bContext *C, wmOperator *op)
ConsoleLine *ci= console_history_verify(C);
char *buf_str= WM_clipboard_text_get(0);
+ char *buf_step, *buf_next;
if(buf_str==NULL)
return OPERATOR_CANCELLED;
- console_line_insert(ci, buf_str); /* TODO - Multiline copy?? */
+ buf_next= buf_str;
+ buf_step= buf_str;
+
+ while((buf_next=buf_step) && buf_next[0] != '\0') {
+ buf_step= strchr(buf_next, '\n');
+ if(buf_step) {
+ *buf_step= '\0';
+ buf_step++;
+ }
+
+ if(buf_next != buf_str) {
+ WM_operator_name_call(C, "CONSOLE_OT_execute", WM_OP_EXEC_DEFAULT, NULL);
+ ci= console_history_verify(C);
+ }
+
+ console_line_insert(ci, buf_next);
+ }
MEM_freeN(buf_str);
diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c
index 1cc8fc37e77..543fa1dfed7 100644
--- a/source/blender/editors/space_nla/nla_edit.c
+++ b/source/blender/editors/space_nla/nla_edit.c
@@ -246,27 +246,6 @@ void NLA_OT_tweakmode_exit (wmOperatorType *ot)
/* ******************** Add Action-Clip Operator ***************************** */
/* Add a new Action-Clip strip to the active track (or the active block if no space in the track) */
-/* pop up menu allowing user to choose the action to use */
-// TODO: at some point, we may have to migrate to a search menu to manage the case where there are many actions
-static int nlaedit_add_actionclip_invoke (bContext *C, wmOperator *op, wmEvent *evt)
-{
- Main *m= CTX_data_main(C);
- bAction *act;
- uiPopupMenu *pup;
- uiLayout *layout;
-
- pup= uiPupMenuBegin(C, "Add Action Clip", 0);
- layout= uiPupMenuLayout(pup);
-
- /* loop through Actions in Main database, adding as items in the menu */
- for (act= m->action.first; act; act= act->id.next)
- uiItemStringO(layout, act->id.name+2, 0, "NLA_OT_actionclip_add", "action", act->id.name+2);
- uiItemS(layout);
-
- uiPupMenuEnd(C, pup);
-
- return OPERATOR_CANCELLED;
-}
/* add the specified action as new strip */
static int nlaedit_add_actionclip_exec (bContext *C, wmOperator *op)
@@ -277,9 +256,9 @@ static int nlaedit_add_actionclip_exec (bContext *C, wmOperator *op)
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter, items;
-
- bAction *act = NULL;
- char actname[20];
+
+ bAction *act;
+
float cfra;
/* get editor data */
@@ -290,8 +269,7 @@ static int nlaedit_add_actionclip_exec (bContext *C, wmOperator *op)
cfra= (float)CFRA;
/* get action to use */
- RNA_string_get(op->ptr, "action", actname);
- act= (bAction *)find_id("AC", actname);
+ act= BLI_findlink(&CTX_data_main(C)->action, RNA_enum_get(op->ptr, "type"));
if (act == NULL) {
BKE_report(op->reports, RPT_ERROR, "No valid Action to add.");
@@ -350,13 +328,15 @@ static int nlaedit_add_actionclip_exec (bContext *C, wmOperator *op)
void NLA_OT_actionclip_add (wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name= "Add Action Strip";
ot->idname= "NLA_OT_actionclip_add";
ot->description= "Add an Action-Clip strip (i.e. an NLA Strip referencing an Action) to the active track";
/* api callbacks */
- ot->invoke= nlaedit_add_actionclip_invoke;
+ ot->invoke= WM_enum_search_invoke;
ot->exec= nlaedit_add_actionclip_exec;
ot->poll= nlaop_poll_tweakmode_off;
@@ -365,7 +345,9 @@ void NLA_OT_actionclip_add (wmOperatorType *ot)
/* props */
// TODO: this would be nicer as an ID-pointer...
- ot->prop = RNA_def_string(ot->srna, "action", "", 19, "Action", "Name of Action to add as a new Action-Clip Strip.");
+ prop= RNA_def_enum(ot->srna, "type", DummyRNA_NULL_items, 0, "Type", "");
+ RNA_def_enum_funcs(prop, RNA_action_itemf);
+ ot->prop= prop;
}
/* ******************** Add Transition Operator ***************************** */
diff --git a/source/blender/editors/space_outliner/outliner.c b/source/blender/editors/space_outliner/outliner.c
index 09b5e3a80e2..4618f7a8873 100644
--- a/source/blender/editors/space_outliner/outliner.c
+++ b/source/blender/editors/space_outliner/outliner.c
@@ -3977,14 +3977,14 @@ static void do_outliner_keyingset_editop(SpaceOops *soops, KeyingSet *ks, ListBa
{
/* add a new path with the information obtained (only if valid) */
// TODO: what do we do with group name? for now, we don't supply one, and just let this use the KeyingSet name
- BKE_keyingset_add_destination(ks, id, NULL, path, array_index, flag, groupmode);
+ BKE_keyingset_add_path(ks, id, NULL, path, array_index, flag, groupmode);
ks->active_path= BLI_countlist(&ks->paths);
}
break;
case KEYINGSET_EDITMODE_REMOVE:
{
/* find the relevant path, then remove it from the KeyingSet */
- KS_Path *ksp= BKE_keyingset_find_destination(ks, id, NULL, path, array_index, groupmode);
+ KS_Path *ksp= BKE_keyingset_find_path(ks, id, NULL, path, array_index, groupmode);
if (ksp) {
/* free path's data */
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 1c04667e501..fc67881367f 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -751,6 +751,10 @@ static void view3d_buttons_area_listener(ARegion *ar, wmNotifier *wmn)
if(wmn->action == NA_RENAME)
ED_region_tag_redraw(ar);
break;
+ case NC_SCREEN:
+ if(wmn->data == ND_GPENCIL)
+ ED_region_tag_redraw(ar);
+ break;
}
}
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index 81a508de139..51e8f9e43b2 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -76,6 +76,7 @@
#include "ED_screen.h"
#include "ED_transform.h"
#include "ED_types.h"
+#include "ED_mesh.h"
#include "UI_interface.h"
#include "UI_resources.h"
@@ -109,9 +110,7 @@ static void view3d_boxview_clip(ScrArea *sa)
if(ar->winx>ar->winy) y1= ar->winy*rv3d->dist/ar->winx;
else y1= rv3d->dist;
-
- ofs[0]= rv3d->ofs[0];
- ofs[1]= rv3d->ofs[1];
+ copy_v2_v2(ofs, rv3d->ofs);
}
else if(ELEM(rv3d->view, RV3D_VIEW_FRONT, RV3D_VIEW_BACK)) {
ofs[2]= rv3d->ofs[2];
@@ -335,8 +334,7 @@ static void viewops_data_create(bContext *C, wmOperator *op, wmEvent *event)
VECCOPY(vod->ofs, rv3d->ofs);
/* If there's no selection, lastofs is unmodified and last value since static */
calculateTransformCenter(C, V3D_CENTROID, lastofs);
- VECCOPY(vod->dyn_ofs, lastofs);
- mul_v3_fl(vod->dyn_ofs, -1.0f);
+ negate_v3_v3(vod->dyn_ofs, lastofs);
}
else if (U.uiflag & USER_ORBIT_ZBUF) {
@@ -371,8 +369,7 @@ static void viewops_data_create(bContext *C, wmOperator *op, wmEvent *event)
closest_to_line_v3(dvec, vod->dyn_ofs, my_pivot, my_origin);
vod->dist0 = rv3d->dist = len_v3v3(my_pivot, dvec);
- negate_v3(dvec);
- VECCOPY(rv3d->ofs, dvec);
+ negate_v3_v3(rv3d->ofs, dvec);
}
negate_v3(vod->dyn_ofs);
VECCOPY(vod->ofs, rv3d->ofs);
@@ -547,11 +544,8 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y)
* dragged. */
phi = si * M_PI / 2.0;
- si= sin(phi);
q1[0]= cos(phi);
- q1[1]*= si;
- q1[2]*= si;
- q1[3]*= si;
+ mul_v3_fl(q1+1, sin(phi));
mul_qt_qtqt(rv3d->viewquat, q1, vod->oldquat);
if (vod->use_dyn_ofs) {
@@ -569,7 +563,7 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y)
}
else {
/* New turntable view code by John Aughey */
- float si, phi, q1[4];
+ float phi, q1[4];
float m[3][3];
float m_inv[3][3];
float xvec[3] = {1,0,0};
@@ -589,11 +583,8 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y)
/* Perform the up/down rotation */
phi = sensitivity * -(y - vod->oldy);
- si = sin(phi);
q1[0] = cos(phi);
- q1[1] = si * xvec[0];
- q1[2] = si * xvec[1];
- q1[3] = si * xvec[2];
+ mul_v3_v3fl(q1+1, xvec, sin(phi));
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, q1);
if (vod->use_dyn_ofs) {
@@ -634,12 +625,10 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y)
if ((dot_v3v3(snapmat[0], viewmat[0]) > thres) &&
(dot_v3v3(snapmat[1], viewmat[1]) > thres) &&
- (dot_v3v3(snapmat[2], viewmat[2]) > thres)){
-
- QUATCOPY(rv3d->viewquat, snapquats[i]);
-
- rv3d->view = view;
-
+ (dot_v3v3(snapmat[2], viewmat[2]) > thres)
+ ) {
+ copy_qt_qt(rv3d->viewquat, snapquats[i]);
+ rv3d->view= view;
break;
}
}
@@ -968,18 +957,15 @@ static void view_zoom_mouseloc(ARegion *ar, float dfac, int mx, int my)
vb[0] = ar->winx;
vb[1] = ar->winy;
- tpos[0] = -rv3d->ofs[0];
- tpos[1] = -rv3d->ofs[1];
- tpos[2] = -rv3d->ofs[2];
+ negate_v3_v3(tpos, rv3d->ofs);
/* Project cursor position into 3D space */
initgrabz(rv3d, tpos[0], tpos[1], tpos[2]);
window_to_3d_delta(ar, dvec, mouseloc[0]-vb[0]/2, mouseloc[1]-vb[1]/2);
/* Calculate view target position for dolly */
- tvec[0] = -(tpos[0] + dvec[0]);
- tvec[1] = -(tpos[1] + dvec[1]);
- tvec[2] = -(tpos[2] + dvec[2]);
+ add_v3_v3v3(tvec, tpos, dvec);
+ negate_v3(tvec);
/* Offset to target position and dolly */
new_dist = rv3d->dist * dfac;
@@ -988,11 +974,7 @@ static void view_zoom_mouseloc(ARegion *ar, float dfac, int mx, int my)
rv3d->dist = new_dist;
/* Calculate final offset */
- dvec[0] = tvec[0] + dvec[0] * dfac;
- dvec[1] = tvec[1] + dvec[1] * dfac;
- dvec[2] = tvec[2] + dvec[2] * dfac;
-
- VECCOPY(rv3d->ofs, dvec);
+ madd_v3_v3v3fl(rv3d->ofs, tvec, dvec, dfac);
} else {
rv3d->dist *= dfac;
}
@@ -1384,7 +1366,7 @@ static int viewselected_exec(bContext *C, wmOperator *op) /* like a localview wi
}
}
else if (paint_facesel_test(ob)) {
-// XXX ok= minmax_tface(min, max);
+ ok= minmax_tface(ob, min, max);
}
else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT)) {
ok= PE_minmax(scene, min, max);
@@ -1393,9 +1375,10 @@ static int viewselected_exec(bContext *C, wmOperator *op) /* like a localview wi
Base *base= FIRSTBASE;
while(base) {
if(TESTBASE(v3d, base)) {
- minmax_object(base->object, min, max);
+
/* account for duplis */
- minmax_object_duplis(scene, base->object, min, max);
+ if (minmax_object_duplis(scene, base->object, min, max)==0)
+ minmax_object(base->object, min, max); /* use if duplis not found */
ok= 1;
}
@@ -1405,9 +1388,7 @@ static int viewselected_exec(bContext *C, wmOperator *op) /* like a localview wi
if(ok==0) return OPERATOR_FINISHED;
- afm[0]= (max[0]-min[0]);
- afm[1]= (max[1]-min[1]);
- afm[2]= (max[2]-min[2]);
+ sub_v3_v3v3(afm, max, min);
size= MAX3(afm[0], afm[1], afm[2]);
if(rv3d->persp==RV3D_ORTHO) {
@@ -1425,9 +1406,8 @@ static int viewselected_exec(bContext *C, wmOperator *op) /* like a localview wi
}
}
- new_ofs[0]= -(min[0]+max[0])/2.0f;
- new_ofs[1]= -(min[1]+max[1])/2.0f;
- new_ofs[2]= -(min[2]+max[2])/2.0f;
+ add_v3_v3v3(new_ofs, min, max);
+ mul_v3_fl(new_ofs, -0.5f);
new_dist = size;
@@ -1482,13 +1462,8 @@ static int viewcenter_cursor_exec(bContext *C, wmOperator *op)
}
else {
/* non camera center */
- float *curs= give_cursor(scene, v3d);
float new_ofs[3];
-
- new_ofs[0]= -curs[0];
- new_ofs[1]= -curs[1];
- new_ofs[2]= -curs[2];
-
+ negate_v3_v3(new_ofs, give_cursor(scene, v3d));
smooth_view(C, NULL, NULL, new_ofs, NULL, NULL, NULL);
}
@@ -1706,9 +1681,7 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
new_ofs[2] = -p[2];
} else {
/* We cant use the depth, fallback to the old way that dosnt set the center depth */
- new_ofs[0] = rv3d->ofs[0];
- new_ofs[1] = rv3d->ofs[1];
- new_ofs[2] = rv3d->ofs[2];
+ copy_v3_v3(new_ofs, rv3d->ofs);
initgrabz(rv3d, -new_ofs[0], -new_ofs[1], -new_ofs[2]);
@@ -1982,7 +1955,7 @@ static EnumPropertyItem prop_view_orbit_items[] = {
static int vieworbit_exec(bContext *C, wmOperator *op)
{
RegionView3D *rv3d= CTX_wm_region_view3d(C);
- float phi, si, q1[4], new_quat[4];
+ float phi, q1[4], new_quat[4];
int orbitdir;
orbitdir = RNA_enum_get(op->ptr, "type");
@@ -1991,6 +1964,7 @@ static int vieworbit_exec(bContext *C, wmOperator *op)
if(rv3d->persp != RV3D_CAMOB) {
if(orbitdir == V3D_VIEW_STEPLEFT || orbitdir == V3D_VIEW_STEPRIGHT) {
+ float si;
/* z-axis */
phi= (float)(M_PI/360.0)*U.pad_rot_angle;
if(orbitdir == V3D_VIEW_STEPRIGHT) phi= -phi;
@@ -2008,11 +1982,8 @@ static int vieworbit_exec(bContext *C, wmOperator *op)
normalize_v3(q1+1);
phi= (float)(M_PI/360.0)*U.pad_rot_angle;
if(orbitdir == V3D_VIEW_STEPDOWN) phi= -phi;
- si= (float)sin(phi);
q1[0]= (float)cos(phi);
- q1[1]*= si;
- q1[2]*= si;
- q1[3]*= si;
+ mul_v3_fl(q1+1, sin(phi));
mul_qt_qtqt(new_quat, rv3d->viewquat, q1);
rv3d->view= 0;
}
@@ -2815,7 +2786,7 @@ void viewmoveNDOF(Scene *scene, ARegion *ar, View3D *v3d, int mode)
float xvec[3] = {1,0,0};
float yvec[3] = {0,-1,0};
float zvec[3] = {0,0,1};
- float phi, si;
+ float phi;
float q1[4];
float obofs[3];
float reverse;
@@ -2964,11 +2935,8 @@ void viewmoveNDOF(Scene *scene, ARegion *ar, View3D *v3d, int mode)
/* Perform the up/down rotation */
phi = sbadjust * rsens * /*0.5f * */ fval[3]; /* spin vertically half as fast as horizontally */
- si = sin(phi);
q1[0] = cos(phi);
- q1[1] = si * xvec[0];
- q1[2] = si * xvec[1];
- q1[3] = si * xvec[2];
+ mul_v3_v3fl(q1+1, xvec, sin(phi));
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, q1);
if (use_sel) {
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index 59051c7a894..1674c135008 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -161,11 +161,9 @@ static void view_settings_from_ob(Object *ob, float *ofs, float *quat, float *di
if (!ob) return;
/* Offset */
- if (ofs) {
- VECCOPY(ofs, ob->obmat[3]);
- mul_v3_fl(ofs, -1.0f); /*flip the vector*/
- }
-
+ if (ofs)
+ negate_v3_v3(ofs, ob->obmat[3]);
+
/* Quat */
if (quat) {
copy_m4_m4(bmat, ob->obmat);
@@ -404,13 +402,9 @@ static void setcameratoview3d(View3D *v3d, RegionView3D *rv3d, Object *ob)
{
float dvec[3];
float mat3[3][3];
-
- dvec[0]= rv3d->dist*rv3d->viewinv[2][0];
- dvec[1]= rv3d->dist*rv3d->viewinv[2][1];
- dvec[2]= rv3d->dist*rv3d->viewinv[2][2];
-
- VECCOPY(ob->loc, dvec);
- sub_v3_v3v3(ob->loc, ob->loc, rv3d->ofs);
+
+ mul_v3_v3fl(dvec, rv3d->viewinv[2], rv3d->dist);
+ sub_v3_v3v3(ob->loc, dvec, rv3d->ofs);
rv3d->viewquat[0]= -rv3d->viewquat[0];
// quat_to_eul( ob->rot,rv3d->viewquat); // in 2.4x for xyz eulers only
@@ -602,9 +596,7 @@ void viewvector(RegionView3D *rv3d, float coord[3], float vec[3])
p2[3] = 1.0f;
mul_m4_v4(rv3d->viewmat, p2);
- p2[0] = 2.0f * p2[0];
- p2[1] = 2.0f * p2[1];
- p2[2] = 2.0f * p2[2];
+ mul_v3_fl(p2, 2.0f);
mul_m4_v4(rv3d->viewinv, p2);
@@ -1154,6 +1146,25 @@ static void view3d_viewlock(RegionView3D *rv3d)
}
}
+/* give a 4x4 matrix from a perspective view, only needs viewquat, ofs and dist
+ * basically the same as...
+ * rv3d->persp= RV3D_PERSP
+ * setviewmatrixview3d(scene, v3d, rv3d);
+ * setcameratoview3d(v3d, rv3d, v3d->camera);
+ * ...but less of a hassle
+ * */
+static void view3d_persp_mat4(RegionView3D *rv3d, float mat[][4])
+{
+ float qt[4], dvec[3];
+ copy_qt_qt(qt, rv3d->viewquat);
+ qt[0]= -qt[0];
+ quat_to_mat4(mat, qt);
+ mat[3][2] -= rv3d->dist;
+ translate_m4(mat, rv3d->ofs[0], rv3d->ofs[1], rv3d->ofs[2]);
+ mul_v3_v3fl(dvec, mat[2], -rv3d->dist);
+ sub_v3_v3v3(mat[3], dvec, rv3d->ofs);
+}
+
/* dont set windows active in in here, is used by renderwin too */
void setviewmatrixview3d(Scene *scene, View3D *v3d, RegionView3D *rv3d)
{
@@ -1690,8 +1701,8 @@ void game_set_commmandline_options(GameData *gm)
test= (gm->flag & GAME_ENABLE_ALL_FRAMES);
SYS_WriteCommandLineInt(syshandle, "fixedtime", test);
-// a= (G.fileflags & G_FILE_GAME_TO_IPO);
-// SYS_WriteCommandLineInt(syshandle, "game2ipo", a);
+ test= (gm->flag & GAME_ENABLE_ANIMATION_RECORD);
+ SYS_WriteCommandLineInt(syshandle, "animation_record", test);
test= (gm->flag & GAME_IGNORE_DEPRECATION_WARNINGS);
SYS_WriteCommandLineInt(syshandle, "ignore_deprecation_warnings", test);
@@ -1940,12 +1951,17 @@ typedef struct FlyInfo {
float xlock_momentum, zlock_momentum; /* nicer dynamics */
float grid; /* world scale 1.0 default */
+ /* root most parent */
+ Object *root_parent;
+
/* backup values */
float dist_backup; /* backup the views distance since we use a zero dist for fly mode */
float ofs_backup[3]; /* backup the views offset incase the user cancels flying in non camera mode */
float rot_backup[4]; /* backup the views quat incase the user cancels flying in non camera mode. (quat for view, eul for camera) */
short persp_backup; /* remember if were ortho or not, only used for restoring the view if it was a ortho view */
+ void *obtfm; /* backup the objects transform */
+
/* compare between last state */
double time_lastwheel; /* used to accelerate when using the mousewheel a lot */
double time_lastdraw; /* time between draws */
@@ -2019,13 +2035,23 @@ static int initFlyInfo (bContext *C, FlyInfo *fly, wmOperator *op, wmEvent *even
fly->persp_backup= fly->rv3d->persp;
fly->dist_backup= fly->rv3d->dist;
if (fly->rv3d->persp==RV3D_CAMOB) {
- /* store the origoinal camera loc and rot */
- VECCOPY(fly->ofs_backup, fly->v3d->camera->loc);
- VECCOPY(fly->rot_backup, fly->v3d->camera->rot);
+ Object *ob_back;
+ if((fly->root_parent=fly->v3d->camera->parent)) {
+ while(fly->root_parent->parent)
+ fly->root_parent= fly->root_parent->parent;
+ ob_back= fly->root_parent;
+ }
+ else {
+ ob_back= fly->v3d->camera;
+ }
+
+ /* store the original camera loc and rot */
+ /* TODO. axis angle etc */
+
+ fly->obtfm= object_tfm_backup(ob_back);
where_is_object(fly->scene, fly->v3d->camera);
- VECCOPY(fly->rv3d->ofs, fly->v3d->camera->obmat[3]);
- mul_v3_fl(fly->rv3d->ofs, -1.0f); /*flip the vector*/
+ negate_v3_v3(fly->rv3d->ofs, fly->v3d->camera->obmat[3]);
fly->rv3d->dist=0.0;
} else {
@@ -2066,10 +2092,14 @@ static int flyEnd(bContext *C, FlyInfo *fly)
if (fly->state == FLY_CANCEL) {
/* Revert to original view? */
if (fly->persp_backup==RV3D_CAMOB) { /* a camera view */
+ Object *ob_back;
+ if(fly->root_parent)ob_back= fly->root_parent;
+ else ob_back= fly->v3d->camera;
- VECCOPY(v3d->camera->loc, fly->ofs_backup);
- VECCOPY(v3d->camera->rot, fly->rot_backup);
- DAG_id_flush_update(&v3d->camera->id, OB_RECALC_OB);
+ /* store the original camera loc and rot */
+ object_tfm_restore(ob_back, fly->obtfm);
+
+ DAG_id_flush_update(&ob_back->id, OB_RECALC_OB);
} else {
/* Non Camera we need to reset the view back to the original location bacause the user canceled*/
QUATCOPY(rv3d->viewquat, fly->rot_backup);
@@ -2079,10 +2109,15 @@ static int flyEnd(bContext *C, FlyInfo *fly)
}
else if (fly->persp_backup==RV3D_CAMOB) { /* camera */
float mat3[3][3];
- copy_m3_m4(mat3, v3d->camera->obmat);
- object_mat3_to_rot(v3d->camera, mat3, TRUE);
+ if(fly->root_parent) {
+ DAG_id_flush_update(&fly->root_parent->id, OB_RECALC_OB);
+ }
+ else {
+ copy_m3_m4(mat3, v3d->camera->obmat);
+ object_mat3_to_rot(v3d->camera, mat3, TRUE);
+ DAG_id_flush_update(&v3d->camera->id, OB_RECALC_OB);
+ }
- DAG_id_flush_update(&v3d->camera->id, OB_RECALC_OB);
#if 0 //XXX2.5
if (IS_AUTOKEY_MODE(NORMAL)) {
allqueue(REDRAWIPO, 0);
@@ -2107,6 +2142,8 @@ static int flyEnd(bContext *C, FlyInfo *fly)
rv3d->rflag &= ~(RV3D_FLYMODE|RV3D_NAVIGATING);
//XXX2.5 BIF_view3d_previewrender_signal(fly->sa, PR_DBASE|PR_DISPRECT); /* not working at the moment not sure why */
+ if(fly->obtfm)
+ MEM_freeN(fly->obtfm);
if(fly->state == FLY_CONFIRM) {
MEM_freeN(fly);
@@ -2250,6 +2287,8 @@ static int flyApply(FlyInfo *fly)
ARegion *ar = fly->ar;
Scene *scene= fly->scene;
+ float prev_view_mat[4][4];
+
float mat[3][3], /* 3x3 copy of the view matrix so we can move allong the view axis */
dvec[3]={0,0,0}, /* this is the direction thast added to the view offset per redraw */
@@ -2265,7 +2304,9 @@ static int flyApply(FlyInfo *fly)
unsigned char
apply_rotation= 1; /* if the user presses shift they can look about without movinf the direction there looking*/
-
+ if(fly->root_parent)
+ view3d_persp_mat4(rv3d, prev_view_mat);
+
/* the dist defines a vector that is infront of the offset
to rotate the view about.
this is no good for fly mode because we
@@ -2458,42 +2499,73 @@ static int flyApply(FlyInfo *fly)
interp_v3_v3v3(dvec, dvec_tmp, fly->dvec_prev, (1.0f/(1.0f+(time_redraw*5.0f))));
if (rv3d->persp==RV3D_CAMOB) {
- if (v3d->camera->protectflag & OB_LOCK_LOCX)
- dvec[0] = 0.0;
- if (v3d->camera->protectflag & OB_LOCK_LOCY)
- dvec[1] = 0.0;
- if (v3d->camera->protectflag & OB_LOCK_LOCZ)
- dvec[2] = 0.0;
+ Object *lock_ob= fly->root_parent ? fly->root_parent : fly->v3d->camera;
+ if (lock_ob->protectflag & OB_LOCK_LOCX) dvec[0] = 0.0;
+ if (lock_ob->protectflag & OB_LOCK_LOCY) dvec[1] = 0.0;
+ if (lock_ob->protectflag & OB_LOCK_LOCZ) dvec[2] = 0.0;
}
add_v3_v3v3(rv3d->ofs, rv3d->ofs, dvec);
-#if 0 //XXX2.5
+
+ /* todo, dynamic keys */
+#if 0
if (fly->zlock && fly->xlock)
- headerprint("FlyKeys Speed:(+/- | Wheel), Upright Axis:X on/Z on, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB");
+ ED_area_headerprint(fly->ar, "FlyKeys Speed:(+/- | Wheel), Upright Axis:X on/Z on, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB");
else if (fly->zlock)
- headerprint("FlyKeys Speed:(+/- | Wheel), Upright Axis:X off/Z on, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB");
+ ED_area_headerprint(fly->ar, "FlyKeys Speed:(+/- | Wheel), Upright Axis:X off/Z on, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB");
else if (fly->xlock)
- headerprint("FlyKeys Speed:(+/- | Wheel), Upright Axis:X on/Z off, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB");
+ ED_area_headerprint(fly->ar, "FlyKeys Speed:(+/- | Wheel), Upright Axis:X on/Z off, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB");
else
- headerprint("FlyKeys Speed:(+/- | Wheel), Upright Axis:X off/Z off, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB");
+ ED_area_headerprint(fly->ar, "FlyKeys Speed:(+/- | Wheel), Upright Axis:X off/Z off, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB");
#endif
/* we are in camera view so apply the view ofs and quat to the view matrix and set the camera to the view */
if (rv3d->persp==RV3D_CAMOB) {
- rv3d->persp= RV3D_PERSP; /*set this so setviewmatrixview3d uses the ofs and quat instead of the camera */
- setviewmatrixview3d(scene, v3d, rv3d);
- setcameratoview3d(v3d, rv3d, v3d->camera);
- rv3d->persp= RV3D_CAMOB;
-
+ ID *id_key;
+ /* transform the parent or the camera? */
+ if(fly->root_parent) {
+ Object *ob_update;
+
+ float view_mat[4][4];
+ float prev_view_imat[4][4];
+ float diff_mat[4][4];
+ float parent_mat[4][4];
+
+ invert_m4_m4(prev_view_imat, prev_view_mat);
+ view3d_persp_mat4(rv3d, view_mat);
+ mul_m4_m4m4(diff_mat, prev_view_imat, view_mat);
+ mul_m4_m4m4(parent_mat, fly->root_parent->obmat, diff_mat);
+ object_apply_mat4(fly->root_parent, parent_mat);
+
+ // where_is_object(scene, fly->root_parent);
+
+ ob_update= v3d->camera->parent;
+ while(ob_update) {
+ DAG_id_flush_update(&ob_update->id, OB_RECALC_OB);
+ ob_update= ob_update->parent;
+ }
+
+ copy_m4_m4(prev_view_mat, view_mat);
+
+ id_key= &fly->root_parent->id;
+
+ }
+ else {
+ float view_mat[4][4];
+ view3d_persp_mat4(rv3d, view_mat);
+ object_apply_mat4(v3d->camera, view_mat);
+ id_key= &v3d->camera->id;
+ }
+
/* record the motion */
- if (autokeyframe_cfra_can_key(scene, &v3d->camera->id)) {
+ if (autokeyframe_cfra_can_key(scene, id_key)) {
bCommonKeySrc cks;
ListBase dsources = {&cks, &cks};
int cfra = CFRA;
/* init common-key-source for use by KeyingSets */
memset(&cks, 0, sizeof(bCommonKeySrc));
- cks.id= &v3d->camera->id;
+ cks.id= id_key;
/* insert keyframes
* 1) on the first frame
@@ -2612,10 +2684,9 @@ void view3d_align_axis_to_vector(View3D *v3d, RegionView3D *rv3d, int axisidx, f
if(axisidx > 0) alignaxis[axisidx-1]= 1.0;
else alignaxis[-axisidx-1]= -1.0;
-
- VECCOPY(norm, vec);
- normalize_v3(norm);
-
+
+ normalize_v3_v3(norm, vec);
+
angle= (float)acos(dot_v3v3(alignaxis, norm));
cross_v3_v3v3(axis, alignaxis, norm);
axis_angle_to_quat( new_quat,axis, -angle);
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index d63054756d9..09c99a47a46 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -718,7 +718,7 @@ int transformEvent(TransInfo *t, wmEvent *event)
}
// Modal numinput events
- t->redraw |= handleNumInput(&(t->num), event, t->snap[1]);
+ t->redraw |= handleNumInput(&(t->num), event);
}
/* else do non-mapped events */
else if (event->val==KM_PRESS) {
@@ -971,7 +971,7 @@ int transformEvent(TransInfo *t, wmEvent *event)
}
// Numerical input events
- t->redraw |= handleNumInput(&(t->num), event, t->snap[1]);
+ t->redraw |= handleNumInput(&(t->num), event);
// NDof input events
switch(handleNDofInput(&(t->ndof), event))
@@ -2081,6 +2081,8 @@ void initWarp(TransInfo *t)
t->snap[1] = 5.0f;
t->snap[2] = 1.0f;
+ t->num.increment = 1.0f;
+
t->flag |= T_NO_CONSTRAINT;
/* we need min/max in view space */
@@ -2237,6 +2239,8 @@ void initShear(TransInfo *t)
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
+ t->num.increment = 0.1f;
+
t->flag |= T_NO_CONSTRAINT;
}
@@ -2363,6 +2367,8 @@ void initResize(TransInfo *t)
t->snap[0] = 0.0f;
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
+
+ t->num.increment = t->snap[1];
}
static void headerResize(TransInfo *t, float vec[3], char *str) {
@@ -2614,6 +2620,8 @@ void initToSphere(TransInfo *t)
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
+ t->num.increment = t->snap[1];
+
t->num.flag |= NUM_NULL_ONE | NUM_NO_NEGATIVE;
t->flag |= T_NO_CONSTRAINT;
@@ -2705,11 +2713,12 @@ void initRotation(TransInfo *t)
t->snap[1] = (float)((5.0/180)*M_PI);
t->snap[2] = t->snap[1] * 0.2f;
+ t->num.increment = 1.0f;
+
if (t->flag & T_2D_EDIT)
t->flag |= T_NO_CONSTRAINT;
- VECCOPY(t->axis, t->viewinv[2]);
- mul_v3_fl(t->axis, -1.0f);
+ negate_v3_v3(t->axis, t->viewinv[2]);
normalize_v3(t->axis);
}
@@ -2967,8 +2976,7 @@ int Rotation(TransInfo *t, short mval[2])
t->con.applyRot(t, NULL, t->axis, &final);
} else {
/* reset axis if constraint is not set */
- VECCOPY(t->axis, t->viewinv[2]);
- mul_v3_fl(t->axis, -1.0f);
+ negate_v3_v3(t->axis, t->viewinv[2]);
normalize_v3(t->axis);
}
@@ -3032,6 +3040,8 @@ void initTrackball(TransInfo *t)
t->snap[1] = (float)((5.0/180)*M_PI);
t->snap[2] = t->snap[1] * 0.2f;
+ t->num.increment = 1.0f;
+
t->flag |= T_NO_CONSTRAINT;
}
@@ -3149,6 +3159,8 @@ void initTranslation(TransInfo *t)
t->snap[0] = 0.0f;
t->snap[1] = t->snap[2] = 1.0f;
}
+
+ t->num.increment = t->snap[1];
}
static void headerTranslation(TransInfo *t, float vec[3], char *str) {
@@ -3339,6 +3351,8 @@ void initShrinkFatten(TransInfo *t)
t->snap[1] = 1.0f;
t->snap[2] = t->snap[1] * 0.1f;
+ t->num.increment = t->snap[1];
+
t->flag |= T_NO_CONSTRAINT;
}
}
@@ -3413,6 +3427,8 @@ void initTilt(TransInfo *t)
t->snap[1] = (float)((5.0/180)*M_PI);
t->snap[2] = t->snap[1] * 0.2f;
+ t->num.increment = t->snap[1];
+
t->flag |= T_NO_CONSTRAINT;
}
@@ -3482,6 +3498,8 @@ void initCurveShrinkFatten(TransInfo *t)
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
+ t->num.increment = t->snap[1];
+
t->flag |= T_NO_ZERO;
t->num.flag |= NUM_NO_ZERO;
@@ -3551,6 +3569,8 @@ void initPushPull(TransInfo *t)
t->snap[0] = 0.0f;
t->snap[1] = 1.0f;
t->snap[2] = t->snap[1] * 0.1f;
+
+ t->num.increment = t->snap[1];
}
@@ -3639,6 +3659,8 @@ void initBevel(TransInfo *t)
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
+ t->num.increment = t->snap[1];
+
/* DON'T KNOW WHY THIS IS NEEDED */
if (G.editBMesh->imval[0] == 0 && G.editBMesh->imval[1] == 0) {
/* save the initial mouse co */
@@ -3748,6 +3770,8 @@ void initBevelWeight(TransInfo *t)
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
+ t->num.increment = t->snap[1];
+
t->flag |= T_NO_CONSTRAINT;
}
@@ -3819,6 +3843,8 @@ void initCrease(TransInfo *t)
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
+ t->num.increment = t->snap[1];
+
t->flag |= T_NO_CONSTRAINT;
}
@@ -3893,6 +3919,8 @@ void initBoneSize(TransInfo *t)
t->snap[0] = 0.0f;
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
+
+ t->num.increment = t->snap[1];
}
static void headerBoneSize(TransInfo *t, float vec[3], char *str) {
@@ -4009,6 +4037,8 @@ void initBoneEnvelope(TransInfo *t)
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
+ t->num.increment = t->snap[1];
+
t->flag |= T_NO_CONSTRAINT;
}
@@ -4586,6 +4616,8 @@ void initEdgeSlide(TransInfo *t)
t->snap[1] = (float)((5.0/180)*M_PI);
t->snap[2] = t->snap[1] * 0.2f;
+ t->num.increment = t->snap[1];
+
t->flag |= T_NO_CONSTRAINT;
}
@@ -4754,6 +4786,8 @@ void initBoneRoll(TransInfo *t)
t->snap[1] = (float)((5.0/180)*M_PI);
t->snap[2] = t->snap[1] * 0.2f;
+ t->num.increment = 1.0f;
+
t->flag |= T_NO_CONSTRAINT;
}
@@ -4814,6 +4848,8 @@ void initBakeTime(TransInfo *t)
t->snap[0] = 0.0f;
t->snap[1] = 1.0f;
t->snap[2] = t->snap[1] * 0.1f;
+
+ t->num.increment = t->snap[1];
}
int BakeTime(TransInfo *t, short mval[2])
@@ -5031,6 +5067,8 @@ void initSeqSlide(TransInfo *t)
t->snap[0] = 0.0f;
t->snap[1] = floor(t->scene->r.frs_sec / t->scene->r.frs_sec_base);
t->snap[2] = 10.0f;
+
+ t->num.increment = t->snap[1];
}
static void headerSeqSlide(TransInfo *t, float val[2], char *str)
@@ -5246,6 +5284,8 @@ void initTimeTranslate(TransInfo *t)
/* initialise snap like for everything else */
t->snap[0] = 0.0f;
t->snap[1] = t->snap[2] = 1.0f;
+
+ t->num.increment = t->snap[1];
}
static void headerTimeTranslate(TransInfo *t, char *str)
@@ -5392,6 +5432,8 @@ void initTimeSlide(TransInfo *t)
/* initialise snap like for everything else */
t->snap[0] = 0.0f;
t->snap[1] = t->snap[2] = 1.0f;
+
+ t->num.increment = t->snap[1];
}
static void headerTimeSlide(TransInfo *t, float sval, char *str)
@@ -5524,6 +5566,8 @@ void initTimeScale(TransInfo *t)
/* initialise snap like for everything else */
t->snap[0] = 0.0f;
t->snap[1] = t->snap[2] = 1.0f;
+
+ t->num.increment = t->snap[1];
}
static void headerTimeScale(TransInfo *t, char *str) {
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 9d0cfdc5ac0..9d236bd47db 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -1116,6 +1116,7 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t)
td->loc = NULL;
td->ext = NULL;
+ td->ob = t->obedit;
td++;
}
@@ -1131,6 +1132,7 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t)
td->loc = NULL;
td->ext = NULL;
+ td->ob = t->obedit;
td++;
}
@@ -1165,6 +1167,7 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t)
normalize_m3(td->axismtx);
td->ext = NULL;
+ td->ob = t->obedit;
td++;
}
@@ -1181,6 +1184,7 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t)
td->flag= TD_SELECTED;
td->ext = NULL;
+ td->ob = t->obedit;
td++;
}
@@ -1209,6 +1213,7 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t)
td->ext = NULL;
td->val = NULL;
+ td->ob = t->obedit;
td++;
}
@@ -1231,6 +1236,7 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t)
td->ext = NULL;
td->val = NULL;
+ td->ob = t->obedit;
td++;
}
@@ -4712,7 +4718,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
Object *ob;
// short redrawipo=0, resetslowpar=1;
int cancelled= (t->state == TRANS_CANCEL);
- short duplicate= (t->undostr && strstr(t->undostr, "Duplicate")) ? 1 : 0;
+ short duplicate= (t->undostr && strstr(t->undostr, "Duplicate")) ? 1 : 0; /* see bugreport #21229 for reasons for this data */
/* early out when nothing happened */
if (t->total == 0 || t->mode == TFM_DUMMY)
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 27eb48614d2..d358614b1eb 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -859,7 +859,8 @@ void drawLine(TransInfo *t, float *center, float *dir, char axis, short options)
setlinestyle(0);
glBegin(GL_LINE_STRIP);
glVertex3fv(v1);
- glVertex3fv(v2);
+ glVertex3fv(center);
+// glVertex3fv(v2);
glEnd();
glPopMatrix();
diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c
index 4c0f192ed40..2e60db8048e 100644
--- a/source/blender/editors/transform/transform_orientations.c
+++ b/source/blender/editors/transform/transform_orientations.c
@@ -817,9 +817,8 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3],
quat_to_mat4( mat,ml_sel->quat);
VECCOPY(normal, mat[2]);
- VECCOPY(plane, mat[1]);
- mul_v3_fl(plane, -1.0);
+ negate_v3_v3(plane, mat[1]);
result = ORIENTATION_NORMAL;
}
@@ -887,7 +886,7 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3],
add_v3_v3v3(plane, plane, pchan->pose_mat[1]);
}
}
- mul_v3_fl(plane, -1.0);
+ negate_v3(plane);
/* we need the transpose of the inverse for a normal... */
copy_m3_m4(imat, ob->obmat);
diff --git a/source/blender/editors/util/numinput.c b/source/blender/editors/util/numinput.c
index d6e2621a235..fc193373327 100644
--- a/source/blender/editors/util/numinput.c
+++ b/source/blender/editors/util/numinput.c
@@ -159,7 +159,7 @@ void applyNumInput(NumInput *n, float *vec)
}
}
-char handleNumInput(NumInput *n, wmEvent *event, float increment)
+char handleNumInput(NumInput *n, wmEvent *event)
{
float Val = 0;
short idx = n->idx, idx_max = n->idx_max;
@@ -170,13 +170,13 @@ char handleNumInput(NumInput *n, wmEvent *event, float increment)
if (!n->ctrl[idx])
n->ctrl[idx] = 1;
- n->val[idx] += increment;
+ n->val[idx] += n->increment;
break;
case NUM_MODAL_INCREMENT_DOWN:
if (!n->ctrl[idx])
n->ctrl[idx] = 1;
- n->val[idx] -= increment;
+ n->val[idx] -= n->increment;
break;
default:
return 0;
@@ -300,6 +300,8 @@ char handleNumInput(NumInput *n, wmEvent *event, float increment)
}
}
+ printf("%f\n", n->val[idx]);
+
/* REDRAW SINCE NUMBERS HAVE CHANGED */
return 1;
}
diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c
index f6ad69c50eb..8ed70b5509f 100644
--- a/source/blender/imbuf/intern/divers.c
+++ b/source/blender/imbuf/intern/divers.c
@@ -270,7 +270,7 @@ void IMB_float_from_rect(struct ImBuf *ibuf)
if(to==NULL) return;
if(tof==NULL) {
- imb_addrectfloatImBuf(ibuf);
+ if (imb_addrectfloatImBuf(ibuf) == 0) return;
tof = ibuf->rect_float;
}
diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h
index 06ace29dbfe..8e04107afe0 100644
--- a/source/blender/makesdna/DNA_cloth_types.h
+++ b/source/blender/makesdna/DNA_cloth_types.h
@@ -66,6 +66,8 @@ typedef struct ClothSimSettings
float goalspring;
float goalfrict;
float velocity_smooth; /* smoothing of velocities for hair */
+ float collider_friction; /* friction with colliders */
+
int stepsPerFrame; /* Number of time steps per frame. */
int flags; /* flags, see CSIMSETT_FLAGS enum above. */
int preroll; /* How many frames of simulation to do before we start. */
@@ -76,7 +78,6 @@ typedef struct ClothSimSettings
short vgroup_struct; /* vertex group for scaling structural stiffness */
short presets; /* used for presets on GUI */
short reset;
- int pad;
struct EffectorWeights *effector_weights;
} ClothSimSettings;
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index d35de0497d9..5af90e2db6d 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -492,6 +492,7 @@ typedef struct GameData {
#define GAME_GLSL_NO_NODES (1 << 10)
#define GAME_GLSL_NO_EXTRA_TEX (1 << 11)
#define GAME_IGNORE_DEPRECATION_WARNINGS (1 << 12)
+#define GAME_ENABLE_ANIMATION_RECORD (1 << 13)
/* GameData.matmode */
#define GAME_MAT_TEXFACE 0
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index a2d18ed5d0a..85c6e73a909 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -276,10 +276,10 @@ typedef struct bTheme {
} bTheme;
/* for the moment only the name. may want to store options with this later */
-typedef struct bExtension {
- struct bExtension *next, *prev;
+typedef struct bAddon {
+ struct bAddon *next, *prev;
char module[64];
-} bExtension;
+} bAddon;
typedef struct SolidLight {
int flag, pad;
@@ -327,7 +327,7 @@ typedef struct UserDef {
struct ListBase uifonts;
struct ListBase uistyles;
struct ListBase keymaps;
- struct ListBase extensions;
+ struct ListBase addons;
char keyconfigstr[64];
short undosteps;
@@ -378,7 +378,7 @@ extern UserDef U; /* from blenkernel blender.c */
#define USER_SECTION_SYSTEM 3
#define USER_SECTION_THEME 4
#define USER_SECTION_INPUT 5
-#define USER_SECTION_EXTENSIONS 6
+#define USER_SECTION_ADDONS 6
/* flag */
#define USER_AUTOSAVE (1 << 0)
@@ -403,7 +403,7 @@ extern UserDef U; /* from blenkernel blender.c */
#define USER_ADD_VIEWALIGNED (1 << 19)
#define USER_RELPATHS (1 << 20)
#define USER_DRAGIMMEDIATE (1 << 21)
-#define USER_DONT_DOSCRIPTLINKS (1 << 22)
+#define USER_SCRIPT_AUTOEXEC_DISABLE (1 << 22)
#define USER_FILENOUI (1 << 23)
#define USER_NONEGFRAMES (1 << 24)
@@ -456,8 +456,10 @@ extern UserDef U; /* from blenkernel blender.c */
#define AUTOKEY_MODE_NORMAL 3
#define AUTOKEY_MODE_EDITKEYS 5
-/* Auto-Keying flag */
- /* U.autokey_flag (not strictly used when autokeying only - is also used when keyframing these days) */
+/* Auto-Keying flag
+ * U.autokey_flag (not strictly used when autokeying only - is also used when keyframing these days)
+ * note: AUTOKEY_FLAG_* is used with a macro, search for lines like IS_AUTOKEY_FLAG(INSERTAVAIL)
+ */
#define AUTOKEY_FLAG_INSERTAVAIL (1<<0)
#define AUTOKEY_FLAG_INSERTNEEDED (1<<1)
#define AUTOKEY_FLAG_AUTOMATKEY (1<<2)
diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h
index 9df3e053d9f..a53645e7442 100644
--- a/source/blender/makesdna/DNA_windowmanager_types.h
+++ b/source/blender/makesdna/DNA_windowmanager_types.h
@@ -271,8 +271,9 @@ typedef struct wmOperator {
IDProperty *properties; /* saved, user-settable properties */
/* runtime */
- struct wmOperatorType *type; /* operator type definition from idname */
+ struct wmOperatorType *type;/* operator type definition from idname */
void *customdata; /* custom storage, only while operator runs */
+ void *py_instance; /* python stores the class instance here */
struct PointerRNA *ptr; /* rna pointer to access properties */
struct ReportList *reports; /* errors and warnings storage */
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index bce449cc66a..eb92b23bd5d 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -49,6 +49,7 @@ extern StructRNA RNA_ActionConstraint;
extern StructRNA RNA_ActionGroup;
extern StructRNA RNA_Actuator;
extern StructRNA RNA_ActuatorSensor;
+extern StructRNA RNA_Addon;
extern StructRNA RNA_AlwaysSensor;
extern StructRNA RNA_AndController;
extern StructRNA RNA_AnimData;
@@ -196,7 +197,6 @@ extern StructRNA RNA_EnumPropertyItem;
extern StructRNA RNA_EnvironmentMap;
extern StructRNA RNA_EnvironmentMapTexture;
extern StructRNA RNA_Event;
-extern StructRNA RNA_Extension;
extern StructRNA RNA_ExplodeModifier;
extern StructRNA RNA_ExpressionController;
extern StructRNA RNA_FCurve;
@@ -374,11 +374,11 @@ extern StructRNA RNA_RenderEngine;
extern StructRNA RNA_RenderLayer;
extern StructRNA RNA_RenderPass;
extern StructRNA RNA_RenderResult;
+extern StructRNA RNA_RenderSettings;
extern StructRNA RNA_RGBANodeSocket;
extern StructRNA RNA_RigidBodyJointConstraint;
extern StructRNA RNA_Scene;
extern StructRNA RNA_SceneGameData;
-extern StructRNA RNA_SceneRenderData;
extern StructRNA RNA_SceneRenderLayer;
extern StructRNA RNA_SceneSequence;
extern StructRNA RNA_Screen;
@@ -665,6 +665,7 @@ StructRNA *RNA_property_pointer_type(PointerRNA *ptr, PropertyRNA *prop);
int RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop);
int RNA_property_editable_index(PointerRNA *ptr, PropertyRNA *prop, int index);
+int RNA_property_editable_flag(PointerRNA *ptr, PropertyRNA *prop); /* without lib check, only checks the flag */
int RNA_property_animateable(PointerRNA *ptr, PropertyRNA *prop);
int RNA_property_animated(PointerRNA *ptr, PropertyRNA *prop);
@@ -809,6 +810,7 @@ void RNA_float_set_array(PointerRNA *ptr, const char *name, const float *values)
int RNA_enum_get(PointerRNA *ptr, const char *name);
void RNA_enum_set(PointerRNA *ptr, const char *name, int value);
+void RNA_enum_set_identifier(PointerRNA *ptr, const char *name, const char *id);
int RNA_enum_is_equal(struct bContext *C, PointerRNA *ptr, const char *name, const char *enumname);
/* lower level functions that donr use a PointerRNA */
diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h
index 2ed365ad79f..ddd6dfef653 100644
--- a/source/blender/makesrna/RNA_enum_types.h
+++ b/source/blender/makesrna/RNA_enum_types.h
@@ -88,6 +88,7 @@ EnumPropertyItem *rna_TransformOrientation_itemf(struct bContext *C, struct Poin
/* Generic functions, return an enum from library data, index is the position
* in the linked list can add more for different types as needed */
+EnumPropertyItem *RNA_action_itemf(struct bContext *C, struct PointerRNA *ptr, int *free);
EnumPropertyItem *RNA_group_itemf(struct bContext *C, struct PointerRNA *ptr, int *free);
EnumPropertyItem *RNA_scene_itemf(struct bContext *C, struct PointerRNA *ptr, int *free);
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index 81e34dad7c0..4a50be6f58b 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -1135,19 +1135,21 @@ int RNA_property_ui_icon(PropertyRNA *prop)
int RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop)
{
- ID *id;
+ ID *id= ptr->id.data;
int flag;
prop= rna_ensure_property(prop);
+ flag= prop->editable ? prop->editable(ptr) : prop->flag;
+ return (flag & PROP_EDITABLE) && (!id || !id->lib || (prop->flag & PROP_LIB_EXCEPTION));
+}
- if(prop->editable)
- flag= prop->editable(ptr);
- else
- flag= prop->flag;
-
- id= ptr->id.data;
+int RNA_property_editable_flag(PointerRNA *ptr, PropertyRNA *prop)
+{
+ int flag;
- return (flag & PROP_EDITABLE) && (!id || !id->lib || (prop->flag & PROP_LIB_EXCEPTION));
+ prop= rna_ensure_property(prop);
+ flag= prop->editable ? prop->editable(ptr) : prop->flag;
+ return (flag & PROP_EDITABLE);
}
/* same as RNA_property_editable(), except this checks individual items in an array */
@@ -1937,8 +1939,12 @@ void RNA_property_pointer_set(PointerRNA *ptr, PropertyRNA *prop, PointerRNA ptr
else {
PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
- if(pprop->set && !((prop->flag & PROP_NEVER_NULL) && ptr_value.data == NULL))
+ if( pprop->set &&
+ !((prop->flag & PROP_NEVER_NULL) && ptr_value.data == NULL) &&
+ !((prop->flag & PROP_ID_SELF_CHECK) && ptr->id.data == ptr_value.id.data)
+ ) {
pprop->set(ptr, ptr_value);
+ }
}
}
@@ -3289,6 +3295,20 @@ void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
printf("RNA_enum_set: %s.%s not found.\n", ptr->type->identifier, name);
}
+void RNA_enum_set_identifier(PointerRNA *ptr, const char *name, const char *id)
+{
+ PropertyRNA *prop= RNA_struct_find_property(ptr, name);
+
+ if(prop) {
+ int value;
+ if(RNA_property_enum_value(NULL, ptr, prop, id, &value))
+ RNA_property_enum_set(ptr, prop, value);
+ else
+ printf("RNA_enum_set_identifier: %s.%s has no enum id '%s'.\n", ptr->type->identifier, name, id);
+ } else
+ printf("RNA_enum_set_identifier: %s.%s not found.\n", ptr->type->identifier, name);
+}
+
int RNA_enum_is_equal(bContext *C, PointerRNA *ptr, const char *name, const char *enumname)
{
PropertyRNA *prop= RNA_struct_find_property(ptr, name);
diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c
index 208f91a452f..453d9b9a844 100644
--- a/source/blender/makesrna/intern/rna_animation.c
+++ b/source/blender/makesrna/intern/rna_animation.c
@@ -249,6 +249,7 @@ static void rna_def_keyingset(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Active Path Index", "Current Keying Set index");
/* Flags */
+ // XXX: depreceated
prop= RNA_def_property(srna, "builtin", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", KEYINGSET_BUILTIN);
diff --git a/source/blender/makesrna/intern/rna_animation_api.c b/source/blender/makesrna/intern/rna_animation_api.c
index 7ce93658789..208e3b9ca4c 100644
--- a/source/blender/makesrna/intern/rna_animation_api.c
+++ b/source/blender/makesrna/intern/rna_animation_api.c
@@ -41,7 +41,7 @@
#include "BKE_animsys.h"
-static void rna_KeyingSet_add_destination(KeyingSet *keyingset, ReportList *reports,
+static void rna_KeyingSet_add_path(KeyingSet *keyingset, ReportList *reports,
ID *id, char rna_path[], int array_index, int entire_array,
int grouping_method, char group_name[])
{
@@ -53,11 +53,11 @@ static void rna_KeyingSet_add_destination(KeyingSet *keyingset, ReportList *repo
/* if data is valid, call the API function for this */
if (keyingset) {
- BKE_keyingset_add_destination(keyingset, id, group_name, rna_path, array_index, flag, grouping_method);
+ BKE_keyingset_add_path(keyingset, id, group_name, rna_path, array_index, flag, grouping_method);
keyingset->active_path= BLI_countlist(&keyingset->paths);
}
else {
- BKE_report(reports, RPT_ERROR, "Keying Set Destination could not be added.");
+ BKE_report(reports, RPT_ERROR, "Keying Set Path could not be added.");
}
}
@@ -69,7 +69,7 @@ void RNA_api_keyingset(StructRNA *srna)
PropertyRNA *parm;
/* Add Destination */
- func= RNA_def_function(srna, "add_destination", "rna_KeyingSet_add_destination");
+ func= RNA_def_function(srna, "add_destination", "rna_KeyingSet_add_path");
RNA_def_function_ui_description(func, "Add a new destination for the Keying Set.");
RNA_def_function_flag(func, FUNC_USE_REPORTS);
/* ID-block for target */
diff --git a/source/blender/makesrna/intern/rna_cloth.c b/source/blender/makesrna/intern/rna_cloth.c
index 961e0708adc..4ecb93eb1d6 100644
--- a/source/blender/makesrna/intern/rna_cloth.c
+++ b/source/blender/makesrna/intern/rna_cloth.c
@@ -225,6 +225,12 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Internal Friction", "");
RNA_def_property_update(prop, 0, "rna_cloth_update");
+ prop= RNA_def_property(srna, "collider_friction", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "collider_friction");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(prop, "Collider Friction", "");
+ RNA_def_property_update(prop, 0, "rna_cloth_update");
+
/* mass */
prop= RNA_def_property(srna, "mass", PROP_FLOAT, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c
index 02bfb9f9493..499423276ab 100644
--- a/source/blender/makesrna/intern/rna_curve.c
+++ b/source/blender/makesrna/intern/rna_curve.c
@@ -805,27 +805,27 @@ static void rna_def_curve(BlenderRNA *brna)
prop= RNA_def_property(srna, "resolution_u", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "resolu");
- RNA_def_property_ui_range(prop, 1, 1024, 1, 0);
RNA_def_property_range(prop, 1, INT_MAX);
+ RNA_def_property_ui_range(prop, 1, 64, 1, 0);
RNA_def_property_ui_text(prop, "Resolution U", "Surface resolution in U direction");
RNA_def_property_update(prop, 0, "rna_Curve_resolution_u_update_data");
prop= RNA_def_property(srna, "resolution_v", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "resolv");
- RNA_def_property_ui_range(prop, 1, 1024, 1, 0);
+ RNA_def_property_ui_range(prop, 1, 64, 1, 0);
RNA_def_property_range(prop, 1, INT_MAX);
RNA_def_property_ui_text(prop, "Resolution V", "Surface resolution in V direction");
RNA_def_property_update(prop, 0, "rna_Curve_resolution_v_update_data");
prop= RNA_def_property(srna, "render_resolution_u", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "resolu_ren");
- RNA_def_property_ui_range(prop, 0, 1024, 1, 0);
RNA_def_property_range(prop, 0, INT_MAX);
+ RNA_def_property_ui_range(prop, 1, 64, 1, 0);
RNA_def_property_ui_text(prop, "Render Resolution U", "Surface resolution in U direction used while rendering. Zero skips this property");
prop= RNA_def_property(srna, "render_resolution_v", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "resolv_ren");
- RNA_def_property_ui_range(prop, 0, 1024, 1, 0);
+ RNA_def_property_ui_range(prop, 1, 64, 1, 0);
RNA_def_property_range(prop, 0, INT_MAX);
RNA_def_property_ui_text(prop, "Render Resolution V", "Surface resolution in V direction used while rendering. Zero skips this property");
@@ -965,13 +965,15 @@ static void rna_def_curve_nurb(BlenderRNA *brna)
prop= RNA_def_property(srna, "resolution_u", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "resolu");
- RNA_def_property_range(prop, 1, 1024);
+ RNA_def_property_range(prop, 1, INT_MAX);
+ RNA_def_property_ui_range(prop, 1, 64, 1, 0);
RNA_def_property_ui_text(prop, "Resolution U", "Curve or Surface subdivisions per segment");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
prop= RNA_def_property(srna, "resolution_v", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "resolv");
- RNA_def_property_range(prop, 1, 1024);
+ RNA_def_property_range(prop, 1, INT_MAX);
+ RNA_def_property_ui_range(prop, 1, 64, 1, 0);
RNA_def_property_ui_text(prop, "Resolution V", "Surface subdivisions per segment");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
diff --git a/source/blender/makesrna/intern/rna_image_api.c b/source/blender/makesrna/intern/rna_image_api.c
index e394fd4f710..533d954871c 100644
--- a/source/blender/makesrna/intern/rna_image_api.c
+++ b/source/blender/makesrna/intern/rna_image_api.c
@@ -37,33 +37,18 @@
#ifdef RNA_RUNTIME
#include "BKE_image.h"
+#include "BKE_packedFile.h"
#include "BKE_main.h"
#include "BKE_utildefines.h"
+#include "IMB_imbuf.h"
+
#include "DNA_image_types.h"
#include "DNA_scene_types.h"
#include "MEM_guardedalloc.h"
-/*
- User should check if returned path exists before copying a file there.
-
- TODO: it would be better to return a (abs, rel) tuple.
-*/
-static char *rna_Image_get_export_path(Image *image, char *dest_dir, int rel)
-{
- int length = FILE_MAX;
- char *path= MEM_callocN(length, "image file path");
-
- if (!BKE_get_image_export_path(image, dest_dir, rel ? NULL : path, length, rel ? path : NULL, length )) {
- MEM_freeN(path);
- return NULL;
- }
-
- return path;
-}
-
-static void rna_Image_save(Image *image, bContext *C, ReportList *reports, char *path, Scene *scene)
+static void rna_Image_save_render(Image *image, bContext *C, ReportList *reports, char *path, Scene *scene)
{
ImBuf *ibuf;
@@ -92,15 +77,25 @@ static void rna_Image_save(Image *image, bContext *C, ReportList *reports, char
}
}
-char *rna_Image_get_abs_filename(Image *image, bContext *C)
+static void rna_Image_save(Image *image, ReportList *reports)
{
- char *filename= MEM_callocN(FILE_MAX, "Image.get_abs_filename()");
-
- BLI_strncpy(filename, image->name, FILE_MAXDIR + FILE_MAXFILE);
- BLI_convertstringcode(filename, CTX_data_main(C)->name);
- BLI_convertstringframe(filename, CTX_data_scene(C)->r.cfra, 0);
-
- return filename;
+ ImBuf *ibuf= BKE_image_get_ibuf(image, NULL);
+ if(ibuf) {
+ if(image->packedfile) {
+ if (writePackedFile(reports, image->name, image->packedfile, 0) != RET_OK) {
+ BKE_reportf(reports, RPT_ERROR, "Image \"%s\" could saved packed file to \"%s\"", image->id.name+2, image->name);
+ }
+ }
+ else if (IMB_saveiff(ibuf, image->name, ibuf->flags)) {
+ ibuf->userflags &= ~IB_BITMAPDIRTY;
+ }
+ else {
+ BKE_reportf(reports, RPT_ERROR, "Image \"%s\" could not be saved to \"%s\"", image->id.name+2, image->name);
+ }
+ }
+ else {
+ BKE_reportf(reports, RPT_ERROR, "Image \"%s\" does not have any image data", image->id.name+2);
+ }
}
#else
@@ -110,27 +105,16 @@ void RNA_api_image(StructRNA *srna)
FunctionRNA *func;
PropertyRNA *parm;
- func= RNA_def_function(srna, "get_export_path", "rna_Image_get_export_path");
- RNA_def_function_ui_description(func, "Produce image export path.");
- parm= RNA_def_string(func, "dest_dir", "", 0, "", "Destination directory.");
- RNA_def_property_flag(parm, PROP_REQUIRED);
- parm= RNA_def_boolean(func, "get_rel_path", 1, "", "Return relative path if True.");
- RNA_def_property_flag(parm, PROP_REQUIRED);
- parm= RNA_def_string(func, "path", "", 0, "", "Absolute export path.");
- RNA_def_function_return(func, parm);
-
- func= RNA_def_function(srna, "get_abs_filename", "rna_Image_get_abs_filename");
- RNA_def_function_ui_description(func, "Get absolute filename.");
- RNA_def_function_flag(func, FUNC_USE_CONTEXT);
- parm= RNA_def_string_file_path(func, "abs_filename", NULL, 0, "", "Image/movie absolute filename.");
- RNA_def_function_return(func, parm);
-
- func= RNA_def_function(srna, "save", "rna_Image_save");
- RNA_def_function_ui_description(func, "Save image to a specific path.");
+ func= RNA_def_function(srna, "save_render", "rna_Image_save_render");
+ RNA_def_function_ui_description(func, "Save image to a specific path using a scenes render settings.");
RNA_def_function_flag(func, FUNC_USE_CONTEXT|FUNC_USE_REPORTS);
parm= RNA_def_string(func, "path", "", 0, "", "Save path.");
RNA_def_property_flag(parm, PROP_REQUIRED);
parm= RNA_def_pointer(func, "scene", "Scene", "", "Scene to take image parameters from.");
+
+ func= RNA_def_function(srna, "save", "rna_Image_save");
+ RNA_def_function_ui_description(func, "Save image to its source path.");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
}
#endif
diff --git a/source/blender/makesrna/intern/rna_lamp.c b/source/blender/makesrna/intern/rna_lamp.c
index f6197a8da15..5b9913ad311 100644
--- a/source/blender/makesrna/intern/rna_lamp.c
+++ b/source/blender/makesrna/intern/rna_lamp.c
@@ -346,12 +346,13 @@ static void rna_def_lamp(BlenderRNA *brna)
prop= RNA_def_property(srna, "distance", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "dist");
- RNA_def_property_ui_range(prop, 0, 1000, 1.0, 2);
+ RNA_def_property_range(prop, 0, INT_MAX);
+ RNA_def_property_ui_range(prop, 0, 1000, 1, 3);
RNA_def_property_ui_text(prop, "Distance", "Falloff distance - the light is at half the original intensity at this point");
RNA_def_property_update(prop, 0, "rna_Lamp_draw_update");
prop= RNA_def_property(srna, "energy", PROP_FLOAT, PROP_NONE);
- RNA_def_property_ui_range(prop, 0, 10.0, 10, 2);
+ RNA_def_property_ui_range(prop, 0, 10, 1, 3);
RNA_def_property_ui_text(prop, "Energy", "Amount of light that the lamp emits");
RNA_def_property_update(prop, 0, "rna_Lamp_draw_update");
diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c
index e937a3b10c2..56c0819680d 100644
--- a/source/blender/makesrna/intern/rna_main_api.c
+++ b/source/blender/makesrna/intern/rna_main_api.c
@@ -30,6 +30,7 @@
#include <stdio.h>
#include "RNA_define.h"
+#include "RNA_access.h"
#include "RNA_types.h"
#include "RNA_enum_types.h"
@@ -38,6 +39,7 @@
#ifdef RNA_RUNTIME
#include "BKE_main.h"
+#include "BKE_curve.h"
#include "BKE_mesh.h"
#include "BKE_armature.h"
#include "BKE_library.h"
@@ -109,12 +111,54 @@ void rna_Main_scenes_remove(Main *bmain, bContext *C, ReportList *reports, struc
unlink_scene(bmain, scene, newscene);
}
-Object *rna_Main_objects_new(Main *bmain, char* name, int type)
-{
- Object *ob= add_only_object(type, name);
+Object *rna_Main_objects_new(Main *bmain, ReportList *reports, char* name, ID *data)
+{
+ Object *ob;
+ int type= OB_EMPTY;
+ if(data) {
+ switch(GS(data->name)) {
+ case ID_ME:
+ type= OB_MESH;
+ break;
+ case ID_CU:
+ type= curve_type((struct Curve *)data);
+ break;
+ case ID_MB:
+ type= OB_MBALL;
+ break;
+ case ID_LA:
+ type= OB_LAMP;
+ break;
+ case ID_CA:
+ type= OB_CAMERA;
+ break;
+ case ID_LT:
+ type= OB_LATTICE;
+ break;
+ case ID_AR:
+ type= OB_ARMATURE;
+ break;
+ default:
+ {
+ const char *idname;
+ if(RNA_enum_id_from_value(id_type_items, GS(data->name), &idname) == 0)
+ idname= "UNKNOWN";
+
+ BKE_reportf(reports, RPT_ERROR, "ID type '%s' is not valid for a object.", idname);
+ return NULL;
+ }
+ }
+
+ data->us++;
+ }
+
+ ob= add_only_object(type, name);
ob->id.us--;
+
+ ob->data= data;
return ob;
}
+
void rna_Main_objects_remove(Main *bmain, ReportList *reports, struct Object *object)
{
/*
@@ -337,10 +381,11 @@ void RNA_def_main_objects(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_struct_ui_text(srna, "Main Objects", "Collection of objects");
func= RNA_def_function(srna, "new", "rna_Main_objects_new");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
RNA_def_function_ui_description(func, "Add a new object to the main database");
parm= RNA_def_string(func, "name", "Object", 0, "", "New name for the datablock.");
RNA_def_property_flag(parm, PROP_REQUIRED);
- parm= RNA_def_enum(func, "type", object_type_items, 0, "", "Type of Object.");
+ parm= RNA_def_pointer(func, "object_data", "ID", "", "Object data or None for an empty object.");
RNA_def_property_flag(parm, PROP_REQUIRED);
/* return type */
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index 295119bf8a2..117a1d5bc60 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -1443,6 +1443,7 @@ static void rna_def_object(BlenderRNA *brna)
static float default_quat[4] = {1,0,0,0}; /* default quaternion values */
static float default_axisAngle[4] = {0,0,1,0}; /* default axis-angle rotation values */
+ static float default_scale[3] = {1,1,1}; /* default scale values */
int matrix_dimsize[]= {4, 4};
int boundbox_dimsize[]= {8, 3};
@@ -1603,6 +1604,7 @@ static void rna_def_object(BlenderRNA *brna)
prop= RNA_def_property(srna, "scale", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "size");
RNA_def_property_editable_array_func(prop, "rna_Object_scale_editable");
+ RNA_def_property_float_array_default(prop, default_scale);
RNA_def_property_ui_text(prop, "Scale", "Scaling of the object");
RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_update");
@@ -1724,8 +1726,9 @@ static void rna_def_object(BlenderRNA *brna)
prop= RNA_def_property(srna, "empty_draw_size", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "empty_drawsize");
- RNA_def_property_range(prop, 0.01, 10.0);
- RNA_def_property_ui_text(prop, "Empty Display Size", "Size of of display for empties in the viewport");
+ RNA_def_property_range(prop, 0.1f, 1000.0f);
+ RNA_def_property_ui_range(prop, 0.01, 100, 1, 1);
+ RNA_def_property_ui_text(prop, "Empty Display Size", "Size of display for empties in the viewport");
RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL);
/* render */
diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c
index 44bf85679c4..240d02f7f9e 100644
--- a/source/blender/makesrna/intern/rna_pose.c
+++ b/source/blender/makesrna/intern/rna_pose.c
@@ -663,6 +663,7 @@ static void rna_def_pose_channel(BlenderRNA *brna)
static float default_quat[4] = {1,0,0,0}; /* default quaternion values */
static float default_axisAngle[4] = {0,0,1,0}; /* default axis-angle rotation values */
+ static float default_scale[3] = {1,1,1}; /* default scale values */
StructRNA *srna;
PropertyRNA *prop;
@@ -722,6 +723,7 @@ static void rna_def_pose_channel(BlenderRNA *brna)
prop= RNA_def_property(srna, "scale", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "size");
RNA_def_property_editable_array_func(prop, "rna_PoseChannel_scale_editable");
+ RNA_def_property_float_array_default(prop, default_scale);
RNA_def_property_ui_text(prop, "Scale", "");
RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable"); // XXX... disabled, since proxy-locked layers are currently used for ensuring proxy-syncing too
RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update");
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 6c6a5b2c0cb..c5f31590029 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -354,12 +354,12 @@ static void rna_Scene_active_keying_set_index_range(PointerRNA *ptr, int *min, i
}
-static char *rna_SceneRenderData_path(PointerRNA *ptr)
+static char *rna_RenderSettings_path(PointerRNA *ptr)
{
- return BLI_sprintfN("render_data");
+ return BLI_sprintfN("render");
}
-static int rna_SceneRenderData_threads_get(PointerRNA *ptr)
+static int rna_RenderSettings_threads_get(PointerRNA *ptr)
{
RenderData *rd= (RenderData*)ptr->data;
@@ -369,7 +369,7 @@ static int rna_SceneRenderData_threads_get(PointerRNA *ptr)
return BLI_system_thread_count();
}
-static int rna_SceneRenderData_save_buffers_get(PointerRNA *ptr)
+static int rna_RenderSettings_save_buffers_get(PointerRNA *ptr)
{
RenderData *rd= (RenderData*)ptr->data;
if(rd->mode & R_BORDER)
@@ -378,14 +378,14 @@ static int rna_SceneRenderData_save_buffers_get(PointerRNA *ptr)
return (rd->scemode & (R_EXR_TILE_FILE|R_FULL_SAMPLE)) != 0;
}
-static int rna_SceneRenderData_full_sample_get(PointerRNA *ptr)
+static int rna_RenderSettings_full_sample_get(PointerRNA *ptr)
{
RenderData *rd= (RenderData*)ptr->data;
return (rd->scemode & R_FULL_SAMPLE) && !(rd->mode & R_BORDER);
}
-static void rna_SceneRenderData_file_format_set(PointerRNA *ptr, int value)
+static void rna_RenderSettings_file_format_set(PointerRNA *ptr, int value)
{
RenderData *rd= (RenderData*)ptr->data;
@@ -413,7 +413,7 @@ static void rna_SceneRender_file_ext_get(PointerRNA *ptr, char *str)
BKE_add_image_extension(str, rd->imtype);
}
-void rna_SceneRenderData_jpeg2k_preset_update(RenderData *rd)
+void rna_RenderSettings_jpeg2k_preset_update(RenderData *rd)
{
rd->subimtype &= ~(R_JPEG2K_12BIT|R_JPEG2K_16BIT | R_JPEG2K_CINE_PRESET|R_JPEG2K_CINE_48FPS);
@@ -435,37 +435,37 @@ void rna_SceneRenderData_jpeg2k_preset_update(RenderData *rd)
}
#ifdef WITH_OPENJPEG
-static void rna_SceneRenderData_jpeg2k_preset_set(PointerRNA *ptr, int value)
+static void rna_RenderSettings_jpeg2k_preset_set(PointerRNA *ptr, int value)
{
RenderData *rd= (RenderData*)ptr->data;
rd->jp2_preset= value;
- rna_SceneRenderData_jpeg2k_preset_update(rd);
+ rna_RenderSettings_jpeg2k_preset_update(rd);
}
-static void rna_SceneRenderData_jpeg2k_depth_set(PointerRNA *ptr, int value)
+static void rna_RenderSettings_jpeg2k_depth_set(PointerRNA *ptr, int value)
{
RenderData *rd= (RenderData*)ptr->data;
rd->jp2_depth= value;
- rna_SceneRenderData_jpeg2k_preset_update(rd);
+ rna_RenderSettings_jpeg2k_preset_update(rd);
}
#endif
#ifdef WITH_QUICKTIME
-static int rna_SceneRenderData_qtcodecsettings_codecType_get(PointerRNA *ptr)
+static int rna_RenderSettings_qtcodecsettings_codecType_get(PointerRNA *ptr)
{
RenderData *rd= (RenderData*)ptr->data;
return quicktime_rnatmpvalue_from_codectype(rd->qtcodecsettings.codecType);
}
-static void rna_SceneRenderData_qtcodecsettings_codecType_set(PointerRNA *ptr, int value)
+static void rna_RenderSettings_qtcodecsettings_codecType_set(PointerRNA *ptr, int value)
{
RenderData *rd= (RenderData*)ptr->data;
rd->qtcodecsettings.codecType = quicktime_codecType_from_rnatmpvalue(value);
}
-static EnumPropertyItem *rna_SceneRenderData_qtcodecsettings_codecType_itemf(bContext *C, PointerRNA *ptr, int *free)
+static EnumPropertyItem *rna_RenderSettings_qtcodecsettings_codecType_itemf(bContext *C, PointerRNA *ptr, int *free)
{
EnumPropertyItem *item= NULL;
EnumPropertyItem tmp = {0, "", 0, "", ""};
@@ -492,19 +492,19 @@ static EnumPropertyItem *rna_SceneRenderData_qtcodecsettings_codecType_itemf(bCo
}
#endif
-static int rna_SceneRenderData_active_layer_index_get(PointerRNA *ptr)
+static int rna_RenderSettings_active_layer_index_get(PointerRNA *ptr)
{
RenderData *rd= (RenderData*)ptr->data;
return rd->actlay;
}
-static void rna_SceneRenderData_active_layer_index_set(PointerRNA *ptr, int value)
+static void rna_RenderSettings_active_layer_index_set(PointerRNA *ptr, int value)
{
RenderData *rd= (RenderData*)ptr->data;
rd->actlay= value;
}
-static void rna_SceneRenderData_active_layer_index_range(PointerRNA *ptr, int *min, int *max)
+static void rna_RenderSettings_active_layer_index_range(PointerRNA *ptr, int *min, int *max)
{
RenderData *rd= (RenderData*)ptr->data;
@@ -513,7 +513,7 @@ static void rna_SceneRenderData_active_layer_index_range(PointerRNA *ptr, int *m
*max= MAX2(0, *max);
}
-static void rna_SceneRenderData_engine_set(PointerRNA *ptr, int value)
+static void rna_RenderSettings_engine_set(PointerRNA *ptr, int value)
{
RenderData *rd= (RenderData*)ptr->data;
RenderEngineType *type= BLI_findlink(&R_engines, value);
@@ -522,7 +522,7 @@ static void rna_SceneRenderData_engine_set(PointerRNA *ptr, int value)
BLI_strncpy(rd->engine, type->idname, sizeof(rd->engine));
}
-static EnumPropertyItem *rna_SceneRenderData_engine_itemf(bContext *C, PointerRNA *ptr, int *free)
+static EnumPropertyItem *rna_RenderSettings_engine_itemf(bContext *C, PointerRNA *ptr, int *free)
{
RenderEngineType *type;
EnumPropertyItem *item= NULL;
@@ -542,7 +542,7 @@ static EnumPropertyItem *rna_SceneRenderData_engine_itemf(bContext *C, PointerRN
return item;
}
-static int rna_SceneRenderData_engine_get(PointerRNA *ptr)
+static int rna_RenderSettings_engine_get(PointerRNA *ptr)
{
RenderData *rd= (RenderData*)ptr->data;
RenderEngineType *type;
@@ -555,7 +555,7 @@ static int rna_SceneRenderData_engine_get(PointerRNA *ptr)
return 0;
}
-static void rna_SceneRenderData_color_management_update(Main *bmain, Scene *unused, PointerRNA *ptr)
+static void rna_RenderSettings_color_management_update(Main *bmain, Scene *unused, PointerRNA *ptr)
{
/* reset image nodes */
Scene *scene= (Scene*)ptr->id.data;
@@ -595,12 +595,12 @@ static void rna_SceneRenderLayer_name_set(PointerRNA *ptr, const char *value)
}
}
-static int rna_SceneRenderData_multiple_engines_get(PointerRNA *ptr)
+static int rna_RenderSettings_multiple_engines_get(PointerRNA *ptr)
{
return (BLI_countlist(&R_engines) > 1);
}
-static int rna_SceneRenderData_use_game_engine_get(PointerRNA *ptr)
+static int rna_RenderSettings_use_game_engine_get(PointerRNA *ptr)
{
RenderData *rd= (RenderData*)ptr->data;
RenderEngineType *type;
@@ -1563,51 +1563,46 @@ static void rna_def_scene_game_data(BlenderRNA *brna)
prop= RNA_def_property(srna, "use_occlusion_culling", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", (1 << 5)); //XXX mode hardcoded // WO_DBVT_CULLING
RNA_def_property_ui_text(prop, "DBVT culling", "Use optimized Bullet DBVT tree for view frustrum and occlusion culling");
- RNA_def_property_update(prop, NC_SCENE, NULL);
// not used // deprecated !!!!!!!!!!!!!
prop= RNA_def_property(srna, "activity_culling", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", (1 << 3)); //XXX mode hardcoded
RNA_def_property_ui_text(prop, "Activity Culling", "Activity culling is enabled");
- RNA_def_property_update(prop, NC_SCENE, NULL);
// not used // deprecated !!!!!!!!!!!!!
prop= RNA_def_property(srna, "activity_culling_box_radius", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "activityBoxRadius");
RNA_def_property_range(prop, 0.0, 1000.0);
RNA_def_property_ui_text(prop, "box radius", "Radius of the activity bubble, in Manhattan length. Objects outside the box are activity-culled");
- RNA_def_property_update(prop, NC_SCENE, NULL);
/* booleans */
- prop= RNA_def_property(srna, "all_frames", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", GAME_ENABLE_ALL_FRAMES);
- RNA_def_property_ui_text(prop, "All Frames", "Render as many frames as possible, rather than respecting framerate");
- RNA_def_property_update(prop, NC_SCENE, NULL);
-
prop= RNA_def_property(srna, "show_debug_properties", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GAME_SHOW_DEBUG_PROPS);
RNA_def_property_ui_text(prop, "Show Debug Properties", "Show properties marked for debugging while the game runs");
- RNA_def_property_update(prop, NC_SCENE, NULL);
prop= RNA_def_property(srna, "show_framerate_profile", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GAME_SHOW_FRAMERATE);
RNA_def_property_ui_text(prop, "Show Framerate and Profile", "Show framerate and profiling information while the game runs");
- RNA_def_property_update(prop, NC_SCENE, NULL);
prop= RNA_def_property(srna, "show_physics_visualization", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GAME_SHOW_PHYSICS);
RNA_def_property_ui_text(prop, "Show Physics Visualization", "Show a visualization of physics bounds and interactions");
- RNA_def_property_update(prop, NC_SCENE, NULL);
- prop= RNA_def_property(srna, "display_lists", PROP_BOOLEAN, PROP_NONE);
+ prop= RNA_def_property(srna, "use_frame_rate", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", GAME_ENABLE_ALL_FRAMES);
+ RNA_def_property_ui_text(prop, "Use Frame Rate", "Respect the frame rate rather then rendering as many frames as possible");
+
+ prop= RNA_def_property(srna, "use_display_lists", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GAME_DISPLAY_LISTS);
RNA_def_property_ui_text(prop, "Display Lists", "Use display lists to speed up rendering by keeping geometry on the GPU");
- RNA_def_property_update(prop, NC_SCENE, NULL);
- prop= RNA_def_property(srna, "deprecation_warnings", PROP_BOOLEAN, PROP_NONE);
+ prop= RNA_def_property(srna, "use_deprecation_warnings", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", GAME_IGNORE_DEPRECATION_WARNINGS);
RNA_def_property_ui_text(prop, "Deprecation Warnings", "Print warnings when using deprecated features in the python API");
- RNA_def_property_update(prop, NC_SCENE, NULL);
+
+ prop= RNA_def_property(srna, "use_animation_record", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GAME_ENABLE_ANIMATION_RECORD);
+ RNA_def_property_ui_text(prop, "Record Animation", "Record animation to fcurves");
/* materials */
prop= RNA_def_property(srna, "material_mode", PROP_ENUM, PROP_NONE);
@@ -1894,10 +1889,10 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
{0, "BLENDER_RENDER", 0, "Blender Render", ""},
{0, NULL, 0, NULL, NULL}};
- srna= RNA_def_struct(brna, "SceneRenderData", NULL);
+ srna= RNA_def_struct(brna, "RenderSettings", NULL);
RNA_def_struct_sdna(srna, "RenderData");
RNA_def_struct_nested(brna, srna, "Scene");
- RNA_def_struct_path_func(srna, "rna_SceneRenderData_path");
+ RNA_def_struct_path_func(srna, "rna_RenderSettings_path");
RNA_def_struct_ui_text(srna, "Render Data", "Rendering settings for a Scene datablock");
prop= RNA_def_property(srna, "color_mode", PROP_ENUM, PROP_NONE);
@@ -2019,14 +2014,14 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
prop= RNA_def_property(srna, "jpeg2k_preset", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "jp2_preset");
RNA_def_property_enum_items(prop, jp2_preset_items);
- RNA_def_property_enum_funcs(prop, NULL, "rna_SceneRenderData_jpeg2k_preset_set", NULL);
+ RNA_def_property_enum_funcs(prop, NULL, "rna_RenderSettings_jpeg2k_preset_set", NULL);
RNA_def_property_ui_text(prop, "Preset", "Use a DCI Standard preset for saving jpeg2000");
RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
prop= RNA_def_property(srna, "jpeg2k_depth", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "jp2_depth");
RNA_def_property_enum_items(prop, jp2_depth_items);
- RNA_def_property_enum_funcs(prop, NULL, "rna_SceneRenderData_jpeg2k_depth_set", NULL);
+ RNA_def_property_enum_funcs(prop, NULL, "rna_RenderSettings_jpeg2k_depth_set", NULL);
RNA_def_property_ui_text(prop, "Depth", "Bit depth per channel");
RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
@@ -2042,9 +2037,9 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
prop= RNA_def_property(srna, "quicktime_codec_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "qtcodecsettings.codecType");
RNA_def_property_enum_items(prop, quicktime_codec_type_items);
- RNA_def_property_enum_funcs(prop, "rna_SceneRenderData_qtcodecsettings_codecType_get",
- "rna_SceneRenderData_qtcodecsettings_codecType_set",
- "rna_SceneRenderData_qtcodecsettings_codecType_itemf");
+ RNA_def_property_enum_funcs(prop, "rna_RenderSettings_qtcodecsettings_codecType_get",
+ "rna_RenderSettings_qtcodecsettings_codecType_set",
+ "rna_RenderSettings_qtcodecsettings_codecType_itemf");
RNA_def_property_ui_text(prop, "Codec", "QuickTime codec type");
RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
@@ -2286,7 +2281,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
prop= RNA_def_property(srna, "threads", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "threads");
RNA_def_property_range(prop, 1, BLENDER_MAX_THREADS);
- RNA_def_property_int_funcs(prop, "rna_SceneRenderData_threads_get", NULL, NULL);
+ RNA_def_property_int_funcs(prop, "rna_RenderSettings_threads_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Threads", "Number of CPU threads to use simultaneously while rendering (for multi-core/CPU systems)");
RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
@@ -2364,7 +2359,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
prop= RNA_def_property(srna, "color_management", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "color_mgt_flag", R_COLOR_MANAGEMENT);
RNA_def_property_ui_text(prop, "Color Management", "Use color profiles and gamma corrected imaging pipeline");
- RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS|NC_MATERIAL|ND_SHADING, "rna_SceneRenderData_color_management_update");
+ RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS|NC_MATERIAL|ND_SHADING, "rna_RenderSettings_color_management_update");
prop= RNA_def_property(srna, "use_file_extension", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "scemode", R_EXTENSION);
@@ -2374,7 +2369,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
prop= RNA_def_property(srna, "file_format", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "imtype");
RNA_def_property_enum_items(prop, image_type_items);
- RNA_def_property_enum_funcs(prop, NULL, "rna_SceneRenderData_file_format_set", NULL);
+ RNA_def_property_enum_funcs(prop, NULL, "rna_RenderSettings_file_format_set", NULL);
RNA_def_property_ui_text(prop, "File Format", "File format to save the rendered images as");
RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
@@ -2396,13 +2391,13 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
prop= RNA_def_property(srna, "save_buffers", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "scemode", R_EXR_TILE_FILE);
- RNA_def_property_boolean_funcs(prop, "rna_SceneRenderData_save_buffers_get", NULL);
+ RNA_def_property_boolean_funcs(prop, "rna_RenderSettings_save_buffers_get", NULL);
RNA_def_property_ui_text(prop, "Save Buffers","Save tiles for all RenderLayers and SceneNodes to files in the temp directory (saves memory, required for Full Sample)");
RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
prop= RNA_def_property(srna, "full_sample", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "scemode", R_FULL_SAMPLE);
- RNA_def_property_boolean_funcs(prop, "rna_SceneRenderData_full_sample_get", NULL);
+ RNA_def_property_boolean_funcs(prop, "rna_RenderSettings_full_sample_get", NULL);
RNA_def_property_ui_text(prop, "Full Sample","Save for every anti-aliasing sample the entire RenderLayer results. This solves anti-aliasing issues with compositing");
RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
@@ -2570,24 +2565,24 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
prop= RNA_def_property(srna, "active_layer_index", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "actlay");
- RNA_def_property_int_funcs(prop, "rna_SceneRenderData_active_layer_index_get", "rna_SceneRenderData_active_layer_index_set", "rna_SceneRenderData_active_layer_index_range");
+ RNA_def_property_int_funcs(prop, "rna_RenderSettings_active_layer_index_get", "rna_RenderSettings_active_layer_index_set", "rna_RenderSettings_active_layer_index_range");
RNA_def_property_ui_text(prop, "Active Layer Index", "Active index in render layer array");
RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
/* engine */
prop= RNA_def_property(srna, "engine", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, engine_items);
- RNA_def_property_enum_funcs(prop, "rna_SceneRenderData_engine_get", "rna_SceneRenderData_engine_set", "rna_SceneRenderData_engine_itemf");
+ RNA_def_property_enum_funcs(prop, "rna_RenderSettings_engine_get", "rna_RenderSettings_engine_set", "rna_RenderSettings_engine_itemf");
RNA_def_property_ui_text(prop, "Engine", "Engine to use for rendering");
RNA_def_property_update(prop, NC_WINDOW, NULL);
prop= RNA_def_property(srna, "multiple_engines", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_funcs(prop, "rna_SceneRenderData_multiple_engines_get", NULL);
+ RNA_def_property_boolean_funcs(prop, "rna_RenderSettings_multiple_engines_get", NULL);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Multiple Engines", "More than one rendering engine is available");
prop= RNA_def_property(srna, "use_game_engine", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_funcs(prop, "rna_SceneRenderData_use_game_engine_get", NULL);
+ RNA_def_property_boolean_funcs(prop, "rna_RenderSettings_use_game_engine_get", NULL);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Use Game Engine", "Current rendering engine is a game engine");
@@ -2779,7 +2774,7 @@ void RNA_def_scene(BlenderRNA *brna)
RNA_def_property_int_funcs(prop, NULL, "rna_Scene_start_frame_set", NULL);
RNA_def_property_range(prop, MINFRAME, MAXFRAME);
RNA_def_property_ui_text(prop, "Start Frame", "First frame of the playback/rendering range");
- RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
+ RNA_def_property_update(prop, NC_SCENE|ND_FRAME, NULL);
prop= RNA_def_property(srna, "end_frame", PROP_INT, PROP_TIME);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
@@ -2787,15 +2782,15 @@ void RNA_def_scene(BlenderRNA *brna)
RNA_def_property_int_funcs(prop, NULL, "rna_Scene_end_frame_set", NULL);
RNA_def_property_range(prop, MINFRAME, MAXFRAME);
RNA_def_property_ui_text(prop, "End Frame", "Final frame of the playback/rendering range");
- RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
+ RNA_def_property_update(prop, NC_SCENE|ND_FRAME, NULL);
prop= RNA_def_property(srna, "frame_step", PROP_INT, PROP_TIME);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_int_sdna(prop, NULL, "r.frame_step");
RNA_def_property_range(prop, 0, MAXFRAME);
- RNA_def_property_ui_range(prop, 0, 100, 1, 0);
+ RNA_def_property_ui_range(prop, 1, 100, 1, 0);
RNA_def_property_ui_text(prop, "Frame Step", "Number of frames to skip forward while rendering/playing back each frame");
- RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
+ RNA_def_property_update(prop, NC_SCENE|ND_FRAME, NULL);
/* Preview Range (frame-range for UI playback) */
prop=RNA_def_property(srna, "use_preview_range", PROP_BOOLEAN, PROP_NONE);
@@ -2803,21 +2798,21 @@ void RNA_def_scene(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "r.flag", SCER_PRV_RANGE);
RNA_def_property_boolean_funcs(prop, NULL, "rna_Scene_use_preview_range_set");
RNA_def_property_ui_text(prop, "Use Preview Range", "");
- RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
+ RNA_def_property_update(prop, NC_SCENE|ND_FRAME, NULL);
prop= RNA_def_property(srna, "preview_range_start_frame", PROP_INT, PROP_TIME);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_int_sdna(prop, NULL, "r.psfra");
RNA_def_property_int_funcs(prop, NULL, "rna_Scene_preview_range_start_frame_set", NULL);
RNA_def_property_ui_text(prop, "Preview Range Start Frame", "");
- RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
+ RNA_def_property_update(prop, NC_SCENE|ND_FRAME, NULL);
prop= RNA_def_property(srna, "preview_range_end_frame", PROP_INT, PROP_TIME);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_int_sdna(prop, NULL, "r.pefra");
RNA_def_property_int_funcs(prop, NULL, "rna_Scene_preview_range_end_frame_set", NULL);
RNA_def_property_ui_text(prop, "Preview Range End Frame", "");
- RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
+ RNA_def_property_update(prop, NC_SCENE|ND_FRAME, NULL);
/* Stamp */
prop= RNA_def_property(srna, "stamp_note", PROP_STRING, PROP_NONE);
@@ -2913,10 +2908,10 @@ void RNA_def_scene(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Physics_update");
/* Render Data */
- prop= RNA_def_property(srna, "render_data", PROP_POINTER, PROP_NONE);
+ prop= RNA_def_property(srna, "render", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "r");
- RNA_def_property_struct_type(prop, "SceneRenderData");
+ RNA_def_property_struct_type(prop, "RenderSettings");
RNA_def_property_ui_text(prop, "Render Data", "");
/* Markers */
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index ee2c96bcbd2..6f6ee5216ae 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -47,6 +47,7 @@
#include "BKE_depsgraph.h"
#include "DNA_object_types.h"
#include "GPU_draw.h"
+#include "BKE_global.h"
#include "MEM_guardedalloc.h"
@@ -55,6 +56,13 @@ static void rna_userdef_update(Main *bmain, Scene *scene, PointerRNA *ptr)
WM_main_add_notifier(NC_WINDOW, NULL);
}
+static void rna_userdef_script_autoexec_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ UserDef *userdef = (UserDef*)ptr->data;
+ if (userdef->flag & USER_SCRIPT_AUTOEXEC_DISABLE) G.f &= ~G_SCRIPT_AUTOEXEC;
+ else G.f |= G_SCRIPT_AUTOEXEC;
+}
+
static void rna_userdef_mipmap_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
GPU_set_mipmap(!(U.gameflags & USER_DISABLE_MIPMAP));
@@ -211,16 +219,16 @@ static void rna_userdef_autosave_update(Main *bmain, Scene *scene, PointerRNA *p
rna_userdef_update(bmain, scene, ptr);
}
-static bExtension *rna_userdef_extension_new(void)
+static bAddon *rna_userdef_addon_new(void)
{
- bExtension *bext= MEM_callocN(sizeof(bExtension), "bext");
- BLI_addtail(&U.extensions, bext);
+ bAddon *bext= MEM_callocN(sizeof(bAddon), "bAddon");
+ BLI_addtail(&U.addons, bext);
return bext;
}
-static void rna_userdef_extension_remove(bExtension *bext)
+static void rna_userdef_addon_remove(bAddon *bext)
{
- BLI_freelinkN(&U.extensions, bext);
+ BLI_freelinkN(&U.addons, bext);
}
@@ -1687,14 +1695,14 @@ static void rna_def_userdef_themes(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Bone Color Sets", "");
}
-static void rna_def_userdef_extensions(BlenderRNA *brna)
+static void rna_def_userdef_addon(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
- srna= RNA_def_struct(brna, "Extension", NULL);
- RNA_def_struct_sdna(srna, "bExtension");
- RNA_def_struct_ui_text(srna, "Extension", "Python extensions to be loaded automatically");
+ srna= RNA_def_struct(brna, "Addon", NULL);
+ RNA_def_struct_sdna(srna, "bAddon");
+ RNA_def_struct_ui_text(srna, "Addon", "Python addons to be loaded automatically");
prop= RNA_def_property(srna, "module", PROP_STRING, PROP_NONE);
RNA_def_property_ui_text(prop, "Module", "Module name");
@@ -1727,7 +1735,6 @@ static void rna_def_userdef_dothemes(BlenderRNA *brna)
rna_def_userdef_theme_space_logic(brna);
rna_def_userdef_theme_colorset(brna);
rna_def_userdef_themes(brna);
- rna_def_userdef_extensions(brna);
}
static void rna_def_userdef_solidlight(BlenderRNA *brna)
@@ -2346,9 +2353,10 @@ static void rna_def_userdef_system(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_ALLWINCODECS);
RNA_def_property_ui_text(prop, "Enable All Codecs", "Enables automatic saving of preview images in the .blend file (Windows only)");
- prop= RNA_def_property(srna, "auto_run_python_scripts", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_DONT_DOSCRIPTLINKS);
+ prop= RNA_def_property(srna, "auto_execute_scripts", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", USER_SCRIPT_AUTOEXEC_DISABLE);
RNA_def_property_ui_text(prop, "Auto Run Python Scripts", "Allow any .blend file to run scripts automatically (unsafe with blend files from an untrusted source)");
+ RNA_def_property_update(prop, 0, "rna_userdef_script_autoexec_update");
prop= RNA_def_property(srna, "prefetch_frames", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "prefetchframes");
@@ -2649,27 +2657,27 @@ static void rna_def_userdef_filepaths(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Save Preview Images", "Enables automatic saving of preview images in the .blend file");
}
-void rna_def_userdef_extension_collection(BlenderRNA *brna, PropertyRNA *cprop)
+void rna_def_userdef_addon_collection(BlenderRNA *brna, PropertyRNA *cprop)
{
StructRNA *srna;
FunctionRNA *func;
PropertyRNA *parm;
- RNA_def_property_srna(cprop, "UserExtensions");
- srna= RNA_def_struct(brna, "UserExtensions", NULL);
- RNA_def_struct_ui_text(srna, "User Extensions", "Collection of extensions");
+ RNA_def_property_srna(cprop, "Addons");
+ srna= RNA_def_struct(brna, "Addons", NULL);
+ RNA_def_struct_ui_text(srna, "User Add-Ons", "Collection of add-ons");
- func= RNA_def_function(srna, "new", "rna_userdef_extension_new");
+ func= RNA_def_function(srna, "new", "rna_userdef_addon_new");
RNA_def_function_flag(func, FUNC_NO_SELF);
- RNA_def_function_ui_description(func, "Add a new camera to the main database");
+ RNA_def_function_ui_description(func, "Add a new addon");
/* return type */
- parm= RNA_def_pointer(func, "extension", "Extension", "", "Extension datablock.");
+ parm= RNA_def_pointer(func, "addon", "Addon", "", "Addon datablock.");
RNA_def_function_return(func, parm);
- func= RNA_def_function(srna, "remove", "rna_userdef_extension_remove");
+ func= RNA_def_function(srna, "remove", "rna_userdef_addon_remove");
RNA_def_function_flag(func, FUNC_NO_SELF);
- RNA_def_function_ui_description(func, "Remove a camera from the current blendfile.");
- parm= RNA_def_pointer(func, "extension", "Extension", "", "Extension to remove.");
+ RNA_def_function_ui_description(func, "Remove addon.");
+ parm= RNA_def_pointer(func, "addon", "Addon", "", "Addon to remove.");
RNA_def_property_flag(parm, PROP_REQUIRED);
}
@@ -2682,7 +2690,7 @@ void RNA_def_userdef(BlenderRNA *brna)
{USER_SECTION_INTERFACE, "INTERFACE", 0, "Interface", ""},
{USER_SECTION_EDIT, "EDITING", 0, "Editing", ""},
{USER_SECTION_INPUT, "INPUT", 0, "Input", ""},
- {USER_SECTION_EXTENSIONS, "EXTENSIONS", 0, "Extensions", ""},
+ {USER_SECTION_ADDONS, "ADDONS", 0, "Add-Ons", ""},
{USER_SECTION_THEME, "THEMES", 0, "Themes", ""},
{USER_SECTION_FILE, "FILES", 0, "File", ""},
{USER_SECTION_SYSTEM, "SYSTEM", 0, "System", ""},
@@ -2711,11 +2719,11 @@ void RNA_def_userdef(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "ThemeStyle");
RNA_def_property_ui_text(prop, "Styles", "");
- prop= RNA_def_property(srna, "extensions", PROP_COLLECTION, PROP_NONE);
- RNA_def_property_collection_sdna(prop, NULL, "extensions", NULL);
- RNA_def_property_struct_type(prop, "Extension");
- RNA_def_property_ui_text(prop, "Extension", "");
- rna_def_userdef_extension_collection(brna, prop);
+ prop= RNA_def_property(srna, "addons", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "addons", NULL);
+ RNA_def_property_struct_type(prop, "Addon");
+ RNA_def_property_ui_text(prop, "Addon", "");
+ rna_def_userdef_addon_collection(brna, prop);
/* nested structs */
@@ -2754,6 +2762,7 @@ void RNA_def_userdef(BlenderRNA *brna)
rna_def_userdef_input(brna);
rna_def_userdef_filepaths(brna);
rna_def_userdef_system(brna);
+ rna_def_userdef_addon(brna);
}
diff --git a/source/blender/python/generic/BGL.c b/source/blender/python/generic/BGL.c
index 2318549f2ec..340ebbe3dcd 100644
--- a/source/blender/python/generic/BGL.c
+++ b/source/blender/python/generic/BGL.c
@@ -36,9 +36,6 @@
#include <GL/glew.h>
#include "MEM_guardedalloc.h"
-static int type_size( int type );
-static Buffer *make_buffer( int type, int ndimensions, int *dimensions );
-
static char Method_Buffer_doc[] =
"(type, dimensions, [template]) - Create a new Buffer object\n\n\
(type) - The format to store data in\n\
@@ -82,7 +79,7 @@ static PyObject *Buffer_dimensions( PyObject * self );
static PyObject *Buffer_getattr( PyObject * self, char *name );
static PyObject *Buffer_repr( PyObject * self );
-PyTypeObject buffer_Type = {
+PyTypeObject BGL_bufferType = {
PyVarObject_HEAD_INIT(NULL, 0)
"buffer", /*tp_name */
sizeof( Buffer ), /*tp_basicsize */
@@ -120,7 +117,7 @@ static PyObject *Method_##funcname (PyObject *self, PyObject *args) {\
/* #endif */
/********/
-static int type_size(int type)
+int BGL_typeSize(int type)
{
switch (type) {
case GL_BYTE:
@@ -137,7 +134,7 @@ static int type_size(int type)
return -1;
}
-static Buffer *make_buffer(int type, int ndimensions, int *dimensions)
+Buffer *BGL_MakeBuffer(int type, int ndimensions, int *dimensions, void *initbuffer)
{
Buffer *buffer;
void *buf= NULL;
@@ -147,39 +144,49 @@ static Buffer *make_buffer(int type, int ndimensions, int *dimensions)
for (i=0; i<ndimensions; i++)
length*= dimensions[i];
- size= type_size(type);
+ size= BGL_typeSize(type);
buf= MEM_mallocN(length*size, "Buffer buffer");
-
- buffer= (Buffer *) PyObject_NEW(Buffer, &buffer_Type);
+
+ buffer= (Buffer *) PyObject_NEW(Buffer, &BGL_bufferType);
buffer->parent= NULL;
buffer->ndimensions= ndimensions;
- buffer->dimensions= dimensions;
+ buffer->dimensions= MEM_mallocN(ndimensions*sizeof(int), "Buffer dimensions");
+ memcpy(buffer->dimensions, dimensions, ndimensions*sizeof(int));
buffer->type= type;
buffer->buf.asvoid= buf;
- for (i= 0; i<length; i++) {
- if (type==GL_BYTE)
- buffer->buf.asbyte[i]= 0;
- else if (type==GL_SHORT)
- buffer->buf.asshort[i]= 0;
- else if (type==GL_INT)
- buffer->buf.asint[i]= 0;
- else if (type==GL_FLOAT)
- buffer->buf.asfloat[i]= 0.0f;
- else if (type==GL_DOUBLE)
- buffer->buf.asdouble[i]= 0.0;
+ if (initbuffer) {
+ memcpy(buffer->buf.asvoid, initbuffer, length*size);
+ } else {
+ memset(buffer->buf.asvoid, 0, length*size);
+ /*
+ for (i= 0; i<length; i++) {
+ if (type==GL_BYTE)
+ buffer->buf.asbyte[i]= 0;
+ else if (type==GL_SHORT)
+ buffer->buf.asshort[i]= 0;
+ else if (type==GL_INT)
+ buffer->buf.asint[i]= 0;
+ else if (type==GL_FLOAT)
+ buffer->buf.asfloat[i]= 0.0f;
+ else if (type==GL_DOUBLE)
+ buffer->buf.asdouble[i]= 0.0;
+ }
+ */
}
return buffer;
}
+#define MAX_DIMENSIONS 256
static PyObject *Method_Buffer (PyObject *self, PyObject *args)
{
PyObject *length_ob= NULL, *template= NULL;
Buffer *buffer;
+ int dimensions[MAX_DIMENSIONS];
int i, type;
- int *dimensions = 0, ndimensions = 0;
+ int ndimensions = 0;
if (!PyArg_ParseTuple(args, "iO|O", &type, &length_ob, &template)) {
PyErr_SetString(PyExc_AttributeError, "expected an int and one or two PyObjects");
@@ -192,11 +199,13 @@ static PyObject *Method_Buffer (PyObject *self, PyObject *args)
if (PyNumber_Check(length_ob)) {
ndimensions= 1;
- dimensions= MEM_mallocN(ndimensions*sizeof(int), "Buffer dimensions");
dimensions[0]= PyLong_AsLong(length_ob);
} else if (PySequence_Check(length_ob)) {
ndimensions= PySequence_Length(length_ob);
- dimensions= MEM_mallocN(ndimensions*sizeof(int), "Buffer dimensions");
+ if (ndimensions > MAX_DIMENSIONS) {
+ PyErr_SetString(PyExc_AttributeError, "too many dimensions, max is 256");
+ return NULL;
+ }
for (i=0; i<ndimensions; i++) {
PyObject *ob= PySequence_GetItem(length_ob, i);
@@ -206,7 +215,7 @@ static PyObject *Method_Buffer (PyObject *self, PyObject *args)
}
}
- buffer= make_buffer(type, ndimensions, dimensions);
+ buffer= BGL_MakeBuffer(type, ndimensions, dimensions, NULL);
if (template && ndimensions) {
if (Buffer_ass_slice((PyObject *) buffer, 0, dimensions[0], template)) {
Py_DECREF(buffer);
@@ -250,9 +259,9 @@ static PyObject *Buffer_item(PyObject *self, int i)
for (j=1; j<buf->ndimensions; j++) {
length*= buf->dimensions[j];
}
- size= type_size(buf->type);
+ size= BGL_typeSize(buf->type);
- newbuf= (Buffer *) PyObject_NEW(Buffer, &buffer_Type);
+ newbuf= (Buffer *) PyObject_NEW(Buffer, &BGL_bufferType);
Py_INCREF(self);
newbuf->parent= self;
@@ -1104,7 +1113,7 @@ PyObject *BGL_Init(void)
PyDict_SetItemString(PySys_GetObject("modules"), BGL_module_def.m_name, mod);
dict= PyModule_GetDict(mod);
- if( PyType_Ready( &buffer_Type) < 0)
+ if( PyType_Ready( &BGL_bufferType) < 0)
return NULL; /* should never happen */
#define EXPP_ADDCONST(x) PyDict_SetItemString(dict, #x, item=PyLong_FromLong((int)x)); Py_DECREF(item)
diff --git a/source/blender/python/generic/BGL.h b/source/blender/python/generic/BGL.h
index 32076f4fba8..89bade930ce 100644
--- a/source/blender/python/generic/BGL.h
+++ b/source/blender/python/generic/BGL.h
@@ -44,9 +44,16 @@
PyObject *BGL_Init(void);
+/*@ Create a buffer object */
+/*@ dimensions is an array of ndimensions integers representing the size of each dimension */
+/*@ initbuffer if not NULL holds a contiguous buffer with the correct format from which the buffer will be initialized */
+struct _Buffer *BGL_MakeBuffer( int type, int ndimensions, int *dimensions, void *initbuffer );
+/*@ Return the size of buffer element, type must be one of GL_BYTE, GL_SHORT, GL_INT, GL_FLOAT or GL_DOUBLE */
+/*@ returns -1 otherwise */
+int BGL_typeSize( int type );
+
/*@ Buffer Object */
/*@ For Python access to OpenGL functions requiring a pointer. */
-
typedef struct _Buffer {
PyObject_VAR_HEAD
PyObject * parent;
@@ -66,6 +73,8 @@ typedef struct _Buffer {
} buf;
} Buffer;
+/*@ The type object */
+extern PyTypeObject BGL_bufferType;
/*@ By golly George! It looks like fancy pants macro time!!! */
@@ -93,7 +102,7 @@ typedef struct _Buffer {
#define buffer_str "O!"
#define buffer_var(number) (bgl_buffer##number)->buf.asvoid
-#define buffer_ref(number) &buffer_Type, &bgl_buffer##number
+#define buffer_ref(number) &BGL_bufferType, &bgl_buffer##number
#define buffer_def(number) Buffer *bgl_buffer##number
/* GL Pointer fields, handled by buffer type */
@@ -101,62 +110,62 @@ typedef struct _Buffer {
#define GLbooleanP_str "O!"
#define GLbooleanP_var(number) (bgl_buffer##number)->buf.asvoid
-#define GLbooleanP_ref(number) &buffer_Type, &bgl_buffer##number
+#define GLbooleanP_ref(number) &BGL_bufferType, &bgl_buffer##number
#define GLbooleanP_def(number) Buffer *bgl_buffer##number
#define GLbyteP_str "O!"
#define GLbyteP_var(number) (bgl_buffer##number)->buf.asvoid
-#define GLbyteP_ref(number) &buffer_Type, &bgl_buffer##number
+#define GLbyteP_ref(number) &BGL_bufferType, &bgl_buffer##number
#define GLbyteP_def(number) Buffer *bgl_buffer##number
#define GLubyteP_str "O!"
#define GLubyteP_var(number) (bgl_buffer##number)->buf.asvoid
-#define GLubyteP_ref(number) &buffer_Type, &bgl_buffer##number
+#define GLubyteP_ref(number) &BGL_bufferType, &bgl_buffer##number
#define GLubyteP_def(number) Buffer *bgl_buffer##number
#define GLintP_str "O!"
#define GLintP_var(number) (bgl_buffer##number)->buf.asvoid
-#define GLintP_ref(number) &buffer_Type, &bgl_buffer##number
+#define GLintP_ref(number) &BGL_bufferType, &bgl_buffer##number
#define GLintP_def(number) Buffer *bgl_buffer##number
#define GLuintP_str "O!"
#define GLuintP_var(number) (bgl_buffer##number)->buf.asvoid
-#define GLuintP_ref(number) &buffer_Type, &bgl_buffer##number
+#define GLuintP_ref(number) &BGL_bufferType, &bgl_buffer##number
#define GLuintP_def(number) Buffer *bgl_buffer##number
#define GLshortP_str "O!"
#define GLshortP_var(number) (bgl_buffer##number)->buf.asvoid
-#define GLshortP_ref(number) &buffer_Type, &bgl_buffer##number
+#define GLshortP_ref(number) &BGL_bufferType, &bgl_buffer##number
#define GLshortP_def(number) Buffer *bgl_buffer##number
#define GLushortP_str "O!"
#define GLushortP_var(number) (bgl_buffer##number)->buf.asvoid
-#define GLushortP_ref(number) &buffer_Type, &bgl_buffer##number
+#define GLushortP_ref(number) &BGL_bufferType, &bgl_buffer##number
#define GLushortP_def(number) Buffer *bgl_buffer##number
#define GLfloatP_str "O!"
#define GLfloatP_var(number) (bgl_buffer##number)->buf.asvoid
-#define GLfloatP_ref(number) &buffer_Type, &bgl_buffer##number
+#define GLfloatP_ref(number) &BGL_bufferType, &bgl_buffer##number
#define GLfloatP_def(number) Buffer *bgl_buffer##number
#define GLdoubleP_str "O!"
#define GLdoubleP_var(number) (bgl_buffer##number)->buf.asvoid
-#define GLdoubleP_ref(number) &buffer_Type, &bgl_buffer##number
+#define GLdoubleP_ref(number) &BGL_bufferType, &bgl_buffer##number
#define GLdoubleP_def(number) Buffer *bgl_buffer##number
#define GLclampfP_str "O!"
#define GLclampfP_var(number) (bgl_buffer##number)->buf.asvoid
-#define GLclampfP_ref(number) &buffer_Type, &bgl_buffer##number
+#define GLclampfP_ref(number) &BGL_bufferType, &bgl_buffer##number
#define GLclampfP_def(number) Buffer *bgl_buffer##number
#define GLvoidP_str "O!"
#define GLvoidP_var(number) (bgl_buffer##number)->buf.asvoid
-#define GLvoidP_ref(number) &buffer_Type, &bgl_buffer##number
+#define GLvoidP_ref(number) &BGL_bufferType, &bgl_buffer##number
#define GLvoidP_def(number) Buffer *bgl_buffer##number
#define buffer_str "O!"
#define buffer_var(number) (bgl_buffer##number)->buf.asvoid
-#define buffer_ref(number) &buffer_Type, &bgl_buffer##number
+#define buffer_ref(number) &BGL_bufferType, &bgl_buffer##number
#define buffer_def(number) Buffer *bgl_buffer##number
/*@The standard GL typedefs are used as prototypes, we can't
diff --git a/source/blender/python/generic/matrix.c b/source/blender/python/generic/matrix.c
index a20ed3e4f59..0b0b1470823 100644
--- a/source/blender/python/generic/matrix.c
+++ b/source/blender/python/generic/matrix.c
@@ -194,7 +194,7 @@ static float matrix_determinant(MatrixObject * self)
self->matrix[2][0], self->matrix[2][1],
self->matrix[2][2]);
} else {
- return determinant_m4((float (*)[4]) *self->matrix);
+ return determinant_m4((float (*)[4])self->contigPtr);
}
}
@@ -221,9 +221,9 @@ static PyObject *Matrix_toQuat(MatrixObject * self)
return NULL;
}
if(self->colSize == 3){
- mat3_to_quat( quat,(float (*)[3])*self->matrix);
+ mat3_to_quat( quat,(float (*)[3])self->contigPtr);
}else{
- mat4_to_quat( quat,(float (*)[4])*self->matrix);
+ mat4_to_quat( quat,(float (*)[4])self->contigPtr);
}
return newQuaternionObject(quat, Py_NEW, NULL);
@@ -267,9 +267,9 @@ PyObject *Matrix_toEuler(MatrixObject * self, PyObject *args)
/*must be 3-4 cols, 3-4 rows, square matrix*/
if(self->colSize ==3 && self->rowSize ==3) {
- mat= (float (*)[3]) *self->matrix;
+ mat= (float (*)[3])self->contigPtr;
}else if (self->colSize ==4 && self->rowSize ==4) {
- copy_m3_m4(tmat, (float (*)[4]) *self->matrix);
+ copy_m3_m4(tmat, (float (*)[4])self->contigPtr);
mat= tmat;
}else {
PyErr_SetString(PyExc_AttributeError, "Matrix.to_euler(): inappropriate matrix size - expects 3x3 or 4x4 matrix\n");
@@ -301,7 +301,7 @@ static char Matrix_Resize4x4_doc[] =
" Resize the matrix to 4x4.\n"
"\n"
" :return: an instance of itself.\n"
-" :rtype: :class:`Vector`\n";
+" :rtype: :class:`Matrix`\n";
PyObject *Matrix_Resize4x4(MatrixObject * self)
{
@@ -359,6 +359,59 @@ PyObject *Matrix_Resize4x4(MatrixObject * self)
Py_INCREF(self);
return (PyObject *)self;
}
+
+static char Matrix_to_4x4_doc[] =
+".. method:: to_4x4()\n"
+"\n"
+" Return a 4x4 copy of this matrix.\n"
+"\n"
+" :return: a new matrix.\n"
+" :rtype: :class:`Matrix`\n";
+PyObject *Matrix_to_4x4(MatrixObject * self)
+{
+ if(!BaseMath_ReadCallback(self))
+ return NULL;
+
+ if(self->colSize==4 && self->rowSize==4) {
+ return (PyObject *)newMatrixObject(self->contigPtr, 4, 4, Py_NEW, Py_TYPE(self));
+ }
+ else if(self->colSize==3 && self->rowSize==3) {
+ float mat[4][4];
+ copy_m4_m3(mat, (float (*)[3])self->contigPtr);
+ return (PyObject *)newMatrixObject((float *)mat, 4, 4, Py_NEW, Py_TYPE(self));
+ }
+ /* TODO, 2x2 matrix */
+
+ PyErr_SetString(PyExc_TypeError, "Matrix.to_4x4(): inappropriate matrix size");
+ return NULL;
+}
+
+static char Matrix_to_3x3_doc[] =
+".. method:: to_3x3()\n"
+"\n"
+" Return a 3x3 copy of this matrix.\n"
+"\n"
+" :return: a new matrix.\n"
+" :rtype: :class:`Matrix`\n";
+PyObject *Matrix_to_3x3(MatrixObject * self)
+{
+ if(!BaseMath_ReadCallback(self))
+ return NULL;
+
+ if(self->colSize==3 && self->rowSize==3) {
+ return (PyObject *)newMatrixObject(self->contigPtr, 3, 3, Py_NEW, Py_TYPE(self));
+ }
+ else if(self->colSize==4 && self->rowSize==4) {
+ float mat[3][3];
+ copy_m3_m4(mat, (float (*)[4])self->contigPtr);
+ return (PyObject *)newMatrixObject((float *)mat, 3, 3, Py_NEW, Py_TYPE(self));
+ }
+ /* TODO, 2x2 matrix */
+
+ PyErr_SetString(PyExc_TypeError, "Matrix.to_3x3(): inappropriate matrix size");
+ return NULL;
+}
+
/*---------------------------Matrix.translationPart() ------------*/
static char Matrix_TranslationPart_doc[] =
".. method:: translation_part()\n"
@@ -439,9 +492,9 @@ PyObject *Matrix_scalePart(MatrixObject * self)
/*must be 3-4 cols, 3-4 rows, square matrix*/
if(self->colSize == 4 && self->rowSize == 4)
- copy_m3_m4(mat, (float (*)[4])*self->matrix);
+ copy_m3_m4(mat, (float (*)[4])self->contigPtr);
else if(self->colSize == 3 && self->rowSize == 3)
- copy_m3_m3(mat, (float (*)[3])*self->matrix);
+ copy_m3_m3(mat, (float (*)[3])self->contigPtr);
else {
PyErr_SetString(PyExc_AttributeError, "Matrix.scale_part(): inappropriate matrix size - expects 3x3 or 4x4 matrix\n");
return NULL;
@@ -497,9 +550,9 @@ PyObject *Matrix_Invert(MatrixObject * self)
mat[2] = -self->matrix[1][0];
mat[3] = self->matrix[0][0];
} else if(self->rowSize == 3) {
- adjoint_m3_m3((float (*)[3]) mat,(float (*)[3]) *self->matrix);
+ adjoint_m3_m3((float (*)[3]) mat,(float (*)[3])self->contigPtr);
} else if(self->rowSize == 4) {
- adjoint_m4_m4((float (*)[4]) mat, (float (*)[4]) *self->matrix);
+ adjoint_m4_m4((float (*)[4]) mat, (float (*)[4])self->contigPtr);
}
/*divide by determinate*/
for(x = 0; x < (self->rowSize * self->colSize); x++) {
@@ -576,9 +629,9 @@ PyObject *Matrix_Transpose(MatrixObject * self)
self->matrix[1][0] = self->matrix[0][1];
self->matrix[0][1] = t;
} else if(self->rowSize == 3) {
- transpose_m3((float (*)[3])*self->matrix);
+ transpose_m3((float (*)[3])self->contigPtr);
} else {
- transpose_m4((float (*)[4])*self->matrix);
+ transpose_m4((float (*)[4])self->contigPtr);
}
BaseMath_WriteCallback(self);
@@ -641,9 +694,9 @@ PyObject *Matrix_Identity(MatrixObject * self)
self->matrix[1][0] = 0.0f;
self->matrix[1][1] = 1.0f;
} else if(self->rowSize == 3) {
- unit_m3((float (*)[3]) *self->matrix);
+ unit_m3((float (*)[3])self->contigPtr);
} else {
- unit_m4((float (*)[4]) *self->matrix);
+ unit_m4((float (*)[4])self->contigPtr);
}
if(!BaseMath_WriteCallback(self))
@@ -667,7 +720,7 @@ PyObject *Matrix_copy(MatrixObject * self)
if(!BaseMath_ReadCallback(self))
return NULL;
- return (PyObject*)newMatrixObject((float (*))*self->matrix, self->rowSize, self->colSize, Py_NEW, Py_TYPE(self));
+ return (PyObject*)newMatrixObject((float (*))self->contigPtr, self->rowSize, self->colSize, Py_NEW, Py_TYPE(self));
}
/*----------------------------print object (internal)-------------*/
@@ -1219,9 +1272,9 @@ static PyObject *Matrix_getMedianScale( MatrixObject * self, void *type )
/*must be 3-4 cols, 3-4 rows, square matrix*/
if(self->colSize == 4 && self->rowSize == 4)
- copy_m3_m4(mat, (float (*)[4])*self->matrix);
+ copy_m3_m4(mat, (float (*)[4])self->contigPtr);
else if(self->colSize == 3 && self->rowSize == 3)
- copy_m3_m3(mat, (float (*)[3])*self->matrix);
+ copy_m3_m3(mat, (float (*)[3])self->contigPtr);
else {
PyErr_SetString(PyExc_AttributeError, "Matrix.median_scale: inappropriate matrix size - expects 3x3 or 4x4 matrix\n");
return NULL;
@@ -1237,9 +1290,9 @@ static PyObject *Matrix_getIsNegative( MatrixObject * self, void *type )
/*must be 3-4 cols, 3-4 rows, square matrix*/
if(self->colSize == 4 && self->rowSize == 4)
- return PyBool_FromLong(is_negative_m4((float (*)[4])*self->matrix));
+ return PyBool_FromLong(is_negative_m4((float (*)[4])self->contigPtr));
else if(self->colSize == 3 && self->rowSize == 3)
- return PyBool_FromLong(is_negative_m3((float (*)[3])*self->matrix));
+ return PyBool_FromLong(is_negative_m3((float (*)[3])self->contigPtr));
else {
PyErr_SetString(PyExc_AttributeError, "Matrix.is_negative: inappropriate matrix size - expects 3x3 or 4x4 matrix\n");
return NULL;
@@ -1271,6 +1324,8 @@ static struct PyMethodDef Matrix_methods[] = {
{"rotation_part", (PyCFunction) Matrix_RotationPart, METH_NOARGS, Matrix_RotationPart_doc},
{"scale_part", (PyCFunction) Matrix_scalePart, METH_NOARGS, Matrix_scalePart_doc},
{"resize4x4", (PyCFunction) Matrix_Resize4x4, METH_NOARGS, Matrix_Resize4x4_doc},
+ {"to_4x4", (PyCFunction) Matrix_to_4x4, METH_NOARGS, Matrix_to_4x4_doc},
+ {"to_3x3", (PyCFunction) Matrix_to_3x3, METH_NOARGS, Matrix_to_3x3_doc},
{"to_euler", (PyCFunction) Matrix_toEuler, METH_VARARGS, Matrix_toEuler_doc},
{"to_quat", (PyCFunction) Matrix_toQuat, METH_NOARGS, Matrix_toQuat_doc},
{"copy", (PyCFunction) Matrix_copy, METH_NOARGS, Matrix_copy_doc},
diff --git a/source/blender/python/intern/bpy_driver.c b/source/blender/python/intern/bpy_driver.c
index 356abeeb40f..f628e7e8569 100644
--- a/source/blender/python/intern/bpy_driver.c
+++ b/source/blender/python/intern/bpy_driver.c
@@ -30,6 +30,7 @@
#include "BPY_extern.h"
#include "BKE_fcurve.h"
+#include "BKE_global.h"
#include <Python.h>
@@ -86,7 +87,7 @@ static int bpy_pydriver_create_dict(void)
/* If there's a Blender text called pydrivers.py, import it.
* Users can add their own functions to this module.
*/
- if (G.f & G_DOSCRIPTLINKS) {
+ if (G.f & G_SCRIPT_AUTOEXEC) {
mod = importText("pydrivers"); /* can also use PyImport_Import() */
if (mod) {
PyDict_SetItemString(d, "pydrivers", mod);
@@ -158,14 +159,18 @@ float BPY_pydriver_eval (ChannelDriver *driver)
int i;
/* sanity checks - should driver be executed? */
- if ((driver == NULL) /*|| (G.f & G_DOSCRIPTLINKS)==0*/)
- return result;
+ /*if (G.f & G_SCRIPT_AUTOEXEC)==0) return result; */
/* get the py expression to be evaluated */
expr = driver->expression;
if ((expr == NULL) || (expr[0]=='\0'))
return result;
+ if(!(G.f & G_SCRIPT_AUTOEXEC)) {
+ printf("skipping driver '%s', automatic scripts are disabled\n", driver->expression);
+ return result;
+ }
+
gilstate = PyGILState_Ensure();
/* init global dictionary for py-driver evaluation settings */
@@ -207,6 +212,8 @@ float BPY_pydriver_eval (ChannelDriver *driver)
for (dvar= driver->variables.first, i=0; dvar; dvar= dvar->next) {
PyTuple_SET_ITEM(expr_vars, i++, PyUnicode_InternFromString(dvar->name));
}
+
+ driver->flag &= ~DRIVER_FLAG_RENAMEVAR;
}
else {
expr_vars= PyTuple_GET_ITEM(((PyObject *)driver->expr_comp), 1);
@@ -253,24 +260,20 @@ float BPY_pydriver_eval (ChannelDriver *driver)
/* process the result */
if (retval == NULL) {
- result = pydriver_error(driver);
- PyGILState_Release(gilstate);
- return result;
- }
+ pydriver_error(driver);
+ result = 0.0f;
+ } else if((result= (float)PyFloat_AsDouble(retval)) == -1.0f && PyErr_Occurred()) {
+ pydriver_error(driver);
+ Py_DECREF(retval);
+ result = 0.0f;
- result = (float)PyFloat_AsDouble(retval);
- Py_DECREF(retval);
-
- if ((result == -1) && PyErr_Occurred()) {
- result = pydriver_error(driver);
- PyGILState_Release(gilstate);
- return result;
}
-
- /* all fine, make sure the "invalid expression" flag is cleared */
- driver->flag &= ~DRIVER_FLAG_INVALID;
+ else {
+ /* all fine, make sure the "invalid expression" flag is cleared */
+ driver->flag &= ~DRIVER_FLAG_INVALID;
+ Py_DECREF(retval);
+ }
PyGILState_Release(gilstate);
-
return result;
}
diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c
index 0b7c8759b5c..4160d56ba25 100644
--- a/source/blender/python/intern/bpy_interface.c
+++ b/source/blender/python/intern/bpy_interface.c
@@ -62,6 +62,7 @@
#include "BKE_text.h"
#include "BKE_context.h"
#include "BKE_main.h"
+#include "BKE_global.h" /* only for script checking */
#include "BPY_extern.h"
@@ -556,24 +557,26 @@ int BPY_button_eval(bContext *C, char *expr, double *value)
PyObject *dict, *mod, *retval;
int error_ret = 0;
- if (!value || !expr || expr[0]=='\0') return -1;
-
+ if (!value || !expr) return -1;
+
+ if(expr[0]=='\0') {
+ *value= 0.0;
+ return error_ret;
+ }
+
bpy_context_set(C, &gilstate);
dict= CreateGlobalDictionary(C, NULL);
-
- /* import some modules: builtins,math*/
- PyDict_SetItemString(dict, "__builtins__", PyEval_GetBuiltins());
mod = PyImport_ImportModule("math");
if (mod) {
PyDict_Merge(dict, PyModule_GetDict(mod), 0); /* 0 - dont overwrite existing values */
-
- /* Only keep for backwards compat! - just import all math into root, they are standard */
- PyDict_SetItemString(dict, "math", mod);
- PyDict_SetItemString(dict, "m", mod);
Py_DECREF(mod);
- }
+ }
+ else { /* highly unlikely but possibly */
+ PyErr_Print();
+ PyErr_Clear();
+ }
retval = PyRun_String(expr, Py_eval_input, dict, dict);
@@ -630,14 +633,19 @@ void BPY_load_user_modules(bContext *C)
for(text=CTX_data_main(C)->text.first; text; text= text->id.next) {
if(text->flags & TXT_ISSCRIPT && BLI_testextensie(text->id.name+2, ".py")) {
- PyObject *module= bpy_text_import(text);
-
- if (module==NULL) {
- PyErr_Print();
- PyErr_Clear();
+ if(!(G.f & G_SCRIPT_AUTOEXEC)) {
+ printf("scripts disabled for \"%s\", skipping '%s'\n", bmain->name, text->id.name+2);
}
else {
- Py_DECREF(module);
+ PyObject *module= bpy_text_import(text);
+
+ if (module==NULL) {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+ else {
+ Py_DECREF(module);
+ }
}
}
}
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index 691010ade0d..2b31f06f51b 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -26,6 +26,7 @@
#include "bpy_rna.h"
#include "bpy_props.h"
#include "bpy_util.h"
+#include "bpy_rna_callback.h"
//#include "blendef.h"
#include "BLI_dynstr.h"
#include "BLI_listbase.h"
@@ -154,6 +155,19 @@ Mathutils_Callback mathutils_rna_matrix_cb = {
(BaseMathSetIndexFunc) NULL
};
+/* same as RNA_enum_value_from_id but raises an exception */
+int pyrna_enum_value_from_id(EnumPropertyItem *item, const char *identifier, int *value, const char *error_prefix)
+{
+ if(RNA_enum_value_from_id(item, identifier, value) == 0) {
+ char *enum_str= BPy_enum_as_string(item);
+ PyErr_Format(PyExc_TypeError, "%s: '%.200s' not found in (%s)", error_prefix, identifier, enum_str);
+ MEM_freeN(enum_str);
+ return -1;
+ }
+
+ return 0;
+}
+
#define PROP_ALL_VECTOR_SUBTYPES PROP_TRANSLATION: case PROP_DIRECTION: case PROP_VELOCITY: case PROP_ACCELERATION: case PROP_XYZ: case PROP_XYZ|PROP_UNIT_LENGTH
PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
@@ -474,16 +488,11 @@ int pyrna_set_to_enum_bitfield(EnumPropertyItem *items, PyObject *value, int *r_
char *param= _PyUnicode_AsString(key);
if(param==NULL) {
- PyErr_Format(PyExc_TypeError, "%s expected a string. found a %.200s", error_prefix, Py_TYPE(key)->tp_name);
+ PyErr_Format(PyExc_TypeError, "%.200s expected a string. found a %.200s", error_prefix, Py_TYPE(key)->tp_name);
return -1;
}
-
- if(RNA_enum_value_from_id(items, param, &ret) == 0) {
- char *enum_str= BPy_enum_as_string(items);
- PyErr_Format(PyExc_TypeError, "%s \"%.200s\" not found in (%.200s)", error_prefix, param, enum_str);
- MEM_freeN(enum_str);
+ if(pyrna_enum_value_from_id(items, param, &ret, error_prefix) < 0)
return -1;
- }
flag |= ret;
}
@@ -507,7 +516,7 @@ static int pyrna_prop_to_enum_bitfield(PointerRNA *ptr, PropertyRNA *prop, PyObj
}
else {
if(PySet_GET_SIZE(value)) {
- PyErr_Format(PyExc_TypeError, "%s: empty enum \"%.200s\" could not have any values assigned.", error_prefix, RNA_property_identifier(prop));
+ PyErr_Format(PyExc_TypeError, "%.200s: empty enum \"%.200s\" could not have any values assigned.", error_prefix, RNA_property_identifier(prop));
ret= -1;
}
else {
@@ -651,7 +660,7 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
ret = pyrna_prop_CreatePyObject(ptr, prop);
break;
default:
- PyErr_Format(PyExc_TypeError, "RNA Error: unknown type \"%d\" (pyrna_prop_to_py)", type);
+ PyErr_Format(PyExc_TypeError, "bpy_struct internal error: unknown type \"%d\" (pyrna_prop_to_py)", type);
ret = NULL;
break;
}
@@ -886,6 +895,9 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, ParameterList *parms, v
} else if((flag & PROP_NEVER_NULL) && value == Py_None) {
PyErr_Format(PyExc_TypeError, "%.200s does not support a 'None' assignment %.200s type", error_prefix, RNA_struct_identifier(ptype));
return -1;
+ } else if(value != Py_None && ((flag & PROP_ID_SELF_CHECK) && ptr->id.data == ((BPy_StructRNA*)value)->ptr.id.data)) {
+ PyErr_Format(PyExc_TypeError, "%.200s ID type does not support assignment to its self", error_prefix);
+ return -1;
} else {
BPy_StructRNA *param= (BPy_StructRNA*)value;
int raise_error= FALSE;
@@ -1084,7 +1096,7 @@ static PyObject *pyrna_prop_collection_subscript_int(BPy_PropertyRNA *self, Py_s
if(RNA_property_collection_lookup_int(&self->ptr, self->prop, keynum, &newptr))
return pyrna_struct_CreatePyObject(&newptr);
- PyErr_Format(PyExc_IndexError, "index %d out of range", keynum);
+ PyErr_Format(PyExc_IndexError, "bpy_prop_collection[index]: index %d out of range", keynum);
return NULL;
}
@@ -1097,7 +1109,7 @@ static PyObject *pyrna_prop_array_subscript_int(BPy_PropertyRNA *self, int keynu
if(keynum >= 0 && keynum < len)
return pyrna_prop_to_py_index(self, keynum);
- PyErr_Format(PyExc_IndexError, "index %d out of range", keynum);
+ PyErr_Format(PyExc_IndexError, "bpy_prop_array[index]: index %d out of range", keynum);
return NULL;
}
@@ -1107,7 +1119,7 @@ static PyObject *pyrna_prop_collection_subscript_str(BPy_PropertyRNA *self, char
if(RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr))
return pyrna_struct_CreatePyObject(&newptr);
- PyErr_Format(PyExc_KeyError, "key \"%.200s\" not found", keyname);
+ PyErr_Format(PyExc_KeyError, "bpy_prop_collection[key]: key \"%.200s\" not found", keyname);
return NULL;
}
/* static PyObject *pyrna_prop_array_subscript_str(BPy_PropertyRNA *self, char *keyname) */
@@ -1237,12 +1249,12 @@ static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject
return pyrna_prop_collection_subscript_slice(&self->ptr, self->prop, start, stop, len);
}
else {
- PyErr_SetString(PyExc_TypeError, "slice steps not supported with rna");
+ PyErr_SetString(PyExc_TypeError, "bpy_prop_collection[slice]: slice steps not supported with rna");
return NULL;
}
}
else {
- PyErr_Format(PyExc_TypeError, "invalid rna key, key must be a string or an int instead of %.200s instance.", Py_TYPE(key)->tp_name);
+ PyErr_Format(PyExc_TypeError, "bpy_prop_collection[key]: invalid key, must be a string or an int instead of %.200s instance.", Py_TYPE(key)->tp_name);
return NULL;
}
}
@@ -1272,12 +1284,12 @@ static PyObject *pyrna_prop_array_subscript(BPy_PropertyRNA *self, PyObject *key
return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, start, stop, len);
}
else {
- PyErr_SetString(PyExc_TypeError, "slice steps not supported with rna");
+ PyErr_SetString(PyExc_TypeError, "bpy_prop_array[slice]: slice steps not supported with rna");
return NULL;
}
}
else {
- PyErr_SetString(PyExc_AttributeError, "invalid key, key must be an int");
+ PyErr_SetString(PyExc_AttributeError, "bpy_prop_array[key]: invalid key, key must be an int");
return NULL;
}
}
@@ -1291,17 +1303,17 @@ static int prop_subscript_ass_array_slice(PointerRNA *ptr, PropertyRNA *prop, in
int ret= 0;
if(value_orig == NULL) {
- PyErr_SetString(PyExc_TypeError, "invalid slice assignment, deleting with list types is not supported by StructRNA.");
+ PyErr_SetString(PyExc_TypeError, "bpy_prop_array[slice] = value: deleting with list types is not supported by bpy_struct.");
return -1;
}
- if(!(value=PySequence_Fast(value_orig, "invalid slice assignment, type is not a sequence"))) {
+ if(!(value=PySequence_Fast(value_orig, "bpy_prop_array[slice] = value: type is not a sequence"))) {
return -1;
}
if(PySequence_Fast_GET_SIZE(value) != stop-start) {
Py_DECREF(value);
- PyErr_SetString(PyExc_TypeError, "invalid slice assignment, resizing StructRNA arrays isn't supported.");
+ PyErr_SetString(PyExc_TypeError, "bpy_prop_array[slice] = value: resizing bpy_struct arrays isn't supported.");
return -1;
}
@@ -1394,7 +1406,7 @@ static int prop_subscript_ass_array_int(BPy_PropertyRNA *self, Py_ssize_t keynum
if(keynum >= 0 && keynum < len)
return pyrna_py_to_prop_index(self, keynum, value);
- PyErr_SetString(PyExc_IndexError, "out of range");
+ PyErr_SetString(PyExc_IndexError, "bpy_prop_array[index] = value: index out of range");
return -1;
}
@@ -1402,8 +1414,8 @@ static int pyrna_prop_array_ass_subscript( BPy_PropertyRNA *self, PyObject *key,
{
/* char *keyname = NULL; */ /* not supported yet */
- if (!RNA_property_editable(&self->ptr, self->prop)) {
- PyErr_Format( PyExc_AttributeError, "PropertyRNA - attribute \"%.200s\" from \"%.200s\" is read-only", RNA_property_identifier(self->prop), RNA_struct_identifier(self->ptr.type) );
+ if (!RNA_property_editable_flag(&self->ptr, self->prop)) {
+ PyErr_Format(PyExc_AttributeError, "bpy_prop_collection: attribute \"%.200s\" from \"%.200s\" is read-only", RNA_property_identifier(self->prop), RNA_struct_identifier(self->ptr.type) );
return -1;
}
@@ -1467,7 +1479,7 @@ static int pyrna_prop_collection_contains(BPy_PropertyRNA *self, PyObject *value
char *keyname = _PyUnicode_AsString(value);
if(keyname==NULL) {
- PyErr_SetString(PyExc_TypeError, "PropertyRNA - key in prop, key must be a string type");
+ PyErr_SetString(PyExc_TypeError, "bpy_prop_collection.__contains__: expected a string");
return -1;
}
@@ -1483,12 +1495,12 @@ static int pyrna_struct_contains(BPy_StructRNA *self, PyObject *value)
char *name = _PyUnicode_AsString(value);
if (!name) {
- PyErr_SetString( PyExc_TypeError, "expected a string");
+ PyErr_SetString( PyExc_TypeError, "bpy_struct.__contains__: expected a string");
return -1;
}
if(RNA_struct_idproperties_check(self->ptr.type)==0) {
- PyErr_SetString( PyExc_TypeError, "this type doesnt support IDProperties");
+ PyErr_SetString( PyExc_TypeError, "bpy_struct: this type doesnt support IDProperties");
return -1;
}
@@ -1545,21 +1557,21 @@ static PyObject *pyrna_struct_subscript( BPy_StructRNA *self, PyObject *key )
}
if(name==NULL) {
- PyErr_SetString( PyExc_TypeError, "only strings are allowed as keys of ID properties");
+ PyErr_SetString( PyExc_TypeError, "bpy_struct[key]: only strings are allowed as keys of ID properties");
return NULL;
}
group= RNA_struct_idproperties(&self->ptr, 0);
if(group==NULL) {
- PyErr_Format( PyExc_KeyError, "key \"%s\" not found", name);
+ PyErr_Format( PyExc_KeyError, "bpy_struct[key]: key \"%s\" not found", name);
return NULL;
}
idprop= IDP_GetPropertyFromGroup(group, name);
if(idprop==NULL) {
- PyErr_Format( PyExc_KeyError, "key \"%s\" not found", name);
+ PyErr_Format( PyExc_KeyError, "bpy_struct[key]: key \"%s\" not found", name);
return NULL;
}
@@ -1571,7 +1583,7 @@ static int pyrna_struct_ass_subscript( BPy_StructRNA *self, PyObject *key, PyObj
IDProperty *group= RNA_struct_idproperties(&self->ptr, 1);
if(group==NULL) {
- PyErr_SetString(PyExc_TypeError, "id properties not supported for this type");
+ PyErr_SetString(PyExc_TypeError, "bpy_struct[key] = val: id properties not supported for this type");
return -1;
}
@@ -1589,7 +1601,7 @@ static PyObject *pyrna_struct_keys(BPy_PropertyRNA *self)
IDProperty *group;
if(RNA_struct_idproperties_check(self->ptr.type)==0) {
- PyErr_SetString( PyExc_TypeError, "this type doesnt support IDProperties");
+ PyErr_SetString( PyExc_TypeError, "bpy_struct.keys(): this type doesn't support IDProperties");
return NULL;
}
@@ -1606,7 +1618,7 @@ static PyObject *pyrna_struct_items(BPy_PropertyRNA *self)
IDProperty *group;
if(RNA_struct_idproperties_check(self->ptr.type)==0) {
- PyErr_SetString( PyExc_TypeError, "this type doesnt support IDProperties");
+ PyErr_SetString( PyExc_TypeError, "bpy_struct.items(): this type doesn't support IDProperties");
return NULL;
}
@@ -1624,7 +1636,7 @@ static PyObject *pyrna_struct_values(BPy_PropertyRNA *self)
IDProperty *group;
if(RNA_struct_idproperties_check(self->ptr.type)==0) {
- PyErr_SetString( PyExc_TypeError, "this type doesnt support IDProperties");
+ PyErr_SetString( PyExc_TypeError, "bpy_struct.values(): this type doesn't support IDProperties");
return NULL;
}
@@ -1636,47 +1648,81 @@ static PyObject *pyrna_struct_values(BPy_PropertyRNA *self)
return BPy_Wrap_GetValues(self->ptr.id.data, group);
}
-static PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args)
+/* internal use for insert and delete */
+int pyrna_struct_keyframe_parse(PointerRNA *ptr, PyObject *args, char *error_prefix,
+ char **path_full, int *index, float *cfra) /* return values */
{
- char *path, *path_full;
- int index= -1; /* default to all */
- float cfra = CTX_data_scene(BPy_GetContext())->r.cfra;
+ char *path;
PropertyRNA *prop;
- PyObject *result;
- if (!PyArg_ParseTuple(args, "s|if:keyframe_insert", &path, &index, &cfra))
- return NULL;
+ if (!PyArg_ParseTuple(args, "s|if", &path, &index, &cfra)) {
+ PyErr_Format(PyExc_TypeError, "%.200s expected a string and optionally an int and float arguments", error_prefix);
+ return -1;
+ }
- if (self->ptr.data==NULL) {
- PyErr_Format( PyExc_TypeError, "keyframe_insert, this struct has no data, cant be animated", path);
- return NULL;
+ if (ptr->data==NULL) {
+ PyErr_Format(PyExc_TypeError, "%.200s this struct has no data, can't be animated", error_prefix);
+ return -1;
}
- prop = RNA_struct_find_property(&self->ptr, path);
+ prop = RNA_struct_find_property(ptr, path);
if (prop==NULL) {
- PyErr_Format( PyExc_TypeError, "keyframe_insert, property \"%s\" not found", path);
- return NULL;
+ PyErr_Format( PyExc_TypeError, "%.200s property \"%s\" not found", error_prefix, path);
+ return -1;
}
- if (!RNA_property_animateable(&self->ptr, prop)) {
- PyErr_Format( PyExc_TypeError, "keyframe_insert, property \"%s\" not animatable", path);
- return NULL;
+ if (!RNA_property_animateable(ptr, prop)) {
+ PyErr_Format( PyExc_TypeError, "%.200s property \"%s\" not animatable", error_prefix, path);
+ return -1;
}
- path_full= RNA_path_from_ID_to_property(&self->ptr, prop);
+ *path_full= RNA_path_from_ID_to_property(ptr, prop);
- if (path_full==NULL) {
- PyErr_Format( PyExc_TypeError, "keyframe_insert, could not make path to \"%s\"", path);
- return NULL;
+ if (*path_full==NULL) {
+ PyErr_Format( PyExc_TypeError, "%.200s could not make path to \"%s\"", error_prefix, path);
+ return -1;
}
- result= PyBool_FromLong( insert_keyframe((ID *)self->ptr.id.data, NULL, NULL, path_full, index, cfra, 0));
+ if(*cfra==FLT_MAX)
+ *cfra= CTX_data_scene(BPy_GetContext())->r.cfra;
+
+ return 0; /* success */
+}
+
+static PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args)
+{
+ PyObject *result;
+ /* args, pyrna_struct_keyframe_parse handles these */
+ char *path_full= NULL;
+ int index= -1;
+ float cfra= FLT_MAX;
+
+ if(pyrna_struct_keyframe_parse(&self->ptr, args, "bpy_struct.keyframe_insert():", &path_full, &index, &cfra) == -1)
+ return NULL;
+
+ result= PyBool_FromLong(insert_keyframe((ID *)self->ptr.id.data, NULL, NULL, path_full, index, cfra, 0));
MEM_freeN(path_full);
return result;
}
+static PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args)
+{
+ PyObject *result;
+ /* args, pyrna_struct_keyframe_parse handles these */
+ char *path_full= NULL;
+ int index= -1;
+ float cfra= FLT_MAX;
+
+ if(pyrna_struct_keyframe_parse(&self->ptr, args, "bpy_struct.keyframe_delete():", &path_full, &index, &cfra) == -1)
+ return NULL;
+
+ result= PyBool_FromLong(delete_keyframe((ID *)self->ptr.id.data, NULL, NULL, path_full, index, cfra, 0));
+ MEM_freeN(path_full);
+
+ return result;
+}
static PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args)
{
@@ -1689,26 +1735,26 @@ static PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args)
return NULL;
if (self->ptr.data==NULL) {
- PyErr_Format( PyExc_TypeError, "driver_add, this struct has no data, cant be animated", path);
+ PyErr_Format( PyExc_TypeError, "bpy_struct.driver_add(): this struct has no data, cant be animated", path);
return NULL;
}
prop = RNA_struct_find_property(&self->ptr, path);
if (prop==NULL) {
- PyErr_Format( PyExc_TypeError, "driver_add, property \"%s\" not found", path);
+ PyErr_Format( PyExc_TypeError, "bpy_struct.driver_add(): property \"%s\" not found", path);
return NULL;
}
if (!RNA_property_animateable(&self->ptr, prop)) {
- PyErr_Format( PyExc_TypeError, "driver_add, property \"%s\" not animatable", path);
+ PyErr_Format( PyExc_TypeError, "bpy_struct.driver_add(): property \"%s\" not animatable", path);
return NULL;
}
path_full= RNA_path_from_ID_to_property(&self->ptr, prop);
if (path_full==NULL) {
- PyErr_Format( PyExc_TypeError, "driver_add, could not make path to \"%s\"", path);
+ PyErr_Format( PyExc_TypeError, "bpy_struct.driver_add(): could not make path to \"%s\"", path);
return NULL;
}
@@ -1778,7 +1824,7 @@ static PyObject *pyrna_struct_path_resolve(BPy_StructRNA *self, PyObject *value)
PropertyRNA *r_prop;
if(path==NULL) {
- PyErr_SetString( PyExc_TypeError, "items() is only valid for collection types" );
+ PyErr_SetString( PyExc_TypeError, "bpy_struct.items(): is only valid for collection types" );
return NULL;
}
@@ -1801,7 +1847,7 @@ static PyObject *pyrna_struct_path_to_id(BPy_StructRNA *self, PyObject *args)
if(name) {
prop= RNA_struct_find_property(&self->ptr, name);
if(prop==NULL) {
- PyErr_Format(PyExc_TypeError, "path_to_id(\"%.200s\") not found", name);
+ PyErr_Format(PyExc_TypeError, "%.200s.path_to_id(\"%.200s\") not found", RNA_struct_identifier(self->ptr.type), name);
return NULL;
}
@@ -1960,7 +2006,7 @@ static PyObject *pyrna_struct_getattro( BPy_StructRNA *self, PyObject *pyname )
if(name[0]=='_') { // rna can't start with a "_", so for __dict__ and similar we can skip using rna lookups
/* annoying exception, maybe we need to have different types for this... */
if((strcmp(name, "__getitem__")==0 || strcmp(name, "__setitem__")==0) && !RNA_struct_idproperties_check(self->ptr.type)) {
- PyErr_SetString(PyExc_AttributeError, "StructRNA - no __getitem__ support for this type");
+ PyErr_SetString(PyExc_AttributeError, "bpy_struct: no __getitem__ support for this type");
ret = NULL;
}
else {
@@ -1977,7 +2023,7 @@ static PyObject *pyrna_struct_getattro( BPy_StructRNA *self, PyObject *pyname )
else if (self->ptr.type == &RNA_Context) {
bContext *C = self->ptr.data;
if(C==NULL) {
- PyErr_Format( PyExc_AttributeError, "StructRNA Context is 'NULL', can't get \"%.200s\" from context", name);
+ PyErr_Format( PyExc_AttributeError, "bpy_struct: Context is 'NULL', can't get \"%.200s\" from context", name);
ret= NULL;
}
else {
@@ -2021,7 +2067,7 @@ static PyObject *pyrna_struct_getattro( BPy_StructRNA *self, PyObject *pyname )
}
else {
#if 0
- PyErr_Format( PyExc_AttributeError, "StructRNA - Attribute \"%.200s\" not found", name);
+ PyErr_Format( PyExc_AttributeError, "bpy_struct: attribute \"%.200s\" not found", name);
ret = NULL;
#endif
/* Include this incase this instance is a subtype of a python class
@@ -2056,30 +2102,13 @@ static int pyrna_struct_setattro( BPy_StructRNA *self, PyObject *pyname, PyObjec
if (prop==NULL) {
return PyObject_GenericSetAttr((PyObject *)self, pyname, value);
-#if 0
- // XXX - This currently allows anything to be assigned to an rna prop, need to see how this should be used
- // but for now it makes porting scripts confusing since it fails silently.
- // edit: allowing this for setting classes internal attributes.
- // edit: allow this for any attribute that alredy exists as a python attr
- if ( (name[0]=='_' /* || pyrna_struct_pydict_contains(self, pyname) */ ) &&
- !BPy_StructRNA_CheckExact(self) &&
-
- return 0;
- } else
- {
- PyErr_Format( PyExc_AttributeError, "StructRNA - Attribute \"%.200s\" not found", name);
- return -1;
- }
-#endif
- }
-
- if (!RNA_property_editable(&self->ptr, prop)) {
- PyErr_Format( PyExc_AttributeError, "StructRNA - Attribute \"%.200s\" from \"%.200s\" is read-only", RNA_property_identifier(prop), RNA_struct_identifier(self->ptr.type) );
+ } else if (!RNA_property_editable_flag(&self->ptr, prop)) {
+ PyErr_Format( PyExc_AttributeError, "bpy_struct: attribute \"%.200s\" from \"%.200s\" is read-only", RNA_property_identifier(prop), RNA_struct_identifier(self->ptr.type) );
return -1;
}
/* pyrna_py_to_prop sets its own exceptions */
- return pyrna_py_to_prop(&self->ptr, prop, NULL, NULL, value, "StructRNA - item.attr = val:");
+ return pyrna_py_to_prop(&self->ptr, prop, NULL, NULL, value, "bpy_struct: item.attr = val:");
}
static PyObject *pyrna_prop_dir(BPy_PropertyRNA *self)
@@ -2151,7 +2180,7 @@ static int pyrna_prop_collection_setattro( BPy_PropertyRNA *self, PyObject *pyna
}
}
- PyErr_Format( PyExc_AttributeError, "BPy_PropertyRNA - Attribute \"%.200s\" not found", name);
+ PyErr_Format( PyExc_AttributeError, "bpy_prop_collection: attribute \"%.200s\" not found", name);
return -1;
}
@@ -2162,7 +2191,7 @@ static PyObject *pyrna_prop_add(BPy_PropertyRNA *self)
RNA_property_collection_add(&self->ptr, self->prop, &r_ptr);
if(!r_ptr.data) {
- PyErr_SetString( PyExc_TypeError, "add() not supported for this collection");
+ PyErr_SetString( PyExc_TypeError, "bpy_prop_collection.add(): not supported for this collection");
return NULL;
}
else {
@@ -2176,12 +2205,12 @@ static PyObject *pyrna_prop_remove(BPy_PropertyRNA *self, PyObject *value)
int key= PyLong_AsSsize_t(value);
if (key==-1 && PyErr_Occurred()) {
- PyErr_SetString( PyExc_TypeError, "remove() expected one int argument");
+ PyErr_SetString( PyExc_TypeError, "bpy_prop_collection.remove(): expected one int argument");
return NULL;
}
if(!RNA_property_collection_remove(&self->ptr, self->prop, key)) {
- PyErr_SetString( PyExc_TypeError, "remove() not supported for this collection");
+ PyErr_SetString( PyExc_TypeError, "bpy_prop_collection.remove() not supported for this collection");
return NULL;
}
@@ -2219,96 +2248,74 @@ static PyGetSetDef pyrna_struct_getseters[] = {
static PyObject *pyrna_prop_keys(BPy_PropertyRNA *self)
{
- PyObject *ret;
- if (RNA_property_type(self->prop) != PROP_COLLECTION) {
- PyErr_SetString( PyExc_TypeError, "keys() is only valid for collection types" );
- ret = NULL;
- } else {
- PyObject *item;
- char name[256], *nameptr;
+ PyObject *ret= PyList_New(0);
+ PyObject *item;
+ char name[256], *nameptr;
- ret = PyList_New(0);
-
- RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) {
- nameptr= RNA_struct_name_get_alloc(&itemptr, name, sizeof(name));
+ RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) {
+ nameptr= RNA_struct_name_get_alloc(&itemptr, name, sizeof(name));
- if(nameptr) {
- /* add to python list */
- item = PyUnicode_FromString( nameptr );
- PyList_Append(ret, item);
- Py_DECREF(item);
- /* done */
-
- if(name != nameptr)
- MEM_freeN(nameptr);
- }
+ if(nameptr) {
+ /* add to python list */
+ item = PyUnicode_FromString( nameptr );
+ PyList_Append(ret, item);
+ Py_DECREF(item);
+ /* done */
+
+ if(name != nameptr)
+ MEM_freeN(nameptr);
}
- RNA_PROP_END;
}
+ RNA_PROP_END;
return ret;
}
static PyObject *pyrna_prop_items(BPy_PropertyRNA *self)
{
- PyObject *ret;
- if (RNA_property_type(self->prop) != PROP_COLLECTION) {
- PyErr_SetString( PyExc_TypeError, "items() is only valid for collection types" );
- ret = NULL;
- } else {
- PyObject *item;
- char name[256], *nameptr;
- int i= 0;
+ PyObject *ret= PyList_New(0);
+ PyObject *item;
+ char name[256], *nameptr;
+ int i= 0;
- ret = PyList_New(0);
-
- RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) {
- if(itemptr.data) {
- /* add to python list */
- item= PyTuple_New(2);
- nameptr= RNA_struct_name_get_alloc(&itemptr, name, sizeof(name));
- if(nameptr) {
- PyTuple_SET_ITEM(item, 0, PyUnicode_FromString( nameptr ));
- if(name != nameptr)
- MEM_freeN(nameptr);
- }
- else {
- PyTuple_SET_ITEM(item, 0, PyLong_FromSsize_t(i)); /* a bit strange but better then returning an empty list */
- }
- PyTuple_SET_ITEM(item, 1, pyrna_struct_CreatePyObject(&itemptr));
-
- PyList_Append(ret, item);
- Py_DECREF(item);
-
- i++;
+ RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) {
+ if(itemptr.data) {
+ /* add to python list */
+ item= PyTuple_New(2);
+ nameptr= RNA_struct_name_get_alloc(&itemptr, name, sizeof(name));
+ if(nameptr) {
+ PyTuple_SET_ITEM(item, 0, PyUnicode_FromString( nameptr ));
+ if(name != nameptr)
+ MEM_freeN(nameptr);
+ }
+ else {
+ PyTuple_SET_ITEM(item, 0, PyLong_FromSsize_t(i)); /* a bit strange but better then returning an empty list */
}
+ PyTuple_SET_ITEM(item, 1, pyrna_struct_CreatePyObject(&itemptr));
+
+ PyList_Append(ret, item);
+ Py_DECREF(item);
+
+ i++;
}
- RNA_PROP_END;
}
+ RNA_PROP_END;
return ret;
}
-
static PyObject *pyrna_prop_values(BPy_PropertyRNA *self)
{
- PyObject *ret;
+ PyObject *ret= PyList_New(0);
+ PyObject *item;
- if (RNA_property_type(self->prop) != PROP_COLLECTION) {
- PyErr_SetString( PyExc_TypeError, "values() is only valid for collection types" );
- ret = NULL;
- } else {
- PyObject *item;
- ret = PyList_New(0);
-
- RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) {
- item = pyrna_struct_CreatePyObject(&itemptr);
- PyList_Append(ret, item);
- Py_DECREF(item);
- }
- RNA_PROP_END;
+ RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) {
+ item = pyrna_struct_CreatePyObject(&itemptr);
+ PyList_Append(ret, item);
+ Py_DECREF(item);
}
-
+ RNA_PROP_END;
+
return ret;
}
@@ -2656,6 +2663,7 @@ static struct PyMethodDef pyrna_struct_methods[] = {
/* maybe this become and ID function */
{"keyframe_insert", (PyCFunction)pyrna_struct_keyframe_insert, METH_VARARGS, NULL},
+// {"keyframe_delete", (PyCFunction)pyrna_struct_keyframe_delete, METH_VARARGS, NULL}, // WIP
{"driver_add", (PyCFunction)pyrna_struct_driver_add, METH_VARARGS, NULL},
{"is_property_set", (PyCFunction)pyrna_struct_is_property_set, METH_VARARGS, NULL},
{"is_property_hidden", (PyCFunction)pyrna_struct_is_property_hidden, METH_VARARGS, NULL},
@@ -2663,6 +2671,11 @@ static struct PyMethodDef pyrna_struct_methods[] = {
{"path_to_id", (PyCFunction)pyrna_struct_path_to_id, METH_VARARGS, NULL},
{"recast_type", (PyCFunction)pyrna_struct_recast_type, METH_NOARGS, NULL},
{"__dir__", (PyCFunction)pyrna_struct_dir, METH_NOARGS, NULL},
+
+ /* experemental */
+ {"callback_add", (PyCFunction)pyrna_callback_add, METH_VARARGS, NULL},
+ {"callback_remove", (PyCFunction)pyrna_callback_remove, METH_VARARGS, NULL},
+
{NULL, NULL, 0, NULL}
};
@@ -2700,7 +2713,7 @@ static PyObject * pyrna_struct_new(PyTypeObject *type, PyObject *args, PyObject
BPy_StructRNA *base = NULL;
- if (!PyArg_ParseTuple(args, "O!:Base BPy_StructRNA", &pyrna_struct_Type, &base))
+ if (!PyArg_ParseTuple(args, "O!:bpy_struct.__new__", &pyrna_struct_Type, &base))
return NULL;
if (type == &pyrna_struct_Type) {
@@ -2883,7 +2896,7 @@ static PyObject * pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw)
ParameterIterator iter;
PropertyRNA *parm;
PyObject *ret, *item;
- int i, args_len, parms_len, ret_len, flag, err= 0, kw_tot= 0, kw_arg;
+ int i, pyargs_len, pykw_len, parms_len, ret_len, flag, err= 0, kw_tot= 0, kw_arg;
const char *parm_id;
PropertyRNA *pret_single= NULL;
@@ -2905,16 +2918,17 @@ static PyObject * pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw)
* the same ID as the functions. */
RNA_pointer_create(self_ptr->id.data, &RNA_Function, self_func, &funcptr);
- args_len= PyTuple_GET_SIZE(args);
+ pyargs_len= PyTuple_GET_SIZE(args);
+ pykw_len= kw ? PyDict_Size(kw) : 0;
RNA_parameter_list_create(&parms, self_ptr, self_func);
RNA_parameter_list_begin(&parms, &iter);
parms_len= RNA_parameter_list_size(&parms);
ret_len= 0;
- if(args_len + (kw ? PyDict_Size(kw):0) > parms_len) {
+ if(pyargs_len + pykw_len > parms_len) {
RNA_parameter_list_end(&iter);
- PyErr_Format(PyExc_TypeError, "%.200s.%.200s(): takes at most %d arguments, got %d", RNA_struct_identifier(self_ptr->type), RNA_function_identifier(self_func), parms_len, args_len);
+ PyErr_Format(PyExc_TypeError, "%.200s.%.200s(): takes at most %d arguments, got %d", RNA_struct_identifier(self_ptr->type), RNA_function_identifier(self_func), parms_len, pyargs_len + pykw_len);
err= -1;
}
@@ -2937,7 +2951,7 @@ static PyObject * pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw)
parm_id= RNA_property_identifier(parm);
item= NULL;
- if ((i < args_len) && (flag & PROP_REQUIRED)) {
+ if ((i < pyargs_len) && (flag & PROP_REQUIRED)) {
item= PyTuple_GET_ITEM(args, i);
i++;
@@ -2988,7 +3002,7 @@ static PyObject * pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw)
* the if below is quick, checking if it passed less keyword args then we gave.
* (Dont overwrite the error if we have one, otherwise can skip important messages and confuse with args)
*/
- if(err == 0 && kw && (PyDict_Size(kw) > kw_tot)) {
+ if(err == 0 && kw && (pykw_len > kw_tot)) {
PyObject *key, *value;
Py_ssize_t pos = 0;
@@ -3111,7 +3125,7 @@ static PyObject * pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw)
/*-----------------------BPy_StructRNA method def------------------------------*/
PyTypeObject pyrna_struct_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
- "StructRNA", /* tp_name */
+ "bpy_struct", /* tp_name */
sizeof( BPy_StructRNA ), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
@@ -3190,7 +3204,7 @@ PyTypeObject pyrna_struct_Type = {
/*-----------------------BPy_PropertyRNA method def------------------------------*/
PyTypeObject pyrna_prop_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
- "PropertyRNA", /* tp_name */
+ "bpy_prop", /* tp_name */
sizeof( BPy_PropertyRNA ), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
@@ -3270,7 +3284,7 @@ PyTypeObject pyrna_prop_Type = {
PyTypeObject pyrna_prop_array_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
- "PropertyArrayRNA", /* tp_name */
+ "bpy_prop_array", /* tp_name */
sizeof( BPy_PropertyRNA ), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
@@ -3350,7 +3364,7 @@ PyTypeObject pyrna_prop_array_Type = {
PyTypeObject pyrna_prop_collection_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
- "PropertyCollectionRNA", /* tp_name */
+ "bpy_prop_collection", /* tp_name */
sizeof( BPy_PropertyRNA ), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
@@ -3669,7 +3683,7 @@ PyObject *pyrna_struct_CreatePyObject( PointerRNA *ptr )
}
if( !pyrna ) {
- PyErr_SetString( PyExc_MemoryError, "couldn't create BPy_StructRNA object" );
+ PyErr_SetString( PyExc_MemoryError, "couldn't create bpy_struct object" );
return NULL;
}
@@ -3915,7 +3929,7 @@ static int deferred_register_prop(StructRNA *srna, PyObject *item, PyObject *key
if(PyArg_ParseTuple(item, "O!O!", &PyCapsule_Type, &py_func_ptr, &PyDict_Type, &py_kw)) {
if(*_PyUnicode_AsString(key)=='_') {
- PyErr_Format(PyExc_ValueError, "StructRNA \"%.200s\" registration error: %.200s could not register because the property starts with an '_'\n", RNA_struct_identifier(srna), _PyUnicode_AsString(key));
+ PyErr_Format(PyExc_ValueError, "bpy_struct \"%.200s\" registration error: %.200s could not register because the property starts with an '_'\n", RNA_struct_identifier(srna), _PyUnicode_AsString(key));
Py_DECREF(dummy_args);
return -1;
}
@@ -3936,7 +3950,7 @@ static int deferred_register_prop(StructRNA *srna, PyObject *item, PyObject *key
PyErr_Clear();
// PyLineSpit();
- PyErr_Format(PyExc_ValueError, "StructRNA \"%.200s\" registration error: %.200s could not register\n", RNA_struct_identifier(srna), _PyUnicode_AsString(key));
+ PyErr_Format(PyExc_ValueError, "bpy_struct \"%.200s\" registration error: %.200s could not register\n", RNA_struct_identifier(srna), _PyUnicode_AsString(key));
Py_DECREF(dummy_args);
return -1;
@@ -4143,7 +4157,8 @@ extern void BPY_update_modules( void ); //XXX temp solution
static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *parms)
{
PyObject *args;
- PyObject *ret= NULL, *py_class, *py_class_instance, *item, *parmitem;
+ PyObject *ret= NULL, *py_srna= NULL, *py_class, *py_class_instance= NULL, *parmitem;
+ void **py_class_instance_store= NULL;
PropertyRNA *parm;
ParameterIterator iter;
PointerRNA funcptr;
@@ -4159,23 +4174,49 @@ static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *par
py_class= RNA_struct_py_type_get(ptr->type);
- item = pyrna_struct_CreatePyObject(ptr);
- if(item == NULL) {
+ /* exception, operators store their PyObjects for re-use */
+ if(ptr->data) {
+ if(RNA_struct_is_a(ptr->type, &RNA_Operator)) {
+ wmOperator *op= ptr->data;
+ if(op->py_instance) {
+ py_class_instance= op->py_instance;
+ Py_INCREF(py_class_instance);
+ }
+ else {
+ /* store the instance here once its created */
+ py_class_instance_store= &op->py_instance;
+ }
+ }
+ }
+ /* end exception */
+
+ if(py_class_instance==NULL)
+ py_srna= pyrna_struct_CreatePyObject(ptr);
+
+ if(py_class_instance) {
+ /* special case, instance is cached */
+ }
+ else if(py_srna == NULL) {
py_class_instance = NULL;
}
- else if(item == Py_None) { /* probably wont ever happen but possible */
- Py_DECREF(item);
+ else if(py_srna == Py_None) { /* probably wont ever happen but possible */
+ Py_DECREF(py_srna);
py_class_instance = NULL;
}
else {
args = PyTuple_New(1);
- PyTuple_SET_ITEM(args, 0, item);
+ PyTuple_SET_ITEM(args, 0, py_srna);
py_class_instance = PyObject_Call(py_class, args, NULL);
Py_DECREF(args);
+
+ if(py_class_instance_store) {
+ *py_class_instance_store = py_class_instance;
+ Py_INCREF(py_class_instance);
+ }
}
if (py_class_instance) { /* Initializing the class worked, now run its invoke function */
- item= PyObject_GetAttrString(py_class, RNA_function_identifier(func));
+ PyObject *item= PyObject_GetAttrString(py_class, RNA_function_identifier(func));
// flag= RNA_function_flag(func);
if(item) {
diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h
index 77f6ec00d48..770e88e1a1d 100644
--- a/source/blender/python/intern/bpy_rna.h
+++ b/source/blender/python/intern/bpy_rna.h
@@ -84,6 +84,8 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop);
PyObject *pyrna_enum_bitfield_to_py(struct EnumPropertyItem *items, int value);
int pyrna_set_to_enum_bitfield(EnumPropertyItem *items, PyObject *value, int *r_value, const char *error_prefix);
+int pyrna_enum_value_from_id(EnumPropertyItem *item, const char *identifier, int *value, const char *error_prefix);
+
/* function for registering types */
PyObject *pyrna_basetype_register(PyObject *self, PyObject *args);
PyObject *pyrna_basetype_unregister(PyObject *self, PyObject *args);
diff --git a/source/blender/python/intern/bpy_rna_callback.c b/source/blender/python/intern/bpy_rna_callback.c
new file mode 100644
index 00000000000..ee0c5cb143b
--- /dev/null
+++ b/source/blender/python/intern/bpy_rna_callback.c
@@ -0,0 +1,111 @@
+/**
+ * $Id:
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "Python.h"
+
+#include "bpy_rna.h"
+#include "bpy_util.h"
+
+#include "BLI_path_util.h"
+#include "DNA_screen_types.h"
+#include "BKE_context.h"
+#include "ED_space_api.h"
+
+EnumPropertyItem region_draw_mode_items[] = {
+ {REGION_DRAW_POST_VIEW, "POST_VIEW", 0, "Pose View", ""},
+ {REGION_DRAW_POST_PIXEL, "POST_PIXEL", 0, "Post Pixel", ""},
+ {REGION_DRAW_PRE_VIEW, "PRE_VIEW", 0, "Pre View", ""},
+ {0, NULL, 0, NULL, NULL}};
+
+
+void cb_region_draw(const bContext *C, ARegion *ar, void *customdata)
+{
+ PyObject *cb_func, *cb_args, *result;
+ PyGILState_STATE gilstate;
+
+ bpy_context_set((bContext *)C, &gilstate);
+
+ cb_func= PyTuple_GET_ITEM((PyObject *)customdata, 0);
+ cb_args= PyTuple_GET_ITEM((PyObject *)customdata, 1);
+ result = PyObject_CallObject(cb_func, cb_args);
+
+ if(result) {
+ Py_DECREF(result);
+ }
+ else {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+
+ bpy_context_clear((bContext *)C, &gilstate);
+}
+
+PyObject *pyrna_callback_add(BPy_StructRNA *self, PyObject *args)
+{
+ void *handle;
+
+ PyObject *cb_func, *cb_args;
+ char *cb_event_str= NULL;
+ int cb_event;
+
+ if (!PyArg_ParseTuple(args, "OO|s:bpy_struct.callback_add", &cb_func, &cb_args, &cb_event_str))
+ return NULL;
+
+ if(RNA_struct_is_a(self->ptr.type, &RNA_Region)) {
+
+ if(pyrna_enum_value_from_id(region_draw_mode_items, cb_event_str, &cb_event, "bpy_struct.callback_add()") < 0)
+ return NULL;
+
+ handle= ED_region_draw_cb_activate(((ARegion *)self->ptr.data)->type, cb_region_draw, (void *)args, cb_event);
+ Py_INCREF(args);
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError, "callbcak_add(): type does not suppport cllbacks");
+ return NULL;
+ }
+
+ return PyCapsule_New((void *)handle, NULL, NULL);
+}
+
+PyObject *pyrna_callback_remove(BPy_StructRNA *self, PyObject *args)
+{
+ PyObject *py_handle;
+ PyObject *py_args;
+ void *handle;
+ void *customdata;
+
+ if (!PyArg_ParseTuple(args, "O!:callback_remove", &PyCapsule_Type, &py_handle))
+ return NULL;
+
+ handle= PyCapsule_GetPointer(py_handle, NULL);
+
+ if(RNA_struct_is_a(self->ptr.type, &RNA_Region)) {
+ customdata= ED_region_draw_cb_customdata(handle);
+ Py_DECREF((PyObject *)customdata);
+
+ ED_region_draw_cb_exit(((ARegion *)self->ptr.data)->type, handle);
+ }
+
+ Py_RETURN_NONE;
+}
diff --git a/source/blender/python/intern/bpy_rna_callback.h b/source/blender/python/intern/bpy_rna_callback.h
new file mode 100644
index 00000000000..b6d771b23b2
--- /dev/null
+++ b/source/blender/python/intern/bpy_rna_callback.h
@@ -0,0 +1,29 @@
+/**
+ * $Id:
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+struct BPy_StructRNA;
+struct PyObject;
+
+struct PyObject *pyrna_callback_add(struct BPy_StructRNA *self, struct PyObject *args);
+struct PyObject *pyrna_callback_remove(struct BPy_StructRNA *self, struct PyObject *args);
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index c44d83f4f06..0a292c7acd5 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -2405,7 +2405,7 @@ static void init_render_mball(Render *re, ObjectRen *obr)
ver->n[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
ver->n[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
normalize_v3(ver->n);
- //if(ob->transflag & OB_NEG_SCALE) mul_v3_fl(ver->n. -1.0);
+ //if(ob->transflag & OB_NEG_SCALE) negate_v3(ver->n);
if(need_orco) ver->orco= orco;
}
diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c
index 10cbd82fb1b..954ff373c89 100644
--- a/source/blender/render/intern/source/shadbuf.c
+++ b/source/blender/render/intern/source/shadbuf.c
@@ -986,8 +986,9 @@ static float readdeepvisibility(DeepSample *dsample, int tot, int z, int bias, f
if(a == 0)
return 1.0f; /* completely in front of all samples */
+ /* converting to float early here because ds->z - prevds->z can overflow */
prevds= ds-1;
- t= (float)(z-bias - prevds->z)/(float)(ds->z - prevds->z);
+ t= ((float)(z-bias) - (float)prevds->z)/((float)ds->z - (float)prevds->z);
return t*ds->v + (1.0f-t)*prevds->v;
}
diff --git a/source/blender/render/intern/source/volumetric.c b/source/blender/render/intern/source/volumetric.c
index 1622ee2bf4c..70e0fd41b7d 100644
--- a/source/blender/render/intern/source/volumetric.c
+++ b/source/blender/render/intern/source/volumetric.c
@@ -488,7 +488,7 @@ void vol_shade_one_lamp(struct ShadeInput *shi, float *co, LampRen *lar, float *
if (ELEM(lar->type, LA_SUN, LA_HEMI))
VECCOPY(lv, lar->vec);
- mul_v3_fl(lv, -1.0f);
+ negate_v3(lv);
if (shi->mat->vol.shade_type == MA_VOL_SHADE_SHADOWED) {
mul_v3_fl(lacol, vol_get_shadow(shi, lar, co));
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index e2b2c17beee..048487fcd68 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -54,6 +54,7 @@
#include "wm.h"
#include "ED_screen.h"
+#include "BPY_extern.h"
#include "RNA_types.h"
@@ -63,6 +64,12 @@
void WM_operator_free(wmOperator *op)
{
+ if(op->py_instance) {
+ /* do this first incase there are any __del__ functions or
+ * similar that use properties */
+ BPY_DECREF(op->py_instance);
+ }
+
if(op->ptr) {
op->properties= op->ptr->data;
MEM_freeN(op->ptr);
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 74679ce89a6..b72bc02aca6 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -28,6 +28,7 @@
#include <stdlib.h>
#include <string.h>
+#include <math.h>
#include "DNA_listBase.h"
#include "DNA_screen_types.h"
@@ -1533,23 +1534,32 @@ void wm_event_do_handlers(bContext *C)
wm_event_free_all(win);
else
{
- if(win->screen->scene)
+ Scene* scene = win->screen->scene;
+ if(scene)
{
int playing = sound_scene_playing(win->screen->scene);
if(playing != -1)
{
+ CTX_wm_window_set(C, win);
+ CTX_wm_screen_set(C, win->screen);
+ CTX_data_scene_set(C, scene);
if(((playing == 1) && (!win->screen->animtimer)) || ((playing == 0) && (win->screen->animtimer)))
{
- CTX_wm_window_set(C, win);
- CTX_wm_screen_set(C, win->screen);
- CTX_data_scene_set(C, win->screen->scene);
-
ED_screen_animation_play(C, -1, 1);
-
- CTX_data_scene_set(C, NULL);
- CTX_wm_screen_set(C, NULL);
- CTX_wm_window_set(C, NULL);
}
+ if(playing == 0)
+ {
+ int ncfra = floor(sound_sync_scene(scene) * FPS);
+ if(ncfra != scene->r.cfra)
+ {
+ scene->r.cfra = ncfra;
+ ED_update_for_newframe(C, 1);
+ WM_event_add_notifier(C, NC_WINDOW, NULL);
+ }
+ }
+ CTX_data_scene_set(C, NULL);
+ CTX_wm_screen_set(C, NULL);
+ CTX_wm_window_set(C, NULL);
}
}
}
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index 16776517e40..2ab6f78daa5 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -241,6 +241,10 @@ static void wm_init_userdef(bContext *C)
UI_init_userdef();
MEM_CacheLimiter_set_maximum(U.memcachelimit * 1024 * 1024);
sound_init(CTX_data_main(C));
+
+ /* set the python auto-execute setting from user prefs */
+ if (U.flag & USER_SCRIPT_AUTOEXEC_DISABLE) G.f &= ~G_SCRIPT_AUTOEXEC;
+ else G.f |= G_SCRIPT_AUTOEXEC;
}
void WM_read_file(bContext *C, char *name, ReportList *reports)
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index b52588f2e75..29359b1ddb9 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -1120,7 +1120,10 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *arg_unuse
else display_name= recent->filename;
uiItemStringO(col, display_name, ICON_FILE_BLEND, "WM_OT_open_mainfile", "path", recent->filename);
}
-
+ uiItemL(col, "Recovery", 0);
+ uiItemO(col, NULL, ICON_FILE_BLEND, "WM_OT_recover_last_session");
+ uiItemO(col, NULL, ICON_FILE_BLEND, "WM_OT_recover_auto_save");
+
uiItemL(col, "", 0);
uiCenteredBoundsBlock(block, 0.0f);
@@ -1323,10 +1326,17 @@ static void open_set_load_ui(wmOperator *op)
RNA_boolean_set(op->ptr, "load_ui", !(U.flag & USER_FILENOUI));
}
+static void open_set_use_scripts(wmOperator *op)
+{
+ if(!RNA_property_is_set(op->ptr, "use_scripts"))
+ RNA_boolean_set(op->ptr, "use_scripts", !(U.flag & USER_SCRIPT_AUTOEXEC_DISABLE));
+}
+
static int wm_open_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
RNA_string_set(op->ptr, "path", G.sce);
open_set_load_ui(op);
+ open_set_use_scripts(op);
WM_event_add_fileselect(C, op);
@@ -1339,11 +1349,17 @@ static int wm_open_mainfile_exec(bContext *C, wmOperator *op)
RNA_string_get(op->ptr, "path", path);
open_set_load_ui(op);
+ open_set_use_scripts(op);
if(RNA_boolean_get(op->ptr, "load_ui"))
G.fileflags &= ~G_FILE_NO_UI;
else
G.fileflags |= G_FILE_NO_UI;
+
+ if(RNA_boolean_get(op->ptr, "use_scripts"))
+ G.f |= G_SCRIPT_AUTOEXEC;
+ else
+ G.f &= ~G_SCRIPT_AUTOEXEC;
// XXX wm in context is not set correctly after WM_read_file -> crash
// do it before for now, but is this correct with multiple windows?
@@ -1367,6 +1383,7 @@ static void WM_OT_open_mainfile(wmOperatorType *ot)
WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_BLENDER, FILE_OPENFILE);
RNA_def_boolean(ot->srna, "load_ui", 1, "Load UI", "Load user interface setup in the .blend file");
+ RNA_def_boolean(ot->srna, "use_scripts", 1, "Trusted Source", "Allow blend file execute scripts automatically, default available from system preferences");
}
/* **************** link/append *************** */
@@ -2997,7 +3014,11 @@ static EnumPropertyItem *rna_id_itemf(bContext *C, PointerRNA *ptr, int *free, I
return item;
}
-/* can add more */
+/* can add more as needed */
+EnumPropertyItem *RNA_action_itemf(bContext *C, PointerRNA *ptr, int *free)
+{
+ return rna_id_itemf(C, ptr, free, C ? (ID *)CTX_data_main(C)->action.first : NULL);
+}
EnumPropertyItem *RNA_group_itemf(bContext *C, PointerRNA *ptr, int *free)
{
return rna_id_itemf(C, ptr, free, C ? (ID *)CTX_data_main(C)->group.first : NULL);