diff options
author | Campbell Barton <ideasman42@gmail.com> | 2011-11-16 07:10:15 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2011-11-16 07:10:15 +0400 |
commit | c00c0134e0f40748885a6bbd5ef8b4ffb7c34f09 (patch) | |
tree | f649494ce560f248505225b3d29972a58b1e91b5 /source | |
parent | e6e265b2b59e02cc7816a2ed43471eca8bca0a62 (diff) | |
parent | 9f46ca46a6fcdacf53d95a61147272352154204b (diff) |
svn merge -r41847:41899 ^/trunk/blender
Diffstat (limited to 'source')
63 files changed, 1151 insertions, 595 deletions
diff --git a/source/blender/blenkernel/BKE_idprop.h b/source/blender/blenkernel/BKE_idprop.h index 10c02f54b2e..fbe5bf2ef44 100644 --- a/source/blender/blenkernel/BKE_idprop.h +++ b/source/blender/blenkernel/BKE_idprop.h @@ -40,7 +40,11 @@ typedef union IDPropertyTemplate { int i; float f; double d; - char *str; + struct { + char *str; + short len; + char subtype; + } string; struct ID *id; struct { short type; @@ -183,7 +187,7 @@ Note that you MUST either attach the id property to an id property group with IDP_AddToGroup or MEM_freeN the property, doing anything else might result in a memory leak. */ -struct IDProperty *IDP_New(int type, IDPropertyTemplate val, const char *name); +struct IDProperty *IDP_New(const int type, const IDPropertyTemplate *val, const char *name); /** \note this will free all child properties of list arrays and groups! Also, note that this does NOT unlink anything! Plus it doesn't free diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h index 77a351d534e..44b92f70519 100644 --- a/source/blender/blenkernel/BKE_screen.h +++ b/source/blender/blenkernel/BKE_screen.h @@ -207,6 +207,7 @@ typedef struct MenuType { char idname[BKE_ST_MAXNAME]; /* unique name */ char label[BKE_ST_MAXNAME]; /* for button text */ + char *description; /* verify if the menu should draw or not */ int (*poll)(const struct bContext *, struct MenuType *); diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 92304278b3f..8c313cc84a1 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -3938,15 +3938,15 @@ static bConstraintTypeInfo CTI_PIVOT = { static void followtrack_new_data (void *cdata) { bFollowTrackConstraint *data= (bFollowTrackConstraint *)cdata; - + data->clip= NULL; - data->flag|= FOLLOWTRACK_ACTIVECLIP; + data->flag |= FOLLOWTRACK_ACTIVECLIP; } static void followtrack_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata) { bFollowTrackConstraint *data= con->data; - + func(con, (ID**)&data->clip, userdata); } @@ -3956,104 +3956,105 @@ static void followtrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase bFollowTrackConstraint *data= con->data; MovieClip *clip= data->clip; MovieTrackingTrack *track; - - if(data->flag&FOLLOWTRACK_ACTIVECLIP) + + if (data->flag & FOLLOWTRACK_ACTIVECLIP) clip= scene->clip; - - if(!clip || !data->track[0]) + + if (!clip || !data->track[0]) return; - + track= BKE_tracking_named_track(&clip->tracking, data->track); - - if(!track) + + if (!track) return; - - if(data->flag&FOLLOWTRACK_USE_3D_POSITION) { - if(track->flag&TRACK_HAS_BUNDLE) { + + if (data->flag & FOLLOWTRACK_USE_3D_POSITION) { + if (track->flag & TRACK_HAS_BUNDLE) { float pos[3], mat[4][4], obmat[4][4]; - + copy_m4_m4(obmat, cob->matrix); - + BKE_get_tracking_mat(cob->scene, NULL, mat); mul_v3_m4v3(pos, mat, track->bundle_pos); - - cob->matrix[3][0]+= pos[0]; - cob->matrix[3][1]+= pos[1]; - cob->matrix[3][2]+= pos[2]; + + cob->matrix[3][0] += pos[0]; + cob->matrix[3][1] += pos[1]; + cob->matrix[3][2] += pos[2]; } - } else { + } + else { Object *camob= cob->scene->camera; - - if(camob) { + + if (camob) { MovieClipUser user; MovieTrackingMarker *marker; float vec[3], disp[3], axis[3], mat[4][4]; float aspect= (scene->r.xsch*scene->r.xasp) / (scene->r.ysch*scene->r.yasp); - float sensor_x, sensor_y, lens, len, d, ortho_scale= 1.f; - + float sensor_x, sensor_y, lens, len, d, ortho_scale= 1.0f; + where_is_object_mat(scene, camob, mat); - + /* camera axis */ - vec[0]= 0.f; - vec[1]= 0.f; - vec[2]= 1.f; + vec[0]= 0.0f; + vec[1]= 0.0f; + vec[2]= 1.0f; mul_v3_m4v3(axis, mat, vec); - + /* distance to projection plane */ copy_v3_v3(vec, cob->matrix[3]); sub_v3_v3(vec, mat[3]); project_v3_v3v3(disp, vec, axis); - + len= len_v3(disp); - - if(len>FLT_EPSILON) { + + if (len > FLT_EPSILON) { float pos[2], rmat[4][4], shiftx= 0.0f, shifty= 0.0f, clipsta= 0.0f, clipend= 0.0f; short is_ortho= 0, sensor_fit= CAMERA_SENSOR_FIT_AUTO; Camera *cam= NULL; - + user.framenr= scene->r.cfra; marker= BKE_tracking_get_marker(track, user.framenr); - + add_v2_v2v2(pos, marker->pos, track->offset); - + object_camera_intrinsics(camob, &cam, &is_ortho, &shiftx, &shifty, &clipsta, &clipend, &lens, &sensor_x, &sensor_y, &sensor_fit); - - if(is_ortho) { - if(cam) + + if (is_ortho) { + if (cam) ortho_scale= cam->ortho_scale; - + vec[0]= ortho_scale * (pos[0]-0.5f+shiftx); vec[1]= ortho_scale * (pos[1]-0.5f+shifty); vec[2]= -len; - - if(aspect>1.f) vec[1]/= aspect; - else vec[0]*= aspect; - + + if (aspect > 1.0f) vec[1] /= aspect; + else vec[0] *= aspect; + mul_v3_m4v3(disp, camob->obmat, vec); - + copy_m4_m4(rmat, camob->obmat); zero_v3(rmat[3]); mul_m4_m4m4(cob->matrix, rmat, cob->matrix); - + copy_v3_v3(cob->matrix[3], disp); } else { - d= (len*sensor_x) / (2.f*lens); - - vec[0]= d*(2.f*(pos[0]+shiftx)-1.f); - vec[1]= d*(2.f*(pos[1]+shifty)-1.f); + d= (len*sensor_x) / (2.0f*lens); + + vec[0]= d*(2.0f*(pos[0]+shiftx)-1.0f); + vec[1]= d*(2.0f*(pos[1]+shifty)-1.0f); vec[2]= -len; - - if(aspect>1.f) vec[1]/= aspect; - else vec[0]*= aspect; - + + if (aspect > 1.0f) vec[1] /= aspect; + else vec[0] *= aspect; + mul_v3_m4v3(disp, camob->obmat, vec); - + /* apply camera rotation so Z-axis would be co-linear */ copy_m4_m4(rmat, camob->obmat); zero_v3(rmat[3]); mul_m4_m4m4(cob->matrix, rmat, cob->matrix); - + copy_v3_v3(cob->matrix[3], disp); } } @@ -4082,15 +4083,15 @@ static bConstraintTypeInfo CTI_FOLLOWTRACK = { static void camerasolver_new_data (void *cdata) { bCameraSolverConstraint *data= (bCameraSolverConstraint *)cdata; - - data->clip= NULL; - data->flag|= CAMERASOLVER_ACTIVECLIP; + + data->clip = NULL; + data->flag |= CAMERASOLVER_ACTIVECLIP; } static void camerasolver_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata) { bCameraSolverConstraint *data= con->data; - + func(con, (ID**)&data->clip, userdata); } @@ -4099,15 +4100,15 @@ static void camerasolver_evaluate (bConstraint *con, bConstraintOb *cob, ListBas Scene *scene= cob->scene; bCameraSolverConstraint *data= con->data; MovieClip *clip= data->clip; - - if(data->flag&CAMERASOLVER_ACTIVECLIP) + + if (data->flag & CAMERASOLVER_ACTIVECLIP) clip= scene->clip; - - if(clip) { + + if (clip) { float mat[4][4], obmat[4][4]; - + BKE_tracking_get_interpolated_camera(&clip->tracking, scene->r.cfra, mat); - + copy_m4_m4(obmat, cob->matrix); mul_m4_m4m4(cob->matrix, mat, obmat); } diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c index ac4b936cb41..a44957ddc01 100644 --- a/source/blender/blenkernel/intern/idprop.c +++ b/source/blender/blenkernel/intern/idprop.c @@ -40,8 +40,6 @@ #include "MEM_guardedalloc.h" -#define BSTR_EQ(a, b) (*(a) == *(b) && !strcmp(a, b)) - /* IDPropertyTemplate is a union in DNA_ID.h */ /*local size table.*/ @@ -193,7 +191,7 @@ static void idp_resize_group_array(IDProperty *prop, int newlen, void *newarr) for(a=prop->len; a<newlen; a++) { val.i = 0; /* silence MSVC warning about uninitialized var when debugging */ - array[a]= IDP_New(IDP_GROUP, val, "IDP_ResizeArray group"); + array[a]= IDP_New(IDP_GROUP, &val, "IDP_ResizeArray group"); } } else { @@ -349,17 +347,20 @@ static IDProperty *IDP_CopyString(IDProperty *prop) void IDP_AssignString(IDProperty *prop, const char *st, int maxlen) { - int stlen; - - stlen = strlen(st); + int stlen = strlen(st); if(maxlen > 0 && maxlen < stlen) stlen= maxlen; - stlen++; /* make room for null byte */ - - IDP_ResizeArray(prop, stlen); - BLI_strncpy(prop->data.pointer, st, stlen); + if (prop->subtype == IDP_STRING_SUB_BYTE) { + IDP_ResizeArray(prop, stlen); + memcpy(prop->data.pointer, st, stlen); + } + else { + stlen++; /* make room for null byte */ + IDP_ResizeArray(prop, stlen); + BLI_strncpy(prop->data.pointer, st, stlen); + } } void IDP_ConcatStringC(IDProperty *prop, const char *st) @@ -461,7 +462,7 @@ void IDP_ReplaceGroupInGroup(IDProperty *dest, IDProperty *src) IDProperty *loop, *prop; for (prop=src->data.group.first; prop; prop=prop->next) { for (loop=dest->data.group.first; loop; loop=loop->next) { - if (BSTR_EQ(loop->name, prop->name)) { + if (strcmp(loop->name, prop->name) == 0) { IDProperty *copy = IDP_CopyProperty(prop); BLI_insertlink(&dest->data.group, loop, copy); @@ -632,7 +633,7 @@ int IDP_EqualsProperties(IDProperty *prop1, IDProperty *prop2) else if(prop1->type == IDP_DOUBLE) return (IDP_Double(prop1) == IDP_Double(prop2)); else if(prop1->type == IDP_STRING) - return BSTR_EQ(IDP_String(prop1), IDP_String(prop2)); + return ((prop1->len == prop2->len) && strncmp(IDP_String(prop1), IDP_String(prop2), prop1->len) == 0); else if(prop1->type == IDP_ARRAY) { if(prop1->len == prop2->len && prop1->subtype == prop2->subtype) return memcmp(IDP_Array(prop1), IDP_Array(prop2), idp_size_table[(int)prop1->subtype]*prop1->len); @@ -670,32 +671,33 @@ int IDP_EqualsProperties(IDProperty *prop1, IDProperty *prop2) return 1; } -IDProperty *IDP_New(int type, IDPropertyTemplate val, const char *name) +/* 'val' is never NULL, dont check */ +IDProperty *IDP_New(const int type, const IDPropertyTemplate *val, const char *name) { IDProperty *prop=NULL; switch (type) { case IDP_INT: prop = MEM_callocN(sizeof(IDProperty), "IDProperty int"); - prop->data.val = val.i; + prop->data.val = val->i; break; case IDP_FLOAT: prop = MEM_callocN(sizeof(IDProperty), "IDProperty float"); - *(float*)&prop->data.val = val.f; + *(float*)&prop->data.val = val->f; break; case IDP_DOUBLE: prop = MEM_callocN(sizeof(IDProperty), "IDProperty float"); - *(double*)&prop->data.val = val.d; + *(double*)&prop->data.val = val->d; break; case IDP_ARRAY: { /*for now, we only support float and int and double arrays*/ - if (val.array.type == IDP_FLOAT || val.array.type == IDP_INT || val.array.type == IDP_DOUBLE || val.array.type == IDP_GROUP) { + if (val->array.type == IDP_FLOAT || val->array.type == IDP_INT || val->array.type == IDP_DOUBLE || val->array.type == IDP_GROUP) { prop = MEM_callocN(sizeof(IDProperty), "IDProperty array"); - prop->subtype = val.array.type; - if (val.array.len) - prop->data.pointer = MEM_callocN(idp_size_table[val.array.type]*val.array.len, "id property array"); - prop->len = prop->totallen = val.array.len; + prop->subtype = val->array.type; + if (val->array.len) + prop->data.pointer = MEM_callocN(idp_size_table[val->array.type]*val->array.len, "id property array"); + prop->len = prop->totallen = val->array.len; break; } else { return NULL; @@ -703,18 +705,36 @@ IDProperty *IDP_New(int type, IDPropertyTemplate val, const char *name) } case IDP_STRING: { - char *st = val.str; + const char *st = val->string.str; prop = MEM_callocN(sizeof(IDProperty), "IDProperty string"); - if (st == NULL) { - prop->data.pointer = MEM_callocN(DEFAULT_ALLOC_FOR_NULL_STRINGS, "id property string 1"); - prop->totallen = DEFAULT_ALLOC_FOR_NULL_STRINGS; - prop->len = 1; /*NULL string, has len of 1 to account for null byte.*/ - } else { - int stlen = strlen(st) + 1; - prop->data.pointer = MEM_mallocN(stlen, "id property string 2"); - prop->len = prop->totallen = stlen; - memcpy(prop->data.pointer, st, stlen); + if (val->string.subtype == IDP_STRING_SUB_BYTE) { + /* note, intentionally not null terminated */ + if (st == NULL) { + prop->data.pointer = MEM_callocN(DEFAULT_ALLOC_FOR_NULL_STRINGS, "id property string 1"); + prop->totallen = DEFAULT_ALLOC_FOR_NULL_STRINGS; + prop->len = 0; + } + else { + prop->data.pointer = MEM_mallocN(val->string.len, "id property string 2"); + prop->len = prop->totallen = val->string.len; + memcpy(prop->data.pointer, st, val->string.len); + } + prop->subtype= IDP_STRING_SUB_BYTE; + } + else { + if (st == NULL) { + prop->data.pointer = MEM_callocN(DEFAULT_ALLOC_FOR_NULL_STRINGS, "id property string 1"); + prop->totallen = DEFAULT_ALLOC_FOR_NULL_STRINGS; + prop->len = 1; /*NULL string, has len of 1 to account for null byte.*/ + } + else { + int stlen = strlen(st) + 1; + prop->data.pointer = MEM_mallocN(stlen, "id property string 3"); + prop->len = prop->totallen = stlen; + memcpy(prop->data.pointer, st, stlen); + } + prop->subtype= IDP_STRING_SUB_UTF8; } break; } diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 5ad7432fa39..c0c19b2604e 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -50,6 +50,7 @@ #include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "DNA_sequence_types.h" +#include "DNA_smoke_types.h" #include "DNA_sound_types.h" #include "DNA_space_types.h" #include "DNA_view3d_types.h" @@ -962,7 +963,6 @@ static ParticleSystem *copy_particlesystem(ParticleSystem *psys) void copy_object_particlesystems(Object *obn, Object *ob) { - ParticleSystemModifierData *psmd; ParticleSystem *psys, *npsys; ModifierData *md; @@ -975,10 +975,28 @@ void copy_object_particlesystems(Object *obn, Object *ob) /* need to update particle modifiers too */ for(md=obn->modifiers.first; md; md=md->next) { if(md->type==eModifierType_ParticleSystem) { - psmd= (ParticleSystemModifierData*)md; + ParticleSystemModifierData *psmd= (ParticleSystemModifierData*)md; if(psmd->psys==psys) psmd->psys= npsys; } + else if(md->type==eModifierType_DynamicPaint) { + DynamicPaintModifierData *pmd= (DynamicPaintModifierData*)md; + if (pmd->brush) { + if(pmd->brush->psys==psys) { + pmd->brush->psys= npsys; + } + } + } + else if (md->type==eModifierType_Smoke) { + SmokeModifierData *smd = (SmokeModifierData*) md; + + if(smd->type==MOD_SMOKE_TYPE_FLOW) { + if (smd->flow) { + if (smd->flow->psys == psys) + smd->flow->psys= npsys; + } + } + } } } } diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 14dfe015894..8b8c974cdc8 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -1163,6 +1163,6 @@ Base *_setlooper_base_step(Scene **sce_iter, Base *base) int scene_use_new_shading_nodes(Scene *scene) { RenderEngineType *type= RE_engines_find(scene->r.engine); - return (type->flag & RE_USE_SHADING_NODES); + return (type && type->flag & RE_USE_SHADING_NODES); } diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index d3d6a658ede..cab621eeff7 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -2368,7 +2368,7 @@ static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, Object *ob, flo /* ---springs */ }/*omit on snap */ }/*loop all bp's*/ -return 0; /*done fine*/ + return 0; /*done fine*/ } static void *exec_softbody_calc_forces(void *data) diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index db4d09e38b3..a67a61c7638 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -252,7 +252,7 @@ void init_tex_mapping(TexMapping *texmap) size_to_mat3(smat, texmap->size); /* rotation */ - /* XXX TexMapping rotation are now in radians. */ + /* TexMapping rotation are now in radians. */ eul_to_mat3(rmat, texmap->rot); /* compose it all */ diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index d582ad7c4d8..59fdf403f0f 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -1874,7 +1874,7 @@ static void calculate_stabdata(MovieTracking *tracking, int framenr, float width mul_v2_fl(loc, stab->locinf); - if(stab->rot_track && stab->rotinf) { + if((stab->flag&TRACKING_STABILIZE_ROTATION) && stab->rot_track && stab->rotinf) { MovieTrackingMarker *marker; float a[2], b[2]; float x0= (float)width/2.0f, y0= (float)height/2.0f; @@ -1916,7 +1916,8 @@ static float stabilization_auto_scale_factor(MovieTracking *tracking, int width, track= tracking->tracks.first; while(track) { - if(track->flag&TRACK_USE_2D_STAB || track==stab->rot_track) { + if(track->flag&TRACK_USE_2D_STAB || + ((stab->flag&TRACKING_STABILIZE_ROTATION) && track==stab->rot_track)) { if(track->markersnr) { sfra= MIN2(sfra, track->markers[0].framenr); efra= MAX2(efra, track->markers[track->markersnr-1].framenr); diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c index 036a52a1235..3af724b4e30 100644 --- a/source/blender/blenkernel/intern/writeffmpeg.c +++ b/source/blender/blenkernel/intern/writeffmpeg.c @@ -1066,13 +1066,13 @@ IDProperty *ffmpeg_property_add(RenderData *rd, const char *type, int opt_index, if (!rd->ffcodecdata.properties) { rd->ffcodecdata.properties - = IDP_New(IDP_GROUP, val, "ffmpeg"); + = IDP_New(IDP_GROUP, &val, "ffmpeg"); } group = IDP_GetPropertyFromGroup(rd->ffcodecdata.properties, type); if (!group) { - group = IDP_New(IDP_GROUP, val, type); + group = IDP_New(IDP_GROUP, &val, type); IDP_AddToGroup(rd->ffcodecdata.properties, group); } @@ -1102,7 +1102,9 @@ IDProperty *ffmpeg_property_add(RenderData *rd, const char *type, int opt_index, idp_type = IDP_FLOAT; break; case FF_OPT_TYPE_STRING: - val.str = (char *)" "; + val.string.str = (char *)" "; + val.string.len = 80; +/* val.str = (char *)" ";*/ idp_type = IDP_STRING; break; case FF_OPT_TYPE_CONST: @@ -1112,7 +1114,7 @@ IDProperty *ffmpeg_property_add(RenderData *rd, const char *type, int opt_index, default: return NULL; } - prop = IDP_New(idp_type, val, name); + prop = IDP_New(idp_type, &val, name); IDP_AddToGroup(group, prop); return prop; } diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c index 2bf7c7c4039..1101a7a246a 100644 --- a/source/blender/blenlib/intern/path_util.c +++ b/source/blender/blenlib/intern/path_util.c @@ -1415,6 +1415,10 @@ int BLI_replace_extension(char *path, size_t maxlen, const char *ext) } } + if (path[a] != '.') { + a= path_len; + } + if(a + ext_len >= maxlen) return 0; diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index a7fb046737d..38b786e306e 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -5468,6 +5468,24 @@ static int point_on_nurb(Nurb *nu, void *point) } } +static Nurb *get_lastsel_nurb(Curve *cu) +{ + ListBase *nubase= curve_editnurbs(cu); + Nurb *nu= nubase->first; + + if(!cu->lastsel) + return NULL; + + while (nu) { + if (point_on_nurb(nu, cu->lastsel)) + return nu; + + nu= nu->next; + } + + return NULL; +} + static void select_nth_bezt(Nurb *nu, BezTriple *bezt, int nth) { int a, start; @@ -5517,21 +5535,11 @@ static void select_nth_bp(Nurb *nu, BPoint *bp, int nth) int CU_select_nth(Object *obedit, int nth) { Curve *cu= (Curve*)obedit->data; - ListBase *nubase= curve_editnurbs(cu); Nurb *nu; - int ok=0; - - /* Search nurb to which selected point belongs to */ - nu= nubase->first; - while (nu) { - if (point_on_nurb(nu, cu->lastsel)) { - ok= 1; - break; - } - nu= nu->next; - } - if (!ok) return 0; + nu= get_lastsel_nurb(cu); + if (!nu) + return 0; if (nu->bezt) { select_nth_bezt(nu, cu->lastsel, nth); @@ -7069,3 +7077,24 @@ void ED_curve_bpcpy(EditNurb *editnurb, BPoint *dst, BPoint *src, int count) memcpy(dst, src, count*sizeof(BPoint)); keyIndex_updateBP(editnurb, src, dst, count); } + +int ED_curve_actSelection(Curve *cu, float center[3]) +{ + Nurb *nu= get_lastsel_nurb(cu); + + if(!nu) + return 0; + + if(nu->bezt) { + BezTriple *bezt= cu->lastsel; + + copy_v3_v3(center, bezt->vec[1]); + } + else { + BPoint *bp= cu->lastsel; + + copy_v3_v3(center, bp->vec); + } + + return 1; +} diff --git a/source/blender/editors/include/ED_curve.h b/source/blender/editors/include/ED_curve.h index 1f9b034b2e5..8f97d1c8602 100644 --- a/source/blender/editors/include/ED_curve.h +++ b/source/blender/editors/include/ED_curve.h @@ -89,6 +89,8 @@ void ED_curve_bpcpy(struct EditNurb *editnurb, struct BPoint *dst, struct BPoint int ED_curve_updateAnimPaths(struct Object *obedit); +int ED_curve_actSelection(struct Curve *cu, float center[3]); + /* debug only */ void printknots(struct Object *obedit); diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index be8bee7452d..b34b56f31ed 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -831,7 +831,7 @@ static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block) if (prop_menu == NULL) { /* annoying, create a property */ IDPropertyTemplate val = {0}; - prop_menu= IDP_New(IDP_GROUP, val, __func__); /* dummy, name is unimportant */ + prop_menu= IDP_New(IDP_GROUP, &val, __func__); /* dummy, name is unimportant */ IDP_AddToGroup(prop_menu, (prop_menu_name= IDP_NewString("", "name", sizeof(mt->idname)))); } diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index ee1f9617813..688e8f95ac7 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -271,7 +271,7 @@ int ui_is_but_utf8(uiBut *but) { if (but->rnaprop) { const int subtype= RNA_property_subtype(but->rnaprop); - return !(ELEM3(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)); + return !(ELEM4(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME, PROP_BYTESTRING)); } else { return !(but->flag & UI_BUT_NO_UTF8); diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index a6f93101fdc..c553c1e35ad 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -677,7 +677,7 @@ PointerRNA uiItemFullO(uiLayout *layout, const char *opname, const char *name, i } else { IDPropertyTemplate val = {0}; - opptr->data= IDP_New(IDP_GROUP, val, "wmOperatorProperties"); + opptr->data= IDP_New(IDP_GROUP, &val, "wmOperatorProperties"); } return *opptr; @@ -1370,7 +1370,7 @@ static void ui_item_menutype_func(bContext *C, uiLayout *layout, void *arg_mt) mt->draw(C, &menu); } -static void ui_item_menu(uiLayout *layout, const char *name, int icon, uiMenuCreateFunc func, void *arg, void *argN) +static void ui_item_menu(uiLayout *layout, const char *name, int icon, uiMenuCreateFunc func, void *arg, void *argN, const char *tip) { uiBlock *block= layout->root->block; uiBut *but; @@ -1393,11 +1393,11 @@ static void ui_item_menu(uiLayout *layout, const char *name, int icon, uiMenuCre w -= 10; if(name[0] && icon) - but= uiDefIconTextMenuBut(block, func, arg, icon, name, 0, 0, w, h, ""); + but= uiDefIconTextMenuBut(block, func, arg, icon, name, 0, 0, w, h, tip); else if(icon) - but= uiDefIconMenuBut(block, func, arg, icon, 0, 0, w, h, ""); + but= uiDefIconMenuBut(block, func, arg, icon, 0, 0, w, h, tip); else - but= uiDefMenuBut(block, func, arg, name, 0, 0, w, h, ""); + but= uiDefMenuBut(block, func, arg, name, 0, 0, w, h, tip); if(argN) { /* ugly .. */ but->poin= (char*)but; @@ -1430,7 +1430,7 @@ void uiItemM(uiLayout *layout, bContext *UNUSED(C), const char *menuname, const if(layout->root->type == UI_LAYOUT_MENU && !icon) icon= ICON_BLANK1; - ui_item_menu(layout, name, icon, ui_item_menutype_func, mt, NULL); + ui_item_menu(layout, name, icon, ui_item_menutype_func, mt, NULL, mt->description); } /* label item */ @@ -1492,11 +1492,11 @@ void uiItemV(uiLayout *layout, const char *name, int icon, int argval) w= ui_text_icon_width(layout, name, icon, 0); if(icon && name[0]) - uiDefIconTextButF(block, BUTM, 0, icon, name, 0, 0, w, UI_UNIT_Y, retvalue, 0.0, 0.0, 0, argval, ""); + uiDefIconTextButF(block, BUT, argval, icon, name, 0, 0, w, UI_UNIT_Y, retvalue, 0.0, 0.0, 0, 0, ""); else if(icon) - uiDefIconButF(block, BUTM, 0, icon, 0, 0, w, UI_UNIT_Y, retvalue, 0.0, 0.0, 0, argval, ""); + uiDefIconButF(block, BUT, argval, icon, 0, 0, w, UI_UNIT_Y, retvalue, 0.0, 0.0, 0, 0, ""); else - uiDefButF(block, BUTM, 0, name, 0, 0, w, UI_UNIT_Y, retvalue, 0.0, 0.0, 0, argval, ""); + uiDefButF(block, BUT, argval, name, 0, 0, w, UI_UNIT_Y, retvalue, 0.0, 0.0, 0, 0, ""); } /* separator item */ @@ -1514,7 +1514,7 @@ void uiItemMenuF(uiLayout *layout, const char *name, int icon, uiMenuCreateFunc if(!func) return; - ui_item_menu(layout, name, icon, func, arg, NULL); + ui_item_menu(layout, name, icon, func, arg, NULL, ""); } typedef struct MenuItemLevel { @@ -1560,7 +1560,7 @@ void uiItemMenuEnumO(uiLayout *layout, const char *opname, const char *propname, BLI_strncpy(lvl->propname, propname, sizeof(lvl->propname)); lvl->opcontext= layout->root->opcontext; - ui_item_menu(layout, name, icon, menu_item_enum_opname_menu, NULL, lvl); + ui_item_menu(layout, name, icon, menu_item_enum_opname_menu, NULL, lvl, ot->description); } static void menu_item_enum_rna_menu(bContext *UNUSED(C), uiLayout *layout, void *arg) @@ -1593,7 +1593,7 @@ void uiItemMenuEnumR(uiLayout *layout, struct PointerRNA *ptr, const char *propn BLI_strncpy(lvl->propname, propname, sizeof(lvl->propname)); lvl->opcontext= layout->root->opcontext; - ui_item_menu(layout, name, icon, menu_item_enum_rna_menu, NULL, lvl); + ui_item_menu(layout, name, icon, menu_item_enum_rna_menu, NULL, lvl, RNA_property_description(prop)); } /**************************** Layout Items ***************************/ @@ -2517,7 +2517,7 @@ static void ui_item_layout(uiItem *item) static void ui_layout_end(uiBlock *block, uiLayout *layout, int *x, int *y) { if(layout->root->handlefunc) - uiBlockSetButmFunc(block, layout->root->handlefunc, layout->root->argv); + uiBlockSetHandleFunc(block, layout->root->handlefunc, layout->root->argv); ui_item_estimate(&layout->item); ui_item_layout(&layout->item); @@ -2747,7 +2747,7 @@ void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op,in { if(!op->properties) { IDPropertyTemplate val = {0}; - op->properties= IDP_New(IDP_GROUP, val, "wmOperatorProperties"); + op->properties= IDP_New(IDP_GROUP, &val, "wmOperatorProperties"); } if(flag & UI_LAYOUT_OP_SHOW_TITLE) { diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 837a9d12af1..513f084b6e8 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -398,7 +398,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) } } - if(but->tip && strlen(but->tip)) { + if(but->tip && but->tip[0] != '\0') { BLI_strncpy(data->lines[data->totline], but->tip, sizeof(data->lines[0])); data->color[data->totline]= 0xFFFFFF; data->totline++; diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index f07dc3b02af..00c59c48c1c 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -889,10 +889,11 @@ void ED_base_object_free_and_unlink(Main *bmain, Scene *scene, Base *base) MEM_freeN(base); } -static int object_delete_exec(bContext *C, wmOperator *UNUSED(op)) +static int object_delete_exec(bContext *C, wmOperator *op) { Main *bmain= CTX_data_main(C); Scene *scene= CTX_data_scene(C); + const short use_global= RNA_boolean_get(op->ptr, "global"); /* int islamp= 0; */ /* UNUSED */ if(CTX_data_edit_object(C)) @@ -907,6 +908,22 @@ static int object_delete_exec(bContext *C, wmOperator *UNUSED(op)) /* remove from current scene only */ ED_base_object_free_and_unlink(bmain, scene, base); + + if (use_global) { + Scene *scene_iter; + Base *base_other; + + for (scene_iter= bmain->scene.first; scene_iter; scene_iter= scene_iter->id.next) { + if (scene_iter != scene && !(scene_iter->id.lib)) { + base_other= object_in_scene(base->object, scene_iter); + if (base_other) { + ED_base_object_free_and_unlink(bmain, scene_iter, base_other); + } + } + } + } + /* end global */ + } CTX_DATA_END; @@ -933,6 +950,8 @@ void OBJECT_OT_delete(wmOperatorType *ot) /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_boolean(ot->srna, "global", 0, "Delete Globally", "Remove object from all scenes"); } /**************************** Copy Utilities ******************************/ diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 4bad1f90326..0c9b7b2cbda 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -339,7 +339,10 @@ void ED_keymap_object(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "OBJECT_OT_move_to_layer", MKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "OBJECT_OT_delete", XKEY, KM_PRESS, 0, 0); + RNA_boolean_set(WM_keymap_add_item(keymap, "OBJECT_OT_delete", XKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "global", TRUE); WM_keymap_add_item(keymap, "OBJECT_OT_delete", DELKEY, KM_PRESS, 0, 0); + RNA_boolean_set(WM_keymap_add_item(keymap, "OBJECT_OT_delete", DELKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "global", TRUE); + WM_keymap_add_menu(keymap, "INFO_MT_add", AKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "OBJECT_OT_duplicates_make_real", AKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0); diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index 316ae756188..c0d4b9106e6 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -5684,7 +5684,7 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op) val.array.len = PROJ_VIEW_DATA_SIZE; val.array.type = IDP_FLOAT; - view_data = IDP_New(IDP_ARRAY, val, PROJ_VIEW_DATA_ID); + view_data = IDP_New(IDP_ARRAY, &val, PROJ_VIEW_DATA_ID); array= (float *)IDP_Array(view_data); memcpy(array, rv3d->winmat, sizeof(rv3d->winmat)); array += sizeof(rv3d->winmat)/sizeof(float); diff --git a/source/blender/editors/space_clip/clip_buttons.c b/source/blender/editors/space_clip/clip_buttons.c index 149aa9106b0..43eb45b17a7 100644 --- a/source/blender/editors/space_clip/clip_buttons.c +++ b/source/blender/editors/space_clip/clip_buttons.c @@ -320,6 +320,7 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P MovieTrackingTrack *track; MovieTrackingMarker *marker; MarkerUpdateCb *cb; + const char *tip; if(!ptr->data) return; @@ -353,7 +354,12 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P if(compact) { block= uiLayoutGetBlock(layout); - bt= uiDefIconButBitI(block, TOGN, MARKER_DISABLED, 0, ICON_RESTRICT_VIEW_OFF, 0, 0, 20, 20, &cb->marker_flag, 0, 0, 1, 0, "Marker is disabled for current frame."); + if(cb->marker_flag&MARKER_DISABLED) + tip= "Marker is disabled at current frame"; + else + tip= "Marker is enabled at current frame"; + + bt= uiDefIconButBitI(block, TOGN, MARKER_DISABLED, 0, ICON_RESTRICT_VIEW_OFF, 0, 0, 20, 20, &cb->marker_flag, 0, 0, 1, 0, tip); uiButSetNFunc(bt, marker_update_cb, cb, NULL); } else { int width, height, step, digits; @@ -394,8 +400,13 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P uiBlockSetHandleFunc(block, marker_block_handler, cb); uiBlockSetNFunc(block, marker_update_cb, cb, NULL); + if(cb->marker_flag&MARKER_DISABLED) + tip= "Marker is disabled at current frame"; + else + tip= "Marker is enabled at current frame"; + uiDefButBitI(block, OPTIONN, MARKER_DISABLED, B_MARKER_FLAG, "Enabled", 10, 190, 145, 19, &cb->marker_flag, - 0, 0, 0, 0, "Marker is disabled for current frame."); + 0, 0, 0, 0, tip); col= uiLayoutColumn(layout, 1); uiLayoutSetActive(col, (cb->marker_flag&MARKER_DISABLED)==0); @@ -405,21 +416,21 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P uiDefBut(block, LABEL, 0, "Position:", 0, 190, 300, 19, NULL, 0, 0, 0, 0, ""); uiDefButF(block, NUM, B_MARKER_POS, "X:", 10, 171, 145, 19, &cb->marker_pos[0], - -10*width, 10.0*width, step, digits, "X-position of marker at frame in screen coordinates."); + -10*width, 10.0*width, step, digits, "X-position of marker at frame in screen coordinates"); uiDefButF(block, NUM, B_MARKER_POS, "Y:", 165, 171, 145, 19, &cb->marker_pos[1], - -10*height, 10.0*height, step, digits, "Y-position of marker at frame in screen coordinates."); + -10*height, 10.0*height, step, digits, "Y-position of marker at frame in screen coordinates"); uiDefBut(block, LABEL, 0, "Offset:", 0, 152, 300, 19, NULL, 0, 0, 0, 0, ""); uiDefButF(block, NUM, B_MARKER_OFFSET, "X:", 10, 133, 145, 19, &cb->track_offset[0], - -10*width, 10.0*width, step, digits, "X-offset to parenting point."); + -10*width, 10.0*width, step, digits, "X-offset to parenting point"); uiDefButF(block, NUM, B_MARKER_OFFSET, "Y:", 165, 133, 145, 19, &cb->track_offset[1], - -10*height, 10.0*height, step, digits, "Y-offset to parenting point."); + -10*height, 10.0*height, step, digits, "Y-offset to parenting point"); uiDefBut(block, LABEL, 0, "Pattern Area:", 0, 114, 300, 19, NULL, 0, 0, 0, 0, ""); uiDefButF(block, NUM, B_MARKER_PAT_DIM, "Width:", 10, 95, 300, 19, &cb->track_pat[0], 3.0f, - 10.0*width, step, digits, "Width of marker's pattern in screen soordinates."); + 10.0*width, step, digits, "Width of marker's pattern in screen coordinates"); uiDefButF(block, NUM, B_MARKER_PAT_DIM, "Height:", 10, 76, 300, 19, &cb->track_pat[1], 3.0f, - 10.0*height, step, digits, "Height of marker's pattern in screen soordinates."); + 10.0*height, step, digits, "Height of marker's pattern in screen coordinates"); uiDefBut(block, LABEL, 0, "Search Area:", 0, 57, 300, 19, NULL, 0, 0, 0, 0, ""); uiDefButF(block, NUM, B_MARKER_SEARCH_POS, "X:", 10, 38, 145, 19, &cb->track_search_pos[0], @@ -427,9 +438,9 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P uiDefButF(block, NUM, B_MARKER_SEARCH_POS, "Y:", 165, 38, 145, 19, &cb->track_search_pos[1], -height, height, step, digits, "X-position of search at frame relative to marker's position"); uiDefButF(block, NUM, B_MARKER_SEARCH_DIM, "Width:", 10, 19, 300, 19, &cb->track_search[0], 3.0f, - 10.0*width, step, digits, "Width of marker's search in screen soordinates."); + 10.0*width, step, digits, "Width of marker's search in screen soordinates"); uiDefButF(block, NUM, B_MARKER_SEARCH_DIM, "Height:", 10, 0, 300, 19, &cb->track_search[1], 3.0f, - 10.0*height, step, digits, "Height of marker's search in screen soordinates."); + 10.0*height, step, digits, "Height of marker's search in screen soordinates"); uiBlockEndAlign(block); } diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c index d713303ca8b..c4a858797e5 100644 --- a/source/blender/editors/space_clip/clip_ops.c +++ b/source/blender/editors/space_clip/clip_ops.c @@ -929,7 +929,7 @@ void CLIP_OT_rebuild_proxy(wmOperatorType *ot) /* identifiers */ ot->name= "Rebuild Proxy and Timecode Indices"; ot->idname= "CLIP_OT_rebuild_proxy"; - ot->description="Rebuild all selected proxies and timecode indeces using the job system"; + ot->description= "Rebuild all selected proxies and timecode indeces in the background"; /* api callbacks */ ot->exec= sequencer_rebuild_proxy_exec; diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index 1b08a9aee4c..7791e9f3e57 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -1653,7 +1653,7 @@ void CLIP_OT_clear_track_path(wmOperatorType *ot) /* identifiers */ ot->name= "Clear Track Path"; - ot->description= "Clear path of selected tracks"; + ot->description= "Clear tracks after/before current position or clear the whole track"; ot->idname= "CLIP_OT_clear_track_path"; /* api callbacks */ @@ -2119,7 +2119,7 @@ void CLIP_OT_set_center_principal(wmOperatorType *ot) { /* identifiers */ ot->name= "Set Principal to Center"; - ot->description= "Set principal point to center of footage"; + ot->description= "Set optical center to center of footage"; ot->idname= "CLIP_OT_set_center_principal"; /* api callbacks */ @@ -2285,7 +2285,7 @@ void CLIP_OT_detect_features(wmOperatorType *ot) /* identifiers */ ot->name= "Detect Features"; - ot->description= "Automatically detect features to track"; + ot->description= "Automatically detect features and place markers to track"; ot->idname= "CLIP_OT_detect_features"; /* api callbacks */ @@ -2910,7 +2910,7 @@ void CLIP_OT_clean_tracks(wmOperatorType *ot) /* identifiers */ ot->name= "Clean Tracks"; - ot->description= "Clean tracks"; + ot->description= "Clean tracks with high error values or few frames"; ot->idname= "CLIP_OT_clean_tracks"; /* api callbacks */ diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c index 6506933df54..9fb880e0bc6 100644 --- a/source/blender/editors/space_graph/graph_select.c +++ b/source/blender/editors/space_graph/graph_select.c @@ -81,8 +81,9 @@ * 0 = deselect * 1 = select * 2 = invert + * - do_channels: whether to affect selection status of channels */ -static void deselect_graph_keys (bAnimContext *ac, short test, short sel) +static void deselect_graph_keys (bAnimContext *ac, short test, short sel, short do_channels) { ListBase anim_data = {NULL, NULL}; bAnimListElem *ale; @@ -121,19 +122,22 @@ static void deselect_graph_keys (bAnimContext *ac, short test, short sel) /* Keyframes First */ ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, sel_cb, NULL); - /* only change selection of channel when the visibility of keyframes doesn't depend on this */ - if ((sipo->flag & SIPO_SELCUVERTSONLY) == 0) { - /* deactivate the F-Curve, and deselect if deselecting keyframes. - * otherwise select the F-Curve too since we've selected all the keyframes - */ - if (sel == SELECT_SUBTRACT) - fcu->flag &= ~FCURVE_SELECTED; - else - fcu->flag |= FCURVE_SELECTED; + /* affect channel selection status? */ + if (do_channels) { + /* only change selection of channel when the visibility of keyframes doesn't depend on this */ + if ((sipo->flag & SIPO_SELCUVERTSONLY) == 0) { + /* deactivate the F-Curve, and deselect if deselecting keyframes. + * otherwise select the F-Curve too since we've selected all the keyframes + */ + if (sel == SELECT_SUBTRACT) + fcu->flag &= ~FCURVE_SELECTED; + else + fcu->flag |= FCURVE_SELECTED; + } + + /* always deactivate all F-Curves if we perform batch ops for selection */ + fcu->flag &= ~FCURVE_ACTIVE; } - - /* always deactivate all F-Curves if we perform batch ops for selection */ - fcu->flag &= ~FCURVE_ACTIVE; } /* Cleanup */ @@ -152,9 +156,9 @@ static int graphkeys_deselectall_exec(bContext *C, wmOperator *op) /* 'standard' behaviour - check if selected, then apply relevant selection */ if (RNA_boolean_get(op->ptr, "invert")) - deselect_graph_keys(&ac, 0, SELECT_INVERT); + deselect_graph_keys(&ac, 0, SELECT_INVERT, TRUE); else - deselect_graph_keys(&ac, 1, SELECT_ADD); + deselect_graph_keys(&ac, 1, SELECT_ADD, TRUE); /* set notifier that things have changed */ WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|NA_SELECTED, NULL); @@ -735,7 +739,7 @@ static void graphkeys_select_leftright (bAnimContext *ac, short leftright, short /* - deselect all other keyframes, so that just the newly selected remain * - channels aren't deselected, since we don't re-select any as a consequence */ - deselect_graph_keys(ac, 0, SELECT_SUBTRACT); + deselect_graph_keys(ac, 0, SELECT_SUBTRACT, FALSE); } /* set callbacks and editing data */ @@ -1106,8 +1110,8 @@ static void mouse_graph_keys (bAnimContext *ac, const int mval[2], short select_ /* reset selection mode */ select_mode= SELECT_ADD; - /* deselect all other keyframes */ - deselect_graph_keys(ac, 0, SELECT_SUBTRACT); + /* deselect all other keyframes (+ F-Curves too) */ + deselect_graph_keys(ac, 0, SELECT_SUBTRACT, TRUE); /* deselect other channels too, but only only do this if * selection of channel when the visibility of keyframes @@ -1217,7 +1221,6 @@ static void graphkeys_mselect_column (bAnimContext *ac, const int mval[2], short bAnimListElem *ale; int filter; - SpaceIpo *sipo= (SpaceIpo *)ac->sl; KeyframeEditFunc select_cb, ok_cb; KeyframeEditData ked; tNearestVertInfo *nvi; @@ -1237,20 +1240,15 @@ static void graphkeys_mselect_column (bAnimContext *ac, const int mval[2], short else if (nvi->fpt) selx= nvi->fpt->vec[0]; - /* if select mode is replace, deselect all keyframes (and channels) first */ + /* if select mode is replace, deselect all keyframes first */ if (select_mode==SELECT_REPLACE) { /* reset selection mode to add to selection */ select_mode= SELECT_ADD; - /* deselect all other keyframes */ - deselect_graph_keys(ac, 0, SELECT_SUBTRACT); - - /* deselect other channels too, but only only do this if - * selection of channel when the visibility of keyframes - * doesn't depend on this + /* - deselect all other keyframes, so that just the newly selected remain + * - channels aren't deselected, since we don't re-select any as a consequence */ - if ((sipo->flag & SIPO_SELCUVERTSONLY) == 0) - ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR); + deselect_graph_keys(ac, 0, SELECT_SUBTRACT, FALSE); } /* initialise keyframe editing data */ diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index a4f67f91763..a7f7e36b182 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -236,6 +236,16 @@ static void unlink_group_cb(bContext *UNUSED(C), Scene *UNUSED(scene), TreeEleme } } +static void unlink_world_cb(bContext *UNUSED(C), Scene *UNUSED(scene), TreeElement *UNUSED(te), TreeStoreElem *tsep, TreeStoreElem *tselem) +{ + Scene *parscene = (Scene *)tsep->id; + World *wo = (World *)tselem->id; + + /* need to use parent scene not just scene, otherwise may end up getting wrong one */ + id_us_min(&wo->id); + parscene->world = NULL; +} + static void outliner_do_libdata_operation(bContext *C, Scene *scene, SpaceOops *soops, ListBase *lb, void (*operation_cb)(bContext *C, Scene *scene, TreeElement *, TreeStoreElem *, TreeStoreElem *)) { @@ -350,6 +360,23 @@ static void singleuser_action_cb(bContext *C, Scene *UNUSED(scene), TreeElement } } +static void singleuser_world_cb(bContext *C, Scene *UNUSED(scene), TreeElement *UNUSED(te), TreeStoreElem *tsep, TreeStoreElem *tselem) +{ + ID *id = tselem->id; + + /* need to use parent scene not just scene, otherwise may end up getting wrong one */ + if (id) { + Scene *parscene = (Scene *)tsep->id; + PointerRNA ptr = {{NULL}}; + PropertyRNA *prop; + + RNA_id_pointer_create(&parscene->id, &ptr); + prop = RNA_struct_find_property(&ptr, "world"); + + id_single_user(C, id, &ptr, prop); + } +} + static void group_linkobs2scene_cb(bContext *UNUSED(C), Scene *scene, TreeElement *UNUSED(te), TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem) { Group *group= (Group *)tselem->id; @@ -746,6 +773,12 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op) WM_event_add_notifier(C, NC_OBJECT|ND_OB_SHADING, NULL); ED_undo_push(C, "Unlink texture"); break; + case ID_WO: + outliner_do_libdata_operation(C, scene, soops, &soops->tree, unlink_world_cb); + + WM_event_add_notifier(C, NC_SCENE|ND_WORLD, NULL); + ED_undo_push(C, "Unlink world"); + break; default: BKE_report(op->reports, RPT_WARNING, "Not Yet"); break; @@ -772,6 +805,13 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op) ED_undo_push(C, "Single-User Action"); break; + case ID_WO: + outliner_do_libdata_operation(C, scene, soops, &soops->tree, singleuser_world_cb); + + WM_event_add_notifier(C, NC_SCENE|ND_WORLD, NULL); + ED_undo_push(C, "Single-User World"); + break; + default: BKE_report(op->reports, RPT_WARNING, "Not Yet"); break; @@ -799,12 +839,13 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op) } break; case OUTLINER_IDOP_RENAME: + { /* rename */ outliner_do_libdata_operation(C, scene, soops, &soops->tree, item_rename_cb); - + WM_event_add_notifier(C, NC_ID|NA_EDITED, NULL); ED_undo_push(C, "Rename"); - + } break; default: diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c index a2c8f971aec..cc85770ac8b 100644 --- a/source/blender/editors/space_view3d/view3d_header.c +++ b/source/blender/editors/space_view3d/view3d_header.c @@ -491,10 +491,9 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C) v3d->modeselect = OB_MODE_OBJECT; } - uiBlockBeginAlign(block); + row= uiLayoutRow(layout, 1); uiDefIconTextButS(block, MENU, B_MODESELECT, object_mode_icon(v3d->modeselect), view3d_modeselect_pup(scene) , 0,0,126 * dpi_fac, UI_UNIT_Y, &(v3d->modeselect), 0, 0, 0, 0, TIP_("Mode")); - uiBlockEndAlign(block); /* Draw type */ uiItemR(layout, &v3dptr, "viewport_shade", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 7d1e9928e78..992fe921dbf 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -97,8 +97,8 @@ #include <stdio.h> -void drawTransformApply(const struct bContext *C, struct ARegion *ar, void *arg); -int doEdgeSlide(TransInfo *t, float perc); +static void drawTransformApply(const struct bContext *C, struct ARegion *ar, void *arg); +static int doEdgeSlide(TransInfo *t, float perc); /* ************************** SPACE DEPENDANT CODE **************************** */ @@ -1788,7 +1788,7 @@ void transformApply(bContext *C, TransInfo *t) t->context = NULL; } -void drawTransformApply(const bContext *C, struct ARegion *UNUSED(ar), void *arg) +static void drawTransformApply(const bContext *C, struct ARegion *UNUSED(ar), void *arg) { TransInfo *t = arg; @@ -4813,7 +4813,7 @@ void initEdgeSlide(TransInfo *t) t->flag |= T_NO_CONSTRAINT|T_NO_PROJECT; } -int doEdgeSlide(TransInfo *t, float perc) +static int doEdgeSlide(TransInfo *t, float perc) { SlideData *sld = t->customData; TransDataSlideVert *svlist = sld->sv, *sv; diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 82b34861b27..d349dfac2fe 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -1550,17 +1550,29 @@ void calculateCenter(TransInfo *t) /* EDIT MODE ACTIVE EDITMODE ELEMENT */ - if (t->obedit && t->obedit->type == OB_MESH) { - BMEditSelection ese; - BMEditMesh *em = ((Mesh*)t->obedit->data)->edit_btmesh; - - if (EDBM_get_actSelection(em, &ese)) { - EDBM_editselection_center(em, t->center, &ese); - calculateCenter2D(t); - break; + if (t->obedit) { + if (t->obedit && t->obedit->type == OB_MESH) { + BMEditSelection ese; + BMEditMesh *em = ((Mesh*)t->obedit->data)->edit_btmesh; + + if (EDBM_get_actSelection(em, &ese)) { + EDBM_editselection_center(em, t->center, &ese); + calculateCenter2D(t); + break; + } + } + else if (ELEM(t->obedit->type, OB_CURVE, OB_SURF)) { + float center[3]; + Curve *cu= (Curve *)t->obedit->data; + + if (ED_curve_actSelection(cu, center)) { + copy_v3_v3(t->center, center); + calculateCenter2D(t); + break; + } } } /* END EDIT MODE ACTIVE ELEMENT */ - + calculateCenterMedian(t); if((t->flag & (T_EDIT|T_POSE))==0) { diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c index 70272c1cea0..07f56d484e7 100644 --- a/source/blender/editors/transform/transform_manipulator.c +++ b/source/blender/editors/transform/transform_manipulator.c @@ -72,6 +72,7 @@ #include "WM_types.h" #include "ED_armature.h" +#include "ED_curve.h" #include "ED_mesh.h" #include "ED_particle.h" #include "ED_view3d.h" @@ -382,56 +383,64 @@ int calc_manipulator_stats(const bContext *C) } else if ELEM(obedit->type, OB_CURVE, OB_SURF) { Curve *cu= obedit->data; - Nurb *nu; - BezTriple *bezt; - BPoint *bp; - ListBase *nurbs= curve_editnurbs(cu); - - nu= nurbs->first; - while(nu) { - if(nu->type == CU_BEZIER) { - bezt= nu->bezt; - a= nu->pntsu; - while(a--) { - /* exceptions - * if handles are hidden then only check the center points. - * If the center knot is selected then only use this as the center point. - */ - if (cu->drawflag & CU_HIDE_HANDLES) { - if (bezt->f2 & SELECT) { - calc_tw_center(scene, bezt->vec[1]); - totsel++; + float center[3]; + + if (v3d->around==V3D_ACTIVE && ED_curve_actSelection(cu, center)) { + calc_tw_center(scene, center); + totsel++; + } + else { + Nurb *nu; + BezTriple *bezt; + BPoint *bp; + ListBase *nurbs= curve_editnurbs(cu); + + nu= nurbs->first; + while(nu) { + if(nu->type == CU_BEZIER) { + bezt= nu->bezt; + a= nu->pntsu; + while(a--) { + /* exceptions + * if handles are hidden then only check the center points. + * If the center knot is selected then only use this as the center point. + */ + if (cu->drawflag & CU_HIDE_HANDLES) { + if (bezt->f2 & SELECT) { + calc_tw_center(scene, bezt->vec[1]); + totsel++; + } } - } - else if (bezt->f2 & SELECT) { - calc_tw_center(scene, bezt->vec[1]); - totsel++; - } - else { - if(bezt->f1) { - calc_tw_center(scene, bezt->vec[0]); + else if (bezt->f2 & SELECT) { + calc_tw_center(scene, bezt->vec[1]); totsel++; } - if(bezt->f3) { - calc_tw_center(scene, bezt->vec[2]); - totsel++; + else { + if(bezt->f1) { + calc_tw_center(scene, bezt->vec[0]); + totsel++; + } + if(bezt->f3) { + calc_tw_center(scene, bezt->vec[2]); + totsel++; + } } + bezt++; } - bezt++; } - } - else { - bp= nu->bp; - a= nu->pntsu*nu->pntsv; - while(a--) { - if(bp->f1 & SELECT) { - calc_tw_center(scene, bp->vec); - totsel++; + else { + bp= nu->bp; + a= nu->pntsu*nu->pntsv; + while(a--) { + if(bp->f1 & SELECT) { + calc_tw_center(scene, bp->vec); + totsel++; + } + bp++; } - bp++; } + nu= nu->next; } - nu= nu->next; } } else if(obedit->type==OB_MBALL) { diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 1e508794045..cf8defe3968 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -92,23 +92,23 @@ /********************* PROTOTYPES ***********************/ -void setSnappingCallback(TransInfo *t); +static void setSnappingCallback(TransInfo *t); -void ApplySnapTranslation(TransInfo *t, float vec[3]); -void ApplySnapRotation(TransInfo *t, float *vec); -void ApplySnapResize(TransInfo *t, float *vec); +static void ApplySnapTranslation(TransInfo *t, float vec[3]); +static void ApplySnapRotation(TransInfo *t, float *vec); +static void ApplySnapResize(TransInfo *t, float *vec); -void CalcSnapGrid(TransInfo *t, float *vec); -void CalcSnapGeometry(TransInfo *t, float *vec); +static void CalcSnapGrid(TransInfo *t, float *vec); +static void CalcSnapGeometry(TransInfo *t, float *vec); -void TargetSnapMedian(TransInfo *t); -void TargetSnapCenter(TransInfo *t); -void TargetSnapClosest(TransInfo *t); -void TargetSnapActive(TransInfo *t); +static void TargetSnapMedian(TransInfo *t); +static void TargetSnapCenter(TransInfo *t); +static void TargetSnapClosest(TransInfo *t); +static void TargetSnapActive(TransInfo *t); -float RotationBetween(TransInfo *t, float p1[3], float p2[3]); -float TranslationBetween(TransInfo *t, float p1[3], float p2[3]); -float ResizeBetween(TransInfo *t, float p1[3], float p2[3]); +static float RotationBetween(TransInfo *t, float p1[3], float p2[3]); +static float TranslationBetween(TransInfo *t, float p1[3], float p2[3]); +static float ResizeBetween(TransInfo *t, float p1[3], float p2[3]); /****************** IMPLEMENTATIONS *********************/ @@ -485,7 +485,7 @@ void initSnapping(TransInfo *t, wmOperator *op) initSnappingMode(t); } -void setSnappingCallback(TransInfo *t) +static void setSnappingCallback(TransInfo *t) { t->tsnap.calcSnap = CalcSnapGeometry; @@ -586,14 +586,14 @@ void getSnapPoint(TransInfo *t, float vec[3]) /********************** APPLY **************************/ -void ApplySnapTranslation(TransInfo *t, float vec[3]) +static void ApplySnapTranslation(TransInfo *t, float vec[3]) { float point[3]; getSnapPoint(t, point); sub_v3_v3v3(vec, point, t->tsnap.snapTarget); } -void ApplySnapRotation(TransInfo *t, float *vec) +static void ApplySnapRotation(TransInfo *t, float *vec) { if (t->tsnap.target == SCE_SNAP_TARGET_CLOSEST) { *vec = t->tsnap.dist; @@ -605,7 +605,7 @@ void ApplySnapRotation(TransInfo *t, float *vec) } } -void ApplySnapResize(TransInfo *t, float vec[3]) +static void ApplySnapResize(TransInfo *t, float vec[3]) { if (t->tsnap.target == SCE_SNAP_TARGET_CLOSEST) { vec[0] = vec[1] = vec[2] = t->tsnap.dist; @@ -619,12 +619,12 @@ void ApplySnapResize(TransInfo *t, float vec[3]) /********************** DISTANCE **************************/ -float TranslationBetween(TransInfo *UNUSED(t), float p1[3], float p2[3]) +static float TranslationBetween(TransInfo *UNUSED(t), float p1[3], float p2[3]) { return len_v3v3(p1, p2); } -float RotationBetween(TransInfo *t, float p1[3], float p2[3]) +static float RotationBetween(TransInfo *t, float p1[3], float p2[3]) { float angle, start[3], end[3], center[3]; @@ -680,7 +680,7 @@ float RotationBetween(TransInfo *t, float p1[3], float p2[3]) return angle; } -float ResizeBetween(TransInfo *t, float p1[3], float p2[3]) +static float ResizeBetween(TransInfo *t, float p1[3], float p2[3]) { float d1[3], d2[3], center[3]; @@ -703,12 +703,12 @@ float ResizeBetween(TransInfo *t, float p1[3], float p2[3]) /********************** CALC **************************/ -void CalcSnapGrid(TransInfo *t, float *UNUSED(vec)) +static void CalcSnapGrid(TransInfo *t, float *UNUSED(vec)) { snapGridAction(t, t->tsnap.snapPoint, BIG_GEARS); } -void CalcSnapGeometry(TransInfo *t, float *UNUSED(vec)) +static void CalcSnapGeometry(TransInfo *t, float *UNUSED(vec)) { if (t->spacetype == SPACE_VIEW3D) { @@ -868,7 +868,7 @@ void CalcSnapGeometry(TransInfo *t, float *UNUSED(vec)) /********************** TARGET **************************/ -void TargetSnapCenter(TransInfo *t) +static void TargetSnapCenter(TransInfo *t) { // Only need to calculate once if ((t->tsnap.status & TARGET_INIT) == 0) @@ -883,7 +883,7 @@ void TargetSnapCenter(TransInfo *t) } } -void TargetSnapActive(TransInfo *t) +static void TargetSnapActive(TransInfo *t) { // Only need to calculate once if ((t->tsnap.status & TARGET_INIT) == 0) @@ -922,7 +922,7 @@ void TargetSnapActive(TransInfo *t) } } -void TargetSnapMedian(TransInfo *t) +static void TargetSnapMedian(TransInfo *t) { // Only need to calculate once if ((t->tsnap.status & TARGET_INIT) == 0) @@ -950,7 +950,7 @@ void TargetSnapMedian(TransInfo *t) } } -void TargetSnapClosest(TransInfo *t) +static void TargetSnapClosest(TransInfo *t) { // Only valid if a snap point has been selected if (t->tsnap.status & POINT_INIT) diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c index 09446fc5eab..9bb4d655a59 100644 --- a/source/blender/editors/uvedit/uvedit_parametrizer.c +++ b/source/blender/editors/uvedit/uvedit_parametrizer.c @@ -546,17 +546,21 @@ static void p_face_flip(PFace *f) PEdge *e1 = f->edge, *e2 = e1->next, *e3 = e2->next; PVert *v1 = e1->vert, *v2 = e2->vert, *v3 = e3->vert; int f1 = e1->flag, f2 = e2->flag, f3 = e3->flag; + float *orig_uv1 = e1->orig_uv, *orig_uv2 = e2->orig_uv, *orig_uv3 = e3->orig_uv; e1->vert = v2; e1->next = e3; + e1->orig_uv = orig_uv2; e1->flag = (f1 & ~PEDGE_VERTEX_FLAGS) | (f2 & PEDGE_VERTEX_FLAGS); e2->vert = v3; e2->next = e1; + e2->orig_uv = orig_uv3; e2->flag = (f2 & ~PEDGE_VERTEX_FLAGS) | (f3 & PEDGE_VERTEX_FLAGS); e3->vert = v1; e3->next = e2; + e3->orig_uv = orig_uv1; e3->flag = (f3 & ~PEDGE_VERTEX_FLAGS) | (f1 & PEDGE_VERTEX_FLAGS); } diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c index fb6c85c2408..3c32332cd8d 100644 --- a/source/blender/imbuf/intern/anim_movie.c +++ b/source/blender/imbuf/intern/anim_movie.c @@ -747,6 +747,8 @@ static int ffmpeg_decode_video_frame(struct anim * anim) anim->next_pts = av_get_pts_from_frame(anim->pFormatCtx, anim->pFrame); + + ffmpeg_postprocess(anim); } av_free_packet(&anim->next_packet); @@ -797,6 +799,8 @@ static int ffmpeg_decode_video_frame(struct anim * anim) == AV_NOPTS_VALUE) ? -1 : (long long int)anim->pFrame->pkt_pts, (long long int)anim->next_pts); + + ffmpeg_postprocess(anim); } } av_free_packet(&anim->next_packet); @@ -808,6 +812,7 @@ static int ffmpeg_decode_video_frame(struct anim * anim) AV_LOG_ERROR, " DECODE READ FAILED: av_read_frame() " "returned error: %d\n", rval); } + return (rval >= 0); } @@ -947,6 +952,7 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position, } IMB_freeImBuf(anim->last_frame); + anim->last_frame = IMB_allocImBuf(anim->x, anim->y, 32, IB_rect); if (anim->next_pts <= pts_to_search && anim->next_undecoded_pts > pts_to_search) { @@ -1050,10 +1056,6 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position, ffmpeg_decode_video_frame(anim); } - anim->last_frame = IMB_allocImBuf(anim->x, anim->y, 32, IB_rect); - - ffmpeg_postprocess(anim); - anim->last_pts = anim->next_pts; ffmpeg_decode_video_frame(anim); diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index c135254b11b..97ea7592d04 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -80,6 +80,13 @@ typedef struct IDProperty { #define IDP_IDPARRAY 9 #define IDP_NUMTYPES 10 +/*->subtype */ + +/* IDP_STRING */ +#define IDP_STRING_SUB_UTF8 0 /* default */ +#define IDP_STRING_SUB_BYTE 1 /* arbitrary byte array, _not_ null terminated */ + + /* add any future new id property types here.*/ /* watch it: Sequence has identical beginning. */ diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 30c22864db1..c2dfcd1d441 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -755,7 +755,7 @@ typedef struct ScrewModifierData { // #define MOD_SCREW_OBJECT_ANGLE (1<<4) typedef struct OceanModifierData { - ModifierData modifier; + ModifierData modifier; struct Ocean *ocean; struct OceanCache *oceancache; @@ -777,25 +777,27 @@ typedef struct OceanModifierData { float foam_coverage; float time; - int seed; - int flag; - int output; - - int refresh; - int bakestart; int bakeend; char cachepath[240]; // FILE_MAX - int cached; - - int geometry_mode; + char cached; + char geometry_mode; + + char flag; + char refresh; + + short repeat_x; + short repeat_y; + + int seed; + float size; - int repeat_x; - int repeat_y; float foam_fade; - + + int pad; + } OceanModifierData; #define MOD_OCEAN_GEOM_GENERATE 0 diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h index f4736add66c..11a6460b1fc 100644 --- a/source/blender/makesdna/DNA_particle_types.h +++ b/source/blender/makesdna/DNA_particle_types.h @@ -233,7 +233,10 @@ typedef struct ParticleSettings { struct PartDeflect *pd2; } ParticleSettings; -typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in copy_particlesystem */ +typedef struct ParticleSystem +{ /* note1: make sure all (runtime) are NULL's in 'copy_particlesystem' XXX, this function is no more! - need to invstigate */ + /* note2: make sure any uses of this struct in DNA are accounted for in 'copy_object_particlesystems' */ + struct ParticleSystem *next, *prev; ParticleSettings *part; /* particle settings */ diff --git a/source/blender/makesdna/DNA_tracking_types.h b/source/blender/makesdna/DNA_tracking_types.h index e1aff048626..cbac3721ac3 100644 --- a/source/blender/makesdna/DNA_tracking_types.h +++ b/source/blender/makesdna/DNA_tracking_types.h @@ -217,6 +217,7 @@ enum { /* MovieTrackingStrabilization->flag */ #define TRACKING_2D_STABILIZATION (1<<0) #define TRACKING_AUTOSCALE (1<<1) +#define TRACKING_STABILIZE_ROTATION (1<<2) /* MovieTrackingReconstruction->flag */ #define TRACKING_RECONSTRUCTED (1<<0) diff --git a/source/blender/makesrna/RNA_define.h b/source/blender/makesrna/RNA_define.h index 6dc7bf2abe3..b7ac5f394b0 100644 --- a/source/blender/makesrna/RNA_define.h +++ b/source/blender/makesrna/RNA_define.h @@ -208,6 +208,9 @@ const char *RNA_property_typename(PropertyType type); #define IS_DNATYPE_FLOAT_COMPAT(_str) (strcmp(_str, "float") == 0 || strcmp(_str, "double") == 0) #define IS_DNATYPE_INT_COMPAT(_str) (strcmp(_str, "int") == 0 || strcmp(_str, "short") == 0 || strcmp(_str, "char") == 0) +/* max size for dynamic defined type descriptors, + * this value is arbitrary */ +#define RNA_DYN_DESCR_MAX 240 #ifdef __cplusplus } diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h index 1655665efe3..e768594fe73 100644 --- a/source/blender/makesrna/RNA_types.h +++ b/source/blender/makesrna/RNA_types.h @@ -108,7 +108,9 @@ typedef enum PropertySubType { PROP_FILEPATH = 1, PROP_DIRPATH = 2, PROP_FILENAME = 3, - PROP_TRANSLATE = 4, /* a string which should be translated */ + PROP_BYTESTRING = 4, /* a string which should be represented as bytes + * in python, still NULL terminated though. */ + PROP_TRANSLATE = 5, /* a string which should be translated */ /* numbers */ PROP_UNSIGNED = 13, diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index 1eaeaf8278f..6dbf7b9c553 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -524,7 +524,11 @@ static char *rna_def_property_get_func(FILE *f, StructRNA *srna, PropertyRNA *pr } else { const PropertySubType subtype= prop->subtype; - const char *string_copy_func= (subtype==PROP_FILEPATH || subtype==PROP_DIRPATH || subtype==PROP_FILENAME) ? "BLI_strncpy" : "BLI_strncpy_utf8"; + const char *string_copy_func= (subtype==PROP_FILEPATH || + subtype==PROP_DIRPATH || + subtype==PROP_FILENAME || + subtype==PROP_BYTESTRING) ? + "BLI_strncpy" : "BLI_strncpy_utf8"; rna_print_data_get(f, dp); if(sprop->maxlength) @@ -739,7 +743,11 @@ static char *rna_def_property_set_func(FILE *f, StructRNA *srna, PropertyRNA *pr } else { const PropertySubType subtype= prop->subtype; - const char *string_copy_func= (subtype==PROP_FILEPATH || subtype==PROP_DIRPATH || subtype==PROP_FILENAME) ? "BLI_strncpy" : "BLI_strncpy_utf8"; + const char *string_copy_func= (subtype==PROP_FILEPATH || + subtype==PROP_DIRPATH || + subtype==PROP_FILENAME || + subtype==PROP_BYTESTRING) ? + "BLI_strncpy" : "BLI_strncpy_utf8"; rna_print_data_get(f, dp); if(sprop->maxlength) @@ -1816,6 +1824,7 @@ static const char *rna_property_subtypename(PropertySubType type) case PROP_FILEPATH: return "PROP_FILEPATH"; case PROP_FILENAME: return "PROP_FILENAME"; case PROP_DIRPATH: return "PROP_DIRPATH"; + case PROP_BYTESTRING: return "PROP_BYTESTRING"; case PROP_TRANSLATE: return "PROP_TRANSLATE"; case PROP_UNSIGNED: return "PROP_UNSIGNED"; case PROP_PERCENTAGE: return "PROP_PERCENTAGE"; @@ -2472,7 +2481,7 @@ static RNAProcessItem PROCESS_ITEMS[]= { {"rna_space.c", NULL, RNA_def_space}, {"rna_speaker.c", NULL, RNA_def_speaker}, {"rna_test.c", NULL, RNA_def_test}, - {"rna_text.c", NULL, RNA_def_text}, + {"rna_text.c", "rna_text_api.c", RNA_def_text}, {"rna_timeline.c", NULL, RNA_def_timeline_marker}, {"rna_sound.c", NULL, RNA_def_sound}, {"rna_ui.c", "rna_ui_api.c", RNA_def_ui}, diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 6f9c7a8f19b..d3666e28338 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -1617,7 +1617,7 @@ void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, int value) group= RNA_struct_idprops(ptr, 1); if(group) - IDP_AddToGroup(group, IDP_New(IDP_INT, val, prop->identifier)); + IDP_AddToGroup(group, IDP_New(IDP_INT, &val, prop->identifier)); } } @@ -1696,7 +1696,7 @@ void RNA_property_boolean_set_array(PointerRNA *ptr, PropertyRNA *prop, const in group= RNA_struct_idprops(ptr, 1); if(group) { - idprop= IDP_New(IDP_ARRAY, val, prop->identifier); + idprop= IDP_New(IDP_ARRAY, &val, prop->identifier); IDP_AddToGroup(group, idprop); memcpy(IDP_Array(idprop), values, sizeof(int)*idprop->len); } @@ -1814,7 +1814,7 @@ void RNA_property_int_set(PointerRNA *ptr, PropertyRNA *prop, int value) group= RNA_struct_idprops(ptr, 1); if(group) - IDP_AddToGroup(group, IDP_New(IDP_INT, val, prop->identifier)); + IDP_AddToGroup(group, IDP_New(IDP_INT, &val, prop->identifier)); } } @@ -1930,7 +1930,7 @@ void RNA_property_int_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *v group= RNA_struct_idprops(ptr, 1); if(group) { - idprop= IDP_New(IDP_ARRAY, val, prop->identifier); + idprop= IDP_New(IDP_ARRAY, &val, prop->identifier); IDP_AddToGroup(group, idprop); memcpy(IDP_Array(idprop), values, sizeof(int)*idprop->len); } @@ -2050,7 +2050,7 @@ void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value) group= RNA_struct_idprops(ptr, 1); if(group) - IDP_AddToGroup(group, IDP_New(IDP_FLOAT, val, prop->identifier)); + IDP_AddToGroup(group, IDP_New(IDP_FLOAT, &val, prop->identifier)); } } @@ -2184,7 +2184,7 @@ void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const floa group= RNA_struct_idprops(ptr, 1); if(group) { - idprop= IDP_New(IDP_ARRAY, val, prop->identifier); + idprop= IDP_New(IDP_ARRAY, &val, prop->identifier); IDP_AddToGroup(group, idprop); memcpy(IDP_Array(idprop), values, sizeof(float)*idprop->len); } @@ -2271,12 +2271,23 @@ void RNA_property_string_get(PointerRNA *ptr, PropertyRNA *prop, char *value) BLI_assert(RNA_property_type(prop) == PROP_STRING); - if((idprop=rna_idproperty_check(&prop, ptr))) - strcpy(value, IDP_String(idprop)); - else if(sprop->get) + if((idprop=rna_idproperty_check(&prop, ptr))) { + /* editing bytes is not 100% supported + * since they can contain NIL chars */ + if (idprop->subtype == IDP_STRING_SUB_BYTE) { + memcpy(value, IDP_String(idprop), idprop->len); + value[idprop->len]= '\0'; + } + else { + memcpy(value, IDP_String(idprop), idprop->len); + } + } + else if(sprop->get) { sprop->get(ptr, value); - else + } + else { strcpy(value, sprop->defaultvalue); + } } char *RNA_property_string_get_alloc(PointerRNA *ptr, PropertyRNA *prop, @@ -2320,8 +2331,18 @@ int RNA_property_string_length(PointerRNA *ptr, PropertyRNA *prop) BLI_assert(RNA_property_type(prop) == PROP_STRING); - if((idprop=rna_idproperty_check(&prop, ptr))) - return strlen(IDP_String(idprop)); + if((idprop=rna_idproperty_check(&prop, ptr))) { + if (idprop->subtype == IDP_STRING_SUB_BYTE) { + return idprop->len; + } + else { +#ifndef NDEBUG + /* these _must_ stay in sync */ + BLI_assert(strlen(IDP_String(idprop)) == idprop->len - 1); +#endif + return idprop->len - 1; + } + } else if(sprop->length) return sprop->length(ptr); else @@ -2336,6 +2357,7 @@ void RNA_property_string_set(PointerRNA *ptr, PropertyRNA *prop, const char *val BLI_assert(RNA_property_type(prop) == PROP_STRING); if((idprop=rna_idproperty_check(&prop, ptr))) + /* both IDP_STRING_SUB_BYTE / IDP_STRING_SUB_UTF8 */ IDP_AssignString(idprop, value, RNA_property_string_maxlength(prop) - 1); else if(sprop->set) sprop->set(ptr, value); /* set function needs to clamp its self */ @@ -2421,7 +2443,7 @@ void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value) group= RNA_struct_idprops(ptr, 1); if(group) - IDP_AddToGroup(group, IDP_New(IDP_INT, val, prop->identifier)); + IDP_AddToGroup(group, IDP_New(IDP_INT, &val, prop->identifier)); } } @@ -2517,7 +2539,7 @@ void RNA_property_pointer_add(PointerRNA *ptr, PropertyRNA *prop) group= RNA_struct_idprops(ptr, 1); if(group) - IDP_AddToGroup(group, IDP_New(IDP_GROUP, val, prop->identifier)); + IDP_AddToGroup(group, IDP_New(IDP_GROUP, &val, prop->identifier)); } else printf("%s %s.%s: only supported for id properties.\n", __func__, ptr->type->identifier, prop->identifier); @@ -2640,7 +2662,7 @@ void RNA_property_collection_add(PointerRNA *ptr, PropertyRNA *prop, PointerRNA IDPropertyTemplate val = {0}; IDProperty *item; - item= IDP_New(IDP_GROUP, val, ""); + item= IDP_New(IDP_GROUP, &val, ""); IDP_AppendArray(idprop, item); // IDP_FreeProperty(item); // IDP_AppendArray does a shallow copy (memcpy), only free memory MEM_freeN(item); @@ -2654,7 +2676,7 @@ void RNA_property_collection_add(PointerRNA *ptr, PropertyRNA *prop, PointerRNA idprop= IDP_NewIDPArray(prop->identifier); IDP_AddToGroup(group, idprop); - item= IDP_New(IDP_GROUP, val, ""); + item= IDP_New(IDP_GROUP, &val, ""); IDP_AppendArray(idprop, item); // IDP_FreeProperty(item); // IDP_AppendArray does a shallow copy (memcpy), only free memory MEM_freeN(item); diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c index 1ea1a4e3e7b..6785f1f4caf 100644 --- a/source/blender/makesrna/intern/rna_armature.c +++ b/source/blender/makesrna/intern/rna_armature.c @@ -169,7 +169,7 @@ static IDProperty *rna_Bone_idprops(PointerRNA *ptr, int create) if(create && !bone->prop) { IDPropertyTemplate val = {0}; - bone->prop= IDP_New(IDP_GROUP, val, "RNA_Bone ID properties"); + bone->prop= IDP_New(IDP_GROUP, &val, "RNA_Bone ID properties"); } return bone->prop; @@ -181,7 +181,7 @@ static IDProperty *rna_EditBone_idprops(PointerRNA *ptr, int create) if(create && !ebone->prop) { IDPropertyTemplate val = {0}; - ebone->prop= IDP_New(IDP_GROUP, val, "RNA_EditBone ID properties"); + ebone->prop= IDP_New(IDP_GROUP, &val, "RNA_EditBone ID properties"); } return ebone->prop; diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 6788fd96595..531508b2d18 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -1106,6 +1106,45 @@ static CustomDataLayer *rna_Mesh_vertex_color_new(struct Mesh *me, struct bConte return cdl; } +static CustomDataLayer *rna_Mesh_int_property_new(struct Mesh *me, struct bContext *C, const char *name) +{ + CustomDataLayer *cdl = NULL; + int index; + + CustomData_add_layer_named(&me->fdata, CD_PROP_INT, CD_DEFAULT, NULL, me->totface, name); + index = CustomData_get_named_layer_index(&me->fdata, CD_PROP_INT, name); + + cdl = (index == -1) ? NULL : &(me->fdata.layers[index]); + + return cdl; +} + +static CustomDataLayer *rna_Mesh_float_property_new(struct Mesh *me, struct bContext *C, const char *name) +{ + CustomDataLayer *cdl = NULL; + int index; + + CustomData_add_layer_named(&me->fdata, CD_PROP_FLT, CD_DEFAULT, NULL, me->totface, name); + index = CustomData_get_named_layer_index(&me->fdata, CD_PROP_FLT, name); + + cdl = (index == -1) ? NULL : &(me->fdata.layers[index]); + + return cdl; +} + +static CustomDataLayer *rna_Mesh_string_property_new(struct Mesh *me, struct bContext *C, const char *name) +{ + CustomDataLayer *cdl = NULL; + int index; + + CustomData_add_layer_named(&me->fdata, CD_PROP_STR, CD_DEFAULT, NULL, me->totface, name); + index = CustomData_get_named_layer_index(&me->fdata, CD_PROP_STR, name); + + cdl = (index == -1) ? NULL : &(me->fdata.layers[index]); + + return cdl; +} + static CustomDataLayer *rna_Mesh_uv_texture_new(struct Mesh *me, struct bContext *C, const char *name) { CustomData *pdata; @@ -1628,7 +1667,8 @@ static void rna_def_mproperties(BlenderRNA *brna) RNA_def_struct_ui_text(srna, "Mesh String Property", "User defined string text value in a string properties layer"); RNA_def_struct_path_func(srna, "rna_MeshStringProperty_path"); - prop= RNA_def_property(srna, "value", PROP_STRING, PROP_NONE); + /* low level mesh data access, treat as bytes */ + prop= RNA_def_property(srna, "value", PROP_STRING, PROP_BYTESTRING); RNA_def_property_string_sdna(prop, NULL, "s"); RNA_def_property_ui_text(prop, "Value", ""); RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); @@ -1828,6 +1868,69 @@ static void rna_def_vertex_colors(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); } +/* mesh int layers */ +static void rna_def_int_layers(BlenderRNA *brna, PropertyRNA *cprop) +{ + StructRNA *srna; + + FunctionRNA *func; + PropertyRNA *parm; + + RNA_def_property_srna(cprop, "IntProperties"); + srna= RNA_def_struct(brna, "IntProperties", NULL); + RNA_def_struct_sdna(srna, "Mesh"); + RNA_def_struct_ui_text(srna, "Int Properties", "Collection of int properties"); + + func= RNA_def_function(srna, "new", "rna_Mesh_int_property_new"); + RNA_def_function_flag(func, FUNC_USE_CONTEXT); + RNA_def_function_ui_description(func, "Add a integer property layer to Mesh"); + RNA_def_string(func, "name", "Int Prop", 0, "", "Int property name"); + parm= RNA_def_pointer(func, "layer", "MeshIntPropertyLayer", "", "The newly created layer"); + RNA_def_function_return(func, parm); +} + +/* mesh float layers */ +static void rna_def_float_layers(BlenderRNA *brna, PropertyRNA *cprop) +{ + StructRNA *srna; + + FunctionRNA *func; + PropertyRNA *parm; + + RNA_def_property_srna(cprop, "FloatProperties"); + srna= RNA_def_struct(brna, "FloatProperties", NULL); + RNA_def_struct_sdna(srna, "Mesh"); + RNA_def_struct_ui_text(srna, "Float Properties", "Collection of float properties"); + + func= RNA_def_function(srna, "new", "rna_Mesh_float_property_new"); + RNA_def_function_flag(func, FUNC_USE_CONTEXT); + RNA_def_function_ui_description(func, "Add a float property layer to Mesh"); + RNA_def_string(func, "name", "Float Prop", 0, "", "Float property name"); + parm= RNA_def_pointer(func, "layer", "MeshFloatPropertyLayer", "", "The newly created layer"); + RNA_def_function_return(func, parm); +} + +/* mesh string layers */ +static void rna_def_string_layers(BlenderRNA *brna, PropertyRNA *cprop) +{ + StructRNA *srna; + + FunctionRNA *func; + PropertyRNA *parm; + + RNA_def_property_srna(cprop, "StringProperties"); + srna= RNA_def_struct(brna, "StringProperties", NULL); + RNA_def_struct_sdna(srna, "Mesh"); + RNA_def_struct_ui_text(srna, "String Properties", "Collection of string properties"); + + func= RNA_def_function(srna, "new", "rna_Mesh_string_property_new"); + RNA_def_function_flag(func, FUNC_USE_CONTEXT); + RNA_def_function_ui_description(func, "Add a string property layer to Mesh"); + RNA_def_string(func, "name", "String Prop", 0, "", "String property name"); + parm= RNA_def_pointer(func, "layer", "MeshStringPropertyLayer", "", "The newly created layer"); + RNA_def_function_return(func, parm); +} + /* mesh.uv_layers */ static void rna_def_uv_textures(BlenderRNA *brna, PropertyRNA *cprop) { @@ -1964,6 +2067,7 @@ static void rna_def_mesh(BlenderRNA *brna) "rna_Mesh_float_layers_length", NULL, NULL, NULL); RNA_def_property_struct_type(prop, "MeshFloatPropertyLayer"); RNA_def_property_ui_text(prop, "Float Property Layers", ""); + rna_def_float_layers(brna, prop); prop= RNA_def_property(srna, "layers_int", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "pdata.layers", "pdata.totlayer"); @@ -1971,6 +2075,7 @@ static void rna_def_mesh(BlenderRNA *brna) "rna_Mesh_int_layers_length", NULL, NULL, NULL); RNA_def_property_struct_type(prop, "MeshIntPropertyLayer"); RNA_def_property_ui_text(prop, "Int Property Layers", ""); + rna_def_int_layers(brna, prop); prop= RNA_def_property(srna, "layers_string", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "pdata.layers", "pdata.totlayer"); @@ -1978,6 +2083,7 @@ static void rna_def_mesh(BlenderRNA *brna) "rna_Mesh_string_layers_length", NULL, NULL, NULL); RNA_def_property_struct_type(prop, "MeshStringPropertyLayer"); RNA_def_property_ui_text(prop, "String Property Layers", ""); + rna_def_string_layers(brna, prop); prop= RNA_def_property(srna, "use_auto_smooth", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_AUTOSMOOTH); diff --git a/source/blender/makesrna/intern/rna_movieclip.c b/source/blender/makesrna/intern/rna_movieclip.c index 91e082cdeae..3b1ac8f22c3 100644 --- a/source/blender/makesrna/intern/rna_movieclip.c +++ b/source/blender/makesrna/intern/rna_movieclip.c @@ -87,19 +87,19 @@ static void rna_def_movieclip_proxy(BlenderRNA *brna) /* build proxy sized */ prop= RNA_def_property(srna, "build_25", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "build_size_flag", IMB_PROXY_25); - RNA_def_property_ui_text(prop, "25%", "Build 25% proxy resolution"); + RNA_def_property_ui_text(prop, "25%", "Build proxy resolution 25% of the original footage dimension"); prop= RNA_def_property(srna, "build_50", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "build_size_flag", IMB_PROXY_50); - RNA_def_property_ui_text(prop, "50%", "Build 50% proxy resolution"); + RNA_def_property_ui_text(prop, "50%", "Build proxy resolution 50% of the original footage dimension"); prop= RNA_def_property(srna, "build_75", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "build_size_flag", IMB_PROXY_75); - RNA_def_property_ui_text(prop, "75%", "Build 75% proxy resolution"); + RNA_def_property_ui_text(prop, "75%", "Build proxy resolution 75% of the original footage dimension"); prop= RNA_def_property(srna, "build_100", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "build_size_flag", IMB_PROXY_100); - RNA_def_property_ui_text(prop, "100%", "Build 100% proxy resolution"); + RNA_def_property_ui_text(prop, "100%", "Build proxy resolution 100% of the original footage dimension"); prop= RNA_def_property(srna, "build_undistorted", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "build_flag", MCLIP_PROXY_BUILD_UNDISTORT); @@ -121,7 +121,7 @@ static void rna_def_movieclip_proxy(BlenderRNA *brna) /* quality of proxied image */ prop= RNA_def_property(srna, "quality", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "quality"); - RNA_def_property_ui_text(prop, "Quality", "JPEG Quality of proxies to build"); + RNA_def_property_ui_text(prop, "Quality", "JPEG quality of proxy images"); RNA_def_property_ui_range(prop, 1, 100, 1, 0); prop= RNA_def_property(srna, "timecode", PROP_ENUM, PROP_NONE); @@ -169,7 +169,7 @@ static void rna_def_moviecliUser(BlenderRNA *brna) /* render undistorted */ prop= RNA_def_property(srna, "use_render_undistorted", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "render_flag", MCLIP_PROXY_RENDER_UNDISTORT); - RNA_def_property_ui_text(prop, "Render Undistorted", "Draw preview using undistorted proxy"); + RNA_def_property_ui_text(prop, "Render Undistorted", "Render preview using undistorted proxy"); RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); } @@ -198,7 +198,7 @@ static void rna_def_movieclip(BlenderRNA *brna) prop= RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH); RNA_def_property_string_sdna(prop, NULL, "name"); - RNA_def_property_ui_text(prop, "File Path", "Filename of the text file"); + RNA_def_property_ui_text(prop, "File Path", "Filename of the movie or sequence file"); RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_MovieClip_reload_update"); prop= RNA_def_property(srna, "tracking", PROP_POINTER, PROP_NONE); @@ -234,7 +234,7 @@ static void rna_def_movieclip(BlenderRNA *brna) /* custom proxy directory */ prop= RNA_def_property(srna, "use_proxy_custom_directory", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", MCLIP_USE_PROXY_CUSTOM_DIR); - RNA_def_property_ui_text(prop, "Proxy Custom Directory", "Use a custom directory to store data"); + RNA_def_property_ui_text(prop, "Proxy Custom Directory", "Create proxy images in a custom directory (default is movie location)"); RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_MovieClip_reload_update"); /* grease pencil */ diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c index d224bd0d4e5..6290c01f992 100644 --- a/source/blender/makesrna/intern/rna_pose.c +++ b/source/blender/makesrna/intern/rna_pose.c @@ -157,7 +157,7 @@ static IDProperty *rna_PoseBone_idprops(PointerRNA *ptr, int create) if(create && !pchan->prop) { IDPropertyTemplate val = {0}; - pchan->prop= IDP_New(IDP_GROUP, val, "RNA_PoseBone group"); + pchan->prop= IDP_New(IDP_GROUP, &val, "RNA_PoseBone group"); } return pchan->prop; diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index d2505fc9775..8fb232332d5 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -1593,12 +1593,12 @@ static void rna_def_space_view3d(BlenderRNA *brna) prop= RNA_def_property(srna, "show_camera_path", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag2", V3D_SHOW_CAMERAPATH); - RNA_def_property_ui_text(prop, "Show Camera Path", "Show reconstructed path of camera"); + RNA_def_property_ui_text(prop, "Show Camera Path", "Show reconstructed camera path"); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); prop= RNA_def_property(srna, "show_tracks_name", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag2", V3D_SHOW_BUNDLENAME); - RNA_def_property_ui_text(prop, "Show Tracks Name", "Show names for tracks objects"); + RNA_def_property_ui_text(prop, "Show Track Names", "Show names for tracks objects"); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); /* region */ @@ -2893,7 +2893,7 @@ static void rna_def_space_clip(BlenderRNA *brna) /* show tiny markers */ prop= RNA_def_property(srna, "show_tiny_markers", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_ui_text(prop, "Show Tiny Markers", "Show markers tiny"); + RNA_def_property_ui_text(prop, "Show Tiny Markers", "Show markers in a more compact manner"); RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_TINY_MARKER); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL); @@ -2960,13 +2960,13 @@ static void rna_def_space_clip(BlenderRNA *brna) /* show graph_frames */ prop= RNA_def_property(srna, "show_graph_frames", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_GRAPH_FRAMES); - RNA_def_property_ui_text(prop, "Show Frames", "Show curves for frames in graph editor"); + RNA_def_property_ui_text(prop, "Show Frames", "Show curve for per-frame average error (camera motion should be solved first)"); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL); /* show graph_tracks */ prop= RNA_def_property(srna, "show_graph_tracks", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_GRAPH_TRACKS); - RNA_def_property_ui_text(prop, "Show Tracks", "Show curves for tracks in graph editor"); + RNA_def_property_ui_text(prop, "Show Tracks", "Display the speed curves (in \"x\" direction red, in \"y\" direction green) for the selected tracks"); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL); } diff --git a/source/blender/makesrna/intern/rna_text.c b/source/blender/makesrna/intern/rna_text.c index a0d0bc088f7..9e3611b4cc5 100644 --- a/source/blender/makesrna/intern/rna_text.c +++ b/source/blender/makesrna/intern/rna_text.c @@ -42,7 +42,7 @@ #ifdef RNA_RUNTIME -int text_file_modified(Text *text); +int text_file_modified(Text *text); /* XXX bad level call */ static void rna_Text_filename_get(PointerRNA *ptr, char *value) { diff --git a/source/blender/makesrna/intern/rna_text_api.c b/source/blender/makesrna/intern/rna_text_api.c index ec669b28918..acfcad80f19 100644 --- a/source/blender/makesrna/intern/rna_text_api.c +++ b/source/blender/makesrna/intern/rna_text_api.c @@ -28,11 +28,25 @@ #include <stdlib.h> #include <stdio.h> - #include "RNA_define.h" #ifdef RNA_RUNTIME +#include "WM_api.h" +#include "WM_types.h" + +static void rna_Text_clear(Text *text) +{ + clear_text(text); + WM_main_add_notifier(NC_TEXT|NA_EDITED, text); +} + +static void rna_Text_write(Text *text, const char *str) +{ + write_text(text, str); + WM_main_add_notifier(NC_TEXT|NA_EDITED, text); +} + #else void RNA_api_text(StructRNA *srna) @@ -40,10 +54,10 @@ void RNA_api_text(StructRNA *srna) FunctionRNA *func; PropertyRNA *prop; - func= RNA_def_function(srna, "clear", "clear_text"); + func= RNA_def_function(srna, "clear", "rna_Text_clear"); RNA_def_function_ui_description(func, "clear the text block"); - func= RNA_def_function(srna, "write", "write_text"); + func= RNA_def_function(srna, "write", "rna_Text_write"); RNA_def_function_ui_description(func, "write text at the cursor location and advance to the end of the text block"); prop= RNA_def_string(func, "text", "Text", 0, "", "New text for this datablock"); RNA_def_property_flag(prop, PROP_REQUIRED); diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c index 4de39811d0b..368359925c4 100644 --- a/source/blender/makesrna/intern/rna_tracking.c +++ b/source/blender/makesrna/intern/rna_tracking.c @@ -39,6 +39,7 @@ #include "rna_internal.h" #include "DNA_movieclip_types.h" +#include "DNA_object_types.h" /* SELECT */ #include "DNA_scene_types.h" #include "WM_types.h" @@ -94,6 +95,29 @@ void rna_trackingTrack_name_set(PointerRNA *ptr, const char *value) BKE_track_unique_name(&clip->tracking, track); } +static int rna_trackingTrack_select_get(PointerRNA *ptr) +{ + MovieTrackingTrack *track= (MovieTrackingTrack *)ptr->data; + + return TRACK_SELECTED(track); +} + +static void rna_trackingTrack_select_set(PointerRNA *ptr, int value) +{ + MovieTrackingTrack *track= (MovieTrackingTrack *)ptr->data; + + if(value) { + track->flag|= SELECT; + track->pat_flag|= SELECT; + track->search_flag|= SELECT; + } + else { + track->flag&= ~SELECT; + track->pat_flag&= ~SELECT; + track->search_flag&= ~SELECT; + } +} + static void rna_tracking_trackerPattern_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) { MovieTrackingTrack *track= (MovieTrackingTrack *)ptr->data; @@ -253,14 +277,14 @@ static void rna_def_trackingSettings(BlenderRNA *brna) prop= RNA_def_property(srna, "speed", PROP_ENUM, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_enum_items(prop, speed_items); - RNA_def_property_ui_text(prop, "Speed", "Speed to make tracking with"); + RNA_def_property_ui_text(prop, "Speed", "Limit speed of tracking to make visual feedback easier (this does not affect the tracking quality)"); /* limit frames */ prop= RNA_def_property(srna, "frames_limit", PROP_INT, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_int_sdna(prop, NULL, "frames_limit"); RNA_def_property_range(prop, 0, SHRT_MAX); - RNA_def_property_ui_text(prop, "Frames Limit", "Amount of frames to be tracked during single tracking operation"); + RNA_def_property_ui_text(prop, "Frames Limit", "Every tracking cycle, this amount of frames are tracked"); /* adjust frames */ prop= RNA_def_property(srna, "frames_adjust", PROP_INT, PROP_NONE); @@ -274,7 +298,7 @@ static void rna_def_trackingSettings(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_int_sdna(prop, NULL, "margin"); RNA_def_property_range(prop, 0, 300); - RNA_def_property_ui_text(prop, "Margin", "Margin for markers from image boundary"); + RNA_def_property_ui_text(prop, "Margin", "Distance from image boudary at which marker stops tracking"); /* keyframe_a */ prop= RNA_def_property(srna, "keyframe_a", PROP_INT, PROP_NONE); @@ -398,7 +422,7 @@ static void rna_def_trackingCamera(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "pixel_aspect"); RNA_def_property_range(prop, 0.1f, 5000.0f); RNA_def_property_ui_range(prop, 0.1f, 5000.0f, 1, 2); - RNA_def_property_ui_text(prop, "Pixel Aspect", "Pixel aspect ratio"); + RNA_def_property_ui_text(prop, "Pixel Aspect Ratio", "Pixel aspect ratio"); RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_tracking_flushUpdate"); } @@ -441,8 +465,8 @@ static void rna_def_trackingTrack(BlenderRNA *brna) PropertyRNA *parm; static EnumPropertyItem tracker_items[] = { - {TRACKER_SAD, "SAD", 0, "SAD", "Sum of Absolute Differences tracker"}, - {TRACKER_KLT, "KLT", 0, "KLT", "Kanade–Lucas–Tomasi tracker"}, + {TRACKER_KLT, "KLT", 0, "KLT", "Kanade–Lucas–Tomasi tracker which works with most of video clips, a bit slower than SAD"}, + {TRACKER_SAD, "SAD", 0, "SAD", "Sum of Absolute Differences tracker which can be used when MLT tracker fails"}, {0, NULL, 0, NULL, NULL}}; rna_def_trackingMarker(brna); @@ -501,7 +525,7 @@ static void rna_def_trackingTrack(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_int_sdna(prop, NULL, "pyramid_levels"); RNA_def_property_range(prop, 1, 16); - RNA_def_property_ui_text(prop, "Pyramid levels", "Number of pyramid levels for KLT tracking"); + RNA_def_property_ui_text(prop, "Pyramid levels", "Number of pyramid levels (increase on blurry footage)"); RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_trackerPyramid_update"); /* minmal correlation - only used for SAD tracker */ @@ -557,6 +581,30 @@ static void rna_def_trackingTrack(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Hide", "Track is hidden"); RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + /* select */ + prop= RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_funcs(prop, "rna_trackingTrack_select_get", "rna_trackingTrack_select_set"); + RNA_def_property_ui_text(prop, "Select", "Track is selected"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + + /* select_anchor */ + prop= RNA_def_property(srna, "select_anchor", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SELECT); + RNA_def_property_ui_text(prop, "Select Anchor", "Track's anchor point is selected"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + + /* select_pattern */ + prop= RNA_def_property(srna, "select_pattern", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "pat_flag", SELECT); + RNA_def_property_ui_text(prop, "Select Pattern", "Track's pattern area is selected"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + + /* select_search */ + prop= RNA_def_property(srna, "select_search", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "search_flag", SELECT); + RNA_def_property_ui_text(prop, "Select Search", "Track's search area is selected"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + /* locked */ prop= RNA_def_property(srna, "lock", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACK_LOCKED); @@ -573,7 +621,7 @@ static void rna_def_trackingTrack(BlenderRNA *brna) prop= RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR); RNA_def_property_array(prop, 3); RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Color", "Color of the track in the Clip Editor"); + RNA_def_property_ui_text(prop, "Color", "Color of the track in the Movie Track Editor and the 3D viewport after a solve"); RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); /* average error */ @@ -636,7 +684,7 @@ static void rna_def_trackingStabilization(BlenderRNA *brna) prop= RNA_def_property(srna, "scale_max", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "maxscale"); RNA_def_property_range(prop, 0.0f, 10.0f); - RNA_def_property_ui_text(prop, "Miximal Scale", "Maximal value for scale factor"); + RNA_def_property_ui_text(prop, "Maximal Scale", "Limits the amount of automatic scaling"); RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_tracking_flushUpdate"); /* influence_location */ @@ -653,6 +701,12 @@ static void rna_def_trackingStabilization(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Scale Influence", "Influence of stabilization algorithm on footage scale"); RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_tracking_flushUpdate"); + /* use_stabilize_rotation */ + prop= RNA_def_property(srna, "use_stabilize_rotation", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACKING_STABILIZE_ROTATION); + RNA_def_property_ui_text(prop, "Stabilize Rotation", "Stabilize horizon line on the shot"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_tracking_flushUpdate"); + /* influence_rotation */ prop= RNA_def_property(srna, "influence_rotation", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "rotinf"); diff --git a/source/blender/makesrna/intern/rna_ui.c b/source/blender/makesrna/intern/rna_ui.c index 58d6911cf17..be0fec41aa1 100644 --- a/source/blender/makesrna/intern/rna_ui.c +++ b/source/blender/makesrna/intern/rna_ui.c @@ -56,6 +56,8 @@ EnumPropertyItem operator_context_items[] = { #ifdef RNA_RUNTIME +#include <assert.h> + #include "MEM_guardedalloc.h" #include "RNA_access.h" @@ -411,6 +413,7 @@ static void rna_Menu_unregister(Main *UNUSED(bmain), StructRNA *type) WM_main_add_notifier(NC_SCREEN|NA_EDITED, NULL); } +static char _menu_descr[RNA_DYN_DESCR_MAX]; static StructRNA *rna_Menu_register(Main *bmain, ReportList *reports, void *data, const char *identifier, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free) { @@ -418,11 +421,17 @@ static StructRNA *rna_Menu_register(Main *bmain, ReportList *reports, void *data Menu dummymenu= {NULL}; PointerRNA dummymtr; int have_function[2]; + size_t over_alloc= 0; /* warning, if this becomes a bess, we better do another alloc */ + size_t description_size= 0; /* setup dummy menu & menu type to store static properties in */ dummymenu.type= &dummymt; + dummymenu.type->description= _menu_descr; RNA_pointer_create(NULL, &RNA_Menu, &dummymenu, &dummymtr); + /* clear incase they are left unset */ + _menu_descr[0]= '\0'; + /* validate the python class */ if(validate(&dummymtr, data, have_function) != 0) return NULL; @@ -439,9 +448,20 @@ static StructRNA *rna_Menu_register(Main *bmain, ReportList *reports, void *data rna_Menu_unregister(bmain, mt->ext.srna); /* create a new menu type */ - mt= MEM_callocN(sizeof(MenuType), "python buttons menu"); + if (_menu_descr[0]) { + description_size= strlen(_menu_descr) + 1; + over_alloc += description_size; + } + + mt= MEM_callocN(sizeof(MenuType) + over_alloc, "python buttons menu"); memcpy(mt, &dummymt, sizeof(dummymt)); + if (_menu_descr[0]) { + char *buf= (char *)(mt + 1); + memcpy(buf, _menu_descr, description_size); + mt->description= buf; + } + mt->ext.srna= RNA_def_struct(&BLENDER_RNA, mt->idname, "Menu"); mt->ext.data= data; mt->ext.call= call; @@ -466,6 +486,14 @@ static StructRNA* rna_Menu_refine(PointerRNA *mtr) return (hdr->type && hdr->type->ext.srna)? hdr->type->ext.srna: &RNA_Menu; } +static void rna_Menu_bl_description_set(PointerRNA *ptr, const char *value) +{ + Menu *data= (Menu*)(ptr->data); + char *str= (char *)data->type->description; + if(!str[0]) BLI_strncpy(str, value, RNA_DYN_DESCR_MAX); /* utf8 already ensured */ + else assert(!"setting the bl_description on a non-builtin menu"); +} + static int rna_UILayout_active_get(PointerRNA *ptr) { return uiLayoutGetActive(ptr->data); @@ -800,6 +828,13 @@ static void rna_def_menu(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_REGISTER); RNA_def_property_ui_text(prop, "Label", "The menu label"); + prop= RNA_def_property(srna, "bl_description", PROP_STRING, PROP_TRANSLATE); + RNA_def_property_string_sdna(prop, NULL, "type->description"); + RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */ + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Menu_bl_description_set"); + // RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL); + RNA_define_verify_sdna(1); } diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index a9a48b80d89..e52a0f830dc 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -429,7 +429,8 @@ void RNA_api_ui_layout(StructRNA *srna) RNA_def_property_flag(parm, PROP_REQUIRED); RNA_def_string(func, "prop_list", "", 0, "", "Identifier of a string property in each data member, specifying which " - "of its properties should have a widget displayed in its row"); + "of its properties should have a widget displayed in its row " + "(format: \"propname1:propname2:propname3:...\")"); RNA_def_int(func, "rows", 5, 0, INT_MAX, "", "Number of rows to display", 0, INT_MAX); RNA_def_int(func, "maxrows", 5, 0, INT_MAX, "", "Maximum number of rows to display", 0, INT_MAX); RNA_def_enum(func, "type", list_type_items, 0, "Type", "Type of list to use"); diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index 77ae7095454..8e05e43b48f 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -421,7 +421,7 @@ static IDProperty *rna_OperatorProperties_idprops(PointerRNA *ptr, int create) { if(create && !ptr->data) { IDPropertyTemplate val = {0}; - ptr->data= IDP_New(IDP_GROUP, val, "RNA_OperatorProperties group"); + ptr->data= IDP_New(IDP_GROUP, &val, "RNA_OperatorProperties group"); } return ptr->data; @@ -966,7 +966,7 @@ void macro_wrapper(wmOperatorType *ot, void *userdata); static char _operator_idname[OP_MAX_TYPENAME]; static char _operator_name[OP_MAX_TYPENAME]; -static char _operator_descr[1024]; +static char _operator_descr[RNA_DYN_DESCR_MAX]; static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void *data, const char *identifier, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free) { wmOperatorType dummyot = {NULL}; @@ -1161,7 +1161,7 @@ static void rna_Operator_bl_idname_set(PointerRNA *ptr, const char *value) { wmOperator *data= (wmOperator*)(ptr->data); char *str= (char *)data->type->idname; - if(!str[0]) strcpy(str, value); + if(!str[0]) BLI_strncpy(str, value, RNA_DYN_DESCR_MAX); /* utf8 already ensured */ else assert(!"setting the bl_idname on a non-builtin operator"); } @@ -1169,7 +1169,7 @@ static void rna_Operator_bl_label_set(PointerRNA *ptr, const char *value) { wmOperator *data= (wmOperator*)(ptr->data); char *str= (char *)data->type->name; - if(!str[0]) strcpy(str, value); + if(!str[0]) BLI_strncpy(str, value, RNA_DYN_DESCR_MAX); /* utf8 already ensured */ else assert(!"setting the bl_label on a non-builtin operator"); } @@ -1177,7 +1177,7 @@ static void rna_Operator_bl_description_set(PointerRNA *ptr, const char *value) { wmOperator *data= (wmOperator*)(ptr->data); char *str= (char *)data->type->description; - if(!str[0]) strcpy(str, value); + if(!str[0]) BLI_strncpy(str, value, RNA_DYN_DESCR_MAX); /* utf8 already ensured */ else assert(!"setting the bl_description on a non-builtin operator"); } @@ -1232,14 +1232,14 @@ static void rna_def_operator(BlenderRNA *brna) prop= RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "type->name"); - RNA_def_property_string_maxlength(prop, 1024); /* else it uses the pointer size! */ + RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Operator_bl_label_set"); // RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_flag(prop, PROP_REGISTER); prop= RNA_def_property(srna, "bl_description", PROP_STRING, PROP_TRANSLATE); RNA_def_property_string_sdna(prop, NULL, "type->description"); - RNA_def_property_string_maxlength(prop, 1024); /* else it uses the pointer size! */ + RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Operator_bl_description_set"); // RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL); @@ -1293,14 +1293,14 @@ static void rna_def_macro_operator(BlenderRNA *brna) prop= RNA_def_property(srna, "bl_label", PROP_STRING, PROP_TRANSLATE); RNA_def_property_string_sdna(prop, NULL, "type->name"); - RNA_def_property_string_maxlength(prop, 1024); /* else it uses the pointer size! */ + RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Operator_bl_label_set"); // RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_flag(prop, PROP_REGISTER); prop= RNA_def_property(srna, "bl_description", PROP_STRING, PROP_TRANSLATE); RNA_def_property_string_sdna(prop, NULL, "type->description"); - RNA_def_property_string_maxlength(prop, 1024); /* else it uses the pointer size! */ + RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Operator_bl_description_set"); // RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL); diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.c index 9cfdb70b7d7..7f20b4c7bc1 100644 --- a/source/blender/modifiers/intern/MOD_ocean.c +++ b/source/blender/modifiers/intern/MOD_ocean.c @@ -178,7 +178,6 @@ static void copyData(ModifierData *md, ModifierData *target) tomd->seed = omd->seed; tomd->flag = omd->flag; - tomd->output = omd->output; tomd->refresh = 0; diff --git a/source/blender/python/generic/CMakeLists.txt b/source/blender/python/generic/CMakeLists.txt index 847a0d19a7f..bd9731a277a 100644 --- a/source/blender/python/generic/CMakeLists.txt +++ b/source/blender/python/generic/CMakeLists.txt @@ -33,17 +33,17 @@ set(INC_SYS ) set(SRC - IDProp.c bgl.c blf_py_api.c bpy_internal_import.c + idprop_py_api.c noise_py_api.c py_capi_utils.c - IDProp.h bgl.h blf_py_api.h bpy_internal_import.h + idprop_py_api.h noise_py_api.h py_capi_utils.h ) diff --git a/source/blender/python/generic/IDProp.c b/source/blender/python/generic/idprop_py_api.c index 6d869a7eb1f..73d954057c9 100644 --- a/source/blender/python/generic/IDProp.c +++ b/source/blender/python/generic/idprop_py_api.c @@ -21,14 +21,14 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/python/generic/IDProp.c +/** \file blender/python/generic/idprop_py_api.c * \ingroup pygen */ #include <Python.h> -#include "IDProp.h" +#include "idprop_py_api.h" #include "MEM_guardedalloc.h" #include "BLI_string.h" @@ -49,72 +49,114 @@ extern PyTypeObject BPy_IDGroup_Type; /*********************** ID Property Main Wrapper Stuff ***************/ -/* use for both array and group */ -static long BPy_IDGroup_hash(BPy_IDProperty *self) +/* ---------------------------------------------------------------------------- + * static conversion functions to avoid duplicate code, no type checking. + */ + +static PyObject *idprop_py_from_idp_string(IDProperty *prop) { - return _Py_HashPointer(self->prop); + if (prop->subtype == IDP_STRING_SUB_BYTE) { + return PyBytes_FromStringAndSize(IDP_Array(prop), prop->len); + } + else { +#ifdef USE_STRING_COERCE + return PyC_UnicodeFromByteAndSize(IDP_Array(prop), prop->len - 1); +#else + return PyUnicode_FromStringAndSize(IDP_Array(prop), prop->len - 1); +#endif + } } -static PyObject *BPy_IDGroup_repr(BPy_IDProperty *self) +static PyObject *idprop_py_from_idp_int(IDProperty *prop) { - return PyUnicode_FromFormat( "<bpy id property from \"%s\">", self->id->name); + return PyLong_FromLong((long)prop->data.val); } -PyObject *BPy_IDGroup_WrapData( ID *id, IDProperty *prop ) +static PyObject *idprop_py_from_idp_float(IDProperty *prop) { - switch ( prop->type ) { - case IDP_STRING: -#ifdef USE_STRING_COERCE - return PyC_UnicodeFromByteAndSize(IDP_Array(prop), prop->len - 1); -#else - return PyUnicode_FromStringAndSize(IDP_Array(prop), prop->len - 1); -#endif - case IDP_INT: - return PyLong_FromLong( (long)prop->data.val ); - case IDP_FLOAT: - return PyFloat_FromDouble( (double)(*(float*)(&prop->data.val)) ); - case IDP_DOUBLE: - return PyFloat_FromDouble( (*(double*)(&prop->data.val)) ); - case IDP_GROUP: - /*blegh*/ - { - BPy_IDProperty *group = PyObject_New(BPy_IDProperty, &BPy_IDGroup_Type); - group->id = id; - group->prop = prop; - return (PyObject*) group; - } - case IDP_ARRAY: - { - BPy_IDProperty *array = PyObject_New(BPy_IDProperty, &BPy_IDArray_Type); - array->id = id; - array->prop = prop; - return (PyObject*) array; - } - case IDP_IDPARRAY: /* this could be better a internal type */ - { - PyObject *seq = PyList_New(prop->len), *wrap; - IDProperty *array= IDP_IDPArray(prop); - int i; + return PyFloat_FromDouble((double)(*(float*)(&prop->data.val))); +} + +static PyObject *idprop_py_from_idp_double(IDProperty *prop) +{ + return PyFloat_FromDouble((*(double*)(&prop->data.val))); +} + +static PyObject *idprop_py_from_idp_group(ID *id, IDProperty *prop, IDProperty *parent) +{ + BPy_IDProperty *group= PyObject_New(BPy_IDProperty, &BPy_IDGroup_Type); + group->id = id; + group->prop = prop; + group->parent = parent; /* can be NULL */ + return (PyObject*) group; +} + +static PyObject *idprop_py_from_idp_array(ID *id, IDProperty *prop) +{ + BPy_IDProperty *array = PyObject_New(BPy_IDProperty, &BPy_IDArray_Type); + array->id = id; + array->prop = prop; + return (PyObject*) array; +} - if (!seq) { - PyErr_Format(PyExc_RuntimeError, "BPy_IDGroup_MapDataToPy, IDP_IDPARRAY: PyList_New(%d) failed", prop->len); - return NULL; - } +static PyObject *idprop_py_from_idp_idparray(ID *id, IDProperty *prop) +{ + PyObject *seq = PyList_New(prop->len), *wrap; + IDProperty *array= IDP_IDPArray(prop); + int i; - for (i=0; i<prop->len; i++) { - wrap= BPy_IDGroup_WrapData(id, array++); + if (!seq) { + PyErr_Format(PyExc_RuntimeError, + "%s: IDP_IDPARRAY: PyList_New(%d) failed", + __func__, prop->len); + return NULL; + } - if (!wrap) /* BPy_IDGroup_MapDataToPy sets the error */ - return NULL; + for (i=0; i<prop->len; i++) { + wrap= BPy_IDGroup_WrapData(id, array++, prop); - PyList_SET_ITEM(seq, i, wrap); - } + if (!wrap) /* BPy_IDGroup_MapDataToPy sets the error */ + return NULL; - return seq; - } - /* case IDP_IDPARRAY: TODO */ + PyList_SET_ITEM(seq, i, wrap); + } + + return seq; +} + +/* -------------------------------------------------------------------------- */ + +/* use for both array and group */ +static long BPy_IDGroup_hash(BPy_IDProperty *self) +{ + return _Py_HashPointer(self->prop); +} + +static PyObject *BPy_IDGroup_repr(BPy_IDProperty *self) +{ + return PyUnicode_FromFormat( "<bpy id property from \"%s\">", self->id->name); +} + +PyObject *BPy_IDGroup_WrapData(ID *id, IDProperty *prop, IDProperty *parent) +{ + switch (prop->type) { + case IDP_STRING: + return idprop_py_from_idp_string(prop); + case IDP_INT: + return idprop_py_from_idp_int(prop); + case IDP_FLOAT: + return idprop_py_from_idp_float(prop); + case IDP_DOUBLE: + return idprop_py_from_idp_double(prop); + case IDP_GROUP: + return idprop_py_from_idp_group(id, prop, parent); + case IDP_ARRAY: + return idprop_py_from_idp_idparray(id, prop); + case IDP_IDPARRAY: /* this could be better a internal type */ + idprop_py_from_idp_array(id, prop); + default: + Py_RETURN_NONE; } - Py_RETURN_NONE; } #if 0 /* UNUSED, currenly assignment overwrites into new properties, rather than setting in-place */ @@ -128,6 +170,7 @@ static int BPy_IDGroup_SetData(BPy_IDProperty *self, IDProperty *prop, PyObject PyErr_SetString(PyExc_TypeError, "expected a string!"); return -1; } + /* NOTE: if this code is enabled, bytes support needs to be added */ #ifdef USE_STRING_COERCE { int alloc_len; @@ -260,8 +303,7 @@ static PyObject *BPy_IDGroup_Map_GetItem(BPy_IDProperty *self, PyObject *item) return NULL; } - return BPy_IDGroup_WrapData(self->id, idprop); - + return BPy_IDGroup_WrapData(self->id, idprop, self->prop); } /*returns NULL on success, error string on failure*/ @@ -323,23 +365,33 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty if (PyFloat_Check(ob)) { val.d = PyFloat_AsDouble(ob); - prop = IDP_New(IDP_DOUBLE, val, name); + prop = IDP_New(IDP_DOUBLE, &val, name); } else if (PyLong_Check(ob)) { val.i = (int) PyLong_AsSsize_t(ob); - prop = IDP_New(IDP_INT, val, name); + prop = IDP_New(IDP_INT, &val, name); } else if (PyUnicode_Check(ob)) { #ifdef USE_STRING_COERCE PyObject *value_coerce= NULL; - val.str = (char *)PyC_UnicodeAsByte(ob, &value_coerce); - prop = IDP_New(IDP_STRING, val, name); + val.string.str = (char *)PyC_UnicodeAsByte(ob, &value_coerce); + val.string.subtype = IDP_STRING_SUB_UTF8; + prop = IDP_New(IDP_STRING, &val, name); Py_XDECREF(value_coerce); #else val.str = _PyUnicode_AsString(ob); prop = IDP_New(IDP_STRING, val, name); #endif } + else if (PyBytes_Check(ob)) { + val.string.str= PyBytes_AS_STRING(ob); + val.string.len= PyBytes_GET_SIZE(ob); + val.string.subtype= IDP_STRING_SUB_BYTE; + + prop = IDP_New(IDP_STRING, &val, name); + //prop = IDP_NewString(PyBytes_AS_STRING(ob), name, PyBytes_GET_SIZE(ob)); + //prop->subtype= IDP_STRING_SUB_BYTE; + } else if (PySequence_Check(ob)) { PyObject *item; int i; @@ -355,7 +407,7 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty switch(val.array.type) { case IDP_DOUBLE: - prop = IDP_New(IDP_ARRAY, val, name); + prop = IDP_New(IDP_ARRAY, &val, name); for (i=0; i<val.array.len; i++) { item = PySequence_GetItem(ob, i); ((double*)IDP_Array(prop))[i] = (float)PyFloat_AsDouble(item); @@ -363,7 +415,7 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty } break; case IDP_INT: - prop = IDP_New(IDP_ARRAY, val, name); + prop = IDP_New(IDP_ARRAY, &val, name); for (i=0; i<val.array.len; i++) { item = PySequence_GetItem(ob, i); ((int*)IDP_Array(prop))[i] = (int)PyLong_AsSsize_t(item); @@ -393,7 +445,7 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty /*we allocate the group first; if we hit any invalid data, we can delete it easily enough.*/ - prop = IDP_New(IDP_GROUP, val, name); + prop = IDP_New(IDP_GROUP, &val, name); len = PyMapping_Length(ob); for (i=0; i<len; i++) { key = PySequence_GetItem(keys, i); @@ -489,108 +541,109 @@ static PyObject *BPy_IDGroup_iter(BPy_IDProperty *self) return (PyObject*) iter; } +/* for simple, non nested types this is the same as BPy_IDGroup_WrapData */ static PyObject *BPy_IDGroup_MapDataToPy(IDProperty *prop) { switch (prop->type) { - case IDP_STRING: -#ifdef USE_STRING_COERCE - return PyC_UnicodeFromByteAndSize(IDP_Array(prop), prop->len - 1); -#else - return PyUnicode_FromStringAndSize(IDP_Array(prop), prop->len - 1); -#endif - break; + case IDP_STRING: + return idprop_py_from_idp_string(prop); + case IDP_INT: + return idprop_py_from_idp_int(prop); + case IDP_FLOAT: + return idprop_py_from_idp_float(prop); + case IDP_DOUBLE: + return idprop_py_from_idp_double(prop); + case IDP_ARRAY: + { + PyObject *seq = PyList_New(prop->len); + int i; + + if (!seq) { + PyErr_Format(PyExc_RuntimeError, + "%s: IDP_ARRAY: PyList_New(%d) failed", + __func__, prop->len); + return NULL; + } + + switch(prop->subtype) { case IDP_FLOAT: - return PyFloat_FromDouble(*((float*)&prop->data.val)); + { + float *array= (float*)IDP_Array(prop); + for (i=0; i<prop->len; i++) { + PyList_SET_ITEM(seq, i, PyFloat_FromDouble(array[i])); + } break; + } case IDP_DOUBLE: - return PyFloat_FromDouble(*((double*)&prop->data.val)); + { + double *array= (double*)IDP_Array(prop); + for (i=0; i<prop->len; i++) { + PyList_SET_ITEM(seq, i, PyFloat_FromDouble(array[i])); + } break; + } case IDP_INT: - return PyLong_FromSsize_t( prop->data.val ); - break; - case IDP_ARRAY: { - PyObject *seq = PyList_New(prop->len); - int i; - - if (!seq) { - PyErr_Format(PyExc_RuntimeError, "BPy_IDGroup_MapDataToPy, IDP_ARRAY: PyList_New(%d) failed", prop->len); - return NULL; + int *array= (int*)IDP_Array(prop); + for (i=0; i<prop->len; i++) { + PyList_SET_ITEM(seq, i, PyLong_FromLong(array[i])); } + break; + } + default: + PyErr_Format(PyExc_RuntimeError, + "%s: invalid/corrupt array type '%d'!", + __func__, prop->subtype); + Py_DECREF(seq); + return NULL; + } - switch(prop->subtype) { - case IDP_FLOAT: - { - float *array= (float*)IDP_Array(prop); - for (i=0; i<prop->len; i++) { - PyList_SET_ITEM(seq, i, PyFloat_FromDouble(array[i])); - } - break; - } - case IDP_DOUBLE: - { - double *array= (double*)IDP_Array(prop); - for (i=0; i<prop->len; i++) { - PyList_SET_ITEM(seq, i, PyFloat_FromDouble(array[i])); - } - break; - } - case IDP_INT: - { - int *array= (int*)IDP_Array(prop); - for (i=0; i<prop->len; i++) { - PyList_SET_ITEM(seq, i, PyLong_FromLong(array[i])); - } - break; - } - default: - PyErr_SetString(PyExc_RuntimeError, "invalid/corrupt array type!"); - Py_DECREF(seq); - return NULL; - } + return seq; + } + case IDP_IDPARRAY: + { + PyObject *seq = PyList_New(prop->len), *wrap; + IDProperty *array= IDP_IDPArray(prop); + int i; - return seq; + if (!seq) { + PyErr_Format(PyExc_RuntimeError, + "%s: IDP_IDPARRAY: PyList_New(%d) failed", + __func__, prop->len); + return NULL; } - case IDP_IDPARRAY: - { - PyObject *seq = PyList_New(prop->len), *wrap; - IDProperty *array= IDP_IDPArray(prop); - int i; - - if (!seq) { - PyErr_Format(PyExc_RuntimeError, "BPy_IDGroup_MapDataToPy, IDP_IDPARRAY: PyList_New(%d) failed", prop->len); - return NULL; - } - for (i=0; i<prop->len; i++) { - wrap= BPy_IDGroup_MapDataToPy(array++); + for (i=0; i<prop->len; i++) { + wrap= BPy_IDGroup_MapDataToPy(array++); - if (!wrap) /* BPy_IDGroup_MapDataToPy sets the error */ - return NULL; + if (!wrap) /* BPy_IDGroup_MapDataToPy sets the error */ + return NULL; - PyList_SET_ITEM(seq, i, wrap); - } - return seq; + PyList_SET_ITEM(seq, i, wrap); } - case IDP_GROUP: - { - PyObject *dict = PyDict_New(), *wrap; - IDProperty *loop; + return seq; + } + case IDP_GROUP: + { + PyObject *dict = PyDict_New(), *wrap; + IDProperty *loop; - for (loop=prop->data.group.first; loop; loop=loop->next) { - wrap = BPy_IDGroup_MapDataToPy(loop); + for (loop=prop->data.group.first; loop; loop=loop->next) { + wrap = BPy_IDGroup_MapDataToPy(loop); - if (!wrap) /* BPy_IDGroup_MapDataToPy sets the error */ - return NULL; + if (!wrap) /* BPy_IDGroup_MapDataToPy sets the error */ + return NULL; - PyDict_SetItemString(dict, loop->name, wrap); - Py_DECREF(wrap); - } - return dict; + PyDict_SetItemString(dict, loop->name, wrap); + Py_DECREF(wrap); } + return dict; + } } - PyErr_Format(PyExc_RuntimeError, "eek!! '%s' property exists with a bad type code '%d' !!!", prop->name, prop->type); + PyErr_Format(PyExc_RuntimeError, + "%s ERROR: '%s' property exists with a bad type code '%d'!", + __func__, prop->name, prop->type); return NULL; } @@ -601,7 +654,9 @@ static PyObject *BPy_IDGroup_Pop(BPy_IDProperty *self, PyObject *value) const char *name = _PyUnicode_AsString(value); if (!name) { - PyErr_SetString(PyExc_TypeError, "pop expected at least 1 argument, got 0"); + PyErr_Format(PyExc_TypeError, + "pop expected at least a string argument, not %.200s", + Py_TYPE(value)->tp_name); return NULL; } @@ -654,44 +709,44 @@ static void BPy_IDGroup_CorrectListLen(IDProperty *prop, PyObject *seq, int len, PyObject *BPy_Wrap_GetKeys(IDProperty *prop) { - PyObject *seq = PyList_New(prop->len); + PyObject *list = PyList_New(prop->len); IDProperty *loop; int i; for (i=0, loop=prop->data.group.first; loop && (i < prop->len); loop=loop->next, i++) - PyList_SET_ITEM(seq, i, PyUnicode_FromString(loop->name)); + PyList_SET_ITEM(list, i, PyUnicode_FromString(loop->name)); /* if the id prop is corrupt, count the remaining */ for (; loop; loop=loop->next, i++) {} if (i != prop->len) { /* if the loop didnt finish, we know the length is wrong */ - BPy_IDGroup_CorrectListLen(prop, seq, i, __func__); - Py_DECREF(seq); /*free the list*/ + BPy_IDGroup_CorrectListLen(prop, list, i, __func__); + Py_DECREF(list); /*free the list*/ /*call self again*/ return BPy_Wrap_GetKeys(prop); } - return seq; + return list; } PyObject *BPy_Wrap_GetValues(ID *id, IDProperty *prop) { - PyObject *seq = PyList_New(prop->len); + PyObject *list = PyList_New(prop->len); IDProperty *loop; int i; for (i=0, loop=prop->data.group.first; loop; loop=loop->next, i++) { - PyList_SET_ITEM(seq, i, BPy_IDGroup_WrapData(id, loop)); + PyList_SET_ITEM(list, i, BPy_IDGroup_WrapData(id, loop, prop)); } if (i != prop->len) { - BPy_IDGroup_CorrectListLen(prop, seq, i, __func__); - Py_DECREF(seq); /*free the list*/ + BPy_IDGroup_CorrectListLen(prop, list, i, __func__); + Py_DECREF(list); /*free the list*/ /*call self again*/ return BPy_Wrap_GetValues(id, prop); } - return seq; + return list; } PyObject *BPy_Wrap_GetItems(ID *id, IDProperty *prop) @@ -703,7 +758,7 @@ PyObject *BPy_Wrap_GetItems(ID *id, IDProperty *prop) for (i=0, loop=prop->data.group.first; loop; loop=loop->next, i++) { PyObject *item= PyTuple_New(2); PyTuple_SET_ITEM(item, 0, PyUnicode_FromString(loop->name)); - PyTuple_SET_ITEM(item, 1, BPy_IDGroup_WrapData(id, loop)); + PyTuple_SET_ITEM(item, 1, BPy_IDGroup_WrapData(id, loop, prop)); PyList_SET_ITEM(seq, i, item); } @@ -738,7 +793,9 @@ static int BPy_IDGroup_Contains(BPy_IDProperty *self, PyObject *value) const char *name = _PyUnicode_AsString(value); if (!name) { - PyErr_SetString(PyExc_TypeError, "expected a string"); + PyErr_Format(PyExc_TypeError, + "expected a string, not a %.200s", + Py_TYPE(value)->tp_name); return -1; } @@ -751,7 +808,9 @@ static PyObject *BPy_IDGroup_Update(BPy_IDProperty *self, PyObject *value) Py_ssize_t i=0; if (!PyDict_Check(value)) { - PyErr_SetString(PyExc_TypeError, "expected an object derived from dict"); + PyErr_Format(PyExc_TypeError, + "expected a dict not a %.200s", + Py_TYPE(value)->tp_name); return NULL; } @@ -781,7 +840,7 @@ static PyObject* BPy_IDGroup_Get(BPy_IDProperty *self, PyObject *args) idprop= IDP_GetPropertyFromGroup(self->prop, key); if (idprop) { - PyObject* pyobj = BPy_IDGroup_WrapData(self->id, idprop); + PyObject* pyobj = BPy_IDGroup_WrapData(self->id, idprop, self->prop); if (pyobj) return pyobj; } @@ -890,18 +949,6 @@ PyTypeObject BPy_IDGroup_Type = { BPy_IDGroup_getseters, /* struct PyGetSetDef *tp_getset; */ }; -/*********** Main external wrapping function *******/ -PyObject *BPy_Wrap_IDProperty(ID *id, IDProperty *prop, IDProperty *parent) -{ - BPy_IDProperty *wrap = PyObject_New(BPy_IDProperty, &BPy_IDGroup_Type); - wrap->prop = prop; - wrap->parent = parent; - wrap->id = id; - //wrap->destroy = 0; - return (PyObject*) wrap; -} - - /********Array Wrapper********/ static PyTypeObject *idp_array_py_type(BPy_IDArray *self, short *is_double) @@ -938,7 +985,10 @@ static PyObject *BPy_IDArray_GetType(BPy_IDArray *self) return PyUnicode_FromString("i"); } - PyErr_SetString(PyExc_RuntimeError, "invalid/corrupt array type!"); + PyErr_Format(PyExc_RuntimeError, + "%s: invalid/corrupt array type '%d'!", + __func__, self->prop->subtype); + return NULL; } @@ -980,7 +1030,10 @@ static PyObject *BPy_IDArray_GetItem(BPy_IDArray *self, int index) return PyLong_FromLong((long)((int*)IDP_Array(self->prop))[index]); } - PyErr_SetString(PyExc_RuntimeError, "invalid/corrupt array type!"); + PyErr_Format(PyExc_RuntimeError, + "%s: invalid/corrupt array type '%d'!", + __func__, self->prop->subtype); + return NULL; } @@ -1143,7 +1196,9 @@ static PyObject *BPy_IDArray_subscript(BPy_IDArray* self, PyObject* item) } } else { - PyErr_Format(PyExc_TypeError, "vector indices must be integers, not %.200s", Py_TYPE(item)->tp_name); + PyErr_Format(PyExc_TypeError, + "vector indices must be integers, not %.200s", + __func__, Py_TYPE(item)->tp_name); return NULL; } } @@ -1172,7 +1227,9 @@ static int BPy_IDArray_ass_subscript(BPy_IDArray* self, PyObject* item, PyObject } } else { - PyErr_Format(PyExc_TypeError, "vector indices must be integers, not %.200s", Py_TYPE(item)->tp_name); + PyErr_Format(PyExc_TypeError, + "vector indices must be integers, not %.200s", + Py_TYPE(item)->tp_name); return -1; } } @@ -1289,7 +1346,7 @@ static PyObject *BPy_Group_Iter_Next(BPy_IDGroup_Iter *self) if (self->mode == IDPROP_ITER_ITEMS) { ret = PyTuple_New(2); PyTuple_SET_ITEM(ret, 0, PyUnicode_FromString(cur->name)); - PyTuple_SET_ITEM(ret, 1, BPy_IDGroup_WrapData(self->group->id, cur)); + PyTuple_SET_ITEM(ret, 1, BPy_IDGroup_WrapData(self->group->id, cur, self->group->prop)); return ret; } else { diff --git a/source/blender/python/generic/IDProp.h b/source/blender/python/generic/idprop_py_api.h index 36cb4c76a5c..599ba8e1db6 100644 --- a/source/blender/python/generic/IDProp.h +++ b/source/blender/python/generic/idprop_py_api.h @@ -20,13 +20,13 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/python/generic/IDProp.h +/** \file blender/python/generic/idprop_py_api.h * \ingroup pygen */ -#ifndef IDPROP_H -#define IDPROP_H +#ifndef PY_IDPROP_API_H +#define PY_IDPROP_API_H struct ID; struct IDProperty; @@ -53,14 +53,13 @@ typedef struct BPy_IDGroup_Iter { int mode; } BPy_IDGroup_Iter; -PyObject *BPy_Wrap_IDProperty(struct ID *id, struct IDProperty *prop, struct IDProperty *parent); PyObject *BPy_Wrap_GetKeys(struct IDProperty *prop); PyObject *BPy_Wrap_GetValues(struct ID *id, struct IDProperty *prop); PyObject *BPy_Wrap_GetItems(struct ID *id, struct IDProperty *prop); int BPy_Wrap_SetMapItem(struct IDProperty *prop, PyObject *key, PyObject *val); -PyObject *BPy_IDGroup_WrapData(struct ID *id, struct IDProperty *prop ); +PyObject *BPy_IDGroup_WrapData(struct ID *id, struct IDProperty *prop, struct IDProperty *parent); const char *BPy_IDProperty_Map_ValidateAndCreate(PyObject *key, struct IDProperty *group, PyObject *ob); void IDProp_Init_Types(void); @@ -68,4 +67,4 @@ void IDProp_Init_Types(void); #define IDPROP_ITER_KEYS 0 #define IDPROP_ITER_ITEMS 1 -#endif /* IDPROP_H */ +#endif /* PY_IDPROP_API_H */ diff --git a/source/blender/python/intern/bpy.c b/source/blender/python/intern/bpy.c index 2df907f3a12..9bb7457a1f7 100644 --- a/source/blender/python/intern/bpy.c +++ b/source/blender/python/intern/bpy.c @@ -53,7 +53,7 @@ #include "MEM_guardedalloc.h" /* external util modules */ -#include "../generic/IDProp.h" +#include "../generic/idprop_py_api.h" #include "../generic/bgl.h" #include "../generic/blf_py_api.h" #include "../mathutils/mathutils.h" diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c index 2b71cdd4ffc..950aa9458d5 100644 --- a/source/blender/python/intern/bpy_props.c +++ b/source/blender/python/intern/bpy_props.c @@ -74,6 +74,7 @@ static EnumPropertyItem property_subtype_string_items[]= { {PROP_FILEPATH, "FILE_PATH", 0, "File Path", ""}, {PROP_DIRPATH, "DIR_PATH", 0, "Directory Path", ""}, {PROP_FILENAME, "FILENAME", 0, "Filename", ""}, + {PROP_BYTESTRING, "BYTE_STRING", 0, "Byte String", ""}, {PROP_TRANSLATE, "TRANSLATE", 0, "Translate", ""}, {PROP_NONE, "NONE", 0, "None", ""}, diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 15a9ba44552..f1916355971 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -73,7 +73,7 @@ #include "BKE_animsys.h" #include "BKE_fcurve.h" -#include "../generic/IDProp.h" /* for IDprop lookups */ +#include "../generic/idprop_py_api.h" /* for IDprop lookups */ #include "../generic/py_capi_utils.h" #ifdef WITH_INTERNATIONAL @@ -598,7 +598,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) int subtype, totdim; int len; int is_thick; - int flag= RNA_property_flag(prop); + const int flag= RNA_property_flag(prop); /* disallow dynamic sized arrays to be wrapped since the size could change * to a size mathutils does not support */ @@ -614,7 +614,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) if (!is_thick) ret= pyrna_prop_CreatePyObject(ptr, prop); /* owned by the mathutils PyObject */ - switch(RNA_property_subtype(prop)) { + switch(subtype) { case PROP_ALL_VECTOR_SUBTYPES: if (len>=2 && len <= 4) { if (is_thick) { @@ -902,7 +902,7 @@ static PyObject *pyrna_prop_str(BPy_PropertyRNA *self) } /* if a pointer, try to print name of pointer target too */ - if (RNA_property_type(self->prop) == PROP_POINTER) { + if (type == PROP_POINTER) { ptr= RNA_property_pointer_get(&self->ptr, self->prop); name= RNA_struct_name_get_alloc(&ptr, NULL, 0, NULL); @@ -916,7 +916,7 @@ static PyObject *pyrna_prop_str(BPy_PropertyRNA *self) return ret; } } - if (RNA_property_type(self->prop) == PROP_COLLECTION) { + if (type == PROP_COLLECTION) { PointerRNA r_ptr; if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) { return PyUnicode_FromFormat("<bpy_%.200s, %.200s>", @@ -1301,7 +1301,7 @@ static PyObject *pyrna_enum_to_py(PointerRNA *ptr, PropertyRNA *prop, int val) PyObject *pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop) { PyObject *ret; - int type= RNA_property_type(prop); + const int type= RNA_property_type(prop); if (RNA_property_array_check(prop)) { return pyrna_py_from_array(ptr, prop); @@ -1320,7 +1320,7 @@ PyObject *pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop) break; case PROP_STRING: { - int subtype= RNA_property_subtype(prop); + const int subtype= RNA_property_subtype(prop); const char *buf; int buf_len; char buf_fixed[32]; @@ -1328,14 +1328,22 @@ PyObject *pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop) buf= RNA_property_string_get_alloc(ptr, prop, buf_fixed, sizeof(buf_fixed), &buf_len); #ifdef USE_STRING_COERCE /* only file paths get special treatment, they may contain non utf-8 chars */ - if (ELEM3(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) { + if (subtype == PROP_BYTESTRING) { + ret= PyBytes_FromStringAndSize(buf, buf_len); + } + else if (ELEM3(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) { ret= PyC_UnicodeFromByteAndSize(buf, buf_len); } else { ret= PyUnicode_FromStringAndSize(buf, buf_len); } #else // USE_STRING_COERCE - ret= PyUnicode_FromStringAndSize(buf, buf_len); + if (subtype == PROP_BYTESTRING) { + ret= PyBytes_FromStringAndSize(buf, buf_len); + } + else { + ret= PyUnicode_FromStringAndSize(buf, buf_len); + } #endif // USE_STRING_COERCE if (buf_fixed != buf) { MEM_freeN((void *)buf); @@ -1450,7 +1458,7 @@ static PyObject *pyrna_func_to_py(PointerRNA *ptr, FunctionRNA *func) static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *value, const char *error_prefix) { /* XXX hard limits should be checked here */ - int type= RNA_property_type(prop); + const int type= RNA_property_type(prop); if (RNA_property_array_check(prop)) { @@ -1534,53 +1542,91 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb } case PROP_STRING: { + const int subtype= RNA_property_subtype(prop); const char *param; -#ifdef USE_STRING_COERCE - PyObject *value_coerce= NULL; - int subtype= RNA_property_subtype(prop); - if (ELEM3(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) { - /* TODO, get size */ - param= PyC_UnicodeAsByte(value, &value_coerce); + + if (subtype == PROP_BYTESTRING) { + + /* Byte String */ + + param= PyBytes_AsString(value); + + if (param==NULL) { + if (PyBytes_Check(value)) { + /* there was an error assigning a string type, + * rather than setting a new error, prefix the existing one + */ + PyC_Err_Format_Prefix(PyExc_TypeError, + "%.200s %.200s.%.200s error assigning bytes", + error_prefix, RNA_struct_identifier(ptr->type), + RNA_property_identifier(prop)); + } + else { + PyErr_Format(PyExc_TypeError, + "%.200s %.200s.%.200s expected a bytes type, not %.200s", + error_prefix, RNA_struct_identifier(ptr->type), + RNA_property_identifier(prop), Py_TYPE(value)->tp_name); + } + + return -1; + } + else { + /* same as unicode */ + if (data) *((char**)data)= (char *)param; /*XXX, this is suspect but needed for function calls, need to see if theres a better way */ + else RNA_property_string_set(ptr, prop, param); + } } else { - param= _PyUnicode_AsString(value); -#ifdef WITH_INTERNATIONAL - if (subtype == PROP_TRANSLATE) { - param= IFACE_(param); + + /* Unicode String */ + +#ifdef USE_STRING_COERCE + PyObject *value_coerce= NULL; + if (ELEM3(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) { + /* TODO, get size */ + param= PyC_UnicodeAsByte(value, &value_coerce); } + else { + param= _PyUnicode_AsString(value); +#ifdef WITH_INTERNATIONAL + if (subtype == PROP_TRANSLATE) { + param= IFACE_(param); + } #endif // WITH_INTERNATIONAL - } + } #else // USE_STRING_COERCE - param= _PyUnicode_AsString(value); + param= _PyUnicode_AsString(value); #endif // USE_STRING_COERCE - if (param==NULL) { - if (PyUnicode_Check(value)) { - /* there was an error assigning a string type, - * rather than setting a new error, prefix the existing one - */ - PyC_Err_Format_Prefix(PyExc_TypeError, - "%.200s %.200s.%.200s error assigning string", - error_prefix, RNA_struct_identifier(ptr->type), - RNA_property_identifier(prop)); + if (param==NULL) { + if (PyUnicode_Check(value)) { + /* there was an error assigning a string type, + * rather than setting a new error, prefix the existing one + */ + PyC_Err_Format_Prefix(PyExc_TypeError, + "%.200s %.200s.%.200s error assigning string", + error_prefix, RNA_struct_identifier(ptr->type), + RNA_property_identifier(prop)); + } + else { + PyErr_Format(PyExc_TypeError, + "%.200s %.200s.%.200s expected a string type, not %.200s", + error_prefix, RNA_struct_identifier(ptr->type), + RNA_property_identifier(prop), Py_TYPE(value)->tp_name); + } + + return -1; } else { - PyErr_Format(PyExc_TypeError, - "%.200s %.200s.%.200s expected a string type, not %.200s", - error_prefix, RNA_struct_identifier(ptr->type), - RNA_property_identifier(prop), Py_TYPE(value)->tp_name); + /* same as bytes */ + if (data) *((char**)data)= (char *)param; /*XXX, this is suspect but needed for function calls, need to see if theres a better way */ + else RNA_property_string_set(ptr, prop, param); } - - return -1; - } - else { - if (data) *((char**)data)= (char *)param; /*XXX, this is suspect but needed for function calls, need to see if theres a better way */ - else RNA_property_string_set(ptr, prop, param); - } #ifdef USE_STRING_COERCE - Py_XDECREF(value_coerce); + Py_XDECREF(value_coerce); #endif // USE_STRING_COERCE + } break; } case PROP_ENUM: @@ -2736,7 +2782,7 @@ static PyObject *pyrna_struct_subscript(BPy_StructRNA *self, PyObject *key) return NULL; } - return BPy_IDGroup_WrapData(self->ptr.id.data, idprop); + return BPy_IDGroup_WrapData(self->ptr.id.data, idprop, group); } static int pyrna_struct_ass_subscript(BPy_StructRNA *self, PyObject *key, PyObject *value) @@ -2751,7 +2797,7 @@ static int pyrna_struct_ass_subscript(BPy_StructRNA *self, PyObject *key, PyObje if (rna_disallow_writes && rna_id_write_error(&self->ptr, key)) { return -1; } -#endif // USE_STRING_COERCE +#endif // USE_PEDANTIC_WRITE if (group==NULL) { PyErr_SetString(PyExc_TypeError, "bpy_struct[key]= val: id properties not supported for this type"); @@ -3440,7 +3486,7 @@ static int pyrna_struct_setattro(BPy_StructRNA *self, PyObject *pyname, PyObject if (rna_disallow_writes && rna_id_write_error(&self->ptr, pyname)) { return -1; } -#endif // USE_STRING_COERCE +#endif // USE_PEDANTIC_WRITE if (name == NULL) { PyErr_SetString(PyExc_AttributeError, "bpy_struct: __setattr__ must be a string"); @@ -3600,7 +3646,7 @@ static int pyrna_prop_collection_setattro(BPy_PropertyRNA *self, PyObject *pynam if (rna_disallow_writes && rna_id_write_error(&self->ptr, pyname)) { return -1; } -#endif // USE_STRING_COERCE +#endif // USE_PEDANTIC_WRITE if (name == NULL) { PyErr_SetString(PyExc_AttributeError, "bpy_prop: __setattr__ must be a string"); @@ -3846,7 +3892,7 @@ static PyObject *pyrna_struct_get(BPy_StructRNA *self, PyObject *args) idprop= IDP_GetPropertyFromGroup(group, key); if (idprop) { - return BPy_IDGroup_WrapData(self->ptr.id.data, idprop); + return BPy_IDGroup_WrapData(self->ptr.id.data, idprop, group); } } @@ -4365,8 +4411,8 @@ static PyObject *pyrna_prop_new(PyTypeObject *type, PyObject *args, PyObject *UN static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data) { PyObject *ret; - int type= RNA_property_type(prop); - int flag= RNA_property_flag(prop); + const int type= RNA_property_type(prop); + const int flag= RNA_property_flag(prop); if (RNA_property_array_check(prop)) { int a, len; @@ -4442,7 +4488,7 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat { char *data_ch; PyObject *value_coerce= NULL; - int subtype= RNA_property_subtype(prop); + const int subtype= RNA_property_subtype(prop); if (flag & PROP_THICK_WRAP) data_ch= (char *)data; @@ -4450,14 +4496,22 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat data_ch= *(char **)data; #ifdef USE_STRING_COERCE - if (ELEM3(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) { + if (subtype == PROP_BYTESTRING) { + ret= PyBytes_FromString(data_ch); + } + else if (ELEM3(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) { ret= PyC_UnicodeFromByte(data_ch); } else { ret= PyUnicode_FromString(data_ch); } #else - ret= PyUnicode_FromString(data_ch); + if (subtype == PROP_BYTESTRING) { + ret= PyBytes_FromString(buf); + } + else { + ret= PyUnicode_FromString(data_ch); + } #endif #ifdef USE_STRING_COERCE diff --git a/source/blender/windowmanager/intern/wm_apple.c b/source/blender/windowmanager/intern/wm_apple.c index c19523cbaee..e17441873d5 100644 --- a/source/blender/windowmanager/intern/wm_apple.c +++ b/source/blender/windowmanager/intern/wm_apple.c @@ -98,8 +98,8 @@ static int checkAppleVideoCard(void) StandardAlert ( kAlertStopAlert, (ConstStr255Param) &inError, (ConstStr255Param)&inText,NULL,&junkHit); abort(); } -CGLDestroyRendererInfo (rend); -return 0; + CGLDestroyRendererInfo (rend); + return 0; } static void getMacAvailableBounds(short *top, short *left, short *bottom, short *right) diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 4342c9f4bff..a7c3e973a39 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -636,7 +636,7 @@ static wmOperator *wm_operator_create(wmWindowManager *wm, wmOperatorType *ot, P } else { IDPropertyTemplate val = {0}; - op->properties= IDP_New(IDP_GROUP, val, "wmOperatorProperties"); + op->properties= IDP_New(IDP_GROUP, &val, "wmOperatorProperties"); } RNA_pointer_create(&wm->id, ot->srna, op->properties, op->ptr); diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 8d7e812a386..1a7031c7d31 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -155,8 +155,9 @@ static void wm_window_match_init(bContext *C, ListBase *wmlist) CTX_wm_window_set(C, active_win); ED_editors_exit(C); - -return; + + /* just had return; here from r12991, this code could just get removed?*/ +#if 0 if(wm==NULL) return; if(G.fileflags & G_FILE_NO_UI) return; @@ -168,6 +169,7 @@ return; //BLI_addtail(screenbase, win->screen); } } +#endif } /* match old WM with new, 4 cases: @@ -193,9 +195,10 @@ static void wm_window_match_do(bContext *C, ListBase *oldwmlist) /* we've read file without wm..., keep current one entirely alive */ if(G.main->wm.first==NULL) { + bScreen *screen= NULL; + /* when loading without UI, no matching needed */ - if(!(G.fileflags & G_FILE_NO_UI)) { - bScreen *screen= CTX_wm_screen(C); + if(!(G.fileflags & G_FILE_NO_UI) && (screen= CTX_wm_screen(C))) { /* match oldwm to new dbase, only old files */ for(wm= oldwmlist->first; wm; wm= wm->id.next) { diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 7fb6ba6e26b..0c538865501 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -597,7 +597,7 @@ void WM_operator_properties_alloc(PointerRNA **ptr, IDProperty **properties, con { if(*properties==NULL) { IDPropertyTemplate val = {0}; - *properties= IDP_New(IDP_GROUP, val, "wmOpItemProp"); + *properties= IDP_New(IDP_GROUP, &val, "wmOpItemProp"); } if(*ptr==NULL) { diff --git a/source/creator/creator.c b/source/creator/creator.c index 7e9e433598b..93cc5ad0d2e 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -467,7 +467,7 @@ static int prefsize(int argc, const char **argv, void *UNUSED(data)) int stax, stay, sizx, sizy; if (argc < 5) { - printf ("-p requires four arguments\n"); + fprintf (stderr, "-p requires four arguments\n"); exit(1); } @@ -545,7 +545,7 @@ static int no_audio(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(da static int set_audio(int argc, const char **argv, void *UNUSED(data)) { if (argc < 1) { - printf("-setaudio require one argument\n"); + fprintf(stderr, "-setaudio require one argument\n"); exit(1); } @@ -1007,6 +1007,10 @@ static int load_file(int UNUSED(argc), const char **argv, void *data) DAG_on_visible_update(CTX_data_main(C), TRUE); } + else { + /* failed to load file, stop processing arguments */ + return -1; + } /* WM_read_file() runs normally but since we're in background mode do here */ #ifdef WITH_PYTHON |