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/anim_deps.c3
-rw-r--r--source/blender/editors/animation/anim_filter.c3
-rw-r--r--source/blender/editors/animation/anim_ops.c3
-rw-r--r--source/blender/editors/animation/fmodifier_ui.c20
-rw-r--r--source/blender/editors/armature/armature_naming.c2
-rw-r--r--source/blender/editors/armature/armature_select.c4
-rw-r--r--source/blender/editors/armature/meshlaplacian.c3
-rw-r--r--source/blender/editors/armature/pose_edit.c2
-rw-r--r--source/blender/editors/curve/editcurve.c570
-rw-r--r--source/blender/editors/curve/editcurve_query.c4
-rw-r--r--source/blender/editors/curve/editcurve_select.c41
-rw-r--r--source/blender/editors/curve/editfont.c15
-rw-r--r--source/blender/editors/curve/editfont_undo.c1
-rw-r--r--source/blender/editors/gpencil/gpencil_edit.c251
-rw-r--r--source/blender/editors/gpencil/gpencil_interpolate.c6
-rw-r--r--source/blender/editors/gpencil/gpencil_mesh.c140
-rw-r--r--source/blender/editors/gpencil/gpencil_trace.h4
-rw-r--r--source/blender/editors/gpencil/gpencil_trace_ops.c311
-rw-r--r--source/blender/editors/include/ED_buttons.h3
-rw-r--r--source/blender/editors/include/ED_curve.h2
-rw-r--r--source/blender/editors/include/ED_fileselect.h4
-rw-r--r--source/blender/editors/include/ED_object.h1
-rw-r--r--source/blender/editors/include/ED_screen.h1
-rw-r--r--source/blender/editors/include/ED_view3d.h2
-rw-r--r--source/blender/editors/interface/interface.c211
-rw-r--r--source/blender/editors/interface/interface_eyedropper.c2
-rw-r--r--source/blender/editors/interface/interface_handlers.c35
-rw-r--r--source/blender/editors/interface/interface_intern.h5
-rw-r--r--source/blender/editors/interface/interface_layout.c10
-rw-r--r--source/blender/editors/interface/interface_panel.c34
-rw-r--r--source/blender/editors/interface/interface_templates.c4
-rw-r--r--source/blender/editors/interface/interface_utils.c4
-rw-r--r--source/blender/editors/interface/interface_widgets.c23
-rw-r--r--source/blender/editors/interface/view2d_ops.c18
-rw-r--r--source/blender/editors/io/io_alembic.c4
-rw-r--r--source/blender/editors/io/io_cache.c2
-rw-r--r--source/blender/editors/io/io_collada.c4
-rw-r--r--source/blender/editors/io/io_usd.c2
-rw-r--r--source/blender/editors/mesh/editmesh_bevel.c128
-rw-r--r--source/blender/editors/mesh/editmesh_intersect.c17
-rw-r--r--source/blender/editors/mesh/editmesh_select_similar.c2
-rw-r--r--source/blender/editors/mesh/editmesh_undo.c1
-rw-r--r--source/blender/editors/object/object_bake.c9
-rw-r--r--source/blender/editors/object/object_hook.c8
-rw-r--r--source/blender/editors/object/object_modifier.c49
-rw-r--r--source/blender/editors/object/object_relations.c16
-rw-r--r--source/blender/editors/object/object_vgroup.c66
-rw-r--r--source/blender/editors/object/object_volume.c2
-rw-r--r--source/blender/editors/physics/particle_object.c4
-rw-r--r--source/blender/editors/physics/rigidbody_world.c2
-rw-r--r--source/blender/editors/render/render_internal.c17
-rw-r--r--source/blender/editors/render/render_opengl.c3
-rw-r--r--source/blender/editors/screen/area.c5
-rw-r--r--source/blender/editors/screen/screen_context.c3
-rw-r--r--source/blender/editors/screen/screen_ops.c4
-rw-r--r--source/blender/editors/screen/screendump.c2
-rw-r--r--source/blender/editors/screen/workspace_edit.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_cursor.c5
-rw-r--r--source/blender/editors/sculpt_paint/paint_mask.c252
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c380
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_cloth.c85
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_face_set.c215
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_undo.c8
-rw-r--r--source/blender/editors/sound/sound_ops.c9
-rw-r--r--source/blender/editors/space_buttons/buttons_context.c44
-rw-r--r--source/blender/editors/space_buttons/buttons_ops.c4
-rw-r--r--source/blender/editors/space_clip/clip_ops.c2
-rw-r--r--source/blender/editors/space_clip/tracking_ops.c6
-rw-r--r--source/blender/editors/space_clip/tracking_select.c12
-rw-r--r--source/blender/editors/space_file/file_ops.c24
-rw-r--r--source/blender/editors/space_file/filelist.c16
-rw-r--r--source/blender/editors/space_file/filelist.h1
-rw-r--r--source/blender/editors/space_file/filesel.c81
-rw-r--r--source/blender/editors/space_file/fsmenu.c44
-rw-r--r--source/blender/editors/space_graph/graph_edit.c73
-rw-r--r--source/blender/editors/space_graph/graph_intern.h1
-rw-r--r--source/blender/editors/space_graph/graph_ops.c1
-rw-r--r--source/blender/editors/space_image/image_ops.c75
-rw-r--r--source/blender/editors/space_info/info_ops.c2
-rw-r--r--source/blender/editors/space_info/info_stats.c6
-rw-r--r--source/blender/editors/space_node/drawnode.c1
-rw-r--r--source/blender/editors/space_node/node_add.c2
-rw-r--r--source/blender/editors/space_node/node_intern.h2
-rw-r--r--source/blender/editors/space_outliner/outliner_select.c206
-rw-r--r--source/blender/editors/space_outliner/outliner_sync.c3
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.c3
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c11
-rw-r--r--source/blender/editors/space_sequencer/sequencer_add.c9
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c3
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c11
-rw-r--r--source/blender/editors/space_sequencer/sequencer_modifier.c3
-rw-r--r--source/blender/editors/space_sequencer/sequencer_ops.c2
-rw-r--r--source/blender/editors/space_sequencer/sequencer_select.c3
-rw-r--r--source/blender/editors/space_sequencer/sequencer_view.c3
-rw-r--r--source/blender/editors/space_sequencer/space_sequencer.c3
-rw-r--r--source/blender/editors/space_text/text_ops.c78
-rw-r--r--source/blender/editors/space_view3d/view3d_buttons.c11
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c12
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_snap.c8
-rw-r--r--source/blender/editors/transform/transform.c24
-rw-r--r--source/blender/editors/transform/transform_convert_sequencer.c3
-rw-r--r--source/blender/editors/transform/transform_gizmo_2d.c2
-rw-r--r--source/blender/editors/transform/transform_mode.c12
-rw-r--r--source/blender/editors/transform/transform_mode_align.c4
-rw-r--r--source/blender/editors/transform/transform_mode_baketime.c4
-rw-r--r--source/blender/editors/transform/transform_mode_bbone_resize.c4
-rw-r--r--source/blender/editors/transform/transform_mode_bend.c4
-rw-r--r--source/blender/editors/transform/transform_mode_boneenvelope.c4
-rw-r--r--source/blender/editors/transform/transform_mode_boneroll.c4
-rw-r--r--source/blender/editors/transform/transform_mode_curveshrinkfatten.c4
-rw-r--r--source/blender/editors/transform/transform_mode_edge_bevelweight.c4
-rw-r--r--source/blender/editors/transform/transform_mode_edge_crease.c4
-rw-r--r--source/blender/editors/transform/transform_mode_edge_rotate_normal.c4
-rw-r--r--source/blender/editors/transform/transform_mode_edge_seq_slide.c4
-rw-r--r--source/blender/editors/transform/transform_mode_edge_slide.c4
-rw-r--r--source/blender/editors/transform/transform_mode_gpopacity.c4
-rw-r--r--source/blender/editors/transform/transform_mode_gpshrinkfatten.c4
-rw-r--r--source/blender/editors/transform/transform_mode_maskshrinkfatten.c4
-rw-r--r--source/blender/editors/transform/transform_mode_mirror.c4
-rw-r--r--source/blender/editors/transform/transform_mode_push_pull.c4
-rw-r--r--source/blender/editors/transform/transform_mode_resize.c4
-rw-r--r--source/blender/editors/transform/transform_mode_rotate.c4
-rw-r--r--source/blender/editors/transform/transform_mode_shear.c4
-rw-r--r--source/blender/editors/transform/transform_mode_shrink_fatten.c4
-rw-r--r--source/blender/editors/transform/transform_mode_skin_resize.c4
-rw-r--r--source/blender/editors/transform/transform_mode_tilt.c4
-rw-r--r--source/blender/editors/transform/transform_mode_timescale.c4
-rw-r--r--source/blender/editors/transform/transform_mode_timeslide.c4
-rw-r--r--source/blender/editors/transform/transform_mode_timetranslate.c4
-rw-r--r--source/blender/editors/transform/transform_mode_tosphere.c4
-rw-r--r--source/blender/editors/transform/transform_mode_trackball.c4
-rw-r--r--source/blender/editors/transform/transform_mode_translate.c4
-rw-r--r--source/blender/editors/transform/transform_mode_vert_slide.c4
-rw-r--r--source/blender/editors/transform/transform_ops.c14
-rw-r--r--source/blender/editors/transform/transform_snap.c3
-rw-r--r--source/blender/editors/util/ed_util_imbuf.c3
137 files changed, 2618 insertions, 1379 deletions
diff --git a/source/blender/editors/animation/anim_deps.c b/source/blender/editors/animation/anim_deps.c
index b2225ec138f..e552a321bca 100644
--- a/source/blender/editors/animation/anim_deps.c
+++ b/source/blender/editors/animation/anim_deps.c
@@ -44,12 +44,13 @@
#include "BKE_gpencil.h"
#include "BKE_main.h"
#include "BKE_node.h"
-#include "BKE_sequencer.h"
#include "DEG_depsgraph.h"
#include "RNA_access.h"
+#include "SEQ_sequencer.h"
+
#include "ED_anim_api.h"
/* **************************** depsgraph tagging ******************************** */
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index 5dff62459ac..2e65fff69f1 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -96,11 +96,12 @@
#include "BKE_material.h"
#include "BKE_modifier.h"
#include "BKE_node.h"
-#include "BKE_sequencer.h"
#include "ED_anim_api.h"
#include "ED_markers.h"
+#include "SEQ_sequencer.h"
+
#include "UI_resources.h" /* for TH_KEYFRAME_SCALE lookup */
/* ************************************************************ */
diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c
index b52ff131b43..9e622aea6ab 100644
--- a/source/blender/editors/animation/anim_ops.c
+++ b/source/blender/editors/animation/anim_ops.c
@@ -37,7 +37,6 @@
#include "BKE_main.h"
#include "BKE_report.h"
#include "BKE_scene.h"
-#include "BKE_sequencer.h"
#include "UI_view2d.h"
@@ -56,6 +55,8 @@
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
+#include "SEQ_sequencer.h"
+
#include "anim_intern.h"
/* ********************** frame change operator ***************************/
diff --git a/source/blender/editors/animation/fmodifier_ui.c b/source/blender/editors/animation/fmodifier_ui.c
index fc622c7a52e..deebf1d1efc 100644
--- a/source/blender/editors/animation/fmodifier_ui.c
+++ b/source/blender/editors/animation/fmodifier_ui.c
@@ -21,13 +21,11 @@
* \ingroup edanimation
*/
-/* User-Interface Stuff for F-Modifiers:
- * This file defines the (C-Coded) templates + editing callbacks needed
- * by the interface stuff or F-Modifiers, as used by F-Curves in the Graph Editor,
- * and NLA-Strips in the NLA Editor.
+/**
+ * User Interface for F-Modifiers
*
- * Copy/Paste Buffer for F-Modifiers:
- * For now, this is also defined in this file so that it can be shared between the
+ * This file defines templates and some editing callbacks needed by the interface for
+ * F-Modifiers, as used by F-Curves in the Graph Editor and NLA-Strips in the NLA Editor.
*/
#include <string.h>
@@ -1047,8 +1045,12 @@ void ANIM_uiTemplate_fmodifier_draw(uiLayout *layout,
}
}
-/* ********************************************** */
-/* COPY/PASTE BUFFER STUFF */
+/* -------------------------------------------------------------------- */
+/** \name Copy / Paste Buffer Code
+ *
+ * For now, this is also defined in this file so that it can be shared between the graph editor
+ * and the NLA editor.
+ * \{ */
/* Copy/Paste Buffer itself (list of FModifier 's) */
static ListBase fmodifier_copypaste_buf = {NULL, NULL};
@@ -1139,4 +1141,4 @@ bool ANIM_fmodifiers_paste_from_buf(ListBase *modifiers, bool replace, FCurve *c
return ok;
}
-/* ********************************************** */
+/** \} */
diff --git a/source/blender/editors/armature/armature_naming.c b/source/blender/editors/armature/armature_naming.c
index 60a1434ed42..8bcaf72f678 100644
--- a/source/blender/editors/armature/armature_naming.c
+++ b/source/blender/editors/armature/armature_naming.c
@@ -606,7 +606,7 @@ void ARMATURE_OT_autoside_names(wmOperatorType *ot)
};
/* identifiers */
- ot->name = "AutoName by Axis";
+ ot->name = "Auto-Name by Axis";
ot->idname = "ARMATURE_OT_autoside_names";
ot->description =
"Automatically renames the selected bones according to which side of the target axis they "
diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c
index 27718b61d70..66c12a0d0d7 100644
--- a/source/blender/editors/armature/armature_select.c
+++ b/source/blender/editors/armature/armature_select.c
@@ -1550,10 +1550,10 @@ enum {
static const EnumPropertyItem prop_similar_types[] = {
{SIMEDBONE_CHILDREN, "CHILDREN", 0, "Children", ""},
- {SIMEDBONE_CHILDREN_IMMEDIATE, "CHILDREN_IMMEDIATE", 0, "Immediate children", ""},
+ {SIMEDBONE_CHILDREN_IMMEDIATE, "CHILDREN_IMMEDIATE", 0, "Immediate Children", ""},
{SIMEDBONE_SIBLINGS, "SIBLINGS", 0, "Siblings", ""},
{SIMEDBONE_LENGTH, "LENGTH", 0, "Length", ""},
- {SIMEDBONE_DIRECTION, "DIRECTION", 0, "Direction (Y axis)", ""},
+ {SIMEDBONE_DIRECTION, "DIRECTION", 0, "Direction (Y Axis)", ""},
{SIMEDBONE_PREFIX, "PREFIX", 0, "Prefix", ""},
{SIMEDBONE_SUFFIX, "SUFFIX", 0, "Suffix", ""},
{SIMEDBONE_LAYER, "LAYER", 0, "Layer", ""},
diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c
index e51e5ec5cef..3c0b6dacbf6 100644
--- a/source/blender/editors/armature/meshlaplacian.c
+++ b/source/blender/editors/armature/meshlaplacian.c
@@ -1547,7 +1547,8 @@ static void meshdeform_matrix_solve(MeshDeformModifierData *mmd, MeshDeformBind
}
}
else {
- BKE_modifier_set_error(&mmd->modifier, "Failed to find bind solution (increase precision?)");
+ BKE_modifier_set_error(
+ mmd->object, &mmd->modifier, "Failed to find bind solution (increase precision?)");
error("Mesh Deform: failed to find bind solution.");
break;
}
diff --git a/source/blender/editors/armature/pose_edit.c b/source/blender/editors/armature/pose_edit.c
index 8a1c2a4afa8..91893af003f 100644
--- a/source/blender/editors/armature/pose_edit.c
+++ b/source/blender/editors/armature/pose_edit.c
@@ -638,7 +638,7 @@ void POSE_OT_autoside_names(wmOperatorType *ot)
};
/* identifiers */
- ot->name = "AutoName by Axis";
+ ot->name = "Auto-Name by Axis";
ot->idname = "POSE_OT_autoside_names";
ot->description =
"Automatically renames the selected bones according to which side of the target axis they "
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 85d86849140..d39c7eb0d95 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -307,12 +307,8 @@ static void keyIndex_delNurb(EditNurb *editnurb, Nurb *nu)
static void keyIndex_delNurbList(EditNurb *editnurb, ListBase *nubase)
{
- Nurb *nu = nubase->first;
-
- while (nu) {
+ LISTBASE_FOREACH (Nurb *, nu, nubase) {
keyIndex_delNurb(editnurb, nu);
-
- nu = nu->next;
}
}
@@ -476,19 +472,15 @@ static void keyIndex_switchDirection(EditNurb *editnurb, Nurb *nu)
static void switch_keys_direction(Curve *cu, Nurb *actnu)
{
- KeyBlock *currkey;
EditNurb *editnurb = cu->editnurb;
ListBase *nubase = &editnurb->nurbs;
- Nurb *nu;
float *fp;
int a;
- currkey = cu->key->block.first;
- while (currkey) {
+ LISTBASE_FOREACH (KeyBlock *, currkey, &cu->key->block) {
fp = currkey->data;
- nu = nubase->first;
- while (nu) {
+ LISTBASE_FOREACH (Nurb *, nu, nubase) {
if (nu->bezt) {
BezTriple *bezt = nu->bezt;
a = nu->pntsu;
@@ -522,11 +514,7 @@ static void switch_keys_direction(Curve *cu, Nurb *actnu)
fp += a * KEYELEM_FLOAT_LEN_BPOINT;
}
}
-
- nu = nu->next;
}
-
- currkey = currkey->next;
}
}
@@ -583,13 +571,11 @@ static void bezt_to_key(BezTriple *bezt, float *key)
static void calc_keyHandles(ListBase *nurb, float *key)
{
- Nurb *nu;
int a;
float *fp = key;
BezTriple *bezt;
- nu = nurb->first;
- while (nu) {
+ LISTBASE_FOREACH (Nurb *, nu, nurb) {
if (nu->bezt) {
BezTriple *prevp, *nextp;
BezTriple cur, prev, next;
@@ -649,8 +635,6 @@ static void calc_keyHandles(ListBase *nurb, float *key)
a = nu->pntsu * nu->pntsv;
fp += a * KEYELEM_FLOAT_LEN_BPOINT;
}
-
- nu = nu->next;
}
}
@@ -658,255 +642,247 @@ static void calc_shapeKeys(Object *obedit, ListBase *newnurbs)
{
Curve *cu = (Curve *)obedit->data;
- /* are there keys? */
- if (cu->key) {
- int a, i;
- EditNurb *editnurb = cu->editnurb;
- KeyBlock *currkey;
- KeyBlock *actkey = BLI_findlink(&cu->key->block, editnurb->shapenr - 1);
- BezTriple *bezt, *oldbezt;
- BPoint *bp, *oldbp;
- Nurb *nu, *newnu;
- int totvert = BKE_keyblock_curve_element_count(&editnurb->nurbs);
-
- float(*ofs)[3] = NULL;
- float *oldkey, *newkey, *ofp;
-
- /* editing the base key should update others */
- if (cu->key->type == KEY_RELATIVE) {
- if (BKE_keyblock_is_basis(cu->key, editnurb->shapenr - 1)) { /* active key is a base */
- int totvec = 0;
-
- /* Calculate needed memory to store offset */
- nu = editnurb->nurbs.first;
- while (nu) {
- if (nu->bezt) {
- /* Three vects to store handles and one for tilt. */
- totvec += nu->pntsu * 4;
- }
- else {
- totvec += 2 * nu->pntsu * nu->pntsv;
- }
+ if (cu->key == NULL) {
+ return;
+ }
- nu = nu->next;
+ int a, i;
+ EditNurb *editnurb = cu->editnurb;
+ KeyBlock *actkey = BLI_findlink(&cu->key->block, editnurb->shapenr - 1);
+ BezTriple *bezt, *oldbezt;
+ BPoint *bp, *oldbp;
+ Nurb *newnu;
+ int totvert = BKE_keyblock_curve_element_count(&editnurb->nurbs);
+
+ float(*ofs)[3] = NULL;
+ float *oldkey, *newkey, *ofp;
+
+ /* editing the base key should update others */
+ if (cu->key->type == KEY_RELATIVE) {
+ if (BKE_keyblock_is_basis(cu->key, editnurb->shapenr - 1)) { /* active key is a base */
+ int totvec = 0;
+
+ /* Calculate needed memory to store offset */
+ LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) {
+
+ if (nu->bezt) {
+ /* Three vects to store handles and one for tilt. */
+ totvec += nu->pntsu * 4;
}
+ else {
+ totvec += 2 * nu->pntsu * nu->pntsv;
+ }
+ }
- ofs = MEM_callocN(sizeof(float[3]) * totvec, "currkey->data");
- nu = editnurb->nurbs.first;
- i = 0;
- while (nu) {
- if (nu->bezt) {
- bezt = nu->bezt;
- a = nu->pntsu;
- while (a--) {
- oldbezt = getKeyIndexOrig_bezt(editnurb, bezt);
+ ofs = MEM_callocN(sizeof(float[3]) * totvec, "currkey->data");
+ i = 0;
+ LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) {
+ if (nu->bezt) {
+ bezt = nu->bezt;
+ a = nu->pntsu;
+ while (a--) {
+ oldbezt = getKeyIndexOrig_bezt(editnurb, bezt);
- if (oldbezt) {
- int j;
- for (j = 0; j < 3; j++) {
- sub_v3_v3v3(ofs[i], bezt->vec[j], oldbezt->vec[j]);
- i++;
- }
- ofs[i][0] = bezt->tilt - oldbezt->tilt;
- ofs[i][1] = bezt->radius - oldbezt->radius;
+ if (oldbezt) {
+ int j;
+ for (j = 0; j < 3; j++) {
+ sub_v3_v3v3(ofs[i], bezt->vec[j], oldbezt->vec[j]);
i++;
}
- else {
- i += 4;
- }
- bezt++;
+ ofs[i][0] = bezt->tilt - oldbezt->tilt;
+ ofs[i][1] = bezt->radius - oldbezt->radius;
+ i++;
}
+ else {
+ i += 4;
+ }
+ bezt++;
}
- else {
- bp = nu->bp;
- a = nu->pntsu * nu->pntsv;
- while (a--) {
- oldbp = getKeyIndexOrig_bp(editnurb, bp);
- if (oldbp) {
- sub_v3_v3v3(ofs[i], bp->vec, oldbp->vec);
- ofs[i + 1][0] = bp->tilt - oldbp->tilt;
- ofs[i + 1][1] = bp->radius - oldbp->radius;
- }
- i += 2;
- bp++;
+ }
+ else {
+ bp = nu->bp;
+ a = nu->pntsu * nu->pntsv;
+ while (a--) {
+ oldbp = getKeyIndexOrig_bp(editnurb, bp);
+ if (oldbp) {
+ sub_v3_v3v3(ofs[i], bp->vec, oldbp->vec);
+ ofs[i + 1][0] = bp->tilt - oldbp->tilt;
+ ofs[i + 1][1] = bp->radius - oldbp->radius;
}
+ i += 2;
+ bp++;
}
-
- nu = nu->next;
}
}
}
+ }
- currkey = cu->key->block.first;
- while (currkey) {
- const bool apply_offset = (ofs && (currkey != actkey) &&
- (editnurb->shapenr - 1 == currkey->relative));
-
- float *fp = newkey = MEM_callocN(cu->key->elemsize * totvert, "currkey->data");
- ofp = oldkey = currkey->data;
+ LISTBASE_FOREACH (KeyBlock *, currkey, &cu->key->block) {
+ const bool apply_offset = (ofs && (currkey != actkey) &&
+ (editnurb->shapenr - 1 == currkey->relative));
- nu = editnurb->nurbs.first;
- /* We need to restore to original curve into newnurb, *not* editcurve's nurbs.
- * Otherwise, in case we update obdata *without* leaving editmode (e.g. viewport render),
- * we would invalidate editcurve. */
- newnu = newnurbs->first;
- i = 0;
- while (nu) {
- if (currkey == actkey) {
- const bool restore = actkey != cu->key->refkey;
+ float *fp = newkey = MEM_callocN(cu->key->elemsize * totvert, "currkey->data");
+ ofp = oldkey = currkey->data;
- if (nu->bezt) {
- bezt = nu->bezt;
- a = nu->pntsu;
- BezTriple *newbezt = newnu->bezt;
- while (a--) {
- int j;
- oldbezt = getKeyIndexOrig_bezt(editnurb, bezt);
+ Nurb *nu = editnurb->nurbs.first;
+ /* We need to restore to original curve into newnurb, *not* editcurve's nurbs.
+ * Otherwise, in case we update obdata *without* leaving editmode (e.g. viewport render),
+ * we would invalidate editcurve. */
+ newnu = newnurbs->first;
+ i = 0;
+ while (nu) {
+ if (currkey == actkey) {
+ const bool restore = actkey != cu->key->refkey;
- for (j = 0; j < 3; j++, i++) {
- copy_v3_v3(&fp[j * 3], bezt->vec[j]);
+ if (nu->bezt) {
+ bezt = nu->bezt;
+ a = nu->pntsu;
+ BezTriple *newbezt = newnu->bezt;
+ while (a--) {
+ int j;
+ oldbezt = getKeyIndexOrig_bezt(editnurb, bezt);
- if (restore && oldbezt) {
- copy_v3_v3(newbezt->vec[j], oldbezt->vec[j]);
- }
- }
- fp[9] = bezt->tilt;
- fp[10] = bezt->radius;
+ for (j = 0; j < 3; j++, i++) {
+ copy_v3_v3(&fp[j * 3], bezt->vec[j]);
if (restore && oldbezt) {
- newbezt->tilt = oldbezt->tilt;
- newbezt->radius = oldbezt->radius;
+ copy_v3_v3(newbezt->vec[j], oldbezt->vec[j]);
}
+ }
+ fp[9] = bezt->tilt;
+ fp[10] = bezt->radius;
- fp += KEYELEM_FLOAT_LEN_BEZTRIPLE;
- i++;
- bezt++;
- newbezt++;
+ if (restore && oldbezt) {
+ newbezt->tilt = oldbezt->tilt;
+ newbezt->radius = oldbezt->radius;
}
- }
- else {
- bp = nu->bp;
- a = nu->pntsu * nu->pntsv;
- BPoint *newbp = newnu->bp;
- while (a--) {
- oldbp = getKeyIndexOrig_bp(editnurb, bp);
- copy_v3_v3(fp, bp->vec);
+ fp += KEYELEM_FLOAT_LEN_BEZTRIPLE;
+ i++;
+ bezt++;
+ newbezt++;
+ }
+ }
+ else {
+ bp = nu->bp;
+ a = nu->pntsu * nu->pntsv;
+ BPoint *newbp = newnu->bp;
+ while (a--) {
+ oldbp = getKeyIndexOrig_bp(editnurb, bp);
- fp[3] = bp->tilt;
- fp[4] = bp->radius;
+ copy_v3_v3(fp, bp->vec);
- if (restore && oldbp) {
- copy_v3_v3(newbp->vec, oldbp->vec);
- newbp->tilt = oldbp->tilt;
- newbp->radius = oldbp->radius;
- }
+ fp[3] = bp->tilt;
+ fp[4] = bp->radius;
- fp += KEYELEM_FLOAT_LEN_BPOINT;
- bp++;
- newbp++;
- i += 2;
+ if (restore && oldbp) {
+ copy_v3_v3(newbp->vec, oldbp->vec);
+ newbp->tilt = oldbp->tilt;
+ newbp->radius = oldbp->radius;
}
+
+ fp += KEYELEM_FLOAT_LEN_BPOINT;
+ bp++;
+ newbp++;
+ i += 2;
}
}
- else {
- int index;
- const float *curofp;
-
- if (oldkey) {
- if (nu->bezt) {
- bezt = nu->bezt;
- a = nu->pntsu;
+ }
+ else {
+ int index;
+ const float *curofp;
- while (a--) {
- index = getKeyIndexOrig_keyIndex(editnurb, bezt);
- if (index >= 0) {
- int j;
- curofp = ofp + index;
+ if (oldkey) {
+ if (nu->bezt) {
+ bezt = nu->bezt;
+ a = nu->pntsu;
- for (j = 0; j < 3; j++, i++) {
- copy_v3_v3(&fp[j * 3], &curofp[j * 3]);
+ while (a--) {
+ index = getKeyIndexOrig_keyIndex(editnurb, bezt);
+ if (index >= 0) {
+ int j;
+ curofp = ofp + index;
- if (apply_offset) {
- add_v3_v3(&fp[j * 3], ofs[i]);
- }
- }
- fp[9] = curofp[9];
- fp[10] = curofp[10];
+ for (j = 0; j < 3; j++, i++) {
+ copy_v3_v3(&fp[j * 3], &curofp[j * 3]);
if (apply_offset) {
- /* Apply tilt offsets. */
- add_v3_v3(fp + 9, ofs[i]);
- i++;
+ add_v3_v3(&fp[j * 3], ofs[i]);
}
+ }
+ fp[9] = curofp[9];
+ fp[10] = curofp[10];
- fp += KEYELEM_FLOAT_LEN_BEZTRIPLE;
+ if (apply_offset) {
+ /* Apply tilt offsets. */
+ add_v3_v3(fp + 9, ofs[i]);
+ i++;
}
- else {
- int j;
- for (j = 0; j < 3; j++, i++) {
- copy_v3_v3(&fp[j * 3], bezt->vec[j]);
- }
- fp[9] = bezt->tilt;
- fp[10] = bezt->radius;
- fp += KEYELEM_FLOAT_LEN_BEZTRIPLE;
+ fp += KEYELEM_FLOAT_LEN_BEZTRIPLE;
+ }
+ else {
+ int j;
+ for (j = 0; j < 3; j++, i++) {
+ copy_v3_v3(&fp[j * 3], bezt->vec[j]);
}
- bezt++;
+ fp[9] = bezt->tilt;
+ fp[10] = bezt->radius;
+
+ fp += KEYELEM_FLOAT_LEN_BEZTRIPLE;
}
+ bezt++;
}
- else {
- bp = nu->bp;
- a = nu->pntsu * nu->pntsv;
- while (a--) {
- index = getKeyIndexOrig_keyIndex(editnurb, bp);
+ }
+ else {
+ bp = nu->bp;
+ a = nu->pntsu * nu->pntsv;
+ while (a--) {
+ index = getKeyIndexOrig_keyIndex(editnurb, bp);
- if (index >= 0) {
- curofp = ofp + index;
- copy_v3_v3(fp, curofp);
- fp[3] = curofp[3];
- fp[4] = curofp[4];
+ if (index >= 0) {
+ curofp = ofp + index;
+ copy_v3_v3(fp, curofp);
+ fp[3] = curofp[3];
+ fp[4] = curofp[4];
- if (apply_offset) {
- add_v3_v3(fp, ofs[i]);
- add_v3_v3(&fp[3], ofs[i + 1]);
- }
- }
- else {
- copy_v3_v3(fp, bp->vec);
- fp[3] = bp->tilt;
- fp[4] = bp->radius;
+ if (apply_offset) {
+ add_v3_v3(fp, ofs[i]);
+ add_v3_v3(&fp[3], ofs[i + 1]);
}
-
- fp += KEYELEM_FLOAT_LEN_BPOINT;
- bp++;
- i += 2;
}
+ else {
+ copy_v3_v3(fp, bp->vec);
+ fp[3] = bp->tilt;
+ fp[4] = bp->radius;
+ }
+
+ fp += KEYELEM_FLOAT_LEN_BPOINT;
+ bp++;
+ i += 2;
}
}
}
-
- nu = nu->next;
- newnu = newnu->next;
}
- if (apply_offset) {
- /* handles could become malicious after offsets applying */
- calc_keyHandles(&editnurb->nurbs, newkey);
- }
-
- currkey->totelem = totvert;
- if (currkey->data) {
- MEM_freeN(currkey->data);
- }
- currkey->data = newkey;
+ nu = nu->next;
+ newnu = newnu->next;
+ }
- currkey = currkey->next;
+ if (apply_offset) {
+ /* handles could become malicious after offsets applying */
+ calc_keyHandles(&editnurb->nurbs, newkey);
}
- if (ofs) {
- MEM_freeN(ofs);
+ currkey->totelem = totvert;
+ if (currkey->data) {
+ MEM_freeN(currkey->data);
}
+ currkey->data = newkey;
+ }
+
+ if (ofs) {
+ MEM_freeN(ofs);
}
}
@@ -929,11 +905,10 @@ static void fcurve_path_rename(AnimData *adt,
ListBase *orig_curves,
ListBase *curves)
{
- FCurve *fcu, *nfcu, *nextfcu;
+ FCurve *nfcu;
int len = strlen(orig_rna_path);
- for (fcu = orig_curves->first; fcu; fcu = nextfcu) {
- nextfcu = fcu->next;
+ LISTBASE_FOREACH_MUTABLE (FCurve *, fcu, orig_curves) {
if (STREQLEN(fcu->rna_path, orig_rna_path, len)) {
char *spath, *suffix = fcu->rna_path + len;
nfcu = BKE_fcurve_copy(fcu);
@@ -977,16 +952,15 @@ static void fcurve_remove(AnimData *adt, ListBase *orig_curves, FCurve *fcu)
static void curve_rename_fcurves(Curve *cu, ListBase *orig_curves)
{
- int nu_index = 0, a, pt_index;
+ int a, pt_index;
EditNurb *editnurb = cu->editnurb;
- Nurb *nu;
CVKeyIndex *keyIndex;
char rna_path[64], orig_rna_path[64];
AnimData *adt = BKE_animdata_from_id(&cu->id);
ListBase curves = {NULL, NULL};
- FCurve *fcu, *next;
- for (nu = editnurb->nurbs.first, nu_index = 0; nu != NULL; nu = nu->next, nu_index++) {
+ int nu_index = 0;
+ LISTBASE_FOREACH_INDEX (Nurb *, nu, &editnurb->nurbs, nu_index) {
if (nu->bezt) {
BezTriple *bezt = nu->bezt;
a = nu->pntsu;
@@ -1054,9 +1028,7 @@ static void curve_rename_fcurves(Curve *cu, ListBase *orig_curves)
/* remove paths for removed control points
* need this to make further step with copying non-cv related curves copying
* not touching cv's f-curves */
- for (fcu = orig_curves->first; fcu; fcu = next) {
- next = fcu->next;
-
+ LISTBASE_FOREACH_MUTABLE (FCurve *, fcu, orig_curves) {
if (STREQLEN(fcu->rna_path, "splines", 7)) {
const char *ch = strchr(fcu->rna_path, '.');
@@ -1066,7 +1038,8 @@ static void curve_rename_fcurves(Curve *cu, ListBase *orig_curves)
}
}
- for (nu = editnurb->nurbs.first, nu_index = 0; nu != NULL; nu = nu->next, nu_index++) {
+ nu_index = 0;
+ LISTBASE_FOREACH_INDEX (Nurb *, nu, &editnurb->nurbs, nu_index) {
keyIndex = NULL;
if (nu->pntsu) {
if (nu->bezt) {
@@ -1086,9 +1059,7 @@ static void curve_rename_fcurves(Curve *cu, ListBase *orig_curves)
/* the remainders in orig_curves can be copied back (like follow path) */
/* (if it's not path to spline) */
- for (fcu = orig_curves->first; fcu; fcu = next) {
- next = fcu->next;
-
+ LISTBASE_FOREACH_MUTABLE (FCurve *, fcu, orig_curves) {
if (STREQLEN(fcu->rna_path, "splines", 7)) {
fcurve_remove(adt, orig_curves, fcu);
}
@@ -1141,13 +1112,11 @@ static int *init_index_map(Object *obedit, int *r_old_totvert)
{
Curve *curve = (Curve *)obedit->data;
EditNurb *editnurb = curve->editnurb;
- Nurb *nu;
CVKeyIndex *keyIndex;
int *old_to_new_map;
- int old_totvert;
- int vertex_index;
- for (nu = curve->nurb.first, old_totvert = 0; nu != NULL; nu = nu->next) {
+ int old_totvert = 0;
+ LISTBASE_FOREACH (Nurb *, nu, &curve->nurb) {
if (nu->bezt) {
old_totvert += nu->pntsu * 3;
}
@@ -1161,7 +1130,8 @@ static int *init_index_map(Object *obedit, int *r_old_totvert)
old_to_new_map[i] = -1;
}
- for (nu = editnurb->nurbs.first, vertex_index = 0; nu != NULL; nu = nu->next) {
+ int vertex_index = 0;
+ LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) {
if (nu->bezt) {
BezTriple *bezt = nu->bezt;
int a = nu->pntsu;
@@ -1205,7 +1175,6 @@ static int *init_index_map(Object *obedit, int *r_old_totvert)
static void remap_hooks_and_vertex_parents(Main *bmain, Object *obedit)
{
- Object *object;
Curve *curve = (Curve *)obedit->data;
EditNurb *editnurb = curve->editnurb;
int *old_to_new_map = NULL;
@@ -1219,8 +1188,7 @@ static void remap_hooks_and_vertex_parents(Main *bmain, Object *obedit)
return;
}
- for (object = bmain->objects.first; object; object = object->id.next) {
- ModifierData *md;
+ LISTBASE_FOREACH (Object *, object, &bmain->objects) {
int index;
if ((object->parent) && (object->parent->data == curve) &&
ELEM(object->partype, PARVERT1, PARVERT3)) {
@@ -1248,7 +1216,7 @@ static void remap_hooks_and_vertex_parents(Main *bmain, Object *obedit)
}
}
if (object->data == curve) {
- for (md = object->modifiers.first; md; md = md->next) {
+ LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
if (md->type == eModifierType_Hook) {
HookModifierData *hmd = (HookModifierData *)md;
int i, j;
@@ -1290,13 +1258,12 @@ void ED_curve_editnurb_load(Main *bmain, Object *obedit)
if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
Curve *cu = obedit->data;
- Nurb *nu, *newnu;
ListBase newnurb = {NULL, NULL}, oldnurb = cu->nurb;
remap_hooks_and_vertex_parents(bmain, obedit);
- for (nu = editnurb->first; nu; nu = nu->next) {
- newnu = BKE_nurb_duplicate(nu);
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
+ Nurb *newnu = BKE_nurb_duplicate(nu);
BLI_addtail(&newnurb, newnu);
if (nu->type == CU_NURBS) {
@@ -1323,7 +1290,6 @@ void ED_curve_editnurb_make(Object *obedit)
{
Curve *cu = (Curve *)obedit->data;
EditNurb *editnurb = cu->editnurb;
- Nurb *nu, *newnu;
KeyBlock *actkey;
if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
@@ -1346,12 +1312,10 @@ void ED_curve_editnurb_make(Object *obedit)
cu->editnurb = editnurb;
}
- nu = cu->nurb.first;
- while (nu) {
- newnu = BKE_nurb_duplicate(nu);
+ LISTBASE_FOREACH (Nurb *, nu, &cu->nurb) {
+ Nurb *newnu = BKE_nurb_duplicate(nu);
BKE_nurb_test_2d(newnu); /* after join, or any other creation of curve */
BLI_addtail(&editnurb->nurbs, newnu);
- nu = nu->next;
}
/* animation could be added in editmode even if there was no animdata in
@@ -1722,11 +1686,10 @@ static void rotateflagNurb(ListBase *editnurb,
const float rotmat[3][3])
{
/* all verts with (flag & 'flag') rotate */
- Nurb *nu;
BPoint *bp;
int a;
- for (nu = editnurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
if (nu->type == CU_NURBS) {
bp = nu->bp;
a = nu->pntsu * nu->pntsv;
@@ -1746,12 +1709,11 @@ static void rotateflagNurb(ListBase *editnurb,
void ed_editnurb_translate_flag(ListBase *editnurb, uint8_t flag, const float vec[3])
{
/* all verts with ('flag' & flag) translate */
- Nurb *nu;
BezTriple *bezt;
BPoint *bp;
int a;
- for (nu = editnurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
if (nu->type == CU_BEZIER) {
a = nu->pntsu;
bezt = nu->bezt;
@@ -1785,11 +1747,10 @@ void ed_editnurb_translate_flag(ListBase *editnurb, uint8_t flag, const float ve
static void weightflagNurb(ListBase *editnurb, short flag, float w)
{
- Nurb *nu;
BPoint *bp;
int a;
- for (nu = editnurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
if (nu->type == CU_NURBS) {
a = nu->pntsu * nu->pntsv;
bp = nu->bp;
@@ -1808,16 +1769,12 @@ static void ed_surf_delete_selected(Object *obedit)
{
Curve *cu = obedit->data;
ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu, *next;
BPoint *bp, *bpn, *newbp;
int a, b, newu, newv;
BLI_assert(obedit->type == OB_SURF);
- nu = editnurb->first;
- while (nu) {
- next = nu->next;
-
+ LISTBASE_FOREACH_MUTABLE (Nurb *, nu, editnurb) {
/* is entire nurb selected */
bp = nu->bp;
a = nu->pntsu * nu->pntsv;
@@ -1903,7 +1860,6 @@ static void ed_surf_delete_selected(Object *obedit)
}
}
}
- nu = next;
}
}
@@ -1912,15 +1868,12 @@ static void ed_curve_delete_selected(Object *obedit, View3D *v3d)
Curve *cu = obedit->data;
EditNurb *editnurb = cu->editnurb;
ListBase *nubase = &editnurb->nurbs;
- Nurb *nu, *next;
BezTriple *bezt, *bezt1;
BPoint *bp, *bp1;
int a, type, nuindex = 0;
/* first loop, can we remove entire pieces? */
- nu = nubase->first;
- while (nu) {
- next = nu->next;
+ LISTBASE_FOREACH_MUTABLE (Nurb *, nu, nubase) {
if (nu->type == CU_BEZIER) {
bezt = nu->bezt;
a = nu->pntsu;
@@ -1981,13 +1934,10 @@ static void ed_curve_delete_selected(Object *obedit, View3D *v3d)
clamp_nurb_order_u(nu);
}
#endif
- nu = next;
nuindex++;
}
/* 2nd loop, delete small pieces: just for curves */
- nu = nubase->first;
- while (nu) {
- next = nu->next;
+ LISTBASE_FOREACH_MUTABLE (Nurb *, nu, nubase) {
type = 0;
if (nu->type == CU_BEZIER) {
bezt = nu->bezt;
@@ -2047,21 +1997,17 @@ static void ed_curve_delete_selected(Object *obedit, View3D *v3d)
BKE_nurb_order_clamp_u(nu);
BKE_nurb_knot_calc_u(nu);
}
- nu = next;
}
}
/* only for OB_SURF */
bool ed_editnurb_extrude_flag(EditNurb *editnurb, const uint8_t flag)
{
- Nurb *nu;
BPoint *bp, *bpn, *newbp;
int a, u, v, len;
bool ok = false;
- nu = editnurb->nurbs.first;
- while (nu) {
-
+ LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) {
if (nu->pntsv == 1) {
bp = nu->bp;
a = nu->pntsu;
@@ -2166,7 +2112,6 @@ bool ed_editnurb_extrude_flag(EditNurb *editnurb, const uint8_t flag)
}
}
}
- nu = nu->next;
}
return ok;
@@ -2197,14 +2142,15 @@ static void adduplicateflagNurb(
Object *obedit, View3D *v3d, ListBase *newnurb, const uint8_t flag, const bool split)
{
ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu, *newnu;
+ Nurb *newnu;
BezTriple *bezt, *bezt1;
BPoint *bp, *bp1, *bp2, *bp3;
Curve *cu = (Curve *)obedit->data;
- int a, b, c, starta, enda, diffa, cyclicu, cyclicv, newu, newv, i;
+ int a, b, c, starta, enda, diffa, cyclicu, cyclicv, newu, newv;
char *usel;
- for (i = 0, nu = editnurb->first; nu; i++, nu = nu->next) {
+ int i = 0;
+ LISTBASE_FOREACH_INDEX (Nurb *, nu, editnurb, i) {
cyclicu = cyclicv = 0;
if (nu->type == CU_BEZIER) {
for (a = 0, bezt = nu->bezt; a < nu->pntsu; a++, bezt++) {
@@ -2569,7 +2515,7 @@ static void adduplicateflagNurb(
}
if (BLI_listbase_is_empty(newnurb) == false) {
- for (nu = newnurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, newnurb) {
if (nu->type == CU_BEZIER) {
if (split) {
/* recalc first and last */
@@ -2619,10 +2565,9 @@ static int switch_direction_exec(bContext *C, wmOperator *UNUSED(op))
}
EditNurb *editnurb = cu->editnurb;
- Nurb *nu;
- int i;
- for (nu = editnurb->nurbs.first, i = 0; nu; nu = nu->next, i++) {
+ int i = 0;
+ LISTBASE_FOREACH_INDEX (Nurb *, nu, &editnurb->nurbs, i) {
if (ED_curve_nurb_select_check(v3d, nu)) {
BKE_nurb_direction_switch(nu);
keyData_switchDirectionNurb(cu, nu);
@@ -2674,13 +2619,12 @@ static int set_goal_weight_exec(bContext *C, wmOperator *op)
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu;
BezTriple *bezt;
BPoint *bp;
float weight = RNA_float_get(op->ptr, "weight");
int a;
- for (nu = editnurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
if (nu->bezt) {
for (bezt = nu->bezt, a = 0; a < nu->pntsu; a++, bezt++) {
if (bezt->f2 & SELECT) {
@@ -2741,13 +2685,12 @@ static int set_radius_exec(bContext *C, wmOperator *op)
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu;
BezTriple *bezt;
BPoint *bp;
float radius = RNA_float_get(op->ptr, "radius");
int a;
- for (nu = editnurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
if (nu->bezt) {
for (bezt = nu->bezt, a = 0; a < nu->pntsu; a++, bezt++) {
if (bezt->f2 & SELECT) {
@@ -2853,12 +2796,11 @@ static int smooth_exec(bContext *C, wmOperator *UNUSED(op))
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu;
int a, a_end;
bool changed = false;
- for (nu = editnurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
if (nu->bezt) {
/* duplicate the curve to use in weight calculation */
const BezTriple *bezt_orig = MEM_dupallocN(nu->bezt);
@@ -2960,7 +2902,6 @@ void CURVE_OT_smooth(wmOperatorType *ot)
static void curve_smooth_value(ListBase *editnurb, const int bezt_offsetof, const int bp_offset)
{
- Nurb *nu;
BezTriple *bezt;
BPoint *bp;
int a;
@@ -2970,7 +2911,7 @@ static void curve_smooth_value(ListBase *editnurb, const int bezt_offsetof, cons
int start_sel, end_sel; /* selection indices, inclusive */
float start_rad, end_rad, fac, range;
- for (nu = editnurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
if (nu->bezt) {
#define BEZT_VALUE(bezt) (*((float *)((char *)(bezt) + bezt_offsetof)))
@@ -3289,12 +3230,11 @@ static int hide_exec(bContext *C, wmOperator *op)
}
ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu;
BPoint *bp;
BezTriple *bezt;
int a, sel;
- for (nu = editnurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
if (nu->type == CU_BEZIER) {
bezt = nu->bezt;
a = nu->pntsu;
@@ -3385,13 +3325,12 @@ static int reveal_exec(bContext *C, wmOperator *op)
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu;
BPoint *bp;
BezTriple *bezt;
int a;
bool changed = false;
- for (nu = editnurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
nu->hide = 0;
if (nu->type == CU_BEZIER) {
bezt = nu->bezt;
@@ -3462,7 +3401,6 @@ static void subdividenurb(Object *obedit, View3D *v3d, int number_cuts)
{
Curve *cu = obedit->data;
EditNurb *editnurb = cu->editnurb;
- Nurb *nu;
BezTriple *bezt, *beztnew, *beztn;
BPoint *bp, *prevbp, *bpnew, *bpn;
float vec[15];
@@ -3471,7 +3409,7 @@ static void subdividenurb(Object *obedit, View3D *v3d, int number_cuts)
// printf("*** subdivideNurb: entering subdivide\n");
- for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) {
amount = 0;
if (nu->type == CU_BEZIER) {
BezTriple *nextbezt;
@@ -3925,7 +3863,6 @@ static int set_spline_type_exec(bContext *C, wmOperator *op)
Main *bmain = CTX_data_main(C);
View3D *v3d = CTX_wm_view3d(C);
ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu;
bool changed = false;
bool changed_size = false;
const bool use_handles = RNA_boolean_get(op->ptr, "use_handles");
@@ -3936,7 +3873,7 @@ static int set_spline_type_exec(bContext *C, wmOperator *op)
continue;
}
- for (nu = editnurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
if (ED_curve_nurb_select_check(v3d, nu)) {
const int pntsu_prev = nu->pntsu;
const char *err_msg = NULL;
@@ -4225,12 +4162,11 @@ static void make_selection_list_nurb(View3D *v3d, ListBase *editnurb, ListBase *
{
ListBase nbase = {NULL, NULL};
NurbSort *nus, *nustest, *headdo, *taildo;
- Nurb *nu;
BPoint *bp;
float dist, headdist, taildist;
int a;
- for (nu = editnurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
if (ED_curve_nurb_select_check(v3d, nu)) {
nus = (NurbSort *)MEM_callocN(sizeof(NurbSort), "sort");
@@ -4996,7 +4932,6 @@ bool ed_editnurb_spin(
{
Curve *cu = (Curve *)obedit->data;
ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu;
float cmat[3][3], tmat[3][3], imat[3][3];
float bmat[3][3], rotmat[3][3], scalemat1[3][3], scalemat2[3][3];
float persmat[3][3], persinv[3][3];
@@ -5056,7 +4991,7 @@ bool ed_editnurb_spin(
}
if (ok) {
- for (nu = editnurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
if (ED_curve_nurb_select_check(v3d, nu)) {
nu->orderv = 4;
nu->flagv |= CU_NURB_CYCLIC;
@@ -5427,8 +5362,6 @@ static int ed_editcurve_addvert(Curve *cu,
View3D *v3d,
const float location_init[3])
{
- Nurb *nu;
-
float center[3];
float temp[3];
uint verts_len;
@@ -5437,7 +5370,7 @@ static int ed_editcurve_addvert(Curve *cu,
zero_v3(center);
verts_len = 0;
- for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) {
int i;
if (nu->type == CU_BEZIER) {
BezTriple *bezt;
@@ -5472,7 +5405,7 @@ static int ed_editcurve_addvert(Curve *cu,
ofs[2] = 0.0f;
}
- for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) {
if (nu->type == CU_BEZIER) {
BezTriple *bezt;
for (i = 0, bezt = nu->bezt; i < nu->pntsu; i++, bezt++) {
@@ -5511,7 +5444,7 @@ static int ed_editcurve_addvert(Curve *cu,
}
/* nothing selected: create a new curve */
- nu = BKE_curve_nurb_active_get(cu);
+ Nurb *nu = BKE_curve_nurb_active_get(cu);
if (!nu || nu->type == CU_BEZIER) {
Nurb *nurb_new;
@@ -5764,8 +5697,7 @@ static int curve_extrude_exec(bContext *C, wmOperator *UNUSED(op))
/* First test: curve? */
if (obedit->type != OB_CURVE) {
- Nurb *nu;
- for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) {
if ((nu->pntsv == 1) && (ED_curve_nurb_select_count(v3d, nu) == 1)) {
as_curve = true;
break;
@@ -5819,13 +5751,12 @@ void CURVE_OT_extrude(wmOperatorType *ot)
static bool curve_toggle_cyclic(View3D *v3d, ListBase *editnurb, int direction)
{
- Nurb *nu;
BezTriple *bezt;
BPoint *bp;
int a;
bool changed = false;
- for (nu = editnurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
if (nu->pntsu > 1 || nu->pntsv > 1) {
if (nu->type == CU_POLY) {
a = nu->pntsu;
@@ -5932,10 +5863,9 @@ static int toggle_cyclic_invoke(bContext *C, wmOperator *op, const wmEvent *UNUS
ListBase *editnurb = object_editcurve_get(obedit);
uiPopupMenu *pup;
uiLayout *layout;
- Nurb *nu;
if (obedit->type == OB_SURF) {
- for (nu = editnurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
if (nu->pntsu > 1 || nu->pntsv > 1) {
if (nu->type == CU_NURBS) {
pup = UI_popup_menu_begin(C, IFACE_("Direction"), ICON_NONE);
@@ -6064,12 +5994,12 @@ static bool curve_delete_segments(Object *obedit, View3D *v3d, const bool split)
Curve *cu = obedit->data;
EditNurb *editnurb = cu->editnurb;
ListBase *nubase = &editnurb->nurbs, newnurb = {NULL, NULL};
- Nurb *nu, *nu1;
+ Nurb *nu1;
BezTriple *bezt, *bezt1, *bezt2;
BPoint *bp, *bp1, *bp2;
int a, b, starta, enda, cut, cyclicut;
- for (nu = nubase->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, nubase) {
nu1 = NULL;
starta = enda = cut = -1;
cyclicut = 0;
@@ -6452,7 +6382,7 @@ static bool curve_delete_segments(Object *obedit, View3D *v3d, const bool split)
}
}
- for (nu = newnurb.first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, &newnurb) {
if (nu->type == CU_BEZIER) {
if (split) {
/* deselect for split operator */
@@ -6620,9 +6550,8 @@ static int curve_dissolve_exec(bContext *C, wmOperator *UNUSED(op))
}
ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu;
- for (nu = editnurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
if ((nu->type == CU_BEZIER) && (nu->pntsu > 2)) {
uint span_step[2] = {nu->pntsu, nu->pntsu};
uint span_len;
@@ -6766,9 +6695,8 @@ static int curve_decimate_exec(bContext *C, wmOperator *op)
{
ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu;
- for (nu = editnurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
if (nu->type == CU_BEZIER) {
if ((nu->pntsu > 2) && nurb_bezt_flag_any(nu, SELECT)) {
const int error_target_len = max_ii(2, nu->pntsu * ratio);
@@ -6917,7 +6845,6 @@ int ED_curve_join_objects_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
Object *ob_active = CTX_data_active_object(C);
Curve *cu;
- Nurb *nu, *newnu;
BezTriple *bezt;
BPoint *bp;
ListBase tempbase;
@@ -6955,9 +6882,8 @@ int ED_curve_join_objects_exec(bContext *C, wmOperator *op)
/* watch it: switch order here really goes wrong */
mul_m4_m4m4(cmat, imat, ob_iter->obmat);
- nu = cu->nurb.first;
- while (nu) {
- newnu = BKE_nurb_duplicate(nu);
+ LISTBASE_FOREACH (Nurb *, nu, &cu->nurb) {
+ Nurb *newnu = BKE_nurb_duplicate(nu);
if (ob_active->totcol) { /* TODO, merge material lists */
CLAMP(newnu->mat_nr, 0, ob_active->totcol - 1);
}
@@ -6983,7 +6909,6 @@ int ED_curve_join_objects_exec(bContext *C, wmOperator *op)
bp++;
}
}
- nu = nu->next;
}
}
@@ -7035,12 +6960,11 @@ static int clear_tilt_exec(bContext *C, wmOperator *UNUSED(op))
}
ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu;
BezTriple *bezt;
BPoint *bp;
int a;
- for (nu = editnurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
if (nu->bezt) {
bezt = nu->bezt;
a = nu->pntsu;
diff --git a/source/blender/editors/curve/editcurve_query.c b/source/blender/editors/curve/editcurve_query.c
index 48571ab2a9b..369137cbe25 100644
--- a/source/blender/editors/curve/editcurve_query.c
+++ b/source/blender/editors/curve/editcurve_query.c
@@ -26,6 +26,7 @@
#include "MEM_guardedalloc.h"
+#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BKE_curve.h"
@@ -170,7 +171,6 @@ void ED_curve_nurb_vert_selected_find(
/* in nu and (bezt or bp) selected are written if there's 1 sel. */
/* if more points selected in 1 spline: return only nu, bezt and bp are 0 */
ListBase *editnurb = &cu->editnurb->nurbs;
- Nurb *nu1;
BezTriple *bezt1;
BPoint *bp1;
int a;
@@ -179,7 +179,7 @@ void ED_curve_nurb_vert_selected_find(
*r_bezt = NULL;
*r_bp = NULL;
- for (nu1 = editnurb->first; nu1; nu1 = nu1->next) {
+ LISTBASE_FOREACH (Nurb *, nu1, editnurb) {
if (nu1->type == CU_BEZIER) {
bezt1 = nu1->bezt;
a = nu1->pntsu;
diff --git a/source/blender/editors/curve/editcurve_select.c b/source/blender/editors/curve/editcurve_select.c
index aa4ba332b66..4097275a2b9 100644
--- a/source/blender/editors/curve/editcurve_select.c
+++ b/source/blender/editors/curve/editcurve_select.c
@@ -237,9 +237,7 @@ int ED_curve_select_count(View3D *v3d, struct EditNurb *editnurb)
bool ED_curve_select_check(View3D *v3d, struct EditNurb *editnurb)
{
- Nurb *nu;
-
- for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) {
if (ED_curve_nurb_select_check(v3d, nu)) {
return true;
}
@@ -284,13 +282,12 @@ bool ED_curve_deselect_all_multi(struct bContext *C)
bool ED_curve_select_swap(EditNurb *editnurb, bool hide_handles)
{
- Nurb *nu;
BPoint *bp;
BezTriple *bezt;
int a;
bool changed = false;
- for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) {
if (nu->type == CU_BEZIER) {
bezt = nu->bezt;
a = nu->pntsu;
@@ -331,7 +328,6 @@ static void select_adjacent_cp(ListBase *editnurb,
const bool cont,
const bool selstatus)
{
- Nurb *nu;
BezTriple *bezt;
BPoint *bp;
int a;
@@ -341,7 +337,7 @@ static void select_adjacent_cp(ListBase *editnurb,
return;
}
- for (nu = editnurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
lastsel = false;
if (nu->type == CU_BEZIER) {
a = nu->pntsu;
@@ -412,7 +408,6 @@ static void select_adjacent_cp(ListBase *editnurb,
static void selectend_nurb(Object *obedit, eEndPoint_Types selfirst, bool doswap, bool selstatus)
{
ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu;
BPoint *bp;
BezTriple *bezt;
Curve *cu;
@@ -425,7 +420,7 @@ static void selectend_nurb(Object *obedit, eEndPoint_Types selfirst, bool doswap
cu = (Curve *)obedit->data;
cu->actvert = CU_ACT_NONE;
- for (nu = editnurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
if (nu->type == CU_BEZIER) {
a = nu->pntsu;
@@ -632,10 +627,9 @@ static int select_linked_exec(bContext *C, wmOperator *UNUSED(op))
Curve *cu = obedit->data;
EditNurb *editnurb = cu->editnurb;
ListBase *nurbs = &editnurb->nurbs;
- Nurb *nu;
bool changed = false;
- for (nu = nurbs->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, nurbs) {
if (ED_curve_nurb_select_check(v3d, nu)) {
changed |= ED_curve_nurb_select_all(nu);
}
@@ -887,7 +881,6 @@ void CURVE_OT_select_previous(wmOperatorType *ot)
static void curve_select_more(Object *obedit)
{
ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu;
BPoint *bp, *tempbp;
int a;
short sel = 0;
@@ -897,7 +890,7 @@ static void curve_select_more(Object *obedit)
/* The algorithm is designed to work in planar cases so it */
/* may not be optimal always (example: end of NURBS sphere) */
if (obedit->type == OB_SURF) {
- for (nu = editnurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
BLI_bitmap *selbpoints;
a = nu->pntsu * nu->pntsv;
bp = nu->bp;
@@ -997,7 +990,6 @@ void CURVE_OT_select_more(wmOperatorType *ot)
static void curve_select_less(Object *obedit)
{
ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu;
BPoint *bp;
BezTriple *bezt;
int a;
@@ -1005,7 +997,7 @@ static void curve_select_less(Object *obedit)
bool lastsel = false;
if (obedit->type == OB_SURF) {
- for (nu = editnurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
BLI_bitmap *selbpoints;
a = nu->pntsu * nu->pntsv;
bp = nu->bp;
@@ -1077,7 +1069,7 @@ static void curve_select_less(Object *obedit)
}
}
else {
- for (nu = editnurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
lastsel = false;
/* check what type of curve/nurb it is */
if (nu->type == CU_BEZIER) {
@@ -1210,14 +1202,13 @@ void CURVE_OT_select_less(wmOperatorType *ot)
static void curve_select_random(ListBase *editnurb, float randfac, int seed, bool select)
{
- Nurb *nu;
BezTriple *bezt;
BPoint *bp;
int a;
RNG *rng = BLI_rng_new_srandom(seed);
- for (nu = editnurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
if (nu->type == CU_BEZIER) {
bezt = nu->bezt;
a = nu->pntsu;
@@ -1431,9 +1422,7 @@ void CURVE_OT_select_nth(wmOperatorType *ot)
}
/* -------------------------------------------------------------------- */
-/* Select Similar */
-
-/** \name Select Similar
+/** \name Select Similar Operator
* \{ */
static const EnumPropertyItem curve_prop_similar_compare_types[] = {
@@ -1702,8 +1691,7 @@ static int curve_select_similar_exec(bContext *C, wmOperator *op)
Curve *cu = obedit->data;
EditNurb *editnurb = cu->editnurb;
- Nurb *nu;
- for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) {
if (!ED_curve_nurb_select_check(v3d, nu)) {
continue;
}
@@ -1736,9 +1724,8 @@ static int curve_select_similar_exec(bContext *C, wmOperator *op)
Curve *cu = obedit->data;
EditNurb *editnurb = cu->editnurb;
bool changed = false;
- Nurb *nu;
- for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) {
switch (optype) {
case SIMCURHAND_TYPE: {
if (nu->type & type_ref) {
@@ -1797,9 +1784,7 @@ void CURVE_OT_select_similar(wmOperatorType *ot)
/** \} */
/* -------------------------------------------------------------------- */
-/* Select Shortest Path */
-
-/** \name Select Path
+/** \name Select Shortest Path Operator
* \{ */
static float curve_calc_dist_pair(const Nurb *nu, int a, int b)
diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c
index 2a880c11afb..1eb35b2c647 100644
--- a/source/blender/editors/curve/editfont.c
+++ b/source/blender/editors/curve/editfont.c
@@ -626,7 +626,7 @@ void FONT_OT_text_paste_from_file(wmOperatorType *ot)
FILE_OPENFILE,
WM_FILESEL_FILEPATH,
FILE_DEFAULTDISPLAY,
- FILE_SORT_ALPHA);
+ FILE_SORT_DEFAULT);
}
/** \} */
@@ -635,7 +635,10 @@ void FONT_OT_text_paste_from_file(wmOperatorType *ot)
/** \name Text To Object
* \{ */
-static void txt_add_object(bContext *C, TextLine *firstline, int totline, const float offset[3])
+static void txt_add_object(bContext *C,
+ const TextLine *firstline,
+ int totline,
+ const float offset[3])
{
Main *bmain = CTX_data_main(C);
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
@@ -644,7 +647,7 @@ static void txt_add_object(bContext *C, TextLine *firstline, int totline, const
Curve *cu;
Object *obedit;
Base *base;
- struct TextLine *tmp;
+ const struct TextLine *tmp;
int nchars = 0, nbytes = 0;
char *s;
int a;
@@ -709,10 +712,10 @@ static void txt_add_object(bContext *C, TextLine *firstline, int totline, const
WM_event_add_notifier(C, NC_OBJECT | NA_ADDED, obedit);
}
-void ED_text_to_object(bContext *C, Text *text, const bool split_lines)
+void ED_text_to_object(bContext *C, const Text *text, const bool split_lines)
{
RegionView3D *rv3d = CTX_wm_region_view3d(C);
- TextLine *line;
+ const TextLine *line;
float offset[3];
int linenum = 0;
@@ -2157,7 +2160,7 @@ void FONT_OT_open(wmOperatorType *ot)
FILE_OPENFILE,
WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH,
FILE_DEFAULTDISPLAY,
- FILE_SORT_ALPHA);
+ FILE_SORT_DEFAULT);
}
/** \} */
diff --git a/source/blender/editors/curve/editfont_undo.c b/source/blender/editors/curve/editfont_undo.c
index ef9bb7e0c88..61c05f62af7 100644
--- a/source/blender/editors/curve/editfont_undo.c
+++ b/source/blender/editors/curve/editfont_undo.c
@@ -74,6 +74,7 @@ typedef struct UndoFont {
#ifdef USE_ARRAY_STORE
+/* -------------------------------------------------------------------- */
/** \name Array Store
* \{ */
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index d54bdf552eb..6258e6e8481 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -2737,12 +2737,12 @@ static bool gpencil_snap_poll(bContext *C)
static int gpencil_snap_to_grid(bContext *C, wmOperator *UNUSED(op))
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
- RegionView3D *rv3d = CTX_wm_region_data(C);
+ ARegion *region = CTX_wm_region(C);
View3D *v3d = CTX_wm_view3d(C);
Scene *scene = CTX_data_scene(C);
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
Object *obact = CTX_data_active_object(C);
- const float gridf = ED_view3d_grid_view_scale(scene, v3d, rv3d, NULL);
+ const float gridf = ED_view3d_grid_view_scale(scene, v3d, region, NULL);
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
/* only editable and visible layers are considered */
@@ -3152,8 +3152,8 @@ void GPENCIL_OT_stroke_cyclical_set(wmOperatorType *ot)
PropertyRNA *prop;
static const EnumPropertyItem cyclic_type[] = {
- {GP_STROKE_CYCLIC_CLOSE, "CLOSE", 0, "Close all", ""},
- {GP_STROKE_CYCLIC_OPEN, "OPEN", 0, "Open all", ""},
+ {GP_STROKE_CYCLIC_CLOSE, "CLOSE", 0, "Close All", ""},
+ {GP_STROKE_CYCLIC_OPEN, "OPEN", 0, "Open All", ""},
{GP_STROKE_CYCLIC_TOGGLE, "TOGGLE", 0, "Toggle", ""},
{0, NULL, 0, NULL, NULL},
};
@@ -3398,24 +3398,50 @@ static void gpencil_stroke_join_strokes(bGPDstroke *gps_a,
}
/* define start and end points of each stroke */
- float area[3], sb[3], ea[3], eb[3];
+ float start_a[3], start_b[3], end_a[3], end_b[3];
pt = &gps_a->points[0];
- copy_v3_v3(area, &pt->x);
+ copy_v3_v3(start_a, &pt->x);
pt = &gps_a->points[gps_a->totpoints - 1];
- copy_v3_v3(ea, &pt->x);
+ copy_v3_v3(end_a, &pt->x);
pt = &gps_b->points[0];
- copy_v3_v3(sb, &pt->x);
+ copy_v3_v3(start_b, &pt->x);
pt = &gps_b->points[gps_b->totpoints - 1];
- copy_v3_v3(eb, &pt->x);
+ copy_v3_v3(end_b, &pt->x);
+
+ /* Check if need flip strokes. */
+ float dist = len_squared_v3v3(end_a, start_b);
+ bool flip_a = false;
+ bool flip_b = false;
+ float lowest = dist;
+
+ dist = len_squared_v3v3(end_a, end_b);
+ if (dist < lowest) {
+ lowest = dist;
+ flip_a = false;
+ flip_b = true;
+ }
+
+ dist = len_squared_v3v3(start_a, start_b);
+ if (dist < lowest) {
+ lowest = dist;
+ flip_a = true;
+ flip_b = false;
+ }
+
+ dist = len_squared_v3v3(start_a, end_b);
+ if (dist < lowest) {
+ lowest = dist;
+ flip_a = true;
+ flip_b = true;
+ }
- /* review if need flip stroke B */
- float ea_sb = len_squared_v3v3(ea, sb);
- float ea_eb = len_squared_v3v3(ea, eb);
- /* flip if distance to end point is shorter */
- if (ea_eb < ea_sb) {
+ if (flip_a) {
+ gpencil_flip_stroke(gps_a);
+ }
+ if (flip_b) {
gpencil_flip_stroke(gps_b);
}
@@ -3439,16 +3465,71 @@ static void gpencil_stroke_join_strokes(bGPDstroke *gps_a,
}
}
+typedef struct tJoinStrokes {
+ bGPDframe *gpf;
+ bGPDstroke *gps;
+ bool used;
+} tJoinStrokes;
+
+static int gpencil_get_nearest_stroke_index(tJoinStrokes *strokes_list,
+ const bGPDstroke *gps,
+ const int totstrokes)
+{
+ int index = -1;
+ float min_dist = FLT_MAX;
+ float dist, start_a[3], end_a[3], start_b[3], end_b[3];
+
+ bGPDspoint *pt = &gps->points[0];
+ copy_v3_v3(start_a, &pt->x);
+
+ pt = &gps->points[gps->totpoints - 1];
+ copy_v3_v3(end_a, &pt->x);
+
+ for (int i = 0; i < totstrokes; i++) {
+ tJoinStrokes *elem = &strokes_list[i];
+ if (elem->used) {
+ continue;
+ }
+ pt = &elem->gps->points[0];
+ copy_v3_v3(start_b, &pt->x);
+
+ pt = &elem->gps->points[elem->gps->totpoints - 1];
+ copy_v3_v3(end_b, &pt->x);
+
+ dist = len_squared_v3v3(start_a, start_b);
+ if (dist < min_dist) {
+ min_dist = dist;
+ index = i;
+ }
+ dist = len_squared_v3v3(start_a, end_b);
+ if (dist < min_dist) {
+ min_dist = dist;
+ index = i;
+ }
+ dist = len_squared_v3v3(end_a, start_b);
+ if (dist < min_dist) {
+ min_dist = dist;
+ index = i;
+ }
+ dist = len_squared_v3v3(end_a, end_b);
+ if (dist < min_dist) {
+ min_dist = dist;
+ index = i;
+ }
+ }
+
+ return index;
+}
+
static int gpencil_stroke_join_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
bGPDlayer *activegpl = BKE_gpencil_layer_active_get(gpd);
Object *ob = CTX_data_active_object(C);
-
- bGPDframe *gpf_a = NULL;
- bGPDstroke *stroke_a = NULL;
- bGPDstroke *stroke_b = NULL;
- bGPDstroke *new_stroke = NULL;
+ /* Limit the number of strokes to join. It makes no sense to allow an very high number of strokes
+ * for CPU time and because to have a stroke with thousands of points is unpractical, so limit
+ * this number avoid to joining a full frame scene in one single stroke. */
+ const int max_join_strokes = 128;
const int type = RNA_enum_get(op->ptr, "type");
const bool leave_gaps = RNA_boolean_get(op->ptr, "leave_gaps");
@@ -3464,87 +3545,89 @@ static int gpencil_stroke_join_exec(bContext *C, wmOperator *op)
BLI_assert(ELEM(type, GP_STROKE_JOIN, GP_STROKE_JOINCOPY));
- /* read all selected strokes */
- bool first = false;
+ int tot_strokes = 0;
+ /** Alloc memory */
+ tJoinStrokes *strokes_list = MEM_malloc_arrayN(sizeof(tJoinStrokes), max_join_strokes, __func__);
+ tJoinStrokes *elem = NULL;
+ /* Read all selected strokes to create a list. */
CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) {
bGPDframe *gpf = gpl->actframe;
if (gpf == NULL) {
continue;
}
- LISTBASE_FOREACH_MUTABLE (bGPDstroke *, gps, &gpf->strokes) {
+ /* Add all stroke selected of the frame. */
+ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
if (gps->flag & GP_STROKE_SELECT) {
/* skip strokes that are invalid for current view */
if (ED_gpencil_stroke_can_use(C, gps) == false) {
continue;
}
- /* check if the color is editable */
+ /* check if the color is editable. */
if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) {
continue;
}
-
- /* to join strokes, cyclic must be disabled */
- gps->flag &= ~GP_STROKE_CYCLIC;
-
- /* saves first frame and stroke */
- if (!first) {
- first = true;
- gpf_a = gpf;
- stroke_a = gps;
+ elem = &strokes_list[tot_strokes];
+ elem->gpf = gpf;
+ elem->gps = gps;
+ elem->used = false;
+
+ tot_strokes++;
+ /* Limit the number of strokes. */
+ if (tot_strokes == max_join_strokes) {
+ BKE_reportf(op->reports,
+ RPT_WARNING,
+ "Too many strokes selected. Only joined first %d strokes.",
+ max_join_strokes);
+ break;
}
- else {
- stroke_b = gps;
-
- /* create a new stroke if was not created before (only created if something to join) */
- if (new_stroke == NULL) {
- new_stroke = BKE_gpencil_stroke_duplicate(stroke_a, true);
+ }
+ }
+ }
+ CTX_DATA_END;
- /* if new, set current color */
- if (type == GP_STROKE_JOINCOPY) {
- new_stroke->mat_nr = stroke_a->mat_nr;
- }
- }
+ /* Nothing to join. */
+ if (tot_strokes < 2) {
+ MEM_SAFE_FREE(strokes_list);
+ return OPERATOR_CANCELLED;
+ }
- /* join new_stroke and stroke B. New stroke will contain all the previous data */
- gpencil_stroke_join_strokes(new_stroke, stroke_b, leave_gaps);
+ /* Take first stroke. */
+ elem = &strokes_list[0];
+ elem->used = true;
- /* if join only, delete old strokes */
- if (type == GP_STROKE_JOIN) {
- if (stroke_a) {
- /* Calc geometry data. */
- BKE_gpencil_stroke_geometry_update(new_stroke);
+ /* Create a new stroke. */
+ bGPDstroke *gps_new = BKE_gpencil_stroke_duplicate(elem->gps, true);
+ gps_new->flag &= ~GP_STROKE_CYCLIC;
+ BLI_insertlinkbefore(&elem->gpf->strokes, elem->gps, gps_new);
- BLI_insertlinkbefore(&gpf_a->strokes, stroke_a, new_stroke);
- BLI_remlink(&gpf->strokes, stroke_a);
- BKE_gpencil_free_stroke(stroke_a);
- stroke_a = NULL;
- }
- if (stroke_b) {
- BLI_remlink(&gpf->strokes, stroke_b);
- BKE_gpencil_free_stroke(stroke_b);
- stroke_b = NULL;
- }
- }
- }
- }
+ /* Join all strokes until the list is completed. */
+ while (true) {
+ int i = gpencil_get_nearest_stroke_index(strokes_list, gps_new, tot_strokes);
+ if (i < 0) {
+ break;
}
+ elem = &strokes_list[i];
+ /* Join new_stroke and stroke B. */
+ gpencil_stroke_join_strokes(gps_new, elem->gps, leave_gaps);
+ elem->used = true;
}
- CTX_DATA_END;
- /* add new stroke if was not added before */
- if (type == GP_STROKE_JOINCOPY) {
- if (new_stroke) {
- /* Add a new frame if needed */
- if (activegpl->actframe == NULL) {
- activegpl->actframe = BKE_gpencil_frame_addnew(activegpl, gpf_a->framenum);
- }
- /* Calc geometry data. */
- BKE_gpencil_stroke_geometry_update(new_stroke);
+ /* Calc geometry data for new stroke. */
+ BKE_gpencil_stroke_geometry_update(gps_new);
- BLI_addtail(&activegpl->actframe->strokes, new_stroke);
+ /* If join only, delete old strokes. */
+ if (type == GP_STROKE_JOIN) {
+ for (int i = 0; i < tot_strokes; i++) {
+ elem = &strokes_list[i];
+ BLI_remlink(&elem->gpf->strokes, elem->gps);
+ BKE_gpencil_free_stroke(elem->gps);
}
}
+ /* Free memory. */
+ MEM_SAFE_FREE(strokes_list);
+
/* notifiers */
DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
@@ -4678,7 +4761,9 @@ typedef bool (*GPencilTestFn)(bGPDstroke *gps,
const float diff_mat[4][4],
void *user_data);
-static void gpencil_cutter_dissolve(bGPDlayer *hit_layer, bGPDstroke *hit_stroke)
+static void gpencil_cutter_dissolve(bGPDlayer *hit_layer,
+ bGPDstroke *hit_stroke,
+ const bool flat_caps)
{
bGPDspoint *pt = NULL;
bGPDspoint *pt1 = NULL;
@@ -4722,6 +4807,17 @@ static void gpencil_cutter_dissolve(bGPDlayer *hit_layer, bGPDstroke *hit_stroke
pt->flag &= ~GP_SPOINT_TAG;
}
}
+ /* If flat caps mode check extremes. */
+ if (flat_caps) {
+ if (hit_stroke->points[0].flag & GP_SPOINT_TAG) {
+ hit_stroke->caps[0] = GP_STROKE_CAP_FLAT;
+ }
+
+ if (hit_stroke->points[hit_stroke->totpoints - 1].flag & GP_SPOINT_TAG) {
+ hit_stroke->caps[1] = GP_STROKE_CAP_FLAT;
+ }
+ }
+
gpencil_stroke_delete_tagged_points(
hit_layer->actframe, hit_stroke, gpsn, GP_SPOINT_TAG, false, 1);
}
@@ -4736,6 +4832,7 @@ static int gpencil_cutter_lasso_select(bContext *C,
ScrArea *area = CTX_wm_area(C);
ToolSettings *ts = CTX_data_tool_settings(C);
const float scale = ts->gp_sculpt.isect_threshold;
+ const bool flat_caps = RNA_boolean_get(op->ptr, "flat_caps");
bGPDspoint *pt;
GP_SpaceConversion gsc = {NULL};
@@ -4810,7 +4907,7 @@ static int gpencil_cutter_lasso_select(bContext *C,
}
LISTBASE_FOREACH_MUTABLE (bGPDstroke *, gps, &gpf->strokes) {
if (gps->flag & GP_STROKE_SELECT) {
- gpencil_cutter_dissolve(gpl, gps);
+ gpencil_cutter_dissolve(gpl, gps, flat_caps);
}
}
}
@@ -4884,6 +4981,8 @@ void GPENCIL_OT_stroke_cutter(wmOperatorType *ot)
/* properties */
WM_operator_properties_gesture_lasso(ot);
+
+ RNA_def_boolean(ot->srna, "flat_caps", 0, "Flat Caps", "");
}
bool ED_object_gpencil_exit(struct Main *bmain, Object *ob)
diff --git a/source/blender/editors/gpencil/gpencil_interpolate.c b/source/blender/editors/gpencil/gpencil_interpolate.c
index 2e13566402b..3a3a9bde38b 100644
--- a/source/blender/editors/gpencil/gpencil_interpolate.c
+++ b/source/blender/editors/gpencil/gpencil_interpolate.c
@@ -220,7 +220,7 @@ static bool gpencil_interpolate_check_todo(bContext *C, bGPdata *gpd)
int fFrame;
/* only selected */
- if ((flag & GP_TOOLFLAG_INTERPOLATE_ONLY_SELECTED) &&
+ if ((GPENCIL_EDIT_MODE(gpd)) && (flag & GP_TOOLFLAG_INTERPOLATE_ONLY_SELECTED) &&
((gps_from->flag & GP_STROKE_SELECT) == 0)) {
continue;
}
@@ -305,7 +305,7 @@ static void gpencil_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi)
bool valid = true;
/* only selected */
- if ((tgpi->flag & GP_TOOLFLAG_INTERPOLATE_ONLY_SELECTED) &&
+ if ((GPENCIL_EDIT_MODE(gpd)) && (tgpi->flag & GP_TOOLFLAG_INTERPOLATE_ONLY_SELECTED) &&
((gps_from->flag & GP_STROKE_SELECT) == 0)) {
valid = false;
}
@@ -1023,7 +1023,7 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
for (gps_from = prevFrame->strokes.first; gps_from; gps_from = gps_from->next) {
/* only selected */
- if ((flag & GP_TOOLFLAG_INTERPOLATE_ONLY_SELECTED) &&
+ if ((GPENCIL_EDIT_MODE(gpd)) && (flag & GP_TOOLFLAG_INTERPOLATE_ONLY_SELECTED) &&
((gps_from->flag & GP_STROKE_SELECT) == 0)) {
continue;
}
diff --git a/source/blender/editors/gpencil/gpencil_mesh.c b/source/blender/editors/gpencil/gpencil_mesh.c
index e4862617d12..c136ef2070e 100644
--- a/source/blender/editors/gpencil/gpencil_mesh.c
+++ b/source/blender/editors/gpencil/gpencil_mesh.c
@@ -25,12 +25,15 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
+#include "BLI_ghash.h"
#include "BLI_math.h"
+#include "DNA_anim_types.h"
#include "DNA_gpencil_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
+#include "BKE_anim_data.h"
#include "BKE_context.h"
#include "BKE_duplilist.h"
#include "BKE_global.h"
@@ -86,6 +89,35 @@ typedef struct GpBakeOb {
Object *ob;
} GpBakeOb;
+/* Get list of keyframes used by selected objects. */
+static void animdata_keyframe_list_get(ListBase *ob_list,
+ const bool only_selected,
+ GHash *r_keyframes)
+{
+ /* Loop all objects to get the list of keyframes used. */
+ LISTBASE_FOREACH (GpBakeOb *, elem, ob_list) {
+ Object *ob = elem->ob;
+ AnimData *adt = BKE_animdata_from_id(&ob->id);
+ if ((adt == NULL) || (adt->action == NULL)) {
+ continue;
+ }
+ LISTBASE_FOREACH (FCurve *, fcurve, &adt->action->curves) {
+ int i;
+ BezTriple *bezt;
+ for (i = 0, bezt = fcurve->bezt; i < fcurve->totvert; i++, bezt++) {
+ /* Keyframe number is x value of point. */
+ if ((bezt->f2 & SELECT) || (!only_selected)) {
+ /* Insert only one key for each keyframe number. */
+ int key = (int)bezt->vec[1][0];
+ if (!BLI_ghash_haskey(r_keyframes, POINTER_FROM_INT(key))) {
+ BLI_ghash_insert(r_keyframes, POINTER_FROM_INT(key), POINTER_FROM_INT(key));
+ }
+ }
+ }
+ }
+ }
+}
+
static void gpencil_bake_duplilist(Depsgraph *depsgraph, Scene *scene, Object *ob, ListBase *list)
{
GpBakeOb *elem = NULL;
@@ -161,13 +193,13 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op)
View3D *v3d = CTX_wm_view3d(C);
Object *ob_gpencil = NULL;
- ListBase list = {NULL, NULL};
- gpencil_bake_ob_list(C, depsgraph, scene, &list);
+ ListBase ob_selected_list = {NULL, NULL};
+ gpencil_bake_ob_list(C, depsgraph, scene, &ob_selected_list);
/* Cannot check this in poll because the active object changes. */
- if (list.first == NULL) {
+ if (ob_selected_list.first == NULL) {
BKE_report(op->reports, RPT_INFO, "No valid object selected");
- gpencil_bake_free_ob_list(&list);
+ gpencil_bake_free_ob_list(&ob_selected_list);
return OPERATOR_CANCELLED;
}
@@ -186,29 +218,20 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op)
const int thickness = RNA_int_get(op->ptr, "thickness");
const bool use_seams = RNA_boolean_get(op->ptr, "seams");
const bool use_faces = RNA_boolean_get(op->ptr, "faces");
+ const bool only_selected = RNA_boolean_get(op->ptr, "only_selected");
const float offset = RNA_float_get(op->ptr, "offset");
const int frame_offset = RNA_int_get(op->ptr, "frame_target") - frame_start;
- char target[64];
- RNA_string_get(op->ptr, "target", target);
const int project_type = RNA_enum_get(op->ptr, "project_type");
+ ob_gpencil = (Object *)RNA_pointer_get(op->ptr, "target").data;
/* Create a new grease pencil object in origin. */
bool newob = false;
- if (STREQ(target, "*NEW")) {
+ if (ob_gpencil == NULL) {
ushort local_view_bits = (v3d && v3d->localvd) ? v3d->local_view_uuid : 0;
const float loc[3] = {0.0f, 0.0f, 0.0f};
ob_gpencil = ED_gpencil_add_object(C, loc, local_view_bits);
newob = true;
}
- else {
- ob_gpencil = BLI_findstring(&bmain->objects, target, offsetof(ID, name) + 2);
- }
-
- if ((ob_gpencil == NULL) || (ob_gpencil->type != OB_GPENCIL)) {
- BKE_report(op->reports, RPT_ERROR, "Target grease pencil object not valid");
- gpencil_bake_free_ob_list(&list);
- return OPERATOR_CANCELLED;
- }
bGPdata *gpd = (bGPdata *)ob_gpencil->data;
gpd->draw_mode = (project_type == GP_REPROJECT_KEEP) ? GP_DRAWMODE_3D : GP_DRAWMODE_2D;
@@ -237,6 +260,13 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op)
/* Loop all frame range. */
int oldframe = (int)DEG_get_ctime(depsgraph);
int key = -1;
+
+ /* Get list of keyframes. */
+ GHash *keyframe_list = BLI_ghash_int_new(__func__);
+ if (only_selected) {
+ animdata_keyframe_list_get(&ob_selected_list, only_selected, keyframe_list);
+ }
+
for (int i = frame_start; i < frame_end + 1; i++) {
key++;
/* Jump if not step limit but include last frame always. */
@@ -244,12 +274,17 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op)
continue;
}
+ /* Check if frame is in the list of frames to be exported. */
+ if ((only_selected) && (!BLI_ghash_haskey(keyframe_list, POINTER_FROM_INT(i)))) {
+ continue;
+ }
+
/* Move scene to new frame. */
CFRA = i;
BKE_scene_graph_update_for_newframe(depsgraph);
/* Loop all objects in the list. */
- LISTBASE_FOREACH (GpBakeOb *, elem, &list) {
+ LISTBASE_FOREACH (GpBakeOb *, elem, &ob_selected_list) {
Object *ob_eval = (Object *)DEG_get_evaluated_object(depsgraph, elem->ob);
/* Generate strokes. */
@@ -270,13 +305,14 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op)
if (project_type != GP_REPROJECT_KEEP) {
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
bGPDframe *gpf = gpl->actframe;
- if (gpf != NULL) {
- LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
- if ((gps->flag & GP_STROKE_TAG) == 0) {
- ED_gpencil_stroke_reproject(
- depsgraph, &gsc, sctx, gpl, gpf, gps, project_type, false);
- gps->flag |= GP_STROKE_TAG;
- }
+ if (gpf == NULL) {
+ continue;
+ }
+ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+ if ((gps->flag & GP_STROKE_TAG) == 0) {
+ ED_gpencil_stroke_reproject(
+ depsgraph, &gsc, sctx, gpl, gpf, gps, project_type, false);
+ gps->flag |= GP_STROKE_TAG;
}
}
}
@@ -314,10 +350,14 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op)
}
/* Free memory. */
- gpencil_bake_free_ob_list(&list);
+ gpencil_bake_free_ob_list(&ob_selected_list);
if (sctx != NULL) {
ED_transform_snap_object_context_destroy(sctx);
}
+ /* Free temp hash table. */
+ if (keyframe_list != NULL) {
+ BLI_ghash_free(keyframe_list, NULL, NULL);
+ }
/* notifiers */
if (newob) {
@@ -334,6 +374,19 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
+static int gpencil_bake_mesh_animation_invoke(bContext *C,
+ wmOperator *op,
+ const wmEvent *UNUSED(event))
+{
+ /* Show popup dialog to allow editing. */
+ /* FIXME: hard-coded dimensions here are just arbitrary. */
+ return WM_operator_props_dialog_popup(C, op, 250);
+}
+
+static bool rna_GPencil_object_poll(PointerRNA *UNUSED(ptr), PointerRNA value)
+{
+ return ((Object *)value.owner_id)->type == OB_GPENCIL;
+}
void GPENCIL_OT_bake_mesh_animation(wmOperatorType *ot)
{
static const EnumPropertyItem reproject_type[] = {
@@ -363,6 +416,7 @@ void GPENCIL_OT_bake_mesh_animation(wmOperatorType *ot)
ot->description = "Bake Mesh Animation to Grease Pencil strokes";
/* callbacks */
+ ot->invoke = gpencil_bake_mesh_animation_invoke;
ot->exec = gpencil_bake_mesh_animation_exec;
ot->poll = gpencil_bake_mesh_animation_poll;
@@ -370,7 +424,15 @@ void GPENCIL_OT_bake_mesh_animation(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- ot->prop = RNA_def_int(
+ ot->prop = RNA_def_pointer_runtime(ot->srna,
+ "target",
+ &RNA_Object,
+ "Target Object",
+ "Target grease pencil object. Leave empty for new object");
+ RNA_def_property_poll_runtime(ot->prop, rna_GPencil_object_poll);
+ RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
+
+ prop = RNA_def_int(
ot->srna, "frame_start", 1, 1, 100000, "Start Frame", "The start frame", 1, 100000);
prop = RNA_def_int(
@@ -379,6 +441,8 @@ void GPENCIL_OT_bake_mesh_animation(wmOperatorType *ot)
prop = RNA_def_int(ot->srna, "step", 1, 1, 100, "Step", "Step between generated frames", 1, 100);
+ RNA_def_int(ot->srna, "thickness", 1, 1, 100, "Thickness", "", 1, 100);
+
prop = RNA_def_float_rotation(ot->srna,
"angle",
0,
@@ -391,18 +455,22 @@ void GPENCIL_OT_bake_mesh_animation(wmOperatorType *ot)
DEG2RADF(180.0f));
RNA_def_property_float_default(prop, DEG2RADF(70.0f));
- RNA_def_int(ot->srna, "thickness", 1, 1, 100, "Thickness", "", 1, 100);
+ RNA_def_float_distance(ot->srna,
+ "offset",
+ 0.001f,
+ 0.0,
+ 100.0,
+ "Stroke Offset",
+ "Offset strokes from fill",
+ 0.0,
+ 100.00);
+
RNA_def_boolean(ot->srna, "seams", 0, "Only Seam Edges", "Convert only seam edges");
RNA_def_boolean(ot->srna, "faces", 1, "Export Faces", "Export faces as filled strokes");
- RNA_def_float_distance(
- ot->srna, "offset", 0.001f, 0.0, 100.0, "Offset", "Offset strokes from fill", 0.0, 100.00);
- RNA_def_int(ot->srna, "frame_target", 1, 1, 100000, "Frame Target", "", 1, 100000);
- RNA_def_string(ot->srna,
- "target",
- "*NEW",
- 64,
- "Target Object",
- "Target grease pencil object name. Leave empty for new object");
+ RNA_def_boolean(
+ ot->srna, "only_selected", 0, "Only Selected Keyframes", "Convert only selected keyframes");
+ RNA_def_int(
+ ot->srna, "frame_target", 1, 1, 100000, "Target Frame", "Destination frame", 1, 100000);
RNA_def_enum(ot->srna, "project_type", reproject_type, GP_REPROJECT_VIEW, "Projection Type", "");
}
diff --git a/source/blender/editors/gpencil/gpencil_trace.h b/source/blender/editors/gpencil/gpencil_trace.h
index 3adde7651cd..85eb4e0609f 100644
--- a/source/blender/editors/gpencil/gpencil_trace.h
+++ b/source/blender/editors/gpencil/gpencil_trace.h
@@ -56,6 +56,10 @@ struct bGPDframe;
#define BM_INV(bm, x, y) (bm_safe(bm, x, y) ? BM_UINV(bm, x, y) : 0)
#define BM_PUT(bm, x, y, b) (bm_safe(bm, x, y) ? BM_UPUT(bm, x, y, b) : 0)
+/* Trace modes */
+#define GPENCIL_TRACE_MODE_SINGLE 0
+#define GPENCIL_TRACE_MODE_SEQUENCE 1
+
void ED_gpencil_trace_bitmap_print(FILE *f, const potrace_bitmap_t *bm);
potrace_bitmap_t *ED_gpencil_trace_bitmap_new(int32_t w, int32_t h);
diff --git a/source/blender/editors/gpencil/gpencil_trace_ops.c b/source/blender/editors/gpencil/gpencil_trace_ops.c
index 4391abee5a1..2d04c31e60d 100644
--- a/source/blender/editors/gpencil/gpencil_trace_ops.c
+++ b/source/blender/editors/gpencil/gpencil_trace_ops.c
@@ -35,8 +35,10 @@
#include "BKE_context.h"
#include "BKE_duplilist.h"
+#include "BKE_global.h"
#include "BKE_gpencil.h"
#include "BKE_image.h"
+#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_object.h"
@@ -45,11 +47,15 @@
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
+#include "UI_interface.h"
+#include "UI_resources.h"
+
#include "WM_api.h"
#include "WM_types.h"
#include "RNA_access.h"
#include "RNA_define.h"
+#include "RNA_enum_types.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
@@ -61,34 +67,50 @@
#include "gpencil_trace.h"
#include "potracelib.h"
+typedef struct TraceJob {
+ /* from wmJob */
+ struct Object *owner;
+ short *stop, *do_update;
+ float *progress;
+
+ bContext *C;
+ wmWindowManager *wm;
+ Main *bmain;
+ Scene *scene;
+ View3D *v3d;
+ Base *base_active;
+ Object *ob_active;
+ Image *image;
+ Object *ob_gpencil;
+ bGPdata *gpd;
+ bGPDlayer *gpl;
+
+ bool was_ob_created;
+
+ int32_t frame_target;
+ float threshold;
+ float scale;
+ float sample;
+ int32_t resolution;
+ int32_t thickness;
+ int32_t turnpolicy;
+ int32_t mode;
+
+ bool success;
+ bool was_canceled;
+} TraceJob;
+
/**
* Trace a image.
- * \param C: Context
- * \param op: Operator
- * \param ob: Grease pencil object, can be NULL
- * \param ima: Image
- * \param gpf: Destination frame
+ * \param ibuf: Image buffer.
+ * \param gpf: Destination frame.
*/
-static bool gpencil_trace_image(
- bContext *C, wmOperator *op, Object *ob, Image *ima, bGPDframe *gpf)
+static bool gpencil_trace_image(TraceJob *trace_job, ImBuf *ibuf, bGPDframe *gpf)
{
- Main *bmain = CTX_data_main(C);
-
potrace_bitmap_t *bm = NULL;
potrace_param_t *param = NULL;
potrace_state_t *st = NULL;
- const float threshold = RNA_float_get(op->ptr, "threshold");
- const float scale = RNA_float_get(op->ptr, "scale");
- const float sample = RNA_float_get(op->ptr, "sample");
- const int32_t resolution = RNA_int_get(op->ptr, "resolution");
- const int32_t thickness = RNA_int_get(op->ptr, "thickness");
- const int32_t turnpolicy = RNA_enum_get(op->ptr, "turnpolicy");
-
- ImBuf *ibuf;
- void *lock;
- ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);
-
/* Create an empty BW bitmap. */
bm = ED_gpencil_trace_bitmap_new(ibuf->x, ibuf->y);
if (!bm) {
@@ -101,10 +123,10 @@ static bool gpencil_trace_image(
return false;
}
param->turdsize = 0;
- param->turnpolicy = turnpolicy;
+ param->turnpolicy = trace_job->turnpolicy;
/* Load BW bitmap with image. */
- ED_gpencil_trace_image_to_bitmap(ibuf, bm, threshold);
+ ED_gpencil_trace_image_to_bitmap(ibuf, bm, trace_job->threshold);
/* Trace the bitmap. */
st = potrace_trace(param, bm);
@@ -128,23 +150,26 @@ static bool gpencil_trace_image(
* Really, there isn't documented in Potrace about how the scale is calculated,
* but after doing a lot of tests, it looks is using a VGA resolution (640) as a base.
* Maybe there are others ways to get the right scale conversion, but this solution works. */
- float scale_potrace = scale * (640.0f / (float)ibuf->x) * ((float)ibuf->x / (float)ibuf->y);
+ float scale_potrace = trace_job->scale * (640.0f / (float)ibuf->x) *
+ ((float)ibuf->x / (float)ibuf->y);
if (ibuf->x > ibuf->y) {
scale_potrace *= (float)ibuf->y / (float)ibuf->x;
}
- ED_gpencil_trace_data_to_strokes(
- bmain, st, ob, gpf, offset, scale_potrace, sample, resolution, thickness);
+ ED_gpencil_trace_data_to_strokes(trace_job->bmain,
+ st,
+ trace_job->ob_gpencil,
+ gpf,
+ offset,
+ scale_potrace,
+ trace_job->sample,
+ trace_job->resolution,
+ trace_job->thickness);
/* Free memory. */
potrace_state_free(st);
potrace_param_free(param);
- /* Release ibuf. */
- if (ibuf) {
- BKE_image_release_ibuf(ima, ibuf, lock);
- }
-
return true;
}
@@ -157,68 +182,192 @@ static bool gpencil_trace_image_poll(bContext *C)
return false;
}
+ Image *image = (Image *)ob->data;
+ if (!ELEM(image->source, IMA_SRC_FILE, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE)) {
+ CTX_wm_operator_poll_msg_set(C, "No valid image format selected");
+ return false;
+ }
+
return true;
}
-static int gpencil_trace_image_exec(bContext *C, wmOperator *op)
+static void trace_initialize_job_data(TraceJob *trace_job)
{
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
- View3D *v3d = CTX_wm_view3d(C);
- Base *base_active = CTX_data_active_base(C);
- Object *ob_active = base_active->object;
- Image *image = (Image *)ob_active->data;
- bool ob_created = false;
-
- const int32_t frame_target = CFRA;
- Object *ob_gpencil = (Object *)RNA_pointer_get(op->ptr, "target").data;
-
/* Create a new grease pencil object. */
- if (ob_gpencil == NULL) {
- ushort local_view_bits = (v3d && v3d->localvd) ? v3d->local_view_uuid : 0;
- ob_gpencil = ED_gpencil_add_object(C, ob_active->loc, local_view_bits);
+ if (trace_job->ob_gpencil == NULL) {
+ ushort local_view_bits = (trace_job->v3d && trace_job->v3d->localvd) ?
+ trace_job->v3d->local_view_uuid :
+ 0;
+ trace_job->ob_gpencil = ED_gpencil_add_object(
+ trace_job->C, trace_job->ob_active->loc, local_view_bits);
/* Apply image rotation. */
- copy_v3_v3(ob_gpencil->rot, ob_active->rot);
+ copy_v3_v3(trace_job->ob_gpencil->rot, trace_job->ob_active->rot);
/* Grease pencil is rotated 90 degrees in X axis by default. */
- ob_gpencil->rot[0] -= DEG2RADF(90.0f);
- ob_created = true;
+ trace_job->ob_gpencil->rot[0] -= DEG2RADF(90.0f);
+ trace_job->was_ob_created = true;
/* Apply image Scale. */
- copy_v3_v3(ob_gpencil->scale, ob_active->scale);
+ copy_v3_v3(trace_job->ob_gpencil->scale, trace_job->ob_active->scale);
+ /* The default display size of the image is 5.0 and this is used as scale = 1.0. */
+ mul_v3_fl(trace_job->ob_gpencil->scale, trace_job->ob_active->empty_drawsize / 5.0f);
}
- if ((ob_gpencil == NULL) || (ob_gpencil->type != OB_GPENCIL)) {
- BKE_report(op->reports, RPT_ERROR, "Target grease pencil object not valid");
- return OPERATOR_CANCELLED;
+ /* Create Layer. */
+ trace_job->gpd = (bGPdata *)trace_job->ob_gpencil->data;
+ trace_job->gpl = BKE_gpencil_layer_active_get(trace_job->gpd);
+ if (trace_job->gpl == NULL) {
+ trace_job->gpl = BKE_gpencil_layer_addnew(trace_job->gpd, DATA_("Trace"), true);
}
+}
- /* Create Layer. */
- bGPdata *gpd = (bGPdata *)ob_gpencil->data;
- bGPDlayer *gpl = BKE_gpencil_layer_active_get(gpd);
- if (gpl == NULL) {
- gpl = BKE_gpencil_layer_addnew(gpd, DATA_("Trace"), true);
+static void trace_start_job(void *customdata, short *stop, short *do_update, float *progress)
+{
+ TraceJob *trace_job = customdata;
+
+ trace_job->stop = stop;
+ trace_job->do_update = do_update;
+ trace_job->progress = progress;
+ trace_job->was_canceled = false;
+
+ G.is_break = false;
+
+ /* Single Image. */
+
+ if ((trace_job->image->source == IMA_SRC_FILE) ||
+ (trace_job->mode == GPENCIL_TRACE_MODE_SINGLE)) {
+ void *lock;
+ ImBuf *ibuf = BKE_image_acquire_ibuf(trace_job->image, NULL, &lock);
+ if (ibuf) {
+ /* Create frame. */
+ bGPDframe *gpf = BKE_gpencil_layer_frame_get(
+ trace_job->gpl, trace_job->frame_target, GP_GETFRAME_ADD_NEW);
+ gpencil_trace_image(trace_job, ibuf, gpf);
+ BKE_image_release_ibuf(trace_job->image, ibuf, lock);
+ *(trace_job->progress) = 1.0f;
+ }
+ }
+ /* Image sequence. */
+ else if (trace_job->image->type == IMA_TYPE_IMAGE) {
+ ImageUser *iuser = trace_job->ob_active->iuser;
+ for (int i = 0; i < iuser->frames; i++) {
+ if (G.is_break) {
+ trace_job->was_canceled = true;
+ break;
+ }
+
+ *(trace_job->progress) = (float)i / (float)iuser->frames;
+ *do_update = true;
+
+ iuser->framenr = i + 1;
+
+ void *lock;
+ ImBuf *ibuf = BKE_image_acquire_ibuf(trace_job->image, iuser, &lock);
+ if (ibuf) {
+ /* Create frame. */
+ bGPDframe *gpf = BKE_gpencil_layer_frame_get(
+ trace_job->gpl, trace_job->frame_target + i, GP_GETFRAME_ADD_NEW);
+ gpencil_trace_image(trace_job, ibuf, gpf);
+
+ BKE_image_release_ibuf(trace_job->image, ibuf, lock);
+ }
+ }
}
- /* Create frame. */
- bGPDframe *gpf = BKE_gpencil_layer_frame_get(gpl, frame_target, GP_GETFRAME_ADD_NEW);
- gpencil_trace_image(C, op, ob_gpencil, image, gpf);
+ trace_job->success = !trace_job->was_canceled;
+ *do_update = true;
+ *stop = 0;
+}
- /* Back to active base. */
- ED_object_base_activate(C, base_active);
+static void trace_end_job(void *customdata)
+{
+ TraceJob *trace_job = customdata;
+
+ /* If canceled, delete all previously created object and data-block. */
+ if ((trace_job->was_canceled) && (trace_job->was_ob_created) && (trace_job->ob_gpencil)) {
+ bGPdata *gpd = trace_job->ob_gpencil->data;
+ BKE_id_delete(trace_job->bmain, &trace_job->ob_gpencil->id);
+ BKE_id_delete(trace_job->bmain, &gpd->id);
+ }
- /* notifiers */
- if (ob_created) {
- DEG_relations_tag_update(bmain);
+ if (trace_job->success) {
+ DEG_relations_tag_update(trace_job->bmain);
+
+ DEG_id_tag_update(&trace_job->scene->id, ID_RECALC_SELECT);
+ DEG_id_tag_update(&trace_job->gpd->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
+
+ WM_main_add_notifier(NC_OBJECT | NA_ADDED, NULL);
+ WM_main_add_notifier(NC_SCENE | ND_OB_ACTIVE, trace_job->scene);
}
+}
- DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
- DEG_id_tag_update(&gpd->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
+static void trace_free_job(void *customdata)
+{
+ TraceJob *tj = customdata;
+ MEM_freeN(tj);
+}
- WM_event_add_notifier(C, NC_OBJECT | NA_ADDED, NULL);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
+static int gpencil_trace_image_exec(bContext *C, wmOperator *op)
+{
+ TraceJob *job = MEM_mallocN(sizeof(TraceJob), "TraceJob");
+ job->C = C;
+ job->owner = CTX_data_active_object(C);
+ job->wm = CTX_wm_manager(C);
+ job->bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ job->scene = scene;
+ job->v3d = CTX_wm_view3d(C);
+ job->base_active = CTX_data_active_base(C);
+ job->ob_active = job->base_active->object;
+ job->image = (Image *)job->ob_active->data;
+ job->frame_target = CFRA;
+
+ job->ob_gpencil = (Object *)RNA_pointer_get(op->ptr, "target").data;
+ job->was_ob_created = false;
+
+ job->threshold = RNA_float_get(op->ptr, "threshold");
+ job->scale = RNA_float_get(op->ptr, "scale");
+ job->sample = RNA_float_get(op->ptr, "sample");
+ job->resolution = RNA_int_get(op->ptr, "resolution");
+ job->thickness = RNA_int_get(op->ptr, "thickness");
+ job->turnpolicy = RNA_enum_get(op->ptr, "turnpolicy");
+ job->mode = RNA_enum_get(op->ptr, "mode");
+
+ trace_initialize_job_data(job);
+
+ /* Back to active base. */
+ ED_object_base_activate(job->C, job->base_active);
+
+ if (job->image->source == IMA_SRC_FILE) {
+ short stop = 0, do_update = true;
+ float progress;
+ trace_start_job(job, &stop, &do_update, &progress);
+ trace_end_job(job);
+ trace_free_job(job);
+ }
+ else {
+ wmJob *wm_job = WM_jobs_get(job->wm,
+ CTX_wm_window(C),
+ job->scene,
+ "Trace Image",
+ WM_JOB_PROGRESS,
+ WM_JOB_TYPE_TRACE_IMAGE);
+
+ WM_jobs_customdata_set(wm_job, job, trace_free_job);
+ WM_jobs_timer(wm_job, 0.1, NC_GEOM | ND_DATA, NC_GEOM | ND_DATA);
+ WM_jobs_callbacks(wm_job, trace_start_job, NULL, NULL, trace_end_job);
+
+ WM_jobs_start(CTX_wm_manager(C), wm_job);
+ }
return OPERATOR_FINISHED;
}
+static int gpencil_trace_image_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ /* Show popup dialog to allow editing. */
+ /* FIXME: hard-coded dimensions here are just arbitrary. */
+ return WM_operator_props_dialog_popup(C, op, 250);
+}
+
static bool rna_GPencil_object_poll(PointerRNA *UNUSED(ptr), PointerRNA value)
{
return ((Object *)value.owner_id)->type == OB_GPENCIL;
@@ -257,12 +406,19 @@ void GPENCIL_OT_trace_image(wmOperatorType *ot)
{0, NULL, 0, NULL, NULL},
};
+ static const EnumPropertyItem trace_modes[] = {
+ {GPENCIL_TRACE_MODE_SINGLE, "SINGLE", 0, "Single", "Trace the current frame of the image"},
+ {GPENCIL_TRACE_MODE_SEQUENCE, "SEQUENCE", 0, "Sequence", "Trace full sequence"},
+ {0, NULL, 0, NULL, NULL},
+ };
+
/* identifiers */
ot->name = "Trace Image to Grease Pencil";
ot->idname = "GPENCIL_OT_trace_image";
ot->description = "Extract Grease Pencil strokes from image";
/* callbacks */
+ ot->invoke = gpencil_trace_image_invoke;
ot->exec = gpencil_trace_image_exec;
ot->poll = gpencil_trace_image_poll;
@@ -270,9 +426,16 @@ void GPENCIL_OT_trace_image(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- prop = RNA_def_pointer_runtime(ot->srna, "target", &RNA_Object, "Target", "");
+ prop = RNA_def_pointer_runtime(
+ ot->srna,
+ "target",
+ &RNA_Object,
+ "Target Object",
+ "Target grease pencil object name. Leave empty to create a new object");
RNA_def_property_poll_runtime(prop, rna_GPencil_object_poll);
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+
RNA_def_int(ot->srna, "thickness", 10, 1, 1000, "Thickness", "", 1, 1000);
RNA_def_int(
ot->srna, "resolution", 5, 1, 20, "Resolution", "Resolution of the generated curves", 1, 20);
@@ -301,7 +464,7 @@ void GPENCIL_OT_trace_image(wmOperatorType *ot)
0.0f,
1.0f,
"Color Threshold",
- "Determine what is considered white and what black",
+ "Determine the lightness threshold above which strokes are generated",
0.0f,
1.0f);
RNA_def_enum(ot->srna,
@@ -310,4 +473,10 @@ void GPENCIL_OT_trace_image(wmOperatorType *ot)
POTRACE_TURNPOLICY_MINORITY,
"Turn Policy",
"Determines how to resolve ambiguities during decomposition of bitmaps into paths");
+ RNA_def_enum(ot->srna,
+ "mode",
+ trace_modes,
+ GPENCIL_TRACE_MODE_SINGLE,
+ "Mode",
+ "Determines if trace simple image or full sequence");
}
diff --git a/source/blender/editors/include/ED_buttons.h b/source/blender/editors/include/ED_buttons.h
index 5d153757900..90d3a527b0c 100644
--- a/source/blender/editors/include/ED_buttons.h
+++ b/source/blender/editors/include/ED_buttons.h
@@ -26,6 +26,7 @@
extern "C" {
#endif
+struct bContext;
struct SpaceProperties;
int ED_buttons_tabs_list(struct SpaceProperties *sbuts, short *context_tabs_array);
@@ -35,6 +36,8 @@ void ED_buttons_search_string_set(struct SpaceProperties *sbuts, const char *val
int ED_buttons_search_string_length(struct SpaceProperties *sbuts);
const char *ED_buttons_search_string_get(struct SpaceProperties *sbuts);
+void ED_buttons_set_context(const struct bContext *C, PointerRNA *ptr, const int context);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/editors/include/ED_curve.h b/source/blender/editors/include/ED_curve.h
index f9b1d9cdc64..8015a665970 100644
--- a/source/blender/editors/include/ED_curve.h
+++ b/source/blender/editors/include/ED_curve.h
@@ -84,7 +84,7 @@ void ED_curve_editfont_load(struct Object *obedit);
void ED_curve_editfont_make(struct Object *obedit);
void ED_curve_editfont_free(struct Object *obedit);
-void ED_text_to_object(struct bContext *C, struct Text *text, const bool split_lines);
+void ED_text_to_object(struct bContext *C, const struct Text *text, const bool split_lines);
void ED_curve_beztcpy(struct EditNurb *editnurb,
struct BezTriple *dst,
diff --git a/source/blender/editors/include/ED_fileselect.h b/source/blender/editors/include/ED_fileselect.h
index 341f97943a5..84808416074 100644
--- a/source/blender/editors/include/ED_fileselect.h
+++ b/source/blender/editors/include/ED_fileselect.h
@@ -35,6 +35,7 @@ struct SpaceFile;
struct bContext;
struct bScreen;
struct uiBlock;
+struct wmOperator;
struct wmWindow;
struct wmWindowManager;
@@ -145,6 +146,9 @@ void ED_fileselect_window_params_get(const struct wmWindow *win,
int win_size[2],
bool *is_maximized);
+struct ScrArea *ED_fileselect_handler_area_find(const struct wmWindow *win,
+ const struct wmOperator *file_operator);
+
int ED_path_extension_type(const char *path);
int ED_file_extension_icon(const char *path);
diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h
index 6fdd65fdcc9..2e9b711c99a 100644
--- a/source/blender/editors/include/ED_object.h
+++ b/source/blender/editors/include/ED_object.h
@@ -160,6 +160,7 @@ extern struct EnumPropertyItem prop_clear_parent_types[];
extern struct EnumPropertyItem prop_make_parent_types[];
#endif
+/* Set the object's parent, return true iff successful. */
bool ED_object_parent_set(struct ReportList *reports,
const struct bContext *C,
struct Scene *scene,
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index b8500ba0c37..dc1c43c0337 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -199,6 +199,7 @@ int ED_region_global_size_y(void);
void ED_area_update_region_sizes(struct wmWindowManager *wm,
struct wmWindow *win,
struct ScrArea *area);
+bool ED_area_has_shared_border(struct ScrArea *a, struct ScrArea *b);
ScrArea *ED_screen_areas_iter_first(const struct wmWindow *win, const bScreen *screen);
ScrArea *ED_screen_areas_iter_next(const bScreen *screen, const ScrArea *area);
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index d3eb6c00f57..f64c6a42f18 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -693,7 +693,7 @@ void ED_view3d_grid_steps(const struct Scene *scene,
float *r_grid_steps);
float ED_view3d_grid_view_scale(struct Scene *scene,
struct View3D *v3d,
- struct RegionView3D *rv3d,
+ struct ARegion *region,
const char **r_grid_unit);
void ED_scene_draw_fps(const struct Scene *scene, int xoffset, int *yoffset);
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index dc20e6f1813..d2f9b31cecd 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -772,6 +772,95 @@ static void ui_but_extra_icons_update_from_old_but(const uiBut *new_but, const u
}
/**
+ * Update pointers and other information in the old active button based on new information in the
+ * corresponding new button from the current layout pass.
+ *
+ * \param oldbut: The button from the last layout pass that will be moved to the new block.
+ * \param but: The newly added button with much of the up to date information, to be feed later.
+ *
+ * \note #uiBut has ownership of many of its pointers. When the button is freed all these
+ * pointers are freed as well, so ownership has to be moved out of \a but in order to free it.
+ */
+static void ui_but_update_old_active_from_new(uiBut *oldbut, uiBut *but)
+{
+ BLI_assert(oldbut->active);
+
+ /* flags from the buttons we want to refresh, may want to add more here... */
+ const int flag_copy = UI_BUT_REDALERT | UI_HAS_ICON;
+ const int drawflag_copy = 0; /* None currently. */
+
+ /* still stuff needs to be copied */
+ oldbut->rect = but->rect;
+ oldbut->context = but->context; /* set by Layout */
+
+ /* drawing */
+ oldbut->icon = but->icon;
+ oldbut->iconadd = but->iconadd;
+ oldbut->alignnr = but->alignnr;
+
+ /* typically the same pointers, but not on undo/redo */
+ /* XXX some menu buttons store button itself in but->poin. Ugly */
+ if (oldbut->poin != (char *)oldbut) {
+ SWAP(char *, oldbut->poin, but->poin);
+ SWAP(void *, oldbut->func_argN, but->func_argN);
+ }
+
+ /* Move tooltip from new to old. */
+ SWAP(uiButToolTipFunc, oldbut->tip_func, but->tip_func);
+ SWAP(void *, oldbut->tip_argN, but->tip_argN);
+
+ oldbut->flag = (oldbut->flag & ~flag_copy) | (but->flag & flag_copy);
+ oldbut->drawflag = (oldbut->drawflag & ~drawflag_copy) | (but->drawflag & drawflag_copy);
+
+ ui_but_extra_icons_update_from_old_but(but, oldbut);
+ SWAP(ListBase, but->extra_op_icons, oldbut->extra_op_icons);
+
+ if (oldbut->type == UI_BTYPE_SEARCH_MENU) {
+ uiButSearch *search_oldbut = (uiButSearch *)oldbut, *search_but = (uiButSearch *)but;
+
+ SWAP(uiButSearchArgFreeFn, search_oldbut->arg_free_fn, search_but->arg_free_fn);
+ SWAP(void *, search_oldbut->arg, search_but->arg);
+ }
+
+ /* copy hardmin for list rows to prevent 'sticking' highlight to mouse position
+ * when scrolling without moving mouse (see T28432) */
+ if (ELEM(oldbut->type, UI_BTYPE_ROW, UI_BTYPE_LISTROW)) {
+ oldbut->hardmax = but->hardmax;
+ }
+
+ if (oldbut->type == UI_BTYPE_PROGRESS_BAR) {
+ uiButProgressbar *progress_oldbut = (uiButProgressbar *)oldbut;
+ uiButProgressbar *progress_but = (uiButProgressbar *)but;
+ progress_oldbut->progress = progress_but->progress;
+ }
+
+ /* move/copy string from the new button to the old */
+ /* needed for alt+mouse wheel over enums */
+ if (but->str != but->strdata) {
+ if (oldbut->str != oldbut->strdata) {
+ SWAP(char *, but->str, oldbut->str);
+ }
+ else {
+ oldbut->str = but->str;
+ but->str = but->strdata;
+ }
+ }
+ else {
+ if (oldbut->str != oldbut->strdata) {
+ MEM_freeN(oldbut->str);
+ oldbut->str = oldbut->strdata;
+ }
+ BLI_strncpy(oldbut->strdata, but->strdata, sizeof(oldbut->strdata));
+ }
+
+ if (but->dragpoin && (but->dragflag & UI_BUT_DRAGPOIN_FREE)) {
+ SWAP(void *, but->dragpoin, oldbut->dragpoin);
+ }
+
+ /* note: if layout hasn't been applied yet, it uses old button pointers... */
+}
+
+/**
* \return true when \a but_p is set (only done for active buttons).
*/
static bool ui_but_update_from_old_block(const bContext *C,
@@ -779,57 +868,36 @@ static bool ui_but_update_from_old_block(const bContext *C,
uiBut **but_p,
uiBut **but_old_p)
{
- const int drawflag_copy = 0; /* None currently. */
-
uiBlock *oldblock = block->oldblock;
- uiBut *oldbut = NULL, *but = *but_p;
- bool found_active = false;
+ uiBut *but = *but_p;
#if 0
- /* simple/stupid - search every time */
- oldbut = ui_but_find_old(oldblock, but);
- (void)but_old_p;
+ /* Simple method - search every time. Keep this for easy testing of the "fast path." */
+ uiBut *oldbut = ui_but_find_old(oldblock, but);
+ UNUSED_VARS(but_old_p);
#else
BLI_assert(*but_old_p == NULL || BLI_findindex(&oldblock->buttons, *but_old_p) != -1);
- /* Fast-path - avoid loop-in-loop, calling #ui_but_find_old
- * as long as old/new buttons are aligned. */
+ /* As long as old and new buttons are aligned, avoid loop-in-loop (calling #ui_but_find_old). */
+ uiBut *oldbut;
if (LIKELY(*but_old_p && ui_but_equals_old(but, *but_old_p))) {
oldbut = *but_old_p;
}
else {
- /* fallback to block search */
+ /* Fallback to block search. */
oldbut = ui_but_find_old(oldblock, but);
}
(*but_old_p) = oldbut ? oldbut->next : NULL;
#endif
+ bool found_active = false;
+
if (!oldbut) {
- return found_active;
+ return false;
}
if (oldbut->active) {
- /* flags from the buttons we want to refresh, may want to add more here... */
- const int flag_copy = UI_BUT_REDALERT | UI_HAS_ICON;
-
- found_active = true;
-
-#if 0
- but->flag = oldbut->flag;
- but->active = oldbut->active;
- but->pos = oldbut->pos;
- but->ofs = oldbut->ofs;
- but->editstr = oldbut->editstr;
- but->editval = oldbut->editval;
- but->editvec = oldbut->editvec;
- but->selsta = oldbut->selsta;
- but->selend = oldbut->selend;
- but->softmin = oldbut->softmin;
- but->softmax = oldbut->softmax;
- oldbut->active = NULL;
-#endif
-
- /* move button over from oldblock to new block */
+ /* Move button over from oldblock to new block. */
BLI_remlink(&oldblock->buttons, oldbut);
BLI_insertlinkafter(&block->buttons, but, oldbut);
/* Add the old button to the button groups in the new block. */
@@ -837,82 +905,16 @@ static bool ui_but_update_from_old_block(const bContext *C,
oldbut->block = block;
*but_p = oldbut;
- /* still stuff needs to be copied */
- oldbut->rect = but->rect;
- oldbut->context = but->context; /* set by Layout */
-
- /* drawing */
- oldbut->icon = but->icon;
- oldbut->iconadd = but->iconadd;
- oldbut->alignnr = but->alignnr;
-
- /* typically the same pointers, but not on undo/redo */
- /* XXX some menu buttons store button itself in but->poin. Ugly */
- if (oldbut->poin != (char *)oldbut) {
- SWAP(char *, oldbut->poin, but->poin);
- SWAP(void *, oldbut->func_argN, but->func_argN);
- }
-
- /* Move tooltip from new to old. */
- SWAP(uiButToolTipFunc, oldbut->tip_func, but->tip_func);
- SWAP(void *, oldbut->tip_argN, but->tip_argN);
-
- oldbut->flag = (oldbut->flag & ~flag_copy) | (but->flag & flag_copy);
- oldbut->drawflag = (oldbut->drawflag & ~drawflag_copy) | (but->drawflag & drawflag_copy);
-
- ui_but_extra_icons_update_from_old_but(but, oldbut);
- SWAP(ListBase, but->extra_op_icons, oldbut->extra_op_icons);
-
- if (oldbut->type == UI_BTYPE_SEARCH_MENU) {
- uiButSearch *search_oldbut = (uiButSearch *)oldbut, *search_but = (uiButSearch *)but;
-
- SWAP(uiButSearchArgFreeFn, search_oldbut->arg_free_fn, search_but->arg_free_fn);
- SWAP(void *, search_oldbut->arg, search_but->arg);
- }
-
- /* copy hardmin for list rows to prevent 'sticking' highlight to mouse position
- * when scrolling without moving mouse (see T28432) */
- if (ELEM(oldbut->type, UI_BTYPE_ROW, UI_BTYPE_LISTROW)) {
- oldbut->hardmax = but->hardmax;
- }
-
- if (oldbut->type == UI_BTYPE_PROGRESS_BAR) {
- uiButProgressbar *progress_oldbut = (uiButProgressbar *)oldbut;
- uiButProgressbar *progress_but = (uiButProgressbar *)but;
- progress_oldbut->progress = progress_but->progress;
- }
+ ui_but_update_old_active_from_new(oldbut, but);
if (!BLI_listbase_is_empty(&block->butstore)) {
UI_butstore_register_update(block, oldbut, but);
}
- /* move/copy string from the new button to the old */
- /* needed for alt+mouse wheel over enums */
- if (but->str != but->strdata) {
- if (oldbut->str != oldbut->strdata) {
- SWAP(char *, but->str, oldbut->str);
- }
- else {
- oldbut->str = but->str;
- but->str = but->strdata;
- }
- }
- else {
- if (oldbut->str != oldbut->strdata) {
- MEM_freeN(oldbut->str);
- oldbut->str = oldbut->strdata;
- }
- BLI_strncpy(oldbut->strdata, but->strdata, sizeof(oldbut->strdata));
- }
-
- if (but->dragpoin && (but->dragflag & UI_BUT_DRAGPOIN_FREE)) {
- SWAP(void *, but->dragpoin, oldbut->dragpoin);
- }
-
BLI_remlink(&block->buttons, but);
ui_but_free(C, but);
- /* note: if layout hasn't been applied yet, it uses old button pointers... */
+ found_active = true;
}
else {
const int flag_copy = UI_BUT_DRAG_MULTI;
@@ -928,9 +930,11 @@ static bool ui_but_update_from_old_block(const bContext *C,
return found_active;
}
-/* needed for temporarily rename buttons, such as in outliner or file-select,
- * they should keep calling uiDefButs to keep them alive */
-/* returns 0 when button removed */
+/**
+ * Needed for temporarily rename buttons, such as in outliner or file-select,
+ * they should keep calling #uiDefBut to keep them alive.
+ * \return false when button removed.
+ */
bool UI_but_active_only_ex(
const bContext *C, ARegion *region, uiBlock *block, uiBut *but, const bool remove_on_failure)
{
@@ -1581,6 +1585,7 @@ void ui_but_override_flag(Main *bmain, uiBut *but)
}
}
+/* -------------------------------------------------------------------- */
/** \name Button Extra Operator Icons
*
* Extra icons are shown on the right hand side of buttons. They can be clicked to invoke custom
diff --git a/source/blender/editors/interface/interface_eyedropper.c b/source/blender/editors/interface/interface_eyedropper.c
index a740a152f1c..4d0e1584156 100644
--- a/source/blender/editors/interface/interface_eyedropper.c
+++ b/source/blender/editors/interface/interface_eyedropper.c
@@ -78,7 +78,7 @@ wmKeyMap *eyedropper_colorband_modal_keymap(wmKeyConfig *keyconf)
{
static const EnumPropertyItem modal_items_point[] = {
{EYE_MODAL_POINT_CANCEL, "CANCEL", 0, "Cancel", ""},
- {EYE_MODAL_POINT_SAMPLE, "SAMPLE_SAMPLE", 0, "Sample a point", ""},
+ {EYE_MODAL_POINT_SAMPLE, "SAMPLE_SAMPLE", 0, "Sample a Point", ""},
{EYE_MODAL_POINT_CONFIRM, "SAMPLE_CONFIRM", 0, "Confirm Sampling", ""},
{EYE_MODAL_POINT_RESET, "SAMPLE_RESET", 0, "Reset Sampling", ""},
{0, NULL, 0, NULL, NULL},
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index b77f8bf3b63..ac31148340a 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -4550,10 +4550,22 @@ static int ui_do_but_TOG(bContext *C, uiBut *but, uiHandleButtonData *data, cons
button_activate_state(C, but, BUTTON_STATE_EXIT);
return WM_UI_HANDLER_BREAK;
}
- if (ELEM(event->type, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->ctrl) {
- /* Support alt+wheel on expanded enum rows */
+ if (ELEM(event->type, MOUSEPAN, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->ctrl) {
+ /* Support ctrl-wheel to cycle values on expanded enum rows. */
if (but->type == UI_BTYPE_ROW) {
- const int direction = (event->type == WHEELDOWNMOUSE) ? -1 : 1;
+ int type = event->type;
+ int val = event->val;
+
+ /* Convert pan to scroll-wheel. */
+ if (type == MOUSEPAN) {
+ ui_pan_to_scroll(event, &type, &val);
+
+ if (type == MOUSEPAN) {
+ return WM_UI_HANDLER_BREAK;
+ }
+ }
+
+ const int direction = (type == WHEELDOWNMOUSE) ? -1 : 1;
uiBut *but_select = ui_but_find_select_in_enum(but, direction);
if (but_select) {
uiBut *but_other = (direction == -1) ? but_select->next : but_select->prev;
@@ -5648,8 +5660,20 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, co
return WM_UI_HANDLER_BREAK;
}
if (ui_but_supports_cycling(but)) {
- if (ELEM(event->type, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->ctrl) {
- const int direction = (event->type == WHEELDOWNMOUSE) ? 1 : -1;
+ if (ELEM(event->type, MOUSEPAN, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->ctrl) {
+ int type = event->type;
+ int val = event->val;
+
+ /* Convert pan to scroll-wheel. */
+ if (type == MOUSEPAN) {
+ ui_pan_to_scroll(event, &type, &val);
+
+ if (type == MOUSEPAN) {
+ return WM_UI_HANDLER_BREAK;
+ }
+ }
+
+ const int direction = (type == WHEELDOWNMOUSE) ? 1 : -1;
data->value = ui_but_menu_step(but, direction);
@@ -7693,6 +7717,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
}
#ifdef USE_DRAG_MULTINUM
+ data = but->active;
if (data) {
if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE) ||
/* if we started dragging, progress on any event */
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 01eb8f95d18..1a8b1ae0a1a 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -995,8 +995,9 @@ void ui_draw_preview_item(
#define UI_TEXT_MARGIN_X 0.4f
#define UI_POPUP_MARGIN (UI_DPI_FAC * 12)
-/* margin at top of screen for popups */
-#define UI_POPUP_MENU_TOP (int)(8 * UI_DPI_FAC)
+/* Margin at top of screen for popups. Note this value must be sufficient
+ to draw a popover arrow to avoid cropping it. */
+#define UI_POPUP_MENU_TOP (int)(10 * UI_DPI_FAC)
#define UI_PIXEL_AA_JITTER 8
extern const float ui_pixel_jitter[UI_PIXEL_AA_JITTER][2];
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index ad260274e78..efb29fe75c3 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -964,7 +964,11 @@ static uiBut *ui_item_with_label(uiLayout *layout,
UI_block_layout_set_current(block, layout);
/* Only add new row if more than 1 item will be added. */
- if (name[0] || use_prop_decorate) {
+ if (name[0]
+#ifdef UI_PROP_DECORATE
+ || use_prop_decorate
+#endif
+ ) {
/* Also avoid setting 'align' if possible. Set the space to zero instead as aligning a large
* number of labels can end up aligning thousands of buttons when displaying key-map search (a
* heavy operation), see: T78636. */
@@ -972,8 +976,8 @@ static uiBut *ui_item_with_label(uiLayout *layout,
sub->space = 0;
}
-#ifdef UI_PROP_DECORATE
if (name[0]) {
+#ifdef UI_PROP_DECORATE
if (use_prop_sep) {
layout_prop_decorate = uiItemL_respect_property_split(layout, name, 0);
}
@@ -2148,7 +2152,6 @@ void uiItemFullR(uiLayout *layout,
uiLayout *layout_split = uiLayoutSplit(
layout_row ? layout_row : layout, UI_ITEM_PROP_SEP_DIVIDE, true);
bool label_added = false;
- layout_split->space = 0;
uiLayout *layout_sub = uiLayoutColumn(layout_split, true);
layout_sub->space = 0;
@@ -3186,7 +3189,6 @@ uiPropertySplitWrapper uiItemPropertySplitWrapperCreate(uiLayout *parent_layout)
uiLayout *layout_row = uiLayoutRow(parent_layout, true);
uiLayout *layout_split = uiLayoutSplit(layout_row, UI_ITEM_PROP_SEP_DIVIDE, true);
- layout_split->space = 0;
split_wrapper.label_column = uiLayoutColumn(layout_split, true);
split_wrapper.label_column->alignment = UI_LAYOUT_ALIGN_RIGHT;
split_wrapper.property_row = ui_item_prop_split_layout_hack(parent_layout, layout_split);
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index bfe5dc223c8..de281724afe 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -313,7 +313,7 @@ Panel *UI_panel_add_instanced(const bContext *C,
Panel *new_panel = panel_add_instanced(region, panels, panel_type, custom_data);
- /* Do this after #panel_add_instatnced so all subpanels are added. */
+ /* Do this after #panel_add_instatnced so all sub-panels are added. */
panel_set_expansion_from_list_data(C, new_panel);
return new_panel;
@@ -325,7 +325,7 @@ Panel *UI_panel_add_instanced(const bContext *C,
*/
void UI_list_panel_unique_str(Panel *panel, char *r_name)
{
- /* The panel sortorder will be unique for a specific panel type because the instanced
+ /* The panel sort-order will be unique for a specific panel type because the instanced
* panel list is regenerated for every change in the data order / length. */
snprintf(r_name, INSTANCED_PANEL_UNIQUE_STR_LEN, "%d", panel->sortorder);
}
@@ -805,7 +805,7 @@ static float panel_region_offset_x_get(const ARegion *region)
/**
* Starting from the "block size" set in #UI_panel_end, calculate the full size
- * of the panel including the subpanel headers and buttons.
+ * of the panel including the sub-panel headers and buttons.
*/
static void panel_calculate_size_recursive(ARegion *region, Panel *panel)
{
@@ -854,7 +854,7 @@ static void panel_calculate_size_recursive(ARegion *region, Panel *panel)
void UI_panel_end(Panel *panel, int width, int height)
{
/* Store the size of the buttons layout in the panel. The actual panel size
- * (including subpanels) is calculated in #UI_panels_end. */
+ * (including sub-panels) is calculated in #UI_panels_end. */
panel->blocksizex = width;
panel->blocksizey = height;
}
@@ -907,25 +907,22 @@ bool UI_panel_matches_search_filter(const Panel *panel)
}
/**
- * Set the flag telling the panel to use its search result status for
- * its expansion. Also activate animation if that changes the expansion.
+ * Set the flag telling the panel to use its search result status for its expansion.
*/
static void panel_set_expansion_from_seach_filter_recursive(const bContext *C,
Panel *panel,
- const bool use_search_closed,
- const bool use_animation)
+ const bool use_search_closed)
{
/* This has to run on inactive panels that may not have a type,
- * but we can prevent running on headerless panels in some cases. */
+ * but we can prevent running on header-less panels in some cases. */
if (panel->type == NULL || !(panel->type->flag & PNL_NO_HEADER)) {
SET_FLAG_FROM_TEST(panel->runtime_flag, use_search_closed, PANEL_USE_CLOSED_FROM_SEARCH);
}
LISTBASE_FOREACH (Panel *, child_panel, &panel->children) {
- /* Don't check if the subpanel is active, otherwise the
+ /* Don't check if the sub-panel is active, otherwise the
* expansion won't be reset when the parent is closed. */
- panel_set_expansion_from_seach_filter_recursive(
- C, child_panel, use_search_closed, use_animation);
+ panel_set_expansion_from_seach_filter_recursive(C, child_panel, use_search_closed);
}
}
@@ -934,11 +931,10 @@ static void panel_set_expansion_from_seach_filter_recursive(const bContext *C,
*/
static void region_panels_set_expansion_from_seach_filter(const bContext *C,
ARegion *region,
- const bool use_search_closed,
- const bool use_animation)
+ const bool use_search_closed)
{
LISTBASE_FOREACH (Panel *, panel, &region->panels) {
- panel_set_expansion_from_seach_filter_recursive(C, panel, use_search_closed, use_animation);
+ panel_set_expansion_from_seach_filter_recursive(C, panel, use_search_closed);
}
set_panels_list_data_expand_flag(C, region);
}
@@ -960,8 +956,8 @@ static void panel_remove_invisible_layouts_recursive(Panel *panel, const Panel *
}
}
else if (UI_panel_is_closed(panel)) {
- /* If subpanels have no search results but the parent panel does, then the parent panel open
- * and the subpanels will close. In that case there must be a way to hide the buttons in the
+ /* If sub-panels have no search results but the parent panel does, then the parent panel open
+ * and the sub-panels will close. In that case there must be a way to hide the buttons in the
* panel but keep the header buttons. */
LISTBASE_FOREACH (uiButtonGroup *, button_group, &block->button_groups) {
if (button_group->flag & UI_BUTTON_GROUP_PANEL_HEADER) {
@@ -1902,10 +1898,10 @@ void UI_panels_end(const bContext *C, ARegion *region, int *r_x, int *r_y)
const bool region_search_filter_active = region->flag & RGN_FLAG_SEARCH_FILTER_ACTIVE;
if (properties_space_needs_realign(area, region)) {
- region_panels_set_expansion_from_seach_filter(C, region, region_search_filter_active, false);
+ region_panels_set_expansion_from_seach_filter(C, region, region_search_filter_active);
}
else if (region->flag & RGN_FLAG_SEARCH_FILTER_UPDATE) {
- region_panels_set_expansion_from_seach_filter(C, region, region_search_filter_active, true);
+ region_panels_set_expansion_from_seach_filter(C, region, region_search_filter_active);
}
if (region->flag & RGN_FLAG_SEARCH_FILTER_ACTIVE) {
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index d4d24b3e3c2..678dbe868e7 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -3304,7 +3304,6 @@ static void colorband_buttons_layout(uiLayout *layout,
row = uiLayoutRow(split, false);
uiItemR(row, &ptr, "position", 0, IFACE_("Pos"), ICON_NONE);
bt = block->buttons.last;
- bt->a1 = 1.0f; /* gives a bit more precision for modifying position */
UI_but_func_set(bt, colorband_update_cb, bt, coba);
row = uiLayoutRow(layout, false);
@@ -3336,7 +3335,6 @@ static void colorband_buttons_layout(uiLayout *layout,
row = uiLayoutRow(subsplit, false);
uiItemR(row, &ptr, "position", UI_ITEM_R_SLIDER, IFACE_("Pos"), ICON_NONE);
bt = block->buttons.last;
- bt->a1 = 1.0f; /* gives a bit more precision for modifying position */
UI_but_func_set(bt, colorband_update_cb, bt, coba);
row = uiLayoutRow(split, false);
@@ -5330,7 +5328,7 @@ static void ui_template_palette_menu(bContext *UNUSED(C), uiLayout *layout, void
{
uiLayout *row;
- uiItemL(layout, IFACE_("Sort by:"), ICON_NONE);
+ uiItemL(layout, IFACE_("Sort By:"), ICON_NONE);
row = uiLayoutRow(layout, false);
uiItemEnumO_value(row, IFACE_("Hue"), ICON_NONE, "PALETTE_OT_sort", "type", 1);
row = uiLayoutRow(layout, false);
diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c
index 6bc644ce5b5..1abde7cf714 100644
--- a/source/blender/editors/interface/interface_utils.c
+++ b/source/blender/editors/interface/interface_utils.c
@@ -645,10 +645,10 @@ bool UI_but_online_manual_id_from_active(const struct bContext *C, char *r_str,
}
/* -------------------------------------------------------------------- */
-/* Modal Button Store API */
-
/** \name Button Store
*
+ * Modal Button Store API.
+ *
* Store for modal operators & handlers to register button pointers
* which are maintained while drawing or NULL when removed.
*
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index 49760b99d2e..e2250c764b1 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -2426,19 +2426,23 @@ static void widget_draw_text_icon(const uiFontStyle *fstyle,
}
}
else if (but->drawflag & UI_BUT_TEXT_LEFT) {
-
- /* Reduce the left padding for labels without an icon. */
- if ((but->type == UI_BTYPE_LABEL) && !(but->flag & UI_HAS_ICON) &&
- !ui_block_is_menu(but->block)) {
- text_padding /= 2;
- }
-
rect->xmin += text_padding;
}
else if (but->drawflag & UI_BUT_TEXT_RIGHT) {
rect->xmax -= text_padding;
}
}
+ else {
+ /* In case a separate text label and some other button are placed under each other,
+ and the outline of the button does not contrast with the background.
+ Add an offset (thickness of the outline) so that the text does not stick out visually. */
+ if (but->drawflag & UI_BUT_TEXT_LEFT) {
+ rect->xmin += U.pixelsize;
+ }
+ else if (but->drawflag & UI_BUT_TEXT_RIGHT) {
+ rect->xmax -= U.pixelsize;
+ }
+ }
/* Menu contains sub-menu items with triangle icon on their right. Shortcut
* strings should be drawn with some padding to the right then. */
@@ -4053,7 +4057,7 @@ static void widget_optionbut(uiWidgetColors *wcol,
}
/* smaller */
- delta = 1 + BLI_rcti_size_y(&recttemp) / 8;
+ delta = (BLI_rcti_size_y(&recttemp) - 2 * U.pixelsize) / 6;
BLI_rcti_resize(
&recttemp, BLI_rcti_size_x(&recttemp) - delta * 2, BLI_rcti_size_y(&recttemp) - delta * 2);
/* Keep one edge in place. */
@@ -4575,6 +4579,9 @@ void ui_draw_but(const bContext *C, struct ARegion *region, uiStyle *style, uiBu
wt->wcol_theme = &tui->wcol_menu_back;
wt->state = widget_state;
}
+ if (!(but->flag & UI_HAS_ICON)) {
+ but->drawflag |= UI_BUT_NO_TEXT_PADDING;
+ }
break;
case UI_BTYPE_SEPR:
diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c
index d8ebbbca023..258516a1c61 100644
--- a/source/blender/editors/interface/view2d_ops.c
+++ b/source/blender/editors/interface/view2d_ops.c
@@ -1122,8 +1122,9 @@ static void view_zoomdrag_apply(bContext *C, wmOperator *op)
dy *= -1;
}
- /* continuous zoom shouldn't move that fast... */
- if (U.viewzoom == USER_ZOOM_CONT) { /* XXX store this setting as RNA prop? */
+ /* Check if the 'timer' is initialized, as zooming with the trackpad
+ * never uses the "Continuous" zoom method, and the 'timer' is not initialized. */
+ if ((U.viewzoom == USER_ZOOM_CONT) && vzd->timer) { /* XXX store this setting as RNA prop? */
const double time = PIL_check_seconds_timer();
const float time_step = (float)(time - vzd->timer_lastdraw);
@@ -1232,6 +1233,11 @@ static int view_zoomdrag_invoke(bContext *C, wmOperator *op, const wmEvent *even
v2d = vzd->v2d;
if (U.uiflag & USER_ZOOM_TO_MOUSEPOS) {
+ ARegion *region = CTX_wm_region(C);
+
+ /* Store initial mouse position (in view space). */
+ UI_view2d_region_to_view(
+ &region->v2d, event->mval[0], event->mval[1], &vzd->mx_2d, &vzd->my_2d);
vzd->zoom_to_mouse_pos = true;
}
@@ -1278,14 +1284,6 @@ static int view_zoomdrag_invoke(bContext *C, wmOperator *op, const wmEvent *even
/* for modal exit test */
vzd->invoke_event = event->type;
- if (U.uiflag & USER_ZOOM_TO_MOUSEPOS) {
- ARegion *region = CTX_wm_region(C);
-
- /* store initial mouse position (in view space) */
- UI_view2d_region_to_view(
- &region->v2d, event->mval[0], event->mval[1], &vzd->mx_2d, &vzd->my_2d);
- }
-
if (v2d->keepofs & V2D_LOCKOFS_X) {
WM_cursor_modal_set(window, WM_CURSOR_NS_SCROLL);
}
diff --git a/source/blender/editors/io/io_alembic.c b/source/blender/editors/io/io_alembic.c
index 292d8e6066c..70125ff35fc 100644
--- a/source/blender/editors/io/io_alembic.c
+++ b/source/blender/editors/io/io_alembic.c
@@ -292,7 +292,7 @@ void WM_OT_alembic_export(wmOperatorType *ot)
FILE_SAVE,
WM_FILESEL_FILEPATH | WM_FILESEL_SHOW_PROPS,
FILE_DEFAULTDISPLAY,
- FILE_SORT_ALPHA);
+ FILE_SORT_DEFAULT);
RNA_def_int(ot->srna,
"start",
@@ -677,7 +677,7 @@ void WM_OT_alembic_import(wmOperatorType *ot)
FILE_OPENFILE,
WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH | WM_FILESEL_SHOW_PROPS,
FILE_DEFAULTDISPLAY,
- FILE_SORT_ALPHA);
+ FILE_SORT_DEFAULT);
RNA_def_float(
ot->srna,
diff --git a/source/blender/editors/io/io_cache.c b/source/blender/editors/io/io_cache.c
index 045a293f71b..b73b8abccfe 100644
--- a/source/blender/editors/io/io_cache.c
+++ b/source/blender/editors/io/io_cache.c
@@ -134,7 +134,7 @@ void CACHEFILE_OT_open(wmOperatorType *ot)
FILE_SAVE,
WM_FILESEL_FILEPATH,
FILE_DEFAULTDISPLAY,
- FILE_SORT_ALPHA);
+ FILE_SORT_DEFAULT);
}
/* ***************************** Reload Operator **************************** */
diff --git a/source/blender/editors/io/io_collada.c b/source/blender/editors/io/io_collada.c
index 54ef5e6b8c5..af505043e6a 100644
--- a/source/blender/editors/io/io_collada.c
+++ b/source/blender/editors/io/io_collada.c
@@ -507,7 +507,7 @@ void WM_OT_collada_export(wmOperatorType *ot)
FILE_SAVE,
WM_FILESEL_FILEPATH | WM_FILESEL_SHOW_PROPS,
FILE_DEFAULTDISPLAY,
- FILE_SORT_ALPHA);
+ FILE_SORT_DEFAULT);
RNA_def_enum(func,
"prop_bc_export_ui_section",
@@ -828,7 +828,7 @@ void WM_OT_collada_import(wmOperatorType *ot)
FILE_OPENFILE,
WM_FILESEL_FILEPATH | WM_FILESEL_SHOW_PROPS,
FILE_DEFAULTDISPLAY,
- FILE_SORT_ALPHA);
+ FILE_SORT_DEFAULT);
RNA_def_boolean(ot->srna,
"import_units",
diff --git a/source/blender/editors/io/io_usd.c b/source/blender/editors/io/io_usd.c
index 45ea52bdebc..0eadb38abb5 100644
--- a/source/blender/editors/io/io_usd.c
+++ b/source/blender/editors/io/io_usd.c
@@ -185,7 +185,7 @@ void WM_OT_usd_export(struct wmOperatorType *ot)
FILE_SAVE,
WM_FILESEL_FILEPATH | WM_FILESEL_SHOW_PROPS,
FILE_DEFAULTDISPLAY,
- FILE_SORT_ALPHA);
+ FILE_SORT_DEFAULT);
RNA_def_boolean(ot->srna,
"selected_objects_only",
diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c
index a90d6530453..b8badd207fe 100644
--- a/source/blender/editors/mesh/editmesh_bevel.c
+++ b/source/blender/editors/mesh/editmesh_bevel.c
@@ -127,15 +127,10 @@ enum {
static float get_bevel_offset(wmOperator *op)
{
- float val;
-
if (RNA_enum_get(op->ptr, "offset_type") == BEVEL_AMT_PERCENT) {
- val = RNA_float_get(op->ptr, "offset_pct");
- }
- else {
- val = RNA_float_get(op->ptr, "offset");
+ return RNA_float_get(op->ptr, "offset_pct");
}
- return val;
+ return RNA_float_get(op->ptr, "offset");
}
static void edbm_bevel_update_status_text(bContext *C, wmOperator *op)
@@ -145,14 +140,12 @@ static void edbm_bevel_update_status_text(bContext *C, wmOperator *op)
char *p = buf;
int available_len = sizeof(buf);
Scene *sce = CTX_data_scene(C);
- char offset_str[NUM_STR_REP_LEN];
- const char *mode_str, *omiter_str, *imiter_str, *vmesh_str, *profile_type_str, *affect_str;
- PropertyRNA *prop;
#define WM_MODALKEY(_id) \
WM_modalkeymap_operator_items_to_string_buf( \
op->type, (_id), true, UI_MAX_SHORTCUT_STR, &available_len, &p)
+ char offset_str[NUM_STR_REP_LEN];
if (RNA_enum_get(op->ptr, "offset_type") == BEVEL_AMT_PERCENT) {
BLI_snprintf(offset_str, NUM_STR_REP_LEN, "%.1f%%", RNA_float_get(op->ptr, "offset_pct"));
}
@@ -167,6 +160,8 @@ static void edbm_bevel_update_status_text(bContext *C, wmOperator *op)
true);
}
+ PropertyRNA *prop;
+ const char *mode_str, *omiter_str, *imiter_str, *vmesh_str, *profile_type_str, *affect_str;
prop = RNA_struct_find_property(op->ptr, "offset_type");
RNA_property_enum_name_gettexted(
C, op->ptr, prop, RNA_property_enum_get(op->ptr, prop), &mode_str);
@@ -240,18 +235,17 @@ static void edbm_bevel_update_status_text(bContext *C, wmOperator *op)
static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal)
{
Scene *scene = CTX_data_scene(C);
+ View3D *v3d = CTX_wm_view3d(C);
ToolSettings *ts = CTX_data_tool_settings(C);
- BevelData *opdata;
ViewLayer *view_layer = CTX_data_view_layer(C);
- float pixels_per_inch;
- int i, otype;
if (is_modal) {
RNA_float_set(op->ptr, "offset", 0.0f);
RNA_float_set(op->ptr, "offset_pct", 0.0f);
}
- op->customdata = opdata = MEM_mallocN(sizeof(BevelData), "beveldata_mesh_operator");
+ op->customdata = MEM_mallocN(sizeof(BevelData), "beveldata_mesh_operator");
+ BevelData *opdata = op->customdata;
uint objects_used_len = 0;
opdata->max_obj_scale = FLT_MIN;
@@ -261,7 +255,7 @@ static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal)
{
uint ob_store_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
- view_layer, CTX_wm_view3d(C), &ob_store_len);
+ view_layer, v3d, &ob_store_len);
opdata->ob_store = MEM_malloc_arrayN(ob_store_len, sizeof(*opdata->ob_store), __func__);
for (uint ob_index = 0; ob_index < ob_store_len; ob_index++) {
Object *obedit = objects[ob_index];
@@ -278,12 +272,12 @@ static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal)
}
opdata->is_modal = is_modal;
- otype = RNA_enum_get(op->ptr, "offset_type");
+ int otype = RNA_enum_get(op->ptr, "offset_type");
opdata->value_mode = (otype == BEVEL_AMT_PERCENT) ? OFFSET_VALUE_PERCENT : OFFSET_VALUE;
opdata->segments = (float)RNA_int_get(op->ptr, "segments");
- pixels_per_inch = U.dpi * U.pixelsize;
+ float pixels_per_inch = U.dpi * U.pixelsize;
- for (i = 0; i < NUM_VALUE_KINDS; i++) {
+ for (int i = 0; i < NUM_VALUE_KINDS; i++) {
opdata->shift_value[i] = -1.0f;
opdata->initial_length[i] = -1.0f;
/* note: scale for OFFSET_VALUE will get overwritten in edbm_bevel_invoke */
@@ -304,7 +298,6 @@ static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal)
/* avoid the cost of allocating a bm copy */
if (is_modal) {
- View3D *v3d = CTX_wm_view3d(C);
ARegion *region = CTX_wm_region(C);
for (uint ob_index = 0; ob_index < opdata->ob_store_len; ob_index++) {
@@ -491,23 +484,21 @@ static int edbm_bevel_exec(bContext *C, wmOperator *op)
static void edbm_bevel_calc_initial_length(wmOperator *op, const wmEvent *event, bool mode_changed)
{
- BevelData *opdata;
- float mlen[2], len, value, sc, st;
- int vmode;
-
- opdata = op->customdata;
- mlen[0] = opdata->mcenter[0] - event->mval[0];
- mlen[1] = opdata->mcenter[1] - event->mval[1];
- len = len_v2(mlen);
- vmode = opdata->value_mode;
+ BevelData *opdata = op->customdata;
+ const float mlen[2] = {
+ opdata->mcenter[0] - event->mval[0],
+ opdata->mcenter[1] - event->mval[1],
+ };
+ float len = len_v2(mlen);
+ int vmode = opdata->value_mode;
if (mode_changed || opdata->initial_length[vmode] == -1.0f) {
/* If current value is not default start value, adjust len so that
* the scaling and offset in edbm_bevel_mouse_set_value will
* start at current value */
- value = (vmode == SEGMENTS_VALUE) ? opdata->segments :
- RNA_float_get(op->ptr, value_rna_name[vmode]);
- sc = opdata->scale[vmode];
- st = value_start[vmode];
+ float value = (vmode == SEGMENTS_VALUE) ? opdata->segments :
+ RNA_float_get(op->ptr, value_rna_name[vmode]);
+ float sc = opdata->scale[vmode];
+ float st = value_start[vmode];
if (value != value_start[vmode]) {
len = (st + sc * (len - MVAL_PIXEL_MARGIN) - value) / sc;
}
@@ -518,18 +509,17 @@ static void edbm_bevel_calc_initial_length(wmOperator *op, const wmEvent *event,
static int edbm_bevel_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
RegionView3D *rv3d = CTX_wm_region_view3d(C);
- BevelData *opdata;
- float center_3d[3];
if (!edbm_bevel_init(C, op, true)) {
return OPERATOR_CANCELLED;
}
- opdata = op->customdata;
+ BevelData *opdata = op->customdata;
opdata->launch_event = WM_userdef_event_type_from_keymap_type(event->type);
/* initialize mouse values */
+ float center_3d[3];
if (!calculateTransformCenter(C, V3D_AROUND_CENTER_MEDIAN, center_3d, opdata->mcenter)) {
/* in this case the tool will likely do nothing,
* ideally this will never happen and should be checked for above */
@@ -561,13 +551,13 @@ static void edbm_bevel_mouse_set_value(wmOperator *op, const wmEvent *event)
{
BevelData *opdata = op->customdata;
int vmode = opdata->value_mode;
- float mdiff[2];
- float value;
- mdiff[0] = opdata->mcenter[0] - event->mval[0];
- mdiff[1] = opdata->mcenter[1] - event->mval[1];
+ const float mdiff[2] = {
+ opdata->mcenter[0] - event->mval[0],
+ opdata->mcenter[1] - event->mval[1],
+ };
- value = ((len_v2(mdiff) - MVAL_PIXEL_MARGIN) - opdata->initial_length[vmode]);
+ float value = ((len_v2(mdiff) - MVAL_PIXEL_MARGIN) - opdata->initial_length[vmode]);
/* Scale according to value mode */
value = value_start[vmode] + value * opdata->scale[vmode];
@@ -599,12 +589,10 @@ static void edbm_bevel_mouse_set_value(wmOperator *op, const wmEvent *event)
static void edbm_bevel_numinput_set_value(wmOperator *op)
{
BevelData *opdata = op->customdata;
- float value;
- int vmode;
- vmode = opdata->value_mode;
- value = (vmode == SEGMENTS_VALUE) ? opdata->segments :
- RNA_float_get(op->ptr, value_rna_name[vmode]);
+ int vmode = opdata->value_mode;
+ float value = (vmode == SEGMENTS_VALUE) ? opdata->segments :
+ RNA_float_get(op->ptr, value_rna_name[vmode]);
applyNumInput(&opdata->num_input[vmode], &value);
CLAMP(value, value_clamp_min[vmode], value_clamp_max[vmode]);
if (vmode == SEGMENTS_VALUE) {
@@ -616,82 +604,61 @@ static void edbm_bevel_numinput_set_value(wmOperator *op)
}
}
-/* Hide one of offset or offset_pct, depending on offset_type */
-static bool edbm_bevel_poll_property(const bContext *UNUSED(C),
- wmOperator *op,
- const PropertyRNA *prop)
-{
- const char *prop_id = RNA_property_identifier(prop);
-
- if (STRPREFIX(prop_id, "offset")) {
- int offset_type = RNA_enum_get(op->ptr, "offset_type");
-
- if (STREQ(prop_id, "offset") && offset_type == BEVEL_AMT_PERCENT) {
- return false;
- }
- if (STREQ(prop_id, "offset_pct") && offset_type != BEVEL_AMT_PERCENT) {
- return false;
- }
- }
-
- return true;
-}
-
wmKeyMap *bevel_modal_keymap(wmKeyConfig *keyconf)
{
static const EnumPropertyItem modal_items[] = {
{BEV_MODAL_CANCEL, "CANCEL", 0, "Cancel", "Cancel bevel"},
{BEV_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", "Confirm bevel"},
- {BEV_MODAL_VALUE_OFFSET, "VALUE_OFFSET", 0, "Change offset", "Value changes offset"},
- {BEV_MODAL_VALUE_PROFILE, "VALUE_PROFILE", 0, "Change profile", "Value changes profile"},
- {BEV_MODAL_VALUE_SEGMENTS, "VALUE_SEGMENTS", 0, "Change segments", "Value changes segments"},
- {BEV_MODAL_SEGMENTS_UP, "SEGMENTS_UP", 0, "Increase segments", "Increase segments"},
- {BEV_MODAL_SEGMENTS_DOWN, "SEGMENTS_DOWN", 0, "Decrease segments", "Decrease segments"},
+ {BEV_MODAL_VALUE_OFFSET, "VALUE_OFFSET", 0, "Change Offset", "Value changes offset"},
+ {BEV_MODAL_VALUE_PROFILE, "VALUE_PROFILE", 0, "Change Profile", "Value changes profile"},
+ {BEV_MODAL_VALUE_SEGMENTS, "VALUE_SEGMENTS", 0, "Change Segments", "Value changes segments"},
+ {BEV_MODAL_SEGMENTS_UP, "SEGMENTS_UP", 0, "Increase Segments", "Increase segments"},
+ {BEV_MODAL_SEGMENTS_DOWN, "SEGMENTS_DOWN", 0, "Decrease Segments", "Decrease segments"},
{BEV_MODAL_OFFSET_MODE_CHANGE,
"OFFSET_MODE_CHANGE",
0,
- "Change offset mode",
+ "Change Offset Mode",
"Cycle through offset modes"},
{BEV_MODAL_CLAMP_OVERLAP_TOGGLE,
"CLAMP_OVERLAP_TOGGLE",
0,
- "Toggle clamp overlap",
+ "Toggle Clamp Overlap",
"Toggle clamp overlap flag"},
{BEV_MODAL_AFFECT_CHANGE,
"AFFECT_CHANGE",
0,
- "Change affect type",
+ "Change Affect Type",
"Change which geometry type the operation affects, edges or vertices"},
{BEV_MODAL_HARDEN_NORMALS_TOGGLE,
"HARDEN_NORMALS_TOGGLE",
0,
- "Toggle harden normals",
+ "Toggle Harden Normals",
"Toggle harden normals flag"},
{BEV_MODAL_MARK_SEAM_TOGGLE,
"MARK_SEAM_TOGGLE",
0,
- "Toggle mark seam",
+ "Toggle Mark Seam",
"Toggle mark seam flag"},
{BEV_MODAL_MARK_SHARP_TOGGLE,
"MARK_SHARP_TOGGLE",
0,
- "Toggle mark sharp",
+ "Toggle Mark Sharp",
"Toggle mark sharp flag"},
{BEV_MODAL_OUTER_MITER_CHANGE,
"OUTER_MITER_CHANGE",
0,
- "Change outer miter",
+ "Change Outer Miter",
"Cycle through outer miter kinds"},
{BEV_MODAL_INNER_MITER_CHANGE,
"INNER_MITER_CHANGE",
0,
- "Change inner miter",
+ "Change Inner Miter",
"Cycle through inner miter kinds"},
{BEV_MODAL_PROFILE_TYPE_CHANGE, "PROFILE_TYPE_CHANGE", 0, "Cycle through profile types", ""},
{BEV_MODAL_VERTEX_MESH_CHANGE,
"VERTEX_MESH_CHANGE",
0,
- "Change intersection method",
+ "Change Intersection Method",
"Cycle through intersection methods"},
{0, NULL, 0, NULL, NULL},
};
@@ -1109,7 +1076,6 @@ void MESH_OT_bevel(wmOperatorType *ot)
ot->modal = edbm_bevel_modal;
ot->cancel = edbm_bevel_cancel;
ot->poll = ED_operator_editmesh;
- ot->poll_property = edbm_bevel_poll_property;
ot->ui = edbm_bevel_ui;
/* flags */
diff --git a/source/blender/editors/mesh/editmesh_intersect.c b/source/blender/editors/mesh/editmesh_intersect.c
index 528ad57b9bf..e2112f91060 100644
--- a/source/blender/editors/mesh/editmesh_intersect.c
+++ b/source/blender/editors/mesh/editmesh_intersect.c
@@ -121,11 +121,10 @@ static void edbm_intersect_select(BMEditMesh *em, struct Mesh *me, bool do_selec
}
/* -------------------------------------------------------------------- */
-/* Cut intersections into geometry */
-
/** \name Simple Intersect (self-intersect)
- * \{
- */
+ *
+ * Cut intersections into geometry.
+ * \{ */
enum {
ISECT_SEL = 0,
@@ -331,15 +330,11 @@ void MESH_OT_intersect(struct wmOperatorType *ot)
/** \} */
/* -------------------------------------------------------------------- */
-/* Boolean (a kind of intersect) */
-
/** \name Boolean Intersect
*
* \note internally this is nearly exactly the same as 'MESH_OT_intersect',
* however from a user perspective they are quite different, so expose as different tools.
- *
- * \{
- */
+ * \{ */
static int edbm_intersect_boolean_exec(bContext *C, wmOperator *op)
{
@@ -488,9 +483,7 @@ void MESH_OT_intersect_boolean(struct wmOperatorType *ot)
/** \} */
/* -------------------------------------------------------------------- */
-/* Face Split by Edges */
-
-/** \name Face/Edge Split
+/** \name Face Split by Edges
* \{ */
static void bm_face_split_by_edges(BMesh *bm,
diff --git a/source/blender/editors/mesh/editmesh_select_similar.c b/source/blender/editors/mesh/editmesh_select_similar.c
index f94d3ba5a70..00349983c57 100644
--- a/source/blender/editors/mesh/editmesh_select_similar.c
+++ b/source/blender/editors/mesh/editmesh_select_similar.c
@@ -83,7 +83,7 @@ static const EnumPropertyItem prop_similar_types[] = {
{SIMFACE_SIDES, "SIDES", 0, "Polygon Sides", ""},
{SIMFACE_PERIMETER, "PERIMETER", 0, "Perimeter", ""},
{SIMFACE_NORMAL, "NORMAL", 0, "Normal", ""},
- {SIMFACE_COPLANAR, "COPLANAR", 0, "Co-planar", ""},
+ {SIMFACE_COPLANAR, "COPLANAR", 0, "Coplanar", ""},
{SIMFACE_SMOOTH, "SMOOTH", 0, "Flat/Smooth", ""},
{SIMFACE_FACEMAP, "FACE_MAP", 0, "Face-Map", ""},
#ifdef WITH_FREESTYLE
diff --git a/source/blender/editors/mesh/editmesh_undo.c b/source/blender/editors/mesh/editmesh_undo.c
index 41d840c4a2d..43cad2db185 100644
--- a/source/blender/editors/mesh/editmesh_undo.c
+++ b/source/blender/editors/mesh/editmesh_undo.c
@@ -118,6 +118,7 @@ typedef struct UndoMesh {
#ifdef USE_ARRAY_STORE
+/* -------------------------------------------------------------------- */
/** \name Array Store
* \{ */
diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c
index ae1aae27b7f..bb8597bf02c 100644
--- a/source/blender/editors/object/object_bake.c
+++ b/source/blender/editors/object/object_bake.c
@@ -97,7 +97,6 @@ typedef struct MultiresBakerJobData {
int len;
} ob_image;
DerivedMesh *lores_dm, *hires_dm;
- bool simple;
int lvl, tot_lvl;
ListBase images;
} MultiresBakerJobData;
@@ -247,7 +246,7 @@ static DerivedMesh *multiresbake_create_loresdm(Scene *scene, Object *ob, int *l
return dm;
}
-static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *lvl, bool *simple)
+static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *lvl)
{
Mesh *me = (Mesh *)ob->data;
MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0);
@@ -264,7 +263,6 @@ static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *l
CustomData_set_only_copy(&cddm->polyData, CD_MASK_BAREMESH.pmask);
*lvl = mmd->totlvl;
- *simple = mmd->simple != 0;
tmp_mmd.lvl = mmd->totlvl;
tmp_mmd.sculptlvl = mmd->totlvl;
@@ -386,7 +384,7 @@ static int multiresbake_image_exec_locked(bContext *C, wmOperator *op)
bkr.ob_image.array = bake_object_image_get_array(ob);
bkr.ob_image.len = ob->totcol;
- bkr.hires_dm = multiresbake_create_hiresdm(scene, ob, &bkr.tot_lvl, &bkr.simple);
+ bkr.hires_dm = multiresbake_create_hiresdm(scene, ob, &bkr.tot_lvl);
bkr.lores_dm = multiresbake_create_loresdm(scene, ob, &bkr.lvl);
RE_multires_bake_images(&bkr);
@@ -441,7 +439,7 @@ static void init_multiresbake_job(bContext *C, MultiresBakeJob *bkj)
data->ob_image.len = ob->totcol;
/* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */
- data->hires_dm = multiresbake_create_hiresdm(scene, ob, &data->tot_lvl, &data->simple);
+ data->hires_dm = multiresbake_create_hiresdm(scene, ob, &data->tot_lvl);
data->lores_dm = multiresbake_create_loresdm(scene, ob, &lvl);
data->lvl = lvl;
@@ -491,7 +489,6 @@ static void multiresbake_startjob(void *bkv, short *stop, short *do_update, floa
bkr.hires_dm = data->hires_dm;
bkr.tot_lvl = data->tot_lvl;
bkr.lvl = data->lvl;
- bkr.simple = data->simple;
/* needed for proper progress bar */
bkr.tot_obj = tot_obj;
diff --git a/source/blender/editors/object/object_hook.c b/source/blender/editors/object/object_hook.c
index 5cfe02dbc59..91c9916d227 100644
--- a/source/blender/editors/object/object_hook.c
+++ b/source/blender/editors/object/object_hook.c
@@ -238,12 +238,11 @@ static void select_editlattice_hook(Object *obedit, HookModifierData *hmd)
static int return_editcurve_indexar(Object *obedit, int *r_tot, int **r_indexar, float r_cent[3])
{
ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu;
BPoint *bp;
BezTriple *bezt;
int *index, a, nr, totvert = 0;
- for (nu = editnurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
if (nu->type == CU_BEZIER) {
bezt = nu->bezt;
a = nu->pntsu;
@@ -280,7 +279,7 @@ static int return_editcurve_indexar(Object *obedit, int *r_tot, int **r_indexar,
nr = 0;
zero_v3(r_cent);
- for (nu = editnurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
if (nu->type == CU_BEZIER) {
bezt = nu->bezt;
a = nu->pntsu;
@@ -377,12 +376,11 @@ static bool object_hook_index_array(Main *bmain,
static void select_editcurve_hook(Object *obedit, HookModifierData *hmd)
{
ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu;
BPoint *bp;
BezTriple *bezt;
int index = 0, a, nr = 0;
- for (nu = editnurb->first; nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, editnurb) {
if (nu->type == CU_BEZIER) {
bezt = nu->bezt;
a = nu->pntsu;
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index 4eed9187d66..ce08c5926f2 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -31,6 +31,7 @@
#include "DNA_armature_types.h"
#include "DNA_curve_types.h"
#include "DNA_key_types.h"
+#include "DNA_lattice_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_force_types.h"
@@ -679,16 +680,15 @@ static int modifier_apply_shape(Main *bmain,
return 0;
}
- /*
- * It should be ridiculously easy to extract the original verts that we want
- * and form the shape data. We can probably use the CD KEYINDEX layer (or
- * whatever I ended up calling it, too tired to check now), though this would
- * by necessity have to make some potentially ugly assumptions about the order
- * of the mesh data :-/ you can probably assume in 99% of cases that the first
- * element of a given index is the original, and any subsequent duplicates are
- * copies/interpolates, but that's an assumption that would need to be tested
- * and then predominantly stated in comments in a half dozen headers.
- */
+ /* We could investigate using the #CD_ORIGINDEX layer
+ * to support other kinds of modifiers besides deforming modifiers.
+ * as this is done in many other places, see: #BKE_mesh_foreach_mapped_vert_coords_get.
+ *
+ * This isn't high priority in practice since most modifiers users
+ * want to apply as a shape are deforming modifiers.
+ *
+ * If a compelling use-case comes up where we want to support other kinds of modifiers
+ * we can look into supporting them. */
if (ob->type == OB_MESH) {
Mesh *mesh_applied;
@@ -721,7 +721,7 @@ static int modifier_apply_shape(Main *bmain,
BKE_id_free(NULL, mesh_applied);
}
else {
- /* TODO: implement for hair, pointclouds and volumes. */
+ /* TODO: implement for hair, point-clouds and volumes. */
BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type");
return 0;
}
@@ -798,8 +798,27 @@ static int modifier_apply_obdata(
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
}
+ else if (ob->type == OB_LATTICE) {
+ Object *object_eval = DEG_get_evaluated_object(depsgraph, ob);
+ Lattice *lattice = ob->data;
+ ModifierEvalContext mectx = {depsgraph, object_eval, 0};
+
+ if (ELEM(mti->type, eModifierTypeType_Constructive, eModifierTypeType_Nonconstructive)) {
+ BKE_report(reports, RPT_ERROR, "Constructive modifiers cannot be applied");
+ return 0;
+ }
+
+ int numVerts;
+ float(*vertexCos)[3] = BKE_lattice_vert_coords_alloc(lattice, &numVerts);
+ mti->deformVerts(md_eval, &mectx, NULL, vertexCos, numVerts);
+ BKE_lattice_vert_coords_apply(lattice, vertexCos);
+
+ MEM_freeN(vertexCos);
+
+ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
+ }
else {
- /* TODO: implement for hair, pointclouds and volumes. */
+ /* TODO: implement for hair, point-clouds and volumes. */
BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type");
return 0;
}
@@ -1478,8 +1497,8 @@ static char *modifier_apply_as_shapekey_get_description(struct bContext *UNUSED(
void OBJECT_OT_modifier_apply_as_shapekey(wmOperatorType *ot)
{
- ot->name = "Apply Modifier As Shapekey";
- ot->description = "Apply modifier as a new shapekey and remove from the stack";
+ ot->name = "Apply Modifier as Shape Key";
+ ot->description = "Apply modifier as a new shape key and remove from the stack";
ot->idname = "OBJECT_OT_modifier_apply_as_shapekey";
ot->invoke = modifier_apply_as_shapekey_invoke;
@@ -1887,7 +1906,7 @@ void OBJECT_OT_multires_external_save(wmOperatorType *ot)
FILE_SAVE,
WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH,
FILE_DEFAULTDISPLAY,
- FILE_SORT_ALPHA);
+ FILE_SORT_DEFAULT);
edit_modifier_properties(ot);
}
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index de3e5f3d5f9..46624a76999 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -696,7 +696,7 @@ bool ED_object_parent_set(ReportList *reports,
/* Preconditions. */
if (ob == par) {
/* Parenting an object to itself is impossible. */
- return true;
+ return false;
}
if (BKE_object_parent_loop_check(par, ob)) {
@@ -981,6 +981,12 @@ struct ParentingContext {
static bool parent_set_nonvertex_parent(bContext *C, struct ParentingContext *parenting_context)
{
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) {
+ if (ob == parenting_context->par) {
+ /* ED_object_parent_set() will fail (and thus return false), but this case shouldn't break
+ * this loop. It's expected that the active object is also selected. */
+ continue;
+ }
+
if (!ED_object_parent_set(parenting_context->reports,
C,
parenting_context->scene,
@@ -1005,6 +1011,12 @@ static bool parent_set_vertex_parent_with_kdtree(bContext *C,
int vert_par[3] = {0, 0, 0};
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) {
+ if (ob == parenting_context->par) {
+ /* ED_object_parent_set() will fail (and thus return false), but this case shouldn't break
+ * this loop. It's expected that the active object is also selected. */
+ continue;
+ }
+
parent_set_vert_find(tree, ob, vert_par, parenting_context->is_vertex_tri);
if (!ED_object_parent_set(parenting_context->reports,
C,
@@ -1359,7 +1371,7 @@ enum {
static const EnumPropertyItem prop_make_track_types[] = {
{CREATE_TRACK_DAMPTRACK, "DAMPTRACK", 0, "Damped Track Constraint", ""},
- {CREATE_TRACK_TRACKTO, "TRACKTO", 0, "Track To Constraint", ""},
+ {CREATE_TRACK_TRACKTO, "TRACKTO", 0, "Track to Constraint", ""},
{CREATE_TRACK_LOCKTRACK, "LOCKTRACK", 0, "Lock Track Constraint", ""},
{0, NULL, 0, NULL, NULL},
};
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
index e92b3323441..b48b854c238 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -2664,12 +2664,23 @@ static void vgroup_assign_verts(Object *ob, const float weight)
static bool vertex_group_supported_poll_ex(bContext *C, const Object *ob)
{
if (!ED_operator_object_active_local_editable_ex(C, ob)) {
+ CTX_wm_operator_poll_msg_set(C, "No active editable object");
return false;
}
+
+ if (!OB_TYPE_SUPPORT_VGROUP(ob->type)) {
+ CTX_wm_operator_poll_msg_set(C, "Object type does not support vertex groups");
+ return false;
+ }
+
+ /* Data checks. */
const ID *data = ob->data;
- return (OB_TYPE_SUPPORT_VGROUP(ob->type) &&
- /* Data checks. */
- (data != NULL) && !ID_IS_LINKED(data) && !ID_IS_OVERRIDE_LIBRARY(data));
+ if (data == NULL || ID_IS_LINKED(data) || ID_IS_OVERRIDE_LIBRARY(data)) {
+ CTX_wm_operator_poll_msg_set(C, "Object type \"%s\" does not have editable data");
+ return false;
+ }
+
+ return true;
}
static bool vertex_group_supported_poll(bContext *C)
@@ -2678,48 +2689,61 @@ static bool vertex_group_supported_poll(bContext *C)
return vertex_group_supported_poll_ex(C, ob);
}
-static bool vertex_group_poll(bContext *C)
+static bool vertex_group_poll_ex(bContext *C, Object *ob)
{
- Object *ob = ED_object_context(C);
+ if (!vertex_group_supported_poll_ex(C, ob)) {
+ return false;
+ }
+
+ if (BLI_listbase_is_empty(&ob->defbase)) {
+ CTX_wm_operator_poll_msg_set(C, "Object has no vertex groups");
+ return false;
+ }
- return (vertex_group_supported_poll(C) && ob->defbase.first);
+ return true;
}
-static bool vertex_group_mesh_poll(bContext *C)
+static bool vertex_group_poll(bContext *C)
{
Object *ob = ED_object_context(C);
-
- return (vertex_group_poll(C) && ob->type == OB_MESH);
+ return vertex_group_poll_ex(C, ob);
}
-static bool vertex_group_mesh_with_dvert_poll(bContext *C)
+static bool vertex_group_mesh_poll_ex(bContext *C, Object *ob)
{
- Object *ob = ED_object_context(C);
-
- if (!vertex_group_mesh_poll(C)) {
+ if (!vertex_group_poll_ex(C, ob)) {
return false;
}
- Mesh *me = ob->data;
- if (me->dvert == NULL) {
+ if (ob->type != OB_MESH) {
+ CTX_wm_operator_poll_msg_set(C, "Only mesh objects are supported");
return false;
}
return true;
}
-static bool UNUSED_FUNCTION(vertex_group_mesh_supported_poll)(bContext *C)
+static bool vertex_group_mesh_with_dvert_poll(bContext *C)
{
Object *ob = ED_object_context(C);
+ if (!vertex_group_mesh_poll_ex(C, ob)) {
+ return false;
+ }
+
+ Mesh *me = ob->data;
+ if (me->dvert == NULL) {
+ CTX_wm_operator_poll_msg_set(C, "The active mesh object has no vertex group data");
+ return false;
+ }
- return (vertex_group_supported_poll(C) && ob->type == OB_MESH);
+ return true;
}
static bool UNUSED_FUNCTION(vertex_group_poll_edit)(bContext *C)
{
Object *ob = ED_object_context(C);
- if (!vertex_group_supported_poll(C)) {
+ if (!vertex_group_supported_poll_ex(C, ob)) {
return false;
}
@@ -2733,7 +2757,7 @@ static bool vertex_group_vert_poll_ex(bContext *C,
{
Object *ob = ED_object_context(C);
- if (!vertex_group_supported_poll(C)) {
+ if (!vertex_group_supported_poll_ex(C, ob)) {
return false;
}
@@ -2786,7 +2810,7 @@ static bool vertex_group_vert_select_unlocked_poll(bContext *C)
{
Object *ob = ED_object_context(C);
- if (!vertex_group_supported_poll(C)) {
+ if (!vertex_group_supported_poll_ex(C, ob)) {
return false;
}
@@ -2807,7 +2831,7 @@ static bool vertex_group_vert_select_mesh_poll(bContext *C)
{
Object *ob = ED_object_context(C);
- if (!vertex_group_supported_poll(C)) {
+ if (!vertex_group_supported_poll_ex(C, ob)) {
return false;
}
diff --git a/source/blender/editors/object/object_volume.c b/source/blender/editors/object/object_volume.c
index c5dc7f9f24d..5aa61139468 100644
--- a/source/blender/editors/object/object_volume.c
+++ b/source/blender/editors/object/object_volume.c
@@ -184,7 +184,7 @@ void OBJECT_OT_volume_import(wmOperatorType *ot)
WM_FILESEL_FILEPATH | WM_FILESEL_DIRECTORY | WM_FILESEL_FILES |
WM_FILESEL_RELPATH,
FILE_DEFAULTDISPLAY,
- FILE_SORT_ALPHA);
+ FILE_SORT_DEFAULT);
RNA_def_boolean(
ot->srna,
diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c
index 56bdc5c21f4..017cd63d9d5 100644
--- a/source/blender/editors/physics/particle_object.c
+++ b/source/blender/editors/physics/particle_object.c
@@ -691,7 +691,7 @@ void PARTICLE_OT_disconnect_hair(wmOperatorType *ot)
ot->flag = OPTYPE_UNDO;
RNA_def_boolean(
- ot->srna, "all", 0, "All hair", "Disconnect all hair systems from the emitter mesh");
+ ot->srna, "all", 0, "All Hair", "Disconnect all hair systems from the emitter mesh");
}
/* from/to_world_space : whether from/to particles are in world or hair space
@@ -981,7 +981,7 @@ void PARTICLE_OT_connect_hair(wmOperatorType *ot)
/* No REGISTER, redo does not work due to missing update, see T47750. */
ot->flag = OPTYPE_UNDO;
- RNA_def_boolean(ot->srna, "all", 0, "All hair", "Connect all hair systems to the emitter mesh");
+ RNA_def_boolean(ot->srna, "all", 0, "All Hair", "Connect all hair systems to the emitter mesh");
}
/************************ particle system copy operator *********************/
diff --git a/source/blender/editors/physics/rigidbody_world.c b/source/blender/editors/physics/rigidbody_world.c
index 42f270874e3..f2e2d7589df 100644
--- a/source/blender/editors/physics/rigidbody_world.c
+++ b/source/blender/editors/physics/rigidbody_world.c
@@ -210,5 +210,5 @@ void RIGIDBODY_OT_world_export(wmOperatorType *ot)
FILE_SAVE,
FILE_RELPATH,
FILE_DEFAULTDISPLAY,
- FILE_SORT_ALPHA);
+ FILE_SORT_DEFAULT);
}
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index 7ca711cd2b8..3dbf70aa4bc 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -57,7 +57,6 @@
#include "BKE_report.h"
#include "BKE_scene.h"
#include "BKE_screen.h"
-#include "BKE_sequencer.h"
#include "BKE_undo_system.h"
#include "DEG_depsgraph.h"
@@ -83,6 +82,8 @@
#include "RNA_access.h"
#include "RNA_define.h"
+#include "SEQ_sequencer.h"
+
#include "BLO_undofile.h"
#include "render_intern.h"
@@ -435,20 +436,6 @@ static void make_renderinfo_string(const RenderStats *rs,
}
}
else {
- if (rs->totvert || rs->totface || rs->totlamp) {
- spos += sprintf(spos, "| ");
- }
-
- if (rs->totvert) {
- spos += sprintf(spos, TIP_("Ve:%d "), rs->totvert);
- }
- if (rs->totface) {
- spos += sprintf(spos, TIP_("Fa:%d "), rs->totface);
- }
- if (rs->totlamp) {
- spos += sprintf(spos, TIP_("Li:%d "), rs->totlamp);
- }
-
if (rs->mem_peak == 0.0f) {
spos += sprintf(spos, TIP_("| Mem:%.2fM (Peak %.2fM) "), megs_used_memory, megs_peak_memory);
}
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index 8d410e36ca6..5d355ada77c 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -54,7 +54,6 @@
#include "BKE_main.h"
#include "BKE_report.h"
#include "BKE_scene.h"
-#include "BKE_sequencer.h"
#include "BKE_writeavi.h"
#include "DEG_depsgraph.h"
@@ -78,6 +77,8 @@
#include "RNA_access.h"
#include "RNA_define.h"
+#include "SEQ_sequencer.h"
+
#include "GPU_framebuffer.h"
#include "GPU_matrix.h"
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index f5962f36412..cffcb1cb4dc 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -1871,6 +1871,11 @@ void ED_area_update_region_sizes(wmWindowManager *wm, wmWindow *win, ScrArea *ar
area->flag &= ~AREA_FLAG_REGION_SIZE_UPDATE;
}
+bool ED_area_has_shared_border(struct ScrArea *a, struct ScrArea *b)
+{
+ return area_getorientation(a, b) != -1;
+}
+
/* called in screen_refresh, or screens_init, also area size changes */
void ED_area_init(wmWindowManager *wm, wmWindow *win, ScrArea *area)
{
diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c
index 3924c334541..af09100b8e6 100644
--- a/source/blender/editors/screen/screen_context.c
+++ b/source/blender/editors/screen/screen_context.c
@@ -48,7 +48,6 @@
#include "BKE_gpencil.h"
#include "BKE_layer.h"
#include "BKE_object.h"
-#include "BKE_sequencer.h"
#include "RNA_access.h"
@@ -56,6 +55,8 @@
#include "ED_armature.h"
#include "ED_gpencil.h"
+#include "SEQ_sequencer.h"
+
#include "UI_interface.h"
#include "WM_api.h"
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 27a1d4e4a50..6f80165ed3c 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -5523,8 +5523,8 @@ static void keymap_modal_set(wmKeyConfig *keyconf)
static const EnumPropertyItem modal_items[] = {
{KM_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""},
{KM_MODAL_APPLY, "APPLY", 0, "Apply", ""},
- {KM_MODAL_SNAP_ON, "SNAP", 0, "Snap on", ""},
- {KM_MODAL_SNAP_OFF, "SNAP_OFF", 0, "Snap off", ""},
+ {KM_MODAL_SNAP_ON, "SNAP", 0, "Snap On", ""},
+ {KM_MODAL_SNAP_OFF, "SNAP_OFF", 0, "Snap Off", ""},
{0, NULL, 0, NULL, NULL},
};
diff --git a/source/blender/editors/screen/screendump.c b/source/blender/editors/screen/screendump.c
index 5d0ae292ffa..7d7a3340dc3 100644
--- a/source/blender/editors/screen/screendump.c
+++ b/source/blender/editors/screen/screendump.c
@@ -249,7 +249,7 @@ void SCREEN_OT_screenshot(wmOperatorType *ot)
FILE_SAVE,
WM_FILESEL_FILEPATH,
FILE_DEFAULTDISPLAY,
- FILE_SORT_ALPHA);
+ FILE_SORT_DEFAULT);
RNA_def_boolean(ot->srna,
"full",
1,
diff --git a/source/blender/editors/screen/workspace_edit.c b/source/blender/editors/screen/workspace_edit.c
index cab2d32bdcf..5430137f5ca 100644
--- a/source/blender/editors/screen/workspace_edit.c
+++ b/source/blender/editors/screen/workspace_edit.c
@@ -57,6 +57,7 @@
#include "screen_intern.h"
+/* -------------------------------------------------------------------- */
/** \name Workspace API
*
* \brief API for managing workspaces and their data.
@@ -231,6 +232,7 @@ void ED_workspace_scene_data_sync(WorkSpaceInstanceHook *hook, Scene *scene)
/** \} Workspace API */
+/* -------------------------------------------------------------------- */
/** \name Workspace Operators
*
* \{ */
diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c
index f0285c8faf3..550913fc8af 100644
--- a/source/blender/editors/sculpt_paint/paint_cursor.c
+++ b/source/blender/editors/sculpt_paint/paint_cursor.c
@@ -1310,6 +1310,11 @@ static bool paint_cursor_context_init(bContext *C,
Object *active_object = pcontext->vc.obact;
pcontext->ss = active_object ? active_object->sculpt : NULL;
+ if (pcontext->ss && pcontext->ss->draw_faded_cursor) {
+ pcontext->outline_alpha = 0.3f;
+ copy_v3_fl(pcontext->outline_col, 0.8f);
+ }
+
pcontext->is_stroke_active = pcontext->ups->stroke_active;
return true;
diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c
index cc0d20089b4..26abd19d5e8 100644
--- a/source/blender/editors/sculpt_paint/paint_mask.c
+++ b/source/blender/editors/sculpt_paint/paint_mask.c
@@ -246,8 +246,16 @@ typedef struct LassoGestureData {
} LassoGestureData;
typedef struct LineGestureData {
+ /* Plane aligned to the gesture line. */
float true_plane[4];
float plane[4];
+
+ /* Planes to limit the action to the length of the gesture segment at both sides of the affected
+ * area. */
+ float side_plane[2][4];
+ float true_side_plane[2][4];
+ bool use_side_planes;
+
bool flip;
} LineGestureData;
@@ -320,6 +328,13 @@ static void sculpt_gesture_operator_properties(wmOperatorType *ot)
false,
"Front Faces Only",
"Affect only faces facing towards the view");
+
+ RNA_def_boolean(ot->srna,
+ "use_limit_to_segment",
+ false,
+ "Limit to Segment",
+ "Apply the gesture action only to the area that is contained within the "
+ "segement without extending its effect to the entire line");
}
static void sculpt_gesture_context_init_common(bContext *C,
@@ -332,6 +347,7 @@ static void sculpt_gesture_context_init_common(bContext *C,
/* Operator properties. */
sgcontext->front_faces_only = RNA_boolean_get(op->ptr, "use_front_faces_only");
+ sgcontext->line.use_side_planes = RNA_boolean_get(op->ptr, "use_limit_to_segment");
/* SculptSession */
sgcontext->ss = ob->sculpt;
@@ -448,6 +464,50 @@ static SculptGestureContext *sculpt_gesture_init_from_box(bContext *C, wmOperato
return sgcontext;
}
+static void sculpt_gesture_line_plane_from_tri(float *r_plane,
+ SculptGestureContext *sgcontext,
+ const bool flip,
+ const float p1[3],
+ const float p2[3],
+ const float p3[3])
+{
+ float normal[3];
+ normal_tri_v3(normal, p1, p2, p3);
+ mul_v3_mat3_m4v3(normal, sgcontext->vc.obact->imat, normal);
+ if (flip) {
+ mul_v3_fl(normal, -1.0f);
+ }
+ float plane_point_object_space[3];
+ mul_v3_m4v3(plane_point_object_space, sgcontext->vc.obact->imat, p1);
+ plane_from_point_normal_v3(r_plane, plane_point_object_space, normal);
+}
+
+/* Creates 4 points in the plane defined by the line and 2 extra points with an offset relative to
+ * this plane. */
+static void sculpt_gesture_line_calculate_plane_points(SculptGestureContext *sgcontext,
+ float line_points[2][2],
+ float r_plane_points[4][3],
+ float r_offset_plane_points[2][3])
+{
+ float depth_point[3];
+ add_v3_v3v3(depth_point, sgcontext->true_view_origin, sgcontext->true_view_normal);
+ ED_view3d_win_to_3d(
+ sgcontext->vc.v3d, sgcontext->vc.region, depth_point, line_points[0], r_plane_points[0]);
+ ED_view3d_win_to_3d(
+ sgcontext->vc.v3d, sgcontext->vc.region, depth_point, line_points[1], r_plane_points[3]);
+
+ madd_v3_v3v3fl(depth_point, sgcontext->true_view_origin, sgcontext->true_view_normal, 10.0f);
+ ED_view3d_win_to_3d(
+ sgcontext->vc.v3d, sgcontext->vc.region, depth_point, line_points[0], r_plane_points[1]);
+ ED_view3d_win_to_3d(
+ sgcontext->vc.v3d, sgcontext->vc.region, depth_point, line_points[1], r_plane_points[2]);
+
+ float normal[3];
+ normal_tri_v3(normal, r_plane_points[0], r_plane_points[1], r_plane_points[2]);
+ add_v3_v3v3(r_offset_plane_points[0], r_plane_points[0], normal);
+ add_v3_v3v3(r_offset_plane_points[1], r_plane_points[3], normal);
+}
+
static SculptGestureContext *sculpt_gesture_init_from_line(bContext *C, wmOperator *op)
{
SculptGestureContext *sgcontext = MEM_callocN(sizeof(SculptGestureContext),
@@ -464,36 +524,33 @@ static SculptGestureContext *sculpt_gesture_init_from_line(bContext *C, wmOperat
sgcontext->line.flip = RNA_boolean_get(op->ptr, "flip");
- float depth_point[3];
- float plane_points[3][3];
-
- /* Calculate a triangle in the line's plane. */
- add_v3_v3v3(depth_point, sgcontext->true_view_origin, sgcontext->true_view_normal);
- ED_view3d_win_to_3d(
- sgcontext->vc.v3d, sgcontext->vc.region, depth_point, line_points[0], plane_points[0]);
-
- madd_v3_v3v3fl(depth_point, sgcontext->true_view_origin, sgcontext->true_view_normal, 10.0f);
- ED_view3d_win_to_3d(
- sgcontext->vc.v3d, sgcontext->vc.region, depth_point, line_points[0], plane_points[1]);
- ED_view3d_win_to_3d(
- sgcontext->vc.v3d, sgcontext->vc.region, depth_point, line_points[1], plane_points[2]);
-
- /* Calculate final line plane and normal using the triangle. */
- float normal[3];
- normal_tri_v3(normal, plane_points[0], plane_points[1], plane_points[2]);
- if (!sgcontext->vc.rv3d->is_persp) {
- mul_v3_fl(normal, -1.0f);
- }
-
- /* Apply flip. */
- if (sgcontext->line.flip) {
- mul_v3_fl(normal, -1.0f);
- }
-
- mul_v3_mat3_m4v3(normal, sgcontext->vc.obact->imat, normal);
- float plane_point_object_space[3];
- mul_v3_m4v3(plane_point_object_space, sgcontext->vc.obact->imat, plane_points[0]);
- plane_from_point_normal_v3(sgcontext->line.true_plane, plane_point_object_space, normal);
+ float plane_points[4][3];
+ float offset_plane_points[2][3];
+ sculpt_gesture_line_calculate_plane_points(
+ sgcontext, line_points, plane_points, offset_plane_points);
+
+ /* Calculate line plane and normal. */
+ const bool flip = sgcontext->line.flip ^ !sgcontext->vc.rv3d->is_persp;
+ sculpt_gesture_line_plane_from_tri(sgcontext->line.true_plane,
+ sgcontext,
+ flip,
+ plane_points[0],
+ plane_points[1],
+ plane_points[2]);
+
+ /* Calculate the side planes. */
+ sculpt_gesture_line_plane_from_tri(sgcontext->line.true_side_plane[0],
+ sgcontext,
+ false,
+ plane_points[1],
+ plane_points[0],
+ offset_plane_points[0]);
+ sculpt_gesture_line_plane_from_tri(sgcontext->line.true_side_plane[1],
+ sgcontext,
+ false,
+ plane_points[3],
+ plane_points[2],
+ offset_plane_points[1]);
return sgcontext;
}
@@ -544,14 +601,20 @@ static void sculpt_gesture_flip_for_symmetry_pass(SculptGestureContext *sgcontex
flip_v3_v3(sgcontext->view_normal, sgcontext->true_view_normal, symmpass);
flip_v3_v3(sgcontext->view_origin, sgcontext->true_view_origin, symmpass);
flip_plane(sgcontext->line.plane, sgcontext->line.true_plane, symmpass);
+ flip_plane(sgcontext->line.side_plane[0], sgcontext->line.true_side_plane[0], symmpass);
+ flip_plane(sgcontext->line.side_plane[1], sgcontext->line.true_side_plane[1], symmpass);
}
static void sculpt_gesture_update_effected_nodes_by_line_plane(SculptGestureContext *sgcontext)
{
SculptSession *ss = sgcontext->ss;
- float clip_planes[1][4];
+ float clip_planes[3][4];
copy_v4_v4(clip_planes[0], sgcontext->line.plane);
- PBVHFrustumPlanes frustum = {.planes = clip_planes, .num_planes = 1};
+ copy_v4_v4(clip_planes[1], sgcontext->line.side_plane[0]);
+ copy_v4_v4(clip_planes[2], sgcontext->line.side_plane[1]);
+
+ const int num_planes = sgcontext->line.use_side_planes ? 3 : 1;
+ PBVHFrustumPlanes frustum = {.planes = clip_planes, .num_planes = num_planes};
BKE_pbvh_search_gather(ss->pbvh,
BKE_pbvh_node_frustum_contain_AABB,
&frustum,
@@ -630,6 +693,11 @@ static bool sculpt_gesture_is_vertex_effected(SculptGestureContext *sgcontext, P
case SCULPT_GESTURE_SHAPE_LASSO:
return sculpt_gesture_is_effected_lasso(sgcontext, vd->co);
case SCULPT_GESTURE_SHAPE_LINE:
+ if (sgcontext->line.use_side_planes) {
+ return plane_point_side_v3(sgcontext->line.plane, vd->co) > 0.0f &&
+ plane_point_side_v3(sgcontext->line.side_plane[0], vd->co) > 0.0f &&
+ plane_point_side_v3(sgcontext->line.side_plane[1], vd->co) > 0.0f;
+ }
return plane_point_side_v3(sgcontext->line.plane, vd->co) > 0.0f;
}
return false;
@@ -862,6 +930,24 @@ static EnumPropertyItem prop_trim_operation_types[] = {
{0, NULL, 0, NULL, NULL},
};
+typedef enum eSculptTrimOrientationType {
+ SCULPT_GESTURE_TRIM_ORIENTATION_VIEW,
+ SCULPT_GESTURE_TRIM_ORIENTATION_SURFACE,
+} eSculptTrimOrientationType;
+static EnumPropertyItem prop_trim_orientation_types[] = {
+ {SCULPT_GESTURE_TRIM_ORIENTATION_VIEW,
+ "VIEW",
+ 0,
+ "View",
+ "Use the view to orientate the trimming shape"},
+ {SCULPT_GESTURE_TRIM_ORIENTATION_SURFACE,
+ "SURFACE",
+ 0,
+ "Surface",
+ "Use the surface normal to orientate the trimming shape"},
+ {0, NULL, 0, NULL, NULL},
+};
+
typedef struct SculptGestureTrimOperation {
SculptGestureOperation op;
@@ -874,6 +960,7 @@ typedef struct SculptGestureTrimOperation {
bool use_cursor_depth;
eSculptTrimOperationType mode;
+ eSculptTrimOrientationType orientation;
} SculptGestureTrimOperation;
static void sculpt_gesture_trim_normals_update(SculptGestureContext *sgcontext)
@@ -910,6 +997,29 @@ static void sculpt_gesture_trim_normals_update(SculptGestureContext *sgcontext)
trim_operation->mesh = result;
}
+/* Get the origin and normal that are going to be used for calculating the depth and position the
+ * trimming geometry. */
+static void sculpt_gesture_trim_shape_origin_normal_get(SculptGestureContext *sgcontext,
+ float *r_origin,
+ float *r_normal)
+{
+ SculptGestureTrimOperation *trim_operation = (SculptGestureTrimOperation *)sgcontext->operation;
+ /* Use the view origin and normal in world space. The trimming mesh coordinates are
+ * calculated in world space, aligned to the view, and then converted to object space to
+ * store them in the final trimming mesh which is going to be used in the boolean operation.
+ */
+ switch (trim_operation->orientation) {
+ case SCULPT_GESTURE_TRIM_ORIENTATION_VIEW:
+ copy_v3_v3(r_origin, sgcontext->world_space_view_origin);
+ copy_v3_v3(r_normal, sgcontext->world_space_view_normal);
+ break;
+ case SCULPT_GESTURE_TRIM_ORIENTATION_SURFACE:
+ mul_v3_m4v3(r_origin, sgcontext->vc.obact->obmat, sgcontext->ss->gesture_initial_location);
+ mul_v3_m4v3(r_normal, sgcontext->vc.obact->obmat, sgcontext->ss->gesture_initial_normal);
+ break;
+ }
+}
+
static void sculpt_gesture_trim_calculate_depth(bContext *C, SculptGestureContext *sgcontext)
{
SculptGestureTrimOperation *trim_operation = (SculptGestureTrimOperation *)sgcontext->operation;
@@ -919,11 +1029,11 @@ static void sculpt_gesture_trim_calculate_depth(bContext *C, SculptGestureContex
const int totvert = SCULPT_vertex_count_get(ss);
- float view_plane[4];
- const float *view_origin = sgcontext->world_space_view_origin;
- const float *view_normal = sgcontext->world_space_view_normal;
-
- plane_from_point_normal_v3(view_plane, view_origin, view_normal);
+ float shape_plane[4];
+ float shape_origin[3];
+ float shape_normal[3];
+ sculpt_gesture_trim_shape_origin_normal_get(sgcontext, shape_origin, shape_normal);
+ plane_from_point_normal_v3(shape_plane, shape_origin, shape_normal);
trim_operation->depth_front = FLT_MAX;
trim_operation->depth_back = -FLT_MAX;
@@ -935,7 +1045,7 @@ static void sculpt_gesture_trim_calculate_depth(bContext *C, SculptGestureContex
* store them. */
float world_space_vco[3];
mul_v3_m4v3(world_space_vco, vc->obact->obmat, vco);
- const float dist = dist_signed_to_plane_v3(world_space_vco, view_plane);
+ const float dist = dist_signed_to_plane_v3(world_space_vco, shape_plane);
trim_operation->depth_front = min_ff(dist, trim_operation->depth_front);
trim_operation->depth_back = max_ff(dist, trim_operation->depth_back);
}
@@ -944,11 +1054,22 @@ static void sculpt_gesture_trim_calculate_depth(bContext *C, SculptGestureContex
float world_space_gesture_initial_location[3];
mul_v3_m4v3(
world_space_gesture_initial_location, vc->obact->obmat, ss->gesture_initial_location);
- const float mid_point_depth = ss->gesture_initial_hit ?
- dist_signed_to_plane_v3(world_space_gesture_initial_location,
- view_plane) :
- (trim_operation->depth_back + trim_operation->depth_front) *
- 0.5f;
+
+ float mid_point_depth;
+ if (trim_operation->orientation == SCULPT_GESTURE_TRIM_ORIENTATION_VIEW) {
+ mid_point_depth = ss->gesture_initial_hit ?
+ dist_signed_to_plane_v3(world_space_gesture_initial_location,
+ shape_plane) :
+ (trim_operation->depth_back + trim_operation->depth_front) * 0.5f;
+ }
+ else {
+ /* When using normal orientation, if the stroke started over the mesh, position the mid point
+ * at 0 distance from the shape plane. This positions the trimming shape half inside of the
+ * surface. */
+ mid_point_depth = ss->gesture_initial_hit ?
+ 0.0f :
+ (trim_operation->depth_back + trim_operation->depth_front) * 0.5f;
+ }
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
Brush *brush = BKE_paint_brush(&sd->paint);
@@ -986,30 +1107,41 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex
depth_back += 0.1f;
}
- /* Use the view origin and normal in world space. The trimming mesh coordinates are calculated in
- * world space, aligned to the view, and then converted to object space to store them in the
- * final trimming mesh which is going to be used in the boolean operation.
- */
- const float *view_origin = sgcontext->world_space_view_origin;
- const float *view_normal = sgcontext->world_space_view_normal;
+ float shape_origin[3];
+ float shape_normal[3];
+ float shape_plane[4];
+ sculpt_gesture_trim_shape_origin_normal_get(sgcontext, shape_origin, shape_normal);
+ plane_from_point_normal_v3(shape_plane, shape_origin, shape_normal);
const float(*ob_imat)[4] = vc->obact->imat;
/* Write vertices coordinates for the front face. */
float depth_point[3];
- madd_v3_v3v3fl(depth_point, view_origin, view_normal, depth_front);
+ madd_v3_v3v3fl(depth_point, shape_origin, shape_normal, depth_front);
for (int i = 0; i < tot_screen_points; i++) {
float new_point[3];
- ED_view3d_win_to_3d(vc->v3d, region, depth_point, screen_points[i], new_point);
+ if (trim_operation->orientation == SCULPT_GESTURE_TRIM_ORIENTATION_VIEW) {
+ ED_view3d_win_to_3d(vc->v3d, region, depth_point, screen_points[i], new_point);
+ }
+ else {
+ ED_view3d_win_to_3d_on_plane(region, shape_plane, screen_points[i], false, new_point);
+ madd_v3_v3fl(new_point, shape_normal, depth_front);
+ }
mul_v3_m4v3(trim_operation->mesh->mvert[i].co, ob_imat, new_point);
mul_v3_m4v3(trim_operation->true_mesh_co[i], ob_imat, new_point);
}
/* Write vertices coordinates for the back face. */
- madd_v3_v3v3fl(depth_point, view_origin, view_normal, depth_back);
+ madd_v3_v3v3fl(depth_point, shape_origin, shape_normal, depth_back);
for (int i = 0; i < tot_screen_points; i++) {
float new_point[3];
- ED_view3d_win_to_3d(vc->v3d, region, depth_point, screen_points[i], new_point);
+ if (trim_operation->orientation == SCULPT_GESTURE_TRIM_ORIENTATION_VIEW) {
+ ED_view3d_win_to_3d(vc->v3d, region, depth_point, screen_points[i], new_point);
+ }
+ else {
+ ED_view3d_win_to_3d_on_plane(region, shape_plane, screen_points[i], false, new_point);
+ madd_v3_v3fl(new_point, shape_normal, depth_back);
+ }
mul_v3_m4v3(trim_operation->mesh->mvert[i + tot_screen_points].co, ob_imat, new_point);
mul_v3_m4v3(trim_operation->true_mesh_co[i + tot_screen_points], ob_imat, new_point);
}
@@ -1224,6 +1356,12 @@ static void sculpt_gesture_init_trim_properties(SculptGestureContext *sgcontext,
trim_operation->mode = RNA_enum_get(op->ptr, "trim_mode");
trim_operation->use_cursor_depth = RNA_boolean_get(op->ptr, "use_cursor_depth");
+ trim_operation->orientation = RNA_enum_get(op->ptr, "trim_orientation");
+
+ /* If the cursor was not over the mesh, force the orientation to view. */
+ if (!sgcontext->ss->gesture_initial_hit) {
+ trim_operation->orientation = SCULPT_GESTURE_TRIM_ORIENTATION_VIEW;
+ }
}
static void sculpt_trim_gesture_operator_properties(wmOperatorType *ot)
@@ -1240,6 +1378,12 @@ static void sculpt_trim_gesture_operator_properties(wmOperatorType *ot)
false,
"Use Cursor for Depth",
"Use cursor location and radius for the dimensions and position of the trimming shape");
+ RNA_def_enum(ot->srna,
+ "trim_orientation",
+ prop_trim_orientation_types,
+ SCULPT_GESTURE_TRIM_ORIENTATION_VIEW,
+ "Shape Orientation",
+ NULL);
}
/* Project Gesture Operation. */
@@ -1425,6 +1569,7 @@ static int sculpt_trim_gesture_box_invoke(bContext *C, wmOperator *op, const wmE
ss->gesture_initial_hit = SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false);
if (ss->gesture_initial_hit) {
copy_v3_v3(ss->gesture_initial_location, sgi.location);
+ copy_v3_v3(ss->gesture_initial_normal, sgi.normal);
}
return WM_gesture_box_invoke(C, op, event);
@@ -1460,6 +1605,7 @@ static int sculpt_trim_gesture_lasso_invoke(bContext *C, wmOperator *op, const w
ss->gesture_initial_hit = SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false);
if (ss->gesture_initial_hit) {
copy_v3_v3(ss->gesture_initial_location, sgi.location);
+ copy_v3_v3(ss->gesture_initial_normal, sgi.normal);
}
return WM_gesture_lasso_invoke(C, op, event);
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 56b5a494df0..ecd45bfb5e9 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -76,6 +76,11 @@
#include "IMB_colormanagement.h"
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+#include "GPU_matrix.h"
+#include "GPU_state.h"
+
#include "WM_api.h"
#include "WM_message.h"
#include "WM_toolsystem.h"
@@ -84,6 +89,7 @@
#include "ED_object.h"
#include "ED_screen.h"
#include "ED_sculpt.h"
+#include "ED_space_api.h"
#include "ED_view3d.h"
#include "paint_intern.h"
#include "sculpt_intern.h"
@@ -1159,6 +1165,7 @@ void SCULPT_floodfill_free(SculptFloodFill *flood)
flood->queue = NULL;
}
+/* -------------------------------------------------------------------- */
/** \name Tool Capabilities
*
* Avoid duplicate checks, internal logic only,
@@ -1380,6 +1387,7 @@ static void sculpt_project_v3_normal_align(SculptSession *ss,
grab_delta, ss->cache->sculpt_normal_symm, (len_signed * normal_weight) * len_view_scale);
}
+/* -------------------------------------------------------------------- */
/** \name SculptProjectVector
*
* Fast-path for #project_plane_v3_v3v3
@@ -1887,6 +1895,7 @@ static float calc_symmetry_feather(Sculpt *sd, StrokeCache *cache)
return 1.0f;
}
+/* -------------------------------------------------------------------- */
/** \name Calculate Normal and Center
*
* Calculate geometry surrounding the brush center.
@@ -2338,7 +2347,7 @@ static float brush_strength(const Sculpt *sd,
final_pressure = pressure * pressure;
return final_pressure * overlap * feather;
case SCULPT_TOOL_SMEAR:
- return pressure * overlap * feather;
+ return alpha * pressure * overlap * feather;
case SCULPT_TOOL_CLAY_STRIPS:
/* Clay Strips needs less strength to compensate the curve. */
final_pressure = powf(pressure, 1.5f);
@@ -3007,6 +3016,7 @@ static void do_mask_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
}
}
+/* -------------------------------------------------------------------- */
/** \name Sculpt Multires Displacement Eraser Brush
* \{ */
@@ -3229,7 +3239,6 @@ static void do_draw_sharp_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to
}
/* -------------------------------------------------------------------- */
-
/** \name Sculpt Topology Brush
* \{ */
@@ -3805,20 +3814,33 @@ static void do_grab_brush_task_cb_ex(void *__restrict userdata,
ss, &test, data->brush->falloff_shape);
const int thread_id = BLI_task_parallel_thread_id(tls);
+ const bool grab_silhouette = brush->flag2 & BRUSH_GRAB_SILHOUETTE;
+
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
SCULPT_orig_vert_data_update(&orig_data, &vd);
if (sculpt_brush_test_sq_fn(&test, orig_data.co)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- orig_data.co,
- sqrtf(test.dist),
- orig_data.no,
- NULL,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
+ float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ orig_data.co,
+ sqrtf(test.dist),
+ orig_data.no,
+ NULL,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ if (grab_silhouette) {
+ float silhouette_test_dir[3];
+ normalize_v3_v3(silhouette_test_dir, grab_delta);
+ if (dot_v3v3(ss->cache->initial_normal, ss->cache->grab_delta_symmetry) < 0.0f) {
+ mul_v3_fl(silhouette_test_dir, -1.0f);
+ }
+ float vno[3];
+ normal_short_to_float_v3(vno, orig_data.no);
+ fade *= max_ff(dot_v3v3(vno, silhouette_test_dir), 0.0f);
+ }
mul_v3_v3fl(proxy[vd.i], grab_delta, fade);
@@ -4752,7 +4774,6 @@ static void do_flatten_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno
}
/* -------------------------------------------------------------------- */
-
/** \name Sculpt Clay Brush
* \{ */
@@ -5277,7 +5298,6 @@ static void do_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
}
/* -------------------------------------------------------------------- */
-
/** \name Sculpt Clay Thumb Brush
* \{ */
@@ -5666,15 +5686,11 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe
/* Check for unsupported features. */
PBVHType type = BKE_pbvh_type(ss->pbvh);
if (brush->sculpt_tool == SCULPT_TOOL_PAINT && type != PBVH_FACES) {
- if (!U.experimental.use_sculpt_vertex_colors) {
- return;
- }
+ return;
}
if (brush->sculpt_tool == SCULPT_TOOL_SMEAR && type != PBVH_FACES) {
- if (!U.experimental.use_sculpt_vertex_colors) {
- return;
- }
+ return;
}
/* Build a list of all nodes that are potentially within the brush's area of influence */
@@ -8126,6 +8142,7 @@ static void SCULPT_OT_symmetrize(wmOperatorType *ot)
/**** Toggle operator for turning sculpt mode on or off ****/
+/** \warning Expects a fully evaluated depsgraph. */
static void sculpt_init_session(Depsgraph *depsgraph, Scene *scene, Object *ob)
{
/* Create persistent sculpt mode data. */
@@ -8190,6 +8207,7 @@ void ED_object_sculptmode_enter_ex(Main *bmain,
if (flush_recalc) {
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
+ BKE_scene_graph_evaluated_ensure(depsgraph, bmain);
}
/* Create sculpt mode session data. */
@@ -8197,10 +8215,6 @@ void ED_object_sculptmode_enter_ex(Main *bmain,
BKE_sculptsession_free(ob);
}
- /* Make sure derived final from original object does not reference possibly
- * freed memory. */
- BKE_object_free_derived_caches(ob);
-
/* Copy the current mesh visibility to the Face Sets. */
BKE_sculpt_face_sets_ensure_from_base_mesh_visibility(me);
@@ -9231,6 +9245,325 @@ static void SCULPT_OT_mask_by_color(wmOperatorType *ot)
1.0f);
}
+/* -------------------------------------------------------------------- */
+/** \name Dyntopo Detail Size Edit Operator
+ * \{ */
+
+/* Defines how much the mouse movement will modify the detail size value. */
+#define DETAIL_SIZE_DELTA_SPEED 0.08f
+#define DETAIL_SIZE_DELTA_ACCURATE_SPEED 0.004f
+
+typedef struct DyntopoDetailSizeEditCustomData {
+ void *draw_handle;
+ Object *active_object;
+
+ float init_mval[2];
+ float accurate_mval[2];
+
+ float outline_col[4];
+
+ bool accurate_mode;
+ bool sample_mode;
+
+ float init_detail_size;
+ float accurate_detail_size;
+ float detail_size;
+ float radius;
+
+ float preview_tri[3][3];
+ float gizmo_mat[4][4];
+} DyntopoDetailSizeEditCustomData;
+
+static void dyntopo_detail_size_parallel_lines_draw(uint pos3d,
+ DyntopoDetailSizeEditCustomData *cd,
+ const float start_co[3],
+ const float end_co[3],
+ bool flip,
+ const float angle)
+{
+ float object_space_constant_detail = 1.0f /
+ (cd->detail_size * mat4_to_scale(cd->active_object->obmat));
+
+ /* The constant detail represents the maximum edge length allowed before subdividing it. If the
+ * triangle grid preview is created with this value it will represent an ideal mesh density where
+ * all edges have the exact maximum length, which never happens in practice. As the minimum edge
+ * length for dyntopo is 0.4 * max_edge_length, this adjust the detail size to the average
+ * between max and min edge length so the preview is more accurate. */
+ object_space_constant_detail *= 0.7f;
+
+ const float total_len = len_v3v3(cd->preview_tri[0], cd->preview_tri[1]);
+ const int tot_lines = (int)(total_len / object_space_constant_detail) + 1;
+ const float tot_lines_fl = total_len / object_space_constant_detail;
+ float spacing_disp[3];
+ sub_v3_v3v3(spacing_disp, end_co, start_co);
+ normalize_v3(spacing_disp);
+
+ float line_disp[3];
+ rotate_v2_v2fl(line_disp, spacing_disp, DEG2RAD(angle));
+ mul_v3_fl(spacing_disp, total_len / tot_lines_fl);
+
+ immBegin(GPU_PRIM_LINES, (uint)tot_lines * 2);
+ for (int i = 0; i < tot_lines; i++) {
+ float line_length;
+ if (flip) {
+ line_length = total_len * ((float)i / (float)tot_lines_fl);
+ }
+ else {
+ line_length = total_len * (1.0f - ((float)i / (float)tot_lines_fl));
+ }
+ float line_start[3];
+ copy_v3_v3(line_start, start_co);
+ madd_v3_v3v3fl(line_start, line_start, spacing_disp, i);
+ float line_end[3];
+ madd_v3_v3v3fl(line_end, line_start, line_disp, line_length);
+ immVertex3fv(pos3d, line_start);
+ immVertex3fv(pos3d, line_end);
+ }
+ immEnd();
+}
+
+static void dyntopo_detail_size_edit_draw(const bContext *UNUSED(C),
+ ARegion *UNUSED(ar),
+ void *arg)
+{
+ DyntopoDetailSizeEditCustomData *cd = arg;
+ GPU_blend(GPU_BLEND_ALPHA);
+ GPU_line_smooth(true);
+
+ uint pos3d = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ GPU_matrix_push();
+ GPU_matrix_mul(cd->gizmo_mat);
+
+ /* Draw Cursor */
+ immUniformColor4fv(cd->outline_col);
+ GPU_line_width(3.0f);
+
+ imm_draw_circle_wire_3d(pos3d, 0, 0, cd->radius, 80);
+
+ /* Draw Triangle. */
+ immUniformColor4f(0.9f, 0.9f, 0.9f, 0.8f);
+ immBegin(GPU_PRIM_LINES, 6);
+ immVertex3fv(pos3d, cd->preview_tri[0]);
+ immVertex3fv(pos3d, cd->preview_tri[1]);
+
+ immVertex3fv(pos3d, cd->preview_tri[1]);
+ immVertex3fv(pos3d, cd->preview_tri[2]);
+
+ immVertex3fv(pos3d, cd->preview_tri[2]);
+ immVertex3fv(pos3d, cd->preview_tri[0]);
+ immEnd();
+
+ /* Draw Grid */
+ GPU_line_width(1.0f);
+ dyntopo_detail_size_parallel_lines_draw(
+ pos3d, cd, cd->preview_tri[0], cd->preview_tri[1], false, 60.0f);
+ dyntopo_detail_size_parallel_lines_draw(
+ pos3d, cd, cd->preview_tri[0], cd->preview_tri[1], true, 120.0f);
+ dyntopo_detail_size_parallel_lines_draw(
+ pos3d, cd, cd->preview_tri[0], cd->preview_tri[2], false, -60.0f);
+ GPU_matrix_pop();
+
+ GPU_blend(GPU_BLEND_NONE);
+ GPU_line_smooth(false);
+}
+
+static void dyntopo_detail_size_edit_cancel(bContext *C, wmOperator *op)
+{
+ Object *active_object = CTX_data_active_object(C);
+ SculptSession *ss = active_object->sculpt;
+ ARegion *ar = CTX_wm_region(C);
+ DyntopoDetailSizeEditCustomData *cd = op->customdata;
+ ED_region_draw_cb_exit(ar->type, cd->draw_handle);
+ ss->draw_faded_cursor = false;
+ MEM_freeN(op->customdata);
+ ED_workspace_status_text(C, NULL);
+}
+
+static void dyntopo_detail_size_sample_from_surface(Object *ob,
+ DyntopoDetailSizeEditCustomData *cd)
+{
+ SculptSession *ss = ob->sculpt;
+ const int active_vertex = SCULPT_active_vertex_get(ss);
+
+ float len_accum = 0;
+ int num_neighbors = 0;
+ SculptVertexNeighborIter ni;
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, active_vertex, ni) {
+ len_accum += len_v3v3(SCULPT_vertex_co_get(ss, active_vertex),
+ SCULPT_vertex_co_get(ss, ni.index));
+ num_neighbors++;
+ }
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
+
+ if (num_neighbors > 0) {
+ const float avg_edge_len = len_accum / num_neighbors;
+ /* Use 0.7 as the average of min and max dyntopo edge length. */
+ const float detail_size = 0.7f / (avg_edge_len * mat4_to_scale(cd->active_object->obmat));
+ cd->detail_size = clamp_f(detail_size, 1.0f, 500.0f);
+ }
+}
+
+static void dyntopo_detail_size_update_from_mouse_delta(DyntopoDetailSizeEditCustomData *cd,
+ const wmEvent *event)
+{
+ const float mval[2] = {event->mval[0], event->mval[1]};
+
+ float detail_size_delta;
+ if (cd->accurate_mode) {
+ detail_size_delta = mval[0] - cd->accurate_mval[0];
+ cd->detail_size = cd->accurate_detail_size +
+ detail_size_delta * DETAIL_SIZE_DELTA_ACCURATE_SPEED;
+ }
+ else {
+ detail_size_delta = mval[0] - cd->init_mval[0];
+ cd->detail_size = cd->init_detail_size + detail_size_delta * DETAIL_SIZE_DELTA_SPEED;
+ }
+
+ if (event->type == EVT_LEFTSHIFTKEY && event->val == KM_PRESS) {
+ cd->accurate_mode = true;
+ copy_v2_v2(cd->accurate_mval, mval);
+ cd->accurate_detail_size = cd->detail_size;
+ }
+ if (event->type == EVT_LEFTSHIFTKEY && event->val == KM_RELEASE) {
+ cd->accurate_mode = false;
+ cd->accurate_detail_size = 0.0f;
+ }
+
+ cd->detail_size = clamp_f(cd->detail_size, 1.0f, 500.0f);
+}
+
+static int dyntopo_detail_size_edit_modal(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ Object *active_object = CTX_data_active_object(C);
+ SculptSession *ss = active_object->sculpt;
+ ARegion *ar = CTX_wm_region(C);
+ DyntopoDetailSizeEditCustomData *cd = op->customdata;
+ Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
+
+ /* Cancel modal operator */
+ if ((event->type == EVT_ESCKEY && event->val == KM_PRESS) ||
+ (event->type == RIGHTMOUSE && event->val == KM_PRESS)) {
+ dyntopo_detail_size_edit_cancel(C, op);
+ ED_region_tag_redraw(ar);
+ return OPERATOR_FINISHED;
+ }
+
+ /* Finish modal operator */
+ if ((event->type == LEFTMOUSE && event->val == KM_RELEASE) ||
+ (event->type == EVT_RETKEY && event->val == KM_PRESS) ||
+ (event->type == EVT_PADENTER && event->val == KM_PRESS)) {
+ ED_region_draw_cb_exit(ar->type, cd->draw_handle);
+ sd->constant_detail = cd->detail_size;
+ ss->draw_faded_cursor = false;
+ MEM_freeN(op->customdata);
+ ED_region_tag_redraw(ar);
+ ED_workspace_status_text(C, NULL);
+ return OPERATOR_FINISHED;
+ }
+
+ ED_region_tag_redraw(ar);
+
+ if (event->type == EVT_LEFTCTRLKEY && event->val == KM_PRESS) {
+ cd->sample_mode = true;
+ }
+ if (event->type == EVT_LEFTCTRLKEY && event->val == KM_RELEASE) {
+ cd->sample_mode = false;
+ }
+
+ /* Sample mode sets the detail size sampling the average edge length under the surface. */
+ if (cd->sample_mode) {
+ dyntopo_detail_size_sample_from_surface(active_object, cd);
+ return OPERATOR_RUNNING_MODAL;
+ }
+ /* Regular mode, changes the detail size by moving the cursor. */
+ dyntopo_detail_size_update_from_mouse_delta(cd, event);
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static int dyntopo_detail_size_edit_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ ARegion *ar = CTX_wm_region(C);
+ Object *active_object = CTX_data_active_object(C);
+ Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
+ Brush *brush = BKE_paint_brush(&sd->paint);
+
+ DyntopoDetailSizeEditCustomData *cd = MEM_callocN(sizeof(DyntopoDetailSizeEditCustomData),
+ "Dyntopo Detail Size Edit OP Custom Data");
+
+ /* Initial operator Custom Data setup. */
+ cd->draw_handle = ED_region_draw_cb_activate(
+ ar->type, dyntopo_detail_size_edit_draw, cd, REGION_DRAW_POST_VIEW);
+ cd->active_object = active_object;
+ cd->init_mval[0] = event->mval[0];
+ cd->init_mval[1] = event->mval[1];
+ cd->detail_size = sd->constant_detail;
+ cd->init_detail_size = sd->constant_detail;
+ copy_v4_v4(cd->outline_col, brush->add_col);
+ op->customdata = cd;
+
+ SculptSession *ss = active_object->sculpt;
+ cd->radius = ss->cursor_radius;
+
+ /* Generates the matrix to position the gizmo in the surface of the mesh using the same location
+ * and orientation as the brush cursor. */
+ float cursor_trans[4][4], cursor_rot[4][4];
+ const float z_axis[4] = {0.0f, 0.0f, 1.0f, 0.0f};
+ float quat[4];
+ copy_m4_m4(cursor_trans, active_object->obmat);
+ translate_m4(
+ cursor_trans, ss->cursor_location[0], ss->cursor_location[1], ss->cursor_location[2]);
+ rotation_between_vecs_to_quat(quat, z_axis, ss->cursor_normal);
+ quat_to_mat4(cursor_rot, quat);
+ copy_m4_m4(cd->gizmo_mat, cursor_trans);
+ mul_m4_m4_post(cd->gizmo_mat, cursor_rot);
+
+ /* Initize the position of the triangle vertices. */
+ const float y_axis[3] = {0.0f, cd->radius, 0.0f};
+ for (int i = 0; i < 3; i++) {
+ zero_v3(cd->preview_tri[i]);
+ rotate_v2_v2fl(cd->preview_tri[i], y_axis, DEG2RAD(120.0f * i));
+ }
+
+ SCULPT_vertex_random_access_ensure(ss);
+
+ WM_event_add_modal_handler(C, op);
+ ED_region_tag_redraw(ar);
+
+ ss->draw_faded_cursor = true;
+
+ const char *status_str = TIP_(
+ "Move the mouse to change the dyntopo detail size. LMB: confirm size, ESC/RMB: cancel");
+ ED_workspace_status_text(C, status_str);
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static bool dyntopo_detail_size_edit_poll(bContext *C)
+{
+ Object *ob = CTX_data_active_object(C);
+ Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
+
+ return SCULPT_mode_poll(C) && ob->sculpt->bm && (sd->flags & SCULPT_DYNTOPO_DETAIL_CONSTANT);
+}
+
+static void SCULPT_OT_dyntopo_detail_size_edit(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Edit Dyntopo Detail Size";
+ ot->description = "Modify the constant detail size of dyntopo interactively";
+ ot->idname = "SCULPT_OT_dyntopo_detail_size_edit";
+
+ /* api callbacks */
+ ot->poll = dyntopo_detail_size_edit_poll;
+ ot->invoke = dyntopo_detail_size_edit_invoke;
+ ot->modal = dyntopo_detail_size_edit_modal;
+ ot->cancel = dyntopo_detail_size_edit_cancel;
+
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
void ED_operatortypes_sculpt(void)
{
WM_operatortype_append(SCULPT_OT_brush_stroke);
@@ -9264,4 +9597,5 @@ void ED_operatortypes_sculpt(void)
WM_operatortype_append(SCULPT_OT_vertex_to_loop_colors);
WM_operatortype_append(SCULPT_OT_color_filter);
WM_operatortype_append(SCULPT_OT_mask_by_color);
+ WM_operatortype_append(SCULPT_OT_dyntopo_detail_size_edit);
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_cloth.c b/source/blender/editors/sculpt_paint/sculpt_cloth.c
index 67129d5da50..20b164fa80c 100644
--- a/source/blender/editors/sculpt_paint/sculpt_cloth.c
+++ b/source/blender/editors/sculpt_paint/sculpt_cloth.c
@@ -139,14 +139,14 @@ static float cloth_brush_simulation_falloff_get(const Brush *brush,
const float falloff = radius + (radius * brush->cloth_sim_limit * brush->cloth_sim_falloff);
if (distance > limit) {
- /* Outiside the limits. */
+ /* Outside the limits. */
return 0.0f;
}
if (distance < falloff) {
/* Before the falloff area. */
return 1.0f;
}
- /* Do a smoothstep transition inside the falloff area. */
+ /* Do a smooth-step transition inside the falloff area. */
float p = 1.0f - ((distance - falloff) / (limit - falloff));
return 3.0f * p * p - 2.0f * p * p * p;
}
@@ -214,7 +214,7 @@ static void cloth_brush_add_length_constraint(SculptSession *ss,
/* Reallocation if the array capacity is exceeded. */
cloth_brush_reallocate_constraints(cloth_sim);
- /* Add the constraint to the GSet to avoid creating it again. */
+ /* Add the constraint to the #GSet to avoid creating it again. */
BLI_edgeset_add(cloth_sim->created_length_constraints, v1, v2);
}
@@ -326,12 +326,15 @@ static void do_cloth_brush_build_constraints_task_cb_ex(
* positions. */
const bool cloth_is_deform_brush = ss->cache != NULL && brush != NULL &&
SCULPT_is_cloth_deform_brush(brush);
+
+ const bool use_falloff_plane = brush->cloth_force_falloff_type ==
+ BRUSH_CLOTH_FORCE_FALLOFF_PLANE;
float radius_squared = 0.0f;
if (cloth_is_deform_brush) {
radius_squared = ss->cache->initial_radius * ss->cache->initial_radius;
}
- /* Only limit the contraint creation to a radius when the simulation is local. */
+ /* Only limit the constraint creation to a radius when the simulation is local. */
const float cloth_sim_radius_squared = brush->cloth_simulation_area_type ==
BRUSH_CLOTH_SIMULATION_AREA_LOCAL ?
data->cloth_sim_radius * data->cloth_sim_radius :
@@ -380,12 +383,21 @@ static void do_cloth_brush_build_constraints_task_cb_ex(
if (brush && brush->sculpt_tool == SCULPT_TOOL_CLOTH) {
/* The cloth brush works by applying forces in most of its modes, but some of them require
* deformation coordinates to make the simulation stable. */
- if (brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_GRAB && len_squared < radius_squared) {
- /* When the grab brush brush is used as part of the cloth brush, deformation constraints
- * are created with different strengths and only inside the radius of the brush. */
- const float fade = BKE_brush_curve_strength(brush, sqrtf(len_squared), ss->cache->radius);
- cloth_brush_add_deformation_constraint(
- data->cloth_sim, node_index, vd.index, fade * CLOTH_DEFORMATION_GRAB_STRENGTH);
+ if (brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_GRAB) {
+ if (use_falloff_plane) {
+ /* With plane falloff the strength of the constraints is set when applying the
+ * deformation forces. */
+ cloth_brush_add_deformation_constraint(
+ data->cloth_sim, node_index, vd.index, CLOTH_DEFORMATION_GRAB_STRENGTH);
+ }
+ else if (len_squared < radius_squared) {
+ /* With radial falloff deformation constraints are created with different strengths and
+ * only inside the radius of the brush. */
+ const float fade = BKE_brush_curve_strength(
+ brush, sqrtf(len_squared), ss->cache->radius);
+ cloth_brush_add_deformation_constraint(
+ data->cloth_sim, node_index, vd.index, fade * CLOTH_DEFORMATION_GRAB_STRENGTH);
+ }
}
else if (brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_SNAKE_HOOK) {
/* Cloth Snake Hook creates deformation constraint with fixed strength because the strength
@@ -436,9 +448,8 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata,
const float *grab_delta = data->grab_delta;
float(*imat)[4] = data->mat;
- const bool use_falloff_plane = !SCULPT_is_cloth_deform_brush(brush) &&
- brush->cloth_force_falloff_type ==
- BRUSH_CLOTH_FORCE_FALLOFF_PLANE;
+ const bool use_falloff_plane = brush->cloth_force_falloff_type ==
+ BRUSH_CLOTH_FORCE_FALLOFF_PLANE;
PBVHVertexIter vd;
const float bstrength = ss->cache->bstrength;
@@ -448,7 +459,7 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata,
ss, &test, data->brush->falloff_shape);
const int thread_id = BLI_task_parallel_thread_id(tls);
- /* For Pich Perpendicular Deform Type. */
+ /* For Pinch Perpendicular Deform Type. */
float x_object_space[3];
float z_object_space[3];
if (brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_PINCH_PERPENDICULAR) {
@@ -470,12 +481,6 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata,
madd_v3_v3fl(gravity, ss->cache->gravity_direction, -data->sd->gravity_factor);
}
- /* Original data for deform brushes. */
- SculptOrigVertData orig_data;
- if (SCULPT_is_cloth_deform_brush(brush)) {
- SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]);
- }
-
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
float force[3];
@@ -486,8 +491,7 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata,
float current_vertex_location[3];
if (brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_GRAB) {
- SCULPT_orig_vert_data_update(&orig_data, &vd);
- copy_v3_v3(current_vertex_location, orig_data.co);
+ copy_v3_v3(current_vertex_location, ss->cache->cloth_sim->init_pos[vd.index]);
}
else {
copy_v3_v3(current_vertex_location, vd.co);
@@ -504,7 +508,7 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata,
float dist = sqrtf(test.dist);
if (use_falloff_plane) {
- dist = dist_to_plane_v3(vd.co, deform_plane);
+ dist = dist_to_plane_v3(current_vertex_location, deform_plane);
}
const float fade = sim_factor * bstrength *
@@ -539,9 +543,15 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata,
break;
case BRUSH_CLOTH_DEFORM_GRAB:
madd_v3_v3v3fl(cloth_sim->deformation_pos[vd.index],
- orig_data.co,
+ cloth_sim->init_pos[vd.index],
ss->cache->grab_delta_symmetry,
fade);
+ if (use_falloff_plane) {
+ cloth_sim->deformation_strength[vd.index] = clamp_f(fade, 0.0f, 1.0f);
+ }
+ else {
+ cloth_sim->deformation_strength[vd.index] = 1.0f;
+ }
zero_v3(force);
break;
case BRUSH_CLOTH_DEFORM_SNAKE_HOOK:
@@ -920,7 +930,7 @@ static void cloth_brush_apply_brush_foces(Sculpt *sd, Object *ob, PBVHNode **nod
BKE_curvemapping_init(brush->curve);
- /* Init the grab delta. */
+ /* Initialize the grab delta. */
copy_v3_v3(grab_delta, ss->cache->grab_delta_symmetry);
normalize_v3(grab_delta);
@@ -930,7 +940,7 @@ static void cloth_brush_apply_brush_foces(Sculpt *sd, Object *ob, PBVHNode **nod
return;
}
- /* Calcuate push offset. */
+ /* Calculate push offset. */
if (brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_PUSH) {
mul_v3_v3fl(offset, ss->cache->sculpt_normal_symm, ss->cache->radius);
@@ -944,7 +954,7 @@ static void cloth_brush_apply_brush_foces(Sculpt *sd, Object *ob, PBVHNode **nod
brush->cloth_force_falloff_type == BRUSH_CLOTH_FORCE_FALLOFF_PLANE) {
SCULPT_calc_brush_plane(sd, ob, nodes, totnode, area_no, area_co);
- /* Init stroke local space matrix. */
+ /* Initialize stroke local space matrix. */
cross_v3_v3v3(mat[0], area_no, ss->cache->grab_delta_symmetry);
mat[0][3] = 0.0f;
cross_v3_v3v3(mat[1], area_no, mat[0]);
@@ -965,8 +975,8 @@ static void cloth_brush_apply_brush_foces(Sculpt *sd, Object *ob, PBVHNode **nod
}
}
- if (brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_SNAKE_HOOK) {
- /* Set the deformation strength to 0. Snake hook will initialize the strength in the required
+ if (ELEM(brush->cloth_deform_type, BRUSH_CLOTH_DEFORM_SNAKE_HOOK, BRUSH_CLOTH_DEFORM_GRAB)) {
+ /* Set the deformation strength to 0. Brushes will initialize the strength in the required
* area. */
const int totverts = SCULPT_vertex_count_get(ss);
for (int i = 0; i < totverts; i++) {
@@ -1058,7 +1068,7 @@ void SCULPT_cloth_brush_ensure_nodes_constraints(
PBVHNode **nodes,
int totnode,
SculptClothSimulation *cloth_sim,
- /* Cannot be const, because it is assigned to a non-const variable.
+ /* Cannot be `const`, because it is assigned to a `non-const` variable.
* NOLINTNEXTLINE: readability-non-const-parameter. */
float initial_location[3],
const float radius)
@@ -1178,7 +1188,7 @@ void SCULPT_do_cloth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
sculpt_cloth_ensure_constraints_in_simulation_area(sd, ob, nodes, totnode);
}
/* The first step of a symmetry pass is never simulated as deformation modes need valid delta
- * for brush tip alignement. */
+ * for brush tip alignment. */
return;
}
@@ -1253,9 +1263,14 @@ void SCULPT_cloth_plane_falloff_preview_draw(const uint gpuattr,
const float outline_col[3],
float outline_alpha)
{
- float local_mat_inv[4][4];
- invert_m4_m4(local_mat_inv, ss->cache->stroke_local_mat);
- GPU_matrix_mul(ss->cache->stroke_local_mat);
+ float local_mat[4][4];
+ copy_m4_m4(local_mat, ss->cache->stroke_local_mat);
+
+ if (ss->cache->brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_GRAB) {
+ add_v3_v3v3(local_mat[3], ss->cache->true_location, ss->cache->grab_delta);
+ }
+
+ GPU_matrix_mul(local_mat);
const float dist = ss->cache->radius;
const float arrow_x = ss->cache->radius * 0.2f;
@@ -1299,7 +1314,7 @@ static EnumPropertyItem prop_cloth_filter_type[] = {
"SCALE",
0,
"Scale",
- "Scales the mesh as a softbody using the origin of the object as scale"},
+ "Scales the mesh as a soft-body using the origin of the object as scale"},
{0, NULL, 0, NULL, NULL},
};
diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.c b/source/blender/editors/sculpt_paint/sculpt_face_set.c
index af6a06caf69..3c87407b2db 100644
--- a/source/blender/editors/sculpt_paint/sculpt_face_set.c
+++ b/source/blender/editors/sculpt_paint/sculpt_face_set.c
@@ -1018,6 +1018,7 @@ void SCULPT_OT_face_sets_randomize_colors(wmOperatorType *ot)
typedef enum eSculptFaceSetEditMode {
SCULPT_FACE_SET_EDIT_GROW = 0,
SCULPT_FACE_SET_EDIT_SHRINK = 1,
+ SCULPT_FACE_SET_EDIT_DELETE_GEOMETRY = 2,
} eSculptFaceSetEditMode;
static EnumPropertyItem prop_sculpt_face_sets_edit_types[] = {
@@ -1035,6 +1036,13 @@ static EnumPropertyItem prop_sculpt_face_sets_edit_types[] = {
"Shrink Face Set",
"Shrinks the Face Sets boundary by one face based on mesh topology",
},
+ {
+ SCULPT_FACE_SET_EDIT_DELETE_GEOMETRY,
+ "DELETE_GEOMETRY",
+ 0,
+ "Delete Geometry",
+ "Deletes the faces that are assigned to the Face Set",
+ },
{0, NULL, 0, NULL, NULL},
};
@@ -1096,6 +1104,78 @@ static void sculpt_face_set_shrink(Object *ob,
}
}
+static bool check_single_face_set(SculptSession *ss, int *face_sets, const bool check_visible_only)
+{
+
+ int first_face_set = SCULPT_FACE_SET_NONE;
+ if (check_visible_only) {
+ for (int f = 0; f < ss->totfaces; f++) {
+ if (face_sets[f] > 0) {
+ first_face_set = face_sets[f];
+ break;
+ }
+ }
+ }
+ else {
+ first_face_set = abs(face_sets[0]);
+ }
+
+ if (first_face_set == SCULPT_FACE_SET_NONE) {
+ return true;
+ }
+
+ for (int f = 0; f < ss->totfaces; f++) {
+ const int face_set_id = check_visible_only ? face_sets[f] : abs(face_sets[f]);
+ if (face_set_id != first_face_set) {
+ return false;
+ }
+ }
+ return true;
+}
+
+static void sculpt_face_set_delete_geometry(Object *ob,
+ SculptSession *ss,
+ const int active_face_set_id,
+ const bool modify_hidden)
+{
+
+ Mesh *mesh = ob->data;
+ const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(mesh);
+ BMesh *bm = BM_mesh_create(&allocsize,
+ &((struct BMeshCreateParams){
+ .use_toolflags = true,
+ }));
+
+ BM_mesh_bm_from_me(bm,
+ mesh,
+ (&(struct BMeshFromMeshParams){
+ .calc_face_normal = true,
+ }));
+
+ BM_mesh_elem_table_init(bm, BM_FACE);
+ BM_mesh_elem_table_ensure(bm, BM_FACE);
+ BM_mesh_elem_hflag_disable_all(bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_TAG, false);
+ BMIter iter;
+ BMFace *f;
+ BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
+ const int face_index = BM_elem_index_get(f);
+ const int face_set_id = modify_hidden ? abs(ss->face_sets[face_index]) :
+ ss->face_sets[face_index];
+ BM_elem_flag_set(f, BM_ELEM_TAG, face_set_id == active_face_set_id);
+ }
+ BM_mesh_delete_hflag_context(bm, BM_ELEM_TAG, DEL_FACES);
+ BM_mesh_elem_hflag_disable_all(bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_TAG, false);
+
+ BM_mesh_bm_to_me(NULL,
+ bm,
+ ob->data,
+ (&(struct BMeshToMeshParams){
+ .calc_object_remap = false,
+ }));
+
+ BM_mesh_free(bm);
+}
+
static void sculpt_face_set_apply_edit(Object *ob,
const int active_face_set_id,
const int mode,
@@ -1103,80 +1183,135 @@ static void sculpt_face_set_apply_edit(Object *ob,
{
SculptSession *ss = ob->sculpt;
- int *prev_face_sets = MEM_dupallocN(ss->face_sets);
-
switch (mode) {
- case SCULPT_FACE_SET_EDIT_GROW:
+ case SCULPT_FACE_SET_EDIT_GROW: {
+ int *prev_face_sets = MEM_dupallocN(ss->face_sets);
sculpt_face_set_grow(ob, ss, prev_face_sets, active_face_set_id, modify_hidden);
+ MEM_SAFE_FREE(prev_face_sets);
break;
- case SCULPT_FACE_SET_EDIT_SHRINK:
+ }
+ case SCULPT_FACE_SET_EDIT_SHRINK: {
+ int *prev_face_sets = MEM_dupallocN(ss->face_sets);
sculpt_face_set_shrink(ob, ss, prev_face_sets, active_face_set_id, modify_hidden);
+ MEM_SAFE_FREE(prev_face_sets);
+ break;
+ }
+ case SCULPT_FACE_SET_EDIT_DELETE_GEOMETRY:
+ sculpt_face_set_delete_geometry(ob, ss, active_face_set_id, modify_hidden);
break;
}
-
- MEM_SAFE_FREE(prev_face_sets);
}
-static int sculpt_face_set_edit_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+static bool sculpt_face_set_edit_is_operation_valid(SculptSession *ss,
+ const eSculptFaceSetEditMode mode,
+ const bool modify_hidden)
{
- Object *ob = CTX_data_active_object(C);
- SculptSession *ss = ob->sculpt;
- Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
-
- const int mode = RNA_enum_get(op->ptr, "mode");
-
- /* Dyntopo not supported. */
if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
+ /* Dyntopo is not supported. */
return OPERATOR_CANCELLED;
}
- /* Ignore other events to avoid repeated operations. */
- if (event->val != KM_PRESS) {
- return OPERATOR_CANCELLED;
+ if (mode == SCULPT_FACE_SET_EDIT_DELETE_GEOMETRY) {
+ if (BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS) {
+ /* Modification of base mesh geometry requires special remapping of multires displacement,
+ * which does not happen here.
+ * Disable delete operation. It can be supported in the future by doing similar displacement
+ * data remapping as what happens in the mesh edit mode. */
+ return false;
+ }
+ if (check_single_face_set(ss, ss->face_sets, !modify_hidden)) {
+ /* Cancel the operator if the mesh only contains one Face Set to avoid deleting the
+ * entire object. */
+ return false;
+ }
}
+ return true;
+}
- BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false, false);
+static void sculpt_face_set_edit_modify_geometry(bContext *C,
+ Object *ob,
+ const int active_face_set,
+ const eSculptFaceSetEditMode mode,
+ const bool modify_hidden)
+{
+ ED_sculpt_undo_geometry_begin(ob, "edit face set delete geometry");
+ sculpt_face_set_apply_edit(ob, abs(active_face_set), mode, modify_hidden);
+ ED_sculpt_undo_geometry_end(ob);
+ BKE_mesh_batch_cache_dirty_tag(ob->data, BKE_MESH_BATCH_DIRTY_ALL);
+ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
+}
- /* Update the current active Face Set and Vertex as the operator can be used directly from the
- * tool without brush cursor. */
- SculptCursorGeometryInfo sgi;
- float mouse[2];
- mouse[0] = event->mval[0];
- mouse[1] = event->mval[1];
- SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false);
+static void face_set_edit_do_post_visibility_updates(Object *ob, PBVHNode **nodes, int totnode)
+{
+ SculptSession *ss = ob->sculpt;
+ PBVH *pbvh = ss->pbvh;
+
+ /* Sync face sets visibility and vertex visibility as now all Face Sets are visible. */
+ SCULPT_visibility_sync_all_face_sets_to_vertices(ob);
+
+ for (int i = 0; i < totnode; i++) {
+ BKE_pbvh_node_mark_update_visibility(nodes[i]);
+ }
+
+ BKE_pbvh_update_vertex_data(ss->pbvh, PBVH_UpdateVisibility);
+
+ if (BKE_pbvh_type(pbvh) == PBVH_FACES) {
+ BKE_mesh_flush_hidden_from_verts(ob->data);
+ }
+}
+static void sculpt_face_set_edit_modify_face_sets(Object *ob,
+ const int active_face_set,
+ const eSculptFaceSetEditMode mode,
+ const bool modify_hidden)
+{
PBVH *pbvh = ob->sculpt->pbvh;
PBVHNode **nodes;
int totnode;
BKE_pbvh_search_gather(pbvh, NULL, NULL, &nodes, &totnode);
if (!nodes) {
- return OPERATOR_CANCELLED;
+ return;
}
-
SCULPT_undo_push_begin("face set edit");
SCULPT_undo_push_node(ob, nodes[0], SCULPT_UNDO_FACE_SETS);
-
- const int active_face_set = SCULPT_active_face_set_get(ss);
- const bool modify_hidden = RNA_boolean_get(op->ptr, "modify_hidden");
-
sculpt_face_set_apply_edit(ob, abs(active_face_set), mode, modify_hidden);
-
SCULPT_undo_push_end();
+ face_set_edit_do_post_visibility_updates(ob, nodes, totnode);
+ MEM_freeN(nodes);
+}
- /* Sync face sets visibility and vertex visibility as now all Face Sets are visible. */
- SCULPT_visibility_sync_all_face_sets_to_vertices(ob);
+static int sculpt_face_set_edit_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ Object *ob = CTX_data_active_object(C);
+ SculptSession *ss = ob->sculpt;
+ Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
- for (int i = 0; i < totnode; i++) {
- BKE_pbvh_node_mark_update_visibility(nodes[i]);
+ const int mode = RNA_enum_get(op->ptr, "mode");
+ const bool modify_hidden = RNA_boolean_get(op->ptr, "modify_hidden");
+
+ if (!sculpt_face_set_edit_is_operation_valid(ss, mode, modify_hidden)) {
+ return OPERATOR_CANCELLED;
}
- BKE_pbvh_update_vertex_data(ss->pbvh, PBVH_UpdateVisibility);
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false, false);
- MEM_SAFE_FREE(nodes);
+ /* Update the current active Face Set and Vertex as the operator can be used directly from the
+ * tool without brush cursor. */
+ SculptCursorGeometryInfo sgi;
+ const float mouse[2] = {event->mval[0], event->mval[1]};
+ SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false);
+ const int active_face_set = SCULPT_active_face_set_get(ss);
- if (BKE_pbvh_type(pbvh) == PBVH_FACES) {
- BKE_mesh_flush_hidden_from_verts(ob->data);
+ switch (mode) {
+ case SCULPT_FACE_SET_EDIT_DELETE_GEOMETRY:
+ sculpt_face_set_edit_modify_geometry(C, ob, active_face_set, mode, modify_hidden);
+ break;
+ case SCULPT_FACE_SET_EDIT_GROW:
+ case SCULPT_FACE_SET_EDIT_SHRINK:
+ sculpt_face_set_edit_modify_face_sets(ob, active_face_set, mode, modify_hidden);
+ break;
}
SCULPT_tag_update_overlays(C);
diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c
index f1410ffad1b..f4f30c903aa 100644
--- a/source/blender/editors/sculpt_paint/sculpt_undo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_undo.c
@@ -1477,8 +1477,6 @@ static void sculpt_undosys_step_decode(
{
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- /* Sculpt needs evaluated state. */
- BKE_scene_view_layer_graph_evaluated_ensure(bmain, scene, view_layer);
Object *ob = OBACT(view_layer);
if (ob && (ob->type == OB_MESH)) {
if (ob->mode & OB_MODE_SCULPT) {
@@ -1486,6 +1484,12 @@ static void sculpt_undosys_step_decode(
}
else {
ED_object_mode_generic_exit(bmain, depsgraph, scene, ob);
+
+ /* Sculpt needs evaluated state.
+ * Note: needs to be done here, as #ED_object_mode_generic_exit will usually invalidate
+ * (some) evaluated data. */
+ BKE_scene_graph_evaluated_ensure(depsgraph, bmain);
+
Mesh *me = ob->data;
/* Don't add sculpt topology undo steps when reading back undo state.
* The undo steps must enter/exit for us. */
diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c
index e5f6b61a2ae..8e2bb6a4813 100644
--- a/source/blender/editors/sound/sound_ops.c
+++ b/source/blender/editors/sound/sound_ops.c
@@ -46,13 +46,14 @@
#include "BKE_packedFile.h"
#include "BKE_report.h"
#include "BKE_scene.h"
-#include "BKE_sequencer.h"
#include "BKE_sound.h"
#include "RNA_access.h"
#include "RNA_define.h"
#include "RNA_enum_types.h"
+#include "SEQ_sequencer.h"
+
#include "UI_interface.h"
#include "WM_api.h"
@@ -170,7 +171,7 @@ static void SOUND_OT_open(wmOperatorType *ot)
FILE_OPENFILE,
WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH,
FILE_DEFAULTDISPLAY,
- FILE_SORT_ALPHA);
+ FILE_SORT_DEFAULT);
RNA_def_boolean(ot->srna, "cache", false, "Cache", "Cache the sound in memory");
RNA_def_boolean(ot->srna, "mono", false, "Mono", "Merge all the sound's channels into one");
}
@@ -197,7 +198,7 @@ static void SOUND_OT_open_mono(wmOperatorType *ot)
FILE_OPENFILE,
WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH,
FILE_DEFAULTDISPLAY,
- FILE_SORT_ALPHA);
+ FILE_SORT_DEFAULT);
RNA_def_boolean(ot->srna, "cache", false, "Cache", "Cache the sound in memory");
RNA_def_boolean(ot->srna, "mono", true, "Mono", "Mixdown the sound to mono");
}
@@ -721,7 +722,7 @@ static void SOUND_OT_mixdown(wmOperatorType *ot)
FILE_SAVE,
WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH | WM_FILESEL_SHOW_PROPS,
FILE_DEFAULTDISPLAY,
- FILE_SORT_ALPHA);
+ FILE_SORT_DEFAULT);
#ifdef WITH_AUDASPACE
RNA_def_int(
ot->srna,
diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c
index 60ce86740cd..8fc16e66466 100644
--- a/source/blender/editors/space_buttons/buttons_context.c
+++ b/source/blender/editors/space_buttons/buttons_context.c
@@ -56,6 +56,7 @@
#include "RNA_access.h"
+#include "ED_buttons.h"
#include "ED_physics.h"
#include "ED_screen.h"
@@ -512,11 +513,11 @@ static bool buttons_context_linestyle_pinnable(const bContext *C, ViewLayer *vie
}
#endif
-static bool buttons_context_path(const bContext *C, ButsContextPath *path, int mainb, int flag)
+static bool buttons_context_path(
+ const bContext *C, SpaceProperties *sbuts, ButsContextPath *path, int mainb, int flag)
{
/* Note we don't use CTX_data here, instead we get it from the window.
* Otherwise there is a loop reading the context that we are setting. */
- SpaceProperties *sbuts = CTX_wm_space_properties(C);
wmWindow *window = CTX_wm_window(C);
Scene *scene = WM_window_get_active_scene(window);
ViewLayer *view_layer = WM_window_get_active_view_layer(window);
@@ -660,14 +661,14 @@ void buttons_context_compute(const bContext *C, SpaceProperties *sbuts)
int flag = 0;
/* Set scene path. */
- buttons_context_path(C, path, BCONTEXT_SCENE, pflag);
+ buttons_context_path(C, sbuts, path, BCONTEXT_SCENE, pflag);
buttons_texture_context_compute(C, sbuts);
/* for each context, see if we can compute a valid path to it, if
* this is the case, we know we have to display the button */
for (int i = 0; i < BCONTEXT_TOT; i++) {
- if (buttons_context_path(C, path, i, pflag)) {
+ if (buttons_context_path(C, sbuts, path, i, pflag)) {
flag |= (1 << i);
/* setting icon for data context */
@@ -713,7 +714,7 @@ void buttons_context_compute(const bContext *C, SpaceProperties *sbuts)
}
}
- buttons_context_path(C, path, sbuts->mainb, pflag);
+ buttons_context_path(C, sbuts, path, sbuts->mainb, pflag);
if (!(flag & (1 << sbuts->mainb))) {
if (flag & (1 << BCONTEXT_OBJECT)) {
@@ -734,6 +735,39 @@ void buttons_context_compute(const bContext *C, SpaceProperties *sbuts)
sbuts->pathflag = flag;
}
+static bool is_pointer_in_path(ButsContextPath *path, PointerRNA *ptr)
+{
+ for (int i = 0; i < path->len; ++i) {
+ if (ptr->owner_id == path->ptr[i].owner_id) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void ED_buttons_set_context(const bContext *C, PointerRNA *ptr, const int context)
+{
+ ScrArea *active_area = CTX_wm_area(C);
+ bScreen *screen = CTX_wm_screen(C);
+
+ LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
+ /* Only update for properties editors that are visible and share a border. */
+ if (area->spacetype != SPACE_PROPERTIES) {
+ continue;
+ }
+ if (!ED_area_has_shared_border(active_area, area)) {
+ continue;
+ }
+
+ SpaceProperties *sbuts = (SpaceProperties *)area->spacedata.first;
+ ButsContextPath path;
+ if (buttons_context_path(C, sbuts, &path, context, 0) && is_pointer_in_path(&path, ptr)) {
+ sbuts->mainbuser = context;
+ sbuts->mainb = sbuts->mainbuser;
+ }
+ }
+}
+
/************************* Context Callback ************************/
const char *buttons_context_dir[] = {
diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c
index 87cf8507dd4..8bdc2ed993f 100644
--- a/source/blender/editors/space_buttons/buttons_ops.c
+++ b/source/blender/editors/space_buttons/buttons_ops.c
@@ -378,7 +378,7 @@ void BUTTONS_OT_file_browse(wmOperatorType *ot)
FILE_OPENFILE,
WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH,
FILE_DEFAULTDISPLAY,
- FILE_SORT_ALPHA);
+ FILE_SORT_DEFAULT);
}
/* Second operator, only difference from BUTTONS_OT_file_browse is WM_FILESEL_DIRECTORY. */
@@ -405,7 +405,7 @@ void BUTTONS_OT_directory_browse(wmOperatorType *ot)
FILE_OPENFILE,
WM_FILESEL_DIRECTORY | WM_FILESEL_RELPATH,
FILE_DEFAULTDISPLAY,
- FILE_SORT_ALPHA);
+ FILE_SORT_DEFAULT);
}
/** \} */
diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c
index 26fa5b8a06c..1b962a92be5 100644
--- a/source/blender/editors/space_clip/clip_ops.c
+++ b/source/blender/editors/space_clip/clip_ops.c
@@ -329,7 +329,7 @@ void CLIP_OT_open(wmOperatorType *ot)
FILE_OPENFILE,
WM_FILESEL_RELPATH | WM_FILESEL_FILES | WM_FILESEL_DIRECTORY,
FILE_DEFAULTDISPLAY,
- FILE_SORT_ALPHA);
+ FILE_SORT_DEFAULT);
}
/** \} */
diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c
index 0631b6ea8a0..4d3e6cf4d6a 100644
--- a/source/blender/editors/space_clip/tracking_ops.c
+++ b/source/blender/editors/space_clip/tracking_ops.c
@@ -1043,13 +1043,13 @@ static int clear_track_path_exec(bContext *C, wmOperator *op)
void CLIP_OT_clear_track_path(wmOperatorType *ot)
{
static const EnumPropertyItem clear_path_actions[] = {
- {TRACK_CLEAR_UPTO, "UPTO", 0, "Clear up-to", "Clear path up to current frame"},
+ {TRACK_CLEAR_UPTO, "UPTO", 0, "Clear Up To", "Clear path up to current frame"},
{TRACK_CLEAR_REMAINED,
"REMAINED",
0,
- "Clear remained",
+ "Clear Remained",
"Clear path at remaining frames (after current)"},
- {TRACK_CLEAR_ALL, "ALL", 0, "Clear all", "Clear the whole path"},
+ {TRACK_CLEAR_ALL, "ALL", 0, "Clear All", "Clear the whole path"},
{0, NULL, 0, NULL, NULL},
};
diff --git a/source/blender/editors/space_clip/tracking_select.c b/source/blender/editors/space_clip/tracking_select.c
index 478d22c7582..063ea9592aa 100644
--- a/source/blender/editors/space_clip/tracking_select.c
+++ b/source/blender/editors/space_clip/tracking_select.c
@@ -975,15 +975,15 @@ static int select_grouped_exec(bContext *C, wmOperator *op)
void CLIP_OT_select_grouped(wmOperatorType *ot)
{
static const EnumPropertyItem select_group_items[] = {
- {0, "KEYFRAMED", 0, "Keyframed tracks", "Select all keyframed tracks"},
- {1, "ESTIMATED", 0, "Estimated tracks", "Select all estimated tracks"},
- {2, "TRACKED", 0, "Tracked tracks", "Select all tracked tracks"},
- {3, "LOCKED", 0, "Locked tracks", "Select all locked tracks"},
- {4, "DISABLED", 0, "Disabled tracks", "Select all disabled tracks"},
+ {0, "KEYFRAMED", 0, "Keyframed Tracks", "Select all keyframed tracks"},
+ {1, "ESTIMATED", 0, "Estimated Tracks", "Select all estimated tracks"},
+ {2, "TRACKED", 0, "Tracked Tracks", "Select all tracked tracks"},
+ {3, "LOCKED", 0, "Locked Tracks", "Select all locked tracks"},
+ {4, "DISABLED", 0, "Disabled Tracks", "Select all disabled tracks"},
{5,
"COLOR",
0,
- "Tracks with same color",
+ "Tracks with Same Color",
"Select all tracks with same color as active track"},
{6, "FAILED", 0, "Failed Tracks", "Select all tracks which failed to be reconstructed"},
{0, NULL, 0, NULL, NULL},
diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c
index 91653fb7785..93367ad3d3c 100644
--- a/source/blender/editors/space_file/file_ops.c
+++ b/source/blender/editors/space_file/file_ops.c
@@ -1351,18 +1351,17 @@ static int file_column_sort_ui_context_invoke(bContext *C,
if (column_type != COLUMN_NONE) {
const FileAttributeColumn *column = &sfile->layout->attribute_columns[column_type];
- if (column->sort_type != FILE_SORT_NONE) {
- if (sfile->params->sort == column->sort_type) {
- /* Already sorting by selected column -> toggle sort invert (three state logic). */
- sfile->params->flag ^= FILE_SORT_INVERT;
- }
- else {
- sfile->params->sort = column->sort_type;
- sfile->params->flag &= ~FILE_SORT_INVERT;
- }
-
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
+ BLI_assert(column->sort_type != FILE_SORT_DEFAULT);
+ if (sfile->params->sort == column->sort_type) {
+ /* Already sorting by selected column -> toggle sort invert (three state logic). */
+ sfile->params->flag ^= FILE_SORT_INVERT;
}
+ else {
+ sfile->params->sort = column->sort_type;
+ sfile->params->flag &= ~FILE_SORT_INVERT;
+ }
+
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
}
}
@@ -2415,7 +2414,8 @@ void file_directory_enter_handle(bContext *C, void *UNUSED(arg_unused), void *UN
WM_operator_properties_create_ptr(&ptr, ot);
RNA_string_set(&ptr, "directory", sfile->params->dir);
RNA_boolean_set(&ptr, "open", true);
- /* Enable confirmation prompt, else it's too easy to accidentally create new directories. */
+ /* Enable confirmation prompt, else it's too easy
+ * to accidentally create new directories. */
RNA_boolean_set(&ptr, "confirm", true);
if (lastdir) {
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index 3004aadb5dd..9e51b6ca4ba 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -294,9 +294,6 @@ enum {
typedef struct FileList {
FileDirEntryArr filelist;
- short prv_w;
- short prv_h;
-
short flags;
short sort;
@@ -586,7 +583,7 @@ static int compare_extension(void *user_data, const void *a1, const void *a2)
void filelist_sort(struct FileList *filelist)
{
- if ((filelist->flags & FL_NEED_SORTING) && (filelist->sort != FILE_SORT_NONE)) {
+ if (filelist->flags & FL_NEED_SORTING) {
void *sort_cb = NULL;
switch (filelist->sort) {
@@ -602,7 +599,7 @@ void filelist_sort(struct FileList *filelist)
case FILE_SORT_EXTENSION:
sort_cb = compare_extension;
break;
- case FILE_SORT_NONE: /* Should never reach this point! */
+ case FILE_SORT_DEFAULT:
default:
BLI_assert(0);
break;
@@ -951,12 +948,6 @@ void filelist_free_icons(void)
}
}
-void filelist_imgsize(struct FileList *filelist, short w, short h)
-{
- filelist->prv_w = w;
- filelist->prv_h = h;
-}
-
static FileDirEntry *filelist_geticon_get_file(struct FileList *filelist, const int index)
{
BLI_assert(G.background == false);
@@ -1303,6 +1294,8 @@ static void filelist_cache_preview_runf(TaskPool *__restrict pool, void *taskdat
}
IMB_thumb_path_lock(preview->path);
+ /* Always generate biggest preview size for now, it's simpler and avoids having to re-generate in
+ * case user switch to a bigger preview size. */
preview->img = IMB_thumb_manage(preview->path, THB_LARGE, source);
IMB_thumb_path_unlock(preview->path);
@@ -1569,7 +1562,6 @@ void filelist_free(struct FileList *filelist)
memset(&filelist->filter_data, 0, sizeof(filelist->filter_data));
filelist->flags &= ~(FL_NEED_SORTING | FL_NEED_FILTERING);
- filelist->sort = FILE_SORT_NONE;
}
void filelist_freelib(struct FileList *filelist)
diff --git a/source/blender/editors/space_file/filelist.h b/source/blender/editors/space_file/filelist.h
index 051b811b001..4b8cc052382 100644
--- a/source/blender/editors/space_file/filelist.h
+++ b/source/blender/editors/space_file/filelist.h
@@ -69,7 +69,6 @@ void filelist_filter(struct FileList *filelist);
void filelist_init_icons(void);
void filelist_free_icons(void);
-void filelist_imgsize(struct FileList *filelist, short w, short h);
struct ImBuf *filelist_getimage(struct FileList *filelist, const int index);
struct ImBuf *filelist_geticon_image(struct FileList *filelist, const int index);
int filelist_geticon(struct FileList *filelist, const int index, const bool is_main);
diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c
index 42b2806814b..15c6972c5f5 100644
--- a/source/blender/editors/space_file/filesel.c
+++ b/source/blender/editors/space_file/filesel.c
@@ -61,6 +61,7 @@
#include "BLF_api.h"
#include "ED_fileselect.h"
+#include "ED_screen.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -266,15 +267,16 @@ short ED_fileselect_set_params(SpaceFile *sfile)
params->display = RNA_property_enum_get(op->ptr, prop);
}
+ if (params->display == FILE_DEFAULTDISPLAY) {
+ params->display = U_default.file_space_data.display_type;
+ }
+
if ((prop = RNA_struct_find_property(op->ptr, "sort_method"))) {
params->sort = RNA_property_enum_get(op->ptr, prop);
}
- else {
- params->sort = U_default.file_space_data.sort_type;
- }
- if (params->display == FILE_DEFAULTDISPLAY) {
- params->display = U_default.file_space_data.display_type;
+ if (params->sort == FILE_SORT_DEFAULT) {
+ params->sort = U_default.file_space_data.sort_type;
}
if (is_relative_path) {
@@ -326,8 +328,9 @@ short ED_fileselect_set_params(SpaceFile *sfile)
return 1;
}
-/* The subset of FileSelectParams.flag items we store into preferences. */
-#define PARAMS_FLAGS_REMEMBERED (FILE_HIDE_DOT | FILE_SORT_INVERT)
+/* The subset of FileSelectParams.flag items we store into preferences. Note that FILE_SORT_ALPHA
+ * may also be remembered, but only conditionally. */
+#define PARAMS_FLAGS_REMEMBERED (FILE_HIDE_DOT)
void ED_fileselect_window_params_get(const wmWindow *win, int win_size[2], bool *is_maximized)
{
@@ -340,6 +343,22 @@ void ED_fileselect_window_params_get(const wmWindow *win, int win_size[2], bool
*is_maximized = WM_window_is_maximized(win);
}
+static bool file_select_use_default_display_type(const SpaceFile *sfile)
+{
+ PropertyRNA *prop;
+ return (sfile->op == NULL) ||
+ !(prop = RNA_struct_find_property(sfile->op->ptr, "display_type")) ||
+ (RNA_property_enum_get(sfile->op->ptr, prop) == FILE_DEFAULTDISPLAY);
+}
+
+static bool file_select_use_default_sort_type(const SpaceFile *sfile)
+{
+ PropertyRNA *prop;
+ return (sfile->op == NULL) ||
+ !(prop = RNA_struct_find_property(sfile->op->ptr, "sort_method")) ||
+ (RNA_property_enum_get(sfile->op->ptr, prop) == FILE_SORT_DEFAULT);
+}
+
void ED_fileselect_set_params_from_userdef(SpaceFile *sfile)
{
wmOperator *op = sfile->op;
@@ -351,12 +370,6 @@ void ED_fileselect_set_params_from_userdef(SpaceFile *sfile)
return;
}
- if (!RNA_struct_property_is_set(op->ptr, "display_type")) {
- sfile->params->display = sfile_udata->display_type;
- }
- if (!RNA_struct_property_is_set(op->ptr, "sort_method")) {
- sfile->params->sort = sfile_udata->sort_type;
- }
sfile->params->thumbnail_size = sfile_udata->thumbnail_size;
sfile->params->details_flags = sfile_udata->details_flags;
sfile->params->filter_id = sfile_udata->filter_id;
@@ -364,6 +377,16 @@ void ED_fileselect_set_params_from_userdef(SpaceFile *sfile)
/* Combine flags we take from params with the flags we take from userdef. */
sfile->params->flag = (sfile->params->flag & ~PARAMS_FLAGS_REMEMBERED) |
(sfile_udata->flag & PARAMS_FLAGS_REMEMBERED);
+
+ if (file_select_use_default_display_type(sfile)) {
+ sfile->params->display = sfile_udata->display_type;
+ }
+ if (file_select_use_default_sort_type(sfile)) {
+ sfile->params->sort = sfile_udata->sort_type;
+ /* For the default sorting, also take invert flag from userdef. */
+ sfile->params->flag = (sfile->params->flag & ~FILE_SORT_INVERT) |
+ (sfile_udata->flag & FILE_SORT_INVERT);
+ }
}
/**
@@ -380,13 +403,24 @@ void ED_fileselect_params_to_userdef(SpaceFile *sfile,
UserDef_FileSpaceData *sfile_udata_new = &U.file_space_data;
UserDef_FileSpaceData sfile_udata_old = U.file_space_data;
- sfile_udata_new->display_type = sfile->params->display;
sfile_udata_new->thumbnail_size = sfile->params->thumbnail_size;
- sfile_udata_new->sort_type = sfile->params->sort;
sfile_udata_new->details_flags = sfile->params->details_flags;
sfile_udata_new->flag = sfile->params->flag & PARAMS_FLAGS_REMEMBERED;
sfile_udata_new->filter_id = sfile->params->filter_id;
+ /* In some rare cases, operators ask for a specific display or sort type (e.g. chronological
+ * sorting for "Recover Auto Save"). So the settings are optimized for a specific operation.
+ * Don't let that change the userdef memory for more general cases. */
+ if (file_select_use_default_display_type(sfile)) {
+ sfile_udata_new->display_type = sfile->params->display;
+ }
+ if (file_select_use_default_sort_type(sfile)) {
+ sfile_udata_new->sort_type = sfile->params->sort;
+ /* In this case also remember the invert flag. */
+ sfile_udata_new->flag = (sfile_udata_new->flag & ~FILE_SORT_INVERT) |
+ (sfile->params->flag & FILE_SORT_INVERT);
+ }
+
if (temp_win_size && !is_maximized) {
sfile_udata_new->temp_win_sizex = temp_win_size[0];
sfile_udata_new->temp_win_sizey = temp_win_size[1];
@@ -1050,3 +1084,20 @@ void file_params_renamefile_activate(SpaceFile *sfile, FileSelectParams *params)
params->rename_flag = 0;
}
}
+
+ScrArea *ED_fileselect_handler_area_find(const wmWindow *win, const wmOperator *file_operator)
+{
+ bScreen *screen = WM_window_get_active_screen(win);
+
+ ED_screen_areas_iter (win, screen, area) {
+ if (area->spacetype == SPACE_FILE) {
+ SpaceFile *sfile = area->spacedata.first;
+
+ if (sfile->op == file_operator) {
+ return area;
+ }
+ }
+ }
+
+ return NULL;
+}
diff --git a/source/blender/editors/space_file/fsmenu.c b/source/blender/editors/space_file/fsmenu.c
index 329b5fe67fd..b7d47902fe8 100644
--- a/source/blender/editors/space_file/fsmenu.c
+++ b/source/blender/editors/space_file/fsmenu.c
@@ -203,7 +203,7 @@ static void fsmenu_xdg_insert_entry(GHash *xdg_map,
xdg_path = xdg_path_buf;
}
fsmenu_insert_entry(
- fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, xdg_path, IFACE_(default_path), icon, FS_INSERT_LAST);
+ fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, xdg_path, N_(default_path), icon, FS_INSERT_LAST);
}
/** \} */
@@ -698,49 +698,49 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
fsmenu_add_windows_folder(fsmenu,
FS_CATEGORY_SYSTEM_BOOKMARKS,
&FOLDERID_Profile,
- IFACE_("Home"),
+ N_("Home"),
ICON_HOME,
FS_INSERT_LAST);
fsmenu_add_windows_folder(fsmenu,
FS_CATEGORY_SYSTEM_BOOKMARKS,
&FOLDERID_Desktop,
- IFACE_("Desktop"),
+ N_("Desktop"),
ICON_DESKTOP,
FS_INSERT_LAST);
fsmenu_add_windows_folder(fsmenu,
FS_CATEGORY_SYSTEM_BOOKMARKS,
&FOLDERID_Documents,
- IFACE_("Documents"),
+ N_("Documents"),
ICON_DOCUMENTS,
FS_INSERT_LAST);
fsmenu_add_windows_folder(fsmenu,
FS_CATEGORY_SYSTEM_BOOKMARKS,
&FOLDERID_Downloads,
- IFACE_("Downloads"),
+ N_("Downloads"),
ICON_IMPORT,
FS_INSERT_LAST);
fsmenu_add_windows_folder(fsmenu,
FS_CATEGORY_SYSTEM_BOOKMARKS,
&FOLDERID_Music,
- IFACE_("Music"),
+ N_("Music"),
ICON_FILE_SOUND,
FS_INSERT_LAST);
fsmenu_add_windows_folder(fsmenu,
FS_CATEGORY_SYSTEM_BOOKMARKS,
&FOLDERID_Pictures,
- IFACE_("Pictures"),
+ N_("Pictures"),
ICON_FILE_IMAGE,
FS_INSERT_LAST);
fsmenu_add_windows_folder(fsmenu,
FS_CATEGORY_SYSTEM_BOOKMARKS,
&FOLDERID_Videos,
- IFACE_("Videos"),
+ N_("Videos"),
ICON_FILE_MOVIE,
FS_INSERT_LAST);
fsmenu_add_windows_folder(fsmenu,
FS_CATEGORY_SYSTEM_BOOKMARKS,
&FOLDERID_Fonts,
- IFACE_("Fonts"),
+ N_("Fonts"),
ICON_FILE_FONT,
FS_INSERT_LAST);
@@ -757,16 +757,12 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
{
/* We store some known macOS system paths and corresponding icons
* and names in the FS_CATEGORY_OTHER (not displayed directly) category. */
- fsmenu_insert_entry(fsmenu,
- FS_CATEGORY_OTHER,
- "/Library/Fonts/",
- IFACE_("Fonts"),
- ICON_FILE_FONT,
- FS_INSERT_LAST);
+ fsmenu_insert_entry(
+ fsmenu, FS_CATEGORY_OTHER, "/Library/Fonts/", N_("Fonts"), ICON_FILE_FONT, FS_INSERT_LAST);
fsmenu_insert_entry(fsmenu,
FS_CATEGORY_OTHER,
"/Applications/",
- IFACE_("Applications"),
+ N_("Applications"),
ICON_FILE_FOLDER,
FS_INSERT_LAST);
@@ -777,13 +773,13 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
fsmenu_insert_entry(fsmenu, FS_CATEGORY_OTHER, line, name, icon, FS_INSERT_LAST);
FS_MACOS_PATH("%s/", NULL, ICON_HOME)
- FS_MACOS_PATH("%s/Desktop/", IFACE_("Desktop"), ICON_DESKTOP)
- FS_MACOS_PATH("%s/Documents/", IFACE_("Documents"), ICON_DOCUMENTS)
- FS_MACOS_PATH("%s/Downloads/", IFACE_("Downloads"), ICON_IMPORT)
- FS_MACOS_PATH("%s/Movies/", IFACE_("Movies"), ICON_FILE_MOVIE)
- FS_MACOS_PATH("%s/Music/", IFACE_("Music"), ICON_FILE_SOUND)
- FS_MACOS_PATH("%s/Pictures/", IFACE_("Pictures"), ICON_FILE_IMAGE)
- FS_MACOS_PATH("%s/Library/Fonts/", IFACE_("Fonts"), ICON_FILE_FONT)
+ FS_MACOS_PATH("%s/Desktop/", N_("Desktop"), ICON_DESKTOP)
+ FS_MACOS_PATH("%s/Documents/", N_("Documents"), ICON_DOCUMENTS)
+ FS_MACOS_PATH("%s/Downloads/", N_("Downloads"), ICON_IMPORT)
+ FS_MACOS_PATH("%s/Movies/", N_("Movies"), ICON_FILE_MOVIE)
+ FS_MACOS_PATH("%s/Music/", N_("Music"), ICON_FILE_SOUND)
+ FS_MACOS_PATH("%s/Pictures/", N_("Pictures"), ICON_FILE_IMAGE)
+ FS_MACOS_PATH("%s/Library/Fonts/", N_("Fonts"), ICON_FILE_FONT)
# undef FS_MACOS_PATH
@@ -902,7 +898,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
if (read_bookmarks && home) {
fsmenu_insert_entry(
- fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, home, IFACE_("Home"), ICON_HOME, FS_INSERT_LAST);
+ fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, home, N_("Home"), ICON_HOME, FS_INSERT_LAST);
/* Follow the XDG spec, check if these are available. */
GHash *xdg_map = fsmenu_xdg_user_dirs_parse(home);
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index 7fc1329df64..9523810aa07 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -1863,6 +1863,75 @@ void GRAPH_OT_bake(wmOperatorType *ot)
/* TODO: add props for start/end frames (Joshua Leung 2009) */
}
+/* ******************** Un-Bake F-Curve Operator *********************** */
+/* This operator unbakes the data of the selected F-Points to F-Curves. */
+
+/* Un-Bake F-Points into F-Curves. */
+static void unbake_graph_curves(bAnimContext *ac, int start, int end)
+{
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+
+ /* Filter data. */
+ const int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_SEL |
+ ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* Loop through filtered data and add keys between selected keyframes on every frame. */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ FCurve *fcu = (FCurve *)ale->key_data;
+
+ fcurve_samples_to_keyframes(fcu, start, end);
+
+ ale->update |= ANIM_UPDATE_DEPS;
+ }
+
+ ANIM_animdata_update(ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
+}
+
+/* ------------------- */
+
+static int graphkeys_unbake_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ bAnimContext ac;
+ Scene *scene = NULL;
+ int start, end;
+
+ /* Get editor data. */
+ if (ANIM_animdata_get_context(C, &ac) == 0) {
+ return OPERATOR_CANCELLED;
+ }
+
+ scene = ac.scene;
+ start = PSFRA;
+ end = PEFRA;
+
+ /* Unbake keyframes. */
+ unbake_graph_curves(&ac, start, end);
+
+ /* Set notifier that keyframes have changed. */
+ /* NOTE: some distinction between order/number of keyframes and type should be made? */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void GRAPH_OT_unbake(wmOperatorType *ot)
+{
+ /* Identifiers */
+ ot->name = "Un-Bake Curve";
+ ot->idname = "GRAPH_OT_unbake";
+ ot->description = "Un-Bake selected F-Points to F-Curves";
+
+ /* API callbacks */
+ ot->exec = graphkeys_unbake_exec;
+ ot->poll = graphop_selected_fcurve_poll;
+
+ /* Flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
#ifdef WITH_AUDASPACE
/* ******************** Sound Bake F-Curve Operator *********************** */
@@ -2021,7 +2090,7 @@ void GRAPH_OT_sound_bake(wmOperatorType *ot)
FILE_OPENFILE,
WM_FILESEL_FILEPATH | WM_FILESEL_SHOW_PROPS,
FILE_DEFAULTDISPLAY,
- FILE_SORT_ALPHA);
+ FILE_SORT_DEFAULT);
RNA_def_float(ot->srna,
"low",
0.0f,
@@ -3507,7 +3576,7 @@ void GRAPH_OT_fmodifier_paste(wmOperatorType *ot)
/* Properties */
RNA_def_boolean(
- ot->srna, "only_active", true, "Only Active", "Only paste F-Modifiers on active F-Curve");
+ ot->srna, "only_active", false, "Only Active", "Only paste F-Modifiers on active F-Curve");
RNA_def_boolean(
ot->srna,
"replace",
diff --git a/source/blender/editors/space_graph/graph_intern.h b/source/blender/editors/space_graph/graph_intern.h
index eaa14fedb93..7add2f7cbb8 100644
--- a/source/blender/editors/space_graph/graph_intern.h
+++ b/source/blender/editors/space_graph/graph_intern.h
@@ -103,6 +103,7 @@ void GRAPH_OT_clean(struct wmOperatorType *ot);
void GRAPH_OT_decimate(struct wmOperatorType *ot);
void GRAPH_OT_sample(struct wmOperatorType *ot);
void GRAPH_OT_bake(struct wmOperatorType *ot);
+void GRAPH_OT_unbake(struct wmOperatorType *ot);
void GRAPH_OT_sound_bake(struct wmOperatorType *ot);
void GRAPH_OT_smooth(struct wmOperatorType *ot);
void GRAPH_OT_euler_filter(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c
index fd68303e759..63acc2a1774 100644
--- a/source/blender/editors/space_graph/graph_ops.c
+++ b/source/blender/editors/space_graph/graph_ops.c
@@ -459,6 +459,7 @@ void graphedit_operatortypes(void)
WM_operatortype_append(GRAPH_OT_easing_type);
WM_operatortype_append(GRAPH_OT_sample);
WM_operatortype_append(GRAPH_OT_bake);
+ WM_operatortype_append(GRAPH_OT_unbake);
WM_operatortype_append(GRAPH_OT_sound_bake);
WM_operatortype_append(GRAPH_OT_smooth);
WM_operatortype_append(GRAPH_OT_clean);
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index e36c7d6b6e7..6f511d30aa9 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -1486,7 +1486,7 @@ void IMAGE_OT_open(wmOperatorType *ot)
WM_FILESEL_FILEPATH | WM_FILESEL_DIRECTORY | WM_FILESEL_FILES |
WM_FILESEL_RELPATH,
FILE_DEFAULTDISPLAY,
- FILE_SORT_ALPHA);
+ FILE_SORT_DEFAULT);
RNA_def_boolean(
ot->srna,
@@ -1638,7 +1638,7 @@ void IMAGE_OT_replace(wmOperatorType *ot)
FILE_OPENFILE,
WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH,
FILE_DEFAULTDISPLAY,
- FILE_SORT_ALPHA);
+ FILE_SORT_DEFAULT);
}
/** \} */
@@ -2038,7 +2038,7 @@ void IMAGE_OT_save_as(wmOperatorType *ot)
FILE_SAVE,
WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH | WM_FILESEL_SHOW_PROPS,
FILE_DEFAULTDISPLAY,
- FILE_SORT_ALPHA);
+ FILE_SORT_DEFAULT);
}
/** \} */
@@ -2047,36 +2047,17 @@ void IMAGE_OT_save_as(wmOperatorType *ot)
/** \name Save Image Operator
* \{ */
-static bool image_file_path_saveable(bContext *C, Image *ima, ImageUser *iuser)
+/**
+ * \param iuser: Image user or NULL when called outside the image space.
+ */
+static bool image_file_format_writable(Image *ima, ImageUser *iuser)
{
- /* Can always repack images. */
- if (BKE_image_has_packedfile(ima)) {
- return true;
- }
-
- /* Test for valid filepath. */
void *lock;
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock);
bool ret = false;
- if (ibuf) {
- Main *bmain = CTX_data_main(C);
- char name[FILE_MAX];
- BLI_strncpy(name, ibuf->name, FILE_MAX);
- BLI_path_abs(name, BKE_main_blendfile_path(bmain));
-
- if (BLI_exists(name) == false) {
- CTX_wm_operator_poll_msg_set(C, "image file not found");
- }
- else if (!BLI_file_is_writable(name)) {
- CTX_wm_operator_poll_msg_set(C, "image path can't be written to");
- }
- else if (!BKE_image_buffer_format_writable(ibuf)) {
- CTX_wm_operator_poll_msg_set(C, "image format is read-only");
- }
- else {
- ret = true;
- }
+ if (ibuf && BKE_image_buffer_format_writable(ibuf)) {
+ ret = true;
}
BKE_image_release_ibuf(ima, ibuf, lock);
@@ -2090,16 +2071,12 @@ static bool image_save_poll(bContext *C)
return false;
}
- Image *ima = image_from_context(C);
- ImageUser *iuser = image_user_from_context(C);
-
- /* Images without a filepath will go to save as. */
- if (!BKE_image_has_filepath(ima)) {
- return true;
- }
+ /* Check if there is a valid file path and image format we can write
+ * outside of the 'poll' so we can show a report with a pop-up. */
- /* Check if there is a valid file path and image format we can write. */
- return image_file_path_saveable(C, ima, iuser);
+ /* Can always repack images.
+ * Images without a filepath will go to "Save As". */
+ return true;
}
static int image_save_exec(bContext *C, wmOperator *op)
@@ -2114,6 +2091,8 @@ static int image_save_exec(bContext *C, wmOperator *op)
if (BKE_image_has_packedfile(image)) {
/* Save packed files to memory. */
BKE_image_memorypack(image);
+ /* Report since this can be called from key shortcuts. */
+ BKE_reportf(op->reports, RPT_INFO, "Packed to memory image \"%s\"", image->filepath);
return OPERATOR_FINISHED;
}
@@ -2123,16 +2102,15 @@ static int image_save_exec(bContext *C, wmOperator *op)
}
image_save_options_from_op(bmain, &opts, op, NULL);
- if (BLI_exists(opts.filepath) && BLI_file_is_writable(opts.filepath)) {
- if (save_image_op(bmain, image, iuser, op, &opts)) {
- /* report since this can be called from key-shortcuts */
- BKE_reportf(op->reports, RPT_INFO, "Saved Image '%s'", opts.filepath);
- ok = true;
- }
- }
- else {
+ /* Check if file write permission is ok. */
+ if (BLI_exists(opts.filepath) && !BLI_file_is_writable(opts.filepath)) {
BKE_reportf(
- op->reports, RPT_ERROR, "Cannot save image, path '%s' is not writable", opts.filepath);
+ op->reports, RPT_ERROR, "Cannot save image, path \"%s\" is not writable", opts.filepath);
+ }
+ else if (save_image_op(bmain, image, iuser, op, &opts)) {
+ /* Report since this can be called from key shortcuts. */
+ BKE_reportf(op->reports, RPT_INFO, "Saved image \"%s\"", opts.filepath);
+ ok = true;
}
BKE_color_managed_view_settings_free(&opts.im_format.view_settings);
@@ -2147,8 +2125,11 @@ static int image_save_exec(bContext *C, wmOperator *op)
static int image_save_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Image *ima = image_from_context(C);
+ ImageUser *iuser = image_user_from_context(C);
- if (!BKE_image_has_packedfile(ima) && !BKE_image_has_filepath(ima)) {
+ /* Not writable formats or images without a file-path will go to "Save As". */
+ if (!BKE_image_has_packedfile(ima) &&
+ (!BKE_image_has_filepath(ima) || !image_file_format_writable(ima, iuser))) {
WM_operator_name_call(C, "IMAGE_OT_save_as", WM_OP_INVOKE_DEFAULT, NULL);
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/space_info/info_ops.c b/source/blender/editors/space_info/info_ops.c
index 0544a2cbefa..1435b95c9bf 100644
--- a/source/blender/editors/space_info/info_ops.c
+++ b/source/blender/editors/space_info/info_ops.c
@@ -516,7 +516,7 @@ void FILE_OT_find_missing_files(wmOperatorType *ot)
FILE_OPENFILE,
WM_FILESEL_DIRECTORY,
FILE_DEFAULTDISPLAY,
- FILE_SORT_ALPHA);
+ FILE_SORT_DEFAULT);
}
/********************* report box operator *********************/
diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c
index db8b6240558..bf21b383ba6 100644
--- a/source/blender/editors/space_info/info_stats.c
+++ b/source/blender/editors/space_info/info_stats.c
@@ -503,7 +503,7 @@ static void get_stats_string(
else if (obedit->type == OB_ARMATURE) {
*ofs += BLI_snprintf(info + *ofs,
len - *ofs,
- TIP_("Verts:%s/%s | Bones:%s/%s"),
+ TIP_("Joints:%s/%s | Bones:%s/%s"),
stats_fmt->totvertsel,
stats_fmt->totvert,
stats_fmt->totbonesel,
@@ -664,6 +664,7 @@ void ED_info_draw_stats(
EDGES,
FACES,
TRIS,
+ JOINTS,
BONES,
LAYERS,
FRAMES,
@@ -678,6 +679,7 @@ void ED_info_draw_stats(
STRNCPY(labels[EDGES], IFACE_("Edges"));
STRNCPY(labels[FACES], IFACE_("Faces"));
STRNCPY(labels[TRIS], IFACE_("Triangles"));
+ STRNCPY(labels[JOINTS], IFACE_("Joints"));
STRNCPY(labels[BONES], IFACE_("Bones"));
STRNCPY(labels[LAYERS], IFACE_("Layers"));
STRNCPY(labels[FRAMES], IFACE_("Frames"));
@@ -709,7 +711,7 @@ void ED_info_draw_stats(
stats_row(col1, labels[TRIS], col2, stats_fmt.tottri, NULL, y, height);
}
else if (obedit->type == OB_ARMATURE) {
- stats_row(col1, labels[VERTS], col2, stats_fmt.totvertsel, stats_fmt.totvert, y, height);
+ stats_row(col1, labels[JOINTS], col2, stats_fmt.totvertsel, stats_fmt.totvert, y, height);
stats_row(col1, labels[BONES], col2, stats_fmt.totbonesel, stats_fmt.totbone, y, height);
}
else {
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 66da2887427..16bbca2a0c3 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -748,6 +748,7 @@ static void node_shader_buts_vect_transform(uiLayout *layout, bContext *UNUSED(C
static void node_shader_buts_attribute(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
+ uiItemR(layout, ptr, "attribute_type", DEFAULT_FLAGS, IFACE_("Type"), ICON_NONE);
uiItemR(layout, ptr, "attribute_name", DEFAULT_FLAGS, IFACE_("Name"), ICON_NONE);
}
diff --git a/source/blender/editors/space_node/node_add.c b/source/blender/editors/space_node/node_add.c
index f8382a17c59..508c0a47e21 100644
--- a/source/blender/editors/space_node/node_add.c
+++ b/source/blender/editors/space_node/node_add.c
@@ -404,7 +404,7 @@ void NODE_OT_add_file(wmOperatorType *ot)
FILE_OPENFILE,
WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH,
FILE_DEFAULTDISPLAY,
- FILE_SORT_ALPHA);
+ FILE_SORT_DEFAULT);
RNA_def_string(ot->srna, "name", "Image", MAX_ID_NAME - 2, "Name", "Data-block name to assign");
}
diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h
index 04e452d5270..aa59b7293a3 100644
--- a/source/blender/editors/space_node/node_intern.h
+++ b/source/blender/editors/space_node/node_intern.h
@@ -266,7 +266,7 @@ extern const char *node_context_dir[];
#define NODE_SOCKDY (0.08f * U.widget_unit)
#define NODE_WIDTH(node) (node->width * UI_DPI_FAC)
#define NODE_HEIGHT(node) (node->height * UI_DPI_FAC)
-#define NODE_MARGIN_X (0.95f * U.widget_unit)
+#define NODE_MARGIN_X (1.10f * U.widget_unit)
#define NODE_SOCKSIZE (0.25f * U.widget_unit)
#define NODE_RESIZE_MARGIN (0.20f * U.widget_unit)
#define NODE_LINK_RESOL 12
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index c6b5f2e2d2b..beba1fc9e8d 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -27,12 +27,16 @@
#include "DNA_armature_types.h"
#include "DNA_collection_types.h"
+#include "DNA_constraint_types.h"
+#include "DNA_gpencil_modifier_types.h"
#include "DNA_gpencil_types.h"
#include "DNA_light_types.h"
#include "DNA_material_types.h"
+#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_sequence_types.h"
+#include "DNA_shader_fx_types.h"
#include "DNA_world_types.h"
#include "BLI_listbase.h"
@@ -40,21 +44,26 @@
#include "BKE_armature.h"
#include "BKE_collection.h"
+#include "BKE_constraint.h"
#include "BKE_context.h"
#include "BKE_gpencil.h"
+#include "BKE_gpencil_modifier.h"
#include "BKE_layer.h"
#include "BKE_main.h"
+#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_paint.h"
+#include "BKE_particle.h"
#include "BKE_report.h"
#include "BKE_scene.h"
-#include "BKE_sequencer.h"
+#include "BKE_shader_fx.h"
#include "BKE_workspace.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
#include "ED_armature.h"
+#include "ED_buttons.h"
#include "ED_gpencil.h"
#include "ED_object.h"
#include "ED_outliner.h"
@@ -63,6 +72,8 @@
#include "ED_sequencer.h"
#include "ED_undo.h"
+#include "SEQ_sequencer.h"
+
#include "WM_api.h"
#include "WM_toolsystem.h"
#include "WM_types.h"
@@ -812,15 +823,26 @@ static eOLDrawState tree_element_active_psys(bContext *C,
}
static int tree_element_active_constraint(bContext *C,
- Scene *UNUSED(scene),
- ViewLayer *UNUSED(sl),
- TreeElement *UNUSED(te),
+ Scene *scene,
+ ViewLayer *view_layer,
+ TreeElement *te,
TreeStoreElem *tselem,
const eOLSetState set)
{
if (set != OL_SETSEL_NONE) {
Object *ob = (Object *)tselem->id;
+ /* Activate the parent bone if this is a bone constraint. */
+ te = te->parent;
+ while (te) {
+ tselem = TREESTORE(te);
+ if (tselem->type == TSE_POSE_CHANNEL) {
+ tree_element_active_posechannel(C, scene, view_layer, ob, te, tselem, set, false);
+ return OL_DRAWSEL_NONE;
+ }
+ te = te->parent;
+ }
+
WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, ob);
}
@@ -1052,6 +1074,7 @@ eOLDrawState tree_element_type_active(bContext *C,
case TSE_POSE_CHANNEL:
return tree_element_active_posechannel(
C, tvc->scene, tvc->view_layer, tvc->ob_pose, te, tselem, set, recursive);
+ case TSE_CONSTRAINT_BASE:
case TSE_CONSTRAINT:
return tree_element_active_constraint(C, tvc->scene, tvc->view_layer, te, tselem, set);
case TSE_R_LAYER:
@@ -1092,6 +1115,169 @@ bPoseChannel *outliner_find_parent_bone(TreeElement *te, TreeElement **r_bone_te
return NULL;
}
+static void outliner_set_properties_tab(bContext *C, TreeElement *te, TreeStoreElem *tselem)
+{
+ PointerRNA ptr = {0};
+ int context = 0;
+
+ /* ID Types */
+ if (tselem->type == 0) {
+ RNA_id_pointer_create(tselem->id, &ptr);
+
+ switch (te->idcode) {
+ case ID_SCE:
+ context = BCONTEXT_SCENE;
+ break;
+ case ID_OB:
+ context = BCONTEXT_OBJECT;
+ break;
+ case ID_ME:
+ case ID_CU:
+ case ID_MB:
+ case ID_IM:
+ case ID_LT:
+ case ID_LA:
+ case ID_CA:
+ case ID_KE:
+ case ID_SPK:
+ case ID_AR:
+ case ID_GD:
+ case ID_LP:
+ case ID_HA:
+ case ID_PT:
+ case ID_VO:
+ context = BCONTEXT_DATA;
+ break;
+ case ID_MA:
+ context = BCONTEXT_MATERIAL;
+ break;
+ case ID_WO:
+ context = BCONTEXT_WORLD;
+ break;
+ }
+ }
+ else {
+ switch (tselem->type) {
+ case TSE_DEFGROUP_BASE:
+ case TSE_DEFGROUP:
+ RNA_id_pointer_create(tselem->id, &ptr);
+ context = BCONTEXT_DATA;
+ break;
+ case TSE_CONSTRAINT_BASE:
+ case TSE_CONSTRAINT: {
+ TreeElement *bone_te = NULL;
+ bPoseChannel *pchan = outliner_find_parent_bone(te, &bone_te);
+
+ if (pchan) {
+ RNA_pointer_create(TREESTORE(bone_te)->id, &RNA_PoseBone, pchan, &ptr);
+ context = BCONTEXT_BONE_CONSTRAINT;
+ }
+ else {
+ RNA_id_pointer_create(tselem->id, &ptr);
+ context = BCONTEXT_CONSTRAINT;
+ }
+
+ /* Expand the selected constraint in the properties editor. */
+ if (tselem->type != TSE_CONSTRAINT_BASE) {
+ BKE_constraint_panel_expand(te->directdata);
+ }
+ break;
+ }
+ case TSE_MODIFIER_BASE:
+ case TSE_MODIFIER:
+ RNA_id_pointer_create(tselem->id, &ptr);
+ context = BCONTEXT_MODIFIER;
+
+ if (tselem->type != TSE_MODIFIER_BASE) {
+ Object *ob = (Object *)tselem->id;
+
+ if (ob->type == OB_GPENCIL) {
+ BKE_gpencil_modifier_panel_expand(te->directdata);
+ }
+ else {
+ BKE_modifier_panel_expand(te->directdata);
+ }
+ }
+ break;
+ case TSE_GPENCIL_EFFECT_BASE:
+ case TSE_GPENCIL_EFFECT:
+ RNA_id_pointer_create(tselem->id, &ptr);
+ context = BCONTEXT_SHADERFX;
+
+ if (tselem->type != TSE_GPENCIL_EFFECT_BASE) {
+ BKE_shaderfx_panel_expand(te->directdata);
+ }
+ break;
+ case TSE_BONE: {
+ bArmature *arm = (bArmature *)tselem->id;
+ Bone *bone = te->directdata;
+
+ RNA_pointer_create(&arm->id, &RNA_Bone, bone, &ptr);
+ context = BCONTEXT_BONE;
+ break;
+ }
+ case TSE_EBONE: {
+ bArmature *arm = (bArmature *)tselem->id;
+ EditBone *ebone = te->directdata;
+
+ RNA_pointer_create(&arm->id, &RNA_EditBone, ebone, &ptr);
+ context = BCONTEXT_BONE;
+ break;
+ }
+ case TSE_POSE_CHANNEL: {
+ Object *ob = (Object *)tselem->id;
+ bArmature *arm = ob->data;
+ bPoseChannel *pchan = te->directdata;
+
+ RNA_pointer_create(&arm->id, &RNA_PoseBone, pchan, &ptr);
+ context = BCONTEXT_BONE;
+ break;
+ }
+ case TSE_POSE_BASE: {
+ Object *ob = (Object *)tselem->id;
+ bArmature *arm = ob->data;
+
+ RNA_pointer_create(&arm->id, &RNA_Armature, arm, &ptr);
+ context = BCONTEXT_DATA;
+ break;
+ }
+ case TSE_R_LAYER_BASE:
+ case TSE_R_LAYER: {
+ ViewLayer *view_layer = te->directdata;
+
+ RNA_pointer_create(tselem->id, &RNA_ViewLayer, view_layer, &ptr);
+ context = BCONTEXT_VIEW_LAYER;
+ break;
+ }
+ case TSE_POSEGRP_BASE:
+ case TSE_POSEGRP: {
+ Object *ob = (Object *)tselem->id;
+ bArmature *arm = ob->data;
+
+ RNA_pointer_create(&arm->id, &RNA_Armature, arm, &ptr);
+ context = BCONTEXT_DATA;
+ break;
+ }
+ case TSE_LINKED_PSYS: {
+ Object *ob = (Object *)tselem->id;
+ ParticleSystem *psys = psys_get_current(ob);
+
+ RNA_pointer_create(&ob->id, &RNA_ParticleSystem, psys, &ptr);
+ context = BCONTEXT_PARTICLE;
+ break;
+ }
+ case TSE_GP_LAYER:
+ RNA_id_pointer_create(tselem->id, &ptr);
+ context = BCONTEXT_DATA;
+ break;
+ }
+ }
+
+ if (ptr.data) {
+ ED_buttons_set_context(C, &ptr, context);
+ }
+}
+
/* ================================================ */
/**
@@ -1116,14 +1302,8 @@ static void do_outliner_item_activate_tree_element(bContext *C,
TSE_SEQUENCE_DUP,
TSE_EBONE,
TSE_LAYER_COLLECTION)) {
- /* Note about TSE_EBONE: In case of a same ID_AR datablock shared among several objects,
- * we do not want to switch out of edit mode (see T48328 for details). */
- }
- else if (tselem->id && OB_DATA_SUPPORT_EDITMODE(te->idcode)) {
- /* Support edit-mode toggle, keeping the active object as is. */
- }
- else if (tselem->type == TSE_POSE_BASE) {
- /* Support pose mode toggle, keeping the active object as is. */
+ /* Note about TSE_EBONE: In case of a same ID_AR datablock shared among several
+ * objects, we do not want to switch out of edit mode (see T48328 for details). */
}
else if (do_activate_data) {
tree_element_set_active_object(C,
@@ -1198,6 +1378,8 @@ static void do_outliner_item_activate_tree_element(bContext *C,
extend ? OL_SETSEL_EXTEND : OL_SETSEL_NORMAL,
recursive);
}
+
+ outliner_set_properties_tab(C, te, tselem);
}
/* Select the item using the set flags */
diff --git a/source/blender/editors/space_outliner/outliner_sync.c b/source/blender/editors/space_outliner/outliner_sync.c
index 3055d15725b..e1a96da1c91 100644
--- a/source/blender/editors/space_outliner/outliner_sync.c
+++ b/source/blender/editors/space_outliner/outliner_sync.c
@@ -39,7 +39,6 @@
#include "BKE_layer.h"
#include "BKE_main.h"
#include "BKE_object.h"
-#include "BKE_sequencer.h"
#include "DEG_depsgraph.h"
@@ -47,6 +46,8 @@
#include "ED_object.h"
#include "ED_outliner.h"
+#include "SEQ_sequencer.h"
+
#include "WM_api.h"
#include "WM_types.h"
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index cbdeb350ba4..159a4616ba7 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -65,7 +65,6 @@
#include "BKE_report.h"
#include "BKE_scene.h"
#include "BKE_screen.h"
-#include "BKE_sequencer.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
@@ -89,6 +88,8 @@
#include "RNA_define.h"
#include "RNA_enum_types.h"
+#include "SEQ_sequencer.h"
+
#include "outliner_intern.h"
/* -------------------------------------------------------------------- */
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index 4fbb394c38f..9cd38ac07f5 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -69,7 +69,6 @@
#include "BKE_main.h"
#include "BKE_modifier.h"
#include "BKE_outliner_treehash.h"
-#include "BKE_sequencer.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
@@ -81,6 +80,8 @@
#include "RNA_access.h"
+#include "SEQ_sequencer.h"
+
#include "UI_interface.h"
#include "outliner_intern.h"
@@ -2206,6 +2207,9 @@ static int outliner_exclude_filter_get(const SpaceOutliner *space_outliner)
case SO_FILTER_OB_ACTIVE:
exclude_filter |= SO_FILTER_OB_STATE_ACTIVE;
break;
+ case SO_FILTER_OB_SELECTABLE:
+ exclude_filter |= SO_FILTER_OB_STATE_SELECTABLE;
+ break;
}
return exclude_filter;
@@ -2288,6 +2292,11 @@ static bool outliner_element_visible_get(ViewLayer *view_layer,
return false;
}
}
+ else if (exclude_filter & SO_FILTER_OB_STATE_SELECTABLE) {
+ if ((base->flag & BASE_SELECTABLE) == 0) {
+ return false;
+ }
+ }
else {
BLI_assert(exclude_filter & SO_FILTER_OB_STATE_ACTIVE);
if (base != BASACT(view_layer)) {
diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c
index 0725109944a..7cf5218cfaa 100644
--- a/source/blender/editors/space_sequencer/sequencer_add.c
+++ b/source/blender/editors/space_sequencer/sequencer_add.c
@@ -43,7 +43,6 @@
#include "BKE_mask.h"
#include "BKE_movieclip.h"
#include "BKE_report.h"
-#include "BKE_sequencer.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -51,6 +50,8 @@
#include "RNA_define.h"
#include "RNA_enum_types.h"
+#include "SEQ_sequencer.h"
+
/* For menu, popup, icons, etc. */
#include "ED_screen.h"
#include "ED_sequencer.h"
@@ -724,7 +725,7 @@ void SEQUENCER_OT_movie_strip_add(struct wmOperatorType *ot)
WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH | WM_FILESEL_FILES |
WM_FILESEL_SHOW_PROPS | WM_FILESEL_DIRECTORY,
FILE_DEFAULTDISPLAY,
- FILE_SORT_ALPHA);
+ FILE_SORT_DEFAULT);
sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME);
RNA_def_boolean(ot->srna, "sound", true, "Sound", "Load sound with the movie");
RNA_def_boolean(ot->srna,
@@ -779,7 +780,7 @@ void SEQUENCER_OT_sound_strip_add(struct wmOperatorType *ot)
WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH | WM_FILESEL_FILES |
WM_FILESEL_SHOW_PROPS | WM_FILESEL_DIRECTORY,
FILE_DEFAULTDISPLAY,
- FILE_SORT_ALPHA);
+ FILE_SORT_DEFAULT);
sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME);
RNA_def_boolean(ot->srna, "cache", false, "Cache", "Cache the sound in memory");
RNA_def_boolean(ot->srna, "mono", false, "Mono", "Merge all the sound's channels into one");
@@ -971,7 +972,7 @@ void SEQUENCER_OT_image_strip_add(struct wmOperatorType *ot)
WM_FILESEL_DIRECTORY | WM_FILESEL_RELPATH | WM_FILESEL_FILES |
WM_FILESEL_SHOW_PROPS | WM_FILESEL_DIRECTORY,
FILE_DEFAULTDISPLAY,
- FILE_SORT_ALPHA);
+ FILE_SORT_DEFAULT);
sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME | SEQPROP_ENDFRAME);
RNA_def_boolean(ot->srna,
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index e9c5b003420..eb35cced95b 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -44,7 +44,6 @@
#include "BKE_fcurve.h"
#include "BKE_global.h"
#include "BKE_scene.h"
-#include "BKE_sequencer.h"
#include "BKE_sound.h"
#include "IMB_colormanagement.h"
@@ -69,6 +68,8 @@
#include "BIF_glutil.h"
+#include "SEQ_sequencer.h"
+
#include "UI_interface.h"
#include "UI_resources.h"
#include "UI_view2d.h"
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index 8a705ef49dd..e405864432a 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -43,9 +43,10 @@
#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_report.h"
-#include "BKE_sequencer.h"
#include "BKE_sound.h"
+#include "SEQ_sequencer.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -97,11 +98,11 @@ EnumPropertyItem sequencer_prop_effect_types[] = {
#define SEQ_SIDE_MOUSE -1
EnumPropertyItem prop_side_types[] = {
- {SEQ_SIDE_MOUSE, "MOUSE", 0, "Mouse position", ""},
+ {SEQ_SIDE_MOUSE, "MOUSE", 0, "Mouse Position", ""},
{SEQ_SIDE_LEFT, "LEFT", 0, "Left", ""},
{SEQ_SIDE_RIGHT, "RIGHT", 0, "Right", ""},
{SEQ_SIDE_BOTH, "BOTH", 0, "Both", ""},
- {SEQ_SIDE_NO_CHANGE, "NO_CHANGE", 0, "No change", ""},
+ {SEQ_SIDE_NO_CHANGE, "NO_CHANGE", 0, "No Change", ""},
{0, NULL, 0, NULL, NULL},
};
@@ -3918,7 +3919,7 @@ void SEQUENCER_OT_change_path(struct wmOperatorType *ot)
WM_FILESEL_DIRECTORY | WM_FILESEL_RELPATH | WM_FILESEL_FILEPATH |
WM_FILESEL_FILES,
FILE_DEFAULTDISPLAY,
- FILE_SORT_ALPHA);
+ FILE_SORT_DEFAULT);
RNA_def_boolean(ot->srna,
"use_placeholders",
false,
@@ -4063,7 +4064,7 @@ void SEQUENCER_OT_export_subtitles(struct wmOperatorType *ot)
FILE_SAVE,
WM_FILESEL_FILEPATH,
FILE_DEFAULTDISPLAY,
- FILE_SORT_ALPHA);
+ FILE_SORT_DEFAULT);
}
/** \} */
diff --git a/source/blender/editors/space_sequencer/sequencer_modifier.c b/source/blender/editors/space_sequencer/sequencer_modifier.c
index 50f2a5084ef..fb09afc6ca5 100644
--- a/source/blender/editors/space_sequencer/sequencer_modifier.c
+++ b/source/blender/editors/space_sequencer/sequencer_modifier.c
@@ -27,7 +27,6 @@
#include "DNA_scene_types.h"
#include "BKE_context.h"
-#include "BKE_sequencer.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -35,6 +34,8 @@
#include "RNA_define.h"
#include "RNA_enum_types.h"
+#include "SEQ_sequencer.h"
+
/* Own include. */
#include "sequencer_intern.h"
diff --git a/source/blender/editors/space_sequencer/sequencer_ops.c b/source/blender/editors/space_sequencer/sequencer_ops.c
index 0a7aa1a6072..bdf6e4ece7f 100644
--- a/source/blender/editors/space_sequencer/sequencer_ops.c
+++ b/source/blender/editors/space_sequencer/sequencer_ops.c
@@ -34,7 +34,7 @@
#include "ED_sequencer.h"
#include "ED_transform.h" /* Transform keymap. */
-#include "BKE_sequencer.h"
+#include "SEQ_sequencer.h"
#include "sequencer_intern.h"
diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c
index 0a4a1ae92d9..2af708494cb 100644
--- a/source/blender/editors/space_sequencer/sequencer_select.c
+++ b/source/blender/editors/space_sequencer/sequencer_select.c
@@ -33,13 +33,14 @@
#include "BKE_context.h"
#include "BKE_report.h"
-#include "BKE_sequencer.h"
#include "WM_api.h"
#include "WM_types.h"
#include "RNA_define.h"
+#include "SEQ_sequencer.h"
+
/* For menu, popup, icons, etc. */
#include "ED_outliner.h"
diff --git a/source/blender/editors/space_sequencer/sequencer_view.c b/source/blender/editors/space_sequencer/sequencer_view.c
index 491c475b596..75d92d5f00d 100644
--- a/source/blender/editors/space_sequencer/sequencer_view.c
+++ b/source/blender/editors/space_sequencer/sequencer_view.c
@@ -28,7 +28,6 @@
#include "DNA_scene_types.h"
#include "BKE_context.h"
-#include "BKE_sequencer.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -39,6 +38,8 @@
#include "RNA_define.h"
+#include "SEQ_sequencer.h"
+
/* For menu, popup, icons, etc. */
#include "ED_anim_api.h"
#include "ED_screen.h"
diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c
index 289477c8353..45c7bac54f8 100644
--- a/source/blender/editors/space_sequencer/space_sequencer.c
+++ b/source/blender/editors/space_sequencer/space_sequencer.c
@@ -38,7 +38,6 @@
#include "BKE_global.h"
#include "BKE_lib_id.h"
#include "BKE_screen.h"
-#include "BKE_sequencer.h"
#include "BKE_sequencer_offscreen.h"
#include "ED_screen.h"
@@ -52,6 +51,8 @@
#include "RNA_access.h"
+#include "SEQ_sequencer.h"
+
#include "UI_interface.h"
#include "UI_resources.h"
#include "UI_view2d.h"
diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c
index 5c7f84ea386..7c592519384 100644
--- a/source/blender/editors/space_text/text_ops.c
+++ b/source/blender/editors/space_text/text_ops.c
@@ -159,6 +159,15 @@ static bool text_new_poll(bContext *UNUSED(C))
return 1;
}
+static bool text_data_poll(bContext *C)
+{
+ Text *text = CTX_data_edit_text(C);
+ if (!text) {
+ return false;
+ }
+ return true;
+}
+
static bool text_edit_poll(bContext *C)
{
Text *text = CTX_data_edit_text(C);
@@ -407,9 +416,9 @@ void TEXT_OT_open(wmOperatorType *ot)
FILE_OPENFILE,
WM_FILESEL_FILEPATH,
FILE_DEFAULTDISPLAY,
- FILE_SORT_ALPHA); /* TODO: relative_path. */
+ FILE_SORT_DEFAULT); /* TODO: relative_path. */
RNA_def_boolean(
- ot->srna, "internal", 0, "Make internal", "Make text file internal after loading");
+ ot->srna, "internal", 0, "Make Internal", "Make text file internal after loading");
}
/** \} */
@@ -573,17 +582,6 @@ void TEXT_OT_make_internal(wmOperatorType *ot)
/** \name Save Operator
* \{ */
-static bool text_save_poll(bContext *C)
-{
- Text *text = CTX_data_edit_text(C);
-
- if (!text_edit_poll(C)) {
- return 0;
- }
-
- return (text->filepath != NULL && !(text->flags & TXT_ISMEM));
-}
-
static void txt_write_file(Main *bmain, Text *text, ReportList *reports)
{
FILE *fp;
@@ -594,6 +592,13 @@ static void txt_write_file(Main *bmain, Text *text, ReportList *reports)
BLI_strncpy(filepath, text->filepath, FILE_MAX);
BLI_path_abs(filepath, BKE_main_blendfile_path(bmain));
+ /* Check if file write permission is ok. */
+ if (BLI_exists(filepath) && !BLI_file_is_writable(filepath)) {
+ BKE_reportf(
+ reports, RPT_ERROR, "Cannot save text file, path \"%s\" is not writable", filepath);
+ return;
+ }
+
fp = BLI_fopen(filepath, "w");
if (fp == NULL) {
BKE_reportf(reports,
@@ -616,8 +621,8 @@ static void txt_write_file(Main *bmain, Text *text, ReportList *reports)
if (BLI_stat(filepath, &st) == 0) {
text->mtime = st.st_mtime;
- /* report since this can be called from key-shortcuts */
- BKE_reportf(reports, RPT_INFO, "Saved Text '%s'", filepath);
+ /* Report since this can be called from key shortcuts. */
+ BKE_reportf(reports, RPT_INFO, "Saved text \"%s\"", filepath);
}
else {
text->mtime = 0;
@@ -644,6 +649,18 @@ static int text_save_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
+static int text_save_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ Text *text = CTX_data_edit_text(C);
+
+ /* Internal and texts without a filepath will go to "Save As". */
+ if (text->filepath == NULL || (text->flags & TXT_ISMEM)) {
+ WM_operator_name_call(C, "TEXT_OT_save_as", WM_OP_INVOKE_DEFAULT, NULL);
+ return OPERATOR_CANCELLED;
+ }
+ return text_save_exec(C, op);
+}
+
void TEXT_OT_save(wmOperatorType *ot)
{
/* identifiers */
@@ -653,7 +670,8 @@ void TEXT_OT_save(wmOperatorType *ot)
/* api callbacks */
ot->exec = text_save_exec;
- ot->poll = text_save_poll;
+ ot->invoke = text_save_invoke;
+ ot->poll = text_edit_poll;
}
/** \} */
@@ -733,7 +751,7 @@ void TEXT_OT_save_as(wmOperatorType *ot)
FILE_SAVE,
WM_FILESEL_FILEPATH,
FILE_DEFAULTDISPLAY,
- FILE_SORT_ALPHA); /* XXX TODO, relative_path. */
+ FILE_SORT_DEFAULT); /* XXX TODO, relative_path. */
}
/** \} */
@@ -742,11 +760,6 @@ void TEXT_OT_save_as(wmOperatorType *ot)
/** \name Run Script Operator
* \{ */
-static bool text_run_script_poll(bContext *C)
-{
- return (CTX_data_edit_text(C) != NULL);
-}
-
static int text_run_script(bContext *C, ReportList *reports)
{
#ifdef WITH_PYTHON
@@ -808,7 +821,7 @@ void TEXT_OT_run_script(wmOperatorType *ot)
ot->description = "Run active script";
/* api callbacks */
- ot->poll = text_run_script_poll;
+ ot->poll = text_data_poll;
ot->exec = text_run_script_exec;
/* flags */
@@ -3693,7 +3706,7 @@ void TEXT_OT_replace(wmOperatorType *ot)
/* properties */
PropertyRNA *prop;
- prop = RNA_def_boolean(ot->srna, "all", false, "Replace all", "Replace all occurrences");
+ prop = RNA_def_boolean(ot->srna, "all", false, "Replace All", "Replace all occurrences");
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
}
@@ -3781,6 +3794,17 @@ static const EnumPropertyItem resolution_items[] = {
{0, NULL, 0, NULL, NULL},
};
+static bool text_resolve_conflict_poll(bContext *C)
+{
+ Text *text = CTX_data_edit_text(C);
+
+ if (!text_edit_poll(C)) {
+ return false;
+ }
+
+ return ((text->filepath != NULL) && !(text->flags & TXT_ISMEM));
+}
+
static int text_resolve_conflict_exec(bContext *C, wmOperator *op)
{
Text *text = CTX_data_edit_text(C);
@@ -3872,7 +3896,7 @@ void TEXT_OT_resolve_conflict(wmOperatorType *ot)
/* api callbacks */
ot->exec = text_resolve_conflict_exec;
ot->invoke = text_resolve_conflict_invoke;
- ot->poll = text_save_poll;
+ ot->poll = text_resolve_conflict_poll;
/* properties */
RNA_def_enum(ot->srna,
@@ -3891,7 +3915,7 @@ void TEXT_OT_resolve_conflict(wmOperatorType *ot)
static int text_to_3d_object_exec(bContext *C, wmOperator *op)
{
- Text *text = CTX_data_edit_text(C);
+ const Text *text = CTX_data_edit_text(C);
const bool split_lines = RNA_boolean_get(op->ptr, "split_lines");
ED_text_to_object(C, text, split_lines);
@@ -3908,7 +3932,7 @@ void TEXT_OT_to_3d_object(wmOperatorType *ot)
/* api callbacks */
ot->exec = text_to_3d_object_exec;
- ot->poll = text_edit_poll;
+ ot->poll = text_data_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index 8e03ed6e11d..f67eb73bbd1 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -283,7 +283,6 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
else if (ob->type == OB_CURVE || ob->type == OB_SURF) {
TransformMedian_Curve *median = &median_basis.curve;
Curve *cu = ob->data;
- Nurb *nu;
BPoint *bp;
BezTriple *bezt;
int a;
@@ -291,8 +290,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
StructRNA *seltype = NULL;
void *selp = NULL;
- nu = nurbs->first;
- while (nu) {
+ LISTBASE_FOREACH (Nurb *, nu, nurbs) {
if (nu->type == CU_BEZIER) {
bezt = nu->bezt;
a = nu->pntsu;
@@ -343,7 +341,6 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
bp++;
}
}
- nu = nu->next;
}
if (totcurvedata == 1) {
@@ -973,15 +970,13 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
const TransformMedian_Curve *median = &median_basis.curve,
*ve_median = &ve_median_basis.curve;
Curve *cu = ob->data;
- Nurb *nu;
BPoint *bp;
BezTriple *bezt;
int a;
ListBase *nurbs = BKE_curve_editNurbs_get(cu);
const float scale_w = compute_scale_factor(ve_median->weight, median->weight);
- nu = nurbs->first;
- while (nu) {
+ LISTBASE_FOREACH (Nurb *, nu, nurbs) {
if (nu->type == CU_BEZIER) {
for (a = nu->pntsu, bezt = nu->bezt; a--; bezt++) {
if (bezt->f2 & SELECT) {
@@ -1038,8 +1033,6 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
}
BKE_nurb_test_2d(nu);
BKE_nurb_handles_test(nu, true, false); /* test for bezier too */
-
- nu = nu->next;
}
}
else if ((ob->type == OB_LATTICE) && (apply_vcos || median_basis.lattice.weight)) {
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 633344837a1..d4c85eeb3d2 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -949,15 +949,16 @@ void ED_view3d_grid_steps(const Scene *scene,
* Currently the simulation is only done when RV3D_VIEW_IS_AXIS. */
float ED_view3d_grid_view_scale(Scene *scene,
View3D *v3d,
- RegionView3D *rv3d,
+ ARegion *region,
const char **r_grid_unit)
{
float grid_scale;
+ RegionView3D *rv3d = region->regiondata;
if (!rv3d->is_persp && RV3D_VIEW_IS_AXIS(rv3d->view)) {
/* Decrease the distance between grid snap points depending on zoom. */
/* `0.38` was a value visually obtained in order to get a snap distance
* that matches previous versions Blender.*/
- float min_dist = 0.38f * (rv3d->dist / v3d->lens);
+ float min_dist = 16.0f / (region->sizex * rv3d->winmat[0][0]);
float grid_steps[STEPS_LEN];
ED_view3d_grid_steps(scene, v3d, rv3d, grid_steps);
/* Skip last item, in case the 'mid_dist' is greater than the largest unit. */
@@ -1468,12 +1469,13 @@ static void draw_selected_name(
}
static void draw_grid_unit_name(
- Scene *scene, RegionView3D *rv3d, View3D *v3d, int xoffset, int *yoffset)
+ Scene *scene, ARegion *region, View3D *v3d, int xoffset, int *yoffset)
{
+ RegionView3D *rv3d = region->regiondata;
if (!rv3d->is_persp && RV3D_VIEW_IS_AXIS(rv3d->view)) {
const char *grid_unit = NULL;
int font_id = BLF_default();
- ED_view3d_grid_view_scale(scene, v3d, rv3d, &grid_unit);
+ ED_view3d_grid_view_scale(scene, v3d, region, &grid_unit);
if (grid_unit) {
char numstr[32] = "";
@@ -1558,7 +1560,7 @@ void view3d_draw_region_info(const bContext *C, ARegion *region)
if (v3d->gridflag & (V3D_SHOW_FLOOR | V3D_SHOW_X | V3D_SHOW_Y | V3D_SHOW_Z)) {
/* draw below the viewport name */
- draw_grid_unit_name(scene, rv3d, v3d, xoffset, &yoffset);
+ draw_grid_unit_name(scene, region, v3d, xoffset, &yoffset);
}
DRW_draw_region_engine_info(xoffset, &yoffset, VIEW3D_OVERLAY_LINEHEIGHT);
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index 7ec6bddd6a3..6e24dfd1db9 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -4828,7 +4828,7 @@ void VIEW3D_OT_background_image_add(wmOperatorType *ot)
FILE_OPENFILE,
WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH,
FILE_DEFAULTDISPLAY,
- FILE_SORT_ALPHA);
+ FILE_SORT_DEFAULT);
}
/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c
index 265cb04c7b2..148a0986c5c 100644
--- a/source/blender/editors/space_view3d/view3d_snap.c
+++ b/source/blender/editors/space_view3d/view3d_snap.c
@@ -73,14 +73,14 @@ static int snap_sel_to_grid_exec(bContext *C, wmOperator *UNUSED(op))
ViewLayer *view_layer_eval = DEG_get_evaluated_view_layer(depsgraph);
Object *obact = CTX_data_active_object(C);
Scene *scene = CTX_data_scene(C);
- RegionView3D *rv3d = CTX_wm_region_data(C);
+ ARegion *region = CTX_wm_region(C);
View3D *v3d = CTX_wm_view3d(C);
TransVertStore tvs = {NULL};
TransVert *tv;
float gridf, imat[3][3], bmat[3][3], vec[3];
int a;
- gridf = ED_view3d_grid_view_scale(scene, v3d, rv3d, NULL);
+ gridf = ED_view3d_grid_view_scale(scene, v3d, region, NULL);
if (OBEDIT_FROM_OBACT(obact)) {
ViewLayer *view_layer = CTX_data_view_layer(C);
@@ -657,11 +657,11 @@ void VIEW3D_OT_snap_selected_to_active(wmOperatorType *ot)
static int snap_curs_to_grid_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
- RegionView3D *rv3d = CTX_wm_region_data(C);
+ ARegion *region = CTX_wm_region(C);
View3D *v3d = CTX_wm_view3d(C);
float gridf, *curs;
- gridf = ED_view3d_grid_view_scale(scene, v3d, rv3d, NULL);
+ gridf = ED_view3d_grid_view_scale(scene, v3d, region, NULL);
curs = scene->cursor.location;
curs[0] = gridf * floorf(0.5f + curs[0] / gridf);
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 4e08b6b1c5d..9f4777a716d 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -646,12 +646,12 @@ wmKeyMap *transform_modal_keymap(wmKeyConfig *keyconf)
static const EnumPropertyItem modal_items[] = {
{TFM_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
{TFM_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""},
- {TFM_MODAL_AXIS_X, "AXIS_X", 0, "X axis", ""},
- {TFM_MODAL_AXIS_Y, "AXIS_Y", 0, "Y axis", ""},
- {TFM_MODAL_AXIS_Z, "AXIS_Z", 0, "Z axis", ""},
- {TFM_MODAL_PLANE_X, "PLANE_X", 0, "X plane", ""},
- {TFM_MODAL_PLANE_Y, "PLANE_Y", 0, "Y plane", ""},
- {TFM_MODAL_PLANE_Z, "PLANE_Z", 0, "Z plane", ""},
+ {TFM_MODAL_AXIS_X, "AXIS_X", 0, "X Axis", ""},
+ {TFM_MODAL_AXIS_Y, "AXIS_Y", 0, "Y Axis", ""},
+ {TFM_MODAL_AXIS_Z, "AXIS_Z", 0, "Z Axis", ""},
+ {TFM_MODAL_PLANE_X, "PLANE_X", 0, "X Plane", ""},
+ {TFM_MODAL_PLANE_Y, "PLANE_Y", 0, "Y Plane", ""},
+ {TFM_MODAL_PLANE_Z, "PLANE_Z", 0, "Z Plane", ""},
{TFM_MODAL_CONS_OFF, "CONS_OFF", 0, "Clear Constraints", ""},
{TFM_MODAL_SNAP_INV_ON, "SNAP_INV_ON", 0, "Snap Invert", ""},
{TFM_MODAL_SNAP_INV_OFF, "SNAP_INV_OFF", 0, "Snap Invert (Off)", ""},
@@ -672,13 +672,13 @@ wmKeyMap *transform_modal_keymap(wmKeyConfig *keyconf)
0,
"Decrease Max AutoIK Chain Length",
""},
- {TFM_MODAL_EDGESLIDE_UP, "EDGESLIDE_EDGE_NEXT", 0, "Select next Edge Slide Edge", ""},
- {TFM_MODAL_EDGESLIDE_DOWN, "EDGESLIDE_PREV_NEXT", 0, "Select previous Edge Slide Edge", ""},
+ {TFM_MODAL_EDGESLIDE_UP, "EDGESLIDE_EDGE_NEXT", 0, "Select Next Edge Slide Edge", ""},
+ {TFM_MODAL_EDGESLIDE_DOWN, "EDGESLIDE_PREV_NEXT", 0, "Select Previous Edge Slide Edge", ""},
{TFM_MODAL_PROPSIZE, "PROPORTIONAL_SIZE", 0, "Adjust Proportional Influence", ""},
{TFM_MODAL_INSERTOFS_TOGGLE_DIR,
"INSERTOFS_TOGGLE_DIR",
0,
- "Toggle Direction for Node Auto-offset",
+ "Toggle Direction for Node Auto-Offset",
""},
{TFM_MODAL_TRANSLATE, "TRANSLATE", 0, "Move", ""},
{TFM_MODAL_ROTATE, "ROTATE", 0, "Rotate", ""},
@@ -1626,11 +1626,9 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
static void initSnapSpatial(TransInfo *t, float r_snap[2])
{
if (t->spacetype == SPACE_VIEW3D) {
- RegionView3D *rv3d = t->region->regiondata;
-
- if (rv3d) {
+ if (t->region->regiondata) {
View3D *v3d = t->area->spacedata.first;
- r_snap[0] = ED_view3d_grid_view_scale(t->scene, v3d, rv3d, NULL) * 1.0f;
+ r_snap[0] = ED_view3d_grid_view_scale(t->scene, v3d, t->region, NULL) * 1.0f;
r_snap[1] = r_snap[0] * 0.1f;
}
}
diff --git a/source/blender/editors/transform/transform_convert_sequencer.c b/source/blender/editors/transform/transform_convert_sequencer.c
index 307fbbdf80b..3f86ef3e81b 100644
--- a/source/blender/editors/transform/transform_convert_sequencer.c
+++ b/source/blender/editors/transform/transform_convert_sequencer.c
@@ -29,10 +29,11 @@
#include "BKE_context.h"
#include "BKE_report.h"
-#include "BKE_sequencer.h"
#include "ED_markers.h"
+#include "SEQ_sequencer.h"
+
#include "UI_view2d.h"
#include "transform.h"
diff --git a/source/blender/editors/transform/transform_gizmo_2d.c b/source/blender/editors/transform/transform_gizmo_2d.c
index c40f3d3f140..09100bb50cc 100644
--- a/source/blender/editors/transform/transform_gizmo_2d.c
+++ b/source/blender/editors/transform/transform_gizmo_2d.c
@@ -53,7 +53,7 @@
/* -------------------------------------------------------------------- */
/** \name Shared Callback's
- */
+ * \{ */
static bool gizmo2d_generic_poll(const bContext *C, wmGizmoGroupType *gzgt)
{
diff --git a/source/blender/editors/transform/transform_mode.c b/source/blender/editors/transform/transform_mode.c
index c525bc0e6ea..67b3a16627f 100644
--- a/source/blender/editors/transform/transform_mode.c
+++ b/source/blender/editors/transform/transform_mode.c
@@ -520,9 +520,7 @@ static void constraintSizeLim(TransInfo *t, TransData *td)
}
/* -------------------------------------------------------------------- */
-/* Transform (Rotation Utils) */
-
-/** \name Transform Rotation Utils
+/** \name Transform (Rotation Utils)
* \{ */
/* Used by Transform Rotation and Transform Normal Rotation */
void headerRotation(TransInfo *t, char str[UI_MAX_DRAW_STR], float final)
@@ -815,9 +813,7 @@ void ElementRotation(
/** \} */
/* -------------------------------------------------------------------- */
-/* Transform (Resize Utils) */
-
-/** \name Transform Resize Utils
+/** \name Transform (Resize Utils)
* \{ */
void headerResize(TransInfo *t, const float vec[3], char str[UI_MAX_DRAW_STR])
{
@@ -1040,9 +1036,7 @@ void ElementResize(TransInfo *t, TransDataContainer *tc, TransData *td, float ma
/** \} */
/* -------------------------------------------------------------------- */
-/* Transform (Frame Utils) */
-
-/** \name Transform Frame Utils
+/** \name Transform (Frame Utils)
* \{ */
/**
diff --git a/source/blender/editors/transform/transform_mode_align.c b/source/blender/editors/transform/transform_mode_align.c
index 4fd4599b940..f16021914f1 100644
--- a/source/blender/editors/transform/transform_mode_align.c
+++ b/source/blender/editors/transform/transform_mode_align.c
@@ -35,9 +35,7 @@
#include "transform_mode.h"
/* -------------------------------------------------------------------- */
-/* Transform (Align) */
-
-/** \name Transform Align
+/** \name Transform (Align)
* \{ */
static void applyAlign(TransInfo *t, const int UNUSED(mval[2]))
diff --git a/source/blender/editors/transform/transform_mode_baketime.c b/source/blender/editors/transform/transform_mode_baketime.c
index 6470776e1a2..5efed6920dc 100644
--- a/source/blender/editors/transform/transform_mode_baketime.c
+++ b/source/blender/editors/transform/transform_mode_baketime.c
@@ -40,9 +40,7 @@
#include "transform_snap.h"
/* -------------------------------------------------------------------- */
-/* Transform (Bake-Time) */
-
-/** \name Transform Bake-Time
+/** \name Transform (Bake-Time)
* \{ */
static void applyBakeTime(TransInfo *t, const int mval[2])
diff --git a/source/blender/editors/transform/transform_mode_bbone_resize.c b/source/blender/editors/transform/transform_mode_bbone_resize.c
index 57e809a566a..e827e604327 100644
--- a/source/blender/editors/transform/transform_mode_bbone_resize.c
+++ b/source/blender/editors/transform/transform_mode_bbone_resize.c
@@ -41,9 +41,7 @@
#include "transform_snap.h"
/* -------------------------------------------------------------------- */
-/* Transform (EditBone (B-bone) width scaling) */
-
-/** \name Transform B-bone width scaling
+/** \name Transform (EditBone B-Bone width scaling)
* \{ */
static void headerBoneSize(TransInfo *t, const float vec[3], char str[UI_MAX_DRAW_STR])
diff --git a/source/blender/editors/transform/transform_mode_bend.c b/source/blender/editors/transform/transform_mode_bend.c
index ca22263712c..21a6a1ebafc 100644
--- a/source/blender/editors/transform/transform_mode_bend.c
+++ b/source/blender/editors/transform/transform_mode_bend.c
@@ -47,9 +47,7 @@
#include "transform_snap.h"
/* -------------------------------------------------------------------- */
-/* Transform (Bend) */
-
-/** \name Transform Bend
+/** \name Transform (Bend)
* \{ */
struct BendCustomData {
diff --git a/source/blender/editors/transform/transform_mode_boneenvelope.c b/source/blender/editors/transform/transform_mode_boneenvelope.c
index 1a25ee50543..ced159a76c9 100644
--- a/source/blender/editors/transform/transform_mode_boneenvelope.c
+++ b/source/blender/editors/transform/transform_mode_boneenvelope.c
@@ -40,9 +40,7 @@
#include "transform_snap.h"
/* -------------------------------------------------------------------- */
-/* Transform (Bone Envelope) */
-
-/** \name Transform Bone Envelope
+/** \name Transform (Bone Envelope)
* \{ */
static void applyBoneEnvelope(TransInfo *t, const int UNUSED(mval[2]))
diff --git a/source/blender/editors/transform/transform_mode_boneroll.c b/source/blender/editors/transform/transform_mode_boneroll.c
index cd277517d6b..da6c0b44c3a 100644
--- a/source/blender/editors/transform/transform_mode_boneroll.c
+++ b/source/blender/editors/transform/transform_mode_boneroll.c
@@ -40,9 +40,7 @@
#include "transform_snap.h"
/* -------------------------------------------------------------------- */
-/* Transform (EditBone Roll) */
-
-/** \name Transform EditBone Roll
+/** \name Transform (EditBone Roll)
* \{ */
static void applyBoneRoll(TransInfo *t, const int UNUSED(mval[2]))
diff --git a/source/blender/editors/transform/transform_mode_curveshrinkfatten.c b/source/blender/editors/transform/transform_mode_curveshrinkfatten.c
index 1935264d6d0..ee63bf4be6f 100644
--- a/source/blender/editors/transform/transform_mode_curveshrinkfatten.c
+++ b/source/blender/editors/transform/transform_mode_curveshrinkfatten.c
@@ -40,9 +40,7 @@
#include "transform_snap.h"
/* -------------------------------------------------------------------- */
-/* Transform (Curve Shrink/Fatten) */
-
-/** \name Transform Curve Shrink/Fatten
+/** \name Transform (Curve Shrink/Fatten)
* \{ */
static void applyCurveShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
diff --git a/source/blender/editors/transform/transform_mode_edge_bevelweight.c b/source/blender/editors/transform/transform_mode_edge_bevelweight.c
index 2f7707cdee4..3ce52ed3296 100644
--- a/source/blender/editors/transform/transform_mode_edge_bevelweight.c
+++ b/source/blender/editors/transform/transform_mode_edge_bevelweight.c
@@ -40,9 +40,7 @@
#include "transform_snap.h"
/* -------------------------------------------------------------------- */
-/* Transform (Bevel Weight) */
-
-/** \name Transform Bevel Weight
+/** \name Transform (Bevel Weight)
* \{ */
static void applyBevelWeight(TransInfo *t, const int UNUSED(mval[2]))
diff --git a/source/blender/editors/transform/transform_mode_edge_crease.c b/source/blender/editors/transform/transform_mode_edge_crease.c
index e2e0afc0a8f..23fa20b68ff 100644
--- a/source/blender/editors/transform/transform_mode_edge_crease.c
+++ b/source/blender/editors/transform/transform_mode_edge_crease.c
@@ -40,9 +40,7 @@
#include "transform_snap.h"
/* -------------------------------------------------------------------- */
-/* Transform (Crease) */
-
-/** \name Transform Crease
+/** \name Transform (Crease)
* \{ */
static void applyCrease(TransInfo *t, const int UNUSED(mval[2]))
diff --git a/source/blender/editors/transform/transform_mode_edge_rotate_normal.c b/source/blender/editors/transform/transform_mode_edge_rotate_normal.c
index 4b083a0529f..32f0d4bd365 100644
--- a/source/blender/editors/transform/transform_mode_edge_rotate_normal.c
+++ b/source/blender/editors/transform/transform_mode_edge_rotate_normal.c
@@ -39,9 +39,7 @@
#include "transform_snap.h"
/* -------------------------------------------------------------------- */
-/* Transform (Normal Rotation) */
-
-/** \name Transform Normal Rotation
+/** \name Transform (Normal Rotation)
* \{ */
static void storeCustomLNorValue(TransDataContainer *tc, BMesh *bm)
diff --git a/source/blender/editors/transform/transform_mode_edge_seq_slide.c b/source/blender/editors/transform/transform_mode_edge_seq_slide.c
index 5222d4d4e5a..dfa5c164acf 100644
--- a/source/blender/editors/transform/transform_mode_edge_seq_slide.c
+++ b/source/blender/editors/transform/transform_mode_edge_seq_slide.c
@@ -42,9 +42,7 @@
#include "transform_snap.h"
/* -------------------------------------------------------------------- */
-/* Transform (Sequencer Slide) */
-
-/** \name Transform Sequencer Slide
+/** \name Transform (Sequencer Slide)
* \{ */
static void headerSeqSlide(TransInfo *t, const float val[2], char str[UI_MAX_DRAW_STR])
diff --git a/source/blender/editors/transform/transform_mode_edge_slide.c b/source/blender/editors/transform/transform_mode_edge_slide.c
index c887b69c792..dae3fe6f7b4 100644
--- a/source/blender/editors/transform/transform_mode_edge_slide.c
+++ b/source/blender/editors/transform/transform_mode_edge_slide.c
@@ -56,9 +56,7 @@
#include "transform_snap.h"
/* -------------------------------------------------------------------- */
-/* Transform (Edge Slide) */
-
-/** \name Transform Edge Slide
+/** \name Transform (Edge Slide)
* \{ */
typedef struct TransDataEdgeSlideVert {
diff --git a/source/blender/editors/transform/transform_mode_gpopacity.c b/source/blender/editors/transform/transform_mode_gpopacity.c
index 5eb390d7cbd..103eb17c273 100644
--- a/source/blender/editors/transform/transform_mode_gpopacity.c
+++ b/source/blender/editors/transform/transform_mode_gpopacity.c
@@ -40,9 +40,7 @@
#include "transform_snap.h"
/* -------------------------------------------------------------------- */
-/* Transform (GPencil Opacity) */
-
-/** \name Transform GPencil Strokes Opacity
+/** \name Transform (GPencil Strokes Opacity)
* \{ */
static void applyGPOpacity(TransInfo *t, const int UNUSED(mval[2]))
diff --git a/source/blender/editors/transform/transform_mode_gpshrinkfatten.c b/source/blender/editors/transform/transform_mode_gpshrinkfatten.c
index 2d886b55a04..14e7c1df4f4 100644
--- a/source/blender/editors/transform/transform_mode_gpshrinkfatten.c
+++ b/source/blender/editors/transform/transform_mode_gpshrinkfatten.c
@@ -40,9 +40,7 @@
#include "transform_snap.h"
/* -------------------------------------------------------------------- */
-/* Transform (GPencil Shrink/Fatten) */
-
-/** \name Transform GPencil Strokes Shrink/Fatten
+/** \name Transform (GPencil Strokes Shrink/Fatten)
* \{ */
static void applyGPShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
diff --git a/source/blender/editors/transform/transform_mode_maskshrinkfatten.c b/source/blender/editors/transform/transform_mode_maskshrinkfatten.c
index 1c5b5000f5c..3019984d70b 100644
--- a/source/blender/editors/transform/transform_mode_maskshrinkfatten.c
+++ b/source/blender/editors/transform/transform_mode_maskshrinkfatten.c
@@ -40,9 +40,7 @@
#include "transform_snap.h"
/* -------------------------------------------------------------------- */
-/* Transform (Mask Shrink/Fatten) */
-
-/** \name Transform Mask Shrink/Fatten
+/** \name Transform (Mask Shrink/Fatten)
* \{ */
static void applyMaskShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
diff --git a/source/blender/editors/transform/transform_mode_mirror.c b/source/blender/editors/transform/transform_mode_mirror.c
index 8d953610eb8..1440553de51 100644
--- a/source/blender/editors/transform/transform_mode_mirror.c
+++ b/source/blender/editors/transform/transform_mode_mirror.c
@@ -38,9 +38,7 @@
#include "transform_mode.h"
/* -------------------------------------------------------------------- */
-/* Transform (Mirror) */
-
-/** \name Transform Mirror
+/** \name Transform (Mirror)
* \{ */
static void applyMirror(TransInfo *t, const int UNUSED(mval[2]))
diff --git a/source/blender/editors/transform/transform_mode_push_pull.c b/source/blender/editors/transform/transform_mode_push_pull.c
index 860dd51da94..8a92978f33f 100644
--- a/source/blender/editors/transform/transform_mode_push_pull.c
+++ b/source/blender/editors/transform/transform_mode_push_pull.c
@@ -41,9 +41,7 @@
#include "transform_snap.h"
/* -------------------------------------------------------------------- */
-/* Transform (Push/Pull) */
-
-/** \name Transform Push/Pull
+/** \name Transform (Push/Pull)
* \{ */
static void applyPushPull(TransInfo *t, const int UNUSED(mval[2]))
diff --git a/source/blender/editors/transform/transform_mode_resize.c b/source/blender/editors/transform/transform_mode_resize.c
index 33303b82567..62a4fbd6f04 100644
--- a/source/blender/editors/transform/transform_mode_resize.c
+++ b/source/blender/editors/transform/transform_mode_resize.c
@@ -39,9 +39,7 @@
#include "transform_snap.h"
/* -------------------------------------------------------------------- */
-/* Transform (Resize) */
-
-/** \name Transform Resize
+/** \name Transform (Resize)
* \{ */
static float ResizeBetween(TransInfo *t, const float p1[3], const float p2[3])
diff --git a/source/blender/editors/transform/transform_mode_rotate.c b/source/blender/editors/transform/transform_mode_rotate.c
index d8857dbc31e..856e71a0df6 100644
--- a/source/blender/editors/transform/transform_mode_rotate.c
+++ b/source/blender/editors/transform/transform_mode_rotate.c
@@ -37,9 +37,7 @@
#include "transform_snap.h"
/* -------------------------------------------------------------------- */
-/* Transform (Rotation) */
-
-/** \name Transform Rotation
+/** \name Transform (Rotation)
* \{ */
static float RotationBetween(TransInfo *t, const float p1[3], const float p2[3])
diff --git a/source/blender/editors/transform/transform_mode_shear.c b/source/blender/editors/transform/transform_mode_shear.c
index dfc6f69b341..a41c49710b9 100644
--- a/source/blender/editors/transform/transform_mode_shear.c
+++ b/source/blender/editors/transform/transform_mode_shear.c
@@ -44,9 +44,7 @@
#include "transform_snap.h"
/* -------------------------------------------------------------------- */
-/* Transform (Shear) */
-
-/** \name Transform Shear
+/** \name Transform (Shear)
* \{ */
static void initShear_mouseInputMode(TransInfo *t)
diff --git a/source/blender/editors/transform/transform_mode_shrink_fatten.c b/source/blender/editors/transform/transform_mode_shrink_fatten.c
index af33c2bb090..cdea388529f 100644
--- a/source/blender/editors/transform/transform_mode_shrink_fatten.c
+++ b/source/blender/editors/transform/transform_mode_shrink_fatten.c
@@ -42,9 +42,7 @@
#include "transform_snap.h"
/* -------------------------------------------------------------------- */
-/* Transform (Shrink-Fatten) */
-
-/** \name Transform Shrink-Fatten
+/** \name Transform (Shrink-Fatten)
* \{ */
static void applyShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
diff --git a/source/blender/editors/transform/transform_mode_skin_resize.c b/source/blender/editors/transform/transform_mode_skin_resize.c
index a1a6f0ce8f8..b4c919cbb86 100644
--- a/source/blender/editors/transform/transform_mode_skin_resize.c
+++ b/source/blender/editors/transform/transform_mode_skin_resize.c
@@ -38,9 +38,7 @@
#include "transform_snap.h"
/* -------------------------------------------------------------------- */
-/* Transform (Skin) */
-
-/** \name Transform Skin
+/** \name Transform (Skin)
* \{ */
static void applySkinResize(TransInfo *t, const int UNUSED(mval[2]))
diff --git a/source/blender/editors/transform/transform_mode_tilt.c b/source/blender/editors/transform/transform_mode_tilt.c
index 07e0e156803..d3b72fdf503 100644
--- a/source/blender/editors/transform/transform_mode_tilt.c
+++ b/source/blender/editors/transform/transform_mode_tilt.c
@@ -40,9 +40,7 @@
#include "transform_snap.h"
/* -------------------------------------------------------------------- */
-/* Transform (Tilt) */
-
-/** \name Transform Tilt
+/** \name Transform (Tilt)
* \{ */
static void applyTilt(TransInfo *t, const int UNUSED(mval[2]))
diff --git a/source/blender/editors/transform/transform_mode_timescale.c b/source/blender/editors/transform/transform_mode_timescale.c
index dbe06a6f1f6..7ae97c66660 100644
--- a/source/blender/editors/transform/transform_mode_timescale.c
+++ b/source/blender/editors/transform/transform_mode_timescale.c
@@ -42,9 +42,7 @@
#include "transform_mode.h"
/* -------------------------------------------------------------------- */
-/* Transform (Animation Time Scale) */
-
-/** \name Transform Animation Time Scale
+/** \name Transform (Animation Time Scale)
* \{ */
static void headerTimeScale(TransInfo *t, char str[UI_MAX_DRAW_STR])
diff --git a/source/blender/editors/transform/transform_mode_timeslide.c b/source/blender/editors/transform/transform_mode_timeslide.c
index 9636b4f6e42..34d3251f9cf 100644
--- a/source/blender/editors/transform/transform_mode_timeslide.c
+++ b/source/blender/editors/transform/transform_mode_timeslide.c
@@ -45,9 +45,7 @@
#include "transform_mode.h"
/* -------------------------------------------------------------------- */
-/* Transform (Animation Time Slide) */
-
-/** \name Transform Animation Time Slide
+/** \name Transform (Animation Time Slide)
* \{ */
static void headerTimeSlide(TransInfo *t, const float sval, char str[UI_MAX_DRAW_STR])
diff --git a/source/blender/editors/transform/transform_mode_timetranslate.c b/source/blender/editors/transform/transform_mode_timetranslate.c
index 226e8a377ea..adebc19c2b9 100644
--- a/source/blender/editors/transform/transform_mode_timetranslate.c
+++ b/source/blender/editors/transform/transform_mode_timetranslate.c
@@ -43,9 +43,7 @@
#include "transform_snap.h"
/* -------------------------------------------------------------------- */
-/* Transform (Animation Translation) */
-
-/** \name Transform Animation Translation
+/** \name Transform (Animation Translation)
* \{ */
static void headerTimeTranslate(TransInfo *t, char str[UI_MAX_DRAW_STR])
diff --git a/source/blender/editors/transform/transform_mode_tosphere.c b/source/blender/editors/transform/transform_mode_tosphere.c
index f49462ccc65..c7a278fe5ea 100644
--- a/source/blender/editors/transform/transform_mode_tosphere.c
+++ b/source/blender/editors/transform/transform_mode_tosphere.c
@@ -40,9 +40,7 @@
#include "transform_snap.h"
/* -------------------------------------------------------------------- */
-/* Transform (ToSphere) */
-
-/** \name Transform ToSphere
+/** \name Transform (ToSphere)
* \{ */
static void applyToSphere(TransInfo *t, const int UNUSED(mval[2]))
diff --git a/source/blender/editors/transform/transform_mode_trackball.c b/source/blender/editors/transform/transform_mode_trackball.c
index 32019e151a1..5a57a69f986 100644
--- a/source/blender/editors/transform/transform_mode_trackball.c
+++ b/source/blender/editors/transform/transform_mode_trackball.c
@@ -40,9 +40,7 @@
#include "transform_snap.h"
/* -------------------------------------------------------------------- */
-/* Transform (Rotation - Trackball) */
-
-/** \name Transform Rotation - Trackball
+/** \name Transform (Rotation - Trackball)
* \{ */
static void applyTrackballValue(TransInfo *t,
diff --git a/source/blender/editors/transform/transform_mode_translate.c b/source/blender/editors/transform/transform_mode_translate.c
index d4748e7933b..183fc8f5dc3 100644
--- a/source/blender/editors/transform/transform_mode_translate.c
+++ b/source/blender/editors/transform/transform_mode_translate.c
@@ -49,9 +49,7 @@
#include "transform_snap.h"
/* -------------------------------------------------------------------- */
-/* Transform (Translation) */
-
-/** \name Transform Translation
+/** \name Transform (Translation)
* \{ */
static void headerTranslation(TransInfo *t, const float vec[3], char str[UI_MAX_DRAW_STR])
diff --git a/source/blender/editors/transform/transform_mode_vert_slide.c b/source/blender/editors/transform/transform_mode_vert_slide.c
index 289ed76c731..1e5d027e253 100644
--- a/source/blender/editors/transform/transform_mode_vert_slide.c
+++ b/source/blender/editors/transform/transform_mode_vert_slide.c
@@ -53,9 +53,7 @@
#include "transform_snap.h"
/* -------------------------------------------------------------------- */
-/* Transform (Vert Slide) */
-
-/** \name Transform Vert Slide
+/** \name Transform (Vert Slide)
* \{ */
typedef struct TransDataVertSlideVert {
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index b164d0d443f..9f39099ea4b 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -825,6 +825,17 @@ static void TRANSFORM_OT_trackball(struct wmOperatorType *ot)
Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP | P_GPENCIL_EDIT | P_CENTER);
}
+/* Similar to #transform_shear_poll. */
+static bool transform_rotate_poll(bContext *C)
+{
+ if (!ED_operator_screenactive(C)) {
+ return false;
+ }
+
+ ScrArea *area = CTX_wm_area(C);
+ return area && !ELEM(area->spacetype, SPACE_ACTION);
+}
+
static void TRANSFORM_OT_rotate(struct wmOperatorType *ot)
{
/* identifiers */
@@ -838,7 +849,7 @@ static void TRANSFORM_OT_rotate(struct wmOperatorType *ot)
ot->exec = transform_exec;
ot->modal = transform_modal;
ot->cancel = transform_cancel;
- ot->poll = ED_operator_screenactive;
+ ot->poll = transform_rotate_poll;
ot->poll_property = transform_poll_property;
RNA_def_float_rotation(
@@ -902,6 +913,7 @@ static void TRANSFORM_OT_bend(struct wmOperatorType *ot)
Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP | P_GPENCIL_EDIT | P_CENTER);
}
+/* Similar to #transform_rotate_poll. */
static bool transform_shear_poll(bContext *C)
{
if (!ED_operator_screenactive(C)) {
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index e461bcb88e9..f1c4c243780 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -38,10 +38,11 @@
#include "BKE_layer.h"
#include "BKE_object.h"
#include "BKE_scene.h"
-#include "BKE_sequencer.h"
#include "RNA_access.h"
+#include "SEQ_sequencer.h"
+
#include "WM_types.h"
#include "ED_gizmo_library.h"
diff --git a/source/blender/editors/util/ed_util_imbuf.c b/source/blender/editors/util/ed_util_imbuf.c
index 9a2b346132e..9ae5cbbdfe9 100644
--- a/source/blender/editors/util/ed_util_imbuf.c
+++ b/source/blender/editors/util/ed_util_imbuf.c
@@ -30,7 +30,6 @@
#include "BKE_image.h"
#include "BKE_main.h"
#include "BKE_screen.h"
-#include "BKE_sequencer.h"
#include "ED_image.h"
#include "ED_screen.h"
@@ -43,6 +42,8 @@
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
+#include "SEQ_sequencer.h"
+
#include "UI_view2d.h"
#include "WM_api.h"