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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/animation/keyframes_edit.c2
-rw-r--r--source/blender/editors/armature/armature_naming.c4
-rw-r--r--source/blender/editors/curve/editcurve.c2
-rw-r--r--source/blender/editors/gpencil/gpencil_brush.c21
-rw-r--r--source/blender/editors/gpencil/gpencil_edit.c102
-rw-r--r--source/blender/editors/gpencil/gpencil_intern.h94
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c17
-rw-r--r--source/blender/editors/gpencil/gpencil_utils.c62
-rw-r--r--source/blender/editors/include/UI_icons.h4
-rw-r--r--source/blender/editors/interface/interface.c11
-rw-r--r--source/blender/editors/interface/interface_layout.c4
-rw-r--r--source/blender/editors/interface/interface_regions.c4
-rw-r--r--source/blender/editors/io/io_alembic.c22
-rw-r--r--source/blender/editors/io/io_collada.c46
-rw-r--r--source/blender/editors/mesh/editmesh_add.c2
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c2
-rw-r--r--source/blender/editors/object/object_add.c18
-rw-r--r--source/blender/editors/object/object_group.c3
-rw-r--r--source/blender/editors/object/object_relations.c185
-rw-r--r--source/blender/editors/physics/dynamicpaint_ops.c36
-rw-r--r--source/blender/editors/physics/particle_edit.c2
-rw-r--r--source/blender/editors/physics/physics_pointcache.c42
-rw-r--r--source/blender/editors/render/render_preview.c2
-rw-r--r--source/blender/editors/screen/screen_edit.c4
-rw-r--r--source/blender/editors/screen/screen_ops.c2
-rw-r--r--source/blender/editors/space_buttons/buttons_texture.c2
-rw-r--r--source/blender/editors/space_image/image_ops.c11
-rw-r--r--source/blender/editors/space_info/info_ops.c1
-rw-r--r--source/blender/editors/space_nla/nla_buttons.c2
-rw-r--r--source/blender/editors/space_node/node_edit.c2
-rw-r--r--source/blender/editors/space_node/space_node.c4
-rw-r--r--source/blender/editors/space_outliner/outliner_edit.c5
-rw-r--r--source/blender/editors/space_outliner/outliner_select.c7
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.c11
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c9
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c3
-rw-r--r--source/blender/editors/space_sequencer/sequencer_select.c2
-rw-r--r--source/blender/editors/space_text/text_autocomplete.c2
-rw-r--r--source/blender/editors/space_text/text_format_pov.c25
-rw-r--r--source/blender/editors/space_text/text_format_pov_ini.c8
-rw-r--r--source/blender/editors/space_view3d/drawarmature.c10
-rw-r--r--source/blender/editors/space_view3d/drawobject.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c2
-rw-r--r--source/blender/editors/transform/transform.c47
-rw-r--r--source/blender/editors/transform/transform_conversions.c58
-rw-r--r--source/blender/editors/transform/transform_generics.c2
-rw-r--r--source/blender/editors/transform/transform_input.c11
-rw-r--r--source/blender/editors/transform/transform_manipulator.c2
-rw-r--r--source/blender/editors/transform/transform_snap_object.c4
-rw-r--r--source/blender/editors/util/undo.c8
-rw-r--r--source/blender/editors/uvedit/uvedit_parametrizer.c2
51 files changed, 554 insertions, 381 deletions
diff --git a/source/blender/editors/animation/keyframes_edit.c b/source/blender/editors/animation/keyframes_edit.c
index 4571df0f077..9d25fc9e1a3 100644
--- a/source/blender/editors/animation/keyframes_edit.c
+++ b/source/blender/editors/animation/keyframes_edit.c
@@ -452,7 +452,7 @@ void ANIM_editkeyframes_refresh(bAnimContext *ac)
ok |= KEYFRAME_OK_H2; \
} \
} (void)0
-
+
/* ------------------------ */
static short ok_bezier_frame(KeyframeEditData *ked, BezTriple *bezt)
diff --git a/source/blender/editors/armature/armature_naming.c b/source/blender/editors/armature/armature_naming.c
index c928508237d..db4b642fe91 100644
--- a/source/blender/editors/armature/armature_naming.c
+++ b/source/blender/editors/armature/armature_naming.c
@@ -311,8 +311,8 @@ typedef struct BoneFlipNameData {
* This way if we are flipping related bones (e.g., Bone.L, Bone.R) at the same time
* all the bones are safely renamed, without conflicting with each other.
*
- * \param arm Armature the bones belong to
- * \param bones ListBase of BoneConflict elems, populated via ED_armature_bones_flip_names_add
+ * \param arm: Armature the bones belong to
+ * \param bones_names: List of BoneConflict elems.
*/
void ED_armature_bones_flip_names(bArmature *arm, ListBase *bones_names)
{
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index a69264cd012..8a366ce6a81 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -4160,7 +4160,7 @@ static int make_segment_exec(bContext *C, wmOperator *op)
*/
bp = nu->bp;
- if (bp[nu->pntsu - 1].f1 & SELECT) {
+ if (bp[nu->pntsu - 1].f1 & SELECT) {
if (nu2 == NULL) {
nu2 = nu;
}
diff --git a/source/blender/editors/gpencil/gpencil_brush.c b/source/blender/editors/gpencil/gpencil_brush.c
index 8ddf3a22517..5332bec0c64 100644
--- a/source/blender/editors/gpencil/gpencil_brush.c
+++ b/source/blender/editors/gpencil/gpencil_brush.c
@@ -773,6 +773,9 @@ typedef struct tGPSB_CloneBrushData {
/* for "stamp" mode, the currently pasted brushes */
bGPDstroke **new_strokes;
+
+ /* mapping from colors referenced per stroke, to the new colours in the "pasted" strokes */
+ GHash *new_colors;
} tGPSB_CloneBrushData;
/* Initialise "clone" brush data */
@@ -816,6 +819,11 @@ static void gp_brush_clone_init(bContext *C, tGP_BrushEditData *gso)
if (1 /*gso->brush->mode == GP_EDITBRUSH_CLONE_MODE_STAMP*/) {
data->new_strokes = MEM_callocN(sizeof(bGPDstroke *) * data->totitems, "cloned strokes ptr array");
}
+
+ /* Init colormap for mapping between the pasted stroke's source colour(names)
+ * and the final colours that will be used here instead...
+ */
+ data->new_colors = gp_copybuf_validate_colormap(gso->gpd);
}
/* Free custom data used for "clone" brush */
@@ -829,6 +837,12 @@ static void gp_brush_clone_free(tGP_BrushEditData *gso)
data->new_strokes = NULL;
}
+ /* free copybuf colormap */
+ if (data->new_colors) {
+ BLI_ghash_free(data->new_colors, NULL, NULL);
+ data->new_colors = NULL;
+ }
+
/* free the customdata itself */
MEM_freeN(data);
gso->customdata = NULL;
@@ -869,6 +883,13 @@ static void gp_brush_clone_add(bContext *C, tGP_BrushEditData *gso)
new_stroke->next = new_stroke->prev = NULL;
BLI_addtail(&gpf->strokes, new_stroke);
+ /* Fix color references */
+ BLI_assert(new_stroke->colorname[0] != '\0');
+ new_stroke->palcolor = BLI_ghash_lookup(data->new_colors, new_stroke->colorname);
+
+ BLI_assert(new_stroke->palcolor != NULL);
+ BLI_strncpy(new_stroke->colorname, new_stroke->palcolor->info, sizeof(new_stroke->colorname));
+
/* Adjust all the stroke's points, so that the strokes
* get pasted relative to where the cursor is now
*/
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index 2df4b2cae54..fc6df49cf6c 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -38,8 +38,11 @@
#include "MEM_guardedalloc.h"
-#include "BLI_math.h"
#include "BLI_blenlib.h"
+#include "BLI_ghash.h"
+#include "BLI_math.h"
+#include "BLI_string.h"
+#include "BLI_string_utils.h"
#include "BLI_utildefines.h"
#include "BLT_translation.h"
@@ -335,11 +338,27 @@ void GPENCIL_OT_duplicate(wmOperatorType *ot)
/* NOTE: is exposed within the editors/gpencil module so that other tools can use it too */
ListBase gp_strokes_copypastebuf = {NULL, NULL};
+/* Hash for hanging on to all the palette colors used by strokes in the buffer
+ *
+ * This is needed to prevent dangling and unsafe pointers when pasting across datablocks,
+ * or after a color used by a stroke in the buffer gets deleted (via user action or undo).
+ */
+GHash *gp_strokes_copypastebuf_colors = NULL;
+
/* Free copy/paste buffer data */
void ED_gpencil_strokes_copybuf_free(void)
{
bGPDstroke *gps, *gpsn;
+ /* Free the palettes buffer
+ * NOTE: This is done before the strokes so that the name ptrs (keys) are still safe
+ */
+ if (gp_strokes_copypastebuf_colors) {
+ BLI_ghash_free(gp_strokes_copypastebuf_colors, NULL, MEM_freeN);
+ gp_strokes_copypastebuf_colors = NULL;
+ }
+
+ /* Free the stroke buffer */
for (gps = gp_strokes_copypastebuf.first; gps; gps = gpsn) {
gpsn = gps->next;
@@ -352,6 +371,46 @@ void ED_gpencil_strokes_copybuf_free(void)
gp_strokes_copypastebuf.first = gp_strokes_copypastebuf.last = NULL;
}
+/* Ensure that destination datablock has all the colours the pasted strokes need
+ * Helper function for copy-pasting strokes
+ */
+GHash *gp_copybuf_validate_colormap(bGPdata *gpd)
+{
+ GHash *new_colors = BLI_ghash_str_new("GPencil Paste Dst Colors");
+ GHashIterator gh_iter;
+
+ /* If there's no active palette yet (i.e. new datablock), add one */
+ bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd);
+ if (palette == NULL) {
+ palette = BKE_gpencil_palette_addnew(gpd, "Pasted Palette", true);
+ }
+
+ /* For each color, figure out what to map to... */
+ GHASH_ITER(gh_iter, gp_strokes_copypastebuf_colors) {
+ bGPDpalettecolor *palcolor;
+ char *name = BLI_ghashIterator_getKey(&gh_iter);
+
+ /* Look for existing color to map to */
+ /* XXX: What to do if same name but different color? Behaviour here should depend on a property? */
+ palcolor = BKE_gpencil_palettecolor_getbyname(palette, name);
+ if (palcolor == NULL) {
+ /* Doesn't Exist - Create new matching color for this palette */
+ /* XXX: This still doesn't fix the pasting across file boundaries problem... */
+ bGPDpalettecolor *src_color = BLI_ghashIterator_getValue(&gh_iter);
+
+ palcolor = MEM_dupallocN(src_color);
+ BLI_addtail(&palette->colors, palcolor);
+
+ BLI_uniquename(&palette->colors, palcolor, DATA_("GP Color"), '.', offsetof(bGPDpalettecolor, info), sizeof(palcolor->info));
+ }
+
+ /* Store this mapping (for use later when pasting) */
+ BLI_ghash_insert(new_colors, name, palcolor);
+ }
+
+ return new_colors;
+}
+
/* --------------------- */
/* Copy selected strokes */
@@ -413,7 +472,26 @@ static int gp_strokes_copy_exec(bContext *C, wmOperator *op)
}
CTX_DATA_END;
- /* done - no updates needed */
+ /* Build up hash of colors used in these strokes, making copies of these to protect against dangling pointers */
+ if (gp_strokes_copypastebuf.first) {
+ gp_strokes_copypastebuf_colors = BLI_ghash_str_new("GPencil CopyBuf Colors");
+
+ for (bGPDstroke *gps = gp_strokes_copypastebuf.first; gps; gps = gps->next) {
+ if (ED_gpencil_stroke_can_use(C, gps)) {
+ if (BLI_ghash_haskey(gp_strokes_copypastebuf_colors, gps->colorname) == false) {
+ bGPDpalettecolor *color = MEM_dupallocN(gps->palcolor);
+
+ BLI_ghash_insert(gp_strokes_copypastebuf_colors, gps->colorname, color);
+ gps->palcolor = color;
+ }
+ }
+ }
+ }
+
+ /* updates (to ensure operator buttons are refreshed, when used via hotkeys) */
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA, NULL); // XXX?
+
+ /* done */
return OPERATOR_FINISHED;
}
@@ -458,6 +536,7 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op)
bGPDframe *gpf;
eGP_PasteMode type = RNA_enum_get(op->ptr, "type");
+ GHash *new_colors;
/* check for various error conditions */
if (gpd == NULL) {
@@ -515,6 +594,10 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op)
}
CTX_DATA_END;
+ /* Ensure that all the necessary colors exist */
+ new_colors = gp_copybuf_validate_colormap(gpd);
+
+ /* Copy over the strokes from the buffer (and adjust the colors) */
for (bGPDstroke *gps = gp_strokes_copypastebuf.first; gps; gps = gps->next) {
if (ED_gpencil_stroke_can_use(C, gps)) {
/* Need to verify if layer exists */
@@ -533,6 +616,7 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op)
*/
gpf = BKE_gpencil_layer_getframe(gpl, CFRA, true);
if (gpf) {
+ /* Create new stroke */
bGPDstroke *new_stroke = MEM_dupallocN(gps);
new_stroke->tmp_layerinfo[0] = '\0';
@@ -543,10 +627,22 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op)
new_stroke->next = new_stroke->prev = NULL;
BLI_addtail(&gpf->strokes, new_stroke);
+
+ /* Fix color references */
+ BLI_assert(new_stroke->colorname[0] != '\0');
+ new_stroke->palcolor = BLI_ghash_lookup(new_colors, new_stroke->colorname);
+
+ BLI_assert(new_stroke->palcolor != NULL);
+ BLI_strncpy(new_stroke->colorname, new_stroke->palcolor->info, sizeof(new_stroke->colorname));
+
+ /*new_stroke->flag |= GP_STROKE_RECALC_COLOR; */
}
}
}
+ /* free temp data */
+ BLI_ghash_free(new_colors, NULL, NULL);
+
/* updates */
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
@@ -750,7 +846,7 @@ void GPENCIL_OT_blank_frame_add(wmOperatorType *ot)
/* identifiers */
ot->name = "Insert Blank Frame";
ot->idname = "GPENCIL_OT_blank_frame_add";
- ot->description = "Inserts a blank frame on the current frame "
+ ot->description = "Insert a blank frame on the current frame "
"(all subsequently existing frames, if any, are shifted right by one frame)";
/* callbacks */
diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h
index 5c7c9b84adb..a3734c56c59 100644
--- a/source/blender/editors/gpencil/gpencil_intern.h
+++ b/source/blender/editors/gpencil/gpencil_intern.h
@@ -40,6 +40,8 @@ struct bGPdata;
struct bGPDstroke;
struct bGPDspoint;
+struct GHash;
+
struct ARegion;
struct View2D;
struct wmOperatorType;
@@ -69,75 +71,23 @@ typedef struct GP_SpaceConversion {
float mat[4][4]; /* transform matrix on the strokes (introduced in [b770964]) */
} GP_SpaceConversion;
-
-/**
- * Check whether a given stroke segment is inside a circular brush
- *
- * \param mval The current screen-space coordinates (midpoint) of the brush
- * \param mvalo The previous screen-space coordinates (midpoint) of the brush (NOT CURRENTLY USED)
- * \param rad The radius of the brush
- *
- * \param x0, y0 The screen-space x and y coordinates of the start of the stroke segment
- * \param x1, y1 The screen-space x and y coordinates of the end of the stroke segment
- */
bool gp_stroke_inside_circle(const int mval[2], const int UNUSED(mvalo[2]),
int rad, int x0, int y0, int x1, int y1);
-
-/**
- * Init settings for stroke point space conversions
- *
- * \param[out] r_gsc The space conversion settings struct, populated with necessary params
- */
void gp_point_conversion_init(struct bContext *C, GP_SpaceConversion *r_gsc);
-/**
- * Convert a Grease Pencil coordinate (i.e. can be 2D or 3D) to screenspace (2D)
- *
- * \param[out] r_x The screen-space x-coordinate of the point
- * \param[out] r_y The screen-space y-coordinate of the point
- */
void gp_point_to_xy(GP_SpaceConversion *settings, struct bGPDstroke *gps, struct bGPDspoint *pt,
int *r_x, int *r_y);
-/**
- * Convert a Grease Pencil coordinate (i.e. can be 2D or 3D) to screenspace (2D)
- *
- * Just like gp_point_to_xy(), except the resulting coordinates are floats not ints.
- * Use this version to solve "stair-step" artifacts which may arise when roundtripping the calculations.
- *
- * \param[out] r_x The screen-space x-coordinate of the point
- * \param[out] r_y The screen-space y-coordinate of the point
- */
void gp_point_to_xy_fl(GP_SpaceConversion *gsc, bGPDstroke *gps, bGPDspoint *pt,
float *r_x, float *r_y);
-/**
- * Convert point to parent space
- *
- * \param pt Original point
- * \param diff_mat Matrix with the difference between original parent matrix
- * \param[out] r_pt Pointer to new point after apply matrix
- */
void gp_point_to_parent_space(bGPDspoint *pt, float diff_mat[4][4], bGPDspoint *r_pt);
-/**
- * Change points position relative to parent object
- */
+
void gp_apply_parent(bGPDlayer *gpl, bGPDstroke *gps);
-/**
- * Change point position relative to parent object
- */
+
void gp_apply_parent_point(bGPDlayer *gpl, bGPDspoint *pt);
-/**
- * Convert a screenspace point to a 3D Grease Pencil coordinate.
- *
- * For use with editing tools where it is easier to perform the operations in 2D,
- * and then later convert the transformed points back to 3D.
- *
- * \param screeN_co The screenspace 2D coordinates to convert to
- * \param[out] r_out The resulting 3D coordinates of the input point
- */
bool gp_point_xy_to_3d(GP_SpaceConversion *gsc, struct Scene *scene, const float screen_co[2], float r_out[3]);
/* Poll Callbacks ------------------------------------ */
@@ -155,48 +105,18 @@ int gp_brush_crt_presets_poll(bContext *C);
extern ListBase gp_strokes_copypastebuf;
+/* Build a map for converting between old colornames and destination-color-refs */
+struct GHash *gp_copybuf_validate_colormap(bGPdata *gpd);
+
/* Stroke Editing ------------------------------------ */
void gp_stroke_delete_tagged_points(bGPDframe *gpf, bGPDstroke *gps, bGPDstroke *next_stroke, int tag_flags);
-/**
- * Apply smooth to stroke point
- * \param gps Stroke to smooth
- * \param i Point index
- * \param inf Amount of smoothing to apply
- * \param affect_pressure Apply smoothing to pressure values too?
- */
bool gp_smooth_stroke(bGPDstroke *gps, int i, float inf, bool affect_pressure);
-
-/**
-* Apply smooth for strength to stroke point
-* \param gps Stroke to smooth
-* \param i Point index
-* \param inf Amount of smoothing to apply
-*/
bool gp_smooth_stroke_strength(bGPDstroke *gps, int i, float inf);
-
-/**
-* Apply smooth for thickness to stroke point (use pressure)
-* \param gps Stroke to smooth
-* \param i Point index
-* \param inf Amount of smoothing to apply
-*/
bool gp_smooth_stroke_thickness(bGPDstroke *gps, int i, float inf);
-
-/**
- * Subdivide a stroke once, by adding points at the midpoint between each pair of points
- * \param gps Stroke data
- * \param new_totpoints Total number of points (after subdividing)
- */
void gp_subdivide_stroke(bGPDstroke *gps, const int new_totpoints);
-
-/**
-* Add randomness to stroke
-* \param gps Stroke data
-* \param brush Brush data
-*/
void gp_randomize_stroke(bGPDstroke *gps, bGPDbrush *brush);
/* Layers Enums -------------------------------------- */
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index 5eacbf6f807..eb49060b629 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -162,6 +162,8 @@ typedef struct tGPsdata {
bGPDbrush *brush; /* current drawing brush */
short straight[2]; /* 1: line horizontal, 2: line vertical, other: not defined, second element position */
int lock_axis; /* lock drawing to one axis */
+
+ short keymodifier; /* key used for invoking the operator */
} tGPsdata;
/* ------ */
@@ -1940,7 +1942,7 @@ static void gpencil_draw_cancel(bContext *C, wmOperator *op)
/* ------------------------------- */
-static int gpencil_draw_init(bContext *C, wmOperator *op)
+static int gpencil_draw_init(bContext *C, wmOperator *op, const wmEvent *event)
{
tGPsdata *p;
eGPencil_PaintModes paintmode = RNA_enum_get(op->ptr, "mode");
@@ -1959,6 +1961,13 @@ static int gpencil_draw_init(bContext *C, wmOperator *op)
gpencil_draw_exit(C, op);
return 0;
}
+
+ if (event != NULL) {
+ p->keymodifier = event->keymodifier;
+ }
+ else {
+ p->keymodifier = -1;
+ }
/* everything is now setup ok */
return 1;
@@ -2200,7 +2209,7 @@ static int gpencil_draw_exec(bContext *C, wmOperator *op)
/* printf("GPencil - Starting Re-Drawing\n"); */
/* try to initialize context data needed while drawing */
- if (!gpencil_draw_init(C, op)) {
+ if (!gpencil_draw_init(C, op, NULL)) {
if (op->customdata) MEM_freeN(op->customdata);
/* printf("\tGP - no valid data\n"); */
return OPERATOR_CANCELLED;
@@ -2275,7 +2284,7 @@ static int gpencil_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event
printf("GPencil - Starting Drawing\n");
/* try to initialize context data needed while drawing */
- if (!gpencil_draw_init(C, op)) {
+ if (!gpencil_draw_init(C, op, event)) {
if (op->customdata)
MEM_freeN(op->customdata);
if (G.debug & G_DEBUG)
@@ -2438,7 +2447,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
* is essential for ensuring that they can quickly return to that view
*/
}
- else if ((ELEM(event->type, DKEY)) && (event->val == KM_RELEASE)) {
+ else if ((ELEM(event->type, p->keymodifier)) && (event->val == KM_RELEASE)) {
/* enable continuous if release D key in mid drawing */
p->scene->toolsettings->gpencil_flags |= GP_TOOL_FLAG_PAINTSESSIONS_ON;
}
diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c
index 2b662d04f03..ed05b8be9ca 100644
--- a/source/blender/editors/gpencil/gpencil_utils.c
+++ b/source/blender/editors/gpencil/gpencil_utils.c
@@ -391,7 +391,16 @@ EnumPropertyItem *ED_gpencil_layers_with_new_enum_itemf(bContext *C, PointerRNA
/* ******************************************************** */
/* Brush Tool Core */
-/* Check if part of stroke occurs within last segment drawn by eraser */
+/**
+ * Check whether a given stroke segment is inside a circular brush
+ *
+ * \param mval The current screen-space coordinates (midpoint) of the brush
+ * \param mvalo The previous screen-space coordinates (midpoint) of the brush (NOT CURRENTLY USED)
+ * \param rad The radius of the brush
+ *
+ * \param x0, y0 The screen-space x and y coordinates of the start of the stroke segment
+ * \param x1, y1 The screen-space x and y coordinates of the end of the stroke segment
+ */
bool gp_stroke_inside_circle(const int mval[2], const int UNUSED(mvalo[2]),
int rad, int x0, int y0, int x1, int y1)
{
@@ -502,7 +511,11 @@ bGPDpalettecolor *ED_gpencil_stroke_getcolor(bGPdata *gpd, bGPDstroke *gps)
/* ******************************************************** */
/* Space Conversion */
-/* Init handling for space-conversion function (from passed-in parameters) */
+/**
+ * Init settings for stroke point space conversions
+ *
+ * \param r_gsc: [out] The space conversion settings struct, populated with necessary params
+ */
void gp_point_conversion_init(bContext *C, GP_SpaceConversion *r_gsc)
{
ScrArea *sa = CTX_wm_area(C);
@@ -538,7 +551,13 @@ void gp_point_conversion_init(bContext *C, GP_SpaceConversion *r_gsc)
}
}
-/* convert point to parent space */
+/**
+ * Convert point to parent space
+ *
+ * \param pt Original point
+ * \param diff_mat Matrix with the difference between original parent matrix
+ * \param[out] r_pt Pointer to new point after apply matrix
+ */
void gp_point_to_parent_space(bGPDspoint *pt, float diff_mat[4][4], bGPDspoint *r_pt)
{
float fpt[3];
@@ -547,7 +566,9 @@ void gp_point_to_parent_space(bGPDspoint *pt, float diff_mat[4][4], bGPDspoint *
copy_v3_v3(&r_pt->x, fpt);
}
-/* Change position relative to parent object */
+/**
+ * Change points position relative to parent object
+ */
void gp_apply_parent(bGPDlayer *gpl, bGPDstroke *gps)
{
bGPDspoint *pt;
@@ -568,7 +589,9 @@ void gp_apply_parent(bGPDlayer *gpl, bGPDstroke *gps)
}
}
-/* Change point position relative to parent object */
+/**
+ * Change point position relative to parent object
+ */
void gp_apply_parent_point(bGPDlayer *gpl, bGPDspoint *pt)
{
/* undo matrix */
@@ -583,8 +606,13 @@ void gp_apply_parent_point(bGPDlayer *gpl, bGPDspoint *pt)
copy_v3_v3(&pt->x, fpt);
}
-/* Convert Grease Pencil points to screen-space values
- * WARNING: This assumes that the caller has already checked whether the stroke in question can be drawn
+/**
+ * Convert a Grease Pencil coordinate (i.e. can be 2D or 3D) to screenspace (2D)
+ *
+ * \param[out] r_x The screen-space x-coordinate of the point
+ * \param[out] r_y The screen-space y-coordinate of the point
+ *
+ * \warning This assumes that the caller has already checked whether the stroke in question can be drawn.
*/
void gp_point_to_xy(GP_SpaceConversion *gsc, bGPDstroke *gps, bGPDspoint *pt,
int *r_x, int *r_y)
@@ -628,8 +656,16 @@ void gp_point_to_xy(GP_SpaceConversion *gsc, bGPDstroke *gps, bGPDspoint *pt,
}
}
-/* Convert Grease Pencil points to screen-space values (as floats)
- * WARNING: This assumes that the caller has already checked whether the stroke in question can be drawn
+/**
+ * Convert a Grease Pencil coordinate (i.e. can be 2D or 3D) to screenspace (2D)
+ *
+ * Just like gp_point_to_xy(), except the resulting coordinates are floats not ints.
+ * Use this version to solve "stair-step" artifacts which may arise when roundtripping the calculations.
+ *
+ * \param r_x: [out] The screen-space x-coordinate of the point
+ * \param r_y: [out] The screen-space y-coordinate of the point
+ *
+ * \warning This assumes that the caller has already checked whether the stroke in question can be drawn
*/
void gp_point_to_xy_fl(GP_SpaceConversion *gsc, bGPDstroke *gps, bGPDspoint *pt,
float *r_x, float *r_y)
@@ -688,6 +724,12 @@ void gp_point_to_xy_fl(GP_SpaceConversion *gsc, bGPDstroke *gps, bGPDspoint *pt,
/**
* Project screenspace coordinates to 3D-space
*
+ * For use with editing tools where it is easier to perform the operations in 2D,
+ * and then later convert the transformed points back to 3D.
+ *
+ * \param screen_co: The screenspace 2D coordinates to convert to
+ * \param r_out: The resulting 3D coordinates of the input point
+ *
* \note We include this as a utility function, since the standard method
* involves quite a few steps, which are invariably always the same
* for all GPencil operations. So, it's nicer to just centralize these.
@@ -722,7 +764,7 @@ bool gp_point_xy_to_3d(GP_SpaceConversion *gsc, Scene *scene, const float screen
}
/**
- * Apply smooth to stroke point
+ * Apply smooth to stroke point
* \param gps Stroke to smooth
* \param i Point index
* \param inf Amount of smoothing to apply
diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h
index 8c604208041..d395cb3e16d 100644
--- a/source/blender/editors/include/UI_icons.h
+++ b/source/blender/editors/include/UI_icons.h
@@ -313,9 +313,9 @@ DEF_ICON(OUTLINER_OB_ARMATURE)
DEF_ICON(OUTLINER_OB_FONT)
DEF_ICON(OUTLINER_OB_SURFACE)
DEF_ICON(OUTLINER_OB_SPEAKER)
+DEF_ICON(OUTLINER_OB_FORCE_FIELD)
+DEF_ICON(OUTLINER_OB_GROUP_INSTANCE)
#ifndef DEF_ICON_BLANK_SKIP
- DEF_ICON(BLANK120)
- DEF_ICON(BLANK121)
DEF_ICON(BLANK122)
DEF_ICON(BLANK123)
DEF_ICON(BLANK124)
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 7180e18ab92..bcb1e3e648a 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -1337,7 +1337,7 @@ static void ui_but_to_pixelrect(rcti *rect, const ARegion *ar, uiBlock *block, u
rctf rectf;
ui_block_to_window_rctf(ar, block, &rectf, (but) ? &but->rect : &block->rect);
- BLI_rcti_rctf_copy(rect, &rectf);
+ BLI_rcti_rctf_copy_round(rect, &rectf);
BLI_rcti_translate(rect, -ar->winrct.xmin, -ar->winrct.ymin);
}
@@ -2335,11 +2335,10 @@ bool ui_but_string_set_eval_num(bContext *C, uiBut *but, const char *str, double
#else /* WITH_PYTHON */
- *value = atof(str);
+ *r_value = atof(str);
ok = true;
- (void)C;
- (void)but;
+ UNUSED_VARS(C, but);
#endif /* WITH_PYTHON */
@@ -3168,7 +3167,9 @@ static uiBut *ui_def_but(
}
if (block->flag & UI_BLOCK_RADIAL) {
- but->drawflag |= (UI_BUT_TEXT_LEFT | UI_BUT_ICON_LEFT);
+ but->drawflag |= UI_BUT_TEXT_LEFT;
+ if (but->str && but->str[0])
+ but->drawflag |= UI_BUT_ICON_LEFT;
}
else if ((block->flag & UI_BLOCK_LOOP) ||
ELEM(but->type,
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 30a2094fee7..da43a58bc74 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -2396,8 +2396,10 @@ static void ui_litem_layout_radial(uiLayout *litem)
/* add a little bit more here to include number */
bitem->but->rect.xmax += 1.5f * UI_UNIT_X;
/* enable drawing as pie item if supported by widget */
- if (ui_item_is_radial_drawable(bitem))
+ if (ui_item_is_radial_drawable(bitem)) {
bitem->but->dt = UI_EMBOSS_RADIAL;
+ bitem->but->drawflag |= UI_BUT_ICON_LEFT;
+ }
}
ui_item_size(item, &itemw, &itemh);
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index 534bd4278ca..5ed94474726 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -2099,9 +2099,11 @@ static void ui_update_color_picker_buts_rgb(uiBlock *block, ColorPicker *cpicker
continue;
if (bt->rnaprop) {
-
ui_but_v3_set(bt, rgb);
+ /* original button that created the color picker already does undo
+ * push, so disable it on RNA buttons in the color picker block */
+ UI_but_flag_disable(bt, UI_BUT_UNDO);
}
else if (STREQ(bt->str, "Hex: ")) {
float rgb_gamma[3];
diff --git a/source/blender/editors/io/io_alembic.c b/source/blender/editors/io/io_alembic.c
index ba8792d12ff..ca4ab30a08d 100644
--- a/source/blender/editors/io/io_alembic.c
+++ b/source/blender/editors/io/io_alembic.c
@@ -31,6 +31,9 @@
# include "BLI_winstuff.h"
#endif
+#include <string.h>
+#include <errno.h>
+
#include "MEM_guardedalloc.h"
#include "DNA_mesh_types.h"
@@ -383,8 +386,8 @@ void WM_OT_alembic_export(wmOperatorType *ot)
"Enable this to run the import in the background, disable to block Blender while importing");
/* This dummy prop is used to check whether we need to init the start and
- * end frame values to that of the scene's, otherwise they are reset at
- * every change, draw update. */
+ * end frame values to that of the scene's, otherwise they are reset at
+ * every change, draw update. */
RNA_def_boolean(ot->srna, "init_scene_frame_range", false, "", "");
}
@@ -417,9 +420,20 @@ static int get_sequence_len(char *filename, int *ofs)
}
char path[FILE_MAX];
+ BLI_path_abs(filename, G.main->name);
BLI_split_dir_part(filename, path, FILE_MAX);
+ if (path[0] == '\0') {
+ /* The filename had no path, so just use the blend file path. */
+ BLI_split_dir_part(G.main->name, path, FILE_MAX);
+ }
+
DIR *dir = opendir(path);
+ if (dir == NULL) {
+ fprintf(stderr, "Error opening directory '%s': %s\n",
+ path, errno ? strerror(errno) : "unknown error");
+ return -1;
+ }
const char *ext = ".abc";
const char *basename = BLI_path_basename(filename);
@@ -523,6 +537,10 @@ static int wm_alembic_import_exec(bContext *C, wmOperator *op)
if (is_sequence) {
sequence_len = get_sequence_len(filename, &offset);
+ if (sequence_len < 0) {
+ BKE_report(op->reports, RPT_ERROR, "Unable to determine ABC sequence length");
+ return OPERATOR_CANCELLED;
+ }
}
bool ok = ABC_import(C, filename, scale, is_sequence, set_frame_range,
diff --git a/source/blender/editors/io/io_collada.c b/source/blender/editors/io/io_collada.c
index 139c9817437..cead08afd61 100644
--- a/source/blender/editors/io/io_collada.c
+++ b/source/blender/editors/io/io_collada.c
@@ -87,8 +87,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
int include_shapekeys;
int deform_bones_only;
- int include_uv_textures;
- int include_material_textures;
+ int export_texture_type;
int use_texture_copies;
int active_uv_only;
@@ -139,8 +138,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
include_shapekeys = RNA_boolean_get(op->ptr, "include_shapekeys");
deform_bones_only = RNA_boolean_get(op->ptr, "deform_bones_only");
- include_uv_textures = RNA_boolean_get(op->ptr, "include_uv_textures");
- include_material_textures = RNA_boolean_get(op->ptr, "include_material_textures");
+ export_texture_type = RNA_enum_get(op->ptr, "export_texture_type_selection");
use_texture_copies = RNA_boolean_get(op->ptr, "use_texture_copies");
active_uv_only = RNA_boolean_get(op->ptr, "active_uv_only");
@@ -169,8 +167,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
deform_bones_only,
active_uv_only,
- include_uv_textures,
- include_material_textures,
+ export_texture_type,
use_texture_copies,
triangulate,
@@ -241,10 +238,7 @@ static void uiCollada_exportSettings(uiLayout *layout, PointerRNA *imfptr)
uiItemR(row, imfptr, "active_uv_only", 0, NULL, ICON_NONE);
row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "include_uv_textures", 0, NULL, ICON_NONE);
-
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "include_material_textures", 0, NULL, ICON_NONE);
+ uiItemR(row, imfptr, "export_texture_type_selection", 0, "", ICON_NONE);
row = uiLayoutRow(box, false);
uiItemR(row, imfptr, "use_texture_copies", 1, NULL, ICON_NONE);
@@ -321,9 +315,15 @@ void WM_OT_collada_export(wmOperatorType *ot)
};
static EnumPropertyItem prop_bc_export_transformation_type[] = {
- {BC_TRANSFORMATION_TYPE_MATRIX, "matrix", 0, "Matrix", "Use <matrix> to specify transformations"},
- {BC_TRANSFORMATION_TYPE_TRANSROTLOC, "transrotloc", 0, "TransRotLoc", "Use <translate>, <rotate>, <scale> to specify transformations"},
- {0, NULL, 0, NULL, NULL}
+ { BC_TRANSFORMATION_TYPE_MATRIX, "matrix", 0, "Matrix", "Use <matrix> to specify transformations" },
+ { BC_TRANSFORMATION_TYPE_TRANSROTLOC, "transrotloc", 0, "TransRotLoc", "Use <translate>, <rotate>, <scale> to specify transformations" },
+ { 0, NULL, 0, NULL, NULL }
+ };
+
+ static EnumPropertyItem prop_bc_export_texture_type[] = {
+ { BC_TEXTURE_TYPE_MAT, "mat", 0, "Materials", "Export Materials" },
+ { BC_TEXTURE_TYPE_UV, "uv", 0, "UV Textures", "Export UV Textures (Face textures) as materials" },
+ { 0, NULL, 0, NULL, NULL }
};
ot->name = "Export COLLADA";
@@ -368,16 +368,9 @@ void WM_OT_collada_export(wmOperatorType *ot)
RNA_def_boolean(func, "deform_bones_only", 0, "Deform Bones only",
"Only export deforming bones with armatures");
-
RNA_def_boolean(func, "active_uv_only", 0, "Only Selected UV Map",
"Export only the selected UV Map");
- RNA_def_boolean(func, "include_uv_textures", 0, "Include UV Textures",
- "Export textures assigned to the object UV Maps");
-
- RNA_def_boolean(func, "include_material_textures", 0, "Include Material Textures",
- "Export textures assigned to the object Materials");
-
RNA_def_boolean(func, "use_texture_copies", 1, "Copy",
"Copy textures to same folder where the .dae file is exported");
@@ -394,11 +387,20 @@ void WM_OT_collada_export(wmOperatorType *ot)
RNA_def_boolean(func, "sort_by_name", 0, "Sort by Object name",
"Sort exported data by Object name");
+
RNA_def_int(func, "export_transformation_type", 0, INT_MIN, INT_MAX,
- "Transform", "Transformation type for translation, scale and rotation", INT_MIN, INT_MAX);
+ "Transform", "Transformation type for translation, scale and rotation", INT_MIN, INT_MAX);
RNA_def_enum(func, "export_transformation_type_selection", prop_bc_export_transformation_type, 0,
- "Transform", "Transformation type for translation, scale and rotation");
+ "Transform", "Transformation type for translation, scale and rotation");
+
+
+ RNA_def_int(func, "export_texture_type", 0, INT_MIN, INT_MAX,
+ "Texture Type", "Type for exported Textures (UV or MAT)", INT_MIN, INT_MAX);
+
+ RNA_def_enum(func, "export_texture_type_selection", prop_bc_export_texture_type, 0,
+ "Texture Type", "Type for exported Textures (UV or MAT)");
+
RNA_def_boolean(func, "open_sim", 0, "Export to SL/OpenSim",
"Compatibility mode for SL, OpenSim and other compatible online worlds");
diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c
index 3725590c188..07fedffaf80 100644
--- a/source/blender/editors/mesh/editmesh_add.c
+++ b/source/blender/editors/mesh/editmesh_add.c
@@ -384,7 +384,7 @@ void MESH_OT_primitive_cone_add(wmOperatorType *ot)
/* props */
RNA_def_int(ot->srna, "vertices", 32, 3, MESH_ADD_VERTS_MAXI, "Vertices", "", 3, 500);
RNA_def_float_distance(ot->srna, "radius1", 1.0f, 0.0, OBJECT_ADD_SIZE_MAXF, "Radius 1", "", 0.001, 100.00);
- RNA_def_float_distance(ot->srna, "radius2", 0.0f, 0.0, OBJECT_ADD_SIZE_MAXF, "Radius 2", "", 0.001, 100.00);
+ RNA_def_float_distance(ot->srna, "radius2", 0.0f, 0.0, OBJECT_ADD_SIZE_MAXF, "Radius 2", "", 0.0, 100.00);
RNA_def_float_distance(ot->srna, "depth", 2.0f, 0.0, OBJECT_ADD_SIZE_MAXF, "Depth", "", 0.001, 100.00);
RNA_def_enum(ot->srna, "end_fill_type", fill_type_items, 1, "Base Fill Type", "");
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index bf59693b856..5e44509e10a 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -1472,7 +1472,7 @@ static void clip_to_ortho_planes(float v1[3], float v2[3], const float center[3]
/* could be v1 or v2 */
sub_v3_v3(v1, center);
- project_plane_v3_v3v3(closest, v1, dir);
+ project_plane_normalized_v3_v3v3(closest, v1, dir);
add_v3_v3(closest, center);
madd_v3_v3v3fl(v1, closest, dir, d);
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index b278d6e1e87..b5a9c4e9e5b 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -1464,8 +1464,6 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
}
if (ob_dst->parent) {
- invert_m4_m4(ob_dst->parentinv, dob->mat);
-
/* note, this may be the parent of other objects, but it should
* still work out ok */
BKE_object_apply_mat4(ob_dst, dob->mat, false, true);
@@ -1486,7 +1484,6 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
ob_dst->partype = PAROBJECT;
/* similer to the code above, see comments */
- invert_m4_m4(ob_dst->parentinv, dob->mat);
BKE_object_apply_mat4(ob_dst, dob->mat, false, true);
DAG_id_tag_update(&ob_dst->id, OB_RECALC_OB);
}
@@ -1640,7 +1637,7 @@ static int convert_exec(bContext *C, wmOperator *op)
MetaBall *mb;
Mesh *me;
const short target = RNA_enum_get(op->ptr, "target");
- const bool keep_original = RNA_boolean_get(op->ptr, "keep_original");
+ bool keep_original = RNA_boolean_get(op->ptr, "keep_original");
int a, mballConverted = 0;
/* don't forget multiple users! */
@@ -1678,6 +1675,19 @@ static int convert_exec(bContext *C, wmOperator *op)
{
for (CollectionPointerLink *link = selected_editable_bases.first; link; link = link->next) {
Base *base = link->ptr.data;
+ ob = base->object;
+
+ /* The way object type conversion works currently (enforcing conversion of *all* objetcs using converted
+ * obdata, even some un-selected/hidden/inother scene ones, sounds totally bad to me.
+ * However, changing this is more design than bugfix, not to mention convoluted code below,
+ * so that will be for later.
+ * But at the very least, do not do that with linked IDs! */
+ if ((ID_IS_LINKED_DATABLOCK(ob) || ID_IS_LINKED_DATABLOCK(ob->data)) && !keep_original) {
+ keep_original = true;
+ BKE_reportf(op->reports, RPT_INFO,
+ "Converting some linked object/object data, enforcing 'Keep Original' option to True");
+ }
+
DAG_id_tag_update(&base->object->id, OB_RECALC_DATA);
}
diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c
index 0fe43c44d7d..568778c0a86 100644
--- a/source/blender/editors/object/object_group.c
+++ b/source/blender/editors/object/object_group.c
@@ -528,8 +528,7 @@ static int group_unlink_exec(bContext *C, wmOperator *UNUSED(op))
if (!group)
return OPERATOR_CANCELLED;
- BKE_libblock_unlink(bmain, group, false, false);
- BKE_libblock_free(bmain, group);
+ BKE_libblock_delete(bmain, group);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, NULL);
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index 7ec43b02b38..3284af2df69 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -2149,24 +2149,6 @@ void ED_object_single_users(Main *bmain, Scene *scene, const bool full, const bo
/******************************* Make Local ***********************************/
-/* helper for below, ma was checked to be not NULL */
-static void make_local_makelocalmaterial(Material *ma)
-{
- AnimData *adt;
- int b;
-
- id_make_local(G.main, &ma->id, false, false);
-
- for (b = 0; b < MAX_MTEX; b++)
- if (ma->mtex[b] && ma->mtex[b]->tex)
- id_make_local(G.main, &ma->mtex[b]->tex->id, false, false);
-
- adt = BKE_animdata_from_id(&ma->id);
- if (adt) BKE_animdata_make_local(adt);
-
- /* nodetree? XXX */
-}
-
enum {
MAKE_LOCAL_SELECT_OB = 1,
MAKE_LOCAL_SELECT_OBDATA = 2,
@@ -2252,123 +2234,142 @@ static bool make_local_all__instance_indirect_unused(Main *bmain, Scene *scene)
return changed;
}
-static int make_local_exec(bContext *C, wmOperator *op)
+static void make_local_animdata_tag_strips(ListBase *strips)
{
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
- AnimData *adt;
- ParticleSystem *psys;
- Material *ma, ***matarar;
- Lamp *la;
- ID *id;
- const int mode = RNA_enum_get(op->ptr, "type");
- int a, b;
+ NlaStrip *strip;
- if (mode == MAKE_LOCAL_ALL) {
- /* de-select so the user can differentiate newly instanced from existing objects */
- BKE_scene_base_deselect_all(scene);
-
- if (make_local_all__instance_indirect_unused(bmain, scene)) {
- BKE_report(op->reports, RPT_INFO,
- "Orphan library objects added to the current scene to avoid loss");
+ for (strip = strips->first; strip; strip = strip->next) {
+ if (strip->act) {
+ strip->act->id.tag &= ~LIB_TAG_PRE_EXISTING;
+ }
+ if (strip->remap && strip->remap->target) {
+ strip->remap->target->id.tag &= ~LIB_TAG_PRE_EXISTING;
}
- BKE_library_make_local(bmain, NULL, NULL, false, false); /* NULL is all libs */
- WM_event_add_notifier(C, NC_WINDOW, NULL);
- return OPERATOR_FINISHED;
+ make_local_animdata_tag_strips(&strip->strips);
}
+}
- tag_localizable_objects(C, mode);
-
- CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
- {
- if ((ob->id.tag & LIB_TAG_DOIT) == 0) {
- continue;
+/* Tag all actions used by given animdata to be made local. */
+static void make_local_animdata_tag(AnimData *adt)
+{
+ if (adt) {
+ /* Actions - Active and Temp */
+ if (adt->action) {
+ adt->action->id.tag &= ~LIB_TAG_PRE_EXISTING;
+ }
+ if (adt->tmpact) {
+ adt->tmpact->id.tag &= ~LIB_TAG_PRE_EXISTING;
+ }
+ /* Remaps */
+ if (adt->remap && adt->remap->target) {
+ adt->remap->target->id.tag &= ~LIB_TAG_PRE_EXISTING;
}
- if (ob->id.lib)
- id_make_local(bmain, &ob->id, false, false);
- }
- CTX_DATA_END;
+ /* Drivers */
+ /* TODO: need to handle the ID-targets too? */
- /* maybe object pointers */
- CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
- {
- if (ob->id.lib == NULL) {
- ID_NEW_REMAP(ob->parent);
+ /* NLA Data */
+ for (NlaTrack *nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
+ make_local_animdata_tag_strips(&nlt->strips);
}
}
- CTX_DATA_END;
-
- CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
- {
- if ((ob->id.tag & LIB_TAG_DOIT) == 0) {
- continue;
- }
+}
- id = ob->data;
+static void make_local_material_tag(Material *ma)
+{
+ if (ma) {
+ ma->id.tag &= ~LIB_TAG_PRE_EXISTING;
+ make_local_animdata_tag(BKE_animdata_from_id(&ma->id));
- if (id && (ELEM(mode, MAKE_LOCAL_SELECT_OBDATA, MAKE_LOCAL_SELECT_OBDATA_MATERIAL))) {
- id_make_local(bmain, id, false, false);
- adt = BKE_animdata_from_id(id);
- if (adt) BKE_animdata_make_local(adt);
+ /* About nodetrees: root one is made local together with material, others we keep linked for now... */
- /* tag indirect data direct */
- matarar = give_matarar(ob);
- if (matarar) {
- for (a = 0; a < ob->totcol; a++) {
- ma = (*matarar)[a];
- if (ma)
- id_lib_extern(&ma->id);
- }
+ for (int a = 0; a < MAX_MTEX; a++) {
+ if (ma->mtex[a] && ma->mtex[a]->tex) {
+ ma->mtex[a]->tex->id.tag &= ~LIB_TAG_PRE_EXISTING;
}
}
+ }
+}
- for (psys = ob->particlesystem.first; psys; psys = psys->next)
- id_make_local(bmain, &psys->part->id, false, false);
+static int make_local_exec(bContext *C, wmOperator *op)
+{
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ ParticleSystem *psys;
+ Material *ma, ***matarar;
+ Lamp *la;
+ const int mode = RNA_enum_get(op->ptr, "type");
+ int a;
+
+ /* Note: we (ab)use LIB_TAG_PRE_EXISTING to cherry pick which ID to make local... */
+ if (mode == MAKE_LOCAL_ALL) {
+ BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, false);
+
+ /* de-select so the user can differentiate newly instanced from existing objects */
+ BKE_scene_base_deselect_all(scene);
- adt = BKE_animdata_from_id(&ob->id);
- if (adt) BKE_animdata_make_local(adt);
+ if (make_local_all__instance_indirect_unused(bmain, scene)) {
+ BKE_report(op->reports, RPT_INFO, "Orphan library objects added to the current scene to avoid loss");
+ }
}
- CTX_DATA_END;
+ else {
+ BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, true);
+ tag_localizable_objects(C, mode);
- if (mode == MAKE_LOCAL_SELECT_OBDATA_MATERIAL) {
CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
{
if ((ob->id.tag & LIB_TAG_DOIT) == 0) {
continue;
}
- if (ob->type == OB_LAMP) {
- la = ob->data;
-
- for (b = 0; b < MAX_MTEX; b++)
- if (la->mtex[b] && la->mtex[b]->tex)
- id_make_local(bmain, &la->mtex[b]->tex->id, false, false);
+ ob->id.tag &= ~LIB_TAG_PRE_EXISTING;
+ make_local_animdata_tag(BKE_animdata_from_id(&ob->id));
+ for (psys = ob->particlesystem.first; psys; psys = psys->next) {
+ psys->part->id.tag &= ~LIB_TAG_PRE_EXISTING;
}
- else {
+
+ if (mode == MAKE_LOCAL_SELECT_OBDATA_MATERIAL) {
for (a = 0; a < ob->totcol; a++) {
ma = ob->mat[a];
- if (ma)
- make_local_makelocalmaterial(ma);
+ if (ma) {
+ make_local_material_tag(ma);
+ }
}
matarar = (Material ***)give_matarar(ob);
if (matarar) {
for (a = 0; a < ob->totcol; a++) {
ma = (*matarar)[a];
- if (ma)
- make_local_makelocalmaterial(ma);
+ if (ma) {
+ make_local_material_tag(ma);
+ }
+ }
+ }
+
+ if (ob->type == OB_LAMP) {
+ BLI_assert(ob->data != NULL);
+ la = ob->data;
+ for (a = 0; a < MAX_MTEX; a++) {
+ if (la->mtex[a] && la->mtex[a]->tex) {
+ la->id.tag &= ~LIB_TAG_PRE_EXISTING;
+ }
}
}
}
+
+ if (ELEM(mode, MAKE_LOCAL_SELECT_OBDATA, MAKE_LOCAL_SELECT_OBDATA_MATERIAL) && ob->data != NULL) {
+ ID *ob_data = ob->data;
+ ob_data->tag &= ~LIB_TAG_PRE_EXISTING;
+ make_local_animdata_tag(BKE_animdata_from_id(ob_data));
+ }
}
CTX_DATA_END;
}
- BKE_main_id_clear_newpoins(bmain);
- WM_event_add_notifier(C, NC_WINDOW, NULL);
+ BKE_library_make_local(bmain, NULL, NULL, true, false); /* NULL is all libs */
+ WM_event_add_notifier(C, NC_WINDOW, NULL);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/physics/dynamicpaint_ops.c b/source/blender/editors/physics/dynamicpaint_ops.c
index 3d7a45843cc..edc3f6c784c 100644
--- a/source/blender/editors/physics/dynamicpaint_ops.c
+++ b/source/blender/editors/physics/dynamicpaint_ops.c
@@ -279,10 +279,10 @@ void DPAINT_OT_output_toggle(wmOperatorType *ot)
/***************************** Image Sequence Baking ******************************/
typedef struct DynamicPaintBakeJob {
- /* from wmJob */
- void *owner;
- short *stop, *do_update;
- float *progress;
+ /* from wmJob */
+ void *owner;
+ short *stop, *do_update;
+ float *progress;
struct Main *bmain;
Scene *scene;
@@ -297,13 +297,13 @@ typedef struct DynamicPaintBakeJob {
static void dpaint_bake_free(void *customdata)
{
- DynamicPaintBakeJob *job = customdata;
- MEM_freeN(job);
+ DynamicPaintBakeJob *job = customdata;
+ MEM_freeN(job);
}
static void dpaint_bake_endjob(void *customdata)
{
- DynamicPaintBakeJob *job = customdata;
+ DynamicPaintBakeJob *job = customdata;
DynamicPaintCanvasSettings *canvas = job->canvas;
canvas->flags &= ~MOD_DPAINT_BAKING;
@@ -311,7 +311,7 @@ static void dpaint_bake_endjob(void *customdata)
dynamicPaint_freeSurfaceData(job->surface);
G.is_rendering = false;
- BKE_spacedata_draw_locks(false);
+ BKE_spacedata_draw_locks(false);
WM_set_locked_interface(G.main->wm.first, false);
@@ -421,26 +421,26 @@ static void dynamicPaint_bakeImageSequence(DynamicPaintBakeJob *job)
static void dpaint_bake_startjob(void *customdata, short *stop, short *do_update, float *progress)
{
- DynamicPaintBakeJob *job = customdata;
+ DynamicPaintBakeJob *job = customdata;
- job->stop = stop;
- job->do_update = do_update;
- job->progress = progress;
+ job->stop = stop;
+ job->do_update = do_update;
+ job->progress = progress;
job->start = PIL_check_seconds_timer();
job->success = 1;
- G.is_break = false; /* reset BKE_blender_test_break*/
+ G.is_break = false; /* reset BKE_blender_test_break*/
/* XXX annoying hack: needed to prevent data corruption when changing
* scene frame in separate threads
- */
- G.is_rendering = true;
- BKE_spacedata_draw_locks(true);
+ */
+ G.is_rendering = true;
+ BKE_spacedata_draw_locks(true);
dynamicPaint_bakeImageSequence(job);
- *do_update = true;
- *stop = 0;
+ *do_update = true;
+ *stop = 0;
}
/*
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index e22a145b3a6..2541aaa4b11 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -4419,7 +4419,7 @@ void PE_undo_push(Scene *scene, const char *str)
undo= undo->prev;
}
if (undo) {
- while (edit->undo.first!=undo) {
+ while (edit->undo.first != undo) {
PTCacheUndo *first= edit->undo.first;
BLI_remlink(&edit->undo, first);
free_PTCacheUndo(first);
diff --git a/source/blender/editors/physics/physics_pointcache.c b/source/blender/editors/physics/physics_pointcache.c
index e81aa584586..f36ebb3715e 100644
--- a/source/blender/editors/physics/physics_pointcache.c
+++ b/source/blender/editors/physics/physics_pointcache.c
@@ -99,45 +99,45 @@ static int ptcache_job_break(void *customdata)
static void ptcache_job_update(void *customdata, float progress, int *cancel)
{
- PointCacheJob *job = customdata;
+ PointCacheJob *job = customdata;
- if (ptcache_job_break(job)) {
- *cancel = 1;
- }
+ if (ptcache_job_break(job)) {
+ *cancel = 1;
+ }
- *(job->do_update) = true;
- *(job->progress) = progress;
+ *(job->do_update) = true;
+ *(job->progress) = progress;
}
static void ptcache_job_startjob(void *customdata, short *stop, short *do_update, float *progress)
{
- PointCacheJob *job = customdata;
+ PointCacheJob *job = customdata;
- job->stop = stop;
- job->do_update = do_update;
- job->progress = progress;
+ job->stop = stop;
+ job->do_update = do_update;
+ job->progress = progress;
- G.is_break = false;
+ G.is_break = false;
- /* XXX annoying hack: needed to prevent data corruption when changing
- * scene frame in separate threads
- */
- G.is_rendering = true;
- BKE_spacedata_draw_locks(true);
+ /* XXX annoying hack: needed to prevent data corruption when changing
+ * scene frame in separate threads
+ */
+ G.is_rendering = true;
+ BKE_spacedata_draw_locks(true);
BKE_ptcache_bake(job->baker);
- *do_update = true;
- *stop = 0;
+ *do_update = true;
+ *stop = 0;
}
static void ptcache_job_endjob(void *customdata)
{
- PointCacheJob *job = customdata;
+ PointCacheJob *job = customdata;
Scene *scene = job->baker->scene;
- G.is_rendering = false;
- BKE_spacedata_draw_locks(false);
+ G.is_rendering = false;
+ BKE_spacedata_draw_locks(false);
WM_set_locked_interface(G.main->wm.first, false);
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index fa18b82507e..35d772afae7 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -1180,7 +1180,7 @@ void ED_preview_icon_render(Main *bmain, Scene *scene, ID *id, unsigned int *rec
ip.bmain = bmain;
ip.scene = scene;
- ip.owner = id;
+ ip.owner = BKE_previewimg_id_ensure(id);
ip.id = id;
icon_preview_add_size(&ip, rect, sizex, sizey);
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index 7d2b77028fc..f469686b0b2 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -1228,6 +1228,7 @@ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win)
winrct.ymax = winsize_y - 1;
/* header size depends on DPI, let's verify */
+ WM_window_set_dpi(win);
screen_refresh_headersizes();
screen_test_scale(win->screen, winsize_x, winsize_y);
@@ -1762,7 +1763,7 @@ bool ED_screen_delete_scene(bContext *C, Scene *scene)
BKE_libblock_remap(bmain, scene, newscene, ID_REMAP_SKIP_INDIRECT_USAGE | ID_REMAP_SKIP_NEVER_NULL_USAGE);
- BKE_libblock_free(bmain, scene);
+ BKE_libblock_free_us(bmain, scene);
return true;
}
@@ -1926,7 +1927,6 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *sa, const s
ED_screen_set(C, sc);
- BKE_screen_free(oldscreen);
BKE_libblock_free(CTX_data_main(C), oldscreen);
/* After we've restored back to SCREENNORMAL, we have to wait with
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 9dbc082c119..c99d9add432 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -3756,7 +3756,7 @@ static int screen_animation_cancel_exec(bContext *C, wmOperator *op)
bScreen *screen = ED_screen_animation_playing(CTX_wm_manager(C));
if (screen) {
- if (RNA_boolean_get(op->ptr, "restore_frame")) {
+ if (RNA_boolean_get(op->ptr, "restore_frame") && screen->animtimer) {
ScreenAnimData *sad = screen->animtimer->customdata;
Scene *scene = CTX_data_scene(C);
diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c
index 72de7e5c81c..1d67ac620b0 100644
--- a/source/blender/editors/space_buttons/buttons_texture.c
+++ b/source/blender/editors/space_buttons/buttons_texture.c
@@ -470,7 +470,7 @@ void buttons_texture_context_compute(const bContext *C, SpaceButs *sbuts)
}
else {
/* set one user as active based on active index */
- if (ct->index == BLI_listbase_count_ex(&ct->users, ct->index + 1))
+ if (ct->index >= BLI_listbase_count_ex(&ct->users, ct->index + 1))
ct->index = 0;
ct->user = BLI_findlink(&ct->users, ct->index);
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index c2cfca295a4..772d87a9bf4 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -1067,6 +1067,7 @@ typedef struct ImageOpenData {
typedef struct ImageFrameRange {
struct ImageFrameRange *next, *prev;
ListBase frames;
+ /** The full path of the first file in the list of image files */
char filepath[FILE_MAX];
} ImageFrameRange;
@@ -1092,12 +1093,12 @@ static void image_open_cancel(bContext *UNUSED(C), wmOperator *op)
/**
* \brief Get a list of frames from the list of image files matching the first file name sequence pattern
* \param ptr [in] the RNA pointer containing the "directory" entry and "files" collection
- * \param frames [out] the list of frame numbers found in the files matching the first one by name
- * \param path [out] the full path of the first file in the list of image files
+ * \param frames_all [out] the list of frame numbers found in the files matching the first one by name
*/
static void image_sequence_get_frame_ranges(PointerRNA *ptr, ListBase *frames_all)
{
char dir[FILE_MAXDIR];
+ const bool do_frame_range = RNA_boolean_get(ptr, "use_sequence_detection");
ImageFrameRange *frame_range = NULL;
RNA_string_get(ptr, "directory", dir);
@@ -1113,7 +1114,8 @@ static void image_sequence_get_frame_ranges(PointerRNA *ptr, ListBase *frames_al
frame->framenr = BLI_stringdec(filename, head, tail, &digits);
/* still in the same sequence */
- if ((frame_range != NULL) &&
+ if (do_frame_range &&
+ (frame_range != NULL) &&
(STREQLEN(base_head, head, FILE_MAX)) &&
(STREQLEN(base_tail, tail, FILE_MAX)))
{
@@ -1448,6 +1450,9 @@ void IMAGE_OT_open(wmOperatorType *ot)
ot, FILE_TYPE_FOLDER | FILE_TYPE_IMAGE | FILE_TYPE_MOVIE, FILE_SPECIAL, FILE_OPENFILE,
WM_FILESEL_FILEPATH | WM_FILESEL_DIRECTORY | WM_FILESEL_FILES | WM_FILESEL_RELPATH,
FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA);
+
+ RNA_def_boolean(ot->srna, "use_sequence_detection", true, "Detect Sequences",
+ "Automatically detect animated sequences in selected images (based on file names)");
}
/******************** Match movie length operator ********************/
diff --git a/source/blender/editors/space_info/info_ops.c b/source/blender/editors/space_info/info_ops.c
index 0e427623840..b87a0de23b9 100644
--- a/source/blender/editors/space_info/info_ops.c
+++ b/source/blender/editors/space_info/info_ops.c
@@ -162,7 +162,6 @@ static int pack_all_exec(bContext *C, wmOperator *op)
Main *bmain = CTX_data_main(C);
packAll(bmain, op->reports, true);
- G.fileflags |= G_AUTOPACK;
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_nla/nla_buttons.c b/source/blender/editors/space_nla/nla_buttons.c
index 5355b8012db..c774b99629c 100644
--- a/source/blender/editors/space_nla/nla_buttons.c
+++ b/source/blender/editors/space_nla/nla_buttons.c
@@ -552,7 +552,7 @@ void nla_buttons_register(ARegionType *art)
pt = MEM_callocN(sizeof(PanelType), "spacetype nla panel modifiers");
strcpy(pt->idname, "NLA_PT_modifiers");
strcpy(pt->label, N_("Modifiers"));
- strcpy(pt->category, "Modifiers");
+ strcpy(pt->category, "Modifiers");
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
pt->draw = nla_panel_modifiers;
pt->poll = nla_strip_eval_panel_poll;
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index 9dc39b1839b..5f8f839025f 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -2086,7 +2086,7 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op)
/* make sure all clipboard nodes would be valid in the target tree */
all_nodes_valid = true;
for (node = clipboard_nodes_lb->first; node; node = node->next) {
- if (!node->typeinfo->poll_instance(node, ntree)) {
+ if (!node->typeinfo->poll_instance || !node->typeinfo->poll_instance(node, ntree)) {
all_nodes_valid = false;
BKE_reportf(op->reports, RPT_ERROR, "Cannot add node %s into node tree %s", node->name, ntree->id.name + 2);
}
diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c
index bbdf6feef01..2267316d257 100644
--- a/source/blender/editors/space_node/space_node.c
+++ b/source/blender/editors/space_node/space_node.c
@@ -753,6 +753,10 @@ static void node_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegi
break;
}
break;
+ case NC_WM:
+ if (wmn->data == ND_JOB)
+ ED_region_tag_redraw(ar);
+ break;
case NC_SCENE:
case NC_MATERIAL:
case NC_TEXTURE:
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index 335eb95da0e..265a19b9e7e 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -1944,7 +1944,7 @@ static int outliner_orphans_purge_invoke(bContext *C, wmOperator *op, const wmEv
{
/* present a prompt to informing users that this change is irreversible */
return WM_operator_confirm_message(C, op,
- "Purging unused data-blocks cannot be undone. "
+ "Purging unused data-blocks cannot be undone and saves to current .blend file. "
"Click here to proceed...");
}
@@ -1966,7 +1966,8 @@ void OUTLINER_OT_orphans_purge(wmOperatorType *ot)
/* identifiers */
ot->idname = "OUTLINER_OT_orphans_purge";
ot->name = "Purge All";
- ot->description = "Clear all orphaned data-blocks without any users from the file (cannot be undone)";
+ ot->description = "Clear all orphaned data-blocks without any users from the file "
+ "(cannot be undone, saves to current .blend file)";
/* callbacks */
ot->invoke = outliner_orphans_purge_invoke;
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index 7e05c76b35b..18cc2a015e6 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -707,7 +707,12 @@ static eOLDrawState tree_element_active_pose(
{
Object *ob = (Object *)tselem->id;
Base *base = BKE_scene_base_find(scene, ob);
-
+
+ if (base == NULL) {
+ /* Armature not instantiated in current scene (e.g. inside an appended group...). */
+ return OL_DRAWSEL_NONE;
+ }
+
if (set != OL_SETSEL_NONE) {
if (scene->obedit)
ED_object_editmode_exit(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO);
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index cdb3df0fae9..29dcf73109c 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -235,8 +235,7 @@ static void unlink_group_cb(
}
else {
Main *bmain = CTX_data_main(C);
- BKE_libblock_unlink(bmain, group, false, false);
- BKE_libblock_free(bmain, group);
+ BKE_libblock_delete(bmain, group);
}
}
@@ -399,7 +398,7 @@ static void object_deselect_cb(
static void object_delete_cb(
bContext *C, ReportList *reports, Scene *scene, TreeElement *te,
- TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
+ TreeStoreElem *tsep, TreeStoreElem *tselem, void *user_data)
{
Base *base = (Base *)te->directdata;
@@ -436,7 +435,7 @@ static void object_delete_cb(
* Should not happen ideally, but does happens, see T51625.
* Rather than twisting in all kind of ways to address all possible cases leading to that situation, simpler
* to allow deleting such object as a mere generic data-block. */
- WM_operator_name_call(C, "OUTLINER_OT_id_delete", WM_OP_INVOKE_REGION_WIN, NULL);
+ id_delete_cb(C, reports, scene, te, tsep, tselem, user_data);
}
}
@@ -1058,7 +1057,7 @@ static EnumPropertyItem prop_group_op_types[] = {
{OL_GROUPOP_UNLINK, "UNLINK", 0, "Unlink Group", ""},
{OL_GROUPOP_LOCAL, "LOCAL", 0, "Make Local Group", ""},
{OL_GROUPOP_LINK, "LINK", 0, "Link Group Objects to Scene", ""},
- {OL_GROUPOP_DELETE, "DELETE", 0, "Delete Group", "WARNING: no undo"},
+ {OL_GROUPOP_DELETE, "DELETE", 0, "Delete Group", ""},
{OL_GROUPOP_REMAP, "REMAP", 0, "Remap Users",
"Make all users of selected data-blocks to use instead current (clicked) one"},
{OL_GROUPOP_INSTANCE, "INSTANCE", 0, "Instance Groups in Scene", ""},
@@ -1097,7 +1096,7 @@ static int outliner_group_operation_exec(bContext *C, wmOperator *op)
DAG_relations_tag_update(CTX_data_main(C));
break;
case OL_GROUPOP_DELETE:
- WM_operator_name_call(C, "OUTLINER_OT_id_delete", WM_OP_INVOKE_REGION_WIN, NULL);
+ outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, id_delete_cb, NULL);
break;
case OL_GROUPOP_REMAP:
outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, id_remap_cb, NULL);
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index ec46c5df9a0..09a49f201d4 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -1080,6 +1080,12 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
PointerRNA pptr, propptr, *ptr = (PointerRNA *)idv;
PropertyRNA *prop, *iterprop;
PropertyType proptype;
+
+ /* Don't display arrays larger, weak but index is stored as a short,
+ * also the outliner isn't intended for editing such large data-sets. */
+ BLI_STATIC_ASSERT(sizeof(te->index) == 2, "Index is no longer short!");
+ const int tot_limit = SHRT_MAX;
+
int a, tot;
/* we do lazy build, for speed and to avoid infinite recusion */
@@ -1101,6 +1107,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
iterprop = RNA_struct_iterator_property(ptr->type);
tot = RNA_property_collection_length(ptr, iterprop);
+ CLAMP_MAX(tot, tot_limit);
/* auto open these cases */
if (!parent || (RNA_property_type(parent->directdata)) == PROP_POINTER)
@@ -1147,6 +1154,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
}
else if (proptype == PROP_COLLECTION) {
tot = RNA_property_collection_length(ptr, prop);
+ CLAMP_MAX(tot, tot_limit);
if (TSELEM_OPEN(tselem, soops)) {
for (a = 0; a < tot; a++) {
@@ -1159,6 +1167,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
}
else if (ELEM(proptype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT)) {
tot = RNA_property_array_length(ptr, prop);
+ CLAMP_MAX(tot, tot_limit);
if (TSELEM_OPEN(tselem, soops)) {
for (a = 0; a < tot; a++)
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index 2d6892c1091..3ae4a233353 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -3352,6 +3352,9 @@ static int sequencer_swap_data_exec(bContext *C, wmOperator *op)
if (seq_act->sound) BKE_sound_add_scene_sound_defaults(scene, seq_act);
if (seq_other->sound) BKE_sound_add_scene_sound_defaults(scene, seq_other);
+ BKE_sequence_invalidate_cache(scene, seq_act);
+ BKE_sequence_invalidate_cache(scene, seq_other);
+
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c
index 48c49f36471..d88ed36e392 100644
--- a/source/blender/editors/space_sequencer/sequencer_select.c
+++ b/source/blender/editors/space_sequencer/sequencer_select.c
@@ -683,7 +683,7 @@ static int sequencer_select_less_exec(bContext *C, wmOperator *UNUSED(op))
if (!select_more_less_seq__internal(scene, false, false))
return OPERATOR_CANCELLED;
-
+
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER | NA_SELECTED, scene);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/space_text/text_autocomplete.c b/source/blender/editors/space_text/text_autocomplete.c
index 9b0bd30ff11..da5fa9da046 100644
--- a/source/blender/editors/space_text/text_autocomplete.c
+++ b/source/blender/editors/space_text/text_autocomplete.c
@@ -328,7 +328,7 @@ static int text_autocomplete_modal(bContext *C, wmOperator *op, const wmEvent *e
if (tools & TOOL_SUGG_LIST) {
texttool_suggest_clear();
}
- if (tools & TOOL_DOCUMENT) {
+ if (tools & TOOL_DOCUMENT) {
texttool_docs_clear();
doc_scroll = 0;
}
diff --git a/source/blender/editors/space_text/text_format_pov.c b/source/blender/editors/space_text/text_format_pov.c
index eb6877d297d..0d19c503798 100644
--- a/source/blender/editors/space_text/text_format_pov.c
+++ b/source/blender/editors/space_text/text_format_pov.c
@@ -100,6 +100,7 @@ static int txtfmt_pov_find_reserved_keywords(const char *string)
else if (STR_LITERAL_STARTSWITH(string, "adc_bailout", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "albedo", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "all_intersections", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "translucency", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "all", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "alpha", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "altitude", len)) i = len;
@@ -149,7 +150,6 @@ static int txtfmt_pov_find_reserved_keywords(const char *string)
else if (STR_LITERAL_STARTSWITH(string, "falloff_angle", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "falloff", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "file_gamma", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "finish", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "flatness", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "flip", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "focal_point", len)) i = len;
@@ -372,6 +372,7 @@ static int txtfmt_pov_find_reserved_builtins(const char *string)
else if (STR_LITERAL_STARTSWITH(string, "mesh", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "object", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "ovus", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "lemon", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "parametric", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "plane", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "poly", len)) i = len;
@@ -383,6 +384,7 @@ static int txtfmt_pov_find_reserved_builtins(const char *string)
else if (STR_LITERAL_STARTSWITH(string, "rainbow", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "sky_sphere", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "smooth_triangle", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "cubic_spline", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "sphere_sweep", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "sphere", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "spline", len)) i = len;
@@ -463,7 +465,12 @@ static int txtfmt_pov_find_specialvar(const char *string)
{
int i, len;
/* Modifiers */
- if (STR_LITERAL_STARTSWITH(string, "adaptive", len)) i = len;
+ if (STR_LITERAL_STARTSWITH(string, "interior_texture", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "double_illuminate", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "media_interaction", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "media_attenuation", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "projected_through", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "noise_generator", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "agate_turb", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "bounded_by", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "brick_size", len)) i = len;
@@ -481,7 +488,6 @@ static int txtfmt_pov_find_specialvar(const char *string)
else if (STR_LITERAL_STARTSWITH(string, "cubic_wave", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "density_map", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "density", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "double_illuminate", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "fade_color", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "fade_colour", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "fade_distance", len)) i = len;
@@ -490,7 +496,7 @@ static int txtfmt_pov_find_specialvar(const char *string)
else if (STR_LITERAL_STARTSWITH(string, "global_lights", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "hollow", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "image_map", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "interior_texture", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "adaptive", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "interior", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "interpolate", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "inverse", len)) i = len;
@@ -501,8 +507,6 @@ static int txtfmt_pov_find_specialvar(const char *string)
else if (STR_LITERAL_STARTSWITH(string, "material", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "matrix", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "media", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "media_attenuation", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "media_interaction", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "mm_per_unit", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "mortar", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "no_bump_scale", len)) i = len;
@@ -510,7 +514,6 @@ static int txtfmt_pov_find_specialvar(const char *string)
else if (STR_LITERAL_STARTSWITH(string, "no_radiosity", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "no_reflection", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "no_shadow", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "noise_generator", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "normal_map", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "normal", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "octaves", len)) i = len;
@@ -522,8 +525,8 @@ static int txtfmt_pov_find_specialvar(const char *string)
else if (STR_LITERAL_STARTSWITH(string, "photons", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "pigment_map", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "pigment", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "finish", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "poly_wave", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "projected_through", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "quick_color", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "quick_colour", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "ramp_wave", len)) i = len;
@@ -693,9 +696,9 @@ static void txtfmt_pov_format_line(SpaceText *st, TextLine *line, const bool do_
}
/* Handle continuations */
else if (cont) {
- /* Multi-line comments */
+ /* C-Style comments */
if (cont & FMT_CONT_COMMENT_C) {
- if (*str == ']' && *(str + 1) == ']') {
+ if (*str == '*' && *(str + 1) == '/') {
*fmt = FMT_TYPE_COMMENT; fmt++; str++;
*fmt = FMT_TYPE_COMMENT;
cont = FMT_CONT_NOP;
@@ -752,7 +755,7 @@ static void txtfmt_pov_format_line(SpaceText *st, TextLine *line, const bool do_
}
}
/* Punctuation */
- else if ((*str != '#') && text_check_delim(*str)) {
+ else if (text_check_delim(*str)) {
*fmt = FMT_TYPE_SYMBOL;
}
/* Identifiers and other text (no previous ws. or delims. so text continues) */
diff --git a/source/blender/editors/space_text/text_format_pov_ini.c b/source/blender/editors/space_text/text_format_pov_ini.c
index 5c20a1c5f00..719f4e3c036 100644
--- a/source/blender/editors/space_text/text_format_pov_ini.c
+++ b/source/blender/editors/space_text/text_format_pov_ini.c
@@ -104,7 +104,11 @@ static int txtfmt_ini_find_reserved(const char *string)
* list is from...
* http://www.povray.org/documentation/view/3.7.0/212/
*/
- if (STR_LITERAL_STARTSWITH(string, "clock_delta", len)) i = len;
+ if (STR_LITERAL_STARTSWITH(string, "Antialias_Threshold", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Bounding_Method", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Antialias_Gamma", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Antialias_Depth", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "clock_delta", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "clock_on", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "clock", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "final_clock", len)) i = len;
@@ -134,6 +138,7 @@ static int txtfmt_ini_find_reserved(const char *string)
else if (STR_LITERAL_STARTSWITH(string, "Create_Ini", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Display_Gamma", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Display", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Version", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Pause_When_Done", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Verbose", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Preview_Start_Size", len)) i = len;
@@ -183,7 +188,6 @@ static int txtfmt_ini_find_reserved(const char *string)
else if (STR_LITERAL_STARTSWITH(string, "Split_Unions", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Antialias", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Sampling_Method", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "Antialias_Threshold", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Jitter_Amount", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Jitter", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Antialias_Depth", len)) i = len;
diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c
index 314b7bf3335..5208013b6fe 100644
--- a/source/blender/editors/space_view3d/drawarmature.c
+++ b/source/blender/editors/space_view3d/drawarmature.c
@@ -1903,6 +1903,11 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
}
}
+ /* custom bone may draw outline double-width */
+ if (arm->flag & ARM_POSEMODE) {
+ glLineWidth(1.0f);
+ }
+
/* draw custom bone shapes as wireframes */
if (!(arm->flag & ARM_NO_CUSTOM) &&
(draw_wire || (dt <= OB_WIRE)) )
@@ -1968,11 +1973,6 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
index = -1;
}
}
-
- /* custom bone may draw outline double-width */
- if (arm->flag & ARM_POSEMODE) {
- glLineWidth(1.0f);
- }
/* wire draw over solid only in posemode */
if ((dt <= OB_WIRE) || (arm->flag & ARM_POSEMODE) || ELEM(arm->drawtype, ARM_LINE, ARM_WIRE)) {
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 884bc6b83ba..3f11703973d 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -7347,7 +7347,7 @@ static void draw_object_wire_color(Scene *scene, Base *base, unsigned char r_ob_
theme_id = TH_GROUP_ACTIVE;
if (scene->basact != base) {
- theme_shade = -16;
+ theme_shade = -32;
}
}
else {
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index eda4d51e7e8..5c13fd37dda 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -1191,7 +1191,7 @@ int view3d_opengl_select(
hits = GPU_select_end();
/* second pass, to get the closest object to camera */
- if (do_passes) {
+ if (do_passes && (hits > 0)) {
GPU_select_begin(buffer, bufsize, &rect, GPU_SELECT_NEAREST_SECOND_PASS, hits);
ED_view3d_draw_select_loop(vc, scene, v3d, ar, use_obedit_skip, use_nearest);
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index d786c755529..ca6e2267218 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -3051,19 +3051,13 @@ static void Bend(TransInfo *t, const int UNUSED(mval[2]))
/** \name Transform Shear
* \{ */
-static void postInputShear(TransInfo *UNUSED(t), float values[3])
-{
- mul_v3_fl(values, 0.05f);
-}
-
static void initShear(TransInfo *t)
{
t->mode = TFM_SHEAR;
t->transform = applyShear;
t->handleEvent = handleEventShear;
-
- setInputPostFct(&t->mouse, postInputShear);
- initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_ABSOLUTE);
+
+ initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_RATIO);
t->idx_max = 0;
t->num.idx_max = 0;
@@ -3085,24 +3079,24 @@ static eRedrawFlag handleEventShear(TransInfo *t, const wmEvent *event)
if (event->type == MIDDLEMOUSE && event->val == KM_PRESS) {
/* Use custom.mode.data pointer to signal Shear direction */
if (t->custom.mode.data == NULL) {
- initMouseInputMode(t, &t->mouse, INPUT_VERTICAL_ABSOLUTE);
+ initMouseInputMode(t, &t->mouse, INPUT_VERTICAL_RATIO);
t->custom.mode.data = (void *)1;
}
else {
- initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_ABSOLUTE);
+ initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_RATIO);
t->custom.mode.data = NULL;
}
status = TREDRAW_HARD;
}
else if (event->type == XKEY && event->val == KM_PRESS) {
- initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_ABSOLUTE);
+ initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_RATIO);
t->custom.mode.data = NULL;
status = TREDRAW_HARD;
}
else if (event->type == YKEY && event->val == KM_PRESS) {
- initMouseInputMode(t, &t->mouse, INPUT_VERTICAL_ABSOLUTE);
+ initMouseInputMode(t, &t->mouse, INPUT_VERTICAL_RATIO);
t->custom.mode.data = (void *)1;
status = TREDRAW_HARD;
@@ -4073,13 +4067,15 @@ static void initTrackball(TransInfo *t)
static void applyTrackballValue(TransInfo *t, const float axis1[3], const float axis2[3], float angles[2])
{
TransData *td = t->data;
- float mat[3][3], smat[3][3], totmat[3][3];
+ float mat[3][3];
+ float axis[3];
+ float angle;
int i;
- axis_angle_normalized_to_mat3(smat, axis1, angles[0]);
- axis_angle_normalized_to_mat3(totmat, axis2, angles[1]);
-
- mul_m3_m3m3(mat, smat, totmat);
+ mul_v3_v3fl(axis, axis1, angles[0]);
+ madd_v3_v3fl(axis, axis2, angles[1]);
+ angle = normalize_v3(axis);
+ axis_angle_normalized_to_mat3(mat, axis, angle);
for (i = 0; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
@@ -4089,10 +4085,7 @@ static void applyTrackballValue(TransInfo *t, const float axis1[3], const float
continue;
if (t->flag & T_PROP_EDIT) {
- axis_angle_normalized_to_mat3(smat, axis1, td->factor * angles[0]);
- axis_angle_normalized_to_mat3(totmat, axis2, td->factor * angles[1]);
-
- mul_m3_m3m3(mat, smat, totmat);
+ axis_angle_normalized_to_mat3(mat, axis, td->factor * angle);
}
ElementRotation(t, td, mat, t->around);
@@ -4278,7 +4271,7 @@ static void headerTranslation(TransInfo *t, const float vec[3], char str[UI_MAX_
bUnit_AsString(distvec, sizeof(distvec), dist * t->scene->unit.scale_length, 4, t->scene->unit.system,
B_UNIT_LENGTH, do_split, false);
}
- else if (dist > 1e10f || dist < -1e10f) {
+ else if (dist > 1e10f || dist < -1e10f) {
/* prevent string buffer overflow */
BLI_snprintf(distvec, NUM_STR_REP_LEN, "%.4e", dist);
}
@@ -5565,7 +5558,7 @@ static void slide_origdata_interp_data_vert(
float v_proj[3][3];
if (do_loop_weight || do_loop_mdisps) {
- project_plane_v3_v3v3(v_proj[1], sv->co_orig_3d, v_proj_axis);
+ project_plane_normalized_v3_v3v3(v_proj[1], sv->co_orig_3d, v_proj_axis);
}
// BM_ITER_ELEM (l, &liter, sv->v, BM_LOOPS_OF_VERT) {
@@ -5599,19 +5592,19 @@ static void slide_origdata_interp_data_vert(
/* In the unlikely case that we're next to a zero length edge - walk around the to the next.
* Since we only need to check if the vertex is in this corner,
* its not important _which_ loop - as long as its not overlapping 'sv->co_orig_3d', see: T45096. */
- project_plane_v3_v3v3(v_proj[0], co_prev, v_proj_axis);
+ project_plane_normalized_v3_v3v3(v_proj[0], co_prev, v_proj_axis);
while (UNLIKELY(((co_prev_ok = (len_squared_v3v3(v_proj[1], v_proj[0]) > eps)) == false) &&
((l_prev = l_prev->prev) != l->next)))
{
co_prev = slide_origdata_orig_vert_co(sod, l_prev->v);
- project_plane_v3_v3v3(v_proj[0], co_prev, v_proj_axis);
+ project_plane_normalized_v3_v3v3(v_proj[0], co_prev, v_proj_axis);
}
- project_plane_v3_v3v3(v_proj[2], co_next, v_proj_axis);
+ project_plane_normalized_v3_v3v3(v_proj[2], co_next, v_proj_axis);
while (UNLIKELY(((co_next_ok = (len_squared_v3v3(v_proj[1], v_proj[2]) > eps)) == false) &&
((l_next = l_next->next) != l->prev)))
{
co_next = slide_origdata_orig_vert_co(sod, l_next->v);
- project_plane_v3_v3v3(v_proj[2], co_next, v_proj_axis);
+ project_plane_normalized_v3_v3v3(v_proj[2], co_next, v_proj_axis);
}
if (co_prev_ok && co_next_ok) {
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 04b9ae75c8f..b7a42121e92 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -771,34 +771,43 @@ int count_set_pose_transflags(int *out_mode, short around, Object *ob)
/* -------- Auto-IK ---------- */
/* adjust pose-channel's auto-ik chainlen */
-static void pchan_autoik_adjust(bPoseChannel *pchan, short chainlen)
+static bool pchan_autoik_adjust(bPoseChannel *pchan, short chainlen)
{
bConstraint *con;
+ bool changed = false;
/* don't bother to search if no valid constraints */
- if ((pchan->constflag & (PCHAN_HAS_IK | PCHAN_HAS_TARGET)) == 0)
- return;
+ if ((pchan->constflag & (PCHAN_HAS_IK | PCHAN_HAS_TARGET)) == 0) {
+ return changed;
+ }
/* check if pchan has ik-constraint */
for (con = pchan->constraints.first; con; con = con->next) {
if (con->type == CONSTRAINT_TYPE_KINEMATIC && (con->enforce != 0.0f)) {
bKinematicConstraint *data = con->data;
-
+
/* only accept if a temporary one (for auto-ik) */
if (data->flag & CONSTRAINT_IK_TEMP) {
/* chainlen is new chainlen, but is limited by maximum chainlen */
- if ((chainlen == 0) || (chainlen > data->max_rootbone))
+ const int old_rootbone = data->rootbone;
+ if ((chainlen == 0) || (chainlen > data->max_rootbone)) {
data->rootbone = data->max_rootbone;
- else
+ }
+ else {
data->rootbone = chainlen;
+ }
+ changed |= (data->rootbone != old_rootbone);
}
}
}
+
+ return changed;
}
/* change the chain-length of auto-ik */
void transform_autoik_update(TransInfo *t, short mode)
{
+ const short old_len = t->settings->autoik_chainlen;
short *chainlen = &t->settings->autoik_chainlen;
bPoseChannel *pchan;
@@ -812,13 +821,29 @@ void transform_autoik_update(TransInfo *t, short mode)
if (*chainlen > 0) (*chainlen)--;
}
+ /* IK length did not change, skip any updates. */
+ if (old_len == *chainlen) {
+ return;
+ }
+
/* sanity checks (don't assume t->poseobj is set, or that it is an armature) */
if (ELEM(NULL, t->poseobj, t->poseobj->pose))
return;
/* apply to all pose-channels */
+ bool changed = false;
for (pchan = t->poseobj->pose->chanbase.first; pchan; pchan = pchan->next) {
- pchan_autoik_adjust(pchan, *chainlen);
+ changed |= pchan_autoik_adjust(pchan, *chainlen);
+ }
+
+#ifdef WITH_LEGACY_DEPSGRAPH
+ if (!DEG_depsgraph_use_legacy())
+#endif
+ {
+ if (changed) {
+ /* TODO(sergey): Consider doing partial update only. */
+ DAG_relations_tag_update(G.main);
+ }
}
}
@@ -2008,9 +2033,9 @@ static bool bmesh_test_dist_add(
}
/**
- * \parm mtx: Measure disatnce in this space.
- * \parm dists: Store the closest connected distance to selected vertices.
- * \parm index: Optionally store the original index we're measuring the distance to (can be NULL).
+ * \param mtx: Measure disatnce in this space.
+ * \param dists: Store the closest connected distance to selected vertices.
+ * \param index: Optionally store the original index we're measuring the distance to (can be NULL).
*/
static void editmesh_set_connectivity_distance(BMesh *bm, float mtx[3][3], float *dists, int *index)
{
@@ -2280,7 +2305,7 @@ static struct TransIslandData *editmesh_islands_info_calc(
}
if (group_tot_single != 0) {
- trans_islands = MEM_reallocN(trans_islands, group_tot + group_tot_single);
+ trans_islands = MEM_reallocN(trans_islands, sizeof(*trans_islands) * (group_tot + group_tot_single));
BM_ITER_MESH_INDEX (v, &viter, bm, BM_VERTS_OF_MESH, i) {
if (BM_elem_flag_test(v, BM_ELEM_SELECT) && (vert_map[i] == -1)) {
@@ -2402,7 +2427,8 @@ static void createTransEditVerts(TransInfo *t)
int island_info_tot;
int *island_vert_map = NULL;
- const bool is_island_center = (t->around == V3D_AROUND_LOCAL_ORIGINS) && (t->mode != TFM_TRANSLATION);
+ /* Even for translation this is needed because of island-orientation, see: T51651. */
+ const bool is_island_center = (t->around == V3D_AROUND_LOCAL_ORIGINS);
/* Original index of our connected vertex when connected distances are calculated.
* Optional, allocate if needed. */
int *dists_index = NULL;
@@ -2468,11 +2494,6 @@ static void createTransEditVerts(TransInfo *t)
editmesh_set_connectivity_distance(em->bm, mtx, dists, dists_index);
}
- /* Only in case of rotation and resize, we want the elements of the edited
- * object to behave as groups whose pivot are the individual origins
- *
- * TODO: use island_info to detect the closest point when the "Snap Target"
- * in Blender UI is "Closest" */
if (is_island_center) {
/* In this specific case, near-by vertices will need to know the island of the nearest connected vertex. */
const bool calc_single_islands = (
@@ -5353,7 +5374,8 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
}
/* update object's loc/rot to get current rigid body transform */
mat4_to_loc_rot_size(ob->loc, rot, scale, ob->obmat);
- BKE_object_mat3_to_rot(ob, rot, false);
+ sub_v3_v3(ob->loc, ob->dloc);
+ BKE_object_mat3_to_rot(ob, rot, false); /* drot is already corrected here */
}
}
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index f78a23be7b8..c23da19f830 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -971,7 +971,7 @@ static void recalcData_sequencer(TransInfo *t)
/* force recalculation of triangles during transformation */
static void recalcData_gpencil_strokes(TransInfo *t)
- {
+{
TransData *td = t->data;
for (int i = 0; i < t->total; i++, td++) {
bGPDstroke *gps = td->extra;
diff --git a/source/blender/editors/transform/transform_input.c b/source/blender/editors/transform/transform_input.c
index 22c39d6ed0c..5f2e5a99090 100644
--- a/source/blender/editors/transform/transform_input.c
+++ b/source/blender/editors/transform/transform_input.c
@@ -86,12 +86,11 @@ static void InputTrackBall(TransInfo *UNUSED(t), MouseInput *mi, const double mv
output[1] *= mi->factor;
}
-static void InputHorizontalRatio(TransInfo *t, MouseInput *UNUSED(mi), const double mval[2], float output[3])
+static void InputHorizontalRatio(TransInfo *t, MouseInput *mi, const double mval[2], float output[3])
{
const int winx = t->ar ? t->ar->winx : 1;
- const double pad = winx / 10;
- output[0] = (mval[0] - pad) / (winx - 2 * pad);
+ output[0] = ((mval[0] - mi->imval[0]) / winx) * 2.0f;
}
static void InputHorizontalAbsolute(TransInfo *t, MouseInput *mi, const double mval[2], float output[3])
@@ -104,12 +103,11 @@ static void InputHorizontalAbsolute(TransInfo *t, MouseInput *mi, const double m
output[0] = dot_v3v3(t->viewinv[0], vec) * 2.0f;
}
-static void InputVerticalRatio(TransInfo *t, MouseInput *UNUSED(mi), const double mval[2], float output[3])
+static void InputVerticalRatio(TransInfo *t, MouseInput *mi, const double mval[2], float output[3])
{
const int winy = t->ar ? t->ar->winy : 1;
- const double pad = winy / 10;
- output[0] = (mval[1] - pad) / (winy - 2 * pad);
+ output[0] = ((mval[1] - mi->imval[1]) / winy) * 2.0f;
}
static void InputVerticalAbsolute(TransInfo *t, MouseInput *mi, const double mval[2], float output[3])
@@ -314,7 +312,6 @@ void initMouseInputMode(TransInfo *t, MouseInput *mi, MouseInputMode mode)
t->helpline = HLP_TRACKBALL;
break;
case INPUT_HORIZONTAL_RATIO:
- mi->factor = (float)(mi->center[0] - mi->imval[0]);
mi->apply = InputHorizontalRatio;
t->helpline = HLP_HARROW;
break;
diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c
index ab2a0225abc..ec066ba91a4 100644
--- a/source/blender/editors/transform/transform_manipulator.c
+++ b/source/blender/editors/transform/transform_manipulator.c
@@ -1755,7 +1755,7 @@ static int manipulator_selectbuf(Scene *scene, ScrArea *sa, ARegion *ar, const i
hits = GPU_select_end();
- if (do_passes) {
+ if (do_passes && (hits > 0)) {
GPU_select_begin(buffer, 64, &rect, GPU_SELECT_NEAREST_SECOND_PASS, hits);
/* do the drawing */
diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c
index b33528b4149..aecd24d4e40 100644
--- a/source/blender/editors/transform/transform_snap_object.c
+++ b/source/blender/editors/transform/transform_snap_object.c
@@ -234,7 +234,7 @@ static void raycast_all_cb(void *userdata, int index, const BVHTreeRay *ray, BVH
/* -------------------------------------------------------------------- */
-/** \Common utilities
+/** Common utilities
* \{ */
/**
@@ -620,7 +620,7 @@ static float dist_aabb_to_plane(
/* -------------------------------------------------------------------- */
-/** \Walk DFS
+/** Walk DFS
* \{ */
typedef void (*Nearest2DGetEdgeVertsCallback)(const int index, const float *v_pair[2], void *data);
diff --git a/source/blender/editors/util/undo.c b/source/blender/editors/util/undo.c
index 4e021d4833e..419c15bf83f 100644
--- a/source/blender/editors/util/undo.c
+++ b/source/blender/editors/util/undo.c
@@ -334,6 +334,12 @@ static int ed_undo_redo_exec(bContext *C, wmOperator *UNUSED(op))
return ret ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
+static int ed_undo_redo_poll(bContext *C)
+{
+ wmOperator *last_op = WM_operator_last_redo(C);
+ return last_op && ED_operator_screenactive(C) &&
+ WM_operator_check_ui_enabled(C, last_op->type->name);
+}
/* ********************** */
@@ -385,7 +391,7 @@ void ED_OT_undo_redo(wmOperatorType *ot)
/* api callbacks */
ot->exec = ed_undo_redo_exec;
- ot->poll = ED_operator_screenactive;
+ ot->poll = ed_undo_redo_poll;
}
/* ui callbacks should call this rather than calling WM_operator_repeat() themselves */
diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c
index bdfff123aa4..8c76d03035a 100644
--- a/source/blender/editors/uvedit/uvedit_parametrizer.c
+++ b/source/blender/editors/uvedit/uvedit_parametrizer.c
@@ -2859,7 +2859,7 @@ static PBool p_chart_symmetry_pins(PChart *chart, PEdge *outer, PVert **pin1, PV
PEdge *cure = NULL, *firste1 = NULL, *firste2 = NULL, *nextbe;
float maxlen = 0.0f, curlen = 0.0f, totlen = 0.0f, firstlen = 0.0f;
float len1, len2;
-
+
/* find longest series of verts split in the chart itself, these are
* marked during construction */
be = outer;