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_filter.c9
-rw-r--r--source/blender/editors/animation/time_scrub_ui.c44
-rw-r--r--source/blender/editors/armature/armature_edit.c20
-rw-r--r--source/blender/editors/armature/armature_relations.c30
-rw-r--r--source/blender/editors/armature/armature_select.c6
-rw-r--r--source/blender/editors/armature/armature_skinning.c4
-rw-r--r--source/blender/editors/armature/meshlaplacian.c5
-rw-r--r--source/blender/editors/curve/editcurve.c4
-rw-r--r--source/blender/editors/curve/editcurve_select.c4
-rw-r--r--source/blender/editors/curve/editfont.c8
-rw-r--r--source/blender/editors/datafiles/CMakeLists.txt1
-rw-r--r--source/blender/editors/gpencil/CMakeLists.txt1
-rw-r--r--source/blender/editors/gpencil/annotate_draw.c47
-rw-r--r--source/blender/editors/gpencil/annotate_paint.c480
-rw-r--r--source/blender/editors/gpencil/drawgpencil.c45
-rw-r--r--source/blender/editors/gpencil/editaction_gpencil.c130
-rw-r--r--source/blender/editors/gpencil/gpencil_add_stroke.c17
-rw-r--r--source/blender/editors/gpencil/gpencil_convert.c444
-rw-r--r--source/blender/editors/gpencil/gpencil_data.c208
-rw-r--r--source/blender/editors/gpencil/gpencil_edit.c374
-rw-r--r--source/blender/editors/gpencil/gpencil_fill.c134
-rw-r--r--source/blender/editors/gpencil/gpencil_intern.h104
-rw-r--r--source/blender/editors/gpencil/gpencil_interpolate.c62
-rw-r--r--source/blender/editors/gpencil/gpencil_merge.c20
-rw-r--r--source/blender/editors/gpencil/gpencil_mesh.c404
-rw-r--r--source/blender/editors/gpencil/gpencil_ops.c143
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c348
-rw-r--r--source/blender/editors/gpencil/gpencil_primitive.c132
-rw-r--r--source/blender/editors/gpencil/gpencil_sculpt_paint.c367
-rw-r--r--source/blender/editors/gpencil/gpencil_select.c236
-rw-r--r--source/blender/editors/gpencil/gpencil_utils.c267
-rw-r--r--source/blender/editors/gpencil/gpencil_uv.c4
-rw-r--r--source/blender/editors/gpencil/gpencil_vertex_ops.c58
-rw-r--r--source/blender/editors/gpencil/gpencil_vertex_paint.c134
-rw-r--r--source/blender/editors/gpencil/gpencil_weight_paint.c112
-rw-r--r--source/blender/editors/include/ED_anim_api.h25
-rw-r--r--source/blender/editors/include/ED_armature.h2
-rw-r--r--source/blender/editors/include/ED_curve.h2
-rw-r--r--source/blender/editors/include/ED_gpencil.h88
-rw-r--r--source/blender/editors/include/ED_mball.h8
-rw-r--r--source/blender/editors/include/ED_mesh.h13
-rw-r--r--source/blender/editors/include/ED_object.h10
-rw-r--r--source/blender/editors/include/ED_render.h2
-rw-r--r--source/blender/editors/include/ED_screen_types.h2
-rw-r--r--source/blender/editors/include/ED_time_scrub_ui.h5
-rw-r--r--source/blender/editors/include/UI_interface.h15
-rw-r--r--source/blender/editors/include/UI_interface_icons.h1
-rw-r--r--source/blender/editors/include/UI_view2d.h7
-rw-r--r--source/blender/editors/interface/interface.c4
-rw-r--r--source/blender/editors/interface/interface_context_menu.c2
-rw-r--r--source/blender/editors/interface/interface_draw.c278
-rw-r--r--source/blender/editors/interface/interface_handlers.c162
-rw-r--r--source/blender/editors/interface/interface_icons.c20
-rw-r--r--source/blender/editors/interface/interface_intern.h5
-rw-r--r--source/blender/editors/interface/interface_layout.c1
-rw-r--r--source/blender/editors/interface/interface_ops.c10
-rw-r--r--source/blender/editors/interface/interface_panel.c188
-rw-r--r--source/blender/editors/interface/interface_region_menu_popup.c14
-rw-r--r--source/blender/editors/interface/interface_region_search.c11
-rw-r--r--source/blender/editors/interface/interface_region_tooltip.c2
-rw-r--r--source/blender/editors/interface/interface_templates.c813
-rw-r--r--source/blender/editors/interface/interface_utils.c23
-rw-r--r--source/blender/editors/interface/interface_widgets.c250
-rw-r--r--source/blender/editors/interface/view2d.c94
-rw-r--r--source/blender/editors/interface/view2d_ops.c24
-rw-r--r--source/blender/editors/io/io_alembic.c8
-rw-r--r--source/blender/editors/io/io_collada.c1
-rw-r--r--source/blender/editors/mesh/editmesh_bevel.c109
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c10
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c11
-rw-r--r--source/blender/editors/mesh/mesh_data.c178
-rw-r--r--source/blender/editors/mesh/mesh_intern.h2
-rw-r--r--source/blender/editors/mesh/mesh_ops.c6
-rw-r--r--source/blender/editors/mesh/meshtools.c10
-rw-r--r--source/blender/editors/metaball/mball_edit.c115
-rw-r--r--source/blender/editors/object/CMakeLists.txt4
-rw-r--r--source/blender/editors/object/object_add.c237
-rw-r--r--source/blender/editors/object/object_constraint.c71
-rw-r--r--source/blender/editors/object/object_data_transfer.c12
-rw-r--r--source/blender/editors/object/object_edit.c33
-rw-r--r--source/blender/editors/object/object_facemap_ops.c7
-rw-r--r--source/blender/editors/object/object_gpencil_modifier.c230
-rw-r--r--source/blender/editors/object/object_intern.h8
-rw-r--r--source/blender/editors/object/object_modes.c2
-rw-r--r--source/blender/editors/object/object_modifier.c166
-rw-r--r--source/blender/editors/object/object_ops.c5
-rw-r--r--source/blender/editors/object/object_relations.c292
-rw-r--r--source/blender/editors/object/object_remesh.c20
-rw-r--r--source/blender/editors/object/object_shader_fx.c98
-rw-r--r--source/blender/editors/object/object_shapekey.c32
-rw-r--r--source/blender/editors/object/object_transform.c50
-rw-r--r--source/blender/editors/object/object_vgroup.c255
-rw-r--r--source/blender/editors/physics/particle_edit.c2
-rw-r--r--source/blender/editors/physics/physics_fluid.c26
-rw-r--r--source/blender/editors/physics/physics_pointcache.c2
-rw-r--r--source/blender/editors/render/render_update.c4
-rw-r--r--source/blender/editors/scene/scene_edit.c2
-rw-r--r--source/blender/editors/screen/area.c33
-rw-r--r--source/blender/editors/screen/screen_edit.c1
-rw-r--r--source/blender/editors/screen/screen_ops.c129
-rw-r--r--source/blender/editors/screen/workspace_layout_edit.c2
-rw-r--r--source/blender/editors/sculpt_paint/CMakeLists.txt2
-rw-r--r--source/blender/editors/sculpt_paint/paint_cursor.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c4
-rw-r--r--source/blender/editors/sculpt_paint/paint_mask.c13
-rw-r--r--source/blender/editors/sculpt_paint/paint_ops.c20
-rw-r--r--source/blender/editors/sculpt_paint/paint_stroke.c5
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex.c12
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c687
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_cloth.c40
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_detail.c2
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_face_set.c10
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_filter_color.c323
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_filter_mask.c10
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_filter_mesh.c17
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_intern.h40
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_mask_expand.c10
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c4
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_paint_color.c477
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_pose.c26
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_smooth.c50
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_transform.c11
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_undo.c68
-rw-r--r--source/blender/editors/sound/sound_ops.c5
-rw-r--r--source/blender/editors/space_action/action_edit.c22
-rw-r--r--source/blender/editors/space_action/action_select.c18
-rw-r--r--source/blender/editors/space_action/space_action.c30
-rw-r--r--source/blender/editors/space_buttons/CMakeLists.txt4
-rw-r--r--source/blender/editors/space_buttons/buttons_context.c6
-rw-r--r--source/blender/editors/space_buttons/space_buttons.c19
-rw-r--r--source/blender/editors/space_clip/clip_dopesheet_draw.c4
-rw-r--r--source/blender/editors/space_clip/clip_ops.c2
-rw-r--r--source/blender/editors/space_clip/space_clip.c12
-rw-r--r--source/blender/editors/space_console/space_console.c7
-rw-r--r--source/blender/editors/space_file/filelist.c2
-rw-r--r--source/blender/editors/space_file/space_file.c5
-rw-r--r--source/blender/editors/space_graph/space_graph.c32
-rw-r--r--source/blender/editors/space_image/image_edit.c2
-rw-r--r--source/blender/editors/space_image/image_ops.c30
-rw-r--r--source/blender/editors/space_info/space_info.c7
-rw-r--r--source/blender/editors/space_nla/nla_buttons.c4
-rw-r--r--source/blender/editors/space_nla/space_nla.c27
-rw-r--r--source/blender/editors/space_node/CMakeLists.txt4
-rw-r--r--source/blender/editors/space_node/drawnode.c38
-rw-r--r--source/blender/editors/space_node/node_draw.c7
-rw-r--r--source/blender/editors/space_node/node_edit.c6
-rw-r--r--source/blender/editors/space_node/space_node.c5
-rw-r--r--source/blender/editors/space_outliner/outliner_collections.c3
-rw-r--r--source/blender/editors/space_outliner/outliner_dragdrop.c3
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c59
-rw-r--r--source/blender/editors/space_outliner/outliner_edit.c30
-rw-r--r--source/blender/editors/space_outliner/outliner_intern.h29
-rw-r--r--source/blender/editors/space_outliner/outliner_select.c305
-rw-r--r--source/blender/editors/space_outliner/outliner_sync.c29
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.c216
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c30
-rw-r--r--source/blender/editors/space_outliner/outliner_utils.c41
-rw-r--r--source/blender/editors/space_outliner/space_outliner.c9
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c20
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c26
-rw-r--r--source/blender/editors/space_sequencer/sequencer_intern.h1
-rw-r--r--source/blender/editors/space_sequencer/sequencer_select.c22
-rw-r--r--source/blender/editors/space_sequencer/space_sequencer.c7
-rw-r--r--source/blender/editors/space_text/text_ops.c85
-rw-r--r--source/blender/editors/space_view3d/view3d_camera_control.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c3
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_fly.c30
-rw-r--r--source/blender/editors/space_view3d/view3d_header.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_placement.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_project.c6
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_snap.c8
-rw-r--r--source/blender/editors/space_view3d/view3d_utils.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_walk.c31
-rw-r--r--source/blender/editors/transform/transform.c63
-rw-r--r--source/blender/editors/transform/transform_constraints.c164
-rw-r--r--source/blender/editors/transform/transform_constraints.h6
-rw-r--r--source/blender/editors/transform/transform_convert.c45
-rw-r--r--source/blender/editors/transform/transform_convert.h2
-rw-r--r--source/blender/editors/transform/transform_convert_armature.c33
-rw-r--r--source/blender/editors/transform/transform_convert_curve.c2
-rw-r--r--source/blender/editors/transform/transform_convert_mask.c2
-rw-r--r--source/blender/editors/transform/transform_convert_mesh.c929
-rw-r--r--source/blender/editors/transform/transform_data.h4
-rw-r--r--source/blender/editors/transform/transform_generics.c64
-rw-r--r--source/blender/editors/transform/transform_mode.c40
-rw-r--r--source/blender/editors/transform/transform_mode.h4
-rw-r--r--source/blender/editors/transform/transform_mode_bbone_resize.c5
-rw-r--r--source/blender/editors/transform/transform_mode_boneenvelope.c1
-rw-r--r--source/blender/editors/transform/transform_mode_edge_slide.c323
-rw-r--r--source/blender/editors/transform/transform_mode_resize.c35
-rw-r--r--source/blender/editors/transform/transform_mode_rotate.c63
-rw-r--r--source/blender/editors/transform/transform_mode_translate.c31
-rw-r--r--source/blender/editors/transform/transform_mode_vert_slide.c38
-rw-r--r--source/blender/editors/transform/transform_ops.c4
-rw-r--r--source/blender/editors/transform/transform_snap.c259
-rw-r--r--source/blender/editors/transform/transform_snap.h2
-rw-r--r--source/blender/editors/transform/transform_snap_object.c114
-rw-r--r--source/blender/editors/uvedit/uvedit_draw.c98
201 files changed, 8756 insertions, 5373 deletions
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index bd83bdae31b..9564b662b12 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -3414,12 +3414,13 @@ static size_t animdata_filter_remove_duplis(ListBase *anim_data)
/* ----------- Public API --------------- */
-/* This function filters the active data source to leave only animation channels suitable for
+/**
+ * This function filters the active data source to leave only animation channels suitable for
* usage by the caller. It will return the length of the list
*
- * *anim_data: is a pointer to a ListBase, to which the filtered animation channels
- * will be placed for use.
- * filter_mode: how should the data be filtered - bitmapping accessed flags
+ * \param anim_data: Is a pointer to a #ListBase,
+ * to which the filtered animation channels will be placed for use.
+ * \param filter_mode: how should the data be filtered - bit-mapping accessed flags.
*/
size_t ANIM_animdata_filter(bAnimContext *ac,
ListBase *anim_data,
diff --git a/source/blender/editors/animation/time_scrub_ui.c b/source/blender/editors/animation/time_scrub_ui.c
index 863f433c778..edc36326c57 100644
--- a/source/blender/editors/animation/time_scrub_ui.c
+++ b/source/blender/editors/animation/time_scrub_ui.c
@@ -92,7 +92,9 @@ static void draw_current_frame(const Scene *scene,
bool display_seconds,
const View2D *v2d,
const rcti *scrub_region_rect,
- int current_frame)
+ int current_frame,
+ float sub_frame,
+ bool draw_line)
{
const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
int frame_x = UI_view2d_view_to_region_x(v2d, current_frame);
@@ -106,6 +108,22 @@ static void draw_current_frame(const Scene *scene,
float bg_color[4];
UI_GetThemeColorShade4fv(TH_CFRAME, -5, bg_color);
+ if (draw_line) {
+ /* Draw vertical line to from the bottom of the current frame box to the bottom of the screen.
+ */
+ const float subframe_x = UI_view2d_view_to_region_x(v2d, current_frame + sub_frame);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformThemeColor(TH_CFRAME);
+ immRectf(pos,
+ subframe_x - U.pixelsize,
+ scrub_region_rect->ymax - box_padding,
+ subframe_x + U.pixelsize,
+ 0.0f);
+ immUnbindProgram();
+ }
+
UI_draw_roundbox_corner_set(UI_CNR_ALL);
UI_draw_roundbox_3fv_alpha(true,
@@ -135,6 +153,28 @@ static void draw_current_frame(const Scene *scene,
text_color);
}
+void ED_time_scrub_draw_current_frame(const ARegion *region,
+ const Scene *scene,
+ bool display_seconds,
+ bool draw_line)
+{
+ const View2D *v2d = &region->v2d;
+ GPU_matrix_push_projection();
+ wmOrtho2_region_pixelspace(region);
+
+ rcti scrub_region_rect;
+ get_time_scrub_region_rect(region, &scrub_region_rect);
+
+ draw_current_frame(scene,
+ display_seconds,
+ v2d,
+ &scrub_region_rect,
+ scene->r.cfra,
+ scene->r.subframe,
+ draw_line);
+ GPU_matrix_pop_projection();
+}
+
void ED_time_scrub_draw(const ARegion *region,
const Scene *scene,
bool display_seconds,
@@ -161,8 +201,6 @@ void ED_time_scrub_draw(const ARegion *region,
region, v2d, &numbers_rect, scene, display_seconds, TH_TEXT);
}
- draw_current_frame(scene, display_seconds, v2d, &scrub_region_rect, scene->r.cfra);
-
GPU_matrix_pop_projection();
}
diff --git a/source/blender/editors/armature/armature_edit.c b/source/blender/editors/armature/armature_edit.c
index a7a705a6202..a010fbd5e81 100644
--- a/source/blender/editors/armature/armature_edit.c
+++ b/source/blender/editors/armature/armature_edit.c
@@ -140,7 +140,16 @@ void ED_armature_origin_set(
mul_m4_v3(ob->imat, cent);
}
else {
- if (around == V3D_AROUND_CENTER_MEDIAN) {
+ if (around == V3D_AROUND_CENTER_BOUNDS) {
+ float min[3], max[3];
+ INIT_MINMAX(min, max);
+ for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
+ minmax_v3v3_v3(min, max, ebone->head);
+ minmax_v3v3_v3(min, max, ebone->tail);
+ }
+ mid_v3_v3v3(cent, min, max);
+ }
+ else { /* #V3D_AROUND_CENTER_MEDIAN. */
int total = 0;
zero_v3(cent);
for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
@@ -152,15 +161,6 @@ void ED_armature_origin_set(
mul_v3_fl(cent, 1.0f / (float)total);
}
}
- else {
- float min[3], max[3];
- INIT_MINMAX(min, max);
- for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
- minmax_v3v3_v3(min, max, ebone->head);
- minmax_v3v3_v3(min, max, ebone->tail);
- }
- mid_v3_v3v3(cent, min, max);
- }
}
/* Do the adjustments */
diff --git a/source/blender/editors/armature/armature_relations.c b/source/blender/editors/armature/armature_relations.c
index d3d00fc44f2..f90d781baca 100644
--- a/source/blender/editors/armature/armature_relations.c
+++ b/source/blender/editors/armature/armature_relations.c
@@ -270,7 +270,7 @@ static void joined_armature_fix_links(
}
/* join armature exec is exported for use in object->join objects operator... */
-int join_armature_exec(bContext *C, wmOperator *op)
+int ED_armature_join_objects_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
@@ -304,10 +304,10 @@ int join_armature_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- /* Get editbones of active armature to add editbones to */
+ /* Get edit-bones of active armature to add edit-bones to */
ED_armature_to_edit(arm);
- /* get pose of active object and move it out of posemode */
+ /* Get pose of active object and move it out of pose-mode */
pose = ob_active->pose;
ob_active->mode &= ~OB_MODE_POSE;
@@ -325,7 +325,7 @@ int join_armature_exec(bContext *C, wmOperator *op)
afd.tarArm = ob_active;
afd.names_map = BLI_ghash_str_new("join_armature_adt_fix");
- /* Make a list of editbones in current armature */
+ /* Make a list of edit-bones in current armature */
ED_armature_to_edit(ob_iter->data);
/* Get Pose of current armature */
@@ -549,7 +549,7 @@ static void separated_armature_fix_links(Main *bmain, Object *origArm, Object *n
/* Helper function for armature separating - remove certain bones from the given armature
* sel: remove selected bones from the armature, otherwise the unselected bones are removed
- * (ob is not in editmode)
+ * (ob is not in edit-mode)
*/
static void separate_armature_bones(Main *bmain, Object *ob, const bool is_select)
{
@@ -557,7 +557,7 @@ static void separate_armature_bones(Main *bmain, Object *ob, const bool is_selec
bPoseChannel *pchan, *pchann;
EditBone *curbone;
- /* make local set of editbones to manipulate here */
+ /* make local set of edit-bones to manipulate here */
ED_armature_to_edit(arm);
/* go through pose-channels, checking if a bone should be removed */
@@ -591,7 +591,7 @@ static void separate_armature_bones(Main *bmain, Object *ob, const bool is_selec
}
}
- /* free any of the extra-data this pchan might have */
+ /* Free any of the extra-data this pchan might have. */
BKE_pose_channel_free(pchan);
BKE_pose_channels_hash_free(ob->pose);
@@ -601,7 +601,7 @@ static void separate_armature_bones(Main *bmain, Object *ob, const bool is_selec
}
}
- /* exit editmode (recalculates pchans too) */
+ /* Exit edit-mode (recalculates pose-channels too). */
ED_armature_edit_deselect_all(ob);
ED_armature_from_edit(bmain, ob->data);
ED_armature_edit_free(ob->data);
@@ -652,15 +652,15 @@ static int separate_armature_exec(bContext *C, wmOperator *op)
}
/* We are going to do this as follows (unlike every other instance of separate):
- * 1. Exit editmode +posemode for active armature/base. Take note of what this is.
+ * 1. Exit edit-mode & pose-mode for active armature/base. Take note of what this is.
* 2. Duplicate base - BASACT is the new one now
* 3. For each of the two armatures,
- * enter editmode -> remove appropriate bones -> exit editmode + recalc.
+ * enter edit-mode -> remove appropriate bones -> exit edit-mode + recalculate.
* 4. Fix constraint links
- * 5. Make original armature active and enter editmode
+ * 5. Make original armature active and enter edit-mode
*/
- /* 1) store starting settings and exit editmode */
+ /* 1) store starting settings and exit edit-mode */
ob_old->mode &= ~OB_MODE_POSE;
ED_armature_from_edit(bmain, ob_old->data);
@@ -700,7 +700,7 @@ static int separate_armature_exec(bContext *C, wmOperator *op)
}
MEM_freeN(bases);
- /* recalc/redraw + cleanup */
+ /* Recalculate/redraw + cleanup */
WM_cursor_wait(0);
if (ok) {
@@ -754,7 +754,7 @@ static void bone_connect_to_new_parent(ListBase *edbo,
float offset[3];
if ((selbone->parent) && (selbone->flag & BONE_CONNECTED)) {
- selbone->parent->flag &= ~(BONE_TIPSEL);
+ selbone->parent->flag &= ~BONE_TIPSEL;
}
/* make actbone the parent of selbone */
@@ -956,7 +956,7 @@ static void editbone_clear_parent(EditBone *ebone, int mode)
{
if (ebone->parent) {
/* for nice selection */
- ebone->parent->flag &= ~(BONE_TIPSEL);
+ ebone->parent->flag &= ~BONE_TIPSEL;
}
if (mode == 1) {
diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c
index eb7c1bc74ea..ccd39429704 100644
--- a/source/blender/editors/armature/armature_select.c
+++ b/source/blender/editors/armature/armature_select.c
@@ -188,7 +188,7 @@ static void *ed_armature_pick_bone_from_selectbuffer_impl(const bool is_editmode
Base *base = NULL;
bool sel;
- hitresult &= ~(BONESEL_ANY);
+ hitresult &= ~BONESEL_ANY;
/* Determine what the current bone is */
if (is_editmode == false) {
base = ED_armature_base_and_pchan_from_select_buffer(bases, bases_len, hitresult, &pchan);
@@ -1302,7 +1302,7 @@ static int armature_de_select_all_exec(bContext *C, wmOperator *op)
if ((ebone->flag & BONE_UNSELECTABLE) == 0) {
ebone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
if (ebone->parent) {
- ebone->parent->flag |= (BONE_TIPSEL);
+ ebone->parent->flag |= BONE_TIPSEL;
}
}
break;
@@ -1317,7 +1317,7 @@ static int armature_de_select_all_exec(bContext *C, wmOperator *op)
if ((ebone->flag & BONE_UNSELECTABLE) == 0) {
ebone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
if (ebone->parent) {
- ebone->parent->flag |= (BONE_TIPSEL);
+ ebone->parent->flag |= BONE_TIPSEL;
}
}
}
diff --git a/source/blender/editors/armature/armature_skinning.c b/source/blender/editors/armature/armature_skinning.c
index 61d8856afbc..b3c58f2575b 100644
--- a/source/blender/editors/armature/armature_skinning.c
+++ b/source/blender/editors/armature/armature_skinning.c
@@ -283,11 +283,11 @@ static void add_verts_to_dgroups(ReportList *reports,
* weights, either through envelopes or using a heat equilibrium.
*
* This function can be called both when parenting a mesh to an armature,
- * or in weightpaint + posemode. In the latter case selection is taken
+ * or in weight-paint + pose-mode. In the latter case selection is taken
* into account and vertex weights can be mirrored.
*
* The mesh vertex positions used are either the final deformed coords
- * from the evaluated mesh in weightpaint mode, the final subsurf coords
+ * from the evaluated mesh in weight-paint mode, the final sub-surface coords
* when parenting, or simply the original mesh coords.
*/
diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c
index d8a6a22a7df..145071522ed 100644
--- a/source/blender/editors/armature/meshlaplacian.c
+++ b/source/blender/editors/armature/meshlaplacian.c
@@ -94,9 +94,8 @@ struct LaplacianSystem {
float (*verts)[3]; /* vertex coordinates */
float (*vnors)[3]; /* vertex normals */
- float (*root)[3]; /* bone root */
- float (*tip)[3]; /* bone tip */
- float (*source)[3]; /* vertex source */
+ float (*root)[3]; /* bone root */
+ float (*tip)[3]; /* bone tip */
int numsource;
float *H; /* diagonal H matrix */
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 4e1c07af001..a39c8261b32 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -1432,7 +1432,7 @@ static int separate_exec(bContext *C, wmOperator *op)
/* 2. Duplicate the object and data. */
/* Take into account user preferences for duplicating actions. */
- short dupflag = (U.dupflag & USER_DUP_ACT);
+ const eDupli_ID_Flags dupflag = (U.dupflag & USER_DUP_ACT);
newbase = ED_object_add_duplicate(bmain, scene, view_layer, oldbase, dupflag);
DEG_relations_tag_update(bmain);
@@ -6895,7 +6895,7 @@ void CURVE_OT_shade_flat(wmOperatorType *ot)
* This is used externally, by #OBJECT_OT_join.
* TODO: shape keys - as with meshes.
*/
-int join_curve_exec(bContext *C, wmOperator *op)
+int ED_curve_join_objects_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
diff --git a/source/blender/editors/curve/editcurve_select.c b/source/blender/editors/curve/editcurve_select.c
index 9294bc6e91b..73f970876b1 100644
--- a/source/blender/editors/curve/editcurve_select.c
+++ b/source/blender/editors/curve/editcurve_select.c
@@ -988,7 +988,7 @@ void CURVE_OT_select_more(wmOperatorType *ot)
/* identifiers */
ot->name = "Select More";
ot->idname = "CURVE_OT_select_more";
- ot->description = "Select control points directly linked to already selected ones";
+ ot->description = "Select control points at the boundary of each selection region";
/* api callbacks */
ot->exec = curve_select_more_exec;
@@ -1203,7 +1203,7 @@ void CURVE_OT_select_less(wmOperatorType *ot)
/* identifiers */
ot->name = "Select Less";
ot->idname = "CURVE_OT_select_less";
- ot->description = "Reduce current selection by deselecting boundary elements";
+ ot->description = "Deselect control points at the boundary of each selection region";
/* api callbacks */
ot->exec = curve_select_less_exec;
diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c
index dc5dc71106f..1bbd4b4a5bc 100644
--- a/source/blender/editors/curve/editfont.c
+++ b/source/blender/editors/curve/editfont.c
@@ -1635,7 +1635,7 @@ static int insert_text_exec(bContext *C, wmOperator *op)
{
Object *obedit = CTX_data_edit_object(C);
char *inserted_utf8;
- wchar_t *inserted_text;
+ char32_t *inserted_text;
int a, len;
if (!RNA_struct_property_is_set(op->ptr, "text")) {
@@ -1645,8 +1645,8 @@ static int insert_text_exec(bContext *C, wmOperator *op)
inserted_utf8 = RNA_string_get_alloc(op->ptr, "text", NULL, 0);
len = BLI_strlen_utf8(inserted_utf8);
- inserted_text = MEM_callocN(sizeof(wchar_t) * (len + 1), "FONT_insert_text");
- BLI_strncpy_wchar_from_utf8(inserted_text, inserted_utf8, len + 1);
+ inserted_text = MEM_callocN(sizeof(char32_t) * (len + 1), "FONT_insert_text");
+ len = BLI_str_utf8_as_utf32(inserted_text, inserted_utf8, MAXTEXT);
for (a = 0; a < len; a++) {
insert_into_textbuf(obedit, inserted_text[a]);
@@ -2133,7 +2133,7 @@ static int open_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)
vfont = (VFont *)idptr.owner_id;
}
- path = (vfont && !BKE_vfont_is_builtin(vfont)) ? vfont->name : U.fontdir;
+ path = (vfont && !BKE_vfont_is_builtin(vfont)) ? vfont->filepath : U.fontdir;
if (RNA_struct_property_is_set(op->ptr, "filepath")) {
return font_open_exec(C, op);
diff --git a/source/blender/editors/datafiles/CMakeLists.txt b/source/blender/editors/datafiles/CMakeLists.txt
index 1a5b3d6ac45..0dcb8de37f1 100644
--- a/source/blender/editors/datafiles/CMakeLists.txt
+++ b/source/blender/editors/datafiles/CMakeLists.txt
@@ -713,6 +713,7 @@ set_property(GLOBAL PROPERTY ICON_GEOM_NAMES
ops.mesh.bisect
ops.mesh.dupli_extrude_cursor
ops.mesh.extrude_faces_move
+ ops.mesh.extrude_manifold
ops.mesh.extrude_region_move
ops.mesh.extrude_region_shrink_fatten
ops.mesh.inset
diff --git a/source/blender/editors/gpencil/CMakeLists.txt b/source/blender/editors/gpencil/CMakeLists.txt
index 4083169d65c..735ad8bc039 100644
--- a/source/blender/editors/gpencil/CMakeLists.txt
+++ b/source/blender/editors/gpencil/CMakeLists.txt
@@ -49,6 +49,7 @@ set(SRC
gpencil_fill.c
gpencil_interpolate.c
gpencil_merge.c
+ gpencil_mesh.c
gpencil_ops.c
gpencil_ops_versioning.c
gpencil_paint.c
diff --git a/source/blender/editors/gpencil/annotate_draw.c b/source/blender/editors/gpencil/annotate_draw.c
index 22df7bbbf31..20307e7f809 100644
--- a/source/blender/editors/gpencil/annotate_draw.c
+++ b/source/blender/editors/gpencil/annotate_draw.c
@@ -172,9 +172,14 @@ static void annotation_draw_stroke_buffer(bGPdata *gps,
float oldpressure = points[0].pressure;
/* draw stroke curve */
- GPU_line_width(max_ff(oldpressure * thickness, 1.0));
+ immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
+
+ float viewport[4];
+ GPU_viewport_size_get_f(viewport);
+ immUniform2fv("viewportSize", &viewport[2]);
+
+ immUniform1f("lineWidth", max_ff(oldpressure * thickness, 1.0) * U.pixelsize);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor3fvAlpha(ink, ink[3]);
immBeginAtMost(GPU_PRIM_LINE_STRIP, totpoints);
@@ -193,7 +198,7 @@ static void annotation_draw_stroke_buffer(bGPdata *gps,
immEnd();
draw_points = 0;
- GPU_line_width(max_ff(pt->pressure * thickness, 1.0f));
+ immUniform1f("lineWidth", max_ff(pt->pressure * thickness, 1.0) * U.pixelsize);
immBeginAtMost(GPU_PRIM_LINE_STRIP, totpoints - i + 1);
/* need to roll-back one point to ensure that there are no gaps in the stroke */
@@ -327,11 +332,17 @@ static void annotation_draw_stroke_3d(
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
+
+ float viewport[4];
+ GPU_viewport_size_get_f(viewport);
+ immUniform2fv("viewportSize", &viewport[2]);
+
+ immUniform1f("lineWidth", max_ff(curpressure * thickness, 1.0) * U.pixelsize);
+
immUniformColor3fvAlpha(ink, ink[3]);
/* draw stroke curve */
- GPU_line_width(max_ff(curpressure * thickness, 1.0f));
immBeginAtMost(GPU_PRIM_LINE_STRIP, totpoints + cyclic_add);
const bGPDspoint *pt = points;
for (int i = 0; i < totpoints; i++, pt++) {
@@ -351,7 +362,7 @@ static void annotation_draw_stroke_3d(
draw_points = 0;
curpressure = pt->pressure;
- GPU_line_width(max_ff(curpressure * thickness, 1.0f));
+ immUniform1f("lineWidth", max_ff(curpressure * thickness, 1.0) * U.pixelsize);
immBeginAtMost(GPU_PRIM_LINE_STRIP, totpoints - i + 1 + cyclic_add);
/* need to roll-back one point to ensure that there are no gaps in the stroke */
@@ -424,11 +435,15 @@ static void annotation_draw_stroke_2d(const bGPDspoint *points,
}
else {
/* draw stroke curve */
- GPU_line_width(max_ff(oldpressure * thickness, 1.0));
-
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
immUniformColor3fvAlpha(ink, ink[3]);
+ float viewport[4];
+ GPU_viewport_size_get_f(viewport);
+ immUniform2fv("viewportSize", &viewport[2]);
+
+ immUniform1f("lineWidth", max_ff(oldpressure * thickness, 1.0) * U.pixelsize);
+
immBeginAtMost(GPU_PRIM_LINE_STRIP, totpoints);
for (int i = 0; i < totpoints; i++) {
@@ -448,7 +463,8 @@ static void annotation_draw_stroke_2d(const bGPDspoint *points,
immEnd();
draw_points = 0;
- GPU_line_width(max_ff(pt->pressure * thickness, 1.0f));
+ immUniform1f("lineWidth", max_ff(pt->pressure * thickness, 1.0) * U.pixelsize);
+
immBeginAtMost(GPU_PRIM_LINE_STRIP, totpoints - i + 1);
/* need to roll-back one point to ensure that there are no gaps in the stroke */
@@ -683,9 +699,6 @@ static void annotation_draw_data_layers(
continue;
}
- /* set basic stroke thickness */
- GPU_line_width(lthick);
-
/* Add layer drawing settings to the set of "draw flags"
* NOTE: If the setting doesn't apply, it *must* be cleared,
* as dflag's carry over from the previous layer
@@ -774,13 +787,7 @@ static void annotation_draw_data_all(Scene *scene,
}
}
-/* ----- Grease Pencil Sketches Drawing API ------ */
-
-/* ............................
- * XXX
- * We need to review the calls below, since they may be/are not that suitable for
- * the new ways that we intend to be drawing data...
- * ............................ */
+/* ----- Annotation Sketches Drawing API ------ */
/* draw grease-pencil sketches to specified 2d-view that uses ibuf corrections */
void ED_annotation_draw_2dimage(const bContext *C)
diff --git a/source/blender/editors/gpencil/annotate_paint.c b/source/blender/editors/gpencil/annotate_paint.c
index 5c5adb32a97..9d80a75b959 100644
--- a/source/blender/editors/gpencil/annotate_paint.c
+++ b/source/blender/editors/gpencil/annotate_paint.c
@@ -204,12 +204,12 @@ typedef struct tGPsdata {
/* minimum length of new segment before new point can be added */
#define MIN_EUCLIDEAN_PX (U.gp_euclideandist)
-static bool gp_stroke_added_check(tGPsdata *p)
+static bool annotation_stroke_added_check(tGPsdata *p)
{
return (p->gpf && p->gpf->strokes.last && p->flags & GP_PAINTFLAG_STROKEADDED);
}
-static void gp_stroke_added_enable(tGPsdata *p)
+static void annotation_stroke_added_enable(tGPsdata *p)
{
BLI_assert(p->gpf->strokes.last != NULL);
p->flags |= GP_PAINTFLAG_STROKEADDED;
@@ -218,13 +218,13 @@ static void gp_stroke_added_enable(tGPsdata *p)
/* ------ */
/* Forward defines for some functions... */
-static void gp_session_validatebuffer(tGPsdata *p);
+static void annotation_session_validatebuffer(tGPsdata *p);
/* ******************************************* */
/* Context Wrangling... */
/* check if context is suitable for drawing */
-static bool gpencil_draw_poll(bContext *C)
+static bool annotation_draw_poll(bContext *C)
{
if (ED_operator_regionactive(C)) {
/* check if current context can support GPencil data */
@@ -249,7 +249,7 @@ static bool gpencil_draw_poll(bContext *C)
}
/* check if projecting strokes into 3d-geometry in the 3D-View */
-static bool gpencil_project_check(tGPsdata *p)
+static bool annotation_project_check(tGPsdata *p)
{
bGPdata *gpd = p->gpd;
return ((gpd->runtime.sbuffer_sflag & GP_STROKE_3DSPACE) &&
@@ -262,7 +262,7 @@ static bool gpencil_project_check(tGPsdata *p)
/* Utilities --------------------------------- */
/* get the reference point for stroke-point conversions */
-static void gp_get_3d_reference(tGPsdata *p, float vec[3])
+static void annotation_get_3d_reference(tGPsdata *p, float vec[3])
{
const float *fp = p->scene->cursor.location;
@@ -273,7 +273,7 @@ static void gp_get_3d_reference(tGPsdata *p, float vec[3])
/* Stroke Editing ---------------------------- */
/* check if the current mouse position is suitable for adding a new point */
-static bool gp_stroke_filtermval(tGPsdata *p, const float mval[2], float pmval[2])
+static bool annotation_stroke_filtermval(tGPsdata *p, const float mval[2], float pmval[2])
{
int dx = (int)fabsf(mval[0] - pmval[0]);
int dy = (int)fabsf(mval[1] - pmval[1]);
@@ -318,7 +318,10 @@ static bool gp_stroke_filtermval(tGPsdata *p, const float mval[2], float pmval[2
}
/* convert screen-coordinates to buffer-coordinates */
-static void gp_stroke_convertcoords(tGPsdata *p, const float mval[2], float out[3], float *depth)
+static void annotation_stroke_convertcoords(tGPsdata *p,
+ const float mval[2],
+ float out[3],
+ float *depth)
{
bGPdata *gpd = p->gpd;
@@ -326,7 +329,7 @@ static void gp_stroke_convertcoords(tGPsdata *p, const float mval[2], float out[
if (gpd->runtime.sbuffer_sflag & GP_STROKE_3DSPACE) {
int mval_i[2];
round_v2i_v2fl(mval_i, mval);
- if (gpencil_project_check(p) &&
+ if (annotation_project_check(p) &&
(ED_view3d_autodist_simple(p->region, mval_i, out, 0, depth))) {
/* projecting onto 3D-Geometry
* - nothing more needs to be done here, since view_autodist_simple() has already done it
@@ -346,7 +349,7 @@ static void gp_stroke_convertcoords(tGPsdata *p, const float mval[2], float out[
* reference point instead or as offset, for easier stroke matching
*/
- gp_get_3d_reference(p, rvec);
+ annotation_get_3d_reference(p, rvec);
zfac = ED_view3d_calc_zfac(p->region->regiondata, rvec, NULL);
if (ED_view3d_project_float_global(p->region, rvec, mval_prj, V3D_PROJ_TEST_NOP) ==
@@ -381,16 +384,17 @@ static void gp_stroke_convertcoords(tGPsdata *p, const float mval[2], float out[
}
}
-/* Apply smooth to buffer while drawing
+/**
+ * Apply smooth to buffer while drawing
* to smooth point C, use 2 before (A, B) and current point (D):
*
- * A----B-----C------D
+ * `A----B-----C------D`
*
* \param p: Temp data
* \param inf: Influence factor
* \param idx: Index of the last point (need minimum 3 points in the array)
*/
-static void gp_smooth_buffer(tGPsdata *p, float inf, int idx)
+static void annotation_smooth_buffer(tGPsdata *p, float inf, int idx)
{
bGPdata *gpd = p->gpd;
short num_points = gpd->runtime.sbuffer_used;
@@ -438,12 +442,12 @@ static void gp_smooth_buffer(tGPsdata *p, float inf, int idx)
copy_v2_v2(&ptc->x, c);
}
-static void gp_stroke_arrow_calc_points_segment(float stroke_points[8],
- const float ref_point[2],
- const float dir_cw[2],
- const float dir_ccw[2],
- const float lenght,
- const float sign)
+static void annotation_stroke_arrow_calc_points_segment(float stroke_points[8],
+ const float ref_point[2],
+ const float dir_cw[2],
+ const float dir_ccw[2],
+ const float lenght,
+ const float sign)
{
stroke_points[0] = ref_point[0] + dir_cw[0] * lenght * sign;
stroke_points[1] = ref_point[1] + dir_cw[1] * lenght * sign;
@@ -451,11 +455,11 @@ static void gp_stroke_arrow_calc_points_segment(float stroke_points[8],
stroke_points[3] = ref_point[1] + dir_ccw[1] * lenght * sign;
}
-static void gp_stroke_arrow_calc_points(tGPspoint *point,
- const float stroke_dir[2],
- float corner[2],
- float stroke_points[8],
- const int arrow_style)
+static void annotation_stroke_arrow_calc_points(tGPspoint *point,
+ const float stroke_dir[2],
+ float corner[2],
+ float stroke_points[8],
+ const int arrow_style)
{
const int arrow_lenght = 8;
float norm_dir[2];
@@ -473,12 +477,12 @@ static void gp_stroke_arrow_calc_points(tGPspoint *point,
stroke_points[3] = corner[1] + inv_norm_dir_counterclockwise[1] * arrow_lenght + norm_dir[1];
break;
case GP_STROKE_ARROWSTYLE_SEGMENT:
- gp_stroke_arrow_calc_points_segment(stroke_points,
- corner,
- inv_norm_dir_clockwise,
- inv_norm_dir_counterclockwise,
- arrow_lenght,
- 1.0f);
+ annotation_stroke_arrow_calc_points_segment(stroke_points,
+ corner,
+ inv_norm_dir_clockwise,
+ inv_norm_dir_counterclockwise,
+ arrow_lenght,
+ 1.0f);
break;
case GP_STROKE_ARROWSTYLE_CLOSED:
mul_v2_fl(norm_dir, arrow_lenght);
@@ -486,12 +490,12 @@ static void gp_stroke_arrow_calc_points(tGPspoint *point,
add_v2_v2(&point->x, norm_dir);
copy_v2_v2(corner, &point->x);
}
- gp_stroke_arrow_calc_points_segment(stroke_points,
- corner,
- inv_norm_dir_clockwise,
- inv_norm_dir_counterclockwise,
- arrow_lenght,
- -1.0f);
+ annotation_stroke_arrow_calc_points_segment(stroke_points,
+ corner,
+ inv_norm_dir_clockwise,
+ inv_norm_dir_counterclockwise,
+ arrow_lenght,
+ -1.0f);
stroke_points[4] = corner[0] - norm_dir[0];
stroke_points[5] = corner[1] - norm_dir[1];
break;
@@ -501,12 +505,12 @@ static void gp_stroke_arrow_calc_points(tGPspoint *point,
add_v2_v2(&point->x, norm_dir);
copy_v2_v2(corner, &point->x);
}
- gp_stroke_arrow_calc_points_segment(stroke_points,
- corner,
- inv_norm_dir_clockwise,
- inv_norm_dir_counterclockwise,
- arrow_lenght * 0.75f,
- -1.0f);
+ annotation_stroke_arrow_calc_points_segment(stroke_points,
+ corner,
+ inv_norm_dir_clockwise,
+ inv_norm_dir_counterclockwise,
+ arrow_lenght * 0.75f,
+ -1.0f);
stroke_points[4] = stroke_points[0] - norm_dir[0];
stroke_points[5] = stroke_points[1] - norm_dir[1];
stroke_points[6] = stroke_points[2] - norm_dir[0];
@@ -518,7 +522,10 @@ static void gp_stroke_arrow_calc_points(tGPspoint *point,
}
/* add current stroke-point to buffer (returns whether point was successfully added) */
-static short gp_stroke_addpoint(tGPsdata *p, const float mval[2], float pressure, double curtime)
+static short annotation_stroke_addpoint(tGPsdata *p,
+ const float mval[2],
+ float pressure,
+ double curtime)
{
bGPdata *gpd = p->gpd;
tGPspoint *pt;
@@ -571,14 +578,14 @@ static short gp_stroke_addpoint(tGPsdata *p, const float mval[2], float pressure
pt++;
float e_heading[2] = {start[0] - end[0], start[1] - end[1]};
/* Calculate points for ending arrow. */
- gp_stroke_arrow_calc_points(
+ annotation_stroke_arrow_calc_points(
pt, e_heading, end, gpd->runtime.arrow_end, gpd->runtime.arrow_end_style);
}
/* Arrow start corner. */
if (gpd->runtime.sbuffer_sflag & GP_STROKE_USE_ARROW_START) {
float s_heading[2] = {end[0] - start[0], end[1] - start[1]};
/* Calculate points for starting arrow. */
- gp_stroke_arrow_calc_points(
+ annotation_stroke_arrow_calc_points(
NULL, s_heading, start, gpd->runtime.arrow_start, gpd->runtime.arrow_start_style);
}
}
@@ -611,7 +618,7 @@ static short gp_stroke_addpoint(tGPsdata *p, const float mval[2], float pressure
if ((p->flags & GP_PAINTFLAG_USE_STABILIZER_TEMP) == 0) {
/* smooth while drawing previous points with a reduction factor for previous */
for (int s = 0; s < 3; s++) {
- gp_smooth_buffer(p, 0.5f * ((3.0f - s) / 3.0f), gpd->runtime.sbuffer_used - s);
+ annotation_smooth_buffer(p, 0.5f * ((3.0f - s) / 3.0f), gpd->runtime.sbuffer_used - s);
}
}
@@ -632,7 +639,7 @@ static short gp_stroke_addpoint(tGPsdata *p, const float mval[2], float pressure
* to stroke. This allows to draw lines more interactively (see new segment
* during mouse slide, e.g.)
*/
- if (gp_stroke_added_check(p)) {
+ if (annotation_stroke_added_check(p)) {
bGPDstroke *gps = p->gpf->strokes.last;
bGPDspoint *pts;
@@ -649,7 +656,7 @@ static short gp_stroke_addpoint(tGPsdata *p, const float mval[2], float pressure
* but poly lines are converting to stroke instantly,
* so initialize depth buffer before converting coordinates
*/
- if (gpencil_project_check(p)) {
+ if (annotation_project_check(p)) {
View3D *v3d = p->area->spacedata.first;
view3d_region_operator_needs_opengl(p->win, p->region);
@@ -660,7 +667,7 @@ static short gp_stroke_addpoint(tGPsdata *p, const float mval[2], float pressure
}
/* convert screen-coordinates to appropriate coordinates (and store them) */
- gp_stroke_convertcoords(p, &pt->x, &pts->x, NULL);
+ annotation_stroke_convertcoords(p, &pt->x, &pts->x, NULL);
/* copy pressure and time */
pts->pressure = pt->pressure;
@@ -681,115 +688,115 @@ static short gp_stroke_addpoint(tGPsdata *p, const float mval[2], float pressure
return GP_STROKEADD_INVALID;
}
-static void gp_stroke_arrow_init_point_default(bGPDspoint *pt)
+static void annotation_stroke_arrow_init_point_default(bGPDspoint *pt)
{
pt->pressure = 1.0f;
pt->strength = 1.0f;
pt->time = 1.0f;
}
-static void gp_stroke_arrow_init_conv_point(bGPDspoint *pt, const float point[3])
+static void annotation_stroke_arrow_init_conv_point(bGPDspoint *pt, const float point[3])
{
copy_v3_v3(&pt->x, point);
- gp_stroke_arrow_init_point_default(pt);
+ annotation_stroke_arrow_init_point_default(pt);
}
-static void gp_stroke_arrow_init_point(
+static void annotation_stroke_arrow_init_point(
tGPsdata *p, tGPspoint *ptc, bGPDspoint *pt, const float co[8], const int co_idx)
{
/* Note: provided co_idx should be always pair number as it's [x1, y1, x2, y2, x3, y3]. */
float real_co[2] = {co[co_idx], co[co_idx + 1]};
copy_v2_v2(&ptc->x, real_co);
- gp_stroke_convertcoords(p, &ptc->x, &pt->x, NULL);
- gp_stroke_arrow_init_point_default(pt);
+ annotation_stroke_convertcoords(p, &ptc->x, &pt->x, NULL);
+ annotation_stroke_arrow_init_point_default(pt);
}
-static void gp_stroke_arrow_allocate(bGPDstroke *gps, const int totpoints)
+static void annotation_stroke_arrow_allocate(bGPDstroke *gps, const int totpoints)
{
/* Copy appropriate settings for stroke. */
gps->totpoints = totpoints;
/* Allocate enough memory for a continuous array for storage points. */
- gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points");
+ gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "annotation_stroke_points");
}
-static void gp_arrow_create_open(tGPsdata *p,
- tGPspoint *ptc,
- bGPDspoint *pt,
- const float corner_point[3],
- const float arrow_points[8])
+static void annotation_arrow_create_open(tGPsdata *p,
+ tGPspoint *ptc,
+ bGPDspoint *pt,
+ const float corner_point[3],
+ const float arrow_points[8])
{
- gp_stroke_arrow_init_point(p, ptc, pt, arrow_points, 0);
+ annotation_stroke_arrow_init_point(p, ptc, pt, arrow_points, 0);
pt++;
- gp_stroke_arrow_init_conv_point(pt, corner_point);
+ annotation_stroke_arrow_init_conv_point(pt, corner_point);
pt++;
- gp_stroke_arrow_init_point(p, ptc, pt, arrow_points, 2);
+ annotation_stroke_arrow_init_point(p, ptc, pt, arrow_points, 2);
}
-static void gp_arrow_create_segm(tGPsdata *p,
- tGPspoint *ptc,
- bGPDspoint *pt,
- const float arrow_points[8])
+static void annotation_arrow_create_segm(tGPsdata *p,
+ tGPspoint *ptc,
+ bGPDspoint *pt,
+ const float arrow_points[8])
{
- gp_stroke_arrow_init_point(p, ptc, pt, arrow_points, 0);
+ annotation_stroke_arrow_init_point(p, ptc, pt, arrow_points, 0);
pt++;
- gp_stroke_arrow_init_point(p, ptc, pt, arrow_points, 2);
+ annotation_stroke_arrow_init_point(p, ptc, pt, arrow_points, 2);
}
-static void gp_arrow_create_closed(tGPsdata *p,
- tGPspoint *ptc,
- bGPDspoint *pt,
- const float arrow_points[8])
+static void annotation_arrow_create_closed(tGPsdata *p,
+ tGPspoint *ptc,
+ bGPDspoint *pt,
+ const float arrow_points[8])
{
- gp_stroke_arrow_init_point(p, ptc, pt, arrow_points, 0);
+ annotation_stroke_arrow_init_point(p, ptc, pt, arrow_points, 0);
pt++;
- gp_stroke_arrow_init_point(p, ptc, pt, arrow_points, 2);
+ annotation_stroke_arrow_init_point(p, ptc, pt, arrow_points, 2);
pt++;
- gp_stroke_arrow_init_point(p, ptc, pt, arrow_points, 4);
+ annotation_stroke_arrow_init_point(p, ptc, pt, arrow_points, 4);
pt++;
- gp_stroke_arrow_init_point(p, ptc, pt, arrow_points, 0);
+ annotation_stroke_arrow_init_point(p, ptc, pt, arrow_points, 0);
}
-static void gp_arrow_create_square(tGPsdata *p,
- tGPspoint *ptc,
- bGPDspoint *pt,
- const float corner_point[3],
- const float arrow_points[8])
+static void annotation_arrow_create_square(tGPsdata *p,
+ tGPspoint *ptc,
+ bGPDspoint *pt,
+ const float corner_point[3],
+ const float arrow_points[8])
{
- gp_stroke_arrow_init_conv_point(pt, corner_point);
+ annotation_stroke_arrow_init_conv_point(pt, corner_point);
pt++;
- gp_stroke_arrow_init_point(p, ptc, pt, arrow_points, 0);
+ annotation_stroke_arrow_init_point(p, ptc, pt, arrow_points, 0);
pt++;
- gp_stroke_arrow_init_point(p, ptc, pt, arrow_points, 4);
+ annotation_stroke_arrow_init_point(p, ptc, pt, arrow_points, 4);
pt++;
- gp_stroke_arrow_init_point(p, ptc, pt, arrow_points, 6);
+ annotation_stroke_arrow_init_point(p, ptc, pt, arrow_points, 6);
pt++;
- gp_stroke_arrow_init_point(p, ptc, pt, arrow_points, 2);
+ annotation_stroke_arrow_init_point(p, ptc, pt, arrow_points, 2);
pt++;
- gp_stroke_arrow_init_conv_point(pt, corner_point);
+ annotation_stroke_arrow_init_conv_point(pt, corner_point);
}
-static void gp_arrow_create(tGPsdata *p,
- tGPspoint *ptc,
- bGPDspoint *pt,
- bGPDstroke *arrow_stroke,
- const float arrow_points[8],
- const int style)
+static void annotation_arrow_create(tGPsdata *p,
+ tGPspoint *ptc,
+ bGPDspoint *pt,
+ bGPDstroke *arrow_stroke,
+ const float arrow_points[8],
+ const int style)
{
float corner_conv[3];
copy_v3_v3(corner_conv, &pt->x);
switch (style) {
case GP_STROKE_ARROWSTYLE_SEGMENT:
- gp_arrow_create_segm(p, ptc, pt, arrow_points);
+ annotation_arrow_create_segm(p, ptc, pt, arrow_points);
break;
case GP_STROKE_ARROWSTYLE_CLOSED:
- gp_arrow_create_closed(p, ptc, pt, arrow_points);
+ annotation_arrow_create_closed(p, ptc, pt, arrow_points);
break;
case GP_STROKE_ARROWSTYLE_OPEN:
- gp_arrow_create_open(p, ptc, pt, corner_conv, arrow_points);
+ annotation_arrow_create_open(p, ptc, pt, corner_conv, arrow_points);
break;
case GP_STROKE_ARROWSTYLE_SQUARE:
- gp_arrow_create_square(p, ptc, pt, corner_conv, arrow_points);
+ annotation_arrow_create_square(p, ptc, pt, corner_conv, arrow_points);
break;
default:
break;
@@ -799,7 +806,7 @@ static void gp_arrow_create(tGPsdata *p,
}
/* make a new stroke from the buffer data */
-static void gp_stroke_newfrombuffer(tGPsdata *p)
+static void annotation_stroke_newfrombuffer(tGPsdata *p)
{
bGPdata *gpd = p->gpd;
bGPDlayer *gpl = p->gpl;
@@ -837,13 +844,13 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
* interactive behavior
*/
if (p->paintmode == GP_PAINTMODE_DRAW_POLY) {
- if (gp_stroke_added_check(p)) {
+ if (annotation_stroke_added_check(p)) {
return;
}
}
/* allocate memory for a new stroke */
- gps = MEM_callocN(sizeof(bGPDstroke), "gp_stroke");
+ gps = MEM_callocN(sizeof(bGPDstroke), "annotation_stroke");
/* copy appropriate settings for stroke */
gps->totpoints = totelem;
@@ -857,7 +864,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
gps->tot_triangles = 0;
/* allocate enough memory for a continuous array for storage points */
- gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points");
+ gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "annotation_stroke_points");
gps->tot_triangles = 0;
/* set pointer to first non-initialized point */
@@ -871,7 +878,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
ptc = gpd->runtime.sbuffer;
/* convert screen-coordinates to appropriate coordinates (and store them) */
- gp_stroke_convertcoords(p, &ptc->x, &pt->x, NULL);
+ annotation_stroke_convertcoords(p, &ptc->x, &pt->x, NULL);
/* copy pressure and time */
pt->pressure = ptc->pressure;
@@ -889,7 +896,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
ptc = ((tGPspoint *)runtime.sbuffer) + (runtime.sbuffer_used - 1);
/* Convert screen-coordinates to appropriate coordinates (and store them). */
- gp_stroke_convertcoords(p, &ptc->x, &pt->x, NULL);
+ annotation_stroke_convertcoords(p, &ptc->x, &pt->x, NULL);
/* Copy pressure and time. */
pt->pressure = ptc->pressure;
@@ -905,18 +912,19 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
/* Setting up arrow stroke. */
bGPDstroke *e_arrow_gps = BKE_gpencil_stroke_duplicate(gps, false);
- gp_stroke_arrow_allocate(e_arrow_gps, totarrowpoints);
+ annotation_stroke_arrow_allocate(e_arrow_gps, totarrowpoints);
/* Set pointer to first non-initialized point. */
pt = e_arrow_gps->points + (e_arrow_gps->totpoints - totarrowpoints);
/* End point. */
ptc = ((tGPspoint *)runtime.sbuffer) + (runtime.sbuffer_used - 1);
- gp_stroke_convertcoords(p, &ptc->x, &pt->x, NULL);
- gp_stroke_arrow_init_point_default(pt);
+ annotation_stroke_convertcoords(p, &ptc->x, &pt->x, NULL);
+ annotation_stroke_arrow_init_point_default(pt);
/* Fill and convert arrow points to create arrow shape. */
- gp_arrow_create(p, ptc, pt, e_arrow_gps, runtime.arrow_end, runtime.arrow_end_style);
+ annotation_arrow_create(
+ p, ptc, pt, e_arrow_gps, runtime.arrow_end, runtime.arrow_end_style);
}
/* Start arrow stroke. */
if ((runtime.sbuffer_sflag & GP_STROKE_USE_ARROW_START) &&
@@ -925,18 +933,19 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
/* Setting up arrow stroke. */
bGPDstroke *s_arrow_gps = BKE_gpencil_stroke_duplicate(gps, false);
- gp_stroke_arrow_allocate(s_arrow_gps, totarrowpoints);
+ annotation_stroke_arrow_allocate(s_arrow_gps, totarrowpoints);
/* Set pointer to first non-initialized point. */
pt = s_arrow_gps->points + (s_arrow_gps->totpoints - totarrowpoints);
/* Start point. */
ptc = runtime.sbuffer;
- gp_stroke_convertcoords(p, &ptc->x, &pt->x, NULL);
- gp_stroke_arrow_init_point_default(pt);
+ annotation_stroke_convertcoords(p, &ptc->x, &pt->x, NULL);
+ annotation_stroke_arrow_init_point_default(pt);
/* Fill and convert arrow points to create arrow shape. */
- gp_arrow_create(p, ptc, pt, s_arrow_gps, runtime.arrow_start, runtime.arrow_start_style);
+ annotation_arrow_create(
+ p, ptc, pt, s_arrow_gps, runtime.arrow_start, runtime.arrow_start_style);
}
}
}
@@ -945,7 +954,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
ptc = gpd->runtime.sbuffer;
/* convert screen-coordinates to appropriate coordinates (and store them) */
- gp_stroke_convertcoords(p, &ptc->x, &pt->x, NULL);
+ annotation_stroke_convertcoords(p, &ptc->x, &pt->x, NULL);
/* copy pressure and time */
pt->pressure = ptc->pressure;
@@ -956,7 +965,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
float *depth_arr = NULL;
/* get an array of depths, far depths are blended */
- if (gpencil_project_check(p)) {
+ if (annotation_project_check(p)) {
int mval_i[2], mval_prev[2] = {0};
int interp_depth = 0;
int found_depth = 0;
@@ -1024,7 +1033,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
for (i = 0, ptc = gpd->runtime.sbuffer; i < gpd->runtime.sbuffer_used && ptc;
i++, ptc++, pt++) {
/* convert screen-coordinates to appropriate coordinates (and store them) */
- gp_stroke_convertcoords(p, &ptc->x, &pt->x, depth_arr ? depth_arr + i : NULL);
+ annotation_stroke_convertcoords(p, &ptc->x, &pt->x, depth_arr ? depth_arr + i : NULL);
/* copy pressure and time */
pt->pressure = ptc->pressure;
@@ -1040,7 +1049,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
/* add stroke to frame */
BLI_addtail(&p->gpf->strokes, gps);
- gp_stroke_added_enable(p);
+ annotation_stroke_added_enable(p);
}
/* --- 'Eraser' for 'Paint' Tool ------ */
@@ -1048,7 +1057,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
/* helper to free a stroke
* NOTE: gps->dvert and gps->triangles should be NULL, but check anyway for good measure
*/
-static void gp_free_stroke(bGPDframe *gpf, bGPDstroke *gps)
+static void annotation_free_stroke(bGPDframe *gpf, bGPDstroke *gps)
{
if (gps->points) {
MEM_freeN(gps->points);
@@ -1066,7 +1075,9 @@ static void gp_free_stroke(bGPDframe *gpf, bGPDstroke *gps)
BLI_freelinkN(&gpf->strokes, gps);
}
-/* which which point is infront (result should only be used for comparison) */
+/**
+ * Which which point is in front (result should only be used for comparison).
+ */
static float view3d_point_depth(const RegionView3D *rv3d, const float co[3])
{
if (rv3d->is_persp) {
@@ -1078,10 +1089,10 @@ static float view3d_point_depth(const RegionView3D *rv3d, const float co[3])
}
/* only erase stroke points that are visible (3d view) */
-static bool gp_stroke_eraser_is_occluded(tGPsdata *p,
- const bGPDspoint *pt,
- const int x,
- const int y)
+static bool annotation_stroke_eraser_is_occluded(tGPsdata *p,
+ const bGPDspoint *pt,
+ const int x,
+ const int y)
{
if ((p->area->spacetype == SPACE_VIEW3D) && (p->flags & GP_PAINTFLAG_V3D_ERASER_DEPTH)) {
RegionView3D *rv3d = p->region->regiondata;
@@ -1100,14 +1111,13 @@ static bool gp_stroke_eraser_is_occluded(tGPsdata *p,
return false;
}
-/* eraser tool - evaluation per stroke */
-/* TODO: this could really do with some optimization (KD-Tree/BVH?) */
-static void gp_stroke_eraser_dostroke(tGPsdata *p,
- bGPDframe *gpf,
- bGPDstroke *gps,
- const float mval[2],
- const int radius,
- const rcti *rect)
+/* Eraser tool - evaluation per stroke. */
+static void annotation_stroke_eraser_dostroke(tGPsdata *p,
+ bGPDframe *gpf,
+ bGPDstroke *gps,
+ const float mval[2],
+ const int radius,
+ const rcti *rect)
{
bGPDspoint *pt1, *pt2;
int pc1[2] = {0};
@@ -1118,19 +1128,19 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
if (gps->totpoints == 0) {
/* just free stroke */
- gp_free_stroke(gpf, gps);
+ annotation_free_stroke(gpf, gps);
}
else if (gps->totpoints == 1) {
/* only process if it hasn't been masked out... */
if (!(p->flags & GP_PAINTFLAG_SELECTMASK) || (gps->points->flag & GP_SPOINT_SELECT)) {
- gp_point_to_xy(&p->gsc, gps, gps->points, &pc1[0], &pc1[1]);
+ gpencil_point_to_xy(&p->gsc, gps, gps->points, &pc1[0], &pc1[1]);
/* do boundbox check first */
if ((!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1])) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) {
/* only check if point is inside */
if (len_v2v2_int(mval_i, pc1) <= radius) {
/* free stroke */
- gp_free_stroke(gpf, gps);
+ annotation_free_stroke(gpf, gps);
}
}
}
@@ -1164,8 +1174,8 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
continue;
}
- gp_point_to_xy(&p->gsc, gps, pt1, &pc1[0], &pc1[1]);
- gp_point_to_xy(&p->gsc, gps, pt2, &pc2[0], &pc2[1]);
+ gpencil_point_to_xy(&p->gsc, gps, pt1, &pc1[0], &pc1[1]);
+ gpencil_point_to_xy(&p->gsc, gps, pt2, &pc2[0], &pc2[1]);
/* Check that point segment of the boundbox of the eraser stroke */
if (((!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1])) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) ||
@@ -1174,9 +1184,9 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
* eraser region (either within stroke painted, or on its lines)
* - this assumes that linewidth is irrelevant
*/
- if (gp_stroke_inside_circle(mval, radius, pc1[0], pc1[1], pc2[0], pc2[1])) {
- if ((gp_stroke_eraser_is_occluded(p, pt1, pc1[0], pc1[1]) == false) ||
- (gp_stroke_eraser_is_occluded(p, pt2, pc2[0], pc2[1]) == false)) {
+ if (gpencil_stroke_inside_circle(mval, radius, pc1[0], pc1[1], pc2[0], pc2[1])) {
+ if ((annotation_stroke_eraser_is_occluded(p, pt1, pc1[0], pc1[1]) == false) ||
+ (annotation_stroke_eraser_is_occluded(p, pt2, pc2[0], pc2[1]) == false)) {
/* Edge is affected - Check individual points now */
if (len_v2v2_int(mval_i, pc1) <= radius) {
pt1->flag |= GP_SPOINT_TAG;
@@ -1192,13 +1202,13 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
/* Second Pass: Remove any points that are tagged */
if (do_cull) {
- gp_stroke_delete_tagged_points(gpf, gps, gps->next, GP_SPOINT_TAG, false, 0);
+ gpencil_stroke_delete_tagged_points(gpf, gps, gps->next, GP_SPOINT_TAG, false, 0);
}
}
}
/* erase strokes which fall under the eraser strokes */
-static void gp_stroke_doeraser(tGPsdata *p)
+static void annotation_stroke_doeraser(tGPsdata *p)
{
bGPDframe *gpf = p->gpf;
bGPDstroke *gps, *gpn;
@@ -1227,7 +1237,7 @@ static void gp_stroke_doeraser(tGPsdata *p)
* (e.g. 2D space strokes in the 3D view, if the same datablock is shared)
*/
if (ED_gpencil_stroke_can_use_direct(p->area, gps)) {
- gp_stroke_eraser_dostroke(p, gpf, gps, p->mval, p->radius, &rect);
+ annotation_stroke_eraser_dostroke(p, gpf, gps, p->mval, p->radius, &rect);
}
}
}
@@ -1236,7 +1246,7 @@ static void gp_stroke_doeraser(tGPsdata *p)
/* Sketching Operator */
/* clear the session buffers (call this before AND after a paint operation) */
-static void gp_session_validatebuffer(tGPsdata *p)
+static void annotation_session_validatebuffer(tGPsdata *p)
{
bGPdata *gpd = p->gpd;
@@ -1251,7 +1261,7 @@ static void gp_session_validatebuffer(tGPsdata *p)
}
/* (re)init new painting data */
-static bool gp_session_initdata(bContext *C, tGPsdata *p)
+static bool annotation_session_initdata(bContext *C, tGPsdata *p)
{
Main *bmain = CTX_data_main(C);
bGPdata **gpd_ptr = NULL;
@@ -1422,13 +1432,13 @@ static bool gp_session_initdata(bContext *C, tGPsdata *p)
}
/* clear out buffer (stored in gp-data), in case something contaminated it */
- gp_session_validatebuffer(p);
+ annotation_session_validatebuffer(p);
return 1;
}
/* init new painting session */
-static tGPsdata *gp_session_initpaint(bContext *C)
+static tGPsdata *annotation_session_initpaint(bContext *C)
{
tGPsdata *p = NULL;
@@ -1438,7 +1448,7 @@ static tGPsdata *gp_session_initpaint(bContext *C)
/* Try to initialize context data
* WARNING: This may not always succeed (e.g. using GP in an annotation-only context)
*/
- if (gp_session_initdata(C, p) == 0) {
+ if (annotation_session_initdata(C, p) == 0) {
/* Invalid state - Exit
* NOTE: It should be safe to just free the data, since failing context checks should
* only happen when no data has been allocated.
@@ -1458,7 +1468,7 @@ static tGPsdata *gp_session_initpaint(bContext *C)
}
/* cleanup after a painting session */
-static void gp_session_cleanup(tGPsdata *p)
+static void annotation_session_cleanup(tGPsdata *p)
{
bGPdata *gpd = (p) ? p->gpd : NULL;
@@ -1481,13 +1491,15 @@ static void gp_session_cleanup(tGPsdata *p)
p->inittime = 0.0;
}
-static void gp_session_free(tGPsdata *p)
+static void annotation_session_free(tGPsdata *p)
{
MEM_freeN(p);
}
/* init new stroke */
-static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, Depsgraph *depsgraph)
+static void annotation_paint_initstroke(tGPsdata *p,
+ eGPencil_PaintModes paintmode,
+ Depsgraph *depsgraph)
{
Scene *scene = p->scene;
ToolSettings *ts = scene->toolsettings;
@@ -1638,13 +1650,13 @@ static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, Deps
}
/* finish off a stroke (clears buffer, but doesn't finish the paint operation) */
-static void gp_paint_strokeend(tGPsdata *p)
+static void annotation_paint_strokeend(tGPsdata *p)
{
ToolSettings *ts = p->scene->toolsettings;
/* for surface sketching, need to set the right OpenGL context stuff so that
* the conversions will project the values correctly...
*/
- if (gpencil_project_check(p)) {
+ if (annotation_project_check(p)) {
View3D *v3d = p->area->spacedata.first;
/* need to restore the original projection settings before packing up */
@@ -1656,22 +1668,22 @@ static void gp_paint_strokeend(tGPsdata *p)
/* check if doing eraser or not */
if ((p->gpd->runtime.sbuffer_sflag & GP_STROKE_ERASER) == 0) {
/* transfer stroke to frame */
- gp_stroke_newfrombuffer(p);
+ annotation_stroke_newfrombuffer(p);
}
/* clean up buffer now */
- gp_session_validatebuffer(p);
+ annotation_session_validatebuffer(p);
}
/* finish off stroke painting operation */
-static void gp_paint_cleanup(tGPsdata *p)
+static void annotation_paint_cleanup(tGPsdata *p)
{
/* p->gpd==NULL happens when stroke failed to initialize,
* for example when GP is hidden in current space (sergey)
*/
if (p->gpd) {
/* finish off a stroke */
- gp_paint_strokeend(p);
+ annotation_paint_strokeend(p);
}
/* "unlock" frame */
@@ -1683,7 +1695,7 @@ static void gp_paint_cleanup(tGPsdata *p)
/* ------------------------------- */
/* Helper callback for drawing the cursor itself */
-static void gpencil_draw_eraser(bContext *UNUSED(C), int x, int y, void *p_ptr)
+static void annotation_draw_eraser(bContext *UNUSED(C), int x, int y, void *p_ptr)
{
tGPsdata *p = (tGPsdata *)p_ptr;
@@ -1729,7 +1741,7 @@ static void gpencil_draw_eraser(bContext *UNUSED(C), int x, int y, void *p_ptr)
}
/* Turn brush cursor in 3D view on/off */
-static void gpencil_draw_toggle_eraser_cursor(tGPsdata *p, short enable)
+static void annotation_draw_toggle_eraser_cursor(tGPsdata *p, short enable)
{
if (p->erasercursor && !enable) {
/* clear cursor */
@@ -1741,11 +1753,11 @@ static void gpencil_draw_toggle_eraser_cursor(tGPsdata *p, short enable)
p->erasercursor = WM_paint_cursor_activate(SPACE_TYPE_ANY,
RGN_TYPE_ANY,
NULL, /* XXX */
- gpencil_draw_eraser,
+ annotation_draw_eraser,
p);
}
}
-static void gpencil_draw_stabilizer(bContext *C, int x, int y, void *p_ptr)
+static void annotation_draw_stabilizer(bContext *C, int x, int y, void *p_ptr)
{
ARegion *region = CTX_wm_region(C);
tGPsdata *p = (tGPsdata *)p_ptr;
@@ -1793,7 +1805,7 @@ static void gpencil_draw_stabilizer(bContext *C, int x, int y, void *p_ptr)
}
/* Turn *stabilizer* brush cursor in 3D view on/off */
-static void gpencil_draw_toggle_stabilizer_cursor(tGPsdata *p, short enable)
+static void annotation_draw_toggle_stabilizer_cursor(tGPsdata *p, short enable)
{
if (p->stabilizer_cursor && !enable) {
/* clear cursor */
@@ -1803,19 +1815,19 @@ static void gpencil_draw_toggle_stabilizer_cursor(tGPsdata *p, short enable)
else if (enable && !p->stabilizer_cursor) {
/* enable cursor */
p->stabilizer_cursor = WM_paint_cursor_activate(
- SPACE_TYPE_ANY, RGN_TYPE_ANY, NULL, gpencil_draw_stabilizer, p);
+ SPACE_TYPE_ANY, RGN_TYPE_ANY, NULL, annotation_draw_stabilizer, p);
}
}
/* Check if tablet eraser is being used (when processing events) */
-static bool gpencil_is_tablet_eraser_active(const wmEvent *event)
+static bool annotation_is_tablet_eraser_active(const wmEvent *event)
{
return (event->tablet.active == EVT_TABLET_ERASER);
}
/* ------------------------------- */
-static void gpencil_draw_exit(bContext *C, wmOperator *op)
+static void annotation_draw_exit(bContext *C, wmOperator *op)
{
tGPsdata *p = op->customdata;
@@ -1827,10 +1839,10 @@ static void gpencil_draw_exit(bContext *C, wmOperator *op)
/* check size of buffer before cleanup, to determine if anything happened here */
if (p->paintmode == GP_PAINTMODE_ERASER) {
/* turn off radial brush cursor */
- gpencil_draw_toggle_eraser_cursor(p, false);
+ annotation_draw_toggle_eraser_cursor(p, false);
}
else if (p->paintmode == GP_PAINTMODE_DRAW) {
- gpencil_draw_toggle_stabilizer_cursor(p, false);
+ annotation_draw_toggle_stabilizer_cursor(p, false);
}
/* always store the new eraser size to be used again next time
@@ -1843,40 +1855,40 @@ static void gpencil_draw_exit(bContext *C, wmOperator *op)
gpencil_undo_finish();
/* cleanup */
- gp_paint_cleanup(p);
- gp_session_cleanup(p);
- gp_session_free(p);
+ annotation_paint_cleanup(p);
+ annotation_session_cleanup(p);
+ annotation_session_free(p);
p = NULL;
}
op->customdata = NULL;
}
-static void gpencil_draw_cancel(bContext *C, wmOperator *op)
+static void annotation_draw_cancel(bContext *C, wmOperator *op)
{
/* this is just a wrapper around exit() */
- gpencil_draw_exit(C, op);
+ annotation_draw_exit(C, op);
}
/* ------------------------------- */
-static int gpencil_draw_init(bContext *C, wmOperator *op, const wmEvent *event)
+static int annotation_draw_init(bContext *C, wmOperator *op, const wmEvent *event)
{
tGPsdata *p;
eGPencil_PaintModes paintmode = RNA_enum_get(op->ptr, "mode");
/* check context */
- p = op->customdata = gp_session_initpaint(C);
+ p = op->customdata = annotation_session_initpaint(C);
if ((p == NULL) || (p->status == GP_STATUS_ERROR)) {
/* something wasn't set correctly in context */
- gpencil_draw_exit(C, op);
+ annotation_draw_exit(C, op);
return 0;
}
/* init painting data */
- gp_paint_initstroke(p, paintmode, CTX_data_ensure_evaluated_depsgraph(C));
+ annotation_paint_initstroke(p, paintmode, CTX_data_ensure_evaluated_depsgraph(C));
if (p->status == GP_STATUS_ERROR) {
- gpencil_draw_exit(C, op);
+ annotation_draw_exit(C, op);
return 0;
}
@@ -1894,7 +1906,7 @@ static int gpencil_draw_init(bContext *C, wmOperator *op, const wmEvent *event)
/* ------------------------------- */
/* ensure that the correct cursor icon is set */
-static void gpencil_draw_cursor_set(tGPsdata *p)
+static void annotation_draw_cursor_set(tGPsdata *p)
{
if (p->paintmode == GP_PAINTMODE_ERASER) {
WM_cursor_modal_set(p->win, WM_CURSOR_ERASER);
@@ -1905,7 +1917,7 @@ static void gpencil_draw_cursor_set(tGPsdata *p)
}
/* update UI indicators of status, including cursor and header prints */
-static void gpencil_draw_status_indicators(bContext *C, tGPsdata *p)
+static void annotation_draw_status_indicators(bContext *C, tGPsdata *p)
{
/* header prints */
switch (p->status) {
@@ -1970,12 +1982,12 @@ static void gpencil_draw_status_indicators(bContext *C, tGPsdata *p)
/* ------------------------------- */
/* create a new stroke point at the point indicated by the painting context */
-static void gpencil_draw_apply(wmOperator *op, tGPsdata *p, Depsgraph *depsgraph)
+static void annotation_draw_apply(wmOperator *op, tGPsdata *p, Depsgraph *depsgraph)
{
/* handle drawing/erasing -> test for erasing first */
if (p->paintmode == GP_PAINTMODE_ERASER) {
/* do 'live' erasing now */
- gp_stroke_doeraser(p);
+ annotation_stroke_doeraser(p);
/* store used values */
p->mvalo[0] = p->mval[0];
@@ -1984,7 +1996,7 @@ static void gpencil_draw_apply(wmOperator *op, tGPsdata *p, Depsgraph *depsgraph
}
/* Only add current point to buffer if mouse moved
* (even though we got an event, it might be just noise). */
- else if (gp_stroke_filtermval(p, p->mval, p->mvalo)) {
+ else if (annotation_stroke_filtermval(p, p->mval, p->mvalo)) {
/* If lazy mouse, interpolate the last and current mouse positions. */
if (p->flags & GP_PAINTFLAG_USE_STABILIZER_TEMP) {
float now_mouse[2];
@@ -1996,26 +2008,24 @@ static void gpencil_draw_apply(wmOperator *op, tGPsdata *p, Depsgraph *depsgraph
}
/* try to add point */
- short ok = gp_stroke_addpoint(p, p->mval, p->pressure, p->curtime);
+ short ok = annotation_stroke_addpoint(p, p->mval, p->pressure, p->curtime);
/* handle errors while adding point */
if ((ok == GP_STROKEADD_FULL) || (ok == GP_STROKEADD_OVERFLOW)) {
/* finish off old stroke */
- gp_paint_strokeend(p);
+ annotation_paint_strokeend(p);
/* And start a new one!!! Else, projection errors! */
- gp_paint_initstroke(p, p->paintmode, depsgraph);
+ annotation_paint_initstroke(p, p->paintmode, depsgraph);
/* start a new stroke, starting from previous point */
- /* XXX Must manually reset inittime... */
- /* XXX We only need to reuse previous point if overflow! */
if (ok == GP_STROKEADD_OVERFLOW) {
p->inittime = p->ocurtime;
- gp_stroke_addpoint(p, p->mvalo, p->opressure, p->ocurtime);
+ annotation_stroke_addpoint(p, p->mvalo, p->opressure, p->ocurtime);
}
else {
p->inittime = p->curtime;
}
- gp_stroke_addpoint(p, p->mval, p->pressure, p->curtime);
+ annotation_stroke_addpoint(p, p->mval, p->pressure, p->curtime);
}
else if (ok == GP_STROKEADD_INVALID) {
/* the painting operation cannot continue... */
@@ -2053,16 +2063,16 @@ static void annotation_draw_apply_event(
/* Key to toggle stabilization. */
if (event->shift > 0 && p->paintmode == GP_PAINTMODE_DRAW) {
/* Using permanent stabilization, shift will deactivate the flag. */
- if (p->flags & (GP_PAINTFLAG_USE_STABILIZER)) {
+ if (p->flags & GP_PAINTFLAG_USE_STABILIZER) {
if (p->flags & GP_PAINTFLAG_USE_STABILIZER_TEMP) {
- gpencil_draw_toggle_stabilizer_cursor(p, false);
+ annotation_draw_toggle_stabilizer_cursor(p, false);
p->flags &= ~GP_PAINTFLAG_USE_STABILIZER_TEMP;
}
}
/* Not using any stabilization flag. Activate temporal one. */
else if ((p->flags & GP_PAINTFLAG_USE_STABILIZER_TEMP) == 0) {
p->flags |= GP_PAINTFLAG_USE_STABILIZER_TEMP;
- gpencil_draw_toggle_stabilizer_cursor(p, true);
+ annotation_draw_toggle_stabilizer_cursor(p, true);
}
}
/* verify key status for straight lines */
@@ -2091,7 +2101,7 @@ static void annotation_draw_apply_event(
so activate the temp flag back again. */
if (p->flags & GP_PAINTFLAG_USE_STABILIZER) {
if ((p->flags & GP_PAINTFLAG_USE_STABILIZER_TEMP) == 0) {
- gpencil_draw_toggle_stabilizer_cursor(p, true);
+ annotation_draw_toggle_stabilizer_cursor(p, true);
p->flags |= GP_PAINTFLAG_USE_STABILIZER_TEMP;
}
}
@@ -2101,7 +2111,7 @@ static void annotation_draw_apply_event(
else if (p->flags & GP_PAINTFLAG_USE_STABILIZER_TEMP) {
/* Reset temporal stabilizer flag and remove cursor. */
p->flags &= ~GP_PAINTFLAG_USE_STABILIZER_TEMP;
- gpencil_draw_toggle_stabilizer_cursor(p, false);
+ annotation_draw_toggle_stabilizer_cursor(p, false);
}
}
@@ -2165,7 +2175,7 @@ static void annotation_draw_apply_event(
RNA_float_set(&itemptr, "time", p->curtime - p->inittime);
/* apply the current latest drawing point */
- gpencil_draw_apply(op, p, depsgraph);
+ annotation_draw_apply(op, p, depsgraph);
/* force refresh */
/* just active area for now, since doing whole screen is too slow */
@@ -2175,7 +2185,7 @@ static void annotation_draw_apply_event(
/* ------------------------------- */
/* operator 'redo' (i.e. after changing some properties, but also for repeat last) */
-static int gpencil_draw_exec(bContext *C, wmOperator *op)
+static int annotation_draw_exec(bContext *C, wmOperator *op)
{
tGPsdata *p = NULL;
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
@@ -2183,7 +2193,7 @@ static int gpencil_draw_exec(bContext *C, wmOperator *op)
/* printf("GPencil - Starting Re-Drawing\n"); */
/* try to initialize context data needed while drawing */
- if (!gpencil_draw_init(C, op, NULL)) {
+ if (!annotation_draw_init(C, op, NULL)) {
if (op->customdata) {
MEM_freeN(op->customdata);
}
@@ -2217,8 +2227,8 @@ static int gpencil_draw_exec(bContext *C, wmOperator *op)
*/
if ((p->flags & GP_PAINTFLAG_FIRSTRUN) == 0) {
/* TODO: both of these ops can set error-status, but we probably don't need to worry */
- gp_paint_strokeend(p);
- gp_paint_initstroke(p, p->paintmode, depsgraph);
+ annotation_paint_strokeend(p);
+ annotation_paint_initstroke(p, p->paintmode, depsgraph);
}
}
@@ -2233,14 +2243,14 @@ static int gpencil_draw_exec(bContext *C, wmOperator *op)
}
/* apply this data as necessary now (as per usual) */
- gpencil_draw_apply(op, p, depsgraph);
+ annotation_draw_apply(op, p, depsgraph);
}
RNA_END;
/* printf("\tGP - done\n"); */
/* cleanup */
- gpencil_draw_exit(C, op);
+ annotation_draw_exit(C, op);
/* refreshes */
WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL);
@@ -2252,12 +2262,12 @@ static int gpencil_draw_exec(bContext *C, wmOperator *op)
/* ------------------------------- */
/* start of interactive drawing part of operator */
-static int gpencil_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+static int annotation_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
tGPsdata *p = NULL;
/* support for tablets eraser pen */
- if (gpencil_is_tablet_eraser_active(event)) {
+ if (annotation_is_tablet_eraser_active(event)) {
RNA_enum_set(op->ptr, "mode", GP_PAINTMODE_ERASER);
}
@@ -2266,7 +2276,7 @@ static int gpencil_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event
}
/* try to initialize context data needed while drawing */
- if (!gpencil_draw_init(C, op, event)) {
+ if (!annotation_draw_init(C, op, event)) {
if (op->customdata) {
MEM_freeN(op->customdata);
}
@@ -2281,21 +2291,15 @@ static int gpencil_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event
/* if empty erase capture and finish */
if (p->status == GP_STATUS_CAPTURE) {
- gpencil_draw_exit(C, op);
+ annotation_draw_exit(C, op);
BKE_report(op->reports, RPT_ERROR, "Nothing to erase");
return OPERATOR_FINISHED;
}
- /* TODO: set any additional settings that we can take from the events?
- * TODO? if tablet is erasing, force eraser to be on? */
-
- /* TODO: move cursor setting stuff to stroke-start so that paintmode can be changed midway...
- */
-
/* if eraser is on, draw radial aid */
if (p->paintmode == GP_PAINTMODE_ERASER) {
- gpencil_draw_toggle_eraser_cursor(p, true);
+ annotation_draw_toggle_eraser_cursor(p, true);
}
else if (p->paintmode == GP_PAINTMODE_DRAW_STRAIGHT) {
if (RNA_enum_get(op->ptr, "arrowstyle_start") != GP_STROKE_ARROWSTYLE_NONE) {
@@ -2312,18 +2316,18 @@ static int gpencil_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event
p->stabilizer_radius = RNA_int_get(op->ptr, "stabilizer_radius");
if (RNA_boolean_get(op->ptr, "use_stabilizer")) {
p->flags |= GP_PAINTFLAG_USE_STABILIZER | GP_PAINTFLAG_USE_STABILIZER_TEMP;
- gpencil_draw_toggle_stabilizer_cursor(p, true);
+ annotation_draw_toggle_stabilizer_cursor(p, true);
}
else if (event->shift > 0) {
p->flags |= GP_PAINTFLAG_USE_STABILIZER_TEMP;
- gpencil_draw_toggle_stabilizer_cursor(p, true);
+ annotation_draw_toggle_stabilizer_cursor(p, true);
}
}
/* set cursor
* NOTE: This may change later (i.e. intentionally via brush toggle,
* or unintentionally if the user scrolls outside the area)...
*/
- gpencil_draw_cursor_set(p);
+ annotation_draw_cursor_set(p);
/* only start drawing immediately if we're allowed to do so... */
if (RNA_boolean_get(op->ptr, "wait_for_input") == false) {
@@ -2348,13 +2352,13 @@ static int gpencil_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event
}
/* gpencil modal operator stores area, which can be removed while using it (like fullscreen) */
-static bool gpencil_area_exists(bContext *C, ScrArea *area_test)
+static bool annotation_area_exists(bContext *C, ScrArea *area_test)
{
bScreen *screen = CTX_wm_screen(C);
return (BLI_findindex(&screen->areabase, area_test) != -1);
}
-static tGPsdata *gpencil_stroke_begin(bContext *C, wmOperator *op)
+static tGPsdata *annotation_stroke_begin(bContext *C, wmOperator *op)
{
tGPsdata *p = op->customdata;
@@ -2372,8 +2376,8 @@ static tGPsdata *gpencil_stroke_begin(bContext *C, wmOperator *op)
/* XXX: watch it with the paintmode! in future,
* it'd be nice to allow changing paint-mode when in sketching-sessions */
- if (gp_session_initdata(C, p)) {
- gp_paint_initstroke(p, p->paintmode, CTX_data_ensure_evaluated_depsgraph(C));
+ if (annotation_session_initdata(C, p)) {
+ annotation_paint_initstroke(p, p->paintmode, CTX_data_ensure_evaluated_depsgraph(C));
}
if (p->status != GP_STATUS_ERROR) {
@@ -2384,15 +2388,15 @@ static tGPsdata *gpencil_stroke_begin(bContext *C, wmOperator *op)
return op->customdata;
}
-static void gpencil_stroke_end(wmOperator *op)
+static void annotation_stroke_end(wmOperator *op)
{
tGPsdata *p = op->customdata;
- gp_paint_cleanup(p);
+ annotation_paint_cleanup(p);
gpencil_undo_push(p->gpd);
- gp_session_cleanup(p);
+ annotation_session_cleanup(p);
p->status = GP_STATUS_IDLING;
op->flag |= OP_IS_MODAL_CURSOR_REGION;
@@ -2439,7 +2443,7 @@ static void annotation_add_missing_events(bContext *C,
}
/* events handling during interactive drawing part of operator */
-static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
+static int annotation_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
tGPsdata *p = op->customdata;
/* default exit state - pass through to support MMB view nav, etc. */
@@ -2542,7 +2546,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (sketch) {
/* end stroke only, and then wait to resume painting soon */
/* printf("\t\tGP - end stroke only\n"); */
- gpencil_stroke_end(op);
+ annotation_stroke_end(op);
/* If eraser mode is on, turn it off after the stroke finishes
* NOTE: This just makes it nicer to work with drawing sessions
@@ -2561,7 +2565,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
* Just hiding this makes it seem like
* you can paint again...
*/
- gpencil_draw_toggle_eraser_cursor(p, false);
+ annotation_draw_toggle_eraser_cursor(p, false);
}
}
@@ -2637,7 +2641,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
/* Switch paintmode (temporarily if need be) based on which button was used
* NOTE: This is to make it more convenient to erase strokes when using drawing sessions
*/
- if ((event->type == RIGHTMOUSE) || gpencil_is_tablet_eraser_active(event)) {
+ if ((event->type == RIGHTMOUSE) || annotation_is_tablet_eraser_active(event)) {
/* turn on eraser */
p->paintmode = GP_PAINTMODE_ERASER;
}
@@ -2646,10 +2650,10 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
p->paintmode = RNA_enum_get(op->ptr, "mode");
}
- gpencil_draw_toggle_eraser_cursor(p, p->paintmode == GP_PAINTMODE_ERASER);
+ annotation_draw_toggle_eraser_cursor(p, p->paintmode == GP_PAINTMODE_ERASER);
/* not painting, so start stroke (this should be mouse-button down) */
- p = gpencil_stroke_begin(C, op);
+ p = annotation_stroke_begin(C, op);
if (p->status == GP_STATUS_ERROR) {
estate = OPERATOR_CANCELLED;
@@ -2733,26 +2737,26 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
/* gpencil modal operator stores area, which can be removed while using it (like fullscreen) */
- if (0 == gpencil_area_exists(C, p->area)) {
+ if (0 == annotation_area_exists(C, p->area)) {
estate = OPERATOR_CANCELLED;
}
else {
/* update status indicators - cursor, header, etc. */
- gpencil_draw_status_indicators(C, p);
+ annotation_draw_status_indicators(C, p);
/* cursor may have changed outside our control - T44084 */
- gpencil_draw_cursor_set(p);
+ annotation_draw_cursor_set(p);
}
/* process last operations before exiting */
switch (estate) {
case OPERATOR_FINISHED:
/* one last flush before we're done */
- gpencil_draw_exit(C, op);
+ annotation_draw_exit(C, op);
WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL);
break;
case OPERATOR_CANCELLED:
- gpencil_draw_exit(C, op);
+ annotation_draw_exit(C, op);
break;
case OPERATOR_RUNNING_MODAL | OPERATOR_PASS_THROUGH:
@@ -2811,11 +2815,11 @@ void GPENCIL_OT_annotate(wmOperatorType *ot)
ot->description = "Make annotations on the active data";
/* api callbacks */
- ot->exec = gpencil_draw_exec;
- ot->invoke = gpencil_draw_invoke;
- ot->modal = gpencil_draw_modal;
- ot->cancel = gpencil_draw_cancel;
- ot->poll = gpencil_draw_poll;
+ ot->exec = annotation_draw_exec;
+ ot->invoke = annotation_draw_invoke;
+ ot->modal = annotation_draw_modal;
+ ot->cancel = annotation_draw_cancel;
+ ot->poll = annotation_draw_poll;
/* flags */
ot->flag = OPTYPE_UNDO | OPTYPE_BLOCKING;
diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c
index 6d41e9bddbe..60fd52db707 100644
--- a/source/blender/editors/gpencil/drawgpencil.c
+++ b/source/blender/editors/gpencil/drawgpencil.c
@@ -114,10 +114,10 @@ typedef enum eDrawStrokeFlags {
/* ----- Tool Buffer Drawing ------ */
/* helper functions to set color of buffer point */
-static void gp_set_point_varying_color(const bGPDspoint *pt,
- const float ink[4],
- uint attr_id,
- bool fix_strength)
+static void gpencil_set_point_varying_color(const bGPDspoint *pt,
+ const float ink[4],
+ uint attr_id,
+ bool fix_strength)
{
float alpha = ink[3] * pt->strength;
if ((fix_strength) && (alpha >= 0.1f)) {
@@ -130,10 +130,10 @@ static void gp_set_point_varying_color(const bGPDspoint *pt,
/* ----------- Volumetric Strokes --------------- */
/* draw a 3D stroke in "volumetric" style */
-static void gp_draw_stroke_volumetric_3d(const bGPDspoint *points,
- int totpoints,
- short thickness,
- const float ink[4])
+static void gpencil_draw_stroke_volumetric_3d(const bGPDspoint *points,
+ int totpoints,
+ short thickness,
+ const float ink[4])
{
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
@@ -147,7 +147,7 @@ static void gp_draw_stroke_volumetric_3d(const bGPDspoint *points,
const bGPDspoint *pt = points;
for (int i = 0; i < totpoints && pt; i++, pt++) {
- gp_set_point_varying_color(pt, ink, color, false);
+ gpencil_set_point_varying_color(pt, ink, color, false);
/* TODO: scale based on view transform */
immAttr1f(size, pt->pressure * thickness);
/* we can adjust size in vertex shader based on view/projection! */
@@ -162,7 +162,10 @@ static void gp_draw_stroke_volumetric_3d(const bGPDspoint *points,
/* ----- Existing Strokes Drawing (3D and Point) ------ */
/* draw a given stroke in 3d (i.e. in 3d-space) */
-static void gp_draw_stroke_3d(tGPDdraw *tgpw, short thickness, const float ink[4], bool cyclic)
+static void gpencil_draw_stroke_3d(tGPDdraw *tgpw,
+ short thickness,
+ const float ink[4],
+ bool cyclic)
{
bGPDspoint *points = tgpw->gps->points;
int totpoints = tgpw->gps->totpoints;
@@ -209,7 +212,7 @@ static void gp_draw_stroke_3d(tGPDdraw *tgpw, short thickness, const float ink[4
for (int i = 0; i < totpoints; i++, pt++) {
/* first point for adjacency (not drawn) */
if (i == 0) {
- gp_set_point_varying_color(points, ink, attr_id.color, (bool)tgpw->is_fill_stroke);
+ gpencil_set_point_varying_color(points, ink, attr_id.color, (bool)tgpw->is_fill_stroke);
if ((cyclic) && (totpoints > 2)) {
immAttr1f(attr_id.thickness, max_ff((points + totpoints - 1)->pressure * thickness, 1.0f));
@@ -222,7 +225,7 @@ static void gp_draw_stroke_3d(tGPDdraw *tgpw, short thickness, const float ink[4
immVertex3fv(attr_id.pos, fpt);
}
/* set point */
- gp_set_point_varying_color(pt, ink, attr_id.color, (bool)tgpw->is_fill_stroke);
+ gpencil_set_point_varying_color(pt, ink, attr_id.color, (bool)tgpw->is_fill_stroke);
immAttr1f(attr_id.thickness, max_ff(pt->pressure * thickness, 1.0f));
mul_v3_m4v3(fpt, tgpw->diff_mat, &pt->x);
immVertex3fv(attr_id.pos, fpt);
@@ -241,7 +244,7 @@ static void gp_draw_stroke_3d(tGPDdraw *tgpw, short thickness, const float ink[4
}
/* last adjacency point (not drawn) */
else {
- gp_set_point_varying_color(
+ gpencil_set_point_varying_color(
points + totpoints - 2, ink, attr_id.color, (bool)tgpw->is_fill_stroke);
immAttr1f(attr_id.thickness, max_ff((points + totpoints - 2)->pressure * thickness, 1.0f));
@@ -256,7 +259,7 @@ static void gp_draw_stroke_3d(tGPDdraw *tgpw, short thickness, const float ink[4
/* ----- Strokes Drawing ------ */
/* Helper for doing all the checks on whether a stroke can be drawn */
-static bool gp_can_draw_stroke(const bGPDstroke *gps, const int dflag)
+static bool gpencil_can_draw_stroke(const bGPDstroke *gps, const int dflag)
{
/* skip stroke if it isn't in the right display space for this drawing context */
/* 1) 3D Strokes */
@@ -293,7 +296,7 @@ static bool gp_can_draw_stroke(const bGPDstroke *gps, const int dflag)
}
/* draw a set of strokes */
-static void gp_draw_strokes(tGPDdraw *tgpw)
+static void gpencil_draw_strokes(tGPDdraw *tgpw)
{
float tcolor[4];
short sthickness;
@@ -307,7 +310,7 @@ static void gp_draw_strokes(tGPDdraw *tgpw)
for (bGPDstroke *gps = gps_init; gps; gps = gps->next) {
/* check if stroke can be drawn */
- if (gp_can_draw_stroke(gps, tgpw->dflag) == false) {
+ if (gpencil_can_draw_stroke(gps, tgpw->dflag) == false) {
continue;
}
/* check if the color is visible */
@@ -316,7 +319,7 @@ static void gp_draw_strokes(tGPDdraw *tgpw)
if ((gp_style == NULL) || (gp_style->flag & GP_MATERIAL_HIDE) ||
/* if onion and ghost flag do not draw*/
- (tgpw->onion && (gp_style->flag & GP_MATERIAL_ONIONSKIN))) {
+ (tgpw->onion && (gp_style->flag & GP_MATERIAL_HIDE_ONIONSKIN))) {
continue;
}
@@ -379,14 +382,14 @@ static void gp_draw_strokes(tGPDdraw *tgpw)
if (gp_style->mode == GP_MATERIAL_MODE_DOT) {
/* volumetric stroke drawing */
if (tgpw->disable_fill != 1) {
- gp_draw_stroke_volumetric_3d(gps->points, gps->totpoints, sthickness, ink);
+ gpencil_draw_stroke_volumetric_3d(gps->points, gps->totpoints, sthickness, ink);
}
}
else {
/* 3D Lines - OpenGL primitives-based */
if (gps->totpoints > 1) {
tgpw->gps = gps;
- gp_draw_stroke_3d(tgpw, sthickness, ink, gps->flag & GP_STROKE_CYCLIC);
+ gpencil_draw_stroke_3d(tgpw, sthickness, ink, gps->flag & GP_STROKE_CYCLIC);
}
}
if (no_xray) {
@@ -408,7 +411,7 @@ static void gp_draw_strokes(tGPDdraw *tgpw)
/* ----- General Drawing ------ */
/* wrapper to draw strokes for filling operator */
-void ED_gp_draw_fill(tGPDdraw *tgpw)
+void ED_gpencil_draw_fill(tGPDdraw *tgpw)
{
- gp_draw_strokes(tgpw);
+ gpencil_draw_strokes(tgpw);
}
diff --git a/source/blender/editors/gpencil/editaction_gpencil.c b/source/blender/editors/gpencil/editaction_gpencil.c
index d2b1eba7d86..752b8a74f4f 100644
--- a/source/blender/editors/gpencil/editaction_gpencil.c
+++ b/source/blender/editors/gpencil/editaction_gpencil.c
@@ -56,7 +56,9 @@
/* Generics - Loopers */
/* Loops over the gp-frames for a gp-layer, and applies the given callback */
-bool ED_gplayer_frames_looper(bGPDlayer *gpl, Scene *scene, short (*gpf_cb)(bGPDframe *, Scene *))
+bool ED_gpencil_layer_frames_looper(bGPDlayer *gpl,
+ Scene *scene,
+ short (*gpf_cb)(bGPDframe *, Scene *))
{
/* error checker */
if (gpl == NULL) {
@@ -79,7 +81,7 @@ bool ED_gplayer_frames_looper(bGPDlayer *gpl, Scene *scene, short (*gpf_cb)(bGPD
/* Data Conversion Tools */
/* make a listing all the gp-frames in a layer as cfraelems */
-void ED_gplayer_make_cfra_list(bGPDlayer *gpl, ListBase *elems, bool onlysel)
+void ED_gpencil_layer_make_cfra_list(bGPDlayer *gpl, ListBase *elems, bool onlysel)
{
CfraElem *ce;
@@ -105,7 +107,7 @@ void ED_gplayer_make_cfra_list(bGPDlayer *gpl, ListBase *elems, bool onlysel)
/* Selection Tools */
/* check if one of the frames in this layer is selected */
-bool ED_gplayer_frame_select_check(bGPDlayer *gpl)
+bool ED_gpencil_layer_frame_select_check(bGPDlayer *gpl)
{
/* error checking */
if (gpl == NULL) {
@@ -124,7 +126,7 @@ bool ED_gplayer_frame_select_check(bGPDlayer *gpl)
}
/* helper function - select gp-frame based on SELECT_* mode */
-static void gpframe_select(bGPDframe *gpf, short select_mode)
+static void gpencil_frame_select(bGPDframe *gpf, short select_mode)
{
if (gpf == NULL) {
return;
@@ -153,12 +155,12 @@ void ED_gpencil_select_frames(bGPDlayer *gpl, short select_mode)
/* handle according to mode */
LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
- gpframe_select(gpf, select_mode);
+ gpencil_frame_select(gpf, select_mode);
}
}
/* set all/none/invert select */
-void ED_gplayer_frame_select_set(bGPDlayer *gpl, short mode)
+void ED_gpencil_layer_frame_select_set(bGPDlayer *gpl, short mode)
{
/* error checking */
if (gpl == NULL) {
@@ -181,12 +183,12 @@ void ED_gpencil_select_frame(bGPDlayer *gpl, int selx, short select_mode)
gpf = BKE_gpencil_layer_frame_find(gpl, selx);
if (gpf) {
- gpframe_select(gpf, select_mode);
+ gpencil_frame_select(gpf, select_mode);
}
}
/* select the frames in this layer that occur within the bounds specified */
-void ED_gplayer_frames_select_box(bGPDlayer *gpl, float min, float max, short select_mode)
+void ED_gpencil_layer_frames_select_box(bGPDlayer *gpl, float min, float max, short select_mode)
{
if (gpl == NULL) {
return;
@@ -195,16 +197,16 @@ void ED_gplayer_frames_select_box(bGPDlayer *gpl, float min, float max, short se
/* only select those frames which are in bounds */
LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
if (IN_RANGE(gpf->framenum, min, max)) {
- gpframe_select(gpf, select_mode);
+ gpencil_frame_select(gpf, select_mode);
}
}
}
/* select the frames in this layer that occur within the lasso/circle region specified */
-void ED_gplayer_frames_select_region(KeyframeEditData *ked,
- bGPDlayer *gpl,
- short tool,
- short select_mode)
+void ED_gpencil_layer_frames_select_region(KeyframeEditData *ked,
+ bGPDlayer *gpl,
+ short tool,
+ short select_mode)
{
if (gpl == NULL) {
return;
@@ -222,13 +224,13 @@ void ED_gplayer_frames_select_region(KeyframeEditData *ked,
if (tool == BEZT_OK_CHANNEL_LASSO) {
/* Lasso */
if (keyframe_region_lasso_test(ked->data, pt)) {
- gpframe_select(gpf, select_mode);
+ gpencil_frame_select(gpf, select_mode);
}
}
else if (tool == BEZT_OK_CHANNEL_CIRCLE) {
/* Circle */
if (keyframe_region_circle_test(ked->data, pt)) {
- gpframe_select(gpf, select_mode);
+ gpencil_frame_select(gpf, select_mode);
}
}
}
@@ -238,7 +240,7 @@ void ED_gplayer_frames_select_region(KeyframeEditData *ked,
/* Frame Editing Tools */
/* Delete selected frames */
-bool ED_gplayer_frames_delete(bGPDlayer *gpl)
+bool ED_gpencil_layer_frames_delete(bGPDlayer *gpl)
{
bool changed = false;
@@ -259,7 +261,7 @@ bool ED_gplayer_frames_delete(bGPDlayer *gpl)
}
/* Duplicate selected frames from given gp-layer */
-void ED_gplayer_frames_duplicate(bGPDlayer *gpl)
+void ED_gpencil_layer_frames_duplicate(bGPDlayer *gpl)
{
/* error checking */
if (gpl == NULL) {
@@ -282,10 +284,12 @@ void ED_gplayer_frames_duplicate(bGPDlayer *gpl)
}
}
-/* Set keyframe type for selected frames from given gp-layer
- * \param type: The type of keyframe (eBezTriple_KeyframeType) to set selected frames to
+/**
+ * Set keyframe type for selected frames from given gp-layer
+ *
+ * \param type: The type of keyframe (#eBezTriple_KeyframeType) to set selected frames to.
*/
-void ED_gplayer_frames_keytype_set(bGPDlayer *gpl, short type)
+void ED_gpencil_layer_frames_keytype_set(bGPDlayer *gpl, short type)
{
if (gpl == NULL) {
return;
@@ -311,20 +315,20 @@ void ED_gplayer_frames_keytype_set(bGPDlayer *gpl, short type)
*/
/* globals for copy/paste data (like for other copy/paste buffers) */
-static ListBase gp_anim_copybuf = {NULL, NULL};
-static int gp_anim_copy_firstframe = 999999999;
-static int gp_anim_copy_lastframe = -999999999;
-static int gp_anim_copy_cfra = 0;
+static ListBase gpencil_anim_copybuf = {NULL, NULL};
+static int gpencil_anim_copy_firstframe = 999999999;
+static int gpencil_anim_copy_lastframe = -999999999;
+static int gpencil_anim_copy_cfra = 0;
/* This function frees any MEM_calloc'ed copy/paste buffer data */
void ED_gpencil_anim_copybuf_free(void)
{
- BKE_gpencil_free_layers(&gp_anim_copybuf);
- BLI_listbase_clear(&gp_anim_copybuf);
+ BKE_gpencil_free_layers(&gpencil_anim_copybuf);
+ BLI_listbase_clear(&gpencil_anim_copybuf);
- gp_anim_copy_firstframe = 999999999;
- gp_anim_copy_lastframe = -999999999;
- gp_anim_copy_cfra = 0;
+ gpencil_anim_copy_firstframe = 999999999;
+ gpencil_anim_copy_lastframe = -999999999;
+ gpencil_anim_copy_cfra = 0;
}
/* This function adds data to the copy/paste buffer, freeing existing data first
@@ -361,11 +365,11 @@ bool ED_gpencil_anim_copybuf_copy(bAnimContext *ac)
BLI_addtail(&copied_frames, new_frame);
/* extend extents for keyframes encountered */
- if (gpf->framenum < gp_anim_copy_firstframe) {
- gp_anim_copy_firstframe = gpf->framenum;
+ if (gpf->framenum < gpencil_anim_copy_firstframe) {
+ gpencil_anim_copy_firstframe = gpf->framenum;
}
- if (gpf->framenum > gp_anim_copy_lastframe) {
- gp_anim_copy_lastframe = gpf->framenum;
+ if (gpf->framenum > gpencil_anim_copy_lastframe) {
+ gpencil_anim_copy_lastframe = gpf->framenum;
}
}
}
@@ -373,7 +377,7 @@ bool ED_gpencil_anim_copybuf_copy(bAnimContext *ac)
/* create a new layer in buffer if there were keyframes here */
if (BLI_listbase_is_empty(&copied_frames) == false) {
bGPDlayer *new_layer = MEM_callocN(sizeof(bGPDlayer), "GPCopyPasteLayer");
- BLI_addtail(&gp_anim_copybuf, new_layer);
+ BLI_addtail(&gpencil_anim_copybuf, new_layer);
/* move over copied frames */
BLI_movelisttolist(&new_layer->frames, &copied_frames);
@@ -385,13 +389,13 @@ bool ED_gpencil_anim_copybuf_copy(bAnimContext *ac)
}
/* in case 'relative' paste method is used */
- gp_anim_copy_cfra = CFRA;
+ gpencil_anim_copy_cfra = CFRA;
/* clean up */
ANIM_animdata_freelist(&anim_data);
/* check if anything ended up in the buffer */
- if (ELEM(NULL, gp_anim_copybuf.first, gp_anim_copybuf.last)) {
+ if (ELEM(NULL, gpencil_anim_copybuf.first, gpencil_anim_copybuf.last)) {
BKE_report(ac->reports, RPT_ERROR, "No keyframes copied to keyframes copy/paste buffer");
return false;
}
@@ -412,26 +416,26 @@ bool ED_gpencil_anim_copybuf_paste(bAnimContext *ac, const short offset_mode)
int offset = 0;
/* check if buffer is empty */
- if (BLI_listbase_is_empty(&gp_anim_copybuf)) {
+ if (BLI_listbase_is_empty(&gpencil_anim_copybuf)) {
BKE_report(ac->reports, RPT_ERROR, "No data in buffer to paste");
return false;
}
/* check if single channel in buffer (disregard names if so) */
- if (gp_anim_copybuf.first == gp_anim_copybuf.last) {
+ if (gpencil_anim_copybuf.first == gpencil_anim_copybuf.last) {
no_name = true;
}
/* methods of offset (eKeyPasteOffset) */
switch (offset_mode) {
case KEYFRAME_PASTE_OFFSET_CFRA_START:
- offset = (CFRA - gp_anim_copy_firstframe);
+ offset = (CFRA - gpencil_anim_copy_firstframe);
break;
case KEYFRAME_PASTE_OFFSET_CFRA_END:
- offset = (CFRA - gp_anim_copy_lastframe);
+ offset = (CFRA - gpencil_anim_copy_lastframe);
break;
case KEYFRAME_PASTE_OFFSET_CFRA_RELATIVE:
- offset = (CFRA - gp_anim_copy_cfra);
+ offset = (CFRA - gpencil_anim_copy_cfra);
break;
case KEYFRAME_PASTE_OFFSET_NONE:
offset = 0;
@@ -451,7 +455,7 @@ bool ED_gpencil_anim_copybuf_paste(bAnimContext *ac, const short offset_mode)
bGPDframe *gpfs, *gpf;
/* find suitable layer from buffer to use to paste from */
- for (gpls = gp_anim_copybuf.first; gpls; gpls = gpls->next) {
+ for (gpls = gpencil_anim_copybuf.first; gpls; gpls = gpls->next) {
/* check if layer name matches */
if ((no_name) || STREQ(gpls->info, gpld->info)) {
break;
@@ -507,7 +511,7 @@ bool ED_gpencil_anim_copybuf_paste(bAnimContext *ac, const short offset_mode)
/* -------------------------------------- */
/* Snap Tools */
-static short snap_gpf_nearest(bGPDframe *UNUSED(gpf), Scene *UNUSED(scene))
+static short gpencil_frame_snap_nearest(bGPDframe *UNUSED(gpf), Scene *UNUSED(scene))
{
#if 0 /* note: gpf->framenum is already an int! */
if (gpf->flag & GP_FRAME_SELECT) {
@@ -517,7 +521,7 @@ static short snap_gpf_nearest(bGPDframe *UNUSED(gpf), Scene *UNUSED(scene))
return 0;
}
-static short snap_gpf_nearestsec(bGPDframe *gpf, Scene *scene)
+static short gpencil_frame_snap_nearestsec(bGPDframe *gpf, Scene *scene)
{
float secf = (float)FPS;
if (gpf->flag & GP_FRAME_SELECT) {
@@ -526,7 +530,7 @@ static short snap_gpf_nearestsec(bGPDframe *gpf, Scene *scene)
return 0;
}
-static short snap_gpf_cframe(bGPDframe *gpf, Scene *scene)
+static short gpencil_frame_snap_cframe(bGPDframe *gpf, Scene *scene)
{
if (gpf->flag & GP_FRAME_SELECT) {
gpf->framenum = (int)CFRA;
@@ -534,7 +538,7 @@ static short snap_gpf_cframe(bGPDframe *gpf, Scene *scene)
return 0;
}
-static short snap_gpf_nearmarker(bGPDframe *gpf, Scene *scene)
+static short gpencil_frame_snap_nearmarker(bGPDframe *gpf, Scene *scene)
{
if (gpf->flag & GP_FRAME_SELECT) {
gpf->framenum = (int)ED_markers_find_nearest_marker_time(&scene->markers,
@@ -544,20 +548,20 @@ static short snap_gpf_nearmarker(bGPDframe *gpf, Scene *scene)
}
/* snap selected frames to ... */
-void ED_gplayer_snap_frames(bGPDlayer *gpl, Scene *scene, short mode)
+void ED_gpencil_layer_snap_frames(bGPDlayer *gpl, Scene *scene, short mode)
{
switch (mode) {
case SNAP_KEYS_NEARFRAME: /* snap to nearest frame */
- ED_gplayer_frames_looper(gpl, scene, snap_gpf_nearest);
+ ED_gpencil_layer_frames_looper(gpl, scene, gpencil_frame_snap_nearest);
break;
case SNAP_KEYS_CURFRAME: /* snap to current frame */
- ED_gplayer_frames_looper(gpl, scene, snap_gpf_cframe);
+ ED_gpencil_layer_frames_looper(gpl, scene, gpencil_frame_snap_cframe);
break;
case SNAP_KEYS_NEARMARKER: /* snap to nearest marker */
- ED_gplayer_frames_looper(gpl, scene, snap_gpf_nearmarker);
+ ED_gpencil_layer_frames_looper(gpl, scene, gpencil_frame_snap_nearmarker);
break;
case SNAP_KEYS_NEARSEC: /* snap to nearest second */
- ED_gplayer_frames_looper(gpl, scene, snap_gpf_nearestsec);
+ ED_gpencil_layer_frames_looper(gpl, scene, gpencil_frame_snap_nearestsec);
break;
default: /* just in case */
break;
@@ -567,7 +571,7 @@ void ED_gplayer_snap_frames(bGPDlayer *gpl, Scene *scene, short mode)
/* -------------------------------------- */
/* Mirror Tools */
-static short mirror_gpf_cframe(bGPDframe *gpf, Scene *scene)
+static short gpencil_frame_mirror_cframe(bGPDframe *gpf, Scene *scene)
{
int diff;
@@ -579,7 +583,7 @@ static short mirror_gpf_cframe(bGPDframe *gpf, Scene *scene)
return 0;
}
-static short mirror_gpf_yaxis(bGPDframe *gpf, Scene *UNUSED(scene))
+static short gpencil_frame_mirror_yaxis(bGPDframe *gpf, Scene *UNUSED(scene))
{
int diff;
@@ -591,7 +595,7 @@ static short mirror_gpf_yaxis(bGPDframe *gpf, Scene *UNUSED(scene))
return 0;
}
-static short mirror_gpf_xaxis(bGPDframe *gpf, Scene *UNUSED(scene))
+static short gpencil_frame_mirror_xaxis(bGPDframe *gpf, Scene *UNUSED(scene))
{
int diff;
@@ -604,7 +608,7 @@ static short mirror_gpf_xaxis(bGPDframe *gpf, Scene *UNUSED(scene))
return 0;
}
-static short mirror_gpf_marker(bGPDframe *gpf, Scene *scene)
+static short gpencil_frame_mirror_marker(bGPDframe *gpf, Scene *scene)
{
static TimeMarker *marker;
static short initialized = 0;
@@ -646,25 +650,25 @@ static short mirror_gpf_marker(bGPDframe *gpf, Scene *scene)
/* mirror selected gp-frames on... */
// TODO: mirror over a specific time
-void ED_gplayer_mirror_frames(bGPDlayer *gpl, Scene *scene, short mode)
+void ED_gpencil_layer_mirror_frames(bGPDlayer *gpl, Scene *scene, short mode)
{
switch (mode) {
case MIRROR_KEYS_CURFRAME: /* mirror over current frame */
- ED_gplayer_frames_looper(gpl, scene, mirror_gpf_cframe);
+ ED_gpencil_layer_frames_looper(gpl, scene, gpencil_frame_mirror_cframe);
break;
case MIRROR_KEYS_YAXIS: /* mirror over frame 0 */
- ED_gplayer_frames_looper(gpl, scene, mirror_gpf_yaxis);
+ ED_gpencil_layer_frames_looper(gpl, scene, gpencil_frame_mirror_yaxis);
break;
case MIRROR_KEYS_XAXIS: /* mirror over value 0 */
- ED_gplayer_frames_looper(gpl, scene, mirror_gpf_xaxis);
+ ED_gpencil_layer_frames_looper(gpl, scene, gpencil_frame_mirror_xaxis);
break;
case MIRROR_KEYS_MARKER: /* mirror over marker */
- mirror_gpf_marker(NULL, scene);
- ED_gplayer_frames_looper(gpl, scene, mirror_gpf_marker);
- mirror_gpf_marker(NULL, scene);
+ gpencil_frame_mirror_marker(NULL, scene);
+ ED_gpencil_layer_frames_looper(gpl, scene, gpencil_frame_mirror_marker);
+ gpencil_frame_mirror_marker(NULL, scene);
break;
default: /* just in case */
- ED_gplayer_frames_looper(gpl, scene, mirror_gpf_yaxis);
+ ED_gpencil_layer_frames_looper(gpl, scene, gpencil_frame_mirror_yaxis);
break;
}
}
diff --git a/source/blender/editors/gpencil/gpencil_add_stroke.c b/source/blender/editors/gpencil/gpencil_add_stroke.c
index 60a4404beaf..39a2d594c13 100644
--- a/source/blender/editors/gpencil/gpencil_add_stroke.c
+++ b/source/blender/editors/gpencil/gpencil_add_stroke.c
@@ -49,7 +49,10 @@ typedef struct ColorTemplate {
} ColorTemplate;
/* Add color an ensure duplications (matched by name) */
-static int gp_stroke_material(Main *bmain, Object *ob, const ColorTemplate *pct, const bool fill)
+static int gpencil_stroke_material(Main *bmain,
+ Object *ob,
+ const ColorTemplate *pct,
+ const bool fill)
{
short *totcol = BKE_object_material_len_p(ob);
Material *ma = NULL;
@@ -224,12 +227,12 @@ void ED_gpencil_create_stroke(bContext *C, Object *ob, float mat[4][4])
bGPDstroke *gps;
/* create colors */
- int color_black = gp_stroke_material(bmain, ob, &gp_stroke_material_black, false);
- gp_stroke_material(bmain, ob, &gp_stroke_material_white, false);
- gp_stroke_material(bmain, ob, &gp_stroke_material_red, false);
- gp_stroke_material(bmain, ob, &gp_stroke_material_green, false);
- gp_stroke_material(bmain, ob, &gp_stroke_material_blue, false);
- gp_stroke_material(bmain, ob, &gp_stroke_material_grey, true);
+ int color_black = gpencil_stroke_material(bmain, ob, &gp_stroke_material_black, false);
+ gpencil_stroke_material(bmain, ob, &gp_stroke_material_white, false);
+ gpencil_stroke_material(bmain, ob, &gp_stroke_material_red, false);
+ gpencil_stroke_material(bmain, ob, &gp_stroke_material_green, false);
+ gpencil_stroke_material(bmain, ob, &gp_stroke_material_blue, false);
+ gpencil_stroke_material(bmain, ob, &gp_stroke_material_grey, true);
/* set first color as active and in brushes */
ob->actcol = color_black + 1;
diff --git a/source/blender/editors/gpencil/gpencil_convert.c b/source/blender/editors/gpencil/gpencil_convert.c
index 78a34cda2f5..e111ce44bc4 100644
--- a/source/blender/editors/gpencil/gpencil_convert.c
+++ b/source/blender/editors/gpencil/gpencil_convert.c
@@ -54,8 +54,11 @@
#include "BKE_fcurve.h"
#include "BKE_global.h"
#include "BKE_gpencil.h"
+#include "BKE_gpencil_geom.h"
+#include "BKE_image.h"
#include "BKE_layer.h"
#include "BKE_main.h"
+#include "BKE_material.h"
#include "BKE_object.h"
#include "BKE_report.h"
#include "BKE_scene.h"
@@ -151,12 +154,12 @@ static const EnumPropertyItem *rna_GPConvert_mode_items(bContext *UNUSED(C),
/* convert the coordinates from the given stroke point into 3d-coordinates
* - assumes that the active space is the 3D-View
*/
-static void gp_strokepoint_convertcoords(bContext *C,
- bGPDlayer *gpl,
- bGPDstroke *gps,
- bGPDspoint *source_pt,
- float p3d[3],
- const rctf *subrect)
+static void gpencil_strokepoint_convertcoords(bContext *C,
+ bGPDlayer *gpl,
+ bGPDstroke *gps,
+ bGPDspoint *source_pt,
+ float p3d[3],
+ const rctf *subrect)
{
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C);
@@ -240,7 +243,7 @@ typedef struct tGpTimingData {
/* Init point buffers for timing data.
* Note this assumes we only grow those arrays!
*/
-static void gp_timing_data_set_nbr(tGpTimingData *gtd, const int nbr)
+static void gpencil_timing_data_set_nbr(tGpTimingData *gtd, const int nbr)
{
float *tmp;
@@ -266,10 +269,10 @@ static void gp_timing_data_set_nbr(tGpTimingData *gtd, const int nbr)
}
/* add stroke point to timing buffers */
-static void gp_timing_data_add_point(tGpTimingData *gtd,
- const double stroke_inittime,
- const float time,
- const float delta_dist)
+static void gpencil_timing_data_add_point(tGpTimingData *gtd,
+ const double stroke_inittime,
+ const float time,
+ const float delta_dist)
{
float delta_time = 0.0f;
const int cur_point = gtd->cur_point;
@@ -305,14 +308,14 @@ static void gp_timing_data_add_point(tGpTimingData *gtd,
#define MIN_TIME_DELTA 0.02f
/* Loop over next points to find the end of the stroke, and compute */
-static int gp_find_end_of_stroke_idx(tGpTimingData *gtd,
- RNG *rng,
- const int idx,
- const int nbr_gaps,
- int *nbr_done_gaps,
- const float tot_gaps_time,
- const float delta_time,
- float *next_delta_time)
+static int gpencil_find_end_of_stroke_idx(tGpTimingData *gtd,
+ RNG *rng,
+ const int idx,
+ const int nbr_gaps,
+ int *nbr_done_gaps,
+ const float tot_gaps_time,
+ const float delta_time,
+ float *next_delta_time)
{
int j;
@@ -362,10 +365,10 @@ static int gp_find_end_of_stroke_idx(tGpTimingData *gtd,
return j - 1;
}
-static void gp_stroke_path_animation_preprocess_gaps(tGpTimingData *gtd,
- RNG *rng,
- int *nbr_gaps,
- float *tot_gaps_time)
+static void gpencil_stroke_path_animation_preprocess_gaps(tGpTimingData *gtd,
+ RNG *rng,
+ int *nbr_gaps,
+ float *tot_gaps_time)
{
int i;
float delta_time = 0.0f;
@@ -393,16 +396,16 @@ static void gp_stroke_path_animation_preprocess_gaps(tGpTimingData *gtd,
}
}
-static void gp_stroke_path_animation_add_keyframes(ReportList *reports,
- PointerRNA ptr,
- PropertyRNA *prop,
- FCurve *fcu,
- Curve *cu,
- tGpTimingData *gtd,
- RNG *rng,
- const float time_range,
- const int nbr_gaps,
- const float tot_gaps_time)
+static void gpencil_stroke_path_animation_add_keyframes(ReportList *reports,
+ PointerRNA ptr,
+ PropertyRNA *prop,
+ FCurve *fcu,
+ Curve *cu,
+ tGpTimingData *gtd,
+ RNG *rng,
+ const float time_range,
+ const int nbr_gaps,
+ const float tot_gaps_time)
{
/* Use actual recorded timing! */
const float time_start = (float)gtd->start_frame;
@@ -428,7 +431,7 @@ static void gp_stroke_path_animation_add_keyframes(ReportList *reports,
start_stroke_idx = i;
delta_time = next_delta_time;
/* find end of that new stroke */
- end_stroke_idx = gp_find_end_of_stroke_idx(
+ end_stroke_idx = gpencil_find_end_of_stroke_idx(
gtd, rng, i, nbr_gaps, &nbr_done_gaps, tot_gaps_time, delta_time, &next_delta_time);
/* This one should *never* be negative! */
end_stroke_time = time_start +
@@ -486,10 +489,10 @@ static void gp_stroke_path_animation_add_keyframes(ReportList *reports,
}
}
-static void gp_stroke_path_animation(bContext *C,
- ReportList *reports,
- Curve *cu,
- tGpTimingData *gtd)
+static void gpencil_stroke_path_animation(bContext *C,
+ ReportList *reports,
+ Curve *cu,
+ tGpTimingData *gtd)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
@@ -557,7 +560,7 @@ static void gp_stroke_path_animation(bContext *C,
/* Pre-process gaps, in case we don't want to keep their original timing */
if (gtd->mode == GP_STROKECONVERT_TIMING_CUSTOMGAP) {
- gp_stroke_path_animation_preprocess_gaps(gtd, rng, &nbr_gaps, &tot_gaps_time);
+ gpencil_stroke_path_animation_preprocess_gaps(gtd, rng, &nbr_gaps, &tot_gaps_time);
}
if (gtd->realtime) {
@@ -571,7 +574,7 @@ static void gp_stroke_path_animation(bContext *C,
printf("GP Stroke Path Conversion: Starting keying!\n");
}
- gp_stroke_path_animation_add_keyframes(
+ gpencil_stroke_path_animation_add_keyframes(
reports, ptr, prop, fcu, cu, gtd, rng, time_range, nbr_gaps, tot_gaps_time);
BLI_rng_free(rng);
@@ -603,16 +606,16 @@ static void gp_stroke_path_animation(bContext *C,
/* convert stroke to 3d path */
/* helper */
-static void gp_stroke_to_path_add_point(tGpTimingData *gtd,
- BPoint *bp,
- const float p[3],
- const float prev_p[3],
- const bool do_gtd,
- const double inittime,
- const float time,
- const float width,
- const float rad_fac,
- float minmax_weights[2])
+static void gpencil_stroke_to_path_add_point(tGpTimingData *gtd,
+ BPoint *bp,
+ const float p[3],
+ const float prev_p[3],
+ const bool do_gtd,
+ const double inittime,
+ const float time,
+ const float width,
+ const float rad_fac,
+ float minmax_weights[2])
{
copy_v3_v3(bp->vec, p);
bp->vec[3] = 1.0f;
@@ -631,22 +634,22 @@ static void gp_stroke_to_path_add_point(tGpTimingData *gtd,
/* Update timing data */
if (do_gtd) {
- gp_timing_data_add_point(gtd, inittime, time, len_v3v3(prev_p, p));
+ gpencil_timing_data_add_point(gtd, inittime, time, len_v3v3(prev_p, p));
}
}
-static void gp_stroke_to_path(bContext *C,
- bGPDlayer *gpl,
- bGPDstroke *gps,
- Curve *cu,
- rctf *subrect,
- Nurb **curnu,
- float minmax_weights[2],
- const float rad_fac,
- bool stitch,
- const bool add_start_point,
- const bool add_end_point,
- tGpTimingData *gtd)
+static void gpencil_stroke_to_path(bContext *C,
+ bGPDlayer *gpl,
+ bGPDstroke *gps,
+ Curve *cu,
+ rctf *subrect,
+ Nurb **curnu,
+ float minmax_weights[2],
+ const float rad_fac,
+ bool stitch,
+ const bool add_start_point,
+ const bool add_end_point,
+ tGpTimingData *gtd)
{
bGPDspoint *pt;
Nurb *nu = (curnu) ? *curnu : NULL;
@@ -682,7 +685,7 @@ static void gp_stroke_to_path(bContext *C,
}
if (do_gtd) {
- gp_timing_data_set_nbr(gtd, nu->pntsu);
+ gpencil_timing_data_set_nbr(gtd, nu->pntsu);
}
/* If needed, make the link between both strokes with two zero-radius additional points */
@@ -710,7 +713,7 @@ static void gp_stroke_to_path(bContext *C,
bp = &nu->bp[old_nbp - 1];
/* First point */
- gp_strokepoint_convertcoords(C, gpl, gps, gps->points, p, subrect);
+ gpencil_strokepoint_convertcoords(C, gpl, gps, gps->points, p, subrect);
if (prev_bp) {
interp_v3_v3v3(p1, bp->vec, prev_bp->vec, -GAP_DFAC);
if (do_gtd) {
@@ -725,21 +728,21 @@ static void gp_stroke_to_path(bContext *C,
}
}
bp++;
- gp_stroke_to_path_add_point(gtd,
- bp,
- p1,
- (bp - 1)->vec,
- do_gtd,
- gps->prev->inittime,
- dt1,
- 0.0f,
- rad_fac,
- minmax_weights);
+ gpencil_stroke_to_path_add_point(gtd,
+ bp,
+ p1,
+ (bp - 1)->vec,
+ do_gtd,
+ gps->prev->inittime,
+ dt1,
+ 0.0f,
+ rad_fac,
+ minmax_weights);
/* Second point */
/* Note dt2 is always negative, which marks the gap. */
if (gps->totpoints > 1) {
- gp_strokepoint_convertcoords(C, gpl, gps, gps->points + 1, next_p, subrect);
+ gpencil_strokepoint_convertcoords(C, gpl, gps, gps->points + 1, next_p, subrect);
interp_v3_v3v3(p2, p, next_p, -GAP_DFAC);
if (do_gtd) {
dt2 = interpf(gps->points[1].time, gps->points[0].time, -GAP_DFAC);
@@ -752,7 +755,7 @@ static void gp_stroke_to_path(bContext *C,
}
}
bp++;
- gp_stroke_to_path_add_point(
+ gpencil_stroke_to_path_add_point(
gtd, bp, p2, p1, do_gtd, gps->inittime, dt2, 0.0f, rad_fac, minmax_weights);
old_nbp += 2;
@@ -761,9 +764,9 @@ static void gp_stroke_to_path(bContext *C,
float p[3], next_p[3];
float dt = 0.0f;
- gp_strokepoint_convertcoords(C, gpl, gps, gps->points, p, subrect);
+ gpencil_strokepoint_convertcoords(C, gpl, gps, gps->points, p, subrect);
if (gps->totpoints > 1) {
- gp_strokepoint_convertcoords(C, gpl, gps, gps->points + 1, next_p, subrect);
+ gpencil_strokepoint_convertcoords(C, gpl, gps, gps->points + 1, next_p, subrect);
interp_v3_v3v3(p, p, next_p, -GAP_DFAC);
if (do_gtd) {
dt = interpf(gps->points[1].time, gps->points[0].time, -GAP_DFAC);
@@ -778,7 +781,7 @@ static void gp_stroke_to_path(bContext *C,
* (which would be expected value) would not work
* (it would be *before* gtd->inittime, which is not supported currently).
*/
- gp_stroke_to_path_add_point(
+ gpencil_stroke_to_path_add_point(
gtd, bp, p, p, do_gtd, gps->inittime, dt, 0.0f, rad_fac, minmax_weights);
old_nbp++;
@@ -796,18 +799,18 @@ static void gp_stroke_to_path(bContext *C,
float width = pt->pressure * (gps->thickness + gpl->line_change) * WIDTH_CORR_FAC;
/* get coordinates to add at */
- gp_strokepoint_convertcoords(C, gpl, gps, pt, p, subrect);
-
- gp_stroke_to_path_add_point(gtd,
- bp,
- p,
- (prev_bp) ? prev_bp->vec : p,
- do_gtd,
- gps->inittime,
- pt->time,
- width,
- rad_fac,
- minmax_weights);
+ gpencil_strokepoint_convertcoords(C, gpl, gps, pt, p, subrect);
+
+ gpencil_stroke_to_path_add_point(gtd,
+ bp,
+ p,
+ (prev_bp) ? prev_bp->vec : p,
+ do_gtd,
+ gps->inittime,
+ pt->time,
+ width,
+ rad_fac,
+ minmax_weights);
prev_bp = bp;
}
@@ -829,7 +832,7 @@ static void gp_stroke_to_path(bContext *C,
dt = GAP_DFAC; /* Rather arbitrary too! */
}
/* Note bp has already been incremented in main loop above, so it points to the right place. */
- gp_stroke_to_path_add_point(
+ gpencil_stroke_to_path_add_point(
gtd, bp, p, prev_bp->vec, do_gtd, gps->inittime, dt, 0.0f, rad_fac, minmax_weights);
}
@@ -847,18 +850,18 @@ static void gp_stroke_to_path(bContext *C,
/* convert stroke to 3d bezier */
/* helper */
-static void gp_stroke_to_bezier_add_point(tGpTimingData *gtd,
- BezTriple *bezt,
- const float p[3],
- const float h1[3],
- const float h2[3],
- const float prev_p[3],
- const bool do_gtd,
- const double inittime,
- const float time,
- const float width,
- const float rad_fac,
- float minmax_weights[2])
+static void gpencil_stroke_to_bezier_add_point(tGpTimingData *gtd,
+ BezTriple *bezt,
+ const float p[3],
+ const float h1[3],
+ const float h2[3],
+ const float prev_p[3],
+ const bool do_gtd,
+ const double inittime,
+ const float time,
+ const float width,
+ const float rad_fac,
+ float minmax_weights[2])
{
copy_v3_v3(bezt->vec[0], h1);
copy_v3_v3(bezt->vec[1], p);
@@ -879,22 +882,22 @@ static void gp_stroke_to_bezier_add_point(tGpTimingData *gtd,
/* Update timing data */
if (do_gtd) {
- gp_timing_data_add_point(gtd, inittime, time, len_v3v3(prev_p, p));
+ gpencil_timing_data_add_point(gtd, inittime, time, len_v3v3(prev_p, p));
}
}
-static void gp_stroke_to_bezier(bContext *C,
- bGPDlayer *gpl,
- bGPDstroke *gps,
- Curve *cu,
- rctf *subrect,
- Nurb **curnu,
- float minmax_weights[2],
- const float rad_fac,
- bool stitch,
- const bool add_start_point,
- const bool add_end_point,
- tGpTimingData *gtd)
+static void gpencil_stroke_to_bezier(bContext *C,
+ bGPDlayer *gpl,
+ bGPDstroke *gps,
+ Curve *cu,
+ rctf *subrect,
+ Nurb **curnu,
+ float minmax_weights[2],
+ const float rad_fac,
+ bool stitch,
+ const bool add_start_point,
+ const bool add_end_point,
+ tGpTimingData *gtd)
{
bGPDspoint *pt;
Nurb *nu = (curnu) ? *curnu : NULL;
@@ -927,7 +930,7 @@ static void gp_stroke_to_bezier(bContext *C,
}
if (do_gtd) {
- gp_timing_data_set_nbr(gtd, nu->pntsu);
+ gpencil_timing_data_set_nbr(gtd, nu->pntsu);
}
tot = gps->totpoints;
@@ -935,12 +938,13 @@ static void gp_stroke_to_bezier(bContext *C,
/* get initial coordinates */
pt = gps->points;
if (tot) {
- gp_strokepoint_convertcoords(C, gpl, gps, pt, (stitch) ? p3d_prev : p3d_cur, subrect);
+ gpencil_strokepoint_convertcoords(C, gpl, gps, pt, (stitch) ? p3d_prev : p3d_cur, subrect);
if (tot > 1) {
- gp_strokepoint_convertcoords(C, gpl, gps, pt + 1, (stitch) ? p3d_cur : p3d_next, subrect);
+ gpencil_strokepoint_convertcoords(
+ C, gpl, gps, pt + 1, (stitch) ? p3d_cur : p3d_next, subrect);
}
if (stitch && tot > 2) {
- gp_strokepoint_convertcoords(C, gpl, gps, pt + 2, p3d_next, subrect);
+ gpencil_strokepoint_convertcoords(C, gpl, gps, pt + 2, p3d_next, subrect);
}
}
@@ -1017,24 +1021,24 @@ static void gp_stroke_to_bezier(bContext *C,
interp_v3_v3v3(h1, p1, bezt->vec[1], BEZT_HANDLE_FAC);
interp_v3_v3v3(h2, p1, p2, BEZT_HANDLE_FAC);
bezt++;
- gp_stroke_to_bezier_add_point(gtd,
- bezt,
- p1,
- h1,
- h2,
- (bezt - 1)->vec[1],
- do_gtd,
- gps->prev->inittime,
- dt1,
- 0.0f,
- rad_fac,
- minmax_weights);
+ gpencil_stroke_to_bezier_add_point(gtd,
+ bezt,
+ p1,
+ h1,
+ h2,
+ (bezt - 1)->vec[1],
+ do_gtd,
+ gps->prev->inittime,
+ dt1,
+ 0.0f,
+ rad_fac,
+ minmax_weights);
/* Second point */
interp_v3_v3v3(h1, p2, p1, BEZT_HANDLE_FAC);
interp_v3_v3v3(h2, p2, p3d_cur, BEZT_HANDLE_FAC);
bezt++;
- gp_stroke_to_bezier_add_point(
+ gpencil_stroke_to_bezier_add_point(
gtd, bezt, p2, h1, h2, p1, do_gtd, gps->inittime, dt2, 0.0f, rad_fac, minmax_weights);
old_nbezt += 2;
@@ -1059,7 +1063,7 @@ static void gp_stroke_to_bezier(bContext *C,
interp_v3_v3v3(h1, p, p3d_cur, -BEZT_HANDLE_FAC);
interp_v3_v3v3(h2, p, p3d_cur, BEZT_HANDLE_FAC);
bezt = &nu->bezt[old_nbezt];
- gp_stroke_to_bezier_add_point(
+ gpencil_stroke_to_bezier_add_point(
gtd, bezt, p, h1, h2, p, do_gtd, gps->inittime, dt, 0.0f, rad_fac, minmax_weights);
old_nbezt++;
@@ -1088,25 +1092,25 @@ static void gp_stroke_to_bezier(bContext *C,
interp_v3_v3v3(h2, p3d_cur, p3d_prev, -BEZT_HANDLE_FAC);
}
- gp_stroke_to_bezier_add_point(gtd,
- bezt,
- p3d_cur,
- h1,
- h2,
- prev_bezt ? prev_bezt->vec[1] : p3d_cur,
- do_gtd,
- gps->inittime,
- pt->time,
- width,
- rad_fac,
- minmax_weights);
+ gpencil_stroke_to_bezier_add_point(gtd,
+ bezt,
+ p3d_cur,
+ h1,
+ h2,
+ prev_bezt ? prev_bezt->vec[1] : p3d_cur,
+ do_gtd,
+ gps->inittime,
+ pt->time,
+ width,
+ rad_fac,
+ minmax_weights);
/* shift coord vects */
copy_v3_v3(p3d_prev, p3d_cur);
copy_v3_v3(p3d_cur, p3d_next);
if (i + 2 < tot) {
- gp_strokepoint_convertcoords(C, gpl, gps, pt + 2, p3d_next, subrect);
+ gpencil_strokepoint_convertcoords(C, gpl, gps, pt + 2, p3d_next, subrect);
}
prev_bezt = bezt;
@@ -1138,18 +1142,18 @@ static void gp_stroke_to_bezier(bContext *C,
interp_v3_v3v3(h2, p, prev_bezt->vec[1], -BEZT_HANDLE_FAC);
/* Note bezt has already been incremented in main loop above,
* so it points to the right place. */
- gp_stroke_to_bezier_add_point(gtd,
- bezt,
- p,
- h1,
- h2,
- prev_bezt->vec[1],
- do_gtd,
- gps->inittime,
- dt,
- 0.0f,
- rad_fac,
- minmax_weights);
+ gpencil_stroke_to_bezier_add_point(gtd,
+ bezt,
+ p,
+ h1,
+ h2,
+ prev_bezt->vec[1],
+ do_gtd,
+ gps->inittime,
+ dt,
+ 0.0f,
+ rad_fac,
+ minmax_weights);
}
/* must calculate handles or else we crash */
@@ -1167,7 +1171,7 @@ static void gp_stroke_to_bezier(bContext *C,
#undef WIDTH_CORR_FAC
#undef BEZT_HANDLE_FAC
-static void gp_stroke_finalize_curve_endpoints(Curve *cu)
+static void gpencil_stroke_finalize_curve_endpoints(Curve *cu)
{
/* start */
Nurb *nu = cu->nurb.first;
@@ -1202,7 +1206,7 @@ static void gp_stroke_finalize_curve_endpoints(Curve *cu)
}
}
-static void gp_stroke_norm_curve_weights(Curve *cu, const float minmax_weights[2])
+static void gpencil_stroke_norm_curve_weights(Curve *cu, const float minmax_weights[2])
{
Nurb *nu;
const float delta = minmax_weights[0];
@@ -1233,7 +1237,7 @@ static void gp_stroke_norm_curve_weights(Curve *cu, const float minmax_weights[2
}
}
-static int gp_camera_view_subrect(bContext *C, rctf *subrect)
+static int gpencil_camera_view_subrect(bContext *C, rctf *subrect)
{
View3D *v3d = CTX_wm_view3d(C);
ARegion *region = CTX_wm_region(C);
@@ -1255,15 +1259,15 @@ static int gp_camera_view_subrect(bContext *C, rctf *subrect)
/* convert a given grease-pencil layer to a 3d-curve representation
* (using current view if appropriate) */
-static void gp_layer_to_curve(bContext *C,
- ReportList *reports,
- bGPdata *gpd,
- bGPDlayer *gpl,
- const int mode,
- const bool norm_weights,
- const float rad_fac,
- const bool link_strokes,
- tGpTimingData *gtd)
+static void gpencil_layer_to_curve(bContext *C,
+ ReportList *reports,
+ bGPdata *gpd,
+ bGPDlayer *gpl,
+ const int mode,
+ const bool norm_weights,
+ const float rad_fac,
+ const bool link_strokes,
+ tGpTimingData *gtd)
{
struct Main *bmain = CTX_data_main(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
@@ -1292,7 +1296,7 @@ static void gp_layer_to_curve(bContext *C,
}
/* initialize camera framing */
- if (gp_camera_view_subrect(C, &subrect)) {
+ if (gpencil_camera_view_subrect(C, &subrect)) {
subrect_ptr = &subrect;
}
@@ -1335,33 +1339,33 @@ static void gp_layer_to_curve(bContext *C,
switch (mode) {
case GP_STROKECONVERT_PATH:
- gp_stroke_to_path(C,
- gpl,
- gps,
- cu,
- subrect_ptr,
- &nu,
- minmax_weights,
- rad_fac,
- stitch,
- add_start_point,
- add_end_point,
- gtd);
+ gpencil_stroke_to_path(C,
+ gpl,
+ gps,
+ cu,
+ subrect_ptr,
+ &nu,
+ minmax_weights,
+ rad_fac,
+ stitch,
+ add_start_point,
+ add_end_point,
+ gtd);
break;
case GP_STROKECONVERT_CURVE:
case GP_STROKECONVERT_POLY: /* convert after */
- gp_stroke_to_bezier(C,
- gpl,
- gps,
- cu,
- subrect_ptr,
- &nu,
- minmax_weights,
- rad_fac,
- stitch,
- add_start_point,
- add_end_point,
- gtd);
+ gpencil_stroke_to_bezier(C,
+ gpl,
+ gps,
+ cu,
+ subrect_ptr,
+ &nu,
+ minmax_weights,
+ rad_fac,
+ stitch,
+ add_start_point,
+ add_end_point,
+ gtd);
break;
default:
BLI_assert(!"invalid mode");
@@ -1372,16 +1376,16 @@ static void gp_layer_to_curve(bContext *C,
/* If link_strokes, be sure first and last points have a zero weight/size! */
if (link_strokes) {
- gp_stroke_finalize_curve_endpoints(cu);
+ gpencil_stroke_finalize_curve_endpoints(cu);
}
/* Update curve's weights, if needed */
if (norm_weights && ((minmax_weights[0] > 0.0f) || (minmax_weights[1] < 1.0f))) {
- gp_stroke_norm_curve_weights(cu, minmax_weights);
+ gpencil_stroke_norm_curve_weights(cu, minmax_weights);
}
/* Create the path animation, if needed */
- gp_stroke_path_animation(C, reports, cu, gtd);
+ gpencil_stroke_path_animation(C, reports, cu, gtd);
if (mode == GP_STROKECONVERT_POLY) {
for (nu = cu->nurb.first; nu; nu = nu->next) {
@@ -1399,7 +1403,7 @@ static void gp_layer_to_curve(bContext *C,
/* Check a GP layer has valid timing data! Else, most timing options are hidden in the operator.
* op may be NULL.
*/
-static bool gp_convert_check_has_valid_timing(bContext *C, bGPDlayer *gpl, wmOperator *op)
+static bool gpencil_convert_check_has_valid_timing(bContext *C, bGPDlayer *gpl, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
@@ -1447,9 +1451,9 @@ static bool gp_convert_check_has_valid_timing(bContext *C, bGPDlayer *gpl, wmOpe
}
/* Check end_frame is always > start frame! */
-static void gp_convert_set_end_frame(struct Main *UNUSED(main),
- struct Scene *UNUSED(scene),
- struct PointerRNA *ptr)
+static void gpencil_convert_set_end_frame(struct Main *UNUSED(main),
+ struct Scene *UNUSED(scene),
+ struct PointerRNA *ptr)
{
int start_frame = RNA_int_get(ptr, "start_frame");
int end_frame = RNA_int_get(ptr, "end_frame");
@@ -1459,7 +1463,7 @@ static void gp_convert_set_end_frame(struct Main *UNUSED(main),
}
}
-static bool gp_convert_poll(bContext *C)
+static bool gpencil_convert_poll(bContext *C)
{
Object *ob = CTX_data_active_object(C);
Scene *scene = CTX_data_scene(C);
@@ -1481,7 +1485,7 @@ static bool gp_convert_poll(bContext *C)
(gpf->strokes.first) && (!GPENCIL_ANY_EDIT_MODE(gpd)));
}
-static int gp_convert_layer_exec(bContext *C, wmOperator *op)
+static int gpencil_convert_layer_exec(bContext *C, wmOperator *op)
{
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "use_timing_data");
Object *ob = CTX_data_active_object(C);
@@ -1502,7 +1506,7 @@ static int gp_convert_layer_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- if (!RNA_property_is_set(op->ptr, prop) && !gp_convert_check_has_valid_timing(C, gpl, op)) {
+ if (!RNA_property_is_set(op->ptr, prop) && !gpencil_convert_check_has_valid_timing(C, gpl, op)) {
BKE_report(op->reports,
RPT_WARNING,
"Current Grease Pencil strokes have no valid timing data, most timing options will "
@@ -1539,7 +1543,8 @@ static int gp_convert_layer_exec(bContext *C, wmOperator *op)
gtd.offset_time = 0.0f;
/* perform conversion */
- gp_layer_to_curve(C, op->reports, gpd, gpl, mode, norm_weights, rad_fac, link_strokes, &gtd);
+ gpencil_layer_to_curve(
+ C, op->reports, gpd, gpl, mode, norm_weights, rad_fac, link_strokes, &gtd);
/* free temp memory */
if (gtd.dists) {
@@ -1560,9 +1565,9 @@ static int gp_convert_layer_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static bool gp_convert_poll_property(const bContext *UNUSED(C),
- wmOperator *op,
- const PropertyRNA *prop)
+static bool gpencil_convert_poll_property(const bContext *UNUSED(C),
+ wmOperator *op,
+ const PropertyRNA *prop)
{
PointerRNA *ptr = op->ptr;
const char *prop_id = RNA_property_identifier(prop);
@@ -1641,9 +1646,9 @@ void GPENCIL_OT_convert(wmOperatorType *ot)
/* callbacks */
ot->invoke = WM_menu_invoke;
- ot->exec = gp_convert_layer_exec;
- ot->poll = gp_convert_poll;
- ot->poll_property = gp_convert_poll_property;
+ ot->exec = gpencil_convert_layer_exec;
+ ot->poll = gpencil_convert_poll;
+ ot->poll_property = gpencil_convert_poll_property;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -1725,7 +1730,7 @@ void GPENCIL_OT_convert(wmOperatorType *ot)
"The end frame of the path control curve (if Realtime is not set)",
1,
100000);
- RNA_def_property_update_runtime(prop, gp_convert_set_end_frame);
+ RNA_def_property_update_runtime(prop, gpencil_convert_set_end_frame);
RNA_def_float(ot->srna,
"gap_duration",
@@ -1771,7 +1776,10 @@ static bool image_to_gpencil_poll(bContext *C)
{
SpaceLink *sl = CTX_wm_space_data(C);
if ((sl != NULL) && (sl->spacetype == SPACE_IMAGE)) {
- return true;
+ SpaceImage *sima = CTX_wm_space_image(C);
+ Image *image = sima->image;
+ ImageUser iuser = sima->iuser;
+ return BKE_image_has_ibuf(image, &iuser);
}
return false;
@@ -1811,7 +1819,7 @@ static int image_to_gpencil_exec(bContext *C, wmOperator *op)
if (done) {
/* Delete any selected point. */
LISTBASE_FOREACH_MUTABLE (bGPDstroke *, gps, &gpf->strokes) {
- gp_stroke_delete_tagged_points(gpf, gps, gps->next, GP_SPOINT_SELECT, false, 0);
+ gpencil_stroke_delete_tagged_points(gpf, gps, gps->next, GP_SPOINT_SELECT, false, 0);
}
BKE_reportf(op->reports, RPT_INFO, "Object created");
diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c
index 8c80334bf8a..44b866d81d7 100644
--- a/source/blender/editors/gpencil/gpencil_data.c
+++ b/source/blender/editors/gpencil/gpencil_data.c
@@ -90,7 +90,7 @@
/* Datablock Operators */
/* ******************* Add New Data ************************ */
-static bool gp_data_add_poll(bContext *C)
+static bool gpencil_data_add_poll(bContext *C)
{
/* the base line we have is that we have somewhere to add Grease Pencil data */
@@ -98,7 +98,7 @@ static bool gp_data_add_poll(bContext *C)
}
/* add new datablock - wrapper around API */
-static int gp_data_add_exec(bContext *C, wmOperator *op)
+static int gpencil_data_add_exec(bContext *C, wmOperator *op)
{
PointerRNA gpd_owner = {NULL};
bGPdata **gpd_ptr = ED_annotation_data_get_pointers(C, &gpd_owner);
@@ -145,14 +145,14 @@ void GPENCIL_OT_annotation_add(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* callbacks */
- ot->exec = gp_data_add_exec;
- ot->poll = gp_data_add_poll;
+ ot->exec = gpencil_data_add_exec;
+ ot->poll = gpencil_data_add_poll;
}
/* ******************* Unlink Data ************************ */
/* poll callback for adding data/layers - special */
-static bool gp_data_unlink_poll(bContext *C)
+static bool gpencil_data_unlink_poll(bContext *C)
{
bGPdata **gpd_ptr = ED_annotation_data_get_pointers(C, NULL);
@@ -168,7 +168,7 @@ static bool gp_data_unlink_poll(bContext *C)
}
/* unlink datablock - wrapper around API */
-static int gp_data_unlink_exec(bContext *C, wmOperator *op)
+static int gpencil_data_unlink_exec(bContext *C, wmOperator *op)
{
bGPdata **gpd_ptr = ED_annotation_data_get_pointers(C, NULL);
@@ -199,8 +199,8 @@ void GPENCIL_OT_data_unlink(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* callbacks */
- ot->exec = gp_data_unlink_exec;
- ot->poll = gp_data_unlink_poll;
+ ot->exec = gpencil_data_unlink_exec;
+ ot->poll = gpencil_data_unlink_poll;
}
/* ************************************************ */
@@ -209,7 +209,7 @@ void GPENCIL_OT_data_unlink(wmOperatorType *ot)
/* ******************* Add New Layer ************************ */
/* add new layer - wrapper around API */
-static int gp_layer_add_exec(bContext *C, wmOperator *op)
+static int gpencil_layer_add_exec(bContext *C, wmOperator *op)
{
const bool is_annotation = STREQ(op->idname, "GPENCIL_OT_layer_annotation_add");
@@ -268,11 +268,11 @@ void GPENCIL_OT_layer_add(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* callbacks */
- ot->exec = gp_layer_add_exec;
- ot->poll = gp_add_poll;
+ ot->exec = gpencil_layer_add_exec;
+ ot->poll = gpencil_add_poll;
}
-static bool gp_add_annotation_poll(bContext *C)
+static bool gpencil_add_annotation_poll(bContext *C)
{
return ED_annotation_data_get_pointers(C, NULL) != NULL;
}
@@ -287,12 +287,12 @@ void GPENCIL_OT_layer_annotation_add(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* callbacks */
- ot->exec = gp_layer_add_exec;
- ot->poll = gp_add_annotation_poll;
+ ot->exec = gpencil_layer_add_exec;
+ ot->poll = gpencil_add_annotation_poll;
}
/* ******************* Remove Active Layer ************************* */
-static int gp_layer_remove_exec(bContext *C, wmOperator *op)
+static int gpencil_layer_remove_exec(bContext *C, wmOperator *op)
{
const bool is_annotation = STREQ(op->idname, "GPENCIL_OT_layer_annotation_remove");
@@ -345,11 +345,11 @@ void GPENCIL_OT_layer_remove(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* callbacks */
- ot->exec = gp_layer_remove_exec;
- ot->poll = gp_active_layer_poll;
+ ot->exec = gpencil_layer_remove_exec;
+ ot->poll = gpencil_active_layer_poll;
}
-static bool gp_active_layer_annotation_poll(bContext *C)
+static bool gpencil_active_layer_annotation_poll(bContext *C)
{
bGPdata *gpd = ED_annotation_data_get_active(C);
bGPDlayer *gpl = BKE_gpencil_layer_active_get(gpd);
@@ -367,8 +367,8 @@ void GPENCIL_OT_layer_annotation_remove(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* callbacks */
- ot->exec = gp_layer_remove_exec;
- ot->poll = gp_active_layer_annotation_poll;
+ ot->exec = gpencil_layer_remove_exec;
+ ot->poll = gpencil_active_layer_annotation_poll;
}
/* ******************* Move Layer Up/Down ************************** */
@@ -377,7 +377,7 @@ enum {
GP_LAYER_MOVE_DOWN = 1,
};
-static int gp_layer_move_exec(bContext *C, wmOperator *op)
+static int gpencil_layer_move_exec(bContext *C, wmOperator *op)
{
const bool is_annotation = STREQ(op->idname, "GPENCIL_OT_layer_annotation_move");
@@ -418,8 +418,8 @@ void GPENCIL_OT_layer_move(wmOperatorType *ot)
ot->description = "Move the active Grease Pencil layer up/down in the list";
/* api callbacks */
- ot->exec = gp_layer_move_exec;
- ot->poll = gp_active_layer_poll;
+ ot->exec = gpencil_layer_move_exec;
+ ot->poll = gpencil_active_layer_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -441,8 +441,8 @@ void GPENCIL_OT_layer_annotation_move(wmOperatorType *ot)
ot->description = "Move the active Annotation layer up/down in the list";
/* api callbacks */
- ot->exec = gp_layer_move_exec;
- ot->poll = gp_active_layer_annotation_poll;
+ ot->exec = gpencil_layer_move_exec;
+ ot->poll = gpencil_active_layer_annotation_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -451,7 +451,7 @@ void GPENCIL_OT_layer_annotation_move(wmOperatorType *ot)
}
/* ********************* Duplicate Layer ************************** */
-static int gp_layer_copy_exec(bContext *C, wmOperator *UNUSED(op))
+static int gpencil_layer_copy_exec(bContext *C, wmOperator *UNUSED(op))
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
bGPDlayer *gpl = BKE_gpencil_layer_active_get(gpd);
@@ -491,8 +491,8 @@ void GPENCIL_OT_layer_duplicate(wmOperatorType *ot)
ot->description = "Make a copy of the active Grease Pencil layer";
/* callbacks */
- ot->exec = gp_layer_copy_exec;
- ot->poll = gp_active_layer_poll;
+ ot->exec = gpencil_layer_copy_exec;
+ ot->poll = gpencil_active_layer_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -504,7 +504,7 @@ enum {
GP_LAYER_COPY_OBJECT_ACT_FRAME = 1,
};
-static bool gp_layer_duplicate_object_poll(bContext *C)
+static bool gpencil_layer_duplicate_object_poll(bContext *C)
{
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *ob = CTX_data_active_object(C);
@@ -529,7 +529,7 @@ static bool gp_layer_duplicate_object_poll(bContext *C)
return false;
}
-static int gp_layer_duplicate_object_exec(bContext *C, wmOperator *op)
+static int gpencil_layer_duplicate_object_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
@@ -622,8 +622,8 @@ void GPENCIL_OT_layer_duplicate_object(wmOperatorType *ot)
ot->description = "Make a copy of the active Grease Pencil layer to new object";
/* callbacks */
- ot->exec = gp_layer_duplicate_object_exec;
- ot->poll = gp_layer_duplicate_object_poll;
+ ot->exec = gpencil_layer_duplicate_object_exec;
+ ot->poll = gpencil_layer_duplicate_object_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -641,7 +641,7 @@ enum {
GP_FRAME_DUP_ALL = 1,
};
-static int gp_frame_duplicate_exec(bContext *C, wmOperator *op)
+static int gpencil_frame_duplicate_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
bGPDlayer *gpl_active = BKE_gpencil_layer_active_get(gpd);
@@ -685,8 +685,8 @@ void GPENCIL_OT_frame_duplicate(wmOperatorType *ot)
ot->description = "Make a copy of the active Grease Pencil Frame";
/* callbacks */
- ot->exec = gp_frame_duplicate_exec;
- ot->poll = gp_active_layer_poll;
+ ot->exec = gpencil_frame_duplicate_exec;
+ ot->poll = gpencil_active_layer_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -700,7 +700,7 @@ enum {
GP_FRAME_CLEAN_FILL_ALL = 1,
};
-static int gp_frame_clean_fill_exec(bContext *C, wmOperator *op)
+static int gpencil_frame_clean_fill_exec(bContext *C, wmOperator *op)
{
bool changed = false;
bGPdata *gpd = ED_gpencil_data_get_active(C);
@@ -770,8 +770,8 @@ void GPENCIL_OT_frame_clean_fill(wmOperatorType *ot)
ot->description = "Remove 'no fill' boundary strokes";
/* callbacks */
- ot->exec = gp_frame_clean_fill_exec;
- ot->poll = gp_active_layer_poll;
+ ot->exec = gpencil_frame_clean_fill_exec;
+ ot->poll = gpencil_active_layer_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -780,7 +780,7 @@ void GPENCIL_OT_frame_clean_fill(wmOperatorType *ot)
}
/* ********************* Clean Loose Boundaries on Frame ************************** */
-static int gp_frame_clean_loose_exec(bContext *C, wmOperator *op)
+static int gpencil_frame_clean_loose_exec(bContext *C, wmOperator *op)
{
bool changed = false;
bGPdata *gpd = ED_gpencil_data_get_active(C);
@@ -846,8 +846,8 @@ void GPENCIL_OT_frame_clean_loose(wmOperatorType *ot)
ot->description = "Remove loose points";
/* callbacks */
- ot->exec = gp_frame_clean_loose_exec;
- ot->poll = gp_active_layer_poll;
+ ot->exec = gpencil_frame_clean_loose_exec;
+ ot->poll = gpencil_active_layer_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -865,7 +865,7 @@ void GPENCIL_OT_frame_clean_loose(wmOperatorType *ot)
/* *********************** Hide Layers ******************************** */
-static int gp_hide_exec(bContext *C, wmOperator *op)
+static int gpencil_hide_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
bGPDlayer *layer = BKE_gpencil_layer_active_get(gpd);
@@ -908,8 +908,8 @@ void GPENCIL_OT_hide(wmOperatorType *ot)
ot->description = "Hide selected/unselected Grease Pencil layers";
/* callbacks */
- ot->exec = gp_hide_exec;
- ot->poll = gp_active_layer_poll; /* NOTE: we need an active layer to play with */
+ ot->exec = gpencil_hide_exec;
+ ot->poll = gpencil_active_layer_poll; /* NOTE: we need an active layer to play with */
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -922,12 +922,12 @@ void GPENCIL_OT_hide(wmOperatorType *ot)
/* ********************** Show All Layers ***************************** */
/* poll callback for showing layers */
-static bool gp_reveal_poll(bContext *C)
+static bool gpencil_reveal_poll(bContext *C)
{
return ED_gpencil_data_get_active(C) != NULL;
}
-static void gp_reveal_select_frame(bContext *C, bGPDframe *frame, bool select)
+static void gpencil_reveal_select_frame(bContext *C, bGPDframe *frame, bool select)
{
bGPDstroke *gps;
for (gps = frame->strokes.first; gps; gps = gps->next) {
@@ -948,7 +948,7 @@ static void gp_reveal_select_frame(bContext *C, bGPDframe *frame, bool select)
}
}
-static int gp_reveal_exec(bContext *C, wmOperator *op)
+static int gpencil_reveal_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
const bool select = RNA_boolean_get(op->ptr, "select");
@@ -967,14 +967,14 @@ static int gp_reveal_exec(bContext *C, wmOperator *op)
if (select) {
/* select all strokes on active frame only (same as select all operator) */
if (gpl->actframe) {
- gp_reveal_select_frame(C, gpl->actframe, true);
+ gpencil_reveal_select_frame(C, gpl->actframe, true);
}
}
else {
/* deselect strokes on all frames (same as deselect all operator) */
bGPDframe *gpf;
for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
- gp_reveal_select_frame(C, gpf, false);
+ gpencil_reveal_select_frame(C, gpf, false);
}
}
}
@@ -996,8 +996,8 @@ void GPENCIL_OT_reveal(wmOperatorType *ot)
ot->description = "Show all Grease Pencil layers";
/* callbacks */
- ot->exec = gp_reveal_exec;
- ot->poll = gp_reveal_poll;
+ ot->exec = gpencil_reveal_exec;
+ ot->poll = gpencil_reveal_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -1008,7 +1008,7 @@ void GPENCIL_OT_reveal(wmOperatorType *ot)
/* ***************** Lock/Unlock All Layers ************************ */
-static int gp_lock_all_exec(bContext *C, wmOperator *UNUSED(op))
+static int gpencil_lock_all_exec(bContext *C, wmOperator *UNUSED(op))
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
@@ -1038,8 +1038,8 @@ void GPENCIL_OT_lock_all(wmOperatorType *ot)
"Lock all Grease Pencil layers to prevent them from being accidentally modified";
/* callbacks */
- ot->exec = gp_lock_all_exec;
- ot->poll = gp_reveal_poll;
+ ot->exec = gpencil_lock_all_exec;
+ ot->poll = gpencil_reveal_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -1047,7 +1047,7 @@ void GPENCIL_OT_lock_all(wmOperatorType *ot)
/* -------------------------- */
-static int gp_unlock_all_exec(bContext *C, wmOperator *UNUSED(op))
+static int gpencil_unlock_all_exec(bContext *C, wmOperator *UNUSED(op))
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
@@ -1076,8 +1076,8 @@ void GPENCIL_OT_unlock_all(wmOperatorType *ot)
ot->description = "Unlock all Grease Pencil layers so that they can be edited";
/* callbacks */
- ot->exec = gp_unlock_all_exec;
- ot->poll = gp_reveal_poll;
+ ot->exec = gpencil_unlock_all_exec;
+ ot->poll = gpencil_reveal_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -1085,7 +1085,7 @@ void GPENCIL_OT_unlock_all(wmOperatorType *ot)
/* ********************** Isolate Layer **************************** */
-static int gp_isolate_layer_exec(bContext *C, wmOperator *op)
+static int gpencil_isolate_layer_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
bGPDlayer *layer = BKE_gpencil_layer_active_get(gpd);
@@ -1153,8 +1153,8 @@ void GPENCIL_OT_layer_isolate(wmOperatorType *ot)
"Toggle whether the active layer is the only one that can be edited and/or visible";
/* callbacks */
- ot->exec = gp_isolate_layer_exec;
- ot->poll = gp_active_layer_poll;
+ ot->exec = gpencil_isolate_layer_exec;
+ ot->poll = gpencil_active_layer_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -1169,7 +1169,7 @@ void GPENCIL_OT_layer_isolate(wmOperatorType *ot)
/* ********************** Merge Layer with the next layer **************************** */
-static int gp_merge_layer_exec(bContext *C, wmOperator *op)
+static int gpencil_merge_layer_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
bGPDlayer *gpl_next = BKE_gpencil_layer_active_get(gpd);
@@ -1242,8 +1242,8 @@ void GPENCIL_OT_layer_merge(wmOperatorType *ot)
ot->description = "Merge the current layer with the layer below";
/* callbacks */
- ot->exec = gp_merge_layer_exec;
- ot->poll = gp_active_layer_poll;
+ ot->exec = gpencil_merge_layer_exec;
+ ot->poll = gpencil_active_layer_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -1251,7 +1251,7 @@ void GPENCIL_OT_layer_merge(wmOperatorType *ot)
/* ********************** Change Layer ***************************** */
-static int gp_layer_change_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(evt))
+static int gpencil_layer_change_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(evt))
{
uiPopupMenu *pup;
uiLayout *layout;
@@ -1265,7 +1265,7 @@ static int gp_layer_change_invoke(bContext *C, wmOperator *op, const wmEvent *UN
return OPERATOR_INTERFACE;
}
-static int gp_layer_change_exec(bContext *C, wmOperator *op)
+static int gpencil_layer_change_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = CTX_data_gpencil_data(C);
bGPDlayer *gpl = NULL;
@@ -1306,9 +1306,9 @@ void GPENCIL_OT_layer_change(wmOperatorType *ot)
ot->description = "Change active Grease Pencil layer";
/* callbacks */
- ot->invoke = gp_layer_change_invoke;
- ot->exec = gp_layer_change_exec;
- ot->poll = gp_active_layer_poll;
+ ot->invoke = gpencil_layer_change_invoke;
+ ot->exec = gpencil_layer_change_exec;
+ ot->poll = gpencil_active_layer_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -1318,7 +1318,7 @@ void GPENCIL_OT_layer_change(wmOperatorType *ot)
RNA_def_enum_funcs(ot->prop, ED_gpencil_layers_with_new_enum_itemf);
}
-static int gp_layer_active_exec(bContext *C, wmOperator *op)
+static int gpencil_layer_active_exec(bContext *C, wmOperator *op)
{
Object *ob = CTX_data_active_object(C);
bGPdata *gpd = (bGPdata *)ob->data;
@@ -1352,8 +1352,8 @@ void GPENCIL_OT_layer_active(wmOperatorType *ot)
ot->description = "Active Grease Pencil layer";
/* callbacks */
- ot->exec = gp_layer_active_exec;
- ot->poll = gp_active_layer_poll;
+ ot->exec = gpencil_layer_active_exec;
+ ot->poll = gpencil_active_layer_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -1373,7 +1373,7 @@ enum {
GP_STROKE_MOVE_BOTTOM = 3,
};
-static int gp_stroke_arrange_exec(bContext *C, wmOperator *op)
+static int gpencil_stroke_arrange_exec(bContext *C, wmOperator *op)
{
Object *ob = CTX_data_active_object(C);
bGPdata *gpd = ED_gpencil_data_get_active(C);
@@ -1503,8 +1503,8 @@ void GPENCIL_OT_stroke_arrange(wmOperatorType *ot)
ot->description = "Arrange selected strokes up/down in the drawing order of the active layer";
/* callbacks */
- ot->exec = gp_stroke_arrange_exec;
- ot->poll = gp_active_layer_poll;
+ ot->exec = gpencil_stroke_arrange_exec;
+ ot->poll = gpencil_active_layer_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -1515,7 +1515,7 @@ void GPENCIL_OT_stroke_arrange(wmOperatorType *ot)
/* ******************* Move Stroke to new color ************************** */
-static int gp_stroke_change_color_exec(bContext *C, wmOperator *op)
+static int gpencil_stroke_change_color_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Material *ma = NULL;
@@ -1599,8 +1599,8 @@ void GPENCIL_OT_stroke_change_color(wmOperatorType *ot)
ot->description = "Move selected strokes to active material";
/* callbacks */
- ot->exec = gp_stroke_change_color_exec;
- ot->poll = gp_active_layer_poll;
+ ot->exec = gpencil_stroke_change_color_exec;
+ ot->poll = gpencil_active_layer_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -1610,7 +1610,7 @@ void GPENCIL_OT_stroke_change_color(wmOperatorType *ot)
/* ******************* Lock color of non selected Strokes colors ************************** */
-static int gp_material_lock_unsused_exec(bContext *C, wmOperator *UNUSED(op))
+static int gpencil_material_lock_unsused_exec(bContext *C, wmOperator *UNUSED(op))
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
@@ -1674,8 +1674,8 @@ void GPENCIL_OT_material_lock_unused(wmOperatorType *ot)
ot->description = "Lock any material not used in any selected stroke";
/* api callbacks */
- ot->exec = gp_material_lock_unsused_exec;
- ot->poll = gp_active_layer_poll;
+ ot->exec = gpencil_material_lock_unsused_exec;
+ ot->poll = gpencil_active_layer_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -1685,7 +1685,7 @@ void GPENCIL_OT_material_lock_unused(wmOperatorType *ot)
/* Drawing Brushes Operators */
/* ******************* Brush resets ************************** */
-static int gp_brush_reset_exec(bContext *C, wmOperator *UNUSED(op))
+static int gpencil_brush_reset_exec(bContext *C, wmOperator *UNUSED(op))
{
Main *bmain = CTX_data_main(C);
ToolSettings *ts = CTX_data_tool_settings(C);
@@ -1743,16 +1743,16 @@ void GPENCIL_OT_brush_reset(wmOperatorType *ot)
ot->description = "Reset Brush to default parameters";
/* api callbacks */
- ot->exec = gp_brush_reset_exec;
+ ot->exec = gpencil_brush_reset_exec;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-static Brush *gp_brush_get_first_by_mode(Main *bmain,
- Paint *UNUSED(paint),
- const enum eContextObjectMode mode,
- char tool)
+static Brush *gpencil_brush_get_first_by_mode(Main *bmain,
+ Paint *UNUSED(paint),
+ const enum eContextObjectMode mode,
+ char tool)
{
Brush *brush_next = NULL;
for (Brush *brush = bmain->brushes.first; brush; brush = brush_next) {
@@ -1782,9 +1782,9 @@ static Brush *gp_brush_get_first_by_mode(Main *bmain,
return NULL;
}
-static void gp_brush_delete_mode_brushes(Main *bmain,
- Paint *paint,
- const enum eContextObjectMode mode)
+static void gpencil_brush_delete_mode_brushes(Main *bmain,
+ Paint *paint,
+ const enum eContextObjectMode mode)
{
Brush *brush_active = paint->brush;
Brush *brush_next = NULL;
@@ -1847,7 +1847,7 @@ static void gp_brush_delete_mode_brushes(Main *bmain,
}
}
-static int gp_brush_reset_all_exec(bContext *C, wmOperator *UNUSED(op))
+static int gpencil_brush_reset_all_exec(bContext *C, wmOperator *UNUSED(op))
{
Main *bmain = CTX_data_main(C);
ToolSettings *ts = CTX_data_tool_settings(C);
@@ -1903,7 +1903,7 @@ static int gp_brush_reset_all_exec(bContext *C, wmOperator *UNUSED(op))
}
}
- gp_brush_delete_mode_brushes(bmain, paint, mode);
+ gpencil_brush_delete_mode_brushes(bmain, paint, mode);
switch (mode) {
case CTX_MODE_PAINT_GPENCIL: {
@@ -1930,7 +1930,7 @@ static int gp_brush_reset_all_exec(bContext *C, wmOperator *UNUSED(op))
BKE_paint_toolslots_brush_validate(bmain, paint);
/* Set Again the first brush of the mode. */
- Brush *deft_brush = gp_brush_get_first_by_mode(bmain, paint, mode, tool);
+ Brush *deft_brush = gpencil_brush_get_first_by_mode(bmain, paint, mode, tool);
if (deft_brush) {
BKE_paint_brush_set(paint, deft_brush);
}
@@ -1950,7 +1950,7 @@ void GPENCIL_OT_brush_reset_all(wmOperatorType *ot)
ot->description = "Delete all mode brushes and recreate a default set";
/* api callbacks */
- ot->exec = gp_brush_reset_all_exec;
+ ot->exec = gpencil_brush_reset_all_exec;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -2496,7 +2496,7 @@ typedef struct tJoinGPencil_AdtFixData {
* Callback to pass to #BKE_fcurves_main_cb()
* for RNA Paths attached to each F-Curve used in the #AnimData.
*/
-static void joined_gpencil_fix_animdata_cb(ID *id, FCurve *fcu, void *user_data)
+static void gpencil_joined_fix_animdata_cb(ID *id, FCurve *fcu, void *user_data)
{
tJoinGPencil_AdtFixData *afd = (tJoinGPencil_AdtFixData *)user_data;
ID *src_id = &afd->src_gpd->id;
@@ -2534,8 +2534,8 @@ static void joined_gpencil_fix_animdata_cb(ID *id, FCurve *fcu, void *user_data)
if (dtar->id == src_id) {
dtar->id = dst_id;
- /* Also check on the subtarget...
- * We duplicate the logic from drivers_path_rename_fix() here, with our own
+ /* Also check on the sub-target.
+ * We duplicate the logic from #drivers_path_rename_fix() here, with our own
* little twists so that we know that it isn't going to clobber the wrong data
*/
if (dtar->rna_path && strstr(dtar->rna_path, "layers[")) {
@@ -2721,7 +2721,7 @@ int ED_gpencil_join_objects_exec(bContext *C, wmOperator *op)
}
/* Fix all the animation data */
- BKE_fcurves_main_cb(bmain, joined_gpencil_fix_animdata_cb, &afd);
+ BKE_fcurves_main_cb(bmain, gpencil_joined_fix_animdata_cb, &afd);
BLI_ghash_free(afd.names_map, MEM_freeN, NULL);
/* Only copy over animdata now, after all the remapping has been done,
@@ -2856,7 +2856,7 @@ void GPENCIL_OT_lock_layer(wmOperatorType *ot)
/* api callbacks */
ot->exec = gpencil_lock_layer_exec;
- ot->poll = gp_active_layer_poll;
+ ot->poll = gpencil_active_layer_poll;
}
/* ********************** Isolate gpencil_ color **************************** */
@@ -3415,7 +3415,7 @@ bool ED_gpencil_add_lattice_modifier(const bContext *C,
}
/* Masking operators */
-static int gp_layer_mask_add_exec(bContext *C, wmOperator *op)
+static int gpencil_layer_mask_add_exec(bContext *C, wmOperator *op)
{
Object *ob = CTX_data_active_object(C);
if ((ob == NULL) || (ob->type != OB_GPENCIL)) {
@@ -3476,14 +3476,14 @@ void GPENCIL_OT_layer_mask_add(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* callbacks */
- ot->exec = gp_layer_mask_add_exec;
- ot->poll = gp_add_poll;
+ ot->exec = gpencil_layer_mask_add_exec;
+ ot->poll = gpencil_add_poll;
/* properties */
RNA_def_string(ot->srna, "name", NULL, 128, "Layer", "Name of the layer");
}
-static int gp_layer_mask_remove_exec(bContext *C, wmOperator *UNUSED(op))
+static int gpencil_layer_mask_remove_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = CTX_data_active_object(C);
if ((ob == NULL) || (ob->type != OB_GPENCIL)) {
@@ -3525,6 +3525,6 @@ void GPENCIL_OT_layer_mask_remove(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* callbacks */
- ot->exec = gp_layer_mask_remove_exec;
- ot->poll = gp_active_layer_poll;
+ ot->exec = gpencil_layer_mask_remove_exec;
+ ot->poll = gpencil_active_layer_poll;
}
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index 76776b5c23c..78e2812fdef 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -95,7 +95,7 @@
* \{ */
/* poll callback for all stroke editing operators */
-static bool gp_stroke_edit_poll(bContext *C)
+static bool gpencil_stroke_edit_poll(bContext *C)
{
/* edit only supported with grease pencil objects */
Object *ob = CTX_data_active_object(C);
@@ -108,7 +108,7 @@ static bool gp_stroke_edit_poll(bContext *C)
}
/* poll callback to verify edit mode in 3D view only */
-static bool gp_strokes_edit3d_poll(bContext *C)
+static bool gpencil_strokes_edit3d_poll(bContext *C)
{
/* edit only supported with grease pencil objects */
Object *ob = CTX_data_active_object(C);
@@ -120,7 +120,7 @@ static bool gp_strokes_edit3d_poll(bContext *C)
* - 1) Editable GP data
* - 2) 3D View only
*/
- return (gp_stroke_edit_poll(C) && ED_operator_view3d_active(C));
+ return (gpencil_stroke_edit_poll(C) && ED_operator_view3d_active(C));
}
static bool gpencil_editmode_toggle_poll(bContext *C)
@@ -789,7 +789,7 @@ void GPENCIL_OT_selection_opacity_toggle(wmOperatorType *ot)
/* callbacks */
ot->exec = gpencil_hideselect_toggle_exec;
- ot->poll = gp_stroke_edit_poll;
+ ot->poll = gpencil_stroke_edit_poll;
/* flags */
ot->flag = OPTYPE_UNDO | OPTYPE_REGISTER;
@@ -802,9 +802,9 @@ void GPENCIL_OT_selection_opacity_toggle(wmOperatorType *ot)
* \{ */
/* Make copies of selected point segments in a selected stroke */
-static void gp_duplicate_points(const bGPDstroke *gps,
- ListBase *new_strokes,
- const char *layername)
+static void gpencil_duplicate_points(const bGPDstroke *gps,
+ ListBase *new_strokes,
+ const char *layername)
{
bGPDspoint *pt;
int i;
@@ -880,7 +880,7 @@ static void gp_duplicate_points(const bGPDstroke *gps,
}
}
-static int gp_duplicate_exec(bContext *C, wmOperator *op)
+static int gpencil_duplicate_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
@@ -933,7 +933,7 @@ static int gp_duplicate_exec(bContext *C, wmOperator *op)
}
else {
/* delegate to a helper, as there's too much to fit in here (for copying subsets)... */
- gp_duplicate_points(gps, &new_strokes, gpl->info);
+ gpencil_duplicate_points(gps, &new_strokes, gpl->info);
}
/* deselect original stroke, or else the originals get moved too
@@ -969,8 +969,8 @@ void GPENCIL_OT_duplicate(wmOperatorType *ot)
ot->description = "Duplicate the selected Grease Pencil strokes";
/* callbacks */
- ot->exec = gp_duplicate_exec;
- ot->poll = gp_stroke_edit_poll;
+ ot->exec = gpencil_duplicate_exec;
+ ot->poll = gpencil_stroke_edit_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -983,12 +983,12 @@ void GPENCIL_OT_duplicate(wmOperatorType *ot)
* \{ */
/* helper to copy a point to temp area */
-static void copy_move_point(bGPDstroke *gps,
- bGPDspoint *temp_points,
- MDeformVert *temp_dverts,
- int from_idx,
- int to_idx,
- const bool copy)
+static void gpencil_copy_move_point(bGPDstroke *gps,
+ bGPDspoint *temp_points,
+ MDeformVert *temp_dverts,
+ int from_idx,
+ int to_idx,
+ const bool copy)
{
bGPDspoint *pt = &temp_points[from_idx];
bGPDspoint *pt_final = &gps->points[to_idx];
@@ -1053,7 +1053,7 @@ static void gpencil_add_move_points(bGPDframe *gpf, bGPDstroke *gps)
BLI_insertlinkafter(&gpf->strokes, gps, gps_new);
/* copy selected point data to new stroke */
- copy_move_point(gps_new, gps->points, gps->dvert, i, 0, true);
+ gpencil_copy_move_point(gps_new, gps->points, gps->dvert, i, 0, true);
/* Calc geometry data. */
BKE_gpencil_stroke_geometry_update(gps);
@@ -1098,13 +1098,13 @@ static void gpencil_add_move_points(bGPDframe *gpf, bGPDstroke *gps)
/* move points to new position */
for (int i = 0; i < oldtotpoints; i++) {
- copy_move_point(gps, temp_points, temp_dverts, i, i2, false);
+ gpencil_copy_move_point(gps, temp_points, temp_dverts, i, i2, false);
i2++;
}
/* If first point, add new point at the beginning. */
if (do_first) {
- copy_move_point(gps, temp_points, temp_dverts, 0, 0, true);
+ gpencil_copy_move_point(gps, temp_points, temp_dverts, 0, 0, true);
/* deselect old */
pt = &gps->points[1];
pt->flag &= ~GP_SPOINT_SELECT;
@@ -1115,7 +1115,8 @@ static void gpencil_add_move_points(bGPDframe *gpf, bGPDstroke *gps)
/* if last point, add new point at the end */
if (do_last) {
- copy_move_point(gps, temp_points, temp_dverts, oldtotpoints - 1, gps->totpoints - 1, true);
+ gpencil_copy_move_point(
+ gps, temp_points, temp_dverts, oldtotpoints - 1, gps->totpoints - 1, true);
/* deselect old */
pt = &gps->points[gps->totpoints - 2];
@@ -1138,7 +1139,7 @@ static void gpencil_add_move_points(bGPDframe *gpf, bGPDstroke *gps)
}
}
-static int gp_extrude_exec(bContext *C, wmOperator *op)
+static int gpencil_extrude_exec(bContext *C, wmOperator *op)
{
Object *obact = CTX_data_active_object(C);
bGPdata *gpd = (bGPdata *)obact->data;
@@ -1194,8 +1195,8 @@ void GPENCIL_OT_extrude(wmOperatorType *ot)
ot->description = "Extrude the selected Grease Pencil points";
/* callbacks */
- ot->exec = gp_extrude_exec;
- ot->poll = gp_stroke_edit_poll;
+ ot->exec = gpencil_extrude_exec;
+ ot->poll = gpencil_stroke_edit_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -1216,16 +1217,16 @@ void GPENCIL_OT_extrude(wmOperatorType *ot)
/* list of bGPDstroke instances */
/* NOTE: is exposed within the editors/gpencil module so that other tools can use it too */
-ListBase gp_strokes_copypastebuf = {NULL, NULL};
+ListBase gpencil_strokes_copypastebuf = {NULL, NULL};
/* Hash for hanging on to all the colors used by strokes in the buffer
*
* This is needed to prevent dangling and unsafe pointers when pasting across data-blocks,
* or after a color used by a stroke in the buffer gets deleted (via user action or undo).
*/
-static GHash *gp_strokes_copypastebuf_colors = NULL;
+static GHash *gpencil_strokes_copypastebuf_colors = NULL;
-static GHash *gp_strokes_copypastebuf_colors_material_to_name_create(Main *bmain)
+static GHash *gpencil_strokes_copypastebuf_colors_material_to_name_create(Main *bmain)
{
GHash *ma_to_name = BLI_ghash_ptr_new(__func__);
@@ -1237,12 +1238,12 @@ static GHash *gp_strokes_copypastebuf_colors_material_to_name_create(Main *bmain
return ma_to_name;
}
-static void gp_strokes_copypastebuf_colors_material_to_name_free(GHash *ma_to_name)
+static void gpencil_strokes_copypastebuf_colors_material_to_name_free(GHash *ma_to_name)
{
BLI_ghash_free(ma_to_name, NULL, MEM_freeN);
}
-static GHash *gp_strokes_copypastebuf_colors_name_to_material_create(Main *bmain)
+static GHash *gpencil_strokes_copypastebuf_colors_name_to_material_create(Main *bmain)
{
GHash *name_to_ma = BLI_ghash_str_new(__func__);
@@ -1254,7 +1255,7 @@ static GHash *gp_strokes_copypastebuf_colors_name_to_material_create(Main *bmain
return name_to_ma;
}
-static void gp_strokes_copypastebuf_colors_name_to_material_free(GHash *name_to_ma)
+static void gpencil_strokes_copypastebuf_colors_name_to_material_free(GHash *name_to_ma)
{
BLI_ghash_free(name_to_ma, MEM_freeN, NULL);
}
@@ -1267,13 +1268,13 @@ void ED_gpencil_strokes_copybuf_free(void)
/* Free the colors buffer
* NOTE: This is done before the strokes so that the ptrs are still safe
*/
- if (gp_strokes_copypastebuf_colors) {
- BLI_ghash_free(gp_strokes_copypastebuf_colors, NULL, MEM_freeN);
- gp_strokes_copypastebuf_colors = NULL;
+ if (gpencil_strokes_copypastebuf_colors) {
+ BLI_ghash_free(gpencil_strokes_copypastebuf_colors, NULL, MEM_freeN);
+ gpencil_strokes_copypastebuf_colors = NULL;
}
/* Free the stroke buffer */
- for (gps = gp_strokes_copypastebuf.first; gps; gps = gpsn) {
+ for (gps = gpencil_strokes_copypastebuf.first; gps; gps = gpsn) {
gpsn = gps->next;
if (gps->points) {
@@ -1286,17 +1287,17 @@ void ED_gpencil_strokes_copybuf_free(void)
MEM_SAFE_FREE(gps->triangles);
- BLI_freelinkN(&gp_strokes_copypastebuf, gps);
+ BLI_freelinkN(&gpencil_strokes_copypastebuf, gps);
}
- gp_strokes_copypastebuf.first = gp_strokes_copypastebuf.last = NULL;
+ gpencil_strokes_copypastebuf.first = gpencil_strokes_copypastebuf.last = NULL;
}
/**
* Ensure that destination datablock has all the colors the pasted strokes need.
* Helper function for copy-pasting strokes
*/
-GHash *gp_copybuf_validate_colormap(bContext *C)
+GHash *gpencil_copybuf_validate_colormap(bContext *C)
{
Main *bmain = CTX_data_main(C);
Object *ob = CTX_data_active_object(C);
@@ -1304,9 +1305,9 @@ GHash *gp_copybuf_validate_colormap(bContext *C)
GHashIterator gh_iter;
/* For each color, check if exist and add if not */
- GHash *name_to_ma = gp_strokes_copypastebuf_colors_name_to_material_create(bmain);
+ GHash *name_to_ma = gpencil_strokes_copypastebuf_colors_name_to_material_create(bmain);
- GHASH_ITER (gh_iter, gp_strokes_copypastebuf_colors) {
+ GHASH_ITER (gh_iter, gpencil_strokes_copypastebuf_colors) {
int *key = BLI_ghashIterator_getKey(&gh_iter);
char *ma_name = BLI_ghashIterator_getValue(&gh_iter);
Material *ma = BLI_ghash_lookup(name_to_ma, ma_name);
@@ -1319,7 +1320,7 @@ GHash *gp_copybuf_validate_colormap(bContext *C)
}
}
- gp_strokes_copypastebuf_colors_name_to_material_free(name_to_ma);
+ gpencil_strokes_copypastebuf_colors_name_to_material_free(name_to_ma);
return new_colors;
}
@@ -1330,7 +1331,7 @@ GHash *gp_copybuf_validate_colormap(bContext *C)
/** \name Copy Selected Strokes Operator
* \{ */
-static int gp_strokes_copy_exec(bContext *C, wmOperator *op)
+static int gpencil_strokes_copy_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Object *ob = CTX_data_active_object(C);
@@ -1389,11 +1390,11 @@ static int gp_strokes_copy_exec(bContext *C, wmOperator *op)
/* add to temp buffer */
gpsd->next = gpsd->prev = NULL;
- BLI_addtail(&gp_strokes_copypastebuf, gpsd);
+ BLI_addtail(&gpencil_strokes_copypastebuf, gpsd);
}
else {
/* delegate to a helper, as there's too much to fit in here (for copying subsets)... */
- gp_duplicate_points(gps, &gp_strokes_copypastebuf, gpl->info);
+ gpencil_duplicate_points(gps, &gpencil_strokes_copypastebuf, gpl->info);
}
}
}
@@ -1401,10 +1402,10 @@ static int gp_strokes_copy_exec(bContext *C, wmOperator *op)
CTX_DATA_END;
/* Build up hash of material colors used in these strokes */
- if (gp_strokes_copypastebuf.first) {
- gp_strokes_copypastebuf_colors = BLI_ghash_int_new("GPencil CopyBuf Colors");
- GHash *ma_to_name = gp_strokes_copypastebuf_colors_material_to_name_create(bmain);
- LISTBASE_FOREACH (bGPDstroke *, gps, &gp_strokes_copypastebuf) {
+ if (gpencil_strokes_copypastebuf.first) {
+ gpencil_strokes_copypastebuf_colors = BLI_ghash_int_new("GPencil CopyBuf Colors");
+ GHash *ma_to_name = gpencil_strokes_copypastebuf_colors_material_to_name_create(bmain);
+ LISTBASE_FOREACH (bGPDstroke *, gps, &gpencil_strokes_copypastebuf) {
if (ED_gpencil_stroke_can_use(C, gps)) {
Material *ma = BKE_object_material_get(ob, gps->mat_nr + 1);
/* Avoid default material. */
@@ -1414,13 +1415,13 @@ static int gp_strokes_copy_exec(bContext *C, wmOperator *op)
char **ma_name_val;
if (!BLI_ghash_ensure_p(
- gp_strokes_copypastebuf_colors, &gps->mat_nr, (void ***)&ma_name_val)) {
+ gpencil_strokes_copypastebuf_colors, &gps->mat_nr, (void ***)&ma_name_val)) {
char *ma_name = BLI_ghash_lookup(ma_to_name, ma);
*ma_name_val = MEM_dupallocN(ma_name);
}
}
}
- gp_strokes_copypastebuf_colors_material_to_name_free(ma_to_name);
+ gpencil_strokes_copypastebuf_colors_material_to_name_free(ma_to_name);
}
/* updates (to ensure operator buttons are refreshed, when used via hotkeys) */
@@ -1438,8 +1439,8 @@ void GPENCIL_OT_copy(wmOperatorType *ot)
ot->description = "Copy selected Grease Pencil points and strokes";
/* callbacks */
- ot->exec = gp_strokes_copy_exec;
- ot->poll = gp_stroke_edit_poll;
+ ot->exec = gpencil_strokes_copy_exec;
+ ot->poll = gpencil_stroke_edit_poll;
/* flags */
// ot->flag = OPTYPE_REGISTER;
@@ -1451,7 +1452,7 @@ void GPENCIL_OT_copy(wmOperatorType *ot)
/** \name Paste Selected Strokes Operator
* \{ */
-static bool gp_strokes_paste_poll(bContext *C)
+static bool gpencil_strokes_paste_poll(bContext *C)
{
ScrArea *area = CTX_wm_area(C);
if (!((area != NULL) && (area->spacetype == SPACE_VIEW3D))) {
@@ -1464,7 +1465,7 @@ static bool gp_strokes_paste_poll(bContext *C)
* 2) Copy buffer must at least have something (though it may be the wrong sort...).
*/
return (ED_gpencil_data_get_active(C) != NULL) &&
- (!BLI_listbase_is_empty(&gp_strokes_copypastebuf));
+ (!BLI_listbase_is_empty(&gpencil_strokes_copypastebuf));
}
typedef enum eGP_PasteMode {
@@ -1472,7 +1473,7 @@ typedef enum eGP_PasteMode {
GP_COPY_TO_ACTIVE = 1,
} eGP_PasteMode;
-static int gp_strokes_paste_exec(bContext *C, wmOperator *op)
+static int gpencil_strokes_paste_exec(bContext *C, wmOperator *op)
{
Object *ob = CTX_data_active_object(C);
bGPdata *gpd = (bGPdata *)ob->data;
@@ -1489,7 +1490,7 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "Operator not supported in multiframe edition");
return OPERATOR_CANCELLED;
}
- else if (BLI_listbase_is_empty(&gp_strokes_copypastebuf)) {
+ else if (BLI_listbase_is_empty(&gpencil_strokes_copypastebuf)) {
BKE_report(op->reports,
RPT_ERROR,
"No strokes to paste, select and copy some points before trying again");
@@ -1509,7 +1510,7 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op)
bGPDstroke *gps;
bool ok = false;
- for (gps = gp_strokes_copypastebuf.first; gps; gps = gps->next) {
+ for (gps = gpencil_strokes_copypastebuf.first; gps; gps = gps->next) {
if (ED_gpencil_stroke_can_use(C, gps)) {
ok = true;
break;
@@ -1535,10 +1536,11 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op)
CTX_DATA_END;
/* Ensure that all the necessary colors exist */
- new_colors = gp_copybuf_validate_colormap(C);
+ new_colors = gpencil_copybuf_validate_colormap(C);
/* Copy over the strokes from the buffer (and adjust the colors) */
- bGPDstroke *gps_init = (!on_back) ? gp_strokes_copypastebuf.first : gp_strokes_copypastebuf.last;
+ bGPDstroke *gps_init = (!on_back) ? gpencil_strokes_copypastebuf.first :
+ gpencil_strokes_copypastebuf.last;
for (bGPDstroke *gps = gps_init; gps; gps = (!on_back) ? gps->next : gps->prev) {
if (ED_gpencil_stroke_can_use(C, gps)) {
/* Need to verify if layer exists */
@@ -1606,8 +1608,8 @@ void GPENCIL_OT_paste(wmOperatorType *ot)
ot->description = "Paste previously copied strokes to active layer or to original layer";
/* callbacks */
- ot->exec = gp_strokes_paste_exec;
- ot->poll = gp_strokes_paste_poll;
+ ot->exec = gpencil_strokes_paste_exec;
+ ot->poll = gpencil_strokes_paste_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -1626,7 +1628,7 @@ void GPENCIL_OT_paste(wmOperatorType *ot)
/** \name Move To Layer Operator
* \{ */
-static int gp_move_to_layer_exec(bContext *C, wmOperator *op)
+static int gpencil_move_to_layer_exec(bContext *C, wmOperator *op)
{
Object *ob = CTX_data_active_object(C);
bGPdata *gpd = (bGPdata *)ob->data;
@@ -1732,8 +1734,8 @@ void GPENCIL_OT_move_to_layer(wmOperatorType *ot)
"Move selected strokes to another layer"; // XXX: allow moving individual points too?
/* callbacks */
- ot->exec = gp_move_to_layer_exec;
- ot->poll = gp_stroke_edit_poll; // XXX?
+ ot->exec = gpencil_move_to_layer_exec;
+ ot->poll = gpencil_stroke_edit_poll; // XXX?
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -1750,7 +1752,7 @@ void GPENCIL_OT_move_to_layer(wmOperatorType *ot)
/** \name Add Blank Frame Operator
* \{ */
-static int gp_blank_frame_add_exec(bContext *C, wmOperator *op)
+static int gpencil_blank_frame_add_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
Scene *scene = CTX_data_scene(C);
@@ -1808,8 +1810,8 @@ void GPENCIL_OT_blank_frame_add(wmOperatorType *ot)
"(all subsequently existing frames, if any, are shifted right by one frame)";
/* callbacks */
- ot->exec = gp_blank_frame_add_exec;
- ot->poll = gp_add_poll;
+ ot->exec = gpencil_blank_frame_add_exec;
+ ot->poll = gpencil_add_poll;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -1828,7 +1830,7 @@ void GPENCIL_OT_blank_frame_add(wmOperatorType *ot)
/** \name Delete Active Frame Operator
* \{ */
-static bool gp_actframe_delete_poll(bContext *C)
+static bool gpencil_actframe_delete_poll(bContext *C)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
bGPDlayer *gpl = BKE_gpencil_layer_active_get(gpd);
@@ -1837,7 +1839,7 @@ static bool gp_actframe_delete_poll(bContext *C)
return (gpl && gpl->actframe);
}
-static bool gp_annotation_actframe_delete_poll(bContext *C)
+static bool annotation_actframe_delete_poll(bContext *C)
{
bGPdata *gpd = ED_annotation_data_get_active(C);
bGPDlayer *gpl = BKE_gpencil_layer_active_get(gpd);
@@ -1847,7 +1849,7 @@ static bool gp_annotation_actframe_delete_poll(bContext *C)
}
/* delete active frame - wrapper around API calls */
-static int gp_actframe_delete_exec(bContext *C, wmOperator *op)
+static int gpencil_actframe_delete_exec(bContext *C, wmOperator *op)
{
const bool is_annotation = STREQ(op->idname, "GPENCIL_OT_annotation_active_frame_delete");
@@ -1890,8 +1892,8 @@ void GPENCIL_OT_active_frame_delete(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* callbacks */
- ot->exec = gp_actframe_delete_exec;
- ot->poll = gp_actframe_delete_poll;
+ ot->exec = gpencil_actframe_delete_exec;
+ ot->poll = gpencil_actframe_delete_poll;
}
void GPENCIL_OT_annotation_active_frame_delete(wmOperatorType *ot)
@@ -1904,8 +1906,8 @@ void GPENCIL_OT_annotation_active_frame_delete(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* callbacks */
- ot->exec = gp_actframe_delete_exec;
- ot->poll = gp_annotation_actframe_delete_poll;
+ ot->exec = gpencil_actframe_delete_exec;
+ ot->poll = annotation_actframe_delete_poll;
}
/** \} */
@@ -1914,7 +1916,7 @@ void GPENCIL_OT_annotation_active_frame_delete(wmOperatorType *ot)
/** \name Delete All Active Frames
* \{ */
-static bool gp_actframe_delete_all_poll(bContext *C)
+static bool gpencil_actframe_delete_all_poll(bContext *C)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
@@ -1924,7 +1926,7 @@ static bool gp_actframe_delete_all_poll(bContext *C)
return (gpd && gpd->layers.first);
}
-static int gp_actframe_delete_all_exec(bContext *C, wmOperator *op)
+static int gpencil_actframe_delete_all_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
Scene *scene = CTX_data_scene(C);
@@ -1969,8 +1971,8 @@ void GPENCIL_OT_active_frames_delete_all(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* callbacks */
- ot->exec = gp_actframe_delete_all_exec;
- ot->poll = gp_actframe_delete_all_poll;
+ ot->exec = gpencil_actframe_delete_all_exec;
+ ot->poll = gpencil_actframe_delete_all_poll;
}
/** \} */
@@ -1998,7 +2000,7 @@ typedef enum eGP_DissolveMode {
} eGP_DissolveMode;
/* Delete selected strokes */
-static int gp_delete_selected_strokes(bContext *C)
+static int gpencil_delete_selected_strokes(bContext *C)
{
bool changed = false;
bGPdata *gpd = ED_gpencil_data_get_active(C);
@@ -2056,7 +2058,7 @@ static int gp_delete_selected_strokes(bContext *C)
/* ----------------------------------- */
/* Delete selected points but keep the stroke */
-static int gp_dissolve_selected_points(bContext *C, eGP_DissolveMode mode)
+static int gpencil_dissolve_selected_points(bContext *C, eGP_DissolveMode mode)
{
Object *ob = CTX_data_active_object(C);
bGPdata *gpd = (bGPdata *)ob->data;
@@ -2282,7 +2284,9 @@ typedef struct tGPDeleteIsland {
int end_idx;
} tGPDeleteIsland;
-static void gp_stroke_join_islands(bGPDframe *gpf, bGPDstroke *gps_first, bGPDstroke *gps_last)
+static void gpencil_stroke_join_islands(bGPDframe *gpf,
+ bGPDstroke *gps_first,
+ bGPDstroke *gps_last)
{
bGPDspoint *pt = NULL;
bGPDspoint *pt_final = NULL;
@@ -2382,12 +2386,12 @@ static void gp_stroke_join_islands(bGPDframe *gpf, bGPDstroke *gps_first, bGPDst
* 2) Each island gets converted to a new stroke
* If the number of points is <= limit, the stroke is deleted
*/
-void gp_stroke_delete_tagged_points(bGPDframe *gpf,
- bGPDstroke *gps,
- bGPDstroke *next_stroke,
- int tag_flags,
- bool select,
- int limit)
+void gpencil_stroke_delete_tagged_points(bGPDframe *gpf,
+ bGPDstroke *gps,
+ bGPDstroke *next_stroke,
+ int tag_flags,
+ bool select,
+ int limit)
{
tGPDeleteIsland *islands = MEM_callocN(sizeof(tGPDeleteIsland) * (gps->totpoints + 1) / 2,
"gp_point_islands");
@@ -2517,7 +2521,7 @@ void gp_stroke_delete_tagged_points(bGPDframe *gpf,
}
/* if cyclic, need to join last stroke with first stroke */
if ((is_cyclic) && (gps_first != NULL) && (gps_first != new_stroke)) {
- gp_stroke_join_islands(gpf, gps_first, new_stroke);
+ gpencil_stroke_join_islands(gpf, gps_first, new_stroke);
}
}
@@ -2530,7 +2534,7 @@ void gp_stroke_delete_tagged_points(bGPDframe *gpf,
}
/* Split selected strokes into segments, splitting on selected points */
-static int gp_delete_selected_points(bContext *C)
+static int gpencil_delete_selected_points(bContext *C)
{
Object *ob = CTX_data_active_object(C);
bGPdata *gpd = ED_gpencil_data_get_active(C);
@@ -2564,7 +2568,7 @@ static int gp_delete_selected_points(bContext *C)
gps->flag &= ~GP_STROKE_SELECT;
/* delete unwanted points by splitting stroke into several smaller ones */
- gp_stroke_delete_tagged_points(gpf, gps, gps->next, GP_SPOINT_SELECT, false, 0);
+ gpencil_stroke_delete_tagged_points(gpf, gps, gps->next, GP_SPOINT_SELECT, false, 0);
changed = true;
}
@@ -2585,9 +2589,9 @@ static int gp_delete_selected_points(bContext *C)
}
/* simple wrapper to external call */
-int gp_delete_selected_point_wrap(bContext *C)
+int gpencil_delete_selected_point_wrap(bContext *C)
{
- return gp_delete_selected_points(C);
+ return gpencil_delete_selected_points(C);
}
/** \} */
@@ -2596,22 +2600,22 @@ int gp_delete_selected_point_wrap(bContext *C)
/** \name Delete Operator
* \{ */
-static int gp_delete_exec(bContext *C, wmOperator *op)
+static int gpencil_delete_exec(bContext *C, wmOperator *op)
{
eGP_DeleteMode mode = RNA_enum_get(op->ptr, "type");
int result = OPERATOR_CANCELLED;
switch (mode) {
case GP_DELETEOP_STROKES: /* selected strokes */
- result = gp_delete_selected_strokes(C);
+ result = gpencil_delete_selected_strokes(C);
break;
case GP_DELETEOP_POINTS: /* selected points (breaks the stroke into segments) */
- result = gp_delete_selected_points(C);
+ result = gpencil_delete_selected_points(C);
break;
case GP_DELETEOP_FRAME: /* active frame */
- result = gp_actframe_delete_exec(C, op);
+ result = gpencil_actframe_delete_exec(C, op);
break;
}
@@ -2638,8 +2642,8 @@ void GPENCIL_OT_delete(wmOperatorType *ot)
/* callbacks */
ot->invoke = WM_menu_invoke;
- ot->exec = gp_delete_exec;
- ot->poll = gp_stroke_edit_poll;
+ ot->exec = gpencil_delete_exec;
+ ot->poll = gpencil_stroke_edit_poll;
/* flags */
ot->flag = OPTYPE_UNDO | OPTYPE_REGISTER;
@@ -2659,11 +2663,11 @@ void GPENCIL_OT_delete(wmOperatorType *ot)
/** \name Dissolve Operator
* \{ */
-static int gp_dissolve_exec(bContext *C, wmOperator *op)
+static int gpencil_dissolve_exec(bContext *C, wmOperator *op)
{
eGP_DissolveMode mode = RNA_enum_get(op->ptr, "type");
- return gp_dissolve_selected_points(C, mode);
+ return gpencil_dissolve_selected_points(C, mode);
}
void GPENCIL_OT_dissolve(wmOperatorType *ot)
@@ -2686,8 +2690,8 @@ void GPENCIL_OT_dissolve(wmOperatorType *ot)
/* callbacks */
ot->invoke = WM_menu_invoke;
- ot->exec = gp_dissolve_exec;
- ot->poll = gp_stroke_edit_poll;
+ ot->exec = gpencil_dissolve_exec;
+ ot->poll = gpencil_stroke_edit_poll;
/* flags */
ot->flag = OPTYPE_UNDO | OPTYPE_REGISTER;
@@ -2711,7 +2715,7 @@ void GPENCIL_OT_dissolve(wmOperatorType *ot)
/* NOTE: For now, we only allow these in the 3D view, as other editors do not
* define a cursor or gridstep which can be used
*/
-static bool gp_snap_poll(bContext *C)
+static bool gpencil_snap_poll(bContext *C)
{
ScrArea *area = CTX_wm_area(C);
Object *ob = CTX_data_active_object(C);
@@ -2720,7 +2724,7 @@ static bool gp_snap_poll(bContext *C)
((area != NULL) && (area->spacetype == SPACE_VIEW3D));
}
-static int gp_snap_to_grid(bContext *C, wmOperator *UNUSED(op))
+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);
@@ -2766,7 +2770,7 @@ static int gp_snap_to_grid(bContext *C, wmOperator *UNUSED(op))
/* return data */
copy_v3_v3(&pt->x, fpt);
- gp_apply_parent_point(depsgraph, obact, gpl, pt);
+ gpencil_apply_parent_point(depsgraph, obact, gpl, pt);
}
}
}
@@ -2787,8 +2791,8 @@ void GPENCIL_OT_snap_to_grid(wmOperatorType *ot)
ot->description = "Snap selected points to the nearest grid points";
/* callbacks */
- ot->exec = gp_snap_to_grid;
- ot->poll = gp_snap_poll;
+ ot->exec = gpencil_snap_to_grid;
+ ot->poll = gpencil_snap_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -2800,7 +2804,7 @@ void GPENCIL_OT_snap_to_grid(wmOperatorType *ot)
/** \name Snapping Selection to Cursor Operator
* \{ */
-static int gp_snap_to_cursor(bContext *C, wmOperator *op)
+static int gpencil_snap_to_cursor(bContext *C, wmOperator *op)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
@@ -2854,7 +2858,7 @@ static int gp_snap_to_cursor(bContext *C, wmOperator *op)
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
if (pt->flag & GP_SPOINT_SELECT) {
copy_v3_v3(&pt->x, cursor_global);
- gp_apply_parent_point(depsgraph, obact, gpl, pt);
+ gpencil_apply_parent_point(depsgraph, obact, gpl, pt);
}
}
}
@@ -2876,8 +2880,8 @@ void GPENCIL_OT_snap_to_cursor(wmOperatorType *ot)
ot->description = "Snap selected points/strokes to the cursor";
/* callbacks */
- ot->exec = gp_snap_to_cursor;
- ot->poll = gp_snap_poll;
+ ot->exec = gpencil_snap_to_cursor;
+ ot->poll = gpencil_snap_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -2896,7 +2900,7 @@ void GPENCIL_OT_snap_to_cursor(wmOperatorType *ot)
/** \name Snapping Cursor to Selection Operator
* \{ */
-static int gp_snap_cursor_to_sel(bContext *C, wmOperator *UNUSED(op))
+static int gpencil_snap_cursor_to_sel(bContext *C, wmOperator *UNUSED(op))
{
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
Object *obact = CTX_data_active_object(C);
@@ -2956,13 +2960,16 @@ static int gp_snap_cursor_to_sel(bContext *C, wmOperator *UNUSED(op))
}
}
- if (scene->toolsettings->transform_pivot_point == V3D_AROUND_CENTER_MEDIAN && count) {
- mul_v3_fl(centroid, 1.0f / (float)count);
- copy_v3_v3(cursor, centroid);
- }
- else {
+ if (scene->toolsettings->transform_pivot_point == V3D_AROUND_CENTER_BOUNDS) {
mid_v3_v3v3(cursor, min, max);
}
+ else { /* #V3D_AROUND_CENTER_MEDIAN. */
+ zero_v3(cursor);
+ if (count) {
+ mul_v3_fl(centroid, 1.0f / (float)count);
+ copy_v3_v3(cursor, centroid);
+ }
+ }
DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
@@ -2978,8 +2985,8 @@ void GPENCIL_OT_snap_cursor_to_selected(wmOperatorType *ot)
ot->description = "Snap cursor to center of selected points";
/* callbacks */
- ot->exec = gp_snap_cursor_to_sel;
- ot->poll = gp_snap_poll;
+ ot->exec = gpencil_snap_cursor_to_sel;
+ ot->poll = gpencil_snap_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -2991,7 +2998,7 @@ void GPENCIL_OT_snap_cursor_to_selected(wmOperatorType *ot)
/** \name Apply Layer Thickness Change to Strokes Operator
* \{ */
-static int gp_stroke_apply_thickness_exec(bContext *C, wmOperator *UNUSED(op))
+static int gpencil_stroke_apply_thickness_exec(bContext *C, wmOperator *UNUSED(op))
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
bGPDlayer *gpl = BKE_gpencil_layer_active_get(gpd);
@@ -3032,8 +3039,8 @@ void GPENCIL_OT_stroke_apply_thickness(wmOperatorType *ot)
ot->description = "Apply the thickness change of the layer to its strokes";
/* api callbacks */
- ot->exec = gp_stroke_apply_thickness_exec;
- ot->poll = gp_active_layer_poll;
+ ot->exec = gpencil_stroke_apply_thickness_exec;
+ ot->poll = gpencil_active_layer_poll;
}
/** \} */
@@ -3048,7 +3055,7 @@ enum {
GP_STROKE_CYCLIC_TOGGLE = 3,
};
-static int gp_stroke_cyclical_set_exec(bContext *C, wmOperator *op)
+static int gpencil_stroke_cyclical_set_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
Object *ob = CTX_data_active_object(C);
@@ -3147,8 +3154,8 @@ void GPENCIL_OT_stroke_cyclical_set(wmOperatorType *ot)
ot->description = "Close or open the selected stroke adding an edge from last to first point";
/* api callbacks */
- ot->exec = gp_stroke_cyclical_set_exec;
- ot->poll = gp_active_layer_poll;
+ ot->exec = gpencil_stroke_cyclical_set_exec;
+ ot->poll = gpencil_active_layer_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -3173,7 +3180,7 @@ enum {
GP_STROKE_CAPS_TOGGLE_DEFAULT = 3,
};
-static int gp_stroke_caps_set_exec(bContext *C, wmOperator *op)
+static int gpencil_stroke_caps_set_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
Object *ob = CTX_data_active_object(C);
@@ -3250,8 +3257,8 @@ void GPENCIL_OT_stroke_caps_set(wmOperatorType *ot)
ot->description = "Change Stroke caps mode (rounded or flat)";
/* api callbacks */
- ot->exec = gp_stroke_caps_set_exec;
- ot->poll = gp_active_layer_poll;
+ ot->exec = gpencil_stroke_caps_set_exec;
+ ot->poll = gpencil_active_layer_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -3422,7 +3429,7 @@ static void gpencil_stroke_join_strokes(bGPDstroke *gps_a,
}
}
-static int gp_stroke_join_exec(bContext *C, wmOperator *op)
+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);
@@ -3549,8 +3556,8 @@ void GPENCIL_OT_stroke_join(wmOperatorType *ot)
ot->description = "Join selected strokes (optionally as new stroke)";
/* api callbacks */
- ot->exec = gp_stroke_join_exec;
- ot->poll = gp_active_layer_poll;
+ ot->exec = gpencil_stroke_join_exec;
+ ot->poll = gpencil_active_layer_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -3570,7 +3577,7 @@ void GPENCIL_OT_stroke_join(wmOperatorType *ot)
/** \name Stroke Flip Operator
* \{ */
-static int gp_stroke_flip_exec(bContext *C, wmOperator *UNUSED(op))
+static int gpencil_stroke_flip_exec(bContext *C, wmOperator *UNUSED(op))
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
Object *ob = CTX_data_active_object(C);
@@ -3620,8 +3627,8 @@ void GPENCIL_OT_stroke_flip(wmOperatorType *ot)
ot->description = "Change direction of the points of the selected strokes";
/* api callbacks */
- ot->exec = gp_stroke_flip_exec;
- ot->poll = gp_active_layer_poll;
+ ot->exec = gpencil_stroke_flip_exec;
+ ot->poll = gpencil_active_layer_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -3633,7 +3640,7 @@ void GPENCIL_OT_stroke_flip(wmOperatorType *ot)
/** \name Stroke Re-project Operator
* \{ */
-static int gp_strokes_reproject_exec(bContext *C, wmOperator *op)
+static int gpencil_strokes_reproject_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
Scene *scene = CTX_data_scene(C);
@@ -3647,7 +3654,7 @@ static int gp_strokes_reproject_exec(bContext *C, wmOperator *op)
/* Init space conversion stuff. */
GP_SpaceConversion gsc = {NULL};
SnapObjectContext *sctx = NULL;
- gp_point_conversion_init(C, &gsc);
+ gpencil_point_conversion_init(C, &gsc);
/* Init snap context for geometry projection. */
sctx = ED_transform_snap_object_context_create_view3d(scene, 0, region, CTX_wm_view3d(C));
@@ -3718,8 +3725,8 @@ void GPENCIL_OT_reproject(wmOperatorType *ot)
/* callbacks */
ot->invoke = WM_menu_invoke;
- ot->exec = gp_strokes_reproject_exec;
- ot->poll = gp_strokes_edit3d_poll;
+ ot->exec = gpencil_strokes_reproject_exec;
+ ot->poll = gpencil_strokes_edit3d_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -3736,7 +3743,7 @@ void GPENCIL_OT_reproject(wmOperatorType *ot)
"Keep original strokes and create a copy before reprojecting instead of reproject them");
}
-static int gp_recalc_geometry_exec(bContext *C, wmOperator *UNUSED(op))
+static int gpencil_recalc_geometry_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = CTX_data_active_object(C);
if ((ob == NULL) || (ob->type != OB_GPENCIL)) {
@@ -3765,8 +3772,8 @@ void GPENCIL_OT_recalc_geometry(wmOperatorType *ot)
ot->description = "Update all internal geometry data";
/* callbacks */
- ot->exec = gp_recalc_geometry_exec;
- ot->poll = gp_active_layer_poll;
+ ot->exec = gpencil_recalc_geometry_exec;
+ ot->poll = gpencil_active_layer_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -3779,7 +3786,7 @@ void GPENCIL_OT_recalc_geometry(wmOperatorType *ot)
* \{ */
/* helper to smooth */
-static void gp_smooth_stroke(bContext *C, wmOperator *op)
+static void gpencil_smooth_stroke(bContext *C, wmOperator *op)
{
const int repeat = RNA_int_get(op->ptr, "repeat");
float factor = RNA_float_get(op->ptr, "factor");
@@ -3826,7 +3833,7 @@ static void gp_smooth_stroke(bContext *C, wmOperator *op)
}
/* helper: Count how many points need to be inserted */
-static int gp_count_subdivision_cuts(bGPDstroke *gps)
+static int gpencil_count_subdivision_cuts(bGPDstroke *gps)
{
bGPDspoint *pt;
int i;
@@ -3844,7 +3851,7 @@ static int gp_count_subdivision_cuts(bGPDstroke *gps)
return totnewpoints;
}
-static int gp_stroke_subdivide_exec(bContext *C, wmOperator *op)
+static int gpencil_stroke_subdivide_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
bGPDspoint *temp_points;
@@ -3863,7 +3870,7 @@ static int gp_stroke_subdivide_exec(bContext *C, wmOperator *op)
if (gps->flag & GP_STROKE_SELECT) {
/* loop as many times as cuts */
for (int s = 0; s < cuts; s++) {
- totnewpoints = gp_count_subdivision_cuts(gps);
+ totnewpoints = gpencil_count_subdivision_cuts(gps);
if (totnewpoints == 0) {
continue;
}
@@ -3963,7 +3970,7 @@ static int gp_stroke_subdivide_exec(bContext *C, wmOperator *op)
GP_EDITABLE_STROKES_END(gpstroke_iter);
/* smooth stroke */
- gp_smooth_stroke(C, op);
+ gpencil_smooth_stroke(C, op);
/* notifiers */
DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
@@ -3984,8 +3991,8 @@ void GPENCIL_OT_stroke_subdivide(wmOperatorType *ot)
"them";
/* api callbacks */
- ot->exec = gp_stroke_subdivide_exec;
- ot->poll = gp_active_layer_poll;
+ ot->exec = gpencil_stroke_subdivide_exec;
+ ot->poll = gpencil_active_layer_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -4011,7 +4018,7 @@ void GPENCIL_OT_stroke_subdivide(wmOperatorType *ot)
}
/* ** simplify stroke *** */
-static int gp_stroke_simplify_exec(bContext *C, wmOperator *op)
+static int gpencil_stroke_simplify_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
float factor = RNA_float_get(op->ptr, "factor");
@@ -4047,8 +4054,8 @@ void GPENCIL_OT_stroke_simplify(wmOperatorType *ot)
ot->description = "Simplify selected stroked reducing number of points";
/* api callbacks */
- ot->exec = gp_stroke_simplify_exec;
- ot->poll = gp_active_layer_poll;
+ ot->exec = gpencil_stroke_simplify_exec;
+ ot->poll = gpencil_active_layer_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -4060,7 +4067,7 @@ void GPENCIL_OT_stroke_simplify(wmOperatorType *ot)
}
/* ** simplify stroke using fixed algorithm *** */
-static int gp_stroke_simplify_fixed_exec(bContext *C, wmOperator *op)
+static int gpencil_stroke_simplify_fixed_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
int steps = RNA_int_get(op->ptr, "step");
@@ -4097,8 +4104,8 @@ void GPENCIL_OT_stroke_simplify_fixed(wmOperatorType *ot)
ot->description = "Simplify selected stroked reducing number of points using fixed algorithm";
/* api callbacks */
- ot->exec = gp_stroke_simplify_fixed_exec;
- ot->poll = gp_active_layer_poll;
+ ot->exec = gpencil_stroke_simplify_fixed_exec;
+ ot->poll = gpencil_active_layer_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -4111,7 +4118,7 @@ void GPENCIL_OT_stroke_simplify_fixed(wmOperatorType *ot)
}
/* ** Resample stroke *** */
-static int gp_stroke_sample_exec(bContext *C, wmOperator *op)
+static int gpencil_stroke_sample_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
const float length = RNA_float_get(op->ptr, "length");
@@ -4146,8 +4153,8 @@ void GPENCIL_OT_stroke_sample(wmOperatorType *ot)
ot->description = "Sample stroke points to predefined segment length";
/* api callbacks */
- ot->exec = gp_stroke_sample_exec;
- ot->poll = gp_active_layer_poll;
+ ot->exec = gpencil_stroke_sample_exec;
+ ot->poll = gpencil_active_layer_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -4164,7 +4171,7 @@ void GPENCIL_OT_stroke_sample(wmOperatorType *ot)
/** \name Stroke Trim Operator
* \{ */
-static int gp_stroke_trim_exec(bContext *C, wmOperator *UNUSED(op))
+static int gpencil_stroke_trim_exec(bContext *C, wmOperator *UNUSED(op))
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
@@ -4221,8 +4228,8 @@ void GPENCIL_OT_stroke_trim(wmOperatorType *ot)
ot->description = "Trim selected stroke to first loop or intersection";
/* api callbacks */
- ot->exec = gp_stroke_trim_exec;
- ot->poll = gp_active_layer_poll;
+ ot->exec = gpencil_stroke_trim_exec;
+ ot->poll = gpencil_active_layer_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -4243,7 +4250,7 @@ typedef enum eGP_SeparateModes {
GP_SEPARATE_LAYER,
} eGP_SeparateModes;
-static int gp_stroke_separate_exec(bContext *C, wmOperator *op)
+static int gpencil_stroke_separate_exec(bContext *C, wmOperator *op)
{
Base *base_new;
Main *bmain = CTX_data_main(C);
@@ -4277,7 +4284,7 @@ static int gp_stroke_separate_exec(bContext *C, wmOperator *op)
/* Create a new object. */
/* Take into account user preferences for duplicating actions. */
- short dupflag = (U.dupflag & USER_DUP_ACT);
+ const eDupli_ID_Flags dupflag = (U.dupflag & USER_DUP_ACT);
base_new = ED_object_add_duplicate(bmain, scene, view_layer, base_prev, dupflag);
ob_dst = base_new->object;
@@ -4347,10 +4354,12 @@ static int gp_stroke_separate_exec(bContext *C, wmOperator *op)
}
/* delete selected points from destination stroke */
- gp_stroke_delete_tagged_points(gpf_dst, gps_dst, NULL, GP_SPOINT_SELECT, false, 0);
+ gpencil_stroke_delete_tagged_points(
+ gpf_dst, gps_dst, NULL, GP_SPOINT_SELECT, false, 0);
/* delete selected points from origin stroke */
- gp_stroke_delete_tagged_points(gpf, gps, gps->next, GP_SPOINT_SELECT, false, 0);
+ gpencil_stroke_delete_tagged_points(
+ gpf, gps, gps->next, GP_SPOINT_SELECT, false, 0);
}
/* selected strokes mode */
else if (mode == GP_SEPARATE_STROKE) {
@@ -4441,8 +4450,8 @@ void GPENCIL_OT_stroke_separate(wmOperatorType *ot)
/* callbacks */
ot->invoke = WM_menu_invoke;
- ot->exec = gp_stroke_separate_exec;
- ot->poll = gp_strokes_edit3d_poll;
+ ot->exec = gpencil_stroke_separate_exec;
+ ot->poll = gpencil_strokes_edit3d_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -4457,7 +4466,7 @@ void GPENCIL_OT_stroke_separate(wmOperatorType *ot)
/** \name Stroke Split Operator
* \{ */
-static int gp_stroke_split_exec(bContext *C, wmOperator *UNUSED(op))
+static int gpencil_stroke_split_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = CTX_data_active_object(C);
bGPdata *gpd = ED_gpencil_data_get_active(C);
@@ -4505,10 +4514,10 @@ static int gp_stroke_split_exec(bContext *C, wmOperator *UNUSED(op))
}
/* delete selected points from destination stroke */
- gp_stroke_delete_tagged_points(gpf, gps_dst, NULL, GP_SPOINT_SELECT, true, 0);
+ gpencil_stroke_delete_tagged_points(gpf, gps_dst, NULL, GP_SPOINT_SELECT, true, 0);
/* delete selected points from origin stroke */
- gp_stroke_delete_tagged_points(gpf, gps, gps->next, GP_SPOINT_SELECT, false, 0);
+ gpencil_stroke_delete_tagged_points(gpf, gps, gps->next, GP_SPOINT_SELECT, false, 0);
}
}
/* select again tagged points */
@@ -4546,8 +4555,8 @@ void GPENCIL_OT_stroke_split(wmOperatorType *ot)
ot->description = "Split selected points as new stroke on same frame";
/* callbacks */
- ot->exec = gp_stroke_split_exec;
- ot->poll = gp_strokes_edit3d_poll;
+ ot->exec = gpencil_stroke_split_exec;
+ ot->poll = gpencil_strokes_edit3d_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -4559,7 +4568,7 @@ void GPENCIL_OT_stroke_split(wmOperatorType *ot)
/** \name Stroke Smooth Operator
* \{ */
-static int gp_stroke_smooth_exec(bContext *C, wmOperator *op)
+static int gpencil_stroke_smooth_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
@@ -4568,7 +4577,7 @@ static int gp_stroke_smooth_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- gp_smooth_stroke(C, op);
+ gpencil_smooth_stroke(C, op);
/* notifiers */
DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
@@ -4587,8 +4596,8 @@ void GPENCIL_OT_stroke_smooth(wmOperatorType *ot)
ot->description = "Smooth selected strokes";
/* api callbacks */
- ot->exec = gp_stroke_smooth_exec;
- ot->poll = gp_active_layer_poll;
+ ot->exec = gpencil_stroke_smooth_exec;
+ ot->poll = gpencil_active_layer_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -4631,8 +4640,8 @@ static bool gpencil_test_lasso(bGPDstroke *gps,
const struct GP_SelectLassoUserData *data = user_data;
bGPDspoint pt2;
int x0, y0;
- gp_point_to_parent_space(pt, diff_mat, &pt2);
- gp_point_to_xy(gsc, gps, &pt2, &x0, &y0);
+ gpencil_point_to_parent_space(pt, diff_mat, &pt2);
+ gpencil_point_to_xy(gsc, gps, &pt2, &x0, &y0);
/* test if in lasso */
return ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(&data->rect, x0, y0) &&
BLI_lasso_is_point_inside(data->mcoords, data->mcoords_len, x0, y0, INT_MAX));
@@ -4688,7 +4697,8 @@ static void gpencil_cutter_dissolve(bGPDlayer *hit_layer, bGPDstroke *hit_stroke
pt->flag &= ~GP_SPOINT_TAG;
}
}
- gp_stroke_delete_tagged_points(hit_layer->actframe, hit_stroke, gpsn, GP_SPOINT_TAG, false, 1);
+ gpencil_stroke_delete_tagged_points(
+ hit_layer->actframe, hit_stroke, gpsn, GP_SPOINT_TAG, false, 1);
}
}
@@ -4715,7 +4725,7 @@ static int gpencil_cutter_lasso_select(bContext *C,
}
/* init space conversion stuff */
- gp_point_conversion_init(C, &gsc);
+ gpencil_point_conversion_init(C, &gsc);
/* deselect all strokes first */
CTX_DATA_BEGIN (C, bGPDstroke *, gps, editable_gpencil_strokes) {
@@ -4877,7 +4887,7 @@ bool ED_object_gpencil_exit(struct Main *bmain, Object *ob)
/** \name Merge By Distance Operator
* \{ */
-static bool gp_merge_by_distance_poll(bContext *C)
+static bool gpencil_merge_by_distance_poll(bContext *C)
{
Object *ob = CTX_data_active_object(C);
if ((ob == NULL) || (ob->type != OB_GPENCIL)) {
@@ -4893,7 +4903,7 @@ static bool gp_merge_by_distance_poll(bContext *C)
return ((gpl != NULL) && (ob->mode == OB_MODE_EDIT_GPENCIL));
}
-static int gp_merge_by_distance_exec(bContext *C, wmOperator *op)
+static int gpencil_merge_by_distance_exec(bContext *C, wmOperator *op)
{
Object *ob = CTX_data_active_object(C);
bGPdata *gpd = (bGPdata *)ob->data;
@@ -4930,8 +4940,8 @@ void GPENCIL_OT_stroke_merge_by_distance(wmOperatorType *ot)
ot->description = "Merge points by distance";
/* api callbacks */
- ot->exec = gp_merge_by_distance_exec;
- ot->poll = gp_merge_by_distance_poll;
+ ot->exec = gpencil_merge_by_distance_exec;
+ ot->poll = gpencil_merge_by_distance_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c
index 502097a0678..168693ff517 100644
--- a/source/blender/editors/gpencil/gpencil_fill.c
+++ b/source/blender/editors/gpencil/gpencil_fill.c
@@ -162,13 +162,13 @@ typedef struct tGPDfill {
} tGPDfill;
/* draw a given stroke using same thickness and color for all points */
-static void gp_draw_basic_stroke(tGPDfill *tgpf,
- bGPDstroke *gps,
- const float diff_mat[4][4],
- const bool cyclic,
- const float ink[4],
- const int flag,
- const float thershold)
+static void gpencil_draw_basic_stroke(tGPDfill *tgpf,
+ bGPDstroke *gps,
+ const float diff_mat[4][4],
+ const bool cyclic,
+ const float ink[4],
+ const int flag,
+ const float thershold)
{
bGPDspoint *points = gps->points;
@@ -223,7 +223,7 @@ static void gp_draw_basic_stroke(tGPDfill *tgpf,
}
/* loop all layers */
-static void gp_draw_datablock(tGPDfill *tgpf, const float ink[4])
+static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4])
{
/* duplicated: etempFlags */
enum {
@@ -298,19 +298,19 @@ static void gp_draw_datablock(tGPDfill *tgpf, const float ink[4])
/* normal strokes */
if ((tgpf->fill_draw_mode == GP_FILL_DMODE_STROKE) ||
(tgpf->fill_draw_mode == GP_FILL_DMODE_BOTH)) {
- ED_gp_draw_fill(&tgpw);
+ ED_gpencil_draw_fill(&tgpw);
}
/* 3D Lines with basic shapes and invisible lines */
if ((tgpf->fill_draw_mode == GP_FILL_DMODE_CONTROL) ||
(tgpf->fill_draw_mode == GP_FILL_DMODE_BOTH)) {
- gp_draw_basic_stroke(tgpf,
- gps,
- tgpw.diff_mat,
- gps->flag & GP_STROKE_CYCLIC,
- ink,
- tgpf->flag,
- tgpf->fill_threshold);
+ gpencil_draw_basic_stroke(tgpf,
+ gps,
+ tgpw.diff_mat,
+ gps->flag & GP_STROKE_CYCLIC,
+ ink,
+ tgpf->flag,
+ tgpf->fill_threshold);
}
}
}
@@ -319,7 +319,7 @@ static void gp_draw_datablock(tGPDfill *tgpf, const float ink[4])
}
/* draw strokes in offscreen buffer */
-static bool gp_render_offscreen(tGPDfill *tgpf)
+static bool gpencil_render_offscreen(tGPDfill *tgpf)
{
bool is_ortho = false;
float winmat[4][4];
@@ -410,7 +410,7 @@ static bool gp_render_offscreen(tGPDfill *tgpf)
/* draw strokes */
float ink[4] = {1.0f, 0.0f, 0.0f, 1.0f};
- gp_draw_datablock(tgpf, ink);
+ gpencil_draw_datablock(tgpf, ink);
GPU_matrix_pop_projection();
GPU_matrix_pop();
@@ -472,15 +472,16 @@ static void set_pixel(ImBuf *ibuf, int idx, const float col[4])
}
}
-/* check if the size of the leak is narrow to determine if the stroke is closed
+/**
+ * Check if the size of the leak is narrow to determine if the stroke is closed
* this is used for strokes with small gaps between them to get a full fill
* and do not get a full screen fill.
*
- * \param ibuf: Image pixel data
- * \param maxpixel: Maximum index
- * \param limit: Limit of pixels to analyze
- * \param index: Index of current pixel
- * \param type: 0-Horizontal 1-Vertical
+ * \param ibuf: Image pixel data.
+ * \param maxpixel: Maximum index.
+ * \param limit: Limit of pixels to analyze.
+ * \param index: Index of current pixel.
+ * \param type: 0-Horizontal 1-Vertical.
*/
static bool is_leak_narrow(ImBuf *ibuf, const int maxpixel, int limit, int index, int type)
{
@@ -576,11 +577,12 @@ static bool is_leak_narrow(ImBuf *ibuf, const int maxpixel, int limit, int index
return (bool)(t_a && t_b);
}
-/* Boundary fill inside strokes
+/**
+ * Boundary fill inside strokes
* Fills the space created by a set of strokes using the stroke color as the boundary
* of the shape to fill.
*
- * \param tgpf: Temporary fill data
+ * \param tgpf: Temporary fill data.
*/
static void gpencil_boundaryfill_area(tGPDfill *tgpf)
{
@@ -665,62 +667,6 @@ static void gpencil_boundaryfill_area(tGPDfill *tgpf)
BLI_stack_free(stack);
}
-/* Check if there are some pixel not filled with green. If no points, means nothing to fill. */
-static bool UNUSED_FUNCTION(gpencil_check_borders)(tGPDfill *tgpf)
-{
- ImBuf *ibuf;
- void *lock;
- ibuf = BKE_image_acquire_ibuf(tgpf->ima, NULL, &lock);
- int idx;
- int pixel = 0;
- float color[4];
- bool found = false;
-
- /* horizontal lines */
- for (idx = 0; idx < ibuf->x; idx++) {
- /* bottom line */
- get_pixel(ibuf, idx, color);
- if (color[1] != 1.0f) {
- found = true;
- break;
- }
- /* top line */
- pixel = idx + (ibuf->x * (ibuf->y - 1));
- get_pixel(ibuf, pixel, color);
- if (color[1] != 1.0f) {
- found = true;
- break;
- }
- }
- if (!found) {
- /* vertical lines */
- for (idx = 0; idx < ibuf->y; idx++) {
- /* left line */
- get_pixel(ibuf, ibuf->x * idx, color);
- if (color[1] != 1.0f) {
- found = true;
- break;
- }
- /* right line */
- pixel = ibuf->x * idx + (ibuf->x - 1);
- get_pixel(ibuf, pixel, color);
- if (color[1] != 1.0f) {
- found = true;
- break;
- }
- }
- }
-
- /* release ibuf */
- if (ibuf) {
- BKE_image_release_ibuf(tgpf->ima, ibuf, lock);
- }
-
- tgpf->ima->id.tag |= LIB_TAG_DOIT;
-
- return found;
-}
-
/* Set a border to create image limits. */
static void gpencil_set_borders(tGPDfill *tgpf, const bool transparent)
{
@@ -1137,12 +1083,12 @@ static void gpencil_stroke_from_buffer(tGPDfill *tgpf)
for (int i = 0; i < tgpf->sbuffer_used && point2D; i++, point2D++, pt++) {
/* convert screen-coordinates to 3D coordinates */
- gp_stroke_convertcoords_tpoint(tgpf->scene,
- tgpf->region,
- tgpf->ob,
- point2D,
- tgpf->depth_arr ? tgpf->depth_arr + i : NULL,
- &pt->x);
+ gpencil_stroke_convertcoords_tpoint(tgpf->scene,
+ tgpf->region,
+ tgpf->ob,
+ point2D,
+ tgpf->depth_arr ? tgpf->depth_arr + i : NULL,
+ &pt->x);
pt->pressure = 1.0f;
pt->strength = 1.0f;
@@ -1183,14 +1129,14 @@ static void gpencil_stroke_from_buffer(tGPDfill *tgpf)
((ts->gpencil_v3d_align & GP_PROJECT_DEPTH_VIEW) == 0)) {
float origin[3];
ED_gpencil_drawing_reference_get(tgpf->scene, tgpf->ob, ts->gpencil_v3d_align, origin);
- ED_gp_project_stroke_to_plane(
+ ED_gpencil_project_stroke_to_plane(
tgpf->scene, tgpf->ob, tgpf->rv3d, gps, origin, tgpf->lock_axis - 1);
}
/* if parented change position relative to parent object */
for (int a = 0; a < tgpf->sbuffer_used; a++) {
pt = &gps->points[a];
- gp_apply_parent_point(tgpf->depsgraph, tgpf->ob, tgpf->gpl, pt);
+ gpencil_apply_parent_point(tgpf->depsgraph, tgpf->ob, tgpf->gpl, pt);
}
/* if camera view, reproject flat to view to avoid perspective effect */
@@ -1223,7 +1169,7 @@ static void gpencil_draw_boundary_lines(const bContext *UNUSED(C), tGPDfill *tgp
return;
}
const float ink[4] = {1.0f, 0.0f, 0.0f, 1.0f};
- gp_draw_datablock(tgpf, ink);
+ gpencil_draw_datablock(tgpf, ink);
}
/* Drawing callback for modal operator in 3d mode */
@@ -1266,7 +1212,7 @@ static bool gpencil_fill_poll(bContext *C)
}
/* Allocate memory and initialize values */
-static tGPDfill *gp_session_init_fill(bContext *C, wmOperator *UNUSED(op))
+static tGPDfill *gpencil_session_init_fill(bContext *C, wmOperator *UNUSED(op))
{
tGPDfill *tgpf = MEM_callocN(sizeof(tGPDfill), "GPencil Fill Data");
@@ -1399,7 +1345,7 @@ static int gpencil_fill_init(bContext *C, wmOperator *op)
}
/* check context */
- tgpf = op->customdata = gp_session_init_fill(C, op);
+ tgpf = op->customdata = gpencil_session_init_fill(C, op);
if (tgpf == NULL) {
/* something wasn't set correctly in context */
gpencil_fill_exit(C, op);
@@ -1499,7 +1445,7 @@ static int gpencil_fill_modal(bContext *C, wmOperator *op, const wmEvent *event)
tgpf->active_cfra = CFRA;
/* render screen to temp image */
- if (gp_render_offscreen(tgpf)) {
+ if (gpencil_render_offscreen(tgpf)) {
/* Set red borders to create a external limit. */
gpencil_set_borders(tgpf, true);
diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h
index 473913c5459..bd697dbc768 100644
--- a/source/blender/editors/gpencil/gpencil_intern.h
+++ b/source/blender/editors/gpencil/gpencil_intern.h
@@ -248,7 +248,7 @@ typedef struct tGPDprimitive {
} tGPDprimitive;
/* Modal Operator Drawing Callbacks ------------------------ */
-void ED_gp_draw_fill(struct tGPDdraw *tgpw);
+void ED_gpencil_draw_fill(struct tGPDdraw *tgpw);
/* ***************************************************** */
/* Internal API */
@@ -272,83 +272,85 @@ typedef struct GP_SpaceConversion {
float mat[4][4]; /* transform matrix on the strokes (introduced in [b770964]) */
} GP_SpaceConversion;
-bool gp_stroke_inside_circle(const float mval[2], int rad, int x0, int y0, int x1, int y1);
+bool gpencil_stroke_inside_circle(const float mval[2], int rad, int x0, int y0, int x1, int y1);
-void gp_point_conversion_init(struct bContext *C, GP_SpaceConversion *r_gsc);
+void gpencil_point_conversion_init(struct bContext *C, GP_SpaceConversion *r_gsc);
-void gp_point_to_xy(const GP_SpaceConversion *gsc,
- const struct bGPDstroke *gps,
- const struct bGPDspoint *pt,
- int *r_x,
- int *r_y);
+void gpencil_point_to_xy(const GP_SpaceConversion *gsc,
+ const struct bGPDstroke *gps,
+ const struct bGPDspoint *pt,
+ int *r_x,
+ int *r_y);
-void gp_point_to_xy_fl(const GP_SpaceConversion *gsc,
- const bGPDstroke *gps,
- const bGPDspoint *pt,
- float *r_x,
- float *r_y);
+void gpencil_point_to_xy_fl(const GP_SpaceConversion *gsc,
+ const bGPDstroke *gps,
+ const bGPDspoint *pt,
+ float *r_x,
+ float *r_y);
-void gp_point_to_parent_space(const bGPDspoint *pt, const float diff_mat[4][4], bGPDspoint *r_pt);
+void gpencil_point_to_parent_space(const bGPDspoint *pt,
+ const float diff_mat[4][4],
+ bGPDspoint *r_pt);
/**
* Change points position relative to parent object
*/
-void gp_apply_parent(struct Depsgraph *depsgraph,
- struct Object *obact,
- bGPDlayer *gpl,
- bGPDstroke *gps);
+void gpencil_apply_parent(struct Depsgraph *depsgraph,
+ struct Object *obact,
+ bGPDlayer *gpl,
+ bGPDstroke *gps);
/**
* Change point position relative to parent object
*/
-void gp_apply_parent_point(struct Depsgraph *depsgraph,
- struct Object *obact,
- bGPDlayer *gpl,
- bGPDspoint *pt);
+void gpencil_apply_parent_point(struct Depsgraph *depsgraph,
+ struct Object *obact,
+ bGPDlayer *gpl,
+ bGPDspoint *pt);
-void gp_point_3d_to_xy(const GP_SpaceConversion *gsc,
- const short flag,
- const float pt[3],
- float xy[2]);
+void gpencil_point_3d_to_xy(const GP_SpaceConversion *gsc,
+ const short flag,
+ const float pt[3],
+ float xy[2]);
-bool gp_point_xy_to_3d(const GP_SpaceConversion *gsc,
- struct Scene *scene,
- const float screen_co[2],
- float r_out[3]);
+bool gpencil_point_xy_to_3d(const GP_SpaceConversion *gsc,
+ struct Scene *scene,
+ const float screen_co[2],
+ float r_out[3]);
/* helper to convert 2d to 3d */
-void gp_stroke_convertcoords_tpoint(struct Scene *scene,
- struct ARegion *region,
- struct Object *ob,
- const struct tGPspoint *point2D,
- float *depth,
- float out[3]);
+void gpencil_stroke_convertcoords_tpoint(struct Scene *scene,
+ struct ARegion *region,
+ struct Object *ob,
+ const struct tGPspoint *point2D,
+ float *depth,
+ float out[3]);
/* Poll Callbacks ------------------------------------ */
/* gpencil_utils.c */
-bool gp_add_poll(struct bContext *C);
-bool gp_active_layer_poll(struct bContext *C);
-bool gp_active_brush_poll(struct bContext *C);
-bool gp_brush_crt_presets_poll(bContext *C);
+bool gpencil_add_poll(struct bContext *C);
+bool gpencil_active_layer_poll(struct bContext *C);
+bool gpencil_active_brush_poll(struct bContext *C);
+bool gpencil_brush_create_presets_poll(bContext *C);
/* Copy/Paste Buffer --------------------------------- */
/* gpencil_edit.c */
-extern ListBase gp_strokes_copypastebuf;
+extern ListBase gpencil_strokes_copypastebuf;
/* Build a map for converting between old colornames and destination-color-refs */
-struct GHash *gp_copybuf_validate_colormap(struct bContext *C);
+struct GHash *gpencil_copybuf_validate_colormap(struct bContext *C);
/* Stroke Editing ------------------------------------ */
-void gp_stroke_delete_tagged_points(bGPDframe *gpf,
- bGPDstroke *gps,
- bGPDstroke *next_stroke,
- int tag_flags,
- bool select,
- int limit);
-int gp_delete_selected_point_wrap(bContext *C);
+void gpencil_stroke_delete_tagged_points(bGPDframe *gpf,
+ bGPDstroke *gps,
+ bGPDstroke *next_stroke,
+ int tag_flags,
+ bool select,
+ int limit);
+int gpencil_delete_selected_point_wrap(bContext *C);
-void gp_subdivide_stroke(bGPDstroke *gps, const int subdivide);
+void gpencil_subdivide_stroke(bGPDstroke *gps, const int subdivide);
/* Layers Enums -------------------------------------- */
@@ -485,6 +487,8 @@ void GPENCIL_OT_frame_clean_fill(struct wmOperatorType *ot);
void GPENCIL_OT_frame_clean_loose(struct wmOperatorType *ot);
void GPENCIL_OT_convert(struct wmOperatorType *ot);
+void GPENCIL_OT_bake_mesh_animation(struct wmOperatorType *ot);
+
void GPENCIL_OT_image_to_grease_pencil(struct wmOperatorType *ot);
enum {
diff --git a/source/blender/editors/gpencil/gpencil_interpolate.c b/source/blender/editors/gpencil/gpencil_interpolate.c
index 5cb49600d05..5e653187edb 100644
--- a/source/blender/editors/gpencil/gpencil_interpolate.c
+++ b/source/blender/editors/gpencil/gpencil_interpolate.c
@@ -100,10 +100,10 @@ static bool gpencil_view3d_poll(bContext *C)
}
/* Perform interpolation */
-static void gp_interpolate_update_points(const bGPDstroke *gps_from,
- const bGPDstroke *gps_to,
- bGPDstroke *new_stroke,
- float factor)
+static void gpencil_interpolate_update_points(const bGPDstroke *gps_from,
+ const bGPDstroke *gps_to,
+ bGPDstroke *new_stroke,
+ float factor)
{
/* update points */
for (int i = 0; i < new_stroke->totpoints; i++) {
@@ -121,7 +121,7 @@ static void gp_interpolate_update_points(const bGPDstroke *gps_from,
/* ****************** Interpolate Interactive *********************** */
/* Helper: free all temp strokes for display. */
-static void gp_interpolate_free_temp_strokes(bGPDframe *gpf)
+static void gpencil_interpolate_free_temp_strokes(bGPDframe *gpf)
{
if (gpf == NULL) {
return;
@@ -136,9 +136,11 @@ static void gp_interpolate_free_temp_strokes(bGPDframe *gpf)
}
/* Helper: Untag all strokes. */
-static void gp_interpolate_untag_strokes(bGPDframe *gpf)
+static void gpencil_interpolate_untag_strokes(bGPDframe *gpf)
{
- BLI_assert(gpf != NULL);
+ if (gpf == NULL) {
+ return;
+ }
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
if (gps->flag & GP_STROKE_TAG) {
@@ -148,7 +150,7 @@ static void gp_interpolate_untag_strokes(bGPDframe *gpf)
}
/* Helper: Update all strokes interpolated */
-static void gp_interpolate_update_strokes(bContext *C, tGPDinterpolate *tgpi)
+static void gpencil_interpolate_update_strokes(bContext *C, tGPDinterpolate *tgpi)
{
bGPdata *gpd = tgpi->gpd;
const float shift = tgpi->shift;
@@ -158,7 +160,7 @@ static void gp_interpolate_update_strokes(bContext *C, tGPDinterpolate *tgpi)
bGPDframe *gpf = tgpil->gpl->actframe;
/* Free temp strokes. */
- gp_interpolate_free_temp_strokes(gpf);
+ gpencil_interpolate_free_temp_strokes(gpf);
LISTBASE_FOREACH (bGPDstroke *, new_stroke, &tgpil->interFrame->strokes) {
bGPDstroke *gps_from, *gps_to;
@@ -176,7 +178,7 @@ static void gp_interpolate_update_strokes(bContext *C, tGPDinterpolate *tgpi)
/* update points position */
if ((gps_from) && (gps_to)) {
- gp_interpolate_update_points(gps_from, gps_to, new_stroke, factor);
+ gpencil_interpolate_update_points(gps_from, gps_to, new_stroke, factor);
/* Add temp strokes. */
if (gpf) {
@@ -193,7 +195,7 @@ static void gp_interpolate_update_strokes(bContext *C, tGPDinterpolate *tgpi)
}
/* Helper: Verify valid strokes for interpolation */
-static bool gp_interpolate_check_todo(bContext *C, bGPdata *gpd)
+static bool gpencil_interpolate_check_todo(bContext *C, bGPdata *gpd)
{
Object *ob = CTX_data_active_object(C);
ToolSettings *ts = CTX_data_tool_settings(C);
@@ -243,7 +245,7 @@ static bool gp_interpolate_check_todo(bContext *C, bGPdata *gpd)
}
/* Helper: Create internal strokes interpolated */
-static void gp_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi)
+static void gpencil_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi)
{
bGPdata *gpd = tgpi->gpd;
bGPDlayer *active_gpl = CTX_data_active_gpencil_layer(C);
@@ -262,6 +264,14 @@ static void gp_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi)
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
tGPDinterpolate_layer *tgpil;
+ /* Untag strokes to be sure nothing is pending. This must be done for
+ * all layer because it could be anything tagged and it would be removed
+ * at the end of the process when all tagged strokes are removed. */
+ if (gpl->actframe != NULL) {
+ gpencil_interpolate_untag_strokes(gpl->actframe);
+ gpencil_interpolate_untag_strokes(gpl->actframe->next);
+ }
+
/* all layers or only active */
if (!(tgpi->flag & GP_TOOLFLAG_INTERPOLATE_ALL_LAYERS) && (gpl != active_gpl)) {
continue;
@@ -278,10 +288,6 @@ static void gp_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi)
tgpil->prevFrame = gpl->actframe;
tgpil->nextFrame = gpl->actframe->next;
- /* Untag interpolated strokes to be sure nothing is pending. */
- gp_interpolate_untag_strokes(tgpil->prevFrame);
- gp_interpolate_untag_strokes(tgpil->nextFrame);
-
BLI_addtail(&tgpi->ilayers, tgpil);
/* create a new temporary frame */
@@ -337,7 +343,7 @@ static void gp_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi)
new_stroke->totpoints = gps_to->totpoints;
}
/* update points position */
- gp_interpolate_update_points(gps_from, gps_to, new_stroke, tgpil->factor);
+ gpencil_interpolate_update_points(gps_from, gps_to, new_stroke, tgpil->factor);
}
else {
/* need an empty stroke to keep index correct for lookup, but resize to smallest size */
@@ -413,7 +419,7 @@ static void gpencil_interpolate_update(bContext *C, wmOperator *op, tGPDinterpol
/* apply... */
tgpi->shift = RNA_float_get(op->ptr, "shift");
/* update points position */
- gp_interpolate_update_strokes(C, tgpi);
+ gpencil_interpolate_update_strokes(C, tgpi);
}
/* ----------------------- */
@@ -433,7 +439,7 @@ static void gpencil_interpolate_exit(bContext *C, wmOperator *op)
/* Clear any temp stroke. */
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
- gp_interpolate_free_temp_strokes(gpf);
+ gpencil_interpolate_free_temp_strokes(gpf);
}
}
@@ -454,7 +460,7 @@ static void gpencil_interpolate_exit(bContext *C, wmOperator *op)
}
/* Init new temporary interpolation data */
-static bool gp_interpolate_set_init_values(bContext *C, wmOperator *op, tGPDinterpolate *tgpi)
+static bool gpencil_interpolate_set_init_values(bContext *C, wmOperator *op, tGPDinterpolate *tgpi)
{
ToolSettings *ts = CTX_data_tool_settings(C);
bGPdata *gpd = CTX_data_gpencil_data(C);
@@ -475,18 +481,18 @@ static bool gp_interpolate_set_init_values(bContext *C, wmOperator *op, tGPDinte
/* set interpolation weight */
tgpi->shift = RNA_float_get(op->ptr, "shift");
/* set layers */
- gp_interpolate_set_points(C, tgpi);
+ gpencil_interpolate_set_points(C, tgpi);
return 1;
}
/* Allocate memory and initialize values */
-static tGPDinterpolate *gp_session_init_interpolation(bContext *C, wmOperator *op)
+static tGPDinterpolate *gpencil_session_init_interpolation(bContext *C, wmOperator *op)
{
tGPDinterpolate *tgpi = MEM_callocN(sizeof(tGPDinterpolate), "GPencil Interpolate Data");
/* define initial values */
- gp_interpolate_set_init_values(C, op, tgpi);
+ gpencil_interpolate_set_init_values(C, op, tgpi);
/* return context data for running operator */
return tgpi;
@@ -498,7 +504,7 @@ static int gpencil_interpolate_init(bContext *C, wmOperator *op)
tGPDinterpolate *tgpi;
/* check context */
- tgpi = op->customdata = gp_session_init_interpolation(C, op);
+ tgpi = op->customdata = gpencil_session_init_interpolation(C, op);
if (tgpi == NULL) {
/* something wasn't set correctly in context */
gpencil_interpolate_exit(C, op);
@@ -540,7 +546,7 @@ static int gpencil_interpolate_invoke(bContext *C, wmOperator *op, const wmEvent
}
/* need editable strokes */
- if (!gp_interpolate_check_todo(C, gpd)) {
+ if (!gpencil_interpolate_check_todo(C, gpd)) {
BKE_report(op->reports, RPT_ERROR, "Interpolation requires some editable strokes");
return OPERATOR_CANCELLED;
}
@@ -731,7 +737,7 @@ void GPENCIL_OT_interpolate(wmOperatorType *ot)
/* ****************** Interpolate Sequence *********************** */
/* Helper: Perform easing equation calculations for GP interpolation operator */
-static float gp_interpolate_seq_easing_calc(GP_Interpolate_Settings *ipo_settings, float time)
+static float gpencil_interpolate_seq_easing_calc(GP_Interpolate_Settings *ipo_settings, float time)
{
const float begin = 0.0f;
const float change = 1.0f;
@@ -1008,7 +1014,7 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
}
else if (ipo_settings->type >= GP_IPO_BACK) {
/* easing equation... */
- factor = gp_interpolate_seq_easing_calc(ipo_settings, factor);
+ factor = gpencil_interpolate_seq_easing_calc(ipo_settings, factor);
}
/* create new strokes data with interpolated points reading original stroke */
@@ -1064,7 +1070,7 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
}
/* update points position */
- gp_interpolate_update_points(gps_from, gps_to, new_stroke, factor);
+ gpencil_interpolate_update_points(gps_from, gps_to, new_stroke, factor);
/* Calc geometry data. */
BKE_gpencil_stroke_geometry_update(new_stroke);
diff --git a/source/blender/editors/gpencil/gpencil_merge.c b/source/blender/editors/gpencil/gpencil_merge.c
index e71bf2098dd..cf806e68837 100644
--- a/source/blender/editors/gpencil/gpencil_merge.c
+++ b/source/blender/editors/gpencil/gpencil_merge.c
@@ -132,7 +132,7 @@ static bGPDstroke *gpencil_prepare_stroke(bContext *C, wmOperator *op, int totpo
bGPDframe *gpf = BKE_gpencil_layer_frame_get(gpl, CFRA, add_frame_mode);
/* stroke */
- bGPDstroke *gps = BKE_gpencil_stroke_new(ob->actcol - 1, totpoints, brush->size);
+ bGPDstroke *gps = BKE_gpencil_stroke_new(MAX2(ob->actcol - 1, 0), totpoints, brush->size);
gps->flag |= GP_STROKE_SELECT;
if (cyclic) {
@@ -178,7 +178,7 @@ static void gpencil_dissolve_points(bContext *C)
}
LISTBASE_FOREACH_MUTABLE (bGPDstroke *, gps, &gpf->strokes) {
- gp_stroke_delete_tagged_points(gpf, gps, gps->next, GP_SPOINT_TAG, false, 0);
+ gpencil_stroke_delete_tagged_points(gpf, gps, gps->next, GP_SPOINT_TAG, false, 0);
}
}
CTX_DATA_END;
@@ -431,7 +431,7 @@ static int gpencil_analyze_strokes(tGPencilPointCache *src_array,
return last;
}
-static bool gp_strokes_merge_poll(bContext *C)
+static bool gpencil_strokes_merge_poll(bContext *C)
{
/* only supported with grease pencil objects */
Object *ob = CTX_data_active_object(C);
@@ -462,7 +462,7 @@ static bool gp_strokes_merge_poll(bContext *C)
return (CTX_DATA_COUNT(C, editable_gpencil_strokes) != 0) && ED_operator_view3d_active(C);
}
-static int gp_stroke_merge_exec(bContext *C, wmOperator *op)
+static int gpencil_stroke_merge_exec(bContext *C, wmOperator *op)
{
const int mode = RNA_enum_get(op->ptr, "mode");
const bool clear_point = RNA_boolean_get(op->ptr, "clear_point");
@@ -546,8 +546,8 @@ void GPENCIL_OT_stroke_merge(wmOperatorType *ot)
ot->description = "Create a new stroke with the selected stroke points";
/* api callbacks */
- ot->exec = gp_stroke_merge_exec;
- ot->poll = gp_strokes_merge_poll;
+ ot->exec = gpencil_stroke_merge_exec;
+ ot->poll = gpencil_strokes_merge_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -563,7 +563,7 @@ void GPENCIL_OT_stroke_merge(wmOperatorType *ot)
}
/* Merge similar materials. */
-static bool gp_stroke_merge_material_poll(bContext *C)
+static bool gpencil_stroke_merge_material_poll(bContext *C)
{
/* only supported with grease pencil objects */
Object *ob = CTX_data_active_object(C);
@@ -574,7 +574,7 @@ static bool gp_stroke_merge_material_poll(bContext *C)
return true;
}
-static int gp_stroke_merge_material_exec(bContext *C, wmOperator *op)
+static int gpencil_stroke_merge_material_exec(bContext *C, wmOperator *op)
{
Object *ob = CTX_data_active_object(C);
bGPdata *gpd = (bGPdata *)ob->data;
@@ -642,8 +642,8 @@ void GPENCIL_OT_stroke_merge_material(wmOperatorType *ot)
ot->description = "Replace materials in strokes merging similar";
/* api callbacks */
- ot->exec = gp_stroke_merge_material_exec;
- ot->poll = gp_stroke_merge_material_poll;
+ ot->exec = gpencil_stroke_merge_material_exec;
+ ot->poll = gpencil_stroke_merge_material_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
diff --git a/source/blender/editors/gpencil/gpencil_mesh.c b/source/blender/editors/gpencil/gpencil_mesh.c
new file mode 100644
index 00000000000..763f5687edf
--- /dev/null
+++ b/source/blender/editors/gpencil/gpencil_mesh.c
@@ -0,0 +1,404 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2008, Blender Foundation
+ * This is a new part of Blender
+ * Operator for converting Grease Pencil data to geometry
+ */
+
+/** \file
+ * \ingroup edgpencil
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_math.h"
+
+#include "DNA_gpencil_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+
+#include "BKE_context.h"
+#include "BKE_duplilist.h"
+#include "BKE_global.h"
+#include "BKE_gpencil.h"
+#include "BKE_gpencil_geom.h"
+#include "BKE_main.h"
+#include "BKE_material.h"
+#include "BKE_object.h"
+#include "BKE_report.h"
+#include "BKE_scene.h"
+
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "ED_gpencil.h"
+#include "ED_transform_snap_object_context.h"
+
+#include "gpencil_intern.h"
+
+/* Check frame_end is always > start frame! */
+static void gpencil_bake_set_frame_end(struct Main *UNUSED(main),
+ struct Scene *UNUSED(scene),
+ struct PointerRNA *ptr)
+{
+ int frame_start = RNA_int_get(ptr, "frame_start");
+ int frame_end = RNA_int_get(ptr, "frame_end");
+
+ if (frame_end <= frame_start) {
+ RNA_int_set(ptr, "frame_end", frame_start + 1);
+ }
+}
+
+/* Extract mesh animation to Grease Pencil. */
+static bool gpencil_bake_mesh_animation_poll(bContext *C)
+{
+ if (CTX_data_mode_enum(C) != CTX_MODE_OBJECT) {
+ return false;
+ }
+
+ /* Only if the current view is 3D View. */
+ ScrArea *area = CTX_wm_area(C);
+ return (area && area->spacetype);
+}
+
+typedef struct GpBakeOb {
+ struct GPBakelist *next, *prev;
+ Object *ob;
+} GpBakeOb;
+
+static void gpencil_bake_duplilist(Depsgraph *depsgraph, Scene *scene, Object *ob, ListBase *list)
+{
+ GpBakeOb *elem = NULL;
+ ListBase *lb;
+ DupliObject *dob;
+ lb = object_duplilist(depsgraph, scene, ob);
+ for (dob = lb->first; dob; dob = dob->next) {
+ if (dob->ob->type != OB_MESH) {
+ continue;
+ }
+ elem = MEM_callocN(sizeof(GpBakeOb), __func__);
+ elem->ob = dob->ob;
+ BLI_addtail(list, elem);
+ }
+
+ free_object_duplilist(lb);
+}
+
+static void gpencil_bake_ob_list(bContext *C, Depsgraph *depsgraph, Scene *scene, ListBase *list)
+{
+ GpBakeOb *elem = NULL;
+
+ /* Add active object. In some files this could not be in selected array. */
+ Object *obact = CTX_data_active_object(C);
+
+ if (obact->type == OB_MESH) {
+ elem = MEM_callocN(sizeof(GpBakeOb), __func__);
+ elem->ob = obact;
+ BLI_addtail(list, elem);
+ }
+ /* Add duplilist. */
+ else if (obact->type == OB_EMPTY) {
+ gpencil_bake_duplilist(depsgraph, scene, obact, list);
+ }
+
+ /* Add other selected objects. */
+ CTX_DATA_BEGIN (C, Object *, ob, selected_objects) {
+ if (ob == obact) {
+ continue;
+ }
+ /* Add selected meshes.*/
+ if (ob->type == OB_MESH) {
+ elem = MEM_callocN(sizeof(GpBakeOb), __func__);
+ elem->ob = ob;
+ BLI_addtail(list, elem);
+ }
+
+ /* Add duplilist. */
+ if (ob->type == OB_EMPTY) {
+ gpencil_bake_duplilist(depsgraph, scene, obact, list);
+ }
+ }
+ CTX_DATA_END;
+}
+
+static void gpencil_bake_free_ob_list(ListBase *list)
+{
+ LISTBASE_FOREACH_MUTABLE (GpBakeOb *, elem, list) {
+ MEM_SAFE_FREE(elem);
+ }
+}
+
+static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op)
+{
+ Main *bmain = CTX_data_main(C);
+ Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+ Scene *scene = CTX_data_scene(C);
+ ARegion *region = CTX_wm_region(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ Object *ob_gpencil = NULL;
+
+ ListBase list = {NULL, NULL};
+ gpencil_bake_ob_list(C, depsgraph, scene, &list);
+
+ /* Cannot check this in poll because the active object changes. */
+ if (list.first == NULL) {
+ BKE_report(op->reports, RPT_INFO, "No valid object selected");
+ gpencil_bake_free_ob_list(&list);
+ return OPERATOR_CANCELLED;
+ }
+
+ /* Grab all relevant settings. */
+ const int step = RNA_int_get(op->ptr, "step");
+
+ const int frame_start = (scene->r.sfra > RNA_int_get(op->ptr, "frame_start")) ?
+ scene->r.sfra :
+ RNA_int_get(op->ptr, "frame_start");
+
+ const int frame_end = (scene->r.efra < RNA_int_get(op->ptr, "frame_end")) ?
+ scene->r.efra :
+ RNA_int_get(op->ptr, "frame_end");
+
+ const float angle = RNA_float_get(op->ptr, "angle");
+ 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 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");
+
+ /* Create a new grease pencil object in origin. */
+ bool newob = false;
+ if (STREQ(target, "*NEW")) {
+ ushort local_view_bits = (v3d && v3d->localvd) ? v3d->local_view_uuid : 0;
+ 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;
+
+ /* Set cursor to indicate working. */
+ WM_cursor_wait(1);
+
+ GP_SpaceConversion gsc = {NULL};
+ SnapObjectContext *sctx = NULL;
+ if (project_type != GP_REPROJECT_KEEP) {
+ /* Init space conversion stuff. */
+ gpencil_point_conversion_init(C, &gsc);
+ /* Init snap context for geometry projection. */
+ sctx = ED_transform_snap_object_context_create_view3d(scene, 0, region, CTX_wm_view3d(C));
+
+ /* Tag all existing strokes to avoid reprojections. */
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
+ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+ gps->flag |= GP_STROKE_TAG;
+ }
+ }
+ }
+ }
+
+ /* Loop all frame range. */
+ int oldframe = (int)DEG_get_ctime(depsgraph);
+ int key = -1;
+ for (int i = frame_start; i < frame_end + 1; i++) {
+ key++;
+ /* Jump if not step limit but include last frame always. */
+ if ((key % step != 0) && (i != frame_end)) {
+ continue;
+ }
+
+ /* Move scene to new frame. */
+ CFRA = i;
+ BKE_scene_graph_update_for_newframe(depsgraph, bmain);
+
+ /* Loop all objects in the list. */
+ LISTBASE_FOREACH (GpBakeOb *, elem, &list) {
+ Object *ob_eval = (Object *)DEG_get_evaluated_object(depsgraph, elem->ob);
+
+ /* Generate strokes. */
+ BKE_gpencil_convert_mesh(bmain,
+ depsgraph,
+ scene,
+ ob_gpencil,
+ elem->ob,
+ angle,
+ thickness,
+ offset,
+ ob_eval->obmat,
+ frame_offset,
+ use_seams,
+ use_faces);
+
+ /* Reproject all untaged created strokes. */
+ 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;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* Return scene frame state and DB to original state. */
+ CFRA = oldframe;
+ BKE_scene_graph_update_for_newframe(depsgraph, bmain);
+
+ /* Remove unused materials. */
+ int actcol = ob_gpencil->actcol;
+ for (int slot = 1; slot <= ob_gpencil->totcol; slot++) {
+ while (slot <= ob_gpencil->totcol && !BKE_object_material_slot_used(ob_gpencil->data, slot)) {
+ ob_gpencil->actcol = slot;
+ BKE_object_material_slot_remove(CTX_data_main(C), ob_gpencil);
+
+ if (actcol >= slot) {
+ actcol--;
+ }
+ }
+ }
+ ob_gpencil->actcol = actcol;
+
+ /* Untag all strokes. */
+ if (project_type != GP_REPROJECT_KEEP) {
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
+ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+ gps->flag &= ~GP_STROKE_TAG;
+ }
+ }
+ }
+ }
+
+ /* Free memory. */
+ gpencil_bake_free_ob_list(&list);
+ if (sctx != NULL) {
+ ED_transform_snap_object_context_destroy(sctx);
+ }
+
+ /* notifiers */
+ if (newob) {
+ DEG_relations_tag_update(bmain);
+ }
+ DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_OBJECT | NA_ADDED, NULL);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
+
+ /* Reset cursor. */
+ WM_cursor_wait(0);
+
+ /* done */
+ return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_bake_mesh_animation(wmOperatorType *ot)
+{
+ static const EnumPropertyItem reproject_type[] = {
+ {GP_REPROJECT_KEEP, "KEEP", 0, "No Reproject", ""},
+ {GP_REPROJECT_FRONT, "FRONT", 0, "Front", "Reproject the strokes using the X-Z plane"},
+ {GP_REPROJECT_SIDE, "SIDE", 0, "Side", "Reproject the strokes using the Y-Z plane"},
+ {GP_REPROJECT_TOP, "TOP", 0, "Top", "Reproject the strokes using the X-Y plane"},
+ {GP_REPROJECT_VIEW,
+ "VIEW",
+ 0,
+ "View",
+ "Reproject the strokes to end up on the same plane, as if drawn from the current viewpoint "
+ "using 'Cursor' Stroke Placement"},
+ {GP_REPROJECT_CURSOR,
+ "CURSOR",
+ 0,
+ "Cursor",
+ "Reproject the strokes using the orientation of 3D cursor"},
+ {0, NULL, 0, NULL, NULL},
+ };
+
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Bake Mesh Animation to Grease Pencil";
+ ot->idname = "GPENCIL_OT_bake_mesh_animation";
+ ot->description = "Bake Mesh Animation to Grease Pencil strokes";
+
+ /* callbacks */
+ ot->exec = gpencil_bake_mesh_animation_exec;
+ ot->poll = gpencil_bake_mesh_animation_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ ot->prop = RNA_def_int(
+ ot->srna, "frame_start", 1, 1, 100000, "Start Frame", "The start frame", 1, 100000);
+
+ prop = RNA_def_int(
+ ot->srna, "frame_end", 250, 1, 100000, "End Frame", "The end frame of animation", 1, 100000);
+ RNA_def_property_update_runtime(prop, gpencil_bake_set_frame_end);
+
+ prop = RNA_def_int(ot->srna, "step", 1, 1, 100, "Step", "Step between generated frames", 1, 100);
+
+ prop = RNA_def_float_rotation(ot->srna,
+ "angle",
+ 0,
+ NULL,
+ DEG2RADF(0.0f),
+ DEG2RADF(180.0f),
+ "Threshold Angle",
+ "Threshold to determine ends of the strokes",
+ DEG2RADF(0.0f),
+ 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_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_enum(ot->srna, "project_type", reproject_type, GP_REPROJECT_VIEW, "Projection Type", "");
+}
diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c
index 94c86572fd3..e645668ef1c 100644
--- a/source/blender/editors/gpencil/gpencil_ops.c
+++ b/source/blender/editors/gpencil/gpencil_ops.c
@@ -63,21 +63,21 @@ static void ed_keymap_gpencil_general(wmKeyConfig *keyconf)
/* ==================== */
/* Poll callback for stroke editing mode */
-static bool gp_stroke_editmode_poll(bContext *C)
+static bool gpencil_stroke_editmode_poll(bContext *C)
{
bGPdata *gpd = CTX_data_gpencil_data(C);
return (gpd && (gpd->flag & GP_DATA_STROKE_EDITMODE));
}
/* Poll callback for stroke painting mode */
-static bool gp_stroke_paintmode_poll(bContext *C)
+static bool gpencil_stroke_paintmode_poll(bContext *C)
{
/* TODO: limit this to mode, but review 2D editors */
bGPdata *gpd = CTX_data_gpencil_data(C);
return (gpd && (gpd->flag & GP_DATA_STROKE_PAINTMODE));
}
-static bool gp_stroke_paintmode_poll_with_tool(bContext *C, const char gpencil_tool)
+static bool gpencil_stroke_paintmode_poll_with_tool(bContext *C, const char gpencil_tool)
{
/* TODO: limit this to mode, but review 2D editors */
bGPdata *gpd = CTX_data_gpencil_data(C);
@@ -95,7 +95,7 @@ static bool gp_stroke_paintmode_poll_with_tool(bContext *C, const char gpencil_t
WM_toolsystem_active_tool_is_brush(C) && (brush->gpencil_tool == gpencil_tool));
}
-static bool gp_stroke_vertexmode_poll_with_tool(bContext *C, const char gpencil_vertex_tool)
+static bool gpencil_stroke_vertexmode_poll_with_tool(bContext *C, const char gpencil_vertex_tool)
{
bGPdata *gpd = CTX_data_gpencil_data(C);
if (!gpd) {
@@ -113,7 +113,7 @@ static bool gp_stroke_vertexmode_poll_with_tool(bContext *C, const char gpencil_
(brush->gpencil_vertex_tool == gpencil_vertex_tool));
}
-static bool gp_stroke_sculptmode_poll_with_tool(bContext *C, const char gpencil_sculpt_tool)
+static bool gpencil_stroke_sculptmode_poll_with_tool(bContext *C, const char gpencil_sculpt_tool)
{
bGPdata *gpd = CTX_data_gpencil_data(C);
if (!gpd) {
@@ -131,7 +131,7 @@ static bool gp_stroke_sculptmode_poll_with_tool(bContext *C, const char gpencil_
(brush->gpencil_sculpt_tool == gpencil_sculpt_tool));
}
-static bool gp_stroke_weightmode_poll_with_tool(bContext *C, const char gpencil_weight_tool)
+static bool gpencil_stroke_weightmode_poll_with_tool(bContext *C, const char gpencil_weight_tool)
{
bGPdata *gpd = CTX_data_gpencil_data(C);
if (!gpd) {
@@ -150,31 +150,31 @@ static bool gp_stroke_weightmode_poll_with_tool(bContext *C, const char gpencil_
}
/* Poll callback for stroke painting (draw brush) */
-static bool gp_stroke_paintmode_draw_poll(bContext *C)
+static bool gpencil_stroke_paintmode_draw_poll(bContext *C)
{
- return gp_stroke_paintmode_poll_with_tool(C, GPAINT_TOOL_DRAW);
+ return gpencil_stroke_paintmode_poll_with_tool(C, GPAINT_TOOL_DRAW);
}
/* Poll callback for stroke painting (erase brush) */
-static bool gp_stroke_paintmode_erase_poll(bContext *C)
+static bool gpencil_stroke_paintmode_erase_poll(bContext *C)
{
- return gp_stroke_paintmode_poll_with_tool(C, GPAINT_TOOL_ERASE);
+ return gpencil_stroke_paintmode_poll_with_tool(C, GPAINT_TOOL_ERASE);
}
/* Poll callback for stroke painting (fill) */
-static bool gp_stroke_paintmode_fill_poll(bContext *C)
+static bool gpencil_stroke_paintmode_fill_poll(bContext *C)
{
- return gp_stroke_paintmode_poll_with_tool(C, GPAINT_TOOL_FILL);
+ return gpencil_stroke_paintmode_poll_with_tool(C, GPAINT_TOOL_FILL);
}
/* Poll callback for stroke painting (tint) */
-static bool gp_stroke_paintmode_tint_poll(bContext *C)
+static bool gpencil_stroke_paintmode_tint_poll(bContext *C)
{
- return gp_stroke_paintmode_poll_with_tool(C, GPAINT_TOOL_TINT);
+ return gpencil_stroke_paintmode_poll_with_tool(C, GPAINT_TOOL_TINT);
}
/* Poll callback for stroke sculpting mode */
-static bool gp_stroke_sculptmode_poll(bContext *C)
+static bool gpencil_stroke_sculptmode_poll(bContext *C)
{
bGPdata *gpd = CTX_data_gpencil_data(C);
Object *ob = CTX_data_active_object(C);
@@ -194,7 +194,7 @@ static bool gp_stroke_sculptmode_poll(bContext *C)
}
/* Poll callback for stroke weight paint mode */
-static bool gp_stroke_weightmode_poll(bContext *C)
+static bool gpencil_stroke_weightmode_poll(bContext *C)
{
bGPdata *gpd = CTX_data_gpencil_data(C);
Object *ob = CTX_data_active_object(C);
@@ -207,7 +207,7 @@ static bool gp_stroke_weightmode_poll(bContext *C)
}
/* Poll callback for stroke vertex paint mode */
-static bool gp_stroke_vertexmode_poll(bContext *C)
+static bool gpencil_stroke_vertexmode_poll(bContext *C)
{
bGPdata *gpd = CTX_data_gpencil_data(C);
Object *ob = CTX_data_active_object(C);
@@ -220,91 +220,91 @@ static bool gp_stroke_vertexmode_poll(bContext *C)
}
/* Poll callback for vertex painting (draw) */
-static bool gp_stroke_vertexmode_draw_poll(bContext *C)
+static bool gpencil_stroke_vertexmode_draw_poll(bContext *C)
{
- return gp_stroke_vertexmode_poll_with_tool(C, GPVERTEX_TOOL_DRAW);
+ return gpencil_stroke_vertexmode_poll_with_tool(C, GPVERTEX_TOOL_DRAW);
}
/* Poll callback for vertex painting (blur) */
-static bool gp_stroke_vertexmode_blur_poll(bContext *C)
+static bool gpencil_stroke_vertexmode_blur_poll(bContext *C)
{
- return gp_stroke_vertexmode_poll_with_tool(C, GPVERTEX_TOOL_BLUR);
+ return gpencil_stroke_vertexmode_poll_with_tool(C, GPVERTEX_TOOL_BLUR);
}
/* Poll callback for vertex painting (average) */
-static bool gp_stroke_vertexmode_average_poll(bContext *C)
+static bool gpencil_stroke_vertexmode_average_poll(bContext *C)
{
- return gp_stroke_vertexmode_poll_with_tool(C, GPVERTEX_TOOL_AVERAGE);
+ return gpencil_stroke_vertexmode_poll_with_tool(C, GPVERTEX_TOOL_AVERAGE);
}
/* Poll callback for vertex painting (smear) */
-static bool gp_stroke_vertexmode_smear_poll(bContext *C)
+static bool gpencil_stroke_vertexmode_smear_poll(bContext *C)
{
- return gp_stroke_vertexmode_poll_with_tool(C, GPVERTEX_TOOL_SMEAR);
+ return gpencil_stroke_vertexmode_poll_with_tool(C, GPVERTEX_TOOL_SMEAR);
}
/* Poll callback for vertex painting (replace) */
-static bool gp_stroke_vertexmode_replace_poll(bContext *C)
+static bool gpencil_stroke_vertexmode_replace_poll(bContext *C)
{
- return gp_stroke_vertexmode_poll_with_tool(C, GPVERTEX_TOOL_REPLACE);
+ return gpencil_stroke_vertexmode_poll_with_tool(C, GPVERTEX_TOOL_REPLACE);
}
/* Poll callback for sculpt (Smooth) */
-static bool gp_stroke_sculptmode_smooth_poll(bContext *C)
+static bool gpencil_stroke_sculptmode_smooth_poll(bContext *C)
{
- return gp_stroke_sculptmode_poll_with_tool(C, GPSCULPT_TOOL_SMOOTH);
+ return gpencil_stroke_sculptmode_poll_with_tool(C, GPSCULPT_TOOL_SMOOTH);
}
/* Poll callback for sculpt (Thickness) */
-static bool gp_stroke_sculptmode_thickness_poll(bContext *C)
+static bool gpencil_stroke_sculptmode_thickness_poll(bContext *C)
{
- return gp_stroke_sculptmode_poll_with_tool(C, GPSCULPT_TOOL_THICKNESS);
+ return gpencil_stroke_sculptmode_poll_with_tool(C, GPSCULPT_TOOL_THICKNESS);
}
/* Poll callback for sculpt (Strength) */
-static bool gp_stroke_sculptmode_strength_poll(bContext *C)
+static bool gpencil_stroke_sculptmode_strength_poll(bContext *C)
{
- return gp_stroke_sculptmode_poll_with_tool(C, GPSCULPT_TOOL_STRENGTH);
+ return gpencil_stroke_sculptmode_poll_with_tool(C, GPSCULPT_TOOL_STRENGTH);
}
/* Poll callback for sculpt (Grab) */
-static bool gp_stroke_sculptmode_grab_poll(bContext *C)
+static bool gpencil_stroke_sculptmode_grab_poll(bContext *C)
{
- return gp_stroke_sculptmode_poll_with_tool(C, GPSCULPT_TOOL_GRAB);
+ return gpencil_stroke_sculptmode_poll_with_tool(C, GPSCULPT_TOOL_GRAB);
}
/* Poll callback for sculpt (Push) */
-static bool gp_stroke_sculptmode_push_poll(bContext *C)
+static bool gpencil_stroke_sculptmode_push_poll(bContext *C)
{
- return gp_stroke_sculptmode_poll_with_tool(C, GPSCULPT_TOOL_PUSH);
+ return gpencil_stroke_sculptmode_poll_with_tool(C, GPSCULPT_TOOL_PUSH);
}
/* Poll callback for sculpt (Twist) */
-static bool gp_stroke_sculptmode_twist_poll(bContext *C)
+static bool gpencil_stroke_sculptmode_twist_poll(bContext *C)
{
- return gp_stroke_sculptmode_poll_with_tool(C, GPSCULPT_TOOL_TWIST);
+ return gpencil_stroke_sculptmode_poll_with_tool(C, GPSCULPT_TOOL_TWIST);
}
/* Poll callback for sculpt (Pinch) */
-static bool gp_stroke_sculptmode_pinch_poll(bContext *C)
+static bool gpencil_stroke_sculptmode_pinch_poll(bContext *C)
{
- return gp_stroke_sculptmode_poll_with_tool(C, GPSCULPT_TOOL_PINCH);
+ return gpencil_stroke_sculptmode_poll_with_tool(C, GPSCULPT_TOOL_PINCH);
}
/* Poll callback for sculpt (Randomize) */
-static bool gp_stroke_sculptmode_randomize_poll(bContext *C)
+static bool gpencil_stroke_sculptmode_randomize_poll(bContext *C)
{
- return gp_stroke_sculptmode_poll_with_tool(C, GPSCULPT_TOOL_RANDOMIZE);
+ return gpencil_stroke_sculptmode_poll_with_tool(C, GPSCULPT_TOOL_RANDOMIZE);
}
/* Poll callback for sculpt (Clone) */
-static bool gp_stroke_sculptmode_clone_poll(bContext *C)
+static bool gpencil_stroke_sculptmode_clone_poll(bContext *C)
{
- return gp_stroke_sculptmode_poll_with_tool(C, GPSCULPT_TOOL_CLONE);
+ return gpencil_stroke_sculptmode_poll_with_tool(C, GPSCULPT_TOOL_CLONE);
}
/* Poll callback for weight paint (Draw) */
-static bool gp_stroke_weightmode_draw_poll(bContext *C)
+static bool gpencil_stroke_weightmode_draw_poll(bContext *C)
{
- return gp_stroke_weightmode_poll_with_tool(C, GPWEIGHT_TOOL_DRAW);
+ return gpencil_stroke_weightmode_poll_with_tool(C, GPWEIGHT_TOOL_DRAW);
}
/* Stroke Editing Keymap - Only when editmode is enabled */
@@ -313,35 +313,35 @@ static void ed_keymap_gpencil_editing(wmKeyConfig *keyconf)
wmKeyMap *keymap = WM_keymap_ensure(keyconf, "Grease Pencil Stroke Edit Mode", 0, 0);
/* set poll callback - so that this keymap only gets enabled when stroke editmode is enabled */
- keymap->poll = gp_stroke_editmode_poll;
+ keymap->poll = gpencil_stroke_editmode_poll;
}
/* keys for draw with a drawing brush (no fill) */
static void ed_keymap_gpencil_painting_draw(wmKeyConfig *keyconf)
{
wmKeyMap *keymap = WM_keymap_ensure(keyconf, "Grease Pencil Stroke Paint (Draw brush)", 0, 0);
- keymap->poll = gp_stroke_paintmode_draw_poll;
+ keymap->poll = gpencil_stroke_paintmode_draw_poll;
}
/* keys for draw with a eraser brush (erase) */
static void ed_keymap_gpencil_painting_erase(wmKeyConfig *keyconf)
{
wmKeyMap *keymap = WM_keymap_ensure(keyconf, "Grease Pencil Stroke Paint (Erase)", 0, 0);
- keymap->poll = gp_stroke_paintmode_erase_poll;
+ keymap->poll = gpencil_stroke_paintmode_erase_poll;
}
/* keys for draw with a fill brush */
static void ed_keymap_gpencil_painting_fill(wmKeyConfig *keyconf)
{
wmKeyMap *keymap = WM_keymap_ensure(keyconf, "Grease Pencil Stroke Paint (Fill)", 0, 0);
- keymap->poll = gp_stroke_paintmode_fill_poll;
+ keymap->poll = gpencil_stroke_paintmode_fill_poll;
}
/* keys for draw with a tint brush */
static void ed_keymap_gpencil_painting_tint(wmKeyConfig *keyconf)
{
wmKeyMap *keymap = WM_keymap_ensure(keyconf, "Grease Pencil Stroke Paint (Tint)", 0, 0);
- keymap->poll = gp_stroke_paintmode_tint_poll;
+ keymap->poll = gpencil_stroke_paintmode_tint_poll;
}
/* Stroke Painting Keymap - Only when paintmode is enabled */
@@ -349,7 +349,7 @@ static void ed_keymap_gpencil_painting(wmKeyConfig *keyconf)
{
/* set poll callback - so that this keymap only gets enabled when stroke paintmode is enabled */
wmKeyMap *keymap = WM_keymap_ensure(keyconf, "Grease Pencil Stroke Paint Mode", 0, 0);
- keymap->poll = gp_stroke_paintmode_poll;
+ keymap->poll = gpencil_stroke_paintmode_poll;
}
/* Stroke Sculpting Keymap - Only when sculptmode is enabled */
@@ -357,7 +357,7 @@ static void ed_keymap_gpencil_sculpting(wmKeyConfig *keyconf)
{
/* set poll callback - so that this keymap only gets enabled when stroke sculptmode is enabled */
wmKeyMap *keymap = WM_keymap_ensure(keyconf, "Grease Pencil Stroke Sculpt Mode", 0, 0);
- keymap->poll = gp_stroke_sculptmode_poll;
+ keymap->poll = gpencil_stroke_sculptmode_poll;
}
/* Stroke Weight Paint Keymap - Only when weight is enabled */
@@ -365,106 +365,106 @@ static void ed_keymap_gpencil_weightpainting(wmKeyConfig *keyconf)
{
/* set poll callback - so that this keymap only gets enabled when stroke sculptmode is enabled */
wmKeyMap *keymap = WM_keymap_ensure(keyconf, "Grease Pencil Stroke Weight Mode", 0, 0);
- keymap->poll = gp_stroke_weightmode_poll;
+ keymap->poll = gpencil_stroke_weightmode_poll;
}
static void ed_keymap_gpencil_vertexpainting(wmKeyConfig *keyconf)
{
/* set poll callback - so that this keymap only gets enabled when stroke vertex is enabled */
wmKeyMap *keymap = WM_keymap_ensure(keyconf, "Grease Pencil Stroke Vertex Mode", 0, 0);
- keymap->poll = gp_stroke_vertexmode_poll;
+ keymap->poll = gpencil_stroke_vertexmode_poll;
}
/* keys for vertex with a draw brush */
static void ed_keymap_gpencil_vertexpainting_draw(wmKeyConfig *keyconf)
{
wmKeyMap *keymap = WM_keymap_ensure(keyconf, "Grease Pencil Stroke Vertex (Draw)", 0, 0);
- keymap->poll = gp_stroke_vertexmode_draw_poll;
+ keymap->poll = gpencil_stroke_vertexmode_draw_poll;
}
/* keys for vertex with a blur brush */
static void ed_keymap_gpencil_vertexpainting_blur(wmKeyConfig *keyconf)
{
wmKeyMap *keymap = WM_keymap_ensure(keyconf, "Grease Pencil Stroke Vertex (Blur)", 0, 0);
- keymap->poll = gp_stroke_vertexmode_blur_poll;
+ keymap->poll = gpencil_stroke_vertexmode_blur_poll;
}
/* keys for vertex with a average brush */
static void ed_keymap_gpencil_vertexpainting_average(wmKeyConfig *keyconf)
{
wmKeyMap *keymap = WM_keymap_ensure(keyconf, "Grease Pencil Stroke Vertex (Average)", 0, 0);
- keymap->poll = gp_stroke_vertexmode_average_poll;
+ keymap->poll = gpencil_stroke_vertexmode_average_poll;
}
/* keys for vertex with a smear brush */
static void ed_keymap_gpencil_vertexpainting_smear(wmKeyConfig *keyconf)
{
wmKeyMap *keymap = WM_keymap_ensure(keyconf, "Grease Pencil Stroke Vertex (Smear)", 0, 0);
- keymap->poll = gp_stroke_vertexmode_smear_poll;
+ keymap->poll = gpencil_stroke_vertexmode_smear_poll;
}
/* keys for vertex with a replace brush */
static void ed_keymap_gpencil_vertexpainting_replace(wmKeyConfig *keyconf)
{
wmKeyMap *keymap = WM_keymap_ensure(keyconf, "Grease Pencil Stroke Vertex (Replace)", 0, 0);
- keymap->poll = gp_stroke_vertexmode_replace_poll;
+ keymap->poll = gpencil_stroke_vertexmode_replace_poll;
}
/* keys for sculpt with a smooth brush */
static void ed_keymap_gpencil_sculptpainting_smooth(wmKeyConfig *keyconf)
{
wmKeyMap *keymap = WM_keymap_ensure(keyconf, "Grease Pencil Stroke Sculpt (Smooth)", 0, 0);
- keymap->poll = gp_stroke_sculptmode_smooth_poll;
+ keymap->poll = gpencil_stroke_sculptmode_smooth_poll;
}
/* keys for sculpt with a thickness brush */
static void ed_keymap_gpencil_sculptpainting_thickness(wmKeyConfig *keyconf)
{
wmKeyMap *keymap = WM_keymap_ensure(keyconf, "Grease Pencil Stroke Sculpt (Thickness)", 0, 0);
- keymap->poll = gp_stroke_sculptmode_thickness_poll;
+ keymap->poll = gpencil_stroke_sculptmode_thickness_poll;
}
/* keys for sculpt with a strength brush */
static void ed_keymap_gpencil_sculptpainting_strength(wmKeyConfig *keyconf)
{
wmKeyMap *keymap = WM_keymap_ensure(keyconf, "Grease Pencil Stroke Sculpt (Strength)", 0, 0);
- keymap->poll = gp_stroke_sculptmode_strength_poll;
+ keymap->poll = gpencil_stroke_sculptmode_strength_poll;
}
/* keys for sculpt with a grab brush */
static void ed_keymap_gpencil_sculptpainting_grab(wmKeyConfig *keyconf)
{
wmKeyMap *keymap = WM_keymap_ensure(keyconf, "Grease Pencil Stroke Sculpt (Grab)", 0, 0);
- keymap->poll = gp_stroke_sculptmode_grab_poll;
+ keymap->poll = gpencil_stroke_sculptmode_grab_poll;
}
/* keys for sculpt with a push brush */
static void ed_keymap_gpencil_sculptpainting_push(wmKeyConfig *keyconf)
{
wmKeyMap *keymap = WM_keymap_ensure(keyconf, "Grease Pencil Stroke Sculpt (Push)", 0, 0);
- keymap->poll = gp_stroke_sculptmode_push_poll;
+ keymap->poll = gpencil_stroke_sculptmode_push_poll;
}
/* keys for sculpt with a twist brush */
static void ed_keymap_gpencil_sculptpainting_twist(wmKeyConfig *keyconf)
{
wmKeyMap *keymap = WM_keymap_ensure(keyconf, "Grease Pencil Stroke Sculpt (Twist)", 0, 0);
- keymap->poll = gp_stroke_sculptmode_twist_poll;
+ keymap->poll = gpencil_stroke_sculptmode_twist_poll;
}
/* keys for sculpt with a pinch brush */
static void ed_keymap_gpencil_sculptpainting_pinch(wmKeyConfig *keyconf)
{
wmKeyMap *keymap = WM_keymap_ensure(keyconf, "Grease Pencil Stroke Sculpt (Pinch)", 0, 0);
- keymap->poll = gp_stroke_sculptmode_pinch_poll;
+ keymap->poll = gpencil_stroke_sculptmode_pinch_poll;
}
/* keys for sculpt with a randomize brush */
static void ed_keymap_gpencil_sculptpainting_randomize(wmKeyConfig *keyconf)
{
wmKeyMap *keymap = WM_keymap_ensure(keyconf, "Grease Pencil Stroke Sculpt (Randomize)", 0, 0);
- keymap->poll = gp_stroke_sculptmode_randomize_poll;
+ keymap->poll = gpencil_stroke_sculptmode_randomize_poll;
}
/* keys for sculpt with a clone brush */
static void ed_keymap_gpencil_sculptpainting_clone(wmKeyConfig *keyconf)
{
wmKeyMap *keymap = WM_keymap_ensure(keyconf, "Grease Pencil Stroke Sculpt (Clone)", 0, 0);
- keymap->poll = gp_stroke_sculptmode_clone_poll;
+ keymap->poll = gpencil_stroke_sculptmode_clone_poll;
}
/* keys for weight with a draw brush */
static void ed_keymap_gpencil_weightpainting_draw(wmKeyConfig *keyconf)
{
wmKeyMap *keymap = WM_keymap_ensure(keyconf, "Grease Pencil Stroke Weight (Draw)", 0, 0);
- keymap->poll = gp_stroke_weightmode_draw_poll;
+ keymap->poll = gpencil_stroke_weightmode_draw_poll;
}
/* ==================== */
@@ -603,6 +603,7 @@ void ED_operatortypes_gpencil(void)
WM_operatortype_append(GPENCIL_OT_frame_clean_loose);
WM_operatortype_append(GPENCIL_OT_convert);
+ WM_operatortype_append(GPENCIL_OT_bake_mesh_animation);
WM_operatortype_append(GPENCIL_OT_image_to_grease_pencil);
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index a9eb94498ad..95133244dfb 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -272,7 +272,7 @@ typedef struct tGPsdata {
/* minimum length of new segment before new point can be added */
#define MIN_EUCLIDEAN_PX (U.gp_euclideandist)
-static void gp_update_cache(bGPdata *gpd)
+static void gpencil_update_cache(bGPdata *gpd)
{
if (gpd) {
DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
@@ -280,19 +280,19 @@ static void gp_update_cache(bGPdata *gpd)
}
}
-static void gp_stroke_added_enable(tGPsdata *p)
+static void gpencil_stroke_added_enable(tGPsdata *p)
{
BLI_assert(p->gpf->strokes.last != NULL);
p->flags |= GP_PAINTFLAG_STROKEADDED;
/* drawing batch cache is dirty now */
- gp_update_cache(p->gpd);
+ gpencil_update_cache(p->gpd);
}
/* ------ */
/* Forward defines for some functions... */
-static void gp_session_validatebuffer(tGPsdata *p);
+static void gpencil_session_validatebuffer(tGPsdata *p);
/* ******************************************* */
/* Context Wrangling... */
@@ -352,7 +352,7 @@ static bool gpencil_project_check(tGPsdata *p)
/* Utilities --------------------------------- */
/* get the reference point for stroke-point conversions */
-static void gp_get_3d_reference(tGPsdata *p, float vec[3])
+static void gpencil_get_3d_reference(tGPsdata *p, float vec[3])
{
Object *ob = NULL;
if (p->ownerPtr.type == &RNA_Object) {
@@ -363,7 +363,7 @@ static void gp_get_3d_reference(tGPsdata *p, float vec[3])
/* Stroke Editing ---------------------------- */
/* check if the current mouse position is suitable for adding a new point */
-static bool gp_stroke_filtermval(tGPsdata *p, const float mval[2], float mvalo[2])
+static bool gpencil_stroke_filtermval(tGPsdata *p, const float mval[2], float mvalo[2])
{
Brush *brush = p->brush;
int dx = (int)fabsf(mval[0] - mvalo[0]);
@@ -410,7 +410,7 @@ static bool gp_stroke_filtermval(tGPsdata *p, const float mval[2], float mvalo[2
}
/* reproject stroke to plane locked to axis in 3d cursor location */
-static void gp_reproject_toplane(tGPsdata *p, bGPDstroke *gps)
+static void gpencil_reproject_toplane(tGPsdata *p, bGPDstroke *gps)
{
bGPdata *gpd = p->gpd;
Object *obact = (Object *)p->ownerPtr.data;
@@ -430,13 +430,15 @@ static void gp_reproject_toplane(tGPsdata *p, bGPDstroke *gps)
}
/* get drawing origin */
- gp_get_3d_reference(p, origin);
- ED_gp_project_stroke_to_plane(p->scene, obact, rv3d, gps, origin, p->lock_axis - 1);
+ gpencil_get_3d_reference(p, origin);
+ ED_gpencil_project_stroke_to_plane(p->scene, obact, rv3d, gps, origin, p->lock_axis - 1);
}
/* convert screen-coordinates to buffer-coordinates */
-/* XXX this method needs a total overhaul! */
-static void gp_stroke_convertcoords(tGPsdata *p, const float mval[2], float out[3], float *depth)
+static void gpencil_stroke_convertcoords(tGPsdata *p,
+ const float mval[2],
+ float out[3],
+ float *depth)
{
bGPdata *gpd = p->gpd;
@@ -476,7 +478,7 @@ static void gp_stroke_convertcoords(tGPsdata *p, const float mval[2], float out[
* 3D-coordinates using the 3D-cursor as reference. In general, this
* works OK, but it could of course be improved. */
- gp_get_3d_reference(p, rvec);
+ gpencil_get_3d_reference(p, rvec);
zfac = ED_view3d_calc_zfac(p->region->regiondata, rvec, NULL);
if (ED_view3d_project_float_global(p->region, rvec, mval_prj, V3D_PROJ_TEST_NOP) ==
@@ -492,7 +494,7 @@ static void gp_stroke_convertcoords(tGPsdata *p, const float mval[2], float out[
}
/* Apply jitter to stroke point. */
-static void gp_brush_jitter(bGPdata *gpd, tGPspoint *pt, const float amplitude)
+static void gpencil_brush_jitter(bGPdata *gpd, tGPspoint *pt, const float amplitude)
{
const float axis[2] = {0.0f, 1.0f};
/* Jitter is applied perpendicular to the mouse movement vector (2D space). */
@@ -513,8 +515,8 @@ static void gp_brush_jitter(bGPdata *gpd, tGPspoint *pt, const float amplitude)
}
}
-/* apply pressure change depending of the angle of the stroke to simulate a pen with shape */
-static void gp_brush_angle(bGPdata *gpd, Brush *brush, tGPspoint *pt, const float mval[2])
+/* Apply pressure change depending of the angle of the stroke to simulate a pen with shape */
+static void gpencil_brush_angle(bGPdata *gpd, Brush *brush, tGPspoint *pt, const float mval[2])
{
float mvec[2];
float sen = brush->gpencil_settings->draw_angle_factor; /* sensitivity */
@@ -551,16 +553,17 @@ static void gp_brush_angle(bGPdata *gpd, Brush *brush, tGPspoint *pt, const floa
}
}
-/* Apply smooth to buffer while drawing
+/**
+ * Apply smooth to buffer while drawing
* to smooth point C, use 2 before (A, B) and current point (D):
*
- * A----B-----C------D
+ * `A----B-----C------D`
*
* \param p: Temp data
* \param inf: Influence factor
* \param idx: Index of the last point (need minimum 3 points in the array)
*/
-static void gp_smooth_buffer(tGPsdata *p, float inf, int idx)
+static void gpencil_smooth_buffer(tGPsdata *p, float inf, int idx)
{
bGPdata *gpd = p->gpd;
GP_Sculpt_Guide *guide = &p->scene->toolsettings->gp_sculpt.guide;
@@ -624,7 +627,7 @@ static void gp_smooth_buffer(tGPsdata *p, float inf, int idx)
}
/* Helper: Apply smooth to segment from Index to Index */
-static void gp_smooth_segment(bGPdata *gpd, const float inf, int from_idx, int to_idx)
+static void gpencil_smooth_segment(bGPdata *gpd, const float inf, int from_idx, int to_idx)
{
const short num_points = to_idx - from_idx;
/* Do nothing if not enough points to smooth out */
@@ -691,12 +694,12 @@ static void gp_smooth_segment(bGPdata *gpd, const float inf, int from_idx, int t
}
}
-static void gp_apply_randomness(tGPsdata *p,
- BrushGpencilSettings *brush_settings,
- tGPspoint *pt,
- const bool press,
- const bool strength,
- const bool uv)
+static void gpencil_apply_randomness(tGPsdata *p,
+ BrushGpencilSettings *brush_settings,
+ tGPspoint *pt,
+ const bool press,
+ const bool strength,
+ const bool uv)
{
bGPdata *gpd = p->gpd;
GpRandomSettings random_settings = p->random_settings;
@@ -764,7 +767,10 @@ static void gp_apply_randomness(tGPsdata *p,
}
/* add current stroke-point to buffer (returns whether point was successfully added) */
-static short gp_stroke_addpoint(tGPsdata *p, const float mval[2], float pressure, double curtime)
+static short gpencil_stroke_addpoint(tGPsdata *p,
+ const float mval[2],
+ float pressure,
+ double curtime)
{
bGPdata *gpd = p->gpd;
Brush *brush = p->brush;
@@ -860,16 +866,16 @@ static short gp_stroke_addpoint(tGPsdata *p, const float mval[2], float pressure
/* FIXME the +2 means minimum jitter is 4 which is a bit strange for UX. */
const float exp_factor = brush_settings->draw_jitter + 2.0f;
const float fac = rand * square_f(exp_factor) * jitpress;
- gp_brush_jitter(gpd, pt, fac);
+ gpencil_brush_jitter(gpd, pt, fac);
}
/* Apply other randomness. */
- gp_apply_randomness(p, brush_settings, pt, true, true, true);
+ gpencil_apply_randomness(p, brush_settings, pt, true, true, true);
}
/* apply angle of stroke to brush size */
if (brush_settings->draw_angle_factor != 0.0f) {
- gp_brush_angle(gpd, brush, pt, mval);
+ gpencil_brush_angle(gpd, brush, pt, mval);
}
/* point time */
@@ -882,14 +888,14 @@ static short gp_stroke_addpoint(tGPsdata *p, const float mval[2], float pressure
/* get origin to reproject point */
float origin[3];
- gp_get_3d_reference(p, origin);
+ gpencil_get_3d_reference(p, origin);
/* reproject current */
ED_gpencil_tpoint_to_point(p->region, origin, pt, &spt);
- ED_gp_project_point_to_plane(p->scene, obact, rv3d, origin, p->lock_axis - 1, &spt);
+ ED_gpencil_project_point_to_plane(p->scene, obact, rv3d, origin, p->lock_axis - 1, &spt);
/* reproject previous */
ED_gpencil_tpoint_to_point(p->region, origin, ptb, &spt2);
- ED_gp_project_point_to_plane(p->scene, obact, rv3d, origin, p->lock_axis - 1, &spt2);
+ ED_gpencil_project_point_to_plane(p->scene, obact, rv3d, origin, p->lock_axis - 1, &spt2);
p->totpixlen += len_v3v3(&spt.x, &spt2.x);
pt->uv_fac = p->totpixlen;
}
@@ -904,9 +910,9 @@ static short gp_stroke_addpoint(tGPsdata *p, const float mval[2], float pressure
/* Smooth while drawing previous points with a reduction factor for previous. */
if (brush->gpencil_settings->active_smooth > 0.0f) {
for (int s = 0; s < 3; s++) {
- gp_smooth_buffer(p,
- brush->gpencil_settings->active_smooth * ((3.0f - s) / 3.0f),
- gpd->runtime.sbuffer_used - s);
+ gpencil_smooth_buffer(p,
+ brush->gpencil_settings->active_smooth * ((3.0f - s) / 3.0f),
+ gpd->runtime.sbuffer_used - s);
}
}
@@ -920,7 +926,7 @@ static short gp_stroke_addpoint(tGPsdata *p, const float mval[2], float pressure
}
/* make a new stroke from the buffer data */
-static void gp_stroke_newfrombuffer(tGPsdata *p)
+static void gpencil_stroke_newfrombuffer(tGPsdata *p)
{
bGPdata *gpd = p->gpd;
bGPDlayer *gpl = p->gpl;
@@ -1000,7 +1006,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
gps->dvert = NULL;
/* drawing batch cache is dirty now */
- gp_update_cache(p->gpd);
+ gpencil_update_cache(p->gpd);
/* set pointer to first non-initialized point */
pt = gps->points + (gps->totpoints - totelem);
if (gps->dvert != NULL) {
@@ -1018,7 +1024,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
ptc = gpd->runtime.sbuffer;
/* convert screen-coordinates to appropriate coordinates (and store them) */
- gp_stroke_convertcoords(p, &ptc->x, &pt->x, NULL);
+ gpencil_stroke_convertcoords(p, &ptc->x, &pt->x, NULL);
/* copy pressure and time */
pt->pressure = ptc->pressure;
pt->strength = ptc->strength;
@@ -1052,7 +1058,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
ptc = ((tGPspoint *)gpd->runtime.sbuffer) + (gpd->runtime.sbuffer_used - 1);
/* convert screen-coordinates to appropriate coordinates (and store them) */
- gp_stroke_convertcoords(p, &ptc->x, &pt->x, NULL);
+ gpencil_stroke_convertcoords(p, &ptc->x, &pt->x, NULL);
/* copy pressure and time */
pt->pressure = ptc->pressure;
pt->strength = ptc->strength;
@@ -1077,11 +1083,11 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
}
/* reproject to plane (only in 3d space) */
- gp_reproject_toplane(p, gps);
+ gpencil_reproject_toplane(p, gps);
pt = gps->points;
for (i = 0; i < gps->totpoints; i++, pt++) {
/* if parented change position relative to parent object */
- gp_apply_parent_point(depsgraph, obact, gpl, pt);
+ gpencil_apply_parent_point(depsgraph, obact, gpl, pt);
}
/* if camera view, reproject flat to view to avoid perspective effect */
@@ -1172,7 +1178,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
for (i = 0, ptc = gpd->runtime.sbuffer; i < gpd->runtime.sbuffer_used && ptc;
i++, ptc++, pt++) {
/* convert screen-coordinates to appropriate coordinates (and store them) */
- gp_stroke_convertcoords(p, &ptc->x, &pt->x, depth_arr ? depth_arr + i : NULL);
+ gpencil_stroke_convertcoords(p, &ptc->x, &pt->x, depth_arr ? depth_arr + i : NULL);
/* copy pressure and time */
pt->pressure = ptc->pressure;
@@ -1194,7 +1200,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
/* subdivide and smooth the stroke */
if ((brush->gpencil_settings->flag & GP_BRUSH_GROUP_SETTINGS) && (subdivide > 0)) {
- gp_subdivide_stroke(gps, subdivide);
+ gpencil_subdivide_stroke(gps, subdivide);
}
/* Smooth stroke after subdiv - only if there's something to do for each iteration,
@@ -1229,9 +1235,9 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
}
/* reproject to plane (only in 3d space) */
- gp_reproject_toplane(p, gps);
+ gpencil_reproject_toplane(p, gps);
/* change position relative to parent object */
- gp_apply_parent(depsgraph, obact, gpl, gps);
+ gpencil_apply_parent(depsgraph, obact, gpl, gps);
/* if camera view, reproject flat to view to avoid perspective effect */
if (is_camera) {
ED_gpencil_project_stroke_to_view(p->C, p->gpl, gps);
@@ -1284,12 +1290,14 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
/* Calc geometry data. */
BKE_gpencil_stroke_geometry_update(gps);
- gp_stroke_added_enable(p);
+ gpencil_stroke_added_enable(p);
}
/* --- 'Eraser' for 'Paint' Tool ------ */
-/* which which point is infront (result should only be used for comparison) */
+/**
+ * Which which point is in front (result should only be used for comparison).
+ */
static float view3d_point_depth(const RegionView3D *rv3d, const float co[3])
{
if (rv3d->is_persp) {
@@ -1301,10 +1309,10 @@ static float view3d_point_depth(const RegionView3D *rv3d, const float co[3])
}
/* only erase stroke points that are visible */
-static bool gp_stroke_eraser_is_occluded(tGPsdata *p,
- const bGPDspoint *pt,
- const int x,
- const int y)
+static bool gpencil_stroke_eraser_is_occluded(tGPsdata *p,
+ const bGPDspoint *pt,
+ const int x,
+ const int y)
{
Object *obact = (Object *)p->ownerPtr.data;
Brush *brush = p->brush;
@@ -1346,10 +1354,10 @@ static bool gp_stroke_eraser_is_occluded(tGPsdata *p,
}
/* apply a falloff effect to brush strength, based on distance */
-static float gp_stroke_eraser_calc_influence(tGPsdata *p,
- const float mval[2],
- const int radius,
- const int co[2])
+static float gpencil_stroke_eraser_calc_influence(tGPsdata *p,
+ const float mval[2],
+ const int radius,
+ const int co[2])
{
Brush *brush = p->brush;
/* Linear Falloff... */
@@ -1373,7 +1381,7 @@ static float gp_stroke_eraser_calc_influence(tGPsdata *p,
}
/* helper to free a stroke */
-static void gp_free_stroke(bGPdata *gpd, bGPDframe *gpf, bGPDstroke *gps)
+static void gpencil_free_stroke(bGPdata *gpd, bGPDframe *gpf, bGPDstroke *gps)
{
if (gps->points) {
MEM_freeN(gps->points);
@@ -1388,7 +1396,7 @@ static void gp_free_stroke(bGPdata *gpd, bGPDframe *gpf, bGPDstroke *gps)
MEM_freeN(gps->triangles);
}
BLI_freelinkN(&gpf->strokes, gps);
- gp_update_cache(gpd);
+ gpencil_update_cache(gpd);
}
/**
@@ -1396,7 +1404,7 @@ static void gp_free_stroke(bGPdata *gpd, bGPDframe *gpf, bGPDstroke *gps)
* to avoid that segments gets the end points rounded.
* The round caps breaks the artistic effect.
*/
-static void gp_stroke_soft_refine(bGPDstroke *gps)
+static void gpencil_stroke_soft_refine(bGPDstroke *gps)
{
bGPDspoint *pt = NULL;
bGPDspoint *pt2 = NULL;
@@ -1431,12 +1439,12 @@ static void gp_stroke_soft_refine(bGPDstroke *gps)
}
/* eraser tool - evaluation per stroke */
-static void gp_stroke_eraser_dostroke(tGPsdata *p,
- bGPDframe *gpf,
- bGPDstroke *gps,
- const float mval[2],
- const int radius,
- const rcti *rect)
+static void gpencil_stroke_eraser_dostroke(tGPsdata *p,
+ bGPDframe *gpf,
+ bGPDstroke *gps,
+ const float mval[2],
+ const int radius,
+ const rcti *rect)
{
Brush *eraser = p->eraser;
bGPDspoint *pt0, *pt1, *pt2;
@@ -1449,20 +1457,20 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
if (gps->totpoints == 0) {
/* just free stroke */
- gp_free_stroke(p->gpd, gpf, gps);
+ gpencil_free_stroke(p->gpd, gpf, gps);
}
else if (gps->totpoints == 1) {
/* only process if it hasn't been masked out... */
if (!(p->flags & GP_PAINTFLAG_SELECTMASK) || (gps->points->flag & GP_SPOINT_SELECT)) {
bGPDspoint pt_temp;
- gp_point_to_parent_space(gps->points, p->diff_mat, &pt_temp);
- gp_point_to_xy(&p->gsc, gps, &pt_temp, &pc1[0], &pc1[1]);
+ gpencil_point_to_parent_space(gps->points, p->diff_mat, &pt_temp);
+ gpencil_point_to_xy(&p->gsc, gps, &pt_temp, &pc1[0], &pc1[1]);
/* do boundbox check first */
if ((!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1])) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) {
/* only check if point is inside */
if (len_v2v2_int(mval_i, pc1) <= radius) {
/* free stroke */
- gp_free_stroke(p->gpd, gpf, gps);
+ gpencil_free_stroke(p->gpd, gpf, gps);
}
}
}
@@ -1479,15 +1487,15 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
/* get points to work with */
pt1 = gps->points + i;
bGPDspoint npt;
- gp_point_to_parent_space(pt1, p->diff_mat, &npt);
- gp_point_to_xy(&p->gsc, gps, &npt, &pc1[0], &pc1[1]);
+ gpencil_point_to_parent_space(pt1, p->diff_mat, &npt);
+ gpencil_point_to_xy(&p->gsc, gps, &npt, &pc1[0], &pc1[1]);
/* do boundbox check first */
if ((!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1])) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) {
/* only check if point is inside */
if (len_v2v2_int(mval_i, pc1) <= radius) {
/* free stroke */
- gp_free_stroke(p->gpd, gpf, gps);
+ gpencil_free_stroke(p->gpd, gpf, gps);
return;
}
}
@@ -1531,19 +1539,19 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
bGPDspoint npt;
if (pt0) {
- gp_point_to_parent_space(pt0, p->diff_mat, &npt);
- gp_point_to_xy(&p->gsc, gps, &npt, &pc0[0], &pc0[1]);
+ gpencil_point_to_parent_space(pt0, p->diff_mat, &npt);
+ gpencil_point_to_xy(&p->gsc, gps, &npt, &pc0[0], &pc0[1]);
}
else {
/* avoid null values */
copy_v2_v2_int(pc0, pc1);
}
- gp_point_to_parent_space(pt1, p->diff_mat, &npt);
- gp_point_to_xy(&p->gsc, gps, &npt, &pc1[0], &pc1[1]);
+ gpencil_point_to_parent_space(pt1, p->diff_mat, &npt);
+ gpencil_point_to_xy(&p->gsc, gps, &npt, &pc1[0], &pc1[1]);
- gp_point_to_parent_space(pt2, p->diff_mat, &npt);
- gp_point_to_xy(&p->gsc, gps, &npt, &pc2[0], &pc2[1]);
+ gpencil_point_to_parent_space(pt2, p->diff_mat, &npt);
+ gpencil_point_to_xy(&p->gsc, gps, &npt, &pc2[0], &pc2[1]);
/* Check that point segment of the boundbox of the eraser stroke */
if (((!ELEM(V2D_IS_CLIPPED, pc0[0], pc0[1])) && BLI_rcti_isect_pt(rect, pc0[0], pc0[1])) ||
@@ -1553,10 +1561,10 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
* eraser region (either within stroke painted, or on its lines)
* - this assumes that linewidth is irrelevant
*/
- if (gp_stroke_inside_circle(mval, radius, pc0[0], pc0[1], pc2[0], pc2[1])) {
- if ((gp_stroke_eraser_is_occluded(p, pt0, pc0[0], pc0[1]) == false) ||
- (gp_stroke_eraser_is_occluded(p, pt1, pc1[0], pc1[1]) == false) ||
- (gp_stroke_eraser_is_occluded(p, pt2, pc2[0], pc2[1]) == false)) {
+ if (gpencil_stroke_inside_circle(mval, radius, pc0[0], pc0[1], pc2[0], pc2[1])) {
+ if ((gpencil_stroke_eraser_is_occluded(p, pt0, pc0[0], pc0[1]) == false) ||
+ (gpencil_stroke_eraser_is_occluded(p, pt1, pc1[0], pc1[1]) == false) ||
+ (gpencil_stroke_eraser_is_occluded(p, pt2, pc2[0], pc2[1]) == false)) {
/* Point is affected: */
/* Adjust thickness
* - Influence of eraser falls off with distance from the middle of the eraser
@@ -1570,18 +1578,18 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
float influence = 0.0f;
if (pt0) {
- influence = gp_stroke_eraser_calc_influence(p, mval, radius, pc0);
+ influence = gpencil_stroke_eraser_calc_influence(p, mval, radius, pc0);
pt0->strength -= influence * strength * f_strength * 0.5f;
CLAMP_MIN(pt0->strength, 0.0f);
pt0->pressure -= influence * strength * f_thickness * 0.5f;
}
- influence = gp_stroke_eraser_calc_influence(p, mval, radius, pc1);
+ influence = gpencil_stroke_eraser_calc_influence(p, mval, radius, pc1);
pt1->strength -= influence * strength * f_strength;
CLAMP_MIN(pt1->strength, 0.0f);
pt1->pressure -= influence * strength * f_thickness;
- influence = gp_stroke_eraser_calc_influence(p, mval, radius, pc2);
+ influence = gpencil_stroke_eraser_calc_influence(p, mval, radius, pc2);
pt2->strength -= influence * strength * f_strength * 0.5f;
CLAMP_MIN(pt2->strength, 0.0f);
pt2->pressure -= influence * strength * f_thickness * 0.5f;
@@ -1604,9 +1612,10 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
}
}
else {
- pt1->pressure -= gp_stroke_eraser_calc_influence(p, mval, radius, pc1) * strength;
- pt2->pressure -= gp_stroke_eraser_calc_influence(p, mval, radius, pc2) * strength *
- 0.5f;
+ pt1->pressure -= gpencil_stroke_eraser_calc_influence(p, mval, radius, pc1) *
+ strength;
+ pt2->pressure -= gpencil_stroke_eraser_calc_influence(p, mval, radius, pc2) *
+ strength * 0.5f;
}
/* 2) Tag any point with overly low influence for removal in the next pass */
@@ -1630,17 +1639,17 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
/* if soft eraser, must analyze points to be sure the stroke ends
* don't get rounded */
if (eraser->gpencil_settings->eraser_mode == GP_BRUSH_ERASER_SOFT) {
- gp_stroke_soft_refine(gps);
+ gpencil_stroke_soft_refine(gps);
}
- gp_stroke_delete_tagged_points(gpf, gps, gps->next, GP_SPOINT_TAG, false, 0);
+ gpencil_stroke_delete_tagged_points(gpf, gps, gps->next, GP_SPOINT_TAG, false, 0);
}
- gp_update_cache(p->gpd);
+ gpencil_update_cache(p->gpd);
}
}
/* erase strokes which fall under the eraser strokes */
-static void gp_stroke_doeraser(tGPsdata *p)
+static void gpencil_stroke_doeraser(tGPsdata *p)
{
rcti rect;
Brush *brush = p->brush;
@@ -1710,7 +1719,7 @@ static void gp_stroke_doeraser(tGPsdata *p)
* (e.g. 2D space strokes in the 3D view, if the same datablock is shared)
*/
if (ED_gpencil_stroke_can_use_direct(p->area, gps)) {
- gp_stroke_eraser_dostroke(p, gpf, gps, p->mval, calc_radius, &rect);
+ gpencil_stroke_eraser_dostroke(p, gpf, gps, p->mval, calc_radius, &rect);
}
}
}
@@ -1720,7 +1729,7 @@ static void gp_stroke_doeraser(tGPsdata *p)
/* Sketching Operator */
/* clear the session buffers (call this before AND after a paint operation) */
-static void gp_session_validatebuffer(tGPsdata *p)
+static void gpencil_session_validatebuffer(tGPsdata *p)
{
bGPdata *gpd = p->gpd;
Brush *brush = p->brush;
@@ -1742,7 +1751,7 @@ static void gp_session_validatebuffer(tGPsdata *p)
}
/* helper to get default eraser and create one if no eraser brush */
-static Brush *gp_get_default_eraser(Main *bmain, ToolSettings *ts)
+static Brush *gpencil_get_default_eraser(Main *bmain, ToolSettings *ts)
{
Brush *brush_dft = NULL;
Paint *paint = &ts->gp_paint->paint;
@@ -1784,7 +1793,7 @@ static Brush *gp_get_default_eraser(Main *bmain, ToolSettings *ts)
}
/* helper to set default eraser and disable others */
-static void gp_set_default_eraser(Main *bmain, Brush *brush_dft)
+static void gpencil_set_default_eraser(Main *bmain, Brush *brush_dft)
{
if (brush_dft == NULL) {
return;
@@ -1803,7 +1812,7 @@ static void gp_set_default_eraser(Main *bmain, Brush *brush_dft)
}
/* initialize a drawing brush */
-static void gp_init_drawing_brush(bContext *C, tGPsdata *p)
+static void gpencil_init_drawing_brush(bContext *C, tGPsdata *p)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
@@ -1831,13 +1840,13 @@ static void gp_init_drawing_brush(bContext *C, tGPsdata *p)
/* assign to temp tGPsdata */
p->brush = paint->brush;
if (paint->brush->gpencil_tool != GPAINT_TOOL_ERASE) {
- p->eraser = gp_get_default_eraser(p->bmain, ts);
+ p->eraser = gpencil_get_default_eraser(p->bmain, ts);
}
else {
p->eraser = paint->brush;
}
/* set new eraser as default */
- gp_set_default_eraser(p->bmain, p->eraser);
+ gpencil_set_default_eraser(p->bmain, p->eraser);
/* use radius of eraser */
p->radius = (short)p->eraser->size;
@@ -1849,7 +1858,7 @@ static void gp_init_drawing_brush(bContext *C, tGPsdata *p)
}
/* initialize a paint brush and a default color if not exist */
-static void gp_init_colors(tGPsdata *p)
+static void gpencil_init_colors(tGPsdata *p)
{
bGPdata *gpd = p->gpd;
Brush *brush = p->brush;
@@ -1862,7 +1871,7 @@ static void gp_init_colors(tGPsdata *p)
}
/* (re)init new painting data */
-static bool gp_session_initdata(bContext *C, wmOperator *op, tGPsdata *p)
+static bool gpencil_session_initdata(bContext *C, wmOperator *op, tGPsdata *p)
{
Main *bmain = CTX_data_main(C);
bGPdata **gpd_ptr = NULL;
@@ -1959,15 +1968,15 @@ static bool gp_session_initdata(bContext *C, wmOperator *op, tGPsdata *p)
}
/* clear out buffer (stored in gp-data), in case something contaminated it */
- gp_session_validatebuffer(p);
+ gpencil_session_validatebuffer(p);
/* set brush and create a new one if null */
- gp_init_drawing_brush(C, p);
+ gpencil_init_drawing_brush(C, p);
/* setup active color */
/* region where paint was originated */
int totcol = p->ob->totcol;
- gp_init_colors(p);
+ gpencil_init_colors(p);
/* check whether the material was newly added */
if (totcol != p->ob->totcol) {
@@ -1987,7 +1996,7 @@ static bool gp_session_initdata(bContext *C, wmOperator *op, tGPsdata *p)
}
/* init new painting session */
-static tGPsdata *gp_session_initpaint(bContext *C, wmOperator *op)
+static tGPsdata *gpencil_session_initpaint(bContext *C, wmOperator *op)
{
tGPsdata *p = NULL;
@@ -1997,7 +2006,7 @@ static tGPsdata *gp_session_initpaint(bContext *C, wmOperator *op)
/* Try to initialize context data
* WARNING: This may not always succeed (e.g. using GP in an annotation-only context)
*/
- if (gp_session_initdata(C, op, p) == 0) {
+ if (gpencil_session_initdata(C, op, p) == 0) {
/* Invalid state - Exit
* NOTE: It should be safe to just free the data, since failing context checks should
* only happen when no data has been allocated.
@@ -2016,7 +2025,7 @@ static tGPsdata *gp_session_initpaint(bContext *C, wmOperator *op)
}
/* cleanup after a painting session */
-static void gp_session_cleanup(tGPsdata *p)
+static void gpencil_session_cleanup(tGPsdata *p)
{
bGPdata *gpd = (p) ? p->gpd : NULL;
@@ -2038,7 +2047,7 @@ static void gp_session_cleanup(tGPsdata *p)
p->inittime = 0.0;
}
-static void gp_session_free(tGPsdata *p)
+static void gpencil_session_free(tGPsdata *p)
{
if (p->rng != NULL) {
BLI_rng_free(p->rng);
@@ -2048,7 +2057,9 @@ static void gp_session_free(tGPsdata *p)
}
/* init new stroke */
-static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, Depsgraph *depsgraph)
+static void gpencil_paint_initstroke(tGPsdata *p,
+ eGPencil_PaintModes paintmode,
+ Depsgraph *depsgraph)
{
Scene *scene = p->scene;
ToolSettings *ts = scene->toolsettings;
@@ -2209,12 +2220,12 @@ static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, Deps
gpd_eval->runtime.sbuffer_brush = p->gpd->runtime.sbuffer_brush;
}
else {
- gp_update_cache(p->gpd);
+ gpencil_update_cache(p->gpd);
}
}
/* finish off a stroke (clears buffer, but doesn't finish the paint operation) */
-static void gp_paint_strokeend(tGPsdata *p)
+static void gpencil_paint_strokeend(tGPsdata *p)
{
ToolSettings *ts = p->scene->toolsettings;
/* for surface sketching, need to set the right OpenGL context stuff so that
@@ -2232,22 +2243,22 @@ static void gp_paint_strokeend(tGPsdata *p)
/* check if doing eraser or not */
if ((p->gpd->runtime.sbuffer_sflag & GP_STROKE_ERASER) == 0) {
/* transfer stroke to frame */
- gp_stroke_newfrombuffer(p);
+ gpencil_stroke_newfrombuffer(p);
}
/* clean up buffer now */
- gp_session_validatebuffer(p);
+ gpencil_session_validatebuffer(p);
}
/* finish off stroke painting operation */
-static void gp_paint_cleanup(tGPsdata *p)
+static void gpencil_paint_cleanup(tGPsdata *p)
{
/* p->gpd==NULL happens when stroke failed to initialize,
* for example when GP is hidden in current space (sergey)
*/
if (p->gpd) {
/* finish off a stroke */
- gp_paint_strokeend(p);
+ gpencil_paint_strokeend(p);
}
/* "unlock" frame */
@@ -2357,19 +2368,19 @@ static void gpencil_draw_exit(bContext *C, wmOperator *op)
else {
/* drawing batch cache is dirty now */
bGPdata *gpd = CTX_data_gpencil_data(C);
- gp_update_cache(gpd);
+ gpencil_update_cache(gpd);
}
/* clear undo stack */
gpencil_undo_finish();
/* cleanup */
- gp_paint_cleanup(p);
- gp_session_cleanup(p);
+ gpencil_paint_cleanup(p);
+ gpencil_session_cleanup(p);
ED_gpencil_toggle_brush_cursor(C, true, NULL);
/* finally, free the temp data */
- gp_session_free(p);
+ gpencil_session_free(p);
p = NULL;
}
@@ -2399,7 +2410,7 @@ static int gpencil_draw_init(bContext *C, wmOperator *op, const wmEvent *event)
}
/* check context */
- p = op->customdata = gp_session_initpaint(C, op);
+ p = op->customdata = gpencil_session_initpaint(C, op);
if ((p == NULL) || (p->status == GP_STATUS_ERROR)) {
/* something wasn't set correctly in context */
gpencil_draw_exit(C, op);
@@ -2407,7 +2418,7 @@ static int gpencil_draw_init(bContext *C, wmOperator *op, const wmEvent *event)
}
/* init painting data */
- gp_paint_initstroke(p, paintmode, CTX_data_ensure_evaluated_depsgraph(C));
+ gpencil_paint_initstroke(p, paintmode, CTX_data_ensure_evaluated_depsgraph(C));
if (p->status == GP_STATUS_ERROR) {
gpencil_draw_exit(C, op);
return 0;
@@ -2493,10 +2504,10 @@ static void gpencil_draw_status_indicators(bContext *C, tGPsdata *p)
/* ------------------------------- */
/* Helper to rotate point around origin */
-static void gp_rotate_v2_v2v2fl(float v[2],
- const float p[2],
- const float origin[2],
- const float angle)
+static void gpencil_rotate_v2_v2v2fl(float v[2],
+ const float p[2],
+ const float origin[2],
+ const float angle)
{
float pt[2];
float r[2];
@@ -2506,7 +2517,7 @@ static void gp_rotate_v2_v2v2fl(float v[2],
}
/* Helper to snap value to grid */
-static float gp_snap_to_grid_fl(float v, const float offset, const float spacing)
+static float gpencil_snap_to_grid_fl(float v, const float offset, const float spacing)
{
if (spacing > 0.0f) {
v -= spacing * 0.5f;
@@ -2521,25 +2532,25 @@ static float gp_snap_to_grid_fl(float v, const float offset, const float spacing
}
/* Helper to snap value to grid */
-static void gp_snap_to_rotated_grid_fl(float v[2],
- const float origin[2],
- const float spacing,
- const float angle)
+static void gpencil_snap_to_rotated_grid_fl(float v[2],
+ const float origin[2],
+ const float spacing,
+ const float angle)
{
- gp_rotate_v2_v2v2fl(v, v, origin, -angle);
- v[1] = gp_snap_to_grid_fl(v[1], origin[1], spacing);
- gp_rotate_v2_v2v2fl(v, v, origin, angle);
+ gpencil_rotate_v2_v2v2fl(v, v, origin, -angle);
+ v[1] = gpencil_snap_to_grid_fl(v[1], origin[1], spacing);
+ gpencil_rotate_v2_v2v2fl(v, v, origin, angle);
}
/* get reference point - screen coords to buffer coords */
-static void gp_origin_set(wmOperator *op, const int mval[2])
+static void gpencil_origin_set(wmOperator *op, const int mval[2])
{
tGPsdata *p = op->customdata;
GP_Sculpt_Guide *guide = &p->scene->toolsettings->gp_sculpt.guide;
float origin[2];
float point[3];
copy_v2fl_v2i(origin, mval);
- gp_stroke_convertcoords(p, origin, point, NULL);
+ gpencil_stroke_convertcoords(p, origin, point, NULL);
if (guide->reference_point == GP_GUIDE_REF_CUSTOM) {
copy_v3_v3(guide->location, point);
}
@@ -2549,7 +2560,7 @@ static void gp_origin_set(wmOperator *op, const int mval[2])
}
/* get reference point - buffer coords to screen coords */
-static void gp_origin_get(tGPsdata *p, float origin[2])
+static void gpencil_origin_get(tGPsdata *p, float origin[2])
{
GP_Sculpt_Guide *guide = &p->scene->toolsettings->gp_sculpt.guide;
float location[3];
@@ -2563,7 +2574,7 @@ static void gp_origin_get(tGPsdata *p, float origin[2])
copy_v3_v3(location, p->scene->cursor.location);
}
GP_SpaceConversion *gsc = &p->gsc;
- gp_point_3d_to_xy(gsc, p->gpd->runtime.sbuffer_sflag, location, origin);
+ gpencil_point_3d_to_xy(gsc, p->gpd->runtime.sbuffer_sflag, location, origin);
}
/* speed guide initial values */
@@ -2574,7 +2585,7 @@ static void gpencil_speed_guide_init(tGPsdata *p, GP_Sculpt_Guide *guide)
float scale = 1.0f;
if (rv3d->is_persp) {
float vec[3];
- gp_get_3d_reference(p, vec);
+ gpencil_get_3d_reference(p, vec);
mul_m4_v3(rv3d->persmat, vec);
scale = vec[2] * rv3d->pixsize;
}
@@ -2583,7 +2594,7 @@ static void gpencil_speed_guide_init(tGPsdata *p, GP_Sculpt_Guide *guide)
}
p->guide.spacing = guide->spacing / scale;
p->guide.half_spacing = p->guide.spacing * 0.5f;
- gp_origin_get(p, p->guide.origin);
+ gpencil_origin_get(p, p->guide.origin);
/* reference for angled snap */
copy_v2_v2(p->guide.unit, p->mvali);
@@ -2595,7 +2606,7 @@ static void gpencil_speed_guide_init(tGPsdata *p, GP_Sculpt_Guide *guide)
p->guide.origin_distance = len_v2v2(p->mvali, p->guide.origin);
if (guide->use_snapping && (guide->spacing > 0.0f)) {
- p->guide.origin_distance = gp_snap_to_grid_fl(
+ p->guide.origin_distance = gpencil_snap_to_grid_fl(
p->guide.origin_distance, 0.0f, p->guide.spacing);
}
@@ -2605,10 +2616,10 @@ static void gpencil_speed_guide_init(tGPsdata *p, GP_Sculpt_Guide *guide)
angle = p->guide.origin_angle + guide->angle;
angle = fmodf(angle + half_angle, guide->angle_snap);
angle -= half_angle;
- gp_rotate_v2_v2v2fl(p->guide.rot_point, p->mvali, p->guide.origin, -angle);
+ gpencil_rotate_v2_v2v2fl(p->guide.rot_point, p->mvali, p->guide.origin, -angle);
}
else {
- gp_rotate_v2_v2v2fl(p->guide.rot_point, p->guide.unit, p->mvali, guide->angle);
+ gpencil_rotate_v2_v2v2fl(p->guide.rot_point, p->guide.unit, p->mvali, guide->angle);
}
}
@@ -2633,14 +2644,15 @@ static void gpencil_snap_to_guide(const tGPsdata *p, const GP_Sculpt_Guide *guid
case GP_GUIDE_PARALLEL: {
closest_to_line_v2(point, point, p->mvali, p->guide.rot_point);
if (guide->use_snapping && (guide->spacing > 0.0f)) {
- gp_snap_to_rotated_grid_fl(point, p->guide.origin, p->guide.spacing, guide->angle);
+ gpencil_snap_to_rotated_grid_fl(point, p->guide.origin, p->guide.spacing, guide->angle);
}
break;
}
case GP_GUIDE_ISO: {
closest_to_line_v2(point, point, p->mvali, p->guide.rot_point);
if (guide->use_snapping && (guide->spacing > 0.0f)) {
- gp_snap_to_rotated_grid_fl(point, p->guide.origin, p->guide.spacing, p->guide.rot_angle);
+ gpencil_snap_to_rotated_grid_fl(
+ point, p->guide.origin, p->guide.spacing, p->guide.rot_angle);
}
break;
}
@@ -2648,10 +2660,10 @@ static void gpencil_snap_to_guide(const tGPsdata *p, const GP_Sculpt_Guide *guid
if (guide->use_snapping && (guide->spacing > 0.0f)) {
closest_to_line_v2(point, point, p->mvali, p->guide.rot_point);
if (p->straight == STROKE_HORIZONTAL) {
- point[1] = gp_snap_to_grid_fl(point[1], p->guide.origin[1], p->guide.spacing);
+ point[1] = gpencil_snap_to_grid_fl(point[1], p->guide.origin[1], p->guide.spacing);
}
else {
- point[0] = gp_snap_to_grid_fl(point[0], p->guide.origin[0], p->guide.spacing);
+ point[0] = gpencil_snap_to_grid_fl(point[0], p->guide.origin[0], p->guide.spacing);
}
}
else if (p->straight == STROKE_HORIZONTAL) {
@@ -2674,7 +2686,7 @@ static void gpencil_draw_apply(bContext *C, wmOperator *op, tGPsdata *p, Depsgra
/* handle drawing/erasing -> test for erasing first */
if (p->paintmode == GP_PAINTMODE_ERASER) {
/* do 'live' erasing now */
- gp_stroke_doeraser(p);
+ gpencil_stroke_doeraser(p);
/* store used values */
copy_v2_v2(p->mvalo, p->mval);
@@ -2682,7 +2694,7 @@ static void gpencil_draw_apply(bContext *C, wmOperator *op, tGPsdata *p, Depsgra
}
/* Only add current point to buffer if mouse moved
* (even though we got an event, it might be just noise). */
- else if (gp_stroke_filtermval(p, p->mval, p->mvalo)) {
+ else if (gpencil_stroke_filtermval(p, p->mval, p->mvalo)) {
/* if lazy mouse, interpolate the last and current mouse positions */
if (GPENCIL_LAZY_MODE(p->brush, p->shift)) {
@@ -2702,26 +2714,26 @@ static void gpencil_draw_apply(bContext *C, wmOperator *op, tGPsdata *p, Depsgra
}
/* try to add point */
- short ok = gp_stroke_addpoint(p, p->mval, p->pressure, p->curtime);
+ short ok = gpencil_stroke_addpoint(p, p->mval, p->pressure, p->curtime);
/* handle errors while adding point */
if ((ok == GP_STROKEADD_FULL) || (ok == GP_STROKEADD_OVERFLOW)) {
/* finish off old stroke */
- gp_paint_strokeend(p);
+ gpencil_paint_strokeend(p);
/* And start a new one!!! Else, projection errors! */
- gp_paint_initstroke(p, p->paintmode, depsgraph);
+ gpencil_paint_initstroke(p, p->paintmode, depsgraph);
/* start a new stroke, starting from previous point */
/* XXX Must manually reset inittime... */
/* XXX We only need to reuse previous point if overflow! */
if (ok == GP_STROKEADD_OVERFLOW) {
p->inittime = p->ocurtime;
- gp_stroke_addpoint(p, p->mvalo, p->opressure, p->ocurtime);
+ gpencil_stroke_addpoint(p, p->mvalo, p->opressure, p->ocurtime);
}
else {
p->inittime = p->curtime;
}
- gp_stroke_addpoint(p, p->mval, p->pressure, p->curtime);
+ gpencil_stroke_addpoint(p, p->mval, p->pressure, p->curtime);
}
else if (ok == GP_STROKEADD_INVALID) {
/* the painting operation cannot continue... */
@@ -2889,13 +2901,13 @@ static void gpencil_draw_apply_event(bContext *C,
else {
p->guide.rot_angle = DEG2RAD(90);
}
- gp_rotate_v2_v2v2fl(p->guide.rot_point, p->guide.unit, p->mvali, p->guide.rot_angle);
+ gpencil_rotate_v2_v2v2fl(p->guide.rot_point, p->guide.unit, p->mvali, p->guide.rot_angle);
}
else if (ELEM(guide->type, GP_GUIDE_GRID)) {
- gp_rotate_v2_v2v2fl(p->guide.rot_point,
- p->guide.unit,
- p->mvali,
- (p->straight == STROKE_VERTICAL) ? M_PI_2 : 0.0f);
+ gpencil_rotate_v2_v2v2fl(p->guide.rot_point,
+ p->guide.unit,
+ p->mvali,
+ (p->straight == STROKE_VERTICAL) ? M_PI_2 : 0.0f);
}
}
@@ -2968,8 +2980,8 @@ static int gpencil_draw_exec(bContext *C, wmOperator *op)
*/
if ((p->flags & GP_PAINTFLAG_FIRSTRUN) == 0) {
/* TODO: both of these ops can set error-status, but we probably don't need to worry */
- gp_paint_strokeend(p);
- gp_paint_initstroke(p, p->paintmode, depsgraph);
+ gpencil_paint_strokeend(p);
+ gpencil_paint_initstroke(p, p->paintmode, depsgraph);
}
}
@@ -3227,8 +3239,8 @@ static tGPsdata *gpencil_stroke_begin(bContext *C, wmOperator *op)
}
/* we may need to set up paint env again if we're resuming */
- if (gp_session_initdata(C, op, p)) {
- gp_paint_initstroke(p, p->paintmode, CTX_data_depsgraph_pointer(C));
+ if (gpencil_session_initdata(C, op, p)) {
+ gpencil_paint_initstroke(p, p->paintmode, CTX_data_depsgraph_pointer(C));
}
if (p->status != GP_STATUS_ERROR) {
@@ -3240,7 +3252,7 @@ static tGPsdata *gpencil_stroke_begin(bContext *C, wmOperator *op)
}
/* Apply pressure change depending of the angle of the stroke for a segment. */
-static void gp_brush_angle_segment(tGPsdata *p, tGPspoint *pt_prev, tGPspoint *pt)
+static void gpencil_brush_angle_segment(tGPsdata *p, tGPspoint *pt_prev, tGPspoint *pt)
{
Brush *brush = p->brush;
/* Sensitivity. */
@@ -3284,7 +3296,7 @@ static void gpencil_add_arc_points(tGPsdata *p, float mval[2], int segments)
/* Apply other randomness to first points. */
for (int i = 0; i < gpd->runtime.sbuffer_used; i++) {
tGPspoint *pt = &points[i];
- gp_apply_randomness(p, brush_settings, pt, false, false, true);
+ gpencil_apply_randomness(p, brush_settings, pt, false, false, true);
}
return;
}
@@ -3359,14 +3371,14 @@ static void gpencil_add_arc_points(tGPsdata *p, float mval[2], int segments)
/* Apply angle of stroke to brush size to interpolated points but slightly attenuated.. */
if (brush_settings->draw_angle_factor != 0.0f) {
- gp_brush_angle_segment(p, pt_step, pt);
+ gpencil_brush_angle_segment(p, pt_step, pt);
CLAMP(pt->pressure, pt_prev->pressure * 0.5f, 1.0f);
/* Use the previous interpolated point for next segment. */
pt_step = pt;
}
/* Apply other randomness. */
- gp_apply_randomness(p, brush_settings, pt, false, false, true);
+ gpencil_apply_randomness(p, brush_settings, pt, false, false, true);
a += step;
}
@@ -3411,7 +3423,7 @@ static void gpencil_add_guide_points(const tGPsdata *p,
for (int i = 0; i < segments; i++) {
pt = &points[idx_prev + i - 1];
- gp_rotate_v2_v2v2fl(&pt->x, start, p->guide.origin, -a);
+ gpencil_rotate_v2_v2v2fl(&pt->x, start, p->guide.origin, -a);
gpencil_snap_to_guide(p, guide, &pt->x);
a += step;
@@ -3547,7 +3559,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
/* set */
case LEFTMOUSE: {
if (ELEM(event->val, KM_RELEASE)) {
- gp_origin_set(op, event->mval);
+ gpencil_origin_set(op, event->mval);
drawmode = true;
}
break;
@@ -3750,7 +3762,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
* the 0.15 value gets a good result in Windows and Linux. */
if (!is_speed_guide && (size_after - size_before > 1)) {
for (int r = 0; r < 5; r++) {
- gp_smooth_segment(p->gpd, 0.15f, size_before - 1, size_after - 1);
+ gpencil_smooth_segment(p->gpd, 0.15f, size_before - 1, size_after - 1);
}
}
diff --git a/source/blender/editors/gpencil/gpencil_primitive.c b/source/blender/editors/gpencil/gpencil_primitive.c
index 82ae99b30be..6bb9f9628fa 100644
--- a/source/blender/editors/gpencil/gpencil_primitive.c
+++ b/source/blender/editors/gpencil/gpencil_primitive.c
@@ -111,7 +111,7 @@
/* Core/Shared Utilities */
/* clear the session buffers (call this before AND after a paint operation) */
-static void gp_session_validatebuffer(tGPDprimitive *p)
+static void gpencil_session_validatebuffer(tGPDprimitive *p)
{
bGPdata *gpd = p->gpd;
@@ -137,7 +137,7 @@ static void gp_session_validatebuffer(tGPDprimitive *p)
}
}
-static void gp_init_colors(tGPDprimitive *p)
+static void gpencil_init_colors(tGPDprimitive *p)
{
bGPdata *gpd = p->gpd;
Brush *brush = p->brush;
@@ -196,10 +196,10 @@ static void gpencil_primitive_constrain(tGPDprimitive *tgpi, bool line_mode)
}
/* Helper to rotate point around origin */
-static void gp_rotate_v2_v2v2fl(float v[2],
- const float p[2],
- const float origin[2],
- const float angle)
+static void gpencil_rotate_v2_v2v2fl(float v[2],
+ const float p[2],
+ const float origin[2],
+ const float angle)
{
float pt[2];
float r[2];
@@ -209,17 +209,17 @@ static void gp_rotate_v2_v2v2fl(float v[2],
}
/* Helper to rotate line around line center. */
-static void gp_primitive_rotate_line(
+static void gpencil_primitive_rotate_line(
float va[2], float vb[2], const float a[2], const float b[2], const float angle)
{
float midpoint[2];
mid_v2_v2v2(midpoint, a, b);
- gp_rotate_v2_v2v2fl(va, a, midpoint, angle);
- gp_rotate_v2_v2v2fl(vb, b, midpoint, angle);
+ gpencil_rotate_v2_v2v2fl(va, a, midpoint, angle);
+ gpencil_rotate_v2_v2v2fl(vb, b, midpoint, angle);
}
/* Helper to update cps */
-static void gp_primitive_update_cps(tGPDprimitive *tgpi)
+static void gpencil_primitive_update_cps(tGPDprimitive *tgpi)
{
if (!tgpi->curve) {
mid_v2_v2v2(tgpi->midpoint, tgpi->start, tgpi->end);
@@ -233,10 +233,10 @@ static void gp_primitive_update_cps(tGPDprimitive *tgpi)
}
else if (tgpi->type == GP_STROKE_ARC) {
if (tgpi->flip) {
- gp_primitive_rotate_line(tgpi->cp1, tgpi->cp2, tgpi->start, tgpi->end, M_PI_2);
+ gpencil_primitive_rotate_line(tgpi->cp1, tgpi->cp2, tgpi->start, tgpi->end, M_PI_2);
}
else {
- gp_primitive_rotate_line(tgpi->cp1, tgpi->cp2, tgpi->end, tgpi->start, M_PI_2);
+ gpencil_primitive_rotate_line(tgpi->cp1, tgpi->cp2, tgpi->end, tgpi->start, M_PI_2);
}
}
}
@@ -294,7 +294,7 @@ static void gpencil_primitive_allocate_memory(tGPDprimitive *tgpi)
/* ****************** Primitive Interactive *********************** */
/* Helper: Create internal strokes primitives data */
-static void gp_primitive_set_initdata(bContext *C, tGPDprimitive *tgpi)
+static void gpencil_primitive_set_initdata(bContext *C, tGPDprimitive *tgpi)
{
Scene *scene = CTX_data_scene(C);
ToolSettings *ts = scene->toolsettings;
@@ -378,7 +378,7 @@ static void gpencil_primitive_add_segment(tGPDprimitive *tgpi)
}
/* Helper: set control point */
-static void gp_primitive_set_cp(tGPDprimitive *tgpi, float p[2], float color[4], int size)
+static void gpencil_primitive_set_cp(tGPDprimitive *tgpi, float p[2], float color[4], int size)
{
if (tgpi->flag == IN_PROGRESS) {
return;
@@ -500,7 +500,7 @@ static void gpencil_primitive_status_indicators(bContext *C, tGPDprimitive *tgpi
}
/* create a rectangle */
-static void gp_primitive_rectangle(tGPDprimitive *tgpi, tGPspoint *points2D)
+static void gpencil_primitive_rectangle(tGPDprimitive *tgpi, tGPspoint *points2D)
{
float coords[5][2];
@@ -531,20 +531,20 @@ static void gp_primitive_rectangle(tGPDprimitive *tgpi, tGPspoint *points2D)
mid_v2_v2v2(tgpi->midpoint, tgpi->start, tgpi->end);
float color[4];
UI_GetThemeColor4fv(TH_GIZMO_PRIMARY, color);
- gp_primitive_set_cp(tgpi, tgpi->end, color, BIG_SIZE_CTL);
+ gpencil_primitive_set_cp(tgpi, tgpi->end, color, BIG_SIZE_CTL);
if (tgpi->tot_stored_edges) {
UI_GetThemeColor4fv(TH_REDALERT, color);
- gp_primitive_set_cp(tgpi, tgpi->start, color, SMALL_SIZE_CTL);
+ gpencil_primitive_set_cp(tgpi, tgpi->start, color, SMALL_SIZE_CTL);
}
else {
- gp_primitive_set_cp(tgpi, tgpi->start, color, BIG_SIZE_CTL);
+ gpencil_primitive_set_cp(tgpi, tgpi->start, color, BIG_SIZE_CTL);
}
UI_GetThemeColor4fv(TH_REDALERT, color);
- gp_primitive_set_cp(tgpi, tgpi->midpoint, color, SMALL_SIZE_CTL);
+ gpencil_primitive_set_cp(tgpi, tgpi->midpoint, color, SMALL_SIZE_CTL);
}
/* create a line */
-static void gp_primitive_line(tGPDprimitive *tgpi, tGPspoint *points2D, bool editable)
+static void gpencil_primitive_line(tGPDprimitive *tgpi, tGPspoint *points2D, bool editable)
{
const int totpoints = (tgpi->tot_edges + tgpi->tot_stored_edges);
const float step = 1.0f / (float)(tgpi->tot_edges - 1);
@@ -559,24 +559,24 @@ static void gp_primitive_line(tGPDprimitive *tgpi, tGPspoint *points2D, bool edi
if (editable) {
float color[4];
UI_GetThemeColor4fv(TH_GIZMO_PRIMARY, color);
- gp_primitive_set_cp(tgpi, tgpi->end, color, BIG_SIZE_CTL);
+ gpencil_primitive_set_cp(tgpi, tgpi->end, color, BIG_SIZE_CTL);
if (tgpi->tot_stored_edges) {
UI_GetThemeColor4fv(TH_REDALERT, color);
- gp_primitive_set_cp(tgpi, tgpi->start, color, SMALL_SIZE_CTL);
+ gpencil_primitive_set_cp(tgpi, tgpi->start, color, SMALL_SIZE_CTL);
}
else {
- gp_primitive_set_cp(tgpi, tgpi->start, color, BIG_SIZE_CTL);
+ gpencil_primitive_set_cp(tgpi, tgpi->start, color, BIG_SIZE_CTL);
}
}
else {
float color[4];
UI_GetThemeColor4fv(TH_REDALERT, color);
- gp_primitive_set_cp(tgpi, tgpi->start, color, SMALL_SIZE_CTL);
+ gpencil_primitive_set_cp(tgpi, tgpi->start, color, SMALL_SIZE_CTL);
}
}
/* create an arc */
-static void gp_primitive_arc(tGPDprimitive *tgpi, tGPspoint *points2D)
+static void gpencil_primitive_arc(tGPDprimitive *tgpi, tGPspoint *points2D)
{
const int totpoints = (tgpi->tot_edges + tgpi->tot_stored_edges);
const float step = M_PI_2 / (float)(tgpi->tot_edges - 1);
@@ -604,20 +604,20 @@ static void gp_primitive_arc(tGPDprimitive *tgpi, tGPspoint *points2D)
}
float color[4];
UI_GetThemeColor4fv(TH_GIZMO_PRIMARY, color);
- gp_primitive_set_cp(tgpi, tgpi->end, color, BIG_SIZE_CTL);
+ gpencil_primitive_set_cp(tgpi, tgpi->end, color, BIG_SIZE_CTL);
if (tgpi->tot_stored_edges) {
UI_GetThemeColor4fv(TH_REDALERT, color);
- gp_primitive_set_cp(tgpi, tgpi->start, color, SMALL_SIZE_CTL);
+ gpencil_primitive_set_cp(tgpi, tgpi->start, color, SMALL_SIZE_CTL);
}
else {
- gp_primitive_set_cp(tgpi, tgpi->start, color, BIG_SIZE_CTL);
+ gpencil_primitive_set_cp(tgpi, tgpi->start, color, BIG_SIZE_CTL);
}
UI_GetThemeColor4fv(TH_GIZMO_SECONDARY, color);
- gp_primitive_set_cp(tgpi, tgpi->cp1, color, BIG_SIZE_CTL * 0.9f);
+ gpencil_primitive_set_cp(tgpi, tgpi->cp1, color, BIG_SIZE_CTL * 0.9f);
}
/* create a bezier */
-static void gp_primitive_bezier(tGPDprimitive *tgpi, tGPspoint *points2D)
+static void gpencil_primitive_bezier(tGPDprimitive *tgpi, tGPspoint *points2D)
{
const int totpoints = (tgpi->tot_edges + tgpi->tot_stored_edges);
const float step = 1.0f / (float)(tgpi->tot_edges - 1);
@@ -639,21 +639,21 @@ static void gp_primitive_bezier(tGPDprimitive *tgpi, tGPspoint *points2D)
}
float color[4];
UI_GetThemeColor4fv(TH_GIZMO_PRIMARY, color);
- gp_primitive_set_cp(tgpi, tgpi->end, color, BIG_SIZE_CTL);
+ gpencil_primitive_set_cp(tgpi, tgpi->end, color, BIG_SIZE_CTL);
if (tgpi->tot_stored_edges) {
UI_GetThemeColor4fv(TH_REDALERT, color);
- gp_primitive_set_cp(tgpi, tgpi->start, color, SMALL_SIZE_CTL);
+ gpencil_primitive_set_cp(tgpi, tgpi->start, color, SMALL_SIZE_CTL);
}
else {
- gp_primitive_set_cp(tgpi, tgpi->start, color, BIG_SIZE_CTL);
+ gpencil_primitive_set_cp(tgpi, tgpi->start, color, BIG_SIZE_CTL);
}
UI_GetThemeColor4fv(TH_GIZMO_SECONDARY, color);
- gp_primitive_set_cp(tgpi, tgpi->cp1, color, BIG_SIZE_CTL * 0.9f);
- gp_primitive_set_cp(tgpi, tgpi->cp2, color, BIG_SIZE_CTL * 0.9f);
+ gpencil_primitive_set_cp(tgpi, tgpi->cp1, color, BIG_SIZE_CTL * 0.9f);
+ gpencil_primitive_set_cp(tgpi, tgpi->cp2, color, BIG_SIZE_CTL * 0.9f);
}
/* create a circle */
-static void gp_primitive_circle(tGPDprimitive *tgpi, tGPspoint *points2D)
+static void gpencil_primitive_circle(tGPDprimitive *tgpi, tGPspoint *points2D)
{
const int totpoints = (tgpi->tot_edges + tgpi->tot_stored_edges);
const float step = (2.0f * M_PI) / (float)(tgpi->tot_edges);
@@ -674,14 +674,14 @@ static void gp_primitive_circle(tGPDprimitive *tgpi, tGPspoint *points2D)
}
float color[4];
UI_GetThemeColor4fv(TH_GIZMO_PRIMARY, color);
- gp_primitive_set_cp(tgpi, tgpi->end, color, BIG_SIZE_CTL);
- gp_primitive_set_cp(tgpi, tgpi->start, color, BIG_SIZE_CTL);
+ gpencil_primitive_set_cp(tgpi, tgpi->end, color, BIG_SIZE_CTL);
+ gpencil_primitive_set_cp(tgpi, tgpi->start, color, BIG_SIZE_CTL);
UI_GetThemeColor4fv(TH_REDALERT, color);
- gp_primitive_set_cp(tgpi, center, color, SMALL_SIZE_CTL);
+ gpencil_primitive_set_cp(tgpi, center, color, SMALL_SIZE_CTL);
}
/* Helper: Update shape of the stroke */
-static void gp_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi)
+static void gpencil_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi)
{
ToolSettings *ts = tgpi->scene->toolsettings;
bGPdata *gpd = tgpi->gpd;
@@ -715,30 +715,30 @@ static void gp_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi)
if (tgpi->tot_edges > 1) {
switch (tgpi->type) {
case GP_STROKE_BOX:
- gp_primitive_rectangle(tgpi, points2D);
+ gpencil_primitive_rectangle(tgpi, points2D);
break;
case GP_STROKE_LINE:
- gp_primitive_line(tgpi, points2D, true);
+ gpencil_primitive_line(tgpi, points2D, true);
break;
case GP_STROKE_POLYLINE:
- gp_primitive_line(tgpi, points2D, false);
+ gpencil_primitive_line(tgpi, points2D, false);
break;
case GP_STROKE_CIRCLE:
- gp_primitive_circle(tgpi, points2D);
+ gpencil_primitive_circle(tgpi, points2D);
break;
case GP_STROKE_ARC:
- gp_primitive_arc(tgpi, points2D);
+ gpencil_primitive_arc(tgpi, points2D);
break;
case GP_STROKE_CURVE:
- gp_primitive_bezier(tgpi, points2D);
+ gpencil_primitive_bezier(tgpi, points2D);
default:
break;
}
}
/* convert screen-coordinates to 3D coordinates */
- gp_session_validatebuffer(tgpi);
- gp_init_colors(tgpi);
+ gpencil_session_validatebuffer(tgpi);
+ gpencil_init_colors(tgpi);
if (gset->flag & GP_SCULPT_SETT_FLAG_PRIMITIVE_CURVE) {
BKE_curvemapping_initialize(ts->gp_sculpt.cur_primitive);
}
@@ -982,12 +982,12 @@ static void gp_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi)
ED_gpencil_drawing_reference_get(tgpi->scene, tgpi->ob, ts->gpencil_v3d_align, origin);
/* reproject current */
ED_gpencil_tpoint_to_point(tgpi->region, origin, tpt, &spt);
- ED_gp_project_point_to_plane(
+ ED_gpencil_project_point_to_plane(
tgpi->scene, tgpi->ob, tgpi->rv3d, origin, tgpi->lock_axis - 1, &spt);
/* reproject previous */
ED_gpencil_tpoint_to_point(tgpi->region, origin, tptb, &spt2);
- ED_gp_project_point_to_plane(
+ ED_gpencil_project_point_to_plane(
tgpi->scene, tgpi->ob, tgpi->rv3d, origin, tgpi->lock_axis - 1, &spt2);
tgpi->totpixlen += len_v3v3(&spt.x, &spt2.x);
tpt->uv_fac = tgpi->totpixlen;
@@ -1011,7 +1011,7 @@ static void gp_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi)
}
/* convert screen-coordinates to 3D coordinates */
- gp_stroke_convertcoords_tpoint(
+ gpencil_stroke_convertcoords_tpoint(
tgpi->scene, tgpi->region, tgpi->ob, p2d, depth_arr ? depth_arr + i : NULL, &pt->x);
pt->pressure = pressure;
@@ -1036,7 +1036,7 @@ static void gp_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi)
bGPDcontrolpoint *cps = tgpi->gpd->runtime.cp_points;
for (int i = 0; i < tgpi->gpd->runtime.tot_cp_points; i++) {
bGPDcontrolpoint *cp = &cps[i];
- gp_stroke_convertcoords_tpoint(
+ gpencil_stroke_convertcoords_tpoint(
tgpi->scene, tgpi->region, tgpi->ob, (tGPspoint *)cp, NULL, &cp->x);
}
}
@@ -1045,14 +1045,14 @@ static void gp_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi)
if (!is_depth) {
float origin[3];
ED_gpencil_drawing_reference_get(tgpi->scene, tgpi->ob, ts->gpencil_v3d_align, origin);
- ED_gp_project_stroke_to_plane(
+ ED_gpencil_project_stroke_to_plane(
tgpi->scene, tgpi->ob, tgpi->rv3d, gps, origin, ts->gp_sculpt.lock_axis - 1);
}
/* if parented change position relative to parent object */
for (int i = 0; i < gps->totpoints; i++) {
bGPDspoint *pt = &gps->points[i];
- gp_apply_parent_point(tgpi->depsgraph, tgpi->ob, tgpi->gpl, pt);
+ gpencil_apply_parent_point(tgpi->depsgraph, tgpi->ob, tgpi->gpl, pt);
}
/* if camera view, reproject flat to view to avoid perspective effect */
@@ -1082,7 +1082,7 @@ static void gpencil_primitive_update(bContext *C, wmOperator *op, tGPDprimitive
tgpi->type = RNA_enum_get(op->ptr, "type");
tgpi->tot_edges = RNA_int_get(op->ptr, "edges");
/* update points position */
- gp_primitive_update_strokes(C, tgpi);
+ gpencil_primitive_update_strokes(C, tgpi);
}
/* Initialise mouse points */
@@ -1237,7 +1237,7 @@ static void gpencil_primitive_init(bContext *C, wmOperator *op)
tgpi->lock_axis = ts->gp_sculpt.lock_axis;
/* set temp layer, frame and stroke */
- gp_primitive_set_initdata(C, tgpi);
+ gpencil_primitive_set_initdata(C, tgpi);
}
/* Invoke handler: Initialize the operator */
@@ -1396,14 +1396,14 @@ static void gpencil_primitive_edit_event_handling(
gpencil_primitive_add_segment(tgpi);
copy_v2_v2(tgpi->start, tgpi->end);
copy_v2_v2(tgpi->origin, tgpi->start);
- gp_primitive_update_cps(tgpi);
+ gpencil_primitive_update_cps(tgpi);
tgpi->flag = IN_POLYLINE;
WM_cursor_modal_set(win, WM_CURSOR_CROSS);
}
else {
tgpi->flag = IN_CURVE_EDIT;
- gp_primitive_update_cps(tgpi);
+ gpencil_primitive_update_cps(tgpi);
gpencil_primitive_update(C, op, tgpi);
}
}
@@ -1460,7 +1460,7 @@ static void gpencil_primitive_edit_event_handling(
case EVT_MKEY: {
if ((event->val == KM_PRESS) && (tgpi->curve) && (ELEM(tgpi->orign_type, GP_STROKE_ARC))) {
tgpi->flip ^= 1;
- gp_primitive_update_cps(tgpi);
+ gpencil_primitive_update_cps(tgpi);
gpencil_primitive_update(C, op, tgpi);
}
break;
@@ -1472,7 +1472,7 @@ static void gpencil_primitive_edit_event_handling(
gpencil_primitive_add_segment(tgpi);
copy_v2_v2(tgpi->start, tgpi->end);
copy_v2_v2(tgpi->origin, tgpi->start);
- gp_primitive_update_cps(tgpi);
+ gpencil_primitive_update_cps(tgpi);
}
break;
}
@@ -1625,7 +1625,7 @@ static int gpencil_primitive_modal(bContext *C, wmOperator *op, const wmEvent *e
if (event->val == KM_PRESS) {
tgpi->flag = IDLE;
tgpi->tot_edges = tgpi->tot_stored_edges ? 1 : 0;
- gp_primitive_update_strokes(C, tgpi);
+ gpencil_primitive_update_strokes(C, tgpi);
gpencil_primitive_interaction_end(C, op, win, tgpi);
return OPERATOR_FINISHED;
}
@@ -1749,7 +1749,7 @@ static int gpencil_primitive_modal(bContext *C, wmOperator *op, const wmEvent *e
(!ELEM(tgpi->type, GP_STROKE_POLYLINE))) {
/* set control points and enter edit mode */
tgpi->flag = IN_CURVE_EDIT;
- gp_primitive_update_cps(tgpi);
+ gpencil_primitive_update_cps(tgpi);
gpencil_primitive_update(C, op, tgpi);
}
else if ((event->val == KM_RELEASE) && (tgpi->flag == IN_PROGRESS) &&
@@ -1792,7 +1792,7 @@ static int gpencil_primitive_modal(bContext *C, wmOperator *op, const wmEvent *e
if (tgpi->tot_stored_edges > 0) {
tgpi->flag = IDLE;
tgpi->tot_edges = tgpi->tot_stored_edges ? 1 : 0;
- gp_primitive_update_strokes(C, tgpi);
+ gpencil_primitive_update_strokes(C, tgpi);
gpencil_primitive_interaction_end(C, op, win, tgpi);
/* done! */
return OPERATOR_FINISHED;
@@ -1871,7 +1871,7 @@ static int gpencil_primitive_modal(bContext *C, wmOperator *op, const wmEvent *e
}
RNA_enum_set(op->ptr, "type", tgpi->type);
- gp_primitive_update_cps(tgpi);
+ gpencil_primitive_update_cps(tgpi);
gpencil_primitive_update(C, op, tgpi);
}
break;
@@ -1880,7 +1880,7 @@ static int gpencil_primitive_modal(bContext *C, wmOperator *op, const wmEvent *e
if (tgpi->flag == IN_CURVE_EDIT) {
tgpi->flag = IN_PROGRESS;
WM_cursor_modal_set(win, WM_CURSOR_NSEW_SCROLL);
- gp_primitive_update_cps(tgpi);
+ gpencil_primitive_update_cps(tgpi);
gpencil_primitive_update(C, op, tgpi);
}
break;
@@ -1908,7 +1908,7 @@ static int gpencil_primitive_modal(bContext *C, wmOperator *op, const wmEvent *e
tgpi->start[0] = tgpi->origin[0] - (tgpi->end[0] - tgpi->origin[0]);
tgpi->start[1] = tgpi->origin[1] - (tgpi->end[1] - tgpi->origin[1]);
}
- gp_primitive_update_cps(tgpi);
+ gpencil_primitive_update_cps(tgpi);
/* update screen */
gpencil_primitive_update(C, op, tgpi);
}
diff --git a/source/blender/editors/gpencil/gpencil_sculpt_paint.c b/source/blender/editors/gpencil/gpencil_sculpt_paint.c
index 6bd945160a6..d0adcea25c1 100644
--- a/source/blender/editors/gpencil/gpencil_sculpt_paint.c
+++ b/source/blender/editors/gpencil/gpencil_sculpt_paint.c
@@ -172,9 +172,9 @@ typedef bool (*GP_BrushApplyCb)(tGP_BrushEditData *gso,
/* Utility Functions */
/* apply lock axis reset */
-static void gpsculpt_compute_lock_axis(tGP_BrushEditData *gso,
- bGPDspoint *pt,
- const float save_pt[3])
+static void gpencil_sculpt_compute_lock_axis(tGP_BrushEditData *gso,
+ bGPDspoint *pt,
+ const float save_pt[3])
{
const ToolSettings *ts = gso->scene->toolsettings;
const View3DCursor *cursor = &gso->scene->cursor;
@@ -221,7 +221,7 @@ static void gpsculpt_compute_lock_axis(tGP_BrushEditData *gso,
/* Context ---------------------------------------- */
/* Get the sculpting settings */
-static GP_Sculpt_Settings *gpsculpt_get_settings(Scene *scene)
+static GP_Sculpt_Settings *gpencil_sculpt_get_settings(Scene *scene)
{
return &scene->toolsettings->gp_sculpt;
}
@@ -229,7 +229,7 @@ static GP_Sculpt_Settings *gpsculpt_get_settings(Scene *scene)
/* Brush Operations ------------------------------- */
/* Invert behavior of brush? */
-static bool gp_brush_invert_check(tGP_BrushEditData *gso)
+static bool gpencil_brush_invert_check(tGP_BrushEditData *gso)
{
/* The basic setting is the brush's setting (from the panel) */
bool invert = ((gso->brush->gpencil_settings->sculpt_flag & GP_SCULPT_FLAG_INVERT) != 0) ||
@@ -251,7 +251,9 @@ static bool gp_brush_invert_check(tGP_BrushEditData *gso)
}
/* Compute strength of effect */
-static float gp_brush_influence_calc(tGP_BrushEditData *gso, const int radius, const int co[2])
+static float gpencil_brush_influence_calc(tGP_BrushEditData *gso,
+ const int radius,
+ const int co[2])
{
Brush *brush = gso->brush;
@@ -322,14 +324,14 @@ static void gpencil_update_geometry(bGPdata *gpd)
/* A simple (but slower + inaccurate)
* smooth-brush implementation to test the algorithm for stroke smoothing. */
-static bool gp_brush_smooth_apply(tGP_BrushEditData *gso,
- bGPDstroke *gps,
- float UNUSED(rot_eval),
- int pt_index,
- const int radius,
- const int co[2])
+static bool gpencil_brush_smooth_apply(tGP_BrushEditData *gso,
+ bGPDstroke *gps,
+ float UNUSED(rot_eval),
+ int pt_index,
+ const int radius,
+ const int co[2])
{
- float inf = gp_brush_influence_calc(gso, radius, co);
+ float inf = gpencil_brush_influence_calc(gso, radius, co);
/* perform smoothing */
if (gso->brush->gpencil_settings->sculpt_mode_flag & GP_SCULPT_FLAGMODE_APPLY_POSITION) {
@@ -352,12 +354,12 @@ static bool gp_brush_smooth_apply(tGP_BrushEditData *gso,
/* Line Thickness Brush */
/* Make lines thicker or thinner by the specified amounts */
-static bool gp_brush_thickness_apply(tGP_BrushEditData *gso,
- bGPDstroke *gps,
- float UNUSED(rot_eval),
- int pt_index,
- const int radius,
- const int co[2])
+static bool gpencil_brush_thickness_apply(tGP_BrushEditData *gso,
+ bGPDstroke *gps,
+ float UNUSED(rot_eval),
+ int pt_index,
+ const int radius,
+ const int co[2])
{
bGPDspoint *pt = gps->points + pt_index;
float inf;
@@ -366,12 +368,12 @@ static bool gp_brush_thickness_apply(tGP_BrushEditData *gso,
* - We divide the strength by 10, so that users can set "sane" values.
* Otherwise, good default values are in the range of 0.093
*/
- inf = gp_brush_influence_calc(gso, radius, co) / 10.0f;
+ inf = gpencil_brush_influence_calc(gso, radius, co) / 10.0f;
/* apply */
/* XXX: this is much too strong,
* and it should probably do some smoothing with the surrounding stuff. */
- if (gp_brush_invert_check(gso)) {
+ if (gpencil_brush_invert_check(gso)) {
/* make line thinner - reduce stroke pressure */
pt->pressure -= inf;
}
@@ -396,21 +398,21 @@ static bool gp_brush_thickness_apply(tGP_BrushEditData *gso,
/* Color Strength Brush */
/* Make color more or less transparent by the specified amounts */
-static bool gp_brush_strength_apply(tGP_BrushEditData *gso,
- bGPDstroke *gps,
- float UNUSED(rot_eval),
- int pt_index,
- const int radius,
- const int co[2])
+static bool gpencil_brush_strength_apply(tGP_BrushEditData *gso,
+ bGPDstroke *gps,
+ float UNUSED(rot_eval),
+ int pt_index,
+ const int radius,
+ const int co[2])
{
bGPDspoint *pt = gps->points + pt_index;
float inf;
/* Compute strength of effect */
- inf = gp_brush_influence_calc(gso, radius, co) * 0.125f;
+ inf = gpencil_brush_influence_calc(gso, radius, co) * 0.125f;
/* Invert effect. */
- if (gp_brush_invert_check(gso)) {
+ if (gpencil_brush_invert_check(gso)) {
inf *= -1.0f;
}
@@ -443,7 +445,7 @@ typedef struct tGPSB_Grab_StrokeData {
} tGPSB_Grab_StrokeData;
/* initialise custom data for handling this stroke */
-static void gp_brush_grab_stroke_init(tGP_BrushEditData *gso, bGPDstroke *gps)
+static void gpencil_brush_grab_stroke_init(tGP_BrushEditData *gso, bGPDstroke *gps)
{
tGPSB_Grab_StrokeData *data = NULL;
@@ -481,15 +483,15 @@ static void gp_brush_grab_stroke_init(tGP_BrushEditData *gso, bGPDstroke *gps)
}
/* store references to stroke points in the initial stage */
-static bool gp_brush_grab_store_points(tGP_BrushEditData *gso,
- bGPDstroke *gps,
- float rot_eval,
- int pt_index,
- const int radius,
- const int co[2])
+static bool gpencil_brush_grab_store_points(tGP_BrushEditData *gso,
+ bGPDstroke *gps,
+ float rot_eval,
+ int pt_index,
+ const int radius,
+ const int co[2])
{
tGPSB_Grab_StrokeData *data = BLI_ghash_lookup(gso->stroke_customdata, gps);
- float inf = gp_brush_influence_calc(gso, radius, co);
+ float inf = gpencil_brush_influence_calc(gso, radius, co);
BLI_assert(data != NULL);
BLI_assert(data->size < data->capacity);
@@ -505,7 +507,7 @@ static bool gp_brush_grab_store_points(tGP_BrushEditData *gso,
}
/* Compute effect vector for grab brush */
-static void gp_brush_grab_calc_dvec(tGP_BrushEditData *gso)
+static void gpencil_brush_grab_calc_dvec(tGP_BrushEditData *gso)
{
/* Convert mouse-movements to movement vector */
RegionView3D *rv3d = gso->region->regiondata;
@@ -532,9 +534,9 @@ static void gp_brush_grab_calc_dvec(tGP_BrushEditData *gso)
}
/* Apply grab transform to all relevant points of the affected strokes */
-static void gp_brush_grab_apply_cached(tGP_BrushEditData *gso,
- bGPDstroke *gps,
- const float diff_mat[4][4])
+static void gpencil_brush_grab_apply_cached(tGP_BrushEditData *gso,
+ bGPDstroke *gps,
+ const float diff_mat[4][4])
{
tGPSB_Grab_StrokeData *data = BLI_ghash_lookup(gso->stroke_customdata, gps);
/* If a new frame is created, could be impossible find the stroke. */
@@ -553,7 +555,7 @@ static void gp_brush_grab_apply_cached(tGP_BrushEditData *gso,
/* get evaluated transformation */
gso->rot_eval = data->rot_eval[i];
- gp_brush_grab_calc_dvec(gso);
+ gpencil_brush_grab_calc_dvec(gso);
/* adjust the amount of displacement to apply */
mul_v3_v3fl(delta, gso->dvec, data->weights[i]);
@@ -569,12 +571,12 @@ static void gp_brush_grab_apply_cached(tGP_BrushEditData *gso,
mul_m4_v3(inverse_diff_mat, &pt->x);
/* compute lock axis */
- gpsculpt_compute_lock_axis(gso, pt, save_pt);
+ gpencil_sculpt_compute_lock_axis(gso, pt, save_pt);
}
}
/* free customdata used for handling this stroke */
-static void gp_brush_grab_stroke_free(void *ptr)
+static void gpencil_brush_grab_stroke_free(void *ptr)
{
tGPSB_Grab_StrokeData *data = (tGPSB_Grab_StrokeData *)ptr;
@@ -589,19 +591,19 @@ static void gp_brush_grab_stroke_free(void *ptr)
/* ----------------------------------------------- */
/* Push Brush */
-/* NOTE: Depends on gp_brush_grab_calc_dvec() */
-static bool gp_brush_push_apply(tGP_BrushEditData *gso,
- bGPDstroke *gps,
- float UNUSED(rot_eval),
- int pt_index,
- const int radius,
- const int co[2])
+/* NOTE: Depends on gpencil_brush_grab_calc_dvec() */
+static bool gpencil_brush_push_apply(tGP_BrushEditData *gso,
+ bGPDstroke *gps,
+ float UNUSED(rot_eval),
+ int pt_index,
+ const int radius,
+ const int co[2])
{
bGPDspoint *pt = gps->points + pt_index;
float save_pt[3];
copy_v3_v3(save_pt, &pt->x);
- float inf = gp_brush_influence_calc(gso, radius, co);
+ float inf = gpencil_brush_influence_calc(gso, radius, co);
float delta[3] = {0.0f};
/* adjust the amount of displacement to apply */
@@ -612,7 +614,7 @@ static bool gp_brush_push_apply(tGP_BrushEditData *gso,
add_v3_v3(&pt->x, delta);
/* compute lock axis */
- gpsculpt_compute_lock_axis(gso, pt, save_pt);
+ gpencil_sculpt_compute_lock_axis(gso, pt, save_pt);
/* done */
return true;
@@ -621,10 +623,10 @@ static bool gp_brush_push_apply(tGP_BrushEditData *gso,
/* ----------------------------------------------- */
/* Pinch Brush */
/* Compute reference midpoint for the brush - this is what we'll be moving towards */
-static void gp_brush_calc_midpoint(tGP_BrushEditData *gso)
+static void gpencil_brush_calc_midpoint(tGP_BrushEditData *gso)
{
/* Convert mouse position to 3D space
- * See: gpencil_paint.c :: gp_stroke_convertcoords()
+ * See: gpencil_paint.c :: gpencil_stroke_convertcoords()
*/
RegionView3D *rv3d = gso->region->regiondata;
const float *rvec = gso->object->loc;
@@ -647,12 +649,12 @@ static void gp_brush_calc_midpoint(tGP_BrushEditData *gso)
}
/* Shrink distance between midpoint and this point... */
-static bool gp_brush_pinch_apply(tGP_BrushEditData *gso,
- bGPDstroke *gps,
- float UNUSED(rot_eval),
- int pt_index,
- const int radius,
- const int co[2])
+static bool gpencil_brush_pinch_apply(tGP_BrushEditData *gso,
+ bGPDstroke *gps,
+ float UNUSED(rot_eval),
+ int pt_index,
+ const int radius,
+ const int co[2])
{
bGPDspoint *pt = gps->points + pt_index;
float fac, inf;
@@ -665,7 +667,7 @@ static bool gp_brush_pinch_apply(tGP_BrushEditData *gso,
* - Div 10 = Not enough effect
* - Div 5 = Happy medium... (by trial and error)
*/
- inf = gp_brush_influence_calc(gso, radius, co) / 5.0f;
+ inf = gpencil_brush_influence_calc(gso, radius, co) / 5.0f;
/* 1) Make this point relative to the cursor/midpoint (dvec) */
float fpt[3];
@@ -677,7 +679,7 @@ static bool gp_brush_pinch_apply(tGP_BrushEditData *gso,
* OR
* Increase the distance (if inverting the brush action!)
*/
- if (gp_brush_invert_check(gso)) {
+ if (gpencil_brush_invert_check(gso)) {
/* Inflate (inverse) */
fac = 1.0f + (inf * inf); /* squared to temper the effect... */
}
@@ -692,7 +694,7 @@ static bool gp_brush_pinch_apply(tGP_BrushEditData *gso,
mul_v3_m4v3(&pt->x, gso->object->imat, fpt);
/* compute lock axis */
- gpsculpt_compute_lock_axis(gso, pt, save_pt);
+ gpencil_sculpt_compute_lock_axis(gso, pt, save_pt);
/* done */
return true;
@@ -704,12 +706,12 @@ static bool gp_brush_pinch_apply(tGP_BrushEditData *gso,
* convert the rotated point and convert it into "data" space
*/
-static bool gp_brush_twist_apply(tGP_BrushEditData *gso,
- bGPDstroke *gps,
- float UNUSED(rot_eval),
- int pt_index,
- const int radius,
- const int co[2])
+static bool gpencil_brush_twist_apply(tGP_BrushEditData *gso,
+ bGPDstroke *gps,
+ float UNUSED(rot_eval),
+ int pt_index,
+ const int radius,
+ const int co[2])
{
bGPDspoint *pt = gps->points + pt_index;
float angle, inf;
@@ -717,10 +719,10 @@ static bool gp_brush_twist_apply(tGP_BrushEditData *gso,
copy_v3_v3(save_pt, &pt->x);
/* Angle to rotate by */
- inf = gp_brush_influence_calc(gso, radius, co);
+ inf = gpencil_brush_influence_calc(gso, radius, co);
angle = DEG2RADF(1.0f) * inf;
- if (gp_brush_invert_check(gso)) {
+ if (gpencil_brush_invert_check(gso)) {
/* invert angle that we rotate by */
angle *= -1;
}
@@ -749,7 +751,7 @@ static bool gp_brush_twist_apply(tGP_BrushEditData *gso,
mul_v3_m4v3(&pt->x, gso->object->imat, fpt);
/* compute lock axis */
- gpsculpt_compute_lock_axis(gso, pt, save_pt);
+ gpencil_sculpt_compute_lock_axis(gso, pt, save_pt);
}
else {
const float axis[3] = {0.0f, 0.0f, 1.0f};
@@ -787,12 +789,12 @@ static bool gp_brush_twist_apply(tGP_BrushEditData *gso,
/* ----------------------------------------------- */
/* Randomize Brush */
/* Apply some random jitter to the point */
-static bool gp_brush_randomize_apply(tGP_BrushEditData *gso,
- bGPDstroke *gps,
- float UNUSED(rot_eval),
- int pt_index,
- const int radius,
- const int co[2])
+static bool gpencil_brush_randomize_apply(tGP_BrushEditData *gso,
+ bGPDstroke *gps,
+ float UNUSED(rot_eval),
+ int pt_index,
+ const int radius,
+ const int co[2])
{
bGPDspoint *pt = gps->points + pt_index;
float save_pt[3];
@@ -801,7 +803,7 @@ static bool gp_brush_randomize_apply(tGP_BrushEditData *gso,
/* Amount of jitter to apply depends on the distance of the point to the cursor,
* as well as the strength of the brush
*/
- const float inf = gp_brush_influence_calc(gso, radius, co) / 2.0f;
+ const float inf = gpencil_brush_influence_calc(gso, radius, co) / 2.0f;
const float fac = BLI_rng_get_float(gso->rng) * inf;
/* apply random to position */
@@ -840,7 +842,7 @@ static bool gp_brush_randomize_apply(tGP_BrushEditData *gso,
ED_view3d_win_to_delta(gso->gsc.region, svec, dvec, zfac);
add_v3_v3(&pt->x, dvec);
/* compute lock axis */
- gpsculpt_compute_lock_axis(gso, pt, save_pt);
+ gpencil_sculpt_compute_lock_axis(gso, pt, save_pt);
}
}
}
@@ -909,7 +911,7 @@ typedef struct tGPSB_CloneBrushData {
} tGPSB_CloneBrushData;
/* Initialise "clone" brush data */
-static void gp_brush_clone_init(bContext *C, tGP_BrushEditData *gso)
+static void gpencil_brush_clone_init(bContext *C, tGP_BrushEditData *gso)
{
tGPSB_CloneBrushData *data;
bGPDstroke *gps;
@@ -918,7 +920,7 @@ static void gp_brush_clone_init(bContext *C, tGP_BrushEditData *gso)
gso->customdata = data = MEM_callocN(sizeof(tGPSB_CloneBrushData), "CloneBrushData");
/* compute midpoint of strokes on clipboard */
- for (gps = gp_strokes_copypastebuf.first; gps; gps = gps->next) {
+ for (gps = gpencil_strokes_copypastebuf.first; gps; gps = gps->next) {
if (ED_gpencil_stroke_can_use(C, gps)) {
const float dfac = 1.0f / ((float)gps->totpoints);
float mid[3] = {0.0f};
@@ -954,11 +956,11 @@ static void gp_brush_clone_init(bContext *C, tGP_BrushEditData *gso)
/* Init colormap for mapping between the pasted stroke's source color (names)
* and the final colors that will be used here instead.
*/
- data->new_colors = gp_copybuf_validate_colormap(C);
+ data->new_colors = gpencil_copybuf_validate_colormap(C);
}
/* Free custom data used for "clone" brush */
-static void gp_brush_clone_free(tGP_BrushEditData *gso)
+static void gpencil_brush_clone_free(tGP_BrushEditData *gso)
{
tGPSB_CloneBrushData *data = gso->customdata;
@@ -980,7 +982,7 @@ static void gp_brush_clone_free(tGP_BrushEditData *gso)
}
/* Create new copies of the strokes on the clipboard */
-static void gp_brush_clone_add(bContext *C, tGP_BrushEditData *gso)
+static void gpencil_brush_clone_add(bContext *C, tGP_BrushEditData *gso)
{
tGPSB_CloneBrushData *data = gso->customdata;
@@ -995,11 +997,11 @@ static void gp_brush_clone_add(bContext *C, tGP_BrushEditData *gso)
/* Compute amount to offset the points by */
/* NOTE: This assumes that screenspace strokes are NOT used in the 3D view... */
- gp_brush_calc_midpoint(gso); /* this puts the cursor location into gso->dvec */
+ gpencil_brush_calc_midpoint(gso); /* this puts the cursor location into gso->dvec */
sub_v3_v3v3(delta, gso->dvec, data->buffer_midpoint);
/* Copy each stroke into the layer */
- for (gps = gp_strokes_copypastebuf.first; gps; gps = gps->next) {
+ for (gps = gpencil_strokes_copypastebuf.first; gps; gps = gps->next) {
if (ED_gpencil_stroke_can_use(C, gps)) {
bGPDstroke *new_stroke;
bGPDspoint *pt;
@@ -1051,14 +1053,14 @@ static void gp_brush_clone_add(bContext *C, tGP_BrushEditData *gso)
}
/* Move newly-added strokes around - "Stamp" mode of the Clone brush */
-static void gp_brush_clone_adjust(tGP_BrushEditData *gso)
+static void gpencil_brush_clone_adjust(tGP_BrushEditData *gso)
{
tGPSB_CloneBrushData *data = gso->customdata;
size_t snum;
/* Compute the amount of movement to apply (overwrites dvec) */
gso->rot_eval = 0.0f;
- gp_brush_grab_calc_dvec(gso);
+ gpencil_brush_grab_calc_dvec(gso);
/* For each of the stored strokes, apply the offset to each point */
/* NOTE: Again this assumes that in the 3D view,
@@ -1075,8 +1077,8 @@ static void gp_brush_clone_adjust(tGP_BrushEditData *gso)
float influence;
/* compute influence on point */
- gp_point_to_xy(&gso->gsc, gps, pt, &sco[0], &sco[1]);
- influence = gp_brush_influence_calc(gso, gso->brush->size, sco);
+ gpencil_point_to_xy(&gso->gsc, gps, pt, &sco[0], &sco[1]);
+ influence = gpencil_brush_influence_calc(gso, gso->brush->size, sco);
/* adjust the amount of displacement to apply */
mul_v3_v3fl(delta, gso->dvec, influence);
@@ -1088,24 +1090,24 @@ static void gp_brush_clone_adjust(tGP_BrushEditData *gso)
}
/* Entrypoint for applying "clone" brush */
-static bool gpsculpt_brush_apply_clone(bContext *C, tGP_BrushEditData *gso)
+static bool gpencil_sculpt_brush_apply_clone(bContext *C, tGP_BrushEditData *gso)
{
/* Which "mode" are we operating in? */
if (gso->first) {
/* Create initial clones */
- gp_brush_clone_add(C, gso);
+ gpencil_brush_clone_add(C, gso);
}
else {
/* Stamp or Continuous Mode */
if (1 /*gso->brush->mode == GP_EDITBRUSH_CLONE_MODE_STAMP*/) {
/* Stamp - Proceed to translate the newly added strokes */
- gp_brush_clone_adjust(gso);
+ gpencil_brush_clone_adjust(gso);
}
else {
/* Continuous - Just keep pasting everytime we move */
/* TODO: The spacing of repeat should be controlled using a
* "stepsize" or similar property? */
- gp_brush_clone_add(C, gso);
+ gpencil_brush_clone_add(C, gso);
}
}
@@ -1115,7 +1117,7 @@ static bool gpsculpt_brush_apply_clone(bContext *C, tGP_BrushEditData *gso)
/* ************************************************ */
/* Header Info for GPencil Sculpt */
-static void gpsculpt_brush_header_set(bContext *C, tGP_BrushEditData *gso)
+static void gpencil_sculpt_brush_header_set(bContext *C, tGP_BrushEditData *gso)
{
Brush *brush = gso->brush;
char str[UI_MAX_DRAW_STR] = "";
@@ -1135,7 +1137,7 @@ static void gpsculpt_brush_header_set(bContext *C, tGP_BrushEditData *gso)
/* Init/Exit ----------------------------------------------- */
-static bool gpsculpt_brush_init(bContext *C, wmOperator *op)
+static bool gpencil_sculpt_brush_init(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
ToolSettings *ts = scene->toolsettings;
@@ -1151,7 +1153,7 @@ static bool gpsculpt_brush_init(bContext *C, wmOperator *op)
gso->depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
gso->bmain = CTX_data_main(C);
/* store state */
- gso->settings = gpsculpt_get_settings(scene);
+ gso->settings = gpencil_sculpt_get_settings(scene);
/* Random generator, only init once. */
uint rng_seed = (uint)(PIL_check_seconds_timer_i() & UINT_MAX);
@@ -1209,7 +1211,7 @@ static bool gpsculpt_brush_init(bContext *C, wmOperator *op)
bool found = false;
/* check that there are some usable strokes in the buffer */
- for (gps = gp_strokes_copypastebuf.first; gps; gps = gps->next) {
+ for (gps = gpencil_strokes_copypastebuf.first; gps; gps = gps->next) {
if (ED_gpencil_stroke_can_use(C, gps)) {
found = true;
break;
@@ -1229,7 +1231,7 @@ static bool gpsculpt_brush_init(bContext *C, wmOperator *op)
}
else {
/* initialise customdata */
- gp_brush_clone_init(C, gso);
+ gpencil_brush_clone_init(C, gso);
}
break;
}
@@ -1246,15 +1248,15 @@ static bool gpsculpt_brush_init(bContext *C, wmOperator *op)
}
/* setup space conversions */
- gp_point_conversion_init(C, &gso->gsc);
+ gpencil_point_conversion_init(C, &gso->gsc);
/* update header */
- gpsculpt_brush_header_set(C, gso);
+ gpencil_sculpt_brush_header_set(C, gso);
return true;
}
-static void gpsculpt_brush_exit(bContext *C, wmOperator *op)
+static void gpencil_sculpt_brush_exit(bContext *C, wmOperator *op)
{
tGP_BrushEditData *gso = op->customdata;
wmWindow *win = CTX_wm_window(C);
@@ -1267,13 +1269,13 @@ static void gpsculpt_brush_exit(bContext *C, wmOperator *op)
* - Keys don't need to be freed, as those are the strokes
* - Values assigned to those keys do, as they are custom structs
*/
- BLI_ghash_free(gso->stroke_customdata, NULL, gp_brush_grab_stroke_free);
+ BLI_ghash_free(gso->stroke_customdata, NULL, gpencil_brush_grab_stroke_free);
break;
}
case GPSCULPT_TOOL_CLONE: {
/* Free customdata */
- gp_brush_clone_free(gso);
+ gpencil_brush_clone_free(gso);
break;
}
@@ -1305,7 +1307,7 @@ static void gpsculpt_brush_exit(bContext *C, wmOperator *op)
}
/* poll callback for stroke sculpting operator(s) */
-static bool gpsculpt_brush_poll(bContext *C)
+static bool gpencil_sculpt_brush_poll(bContext *C)
{
ScrArea *area = CTX_wm_area(C);
if (area && area->spacetype != SPACE_VIEW3D) {
@@ -1318,7 +1320,7 @@ static bool gpsculpt_brush_poll(bContext *C)
/* Init Sculpt Stroke ---------------------------------- */
-static void gpsculpt_brush_init_stroke(bContext *C, tGP_BrushEditData *gso)
+static void gpencil_sculpt_brush_init_stroke(bContext *C, tGP_BrushEditData *gso)
{
bGPdata *gpd = gso->gpd;
@@ -1360,10 +1362,10 @@ static void gpsculpt_brush_init_stroke(bContext *C, tGP_BrushEditData *gso)
* For strokes with one point only this is impossible to calculate because there isn't a
* valid reference point.
*/
-static float gpsculpt_rotation_eval_get(tGP_BrushEditData *gso,
- bGPDstroke *gps_eval,
- bGPDspoint *pt_eval,
- int idx_eval)
+static float gpencil_sculpt_rotation_eval_get(tGP_BrushEditData *gso,
+ bGPDstroke *gps_eval,
+ bGPDspoint *pt_eval,
+ int idx_eval)
{
/* If multiframe or no modifiers, return 0. */
if ((GPENCIL_MULTIEDIT_SESSIONS_ON(gso->gpd)) || (!gso->is_transformed)) {
@@ -1402,22 +1404,22 @@ static float gpsculpt_rotation_eval_get(tGP_BrushEditData *gso,
/* create 2D vectors of the stroke segments */
float v_orig_a[2], v_orig_b[2], v_eval_a[2], v_eval_b[2];
- gp_point_3d_to_xy(gsc, GP_STROKE_3DSPACE, &pt_orig->x, v_orig_a);
- gp_point_3d_to_xy(gsc, GP_STROKE_3DSPACE, &pt_orig_prev->x, v_orig_b);
+ gpencil_point_3d_to_xy(gsc, GP_STROKE_3DSPACE, &pt_orig->x, v_orig_a);
+ gpencil_point_3d_to_xy(gsc, GP_STROKE_3DSPACE, &pt_orig_prev->x, v_orig_b);
sub_v2_v2(v_orig_a, v_orig_b);
- gp_point_3d_to_xy(gsc, GP_STROKE_3DSPACE, &pt_eval->x, v_eval_a);
- gp_point_3d_to_xy(gsc, GP_STROKE_3DSPACE, &pt_prev_eval->x, v_eval_b);
+ gpencil_point_3d_to_xy(gsc, GP_STROKE_3DSPACE, &pt_eval->x, v_eval_a);
+ gpencil_point_3d_to_xy(gsc, GP_STROKE_3DSPACE, &pt_prev_eval->x, v_eval_b);
sub_v2_v2(v_eval_a, v_eval_b);
return angle_v2v2(v_orig_a, v_eval_a);
}
/* Apply brush operation to points in this stroke */
-static bool gpsculpt_brush_do_stroke(tGP_BrushEditData *gso,
- bGPDstroke *gps,
- const float diff_mat[4][4],
- GP_BrushApplyCb apply)
+static bool gpencil_sculpt_brush_do_stroke(tGP_BrushEditData *gso,
+ bGPDstroke *gps,
+ const float diff_mat[4][4],
+ GP_BrushApplyCb apply)
{
GP_SpaceConversion *gsc = &gso->gsc;
rcti *rect = &gso->brush_rect;
@@ -1447,8 +1449,8 @@ static bool gpsculpt_brush_do_stroke(tGP_BrushEditData *gso,
if (gps->totpoints == 1) {
bGPDspoint pt_temp;
pt = &gps->points[0];
- gp_point_to_parent_space(gps->points, diff_mat, &pt_temp);
- gp_point_to_xy(gsc, gps, &pt_temp, &pc1[0], &pc1[1]);
+ gpencil_point_to_parent_space(gps->points, diff_mat, &pt_temp);
+ gpencil_point_to_xy(gsc, gps, &pt_temp, &pc1[0], &pc1[1]);
pt_active = (pt->runtime.pt_orig) ? pt->runtime.pt_orig : pt;
/* do boundbox check first */
@@ -1459,7 +1461,7 @@ static bool gpsculpt_brush_do_stroke(tGP_BrushEditData *gso,
if (len_v2v2_int(mval_i, pc1) <= radius) {
/* apply operation to this point */
if (pt_active != NULL) {
- rot_eval = gpsculpt_rotation_eval_get(gso, gps, pt, 0);
+ rot_eval = gpencil_sculpt_rotation_eval_get(gso, gps, pt, 0);
changed = apply(gso, gps_active, rot_eval, 0, radius, pc1);
}
}
@@ -1483,11 +1485,11 @@ static bool gpsculpt_brush_do_stroke(tGP_BrushEditData *gso,
}
}
bGPDspoint npt;
- gp_point_to_parent_space(pt1, diff_mat, &npt);
- gp_point_to_xy(gsc, gps, &npt, &pc1[0], &pc1[1]);
+ gpencil_point_to_parent_space(pt1, diff_mat, &npt);
+ gpencil_point_to_xy(gsc, gps, &npt, &pc1[0], &pc1[1]);
- gp_point_to_parent_space(pt2, diff_mat, &npt);
- gp_point_to_xy(gsc, gps, &npt, &pc2[0], &pc2[1]);
+ gpencil_point_to_parent_space(pt2, diff_mat, &npt);
+ gpencil_point_to_xy(gsc, gps, &npt, &pc2[0], &pc2[1]);
/* Check that point segment of the boundbox of the selection stroke */
if (((!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1])) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) ||
@@ -1496,7 +1498,7 @@ static bool gpsculpt_brush_do_stroke(tGP_BrushEditData *gso,
* brush region (either within stroke painted, or on its lines)
* - this assumes that linewidth is irrelevant
*/
- if (gp_stroke_inside_circle(gso->mval, radius, pc1[0], pc1[1], pc2[0], pc2[1])) {
+ if (gpencil_stroke_inside_circle(gso->mval, radius, pc1[0], pc1[1], pc2[0], pc2[1])) {
/* Apply operation to these points */
bool ok = false;
@@ -1513,7 +1515,7 @@ static bool gpsculpt_brush_do_stroke(tGP_BrushEditData *gso,
}
index = (pt->runtime.pt_orig) ? pt->runtime.idx_orig : i;
if ((pt_active != NULL) && (index < gps_active->totpoints)) {
- rot_eval = gpsculpt_rotation_eval_get(gso, gps, pt, i);
+ rot_eval = gpencil_sculpt_rotation_eval_get(gso, gps, pt, i);
ok = apply(gso, gps_active, rot_eval, index, radius, pc1);
}
@@ -1530,7 +1532,7 @@ static bool gpsculpt_brush_do_stroke(tGP_BrushEditData *gso,
pt_active = (pt->runtime.pt_orig) ? pt->runtime.pt_orig : pt;
index = (pt->runtime.pt_orig) ? pt->runtime.idx_orig : i + 1;
if ((pt_active != NULL) && (index < gps_active->totpoints)) {
- rot_eval = gpsculpt_rotation_eval_get(gso, gps, pt, i + 1);
+ rot_eval = gpencil_sculpt_rotation_eval_get(gso, gps, pt, i + 1);
ok |= apply(gso, gps_active, rot_eval, index, radius, pc2);
include_last = false;
}
@@ -1551,7 +1553,7 @@ static bool gpsculpt_brush_do_stroke(tGP_BrushEditData *gso,
pt_active = (pt->runtime.pt_orig) ? pt->runtime.pt_orig : pt;
index = (pt->runtime.pt_orig) ? pt->runtime.idx_orig : i;
if ((pt_active != NULL) && (index < gps_active->totpoints)) {
- rot_eval = gpsculpt_rotation_eval_get(gso, gps, pt, i);
+ rot_eval = gpencil_sculpt_rotation_eval_get(gso, gps, pt, i);
changed |= apply(gso, gps_active, rot_eval, index, radius, pc1);
include_last = false;
}
@@ -1564,11 +1566,11 @@ static bool gpsculpt_brush_do_stroke(tGP_BrushEditData *gso,
}
/* Apply sculpt brushes to strokes in the given frame */
-static bool gpsculpt_brush_do_frame(bContext *C,
- tGP_BrushEditData *gso,
- bGPDlayer *gpl,
- bGPDframe *gpf,
- const float diff_mat[4][4])
+static bool gpencil_sculpt_brush_do_frame(bContext *C,
+ tGP_BrushEditData *gso,
+ bGPDlayer *gpl,
+ bGPDframe *gpf,
+ const float diff_mat[4][4])
{
bool changed = false;
bool redo_geom = false;
@@ -1588,20 +1590,22 @@ static bool gpsculpt_brush_do_frame(bContext *C,
switch (tool) {
case GPSCULPT_TOOL_SMOOTH: /* Smooth strokes */
{
- changed |= gpsculpt_brush_do_stroke(gso, gps, diff_mat, gp_brush_smooth_apply);
+ changed |= gpencil_sculpt_brush_do_stroke(gso, gps, diff_mat, gpencil_brush_smooth_apply);
redo_geom |= changed;
break;
}
case GPSCULPT_TOOL_THICKNESS: /* Adjust stroke thickness */
{
- changed |= gpsculpt_brush_do_stroke(gso, gps, diff_mat, gp_brush_thickness_apply);
+ changed |= gpencil_sculpt_brush_do_stroke(
+ gso, gps, diff_mat, gpencil_brush_thickness_apply);
break;
}
case GPSCULPT_TOOL_STRENGTH: /* Adjust stroke color strength */
{
- changed |= gpsculpt_brush_do_stroke(gso, gps, diff_mat, gp_brush_strength_apply);
+ changed |= gpencil_sculpt_brush_do_stroke(
+ gso, gps, diff_mat, gpencil_brush_strength_apply);
break;
}
@@ -1614,13 +1618,13 @@ static bool gpsculpt_brush_do_frame(bContext *C,
* 1) Prepare data buffers (init/clear) for this stroke
* 2) Use the points now under the cursor
*/
- gp_brush_grab_stroke_init(gso, gps_active);
- changed |= gpsculpt_brush_do_stroke(
- gso, gps_active, diff_mat, gp_brush_grab_store_points);
+ gpencil_brush_grab_stroke_init(gso, gps_active);
+ changed |= gpencil_sculpt_brush_do_stroke(
+ gso, gps_active, diff_mat, gpencil_brush_grab_store_points);
}
else {
/* Apply effect to the stored points */
- gp_brush_grab_apply_cached(gso, gps_active, diff_mat);
+ gpencil_brush_grab_apply_cached(gso, gps_active, diff_mat);
changed |= true;
}
}
@@ -1630,28 +1634,29 @@ static bool gpsculpt_brush_do_frame(bContext *C,
case GPSCULPT_TOOL_PUSH: /* Push points */
{
- changed |= gpsculpt_brush_do_stroke(gso, gps, diff_mat, gp_brush_push_apply);
+ changed |= gpencil_sculpt_brush_do_stroke(gso, gps, diff_mat, gpencil_brush_push_apply);
redo_geom |= changed;
break;
}
case GPSCULPT_TOOL_PINCH: /* Pinch points */
{
- changed |= gpsculpt_brush_do_stroke(gso, gps, diff_mat, gp_brush_pinch_apply);
+ changed |= gpencil_sculpt_brush_do_stroke(gso, gps, diff_mat, gpencil_brush_pinch_apply);
redo_geom |= changed;
break;
}
case GPSCULPT_TOOL_TWIST: /* Twist points around midpoint */
{
- changed |= gpsculpt_brush_do_stroke(gso, gps, diff_mat, gp_brush_twist_apply);
+ changed |= gpencil_sculpt_brush_do_stroke(gso, gps, diff_mat, gpencil_brush_twist_apply);
redo_geom |= changed;
break;
}
case GPSCULPT_TOOL_RANDOMIZE: /* Apply jitter */
{
- changed |= gpsculpt_brush_do_stroke(gso, gps, diff_mat, gp_brush_randomize_apply);
+ changed |= gpencil_sculpt_brush_do_stroke(
+ gso, gps, diff_mat, gpencil_brush_randomize_apply);
redo_geom |= changed;
break;
}
@@ -1685,7 +1690,7 @@ static bool gpsculpt_brush_do_frame(bContext *C,
}
/* Perform two-pass brushes which modify the existing strokes */
-static bool gpsculpt_brush_apply_standard(bContext *C, tGP_BrushEditData *gso)
+static bool gpencil_sculpt_brush_apply_standard(bContext *C, tGP_BrushEditData *gso)
{
ToolSettings *ts = gso->scene->toolsettings;
Depsgraph *depsgraph = gso->depsgraph;
@@ -1703,7 +1708,7 @@ static bool gpsculpt_brush_apply_standard(bContext *C, tGP_BrushEditData *gso)
{
/* calculate amount of displacement to apply */
gso->rot_eval = 0.0f;
- gp_brush_grab_calc_dvec(gso);
+ gpencil_brush_grab_calc_dvec(gso);
break;
}
@@ -1711,7 +1716,7 @@ static bool gpsculpt_brush_apply_standard(bContext *C, tGP_BrushEditData *gso)
case GPSCULPT_TOOL_TWIST: /* Twist points around midpoint */
{
/* calculate midpoint of the brush (in data space) */
- gp_brush_calc_midpoint(gso);
+ gpencil_brush_calc_midpoint(gso);
break;
}
@@ -1719,7 +1724,7 @@ static bool gpsculpt_brush_apply_standard(bContext *C, tGP_BrushEditData *gso)
{
/* compute the displacement vector for the cursor (in data space) */
gso->rot_eval = 0.0f;
- gp_brush_grab_calc_dvec(gso);
+ gpencil_brush_grab_calc_dvec(gso);
break;
}
@@ -1764,7 +1769,7 @@ static bool gpsculpt_brush_apply_standard(bContext *C, tGP_BrushEditData *gso)
}
/* affect strokes in this frame */
- changed |= gpsculpt_brush_do_frame(C, gso, gpl, gpf, diff_mat);
+ changed |= gpencil_sculpt_brush_do_frame(C, gso, gpl, gpf, diff_mat);
}
}
}
@@ -1772,7 +1777,7 @@ static bool gpsculpt_brush_apply_standard(bContext *C, tGP_BrushEditData *gso)
if (gpl->actframe != NULL) {
/* Apply to active frame's strokes */
gso->mf_falloff = 1.0f;
- changed |= gpsculpt_brush_do_frame(C, gso, gpl, gpl->actframe, diff_mat);
+ changed |= gpencil_sculpt_brush_do_frame(C, gso, gpl, gpl->actframe, diff_mat);
}
}
}
@@ -1781,7 +1786,7 @@ static bool gpsculpt_brush_apply_standard(bContext *C, tGP_BrushEditData *gso)
}
/* Calculate settings for applying brush */
-static void gpsculpt_brush_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
+static void gpencil_sculpt_brush_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
{
tGP_BrushEditData *gso = op->customdata;
Brush *brush = gso->brush;
@@ -1821,10 +1826,10 @@ static void gpsculpt_brush_apply(bContext *C, wmOperator *op, PointerRNA *itempt
/* Apply brush */
char tool = gso->brush->gpencil_sculpt_tool;
if (tool == GPSCULPT_TOOL_CLONE) {
- changed = gpsculpt_brush_apply_clone(C, gso);
+ changed = gpencil_sculpt_brush_apply_clone(C, gso);
}
else {
- changed = gpsculpt_brush_apply_standard(C, gso);
+ changed = gpencil_sculpt_brush_apply_standard(C, gso);
}
/* Updates */
@@ -1841,7 +1846,7 @@ static void gpsculpt_brush_apply(bContext *C, wmOperator *op, PointerRNA *itempt
}
/* Running --------------------------------------------- */
-static Brush *gpsculpt_get_smooth_brush(tGP_BrushEditData *gso)
+static Brush *gpencil_sculpt_get_smooth_brush(tGP_BrushEditData *gso)
{
Main *bmain = gso->bmain;
Brush *brush = BLI_findstring(&bmain->brushes, "Smooth Stroke", offsetof(ID, name) + 2);
@@ -1850,7 +1855,7 @@ static Brush *gpsculpt_get_smooth_brush(tGP_BrushEditData *gso)
}
/* helper - a record stroke, and apply paint event */
-static void gpsculpt_brush_apply_event(bContext *C, wmOperator *op, const wmEvent *event)
+static void gpencil_sculpt_brush_apply_event(bContext *C, wmOperator *op, const wmEvent *event)
{
tGP_BrushEditData *gso = op->customdata;
PointerRNA itemptr;
@@ -1878,7 +1883,7 @@ static void gpsculpt_brush_apply_event(bContext *C, wmOperator *op, const wmEven
if (event->shift) {
gso->brush_prev = gso->brush;
- gso->brush = gpsculpt_get_smooth_brush(gso);
+ gso->brush = gpencil_sculpt_get_smooth_brush(gso);
if (gso->brush == NULL) {
gso->brush = gso->brush_prev;
}
@@ -1890,28 +1895,28 @@ static void gpsculpt_brush_apply_event(bContext *C, wmOperator *op, const wmEven
}
/* apply */
- gpsculpt_brush_apply(C, op, &itemptr);
+ gpencil_sculpt_brush_apply(C, op, &itemptr);
}
/* reapply */
-static int gpsculpt_brush_exec(bContext *C, wmOperator *op)
+static int gpencil_sculpt_brush_exec(bContext *C, wmOperator *op)
{
- if (!gpsculpt_brush_init(C, op)) {
+ if (!gpencil_sculpt_brush_init(C, op)) {
return OPERATOR_CANCELLED;
}
RNA_BEGIN (op->ptr, itemptr, "stroke") {
- gpsculpt_brush_apply(C, op, &itemptr);
+ gpencil_sculpt_brush_apply(C, op, &itemptr);
}
RNA_END;
- gpsculpt_brush_exit(C, op);
+ gpencil_sculpt_brush_exit(C, op);
return OPERATOR_FINISHED;
}
/* start modal painting */
-static int gpsculpt_brush_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+static int gpencil_sculpt_brush_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
tGP_BrushEditData *gso = NULL;
const bool is_modal = RNA_boolean_get(op->ptr, "wait_for_input");
@@ -1927,7 +1932,7 @@ static int gpsculpt_brush_invoke(bContext *C, wmOperator *op, const wmEvent *eve
}
/* init painting data */
- if (!gpsculpt_brush_init(C, op)) {
+ if (!gpencil_sculpt_brush_init(C, op)) {
return OPERATOR_CANCELLED;
}
@@ -1974,11 +1979,11 @@ static int gpsculpt_brush_invoke(bContext *C, wmOperator *op, const wmEvent *eve
ARegion *region = CTX_wm_region(C);
/* ensure that we'll have a new frame to draw on */
- gpsculpt_brush_init_stroke(C, gso);
+ gpencil_sculpt_brush_init_stroke(C, gso);
/* apply first dab... */
gso->is_painting = true;
- gpsculpt_brush_apply_event(C, op, event);
+ gpencil_sculpt_brush_apply_event(C, op, event);
/* redraw view with feedback */
ED_region_tag_redraw(region);
@@ -1988,7 +1993,7 @@ static int gpsculpt_brush_invoke(bContext *C, wmOperator *op, const wmEvent *eve
}
/* painting - handle events */
-static int gpsculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent *event)
+static int gpencil_sculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
tGP_BrushEditData *gso = op->customdata;
const bool is_modal = RNA_boolean_get(op->ptr, "wait_for_input");
@@ -2003,7 +2008,7 @@ static int gpsculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent *even
case MOUSEMOVE:
case INBETWEEN_MOUSEMOVE:
/* apply brush effect at new position */
- gpsculpt_brush_apply_event(C, op, event);
+ gpencil_sculpt_brush_apply_event(C, op, event);
/* force redraw, so that the cursor will at least be valid */
redraw_region = true;
@@ -2013,7 +2018,7 @@ static int gpsculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent *even
case TIMER:
if (event->customdata == gso->timer) {
gso->timerTick = true;
- gpsculpt_brush_apply_event(C, op, event);
+ gpencil_sculpt_brush_apply_event(C, op, event);
gso->timerTick = false;
}
break;
@@ -2029,7 +2034,7 @@ static int gpsculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent *even
/* end sculpt session, since we're not modal */
gso->is_painting = false;
- gpsculpt_brush_exit(C, op);
+ gpencil_sculpt_brush_exit(C, op);
return OPERATOR_FINISHED;
}
break;
@@ -2038,7 +2043,7 @@ static int gpsculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent *even
case MIDDLEMOUSE:
case RIGHTMOUSE:
case EVT_ESCKEY:
- gpsculpt_brush_exit(C, op);
+ gpencil_sculpt_brush_exit(C, op);
return OPERATOR_FINISHED;
}
}
@@ -2053,14 +2058,14 @@ static int gpsculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent *even
gso->is_painting = true;
gso->first = true;
- gpsculpt_brush_init_stroke(C, gso);
- gpsculpt_brush_apply_event(C, op, event);
+ gpencil_sculpt_brush_init_stroke(C, gso);
+ gpencil_sculpt_brush_apply_event(C, op, event);
break;
/* Exit modal operator, based on the "standard" ops */
case RIGHTMOUSE:
case EVT_ESCKEY:
- gpsculpt_brush_exit(C, op);
+ gpencil_sculpt_brush_exit(C, op);
return OPERATOR_FINISHED;
/* MMB is often used for view manipulations */
@@ -2124,11 +2129,11 @@ void GPENCIL_OT_sculpt_paint(wmOperatorType *ot)
ot->description = "Apply tweaks to strokes by painting over the strokes"; // XXX
/* api callbacks */
- ot->exec = gpsculpt_brush_exec;
- ot->invoke = gpsculpt_brush_invoke;
- ot->modal = gpsculpt_brush_modal;
- ot->cancel = gpsculpt_brush_exit;
- ot->poll = gpsculpt_brush_poll;
+ ot->exec = gpencil_sculpt_brush_exec;
+ ot->invoke = gpencil_sculpt_brush_invoke;
+ ot->modal = gpencil_sculpt_brush_modal;
+ ot->cancel = gpencil_sculpt_brush_exit;
+ ot->poll = gpencil_sculpt_brush_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
diff --git a/source/blender/editors/gpencil/gpencil_select.c b/source/blender/editors/gpencil/gpencil_select.c
index c41b2993a80..ea6f53d24bb 100644
--- a/source/blender/editors/gpencil/gpencil_select.c
+++ b/source/blender/editors/gpencil/gpencil_select.c
@@ -369,7 +369,7 @@ typedef enum eGP_SelectGrouped {
/* ----------------------------------- */
/* On each visible layer, check for selected strokes - if found, select all others */
-static void gp_select_same_layer(bContext *C)
+static void gpencil_select_same_layer(bContext *C)
{
Scene *scene = CTX_data_scene(C);
@@ -412,7 +412,7 @@ static void gp_select_same_layer(bContext *C)
}
/* Select all strokes with same colors as selected ones */
-static void gp_select_same_material(bContext *C)
+static void gpencil_select_same_material(bContext *C)
{
/* First, build set containing all the colors of selected strokes */
GSet *selected_colors = BLI_gset_str_new("GP Selected Colors");
@@ -462,10 +462,10 @@ static int gpencil_select_grouped_exec(bContext *C, wmOperator *op)
switch (mode) {
case GP_SEL_SAME_LAYER:
- gp_select_same_layer(C);
+ gpencil_select_same_layer(C);
break;
case GP_SEL_SAME_MATERIAL:
- gp_select_same_material(C);
+ gpencil_select_same_material(C);
break;
default:
@@ -853,142 +853,87 @@ void GPENCIL_OT_select_less(wmOperatorType *ot)
* Helper to check if a given stroke is within the area.
*
* \note Code here is adapted (i.e. copied directly)
- * from gpencil_paint.c #gp_stroke_eraser_dostroke().
+ * from gpencil_paint.c #gpencil_stroke_eraser_dostroke().
* It would be great to de-duplicate the logic here sometime, but that can wait.
*/
-static bool gp_stroke_do_circle_sel(bGPdata *UNUSED(gpd),
- bGPDlayer *gpl,
- bGPDstroke *gps,
- GP_SpaceConversion *gsc,
- const int mx,
- const int my,
- const int radius,
- const bool select,
- rcti *rect,
- const float diff_mat[4][4],
- const int selectmode,
- const float scale)
+static bool gpencil_stroke_do_circle_sel(bGPdata *UNUSED(gpd),
+ bGPDlayer *gpl,
+ bGPDstroke *gps,
+ GP_SpaceConversion *gsc,
+ const int mx,
+ const int my,
+ const int radius,
+ const bool select,
+ rcti *rect,
+ const float diff_mat[4][4],
+ const int selectmode,
+ const float scale)
{
- bGPDspoint *pt1 = NULL;
- bGPDspoint *pt2 = NULL;
- int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
+ bGPDspoint *pt = NULL;
+ int x0 = 0, y0 = 0;
int i;
bool changed = false;
bGPDstroke *gps_active = (gps->runtime.gps_orig) ? gps->runtime.gps_orig : gps;
bGPDspoint *pt_active = NULL;
+ bool hit = false;
+
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ pt_active = (pt->runtime.pt_orig) ? pt->runtime.pt_orig : pt;
- if (gps->totpoints == 1) {
bGPDspoint pt_temp;
- gp_point_to_parent_space(gps->points, diff_mat, &pt_temp);
- gp_point_to_xy(gsc, gps, &pt_temp, &x0, &y0);
+ gpencil_point_to_parent_space(pt_active, diff_mat, &pt_temp);
+ gpencil_point_to_xy(gsc, gps, &pt_temp, &x0, &y0);
/* do boundbox check first */
if ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(rect, x0, y0)) {
/* only check if point is inside */
if (((x0 - mx) * (x0 - mx) + (y0 - my) * (y0 - my)) <= radius * radius) {
+ hit = true;
+
/* change selection */
if (select) {
- gps_active->points->flag |= GP_SPOINT_SELECT;
+ pt_active->flag |= GP_SPOINT_SELECT;
gps_active->flag |= GP_STROKE_SELECT;
}
else {
- gps_active->points->flag &= ~GP_SPOINT_SELECT;
+ pt_active->flag &= ~GP_SPOINT_SELECT;
gps_active->flag &= ~GP_STROKE_SELECT;
}
+ changed = true;
+ /* if stroke mode, don't check more points */
+ if ((hit) && (selectmode == GP_SELECTMODE_STROKE)) {
+ break;
+ }
- return true;
- }
- }
- }
- else {
- /* Loop over the points in the stroke, checking for intersections
- * - an intersection means that we touched the stroke
- */
- bool hit = false;
- for (i = 0; (i + 1) < gps->totpoints; i++) {
- /* get points to work with */
- pt1 = gps->points + i;
- pt2 = gps->points + i + 1;
- bGPDspoint npt;
- gp_point_to_parent_space(pt1, diff_mat, &npt);
- gp_point_to_xy(gsc, gps, &npt, &x0, &y0);
-
- gp_point_to_parent_space(pt2, diff_mat, &npt);
- gp_point_to_xy(gsc, gps, &npt, &x1, &y1);
-
- /* check that point segment of the boundbox of the selection stroke */
- if (((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(rect, x0, y0)) ||
- ((!ELEM(V2D_IS_CLIPPED, x1, y1)) && BLI_rcti_isect_pt(rect, x1, y1))) {
- float mval[2] = {(float)mx, (float)my};
-
- /* check if point segment of stroke had anything to do with
- * eraser region (either within stroke painted, or on its lines)
- * - this assumes that linewidth is irrelevant
- */
- if (gp_stroke_inside_circle(mval, radius, x0, y0, x1, y1)) {
- /* change selection of stroke, and then of both points
- * (as the last point otherwise wouldn't get selected
- * as we only do n-1 loops through).
- */
- hit = true;
- if (select) {
- pt_active = pt1->runtime.pt_orig;
- if (pt_active != NULL) {
- pt_active->flag |= GP_SPOINT_SELECT;
- }
- pt_active = pt2->runtime.pt_orig;
- if (pt_active != NULL) {
- pt_active->flag |= GP_SPOINT_SELECT;
- }
- changed = true;
- }
- else {
- pt_active = pt1->runtime.pt_orig;
- if (pt_active != NULL) {
- pt_active->flag &= ~GP_SPOINT_SELECT;
- }
- pt_active = pt2->runtime.pt_orig;
- if (pt_active != NULL) {
- pt_active->flag &= ~GP_SPOINT_SELECT;
- }
- changed = true;
- }
+ /* Expand selection to segment. */
+ if ((hit) && (selectmode == GP_SELECTMODE_SEGMENT) && (select) && (pt_active != NULL)) {
+ float r_hita[3], r_hitb[3];
+ bool hit_select = (bool)(pt_active->flag & GP_SPOINT_SELECT);
+ ED_gpencil_select_stroke_segment(
+ gpl, gps_active, pt_active, hit_select, false, scale, r_hita, r_hitb);
}
}
- /* if stroke mode, don't check more points */
- if ((hit) && (selectmode == GP_SELECTMODE_STROKE)) {
- break;
- }
}
+ }
- /* if stroke mode expand selection */
- if ((hit) && (selectmode == GP_SELECTMODE_STROKE)) {
- for (i = 0, pt1 = gps->points; i < gps->totpoints; i++, pt1++) {
- pt_active = (pt1->runtime.pt_orig) ? pt1->runtime.pt_orig : pt1;
- if (pt_active != NULL) {
- if (select) {
- pt_active->flag |= GP_SPOINT_SELECT;
- }
- else {
- pt_active->flag &= ~GP_SPOINT_SELECT;
- }
+ /* If stroke mode expand selection. */
+ if ((hit) && (selectmode == GP_SELECTMODE_STROKE)) {
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ pt_active = (pt->runtime.pt_orig) ? pt->runtime.pt_orig : pt;
+ if (pt_active != NULL) {
+ if (select) {
+ pt_active->flag |= GP_SPOINT_SELECT;
+ }
+ else {
+ pt_active->flag &= ~GP_SPOINT_SELECT;
}
}
}
-
- /* expand selection to segment */
- pt_active = (pt1->runtime.pt_orig) ? pt1->runtime.pt_orig : pt1;
- if ((hit) && (selectmode == GP_SELECTMODE_SEGMENT) && (select) && (pt_active != NULL)) {
- float r_hita[3], r_hitb[3];
- bool hit_select = (bool)(pt1->flag & GP_SPOINT_SELECT);
- ED_gpencil_select_stroke_segment(
- gpl, gps_active, pt_active, hit_select, false, scale, r_hita, r_hitb);
- }
-
- /* Ensure that stroke selection is in sync with its points */
- BKE_gpencil_stroke_sync_selection(gps_active);
}
+ /* Ensure that stroke selection is in sync with its points. */
+ BKE_gpencil_stroke_sync_selection(gps_active);
+
return changed;
}
@@ -1043,7 +988,7 @@ static int gpencil_circle_select_exec(bContext *C, wmOperator *op)
}
/* init space conversion stuff */
- gp_point_conversion_init(C, &gsc);
+ gpencil_point_conversion_init(C, &gsc);
/* rect is rectangle of selection circle */
rect.xmin = mx - radius;
@@ -1053,18 +998,18 @@ static int gpencil_circle_select_exec(bContext *C, wmOperator *op)
/* find visible strokes, and select if hit */
GP_EVALUATED_STROKES_BEGIN (gpstroke_iter, C, gpl, gps) {
- changed |= gp_stroke_do_circle_sel(gpd,
- gpl,
- gps,
- &gsc,
- mx,
- my,
- radius,
- select,
- &rect,
- gpstroke_iter.diff_mat,
- selectmode,
- scale);
+ changed |= gpencil_stroke_do_circle_sel(gpd,
+ gpl,
+ gps,
+ &gsc,
+ mx,
+ my,
+ radius,
+ select,
+ &rect,
+ gpstroke_iter.diff_mat,
+ selectmode,
+ scale);
}
GP_EVALUATED_STROKES_END(gpstroke_iter);
@@ -1157,7 +1102,7 @@ static int gpencil_generic_select_exec(
}
/* init space conversion stuff */
- gp_point_conversion_init(C, &gsc);
+ gpencil_point_conversion_init(C, &gsc);
/* deselect all strokes first? */
if (SEL_OP_USE_PRE_DESELECT(sel_op) || (GPENCIL_PAINT_MODE(gpd))) {
@@ -1255,7 +1200,7 @@ static int gpencil_generic_select_exec(
/* if paint mode,delete selected points */
if (GPENCIL_PAINT_MODE(gpd)) {
- gp_delete_selected_point_wrap(C);
+ gpencil_delete_selected_point_wrap(C);
changed = true;
DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
}
@@ -1292,8 +1237,8 @@ static bool gpencil_test_box(bGPDstroke *gps,
const struct GP_SelectBoxUserData *data = user_data;
bGPDspoint pt2;
int x0, y0;
- gp_point_to_parent_space(pt, diff_mat, &pt2);
- gp_point_to_xy(gsc, gps, &pt2, &x0, &y0);
+ gpencil_point_to_parent_space(pt, diff_mat, &pt2);
+ gpencil_point_to_xy(gsc, gps, &pt2, &x0, &y0);
return ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(&data->rect, x0, y0));
}
@@ -1349,8 +1294,8 @@ static bool gpencil_test_lasso(bGPDstroke *gps,
const struct GP_SelectLassoUserData *data = user_data;
bGPDspoint pt2;
int x0, y0;
- gp_point_to_parent_space(pt, diff_mat, &pt2);
- gp_point_to_xy(gsc, gps, &pt2, &x0, &y0);
+ gpencil_point_to_parent_space(pt, diff_mat, &pt2);
+ gpencil_point_to_xy(gsc, gps, &pt2, &x0, &y0);
/* test if in lasso boundbox + within the lasso noose */
return ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(&data->rect, x0, y0) &&
BLI_lasso_is_point_inside(data->mcoords, data->mcoords_len, x0, y0, INT_MAX));
@@ -1431,7 +1376,6 @@ static int gpencil_select_exec(bContext *C, wmOperator *op)
bGPdata *gpd = ED_gpencil_data_get_active(C);
ToolSettings *ts = CTX_data_tool_settings(C);
const float scale = ts->gp_sculpt.isect_threshold;
- const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
/* "radius" is simply a threshold (screen space) to make it easier to test with a tolerance */
const float radius = 0.4f * U.widget_unit;
@@ -1473,7 +1417,7 @@ static int gpencil_select_exec(bContext *C, wmOperator *op)
}
/* init space conversion stuff */
- gp_point_conversion_init(C, &gsc);
+ gpencil_point_conversion_init(C, &gsc);
/* get mouse location */
RNA_int_get_array(op->ptr, "location", mval);
@@ -1484,24 +1428,13 @@ static int gpencil_select_exec(bContext *C, wmOperator *op)
bGPDspoint *pt;
int i;
- /* Check boundbox to speedup. */
- float fmval[2];
- copy_v2fl_v2i(fmval, mval);
- if (!ED_gpencil_stroke_check_collision(
- &gsc, gps_active, fmval, radius, gpstroke_iter.diff_mat)) {
- continue;
- }
-
/* firstly, check for hit-point */
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
int xy[2];
- if ((!is_multiedit) && (pt->runtime.pt_orig == NULL)) {
- continue;
- }
bGPDspoint pt2;
- gp_point_to_parent_space(pt, gpstroke_iter.diff_mat, &pt2);
- gp_point_to_xy(&gsc, gps, &pt2, &xy[0], &xy[1]);
+ gpencil_point_to_parent_space(pt, gpstroke_iter.diff_mat, &pt2);
+ gpencil_point_to_xy(&gsc, gps, &pt2, &xy[0], &xy[1]);
/* do boundbox check first */
if (!ELEM(V2D_IS_CLIPPED, xy[0], xy[1])) {
@@ -1513,27 +1446,12 @@ static int gpencil_select_exec(bContext *C, wmOperator *op)
if (pt_distance < hit_distance) {
hit_layer = gpl;
hit_stroke = gps_active;
- hit_point = (!is_multiedit) ? pt->runtime.pt_orig : pt;
+ hit_point = (pt->runtime.pt_orig) ? pt->runtime.pt_orig : pt;
hit_distance = pt_distance;
}
}
}
}
- if (ELEM(NULL, hit_stroke, hit_point)) {
- /* If nothing hit, check if the mouse is inside any filled stroke.
- * Only check filling materials. */
- MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(ob, gps->mat_nr + 1);
- if ((gp_style->flag & GP_MATERIAL_FILL_SHOW) == 0) {
- continue;
- }
- bool hit_fill = ED_gpencil_stroke_point_is_inside(gps, &gsc, mval, gpstroke_iter.diff_mat);
- if (hit_fill) {
- hit_stroke = gps_active;
- hit_point = &gps_active->points[0];
- /* Extend selection to all stroke. */
- whole = true;
- }
- }
}
GP_EVALUATED_STROKES_END(gpstroke_iter);
diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c
index 467b7ee86bf..7f77999a17b 100644
--- a/source/blender/editors/gpencil/gpencil_utils.c
+++ b/source/blender/editors/gpencil/gpencil_utils.c
@@ -94,7 +94,7 @@
/* Context Wrangling... */
/**
- * Get pointer to active Grease Pencil datablock,
+ * Get pointer to active Grease Pencil data-block,
* and an RNA-pointer to trace back to whatever owns it,
* when context info is not available.
*/
@@ -107,7 +107,7 @@ bGPdata **ED_gpencil_data_get_pointers_direct(ScrArea *area, Object *ob, Pointer
switch (area->spacetype) {
case SPACE_PROPERTIES: /* properties */
case SPACE_INFO: /* header info */
- case SPACE_TOPBAR: /* Topbar */
+ case SPACE_TOPBAR: /* Top-bar */
case SPACE_VIEW3D: /* 3D-View */
{
if (ob && (ob->type == OB_GPENCIL)) {
@@ -132,7 +132,7 @@ bGPdata **ED_gpencil_data_get_pointers_direct(ScrArea *area, Object *ob, Pointer
}
/**
- * Get pointer to active Grease Pencil datablock for annotations,
+ * Get pointer to active Grease Pencil data-block for annotations,
* and an RNA-pointer to trace back to whatever owns it,
* when context info is not available.
*/
@@ -154,7 +154,7 @@ bGPdata **ED_annotation_data_get_pointers_direct(ID *screen_id,
break;
}
- case SPACE_TOPBAR: /* Topbar */
+ case SPACE_TOPBAR: /* Top-bar */
case SPACE_VIEW3D: /* 3D-View */
{
if (r_ptr) {
@@ -237,8 +237,10 @@ bGPdata **ED_annotation_data_get_pointers_direct(ID *screen_id,
return NULL;
}
-/* Get pointer to active Grease Pencil datablock,
- * and an RNA-pointer to trace back to whatever owns it. */
+/**
+ * Get pointer to active Grease Pencil data-block,
+ * and an RNA-pointer to trace back to whatever owns it.
+ */
bGPdata **ED_gpencil_data_get_pointers(const bContext *C, PointerRNA *r_ptr)
{
ScrArea *area = CTX_wm_area(C);
@@ -247,8 +249,10 @@ bGPdata **ED_gpencil_data_get_pointers(const bContext *C, PointerRNA *r_ptr)
return ED_gpencil_data_get_pointers_direct(area, ob, r_ptr);
}
-/* Get pointer to active Grease Pencil datablock,
- * and an RNA-pointer to trace back to whatever owns it. */
+/**
+ * Get pointer to active Grease Pencil data-block,
+ * and an RNA-pointer to trace back to whatever owns it.
+ */
bGPdata **ED_annotation_data_get_pointers(const bContext *C, PointerRNA *r_ptr)
{
ID *screen_id = (ID *)CTX_wm_screen(C);
@@ -259,14 +263,14 @@ bGPdata **ED_annotation_data_get_pointers(const bContext *C, PointerRNA *r_ptr)
}
/* -------------------------------------------------------- */
-/* Get the active Grease Pencil datablock, when context is not available */
+/* Get the active Grease Pencil data-block, when context is not available */
bGPdata *ED_gpencil_data_get_active_direct(ScrArea *area, Object *ob)
{
bGPdata **gpd_ptr = ED_gpencil_data_get_pointers_direct(area, ob, NULL);
return (gpd_ptr) ? *(gpd_ptr) : NULL;
}
-/* Get the active Grease Pencil datablock, when context is not available */
+/* Get the active Grease Pencil data-block, when context is not available */
bGPdata *ED_annotation_data_get_active_direct(ID *screen_id, ScrArea *area, Scene *scene)
{
bGPdata **gpd_ptr = ED_annotation_data_get_pointers_direct(screen_id, area, scene, NULL);
@@ -274,7 +278,7 @@ bGPdata *ED_annotation_data_get_active_direct(ID *screen_id, ScrArea *area, Scen
}
/**
- * Get the active Grease Pencil datablock
+ * Get the active Grease Pencil data-block
*/
bGPdata *ED_gpencil_data_get_active(const bContext *C)
{
@@ -285,9 +289,10 @@ bGPdata *ED_gpencil_data_get_active(const bContext *C)
return ob->data;
}
-/* Get the active Grease Pencil datablock
- * \note This is the original (bmain) copy of the datablock, stored in files.
- * Do not use for reading evaluated copies of GP Objects data
+/**
+ * Get the active Grease Pencil data-block
+ * \note This is the original (#G.main) copy of the data-block, stored in files.
+ * Do not use for reading evaluated copies of GP Objects data.
*/
bGPdata *ED_annotation_data_get_active(const bContext *C)
{
@@ -295,11 +300,11 @@ bGPdata *ED_annotation_data_get_active(const bContext *C)
return (gpd_ptr) ? *(gpd_ptr) : NULL;
}
/**
- * Get the evaluated copy of the active Grease Pencil datablock (where applicable)
- * - For the 3D View (i.e. "GP Objects"), this gives the evaluated copy of the GP datablock
- * (i.e. a copy of the active GP datablock for the active object, where modifiers have been
+ * Get the evaluated copy of the active Grease Pencil data-block (where applicable)
+ * - For the 3D View (i.e. "GP Objects"), this gives the evaluated copy of the GP data-block
+ * (i.e. a copy of the active GP data-block for the active object, where modifiers have been
* applied). This is needed to correctly work with "Copy-on-Write".
- * - For all other editors (i.e. "GP Annotations"), this just gives the active datablock
+ * - For all other editors (i.e. "GP Annotations"), this just gives the active data-block
* like for #ED_gpencil_data_get_active()
*/
bGPdata *ED_gpencil_data_get_active_evaluated(const bContext *C)
@@ -322,8 +327,7 @@ bGPdata *ED_gpencil_data_get_active_evaluated(const bContext *C)
bool ED_gpencil_data_owner_is_annotation(PointerRNA *owner_ptr)
{
/* Key Assumption: If the pointer is an object, we're dealing with a GP Object's data.
- * Otherwise, the GP datablock is being used for annotations (i.e. everywhere else)
- */
+ * Otherwise, the GP data-block is being used for annotations (i.e. everywhere else). */
return ((owner_ptr) && (owner_ptr->type != &RNA_Object));
}
@@ -354,7 +358,7 @@ bool ED_gpencil_has_keyframe_v3d(Scene *UNUSED(scene), Object *ob, int cfra)
/* Poll Callbacks */
/* poll callback for adding data/layers - special */
-bool gp_add_poll(bContext *C)
+bool gpencil_add_poll(bContext *C)
{
Object *ob = CTX_data_active_object(C);
if (ob == NULL) {
@@ -366,7 +370,7 @@ bool gp_add_poll(bContext *C)
}
/* poll callback for checking if there is an active layer */
-bool gp_active_layer_poll(bContext *C)
+bool gpencil_active_layer_poll(bContext *C)
{
Object *ob = CTX_data_active_object(C);
if ((ob == NULL) || (ob->type != OB_GPENCIL)) {
@@ -379,7 +383,7 @@ bool gp_active_layer_poll(bContext *C)
}
/* poll callback for checking if there is an active brush */
-bool gp_active_brush_poll(bContext *C)
+bool gpencil_active_brush_poll(bContext *C)
{
ToolSettings *ts = CTX_data_tool_settings(C);
Paint *paint = &ts->gp_paint->paint;
@@ -527,13 +531,12 @@ const EnumPropertyItem *ED_gpencil_material_enum_itemf(bContext *C,
* Check whether a given stroke segment is inside a circular brush
*
* \param mval: The current screen-space coordinates (midpoint) of the brush
- * \param mvalo: The previous screen-space coordinates (midpoint) of the brush (NOT CURRENTLY USED)
* \param rad: The radius of the brush
*
* \param x0, y0: The screen-space x and y coordinates of the start of the stroke segment
* \param x1, y1: The screen-space x and y coordinates of the end of the stroke segment
*/
-bool gp_stroke_inside_circle(const float mval[2], int rad, int x0, int y0, int x1, int y1)
+bool gpencil_stroke_inside_circle(const float mval[2], int rad, int x0, int y0, int x1, int y1)
{
/* simple within-radius check for now */
const float screen_co_a[2] = {x0, y0};
@@ -611,7 +614,7 @@ bool ED_gpencil_stroke_color_use(Object *ob, const bGPDlayer *gpl, const bGPDstr
*
* \param r_gsc: [out] The space conversion settings struct, populated with necessary params
*/
-void gp_point_conversion_init(bContext *C, GP_SpaceConversion *r_gsc)
+void gpencil_point_conversion_init(bContext *C, GP_SpaceConversion *r_gsc)
{
ScrArea *area = CTX_wm_area(C);
ARegion *region = CTX_wm_region(C);
@@ -658,7 +661,9 @@ void gp_point_conversion_init(bContext *C, GP_SpaceConversion *r_gsc)
* \param diff_mat: Matrix with the difference between original parent matrix
* \param[out] r_pt: Pointer to new point after apply matrix
*/
-void gp_point_to_parent_space(const bGPDspoint *pt, const float diff_mat[4][4], bGPDspoint *r_pt)
+void gpencil_point_to_parent_space(const bGPDspoint *pt,
+ const float diff_mat[4][4],
+ bGPDspoint *r_pt)
{
float fpt[3];
@@ -669,7 +674,7 @@ void gp_point_to_parent_space(const bGPDspoint *pt, const float diff_mat[4][4],
/**
* Change position relative to parent object
*/
-void gp_apply_parent(Depsgraph *depsgraph, Object *obact, bGPDlayer *gpl, bGPDstroke *gps)
+void gpencil_apply_parent(Depsgraph *depsgraph, Object *obact, bGPDlayer *gpl, bGPDstroke *gps)
{
bGPDspoint *pt;
int i;
@@ -692,7 +697,10 @@ void gp_apply_parent(Depsgraph *depsgraph, Object *obact, bGPDlayer *gpl, bGPDst
/**
* Change point position relative to parent object
*/
-void gp_apply_parent_point(Depsgraph *depsgraph, Object *obact, bGPDlayer *gpl, bGPDspoint *pt)
+void gpencil_apply_parent_point(Depsgraph *depsgraph,
+ Object *obact,
+ bGPDlayer *gpl,
+ bGPDspoint *pt)
{
/* undo matrix */
float diff_mat[4][4];
@@ -715,7 +723,7 @@ void gp_apply_parent_point(Depsgraph *depsgraph, Object *obact, bGPDlayer *gpl,
* \warning This assumes that the caller has already checked
* whether the stroke in question can be drawn.
*/
-void gp_point_to_xy(
+void gpencil_point_to_xy(
const GP_SpaceConversion *gsc, const bGPDstroke *gps, const bGPDspoint *pt, int *r_x, int *r_y)
{
const ARegion *region = gsc->region;
@@ -760,21 +768,21 @@ void gp_point_to_xy(
/**
* Convert a Grease Pencil coordinate (i.e. can be 2D or 3D) to screenspace (2D).
*
- * Just like #gp_point_to_xy(), except the resulting coordinates are floats not ints.
+ * Just like #gpencil_point_to_xy(), except the resulting coordinates are floats not ints.
* Use this version to solve "stair-step" artifacts which may arise when
* roundtripping the calculations.
*
- * \param r_x[out]: The screen-space x-coordinate of the point.
- * \param r_y[out]: The screen-space y-coordinate of the point.
+ * \param r_x: The screen-space x-coordinate of the point.
+ * \param r_y: The screen-space y-coordinate of the point.
*
* \warning This assumes that the caller has already checked
* whether the stroke in question can be drawn.
*/
-void gp_point_to_xy_fl(const GP_SpaceConversion *gsc,
- const bGPDstroke *gps,
- const bGPDspoint *pt,
- float *r_x,
- float *r_y)
+void gpencil_point_to_xy_fl(const GP_SpaceConversion *gsc,
+ const bGPDstroke *gps,
+ const bGPDspoint *pt,
+ float *r_x,
+ float *r_y)
{
const ARegion *region = gsc->region;
const View2D *v2d = gsc->v2d;
@@ -828,12 +836,12 @@ void gp_point_to_xy_fl(const GP_SpaceConversion *gsc,
}
/**
- * generic based on gp_point_to_xy_fl
+ * generic based on gpencil_point_to_xy_fl
*/
-void gp_point_3d_to_xy(const GP_SpaceConversion *gsc,
- const short flag,
- const float pt[3],
- float xy[2])
+void gpencil_point_3d_to_xy(const GP_SpaceConversion *gsc,
+ const short flag,
+ const float pt[3],
+ float xy[2])
{
const ARegion *region = gsc->region;
const View2D *v2d = gsc->v2d;
@@ -899,10 +907,10 @@ void gp_point_3d_to_xy(const GP_SpaceConversion *gsc,
*
* \warning Assumes that it is getting called in a 3D view only.
*/
-bool gp_point_xy_to_3d(const GP_SpaceConversion *gsc,
- Scene *scene,
- const float screen_co[2],
- float r_out[3])
+bool gpencil_point_xy_to_3d(const GP_SpaceConversion *gsc,
+ Scene *scene,
+ const float screen_co[2],
+ float r_out[3])
{
const RegionView3D *rv3d = gsc->region->regiondata;
float rvec[3];
@@ -935,16 +943,16 @@ bool gp_point_xy_to_3d(const GP_SpaceConversion *gsc,
* Convert tGPspoint (temporary 2D/screenspace point data used by GP modal operators)
* to 3D coordinates.
*
- * \param point2D: The screenspace 2D point data to convert.
+ * \param point2D: The screen-space 2D point data to convert.
* \param depth: Depth array (via #ED_view3d_autodist_depth()).
- * \param[out] r_out: The resulting 2D point data.
+ * \param r_out: The resulting 2D point data.
*/
-void gp_stroke_convertcoords_tpoint(Scene *scene,
- ARegion *region,
- Object *ob,
- const tGPspoint *point2D,
- float *depth,
- float r_out[3])
+void gpencil_stroke_convertcoords_tpoint(Scene *scene,
+ ARegion *region,
+ Object *ob,
+ const tGPspoint *point2D,
+ float *depth,
+ float r_out[3])
{
ToolSettings *ts = scene->toolsettings;
@@ -982,7 +990,7 @@ void gp_stroke_convertcoords_tpoint(Scene *scene,
/**
* Get drawing reference point for conversion or projection of the stroke
- * \param[out] r_vec : Reference point found
+ * \param r_vec: Reference point found
*/
void ED_gpencil_drawing_reference_get(const Scene *scene,
const Object *ob,
@@ -1024,7 +1032,7 @@ void ED_gpencil_project_stroke_to_view(bContext *C, bGPDlayer *gpl, bGPDstroke *
float inverse_diff_mat[4][4];
/* init space conversion stuff */
- gp_point_conversion_init(C, &gsc);
+ gpencil_point_conversion_init(C, &gsc);
BKE_gpencil_parent_matrix_get(depsgraph, ob, gpl, diff_mat);
invert_m4_m4(inverse_diff_mat, diff_mat);
@@ -1034,11 +1042,11 @@ void ED_gpencil_project_stroke_to_view(bContext *C, bGPDlayer *gpl, bGPDstroke *
float xy[2];
bGPDspoint pt2;
- gp_point_to_parent_space(pt, diff_mat, &pt2);
- gp_point_to_xy_fl(&gsc, gps, &pt2, &xy[0], &xy[1]);
+ gpencil_point_to_parent_space(pt, diff_mat, &pt2);
+ gpencil_point_to_xy_fl(&gsc, gps, &pt2, &xy[0], &xy[1]);
/* Planar - All on same plane parallel to the viewplane */
- gp_point_xy_to_3d(&gsc, scene, xy, &pt->x);
+ gpencil_point_xy_to_3d(&gsc, scene, xy, &pt->x);
/* Unapply parent corrections */
mul_m4_v3(inverse_diff_mat, &pt->x);
@@ -1048,12 +1056,12 @@ void ED_gpencil_project_stroke_to_view(bContext *C, bGPDlayer *gpl, bGPDstroke *
/**
* Reproject all points of the stroke to a plane locked to axis to avoid stroke offset
*/
-void ED_gp_project_stroke_to_plane(const Scene *scene,
- const Object *ob,
- const RegionView3D *rv3d,
- bGPDstroke *gps,
- const float origin[3],
- const int axis)
+void ED_gpencil_project_stroke_to_plane(const Scene *scene,
+ const Object *ob,
+ const RegionView3D *rv3d,
+ bGPDstroke *gps,
+ const float origin[3],
+ const int axis)
{
const ToolSettings *ts = scene->toolsettings;
const View3DCursor *cursor = &scene->cursor;
@@ -1165,13 +1173,13 @@ void ED_gpencil_stroke_reproject(Depsgraph *depsgraph,
float xy[2];
/* 3D to Screen-space */
- /* Note: We can't use gp_point_to_xy() here because that uses ints for the screen-space
+ /* Note: We can't use gpencil_point_to_xy() here because that uses ints for the screen-space
* coordinates, resulting in lost precision, which in turn causes stair-stepping
* artifacts in the final points. */
bGPDspoint pt2;
- gp_point_to_parent_space(pt, diff_mat, &pt2);
- gp_point_to_xy_fl(gsc, gps_active, &pt2, &xy[0], &xy[1]);
+ gpencil_point_to_parent_space(pt, diff_mat, &pt2);
+ gpencil_point_to_xy_fl(gsc, gps_active, &pt2, &xy[0], &xy[1]);
/* Project stroke in one axis */
if (ELEM(mode, GP_REPROJECT_FRONT, GP_REPROJECT_SIDE, GP_REPROJECT_TOP, GP_REPROJECT_CURSOR)) {
@@ -1199,18 +1207,18 @@ void ED_gpencil_stroke_reproject(Depsgraph *depsgraph,
}
}
- ED_gp_project_point_to_plane(gsc->scene, gsc->ob, rv3d, origin, axis, &pt2);
+ ED_gpencil_project_point_to_plane(gsc->scene, gsc->ob, rv3d, origin, axis, &pt2);
copy_v3_v3(&pt->x, &pt2.x);
/* apply parent again */
- gp_apply_parent_point(depsgraph, gsc->ob, gpl, pt);
+ gpencil_apply_parent_point(depsgraph, gsc->ob, gpl, pt);
}
/* Project screen-space back to 3D space (from current perspective)
* so that all points have been treated the same way. */
else if (mode == GP_REPROJECT_VIEW) {
/* Planar - All on same plane parallel to the view-plane. */
- gp_point_xy_to_3d(gsc, gsc->scene, xy, &pt->x);
+ gpencil_point_xy_to_3d(gsc, gsc->scene, xy, &pt->x);
}
else {
/* Geometry - Snap to surfaces of visible geometry */
@@ -1238,7 +1246,7 @@ void ED_gpencil_stroke_reproject(Depsgraph *depsgraph,
}
else {
/* Default to planar */
- gp_point_xy_to_3d(gsc, gsc->scene, xy, &pt->x);
+ gpencil_point_xy_to_3d(gsc, gsc->scene, xy, &pt->x);
}
}
@@ -1251,14 +1259,14 @@ void ED_gpencil_stroke_reproject(Depsgraph *depsgraph,
/**
* Reproject given point to a plane locked to axis to avoid stroke offset
- * \param[in,out] pt: Point to affect
+ * \param pt: Point to affect (used for input & output).
*/
-void ED_gp_project_point_to_plane(const Scene *scene,
- const Object *ob,
- const RegionView3D *rv3d,
- const float origin[3],
- const int axis,
- bGPDspoint *pt)
+void ED_gpencil_project_point_to_plane(const Scene *scene,
+ const Object *ob,
+ const RegionView3D *rv3d,
+ const float origin[3],
+ const int axis,
+ bGPDspoint *pt)
{
const ToolSettings *ts = scene->toolsettings;
const View3DCursor *cursor = &scene->cursor;
@@ -1330,7 +1338,7 @@ void ED_gp_project_point_to_plane(const Scene *scene,
* \param gps: Stroke data
* \param subdivide: Number of times to subdivide
*/
-void gp_subdivide_stroke(bGPDstroke *gps, const int subdivide)
+void gpencil_subdivide_stroke(bGPDstroke *gps, const int subdivide)
{
bGPDspoint *temp_points;
int totnewpoints, oldtotpoints;
@@ -1730,7 +1738,7 @@ void ED_gpencil_vgroup_deselect(bContext *C, Object *ob)
/* Cursor drawing */
/* check if cursor is in drawing region */
-static bool gp_check_cursor_region(bContext *C, int mval_i[2])
+static bool gpencil_check_cursor_region(bContext *C, int mval_i[2])
{
ARegion *region = CTX_wm_region(C);
ScrArea *area = CTX_wm_area(C);
@@ -1802,7 +1810,7 @@ void ED_gpencil_brush_draw_eraser(Brush *brush, int x, int y)
GPU_line_smooth(false);
}
-static bool gp_brush_cursor_poll(bContext *C)
+static bool gpencil_brush_cursor_poll(bContext *C)
{
if (WM_toolsystem_active_tool_is_brush(C)) {
return true;
@@ -1810,8 +1818,10 @@ static bool gp_brush_cursor_poll(bContext *C)
return false;
}
-/* Helper callback for drawing the cursor itself */
-static void gp_brush_cursor_draw(bContext *C, int x, int y, void *customdata)
+/**
+ * Helper callback for drawing the cursor itself.
+ */
+static void gpencil_brush_cursor_draw(bContext *C, int x, int y, void *customdata)
{
Scene *scene = CTX_data_scene(C);
Object *ob = CTX_data_active_object(C);
@@ -1830,8 +1840,8 @@ static void gp_brush_cursor_draw(bContext *C, int x, int y, void *customdata)
float radius = 3.0f;
int mval_i[2] = {x, y};
- /* check if cursor is in drawing region and has valid datablock */
- if ((!gp_check_cursor_region(C, mval_i)) || (gpd == NULL)) {
+ /* Check if cursor is in drawing region and has valid data-block. */
+ if ((!gpencil_check_cursor_region(C, mval_i)) || (gpd == NULL)) {
return;
}
@@ -2016,8 +2026,8 @@ void ED_gpencil_toggle_brush_cursor(bContext *C, bool enable, void *customdata)
/* enable cursor */
gset->paintcursor = WM_paint_cursor_activate(SPACE_TYPE_ANY,
RGN_TYPE_ANY,
- gp_brush_cursor_poll,
- gp_brush_cursor_draw,
+ gpencil_brush_cursor_poll,
+ gpencil_brush_cursor_draw,
(lastpost) ? customdata : NULL);
}
}
@@ -2081,7 +2091,9 @@ void ED_gpencil_setup_modes(bContext *C, bGPdata *gpd, int newmode)
}
}
-/* helper to convert 2d to 3d for simple drawing buffer */
+/**
+ * Helper to convert 2d to 3d for simple drawing buffer.
+ */
static void gpencil_stroke_convertcoords(ARegion *region,
const tGPspoint *point2D,
const float origin[3],
@@ -2107,7 +2119,9 @@ static void gpencil_stroke_convertcoords(ARegion *region,
}
}
-/* convert 2d tGPspoint to 3d bGPDspoint */
+/**
+ * Convert 2d #tGPspoint to 3d #bGPDspoint.
+ */
void ED_gpencil_tpoint_to_point(ARegion *region,
float origin[3],
const tGPspoint *tpt,
@@ -2125,7 +2139,9 @@ void ED_gpencil_tpoint_to_point(ARegion *region,
pt->uv_rot = tpt->uv_rot;
}
-/* recalc uv for any stroke using the material */
+/**
+ * Recalculate UV for any stroke using the material.
+ */
void ED_gpencil_update_color_uv(Main *bmain, Material *mat)
{
Material *gps_ma = NULL;
@@ -2212,7 +2228,8 @@ static bool gpencil_check_collision(bGPDstroke *gps,
return hit;
}
-static void gp_copy_points(bGPDstroke *gps, bGPDspoint *pt, bGPDspoint *pt_final, int i, int i2)
+static void gpencil_copy_points(
+ bGPDstroke *gps, bGPDspoint *pt, bGPDspoint *pt_final, int i, int i2)
{
/* don't copy same point */
if (i == i2) {
@@ -2244,7 +2261,7 @@ static void gp_copy_points(bGPDstroke *gps, bGPDspoint *pt, bGPDspoint *pt_final
}
}
-static void gp_insert_point(
+static void gpencil_insert_point(
bGPDstroke *gps, bGPDspoint *a_pt, bGPDspoint *b_pt, const float co_a[3], float co_b[3])
{
bGPDspoint *temp_points;
@@ -2287,16 +2304,16 @@ static void gp_insert_point(
for (int i = 0; i < oldtotpoints; i++) {
bGPDspoint *pt = &temp_points[i];
bGPDspoint *pt_final = &gps->points[i2];
- gp_copy_points(gps, pt, pt_final, i, i2);
+ gpencil_copy_points(gps, pt, pt_final, i, i2);
/* create new point duplicating point and copy location */
if ((i == a_idx) || (i == b_idx)) {
i2++;
pt_final = &gps->points[i2];
- gp_copy_points(gps, pt, pt_final, i, i2);
+ gpencil_copy_points(gps, pt, pt_final, i, i2);
copy_v3_v3(&pt_final->x, (i == a_idx) ? co_a : co_b);
- /* unselect */
+ /* Un-select. */
pt_final->flag &= ~GP_SPOINT_SELECT;
/* tag to avoid more checking with this point */
pt_final->flag |= GP_SPOINT_TAG;
@@ -2304,13 +2321,13 @@ static void gp_insert_point(
i2++;
}
- /* Calc geometry data. */
+ /* Calculate geometry data. */
BKE_gpencil_stroke_geometry_update(gps);
MEM_SAFE_FREE(temp_points);
}
-static float gp_calc_factor(float p2d_a1[2], float p2d_a2[2], float r_hit2d[2])
+static float gpencil_calc_factor(float p2d_a1[2], float p2d_a2[2], float r_hit2d[2])
{
float dist1 = len_squared_v2v2(p2d_a1, p2d_a2);
float dist2 = len_squared_v2v2(p2d_a1, r_hit2d);
@@ -2435,7 +2452,7 @@ int ED_gpencil_select_stroke_segment(bGPDlayer *gpl,
}
if (hit_a) {
- f = gp_calc_factor(p2d_a1, p2d_a2, r_hit2d);
+ f = gpencil_calc_factor(p2d_a1, p2d_a2, r_hit2d);
interp_v3_v3v3(r_hita, &pta1->x, &pta2->x, f);
if (f > min_factor) {
hit_pointa = pta2; /* first point is second (inverted loop) */
@@ -2468,7 +2485,7 @@ int ED_gpencil_select_stroke_segment(bGPDlayer *gpl,
}
if (hit_b) {
- f = gp_calc_factor(p2d_a1, p2d_a2, r_hit2d);
+ f = gpencil_calc_factor(p2d_a1, p2d_a2, r_hit2d);
interp_v3_v3v3(r_hitb, &pta1->x, &pta2->x, f);
if (f > min_factor) {
hit_pointb = pta1;
@@ -2482,7 +2499,7 @@ int ED_gpencil_select_stroke_segment(bGPDlayer *gpl,
/* insert new point in the collision points */
if (insert) {
- gp_insert_point(gps, hit_pointa, hit_pointb, r_hita, r_hitb);
+ gpencil_insert_point(gps, hit_pointa, hit_pointb, r_hita, r_hitb);
}
/* free memory */
@@ -2610,7 +2627,10 @@ void ED_gpencil_select_toggle_all(bContext *C, int action)
}
}
-/* Ensure the SBuffer (while drawing stroke) size is enough to save all points of the stroke */
+/**
+ * Ensure the #tGPspoint buffer (while drawing stroke)
+ * size is enough to save all points of the stroke.
+ */
tGPspoint *ED_gpencil_sbuffer_ensure(tGPspoint *buffer_array,
int *buffer_size,
int *buffer_used,
@@ -2661,10 +2681,12 @@ void ED_gpencil_sbuffer_update_eval(bGPdata *gpd, Object *ob_eval)
gpd_eval->runtime.cp_points = gpd->runtime.cp_points;
}
-/* Tag all scene grease pencil object to update. */
+/**
+ * Tag all scene grease pencil object to update.
+ */
void ED_gpencil_tag_scene_gpencil(Scene *scene)
{
- /* mark all grease pencil datablocks of the scene */
+ /* Mark all grease pencil data-blocks of the scene. */
FOREACH_SCENE_COLLECTION_BEGIN (scene, collection) {
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (collection, ob) {
if (ob->type == OB_GPENCIL) {
@@ -2748,7 +2770,7 @@ void ED_gpencil_init_random_settings(Brush *brush,
random_settings->pressure = BLI_hash_int_01(BLI_hash_int_2d(ix + iz, iy + iz)) * 2.0f - 1.0f;
}
- /* Randomn to color strength. */
+ /* Random to color strength. */
if (brush_settings->draw_random_strength) {
random_settings->strength = BLI_hash_int_01(BLI_hash_int_2d(ix + iy, iy + iz + ix)) * 2.0f -
1.0f;
@@ -2881,8 +2903,8 @@ void ED_gpencil_sbuffer_vertex_color_set(Depsgraph *depsgraph,
/* Random Color. */
gpencil_sbuffer_vertex_color_random(gpd, brush, tpt, random_color, pen_pressure);
- /* Copy to eval data because paint operators don't tag refresh until end for speedup
- painting. */
+ /* Copy to evaluate data because paint operators don't tag refresh until end for speedup
+ * painting. */
if (gpd_eval != NULL) {
copy_v4_v4(gpd_eval->runtime.vert_color_fill, gpd->runtime.vert_color_fill);
gpd_eval->runtime.matid = gpd->runtime.matid;
@@ -2908,12 +2930,12 @@ bool ED_gpencil_stroke_check_collision(GP_SpaceConversion *gsc,
/* Convert bound box to 2d */
copy_v3_v3(&pt_dummy.x, gps->boundbox_min);
- gp_point_to_parent_space(&pt_dummy, diff_mat, &pt_dummy_ps);
- gp_point_to_xy_fl(gsc, gps, &pt_dummy_ps, &boundbox_min[0], &boundbox_min[1]);
+ gpencil_point_to_parent_space(&pt_dummy, diff_mat, &pt_dummy_ps);
+ gpencil_point_to_xy_fl(gsc, gps, &pt_dummy_ps, &boundbox_min[0], &boundbox_min[1]);
copy_v3_v3(&pt_dummy.x, gps->boundbox_max);
- gp_point_to_parent_space(&pt_dummy, diff_mat, &pt_dummy_ps);
- gp_point_to_xy_fl(gsc, gps, &pt_dummy_ps, &boundbox_max[0], &boundbox_max[1]);
+ gpencil_point_to_parent_space(&pt_dummy, diff_mat, &pt_dummy_ps);
+ gpencil_point_to_xy_fl(gsc, gps, &pt_dummy_ps, &boundbox_max[0], &boundbox_max[1]);
/* Ensure the bounding box is oriented to axis. */
if (boundbox_max[0] < boundbox_min[0]) {
@@ -2925,7 +2947,7 @@ bool ED_gpencil_stroke_check_collision(GP_SpaceConversion *gsc,
rcti rect_stroke = {boundbox_min[0], boundbox_max[0], boundbox_min[1], boundbox_max[1]};
- /* For mouse, add a small offet to avoid false negative in corners. */
+ /* For mouse, add a small offset to avoid false negative in corners. */
rcti rect_mouse = {mouse[0] - offset, mouse[0] + offset, mouse[1] - offset, mouse[1] + offset};
/* Check collision between both rectangles. */
@@ -2933,12 +2955,13 @@ bool ED_gpencil_stroke_check_collision(GP_SpaceConversion *gsc,
}
/**
- * Check if a point is inside of the stroke
- * \param gps: Stroke to check
- * \param gsc: SpaceConversion data
- * \param mouse: Mouse position
- * \param diff_mat: View matrix
- * \return True if the point is inside
+ * Check if a point is inside of the stroke.
+ *
+ * \param gps: Stroke to check.
+ * \param gsc: Space conversion data.
+ * \param mouse: Mouse position.
+ * \param diff_mat: View matrix.
+ * \return True if the point is inside.
*/
bool ED_gpencil_stroke_point_is_inside(bGPDstroke *gps,
GP_SpaceConversion *gsc,
@@ -2959,11 +2982,11 @@ bool ED_gpencil_stroke_point_is_inside(bGPDstroke *gps,
int i;
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
bGPDspoint pt2;
- gp_point_to_parent_space(pt, diff_mat, &pt2);
- gp_point_to_xy(gsc, gps, &pt2, &mcoords[i][0], &mcoords[i][1]);
+ gpencil_point_to_parent_space(pt, diff_mat, &pt2);
+ gpencil_point_to_xy(gsc, gps, &pt2, &mcoords[i][0], &mcoords[i][1]);
}
- /* Compute boundbox of lasso (for faster testing later). */
+ /* Compute bound-box of lasso (for faster testing later). */
rcti rect;
BLI_lasso_boundbox(&rect, mcoords, len);
diff --git a/source/blender/editors/gpencil/gpencil_uv.c b/source/blender/editors/gpencil/gpencil_uv.c
index 0dfc7e0728e..e21b2049028 100644
--- a/source/blender/editors/gpencil/gpencil_uv.c
+++ b/source/blender/editors/gpencil/gpencil_uv.c
@@ -148,7 +148,7 @@ static bool gpencil_uv_transform_init(bContext *C, wmOperator *op)
opdata->ob = CTX_data_active_object(C);
opdata->gpd = (bGPdata *)opdata->ob->data;
- gp_point_conversion_init(C, &opdata->gsc);
+ gpencil_point_conversion_init(C, &opdata->gsc);
opdata->array_loc = NULL;
opdata->array_rot = NULL;
opdata->array_scale = NULL;
@@ -197,7 +197,7 @@ static bool gpencil_uv_transform_init(bContext *C, wmOperator *op)
GP_EDITABLE_STROKES_END(gpstroke_iter);
}
/* Convert to 2D. */
- gp_point_3d_to_xy(&opdata->gsc, GP_STROKE_3DSPACE, center, opdata->mcenter);
+ gpencil_point_3d_to_xy(&opdata->gsc, GP_STROKE_3DSPACE, center, opdata->mcenter);
return true;
}
diff --git a/source/blender/editors/gpencil/gpencil_vertex_ops.c b/source/blender/editors/gpencil/gpencil_vertex_ops.c
index 4db88bd552f..36ce7d3dc47 100644
--- a/source/blender/editors/gpencil/gpencil_vertex_ops.c
+++ b/source/blender/editors/gpencil/gpencil_vertex_ops.c
@@ -74,7 +74,7 @@ static const EnumPropertyItem gpencil_modesEnumPropertyItem_mode[] = {
};
/* Poll callback for stroke vertex paint operator. */
-static bool gp_vertexpaint_mode_poll(bContext *C)
+static bool gpencil_vertexpaint_mode_poll(bContext *C)
{
ToolSettings *ts = CTX_data_tool_settings(C);
Object *ob = CTX_data_active_object(C);
@@ -97,7 +97,7 @@ static bool gp_vertexpaint_mode_poll(bContext *C)
return false;
}
-static int gp_vertexpaint_brightness_contrast_exec(bContext *C, wmOperator *op)
+static int gpencil_vertexpaint_brightness_contrast_exec(bContext *C, wmOperator *op)
{
Object *ob = CTX_data_active_object(C);
bGPdata *gpd = (bGPdata *)ob->data;
@@ -178,8 +178,8 @@ void GPENCIL_OT_vertex_color_brightness_contrast(wmOperatorType *ot)
ot->description = "Adjust vertex color brightness/contrast";
/* api callbacks */
- ot->exec = gp_vertexpaint_brightness_contrast_exec;
- ot->poll = gp_vertexpaint_mode_poll;
+ ot->exec = gpencil_vertexpaint_brightness_contrast_exec;
+ ot->poll = gpencil_vertexpaint_mode_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -192,7 +192,7 @@ void GPENCIL_OT_vertex_color_brightness_contrast(wmOperatorType *ot)
RNA_def_property_ui_range(prop, min, max, 1, 1);
}
-static int gp_vertexpaint_hsv_exec(bContext *C, wmOperator *op)
+static int gpencil_vertexpaint_hsv_exec(bContext *C, wmOperator *op)
{
Object *ob = CTX_data_active_object(C);
bGPdata *gpd = (bGPdata *)ob->data;
@@ -273,8 +273,8 @@ void GPENCIL_OT_vertex_color_hsv(wmOperatorType *ot)
ot->description = "Adjust vertex color HSV values";
/* api callbacks */
- ot->exec = gp_vertexpaint_hsv_exec;
- ot->poll = gp_vertexpaint_mode_poll;
+ ot->exec = gpencil_vertexpaint_hsv_exec;
+ ot->poll = gpencil_vertexpaint_mode_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -286,7 +286,7 @@ void GPENCIL_OT_vertex_color_hsv(wmOperatorType *ot)
RNA_def_float(ot->srna, "v", 1.0f, 0.0f, 2.0f, "Value", "", 0.0f, 2.0f);
}
-static int gp_vertexpaint_invert_exec(bContext *C, wmOperator *op)
+static int gpencil_vertexpaint_invert_exec(bContext *C, wmOperator *op)
{
Object *ob = CTX_data_active_object(C);
bGPdata *gpd = (bGPdata *)ob->data;
@@ -344,8 +344,8 @@ void GPENCIL_OT_vertex_color_invert(wmOperatorType *ot)
ot->description = "Invert RGB values";
/* api callbacks */
- ot->exec = gp_vertexpaint_invert_exec;
- ot->poll = gp_vertexpaint_mode_poll;
+ ot->exec = gpencil_vertexpaint_invert_exec;
+ ot->poll = gpencil_vertexpaint_mode_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -354,7 +354,7 @@ void GPENCIL_OT_vertex_color_invert(wmOperatorType *ot)
ot->prop = RNA_def_enum(ot->srna, "mode", gpencil_modesEnumPropertyItem_mode, 0, "Mode", "");
}
-static int gp_vertexpaint_levels_exec(bContext *C, wmOperator *op)
+static int gpencil_vertexpaint_levels_exec(bContext *C, wmOperator *op)
{
Object *ob = CTX_data_active_object(C);
bGPdata *gpd = (bGPdata *)ob->data;
@@ -413,8 +413,8 @@ void GPENCIL_OT_vertex_color_levels(wmOperatorType *ot)
ot->description = "Adjust levels of vertex colors";
/* api callbacks */
- ot->exec = gp_vertexpaint_levels_exec;
- ot->poll = gp_vertexpaint_mode_poll;
+ ot->exec = gpencil_vertexpaint_levels_exec;
+ ot->poll = gpencil_vertexpaint_mode_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -428,13 +428,13 @@ void GPENCIL_OT_vertex_color_levels(wmOperatorType *ot)
ot->srna, "gain", 1.0f, 0.0f, FLT_MAX, "Gain", "Value to multiply colors by", 0.0f, 10.0f);
}
-static int gp_vertexpaint_set_exec(bContext *C, wmOperator *op)
+static int gpencil_vertexpaint_set_exec(bContext *C, wmOperator *op)
{
ToolSettings *ts = CTX_data_tool_settings(C);
Object *ob = CTX_data_active_object(C);
bGPdata *gpd = (bGPdata *)ob->data;
Paint *paint = &ts->gp_vertexpaint->paint;
- Brush *brush = brush = paint->brush;
+ Brush *brush = paint->brush;
bool changed = false;
int i;
@@ -485,8 +485,8 @@ void GPENCIL_OT_vertex_color_set(wmOperatorType *ot)
ot->description = "Set active color to all selected vertex";
/* api callbacks */
- ot->exec = gp_vertexpaint_set_exec;
- ot->poll = gp_vertexpaint_mode_poll;
+ ot->exec = gpencil_vertexpaint_set_exec;
+ ot->poll = gpencil_vertexpaint_mode_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -497,7 +497,9 @@ void GPENCIL_OT_vertex_color_set(wmOperatorType *ot)
}
/* Helper to extract color from vertex color to create a palette. */
-static bool gp_extract_palette_from_vertex(bContext *C, const bool selected, const int threshold)
+static bool gpencil_extract_palette_from_vertex(bContext *C,
+ const bool selected,
+ const int threshold)
{
Main *bmain = CTX_data_main(C);
Object *ob = CTX_data_active_object(C);
@@ -657,7 +659,7 @@ static uint get_material_type(MaterialGPencilStyle *gp_style,
return r_i;
}
-static bool gp_material_to_vertex_poll(bContext *C)
+static bool gpencil_material_to_vertex_poll(bContext *C)
{
/* only supported with grease pencil objects */
Object *ob = CTX_data_active_object(C);
@@ -668,7 +670,7 @@ static bool gp_material_to_vertex_poll(bContext *C)
return true;
}
-static int gp_material_to_vertex_exec(bContext *C, wmOperator *op)
+static int gpencil_material_to_vertex_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Object *ob = CTX_data_active_object(C);
@@ -814,7 +816,7 @@ static int gp_material_to_vertex_exec(bContext *C, wmOperator *op)
/* Generate a Palette. */
if (palette) {
- gp_extract_palette_from_vertex(C, selected, 1);
+ gpencil_extract_palette_from_vertex(C, selected, 1);
}
/* Clean unused materials. */
@@ -834,8 +836,8 @@ void GPENCIL_OT_material_to_vertex_color(wmOperatorType *ot)
ot->description = "Replace materials in strokes with Vertex Color";
/* api callbacks */
- ot->exec = gp_material_to_vertex_exec;
- ot->poll = gp_material_to_vertex_poll;
+ ot->exec = gpencil_material_to_vertex_exec;
+ ot->poll = gpencil_material_to_vertex_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -852,7 +854,7 @@ void GPENCIL_OT_material_to_vertex_color(wmOperatorType *ot)
}
/* Extract Palette from Vertex Color. */
-static bool gp_extract_palette_vertex_poll(bContext *C)
+static bool gpencil_extract_palette_vertex_poll(bContext *C)
{
/* only supported with grease pencil objects */
Object *ob = CTX_data_active_object(C);
@@ -863,12 +865,12 @@ static bool gp_extract_palette_vertex_poll(bContext *C)
return true;
}
-static int gp_extract_palette_vertex_exec(bContext *C, wmOperator *op)
+static int gpencil_extract_palette_vertex_exec(bContext *C, wmOperator *op)
{
const bool selected = RNA_boolean_get(op->ptr, "selected");
const int threshold = RNA_int_get(op->ptr, "threshold");
- if (gp_extract_palette_from_vertex(C, selected, threshold)) {
+ if (gpencil_extract_palette_from_vertex(C, selected, threshold)) {
BKE_reportf(op->reports, RPT_INFO, "Palette created");
}
else {
@@ -886,8 +888,8 @@ void GPENCIL_OT_extract_palette_vertex(wmOperatorType *ot)
ot->description = "Extract all colors used in Grease Pencil Vertex and create a Palette";
/* api callbacks */
- ot->exec = gp_extract_palette_vertex_exec;
- ot->poll = gp_extract_palette_vertex_poll;
+ ot->exec = gpencil_extract_palette_vertex_exec;
+ ot->poll = gpencil_extract_palette_vertex_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
diff --git a/source/blender/editors/gpencil/gpencil_vertex_paint.c b/source/blender/editors/gpencil/gpencil_vertex_paint.c
index fe3f0871fdc..99d55350527 100644
--- a/source/blender/editors/gpencil/gpencil_vertex_paint.c
+++ b/source/blender/editors/gpencil/gpencil_vertex_paint.c
@@ -263,7 +263,7 @@ static void brush_calc_dvec_2d(tGP_BrushVertexpaintData *gso)
* number of pixels (see: GP_GRID_PIXEL_SIZE)
*/
-static void gp_grid_cells_init(tGP_BrushVertexpaintData *gso)
+static void gpencil_grid_cells_init(tGP_BrushVertexpaintData *gso)
{
tGP_Grid *grid;
float bottom[2];
@@ -298,7 +298,7 @@ static void gp_grid_cells_init(tGP_BrushVertexpaintData *gso)
}
/* Get the index used in the grid base on dvec. */
-static void gp_grid_cell_average_color_idx_get(tGP_BrushVertexpaintData *gso, int r_idx[2])
+static void gpencil_grid_cell_average_color_idx_get(tGP_BrushVertexpaintData *gso, int r_idx[2])
{
/* Lower direction. */
if (gso->dvec[1] < 0.0f) {
@@ -348,7 +348,7 @@ static void gp_grid_cell_average_color_idx_get(tGP_BrushVertexpaintData *gso, in
}
}
-static int gp_grid_cell_index_get(tGP_BrushVertexpaintData *gso, int pc[2])
+static int gpencil_grid_cell_index_get(tGP_BrushVertexpaintData *gso, int pc[2])
{
float bottom[2], top[2];
@@ -366,7 +366,7 @@ static int gp_grid_cell_index_get(tGP_BrushVertexpaintData *gso, int pc[2])
}
/* Fill the grid with the color in each cell and assign point cell index. */
-static void gp_grid_colors_calc(tGP_BrushVertexpaintData *gso)
+static void gpencil_grid_colors_calc(tGP_BrushVertexpaintData *gso)
{
tGP_Selected *selected = NULL;
bGPDstroke *gps_selected = NULL;
@@ -383,7 +383,7 @@ static void gp_grid_colors_calc(tGP_BrushVertexpaintData *gso)
selected = &gso->pbuffer[i];
gps_selected = selected->gps;
pt = &gps_selected->points[selected->pt_index];
- int grid_index = gp_grid_cell_index_get(gso, selected->pc);
+ int grid_index = gpencil_grid_cell_index_get(gso, selected->pc);
if (grid_index > -1) {
grid = &gso->grid[grid_index];
@@ -639,7 +639,7 @@ static bool brush_smear_apply(tGP_BrushVertexpaintData *gso,
/* Need get average colors in the grid. */
if ((!gso->grid_ready) && (gso->pbuffer_used > 0)) {
- gp_grid_colors_calc(gso);
+ gpencil_grid_colors_calc(gso);
}
/* The influence is equal to strength and no decay around brush radius. */
@@ -657,10 +657,10 @@ static bool brush_smear_apply(tGP_BrushVertexpaintData *gso,
inf *= fac;
/* Retry row and col for average color. */
- gp_grid_cell_average_color_idx_get(gso, average_idx);
+ gpencil_grid_cell_average_color_idx_get(gso, average_idx);
/* Retry average color cell. */
- int grid_index = gp_grid_cell_index_get(gso, selected->pc);
+ int grid_index = gpencil_grid_cell_index_get(gso, selected->pc);
if (grid_index > -1) {
int row = grid_index / gso->grid_size;
int col = grid_index - (gso->grid_size * row);
@@ -700,7 +700,7 @@ static bool brush_smear_apply(tGP_BrushVertexpaintData *gso,
/* ************************************************ */
/* Header Info */
-static void gp_vertexpaint_brush_header_set(bContext *C)
+static void gpencil_vertexpaint_brush_header_set(bContext *C)
{
ED_workspace_status_text(C,
TIP_("GPencil Vertex Paint: LMB to paint | RMB/Escape to Exit"
@@ -712,7 +712,7 @@ static void gp_vertexpaint_brush_header_set(bContext *C)
/* Init/Exit ----------------------------------------------- */
-static bool gp_vertexpaint_brush_init(bContext *C, wmOperator *op)
+static bool gpencil_vertexpaint_brush_init(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
ToolSettings *ts = CTX_data_tool_settings(C);
@@ -765,15 +765,15 @@ static bool gp_vertexpaint_brush_init(bContext *C, wmOperator *op)
}
/* Setup space conversions. */
- gp_point_conversion_init(C, &gso->gsc);
+ gpencil_point_conversion_init(C, &gso->gsc);
/* Update header. */
- gp_vertexpaint_brush_header_set(C);
+ gpencil_vertexpaint_brush_header_set(C);
return true;
}
-static void gp_vertexpaint_brush_exit(bContext *C, wmOperator *op)
+static void gpencil_vertexpaint_brush_exit(bContext *C, wmOperator *op)
{
tGP_BrushVertexpaintData *gso = op->customdata;
@@ -791,17 +791,17 @@ static void gp_vertexpaint_brush_exit(bContext *C, wmOperator *op)
}
/* Poll callback for stroke vertex paint operator. */
-static bool gp_vertexpaint_brush_poll(bContext *C)
+static bool gpencil_vertexpaint_brush_poll(bContext *C)
{
/* NOTE: this is a bit slower, but is the most accurate... */
return CTX_DATA_COUNT(C, editable_gpencil_strokes) != 0;
}
/* Helper to save the points selected by the brush. */
-static void gp_save_selected_point(tGP_BrushVertexpaintData *gso,
- bGPDstroke *gps,
- int index,
- int pc[2])
+static void gpencil_save_selected_point(tGP_BrushVertexpaintData *gso,
+ bGPDstroke *gps,
+ int index,
+ int pc[2])
{
tGP_Selected *selected;
bGPDspoint *pt = &gps->points[index];
@@ -822,10 +822,10 @@ static void gp_save_selected_point(tGP_BrushVertexpaintData *gso,
}
/* Select points in this stroke and add to an array to be used later. */
-static void gp_vertexpaint_select_stroke(tGP_BrushVertexpaintData *gso,
- bGPDstroke *gps,
- const char tool,
- const float diff_mat[4][4])
+static void gpencil_vertexpaint_select_stroke(tGP_BrushVertexpaintData *gso,
+ bGPDstroke *gps,
+ const char tool,
+ const float diff_mat[4][4])
{
GP_SpaceConversion *gsc = &gso->gsc;
rcti *rect = &gso->brush_rect;
@@ -851,8 +851,8 @@ static void gp_vertexpaint_select_stroke(tGP_BrushVertexpaintData *gso,
if (gps->totpoints == 1) {
bGPDspoint pt_temp;
pt = &gps->points[0];
- gp_point_to_parent_space(gps->points, diff_mat, &pt_temp);
- gp_point_to_xy(gsc, gps, &pt_temp, &pc1[0], &pc1[1]);
+ gpencil_point_to_parent_space(gps->points, diff_mat, &pt_temp);
+ gpencil_point_to_xy(gsc, gps, &pt_temp, &pc1[0], &pc1[1]);
pt_active = (pt->runtime.pt_orig) ? pt->runtime.pt_orig : pt;
/* do boundbox check first */
@@ -863,7 +863,7 @@ static void gp_vertexpaint_select_stroke(tGP_BrushVertexpaintData *gso,
if (len_v2v2_int(mval_i, pc1) <= radius) {
/* apply operation to this point */
if (pt_active != NULL) {
- gp_save_selected_point(gso, gps_active, 0, pc1);
+ gpencil_save_selected_point(gso, gps_active, 0, pc1);
}
}
}
@@ -888,11 +888,11 @@ static void gp_vertexpaint_select_stroke(tGP_BrushVertexpaintData *gso,
}
bGPDspoint npt;
- gp_point_to_parent_space(pt1, diff_mat, &npt);
- gp_point_to_xy(gsc, gps, &npt, &pc1[0], &pc1[1]);
+ gpencil_point_to_parent_space(pt1, diff_mat, &npt);
+ gpencil_point_to_xy(gsc, gps, &npt, &pc1[0], &pc1[1]);
- gp_point_to_parent_space(pt2, diff_mat, &npt);
- gp_point_to_xy(gsc, gps, &npt, &pc2[0], &pc2[1]);
+ gpencil_point_to_parent_space(pt2, diff_mat, &npt);
+ gpencil_point_to_xy(gsc, gps, &npt, &pc2[0], &pc2[1]);
/* Check that point segment of the boundbox of the selection stroke */
if (((!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1])) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) ||
@@ -901,7 +901,7 @@ static void gp_vertexpaint_select_stroke(tGP_BrushVertexpaintData *gso,
* brush region (either within stroke painted, or on its lines)
* - this assumes that linewidth is irrelevant
*/
- if (gp_stroke_inside_circle(gso->mval, radius, pc1[0], pc1[1], pc2[0], pc2[1])) {
+ if (gpencil_stroke_inside_circle(gso->mval, radius, pc1[0], pc1[1], pc2[0], pc2[1])) {
/* To each point individually... */
pt = &gps->points[i];
@@ -914,7 +914,7 @@ static void gp_vertexpaint_select_stroke(tGP_BrushVertexpaintData *gso,
continue;
}
hit = true;
- gp_save_selected_point(gso, gps_active, index, pc1);
+ gpencil_save_selected_point(gso, gps_active, index, pc1);
}
/* Only do the second point if this is the last segment,
@@ -931,7 +931,7 @@ static void gp_vertexpaint_select_stroke(tGP_BrushVertexpaintData *gso,
index = (pt->runtime.pt_orig) ? pt->runtime.idx_orig : i + 1;
if (pt_active != NULL) {
hit = true;
- gp_save_selected_point(gso, gps_active, index, pc2);
+ gpencil_save_selected_point(gso, gps_active, index, pc2);
include_last = false;
}
}
@@ -950,7 +950,7 @@ static void gp_vertexpaint_select_stroke(tGP_BrushVertexpaintData *gso,
index = (pt->runtime.pt_orig) ? pt->runtime.idx_orig : i;
if (pt_active != NULL) {
hit = true;
- gp_save_selected_point(gso, gps_active, index, pc1);
+ gpencil_save_selected_point(gso, gps_active, index, pc1);
include_last = false;
}
@@ -970,7 +970,7 @@ static void gp_vertexpaint_select_stroke(tGP_BrushVertexpaintData *gso,
/* Need repeat the effect because if we don't do that the tint process
* is very slow. */
for (int repeat = 0; repeat < 50; repeat++) {
- gp_save_selected_point(gso, gps_active, -1, NULL);
+ gpencil_save_selected_point(gso, gps_active, -1, NULL);
}
}
}
@@ -979,11 +979,11 @@ static void gp_vertexpaint_select_stroke(tGP_BrushVertexpaintData *gso,
}
/* Apply vertex paint brushes to strokes in the given frame. */
-static bool gp_vertexpaint_brush_do_frame(bContext *C,
- tGP_BrushVertexpaintData *gso,
- bGPDlayer *gpl,
- bGPDframe *gpf,
- const float diff_mat[4][4])
+static bool gpencil_vertexpaint_brush_do_frame(bContext *C,
+ tGP_BrushVertexpaintData *gso,
+ bGPDlayer *gpl,
+ bGPDframe *gpf,
+ const float diff_mat[4][4])
{
Object *ob = CTX_data_active_object(C);
const char tool = ob->mode == OB_MODE_VERTEX_GPENCIL ? gso->brush->gpencil_vertex_tool :
@@ -1010,7 +1010,7 @@ static bool gp_vertexpaint_brush_do_frame(bContext *C,
}
/* Check points below the brush. */
- gp_vertexpaint_select_stroke(gso, gps, tool, diff_mat);
+ gpencil_vertexpaint_select_stroke(gso, gps, tool, diff_mat);
}
/* For Average tool, need calculate the average resulting color from all colors
@@ -1092,7 +1092,7 @@ static bool gp_vertexpaint_brush_do_frame(bContext *C,
}
/* Apply brush effect to all layers. */
-static bool gp_vertexpaint_brush_apply_to_layers(bContext *C, tGP_BrushVertexpaintData *gso)
+static bool gpencil_vertexpaint_brush_apply_to_layers(bContext *C, tGP_BrushVertexpaintData *gso)
{
ToolSettings *ts = CTX_data_tool_settings(C);
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
@@ -1138,7 +1138,7 @@ static bool gp_vertexpaint_brush_apply_to_layers(bContext *C, tGP_BrushVertexpai
}
/* affect strokes in this frame */
- changed |= gp_vertexpaint_brush_do_frame(C, gso, gpl, gpf, diff_mat);
+ changed |= gpencil_vertexpaint_brush_do_frame(C, gso, gpl, gpf, diff_mat);
}
}
}
@@ -1146,7 +1146,7 @@ static bool gp_vertexpaint_brush_apply_to_layers(bContext *C, tGP_BrushVertexpai
/* Apply to active frame's strokes */
if (gpl->actframe != NULL) {
gso->mf_falloff = 1.0f;
- changed |= gp_vertexpaint_brush_do_frame(C, gso, gpl, gpl->actframe, diff_mat);
+ changed |= gpencil_vertexpaint_brush_do_frame(C, gso, gpl, gpl->actframe, diff_mat);
}
}
}
@@ -1155,7 +1155,7 @@ static bool gp_vertexpaint_brush_apply_to_layers(bContext *C, tGP_BrushVertexpai
}
/* Calculate settings for applying brush */
-static void gp_vertexpaint_brush_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
+static void gpencil_vertexpaint_brush_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
{
tGP_BrushVertexpaintData *gso = op->customdata;
Brush *brush = gso->brush;
@@ -1196,9 +1196,9 @@ static void gp_vertexpaint_brush_apply(bContext *C, wmOperator *op, PointerRNA *
brush_calc_dvec_2d(gso);
/* Calc grid for smear tool. */
- gp_grid_cells_init(gso);
+ gpencil_grid_cells_init(gso);
- changed = gp_vertexpaint_brush_apply_to_layers(C, gso);
+ changed = gpencil_vertexpaint_brush_apply_to_layers(C, gso);
/* Updates */
if (changed) {
@@ -1216,7 +1216,9 @@ static void gp_vertexpaint_brush_apply(bContext *C, wmOperator *op, PointerRNA *
/* Running --------------------------------------------- */
/* helper - a record stroke, and apply paint event */
-static void gp_vertexpaint_brush_apply_event(bContext *C, wmOperator *op, const wmEvent *event)
+static void gpencil_vertexpaint_brush_apply_event(bContext *C,
+ wmOperator *op,
+ const wmEvent *event)
{
tGP_BrushVertexpaintData *gso = op->customdata;
PointerRNA itemptr;
@@ -1238,28 +1240,28 @@ static void gp_vertexpaint_brush_apply_event(bContext *C, wmOperator *op, const
RNA_float_set(&itemptr, "pressure", pressure);
/* apply */
- gp_vertexpaint_brush_apply(C, op, &itemptr);
+ gpencil_vertexpaint_brush_apply(C, op, &itemptr);
}
/* reapply */
-static int gp_vertexpaint_brush_exec(bContext *C, wmOperator *op)
+static int gpencil_vertexpaint_brush_exec(bContext *C, wmOperator *op)
{
- if (!gp_vertexpaint_brush_init(C, op)) {
+ if (!gpencil_vertexpaint_brush_init(C, op)) {
return OPERATOR_CANCELLED;
}
RNA_BEGIN (op->ptr, itemptr, "stroke") {
- gp_vertexpaint_brush_apply(C, op, &itemptr);
+ gpencil_vertexpaint_brush_apply(C, op, &itemptr);
}
RNA_END;
- gp_vertexpaint_brush_exit(C, op);
+ gpencil_vertexpaint_brush_exit(C, op);
return OPERATOR_FINISHED;
}
/* start modal painting */
-static int gp_vertexpaint_brush_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+static int gpencil_vertexpaint_brush_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
tGP_BrushVertexpaintData *gso = NULL;
const bool is_modal = RNA_boolean_get(op->ptr, "wait_for_input");
@@ -1273,7 +1275,7 @@ static int gp_vertexpaint_brush_invoke(bContext *C, wmOperator *op, const wmEven
}
/* init painting data */
- if (!gp_vertexpaint_brush_init(C, op)) {
+ if (!gpencil_vertexpaint_brush_init(C, op)) {
return OPERATOR_CANCELLED;
}
@@ -1288,7 +1290,7 @@ static int gp_vertexpaint_brush_invoke(bContext *C, wmOperator *op, const wmEven
/* apply first dab... */
gso->is_painting = true;
- gp_vertexpaint_brush_apply_event(C, op, event);
+ gpencil_vertexpaint_brush_apply_event(C, op, event);
/* redraw view with feedback */
ED_region_tag_redraw(region);
@@ -1298,7 +1300,7 @@ static int gp_vertexpaint_brush_invoke(bContext *C, wmOperator *op, const wmEven
}
/* painting - handle events */
-static int gp_vertexpaint_brush_modal(bContext *C, wmOperator *op, const wmEvent *event)
+static int gpencil_vertexpaint_brush_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
tGP_BrushVertexpaintData *gso = op->customdata;
const bool is_modal = RNA_boolean_get(op->ptr, "wait_for_input");
@@ -1313,7 +1315,7 @@ static int gp_vertexpaint_brush_modal(bContext *C, wmOperator *op, const wmEvent
case MOUSEMOVE:
case INBETWEEN_MOUSEMOVE:
/* apply brush effect at new position */
- gp_vertexpaint_brush_apply_event(C, op, event);
+ gpencil_vertexpaint_brush_apply_event(C, op, event);
/* force redraw, so that the cursor will at least be valid */
redraw_region = true;
@@ -1329,7 +1331,7 @@ static int gp_vertexpaint_brush_modal(bContext *C, wmOperator *op, const wmEvent
/* end painting, since we're not modal */
gso->is_painting = false;
- gp_vertexpaint_brush_exit(C, op);
+ gpencil_vertexpaint_brush_exit(C, op);
return OPERATOR_FINISHED;
}
break;
@@ -1338,7 +1340,7 @@ static int gp_vertexpaint_brush_modal(bContext *C, wmOperator *op, const wmEvent
case MIDDLEMOUSE:
case RIGHTMOUSE:
case EVT_ESCKEY:
- gp_vertexpaint_brush_exit(C, op);
+ gpencil_vertexpaint_brush_exit(C, op);
return OPERATOR_FINISHED;
}
}
@@ -1353,13 +1355,13 @@ static int gp_vertexpaint_brush_modal(bContext *C, wmOperator *op, const wmEvent
gso->is_painting = true;
gso->first = true;
- gp_vertexpaint_brush_apply_event(C, op, event);
+ gpencil_vertexpaint_brush_apply_event(C, op, event);
break;
/* Exit modal operator, based on the "standard" ops */
case RIGHTMOUSE:
case EVT_ESCKEY:
- gp_vertexpaint_brush_exit(C, op);
+ gpencil_vertexpaint_brush_exit(C, op);
return OPERATOR_FINISHED;
/* MMB is often used for view manipulations */
@@ -1421,11 +1423,11 @@ void GPENCIL_OT_vertex_paint(wmOperatorType *ot)
ot->description = "Paint stroke points with a color";
/* api callbacks */
- ot->exec = gp_vertexpaint_brush_exec;
- ot->invoke = gp_vertexpaint_brush_invoke;
- ot->modal = gp_vertexpaint_brush_modal;
- ot->cancel = gp_vertexpaint_brush_exit;
- ot->poll = gp_vertexpaint_brush_poll;
+ ot->exec = gpencil_vertexpaint_brush_exec;
+ ot->invoke = gpencil_vertexpaint_brush_invoke;
+ ot->modal = gpencil_vertexpaint_brush_modal;
+ ot->cancel = gpencil_vertexpaint_brush_exit;
+ ot->poll = gpencil_vertexpaint_brush_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
diff --git a/source/blender/editors/gpencil/gpencil_weight_paint.c b/source/blender/editors/gpencil/gpencil_weight_paint.c
index 2ebf1aba353..e41146575e4 100644
--- a/source/blender/editors/gpencil/gpencil_weight_paint.c
+++ b/source/blender/editors/gpencil/gpencil_weight_paint.c
@@ -268,7 +268,7 @@ static bool brush_draw_apply(tGP_BrushWeightpaintData *gso,
/* ************************************************ */
/* Header Info */
-static void gp_weightpaint_brush_header_set(bContext *C)
+static void gpencil_weightpaint_brush_header_set(bContext *C)
{
ED_workspace_status_text(C, TIP_("GPencil Weight Paint: LMB to paint | RMB/Escape to Exit"));
}
@@ -278,7 +278,7 @@ static void gp_weightpaint_brush_header_set(bContext *C)
/* Init/Exit ----------------------------------------------- */
-static bool gp_weightpaint_brush_init(bContext *C, wmOperator *op)
+static bool gpencil_weightpaint_brush_init(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
ToolSettings *ts = CTX_data_tool_settings(C);
@@ -330,15 +330,15 @@ static bool gp_weightpaint_brush_init(bContext *C, wmOperator *op)
}
/* Setup space conversions. */
- gp_point_conversion_init(C, &gso->gsc);
+ gpencil_point_conversion_init(C, &gso->gsc);
/* Update header. */
- gp_weightpaint_brush_header_set(C);
+ gpencil_weightpaint_brush_header_set(C);
return true;
}
-static void gp_weightpaint_brush_exit(bContext *C, wmOperator *op)
+static void gpencil_weightpaint_brush_exit(bContext *C, wmOperator *op)
{
tGP_BrushWeightpaintData *gso = op->customdata;
@@ -352,17 +352,17 @@ static void gp_weightpaint_brush_exit(bContext *C, wmOperator *op)
}
/* Poll callback for stroke weight paint operator. */
-static bool gp_weightpaint_brush_poll(bContext *C)
+static bool gpencil_weightpaint_brush_poll(bContext *C)
{
/* NOTE: this is a bit slower, but is the most accurate... */
return CTX_DATA_COUNT(C, editable_gpencil_strokes) != 0;
}
/* Helper to save the points selected by the brush. */
-static void gp_save_selected_point(tGP_BrushWeightpaintData *gso,
- bGPDstroke *gps,
- int index,
- int pc[2])
+static void gpencil_save_selected_point(tGP_BrushWeightpaintData *gso,
+ bGPDstroke *gps,
+ int index,
+ int pc[2])
{
tGP_Selected *selected;
bGPDspoint *pt = &gps->points[index];
@@ -381,9 +381,9 @@ static void gp_save_selected_point(tGP_BrushWeightpaintData *gso,
}
/* Select points in this stroke and add to an array to be used later. */
-static void gp_weightpaint_select_stroke(tGP_BrushWeightpaintData *gso,
- bGPDstroke *gps,
- const float diff_mat[4][4])
+static void gpencil_weightpaint_select_stroke(tGP_BrushWeightpaintData *gso,
+ bGPDstroke *gps,
+ const float diff_mat[4][4])
{
GP_SpaceConversion *gsc = &gso->gsc;
rcti *rect = &gso->brush_rect;
@@ -409,8 +409,8 @@ static void gp_weightpaint_select_stroke(tGP_BrushWeightpaintData *gso,
if (gps->totpoints == 1) {
bGPDspoint pt_temp;
pt = &gps->points[0];
- gp_point_to_parent_space(gps->points, diff_mat, &pt_temp);
- gp_point_to_xy(gsc, gps, &pt_temp, &pc1[0], &pc1[1]);
+ gpencil_point_to_parent_space(gps->points, diff_mat, &pt_temp);
+ gpencil_point_to_xy(gsc, gps, &pt_temp, &pc1[0], &pc1[1]);
pt_active = (pt->runtime.pt_orig) ? pt->runtime.pt_orig : pt;
/* do boundbox check first */
@@ -421,7 +421,7 @@ static void gp_weightpaint_select_stroke(tGP_BrushWeightpaintData *gso,
if (len_v2v2_int(mval_i, pc1) <= radius) {
/* apply operation to this point */
if (pt_active != NULL) {
- gp_save_selected_point(gso, gps_active, 0, pc1);
+ gpencil_save_selected_point(gso, gps_active, 0, pc1);
}
}
}
@@ -436,11 +436,11 @@ static void gp_weightpaint_select_stroke(tGP_BrushWeightpaintData *gso,
pt2 = gps->points + i + 1;
bGPDspoint npt;
- gp_point_to_parent_space(pt1, diff_mat, &npt);
- gp_point_to_xy(gsc, gps, &npt, &pc1[0], &pc1[1]);
+ gpencil_point_to_parent_space(pt1, diff_mat, &npt);
+ gpencil_point_to_xy(gsc, gps, &npt, &pc1[0], &pc1[1]);
- gp_point_to_parent_space(pt2, diff_mat, &npt);
- gp_point_to_xy(gsc, gps, &npt, &pc2[0], &pc2[1]);
+ gpencil_point_to_parent_space(pt2, diff_mat, &npt);
+ gpencil_point_to_xy(gsc, gps, &npt, &pc2[0], &pc2[1]);
/* Check that point segment of the boundbox of the selection stroke */
if (((!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1])) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) ||
@@ -449,14 +449,14 @@ static void gp_weightpaint_select_stroke(tGP_BrushWeightpaintData *gso,
* brush region (either within stroke painted, or on its lines)
* - this assumes that linewidth is irrelevant
*/
- if (gp_stroke_inside_circle(gso->mval, radius, pc1[0], pc1[1], pc2[0], pc2[1])) {
+ if (gpencil_stroke_inside_circle(gso->mval, radius, pc1[0], pc1[1], pc2[0], pc2[1])) {
/* To each point individually... */
pt = &gps->points[i];
pt_active = (pt->runtime.pt_orig) ? pt->runtime.pt_orig : pt;
index = (pt->runtime.pt_orig) ? pt->runtime.idx_orig : i;
if (pt_active != NULL) {
- gp_save_selected_point(gso, gps_active, index, pc1);
+ gpencil_save_selected_point(gso, gps_active, index, pc1);
}
/* Only do the second point if this is the last segment,
@@ -472,7 +472,7 @@ static void gp_weightpaint_select_stroke(tGP_BrushWeightpaintData *gso,
pt_active = (pt->runtime.pt_orig) ? pt->runtime.pt_orig : pt;
index = (pt->runtime.pt_orig) ? pt->runtime.idx_orig : i + 1;
if (pt_active != NULL) {
- gp_save_selected_point(gso, gps_active, index, pc2);
+ gpencil_save_selected_point(gso, gps_active, index, pc2);
include_last = false;
}
}
@@ -490,7 +490,7 @@ static void gp_weightpaint_select_stroke(tGP_BrushWeightpaintData *gso,
pt_active = (pt->runtime.pt_orig) ? pt->runtime.pt_orig : pt;
index = (pt->runtime.pt_orig) ? pt->runtime.idx_orig : i;
if (pt_active != NULL) {
- gp_save_selected_point(gso, gps_active, index, pc1);
+ gpencil_save_selected_point(gso, gps_active, index, pc1);
include_last = false;
}
@@ -501,11 +501,11 @@ static void gp_weightpaint_select_stroke(tGP_BrushWeightpaintData *gso,
}
/* Apply weight paint brushes to strokes in the given frame. */
-static bool gp_weightpaint_brush_do_frame(bContext *C,
- tGP_BrushWeightpaintData *gso,
- bGPDlayer *gpl,
- bGPDframe *gpf,
- const float diff_mat[4][4])
+static bool gpencil_weightpaint_brush_do_frame(bContext *C,
+ tGP_BrushWeightpaintData *gso,
+ bGPDlayer *gpl,
+ bGPDframe *gpf,
+ const float diff_mat[4][4])
{
Object *ob = CTX_data_active_object(C);
char tool = gso->brush->gpencil_weight_tool;
@@ -531,7 +531,7 @@ static bool gp_weightpaint_brush_do_frame(bContext *C,
}
/* Check points below the brush. */
- gp_weightpaint_select_stroke(gso, gps, diff_mat);
+ gpencil_weightpaint_select_stroke(gso, gps, diff_mat);
}
/*---------------------------------------------------------------------
@@ -561,7 +561,7 @@ static bool gp_weightpaint_brush_do_frame(bContext *C,
}
/* Apply brush effect to all layers. */
-static bool gp_weightpaint_brush_apply_to_layers(bContext *C, tGP_BrushWeightpaintData *gso)
+static bool gpencil_weightpaint_brush_apply_to_layers(bContext *C, tGP_BrushWeightpaintData *gso)
{
ToolSettings *ts = CTX_data_tool_settings(C);
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
@@ -608,7 +608,7 @@ static bool gp_weightpaint_brush_apply_to_layers(bContext *C, tGP_BrushWeightpai
}
/* affect strokes in this frame */
- changed |= gp_weightpaint_brush_do_frame(C, gso, gpl, gpf, diff_mat);
+ changed |= gpencil_weightpaint_brush_do_frame(C, gso, gpl, gpf, diff_mat);
}
}
}
@@ -616,7 +616,7 @@ static bool gp_weightpaint_brush_apply_to_layers(bContext *C, tGP_BrushWeightpai
if (gpl->actframe != NULL) {
/* Apply to active frame's strokes */
gso->mf_falloff = 1.0f;
- changed |= gp_weightpaint_brush_do_frame(C, gso, gpl, gpl->actframe, diff_mat);
+ changed |= gpencil_weightpaint_brush_do_frame(C, gso, gpl, gpl->actframe, diff_mat);
}
}
}
@@ -625,7 +625,7 @@ static bool gp_weightpaint_brush_apply_to_layers(bContext *C, tGP_BrushWeightpai
}
/* Calculate settings for applying brush */
-static void gp_weightpaint_brush_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
+static void gpencil_weightpaint_brush_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
{
tGP_BrushWeightpaintData *gso = op->customdata;
Brush *brush = gso->brush;
@@ -658,7 +658,7 @@ static void gp_weightpaint_brush_apply(bContext *C, wmOperator *op, PointerRNA *
/* Calculate 2D direction vector and relative angle. */
brush_calc_dvec_2d(gso);
- changed = gp_weightpaint_brush_apply_to_layers(C, gso);
+ changed = gpencil_weightpaint_brush_apply_to_layers(C, gso);
/* Updates */
if (changed) {
@@ -676,7 +676,9 @@ static void gp_weightpaint_brush_apply(bContext *C, wmOperator *op, PointerRNA *
/* Running --------------------------------------------- */
/* helper - a record stroke, and apply paint event */
-static void gp_weightpaint_brush_apply_event(bContext *C, wmOperator *op, const wmEvent *event)
+static void gpencil_weightpaint_brush_apply_event(bContext *C,
+ wmOperator *op,
+ const wmEvent *event)
{
tGP_BrushWeightpaintData *gso = op->customdata;
PointerRNA itemptr;
@@ -698,28 +700,28 @@ static void gp_weightpaint_brush_apply_event(bContext *C, wmOperator *op, const
RNA_float_set(&itemptr, "pressure", pressure);
/* apply */
- gp_weightpaint_brush_apply(C, op, &itemptr);
+ gpencil_weightpaint_brush_apply(C, op, &itemptr);
}
/* reapply */
-static int gp_weightpaint_brush_exec(bContext *C, wmOperator *op)
+static int gpencil_weightpaint_brush_exec(bContext *C, wmOperator *op)
{
- if (!gp_weightpaint_brush_init(C, op)) {
+ if (!gpencil_weightpaint_brush_init(C, op)) {
return OPERATOR_CANCELLED;
}
RNA_BEGIN (op->ptr, itemptr, "stroke") {
- gp_weightpaint_brush_apply(C, op, &itemptr);
+ gpencil_weightpaint_brush_apply(C, op, &itemptr);
}
RNA_END;
- gp_weightpaint_brush_exit(C, op);
+ gpencil_weightpaint_brush_exit(C, op);
return OPERATOR_FINISHED;
}
/* start modal painting */
-static int gp_weightpaint_brush_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+static int gpencil_weightpaint_brush_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
tGP_BrushWeightpaintData *gso = NULL;
const bool is_modal = RNA_boolean_get(op->ptr, "wait_for_input");
@@ -733,7 +735,7 @@ static int gp_weightpaint_brush_invoke(bContext *C, wmOperator *op, const wmEven
}
/* init painting data */
- if (!gp_weightpaint_brush_init(C, op)) {
+ if (!gpencil_weightpaint_brush_init(C, op)) {
return OPERATOR_CANCELLED;
}
@@ -748,7 +750,7 @@ static int gp_weightpaint_brush_invoke(bContext *C, wmOperator *op, const wmEven
/* apply first dab... */
gso->is_painting = true;
- gp_weightpaint_brush_apply_event(C, op, event);
+ gpencil_weightpaint_brush_apply_event(C, op, event);
/* redraw view with feedback */
ED_region_tag_redraw(region);
@@ -758,7 +760,7 @@ static int gp_weightpaint_brush_invoke(bContext *C, wmOperator *op, const wmEven
}
/* painting - handle events */
-static int gp_weightpaint_brush_modal(bContext *C, wmOperator *op, const wmEvent *event)
+static int gpencil_weightpaint_brush_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
tGP_BrushWeightpaintData *gso = op->customdata;
const bool is_modal = RNA_boolean_get(op->ptr, "wait_for_input");
@@ -773,7 +775,7 @@ static int gp_weightpaint_brush_modal(bContext *C, wmOperator *op, const wmEvent
case MOUSEMOVE:
case INBETWEEN_MOUSEMOVE:
/* apply brush effect at new position */
- gp_weightpaint_brush_apply_event(C, op, event);
+ gpencil_weightpaint_brush_apply_event(C, op, event);
/* force redraw, so that the cursor will at least be valid */
redraw_region = true;
@@ -789,7 +791,7 @@ static int gp_weightpaint_brush_modal(bContext *C, wmOperator *op, const wmEvent
/* end painting, since we're not modal */
gso->is_painting = false;
- gp_weightpaint_brush_exit(C, op);
+ gpencil_weightpaint_brush_exit(C, op);
return OPERATOR_FINISHED;
}
break;
@@ -798,7 +800,7 @@ static int gp_weightpaint_brush_modal(bContext *C, wmOperator *op, const wmEvent
case MIDDLEMOUSE:
case RIGHTMOUSE:
case EVT_ESCKEY:
- gp_weightpaint_brush_exit(C, op);
+ gpencil_weightpaint_brush_exit(C, op);
return OPERATOR_FINISHED;
}
}
@@ -813,13 +815,13 @@ static int gp_weightpaint_brush_modal(bContext *C, wmOperator *op, const wmEvent
gso->is_painting = true;
gso->first = true;
- gp_weightpaint_brush_apply_event(C, op, event);
+ gpencil_weightpaint_brush_apply_event(C, op, event);
break;
/* Exit modal operator, based on the "standard" ops */
case RIGHTMOUSE:
case EVT_ESCKEY:
- gp_weightpaint_brush_exit(C, op);
+ gpencil_weightpaint_brush_exit(C, op);
return OPERATOR_FINISHED;
/* MMB is often used for view manipulations */
@@ -881,11 +883,11 @@ void GPENCIL_OT_weight_paint(wmOperatorType *ot)
ot->description = "Paint stroke points with a color";
/* api callbacks */
- ot->exec = gp_weightpaint_brush_exec;
- ot->invoke = gp_weightpaint_brush_invoke;
- ot->modal = gp_weightpaint_brush_modal;
- ot->cancel = gp_weightpaint_brush_exit;
- ot->poll = gp_weightpaint_brush_poll;
+ ot->exec = gpencil_weightpaint_brush_exec;
+ ot->invoke = gpencil_weightpaint_brush_invoke;
+ ot->modal = gpencil_weightpaint_brush_modal;
+ ot->cancel = gpencil_weightpaint_brush_exit;
+ ot->poll = gpencil_weightpaint_brush_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h
index 426a470b128..3aecec0d6b6 100644
--- a/source/blender/editors/include/ED_anim_api.h
+++ b/source/blender/editors/include/ED_anim_api.h
@@ -281,10 +281,13 @@ typedef enum eAnim_Update_Flags {
/* filtering flags - under what circumstances should a channel be returned */
typedef enum eAnimFilter_Flags {
- /** data which channel represents is fits the dopesheet filters
- * (i.e. scene visibility criteria) */
- /* XXX: it's hard to think of any examples where this *ISN'T* the case...
- * perhaps becomes implicit?. */
+ /**
+ * Data which channel represents is fits the dope-sheet filters
+ * (i.e. scene visibility criteria).
+ *
+ * XXX: it's hard to think of any examples where this *ISN'T* the case...
+ * perhaps becomes implicit?.
+ */
ANIMFILTER_DATA_VISIBLE = (1 << 0),
/** channel is visible within the channel-list hierarchy
* (i.e. F-Curves within Groups in ActEdit) */
@@ -297,7 +300,7 @@ typedef enum eAnimFilter_Flags {
/** for its type, channel should be "active" one */
ANIMFILTER_ACTIVE = (1 << 4),
- /** channel is a child of the active group (* Actions speciality) */
+ /** channel is a child of the active group (* Actions specialty) */
ANIMFILTER_ACTGROUPED = (1 << 5),
/** channel must be selected/not-selected, but both must not be set together */
@@ -310,8 +313,10 @@ typedef enum eAnimFilter_Flags {
* for Graph Editor's option for keys on select curves only */
ANIMFILTER_SELEDIT = (1 << 9),
- /** flags used to enforce certain data types
- * \node the ones for curves and NLA tracks were redundant and have been removed for now...
+ /**
+ * Flags used to enforce certain data types.
+ *
+ * \note The ones for curves and NLA tracks were redundant and have been removed for now.
*/
ANIMFILTER_ANIMDATA = (1 << 10),
@@ -321,7 +326,7 @@ typedef enum eAnimFilter_Flags {
/** for checking if we should keep some collapsed channel around (internal use only!) */
ANIMFILTER_TMP_PEEK = (1 << 30),
- /** ignore ONLYSEL flag from filterflag, (internal use only!) */
+ /** Ignore ONLYSEL flag from #bDopeSheet.filterflag (internal use only!) */
ANIMFILTER_TMP_IGNORE_ONLYSEL = (1u << 31),
} eAnimFilter_Flags;
@@ -640,14 +645,14 @@ bool ANIM_remove_empty_action_from_animdata(struct AnimData *adt);
/* ---------- Current Frame Drawing ---------------- */
/* flags for Current Frame Drawing */
-enum eAnimEditDraw_CurrentFrame {
+typedef enum eAnimEditDraw_CurrentFrame {
/* plain time indicator with no special indicators */
/* DRAWCFRA_PLAIN = 0, */ /* UNUSED */
/* time indication in seconds or frames */
DRAWCFRA_UNIT_SECONDS = (1 << 0),
/* draw indicator extra wide (for timeline) */
DRAWCFRA_WIDE = (1 << 1),
-};
+} eAnimEditDraw_CurrentFrame;
/* main call to draw current-frame indicator in an Animation Editor */
void ANIM_draw_cfra(const struct bContext *C, struct View2D *v2d, short flag);
diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h
index 541e2633512..eef431c40fa 100644
--- a/source/blender/editors/include/ED_armature.h
+++ b/source/blender/editors/include/ED_armature.h
@@ -174,7 +174,7 @@ void ED_operatormacros_armature(void);
void ED_keymap_armature(struct wmKeyConfig *keyconf);
/* armature_relations.c */
-int join_armature_exec(struct bContext *C, struct wmOperator *op);
+int ED_armature_join_objects_exec(struct bContext *C, struct wmOperator *op);
/* armature_select.c */
struct Base *ED_armature_base_and_ebone_from_select_buffer(struct Base **bases,
diff --git a/source/blender/editors/include/ED_curve.h b/source/blender/editors/include/ED_curve.h
index 95c454043da..79f5f62f293 100644
--- a/source/blender/editors/include/ED_curve.h
+++ b/source/blender/editors/include/ED_curve.h
@@ -66,7 +66,7 @@ int ED_curve_nurb_select_count(struct View3D *v3d, struct Nurb *nu);
bool ED_curve_nurb_select_all(const struct Nurb *nu);
bool ED_curve_nurb_deselect_all(const struct Nurb *nu);
-int join_curve_exec(struct bContext *C, struct wmOperator *op);
+int ED_curve_join_objects_exec(struct bContext *C, struct wmOperator *op);
/* editcurve_select.c */
bool ED_curve_select_check(struct View3D *v3d, struct EditNurb *editnurb);
diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h
index 2a1d9c2dd6c..f961f835f12 100644
--- a/source/blender/editors/include/ED_gpencil.h
+++ b/source/blender/editors/include/ED_gpencil.h
@@ -87,15 +87,24 @@ typedef enum eGP_ReprojectModes {
* Used as part of the 'stroke cache' used during drawing of new strokes
*/
typedef struct tGPspoint {
- float x, y; /* x and y coordinates of cursor (in relative to area) */
- float pressure; /* pressure of tablet at this point */
- float strength; /* pressure of tablet at this point for alpha factor */
- float time; /* Time relative to stroke start (used when converting to path) */
- float uv_fac; /* factor of uv along the stroke */
- float uv_rot; /* uv rotation for dor mode */
- float rnd[3]; /* rnd value */
- bool rnd_dirty; /* rnd flag */
- float vert_color[4]; /* Point vertex color. */
+ /** Coordinates x and y of cursor (in relative to area). */
+ float x, y;
+ /** Pressure of tablet at this point. */
+ float pressure;
+ /** Pressure of tablet at this point for alpha factor. */
+ float strength;
+ /** Time relative to stroke start (used when converting to path). */
+ float time;
+ /** Factor of uv along the stroke. */
+ float uv_fac;
+ /** UV rotation for dot mode. */
+ float uv_rot;
+ /** Random value. */
+ float rnd[3];
+ /** Random flag. */
+ bool rnd_dirty;
+ /** Point vertex color. */
+ float vert_color[4];
} tGPspoint;
/* ----------- Grease Pencil Tools/Context ------------- */
@@ -166,28 +175,31 @@ void ED_annotation_draw_ex(struct Scene *scene,
const char spacetype);
/* ----------- Grease-Pencil AnimEdit API ------------------ */
-bool ED_gplayer_frames_looper(struct bGPDlayer *gpl,
- struct Scene *scene,
- short (*gpf_cb)(struct bGPDframe *, struct Scene *));
-void ED_gplayer_make_cfra_list(struct bGPDlayer *gpl, ListBase *elems, bool onlysel);
-
-bool ED_gplayer_frame_select_check(struct bGPDlayer *gpl);
-void ED_gplayer_frame_select_set(struct bGPDlayer *gpl, short mode);
-void ED_gplayer_frames_select_box(struct bGPDlayer *gpl, float min, float max, short select_mode);
-void ED_gplayer_frames_select_region(struct KeyframeEditData *ked,
- struct bGPDlayer *gpl,
- short tool,
- short select_mode);
+bool ED_gpencil_layer_frames_looper(struct bGPDlayer *gpl,
+ struct Scene *scene,
+ short (*gpf_cb)(struct bGPDframe *, struct Scene *));
+void ED_gpencil_layer_make_cfra_list(struct bGPDlayer *gpl, ListBase *elems, bool onlysel);
+
+bool ED_gpencil_layer_frame_select_check(struct bGPDlayer *gpl);
+void ED_gpencil_layer_frame_select_set(struct bGPDlayer *gpl, short mode);
+void ED_gpencil_layer_frames_select_box(struct bGPDlayer *gpl,
+ float min,
+ float max,
+ short select_mode);
+void ED_gpencil_layer_frames_select_region(struct KeyframeEditData *ked,
+ struct bGPDlayer *gpl,
+ short tool,
+ short select_mode);
void ED_gpencil_select_frames(struct bGPDlayer *gpl, short select_mode);
void ED_gpencil_select_frame(struct bGPDlayer *gpl, int selx, short select_mode);
-bool ED_gplayer_frames_delete(struct bGPDlayer *gpl);
-void ED_gplayer_frames_duplicate(struct bGPDlayer *gpl);
+bool ED_gpencil_layer_frames_delete(struct bGPDlayer *gpl);
+void ED_gpencil_layer_frames_duplicate(struct bGPDlayer *gpl);
-void ED_gplayer_frames_keytype_set(struct bGPDlayer *gpl, short type);
+void ED_gpencil_layer_frames_keytype_set(struct bGPDlayer *gpl, short type);
-void ED_gplayer_snap_frames(struct bGPDlayer *gpl, struct Scene *scene, short mode);
-void ED_gplayer_mirror_frames(struct bGPDlayer *gpl, struct Scene *scene, short mode);
+void ED_gpencil_layer_snap_frames(struct bGPDlayer *gpl, struct Scene *scene, short mode);
+void ED_gpencil_layer_mirror_frames(struct bGPDlayer *gpl, struct Scene *scene, short mode);
void ED_gpencil_anim_copybuf_free(void);
bool ED_gpencil_anim_copybuf_copy(struct bAnimContext *ac);
@@ -242,18 +254,18 @@ void ED_gpencil_add_defaults(struct bContext *C, struct Object *ob);
void ED_gpencil_setup_modes(struct bContext *C, struct bGPdata *gpd, int newmode);
bool ED_object_gpencil_exit(struct Main *bmain, struct Object *ob);
-void ED_gp_project_stroke_to_plane(const struct Scene *scene,
- const struct Object *ob,
- const struct RegionView3D *rv3d,
- struct bGPDstroke *gps,
- const float origin[3],
- const int axis);
-void ED_gp_project_point_to_plane(const struct Scene *scene,
- const struct Object *ob,
- const struct RegionView3D *rv3d,
- const float origin[3],
- const int axis,
- struct bGPDspoint *pt);
+void ED_gpencil_project_stroke_to_plane(const struct Scene *scene,
+ const struct Object *ob,
+ const struct RegionView3D *rv3d,
+ struct bGPDstroke *gps,
+ const float origin[3],
+ const int axis);
+void ED_gpencil_project_point_to_plane(const struct Scene *scene,
+ const struct Object *ob,
+ const struct RegionView3D *rv3d,
+ const float origin[3],
+ const int axis,
+ struct bGPDspoint *pt);
void ED_gpencil_drawing_reference_get(const struct Scene *scene,
const struct Object *ob,
char align_flag,
diff --git a/source/blender/editors/include/ED_mball.h b/source/blender/editors/include/ED_mball.h
index 938d1059f90..5c2106b934c 100644
--- a/source/blender/editors/include/ED_mball.h
+++ b/source/blender/editors/include/ED_mball.h
@@ -38,8 +38,12 @@ void ED_operatortypes_metaball(void);
void ED_operatormacros_metaball(void);
void ED_keymap_metaball(struct wmKeyConfig *keyconf);
-struct MetaElem *ED_mball_add_primitive(
- struct bContext *C, struct Object *obedit, float mat[4][4], float dia, int type);
+struct MetaElem *ED_mball_add_primitive(struct bContext *C,
+ struct Object *obedit,
+ bool obedit_is_new,
+ float mat[4][4],
+ float dia,
+ int type);
bool ED_mball_select_pick(
struct bContext *C, const int mval[2], bool extend, bool deselect, bool toggle);
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index 20e54df1ccb..9c49d991182 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -426,6 +426,15 @@ bool ED_mesh_color_remove_index(struct Mesh *me, const int n);
bool ED_mesh_color_remove_active(struct Mesh *me);
bool ED_mesh_color_remove_named(struct Mesh *me, const char *name);
+bool ED_mesh_sculpt_color_ensure(struct Mesh *me, const char *name);
+int ED_mesh_sculpt_color_add(struct Mesh *me,
+ const char *name,
+ const bool active_set,
+ const bool do_init);
+bool ED_mesh_sculpt_color_remove_index(struct Mesh *me, const int n);
+bool ED_mesh_sculpt_color_remove_active(struct Mesh *me);
+bool ED_mesh_sculpt_color_remove_named(struct Mesh *me, const char *name);
+
void ED_mesh_report_mirror(struct wmOperator *op, int totmirr, int totfail);
void ED_mesh_report_mirror_ex(struct wmOperator *op, int totmirr, int totfail, char selectmode);
@@ -445,8 +454,8 @@ void EDBM_redo_state_restore(struct BMBackup, struct BMEditMesh *em, int recalct
void EDBM_redo_state_free(struct BMBackup *, struct BMEditMesh *em, int recalctess);
/* *** meshtools.c *** */
-int join_mesh_exec(struct bContext *C, struct wmOperator *op);
-int join_mesh_shapes_exec(struct bContext *C, struct wmOperator *op);
+int ED_mesh_join_objects_exec(struct bContext *C, struct wmOperator *op);
+int ED_mesh_shapes_join_objects_exec(struct bContext *C, struct wmOperator *op);
/* mirror lookup api */
/* Spatial Mirror */
diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h
index 5c33513f0a4..73c58753531 100644
--- a/source/blender/editors/include/ED_object.h
+++ b/source/blender/editors/include/ED_object.h
@@ -185,7 +185,7 @@ struct Base *ED_object_add_duplicate(struct Main *bmain,
struct Scene *scene,
struct ViewLayer *view_layer,
struct Base *base,
- int dupflag);
+ const uint dupflag);
void ED_object_parent(struct Object *ob,
struct Object *parent,
@@ -421,6 +421,10 @@ int ED_object_gpencil_modifier_move_down(struct ReportList *reports,
int ED_object_gpencil_modifier_move_up(struct ReportList *reports,
struct Object *ob,
struct GpencilModifierData *md);
+bool ED_object_gpencil_modifier_move_to_index(struct ReportList *reports,
+ struct Object *ob,
+ struct GpencilModifierData *md,
+ const int index);
int ED_object_gpencil_modifier_apply(struct Main *bmain,
struct ReportList *reports,
struct Depsgraph *depsgraph,
@@ -449,6 +453,10 @@ int ED_object_shaderfx_move_down(struct ReportList *reports,
int ED_object_shaderfx_move_up(struct ReportList *reports,
struct Object *ob,
struct ShaderFxData *fx);
+bool ED_object_shaderfx_move_to_index(struct ReportList *reports,
+ struct Object *ob,
+ struct ShaderFxData *fx,
+ const int index);
/* object_select.c */
void ED_object_select_linked_by_id(struct bContext *C, struct ID *id);
diff --git a/source/blender/editors/include/ED_render.h b/source/blender/editors/include/ED_render.h
index f03739c74c4..ba70abcc055 100644
--- a/source/blender/editors/include/ED_render.h
+++ b/source/blender/editors/include/ED_render.h
@@ -47,7 +47,7 @@ void ED_operatortypes_render(void);
/* render_update.c */
-void ED_render_engine_changed(struct Main *bmain);
+void ED_render_engine_changed(struct Main *bmain, const bool update_scene_data);
void ED_render_engine_area_exit(struct Main *bmain, struct ScrArea *area);
void ED_render_view_layer_changed(struct Main *bmain, struct bScreen *screen);
diff --git a/source/blender/editors/include/ED_screen_types.h b/source/blender/editors/include/ED_screen_types.h
index 51f3eea74fa..9826ec8c3b8 100644
--- a/source/blender/editors/include/ED_screen_types.h
+++ b/source/blender/editors/include/ED_screen_types.h
@@ -131,7 +131,7 @@ enum {
*/
AZONE_FULLSCREEN,
/**
- * Hotspot azone around scroll-bars to show/hide them.
+ * Hot-spot #AZone around scroll-bars to show/hide them.
* Only show the scroll-bars when the cursor is close.
*/
AZONE_REGION_SCROLL,
diff --git a/source/blender/editors/include/ED_time_scrub_ui.h b/source/blender/editors/include/ED_time_scrub_ui.h
index d5b9fa2a553..483dce56577 100644
--- a/source/blender/editors/include/ED_time_scrub_ui.h
+++ b/source/blender/editors/include/ED_time_scrub_ui.h
@@ -32,6 +32,11 @@ struct bContext;
struct bDopeSheet;
struct wmEvent;
+void ED_time_scrub_draw_current_frame(const struct ARegion *region,
+ const struct Scene *scene,
+ bool display_seconds,
+ bool draw_vert_line);
+
void ED_time_scrub_draw(const struct ARegion *region,
const struct Scene *scene,
bool display_seconds,
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 59dcc9a8ace..1cedd4e122f 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -1706,12 +1706,17 @@ void UI_panel_category_draw_all(struct ARegion *region, const char *category_id_
struct PanelType *UI_paneltype_find(int space_id, int region_id, const char *idname);
+struct PointerRNA *UI_region_panel_custom_data_under_cursor(const struct bContext *C,
+ const struct wmEvent *event);
+void UI_panel_custom_data_set(struct Panel *panel, struct PointerRNA *custom_data);
+
/* Polyinstantiated panels for representing a list of data. */
struct Panel *UI_panel_add_instanced(struct ScrArea *area,
struct ARegion *region,
struct ListBase *panels,
char *panel_idname,
- int list_index);
+ int list_index,
+ struct PointerRNA *custom_data);
void UI_panels_free_instanced(struct bContext *C, struct ARegion *region);
#define LIST_PANEL_UNIQUE_STR_LEN 4
@@ -2004,6 +2009,10 @@ void uiTemplatePathBuilder(uiLayout *layout,
struct PointerRNA *root_ptr,
const char *text);
void uiTemplateModifiers(uiLayout *layout, struct bContext *C);
+void uiTemplateGpencilModifiers(uiLayout *layout, struct bContext *C);
+void uiTemplateShaderFx(uiLayout *layout, struct bContext *C);
+void uiTemplateConstraints(uiLayout *layout, struct bContext *C, bool use_bone_constraints);
+
uiLayout *uiTemplateGpencilModifier(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr);
void uiTemplateGpencilColorPreview(uiLayout *layout,
struct bContext *C,
@@ -2014,11 +2023,9 @@ void uiTemplateGpencilColorPreview(uiLayout *layout,
float scale,
int filter);
-uiLayout *uiTemplateShaderFx(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr);
-
void uiTemplateOperatorRedoProperties(uiLayout *layout, const struct bContext *C);
-uiLayout *uiTemplateConstraint(uiLayout *layout, struct PointerRNA *ptr);
+void uiTemplateConstraintHeader(uiLayout *layout, struct PointerRNA *ptr);
void uiTemplatePreview(uiLayout *layout,
struct bContext *C,
struct ID *id,
diff --git a/source/blender/editors/include/UI_interface_icons.h b/source/blender/editors/include/UI_interface_icons.h
index a304c76bc9d..0529ee08da6 100644
--- a/source/blender/editors/include/UI_interface_icons.h
+++ b/source/blender/editors/include/UI_interface_icons.h
@@ -106,6 +106,7 @@ struct PreviewImage *UI_icon_to_preview(int icon_id);
int UI_rnaptr_icon_get(struct bContext *C, struct PointerRNA *ptr, int rnaicon, const bool big);
int UI_idcode_icon_get(const int idcode);
+int UI_library_icon_get(const struct ID *id);
#ifdef __cplusplus
}
diff --git a/source/blender/editors/include/UI_view2d.h b/source/blender/editors/include/UI_view2d.h
index ffc06e94a90..0ddc45f4878 100644
--- a/source/blender/editors/include/UI_view2d.h
+++ b/source/blender/editors/include/UI_view2d.h
@@ -180,9 +180,10 @@ void UI_view2d_draw_scale_x__frames_or_seconds(const struct ARegion *region,
int colorid);
/* scrollbar drawing */
-View2DScrollers *UI_view2d_scrollers_calc(struct View2D *v2d, const struct rcti *mask_custom);
-void UI_view2d_scrollers_draw(struct View2D *v2d, View2DScrollers *scrollers);
-void UI_view2d_scrollers_free(View2DScrollers *scrollers);
+void UI_view2d_scrollers_calc(struct View2D *v2d,
+ const struct rcti *mask_custom,
+ struct View2DScrollers *r_scrollers);
+void UI_view2d_scrollers_draw(struct View2D *v2d, const struct rcti *mask_custom);
/* list view tools */
void UI_view2d_listview_view_to_cell(float columnwidth,
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 04c259ab092..55f41913499 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -1504,7 +1504,7 @@ static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block)
void ui_but_override_flag(uiBut *but)
{
- const int override_status = RNA_property_override_library_status(
+ const uint override_status = RNA_property_override_library_status(
&but->rnapoin, but->rnaprop, but->rnaindex);
if (override_status & RNA_OVERRIDE_STATUS_OVERRIDDEN) {
@@ -6422,7 +6422,7 @@ void UI_but_func_search_set_context_menu(uiBut *but, uiButSearchContextMenuFn co
}
/**
- * \param separator_string: when not NULL, this string is used as a separator,
+ * \param search_sep_string: when not NULL, this string is used as a separator,
* showing the icon and highlighted text after the last instance of this string.
*/
void UI_but_func_search_set_sep_string(uiBut *but, const char *search_sep_string)
diff --git a/source/blender/editors/interface/interface_context_menu.c b/source/blender/editors/interface/interface_context_menu.c
index cc370113422..15d00d8537b 100644
--- a/source/blender/editors/interface/interface_context_menu.c
+++ b/source/blender/editors/interface/interface_context_menu.c
@@ -561,7 +561,7 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but)
const bool is_array_component = (is_array && but->rnaindex != -1);
const bool is_whole_array = (is_array && but->rnaindex == -1);
- const int override_status = RNA_property_override_library_status(ptr, prop, -1);
+ const uint override_status = RNA_property_override_library_status(ptr, prop, -1);
const bool is_overridable = (override_status & RNA_OVERRIDE_STATUS_OVERRIDABLE) != 0;
/* Set the (button_pointer, button_prop)
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index 499d2f7f1fa..720a5bcff37 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -25,6 +25,7 @@
#include <string.h>
#include "DNA_color_types.h"
+#include "DNA_curve_types.h"
#include "DNA_curveprofile_types.h"
#include "DNA_movieclip_types.h"
#include "DNA_screen_types.h"
@@ -118,51 +119,53 @@ void UI_draw_roundbox_aa(
bool filled, float minx, float miny, float maxx, float maxy, float rad, const float color[4])
{
uiWidgetBaseParameters widget_params = {
- .recti.xmin = minx,
- .recti.ymin = miny,
- .recti.xmax = maxx,
- .recti.ymax = maxy,
+ .recti.xmin = minx + U.pixelsize,
+ .recti.ymin = miny + U.pixelsize,
+ .recti.xmax = maxx - U.pixelsize,
+ .recti.ymax = maxy - U.pixelsize,
+ .rect.xmin = minx,
+ .rect.ymin = miny,
+ .rect.xmax = maxx,
+ .rect.ymax = maxy,
.radi = rad,
+ .rad = rad,
.round_corners[0] = (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 1.0f : 0.0f,
.round_corners[1] = (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 1.0f : 0.0f,
.round_corners[2] = (roundboxtype & UI_CNR_TOP_RIGHT) ? 1.0f : 0.0f,
.round_corners[3] = (roundboxtype & UI_CNR_TOP_LEFT) ? 1.0f : 0.0f,
- .color_inner1[0] = color[0],
- .color_inner2[0] = color[0],
- .color_inner1[1] = color[1],
- .color_inner2[1] = color[1],
- .color_inner1[2] = color[2],
- .color_inner2[2] = color[2],
- .color_inner1[3] = color[3],
- .color_inner2[3] = color[3],
+ .color_inner1[0] = filled ? color[0] : 0.0f,
+ .color_inner1[1] = filled ? color[1] : 0.0f,
+ .color_inner1[2] = filled ? color[2] : 0.0f,
+ .color_inner1[3] = filled ? color[3] : 0.0f,
+ .color_inner2[0] = filled ? color[0] : 0.0f,
+ .color_inner2[1] = filled ? color[1] : 0.0f,
+ .color_inner2[2] = filled ? color[2] : 0.0f,
+ .color_inner2[3] = filled ? color[3] : 0.0f,
+ .color_outline[0] = color[0],
+ .color_outline[1] = color[1],
+ .color_outline[2] = color[2],
+ .color_outline[3] = color[3],
.alpha_discard = 1.0f,
};
- GPU_blend(true);
-
+ /* XXX this is to emulate previous behavior of semitransparent fills but that's was a side effect
+ * of the previous AA method. Better fix the callers. */
if (filled) {
- /* plain antialiased filled box */
- widget_params.color_inner1[3] *= 0.125f;
- widget_params.color_inner2[3] *= 0.125f;
-
- /* WATCH: This is assuming the ModelViewProjectionMatrix is area pixel space.
- * If it has been scaled, then it's no longer valid. */
- GPUBatch *batch = ui_batch_roundbox_get(filled, true);
- GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
- GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params);
- GPU_batch_draw(batch);
+ widget_params.color_inner1[3] *= 0.65f;
+ widget_params.color_inner2[3] *= 0.65f;
+ widget_params.color_outline[3] *= 0.65f;
}
- else {
- /* plain antialiased unfilled box */
- GPU_line_smooth(true);
- GPUBatch *batch = ui_batch_roundbox_get(filled, false);
- GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
- GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params);
- GPU_batch_draw(batch);
+ /* WATCH: This is assuming the ModelViewProjectionMatrix is area pixel space.
+ * If it has been scaled, then it's no longer valid. */
- GPU_line_smooth(false);
- }
+ GPUBatch *batch = ui_batch_roundbox_widget_get();
+ GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
+ GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params);
+
+ GPU_blend(true);
+
+ GPU_batch_draw(batch);
GPU_blend(false);
}
@@ -251,32 +254,49 @@ void UI_draw_roundbox_4fv(
immEnd();
immUnbindProgram();
#endif
-
uiWidgetBaseParameters widget_params = {
- .recti.xmin = minx,
- .recti.ymin = miny,
- .recti.xmax = maxx,
- .recti.ymax = maxy,
+ .recti.xmin = minx + U.pixelsize,
+ .recti.ymin = miny + U.pixelsize,
+ .recti.xmax = maxx - U.pixelsize,
+ .recti.ymax = maxy - U.pixelsize,
+ .rect.xmin = minx,
+ .rect.ymin = miny,
+ .rect.xmax = maxx,
+ .rect.ymax = maxy,
.radi = rad,
+ .rad = rad,
.round_corners[0] = (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 1.0f : 0.0f,
.round_corners[1] = (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 1.0f : 0.0f,
.round_corners[2] = (roundboxtype & UI_CNR_TOP_RIGHT) ? 1.0f : 0.0f,
.round_corners[3] = (roundboxtype & UI_CNR_TOP_LEFT) ? 1.0f : 0.0f,
- .color_inner1[0] = col[0],
- .color_inner2[0] = col[0],
- .color_inner1[1] = col[1],
- .color_inner2[1] = col[1],
- .color_inner1[2] = col[2],
- .color_inner2[2] = col[2],
- .color_inner1[3] = col[3],
- .color_inner2[3] = col[3],
+ .color_inner1[0] = filled ? col[0] : 0.0f,
+ .color_inner1[1] = filled ? col[1] : 0.0f,
+ .color_inner1[2] = filled ? col[2] : 0.0f,
+ .color_inner1[3] = filled ? col[3] : 0.0f,
+ .color_inner2[0] = filled ? col[0] : 0.0f,
+ .color_inner2[1] = filled ? col[1] : 0.0f,
+ .color_inner2[2] = filled ? col[2] : 0.0f,
+ .color_inner2[3] = filled ? col[3] : 0.0f,
+ .color_outline[0] = col[0],
+ .color_outline[1] = col[1],
+ .color_outline[2] = col[2],
+ .color_outline[3] = col[3],
.alpha_discard = 1.0f,
};
+ /* Exactly the same as UI_draw_roundbox_aa but does not do the legacy transparency. */
- GPUBatch *batch = ui_batch_roundbox_get(filled, false);
+ /* WATCH: This is assuming the ModelViewProjectionMatrix is area pixel space.
+ * If it has been scaled, then it's no longer valid. */
+
+ GPUBatch *batch = ui_batch_roundbox_widget_get();
GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params);
+
+ GPU_blend(true);
+
GPU_batch_draw(batch);
+
+ GPU_blend(false);
}
#if 0
@@ -427,32 +447,46 @@ void UI_draw_roundbox_shade_x(bool filled,
immEnd();
immUnbindProgram();
#endif
-
uiWidgetBaseParameters widget_params = {
- .recti.xmin = minx,
- .recti.ymin = miny,
- .recti.xmax = maxx,
- .recti.ymax = maxy,
+ .recti.xmin = minx + U.pixelsize,
+ .recti.ymin = miny + U.pixelsize,
+ .recti.xmax = maxx - U.pixelsize,
+ .recti.ymax = maxy - U.pixelsize,
+ .rect.xmin = minx,
+ .rect.ymin = miny,
+ .rect.xmax = maxx,
+ .rect.ymax = maxy,
.radi = rad,
+ .rad = rad,
.round_corners[0] = (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 1.0f : 0.0f,
.round_corners[1] = (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 1.0f : 0.0f,
.round_corners[2] = (roundboxtype & UI_CNR_TOP_RIGHT) ? 1.0f : 0.0f,
.round_corners[3] = (roundboxtype & UI_CNR_TOP_LEFT) ? 1.0f : 0.0f,
- .color_inner1[0] = min_ff(1.0f, col[0] + shadetop),
- .color_inner2[0] = max_ff(0.0f, col[0] + shadedown),
- .color_inner1[1] = min_ff(1.0f, col[1] + shadetop),
- .color_inner2[1] = max_ff(0.0f, col[1] + shadedown),
- .color_inner1[2] = min_ff(1.0f, col[2] + shadetop),
- .color_inner2[2] = max_ff(0.0f, col[2] + shadedown),
- .color_inner1[3] = 1.0f,
- .color_inner2[3] = 1.0f,
+ .color_inner1[0] = !filled ? 0.0f : min_ff(1.0f, col[0] + shadetop),
+ .color_inner1[1] = !filled ? 0.0f : min_ff(1.0f, col[1] + shadetop),
+ .color_inner1[2] = !filled ? 0.0f : min_ff(1.0f, col[2] + shadetop),
+ .color_inner1[3] = !filled ? 0.0f : 1.0f,
+ .color_inner2[0] = !filled ? 0.0f : max_ff(0.0f, col[0] + shadedown),
+ .color_inner2[1] = !filled ? 0.0f : max_ff(0.0f, col[1] + shadedown),
+ .color_inner2[2] = !filled ? 0.0f : max_ff(0.0f, col[2] + shadedown),
+ .color_inner2[3] = !filled ? 0.0f : 1.0f,
+ /* TODO: non-filled box don't have gradients. Just use middle color. */
+ .color_outline[0] = clamp_f(col[0] + shadetop + shadedown, 0.0f, 1.0f),
+ .color_outline[1] = clamp_f(col[1] + shadetop + shadedown, 0.0f, 1.0f),
+ .color_outline[2] = clamp_f(col[2] + shadetop + shadedown, 0.0f, 1.0f),
+ .color_outline[3] = clamp_f(col[3] + shadetop + shadedown, 0.0f, 1.0f),
+ .shade_dir = 1.0f,
.alpha_discard = 1.0f,
};
- GPUBatch *batch = ui_batch_roundbox_get(filled, false);
+ GPU_blend(true);
+
+ GPUBatch *batch = ui_batch_roundbox_widget_get();
GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params);
GPU_batch_draw(batch);
+
+ GPU_blend(false);
}
#if 0 /* unused */
@@ -765,10 +799,8 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(region),
*
* \note This function is to be used with the 2D dashed shader enabled.
*
- * \param pos: is a PRIM_FLOAT, 2, GPU_FETCH_FLOAT vertex attribute.
- * \param line_origin: is a PRIM_FLOAT, 2, GPU_FETCH_FLOAT vertex attribute.
- *
- * The next 4 parameters are the offsets for the view, not the zones.
+ * \param pos: is a #PRIM_FLOAT, 2, #GPU_FETCH_FLOAT vertex attribute.
+ * \param x1, x2, y1, y2: The offsets for the view, not the zones.
*/
void UI_draw_safe_areas(uint pos,
float x1,
@@ -801,7 +833,7 @@ void UI_draw_safe_areas(uint pos,
static void draw_scope_end(const rctf *rect, GLint *scissor)
{
- /* restore scissortest */
+ /* Restore scissor test. */
GPU_scissor(scissor[0], scissor[1], scissor[2], scissor[3]);
GPU_blend_set_func_separate(
@@ -2131,7 +2163,19 @@ void ui_draw_but_CURVE(ARegion *region, uiBut *but, const uiWidgetColors *wcol,
immUnbindProgram();
}
-/** Used to draw a curve profile widget. Somewhat similar to ui_draw_but_CURVE */
+/**
+ * Helper for #ui_draw_but_CURVEPROFILE. Used to tell whether to draw a control point's handles.
+ */
+static bool point_draw_handles(CurveProfilePoint *point)
+{
+ return (point->flag & PROF_SELECT &&
+ (ELEM(point->h1, HD_FREE, HD_ALIGN) || ELEM(point->h2, HD_FREE, HD_ALIGN))) ||
+ ELEM(point->flag, PROF_H1_SELECT, PROF_H2_SELECT);
+}
+
+/**
+ * Draws the curve profile widget. Somewhat similar to ui_draw_but_CURVE.
+ */
void ui_draw_but_CURVEPROFILE(ARegion *region,
uiBut *but,
const uiWidgetColors *wcol,
@@ -2147,18 +2191,18 @@ void ui_draw_but_CURVEPROFILE(ARegion *region,
profile = (CurveProfile *)but->poin;
}
- /* Calculate offset and zoom */
+ /* Calculate offset and zoom. */
float zoomx = (BLI_rcti_size_x(rect) - 2.0f) / BLI_rctf_size_x(&profile->view_rect);
float zoomy = (BLI_rcti_size_y(rect) - 2.0f) / BLI_rctf_size_y(&profile->view_rect);
float offsx = profile->view_rect.xmin - (1.0f / zoomx);
float offsy = profile->view_rect.ymin - (1.0f / zoomy);
- /* Exit early if too narrow */
+ /* Exit early if too narrow. */
if (zoomx == 0.0f) {
return;
}
- /* Test needed because path can draw outside of boundary */
+ /* Test needed because path can draw outside of boundary. */
int scissor[4];
GPU_scissor_get_i(scissor);
rcti scissor_new = {
@@ -2180,7 +2224,7 @@ void ui_draw_but_CURVEPROFILE(ARegion *region,
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- /* Backdrop */
+ /* Draw the backdrop. */
float color_backdrop[4] = {0, 0, 0, 1};
if (profile->flag & PROF_USE_CLIP) {
gl_shaded_color_get_fl((uchar *)wcol->inner, -20, color_backdrop);
@@ -2199,33 +2243,33 @@ void ui_draw_but_CURVEPROFILE(ARegion *region,
immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
}
- /* 0.25 step grid */
+ /* 0.25 step grid. */
gl_shaded_color((uchar *)wcol->inner, -16);
ui_draw_but_curve_grid(pos, rect, zoomx, zoomy, offsx, offsy, 0.25f);
- /* 1.0 step grid */
+ /* 1.0 step grid. */
gl_shaded_color((uchar *)wcol->inner, -24);
ui_draw_but_curve_grid(pos, rect, zoomx, zoomy, offsx, offsy, 1.0f);
- /* Draw the path's fill */
+ /* Draw the path's fill. */
if (profile->table == NULL) {
- BKE_curveprofile_update(profile, false);
+ BKE_curveprofile_update(profile, PROF_UPDATE_NONE);
}
CurveProfilePoint *pts = profile->table;
- /* Also add the last points on the right and bottom edges to close off the fill polygon */
+ /* Also add the last points on the right and bottom edges to close off the fill polygon. */
bool add_left_tri = profile->view_rect.xmin < 0.0f;
bool add_bottom_tri = profile->view_rect.ymin < 0.0f;
uint tot_points = (uint)PROF_N_TABLE(profile->path_len) + 1 + add_left_tri + add_bottom_tri;
uint tot_triangles = tot_points - 2;
- /* Create array of the positions of the table's points */
+ /* Create array of the positions of the table's points. */
float(*table_coords)[2] = MEM_mallocN(sizeof(*table_coords) * tot_points, "table x coords");
for (i = 0; i < (uint)PROF_N_TABLE(profile->path_len);
- i++) { /* Only add the points from the table here */
+ i++) { /* Only add the points from the table here. */
table_coords[i][0] = pts[i].x;
table_coords[i][1] = pts[i].y;
}
if (add_left_tri && add_bottom_tri) {
- /* Add left side, bottom left corner, and bottom side points */
+ /* Add left side, bottom left corner, and bottom side points. */
table_coords[tot_points - 3][0] = profile->view_rect.xmin;
table_coords[tot_points - 3][1] = 1.0f;
table_coords[tot_points - 2][0] = profile->view_rect.xmin;
@@ -2234,30 +2278,30 @@ void ui_draw_but_CURVEPROFILE(ARegion *region,
table_coords[tot_points - 1][1] = profile->view_rect.ymin;
}
else if (add_left_tri) {
- /* Add the left side and bottom left corner points */
+ /* Add the left side and bottom left corner points. */
table_coords[tot_points - 2][0] = profile->view_rect.xmin;
table_coords[tot_points - 2][1] = 1.0f;
table_coords[tot_points - 1][0] = profile->view_rect.xmin;
table_coords[tot_points - 1][1] = 0.0f;
}
else if (add_bottom_tri) {
- /* Add the bottom side and bottom left corner points */
+ /* Add the bottom side and bottom left corner points. */
table_coords[tot_points - 2][0] = 0.0f;
table_coords[tot_points - 2][1] = profile->view_rect.ymin;
table_coords[tot_points - 1][0] = 1.0f;
table_coords[tot_points - 1][1] = profile->view_rect.ymin;
}
else {
- /* Just add the bottom corner point. Side points would be redundant anyway */
+ /* Just add the bottom corner point. Side points would be redundant anyway. */
table_coords[tot_points - 1][0] = 0.0f;
table_coords[tot_points - 1][1] = 0.0f;
}
- /* Calculate the table point indices of the triangles for the profile's fill */
+ /* Calculate the table point indices of the triangles for the profile's fill. */
uint(*tri_indices)[3] = MEM_mallocN(sizeof(*tri_indices) * tot_triangles, "return tri indices");
BLI_polyfill_calc(table_coords, tot_points, -1, tri_indices);
- /* Draw the triangles for the profile fill */
+ /* Draw the triangles for the profile fill. */
immUniformColor3ubvAlpha((const uchar *)wcol->item, 128);
GPU_blend(true);
GPU_polygon_smooth(false);
@@ -2273,7 +2317,7 @@ void ui_draw_but_CURVEPROFILE(ARegion *region,
immEnd();
MEM_freeN(tri_indices);
- /* Draw the profile's path so the edge stands out a bit */
+ /* Draw the profile's path so the edge stands out a bit. */
tot_points -= (add_left_tri + add_left_tri);
GPU_line_width(1.0f);
immUniformColor3ubvAlpha((const uchar *)wcol->item, 255);
@@ -2285,9 +2329,44 @@ void ui_draw_but_CURVEPROFILE(ARegion *region,
immVertex2f(pos, fx, fy);
}
immEnd();
- immUnbindProgram();
MEM_freeN(table_coords);
+ /* Draw the handles for the selected control points. */
+ pts = profile->path;
+ tot_points = (uint)profile->path_len;
+ int selected_free_points = 0;
+ for (i = 0; i < tot_points; i++) {
+ if (point_draw_handles(&pts[i])) {
+ selected_free_points++;
+ }
+ }
+ /* Draw the lines to the handles from the points. */
+ if (selected_free_points > 0) {
+ GPU_line_width(1.0f);
+ gl_shaded_color((uchar *)wcol->inner, -24);
+ GPU_line_smooth(true);
+ immBegin(GPU_PRIM_LINES, selected_free_points * 4);
+ float ptx, pty;
+ for (i = 0; i < tot_points; i++) {
+ if (point_draw_handles(&pts[i])) {
+ ptx = rect->xmin + zoomx * (pts[i].x - offsx);
+ pty = rect->ymin + zoomy * (pts[i].y - offsy);
+
+ fx = rect->xmin + zoomx * (pts[i].h1_loc[0] - offsx);
+ fy = rect->ymin + zoomy * (pts[i].h1_loc[1] - offsy);
+ immVertex2f(pos, ptx, pty);
+ immVertex2f(pos, fx, fy);
+
+ fx = rect->xmin + zoomx * (pts[i].h2_loc[0] - offsx);
+ fy = rect->ymin + zoomy * (pts[i].h2_loc[1] - offsy);
+ immVertex2f(pos, ptx, pty);
+ immVertex2f(pos, fx, fy);
+ }
+ }
+ immEnd();
+ }
+ immUnbindProgram();
+
/* New GPU instructions for control points and sampled points. */
format = immVertexFormat();
pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
@@ -2311,8 +2390,6 @@ void ui_draw_but_CURVEPROFILE(ARegion *region,
}
/* Draw the control points. */
- pts = profile->path;
- tot_points = (uint)profile->path_len;
GPU_line_smooth(false);
GPU_blend(false);
GPU_point_size(max_ff(3.0f, min_ff(UI_DPI_FAC / but->block->aspect * 5.0f, 5.0f)));
@@ -2325,6 +2402,28 @@ void ui_draw_but_CURVEPROFILE(ARegion *region,
}
immEnd();
+ /* Draw the handle points. */
+ if (selected_free_points > 0) {
+ GPU_line_smooth(false);
+ GPU_blend(false);
+ GPU_point_size(max_ff(2.0f, min_ff(UI_DPI_FAC / but->block->aspect * 4.0f, 4.0f)));
+ immBegin(GPU_PRIM_POINTS, selected_free_points * 2);
+ for (i = 0; i < tot_points; i++) {
+ if (point_draw_handles(&pts[i])) {
+ fx = rect->xmin + zoomx * (pts[i].h1_loc[0] - offsx);
+ fy = rect->ymin + zoomy * (pts[i].h1_loc[1] - offsy);
+ immAttr4fv(col, (pts[i].flag & PROF_H1_SELECT) ? color_vert_select : color_vert);
+ immVertex2f(pos, fx, fy);
+
+ fx = rect->xmin + zoomx * (pts[i].h2_loc[0] - offsx);
+ fy = rect->ymin + zoomy * (pts[i].h2_loc[1] - offsy);
+ immAttr4fv(col, (pts[i].flag & PROF_H2_SELECT) ? color_vert_select : color_vert);
+ immVertex2f(pos, fx, fy);
+ }
+ }
+ immEnd();
+ }
+
/* Draw the sampled points in addition to the control points if they have been created */
pts = profile->segments;
tot_points = (uint)profile->segments_len;
@@ -2339,7 +2438,6 @@ void ui_draw_but_CURVEPROFILE(ARegion *region,
}
immEnd();
}
-
immUnbindProgram();
/* restore scissortest */
@@ -2678,7 +2776,6 @@ void ui_draw_dropshadow(
GPU_batch_draw(batch);
/* outline emphasis */
- GPU_line_smooth(true);
float color[4] = {0.0f, 0.0f, 0.0f, 0.4f};
UI_draw_roundbox_4fv(false,
rct->xmin - 0.5f,
@@ -2687,7 +2784,6 @@ void ui_draw_dropshadow(
rct->ymax + 0.5f,
radius + 0.5f,
color);
- GPU_line_smooth(false);
GPU_blend(false);
}
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 42feda0e1bc..f6bfb492c92 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -4872,7 +4872,7 @@ static void ui_numedit_set_active(uiBut *but)
/* Don't change the cursor once pressed. */
if ((but->flag & UI_SELECT) == 0) {
- if ((but->drawflag & (UI_BUT_ACTIVE_LEFT)) || (but->drawflag & (UI_BUT_ACTIVE_RIGHT))) {
+ if ((but->drawflag & UI_BUT_ACTIVE_LEFT) || (but->drawflag & UI_BUT_ACTIVE_RIGHT)) {
if (data->changed_cursor) {
WM_cursor_modal_restore(data->window);
data->changed_cursor = false;
@@ -6944,7 +6944,7 @@ static bool ui_numedit_but_CURVEPROFILE(uiBlock *block,
d[0] = mx - data->dragstartx;
d[1] = my - data->dragstarty;
- if (len_squared_v2(d) < (3.0f * 3.0f)) {
+ if (len_squared_v2(d) < (9.0f * U.dpi_fac)) {
snap = false;
}
}
@@ -6953,32 +6953,38 @@ static bool ui_numedit_but_CURVEPROFILE(uiBlock *block,
fy = (my - dragy) / zoomy;
if (data->dragsel != -1) {
- CurveProfilePoint *point_last = NULL;
+ float last_x, last_y;
const float mval_factor = ui_mouse_scale_warp_factor(shift);
bool moved_point = false; /* for ctrl grid, can't use orig coords because of sorting */
fx *= mval_factor;
fy *= mval_factor;
- /* Move all the points that aren't the last or the first */
- for (a = 1; a < profile->path_len - 1; a++) {
- if (pts[a].flag & PROF_SELECT) {
- float origx = pts[a].x, origy = pts[a].y;
- pts[a].x += fx;
- pts[a].y += fy;
- if (snap) {
- pts[a].x = 0.125f * roundf(8.0f * pts[a].x);
- pts[a].y = 0.125f * roundf(8.0f * pts[a].y);
+ /* Move all selected points. */
+ float delta[2] = {fx, fy};
+ for (a = 0; a < profile->path_len; a++) {
+ /* Don't move the last and first control points. */
+ if ((pts[a].flag & PROF_SELECT) && (a != 0) && (a != profile->path_len)) {
+ moved_point |= BKE_curveprofile_move_point(profile, &pts[a], snap, delta);
+ last_x = pts[a].x;
+ last_y = pts[a].y;
+ }
+ else {
+ /* Move handles when they're selected but the control point isn't. */
+ if (ELEM(pts[a].h2, HD_FREE, HD_ALIGN) && pts[a].flag == PROF_H1_SELECT) {
+ moved_point |= BKE_curveprofile_move_handle(&pts[a], true, snap, delta);
+ last_x = pts[a].h1_loc[0];
+ last_y = pts[a].h1_loc[1];
}
- if (!moved_point && (pts[a].x != origx || pts[a].y != origy)) {
- moved_point = true;
+ if (ELEM(pts[a].h2, HD_FREE, HD_ALIGN) && pts[a].flag == PROF_H2_SELECT) {
+ moved_point |= BKE_curveprofile_move_handle(&pts[a], false, snap, delta);
+ last_x = pts[a].h2_loc[0];
+ last_y = pts[a].h2_loc[1];
}
-
- point_last = &pts[a];
}
}
- BKE_curveprofile_update(profile, false);
+ BKE_curveprofile_update(profile, PROF_UPDATE_NONE);
if (moved_point) {
data->draglastx = evtx;
@@ -6989,10 +6995,8 @@ static bool ui_numedit_but_CURVEPROFILE(uiBlock *block,
* but in practice this isnt really an issue */
if (ui_but_is_cursor_warp(but)) {
/* OK but can go outside bounds */
- data->ungrab_mval[0] = but->rect.xmin +
- ((point_last->x - profile->view_rect.xmin) * zoomx);
- data->ungrab_mval[1] = but->rect.ymin +
- ((point_last->y - profile->view_rect.ymin) * zoomy);
+ data->ungrab_mval[0] = but->rect.xmin + ((last_x - profile->view_rect.xmin) * zoomx);
+ data->ungrab_mval[1] = but->rect.ymin + ((last_y - profile->view_rect.ymin) * zoomy);
BLI_rctf_clamp_pt_v(&but->rect, data->ungrab_mval);
}
#endif
@@ -7000,7 +7004,7 @@ static bool ui_numedit_but_CURVEPROFILE(uiBlock *block,
data->dragchange = true; /* mark for selection */
}
else {
- /* clamp for clip */
+ /* Clamp the view rect when clipping is on. */
if (profile->flag & PROF_USE_CLIP) {
if (profile->view_rect.xmin - fx < profile->clip_rect.xmin) {
fx = profile->view_rect.xmin - profile->clip_rect.xmin;
@@ -7031,16 +7035,26 @@ static bool ui_numedit_but_CURVEPROFILE(uiBlock *block,
}
/**
+ * Helper for #ui_do_but_CURVEPROFILE. Used to tell whether to select a control point's handles.
+ */
+static bool point_draw_handles(CurveProfilePoint *point)
+{
+ return (point->flag & PROF_SELECT &&
+ (ELEM(point->h1, HD_FREE, HD_ALIGN) || ELEM(point->h2, HD_FREE, HD_ALIGN))) ||
+ ELEM(point->flag, PROF_H1_SELECT, PROF_H2_SELECT);
+}
+
+/**
* Interaction for curve profile widget.
* \note Uses hardcoded keys rather than the keymap.
*/
static int ui_do_but_CURVEPROFILE(
bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
- int mx, my, i;
+ CurveProfile *profile = (CurveProfile *)but->poin;
+ int mx = event->x;
+ int my = event->y;
- mx = event->x;
- my = event->y;
ui_window_to_block(data->region, block, &mx, &my);
/* Move selected control points. */
@@ -7053,12 +7067,10 @@ static int ui_do_but_CURVEPROFILE(
return WM_UI_HANDLER_BREAK;
}
- CurveProfile *profile = (CurveProfile *)but->poin;
-
/* Delete selected control points. */
if (event->type == EVT_XKEY && event->val == KM_RELEASE) {
BKE_curveprofile_remove_by_flag(profile, PROF_SELECT);
- BKE_curveprofile_update(profile, false);
+ BKE_curveprofile_update(profile, PROF_UPDATE_NONE);
button_activate_state(C, but, BUTTON_STATE_EXIT);
return WM_UI_HANDLER_BREAK;
}
@@ -7066,76 +7078,94 @@ static int ui_do_but_CURVEPROFILE(
/* Selecting, adding, and starting point movements. */
if (data->state == BUTTON_STATE_HIGHLIGHT) {
if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
- CurveProfilePoint *pts; /* Path or table. */
const float m_xy[2] = {mx, my};
- float dist_min_sq;
- int i_selected = -1;
if (event->ctrl) {
float f_xy[2];
BLI_rctf_transform_pt_v(&profile->view_rect, &but->rect, f_xy, m_xy);
BKE_curveprofile_insert(profile, f_xy[0], f_xy[1]);
- BKE_curveprofile_update(profile, false);
+ BKE_curveprofile_update(profile, PROF_UPDATE_CLIP);
}
/* Check for selecting of a point by finding closest point in radius. */
- dist_min_sq = square_f(U.dpi_fac * 14.0f); /* 14 pixels radius for selecting points. */
- pts = profile->path;
- for (i = 0; i < profile->path_len; i++) {
+ CurveProfilePoint *pts = profile->path;
+ float dist_min_sq = square_f(U.dpi_fac * 14.0f); /* 14 pixels radius for selecting points. */
+ int i_selected = -1;
+ short selection_type = 0; /* For handle selection. */
+ for (int i = 0; i < profile->path_len; i++) {
float f_xy[2];
BLI_rctf_transform_pt_v(&but->rect, &profile->view_rect, f_xy, &pts[i].x);
- const float dist_sq = len_squared_v2v2(m_xy, f_xy);
+ float dist_sq = len_squared_v2v2(m_xy, f_xy);
if (dist_sq < dist_min_sq) {
i_selected = i;
+ selection_type = PROF_SELECT;
dist_min_sq = dist_sq;
}
+
+ /* Also select handles if the point is selected and it has the right handle type. */
+ if (point_draw_handles(&pts[i])) {
+ if (ELEM(profile->path[i].h1, HD_FREE, HD_ALIGN)) {
+ BLI_rctf_transform_pt_v(&but->rect, &profile->view_rect, f_xy, pts[i].h1_loc);
+ dist_sq = len_squared_v2v2(m_xy, f_xy);
+ if (dist_sq < dist_min_sq) {
+ i_selected = i;
+ selection_type = PROF_H1_SELECT;
+ dist_min_sq = dist_sq;
+ }
+ }
+ if (ELEM(profile->path[i].h2, HD_FREE, HD_ALIGN)) {
+ BLI_rctf_transform_pt_v(&but->rect, &profile->view_rect, f_xy, pts[i].h2_loc);
+ dist_sq = len_squared_v2v2(m_xy, f_xy);
+ if (dist_sq < dist_min_sq) {
+ i_selected = i;
+ selection_type = PROF_H2_SELECT;
+ dist_min_sq = dist_sq;
+ }
+ }
+ }
}
- /* Add a point if the click was close to the path but not a control point. */
- if (i_selected == -1) { /* No control point selected. */
+ /* Add a point if the click was close to the path but not a control point or handle. */
+ if (i_selected == -1) {
float f_xy[2], f_xy_prev[2];
- pts = profile->table;
- BLI_rctf_transform_pt_v(&but->rect, &profile->view_rect, f_xy, &pts[0].x);
+ CurveProfilePoint *table = profile->table;
+ BLI_rctf_transform_pt_v(&but->rect, &profile->view_rect, f_xy, &table[0].x);
dist_min_sq = square_f(U.dpi_fac * 8.0f); /* 8 pixel radius from each table point. */
/* Loop through the path's high resolution table and find what's near the click. */
- for (i = 1; i <= PROF_N_TABLE(profile->path_len); i++) {
+ for (int i = 1; i <= PROF_N_TABLE(profile->path_len); i++) {
copy_v2_v2(f_xy_prev, f_xy);
- BLI_rctf_transform_pt_v(&but->rect, &profile->view_rect, f_xy, &pts[i].x);
+ BLI_rctf_transform_pt_v(&but->rect, &profile->view_rect, f_xy, &table[i].x);
if (dist_squared_to_line_segment_v2(m_xy, f_xy_prev, f_xy) < dist_min_sq) {
BLI_rctf_transform_pt_v(&profile->view_rect, &but->rect, f_xy, m_xy);
CurveProfilePoint *new_pt = BKE_curveprofile_insert(profile, f_xy[0], f_xy[1]);
- BKE_curveprofile_update(profile, false);
-
- /* reset pts back to the control points. */
- pts = profile->path;
+ BKE_curveprofile_update(profile, PROF_UPDATE_CLIP);
/* Get the index of the newly added point. */
- for (i = 0; i < profile->path_len; i++) {
- if (&pts[i] == new_pt) {
- i_selected = i;
- }
- }
+ i_selected = (int)(new_pt - profile->path);
+ BLI_assert(i_selected >= 0 && i_selected <= profile->path_len);
+ selection_type = PROF_SELECT;
break;
}
}
}
- /* Change the flag for the point(s) if one was selected. */
+ /* Change the flag for the point(s) if one was selected or added. */
if (i_selected != -1) {
/* Deselect all if this one is deselected, except if we hold shift. */
- if (!event->shift) {
- for (i = 0; i < profile->path_len; i++) {
- pts[i].flag &= ~PROF_SELECT;
- }
- pts[i_selected].flag |= PROF_SELECT;
+ if (event->shift) {
+ pts[i_selected].flag ^= selection_type;
}
else {
- pts[i_selected].flag ^= PROF_SELECT;
+ for (int i = 0; i < profile->path_len; i++) {
+ // pts[i].flag &= ~(PROF_SELECT | PROF_H1_SELECT | PROF_H2_SELECT);
+ profile->path[i].flag &= ~(PROF_SELECT | PROF_H1_SELECT | PROF_H2_SELECT);
+ }
+ profile->path[i_selected].flag |= selection_type;
}
}
else {
@@ -7166,19 +7196,13 @@ static int ui_do_but_CURVEPROFILE(
else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
/* Finish move. */
if (data->dragsel != -1) {
- CurveProfilePoint *pts = profile->path;
if (data->dragchange == false) {
/* Deselect all, select one. */
- if (!event->shift) {
- for (i = 0; i < profile->path_len; i++) {
- pts[i].flag &= ~PROF_SELECT;
- }
- pts[data->dragsel].flag |= PROF_SELECT;
- }
}
else {
- BKE_curveprofile_update(profile, true); /* Remove doubles after move. */
+ /* Remove doubles, clip after move. */
+ BKE_curveprofile_update(profile, PROF_UPDATE_REMOVE_DOUBLES | PROF_UPDATE_CLIP);
}
}
button_activate_state(C, but, BUTTON_STATE_EXIT);
@@ -9947,7 +9971,7 @@ static int ui_handle_menu_event(bContext *C,
if (ELEM(event->val, KM_PRESS, KM_DBL_CLICK)) {
if ((is_parent_menu == false) && (U.uiflag & USER_MENUOPENAUTO) == 0) {
/* for root menus, allow clicking to close */
- if (block->flag & (UI_BLOCK_OUT_1)) {
+ if (block->flag & UI_BLOCK_OUT_1) {
menu->menuretval = UI_RETURN_OK;
}
else {
@@ -9955,7 +9979,7 @@ static int ui_handle_menu_event(bContext *C,
}
}
else if (saferct && !BLI_rctf_isect_pt(&saferct->parent, event->x, event->y)) {
- if (block->flag & (UI_BLOCK_OUT_1)) {
+ if (block->flag & UI_BLOCK_OUT_1) {
menu->menuretval = UI_RETURN_OK;
}
else {
@@ -10049,7 +10073,7 @@ static int ui_handle_menu_event(bContext *C,
/* strict check, and include the parent rect */
if (!menu->dotowards && !saferct) {
- if (block->flag & (UI_BLOCK_OUT_1)) {
+ if (block->flag & UI_BLOCK_OUT_1) {
menu->menuretval = UI_RETURN_OK;
}
else {
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index deea3028354..7411639a99f 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -2192,6 +2192,26 @@ int ui_id_icon_get(const bContext *C, ID *id, const bool big)
return iconid;
}
+int UI_library_icon_get(const ID *id)
+{
+ if (ID_IS_LINKED(id)) {
+ if (id->tag & LIB_TAG_MISSING) {
+ return ICON_LIBRARY_DATA_BROKEN;
+ }
+ else if (id->tag & LIB_TAG_INDIRECT) {
+ return ICON_LIBRARY_DATA_INDIRECT;
+ }
+ else {
+ return ICON_LIBRARY_DATA_DIRECT;
+ }
+ }
+ else if (ID_IS_OVERRIDE_LIBRARY(id)) {
+ return ICON_LIBRARY_DATA_OVERRIDE;
+ }
+
+ return ICON_NONE;
+}
+
int UI_rnaptr_icon_get(bContext *C, PointerRNA *ptr, int rnaicon, const bool big)
{
ID *id = NULL;
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 6cd990ec2b0..fac78808a9a 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -848,6 +848,8 @@ typedef struct uiWidgetBaseParameters {
* The absolute value itself is the discard factor.
* Initialize value to 1.0.f if you don't want discard */
float alpha_discard;
+ float tria_type;
+ float _pad[3];
} uiWidgetBaseParameters;
enum {
@@ -861,8 +863,7 @@ enum {
ROUNDBOX_TRIA_MAX, /* don't use */
};
-struct GPUBatch *ui_batch_roundbox_get(bool filled, bool antialiased);
-struct GPUBatch *ui_batch_roundbox_widget_get(int tria);
+struct GPUBatch *ui_batch_roundbox_widget_get(void);
struct GPUBatch *ui_batch_roundbox_shadow_get(void);
void ui_draw_anti_tria_rect(const rctf *rect, char dir, const float color[4]);
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 6aefef197df..188ff62d923 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -5576,6 +5576,7 @@ static void ui_paneltype_draw_impl(bContext *C, PanelType *pt, uiLayout *layout,
panel->layout = layout;
pt->draw(C, panel);
panel->layout = NULL;
+ BLI_assert(panel->runtime.custom_data_ptr == NULL);
MEM_freeN(panel);
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index 41c89d2d832..924fc6738e1 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -513,7 +513,7 @@ static bool override_type_set_button_poll(bContext *C)
UI_context_active_but_prop_get(C, &ptr, &prop, &index);
- const int override_status = RNA_property_override_library_status(&ptr, prop, index);
+ const uint override_status = RNA_property_override_library_status(&ptr, prop, index);
return (ptr.data && prop && (override_status & RNA_OVERRIDE_STATUS_OVERRIDABLE));
}
@@ -613,7 +613,7 @@ static bool override_remove_button_poll(bContext *C)
UI_context_active_but_prop_get(C, &ptr, &prop, &index);
- const int override_status = RNA_property_override_library_status(&ptr, prop, index);
+ const uint override_status = RNA_property_override_library_status(&ptr, prop, index);
return (ptr.data && ptr.owner_id && prop && (override_status & RNA_OVERRIDE_STATUS_OVERRIDDEN));
}
@@ -630,11 +630,11 @@ static int override_remove_button_exec(bContext *C, wmOperator *op)
UI_context_active_but_prop_get(C, &ptr, &prop, &index);
ID *id = ptr.owner_id;
- IDOverrideLibraryProperty *oprop = RNA_property_override_property_find(&ptr, prop);
+ IDOverrideLibraryProperty *oprop = RNA_property_override_property_find(&ptr, prop, &id);
BLI_assert(oprop != NULL);
BLI_assert(id != NULL && id->override_library != NULL);
- const bool is_template = (id->override_library->reference == NULL);
+ const bool is_template = ID_IS_OVERRIDE_LIBRARY_TEMPLATE(id);
/* We need source (i.e. linked data) to restore values of deleted overrides...
* If this is an override template, we obviously do not need to restore anything. */
@@ -1309,7 +1309,7 @@ static int editsource_text_edit(bContext *C,
printf("%s:%d\n", filepath, line);
for (text = bmain->texts.first; text; text = text->id.next) {
- if (text->name && BLI_path_cmp(text->name, filepath) == 0) {
+ if (text->filepath && BLI_path_cmp(text->filepath, filepath) == 0) {
break;
}
}
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index 55657d7297a..2eeab4efbc7 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -245,20 +245,25 @@ static bool panels_need_realign(ScrArea *area, ARegion *region, Panel **r_panel_
/********* Functions for instanced panels. ***********/
-static Panel *UI_panel_add_instanced_ex(
- ScrArea *area, ARegion *region, ListBase *panels, PanelType *panel_type, int list_index)
+static Panel *UI_panel_add_instanced_ex(ScrArea *area,
+ ARegion *region,
+ ListBase *panels,
+ PanelType *panel_type,
+ int list_index,
+ PointerRNA *custom_data)
{
Panel *panel = MEM_callocN(sizeof(Panel), "instanced panel");
panel->type = panel_type;
BLI_strncpy(panel->panelname, panel_type->idname, sizeof(panel->panelname));
panel->runtime.list_index = list_index;
+ panel->runtime.custom_data_ptr = custom_data;
/* Add the panel's children too. Although they aren't instanced panels, we can still use this
* function to create them, as UI_panel_begin does other things we don't need to do. */
LISTBASE_FOREACH (LinkData *, child, &panel_type->children) {
PanelType *child_type = child->data;
- UI_panel_add_instanced_ex(area, region, &panel->children, child_type, list_index);
+ UI_panel_add_instanced_ex(area, region, &panel->children, child_type, list_index, custom_data);
}
/* Make sure the panel is added to the end of the display-order as well. This is needed for
@@ -283,8 +288,12 @@ static Panel *UI_panel_add_instanced_ex(
* Called in situations where panels need to be added dynamically rather than having only one panel
* corresponding to each PanelType.
*/
-Panel *UI_panel_add_instanced(
- ScrArea *area, ARegion *region, ListBase *panels, char *panel_idname, int list_index)
+Panel *UI_panel_add_instanced(ScrArea *area,
+ ARegion *region,
+ ListBase *panels,
+ char *panel_idname,
+ int list_index,
+ PointerRNA *custom_data)
{
ARegionType *region_type = region->type;
@@ -296,7 +305,7 @@ Panel *UI_panel_add_instanced(
return NULL;
}
- return UI_panel_add_instanced_ex(area, region, panels, panel_type, list_index);
+ return UI_panel_add_instanced_ex(area, region, panels, panel_type, list_index, custom_data);
}
/**
@@ -332,7 +341,8 @@ static void panel_free_block(ARegion *region, Panel *panel)
}
/**
- * Free a panel and it's children.
+ * Free a panel and it's children. Custom data is shared by the panel and its children
+ * and is freed by #UI_panels_free_instanced.
*
* \note The only panels that should need to be deleted at runtime are panels with the
* #PNL_INSTANCED flag set.
@@ -369,6 +379,13 @@ void UI_panels_free_instanced(bContext *C, ARegion *region)
if (C != NULL && panel->activedata != NULL) {
panel_activate_state(C, panel, PANEL_STATE_EXIT);
}
+
+ /* Free panel's custom data. */
+ if (panel->runtime.custom_data_ptr != NULL) {
+ MEM_freeN(panel->runtime.custom_data_ptr);
+ }
+
+ /* Free the panel and its sub-panels. */
panel_delete(region, &region->panels, panel);
}
}
@@ -387,9 +404,19 @@ bool UI_panel_list_matches_data(ARegion *region,
ListBase *data,
uiListPanelIDFromDataFunc panel_idname_func)
{
- int data_len = BLI_listbase_count(data);
+ /* Check for NULL data. */
+ int data_len = 0;
+ Link *data_link = NULL;
+ if (data == NULL) {
+ data_len = 0;
+ data_link = NULL;
+ }
+ else {
+ data_len = BLI_listbase_count(data);
+ data_link = data->first;
+ }
+
int i = 0;
- Link *data_link = data->first;
LISTBASE_FOREACH (Panel *, panel, &region->panels) {
if (panel->type != NULL && panel->type->flag & PNL_INSTANCED) {
/* The panels were reordered by drag and drop. */
@@ -493,7 +520,7 @@ static void reorder_instanced_panel_list(bContext *C, ARegion *region, Panel *dr
/**
* Recursive implementation for #UI_panel_set_expand_from_list_data.
*
- * \return Whether the closed flag for the panel or any subpanels changed.
+ * \return Whether the closed flag for the panel or any sub-panels changed.
*/
static bool panel_set_expand_from_list_data_recursive(Panel *panel, short flag, short *flag_index)
{
@@ -513,7 +540,7 @@ static bool panel_set_expand_from_list_data_recursive(Panel *panel, short flag,
}
/**
- * Set the expansion of the panel and its subpanels from the flag stored by the list data
+ * Set the expansion of the panel and its sub-panels from the flag stored by the list data
* corresponding to this panel. The flag has expansion stored in each bit in depth first
* order.
*/
@@ -583,6 +610,26 @@ static void set_panels_list_data_expand_flag(const bContext *C, ARegion *region)
/****************************** panels ******************************/
+/**
+ * Set flag state for a panel and its sub-panels.
+ *
+ * \return True if this function changed any of the flags, false if it didn't.
+ */
+static bool panel_set_flag_recursive(Panel *panel, int flag, bool value)
+{
+ short flag_original = panel->flag;
+
+ SET_FLAG_FROM_TEST(panel->flag, value, flag);
+
+ bool changed = (flag_original != panel->flag);
+
+ LISTBASE_FOREACH (Panel *, child, &panel->children) {
+ changed |= panel_set_flag_recursive(child, flag, value);
+ }
+
+ return changed;
+}
+
static void panels_collapse_all(const bContext *C,
ScrArea *area,
ARegion *region,
@@ -980,7 +1027,7 @@ void ui_draw_aligned_panel(uiStyle *style,
* can't be dragged. This may be changed in future. */
show_background);
const int panel_col = is_subpanel ? TH_PANEL_SUB_BACK : TH_PANEL_BACK;
- const bool draw_box_style = (panel->type && panel->type->flag & (PNL_DRAW_BOX));
+ const bool draw_box_style = (panel->type && panel->type->flag & PNL_DRAW_BOX);
/* Use the theme for box widgets for box-style panels. */
uiWidgetColors *box_wcol = NULL;
@@ -1160,7 +1207,7 @@ void ui_draw_aligned_panel(uiStyle *style,
/* Draw panel backdrop if it wasn't already been drawn by the single opaque round box earlier.
* Note: Sub-panels blend with panels, so they can't be opaque. */
if (show_background && !(draw_box_style && !is_subpanel)) {
- /* Draw the bottom subpanels . */
+ /* Draw the bottom sub-panels. */
if (draw_box_style) {
if (panel->next) {
immUniformThemeColor(panel_col);
@@ -1461,11 +1508,6 @@ static bool uiAlignPanelStep(ScrArea *area, ARegion *region, const float fac, co
ps->panel->ofsx = 0;
ps->panel->ofsy = -get_panel_size_y(ps->panel);
ps->panel->ofsx += ps->panel->runtime.region_ofsx;
- /* Extra margin if the panel is a box style panel. */
- if (ps->panel->type && ps->panel->type->flag & PNL_DRAW_BOX) {
- ps->panel->ofsx += UI_PANEL_BOX_STYLE_MARGIN;
- ps->panel->ofsy -= UI_PANEL_BOX_STYLE_MARGIN;
- }
for (a = 0; a < tot - 1; a++, ps++) {
psnext = ps + 1;
@@ -1475,16 +1517,12 @@ static bool uiAlignPanelStep(ScrArea *area, ARegion *region, const float fac, co
bool use_box_next = psnext->panel->type && psnext->panel->type->flag & PNL_DRAW_BOX;
psnext->panel->ofsx = ps->panel->ofsx;
psnext->panel->ofsy = get_panel_real_ofsy(ps->panel) - get_panel_size_y(psnext->panel);
+
/* Extra margin for box style panels. */
+ ps->panel->ofsx += (use_box) ? UI_PANEL_BOX_STYLE_MARGIN : 0.0f;
if (use_box || use_box_next) {
psnext->panel->ofsy -= UI_PANEL_BOX_STYLE_MARGIN;
}
- if (use_box && !use_box_next) {
- psnext->panel->ofsx -= UI_PANEL_BOX_STYLE_MARGIN;
- }
- else if (!use_box && use_box_next) {
- psnext->panel->ofsx += UI_PANEL_BOX_STYLE_MARGIN;
- }
}
else {
psnext->panel->ofsx = get_panel_real_ofsx(ps->panel);
@@ -1492,6 +1530,10 @@ static bool uiAlignPanelStep(ScrArea *area, ARegion *region, const float fac, co
get_panel_size_y(psnext->panel);
}
}
+ /* Extra margin for the last panel if it's a box-style panel. */
+ if (panelsort[tot - 1].panel->type && panelsort[tot - 1].panel->type->flag & PNL_DRAW_BOX) {
+ panelsort[tot - 1].panel->ofsx += UI_PANEL_BOX_STYLE_MARGIN;
+ }
/* we interpolate */
done = false;
@@ -2017,14 +2059,28 @@ static void ui_handle_panel_header(
if (button == 2) { /* close */
ED_region_tag_redraw(region);
}
- else { /* collapse */
+ else {
+ /* Collapse and expand panels. */
+
if (ctrl) {
- /* Only collapse all for parent panels. */
+ /* For parent panels, collapse all other panels or toggle children. */
if (block->panel->type != NULL && block->panel->type->parent == NULL) {
- panels_collapse_all(C, area, region, block->panel);
+ if (block->panel->flag & PNL_CLOSED || BLI_listbase_is_empty(&block->panel->children)) {
+ panels_collapse_all(C, area, region, block->panel);
- /* reset the view - we don't want to display a view without content */
- UI_view2d_offset(&region->v2d, 0.0f, 1.0f);
+ /* Reset the view - we don't want to display a view without content. */
+ UI_view2d_offset(&region->v2d, 0.0f, 1.0f);
+ }
+ else {
+ const int closed_flag = (align == BUT_HORIZONTAL) ? PNL_CLOSEDX : PNL_CLOSEDY;
+ /* If a panel has sub-panels and it's open, toggle the expansion
+ * of the sub-panels (based on the expansion of the first subpanel). */
+ Panel *first_child = block->panel->children.first;
+ BLI_assert(first_child != NULL);
+ panel_set_flag_recursive(
+ block->panel, closed_flag, (first_child->flag & PNL_CLOSED) == 0);
+ block->panel->flag |= closed_flag;
+ }
}
}
@@ -2847,6 +2903,56 @@ int ui_handler_panel_region(bContext *C,
return retval;
}
+static void ui_panel_custom_data_set_recursive(Panel *panel, PointerRNA *custom_data)
+{
+ panel->runtime.custom_data_ptr = custom_data;
+
+ LISTBASE_FOREACH (Panel *, child_panel, &panel->children) {
+ ui_panel_custom_data_set_recursive(child_panel, custom_data);
+ }
+}
+
+void UI_panel_custom_data_set(Panel *panel, PointerRNA *custom_data)
+{
+ BLI_assert(panel->type != NULL);
+
+ /* Free the old custom data, which should be shared among all of the panel's sub-panels. */
+ if (panel->runtime.custom_data_ptr != NULL) {
+ MEM_freeN(panel->runtime.custom_data_ptr);
+ }
+
+ ui_panel_custom_data_set_recursive(panel, custom_data);
+}
+
+PointerRNA *UI_region_panel_custom_data_under_cursor(const bContext *C, const wmEvent *event)
+{
+ ARegion *region = CTX_wm_region(C);
+
+ Panel *panel = NULL;
+ LISTBASE_FOREACH (uiBlock *, block, &region->uiblocks) {
+ panel = block->panel;
+ if (panel == NULL) {
+ continue;
+ }
+
+ int mx = event->x;
+ int my = event->y;
+ ui_window_to_block(region, block, &mx, &my);
+ int mouse_state = ui_panel_mouse_state_get(block, panel, mx, my);
+ if (ELEM(mouse_state, PANEL_MOUSE_INSIDE_CONTENT, PANEL_MOUSE_INSIDE_HEADER)) {
+ break;
+ }
+ }
+
+ if (panel == NULL) {
+ return NULL;
+ }
+
+ PointerRNA *customdata = panel->runtime.custom_data_ptr;
+
+ return customdata;
+}
+
/**************** window level modal panel interaction **************/
/* note, this is modal handler and should not swallow events for animation */
@@ -2899,24 +3005,6 @@ static void ui_handler_remove_panel(bContext *C, void *userdata)
panel_activate_state(C, panel, PANEL_STATE_EXIT);
}
-/**
- * Set selection state for a panel and its subpanels. The subpanels need to know they are selected
- * too so they can be drawn above their parent when it is dragged.
- */
-static void set_panel_selection(Panel *panel, bool value)
-{
- if (value) {
- panel->flag |= PNL_SELECT;
- }
- else {
- panel->flag &= ~PNL_SELECT;
- }
-
- LISTBASE_FOREACH (Panel *, child, &panel->children) {
- set_panel_selection(child, value);
- }
-}
-
static void panel_activate_state(const bContext *C, Panel *panel, uiHandlePanelState state)
{
uiHandlePanelData *data = panel->activedata;
@@ -2929,6 +3017,8 @@ static void panel_activate_state(const bContext *C, Panel *panel, uiHandlePanelS
bool was_drag_drop = (data && data->state == PANEL_STATE_DRAG);
+ /* Set selection state for the panel and its sub-panels, which need to know they are selected
+ * too so they can be drawn above their parent when it's dragged. */
if (state == PANEL_STATE_EXIT || state == PANEL_STATE_ANIMATION) {
if (data && data->state != PANEL_STATE_ANIMATION) {
/* XXX:
@@ -2941,10 +3031,10 @@ static void panel_activate_state(const bContext *C, Panel *panel, uiHandlePanelS
check_panel_overlap(region, NULL); /* clears */
}
- set_panel_selection(panel, false);
+ panel_set_flag_recursive(panel, PNL_SELECT, false);
}
else {
- set_panel_selection(panel, true);
+ panel_set_flag_recursive(panel, PNL_SELECT, true);
}
if (data && data->animtimer) {
diff --git a/source/blender/editors/interface/interface_region_menu_popup.c b/source/blender/editors/interface/interface_region_menu_popup.c
index 3e34b7f3f8a..65f5798bdce 100644
--- a/source/blender/editors/interface/interface_region_menu_popup.c
+++ b/source/blender/editors/interface/interface_region_menu_popup.c
@@ -184,7 +184,12 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
pup->block->handle = NULL;
}
- if (pup->but) {
+ /* Find block minimum width. */
+ if (uiLayoutGetUnitsX(pup->layout) != 0.0f) {
+ /* Use the minimum width from the layout if it's set. */
+ minwidth = uiLayoutGetUnitsX(pup->layout) * UI_UNIT_X;
+ }
+ else if (pup->but) {
/* minimum width to enforece */
if (pup->but->drawstr[0]) {
minwidth = BLI_rctf_size_x(&pup->but->rect);
@@ -193,7 +198,13 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
/* For buttons with no text, use the minimum (typically icon only). */
minwidth = UI_MENU_WIDTH_MIN;
}
+ }
+ else {
+ minwidth = UI_MENU_WIDTH_MIN;
+ }
+ /* Find block direction. */
+ if (pup->but) {
if (pup->block->direction != 0) {
/* allow overriding the direction from menu_func */
direction = pup->block->direction;
@@ -203,7 +214,6 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
}
}
else {
- minwidth = UI_MENU_WIDTH_MIN;
direction = UI_DIR_DOWN;
}
diff --git a/source/blender/editors/interface/interface_region_search.c b/source/blender/editors/interface/interface_region_search.c
index 68be08ef4f8..c88dd1954c9 100644
--- a/source/blender/editors/interface/interface_region_search.c
+++ b/source/blender/editors/interface/interface_region_search.c
@@ -77,6 +77,9 @@ struct uiSearchItems {
int *icons;
int *states;
+ /** Is there any item with an icon? */
+ bool has_icon;
+
AutoComplete *autocpl;
void *active;
};
@@ -122,6 +125,10 @@ bool UI_search_item_add(uiSearchItems *items, const char *name, void *poin, int
return true;
}
+ if (iconid) {
+ items->has_icon = true;
+ }
+
/* hijack for finding active item */
if (items->active) {
if (poin == items->active) {
@@ -562,6 +569,10 @@ static void ui_searchbox_region_draw_cb(const bContext *C, ARegion *region)
/* widget itself */
if ((search_sep_len == 0) ||
!(name_sep_test = strstr(data->items.names[a], data->sep_string))) {
+ if (!icon && data->items.has_icon) {
+ /* If there is any icon item, make sure all items line up. */
+ icon = ICON_BLANK1;
+ }
/* Simple menu item. */
ui_draw_menu_item(&data->fstyle, &rect, name, icon, state, use_sep_char, NULL);
diff --git a/source/blender/editors/interface/interface_region_tooltip.c b/source/blender/editors/interface/interface_region_tooltip.c
index b64f080d9cc..9fed98ffda2 100644
--- a/source/blender/editors/interface/interface_region_tooltip.c
+++ b/source/blender/editors/interface/interface_region_tooltip.c
@@ -923,7 +923,7 @@ static uiTooltipData *ui_tooltip_data_from_button(bContext *C, uiBut *but)
.style = UI_TIP_STYLE_NORMAL,
.color_id = UI_TIP_LC_NORMAL,
});
- field->text = BLI_sprintfN(TIP_("Library: %s"), id->lib->name);
+ field->text = BLI_sprintfN(TIP_("Library: %s"), id->lib->filepath);
}
}
}
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 1ce1e2950d5..baea948e122 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -361,11 +361,16 @@ static bool id_search_add(const bContext *C,
* followed by ID_NAME-2 characters from id->name
*/
char name_ui[MAX_ID_FULL_NAME_UI];
- BKE_id_full_name_ui_prefix_get(name_ui, id, UI_SEP_CHAR);
-
int iconid = ui_id_icon_get(C, id, template_ui->preview);
bool has_sep_char = (id->lib != NULL);
+ /* When using previews, the library hint (linked, overridden, missing) is added with a
+ * character prefix, otherwise we can use a icon. */
+ BKE_id_full_name_ui_prefix_get(name_ui, id, template_ui->preview, UI_SEP_CHAR);
+ if (!template_ui->preview) {
+ iconid = UI_library_icon_get(id);
+ }
+
if (!UI_search_item_add(
items, name_ui, id, iconid, has_sep_char ? UI_BUT_HAS_SEP_CHAR : 0)) {
return false;
@@ -511,6 +516,7 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
PointerRNA idptr = RNA_property_pointer_get(&template_ui->ptr, template_ui->prop);
ID *id = idptr.data;
int event = POINTER_AS_INT(arg_event);
+ const char *undo_push_label = NULL;
switch (event) {
case UI_ID_BROWSE:
@@ -531,6 +537,7 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
id_us_clear_real(id);
id_fake_user_clear(id);
id->us = 0;
+ undo_push_label = "Delete Data-Block";
}
break;
@@ -542,6 +549,7 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
else {
id_us_min(id);
}
+ undo_push_label = "Fake User";
}
else {
return;
@@ -572,15 +580,17 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
}
RNA_property_pointer_set(&template_ui->ptr, template_ui->prop, idptr, NULL);
RNA_property_update(C, &template_ui->ptr, template_ui->prop);
+ undo_push_label = "Make Local";
}
break;
case UI_ID_OVERRIDE:
- if (id && id->override_library) {
+ if (id && ID_IS_OVERRIDE_LIBRARY(id)) {
BKE_lib_override_library_free(&id->override_library, true);
/* reassign to get get proper updates/notifiers */
idptr = RNA_property_pointer_get(&template_ui->ptr, template_ui->prop);
RNA_property_pointer_set(&template_ui->ptr, template_ui->prop, idptr, NULL);
RNA_property_update(C, &template_ui->ptr, template_ui->prop);
+ undo_push_label = "Override Data-Block";
}
break;
case UI_ID_ALONE:
@@ -601,6 +611,7 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
id_single_user(C, id, &template_ui->ptr, template_ui->prop);
DEG_relations_tag_update(bmain);
}
+ undo_push_label = "Make Single User";
}
break;
#if 0
@@ -608,6 +619,10 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
break;
#endif
}
+
+ if (undo_push_label != NULL) {
+ ED_undo_push(C, undo_push_label);
+ }
}
static const char *template_id_browse_tip(const StructRNA *type)
@@ -1823,6 +1838,20 @@ void uiTemplatePathBuilder(uiLayout *layout,
* Template for building the panel layout for the active object's modifiers.
* \{ */
+/**
+ * Get the active object or the property region's pinned object.
+ */
+static Object *get_context_object(const bContext *C)
+{
+ SpaceProperties *sbuts = CTX_wm_space_properties(C);
+ if (sbuts != NULL && (sbuts->pinid != NULL) && GS(sbuts->pinid->name) == ID_OB) {
+ return (Object *)sbuts->pinid;
+ }
+ else {
+ return CTX_data_active_object(C);
+ }
+}
+
static void modifier_panel_id(void *md_link, char *r_name)
{
ModifierData *md = (ModifierData *)md_link;
@@ -1834,14 +1863,7 @@ void uiTemplateModifiers(uiLayout *UNUSED(layout), bContext *C)
ScrArea *sa = CTX_wm_area(C);
ARegion *region = CTX_wm_region(C);
- Object *ob;
- SpaceProperties *sbuts = CTX_wm_space_properties(C);
- if (sbuts != NULL && (sbuts->pinid != NULL) && GS(sbuts->pinid->name) == ID_OB) {
- ob = (Object *)sbuts->pinid;
- }
- else {
- ob = CTX_data_active_object(C);
- }
+ Object *ob = get_context_object(C);
ListBase *modifiers = &ob->modifiers;
bool panels_match = UI_panel_list_matches_data(region, modifiers, modifier_panel_id);
@@ -1851,14 +1873,22 @@ void uiTemplateModifiers(uiLayout *UNUSED(layout), bContext *C)
ModifierData *md = modifiers->first;
for (int i = 0; md; i++, md = md->next) {
const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
- if (mti->panelRegister) {
- char panel_idname[MAX_NAME];
- modifier_panel_id(md, panel_idname);
+ if (mti->panelRegister == NULL) {
+ continue;
+ }
- Panel *new_panel = UI_panel_add_instanced(sa, region, &region->panels, panel_idname, i);
- if (new_panel != NULL) {
- UI_panel_set_expand_from_list_data(C, new_panel);
- }
+ char panel_idname[MAX_NAME];
+ modifier_panel_id(md, panel_idname);
+
+ /* Create custom data RNA pointer. */
+ PointerRNA *md_ptr = MEM_mallocN(sizeof(PointerRNA), "panel customdata");
+ RNA_pointer_create(&ob->id, &RNA_Modifier, md, md_ptr);
+
+ Panel *new_panel = UI_panel_add_instanced(
+ sa, region, &region->panels, panel_idname, i, md_ptr);
+
+ if (new_panel != NULL) {
+ UI_panel_set_expand_from_list_data(C, new_panel);
}
}
}
@@ -1868,274 +1898,321 @@ void uiTemplateModifiers(uiLayout *UNUSED(layout), bContext *C)
if ((panel->type != NULL) && (panel->type->flag & PNL_INSTANCED))
UI_panel_set_expand_from_list_data(C, panel);
}
+
+ /* Assuming there's only one group of instanced panels, update the custom data pointers. */
+ Panel *panel = region->panels.first;
+ LISTBASE_FOREACH (ModifierData *, md, modifiers) {
+ const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
+ if (mti->panelRegister == NULL) {
+ continue;
+ }
+
+ /* Move to the next instanced panel corresponding to the next modifier. */
+ while ((panel->type == NULL) || !(panel->type->flag & PNL_INSTANCED)) {
+ panel = panel->next;
+ BLI_assert(panel != NULL); /* There shouldn't be fewer panels than modifiers with UIs. */
+ }
+
+ PointerRNA *md_ptr = MEM_mallocN(sizeof(PointerRNA), "panel customdata");
+ RNA_pointer_create(&ob->id, &RNA_Modifier, md, md_ptr);
+ UI_panel_custom_data_set(panel, md_ptr);
+
+ panel = panel->next;
+ }
}
}
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Grease Pencil Modifier Template
+/** \name Constraints Template
+ *
+ * Template for building the panel layout for the active object or bone's constraints.
* \{ */
-#define ERROR_LIBDATA_MESSAGE TIP_("Can't edit external library data")
+/** For building the panel UI for constraints. */
+#define CONSTRAINT_TYPE_PANEL_PREFIX "OBJECT_PT_"
+#define CONSTRAINT_BONE_TYPE_PANEL_PREFIX "BONE_PT_"
-static uiLayout *gpencil_draw_modifier(uiLayout *layout, Object *ob, GpencilModifierData *md)
+/**
+ * Check if the panel's ID starts with 'BONE', meaning it is a bone constraint.
+ */
+static bool constraint_panel_is_bone(Panel *panel)
{
- const GpencilModifierTypeInfo *mti = BKE_gpencil_modifier_get_info(md->type);
- PointerRNA ptr;
- uiBlock *block;
- uiLayout *box, *column, *row, *sub;
- uiLayout *result = NULL;
-
- /* create RNA pointer */
- RNA_pointer_create(&ob->id, &RNA_GpencilModifier, md, &ptr);
-
- column = uiLayoutColumn(layout, true);
- uiLayoutSetContextPointer(column, "modifier", &ptr);
-
- /* rounded header ------------------------------------------------------------------- */
- box = uiLayoutBox(column);
-
- row = uiLayoutRow(box, false);
- block = uiLayoutGetBlock(row);
-
- UI_block_emboss_set(block, UI_EMBOSS_NONE);
- /* Open/Close ................................. */
- uiItemR(row, &ptr, "show_expanded", 0, "", ICON_NONE);
-
- /* modifier-type icon */
- uiItemL(row, "", RNA_struct_ui_icon(ptr.type));
- UI_block_emboss_set(block, UI_EMBOSS);
+ return (panel->panelname[0] == 'B') && (panel->panelname[1] == 'O') &&
+ (panel->panelname[2] == 'N') && (panel->panelname[3] == 'E');
+}
- /* modifier name */
- if (mti->isDisabled && mti->isDisabled(md, 0)) {
- uiLayoutSetRedAlert(row, true);
+/**
+ * Get the constraints for the active pose bone or the active / pinned object.
+ */
+static ListBase *get_constraints(const bContext *C, bool use_bone_constraints)
+{
+ ListBase *constraints = {NULL};
+ if (use_bone_constraints) {
+ bPoseChannel *pose_bone = CTX_data_pointer_get(C, "pose_bone").data;
+ if (pose_bone != NULL) {
+ constraints = &pose_bone->constraints;
+ }
}
- uiItemR(row, &ptr, "name", 0, "", ICON_NONE);
- uiLayoutSetRedAlert(row, false);
-
- /* mode enabling buttons */
- UI_block_align_begin(block);
- uiItemR(row, &ptr, "show_render", 0, "", ICON_NONE);
- uiItemR(row, &ptr, "show_viewport", 0, "", ICON_NONE);
-
- if (mti->flags & eGpencilModifierTypeFlag_SupportsEditmode) {
- sub = uiLayoutRow(row, true);
- uiLayoutSetActive(sub, false);
- uiItemR(sub, &ptr, "show_in_editmode", 0, "", ICON_NONE);
+ else {
+ Object *ob = get_context_object(C);
+ if (ob != NULL) {
+ constraints = &ob->constraints;
+ }
}
+ return constraints;
+}
- UI_block_align_end(block);
-
- /* Up/Down + Delete ........................... */
- UI_block_align_begin(block);
- uiItemO(row, "", ICON_TRIA_UP, "OBJECT_OT_gpencil_modifier_move_up");
- uiItemO(row, "", ICON_TRIA_DOWN, "OBJECT_OT_gpencil_modifier_move_down");
- UI_block_align_end(block);
-
- UI_block_emboss_set(block, UI_EMBOSS_NONE);
- uiItemO(row, "", ICON_X, "OBJECT_OT_gpencil_modifier_remove");
- UI_block_emboss_set(block, UI_EMBOSS);
+/**
+ * Move a constraint to the index it's moved to after a drag and drop.
+ */
+static void constraint_reorder(bContext *C, Panel *panel, int new_index)
+{
+ bool constraint_from_bone = constraint_panel_is_bone(panel);
+ ListBase *lb = get_constraints(C, constraint_from_bone);
- /* modifier settings (under the header) --------------------------------------------------- */
- if (md->mode & eGpencilModifierMode_Expanded) {
- /* apply/convert/copy */
- box = uiLayoutBox(column);
- row = uiLayoutRow(box, false);
+ bConstraint *con = BLI_findlink(lb, panel->runtime.list_index);
+ PointerRNA props_ptr;
+ wmOperatorType *ot = WM_operatortype_find("CONSTRAINT_OT_move_to_index", false);
+ WM_operator_properties_create_ptr(&props_ptr, ot);
+ RNA_string_set(&props_ptr, "constraint", con->name);
+ RNA_int_set(&props_ptr, "index", new_index);
+ /* Set owner to #EDIT_CONSTRAINT_OWNER_OBJECT or #EDIT_CONSTRAINT_OWNER_BONE. */
+ RNA_enum_set(&props_ptr, "owner", constraint_from_bone ? 1 : 0);
+ WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &props_ptr);
+ WM_operator_properties_free(&props_ptr);
+}
- /* only here obdata, the rest of modifiers is ob level */
- UI_block_lock_set(block, BKE_object_obdata_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
+/**
+ * Get the expand flag from the active constraint to use for the panel.
+ */
+static short get_constraint_expand_flag(const bContext *C, Panel *panel)
+{
+ bool constraint_from_bone = constraint_panel_is_bone(panel);
+ ListBase *lb = get_constraints(C, constraint_from_bone);
- uiLayoutSetOperatorContext(row, WM_OP_INVOKE_DEFAULT);
+ bConstraint *con = BLI_findlink(lb, panel->runtime.list_index);
+ return con->ui_expand_flag;
+}
- sub = uiLayoutRow(row, false);
- if (mti->flags & eGpencilModifierTypeFlag_NoApply) {
- uiLayoutSetEnabled(sub, false);
- }
- uiItemEnumO(sub,
- "OBJECT_OT_gpencil_modifier_apply",
- CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Apply"),
- 0,
- "apply_as",
- MODIFIER_APPLY_DATA);
+/**
+ * Save the expand flag for the panel and sub-panels to the constraint.
+ */
+static void set_constraint_expand_flag(const bContext *C, Panel *panel, short expand_flag)
+{
+ bool constraint_from_bone = constraint_panel_is_bone(panel);
+ ListBase *lb = get_constraints(C, constraint_from_bone);
- UI_block_lock_clear(block);
- UI_block_lock_set(block, ob && ID_IS_LINKED(ob), ERROR_LIBDATA_MESSAGE);
+ bConstraint *con = BLI_findlink(lb, panel->runtime.list_index);
+ con->ui_expand_flag = expand_flag;
+}
- uiItemO(row,
- CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Copy"),
- ICON_NONE,
- "OBJECT_OT_gpencil_modifier_copy");
+/**
+ * Function with void * argument for #uiListPanelIDFromDataFunc.
+ *
+ * \note: Constraint panel types are assumed to be named with the struct name field
+ * concatenated to the defined prefix.
+ */
+static void object_constraint_panel_id(void *md_link, char *r_name)
+{
+ bConstraint *con = (bConstraint *)md_link;
+ const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_from_type(con->type);
- /* result is the layout block inside the box,
- * that we return so that modifier settings can be drawn */
- result = uiLayoutColumn(box, false);
- block = uiLayoutAbsoluteBlock(box);
- }
+ strcpy(r_name, CONSTRAINT_TYPE_PANEL_PREFIX);
+ strcat(r_name, cti->structName);
+}
- /* error messages */
- if (md->error) {
- box = uiLayoutBox(column);
- row = uiLayoutRow(box, false);
- uiItemL(row, md->error, ICON_ERROR);
- }
+static void bone_constraint_panel_id(void *md_link, char *r_name)
+{
+ bConstraint *con = (bConstraint *)md_link;
+ const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_from_type(con->type);
- return result;
+ strcpy(r_name, CONSTRAINT_BONE_TYPE_PANEL_PREFIX);
+ strcat(r_name, cti->structName);
}
-uiLayout *uiTemplateGpencilModifier(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+/**
+ * Check if the constraint panels don't match the data and rebuild the panels if so.
+ */
+void uiTemplateConstraints(uiLayout *UNUSED(layout), bContext *C, bool use_bone_constraints)
{
- Object *ob;
- GpencilModifierData *md, *vmd;
- int i;
-
- /* verify we have valid data */
- if (!RNA_struct_is_a(ptr->type, &RNA_GpencilModifier)) {
- RNA_warning("Expected modifier on object");
- return NULL;
- }
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *region = CTX_wm_region(C);
- ob = (Object *)ptr->owner_id;
- md = ptr->data;
+ ListBase *constraints = get_constraints(C, use_bone_constraints);
- if (!ob || !(GS(ob->id.name) == ID_OB)) {
- RNA_warning("Expected modifier on object");
- return NULL;
- }
+ /* Switch between the bone panel ID function and the object panel ID function. */
+ uiListPanelIDFromDataFunc panel_id_func = use_bone_constraints ? bone_constraint_panel_id :
+ object_constraint_panel_id;
- UI_block_lock_set(uiLayoutGetBlock(layout), (ob && ID_IS_LINKED(ob)), ERROR_LIBDATA_MESSAGE);
+ bool panels_match = UI_panel_list_matches_data(region, constraints, panel_id_func);
- /* find modifier and draw it */
- vmd = ob->greasepencil_modifiers.first;
- for (i = 0; vmd; i++, vmd = vmd->next) {
- if (md == vmd) {
- return gpencil_draw_modifier(layout, ob, md);
+ if (!panels_match) {
+ UI_panels_free_instanced(C, region);
+ bConstraint *con = (constraints == NULL) ? NULL : constraints->first;
+ for (int i = 0; con; i++, con = con->next) {
+ char panel_idname[MAX_NAME];
+ panel_id_func(con, panel_idname);
+
+ Panel *new_panel = UI_panel_add_instanced(
+ sa, region, &region->panels, panel_idname, i, NULL);
+ if (new_panel) {
+ /* Set the list panel functionality function pointers since we don't do it with
+ * python. */
+ new_panel->type->set_list_data_expand_flag = set_constraint_expand_flag;
+ new_panel->type->get_list_data_expand_flag = get_constraint_expand_flag;
+ new_panel->type->reorder = constraint_reorder;
+
+ UI_panel_set_expand_from_list_data(C, new_panel);
+ }
+ }
+ }
+ else {
+ /* The expansion might have been changed elsewhere, so we still need to set it. */
+ LISTBASE_FOREACH (Panel *, panel, &region->panels) {
+ if ((panel->type != NULL) && (panel->type->flag & PNL_INSTANCED))
+ UI_panel_set_expand_from_list_data(C, panel);
}
}
-
- return NULL;
}
+#undef CONSTRAINT_TYPE_PANEL_PREFIX
+#undef CONSTRAINT_BONE_TYPE_PANEL_PREFIX
+
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Grease Pencil Shader FX Template
+/** \name Grease Pencil Modifiers Template
* \{ */
-static uiLayout *gpencil_draw_shaderfx(uiLayout *layout, Object *ob, ShaderFxData *md)
+/**
+ * Function with void * argument for #uiListPanelIDFromDataFunc.
+ */
+static void gpencil_modifier_panel_id(void *md_link, char *r_name)
{
- const ShaderFxTypeInfo *mti = BKE_shaderfx_get_info(md->type);
- PointerRNA ptr;
- uiBlock *block;
- uiLayout *box, *column, *row, *sub;
- uiLayout *result = NULL;
+ ModifierData *md = (ModifierData *)md_link;
+ BKE_gpencil_modifierType_panel_id(md->type, r_name);
+}
- /* create RNA pointer */
- RNA_pointer_create(&ob->id, &RNA_ShaderFx, md, &ptr);
+void uiTemplateGpencilModifiers(uiLayout *UNUSED(layout), bContext *C)
+{
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *region = CTX_wm_region(C);
+ Object *ob = get_context_object(C);
+ ListBase *modifiers = &ob->greasepencil_modifiers;
- column = uiLayoutColumn(layout, true);
- uiLayoutSetContextPointer(column, "shaderfx", &ptr);
+ bool panels_match = UI_panel_list_matches_data(region, modifiers, gpencil_modifier_panel_id);
- /* rounded header ------------------------------------------------------------------- */
- box = uiLayoutBox(column);
+ if (!panels_match) {
+ UI_panels_free_instanced(C, region);
+ GpencilModifierData *md = modifiers->first;
+ for (int i = 0; md; i++, md = md->next) {
+ const GpencilModifierTypeInfo *mti = BKE_gpencil_modifier_get_info(md->type);
+ if (mti->panelRegister == NULL) {
+ continue;
+ }
- row = uiLayoutRow(box, false);
- block = uiLayoutGetBlock(row);
+ char panel_idname[MAX_NAME];
+ gpencil_modifier_panel_id(md, panel_idname);
- UI_block_emboss_set(block, UI_EMBOSS_NONE);
- /* Open/Close ................................. */
- uiItemR(row, &ptr, "show_expanded", 0, "", ICON_NONE);
+ /* Create custom data RNA pointer. */
+ PointerRNA *md_ptr = MEM_mallocN(sizeof(PointerRNA), "panel customdata");
+ RNA_pointer_create(&ob->id, &RNA_GpencilModifier, md, md_ptr);
- /* shader-type icon */
- uiItemL(row, "", RNA_struct_ui_icon(ptr.type));
- UI_block_emboss_set(block, UI_EMBOSS);
+ Panel *new_panel = UI_panel_add_instanced(
+ sa, region, &region->panels, panel_idname, i, md_ptr);
- /* effect name */
- if (mti->isDisabled && mti->isDisabled(md, 0)) {
- uiLayoutSetRedAlert(row, true);
+ if (new_panel != NULL) {
+ UI_panel_set_expand_from_list_data(C, new_panel);
+ }
+ }
}
- uiItemR(row, &ptr, "name", 0, "", ICON_NONE);
- uiLayoutSetRedAlert(row, false);
-
- /* mode enabling buttons */
- UI_block_align_begin(block);
- uiItemR(row, &ptr, "show_render", 0, "", ICON_NONE);
- uiItemR(row, &ptr, "show_viewport", 0, "", ICON_NONE);
+ else {
+ /* The expansion might have been changed elsewhere, so we still need to set it. */
+ LISTBASE_FOREACH (Panel *, panel, &region->panels) {
+ if ((panel->type != NULL) && (panel->type->flag & PNL_INSTANCED))
+ UI_panel_set_expand_from_list_data(C, panel);
+ }
- if (mti->flags & eShaderFxTypeFlag_SupportsEditmode) {
- sub = uiLayoutRow(row, true);
- uiLayoutSetActive(sub, false);
- uiItemR(sub, &ptr, "show_in_editmode", 0, "", ICON_NONE);
- }
+ /* Assuming there's only one group of instanced panels, update the custom data pointers. */
+ Panel *panel = region->panels.first;
+ LISTBASE_FOREACH (ModifierData *, md, modifiers) {
+ const GpencilModifierTypeInfo *mti = BKE_gpencil_modifier_get_info(md->type);
+ if (mti->panelRegister == NULL) {
+ continue;
+ }
- UI_block_align_end(block);
+ /* Move to the next instanced panel corresponding to the next modifier. */
+ while ((panel->type == NULL) || !(panel->type->flag & PNL_INSTANCED)) {
+ panel = panel->next;
+ BLI_assert(panel != NULL); /* There shouldn't be fewer panels than modifiers with UIs. */
+ }
- /* Up/Down + Delete ........................... */
- UI_block_align_begin(block);
- uiItemO(row, "", ICON_TRIA_UP, "OBJECT_OT_shaderfx_move_up");
- uiItemO(row, "", ICON_TRIA_DOWN, "OBJECT_OT_shaderfx_move_down");
- UI_block_align_end(block);
+ PointerRNA *md_ptr = MEM_mallocN(sizeof(PointerRNA), "panel customdata");
+ RNA_pointer_create(&ob->id, &RNA_GpencilModifier, md, md_ptr);
+ UI_panel_custom_data_set(panel, md_ptr);
- UI_block_emboss_set(block, UI_EMBOSS_NONE);
- uiItemO(row, "", ICON_X, "OBJECT_OT_shaderfx_remove");
- UI_block_emboss_set(block, UI_EMBOSS);
+ panel = panel->next;
+ }
+ }
+}
- /* effect settings (under the header) --------------------------------------------------- */
- if (md->mode & eShaderFxMode_Expanded) {
- /* apply/convert/copy */
- box = uiLayoutBox(column);
- row = uiLayoutRow(box, false);
+/** \} */
- /* only here obdata, the rest of effect is ob level */
- UI_block_lock_set(block, BKE_object_obdata_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
+/** \} */
- /* result is the layout block inside the box,
- * that we return so that effect settings can be drawn */
- result = uiLayoutColumn(box, false);
- block = uiLayoutAbsoluteBlock(box);
- }
+#define ERROR_LIBDATA_MESSAGE TIP_("Can't edit external library data")
- /* error messages */
- if (md->error) {
- box = uiLayoutBox(column);
- row = uiLayoutRow(box, false);
- uiItemL(row, md->error, ICON_ERROR);
- }
+/* -------------------------------------------------------------------- */
+/** \name ShaderFx Template
+ *
+ * Template for building the panel layout for the active object's grease pencil shader
+ * effects.
+ * \{ */
- return result;
+/**
+ * Function with void * argument for #uiListPanelIDFromDataFunc.
+ */
+static void shaderfx_panel_id(void *fx_v, char *r_idname)
+{
+ ShaderFxData *fx = (ShaderFxData *)fx_v;
+ BKE_shaderfxType_panel_id(fx->type, r_idname);
}
-uiLayout *uiTemplateShaderFx(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+/**
+ * Check if the shader effect panels don't match the data and rebuild the panels if so.
+ */
+void uiTemplateShaderFx(uiLayout *UNUSED(layout), bContext *C)
{
- Object *ob;
- ShaderFxData *fx, *vfx;
- int i;
-
- /* verify we have valid data */
- if (!RNA_struct_is_a(ptr->type, &RNA_ShaderFx)) {
- RNA_warning("Expected shader fx on object");
- return NULL;
- }
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *region = CTX_wm_region(C);
+ Object *ob = get_context_object(C);
+ ListBase *shaderfx = &ob->shader_fx;
- ob = (Object *)ptr->owner_id;
- fx = ptr->data;
+ bool panels_match = UI_panel_list_matches_data(region, shaderfx, shaderfx_panel_id);
- if (!ob || !(GS(ob->id.name) == ID_OB)) {
- RNA_warning("Expected shader fx on object");
- return NULL;
+ if (!panels_match) {
+ UI_panels_free_instanced(C, region);
+ ShaderFxData *fx = shaderfx->first;
+ for (int i = 0; fx; i++, fx = fx->next) {
+ char panel_idname[MAX_NAME];
+ shaderfx_panel_id(fx, panel_idname);
+
+ Panel *new_panel = UI_panel_add_instanced(
+ sa, region, &region->panels, panel_idname, i, NULL);
+ if (new_panel != NULL) {
+ UI_panel_set_expand_from_list_data(C, new_panel);
+ }
+ }
}
-
- UI_block_lock_set(uiLayoutGetBlock(layout), (ob && ID_IS_LINKED(ob)), ERROR_LIBDATA_MESSAGE);
-
- /* find modifier and draw it */
- vfx = ob->shader_fx.first;
- for (i = 0; vfx; i++, vfx = vfx->next) {
- if (fx == vfx) {
- return gpencil_draw_shaderfx(layout, ob, fx);
+ else {
+ /* The expansion might have been changed elsewhere, so we still need to set it. */
+ LISTBASE_FOREACH (Panel *, panel, &region->panels) {
+ if ((panel->type != NULL) && (panel->type->flag & PNL_INSTANCED))
+ UI_panel_set_expand_from_list_data(C, panel);
}
}
-
- return NULL;
}
/** \} */
@@ -2441,38 +2518,25 @@ void uiTemplateOperatorRedoProperties(uiLayout *layout, const bContext *C)
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Constraint Template
+/** \name Constraint Header Template
* \{ */
+#define ERROR_LIBDATA_MESSAGE TIP_("Can't edit external library data")
+
static void constraint_active_func(bContext *UNUSED(C), void *ob_v, void *con_v)
{
ED_object_constraint_active_set(ob_v, con_v);
}
-/* draw panel showing settings for a constraint */
-static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con)
+static void draw_constraint_header(uiLayout *layout, Object *ob, bConstraint *con)
{
bPoseChannel *pchan = BKE_pose_channel_active(ob);
- const bConstraintTypeInfo *cti;
uiBlock *block;
- uiLayout *result = NULL, *col, *box, *row;
+ uiLayout *sub;
PointerRNA ptr;
- char typestr[32];
short proxy_protected, xco = 0, yco = 0;
// int rb_col; // UNUSED
- /* get constraint typeinfo */
- cti = BKE_constraint_typeinfo_get(con);
- if (cti == NULL) {
- /* exception for 'Null' constraint - it doesn't have constraint typeinfo! */
- BLI_strncpy(typestr,
- (con->type == CONSTRAINT_TYPE_NULL) ? IFACE_("Null") : IFACE_("Unknown"),
- sizeof(typestr));
- }
- else {
- BLI_strncpy(typestr, IFACE_(cti->name), sizeof(typestr));
- }
-
/* determine whether constraint is proxy protected or not */
if (BKE_constraints_proxylocked_owner(ob, pchan)) {
proxy_protected = (con->flag & CONSTRAINT_PROXY_LOCAL) == 0;
@@ -2487,36 +2551,23 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con)
RNA_pointer_create(&ob->id, &RNA_Constraint, con, &ptr);
- col = uiLayoutColumn(layout, true);
- uiLayoutSetContextPointer(col, "constraint", &ptr);
-
- box = uiLayoutBox(col);
- row = uiLayoutRow(box, false);
- block = uiLayoutGetBlock(box);
+ uiLayoutSetContextPointer(layout, "constraint", &ptr);
- /* Draw constraint header */
+ /* Constraint type icon. */
+ sub = uiLayoutRow(layout, false);
+ uiLayoutSetEmboss(sub, false);
+ uiLayoutSetRedAlert(sub, (con->flag & CONSTRAINT_DISABLE));
+ uiItemL(sub, "", RNA_struct_ui_icon(ptr.type));
- /* open/close */
- UI_block_emboss_set(block, UI_EMBOSS_NONE);
- uiItemR(row, &ptr, "show_expanded", 0, "", ICON_NONE);
-
- /* constraint-type icon */
- uiItemL(row, "", RNA_struct_ui_icon(ptr.type));
UI_block_emboss_set(block, UI_EMBOSS);
- if (con->flag & CONSTRAINT_DISABLE) {
- uiLayoutSetRedAlert(row, true);
- }
-
if (proxy_protected == 0) {
- uiItemR(row, &ptr, "name", 0, "", ICON_NONE);
+ uiItemR(layout, &ptr, "name", 0, "", ICON_NONE);
}
else {
- uiItemL(row, con->name, ICON_NONE);
+ uiItemL(layout, con->name, ICON_NONE);
}
- uiLayoutSetRedAlert(row, false);
-
/* proxy-protected constraints cannot be edited, so hide up/down + close buttons */
if (proxy_protected) {
UI_block_emboss_set(block, UI_EMBOSS_NONE);
@@ -2555,54 +2606,20 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con)
UI_block_emboss_set(block, UI_EMBOSS);
}
else {
- short prev_proxylock, show_upbut, show_downbut;
-
- /* Up/Down buttons:
- * Proxy-constraints are not allowed to occur after local (non-proxy) constraints
- * as that poses problems when restoring them, so disable the "up" button where
- * it may cause this situation.
- *
- * Up/Down buttons should only be shown (or not grayed - todo) if they serve some purpose.
- */
- if (BKE_constraints_proxylocked_owner(ob, pchan)) {
- if (con->prev) {
- prev_proxylock = (con->prev->flag & CONSTRAINT_PROXY_LOCAL) ? 0 : 1;
- }
- else {
- prev_proxylock = 0;
- }
- }
- else {
- prev_proxylock = 0;
- }
-
- show_upbut = ((prev_proxylock == 0) && (con->prev));
- show_downbut = (con->next) ? 1 : 0;
-
/* enabled */
UI_block_emboss_set(block, UI_EMBOSS_NONE);
- uiItemR(row, &ptr, "mute", 0, "", 0);
+ uiItemR(layout, &ptr, "mute", 0, "", 0);
UI_block_emboss_set(block, UI_EMBOSS);
- uiLayoutSetOperatorContext(row, WM_OP_INVOKE_DEFAULT);
-
- /* up/down */
- if (show_upbut || show_downbut) {
- UI_block_align_begin(block);
- if (show_upbut) {
- uiItemO(row, "", ICON_TRIA_UP, "CONSTRAINT_OT_move_up");
- }
-
- if (show_downbut) {
- uiItemO(row, "", ICON_TRIA_DOWN, "CONSTRAINT_OT_move_down");
- }
- UI_block_align_end(block);
- }
+ uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT);
/* Close 'button' - emboss calls here disable drawing of 'button' behind X */
UI_block_emboss_set(block, UI_EMBOSS_NONE);
- uiItemO(row, "", ICON_X, "CONSTRAINT_OT_delete");
+ uiItemO(layout, "", ICON_X, "CONSTRAINT_OT_delete");
UI_block_emboss_set(block, UI_EMBOSS);
+
+ /* Some extra padding at the end, so the 'x' icon isn't too close to drag button. */
+ uiItemS(layout);
}
/* Set but-locks for protected settings (magic numbers are used here!) */
@@ -2610,23 +2627,11 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con)
UI_block_lock_set(block, true, TIP_("Cannot edit Proxy-Protected Constraint"));
}
- /* Draw constraint data */
- if ((con->flag & CONSTRAINT_EXPAND) == 0) {
- (yco) -= 10.5f * UI_UNIT_Y;
- }
- else {
- box = uiLayoutBox(col);
- block = uiLayoutAbsoluteBlock(box);
- result = box;
- }
-
/* clear any locks set up for proxies/lib-linking */
UI_block_lock_clear(block);
-
- return result;
}
-uiLayout *uiTemplateConstraint(uiLayout *layout, PointerRNA *ptr)
+void uiTemplateConstraintHeader(uiLayout *layout, PointerRNA *ptr)
{
Object *ob;
bConstraint *con;
@@ -2634,7 +2639,7 @@ uiLayout *uiTemplateConstraint(uiLayout *layout, PointerRNA *ptr)
/* verify we have valid data */
if (!RNA_struct_is_a(ptr->type, &RNA_Constraint)) {
RNA_warning("Expected constraint on object");
- return NULL;
+ return;
}
ob = (Object *)ptr->owner_id;
@@ -2642,7 +2647,7 @@ uiLayout *uiTemplateConstraint(uiLayout *layout, PointerRNA *ptr)
if (!ob || !(GS(ob->id.name) == ID_OB)) {
RNA_warning("Expected constraint on object");
- return NULL;
+ return;
}
UI_block_lock_set(uiLayoutGetBlock(layout), (ob && ID_IS_LINKED(ob)), ERROR_LIBDATA_MESSAGE);
@@ -2651,11 +2656,11 @@ uiLayout *uiTemplateConstraint(uiLayout *layout, PointerRNA *ptr)
if (con->type == CONSTRAINT_TYPE_KINEMATIC) {
bKinematicConstraint *data = con->data;
if (data->flag & CONSTRAINT_IK_TEMP) {
- return NULL;
+ return;
}
}
- return draw_constraint(layout, ob, con);
+ draw_constraint_header(layout, ob, con);
}
/** \} */
@@ -4525,7 +4530,7 @@ static void CurveProfile_presets_dofunc(bContext *C, void *profile_v, int event)
profile->preset = event;
BKE_curveprofile_reset(profile);
- BKE_curveprofile_update(profile, false);
+ BKE_curveprofile_update(profile, PROF_UPDATE_NONE);
ED_undo_push(C, "CurveProfile tools");
ED_region_tag_redraw(CTX_wm_region(C));
@@ -4641,7 +4646,7 @@ static void CurveProfile_tools_dofunc(bContext *C, void *profile_v, int event)
switch (event) {
case UIPROFILE_FUNC_RESET: /* reset */
BKE_curveprofile_reset(profile);
- BKE_curveprofile_update(profile, false);
+ BKE_curveprofile_update(profile, PROF_UPDATE_NONE);
break;
case UIPROFILE_FUNC_RESET_VIEW: /* reset view to clipping rect */
profile->view_rect = profile->clip_rect;
@@ -4707,7 +4712,7 @@ static void CurveProfile_buttons_zoom_in(bContext *C, void *profile_v, void *UNU
CurveProfile *profile = profile_v;
float d;
- /* we allow 20 times zoom */
+ /* Allow a 20x zoom. */
if (BLI_rctf_size_x(&profile->view_rect) > 0.04f * BLI_rctf_size_x(&profile->clip_rect)) {
d = 0.1154f * BLI_rctf_size_x(&profile->view_rect);
profile->view_rect.xmin += d;
@@ -4771,7 +4776,7 @@ static void CurveProfile_clipping_toggle(bContext *C, void *cb_v, void *profile_
profile->flag ^= PROF_USE_CLIP;
- BKE_curveprofile_update(profile, false);
+ BKE_curveprofile_update(profile, PROF_UPDATE_NONE);
rna_update_cb(C, cb_v, NULL);
}
@@ -4780,7 +4785,7 @@ static void CurveProfile_buttons_reverse(bContext *C, void *cb_v, void *profile_
CurveProfile *profile = profile_v;
BKE_curveprofile_reverse(profile);
- BKE_curveprofile_update(profile, false);
+ BKE_curveprofile_update(profile, PROF_UPDATE_NONE);
rna_update_cb(C, cb_v, NULL);
}
@@ -4789,35 +4794,23 @@ static void CurveProfile_buttons_delete(bContext *C, void *cb_v, void *profile_v
CurveProfile *profile = profile_v;
BKE_curveprofile_remove_by_flag(profile, SELECT);
- BKE_curveprofile_update(profile, false);
-
- rna_update_cb(C, cb_v, NULL);
-}
-
-static void CurveProfile_buttons_setsharp(bContext *C, void *cb_v, void *profile_v)
-{
- CurveProfile *profile = profile_v;
-
- BKE_curveprofile_selected_handle_set(profile, HD_VECT, HD_VECT);
- BKE_curveprofile_update(profile, false);
+ BKE_curveprofile_update(profile, PROF_UPDATE_NONE);
rna_update_cb(C, cb_v, NULL);
}
-static void CurveProfile_buttons_setcurved(bContext *C, void *cb_v, void *profile_v)
+static void CurveProfile_buttons_update(bContext *C, void *arg1_v, void *profile_v)
{
CurveProfile *profile = profile_v;
-
- BKE_curveprofile_selected_handle_set(profile, HD_AUTO, HD_AUTO);
- BKE_curveprofile_update(profile, false);
-
- rna_update_cb(C, cb_v, NULL);
+ BKE_curveprofile_update(profile, PROF_UPDATE_REMOVE_DOUBLES | PROF_UPDATE_CLIP);
+ rna_update_cb(C, arg1_v, NULL);
}
-static void CurveProfile_buttons_update(bContext *C, void *arg1_v, void *profile_v)
+static void CurveProfile_buttons_reset(bContext *C, void *arg1_v, void *profile_v)
{
CurveProfile *profile = profile_v;
- BKE_curveprofile_update(profile, true);
+ BKE_curveprofile_reset(profile);
+ BKE_curveprofile_update(profile, PROF_UPDATE_NONE);
rna_update_cb(C, arg1_v, NULL);
}
@@ -4836,7 +4829,7 @@ static void CurveProfile_buttons_layout(uiLayout *layout, PointerRNA *ptr, RNAUp
UI_block_emboss_set(block, UI_EMBOSS);
- uiLayoutRow(layout, false);
+ uiLayoutSetPropSep(layout, false);
/* Preset selector */
/* There is probably potential to use simpler "uiItemR" functions here, but automatic updating
@@ -4845,6 +4838,29 @@ static void CurveProfile_buttons_layout(uiLayout *layout, PointerRNA *ptr, RNAUp
block, CurveProfile_buttons_presets, profile, "Preset", 0, 0, UI_UNIT_X, UI_UNIT_X, "");
UI_but_funcN_set(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
+ /* Show a "re-apply" preset button when it has been changed from the preset. */
+ if (profile->flag & PROF_DIRTY_PRESET) {
+ /* Only for dynamic presets. */
+ if (ELEM(profile->preset, PROF_PRESET_STEPS, PROF_PRESET_SUPPORTS)) {
+ bt = uiDefIconTextBut(block,
+ UI_BTYPE_BUT,
+ 0,
+ ICON_NONE,
+ "Apply Preset",
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_X,
+ NULL,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ "Reapply and update the preset, removing changes");
+ UI_but_funcN_set(bt, CurveProfile_buttons_reset, MEM_dupallocN(cb), profile);
+ }
+ }
+
row = uiLayoutRow(layout, false);
/* (Left aligned) */
@@ -4952,11 +4968,24 @@ static void CurveProfile_buttons_layout(uiLayout *layout, PointerRNA *ptr, RNAUp
"");
/* Position sliders for (first) selected point */
+ float *selection_x, *selection_y;
for (i = 0; i < profile->path_len; i++) {
if (profile->path[i].flag & PROF_SELECT) {
point = &profile->path[i];
+ selection_x = &point->x;
+ selection_y = &point->y;
break;
}
+ else if (profile->path[i].flag & PROF_H1_SELECT) {
+ point = &profile->path[i];
+ selection_x = &point->h1_loc[0];
+ selection_y = &point->h1_loc[1];
+ }
+ else if (profile->path[i].flag & PROF_H2_SELECT) {
+ point = &profile->path[i];
+ selection_x = &point->h2_loc[0];
+ selection_y = &point->h2_loc[1];
+ }
}
if (i == 0 || i == profile->path_len - 1) {
point_last_or_first = true;
@@ -4972,46 +5001,19 @@ static void CurveProfile_buttons_layout(uiLayout *layout, PointerRNA *ptr, RNAUp
bounds.xmax = bounds.ymax = 1000.0;
}
- uiLayoutRow(layout, true);
- UI_block_funcN_set(block, CurveProfile_buttons_update, MEM_dupallocN(cb), profile);
+ row = uiLayoutRow(layout, true);
- /* Sharp / Smooth */
- bt = uiDefIconBut(block,
- UI_BTYPE_BUT,
- 0,
- ICON_LINCURVE,
- 0,
- 0,
- UI_UNIT_X,
- UI_UNIT_X,
- NULL,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- TIP_("Set the point's handle type to sharp"));
- if (point_last_or_first) {
- UI_but_flag_enable(bt, UI_BUT_DISABLED);
- }
- UI_but_funcN_set(bt, CurveProfile_buttons_setsharp, MEM_dupallocN(cb), profile);
- bt = uiDefIconBut(block,
- UI_BTYPE_BUT,
- 0,
- ICON_SMOOTHCURVE,
- 0,
- 0,
- UI_UNIT_X,
- UI_UNIT_X,
- NULL,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- TIP_("Set the point's handle type to smooth"));
- UI_but_funcN_set(bt, CurveProfile_buttons_setcurved, MEM_dupallocN(cb), profile);
- if (point_last_or_first) {
- UI_but_flag_enable(bt, UI_BUT_DISABLED);
- }
+ PointerRNA point_ptr;
+ RNA_pointer_create(ptr->owner_id, &RNA_CurveProfilePoint, point, &point_ptr);
+ PropertyRNA *prop_handle_type = RNA_struct_find_property(&point_ptr, "handle_type_1");
+ uiItemFullR(row,
+ &point_ptr,
+ prop_handle_type,
+ RNA_NO_INDEX,
+ 0,
+ UI_ITEM_R_EXPAND | UI_ITEM_R_ICON_ONLY,
+ "",
+ ICON_NONE);
/* Position */
bt = uiDefButF(block,
@@ -5022,16 +5024,16 @@ static void CurveProfile_buttons_layout(uiLayout *layout, PointerRNA *ptr, RNAUp
2 * UI_UNIT_Y,
UI_UNIT_X * 10,
UI_UNIT_Y,
- &point->x,
+ selection_x,
bounds.xmin,
bounds.xmax,
1,
5,
"");
+ UI_but_funcN_set(bt, CurveProfile_buttons_update, MEM_dupallocN(cb), profile);
if (point_last_or_first) {
UI_but_flag_enable(bt, UI_BUT_DISABLED);
}
-
bt = uiDefButF(block,
UI_BTYPE_NUM,
0,
@@ -5040,12 +5042,13 @@ static void CurveProfile_buttons_layout(uiLayout *layout, PointerRNA *ptr, RNAUp
1 * UI_UNIT_Y,
UI_UNIT_X * 10,
UI_UNIT_Y,
- &point->y,
+ selection_y,
bounds.ymin,
bounds.ymax,
1,
5,
"");
+ UI_but_funcN_set(bt, CurveProfile_buttons_update, MEM_dupallocN(cb), profile);
if (point_last_or_first) {
UI_but_flag_enable(bt, UI_BUT_DISABLED);
}
@@ -7271,37 +7274,35 @@ void uiTemplateCacheFile(uiLayout *layout,
SpaceProperties *sbuts = CTX_wm_space_properties(C);
- uiLayout *row = uiLayoutRow(layout, false);
- uiBlock *block = uiLayoutGetBlock(row);
- uiDefBut(block, UI_BTYPE_LABEL, 0, IFACE_("File Path:"), 0, 19, 145, 19, NULL, 0, 0, 0, 0, "");
-
- row = uiLayoutRow(layout, false);
- uiLayout *split = uiLayoutSplit(row, 0.0f, false);
- row = uiLayoutRow(split, true);
+ uiLayout *row, *sub, *subsub;
- uiItemR(row, &fileptr, "filepath", 0, "", ICON_NONE);
- uiItemO(row, "", ICON_FILE_REFRESH, "cachefile.reload");
+ uiLayoutSetPropSep(layout, true);
- row = uiLayoutRow(layout, false);
- uiItemR(row, &fileptr, "is_sequence", 0, "Is Sequence", ICON_NONE);
+ row = uiLayoutRow(layout, true);
+ uiItemR(row, &fileptr, "filepath", 0, NULL, ICON_NONE);
+ sub = uiLayoutRow(row, true);
+ uiItemO(sub, "", ICON_FILE_REFRESH, "cachefile.reload");
row = uiLayoutRow(layout, false);
- uiItemR(row, &fileptr, "override_frame", 0, "Override Frame", ICON_NONE);
+ uiItemR(row, &fileptr, "is_sequence", 0, NULL, ICON_NONE);
- row = uiLayoutRow(layout, false);
- uiLayoutSetActive(row, RNA_boolean_get(&fileptr, "override_frame"));
- uiItemR(row, &fileptr, "frame", 0, "Frame", ICON_NONE);
+ row = uiLayoutRowWithHeading(layout, true, IFACE_("Override Frame"));
+ sub = uiLayoutRow(row, true);
+ uiLayoutSetPropDecorate(sub, false);
+ uiItemR(sub, &fileptr, "override_frame", 0, "", ICON_NONE);
+ subsub = uiLayoutRow(sub, true);
+ uiLayoutSetActive(subsub, RNA_boolean_get(&fileptr, "override_frame"));
+ uiItemR(subsub, &fileptr, "frame", 0, "", ICON_NONE);
+ uiItemDecoratorR(row, &fileptr, "frame", 0);
row = uiLayoutRow(layout, false);
- uiItemR(row, &fileptr, "frame_offset", 0, "Frame Offset", ICON_NONE);
+ uiItemR(row, &fileptr, "frame_offset", 0, NULL, ICON_NONE);
uiLayoutSetActive(row, !RNA_boolean_get(&fileptr, "is_sequence"));
- row = uiLayoutRow(layout, false);
- uiItemL(row, IFACE_("Manual Transform:"), ICON_NONE);
-
- row = uiLayoutRow(layout, false);
- uiLayoutSetActive(row, (sbuts->mainb == BCONTEXT_CONSTRAINT));
- uiItemR(row, &fileptr, "scale", 0, "Scale", ICON_NONE);
+ if (sbuts->mainb == BCONTEXT_CONSTRAINT) {
+ row = uiLayoutRow(layout, false);
+ uiItemR(row, &fileptr, "scale", 0, IFACE_("Manual Scale"), ICON_NONE);
+ }
/* TODO: unused for now, so no need to expose. */
#if 0
diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c
index 3737b607305..432da3d5dd5 100644
--- a/source/blender/editors/interface/interface_utils.c
+++ b/source/blender/editors/interface/interface_utils.c
@@ -45,6 +45,7 @@
#include "RNA_access.h"
#include "UI_interface.h"
+#include "UI_interface_icons.h"
#include "UI_resources.h"
#include "WM_api.h"
@@ -384,6 +385,7 @@ typedef struct CollItemSearch {
char *name;
int index;
int iconid;
+ bool is_id;
uint has_sep_char : 1;
} CollItemSearch;
@@ -418,6 +420,7 @@ void ui_rna_collection_search_update_fn(const struct bContext *C,
const bool skip_filter = data->search_but && !data->search_but->changed;
char name_buf[UI_MAX_DRAW_STR];
char *name;
+ bool has_id_icon = false;
/* build a temporary list of relevant items first */
RNA_PROP_BEGIN (&data->search_ptr, itemptr, data->search_prop) {
@@ -437,16 +440,20 @@ void ui_rna_collection_search_update_fn(const struct bContext *C,
int iconid = ICON_NONE;
bool has_sep_char = false;
+ bool is_id = itemptr.type && RNA_struct_is_ID(itemptr.type);
- if (itemptr.type && RNA_struct_is_ID(itemptr.type)) {
+ if (is_id) {
iconid = ui_id_icon_get(C, itemptr.data, false);
+ if (!ELEM(iconid, 0, ICON_BLANK1)) {
+ has_id_icon = true;
+ }
if (requires_exact_data_name) {
name = RNA_struct_name_get_alloc(&itemptr, name_buf, sizeof(name_buf), NULL);
}
else {
const ID *id = itemptr.data;
- BKE_id_full_name_ui_prefix_get(name_buf, id, UI_SEP_CHAR);
+ BKE_id_full_name_ui_prefix_get(name_buf, itemptr.data, true, UI_SEP_CHAR);
BLI_STATIC_ASSERT(sizeof(name_buf) >= MAX_ID_FULL_NAME_UI,
"Name string buffer should be big enough to hold full UI ID name");
name = name_buf;
@@ -464,6 +471,7 @@ void ui_rna_collection_search_update_fn(const struct bContext *C,
cis->name = BLI_strdup(name);
cis->index = i;
cis->iconid = iconid;
+ cis->is_id = is_id;
cis->has_sep_char = has_sep_char;
BLI_addtail(items_list, cis);
}
@@ -480,6 +488,17 @@ void ui_rna_collection_search_update_fn(const struct bContext *C,
/* add search items from temporary list */
for (cis = items_list->first; cis; cis = cis->next) {
+ /* If no item has an own icon to display, libraries can use the library icons rather than the
+ * name prefix for showing the library status. */
+ if (!has_id_icon && cis->is_id) {
+ cis->iconid = UI_library_icon_get(cis->data);
+ /* No need to re-allocate, string should be shorter than before (lib status prefix is
+ * removed). */
+ BKE_id_full_name_ui_prefix_get(name_buf, cis->data, false, UI_SEP_CHAR);
+ BLI_assert(strlen(name_buf) <= MEM_allocN_len(cis->name));
+ strcpy(cis->name, name_buf);
+ }
+
if (!UI_search_item_add(items,
cis->name,
cis->data,
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index 0498b312618..16a5a13885b 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -393,35 +393,14 @@ static const uint g_shape_preset_hold_action_face[2][3] = {{2, 0, 1}, {3, 5, 4}}
*
* \{ */
-/* offset in triavec[] in shader per type */
-static const int tria_ofs[ROUNDBOX_TRIA_MAX] = {
- [ROUNDBOX_TRIA_NONE] = 0,
- [ROUNDBOX_TRIA_ARROWS] = 0,
- [ROUNDBOX_TRIA_SCROLL] = 12,
- [ROUNDBOX_TRIA_MENU] = 28,
- [ROUNDBOX_TRIA_CHECK] = 34,
- [ROUNDBOX_TRIA_HOLD_ACTION_ARROW] = 40,
-};
-static const int tria_vcount[ROUNDBOX_TRIA_MAX] = {
- [ROUNDBOX_TRIA_NONE] = 0,
- [ROUNDBOX_TRIA_ARROWS] = 6,
- [ROUNDBOX_TRIA_SCROLL] = 16,
- [ROUNDBOX_TRIA_MENU] = 6,
- [ROUNDBOX_TRIA_CHECK] = 6,
- [ROUNDBOX_TRIA_HOLD_ACTION_ARROW] = 3,
-};
-
static struct {
- GPUBatch *roundbox_widget[ROUNDBOX_TRIA_MAX];
-
- GPUBatch *roundbox_simple;
- GPUBatch *roundbox_simple_aa;
- GPUBatch *roundbox_simple_outline;
+ GPUBatch *roundbox_widget;
GPUBatch *roundbox_shadow;
+ /* TODO remove */
GPUVertFormat format;
uint vflag_id;
-} g_ui_batch_cache = {{0}};
+} g_ui_batch_cache = {0};
static GPUVertFormat *vflag_format(void)
{
@@ -436,7 +415,7 @@ static GPUVertFormat *vflag_format(void)
#define INNER 0
#define OUTLINE 1
#define EMBOSS 2
-#define NO_AA WIDGET_AA_JITTER
+#define NO_AA 0
static void set_roundbox_vertex_data(GPUVertBufRaw *vflag_step, uint32_t d)
{
@@ -462,176 +441,30 @@ static uint32_t set_roundbox_vertex(GPUVertBufRaw *vflag_step,
return *data;
}
-static uint32_t set_tria_vertex(
- GPUVertBufRaw *vflag_step, int tria_type, int tria_v, int tria_id, int jit_v)
-{
- uint32_t *data = GPU_vertbuf_raw_step(vflag_step);
- if (ELEM(tria_type, ROUNDBOX_TRIA_ARROWS)) {
- tria_v += tria_id * tria_vcount[ROUNDBOX_TRIA_ARROWS];
- }
- *data = tria_ofs[tria_type] + tria_v;
- *data |= jit_v << 6;
- *data |= (tria_id == 0) ? (1 << 10) : 0; /* is first tria */
- *data |= 1 << 14; /* is tria vert */
- return *data;
-}
-
-static void roundbox_batch_add_tria(GPUVertBufRaw *vflag_step, int tria, uint32_t last_data)
+GPUBatch *ui_batch_roundbox_widget_get(void)
{
- const int tria_num =
- ELEM(tria, ROUNDBOX_TRIA_CHECK, ROUNDBOX_TRIA_HOLD_ACTION_ARROW, ROUNDBOX_TRIA_MENU) ? 1 : 2;
- /* for each tria */
- for (int t = 0; t < tria_num; t++) {
- for (int j = 0; j < WIDGET_AA_JITTER; j++) {
- /* restart */
- set_roundbox_vertex_data(vflag_step, last_data);
- set_tria_vertex(vflag_step, tria, 0, t, j);
- for (int v = 0; v < tria_vcount[tria]; v++) {
- last_data = set_tria_vertex(vflag_step, tria, v, t, j);
- }
- }
- }
-}
-
-GPUBatch *ui_batch_roundbox_widget_get(int tria)
-{
- if (g_ui_batch_cache.roundbox_widget[tria] == NULL) {
- uint32_t last_data;
- GPUVertBufRaw vflag_step;
+ if (g_ui_batch_cache.roundbox_widget == NULL) {
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(vflag_format());
- int vcount = WIDGET_SIZE_MAX; /* inner */
- vcount += 2; /* restart */
- vcount += ((WIDGET_SIZE_MAX + 1) * 2) * WIDGET_AA_JITTER; /* outline (edges) */
- vcount += 2; /* restart */
- vcount += ((WIDGET_CURVE_RESOLU * 2) * 2) * WIDGET_AA_JITTER; /* emboss */
- if (tria) {
- vcount += (tria_vcount[tria] + 2) * WIDGET_AA_JITTER; /* tria1 */
- if (!ELEM(tria, ROUNDBOX_TRIA_CHECK, ROUNDBOX_TRIA_HOLD_ACTION_ARROW, ROUNDBOX_TRIA_MENU)) {
- vcount += (tria_vcount[tria] + 2) * WIDGET_AA_JITTER; /* tria2 */
- }
- }
- GPU_vertbuf_data_alloc(vbo, vcount);
- GPU_vertbuf_attr_get_raw_data(vbo, g_ui_batch_cache.vflag_id, &vflag_step);
- /* Inner */
- for (int c1 = 0, c2 = 3; c1 < 2; c1++, c2--) {
- for (int a1 = 0, a2 = WIDGET_CURVE_RESOLU - 1; a2 >= 0; a1++, a2--) {
- last_data = set_roundbox_vertex(&vflag_step, c1, a1, NO_AA, true, false, INNER);
- last_data = set_roundbox_vertex(&vflag_step, c2, a2, NO_AA, true, false, INNER);
- }
- }
- /* restart */
- set_roundbox_vertex_data(&vflag_step, last_data);
- set_roundbox_vertex(&vflag_step, 0, 0, 0, true, false, OUTLINE);
- /* Outlines */
- for (int j = 0; j < WIDGET_AA_JITTER; j++) {
- for (int c = 0; c < 4; c++) {
- for (int a = 0; a < WIDGET_CURVE_RESOLU; a++) {
- set_roundbox_vertex(&vflag_step, c, a, j, true, false, OUTLINE);
- set_roundbox_vertex(&vflag_step, c, a, j, false, false, OUTLINE);
- }
- }
- /* Close the loop. */
- set_roundbox_vertex(&vflag_step, 0, 0, j, true, false, OUTLINE);
- last_data = set_roundbox_vertex(&vflag_step, 0, 0, j, false, false, OUTLINE);
- }
- /* restart */
- set_roundbox_vertex_data(&vflag_step, last_data);
- set_roundbox_vertex(&vflag_step, 0, 0, 0, false, false, EMBOSS);
- /* Emboss */
- /* go back and forth : avoid degenerate triangle (but beware of backface cull) */
- bool rev = false;
- for (int j = 0; j < WIDGET_AA_JITTER; j++, rev = !rev) {
- for (int c = (rev) ? 1 : 0; (rev) ? c >= 0 : c < 2; (rev) ? c-- : c++) {
- int sta = (rev) ? WIDGET_CURVE_RESOLU - 1 : 0;
- int end = WIDGET_CURVE_RESOLU;
- for (int a = sta; (rev) ? a >= 0 : a < end; (rev) ? a-- : a++) {
- set_roundbox_vertex(&vflag_step, c, a, j, false, false, EMBOSS);
- last_data = set_roundbox_vertex(&vflag_step, c, a, j, false, true, EMBOSS);
- }
- }
- }
- if (tria) {
- roundbox_batch_add_tria(&vflag_step, tria, last_data);
- }
- g_ui_batch_cache.roundbox_widget[tria] = GPU_batch_create_ex(
- GPU_PRIM_TRI_STRIP, vbo, NULL, GPU_BATCH_OWNS_VBO);
- gpu_batch_presets_register(g_ui_batch_cache.roundbox_widget[tria]);
- }
- return g_ui_batch_cache.roundbox_widget[tria];
-}
-GPUBatch *ui_batch_roundbox_get(bool filled, bool antialiased)
-{
- GPUBatch **batch = NULL;
+ GPU_vertbuf_data_alloc(vbo, 12);
- if (filled) {
- if (antialiased) {
- batch = &g_ui_batch_cache.roundbox_simple_aa;
- }
- else {
- batch = &g_ui_batch_cache.roundbox_simple;
- }
- }
- else {
- if (antialiased) {
- BLI_assert(0); /* Use GL_LINE_SMOOTH instead!!: */
- }
- else {
- batch = &g_ui_batch_cache.roundbox_simple_outline;
- }
- }
+ GPUIndexBufBuilder ibuf;
+ GPU_indexbuf_init(&ibuf, GPU_PRIM_TRIS, 6, 12);
+ /* Widget */
+ GPU_indexbuf_add_tri_verts(&ibuf, 0, 1, 2);
+ GPU_indexbuf_add_tri_verts(&ibuf, 2, 1, 3);
+ /* Trias */
+ GPU_indexbuf_add_tri_verts(&ibuf, 4, 5, 6);
+ GPU_indexbuf_add_tri_verts(&ibuf, 6, 5, 7);
- if (*batch == NULL) {
- uint32_t last_data;
- GPUVertBufRaw vflag_step;
- GPUVertBuf *vbo = GPU_vertbuf_create_with_format(vflag_format());
- int vcount = WIDGET_SIZE_MAX;
- vcount += (filled) ? 2 : 0;
- vcount *= (antialiased) ? WIDGET_AA_JITTER : 1;
- GPU_vertbuf_data_alloc(vbo, vcount);
- GPU_vertbuf_attr_get_raw_data(vbo, g_ui_batch_cache.vflag_id, &vflag_step);
+ GPU_indexbuf_add_tri_verts(&ibuf, 8, 9, 10);
+ GPU_indexbuf_add_tri_verts(&ibuf, 10, 9, 11);
- if (filled) {
- for (int j = 0; j < WIDGET_AA_JITTER; j++) {
- if (!antialiased) {
- j = NO_AA;
- }
- /* restart */
- set_roundbox_vertex(&vflag_step, 0, 0, j, true, false, INNER);
- for (int c1 = 0, c2 = 3; c1 < 2; c1++, c2--) {
- for (int a1 = 0, a2 = WIDGET_CURVE_RESOLU - 1; a2 >= 0; a1++, a2--) {
- last_data = set_roundbox_vertex(&vflag_step, c1, a1, j, true, false, INNER);
- last_data = set_roundbox_vertex(&vflag_step, c2, a2, j, true, false, INNER);
- }
- }
- /* restart */
- set_roundbox_vertex_data(&vflag_step, last_data);
- if (!antialiased) {
- break;
- }
- }
- *batch = GPU_batch_create_ex(GPU_PRIM_TRI_STRIP, vbo, NULL, GPU_BATCH_OWNS_VBO);
- }
- else {
- for (int j = 0; j < WIDGET_AA_JITTER; j++) {
- if (!antialiased) {
- j = NO_AA;
- }
- for (int c = 0; c < 4; c++) {
- for (int a = 0; a < WIDGET_CURVE_RESOLU; a++) {
- set_roundbox_vertex(&vflag_step, c, a, j, true, false, INNER);
- }
- }
- if (!antialiased) {
- break;
- }
- }
- *batch = GPU_batch_create_ex(GPU_PRIM_LINE_LOOP, vbo, NULL, GPU_BATCH_OWNS_VBO);
- }
-
- gpu_batch_presets_register(*batch);
+ g_ui_batch_cache.roundbox_widget = GPU_batch_create_ex(
+ GPU_PRIM_TRIS, vbo, GPU_indexbuf_build(&ibuf), GPU_BATCH_OWNS_INDEX | GPU_BATCH_OWNS_VBO);
+ gpu_batch_presets_register(g_ui_batch_cache.roundbox_widget);
}
- return *batch;
+ return g_ui_batch_cache.roundbox_widget;
}
GPUBatch *ui_batch_roundbox_shadow_get(void)
@@ -1314,14 +1147,13 @@ static void widgetbase_set_uniform_colors_ubv(uiWidgetBase *wtb,
/* keep in sync with shader */
#define MAX_WIDGET_BASE_BATCH 6
-#define MAX_WIDGET_PARAMETERS 11
+#define MAX_WIDGET_PARAMETERS 12
static struct {
- GPUBatch *batch; /* Batch type */
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH];
int count;
bool enabled;
-} g_widget_base_batch = {0};
+} g_widget_base_batch = {{{{0}}}};
void UI_widgetbase_draw_cache_flush(void)
{
@@ -1332,7 +1164,7 @@ void UI_widgetbase_draw_cache_flush(void)
return;
}
- GPUBatch *batch = g_widget_base_batch.batch;
+ GPUBatch *batch = ui_batch_roundbox_widget_get();
if (g_widget_base_batch.count == 1) {
/* draw single */
GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
@@ -1376,31 +1208,15 @@ void UI_widgetbase_draw_cache_end(void)
GPU_blend(false);
}
-static void draw_widgetbase_batch(GPUBatch *batch, uiWidgetBase *wtb)
+static void draw_widgetbase_batch(uiWidgetBase *wtb)
{
+ wtb->uniform_params.tria_type = wtb->tria1.type;
wtb->uniform_params.tria1_size = wtb->tria1.size;
wtb->uniform_params.tria2_size = wtb->tria2.size;
copy_v2_v2(wtb->uniform_params.tria1_center, wtb->tria1.center);
copy_v2_v2(wtb->uniform_params.tria2_center, wtb->tria2.center);
if (g_widget_base_batch.enabled) {
- if (g_widget_base_batch.batch == NULL) {
- g_widget_base_batch.batch = ui_batch_roundbox_widget_get(ROUNDBOX_TRIA_ARROWS);
- }
-
- /* draw multi */
- if (batch != g_ui_batch_cache.roundbox_widget[ROUNDBOX_TRIA_NONE] &&
- batch != g_widget_base_batch.batch) {
- /* issue previous calls before changing batch type. */
- UI_widgetbase_draw_cache_flush();
- g_widget_base_batch.batch = batch;
- }
-
- /* No need to change batch if tria is not visible. Just scale it to 0. */
- if (batch == g_ui_batch_cache.roundbox_widget[ROUNDBOX_TRIA_NONE]) {
- wtb->uniform_params.tria1_size = wtb->uniform_params.tria2_size = 0;
- }
-
g_widget_base_batch.params[g_widget_base_batch.count] = wtb->uniform_params;
g_widget_base_batch.count++;
@@ -1412,6 +1228,7 @@ static void draw_widgetbase_batch(GPUBatch *batch, uiWidgetBase *wtb)
const float checker_params[3] = {
UI_ALPHA_CHECKER_DARK / 255.0f, UI_ALPHA_CHECKER_LIGHT / 255.0f, 8.0f};
/* draw single */
+ GPUBatch *batch = ui_batch_roundbox_widget_get();
GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
GPU_batch_uniform_4fv_array(
batch, "parameters", MAX_WIDGET_PARAMETERS, (float *)&wtb->uniform_params);
@@ -1434,8 +1251,6 @@ static void widgetbase_draw_ex(uiWidgetBase *wtb,
show_alpha_checkers = false;
}
- GPU_blend(true);
-
/* backdrop non AA */
if (wtb->draw_inner) {
if (wcol->shaded == 0) {
@@ -1455,7 +1270,7 @@ static void widgetbase_draw_ex(uiWidgetBase *wtb,
outline_col[0] = wcol->outline[0];
outline_col[1] = wcol->outline[1];
outline_col[2] = wcol->outline[2];
- outline_col[3] = wcol->outline[3] / WIDGET_AA_JITTER;
+ outline_col[3] = wcol->outline[3];
/* emboss bottom shadow */
if (wtb->draw_emboss) {
@@ -1467,7 +1282,7 @@ static void widgetbase_draw_ex(uiWidgetBase *wtb,
tria_col[0] = wcol->item[0];
tria_col[1] = wcol->item[1];
tria_col[2] = wcol->item[2];
- tria_col[3] = (uchar)((float)wcol->item[3] / WIDGET_AA_JITTER);
+ tria_col[3] = wcol->item[3];
}
/* Draw everything in one drawcall */
@@ -1476,11 +1291,10 @@ static void widgetbase_draw_ex(uiWidgetBase *wtb,
widgetbase_set_uniform_colors_ubv(
wtb, inner_col1, inner_col2, outline_col, emboss_col, tria_col, show_alpha_checkers);
- GPUBatch *roundbox_batch = ui_batch_roundbox_widget_get(wtb->tria1.type);
- draw_widgetbase_batch(roundbox_batch, wtb);
+ GPU_blend(true);
+ draw_widgetbase_batch(wtb);
+ GPU_blend(false);
}
-
- GPU_blend(false);
}
static void widgetbase_draw(uiWidgetBase *wtb, const uiWidgetColors *wcol)
diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c
index f8419ba3eba..d696c99851b 100644
--- a/source/blender/editors/interface/view2d.c
+++ b/source/blender/editors/interface/view2d.c
@@ -113,10 +113,10 @@ BLI_INLINE void clamp_rctf_to_rcti(rcti *dst, const rctf *src)
static int view2d_scroll_mapped(int scroll)
{
if (scroll & V2D_SCROLL_HORIZONTAL_FULLR) {
- scroll &= ~(V2D_SCROLL_HORIZONTAL);
+ scroll &= ~V2D_SCROLL_HORIZONTAL;
}
if (scroll & V2D_SCROLL_VERTICAL_FULLR) {
- scroll &= ~(V2D_SCROLL_VERTICAL);
+ scroll &= ~V2D_SCROLL_VERTICAL;
}
return scroll;
}
@@ -198,7 +198,7 @@ static void view2d_masks(View2D *v2d, const rcti *mask_scroll)
}
/* horizontal scroller */
- if (scroll & (V2D_SCROLL_BOTTOM)) {
+ if (scroll & V2D_SCROLL_BOTTOM) {
/* on bottom edge of region */
v2d->hor = *mask_scroll;
v2d->hor.ymax = scroll_height;
@@ -211,7 +211,7 @@ static void view2d_masks(View2D *v2d, const rcti *mask_scroll)
/* adjust vertical scroller if there's a horizontal scroller, to leave corner free */
if (scroll & V2D_SCROLL_VERTICAL) {
- if (scroll & (V2D_SCROLL_BOTTOM)) {
+ if (scroll & V2D_SCROLL_BOTTOM) {
/* on bottom edge of region */
v2d->vert.ymin = v2d->hor.ymax;
}
@@ -1408,22 +1408,22 @@ struct View2DScrollers {
int vert_min, vert_max; /* vertical scrollbar */
int hor_min, hor_max; /* horizontal scrollbar */
- rcti hor, vert; /* exact size of slider backdrop */
- int horfull, vertfull; /* set if sliders are full, we don't draw them */
+ /** Exact size of slider backdrop. */
+ rcti hor, vert;
+ /* set if sliders are full, we don't draw them */
+ /* int horfull, vertfull; */ /* UNUSED */
};
/* Calculate relevant scroller properties */
-View2DScrollers *UI_view2d_scrollers_calc(View2D *v2d, const rcti *mask_custom)
+void UI_view2d_scrollers_calc(View2D *v2d,
+ const rcti *mask_custom,
+ struct View2DScrollers *r_scrollers)
{
- View2DScrollers *scrollers;
rcti vert, hor;
float fac1, fac2, totsize, scrollsize;
int scroll = view2d_scroll_mapped(v2d->scroll);
int smaller;
- /* scrollers is allocated here... */
- scrollers = MEM_callocN(sizeof(View2DScrollers), "View2DScrollers");
-
/* Always update before drawing (for dynamically sized scrollers). */
view2d_masks(v2d, mask_custom);
@@ -1452,12 +1452,12 @@ View2DScrollers *UI_view2d_scrollers_calc(View2D *v2d, const rcti *mask_custom)
vert.xmax -= smaller;
}
- CLAMP(vert.ymin, vert.ymin, vert.ymax - V2D_SCROLL_HANDLE_SIZE_HOTSPOT);
- CLAMP(hor.xmin, hor.xmin, hor.xmax - V2D_SCROLL_HANDLE_SIZE_HOTSPOT);
+ CLAMP_MAX(vert.ymin, vert.ymax - V2D_SCROLL_HANDLE_SIZE_HOTSPOT);
+ CLAMP_MAX(hor.xmin, hor.xmax - V2D_SCROLL_HANDLE_SIZE_HOTSPOT);
/* store in scrollers, used for drawing */
- scrollers->vert = vert;
- scrollers->hor = hor;
+ r_scrollers->vert = vert;
+ r_scrollers->hor = hor;
/* scroller 'buttons':
* - These should always remain within the visible region of the scrollbar
@@ -1475,30 +1475,30 @@ View2DScrollers *UI_view2d_scrollers_calc(View2D *v2d, const rcti *mask_custom)
fac1 = (v2d->cur.xmin - v2d->tot.xmin) / totsize;
if (fac1 <= 0.0f) {
- scrollers->hor_min = hor.xmin;
+ r_scrollers->hor_min = hor.xmin;
}
else {
- scrollers->hor_min = (int)(hor.xmin + (fac1 * scrollsize));
+ r_scrollers->hor_min = (int)(hor.xmin + (fac1 * scrollsize));
}
fac2 = (v2d->cur.xmax - v2d->tot.xmin) / totsize;
if (fac2 >= 1.0f) {
- scrollers->hor_max = hor.xmax;
+ r_scrollers->hor_max = hor.xmax;
}
else {
- scrollers->hor_max = (int)(hor.xmin + (fac2 * scrollsize));
+ r_scrollers->hor_max = (int)(hor.xmin + (fac2 * scrollsize));
}
/* prevent inverted sliders */
- if (scrollers->hor_min > scrollers->hor_max) {
- scrollers->hor_min = scrollers->hor_max;
+ if (r_scrollers->hor_min > r_scrollers->hor_max) {
+ r_scrollers->hor_min = r_scrollers->hor_max;
}
/* prevent sliders from being too small to grab */
- if ((scrollers->hor_max - scrollers->hor_min) < V2D_SCROLL_THUMB_SIZE_MIN) {
- scrollers->hor_max = scrollers->hor_min + V2D_SCROLL_THUMB_SIZE_MIN;
+ if ((r_scrollers->hor_max - r_scrollers->hor_min) < V2D_SCROLL_THUMB_SIZE_MIN) {
+ r_scrollers->hor_max = r_scrollers->hor_min + V2D_SCROLL_THUMB_SIZE_MIN;
- CLAMP(scrollers->hor_max, hor.xmin + V2D_SCROLL_THUMB_SIZE_MIN, hor.xmax);
- CLAMP(scrollers->hor_min, hor.xmin, hor.xmax - V2D_SCROLL_THUMB_SIZE_MIN);
+ CLAMP(r_scrollers->hor_max, hor.xmin + V2D_SCROLL_THUMB_SIZE_MIN, hor.xmax);
+ CLAMP(r_scrollers->hor_min, hor.xmin, hor.xmax - V2D_SCROLL_THUMB_SIZE_MIN);
}
}
@@ -1513,39 +1513,39 @@ View2DScrollers *UI_view2d_scrollers_calc(View2D *v2d, const rcti *mask_custom)
fac1 = (v2d->cur.ymin - v2d->tot.ymin) / totsize;
if (fac1 <= 0.0f) {
- scrollers->vert_min = vert.ymin;
+ r_scrollers->vert_min = vert.ymin;
}
else {
- scrollers->vert_min = (int)(vert.ymin + (fac1 * scrollsize));
+ r_scrollers->vert_min = (int)(vert.ymin + (fac1 * scrollsize));
}
fac2 = (v2d->cur.ymax - v2d->tot.ymin) / totsize;
if (fac2 >= 1.0f) {
- scrollers->vert_max = vert.ymax;
+ r_scrollers->vert_max = vert.ymax;
}
else {
- scrollers->vert_max = (int)(vert.ymin + (fac2 * scrollsize));
+ r_scrollers->vert_max = (int)(vert.ymin + (fac2 * scrollsize));
}
/* prevent inverted sliders */
- if (scrollers->vert_min > scrollers->vert_max) {
- scrollers->vert_min = scrollers->vert_max;
+ if (r_scrollers->vert_min > r_scrollers->vert_max) {
+ r_scrollers->vert_min = r_scrollers->vert_max;
}
/* prevent sliders from being too small to grab */
- if ((scrollers->vert_max - scrollers->vert_min) < V2D_SCROLL_THUMB_SIZE_MIN) {
- scrollers->vert_max = scrollers->vert_min + V2D_SCROLL_THUMB_SIZE_MIN;
+ if ((r_scrollers->vert_max - r_scrollers->vert_min) < V2D_SCROLL_THUMB_SIZE_MIN) {
+ r_scrollers->vert_max = r_scrollers->vert_min + V2D_SCROLL_THUMB_SIZE_MIN;
- CLAMP(scrollers->vert_max, vert.ymin + V2D_SCROLL_THUMB_SIZE_MIN, vert.ymax);
- CLAMP(scrollers->vert_min, vert.ymin, vert.ymax - V2D_SCROLL_THUMB_SIZE_MIN);
+ CLAMP(r_scrollers->vert_max, vert.ymin + V2D_SCROLL_THUMB_SIZE_MIN, vert.ymax);
+ CLAMP(r_scrollers->vert_min, vert.ymin, vert.ymax - V2D_SCROLL_THUMB_SIZE_MIN);
}
}
-
- return scrollers;
}
/* Draw scrollbars in the given 2d-region */
-void UI_view2d_scrollers_draw(View2D *v2d, View2DScrollers *vs)
+void UI_view2d_scrollers_draw(View2D *v2d, const rcti *mask_custom)
{
+ View2DScrollers scrollers;
+ UI_view2d_scrollers_calc(v2d, mask_custom, &scrollers);
bTheme *btheme = UI_GetTheme();
rcti vert, hor;
const int scroll = view2d_scroll_mapped(v2d->scroll);
@@ -1556,8 +1556,8 @@ void UI_view2d_scrollers_draw(View2D *v2d, View2DScrollers *vs)
UI_GetThemeColor4ubv(TH_BACK, scrollers_back_color);
/* make copies of rects for less typing */
- vert = vs->vert;
- hor = vs->hor;
+ vert = scrollers.vert;
+ hor = scrollers.hor;
/* horizontal scrollbar */
if (scroll & V2D_SCROLL_HORIZONTAL) {
@@ -1566,8 +1566,8 @@ void UI_view2d_scrollers_draw(View2D *v2d, View2DScrollers *vs)
rcti slider;
int state;
- slider.xmin = vs->hor_min;
- slider.xmax = vs->hor_max;
+ slider.xmin = scrollers.hor_min;
+ slider.xmax = scrollers.hor_max;
slider.ymin = hor.ymin;
slider.ymax = hor.ymax;
@@ -1602,8 +1602,8 @@ void UI_view2d_scrollers_draw(View2D *v2d, View2DScrollers *vs)
slider.xmin = vert.xmin;
slider.xmax = vert.xmax;
- slider.ymin = vs->vert_min;
- slider.ymax = vs->vert_max;
+ slider.ymin = scrollers.vert_min;
+ slider.ymax = scrollers.vert_max;
state = (v2d->scroll_ui & V2D_SCROLL_V_ACTIVE) ? UI_SCROLL_PRESSED : 0;
@@ -1631,12 +1631,6 @@ void UI_view2d_scrollers_draw(View2D *v2d, View2DScrollers *vs)
btheme->tui.widget_emboss[3] = emboss_alpha;
}
-/* free temporary memory used for drawing scrollers */
-void UI_view2d_scrollers_free(View2DScrollers *scrollers)
-{
- MEM_freeN(scrollers);
-}
-
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c
index 98bbd7af943..0efb49f42bf 100644
--- a/source/blender/editors/interface/view2d_ops.c
+++ b/source/blender/editors/interface/view2d_ops.c
@@ -1922,6 +1922,9 @@ struct View2DScrollers {
/* focus bubbles */
int vert_min, vert_max; /* vertical scrollbar */
int hor_min, hor_max; /* horizontal scrollbar */
+
+ /* These values are written into, even if we don't use them. */
+ rcti _hor, _vert;
};
/* quick enum for vsm->zone (scroller handles) */
@@ -2011,7 +2014,7 @@ static void scroller_activate_init(bContext *C,
const char in_scroller)
{
v2dScrollerMove *vsm;
- View2DScrollers *scrollers;
+ View2DScrollers scrollers;
ARegion *region = CTX_wm_region(C);
View2D *v2d = &region->v2d;
rctf tot_cur_union;
@@ -2032,7 +2035,7 @@ static void scroller_activate_init(bContext *C,
/* 'zone' depends on where mouse is relative to bubble
* - zooming must be allowed on this axis, otherwise, default to pan
*/
- scrollers = UI_view2d_scrollers_calc(v2d, NULL);
+ UI_view2d_scrollers_calc(v2d, NULL, &scrollers);
/* Use a union of 'cur' & 'tot' in case the current view is far outside 'tot'. In this cases
* moving the scroll bars has far too little effect and the view can get stuck T31476. */
@@ -2049,15 +2052,15 @@ static void scroller_activate_init(bContext *C,
/* get 'zone' (i.e. which part of scroller is activated) */
vsm->zone = mouse_in_scroller_handle(
- event->mval[0], v2d->hor.xmin, v2d->hor.xmax, scrollers->hor_min, scrollers->hor_max);
+ event->mval[0], v2d->hor.xmin, v2d->hor.xmax, scrollers.hor_min, scrollers.hor_max);
if ((v2d->keepzoom & V2D_LOCKZOOM_X) && ELEM(vsm->zone, SCROLLHANDLE_MIN, SCROLLHANDLE_MAX)) {
/* default to scroll, as handles not usable */
vsm->zone = SCROLLHANDLE_BAR;
}
- vsm->scrollbarwidth = scrollers->hor_max - scrollers->hor_min;
- vsm->scrollbar_orig = ((scrollers->hor_max + scrollers->hor_min) / 2) + region->winrct.xmin;
+ vsm->scrollbarwidth = scrollers.hor_max - scrollers.hor_min;
+ vsm->scrollbar_orig = ((scrollers.hor_max + scrollers.hor_min) / 2) + region->winrct.xmin;
}
else {
/* vertical scroller - calculate adjustment factor first */
@@ -2069,18 +2072,17 @@ static void scroller_activate_init(bContext *C,
/* get 'zone' (i.e. which part of scroller is activated) */
vsm->zone = mouse_in_scroller_handle(
- event->mval[1], v2d->vert.ymin, v2d->vert.ymax, scrollers->vert_min, scrollers->vert_max);
+ event->mval[1], v2d->vert.ymin, v2d->vert.ymax, scrollers.vert_min, scrollers.vert_max);
if ((v2d->keepzoom & V2D_LOCKZOOM_Y) && ELEM(vsm->zone, SCROLLHANDLE_MIN, SCROLLHANDLE_MAX)) {
/* default to scroll, as handles not usable */
vsm->zone = SCROLLHANDLE_BAR;
}
- vsm->scrollbarwidth = scrollers->vert_max - scrollers->vert_min;
- vsm->scrollbar_orig = ((scrollers->vert_max + scrollers->vert_min) / 2) + region->winrct.ymin;
+ vsm->scrollbarwidth = scrollers.vert_max - scrollers.vert_min;
+ vsm->scrollbar_orig = ((scrollers.vert_max + scrollers.vert_min) / 2) + region->winrct.ymin;
}
- UI_view2d_scrollers_free(scrollers);
ED_region_tag_redraw_no_rebuild(region);
}
@@ -2299,8 +2301,8 @@ static int scroller_activate_invoke(bContext *C, wmOperator *op, const wmEvent *
}
/* zone is also inappropriate if scroller is not visible... */
- if (((vsm->scroller == 'h') && (v2d->scroll & (V2D_SCROLL_HORIZONTAL_FULLR))) ||
- ((vsm->scroller == 'v') && (v2d->scroll & (V2D_SCROLL_VERTICAL_FULLR)))) {
+ if (((vsm->scroller == 'h') && (v2d->scroll & V2D_SCROLL_HORIZONTAL_FULLR)) ||
+ ((vsm->scroller == 'v') && (v2d->scroll & V2D_SCROLL_VERTICAL_FULLR))) {
/* free customdata initialized */
scroller_activate_exit(C, op);
diff --git a/source/blender/editors/io/io_alembic.c b/source/blender/editors/io/io_alembic.c
index fc2c55ffeda..9db1fe31494 100644
--- a/source/blender/editors/io/io_alembic.c
+++ b/source/blender/editors/io/io_alembic.c
@@ -410,8 +410,11 @@ void WM_OT_alembic_export(wmOperatorType *ot)
"Use Subdivision Schema",
"Export meshes using Alembic's subdivision schema");
- RNA_def_boolean(
- ot->srna, "apply_subdiv", 0, "Apply Subdivision Surface", "Export subdivision surfaces as meshes");
+ RNA_def_boolean(ot->srna,
+ "apply_subdiv",
+ 0,
+ "Apply Subdivision Surface",
+ "Export subdivision surfaces as meshes");
RNA_def_boolean(ot->srna,
"curves_as_mesh",
@@ -667,6 +670,7 @@ void WM_OT_alembic_import(wmOperatorType *ot)
ot->name = "Import Alembic";
ot->description = "Load an Alembic archive";
ot->idname = "WM_OT_alembic_import";
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
ot->invoke = wm_alembic_import_invoke;
ot->exec = wm_alembic_import_exec;
diff --git a/source/blender/editors/io/io_collada.c b/source/blender/editors/io/io_collada.c
index 9091e7d8afc..c1a4492994a 100644
--- a/source/blender/editors/io/io_collada.c
+++ b/source/blender/editors/io/io_collada.c
@@ -857,6 +857,7 @@ void WM_OT_collada_import(wmOperatorType *ot)
ot->name = "Import COLLADA";
ot->description = "Load a Collada file";
ot->idname = "WM_OT_collada_import";
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
ot->invoke = WM_operator_filesel;
ot->exec = wm_collada_import_exec;
diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c
index e94412233ff..d18f5de357f 100644
--- a/source/blender/editors/mesh/editmesh_bevel.c
+++ b/source/blender/editors/mesh/editmesh_bevel.c
@@ -121,7 +121,7 @@ enum {
BEV_MODAL_MARK_SHARP_TOGGLE,
BEV_MODAL_OUTER_MITER_CHANGE,
BEV_MODAL_INNER_MITER_CHANGE,
- BEV_MODAL_CUSTOM_PROFILE_TOGGLE,
+ BEV_MODAL_PROFILE_TYPE_CHANGE,
BEV_MODAL_VERTEX_MESH_CHANGE,
};
@@ -146,7 +146,7 @@ static void edbm_bevel_update_status_text(bContext *C, wmOperator *op)
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;
+ const char *mode_str, *omiter_str, *imiter_str, *vmesh_str, *profile_type_str;
PropertyRNA *prop;
#define WM_MODALKEY(_id) \
@@ -170,6 +170,9 @@ static void edbm_bevel_update_status_text(bContext *C, wmOperator *op)
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);
+ prop = RNA_struct_find_property(op->ptr, "profile_type");
+ RNA_property_enum_name_gettexted(
+ C, op->ptr, prop, RNA_property_enum_get(op->ptr, prop), &profile_type_str);
prop = RNA_struct_find_property(op->ptr, "miter_outer");
RNA_property_enum_name_gettexted(
C, op->ptr, prop, RNA_property_enum_get(op->ptr, prop), &omiter_str);
@@ -195,7 +198,7 @@ static void edbm_bevel_update_status_text(bContext *C, wmOperator *op)
"%s: Harden Normals (%s), "
"%s: Mark Seam (%s), "
"%s: Mark Sharp (%s), "
- "%s: Custom Profile (%s), "
+ "%s: Profile Type (%s), "
"%s: Intersection (%s)"),
WM_MODALKEY(BEV_MODAL_CONFIRM),
WM_MODALKEY(BEV_MODAL_CANCEL),
@@ -221,8 +224,8 @@ static void edbm_bevel_update_status_text(bContext *C, wmOperator *op)
WM_bool_as_string(RNA_boolean_get(op->ptr, "mark_seam")),
WM_MODALKEY(BEV_MODAL_MARK_SHARP_TOGGLE),
WM_bool_as_string(RNA_boolean_get(op->ptr, "mark_sharp")),
- WM_MODALKEY(BEV_MODAL_CUSTOM_PROFILE_TOGGLE),
- WM_bool_as_string(RNA_boolean_get(op->ptr, "use_custom_profile")),
+ WM_MODALKEY(BEV_MODAL_PROFILE_TYPE_CHANGE),
+ profile_type_str,
WM_MODALKEY(BEV_MODAL_VERTEX_MESH_CHANGE),
vmesh_str);
@@ -327,6 +330,7 @@ static bool edbm_bevel_calc(wmOperator *op)
const float offset = get_bevel_offset(op);
const int offset_type = RNA_enum_get(op->ptr, "offset_type");
+ const int profile_type = RNA_enum_get(op->ptr, "profile_type");
const int segments = RNA_int_get(op->ptr, "segments");
const float profile = RNA_float_get(op->ptr, "profile");
const bool vertex_only = RNA_boolean_get(op->ptr, "vertex_only");
@@ -340,7 +344,6 @@ static bool edbm_bevel_calc(wmOperator *op)
const int miter_outer = RNA_enum_get(op->ptr, "miter_outer");
const int miter_inner = RNA_enum_get(op->ptr, "miter_inner");
const float spread = RNA_float_get(op->ptr, "spread");
- const bool use_custom_profile = RNA_boolean_get(op->ptr, "use_custom_profile");
const int vmesh_method = RNA_enum_get(op->ptr, "vmesh_method");
for (uint ob_index = 0; ob_index < opdata->ob_store_len; ob_index++) {
@@ -364,16 +367,17 @@ static bool edbm_bevel_calc(wmOperator *op)
EDBM_op_init(em,
&bmop,
op,
- "bevel geom=%hev offset=%f segments=%i vertex_only=%b offset_type=%i profile=%f "
- "clamp_overlap=%b material=%i loop_slide=%b mark_seam=%b mark_sharp=%b "
- "harden_normals=%b face_strength_mode=%i "
- "miter_outer=%i miter_inner=%i spread=%f smoothresh=%f use_custom_profile=%b "
- "custom_profile=%p vmesh_method=%i",
+ "bevel geom=%hev offset=%f segments=%i vertex_only=%b offset_type=%i "
+ "profile_type=%i profile=%f clamp_overlap=%b material=%i loop_slide=%b "
+ "mark_seam=%b mark_sharp=%b harden_normals=%b face_strength_mode=%i "
+ "miter_outer=%i miter_inner=%i spread=%f smoothresh=%f custom_profile=%p "
+ "vmesh_method=%i",
BM_ELEM_SELECT,
offset,
segments,
vertex_only,
offset_type,
+ profile_type,
profile,
clamp_overlap,
material,
@@ -386,7 +390,6 @@ static bool edbm_bevel_calc(wmOperator *op)
miter_inner,
spread,
me->smoothresh,
- use_custom_profile,
opdata->custom_profile,
vmesh_method);
@@ -681,7 +684,7 @@ wmKeyMap *bevel_modal_keymap(wmKeyConfig *keyconf)
0,
"Change inner miter",
"Cycle through inner miter kinds"},
- {BEV_MODAL_CUSTOM_PROFILE_TOGGLE, "CUSTOM_PROFILE_TOGGLE", 0, "Toggle custom profile", ""},
+ {BEV_MODAL_PROFILE_TYPE_CHANGE, "PROFILE_TYPE_CHANGE", 0, "Cycle through profile types", ""},
{BEV_MODAL_VERTEX_MESH_CHANGE,
"VERTEX_MESH_CHANGE",
0,
@@ -892,9 +895,13 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event)
break;
}
- case BEV_MODAL_CUSTOM_PROFILE_TOGGLE: {
- bool use_custom_profile = RNA_boolean_get(op->ptr, "use_custom_profile");
- RNA_boolean_set(op->ptr, "use_custom_profile", !use_custom_profile);
+ case BEV_MODAL_PROFILE_TYPE_CHANGE: {
+ int profile_type = RNA_enum_get(op->ptr, "profile_type");
+ profile_type++;
+ if (profile_type > BEVEL_PROFILE_CUSTOM) {
+ profile_type = BEVEL_PROFILE_SUPERELLIPSE;
+ }
+ RNA_enum_set(op->ptr, "profile_type", profile_type);
edbm_bevel_calc(op);
edbm_bevel_update_status_text(C, op);
handled = true;
@@ -938,21 +945,12 @@ static void edbm_bevel_ui(bContext *C, wmOperator *op)
RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
+ int profile_type = RNA_enum_get(&ptr, "profile_type");
+
if (RNA_enum_get(&ptr, "offset_type") == BEVEL_AMT_PERCENT) {
uiItemR(layout, &ptr, "offset_pct", 0, NULL, ICON_NONE);
}
else {
- switch (RNA_enum_get(&ptr, "offset_type")) {
- case BEVEL_AMT_DEPTH:
- offset_name = "Depth";
- break;
- case BEVEL_AMT_WIDTH:
- offset_name = "Width";
- break;
- case BEVEL_AMT_OFFSET:
- offset_name = "Offset";
- break;
- }
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), &offset_name);
@@ -972,7 +970,14 @@ static void edbm_bevel_ui(bContext *C, wmOperator *op)
uiItemR(col, &ptr, "harden_normals", 0, NULL, ICON_NONE);
uiItemR(layout, &ptr, "segments", 0, NULL, ICON_NONE);
- uiItemR(layout, &ptr, "profile", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ if (ELEM(profile_type, BEVEL_PROFILE_SUPERELLIPSE, BEVEL_PROFILE_CUSTOM)) {
+ uiItemR(layout,
+ &ptr,
+ "profile",
+ UI_ITEM_R_SLIDER,
+ (profile_type == BEVEL_PROFILE_SUPERELLIPSE) ? IFACE_("Shape") : IFACE_("Miter Shape"),
+ ICON_NONE);
+ }
uiItemR(layout, &ptr, "material", 0, NULL, ICON_NONE);
uiItemL(layout, "Miter Type:", ICON_NONE);
@@ -990,9 +995,11 @@ static void edbm_bevel_ui(bContext *C, wmOperator *op)
row = uiLayoutRow(layout, true);
uiItemR(row, &ptr, "vmesh_method", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
- uiItemR(layout, &ptr, "use_custom_profile", 0, NULL, ICON_NONE);
- if (RNA_boolean_get(&ptr, "use_custom_profile")) {
- /* Get an RNA pointer to ToolSettings to give to the curve profile template code */
+ uiItemL(layout, "Profile Type:", ICON_NONE);
+ row = uiLayoutRow(layout, true);
+ uiItemR(row, &ptr, "profile_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ if (profile_type == BEVEL_PROFILE_CUSTOM) {
+ /* Get an RNA pointer to ToolSettings to give to the curve profile template code. */
Scene *scene = CTX_data_scene(C);
RNA_pointer_create(&scene->id, &RNA_ToolSettings, scene->toolsettings, &toolsettings_ptr);
uiTemplateCurveProfile(layout, &toolsettings_ptr, "custom_bevel_profile_preset");
@@ -1012,6 +1019,25 @@ void MESH_OT_bevel(wmOperatorType *ot)
"Depth",
"Amount is perpendicular distance from original edge to bevel face"},
{BEVEL_AMT_PERCENT, "PERCENT", 0, "Percent", "Amount is percent of adjacent edge length"},
+ {BEVEL_AMT_ABSOLUTE,
+ "ABSOLUTE",
+ 0,
+ "Absolute",
+ "Amount is absolute distance along adjacent edge"},
+ {0, NULL, 0, NULL, NULL},
+ };
+
+ static const EnumPropertyItem prop_profile_type_items[] = {
+ {BEVEL_PROFILE_SUPERELLIPSE,
+ "SUPERELLIPSE",
+ 0,
+ "Superellipse",
+ "The profile can be a concave or convex curve"},
+ {BEVEL_PROFILE_CUSTOM,
+ "CUSTOM",
+ 0,
+ "Custom",
+ "The profile can be any arbitrary path between its endpoints"},
{0, NULL, 0, NULL, NULL},
};
@@ -1068,13 +1094,24 @@ void MESH_OT_bevel(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_GRAB_CURSOR_XY | OPTYPE_BLOCKING;
/* properties */
- RNA_def_enum(
- ot->srna, "offset_type", offset_type_items, 0, "Width Type", "What distance Width measures");
+ RNA_def_enum(ot->srna,
+ "offset_type",
+ offset_type_items,
+ 0,
+ "Width Type",
+ "The method for determining the size of the bevel");
prop = RNA_def_property(ot->srna, "offset", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_range(prop, 0.0, 1e6);
RNA_def_property_ui_range(prop, 0.0, 100.0, 1, 3);
RNA_def_property_ui_text(prop, "Width", "Bevel amount");
+ RNA_def_enum(ot->srna,
+ "profile_type",
+ prop_profile_type_items,
+ 0,
+ "Profile Type",
+ "The type of shape used to rebuild a beveled section");
+
prop = RNA_def_property(ot->srna, "offset_pct", PROP_FLOAT, PROP_PERCENTAGE);
RNA_def_property_range(prop, 0.0, 100);
RNA_def_property_ui_text(prop, "Width Percent", "Bevel amount for percentage method");
@@ -1161,12 +1198,6 @@ void MESH_OT_bevel(wmOperatorType *ot)
0.0f,
100.0f);
- RNA_def_boolean(ot->srna,
- "use_custom_profile",
- false,
- "Custom Profile",
- "Use a custom profile for the bevel");
-
RNA_def_enum(ot->srna,
"vmesh_method",
vmesh_method_items,
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index 5f5599b53df..369c7735d20 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -1895,12 +1895,12 @@ static BMFace *knife_find_closest_face(KnifeTool_OpData *kcd,
if (!f) {
if (kcd->is_interactive) {
- /* try to use backbuffer selection method if ray casting failed */
+ /* Try to use back-buffer selection method if ray casting failed. */
f = EDBM_face_find_nearest(&kcd->vc, &dist);
/* cheat for now; just put in the origin instead
* of a true coordinate on the face.
- * This just puts a point 1.0f infront of the view. */
+ * This just puts a point 1.0f in front of the view. */
add_v3_v3v3(co, origin, ray);
}
}
@@ -1908,8 +1908,10 @@ static BMFace *knife_find_closest_face(KnifeTool_OpData *kcd,
return f;
}
-/* find the 2d screen space density of vertices within a radius. used to scale snapping
- * distance for picking edges/verts.*/
+/**
+ * Find the 2d screen space density of vertices within a radius.
+ * Used to scale snapping distance for picking edges/verts.
+ */
static int knife_sample_screen_density(KnifeTool_OpData *kcd, const float radius)
{
BMFace *f;
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index a0a3d24e49a..2cffb3ecdec 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -4161,7 +4161,7 @@ static Base *mesh_separate_tagged(
CustomData_bmesh_init_pool(&bm_new->pdata, bm_mesh_allocsize_default.totface, BM_FACE);
/* Take into account user preferences for duplicating actions. */
- short dupflag = USER_DUP_MESH | (U.dupflag & USER_DUP_ACT);
+ const eDupli_ID_Flags dupflag = USER_DUP_MESH | (U.dupflag & USER_DUP_ACT);
base_new = ED_object_add_duplicate(bmain, scene, view_layer, base_old, dupflag);
/* normally would call directly after but in this case delay recalc */
@@ -4233,7 +4233,7 @@ static Base *mesh_separate_arrays(Main *bmain,
CustomData_bmesh_init_pool(&bm_new->pdata, faces_len, BM_FACE);
/* Take into account user preferences for duplicating actions. */
- short dupflag = USER_DUP_MESH | (U.dupflag & USER_DUP_ACT);
+ const eDupli_ID_Flags dupflag = USER_DUP_MESH | (U.dupflag & USER_DUP_ACT);
base_new = ED_object_add_duplicate(bmain, scene, view_layer, base_old, dupflag);
/* normally would call directly after but in this case delay recalc */
@@ -7240,8 +7240,11 @@ void MESH_OT_wireframe(wmOperatorType *ot)
/* use 1 rather then 10 for max else dragging the button moves too far */
RNA_def_property_ui_range(prop, 0.0, 1.0, 0.01, 4);
RNA_def_float_distance(ot->srna, "offset", 0.01f, 0.0f, 1e4f, "Offset", "", 0.0f, 10.0f);
- RNA_def_boolean(
- ot->srna, "use_crease", false, "Crease", "Crease hub edges for an improved subdivision surface");
+ RNA_def_boolean(ot->srna,
+ "use_crease",
+ false,
+ "Crease",
+ "Crease hub edges for an improved subdivision surface");
prop = RNA_def_float(
ot->srna, "crease_weight", 0.01f, 0.0f, 1e3f, "Crease weight", "", 0.0f, 1.0f);
RNA_def_property_ui_range(prop, 0.0, 1.0, 0.1, 2);
diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c
index 51b699acd63..8fce726eff5 100644
--- a/source/blender/editors/mesh/mesh_data.c
+++ b/source/blender/editors/mesh/mesh_data.c
@@ -121,8 +121,15 @@ static void delete_customdata_layer(Mesh *me, CustomDataLayer *layer)
CustomData *data;
int layer_index, tot, n;
- data = mesh_customdata_get_type(
- me, (ELEM(type, CD_MLOOPUV, CD_MLOOPCOL)) ? BM_LOOP : BM_FACE, &tot);
+ char htype = BM_FACE;
+ if (ELEM(type, CD_MLOOPCOL, CD_MLOOPUV)) {
+ htype = BM_LOOP;
+ }
+ else if (ELEM(type, CD_PROP_COLOR)) {
+ htype = BM_VERT;
+ }
+
+ data = mesh_customdata_get_type(me, htype, &tot);
layer_index = CustomData_get_layer_index(data, type);
n = (layer - &data->layers[layer_index]);
BLI_assert(n >= 0 && (n + layer_index) < data->totlayer);
@@ -488,6 +495,117 @@ bool ED_mesh_color_remove_named(Mesh *me, const char *name)
}
}
+/*********************** Sculpt Vertex colors operators ************************/
+
+/* note: keep in sync with ED_mesh_uv_texture_add */
+int ED_mesh_sculpt_color_add(Mesh *me, const char *name, const bool active_set, const bool do_init)
+{
+ BMEditMesh *em;
+ int layernum;
+
+ if (me->edit_mesh) {
+ em = me->edit_mesh;
+
+ layernum = CustomData_number_of_layers(&em->bm->vdata, CD_PROP_COLOR);
+ if (layernum >= MAX_MCOL) {
+ return -1;
+ }
+
+ /* CD_PROP_COLOR */
+ BM_data_layer_add_named(em->bm, &em->bm->vdata, CD_PROP_COLOR, name);
+ /* copy data from active vertex color layer */
+ if (layernum && do_init) {
+ const int layernum_dst = CustomData_get_active_layer(&em->bm->vdata, CD_PROP_COLOR);
+ BM_data_layer_copy(em->bm, &em->bm->vdata, CD_PROP_COLOR, layernum_dst, layernum);
+ }
+ if (active_set || layernum == 0) {
+ CustomData_set_layer_active(&em->bm->vdata, CD_PROP_COLOR, layernum);
+ }
+ }
+ else {
+ layernum = CustomData_number_of_layers(&me->vdata, CD_PROP_COLOR);
+ if (layernum >= MAX_MCOL) {
+ return -1;
+ }
+
+ if (CustomData_has_layer(&me->vdata, CD_PROP_COLOR) && do_init) {
+ MPropCol *color_data = CustomData_get_layer(&me->vdata, CD_PROP_COLOR);
+ CustomData_add_layer_named(
+ &me->vdata, CD_PROP_COLOR, CD_DUPLICATE, color_data, me->totvert, name);
+ }
+ else {
+ CustomData_add_layer_named(&me->vdata, CD_PROP_COLOR, CD_DEFAULT, NULL, me->totvert, name);
+ }
+
+ if (active_set || layernum == 0) {
+ CustomData_set_layer_active(&me->vdata, CD_PROP_COLOR, layernum);
+ }
+
+ BKE_mesh_update_customdata_pointers(me, true);
+ }
+
+ DEG_id_tag_update(&me->id, 0);
+ WM_main_add_notifier(NC_GEOM | ND_DATA, me);
+
+ return layernum;
+}
+
+bool ED_mesh_sculpt_color_ensure(struct Mesh *me, const char *name)
+{
+ BLI_assert(me->edit_mesh == NULL);
+
+ if (me->totvert && !CustomData_has_layer(&me->vdata, CD_PROP_COLOR)) {
+ CustomData_add_layer_named(&me->vdata, CD_PROP_COLOR, CD_DEFAULT, NULL, me->totvert, name);
+ BKE_mesh_update_customdata_pointers(me, true);
+ }
+
+ DEG_id_tag_update(&me->id, 0);
+
+ return (me->mloopcol != NULL);
+}
+
+bool ED_mesh_sculpt_color_remove_index(Mesh *me, const int n)
+{
+ CustomData *vdata = GET_CD_DATA(me, vdata);
+ CustomDataLayer *cdl;
+ int index;
+
+ index = CustomData_get_layer_index_n(vdata, CD_PROP_COLOR, n);
+ cdl = (index == -1) ? NULL : &vdata->layers[index];
+
+ if (!cdl) {
+ return false;
+ }
+
+ delete_customdata_layer(me, cdl);
+ DEG_id_tag_update(&me->id, 0);
+ WM_main_add_notifier(NC_GEOM | ND_DATA, me);
+
+ return true;
+}
+bool ED_mesh_sculpt_color_remove_active(Mesh *me)
+{
+ CustomData *vdata = GET_CD_DATA(me, vdata);
+ const int n = CustomData_get_active_layer(vdata, CD_PROP_COLOR);
+ if (n != -1) {
+ return ED_mesh_sculpt_color_remove_index(me, n);
+ }
+ else {
+ return false;
+ }
+}
+bool ED_mesh_sculpt_color_remove_named(Mesh *me, const char *name)
+{
+ CustomData *vdata = GET_CD_DATA(me, vdata);
+ const int n = CustomData_get_named_layer(vdata, CD_PROP_COLOR, name);
+ if (n != -1) {
+ return ED_mesh_sculpt_color_remove_index(me, n);
+ }
+ else {
+ return false;
+ }
+}
+
/*********************** UV texture operators ************************/
static bool layers_poll(bContext *C)
@@ -619,6 +737,62 @@ void MESH_OT_vertex_color_remove(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+/*********************** Sculpt Vertex Color Operators ************************/
+
+static int mesh_sculpt_vertex_color_add_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Object *ob = ED_object_context(C);
+ Mesh *me = ob->data;
+
+ if (ED_mesh_sculpt_color_add(me, NULL, true, true) == -1) {
+ return OPERATOR_CANCELLED;
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+void MESH_OT_sculpt_vertex_color_add(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Add Sculpt Vertex Color";
+ ot->description = "Add vertex color layer";
+ ot->idname = "MESH_OT_sculpt_vertex_color_add";
+
+ /* api callbacks */
+ ot->poll = layers_poll;
+ ot->exec = mesh_sculpt_vertex_color_add_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+static int mesh_sculpt_vertex_color_remove_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Object *ob = ED_object_context(C);
+ Mesh *me = ob->data;
+
+ if (!ED_mesh_sculpt_color_remove_active(me)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+void MESH_OT_sculpt_vertex_color_remove(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Remove Sculpt Vertex Color";
+ ot->description = "Remove vertex color layer";
+ ot->idname = "MESH_OT_sculpt_vertex_color_remove";
+
+ /* api callbacks */
+ ot->exec = mesh_sculpt_vertex_color_remove_exec;
+ ot->poll = layers_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
/* *** CustomData clear functions, we need an operator for each *** */
static int mesh_customdata_clear_exec__internal(bContext *C, char htype, int type)
diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h
index 5e70069456b..bebad312454 100644
--- a/source/blender/editors/mesh/mesh_intern.h
+++ b/source/blender/editors/mesh/mesh_intern.h
@@ -267,6 +267,8 @@ void MESH_OT_uv_texture_add(struct wmOperatorType *ot);
void MESH_OT_uv_texture_remove(struct wmOperatorType *ot);
void MESH_OT_vertex_color_add(struct wmOperatorType *ot);
void MESH_OT_vertex_color_remove(struct wmOperatorType *ot);
+void MESH_OT_sculpt_vertex_color_add(struct wmOperatorType *ot);
+void MESH_OT_sculpt_vertex_color_remove(struct wmOperatorType *ot);
/* no create_mask yet */
void MESH_OT_customdata_mask_clear(struct wmOperatorType *ot);
void MESH_OT_customdata_skin_add(struct wmOperatorType *ot);
diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c
index c52a5956ac4..ad1e91a57c0 100644
--- a/source/blender/editors/mesh/mesh_ops.c
+++ b/source/blender/editors/mesh/mesh_ops.c
@@ -155,6 +155,8 @@ void ED_operatortypes_mesh(void)
WM_operatortype_append(MESH_OT_uv_texture_remove);
WM_operatortype_append(MESH_OT_vertex_color_add);
WM_operatortype_append(MESH_OT_vertex_color_remove);
+ WM_operatortype_append(MESH_OT_sculpt_vertex_color_add);
+ WM_operatortype_append(MESH_OT_sculpt_vertex_color_remove);
WM_operatortype_append(MESH_OT_customdata_mask_clear);
WM_operatortype_append(MESH_OT_customdata_skin_add);
WM_operatortype_append(MESH_OT_customdata_skin_clear);
@@ -278,8 +280,8 @@ void ED_operatormacros_mesh(void)
RNA_boolean_set(otmacro->ptr, "mirror", false);
ot = WM_operatortype_append_macro(
- "MESH_OT_extrude_region_dissolve_move_intersect",
- "Extrude, Dissolve, Move and Intersect",
+ "MESH_OT_extrude_manifold",
+ "Extrude Manifold",
"Extrude, dissolves edges whose faces form a flat surface and intersect new edges",
OPTYPE_UNDO | OPTYPE_REGISTER);
otmacro = WM_operatortype_macro_define(ot, "MESH_OT_extrude_region");
diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c
index 917bbe61e3d..1bdf2ede22a 100644
--- a/source/blender/editors/mesh/meshtools.c
+++ b/source/blender/editors/mesh/meshtools.c
@@ -297,7 +297,7 @@ static void join_mesh_single(Depsgraph *depsgraph,
*mpoly_pp += me->totpoly;
}
-int join_mesh_exec(bContext *C, wmOperator *op)
+int ED_mesh_join_objects_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
@@ -706,12 +706,14 @@ int join_mesh_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-/*********************** JOIN AS SHAPES ***************************/
+/* -------------------------------------------------------------------- */
+/** \name Join as Shapes
+ * \{ */
/* Append selected meshes vertex locations as shapes of the active mesh,
* return 0 if no join is made (error) and 1 of the join is done */
-int join_mesh_shapes_exec(bContext *C, wmOperator *op)
+int ED_mesh_shapes_join_objects_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
@@ -796,6 +798,8 @@ int join_mesh_shapes_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
+/** \} */
+
/* -------------------------------------------------------------------- */
/** \name Mesh Topology Mirror API
* \{ */
diff --git a/source/blender/editors/metaball/mball_edit.c b/source/blender/editors/metaball/mball_edit.c
index a25175510cd..094011ebef1 100644
--- a/source/blender/editors/metaball/mball_edit.c
+++ b/source/blender/editors/metaball/mball_edit.c
@@ -58,6 +58,10 @@
#include "mball_intern.h"
+/* -------------------------------------------------------------------- */
+/** \name Edit Mode Functions
+ * \{ */
+
/* This function is used to free all MetaElems from MetaBall */
void ED_mball_editmball_free(Object *obedit)
{
@@ -93,9 +97,36 @@ void ED_mball_editmball_load(Object *UNUSED(obedit))
{
}
-/* Add metaelem primitive to metaball object (which is in edit mode) */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Selection
+ * \{ */
+
+bool ED_mball_deselect_all_multi(bContext *C)
+{
+ Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+ ViewContext vc;
+ ED_view3d_viewcontext_init(C, &vc, depsgraph);
+ uint bases_len = 0;
+ Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(
+ vc.view_layer, vc.v3d, &bases_len);
+ bool changed_multi = BKE_mball_deselect_all_multi_ex(bases, bases_len);
+ MEM_freeN(bases);
+ return changed_multi;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Add Meta Primitive Utility
+ * \{ */
+
+/**
+ * Add meta-element primitive to meta-ball object (which is in edit mode).
+ */
MetaElem *ED_mball_add_primitive(
- bContext *UNUSED(C), Object *obedit, float mat[4][4], float dia, int type)
+ bContext *UNUSED(C), Object *obedit, bool obedit_is_new, float mat[4][4], float dia, int type)
{
MetaBall *mball = (MetaBall *)obedit->data;
MetaElem *ml;
@@ -109,16 +140,28 @@ MetaElem *ED_mball_add_primitive(
ml = BKE_mball_element_add(mball, type);
ml->rad *= dia;
- mball->wiresize *= dia;
- mball->rendersize *= dia;
+
+ if (obedit_is_new) {
+ mball->wiresize *= dia;
+ mball->rendersize *= dia;
+ }
copy_v3_v3(&ml->x, mat[3]);
+ /* MB_ELIPSOID works differently (intentional?). Whatever the case,
+ * on testing this needs to be skipped otherwise it doesn't behave like other types. */
+ if (type != MB_ELIPSOID) {
+ mul_v3_fl(&ml->expx, dia);
+ }
ml->flag |= SELECT;
mball->lastelem = ml;
return ml;
}
-/***************************** Select/Deselect operator *****************************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select/Deselect Operator
+ * \{ */
/* Select or deselect all MetaElements */
static int mball_select_all_exec(bContext *C, wmOperator *op)
@@ -175,8 +218,11 @@ void MBALL_OT_select_all(wmOperatorType *ot)
WM_operator_properties_select_all(ot);
}
+/** \} */
+
/* -------------------------------------------------------------------- */
-/* Select Similar */
+/** \name Select Similar Operator
+ * \{ */
enum {
SIMMBALL_TYPE = 1,
@@ -428,9 +474,12 @@ void MBALL_OT_select_similar(wmOperatorType *ot)
RNA_def_float(ot->srna, "threshold", 0.1, 0.0, FLT_MAX, "Threshold", "", 0.01, 1.0);
}
-/***************************** Select random operator *****************************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Random Operator
+ * \{ */
-/* Random metaball selection */
static int select_random_metaelems_exec(bContext *C, wmOperator *op)
{
const bool select = (RNA_enum_get(op->ptr, "action") == SEL_SELECT);
@@ -494,7 +543,11 @@ void MBALL_OT_select_random_metaelems(struct wmOperatorType *ot)
WM_operator_properties_select_random(ot);
}
-/***************************** Duplicate operator *****************************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Duplicate Meta-Ball Operator
+ * \{ */
/* Duplicate selected MetaElements */
static int duplicate_metaelems_exec(bContext *C, wmOperator *UNUSED(op))
@@ -546,9 +599,14 @@ void MBALL_OT_duplicate_metaelems(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/***************************** Delete operator *****************************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Delete Meta-Ball Operator
+ *
+ * Delete all selected MetaElems (not MetaBall).
+ * \{ */
-/* Delete all selected MetaElems (not MetaBall) */
static int delete_metaelems_exec(bContext *C, wmOperator *UNUSED(op))
{
ViewLayer *view_layer = CTX_data_view_layer(C);
@@ -601,9 +659,12 @@ void MBALL_OT_delete_metaelems(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/***************************** Hide operator *****************************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Hide Meta-Elements Operator
+ * \{ */
-/* Hide selected MetaElems */
static int hide_metaelems_exec(bContext *C, wmOperator *op)
{
Object *obedit = CTX_data_edit_object(C);
@@ -646,9 +707,12 @@ void MBALL_OT_hide_metaelems(wmOperatorType *ot)
ot->srna, "unselected", false, "Unselected", "Hide unselected rather than selected");
}
-/***************************** Unhide operator *****************************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Un-Hide Meta-Elements Operator
+ * \{ */
-/* Unhide all edited MetaElems */
static int reveal_metaelems_exec(bContext *C, wmOperator *op)
{
Object *obedit = CTX_data_edit_object(C);
@@ -689,6 +753,12 @@ void MBALL_OT_reveal_metaelems(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "select", true, "Select", "");
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Select Pick Utility
+ * \{ */
+
/* Select MetaElement with mouse click (user can select radius circle or
* stiffness circle) */
bool ED_mball_select_pick(bContext *C, const int mval[2], bool extend, bool deselect, bool toggle)
@@ -740,7 +810,7 @@ bool ED_mball_select_pick(bContext *C, const int mval[2], bool extend, bool dese
continue;
}
- if (metaelem_id != (hitresult & 0xFFFF0000 & ~(MBALLSEL_ANY))) {
+ if (metaelem_id != (hitresult & 0xFFFF0000 & ~MBALLSEL_ANY)) {
continue;
}
@@ -831,15 +901,4 @@ bool ED_mball_select_pick(bContext *C, const int mval[2], bool extend, bool dese
return false;
}
-bool ED_mball_deselect_all_multi(bContext *C)
-{
- Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
- ViewContext vc;
- ED_view3d_viewcontext_init(C, &vc, depsgraph);
- uint bases_len = 0;
- Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(
- vc.view_layer, vc.v3d, &bases_len);
- bool changed_multi = BKE_mball_deselect_all_multi_ex(bases, bases_len);
- MEM_freeN(bases);
- return changed_multi;
-}
+/** \} */
diff --git a/source/blender/editors/object/CMakeLists.txt b/source/blender/editors/object/CMakeLists.txt
index fb273cf49a8..953ef8114f9 100644
--- a/source/blender/editors/object/CMakeLists.txt
+++ b/source/blender/editors/object/CMakeLists.txt
@@ -91,8 +91,4 @@ if(WITH_INTERNATIONAL)
add_definitions(-DWITH_INTERNATIONAL)
endif()
-if(WITH_NEW_OBJECT_TYPES)
- add_definitions(-DWITH_NEW_OBJECT_TYPES)
-endif()
-
blender_add_lib(bf_editor_object "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 8289f52b0c8..8073d87080f 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -65,6 +65,7 @@
#include "BKE_effect.h"
#include "BKE_font.h"
#include "BKE_gpencil_curve.h"
+#include "BKE_gpencil_geom.h"
#include "BKE_hair.h"
#include "BKE_key.h"
#include "BKE_lattice.h"
@@ -96,6 +97,8 @@
#include "RNA_define.h"
#include "RNA_enum_types.h"
+#include "UI_interface.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -857,7 +860,7 @@ static int object_metaball_add_exec(bContext *C, wmOperator *op)
* we want to pass in 1 so other values such as resolution are scaled by 1.0. */
dia = RNA_float_get(op->ptr, "radius") / 2;
- ED_mball_add_primitive(C, obedit, mat, dia, RNA_enum_get(op->ptr, "type"));
+ ED_mball_add_primitive(C, obedit, newob, mat, dia, RNA_enum_get(op->ptr, "type"));
/* userdef */
if (newob && !enter_editmode) {
@@ -1508,6 +1511,14 @@ void OBJECT_OT_speaker_add(wmOperatorType *ot)
/** \name Add Hair Operator
* \{ */
+static bool object_hair_add_poll(bContext *C)
+{
+ if (!U.experimental.use_new_hair_type) {
+ return false;
+ }
+ return ED_operator_objectmode(C);
+}
+
static int object_hair_add_exec(bContext *C, wmOperator *op)
{
ushort local_view_bits;
@@ -1531,7 +1542,7 @@ void OBJECT_OT_hair_add(wmOperatorType *ot)
/* api callbacks */
ot->exec = object_hair_add_exec;
- ot->poll = ED_operator_objectmode;
+ ot->poll = object_hair_add_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -1545,6 +1556,14 @@ void OBJECT_OT_hair_add(wmOperatorType *ot)
/** \name Add Point Cloud Operator
* \{ */
+static bool object_pointcloud_add_poll(bContext *C)
+{
+ if (!U.experimental.use_new_particle_system) {
+ return false;
+ }
+ return ED_operator_objectmode(C);
+}
+
static int object_pointcloud_add_exec(bContext *C, wmOperator *op)
{
ushort local_view_bits;
@@ -1568,7 +1587,7 @@ void OBJECT_OT_pointcloud_add(wmOperatorType *ot)
/* api callbacks */
ot->exec = object_pointcloud_add_exec;
- ot->poll = ED_operator_objectmode;
+ ot->poll = object_pointcloud_add_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -2129,11 +2148,11 @@ void OBJECT_OT_duplicates_make_real(wmOperatorType *ot)
static const EnumPropertyItem convert_target_items[] = {
{OB_CURVE, "CURVE", ICON_OUTLINER_OB_CURVE, "Curve from Mesh/Text", ""},
{OB_MESH, "MESH", ICON_OUTLINER_OB_MESH, "Mesh from Curve/Meta/Surf/Text", ""},
- {OB_GPENCIL, "GPENCIL", ICON_OUTLINER_OB_GREASEPENCIL, "Grease Pencil from Curve", ""},
+ {OB_GPENCIL, "GPENCIL", ICON_OUTLINER_OB_GREASEPENCIL, "Grease Pencil from Curve/Mesh", ""},
{0, NULL, 0, NULL, NULL},
};
-static void convert_ensure_curve_cache(Depsgraph *depsgraph, Scene *scene, Object *ob)
+static void object_data_convert_ensure_curve_cache(Depsgraph *depsgraph, Scene *scene, Object *ob)
{
if (ob->runtime.curve_cache == NULL) {
/* Force creation. This is normally not needed but on operator
@@ -2152,7 +2171,7 @@ static void convert_ensure_curve_cache(Depsgraph *depsgraph, Scene *scene, Objec
}
}
-static void curvetomesh(Main *bmain, Depsgraph *depsgraph, Object *ob)
+static void object_data_convert_curve_to_mesh(Main *bmain, Depsgraph *depsgraph, Object *ob)
{
Object *object_eval = DEG_get_evaluated_object(depsgraph, ob);
Curve *curve = ob->data;
@@ -2185,17 +2204,22 @@ static void curvetomesh(Main *bmain, Depsgraph *depsgraph, Object *ob)
}
}
-static bool convert_poll(bContext *C)
+static bool object_convert_poll(bContext *C)
{
Scene *scene = CTX_data_scene(C);
Base *base_act = CTX_data_active_base(C);
Object *obact = base_act ? base_act->object : NULL;
- return (!ID_IS_LINKED(scene) && obact && (BKE_object_is_in_editmode(obact) == false) &&
- (base_act->flag & BASE_SELECTED) && !ID_IS_LINKED(obact));
+ if (obact == NULL || obact->data == NULL || ID_IS_LINKED(obact) ||
+ ID_IS_OVERRIDE_LIBRARY(obact) || ID_IS_OVERRIDE_LIBRARY(obact->data)) {
+ return false;
+ }
+
+ return (!ID_IS_LINKED(scene) && (BKE_object_is_in_editmode(obact) == false) &&
+ (base_act->flag & BASE_SELECTED));
}
-/* Helper for convert_exec */
+/* Helper for object_convert_exec */
static Base *duplibase_for_convert(
Main *bmain, Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, Base *base, Object *ob)
{
@@ -2230,7 +2254,7 @@ static Base *duplibase_for_convert(
* time we need to duplicate an object to convert it. Even worse, this is not 100% correct, since
* we do not yet have duplicated obdata.
* However, that is a safe solution for now. Proper, longer-term solution is to refactor
- * convert_exec to:
+ * object_convert_exec to:
* - duplicate all data it needs to in a first loop.
* - do a single update.
* - convert data in a second loop. */
@@ -2248,7 +2272,7 @@ static Base *duplibase_for_convert(
return basen;
}
-static int convert_exec(bContext *C, wmOperator *op)
+static int object_convert_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
@@ -2261,9 +2285,16 @@ static int convert_exec(bContext *C, wmOperator *op)
Nurb *nu;
MetaBall *mb;
Mesh *me;
- Object *gpencil_ob = NULL;
+ Object *ob_gpencil = NULL;
const short target = RNA_enum_get(op->ptr, "target");
bool keep_original = RNA_boolean_get(op->ptr, "keep_original");
+
+ const float angle = RNA_float_get(op->ptr, "angle");
+ 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 float offset = RNA_float_get(op->ptr, "offset");
+
int a, mballConverted = 0;
bool gpencilConverted = false;
@@ -2375,6 +2406,54 @@ static int convert_exec(bContext *C, wmOperator *op)
ED_rigidbody_object_remove(bmain, scene, newob);
}
}
+ else if (ob->type == OB_MESH && target == OB_GPENCIL) {
+ ob->flag |= OB_DONE;
+
+ /* Create a new grease pencil object and copy transformations. */
+ ushort local_view_bits = (v3d && v3d->localvd) ? v3d->local_view_uuid : 0;
+ float loc[3], size[3], rot[3][3], eul[3];
+ float matrix[4][4];
+ mat4_to_loc_rot_size(loc, rot, size, ob->obmat);
+ mat3_to_eul(eul, rot);
+
+ ob_gpencil = ED_gpencil_add_object(C, loc, local_view_bits);
+ copy_v3_v3(ob_gpencil->loc, loc);
+ copy_v3_v3(ob_gpencil->rot, eul);
+ copy_v3_v3(ob_gpencil->scale, size);
+ unit_m4(matrix);
+ /* Set object in 3D mode. */
+ bGPdata *gpd = (bGPdata *)ob_gpencil->data;
+ gpd->draw_mode = GP_DRAWMODE_3D;
+
+ BKE_gpencil_convert_mesh(bmain,
+ depsgraph,
+ scene,
+ ob_gpencil,
+ ob,
+ angle,
+ thickness,
+ offset,
+ matrix,
+ 0,
+ use_seams,
+ use_faces);
+ gpencilConverted = true;
+
+ /* Remove unused materials. */
+ int actcol = ob_gpencil->actcol;
+ for (int slot = 1; slot <= ob_gpencil->totcol; slot++) {
+ while (slot <= ob_gpencil->totcol &&
+ !BKE_object_material_slot_used(ob_gpencil->data, slot)) {
+ ob_gpencil->actcol = slot;
+ BKE_object_material_slot_remove(CTX_data_main(C), ob_gpencil);
+
+ if (actcol >= slot) {
+ actcol--;
+ }
+ }
+ }
+ ob_gpencil->actcol = actcol;
+ }
else if (ob->type == OB_MESH) {
ob->flag |= OB_DONE;
@@ -2470,7 +2549,7 @@ static int convert_exec(bContext *C, wmOperator *op)
if (target == OB_MESH) {
/* No assumption should be made that the resulting objects is a mesh, as conversion can
* fail. */
- curvetomesh(bmain, depsgraph, newob);
+ object_data_convert_curve_to_mesh(bmain, depsgraph, newob);
/* meshes doesn't use displist */
BKE_object_free_curve_cache(newob);
}
@@ -2495,7 +2574,7 @@ static int convert_exec(bContext *C, wmOperator *op)
/* No assumption should be made that the resulting objects is a mesh, as conversion can
* fail. */
- curvetomesh(bmain, depsgraph, newob);
+ object_data_convert_curve_to_mesh(bmain, depsgraph, newob);
/* meshes doesn't use displist */
BKE_object_free_curve_cache(newob);
}
@@ -2509,10 +2588,10 @@ static int convert_exec(bContext *C, wmOperator *op)
* Nurbs Surface are not supported.
*/
ushort local_view_bits = (v3d && v3d->localvd) ? v3d->local_view_uuid : 0;
- gpencil_ob = ED_gpencil_add_object(C, ob->loc, local_view_bits);
- copy_v3_v3(gpencil_ob->rot, ob->rot);
- copy_v3_v3(gpencil_ob->scale, ob->scale);
- BKE_gpencil_convert_curve(bmain, scene, gpencil_ob, ob, false, false, true);
+ ob_gpencil = ED_gpencil_add_object(C, ob->loc, local_view_bits);
+ copy_v3_v3(ob_gpencil->rot, ob->rot);
+ copy_v3_v3(ob_gpencil->scale, ob->scale);
+ BKE_gpencil_convert_curve(bmain, scene, ob_gpencil, ob, false, false, true);
gpencilConverted = true;
}
}
@@ -2549,7 +2628,7 @@ static int convert_exec(bContext *C, wmOperator *op)
}
}
- convert_ensure_curve_cache(depsgraph, scene, baseob);
+ object_data_convert_ensure_curve_cache(depsgraph, scene, baseob);
BKE_mesh_from_metaball(&baseob->runtime.curve_cache->disp, newob->data);
if (obact->type == OB_MBALL) {
@@ -2618,12 +2697,12 @@ static int convert_exec(bContext *C, wmOperator *op)
}
FOREACH_SCENE_OBJECT_END;
}
- /* Remove curves converted to Grease Pencil object. */
+ /* Remove curves and meshes converted to Grease Pencil object. */
if (gpencilConverted) {
- FOREACH_SCENE_OBJECT_BEGIN (scene, ob_curve) {
- if (ob_curve->type == OB_CURVE) {
- if (ob_curve->flag & OB_DONE) {
- ED_object_base_free_and_unlink(bmain, scene, ob_curve);
+ FOREACH_SCENE_OBJECT_BEGIN (scene, ob_delete) {
+ if ((ob_delete->type == OB_CURVE) || (ob_delete->type == OB_MESH)) {
+ if (ob_delete->flag & OB_DONE) {
+ ED_object_base_free_and_unlink(bmain, scene, ob_delete);
}
}
}
@@ -2652,8 +2731,28 @@ static int convert_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
+static void object_convert_ui(bContext *UNUSED(C), wmOperator *op)
+{
+ uiLayout *layout = op->layout;
+ PointerRNA ptr;
+
+ RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
+ uiItemR(layout, &ptr, "target", 0, NULL, ICON_NONE);
+ uiItemR(layout, &ptr, "keep_original", 0, NULL, ICON_NONE);
+
+ if (RNA_enum_get(&ptr, "target") == OB_GPENCIL) {
+ uiItemR(layout, &ptr, "thickness", 0, NULL, ICON_NONE);
+ uiItemR(layout, &ptr, "angle", 0, NULL, ICON_NONE);
+ uiItemR(layout, &ptr, "offset", 0, NULL, ICON_NONE);
+ uiItemR(layout, &ptr, "seams", 0, NULL, ICON_NONE);
+ uiItemR(layout, &ptr, "faces", 0, NULL, ICON_NONE);
+ }
+}
+
void OBJECT_OT_convert(wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name = "Convert to";
ot->description = "Convert selected objects to another type";
@@ -2661,8 +2760,9 @@ void OBJECT_OT_convert(wmOperatorType *ot)
/* api callbacks */
ot->invoke = WM_menu_invoke;
- ot->exec = convert_exec;
- ot->poll = convert_poll;
+ ot->exec = object_convert_exec;
+ ot->poll = object_convert_poll;
+ ot->ui = object_convert_ui;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -2675,6 +2775,31 @@ void OBJECT_OT_convert(wmOperatorType *ot)
0,
"Keep Original",
"Keep original objects instead of replacing them");
+
+ prop = RNA_def_float_rotation(ot->srna,
+ "angle",
+ 0,
+ NULL,
+ DEG2RADF(0.0f),
+ DEG2RADF(180.0f),
+ "Threshold Angle",
+ "Threshold to determine ends of the strokes",
+ DEG2RADF(0.0f),
+ DEG2RADF(180.0f));
+ RNA_def_property_float_default(prop, DEG2RADF(70.0f));
+
+ RNA_def_int(ot->srna, "thickness", 5, 1, 100, "Thickness", "", 1, 100);
+ 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.01f,
+ 0.0,
+ OBJECT_ADD_SIZE_MAXF,
+ "Stroke Offset",
+ "Offset strokes from fill",
+ 0.0,
+ 100.00);
}
/** \} */
@@ -2693,8 +2818,12 @@ void OBJECT_OT_convert(wmOperatorType *ot)
/* used below, assumes id.new is correct */
/* leaves selection of base/object unaltered */
/* Does set ID->newid pointers. */
-static Base *object_add_duplicate_internal(
- Main *bmain, Scene *scene, ViewLayer *view_layer, Object *ob, int dupflag)
+static Base *object_add_duplicate_internal(Main *bmain,
+ Scene *scene,
+ ViewLayer *view_layer,
+ Object *ob,
+ const eDupli_ID_Flags dupflag,
+ const eLibIDDuplicateFlags duplicate_options)
{
Base *base, *basen = NULL;
Object *obn;
@@ -2703,7 +2832,7 @@ static Base *object_add_duplicate_internal(
/* nothing? */
}
else {
- obn = ID_NEW_SET(ob, BKE_object_duplicate(bmain, ob, dupflag));
+ obn = ID_NEW_SET(ob, BKE_object_duplicate(bmain, ob, dupflag, duplicate_options));
DEG_id_tag_update(&obn->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
base = BKE_view_layer_base_find(view_layer, ob);
@@ -2742,12 +2871,13 @@ static Base *object_add_duplicate_internal(
* note: caller must do DAG_relations_tag_update(bmain);
* this is not done automatic since we may duplicate many objects in a batch */
Base *ED_object_add_duplicate(
- Main *bmain, Scene *scene, ViewLayer *view_layer, Base *base, int dupflag)
+ Main *bmain, Scene *scene, ViewLayer *view_layer, Base *base, const eDupli_ID_Flags dupflag)
{
Base *basen;
Object *ob;
- basen = object_add_duplicate_internal(bmain, scene, view_layer, base->object, dupflag);
+ basen = object_add_duplicate_internal(
+ bmain, scene, view_layer, base->object, dupflag, LIB_ID_DUPLICATE_IS_SUBPROCESS);
if (basen == NULL) {
return NULL;
}
@@ -2775,10 +2905,11 @@ static int duplicate_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
const bool linked = RNA_boolean_get(op->ptr, "linked");
- int dupflag = (linked) ? 0 : U.dupflag;
+ const eDupli_ID_Flags dupflag = (linked) ? 0 : (eDupli_ID_Flags)U.dupflag;
CTX_DATA_BEGIN (C, Base *, base, selected_bases) {
- Base *basen = object_add_duplicate_internal(bmain, scene, view_layer, base->object, dupflag);
+ Base *basen = object_add_duplicate_internal(
+ bmain, scene, view_layer, base->object, dupflag, 0);
/* note that this is safe to do with this context iterator,
* the list is made in advance */
@@ -2849,7 +2980,7 @@ void OBJECT_OT_duplicate(wmOperatorType *ot)
* Use for drag & drop.
* \{ */
-static int add_named_exec(bContext *C, wmOperator *op)
+static int object_add_named_exec(bContext *C, wmOperator *op)
{
wmWindow *win = CTX_wm_window(C);
const wmEvent *event = win ? win->eventstate : NULL;
@@ -2859,7 +2990,7 @@ static int add_named_exec(bContext *C, wmOperator *op)
Base *basen;
Object *ob;
const bool linked = RNA_boolean_get(op->ptr, "linked");
- int dupflag = (linked) ? 0 : U.dupflag;
+ const eDupli_ID_Flags dupflag = (linked) ? 0 : (eDupli_ID_Flags)U.dupflag;
char name[MAX_ID_NAME - 2];
/* find object, create fake base */
@@ -2872,7 +3003,7 @@ static int add_named_exec(bContext *C, wmOperator *op)
}
/* prepare dupli */
- basen = object_add_duplicate_internal(bmain, scene, view_layer, ob, dupflag);
+ basen = object_add_duplicate_internal(bmain, scene, view_layer, ob, dupflag, 0);
if (basen == NULL) {
BKE_report(op->reports, RPT_ERROR, "Object could not be duplicated");
@@ -2912,7 +3043,7 @@ void OBJECT_OT_add_named(wmOperatorType *ot)
ot->idname = "OBJECT_OT_add_named";
/* api callbacks */
- ot->exec = add_named_exec;
+ ot->exec = object_add_named_exec;
ot->poll = ED_operator_objectmode;
/* flags */
@@ -2933,23 +3064,24 @@ void OBJECT_OT_add_named(wmOperatorType *ot)
*
* \{ */
-static bool join_poll(bContext *C)
+static bool object_join_poll(bContext *C)
{
Object *ob = CTX_data_active_object(C);
- if (!ob || ID_IS_LINKED(ob)) {
- return 0;
+ if (ob == NULL || ob->data == NULL || ID_IS_LINKED(ob) || ID_IS_OVERRIDE_LIBRARY(ob) ||
+ ID_IS_OVERRIDE_LIBRARY(ob->data)) {
+ return false;
}
if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_ARMATURE, OB_GPENCIL)) {
return ED_operator_screenactive(C);
}
else {
- return 0;
+ return false;
}
}
-static int join_exec(bContext *C, wmOperator *op)
+static int object_join_exec(bContext *C, wmOperator *op)
{
Object *ob = CTX_data_active_object(C);
@@ -2970,13 +3102,13 @@ static int join_exec(bContext *C, wmOperator *op)
}
if (ob->type == OB_MESH) {
- return join_mesh_exec(C, op);
+ return ED_mesh_join_objects_exec(C, op);
}
else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
- return join_curve_exec(C, op);
+ return ED_curve_join_objects_exec(C, op);
}
else if (ob->type == OB_ARMATURE) {
- return join_armature_exec(C, op);
+ return ED_armature_join_objects_exec(C, op);
}
else if (ob->type == OB_GPENCIL) {
return ED_gpencil_join_objects_exec(C, op);
@@ -2993,8 +3125,8 @@ void OBJECT_OT_join(wmOperatorType *ot)
ot->idname = "OBJECT_OT_join";
/* api callbacks */
- ot->exec = join_exec;
- ot->poll = join_poll;
+ ot->exec = object_join_exec;
+ ot->poll = object_join_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -3010,8 +3142,9 @@ static bool join_shapes_poll(bContext *C)
{
Object *ob = CTX_data_active_object(C);
- if (!ob || ID_IS_LINKED(ob)) {
- return 0;
+ if (ob == NULL || ob->data == NULL || ID_IS_LINKED(ob) || ID_IS_OVERRIDE_LIBRARY(ob) ||
+ ID_IS_OVERRIDE_LIBRARY(ob->data)) {
+ return false;
}
/* only meshes supported at the moment */
@@ -3019,7 +3152,7 @@ static bool join_shapes_poll(bContext *C)
return ED_operator_screenactive(C);
}
else {
- return 0;
+ return false;
}
}
@@ -3037,7 +3170,7 @@ static int join_shapes_exec(bContext *C, wmOperator *op)
}
if (ob->type == OB_MESH) {
- return join_mesh_shapes_exec(C, op);
+ return ED_mesh_shapes_join_objects_exec(C, op);
}
return OPERATOR_CANCELLED;
diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c
index a2d33ffe413..5746480e3f8 100644
--- a/source/blender/editors/object/object_constraint.c
+++ b/source/blender/editors/object/object_constraint.c
@@ -1557,6 +1557,77 @@ void CONSTRAINT_OT_move_up(wmOperatorType *ot)
/** \} */
/* ------------------------------------------------------------------- */
+/** \name Move Constraint To Index Operator
+ * \{ */
+
+static int constraint_move_to_index_exec(bContext *C, wmOperator *op)
+{
+ Object *ob = ED_object_active_context(C);
+ bConstraint *con = edit_constraint_property_get(op, ob, 0);
+
+ int new_index = RNA_int_get(op->ptr, "index");
+ if (new_index < 0) {
+ new_index = 0;
+ }
+
+ if (con) {
+ ListBase *conlist = ED_object_constraint_list_from_constraint(ob, con, NULL);
+ int current_index = BLI_findindex(conlist, con);
+ BLI_assert(current_index >= 0);
+
+ BLI_listbase_link_move(conlist, con, new_index - current_index);
+
+ WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, ob);
+
+ return OPERATOR_FINISHED;
+ }
+
+ return OPERATOR_CANCELLED;
+}
+
+static int constraint_move_to_index_invoke(bContext *C,
+ wmOperator *op,
+ const wmEvent *UNUSED(event))
+{
+ if (edit_constraint_invoke_properties(C, op)) {
+ return constraint_move_to_index_exec(C, op);
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
+}
+
+void CONSTRAINT_OT_move_to_index(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Move Constraint To Index";
+ ot->idname = "CONSTRAINT_OT_move_to_index";
+ ot->description =
+ "Change the constraint's position in the list so it evaluates after the set number of "
+ "others";
+
+ /* callbacks */
+ ot->exec = constraint_move_to_index_exec;
+ ot->invoke = constraint_move_to_index_invoke;
+ ot->poll = edit_constraint_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ edit_constraint_properties(ot);
+ RNA_def_int(ot->srna,
+ "index",
+ 0,
+ 0,
+ INT_MAX,
+ "Index",
+ "The index to move the constraint to",
+ 0,
+ INT_MAX);
+}
+
+/** \} */
+
+/* ------------------------------------------------------------------- */
/** \name Clear Pose Constraints Operator
* \{ */
diff --git a/source/blender/editors/object/object_data_transfer.c b/source/blender/editors/object/object_data_transfer.c
index 274cd31406c..0df33255c34 100644
--- a/source/blender/editors/object/object_data_transfer.c
+++ b/source/blender/editors/object/object_data_transfer.c
@@ -381,7 +381,7 @@ static bool data_transfer_exec_is_object_valid(wmOperator *op,
me->id.tag &= ~LIB_TAG_DOIT;
return true;
}
- else if (!ID_IS_LINKED(me)) {
+ else if (!ID_IS_LINKED(me) && !ID_IS_OVERRIDE_LIBRARY(me)) {
/* Do not apply transfer operation more than once. */
/* XXX This is not nice regarding vgroups, which are half-Object data... :/ */
BKE_reportf(
@@ -446,8 +446,8 @@ static int data_transfer_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
- if (reverse_transfer && ID_IS_LINKED(ob_src->data)) {
- /* Do not transfer to linked data, not supported. */
+ if (reverse_transfer && (ID_IS_LINKED(ob_src->data) || ID_IS_OVERRIDE_LIBRARY(ob_src->data))) {
+ /* Do not transfer to linked or override data, not supported. */
return OPERATOR_CANCELLED;
}
@@ -530,7 +530,7 @@ static bool data_transfer_poll(bContext *C)
{
Object *ob = ED_object_active_context(C);
ID *data = (ob) ? ob->data : NULL;
- return (ob && ob->type == OB_MESH && data);
+ return (ob != NULL && ob->type == OB_MESH && data != NULL);
}
/* Used by both OBJECT_OT_data_transfer and OBJECT_OT_datalayout_transfer */
@@ -786,7 +786,7 @@ static int datalayout_transfer_exec(bContext *C, wmOperator *op)
const bool use_delete = false; /* Never when used from modifier, for now. */
- if (!ob_src) {
+ if (!ob_src || ID_IS_LINKED(ob_dst) || ID_IS_OVERRIDE_LIBRARY(ob_dst)) {
return OPERATOR_CANCELLED;
}
@@ -854,7 +854,7 @@ static int datalayout_transfer_exec(bContext *C, wmOperator *op)
static int datalayout_transfer_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- if (edit_modifier_invoke_properties(C, op)) {
+ if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
return datalayout_transfer_exec(C, op);
}
else {
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index d522dcabae3..283aaec85ef 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -600,7 +600,8 @@ bool ED_object_editmode_enter_ex(Main *bmain, Scene *scene, Object *ob, int flag
{
bool ok = false;
- if (ELEM(NULL, ob, ob->data) || ID_IS_LINKED(ob)) {
+ if (ELEM(NULL, ob, ob->data) || ID_IS_LINKED(ob) || ID_IS_OVERRIDE_LIBRARY(ob) ||
+ ID_IS_OVERRIDE_LIBRARY(ob->data)) {
return false;
}
@@ -695,14 +696,10 @@ bool ED_object_editmode_enter(bContext *C, int flag)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
- Object *ob;
/* Active layer checked here for view3d,
* callers that don't want view context can call the extended version. */
- ob = CTX_data_active_object(C);
- if ((ob == NULL) || ID_IS_LINKED(ob)) {
- return false;
- }
+ Object *ob = CTX_data_active_object(C);
return ED_object_editmode_enter_ex(bmain, scene, ob, flag);
}
@@ -760,7 +757,8 @@ static bool editmode_toggle_poll(bContext *C)
Object *ob = CTX_data_active_object(C);
/* covers proxies too */
- if (ELEM(NULL, ob, ob->data) || ID_IS_LINKED(ob->data)) {
+ if (ELEM(NULL, ob, ob->data) || ID_IS_LINKED(ob->data) || ID_IS_OVERRIDE_LIBRARY(ob) ||
+ ID_IS_OVERRIDE_LIBRARY(ob->data)) {
return 0;
}
@@ -1368,7 +1366,8 @@ static bool shade_poll(bContext *C)
Object *obact = OBACT(view_layer);
if (obact != NULL) {
/* Doesn't handle edit-data, sculpt dynamic-topology, or their undo systems. */
- if (obact->mode & (OB_MODE_EDIT | OB_MODE_SCULPT)) {
+ if (obact->mode & (OB_MODE_EDIT | OB_MODE_SCULPT) || obact->data == NULL ||
+ ID_IS_OVERRIDE_LIBRARY(obact) || ID_IS_OVERRIDE_LIBRARY(obact->data)) {
return false;
}
}
@@ -1771,15 +1770,6 @@ static void move_to_collection_menu_create(bContext *UNUSED(C), uiLayout *layout
const char *name = BKE_collection_ui_name_get(menu->collection);
UI_block_flag_enable(uiLayoutGetBlock(layout), UI_BLOCK_IS_FLIP);
- uiItemIntO(layout, name, ICON_NONE, menu->ot->idname, "collection_index", menu->index);
- uiItemS(layout);
-
- for (MoveToCollectionData *submenu = menu->submenus.first; submenu != NULL;
- submenu = submenu->next) {
- move_to_collection_menus_items(layout, submenu);
- }
-
- uiItemS(layout);
WM_operator_properties_create_ptr(&menu->ptr, menu->ot);
RNA_int_set(&menu->ptr, "collection_index", menu->index);
@@ -1787,6 +1777,15 @@ static void move_to_collection_menu_create(bContext *UNUSED(C), uiLayout *layout
uiItemFullO_ptr(
layout, menu->ot, "New Collection", ICON_ADD, menu->ptr.data, WM_OP_INVOKE_DEFAULT, 0, NULL);
+
+ uiItemS(layout);
+
+ uiItemIntO(layout, name, ICON_SCENE_DATA, menu->ot->idname, "collection_index", menu->index);
+
+ for (MoveToCollectionData *submenu = menu->submenus.first; submenu != NULL;
+ submenu = submenu->next) {
+ move_to_collection_menus_items(layout, submenu);
+ }
}
static void move_to_collection_menus_items(uiLayout *layout, MoveToCollectionData *menu)
diff --git a/source/blender/editors/object/object_facemap_ops.c b/source/blender/editors/object/object_facemap_ops.c
index 147bd3d7871..6e0376358bb 100644
--- a/source/blender/editors/object/object_facemap_ops.c
+++ b/source/blender/editors/object/object_facemap_ops.c
@@ -171,14 +171,15 @@ static bool face_map_supported_poll(bContext *C)
{
Object *ob = ED_object_context(C);
ID *data = (ob) ? ob->data : NULL;
- return (ob && !ob->id.lib && ob->type == OB_MESH && data && !data->lib);
+ return (ob && !ID_IS_LINKED(ob) && !ID_IS_OVERRIDE_LIBRARY(ob) && ob->type == OB_MESH && data &&
+ !ID_IS_LINKED(data) && !ID_IS_OVERRIDE_LIBRARY(data));
}
static bool face_map_supported_edit_mode_poll(bContext *C)
{
Object *ob = ED_object_context(C);
- ID *data = (ob) ? ob->data : NULL;
- if (ob && !ob->id.lib && ob->type == OB_MESH && data && !data->lib) {
+
+ if (face_map_supported_poll(C)) {
if (ob->mode == OB_MODE_EDIT) {
return true;
}
diff --git a/source/blender/editors/object/object_gpencil_modifier.c b/source/blender/editors/object/object_gpencil_modifier.c
index 6d0f53cfa1e..cfdb6fea52d 100644
--- a/source/blender/editors/object/object_gpencil_modifier.c
+++ b/source/blender/editors/object/object_gpencil_modifier.c
@@ -24,6 +24,7 @@
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include "MEM_guardedalloc.h"
@@ -54,6 +55,8 @@
#include "ED_object.h"
#include "ED_screen.h"
+#include "UI_interface.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -105,23 +108,6 @@ GpencilModifierData *ED_object_gpencil_modifier_add(
return new_md;
}
-/* Return true if the object has a modifier of type 'type' other than
- * the modifier pointed to be 'exclude', otherwise returns false. */
-static bool UNUSED_FUNCTION(gpencil_object_has_modifier)(const Object *ob,
- const GpencilModifierData *exclude,
- GpencilModifierType type)
-{
- GpencilModifierData *md;
-
- for (md = ob->greasepencil_modifiers.first; md; md = md->next) {
- if ((md != exclude) && (md->type == type)) {
- return true;
- }
- }
-
- return false;
-}
-
static bool gpencil_object_modifier_remove(Main *bmain,
Object *ob,
GpencilModifierData *md,
@@ -211,6 +197,40 @@ int ED_object_gpencil_modifier_move_down(ReportList *UNUSED(reports),
return 1;
}
+bool ED_object_gpencil_modifier_move_to_index(ReportList *reports,
+ Object *ob,
+ GpencilModifierData *md,
+ const int index)
+{
+ BLI_assert(md != NULL);
+ BLI_assert(index >= 0);
+ if (index >= BLI_listbase_count(&ob->greasepencil_modifiers)) {
+ BKE_report(reports, RPT_WARNING, "Cannot move modifier beyond the end of the stack");
+ return false;
+ }
+
+ int md_index = BLI_findindex(&ob->greasepencil_modifiers, md);
+ BLI_assert(md_index != -1);
+ if (md_index < index) {
+ /* Move modifier down in list. */
+ for (; md_index < index; md_index++) {
+ if (!ED_object_gpencil_modifier_move_down(reports, ob, md)) {
+ break;
+ }
+ }
+ }
+ else {
+ /* Move modifier up in list. */
+ for (; md_index > index; md_index--) {
+ if (!ED_object_gpencil_modifier_move_up(reports, ob, md)) {
+ break;
+ }
+ }
+ }
+
+ return true;
+}
+
static int gpencil_modifier_apply_obdata(
ReportList *reports, Main *bmain, Depsgraph *depsgraph, Object *ob, GpencilModifierData *md)
{
@@ -428,22 +448,58 @@ static void gpencil_edit_modifier_properties(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_HIDDEN);
}
-static int gpencil_edit_modifier_invoke_properties(bContext *C, wmOperator *op)
+static void gpencil_edit_modifier_report_property(wmOperatorType *ot)
{
- GpencilModifierData *md;
+ PropertyRNA *prop = RNA_def_boolean(
+ ot->srna, "report", false, "Report", "Create a notification after the operation");
+ RNA_def_property_flag(prop, PROP_HIDDEN);
+}
+/**
+ * \param event: If this isn't NULL, the operator will also look for panels underneath
+ * the cursor with customdata set to a modifier.
+ * \param r_retval: This should be used if #event is used in order to to return
+ * #OPERATOR_PASS_THROUGH to check other operators with the same key set.
+ */
+static bool gpencil_edit_modifier_invoke_properties(bContext *C,
+ wmOperator *op,
+ const wmEvent *event,
+ int *r_retval)
+{
if (RNA_struct_property_is_set(op->ptr, "modifier")) {
return true;
}
- else {
- PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_GpencilModifier);
- if (ptr.data) {
- md = ptr.data;
- RNA_string_set(op->ptr, "modifier", md->name);
- return true;
+
+ PointerRNA ctx_ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_GpencilModifier);
+ if (ctx_ptr.data != NULL) {
+ GpencilModifierData *md = ctx_ptr.data;
+ RNA_string_set(op->ptr, "modifier", md->name);
+ return true;
+ }
+
+ /* Check the custom data of panels under the mouse for a modifier. */
+ if (event != NULL) {
+ PointerRNA *panel_ptr = UI_region_panel_custom_data_under_cursor(C, event);
+
+ if (!(panel_ptr == NULL || RNA_pointer_is_null(panel_ptr))) {
+ if (RNA_struct_is_a(panel_ptr->type, &RNA_GpencilModifier)) {
+ GpencilModifierData *md = panel_ptr->data;
+ RNA_string_set(op->ptr, "modifier", md->name);
+ return true;
+ }
+ else {
+ BLI_assert(r_retval != NULL); /* We need the return value in this case. */
+ if (r_retval != NULL) {
+ *r_retval = (OPERATOR_PASS_THROUGH | OPERATOR_CANCELLED);
+ }
+ return false;
+ }
}
}
+ if (r_retval != NULL) {
+ *r_retval = OPERATOR_CANCELLED;
+ }
return false;
}
@@ -472,24 +528,35 @@ static int gpencil_modifier_remove_exec(bContext *C, wmOperator *op)
Object *ob = ED_object_active_context(C);
GpencilModifierData *md = gpencil_edit_modifier_property_get(op, ob, 0);
- if (!md || !ED_object_gpencil_modifier_remove(op->reports, bmain, ob, md)) {
+ if (md == NULL) {
+ return OPERATOR_CANCELLED;
+ }
+
+ /* Store name temporarily for report. */
+ char name[MAX_NAME];
+ strcpy(name, md->name);
+
+ if (!ED_object_gpencil_modifier_remove(op->reports, bmain, ob, md)) {
return OPERATOR_CANCELLED;
}
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+ if (RNA_boolean_get(op->ptr, "report")) {
+ BKE_reportf(op->reports, RPT_INFO, "Removed modifier: %s", name);
+ }
+
return OPERATOR_FINISHED;
}
-static int gpencil_modifier_remove_invoke(bContext *C,
- wmOperator *op,
- const wmEvent *UNUSED(event))
+static int gpencil_modifier_remove_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- if (gpencil_edit_modifier_invoke_properties(C, op)) {
+ int retval;
+ if (gpencil_edit_modifier_invoke_properties(C, op, event, &retval)) {
return gpencil_modifier_remove_exec(C, op);
}
else {
- return OPERATOR_CANCELLED;
+ return retval;
}
}
@@ -506,6 +573,7 @@ void OBJECT_OT_gpencil_modifier_remove(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
gpencil_edit_modifier_properties(ot);
+ gpencil_edit_modifier_report_property(ot);
}
/************************ move up modifier operator *********************/
@@ -525,15 +593,14 @@ static int gpencil_modifier_move_up_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int gpencil_modifier_move_up_invoke(bContext *C,
- wmOperator *op,
- const wmEvent *UNUSED(event))
+static int gpencil_modifier_move_up_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- if (gpencil_edit_modifier_invoke_properties(C, op)) {
+ int retval;
+ if (gpencil_edit_modifier_invoke_properties(C, op, event, &retval)) {
return gpencil_modifier_move_up_exec(C, op);
}
else {
- return OPERATOR_CANCELLED;
+ return retval;
}
}
@@ -569,15 +636,14 @@ static int gpencil_modifier_move_down_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int gpencil_modifier_move_down_invoke(bContext *C,
- wmOperator *op,
- const wmEvent *UNUSED(event))
+static int gpencil_modifier_move_down_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- if (gpencil_edit_modifier_invoke_properties(C, op)) {
+ int retval;
+ if (gpencil_edit_modifier_invoke_properties(C, op, event, &retval)) {
return gpencil_modifier_move_down_exec(C, op);
}
else {
- return OPERATOR_CANCELLED;
+ return retval;
}
}
@@ -596,6 +662,59 @@ void OBJECT_OT_gpencil_modifier_move_down(wmOperatorType *ot)
gpencil_edit_modifier_properties(ot);
}
+/* ************************* Move to Index Gpencil Modifier Operator ************************* */
+
+static bool gpencil_modifier_move_to_index_poll(bContext *C)
+{
+ return gpencil_edit_modifier_poll(C);
+}
+
+static int gpencil_modifier_move_to_index_exec(bContext *C, wmOperator *op)
+{
+ Object *ob = ED_object_active_context(C);
+ GpencilModifierData *md = gpencil_edit_modifier_property_get(op, ob, 0);
+ int index = RNA_int_get(op->ptr, "index");
+
+ if (!ED_object_gpencil_modifier_move_to_index(op->reports, ob, md, index)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
+ WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+static int gpencil_modifier_move_to_index_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ int retval;
+ if (gpencil_edit_modifier_invoke_properties(C, op, event, &retval)) {
+ return gpencil_modifier_move_to_index_exec(C, op);
+ }
+ else {
+ return retval;
+ }
+}
+
+void OBJECT_OT_gpencil_modifier_move_to_index(wmOperatorType *ot)
+{
+ ot->name = "Move Active Modifier to Index";
+ ot->idname = "OBJECT_OT_gpencil_modifier_move_to_index";
+ ot->description =
+ "Change the modifier's position in the list so it evaluates after the set number of "
+ "others";
+
+ ot->invoke = gpencil_modifier_move_to_index_invoke;
+ ot->exec = gpencil_modifier_move_to_index_exec;
+ ot->poll = gpencil_modifier_move_to_index_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ edit_modifier_properties(ot);
+ RNA_def_int(
+ ot->srna, "index", 0, 0, INT_MAX, "Index", "The index to move the modifier to", 0, INT_MAX);
+}
+
/************************ apply modifier operator *********************/
static int gpencil_modifier_apply_exec(bContext *C, wmOperator *op)
@@ -606,23 +725,36 @@ static int gpencil_modifier_apply_exec(bContext *C, wmOperator *op)
GpencilModifierData *md = gpencil_edit_modifier_property_get(op, ob, 0);
int apply_as = RNA_enum_get(op->ptr, "apply_as");
- if (!md || !ED_object_gpencil_modifier_apply(bmain, op->reports, depsgraph, ob, md, apply_as)) {
+ if (md == NULL) {
+ return OPERATOR_CANCELLED;
+ }
+
+ /* Store name temporarily for report. */
+ char name[MAX_NAME];
+ strcpy(name, md->name);
+
+ if (!ED_object_gpencil_modifier_apply(bmain, op->reports, depsgraph, ob, md, apply_as)) {
return OPERATOR_CANCELLED;
}
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+ if (RNA_boolean_get(op->ptr, "report")) {
+ BKE_reportf(op->reports, RPT_INFO, "Applied modifier: %s", name);
+ }
+
return OPERATOR_FINISHED;
}
-static int gpencil_modifier_apply_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+static int gpencil_modifier_apply_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- if (gpencil_edit_modifier_invoke_properties(C, op)) {
+ int retval;
+ if (gpencil_edit_modifier_invoke_properties(C, op, event, &retval)) {
return gpencil_modifier_apply_exec(C, op);
}
else {
- return OPERATOR_CANCELLED;
+ return retval;
}
}
@@ -656,6 +788,7 @@ void OBJECT_OT_gpencil_modifier_apply(wmOperatorType *ot)
"Apply as",
"How to apply the modifier to the geometry");
gpencil_edit_modifier_properties(ot);
+ gpencil_edit_modifier_report_property(ot);
}
/************************ copy modifier operator *********************/
@@ -675,13 +808,14 @@ static int gpencil_modifier_copy_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int gpencil_modifier_copy_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+static int gpencil_modifier_copy_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- if (gpencil_edit_modifier_invoke_properties(C, op)) {
+ int retval;
+ if (gpencil_edit_modifier_invoke_properties(C, op, event, &retval)) {
return gpencil_modifier_copy_exec(C, op);
}
else {
- return OPERATOR_CANCELLED;
+ return retval;
}
}
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index c5a6e38fbcb..afc87c0caba 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -153,7 +153,10 @@ bool edit_modifier_poll_generic(struct bContext *C,
const bool is_editmode_allowed);
bool edit_modifier_poll(struct bContext *C);
void edit_modifier_properties(struct wmOperatorType *ot);
-int edit_modifier_invoke_properties(struct bContext *C, struct wmOperator *op);
+bool edit_modifier_invoke_properties(struct bContext *C,
+ struct wmOperator *op,
+ const struct wmEvent *event,
+ int *r_retval);
struct ModifierData *edit_modifier_property_get(struct wmOperator *op,
struct Object *ob,
int type);
@@ -190,6 +193,7 @@ void OBJECT_OT_gpencil_modifier_add(struct wmOperatorType *ot);
void OBJECT_OT_gpencil_modifier_remove(struct wmOperatorType *ot);
void OBJECT_OT_gpencil_modifier_move_up(struct wmOperatorType *ot);
void OBJECT_OT_gpencil_modifier_move_down(struct wmOperatorType *ot);
+void OBJECT_OT_gpencil_modifier_move_to_index(struct wmOperatorType *ot);
void OBJECT_OT_gpencil_modifier_apply(struct wmOperatorType *ot);
void OBJECT_OT_gpencil_modifier_copy(struct wmOperatorType *ot);
@@ -198,6 +202,7 @@ void OBJECT_OT_shaderfx_add(struct wmOperatorType *ot);
void OBJECT_OT_shaderfx_remove(struct wmOperatorType *ot);
void OBJECT_OT_shaderfx_move_up(struct wmOperatorType *ot);
void OBJECT_OT_shaderfx_move_down(struct wmOperatorType *ot);
+void OBJECT_OT_shaderfx_move_to_index(struct wmOperatorType *ot);
/* object_constraint.c */
void OBJECT_OT_constraint_add(struct wmOperatorType *ot);
@@ -217,6 +222,7 @@ void POSE_OT_ik_clear(struct wmOperatorType *ot);
void CONSTRAINT_OT_delete(struct wmOperatorType *ot);
void CONSTRAINT_OT_move_up(struct wmOperatorType *ot);
+void CONSTRAINT_OT_move_to_index(struct wmOperatorType *ot);
void CONSTRAINT_OT_move_down(struct wmOperatorType *ot);
void CONSTRAINT_OT_stretchto_reset(struct wmOperatorType *ot);
diff --git a/source/blender/editors/object/object_modes.c b/source/blender/editors/object/object_modes.c
index c518fd32c7f..5d4476ecb8c 100644
--- a/source/blender/editors/object/object_modes.c
+++ b/source/blender/editors/object/object_modes.c
@@ -116,7 +116,7 @@ bool ED_object_mode_compat_test(const Object *ob, eObjectMode mode)
case OB_SURF:
case OB_FONT:
case OB_MBALL:
- if (mode & (OB_MODE_EDIT)) {
+ if (mode & OB_MODE_EDIT) {
return true;
}
break;
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index a6c5814e88a..6b0eff5b6e5 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -88,6 +88,8 @@
#include "ED_screen.h"
#include "ED_sculpt.h"
+#include "UI_interface.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -1037,22 +1039,58 @@ void edit_modifier_properties(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_HIDDEN);
}
-int edit_modifier_invoke_properties(bContext *C, wmOperator *op)
+static void edit_modifier_report_property(wmOperatorType *ot)
{
- ModifierData *md;
+ PropertyRNA *prop = RNA_def_boolean(
+ ot->srna, "report", false, "Report", "Create a notification after the operation");
+ RNA_def_property_flag(prop, PROP_HIDDEN);
+}
+/**
+ * \param event: If this isn't NULL, the operator will also look for panels underneath
+ * the cursor with customdata set to a modifier.
+ * \param r_retval: This should be used if #event is used in order to to return
+ * #OPERATOR_PASS_THROUGH to check other operators with the same key set.
+ */
+bool edit_modifier_invoke_properties(bContext *C,
+ wmOperator *op,
+ const wmEvent *event,
+ int *r_retval)
+{
if (RNA_struct_property_is_set(op->ptr, "modifier")) {
return true;
}
- else {
- PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
- if (ptr.data) {
- md = ptr.data;
- RNA_string_set(op->ptr, "modifier", md->name);
- return true;
+
+ PointerRNA ctx_ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
+ if (ctx_ptr.data != NULL) {
+ ModifierData *md = ctx_ptr.data;
+ RNA_string_set(op->ptr, "modifier", md->name);
+ return true;
+ }
+
+ /* Check the custom data of panels under the mouse for a modifier. */
+ if (event != NULL) {
+ PointerRNA *panel_ptr = UI_region_panel_custom_data_under_cursor(C, event);
+
+ if (!(panel_ptr == NULL || RNA_pointer_is_null(panel_ptr))) {
+ if (RNA_struct_is_a(panel_ptr->type, &RNA_Modifier)) {
+ ModifierData *md = panel_ptr->data;
+ RNA_string_set(op->ptr, "modifier", md->name);
+ return true;
+ }
+ else {
+ BLI_assert(r_retval != NULL); /* We need the return value in this case. */
+ if (r_retval != NULL) {
+ *r_retval = (OPERATOR_PASS_THROUGH | OPERATOR_CANCELLED);
+ }
+ return false;
+ }
}
}
+ if (r_retval != NULL) {
+ *r_retval = OPERATOR_CANCELLED;
+ }
return false;
}
@@ -1085,7 +1123,15 @@ static int modifier_remove_exec(bContext *C, wmOperator *op)
ModifierData *md = edit_modifier_property_get(op, ob, 0);
int mode_orig = ob->mode;
- if (!md || !ED_object_modifier_remove(op->reports, bmain, ob, md)) {
+ if (md == NULL) {
+ return OPERATOR_CANCELLED;
+ }
+
+ /* Store name temporarily for report. */
+ char name[MAX_NAME];
+ strcpy(name, md->name);
+
+ if (!ED_object_modifier_remove(op->reports, bmain, ob, md)) {
return OPERATOR_CANCELLED;
}
@@ -1099,16 +1145,22 @@ static int modifier_remove_exec(bContext *C, wmOperator *op)
}
}
}
+
+ if (RNA_boolean_get(op->ptr, "report")) {
+ BKE_reportf(op->reports, RPT_INFO, "Removed modifier: %s", name);
+ }
+
return OPERATOR_FINISHED;
}
-static int modifier_remove_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+static int modifier_remove_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- if (edit_modifier_invoke_properties(C, op)) {
+ int retval;
+ if (edit_modifier_invoke_properties(C, op, event, &retval)) {
return modifier_remove_exec(C, op);
}
else {
- return OPERATOR_CANCELLED;
+ return retval;
}
}
@@ -1125,6 +1177,7 @@ void OBJECT_OT_modifier_remove(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
edit_modifier_properties(ot);
+ edit_modifier_report_property(ot);
}
/** \} */
@@ -1148,13 +1201,14 @@ static int modifier_move_up_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int modifier_move_up_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+static int modifier_move_up_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- if (edit_modifier_invoke_properties(C, op)) {
+ int retval;
+ if (edit_modifier_invoke_properties(C, op, event, &retval)) {
return modifier_move_up_exec(C, op);
}
else {
- return OPERATOR_CANCELLED;
+ return retval;
}
}
@@ -1194,13 +1248,14 @@ static int modifier_move_down_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int modifier_move_down_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+static int modifier_move_down_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- if (edit_modifier_invoke_properties(C, op)) {
+ int retval;
+ if (edit_modifier_invoke_properties(C, op, event, &retval)) {
return modifier_move_down_exec(C, op);
}
else {
- return OPERATOR_CANCELLED;
+ return retval;
}
}
@@ -1246,13 +1301,14 @@ static int modifier_move_to_index_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int modifier_move_to_index_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+static int modifier_move_to_index_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- if (edit_modifier_invoke_properties(C, op)) {
+ int retval;
+ if (edit_modifier_invoke_properties(C, op, event, &retval)) {
return modifier_move_to_index_exec(C, op);
}
else {
- return OPERATOR_CANCELLED;
+ return retval;
}
}
@@ -1291,6 +1347,10 @@ static bool modifier_apply_poll(bContext *C)
Object *ob = (ptr.owner_id != NULL) ? (Object *)ptr.owner_id : ED_object_active_context(C);
ModifierData *md = ptr.data; /* May be NULL. */
+ if (ID_IS_OVERRIDE_LIBRARY(ob) || ID_IS_OVERRIDE_LIBRARY(ob->data)) {
+ CTX_wm_operator_poll_msg_set(C, "Modifiers cannot be applied on override data");
+ return false;
+ }
if ((ob->data != NULL) && ID_REAL_USERS(ob->data) > 1) {
CTX_wm_operator_poll_msg_set(C, "Modifiers cannot be applied to multi-user data");
return false;
@@ -1315,7 +1375,15 @@ static int modifier_apply_exec(bContext *C, wmOperator *op)
ModifierData *md = edit_modifier_property_get(op, ob, 0);
int apply_as = RNA_enum_get(op->ptr, "apply_as");
- if (!md || !ED_object_modifier_apply(bmain, op->reports, depsgraph, scene, ob, md, apply_as)) {
+ if (md == NULL) {
+ return OPERATOR_CANCELLED;
+ }
+
+ /* Store name temporarily for report. */
+ char name[MAX_NAME];
+ strcpy(name, md->name);
+
+ if (!ED_object_modifier_apply(bmain, op->reports, depsgraph, scene, ob, md, apply_as)) {
return OPERATOR_CANCELLED;
}
@@ -1323,16 +1391,21 @@ static int modifier_apply_exec(bContext *C, wmOperator *op)
DEG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+ if (RNA_boolean_get(op->ptr, "report")) {
+ BKE_reportf(op->reports, RPT_INFO, "Applied modifier: %s", name);
+ }
+
return OPERATOR_FINISHED;
}
-static int modifier_apply_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+static int modifier_apply_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- if (edit_modifier_invoke_properties(C, op)) {
+ int retval;
+ if (edit_modifier_invoke_properties(C, op, event, &retval)) {
return modifier_apply_exec(C, op);
}
else {
- return OPERATOR_CANCELLED;
+ return retval;
}
}
@@ -1366,6 +1439,7 @@ void OBJECT_OT_modifier_apply(wmOperatorType *ot)
"Apply as",
"How to apply the modifier to the geometry");
edit_modifier_properties(ot);
+ edit_modifier_report_property(ot);
}
/** \} */
@@ -1396,7 +1470,7 @@ static int modifier_convert_exec(bContext *C, wmOperator *op)
static int modifier_convert_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- if (edit_modifier_invoke_properties(C, op)) {
+ if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
return modifier_convert_exec(C, op);
}
else {
@@ -1440,13 +1514,14 @@ static int modifier_copy_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int modifier_copy_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+static int modifier_copy_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- if (edit_modifier_invoke_properties(C, op)) {
+ int retval;
+ if (edit_modifier_invoke_properties(C, op, event, &retval)) {
return modifier_copy_exec(C, op);
}
else {
- return OPERATOR_CANCELLED;
+ return retval;
}
}
@@ -1501,7 +1576,7 @@ static int multires_higher_levels_delete_invoke(bContext *C,
wmOperator *op,
const wmEvent *UNUSED(event))
{
- if (edit_modifier_invoke_properties(C, op)) {
+ if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
return multires_higher_levels_delete_exec(C, op);
}
else {
@@ -1579,7 +1654,7 @@ static int multires_subdivide_exec(bContext *C, wmOperator *op)
static int multires_subdivide_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- if (edit_modifier_invoke_properties(C, op)) {
+ if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
return multires_subdivide_exec(C, op);
}
else {
@@ -1656,7 +1731,7 @@ static int multires_reshape_exec(bContext *C, wmOperator *op)
static int multires_reshape_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- if (edit_modifier_invoke_properties(C, op)) {
+ if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
return multires_reshape_exec(C, op);
}
else {
@@ -1720,7 +1795,7 @@ static int multires_external_save_invoke(bContext *C, wmOperator *op, const wmEv
Mesh *me = ob->data;
char path[FILE_MAX];
- if (!edit_modifier_invoke_properties(C, op)) {
+ if (!edit_modifier_invoke_properties(C, op, NULL, NULL)) {
return OPERATOR_CANCELLED;
}
@@ -1837,7 +1912,7 @@ static int multires_base_apply_exec(bContext *C, wmOperator *op)
static int multires_base_apply_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- if (edit_modifier_invoke_properties(C, op)) {
+ if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
return multires_base_apply_exec(C, op);
}
else {
@@ -1891,7 +1966,7 @@ static int multires_unsubdivide_exec(bContext *C, wmOperator *op)
static int multires_unsubdivide_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- if (edit_modifier_invoke_properties(C, op)) {
+ if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
return multires_unsubdivide_exec(C, op);
}
else {
@@ -1949,7 +2024,7 @@ static int multires_rebuild_subdiv_invoke(bContext *C,
wmOperator *op,
const wmEvent *UNUSED(event))
{
- if (edit_modifier_invoke_properties(C, op)) {
+ if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
return multires_rebuild_subdiv_exec(C, op);
}
else {
@@ -1999,8 +2074,9 @@ static bool skin_poll(bContext *C)
static bool skin_edit_poll(bContext *C)
{
- return (CTX_data_edit_object(C) &&
- edit_modifier_poll_generic(C, &RNA_SkinModifier, (1 << OB_MESH), true));
+ Object *ob = CTX_data_edit_object(C);
+ return (ob != NULL && edit_modifier_poll_generic(C, &RNA_SkinModifier, (1 << OB_MESH), true) &&
+ !ID_IS_OVERRIDE_LIBRARY(ob) && !ID_IS_OVERRIDE_LIBRARY(ob->data));
}
static void skin_root_clear(BMVert *bm_vert, GSet *visited, const int cd_vert_skin_offset)
@@ -2327,7 +2403,7 @@ static int skin_armature_create_exec(bContext *C, wmOperator *op)
static int skin_armature_create_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- if (edit_modifier_invoke_properties(C, op)) {
+ if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
return skin_armature_create_exec(C, op);
}
else {
@@ -2406,7 +2482,7 @@ static int correctivesmooth_bind_exec(bContext *C, wmOperator *op)
static int correctivesmooth_bind_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- if (edit_modifier_invoke_properties(C, op)) {
+ if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
return correctivesmooth_bind_exec(C, op);
}
else {
@@ -2483,7 +2559,7 @@ static int meshdeform_bind_exec(bContext *C, wmOperator *op)
static int meshdeform_bind_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- if (edit_modifier_invoke_properties(C, op)) {
+ if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
return meshdeform_bind_exec(C, op);
}
else {
@@ -2539,7 +2615,7 @@ static int explode_refresh_exec(bContext *C, wmOperator *op)
static int explode_refresh_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- if (edit_modifier_invoke_properties(C, op)) {
+ if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
return explode_refresh_exec(C, op);
}
else {
@@ -2743,7 +2819,7 @@ static int ocean_bake_exec(bContext *C, wmOperator *op)
static int ocean_bake_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- if (edit_modifier_invoke_properties(C, op)) {
+ if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
return ocean_bake_exec(C, op);
}
else {
@@ -2822,7 +2898,7 @@ static int laplaciandeform_bind_exec(bContext *C, wmOperator *op)
static int laplaciandeform_bind_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- if (edit_modifier_invoke_properties(C, op)) {
+ if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
return laplaciandeform_bind_exec(C, op);
}
else {
@@ -2891,7 +2967,7 @@ static int surfacedeform_bind_exec(bContext *C, wmOperator *op)
static int surfacedeform_bind_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- if (edit_modifier_invoke_properties(C, op)) {
+ if (edit_modifier_invoke_properties(C, op, NULL, NULL)) {
return surfacedeform_bind_exec(C, op);
}
else {
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index 05f1ced8615..e28bbb3fb1c 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -109,10 +109,8 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_light_add);
WM_operatortype_append(OBJECT_OT_camera_add);
WM_operatortype_append(OBJECT_OT_speaker_add);
-#ifdef WITH_NEW_OBJECT_TYPES
WM_operatortype_append(OBJECT_OT_hair_add);
WM_operatortype_append(OBJECT_OT_pointcloud_add);
-#endif
WM_operatortype_append(OBJECT_OT_volume_add);
WM_operatortype_append(OBJECT_OT_volume_import);
WM_operatortype_append(OBJECT_OT_add);
@@ -152,6 +150,7 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_gpencil_modifier_remove);
WM_operatortype_append(OBJECT_OT_gpencil_modifier_move_up);
WM_operatortype_append(OBJECT_OT_gpencil_modifier_move_down);
+ WM_operatortype_append(OBJECT_OT_gpencil_modifier_move_to_index);
WM_operatortype_append(OBJECT_OT_gpencil_modifier_apply);
WM_operatortype_append(OBJECT_OT_gpencil_modifier_copy);
@@ -160,6 +159,7 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_shaderfx_remove);
WM_operatortype_append(OBJECT_OT_shaderfx_move_up);
WM_operatortype_append(OBJECT_OT_shaderfx_move_down);
+ WM_operatortype_append(OBJECT_OT_shaderfx_move_to_index);
WM_operatortype_append(OBJECT_OT_correctivesmooth_bind);
WM_operatortype_append(OBJECT_OT_meshdeform_bind);
@@ -179,6 +179,7 @@ void ED_operatortypes_object(void)
WM_operatortype_append(CONSTRAINT_OT_delete);
WM_operatortype_append(CONSTRAINT_OT_move_up);
WM_operatortype_append(CONSTRAINT_OT_move_down);
+ WM_operatortype_append(CONSTRAINT_OT_move_to_index);
WM_operatortype_append(CONSTRAINT_OT_stretchto_reset);
WM_operatortype_append(CONSTRAINT_OT_limitdistance_reset);
WM_operatortype_append(CONSTRAINT_OT_childof_set_inverse);
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index fd2fcb11635..509b70f849e 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -33,6 +33,7 @@
#include "DNA_collection_types.h"
#include "DNA_constraint_types.h"
#include "DNA_gpencil_types.h"
+#include "DNA_key_types.h"
#include "DNA_lattice_types.h"
#include "DNA_light_types.h"
#include "DNA_material_types.h"
@@ -68,6 +69,7 @@
#include "BKE_gpencil.h"
#include "BKE_hair.h"
#include "BKE_idprop.h"
+#include "BKE_idtype.h"
#include "BKE_lattice.h"
#include "BKE_layer.h"
#include "BKE_lib_id.h"
@@ -1771,7 +1773,10 @@ static Collection *single_object_users_collection(Main *bmain,
/* Generate new copies for objects in given collection and all its children,
* and optionally also copy collections themselves. */
if (copy_collections && !is_master_collection) {
- collection = ID_NEW_SET(collection, BKE_collection_copy(bmain, NULL, collection));
+ Collection *collection_new;
+ BKE_id_copy(bmain, &collection->id, (ID **)&collection_new);
+ id_us_min(&collection_new->id);
+ collection = ID_NEW_SET(collection, collection_new);
}
/* We do not remap to new objects here, this is done in separate step. */
@@ -2246,47 +2251,66 @@ void OBJECT_OT_make_local(wmOperatorType *ot)
/** \name Make Library Override Operator
* \{ */
-static void make_override_library_tag_object(Object *obact, Object *ob)
+static bool make_override_hierarchy_recursive_tag(Main *bmain, ID *id)
{
- if (ob == obact) {
- return;
+ MainIDRelationsEntry *entry = BLI_ghash_lookup(bmain->relations->id_user_to_used, id);
+
+ /* This way we won't process again that ID should we encounter it again through another
+ * relationship hierarchy.
+ * Note that this does not free any memory from relations, so we can still use the entries.
+ */
+ BKE_main_relations_ID_remove(bmain, id);
+
+ for (; entry != NULL; entry = entry->next) {
+ /* We only consider IDs from the same library. */
+ if (entry->id_pointer != NULL && (*entry->id_pointer)->lib == id->lib) {
+ if (make_override_hierarchy_recursive_tag(bmain, *entry->id_pointer)) {
+ id->tag |= LIB_TAG_DOIT;
+ }
+ }
}
- if (!ID_IS_LINKED(ob)) {
- return;
+ return (id->tag & LIB_TAG_DOIT) != 0;
+}
+
+static int make_override_tag_ids_cb(LibraryIDLinkCallbackData *cb_data)
+{
+ if (cb_data->cb_flag & (IDWALK_CB_EMBEDDED | IDWALK_CB_LOOPBACK)) {
+ return IDWALK_RET_STOP_RECURSION;
}
- /* Note: all this is very case-by-case bad handling, ultimately we'll want a real full
- * 'automatic', generic handling of all this,
- * will probably require adding some override-aware stuff to library_query code... */
+ ID *id_root = cb_data->user_data;
+ Library *library_root = id_root->lib;
+ ID *id = *cb_data->id_pointer;
+ ID *id_owner = cb_data->id_owner;
- if (obact->type == OB_ARMATURE && ob->modifiers.first != NULL) {
- for (ModifierData *md = ob->modifiers.first; md != NULL; md = md->next) {
- if (md->type == eModifierType_Armature) {
- ArmatureModifierData *amd = (ArmatureModifierData *)md;
- if (amd->object == obact) {
- ob->id.tag |= LIB_TAG_DOIT;
- break;
- }
- }
- }
+ BLI_assert(id_owner == cb_data->id_self);
+
+ if (ELEM(id, NULL, id_owner)) {
+ return IDWALK_RET_NOP;
}
- else if (ob->parent == obact) {
- ob->id.tag |= LIB_TAG_DOIT;
+
+ BLI_assert(id->lib != NULL);
+ BLI_assert(id_owner->lib == library_root);
+
+ if (id->tag & LIB_TAG_DOIT) {
+ /* Already processed, but maybe not with the same chain of dependency, so we need to check that
+ * one nonetheless. */
+ return IDWALK_RET_STOP_RECURSION;
}
- if (ob->id.tag & LIB_TAG_DOIT) {
- printf("Indirectly overriding %s for %s\n", ob->id.name, obact->id.name);
+ if (id->lib != library_root) {
+ /* We do not override data-blocks from other libraries, nor do we process them. */
+ return IDWALK_RET_STOP_RECURSION;
}
-}
-static void make_override_library_tag_collections(Collection *collection)
-{
- collection->id.tag |= LIB_TAG_DOIT;
- for (CollectionChild *coll_child = collection->children.first; coll_child != NULL;
- coll_child = coll_child->next) {
- make_override_library_tag_collections(coll_child->collection);
+ /* We tag all collections and objects for override. And we also tag all other data-blocks which
+ * would user one of those. */
+ if (ELEM(GS(id->name), ID_OB, ID_GR)) {
+ id->tag |= LIB_TAG_DOIT;
}
+
+ return IDWALK_RET_NOP;
}
/* Set the object to override. */
@@ -2335,6 +2359,7 @@ static int make_override_library_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Object *obact = CTX_data_active_object(C);
+ ID *id_root = NULL;
bool success = false;
@@ -2348,111 +2373,156 @@ static int make_override_library_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
+ id_root = &obact->instance_collection->id;
+ }
+ else if (!ID_IS_OVERRIDABLE_LIBRARY(obact)) {
+ BKE_reportf(op->reports,
+ RPT_ERROR_INVALID_INPUT,
+ "Active object '%s' is not overridable",
+ obact->id.name + 2);
+ return OPERATOR_CANCELLED;
+ }
+ /* Else, poll func ensures us that ID_IS_LINKED(obact) is true. */
+ else {
+ id_root = &obact->id;
+ }
- Object *obcollection = obact;
- Collection *collection = obcollection->instance_collection;
+ BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
- const ListBase dup_collection_objects = BKE_collection_object_cache_get(collection);
- Base *base = BLI_findlink(&dup_collection_objects, RNA_enum_get(op->ptr, "object"));
- obact = base->object;
+ /* Tag all collections and objects, as well as other IDs using them. */
+ id_root->tag |= LIB_TAG_DOIT;
- /* First, we make a library override of the linked collection itself, and all its children. */
- make_override_library_tag_collections(collection);
+ BKE_main_relations_create(bmain, 0);
- /* Then, we make library override of the whole set of objects in the Collection. */
- FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (collection, ob) {
- ob->id.tag |= LIB_TAG_DOIT;
- }
- FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
-
- /* Then, we remove (untag) bone shape objects, you shall never want to override those
- * (hopefully)... */
- FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (collection, ob) {
- if (ob->type == OB_ARMATURE && ob->pose != NULL) {
- for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan != NULL; pchan = pchan->next) {
- if (pchan->custom != NULL) {
- pchan->custom->id.tag &= ~LIB_TAG_DOIT;
- }
+ BKE_library_foreach_ID_link(
+ bmain, id_root, make_override_tag_ids_cb, id_root, IDWALK_READONLY | IDWALK_RECURSE);
+
+ /* Then, we remove (untag) bone shape objects, you shall never want to override those
+ * (hopefully)... */
+ LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
+ if (ob->type == OB_ARMATURE && ob->pose != NULL && (ob->id.tag & LIB_TAG_DOIT)) {
+ for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan != NULL; pchan = pchan->next) {
+ if (pchan->custom != NULL) {
+ pchan->custom->id.tag &= ~LIB_TAG_DOIT;
}
}
}
- FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
+ }
- success = BKE_lib_override_library_create_from_tag(bmain);
+ /* The we tag all intermediary data-blocks in-between to overridden ones (e.g. if a shapekey has
+ * a driver using an armature object's bone, we need to override the shapekey/obdata, the objects
+ * using them, etc.) */
+ make_override_hierarchy_recursive_tag(bmain, id_root);
+
+ BKE_main_relations_free(bmain);
+
+ ID *id;
+ FOREACH_MAIN_ID_BEGIN (bmain, id) {
+ if (id->tag & LIB_TAG_DOIT && id->lib != NULL) {
+ printf("ID %s tagged for override\n", id->name);
+ }
+ }
+ FOREACH_MAIN_ID_END;
- /* Instantiate our newly overridden objects in scene, if not yet done. */
+ success = BKE_lib_override_library_create_from_tag(bmain);
+
+ if (success) {
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- Collection *new_collection = (Collection *)collection->id.newid;
- BKE_collection_add_from_object(bmain, scene, obcollection, new_collection);
+ BKE_main_collection_sync(bmain);
+
+ switch (GS(id_root->name)) {
+ case ID_GR: {
+ Collection *collection_new = ((Collection *)id_root->newid);
+ BKE_collection_add_from_object(bmain, scene, obact, collection_new);
+
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (collection_new, ob_new) {
+ if (ob_new != NULL && ob_new->id.override_library != NULL) {
+ Base *base;
+ if ((base = BKE_view_layer_base_find(view_layer, ob_new)) == NULL) {
+ BKE_collection_object_add_from(bmain, scene, obact, ob_new);
+ base = BKE_view_layer_base_find(view_layer, ob_new);
+ DEG_id_tag_update_ex(bmain, &ob_new->id, ID_RECALC_TRANSFORM | ID_RECALC_BASE_FLAGS);
+ }
- FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (new_collection, new_ob) {
- if (new_ob != NULL && new_ob->id.override_library != NULL) {
- if ((base = BKE_view_layer_base_find(view_layer, new_ob)) == NULL) {
- BKE_collection_object_add_from(bmain, scene, obcollection, new_ob);
- base = BKE_view_layer_base_find(view_layer, new_ob);
- DEG_id_tag_update_ex(bmain, &new_ob->id, ID_RECALC_TRANSFORM | ID_RECALC_BASE_FLAGS);
+ if (ob_new == (Object *)obact->id.newid) {
+ /* TODO: is setting active needed? */
+ BKE_view_layer_base_select_and_set_active(view_layer, base);
+ }
+ }
}
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
+ break;
+ }
+ case ID_OB: {
+ BKE_collection_object_add_from(bmain, scene, obact, ((Object *)id_root->newid));
+ break;
+ }
+ default:
+ BLI_assert(0);
+ }
- if (new_ob == (Object *)obact->id.newid) {
- /* TODO: is setting active needed? */
- BKE_view_layer_base_select_and_set_active(view_layer, base);
+ /* We need to ensure all new overrides of objects are properly instantiated. */
+ LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
+ Object *ob_new = (Object *)ob->id.newid;
+ if (ob_new != NULL) {
+ BLI_assert(ob_new->id.override_library != NULL &&
+ ob_new->id.override_library->reference == &ob->id);
+
+ Collection *default_instantiating_collection = NULL;
+ Base *base;
+ if ((base = BKE_view_layer_base_find(view_layer, ob_new)) == NULL) {
+ if (default_instantiating_collection == NULL) {
+ switch (GS(id_root->name)) {
+ case ID_GR: {
+ default_instantiating_collection = BKE_collection_add(
+ bmain, (Collection *)id_root, "OVERRIDE_HIDDEN");
+ break;
+ }
+ case ID_OB: {
+ /* Add the new container collection to one of the collections instantiating the
+ * root object, or scene's master collection if none found. */
+ Object *ob_root = (Object *)id_root;
+ LISTBASE_FOREACH (Collection *, collection, &bmain->collections) {
+ if (BKE_collection_has_object(collection, ob_root) &&
+ BKE_view_layer_has_collection(view_layer, collection)) {
+ default_instantiating_collection = BKE_collection_add(
+ bmain, collection, "OVERRIDE_HIDDEN");
+ }
+ }
+ if (default_instantiating_collection == NULL) {
+ default_instantiating_collection = BKE_collection_add(
+ bmain, scene->master_collection, "OVERRIDE_HIDDEN");
+ }
+ break;
+ }
+ default:
+ BLI_assert(0);
+ }
+ /* Hide the collection from viewport and render. */
+ default_instantiating_collection->flag |= COLLECTION_RESTRICT_VIEWPORT |
+ COLLECTION_RESTRICT_RENDER;
+ }
+
+ BKE_collection_object_add(bmain, default_instantiating_collection, ob_new);
+ DEG_id_tag_update_ex(bmain, &ob_new->id, ID_RECALC_TRANSFORM | ID_RECALC_BASE_FLAGS);
}
- /* We still want to store all objects' current override status (i.e. change of parent). */
- BKE_lib_override_library_operations_create(bmain, &new_ob->id, true);
}
}
- FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
/* Remove the instance empty from this scene, the items now have an overridden collection
* instead. */
- ED_object_base_free_and_unlink(bmain, scene, obcollection);
-
- /* Also, we'd likely want to lock by default things like
- * transformations of implicitly overridden objects? */
-
- DEG_id_tag_update(&scene->id, 0);
-
- /* Cleanup. */
- BKE_main_id_clear_newpoins(bmain);
- BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
- }
- else if (!ID_IS_OVERRIDABLE_LIBRARY(obact)) {
- BKE_reportf(op->reports,
- RPT_ERROR_INVALID_INPUT,
- "Active object '%s' is not overridable",
- obact->id.name + 2);
- return OPERATOR_CANCELLED;
- }
- /* Else, poll func ensures us that ID_IS_LINKED(obact) is true. */
- else if (obact->type == OB_ARMATURE) {
- BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
-
- obact->id.tag |= LIB_TAG_DOIT;
-
- for (Object *ob = bmain->objects.first; ob != NULL; ob = ob->id.next) {
- make_override_library_tag_object(obact, ob);
+ if (id_root != &obact->id) {
+ ED_object_base_free_and_unlink(bmain, scene, obact);
}
-
- success = BKE_lib_override_library_create_from_tag(bmain);
-
- /* Also, we'd likely want to lock by default things like
- * transformations of implicitly overridden objects? */
-
- /* Cleanup. */
- BKE_main_id_clear_newpoins(bmain);
- BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
- }
- /* TODO: probably more cases where we want to do automated smart things in the future! */
- else {
- /* For now, remapp all local usages of linked ID to local override one here. */
- BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, true);
- success = (BKE_lib_override_library_create_from_id(bmain, &obact->id, true) != NULL);
- BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
}
+ /* Cleanup. */
+ BKE_main_id_clear_newpoins(bmain);
+ BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
+
+ DEG_id_tag_update(&CTX_data_scene(C)->id, ID_RECALC_BASE_FLAGS | ID_RECALC_COPY_ON_WRITE);
WM_event_add_notifier(C, NC_WINDOW, NULL);
return success ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
diff --git a/source/blender/editors/object/object_remesh.c b/source/blender/editors/object/object_remesh.c
index 1d7920b9991..664d4219686 100644
--- a/source/blender/editors/object/object_remesh.c
+++ b/source/blender/editors/object/object_remesh.c
@@ -100,7 +100,12 @@ static bool object_remesh_poll(bContext *C)
{
Object *ob = CTX_data_active_object(C);
- if (ob == NULL) {
+ if (ob == NULL || ob->data == NULL) {
+ return false;
+ }
+
+ if (ID_IS_LINKED(ob) || ID_IS_LINKED(ob->data) || ID_IS_OVERRIDE_LIBRARY(ob->data)) {
+ CTX_wm_operator_poll_msg_set(C, "The remesher cannot worked on linked or override data");
return false;
}
@@ -174,6 +179,11 @@ static int voxel_remesh_exec(bContext *C, wmOperator *op)
BKE_remesh_reproject_sculpt_face_sets(new_mesh, mesh);
}
+ if (mesh->flag & ME_REMESH_REPROJECT_VERTEX_COLORS) {
+ BKE_mesh_runtime_clear_geometry(mesh);
+ BKE_remesh_reproject_vertex_paint(new_mesh, mesh);
+ }
+
BKE_mesh_nomain_to_mesh(new_mesh, mesh, ob, &CD_MASK_MESH, true);
if (mesh->flag & ME_REMESH_SMOOTH_NORMALS) {
@@ -521,7 +531,9 @@ static int voxel_size_edit_invoke(bContext *C, wmOperator *op, const wmEvent *ev
/* Project the selected face in the previous step of the Bounding Box. */
for (int i = 0; i < 4; i++) {
- ED_view3d_project(ar, cd->preview_plane[i], preview_plane_proj[i]);
+ float preview_plane_world_space[3];
+ mul_v3_m4v3(preview_plane_world_space, active_object->obmat, cd->preview_plane[i]);
+ ED_view3d_project(ar, preview_plane_world_space, preview_plane_proj[i]);
}
/* Get the initial X and Y axis of the basis from the edges of the Bounding Box face. */
@@ -569,7 +581,9 @@ static int voxel_size_edit_invoke(bContext *C, wmOperator *op, const wmEvent *ev
copy_v3_v3(cd->text_mat[3], text_pos);
/* Scale the text. */
- const float pixelsize = ED_view3d_pixel_size(rv3d, text_pos);
+ float text_pos_word_space[3];
+ mul_v3_m4v3(text_pos_word_space, active_object->obmat, text_pos);
+ const float pixelsize = ED_view3d_pixel_size(rv3d, text_pos_word_space);
scale_m4_fl(scale_mat, pixelsize * 0.5f);
mul_m4_m4_post(cd->text_mat, scale_mat);
diff --git a/source/blender/editors/object/object_shader_fx.c b/source/blender/editors/object/object_shader_fx.c
index 5db4a5a4f57..d9f37b8e38b 100644
--- a/source/blender/editors/object/object_shader_fx.c
+++ b/source/blender/editors/object/object_shader_fx.c
@@ -200,6 +200,40 @@ int ED_object_shaderfx_move_down(ReportList *UNUSED(reports), Object *ob, Shader
return 1;
}
+bool ED_object_shaderfx_move_to_index(ReportList *reports,
+ Object *ob,
+ ShaderFxData *fx,
+ const int index)
+{
+ BLI_assert(fx != NULL);
+ BLI_assert(index >= 0);
+ if (index >= BLI_listbase_count(&ob->shader_fx)) {
+ BKE_report(reports, RPT_WARNING, "Cannot move effect beyond the end of the stack");
+ return false;
+ }
+
+ int fx_index = BLI_findindex(&ob->shader_fx, fx);
+ BLI_assert(fx_index != -1);
+ if (fx_index < index) {
+ /* Move shaderfx down in list. */
+ for (; fx_index < index; fx_index++) {
+ if (!ED_object_shaderfx_move_down(reports, ob, fx)) {
+ break;
+ }
+ }
+ }
+ else {
+ /* Move shaderfx up in list. */
+ for (; fx_index > index; fx_index--) {
+ if (!ED_object_shaderfx_move_up(reports, ob, fx)) {
+ break;
+ }
+ }
+ }
+
+ return true;
+}
+
/************************ add effect operator *********************/
static int shaderfx_add_exec(bContext *C, wmOperator *op)
@@ -391,8 +425,8 @@ static int shaderfx_remove_invoke(bContext *C, wmOperator *op, const wmEvent *UN
void OBJECT_OT_shaderfx_remove(wmOperatorType *ot)
{
- ot->name = "Remove Grease Pencil Modifier";
- ot->description = "Remove a shaderfx from the active grease pencil object";
+ ot->name = "Remove Grease Pencil Effect";
+ ot->description = "Remove a effect from the active grease pencil object";
ot->idname = "OBJECT_OT_shaderfx_remove";
ot->invoke = shaderfx_remove_invoke;
@@ -433,8 +467,8 @@ static int shaderfx_move_up_invoke(bContext *C, wmOperator *op, const wmEvent *U
void OBJECT_OT_shaderfx_move_up(wmOperatorType *ot)
{
- ot->name = "Move Up Modifier";
- ot->description = "Move shaderfx up in the stack";
+ ot->name = "Move Up Effect";
+ ot->description = "Move effect up in the stack";
ot->idname = "OBJECT_OT_shaderfx_move_up";
ot->invoke = shaderfx_move_up_invoke;
@@ -475,8 +509,8 @@ static int shaderfx_move_down_invoke(bContext *C, wmOperator *op, const wmEvent
void OBJECT_OT_shaderfx_move_down(wmOperatorType *ot)
{
- ot->name = "Move Down Modifier";
- ot->description = "Move shaderfx down in the stack";
+ ot->name = "Move Down Effect";
+ ot->description = "Move effect down in the stack";
ot->idname = "OBJECT_OT_shaderfx_move_down";
ot->invoke = shaderfx_move_down_invoke;
@@ -487,3 +521,55 @@ void OBJECT_OT_shaderfx_move_down(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
edit_shaderfx_properties(ot);
}
+
+/************************ move shaderfx to index operator *********************/
+
+static bool shaderfx_move_to_index_poll(bContext *C)
+{
+ return edit_shaderfx_poll_generic(C, &RNA_ShaderFx, 0);
+}
+
+static int shaderfx_move_to_index_exec(bContext *C, wmOperator *op)
+{
+ Object *ob = ED_object_active_context(C);
+ ShaderFxData *fx = edit_shaderfx_property_get(op, ob, 0);
+ int index = RNA_int_get(op->ptr, "index");
+
+ if (!fx || !ED_object_shaderfx_move_to_index(op->reports, ob, fx, index)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
+ WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+static int shaderfx_move_to_index_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ if (edit_shaderfx_invoke_properties(C, op)) {
+ return shaderfx_move_to_index_exec(C, op);
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
+}
+
+void OBJECT_OT_shaderfx_move_to_index(wmOperatorType *ot)
+{
+ ot->name = "Move Effect to Index";
+ ot->idname = "OBJECT_OT_shaderfx_move_to_index";
+ ot->description =
+ "Change the effect's position in the list so it evaluates after the set number of "
+ "others";
+
+ ot->invoke = shaderfx_move_to_index_invoke;
+ ot->exec = shaderfx_move_to_index_exec;
+ ot->poll = shaderfx_move_to_index_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ edit_shaderfx_properties(ot);
+ RNA_def_int(
+ ot->srna, "index", 0, 0, INT_MAX, "Index", "The index to move the effect to", 0, INT_MAX);
+}
diff --git a/source/blender/editors/object/object_shapekey.c b/source/blender/editors/object/object_shapekey.c
index 26d33bbc375..71778f92349 100644
--- a/source/blender/editors/object/object_shapekey.c
+++ b/source/blender/editors/object/object_shapekey.c
@@ -216,40 +216,38 @@ static bool object_shape_key_mirror(
/********************** shape key operators *********************/
-static bool shape_key_mode_poll(bContext *C)
+static bool shape_key_poll(bContext *C)
{
Object *ob = ED_object_context(C);
ID *data = (ob) ? ob->data : NULL;
- return (ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data) && ob->mode != OB_MODE_EDIT);
+
+ return (ob != NULL && !ID_IS_LINKED(ob) && !ID_IS_OVERRIDE_LIBRARY(ob) && data != NULL &&
+ !ID_IS_LINKED(data) && !ID_IS_OVERRIDE_LIBRARY(data));
}
-static bool shape_key_mode_exists_poll(bContext *C)
+static bool shape_key_mode_poll(bContext *C)
{
Object *ob = ED_object_context(C);
- ID *data = (ob) ? ob->data : NULL;
- /* same as shape_key_mode_poll */
- return (ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data) && ob->mode != OB_MODE_EDIT) &&
- /* check a keyblock exists */
- (BKE_keyblock_from_object(ob) != NULL);
+ return (shape_key_poll(C) && ob->mode != OB_MODE_EDIT);
}
-static bool shape_key_move_poll(bContext *C)
+static bool shape_key_mode_exists_poll(bContext *C)
{
- /* Same as shape_key_mode_exists_poll above, but ensure we have at least two shapes! */
Object *ob = ED_object_context(C);
- ID *data = (ob) ? ob->data : NULL;
- Key *key = BKE_key_from_object(ob);
- return (ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data) && ob->mode != OB_MODE_EDIT &&
- key && key->totkey > 1);
+ return (shape_key_mode_poll(C) &&
+ /* check a keyblock exists */
+ (BKE_keyblock_from_object(ob) != NULL));
}
-static bool shape_key_poll(bContext *C)
+static bool shape_key_move_poll(bContext *C)
{
+ /* Same as shape_key_mode_exists_poll above, but ensure we have at least two shapes! */
Object *ob = ED_object_context(C);
- ID *data = (ob) ? ob->data : NULL;
- return (ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data));
+ Key *key = BKE_key_from_object(ob);
+
+ return (shape_key_mode_poll(C) && key != NULL && key->totkey > 1);
}
static int shape_key_add_exec(bContext *C, wmOperator *op)
diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c
index 132b530455e..161611d59c9 100644
--- a/source/blender/editors/object/object_transform.c
+++ b/source/blender/editors/object/object_transform.c
@@ -1098,15 +1098,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
mul_m4_v3(obedit->imat, cent);
}
else {
- if (around == V3D_AROUND_CENTER_MEDIAN) {
- if (em->bm->totvert) {
- const float total_div = 1.0f / (float)em->bm->totvert;
- BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
- madd_v3_v3fl(cent, eve->co, total_div);
- }
- }
- }
- else {
+ if (around == V3D_AROUND_CENTER_BOUNDS) {
float min[3], max[3];
INIT_MINMAX(min, max);
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
@@ -1114,6 +1106,14 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
}
mid_v3_v3v3(cent, min, max);
}
+ else { /* #V3D_AROUND_CENTER_MEDIAN. */
+ if (em->bm->totvert) {
+ const float total_div = 1.0f / (float)em->bm->totvert;
+ BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
+ madd_v3_v3fl(cent, eve->co, total_div);
+ }
+ }
+ }
}
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
@@ -1211,12 +1211,12 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
else if (centermode == ORIGIN_TO_CENTER_OF_MASS_VOLUME) {
BKE_mesh_center_of_volume(me, cent);
}
- else if (around == V3D_AROUND_CENTER_MEDIAN) {
- BKE_mesh_center_median(me, cent);
- }
- else {
+ else if (around == V3D_AROUND_CENTER_BOUNDS) {
BKE_mesh_center_bounds(me, cent);
}
+ else { /* #V3D_AROUND_CENTER_MEDIAN. */
+ BKE_mesh_center_median(me, cent);
+ }
negate_v3_v3(cent_neg, cent);
BKE_mesh_translate(me, cent_neg, 1);
@@ -1231,12 +1231,12 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
if (centermode == ORIGIN_TO_CURSOR) {
/* done */
}
- else if (around == V3D_AROUND_CENTER_MEDIAN) {
- BKE_curve_center_median(cu, cent);
- }
- else {
+ else if (around == V3D_AROUND_CENTER_BOUNDS) {
BKE_curve_center_bounds(cu, cent);
}
+ else { /* #V3D_AROUND_CENTER_MEDIAN. */
+ BKE_curve_center_median(cu, cent);
+ }
/* don't allow Z change if curve is 2D */
if ((ob->type == OB_CURVE) && !(cu->flag & CU_3D)) {
@@ -1324,12 +1324,12 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
if (centermode == ORIGIN_TO_CURSOR) {
/* done */
}
- else if (around == V3D_AROUND_CENTER_MEDIAN) {
- BKE_mball_center_median(mb, cent);
- }
- else {
+ else if (around == V3D_AROUND_CENTER_BOUNDS) {
BKE_mball_center_bounds(mb, cent);
}
+ else { /* #V3D_AROUND_CENTER_MEDIAN. */
+ BKE_mball_center_median(mb, cent);
+ }
negate_v3_v3(cent_neg, cent);
BKE_mball_translate(mb, cent_neg);
@@ -1351,12 +1351,12 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
if (centermode == ORIGIN_TO_CURSOR) {
/* done */
}
- else if (around == V3D_AROUND_CENTER_MEDIAN) {
- BKE_lattice_center_median(lt, cent);
- }
- else {
+ else if (around == V3D_AROUND_CENTER_BOUNDS) {
BKE_lattice_center_bounds(lt, cent);
}
+ else { /* #V3D_AROUND_CENTER_MEDIAN. */
+ BKE_lattice_center_median(lt, cent);
+ }
negate_v3_v3(cent_neg, cent);
BKE_lattice_translate(lt, cent_neg, 1);
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
index fb79cfb910e..7ca2a89f61d 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -77,7 +77,10 @@
#include "object_intern.h"
-/************************ Exported Functions **********************/
+/* -------------------------------------------------------------------- */
+/** \name Public Utility Functions
+ * \{ */
+
static bool vertex_group_use_vert_sel(Object *ob)
{
if (ob->mode == OB_MODE_EDIT) {
@@ -682,7 +685,11 @@ static void vgroup_copy_active_to_sel(Object *ob, eVGroupSelect subset_type)
MEM_freeN((void *)vgroup_validmap);
}
-/***********************Start weight transfer (WT)*********************************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Shared Weight Transfer Operator Properties
+ * \{ */
static const EnumPropertyItem WT_vertex_group_select_item[] = {
{WT_VGROUP_ACTIVE, "ACTIVE", 0, "Active Group", "The active Vertex Group"},
@@ -779,7 +786,15 @@ static void vgroup_operator_subset_select_props(wmOperatorType *ot, bool use_act
ot->prop = prop;
}
-/***********************End weight transfer (WT)***********************************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name High Level Vertex Group Add/Remove
+ *
+ * Wrap lower level `BKE` functions.
+ *
+ * \note that operations on many vertices should use #ED_vgroup_parray_alloc.
+ * \{ */
/* for Mesh in Object mode */
/* allows editmode for Lattice */
@@ -976,7 +991,11 @@ void ED_vgroup_select_by_name(Object *ob, const char *name)
ob->actdef = BKE_object_defgroup_name_index(ob, name) + 1;
}
-/********************** Operator Implementations *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Operator Function Implementations
+ * \{ */
/* only in editmode */
static void vgroup_select_verts(Object *ob, int select)
@@ -2634,48 +2653,49 @@ static void vgroup_assign_verts(Object *ob, const float weight)
}
}
-/********************** vertex group operators *********************/
+/** \} */
-static bool vertex_group_poll(bContext *C)
+/* -------------------------------------------------------------------- */
+/** \name Shared Operator Poll Functions
+ * \{ */
+
+static bool vertex_group_supported_poll(bContext *C)
{
Object *ob = ED_object_context(C);
ID *data = (ob) ? ob->data : NULL;
- return (ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data) &&
- OB_TYPE_SUPPORT_VGROUP(ob->type) && ob->defbase.first);
+ return (ob && !ID_IS_LINKED(ob) && OB_TYPE_SUPPORT_VGROUP(ob->type) &&
+ !ID_IS_OVERRIDE_LIBRARY(ob) && data && !ID_IS_LINKED(data) &&
+ !ID_IS_OVERRIDE_LIBRARY(data));
}
-static bool vertex_group_supported_poll(bContext *C)
+static bool vertex_group_poll(bContext *C)
{
Object *ob = ED_object_context(C);
- ID *data = (ob) ? ob->data : NULL;
- return (ob && !ID_IS_LINKED(ob) && OB_TYPE_SUPPORT_VGROUP(ob->type) && data &&
- !ID_IS_LINKED(data));
+
+ return (vertex_group_supported_poll(C) && ob->defbase.first);
}
static bool vertex_group_mesh_poll(bContext *C)
{
Object *ob = ED_object_context(C);
- ID *data = (ob) ? ob->data : NULL;
- return (ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data) && ob->type == OB_MESH &&
- ob->defbase.first);
+ return (vertex_group_poll(C) && ob->type == OB_MESH);
}
static bool UNUSED_FUNCTION(vertex_group_mesh_supported_poll)(bContext *C)
{
Object *ob = ED_object_context(C);
- ID *data = (ob) ? ob->data : NULL;
- return (ob && !ID_IS_LINKED(ob) && ob->type == OB_MESH && data && !ID_IS_LINKED(data));
+
+ return (vertex_group_supported_poll(C) && ob->type == OB_MESH);
}
static bool UNUSED_FUNCTION(vertex_group_poll_edit)(bContext *C)
{
Object *ob = ED_object_context(C);
- ID *data = (ob) ? ob->data : NULL;
- if (!(ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data))) {
- return 0;
+ if (!vertex_group_supported_poll(C)) {
+ return false;
}
return BKE_object_is_in_editmode_vgroup(ob);
@@ -2687,9 +2707,8 @@ static bool vertex_group_vert_poll_ex(bContext *C,
const short ob_type_flag)
{
Object *ob = ED_object_context(C);
- ID *data = (ob) ? ob->data : NULL;
- if (!(ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data))) {
+ if (!vertex_group_supported_poll(C)) {
return false;
}
@@ -2747,14 +2766,13 @@ static bool vertex_group_mesh_vert_select_poll(bContext *C)
static bool vertex_group_vert_select_unlocked_poll(bContext *C)
{
Object *ob = ED_object_context(C);
- ID *data = (ob) ? ob->data : NULL;
- if (!(ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data))) {
- return 0;
+ if (!vertex_group_supported_poll(C)) {
+ return false;
}
if (!(BKE_object_is_in_editmode_vgroup(ob) || BKE_object_is_in_wpaint_select_vert(ob))) {
- return 0;
+ return false;
}
if (ob->actdef != 0) {
@@ -2763,26 +2781,31 @@ static bool vertex_group_vert_select_unlocked_poll(bContext *C)
return !(dg->flag & DG_LOCK_WEIGHT);
}
}
- return 1;
+ return true;
}
static bool vertex_group_vert_select_mesh_poll(bContext *C)
{
Object *ob = ED_object_context(C);
- ID *data = (ob) ? ob->data : NULL;
- if (!(ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data))) {
- return 0;
+ if (!vertex_group_supported_poll(C)) {
+ return false;
}
/* only difference to #vertex_group_vert_select_poll */
if (ob->type != OB_MESH) {
- return 0;
+ return false;
}
return (BKE_object_is_in_editmode_vgroup(ob) || BKE_object_is_in_wpaint_select_vert(ob));
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Vertex Group Add Operator
+ * \{ */
+
static int vertex_group_add_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = ED_object_context(C);
@@ -2811,6 +2834,12 @@ void OBJECT_OT_vertex_group_add(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Vertex Group Remove Operator
+ * \{ */
+
static int vertex_group_remove_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_context(C);
@@ -2858,6 +2887,12 @@ void OBJECT_OT_vertex_group_remove(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Vertex Group Assign Operator
+ * \{ */
+
static int vertex_group_assign_exec(bContext *C, wmOperator *UNUSED(op))
{
ToolSettings *ts = CTX_data_tool_settings(C);
@@ -2888,6 +2923,12 @@ void OBJECT_OT_vertex_group_assign(wmOperatorType *ot)
ot->flag = /*OPTYPE_REGISTER|*/ OPTYPE_UNDO;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Vertex Group Assign New Operator
+ * \{ */
+
/* NOTE: just a wrapper around vertex_group_assign_exec(), except we add these to a new group */
static int vertex_group_assign_new_exec(bContext *C, wmOperator *op)
{
@@ -2917,6 +2958,12 @@ void OBJECT_OT_vertex_group_assign_new(wmOperatorType *ot)
ot->flag = /*OPTYPE_REGISTER|*/ OPTYPE_UNDO;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Vertex Group Remove From Operator
+ * \{ */
+
static int vertex_group_remove_from_exec(bContext *C, wmOperator *op)
{
const bool use_all_groups = RNA_boolean_get(op->ptr, "use_all_groups");
@@ -2968,6 +3015,12 @@ void OBJECT_OT_vertex_group_remove_from(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Vertex Group Select Operator
+ * \{ */
+
static int vertex_group_select_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = ED_object_context(C);
@@ -2998,6 +3051,12 @@ void OBJECT_OT_vertex_group_select(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Vertex Group Deselect Operator
+ * \{ */
+
static int vertex_group_deselect_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = ED_object_context(C);
@@ -3037,6 +3096,12 @@ static int vertex_group_copy_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Vertex Group Copy Operator
+ * \{ */
+
void OBJECT_OT_vertex_group_copy(wmOperatorType *ot)
{
/* identifiers */
@@ -3074,6 +3139,12 @@ static int vertex_group_levels_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Vertex Group Levels Operator
+ * \{ */
+
void OBJECT_OT_vertex_group_levels(wmOperatorType *ot)
{
/* identifiers */
@@ -3115,6 +3186,12 @@ static int vertex_group_normalize_exec(bContext *C, wmOperator *UNUSED(op))
}
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Vertex Group Normalize Operator
+ * \{ */
+
void OBJECT_OT_vertex_group_normalize(wmOperatorType *ot)
{
/* identifiers */
@@ -3158,6 +3235,12 @@ static int vertex_group_normalize_all_exec(bContext *C, wmOperator *op)
}
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Vertex Group Normalize All Operator
+ * \{ */
+
void OBJECT_OT_vertex_group_normalize_all(wmOperatorType *ot)
{
/* identifiers */
@@ -3182,6 +3265,12 @@ void OBJECT_OT_vertex_group_normalize_all(wmOperatorType *ot)
"Keep the values of the active group while normalizing others");
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Vertex Group Fix Position Operator
+ * \{ */
+
static int vertex_group_fix_exec(bContext *C, wmOperator *op)
{
Object *ob = CTX_data_active_object(C);
@@ -3259,6 +3348,12 @@ void OBJECT_OT_vertex_group_fix(wmOperatorType *ot)
1.f);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Vertex Group Lock Operator
+ * \{ */
+
static int vertex_group_lock_exec(bContext *C, wmOperator *op)
{
Object *ob = CTX_data_active_object(C);
@@ -3361,6 +3456,12 @@ void OBJECT_OT_vertex_group_lock(wmOperatorType *ot)
"Apply the action based on vertex group selection");
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Vertex Group Invert Operator
+ * \{ */
+
static int vertex_group_invert_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_context(C);
@@ -3410,6 +3511,12 @@ void OBJECT_OT_vertex_group_invert(wmOperatorType *ot)
"Remove verts from groups that have zero weight after inverting");
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Vertex Group Invert Operator
+ * \{ */
+
static int vertex_group_smooth_exec(bContext *C, wmOperator *op)
{
const float fac = RNA_float_get(op->ptr, "factor");
@@ -3482,6 +3589,12 @@ void OBJECT_OT_vertex_group_smooth(wmOperatorType *ot)
1.0f);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Vertex Group Clean Operator
+ * \{ */
+
static int vertex_group_clean_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_context(C);
@@ -3535,6 +3648,12 @@ void OBJECT_OT_vertex_group_clean(wmOperatorType *ot)
"Keep verts assigned to at least one group when cleaning");
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Vertex Group Quantize Operator
+ * \{ */
+
static int vertex_group_quantize_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_context(C);
@@ -3574,6 +3693,12 @@ void OBJECT_OT_vertex_group_quantize(wmOperatorType *ot)
RNA_def_int(ot->srna, "steps", 4, 1, 1000, "Steps", "Number of steps between 0 and 1", 1, 100);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Vertex Group Limit Total Operator
+ * \{ */
+
static int vertex_group_limit_total_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_context(C);
@@ -3625,6 +3750,12 @@ void OBJECT_OT_vertex_group_limit_total(wmOperatorType *ot)
RNA_def_int(ot->srna, "limit", 4, 1, 32, "Limit", "Maximum number of deform weights", 1, 32);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Vertex Group Mirror Operator
+ * \{ */
+
static int vertex_group_mirror_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_context(C);
@@ -3677,6 +3808,12 @@ void OBJECT_OT_vertex_group_mirror(wmOperatorType *ot)
"Use topology based mirroring (for when both sides of mesh have matching, unique topology)");
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Vertex Group Copy to Linked Operator
+ * \{ */
+
static int vertex_group_copy_to_linked_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
@@ -3720,6 +3857,12 @@ void OBJECT_OT_vertex_group_copy_to_linked(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Vertex Group Copy to Selected Operator
+ * \{ */
+
static int vertex_group_copy_to_selected_exec(bContext *C, wmOperator *op)
{
Object *obact = ED_object_context(C);
@@ -3768,6 +3911,12 @@ void OBJECT_OT_vertex_group_copy_to_selected(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Vertex Group Set Active Operator
+ * \{ */
+
static int set_active_group_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_context(C);
@@ -3836,6 +3985,12 @@ void OBJECT_OT_vertex_group_set_active(wmOperatorType *ot)
ot->prop = prop;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Vertex Group Sort Operator
+ * \{ */
+
/* creates the name_array parameter for vgroup_do_remap, call this before fiddling
* with the order of vgroups then call vgroup_do_remap after */
static char *vgroup_init_remap(Object *ob)
@@ -4030,6 +4185,12 @@ void OBJECT_OT_vertex_group_sort(wmOperatorType *ot)
RNA_def_enum(ot->srna, "sort_type", vgroup_sort_type, SORT_TYPE_NAME, "Sort type", "Sort type");
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Vertex Group Move Operator
+ * \{ */
+
static int vgroup_move_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_context(C);
@@ -4089,6 +4250,12 @@ void OBJECT_OT_vertex_group_move(wmOperatorType *ot)
"Direction to move the active vertex group towards");
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Vertex Group Weight Paste Operator
+ * \{ */
+
static void vgroup_copy_active_to_sel_single(Object *ob, const int def_nr)
{
MDeformVert *dvert_act;
@@ -4218,6 +4385,12 @@ void OBJECT_OT_vertex_weight_paste(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Vertex Group Weight Delete Operator
+ * \{ */
+
static int vertex_weight_delete_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_context(C);
@@ -4262,6 +4435,12 @@ void OBJECT_OT_vertex_weight_delete(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Vertex Group Set Active by Weight Operator
+ * \{ */
+
static int vertex_weight_set_active_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_context(C);
@@ -4303,6 +4482,12 @@ void OBJECT_OT_vertex_weight_set_active(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Vertex Group Normalize Active Vertex Operator
+ * \{ */
+
static int vertex_weight_normalize_active_vertex_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = ED_object_context(C);
@@ -4338,6 +4523,12 @@ void OBJECT_OT_vertex_weight_normalize_active_vertex(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Vertex Group Copy Weights from Active Operator
+ * \{ */
+
static int vertex_weight_copy_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = ED_object_context(C);
@@ -4366,3 +4557,5 @@ void OBJECT_OT_vertex_weight_copy(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+
+/** \} */
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index ef5ed806c1e..457c8ba30e6 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -4103,7 +4103,7 @@ static void brush_add_count_iter(void *__restrict iter_data_v,
BrushAddCountIterTLSData *tls = tls_v->userdata_chunk;
const int number = iter_data->number;
const short size = iter_data->size;
- const short size2 = size * size;
+ const int size2 = size * size;
float dmx, dmy;
if (number > 1) {
dmx = size;
diff --git a/source/blender/editors/physics/physics_fluid.c b/source/blender/editors/physics/physics_fluid.c
index 8524870c15e..8f6b5aa8bc3 100644
--- a/source/blender/editors/physics/physics_fluid.c
+++ b/source/blender/editors/physics/physics_fluid.c
@@ -270,31 +270,31 @@ static void fluid_bake_sequence(FluidJob *job)
*(job->do_update) = true;
}
- /* Get current pause frame (pointer) - depending on bake type */
+ /* Get current pause frame (pointer) - depending on bake type. */
pause_frame = job->pause_frame;
- /* Set frame to start point (depending on current pause frame value) */
+ /* Set frame to start point (depending on current pause frame value). */
is_first_frame = ((*pause_frame) == 0);
frame = is_first_frame ? mds->cache_frame_start : (*pause_frame);
- /* Save orig frame and update scene frame */
+ /* Save orig frame and update scene frame. */
orig_frame = CFRA;
CFRA = frame;
- /* Loop through selected frames */
+ /* Loop through selected frames. */
for (; frame <= mds->cache_frame_end; frame++) {
const float progress = (frame - mds->cache_frame_start) / (float)frames;
- /* Keep track of pause frame - needed to init future loop */
+ /* Keep track of pause frame - needed to init future loop. */
(*pause_frame) = frame;
- /* If user requested stop, quit baking */
+ /* If user requested stop, quit baking. */
if (G.is_break) {
job->success = 0;
return;
}
- /* Update progress bar */
+ /* Update progress bar. */
if (job->do_update) {
*(job->do_update) = true;
}
@@ -304,17 +304,17 @@ static void fluid_bake_sequence(FluidJob *job)
CFRA = frame;
- /* Update animation system */
+ /* Update animation system. */
ED_update_for_newframe(job->bmain, job->depsgraph);
- /* If user requested stop, quit baking */
+ /* If user requested stop, quit baking. */
if (G.is_break) {
job->success = 0;
return;
}
}
- /* Restore frame position that we were on before bake */
+ /* Restore frame position that we were on before bake. */
CFRA = orig_frame;
}
@@ -355,9 +355,9 @@ static void fluid_bake_endjob(void *customdata)
WM_set_locked_interface(G_MAIN->wm.first, false);
/* Bake was successful:
- * Report for ended bake and how long it took */
+ * Report for ended bake and how long it took. */
if (job->success) {
- /* Show bake info */
+ /* Show bake info. */
WM_reportf(
RPT_INFO, "Fluid: %s complete! (%.2f)", job->name, PIL_check_seconds_timer() - job->start);
}
@@ -365,7 +365,7 @@ static void fluid_bake_endjob(void *customdata)
if (mds->error[0] != '\0') {
WM_reportf(RPT_ERROR, "Fluid: %s failed: %s", job->name, mds->error);
}
- else { /* User canceled the bake */
+ else { /* User canceled the bake. */
WM_reportf(RPT_WARNING, "Fluid: %s canceled!", job->name);
}
}
diff --git a/source/blender/editors/physics/physics_pointcache.c b/source/blender/editors/physics/physics_pointcache.c
index 700a94e4f93..5bd56baf41e 100644
--- a/source/blender/editors/physics/physics_pointcache.c
+++ b/source/blender/editors/physics/physics_pointcache.c
@@ -132,7 +132,7 @@ static void ptcache_job_endjob(void *customdata)
WM_set_locked_interface(job->wm, false);
WM_main_add_notifier(NC_SCENE | ND_FRAME, scene);
- WM_main_add_notifier(NC_OBJECT | ND_POINTCACHE, job->baker->pid.ob);
+ WM_main_add_notifier(NC_OBJECT | ND_POINTCACHE, job->baker->pid.owner_id);
}
static void ptcache_free_bake(PointCache *cache)
diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c
index 10f69f3fe9d..7d0ad42c703 100644
--- a/source/blender/editors/render/render_update.c
+++ b/source/blender/editors/render/render_update.c
@@ -178,7 +178,7 @@ void ED_render_engine_area_exit(Main *bmain, ScrArea *area)
}
}
-void ED_render_engine_changed(Main *bmain)
+void ED_render_engine_changed(Main *bmain, const bool update_scene_data)
{
/* on changing the render engine type, clear all running render engines */
for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
@@ -198,7 +198,7 @@ void ED_render_engine_changed(Main *bmain)
update_ctx.view_layer = view_layer;
ED_render_id_flush_update(&update_ctx, &scene->id);
}
- if (scene->nodetree) {
+ if (scene->nodetree && update_scene_data) {
ntreeCompositUpdateRLayers(scene->nodetree);
}
}
diff --git a/source/blender/editors/scene/scene_edit.c b/source/blender/editors/scene/scene_edit.c
index c32bb69db4e..a1fa5e2d655 100644
--- a/source/blender/editors/scene/scene_edit.c
+++ b/source/blender/editors/scene/scene_edit.c
@@ -122,7 +122,7 @@ void ED_scene_change_update(Main *bmain, Scene *scene, ViewLayer *layer)
DEG_graph_relations_update(depsgraph, bmain, scene, layer);
DEG_on_visible_update(bmain, false);
- ED_render_engine_changed(bmain);
+ ED_render_engine_changed(bmain, false);
ED_update_for_newframe(bmain, depsgraph);
}
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index c04122edd36..a182dd662af 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -646,7 +646,7 @@ void ED_region_tag_redraw(ARegion *region)
void ED_region_tag_redraw_cursor(ARegion *region)
{
if (region) {
- region->do_draw_overlay = RGN_DRAW;
+ region->do_draw_paintcursor = RGN_DRAW;
}
}
@@ -1145,7 +1145,7 @@ static void region_overlap_fix(ScrArea *area, ARegion *region)
/* find overlapping previous region on same place */
for (ar1 = region->prev; ar1; ar1 = ar1->prev) {
- if (ar1->flag & (RGN_FLAG_HIDDEN)) {
+ if (ar1->flag & RGN_FLAG_HIDDEN) {
continue;
}
@@ -1194,7 +1194,7 @@ static void region_overlap_fix(ScrArea *area, ARegion *region)
/* At this point, 'region' is in its final position and still open.
* Make a final check it does not overlap any previous 'other side' region. */
for (ar1 = region->prev; ar1; ar1 = ar1->prev) {
- if (ar1->flag & (RGN_FLAG_HIDDEN)) {
+ if (ar1->flag & RGN_FLAG_HIDDEN) {
continue;
}
if (ELEM(ar1->alignment, RGN_ALIGN_FLOAT)) {
@@ -1556,7 +1556,14 @@ static void region_rect_recursive(
/* Tag for redraw if size changes. */
if (region->winx != prev_winx || region->winy != prev_winy) {
- ED_region_tag_redraw(region);
+ /* 3D View needs a full rebuild in case a progressive render runs. Rest can live with
+ * no-rebuild (e.g. Outliner) */
+ if (area->spacetype == SPACE_VIEW3D) {
+ ED_region_tag_redraw(region);
+ }
+ else {
+ ED_region_tag_redraw_no_rebuild(region);
+ }
}
/* Clear, initialize on demand. */
@@ -2348,9 +2355,9 @@ BLI_INLINE bool streq_array_any(const char *s, const char *arr[])
/**
* Builds the panel layout for the input \a panel or type \a pt.
*
- * \param panel The panel to draw. Can be null, in which case a panel with the type of \a pt will
- * be created.
- * \param unique_panel_str A unique identifier for the name of the \a uiBlock associated with the
+ * \param panel: The panel to draw. Can be null,
+ * in which case a panel with the type of \a pt will be created.
+ * \param unique_panel_str: A unique identifier for the name of the \a uiBlock associated with the
* panel. Used when the panel is an instanced panel so a unique identifier is needed to find the
* correct old \a uiBlock, and NULL otherwise.
*/
@@ -2566,16 +2573,16 @@ void ED_region_panels_layout_ex(const bContext *C,
/* only allow scrolling in vertical direction */
v2d->keepofs |= V2D_LOCKOFS_X | V2D_KEEPOFS_Y;
v2d->keepofs &= ~(V2D_LOCKOFS_Y | V2D_KEEPOFS_X);
- v2d->scroll &= ~(V2D_SCROLL_BOTTOM);
- v2d->scroll |= (V2D_SCROLL_RIGHT);
+ v2d->scroll &= ~V2D_SCROLL_BOTTOM;
+ v2d->scroll |= V2D_SCROLL_RIGHT;
}
else {
/* for now, allow scrolling in both directions (since layouts are optimized for vertical,
* they often don't fit in horizontal layout)
*/
v2d->keepofs &= ~(V2D_LOCKOFS_X | V2D_LOCKOFS_Y | V2D_KEEPOFS_X | V2D_KEEPOFS_Y);
- v2d->scroll |= (V2D_SCROLL_BOTTOM);
- v2d->scroll &= ~(V2D_SCROLL_RIGHT);
+ v2d->scroll |= V2D_SCROLL_BOTTOM;
+ v2d->scroll &= ~V2D_SCROLL_RIGHT;
}
/* collect categories */
@@ -2788,9 +2795,7 @@ void ED_region_panels_draw(const bContext *C, ARegion *region)
mask_buf.xmax -= UI_PANEL_CATEGORY_MARGIN_WIDTH;
mask = &mask_buf;
}
- View2DScrollers *scrollers = UI_view2d_scrollers_calc(v2d, mask);
- UI_view2d_scrollers_draw(v2d, scrollers);
- UI_view2d_scrollers_free(scrollers);
+ UI_view2d_scrollers_draw(v2d, mask);
}
void ED_region_panels_ex(
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index 6f004238522..b6f210d7f13 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -1331,6 +1331,7 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *area, const
oldscreen->animtimer = NULL;
ED_screen_change(C, screen);
+ ED_area_tag_refresh(fullsa);
BKE_workspace_layout_remove(CTX_data_main(C), workspace, layout_old);
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index b2243f2ccb9..5de8ccd404d 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -366,19 +366,20 @@ bool ED_operator_object_active_editable_mesh(bContext *C)
{
Object *ob = ED_object_active_context(C);
return ((ob != NULL) && !ID_IS_LINKED(ob) && !ed_object_hidden(ob) && (ob->type == OB_MESH) &&
- !ID_IS_LINKED(ob->data));
+ !ID_IS_LINKED(ob->data) && !ID_IS_OVERRIDE_LIBRARY(ob->data));
}
bool ED_operator_object_active_editable_font(bContext *C)
{
Object *ob = ED_object_active_context(C);
- return ((ob != NULL) && !ID_IS_LINKED(ob) && !ed_object_hidden(ob) && (ob->type == OB_FONT));
+ return ((ob != NULL) && !ID_IS_LINKED(ob) && !ed_object_hidden(ob) && (ob->type == OB_FONT) &&
+ !ID_IS_LINKED(ob->data) && !ID_IS_OVERRIDE_LIBRARY(ob->data));
}
bool ED_operator_editable_mesh(bContext *C)
{
Mesh *mesh = ED_mesh_context(C);
- return (mesh != NULL) && !ID_IS_LINKED(mesh);
+ return (mesh != NULL) && !ID_IS_LINKED(mesh) && !ID_IS_OVERRIDE_LIBRARY(mesh);
}
bool ED_operator_editmesh(bContext *C)
@@ -1761,7 +1762,7 @@ static void area_move_apply_do(const bContext *C,
screen->do_refresh = true;
redraw_all = true;
}
- ED_area_tag_redraw(area);
+ ED_area_tag_redraw_no_rebuild(area);
}
}
if (redraw_all) {
@@ -4273,68 +4274,67 @@ static void SCREEN_OT_region_context_menu(wmOperatorType *ot)
*
* Animation Step.
* \{ */
+static bool screen_animation_region_supports_time_follow(eSpace_Type spacetype,
+ eRegionType regiontype)
+{
+ return (regiontype == RGN_TYPE_WINDOW &&
+ ELEM(spacetype, SPACE_SEQ, SPACE_GRAPH, SPACE_ACTION, SPACE_NLA)) ||
+ (spacetype == SPACE_CLIP && regiontype == RGN_TYPE_PREVIEW);
+}
-static int match_region_with_redraws(int spacetype,
- int regiontype,
- int redraws,
- bool from_anim_edit)
+static bool match_region_with_redraws(const ScrArea *area,
+ eRegionType regiontype,
+ eScreen_Redraws_Flag redraws,
+ bool from_anim_edit)
{
+ const eSpace_Type spacetype = area->spacetype;
if (regiontype == RGN_TYPE_WINDOW) {
switch (spacetype) {
case SPACE_VIEW3D:
if ((redraws & TIME_ALL_3D_WIN) || from_anim_edit) {
- return 1;
+ return true;
}
break;
case SPACE_GRAPH:
case SPACE_NLA:
if ((redraws & TIME_ALL_ANIM_WIN) || from_anim_edit) {
- return 1;
+ return true;
}
break;
case SPACE_ACTION:
/* if only 1 window or 3d windows, we do timeline too
* NOTE: Now we do action editor in all these cases, since timeline is here. */
if ((redraws & (TIME_ALL_ANIM_WIN | TIME_REGION | TIME_ALL_3D_WIN)) || from_anim_edit) {
- return 1;
+ return true;
}
break;
case SPACE_PROPERTIES:
if (redraws & TIME_ALL_BUTS_WIN) {
- return 1;
+ return true;
}
break;
case SPACE_SEQ:
if ((redraws & (TIME_SEQ | TIME_ALL_ANIM_WIN)) || from_anim_edit) {
- return 1;
+ return true;
}
break;
case SPACE_NODE:
- if (redraws & (TIME_NODES)) {
- return 1;
+ if (redraws & TIME_NODES) {
+ return true;
}
break;
case SPACE_IMAGE:
if ((redraws & TIME_ALL_IMAGE_WIN) || from_anim_edit) {
- return 1;
+ return true;
}
break;
case SPACE_CLIP:
if ((redraws & TIME_CLIPS) || from_anim_edit) {
- return 1;
+ return true;
}
break;
- }
- }
- else if (regiontype == RGN_TYPE_CHANNELS) {
- switch (spacetype) {
- case SPACE_GRAPH:
- case SPACE_ACTION:
- case SPACE_NLA:
- if (redraws & TIME_ALL_ANIM_WIN) {
- return 1;
- }
+ default:
break;
}
}
@@ -4345,30 +4345,68 @@ static int match_region_with_redraws(int spacetype,
* during playback, so asking people to enable special option
* for this is a bit tricky, so add exception here for refreshing
* Properties Editor for SpaceClip always */
- return 1;
+ return true;
}
if (redraws & TIME_ALL_BUTS_WIN) {
- return 1;
+ return true;
}
}
- else if (ELEM(regiontype, RGN_TYPE_HEADER, RGN_TYPE_TOOL_HEADER)) {
+ else if (regiontype == RGN_TYPE_HEADER) {
if (spacetype == SPACE_ACTION) {
- return 1;
+ /* The timeline shows the current frame in the header. Other headers
+ * don't need to be updated. */
+ SpaceAction *saction = (SpaceAction *)area->spacedata.first;
+ return saction->mode == SACTCONT_TIMELINE;
}
}
else if (regiontype == RGN_TYPE_PREVIEW) {
switch (spacetype) {
case SPACE_SEQ:
if (redraws & (TIME_SEQ | TIME_ALL_ANIM_WIN)) {
- return 1;
+ return true;
}
break;
case SPACE_CLIP:
- return 1;
+ return true;
+ default:
+ break;
}
}
- return 0;
+ return false;
+}
+
+static void screen_animation_region_tag_redraw(ScrArea *area,
+ ARegion *region,
+ const Scene *scene,
+ eScreen_Redraws_Flag redraws)
+{
+ /* Do follow time here if editor type supports it */
+ if ((redraws & TIME_FOLLOW) &&
+ (screen_animation_region_supports_time_follow(area->spacetype, region->regiontype))) {
+ float w = BLI_rctf_size_x(&region->v2d.cur);
+ if (scene->r.cfra < region->v2d.cur.xmin) {
+ region->v2d.cur.xmax = scene->r.cfra;
+ region->v2d.cur.xmin = region->v2d.cur.xmax - w;
+ ED_region_tag_redraw(region);
+ return;
+ }
+ else if (scene->r.cfra > region->v2d.cur.xmax) {
+ region->v2d.cur.xmin = scene->r.cfra;
+ region->v2d.cur.xmax = region->v2d.cur.xmin + w;
+ ED_region_tag_redraw(region);
+ return;
+ }
+ }
+
+ /* No need to do a full redraw as the current frame indicator is only updated.
+ * We do need to redraw when this area is in full screen as no other areas
+ * will be tagged for redrawing. */
+ if ((region->regiontype == RGN_TYPE_WINDOW) &&
+ (ELEM(area->spacetype, SPACE_GRAPH, SPACE_NLA, SPACE_ACTION, SPACE_SEQ)) && !area->full) {
+ return;
+ }
+ ED_region_tag_redraw(region);
}
//#define PROFILE_AUDIO_SYNCH
@@ -4409,7 +4447,8 @@ static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), const wmEv
}
if (scene_eval == NULL) {
- /* Happens when undo/redo system is used during playback, nothing meaningful we can do here.
+ /* Happens when undo/redo system is used during playback, nothing meaningful we can do
+ * here.
*/
}
else if (scene_eval->id.recalc & ID_RECALC_AUDIO_SEEK) {
@@ -4549,28 +4588,12 @@ static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), const wmEv
redraw = true;
}
else if (match_region_with_redraws(
- area->spacetype, region->regiontype, sad->redraws, sad->from_anim_edit)) {
+ area, region->regiontype, sad->redraws, sad->from_anim_edit)) {
redraw = true;
}
if (redraw) {
- ED_region_tag_redraw(region);
- /* do follow here if editor type supports it */
- if ((sad->redraws & TIME_FOLLOW)) {
- if ((region->regiontype == RGN_TYPE_WINDOW &&
- ELEM(area->spacetype, SPACE_SEQ, SPACE_GRAPH, SPACE_ACTION, SPACE_NLA)) ||
- (area->spacetype == SPACE_CLIP && region->regiontype == RGN_TYPE_PREVIEW)) {
- float w = BLI_rctf_size_x(&region->v2d.cur);
- if (scene->r.cfra < region->v2d.cur.xmin) {
- region->v2d.cur.xmax = scene->r.cfra;
- region->v2d.cur.xmin = region->v2d.cur.xmax - w;
- }
- else if (scene->r.cfra > region->v2d.cur.xmax) {
- region->v2d.cur.xmin = scene->r.cfra;
- region->v2d.cur.xmax = region->v2d.cur.xmin + w;
- }
- }
- }
+ screen_animation_region_tag_redraw(area, region, scene, sad->redraws);
}
}
}
diff --git a/source/blender/editors/screen/workspace_layout_edit.c b/source/blender/editors/screen/workspace_layout_edit.c
index 7ce92bc3e4d..0af81e0db21 100644
--- a/source/blender/editors/screen/workspace_layout_edit.c
+++ b/source/blender/editors/screen/workspace_layout_edit.c
@@ -38,7 +38,7 @@
#include "screen_intern.h"
/**
- * Empty screen, with 1 dummy area without spacedata. Uses window size.
+ * Empty screen, with 1 dummy area without space-data. Uses window size.
*/
WorkSpaceLayout *ED_workspace_layout_add(Main *bmain,
WorkSpace *workspace,
diff --git a/source/blender/editors/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt
index b8754953741..ed87d524627 100644
--- a/source/blender/editors/sculpt_paint/CMakeLists.txt
+++ b/source/blender/editors/sculpt_paint/CMakeLists.txt
@@ -64,10 +64,12 @@ set(SRC
sculpt_detail.c
sculpt_dyntopo.c
sculpt_face_set.c
+ sculpt_filter_color.c
sculpt_filter_mask.c
sculpt_filter_mesh.c
sculpt_mask_expand.c
sculpt_multiplane_scrape.c
+ sculpt_paint_color.c
sculpt_pose.c
sculpt_smooth.c
sculpt_transform.c
diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c
index 4222a466a7b..1291de04634 100644
--- a/source/blender/editors/sculpt_paint/paint_cursor.c
+++ b/source/blender/editors/sculpt_paint/paint_cursor.c
@@ -1441,7 +1441,7 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
* cursor won't be tagged to update, so always initialize the preview chain if it is
* null before drawing it. */
if (update_previews || !ss->pose_ik_chain_preview) {
- BKE_sculpt_update_object_for_edit(depsgraph, vc.obact, true, false);
+ BKE_sculpt_update_object_for_edit(depsgraph, vc.obact, true, false, false);
/* Free the previous pose brush preview. */
if (ss->pose_ik_chain_preview) {
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index 08af3bdd16c..7f64fdf3501 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -1301,7 +1301,7 @@ static bool brush_colors_flip_poll(bContext *C)
else {
Object *ob = CTX_data_active_object(C);
if (ob != NULL) {
- if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_TEXTURE_PAINT)) {
+ if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_TEXTURE_PAINT | OB_MODE_SCULPT)) {
return true;
}
}
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index 5e3204b6d5a..dfb8f03fa6e 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -811,7 +811,7 @@ static bool project_paint_PickColor(
}
/**
- * Check if 'pt' is infront of the 3 verts on the Z axis (used for screenspace occlusion test)
+ * Check if 'pt' is in front of the 3 verts on the Z axis (used for screen-space occlusion test)
* \return
* - `0`: no occlusion
* - `-1`: no occlusion but 2D intersection is true
@@ -836,7 +836,7 @@ static int project_paint_occlude_ptv(const float pt[3],
}
/* From here on we know there IS an intersection */
- /* if ALL of the verts are infront of us then we know it intersects ? */
+ /* if ALL of the verts are in front of us then we know it intersects ? */
if (v1[2] < pt[2] && v2[2] < pt[2] && v3[2] < pt[2]) {
return 1;
}
diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c
index c32e496f4f5..6e0402fc6e0 100644
--- a/source/blender/editors/sculpt_paint/paint_mask.c
+++ b/source/blender/editors/sculpt_paint/paint_mask.c
@@ -146,12 +146,11 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op)
PBVHNode **nodes;
int totnode;
bool multires;
- Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
mode = RNA_enum_get(op->ptr, "mode");
value = RNA_float_get(op->ptr, "value");
- BKE_sculpt_update_object_for_edit(depsgraph, ob, false, true);
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, false, true, false);
pbvh = ob->sculpt->pbvh;
multires = (BKE_pbvh_type(pbvh) == PBVH_GRIDS);
@@ -169,7 +168,7 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op)
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(0, totnode, &data, mask_flood_fill_task_cb, &settings);
if (multires) {
@@ -313,7 +312,7 @@ bool ED_sculpt_mask_box_select(struct bContext *C, ViewContext *vc, const rcti *
/* Transform the clip planes in object space. */
ED_view3d_clipping_calc(&bb, clip_planes, vc->region, vc->obact, rect);
- BKE_sculpt_update_object_for_edit(depsgraph, ob, false, true);
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, false, true, false);
pbvh = ob->sculpt->pbvh;
multires = (BKE_pbvh_type(pbvh) == PBVH_GRIDS);
@@ -344,7 +343,7 @@ bool ED_sculpt_mask_box_select(struct bContext *C, ViewContext *vc, const rcti *
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(0, totnode, &data, mask_box_select_task_cb, &settings);
if (nodes) {
@@ -500,7 +499,7 @@ static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op)
ED_view3d_clipping_calc(&bb, clip_planes, vc.region, vc.obact, &data.rect);
- BKE_sculpt_update_object_for_edit(depsgraph, ob, false, true);
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, false, true, false);
pbvh = ob->sculpt->pbvh;
multires = (BKE_pbvh_type(pbvh) == PBVH_GRIDS);
@@ -533,7 +532,7 @@ static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op)
data.task_data.value = value;
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(0, totnode, &data, mask_gesture_lasso_task_cb, &settings);
if (nodes) {
diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c
index 0f54d5e0821..191ae1da343 100644
--- a/source/blender/editors/sculpt_paint/paint_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_ops.c
@@ -304,7 +304,10 @@ static bool palette_extract_img_poll(bContext *C)
{
SpaceLink *sl = CTX_wm_space_data(C);
if ((sl != NULL) && (sl->spacetype == SPACE_IMAGE)) {
- return true;
+ SpaceImage *sima = CTX_wm_space_image(C);
+ Image *image = sima->image;
+ ImageUser iuser = sima->iuser;
+ return BKE_image_has_ibuf(image, &iuser);
}
return false;
@@ -326,16 +329,16 @@ static int palette_extract_img_exec(bContext *C, wmOperator *op)
ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock);
- if (ibuf->rect) {
+ if (ibuf && ibuf->rect) {
/* Extract all colors. */
+ const int range = (int)pow(10.0f, threshold);
for (int row = 0; row < ibuf->y; row++) {
for (int col = 0; col < ibuf->x; col++) {
float color[4];
IMB_sampleImageAtLocation(ibuf, (float)col, (float)row, false, color);
- const float range = pow(10.0f, threshold);
- color[0] = truncf(color[0] * range) / range;
- color[1] = truncf(color[1] * range) / range;
- color[2] = truncf(color[2] * range) / range;
+ for (int i = 0; i < 3; i++) {
+ color[i] = truncf(color[i] * range) / range;
+ }
uint key = rgb_to_cpack(color[0], color[1], color[2]);
if (!BLI_ghash_haskey(color_table, POINTER_FROM_INT(key))) {
@@ -360,6 +363,8 @@ static int palette_extract_img_exec(bContext *C, wmOperator *op)
static void PALETTE_OT_extract_from_image(wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name = "Extract Palette from Image";
ot->idname = "PALETTE_OT_extract_from_image";
@@ -373,7 +378,8 @@ static void PALETTE_OT_extract_from_image(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- RNA_def_int(ot->srna, "threshold", 1, 1, 4, "Threshold", "", 1, 4);
+ prop = RNA_def_int(ot->srna, "threshold", 1, 1, 1, "Threshold", "", 1, 1);
+ RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
}
/* Sort Palette color by Hue and Saturation. */
diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c
index 2c6f708d82a..447d5373a48 100644
--- a/source/blender/editors/sculpt_paint/paint_stroke.c
+++ b/source/blender/editors/sculpt_paint/paint_stroke.c
@@ -909,7 +909,7 @@ PaintStroke *paint_stroke_new(bContext *C,
stroke->zoom_2d = max_ff(zoomx, zoomy);
if (stroke->stroke_mode == BRUSH_STROKE_INVERT) {
- if (br->flag & (BRUSH_CURVE)) {
+ if (br->flag & BRUSH_CURVE) {
RNA_enum_set(op->ptr, "mode", BRUSH_STROKE_NORMAL);
}
}
@@ -1467,8 +1467,7 @@ int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
else if (first_modal ||
/* regular dabs */
- (!(br->flag & (BRUSH_AIRBRUSH)) &&
- (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE))) ||
+ (!(br->flag & BRUSH_AIRBRUSH) && (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE))) ||
/* airbrush */
((br->flag & BRUSH_AIRBRUSH) && event->type == TIMER &&
event->customdata == stroke->timer)) {
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index 6de54b3ae6a..7ac778630ac 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -1101,12 +1101,12 @@ static void vertex_paint_init_session(Depsgraph *depsgraph,
BLI_assert(ob->sculpt == NULL);
ob->sculpt = MEM_callocN(sizeof(SculptSession), "sculpt session");
ob->sculpt->mode_type = object_mode;
- BKE_sculpt_update_object_for_edit(depsgraph, ob, false, false);
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, false, false, false);
}
static void vertex_paint_init_stroke(Depsgraph *depsgraph, Object *ob)
{
- BKE_sculpt_update_object_for_edit(depsgraph, ob, false, false);
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, false, false, false);
}
static void vertex_paint_init_session_data(const ToolSettings *ts, Object *ob)
@@ -1425,10 +1425,10 @@ static int wpaint_mode_toggle_exec(bContext *C, wmOperator *op)
}
}
- /* Weightpaint works by overriding colors in mesh,
- * so need to make sure we recalc on enter and
+ /* Weight-paint works by overriding colors in mesh,
+ * so need to make sure we recalculate on enter and
* exit (exit needs doing regardless because we
- * should redeform).
+ * should re-deform).
*/
DEG_id_tag_update(&me->id, 0);
@@ -2171,7 +2171,7 @@ static void calculate_average_weight(SculptThreadedTaskData *data,
data->custom_data = accum;
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (data->sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(0, totnode, data, do_wpaint_brush_calc_average_weight_cb_ex, &settings);
uint accum_len = 0;
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 75c88047914..fb7ae4d017d 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -30,6 +30,7 @@
#include "BLI_gsqueue.h"
#include "BLI_hash.h"
#include "BLI_math.h"
+#include "BLI_math_color_blend.h"
#include "BLI_task.h"
#include "BLI_utildefines.h"
@@ -73,6 +74,8 @@
#include "DEG_depsgraph.h"
+#include "IMB_colormanagement.h"
+
#include "WM_api.h"
#include "WM_message.h"
#include "WM_toolsystem.h"
@@ -153,6 +156,21 @@ const float *SCULPT_vertex_co_get(SculptSession *ss, int index)
return NULL;
}
+const float *SCULPT_vertex_color_get(SculptSession *ss, int index)
+{
+ switch (BKE_pbvh_type(ss->pbvh)) {
+ case PBVH_FACES:
+ if (ss->vcol) {
+ return ss->vcol[index].color;
+ }
+ break;
+ case PBVH_BMESH:
+ case PBVH_GRIDS:
+ break;
+ }
+ return NULL;
+}
+
void SCULPT_vertex_normal_get(SculptSession *ss, int index, float no[3])
{
switch (BKE_pbvh_type(ss->pbvh)) {
@@ -180,6 +198,23 @@ void SCULPT_vertex_normal_get(SculptSession *ss, int index, float no[3])
}
}
+static const float *sculpt_vertex_persistent_co_get(SculptSession *ss, int index)
+{
+ if (ss->persistent_base) {
+ return ss->persistent_base[index].co;
+ }
+ return SCULPT_vertex_co_get(ss, index);
+}
+
+static void sculpt_vertex_persistent_normal_get(SculptSession *ss, int index, float no[3])
+{
+ if (ss->persistent_base) {
+ copy_v3_v3(no, ss->persistent_base[index].no);
+ return;
+ }
+ SCULPT_vertex_normal_get(ss, index, no);
+}
+
float SCULPT_vertex_mask_get(SculptSession *ss, int index)
{
BMVert *v;
@@ -633,6 +668,13 @@ static void sculpt_vertex_neighbors_get_faces(SculptSession *ss,
}
}
}
+
+ if (ss->fake_neighbors.use_fake_neighbors) {
+ BLI_assert(ss->fake_neighbors.fake_neighbor_index != NULL);
+ if (ss->fake_neighbors.fake_neighbor_index[index] != FAKE_NEIGHBOR_NONE) {
+ sculpt_vertex_neighbor_add(iter, ss->fake_neighbors.fake_neighbor_index[index]);
+ }
+ }
}
static void sculpt_vertex_neighbors_get_grids(SculptSession *ss,
@@ -665,6 +707,13 @@ static void sculpt_vertex_neighbors_get_grids(SculptSession *ss,
neighbors.coords[i].y * key->grid_size + neighbors.coords[i].x);
}
+ if (ss->fake_neighbors.use_fake_neighbors) {
+ BLI_assert(ss->fake_neighbors.fake_neighbor_index != NULL);
+ if (ss->fake_neighbors.fake_neighbor_index[index] != FAKE_NEIGHBOR_NONE) {
+ sculpt_vertex_neighbor_add(iter, ss->fake_neighbors.fake_neighbor_index[index]);
+ }
+ }
+
if (neighbors.coords != neighbors.coords_fixed) {
MEM_freeN(neighbors.coords);
}
@@ -821,7 +870,7 @@ int SCULPT_nearest_vertex_get(
nvtd.nearest_vertex_distance_squared = FLT_MAX;
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
settings.func_reduce = nearest_vertex_get_reduce;
settings.userdata_chunk = &nvtd;
settings.userdata_chunk_size = sizeof(NearestVertexTLSData);
@@ -998,6 +1047,8 @@ static bool sculpt_tool_is_proxy_used(const char sculpt_tool)
SCULPT_TOOL_LAYER,
SCULPT_TOOL_POSE,
SCULPT_TOOL_CLOTH,
+ SCULPT_TOOL_PAINT,
+ SCULPT_TOOL_SMEAR,
SCULPT_TOOL_DRAW_FACE_SETS);
}
@@ -1045,9 +1096,7 @@ typedef enum StrokeFlags {
/* Initialize a SculptOrigVertData for accessing original vertex data;
* handles BMesh, mesh, and multires. */
-static void sculpt_orig_vert_data_unode_init(SculptOrigVertData *data,
- Object *ob,
- SculptUndoNode *unode)
+void SCULPT_orig_vert_data_unode_init(SculptOrigVertData *data, Object *ob, SculptUndoNode *unode)
{
SculptSession *ss = ob->sculpt;
BMesh *bm = ss->bm;
@@ -1062,6 +1111,7 @@ static void sculpt_orig_vert_data_unode_init(SculptOrigVertData *data,
data->coords = data->unode->co;
data->normals = data->unode->no;
data->vmasks = data->unode->mask;
+ data->colors = data->unode->col;
}
}
@@ -1071,7 +1121,7 @@ void SCULPT_orig_vert_data_init(SculptOrigVertData *data, Object *ob, PBVHNode *
{
SculptUndoNode *unode;
unode = SCULPT_undo_push_node(ob, node, SCULPT_UNDO_COORDS);
- sculpt_orig_vert_data_unode_init(data, ob, unode);
+ SCULPT_orig_vert_data_unode_init(data, ob, unode);
}
/* Update a SculptOrigVertData for a particular vertex from the PBVH
@@ -1087,6 +1137,9 @@ void SCULPT_orig_vert_data_update(SculptOrigVertData *orig_data, PBVHVertexIter
orig_data->no = orig_data->normals[iter->i];
}
}
+ else if (orig_data->unode->type == SCULPT_UNDO_COLOR) {
+ orig_data->col = orig_data->colors[iter->i];
+ }
else if (orig_data->unode->type == SCULPT_UNDO_MASK) {
if (orig_data->bm_log) {
orig_data->mask = BM_log_original_mask(orig_data->bm_log, iter->bm_vert);
@@ -1247,7 +1300,7 @@ static void paint_mesh_restore_co_task_cb(void *__restrict userdata,
PBVHVertexIter vd;
SculptOrigVertData orig_data;
- sculpt_orig_vert_data_unode_init(&orig_data, data->ob, unode);
+ SCULPT_orig_vert_data_unode_init(&orig_data, data->ob, unode);
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
@@ -1265,6 +1318,9 @@ static void paint_mesh_restore_co_task_cb(void *__restrict userdata,
else if (orig_data.unode->type == SCULPT_UNDO_MASK) {
*vd.mask = orig_data.mask;
}
+ else if (orig_data.unode->type == SCULPT_UNDO_COLOR) {
+ copy_v4_v4(vd.col, orig_data.col);
+ }
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
@@ -1288,7 +1344,7 @@ static void paint_mesh_restore_co(Sculpt *sd, Object *ob)
/**
* Disable OpenMP when dynamic-topology is enabled. Otherwise, new entries might be inserted by
- * #sculpt_undo_push_node() into the GHash used internally by #BM_log_original_vert_co()
+ * #SCULPT_undo_push_node() into the #GHash used internally by #BM_log_original_vert_co()
* by a different thread. See T33787. */
SculptThreadedTaskData data = {
.sd = sd,
@@ -1298,9 +1354,11 @@ static void paint_mesh_restore_co(Sculpt *sd, Object *ob)
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP) && !ss->bm, totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true && !ss->bm, totnode);
BLI_task_parallel_range(0, totnode, &data, paint_mesh_restore_co_task_cb, &settings);
+ BKE_pbvh_node_color_buffer_free(ss->pbvh);
+
MEM_SAFE_FREE(nodes);
}
@@ -1478,6 +1536,9 @@ bool SCULPT_brush_test_cube(SculptBrushTest *test,
{
float side = M_SQRT1_2;
float local_co[3];
+ float i_local[4][4];
+
+ invert_m4_m4(i_local, local);
if (sculpt_brush_test_clipping(test, co)) {
return false;
@@ -1924,7 +1985,7 @@ static void calc_area_center(
AreaNormalCenterTLSData anctd = {{{0}}};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
settings.func_reduce = calc_area_normal_and_center_reduce;
settings.userdata_chunk = &anctd;
settings.userdata_chunk_size = sizeof(AreaNormalCenterTLSData);
@@ -1953,8 +2014,7 @@ void SCULPT_calc_area_normal(
Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float r_area_no[3])
{
const Brush *brush = BKE_paint_brush(&sd->paint);
- bool use_threading = (sd->flags & SCULPT_USE_OPENMP);
- SCULPT_pbvh_calc_area_normal(brush, ob, nodes, totnode, use_threading, r_area_no);
+ SCULPT_pbvh_calc_area_normal(brush, ob, nodes, totnode, true, r_area_no);
}
/* Expose 'calc_area_normal' externally. */
@@ -2024,7 +2084,7 @@ static void calc_area_normal_and_center(
AreaNormalCenterTLSData anctd = {{{0}}};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
settings.func_reduce = calc_area_normal_and_center_reduce;
settings.userdata_chunk = &anctd;
settings.userdata_chunk_size = sizeof(AreaNormalCenterTLSData);
@@ -2116,6 +2176,11 @@ static float brush_strength(const Sculpt *sd,
return alpha * pressure * overlap * feather;
case SCULPT_TOOL_SLIDE_RELAX:
return alpha * pressure * overlap * feather * 2.0f;
+ case SCULPT_TOOL_PAINT:
+ final_pressure = pressure * pressure;
+ return final_pressure * overlap * feather;
+ case SCULPT_TOOL_SMEAR:
+ return pressure * overlap * feather;
case SCULPT_TOOL_CLAY_STRIPS:
/* Clay Strips needs less strength to compensate the curve. */
final_pressure = powf(pressure, 1.5f);
@@ -2577,11 +2642,6 @@ static void update_brush_local_mat(Sculpt *sd, Object *ob)
}
}
-/* Note: uses after-struct allocated mem to store actual cache... */
-typedef struct SculptDoBrushSmoothGridDataChunk {
- size_t tmpgrid_size;
-} SculptDoBrushSmoothGridDataChunk;
-
typedef struct {
SculptSession *ss;
const float *ray_start;
@@ -2689,7 +2749,7 @@ static void bmesh_topology_rake(
.strength = factor,
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(0, totnode, &data, do_topology_rake_bmesh_task_cb_ex, &settings);
}
@@ -2746,7 +2806,7 @@ static void do_mask_brush_draw(Sculpt *sd, Object *ob, PBVHNode **nodes, int tot
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(0, totnode, &data, do_mask_brush_draw_task_cb_ex, &settings);
}
@@ -2834,7 +2894,7 @@ static void do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(0, totnode, &data, do_draw_brush_task_cb_ex, &settings);
}
@@ -2911,7 +2971,7 @@ static void do_draw_sharp_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(0, totnode, &data, do_draw_sharp_brush_task_cb_ex, &settings);
}
@@ -3098,7 +3158,7 @@ static void do_slide_relax_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int t
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
if (ss->cache->alt_smooth) {
for (int i = 0; i < 4; i++) {
BLI_task_parallel_range(0, totnode, &data, do_topology_relax_task_cb_ex, &settings);
@@ -3308,7 +3368,7 @@ static void do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(0, totnode, &data, do_crease_brush_task_cb_ex, &settings);
}
@@ -3422,7 +3482,7 @@ static void do_pinch_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(0, totnode, &data, do_pinch_brush_task_cb_ex, &settings);
}
@@ -3495,7 +3555,7 @@ static void do_grab_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(0, totnode, &data, do_grab_brush_task_cb_ex, &settings);
}
@@ -3604,7 +3664,7 @@ static void do_elastic_deform_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, in
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(0, totnode, &data, do_elastic_deform_brush_task_cb_ex, &settings);
}
@@ -3811,7 +3871,7 @@ static void do_nudge_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(0, totnode, &data, do_nudge_brush_task_cb_ex, &settings);
}
@@ -3933,7 +3993,7 @@ static void do_snake_hook_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(0, totnode, &data, do_snake_hook_brush_task_cb_ex, &settings);
}
@@ -4006,7 +4066,7 @@ static void do_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(0, totnode, &data, do_thumb_brush_task_cb_ex, &settings);
}
@@ -4080,7 +4140,7 @@ static void do_rotate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(0, totnode, &data, do_rotate_brush_task_cb_ex, &settings);
}
@@ -4093,7 +4153,7 @@ static void do_layer_brush_task_cb_ex(void *__restrict userdata,
Sculpt *sd = data->sd;
const Brush *brush = data->brush;
- const bool use_persistent_base = ss->layer_base && brush->flag & BRUSH_PERSISTENT;
+ const bool use_persistent_base = ss->persistent_base && brush->flag & BRUSH_PERSISTENT;
PBVHVertexIter vd;
SculptOrigVertData orig_data;
@@ -4123,7 +4183,7 @@ static void do_layer_brush_task_cb_ex(void *__restrict userdata,
const int vi = vd.index;
float *disp_factor;
if (use_persistent_base) {
- disp_factor = &ss->layer_base[vi].disp;
+ disp_factor = &ss->persistent_base[vi].disp;
}
else {
disp_factor = &ss->cache->layer_displacement_factor[vi];
@@ -4153,9 +4213,9 @@ static void do_layer_brush_task_cb_ex(void *__restrict userdata,
float normal[3];
if (use_persistent_base) {
- copy_v3_v3(normal, ss->layer_base[vi].no);
+ sculpt_vertex_persistent_normal_get(ss, vi, normal);
mul_v3_fl(normal, brush->height);
- madd_v3_v3v3fl(final_co, ss->layer_base[vi].co, normal, *disp_factor);
+ madd_v3_v3v3fl(final_co, sculpt_vertex_persistent_co_get(ss, vi), normal, *disp_factor);
}
else {
normal_short_to_float_v3(normal, orig_data.no);
@@ -4196,7 +4256,7 @@ static void do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(0, totnode, &data, do_layer_brush_task_cb_ex, &settings);
}
@@ -4263,7 +4323,7 @@ static void do_inflate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(0, totnode, &data, do_inflate_brush_task_cb_ex, &settings);
}
@@ -4388,7 +4448,7 @@ static void do_flatten_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(0, totnode, &data, do_flatten_brush_task_cb_ex, &settings);
}
@@ -4539,7 +4599,7 @@ static void do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
ClaySampleData csd = {{0}};
TaskParallelSettings sample_settings;
- BKE_pbvh_parallel_range_settings(&sample_settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&sample_settings, true, totnode);
sample_settings.func_reduce = calc_clay_surface_reduce;
sample_settings.userdata_chunk = &csd;
sample_settings.userdata_chunk_size = sizeof(ClaySampleData);
@@ -4570,7 +4630,7 @@ static void do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(0, totnode, &data, do_clay_brush_task_cb_ex, &settings);
}
@@ -4677,6 +4737,17 @@ static void do_clay_strips_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int t
mul_v3_fl(temp, displace);
add_v3_v3(area_co, temp);
+ /* Clay Strips uses a cube test with falloff in the XY axis (not in Z) and a plane to deform the
+ * vertices. When in Add mode, vertices that are below the plane and inside the cube are move
+ * towards the plane. In this situation, there may be cases where a vertex is outside the cube
+ * but below the plane, so won't be deformed, causing artifacts. In order to prevent these
+ * artifacts, this displaces the test cube space in relation to the plane in order to
+ * deform more vertices that may be below it. */
+ /* The 0.7 and 1.25 factors are arbitrary and don't have any relation between them, they were set
+ * by doing multiple tests using the default "Clay Strips" brush preset. */
+ float area_co_displaced[3];
+ madd_v3_v3v3fl(area_co_displaced, area_co, area_no, -radius * 0.7f);
+
/* Init brush local space matrix. */
cross_v3_v3v3(mat[0], area_no, ss->cache->grab_delta_symmetry);
mat[0][3] = 0.0f;
@@ -4684,13 +4755,19 @@ static void do_clay_strips_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int t
mat[1][3] = 0.0f;
copy_v3_v3(mat[2], area_no);
mat[2][3] = 0.0f;
- copy_v3_v3(mat[3], ss->cache->location);
+ copy_v3_v3(mat[3], area_co_displaced);
mat[3][3] = 1.0f;
normalize_m4(mat);
/* Scale brush local space matrix. */
scale_m4_fl(scale, ss->cache->radius);
mul_m4_m4m4(tmat, mat, scale);
+
+ /* Deform the local space in Z to scale the test cube. As the test cube does not have falloff in
+ * Z this does not produce artifacts in the falloff cube and allows to deform extra vertices
+ * during big deformation while keeping the surface as uniform as possible. */
+ mul_v3_fl(tmat[2], 1.25f);
+
invert_m4_m4(mat, tmat);
SculptThreadedTaskData data = {
@@ -4704,7 +4781,7 @@ static void do_clay_strips_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int t
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(0, totnode, &data, do_clay_strips_brush_task_cb_ex, &settings);
}
@@ -4798,7 +4875,7 @@ static void do_fill_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(0, totnode, &data, do_fill_brush_task_cb_ex, &settings);
}
@@ -4891,7 +4968,7 @@ static void do_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(0, totnode, &data, do_scrape_brush_task_cb_ex, &settings);
}
@@ -5064,7 +5141,7 @@ static void do_clay_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(0, totnode, &data, do_clay_thumb_brush_task_cb_ex, &settings);
}
@@ -5136,7 +5213,7 @@ static void do_gravity(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, fl
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(0, totnode, &data, do_gravity_task_cb_ex, &settings);
}
@@ -5255,23 +5332,23 @@ static void do_brush_action_task_cb(void *__restrict userdata,
/* Face Sets modifications do a single undo push */
if (data->brush->sculpt_tool == SCULPT_TOOL_DRAW_FACE_SETS) {
+ BKE_pbvh_node_mark_redraw(data->nodes[n]);
/* Draw face sets in smooth mode moves the vertices. */
if (ss->cache->alt_smooth) {
SCULPT_undo_push_node(data->ob, data->nodes[n], SCULPT_UNDO_COORDS);
BKE_pbvh_node_mark_update(data->nodes[n]);
}
}
- else {
- SCULPT_undo_push_node(data->ob,
- data->nodes[n],
- data->brush->sculpt_tool == SCULPT_TOOL_MASK ? SCULPT_UNDO_MASK :
- SCULPT_UNDO_COORDS);
- }
-
- if (data->brush->sculpt_tool == SCULPT_TOOL_MASK) {
+ else if (data->brush->sculpt_tool == SCULPT_TOOL_MASK) {
+ SCULPT_undo_push_node(data->ob, data->nodes[n], SCULPT_UNDO_MASK);
BKE_pbvh_node_mark_update_mask(data->nodes[n]);
}
+ else if (ELEM(data->brush->sculpt_tool, SCULPT_TOOL_PAINT, SCULPT_TOOL_SMEAR)) {
+ SCULPT_undo_push_node(data->ob, data->nodes[n], SCULPT_UNDO_COLOR);
+ BKE_pbvh_node_mark_update_color(data->nodes[n]);
+ }
else {
+ SCULPT_undo_push_node(data->ob, data->nodes[n], SCULPT_UNDO_COORDS);
BKE_pbvh_node_mark_update(data->nodes[n]);
}
}
@@ -5282,7 +5359,17 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe
int totnode;
PBVHNode **nodes;
- /* Build a list of all nodes that are potentially within the brush's area of influence. */
+ /* Check for unsupported features. */
+ PBVHType type = BKE_pbvh_type(ss->pbvh);
+ if (brush->sculpt_tool == SCULPT_TOOL_PAINT && type != PBVH_FACES) {
+ return;
+ }
+
+ if (brush->sculpt_tool == SCULPT_TOOL_SMEAR && type != PBVH_FACES) {
+ return;
+ }
+
+ /* Build a list of all nodes that are potentially within the brush's area of influence */
/* These brushes need to update all nodes as they are not constrained by the brush radius */
/* Elastic deform needs all nodes to avoid artifacts as the effect of the brush is not
@@ -5322,7 +5409,14 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe
* and the number of nodes under the brush influence. */
if (brush->sculpt_tool == SCULPT_TOOL_DRAW_FACE_SETS && ss->cache->first_time &&
ss->cache->mirror_symmetry_pass == 0 && !ss->cache->alt_smooth) {
- SCULPT_undo_push_node(ob, NULL, SCULPT_UNDO_FACE_SETS);
+
+ /* Dyntopo does not support Face Sets data, so it can't store/restore it from undo. */
+ /* TODO (pablodp606): This check should be done in the undo code and not here, but the rest of
+ * the sculpt code is not checking for unsupported undo types that may return a null node. */
+ if (BKE_pbvh_type(ss->pbvh) != PBVH_BMESH) {
+ SCULPT_undo_push_node(ob, NULL, SCULPT_UNDO_FACE_SETS);
+ }
+
if (ss->cache->invert) {
/* When inverting the brush, pick the paint face mask ID from the mesh. */
ss->cache->paint_face_set = SCULPT_active_face_set_get(ss);
@@ -5345,7 +5439,7 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(0, totnode, &task_data, do_brush_action_task_cb, &settings);
if (sculpt_brush_needs_normal(ss, brush)) {
@@ -5464,6 +5558,12 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe
case SCULPT_TOOL_DRAW_FACE_SETS:
SCULPT_do_draw_face_sets_brush(sd, ob, nodes, totnode);
break;
+ case SCULPT_TOOL_PAINT:
+ SCULPT_do_paint_brush(sd, ob, nodes, totnode);
+ break;
+ case SCULPT_TOOL_SMEAR:
+ SCULPT_do_smear_brush(sd, ob, nodes, totnode);
+ break;
}
if (!ELEM(brush->sculpt_tool, SCULPT_TOOL_SMOOTH, SCULPT_TOOL_MASK) &&
@@ -5602,7 +5702,7 @@ static void sculpt_combine_proxies(Sculpt *sd, Object *ob)
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(0, totnode, &data, sculpt_combine_proxies_task_cb, &settings);
}
@@ -5690,7 +5790,7 @@ void SCULPT_flush_stroke_deform(Sculpt *sd, Object *ob, bool is_proxy_used)
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(0, totnode, &data, SCULPT_flush_stroke_deform_task_cb, &settings);
if (vertCos) {
@@ -5991,6 +6091,10 @@ static const char *sculpt_tool_name(Sculpt *sd)
return "Cloth Brush";
case SCULPT_TOOL_DRAW_FACE_SETS:
return "Draw Face Sets";
+ case SCULPT_TOOL_PAINT:
+ return "Paint Brush";
+ case SCULPT_TOOL_SMEAR:
+ return "Smear Brush";
}
return "Sculpting";
@@ -6005,6 +6109,7 @@ void SCULPT_cache_free(StrokeCache *cache)
MEM_SAFE_FREE(cache->dial);
MEM_SAFE_FREE(cache->surface_smooth_laplacian_disp);
MEM_SAFE_FREE(cache->layer_displacement_factor);
+ MEM_SAFE_FREE(cache->prev_colors);
if (cache->pose_ik_chain) {
SCULPT_pose_ik_chain_free(cache->pose_ik_chain);
@@ -6119,7 +6224,11 @@ static void sculpt_update_cache_invariants(
cache->saved_mask_brush_tool = brush->mask_tool;
brush->mask_tool = BRUSH_MASK_SMOOTH;
}
- else if (ELEM(brush->sculpt_tool, SCULPT_TOOL_SLIDE_RELAX, SCULPT_TOOL_DRAW_FACE_SETS)) {
+ else if (ELEM(brush->sculpt_tool,
+ SCULPT_TOOL_SLIDE_RELAX,
+ SCULPT_TOOL_DRAW_FACE_SETS,
+ SCULPT_TOOL_PAINT,
+ SCULPT_TOOL_SMEAR)) {
/* Do nothing, this tool has its own smooth mode. */
}
else {
@@ -6266,6 +6375,7 @@ static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Bru
int tool = brush->sculpt_tool;
if (ELEM(tool,
+ SCULPT_TOOL_PAINT,
SCULPT_TOOL_GRAB,
SCULPT_TOOL_ELASTIC_DEFORM,
SCULPT_TOOL_CLOTH,
@@ -6519,7 +6629,7 @@ static bool sculpt_needs_connectivity_info(const Sculpt *sd,
((brush->sculpt_tool == SCULPT_TOOL_MASK) && (brush->mask_tool == BRUSH_MASK_SMOOTH)) ||
(brush->sculpt_tool == SCULPT_TOOL_POSE) ||
(brush->sculpt_tool == SCULPT_TOOL_SLIDE_RELAX) ||
- (brush->sculpt_tool == SCULPT_TOOL_CLOTH) ||
+ (brush->sculpt_tool == SCULPT_TOOL_CLOTH) || (brush->sculpt_tool == SCULPT_TOOL_SMEAR) ||
(brush->sculpt_tool == SCULPT_TOOL_DRAW_FACE_SETS));
}
@@ -6533,7 +6643,7 @@ void SCULPT_stroke_modifiers_check(const bContext *C, Object *ob, const Brush *b
if (ss->shapekey_active || ss->deform_modifiers_active ||
(!BKE_sculptsession_use_pbvh_draw(ob, v3d) && need_pmap)) {
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
- BKE_sculpt_update_object_for_edit(depsgraph, ob, need_pmap, false);
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, need_pmap, false, false);
}
}
@@ -6877,7 +6987,7 @@ static void sculpt_brush_stroke_init(bContext *C, wmOperator *op)
SculptSession *ss = CTX_data_active_object(C)->sculpt;
Brush *brush = BKE_paint_brush(&sd->paint);
int mode = RNA_enum_get(op->ptr, "mode");
- bool is_smooth;
+ bool is_smooth, needs_colors;
bool need_mask = false;
if (brush->sculpt_tool == SCULPT_TOOL_MASK) {
@@ -6892,7 +7002,8 @@ static void sculpt_brush_stroke_init(bContext *C, wmOperator *op)
sculpt_brush_init_tex(scene, sd, ss);
is_smooth = sculpt_needs_connectivity_info(sd, brush, ss, mode);
- BKE_sculpt_update_object_for_edit(depsgraph, ob, is_smooth, need_mask);
+ needs_colors = ELEM(brush->sculpt_tool, SCULPT_TOOL_PAINT, SCULPT_TOOL_SMEAR);
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, is_smooth, need_mask, needs_colors);
}
static void sculpt_restore_mesh(Sculpt *sd, Object *ob)
@@ -7035,12 +7146,19 @@ void SCULPT_flush_update_done(const bContext *C, Object *ob, SculptUpdateType up
if (update_flags & SCULPT_UPDATE_COORDS) {
BKE_pbvh_update_bounds(ss->pbvh, PBVH_UpdateOriginalBB);
+
+ /* Coordinates were modified, so fake neighbors are not longer valid. */
+ SCULPT_fake_neighbors_free(ob);
}
if (update_flags & SCULPT_UPDATE_MASK) {
BKE_pbvh_update_vertex_data(ss->pbvh, PBVH_UpdateMask);
}
+ if (update_flags & SCULPT_UPDATE_COLOR) {
+ BKE_pbvh_update_vertex_data(ss->pbvh, PBVH_UpdateColor);
+ }
+
if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
BKE_pbvh_bmesh_after_stroke(ss->pbvh);
}
@@ -7155,6 +7273,9 @@ static void sculpt_stroke_update_step(bContext *C,
if (brush->sculpt_tool == SCULPT_TOOL_MASK) {
SCULPT_flush_update_step(C, SCULPT_UPDATE_MASK);
}
+ else if (ELEM(brush->sculpt_tool, SCULPT_TOOL_PAINT, SCULPT_TOOL_SMEAR)) {
+ SCULPT_flush_update_step(C, SCULPT_UPDATE_COLOR);
+ }
else {
SCULPT_flush_update_step(C, SCULPT_UPDATE_COORDS);
}
@@ -7192,7 +7313,11 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str
if (brush->sculpt_tool == SCULPT_TOOL_MASK) {
brush->mask_tool = ss->cache->saved_mask_brush_tool;
}
- else if (ELEM(brush->sculpt_tool, SCULPT_TOOL_SLIDE_RELAX, SCULPT_TOOL_DRAW_FACE_SETS)) {
+ else if (ELEM(brush->sculpt_tool,
+ SCULPT_TOOL_SLIDE_RELAX,
+ SCULPT_TOOL_DRAW_FACE_SETS,
+ SCULPT_TOOL_PAINT,
+ SCULPT_TOOL_SMEAR)) {
/* Do nothing. */
}
else {
@@ -7208,6 +7333,7 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str
SCULPT_automasking_end(ob);
}
+ BKE_pbvh_node_color_buffer_free(ss->pbvh);
SCULPT_cache_free(ss->cache);
ss->cache = NULL;
@@ -7346,18 +7472,18 @@ static int sculpt_set_persistent_base_exec(bContext *C, wmOperator *UNUSED(op))
if (ss) {
SCULPT_vertex_random_access_init(ss);
- BKE_sculpt_update_object_for_edit(depsgraph, ob, false, false);
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, false, false, false);
- MEM_SAFE_FREE(ss->layer_base);
+ MEM_SAFE_FREE(ss->persistent_base);
const int totvert = SCULPT_vertex_count_get(ss);
- ss->layer_base = MEM_mallocN(sizeof(SculptLayerPersistentBase) * totvert,
- "layer persistent base");
+ ss->persistent_base = MEM_mallocN(sizeof(SculptPersistentBase) * totvert,
+ "layer persistent base");
for (int i = 0; i < totvert; i++) {
- copy_v3_v3(ss->layer_base[i].co, SCULPT_vertex_co_get(ss, i));
- SCULPT_vertex_normal_get(ss, i, ss->layer_base[i].no);
- ss->layer_base[i].disp = 0.0f;
+ copy_v3_v3(ss->persistent_base[i].co, SCULPT_vertex_co_get(ss, i));
+ SCULPT_vertex_normal_get(ss, i, ss->persistent_base[i].no);
+ ss->persistent_base[i].disp = 0.0f;
}
}
@@ -7548,7 +7674,7 @@ static void sculpt_init_session(Depsgraph *depsgraph, Scene *scene, Object *ob)
ob->sculpt = MEM_callocN(sizeof(SculptSession), "sculpt session");
ob->sculpt->mode_type = OB_MODE_SCULPT;
- BKE_sculpt_update_object_for_edit(depsgraph, ob, false, false);
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, false, false, false);
/* Here we can detect geometry that was just added to Sculpt Mode as it has the
* SCULPT_FACE_SET_NONE assigned, so we can create a new Face Set for it. */
@@ -7834,7 +7960,7 @@ void SCULPT_geometry_preview_lines_update(bContext *C, SculptSession *ss, float
return;
}
- BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true);
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);
if (!ss->pmap) {
return;
@@ -7886,6 +8012,417 @@ void SCULPT_geometry_preview_lines_update(bContext *C, SculptSession *ss, float
ss->preview_vert_index_count = totpoints;
}
+static int vertex_to_loop_colors_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Object *ob = CTX_data_active_object(C);
+
+ ID *data;
+ data = ob->data;
+ if (data && ID_IS_LINKED(data)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ if (ob->type != OB_MESH) {
+ return OPERATOR_CANCELLED;
+ }
+
+ Mesh *mesh = ob->data;
+
+ const int mloopcol_layer_n = CustomData_get_active_layer(&mesh->ldata, CD_MLOOPCOL);
+ if (mloopcol_layer_n == -1) {
+ return OPERATOR_CANCELLED;
+ }
+ MLoopCol *loopcols = CustomData_get_layer_n(&mesh->ldata, CD_MLOOPCOL, mloopcol_layer_n);
+
+ const int MPropCol_layer_n = CustomData_get_active_layer(&mesh->vdata, CD_PROP_COLOR);
+ if (MPropCol_layer_n == -1) {
+ return OPERATOR_CANCELLED;
+ }
+ MPropCol *vertcols = CustomData_get_layer_n(&mesh->vdata, CD_PROP_COLOR, MPropCol_layer_n);
+
+ MLoop *loops = CustomData_get_layer(&mesh->ldata, CD_MLOOP);
+ MPoly *polys = CustomData_get_layer(&mesh->pdata, CD_MPOLY);
+
+ for (int i = 0; i < mesh->totpoly; i++) {
+ MPoly *c_poly = &polys[i];
+ for (int j = 0; j < c_poly->totloop; j++) {
+ int loop_index = c_poly->loopstart + j;
+ MLoop *c_loop = &loops[c_poly->loopstart + j];
+ loopcols[loop_index].r = (char)(vertcols[c_loop->v].color[0] * 255);
+ loopcols[loop_index].g = (char)(vertcols[c_loop->v].color[1] * 255);
+ loopcols[loop_index].b = (char)(vertcols[c_loop->v].color[2] * 255);
+ loopcols[loop_index].a = (char)(vertcols[c_loop->v].color[3] * 255);
+ }
+ }
+
+ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
+
+ return OPERATOR_FINISHED;
+}
+
+static void SCULPT_OT_vertex_to_loop_colors(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Sculpt Vertex Color to Vertex Color";
+ ot->description = "Copy the Sculpt Vertex Color to a regular color layer";
+ ot->idname = "SCULPT_OT_vertex_to_loop_colors";
+
+ /* api callbacks */
+ ot->poll = SCULPT_mode_poll;
+ ot->exec = vertex_to_loop_colors_exec;
+
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+static int loop_to_vertex_colors_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Object *ob = CTX_data_active_object(C);
+
+ ID *data;
+ data = ob->data;
+ if (data && ID_IS_LINKED(data)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ if (ob->type != OB_MESH) {
+ return OPERATOR_CANCELLED;
+ }
+
+ Mesh *mesh = ob->data;
+
+ const int mloopcol_layer_n = CustomData_get_active_layer(&mesh->ldata, CD_MLOOPCOL);
+ if (mloopcol_layer_n == -1) {
+ return OPERATOR_CANCELLED;
+ }
+ MLoopCol *loopcols = CustomData_get_layer_n(&mesh->ldata, CD_MLOOPCOL, mloopcol_layer_n);
+
+ const int MPropCol_layer_n = CustomData_get_active_layer(&mesh->vdata, CD_PROP_COLOR);
+ if (MPropCol_layer_n == -1) {
+ return OPERATOR_CANCELLED;
+ }
+ MPropCol *vertcols = CustomData_get_layer_n(&mesh->vdata, CD_PROP_COLOR, MPropCol_layer_n);
+
+ MLoop *loops = CustomData_get_layer(&mesh->ldata, CD_MLOOP);
+ MPoly *polys = CustomData_get_layer(&mesh->pdata, CD_MPOLY);
+
+ for (int i = 0; i < mesh->totpoly; i++) {
+ MPoly *c_poly = &polys[i];
+ for (int j = 0; j < c_poly->totloop; j++) {
+ int loop_index = c_poly->loopstart + j;
+ MLoop *c_loop = &loops[c_poly->loopstart + j];
+ vertcols[c_loop->v].color[0] = (loopcols[loop_index].r / 255.0f);
+ vertcols[c_loop->v].color[1] = (loopcols[loop_index].g / 255.0f);
+ vertcols[c_loop->v].color[2] = (loopcols[loop_index].b / 255.0f);
+ vertcols[c_loop->v].color[3] = (loopcols[loop_index].a / 255.0f);
+ }
+ }
+
+ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
+
+ return OPERATOR_FINISHED;
+}
+
+static void SCULPT_OT_loop_to_vertex_colors(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Vertex Color to Sculpt Vertex Color";
+ ot->description = "Copy the active loop color layer to the vertex color";
+ ot->idname = "SCULPT_OT_loop_to_vertex_colors";
+
+ /* api callbacks */
+ ot->poll = SCULPT_mode_poll;
+ ot->exec = loop_to_vertex_colors_exec;
+
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+static int sculpt_sample_color_invoke(bContext *C,
+ wmOperator *UNUSED(op),
+ const wmEvent *UNUSED(e))
+{
+ Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
+ Scene *scene = CTX_data_scene(C);
+ Object *ob = CTX_data_active_object(C);
+ Brush *brush = BKE_paint_brush(&sd->paint);
+ SculptSession *ss = ob->sculpt;
+ int active_vertex = SCULPT_active_vertex_get(ss);
+ const float *active_vertex_color = SCULPT_vertex_color_get(ss, active_vertex);
+ if (!active_vertex_color) {
+ return OPERATOR_CANCELLED;
+ }
+
+ float color_srgb[3];
+ copy_v3_v3(color_srgb, active_vertex_color);
+ IMB_colormanagement_scene_linear_to_srgb_v3(color_srgb);
+ BKE_brush_color_set(scene, brush, color_srgb);
+ BKE_brush_alpha_set(scene, brush, active_vertex_color[3]);
+
+ WM_event_add_notifier(C, NC_BRUSH | NA_EDITED, brush);
+
+ return OPERATOR_FINISHED;
+}
+
+static void SCULPT_OT_sample_color(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Sample color";
+ ot->idname = "SCULPT_OT_sample_color";
+ ot->description = "Sample the vertex color of the active vertex";
+
+ /* api callbacks */
+ ot->invoke = sculpt_sample_color_invoke;
+ ot->poll = SCULPT_mode_poll;
+
+ ot->flag = OPTYPE_REGISTER;
+}
+
+/* Fake Neighbors. */
+/* This allows the sculpt tools to work on meshes with multiple connected components as they had
+ * only one connected component. When initialized and enabled, the sculpt API will return extra
+ * connectivity neighbors that are not in the real mesh. These neighbors are calculated for each
+ * vertex using the minimun distance to a vertex that is in a different connected component. */
+
+/* The fake neighbors first need to be ensured to be initialized.
+ * After that tools which needs fake neighbors functionality need to
+ * temporarily enable it:
+ *
+ * void my_awesome_sculpt_tool() {
+ * SCULPT_fake_neighbors_ensure(sd, object, brush->disconnected_distance_max);
+ * SCULPT_fake_neighbors_enable(ob);
+ *
+ * ... Logic of the tool ...
+ * SCULPT_fake_neighbors_disable(ob);
+ * }
+ *
+ * Such approach allows to keep all the connectivity information ready for reuse
+ * (withouy having lag prior to every stroke), but also makes it so the affect
+ * is localized to a specific brushes and tools only. */
+
+enum {
+ SCULPT_TOPOLOGY_ID_NONE,
+ SCULPT_TOPOLOGY_ID_DEFAULT,
+};
+
+static int SCULPT_vertex_get_connected_component(SculptSession *ss, int index)
+{
+ if (ss->vertex_info.connected_component) {
+ return ss->vertex_info.connected_component[index];
+ }
+ return SCULPT_TOPOLOGY_ID_DEFAULT;
+}
+
+static void SCULPT_fake_neighbor_init(SculptSession *ss, const float max_dist)
+{
+ const int totvert = SCULPT_vertex_count_get(ss);
+ ss->fake_neighbors.fake_neighbor_index = MEM_malloc_arrayN(
+ totvert, sizeof(int), "fake neighbor");
+ for (int i = 0; i < totvert; i++) {
+ ss->fake_neighbors.fake_neighbor_index[i] = FAKE_NEIGHBOR_NONE;
+ }
+
+ ss->fake_neighbors.current_max_distance = max_dist;
+}
+
+static void SCULPT_fake_neighbor_add(SculptSession *ss, int v_index_a, int v_index_b)
+{
+ if (ss->fake_neighbors.fake_neighbor_index[v_index_a] == FAKE_NEIGHBOR_NONE) {
+ ss->fake_neighbors.fake_neighbor_index[v_index_a] = v_index_b;
+ ss->fake_neighbors.fake_neighbor_index[v_index_b] = v_index_a;
+ }
+}
+
+static void sculpt_pose_fake_neighbors_free(SculptSession *ss)
+{
+ MEM_SAFE_FREE(ss->fake_neighbors.fake_neighbor_index);
+}
+
+typedef struct NearestVertexFakeNeighborTLSData {
+ int nearest_vertex_index;
+ float nearest_vertex_distance_squared;
+ int current_topology_id;
+} NearestVertexFakeNeighborTLSData;
+
+static void do_fake_neighbor_search_task_cb(void *__restrict userdata,
+ const int n,
+ const TaskParallelTLS *__restrict tls)
+{
+ SculptThreadedTaskData *data = userdata;
+ SculptSession *ss = data->ob->sculpt;
+ NearestVertexFakeNeighborTLSData *nvtd = tls->userdata_chunk;
+ PBVHVertexIter vd;
+
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
+ {
+ int vd_topology_id = SCULPT_vertex_get_connected_component(ss, vd.index);
+ if (vd_topology_id != nvtd->current_topology_id &&
+ ss->fake_neighbors.fake_neighbor_index[vd.index] == FAKE_NEIGHBOR_NONE) {
+ float distance_squared = len_squared_v3v3(vd.co, data->nearest_vertex_search_co);
+ if (distance_squared < nvtd->nearest_vertex_distance_squared &&
+ distance_squared < data->max_distance_squared) {
+ nvtd->nearest_vertex_index = vd.index;
+ nvtd->nearest_vertex_distance_squared = distance_squared;
+ }
+ }
+ }
+ BKE_pbvh_vertex_iter_end;
+}
+
+static void fake_neighbor_search_reduce(const void *__restrict UNUSED(userdata),
+ void *__restrict chunk_join,
+ void *__restrict chunk)
+{
+ NearestVertexFakeNeighborTLSData *join = chunk_join;
+ NearestVertexFakeNeighborTLSData *nvtd = chunk;
+ if (join->nearest_vertex_index == -1) {
+ join->nearest_vertex_index = nvtd->nearest_vertex_index;
+ join->nearest_vertex_distance_squared = nvtd->nearest_vertex_distance_squared;
+ }
+ else if (nvtd->nearest_vertex_distance_squared < join->nearest_vertex_distance_squared) {
+ join->nearest_vertex_index = nvtd->nearest_vertex_index;
+ join->nearest_vertex_distance_squared = nvtd->nearest_vertex_distance_squared;
+ }
+}
+
+static int SCULPT_fake_neighbor_search(Sculpt *sd, Object *ob, const int index, float max_distance)
+{
+ SculptSession *ss = ob->sculpt;
+ PBVHNode **nodes = NULL;
+ int totnode;
+ SculptSearchSphereData data = {
+ .ss = ss,
+ .sd = sd,
+ .radius_squared = max_distance * max_distance,
+ .original = false,
+ .center = SCULPT_vertex_co_get(ss, index),
+ };
+ BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, &totnode);
+
+ if (totnode == 0) {
+ return -1;
+ }
+
+ SculptThreadedTaskData task_data = {
+ .sd = sd,
+ .ob = ob,
+ .nodes = nodes,
+ .max_distance_squared = max_distance * max_distance,
+ };
+
+ copy_v3_v3(task_data.nearest_vertex_search_co, SCULPT_vertex_co_get(ss, index));
+
+ NearestVertexFakeNeighborTLSData nvtd;
+ nvtd.nearest_vertex_index = -1;
+ nvtd.nearest_vertex_distance_squared = FLT_MAX;
+ nvtd.current_topology_id = SCULPT_vertex_get_connected_component(ss, index);
+
+ TaskParallelSettings settings;
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
+ settings.func_reduce = fake_neighbor_search_reduce;
+ settings.userdata_chunk = &nvtd;
+ settings.userdata_chunk_size = sizeof(NearestVertexFakeNeighborTLSData);
+ BLI_task_parallel_range(0, totnode, &task_data, do_fake_neighbor_search_task_cb, &settings);
+
+ MEM_SAFE_FREE(nodes);
+
+ return nvtd.nearest_vertex_index;
+}
+
+typedef struct SculptTopologyIDFloodFillData {
+ int next_id;
+} SculptTopologyIDFloodFillData;
+
+static bool SCULPT_connected_components_floodfill_cb(
+ SculptSession *ss, int from_v, int to_v, bool UNUSED(is_duplicate), void *userdata)
+{
+ SculptTopologyIDFloodFillData *data = userdata;
+ ss->vertex_info.connected_component[from_v] = data->next_id;
+ ss->vertex_info.connected_component[to_v] = data->next_id;
+ return true;
+}
+
+static void sculpt_connected_components_ensure(Object *ob)
+{
+ SculptSession *ss = ob->sculpt;
+
+ /* Topology IDs already initialized. They only need to be recalculated when the PBVH is rebuild.
+ */
+ if (ss->vertex_info.connected_component) {
+ return;
+ }
+
+ const int totvert = SCULPT_vertex_count_get(ss);
+ ss->vertex_info.connected_component = MEM_malloc_arrayN(totvert, sizeof(int), "topology ID");
+
+ for (int i = 0; i < totvert; i++) {
+ ss->vertex_info.connected_component[i] = SCULPT_TOPOLOGY_ID_NONE;
+ }
+
+ int next_id = 0;
+ for (int i = 0; i < totvert; i++) {
+ if (ss->vertex_info.connected_component[i] == SCULPT_TOPOLOGY_ID_NONE) {
+ SculptFloodFill flood;
+ SCULPT_floodfill_init(ss, &flood);
+ SCULPT_floodfill_add_initial(&flood, i);
+ SculptTopologyIDFloodFillData data;
+ data.next_id = next_id;
+ SCULPT_floodfill_execute(ss, &flood, SCULPT_connected_components_floodfill_cb, &data);
+ SCULPT_floodfill_free(&flood);
+ next_id++;
+ }
+ }
+}
+
+void SCULPT_fake_neighbors_ensure(Sculpt *sd, Object *ob, const float max_dist)
+{
+ SculptSession *ss = ob->sculpt;
+ const int totvert = SCULPT_vertex_count_get(ss);
+
+ /* Fake neighbors were already initialized with the same distance, so no need to be recalculated.
+ */
+ if (ss->fake_neighbors.fake_neighbor_index &&
+ ss->fake_neighbors.current_max_distance == max_dist) {
+ return;
+ }
+
+ sculpt_connected_components_ensure(ob);
+ SCULPT_fake_neighbor_init(ss, max_dist);
+
+ for (int i = 0; i < totvert; i++) {
+ const int from_v = i;
+
+ /* This vertex does not have a fake neighbor yet, seach one for it. */
+ if (ss->fake_neighbors.fake_neighbor_index[from_v] == FAKE_NEIGHBOR_NONE) {
+ const int to_v = SCULPT_fake_neighbor_search(sd, ob, from_v, max_dist);
+ if (to_v != -1) {
+ /* Add the fake neighbor if available. */
+ SCULPT_fake_neighbor_add(ss, from_v, to_v);
+ }
+ }
+ }
+}
+
+void SCULPT_fake_neighbors_enable(Object *ob)
+{
+ SculptSession *ss = ob->sculpt;
+ BLI_assert(ss->fake_neighbors.fake_neighbor_index != NULL);
+ ss->fake_neighbors.use_fake_neighbors = true;
+}
+
+void SCULPT_fake_neighbors_disable(Object *ob)
+{
+ SculptSession *ss = ob->sculpt;
+ BLI_assert(ss->fake_neighbors.fake_neighbor_index != NULL);
+ ss->fake_neighbors.use_fake_neighbors = false;
+}
+
+void SCULPT_fake_neighbors_free(Object *ob)
+{
+ SculptSession *ss = ob->sculpt;
+ sculpt_pose_fake_neighbors_free(ss);
+}
+
void ED_operatortypes_sculpt(void)
{
WM_operatortype_append(SCULPT_OT_brush_stroke);
@@ -7908,4 +8445,8 @@ void ED_operatortypes_sculpt(void)
WM_operatortype_append(SCULPT_OT_face_sets_init);
WM_operatortype_append(SCULPT_OT_cloth_filter);
WM_operatortype_append(SCULPT_OT_face_sets_edit);
+ WM_operatortype_append(SCULPT_OT_sample_color);
+ WM_operatortype_append(SCULPT_OT_loop_to_vertex_colors);
+ WM_operatortype_append(SCULPT_OT_vertex_to_loop_colors);
+ WM_operatortype_append(SCULPT_OT_color_filter);
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_cloth.c b/source/blender/editors/sculpt_paint/sculpt_cloth.c
index 7776af11a77..c821685e8b1 100644
--- a/source/blender/editors/sculpt_paint/sculpt_cloth.c
+++ b/source/blender/editors/sculpt_paint/sculpt_cloth.c
@@ -25,7 +25,7 @@
#include "BLI_blenlib.h"
#include "BLI_dial_2d.h"
-#include "BLI_ghash.h"
+#include "BLI_edgehash.h"
#include "BLI_gsqueue.h"
#include "BLI_hash.h"
#include "BLI_math.h"
@@ -106,25 +106,11 @@
#define CLOTH_MAX_CONSTRAINTS_PER_VERTEX 1024
#define CLOTH_SIMULATION_TIME_STEP 0.01f
-static void cloth_brush_constraint_key_get(int r_key[2], const int v1, const int v2)
-{
- if (v1 < v2) {
- r_key[0] = v1;
- r_key[1] = v2;
- }
- else {
- r_key[0] = v2;
- r_key[1] = v1;
- }
-}
-
static bool cloth_brush_sim_has_length_constraint(SculptClothSimulation *cloth_sim,
const int v1,
const int v2)
{
- int constraint[2];
- cloth_brush_constraint_key_get(constraint, v1, v2);
- return BLI_gset_haskey(cloth_sim->created_length_constraints, constraint);
+ return BLI_edgeset_haskey(cloth_sim->created_length_constraints, v1, v2);
}
static void cloth_brush_add_length_constraint(SculptSession *ss,
@@ -149,9 +135,7 @@ static void cloth_brush_add_length_constraint(SculptSession *ss,
}
/* Add the constraint to the GSet to avoid creating it again. */
- int constraint[2];
- cloth_brush_constraint_key_get(constraint, v1, v2);
- BLI_gset_add(cloth_sim->created_length_constraints, constraint);
+ BLI_edgeset_add(cloth_sim->created_length_constraints, v1, v2);
}
static void do_cloth_brush_build_constraints_task_cb_ex(
@@ -472,8 +456,7 @@ static void cloth_brush_build_nodes_constraints(Sculpt *sd,
TaskParallelSettings settings;
BKE_pbvh_parallel_range_settings(&settings, false, totnode);
- cloth_sim->created_length_constraints = BLI_gset_new(
- BLI_ghashutil_inthash_v2_p, BLI_ghashutil_inthash_v2_cmp, "created length constraints");
+ cloth_sim->created_length_constraints = BLI_edgeset_new("created length constraints");
SculptThreadedTaskData build_constraints_data = {
.sd = sd,
@@ -487,7 +470,7 @@ static void cloth_brush_build_nodes_constraints(Sculpt *sd,
BLI_task_parallel_range(
0, totnode, &build_constraints_data, do_cloth_brush_build_constraints_task_cb_ex, &settings);
- BLI_gset_free(cloth_sim->created_length_constraints, NULL);
+ BLI_edgeset_free(cloth_sim->created_length_constraints);
}
static void cloth_brush_satisfy_constraints(SculptSession *ss,
@@ -564,7 +547,7 @@ static void cloth_brush_do_simulation_step(
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(
0, totnode, &solve_simulation_data, do_cloth_brush_solve_simulation_task_cb_ex, &settings);
}
@@ -639,7 +622,7 @@ static void cloth_brush_apply_brush_foces(Sculpt *sd, Object *ob, PBVHNode **nod
}
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(
0, totnode, &apply_forces_data, do_cloth_brush_apply_forces_task_cb_ex, &settings);
}
@@ -873,7 +856,7 @@ static int sculpt_cloth_filter_modal(bContext *C, wmOperator *op, const wmEvent
SCULPT_vertex_random_access_init(ss);
- BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true);
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);
const int totverts = SCULPT_vertex_count_get(ss);
for (int i = 0; i < totverts; i++) {
@@ -889,8 +872,7 @@ static int sculpt_cloth_filter_modal(bContext *C, wmOperator *op, const wmEvent
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(
- &settings, (sd->flags & SCULPT_USE_OPENMP), ss->filter_cache->totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode);
BLI_task_parallel_range(
0, ss->filter_cache->totnode, &data, cloth_filter_apply_forces_task_cb, &settings);
@@ -922,10 +904,10 @@ static int sculpt_cloth_filter_invoke(bContext *C, wmOperator *op, const wmEvent
SCULPT_vertex_random_access_init(ss);
/* Needs mask data to be available as it is used when solving the constraints. */
- BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true);
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);
SCULPT_undo_push_begin("Cloth filter");
- SCULPT_filter_cache_init(ob, sd);
+ SCULPT_filter_cache_init(ob, sd, SCULPT_UNDO_COORDS);
const float cloth_mass = RNA_float_get(op->ptr, "cloth_mass");
const float cloth_damping = RNA_float_get(op->ptr, "cloth_damping");
diff --git a/source/blender/editors/sculpt_paint/sculpt_detail.c b/source/blender/editors/sculpt_paint/sculpt_detail.c
index f071deaa219..463233fd6fb 100644
--- a/source/blender/editors/sculpt_paint/sculpt_detail.c
+++ b/source/blender/editors/sculpt_paint/sculpt_detail.c
@@ -181,7 +181,7 @@ static void sample_detail_voxel(bContext *C, ViewContext *vc, int mx, int my)
/* Update the active vertex. */
float mouse[2] = {mx, my};
SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false);
- BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false);
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false, false);
/* Average the edge length of the connected edges to the active vertex. */
int active_vertex = SCULPT_active_vertex_get(ss);
diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.c b/source/blender/editors/sculpt_paint/sculpt_face_set.c
index 7bb54366204..031b4f8731d 100644
--- a/source/blender/editors/sculpt_paint/sculpt_face_set.c
+++ b/source/blender/editors/sculpt_paint/sculpt_face_set.c
@@ -203,7 +203,7 @@ void SCULPT_do_draw_face_sets_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, in
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
if (ss->cache->alt_smooth) {
for (int i = 0; i < 4; i++) {
BLI_task_parallel_range(0, totnode, &data, do_relax_face_sets_brush_task_cb_ex, &settings);
@@ -269,7 +269,7 @@ static int sculpt_face_set_create_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- BKE_sculpt_update_object_for_edit(depsgraph, ob, true, mode == SCULPT_FACE_SET_MASKED);
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, true, mode == SCULPT_FACE_SET_MASKED, false);
const int tot_vert = SCULPT_vertex_count_get(ss);
float threshold = 0.5f;
@@ -630,7 +630,7 @@ static int sculpt_face_set_init_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false);
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false, false);
PBVH *pbvh = ob->sculpt->pbvh;
PBVHNode **nodes;
@@ -787,7 +787,7 @@ static int sculpt_face_sets_change_visibility_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true);
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);
const int tot_vert = SCULPT_vertex_count_get(ss);
const int mode = RNA_enum_get(op->ptr, "mode");
@@ -1083,7 +1083,7 @@ static int sculpt_face_set_edit_invoke(bContext *C, wmOperator *op, const wmEven
return OPERATOR_CANCELLED;
}
- BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false);
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false, false);
PBVH *pbvh = ob->sculpt->pbvh;
PBVHNode **nodes;
diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_color.c b/source/blender/editors/sculpt_paint/sculpt_filter_color.c
new file mode 100644
index 00000000000..5f7805af347
--- /dev/null
+++ b/source/blender/editors/sculpt_paint/sculpt_filter_color.c
@@ -0,0 +1,323 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup edsculpt
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_hash.h"
+#include "BLI_math.h"
+#include "BLI_math_color_blend.h"
+#include "BLI_task.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "BKE_brush.h"
+#include "BKE_colortools.h"
+#include "BKE_context.h"
+#include "BKE_mesh.h"
+#include "BKE_mesh_mapping.h"
+#include "BKE_object.h"
+#include "BKE_paint.h"
+#include "BKE_pbvh.h"
+#include "BKE_scene.h"
+
+#include "IMB_colormanagement.h"
+
+#include "DEG_depsgraph.h"
+
+#include "WM_api.h"
+#include "WM_message.h"
+#include "WM_toolsystem.h"
+#include "WM_types.h"
+
+#include "ED_object.h"
+#include "ED_screen.h"
+#include "ED_sculpt.h"
+#include "paint_intern.h"
+#include "sculpt_intern.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "UI_interface.h"
+
+#include "bmesh.h"
+
+#include <math.h>
+#include <stdlib.h>
+
+typedef enum eSculptColorFilterTypes {
+ COLOR_FILTER_FILL,
+ COLOR_FILTER_HUE,
+ COLOR_FILTER_SATURATION,
+ COLOR_FILTER_VALUE,
+ COLOR_FILTER_BRIGHTNESS,
+ COLOR_FILTER_CONTRAST,
+ COLOR_FILTER_RED,
+ COLOR_FILTER_GREEN,
+ COLOR_FILTER_BLUE,
+ COLOR_FILTER_SMOOTH,
+} eSculptColorFilterTypes;
+
+EnumPropertyItem prop_color_filter_types[] = {
+ {COLOR_FILTER_FILL, "FILL", 0, "Fill", "Fill with a specific color"},
+ {COLOR_FILTER_HUE, "HUE", 0, "Hue", "Change hue"},
+ {COLOR_FILTER_SATURATION, "SATURATION", 0, "Saturation", "Change saturation"},
+ {COLOR_FILTER_VALUE, "VALUE", 0, "Value", "Change value"},
+
+ {COLOR_FILTER_BRIGHTNESS, "BRIGTHNESS", 0, "Brightness", "Change brightness"},
+ {COLOR_FILTER_CONTRAST, "CONTRAST", 0, "Contrast", "Change contrast"},
+
+ {COLOR_FILTER_SMOOTH, "SMOOTH", 0, "Smooth", "Smooth colors"},
+
+ {COLOR_FILTER_RED, "RED", 0, "Red", "Change red channel"},
+ {COLOR_FILTER_GREEN, "GREEN", 0, "Green", "Change green channel"},
+ {COLOR_FILTER_BLUE, "BLUE", 0, "Blue", "Change blue channel"},
+ {0, NULL, 0, NULL, NULL},
+};
+
+static void color_filter_task_cb(void *__restrict userdata,
+ const int n,
+ const TaskParallelTLS *__restrict UNUSED(tls))
+{
+ SculptThreadedTaskData *data = userdata;
+ SculptSession *ss = data->ob->sculpt;
+
+ const int mode = data->filter_type;
+
+ SculptOrigVertData orig_data;
+ SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]);
+
+ PBVHVertexIter vd;
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
+ {
+ SCULPT_orig_vert_data_update(&orig_data, &vd);
+ float orig_color[3], final_color[4], hsv_color[3];
+ int hue;
+ float brightness, contrast, gain, delta, offset;
+ float fade = vd.mask ? *vd.mask : 0.0f;
+ fade = 1.0f - fade;
+ fade *= data->filter_strength;
+
+ copy_v3_v3(orig_color, orig_data.col);
+
+ switch (mode) {
+ case COLOR_FILTER_FILL: {
+ float fill_color_rgba[4];
+ copy_v3_v3(fill_color_rgba, data->filter_fill_color);
+ fill_color_rgba[3] = 1.0f;
+ CLAMP(fade, 0.0f, 1.0f);
+ mul_v4_fl(fill_color_rgba, fade);
+ blend_color_mix_float(final_color, orig_data.col, fill_color_rgba);
+ break;
+ }
+ case COLOR_FILTER_HUE:
+ rgb_to_hsv_v(orig_color, hsv_color);
+ hue = hsv_color[0] + fade;
+ hsv_color[0] = fabs((hsv_color[0] + fade) - hue);
+ hsv_to_rgb_v(hsv_color, final_color);
+ break;
+ case COLOR_FILTER_SATURATION:
+ rgb_to_hsv_v(orig_color, hsv_color);
+ hsv_color[1] = hsv_color[1] + fade;
+ CLAMP(hsv_color[1], 0.0f, 1.0f);
+ hsv_to_rgb_v(hsv_color, final_color);
+ break;
+ case COLOR_FILTER_VALUE:
+ rgb_to_hsv_v(orig_color, hsv_color);
+ hsv_color[2] = hsv_color[2] + fade;
+ CLAMP(hsv_color[2], 0.0f, 1.0f);
+ hsv_to_rgb_v(hsv_color, final_color);
+ break;
+ case COLOR_FILTER_RED:
+ orig_color[0] = orig_color[0] + fade;
+ CLAMP(orig_color[0], 0.0f, 1.0f);
+ copy_v3_v3(final_color, orig_color);
+ break;
+ case COLOR_FILTER_GREEN:
+ orig_color[1] = orig_color[1] + fade;
+ CLAMP(orig_color[1], 0.0f, 1.0f);
+ copy_v3_v3(final_color, orig_color);
+ break;
+ case COLOR_FILTER_BLUE:
+ orig_color[2] = orig_color[2] + fade;
+ CLAMP(orig_color[2], 0.0f, 1.0f);
+ copy_v3_v3(final_color, orig_color);
+ break;
+ case COLOR_FILTER_BRIGHTNESS:
+ CLAMP(fade, -1.0f, 1.0f);
+ brightness = fade;
+ contrast = 0;
+ delta = contrast / 2.0f;
+ gain = 1.0f - delta * 2.0f;
+ delta *= -1;
+ offset = gain * (brightness + delta);
+ for (int i = 0; i < 3; i++) {
+ final_color[i] = gain * orig_color[i] + offset;
+ CLAMP(final_color[i], 0.0f, 1.0f);
+ }
+ break;
+ case COLOR_FILTER_CONTRAST:
+ CLAMP(fade, -1.0f, 1.0f);
+ brightness = 0;
+ contrast = fade;
+ delta = contrast / 2.0f;
+ gain = 1.0f - delta * 2.0f;
+ if (contrast > 0) {
+ gain = 1.0f / ((gain != 0.0f) ? gain : FLT_EPSILON);
+ offset = gain * (brightness - delta);
+ }
+ else {
+ delta *= -1;
+ offset = gain * (brightness + delta);
+ }
+ for (int i = 0; i < 3; i++) {
+ final_color[i] = gain * orig_color[i] + offset;
+ CLAMP(final_color[i], 0.0f, 1.0f);
+ }
+ break;
+ case COLOR_FILTER_SMOOTH: {
+ CLAMP(fade, -1.0f, 1.0f);
+ float smooth_color[4];
+ SCULPT_neighbor_color_average(ss, smooth_color, vd.index);
+ blend_color_interpolate_float(final_color, vd.col, smooth_color, fade);
+ break;
+ }
+ }
+
+ copy_v3_v3(vd.col, final_color);
+
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+ }
+ }
+ BKE_pbvh_vertex_iter_end;
+ BKE_pbvh_node_mark_update_color(data->nodes[n]);
+}
+
+static int sculpt_color_filter_modal(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ Object *ob = CTX_data_active_object(C);
+ SculptSession *ss = ob->sculpt;
+ Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
+ const int mode = RNA_enum_get(op->ptr, "type");
+ float filter_strength = RNA_float_get(op->ptr, "strength");
+
+ if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
+ SCULPT_undo_push_end();
+ SCULPT_filter_cache_free(ss);
+ SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_COLOR);
+ return OPERATOR_FINISHED;
+ }
+
+ if (event->type != MOUSEMOVE) {
+ return OPERATOR_RUNNING_MODAL;
+ }
+
+ float len = event->prevclickx - event->mval[0];
+ filter_strength = filter_strength * -len * 0.001f;
+
+ float fill_color[3];
+ RNA_float_get_array(op->ptr, "fill_color", fill_color);
+ IMB_colormanagement_srgb_to_scene_linear_v3(fill_color);
+
+ SculptThreadedTaskData data = {
+ .sd = sd,
+ .ob = ob,
+ .nodes = ss->filter_cache->nodes,
+ .filter_type = mode,
+ .filter_strength = filter_strength,
+ .filter_fill_color = fill_color,
+ };
+
+ TaskParallelSettings settings;
+ BLI_parallel_range_settings_defaults(&settings);
+
+ BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode);
+ BLI_task_parallel_range(0, ss->filter_cache->totnode, &data, color_filter_task_cb, &settings);
+
+ SCULPT_flush_update_step(C, SCULPT_UPDATE_COLOR);
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static int sculpt_color_filter_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ Object *ob = CTX_data_active_object(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
+ Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
+ SculptSession *ss = ob->sculpt;
+ int mode = RNA_enum_get(op->ptr, "type");
+ PBVH *pbvh = ob->sculpt->pbvh;
+
+ /* Disable for multires and dyntopo for now */
+ if (!ss->pbvh) {
+ return OPERATOR_CANCELLED;
+ }
+ if (BKE_pbvh_type(pbvh) != PBVH_FACES) {
+ return OPERATOR_CANCELLED;
+ }
+
+ if (!ss->vcol) {
+ return OPERATOR_CANCELLED;
+ }
+
+ SCULPT_undo_push_begin("color filter");
+
+ bool needs_pmap = mode == COLOR_FILTER_SMOOTH;
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, needs_pmap, false, true);
+
+ if (BKE_pbvh_type(pbvh) == PBVH_FACES && needs_pmap && !ob->sculpt->pmap) {
+ return OPERATOR_CANCELLED;
+ }
+
+ SCULPT_filter_cache_init(ob, sd, SCULPT_UNDO_COLOR);
+
+ WM_event_add_modal_handler(C, op);
+ return OPERATOR_RUNNING_MODAL;
+}
+
+void SCULPT_OT_color_filter(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Filter color";
+ ot->idname = "SCULPT_OT_color_filter";
+ ot->description = "Applies a filter to modify the current sculpt vertex colors";
+
+ /* api callbacks */
+ ot->invoke = sculpt_color_filter_invoke;
+ ot->modal = sculpt_color_filter_modal;
+ ot->poll = SCULPT_mode_poll;
+
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* rna */
+ RNA_def_enum(ot->srna, "type", prop_color_filter_types, COLOR_FILTER_HUE, "Filter type", "");
+ RNA_def_float(
+ ot->srna, "strength", 1.0f, -10.0f, 10.0f, "Strength", "Filter Strength", -10.0f, 10.0f);
+
+ PropertyRNA *prop = RNA_def_float_color(
+ ot->srna, "fill_color", 3, NULL, 0.0f, FLT_MAX, "Fill Color", "fill color", 0.0f, 1.0f);
+ RNA_def_property_subtype(prop, PROP_COLOR_GAMMA);
+}
diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mask.c b/source/blender/editors/sculpt_paint/sculpt_filter_mask.c
index d2a683461a7..83145f5600f 100644
--- a/source/blender/editors/sculpt_paint/sculpt_filter_mask.c
+++ b/source/blender/editors/sculpt_paint/sculpt_filter_mask.c
@@ -202,7 +202,7 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op)
int totnode;
int filter_type = RNA_enum_get(op->ptr, "filter_type");
- BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true);
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);
SCULPT_vertex_random_access_init(ss);
@@ -247,7 +247,7 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op)
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(0, totnode, &data, mask_filter_task_cb, &settings);
if (ELEM(filter_type, MASK_FILTER_GROW, MASK_FILTER_SHRINK)) {
@@ -276,7 +276,7 @@ void SCULPT_mask_filter_smooth_apply(
for (int i = 0; i < smooth_iterations; i++) {
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(0, totnode, &data, mask_filter_task_cb, &settings);
}
}
@@ -432,7 +432,7 @@ static int sculpt_dirty_mask_exec(bContext *C, wmOperator *op)
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
int totnode;
- BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true);
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);
SCULPT_vertex_random_access_init(ss);
@@ -459,7 +459,7 @@ static int sculpt_dirty_mask_exec(bContext *C, wmOperator *op)
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
settings.func_reduce = dirty_mask_compute_range_reduce;
settings.userdata_chunk = &range;
diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
index fd0f67f040a..494588d0996 100644
--- a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
+++ b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
@@ -70,10 +70,10 @@ static void filter_cache_init_task_cb(void *__restrict userdata,
SculptThreadedTaskData *data = userdata;
PBVHNode *node = data->nodes[i];
- SCULPT_undo_push_node(data->ob, node, SCULPT_UNDO_COORDS);
+ SCULPT_undo_push_node(data->ob, node, data->filter_undo_type);
}
-void SCULPT_filter_cache_init(Object *ob, Sculpt *sd)
+void SCULPT_filter_cache_init(Object *ob, Sculpt *sd, const int undo_type)
{
SculptSession *ss = ob->sculpt;
PBVH *pbvh = ob->sculpt->pbvh;
@@ -110,11 +110,11 @@ void SCULPT_filter_cache_init(Object *ob, Sculpt *sd)
.sd = sd,
.ob = ob,
.nodes = ss->filter_cache->nodes,
+ .filter_undo_type = undo_type,
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(
- &settings, (sd->flags & SCULPT_USE_OPENMP), ss->filter_cache->totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode);
BLI_task_parallel_range(
0, ss->filter_cache->totnode, &data, filter_cache_init_task_cb, &settings);
}
@@ -475,7 +475,7 @@ static int sculpt_mesh_filter_modal(bContext *C, wmOperator *op, const wmEvent *
SCULPT_vertex_random_access_init(ss);
bool needs_pmap = sculpt_mesh_filter_needs_pmap(filter_type, use_face_sets);
- BKE_sculpt_update_object_for_edit(depsgraph, ob, needs_pmap, false);
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, needs_pmap, false, false);
SculptThreadedTaskData data = {
.sd = sd,
@@ -486,8 +486,7 @@ static int sculpt_mesh_filter_modal(bContext *C, wmOperator *op, const wmEvent *
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(
- &settings, (sd->flags & SCULPT_USE_OPENMP), ss->filter_cache->totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode);
BLI_task_parallel_range(0, ss->filter_cache->totnode, &data, mesh_filter_task_cb, &settings);
if (filter_type == MESH_FILTER_SURFACE_SMOOTH) {
@@ -542,7 +541,7 @@ static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent
SCULPT_vertex_random_access_init(ss);
bool needs_pmap = sculpt_mesh_filter_needs_pmap(filter_type, use_face_sets);
- BKE_sculpt_update_object_for_edit(depsgraph, ob, needs_pmap, false);
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, needs_pmap, false, false);
const int totvert = SCULPT_vertex_count_get(ss);
if (BKE_pbvh_type(pbvh) == PBVH_FACES && needs_pmap && !ob->sculpt->pmap) {
@@ -551,7 +550,7 @@ static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent
SCULPT_undo_push_begin("Mesh filter");
- SCULPT_filter_cache_init(ob, sd);
+ SCULPT_filter_cache_init(ob, sd, SCULPT_UNDO_COORDS);
if (use_face_sets) {
ss->filter_cache->active_face_set = SCULPT_active_face_set_get(ss);
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index 0e27658e848..c981f89ada7 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -27,6 +27,7 @@
#include "DNA_brush_types.h"
#include "DNA_key_types.h"
#include "DNA_listBase.h"
+#include "DNA_meshdata_types.h"
#include "DNA_vec_types.h"
#include "BLI_bitmap.h"
@@ -56,6 +57,7 @@ typedef enum SculptUpdateType {
SCULPT_UPDATE_COORDS = 1 << 0,
SCULPT_UPDATE_MASK = 1 << 1,
SCULPT_UPDATE_VISIBILITY = 1 << 2,
+ SCULPT_UPDATE_COLOR = 1 << 3,
} SculptUpdateType;
void SCULPT_flush_update_step(bContext *C, SculptUpdateType update_flags);
@@ -92,6 +94,7 @@ int SCULPT_vertex_count_get(struct SculptSession *ss);
const float *SCULPT_vertex_co_get(struct SculptSession *ss, int index);
void SCULPT_vertex_normal_get(SculptSession *ss, int index, float no[3]);
float SCULPT_vertex_mask_get(struct SculptSession *ss, int index);
+const float *SCULPT_vertex_color_get(SculptSession *ss, int index);
#define SCULPT_VERTEX_NEIGHBOR_FIXED_CAPACITY 256
typedef struct SculptVertexNeighborIter {
@@ -145,6 +148,15 @@ void SCULPT_active_vertex_normal_get(SculptSession *ss, float normal[3]);
bool SCULPT_vertex_is_boundary(SculptSession *ss, const int index);
+/* Fake Neighbors */
+
+#define FAKE_NEIGHBOR_NONE -1
+
+void SCULPT_fake_neighbors_ensure(struct Sculpt *sd, Object *ob, const float max_dist);
+void SCULPT_fake_neighbors_enable(Object *ob);
+void SCULPT_fake_neighbors_disable(Object *ob);
+void SCULPT_fake_neighbors_free(struct Object *ob);
+
/* Sculpt Visibility API */
void SCULPT_vertex_visible_set(SculptSession *ss, int index, bool visible);
@@ -179,15 +191,20 @@ typedef struct {
float (*coords)[3];
short (*normals)[3];
const float *vmasks;
+ float (*colors)[4];
/* Original coordinate, normal, and mask. */
const float *co;
const short *no;
float mask;
+ const float *col;
} SculptOrigVertData;
void SCULPT_orig_vert_data_init(SculptOrigVertData *data, Object *ob, PBVHNode *node);
void SCULPT_orig_vert_data_update(SculptOrigVertData *orig_data, PBVHVertexIter *iter);
+void SCULPT_orig_vert_data_unode_init(SculptOrigVertData *data,
+ Object *ob,
+ struct SculptUndoNode *unode);
/* Utils. */
void SCULPT_calc_brush_plane(struct Sculpt *sd,
@@ -305,7 +322,7 @@ float *SCULPT_boundary_automasking_init(Object *ob,
float *automask_factor);
/* Filters. */
-void SCULPT_filter_cache_init(Object *ob, Sculpt *sd);
+void SCULPT_filter_cache_init(Object *ob, Sculpt *sd, const int undo_type);
void SCULPT_filter_cache_free(SculptSession *ss);
void SCULPT_mask_filter_smooth_apply(
@@ -374,6 +391,12 @@ void SCULPT_multiplane_scrape_preview_draw(const uint gpuattr,
/* Draw Face Sets Brush. */
void SCULPT_do_draw_face_sets_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
+/* Paint Brush. */
+void SCULPT_do_paint_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
+
+/* Smear Brush. */
+void SCULPT_do_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
+
/* Smooth Brush. */
void SCULPT_neighbor_average(SculptSession *ss, float avg[3], uint vert);
@@ -383,6 +406,7 @@ void SCULPT_bmesh_four_neighbor_average(float avg[3], float direction[3], struct
void SCULPT_neighbor_coords_average(SculptSession *ss, float result[3], int index);
float SCULPT_neighbor_mask_average(SculptSession *ss, int index);
+void SCULPT_neighbor_color_average(SculptSession *ss, float result[4], int index);
void SCULPT_smooth(Sculpt *sd,
Object *ob,
@@ -427,6 +451,7 @@ typedef enum {
SCULPT_UNDO_DYNTOPO_SYMMETRIZE,
SCULPT_UNDO_GEOMETRY,
SCULPT_UNDO_FACE_SETS,
+ SCULPT_UNDO_COLOR,
} SculptUndoType;
/* Storage of geometry for the undo node.
@@ -457,6 +482,7 @@ typedef struct SculptUndoNode {
float (*co)[3];
float (*orig_co)[3];
short (*no)[3];
+ float (*col)[4];
float *mask;
int totvert;
@@ -556,6 +582,7 @@ typedef struct SculptThreadedTaskData {
int filter_type;
float filter_strength;
+ float *filter_fill_color;
bool use_area_cos;
bool use_area_nos;
@@ -568,6 +595,8 @@ typedef struct SculptThreadedTaskData {
bool any_vertex_sampled;
+ float *wet_mix_sampled_color;
+
float *prev_mask;
float *pose_factor;
@@ -601,6 +630,7 @@ typedef struct SculptThreadedTaskData {
bool dirty_mask_dirty_only;
int face_set;
+ int filter_undo_type;
ThreadMutex mutex;
@@ -720,6 +750,8 @@ typedef struct StrokeCache {
float bstrength;
float normal_weight; /* from brush (with optional override) */
+ float (*prev_colors)[4];
+
/* The rest is temporary storage that isn't saved as a property */
bool first_time; /* Beginning of stroke may do some things special */
@@ -813,6 +845,9 @@ typedef struct StrokeCache {
float stroke_local_mat[4][4];
float multiplane_scrape_angle;
+ float wet_mix_prev_color[4];
+ float density_seed;
+
rcti previous_r; /* previous redraw rectangle */
rcti current_r; /* current redraw rectangle */
@@ -901,6 +936,9 @@ void SCULPT_OT_mesh_filter(struct wmOperatorType *ot);
/* Cloth Filter. */
void SCULPT_OT_cloth_filter(struct wmOperatorType *ot);
+/* Color Filter. */
+void SCULPT_OT_color_filter(struct wmOperatorType *ot);
+
/* Mask filter and Dirty Mask. */
void SCULPT_OT_mask_filter(struct wmOperatorType *ot);
void SCULPT_OT_dirty_mask(struct wmOperatorType *ot);
diff --git a/source/blender/editors/sculpt_paint/sculpt_mask_expand.c b/source/blender/editors/sculpt_paint/sculpt_mask_expand.c
index cbb198e14a3..60483cc168d 100644
--- a/source/blender/editors/sculpt_paint/sculpt_mask_expand.c
+++ b/source/blender/editors/sculpt_paint/sculpt_mask_expand.c
@@ -206,7 +206,7 @@ static int sculpt_mask_expand_modal(bContext *C, wmOperator *op, const wmEvent *
(event->type == EVT_PADENTER && event->val == KM_PRESS)) {
/* Smooth iterations. */
- BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false);
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false, false);
const int smooth_iterations = RNA_int_get(op->ptr, "smooth_iterations");
SCULPT_mask_filter_smooth_apply(
sd, ob, ss->filter_cache->nodes, ss->filter_cache->totnode, smooth_iterations);
@@ -289,8 +289,7 @@ static int sculpt_mask_expand_modal(bContext *C, wmOperator *op, const wmEvent *
.mask_expand_create_face_set = RNA_boolean_get(op->ptr, "create_face_set"),
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(
- &settings, (sd->flags & SCULPT_USE_OPENMP), ss->filter_cache->totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode);
BLI_task_parallel_range(0, ss->filter_cache->totnode, &data, sculpt_expand_task_cb, &settings);
ss->filter_cache->mask_update_current_it = mask_expand_update_it;
}
@@ -365,7 +364,7 @@ static int sculpt_mask_expand_invoke(bContext *C, wmOperator *op, const wmEvent
SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false);
- BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true);
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);
int vertex_count = SCULPT_vertex_count_get(ss);
@@ -459,8 +458,7 @@ static int sculpt_mask_expand_invoke(bContext *C, wmOperator *op, const wmEvent
.mask_expand_create_face_set = RNA_boolean_get(op->ptr, "create_face_set"),
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(
- &settings, (sd->flags & SCULPT_USE_OPENMP), ss->filter_cache->totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode);
BLI_task_parallel_range(0, ss->filter_cache->totnode, &data, sculpt_expand_task_cb, &settings);
const char *status_str = TIP_(
diff --git a/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c b/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c
index f3327706102..503f9429a50 100644
--- a/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c
+++ b/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c
@@ -304,7 +304,7 @@ void SCULPT_do_multiplane_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes,
MultiplaneScrapeSampleData mssd = {{{0}}};
TaskParallelSettings sample_settings;
- BKE_pbvh_parallel_range_settings(&sample_settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&sample_settings, true, totnode);
sample_settings.func_reduce = calc_multiplane_scrape_surface_reduce;
sample_settings.userdata_chunk = &mssd;
sample_settings.userdata_chunk_size = sizeof(MultiplaneScrapeSampleData);
@@ -395,7 +395,7 @@ void SCULPT_do_multiplane_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes,
plane_from_point_normal_v3(data.multiplane_scrape_planes[0], area_co, plane_no);
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(0, totnode, &data, do_multiplane_scrape_brush_task_cb_ex, &settings);
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_color.c b/source/blender/editors/sculpt_paint/sculpt_paint_color.c
new file mode 100644
index 00000000000..9b38def6b7b
--- /dev/null
+++ b/source/blender/editors/sculpt_paint/sculpt_paint_color.c
@@ -0,0 +1,477 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup edsculpt
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_hash.h"
+#include "BLI_math.h"
+#include "BLI_math_color_blend.h"
+#include "BLI_task.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "BKE_brush.h"
+#include "BKE_colortools.h"
+#include "BKE_context.h"
+#include "BKE_mesh.h"
+#include "BKE_mesh_mapping.h"
+#include "BKE_object.h"
+#include "BKE_paint.h"
+#include "BKE_pbvh.h"
+#include "BKE_scene.h"
+
+#include "DEG_depsgraph.h"
+
+#include "IMB_colormanagement.h"
+
+#include "WM_api.h"
+#include "WM_message.h"
+#include "WM_toolsystem.h"
+#include "WM_types.h"
+
+#include "ED_object.h"
+#include "ED_screen.h"
+#include "ED_sculpt.h"
+#include "paint_intern.h"
+#include "sculpt_intern.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "UI_interface.h"
+
+#include "IMB_imbuf.h"
+
+#include "bmesh.h"
+
+#include <math.h>
+#include <stdlib.h>
+
+static void do_color_smooth_task_cb_exec(void *__restrict userdata,
+ const int n,
+ const TaskParallelTLS *__restrict tls)
+{
+ SculptThreadedTaskData *data = userdata;
+ SculptSession *ss = data->ob->sculpt;
+ const Brush *brush = data->brush;
+ const float bstrength = ss->cache->bstrength;
+
+ PBVHVertexIter vd;
+
+ SculptBrushTest test;
+ SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
+ ss, &test, data->brush->falloff_shape);
+ const int thread_id = BLI_task_parallel_thread_id(tls);
+
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
+ {
+ if (sculpt_brush_test_sq_fn(&test, vd.co)) {
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ float smooth_color[4];
+ SCULPT_neighbor_color_average(ss, smooth_color, vd.index);
+ blend_color_interpolate_float(vd.col, vd.col, smooth_color, fade);
+
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+ }
+ }
+ }
+ BKE_pbvh_vertex_iter_end;
+}
+
+static void do_paint_brush_task_cb_ex(void *__restrict userdata,
+ const int n,
+ const TaskParallelTLS *__restrict tls)
+{
+ SculptThreadedTaskData *data = userdata;
+ SculptSession *ss = data->ob->sculpt;
+ const Brush *brush = data->brush;
+ const float bstrength = fabsf(ss->cache->bstrength);
+
+ PBVHVertexIter vd;
+ PBVHColorBufferNode *color_buffer;
+
+ SculptOrigVertData orig_data;
+ SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]);
+
+ color_buffer = BKE_pbvh_node_color_buffer_get(data->nodes[n]);
+
+ SculptBrushTest test;
+ SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
+ ss, &test, data->brush->falloff_shape);
+ const int thread_id = BLI_task_parallel_thread_id(tls);
+
+ float brush_color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
+ copy_v3_v3(brush_color, BKE_brush_color_get(ss->scene, brush));
+ IMB_colormanagement_srgb_to_scene_linear_v3(brush_color);
+
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
+ {
+ SCULPT_orig_vert_data_update(&orig_data, &vd);
+
+ bool affect_vertex = false;
+ float distance_to_stroke_location = 0.0f;
+ if (brush->tip_roundness < 1.0f) {
+ affect_vertex = SCULPT_brush_test_cube(&test, vd.co, data->mat, brush->tip_roundness);
+ distance_to_stroke_location = ss->cache->radius * test.dist;
+ }
+ else {
+ affect_vertex = sculpt_brush_test_sq_fn(&test, vd.co);
+ distance_to_stroke_location = sqrtf(test.dist);
+ }
+
+ if (affect_vertex) {
+ float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ distance_to_stroke_location,
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ /* Density. */
+ float noise = 1.0f;
+ const float density = brush->density;
+ if (density < 1.0f) {
+ const float hash_noise = BLI_hash_int_01(ss->cache->density_seed * 1000 * vd.index);
+ if (hash_noise > density) {
+ noise = density * hash_noise;
+ fade = fade * noise;
+ }
+ }
+
+ /* Brush paint color, brush test falloff and flow. */
+ float paint_color[4];
+ float wet_mix_color[4];
+ float buffer_color[4];
+
+ mul_v4_v4fl(paint_color, brush_color, fade * brush->flow);
+ mul_v4_v4fl(wet_mix_color, data->wet_mix_sampled_color, fade * brush->flow);
+
+ /* Interpolate with the wet_mix color for wet paint mixing. */
+ blend_color_interpolate_float(paint_color, paint_color, wet_mix_color, brush->wet_mix);
+ blend_color_mix_float(color_buffer->color[vd.i], color_buffer->color[vd.i], paint_color);
+
+ /* Final mix over the original color using brush alpha. */
+ mul_v4_v4fl(buffer_color, color_buffer->color[vd.i], brush->alpha);
+
+ IMB_blend_color_float(vd.col, orig_data.col, buffer_color, brush->blend);
+ }
+ CLAMP4(vd.col, 0.0f, 1.0f);
+
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+ }
+ }
+ BKE_pbvh_vertex_iter_end;
+}
+
+typedef struct SampleWetPaintTLSData {
+ int tot_samples;
+ float color[4];
+} SampleWetPaintTLSData;
+
+static void do_sample_wet_paint_task_cb(void *__restrict userdata,
+ const int n,
+ const TaskParallelTLS *__restrict tls)
+{
+ SculptThreadedTaskData *data = userdata;
+ SculptSession *ss = data->ob->sculpt;
+ SampleWetPaintTLSData *swptd = tls->userdata_chunk;
+ PBVHVertexIter vd;
+
+ SculptBrushTest test;
+ SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
+ ss, &test, data->brush->falloff_shape);
+
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
+ {
+ if (sculpt_brush_test_sq_fn(&test, vd.co)) {
+ add_v4_v4(swptd->color, vd.col);
+ swptd->tot_samples++;
+ }
+ }
+ BKE_pbvh_vertex_iter_end;
+}
+
+static void sample_wet_paint_reduce(const void *__restrict UNUSED(userdata),
+ void *__restrict chunk_join,
+ void *__restrict chunk)
+{
+ SampleWetPaintTLSData *join = chunk_join;
+ SampleWetPaintTLSData *swptd = chunk;
+
+ join->tot_samples += swptd->tot_samples;
+ add_v4_v4(join->color, swptd->color);
+}
+
+void SCULPT_do_paint_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
+{
+ Brush *brush = BKE_paint_brush(&sd->paint);
+ SculptSession *ss = ob->sculpt;
+
+ if (!ss->vcol) {
+ return;
+ }
+
+ if (ss->cache->first_time && ss->cache->mirror_symmetry_pass == 0) {
+ ss->cache->density_seed = BLI_hash_int_01(ss->cache->location[0] * 1000);
+ return;
+ }
+
+ BKE_curvemapping_initialize(brush->curve);
+
+ float area_no[3];
+ float mat[4][4];
+ float scale[4][4];
+ float tmat[4][4];
+
+ /* If the brush is round the tip does not need to be aligned to the surface, so this saves a
+ * whole iteration over the affected nodes. */
+ if (brush->tip_roundness < 1.0f) {
+ SCULPT_calc_area_normal(sd, ob, nodes, totnode, area_no);
+
+ cross_v3_v3v3(mat[0], area_no, ss->cache->grab_delta_symmetry);
+ mat[0][3] = 0;
+ cross_v3_v3v3(mat[1], area_no, mat[0]);
+ mat[1][3] = 0;
+ copy_v3_v3(mat[2], area_no);
+ mat[2][3] = 0;
+ copy_v3_v3(mat[3], ss->cache->location);
+ mat[3][3] = 1;
+ normalize_m4(mat);
+
+ scale_m4_fl(scale, ss->cache->radius);
+ mul_m4_m4m4(tmat, mat, scale);
+ mul_v3_fl(tmat[1], brush->tip_scale_x);
+ invert_m4_m4(mat, tmat);
+ if (is_zero_m4(mat)) {
+ return;
+ }
+ }
+
+ /* Smooth colors mode. */
+ if (ss->cache->alt_smooth) {
+ SculptThreadedTaskData data = {
+ .sd = sd,
+ .ob = ob,
+ .brush = brush,
+ .nodes = nodes,
+ .mat = mat,
+ };
+
+ TaskParallelSettings settings;
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
+ BLI_task_parallel_range(0, totnode, &data, do_color_smooth_task_cb_exec, &settings);
+ return;
+ }
+
+ /* Regular Paint mode. */
+
+ /* Wet paint color sampling. */
+ float wet_color[4] = {0.0f};
+ if (brush->wet_mix > 0.0f) {
+ SculptThreadedTaskData task_data = {
+ .sd = sd,
+ .ob = ob,
+ .nodes = nodes,
+ .brush = brush,
+ };
+
+ SampleWetPaintTLSData swptd;
+ swptd.tot_samples = 0;
+ zero_v4(swptd.color);
+
+ TaskParallelSettings settings_sample;
+ BKE_pbvh_parallel_range_settings(&settings_sample, true, totnode);
+ settings_sample.func_reduce = sample_wet_paint_reduce;
+ settings_sample.userdata_chunk = &swptd;
+ settings_sample.userdata_chunk_size = sizeof(SampleWetPaintTLSData);
+ BLI_task_parallel_range(0, totnode, &task_data, do_sample_wet_paint_task_cb, &settings_sample);
+
+ if (swptd.tot_samples > 0 && is_finite_v4(swptd.color)) {
+ copy_v4_v4(wet_color, swptd.color);
+ mul_v4_fl(wet_color, 1.0f / (float)swptd.tot_samples);
+ CLAMP4(wet_color, 0.0f, 1.0f);
+
+ if (ss->cache->first_time) {
+ copy_v4_v4(ss->cache->wet_mix_prev_color, wet_color);
+ }
+ blend_color_interpolate_float(
+ wet_color, wet_color, ss->cache->wet_mix_prev_color, brush->wet_persistence);
+ copy_v4_v4(ss->cache->wet_mix_prev_color, wet_color);
+ CLAMP4(ss->cache->wet_mix_prev_color, 0.0f, 1.0f);
+ }
+ }
+
+ /* Threaded loop over nodes. */
+ SculptThreadedTaskData data = {
+ .sd = sd,
+ .ob = ob,
+ .brush = brush,
+ .nodes = nodes,
+ .wet_mix_sampled_color = wet_color,
+ .mat = mat,
+ };
+
+ TaskParallelSettings settings;
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
+ BLI_task_parallel_range(0, totnode, &data, do_paint_brush_task_cb_ex, &settings);
+}
+
+static void do_smear_brush_task_cb_exec(void *__restrict userdata,
+ const int n,
+ const TaskParallelTLS *__restrict tls)
+{
+ SculptThreadedTaskData *data = userdata;
+ SculptSession *ss = data->ob->sculpt;
+ const Brush *brush = data->brush;
+ const float bstrength = ss->cache->bstrength;
+
+ PBVHVertexIter vd;
+
+ SculptBrushTest test;
+ SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
+ ss, &test, data->brush->falloff_shape);
+ const int thread_id = BLI_task_parallel_thread_id(tls);
+
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
+ {
+ if (sculpt_brush_test_sq_fn(&test, vd.co)) {
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ float current_disp[3];
+ float current_disp_norm[3];
+ float interp_color[4];
+ copy_v4_v4(interp_color, ss->cache->prev_colors[vd.index]);
+
+ sub_v3_v3v3(current_disp, ss->cache->location, ss->cache->last_location);
+ normalize_v3_v3(current_disp_norm, current_disp);
+ mul_v3_v3fl(current_disp, current_disp_norm, ss->cache->bstrength);
+
+ SculptVertexNeighborIter ni;
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) {
+ float vertex_disp[3];
+ float vertex_disp_norm[3];
+ sub_v3_v3v3(vertex_disp, SCULPT_vertex_co_get(ss, ni.index), vd.co);
+ const float *neighbor_color = ss->cache->prev_colors[ni.index];
+ normalize_v3_v3(vertex_disp_norm, vertex_disp);
+ if (dot_v3v3(current_disp_norm, vertex_disp_norm) < 0.0f) {
+ const float color_interp = clamp_f(
+ -dot_v3v3(current_disp_norm, vertex_disp_norm), 0.0f, 1.0f);
+ float color_mix[4];
+ copy_v4_v4(color_mix, neighbor_color);
+ mul_v4_fl(color_mix, color_interp * fade);
+ blend_color_mix_float(interp_color, interp_color, color_mix);
+ }
+ }
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
+
+ blend_color_interpolate_float(vd.col, ss->cache->prev_colors[vd.index], interp_color, fade);
+
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+ }
+ }
+ }
+ BKE_pbvh_vertex_iter_end;
+}
+
+static void do_smear_store_prev_colors_task_cb_exec(void *__restrict userdata,
+ const int n,
+ const TaskParallelTLS *__restrict UNUSED(tls))
+{
+ SculptThreadedTaskData *data = userdata;
+ SculptSession *ss = data->ob->sculpt;
+
+ PBVHVertexIter vd;
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
+ {
+ copy_v4_v4(ss->cache->prev_colors[vd.index], SCULPT_vertex_color_get(ss, vd.index));
+ }
+ BKE_pbvh_vertex_iter_end;
+}
+
+void SCULPT_do_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
+{
+ Brush *brush = BKE_paint_brush(&sd->paint);
+ SculptSession *ss = ob->sculpt;
+
+ if (!ss->vcol) {
+ return;
+ }
+
+ const int totvert = SCULPT_vertex_count_get(ss);
+
+ if (ss->cache->first_time && ss->cache->mirror_symmetry_pass == 0) {
+ if (!ss->cache->prev_colors) {
+ ss->cache->prev_colors = MEM_callocN(sizeof(float) * 4 * totvert, "prev colors");
+ for (int i = 0; i < totvert; i++) {
+ copy_v4_v4(ss->cache->prev_colors[i], SCULPT_vertex_color_get(ss, i));
+ }
+ }
+ }
+
+ BKE_curvemapping_initialize(brush->curve);
+
+ SculptThreadedTaskData data = {
+ .sd = sd,
+ .ob = ob,
+ .brush = brush,
+ .nodes = nodes,
+ };
+
+ TaskParallelSettings settings;
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
+
+ /* Smooth colors mode. */
+ if (ss->cache->alt_smooth) {
+ BLI_task_parallel_range(0, totnode, &data, do_color_smooth_task_cb_exec, &settings);
+ }
+ else {
+ /* Smear mode. */
+ BLI_task_parallel_range(0, totnode, &data, do_smear_store_prev_colors_task_cb_exec, &settings);
+ BLI_task_parallel_range(0, totnode, &data, do_smear_brush_task_cb_exec, &settings);
+ }
+}
diff --git a/source/blender/editors/sculpt_paint/sculpt_pose.c b/source/blender/editors/sculpt_paint/sculpt_pose.c
index a4a87051e03..c9e2b7318d6 100644
--- a/source/blender/editors/sculpt_paint/sculpt_pose.c
+++ b/source/blender/editors/sculpt_paint/sculpt_pose.c
@@ -293,7 +293,7 @@ static void sculpt_pose_grow_pose_factor(Sculpt *sd,
PoseGrowFactorTLSData gftd;
gftd.pos_count = 0;
zero_v3(gftd.pos_avg);
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
settings.func_reduce = pose_brush_grow_factor_reduce;
settings.userdata_chunk = &gftd;
settings.userdata_chunk_size = sizeof(PoseGrowFactorTLSData);
@@ -937,18 +937,32 @@ SculptPoseIKChain *SCULPT_pose_ik_chain_init(Sculpt *sd,
const float initial_location[3],
const float radius)
{
+ SculptPoseIKChain *ik_chain = NULL;
+
+ const bool use_fake_neighbors = !(br->flag2 & BRUSH_USE_CONNECTED_ONLY);
+
+ if (use_fake_neighbors) {
+ SCULPT_fake_neighbors_ensure(sd, ob, br->disconnected_distance_max);
+ SCULPT_fake_neighbors_enable(ob);
+ }
+
switch (br->pose_origin_type) {
case BRUSH_POSE_ORIGIN_TOPOLOGY:
- return pose_ik_chain_init_topology(sd, ob, ss, br, initial_location, radius);
+ ik_chain = pose_ik_chain_init_topology(sd, ob, ss, br, initial_location, radius);
break;
case BRUSH_POSE_ORIGIN_FACE_SETS:
- return pose_ik_chain_init_face_sets(sd, ob, ss, br, radius);
+ ik_chain = pose_ik_chain_init_face_sets(sd, ob, ss, br, radius);
break;
case BRUSH_POSE_ORIGIN_FACE_SETS_FK:
return pose_ik_chain_init_face_sets_fk(sd, ob, ss, radius, initial_location);
break;
}
- return NULL;
+
+ if (use_fake_neighbors) {
+ SCULPT_fake_neighbors_disable(ob);
+ }
+
+ return ik_chain;
}
void SCULPT_pose_brush_init(Sculpt *sd, Object *ob, SculptSession *ss, Brush *br)
@@ -975,7 +989,7 @@ void SCULPT_pose_brush_init(Sculpt *sd, Object *ob, SculptSession *ss, Brush *br
data.pose_factor = ss->cache->pose_ik_chain->segments[ik].weights;
for (int i = 0; i < br->pose_smooth_iterations; i++) {
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(0, totnode, &data, pose_brush_init_task_cb_ex, &settings);
}
}
@@ -1198,7 +1212,7 @@ void SCULPT_do_pose_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(0, totnode, &data, do_pose_brush_task_cb_ex, &settings);
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_smooth.c b/source/blender/editors/sculpt_paint/sculpt_smooth.c
index 17451cb40ae..aa82ae1d7ad 100644
--- a/source/blender/editors/sculpt_paint/sculpt_smooth.c
+++ b/source/blender/editors/sculpt_paint/sculpt_smooth.c
@@ -226,6 +226,26 @@ float SCULPT_neighbor_mask_average(SculptSession *ss, int index)
}
}
+void SCULPT_neighbor_color_average(SculptSession *ss, float result[4], int index)
+{
+ float avg[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ int total = 0;
+
+ SculptVertexNeighborIter ni;
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, index, ni) {
+ add_v4_v4(avg, SCULPT_vertex_color_get(ss, ni.index));
+ total++;
+ }
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
+
+ if (total > 0) {
+ mul_v4_v4fl(result, avg, 1.0f / (float)total);
+ }
+ else {
+ copy_v4_v4(result, SCULPT_vertex_color_get(ss, index));
+ }
+}
+
static void do_smooth_brush_mesh_task_cb_ex(void *__restrict userdata,
const int n,
const TaskParallelTLS *__restrict tls)
@@ -433,7 +453,7 @@ void SCULPT_smooth(Sculpt *sd,
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
switch (type) {
case PBVH_GRIDS:
@@ -525,10 +545,15 @@ static void SCULPT_do_surface_smooth_brush_laplacian_task_cb_ex(
{
SCULPT_orig_vert_data_update(&orig_data, &vd);
if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade =
- bstrength *
- SCULPT_brush_strength_factor(
- ss, brush, vd.co, sqrtf(test.dist), vd.no, vd.fno, 0.0f, vd.index, thread_id);
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
float disp[3];
SCULPT_surface_smooth_laplacian_step(ss,
@@ -566,10 +591,15 @@ static void SCULPT_do_surface_smooth_brush_displace_task_cb_ex(
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade =
- bstrength *
- SCULPT_brush_strength_factor(
- ss, brush, vd.co, sqrtf(test.dist), vd.no, vd.fno, 0.0f, vd.index, thread_id);
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
SCULPT_surface_smooth_displace_step(
ss, vd.co, ss->cache->surface_smooth_laplacian_disp, vd.index, beta, fade);
}
@@ -598,7 +628,7 @@ void SCULPT_do_surface_smooth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, in
};
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
for (int i = 0; i < brush->surface_smooth_iterations; i++) {
BLI_task_parallel_range(
0, totnode, &data, SCULPT_do_surface_smooth_brush_laplacian_task_cb_ex, &settings);
diff --git a/source/blender/editors/sculpt_paint/sculpt_transform.c b/source/blender/editors/sculpt_paint/sculpt_transform.c
index 59a4695ce18..f616817c330 100644
--- a/source/blender/editors/sculpt_paint/sculpt_transform.c
+++ b/source/blender/editors/sculpt_paint/sculpt_transform.c
@@ -71,12 +71,12 @@ void ED_sculpt_init_transform(struct bContext *C)
copy_v4_v4(ss->init_pivot_rot, ss->pivot_rot);
SCULPT_undo_push_begin("Transform");
- BKE_sculpt_update_object_for_edit(depsgraph, ob, false, false);
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, false, false, false);
ss->pivot_rot[3] = 1.0f;
SCULPT_vertex_random_access_init(ss);
- SCULPT_filter_cache_init(ob, sd);
+ SCULPT_filter_cache_init(ob, sd, SCULPT_UNDO_COORDS);
}
static void sculpt_transform_task_cb(void *__restrict userdata,
@@ -127,7 +127,7 @@ void ED_sculpt_update_modal_transform(struct bContext *C)
const char symm = sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL;
SCULPT_vertex_random_access_init(ss);
- BKE_sculpt_update_object_for_edit(depsgraph, ob, false, false);
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, false, false, false);
SculptThreadedTaskData data = {
.sd = sd,
@@ -178,8 +178,7 @@ void ED_sculpt_update_modal_transform(struct bContext *C)
}
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(
- &settings, (sd->flags & SCULPT_USE_OPENMP), ss->filter_cache->totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode);
BLI_task_parallel_range(
0, ss->filter_cache->totnode, &data, sculpt_transform_task_cb, &settings);
@@ -253,7 +252,7 @@ static int sculpt_set_pivot_position_exec(bContext *C, wmOperator *op)
int mode = RNA_enum_get(op->ptr, "mode");
- BKE_sculpt_update_object_for_edit(depsgraph, ob, false, true);
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, false, true, false);
/* Pivot to center. */
if (mode == SCULPT_PIVOT_POSITION_ORIGIN) {
diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c
index d21552efafe..6ede631eb11 100644
--- a/source/blender/editors/sculpt_paint/sculpt_undo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_undo.c
@@ -205,7 +205,7 @@ static bool sculpt_undo_restore_coords(bContext *C, Depsgraph *depsgraph, Sculpt
if (kb) {
ob->shapenr = BLI_findindex(&key->block, kb) + 1;
- BKE_sculpt_update_object_for_edit(depsgraph, ob, false, false);
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, false, false, false);
WM_event_add_notifier(C, NC_OBJECT | ND_DATA, ob);
}
else {
@@ -326,6 +326,29 @@ static bool sculpt_undo_restore_hidden(bContext *C, SculptUndoNode *unode)
return true;
}
+static bool sculpt_undo_restore_color(bContext *C, SculptUndoNode *unode)
+{
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Object *ob = OBACT(view_layer);
+ SculptSession *ss = ob->sculpt;
+ MVert *mvert;
+ MPropCol *vcol;
+ int *index, i;
+
+ if (unode->maxvert) {
+ /* regular mesh restore */
+ index = unode->index;
+ mvert = ss->mvert;
+ vcol = ss->vcol;
+
+ for (i = 0; i < unode->totvert; i++) {
+ copy_v4_v4(vcol[index[i]].color, unode->col[i]);
+ mvert[index[i]].flag |= ME_VERT_PBVH_UPDATE;
+ }
+ }
+ return true;
+}
+
static bool sculpt_undo_restore_mask(bContext *C, SculptUndoNode *unode)
{
ViewLayer *view_layer = CTX_data_view_layer(C);
@@ -394,10 +417,7 @@ static void sculpt_undo_bmesh_restore_generic_task_cb(
BKE_pbvh_node_mark_redraw(nodes[n]);
}
-static void sculpt_undo_bmesh_restore_generic(bContext *C,
- SculptUndoNode *unode,
- Object *ob,
- SculptSession *ss)
+static void sculpt_undo_bmesh_restore_generic(SculptUndoNode *unode, Object *ob, SculptSession *ss)
{
if (unode->applied) {
BM_log_undo(ss->bm, ss->bm_log);
@@ -411,12 +431,11 @@ static void sculpt_undo_bmesh_restore_generic(bContext *C,
if (unode->type == SCULPT_UNDO_MASK) {
int totnode;
PBVHNode **nodes;
- Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(
0, totnode, nodes, sculpt_undo_bmesh_restore_generic_task_cb, &settings);
@@ -588,7 +607,7 @@ static int sculpt_undo_bmesh_restore(bContext *C,
return true;
default:
if (ss->bm_log) {
- sculpt_undo_bmesh_restore_generic(C, unode, ob, ss);
+ sculpt_undo_bmesh_restore_generic(unode, ob, ss);
return true;
}
break;
@@ -633,7 +652,7 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase
rebuild = true;
BKE_pbvh_search_callback(ss->pbvh, NULL, NULL, update_cb, &rebuild);
- BKE_sculpt_update_object_for_edit(depsgraph, ob, true, need_mask);
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, true, need_mask, false);
SCULPT_visibility_sync_all_face_sets_to_vertices(ss);
@@ -659,7 +678,7 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase
* ensure object is updated after the node is handled. */
const SculptUndoNode *first_unode = (const SculptUndoNode *)lb->first;
if (first_unode->type != SCULPT_UNDO_GEOMETRY) {
- BKE_sculpt_update_object_for_edit(depsgraph, ob, false, need_mask);
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, false, need_mask, false);
}
if (sculpt_undo_bmesh_restore(C, lb->first, ob, ss)) {
@@ -712,10 +731,15 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase
break;
case SCULPT_UNDO_FACE_SETS:
break;
+ case SCULPT_UNDO_COLOR:
+ if (sculpt_undo_restore_color(C, unode)) {
+ update = true;
+ }
+ break;
case SCULPT_UNDO_GEOMETRY:
sculpt_undo_geometry_restore(unode, ob);
- BKE_sculpt_update_object_for_edit(depsgraph, ob, false, need_mask);
+ BKE_sculpt_update_object_for_edit(depsgraph, ob, false, need_mask, false);
break;
case SCULPT_UNDO_DYNTOPO_BEGIN:
@@ -998,6 +1022,12 @@ static SculptUndoNode *sculpt_undo_alloc_node(Object *ob, PBVHNode *node, Sculpt
usculpt->undo_size += (sizeof(float) * sizeof(int)) * allvert;
break;
+ case SCULPT_UNDO_COLOR:
+ unode->col = MEM_callocN(sizeof(MPropCol) * allvert, "SculptUndoNode.col");
+
+ usculpt->undo_size += (sizeof(MPropCol) * sizeof(int)) * allvert;
+
+ break;
case SCULPT_UNDO_DYNTOPO_BEGIN:
case SCULPT_UNDO_DYNTOPO_END:
case SCULPT_UNDO_DYNTOPO_SYMMETRIZE:
@@ -1083,6 +1113,18 @@ static void sculpt_undo_store_mask(Object *ob, SculptUndoNode *unode)
BKE_pbvh_vertex_iter_end;
}
+static void sculpt_undo_store_color(Object *ob, SculptUndoNode *unode)
+{
+ SculptSession *ss = ob->sculpt;
+ PBVHVertexIter vd;
+
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, unode->node, vd, PBVH_ITER_ALL)
+ {
+ copy_v4_v4(unode->col[vd.i], vd.col);
+ }
+ BKE_pbvh_vertex_iter_end;
+}
+
static SculptUndoNodeGeometry *sculpt_undo_geometry_get(SculptUndoNode *unode)
{
if (!unode->geometry_original.is_initialized) {
@@ -1203,6 +1245,7 @@ static SculptUndoNode *sculpt_undo_bmesh_push(Object *ob, PBVHNode *node, Sculpt
case SCULPT_UNDO_DYNTOPO_SYMMETRIZE:
case SCULPT_UNDO_GEOMETRY:
case SCULPT_UNDO_FACE_SETS:
+ case SCULPT_UNDO_COLOR:
break;
}
}
@@ -1272,6 +1315,9 @@ SculptUndoNode *SCULPT_undo_push_node(Object *ob, PBVHNode *node, SculptUndoType
case SCULPT_UNDO_MASK:
sculpt_undo_store_mask(ob, unode);
break;
+ case SCULPT_UNDO_COLOR:
+ sculpt_undo_store_color(ob, unode);
+ break;
case SCULPT_UNDO_DYNTOPO_BEGIN:
case SCULPT_UNDO_DYNTOPO_END:
case SCULPT_UNDO_DYNTOPO_SYMMETRIZE:
diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c
index 81ac8a16d8a..2e52f3aa8a8 100644
--- a/source/blender/editors/sound/sound_ops.c
+++ b/source/blender/editors/sound/sound_ops.c
@@ -771,7 +771,7 @@ static int sound_pack_exec(bContext *C, wmOperator *op)
}
sound->packedfile = BKE_packedfile_new(
- op->reports, sound->name, ID_BLEND_PATH(bmain, &sound->id));
+ op->reports, sound->filepath, ID_BLEND_PATH(bmain, &sound->id));
BKE_sound_load(bmain, sound);
return OPERATOR_FINISHED;
@@ -847,7 +847,8 @@ static int sound_unpack_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE
"AutoPack is enabled, so image will be packed again on file save");
}
- unpack_menu(C, "SOUND_OT_unpack", sound->id.name + 2, sound->name, "sounds", sound->packedfile);
+ unpack_menu(
+ C, "SOUND_OT_unpack", sound->id.name + 2, sound->filepath, "sounds", sound->packedfile);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c
index b390e4b56d6..aa784800be0 100644
--- a/source/blender/editors/space_action/action_edit.c
+++ b/source/blender/editors/space_action/action_edit.c
@@ -800,10 +800,17 @@ static void insert_gpencil_keys(bAnimContext *ac, short mode)
add_frame_mode = GP_GETFRAME_ADD_NEW;
}
- /* insert gp frames */
+ /* Insert gp frames. */
+ bGPdata *gpd_old = NULL;
for (ale = anim_data.first; ale; ale = ale->next) {
+ bGPdata *gpd = (bGPdata *)ale->id;
bGPDlayer *gpl = (bGPDlayer *)ale->data;
BKE_gpencil_layer_frame_get(gpl, CFRA, add_frame_mode);
+ /* Check if the gpd changes to tag only once. */
+ if (gpd != gpd_old) {
+ BKE_gpencil_tag(gpd);
+ gpd_old = gpd;
+ }
}
ANIM_animdata_update(ac, &anim_data);
@@ -839,6 +846,9 @@ static int actkeys_insertkey_exec(bContext *C, wmOperator *op)
}
/* set notifier that keyframes have changed */
+ if (ac.datatype == ANIMCONT_GPENCIL) {
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+ }
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
return OPERATOR_FINISHED;
@@ -888,7 +898,7 @@ static void duplicate_action_keys(bAnimContext *ac)
duplicate_fcurve_keys((FCurve *)ale->key_data);
}
else if (ale->type == ANIMTYPE_GPLAYER) {
- ED_gplayer_frames_duplicate((bGPDlayer *)ale->data);
+ ED_gpencil_layer_frames_duplicate((bGPDlayer *)ale->data);
}
else if (ale->type == ANIMTYPE_MASKLAYER) {
ED_masklayer_frames_duplicate((MaskLayer *)ale->data);
@@ -964,7 +974,7 @@ static bool delete_action_keys(bAnimContext *ac)
bool changed = false;
if (ale->type == ANIMTYPE_GPLAYER) {
- changed = ED_gplayer_frames_delete((bGPDlayer *)ale->data);
+ changed = ED_gpencil_layer_frames_delete((bGPDlayer *)ale->data);
}
else if (ale->type == ANIMTYPE_MASKLAYER) {
changed = ED_masklayer_frames_delete((MaskLayer *)ale->data);
@@ -1539,7 +1549,7 @@ static void setkeytype_gpencil_keys(bAnimContext *ac, short mode)
/* loop through each layer */
for (ale = anim_data.first; ale; ale = ale->next) {
if (ale->type == ANIMTYPE_GPLAYER) {
- ED_gplayer_frames_keytype_set(ale->data, mode);
+ ED_gpencil_layer_frames_keytype_set(ale->data, mode);
ale->update |= ANIM_UPDATE_DEPS;
}
}
@@ -1740,7 +1750,7 @@ static void snap_action_keys(bAnimContext *ac, short mode)
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
if (ale->type == ANIMTYPE_GPLAYER) {
- ED_gplayer_snap_frames(ale->data, ac->scene, mode);
+ ED_gpencil_layer_snap_frames(ale->data, ac->scene, mode);
}
else if (ale->type == ANIMTYPE_MASKLAYER) {
ED_masklayer_snap_frames(ale->data, ac->scene, mode);
@@ -1870,7 +1880,7 @@ static void mirror_action_keys(bAnimContext *ac, short mode)
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
if (ale->type == ANIMTYPE_GPLAYER) {
- ED_gplayer_mirror_frames(ale->data, ac->scene, mode);
+ ED_gpencil_layer_mirror_frames(ale->data, ac->scene, mode);
}
else if (ale->type == ANIMTYPE_MASKLAYER) {
/* TODO */
diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c
index bbb68f632fb..f40b792269b 100644
--- a/source/blender/editors/space_action/action_select.c
+++ b/source/blender/editors/space_action/action_select.c
@@ -270,7 +270,7 @@ static void deselect_action_keys(bAnimContext *ac, short test, short sel)
if (test) {
for (ale = anim_data.first; ale; ale = ale->next) {
if (ale->type == ANIMTYPE_GPLAYER) {
- if (ED_gplayer_frame_select_check(ale->data)) {
+ if (ED_gpencil_layer_frame_select_check(ale->data)) {
sel = SELECT_SUBTRACT;
break;
}
@@ -296,7 +296,7 @@ static void deselect_action_keys(bAnimContext *ac, short test, short sel)
/* Now set the flags */
for (ale = anim_data.first; ale; ale = ale->next) {
if (ale->type == ANIMTYPE_GPLAYER) {
- ED_gplayer_frame_select_set(ale->data, sel);
+ ED_gpencil_layer_frame_select_set(ale->data, sel);
ale->update |= ANIM_UPDATE_DEPS;
}
else if (ale->type == ANIMTYPE_MASKLAYER) {
@@ -405,14 +405,14 @@ static void box_select_elem(
bGPdata *gpd = ale->data;
bGPDlayer *gpl;
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
- ED_gplayer_frames_select_box(gpl, xmin, xmax, data->selectmode);
+ ED_gpencil_layer_frames_select_box(gpl, xmin, xmax, data->selectmode);
}
ale->update |= ANIM_UPDATE_DEPS;
break;
}
#endif
case ANIMTYPE_GPLAYER: {
- ED_gplayer_frames_select_box(ale->data, xmin, xmax, sel_data->selectmode);
+ ED_gpencil_layer_frames_select_box(ale->data, xmin, xmax, sel_data->selectmode);
ale->update |= ANIM_UPDATE_DEPS;
break;
}
@@ -641,13 +641,13 @@ static void region_select_elem(RegionSelectData *sel_data, bAnimListElem *ale, b
bGPdata *gpd = ale->data;
bGPDlayer *gpl;
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
- ED_gplayer_frames_select_region(&rdata->ked, ale->data, rdata->mode, rdata->selectmode);
+ ED_gpencil_layer_frames_select_region(&rdata->ked, ale->data, rdata->mode, rdata->selectmode);
}
break;
}
#endif
case ANIMTYPE_GPLAYER: {
- ED_gplayer_frames_select_region(
+ ED_gpencil_layer_frames_select_region(
&sel_data->ked, ale->data, sel_data->mode, sel_data->selectmode);
ale->update |= ANIM_UPDATE_DEPS;
break;
@@ -972,7 +972,7 @@ static void markers_selectkeys_between(bAnimContext *ac)
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1);
}
else if (ale->type == ANIMTYPE_GPLAYER) {
- ED_gplayer_frames_select_box(ale->data, min, max, SELECT_ADD);
+ ED_gpencil_layer_frames_select_box(ale->data, min, max, SELECT_ADD);
ale->update |= ANIM_UPDATE_DEPS;
}
else if (ale->type == ANIMTYPE_MASKLAYER) {
@@ -1008,7 +1008,7 @@ static void columnselect_action_keys(bAnimContext *ac, short mode)
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
for (ale = anim_data.first; ale; ale = ale->next) {
- ED_gplayer_make_cfra_list(ale->data, &ked.list, 1);
+ ED_gpencil_layer_make_cfra_list(ale->data, &ked.list, 1);
}
}
else {
@@ -1385,7 +1385,7 @@ static void actkeys_select_leftright(bAnimContext *ac, short leftright, short se
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1);
}
else if (ale->type == ANIMTYPE_GPLAYER) {
- ED_gplayer_frames_select_box(ale->data, ked.f1, ked.f2, select_mode);
+ ED_gpencil_layer_frames_select_box(ale->data, ked.f1, ked.f2, select_mode);
ale->update |= ANIM_UPDATE_DEPS;
}
else if (ale->type == ANIMTYPE_MASKLAYER) {
diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c
index e92ea906237..079cee290ae 100644
--- a/source/blender/editors/space_action/space_action.c
+++ b/source/blender/editors/space_action/space_action.c
@@ -128,7 +128,7 @@ static SpaceLink *action_new(const ScrArea *area, const Scene *scene)
region->v2d.minzoom = 0.01f;
region->v2d.maxzoom = 50;
region->v2d.scroll = (V2D_SCROLL_BOTTOM | V2D_SCROLL_HORIZONTAL_HANDLES);
- region->v2d.scroll |= (V2D_SCROLL_RIGHT);
+ region->v2d.scroll |= V2D_SCROLL_RIGHT;
region->v2d.keepzoom = V2D_LOCKZOOM_Y;
region->v2d.keepofs = V2D_KEEPOFS_Y;
region->v2d.align = V2D_ALIGN_NO_POS_Y;
@@ -181,10 +181,14 @@ static void action_main_region_draw(const bContext *C, ARegion *region)
Object *obact = CTX_data_active_object(C);
bAnimContext ac;
View2D *v2d = &region->v2d;
- View2DScrollers *scrollers;
short marker_flag = 0;
short cfra_flag = 0;
+ UI_view2d_view_ortho(v2d);
+ if (saction->flag & SACTION_DRAWTIME) {
+ cfra_flag |= DRAWCFRA_UNIT_SECONDS;
+ }
+
/* clear and setup matrix */
UI_ThemeClearColor(TH_BACK);
GPU_clear(GPU_COLOR_BIT);
@@ -204,12 +208,6 @@ static void action_main_region_draw(const bContext *C, ARegion *region)
draw_channel_strips(&ac, saction, region);
}
- /* current frame */
- if (saction->flag & SACTION_DRAWTIME) {
- cfra_flag |= DRAWCFRA_UNIT_SECONDS;
- }
- ANIM_draw_cfra(C, v2d, cfra_flag);
-
/* markers */
UI_view2d_view_orthoSpecial(region, v2d, 1);
@@ -238,11 +236,20 @@ static void action_main_region_draw(const bContext *C, ARegion *region)
/* scrubbing region */
ED_time_scrub_draw(region, scene, saction->flag & SACTION_DRAWTIME, true);
+}
+
+static void action_main_region_draw_overlay(const bContext *C, ARegion *region)
+{
+ /* draw entirely, view changes should be handled here */
+ const SpaceAction *saction = CTX_wm_space_action(C);
+ const Scene *scene = CTX_data_scene(C);
+ View2D *v2d = &region->v2d;
+
+ /* scrubbing region */
+ ED_time_scrub_draw_current_frame(region, scene, saction->flag & SACTION_DRAWTIME, true);
/* scrollers */
- scrollers = UI_view2d_scrollers_calc(v2d, NULL);
- UI_view2d_scrollers_draw(v2d, scrollers);
- UI_view2d_scrollers_free(scrollers);
+ UI_view2d_scrollers_draw(v2d, NULL);
}
/* add handlers, stuff you only do once or on area/region changes */
@@ -874,6 +881,7 @@ void ED_spacetype_action(void)
art->regionid = RGN_TYPE_WINDOW;
art->init = action_main_region_init;
art->draw = action_main_region_draw;
+ art->draw_overlay = action_main_region_draw_overlay;
art->listener = action_main_region_listener;
art->message_subscribe = saction_main_region_message_subscribe;
art->keymapflag = ED_KEYMAP_VIEW2D | ED_KEYMAP_ANIMATION | ED_KEYMAP_FRAMES;
diff --git a/source/blender/editors/space_buttons/CMakeLists.txt b/source/blender/editors/space_buttons/CMakeLists.txt
index c3b7d65689f..25ff6bbd098 100644
--- a/source/blender/editors/space_buttons/CMakeLists.txt
+++ b/source/blender/editors/space_buttons/CMakeLists.txt
@@ -54,8 +54,4 @@ if(WITH_FREESTYLE)
add_definitions(-DWITH_FREESTYLE)
endif()
-if(WITH_NEW_OBJECT_TYPES)
- add_definitions(-DWITH_NEW_OBJECT_TYPES)
-endif()
-
blender_add_lib(bf_editor_space_buttons "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c
index 7e6088bc3cc..ba618083620 100644
--- a/source/blender/editors/space_buttons/buttons_context.c
+++ b/source/blender/editors/space_buttons/buttons_context.c
@@ -251,14 +251,12 @@ static int buttons_context_path_data(ButsContextPath *path, int type)
else if (RNA_struct_is_a(ptr->type, &RNA_GreasePencil) && (type == -1 || type == OB_GPENCIL)) {
return 1;
}
-#ifdef WITH_NEW_OBJECT_TYPES
else if (RNA_struct_is_a(ptr->type, &RNA_Hair) && (type == -1 || type == OB_HAIR)) {
return 1;
}
else if (RNA_struct_is_a(ptr->type, &RNA_PointCloud) && (type == -1 || type == OB_POINTCLOUD)) {
return 1;
}
-#endif
else if (RNA_struct_is_a(ptr->type, &RNA_Volume) && (type == -1 || type == OB_VOLUME)) {
return 1;
}
@@ -796,10 +794,8 @@ const char *buttons_context_dir[] = {
"line_style",
"collection",
"gpencil",
-#ifdef WITH_NEW_OBJECT_TYPES
"hair",
"pointcloud",
-#endif
"volume",
NULL,
};
@@ -878,7 +874,6 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
set_pointer_type(path, result, &RNA_LightProbe);
return 1;
}
-#ifdef WITH_NEW_OBJECT_TYPES
else if (CTX_data_equals(member, "hair")) {
set_pointer_type(path, result, &RNA_Hair);
return 1;
@@ -887,7 +882,6 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
set_pointer_type(path, result, &RNA_PointCloud);
return 1;
}
-#endif
else if (CTX_data_equals(member, "volume")) {
set_pointer_type(path, result, &RNA_Volume);
return 1;
diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c
index 187334a5c34..71b86996989 100644
--- a/source/blender/editors/space_buttons/space_buttons.c
+++ b/source/blender/editors/space_buttons/space_buttons.c
@@ -30,10 +30,10 @@
#include "BLI_utildefines.h"
#include "BKE_context.h"
+#include "BKE_gpencil_modifier.h" /* Types for registering panels. */
#include "BKE_modifier.h"
#include "BKE_screen.h"
-
-#include "DNA_modifier_types.h"
+#include "BKE_shader_fx.h"
#include "ED_screen.h"
#include "ED_space_api.h"
@@ -643,6 +643,21 @@ void ED_spacetype_buttons(void)
mti->panelRegister(art);
}
}
+ for (int i = 0; i < NUM_GREASEPENCIL_MODIFIER_TYPES; i++) {
+ const GpencilModifierTypeInfo *mti = BKE_gpencil_modifier_get_info(i);
+ if (mti != NULL && mti->panelRegister != NULL) {
+ mti->panelRegister(art);
+ }
+ }
+ for (int i = 0; i < NUM_SHADER_FX_TYPES; i++) {
+ if (i == eShaderFxType_Light_deprecated) {
+ continue;
+ }
+ const ShaderFxTypeInfo *fxti = BKE_shaderfx_get_info(i);
+ if (fxti != NULL && fxti->panelRegister != NULL) {
+ fxti->panelRegister(art);
+ }
+ }
/* regions: header */
art = MEM_callocN(sizeof(ARegionType), "spacetype buttons region");
diff --git a/source/blender/editors/space_clip/clip_dopesheet_draw.c b/source/blender/editors/space_clip/clip_dopesheet_draw.c
index 84ab5e6524b..c3aca95910b 100644
--- a/source/blender/editors/space_clip/clip_dopesheet_draw.c
+++ b/source/blender/editors/space_clip/clip_dopesheet_draw.c
@@ -118,7 +118,7 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *region, Scene *scene)
MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
MovieTrackingDopesheetChannel *channel;
float strip[4], selected_strip[4];
- float height = (dopesheet->tot_channel * CHANNEL_STEP) + (CHANNEL_HEIGHT);
+ float height = (dopesheet->tot_channel * CHANNEL_STEP) + CHANNEL_HEIGHT;
uint keyframe_len = 0;
@@ -305,7 +305,7 @@ void clip_draw_dopesheet_channels(const bContext *C, ARegion *region)
MovieTracking *tracking = &clip->tracking;
MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
- int height = (dopesheet->tot_channel * CHANNEL_STEP) + (CHANNEL_HEIGHT);
+ int height = (dopesheet->tot_channel * CHANNEL_STEP) + CHANNEL_HEIGHT;
if (height > BLI_rcti_size_y(&v2d->mask)) {
/* don't use totrect set, as the width stays the same
diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c
index 984aa0a63ad..22707b97afa 100644
--- a/source/blender/editors/space_clip/clip_ops.c
+++ b/source/blender/editors/space_clip/clip_ops.c
@@ -283,7 +283,7 @@ static int open_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)
}
if (clip) {
- BLI_strncpy(path, clip->name, sizeof(path));
+ BLI_strncpy(path, clip->filepath, sizeof(path));
BLI_path_abs(path, CTX_data_main(C)->name);
BLI_path_parent_dir(path);
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
index a68e06951f7..54da00a132d 100644
--- a/source/blender/editors/space_clip/space_clip.c
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -96,7 +96,7 @@ static void init_preview_region(const Scene *scene,
region->v2d.minzoom = 0.01f;
region->v2d.maxzoom = 50;
region->v2d.scroll = (V2D_SCROLL_BOTTOM | V2D_SCROLL_HORIZONTAL_HANDLES);
- region->v2d.scroll |= (V2D_SCROLL_RIGHT);
+ region->v2d.scroll |= V2D_SCROLL_RIGHT;
region->v2d.keepzoom = V2D_LOCKZOOM_Y;
region->v2d.keepofs = V2D_KEEPOFS_Y;
region->v2d.align = V2D_ALIGN_NO_POS_Y;
@@ -1045,7 +1045,6 @@ static void clip_preview_region_init(wmWindowManager *wm, ARegion *region)
static void graph_region_draw(const bContext *C, ARegion *region)
{
View2D *v2d = &region->v2d;
- View2DScrollers *scrollers;
SpaceClip *sc = CTX_wm_space_clip(C);
Scene *scene = CTX_data_scene(C);
short cfra_flag = 0;
@@ -1076,9 +1075,7 @@ static void graph_region_draw(const bContext *C, ARegion *region)
ED_time_scrub_draw(region, scene, sc->flag & SC_SHOW_SECONDS, true);
/* scrollers */
- scrollers = UI_view2d_scrollers_calc(v2d, NULL);
- UI_view2d_scrollers_draw(v2d, scrollers);
- UI_view2d_scrollers_free(scrollers);
+ UI_view2d_scrollers_draw(v2d, NULL);
/* scale indicators */
{
@@ -1095,7 +1092,6 @@ static void dopesheet_region_draw(const bContext *C, ARegion *region)
SpaceClip *sc = CTX_wm_space_clip(C);
MovieClip *clip = ED_space_clip_get_clip(sc);
View2D *v2d = &region->v2d;
- View2DScrollers *scrollers;
short cfra_flag = 0;
if (clip) {
@@ -1127,9 +1123,7 @@ static void dopesheet_region_draw(const bContext *C, ARegion *region)
ED_time_scrub_draw(region, scene, sc->flag & SC_SHOW_SECONDS, true);
/* scrollers */
- scrollers = UI_view2d_scrollers_calc(v2d, NULL);
- UI_view2d_scrollers_draw(v2d, scrollers);
- UI_view2d_scrollers_free(scrollers);
+ UI_view2d_scrollers_draw(v2d, NULL);
}
static void clip_preview_region_draw(const bContext *C, ARegion *region)
diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c
index d8c097cad37..3c62aeb1759 100644
--- a/source/blender/editors/space_console/space_console.c
+++ b/source/blender/editors/space_console/space_console.c
@@ -70,7 +70,7 @@ static SpaceLink *console_new(const ScrArea *UNUSED(area), const Scene *UNUSED(s
region->regiontype = RGN_TYPE_WINDOW;
/* keep in sync with info */
- region->v2d.scroll |= (V2D_SCROLL_RIGHT);
+ region->v2d.scroll |= V2D_SCROLL_RIGHT;
region->v2d.align |= V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_NEG_Y; /* align bottom left */
region->v2d.keepofs |= V2D_LOCKOFS_X;
region->v2d.keepzoom = (V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y | V2D_LIMITZOOM | V2D_KEEPASPECT);
@@ -208,7 +208,6 @@ static void console_main_region_draw(const bContext *C, ARegion *region)
/* draw entirely, view changes should be handled here */
SpaceConsole *sc = CTX_wm_space_console(C);
View2D *v2d = &region->v2d;
- View2DScrollers *scrollers;
if (BLI_listbase_is_empty(&sc->scrollback)) {
WM_operator_name_call((bContext *)C, "CONSOLE_OT_banner", WM_OP_EXEC_DEFAULT, NULL);
@@ -230,9 +229,7 @@ static void console_main_region_draw(const bContext *C, ARegion *region)
UI_view2d_view_restore(C);
/* scrollers */
- scrollers = UI_view2d_scrollers_calc(v2d, NULL);
- UI_view2d_scrollers_draw(v2d, scrollers);
- UI_view2d_scrollers_free(scrollers);
+ UI_view2d_scrollers_draw(v2d, NULL);
}
static void console_operatortypes(void)
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index d8d7ef01a2e..f60ef2b6aed 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -2740,7 +2740,7 @@ static void filelist_readjob_main_recursive(Main *bmain, FileList *filelist)
}
else {
char relname[FILE_MAX + (MAX_ID_NAME - 2) + 3];
- BLI_snprintf(relname, sizeof(relname), "%s | %s", id->lib->name, id->name + 2);
+ BLI_snprintf(relname, sizeof(relname), "%s | %s", id->lib->filepath, id->name + 2);
files->entry->relpath = BLI_strdup(relname);
}
// files->type |= S_IFREG;
diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c
index 21b705cbb44..56f3fd08bae 100644
--- a/source/blender/editors/space_file/space_file.c
+++ b/source/blender/editors/space_file/space_file.c
@@ -449,7 +449,6 @@ static void file_main_region_draw(const bContext *C, ARegion *region)
FileSelectParams *params = ED_fileselect_get_params(sfile);
View2D *v2d = &region->v2d;
- View2DScrollers *scrollers;
float col[3];
/* Needed, because filelist is not initialized on loading */
@@ -509,9 +508,7 @@ static void file_main_region_draw(const bContext *C, ARegion *region)
/* scrollers */
rcti view_rect;
ED_fileselect_layout_maskrect(sfile->layout, v2d, &view_rect);
- scrollers = UI_view2d_scrollers_calc(v2d, &view_rect);
- UI_view2d_scrollers_draw(v2d, scrollers);
- UI_view2d_scrollers_free(scrollers);
+ UI_view2d_scrollers_draw(v2d, &view_rect);
}
static void file_operatortypes(void)
diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c
index b9c7c529620..052e089942c 100644
--- a/source/blender/editors/space_graph/space_graph.c
+++ b/source/blender/editors/space_graph/space_graph.c
@@ -200,9 +200,7 @@ static void graph_main_region_draw(const bContext *C, ARegion *region)
Scene *scene = CTX_data_scene(C);
bAnimContext ac;
View2D *v2d = &region->v2d;
- View2DScrollers *scrollers;
float col[3];
- short cfra_flag = 0;
/* clear and setup matrix */
UI_GetThemeColor3fv(TH_BACK, col);
@@ -284,14 +282,6 @@ static void graph_main_region_draw(const bContext *C, ARegion *region)
immUnbindProgram();
}
- if (sipo->mode != SIPO_MODE_DRIVERS) {
- /* current frame */
- if (sipo->flag & SIPO_DRAWTIME) {
- cfra_flag |= DRAWCFRA_UNIT_SECONDS;
- }
- ANIM_draw_cfra(C, v2d, cfra_flag);
- }
-
/* markers */
if (sipo->mode != SIPO_MODE_DRIVERS) {
UI_view2d_view_orthoSpecial(region, v2d, 1);
@@ -316,12 +306,22 @@ static void graph_main_region_draw(const bContext *C, ARegion *region)
/* time-scrubbing */
ED_time_scrub_draw(region, scene, display_seconds, false);
+}
+
+static void graph_main_region_draw_overlay(const bContext *C, ARegion *region)
+{
+ /* draw entirely, view changes should be handled here */
+ const SpaceGraph *sipo = CTX_wm_space_graph(C);
+ const Scene *scene = CTX_data_scene(C);
+ const bool draw_vert_line = sipo->mode != SIPO_MODE_DRIVERS;
+ View2D *v2d = &region->v2d;
+
+ /* scrubbing region */
+ ED_time_scrub_draw_current_frame(region, scene, sipo->flag & SIPO_DRAWTIME, draw_vert_line);
/* scrollers */
// FIXME: args for scrollers depend on the type of data being shown...
- scrollers = UI_view2d_scrollers_calc(v2d, NULL);
- UI_view2d_scrollers_draw(v2d, scrollers);
- UI_view2d_scrollers_free(scrollers);
+ UI_view2d_scrollers_draw(v2d, NULL);
/* scale numbers */
{
@@ -358,7 +358,6 @@ static void graph_channel_region_draw(const bContext *C, ARegion *region)
{
bAnimContext ac;
View2D *v2d = &region->v2d;
- View2DScrollers *scrollers;
float col[3];
/* clear and setup matrix */
@@ -380,9 +379,7 @@ static void graph_channel_region_draw(const bContext *C, ARegion *region)
UI_view2d_view_restore(C);
/* scrollers */
- scrollers = UI_view2d_scrollers_calc(v2d, NULL);
- UI_view2d_scrollers_draw(v2d, scrollers);
- UI_view2d_scrollers_free(scrollers);
+ UI_view2d_scrollers_draw(v2d, NULL);
}
/* add handlers, stuff you only do once or on area/region changes */
@@ -859,6 +856,7 @@ void ED_spacetype_ipo(void)
art->regionid = RGN_TYPE_WINDOW;
art->init = graph_main_region_init;
art->draw = graph_main_region_draw;
+ art->draw_overlay = graph_main_region_draw_overlay;
art->listener = graph_region_listener;
art->message_subscribe = graph_region_message_subscribe;
art->keymapflag = ED_KEYMAP_VIEW2D | ED_KEYMAP_ANIMATION | ED_KEYMAP_FRAMES;
diff --git a/source/blender/editors/space_image/image_edit.c b/source/blender/editors/space_image/image_edit.c
index c9f2ec38354..cb0fdcf23ca 100644
--- a/source/blender/editors/space_image/image_edit.c
+++ b/source/blender/editors/space_image/image_edit.c
@@ -191,7 +191,7 @@ int ED_space_image_get_display_channel_mask(ImBuf *ibuf)
result &= ~(SI_USE_ALPHA | SI_SHOW_ALPHA);
}
if (!zbuf) {
- result &= ~(SI_SHOW_ZBUF);
+ result &= ~SI_SHOW_ZBUF;
}
if (!color) {
result &= ~(SI_SHOW_R | SI_SHOW_G | SI_SHOW_B);
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 8cb85ce9800..f71c92b4c1f 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -1237,7 +1237,7 @@ static Image *image_open_single(Main *bmain,
if (!exists) {
/* only image path after save, never ibuf */
if (is_relative_path) {
- BLI_path_rel(ima->name, relbase);
+ BLI_path_rel(ima->filepath, relbase);
}
/* handle multiview images */
@@ -1417,7 +1417,7 @@ static int image_open_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(
}
if (ima) {
- path = ima->name;
+ path = ima->filepath;
}
if (RNA_struct_property_is_set(op->ptr, "filepath")) {
@@ -1577,7 +1577,7 @@ static int image_replace_exec(bContext *C, wmOperator *op)
RNA_string_get(op->ptr, "filepath", str);
/* we cant do much if the str is longer then FILE_MAX :/ */
- BLI_strncpy(sima->image->name, str, sizeof(sima->image->name));
+ BLI_strncpy(sima->image->filepath, str, sizeof(sima->image->filepath));
if (sima->image->source == IMA_SRC_GENERATED) {
sima->image->source = IMA_SRC_FILE;
@@ -1614,10 +1614,10 @@ static int image_replace_invoke(bContext *C, wmOperator *op, const wmEvent *UNUS
}
if (!RNA_struct_property_is_set(op->ptr, "relative_path")) {
- RNA_boolean_set(op->ptr, "relative_path", BLI_path_is_rel(sima->image->name));
+ RNA_boolean_set(op->ptr, "relative_path", BLI_path_is_rel(sima->image->filepath));
}
- image_filesel(C, op, sima->image->name);
+ image_filesel(C, op, sima->image->filepath);
return OPERATOR_RUNNING_MODAL;
}
@@ -1777,7 +1777,7 @@ static int image_save_options_init(Main *bmain,
/* append UDIM numbering if not present */
if (ima->source == IMA_SRC_TILED &&
- (BLI_path_sequence_decode(ima->name, NULL, NULL, NULL) != 1001)) {
+ (BLI_path_sequence_decode(ima->filepath, NULL, NULL, NULL) != 1001)) {
int len = strlen(opts->filepath);
STR_CONCAT(opts->filepath, len, ".1001");
}
@@ -2301,7 +2301,7 @@ static bool image_should_be_saved(Image *ima, bool *is_format_writable)
static bool image_has_valid_path(Image *ima)
{
- return strchr(ima->name, '\\') || strchr(ima->name, '/');
+ return strchr(ima->filepath, '\\') || strchr(ima->filepath, '/');
}
bool ED_image_should_save_modified(const Main *bmain)
@@ -2336,7 +2336,7 @@ int ED_image_save_all_modified_info(const Main *bmain, ReportList *reports)
RPT_WARNING,
"Packed library image can't be saved: \"%s\" from \"%s\"",
ima->id.name + 2,
- ima->id.lib->name);
+ ima->id.lib->filepath);
}
}
else if (!is_format_writable) {
@@ -2348,19 +2348,21 @@ int ED_image_save_all_modified_info(const Main *bmain, ReportList *reports)
else {
if (image_has_valid_path(ima)) {
num_saveable_images++;
- if (BLI_gset_haskey(unique_paths, ima->name)) {
+ if (BLI_gset_haskey(unique_paths, ima->filepath)) {
BKE_reportf(reports,
RPT_WARNING,
"Multiple images can't be saved to an identical path: \"%s\"",
- ima->name);
+ ima->filepath);
}
else {
- BLI_gset_insert(unique_paths, BLI_strdup(ima->name));
+ BLI_gset_insert(unique_paths, BLI_strdup(ima->filepath));
}
}
else {
- BKE_reportf(
- reports, RPT_WARNING, "Image can't be saved, no valid file path: \"%s\"", ima->name);
+ BKE_reportf(reports,
+ RPT_WARNING,
+ "Image can't be saved, no valid file path: \"%s\"",
+ ima->filepath);
}
}
}
@@ -3044,7 +3046,7 @@ static int image_unpack_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE
unpack_menu(C,
"IMAGE_OT_unpack",
ima->id.name + 2,
- ima->name,
+ ima->filepath,
"textures",
BKE_image_has_packedfile(ima) ?
((ImagePackedFile *)ima->packedfiles.first)->packedfile :
diff --git a/source/blender/editors/space_info/space_info.c b/source/blender/editors/space_info/space_info.c
index 04df0f0d4f0..836830916ed 100644
--- a/source/blender/editors/space_info/space_info.c
+++ b/source/blender/editors/space_info/space_info.c
@@ -77,7 +77,7 @@ static SpaceLink *info_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scen
region->regiontype = RGN_TYPE_WINDOW;
/* keep in sync with console */
- region->v2d.scroll |= (V2D_SCROLL_RIGHT);
+ region->v2d.scroll |= V2D_SCROLL_RIGHT;
region->v2d.align |= V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_NEG_Y; /* align bottom left */
region->v2d.keepofs |= V2D_LOCKOFS_X;
region->v2d.keepzoom = (V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y | V2D_LIMITZOOM | V2D_KEEPASPECT);
@@ -139,7 +139,6 @@ static void info_main_region_draw(const bContext *C, ARegion *region)
/* draw entirely, view changes should be handled here */
SpaceInfo *sinfo = CTX_wm_space_info(C);
View2D *v2d = &region->v2d;
- View2DScrollers *scrollers;
/* clear and setup matrix */
UI_ThemeClearColor(TH_BACK);
@@ -161,9 +160,7 @@ static void info_main_region_draw(const bContext *C, ARegion *region)
UI_view2d_view_restore(C);
/* scrollers */
- scrollers = UI_view2d_scrollers_calc(v2d, NULL);
- UI_view2d_scrollers_draw(v2d, scrollers);
- UI_view2d_scrollers_free(scrollers);
+ UI_view2d_scrollers_draw(v2d, NULL);
}
static void info_operatortypes(void)
diff --git a/source/blender/editors/space_nla/nla_buttons.c b/source/blender/editors/space_nla/nla_buttons.c
index 307b6d9bc21..d0d9f2f57bb 100644
--- a/source/blender/editors/space_nla/nla_buttons.c
+++ b/source/blender/editors/space_nla/nla_buttons.c
@@ -407,7 +407,7 @@ static void nla_panel_properties(const bContext *C, Panel *panel)
uiItemR(row, &strip_ptr, "use_auto_blend", 0, NULL, ICON_NONE); // XXX as toggle?
/* settings */
- column = uiLayoutColumnWithHeading(layout, true, "Playback");
+ column = uiLayoutColumnWithHeading(layout, true, IFACE_("Playback"));
row = uiLayoutRow(column, true);
uiLayoutSetActive(row,
!(RNA_boolean_get(&strip_ptr, "use_animated_influence") ||
@@ -446,7 +446,7 @@ static void nla_panel_actclip(const bContext *C, Panel *panel)
uiItemR(column, &strip_ptr, "action_frame_start", 0, IFACE_("Frame Start"), ICON_NONE);
uiItemR(column, &strip_ptr, "action_frame_end", 0, IFACE_("End"), ICON_NONE);
- row = uiLayoutRowWithHeading(layout, false, "Sync Length");
+ row = uiLayoutRowWithHeading(layout, false, IFACE_("Sync Length"));
uiItemR(row, &strip_ptr, "use_sync_length", 0, "", ICON_NONE);
uiItemO(row, IFACE_("Now"), ICON_FILE_REFRESH, "NLA_OT_action_sync_length");
diff --git a/source/blender/editors/space_nla/space_nla.c b/source/blender/editors/space_nla/space_nla.c
index f060693d9f4..b09536e0621 100644
--- a/source/blender/editors/space_nla/space_nla.c
+++ b/source/blender/editors/space_nla/space_nla.c
@@ -120,7 +120,7 @@ static SpaceLink *nla_new(const ScrArea *area, const Scene *scene)
region->v2d.minzoom = 0.01f;
region->v2d.maxzoom = 50;
region->v2d.scroll = (V2D_SCROLL_BOTTOM | V2D_SCROLL_HORIZONTAL_HANDLES);
- region->v2d.scroll |= (V2D_SCROLL_RIGHT);
+ region->v2d.scroll |= V2D_SCROLL_RIGHT;
region->v2d.keepzoom = V2D_LOCKZOOM_Y;
region->v2d.keepofs = V2D_KEEPOFS_Y;
region->v2d.align = V2D_ALIGN_NO_POS_Y;
@@ -191,7 +191,6 @@ static void nla_channel_region_draw(const bContext *C, ARegion *region)
{
bAnimContext ac;
View2D *v2d = &region->v2d;
- View2DScrollers *scrollers;
/* clear and setup matrix */
UI_ThemeClearColor(TH_BACK);
@@ -211,9 +210,7 @@ static void nla_channel_region_draw(const bContext *C, ARegion *region)
UI_view2d_view_restore(C);
/* scrollers */
- scrollers = UI_view2d_scrollers_calc(v2d, NULL);
- UI_view2d_scrollers_draw(v2d, scrollers);
- UI_view2d_scrollers_free(scrollers);
+ UI_view2d_scrollers_draw(v2d, NULL);
}
/* add handlers, stuff you only do once or on area/region changes */
@@ -237,7 +234,6 @@ static void nla_main_region_draw(const bContext *C, ARegion *region)
Scene *scene = CTX_data_scene(C);
bAnimContext ac;
View2D *v2d = &region->v2d;
- View2DScrollers *scrollers;
short cfra_flag = 0;
/* clear and setup matrix */
@@ -263,13 +259,10 @@ static void nla_main_region_draw(const bContext *C, ARegion *region)
UI_view2d_text_cache_draw(region);
}
- UI_view2d_view_ortho(v2d);
-
/* current frame */
if (snla->flag & SNLA_DRAWTIME) {
cfra_flag |= DRAWCFRA_UNIT_SECONDS;
}
- ANIM_draw_cfra(C, v2d, cfra_flag);
/* markers */
UI_view2d_view_orthoSpecial(region, v2d, 1);
@@ -290,11 +283,20 @@ static void nla_main_region_draw(const bContext *C, ARegion *region)
UI_view2d_view_restore(C);
ED_time_scrub_draw(region, scene, snla->flag & SNLA_DRAWTIME, true);
+}
+
+static void nla_main_region_draw_overlay(const bContext *C, ARegion *region)
+{
+ /* draw entirely, view changes should be handled here */
+ const SpaceNla *snla = CTX_wm_space_nla(C);
+ const Scene *scene = CTX_data_scene(C);
+ View2D *v2d = &region->v2d;
+
+ /* scrubbing region */
+ ED_time_scrub_draw_current_frame(region, scene, snla->flag & SNLA_DRAWTIME, true);
/* scrollers */
- scrollers = UI_view2d_scrollers_calc(v2d, NULL);
- UI_view2d_scrollers_draw(v2d, scrollers);
- UI_view2d_scrollers_free(scrollers);
+ UI_view2d_scrollers_draw(v2d, NULL);
}
/* add handlers, stuff you only do once or on area/region changes */
@@ -620,6 +622,7 @@ void ED_spacetype_nla(void)
art->regionid = RGN_TYPE_WINDOW;
art->init = nla_main_region_init;
art->draw = nla_main_region_draw;
+ art->draw_overlay = nla_main_region_draw_overlay;
art->listener = nla_main_region_listener;
art->message_subscribe = nla_main_region_message_subscribe;
art->keymapflag = ED_KEYMAP_VIEW2D | ED_KEYMAP_ANIMATION | ED_KEYMAP_FRAMES;
diff --git a/source/blender/editors/space_node/CMakeLists.txt b/source/blender/editors/space_node/CMakeLists.txt
index 4e21cdc9d16..f8c30f9a688 100644
--- a/source/blender/editors/space_node/CMakeLists.txt
+++ b/source/blender/editors/space_node/CMakeLists.txt
@@ -75,10 +75,6 @@ if(WITH_OPENIMAGEDENOISE)
add_definitions(-DWITH_OPENIMAGEDENOISE)
endif()
-if (WITH_NEW_SIMULATION_TYPE)
- add_definitions(-DWITH_NEW_SIMULATION_TYPE)
-endif()
-
add_definitions(${GL_DEFINITIONS})
blender_add_lib(bf_editor_space_node "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 01ac3a80871..234ca5d5ce6 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -849,12 +849,35 @@ static void node_shader_buts_tex_environment_ex(uiLayout *layout, bContext *C, P
static void node_shader_buts_tex_sky(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "sky_type", DEFAULT_FLAGS, "", ICON_NONE);
- uiItemR(layout, ptr, "sun_direction", DEFAULT_FLAGS, "", ICON_NONE);
- uiItemR(layout, ptr, "turbidity", DEFAULT_FLAGS, NULL, ICON_NONE);
- if (RNA_enum_get(ptr, "sky_type") == SHD_SKY_NEW) {
+ if (RNA_enum_get(ptr, "sky_type") == SHD_SKY_PREETHAM) {
+ uiItemR(layout, ptr, "sun_direction", DEFAULT_FLAGS, "", ICON_NONE);
+ uiItemR(layout, ptr, "turbidity", DEFAULT_FLAGS, NULL, ICON_NONE);
+ }
+ if (RNA_enum_get(ptr, "sky_type") == SHD_SKY_HOSEK) {
+ uiItemR(layout, ptr, "sun_direction", DEFAULT_FLAGS, "", ICON_NONE);
+ uiItemR(layout, ptr, "turbidity", DEFAULT_FLAGS, NULL, ICON_NONE);
uiItemR(layout, ptr, "ground_albedo", DEFAULT_FLAGS, NULL, ICON_NONE);
}
+ if (RNA_enum_get(ptr, "sky_type") == SHD_SKY_NISHITA) {
+ uiItemR(layout, ptr, "sun_disc", DEFAULT_FLAGS, NULL, 0);
+
+ if (RNA_boolean_get(ptr, "sun_disc")) {
+ uiItemR(layout, ptr, "sun_size", DEFAULT_FLAGS, NULL, ICON_NONE);
+ }
+
+ uiLayout *col;
+ col = uiLayoutColumn(layout, true);
+ uiItemR(col, ptr, "sun_elevation", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, ptr, "sun_rotation", DEFAULT_FLAGS, NULL, ICON_NONE);
+
+ uiItemR(layout, ptr, "altitude", DEFAULT_FLAGS, NULL, ICON_NONE);
+
+ col = uiLayoutColumn(layout, true);
+ uiItemR(col, ptr, "air_density", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, ptr, "dust_density", DEFAULT_FLAGS, NULL, ICON_NONE);
+ uiItemR(col, ptr, "ozone_density", DEFAULT_FLAGS, NULL, ICON_NONE);
+ }
}
static void node_shader_buts_tex_gradient(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
@@ -991,7 +1014,14 @@ static void node_shader_buts_vertex_color(uiLayout *layout, bContext *C, Pointer
PointerRNA obptr = CTX_data_pointer_get(C, "active_object");
if (obptr.data && RNA_enum_get(&obptr, "type") == OB_MESH) {
PointerRNA dataptr = RNA_pointer_get(&obptr, "data");
- uiItemPointerR(layout, ptr, "layer_name", &dataptr, "vertex_colors", "", ICON_GROUP_VCOL);
+
+ if (RNA_collection_length(&dataptr, "sculpt_vertex_colors")) {
+ uiItemPointerR(
+ layout, ptr, "layer_name", &dataptr, "sculpt_vertex_colors", "", ICON_GROUP_VCOL);
+ }
+ else {
+ uiItemPointerR(layout, ptr, "layer_name", &dataptr, "vertex_colors", "", ICON_GROUP_VCOL);
+ }
}
else {
uiItemL(layout, "No mesh in active object.", ICON_ERROR);
diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c
index bd8950c5085..c3823d8eb27 100644
--- a/source/blender/editors/space_node/node_draw.c
+++ b/source/blender/editors/space_node/node_draw.c
@@ -1323,7 +1323,7 @@ static void node_draw_basis(const bContext *C,
UI_BTYPE_LABEL,
0,
showname,
- (int)(rct->xmin + (NODE_MARGIN_X)),
+ (int)(rct->xmin + NODE_MARGIN_X),
(int)(rct->ymax - NODE_DY),
(short)(iconofs - rct->xmin - 18.0f),
(short)NODE_DY,
@@ -1772,7 +1772,6 @@ static void draw_group_overlay(const bContext *C, ARegion *region)
void drawnodespace(const bContext *C, ARegion *region)
{
wmWindow *win = CTX_wm_window(C);
- View2DScrollers *scrollers;
SpaceNode *snode = CTX_wm_space_node(C);
View2D *v2d = &region->v2d;
@@ -1921,7 +1920,5 @@ void drawnodespace(const bContext *C, ARegion *region)
draw_tree_path(snode);
/* scrollers */
- scrollers = UI_view2d_scrollers_calc(v2d, NULL);
- UI_view2d_scrollers_draw(v2d, scrollers);
- UI_view2d_scrollers_free(scrollers);
+ UI_view2d_scrollers_draw(v2d, NULL);
}
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index ac58ec1e636..11d87148713 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -1428,11 +1428,15 @@ int node_render_changed_exec(bContext *C, wmOperator *UNUSED(op))
Scene *sce = CTX_data_scene(C);
bNode *node;
+ /* This is actually a test whether scene is used by the compositor or not.
+ * All the nodes are using same render result, so there is no need to do
+ * anything smart about check how exactly scene is used. */
for (node = sce->nodetree->nodes.first; node; node = node->next) {
- if (node->id == (ID *)sce && node->need_exec) {
+ if (node->id == (ID *)sce) {
break;
}
}
+
if (node) {
ViewLayer *view_layer = BLI_findlink(&sce->view_layers, node->custom1);
diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c
index f339d11b842..562aa6b078c 100644
--- a/source/blender/editors/space_node/space_node.c
+++ b/source/blender/editors/space_node/space_node.c
@@ -936,11 +936,10 @@ static void node_space_subtype_item_extend(bContext *C, EnumPropertyItem **item,
bool free;
const EnumPropertyItem *item_src = RNA_enum_node_tree_types_itemf_impl(C, &free);
for (const EnumPropertyItem *item_iter = item_src; item_iter->identifier; item_iter++) {
-#ifndef WITH_NEW_SIMULATION_TYPE
- if (STREQ(item_iter->identifier, "SimulationNodeTree")) {
+ if (!U.experimental.use_new_particle_system &&
+ STREQ(item_iter->identifier, "SimulationNodeTree")) {
continue;
}
-#endif
RNA_enum_item_add(item, totitem, item_iter);
}
if (free) {
diff --git a/source/blender/editors/space_outliner/outliner_collections.c b/source/blender/editors/space_outliner/outliner_collections.c
index 82ff9e06194..131491fcc40 100644
--- a/source/blender/editors/space_outliner/outliner_collections.c
+++ b/source/blender/editors/space_outliner/outliner_collections.c
@@ -581,7 +581,8 @@ static int collection_duplicate_exec(bContext *C, wmOperator *op)
"it won't be linked to any view layer");
}
- BKE_collection_duplicate(bmain, parent, collection, true, true, !linked);
+ const eDupli_ID_Flags dupli_flags = USER_DUP_OBJECT | (linked ? 0 : U.dupflag);
+ BKE_collection_duplicate(bmain, parent, collection, dupli_flags, 0);
DEG_relations_tag_update(bmain);
WM_main_add_notifier(NC_SCENE | ND_LAYER, CTX_data_scene(C));
diff --git a/source/blender/editors/space_outliner/outliner_dragdrop.c b/source/blender/editors/space_outliner/outliner_dragdrop.c
index c2c9f3a5bfb..70a628eead0 100644
--- a/source/blender/editors/space_outliner/outliner_dragdrop.c
+++ b/source/blender/editors/space_outliner/outliner_dragdrop.c
@@ -907,6 +907,9 @@ static int outliner_item_drag_drop_invoke(bContext *C,
return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
}
+ /* Scroll view when dragging near edges */
+ WM_operator_name_call(C, "VIEW2D_OT_edge_pan", WM_OP_INVOKE_DEFAULT, NULL);
+
wmDrag *drag = WM_event_start_drag(C, data.icon, WM_DRAG_ID, NULL, 0.0, WM_DRAG_NOP);
if (ELEM(GS(data.drag_id->name), ID_OB, ID_GR)) {
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index 9a9bd610322..5eee97e3fee 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -709,9 +709,9 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
Library *lib = (Library *)tselem->id;
char expanded[FILE_MAX];
- BKE_library_filepath_set(bmain, lib, lib->name);
+ BKE_library_filepath_set(bmain, lib, lib->filepath);
- BLI_strncpy(expanded, lib->name, sizeof(expanded));
+ BLI_strncpy(expanded, lib->filepath, sizeof(expanded));
BLI_path_abs(expanded, BKE_main_blendfile_path(bmain));
if (!BLI_exists(expanded)) {
BKE_reportf(CTX_wm_reports(C),
@@ -1657,7 +1657,6 @@ static void outliner_draw_userbuts(uiBlock *block,
uiBut *bt;
ID *id = tselem->id;
const char *tip = NULL;
- int icon = ICON_NONE;
char buf[16] = "";
int but_flag = UI_BUT_DRAG_LOCK;
@@ -1683,18 +1682,16 @@ static void outliner_draw_userbuts(uiBlock *block,
UI_but_flag_enable(bt, but_flag);
if (id->flag & LIB_FAKEUSER) {
- icon = ICON_FILE_TICK;
tip = TIP_("Data-block will be retained using a fake user");
}
else {
- icon = ICON_X;
tip = TIP_("Data-block has no users and will be deleted");
}
bt = uiDefIconButBitS(block,
UI_BTYPE_ICON_TOGGLE,
LIB_FAKEUSER,
1,
- icon,
+ ICON_FAKE_USER_OFF,
(int)(region->v2d.cur.xmax - OL_TOG_USER_BUTS_STATUS),
te->ys,
UI_UNIT_X,
@@ -1707,25 +1704,6 @@ static void outliner_draw_userbuts(uiBlock *block,
tip);
UI_but_func_set(bt, restrictbutton_id_user_toggle, id, NULL);
UI_but_flag_enable(bt, but_flag);
-
- bt = uiDefButBitS(block,
- UI_BTYPE_ICON_TOGGLE,
- LIB_FAKEUSER,
- 1,
- (id->flag & LIB_FAKEUSER) ? "F" : " ",
- (int)(region->v2d.cur.xmax - OL_TOG_USER_BUTS_FAKEUSER),
- te->ys,
- UI_UNIT_X,
- UI_UNIT_Y,
- &id->flag,
- 0,
- 0,
- 0,
- 0,
- TIP_("Data-block has a 'fake' user which will keep it in the file "
- "even if nothing else uses it"));
- UI_but_func_set(bt, restrictbutton_id_user_toggle, id, NULL);
- UI_but_flag_enable(bt, but_flag);
}
}
@@ -1864,7 +1842,7 @@ static void outliner_buttons(const bContext *C,
len = sizeof(((ModifierData *)0)->name);
}
else if (tselem->id && GS(tselem->id->name) == ID_LI) {
- len = sizeof(((Library *)0)->name);
+ len = sizeof(((Library *)0)->filepath);
}
else {
len = MAX_ID_NAME - 2;
@@ -2288,6 +2266,7 @@ TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te)
data.icon = ICON_MATERIAL_DATA;
break;
case TSE_POSEGRP_BASE:
+ case TSE_POSEGRP:
data.icon = ICON_GROUP_BONE;
break;
case TSE_SEQUENCE:
@@ -2702,7 +2681,7 @@ static void tselem_draw_icon(uiBlock *block,
0.0,
1.0,
alpha,
- (data.drag_id && ID_IS_LINKED(data.drag_id)) ? data.drag_id->lib->name : "");
+ (data.drag_id && ID_IS_LINKED(data.drag_id)) ? data.drag_id->lib->filepath : "");
}
}
@@ -3129,18 +3108,13 @@ static void outliner_draw_tree_element(bContext *C,
offsx += 2 * ufac;
}
- if (ELEM(tselem->type, 0, TSE_LAYER_COLLECTION) && ID_IS_LINKED(tselem->id)) {
- if (tselem->id->tag & LIB_TAG_MISSING) {
- UI_icon_draw_alpha((float)startx + offsx + 2 * ufac,
- (float)*starty + 2 * ufac,
- ICON_LIBRARY_DATA_BROKEN,
- alpha_fac);
- }
- else if (tselem->id->tag & LIB_TAG_INDIRECT) {
- UI_icon_draw_alpha((float)startx + offsx + 2 * ufac,
- (float)*starty + 2 * ufac,
- ICON_LIBRARY_DATA_INDIRECT,
- alpha_fac);
+ if (ELEM(tselem->type, 0, TSE_LAYER_COLLECTION) ||
+ ((tselem->type == TSE_RNA_STRUCT) && RNA_struct_is_ID(te->rnaptr.type))) {
+ const BIFIconID lib_icon = UI_library_icon_get(tselem->id);
+ if (lib_icon != ICON_NONE) {
+ UI_icon_draw_alpha(
+ (float)startx + offsx + 2 * ufac, (float)*starty + 2 * ufac, lib_icon, alpha_fac);
+ offsx += UI_UNIT_X + 4 * ufac;
}
else {
UI_icon_draw_alpha((float)startx + offsx + 2 * ufac,
@@ -3171,13 +3145,6 @@ static void outliner_draw_tree_element(bContext *C,
}
offsx += UI_UNIT_X + 4 * ufac;
}
- else if (ELEM(tselem->type, 0, TSE_LAYER_COLLECTION) && ID_IS_OVERRIDE_LIBRARY(tselem->id)) {
- UI_icon_draw_alpha((float)startx + offsx + 2 * ufac,
- (float)*starty + 2 * ufac,
- ICON_LIBRARY_DATA_OVERRIDE,
- alpha_fac);
- offsx += UI_UNIT_X + 4 * ufac;
- }
GPU_blend(false);
/* name */
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index 3db75d9288b..bee8b28e658 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -191,7 +191,14 @@ static int outliner_item_openclose_modal(bContext *C, wmOperator *op, const wmEv
/* Only toggle openclose on the same level as the first clicked element */
if (te->xs == data->x_location) {
outliner_item_openclose(te, data->open, false);
- ED_region_tag_redraw(region);
+
+ /* Avoid rebuild if possible. */
+ if (outliner_element_needs_rebuild_on_open_change(TREESTORE(te))) {
+ ED_region_tag_redraw(region);
+ }
+ else {
+ ED_region_tag_redraw_no_rebuild(region);
+ }
}
}
@@ -231,7 +238,13 @@ static int outliner_item_openclose_invoke(bContext *C, wmOperator *op, const wmE
(toggle_all && (outliner_flag_is_any_test(&te->subtree, TSE_CLOSED, 1)));
outliner_item_openclose(te, open, toggle_all);
- ED_region_tag_redraw(region);
+ /* Avoid rebuild if possible. */
+ if (outliner_element_needs_rebuild_on_open_change(TREESTORE(te))) {
+ ED_region_tag_redraw(region);
+ }
+ else {
+ ED_region_tag_redraw_no_rebuild(region);
+ }
/* Only toggle once for single click toggling */
if (event->type == LEFTMOUSE) {
@@ -532,7 +545,7 @@ static int outliner_id_delete_invoke_do(bContext *C,
BKE_reportf(reports,
RPT_ERROR_INVALID_INPUT,
"Cannot delete indirectly linked library '%s'",
- ((Library *)tselem->id)->filepath);
+ ((Library *)tselem->id)->filepath_abs);
return OPERATOR_CANCELLED;
}
id_delete(C, reports, te, tselem);
@@ -898,12 +911,13 @@ static int lib_relocate(
Library *lib = (Library *)tselem->id;
char dir[FILE_MAXDIR], filename[FILE_MAX];
- BLI_split_dirfile(lib->filepath, dir, filename, sizeof(dir), sizeof(filename));
+ BLI_split_dirfile(lib->filepath_abs, dir, filename, sizeof(dir), sizeof(filename));
- printf("%s, %s\n", tselem->id->name, lib->filepath);
+ printf("%s, %s\n", tselem->id->name, lib->filepath_abs);
- /* We assume if both paths in lib are not the same then lib->name was relative... */
- RNA_boolean_set(&op_props, "relative_path", BLI_path_cmp(lib->filepath, lib->name) != 0);
+ /* We assume if both paths in lib are not the same then `lib->filepath` was relative. */
+ RNA_boolean_set(
+ &op_props, "relative_path", BLI_path_cmp(lib->filepath_abs, lib->filepath) != 0);
RNA_string_set(&op_props, "directory", dir);
RNA_string_set(&op_props, "filename", filename);
@@ -930,7 +944,7 @@ static int outliner_lib_relocate_invoke_do(
BKE_reportf(reports,
RPT_ERROR_INVALID_INPUT,
"Cannot relocate indirectly linked library '%s'",
- ((Library *)tselem->id)->filepath);
+ ((Library *)tselem->id)->filepath_abs);
return OPERATOR_CANCELLED;
}
else {
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index f2b64bc2a4b..b590eb75407 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -163,8 +163,7 @@ typedef enum {
#define OL_Y_OFFSET 2
#define OL_TOG_USER_BUTS_USERS (UI_UNIT_X * 2.0f + V2D_SCROLL_WIDTH)
-#define OL_TOG_USER_BUTS_STATUS (UI_UNIT_X * 3.0f + V2D_SCROLL_WIDTH)
-#define OL_TOG_USER_BUTS_FAKEUSER (UI_UNIT_X + V2D_SCROLL_WIDTH)
+#define OL_TOG_USER_BUTS_STATUS (UI_UNIT_X + V2D_SCROLL_WIDTH)
#define OL_RNA_COLX (UI_UNIT_X * 15)
#define OL_RNA_COL_SIZEX (UI_UNIT_X * 7.5f)
@@ -216,6 +215,16 @@ typedef struct TreeViewContext {
Object *ob_pose;
} TreeViewContext;
+typedef enum TreeItemSelectAction {
+ OL_ITEM_DESELECT = 0, /* Deselect the item */
+ OL_ITEM_SELECT = (1 << 0), /* Select the item */
+ OL_ITEM_SELECT_DATA = (1 << 1), /* Select object data */
+ OL_ITEM_ACTIVATE = (1 << 2), /* Activate the item */
+ OL_ITEM_EXTEND = (1 << 3), /* Extend the current selection */
+ OL_ITEM_RECURSIVE = (1 << 4), /* Select recursively */
+ OL_ITEM_TOGGLE_MODE = (1 << 5) /* Temporary */
+} TreeItemSelectAction;
+
/* outliner_tree.c ----------------------------------------------- */
void outliner_free_tree(ListBase *tree);
@@ -228,6 +237,8 @@ void outliner_build_tree(struct Main *mainvar,
struct SpaceOutliner *soops,
struct ARegion *region);
+bool outliner_element_needs_rebuild_on_open_change(const TreeStoreElem *tselem);
+
typedef struct IDsSelectedData {
struct ListBase selected_array;
} IDsSelectedData;
@@ -266,21 +277,16 @@ eOLDrawState tree_element_active(struct bContext *C,
const eOLSetState set,
const bool handle_all_types);
-void outliner_item_do_activate_from_tree_element(
- struct bContext *C, TreeElement *te, TreeStoreElem *tselem, bool extend, bool recursive);
-
-void outliner_item_select(struct SpaceOutliner *soops,
- const struct TreeElement *te,
- const bool extend,
- const bool toggle);
+void outliner_item_select(struct bContext *C,
+ struct SpaceOutliner *soops,
+ struct TreeElement *te,
+ const short select_flag);
void outliner_object_mode_toggle(struct bContext *C,
Scene *scene,
ViewLayer *view_layer,
Base *base);
-void outliner_element_activate(struct SpaceOutliner *soops, struct TreeStoreElem *tselem);
-
bool outliner_item_is_co_over_name_icons(const TreeElement *te, float view_co_x);
bool outliner_item_is_co_within_close_toggle(const TreeElement *te, float view_co_x);
@@ -495,6 +501,7 @@ TreeElement *outliner_find_parent_element(ListBase *lb,
TreeElement *outliner_find_id(struct SpaceOutliner *soops, ListBase *lb, const struct ID *id);
TreeElement *outliner_find_posechannel(ListBase *lb, const struct bPoseChannel *pchan);
TreeElement *outliner_find_editbone(ListBase *lb, const struct EditBone *ebone);
+TreeElement *outliner_search_back_te(TreeElement *te, short idcode);
struct ID *outliner_search_back(TreeElement *te, short idcode);
bool outliner_tree_traverse(const SpaceOutliner *soops,
ListBase *tree,
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index fa8422573ab..8a408a41897 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -111,7 +111,7 @@ static bool do_outliner_activate_common(bContext *C,
* If extend is used, we try to have the other compatible selected objects in the new mode as well.
* Otherwise only the new object will be active, selected and in the edit mode.
*/
-static void do_outliner_activate_obdata(
+static void do_outliner_item_editmode_toggle(
bContext *C, Scene *scene, ViewLayer *view_layer, Base *base, const bool extend)
{
Main *bmain = CTX_data_main(C);
@@ -159,7 +159,7 @@ static void do_outliner_activate_obdata(
}
}
-static void do_outliner_activate_pose(
+static void do_outliner_item_posemode_toggle(
bContext *C, Scene *scene, ViewLayer *view_layer, Base *base, const bool extend)
{
Main *bmain = CTX_data_main(C);
@@ -214,10 +214,42 @@ void outliner_object_mode_toggle(bContext *C, Scene *scene, ViewLayer *view_laye
{
Object *obact = OBACT(view_layer);
if (obact->mode & OB_MODE_EDIT) {
- do_outliner_activate_obdata(C, scene, view_layer, base, true);
+ do_outliner_item_editmode_toggle(C, scene, view_layer, base, true);
}
else if (obact->mode & OB_MODE_POSE) {
- do_outliner_activate_pose(C, scene, view_layer, base, true);
+ do_outliner_item_posemode_toggle(C, scene, view_layer, base, true);
+ }
+}
+
+/* Toggle the item's interaction mode if supported */
+static void outliner_item_mode_toggle(bContext *C,
+ TreeViewContext *tvc,
+ TreeElement *te,
+ const bool extend)
+{
+ TreeStoreElem *tselem = TREESTORE(te);
+
+ if (tselem->type == 0) {
+ if (OB_DATA_SUPPORT_EDITMODE(te->idcode)) {
+ Object *ob = (Object *)outliner_search_back(te, ID_OB);
+ if ((ob != NULL) && (ob->data == tselem->id)) {
+ Base *base = BKE_view_layer_base_find(tvc->view_layer, ob);
+ if ((base != NULL) && (base->flag & BASE_VISIBLE_DEPSGRAPH)) {
+ do_outliner_item_editmode_toggle(C, tvc->scene, tvc->view_layer, base, extend);
+ }
+ }
+ }
+ else if (ELEM(te->idcode, ID_GD)) {
+ /* set grease pencil to object mode */
+ WM_operator_name_call(C, "GPENCIL_OT_editmode_toggle", WM_OP_INVOKE_REGION_WIN, NULL);
+ }
+ }
+ else if (tselem->type == TSE_POSE_BASE) {
+ Object *ob = (Object *)tselem->id;
+ Base *base = BKE_view_layer_base_find(tvc->view_layer, ob);
+ if (base != NULL) {
+ do_outliner_item_posemode_toggle(C, tvc->scene, tvc->view_layer, base, extend);
+ }
}
}
@@ -302,28 +334,32 @@ static void do_outliner_ebone_select_recursive(bArmature *arm, EditBone *ebone_p
static eOLDrawState tree_element_set_active_object(bContext *C,
Scene *scene,
ViewLayer *view_layer,
- SpaceOutliner *soops,
+ SpaceOutliner *UNUSED(soops),
TreeElement *te,
const eOLSetState set,
bool recursive)
{
TreeStoreElem *tselem = TREESTORE(te);
TreeStoreElem *parent_tselem = NULL;
+ TreeElement *parent_te = NULL;
Scene *sce;
Base *base;
Object *ob = NULL;
- TreeElement *te_ob = NULL;
/* if id is not object, we search back */
- if (te->idcode == ID_OB) {
+ if (tselem->type == 0 && te->idcode == ID_OB) {
ob = (Object *)tselem->id;
}
else {
- ob = (Object *)outliner_search_back(te, ID_OB);
-
- /* Don't return when activating children of the previous active object. */
- if (ob == OBACT(view_layer) && set == OL_SETSEL_NONE) {
- return OL_DRAWSEL_NONE;
+ parent_te = outliner_search_back_te(te, ID_OB);
+ if (parent_te) {
+ parent_tselem = TREESTORE(parent_te);
+ ob = (Object *)parent_tselem->id;
+
+ /* Don't return when activating children of the previous active object. */
+ if (ob == OBACT(view_layer) && set == OL_SETSEL_NONE) {
+ return OL_DRAWSEL_NONE;
+ }
}
}
if (ob == NULL) {
@@ -356,11 +392,6 @@ static eOLDrawState tree_element_set_active_object(bContext *C,
}
}
- te_ob = outliner_find_id(soops, &soops->tree, (ID *)ob);
- if (te_ob != NULL && te_ob != te) {
- parent_tselem = TREESTORE(te_ob);
- }
-
if (base) {
if (set == OL_SETSEL_EXTEND) {
/* swap select */
@@ -863,8 +894,8 @@ static eOLDrawState tree_element_active_text(bContext *UNUSED(C),
return OL_DRAWSEL_NONE;
}
-static eOLDrawState tree_element_active_pose(bContext *C,
- Scene *scene,
+static eOLDrawState tree_element_active_pose(bContext *UNUSED(C),
+ Scene *UNUSED(scene),
ViewLayer *view_layer,
TreeElement *UNUSED(te),
TreeStoreElem *tselem,
@@ -879,7 +910,6 @@ static eOLDrawState tree_element_active_pose(bContext *C,
}
if (set != OL_SETSEL_NONE) {
- do_outliner_activate_pose(C, scene, view_layer, base, (set == OL_SETSEL_EXTEND));
}
else {
if (ob->mode & OB_MODE_POSE) {
@@ -1113,13 +1143,6 @@ eOLDrawState tree_element_type_active(bContext *C,
/* ================================================ */
-/* Activate a tree store element and set the walk navigation start element */
-void outliner_element_activate(SpaceOutliner *soops, TreeStoreElem *tselem)
-{
- outliner_flag_set(&soops->tree, TSE_ACTIVE | TSE_ACTIVE_WALK, false);
- tselem->flag |= TSE_ACTIVE | TSE_ACTIVE_WALK;
-}
-
/**
* Action when clicking to activate an item (typically under the mouse cursor),
* but don't do any cursor intersection checks.
@@ -1133,9 +1156,8 @@ static void do_outliner_item_activate_tree_element(bContext *C,
TreeStoreElem *tselem,
const bool extend,
const bool recursive,
- const bool is_over_name_icons)
+ const bool do_activate_data)
{
- bool do_activate_data = soops->flag & SO_SYNC_SELECT || is_over_name_icons;
/* Always makes active object, except for some specific types. */
if (ELEM(tselem->type,
TSE_SEQUENCE,
@@ -1153,7 +1175,6 @@ static void do_outliner_item_activate_tree_element(bContext *C,
/* Support pose mode toggle, keeping the active object as is. */
}
else if (do_activate_data) {
- /* Only activate when synced selection is enabled */
tree_element_set_active_object(C,
tvc->scene,
tvc->view_layer,
@@ -1164,9 +1185,6 @@ static void do_outliner_item_activate_tree_element(bContext *C,
recursive && tselem->type == 0);
}
- /* Mark as active in the outliner */
- outliner_element_activate(soops, tselem);
-
if (tselem->type == 0) { // the lib blocks
if (do_activate_data == false) {
/* Only select in outliner. */
@@ -1216,19 +1234,6 @@ static void do_outliner_item_activate_tree_element(bContext *C,
DEG_id_tag_update(&tvc->scene->id, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, tvc->scene);
}
- else if (OB_DATA_SUPPORT_EDITMODE(te->idcode)) {
- Object *ob = (Object *)outliner_search_back(te, ID_OB);
- if ((ob != NULL) && (ob->data == tselem->id)) {
- Base *base = BKE_view_layer_base_find(tvc->view_layer, ob);
- if ((base != NULL) && (base->flag & BASE_VISIBLE_DEPSGRAPH)) {
- do_outliner_activate_obdata(C, tvc->scene, tvc->view_layer, base, extend);
- }
- }
- }
- else if (ELEM(te->idcode, ID_GD)) {
- /* set grease pencil to object mode */
- WM_operator_name_call(C, "GPENCIL_OT_editmode_toggle", WM_OP_INVOKE_REGION_WIN, NULL);
- }
else { // rest of types
tree_element_active(C, tvc, soops, te, OL_SETSEL_NORMAL, false);
}
@@ -1239,23 +1244,49 @@ static void do_outliner_item_activate_tree_element(bContext *C,
}
}
-/**
- * \param extend: Don't deselect other items, only modify \a te.
- * \param toggle: Select \a te when not selected, deselect when selected.
- */
-void outliner_item_select(SpaceOutliner *soops,
- const TreeElement *te,
- const bool extend,
- const bool toggle)
+/* Select the item using the set flags */
+void outliner_item_select(bContext *C,
+ SpaceOutliner *soops,
+ TreeElement *te,
+ const short select_flag)
{
TreeStoreElem *tselem = TREESTORE(te);
- const short new_flag = (toggle && (tselem->flag & TSE_ACTIVE)) ? (tselem->flag ^ TSE_SELECTED) :
- (tselem->flag | TSE_SELECTED);
+ const bool activate = select_flag & OL_ITEM_ACTIVATE;
+ const bool extend = select_flag & OL_ITEM_EXTEND;
+ const bool activate_data = select_flag & OL_ITEM_SELECT_DATA;
- if (extend == false) {
- outliner_flag_set(&soops->tree, TSE_SELECTED, false);
+ /* Clear previous active when activating and clear selection when not extending selection */
+ const short clear_flag = (activate ? TSE_ACTIVE : 0) | (extend ? 0 : TSE_SELECTED);
+ if (clear_flag) {
+ outliner_flag_set(&soops->tree, clear_flag, false);
+ }
+
+ if (select_flag & OL_ITEM_SELECT) {
+ tselem->flag |= TSE_SELECTED;
+ }
+ else {
+ tselem->flag &= ~TSE_SELECTED;
+ }
+
+ if (activate) {
+ TreeViewContext tvc;
+ outliner_viewcontext_init(C, &tvc);
+
+ tselem->flag |= TSE_ACTIVE;
+ do_outliner_item_activate_tree_element(C,
+ &tvc,
+ soops,
+ te,
+ tselem,
+ extend,
+ select_flag & OL_ITEM_RECURSIVE,
+ activate_data || soops->flag & SO_SYNC_SELECT);
+
+ /* Mode toggle on data activate for now, but move later */
+ if (select_flag & OL_ITEM_TOGGLE_MODE) {
+ outliner_item_mode_toggle(C, &tvc, te, extend);
+ }
}
- tselem->flag = new_flag;
}
static bool do_outliner_range_select_recursive(ListBase *lb,
@@ -1298,8 +1329,7 @@ static void do_outliner_range_select(bContext *C,
/* If no active element exists, activate the element under the cursor */
if (!active) {
- outliner_item_select(soops, cursor, false, false);
- outliner_item_do_activate_from_tree_element(C, cursor, TREESTORE(cursor), false, false);
+ outliner_item_select(C, soops, cursor, OL_ITEM_SELECT | OL_ITEM_ACTIVATE);
return;
}
@@ -1312,14 +1342,13 @@ static void do_outliner_range_select(bContext *C,
/* Select active if under cursor */
if (active == cursor) {
- TREESTORE(cursor)->flag |= TSE_SELECTED;
+ outliner_item_select(C, soops, cursor, OL_ITEM_SELECT);
return;
}
- /* If active is not selected, select the element under the cursor */
+ /* If active is not selected or visible, select and activate the element under the cursor */
if (!active_selected || !outliner_is_element_visible(active)) {
- outliner_item_select(soops, cursor, false, false);
- outliner_item_do_activate_from_tree_element(C, cursor, TREESTORE(cursor), false, false);
+ outliner_item_select(C, soops, cursor, OL_ITEM_SELECT | OL_ITEM_ACTIVATE);
return;
}
@@ -1334,23 +1363,6 @@ static bool outliner_is_co_within_restrict_columns(const SpaceOutliner *soops,
}
/**
- * A version of #outliner_item_do_activate_from_cursor that takes the tree element directly.
- * and doesn't depend on the pointer position.
- *
- * This allows us to simulate clicking on an item without dealing with the mouse cursor.
- */
-void outliner_item_do_activate_from_tree_element(
- bContext *C, TreeElement *te, TreeStoreElem *tselem, bool extend, bool recursive)
-{
- SpaceOutliner *soops = CTX_wm_space_outliner(C);
-
- TreeViewContext tvc;
- outliner_viewcontext_init(C, &tvc);
-
- do_outliner_item_activate_tree_element(C, &tvc, soops, te, tselem, extend, recursive, false);
-}
-
-/**
* Action to run when clicking in the outliner,
*
* May expend/collapse branches or activate items.
@@ -1402,14 +1414,17 @@ static int outliner_item_do_activate_from_cursor(bContext *C,
do_outliner_range_select(C, soops, activate_te, extend);
}
else {
- TreeViewContext tvc;
- outliner_viewcontext_init(C, &tvc);
-
const bool is_over_name_icons = outliner_item_is_co_over_name_icons(activate_te,
view_mval[0]);
- outliner_item_select(soops, activate_te, extend, extend);
- do_outliner_item_activate_tree_element(
- C, &tvc, soops, activate_te, activate_tselem, extend, false, is_over_name_icons);
+ /* Always select unless already active and selected */
+ const bool select = !extend || !(activate_tselem->flag & TSE_ACTIVE &&
+ activate_tselem->flag & TSE_SELECTED);
+
+ const short select_flag = OL_ITEM_ACTIVATE | (select ? OL_ITEM_SELECT : OL_ITEM_DESELECT) |
+ (is_over_name_icons ? OL_ITEM_SELECT_DATA : 0) |
+ (extend ? OL_ITEM_EXTEND : 0) | OL_ITEM_TOGGLE_MODE;
+
+ outliner_item_select(C, soops, activate_te, select_flag);
}
changed = true;
@@ -1468,23 +1483,19 @@ void OUTLINER_OT_item_activate(wmOperatorType *ot)
/* **************** Box Select Tool ****************** */
static void outliner_item_box_select(
- SpaceOutliner *soops, Scene *scene, rctf *rectf, TreeElement *te, bool select)
+ bContext *C, SpaceOutliner *soops, Scene *scene, rctf *rectf, TreeElement *te, bool select)
{
TreeStoreElem *tselem = TREESTORE(te);
if (te->ys <= rectf->ymax && te->ys + UI_UNIT_Y >= rectf->ymin) {
- if (select) {
- tselem->flag |= TSE_SELECTED;
- }
- else {
- tselem->flag &= ~TSE_SELECTED;
- }
+ outliner_item_select(
+ C, soops, te, (select ? OL_ITEM_SELECT : OL_ITEM_DESELECT) | OL_ITEM_EXTEND);
}
/* Look at its children. */
if (TSELEM_OPEN(tselem, soops)) {
for (te = te->subtree.first; te; te = te->next) {
- outliner_item_box_select(soops, scene, rectf, te, select);
+ outliner_item_box_select(C, soops, scene, rectf, te, select);
}
}
}
@@ -1506,7 +1517,7 @@ static int outliner_box_select_exec(bContext *C, wmOperator *op)
UI_view2d_region_to_view_rctf(&region->v2d, &rectf, &rectf);
LISTBASE_FOREACH (TreeElement *, te, &soops->tree) {
- outliner_item_box_select(soops, scene, &rectf, te, select);
+ outliner_item_box_select(C, soops, scene, &rectf, te, select);
}
DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
@@ -1587,17 +1598,17 @@ static TreeElement *outliner_find_rightmost_visible_child(SpaceOutliner *soops,
}
/* Find previous visible element in the tree */
-static TreeElement *outliner_find_previous_element(SpaceOutliner *soops, TreeElement *walk_element)
+static TreeElement *outliner_find_previous_element(SpaceOutliner *soops, TreeElement *te)
{
- if (walk_element->prev) {
- walk_element = outliner_find_rightmost_visible_child(soops, walk_element->prev);
+ if (te->prev) {
+ te = outliner_find_rightmost_visible_child(soops, te->prev);
}
- else if (walk_element->parent) {
+ else if (te->parent) {
/* Use parent if at beginning of list */
- walk_element = walk_element->parent;
+ te = te->parent;
}
- return walk_element;
+ return te;
}
/* Recursively search up the tree until a successor to a given element is found */
@@ -1618,98 +1629,78 @@ static TreeElement *outliner_element_find_successor_in_parents(TreeElement *te)
}
/* Find next visible element in the tree */
-static TreeElement *outliner_find_next_element(SpaceOutliner *soops, TreeElement *walk_element)
+static TreeElement *outliner_find_next_element(SpaceOutliner *soops, TreeElement *te)
{
- TreeStoreElem *tselem = TREESTORE(walk_element);
+ TreeStoreElem *tselem = TREESTORE(te);
- if (TSELEM_OPEN(tselem, soops) && walk_element->subtree.first) {
- walk_element = walk_element->subtree.first;
+ if (TSELEM_OPEN(tselem, soops) && te->subtree.first) {
+ te = te->subtree.first;
}
- else if (walk_element->next) {
- walk_element = walk_element->next;
+ else if (te->next) {
+ te = te->next;
}
else {
- walk_element = outliner_element_find_successor_in_parents(walk_element);
+ te = outliner_element_find_successor_in_parents(te);
}
- return walk_element;
+ return te;
}
static TreeElement *do_outliner_select_walk(SpaceOutliner *soops,
- TreeElement *walk_element,
+ TreeElement *te,
const int direction,
const bool extend,
const bool toggle_all)
{
- TreeStoreElem *tselem = TREESTORE(walk_element);
-
- if (!extend) {
- outliner_flag_set(&soops->tree, TSE_SELECTED, false);
- }
- tselem->flag &= ~TSE_ACTIVE_WALK;
+ TreeStoreElem *tselem = TREESTORE(te);
switch (direction) {
case UI_SELECT_WALK_UP:
- walk_element = outliner_find_previous_element(soops, walk_element);
+ te = outliner_find_previous_element(soops, te);
break;
case UI_SELECT_WALK_DOWN:
- walk_element = outliner_find_next_element(soops, walk_element);
+ te = outliner_find_next_element(soops, te);
break;
case UI_SELECT_WALK_LEFT:
- outliner_item_openclose(walk_element, false, toggle_all);
+ outliner_item_openclose(te, false, toggle_all);
break;
case UI_SELECT_WALK_RIGHT:
- outliner_item_openclose(walk_element, true, toggle_all);
+ outliner_item_openclose(te, true, toggle_all);
break;
}
- TreeStoreElem *tselem_new = TREESTORE(walk_element);
-
/* If new element is already selected, deselect the previous element */
+ TreeStoreElem *tselem_new = TREESTORE(te);
if (extend) {
tselem->flag = (tselem_new->flag & TSE_SELECTED) ? (tselem->flag & ~TSE_SELECTED) :
(tselem->flag | TSE_SELECTED);
}
- tselem_new->flag |= TSE_SELECTED | TSE_ACTIVE_WALK;
-
- return walk_element;
+ return te;
}
-/* Find walk select element, or set it if it does not exist.
- * Changed is set to true if walk element is found, false if it was set */
+/* Find the active element to walk from, or set one if none exists.
+ * Changed is set to true if the active element is found, or false if it was set */
static TreeElement *find_walk_select_start_element(SpaceOutliner *soops, bool *changed)
{
- TreeElement *walk_element = outliner_find_element_with_flag(&soops->tree, TSE_ACTIVE_WALK);
-
+ TreeElement *active_te = outliner_find_element_with_flag(&soops->tree, TSE_ACTIVE);
*changed = false;
- /* If no walk element exists, start from active */
- if (!walk_element) {
- TreeElement *active_element = outliner_find_element_with_flag(&soops->tree, TSE_ACTIVE);
-
- /* If no active element exists, use the first element in the tree */
- if (!active_element) {
- walk_element = soops->tree.first;
- }
- else {
- walk_element = active_element;
- }
-
+ /* If no active element exists, use the first element in the tree */
+ if (!active_te) {
+ active_te = soops->tree.first;
*changed = true;
}
- /* If walk element is not visible, set that element's first visible parent as walk element */
- if (!outliner_is_element_visible(walk_element)) {
- TREESTORE(walk_element)->flag &= ~TSE_ACTIVE_WALK;
-
- while (!outliner_is_element_visible(walk_element)) {
- walk_element = walk_element->parent;
+ /* If the active element is not visible, activate the first visible parent element */
+ if (!outliner_is_element_visible(active_te)) {
+ while (!outliner_is_element_visible(active_te)) {
+ active_te = active_te->parent;
}
*changed = true;
}
- return walk_element;
+ return active_te;
}
/* Scroll the outliner when the walk element reaches the top or bottom boundary */
@@ -1738,18 +1729,18 @@ static int outliner_walk_select_invoke(bContext *C, wmOperator *op, const wmEven
const bool toggle_all = RNA_boolean_get(op->ptr, "toggle_all");
bool changed;
- TreeElement *walk_element = find_walk_select_start_element(soops, &changed);
+ TreeElement *active_te = find_walk_select_start_element(soops, &changed);
- /* If finding the starting walk select element did not move the element, proceed to walk */
+ /* If finding the active element did not modify the selection, proceed to walk */
if (!changed) {
- walk_element = do_outliner_select_walk(soops, walk_element, direction, extend, toggle_all);
- }
- else {
- TREESTORE(walk_element)->flag |= TSE_SELECTED | TSE_ACTIVE_WALK;
+ active_te = do_outliner_select_walk(soops, active_te, direction, extend, toggle_all);
}
+ outliner_item_select(
+ C, soops, active_te, OL_ITEM_SELECT | OL_ITEM_ACTIVATE | (extend ? OL_ITEM_EXTEND : 0));
+
/* Scroll outliner to focus on walk element */
- outliner_walk_scroll(region, walk_element);
+ outliner_walk_scroll(region, active_te);
ED_outliner_select_sync_from_outliner(C, soops);
ED_region_tag_redraw(region);
diff --git a/source/blender/editors/space_outliner/outliner_sync.c b/source/blender/editors/space_outliner/outliner_sync.c
index 852773d3979..a4be4062746 100644
--- a/source/blender/editors/space_outliner/outliner_sync.c
+++ b/source/blender/editors/space_outliner/outliner_sync.c
@@ -392,7 +392,6 @@ void ED_outliner_select_sync_from_outliner(bContext *C, SpaceOutliner *soops)
}
static void outliner_select_sync_from_object(ViewLayer *view_layer,
- SpaceOutliner *soops,
Object *obact,
TreeElement *te,
TreeStoreElem *tselem)
@@ -403,7 +402,7 @@ static void outliner_select_sync_from_object(ViewLayer *view_layer,
const bool is_selected = (base != NULL) && ((base->flag & BASE_SELECTED) != 0);
if (base && (ob == obact)) {
- outliner_element_activate(soops, tselem);
+ tselem->flag |= TSE_ACTIVE;
}
else {
tselem->flag &= ~TSE_ACTIVE;
@@ -417,15 +416,14 @@ static void outliner_select_sync_from_object(ViewLayer *view_layer,
}
}
-static void outliner_select_sync_from_edit_bone(SpaceOutliner *soops,
- EditBone *ebone_active,
+static void outliner_select_sync_from_edit_bone(EditBone *ebone_active,
TreeElement *te,
TreeStoreElem *tselem)
{
EditBone *ebone = (EditBone *)te->directdata;
if (ebone == ebone_active) {
- outliner_element_activate(soops, tselem);
+ tselem->flag |= TSE_ACTIVE;
}
else {
tselem->flag &= ~TSE_ACTIVE;
@@ -439,8 +437,7 @@ static void outliner_select_sync_from_edit_bone(SpaceOutliner *soops,
}
}
-static void outliner_select_sync_from_pose_bone(SpaceOutliner *soops,
- bPoseChannel *pchan_active,
+static void outliner_select_sync_from_pose_bone(bPoseChannel *pchan_active,
TreeElement *te,
TreeStoreElem *tselem)
{
@@ -448,7 +445,7 @@ static void outliner_select_sync_from_pose_bone(SpaceOutliner *soops,
Bone *bone = pchan->bone;
if (pchan == pchan_active) {
- outliner_element_activate(soops, tselem);
+ tselem->flag |= TSE_ACTIVE;
}
else {
tselem->flag &= ~TSE_ACTIVE;
@@ -462,14 +459,12 @@ static void outliner_select_sync_from_pose_bone(SpaceOutliner *soops,
}
}
-static void outliner_select_sync_from_sequence(SpaceOutliner *soops,
- Sequence *sequence_active,
- TreeStoreElem *tselem)
+static void outliner_select_sync_from_sequence(Sequence *sequence_active, TreeStoreElem *tselem)
{
Sequence *seq = (Sequence *)tselem->id;
if (seq == sequence_active) {
- outliner_element_activate(soops, tselem);
+ tselem->flag |= TSE_ACTIVE;
}
else {
tselem->flag &= ~TSE_ACTIVE;
@@ -506,26 +501,26 @@ static void outliner_sync_selection_to_outliner(ViewLayer *view_layer,
if (tselem->type == 0 && te->idcode == ID_OB) {
if (sync_types->object) {
- outliner_select_sync_from_object(view_layer, soops, active_data->object, te, tselem);
+ outliner_select_sync_from_object(view_layer, active_data->object, te, tselem);
}
}
else if (tselem->type == TSE_EBONE) {
if (sync_types->edit_bone) {
- outliner_select_sync_from_edit_bone(soops, active_data->edit_bone, te, tselem);
+ outliner_select_sync_from_edit_bone(active_data->edit_bone, te, tselem);
}
}
else if (tselem->type == TSE_POSE_CHANNEL) {
if (sync_types->pose_bone) {
- outliner_select_sync_from_pose_bone(soops, active_data->pose_channel, te, tselem);
+ outliner_select_sync_from_pose_bone(active_data->pose_channel, te, tselem);
}
}
else if (tselem->type == TSE_SEQUENCE) {
if (sync_types->sequence) {
- outliner_select_sync_from_sequence(soops, active_data->sequence, tselem);
+ outliner_select_sync_from_sequence(active_data->sequence, tselem);
}
}
else {
- tselem->flag &= ~TSE_SELECTED;
+ tselem->flag &= ~(TSE_SELECTED | TSE_ACTIVE);
}
/* Sync subtree elements */
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index b4c5dd8813a..51b919cd0dc 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -44,6 +44,7 @@
#include "DNA_world_types.h"
#include "BLI_blenlib.h"
+#include "BLI_ghash.h"
#include "BLI_utildefines.h"
#include "BKE_anim_data.h"
@@ -573,8 +574,7 @@ static void merged_element_search_exec_fn(struct bContext *C, void *UNUSED(arg1)
SpaceOutliner *soops = CTX_wm_space_outliner(C);
TreeElement *te = (TreeElement *)element;
- outliner_item_select(soops, te, false, false);
- outliner_item_do_activate_from_tree_element(C, te, te->store_elem, false, false);
+ outliner_item_select(C, soops, te, OL_ITEM_SELECT | OL_ITEM_ACTIVATE);
ED_outliner_select_sync_from_outliner(C, soops);
}
@@ -664,12 +664,13 @@ static void object_select_hierarchy_cb(bContext *C,
Scene *UNUSED(scene),
TreeElement *te,
TreeStoreElem *UNUSED(tsep),
- TreeStoreElem *tselem,
+ TreeStoreElem *UNUSED(tselem),
void *UNUSED(user_data))
{
/* Don't extend because this toggles, which is nice for Ctrl-Click but not for a menu item.
* it's especially confusing when multiple items are selected since some toggle on/off. */
- outliner_item_do_activate_from_tree_element(C, te, tselem, false, true);
+ SpaceOutliner *soops = CTX_wm_space_outliner(C);
+ outliner_item_select(C, soops, te, OL_ITEM_SELECT | OL_ITEM_ACTIVATE | OL_ITEM_RECURSIVE);
}
static void object_deselect_cb(bContext *C,
@@ -689,12 +690,8 @@ static void object_deselect_cb(bContext *C,
}
}
-static void outliner_object_delete(bContext *C,
- ReportList *reports,
- Scene *scene,
- TreeStoreElem *tselem)
+static void outliner_object_delete_fn(bContext *C, ReportList *reports, Scene *scene, Object *ob)
{
- Object *ob = (Object *)tselem->id;
if (ob) {
Main *bmain = CTX_data_main(C);
if (ob->id.tag & LIB_TAG_INDIRECT) {
@@ -862,7 +859,6 @@ void outliner_do_object_operation_ex(bContext *C,
bool select_recurse)
{
TreeElement *te;
-
for (te = lb->first; te; te = te->next) {
TreeStoreElem *tselem = TREESTORE(te);
bool select_handled = false;
@@ -1177,82 +1173,6 @@ static void outliner_do_data_operation(
}
}
-static Base *outline_delete_hierarchy(bContext *C, ReportList *reports, Scene *scene, Base *base)
-{
- Base *child_base, *base_next;
- Object *parent;
- ViewLayer *view_layer = CTX_data_view_layer(C);
-
- if (!base) {
- return NULL;
- }
-
- for (child_base = view_layer->object_bases.first; child_base; child_base = base_next) {
- base_next = child_base->next;
- for (parent = child_base->object->parent; parent && (parent != base->object);
- parent = parent->parent) {
- /* pass */
- }
- if (parent) {
- base_next = outline_delete_hierarchy(C, reports, scene, child_base);
- }
- }
-
- base_next = base->next;
-
- Main *bmain = CTX_data_main(C);
- if (base->object->id.tag & LIB_TAG_INDIRECT) {
- BKE_reportf(reports,
- RPT_WARNING,
- "Cannot delete indirectly linked object '%s'",
- base->object->id.name + 2);
- return base_next;
- }
- else if (BKE_library_ID_is_indirectly_used(bmain, base->object) &&
- ID_REAL_USERS(base->object) <= 1 && ID_EXTRA_USERS(base->object) == 0) {
- BKE_reportf(reports,
- RPT_WARNING,
- "Cannot delete object '%s' from scene '%s', indirectly used objects need at least "
- "one user",
- base->object->id.name + 2,
- scene->id.name + 2);
- return base_next;
- }
- ED_object_base_free_and_unlink(CTX_data_main(C), scene, base->object);
- return base_next;
-}
-
-static void object_delete_hierarchy_cb(bContext *C,
- ReportList *reports,
- Scene *scene,
- TreeElement *te,
- TreeStoreElem *UNUSED(tsep),
- TreeStoreElem *tselem,
- void *UNUSED(user_data))
-{
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Base *base = (Base *)te->directdata;
- Object *obedit = CTX_data_edit_object(C);
-
- if (!base) {
- base = BKE_view_layer_base_find(view_layer, (Object *)tselem->id);
- }
- if (base) {
- /* Check also library later. */
- for (; obedit && (obedit != base->object); obedit = obedit->parent) {
- /* pass */
- }
- if (obedit == base->object) {
- ED_object_editmode_exit(C, EM_FREEDATA);
- }
-
- outline_delete_hierarchy(C, reports, scene, base);
- }
-
- DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
-}
-
static Base *outline_batch_delete_hierarchy(
ReportList *reports, Main *bmain, ViewLayer *view_layer, Scene *scene, Base *base)
{
@@ -1305,21 +1225,16 @@ static Base *outline_batch_delete_hierarchy(
return base_next;
}
-static void object_batch_delete_hierarchy_cb(bContext *C,
+static void object_batch_delete_hierarchy_fn(bContext *C,
ReportList *reports,
Scene *scene,
- TreeElement *te,
- TreeStoreElem *UNUSED(tsep),
- TreeStoreElem *tselem,
- void *UNUSED(user_data))
+ Object *ob)
{
ViewLayer *view_layer = CTX_data_view_layer(C);
- Base *base = (Base *)te->directdata;
Object *obedit = CTX_data_edit_object(C);
- if (!base) {
- base = BKE_view_layer_base_find(view_layer, (Object *)tselem->id);
- }
+ Base *base = BKE_view_layer_base_find(view_layer, ob);
+
if (base) {
/* Check also library later. */
for (; obedit && (obedit != base->object); obedit = obedit->parent) {
@@ -1343,7 +1258,6 @@ enum {
OL_OP_SELECT = 1,
OL_OP_DESELECT,
OL_OP_SELECT_HIERARCHY,
- OL_OP_DELETE_HIERARCHY,
OL_OP_REMAP,
OL_OP_LOCALIZED, /* disabled, see below */
OL_OP_TOGVIS,
@@ -1358,7 +1272,6 @@ static const EnumPropertyItem prop_object_op_types[] = {
{OL_OP_SELECT, "SELECT", ICON_RESTRICT_SELECT_OFF, "Select", ""},
{OL_OP_DESELECT, "DESELECT", 0, "Deselect", ""},
{OL_OP_SELECT_HIERARCHY, "SELECT_HIERARCHY", 0, "Select Hierarchy", ""},
- {OL_OP_DELETE_HIERARCHY, "DELETE_HIERARCHY", 0, "Delete Hierarchy", ""},
{OL_OP_REMAP,
"REMAP",
0,
@@ -1372,7 +1285,6 @@ static const EnumPropertyItem prop_object_op_types[] = {
static int outliner_object_operation_exec(bContext *C, wmOperator *op)
{
- struct wmMsgBus *mbus = CTX_wm_message_bus(C);
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
wmWindow *win = CTX_wm_window(C);
@@ -1413,43 +1325,6 @@ static int outliner_object_operation_exec(bContext *C, wmOperator *op)
str = "Deselect Objects";
selection_changed = true;
}
- else if (event == OL_OP_DELETE_HIERARCHY) {
- ViewLayer *view_layer = CTX_data_view_layer(C);
- const Base *basact_prev = BASACT(view_layer);
-
- /* Keeping old 'safe and slow' code for a bit (new one enabled on 28/01/2019). */
- if (G.debug_value == 666) {
- outliner_do_object_operation_ex(
- C, op->reports, scene, soops, &soops->tree, object_delete_hierarchy_cb, NULL, false);
- }
- else {
- BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
-
- outliner_do_object_operation_ex(C,
- op->reports,
- scene,
- soops,
- &soops->tree,
- object_batch_delete_hierarchy_cb,
- NULL,
- false);
-
- BKE_id_multi_tagged_delete(bmain);
- }
-
- /* XXX: See outliner_delete_exec comment below. */
- outliner_cleanup_tree(soops);
-
- DEG_relations_tag_update(bmain);
- str = "Delete Object Hierarchy";
- DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
- if (basact_prev != BASACT(view_layer)) {
- WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
- WM_msg_publish_rna_prop(mbus, &scene->id, view_layer, LayerObjects, active);
- }
- selection_changed = true;
- }
else if (event == OL_OP_REMAP) {
outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, id_remap_cb, NULL);
/* No undo push here, operator does it itself (since it's a modal one, the op_undo_depth trick
@@ -1513,22 +1388,38 @@ void OUTLINER_OT_object_operation(wmOperatorType *ot)
/** \name Delete Object/Collection Operator
* \{ */
-static void outliner_objects_delete(
- bContext *C, Scene *scene, SpaceOutliner *soops, ReportList *reports, ListBase *lb)
+typedef void (*OutlinerDeleteFunc)(bContext *C, ReportList *reports, Scene *scene, Object *ob);
+
+static void outliner_do_object_delete(bContext *C,
+ ReportList *reports,
+ Scene *scene,
+ GSet *objects_to_delete,
+ OutlinerDeleteFunc delete_fn)
{
- LISTBASE_FOREACH (TreeElement *, te, lb) {
- TreeStoreElem *tselem = TREESTORE(te);
+ GSetIterator objects_to_delete_iter;
+ GSET_ITER (objects_to_delete_iter, objects_to_delete) {
+ Object *ob = (Object *)BLI_gsetIterator_getKey(&objects_to_delete_iter);
- if (tselem->flag & TSE_SELECTED) {
- if (tselem->type == 0 && te->idcode == ID_OB) {
- outliner_object_delete(C, reports, scene, tselem);
- }
- }
+ delete_fn(C, reports, scene, ob);
+ }
+}
- if (TSELEM_OPEN(tselem, soops)) {
- outliner_objects_delete(C, scene, soops, reports, &te->subtree);
- }
+static TreeTraversalAction outliner_find_objects_to_delete(TreeElement *te, void *customdata)
+{
+ GSet *objects_to_delete = (GSet *)customdata;
+ TreeStoreElem *tselem = TREESTORE(te);
+
+ if (outliner_is_collection_tree_element(te)) {
+ return TRAVERSE_CONTINUE;
}
+
+ if (tselem->type || (tselem->id == NULL) || (GS(tselem->id->name) != ID_OB)) {
+ return TRAVERSE_SKIP_CHILDS;
+ }
+
+ BLI_gset_add(objects_to_delete, tselem->id);
+
+ return TRAVERSE_CONTINUE;
}
static int outliner_delete_exec(bContext *C, wmOperator *op)
@@ -1537,12 +1428,32 @@ static int outliner_delete_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
SpaceOutliner *soops = CTX_wm_space_outliner(C);
struct wmMsgBus *mbus = CTX_wm_message_bus(C);
-
ViewLayer *view_layer = CTX_data_view_layer(C);
const Base *basact_prev = BASACT(view_layer);
- outliner_collection_delete(C, bmain, scene, op->reports, false);
- outliner_objects_delete(C, scene, soops, op->reports, &soops->tree);
+ const bool delete_hierarchy = RNA_boolean_get(op->ptr, "hierarchy");
+
+ /* Get selected objects skipping duplicates to prevent deleting objects linked to multiple
+ * collections twice */
+ GSet *objects_to_delete = BLI_gset_ptr_new(__func__);
+ outliner_tree_traverse(
+ soops, &soops->tree, 0, TSE_SELECTED, outliner_find_objects_to_delete, objects_to_delete);
+
+ if (delete_hierarchy) {
+ BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
+
+ outliner_do_object_delete(
+ C, op->reports, scene, objects_to_delete, object_batch_delete_hierarchy_fn);
+
+ BKE_id_multi_tagged_delete(bmain);
+ }
+ else {
+ outliner_do_object_delete(C, op->reports, scene, objects_to_delete, outliner_object_delete_fn);
+ }
+
+ BLI_gset_free(objects_to_delete, NULL);
+
+ outliner_collection_delete(C, bmain, scene, op->reports, delete_hierarchy);
/* Tree management normally happens from draw_outliner(), but when
* you're clicking too fast on Delete object from context menu in
@@ -1579,6 +1490,11 @@ void OUTLINER_OT_delete(wmOperatorType *ot)
/* flags */
ot->flag |= OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ PropertyRNA *prop = RNA_def_boolean(
+ ot->srna, "hierarchy", false, "Hierarchy", "Delete child objects and collections");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
/** \} */
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index d6efe683673..bc272431e3a 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -235,6 +235,17 @@ static TreeElement *outliner_add_element(
/* -------------------------------------------------------- */
+/**
+ * Check if an element type needs a full rebuild if the open/collapsed state changes.
+ * These element types don't add children if collapsed.
+ *
+ * This current check isn't great really. A per element-type flag would be preferable.
+ */
+bool outliner_element_needs_rebuild_on_open_change(const TreeStoreElem *tselem)
+{
+ return ELEM(tselem->type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_KEYMAP);
+}
+
/* special handling of hierarchical non-lib data */
static void outliner_add_bone(
SpaceOutliner *soops, ListBase *lb, ID *id, Bone *curBone, TreeElement *parent, int *a)
@@ -538,7 +549,7 @@ static void outliner_add_id_contents(SpaceOutliner *soops,
/* expand specific data always */
switch (GS(id->name)) {
case ID_LI: {
- te->name = ((Library *)id)->name;
+ te->name = ((Library *)id)->filepath;
break;
}
case ID_SCE: {
@@ -786,8 +797,13 @@ static void outliner_add_id_contents(SpaceOutliner *soops,
}
}
-// TODO: this function needs to be split up! It's getting a bit too large...
-// Note: "ID" is not always a real ID
+/**
+ * TODO: this function needs to be split up! It's getting a bit too large...
+ *
+ * \note: "ID" is not always a real ID
+ * \note: If child items are only added to the tree if the item is open, the TSE_ type _must_ be
+ * added to #outliner_element_needs_rebuild_on_open_change().
+ */
static TreeElement *outliner_add_element(
SpaceOutliner *soops, ListBase *lb, void *idv, TreeElement *parent, short type, short index)
{
@@ -854,7 +870,7 @@ static TreeElement *outliner_add_element(
else {
/* do here too, for blend file viewer, own ID_LI then shows file name */
if (GS(id->name) == ID_LI) {
- te->name = ((Library *)id)->name;
+ te->name = ((Library *)id)->filepath;
}
else {
te->name = id->name + 2; // default, can be overridden by Library or non-ID data
@@ -2340,8 +2356,10 @@ void outliner_build_tree(
for (lib = mainvar->libraries.first; lib; lib = lib->id.next) {
ten = outliner_add_library_contents(mainvar, soops, &soops->tree, lib);
- BLI_assert(ten != NULL);
- lib->id.newid = (ID *)ten;
+ /* NULL-check matters, due to filtering there may not be a new element. */
+ if (ten) {
+ lib->id.newid = (ID *)ten;
+ }
}
/* make hierarchy */
ten = soops->tree.first;
diff --git a/source/blender/editors/space_outliner/outliner_utils.c b/source/blender/editors/space_outliner/outliner_utils.c
index a058c30cef2..a120718e36b 100644
--- a/source/blender/editors/space_outliner/outliner_utils.c
+++ b/source/blender/editors/space_outliner/outliner_utils.c
@@ -84,12 +84,24 @@ TreeElement *outliner_find_item_at_y(const SpaceOutliner *soops,
/* co_y is inside this element */
return te_iter;
}
- else if (TSELEM_OPEN(te_iter->store_elem, soops)) {
- /* co_y is lower than current element, possibly inside children */
- TreeElement *te_sub = outliner_find_item_at_y(soops, &te_iter->subtree, view_co_y);
- if (te_sub) {
- return te_sub;
- }
+
+ if (BLI_listbase_is_empty(&te_iter->subtree) || !TSELEM_OPEN(TREESTORE(te_iter), soops)) {
+ /* No need for recursion. */
+ continue;
+ }
+
+ /* If the coordinate is lower than the next element, we can continue with that one and skip
+ * recursion too. */
+ const TreeElement *te_next = te_iter->next;
+ if (te_next && (view_co_y < (te_next->ys + UI_UNIT_Y))) {
+ continue;
+ }
+
+ /* co_y is lower than current element (but not lower than the next one), possibly inside
+ * children */
+ TreeElement *te_sub = outliner_find_item_at_y(soops, &te_iter->subtree, view_co_y);
+ if (te_sub) {
+ return te_sub;
}
}
}
@@ -256,7 +268,7 @@ TreeElement *outliner_find_editbone(ListBase *lb, const EditBone *ebone)
return NULL;
}
-ID *outliner_search_back(TreeElement *te, short idcode)
+TreeElement *outliner_search_back_te(TreeElement *te, short idcode)
{
TreeStoreElem *tselem;
te = te->parent;
@@ -264,13 +276,26 @@ ID *outliner_search_back(TreeElement *te, short idcode)
while (te) {
tselem = TREESTORE(te);
if (tselem->type == 0 && te->idcode == idcode) {
- return tselem->id;
+ return te;
}
te = te->parent;
}
return NULL;
}
+ID *outliner_search_back(TreeElement *te, short idcode)
+{
+ TreeElement *search_te;
+ TreeStoreElem *tselem;
+
+ search_te = outliner_search_back_te(te, idcode);
+ if (search_te) {
+ tselem = TREESTORE(search_te);
+ return tselem->id;
+ }
+ return NULL;
+}
+
/**
* Iterate over all tree elements (pre-order traversal), executing \a func callback for
* each tree element matching the optional filters.
diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c
index 9450136b6a6..aa1663dff01 100644
--- a/source/blender/editors/space_outliner/space_outliner.c
+++ b/source/blender/editors/space_outliner/space_outliner.c
@@ -84,7 +84,6 @@ static void outliner_main_region_init(wmWindowManager *wm, ARegion *region)
static void outliner_main_region_draw(const bContext *C, ARegion *region)
{
View2D *v2d = &region->v2d;
- View2DScrollers *scrollers;
/* clear */
UI_ThemeClearColor(TH_BACK);
@@ -96,9 +95,7 @@ static void outliner_main_region_draw(const bContext *C, ARegion *region)
UI_view2d_view_restore(C);
/* scrollers */
- scrollers = UI_view2d_scrollers_calc(v2d, NULL);
- UI_view2d_scrollers_draw(v2d, scrollers);
- UI_view2d_scrollers_free(scrollers);
+ UI_view2d_scrollers_draw(v2d, NULL);
}
static void outliner_main_region_free(ARegion *UNUSED(region))
@@ -215,7 +212,7 @@ static void outliner_main_region_listener(wmWindow *UNUSED(win),
}
break;
case NC_SCREEN:
- if (ELEM(wmn->data, ND_LAYER)) {
+ if (ELEM(wmn->data, ND_LAYOUTDELETE, ND_LAYER)) {
ED_region_tag_redraw(region);
}
break;
@@ -398,7 +395,7 @@ static void outliner_deactivate(struct ScrArea *area)
/* Remove hover highlights */
SpaceOutliner *soops = area->spacedata.first;
outliner_flag_set(&soops->tree, TSE_HIGHLIGHTED, false);
- ED_region_tag_redraw(BKE_area_find_region_type(area, RGN_TYPE_WINDOW));
+ ED_region_tag_redraw_no_rebuild(BKE_area_find_region_type(area, RGN_TYPE_WINDOW));
}
/* only called once, from space_api/spacetypes.c */
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index 1f06ab68516..1af552680a3 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -697,7 +697,8 @@ static void draw_seq_text(View2D *v2d,
str_len = 0;
}
else if (seq->sound) {
- str_len = BLI_snprintf(str, sizeof(str), "%s: %s | %d", name, seq->sound->name, seq->len);
+ str_len = BLI_snprintf(
+ str, sizeof(str), "%s: %s | %d", name, seq->sound->filepath, seq->len);
}
else {
str_len = BLI_snprintf(str, sizeof(str), "%s | %d", name, seq->len);
@@ -2257,7 +2258,6 @@ void draw_timeline_seq(const bContext *C, ARegion *region)
Editing *ed = BKE_sequencer_editing_get(scene, false);
SpaceSeq *sseq = CTX_wm_space_seq(C);
View2D *v2d = &region->v2d;
- View2DScrollers *scrollers;
short cfra_flag = 0;
float col[3];
@@ -2299,9 +2299,6 @@ void draw_timeline_seq(const bContext *C, ARegion *region)
cfra_flag |= DRAWCFRA_UNIT_SECONDS;
}
- /* Draw the current frame indicator. */
- ANIM_draw_cfra(C, v2d, cfra_flag);
-
/* Draw overlap frame frame indicator. */
if (scene->ed && scene->ed->over_flag & SEQ_EDIT_OVERLAY_SHOW) {
int cfra_over = (scene->ed->over_flag & SEQ_EDIT_OVERLAY_ABS) ?
@@ -2345,9 +2342,6 @@ void draw_timeline_seq(const bContext *C, ARegion *region)
ED_region_draw_cb_draw(C, region, REGION_DRAW_POST_VIEW);
UI_view2d_view_restore(C);
ED_time_scrub_draw(region, scene, !(sseq->flag & SEQ_DRAWFRAMES), true);
- scrollers = UI_view2d_scrollers_calc(v2d, NULL);
- UI_view2d_scrollers_draw(v2d, scrollers);
- UI_view2d_scrollers_free(scrollers);
/* Draw channel numbers. */
{
@@ -2357,3 +2351,13 @@ void draw_timeline_seq(const bContext *C, ARegion *region)
UI_view2d_draw_scale_y__block(region, v2d, &rect, TH_SCROLL_TEXT);
}
}
+
+void draw_timeline_seq_display(const bContext *C, ARegion *region)
+{
+ const Scene *scene = CTX_data_scene(C);
+ const SpaceSeq *sseq = CTX_wm_space_seq(C);
+ View2D *v2d = &region->v2d;
+
+ ED_time_scrub_draw_current_frame(region, scene, !(sseq->flag & SEQ_DRAWFRAMES), true);
+ UI_view2d_scrollers_draw(v2d, NULL);
+}
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index 9311cbed265..f74a4eae3bb 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -673,6 +673,14 @@ int seq_effect_find_selected(Scene *scene,
*r_selseq2 = seq2;
*r_selseq3 = seq3;
+ /* TODO(Richard): This function needs some refactoring, this is just quick hack for T73828. */
+ if (BKE_sequence_effect_get_num_inputs(type) < 3) {
+ *r_selseq3 = NULL;
+ }
+ if (BKE_sequence_effect_get_num_inputs(type) < 2) {
+ *r_selseq2 = NULL;
+ }
+
return 1;
}
@@ -1403,14 +1411,21 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op)
BKE_sequence_base_shuffle(ed->seqbasep, seq, scene);
}
}
- else if (seq->type & SEQ_TYPE_EFFECT) {
+ }
+
+ /* Recalculate bounds of effect strips. */
+ for (seq = ed->seqbasep->first; seq; seq = seq->next) {
+ if (seq->type & SEQ_TYPE_EFFECT) {
if (seq->seq1 && (seq->seq1->flag & SELECT)) {
+ BKE_sequencer_offset_animdata(scene, seq, (snap_frame - seq->startdisp));
BKE_sequence_calc(scene, seq);
}
else if (seq->seq2 && (seq->seq2->flag & SELECT)) {
+ BKE_sequencer_offset_animdata(scene, seq, (snap_frame - seq->startdisp));
BKE_sequence_calc(scene, seq);
}
else if (seq->seq3 && (seq->seq3->flag & SELECT)) {
+ BKE_sequencer_offset_animdata(scene, seq, (snap_frame - seq->startdisp));
BKE_sequence_calc(scene, seq);
}
}
@@ -2218,6 +2233,11 @@ static int sequencer_reassign_inputs_exec(bContext *C, wmOperator *op)
Sequence *seq1, *seq2, *seq3, *last_seq = BKE_sequencer_active_get(scene);
const char *error_msg;
+ if (BKE_sequence_effect_get_num_inputs(last_seq->type) != 0) {
+ BKE_report(op->reports, RPT_ERROR, "Cannot reassign inputs: strip has no inputs");
+ return OPERATOR_CANCELLED;
+ }
+
if (!seq_effect_find_selected(
scene, last_seq, last_seq->type, &seq1, &seq2, &seq3, &error_msg)) {
BKE_report(op->reports, RPT_ERROR, error_msg);
@@ -3433,6 +3453,7 @@ static int sequencer_paste_exec(bContext *C, wmOperator *UNUSED(op))
* on the actual data-blocks. */
BKE_sequencer_base_clipboard_pointers_restore(&seqbase_clipboard, bmain);
BKE_sequence_base_dupli_recursive(scene, scene, &nseqbase, &seqbase_clipboard, 0, 0);
+ BKE_sequencer_base_clipboard_pointers_store(bmain, &seqbase_clipboard);
iseq_first = nseqbase.first;
@@ -3451,6 +3472,7 @@ static int sequencer_paste_exec(bContext *C, wmOperator *UNUSED(op))
}
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
+ DEG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
ED_outliner_select_sync_from_sequence_tag(C);
@@ -3925,7 +3947,7 @@ static int sequencer_change_path_exec(bContext *C, wmOperator *op)
}
char filepath[FILE_MAX];
RNA_string_get(op->ptr, "filepath", filepath);
- BLI_strncpy(sound->name, filepath, sizeof(sound->name));
+ BLI_strncpy(sound->filepath, filepath, sizeof(sound->filepath));
BKE_sound_load(bmain, sound);
}
else {
diff --git a/source/blender/editors/space_sequencer/sequencer_intern.h b/source/blender/editors/space_sequencer/sequencer_intern.h
index 12533dbc74f..fee07e8941d 100644
--- a/source/blender/editors/space_sequencer/sequencer_intern.h
+++ b/source/blender/editors/space_sequencer/sequencer_intern.h
@@ -43,6 +43,7 @@ struct wmOperator;
/* sequencer_draw.c */
void draw_timeline_seq(const struct bContext *C, struct ARegion *region);
+void draw_timeline_seq_display(const struct bContext *C, struct ARegion *region);
void sequencer_draw_preview(const struct bContext *C,
struct Scene *scene,
struct ARegion *region,
diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c
index 2686edd58a5..85b70354ab3 100644
--- a/source/blender/editors/space_sequencer/sequencer_select.c
+++ b/source/blender/editors/space_sequencer/sequencer_select.c
@@ -409,32 +409,15 @@ static int sequencer_select_exec(bContext *C, wmOperator *op)
/* Select left, right or overlapping the current frame. */
if (side_of_frame) {
/* Use different logic for this. */
- float x;
if (extend == false) {
ED_sequencer_deselect_all(scene);
}
- /* 10px margin around current frame to select under the current frame with mouse. */
- float margin = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask) * 10;
- x = UI_view2d_region_to_view_x(v2d, mval[0]);
- if (x >= CFRA - margin && x <= CFRA + margin) {
- x = CFRA;
- }
+ const float x = UI_view2d_region_to_view_x(v2d, mval[0]);
SEQP_BEGIN (ed, seq) {
- bool test = false;
- /* FIXME(campbell): this functionality is only in the sequencer,
- * either we should support this for all timeline views or remove it. */
- if ((x == CFRA) && (seq->startdisp <= CFRA) && (seq->enddisp >= CFRA)) {
- /* Select overlapping the current frame. */
- test = true;
- }
- else if ((x < CFRA && seq->enddisp <= CFRA) || (x > CFRA && seq->startdisp >= CFRA)) {
+ if (((x < CFRA) && (seq->enddisp <= CFRA)) || ((x >= CFRA) && (seq->startdisp >= CFRA))) {
/* Select left or right. */
- test = true;
- }
-
- if (test) {
seq->flag |= SELECT;
recurs_sel_seq(seq);
}
@@ -1023,7 +1006,6 @@ static int sequencer_select_side_of_frame_exec(bContext *C, wmOperator *op)
void SEQUENCER_OT_select_side_of_frame(wmOperatorType *ot)
{
static const EnumPropertyItem sequencer_select_left_right_types[] = {
- {0, "OVERLAP", 0, "Overlap", "Select overlapping the current frame"},
{-1, "LEFT", 0, "Left", "Select to the left of the current frame"},
{1, "RIGHT", 0, "Right", "Select to the right of the current frame"},
{0, NULL, 0, NULL, NULL},
diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c
index f52cfdd34c0..368f9c1af19 100644
--- a/source/blender/editors/space_sequencer/space_sequencer.c
+++ b/source/blender/editors/space_sequencer/space_sequencer.c
@@ -521,6 +521,12 @@ static void sequencer_main_region_draw(const bContext *C, ARegion *region)
draw_timeline_seq(C, region);
}
+/* Strip editing timeline. */
+static void sequencer_main_region_draw_overlay(const bContext *C, ARegion *region)
+{
+ draw_timeline_seq_display(C, region);
+}
+
static void sequencer_main_region_listener(wmWindow *UNUSED(win),
ScrArea *UNUSED(area),
ARegion *region,
@@ -865,6 +871,7 @@ void ED_spacetype_sequencer(void)
art->regionid = RGN_TYPE_WINDOW;
art->init = sequencer_main_region_init;
art->draw = sequencer_main_region_draw;
+ art->draw_overlay = sequencer_main_region_draw_overlay;
art->listener = sequencer_main_region_listener;
art->message_subscribe = sequencer_main_region_message_subscribe;
art->keymapflag = ED_KEYMAP_TOOL | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES | ED_KEYMAP_ANIMATION;
diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c
index e50b25de412..c0343900f8b 100644
--- a/source/blender/editors/space_text/text_ops.c
+++ b/source/blender/editors/space_text/text_ops.c
@@ -85,7 +85,7 @@ static void test_line_start(char c, bool *r_last_state)
/**
* This function converts the indentation tabs from a buffer to spaces.
- * \param buf: A pointer to a cstring.
+ * \param in_buf: A pointer to a cstring.
* \param tab_size: The size, in spaces, of the tab character.
*/
static char *buf_tabs_to_spaces(const char *in_buf, const int tab_size)
@@ -370,7 +370,7 @@ static int text_open_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(e
{
Main *bmain = CTX_data_main(C);
Text *text = CTX_data_edit_text(C);
- const char *path = (text && text->name) ? text->name : BKE_main_blendfile_path(bmain);
+ const char *path = (text && text->filepath) ? text->filepath : BKE_main_blendfile_path(bmain);
if (RNA_struct_property_is_set(op->ptr, "filepath")) {
return text_open_exec(C, op);
@@ -428,6 +428,13 @@ static int text_reload_exec(bContext *C, wmOperator *op)
const int orig_curl = BLI_findindex(&text->lines, text->curl);
const int orig_curc = text->curc;
+ /* Don't make this part of 'poll', since 'Alt-R' will type 'R',
+ * if poll checks for the filename. */
+ if (text->filepath == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "This text has not been saved");
+ return OPERATOR_CANCELLED;
+ }
+
if (!BKE_text_reload(text)) {
BKE_report(op->reports, RPT_ERROR, "Could not reopen file");
return OPERATOR_CANCELLED;
@@ -536,10 +543,7 @@ static int text_make_internal_exec(bContext *C, wmOperator *UNUSED(op))
text->flags |= TXT_ISMEM | TXT_ISDIRTY;
- if (text->name) {
- MEM_freeN(text->name);
- text->name = NULL;
- }
+ MEM_SAFE_FREE(text->filepath);
text_update_cursor_moved(C);
WM_event_add_notifier(C, NC_TEXT | NA_EDITED, text);
@@ -576,7 +580,7 @@ static bool text_save_poll(bContext *C)
return 0;
}
- return (text->name != NULL && !(text->flags & TXT_ISMEM));
+ return (text->filepath != NULL && !(text->flags & TXT_ISMEM));
}
static void txt_write_file(Main *bmain, Text *text, ReportList *reports)
@@ -586,7 +590,7 @@ static void txt_write_file(Main *bmain, Text *text, ReportList *reports)
BLI_stat_t st;
char filepath[FILE_MAX];
- BLI_strncpy(filepath, text->name, FILE_MAX);
+ BLI_strncpy(filepath, text->filepath, FILE_MAX);
BLI_path_abs(filepath, BKE_main_blendfile_path(bmain));
fp = BLI_fopen(filepath, "w");
@@ -669,10 +673,10 @@ static int text_save_as_exec(bContext *C, wmOperator *op)
RNA_string_get(op->ptr, "filepath", str);
- if (text->name) {
- MEM_freeN(text->name);
+ if (text->filepath) {
+ MEM_freeN(text->filepath);
}
- text->name = BLI_strdup(str);
+ text->filepath = BLI_strdup(str);
text->flags &= ~TXT_ISMEM;
txt_write_file(bmain, text, op->reports);
@@ -693,8 +697,8 @@ static int text_save_as_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE
return text_save_as_exec(C, op);
}
- if (text->name) {
- str = text->name;
+ if (text->filepath) {
+ str = text->filepath;
}
else if (text->flags & TXT_ISMEM) {
str = text->id.name + 2;
@@ -3621,9 +3625,57 @@ void TEXT_OT_find(wmOperatorType *ot)
/** \name Replace Operator
* \{ */
+static int text_replace_all(bContext *C)
+{
+ SpaceText *st = CTX_wm_space_text(C);
+ Text *text = st->text;
+ const int flags = st->flags;
+ int found = 0;
+
+ if (!st->findstr[0]) {
+ return OPERATOR_CANCELLED;
+ }
+
+ const int orig_curl = BLI_findindex(&text->lines, text->curl);
+ const int orig_curc = text->curc;
+ bool has_sel = txt_has_sel(text);
+
+ txt_move_toline(text, 0, false);
+
+ found = txt_find_string(text, st->findstr, 0, flags & ST_MATCH_CASE);
+ if (found) {
+ ED_text_undo_push_init(C);
+
+ do {
+ txt_insert_buf(text, st->replacestr);
+ if (text->curl && text->curl->format) {
+ MEM_freeN(text->curl->format);
+ text->curl->format = NULL;
+ }
+ found = txt_find_string(text, st->findstr, 0, flags & ST_MATCH_CASE);
+ } while (found);
+
+ WM_event_add_notifier(C, NC_TEXT | NA_EDITED, text);
+ text_drawcache_tag_update(CTX_wm_space_text(C), 1);
+ }
+ else {
+ /* Restore position */
+ txt_move_to(text, orig_curl, orig_curc, has_sel);
+ return OPERATOR_CANCELLED;
+ }
+
+ return OPERATOR_FINISHED;
+}
+
static int text_replace_exec(bContext *C, wmOperator *op)
{
- return text_find_and_replace(C, op, TEXT_REPLACE);
+ bool replace_all = RNA_boolean_get(op->ptr, "all");
+ if (replace_all) {
+ return text_replace_all(C);
+ }
+ else {
+ return text_find_and_replace(C, op, TEXT_REPLACE);
+ }
}
void TEXT_OT_replace(wmOperatorType *ot)
@@ -3639,6 +3691,11 @@ void TEXT_OT_replace(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_UNDO;
+
+ /* properties */
+ PropertyRNA *prop;
+ prop = RNA_def_boolean(ot->srna, "all", false, "Replace all", "Replace all occurrences");
+ RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
}
/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_camera_control.c b/source/blender/editors/space_view3d/view3d_camera_control.c
index daa3f641404..aeabe68c2d0 100644
--- a/source/blender/editors/space_view3d/view3d_camera_control.c
+++ b/source/blender/editors/space_view3d/view3d_camera_control.c
@@ -182,7 +182,7 @@ struct View3DCameraControl *ED_view3d_cameracontrol_acquire(Depsgraph *depsgraph
copy_qt_qt(vctrl->rot_backup, rv3d->viewquat);
copy_v3_v3(vctrl->ofs_backup, rv3d->ofs);
- /* the dist defines a vector that is infront of the offset
+ /* The dist defines a vector that is in front of the offset
* to rotate the view about.
* this is no good for fly mode because we
* want to rotate about the viewers center.
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index fac378ae104..b3165c9fc78 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -2376,7 +2376,7 @@ void ED_view3d_datamask(const bContext *C,
{
if (ELEM(v3d->shading.type, OB_TEXTURE, OB_MATERIAL, OB_RENDER)) {
r_cddata_masks->lmask |= CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL;
- r_cddata_masks->vmask |= CD_MASK_ORCO;
+ r_cddata_masks->vmask |= CD_MASK_ORCO | CD_MASK_PROP_COLOR;
}
else if (v3d->shading.type == OB_SOLID) {
if (v3d->shading.color_type == V3D_SHADING_TEXTURE_COLOR) {
@@ -2384,6 +2384,7 @@ void ED_view3d_datamask(const bContext *C,
}
if (v3d->shading.color_type == V3D_SHADING_VERTEX_COLOR) {
r_cddata_masks->lmask |= CD_MASK_MLOOPCOL;
+ r_cddata_masks->vmask |= CD_MASK_ORCO | CD_MASK_PROP_COLOR;
}
}
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index edd75d8e561..3c3dea1509d 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -4988,7 +4988,7 @@ void ED_view3d_cursor3d_position(bContext *C,
ED_view3d_calc_zfac(rv3d, cursor_co, &flip);
- /* reset the depth based on the view offset (we _know_ the offset is infront of us) */
+ /* Reset the depth based on the view offset (we _know_ the offset is in front of us). */
if (flip) {
negate_v3_v3(cursor_co, rv3d->ofs);
/* re initialize, no need to check flip again */
diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c
index 06d1a033a0d..506969443fd 100644
--- a/source/blender/editors/space_view3d/view3d_fly.c
+++ b/source/blender/editors/space_view3d/view3d_fly.c
@@ -55,6 +55,10 @@
#include "view3d_intern.h" /* own include */
+/* -------------------------------------------------------------------- */
+/** \name Modal Key-map
+ * \{ */
+
/* NOTE: these defines are saved in keymap files,
* do not change values but just add new ones */
enum {
@@ -138,6 +142,12 @@ void fly_modal_keymap(wmKeyConfig *keyconf)
WM_modalkeymap_assign(keymap, "VIEW3D_OT_fly");
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Internal Fly Structs
+ * \{ */
+
typedef struct FlyInfo {
/* context stuff */
RegionView3D *rv3d;
@@ -205,6 +215,12 @@ typedef struct FlyInfo {
} FlyInfo;
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Internal Fly Drawing
+ * \{ */
+
/* prototypes */
#ifdef WITH_INPUT_NDOF
static void flyApply_ndof(bContext *C, FlyInfo *fly, bool is_confirm);
@@ -278,6 +294,12 @@ static void drawFlyPixel(const struct bContext *UNUSED(C), ARegion *UNUSED(regio
immUnbindProgram();
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Internal Fly Logic
+ * \{ */
+
/* FlyInfo->state */
enum {
FLY_RUNNING = 0,
@@ -1034,6 +1056,12 @@ static void flyApply_ndof(bContext *C, FlyInfo *fly, bool is_confirm)
}
#endif /* WITH_INPUT_NDOF */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Fly Operator
+ * \{ */
+
static int fly_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
RegionView3D *rv3d = CTX_wm_region_view3d(C);
@@ -1128,3 +1156,5 @@ void VIEW3D_OT_fly(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_BLOCKING;
}
+
+/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c
index 829d793333e..f2e42cd1725 100644
--- a/source/blender/editors/space_view3d/view3d_header.c
+++ b/source/blender/editors/space_view3d/view3d_header.c
@@ -209,7 +209,7 @@ static void uiTemplatePaintModeSelection(uiLayout *layout, struct bContext *C)
PointerRNA meshptr;
RNA_pointer_create(ob->data, &RNA_Mesh, ob->data, &meshptr);
- if (ob->mode & (OB_MODE_TEXTURE_PAINT)) {
+ if (ob->mode & OB_MODE_TEXTURE_PAINT) {
uiItemR(layout, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
}
else {
diff --git a/source/blender/editors/space_view3d/view3d_placement.c b/source/blender/editors/space_view3d/view3d_placement.c
index f2b78bc2aaf..131fbbc02ee 100644
--- a/source/blender/editors/space_view3d/view3d_placement.c
+++ b/source/blender/editors/space_view3d/view3d_placement.c
@@ -936,6 +936,8 @@ static int view3d_interactive_add_modal(bContext *C, wmOperator *op, const wmEve
RNA_float_set_array(&op_props, "rotation", rotation);
RNA_float_set_array(&op_props, "location", location);
RNA_float_set_array(&op_props, "scale", scale);
+ /* Always use default size here. */
+ RNA_float_set(&op_props, "size", 2.0f);
WM_operator_name_call_ptr(C, ot, WM_OP_EXEC_DEFAULT, &op_props);
WM_operator_properties_free(&op_props);
}
diff --git a/source/blender/editors/space_view3d/view3d_project.c b/source/blender/editors/space_view3d/view3d_project.c
index 3a0f0f468fc..f4ec9a22520 100644
--- a/source/blender/editors/space_view3d/view3d_project.c
+++ b/source/blender/editors/space_view3d/view3d_project.c
@@ -557,9 +557,9 @@ void ED_view3d_win_to_3d(const View3D *v3d,
copy_v3_v3(ray_origin, rv3d->viewinv[3]);
ED_view3d_win_to_vector(region, mval, ray_direction);
- /* note, we could use isect_line_plane_v3()
- * however we want the intersection to be infront of the view no matter what,
- * so apply the unsigned factor instead */
+ /* Note: we could use #isect_line_plane_v3()
+ * however we want the intersection to be in front of the view no matter what,
+ * so apply the unsigned factor instead. */
plane_from_point_normal_v3(plane, depth_pt, rv3d->viewinv[2]);
isect_ray_plane_v3(ray_origin, ray_direction, plane, &lambda, false);
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 1bdb8268c23..9e235d72f26 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -3007,7 +3007,7 @@ static bool do_meta_box_select(ViewContext *vc, const rcti *rect, const eSelectO
continue;
}
- if (metaelem_id != (hitresult & 0xFFFF0000 & ~(MBALLSEL_ANY))) {
+ if (metaelem_id != (hitresult & 0xFFFF0000 & ~MBALLSEL_ANY)) {
continue;
}
diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c
index 437c0dd4035..91b2971585d 100644
--- a/source/blender/editors/space_view3d/view3d_snap.c
+++ b/source/blender/editors/space_view3d/view3d_snap.c
@@ -850,12 +850,12 @@ static bool snap_curs_to_sel_ex(bContext *C, float cursor[3])
return false;
}
- if (scene->toolsettings->transform_pivot_point == V3D_AROUND_CENTER_MEDIAN) {
- mul_v3_fl(centroid, 1.0f / (float)count);
- copy_v3_v3(cursor, centroid);
+ if (scene->toolsettings->transform_pivot_point == V3D_AROUND_CENTER_BOUNDS) {
+ mid_v3_v3v3(cursor, min, max);
}
else {
- mid_v3_v3v3(cursor, min, max);
+ mul_v3_fl(centroid, 1.0f / (float)count);
+ copy_v3_v3(cursor, centroid);
}
return true;
}
diff --git a/source/blender/editors/space_view3d/view3d_utils.c b/source/blender/editors/space_view3d/view3d_utils.c
index 377e8c58ba3..15d6a43d105 100644
--- a/source/blender/editors/space_view3d/view3d_utils.c
+++ b/source/blender/editors/space_view3d/view3d_utils.c
@@ -94,7 +94,7 @@ bool ED_view3d_has_workbench_in_texture_color(const Scene *scene,
if (v3d->shading.color_type == V3D_SHADING_TEXTURE_COLOR) {
return true;
}
- if (ob->mode == OB_MODE_TEXTURE_PAINT) {
+ if (ob && ob->mode == OB_MODE_TEXTURE_PAINT) {
return true;
}
}
diff --git a/source/blender/editors/space_view3d/view3d_walk.c b/source/blender/editors/space_view3d/view3d_walk.c
index 7aefd173953..50fa573423a 100644
--- a/source/blender/editors/space_view3d/view3d_walk.c
+++ b/source/blender/editors/space_view3d/view3d_walk.c
@@ -65,6 +65,10 @@
/* ensure the target position is one we can reach, see: T45771 */
#define USE_PIXELSIZE_NATIVE_SUPPORT
+/* -------------------------------------------------------------------- */
+/** \name Modal Key-map
+ * \{ */
+
/* NOTE: these defines are saved in keymap files,
* do not change values but just add new ones */
enum {
@@ -173,6 +177,12 @@ void walk_modal_keymap(wmKeyConfig *keyconf)
WM_modalkeymap_assign(keymap, "VIEW3D_OT_walk");
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Internal Walk Structs
+ * \{ */
+
typedef struct WalkTeleport {
eWalkTeleportState state;
float duration; /* from user preferences */
@@ -283,6 +293,12 @@ typedef struct WalkInfo {
} WalkInfo;
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Internal Walk Drawing
+ * \{ */
+
/* prototypes */
#ifdef WITH_INPUT_NDOF
static void walkApply_ndof(bContext *C, WalkInfo *walk, bool is_confirm);
@@ -340,6 +356,12 @@ static void drawWalkPixel(const struct bContext *UNUSED(C), ARegion *region, voi
immUnbindProgram();
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Internal Walk Logic
+ * \{ */
+
static void walk_navigation_mode_set(WalkInfo *walk, eWalkMethod mode)
{
if (mode == WALK_MODE_FREE) {
@@ -1343,7 +1365,12 @@ static void walkApply_ndof(bContext *C, WalkInfo *walk, bool is_confirm)
}
#endif /* WITH_INPUT_NDOF */
-/****** walk operator ******/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Walk Operator
+ * \{ */
+
static int walk_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
RegionView3D *rv3d = CTX_wm_region_view3d(C);
@@ -1438,3 +1465,5 @@ void VIEW3D_OT_walk(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_BLOCKING;
}
+
+/** \} */
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index b02b1814c67..eb60273fc79 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -526,8 +526,11 @@ static void viewRedrawPost(bContext *C, TransInfo *t)
}
/* redraw UV editor */
- if (ELEM(t->mode, TFM_VERT_SLIDE, TFM_EDGE_SLIDE) &&
- (t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT)) {
+ const char uvcalc_correct_flag = ELEM(t->mode, TFM_VERT_SLIDE, TFM_EDGE_SLIDE) ?
+ UVCALC_TRANSFORM_CORRECT_SLIDE :
+ UVCALC_TRANSFORM_CORRECT;
+
+ if ((t->data_type == TC_MESH_VERTS) && (t->settings->uvcalc_flag & uvcalc_correct_flag)) {
WM_event_add_notifier(C, NC_GEOM | ND_DATA, NULL);
}
@@ -1591,17 +1594,24 @@ static void drawTransformPixel(const struct bContext *C, ARegion *region, void *
void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
{
ToolSettings *ts = CTX_data_tool_settings(C);
- int proportional = 0;
PropertyRNA *prop;
if (!(t->con.mode & CON_APPLY) && (t->flag & T_MODAL) &&
ELEM(t->mode, TFM_TRANSLATION, TFM_RESIZE)) {
/* When redoing these modes the first time, it's more convenient to save
- * the Global orientation. */
- mul_m3_v3(t->spacemtx, t->values_final);
- unit_m3(t->spacemtx);
+ * in the Global orientation. */
+ if (t->mode == TFM_TRANSLATION) {
+ mul_m3_v3(t->spacemtx, t->values_final);
+ }
+ else {
+ float tmat[3][3], sizemat[3][3];
+ size_to_mat3(sizemat, t->values_final);
+ mul_m3_m3m3(tmat, t->spacemtx, sizemat);
+ mat3_to_size(t->values_final, tmat);
+ }
BLI_assert(t->orient_curr == 0);
+ unit_m3(t->spacemtx);
t->orient[0].type = V3D_ORIENT_GLOBAL;
}
@@ -1619,15 +1629,17 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
}
}
+ bool use_prop_edit = false;
+ int prop_edit_flag = 0;
if (t->flag & T_PROP_EDIT_ALL) {
if (t->flag & T_PROP_EDIT) {
- proportional |= PROP_EDIT_USE;
+ use_prop_edit = true;
}
if (t->flag & T_PROP_CONNECTED) {
- proportional |= PROP_EDIT_CONNECTED;
+ prop_edit_flag |= PROP_EDIT_CONNECTED;
}
if (t->flag & T_PROP_PROJECTED) {
- proportional |= PROP_EDIT_PROJECTED;
+ prop_edit_flag |= PROP_EDIT_PROJECTED;
}
}
@@ -1639,20 +1651,27 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
if (!(t->options & CTX_NO_PET)) {
if ((prop = RNA_struct_find_property(op->ptr, "use_proportional_edit")) &&
!RNA_property_is_set(op->ptr, prop)) {
+ const Object *obact = OBACT(t->view_layer);
+
if (t->spacetype == SPACE_GRAPH) {
- ts->proportional_fcurve = proportional;
+ ts->proportional_fcurve = use_prop_edit;
}
else if (t->spacetype == SPACE_ACTION) {
- ts->proportional_action = proportional;
- }
- else if (t->obedit_type != -1) {
- ts->proportional_edit = proportional;
+ ts->proportional_action = use_prop_edit;
}
else if (t->options & CTX_MASK) {
- ts->proportional_mask = proportional != 0;
+ ts->proportional_mask = use_prop_edit;
}
- else if ((t->options & CTX_CURSOR) == 0) {
- ts->proportional_objects = proportional != 0;
+ else if (obact && obact->mode == OB_MODE_OBJECT) {
+ ts->proportional_objects = use_prop_edit;
+ }
+ else {
+ if (use_prop_edit) {
+ ts->proportional_edit |= PROP_EDIT_USE;
+ }
+ else {
+ ts->proportional_edit &= ~PROP_EDIT_USE;
+ }
}
}
@@ -1685,9 +1704,9 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
}
if ((prop = RNA_struct_find_property(op->ptr, "use_proportional_edit"))) {
- RNA_property_boolean_set(op->ptr, prop, proportional & PROP_EDIT_USE);
- RNA_boolean_set(op->ptr, "use_proportional_connected", proportional & PROP_EDIT_CONNECTED);
- RNA_boolean_set(op->ptr, "use_proportional_projected", proportional & PROP_EDIT_PROJECTED);
+ RNA_property_boolean_set(op->ptr, prop, use_prop_edit);
+ RNA_boolean_set(op->ptr, "use_proportional_connected", prop_edit_flag & PROP_EDIT_CONNECTED);
+ RNA_boolean_set(op->ptr, "use_proportional_projected", prop_edit_flag & PROP_EDIT_PROJECTED);
RNA_enum_set(op->ptr, "proportional_edit_falloff", t->prop_mode);
RNA_float_set(op->ptr, "proportional_size", t->prop_size);
}
@@ -1768,7 +1787,7 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
if ((prop = RNA_struct_find_property(op->ptr, "correct_uv"))) {
RNA_property_boolean_set(
- op->ptr, prop, (t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) != 0);
+ op->ptr, prop, (t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT_SLIDE) != 0);
}
}
@@ -1819,6 +1838,8 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
int options = 0;
PropertyRNA *prop;
+ mode = transform_mode_really_used(C, mode);
+
t->context = C;
/* added initialize, for external calls to set stuff in TransInfo, like undo string */
diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c
index 838c1880881..66b90eb159f 100644
--- a/source/blender/editors/transform/transform_constraints.c
+++ b/source/blender/editors/transform/transform_constraints.c
@@ -79,6 +79,27 @@ static void projection_matrix_calc(const TransInfo *t, float r_pmtx[3][3])
}
/* ************************** CONSTRAINTS ************************* */
+#define CONSTRAIN_EPSILON 0.0001f
+
+static void constraint_plane_calc(TransInfo *t, float r_plane[4])
+{
+ const float *constraint_vector[2];
+ int n = 0;
+ for (int i = 0; i < 3; i++) {
+ if (t->con.mode & (CON_AXIS0 << i)) {
+ constraint_vector[n++] = t->spacemtx[i];
+ if (n == 2) {
+ break;
+ }
+ }
+ }
+ BLI_assert(n == 2);
+
+ cross_v3_v3v3(r_plane, constraint_vector[0], constraint_vector[1]);
+ normalize_v3(r_plane);
+ r_plane[3] = -dot_v3v3(r_plane, t->center_global);
+}
+
static void constraintValuesFinal(TransInfo *t, float vec[3])
{
int mode = t->con.mode;
@@ -297,32 +318,83 @@ static void axisProjection(const TransInfo *t,
}
/**
- * Return true if the 2x axis are both aligned when projected into the view.
- * In this case, we can't usefully project the cursor onto the plane.
+ * Snap to the intersection between the edge direction and the constraint plane.
*/
-static bool isPlaneProjectionViewAligned(const TransInfo *t)
+static void constraint_snap_plane_to_edge(const TransInfo *t, const float plane[4], float r_out[3])
{
- const float eps = 0.001f;
- const float *constraint_vector[2];
- int n = 0;
- for (int i = 0; i < 3; i++) {
- if (t->con.mode & (CON_AXIS0 << i)) {
- constraint_vector[n++] = t->spacemtx[i];
- if (n == 2) {
- break;
- }
- }
+ float lambda;
+ const float *edge_snap_point = t->tsnap.snapPoint;
+ const float *edge_dir = t->tsnap.snapNormal;
+ bool is_aligned = fabsf(dot_v3v3(edge_dir, plane)) < CONSTRAIN_EPSILON;
+ if (!is_aligned && isect_ray_plane_v3(edge_snap_point, edge_dir, plane, &lambda, false)) {
+ madd_v3_v3v3fl(r_out, edge_snap_point, edge_dir, lambda);
+ sub_v3_v3(r_out, t->tsnap.snapTarget);
}
- BLI_assert(n == 2);
+}
+
+/**
+ * Snap to the nearest point between the snap point and the line that
+ * intersects the face plane with the constraint plane.
+ */
+static void constraint_snap_plane_to_face(const TransInfo *t, const float plane[4], float r_out[3])
+{
+ float face_plane[4], isect_orig[3], isect_dir[3];
+ const float *face_snap_point = t->tsnap.snapPoint;
+ const float *face_normal = t->tsnap.snapNormal;
+ plane_from_point_normal_v3(face_plane, face_snap_point, face_normal);
+ bool is_aligned = fabsf(dot_v3v3(plane, face_plane)) > (1.0f - CONSTRAIN_EPSILON);
+ if (!is_aligned && isect_plane_plane_v3(plane, face_plane, isect_orig, isect_dir)) {
+ closest_to_ray_v3(r_out, face_snap_point, isect_orig, isect_dir);
+ sub_v3_v3(r_out, t->tsnap.snapTarget);
+ }
+}
- float view_to_plane[3], plane_normal[3];
+/**
+ * Snap to the nearest point on the axis to the edge/line element.
+ */
+void transform_constraint_snap_axis_to_edge(const TransInfo *t,
+ const float axis[3],
+ float r_out[3])
+{
+ float lambda;
+ const float *edge_snap_point = t->tsnap.snapPoint;
+ const float *edge_dir = t->tsnap.snapNormal;
+ bool is_aligned = fabsf(dot_v3v3(axis, edge_dir)) > (1.0f - CONSTRAIN_EPSILON);
+ if (!is_aligned &&
+ isect_ray_ray_v3(t->tsnap.snapTarget, axis, edge_snap_point, edge_dir, &lambda, NULL)) {
+ mul_v3_v3fl(r_out, axis, lambda);
+ }
+}
- getViewVector(t, t->center_global, view_to_plane);
+/**
+ * Snap to the intersection of the axis and the plane defined by the face.
+ */
+void transform_constraint_snap_axis_to_face(const TransInfo *t,
+ const float axis[3],
+ float r_out[3])
+{
+ float lambda;
+ float face_plane[4];
+ const float *face_snap_point = t->tsnap.snapPoint;
+ const float *face_normal = t->tsnap.snapNormal;
+ plane_from_point_normal_v3(face_plane, face_snap_point, face_normal);
+ bool is_aligned = fabsf(dot_v3v3(axis, face_plane)) < CONSTRAIN_EPSILON;
+ if (!is_aligned && isect_ray_plane_v3(t->tsnap.snapTarget, axis, face_plane, &lambda, false)) {
+ mul_v3_v3fl(r_out, axis, lambda);
+ }
+}
- cross_v3_v3v3(plane_normal, constraint_vector[0], constraint_vector[1]);
- normalize_v3(plane_normal);
+/**
+ * Return true if the 2x axis are both aligned when projected into the view.
+ * In this case, we can't usefully project the cursor onto the plane.
+ */
+static bool isPlaneProjectionViewAligned(const TransInfo *t, float plane[4])
+{
+ const float eps = 0.001f;
+ float view_to_plane[3];
+ getViewVector(t, t->center_global, view_to_plane);
- float factor = dot_v3v3(plane_normal, view_to_plane);
+ float factor = dot_v3v3(plane, view_to_plane);
return fabsf(factor) < eps;
}
@@ -361,14 +433,31 @@ static void applyAxisConstraintVec(
copy_v3_v3(out, in);
if (!td && t->con.mode & CON_APPLY) {
mul_m3_v3(t->con.pmtx, out);
+ bool is_snap_to_edge = false, is_snap_to_face = false;
+ if (activeSnap(t)) {
+ is_snap_to_edge = (t->tsnap.snapElem & SCE_SNAP_MODE_EDGE) != 0;
+ is_snap_to_face = (t->tsnap.snapElem & SCE_SNAP_MODE_FACE) != 0;
+ }
- // With snap, a projection is alright, no need to correct for view alignment
- if (!validSnap(t)) {
+ /* With snap points, a projection is alright, no adjustments needed. */
+ if (!validSnap(t) || is_snap_to_edge || is_snap_to_face) {
const int dims = getConstraintSpaceDimension(t);
if (dims == 2) {
if (!is_zero_v3(out)) {
- if (!isPlaneProjectionViewAligned(t)) {
- planeProjection(t, in, out);
+ float plane[4];
+ constraint_plane_calc(t, plane);
+
+ if (is_snap_to_edge) {
+ constraint_snap_plane_to_edge(t, plane, out);
+ }
+ else if (is_snap_to_face) {
+ constraint_snap_plane_to_face(t, plane, out);
+ }
+ else {
+ /* View alignment correction. */
+ if (!isPlaneProjectionViewAligned(t, plane)) {
+ planeProjection(t, in, out);
+ }
}
}
}
@@ -384,7 +473,17 @@ static void applyAxisConstraintVec(
else if (t->con.mode & CON_AXIS2) {
copy_v3_v3(c, t->spacemtx[2]);
}
- axisProjection(t, c, in, out);
+
+ if (is_snap_to_edge) {
+ transform_constraint_snap_axis_to_edge(t, c, out);
+ }
+ else if (is_snap_to_face) {
+ transform_constraint_snap_axis_to_face(t, c, out);
+ }
+ else {
+ /* View alignment correction. */
+ axisProjection(t, c, in, out);
+ }
}
}
postConstraintChecks(t, out);
@@ -779,12 +878,21 @@ void drawPropCircle(const struct bContext *C, TransInfo *t)
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
- immUniformThemeColor(TH_GRID);
+ immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
+
+ float viewport[4];
+ GPU_viewport_size_get_f(viewport);
+ GPU_blend(true);
+
+ immUniform2fv("viewportSize", &viewport[2]);
+ immUniform1f("lineWidth", 3.0f * U.pixelsize);
+
+ immUniformThemeColorShadeAlpha(TH_GRID, -20, 255);
+ imm_drawcircball(t->center_global, t->prop_size, imat, pos);
- GPU_logic_op_invert_set(true);
+ immUniform1f("lineWidth", 1.0f * U.pixelsize);
+ immUniformThemeColorShadeAlpha(TH_GRID, 20, 255);
imm_drawcircball(t->center_global, t->prop_size, imat, pos);
- GPU_logic_op_invert_set(false);
immUnbindProgram();
diff --git a/source/blender/editors/transform/transform_constraints.h b/source/blender/editors/transform/transform_constraints.h
index c41b9361ca4..282060af2c3 100644
--- a/source/blender/editors/transform/transform_constraints.h
+++ b/source/blender/editors/transform/transform_constraints.h
@@ -27,6 +27,12 @@
struct TransInfo;
void constraintNumInput(TransInfo *t, float vec[3]);
+void transform_constraint_snap_axis_to_edge(const TransInfo *t,
+ const float axis[3],
+ float r_out[3]);
+void transform_constraint_snap_axis_to_face(const TransInfo *t,
+ const float axis[3],
+ float r_out[3]);
void setConstraint(TransInfo *t, int mode, const char text[]);
void setAxisMatrixConstraint(TransInfo *t, int mode, const char text[]);
void setLocalConstraint(TransInfo *t, int mode, const char text[]);
diff --git a/source/blender/editors/transform/transform_convert.c b/source/blender/editors/transform/transform_convert.c
index 064057990e0..5d1fd1543df 100644
--- a/source/blender/editors/transform/transform_convert.c
+++ b/source/blender/editors/transform/transform_convert.c
@@ -774,7 +774,7 @@ bool constraints_list_needinv(TransInfo *t, ListBase *list)
bConstraint *con;
/* loop through constraints, checking if there's one of the mentioned
- * constraints needing special crazyspace corrections
+ * constraints needing special crazy-space corrections
*/
if (list) {
for (con = list->first; con; con = con->next) {
@@ -1148,21 +1148,6 @@ void createTransData(bContext *C, TransInfo *t)
}
t->flag |= T_OBJECT;
-
- /* Check if we're transforming the camera from the camera */
- if ((t->spacetype == SPACE_VIEW3D) && (t->region->regiontype == RGN_TYPE_WINDOW)) {
- View3D *v3d = t->view;
- RegionView3D *rv3d = t->region->regiondata;
- if ((rv3d->persp == RV3D_CAMOB) && v3d->camera) {
- /* we could have a flag to easily check an object is being transformed */
- if (v3d->camera->id.tag & LIB_TAG_DOIT) {
- t->flag |= T_CAMERA;
- }
- }
- else if (v3d->ob_center && v3d->ob_center->id.tag & LIB_TAG_DOIT) {
- t->flag |= T_CAMERA;
- }
- }
convert_type = TC_OBJECT;
}
@@ -1175,6 +1160,7 @@ void createTransData(bContext *C, TransInfo *t)
break;
case TC_POSE:
createTransPose(t);
+ /* Disable PET, its not usable in pose mode yet [#32444] */
init_prop_edit = false;
break;
case TC_ARMATURE_VERTS:
@@ -1224,6 +1210,20 @@ void createTransData(bContext *C, TransInfo *t)
break;
case TC_OBJECT:
createTransObject(C, t);
+ /* Check if we're transforming the camera from the camera */
+ if ((t->spacetype == SPACE_VIEW3D) && (t->region->regiontype == RGN_TYPE_WINDOW)) {
+ View3D *v3d = t->view;
+ RegionView3D *rv3d = t->region->regiondata;
+ if ((rv3d->persp == RV3D_CAMOB) && v3d->camera) {
+ /* we could have a flag to easily check an object is being transformed */
+ if (v3d->camera->id.tag & LIB_TAG_DOIT) {
+ t->flag |= T_CAMERA;
+ }
+ }
+ else if (v3d->ob_center && v3d->ob_center->id.tag & LIB_TAG_DOIT) {
+ t->flag |= T_CAMERA;
+ }
+ }
break;
case TC_OBJECT_TEXSPACE:
createTransTexspace(t);
@@ -1292,18 +1292,9 @@ void createTransData(bContext *C, TransInfo *t)
* and are still added into transform data. */
sort_trans_data_selected_first(t);
}
- }
-
- /* exception... hackish, we want bonesize to use bone orientation matrix (ton) */
- if (t->mode == TFM_BONESIZE) {
- t->flag &= ~(T_EDIT | T_POINTS);
- t->flag |= T_POSE;
- t->obedit_type = -1;
- t->data_type = TC_NONE;
- FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- tc->poseobj = tc->obedit;
- tc->obedit = NULL;
+ if (!init_prop_edit) {
+ t->flag &= ~T_PROP_EDIT_ALL;
}
}
diff --git a/source/blender/editors/transform/transform_convert.h b/source/blender/editors/transform/transform_convert.h
index a94bd609d94..f7eea286983 100644
--- a/source/blender/editors/transform/transform_convert.h
+++ b/source/blender/editors/transform/transform_convert.h
@@ -47,7 +47,7 @@ bool clipUVTransform(TransInfo *t, float vec[2], const bool resize);
void clipUVData(TransInfo *t);
/* transform_convert_mesh.c */
-void trans_mesh_customdata_correction_init(TransInfo *t, struct TransDataContainer *tc);
+void trans_mesh_customdata_correction_init(TransInfo *t);
/* transform_convert_sequencer.c */
int transform_convert_sequencer_get_snap_bound(TransInfo *t);
diff --git a/source/blender/editors/transform/transform_convert_armature.c b/source/blender/editors/transform/transform_convert_armature.c
index 75b51b3d2c4..f721ed0b866 100644
--- a/source/blender/editors/transform/transform_convert_armature.c
+++ b/source/blender/editors/transform/transform_convert_armature.c
@@ -553,8 +553,7 @@ static void pose_mirror_info_init(PoseInitData_Mirror *pid,
/** \name Convert Armature
* \{ */
-static void add_pose_transdata(
- TransInfo *t, bPoseChannel *pchan, Object *ob, TransDataContainer *tc, TransData *td)
+static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, TransData *td)
{
Bone *bone = pchan->bone;
float pmat[3][3], omat[3][3];
@@ -667,20 +666,16 @@ static void add_pose_transdata(
mul_m3_m3m3(td->axismtx, omat, pmat);
normalize_m3(td->axismtx);
- if (ELEM(t->mode, TFM_BONESIZE, TFM_BONE_ENVELOPE_DIST)) {
- bArmature *arm = tc->poseobj->data;
-
- if ((t->mode == TFM_BONE_ENVELOPE_DIST) || (arm->drawtype == ARM_ENVELOPE)) {
- td->loc = NULL;
- td->val = &bone->dist;
- td->ival = bone->dist;
- }
- else {
- // abusive storage of scale in the loc pointer :)
- td->loc = &bone->xwidth;
- copy_v3_v3(td->iloc, td->loc);
- td->val = NULL;
- }
+ if (t->mode == TFM_BONE_ENVELOPE_DIST) {
+ td->loc = NULL;
+ td->val = &bone->dist;
+ td->ival = bone->dist;
+ }
+ else if (t->mode == TFM_BONESIZE) {
+ // abusive storage of scale in the loc pointer :)
+ td->loc = &bone->xwidth;
+ copy_v3_v3(td->iloc, td->loc);
+ td->val = NULL;
}
/* in this case we can do target-less IK grabbing */
@@ -836,7 +831,7 @@ void createTransPose(TransInfo *t)
td = tc->data;
LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) {
if (pchan->bone->flag & BONE_TRANSFORM) {
- add_pose_transdata(t, pchan, ob, tc, td);
+ add_pose_transdata(t, pchan, ob, td);
td++;
}
}
@@ -862,8 +857,6 @@ void createTransPose(TransInfo *t)
}
t->flag |= T_POSE;
- /* disable PET, its not usable in pose mode yet [#32444] */
- t->flag &= ~T_PROP_EDIT_ALL;
}
void createTransArmatureVerts(TransInfo *t)
@@ -988,7 +981,7 @@ void createTransArmatureVerts(TransInfo *t)
}
else if (ELEM(t->mode, TFM_BONESIZE, TFM_BONE_ENVELOPE_DIST)) {
if (ebo->flag & BONE_SELECTED) {
- if ((t->mode == TFM_BONE_ENVELOPE_DIST) || (arm->drawtype == ARM_ENVELOPE)) {
+ if (t->mode == TFM_BONE_ENVELOPE_DIST) {
td->loc = NULL;
td->val = &ebo->dist;
td->ival = ebo->dist;
diff --git a/source/blender/editors/transform/transform_convert_curve.c b/source/blender/editors/transform/transform_convert_curve.c
index 6c03f86f883..37e37072ed7 100644
--- a/source/blender/editors/transform/transform_convert_curve.c
+++ b/source/blender/editors/transform/transform_convert_curve.c
@@ -87,7 +87,7 @@ void createTransCurveVerts(TransInfo *t)
t->data_len_all = 0;
- /* Count control points (one per bez-triple) if any number of handles are selected.
+ /* Count control points (one per #BezTriple) if any number of handles are selected.
* Needed for #transform_around_single_fallback_ex. */
int data_len_all_pt = 0;
diff --git a/source/blender/editors/transform/transform_convert_mask.c b/source/blender/editors/transform/transform_convert_mask.c
index 66c27bca207..6f34c49bdac 100644
--- a/source/blender/editors/transform/transform_convert_mask.c
+++ b/source/blender/editors/transform/transform_convert_mask.c
@@ -149,7 +149,7 @@ static void MaskPointToTransData(Scene *scene,
/* CV coords are scaled by aspects. this is needed for rotations and
* proportional editing to be consistent with the stretched CV coords
- * that are displayed. this also means that for display and numinput,
+ * that are displayed. this also means that for display and number-input,
* and when the CV coords are flushed, these are converted each time */
mul_v2_m3v2(td2d->loc, parent_matrix, bezt->vec[i]);
td2d->loc[0] *= asp[0];
diff --git a/source/blender/editors/transform/transform_convert_mesh.c b/source/blender/editors/transform/transform_convert_mesh.c
index 27ddad262f7..1c286415ea6 100644
--- a/source/blender/editors/transform/transform_convert_mesh.c
+++ b/source/blender/editors/transform/transform_convert_mesh.c
@@ -50,10 +50,11 @@
/* Own include. */
#include "transform_convert.h"
-/* Used for both mirror epsilon and TD_MIRROR_EDGE_ */
-#define TRANSFORM_MAXDIST_MIRROR 0.00002f
+/* -------------------------------------------------------------------- */
+/** \name Island Creation
+ *
+ * \{ */
-/* when transforming islands */
struct TransIslandData {
float (*center)[3];
float (*axismtx)[3][3];
@@ -61,8 +62,186 @@ struct TransIslandData {
int *island_vert_map;
};
+static void editmesh_islands_info_calc(BMEditMesh *em,
+ const bool calc_single_islands,
+ const bool calc_island_center,
+ const bool calc_island_axismtx,
+ struct TransIslandData *r_island_data)
+{
+ BMesh *bm = em->bm;
+ char htype;
+ char itype;
+ int i;
+
+ /* group vars */
+ float(*center)[3] = NULL;
+ float(*axismtx)[3][3] = NULL;
+ int *groups_array;
+ int(*group_index)[2];
+ int group_tot;
+ void **ele_array;
+
+ int *vert_map;
+
+ if (em->selectmode & (SCE_SELECT_VERTEX | SCE_SELECT_EDGE)) {
+ groups_array = MEM_mallocN(sizeof(*groups_array) * bm->totedgesel, __func__);
+ group_tot = BM_mesh_calc_edge_groups(
+ bm, groups_array, &group_index, NULL, NULL, BM_ELEM_SELECT);
+
+ htype = BM_EDGE;
+ itype = BM_VERTS_OF_EDGE;
+ }
+ else { /* (bm->selectmode & SCE_SELECT_FACE) */
+ groups_array = MEM_mallocN(sizeof(*groups_array) * bm->totfacesel, __func__);
+ group_tot = BM_mesh_calc_face_groups(
+ bm, groups_array, &group_index, NULL, NULL, BM_ELEM_SELECT, BM_VERT);
+
+ htype = BM_FACE;
+ itype = BM_VERTS_OF_FACE;
+ }
+
+ if (calc_island_center) {
+ center = MEM_mallocN(sizeof(*center) * group_tot, __func__);
+ }
+
+ if (calc_island_axismtx) {
+ axismtx = MEM_mallocN(sizeof(*axismtx) * group_tot, __func__);
+ }
+
+ vert_map = MEM_mallocN(sizeof(*vert_map) * bm->totvert, __func__);
+ /* we shouldn't need this, but with incorrect selection flushing
+ * its possible we have a selected vertex that's not in a face,
+ * for now best not crash in that case. */
+ copy_vn_i(vert_map, bm->totvert, -1);
+
+ BM_mesh_elem_table_ensure(bm, htype);
+ ele_array = (htype == BM_FACE) ? (void **)bm->ftable : (void **)bm->etable;
+
+ BM_mesh_elem_index_ensure(bm, BM_VERT);
+
+ /* may be an edge OR a face array */
+ for (i = 0; i < group_tot; i++) {
+ BMEditSelection ese = {NULL};
+
+ const int fg_sta = group_index[i][0];
+ const int fg_len = group_index[i][1];
+ float co[3], no[3], tangent[3];
+ int j;
+
+ zero_v3(co);
+ zero_v3(no);
+ zero_v3(tangent);
+
+ ese.htype = htype;
+
+ /* loop on each face or edge in this group:
+ * - assign r_vert_map
+ * - calculate (co, no)
+ */
+ for (j = 0; j < fg_len; j++) {
+ ese.ele = ele_array[groups_array[fg_sta + j]];
+
+ if (center) {
+ float tmp_co[3];
+ BM_editselection_center(&ese, tmp_co);
+ add_v3_v3(co, tmp_co);
+ }
+
+ if (axismtx) {
+ float tmp_no[3], tmp_tangent[3];
+ BM_editselection_normal(&ese, tmp_no);
+ BM_editselection_plane(&ese, tmp_tangent);
+ add_v3_v3(no, tmp_no);
+ add_v3_v3(tangent, tmp_tangent);
+ }
+
+ {
+ /* setup vertex map */
+ BMIter iter;
+ BMVert *v;
+
+ /* connected edge-verts */
+ BM_ITER_ELEM (v, &iter, ese.ele, itype) {
+ vert_map[BM_elem_index_get(v)] = i;
+ }
+ }
+ }
+
+ if (center) {
+ mul_v3_v3fl(center[i], co, 1.0f / (float)fg_len);
+ }
+
+ if (axismtx) {
+ if (createSpaceNormalTangent(axismtx[i], no, tangent)) {
+ /* pass */
+ }
+ else {
+ if (normalize_v3(no) != 0.0f) {
+ axis_dominant_v3_to_m3(axismtx[i], no);
+ invert_m3(axismtx[i]);
+ }
+ else {
+ unit_m3(axismtx[i]);
+ }
+ }
+ }
+ }
+
+ MEM_freeN(groups_array);
+ MEM_freeN(group_index);
+
+ /* for PET we need islands of 1 so connected vertices can use it with V3D_AROUND_LOCAL_ORIGINS */
+ if (calc_single_islands) {
+ BMIter viter;
+ BMVert *v;
+ int group_tot_single = 0;
+
+ BM_ITER_MESH_INDEX (v, &viter, bm, BM_VERTS_OF_MESH, i) {
+ if (BM_elem_flag_test(v, BM_ELEM_SELECT) && (vert_map[i] == -1)) {
+ group_tot_single += 1;
+ }
+ }
+
+ if (group_tot_single != 0) {
+ if (center) {
+ center = MEM_reallocN(center, sizeof(*center) * (group_tot + group_tot_single));
+ }
+ if (axismtx) {
+ axismtx = MEM_reallocN(axismtx, sizeof(*axismtx) * (group_tot + group_tot_single));
+ }
+
+ BM_ITER_MESH_INDEX (v, &viter, bm, BM_VERTS_OF_MESH, i) {
+ if (BM_elem_flag_test(v, BM_ELEM_SELECT) && (vert_map[i] == -1)) {
+ vert_map[i] = group_tot;
+ if (center) {
+ copy_v3_v3(center[group_tot], v->co);
+ }
+ if (axismtx) {
+ if (is_zero_v3(v->no) != 0.0f) {
+ axis_dominant_v3_to_m3(axismtx[group_tot], v->no);
+ invert_m3(axismtx[group_tot]);
+ }
+ else {
+ unit_m3(axismtx[group_tot]);
+ }
+ }
+
+ group_tot += 1;
+ }
+ }
+ }
+ }
+
+ r_island_data->axismtx = axismtx;
+ r_island_data->center = center;
+ r_island_data->island_tot = group_tot;
+ r_island_data->island_vert_map = vert_map;
+}
+
+/** \} */
+
/* -------------------------------------------------------------------- */
-/** \name Edit Mesh Verts Transform Creation
+/** \name Connectivity Distance for Proportional Editing
*
* \{ */
@@ -243,171 +422,25 @@ static void editmesh_set_connectivity_distance(BMesh *bm,
}
}
-static void editmesh_islands_info_calc(BMEditMesh *em,
- const bool calc_single_islands,
- const bool calc_island_axismtx,
- struct TransIslandData *r_island_data)
-{
- BMesh *bm = em->bm;
- char htype;
- char itype;
- int i;
-
- /* group vars */
- float(*center)[3];
- float(*axismtx)[3][3] = NULL;
- int *groups_array;
- int(*group_index)[2];
- int group_tot;
- void **ele_array;
-
- int *vert_map;
-
- if (em->selectmode & (SCE_SELECT_VERTEX | SCE_SELECT_EDGE)) {
- groups_array = MEM_mallocN(sizeof(*groups_array) * bm->totedgesel, __func__);
- group_tot = BM_mesh_calc_edge_groups(
- bm, groups_array, &group_index, NULL, NULL, BM_ELEM_SELECT);
-
- htype = BM_EDGE;
- itype = BM_VERTS_OF_EDGE;
- }
- else { /* (bm->selectmode & SCE_SELECT_FACE) */
- groups_array = MEM_mallocN(sizeof(*groups_array) * bm->totfacesel, __func__);
- group_tot = BM_mesh_calc_face_groups(
- bm, groups_array, &group_index, NULL, NULL, BM_ELEM_SELECT, BM_VERT);
-
- htype = BM_FACE;
- itype = BM_VERTS_OF_FACE;
- }
-
- center = MEM_mallocN(sizeof(*center) * group_tot, __func__);
-
- if (calc_island_axismtx) {
- axismtx = MEM_mallocN(sizeof(*axismtx) * group_tot, __func__);
- }
-
- vert_map = MEM_mallocN(sizeof(*vert_map) * bm->totvert, __func__);
- /* we shouldn't need this, but with incorrect selection flushing
- * its possible we have a selected vertex that's not in a face,
- * for now best not crash in that case. */
- copy_vn_i(vert_map, bm->totvert, -1);
-
- BM_mesh_elem_table_ensure(bm, htype);
- ele_array = (htype == BM_FACE) ? (void **)bm->ftable : (void **)bm->etable;
-
- BM_mesh_elem_index_ensure(bm, BM_VERT);
-
- /* may be an edge OR a face array */
- for (i = 0; i < group_tot; i++) {
- BMEditSelection ese = {NULL};
-
- const int fg_sta = group_index[i][0];
- const int fg_len = group_index[i][1];
- float co[3], no[3], tangent[3];
- int j;
-
- zero_v3(co);
- zero_v3(no);
- zero_v3(tangent);
-
- ese.htype = htype;
-
- /* loop on each face or edge in this group:
- * - assign r_vert_map
- * - calculate (co, no)
- */
- for (j = 0; j < fg_len; j++) {
- float tmp_co[3], tmp_no[3], tmp_tangent[3];
-
- ese.ele = ele_array[groups_array[fg_sta + j]];
-
- BM_editselection_center(&ese, tmp_co);
- add_v3_v3(co, tmp_co);
-
- if (axismtx) {
- BM_editselection_normal(&ese, tmp_no);
- BM_editselection_plane(&ese, tmp_tangent);
- add_v3_v3(no, tmp_no);
- add_v3_v3(tangent, tmp_tangent);
- }
-
- {
- /* setup vertex map */
- BMIter iter;
- BMVert *v;
-
- /* connected edge-verts */
- BM_ITER_ELEM (v, &iter, ese.ele, itype) {
- vert_map[BM_elem_index_get(v)] = i;
- }
- }
- }
-
- mul_v3_v3fl(center[i], co, 1.0f / (float)fg_len);
-
- if (axismtx) {
- if (createSpaceNormalTangent(axismtx[i], no, tangent)) {
- /* pass */
- }
- else {
- if (normalize_v3(no) != 0.0f) {
- axis_dominant_v3_to_m3(axismtx[i], no);
- invert_m3(axismtx[i]);
- }
- else {
- unit_m3(axismtx[i]);
- }
- }
- }
- }
-
- MEM_freeN(groups_array);
- MEM_freeN(group_index);
-
- /* for PET we need islands of 1 so connected vertices can use it with V3D_AROUND_LOCAL_ORIGINS */
- if (calc_single_islands) {
- BMIter viter;
- BMVert *v;
- int group_tot_single = 0;
-
- BM_ITER_MESH_INDEX (v, &viter, bm, BM_VERTS_OF_MESH, i) {
- if (BM_elem_flag_test(v, BM_ELEM_SELECT) && (vert_map[i] == -1)) {
- group_tot_single += 1;
- }
- }
-
- if (group_tot_single != 0) {
- center = MEM_reallocN(center, sizeof(*center) * (group_tot + group_tot_single));
- if (axismtx) {
- axismtx = MEM_reallocN(axismtx, sizeof(*axismtx) * (group_tot + group_tot_single));
- }
+/** \} */
- BM_ITER_MESH_INDEX (v, &viter, bm, BM_VERTS_OF_MESH, i) {
- if (BM_elem_flag_test(v, BM_ELEM_SELECT) && (vert_map[i] == -1)) {
- vert_map[i] = group_tot;
- copy_v3_v3(center[group_tot], v->co);
+/* -------------------------------------------------------------------- */
+/** \name TransDataMirror Creation
+ *
+ * \{ */
- if (axismtx) {
- if (is_zero_v3(v->no) != 0.0f) {
- axis_dominant_v3_to_m3(axismtx[group_tot], v->no);
- invert_m3(axismtx[group_tot]);
- }
- else {
- unit_m3(axismtx[group_tot]);
- }
- }
+/* Used for both mirror epsilon and TD_MIRROR_EDGE_ */
+#define TRANSFORM_MAXDIST_MIRROR 0.00002f
- group_tot += 1;
- }
- }
- }
- }
+struct MirrorDataVert {
+ int index;
+ int flag;
+};
- r_island_data->axismtx = axismtx;
- r_island_data->center = center;
- r_island_data->island_tot = group_tot;
- r_island_data->island_vert_map = vert_map;
-}
+struct TransMirrorData {
+ struct MirrorDataVert *vert_map;
+ int mirror_elem_len;
+};
static bool is_in_quadrant_v3(const float co[3], const int quadrant[3], const float epsilon)
{
@@ -423,172 +456,124 @@ static bool is_in_quadrant_v3(const float co[3], const int quadrant[3], const fl
return true;
}
-static TransDataMirror *editmesh_mirror_data_calc(BMEditMesh *em,
- bool use_select,
- const bool use_topology,
- const bool mirror_axis[3],
- int *r_mirror_data_len,
- BLI_bitmap **r_mirror_bitmap)
+static void editmesh_mirror_data_calc(BMEditMesh *em,
+ const bool use_select,
+ const bool use_topology,
+ const bool mirror_axis[3],
+ struct TransMirrorData *r_mirror_data)
{
- BMesh *bm = em->bm;
- int *index[3] = {NULL};
- int i;
-
- bool test_selected_only = use_select && (mirror_axis[0] + mirror_axis[1] + mirror_axis[2]) == 1;
- for (i = 0; i < 3; i++) {
- if (mirror_axis[i]) {
- index[i] = MEM_mallocN(bm->totvert * sizeof(int), __func__);
- EDBM_verts_mirror_cache_begin_ex(
- em, i, false, test_selected_only, use_topology, TRANSFORM_MAXDIST_MIRROR, index[i]);
- }
- }
+ struct MirrorDataVert *vert_map;
+ BMesh *bm = em->bm;
BMVert *eve;
BMIter iter;
+ int i, flag, totvert = bm->totvert;
- int quadrant[3];
- {
- float select_sum[3] = {0};
- BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
- if (BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
- continue;
- }
- if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
- add_v3_v3(select_sum, eve->co);
- }
- }
-
- for (i = 0; i < 3; i++) {
- if (mirror_axis[i]) {
- quadrant[i] = select_sum[i] >= 0.0f ? 1 : -1;
- }
- else {
- quadrant[i] = 0;
- }
- }
- }
+ vert_map = MEM_mallocN(totvert * sizeof(*vert_map), __func__);
- /* Tag only elements that will be transformed within the quadrant. */
+ float select_sum[3] = {0};
BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
+ vert_map[i] = (struct MirrorDataVert){-1, 0};
if (BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
continue;
}
- if ((!use_select || BM_elem_flag_test(eve, BM_ELEM_SELECT)) &&
- is_in_quadrant_v3(eve->co, quadrant, TRANSFORM_MAXDIST_MIRROR)) {
- BM_elem_flag_enable(eve, BM_ELEM_TAG);
- BM_elem_index_set(eve, i);
+ if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
+ add_v3_v3(select_sum, eve->co);
+ }
+ }
+
+ /* Tag only elements that will be transformed within the quadrant. */
+ int quadrant[3];
+ for (int a = 0; a < 3; a++) {
+ if (mirror_axis[a]) {
+ quadrant[a] = select_sum[a] >= 0.0f ? 1 : -1;
}
else {
- BM_elem_flag_disable(eve, BM_ELEM_TAG);
- BM_elem_index_set(eve, -1);
+ quadrant[a] = 0;
}
}
+ uint mirror_elem_len = 0;
+ int *index[3] = {NULL, NULL, NULL};
+ bool test_selected_only = use_select && (mirror_axis[0] + mirror_axis[1] + mirror_axis[2]) == 1;
for (int a = 0; a < 3; a++) {
- int *index_iter = index[a];
- if (index_iter == NULL) {
+ if (!mirror_axis[a]) {
continue;
}
+
+ index[a] = MEM_mallocN(totvert * sizeof(*index[a]), __func__);
+ EDBM_verts_mirror_cache_begin_ex(
+ em, a, false, test_selected_only, use_topology, TRANSFORM_MAXDIST_MIRROR, index[a]);
+
+ flag = TD_MIRROR_X << a;
BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
+ int i_mirr = index[a][i];
+ if (i_mirr < 0) {
+ continue;
+ }
if (BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
continue;
}
- if (test_selected_only && !BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
+ if (use_select && !BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
continue;
}
- int elem_index = BM_elem_index_get(eve);
- if (elem_index != -1) {
- int i_mirr = index_iter[i];
- if (i_mirr >= 0) {
- BMVert *vmir = BM_vert_at_index(bm, i_mirr);
- BM_elem_index_set(vmir, elem_index);
-
- /* The slot of this element in the index array no longer needs to be read.
- * Use to set the mirror sign. */
- if (index[0] && a > 0) {
- index[0][i_mirr] = index[0][i];
- }
- if (index[1] && a > 1) {
- index[1][i_mirr] = index[1][i];
- }
- /* Use -2 to differ from -1, but both can work. */
- index_iter[i_mirr] = -2;
- }
+ if (!is_in_quadrant_v3(eve->co, quadrant, TRANSFORM_MAXDIST_MIRROR)) {
+ continue;
}
- }
- }
- /* Count mirror elements. */
- uint mirror_elem_len = 0;
- BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
- if (BM_elem_flag_test(eve, BM_ELEM_HIDDEN | BM_ELEM_TAG)) {
- /* Not a mirror element. */
- BM_elem_index_set(eve, -1);
- continue;
- }
- int elem_index = BM_elem_index_get(eve);
- if (elem_index != -1) {
+ vert_map[i_mirr] = (struct MirrorDataVert){i, flag};
mirror_elem_len++;
}
}
- TransDataMirror *td_mirror_iter, *td_mirror = NULL;
- if (mirror_elem_len != 0) {
- td_mirror = MEM_mallocN(mirror_elem_len * sizeof(*td_mirror), __func__);
- td_mirror_iter = &td_mirror[0];
-
- *r_mirror_bitmap = BLI_BITMAP_NEW(bm->totvert, __func__);
-
- BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
- int elem_index = BM_elem_index_get(eve);
- if (elem_index != -1) {
- BMVert *v_src = BM_vert_at_index(bm, elem_index);
+ if (mirror_elem_len) {
+ for (int a = 0; a < 3; a++) {
+ if (!mirror_axis[a]) {
+ continue;
+ }
- int flag = 0;
- if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
- flag |= TD_SELECTED;
- }
- if (index[0] && index[0][i] == -2) {
- flag |= TD_MIRROR_X;
- }
- if (index[1] && index[1][i] == -2) {
- flag |= TD_MIRROR_Y;
+ flag = TD_MIRROR_X << a;
+ for (i = 0; i < totvert; i++) {
+ int i_mirr = index[a][i];
+ if (i_mirr < 0) {
+ continue;
}
- if (index[2] && index[2][i] == -2) {
- flag |= TD_MIRROR_Z;
+ if (vert_map[i].index != -1 && !(vert_map[i].flag & flag)) {
+ if (vert_map[i_mirr].index == -1) {
+ mirror_elem_len++;
+ }
+ vert_map[i_mirr].index = vert_map[i].index;
+ vert_map[i_mirr].flag |= vert_map[i].flag | flag;
}
-
- td_mirror_iter->extra = eve;
- td_mirror_iter->loc = eve->co;
- copy_v3_v3(td_mirror_iter->iloc, eve->co);
- td_mirror_iter->flag = flag;
- td_mirror_iter->loc_src = v_src->co;
- /** `center` will be set in the main createTransEditVerts loop.
- * copy_v3_v3(td_mirror_iter->center, eve->co); */
-
- td_mirror_iter++;
-
- BLI_BITMAP_ENABLE(*r_mirror_bitmap, i);
}
}
}
+ else {
+ MEM_freeN(vert_map);
+ vert_map = NULL;
+ }
MEM_SAFE_FREE(index[0]);
MEM_SAFE_FREE(index[1]);
MEM_SAFE_FREE(index[2]);
- bm->elem_index_dirty |= BM_VERT;
- *r_mirror_data_len = mirror_elem_len;
- return td_mirror;
+ r_mirror_data->vert_map = vert_map;
+ r_mirror_data->mirror_elem_len = mirror_elem_len;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Edit Mesh Verts Transform Creation
+ *
+ * \{ */
+
static void transdata_center_get(const struct TransIslandData *island_data,
const int island_index,
- const bool no_island_center,
const float iloc[3],
float r_center[3])
{
- if (island_index != -1 && !no_island_center) {
+ if (island_data->center && island_index != -1) {
copy_v3_v3(r_center, island_data->center[island_index]);
}
else {
@@ -604,8 +589,7 @@ static void VertsToTransData(TransInfo *t,
BMVert *eve,
float *bweight,
const struct TransIslandData *island_data,
- const int island_index,
- const bool no_island_center)
+ const int island_index)
{
float *no, _no[3];
BLI_assert(BM_elem_flag_test(eve, BM_ELEM_HIDDEN) == 0);
@@ -626,7 +610,7 @@ static void VertsToTransData(TransInfo *t,
no = eve->no;
}
- transdata_center_get(island_data, island_index, no_island_center, td->iloc, td->center);
+ transdata_center_get(island_data, island_index, td->iloc, td->center);
if ((island_index != -1) && island_data->axismtx) {
copy_m3_m3(td->axismtx, island_data->axismtx[island_index]);
@@ -676,31 +660,12 @@ void createTransEditVerts(TransInfo *t)
BMesh *bm = em->bm;
BMVert *eve;
BMIter iter;
- float(*mappedcos)[3] = NULL, (*quats)[4] = NULL;
- float mtx[3][3], smtx[3][3], (*defmats)[3][3] = NULL, (*defcos)[3] = NULL;
- float *dists = NULL;
+ float mtx[3][3], smtx[3][3];
int a;
const int prop_mode = (t->flag & T_PROP_EDIT) ? (t->flag & T_PROP_EDIT_ALL) : 0;
- int cd_vert_bweight_offset = -1;
struct TransIslandData island_data = {NULL};
-
- /* Snap rotation along normal needs a common axis for whole islands,
- * otherwise one get random crazy results, see T59104.
- * However, we do not want to use the island center for the pivot/translation reference. */
- const bool is_snap_rotate = ((t->mode == TFM_TRANSLATION) &&
- /* There is not guarantee that snapping
- * is initialized yet at this point... */
- (usingSnappingNormal(t) ||
- (t->settings->snap_flag & SCE_SNAP_ROTATE) != 0) &&
- (t->around != V3D_AROUND_LOCAL_ORIGINS));
- /* Even for translation this is needed because of island-orientation, see: T51651. */
- const bool is_island_center = (t->around == V3D_AROUND_LOCAL_ORIGINS) || is_snap_rotate;
- /* Original index of our connected vertex when connected distances are calculated.
- * Optional, allocate if needed. */
- int *dists_index = NULL;
-
- BLI_bitmap *mirror_bitmap = NULL;
+ struct TransMirrorData mirror_data = {NULL};
/**
* Quick check if we can transform.
@@ -711,20 +676,7 @@ void createTransEditVerts(TransInfo *t)
/* Support other objects using PET to adjust these, unless connected is enabled. */
if ((!prop_mode || (prop_mode & T_PROP_CONNECTED)) && (bm->totvertsel == 0)) {
- goto cleanup;
- }
-
- if (t->mode == TFM_BWEIGHT) {
- BM_mesh_cd_flag_ensure(bm, BKE_mesh_from_object(tc->obedit), ME_CDFLAG_VERT_BWEIGHT);
- cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
- }
-
- if (tc->use_mirror_axis_any) {
- bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0;
- bool use_select = (t->flag & T_PROP_EDIT) == 0;
- bool mirror_axis[3] = {tc->use_mirror_axis_x, tc->use_mirror_axis_y, tc->use_mirror_axis_z};
- tc->data_mirror = editmesh_mirror_data_calc(
- em, use_select, use_topology, mirror_axis, &tc->data_mirror_len, &mirror_bitmap);
+ continue;
}
int data_len = 0;
@@ -734,44 +686,41 @@ void createTransEditVerts(TransInfo *t)
data_len++;
}
}
-
- if (data_len == 0) {
- goto cleanup;
- }
-
- /* allocating scratch arrays */
- if (prop_mode & T_PROP_CONNECTED) {
- dists = MEM_mallocN(em->bm->totvert * sizeof(float), __func__);
- if (is_island_center) {
- dists_index = MEM_mallocN(em->bm->totvert * sizeof(int), __func__);
- }
- }
}
else {
data_len = bm->totvertsel;
}
- if (mirror_bitmap) {
- BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, a) {
- if (prop_mode || BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
- if (BLI_BITMAP_TEST(mirror_bitmap, a)) {
- data_len--;
- }
- }
- }
+ if (data_len == 0) {
+ continue;
}
- BLI_assert(data_len != 0);
+ /* Snap rotation along normal needs a common axis for whole islands,
+ * otherwise one get random crazy results, see T59104.
+ * However, we do not want to use the island center for the pivot/translation reference. */
+ const bool is_snap_rotate = ((t->mode == TFM_TRANSLATION) &&
+ /* There is not guarantee that snapping
+ * is initialized yet at this point... */
+ (usingSnappingNormal(t) ||
+ (t->settings->snap_flag & SCE_SNAP_ROTATE) != 0) &&
+ (t->around != V3D_AROUND_LOCAL_ORIGINS));
- tc->data_len = data_len;
- tc->data = MEM_callocN(data_len * sizeof(TransData), "TransObData(Mesh EditMode)");
- if (ELEM(t->mode, TFM_SKIN_RESIZE, TFM_SHRINKFATTEN)) {
- /* warning, this is overkill, we only need 2 extra floats,
- * but this stores loads of extra stuff, for TFM_SHRINKFATTEN its even more overkill
- * since we may not use the 'alt' transform mode to maintain shell thickness,
- * but with generic transform code its hard to lazy init vars */
- tx = tc->data_ext = MEM_callocN(tc->data_len * sizeof(TransDataExtension),
- "TransObData ext");
+ /* Even for translation this is needed because of island-orientation, see: T51651. */
+ const bool is_island_center = (t->around == V3D_AROUND_LOCAL_ORIGINS) || is_snap_rotate;
+ if (is_island_center) {
+ /* In this specific case, near-by vertices will need to know
+ * the island of the nearest connected vertex. */
+ const bool calc_single_islands = ((prop_mode & T_PROP_CONNECTED) &&
+ (t->around == V3D_AROUND_LOCAL_ORIGINS) &&
+ (em->selectmode & SCE_SELECT_VERTEX));
+
+ const bool calc_island_center = !is_snap_rotate;
+ /* The island axismtx is only necessary in some modes.
+ * TODO(Germano): Extend the list to exclude other modes. */
+ const bool calc_island_axismtx = !ELEM(t->mode, TFM_SHRINKFATTEN);
+
+ editmesh_islands_info_calc(
+ em, calc_single_islands, calc_island_center, calc_island_axismtx, &island_data);
}
copy_m3_m4(mtx, tc->obedit->obmat);
@@ -779,26 +728,58 @@ void createTransEditVerts(TransInfo *t)
* matrix inversion still works and we can still moving along the other */
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
+ /* Original index of our connected vertex when connected distances are calculated.
+ * Optional, allocate if needed. */
+ int *dists_index = NULL;
+ float *dists = NULL;
if (prop_mode & T_PROP_CONNECTED) {
+ dists = MEM_mallocN(bm->totvert * sizeof(float), __func__);
+ if (is_island_center) {
+ dists_index = MEM_mallocN(bm->totvert * sizeof(int), __func__);
+ }
editmesh_set_connectivity_distance(em->bm, mtx, dists, dists_index);
}
- if (is_island_center) {
- /* In this specific case, near-by vertices will need to know
- * the island of the nearest connected vertex. */
- const bool calc_single_islands = ((prop_mode & T_PROP_CONNECTED) &&
- (t->around == V3D_AROUND_LOCAL_ORIGINS) &&
- (em->selectmode & SCE_SELECT_VERTEX));
+ /* Create TransDataMirror. */
+ if (tc->use_mirror_axis_any) {
+ bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0;
+ bool use_select = (t->flag & T_PROP_EDIT) == 0;
+ bool mirror_axis[3] = {tc->use_mirror_axis_x, tc->use_mirror_axis_y, tc->use_mirror_axis_z};
+ editmesh_mirror_data_calc(em, use_select, use_topology, mirror_axis, &mirror_data);
- /* The island axismtx is only necessary in some modes.
- * TODO(Germano): Extend the list to exclude other modes. */
- const bool calc_island_axismtx = !ELEM(t->mode, TFM_SHRINKFATTEN);
+ if (mirror_data.vert_map) {
+ tc->data_mirror_len = mirror_data.mirror_elem_len;
+ tc->data_mirror = MEM_mallocN(mirror_data.mirror_elem_len * sizeof(*tc->data_mirror),
+ __func__);
+
+ BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, a) {
+ if (prop_mode || BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
+ if (mirror_data.vert_map[a].index != -1) {
+ data_len--;
+ }
+ }
+ }
+ }
+ }
- editmesh_islands_info_calc(em, calc_single_islands, calc_island_axismtx, &island_data);
+ /* Create TransData. */
+ BLI_assert(data_len >= 1);
+ tc->data_len = data_len;
+ tc->data = MEM_callocN(data_len * sizeof(TransData), "TransObData(Mesh EditMode)");
+ if (ELEM(t->mode, TFM_SKIN_RESIZE, TFM_SHRINKFATTEN)) {
+ /* warning, this is overkill, we only need 2 extra floats,
+ * but this stores loads of extra stuff, for TFM_SHRINKFATTEN its even more overkill
+ * since we may not use the 'alt' transform mode to maintain shell thickness,
+ * but with generic transform code its hard to lazy init vars */
+ tx = tc->data_ext = MEM_callocN(tc->data_len * sizeof(TransDataExtension),
+ "TransObData ext");
}
/* detect CrazySpace [tm] */
+ float(*quats)[4] = NULL;
+ float(*defmats)[3][3] = NULL;
if (BKE_modifiers_get_cage_index(t->scene, tc->obedit, NULL, 1) != -1) {
+ float(*defcos)[3] = NULL;
int totleft = -1;
if (BKE_modifiers_is_correctable_deformed(t->scene, tc->obedit)) {
BKE_scene_graph_evaluated_ensure(t->depsgraph, CTX_data_main(t->context));
@@ -813,16 +794,17 @@ void createTransEditVerts(TransInfo *t)
t->depsgraph, scene_eval, obedit_eval, em_eval, &defmats, &defcos);
}
- /* if we still have more modifiers, also do crazyspace
- * correction with quats, relative to the coordinates after
- * the modifiers that support deform matrices (defcos) */
+ /* If we still have more modifiers, also do crazy-space
+ * correction with \a quats, relative to the coordinates after
+ * the modifiers that support deform matrices \a defcos. */
-#if 0 /* TODO, fix crazyspace+extrude so it can be enabled for general use - campbell */
+#if 0 /* TODO, fix crazy-space & extrude so it can be enabled for general use - campbell */
if ((totleft > 0) || (totleft == -1))
#else
if (totleft > 0)
#endif
{
+ float(*mappedcos)[3] = NULL;
mappedcos = BKE_crazyspace_get_mapped_editverts(t->depsgraph, tc->obedit);
quats = MEM_mallocN(em->bm->totvert * sizeof(*quats), "crazy quats");
BKE_crazyspace_set_quats_editmesh(em, defcos, mappedcos, quats, !prop_mode);
@@ -836,6 +818,12 @@ void createTransEditVerts(TransInfo *t)
}
}
+ int cd_vert_bweight_offset = -1;
+ if (t->mode == TFM_BWEIGHT) {
+ BM_mesh_cd_flag_ensure(bm, BKE_mesh_from_object(tc->obedit), ME_CDFLAG_VERT_BWEIGHT);
+ cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
+ }
+
TransData *tob = tc->data;
TransDataMirror *td_mirror = tc->data_mirror;
BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, a) {
@@ -849,9 +837,20 @@ void createTransEditVerts(TransInfo *t)
island_index = island_data.island_vert_map[connected_index];
}
- if (mirror_bitmap && BLI_BITMAP_TEST(mirror_bitmap, a)) {
- transdata_center_get(
- &island_data, island_index, is_snap_rotate, td_mirror->iloc, td_mirror->center);
+ if (mirror_data.vert_map && mirror_data.vert_map[a].index != -1) {
+ int elem_index = mirror_data.vert_map[a].index;
+ BMVert *v_src = BM_vert_at_index(bm, elem_index);
+
+ if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
+ mirror_data.vert_map[a].flag |= TD_SELECTED;
+ }
+
+ td_mirror->extra = eve;
+ td_mirror->loc = eve->co;
+ copy_v3_v3(td_mirror->iloc, eve->co);
+ td_mirror->flag = mirror_data.vert_map[a].flag;
+ td_mirror->loc_src = v_src->co;
+ transdata_center_get(&island_data, island_index, td_mirror->iloc, td_mirror->center);
td_mirror++;
}
@@ -862,8 +861,7 @@ void createTransEditVerts(TransInfo *t)
/* Do not use the island center in case we are using islands
* only to get axis for snap/rotate to normal... */
- VertsToTransData(
- t, tob, tx, em, eve, bweight, &island_data, island_index, is_snap_rotate);
+ VertsToTransData(t, tob, tx, em, eve, bweight, &island_data, island_index);
if (tx) {
tx++;
}
@@ -933,17 +931,15 @@ void createTransEditVerts(TransInfo *t)
if (island_data.center) {
MEM_freeN(island_data.center);
}
-
if (island_data.axismtx) {
MEM_freeN(island_data.axismtx);
}
-
if (island_data.island_vert_map) {
MEM_freeN(island_data.island_vert_map);
}
-
- cleanup:
- /* crazy space free */
+ if (mirror_data.vert_map) {
+ MEM_freeN(mirror_data.vert_map);
+ }
if (quats) {
MEM_freeN(quats);
}
@@ -956,9 +952,6 @@ void createTransEditVerts(TransInfo *t)
if (dists_index) {
MEM_freeN(dists_index);
}
- if (mirror_bitmap) {
- MEM_freeN(mirror_bitmap);
- }
}
}
@@ -1075,99 +1068,118 @@ static void create_trans_vert_customdata_layer(BMVert *v,
BLI_ghash_insert(tcld->origverts, v, r_tcld_vert);
}
-void trans_mesh_customdata_correction_init(TransInfo *t, TransDataContainer *tc)
+static void trans_mesh_customdata_correction_init_container(TransInfo *t, TransDataContainer *tc)
{
if (tc->custom.type.data) {
/* Custom data correction has initiated before. */
BLI_assert(tc->custom.type.free_cb == trans_mesh_customdata_free_cb);
return;
}
- int i;
+
+ if (!ELEM(t->mode,
+ TFM_TRANSLATION,
+ TFM_ROTATION,
+ TFM_RESIZE,
+ TFM_TOSPHERE,
+ TFM_SHEAR,
+ TFM_BEND,
+ TFM_SHRINKFATTEN,
+ TFM_TRACKBALL,
+ TFM_PUSHPULL,
+ TFM_ALIGN)) {
+ /* Currently only modes that change the position of vertices are supported. */
+ return;
+ }
BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
BMesh *bm = em->bm;
- bool use_origfaces;
- int cd_loop_mdisp_offset;
- {
- const bool has_layer_math = CustomData_has_math(&bm->ldata);
- cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
- if ((t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) &&
- /* don't do this at all for non-basis shape keys, too easy to
- * accidentally break uv maps or vertex colors then */
- (bm->shapenr <= 1) && (has_layer_math || (cd_loop_mdisp_offset != -1))) {
- use_origfaces = true;
- }
- else {
- use_origfaces = false;
- cd_loop_mdisp_offset = -1;
- }
+ if (bm->shapenr > 1) {
+ /* Don't do this at all for non-basis shape keys, too easy to
+ * accidentally break uv maps or vertex colors then */
+ /* create copies of faces for customdata projection. */
+ return;
}
- if (use_origfaces) {
- /* create copies of faces for customdata projection */
- bmesh_edit_begin(bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES);
-
- struct GHash *origfaces = BLI_ghash_ptr_new(__func__);
- struct BMesh *bm_origfaces = BM_mesh_create(&bm_mesh_allocsize_default,
- &((struct BMeshCreateParams){
- .use_toolflags = false,
- }));
-
- /* we need to have matching customdata */
- BM_mesh_copy_init_customdata(bm_origfaces, bm, NULL);
-
- int *layer_math_map = NULL;
- int layer_index_dst = 0;
- {
- /* TODO: We don't need `sod->layer_math_map` when there are no loops linked
- * to one of the sliding vertices. */
- if (CustomData_has_math(&bm->ldata)) {
- /* over alloc, only 'math' layers are indexed */
- layer_math_map = MEM_mallocN(bm->ldata.totlayer * sizeof(int), __func__);
- for (i = 0; i < bm->ldata.totlayer; i++) {
- if (CustomData_layer_has_math(&bm->ldata, i)) {
- layer_math_map[layer_index_dst++] = i;
- }
+ const bool has_layer_math = CustomData_has_math(&bm->ldata);
+ const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
+ if (!has_layer_math && (cd_loop_mdisp_offset == -1)) {
+ return;
+ }
+
+ bmesh_edit_begin(bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES);
+
+ struct GHash *origfaces = BLI_ghash_ptr_new(__func__);
+ struct BMesh *bm_origfaces = BM_mesh_create(&bm_mesh_allocsize_default,
+ &((struct BMeshCreateParams){
+ .use_toolflags = false,
+ }));
+
+ /* we need to have matching customdata */
+ BM_mesh_copy_init_customdata(bm_origfaces, bm, NULL);
+
+ int *layer_math_map = NULL;
+ int layer_math_map_len = 0;
+ {
+ /* TODO: We don't need `sod->layer_math_map` when there are no loops linked
+ * to one of the sliding vertices. */
+ if (has_layer_math) {
+ /* over alloc, only 'math' layers are indexed */
+ layer_math_map = MEM_mallocN(bm->ldata.totlayer * sizeof(int), __func__);
+ for (int i = 0; i < bm->ldata.totlayer; i++) {
+ if (CustomData_layer_has_math(&bm->ldata, i)) {
+ layer_math_map[layer_math_map_len++] = i;
}
- BLI_assert(layer_index_dst != 0);
}
+ BLI_assert(layer_math_map_len != 0);
}
+ }
- struct TransCustomDataLayer *tcld;
- tc->custom.type.data = tcld = MEM_mallocN(sizeof(*tcld), __func__);
- tc->custom.type.free_cb = trans_mesh_customdata_free_cb;
-
- tcld->bm = bm;
- tcld->origfaces = origfaces;
- tcld->bm_origfaces = bm_origfaces;
- tcld->cd_loop_mdisp_offset = cd_loop_mdisp_offset;
- tcld->layer_math_map = layer_math_map;
- tcld->layer_math_map_num = layer_index_dst;
- tcld->arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
+ struct TransCustomDataLayer *tcld = MEM_mallocN(sizeof(*tcld), __func__);
+ int data_len = tc->data_len + tc->data_mirror_len;
- int data_len = tc->data_len + tc->data_mirror_len;
- struct GHash *origverts = BLI_ghash_ptr_new_ex(__func__, data_len);
- tcld->origverts = origverts;
+ tcld->bm = bm;
+ tcld->origfaces = origfaces;
+ tcld->bm_origfaces = bm_origfaces;
+ tcld->cd_loop_mdisp_offset = cd_loop_mdisp_offset;
+ tcld->layer_math_map = layer_math_map;
+ tcld->layer_math_map_num = layer_math_map_len;
+ tcld->arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
+ tcld->origverts = BLI_ghash_ptr_new_ex(__func__, data_len);
+ tcld->data = BLI_memarena_alloc(tcld->arena, data_len * sizeof(*tcld->data));
+ tcld->data_len = data_len;
- struct TransCustomDataLayerVert *tcld_vert, *tcld_vert_iter;
- tcld_vert = BLI_memarena_alloc(tcld->arena, data_len * sizeof(*tcld_vert));
- tcld_vert_iter = &tcld_vert[0];
+ {
+ /* Setup Verts. */
+ struct TransCustomDataLayerVert *tcld_vert_iter = &tcld->data[0];
- TransData *tob;
- for (i = tc->data_len, tob = tc->data; i--; tob++, tcld_vert_iter++) {
+ TransData *tob = tc->data;
+ for (int i = tc->data_len; i--; tob++, tcld_vert_iter++) {
BMVert *v = tob->extra;
create_trans_vert_customdata_layer(v, tcld, tcld_vert_iter);
}
TransDataMirror *td_mirror = tc->data_mirror;
- for (i = tc->data_mirror_len; i--; td_mirror++, tcld_vert_iter++) {
+ for (int i = tc->data_mirror_len; i--; td_mirror++, tcld_vert_iter++) {
BMVert *v = td_mirror->extra;
create_trans_vert_customdata_layer(v, tcld, tcld_vert_iter);
}
+ }
+
+ tc->custom.type.data = tcld;
+ tc->custom.type.free_cb = trans_mesh_customdata_free_cb;
+}
+
+void trans_mesh_customdata_correction_init(TransInfo *t)
+{
+ const char uvcalc_correct_flag = ELEM(t->mode, TFM_VERT_SLIDE, TFM_EDGE_SLIDE) ?
+ UVCALC_TRANSFORM_CORRECT_SLIDE :
+ UVCALC_TRANSFORM_CORRECT;
- tcld->data = tcld_vert;
- tcld->data_len = data_len;
+ if (t->settings->uvcalc_flag & uvcalc_correct_flag) {
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+ trans_mesh_customdata_correction_init_container(t, tc);
+ }
}
}
@@ -1187,19 +1199,17 @@ static void trans_mesh_customdata_correction_apply_vert(struct TransCustomDataLa
BMesh *bm = tcld->bm;
BMVert *v = tcld_vert->v;
const float *co_orig_3d = tcld_vert->co_orig_3d;
- struct LinkNode **cd_loop_groups = tcld_vert->cd_loop_groups;
BMIter liter;
int j, l_num;
float *loop_weights;
const bool is_moved = (len_squared_v3v3(v->co, co_orig_3d) > FLT_EPSILON);
- const bool do_loop_weight = tcld->layer_math_map_num && is_moved;
- const bool do_loop_mdisps = is_final && is_moved && (tcld->cd_loop_mdisp_offset != -1);
+ const bool do_loop_weight = is_moved && tcld->layer_math_map_num;
const float *v_proj_axis = v->no;
/* original (l->prev, l, l->next) projections for each loop ('l' remains unchanged) */
float v_proj[3][3];
- if (do_loop_weight || do_loop_mdisps) {
+ if (do_loop_weight) {
project_plane_normalized_v3_v3v3(v_proj[1], co_orig_3d, v_proj_axis);
}
@@ -1264,6 +1274,7 @@ static void trans_mesh_customdata_correction_apply_vert(struct TransCustomDataLa
}
}
+ struct LinkNode **cd_loop_groups = tcld_vert->cd_loop_groups;
if (tcld->layer_math_map_num && cd_loop_groups) {
if (do_loop_weight) {
for (j = 0; j < tcld->layer_math_map_num; j++) {
@@ -1283,6 +1294,7 @@ static void trans_mesh_customdata_correction_apply_vert(struct TransCustomDataLa
* Interpolate from every other loop (not ideal)
* However values will only be taken from loops which overlap other mdisps.
* */
+ const bool do_loop_mdisps = is_moved && is_final && (tcld->cd_loop_mdisp_offset != -1);
if (do_loop_mdisps) {
float(*faces_center)[3] = BLI_array_alloca(faces_center, l_num);
BMLoop *l;
@@ -1386,13 +1398,9 @@ void recalcData_mesh(TransInfo *t)
}
}
- if (ELEM(t->mode, TFM_EDGE_SLIDE, TFM_VERT_SLIDE)) {
- FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- trans_mesh_customdata_correction_apply(tc, false);
- }
- }
-
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+ trans_mesh_customdata_correction_apply(tc, false);
+
DEG_id_tag_update(tc->obedit->data, 0); /* sets recalc flags */
BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
EDBM_mesh_normals_update(em);
@@ -1408,18 +1416,9 @@ void recalcData_mesh(TransInfo *t)
void special_aftertrans_update__mesh(bContext *UNUSED(C), TransInfo *t)
{
const bool canceled = (t->state == TRANS_CANCEL);
+ const bool use_automerge = !canceled && (t->flag & (T_AUTOMERGE | T_AUTOSPLIT)) != 0;
- if (canceled) {
- /* Exception, edge slide transformed UVs too. */
- if (t->mode == TFM_EDGE_SLIDE) {
- doEdgeSlide(t, 0.0f);
- }
- else if (t->mode == TFM_VERT_SLIDE) {
- doVertSlide(t, 0.0f);
- }
- }
-
- if (ELEM(t->mode, TFM_EDGE_SLIDE, TFM_VERT_SLIDE)) {
+ if (TRANS_DATA_CONTAINER_FIRST_OK(t)->custom.type.data != NULL) {
/* Handle multires re-projection, done
* on transform completion since it's
* really slow -joeedh. */
@@ -1428,10 +1427,8 @@ void special_aftertrans_update__mesh(bContext *UNUSED(C), TransInfo *t)
}
}
- bool use_automerge = !canceled && (t->flag & (T_AUTOMERGE | T_AUTOSPLIT)) != 0;
if (use_automerge) {
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
-
BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
BMesh *bm = em->bm;
char hflag;
diff --git a/source/blender/editors/transform/transform_data.h b/source/blender/editors/transform/transform_data.h
index bc95fdad59c..48ed9ecf34b 100644
--- a/source/blender/editors/transform/transform_data.h
+++ b/source/blender/editors/transform/transform_data.h
@@ -88,8 +88,8 @@ typedef struct TransDataExtension {
* It is the same but without the #Bone.bone_mat, see #TD_PBONE_LOCAL_MTX_C. */
float l_smtx[3][3];
/** The rotscale matrix of pose bone, to allow using snap-align in translation mode,
- * when td->mtx is the loc pose bone matrix (and hence can't be used to apply
- * rotation in some cases, namely when a bone is in "NoLocal" or "Hinge" mode)... */
+ * when #TransData.mtx is the loc pose bone matrix (and hence can't be used to apply
+ * rotation in some cases, namely when a bone is in "No-Local" or "Hinge" mode)... */
float r_mtx[3][3];
/** Inverse of previous one. */
float r_smtx[3][3];
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 78c47014d62..cce6ef1f3bd 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -131,21 +131,6 @@ void resetTransRestrictions(TransInfo *t)
t->flag &= ~T_ALL_RESTRICTIONS;
}
-static int initTransInfo_edit_pet_to_flag(const int proportional)
-{
- int flag = 0;
- if (proportional & PROP_EDIT_USE) {
- flag |= T_PROP_EDIT;
- }
- if (proportional & PROP_EDIT_CONNECTED) {
- flag |= T_PROP_CONNECTED;
- }
- if (proportional & PROP_EDIT_PROJECTED) {
- flag |= T_PROP_PROJECTED;
- }
- return flag;
-}
-
void initTransDataContainers_FromObjectData(TransInfo *t,
Object *obact,
Object **objects,
@@ -390,15 +375,15 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
if (op && ((prop = RNA_struct_find_property(op->ptr, "correct_uv")))) {
if (RNA_property_is_set(op->ptr, prop)) {
if (RNA_property_boolean_get(op->ptr, prop)) {
- t->settings->uvcalc_flag |= UVCALC_TRANSFORM_CORRECT;
+ t->settings->uvcalc_flag |= UVCALC_TRANSFORM_CORRECT_SLIDE;
}
else {
- t->settings->uvcalc_flag &= ~UVCALC_TRANSFORM_CORRECT;
+ t->settings->uvcalc_flag &= ~UVCALC_TRANSFORM_CORRECT_SLIDE;
}
}
else {
RNA_property_boolean_set(
- op->ptr, prop, (t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) != 0);
+ op->ptr, prop, (t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT_SLIDE) != 0);
}
}
}
@@ -550,7 +535,8 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
orient_types[2] = orient_type_scene;
}
else {
- if ((t->flag & T_MODAL) && (use_orient_axis || transform_mode_is_changeable(t->mode))) {
+ if ((t->flag & T_MODAL) && (use_orient_axis || transform_mode_is_changeable(t->mode)) &&
+ (t->mode != TFM_ALIGN)) {
orient_types[0] = V3D_ORIENT_VIEW;
}
else {
@@ -636,45 +622,45 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
/* setting PET flag only if property exist in operator. Otherwise, assume it's not supported */
if (op && (prop = RNA_struct_find_property(op->ptr, "use_proportional_edit"))) {
if (RNA_property_is_set(op->ptr, prop)) {
- int proportional = 0;
if (RNA_property_boolean_get(op->ptr, prop)) {
- proportional |= PROP_EDIT_USE;
+ t->flag |= T_PROP_EDIT;
if (RNA_boolean_get(op->ptr, "use_proportional_connected")) {
- proportional |= PROP_EDIT_CONNECTED;
+ t->flag |= T_PROP_CONNECTED;
}
if (RNA_boolean_get(op->ptr, "use_proportional_projected")) {
- proportional |= PROP_EDIT_PROJECTED;
+ t->flag |= T_PROP_PROJECTED;
}
}
- t->flag |= initTransInfo_edit_pet_to_flag(proportional);
}
else {
/* use settings from scene only if modal */
if (t->flag & T_MODAL) {
if ((t->options & CTX_NO_PET) == 0) {
+ bool use_prop_edit = false;
if (t->spacetype == SPACE_GRAPH) {
- t->flag |= initTransInfo_edit_pet_to_flag(ts->proportional_fcurve);
+ use_prop_edit = ts->proportional_fcurve;
}
else if (t->spacetype == SPACE_ACTION) {
- t->flag |= initTransInfo_edit_pet_to_flag(ts->proportional_action);
+ use_prop_edit = ts->proportional_action;
}
- else if (t->obedit_type != -1) {
- t->flag |= initTransInfo_edit_pet_to_flag(ts->proportional_edit);
+ else if (t->options & CTX_MASK) {
+ use_prop_edit = ts->proportional_mask;
}
- else if (t->options & CTX_GPENCIL_STROKES) {
- t->flag |= initTransInfo_edit_pet_to_flag(ts->proportional_edit);
+ else if (obact && obact->mode == OB_MODE_OBJECT) {
+ use_prop_edit = ts->proportional_objects;
}
- else if (t->options & CTX_MASK) {
- if (ts->proportional_mask) {
- t->flag |= T_PROP_EDIT;
-
- if (ts->proportional_edit & PROP_EDIT_CONNECTED) {
- t->flag |= T_PROP_CONNECTED;
- }
- }
+ else {
+ use_prop_edit = (ts->proportional_edit & PROP_EDIT_USE) != 0;
}
- else if (!(t->options & CTX_CURSOR) && ts->proportional_objects) {
+
+ if (use_prop_edit) {
t->flag |= T_PROP_EDIT;
+ if (ts->proportional_edit & PROP_EDIT_CONNECTED) {
+ t->flag |= T_PROP_CONNECTED;
+ }
+ if (ts->proportional_edit & PROP_EDIT_PROJECTED) {
+ t->flag |= T_PROP_PROJECTED;
+ }
}
}
}
diff --git a/source/blender/editors/transform/transform_mode.c b/source/blender/editors/transform/transform_mode.c
index f028044809f..831ea90b4e4 100644
--- a/source/blender/editors/transform/transform_mode.c
+++ b/source/blender/editors/transform/transform_mode.c
@@ -50,6 +50,23 @@
/* Own include. */
#include "transform_mode.h"
+int transform_mode_really_used(bContext *C, int mode)
+{
+ if (mode == TFM_BONESIZE) {
+ Object *ob = CTX_data_active_object(C);
+ BLI_assert(ob);
+ if (ob->type != OB_ARMATURE) {
+ return TFM_RESIZE;
+ }
+ bArmature *arm = ob->data;
+ if (arm->drawtype == ARM_ENVELOPE) {
+ return TFM_BONE_ENVELOPE_DIST;
+ }
+ }
+
+ return mode;
+}
+
bool transdata_check_local_center(TransInfo *t, short around)
{
return ((around == V3D_AROUND_LOCAL_ORIGINS) &&
@@ -1174,25 +1191,12 @@ void transform_mode_init(TransInfo *t, wmOperator *op, const int mode)
case TFM_CREASE:
initCrease(t);
break;
- case TFM_BONESIZE: { /* used for both B-Bone width (bonesize) as for deform-dist (envelope) */
- /* Note: we have to pick one, use the active object. */
- TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_OK(t);
- bArmature *arm = tc->poseobj->data;
- if (arm->drawtype == ARM_ENVELOPE) {
- initBoneEnvelope(t);
- t->mode = TFM_BONE_ENVELOPE_DIST;
- }
- else {
- initBoneSize(t);
- }
+ case TFM_BONESIZE:
+ initBoneSize(t);
break;
- }
case TFM_BONE_ENVELOPE:
- initBoneEnvelope(t);
- break;
case TFM_BONE_ENVELOPE_DIST:
initBoneEnvelope(t);
- t->mode = TFM_BONE_ENVELOPE_DIST;
break;
case TFM_EDGE_SLIDE:
case TFM_VERT_SLIDE: {
@@ -1267,6 +1271,12 @@ void transform_mode_init(TransInfo *t, wmOperator *op, const int mode)
break;
}
+ if (t->data_type == TC_MESH_VERTS) {
+ /* Init Custom Data correction.
+ * Ideally this should be called when creating the TransData. */
+ trans_mesh_customdata_correction_init(t);
+ }
+
/* TODO(germano): Some of these operations change the `t->mode`.
* This can be bad for Redo.
* BLI_assert(t->mode == mode); */
diff --git a/source/blender/editors/transform/transform_mode.h b/source/blender/editors/transform/transform_mode.h
index 464deff983b..5cda8e3063a 100644
--- a/source/blender/editors/transform/transform_mode.h
+++ b/source/blender/editors/transform/transform_mode.h
@@ -26,6 +26,7 @@
#define __TRANSFORM_MODE_H__
struct AnimData;
+struct bContext;
struct LinkNode;
struct TransData;
struct TransDataContainer;
@@ -40,6 +41,7 @@ typedef struct TransDataGenericSlideVert {
} TransDataGenericSlideVert;
/* transform_mode.c */
+int transform_mode_really_used(struct bContext *C, int mode);
bool transdata_check_local_center(TransInfo *t, short around);
bool transform_mode_is_changeable(const int mode);
void protectedTransBits(short protectflag, float vec[3]);
@@ -95,7 +97,6 @@ void initSeqSlide(TransInfo *t);
/* transform_mode_edge_slide.c */
void drawEdgeSlide(TransInfo *t);
-void doEdgeSlide(TransInfo *t, float perc);
void initEdgeSlide_ex(
TransInfo *t, bool use_double_side, bool use_even, bool flipped, bool use_clamp);
void initEdgeSlide(TransInfo *t);
@@ -153,7 +154,6 @@ void initTranslation(TransInfo *t);
/* transform_mode_vert_slide.c */
void drawVertSlide(TransInfo *t);
-void doVertSlide(TransInfo *t, float perc);
void initVertSlide_ex(TransInfo *t, bool use_even, bool flipped, bool use_clamp);
void initVertSlide(TransInfo *t);
#endif
diff --git a/source/blender/editors/transform/transform_mode_bbone_resize.c b/source/blender/editors/transform/transform_mode_bbone_resize.c
index 77850e74785..2c2253630c0 100644
--- a/source/blender/editors/transform/transform_mode_bbone_resize.c
+++ b/source/blender/editors/transform/transform_mode_bbone_resize.c
@@ -132,6 +132,11 @@ static void applyBoneSize(TransInfo *t, const int UNUSED(mval[2]))
if (t->con.applySize) {
t->con.applySize(t, NULL, NULL, mat);
+ for (i = 0; i < 3; i++) {
+ if (!(t->con.mode & (CON_AXIS0 << i))) {
+ t->values_final[i] = 1.0f;
+ }
+ }
}
copy_m3_m3(t->mat, mat); // used in gizmo
diff --git a/source/blender/editors/transform/transform_mode_boneenvelope.c b/source/blender/editors/transform/transform_mode_boneenvelope.c
index 7045d190478..b7a34769f5a 100644
--- a/source/blender/editors/transform/transform_mode_boneenvelope.c
+++ b/source/blender/editors/transform/transform_mode_boneenvelope.c
@@ -96,7 +96,6 @@ static void applyBoneEnvelope(TransInfo *t, const int UNUSED(mval[2]))
void initBoneEnvelope(TransInfo *t)
{
- t->mode = TFM_BONE_ENVELOPE;
t->transform = applyBoneEnvelope;
initMouseInputMode(t, &t->mouse, INPUT_SPRING);
diff --git a/source/blender/editors/transform/transform_mode_edge_slide.c b/source/blender/editors/transform/transform_mode_edge_slide.c
index 42f75f041b9..ed22afc404e 100644
--- a/source/blender/editors/transform/transform_mode_edge_slide.c
+++ b/source/blender/editors/transform/transform_mode_edge_slide.c
@@ -50,6 +50,7 @@
#include "BLT_translation.h"
#include "transform.h"
+#include "transform_constraints.h"
#include "transform_convert.h"
#include "transform_mode.h"
#include "transform_snap.h"
@@ -96,24 +97,28 @@ typedef struct EdgeSlideParams {
} EdgeSlideParams;
/**
- * Get the first valid EdgeSlideData.
+ * Get the first valid TransDataContainer *.
*
* Note we cannot trust TRANS_DATA_CONTAINER_FIRST_OK because of multi-object that
* may leave items with invalid custom data in the transform data container.
*/
-static EdgeSlideData *edgeSlideFirstGet(TransInfo *t)
+static TransDataContainer *edge_slide_container_first_ok(TransInfo *t)
{
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- EdgeSlideData *sld = tc->custom.mode.data;
- if (sld == NULL) {
- continue;
+ if (tc->custom.mode.data) {
+ return tc;
}
- return sld;
}
BLI_assert(!"Should never happen, at least one EdgeSlideData should be valid");
return NULL;
}
+static EdgeSlideData *edgeSlideFirstGet(TransInfo *t)
+{
+ TransDataContainer *tc = edge_slide_container_first_ok(t);
+ return tc->custom.mode.data;
+}
+
static void calcEdgeSlideCustomPoints(struct TransInfo *t)
{
EdgeSlideData *sld = edgeSlideFirstGet(t);
@@ -1129,132 +1134,226 @@ static eRedrawFlag handleEventEdgeSlide(struct TransInfo *t, const struct wmEven
void drawEdgeSlide(TransInfo *t)
{
- if ((t->mode == TFM_EDGE_SLIDE) && edgeSlideFirstGet(t)) {
- const EdgeSlideParams *slp = t->custom.mode.data;
- EdgeSlideData *sld = edgeSlideFirstGet(t);
- const bool is_clamp = !(t->flag & T_ALT_TRANSFORM);
+ if (t->mode != TFM_EDGE_SLIDE) {
+ return;
+ }
- /* Even mode */
- if ((slp->use_even == true) || (is_clamp == false)) {
- const float line_size = UI_GetThemeValuef(TH_OUTLINE_WIDTH) + 0.5f;
+ EdgeSlideData *sld = edgeSlideFirstGet(t);
+ if (sld == NULL) {
+ return;
+ }
- GPU_depth_test(false);
+ const EdgeSlideParams *slp = t->custom.mode.data;
+ const bool is_clamp = !(t->flag & T_ALT_TRANSFORM);
- GPU_blend(true);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ const float line_size = UI_GetThemeValuef(TH_OUTLINE_WIDTH) + 0.5f;
- GPU_matrix_push();
- GPU_matrix_mul(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->obmat);
+ GPU_depth_test(false);
- uint pos = GPU_vertformat_attr_add(
- immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ GPU_blend(true);
+ GPU_blend_set_func_separate(
+ GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ GPU_matrix_push();
+ GPU_matrix_mul(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->obmat);
- if (slp->use_even == true) {
- float co_a[3], co_b[3], co_mark[3];
- TransDataEdgeSlideVert *curr_sv = &sld->sv[sld->curr_sv_index];
- const float fac = (slp->perc + 1.0f) / 2.0f;
- const float ctrl_size = UI_GetThemeValuef(TH_FACEDOT_SIZE) + 1.5f;
- const float guide_size = ctrl_size - 0.5f;
- const int alpha_shade = -30;
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
- add_v3_v3v3(co_a, curr_sv->v_co_orig, curr_sv->dir_side[0]);
- add_v3_v3v3(co_b, curr_sv->v_co_orig, curr_sv->dir_side[1]);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
- GPU_line_width(line_size);
- immUniformThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade);
- immBeginAtMost(GPU_PRIM_LINES, 4);
- if (curr_sv->v_side[0]) {
- immVertex3fv(pos, curr_sv->v_side[0]->co);
- immVertex3fv(pos, curr_sv->v_co_orig);
- }
+ if (slp->use_even == true) {
+ /* Even mode */
+ float co_a[3], co_b[3], co_mark[3];
+ TransDataEdgeSlideVert *curr_sv = &sld->sv[sld->curr_sv_index];
+ const float fac = (slp->perc + 1.0f) / 2.0f;
+ const float ctrl_size = UI_GetThemeValuef(TH_FACEDOT_SIZE) + 1.5f;
+ const float guide_size = ctrl_size - 0.5f;
+ const int alpha_shade = -30;
+
+ add_v3_v3v3(co_a, curr_sv->v_co_orig, curr_sv->dir_side[0]);
+ add_v3_v3v3(co_b, curr_sv->v_co_orig, curr_sv->dir_side[1]);
+
+ GPU_line_width(line_size);
+ immUniformThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade);
+ immBeginAtMost(GPU_PRIM_LINES, 4);
+ if (curr_sv->v_side[0]) {
+ immVertex3fv(pos, curr_sv->v_side[0]->co);
+ immVertex3fv(pos, curr_sv->v_co_orig);
+ }
+ if (curr_sv->v_side[1]) {
+ immVertex3fv(pos, curr_sv->v_side[1]->co);
+ immVertex3fv(pos, curr_sv->v_co_orig);
+ }
+ immEnd();
+
+ {
+ float *co_test = NULL;
+ if (slp->flipped) {
if (curr_sv->v_side[1]) {
- immVertex3fv(pos, curr_sv->v_side[1]->co);
- immVertex3fv(pos, curr_sv->v_co_orig);
+ co_test = curr_sv->v_side[1]->co;
}
- immEnd();
-
- {
- float *co_test = NULL;
- if (slp->flipped) {
- if (curr_sv->v_side[1]) {
- co_test = curr_sv->v_side[1]->co;
- }
- }
- else {
- if (curr_sv->v_side[0]) {
- co_test = curr_sv->v_side[0]->co;
- }
- }
-
- if (co_test != NULL) {
- immUniformThemeColorShadeAlpha(TH_SELECT, -30, alpha_shade);
- GPU_point_size(ctrl_size);
- immBegin(GPU_PRIM_POINTS, 1);
- immVertex3fv(pos, co_test);
- immEnd();
- }
+ }
+ else {
+ if (curr_sv->v_side[0]) {
+ co_test = curr_sv->v_side[0]->co;
}
+ }
- immUniformThemeColorShadeAlpha(TH_SELECT, 255, alpha_shade);
- GPU_point_size(guide_size);
+ if (co_test != NULL) {
+ immUniformThemeColorShadeAlpha(TH_SELECT, -30, alpha_shade);
+ GPU_point_size(ctrl_size);
immBegin(GPU_PRIM_POINTS, 1);
- interp_line_v3_v3v3v3(co_mark, co_b, curr_sv->v_co_orig, co_a, fac);
- immVertex3fv(pos, co_mark);
+ immVertex3fv(pos, co_test);
immEnd();
}
+ }
+
+ immUniformThemeColorShadeAlpha(TH_SELECT, 255, alpha_shade);
+ GPU_point_size(guide_size);
+ immBegin(GPU_PRIM_POINTS, 1);
+ interp_line_v3_v3v3v3(co_mark, co_b, curr_sv->v_co_orig, co_a, fac);
+ immVertex3fv(pos, co_mark);
+ immEnd();
+ }
+ else if (is_clamp == false) {
+ const int side_index = sld->curr_side_unclamp;
+ TransDataEdgeSlideVert *sv;
+ int i;
+ const int alpha_shade = -160;
+
+ GPU_line_width(line_size);
+ immUniformThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade);
+ immBegin(GPU_PRIM_LINES, sld->totsv * 2);
+
+ /* TODO(campbell): Loop over all verts */
+ sv = sld->sv;
+ for (i = 0; i < sld->totsv; i++, sv++) {
+ float a[3], b[3];
+
+ if (!is_zero_v3(sv->dir_side[side_index])) {
+ copy_v3_v3(a, sv->dir_side[side_index]);
+ }
else {
- if (is_clamp == false) {
- const int side_index = sld->curr_side_unclamp;
- TransDataEdgeSlideVert *sv;
- int i;
- const int alpha_shade = -160;
+ copy_v3_v3(a, sv->dir_side[!side_index]);
+ }
- GPU_line_width(line_size);
- immUniformThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade);
- immBegin(GPU_PRIM_LINES, sld->totsv * 2);
+ mul_v3_fl(a, 100.0f);
+ negate_v3_v3(b, a);
+ add_v3_v3(a, sv->v_co_orig);
+ add_v3_v3(b, sv->v_co_orig);
- /* TODO(campbell): Loop over all verts */
- sv = sld->sv;
- for (i = 0; i < sld->totsv; i++, sv++) {
- float a[3], b[3];
+ immVertex3fv(pos, a);
+ immVertex3fv(pos, b);
+ }
+ immEnd();
+ }
+ else {
+ /* Common case. */
+ TransDataEdgeSlideVert *curr_sv = &sld->sv[sld->curr_sv_index];
+ const int alpha_shade = -160;
+
+ float co_dir[3];
+ add_v3_v3v3(co_dir, curr_sv->v_co_orig, curr_sv->dir_side[sld->curr_side_unclamp]);
+
+ GPU_line_width(line_size);
+ immUniformThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade);
+ immBeginAtMost(GPU_PRIM_LINES, 2);
+ immVertex3fv(pos, curr_sv->v_co_orig);
+ immVertex3fv(pos, co_dir);
+ immEnd();
+ }
- if (!is_zero_v3(sv->dir_side[side_index])) {
- copy_v3_v3(a, sv->dir_side[side_index]);
- }
- else {
- copy_v3_v3(a, sv->dir_side[!side_index]);
- }
+ immUnbindProgram();
- mul_v3_fl(a, 100.0f);
- negate_v3_v3(b, a);
- add_v3_v3(a, sv->v_co_orig);
- add_v3_v3(b, sv->v_co_orig);
+ GPU_matrix_pop();
- immVertex3fv(pos, a);
- immVertex3fv(pos, b);
- }
- immEnd();
- }
- else {
- BLI_assert(0);
- }
- }
+ GPU_blend(false);
- immUnbindProgram();
+ GPU_depth_test(true);
+}
- GPU_matrix_pop();
+static void edge_slide_snap_apply(TransInfo *t, float *value)
+{
+ TransDataContainer *tc = edge_slide_container_first_ok(t);
+ EdgeSlideParams *slp = t->custom.mode.data;
+ EdgeSlideData *sld_active = tc->custom.mode.data;
+ TransDataEdgeSlideVert *sv = &sld_active->sv[sld_active->curr_sv_index];
+ float snap_point[3], co_orig[3], co_dest[2][3], dvec[3];
+
+ copy_v3_v3(co_orig, sv->v_co_orig);
+ add_v3_v3v3(co_dest[0], co_orig, sv->dir_side[0]);
+ add_v3_v3v3(co_dest[1], co_orig, sv->dir_side[1]);
+ if (tc->use_local_mat) {
+ mul_m4_v3(tc->mat, co_orig);
+ mul_m4_v3(tc->mat, co_dest[0]);
+ mul_m4_v3(tc->mat, co_dest[1]);
+ }
- GPU_blend(false);
+ getSnapPoint(t, dvec);
+ sub_v3_v3(dvec, t->tsnap.snapTarget);
+ add_v3_v3v3(snap_point, co_orig, dvec);
- GPU_depth_test(true);
+ float perc = *value;
+ int side_index;
+ float t_mid;
+ if (slp->use_even == false) {
+ const bool is_clamp = !(t->flag & T_ALT_TRANSFORM);
+ if (is_clamp) {
+ side_index = perc < 0.0f;
+ }
+ else {
+ side_index = sld_active->curr_side_unclamp;
}
}
+ else {
+ /* Could be pre-calculated. */
+ t_mid = line_point_factor_v3((float[3]){0.0f, 0.0f, 0.0f}, sv->dir_side[0], sv->dir_side[1]);
+
+ float t_snap = line_point_factor_v3(snap_point, co_dest[0], co_dest[1]);
+ side_index = t_snap >= t_mid;
+ }
+
+ if (t->tsnap.snapElem & (SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE)) {
+ float co_dir[3];
+ sub_v3_v3v3(co_dir, co_dest[side_index], co_orig);
+ if (t->tsnap.snapElem & SCE_SNAP_MODE_EDGE) {
+ transform_constraint_snap_axis_to_edge(t, co_dir, dvec);
+ }
+ else {
+ transform_constraint_snap_axis_to_face(t, co_dir, dvec);
+ }
+ add_v3_v3v3(snap_point, co_orig, dvec);
+ }
+
+ perc = line_point_factor_v3(snap_point, co_orig, co_dest[side_index]);
+ if (slp->use_even == false) {
+ if (side_index) {
+ perc *= -1;
+ }
+ }
+ else {
+ if (!side_index) {
+ perc = (1.0f - perc) * t_mid;
+ }
+ else {
+ perc = perc * (1.0f - t_mid) + t_mid;
+ }
+
+ if (slp->flipped) {
+ perc = 1.0f - perc;
+ }
+
+ perc = (2 * perc) - 1.0f;
+
+ if (!slp->flipped) {
+ perc *= -1;
+ }
+ }
+
+ *value = perc;
}
-void doEdgeSlide(TransInfo *t, float perc)
+static void doEdgeSlide(TransInfo *t, float perc)
{
EdgeSlideParams *slp = t->custom.mode.data;
EdgeSlideData *sld_active = edgeSlideFirstGet(t);
@@ -1365,6 +1464,7 @@ static void applyEdgeSlide(TransInfo *t, const int UNUSED(mval[2]))
final = t->values[0];
+ applySnapping(t, &final);
snapGridIncrement(t, &final);
/* only do this so out of range values are not displayed */
@@ -1413,6 +1513,8 @@ void initEdgeSlide_ex(
t->mode = TFM_EDGE_SLIDE;
t->transform = applyEdgeSlide;
t->handleEvent = handleEventEdgeSlide;
+ t->tsnap.applySnap = edge_slide_snap_apply;
+ t->tsnap.distance = transform_snap_distance_len_squared_fn;
{
EdgeSlideParams *slp = MEM_callocN(sizeof(*slp), __func__);
@@ -1432,16 +1534,13 @@ void initEdgeSlide_ex(
t->custom.mode.use_free = true;
}
- if (use_double_side) {
- FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- sld = use_double_side ? createEdgeSlideVerts_double_side(t, tc) :
- createEdgeSlideVerts_single_side(t, tc);
- if (sld) {
- tc->custom.mode.data = sld;
- tc->custom.mode.free_cb = freeEdgeSlideVerts;
- trans_mesh_customdata_correction_init(t, tc);
- ok = true;
- }
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+ sld = use_double_side ? createEdgeSlideVerts_double_side(t, tc) :
+ createEdgeSlideVerts_single_side(t, tc);
+ if (sld) {
+ tc->custom.mode.data = sld;
+ tc->custom.mode.free_cb = freeEdgeSlideVerts;
+ ok = true;
}
}
diff --git a/source/blender/editors/transform/transform_mode_resize.c b/source/blender/editors/transform/transform_mode_resize.c
index ebce32a598e..5fb46b30e0d 100644
--- a/source/blender/editors/transform/transform_mode_resize.c
+++ b/source/blender/editors/transform/transform_mode_resize.c
@@ -44,6 +44,39 @@
/** \name Transform Resize
* \{ */
+static float ResizeBetween(TransInfo *t, const float p1[3], const float p2[3])
+{
+ float d1[3], d2[3], len_d1;
+
+ sub_v3_v3v3(d1, p1, t->center_global);
+ sub_v3_v3v3(d2, p2, t->center_global);
+
+ if (t->con.applyRot != NULL && (t->con.mode & CON_APPLY)) {
+ mul_m3_v3(t->con.pmtx, d1);
+ mul_m3_v3(t->con.pmtx, d2);
+ }
+
+ project_v3_v3v3(d1, d1, d2);
+
+ len_d1 = len_v3(d1);
+
+ /* Use 'invalid' dist when `center == p1` (after projecting),
+ * in this case scale will _never_ move the point in relation to the center,
+ * so it makes no sense to take it into account when scaling. see: T46503 */
+ return len_d1 != 0.0f ? len_v3(d2) / len_d1 : TRANSFORM_DIST_INVALID;
+}
+
+static void ApplySnapResize(TransInfo *t, float vec[3])
+{
+ float point[3];
+ getSnapPoint(t, point);
+
+ float dist = ResizeBetween(t, t->tsnap.snapTarget, point);
+ if (dist != TRANSFORM_DIST_INVALID) {
+ copy_v3_fl(vec, dist);
+ }
+}
+
static void applyResize(TransInfo *t, const int UNUSED(mval[2]))
{
float mat[3][3];
@@ -134,6 +167,8 @@ void initResize(TransInfo *t)
{
t->mode = TFM_RESIZE;
t->transform = applyResize;
+ t->tsnap.applySnap = ApplySnapResize;
+ t->tsnap.distance = ResizeBetween;
initMouseInputMode(t, &t->mouse, INPUT_SPRING_FLIP);
diff --git a/source/blender/editors/transform/transform_mode_rotate.c b/source/blender/editors/transform/transform_mode_rotate.c
index 6480cb6c30e..4fa5dffc473 100644
--- a/source/blender/editors/transform/transform_mode_rotate.c
+++ b/source/blender/editors/transform/transform_mode_rotate.c
@@ -42,6 +42,67 @@
/** \name Transform Rotation
* \{ */
+static float RotationBetween(TransInfo *t, const float p1[3], const float p2[3])
+{
+ float angle, start[3], end[3];
+
+ sub_v3_v3v3(start, p1, t->center_global);
+ sub_v3_v3v3(end, p2, t->center_global);
+
+ // Angle around a constraint axis (error prone, will need debug)
+ if (t->con.applyRot != NULL && (t->con.mode & CON_APPLY)) {
+ float axis[3], tmp[3];
+
+ t->con.applyRot(t, NULL, NULL, axis, NULL);
+
+ project_v3_v3v3(tmp, end, axis);
+ sub_v3_v3v3(end, end, tmp);
+
+ project_v3_v3v3(tmp, start, axis);
+ sub_v3_v3v3(start, start, tmp);
+
+ normalize_v3(end);
+ normalize_v3(start);
+
+ cross_v3_v3v3(tmp, start, end);
+
+ if (dot_v3v3(tmp, axis) < 0.0f) {
+ angle = -acosf(dot_v3v3(start, end));
+ }
+ else {
+ angle = acosf(dot_v3v3(start, end));
+ }
+ }
+ else {
+ float mtx[3][3];
+
+ copy_m3_m4(mtx, t->viewmat);
+
+ mul_m3_v3(mtx, end);
+ mul_m3_v3(mtx, start);
+
+ angle = atan2f(start[1], start[0]) - atan2f(end[1], end[0]);
+ }
+
+ if (angle > (float)M_PI) {
+ angle = angle - 2 * (float)M_PI;
+ }
+ else if (angle < -((float)M_PI)) {
+ angle = 2.0f * (float)M_PI + angle;
+ }
+
+ return angle;
+}
+
+static void ApplySnapRotation(TransInfo *t, float *value)
+{
+ float point[3];
+ getSnapPoint(t, point);
+
+ float dist = RotationBetween(t, t->tsnap.snapTarget, point);
+ *value = dist;
+}
+
static float large_rotation_limit(float angle)
{
/* Limit rotation to 1001 turns max
@@ -173,6 +234,8 @@ void initRotation(TransInfo *t)
{
t->mode = TFM_ROTATION;
t->transform = applyRotation;
+ t->tsnap.applySnap = ApplySnapRotation;
+ t->tsnap.distance = RotationBetween;
setInputPostFct(&t->mouse, postInputRotation);
initMouseInputMode(t, &t->mouse, INPUT_ANGLE);
diff --git a/source/blender/editors/transform/transform_mode_translate.c b/source/blender/editors/transform/transform_mode_translate.c
index 60caa257a40..aee05197f10 100644
--- a/source/blender/editors/transform/transform_mode_translate.c
+++ b/source/blender/editors/transform/transform_mode_translate.c
@@ -34,6 +34,7 @@
#include "BKE_report.h"
#include "BKE_unit.h"
+#include "ED_node.h"
#include "ED_screen.h"
#include "WM_api.h"
@@ -214,6 +215,34 @@ static void headerTranslation(TransInfo *t, const float vec[3], char str[UI_MAX_
}
}
+static void ApplySnapTranslation(TransInfo *t, float vec[3])
+{
+ float point[3];
+ getSnapPoint(t, point);
+
+ if (t->spacetype == SPACE_NODE) {
+ char border = t->tsnap.snapNodeBorder;
+ if (border & (NODE_LEFT | NODE_RIGHT)) {
+ vec[0] = point[0] - t->tsnap.snapTarget[0];
+ }
+ if (border & (NODE_BOTTOM | NODE_TOP)) {
+ vec[1] = point[1] - t->tsnap.snapTarget[1];
+ }
+ }
+ else {
+ if (t->spacetype == SPACE_VIEW3D) {
+ if (t->options & CTX_PAINT_CURVE) {
+ if (ED_view3d_project_float_global(t->region, point, point, V3D_PROJ_TEST_NOP) !=
+ V3D_PROJ_RET_OK) {
+ zero_v3(point); /* no good answer here... */
+ }
+ }
+ }
+
+ sub_v3_v3v3(vec, point, t->tsnap.snapTarget);
+ }
+}
+
static void applyTranslationValue(TransInfo *t, const float vec[3])
{
const bool apply_snap_align_rotation = usingSnappingNormal(
@@ -376,6 +405,8 @@ void initTranslation(TransInfo *t)
}
t->transform = applyTranslation;
+ t->tsnap.applySnap = ApplySnapTranslation;
+ t->tsnap.distance = transform_snap_distance_len_squared_fn;
initMouseInputMode(t, &t->mouse, INPUT_VECTOR);
diff --git a/source/blender/editors/transform/transform_mode_vert_slide.c b/source/blender/editors/transform/transform_mode_vert_slide.c
index 62415b1ddc6..4b75c362da9 100644
--- a/source/blender/editors/transform/transform_mode_vert_slide.c
+++ b/source/blender/editors/transform/transform_mode_vert_slide.c
@@ -47,6 +47,7 @@
#include "BLT_translation.h"
#include "transform.h"
+#include "transform_constraints.h"
#include "transform_convert.h"
#include "transform_mode.h"
#include "transform_snap.h"
@@ -491,7 +492,7 @@ void drawVertSlide(TransInfo *t)
}
}
-void doVertSlide(TransInfo *t, float perc)
+static void doVertSlide(TransInfo *t, float perc)
{
VertSlideParams *slp = t->custom.mode.data;
@@ -538,6 +539,37 @@ void doVertSlide(TransInfo *t, float perc)
}
}
+static void vert_slide_snap_apply(TransInfo *t, float *value)
+{
+ TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_OK(t);
+ VertSlideData *sld = tc->custom.mode.data;
+ TransDataVertSlideVert *sv = &sld->sv[sld->curr_sv_index];
+
+ float snap_point[3], co_orig_3d[3], co_curr_3d[3], dvec[3];
+ copy_v3_v3(co_orig_3d, sv->co_orig_3d);
+ copy_v3_v3(co_curr_3d, sv->co_link_orig_3d[sv->co_link_curr]);
+ if (tc->use_local_mat) {
+ mul_m4_v3(tc->mat, co_orig_3d);
+ mul_m4_v3(tc->mat, co_curr_3d);
+ }
+
+ getSnapPoint(t, dvec);
+ sub_v3_v3(dvec, t->tsnap.snapTarget);
+ if (t->tsnap.snapElem & (SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE)) {
+ float co_dir_3d[3];
+ sub_v3_v3v3(co_dir_3d, co_curr_3d, co_orig_3d);
+ if (t->tsnap.snapElem & SCE_SNAP_MODE_EDGE) {
+ transform_constraint_snap_axis_to_edge(t, co_dir_3d, dvec);
+ }
+ else {
+ transform_constraint_snap_axis_to_face(t, co_dir_3d, dvec);
+ }
+ }
+
+ add_v3_v3v3(snap_point, co_orig_3d, dvec);
+ *value = line_point_factor_v3(snap_point, co_orig_3d, co_curr_3d);
+}
+
static void applyVertSlide(TransInfo *t, const int UNUSED(mval[2]))
{
char str[UI_MAX_DRAW_STR];
@@ -551,6 +583,7 @@ static void applyVertSlide(TransInfo *t, const int UNUSED(mval[2]))
final = t->values[0];
+ applySnapping(t, &final);
snapGridIncrement(t, &final);
/* only do this so out of range values are not displayed */
@@ -596,6 +629,8 @@ void initVertSlide_ex(TransInfo *t, bool use_even, bool flipped, bool use_clamp)
t->mode = TFM_VERT_SLIDE;
t->transform = applyVertSlide;
t->handleEvent = handleEventVertSlide;
+ t->tsnap.applySnap = vert_slide_snap_apply;
+ t->tsnap.distance = transform_snap_distance_len_squared_fn;
{
VertSlideParams *slp = MEM_callocN(sizeof(*slp), __func__);
@@ -617,7 +652,6 @@ void initVertSlide_ex(TransInfo *t, bool use_even, bool flipped, bool use_clamp)
if (sld) {
tc->custom.mode.data = sld;
tc->custom.mode.free_cb = freeVertSlideVerts;
- trans_mesh_customdata_correction_init(t, tc);
ok = true;
}
}
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index 95249f4d17b..f86bcc41bee 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -1049,11 +1049,11 @@ static void TRANSFORM_OT_bbone_resize(struct wmOperatorType *ot)
ot->exec = transform_exec;
ot->modal = transform_modal;
ot->cancel = transform_cancel;
- ot->poll = ED_operator_editarmature;
+ ot->poll = ED_operator_object_active;
ot->poll_property = transform_poll_property;
RNA_def_float_translation(
- ot->srna, "value", 2, VecOne, -FLT_MAX, FLT_MAX, "Display Size", "", -FLT_MAX, FLT_MAX);
+ ot->srna, "value", 3, VecOne, -FLT_MAX, FLT_MAX, "Display Size", "", -FLT_MAX, FLT_MAX);
WM_operatortype_props_advanced_begin(ot);
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index b508507cd4e..2943c3cb8ea 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -22,23 +22,13 @@
*/
#include <float.h>
-#include <math.h>
-#include <stdio.h>
-#include <stdlib.h>
#include "PIL_time.h"
-#include "DNA_node_types.h"
-#include "DNA_object_types.h"
-#include "DNA_scene_types.h"
-#include "DNA_screen_types.h"
-#include "DNA_space_types.h"
-#include "DNA_view3d_types.h"
#include "DNA_windowmanager_types.h"
#include "BLI_blenlib.h"
#include "BLI_math.h"
-#include "BLI_utildefines.h"
#include "GPU_immediate.h"
#include "GPU_state.h"
@@ -58,7 +48,6 @@
#include "ED_node.h"
#include "ED_transform_snap_object_context.h"
#include "ED_uvedit.h"
-#include "ED_view3d.h"
#include "UI_resources.h"
#include "UI_view2d.h"
@@ -80,10 +69,6 @@
static void setSnappingCallback(TransInfo *t);
-static void ApplySnapTranslation(TransInfo *t, float vec[3]);
-static void ApplySnapRotation(TransInfo *t, float *vec);
-static void ApplySnapResize(TransInfo *t, float vec[2]);
-
/* static void CalcSnapGrid(TransInfo *t, float *vec); */
static void CalcSnapGeometry(TransInfo *t, float *vec);
@@ -92,10 +77,6 @@ static void TargetSnapCenter(TransInfo *t);
static void TargetSnapClosest(TransInfo *t);
static void TargetSnapActive(TransInfo *t);
-static float RotationBetween(TransInfo *t, const float p1[3], const float p2[3]);
-static float TranslationBetween(TransInfo *t, const float p1[3], const float p2[3]);
-static float ResizeBetween(TransInfo *t, const float p1[3], const float p2[3]);
-
/** \} */
/* -------------------------------------------------------------------- */
@@ -143,6 +124,12 @@ bool transformModeUseSnap(const TransInfo *t)
if (t->mode == TFM_RESIZE) {
return (ts->snap_transform_mode_flag & SCE_SNAP_TRANSFORM_MODE_SCALE) != 0;
}
+ if (t->mode == TFM_VERT_SLIDE) {
+ return true;
+ }
+ if (t->mode == TFM_EDGE_SLIDE) {
+ return true;
+ }
return false;
}
@@ -476,7 +463,6 @@ void resetSnapping(TransInfo *t)
t->tsnap.modeSelect = 0;
t->tsnap.target = 0;
t->tsnap.last = 0;
- t->tsnap.applySnap = NULL;
t->tsnap.snapNormal[0] = 0;
t->tsnap.snapNormal[1] = 0;
@@ -557,35 +543,32 @@ static void initSnappingMode(TransInfo *t)
t->tsnap.mode = ts->snap_mode;
}
- if ((t->spacetype == SPACE_VIEW3D || t->spacetype == SPACE_IMAGE) && /* Only 3D view or UV */
- (t->flag & T_CAMERA) == 0) /* Not with camera selected in camera view */
- {
+ if ((t->spacetype == SPACE_VIEW3D || t->spacetype == SPACE_IMAGE) && (t->flag & T_CAMERA) == 0) {
+ /* Only 3D view or UV. */
+ /* Not with camera selected in camera view. */
+
setSnappingCallback(t);
- /* Edit mode */
- if (t->tsnap.applySnap != NULL && // A snapping function actually exist
- ((obedit_type != -1) &&
- /* Temporary limited to edit mode meshes, armature, curves, metaballs. */
- ELEM(obedit_type, OB_MESH, OB_ARMATURE, OB_CURVE, OB_LATTICE, OB_MBALL))) {
- /* Exclude editmesh if using proportional edit */
+ if ((obedit_type != -1) &&
+ ELEM(obedit_type, OB_MESH, OB_ARMATURE, OB_CURVE, OB_LATTICE, OB_MBALL)) {
+ /* Edit mode */
+ /* Temporary limited to edit mode meshes, armature, curves, metaballs. */
+
if ((obedit_type == OB_MESH) && (t->flag & T_PROP_EDIT)) {
+ /* Exclude editmesh if using proportional edit */
t->tsnap.modeSelect = SNAP_NOT_ACTIVE;
}
else {
t->tsnap.modeSelect = t->tsnap.snap_self ? SNAP_ALL : SNAP_NOT_ACTIVE;
}
}
- /* Particles edit mode*/
- else if (t->tsnap.applySnap != NULL && // A snapping function actually exist
- ((obedit_type == -1) && base_act && base_act->object &&
- base_act->object->mode & OB_MODE_PARTICLE_EDIT)) {
+ else if ((obedit_type == -1) && base_act && base_act->object &&
+ (base_act->object->mode & OB_MODE_PARTICLE_EDIT)) {
+ /* Particles edit mode. */
t->tsnap.modeSelect = SNAP_ALL;
}
- /* Object mode */
- else if (t->tsnap.applySnap != NULL && // A snapping function actually exist
- (obedit_type == -1)) // Object Mode
- {
-
+ else if (obedit_type == -1) {
+ /* Object mode */
if (t->options & (CTX_GPENCIL_STROKES | CTX_CURSOR | CTX_OBMODE_XFORM_OBDATA)) {
/* In "Edit Strokes" mode,
* snap tool can perform snap to selected or active objects (see T49632)
@@ -605,14 +588,7 @@ static void initSnappingMode(TransInfo *t)
}
else if (t->spacetype == SPACE_NODE) {
setSnappingCallback(t);
-
- if (t->tsnap.applySnap != NULL) {
- t->tsnap.modeSelect = SNAP_NOT_SELECTED;
- }
- else {
- /* Grid if snap is not possible */
- t->tsnap.mode = SCE_SNAP_MODE_INCREMENT;
- }
+ t->tsnap.modeSelect = SNAP_NOT_SELECTED;
}
else if (t->spacetype == SPACE_SEQ) {
/* We do our own snapping currently, so nothing here */
@@ -720,8 +696,13 @@ static void setSnappingCallback(TransInfo *t)
t->tsnap.targetSnap = TargetSnapClosest;
break;
case SCE_SNAP_TARGET_CENTER:
- t->tsnap.targetSnap = TargetSnapCenter;
- break;
+ if (!ELEM(t->mode, TFM_ROTATION, TFM_RESIZE)) {
+ t->tsnap.targetSnap = TargetSnapCenter;
+ break;
+ }
+ /* Can't do TARGET_CENTER with these modes,
+ * use TARGET_MEDIAN instead. */
+ ATTR_FALLTHROUGH;
case SCE_SNAP_TARGET_MEDIAN:
t->tsnap.targetSnap = TargetSnapMedian;
break;
@@ -729,36 +710,6 @@ static void setSnappingCallback(TransInfo *t)
t->tsnap.targetSnap = TargetSnapActive;
break;
}
-
- switch (t->mode) {
- case TFM_TRANSLATION:
- t->tsnap.applySnap = ApplySnapTranslation;
- t->tsnap.distance = TranslationBetween;
- break;
- case TFM_ROTATION:
- t->tsnap.applySnap = ApplySnapRotation;
- t->tsnap.distance = RotationBetween;
-
- // Can't do TARGET_CENTER with rotation, use TARGET_MEDIAN instead
- if (t->tsnap.target == SCE_SNAP_TARGET_CENTER) {
- t->tsnap.target = SCE_SNAP_TARGET_MEDIAN;
- t->tsnap.targetSnap = TargetSnapMedian;
- }
- break;
- case TFM_RESIZE:
- t->tsnap.applySnap = ApplySnapResize;
- t->tsnap.distance = ResizeBetween;
-
- // Can't do TARGET_CENTER with resize, use TARGET_MEDIAN instead
- if (t->tsnap.target == SCE_SNAP_TARGET_CENTER) {
- t->tsnap.target = SCE_SNAP_TARGET_MEDIAN;
- t->tsnap.targetSnap = TargetSnapMedian;
- }
- break;
- default:
- t->tsnap.applySnap = NULL;
- break;
- }
}
void addSnapPoint(TransInfo *t)
@@ -859,145 +810,6 @@ void getSnapPoint(const TransInfo *t, float vec[3])
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Apply Snap
- * \{ */
-
-static void ApplySnapTranslation(TransInfo *t, float vec[3])
-{
- float point[3];
- getSnapPoint(t, point);
-
- if (t->spacetype == SPACE_NODE) {
- char border = t->tsnap.snapNodeBorder;
- if (border & (NODE_LEFT | NODE_RIGHT)) {
- vec[0] = point[0] - t->tsnap.snapTarget[0];
- }
- if (border & (NODE_BOTTOM | NODE_TOP)) {
- vec[1] = point[1] - t->tsnap.snapTarget[1];
- }
- }
- else {
- if (t->spacetype == SPACE_VIEW3D) {
- if (t->options & CTX_PAINT_CURVE) {
- if (ED_view3d_project_float_global(t->region, point, point, V3D_PROJ_TEST_NOP) !=
- V3D_PROJ_RET_OK) {
- zero_v3(point); /* no good answer here... */
- }
- }
- }
-
- sub_v3_v3v3(vec, point, t->tsnap.snapTarget);
- }
-}
-
-static void ApplySnapRotation(TransInfo *t, float *value)
-{
- float point[3];
- getSnapPoint(t, point);
-
- float dist = RotationBetween(t, t->tsnap.snapTarget, point);
- *value = dist;
-}
-
-static void ApplySnapResize(TransInfo *t, float vec[3])
-{
- float point[3];
- getSnapPoint(t, point);
-
- float dist = ResizeBetween(t, t->tsnap.snapTarget, point);
- if (dist != TRANSFORM_DIST_INVALID) {
- copy_v3_fl(vec, dist);
- }
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Distance
- * \{ */
-
-static float TranslationBetween(TransInfo *UNUSED(t), const float p1[3], const float p2[3])
-{
- return len_squared_v3v3(p1, p2);
-}
-
-static float RotationBetween(TransInfo *t, const float p1[3], const float p2[3])
-{
- float angle, start[3], end[3];
-
- sub_v3_v3v3(start, p1, t->center_global);
- sub_v3_v3v3(end, p2, t->center_global);
-
- // Angle around a constraint axis (error prone, will need debug)
- if (t->con.applyRot != NULL && (t->con.mode & CON_APPLY)) {
- float axis[3], tmp[3];
-
- t->con.applyRot(t, NULL, NULL, axis, NULL);
-
- project_v3_v3v3(tmp, end, axis);
- sub_v3_v3v3(end, end, tmp);
-
- project_v3_v3v3(tmp, start, axis);
- sub_v3_v3v3(start, start, tmp);
-
- normalize_v3(end);
- normalize_v3(start);
-
- cross_v3_v3v3(tmp, start, end);
-
- if (dot_v3v3(tmp, axis) < 0.0f) {
- angle = -acosf(dot_v3v3(start, end));
- }
- else {
- angle = acosf(dot_v3v3(start, end));
- }
- }
- else {
- float mtx[3][3];
-
- copy_m3_m4(mtx, t->viewmat);
-
- mul_m3_v3(mtx, end);
- mul_m3_v3(mtx, start);
-
- angle = atan2f(start[1], start[0]) - atan2f(end[1], end[0]);
- }
-
- if (angle > (float)M_PI) {
- angle = angle - 2 * (float)M_PI;
- }
- else if (angle < -((float)M_PI)) {
- angle = 2.0f * (float)M_PI + angle;
- }
-
- return angle;
-}
-
-static float ResizeBetween(TransInfo *t, const float p1[3], const float p2[3])
-{
- float d1[3], d2[3], len_d1;
-
- sub_v3_v3v3(d1, p1, t->center_global);
- sub_v3_v3v3(d2, p2, t->center_global);
-
- if (t->con.applyRot != NULL && (t->con.mode & CON_APPLY)) {
- mul_m3_v3(t->con.pmtx, d1);
- mul_m3_v3(t->con.pmtx, d2);
- }
-
- project_v3_v3v3(d1, d1, d2);
-
- len_d1 = len_v3(d1);
-
- /* Use 'invalid' dist when `center == p1` (after projecting),
- * in this case scale will _never_ move the point in relation to the center,
- * so it makes no sense to take it into account when scaling. see: T46503 */
- return len_d1 != 0.0f ? len_v3(d2) / len_d1 : TRANSFORM_DIST_INVALID;
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
/** \name Calc Snap (Generic)
* \{ */
@@ -1734,3 +1546,16 @@ static void applyGridIncrement(
}
/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Generic callbacks
+ * \{ */
+
+float transform_snap_distance_len_squared_fn(TransInfo *UNUSED(t),
+ const float p1[3],
+ const float p2[3])
+{
+ return len_squared_v3v3(p1, p2);
+}
+
+/** \} */
diff --git a/source/blender/editors/transform/transform_snap.h b/source/blender/editors/transform/transform_snap.h
index c088cf80f0d..688661bc2cb 100644
--- a/source/blender/editors/transform/transform_snap.h
+++ b/source/blender/editors/transform/transform_snap.h
@@ -87,4 +87,6 @@ void addSnapPoint(TransInfo *t);
eRedrawFlag updateSelectedSnapPoint(TransInfo *t);
void removeSnapPoint(TransInfo *t);
+float transform_snap_distance_len_squared_fn(TransInfo *t, const float p1[3], const float p2[3]);
+
#endif /* __TRANSFORM_SNAP_H__ */
diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c
index 08ef5109a74..4198b4c02a3 100644
--- a/source/blender/editors/transform/transform_snap_object.c
+++ b/source/blender/editors/transform/transform_snap_object.c
@@ -367,17 +367,15 @@ static SnapObjectData *snap_object_data_editmesh_get(SnapObjectContext *sctx,
* \{ */
typedef void (*IterSnapObjsCallback)(SnapObjectContext *sctx,
- bool use_obedit,
- bool use_backface_culling,
Object *ob,
float obmat[4][4],
+ bool use_obedit,
+ bool use_backface_culling,
+ bool is_object_active,
void *data);
/**
* Walks through all objects in the scene to create the list of objects to snap.
- *
- * \param sctx: Snap context to store data.
- * \param snap_select: from enum #eSnapSelect.
*/
static void iter_snap_objects(SnapObjectContext *sctx,
Depsgraph *depsgraph,
@@ -393,7 +391,6 @@ static void iter_snap_objects(SnapObjectContext *sctx,
Base *base_act = view_layer->basact;
for (Base *base = view_layer->object_bases.first; base != NULL; base = base->next) {
-
if (!BASE_VISIBLE(v3d, base)) {
continue;
}
@@ -405,13 +402,14 @@ static void iter_snap_objects(SnapObjectContext *sctx,
continue;
}
+ const bool is_object_active = (base == base_act);
if (snap_select == SNAP_NOT_SELECTED) {
if ((base->flag & BASE_SELECTED) || (base->flag_legacy & BA_WAS_SEL)) {
continue;
}
}
else if (snap_select == SNAP_NOT_ACTIVE) {
- if (base == base_act) {
+ if (is_object_active) {
continue;
}
}
@@ -421,14 +419,24 @@ static void iter_snap_objects(SnapObjectContext *sctx,
DupliObject *dupli_ob;
ListBase *lb = object_duplilist(depsgraph, sctx->scene, obj_eval);
for (dupli_ob = lb->first; dupli_ob; dupli_ob = dupli_ob->next) {
- sob_callback(
- sctx, use_object_edit_cage, use_backface_culling, dupli_ob->ob, dupli_ob->mat, data);
+ sob_callback(sctx,
+ dupli_ob->ob,
+ dupli_ob->mat,
+ use_object_edit_cage,
+ use_backface_culling,
+ is_object_active,
+ data);
}
free_object_duplilist(lb);
}
- sob_callback(
- sctx, use_object_edit_cage, use_backface_culling, obj_eval, obj_eval->obmat, data);
+ sob_callback(sctx,
+ obj_eval,
+ obj_eval->obmat,
+ use_object_edit_cage,
+ use_backface_culling,
+ is_object_active,
+ data);
}
}
@@ -956,10 +964,11 @@ struct RaycastObjUserData {
* \note Duplicate args here are documented at #snapObjectsRay
*/
static void raycast_obj_fn(SnapObjectContext *sctx,
- bool use_obedit,
- bool use_backface_culling,
Object *ob,
float obmat[4][4],
+ bool use_obedit,
+ bool use_backface_culling,
+ bool is_object_active,
void *data)
{
struct RaycastObjUserData *dt = data;
@@ -1032,24 +1041,26 @@ static void raycast_obj_fn(SnapObjectContext *sctx,
case OB_CURVE:
case OB_SURF:
case OB_FONT: {
- Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
- if (mesh_eval) {
- retval = raycastMesh(sctx,
- dt->ray_start,
- dt->ray_dir,
- ob,
- mesh_eval,
- obmat,
- ob_index,
- false,
- use_backface_culling,
- ray_depth,
- dt->r_loc,
- dt->r_no,
- dt->r_index,
- dt->r_hit_list);
- break;
+ if (!is_object_active) {
+ Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
+ if (mesh_eval) {
+ retval = raycastMesh(sctx,
+ dt->ray_start,
+ dt->ray_dir,
+ ob,
+ mesh_eval,
+ obmat,
+ ob_index,
+ false,
+ use_backface_culling,
+ ray_depth,
+ dt->r_loc,
+ dt->r_no,
+ dt->r_index,
+ dt->r_hit_list);
+ }
}
+ break;
}
}
@@ -1071,9 +1082,7 @@ static void raycast_obj_fn(SnapObjectContext *sctx,
* Walks through all objects in the scene to find the `hit` on object surface.
*
* \param sctx: Snap context to store data.
- * \param snap_select: from enum eSnapSelect.
- * \param use_object_edit_cage: Uses the coordinates of BMesh(if any) to do the snapping.
- * \param obj_list: List with objects to snap (created in `create_object_list`).
+ * \param params: Snapping behavior.
*
* Read/Write Args
* ---------------
@@ -2054,15 +2063,15 @@ static short snapCurve(SnapData *snapdata,
}
/* may extend later (for now just snaps to empty center) */
-static short snapEmpty(SnapData *snapdata,
- Object *ob,
- const float obmat[4][4],
- /* read/write args */
- float *dist_px,
- /* return args */
- float r_loc[3],
- float *UNUSED(r_no),
- int *r_index)
+static short snap_object_center(SnapData *snapdata,
+ Object *ob,
+ const float obmat[4][4],
+ /* read/write args */
+ float *dist_px,
+ /* return args */
+ float r_loc[3],
+ float *UNUSED(r_no),
+ int *r_index)
{
short retval = 0;
@@ -2117,7 +2126,7 @@ static short snapCamera(const SnapObjectContext *sctx,
float *dist_px,
/* return args */
float r_loc[3],
- float *UNUSED(r_no),
+ float *r_no,
int *r_index)
{
short retval = 0;
@@ -2132,7 +2141,7 @@ static short snapCamera(const SnapObjectContext *sctx,
MovieTracking *tracking;
if (clip == NULL) {
- return retval;
+ return snap_object_center(snapdata, object, obmat, dist_px, r_loc, r_no, r_index);
}
if (object->transflag & OB_DUPLI) {
return retval;
@@ -2650,11 +2659,12 @@ struct SnapObjUserData {
*
* \note Duplicate args here are documented at #snapObjectsRay
*/
-static void sanp_obj_fn(SnapObjectContext *sctx,
- bool use_obedit,
- bool use_backface_culling,
+static void snap_obj_fn(SnapObjectContext *sctx,
Object *ob,
float obmat[4][4],
+ bool use_obedit,
+ bool use_backface_culling,
+ bool UNUSED(is_object_active),
void *data)
{
struct SnapObjUserData *dt = data;
@@ -2729,10 +2739,10 @@ static void sanp_obj_fn(SnapObjectContext *sctx,
break;
}
case OB_EMPTY:
- retval = snapEmpty(dt->snapdata, ob, obmat, dt->dist_px, dt->r_loc, dt->r_no, dt->r_index);
- break;
case OB_GPENCIL:
- retval = snapEmpty(dt->snapdata, ob, obmat, dt->dist_px, dt->r_loc, dt->r_no, dt->r_index);
+ case OB_LAMP:
+ retval = snap_object_center(
+ dt->snapdata, ob, obmat, dt->dist_px, dt->r_loc, dt->r_no, dt->r_index);
break;
case OB_CAMERA:
retval = snapCamera(
@@ -2800,7 +2810,7 @@ static short snapObjectsRay(SnapObjectContext *sctx,
.ret = 0,
};
- iter_snap_objects(sctx, depsgraph, params, sanp_obj_fn, &data);
+ iter_snap_objects(sctx, depsgraph, params, snap_obj_fn, &data);
return data.ret;
}
@@ -3205,7 +3215,7 @@ short ED_transform_snap_object_project_view3d_ex(SnapObjectContext *sctx,
* \param mval: Screenspace coordinate.
* \param prev_co: Coordinate for perpendicular point calculation (optional).
* \param dist_px: Maximum distance to snap (in pixels).
- * \param r_co: hit location.
+ * \param r_loc: hit location.
* \param r_no: hit normal (optional).
* \return Snap success
*/
diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c
index 897e2f13774..df6e4f70e99 100644
--- a/source/blender/editors/uvedit/uvedit_draw.c
+++ b/source/blender/editors/uvedit/uvedit_draw.c
@@ -409,70 +409,49 @@ static void draw_uvs(SpaceImage *sima,
GPU_blend(true);
}
- switch (sima->dt_uv) {
- case SI_UVDT_DASH: {
- float dash_colors[2][4] = {
- {0.56f, 0.56f, 0.56f, overlay_alpha},
- {0.07f, 0.07f, 0.07f, overlay_alpha},
- };
- float viewport_size[4];
- GPU_viewport_size_get_f(viewport_size);
-
- GPU_line_width(1.0f);
- GPU_batch_program_set_builtin(batch->edges, GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
- GPU_batch_uniform_4fv_array(batch->edges, "colors", 2, (float *)dash_colors);
- GPU_batch_uniform_2f(batch->edges,
- "viewport_size",
- viewport_size[2] / UI_DPI_FAC,
- viewport_size[3] / UI_DPI_FAC);
- GPU_batch_uniform_1i(batch->edges, "colors_len", 2); /* "advanced" mode */
- GPU_batch_uniform_1f(batch->edges, "dash_width", 4.0f);
- GPU_batch_uniform_1f(batch->edges, "dash_factor", 0.5f);
- GPU_batch_draw(batch->edges);
- break;
- }
- case SI_UVDT_BLACK:
- case SI_UVDT_WHITE:
- case SI_UVDT_OUTLINE: {
- /* We could modify the vbo's data filling
- * instead of modifying the provoking vert. */
- glProvokingVertex(GL_FIRST_VERTEX_CONVENTION);
-
- UI_GetThemeColor3fv(TH_EDGE_SELECT, col2);
- col2[3] = overlay_alpha;
-
- GPU_batch_program_set_builtin(
- batch->edges, (interpedges) ? GPU_SHADER_2D_UV_EDGES_SMOOTH : GPU_SHADER_2D_UV_EDGES);
-
- if (sima->dt_uv == SI_UVDT_OUTLINE) {
- /* Black Outline. */
- GPU_line_width(3.0f);
- GPU_batch_uniform_4f(batch->edges, "edgeColor", 0.0f, 0.0f, 0.0f, overlay_alpha);
- GPU_batch_uniform_4f(batch->edges, "selectColor", 0.0f, 0.0f, 0.0f, overlay_alpha);
- GPU_batch_draw(batch->edges);
-
- UI_GetThemeColor3fv(TH_WIRE_EDIT, col1);
- }
- else if (sima->dt_uv == SI_UVDT_WHITE) {
- copy_v3_fl3(col1, 1.0f, 1.0f, 1.0f);
- }
- else {
- copy_v3_fl3(col1, 0.0f, 0.0f, 0.0f);
- }
- col1[3] = overlay_alpha;
+ {
+ /* We could modify the vbo's data filling
+ * instead of modifying the provoking vert. */
+ glProvokingVertex(GL_FIRST_VERTEX_CONVENTION);
+
+ UI_GetThemeColor3fv(TH_EDGE_SELECT, col2);
+ col2[3] = overlay_alpha;
- /* Inner Line. Use depth test to insure selection is drawn on top. */
- GPU_depth_test(true);
- GPU_line_width(1.0f);
- GPU_batch_uniform_4fv(batch->edges, "edgeColor", col1);
- GPU_batch_uniform_4fv(batch->edges, "selectColor", col2);
+ float dash_width = (sima->dt_uv & SI_UVDT_DASH) ? (4.0f * UI_DPI_FAC) : 9999.0f;
+
+ GPU_batch_program_set_builtin(
+ batch->edges, (interpedges) ? GPU_SHADER_2D_UV_EDGES_SMOOTH : GPU_SHADER_2D_UV_EDGES);
+
+ if (sima->dt_uv == SI_UVDT_OUTLINE) {
+ /* Black Outline. */
+ GPU_line_width(3.0f);
+ GPU_batch_uniform_4f(batch->edges, "edgeColor", 0.0f, 0.0f, 0.0f, overlay_alpha);
+ GPU_batch_uniform_4f(batch->edges, "selectColor", 0.0f, 0.0f, 0.0f, overlay_alpha);
+ GPU_batch_uniform_1f(batch->edges, "dashWidth", dash_width);
GPU_batch_draw(batch->edges);
- GPU_depth_test(false);
- glProvokingVertex(GL_LAST_VERTEX_CONVENTION);
- break;
+ UI_GetThemeColor3fv(TH_WIRE_EDIT, col1);
+ }
+ else if (sima->dt_uv == SI_UVDT_BLACK) {
+ copy_v3_fl3(col1, 0.0f, 0.0f, 0.0f);
}
+ else {
+ copy_v3_fl3(col1, 1.0f, 1.0f, 1.0f);
+ }
+ col1[3] = overlay_alpha;
+
+ /* Inner Line. Use depth test to insure selection is drawn on top. */
+ GPU_depth_test(true);
+ GPU_line_width(1.0f);
+ GPU_batch_uniform_4fv(batch->edges, "edgeColor", col1);
+ GPU_batch_uniform_4fv(batch->edges, "selectColor", col2);
+ GPU_batch_uniform_1f(batch->edges, "dashWidth", dash_width);
+ GPU_batch_draw(batch->edges);
+ GPU_depth_test(false);
+
+ glProvokingVertex(GL_LAST_VERTEX_CONVENTION);
}
+
if (sima->flag & SI_SMOOTH_UV) {
GPU_line_smooth(false);
GPU_blend(false);
@@ -481,6 +460,7 @@ static void draw_uvs(SpaceImage *sima,
GPU_blend(false);
}
}
+
if (batch->verts || batch->facedots) {
UI_GetThemeColor4fv(TH_VERTEX_SELECT, col2);
if (batch->verts) {