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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorBastien Montagne <montagne29@wanadoo.fr>2016-12-29 21:57:42 +0300
committerBastien Montagne <montagne29@wanadoo.fr>2016-12-29 22:05:22 +0300
commitf874aeef70f2f315c3062d9694ae816674d0cdd0 (patch)
treee2c8ddb8ecfc415d89225a081ae8755f355993bd /source
parent6ecab6dd8e48d564a2b43e0e81e79d079e8b4c77 (diff)
parentbf7d7bc323d5505b78688af2df1f66e1053f62e1 (diff)
Merge branch 'master' into blender2.8
Please **DO NOT** add changes from master when it's totally uneeded! Changes to BLI_ area most certainly shall *always* be done in master, there is absolutely no point in adding more diff between the two branches than needed, will only makes merging more cumbersome! Conflicts: CMakeLists.txt source/blender/blenlib/intern/math_vector_inline.c
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/intern/sound.c12
-rw-r--r--source/blender/blenlib/BLI_math_vector.h16
-rw-r--r--source/blender/blenlib/intern/math_geom.c6
-rw-r--r--source/blender/blenlib/intern/math_vector_inline.c29
-rw-r--r--source/blender/blenloader/intern/readfile.c9
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.c48
-rw-r--r--source/blender/editors/animation/anim_deps.c26
-rw-r--r--source/blender/editors/include/ED_util.h1
-rw-r--r--source/blender/editors/interface/interface_layout.c3
-rw-r--r--source/blender/editors/screen/screen_ops.c1
-rw-r--r--source/blender/editors/space_action/space_action.c13
-rw-r--r--source/blender/editors/space_image/image_ops.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_buttons.c6
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c7
-rw-r--r--source/blender/editors/util/undo.c18
-rw-r--r--source/blender/editors/uvedit/uvedit_unwrap_ops.c4
-rw-r--r--source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp4
-rw-r--r--source/blender/freestyle/intern/geometry/GeomUtils.cpp2
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp40
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapBuilder.h2
-rw-r--r--source/blender/makesrna/intern/rna_gpencil.c7
-rw-r--r--source/blender/makesrna/intern/rna_main_api.c127
-rw-r--r--source/blender/makesrna/intern/rna_mesh.c8
-rw-r--r--source/blender/makesrna/intern/rna_sequencer.c2
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c4
-rw-r--r--source/blender/python/intern/bpy_rna_anim.c104
26 files changed, 408 insertions, 93 deletions
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index f20885b1e8f..d5a395ffc4b 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -167,6 +167,10 @@ static const char *force_device = NULL;
#ifdef WITH_JACK
static void sound_sync_callback(void *data, int mode, float time)
{
+ // Ugly: Blender doesn't like it when the animation is played back during rendering
+ if (G.is_rendering)
+ return;
+
struct Main *bmain = (struct Main *)data;
struct Scene *scene;
@@ -693,6 +697,10 @@ void BKE_sound_seek_scene(struct Main *bmain, struct Scene *scene)
float BKE_sound_sync_scene(struct Scene *scene)
{
+ // Ugly: Blender doesn't like it when the animation is played back during rendering
+ if (G.is_rendering)
+ return NAN_FLT;
+
if (scene->playback_handle) {
if (scene->audio.flag & AUDIO_SYNC)
return AUD_getSynchronizerPosition(scene->playback_handle);
@@ -704,6 +712,10 @@ float BKE_sound_sync_scene(struct Scene *scene)
int BKE_sound_scene_playing(struct Scene *scene)
{
+ // Ugly: Blender doesn't like it when the animation is played back during rendering
+ if (G.is_rendering)
+ return -1;
+
if (scene->audio.flag & AUDIO_SYNC)
return AUD_isSynchronizerPlaying();
else
diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h
index fbecffc1270..f5beda0f13e 100644
--- a/source/blender/blenlib/BLI_math_vector.h
+++ b/source/blender/blenlib/BLI_math_vector.h
@@ -123,13 +123,13 @@ MINLINE void mul_v4_fl(float r[4], float f);
MINLINE void mul_v4_v4fl(float r[3], const float a[3], float f);
MINLINE void mul_v2_v2_cw(float r[2], const float mat[2], const float vec[2]);
MINLINE void mul_v2_v2_ccw(float r[2], const float mat[2], const float vec[2]);
-MINLINE float mul_project_m4_v3_zfac(const float mat[4][4], const float co[3]) ATTR_WARN_UNUSED_RESULT;
-MINLINE float dot_m3_v3_row_x(const float M[3][3], const float a[3]) ATTR_WARN_UNUSED_RESULT;
-MINLINE float dot_m3_v3_row_y(const float M[3][3], const float a[3]) ATTR_WARN_UNUSED_RESULT;
-MINLINE float dot_m3_v3_row_z(const float M[3][3], const float a[3]) ATTR_WARN_UNUSED_RESULT;
-MINLINE float dot_m4_v3_row_x(const float M[4][4], const float a[3]) ATTR_WARN_UNUSED_RESULT;
-MINLINE float dot_m4_v3_row_y(const float M[4][4], const float a[3]) ATTR_WARN_UNUSED_RESULT;
-MINLINE float dot_m4_v3_row_z(const float M[4][4], const float a[3]) ATTR_WARN_UNUSED_RESULT;
+MINLINE float mul_project_m4_v3_zfac(float mat[4][4], const float co[3]) ATTR_WARN_UNUSED_RESULT;
+MINLINE float dot_m3_v3_row_x(float M[3][3], const float a[3]) ATTR_WARN_UNUSED_RESULT;
+MINLINE float dot_m3_v3_row_y(float M[3][3], const float a[3]) ATTR_WARN_UNUSED_RESULT;
+MINLINE float dot_m3_v3_row_z(float M[3][3], const float a[3]) ATTR_WARN_UNUSED_RESULT;
+MINLINE float dot_m4_v3_row_x(float M[4][4], const float a[3]) ATTR_WARN_UNUSED_RESULT;
+MINLINE float dot_m4_v3_row_y(float M[4][4], const float a[3]) ATTR_WARN_UNUSED_RESULT;
+MINLINE float dot_m4_v3_row_z(float M[4][4], const float a[3]) ATTR_WARN_UNUSED_RESULT;
MINLINE void madd_v2_v2fl(float r[2], const float a[2], float f);
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f);
@@ -171,7 +171,7 @@ MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3]);
MINLINE void add_newell_cross_v3_v3v3(float n[3], const float v_prev[3], const float v_curr[3]);
-MINLINE void star_m3_v3(float rmat[3][3], const float a[3]);
+MINLINE void star_m3_v3(float rmat[3][3], float a[3]);
/*********************************** Length **********************************/
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index 38947e139ff..46d963ee268 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -3763,6 +3763,9 @@ void interp_barycentric_tri_v3(float data[3][3], float u, float v, float res[3])
/***************************** View & Projection *****************************/
+/**
+ * Matches `glOrtho` result.
+ */
void orthographic_m4(float matrix[4][4], const float left, const float right, const float bottom, const float top,
const float nearClip, const float farClip)
{
@@ -3783,6 +3786,9 @@ void orthographic_m4(float matrix[4][4], const float left, const float right, co
matrix[3][2] = -(farClip + nearClip) / Zdelta;
}
+/**
+ * Matches `glFrustum` result.
+ */
void perspective_m4(float mat[4][4], const float left, const float right, const float bottom, const float top,
const float nearClip, const float farClip)
{
diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c
index dbc46ffc233..ee5e8651bd3 100644
--- a/source/blender/blenlib/intern/math_vector_inline.c
+++ b/source/blender/blenlib/intern/math_vector_inline.c
@@ -479,8 +479,19 @@ MINLINE void mul_v2_v2_ccw(float r[2], const float mat[2], const float vec[2])
r[1] = mat[1] * vec[0] + (+mat[0]) * vec[1];
}
-/* note: could add a matrix inline */
-MINLINE float mul_project_m4_v3_zfac(const float mat[4][4], const float co[3])
+/**
+ * Convenience function to get the projected depth of a position.
+ * This avoids creating a temporary 4D vector and multiplying it - only for the 4th component.
+ *
+ * Matches logic for:
+ *
+ * \code{.c}
+ * float co_4d[4] = {co[0], co[1], co[2], 1.0};
+ * mul_m4_v4(mat, co_4d);
+ * return co_4d[3];
+ * \endcode
+ */
+MINLINE float mul_project_m4_v3_zfac(float mat[4][4], const float co[3])
{
return (mat[0][3] * co[0]) +
(mat[1][3] * co[1]) +
@@ -490,15 +501,15 @@ MINLINE float mul_project_m4_v3_zfac(const float mat[4][4], const float co[3])
/**
* Has the effect of #mul_m3_v3(), on a single axis.
*/
-MINLINE float dot_m3_v3_row_x(const float M[3][3], const float a[3])
+MINLINE float dot_m3_v3_row_x(float M[3][3], const float a[3])
{
return M[0][0] * a[0] + M[1][0] * a[1] + M[2][0] * a[2];
}
-MINLINE float dot_m3_v3_row_y(const float M[3][3], const float a[3])
+MINLINE float dot_m3_v3_row_y(float M[3][3], const float a[3])
{
return M[0][1] * a[0] + M[1][1] * a[1] + M[2][1] * a[2];
}
-MINLINE float dot_m3_v3_row_z(const float M[3][3], const float a[3])
+MINLINE float dot_m3_v3_row_z(float M[3][3], const float a[3])
{
return M[0][2] * a[0] + M[1][2] * a[1] + M[2][2] * a[2];
}
@@ -507,15 +518,15 @@ MINLINE float dot_m3_v3_row_z(const float M[3][3], const float a[3])
* Has the effect of #mul_mat3_m4_v3(), on a single axis.
* (no adding translation)
*/
-MINLINE float dot_m4_v3_row_x(const float M[4][4], const float a[3])
+MINLINE float dot_m4_v3_row_x(float M[4][4], const float a[3])
{
return M[0][0] * a[0] + M[1][0] * a[1] + M[2][0] * a[2];
}
-MINLINE float dot_m4_v3_row_y(const float M[4][4], const float a[3])
+MINLINE float dot_m4_v3_row_y(float M[4][4], const float a[3])
{
return M[0][1] * a[0] + M[1][1] * a[1] + M[2][1] * a[2];
}
-MINLINE float dot_m4_v3_row_z(const float M[4][4], const float a[3])
+MINLINE float dot_m4_v3_row_z(float M[4][4], const float a[3])
{
return M[0][2] * a[0] + M[1][2] * a[1] + M[2][2] * a[2];
}
@@ -745,7 +756,7 @@ MINLINE void add_newell_cross_v3_v3v3(float n[3], const float v_prev[3], const f
n[2] += (v_prev[0] - v_curr[0]) * (v_prev[1] + v_curr[1]);
}
-MINLINE void star_m3_v3(float rmat[3][3], const float a[3])
+MINLINE void star_m3_v3(float rmat[3][3], float a[3])
{
rmat[0][0] = rmat[1][1] = rmat[2][2] = 0.0;
rmat[0][1] = -a[2];
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index d3576a12b9c..0e1861abcf1 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -8385,6 +8385,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
static void do_versions_after_linking(Main *main)
{
+ UNUSED_VARS(main);
// printf("%s for %s (%s), %d.%d\n", __func__, main->curlib ? main->curlib->name : main->name,
// main->curlib ? "LIB" : "MAIN", main->versionfile, main->subversionfile);
}
@@ -9811,9 +9812,15 @@ static void give_base_to_objects(Main *mainvar, Scene *scene, View3D *v3d, Libra
if (active_lay) {
ob->lay = active_lay;
}
+ if (flag & FILE_AUTOSELECT) {
+ /* Note that link_object_postprocess() already checks for FILE_AUTOSELECT flag,
+ * but it will miss objects from non-instanciated groups... */
+ ob->flag |= SELECT;
+ /* do NOT make base active here! screws up GUI stuff, if you want it do it on src/ level */
+ }
- base->lay = ob->lay;
base->object = ob;
+ base->lay = ob->lay;
base->flag = ob->flag;
CLAMP_MIN(ob->id.us, 0);
diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c
index 8340be81aa8..05169a2a976 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -57,6 +57,7 @@
#define BEVEL_EPSILON_ANG DEG2RADF(2.0f)
#define BEVEL_SMALL_ANG DEG2RADF(10.0f)
#define BEVEL_MAX_ADJUST_PCT 10.0f
+#define BEVEL_MAX_AUTO_ADJUST_PCT 300.0f
/* happens far too often, uncomment for development */
// #define BEVEL_ASSERT_PROJECT
@@ -323,15 +324,33 @@ static bool edge_half_offset_changed(EdgeHalf *e)
e->offset_r != e->offset_r_spec;
}
-static bool any_edge_half_offset_changed(BevVert *bv)
+static float adjusted_rel_change(float val, float spec)
+{
+ float relchg;
+
+ relchg = 0.0f;
+ if (val != spec) {
+ if (spec == 0)
+ relchg = 1000.0f; /* arbitrary large value */
+ else
+ relchg = fabsf((val - spec) / spec);
+ }
+ return relchg;
+}
+
+static float max_edge_half_offset_rel_change(BevVert *bv)
{
int i;
+ float max_rel_change;
+ EdgeHalf *e;
+ max_rel_change = 0.0f;
for (i = 0; i < bv->edgecount; i++) {
- if (edge_half_offset_changed(&bv->edges[i]))
- return true;
+ e = &bv->edges[i];
+ max_rel_change = max_ff(max_rel_change, adjusted_rel_change(e->offset_l, e->offset_l_spec));
+ max_rel_change = max_ff(max_rel_change, adjusted_rel_change(e->offset_r, e->offset_r_spec));
}
- return false;
+ return max_rel_change;
}
/* Return the next EdgeHalf after from_e that is beveled.
@@ -1951,6 +1970,7 @@ static void adjust_offsets(BevelParams *bp)
GHashIterator giter;
EdgeHalf *e, *efirst, *eother;
GSQueue *q;
+ float max_rel_adj;
BLI_assert(!bp->vertex_only);
GHASH_ITER(giter, bp->vert_hash) {
@@ -1966,7 +1986,7 @@ static void adjust_offsets(BevelParams *bp)
searchi = -1;
GHASH_ITER(giter, bp->vert_hash) {
bv = BLI_ghashIterator_getValue(&giter);
- if (!bv->visited && any_edge_half_offset_changed(bv)) {
+ if (!bv->visited && max_edge_half_offset_rel_change(bv) > 0.0f) {
i = BM_elem_index_get(bv->v);
if (!searchbv || i < searchi) {
searchbv = bv;
@@ -1996,6 +2016,24 @@ static void adjust_offsets(BevelParams *bp)
}
}
BLI_gsqueue_free(q);
+
+ /* Should we auto-limit the error accumulation? Typically, spirals can lead to 100x relative adjustments,
+ * and somewhat hacky mechanism of using bp->limit_offset to indicate "clamp the adjustments" is not
+ * obvious to users, who almost certainaly want clamping in this situation.
+ * The reason not to clamp always is that some models work better without it (e.g., Bent_test in regression
+ * suite, where relative adjust maximum is about .6). */
+ if (!bp->limit_offset) {
+ max_rel_adj = 0.0f;
+ GHASH_ITER(giter, bp->vert_hash) {
+ bv = BLI_ghashIterator_getValue(&giter);
+ max_rel_adj = max_ff(max_rel_adj, max_edge_half_offset_rel_change(bv));
+ }
+ if (max_rel_adj > BEVEL_MAX_AUTO_ADJUST_PCT / 100.0f) {
+ bp->limit_offset = true;
+ adjust_offsets(bp);
+ bp->limit_offset = false;
+ }
+ }
}
/* Do the edges at bv form a "pipe"?
diff --git a/source/blender/editors/animation/anim_deps.c b/source/blender/editors/animation/anim_deps.c
index 437dd2b2de2..cc77a321a89 100644
--- a/source/blender/editors/animation/anim_deps.c
+++ b/source/blender/editors/animation/anim_deps.c
@@ -309,6 +309,28 @@ static void animchan_sync_fcurve(bAnimContext *ac, bAnimListElem *ale, FCurve **
}
}
+/* perform syncing updates for GPencil Layers */
+static void animchan_sync_gplayer(bAnimContext *UNUSED(ac), bAnimListElem *ale)
+{
+ bGPDlayer *gpl = (bGPDlayer *)ale->data;
+
+ /* Make sure the selection flags agree with the "active" flag.
+ * The selection flags are used in the Dopesheet only, whereas
+ * the active flag is used everywhere else. Hence, we try to
+ * sync these here so that it all seems to be have as the user
+ * expects - T50184
+ *
+ * Assume that we only really do this when the active status changes.
+ * (NOTE: This may prove annoying if it means selection is always lost)
+ */
+ if (gpl->flag & GP_LAYER_ACTIVE) {
+ gpl->flag |= GP_LAYER_SELECT;
+ }
+ else {
+ gpl->flag &= ~GP_LAYER_SELECT;
+ }
+}
+
/* ---------------- */
/* Main call to be exported to animation editors */
@@ -343,6 +365,10 @@ void ANIM_sync_animchannels_to_data(const bContext *C)
case ANIMTYPE_FCURVE:
animchan_sync_fcurve(&ac, ale, &active_fcurve);
break;
+
+ case ANIMTYPE_GPLAYER:
+ animchan_sync_gplayer(&ac, ale);
+ break;
}
}
diff --git a/source/blender/editors/include/ED_util.h b/source/blender/editors/include/ED_util.h
index a4afa958450..60c4b3593aa 100644
--- a/source/blender/editors/include/ED_util.h
+++ b/source/blender/editors/include/ED_util.h
@@ -60,6 +60,7 @@ void ED_undo_redo(struct bContext *C);
void ED_OT_undo(struct wmOperatorType *ot);
void ED_OT_undo_push(struct wmOperatorType *ot);
void ED_OT_redo(struct wmOperatorType *ot);
+void ED_OT_undo_redo(struct wmOperatorType *ot);
void ED_OT_undo_history(struct wmOperatorType *ot);
int ED_undo_operator_repeat(struct bContext *C, struct wmOperator *op);
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 80d091c0fdb..940e982d326 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -1463,8 +1463,9 @@ void uiItemEnumR_string(uiLayout *layout, struct PointerRNA *ptr, const char *pr
for (a = 0; item[a].identifier; a++) {
if (item[a].value == ivalue) {
const char *item_name = name ? name : CTX_IFACE_(RNA_property_translation_context(prop), item[a].name);
+ const int flag = item_name[0] ? 0 : UI_ITEM_R_ICON_ONLY;
- uiItemFullR(layout, ptr, prop, RNA_ENUM_VALUE, ivalue, 0, item_name, icon ? icon : item[a].icon);
+ uiItemFullR(layout, ptr, prop, RNA_ENUM_VALUE, ivalue, flag, item_name, icon ? icon : item[a].icon);
break;
}
}
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 681b5954512..32b63aca34c 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -4334,6 +4334,7 @@ void ED_operatortypes_screen(void)
WM_operatortype_append(ED_OT_undo);
WM_operatortype_append(ED_OT_undo_push);
WM_operatortype_append(ED_OT_redo);
+ WM_operatortype_append(ED_OT_undo_redo);
WM_operatortype_append(ED_OT_undo_history);
WM_operatortype_append(ED_OT_flush_edits);
diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c
index 671d6bb083e..83655a2ba9e 100644
--- a/source/blender/editors/space_action/space_action.c
+++ b/source/blender/editors/space_action/space_action.c
@@ -337,7 +337,7 @@ static void action_channel_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(
}
break;
case NC_GPENCIL:
- if (wmn->action == NA_RENAME)
+ if (ELEM(wmn->action, NA_RENAME, NA_SELECTED))
ED_region_tag_redraw(ar);
break;
case NC_ID:
@@ -407,10 +407,15 @@ static void action_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn)
/* context changes */
switch (wmn->category) {
case NC_GPENCIL:
- if (wmn->action == NA_EDITED) {
- /* only handle this event in GPencil mode for performance considerations */
- if (saction->mode == SACTCONT_GPENCIL)
+ /* only handle these events in GPencil mode for performance considerations */
+ if (saction->mode == SACTCONT_GPENCIL) {
+ if (wmn->action == NA_EDITED) {
ED_area_tag_redraw(sa);
+ }
+ else if (wmn->action == NA_SELECTED) {
+ saction->flag |= SACTION_TEMP_NEEDCHANSYNC;
+ ED_area_tag_refresh(sa);
+ }
}
break;
case NC_ANIMATION:
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 6a1c0e7e4bf..324a3cb13b7 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -1475,7 +1475,7 @@ static int image_match_len_exec(bContext *C, wmOperator *UNUSED(op))
if (!ima || !iuser || !BKE_image_has_anim(ima))
return OPERATOR_CANCELLED;
- struct ImageAnim *anim = ((ImageAnim *)ima->anims.first)->anim;
+ struct anim *anim = ((ImageAnim *)ima->anims.first)->anim;
if (!anim)
return OPERATOR_CANCELLED;
iuser->frames = IMB_anim_get_duration(anim, IMB_TC_RECORD_RUN);
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index b9c8c98b62f..351c7ccec15 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -476,7 +476,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
uiDefButF(block, UI_BTYPE_NUM, B_OBJECTPANELMEDIAN,
totedgedata == 1 ? IFACE_("Crease:") : IFACE_("Mean Crease:"),
0, yi -= buth + but_margin, 200, buth,
- &(tfp->ve_median[M_CREASE]), 0.0, 1.0, 1, 2, TIP_("Weight used by SubSurf modifier"));
+ &(tfp->ve_median[M_CREASE]), 0.0, 1.0, 1, 2, TIP_("Weight used by the Subdivision Surface modifier"));
}
}
/* Curve... */
@@ -491,7 +491,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
else if (totcurvedata > 1) {
uiDefButF(block, UI_BTYPE_NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Weight:"),
0, yi -= buth + but_margin, 200, buth,
- &(tfp->ve_median[C_WEIGHT]), 0.0, 1.0, 1, 3, TIP_("Weight used for SoftBody Goal"));
+ &(tfp->ve_median[C_WEIGHT]), 0.0, 1.0, 1, 3, TIP_("Weight used for Soft Body Goal"));
uiDefButF(block, UI_BTYPE_NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Radius:"),
0, yi -= buth + but_margin, 200, buth,
&(tfp->ve_median[C_RADIUS]), 0.0, 100.0, 1, 3, TIP_("Radius of curve control points"));
@@ -509,7 +509,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
else if (totlattdata > 1) {
uiDefButF(block, UI_BTYPE_NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Weight:"),
0, yi -= buth + but_margin, 200, buth,
- &(tfp->ve_median[L_WEIGHT]), 0.0, 1.0, 1, 3, TIP_("Weight used for SoftBody Goal"));
+ &(tfp->ve_median[L_WEIGHT]), 0.0, 1.0, 1, 3, TIP_("Weight used for Soft Body Goal"));
}
UI_block_align_end(block);
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index 620bbf03f32..2b53eb71d99 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -4064,6 +4064,9 @@ static int vieworbit_exec(bContext *C, wmOperator *op)
mul_qt_qtqt(quat_new, rv3d->viewquat, quat_mul);
+ /* avoid precision loss over time */
+ normalize_qt(quat_new);
+
if (view_opposite != RV3D_VIEW_USER) {
rv3d->view = view_opposite;
/* avoid float in-precision, just get a new orientation */
@@ -4130,6 +4133,10 @@ static void view_roll_angle(ARegion *ar, float quat[4], const float orig_quat[4]
axis_angle_normalized_to_quat(quat_mul, dvec, angle);
mul_qt_qtqt(quat, orig_quat, quat_mul);
+
+ /* avoid precision loss over time */
+ normalize_qt(quat);
+
rv3d->view = RV3D_VIEW_USER;
}
diff --git a/source/blender/editors/util/undo.c b/source/blender/editors/util/undo.c
index 4a9311416b3..fab5b7e821f 100644
--- a/source/blender/editors/util/undo.c
+++ b/source/blender/editors/util/undo.c
@@ -327,6 +327,13 @@ static int ed_redo_exec(bContext *C, wmOperator *UNUSED(op))
return ed_undo_step(C, -1, NULL);
}
+static int ed_undo_redo_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ wmOperator *last_op = WM_operator_last_redo(C);
+ const int ret = ED_undo_operator_repeat(C, last_op);
+ return ret ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
+}
+
/* ********************** */
@@ -369,6 +376,17 @@ void ED_OT_redo(wmOperatorType *ot)
ot->poll = ED_operator_screenactive;
}
+void ED_OT_undo_redo(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Undo and Redo";
+ ot->description = "Undo and redo previous action";
+ ot->idname = "ED_OT_undo_redo";
+
+ /* api callbacks */
+ ot->exec = ed_undo_redo_exec;
+ ot->poll = ED_operator_screenactive;
+}
/* ui callbacks should call this rather than calling WM_operator_repeat() themselves */
int ED_undo_operator_repeat(bContext *C, struct wmOperator *op)
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
index 8e4ba4c0afa..d8080002818 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
@@ -1222,7 +1222,7 @@ static int unwrap_exec(bContext *C, wmOperator *op)
* pass operator for warning append */
modifier_unwrap_state(obedit, scene, &use_subsurf_final);
if (use_subsurf != use_subsurf_final)
- BKE_report(op->reports, RPT_INFO, "Subsurf modifier needs to be first to work with unwrap");
+ BKE_report(op->reports, RPT_INFO, "Subdivision Surface modifier needs to be first to work with unwrap");
/* execute unwrap */
ED_unwrap_lscm(scene, obedit, true);
@@ -1259,7 +1259,7 @@ void UV_OT_unwrap(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "correct_aspect", 1, "Correct Aspect",
"Map UVs taking image aspect ratio into account");
RNA_def_boolean(ot->srna, "use_subsurf_data", 0, "Use Subsurf Modifier",
- "Map UVs taking vertex position after subsurf into account");
+ "Map UVs taking vertex position after Subdivision Surface modifier has been applied");
RNA_def_float_factor(ot->srna, "margin", 0.001f, 0.0f, 1.0f, "Margin", "Space between islands", 0.0f, 1.0f);
}
diff --git a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
index 2af4447e4dc..223bc607e21 100644
--- a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
+++ b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
@@ -433,8 +433,8 @@ static void prepare(Render *re, SceneRenderLayer *srl)
cout << "Crease angle : " << controller->getCreaseAngle() << endl;
cout << "Sphere radius : " << controller->getSphereRadius() << endl;
cout << "Face smoothness : " << (controller->getFaceSmoothness() ? "enabled" : "disabled") << endl;
- cout << "Redges and valleys : " << (controller->getComputeRidgesAndValleysFlag() ? "enabled" : "disabled") <<
- endl;
+ cout << "Ridges and valleys : " <<
+ (controller->getComputeRidgesAndValleysFlag() ? "enabled" : "disabled") << endl;
cout << "Suggestive contours : " <<
(controller->getComputeSuggestiveContoursFlag() ? "enabled" : "disabled") << endl;
cout << "Suggestive contour Kr derivative epsilon : " <<
diff --git a/source/blender/freestyle/intern/geometry/GeomUtils.cpp b/source/blender/freestyle/intern/geometry/GeomUtils.cpp
index 3eb92c559fe..cd7c1b83a4e 100644
--- a/source/blender/freestyle/intern/geometry/GeomUtils.cpp
+++ b/source/blender/freestyle/intern/geometry/GeomUtils.cpp
@@ -470,6 +470,8 @@ bool intersectRayTriangle(const Vec3r& orig, const Vec3r& dir, const Vec3r& v0,
}
// Intersection between plane and ray, adapted from Graphics Gems, Didier Badouel
+// The plane is represented by a set of points P implicitly defined as dot(norm, P) + d = 0.
+// The ray is represented as r(t) = orig + dir * t.
intersection_test intersectRayPlane(const Vec3r& orig, const Vec3r& dir, const Vec3r& norm, const real d,
real& t, const real epsilon)
{
diff --git a/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp b/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp
index 380bb0dd3ca..794c782bb73 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp
+++ b/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp
@@ -57,7 +57,7 @@ using namespace std;
template <typename G, typename I>
static void findOccludee(FEdge *fe, G& /*grid*/, I& occluders, real epsilon, WFace **oaWFace,
- Vec3r& u, Vec3r& A, Vec3r& origin, Vec3r& edge, vector<WVertex*>& faceVertices)
+ Vec3r& u, Vec3r& A, Vec3r& origin, Vec3r& edgeDir, vector<WVertex*>& faceVertices)
{
WFace *face = NULL;
if (fe->isSmooth()) {
@@ -125,7 +125,7 @@ static void findOccludee(FEdge *fe, G& /*grid*/, I& occluders, real epsilon, WFa
// check whether the edge and the polygon plane are coincident:
//-------------------------------------------------------------
//first let us compute the plane equation.
- if (GeomUtils::COINCIDENT == GeomUtils::intersectRayPlane(origin, edge, p->getNormal(), d, t, epsilon))
+ if (GeomUtils::COINCIDENT == GeomUtils::intersectRayPlane(origin, edgeDir, p->getNormal(), d, t, epsilon))
{
#if LOGGING
if (_global.debug & G_DEBUG_FREESTYLE) {
@@ -172,10 +172,11 @@ template <typename G, typename I>
static void findOccludee(FEdge *fe, G& grid, real epsilon, ViewEdge * /*ve*/, WFace **oaFace)
{
Vec3r A;
- Vec3r edge;
+ Vec3r edgeDir;
Vec3r origin;
A = Vec3r(((fe)->vertexA()->point3D() + (fe)->vertexB()->point3D()) / 2.0);
- edge = Vec3r((fe)->vertexB()->point3D() - (fe)->vertexA()->point3D());
+ edgeDir = Vec3r((fe)->vertexB()->point3D() - (fe)->vertexA()->point3D());
+ edgeDir.normalize();
origin = Vec3r((fe)->vertexA()->point3D());
Vec3r u;
if (grid.orthographicProjection()) {
@@ -199,7 +200,7 @@ static void findOccludee(FEdge *fe, G& grid, real epsilon, ViewEdge * /*ve*/, WF
}
I occluders(grid, A, epsilon);
- findOccludee<G, I>(fe, grid, occluders, epsilon, oaFace, u, A, origin, edge, faceVertices);
+ findOccludee<G, I>(fe, grid, occluders, epsilon, oaFace, u, A, origin, edgeDir, faceVertices);
}
// computeVisibility takes a pointer to foundOccluders, instead of using a reference,
@@ -211,11 +212,12 @@ static int computeVisibility(ViewMap *viewMap, FEdge *fe, G& grid, real epsilon,
int qi = 0;
Vec3r center;
- Vec3r edge;
+ Vec3r edgeDir;
Vec3r origin;
center = fe->center3d();
- edge = Vec3r(fe->vertexB()->point3D() - fe->vertexA()->point3D());
+ edgeDir = Vec3r(fe->vertexB()->point3D() - fe->vertexA()->point3D());
+ edgeDir.normalize();
origin = Vec3r(fe->vertexA()->point3D());
Vec3r vp;
@@ -337,7 +339,7 @@ static int computeVisibility(ViewMap *viewMap, FEdge *fe, G& grid, real epsilon,
// check whether the edge and the polygon plane are coincident:
//-------------------------------------------------------------
//first let us compute the plane equation.
- if (GeomUtils::COINCIDENT == GeomUtils::intersectRayPlane(origin, edge, p->getNormal(), d, t, epsilon)) {
+ if (GeomUtils::COINCIDENT == GeomUtils::intersectRayPlane(origin, edgeDir, p->getNormal(), d, t, epsilon)) {
#if LOGGING
if (_global.debug & G_DEBUG_FREESTYLE) {
cout << "\t\tRejecting occluder for target coincidence." << endl;
@@ -391,7 +393,7 @@ static int computeVisibility(ViewMap *viewMap, FEdge *fe, G& grid, real epsilon,
}
// Find occludee
- findOccludee<G, I>(fe, grid, occluders, epsilon, oaWFace, u, center, origin, edge, faceVertices);
+ findOccludee<G, I>(fe, grid, occluders, epsilon, oaWFace, u, center, origin, edgeDir, faceVertices);
return qi;
}
@@ -1788,7 +1790,7 @@ void ViewMapBuilder::ComputeVeryFastRayCastingVisibility(ViewMap *ioViewMap, rea
}
void ViewMapBuilder::FindOccludee(FEdge *fe, Grid *iGrid, real epsilon, Polygon3r **oaPolygon, unsigned timestamp,
- Vec3r& u, Vec3r& A, Vec3r& origin, Vec3r& edge, vector<WVertex*>& faceVertices)
+ Vec3r& u, Vec3r& A, Vec3r& origin, Vec3r& edgeDir, vector<WVertex*>& faceVertices)
{
WFace *face = NULL;
if (fe->isSmooth()) {
@@ -1856,7 +1858,7 @@ void ViewMapBuilder::FindOccludee(FEdge *fe, Grid *iGrid, real epsilon, Polygon3
continue;
}
else {
- if (GeomUtils::COINCIDENT == GeomUtils::intersectRayPlane(origin, edge, normal, d, t, epsilon))
+ if (GeomUtils::COINCIDENT == GeomUtils::intersectRayPlane(origin, edgeDir, normal, d, t, epsilon))
continue;
}
if ((*p)->rayIntersect(A, v, t, t_u, t_v)) {
@@ -1883,10 +1885,11 @@ void ViewMapBuilder::FindOccludee(FEdge *fe, Grid *iGrid, real epsilon, Polygon3
OccludersSet occluders;
Vec3r A;
- Vec3r edge;
+ Vec3r edgeDir;
Vec3r origin;
A = Vec3r(((fe)->vertexA()->point3D() + (fe)->vertexB()->point3D()) / 2.0);
- edge = Vec3r((fe)->vertexB()->point3D() - (fe)->vertexA()->point3D());
+ edgeDir = Vec3r((fe)->vertexB()->point3D() - (fe)->vertexA()->point3D());
+ edgeDir.normalize();
origin = Vec3r((fe)->vertexA()->point3D());
Vec3r u;
if (_orthographicProjection) {
@@ -1910,7 +1913,7 @@ void ViewMapBuilder::FindOccludee(FEdge *fe, Grid *iGrid, real epsilon, Polygon3
if (face)
face->RetrieveVertexList(faceVertices);
- return FindOccludee(fe, iGrid, epsilon, oaPolygon, timestamp, u, A, origin, edge, faceVertices);
+ return FindOccludee(fe, iGrid, epsilon, oaPolygon, timestamp, u, A, origin, edgeDir, faceVertices);
}
int ViewMapBuilder::ComputeRayCastingVisibility(FEdge *fe, Grid *iGrid, real epsilon, set<ViewShape*>& oOccluders,
@@ -1920,11 +1923,12 @@ int ViewMapBuilder::ComputeRayCastingVisibility(FEdge *fe, Grid *iGrid, real eps
int qi = 0;
Vec3r center;
- Vec3r edge;
+ Vec3r edgeDir;
Vec3r origin;
center = fe->center3d();
- edge = Vec3r(fe->vertexB()->point3D() - fe->vertexA()->point3D());
+ edgeDir = Vec3r(fe->vertexB()->point3D() - fe->vertexA()->point3D());
+ edgeDir.normalize();
origin = Vec3r(fe->vertexA()->point3D());
// Is the edge outside the view frustum ?
Vec3r gridOrigin(iGrid->getOrigin());
@@ -2062,7 +2066,7 @@ int ViewMapBuilder::ComputeRayCastingVisibility(FEdge *fe, Grid *iGrid, real eps
//-------------------------------------------------------------
//first let us compute the plane equation.
- if (GeomUtils::COINCIDENT == GeomUtils::intersectRayPlane(origin, edge, normal, d, t, epsilon)) {
+ if (GeomUtils::COINCIDENT == GeomUtils::intersectRayPlane(origin, edgeDir, normal, d, t, epsilon)) {
#if LOGGING
if (_global.debug & G_DEBUG_FREESTYLE) {
cout << "\t\tRejecting occluder for target coincidence." << endl;
@@ -2099,7 +2103,7 @@ int ViewMapBuilder::ComputeRayCastingVisibility(FEdge *fe, Grid *iGrid, real eps
}
// Find occludee
- FindOccludee(fe, iGrid, epsilon, oaPolygon, timestamp, u, center, origin, edge, faceVertices);
+ FindOccludee(fe, iGrid, epsilon, oaPolygon, timestamp, u, center, origin, edgeDir, faceVertices);
return qi;
}
diff --git a/source/blender/freestyle/intern/view_map/ViewMapBuilder.h b/source/blender/freestyle/intern/view_map/ViewMapBuilder.h
index 36497bf8d22..440ae93c7df 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapBuilder.h
+++ b/source/blender/freestyle/intern/view_map/ViewMapBuilder.h
@@ -250,7 +250,7 @@ protected:
// FIXME
void FindOccludee(FEdge *fe, Grid *iGrid, real epsilon, Polygon3r **oaPolygon, unsigned timestamp);
void FindOccludee(FEdge *fe, Grid *iGrid, real epsilon, Polygon3r **oaPolygon, unsigned timestamp,
- Vec3r& u, Vec3r& A, Vec3r& origin, Vec3r& edge, vector<WVertex*>& faceVertices);
+ Vec3r& u, Vec3r& A, Vec3r& origin, Vec3r& edgeDir, vector<WVertex*>& faceVertices);
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewMapBuilder")
diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c
index 69ee671901a..41a73cfc528 100644
--- a/source/blender/makesrna/intern/rna_gpencil.c
+++ b/source/blender/makesrna/intern/rna_gpencil.c
@@ -1276,13 +1276,13 @@ static void rna_def_gpencil_layer(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_ACTIVE);
RNA_def_property_boolean_funcs(prop, NULL, "rna_GPencilLayer_active_set");
RNA_def_property_ui_text(prop, "Active", "Set active layer for editing");
- RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
+ RNA_def_property_update(prop, NC_GPENCIL | ND_DATA | NA_SELECTED, NULL);
#endif
prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_SELECT);
RNA_def_property_ui_text(prop, "Select", "Layer is selected for editing in the Dope Sheet");
- RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
+ RNA_def_property_update(prop, NC_GPENCIL | ND_DATA | NA_SELECTED, "rna_GPencil_update");
/* XXX keep this option? */
prop = RNA_def_property(srna, "show_points", PROP_BOOLEAN, PROP_NONE);
@@ -1370,14 +1370,15 @@ static void rna_def_gpencil_layers_api(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_property_pointer_funcs(prop, "rna_GPencil_active_layer_get", "rna_GPencil_active_layer_set", NULL, NULL);
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Active Layer", "Active grease pencil layer");
+ RNA_def_property_update(prop, NC_GPENCIL | ND_DATA | NA_SELECTED, NULL);
prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED);
-
RNA_def_property_int_funcs(prop,
"rna_GPencil_active_layer_index_get",
"rna_GPencil_active_layer_index_set",
"rna_GPencil_active_layer_index_range");
RNA_def_property_ui_text(prop, "Active Layer Index", "Index of active grease pencil layer");
+ RNA_def_property_update(prop, NC_GPENCIL | ND_DATA | NA_SELECTED, NULL);
}
static void rna_def_gpencil_palettecolor(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c
index 673f7acbd6a..244820f5a49 100644
--- a/source/blender/makesrna/intern/rna_main_api.c
+++ b/source/blender/makesrna/intern/rna_main_api.c
@@ -116,6 +116,13 @@
#endif
+static void rna_idname_validate(const char *name, char *r_name)
+{
+ BLI_strncpy(r_name, name, MAX_ID_NAME - 2);
+ BLI_utf8_invalid_strip(r_name, strlen(r_name));
+}
+
+
static void rna_Main_ID_remove(Main *bmain, ReportList *reports, PointerRNA *id_ptr, int do_unlink)
{
ID *id = id_ptr->data;
@@ -137,14 +144,20 @@ static void rna_Main_ID_remove(Main *bmain, ReportList *reports, PointerRNA *id_
static Camera *rna_Main_cameras_new(Main *bmain, const char *name)
{
- ID *id = BKE_camera_add(bmain, name);
+ char safe_name[MAX_ID_NAME - 2];
+ rna_idname_validate(name, safe_name);
+
+ ID *id = BKE_camera_add(bmain, safe_name);
id_us_min(id);
return (Camera *)id;
}
static Scene *rna_Main_scenes_new(Main *bmain, const char *name)
{
- return BKE_scene_add(bmain, name);
+ char safe_name[MAX_ID_NAME - 2];
+ rna_idname_validate(name, safe_name);
+
+ return BKE_scene_add(bmain, safe_name);
}
static void rna_Main_scenes_remove(Main *bmain, bContext *C, ReportList *reports, PointerRNA *scene_ptr, int do_unlink)
{
@@ -180,6 +193,9 @@ static void rna_Main_scenes_remove(Main *bmain, bContext *C, ReportList *reports
static Object *rna_Main_objects_new(Main *bmain, ReportList *reports, const char *name, ID *data)
{
+ char safe_name[MAX_ID_NAME - 2];
+ rna_idname_validate(name, safe_name);
+
Object *ob;
int type = OB_EMPTY;
if (data) {
@@ -223,7 +239,7 @@ static Object *rna_Main_objects_new(Main *bmain, ReportList *reports, const char
id_us_plus(data);
}
- ob = BKE_object_add_only_object(bmain, type, name);
+ ob = BKE_object_add_only_object(bmain, type, safe_name);
id_us_min(&ob->id);
ob->data = data;
@@ -234,7 +250,10 @@ static Object *rna_Main_objects_new(Main *bmain, ReportList *reports, const char
static Material *rna_Main_materials_new(Main *bmain, const char *name)
{
- ID *id = (ID *)BKE_material_add(bmain, name);
+ char safe_name[MAX_ID_NAME - 2];
+ rna_idname_validate(name, safe_name);
+
+ ID *id = (ID *)BKE_material_add(bmain, safe_name);
id_us_min(id);
return (Material *)id;
}
@@ -245,20 +264,27 @@ static EnumPropertyItem *rna_Main_nodetree_type_itemf(bContext *UNUSED(C), Point
}
static struct bNodeTree *rna_Main_nodetree_new(Main *bmain, const char *name, int type)
{
+ char safe_name[MAX_ID_NAME - 2];
+ rna_idname_validate(name, safe_name);
+
bNodeTreeType *typeinfo = rna_node_tree_type_from_enum(type);
if (typeinfo) {
- bNodeTree *ntree = ntreeAddTree(bmain, name, typeinfo->idname);
+ bNodeTree *ntree = ntreeAddTree(bmain, safe_name, typeinfo->idname);
id_us_min(&ntree->id);
return ntree;
}
- else
+ else {
return NULL;
+ }
}
static Mesh *rna_Main_meshes_new(Main *bmain, const char *name)
{
- Mesh *me = BKE_mesh_add(bmain, name);
+ char safe_name[MAX_ID_NAME - 2];
+ rna_idname_validate(name, safe_name);
+
+ Mesh *me = BKE_mesh_add(bmain, safe_name);
id_us_min(&me->id);
return me;
}
@@ -286,7 +312,10 @@ Mesh *rna_Main_meshes_new_from_object(
static Lamp *rna_Main_lamps_new(Main *bmain, const char *name, int type)
{
- Lamp *lamp = BKE_lamp_add(bmain, name);
+ char safe_name[MAX_ID_NAME - 2];
+ rna_idname_validate(name, safe_name);
+
+ Lamp *lamp = BKE_lamp_add(bmain, safe_name);
lamp->type = type;
id_us_min(&lamp->id);
return lamp;
@@ -294,8 +323,11 @@ static Lamp *rna_Main_lamps_new(Main *bmain, const char *name, int type)
static Image *rna_Main_images_new(Main *bmain, const char *name, int width, int height, int alpha, int float_buffer, int stereo3d)
{
+ char safe_name[MAX_ID_NAME - 2];
+ rna_idname_validate(name, safe_name);
+
float color[4] = {0.0, 0.0, 0.0, 1.0};
- Image *image = BKE_image_add_generated(bmain, width, height, name, alpha ? 32 : 24, float_buffer, 0, color, stereo3d);
+ Image *image = BKE_image_add_generated(bmain, width, height, safe_name, alpha ? 32 : 24, float_buffer, 0, color, stereo3d);
id_us_min(&image->id);
return image;
}
@@ -322,21 +354,30 @@ static Image *rna_Main_images_load(Main *bmain, ReportList *reports, const char
static Lattice *rna_Main_lattices_new(Main *bmain, const char *name)
{
- Lattice *lt = BKE_lattice_add(bmain, name);
+ char safe_name[MAX_ID_NAME - 2];
+ rna_idname_validate(name, safe_name);
+
+ Lattice *lt = BKE_lattice_add(bmain, safe_name);
id_us_min(&lt->id);
return lt;
}
static Curve *rna_Main_curves_new(Main *bmain, const char *name, int type)
{
- Curve *cu = BKE_curve_add(bmain, name, type);
+ char safe_name[MAX_ID_NAME - 2];
+ rna_idname_validate(name, safe_name);
+
+ Curve *cu = BKE_curve_add(bmain, safe_name, type);
id_us_min(&cu->id);
return cu;
}
static MetaBall *rna_Main_metaballs_new(Main *bmain, const char *name)
{
- MetaBall *mb = BKE_mball_add(bmain, name);
+ char safe_name[MAX_ID_NAME - 2];
+ rna_idname_validate(name, safe_name);
+
+ MetaBall *mb = BKE_mball_add(bmain, safe_name);
id_us_min(&mb->id);
return mb;
}
@@ -364,7 +405,10 @@ static VFont *rna_Main_fonts_load(Main *bmain, ReportList *reports, const char *
static Tex *rna_Main_textures_new(Main *bmain, const char *name, int type)
{
- Tex *tex = BKE_texture_add(bmain, name);
+ char safe_name[MAX_ID_NAME - 2];
+ rna_idname_validate(name, safe_name);
+
+ Tex *tex = BKE_texture_add(bmain, safe_name);
BKE_texture_type_set(tex, type);
id_us_min(&tex->id);
return tex;
@@ -372,26 +416,38 @@ static Tex *rna_Main_textures_new(Main *bmain, const char *name, int type)
static Brush *rna_Main_brushes_new(Main *bmain, const char *name, int mode)
{
- Brush *brush = BKE_brush_add(bmain, name, mode);
+ char safe_name[MAX_ID_NAME - 2];
+ rna_idname_validate(name, safe_name);
+
+ Brush *brush = BKE_brush_add(bmain, safe_name, mode);
id_us_min(&brush->id);
return brush;
}
static World *rna_Main_worlds_new(Main *bmain, const char *name)
{
- World *world = add_world(bmain, name);
+ char safe_name[MAX_ID_NAME - 2];
+ rna_idname_validate(name, safe_name);
+
+ World *world = add_world(bmain, safe_name);
id_us_min(&world->id);
return world;
}
static Group *rna_Main_groups_new(Main *bmain, const char *name)
{
- return BKE_group_add(bmain, name);
+ char safe_name[MAX_ID_NAME - 2];
+ rna_idname_validate(name, safe_name);
+
+ return BKE_group_add(bmain, safe_name);
}
static Speaker *rna_Main_speakers_new(Main *bmain, const char *name)
{
- Speaker *speaker = BKE_speaker_add(bmain, name);
+ char safe_name[MAX_ID_NAME - 2];
+ rna_idname_validate(name, safe_name);
+
+ Speaker *speaker = BKE_speaker_add(bmain, safe_name);
id_us_min(&speaker->id);
return speaker;
}
@@ -413,7 +469,10 @@ static bSound *rna_Main_sounds_load(Main *bmain, const char *name, int check_exi
static Text *rna_Main_texts_new(Main *bmain, const char *name)
{
- return BKE_text_add(bmain, name);
+ char safe_name[MAX_ID_NAME - 2];
+ rna_idname_validate(name, safe_name);
+
+ return BKE_text_add(bmain, safe_name);
}
static Text *rna_Main_texts_load(Main *bmain, ReportList *reports, const char *filepath, int is_internal)
@@ -432,28 +491,40 @@ static Text *rna_Main_texts_load(Main *bmain, ReportList *reports, const char *f
static bArmature *rna_Main_armatures_new(Main *bmain, const char *name)
{
- bArmature *arm = BKE_armature_add(bmain, name);
+ char safe_name[MAX_ID_NAME - 2];
+ rna_idname_validate(name, safe_name);
+
+ bArmature *arm = BKE_armature_add(bmain, safe_name);
id_us_min(&arm->id);
return arm;
}
static bAction *rna_Main_actions_new(Main *bmain, const char *name)
{
- bAction *act = add_empty_action(bmain, name);
+ char safe_name[MAX_ID_NAME - 2];
+ rna_idname_validate(name, safe_name);
+
+ bAction *act = add_empty_action(bmain, safe_name);
id_fake_user_clear(&act->id);
return act;
}
static ParticleSettings *rna_Main_particles_new(Main *bmain, const char *name)
{
- ParticleSettings *part = psys_new_settings(name, bmain);
+ char safe_name[MAX_ID_NAME - 2];
+ rna_idname_validate(name, safe_name);
+
+ ParticleSettings *part = psys_new_settings(safe_name, bmain);
id_us_min(&part->id);
return part;
}
static Palette *rna_Main_palettes_new(Main *bmain, const char *name)
{
- Palette *palette = BKE_palette_add(bmain, name);
+ char safe_name[MAX_ID_NAME - 2];
+ rna_idname_validate(name, safe_name);
+
+ Palette *palette = BKE_palette_add(bmain, safe_name);
id_us_min(&palette->id);
return (Palette *)palette;
}
@@ -481,16 +552,18 @@ static MovieClip *rna_Main_movieclip_load(Main *bmain, ReportList *reports, cons
static Mask *rna_Main_mask_new(Main *bmain, const char *name)
{
- Mask *mask;
-
- mask = BKE_mask_new(bmain, name);
+ char safe_name[MAX_ID_NAME - 2];
+ rna_idname_validate(name, safe_name);
- return mask;
+ return BKE_mask_new(bmain, safe_name);
}
static FreestyleLineStyle *rna_Main_linestyles_new(Main *bmain, const char *name)
{
- FreestyleLineStyle *linestyle = BKE_linestyle_new(bmain, name);
+ char safe_name[MAX_ID_NAME - 2];
+ rna_idname_validate(name, safe_name);
+
+ FreestyleLineStyle *linestyle = BKE_linestyle_new(bmain, safe_name);
id_us_min(&linestyle->id);
return linestyle;
}
diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c
index 3dc58442851..ad5f320625c 100644
--- a/source/blender/makesrna/intern/rna_mesh.c
+++ b/source/blender/makesrna/intern/rna_mesh.c
@@ -1962,7 +1962,7 @@ static void rna_def_medge(BlenderRNA *brna)
prop = RNA_def_property(srna, "crease", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_funcs(prop, "rna_MEdge_crease_get", "rna_MEdge_crease_set", NULL);
- RNA_def_property_ui_text(prop, "Crease", "Weight used by the Subsurf modifier for creasing");
+ RNA_def_property_ui_text(prop, "Crease", "Weight used by the Subdivision Surface modifier for creasing");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
prop = RNA_def_property(srna, "bevel_weight", PROP_FLOAT, PROP_NONE);
@@ -1987,7 +1987,7 @@ static void rna_def_medge(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_edge_sharp", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_SHARP);
- RNA_def_property_ui_text(prop, "Sharp", "Sharp edge for the EdgeSplit modifier");
+ RNA_def_property_ui_text(prop, "Sharp", "Sharp edge for the Edge Split modifier");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
prop = RNA_def_property(srna, "is_loose", PROP_BOOLEAN, PROP_NONE);
@@ -3560,7 +3560,7 @@ static void rna_def_mesh(BlenderRNA *brna)
prop = RNA_def_property(srna, "show_edge_crease", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "drawflag", ME_DRAWCREASES);
- RNA_def_property_ui_text(prop, "Draw Creases", "Display creases created for subsurf weighting");
+ RNA_def_property_ui_text(prop, "Draw Creases", "Display creases created for Subdivision Surface modifier");
RNA_def_property_update(prop, 0, "rna_Mesh_update_draw");
prop = RNA_def_property(srna, "show_edge_bevel_weight", PROP_BOOLEAN, PROP_NONE);
@@ -3575,7 +3575,7 @@ static void rna_def_mesh(BlenderRNA *brna)
prop = RNA_def_property(srna, "show_edge_sharp", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "drawflag", ME_DRAWSHARP);
- RNA_def_property_ui_text(prop, "Draw Sharp", "Display sharp edges, used with the EdgeSplit modifier");
+ RNA_def_property_ui_text(prop, "Draw Sharp", "Display sharp edges, used with the Edge Split modifier");
RNA_def_property_update(prop, 0, "rna_Mesh_update_draw");
prop = RNA_def_property(srna, "show_freestyle_edge_marks", PROP_BOOLEAN, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c
index ae444acc432..3e6d8441363 100644
--- a/source/blender/makesrna/intern/rna_sequencer.c
+++ b/source/blender/makesrna/intern/rna_sequencer.c
@@ -1674,7 +1674,7 @@ static void rna_def_filter_video(StructRNA *srna)
prop = RNA_def_property(srna, "use_deinterlace", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_FILTERY);
- RNA_def_property_ui_text(prop, "De-Interlace", "For video movies to remove fields");
+ RNA_def_property_ui_text(prop, "Deinterlace", "Remove fields from video movies");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update_reopen_files");
prop = RNA_def_property(srna, "alpha_mode", PROP_ENUM, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index beb1d890ba9..e68e67586e9 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -3287,7 +3287,7 @@ static void rna_def_userdef_walk_navigation(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_mouse_reverse", PROP_BOOLEAN, PROP_BOOLEAN);
RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_WALK_MOUSE_REVERSE);
- RNA_def_property_ui_text(prop, "Reverse Mouse", "Reverse the mouse look");
+ RNA_def_property_ui_text(prop, "Reverse Mouse", "Reverse the vertical movement of the mouse");
}
static void rna_def_userdef_view(BlenderRNA *brna)
@@ -4332,7 +4332,7 @@ static void rna_def_userdef_input(BlenderRNA *brna)
prop = RNA_def_property(srna, "ndof_deadzone", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_range(prop, 0.0f, 1.0f);
- RNA_def_property_ui_text(prop, "Deadzone", "Deadzone of the 3D Mouse");
+ RNA_def_property_ui_text(prop, "Deadzone", "Threshold of initial movement needed from the device's rest position");
RNA_def_property_update(prop, 0, "rna_userdef_ndof_deadzone_update");
prop = RNA_def_property(srna, "ndof_pan_yz_swap_axis", PROP_BOOLEAN, PROP_NONE);
diff --git a/source/blender/python/intern/bpy_rna_anim.c b/source/blender/python/intern/bpy_rna_anim.c
index 92931eb8090..5fbe1ab971a 100644
--- a/source/blender/python/intern/bpy_rna_anim.c
+++ b/source/blender/python/intern/bpy_rna_anim.c
@@ -36,12 +36,15 @@
#include "DNA_scene_types.h"
#include "DNA_anim_types.h"
+
#include "ED_keyframing.h"
+#include "ED_keyframes_edit.h"
#include "BKE_report.h"
#include "BKE_context.h"
#include "BKE_animsys.h"
#include "BKE_fcurve.h"
+#include "BKE_idcode.h"
#include "RNA_access.h"
#include "RNA_enum_types.h"
@@ -223,9 +226,47 @@ PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyOb
{
return NULL;
}
+ else if (self->ptr.type == &RNA_NlaStrip) {
+ /* Handle special properties for NLA Strips, whose F-Curves are stored on the
+ * strips themselves. These are stored separately or else the properties will
+ * not have any effect.
+ */
+ ReportList reports;
+ short result = 0;
+
+ PointerRNA ptr = self->ptr;
+ PropertyRNA *prop = NULL;
+ const char *prop_name;
+
+ BKE_reports_init(&reports, RPT_STORE);
+
+ /* Retrieve the property identifier from the full path, since we can't get it any other way */
+ prop_name = strrchr(path_full, '.');
+ if ((prop_name >= path_full) &&
+ (prop_name + 1 < path_full + strlen(path_full)))
+ {
+ prop = RNA_struct_find_property(&ptr, prop_name + 1);
+ }
+
+ if (prop) {
+ NlaStrip *strip = (NlaStrip *)ptr.data;
+ FCurve *fcu = list_find_fcurve(&strip->fcurves, RNA_property_identifier(prop), index);
+
+ result = insert_keyframe_direct(&reports, ptr, prop, fcu, cfra, keytype, index);
+ }
+ else {
+ BKE_reportf(&reports, RPT_ERROR, "Could not resolve path (%s)", path_full);
+ }
+ MEM_freeN((void *)path_full);
+
+ if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1)
+ return NULL;
+
+ return PyBool_FromLong(result);
+ }
else {
- short result;
ReportList reports;
+ short result;
BKE_reports_init(&reports, RPT_STORE);
@@ -272,6 +313,67 @@ PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args, PyOb
{
return NULL;
}
+ else if (self->ptr.type == &RNA_NlaStrip) {
+ /* Handle special properties for NLA Strips, whose F-Curves are stored on the
+ * strips themselves. These are stored separately or else the properties will
+ * not have any effect.
+ */
+ ReportList reports;
+ short result = 0;
+
+ PointerRNA ptr = self->ptr;
+ PropertyRNA *prop = NULL;
+ const char *prop_name;
+
+ BKE_reports_init(&reports, RPT_STORE);
+
+ /* Retrieve the property identifier from the full path, since we can't get it any other way */
+ prop_name = strrchr(path_full, '.');
+ if ((prop_name >= path_full) &&
+ (prop_name + 1 < path_full + strlen(path_full)))
+ {
+ prop = RNA_struct_find_property(&ptr, prop_name + 1);
+ }
+
+ if (prop) {
+ ID *id = ptr.id.data;
+ NlaStrip *strip = (NlaStrip *)ptr.data;
+ FCurve *fcu = list_find_fcurve(&strip->fcurves, RNA_property_identifier(prop), index);
+
+ BLI_assert(fcu != NULL); /* NOTE: This should be true, or else we wouldn't be able to get here */
+
+ if (BKE_fcurve_is_protected(fcu)) {
+ BKE_reportf(&reports, RPT_WARNING,
+ "Not deleting keyframe for locked F-Curve for NLA Strip influence on %s - %s '%s'",
+ strip->name, BKE_idcode_to_name(GS(id->name)), id->name + 2);
+ }
+ else {
+ /* remove the keyframe directly
+ * NOTE: cannot use delete_keyframe_fcurve(), as that will free the curve,
+ * and delete_keyframe() expects the FCurve to be part of an action
+ */
+ bool found = false;
+ int i;
+
+ /* try to find index of beztriple to get rid of */
+ i = binarysearch_bezt_index(fcu->bezt, cfra, fcu->totvert, &found);
+ if (found) {
+ /* delete the key at the index (will sanity check + do recalc afterwards) */
+ delete_fcurve_key(fcu, i, 1);
+ result = true;
+ }
+ }
+ }
+ else {
+ BKE_reportf(&reports, RPT_ERROR, "Could not resolve path (%s)", path_full);
+ }
+ MEM_freeN((void *)path_full);
+
+ if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1)
+ return NULL;
+
+ return PyBool_FromLong(result);
+ }
else {
short result;
ReportList reports;